feat(cli): add tasks list to close CLI <-> MCP list_tasks drift#54
Merged
Conversation
closes cli-add-list-command
The MCP server has exposed `list_tasks` with priority/tag/unclaimed/
unblocked filters since v0.6, but the CLI had no equivalent — agents
scripting through `tasks` could only call `tasks pick` (one task) or
parse TASKS.md themselves. Close the gap:
tasks list # all tasks, P0 first
tasks list --priority P0 --tag backend
tasks list --unclaimed --unblocked # only pickable work
tasks list --priority P0 --json
Default output is `<priority>\t<id>\t<summary>` (tab-separated, `-`
for tasks without an ID). `--json` returns the same structured fields
the MCP `list_tasks` response uses (id, summary, priority, tags,
blocked, claimed, file, line) so callers can swap backends without
changing scripts.
Implementation reuses `loadAllTasks`, `getAllTaskIds`, and `isBlocked`
from @tasks-md/parser — the same predicates `pickBestTask` and the
MCP server's `listTasksFromFiles` use — so CLI and MCP cannot drift.
Pin tests so the same drift fails CI next time:
cli.test.ts -> 8 listTasks unit tests covering every filter +
priority sort + structured output + claimed prefix
-> 4 CLI integration tests covering tab-separated default,
--json round-trip, --priority --unclaimed parity with
the MCP path, and empty-match messaging
-> --help test now also asserts `list` is advertised
Docs updated in lockstep:
README.md (CLI examples)
packages/cli/README.md (new tasks list section)
docs/user-stories/07-monitor-queue-health.md (Enumerate Tasks Programmatically section)
docs/user-stories/README.md (story 07 + automation table)
This was referenced May 3, 2026
fyodoriv
added a commit
that referenced
this pull request
May 3, 2026
…59) closes cli-restore-json-on-read-commands Commit ccf1360 (2026-03-17, "remove unused features") dropped the --json flag from tasks pick/stats/diff, but PR #54 (2026-05-03) added --json to the new tasks list command. The CLI surface ended up inconsistent: one read command was JSON-scriptable, three were not. Restoring --json across all four read commands (pick / list / stats / diff) so any script can choose a command and parse its output with the same `JSON.parse(stdout)` call. Behavior: - pick --json: emits {picked: false} when the queue is empty, otherwise {picked: true, summary, priority, file, line, metadata, candidates, unblocks}. Same shape as the historical implementation in commit a567140. - stats --json: full QueueStats object (same type the lib already exports — total, byPriority, blocked, claimed, available, fileCount, throughput, topAgents). - diff --json: full QueueDiff object (ref, added, removed, claimed, hasChanges). - list --json: unchanged. Tests added in cli.test.ts pinning all four JSON paths plus a --help parity check that fails CI if any read command stops advertising --json: - pick --json outputs structured JSON - pick --json outputs {picked: false} for empty queue - stats --json outputs structured JSON - diff --json outputs structured JSON (uses git add -f to bypass any global gitignore that excludes TASKS.md in the test temp dir) - --help advertises --json for every read command Verified: npm run build, npm test (402 tests pass, +5 new), npm run lint, npx -y @tasks-md/lint TASKS.md. --- _🤖 Written by an agent, not Fyodor. Ping me if this looks off._
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
closes `cli-add-list-command`
The MCP server has exposed `list_tasks` with priority/tag/unclaimed/unblocked filters since v0.6, but the CLI had no equivalent — agents scripting through `tasks` could only call `tasks pick` (one task) or parse TASKS.md themselves. Close the gap:
``` tasks list # all tasks, P0 first tasks list --priority P0 --tag backend tasks list --unclaimed --unblocked # only pickable work tasks list --priority P0 --json ```
Default output is `\t\t
Implementation reuses `loadAllTasks`, `getAllTaskIds`, and `isBlocked` from `@tasks-md/parser` — the same predicates `pickBestTask` and the MCP server's `listTasksFromFiles` use — so CLI and MCP cannot drift.
Why needed
Agents that orchestrate work via the CLI (taskgrind, etc.) had to either call MCP for enumeration or hand-parse TASKS.md. `tasks list` gives them a first-class enumerator that mirrors the MCP `list_tasks` response field-for-field.
Test plan
``` $ tasks list --priority P2 --unclaimed --unblocked P2 user-stories-acceptance-sharpening Sharpen vague acceptance ... P2 docs-accuracy-batch-readme-cli Documentation accuracy batch ... P2 user-stories-polish-batch Polish batch ... ```
New unit tests pin every claim in the acceptance criteria:
Scope
🤖 Written by an agent, not Fyodor. Ping me if this looks off.