Skip to content

refactor(cli-schema): derive the flag tail of usage synopses so an option addition never edits usageOverride #2444

Description

@thymikee

Wave 2 child of #2409. Named but not done in PR #2421.

Purpose

An option added to a command whose synopsis is hand-written must be restated in that synopsis by hand. #2421 made the descriptor the single declaration of an option for cli-schema flags, the MCP schema and daemon flags; the usageOverride string is the last restatement left on the help surface.

Baseline

On main at 41e2633f10:

  • buildCommandUsage returns schema.usageOverride verbatim when it is set (src/cli-schema/usage.ts:19). Otherwise it renders the positionals plus one [label] per key in allowedFlags, in that order, using the flag declaration's usageLabel.
  • 39 command descriptors set usageOverride (grep -rn "usageOverride:" src/commands). 38 encode shapes the generator cannot express: alternation (clipboard read | clipboard write <text>), subcommand forms (session list | session state-dir | …), value enumerations (orientation <portrait|…>), multi-line families (perf, metro).
  • snapshot is the one override whose content is flags-only (src/commands/capture/snapshot.ts:54). It differs from the generated line in two ways. The generator renders --depth, -d <depth> and --scope, -s <scope> (the declared usageLabel, src/commands/cli-grammar/flag-definitions-workflow.ts:185) where the override shows -d <depth> and -s <scope>. The generator appends [--record] because record is in allowedFlags (snapshot.ts:56), while no synopsis in website/docs/docs/commands.md shows [--record] today (0 occurrences).
  • Replay of feat(ios): expose AX custom actions on merged accessibility elements #1665 (--actions on snapshot): the change edited the override string and the docs line website/docs/docs/commands.md:353, which src/__tests__/command-doc-coverage.test.ts:78 pins byte-for-byte against buildCommandUsage('snapshot', …).
  • Help tests are literal assert.match asserts, not golden files (src/cli-schema/cli-help-command-usage.test.ts:270 and siblings). None pins the full snapshot line.

Required work

  1. Decide the two rendering rules on the flag declaration, not per command: (a) how a flag with a short alias renders in a synopsis (full --depth, -d <depth> as generated lines do today, or short-only as the snapshot override does), and (b) which cross-cutting flags stay out of synopses. Encode (b) as a field on the flag declaration (for example usageHidden: true on the record definition), never as an override.
  2. Drop usageOverride from snapshot. Its --help line is generated; the docs line at commands.md:353 moves to the generated form and the byte-for-byte doc test stays green.
  3. Classify the remaining 38 overrides in the PR body: "positional grammar the generator cannot express, keep" or "flag tail derivable". Where an override is a hand-written positional part followed by flags, split it so only the positional part stays hand-written and the flag tail is generated from allowedFlags. Pure alternation and subcommand overrides stay as they are.
  4. Guard: a test fails when a command has usageOverride set and a key in its allowedFlags that is neither marked hidden nor mentioned in the override. An override can no longer silently lag its flags.

Acceptance, measurable from git

  • Re-doing feat(ios): expose AX custom actions on merged accessibility elements #1665's --actions addition on the new shape edits no usageOverride string. The docs line still changes; that is the documented coverage rule, not a restatement.
  • agent-device snapshot --help output is either byte-identical to today or changed exactly per rules 1(a) and 1(b), with the help tests updated in the same PR and the rule pinned by one test.
  • Every remaining usageOverride mentions every non-hidden flag in its command's allowedFlags (the step-4 guard is green), or the command is listed in the PR as an intentional exception with the reason.

Non-goals

  • A usage grammar for alternation or subcommands; the non-derivable overrides stay hand-written.
  • Changing option names or semantics. listUsageOverride is untouched.

Dependencies

None. Builds on #2421 (ad79461c72).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions