Skip to content

feat(studio): rebuild remaining Ular stack on current main#2291

Open
miguel-heygen wants to merge 15 commits into
mainfrom
magi/rebuilt-studio-stack
Open

feat(studio): rebuild remaining Ular stack on current main#2291
miguel-heygen wants to merge 15 commits into
mainfrom
magi/rebuilt-studio-stack

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

Rebuilds the remaining Studio stack from origin/studio-dnd/consolidated-tip onto current main after Graphite closed-parent races.

Includes the exact Ular payload for the remaining logical changes (#2205, #2207, #2209, #2212, #2214, #2216), applied in order. Conflict resolution was limited to the .fallowrc canonical file and the timeline/thumbnail transitions; no commits were dropped.

Validation: commit ancestry and clean worktree verified. Local Studio typecheck could not run because this clean checkout has no node_modules (vite/client missing); required CI must be the merge gate.

Please review current-head diff and run full required checks before merge.

What: extends 21 glue files so the OLD timeline/canvas engine and the NEW
NLE components type-check side by side: playerStore (multi-select setters,
zoom pin, snap toggle, non-reactive scale scratch), drag-state types gain
optional NLE fields, timelineLayout/timelineAssetDrop/timelineEditingHelpers/
timelineEditing/timelineElementHelpers/studioHelpers/assetHelpers gain the
NLE exports, DomEditOverlay + gestures + AssetContextMenu + Timeline props
gain optional callbacks/params, contexts gain *Optional hooks, and
TimelineEditCallbacks.onMoveElements becomes a bivariant method accepting
both engines' change shapes. patchDocumentRootDuration's test rides along.

Why: this is the keystone that dissolves the old "welded glue" problem —
every symbol the NLE components need is ADDED next to what the old engine
still uses, so the engine components and the swaps can land as separate
reviewable PRs.

How: 15 authored intermediate files (main content + additive symbols; no
behavior changes — new fields optional, new callbacks unused until wired)
plus 6 files whose final content is already purely additive. New exports
without consumers yet carry TEMP(studio-dnd) ignoreExports entries, removed
by the app-shell swap.

Test plan: tsc --noEmit in studio + studio-server (verifies BOTH engines
compile); bunx vitest run (full suite green incl. the 6 new
patchDocumentRootDuration tests); fallow audit clean.
What: the timeline-side wiring layer, unwired: TimelineLanes (the lane
renderer driving drag/resize/marquee), timelineMarquee (+tests),
useTimelineStackingSync, useTimelineGeometry, useTimelineEditPinning,
useTimelineEditingDrops.

Why: everything between the pure drag math and <Timeline> itself; the
timeline-glue swap PR then only rewires Timeline/TimelineCanvas onto these.

How: new files, tsc-clean against the coexistence layer. Unwired components
carry TEMP(studio-dnd) entry registrations, removed at the app-shell swap.

Test plan: bunx vitest run timelineMarquee.test.ts; tsc --noEmit; fallow
audit clean.
What: EditorShell (the full editor layout replacing NLELayout +
StudioPreviewArea), TimelinePane (timeline host with sub-comp rebasing) and
useTimelineEditCallbacks (the callback bag bridging store edits to the
timeline), all unwired.

Why: the shell that App swaps to in the final step; reviewing it standalone
keeps that swap PR small.

How: new files against the coexistence layer; TEMP(studio-dnd) entries
until App mounts EditorShell in the app-shell swap.

Test plan: tsc --noEmit; bunx vitest run (suite unchanged); fallow audit
clean.
…LE engine

What: flips the timeline glue to its final form (23 files): Timeline and
TimelineCanvas rebuilt on TimelineLanes/TimelineOverlays, useTimelineClipDrag
drives preview/commit through the new drag engine, range selection goes
multi-select, playback loop moves to useTimelinePlayerLoop. Deletes the 9
old-engine files this orphans (group drag, marquee selection, snap targets,
layer gutter, selection overlays + their suites) — each is compile- or
gate-forced by this swap, verified by probe.

Why: second swap step; timeline-only, canvas and App untouched.

How: modified files to final content + forced deletions.
playerStore/timelineEditing/timelineCallbacks stay at their coexistence
form until the app swap (the old App still runs on them).

Test plan: tsc --noEmit; bunx vitest run (full suite); fallow audit clean.
What: ImageThumbnail (+tests) and thumbnailUtils (+tests) — frame decode
with SVG/AVIF format fallbacks and rounded-corner clipping — plus
VideoThumbnail updates.

Why: the decode layer for timeline clip thumbnails, ahead of the visual
refresh that renders them.

How: new modules + one modified file; purely presentational.

Test plan: bunx vitest run on both test files; tsc --noEmit; fallow audit
clean.
What: blocks tab install flow, right-panel and global drag-overlay polish,
music beat analysis and clip-content rendering hooks, and the
preview-helper utilities backing asset preview.

Why: completes the studio NLE stack on top of the visual refresh.

How: modified files only (kept as one PR: splitting further would produce
sub-150-LOC fragments of interdependent panel glue).

Test plan: bunx vitest run studioPreviewHelpers/studioUrlState suites; tsc
--noEmit; fallow audit clean.
@github-actions

github-actions Bot commented Jul 12, 2026

Copy link
Copy Markdown

Fallow audit report

Found 103 findings.

Dead code (38)
Severity Rule Location Description
major fallow/unused-file packages/studio/src/components/EditorShell.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/editor/domEditOverlayGeometry.ts:228 Export 'overlayCornersCentroid' is never imported by other modules
major fallow/unused-export packages/studio/src/components/editor/domEditOverlayGeometry.ts:246 Export 'elementCornerOverlayPoints' is never imported by other modules
major fallow/unused-export packages/studio/src/components/editor/domEditOverlayGeometry.ts:325 Export 'orientedOverlayRect' is never imported by other modules
major fallow/unused-export packages/studio/src/components/editor/manualOffsetDrag.ts:489 Export 'applyManualOffsetNudgeDraft' is never imported by other modules
major fallow/unused-export packages/studio/src/components/editor/manualOffsetDrag.ts:503 Export 'applyManualOffsetNudgeCommit' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/AssetPreviewOverlay.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/AssetPreviewOverlay.tsx:79 Export 'AssetPreviewOverlay' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/NLEContext.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/NLEContext.tsx:25 Export 'shouldDisableTimelineWhileCompositionLoading' is never imported by other modules
major fallow/unused-export packages/studio/src/components/nle/NLEContext.tsx:60 Export 'useNLEContext' is never imported by other modules
major fallow/unused-export packages/studio/src/components/nle/NLEContext.tsx:77 Export 'NLEProvider' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/PreviewOverlays.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/PreviewOverlays.tsx:112 Export 'PreviewOverlays' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/PreviewPane.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/PreviewPane.tsx:50 Export 'PreviewPane' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/TimelinePane.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/TimelinePane.tsx:38 Export 'TimelinePane' is never imported by other modules
major fallow/unused-file packages/studio/src/components/nle/useTimelineEditCallbacks.ts:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/nle/useTimelineEditCallbacks.ts:41 Export 'useTimelineEditCallbacks' is never imported by other modules
major fallow/unused-file packages/studio/src/components/sidebar/AssetCard.tsx:1 File is not reachable from any entry point
major fallow/unused-export packages/studio/src/components/sidebar/AssetContextMenu.tsx:84 Export 'DeleteConfirm' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingGsap.ts:17 Export 'patchIframeRootDuration' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingGsap.ts:38 Export 'shiftGsapPositionsBatch' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingGsap.ts:62 Export 'syncTimingEditPreview' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingHelpers.ts:597 Re-export 'patchIframeRootDuration' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingHelpers.ts:598 Re-export 'shiftGsapPositionsBatch' is never imported by other modules
major fallow/unused-export packages/studio/src/hooks/timelineEditingHelpers.ts:599 Re-export 'syncTimingEditPreview' is never imported by other modules
major fallow/unused-file packages/studio/src/hooks/useTimelineEditingDrops.ts:1 File is not reachable from any entry point
major fallow/unused-type packages/studio/src/player/components/timelineEditing.ts:18 Type re-export 'TimelineGroupResizeEdge' is never imported by other modules
major fallow/unused-type packages/studio/src/player/components/timelineEditing.ts:19 Type re-export 'TimelineGroupTimingMember' is never imported by other modules
major fallow/unused-export packages/studio/src/player/components/timelineEditing.ts:335 Export 'selectTimelineElementsInMarquee' is never imported by other modules
major fallow/unused-export packages/studio/src/player/components/timelineGroupEditing.ts:187 Export 'buildTimelineGroupResizeMembers' is never imported by other modules
major fallow/unused-export packages/studio/src/player/components/timelineGroupEditing.ts:215 Export 'resolveTimelineGroupResizeChanges' is never imported by other modules
major fallow/unused-export packages/studio/src/player/components/timelineGroupEditing.ts:246 Export 'applyTimelineGroupResizePreview' is never imported by other modules
major fallow/unused-export packages/studio/src/player/lib/timelineElementHelpers.ts:72 Export 'furthestClipEndFromDocument' is never imported by other modules
major fallow/unused-export packages/studio/src/player/lib/timelineElementHelpers.ts:99 Export 'furthestClipEndFromSource' is never imported by other modules
major fallow/unused-export packages/studio/src/utils/timelineAssetDrop.ts:150 Export 'setCompositionDurationToContent' is never imported by other modules
Duplication (52, showing 50)
Severity Rule Location Description
minor fallow/code-duplication packages/studio/src/components/EditorShell.tsx:52 Code clone group 1 (424 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/EditorShell.tsx:192 Code clone group 2 (11 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/StudioPreviewArea.tsx:77 Code clone group 1 (424 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/StudioPreviewArea.tsx:189 Code clone group 3 (19 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/StudioPreviewArea.tsx:252 Code clone group 4 (98 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/StudioPreviewArea.tsx:431 Code clone group 5 (27 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLEContext.tsx:116 Code clone group 6 (27 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLEContext.tsx:140 Code clone group 7 (45 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLEContext.tsx:178 Code clone group 8 (79 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLEContext.tsx:257 Code clone group 9 (21 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:45 Code clone group 10 (19 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:159 Code clone group 6 (27 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:187 Code clone group 7 (45 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:231 Code clone group 11 (47 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:256 Code clone group 12 (38 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:292 Code clone group 8 (79 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:370 Code clone group 9 (21 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:395 Code clone group 13 (14 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:414 Code clone group 2 (11 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:512 Code clone group 14 (18 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/NLELayout.tsx:530 Code clone group 15 (22 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/PreviewOverlays.tsx:185 Code clone group 5 (27 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/PreviewPane.tsx:92 Code clone group 13 (14 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/TimelinePane.tsx:14 Code clone group 10 (19 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/TimelinePane.tsx:64 Code clone group 11 (47 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/TimelinePane.tsx:109 Code clone group 12 (38 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/TimelinePane.tsx:167 Code clone group 14 (18 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/TimelinePane.tsx:186 Code clone group 15 (22 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/useTimelineEditCallbacks.ts:63 Code clone group 3 (19 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/components/nle/useTimelineEditCallbacks.ts:89 Code clone group 4 (98 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/timelineEditingHelpers.ts:544 Code clone group 16 (13 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/timelineEditingHelpers.ts:567 Code clone group 16 (13 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useAnimatedPropertyCommit.test.tsx:79 Code clone group 17 (9 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useAnimatedPropertyCommit.test.tsx:93 Code clone group 17 (9 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useBlockHandlers.ts:14 Code clone group 18 (13 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditing.ts:351 Code clone group 19 (110 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditing.ts:459 Code clone group 20 (8 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditing.ts:479 Code clone group 21 (32 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditing.ts:501 Code clone group 22 (24 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditing.ts:524 Code clone group 23 (11 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditingDrops.ts:48 Code clone group 19 (110 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditingDrops.ts:94 Code clone group 20 (8 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditingDrops.ts:146 Code clone group 21 (32 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditingDrops.ts:168 Code clone group 22 (24 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/hooks/useTimelineEditingDrops.ts:191 Code clone group 23 (11 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/player/components/ImageThumbnail.test.tsx:8 Code clone group 24 (28 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/player/components/VideoThumbnail.test.tsx:7 Code clone group 24 (28 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/player/components/VideoThumbnail.test.tsx:96 Code clone group 25 (15 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/player/components/VideoThumbnail.test.tsx:138 Code clone group 25 (15 lines, 2 instances)
minor fallow/code-duplication packages/studio/src/utils/blockInstaller.ts:35 Code clone group 18 (13 lines, 2 instances)

Showing 50 of 52 findings. Run fallow locally or inspect the CI output for the full report.

Health (12)
Severity Rule Location Description
minor fallow/high-crap-score packages/studio/src/components/editor/domEditOverlayGeometry.ts:246 'elementCornerOverlayPoints' has CRAP score 31.6 (threshold: 30.0, cyclomatic 10)
minor fallow/high-cognitive-complexity packages/studio/src/components/editor/manualOffsetDrag.ts:328 'createManualOffsetDragMember' has cognitive complexity 17 (threshold: 15)
major fallow/high-crap-score packages/studio/src/components/nle/NLEContext.tsx:151 'handleDrillDown' has CRAP score 90.0 (threshold: 30.0, cyclomatic 9)
major fallow/high-crap-score packages/studio/src/components/nle/NLEContext.tsx:191 '<arrow>' has CRAP score 72.0 (threshold: 30.0, cyclomatic 8)
minor fallow/high-crap-score packages/studio/src/components/nle/NLEContext.tsx:237 '<arrow>' has CRAP score 42.0 (threshold: 30.0, cyclomatic 6)
minor fallow/high-crap-score packages/studio/src/components/sidebar/AssetCard.tsx:144 'handlePointerUp' has CRAP score 42.0 (threshold: 30.0, cyclomatic 6)
minor fallow/high-crap-score packages/studio/src/components/sidebar/AssetCard.tsx:266 'FontRow' has CRAP score 30.0 (threshold: 30.0, cyclomatic 5)
critical fallow/high-crap-score packages/studio/src/player/hooks/usePlaybackKeyboard.ts:83 'handlePlaybackKeyDown' has CRAP score 253.2 (threshold: 30.0, cyclomatic 32)
minor fallow/high-cognitive-complexity packages/studio/src/player/lib/timelineElementHelpers.ts:124 'applyMediaMetadataFromElement' has cognitive complexity 20 (threshold: 15)
minor fallow/high-crap-score packages/studio/src/player/lib/timelineElementHelpers.ts:316 'nodeMatchesManifestClip' has CRAP score 43.1 (threshold: 30.0, cyclomatic 12)
minor fallow/high-cognitive-complexity packages/studio/src/player/lib/timelineIframeHelpers.ts:40 'autoHealMissingCompositionIds' has cognitive complexity 23 (threshold: 15)
critical fallow/high-crap-score packages/studio/src/player/lib/timelineIframeHelpers.ts:284 '<arrow>' has CRAP score 659.7 (threshold: 30.0, cyclomatic 53)
Architecture (1)
Severity Rule Location Description
major fallow/circular-dependency packages/studio/src/player/components/timelineEditing.ts:9 Circular dependency: packages/studio/src/player/components/timelineEditing.ts → packages/studio/src/player/components/timelineGroupEditing.ts

Generated by fallow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants