Skip to content

bin/vh <command> -h prints its usage instead of running the command - #50

Merged
ZLHad merged 4 commits into
mainfrom
claude/subcommand-help
Oct 2, 2026
Merged

ZLHad merged 4 commits into
mainfrom
claude/subcommand-help

Conversation

@ZLHad

@ZLHad ZLHad commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Why

bin/vh sheet -h failed with basename: illegal option -- h. Review found the same class of bug across the CLI: -h and --help reached the command as an ordinary argument.

command before (main) after
setup -h ran the whole install (npm install, references/fetch.sh, the swatch renderer) header usage, exit 0
sync-agents -h rewrote AGENTS.md header usage, exit 0
doctor -h, types -h ran as usual header usage, exit 0
sheet -h basename error, exit 1 header usage, exit 0
check -h ffprobe's own help header usage, exit 0
gif -h ffmpeg Unrecognized option 'h.gif', exit 8 header usage, exit 0
hf-init -h no such project: -h, exit 1 header usage, exit 0
mux -h bash line 573: 2: usage: …, exit 1 header usage, exit 0
beats -h libsndfile error opening -h, exit 1 header usage, exit 0
qa -h / qa --help / qa mix -h JSONDecodeError traceback / the docstring with exit 1 / qa mix: no such folder: -h, exit 1 the docstring (78 lines), exit 0
style -h checked the swatch renderer's npm install, then printed render.sh's help header usage (now with a pointer to render.sh -h), exit 0
style check -h reached determinism.sh as a preset name its own usage line, exit 0
new, effort, install-skill, music with -h a usage, but exit 1 (music --help: "unknown option") header usage, exit 0
tts -h built the mlx-audio environment, then argparse's help header usage + tts.py's option list via the plain python3, exit 0, nothing installed
sfx, captions, readcheck, review, storyboard, rhythm, cover-preview, voices, mix, recipes their own help unchanged

Changes

  • bin/vh: before dispatch, bin/vh <command> -h|--help prints that command's lines from the help header at the top of bin/vh (cmd_usage, continuation lines included) and exits 0. The header already lists every command and its arguments, so this usage cannot drift from bin/vh help. Commands with a fuller help of their own (the last row, plus qa) keep it. An unknown command with -h still exits 1; without -h, every command behaves as before. cmd_usage reads the name through ENVIRON, since awk -v expands backslashes.
  • tools/audio/qa.py: -h or --help anywhere in the arguments prints the docstring and exits 0.
  • tools/ci.sh: the smoke test reads the list of dispatched commands from bin/vh, drops the own-help list (and fails if that list names a command that is not dispatched), then runs -h and --help for the remaining 16 and for style check. It expects exit 0 and output starting with usage: bin/vh <command> . It runs on a copy of bin/vh in a temp folder whose only content is a link to tools/, with uv and npm stubbed out on PATH, so nothing is downloaded and if the check ever regressed, setup would stop at its first cd and sync-agents would write the temp folder's AGENTS.md. I checked this with main's bin/vh: the real AGENTS.md was unchanged.
  • CHANGELOG.md: an entry.

Four commits. The first fixed six commands one at a time. The second moved the check into the dispatcher after the review found the rows above. The third keeps the fuller help of sfx, qa and tts and makes the CI test safe and complete, after the second review. The fourth stubs uv and npm in that test and loosens its command-count floor, after the third review (approve).

Checked

  • tools/ci.sh and VH_BASH=/bin/bash tools/ci.sh --committed (bash 3.2, clean checkout of HEAD): all checks passed.
  • By hand, each row of the table; bin/vh nosuch -h and bin/vh 'ne\w' -h exit 1; bin/vh -h and bin/vh help -h print the full help.
  • Second review: cmd_usage gives identical output on macOS awk, mawk and BusyBox awk; 51 invocations without -h match main under both bashes.

Not changed

  • I first suspected that styles/product-keynote/STYLE.md cites lemo-opuscar under the wrong licence (CC BY 4.0, while the current LICENSE is MIT). It is correct as written: the preset was adapted on 2026-09-29 from the snapshot before the MIT switch, and references/community-skills.md says such adaptations keep their CC BY attribution, as 22 other presets do.
  • Pre-existing, left alone: hf-init passes its resolution to hyperframes init unchecked, so a typo reports "init failed (offline?)"; sheet on a missing video creates out/check/ next to it and shows a Python traceback; bin/vh tts <project> -h takes -h as the provider.

ZLHad added 2 commits October 2, 2026 15:39
These took -h as a video, project or preset name: sheet failed in
basename, check printed ffprobe's help, gif failed in ffmpeg, hf-init
said no such project, mux printed a bash parameter error, and style
printed render.sh's help after checking the swatch renderer's npm
install. Each now prints its own usage line and exits 0 for -h and
--help; CI checks all six.
The first commit fixed six commands one by one. The review found that
-h was still passed through elsewhere: setup -h ran the whole install,
sync-agents -h rewrote AGENTS.md, beats and qa took -h as an audio
file or mix, style check -h reached determinism.sh, and new, effort,
install-skill, music and sfx exited 1. The dispatcher now prints the
command's lines from the help header for -h and --help and exits 0;
captions, readcheck, review, storyboard, rhythm, cover-preview, voices,
mix and recipes keep their own help. The per-command edits are gone.
@ZLHad ZLHad changed the title -h prints the usage for sheet, check, gif, hf-init, mux and style bin/vh <command> -h prints its usage instead of running the command Oct 2, 2026
ZLHad added 2 commits October 2, 2026 16:16
Second review: sfx -h already printed its full docstring and exited 0,
and tts and qa have fuller help than the header's lines, so sfx and qa
pass through again (qa now prints its docstring for -h or --help, also
qa mix -h, and exits 0) and tts -h prints the header lines plus
tts.py's option list, read with the plain python3 so nothing is
installed. The CI test now reads the command list from the dispatch,
so a new command without a header line is caught, and runs on a copy
of bin/vh in a temp folder, so a regression cannot run setup or
rewrite AGENTS.md. cmd_usage reads the name through ENVIRON (awk -v
expands backslashes), and the header's style entry points to
render.sh -h.
Third review: with HOME in the temp folder, a broken check would still
let uv build mlx-audio or librosa there, and the floor of 15 commands
sat one below today's 16, so moving one more command onto the own-help
list would have failed the test for nothing.
@ZLHad
ZLHad marked this pull request as ready for review October 2, 2026 08:35
@ZLHad
ZLHad enabled auto-merge (squash) October 2, 2026 08:35
@ZLHad
ZLHad merged commit 7057c74 into main Oct 2, 2026
2 checks passed
@ZLHad
ZLHad deleted the claude/subcommand-help branch October 2, 2026 08:36
ZLHad added a commit that referenced this pull request Oct 2, 2026
…he READMEs (#51)

* Docs: counts and wording after #41–#50; a Blender section in the README; Blender large-scene notes

- overview/architecture SVGs, CITATION.cff, recipes/README: 31 styles, 13 playbook docs, 30 reference repos, 9 types
- README (en/zh): styles are references, not templates; quick's checks; concept cards in the FAQ; research note 06;
  the reel is 46 s; the bin/vh table lists new flags, style compare/apply, storyboard/rhythm/cover-preview
- README: code-driven Blender as a feature (badge, a bullet, a section)
- engines/blender.md: lessons from the intro film's opening (numpy-driven point clouds, velocity motion blur,
  no denoiser on stars, camera up vector, nodexpr, chunked resumable renders, Metal determinism)
- styles/_swatch/lib.js: color(tokens, 'fg') falls back to ink/text before magenta (pastel-ui names its foreground ink)
- showcase 00/01 READMEs: mix figures re-measured after the #40 sound refresh; build_audio.sh comments: 21 built-ins

* Intro film v5: a Blender galaxy opening, 150.5 s, and HD players in the READMEs

- showcase/04-intro-film is now v5: 0–15.8 s rendered in Blender (Cycles, a galaxy of films),
  the rest in HyperFrames + Three.js, one camera handed across the dissolve. v3 moves to v3/.
- The film follows one request (showcase 02's question) through the router, the gates and the
  self-review loop to the finished short. A time map (js/tmap.js) lengthens holds so every line
  meets the reading-time floor; the score is retimed with the same map.
- READMEs: the samples play inline (GitHub user-attachments, 1080p, a small corner mark); the
  intro plays as eight chapters. Each sample links its original file.
- Lessons into playbook/02 and 08, engines/blender.md, recipes; CHANGELOG entry.

* Intro v5: fixes from review — shellcheck, the beat map, a reproducible Reproduce block

- tools/deliver.sh and tools/build_audio.sh pass shellcheck; deliver.sh drops the unused 720p clip and WebP preview and
  cuts the eight README chapters instead (tools/chapters.sh, tools/watermark.sh, now in the repo).
- audio/music.beats.json (the body score's beat map, which js/main.js reads for its pulses) is committed; rendering
  audio/score.base.json reproduces it byte for byte, and a missing map now logs a warning instead of failing silently.
- Reproduce: npm i (no lockfile), the shader export before the atlases, film_atlas.py pinned to the 41 rows the film
  was made with (the rebuilt films.jpg is byte-identical), Blender steps marked macOS only (bl.sh says so and exits).
- The hand-over is 15.0–15.6 s everywhere; the Blender determinism figures say which plate they are from; the asset
  ledger covers the AI stills, atlases and v5 audio; showcase docs use showcase paths (NOTES says it is a log).
- README chapter thumbnails: chapters 2–8 re-uploaded without a picture fade-in (frame 0 is the player's thumbnail);
  the 04 cell says it plays chapter 5; exact chapter ranges; the clone is about 530 MB now.

* Intro v5: cut the README chapters after the final check; chapters.sh is executable
ZLHad added a commit that referenced this pull request Oct 4, 2026
)

* -h prints the usage for sheet, check, gif, hf-init, mux and style

These took -h as a video, project or preset name: sheet failed in
basename, check printed ffprobe's help, gif failed in ffmpeg, hf-init
said no such project, mux printed a bash parameter error, and style
printed render.sh's help after checking the swatch renderer's npm
install. Each now prints its own usage line and exits 0 for -h and
--help; CI checks all six.

* Answer -h at the dispatcher for every command without its own help

The first commit fixed six commands one by one. The review found that
-h was still passed through elsewhere: setup -h ran the whole install,
sync-agents -h rewrote AGENTS.md, beats and qa took -h as an audio
file or mix, style check -h reached determinism.sh, and new, effort,
install-skill, music and sfx exited 1. The dispatcher now prints the
command's lines from the help header for -h and --help and exits 0;
captions, readcheck, review, storyboard, rhythm, cover-preview, voices,
mix and recipes keep their own help. The per-command edits are gone.

* Keep sfx, qa and tts's full help; run the -h test on a copy

Second review: sfx -h already printed its full docstring and exited 0,
and tts and qa have fuller help than the header's lines, so sfx and qa
pass through again (qa now prints its docstring for -h or --help, also
qa mix -h, and exits 0) and tts -h prints the header lines plus
tts.py's option list, read with the plain python3 so nothing is
installed. The CI test now reads the command list from the dispatch,
so a new command without a header line is caught, and runs on a copy
of bin/vh in a temp folder, so a regression cannot run setup or
rewrite AGENTS.md. cmd_usage reads the name through ENVIRON (awk -v
expands backslashes), and the header's style entry points to
render.sh -h.

* CI -h test: stub uv and npm, loosen the command-count floor

Third review: with HOME in the temp folder, a broken check would still
let uv build mlx-audio or librosa there, and the floor of 15 commands
sat one below today's 16, so moving one more command onto the own-help
list would have failed the test for nothing.
ZLHad added a commit that referenced this pull request Oct 4, 2026
…he READMEs (#51)

* Docs: counts and wording after #41–#50; a Blender section in the README; Blender large-scene notes

- overview/architecture SVGs, CITATION.cff, recipes/README: 31 styles, 13 playbook docs, 30 reference repos, 9 types
- README (en/zh): styles are references, not templates; quick's checks; concept cards in the FAQ; research note 06;
  the reel is 46 s; the bin/vh table lists new flags, style compare/apply, storyboard/rhythm/cover-preview
- README: code-driven Blender as a feature (badge, a bullet, a section)
- engines/blender.md: lessons from the intro film's opening (numpy-driven point clouds, velocity motion blur,
  no denoiser on stars, camera up vector, nodexpr, chunked resumable renders, Metal determinism)
- styles/_swatch/lib.js: color(tokens, 'fg') falls back to ink/text before magenta (pastel-ui names its foreground ink)
- showcase 00/01 READMEs: mix figures re-measured after the #40 sound refresh; build_audio.sh comments: 21 built-ins

* Intro film v5: a Blender galaxy opening, 150.5 s, and HD players in the READMEs

- showcase/04-intro-film is now v5: 0–15.8 s rendered in Blender (Cycles, a galaxy of films),
  the rest in HyperFrames + Three.js, one camera handed across the dissolve. v3 moves to v3/.
- The film follows one request (showcase 02's question) through the router, the gates and the
  self-review loop to the finished short. A time map (js/tmap.js) lengthens holds so every line
  meets the reading-time floor; the score is retimed with the same map.
- READMEs: the samples play inline (GitHub user-attachments, 1080p, a small corner mark); the
  intro plays as eight chapters. Each sample links its original file.
- Lessons into playbook/02 and 08, engines/blender.md, recipes; CHANGELOG entry.

* Intro v5: fixes from review — shellcheck, the beat map, a reproducible Reproduce block

- tools/deliver.sh and tools/build_audio.sh pass shellcheck; deliver.sh drops the unused 720p clip and WebP preview and
  cuts the eight README chapters instead (tools/chapters.sh, tools/watermark.sh, now in the repo).
- audio/music.beats.json (the body score's beat map, which js/main.js reads for its pulses) is committed; rendering
  audio/score.base.json reproduces it byte for byte, and a missing map now logs a warning instead of failing silently.
- Reproduce: npm i (no lockfile), the shader export before the atlases, film_atlas.py pinned to the 41 rows the film
  was made with (the rebuilt films.jpg is byte-identical), Blender steps marked macOS only (bl.sh says so and exits).
- The hand-over is 15.0–15.6 s everywhere; the Blender determinism figures say which plate they are from; the asset
  ledger covers the AI stills, atlases and v5 audio; showcase docs use showcase paths (NOTES says it is a log).
- README chapter thumbnails: chapters 2–8 re-uploaded without a picture fade-in (frame 0 is the player's thumbnail);
  the 04 cell says it plays chapter 5; exact chapter ranges; the clone is about 530 MB now.

* Intro v5: cut the README chapters after the final check; chapters.sh is executable
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.

1 participant