Deploy:
- Multi-stage Dockerfile (shadow-cljs release → Python+ffmpeg runtime), fly.toml
(one machine, scale-to-zero, SQLite on a volume), .dockerignore, DEPLOY.md
- Same-origin release build: api-port defaults "9001" for dev, "" in release
(no CORS in prod)
- env-driven settings (SECRET_KEY/DEBUG/ALLOWED_HOSTS/DB_PATH/CSRF), WhiteNoise
serving static + the SPA, R2 (S3-compatible) media storage when R2_* is set
- thumbnails reworked storage-agnostic: download clip, ffmpeg select-pass, upload
tiles via default_storage (R2 in prod, disk in dev)
- pin channels/daphne; add whitenoise/django-storages/boto3
UI:
- frame step buttons flanking play (disabled at timeline bounds)
- Add-annotation button moved into the toolbar, made prominent
- picker mode pulses a 1-bit glow on clips / frame readout / (while linking)
annotation bars; linking an annotation bar inserts a timeline link
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend / dev:
- Bind dev server to 0.0.0.0 and allow Tailscale MagicDNS + tailnet-IP origins
in ALLOWED_HOSTS / CORS / CSRF so the app is reachable over Tailscale
- Unified, idempotent dev launcher (Django + media + shadow watch), hot reload,
no manual compiles
Frontend:
- Migrate fetches to re-frame :http-xhrio with failure handling; surface
network / load / save errors where the user expects them
- Extract markdown + link formatting into tl.md: parse/serialize round-trip
(recursive chip serialization fix), block markdown (headings/lists/paragraphs)
- Timeline-opening links: navigate the stack to any reachable timeline;
autocomplete lists all timelines (root included, orphans dropped) with a live
preview that pushes the stack and reverts on commit/cancel
- Annotation pane shows the current context's description with edit-in-context
(drops into the parent timeline for marks, pops back when done) + root content
- Fixes: deep-link playhead seek, replay-from-end, mobile input zoom, notch
safe-area insets, autofocus the content field, freeze form to snapshot context
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Script pane: PDF tab beside annotations; "Add script annotation" arms
highlight mode on the draft, ✓/✕ to confirm/cancel, auto-scrolls to the
active annotation's highlights during playback. Adds Project.script.
- Realtime: Django Channels websocket per project broadcasts attributed
scene deltas after each save; peers merge them in (keeping local drafts).
- Logout link in the editor project-bar.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Project gains a clip FileField; POST /api/projects/ creates one from an
uploaded otio + clip (<=100 MB), owned by the requester
- add /api/me/ and project-detail; scene GET is public (view without login),
PUT stays owner/collaborator-only
- serve media in DEBUG (range requests for video seek); CORS for the cljs dev
origin with credentials
- seed_demo now builds the Challengers project from the bundled otio + 480p clip
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A Project (owner, OTIO file, fps, scene JSON) persists the timeline. Session
API: list projects, GET/PUT scene, serve OTIO. Admin manages users/projects;
seed_demo creates a project from the bundled one_two_three.otio.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>