Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(commands): discoverable flags, per-command --help, strict validation#373

Merged
clangenb merged 5 commits into
mainfrom
feat/command-flag-help-ux
May 19, 2026
Merged

feat(commands): discoverable flags, per-command --help, strict validation#373
clangenb merged 5 commits into
mainfrom
feat/command-flag-help-ux

Conversation

@eldara-cruncher
Copy link
Copy Markdown
Collaborator

Context

The :command palette (Bubble Tea TUI, not a shell CLI) had no flag discoverability: :bootstrap --upgrade worked but was documented nowhere in-app, :bootstrap --help silently ran bootstrap (the --help flag was parsed then never read), and any misspelled/unknown flag was silently swallowed by parseArgs.

What changed

  • registry/spec.go (new): optional CommandWithSpec capability (Spec() CommandSpec), discovered by type assertion exactly like the existing Aliaser. CommandSpec{Usage, Flags, Examples, Passthrough}, plus SpecOf (alias-resolving) and a Distance (Levenshtein) helper.
  • commands/api/parse.go: single chokepoint — short-circuits Passthrough specs, intercepts --help/-h/-help into the new ErrHelpRequested sentinel (error.go), then runs global strict unknown-flag validation (validate.go) with a did you mean --x? suggestion.
  • commands/command/help.go: CommandHelpCategories/CommandHelpCmd build a per-command screen reusing the existing detailed help view ([]HelpCategoryNewDetailed); :help <cmd> routes through the same builder with a typo suggestion. No help-view rendering changes.
  • app/update.go: recovers ErrHelpRequested via errors.As and renders the per-command help.
  • Every command now declares a Spec(). The OSS bootstrap stub uses Passthrough:true so :bootstrap/--help/Pro flags still yield the Business-Edition notice and no Pro flag internals enter the OSS repo (respects the Pro Feature Boundary).
  • CLAUDE.md: documented the Command Spec pattern and the new-command requirement.

Behaviour

  • :bootstrap --help and :help bootstrap -> Usage/Flags/Examples screen.
  • :bootstrap --upgrad -> inline unknown flag --upgrad for :bootstrap, did you mean --upgrade?
  • :quit --xyz -> rejected (global strict applies to zero-flag commands too).

Breaking

Previously-ignored unknown flags are now rejected. The two existing parse_test.go cases that fed node --verbose are intentionally repointed at the passthrough bootstrap command — flag/positional separation is still covered, and strict rejection is covered by new cases.

Cross-repo

This OSS change defines registry.CommandSpec; the companion swarmcli-be PR (bootstrap/license specs) must merge after this one or pro CI fails with undefined: registry.CommandSpec.

Tests

go build, go test ./..., and golangci-lint run ./... all green. Added: registry/spec_test.go, commands/command/help_test.go, parse_test extensions.

🤖 Generated with Claude Code

…tion

The `:command` palette had no flag discoverability: `:cmd --help` silently
ran the command and unknown/misspelled flags were silently ignored.

Add an optional `registry.CommandWithSpec` capability (same type-assertion
pattern as `Aliaser`) carrying a declarative `CommandSpec{Usage, Flags,
Examples, Passthrough}`. `api.ParseInput` is now the single chokepoint
that: short-circuits Passthrough specs, intercepts `--help`/`-h`/`-help`
(and `:help <cmd>`) into a per-command help screen reusing the existing
detailed help view, then enforces global-strict unknown-flag rejection
with a "did you mean --x?" suggestion.

Every command declares a spec; the OSS bootstrap stub uses Passthrough
so it keeps its Business-Edition notice and no Pro flag internals enter
the OSS repo. Docs updated in CLAUDE.md.

BREAKING: previously-ignored unknown flags are now rejected. The two
parse_test cases that fed `node --verbose` are repointed at the
passthrough `bootstrap` command (flag/positional separation still
covered; strict rejection covered by new cases).

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
clangenb and others added 4 commits May 19, 2026 07:03
The detailed help view renders categories as side-by-side columns with
a 15-char key column — built for short keybinding cheat-sheets. Long
usage/flag strings overflowed and collided (reported on :bootstrap
--help).

Add a distinct CommandHelp payload routed to a new vertical renderer:
sections stacked top-to-bottom, short-key sections (flags) in an aligned
key/description column, long-key sections (usage/examples) stacked with
word-wrapped lines. The columnar keybinding cheat-sheet path
(NewDetailed / `?`) is untouched — no regression to existing views.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
…help

Two UX fixes on top of the flag-spec work:

1. The parser only understood `--host=localhost`; `--host localhost`
   left `host=true` and dropped the value as a positional. parseArgs is
   now spec-aware: a flag declared TakesValue consumes the next token
   (`--host localhost`), the `=` form still works, and a value flag
   with no following token is a clear error. ParseInput resolves the
   spec before parsing to build the value-flag set.

2. Add an optional CommandSpec.Detail prose field, rendered as a
   wrapped paragraph under USAGE (author newlines preserved as
   paragraph breaks). Lets a command explain non-obvious modes — e.g.
   that running with no flags starts an interactive flow. The USAGE
   block now always stacks command-line then description as a header.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
- :help page header gains a dim second line:
  "Tip: <command> --help (or -h) for flags, usage & examples".
  Command-list path only (FrameHeader) — absent from per-command and
  ? keybinding screens, filter-proof.
- Behavior-only Detail added to every OSS command spec (help, quit,
  contexts, stack, node, network, secret, config). OSS bootstrap stub
  stays Passthrough (no Detail by design).
- Tests: FrameHeader hint placement; guard that every non-passthrough
  registered command ships a Detail.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
The two-line FrameHeader broke the box border (ui.RenderFramedBox treats
the header as one bordered line; RenderFramedBoxHeight assumes
headerLines=1). Revert FrameHeader to the single styled "Available
Commands" line and render the discoverability tip as the first body
line in the default terminal colour, followed by a blank line before
the table header. Filter rebuild keeps the tip. Box border is intact.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
@clangenb clangenb merged commit bfe5777 into main May 19, 2026
13 checks passed
@eldara-cruncher eldara-cruncher deleted the feat/command-flag-help-ux branch June 5, 2026 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants