Skip to content

refactor: derive flags, help and completions from one command spec - #427

Merged
sametcelikbicak merged 1 commit into
mainfrom
refactor/single-command-spec
Oct 6, 2026
Merged

sametcelikbicak merged 1 commit into
mainfrom
refactor/single-command-spec

Conversation

@sametcelikbicak

Copy link
Copy Markdown
Member

Closes #410. Addresses #296's premise (the generators move, they are not deleted) without touching that issue's src/api/ move.

The drift this fixes

$ rolecraft use <src> --dry-run     # bash completes it, CLI rejects it
✗  use: unknown flag "--dry-run"
$ rolecraft list --repo x           # bash and zsh complete it, exists nowhere

Also gone: --repo/--slug (never existed), check-updates (no completion entry in any shell), init --description/--agents (accepted but undocumented), --dry-run on mcp remove (tracked separately in #410's notes).

What changed

src/commands/spec.js is the one description — every command, its flags, their descriptions, subcommands and aliases. From it:

  • validation — one validateFlags call in main() replaces 18 hand-written lists inside handlers
  • help — the root command list and each command's own help are generated. install --help went from 204 lines to 16; mcp --help was unreachable dead text and now works
  • completions — bash, zsh and fish are generated from the same table (completions.js: 416 → 206 lines)
  • docs — docs/reference.md's common-flags table is generated, with a test that fails if it goes stale

--verbose and --help are accepted by every command now. That was the point of the UserError.detail/.code fields: they could never reach a user before, because every command but test rejected the flag.

Exit codes

2 for a usage error — unknown command, subcommand or flag, or a missing required argument. 1 for a failed operation. Previously everything was 1, so a typo was indistinguishable from a failed install.

Deliberate behavior changes

Flagged in the issue as not-a-bugfix, kept separate so a bisect stays clean:

  • unknown flags exit 2 instead of 1
  • --verbose now works everywhere (previously an error on 24 of 25 commands)
  • -v is no longer ambiguous — it was --version at top level and test --verbose inside test

Left out

The 87 per-agent flags stay accepted and completed but are not listed in install --help, which points at rolecraft agents instead. 87 lines of --claude Also install to ~/.claude/skills/ is not a help page.

Tests

spec.test.js checks the spec's own invariants and that the generated docs table is current. cli-contract.test.js spawns the real CLI to check that every non-passthrough command rejects an unknown flag with exit 2, that every spec flag appears in its own --help, and that every word bash completes is a word the CLI accepts — the check that would have caught --repo.

)

The command surface was written out by hand in six places and had already
drifted: bash completion offered --dry-run for `use` (which rejects it)
and --repo/--slug (which exist nowhere), `check-updates` had no
completion entry, and `init --description/--agents` were accepted but
undocumented.

src/commands/spec.js is now the single description: every command, its
flags, their descriptions, subcommands and aliases. From it:

- `bin/rolecraft.js` validates flags in one place in main() instead of 18
  hand-written lists per handler, and generates both the root help and
  focused per-command help (`install --help` is 16 lines, not 204)
- `completions.js` generates bash, zsh and fish from the same table
- `docs/reference.md`'s common-flags table is generated from it

`--verbose` and `--help` are now accepted by every command, so
UserError.detail and .code actually reach users.

Exit codes split: 2 for a usage error (unknown command, subcommand or
flag), 1 for a failed operation. A missing required argument is a usage
error too, and no longer gets reported as exit 1.

The 87 per-agent flags stay accepted and completed but are not listed in
`install --help`, which points at `rolecraft agents` instead.

Behavior changes are deliberate and listed in the issue: unknown flags
exit 2 rather than 1, previously-rejected flags now work, and `-v` is no
longer ambiguous between `test --verbose` and `--version`.
@sametcelikbicak sametcelikbicak changed the title refactor: derive flags, help and completions from one command spec (#410) refactor: derive flags, help and completions from one command spec Oct 6, 2026
@sametcelikbicak
sametcelikbicak merged commit 86ae439 into main Oct 6, 2026
7 checks passed
@sametcelikbicak
sametcelikbicak deleted the refactor/single-command-spec branch October 6, 2026 08:04
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.

refactor: derive flags, usage and shell completions from one command spec

1 participant