Commit Graph

24 Commits

Author SHA1 Message Date
Miguel Ángel f2ae1f592a fix(studio): remove debug outline from preview iframe; add sub-composition video regression test
Removes outline: '1px solid black' from the preview iframe in Player.tsx —
a leftover debug style that drew a visible rectangular border around every
composition preview.

Adds regression test 'sub-composition-video' to prevent recurrence of
the bug where video elements inside sub-compositions (lacking explicit
id attributes) rendered as black frames. Covers the three-part fix:
union selector in parseVideoElements, Infinity end fallback, and
auto-assigned id persistence into compiled HTML.
2026-03-30 22:56:15 +02:00
Miguel Ángel 3fa61e11c2 fix(cli): fix thumbnail generation — engine import, singleton browser, seek time
Root cause: buildChromeArgs/acquireBrowser imported from
@hyperframes/producer which does not re-export them; only
@hyperframes/engine does. All requests silently returned null.

Also: singleton shared browser (was spawning per request),
domcontentloaded instead of networkidle2, seek time 0.5→2s.
2026-03-30 22:24:43 +02:00
Miguel Ángel a182ffdb0c fix(studio): object-contain on inline hover-autoplay video and image assets 2026-03-30 22:24:43 +02:00
Miguel Ángel b1d5c0aaee fix(studio): use object-contain for thumbnails so portrait videos display correctly
object-cover was cropping 9:16 portrait videos to a narrow slice inside
the fixed landscape 80x45px thumbnail cells. object-contain shows the
full frame with neutral-background letterboxing. Applies to Renders tab,
Compositions tab, Assets tab, and timeline clip strip thumbnails.
2026-03-30 22:24:43 +02:00
Miguel Ángel f705402c6d fix(engine,studio): persist auto-assigned video IDs into compiled HTML; shared VideoFrameThumbnail
Render fix: parseVideoElements assigned IDs in JSDOM memory but the
compiled HTML written to disk had no id on id-less video elements, so
injectVideoFramesBatch's getElementById returned null. Now does a second
DOM pass to inject IDs into the HTML string before returning it.

Studio thumbnails: extracted VideoFrameThumbnail into a shared ui/
component. AssetsTab now uses canvas frame extraction (seeks to 10%
duration) instead of <video preload=metadata> which shows a black t=0
frame. RenderQueueItem imports from the same shared component.
2026-03-30 22:24:43 +02:00
Miguel Ángel a63f644002 feat(studio): inline autoplay on render thumbnail hover (no expand)
On hover the thumbnail slot swaps from the static extracted frame to a
live muted looping video in the same w-20 h-[45px] cell — no overlay,
no expansion. Static frame fades out (150ms opacity) as the video takes
over; video is only mounted while hovered so it doesn't run in the
background.
2026-03-30 22:22:35 +02:00
Miguel Ángel 2e60005137 feat(studio): hover-to-autoplay on render rows using shared ExpandedVideoPreview
Extracted shared ExpandedVideoPreview component (src/components/ui/)
used by both AssetsTab (video assets) and RenderQueueItem (rendered
videos). Wraps completed render rows in ExpandOnHover with the same
spring-expand + video autoplay pattern as the Compositions and Assets
tabs. No code duplication: AssetsTab video case delegates to the shared
component, RenderQueueItem reuses it with an Open action button.
2026-03-30 22:22:35 +02:00
Miguel Ángel 781bae2a44 feat(studio): show video frame thumbnail on render rows
Extracts a first-representative-frame from the rendered MP4 using a
hidden video + canvas (same technique as VideoThumbnail). The thumbnail
cell matches CompCard's w-20 h-[45px] sizing so Renders, Compositions,
and Assets tabs all share the same visual language. Rendering/failed/
cancelled rows show a status indicator in the thumbnail slot instead.
2026-03-30 22:22:34 +02:00
Miguel Ángel 7bc8d3ff66 feat(studio): open rendered video in new tab on row click
Clicking a completed render row now opens the video inline in the
browser instead of forcing a download. Added /render/:jobId/view
endpoint with Content-Disposition: inline so the browser plays the
video natively. Download button is preserved on hover for explicit
saves. stopPropagation on action buttons prevents row click conflicts.
2026-03-30 22:22:34 +02:00
Miguel Ángel 04cf7b2eb6 fix(studio): raise Shift+drag hint above timeline clips with z-20 2026-03-30 22:22:34 +02:00
Miguel Ángel 90f2eb7a73 fix(studio): surface render error messages in the renders panel
The SSE progress stream already sent error details on failure but
the client never stored or displayed them. Failed renders now show
the error message below the status indicator, matching the detail
level of the CLI render command.
2026-03-30 22:22:34 +02:00
Miguel Ángel 4d659064ef fix(studio): show clear error when render server is unreachable (#116)
## Summary

- Surfaces error message when render fails due to producer server not running
- Two cases covered: initial POST failure and SSE connection drop
- Failed jobs now show the error reason in red text in the Renders panel

## Test plan

- [x] Start studio without producer server
- [x] Click render → should show "Could not reach render server" in red
- [x] Start render then kill producer → should show "Connection lost"

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-29 08:16:05 +02:00
Miguel Ángel 95d7dc0623 fix(cli): align render output naming and add WebM support to studioServer (#109)
## Summary

- CLI render: use timestamped filenames (`project_date_time.ext`) matching the studio's naming convention, preventing overwrites of previous renders
- studioServer: read `fps`/`quality`/`format` from POST body instead of hardcoding `fps:30`/`quality:standard`/`mp4`
- studioServer: use timestamped job IDs matching the studio pattern
- studioServer: fix download endpoint to serve correct content-type for WebM

## Test plan

- [x] `hyperframes render --format webm` outputs timestamped WebM file
- [x] `hyperframes render` outputs timestamped MP4 (no overwrite)
- [x] Studio embedded server (`hyperframes dev`) renders with correct format when selected in UI
- [x] Download endpoint serves correct MIME type for WebM renders
2026-03-28 21:49:10 +01:00
Miguel Ángel 40bd159103 feat(studio): render queue, layout restructure, home page, hover preview (#95)
## Summary
- Add render queue panel with progress tracking, download, and delete actions
- Restructure App layout: home page with project picker, session-based routing
- Add ExpandOnHover component for preview-on-hover interactions (uses motion/react)
- CompositionsTab now supports hover preview with expanded iframe view
- Vite config: guard setInterval cleanup to dev-only (fixes CI build timeout)
- Add favicon and update studio package deps

## Test plan
- [x] Render queue shows progress, completes, and allows download
- [x] Home page lists projects and navigates to session view
- [x] ExpandOnHover shows expanded preview on mouse hover with spring animation
- [x] `vite build` exits cleanly (no hanging process from setInterval)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 21:28:43 +01:00
Miguel Ángel 9ae239d177 feat(studio): add left sidebar with Compositions and Assets tabs (#94)
## Summary
- Add collapsible left sidebar with Compositions and Assets tabs
- Compositions tab lists all sub-compositions with thumbnail previews and navigation
- Clicking a composition opens it in the code editor AND navigates the preview to show that composition
- Assets tab categorizes project files by type (images, fonts, media)
- Race condition guard on composition fetch with functional state update
- Thumbnail error fallback shows name initial instead of empty box

## Test plan
- [x] Sidebar opens/closes with smooth transition
- [x] Compositions tab lists files from project API
- [x] Clicking a composition changes the preview iframe to that composition
- [x] Assets tab categorizes files by type

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 20:55:15 +01:00
Miguel Ángel 0167e69374 feat(studio): add Edit Range toolbar with Copy to Agent (#65)
## Summary
- Replace Split/Delete buttons with Edit Range toolbar
- Edit button opens a time-range selection on the timeline
- "Copy to Agent" exports the selected range as a prompt-ready description
- Range selection shows start/end times with drag handles

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 20:50:34 +01:00
Miguel Ángel 8c1ae77697 refactor(studio): update layout, config, and remove agent activity tracking (#64)
## Summary
- **NLELayout**: Add toolbar slot, composition breadcrumb navigation, improved responsive layout
- **Vite config**: Add full project API (preview, thumbnail, render, file CRUD) for standalone dev mode
- Remove AgentActivityTrack component (replaced by timeline clips)
- Add HTML editor utilities for composition source editing
- Guard setInterval cleanup to dev-only to prevent `vite build` from hanging in CI

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 20:45:00 +01:00
Miguel Ángel 0769678f46 refactor(studio): improve Timeline, PlayerControls, and player hook (#63)
## Summary
- **Timeline**: Refactored track rendering with zoom support, drag/resize interactions, and playhead scrubbing
- **PlayerControls**: Redesigned with seek bar, time display, playback rate selector
- **useTimelinePlayer**: Enhanced with iframe bridge communication, timeline message parsing, and deterministic seek
- Add Timeline unit tests (109 lines)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 20:39:35 +01:00
Miguel Ángel 625b5131bd refactor(studio): improve player store with zoom and element updates (#61)
## Summary
- Add zoom state (zoomMode, pixelsPerSecond) to player store
- Add timeline element updates (setElements, clearElements)
- Remove unused/duplicate exports from player barrel file

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-28 08:59:33 +01:00
Miguel Ángel d52ea88df5 fix(cli): make blank template a full HTML document
The blank template was a bare `<div>` fragment without `<!DOCTYPE>`,
`<head>`, or `<body>`. This caused:
- Blank preview (bundler/runtime can't initialize from a fragment)
- "Failed to run lint" (parsing errors on the malformed document)

All other templates (swiss-grid, vignelli, warm-grain, play-mode) are
proper HTML documents — blank was the only outlier.

Also improves lint error reporting to show the actual error message
instead of the generic "Failed to run lint."

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 02:50:53 -04:00
James 5ace89d634 feat(cli): implement embedded dev server for hyperframes dev
When installed via npx, `hyperframes dev` now starts a standalone
Hono HTTP server that serves the pre-built studio SPA and implements
the project API (file listing, read/write, preview bundling,
sub-composition rendering, runtime serving, SSE file watching).

Three modes are auto-detected:
1. Monorepo dev (running from .ts source) → spawn Vite (existing)
2. Local @hyperframes/studio installed → spawn Vite via package (new)
3. Default → embedded Hono server (new, zero extra deps needed)

Also patches the studio SPA to use EventSource SSE fallback when
Vite HMR is unavailable (production/embedded builds).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:34:00 +00: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
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 9f8e5ba5a1 initial code (#2)
* feat: initial code port from hyperframes-internal

Port all OSS-ready packages from the internal monorepo:
- @hyperframes/core — shared types, HTML generation, GSAP utilities, runtime
- @hyperframes/cli — CLI for creating, previewing, and rendering compositions
- @hyperframes/engine — framework-agnostic rendering engine (BeginFrame + FFmpeg)
- @hyperframes/producer — video rendering pipeline (Puppeteer + FFmpeg)
- @hyperframes/ui-player — browser-based video player component
- @hyperframes/studio — composition editor (React frontend + Hono backend)

Includes regression test suite with Docker-based test harness.

All HeyGen-internal references, deployment infrastructure, and
proprietary assets have been removed. Package names migrated
from @app/* to @hyperframes/*.

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

* fix: scrub internal codenames and stale references from OSS port

- Replace static.heygen.ai runtime URLs in test fixtures
- Remove internal CDN publish script (publish-hyperframe-runtime.ts)
- Replace sandbox-studio, sandbox-interceptor, __magicEditRuntime
  with neutral names (studio, hyperframe-runtime, __hyperframeRuntime)
- Fix stale Vault API / localhost references in docs
- Remove broken deprecated_studio link

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

* fix: remove remaining internal codenames and stale references

- Delete stale producer README.md and PIPELINE.md (referenced nonexistent files)
- Replace "Cerberus" codename with "HyperFrames" in test design reviews
- Replace magic-edit postMessage identifiers with hf-preview/hf-parent
- Rename debug-magic-edit-timeline.ts to debug-timeline.ts
- Replace "Motion Cut" with "HyperFrames" in Timeline comments
- Fix studio/CLI references to nonexistent archive package
  (use local data/projects/ dir, stub render proxy)

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-21 22:43:56 -07:00