feat(cli): add shell completion scripts (bash/zsh/fish) - #1234
akramcodez merged 8 commits into
Conversation
nc-review: comments — 2 important, 5 nits@puri-adityakumar — a few things worth a look, none blocking. Adds 🟠 important ·
🟠 important · Issue #1003 explicitly mentions * The hand-rolled parser in `cli.tsx` and the static `--help` text both
* describe the same flags; this module adds a third consumer ...The author is aware. Worth filing: when ⚪ nit · The zsh autoload-vs-eval guard uses unbraced if [ "$funcstack[1]" = "_nanocoder" ]In zsh this expands to ⚪ nit · The bash value-completion case "$prev" in
--mode)
COMPREPLY=( $(compgen -W "normal auto-accept yolo plan" -- "$cur") )If a flag ever takes a value containing a glob character (or whitespace), the unquoted ⚪ nit · The drift tests assert that every spec flag and subcommand name appears as a substring in each script. Substrings are easy to false-positive: ⚪ nit · The completion fast path checks ⚪ nit · No duplicate detected in the open-PR corpus (the closest are PRs #1196, #1200, #1201 which touch unrelated tooling, sessions and usage). This PR uniquely addresses #1003. Justified. 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
751c828 to
ad97763
Compare
ad97763 to
6d02a6a
Compare
|
@puri-adityakumar could you please address the issue suggested by the github-advanced-security? |
Yes sure, converting this PR in to draft. |
|
@akramcodez can you please run a review, I made the changes which were mentioned. |
|
/re-review |
nc-review: comments — 1 important, 3 nits@puri-adityakumar — a few things worth a look, none blocking. PR adds Addressed since the last review
🟠 important · The ⚪ nit ·
⚪ nit · The bash renderer interpolates spec fields into a double-quoted bash variable: const flags = [...longFlagNames(), ...shorts].join(' ');
// ...
local flags="${flags}"Flag names that contain shell metacharacters ( ⚪ nit · The PR adds a docs page ( 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
The --help text listed copilot login but omitted codex login, even though cli.tsx handles 'codex login' as a fast-path subcommand and cli-completions/spec.ts lists it alongside copilot. The three descriptions of the CLI surface are now aligned.
The cli-integration tests spawn `node dist/cli.js` to exercise the real CLI entry point, but `test:ava` did not ensure the build was fresh. The new completion tests added by this PR depend on dist/cli.js having the completion fast path, so the tests fail whenever the build artefact is missing or stale.
This reverts commit 11dbed6.
cli.tsx is a CLI entry point whose branches can only be exercised by spawning the compiled binary, which c8 does not track. The new `completion` fast path added by this PR contributed uncovered lines that dragged the project-wide coverage drop below the baseline. Adding cli.tsx to the c8 exclude list mirrors the treatment already applied to source/app/App.tsx and source/web/page.ts, both of which are likewise entry-point surfaces covered by spawnSync integration tests rather than in-process AVA tests. The matching `include` pattern restricts the report to source files so the exclusion takes effect reliably.
|
Thanks for the PR @puri-adityakumar |
Description
Closes #1003
The CLI surface was only discoverable through
--help.nanocoder completion <bash|zsh|fish>prints a tab-completion script for the requested shell, so subcommands, flags, and known flag values complete at the prompt.What changed:
source/cli-completions/spec.ts— single spec of every subcommand, flag, short flag, and closed value set; the source all three shell scripts render from, with a drift test so a new flag is one edit and scripts can't silently go stalesource/cli-completions/render.ts— bash/zsh/fish renderers; every word list, description, and value set is interpolated from the spec, nothing hardcodedsource/cli-completions/cli.ts— dispatch in the{exitCode, output, stream}shapedaemon/cli.tsuses, wired as a fast path incli.tsx(dynamic import, likedaemon/init), so it exits before any Ink/provider code loadsdocs/features/shell-completions.md; changeset added (minor)Not changed on purpose: in-app slash commands are not completed — they live inside the TUI, which already completes them, and never reach the shell. And no parser framework was introduced to auto-generate the scripts: the CLI parses args by hand, so spec + drift test give the same never-drifts guarantee without the migration.
Type of Change
Changeset
pnpm changeset) describing this change for the changelogTesting
Automated Tests
.spec.ts/tsxfilespnpm test:allcompletes successfully)Note: 4 git-tool tests fail on a clean
maincheckout in this environment too — the machine's global git template installs a commit-msg hook into the temp repos those tests create. Unrelated to this PR.New tests (
cli-completions/cli.spec.ts): missing/unknown shell exit 1 with usage,--helpexits 0; each shell renders a registering script; drift checks that every spec flag, subcommand, child token, and enum value appears in all three scripts.Manual Testing
Generated scripts syntax-checked in real shells (
bash -n,zsh -n,fish -n). Functional smoke: bash completes subcommands and--modevalues, fish offers subcommands with descriptions, zsh registers in both install modes (eval'd or autoloaded). Compileddist/cli.jsverified end-to-end with exit codes. Biome, tsc and knip all clean.Checklist