Commit Graph
19 Commits
Author SHA1 Message Date
Miguel ÁngelandClaude Sonnet 4.6 9d2362990b fix(cli): inject version from package.json, fix docker hint, add --port to dev
- version.ts: replace hardcoded "0.1.0" with __CLI_VERSION__ injected by
  tsup at build time from package.json — fixes version mismatch where
  `hyperframes --version` reported 0.1.0 while package was 0.1.4
- tsup.config.ts: add define.__CLI_VERSION__ using package.json version
- render.ts: renderDocker error handler showed "Try --docker" even when
  already using --docker — changed to "Check Docker is running: docker info"
- dev.ts: add missing --port arg to embedded mode; findAvailablePort now
  starts from the user-supplied port instead of hardcoded 3002

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 00:45:36 +00:00
Miguel Ángel e554710646 fix(producer): propagate data-start to inner composition element during compilation (#73)
## Summary
- copy data-start from the host sub-composition node to the inlined inner composition root
- preserve the correct runtime offset lookup for nested compositions after producer compilation
- avoid nested GSAP timelines snapping to their end state when the host starts later than t=0
2026-03-27 00:20:16 +01:00
Miguel Ángel e1c1c6fb30 fix: rewrite workspace deps before npm publish (#67)
## Summary
- rewrite workspace protocol dependencies to publish-safe semver ranges before the npm publish workflow runs
- keep workspace protocol references in source manifests for normal monorepo development
- ensure the published `@hyperframes/producer` manifest no longer ships unresolved `workspace:` deps

## Why
The internal repo hit a Docker build failure because the published `@hyperframes/producer` metadata still contained `workspace:^` dependencies for `@hyperframes/core` and `@hyperframes/engine`. `npm install` cannot resolve those outside the monorepo, so the published package itself was the root cause.

## Validation
- `bun install --frozen-lockfile`
- `bun run build:producer`
- `bun run prepare:publish-manifests`
- `npm pack --workspace packages/core`
- `npm pack --workspace packages/engine`
- `npm pack --workspace packages/producer`
- installed the three tarballs together in a clean temp project with `npm install --ignore-scripts`
- extracted the producer tarball and verified its `package.json` contains `^0.1.3` for `@hyperframes/core` and `@hyperframes/engine`, not `workspace:^`
2026-03-26 21:14:39 +01:00
Miguel Ángel 36c91cecbb chore: release v0.1.3 (#60)
## Release v0.1.3

Bumps all packages to v0.1.3.

### Changes since v0.1.2
- fix(producer): resolve manifest from sibling dist/ directory
- fix(producer): add margin reset when wrapping HTML fragments
- fix(producer): exclude test files from tsc build
- feat(cli): add opt-out anonymous telemetry via PostHog
- feat: add HyperFrames skills for AI coding tools
- fix(cli): resolve npx hyperframes from inside monorepo
- fix(ci): publish workflow fixes (remove provenance, idempotent steps, remove prepublishOnly)

After merging, the release tag is created automatically, which triggers npm publish.
2026-03-26 19:17:09 +01:00
Miguel Ángel 251ed23252 fix(producer): add margin reset when wrapping HTML fragments (#55)
## Summary

- When `index.html` is a bare fragment (just a `<div>` without `<!DOCTYPE>`), `ensureFullDocument()` wraps it in a minimal HTML document
- The wrapper was missing a CSS reset, so Chrome applied its default `body { margin: 8px }` — creating visible white lines at the top and left edges of rendered video
- Added `* { margin:0; padding:0; box-sizing:border-box }` and `body { overflow:hidden; background:#000 }` to the fragment wrapper

## Test plan

- [x] Render a composition that starts with a bare `<div>` (no `<!DOCTYPE html>`)
- [x] Verify no white lines appear at the edges of the rendered MP4
2026-03-26 04:48:47 +01:00
Miguel Ángel bca76ce82e fix(ci): make publish steps idempotent with continue-on-error (#51)
Already-published versions cause npm to return E403. With
continue-on-error, the workflow skips published packages and
continues to publish the remaining ones. Safe to re-run.
2026-03-25 19:15:06 +01:00
Miguel Ángel d2884531c1 fix(ci): remove prepublishOnly build scripts (#50)
The publish workflow already runs `bun run build` before publishing.
The prepublishOnly scripts tried to run pnpm/bun which may not be
available during `npm publish`. Replace with no-op to prevent failures.
2026-03-25 19:11:37 +01:00
Miguel Ángel b7fbb52e0c Merge pull request #49 from heygen-com/fix/publish-remove-provenance
fix(ci): remove --provenance from npm publish
2026-03-25 19:06:05 +01:00
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
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
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