fix(cli): restore hyperframes capture <url>; move video download to --video flag#1475
Merged
Conversation
… `--video` flag PR #1447 added `capture video` as a citty subCommand. citty's runCommand (node_modules/.bun/citty@0.2.2/.../dist/index.mjs:209-227) treats any non-flag positional as a subcommand-name attempt and throws E_UNKNOWN_COMMAND when it doesn't match — there's no fallback to the parent's positional args, so `hyperframes capture https://vercel.com` died with "Unknown command https://vercel.com". Per James's suggestion, surface video-download as `capture --video <project>` (a mode flag) instead of a subcommand. Citty has no issue with a positional URL coexisting with flags. `video.ts` now exports `runVideoMode()` instead of a `defineCommand` default export. - `hyperframes capture <url>` works again - `hyperframes capture --video <project> --index N` downloads video - `hyperframes capture --video <project> --list` lists manifest - `hyperframes capture --video <project> --video-url <url>` downloads by URL
miguel-heygen
approved these changes
Jun 15, 2026
miguel-heygen
left a comment
Collaborator
There was a problem hiding this comment.
Strengths:
capture.ts:73–81— the dispatch logic is crisp: oneif (args.video)guard, clean import, early return. Dead simple to follow.video.ts— the// fallow-ignore-next-line complexitydirective moved correctly to the exported function (line 171). Byte-identical logic preservation is well-executed.--video-urlnaming (instead of--url) is the right call; the PR body correctly explains citty's rejection of name collisions.
Review:
No blockers found.
- nit
capture.ts:62— the"video-url"description says "Pair with --index, --video-url, or --list" (redundant self-reference). Minor copy issue. - nit
video.ts:176–178—VideoModeArgs.urlfield comment says "Exact video URL… (must match a manifest entry)" but that phrasing was already in the old subcommand. No need to address; just noting it's preserved as-is.
CI: All required checks green. Windows jobs (Render, Tests) pass on main — the two pending entries in CI are unrelated infra jobs that pass on main. regression-shards is skipping (expected for a CLI-only diff). No CI concerns.
Audited: packages/cli/src/commands/capture.ts (full), packages/cli/src/commands/capture/video.ts (full), packages/cli/src/commands/capture/video.test.ts (grep-audited for test coverage of renamed exports).
Verdict: APPROVE
Reasoning: Clean refactor — subcommand replaced by mode flag, all 22 unit tests pass, CLI smoke passes, behavior preserved byte-for-byte. The citty root-cause analysis is correct and the fix is minimal.
— Magi (AI reviewer)
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.
What
Restore
hyperframes capture <url>(broken in v0.6.99) by replacing thecapture videosubcommand from #1447 with a--video <project>mode flag on the parentcapturecommand.Why
PR #1447 made video-download a citty subcommand of capture. citty's
runCommand(dist/index.mjs:209-227) treats any non-flag positional as a subcommand-name attempt and throwsE_UNKNOWN_COMMANDwhen it doesn't match — there's no fallback to the parent's positional args. Sohyperframes capture https://vercel.comdied withUnknown command https://vercel.com. Verified against a minimal repro of citty 0.2.2.Per James's suggestion on #1447, expose video-download as a mode flag instead. Citty has no issue with a positional URL coexisting with flags, so both surfaces work side-by-side.
How
subCommands+ the parent-run guard from packages/cli/src/commands/capture.ts; make theurlpositionalrequired: false.--video,--index,--list,--video-urlflags to capture. (--video-urlinstead of--urlbecause the parent already has aurlpositional and citty rejects name collisions.)runVideoMode(args)instead of adefineCommanddefault. All pure helpers (safeFilename,streamToFile,pickManifestEntry,findFilenameCollision, content-type whitelist, 250MB cap) are byte-identical.run()dispatches onargs.video: if set, callrunVideoModeand return; otherwise treatargs.urlas the website URL.Test plan
video.test.tscontinue to pass (they cover pure helpers, not the citty wrapper); 843 CLI tests pass.hyperframes capture https://example.com -o /tmp/foo— works (was broken)hyperframes capture --video <proj> --list— lists 9 entrieshyperframes capture --video <proj> --index 1— downloads 1.8MBhyperframes capture --video <proj> --index 1(re-run) — EEXIST skiphyperframes capture --video <proj> --index 999— rejects with available indiceshyperframes capture(no args) —Missing URL+ exit 1bunx oxlintcleanbunx oxfmt --checkclean