Skip to content

fix(cli): parse capture and grade-compare --timeout as a duration - #7715

Merged
jrusso1020 merged 1 commit into
heygen-com:mainfrom
shurtado24:fix/timeout-parsing
Nov 14, 2026
Merged

jrusso1020 merged 1 commit into
heygen-com:mainfrom
shurtado24:fix/timeout-parsing

Conversation

@shurtado24

Copy link
Copy Markdown
Contributor

What

capture --timeout and grade-compare --timeout now accept a duration such as 30s or 2m, as check and snapshot already do. A value that is not a duration now prints a warning and uses the command's default.

# before
capture --timeout 1s          → 1 ms page-load timeout
grade-compare --timeout abc   → 5000 ms, no warning
# after
capture --timeout 1s          → 1000 ms
grade-compare --timeout abc   → 5000 ms, warns: --timeout "abc" is not a duration; using 5000 ms.

Why

Both commands read --timeout with their own parseInt. That turned 1s into 1 ms in capture, and it threw away invalid input in grade-compare without saying so. The shared parseTimeoutMs helper already handles units and warnings for check and snapshot.

Related work

Fixes #7671

How

  • packages/cli/src/commands/capture.ts: parseTimeoutMs(args.timeout, DEFAULT_CAPTURE_TIMEOUT_MS). The default stays 120000 ms. The CLI now passes it explicitly, where before it passed undefined and captureAttempt filled in the same value.
  • packages/cli/src/commands/grade-compare.ts: parseGradeCompareArgs uses parseTimeoutMs(args.timeout, DEFAULT_RENDER_READY_TIMEOUT_MS). The default stays 5000 ms.
  • Both --timeout help descriptions and their rows in docs/packages/cli.mdx now mention units such as 30s.

Test plan

  • Unit tests added/updated:
    • capture.test.ts runs the command with captureWebsite mocked. 1s, 2m, 45000 and an omitted flag reach capture as 1000, 120000, 45000 and 120000 ms. abc warns and uses 120000.
    • grade-compare.test.ts: parseGradeCompareArgs reads 1s, 1500ms, 8000 and an omitted flag as 1000, 1500, 8000 and 5000 ms. abc warns and uses 5000.
    • Six of the new cases fail on main: 1s and 2m (they become 1 ms and 2 ms), the omitted capture timeout (undefined), and abc in both commands (no warning).
    • The capture, grade-compare and timeoutArg suites pass: 63 passed, 1 skipped.
  • Manual testing performed with the CLI built from source:
    • capture --local-file on a small page: --timeout 1ms (what 1s used to become) fails with capture navigation timed out. --timeout 1s loads the page and writes the capture. --timeout abc warns and captures with the 120000 ms default.
    • grade-compare on a 320×180 frame with two grades: 1s, 1ms and an omitted flag all write the comparison sheet. abc warns and uses 5000 ms.
    • Both --help outputs show the new descriptions.
  • Documentation updated (if applicable): docs/packages/cli.mdx, both --timeout rows.
  • Comments follow CONTRIBUTING.md "Comments": no new comments.

Also run: oxlint, oxfmt --check, tsc --noEmit (cli, core, studio, scripts), fallow audit --base upstream/main, comment-ratchet, check-comment-citations, check:cli-process-ownership. All clean.

Not covered

capture read --timeout with parseInt, so `--timeout 1s` became a 1 ms
page-load timeout. grade-compare dropped an invalid value without a
warning. Both now use the shared parseTimeoutMs helper that check and
snapshot already use, keeping their defaults of 120000 ms and 5000 ms.

Fixes heygen-com#7671
@mintlify

mintlify Bot commented Nov 14, 2026

Copy link
Copy Markdown

Preview approval required

This pull request comes from a fork, so Mintlify won't build a preview until someone with write access approves commit aac5352.

Approve preview

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: COMMENT (needs human) · 0 blocker · 0 important · 1 nit
The code is ready to approve. CI hasn't run because this is a fork PR and every workflow is action_required. A maintainer needs to approve the workflow runs, and the required checks have to pass before this merges.

Scope

Read all 5 files end to end, plus utils/timeoutArg.ts, captureAttempt.ts and navigateForCapture.ts, to see how the timeout gets used. Ran it locally at aac5352: capture.test.ts, grade-compare.test.ts and timeoutArg.test.ts (64 passed); oxlint and oxfmt are clean, and tsc reports no errors in the changed files. No prior reviews to dedupe against.

— Genesis

skipVision: args["skip-vision"] as boolean,
maxScreenshots,
timeout: args.timeout ? parseInt(args.timeout as string) : undefined,
timeout: parseTimeoutMs(args.timeout, DEFAULT_CAPTURE_TIMEOUT_MS),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: capture --timeout 0 changes meaning with no warning. Before, "0" is a truthy string, so it passed through as 0. navigateForCapture then ran goto with timeout: 0, which in Puppeteer means wait forever. Now parseTimeoutMs returns the 120000 fallback for ms <= 0 and prints nothing. It's undocumented, so this is fine if intended. If anyone relied on 0 to mean no limit, it's worth a line in the PR body, or a warning from the helper when the value is <= 0.

@jrusso1020 jrusso1020 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewed at aac535278bf1ee0f110cd87615212d08e8074617.

Need: yes, interpret duration flags consistently · Size: ok · Reuse: existing parseTimeoutMs used by check/snapshot · Simpler: already minimal · Structure: fine (checked command argument and downstream timeout paths; no split)
Risk: low — localized argument parsing with unchanged default durations.

Thanks for covering both commands and updating their help and docs. capture.ts:242 now forwards milliseconds from the shared parser, and grade-compare.ts:294 uses the same conversion before the existing render-ready path. Defaults remain 120000 and 5000 ms; malformed durations warn on stderr, preserving JSON stdout. No blocking findings. As Genesis noted, the undocumented capture --timeout 0 now falls back to 120000 ms rather than disabling the navigation timeout; that compatibility note is nonblocking.

Validation: bun run build passes. On Node 24.22.2, vitest run --project unit src/commands/capture.test.ts src/commands/grade-compare.test.ts src/utils/timeoutArg.test.ts src/capture/navigateForCapture.test.ts --maxWorkers=2: 103 passed. Capture tests exercise the command forwarding milliseconds to captureWebsite; grade-compare tests exercise argument parsing, and I traced that value into the render-ready consumer. Restoring the two old parseInt expressions makes six timeout regressions fail; restoring this head makes all 11 timeout-selected tests pass. Oxlint and oxfmt checks pass on all four changed TypeScript files. Temporary edits restored.

CI workflows at this head are awaiting fork-run authorization (action_required); the available success checks do not mean the test workflows ran. I did not repeat the author's browser capture or grade-sheet walkthrough.

Verdict: APPROVE
Reasoning: The two affected commands now use the established duration parser, and the focused regression coverage exercises units, bare milliseconds, omitted arguments and malformed input.

— Rames

@jrusso1020
jrusso1020 enabled auto-merge November 14, 2026 04:10
@jrusso1020
jrusso1020 added this pull request to the merge queue Nov 14, 2026
Merged via the queue into heygen-com:main with commit 50c21c3 Nov 14, 2026
72 checks passed
@heygengenesis heygengenesis Bot mentioned this pull request Nov 14, 2026
1 of 2 tasks
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.

cli: capture --timeout 1s means 1 ms and grade-compare --timeout abc silently becomes 5000

3 participants