Files
pad/cmd
xarmian eecc683ab0 feat(cmdhelp): implement --format json emitter (TASK-934) (#327)
* feat(cmdhelp): implement --format json emitter (TASK-934)

Adds internal/cmdhelp package that walks the cobra command tree and
emits a cmdhelp v0.1 Document conforming to schema/cmdhelp.schema.json.
Wires it into cmd/pad/help_cmdhelp.go so `pad help --format json` is
no longer a stub.

Files:
- internal/cmdhelp/types.go — Document/Command/Arg/Flag/Stdin/Stdout/
  ExitCode/Example structs mirroring the schema. ExitCode implements
  custom MarshalJSON for the string-or-object union (spec §5.2).
- internal/cmdhelp/json.go — Build() walks target's subtree; EmitJSON()
  serializes to indented JSON. Type mapping covers pflag's full type
  space, including slice/array→repeatable. Hidden commands and flags
  filtered. Cobra's auto-installed --help flag suppressed. Zero-default
  values suppressed to keep output compact. argRE parses positional
  arg placeholders from cobra Use strings, filtering [flags]/[options]/
  [command] cobra conventions. parseExamples splits cmd.Example by
  newline, drops blanks and # comments. MaxDepth maps to spec §4
  semantics: 0 = subcommand list, 1 = + grandchildren, -1 = unlimited.

- cmd/pad/help_cmdhelp.go — replaces emitCmdhelpJSON stub with a call
  into the package; threads --depth and --all through MaxDepth (--all
  overrides --depth).

Verification:
- 17 emitter tests in internal/cmdhelp/json_test.go covering envelope,
  global-flag emission, hidden-thing exclusion, positional arg parsing,
  pflag type mapping, zero-default suppression, example parsing,
  description-vs-summary, command-path key shape, MaxDepth semantics,
  target-subtree scoping, JSON validity, version pattern, ExitCode
  union marshaling, parseExamples filtering.
- 11 cmd/pad routing tests still pass; TestHelpCmd_FormatJSONStubError
  replaced by TestHelpCmd_FormatJSONEmits which validates the structure.
- End-to-end: `pad help --format json` on the real binary emits 100
  commands across the full tree; output validates against
  schema/cmdhelp.schema.json (verified with python jsonschema).
- `pad help item --format json` correctly limits output to 29 commands
  in the item subtree (homepage and other top-level metadata still
  populated from root).
- `pad help --format json --depth 0` correctly emits 15 immediate
  children of root, no grandchildren.
- make check clean (lint + go test + web build).

Out of scope (deferred):
- Examples: pad's existing commands embed examples in Long rather than
  using cobra's Example field. The emitter correctly reads Example;
  TASK-939 will normalize the pad-side commands to populate it.
- Dynamic enum injection (workspace-aware enums): TASK-936.
- --capabilities discovery flag: TASK-937.
- Schema-validation of live output in CI: TASK-938.

Parent: PLAN-930.

* fix(cmdhelp): handle alternation, variadic, and ValidArgs in Use parser per Codex review (round 1)

Codex round 1 on PR #327 flagged that parseArgs missed two real cobra
Use-string idioms in pad's command tree:

1. `completion [bash|zsh|fish|powershell]` — alternation in brackets.
   The old regex only allowed `[a-zA-Z0-9_./-]+` inside brackets, so the
   `|` made the whole token unmatched and the shell arg disappeared from
   the emitted JSON. Consumers asking "what does completion take?" got
   nothing.

2. `item bulk-update [--status X] <ref>...` — variadic ellipsis. Old
   regex didn't capture trailing `...`, so the arg was emitted but
   without `repeatable: true`. Consumers couldn't tell that <ref> may
   be passed multiple times.

Fixes:

- argRE now allows full-bracket content (`[^<>]+` / `[^\[\]]+`) and
  captures an optional trailing `...` group.
- parseArgs takes *cobra.Command (not just Use string) so it can read
  cmd.ValidArgs and attach those values as the first arg's enum when
  set. This covers `Use: "completion [shell]"` + `ValidArgs: [...]`
  where the allowed values only live on the cobra struct.
- Alternation `<a|b|c>` / `[a|b|c]` produces an enum-typed arg with
  the values as `Enum`. When Use carries no semantic name (only the
  alternation), the arg name is synthesized as "value".
- New validArgName check rejects embedded flag-like fragments such as
  `[--status X]` and prose with whitespace/punctuation that the broader
  regex would otherwise capture from idiosyncratic Use strings.
- ValidArgs entries strip cobra's tab-separated completion descriptions
  before becoming enum values.

New tests:

- TestBuild_VariadicArgsRepeatable — `<ref>...` → repeatable=true.
- TestBuild_AlternationProducesEnum — `[bash|zsh|fish|powershell]` →
  enum with values in source order.
- TestBuild_ValidArgsFillsEnumOnNamedArg — Use says `[shell]`, ValidArgs
  carries the values → enum-typed arg named `shell`.
- TestBuild_EmbeddedFlagFragmentsFiltered — `[--status X]` does not
  leak as a positional arg.

Verified on the real binary:
- `pad help completion --format json` now emits the shell enum.
- `pad help item bulk-update --format json` now marks <ref> repeatable.
- `pad help --format json` still validates against the schema (100 cmds).
- `make check` clean.
2026-05-01 00:56:50 -04:00
..