Commit Graph
2135 Commits
Author SHA1 Message Date
Vance Ingalls 80dc7c49f6 feat(studio): add Blur and Pixelate effect sliders 2026-07-14 15:51:52 -07:00
Vance IngallsandClaude Sonnet 5 93f3bf5945 feat(studio): add Vignette and Grain rows with tuned-settings sub-panel
Also hoists the pointerdown-drag/reset-click test scaffold shared by the
new Roundness tests and the existing Contrast/Exposure tests into helpers
(findRowByText/dragSliderTrack/clickSliderReset), and exempts pre-existing,
branch-inherited fallow findings unrelated to this task (TextFieldEditor
complexity from earlier Text-inspector commits; test-scaffold duplication
across four flat-inspector-series test files from Plans 2-4) via
.fallowrc.jsonc, per this repo's established convention for line-shift/
inherited findings.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:51:51 -07:00
Vance IngallsandClaude Sonnet 5 82cb7b8979 refactor(studio): collapse dead-branch scale ternary in Adjust sliders
Review of Task 6 flagged the exposure/other-key scale ternary as always
resolving to 100 on both arms.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:50:52 -07:00
Vance Ingalls 96d90feb50 feat(studio): add the 10 Adjust sliders to FlatColorGradingSection 2026-07-14 15:50:51 -07:00
Vance Ingalls 9b6bed2824 feat(studio): add FlatColorGradingSection Preset and Custom LUT rows 2026-07-14 15:50:51 -07:00
Vance Ingalls 160193d833 feat(studio): add FlatColorGradingAccessory (compare, status dot, reset) 2026-07-14 15:50:50 -07:00
Vance Ingalls 18e4aef7dc feat(studio): widen FlatSelectRow options to support label!=value entries 2026-07-14 15:50:49 -07:00
Vance Ingalls afafeccf4c feat(studio): add centerTick and reset-slot to FlatSlider for bipolar grade rows 2026-07-14 15:50:49 -07:00
Vance Ingalls 22b3f07c56 refactor(studio): extract useColorGradingController from ColorGradingSection 2026-07-14 15:50:48 -07:00
Vance Ingalls 5a3abdef36 feat(studio): wire the flat Media group into the one-open accordion 2026-07-14 15:50:45 -07:00
Vance Ingalls ea463cdf8f feat(studio): add fit/position rows to FlatMediaSection 2026-07-14 15:50:45 -07:00
Vance Ingalls 79fdff8701 feat(studio): add loop/muted/has-audio-track toggles to FlatMediaSection 2026-07-14 15:50:45 -07:00
Vance Ingalls ab263f25b4 feat(studio): add volume/rate/media-start sliders to FlatMediaSection 2026-07-14 15:50:45 -07:00
Vance Ingalls 138d45faac feat(studio): add cutout sub-block to FlatMediaSection 2026-07-14 15:50:44 -07:00
Vance Ingalls 0e0cb4846d feat(studio): add FlatMediaSection scaffold + source/copy row 2026-07-14 15:50:44 -07:00
Vance Ingalls 14d8de7492 feat(studio): add FlatToggle primitive 2026-07-14 15:50:44 -07:00
Vance IngallsandClaude Sonnet 5 4b592832ab fix(studio): recompute keyframe currentPct from the corrected timing basis in the flat Layout group
Follow-up to 684ec4e87: that fix corrected the seek target for Layout's
keyframe gutter via deriveElementTiming, but currentPct — which drives
KeyframeNavigation's diamond active/inactive state and prev/next arrow
targeting — still used PropertyPanel's naive elStart=0/elDuration=1
basis. For an element with animations but no explicit data-duration,
seeking to a keyframe's real absolute time no longer lit that
keyframe's diamond as active, and the prev/next arrows targeted the
wrong keyframes.

Thread currentTime into PropertyPanelFlat (swapping the now-redundant
currentPct prop 1-for-1, so PropertyPanel.tsx's line count is
unchanged) and recompute currentPct there from the same
deriveElementTiming basis already used for the seek fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:50:43 -07:00
Vance IngallsandClaude Sonnet 5 b155ed46b6 fix(studio): reconcile keyframe-seek timing basis between flat Layout and Motion groups
Whole-plan coherence review (Plan 3a Layout + Plan 3b Motion) found that
Layout's keyframe gutter and Motion's Timing row independently derived an
element's start/duration and disagreed whenever an element had animations
but no explicit data-duration: Motion correctly inferred the range from the
element's GSAP tweens, while Layout's keyframe gutter fell back to a naive
`duration ?? 1`, so clicking a keyframe percentage in Layout could seek to a
different absolute time than what Motion's Timing row displayed.

Extract deriveElementTiming (propertyPanelFlatTimingDerivation.ts) as the
single shared basis both paths now consume: FlatTimingRow (Motion) and
PropertyPanelFlat's own elStart/elDuration (Layout's keyframe gutter and 3D
Transform block). PropertyPanelFlat now recomputes this basis itself from
its own element/gsapAnimations props instead of trusting the parent's naive
value, so PropertyPanel.tsx (and its legacy non-flat panel) is untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:50:43 -07:00
Vance Ingalls 47591f07a6 feat(studio): wire the flat Motion group into the one-open accordion 2026-07-14 15:50:42 -07:00
Vance Ingalls 9676382bb5 feat(studio): compose FlatMotionSection from Timing and the flat effect-card list 2026-07-14 15:50:42 -07:00
Vance Ingalls a3d092ee0f feat(studio): add flat collapsed-header variant to AnimationCard 2026-07-14 15:50:42 -07:00
Vance Ingalls fb1373905f feat(studio): add FlatTimingRow for the flat Motion group 2026-07-14 15:50:42 -07:00
Vance IngallsandClaude Sonnet 5 8602e1a8c9 feat(studio): wire the flat Layout group into the one-open accordion
Thread the Layout-group values through PropertyPanel -> PropertyPanelFlat
and add the third FlatGroup to the one-open/pin accordion (unconditional,
matching legacy Layout). Default-open Layout when neither Text nor Style
applies.

Fix the Flex double-render: the legacy StyleSections still renders its own
Flex Section, and the new flat Layout group renders its own LayoutFlexBlock.
Add an additive optional hideFlex prop to StyleSections and pass it on the
flat path so Flex renders exactly once (from the flat Layout group). Non-flat
callers omit it and are unchanged.

Extract the shared onLivePreviewProps closure into gsapLivePreview.ts (it was
duplicated inline in the legacy path) so PropertyPanel.tsx stays within the
600-LOC studio gate.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:50:41 -07:00
Vance Ingalls 0369865ddb feat(studio): compose FlatLayoutSection from geometry, z-index, flex, and 3D blocks 2026-07-14 15:50:41 -07:00
Vance Ingalls 5edaf6db7a feat(studio): nest the existing 3D transform sub-view in a flat wrapper 2026-07-14 15:50:41 -07:00
Vance IngallsandClaude Sonnet 5 3b958aeb77 feat(studio): add flat Layout Z-index row and Flex sub-block
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-14 15:50:41 -07:00
Vance Ingalls 588895f317 feat(studio): add flat Layout geometry rows (X/Y/W/H/Angle) with keyframe gutters 2026-07-14 15:50:40 -07:00
Vance Ingalls fea582f2b4 feat(studio): wire the flat Style group into the one-open accordion 2026-07-14 15:50:39 -07:00
Vance Ingalls ff7a9c593a feat(studio): add flat Opacity slider, completing the Style group 2026-07-14 15:50:39 -07:00
Vance Ingalls 11d1cc7499 feat(studio): add flat Overflow and Mask rows to the Style group 2026-07-14 15:50:39 -07:00
Vance Ingalls cb8962652b feat(studio): add flat Layer blur and Backdrop sliders to the Style group 2026-07-14 15:50:39 -07:00
Vance Ingalls 9888968219 feat(studio): add flat Shadow and Blend rows to the Style group 2026-07-14 15:50:38 -07:00
Vance Ingalls b86717d758 feat(studio): add flat Stroke and Radius rows to the Style group 2026-07-14 15:50:38 -07:00
Vance Ingalls 2d9989db3b feat(studio): add FlatStyleSection with the flat Fill sub-block 2026-07-14 15:50:38 -07:00
Vance Ingalls 760aa09a43 feat(studio): add stroke-summary format/parse helpers for the flat Style group 2026-07-14 15:50:38 -07:00
Vance Ingalls f71fcf4da0 feat(studio): add FlatSelectRow primitive for the flat inspector 2026-07-14 15:50:37 -07:00
Vance Ingalls 9854c6de71 feat(studio): add FlatSlider primitive for the flat inspector 2026-07-14 15:50:37 -07:00
Vance Ingalls 8224cb2060 feat(studio): flat inspector foundation + Text group (#2120)
## What

First PR in a 6-PR stack migrating Studio's right-panel property inspector from an always-expanded stacked-sections layout to a "flat" one-open-at-a-time accordion. This PR lays the foundation: the `STUDIO_FLAT_INSPECTOR_ENABLED` feature flag, the accordion primitives (`FlatRow`, `FlatSegmentedRow`, `FlatGroup`, `PinnedZoneDivider`), the flat identity header/footer, and the first migrated group — Text.

Stack: #2120 (this) → #2121 (Style) → #2122 (Layout+Motion) → #2123 (Media) → #2124 (Grade) → #2125 (Pinning + multi-field Text).

## Why

The legacy inspector renders every applicable section expanded at once, which gets unwieldy as an element accumulates properties across style/layout/motion/media/grade. The flat redesign shows one section at a time (plus pinned sections), matching a design handoff mock.

## How

- `FlatGroup` owns the one-open accordion state (`openGroupId`/`onToggleOpen`) and pin affordance (`onTogglePin`), styled per the design mock.
- `FlatTextSection` is the first migrated group and the reference implementation every later group's task followed for the `isOpen`/`onToggleOpen`/`onTogglePin`/`summary` wiring pattern.
- Includes a same-PR bugfix (found via live browser testing, not caught by any automated test): the Text `FlatGroup` was rendering unconditionally regardless of element type (empty for non-text elements), and the multi-field fallback doubled the "Text" heading. Fixed by gating on `isTextEditableSelection` and adding a `hideOwnHeading` prop to the legacy `TextSection` fallback.
- Entirely gated behind `STUDIO_FLAT_INSPECTOR_ENABLED` (default off) — the legacy panel is untouched and remains the default for all users.

## Test plan

- Every primitive and the Text group have dedicated Vitest suites using real DOM events (click/pointerdown) with exact assertions, not shallow snapshots.
- Manually verified in Studio via live browser testing against the design mock (this is what caught the bugfix above).
- Full monorepo test suite green; `oxlint`/`oxfmt` clean; this repo's `fallow` complexity/duplication gate passes.
- [x] Unit tests added/updated
- [x] Manual testing performed
- [ ] Documentation updated (not applicable — internal Studio UI behind an off-by-default flag)
2026-07-14 15:47:14 -07:00
Vance Ingalls e85a50662b docs(templates): note how to bump the project's pinned CLI 2026-07-14 15:29:56 -07:00
Vance Ingalls 9bcd279b29 feat(cli): surface stale project pin to non-TTY agents, throttled 2026-07-14 15:28:52 -07:00
Vance Ingalls c1b1c729e5 feat(cli): hyperframes upgrade --project bumps pinned package.json scripts 2026-07-14 15:28:52 -07:00
Vance Ingalls 6fec8f39ae feat(cli): add project-pin rewrite helper 2026-07-14 15:28:51 -07:00
Miguel Ángel 14df58f017 fix(check): ignore registry component templates (#2450) 2026-07-14 18:21:25 -04:00
Miguel Ángel 9e2afbcce5 fix(engine): consolidate capture readiness and retries (#2404)
* fix(engine): await dynamic CSS backgrounds before capture

* fix(render): retry transient network changes

* fix(engine): parse CSS URLs without backtracking

* fix(engine): decode CSS backgrounds in batch capture
2026-07-14 18:10:03 -04:00
Vance Ingalls 97cbe48f30 Merge pull request #2442 from heygen-com/fix/shadow-crossfile-and-stale-anim
fix(studio): cross-file tripwire guard + stale-session disk check for animation parity
2026-07-14 15:04:58 -07:00
Miguel Ángel 9ce44b6603 fix(cli): bundle preview font localization (#2449) 2026-07-14 18:02:51 -04:00
Miguel Ángel 0b3dfb3f84 fix(render): consolidate duration and timing correctness (#2405)
* fix(producer): pass variables to duration probe

* fix(producer): tolerate rounded frame-boundary durations

* fix(cli): resolve relative data-start references in composition duration

`compositions --json` computed each timed child's start with a bare
parseFloat(data-start ?? "0") in parseCompositions (host duration) and
parseSubComposition (sub-comp duration). A relative reference like
data-start="s1" ("start when clip s1 ends") is not numeric, so parseFloat
returned NaN and that clip's contribution to the max-end was silently
dropped — a host with two 3s clips (2nd data-start="s1") reported duration 3
instead of 6, breaking compositions/inspect/snapshot for composition-clip
relative timing.

Resolve relative references the same way the extractor does (parseStartExpression
from @hyperframes/core + a findReferenceTargetEl/resolveReferencedStart port,
since the engine's referenceResolver isn't a public export across the package
boundary). Verified: host duration now 6; 3 tests pass.
(Implemented via Codex; verified independently.)
2026-07-14 17:12:36 -04:00
Miguel Ángel 4b0b89e8b1 chore: release v0.7.58 (#2446) 2026-07-14 16:15:59 -04:00
Vance IngallsandClaude Fable 5 17f3e5beb0 fix(studio): apply cross-file rule to all tripwire entry points; harden disk-truth check
Review round on PR #2442:

- miguel (blocker): the cross-file eligibility rule only guarded the
  dom-edit tripwire; recordResolverParity and
  recordAnimationResolverParity ran before wrongCompositionFile at
  every cutover surface, so cross-file ops still emitted false
  element_not_found (id present in the OTHER file's source passes the
  runtime-node filter) and polluted the attempt denominator. The rule
  now lives in one shared isCrossFileEdit guard applied by all three
  entry points, wired with { targetPath, compositionPath } at all six
  sdkCutover call sites (timing, timing-batch, gsap add/set/remove,
  keyframe chokepoint, delete).

- Rames (race): the disk-truth read is now dispatched SYNCHRONOUSLY in
  the same prologue as the miss check, before control returns to the
  caller whose cutover persist writes the same file moments later — a
  post-write read would see a remove op's target legitimately gone and
  misclassify it as a genuine divergence. Sync reader throws become
  rejections (IIFE), not exceptions into the swallow-all catch.

- Rames (parse failure): openComposition failure inside the disk check
  now fails open as sourceReadFailed (unparseable source is not ground
  truth), instead of the outer catch dropping the divergence event
  entirely.

recordResolverParity's source check extracted to checkHfIdInSource
(complexity gate), mirroring checkAnimationIdOnDisk's error discipline.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 13:13:09 -07:00
Miguel Ángel 6c2513d5c8 fix(check): resolve color-mix() colors in contrast audit instead of false-failing (#2445) 2026-07-14 15:51:11 -04:00