mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
* fix(studio): open SDK shadow session in master view (was never opening) useSdkSession(projectId, activeCompPath) received activeCompPath=null in the master/entry view — the studio's convention where null means index.html (isMasterView = !activeCompPath || activeCompPath === "index.html"). The hook's guard `if (!projectId || !activeCompPath) return` then bailed, so the SDK session never opened in the default editing surface. Result: sdkSession was null there → every shadow tap (onDomEditPersisted, onElementDeleted, timing, gsap) was undefined/no-op → zero sdk_shadow_dispatch telemetry for master-view edits (the common case). Shadow only fired when a sub-comp was explicitly opened (which sets activeCompPath). Resolve null → "index.html" (matching the existing convention used by isMasterView and blockInstaller) so the session opens in master view. Verified live: instrumenting the hook showed phase "skipped_no_ids" (activeCompPath null) before, "opened" after. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(studio): shadow property parity — read camelCase style key, not kebab The inline-style parity resolver read flat.styles[op.property] with the kebab-case PatchOperation key ("background-color"), but ElementSnapshot inlineStyles are camelCase ("backgroundColor"), so the read-back was always null → a false value_mismatch on every hyphenated CSS property. Single-word props (color, opacity) coincide, so unit tests missed it. Found live: a color edit on a box emitted op:property mismatchCount:1 with {property:"background-color", expected:"rgb(255,79,88)", actual:null}. Convert kebab→camel for the read-back (fall back to the raw key). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(studio): emit op:delete shadow for timeline-clip deletes The Delete/Backspace hotkey routes to handleTimelineElementDelete whenever a timeline element is selected (useAppHotkeys: `if (selectedElementId) { handleTimelineElementDelete(el); return; }`), returning before the shadow-wired handleDomEditElementDelete. Every clip is a timeline element, so clip deletes — the common case — emitted no op:delete; the delete shadow only fired for a non-timed DOM selection. Add runShadowDelete(sdkSession, element.hfId) to handleTimelineElementDelete's success path, mirroring the move/resize timing taps. Verified live (browser-use): deleting a clip now emits sdk_shadow_dispatch op:delete dispatched:true mismatchCount:0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(studio): match GSAP fidelity tweens by resolved element, not raw selector gsap_fidelity keyed tweens by id (targetSelector-method-position). On tween ADD, the SDK writer emits [data-hf-id="X"] selectors while the server emits class selectors (.x) for the same element — different ids → false present/absent mismatch (mc:2) on every add. Update/remove were clean (the tween already existed with one consistent selector). Key by resolved element (selector → data-hf-id via the pre-op DOM) + method + position, so equivalent tweens match and only real value drift registers. Falls back to raw selector when resolution isn't possible. Found live (browser-use): adding a tween emitted gsap_fidelity mc:2 with {[data-hf-id="hf-b"]-to-0 present-only} + {.b-to-0 present-only}. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(studio): don't shadow studio-internal data-hf-* marker attributes Property-path parity false-mismatched on canvas-drag (path-offset) edits, which emit attribute ops like {property:"data-hf-studio-path-offset"}: 1. The name was built as `data-${op.property}` → double-prefix "data-data-hf-studio-path-offset". 2. The SDK model excludes all data-hf-* attributes, so even the right name reads back null → false value_mismatch. attrName() prefixes only when needed; isShadowableOp() drops data-hf-* attribute ops (studio-internal markers the SDK can't represent), filtered in sdkShadowDispatch before dispatch + parity. Code-confirmed via handleDomPathOffsetCommit → commitPositionPatchToHtml → persistDomEditOperations → onDomEditPersisted; live repro blocked because the test comp's elements were GSAP-animated (drags route to the GSAP path). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(studio): document tweenKey + selector-resolver ceilings (PR review) Per review (Rames, non-blocking): name the two silent fail-modes in the GSAP fidelity diff rather than build speculative disambiguators (not observed in studio-emitted templates). - tweenKey: coincident tweens (same element+method+position) collapse, last wins. Props can't join the key — a matched pair must share a key for the field-diff to run. Upgrade path: property-name hash. - makeSelectorResolver: first-match heuristic; ambiguous shared-class selectors may misunify. Upgrade path: querySelectorAll + uniqueness. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>