Summary
camkit rebuild can produce a project.tscproj that permanently hangs Camtasia on open (CPU pegged 600-750%, unresponsive, system-wide lag, never self-resolves after 2+ min, requires force-quit) when a single screen-recording source (ScreenVMFile + paired UnifiedMedia camera track) is cut into 3 or more separate timeline fragments.
Repro
Confirmed on fc-loop.cmproj (Camtasia build 2026.1.3) via isolated scratch-copy testing:
- Take a project with a screen+camera recording source (dual-track:
ScreenVMFile on one track, UnifiedMedia on a paired track, same src id, matching start/duration).
- Run
camkit rebuild --from <keep.json> --force with a keep-list that references that source 3+ times (3+ separate {start,end} ranges from the same src).
camkit open (or manually opening the resulting .cmproj) hangs Camtasia indefinitely.
Isolation results
- 1 fragment from a screen source: opens fine, low CPU.
- 2 fragments from the same screen source: opens fine.
- 3 fragments from the same screen source: hangs, reproducibly. Confirmed independent of whether Camtasia was already warm/idle or freshly launched — not a startup race.
- Plain webcam-only (
UnifiedMedia, no screen capture) sources cut into many fragments: no problem, even many cuts.
- The resulting
project.tscproj was verified valid: correct JSON, sane sourceBin/track/media counts, matching start/duration between the two tracks of a screen+camera pair, no negative/zero-duration clips, no group/link fields present or malformed in the schema.
packages/core/src/rebuild.ts is unchanged between main and the live-timeline-editing branch (verified via git diff main...HEAD), so this is not a branch-specific regression — main should reproduce identically.
Hypothesis (unconfirmed)
Camtasia is a closed binary so the internal mechanism isn't directly inspectable. Best guess: something Camtasia recomputes per screen-recording fragment on load — likely SmartFocus/cursor-tracking data or thumbnail/waveform proxy generation (each clip's parameters includes cursorTrackLevel, cursorScale, geometryCrop0-3, etc.) — that's cheap for 1-2 fragments but becomes pathological (infinite loop or exponential blowup) at 3+.
Impact
Blocks the rough-cut skill (skills/rough-cut/SKILL.md) for any screen-recording-heavy project, since a real rough cut typically needs many more than 2 cuts inside a single screen recording.
Next steps to investigate
- Diff a working 2-fragment
project.tscproj against a hanging 3-fragment one field-by-field for anything that changes qualitatively (not just count).
- Sample the hung Camtasia process's stack (Activity Monitor "Sample Process") to see what function it's actually spinning in.
- Try merging adjacent kept fragments within a screen source below some gap threshold in
rebuild.ts so each screen source ends up with only 1-2 pieces instead of many, as a workaround pending a real fix.
Summary
camkit rebuildcan produce aproject.tscprojthat permanently hangs Camtasia on open (CPU pegged 600-750%, unresponsive, system-wide lag, never self-resolves after 2+ min, requires force-quit) when a single screen-recording source (ScreenVMFile+ pairedUnifiedMediacamera track) is cut into 3 or more separate timeline fragments.Repro
Confirmed on
fc-loop.cmproj(Camtasia build 2026.1.3) via isolated scratch-copy testing:ScreenVMFileon one track,UnifiedMediaon a paired track, samesrcid, matching start/duration).camkit rebuild --from <keep.json> --forcewith a keep-list that references that source 3+ times (3+ separate{start,end}ranges from the samesrc).camkit open(or manually opening the resulting.cmproj) hangs Camtasia indefinitely.Isolation results
UnifiedMedia, no screen capture) sources cut into many fragments: no problem, even many cuts.project.tscprojwas verified valid: correct JSON, sanesourceBin/track/media counts, matching start/duration between the two tracks of a screen+camera pair, no negative/zero-duration clips, no group/link fields present or malformed in the schema.packages/core/src/rebuild.tsis unchanged betweenmainand thelive-timeline-editingbranch (verified viagit diff main...HEAD), so this is not a branch-specific regression —mainshould reproduce identically.Hypothesis (unconfirmed)
Camtasia is a closed binary so the internal mechanism isn't directly inspectable. Best guess: something Camtasia recomputes per screen-recording fragment on load — likely SmartFocus/cursor-tracking data or thumbnail/waveform proxy generation (each clip's
parametersincludescursorTrackLevel,cursorScale,geometryCrop0-3, etc.) — that's cheap for 1-2 fragments but becomes pathological (infinite loop or exponential blowup) at 3+.Impact
Blocks the
rough-cutskill (skills/rough-cut/SKILL.md) for any screen-recording-heavy project, since a real rough cut typically needs many more than 2 cuts inside a single screen recording.Next steps to investigate
project.tscprojagainst a hanging 3-fragment one field-by-field for anything that changes qualitatively (not just count).rebuild.tsso each screen source ends up with only 1-2 pieces instead of many, as a workaround pending a real fix.