Skip to content

fix: respect --json flag on --help for root and groups#373

Merged
MattDevy merged 2 commits into
mainfrom
claude/hardcore-jepsen-85c4e4
May 28, 2026
Merged

fix: respect --json flag on --help for root and groups#373
MattDevy merged 2 commits into
mainfrom
claude/hardcore-jepsen-85c4e4

Conversation

@MattDevy

Copy link
Copy Markdown
Contributor

Summary

elastic --help --json (and elastic <group> --help --json) was printing plain text help instead of respecting the --json flag. Only leaf commands ran their help through the JSON-aware formatter, and even there the detection used thisCmd.parent?.optsWithGlobals(), which returns undefined for the root program.

What changed

  • New helpers in src/factory.ts:
    • hasGlobalJsonFlag(cmd) walks up to the root and reads its --json opt, so detection works uniformly for root, groups, and leaves.
    • formatHelpAsJson(cmd) serialises name, description, usage, visible options, and visible sub-commands.
    • Exported configureJsonHelp(cmd) hooks Commander's help formatter and falls back to text help when --json is not set.
  • defineGroup now calls configureJsonHelp so every group inherits the behaviour.
  • src/cli.ts calls configureJsonHelp(program) on the root program.
  • Existing leaf-command behaviour is preserved: commands with an input Zod schema continue to emit that schema; commands without one still emit empty output (existing contract covered by test/factory.test.ts).

Tests

Added a new elastic CLI -- --help --json suite in test/cli.test.ts:

  • elastic --help --json returns structured JSON with name, options, and commands.
  • Flag order (--json --help) also works.
  • elastic --help (no --json) still emits plain text.
  • elastic sanitize --help --json returns JSON for a group.

Updated the export-surface assertion in test/factory.test.ts to include the new configureJsonHelp export.

Test plan

  • npm run build
  • node --import tsx/esm --test test/cli.test.ts (30 pass, including 4 new)
  • node --import tsx/esm --test test/factory.test.ts (268 pass)
  • npm run test:lint
  • Manual verification:
    • elastic --help --json → JSON
    • elastic --json --help → JSON
    • elastic --help → text (unchanged)
    • elastic sanitize --help --json → JSON
    • elastic cli-schema --help --json → empty (unchanged leaf-without-input-schema contract)

Commander's help formatter was only configured for leaf commands, and the
leaf-level JSON detection used thisCmd.parent?.optsWithGlobals(), which
returns undefined for the root program. As a result, `elastic --help --json`
and `elastic <group> --help --json` printed plain text instead of JSON.

Add a unified hasGlobalJsonFlag() helper that walks to the root, a
formatHelpAsJson() serialiser, and an exported configureJsonHelp() that
hooks into Commander's help formatter. Apply it to the root program and to
every group built via defineGroup. Existing leaf-command behaviour (input
JSON Schema for commands with an input schema, empty otherwise) is
preserved.

Add regression tests covering root --help --json, flag order, the negative
case (text help when --json is absent), and group --help --json.
@github-actions

github-actions Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

MegaLinter analysis: Success

Descriptor Linter Files Fixed Errors Warnings Elapsed time
✅ COPYPASTE jscpd yes no no 10.27s
✅ REPOSITORY gitleaks yes no no 62.01s
✅ REPOSITORY git_diff yes no no 0.79s
✅ REPOSITORY secretlint yes no no 39.06s
✅ REPOSITORY trivy yes no no 20.33s
✅ TYPESCRIPT eslint 4 0 0 6.37s

Notices

📣 MegaLinter 9.5.0 is out! Discover the new features and security recommendations in the release announcement. (Skip this info by defining SECURITY_SUGGESTIONS: false)

See detailed reports in MegaLinter artifacts
Set VALIDATE_ALL_CODEBASE: true in mega-linter.yml to validate all sources, not only the diff

MegaLinter is graciously provided by OX Security
Show us your support by starring ⭐ the repository

CI flagged branch coverage at 89.99% (threshold 90%) and a stale NOTICE.txt
left over from the yaml@2.9.0 bump in main.

- Add focused unit tests for `configureJsonHelp` covering the JSON/text
  paths, mandatory options, string/number/boolean defaults, hidden options
  and commands, sub-command aliases, the auto-added `help` command filter,
  and the group-via-parent-walk case.
- Drop dead `?? ''` fallbacks on Commander's `description` (it's always a
  string) and a redundant `dv !== undefined` short-circuit in
  `formatHelpAsJson` to keep branch coverage above threshold.
- Regenerate NOTICE.txt so the yaml entry matches the installed version.
@MattDevy MattDevy marked this pull request as ready for review May 28, 2026 09:34

@Anaethelion Anaethelion left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@MattDevy MattDevy merged commit 2297c98 into main May 28, 2026
33 of 36 checks passed
@MattDevy MattDevy deleted the claude/hardcore-jepsen-85c4e4 branch May 28, 2026 09:50
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.

2 participants