Commit Graph
260 Commits
Author SHA1 Message Date
Miguel Ángel 4c5071b76b fix(ci): remove --provenance from npm publish
npm provenance requires a public GitHub repo. The repo is currently
set to "internal" visibility, which causes E422 on publish.
Remove --provenance until the repo is made public.
2026-03-25 13:36:15 -04:00
Miguel Ángel 60ec575cd6 fix(ci): remove pnpm from publish workflow, use bun + npm
- Remove pnpm/action-setup (no pnpm-lock.yaml exists after bun migration)
- Remove cache: pnpm from setup-node (caused "lockfile not found" error)
- Use bun for install/build, npm for publish (npm comes with node)
- Pass NODE_AUTH_TOKEN per publish step
2026-03-25 13:30:40 -04:00
Miguel Ángel 5f4c9c3383 fix(producer): preserve @import rules during CSS composition scoping (#40)
## What

Enhanced base64 media detection to identify fabricated data and fixed CSS scoping to preserve @import rules.

## Why

The linter was flagging all base64 media as prohibited, but the real issue is fabricated/fake base64 data that won't actually play. Additionally, CSS @import rules were being corrupted during composition scoping, breaking font imports and other external stylesheets.

## How

- Updated base64 media linting to detect fabricated data by checking for repetitive patterns and suspicious characteristics
- Changed error code from `base64_media_prohibited` to `fabricated_inline_media` with severity based on suspicion level
- Fixed `scopeCssToComposition()` to extract @import rules before applying selector scoping, then prepend them to the final output
- Added minimum length threshold (100 chars) for base64 detection to focus on substantial media files

## Test plan

- [x] Added regression test `css-import-scoping` to verify @import rules survive CSS scoping and render correctly
- [x] Updated linter logic to distinguish between legitimate and fabricated base64 media
- [x] Verified CSS scoping preserves @import statements while properly scoping selectors
2026-03-25 00:25:12 +01:00
Miguel ÁngelandClaude Opus 4.6 d3c6228d89 fix(producer): preserve @import rules during CSS composition scoping
scopeCssToComposition corrupted @import url() rules because they have
no {} block. The selector regex ([^{}@]+)\{ treated the text after @
as a selector, producing invalid CSS like:

  @[data-composition-id="x"] import url('...')

This broke font loading, CSS variable resolution, and all composition
styling in rendered output.

Fix: extract @import rules before running the scoping regex, then
prepend them back unmodified.

Also adds:
- Regression test fixture (css-import-scoping)
- Common-mistakes docs: autoplay/loop, GSAP TextPlugin, sub-composition
  positioning
- Format fix for hyperframeLinter.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 18:51:05 -04:00
Miguel Ángel e6a643ac1d feat(core): add support for playback-rate and loop for media elements (#41)
## Adds playback rate and loop support for media elements

Introduces per-element playback rate control and looping functionality for `<video>` and `<audio>` elements in the runtime media system.

### Playback Rate Control
- Reads `defaultPlaybackRate` property from media elements (set via JavaScript)
- Clamped to [0.1, 5] range for safety
- Multiplied with global transport rate during playback
- Adjusts timeline duration calculation: 10s source at 0.5x rate = 20s on timeline
- Defaults to 1.0 when not specified

### Loop Functionality  
- Reads native `loop` attribute from media elements
- When enabled, wraps `relTime` using modulo of source duration
- Restarts from `mediaStart` offset when source reaches end
- Works correctly with partial media clips (respects `data-media-start`)
- Defaults to false when not specified

### Implementation Details
- Extends `RuntimeMediaClip` type with `playbackRate`, `loop`, and `sourceDuration` fields
- Updates `refreshRuntimeMediaCache` to parse new properties from DOM elements
- Modifies `syncRuntimeMedia` to apply per-element rates and handle loop wrapping
- Maintains backward compatibility with existing media clips

### Test Coverage
Adds 8 new unit tests covering:
- Playback rate parsing from DOM elements
- Rate clamping to valid ranges  
- Duration adjustment calculations
- Combined per-element and global rate application
- Loop wrapping with and without `mediaStart` offsets
- Non-looping behavior verification
2026-03-24 23:24:51 +01:00
Miguel Ángel 46e9f8d248 feat(core): add loop and data-playback-rate for media elements
- data-playback-rate: per-element slow-mo/fast-forward (0.1-5x range)
  Multiplied with global transport rate. Affects timeline duration
  calculation when source duration is used as fallback.

- loop: native HTML loop attribute now works correctly in the runtime.
  Wraps media playback from mediaStart when source reaches end.
  Enables looping short clips over longer durations.

Both follow the existing data-media-start/data-volume pattern.
2026-03-24 17:27:41 -04:00
Miguel Ángel 1ea55d8f3a test(regression): add editor-agent-prod regression fixture (#37)
## Summary

- Adds `editor-agent-prod` regression test fixture for the producer
- Tests preview/render parity for compositions with sub-compositions, GSAP timelines, overlay elements, and `data-end` attributes  
- Adds `styles-g` shard to regression CI workflow to run the new test
- Creates comprehensive Basel Form-styled video composition with intro/outro cards, reveals, persistent overlays, and captions
- Includes biomorphic SVG assets and Inter font integration for typographic consistency
- Tests complex animation timing with staggered entrances, crossfades, and synchronized A-roll movements

## Test plan

- [x] Regression CI passes for editor-agent-prod shard
- [x] Existing regression tests unaffected
- [x] Preview/render output matches expected visual and timing specifications
2026-03-24 21:25:42 +01:00
Miguel ÁngelandClaude Opus 4.6 36f3b8c87d test(regression): add editor-agent-prod regression fixture
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:33:13 -04:00
Vance IngallsandClaude Opus 4.6 61c5257402 fix(ci): update publish workflow to use bun install (#36)
* fix(ci): update publish workflow to use bun install

pnpm-lock.yaml was removed in the bun migration but publish.yml
still referenced it. Use bun for install/build, keep pnpm for
publish (publishConfig overrides + --provenance).

* docs: update stale pnpm references to bun across docs and scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 08:46:58 -07:00
Miguel Ángel f84df64e64 chore: release v0.1.2 (#32)
## Release v0.1.2

Bumps all packages to v0.1.2.

**After merging**, the release tag is created automatically, which triggers npm publish.
2026-03-24 06:06:12 +01:00
James Russo f1240a81a0 Merge pull request #35 from heygen-com/fix/studio-readme-bun
fix(docs): update studio README to use bun instead of pnpm
2026-03-23 22:03:11 -07:00
JamesandClaude Opus 4.6 4c35e4501a fix(docs): update studio README to use bun instead of pnpm
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 05:02:29 +00:00
James Russo c96c730460 Merge pull request #34 from heygen-com/docs/oss-documentation
docs: add per-package READMEs and polish root docs for OSS launch
2026-03-23 22:01:38 -07:00
JamesandClaude Opus 4.6 039985b1fe ci: split lint and format into separate jobs
- Lint (oxlint) only runs when code changes are detected
- Format (oxfmt) runs on all PRs including docs-only changes
- Update path filter: pnpm-lock.yaml → bun.lock

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:54:51 +00:00
JamesandClaude Opus 4.6 065de441b3 style: apply oxfmt formatting to markdown files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:54:24 +00:00
JamesandClaude Opus 4.6 98113c2447 docs: add per-package READMEs and polish root docs for OSS launch
- Add READMEs for all 5 packages (core, engine, producer, cli, studio)
  with install, overview, basic usage, and links to full docs
- Rewrite core README from internal doc to OSS-facing format
- Polish root README: add badges, packages table, docs link, requirements
- Add AI usage policy and BDFL governance statement to CONTRIBUTING.md
- Genericize license references (pending final license decision)
- Docs URL set to hyperframes.heygen.com

Addresses VA-850.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 04:53:00 +00:00
github-actions[bot] 7d75ba30db chore: release v0.1.2 2026-03-24 04:32:13 +00:00
Miguel Ángel 9c31fa870c fix: composition issues in runtime code + producer parity (#31)
## What

Enhanced the hyperframe linter with new media validation rules and improved error detection for critical HTML issues.

## Why

The linter needed to catch more critical HTML errors that cause compositions to fail at render time, including self-closing media tags, placeholder URLs, and fabricated base64 data. Additionally, the media URL validation needed better concurrency control and more accurate error reporting.

## How

**Linter improvements:**

- Added detection for self-closing `<audio/>` and `<video/>` tags that cause rendering issues
- Added validation for placeholder media URLs ([placehold.co](http://placehold.co), [example.com](http://example.com), etc.) that return 404 errors
- Enhanced fabricated base64 media detection with severity levels (error for suspicious patterns, warning for others)
- Renamed `suspicious_global_gsap_selector` to `unscoped_gsap_selector` for clarity
- Improved error messages and fix hints to be more actionable

**Media URL validation enhancements:**

- Added concurrency control to `lintMediaUrls()` with configurable batch processing (default 15 parallel requests)
- Improved error handling and timeout management for URL accessibility checks
- Enhanced error messages to focus on URL replacement rather than tool-specific suggestions

**Runtime improvements:**

- Added null checks in picker module to prevent errors with missing DOM nodes and attributes
- Added TypeScript configuration for the runtime module with strict type checking

**Configuration cleanup:**

- Removed unused render seek configuration options from engine config
- Updated file server to support both inline scripts and external script URLs in head injection
- Fixed runtime script marker references for proper script stripping

## Test plan

- [x] Unit tests added for new linter rules (self-closing media, placeholder URLs, fabricated base64)
- [x] Test coverage for renamed linter code verification
- [x] Validation of fabricated vs non-suspicious base64 media detection
- [x] Manual testing of media URL accessibility checking with concurrency limits
- [x] Testing of picker module null safety improvements
2026-03-24 05:31:30 +01:00
Miguel Ángel 062f6f1c10 fix: composition issues in runtime code + producer parity 2026-03-23 23:56:42 -04:00
Vance Ingalls 94e25443ae build: migrate from pnpm to bun as package manager (#28)
## Summary
- Replace pnpm with bun for dependency installation, script running, and ad-hoc execution
- Keep pnpm for publish workflow only (`publishConfig` overrides + `--provenance`)
- `bun install` replaces `pnpm install` (~4-5x faster cold installs)
- `bun run` replaces `pnpm run` (~28x less startup overhead)
- `bunx` replaces `npx` in lefthook hooks
- CI workflows updated (`oven-sh/setup-bun@v2` + `actions/setup-node@v4`)
- `pnpm-lock.yaml` removed, `bun.lock` generated
- `pnpm-workspace.yaml` kept for publish compatibility
- CLI source code (`packages/cli/src/`) unchanged — shipped to end users who may not have bun

Part 5/5 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `bun run lint` — 0 errors
- [x] `bun run format:check` — all files pass
- [x] `bun run build` — all 5 packages build
- [x] 330 core tests pass
- [x] 18 engine tests pass
- [x] `publish.yml` unchanged (pnpm stays for npm publishing)
- [x] No `bunx`/`bun run` references in shipped source code (`packages/*/src/`)
2026-03-23 19:50:57 -07:00
Vance Ingalls a6c5e08abb ci: add lint and format check job, update CONTRIBUTING.md (#26)
## Summary
- Add `lint-and-format` job to CI workflow (`pnpm lint` + `pnpm format:check`)
- Fix lefthook commands to use `npx` prefix (bare binaries not on PATH)
- Update CONTRIBUTING.md: document new tooling, commit conventions, and lefthook hooks

Part 4/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] CI job matches existing pattern (pnpm 10, node 22, frozen lockfile)
- [x] Git hooks work end-to-end (bad messages rejected, valid commits pass)
- [x] CONTRIBUTING.md accurately reflects new tooling
2026-03-23 18:49:06 -07:00
James Russo 2a6b547b74 Merge pull request #33 from heygen-com/docs/mintlify-setup
docs: add Mintlify documentation site
2026-03-23 18:09:57 -07:00
Vance Ingalls 20be2ea1c2 style: apply oxfmt baseline formatting across all source files (#25)
## Summary
- Run `oxfmt .` across the entire codebase to establish formatted baseline
- 299 files changed — mechanical formatting only, no logic changes
- Double quotes, semicolons, 2-space indent, trailing commas, 100 print width

Part 3/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm format:check` — all 426 files pass
- [x] `pnpm -r typecheck` — all packages pass
- [x] `pnpm build` — all packages build
- [x] All 348 tests pass
2026-03-23 17:15:14 -07:00
JamesandClaude Opus 4.6 43283348eb ci: remove workflow files from path filters
The CI and regression path filters included their own workflow files,
which meant any PR that changed CI config would trigger the full
build/test/regression suite. Workflow file changes don't need code
validation — they need a test run of the workflow itself, which
happens automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:15:05 +00:00
JamesandClaude Opus 4.6 623ba1dc60 chore(docs): update to Prism brand logo, favicon, and colors
Replace pre-Prism logos with the current Prism brand assets:
- Logo light: HeyGen_Logo_Prism_Black.svg (gradient wordmark for light bg)
- Logo dark: HeyGen_Logo_Prism_White.svg (gradient wordmark for dark bg)
- Favicon: PRISM_ORB.svg (the new Prism orb icon)
- Brand color: #00C4FF (Prism cyan) replacing #7559FF (old purple)
- Update Mermaid diagram colors in determinism.mdx to match

Also includes CI fix: switch from paths-ignore to dorny/paths-filter
with `if:` conditions so required checks auto-pass on docs-only PRs
instead of hanging as "pending".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:09:13 +00:00
JamesandClaude Opus 4.6 7adcb2322d ci: use path-based skip instead of paths-ignore for required checks
The repo has a ruleset requiring these checks: Build, Typecheck,
Test: core, Test: engine, Test: runtime contract, regression.
With paths-ignore, docs-only PRs would never report these checks,
blocking merge forever.

Fix: add a `changes` job using dorny/paths-filter that detects
whether code files changed. Each job uses `if: needs.changes.outputs.code == 'true'`
which causes GitHub to report the job as "skipped" (counts as passing)
rather than "never started" (counts as pending).

The regression summary job explicitly handles the no-code-changes case
by checking the filter output before evaluating shard results.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:05:57 +00:00
JamesandClaude Opus 4.6 769d34f8f9 ci: add docs validation workflow and skip CI on docs-only changes
- New docs.yml: runs `mint validate` and `mint broken-links` on docs/** changes
- ci.yml: paths-ignore docs/**, *.md so build/typecheck/tests don't run on docs-only PRs
- regression.yml: same paths-ignore to skip Docker regression tests on docs-only PRs

No branch protection is configured, so paths-ignore won't block merges.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:04:26 +00:00
JamesandClaude Opus 4.6 3f6608f38b chore(docs): update to new HeyGen logo and favicon
Replace old gradient pinwheel logo with the current HeyGen branding:
- Logo light: flat wordmark with #7559FF purple play icon (black text)
- Logo dark: same wordmark with white text
- Favicon: purple rounded square with white play icon (SVG)

Remove old favicon.ico and gradient icon.svg.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 00:02:57 +00:00
JamesandClaude Opus 4.6 915fe2f47a docs: improve quality based on Remotion/Stripe/Tailwind patterns
Major improvements across all 18 pages:

- Use Mintlify components: <Steps> for tutorials, <Tabs> for alternatives,
  <CodeGroup> for multi-platform commands, <Tree> for directory structures,
  <AccordionGroup> for FAQ/scannable content, <Mermaid> for diagrams
- Add filename annotations to all code blocks (e.g., ```html index.html)
- Add numbered comments inside multi-step code examples
- Show expected terminal output after CLI commands
- Add "When to use" / "When NOT to use" sections to all package pages
- Add "Next Steps" CardGroup to every page (no dead-end pages)
- Cross-link between pages at point of curiosity (not just "see also" dumps)
- Expand thin pages (engine, studio) with architecture details and examples
- Add decision guides (rendering modes, template selection)
- Use <Warning> and <Note> sparingly (max 2-3 per page)

Also adds DOCS_GUIDELINES.md at repo root with writing standards.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 23:57:01 +00:00
Vance Ingalls 323ff8f860 fix: resolve oxlint errors across codebase (#24)
## Summary
- Remove 5 unused `beforeEach` imports from test files
- Remove unused imports (`existsSync`, `TimelineCompositionElement`)
- Remove unused destructured variables (`options`, `width`, `height`, `goldenEl`)
- Remove dead `formatDuration` function
- Fix unused catch parameters (`catch (err)` → `catch`)
- Prefix unused `renderError` state with `_`
- Add `eslint-disable-next-line` for 2 React exhaustive-deps false positives (stable ref + zustand setter)

Part 2/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm lint` — 0 errors on 193 files
- [x] All 348 tests pass (core + engine)
2026-03-23 16:41:41 -07:00
Vance Ingalls 17e90f0671 build: add oxlint, oxfmt, commitlint, lefthook, knip, and editorconfig configs (#23)
## Summary
- Install oxlint, oxfmt, commitlint, lefthook, knip as dev dependencies
- Add `.oxlintrc.json` (correctness rules + React plugin)
- Add `.oxfmtrc.json` (double quotes, semicolons, 2-space indent, trailing commas)
- Add `commitlint.config.js` (conventional commits)
- Add `lefthook.yml` (pre-commit lint+format, commit-msg commitlint)
- Add `.editorconfig` and `knip.config.ts`
- Add scripts: `pnpm lint`, `pnpm format`, `pnpm format:check`, `pnpm knip`

Part 1/4 of [VA-851](https://linear.app/heygen/issue/VA-851/pre-migration-configure-eslint-prettier-and-conventional-commits)

## Test plan
- [x] `pnpm lint` runs (reports pre-existing errors, expected)
- [x] `pnpm format:check` runs (reports pre-existing diffs, expected)
- [x] `commitlint` validates and rejects messages correctly
- [x] lefthook hooks install via `pnpm run prepare`
- [x] `pnpm knip` runs
2026-03-23 16:05:47 -07:00
JamesandClaude Opus 4.6 00bd2e5ae2 docs: add Mintlify documentation site
Set up /docs directory with docs.json config, HeyGen branding (logo, favicon,
#7559FF purple), and 18 MDX pages covering:
- Getting started (introduction, quickstart)
- Concepts (compositions, data attributes, frame adapters, determinism)
- Guides (GSAP animation, templates, rendering, common mistakes, troubleshooting)
- Package docs (core, engine, producer, studio, CLI)
- Reference (HTML schema) and contributing guide

Content adapted from existing repo docs (core/docs/, cli/src/docs/, README).
Validated with `mint validate` and `mint broken-links`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 22:39:08 +00:00
James Russo 7c48f2a98b Merge pull request #27 from heygen-com/ci/regression-tests
ci(regression): add Docker-based regression test pipeline
2026-03-23 14:15:52 -07:00
JamesandClaude Opus 4.6 40260ff133 ci(regression): increase sharding to 3 tests per shard
Split 21 style tests into 6 shards (3 each, last has 2) to reduce
max wall time from ~38min to ~25min. Each test takes ~7-8min plus
~5min Docker overhead per shard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:43:05 +00:00
JamesandClaude Opus 4.6 df6aa100d4 ci(regression): make all style shards required
All style regression tests passed on first run — promote them from
optional (continue-on-error) to required. Rebalanced into 4 style
shards + 1 fast shard, all gated by the summary job.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 20:03:30 +00:00
JamesandClaude Opus 4.6 04c48d5bc5 ci(regression): add Docker-based regression test pipeline
Port the regression test infrastructure from the internal repo to OSS.
Runs golden-baseline visual/audio comparisons inside Docker for deterministic results.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 19:08:25 +00:00
Vance IngallsandClaude Opus 4.6 0276255b76 fix: rename root package to avoid shadowing published CLI (#17)
`npx hyperframes init` failed with "could not determine executable to run"
because the monorepo root package.json shared the same name as the published
npm package. npx resolved the local root (which has no bin field) instead of
the published package. Renaming to "hyperframes-monorepo" follows the same
convention as remotion-monorepo.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 22:47:18 -07:00
James Russo cf7250ffe7 Merge pull request #16 from heygen-com/feat/release-workflow-dispatch
feat(ci): add workflow_dispatch release trigger with dry-run and GitHub Release
2026-03-22 20:59:41 -07:00
James f25eb06093 feat(ci): add PR-based release flow with auto-tagging 2026-03-23 03:49:18 +00:00
James Russo edd1c02601 Merge pull request #15 from heygen-com/fix/publish-npm-token
fix(ci): use NPM_TOKEN secret for npm publish auth
v0.1.1
2026-03-22 20:36:11 -07:00
James 3fe9267e97 fix(ci): use Node 24 for npm trusted publishing (requires npm >= 11.5.1) 2026-03-23 03:35:04 +00:00
James Russo 05d18e9172 Merge pull request #14 from heygen-com/chore/release-v0.1.1
chore: release v0.1.1
2026-03-22 20:25:48 -07:00
James 4fa627d36a chore: release v0.1.1 2026-03-23 03:24:59 +00:00
James Russo f0cf0839b0 Merge pull request #13 from heygen-com/03-23-ci_add_tag-triggered_npm_publish_workflow_with_oidc_provenance
ci: add CI pipeline, npm publish workflow, and release tooling
2026-03-22 20:23:46 -07:00
James 306909534b ci: add tag-triggered npm publish workflow with OIDC provenance 2026-03-23 03:20:21 +00:00
James 98dedf8c14 ci: add CI pipeline with build, typecheck, and test jobs 2026-03-23 03:19:59 +00:00
Vance IngallsandClaude Opus 4.6 1a713b37b9 fix: change workspace:* to workspace:^ for npm publish compatibility (#12)
pnpm converts workspace:^ to ^X.Y.Z during publish, but workspace:*
was left unconverted in the registry. This caused install failures
for external consumers.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 20:15:54 -07:00
James Russo 3e4692d2ab Merge pull request #9 from heygen-com/03-23-fix_resolve_build_and_typecheck_failures_across_packages
fix: resolve build and typecheck failures across packages
2026-03-22 19:11:59 -07:00
James fac39541f5 fix: resolve build and typecheck failures across packages 2026-03-23 01:29:53 +00:00
Vance IngallsandClaude Opus 4.6 00909c8258 fix: revert parity harness to puppeteer-core with channel: chrome
The puppeteer import caused protocol timeout issues. Revert to
puppeteer-core but add channel: "chrome" to auto-discover the
Chrome binary installed by 'puppeteer browsers install'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 01:31:33 -07:00