Skip to content

feat(validate): extract @hyperframes/validate importable runtime validate#2013

Draft
xuanruli wants to merge 1 commit into
mainfrom
xuanru/expose-runtime-validate-fn
Draft

feat(validate): extract @hyperframes/validate importable runtime validate#2013
xuanruli wants to merge 1 commit into
mainfrom
xuanru/expose-runtime-validate-fn

Conversation

@xuanruli

@xuanruli xuanruli commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

What

Extracts the browser-based validate into a new @hyperframes/validate package that exports validateHtmlInBrowser(html, opts) — mirroring how @hyperframes/lint exposes lintHyperframeHtml. The validate CLI command is behavior-unchanged; it now delegates to the package.

Why

The full validate harness (console/network/HTTP error capture, contrast + clip-duration audits, remote-asset localization, viewport-from-comp) only lived inline in the CLI command, so external consumers (e.g. the astral video-agent's validate_hyperframes bridge) can't reuse it. They reimplement a parallel headless harness that drifts from render:

  • no asset localization → false CORS / net::ERR_FAILED on the crossorigin <img> S3 fetches the real render localizes first
  • hardcoded 1920×1080 viewport → false out_of_frame on portrait comps
  • hand-maintained runtime-parity that silently rots

Lint doesn't have this problem because it's an importable package. This gives validate the same shape, so there's one implementation everyone shares.

Design (mirrors the lint pattern)

  • Package owns the machinery, caller owns I/O. validateHtmlInBrowser takes opts.browserExecutablePath — the CLI resolves Chrome via its own ensureBrowser() and passes it in. The package has no browser/manager, staying launch-agnostic (lint owns rules, not file I/O; validate owns the audit, not browser discovery).
  • opts.onPage(page) runs caller checks on the same loaded page before teardown (findings merged into errors/warnings). This is the hook a downstream consumer uses to layer its own gates — e.g. the caption-zone / out-of-frame geometry checks — without a second browser load or a forked harness.
  • contrast-audit.browser.js moves to the package (its only consumer). The CLI build copies it into dist/commands and the bundled runtime loads it via the same page.addScriptTag path.
  • Small low-level helpers validate needs (static file server, comp-viewport parse, linkedom shim, error normalizer) are vendored into the package so it doesn't import from @hyperframes/cli (which depends on it). Folding cli + validate onto a shared low-level package is a sensible follow-up — flagged in .fallowrc duplicates.ignore with the repo's existing moved-code convention. (Maintainer call — happy to do it either way.)
  • Tests move with the code they cover (pure-function unit tests + the contrast-script browser test). The CLI keeps only extractCompositionErrorsFromLint, a CLI-side lint→error shaping concern.

Verification

  • @hyperframes/validate: build + typecheck clean, tests 13/13
  • @hyperframes/cli: build clean, tests 1270/1270 (103 files)
  • fallow audit --base origin/main: clean on 20 changed files
  • e2e: hyperframes validate on a real composition through the package (Chrome launch + contrast audit) → ok: true

Follow-ups (not in this PR)

  1. Point the astral validate_hyperframes bridge at validateHtmlInBrowser + pass onPage = caption-zone / out-of-frame gates, replacing its standalone bridge.mjs.
  2. Optional: extract cli + validate's shared low-level helpers into a dedicated package to drop the vendored copies.

🤖 Generated with Claude Code

@xuanruli xuanruli force-pushed the xuanru/expose-runtime-validate-fn branch from 6778d89 to 88596f0 Compare July 7, 2026 04:53
@xuanruli xuanruli changed the title [RFC/WIP] Expose runtime validate as importable validateHtmlInBrowser (+ onPage hook) feat(validate): extract @hyperframes/validate importable runtime validate Jul 7, 2026
@xuanruli xuanruli marked this pull request as ready for review July 7, 2026 04:53
@xuanruli xuanruli marked this pull request as draft July 7, 2026 04:57
@xuanruli xuanruli force-pushed the xuanru/expose-runtime-validate-fn branch 2 times, most recently from 97da76f to 5cd79b1 Compare July 7, 2026 05:15
…date

The browser-based `validate` (console/network/HTTP + contrast/clip audits, remote-asset
localization, viewport-from-comp) only existed inline in the `validate` CLI command, so
external consumers couldn't reuse it — they reimplement a parallel headless harness that
drifts from render (missing localize → false CORS; hardcoded viewport → false out-of-frame;
hand-maintained runtime parity). Lint doesn't have this problem: it's an importable
`@hyperframes/lint` package.

This lifts the browser core into a new `@hyperframes/validate` package, exporting
`validateHtmlInBrowser(html, opts)`. The CLI `validate` command is behavior-unchanged: it
lints + bundles, resolves Chrome via its own `ensureBrowser()`, and delegates. The package
takes `opts.browserExecutablePath` so the caller owns browser discovery — the package stays
launch-agnostic (no browser/manager), like lint owns rules but not I/O.

New `opts.onPage(page)` runs extra checks on the SAME loaded page before teardown (findings
merged), so a consumer can layer its own gates (e.g. caption-zone / out-of-frame) without a
second browser load.

- contrast-audit.browser.js moves to the package (its only consumer); the CLI build copies it
  into dist and the bundled runtime loads it via the same page.addScriptTag path.
- The small low-level helpers validate needs (static file server, comp-viewport parse,
  linkedom shim, error normalizer) are vendored into the package so it doesn't import from
  @hyperframes/cli (which depends on it); folding both onto a shared low-level package is a
  follow-up. Marked in .fallowrc duplicates.ignore, matching the repo's moved-code convention.
- Pure-function + contrast-script tests move to the package with the code they cover; the CLI
  keeps only extractCompositionErrorsFromLint (a CLI-side lint→error shaping concern).

Verified: package build + typecheck clean, package tests 13/13, CLI tests 1270/1270 (103
files), fallow audit clean on 20 changed files, and an e2e `hyperframes validate` on a real
composition through the package (Chrome launch + contrast audit) returns ok:true.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xuanruli xuanruli force-pushed the xuanru/expose-runtime-validate-fn branch from 5cd79b1 to a108ffa Compare July 7, 2026 06:41
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