Skip to content

fix: show subcommand-specific help for gsd <sub> --help#3444

Open
murataslan1 wants to merge 4 commits intogsd-build:mainfrom
murataslan1:fix/subcommand-help-dispatch
Open

fix: show subcommand-specific help for gsd <sub> --help#3444
murataslan1 wants to merge 4 commits intogsd-build:mainfrom
murataslan1:fix/subcommand-help-dispatch

Conversation

@murataslan1
Copy link
Copy Markdown
Contributor

Summary

  • --help was caught during arg parsing and exited immediately, before the subcommand could be identified
  • Now defers the flag and checks for a matching subcommand after parsing completes
  • Falls back to main help when no subcommand is given or the subcommand has no dedicated help

Fixes #3423

Test plan

  • gsd sessions --help shows sessions help (not main help)
  • gsd worktree --help shows worktree help
  • gsd wt --help shows worktree help (alias)
  • gsd headless --help shows headless help
  • gsd --help still shows main help
  • gsd -h still shows main help
  • gsd nonexistent --help falls back to main help

--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
Copilot AI review requested due to automatic review settings April 3, 2026 12:27
@github-actions github-actions bot added bug Something isn't working High Priority labels Apr 3, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

🟡 PR Risk Report — MEDIUM

Files changed 2
Systems affected 1
Overall risk 🟡 MEDIUM

Affected Systems

Risk System
🟡 medium CLI
File Breakdown
Risk File Systems
🟡 src/cli.ts CLI
src/tests/integration/e2e-smoke.test.ts (unclassified)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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/-h instead 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.

Comment thread src/cli.ts Outdated
Comment on lines +171 to +189
if (!subcommand || !printSubcommandHelp(subcommand, process.env.GSD_VERSION || '0.0.0')) {
printHelp(process.env.GSD_VERSION || '0.0.0')
}
process.exit(0)
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
@murataslan1
Copy link
Copy Markdown
Contributor Author

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:
--mode <text|json|rpc> Output mode (default: interactive)
--print, -p Single-shot print mode
--model Override model (e.g. claude-opus-4-6)
--no-session Disable session persistence
--extension Load additional extension
--tools <a,b,c> Restrict available tools
--version, -v Print version and exit
--help, -h Print this help and exit

Subcommands:
config Re-run the setup wizard and work correctly in non-TTY contexts (pipes, CI, etc.).

Copy link
Copy Markdown
Collaborator

@trek-e trek-e left a comment

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator

@trek-e trek-e left a comment

Choose a reason for hiding this comment

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

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working High Priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: gsd <subcommand> --help does not give help for the subcommand

3 participants