Skip to content
Closed
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
0217232
feat(core): acorn GSAP read path with T6b differential corpus tests
vanceingalls Jun 12, 2026
a737e1f
test(core): extend dropped-key test to cover all four GSAP callback p…
vanceingalls Jun 12, 2026
a1ffdfa
feat(core): acorn GSAP write path — magic-string offset-splice (T6c)
vanceingalls Jun 12, 2026
18d0380
feat(core): parse-parity suite for acorn parser (T6d)
vanceingalls Jun 12, 2026
4da9427
feat(sdk,core): phase 3b — 8 gsap/label ops + setClassStyle
vanceingalls Jun 12, 2026
8ecaeef
refactor(core): swap studio-api read path from recast to acorn parser…
vanceingalls Jun 12, 2026
dfa19d6
fix(core,sdk): code-review findings — 5 correctness bugs + 2 cleanup
vanceingalls Jun 12, 2026
93e8fcd
docs(core): add trust-model header to T6d parity suite
vanceingalls Jun 12, 2026
def5462
feat(sdk): file-backed fs adapter + setTiming GSAP-script sync; add s…
vanceingalls Jun 14, 2026
281b65a
fix(sdk-playground): oxfmt formatting on index.html
vanceingalls Jun 15, 2026
2929d5a
fix(sdk): fs adapter flush() tracks in-flight writes; add to T13 cont…
vanceingalls Jun 14, 2026
e5685b3
feat(sdk): can() returns CanResult; T4 dispatch-boundary tests
vanceingalls Jun 14, 2026
dc55d34
fix(sdk): 8 code-review correctness fixes
vanceingalls Jun 14, 2026
85f4ba6
fix(sdk): export CanResult from package root so callers can switch on…
vanceingalls Jun 15, 2026
58987f3
feat(sdk): stage 4 — canUndo/canRedo, removeElement GSAP cascade, ove…
vanceingalls Jun 14, 2026
002595b
docs(sdk): document cascadeRemoveAnimations bare-id v1 limitation for…
vanceingalls Jun 15, 2026
12e4a2b
feat(sdk): stage 5 — export adapter factories from package root
vanceingalls Jun 14, 2026
b28a81a
feat(sdk): stage 6 — sub-composition scoped ids (F9)
vanceingalls Jun 14, 2026
3ec2adc
feat(sdk): add find({ composition }) filter — Stage 6 WS-C completion
vanceingalls Jun 14, 2026
3f3c813
feat(sdk): stage 7 step 1 — http persist adapter
vanceingalls Jun 14, 2026
07fa7fc
fix(sdk/http): serialize concurrent writes to same path
vanceingalls Jun 15, 2026
ae58fa2
fix(sdk): http adapter — headers option, listVersions/loadFrom doc, f…
vanceingalls Jun 15, 2026
bfecf79
feat(sdk): stage 7 step 2 — setSelection API
vanceingalls Jun 14, 2026
7d5ab82
fix(sdk): guard setSelection against same-id no-ops
vanceingalls Jun 15, 2026
eb59034
fix(sdk): de-duplicate ids in setSelection
vanceingalls Jun 15, 2026
c13f332
fix(sdk): document PreviewAdapter.on("selection") as stage 8 prep
vanceingalls Jun 15, 2026
c4309ea
feat(studio): stage 7 step 1 — wire SDK session into Studio
vanceingalls Jun 14, 2026
1462047
feat(studio): stage 7 step 2 — mirror canvas selection into SDK session
vanceingalls Jun 14, 2026
85c7575
fix(studio): use adapter.read() in useSdkSession bootstrap
vanceingalls Jun 15, 2026
d75f15e
fix(studio): flush in-flight http writes before disposing SDK session
vanceingalls Jun 15, 2026
7c17dd9
fix(studio): dispose SDK session if cleanup fires during openComposition
vanceingalls Jun 15, 2026
0e450d9
feat(sdk,studio): stage 7 step 3a — persistPath + SDK session reload-…
vanceingalls Jun 14, 2026
d86e97c
docs(sdk): document persistPath as immutable for session lifetime
vanceingalls Jun 15, 2026
4520a5f
Merge remote-tracking branch 'origin/main' into sdk-stage7-studio-s7s…
vanceingalls Jun 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 191 additions & 0 deletions sdk-status-report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
@hyperframes/sdk — Status Report
June 13, 2026


OVERVIEW

The SDK is a headless, framework-neutral composition editing engine for HyperFrames.
It lets hosts (Studio, AI agents, Pacific/HeyGen) read and mutate compositions through
a typed method layer that emits RFC 6902 patches. Work is split into 9 stages.
Stages 1–3a are complete and merged. Stages 3b and the acorn parser stack are code
complete and pending review. An interactive playground (sdk-playground) now exercises
the full op surface end-to-end against a live preview and file-backed persistence.


WHAT IS MERGED (DONE)

Stage 1 — Design Decisions
All three gate decisions locked:
- Brand representation: CSS variables (not data-brand-* attributes)
- Timeline model: per-element start/duration/hold
- Storage model: content-addressed SHA-256 keys

Stage 2 — Foundation (Phase 1)
Package scaffolding, types, GSAP serializer, PersistAdapter contract suite (T13),
three host-archetype usage examples. Fully shipped.

Stage 3 — Browser-safe Parser (Phase 2)
Replaced recast/Babel (Node-only, 500KB) with acorn + magic-string (15KB, browser-safe).
This was the technical gate for all editing operations. Five PRs in a Graphite stack:
- #1338 lint rule: warn on missing data-no-timeline
- #1368 acorn read path + differential tests
- #1369 acorn write path (magic-string offset-splice)
- #1370 parse-parity suite (recast vs acorn agreement)
- #1392 swap studio-api files.ts from recast to acorn

Stage 3a — Session API (Phase 3a)
Core session: document model, dispatch/patch loop, history coalescing,
PersistAdapter queue, optional history module. Merged PR #1325.

Gesture-to-Keyframes Stack
The prerequisite for Studio migration step 3 (edit ops). PRs #1301 and #1311 merged.


WHAT IS CODE COMPLETE, IN REVIEW (latest first)

Stage 4 (partial) — can() + T4 tests + FsAdapter T13 [June 13, PR #1425/#1426]
can() now returns structured CanResult ({ok:true} | {ok:false, code, message, hint?})
instead of a bare boolean. validateOp() in mutate.ts matches the same shape.
CAN_OK constant + canErr() helper keep callers concise.
T4 dispatch-boundary tests (session.dispatch.test.ts) cover:
- patch events fire after dispatch
- override-set pipeline via setVariable
- can() CanResult shape for valid/invalid ops
- batch() applies all ops and emits a single patch event
- addGsapTween round-trip via session
- custom origin forwarded through patch event
FsAdapter flush() was a silent no-op: in-flight writes could be abandoned before
they settled, causing a torn write on fast save-quit. Fixed with inflightWrites:
Set<Promise<void>> — flush() now awaits all in-flight promises. Also fixed a
same-millisecond version-key collision with a versionCounter monotonic suffix.
FsAdapter is now exercised by the T13 PersistAdapter contract suite, closing the
gap between the stub and the contract.

Stage 3b — GSAP Editing Engine (Phase 3b)
9 new SDK operations shipped in PR #1379:
addGsapTween, setGsapTween, removeGsapTween
addGsapKeyframe, setGsapKeyframe, removeGsapKeyframe
addLabel, removeLabel
setClassStyle

A code review (June 12) found and fixed 6 bugs before the stack merges:
1. Program-scope variable bindings were silently lost (querySelector at top
level was never resolved). Fixed with a null-key fallback in the scope chain.
2. fromTo argument guard was too loose (could read undefined args[2]/args[3]).
3. removeAnimation had a fuzzing fallback that silently deleted the wrong
animation by converting -from- IDs to -to- IDs. Removed.
4. stagger property was handled in addGsapTween but missing from setGsapTween.
5. apply-patches script case had no handler for op=remove.
6. valueToCode had no NaN guard and used a wrong regex for property key safety.

setTiming GSAP-sync fix (June 13, found via playground)
setTiming was a silent no-op for animation timing on GSAP compositions: it
stamped data-start/data-end on the DOM node, but the runtime re-stamps those
attributes FROM GSAP positions on next init, so the edit was overwritten.
handleSetTiming now also rewrites the GSAP script (parseGsapScriptAcornForWrite
+ updateAnimationInScript), flushing both models in one patch pair so they stay
in sync. DAW-style trim in the playground depends on this.

Stack is awaiting re-stamp from reviewers (Miguel on #1379, Rames on #1368/#1370).

Stage 5 — Adapters (partial, in playground)
fs PersistAdapter is now implemented (was a stub): node:fs/promises read/write,
timestamped version history under .hf-versions/<path>/, prune to maxVersions (20),
listVersions/loadFrom. Still needs to be run against the T13 contract suite.
A fetch-based PersistAdapter (browser → Vite dev-server endpoints) provides the
HTTP shape ahead of the real post-Pacific HTTP adapter.
A concrete PreviewAdapter (PlaygroundPreview) implements select/on('selection')
and the draft/commit/cancel stubs — first real impl beyond the contract.
S3 + production HTTP adapters and the headless null PreviewAdapter remain.

Stage 8 — Packaging and DX (partial)
sdk-playground shipped: interactive browser harness over the full op surface
(setStyle/setText/setAttribute/removeElement/setVariableValue/find/selection
proxy/all 9 GSAP+label ops/setClassStyle), live preview iframe with click-select
and drag-to-reposition, DAW-style timeline trim via setTiming, file-backed
persistence with version history, undo/redo/can/getOverrides/flush, raw-HTML
editor modal. README documents built vs planned.
@hyperframes/editor drop-in, CDN bundle, npm create scaffold, and the docs
ladder remain.


WHAT IS NOT STARTED

Stage 4 remainder
removeElement v1 — cascade rules, override-set removal, soft/hard op classification,
inverse patch carrying full serialized subtree.
createHistory — 300ms coalescing, origin-scoped.

Stage 5 remainder — Adapters (Phase 4)
S3 and production HTTP PersistAdapters (post-Pacific).
PreviewAdapter: headless null adapter for agents and CI.

Stage 6 — Advanced (Phase 5)
Sub-composition editing via scoped element IDs.
Soft vs hard op classification (reversible vs destructive).
Testing utilities for hosts building on the SDK.

Stage 7 — Studio Migration
5-step feature-flag migration. Each step can be rolled back independently.
Step 1: persistence
Step 2: selection
Step 3: edit ops (commit handlers become dispatch calls — absorbs the old R5 track)
Step 4: history
Step 5: App.tsx collapse
Canvas, panel, and timeline components land in a new @hyperframes/react package.
This stage is roughly as much work as everything shipped so far.

Stage 8 remainder — Packaging and DX
@hyperframes/editor: 5-line drop-in component plus CDN bundle.
npm create scaffold (playground itself is shipped — see above).
Full documentation ladder (quickstart, guides, generated reference, architecture explanation).

Stage 9 — Pacific / AI Studio Integration
HyperframesElement draft type, draft_to_edit classification.
heygen_video_workflow fan-out to hyperframes_producer_activity (transparent WebM at
graphic-clip level).
Embedded session wiring, word-aligned timing with shared resolver.


SEPARATE TRACKS

Runtime bridge freeze (R6)
Rename window.__* globals to versioned __HYPERFRAMES.* namespace.
Gated on Phase 1 (complete). Not yet scheduled.

Write-path migration (T6f)
The read path now uses acorn everywhere. The write path (convertToKeyframes,
removeAllKeyframes, setArcPath, etc.) still uses recast. Full migration is the
next post-merge task for the parser team.

GSAP plugin support branch
feat/gsap-plugin-support: code complete, 95 tests, no PR ever opened.
Branch is 79 days old and may be superseded by the acorn parser work.
Decision needed: open a PR, archive, or rebase onto current stack.


ROUGH PROGRESS

Stages complete or in review: 1, 2, 3 (all), 3a, 3b, 4 (partial: can/T4/FsAdapter)
Stages partially done: 5 (fs + fetch adapters, PreviewAdapter impl),
8 (playground shipped)
Stages not started: 4 (remainder: removeElement, createHistory), 6, 7, 9

Current stack is approximately 40% of the full roadmap by stage count.
Stage 7 (Studio Migration) and Stage 9 (Pacific) are the largest remaining efforts.


OPEN QUESTIONS FROM PRD

1. commitPreview() location — recommendation: core session API over PreviewAdapter
2. setHold surface — recommendation: dispatch op
3. Render granularity: per-element WebM now, per-scene layers later?
4. Animation markers: expose GSAP labels for host-level sequencing?
5. North star: model the entire Pacific draft as one SDK document?


CONTACTS

Acorn parser / Phase 3b: Vance
Studio migration: TBD
Pacific integration: TBD
Loading