fix: show subcommand-specific help for gsd <sub> --help#3444
fix: show subcommand-specific help for gsd <sub> --help#3444murataslan1 wants to merge 4 commits intogsd-build:mainfrom
gsd <sub> --help#3444Conversation
--help was caught during arg parsing and exited immediately, before the subcommand name could be collected. Defer the flag and check for a matching subcommand after parsing completes. Fixes gsd-build#3423
🟡 PR Risk Report — MEDIUM
Affected Systems
File Breakdown
|
There was a problem hiding this comment.
Pull request overview
This PR fixes CLI help behavior so gsd <subcommand> --help (and -h) can display subcommand-specific help by deferring --help handling until after the subcommand is identified.
Changes:
- Change arg parsing to record
--help/-hinstead of exiting immediately during parsing. - Add centralized post-parse help handling that attempts subcommand help first and falls back to top-level help.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!subcommand || !printSubcommandHelp(subcommand, process.env.GSD_VERSION || '0.0.0')) { | ||
| printHelp(process.env.GSD_VERSION || '0.0.0') | ||
| } | ||
| process.exit(0) |
There was a problem hiding this comment.
Help handling now runs after the non-TTY (stdin) gate. This introduces a regression where gsd --help / gsd -h will exit with the interactive-mode TTY error when stdin is not a TTY (e.g., in some CI/piped contexts), instead of printing help. Consider moving the cliFlags.help handling above the TTY gate, or updating the gate condition to exempt cliFlags.help.
|
Good catch — fixed in the latest commit. The dispatch is now moved above the TTY gate so GSD v2.4.0 — Get Shit Done Usage: gsd [options] [message...] Options: Subcommands: |
trek-e
left a comment
There was a problem hiding this comment.
Fixes #3423. CI passes (classify check). Implementation is correct.
The refactor moves help handling before the TTY gate, which is the right approach — it fixes 'gsd --help' in non-interactive contexts (pipes, CI). The logic is straightforward: defer process.exit from parseCliArgs, then handle help as a top-level check before the TTY guard.
The test update in e2e-smoke.test.ts correctly relaxes the headless assertion (removing the 'Usage:' check that relied on the old behavior) and the config assertion now accepts either 'Usage:' or 'config' in the output — appropriate given subcommand-specific help may or may not include 'Usage:' literally.
Approved.
trek-e
left a comment
There was a problem hiding this comment.
PR #3444 — fix: show subcommand-specific help for gsd <sub> --help
Verdict: APPROVE
Severity: MINOR (noted, not blocking)
What was fixed
The original parseCliArgs() called printHelp() + process.exit(0) immediately on --help, before the subcommand argument had been collected. This PR defers that to a flags.help boolean and handles it after parsing completes, enabling printSubcommandHelp(subcommand) to run when a subcommand precedes --help.
The logic is correct. Fallback to main help when printSubcommandHelp returns falsy is appropriate.
MINOR: Test assertion weakened in e2e-smoke.test.ts
// Before:
assert.ok(output.includes("Usage:"), ...);
// After:
assert.ok(output.includes("Usage:") || output.includes("config"), ...);The || output.includes("config") branch is so broad that it would pass if the word "config" appears anywhere in the output, including error messages. The intent is to verify meaningful help content was printed. If printSubcommandHelp("config") exists and produces consistent output, assert against a known string from that output instead.
MINOR: -h short form now deferred but test plan doesn't cover -h <subcommand>
The diff correctly defers -h alongside --help. The test plan mentions gsd -h shows main help, but doesn't cover gsd sessions -h (short-form with subcommand). Worth adding.
No security or correctness concerns
No argument injection surface — subcommand is taken from cliFlags.messages[0] (already parsed argv) and passed only to printSubcommandHelp which does a string lookup, not a shell exec.
PASS on the fix itself. The weakened test assertion is worth tightening before merge but is not a blocker.
Summary
--helpwas caught during arg parsing and exited immediately, before the subcommand could be identifiedFixes #3423
Test plan
gsd sessions --helpshows sessions help (not main help)gsd worktree --helpshows worktree helpgsd wt --helpshows worktree help (alias)gsd headless --helpshows headless helpgsd --helpstill shows main helpgsd -hstill shows main helpgsd nonexistent --helpfalls back to main help