Skip to content

Add the three task commands: get, cancel and delete - #29

Merged
curquiza merged 1 commit into
mainfrom
tasks-commands
Oct 27, 2026
Merged

curquiza merged 1 commit into
mainfrom
tasks-commands

Conversation

@curquiza

@curquiza curquiza commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

What

Add meili get tasks, meili cancel tasks and meili delete tasks, the three stable routes of /tasks.

Contract

  • The command name and flags derive from its routes by the naming rules of docs/contract/commands.md, and each route is reachable by a distinct set of flags, or the exception is recorded with its reason (or this pull request changes the contract and nothing else)
  • Output goes through src/lib/output.ts, errors through src/lib/errors.ts
  • The command never waits for a human: no prompt, no question, no $EDITOR; a delete command spreads BaseCommand.confirmFlags and its examples carry --yes
  • The command never speaks HTTP itself: the SDK or the generated client only, no fetch outside src/lib/clients/

Tests

  • --help snapshot added or updated on purpose
  • JSON output snapshot for one success case per route and one error case
  • Integration test added (Meilisearch API commands only)
  • pnpm lint, pnpm typecheck, pnpm test pass locally

Simplicity

  • Nothing in the diff exists for a case the API cannot produce, a caller that does not exist, or a generality nobody asked for (rule 16)
  • Anything shared lives in src/lib/, is used by this command, and is named below

Docs

  • docs/contract/ updated for every name, flag, variable or code this change adds or renames, or nothing to update
  • The ADRs that touch this change were read; what they decide still holds, or a new ADR says what changed
  • No accepted ADR was edited. A new ADR was added if a decision changed.

Housekeeping

  • oclif.manifest.json regenerated
  • Changeset added, or the change is invisible to users of the package (docs of this repository, tests, CI)
  • New dependency justified below, or none added

Notes for the reviewer

Command Route Key action
meili get tasks GET /tasks tasks.get
meili cancel tasks POST /tasks/cancel tasks.cancel
meili delete tasks --yes DELETE /tasks tasks.delete

Three commands of one resource in one change, as rule 10 allows. POST /tasks/compact is left out: it is an experimental route, already recorded as an exception. GET /tasks/stream and GET /tasks/{task_id}/documents stay recorded without command.

Shared pieces added to src/lib/, used by the three commands

  • src/lib/task-filters.ts: the twelve selectors the three routes share (--ids, --batch-ids, --index-ids, --canceled-by, --types, --statuses and the six date filters), plus the query they build. Spread into each command's own flags, so meili schema --command shows them (ADR 0010). GET /batches takes the same filters, so this file is where that command will find them.
  • src/lib/pagination.ts: GET /tasks pages with from/next, not offset/total — the shape commands.md already names in its List routes group. nextFromQuery follows the cursor, and outputList takes the walk its route uses as a fourth argument, so get indexes and get documents now name nextOffsetQuery. mergePages drops the fields that describe one page itself; a route carries one pair or the other, so dropping all three is dropping its.
  • src/lib/base-command.ts: fromPaginationFlags, --limit/--from/--all. --limit and --all are the same flag objects as paginationFlags, so the wording lives once. Added to the group list of test/contract/env.test.ts, which rule 14 walks.

Interface decisions

  • cancel tasks with no filter is passed through to the API, which answers missing_task_filters and exits 1. delete tasks with no filter is refused by the CLI, cli_usage and exit 2 before any network call, because output.md requires it of a delete. The two differ on purpose: the destructive rule covers the verb delete and nothing else.
  • --statuses and --types declare no closed list of values. The API accepts * next to its enum, and the values are comma-separated, which an oclif options list would validate as one string. The text travels as written and the API names what it refuses, as output.md says.
  • --all on get tasks follows the next cursor and merges into one envelope with limit and from dropped. output.md said limit and offset; the sentence now covers both shapes.

One simplification considered and not taken

outputList's fourth argument could go away by having pagination.ts read the envelope shape ("next" in page), which would also keep get indexes and get documents out of this diff. The AllTasks schema of the OpenAPI document lists only results, total and limit as required: from and next are optional. A next the API omitted would fall through to the offset walk and re-fetch from the start, so the route's walk is named at the call site instead.

Unrelated line fixed on the way

src/lib/tasks.ts hinted meili task get <uid> on a --wait timeout, a command that never existed. It now names meili get tasks --ids <uid>.

No new dependency.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added get tasks with filters for task IDs, indexes, status, type, batches, and date ranges, plus cursor pagination and --all output.
    • Added cancel tasks and delete tasks with matching filters. Deletion requires --yes; both commands can wait for a final task status.
    • Added get indexes support for listing and retrieving indexes.
  • Documentation

    • Documented task commands, deletion, and pagination behavior.

`meili get tasks` covers `GET /tasks`, `meili cancel tasks` covers
`POST /tasks/cancel` and `meili delete tasks` covers `DELETE /tasks`.
The three routes take the same twelve selectors, so they are declared
once in `src/lib/task-filters.ts` and spread into each command.

`GET /tasks` pages with `from` and `next` rather than `offset` and
`total`, which `commands.md` already names: `BaseCommand` gains the
`fromPaginationFlags` group the contract's List routes group describes
for a cursor route, `pagination.ts` gains `nextFromQuery`, and
`outputList` takes the walk its route uses. `mergePages` now drops the
fields that describe one page, whichever pair a route carries, and
`output.md` says so.

`cancel tasks` without a filter is passed through: the API answers
`missing_task_filters` and the command exits 1. `delete tasks` without
one is refused by the CLI, `cli_usage` and exit 2 before any network
call, as `output.md` requires of a `delete`.

On the way, `src/lib/tasks.ts` stops hinting `meili task get <uid>` on a
`--wait` timeout, a command that never existed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Walkthrough

The CLI adds commands to list, cancel, and delete tasks. Task listing supports shared filters and cursor-based pagination. Cancellation and deletion use task filters, with deletion requiring confirmation. Tests and command metadata cover the new commands and pagination behavior.

Changes: Task command workflows

Layer / File(s) Summary
Shared pagination
src/lib/pagination.ts, src/lib/base-command.ts, src/commands/get/documents.ts, src/commands/get/indexes.ts, test/lib/pagination.test.ts, test/contract/env.test.ts, docs/contract/output.md, oclif.manifest.json
List output now uses a caller-provided next-query function for offset or cursor pagination. JSON page merging removes pagination fields from the final envelope. Existing document and index listings pass the offset strategy.
Task retrieval and filters
src/lib/task-filters.ts, src/commands/get/tasks.ts, test/commands/get/tasks.test.ts, test/helpers/meilisearch-handlers.ts, test/integration/meilisearch/get-tasks.test.ts, oclif.manifest.json
The task-list command maps shared task filters to query parameters and supports reverse ordering and cursor pagination. Unit and integration tests cover filtering, JSON, NDJSON, and page traversal.
Task cancellation and deletion
src/commands/cancel/tasks.ts, src/commands/delete/tasks.ts, test/commands/{cancel,delete}/tasks.test.ts, test/integration/meilisearch/{cancel,delete}-tasks.test.ts, oclif.manifest.json, docs/contract/commands.md, package.json, .changeset/first-version.md, src/lib/tasks.ts, test/lib/tasks.test.ts
Cancellation submits task filters to POST /tasks/cancel. Deletion requires confirmation and at least one filter before calling DELETE /tasks. Tests cover command output, errors, waiting, and deletion confirmation. The task timeout hint now uses meili get tasks --ids <uid>.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant GetTasks
  participant BaseCommand
  participant tasks.getTasks
  participant Meilisearch
  GetTasks->>BaseCommand: Call outputList with query and nextFromQuery
  loop Each page
    BaseCommand->>tasks.getTasks: Fetch page with current query
    tasks.getTasks->>Meilisearch: GET /tasks with limit and optional from
    Meilisearch-->>tasks.getTasks: Return results and next cursor
    tasks.getTasks-->>BaseCommand: Return ListPage
    BaseCommand->>BaseCommand: Derive next query from page.next
  end
Loading

Possibly related PRs

  • meilisearch/cli#21: Adds GetDocuments, whose outputList call was updated to use the new pagination callback.
Merge Risk: Minimal · up to 222c6

The task commands and pagination changes are ready to merge after normal checks; no established issue currently blocks them.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 19 files. (5 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely identifies the three primary task commands added by the pull request: get, cancel, and delete.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 19 files. (5 skipped: 5 unsupported.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔇 Additional comments: 24
docs/contract/output.md: 1

113-113: LGTM!

oclif.manifest.json: 1

1159-1167: LGTM!

Also applies to: 1188-1351, 2485-2493, 2539-2879, 3484-3493, 3540-3651, 3660-3664, 3677-3688

src/commands/get/documents.ts: 1

7-7: LGTM!

Also applies to: 83-83

src/commands/get/indexes.ts: 1

3-3: LGTM!

Also applies to: 41-41

src/lib/base-command.ts: 1

39-43: LGTM!

Also applies to: 123-139, 248-252, 262-268

test/contract/env.test.ts: 1

43-43: LGTM!

test/lib/pagination.test.ts: 1

28-41: LGTM!

Also applies to: 62-80, 84-97

src/lib/tasks.ts: 1

19-19: LGTM!

Also applies to: 78-78

src/lib/task-filters.ts: 1

1-90: LGTM!

src/commands/get/tasks.ts: 1

1-47: LGTM!

test/helpers/meilisearch-handlers.ts: 1

120-152: LGTM!

test/commands/get/tasks.test.ts: 1

1-120: LGTM!

test/integration/meilisearch/get-tasks.test.ts: 1

1-70: LGTM!

src/commands/cancel/tasks.ts: 1

1-31: LGTM!

src/commands/delete/tasks.ts: 1

1-41: LGTM!

docs/contract/commands.md: 1

52-52: LGTM!

package.json: 1

57-59: LGTM!

.changeset/first-version.md: 1

10-10: LGTM!

test/commands/cancel/tasks.test.ts: 1

1-88: LGTM!

test/commands/delete/tasks.test.ts: 1

1-82: LGTM!

test/integration/meilisearch/cancel-tasks.test.ts: 1

1-59: LGTM!

test/integration/meilisearch/delete-tasks.test.ts: 1

1-54: LGTM!

test/lib/tasks.test.ts: 1

85-87: LGTM!

src/lib/pagination.ts: 1

42-42: Trivial · Stability & Availability · Quick win

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Reject a next cursor that equals the cursor just requested.

nextFromQuery returns { ...query, from: next } for every numeric next. iteratePages then calls fetchPage again. If the server answers a next equal to the current from, the same page is requested forever. --all then never ends. In ndjson mode it prints the same page without end. In json mode it buffers pages without end until memory runs out. A buggy or hostile server can cause this.

Throw an error when the cursor does not move. Import MeiliCliError from ./errors.js. The contract has no code for a bad server answer, so cli_internal is the closest existing one. Adding a new code is a contract change.

🛡️ Proposed fix
 export function nextFromQuery(query: FromQuery, page: ListPage): FromQuery | undefined {
   const next = page.next;
-  return typeof next === "number" ? { ...query, from: next } : undefined;
+  if (typeof next !== "number") return undefined;
+  if (next === query.from) {
+    throw new MeiliCliError(
+      "cli_internal",
+      `The API answered the cursor \`next\` ${next} that the request already used.`,
+    );
+  }
+  return { ...query, from: next };
 }

Based on learnings: "detect and reject responses where the server indicates more pages ... but the returned end cursor is unchanged from the previous request."

Source: Learnings


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Essentials
  • Run ID: 4c8a361d-bc12-4682-87ea-a756781860e3
Commits

Reviewing files that changed from the base of the PR and between f94cfa2 and 222c6f1.

Files ignored due to path filters: 5
  • test/commands/cancel/__snapshots__/tasks.test.ts.snap is excluded by !**/*.snap
  • test/commands/delete/__snapshots__/tasks.test.ts.snap is excluded by !**/*.snap
  • test/commands/get/__snapshots__/tasks.test.ts.snap is excluded by !**/*.snap
  • test/contract/__snapshots__/commands.test.ts.snap is excluded by !**/*.snap
  • test/contract/__snapshots__/help.test.ts.snap is excluded by !**/*.snap
Files selected for processing: 24
  • .changeset/first-version.md
  • docs/contract/commands.md
  • docs/contract/output.md
  • oclif.manifest.json
  • package.json
  • src/commands/cancel/tasks.ts
  • src/commands/delete/tasks.ts
  • src/commands/get/documents.ts
  • src/commands/get/indexes.ts
  • src/commands/get/tasks.ts
  • src/lib/base-command.ts
  • src/lib/pagination.ts
  • src/lib/task-filters.ts
  • src/lib/tasks.ts
  • test/commands/cancel/tasks.test.ts
  • test/commands/delete/tasks.test.ts
  • test/commands/get/tasks.test.ts
  • test/contract/env.test.ts
  • test/helpers/meilisearch-handlers.ts
  • test/integration/meilisearch/cancel-tasks.test.ts
  • test/integration/meilisearch/delete-tasks.test.ts
  • test/integration/meilisearch/get-tasks.test.ts
  • test/lib/pagination.test.ts
  • test/lib/tasks.test.ts

Included review availability: This review used your included allowance. 4 included reviews remain after this review. Your included PR review attempts over the past 7 days set your current allowance at 5 reviews per hour.

@curquiza
curquiza merged commit 59bb558 into main Oct 27, 2026
3 checks passed
This was referenced Oct 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant