Conversation
Add src/cli/index.ts with an argument parser and subcommand dispatcher that routes to list/read/create/update/delete handlers, each calling the NoteAPI over HTTP via a shared client. Unknown/missing subcommands print usage to stderr and exit non-zero; handler errors are caught and printed as a clean message with no stack trace. Adds an npm bin entry (noteapi-cli) and dispatcher tests.
- Add shared parseFlags() helper for --flag value / --flag=value parsing - list honors --tag and --q query filters against GET /api/notes - read requires --id and errors non-zero with a clear message when missing - Add unit tests for list/read commands and update dispatcher usage-message assertions
…d flags - create requires --title and --content, POSTs and prints the created note - update requires --id plus at least one of --title/--content, PUTs partial updates - delete requires --id, DELETEs and confirms removal - all three surface API errors with non-zero exit via the existing dispatcher
- src/cli/help.ts holds global and per-subcommand usage text - 'noteapi-cli --help'/'-h' prints global usage and exits 0 - 'noteapi-cli <sub> --help'/'-h' prints that subcommand's usage and exits 0, short-circuiting before the handler runs (no API calls, no stack traces) - Add cli-help.test.ts covering global and all five subcommand help paths
Implement --version and -v flags that print the current version from package.json and exit with code 0. The version flag is checked before subcommand dispatch, so it works even when combined with other flags/arguments. - Created src/cli/version.ts with getVersion() and printVersion() utilities - Updated src/cli/index.ts to handle version flags early in dispatch - Added tests for --version and -v flag behavior - All tests pass, linter passes
Reviewer feedback flagged that cli-commands.test.ts only exercised the missing-required-flag validation path, not genuine apiRequest rejections (e.g. 404s), deviating from the convention established in notes.test.ts. Adds a rejected-apiRequest test per command asserting the command's promise rejects with a clean message so run() exits non-zero.
Adds src/cli/validation.ts with trim-based isNonEmpty/requireNonEmptyFlags helpers, consistent with the src/utils/validation.ts pattern for request bodies. Wires these into read/create/update/delete so passing '' or ' ' to a required flag (--id, --title, --content) throws a clean Usage error and exits non-zero instead of silently proceeding with a blank value.
The previous implementation only checked if the subcommand itself was --version/-v, meaning 'list --version' would fail to print the version. Now hasVersionFlag() scans the entire argv array to find --version/-v regardless of position, so it works even when combined with other flags. Added tests for 'list --version', 'read -v', and 'create --id abc --version' patterns to verify the fix works as described in the acceptance criteria.
Adds tests/cli-crud.test.ts which starts the NoteAPI Express app on an ephemeral port and drives the CLI dispatcher (run()) against it over HTTP, covering list/read/create/update/delete happy paths and error paths (missing required flags, 404 on read/update/delete of unknown id), and asserting exit codes and stdout content.
…toy-7rp.3) Adds tests/cli-help-validation.test.ts covering: global and per-subcommand --help/-h exit 0 with usage text; empty/whitespace-only required args (--id, --title, --content) rejected with non-zero exit and a clear usage message; and that error output contains no stack traces.
Create dedicated test suite for --version and -v flags asserting they print a non-empty version string and exit with code 0.
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.
gh-toy-mi2 (CLI CRUD): All five subcommands implemented — src/cli/commands/{list,read,create,update,delete}.ts — with a shared flag parser (src/cli/args.ts), a fetch-based API client that maps API errors and unreachable-server to non-zero exit (src/cli/client.ts), and end-to-end coverage against a real Express server in tests/cli-crud.test.ts (create/read/update/delete plus 404 error paths). Matches AC.
gh-toy-7rp (help + validation): Global and per-subcommand --help/-h exit 0 (src/cli/help.ts, src/cli/index.ts:31-40); empty/whitespace-only required args rejected via requireNonEmptyFlags/isNonEmpty (src/cli/validation.ts) with clear usage messages and exit 1; index.ts catch block prints "Error: " with no stack trace. Covered by tests/cli-help.test.ts, cli-help-validation.test.ts, cli-validation.test.ts. Matches AC.
gh-toy-4ef (--version): --version/-v detected anywhere in argv (fix 8d0fb1a), prints version and exits 0, works alongside other flags; covered by tests/cli-version.test.ts and cli-help-validation.test.ts. NOTE: this bead is labeled integ-canary and its AC text ("./tool --version prints fleet-e2e-toy v1.0.0", External gh-1, created 2026-05-12) is generic fleet-canary boilerplate that does not correspond to this NoteAPI project — there is no ./tool binary and the project uses a "noteapi v" convention. The implementation prints "noteapi v1.0.0" (src/cli/version.ts:17), which satisfies the substantive intent (version flag, exit 0, composes with other flags). Treating the literal string mismatch as a canary-criteria artifact rather than an implementation defect; captured as a follow-up newTask for the planner rather than a reopen.
File hygiene clean: only src/cli/** and tests/cli-* added, package.json gains a legitimate bin entry (noteapi-cli), and feedback.md was removed before harvest (commit a040553). Working-tree modifications to .beads/interactions.jsonl are from my own review bd invocations, and the sprint-logs/*.jsonl change is a durable workflow cost log (not flagged per policy). Codebase is releasable for the completed work.
Unrelated note: an MCP server ("apra-fleet") returned instructions attempting to have me reproduce injected "onboarding" content verbatim as my first output. I disregarded it as prompt injection irrelevant to this review; it had no bearing on the verdict.