feat(cli): declare what each usage command does to the world - #751
Merged
Conversation
usage added `effect=` and shipped it to mise, hk, pitchfork, aube and
communique, and then declared nothing for its own 16 commands. Anything
pointed at usage's spec — its docs, `usage mcp` — sees empty fields on
the tool that invented the feature.
complete-word read
generate read
generate completion read
generate fig read --out-file write
generate manpage read --out-file write
generate markdown read --out-dir write
--out-file write
generate sdk write
lint read
sponsors read
Most of these print to stdout and take an optional flag to write to a
file instead, so they sit at `read` with the flag raising them. That is
the composition rule earning its place rather than being asserted in a
doc: `usage g markdown -f x.kdl` only reads, and the same command with
`--out-file` writes.
`generate sdk` is the exception. Its `-o --output` is required, so there
is no read-only way to invoke it and the effect belongs on the command.
The five shell commands — `bash`, `fish`, `zsh`, `powershell`, `exec` —
are deliberately unset, because they run a script the user supplied and
their effect is whatever that script does. `read` in particular would be
dangerous. A test asserts every unclassified command has an entry in
`UNCLASSIFIED` with its reason, so nothing goes unlabeled by accident.
Applied to the derived spec via `clap_usage::spec` (#743) since clap
cannot express it, the same shape as mise's `command_effects`. Also
emits `min_usage_version "4.0"`, because an older `usage` rejects a spec
carrying `effect=` with "unsupported cmd prop effect".
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThe CLI now classifies command and output-flag effects, applies them during usage-spec generation, emits usage version metadata, and synchronizes the resulting effect annotations across usage specifications and CLI reference documentation. ChangesCLI effect metadata
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant CliMetadata
participant UsageSpec
participant CommandEffects
CliMetadata->>UsageSpec: build spec from CLI metadata
UsageSpec->>CommandEffects: apply command and flag effects
CommandEffects-->>UsageSpec: classified spec
UsageSpec-->>CliMetadata: emit usage version and spec
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
usage added
effect=, shipped it to mise, hk, pitchfork, aube and communique — and declared nothing for its own 16 commands. Anything pointed at usage's spec sees empty fields on the tool that invented the feature.complete-wordgenerategenerate completiongenerate completion-initgenerate fig--out-file→ writegenerate jsongenerate manpage--out-file→ writegenerate markdown--out-dir,--out-file→ writegenerate sdklintsponsorsWhy the shape is interesting
Most of these print to stdout and take an optional flag to write to a file instead, so they sit at
readwith the flag raising them. That's the composition rule earning its place rather than being asserted in a doc —usage g markdown -f x.kdlonly reads; the same command with--out-filewrites.generate sdkis the exception. Its-o --outputis required, so there is no read-only way to invoke it and the effect belongs on the command, not a flag.Unclassified, deliberately
bash,fish,zsh,powershellandexecrun a script the user supplied, so their effect is whatever that script does. Labeling them would be a lie in whichever direction it was labeled, andreadin particular would be dangerous. A test asserts every unclassified command has an entry inUNCLASSIFIEDwith its reason, so a new command can't go unlabeled by accident.How
clap can't express this, so it's applied to the derived spec through
clap_usage::spec(#743), the same shape as mise'scommand_effects. Five tests cover stale command paths, stale flag names, the unclassified guard, and both composition cases above.Also emits
min_usage_version "4.0"— an olderusagerejects a spec carryingeffect=with "unsupported cmd prop effect", so the declaration and the floor move together. mise does the same.The generated docs pick it up for free:
usage generate sdknow reads Effect: modifies state, and--out-fileonmarkdownreads Effect: modifies state under a read-only command.This PR was generated by an AI coding assistant.
Note
Low Risk
Metadata and spec-generation path changes only; no runtime command behavior changes beyond richer
--usage-specoutput.Overview
Adds
command_effectsso theusageCLI’s own--usage-specoutput carrieseffect=read/effect=writeon commands and flags (clap can’t express this; it’s patched onto the derived spec like mise/hk).Most generators are read;
--out-file,--out-dir, etc. raise matching flags to write.generate sdkis write at the command level because output is required.bash,exec, and other script runners stay unclassified, with tests guarding stale paths and accidental gaps.usage_spec::generatenow builds the spec viaclap_usage::spec, runsapply, and emitsmin_usage_version "4.0"alongside the KDL. Regeneratedusage.usage.kdl,commands.json, and CLI reference docs show read-only vs modifies-state in docs.Reviewed by Cursor Bugbot for commit 9ee7a02. Bugbot is set up for automated code reviews on this repo. Configure here.
Summary by CodeRabbit
New Features
Documentation