--help prints the usage and never runs the command - #15
Merged
Merged
Conversation
Most subcommands ignored --help / -h and ran anyway: `skillhook jobs prune --help`
pruned jobs, `service install --help` installed the service, `config set ... --help`
wrote the config. 0.6.0 fixed this only for `skillhook cloud`.
main.ts now handles --help / -h (and `skillhook help <command>`) before any command
code runs, printing the usage that COMMANDS pairs with every command, so a new
command cannot forget it; --json prints { ok, command, usage }. The per-command
checks in cloud.ts and update.ts are gone. serve, doctor, health, runners, mcp and
url gained a usage text, and `job <subcommand> --help` follows jobCommand's dispatch
(the agent's job API, or `jobs` for the rest). Each command's USAGE is now an
exported <NAME>_USAGE, like INIT_USAGE and UPDATE_USAGE already were.
src/cli.test.ts runs every COMMANDS entry and every subcommand with --help,
-h --json and `help <command>` against a tempHome() and asserts exit 0, the usage
on stdout, nothing on stderr, no stdin read and an unchanged home (every file with
its mtime and content). The service and Tailscale mutators are stubbed for the
file, so a regression can never reach the real launchd/systemd or Funnel.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A safety fix: most subcommands ignored
--help/-hand did their work anyway.0.6.0 (#14) fixed this for
skillhook cloud <subcommand> --helponly, insidecloud.ts.The fix: one check, before any command runs
COMMANDSinsrc/commands/main.tsnow pairs every command with its usage ({ run, usage }), andmain()checks--help/-hright after resolving the command, before any command code runs. It prints the usage and exits 0. A new command cannot be registered without a usage, and cannot forget the check.skillhook help <command> [subcommand]does the same thing (skillhook helpalone still prints the overview).--jsonprints{ "ok": true, "command": "jobs", "usage": "…" }.cloud.tsandupdate.tsare gone, because the central one covers them.serve,doctor,health,runners,mcpandurlhad no usage text and now have one.init's usage now lists--runner shell, which the command already accepted.skillhook job <subcommand> --helpfollowsjobCommand's dispatch. The agent subcommands (progress|ask|outcome|note|context, or no subcommand) print the job API usage. Everything else (job list,job prune, …) is reallyjobs …, so it prints thejobsusage.USAGEbecame an exported<NAME>_USAGE, asINIT_USAGEandUPDATE_USAGEalready were. Most of the diff insrc/commands/*.tsis this mechanical rename.The test (
src/cli.test.ts)It runs every entry of
COMMANDSand every subcommand in three forms:… --help,… -h --jsonandhelp …. That is about 400 invocations, against atempHome()set up so that each line has something to act on: a job to prune or answer, a delivery to replay, secrets and config to change, a linked project, a scheduled skill and a stored API key. Every invocation must:The table must also cover every subcommand the usage texts document (
skillhook jobs prune …,skillhook projects add|remove …), and everyCOMMANDSkey (aliases reuse their command's lines). As a control, the samejobs pruneline without--helpdoes prune, and the snapshot shows it.It is hermetic even if the fix regresses. The env sets
SKILLHOOK_NO_UPDATE_CHECK=1, unreachable registry and cloud URLs,SKILLHOOK_NO_CLOUD=1and fake claude/codex.installService,uninstallService,restartService,enableExposureanddisableExposureare stubbed withvi.mockfor this file, so a broken check can never touch the real launchd/systemd service or Tailscale Funnel. The test asserts none of them was called.I checked that the test catches the bug. With the check skipped for
jobs, it fails onexpected 'Removed 1 old job(s)' to contain 'skillhook jobs prune [--keep N]'. With a stray file write added to the help path, the snapshot names the line and shows the new file. With a subcommand missing from the table, it fails onskillhook jobs prune --help: expected [...] to include 'prune'. The whole test takes about 0.3 s.npm run checkpasses: typecheck, 280 tests, build, schema and release metadata. CHANGELOG has an## Unreleasedentry. README (global options) and AGENTS.md (registering a command) mention the new rule.🤖 Generated with Claude Code