Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 5 additions & 5 deletions .agents/rules/edit-mode-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,14 +199,14 @@ When developing, refactoring, or adding features to Edit mode in SceneFlow, stri
- The raw cues modal provides a comprehensive 2-column workstation (`RawCuesModal.tsx`):
- **Left Column**: Live schema reference with essential fields (`startTime`, `endTime`, `selectedText`, `type`), collapsible optional/auto-calculated fields, and quick copyable example snippet with 1-click insertion.
- **Right Column**: Dual-tab workspace housing the `{ } JSON Data` editor and `🤖 Sync Prompt & Schema` AI integration deck.
- **Minimal Canonical Schema Contract (`cues.schema.json`, `public/schema.json`)**:
- JSON schema must remain strictly a structural data contract (types, enums, required fields).
- Avoid verbose descriptions inside schema properties, as excessive natural language degrades token sampling quality during LLM constrained decoding.
- Business logic—such as verbatim `<ScriptText>` excerpt copying and `(minutes * 60) + seconds` timecode math—is enforced within `cues.prompt.ts` (`public/sync-prompt.txt`).
- **Minimal Canonical Schema & Prompt SSOT (`src/schemas/cues.schema.json`, `src/schemas/cues.prompt.ts`, `vite.config.ts`)**:
- `src/schemas/` is the Single Source of Truth (SSOT); `cuesAssetsPlugin` in `vite.config.ts` serves `/sync-prompt.txt` and `/schema.json` in dev and emits them to `dist/` at build time without maintaining duplicate files in `public/`.
- `cues.schema.json` must remain strictly a Gemini-compatible structural data contract (types, enums, nullable `speaker`, required fields: `id`, `type`, `speaker`, `selectedText`, `startTime`, `endTime`) without `$schema` or verbose natural-language bloat.
- Business logic—such as verbatim `<ScriptText>` excerpt copying, `[[STAGING]]` block exclusion, chronological sorting, `endTime > startTime`, speaker extension stripping, `(minutes * 60) + seconds` timecode math, and the 8 cue `type` definitions—is enforced within `cues.prompt.ts`.
- **Draft Baseline UI Separation**:
- Guidance indicating that prompts provide a draft baseline for user customization must reside cleanly outside the markdown prompt text in the UI to keep copied prompts ready for Gemini/LLM system instructions.
- **Segmented Sub-View Switcher (`prompt` | `schema` | `split`)**:
- Supports switching between full-width views (`prompt` or `schema`) to ensure zero horizontal scrollbars on JSON schema lines, while preserving a `split` option for side-by-side comparison on wide screens.
- Supports switching between full-width views (`prompt` or `schema`) to ensure zero horizontal scrollbars on JSON schema lines, while preserving a `split` option for side-by-side comparison on wide screens. Each panel header owns a single Copy action (no duplicate toolbar copy buttons or redundant top-right `Edit JSON` tab switches).
- **Context-Aware Footer & Wrap-Resistant Buttons**:
- Footers adapt actions dynamically per tab: `Cancel` and `Apply Cues (N)` on JSON Data; `Close` and `Go to JSON Data →` on Sync Prompt & Schema.
- Buttons must declare `whitespace-nowrap`, matching vertical padding (`py-2`), and Title Case labels to eliminate multi-line wrapping and container height distortion.
Expand Down
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CI

on:
push:
branches: [main, dev]
pull_request:

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

- name: Install dependencies
run: npm ci

- name: Typecheck
run: npm run lint

- name: Build
run: npm run build
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [2.6.0] - 2026-11-14

### Refactored
- **Sync Prompt & Schema Single Source of Truth (`src/schemas/`, `vite.config.ts`)**:
- Removed duplicate `public/sync-prompt.txt` and `public/schema.json` static files.
- Added `cuesAssetsPlugin` in `vite.config.ts` to serve `/sync-prompt.txt` and `/schema.json` in dev middleware and emit them into `dist/` during production builds directly from `src/schemas/cues.prompt.ts` and `src/schemas/cues.schema.json`.
- **Cues JSON Editor UI Cleanup (`src/components/RawCuesModal.tsx`)**:
- Removed duplicate copy buttons from the `Sync Prompt & Schema` sub-view toolbar (retaining the single contextual Copy button in each panel header) and removed the redundant top-right `Edit JSON →` tab-switch button.

### Changed
- **Sync Prompt & Gemini Schema Refinement (`src/schemas/cues.prompt.ts`, `src/schemas/cues.schema.json`)**:
- Updated `CUES_SYNC_PROMPT` to preserve casing, ignore `[[STAGING]]` blocks, enforce chronological sorting and `endTime > startTime` (minimum `0.5s` for instantaneous transitions/shots), strip `(V.O.)`/`(O.S.)`/`(CONT'D)` extensions from `speaker`, and define all 8 cue `type` categories.
- Updated `cues.schema.json` to mark `speaker` as `required` with `nullable: true` (`"Explicitly null if non-dialogue."`) and stripped non-Gemini `$schema` metadata.

### Added
- **7 New AI Scenes Examples (`src/examples.ts`, `SCENEFLOW_CATALOGUE.md`)**:
- Added `scene_screaming_amber_wood.json` (**Screaming Amber Wood**, Seedance 2.5), `scene_coordinates_for_three.json` (**Coordinates for Three**, Seedance 2.5), `scene_pineapple.json` (**Pineapple**, Seedance 2.0), `scene_what_the_glacier_keeps.json` (**What the Glacier Keeps**, Seedance 2.0), `scene_paperweight.json` (**Paperweight**, Seedance 2.0), `scene_the_unresolved_variable.json` (**The Unresolved Variable**, Seedance 2.0), and `scene_the_event_boundary.json` (**The Event Boundary**, Seedance 2.0) under `public/examples/scenes/`.
- Registered all 7 projects under **AI Scenes** in `src/examples.ts` with `auteur script` and Seedance tags, loglines/release dates from `vector-film`, and updated `SCENEFLOW_CATALOGUE.md` (24 total AI Scenes).
- **Local Video File Playback ([#19](https://github.com/taruma/SceneFlow/pull/19))**:
- Added a **Local File** picker in the Edit-mode source bar to play local `.mp4`, `.webm`, and `.mov` files via an HTML `<video>` element for the current session without modifying the project's `youtubeId` or saved JSON.
- Introduced the `MediaPlayer` interface (`src/lib/mediaPlayer.ts`) and `createVideoElementPlayer` adapter so transport, timeline scrubbing, seeking, loop preview, keyboard shortcuts, and cue timing work uniformly across YouTube and local video sources.
- Added codec/file decode error handling (`"This browser can't play this file"`) and updated `README.md` (contributed by [@icanhasjonas](https://github.com/icanhasjonas)).
- **Last Radio [AI Clips] Example (`clip_last_radio`, `src/examples.ts`, `SCENEFLOW_CATALOGUE.md`)**:
- Added new sample project `clip_last_radio.json` featuring a visceral 35mm disaster thriller cross-cut between a submerging subterranean parking structure and a storm-battered street command zone with Seedance 2.5 cue mappings synchronized to YouTube playback.
- Registered 'Last Radio' under **AI Clips** in `src/examples.ts` and updated `SCENEFLOW_CATALOGUE.md`.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ https://github.com/user-attachments/assets/cf3a7fec-2a4b-48d8-9028-245eba49934c
### Platform & Performance

- **Mobile-Responsive** — Native bottom-sheet drawers for library and themes with adaptive staging badges and sticky mobile video transport
- **App Info & Attribution** — Desktop information modal with dynamic versioning (`v2.5.1`), author attribution, and documentation resource links
- **App Info & Attribution** — Desktop information modal with dynamic versioning (`v2.6.0`), author attribution, and documentation resource links
- **Centralized Keyboard Shortcuts Registry & Interactive Cheat-Sheet Modal** — Searchable modal triggered globally via <kbd>?</kbd> (<kbd>Shift+/</kbd>) or Studio Settings, featuring category filter tabs, platform glyphs (<kbd>⌘</kbd> vs <kbd>Ctrl</kbd>), and quick navigation hotkeys (<kbd>Shift+F</kbd> File Menu, <kbd>Shift+S</kbd> Source Script, <kbd>Shift+E</kbd> Cue Editor, <kbd>Shift+L</kbd> Library, <kbd>Ctrl+Enter</kbd> Script Commit)
- **High-Performance Architecture** — Monolithic bundle splitting via dynamic `React.lazy()` secondary modals and Vite Rollup `manualChunks`, slashing initial JS bundle payload by **70%** (778 kB → 243 kB; 215 kB → 65 kB gzip)
- **Vercel Analytics** — Audience traffic insights and real-time Web Vitals monitoring
Expand Down
9 changes: 8 additions & 1 deletion SCENEFLOW_CATALOGUE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@ To load a remote project, use `?project=URL`.

---

## AI Scenes (17)
## AI Scenes (24)

| Date | ID | Title | Video Model |
|---|---|---|---|
| 2026-08-16 | `scene_screaming_amber_wood` | Screaming Amber Wood | Seedance 2.5 |
| 2026-08-15 | `scene_coordinates_for_three` | Coordinates for Three | Seedance 2.5 |
| 2026-08-12 | `scene_three_years_late` | Three Years Late | Seedance 2.5 |
| 2026-08-11 | `scene_observation_only` | Observation Only | Seedance 2.5 |
| 2026-08-09 | `scene_entropy` | Entropy | Seedance 2.5 |
| 2026-08-08 | `scene_frequency` | Frequency Over Force *(default)* | Seedance 2.5 |
| 2026-07-30 | `scene_pineapple` | Pineapple | Seedance 2.0 |
| 2026-07-27 | `scene_what_the_glacier_keeps` | What the Glacier Keeps | Seedance 2.0 |
| 2026-07-23 | `scene_paperweight` | Paperweight | Seedance 2.0 |
| 2026-07-17 | `scene_still_here` | Still Here | Seedance 2.0 |
| 2026-07-09 | `scene_the_unresolved_variable` | The Unresolved Variable | Seedance 2.0 |
| 2026-07-03 | `scene_the_event_boundary` | The Event Boundary | Seedance 2.0 |
| 2026-06-16 | `scene_vector_field` | Vector Field | Seedance 2.0 |
| 2026-06-13 | `museum` | Museum | Seedance 2.0 |
| 2026-05-24 | `afraid` | Afraid | Seedance 2.0 |
Expand Down
12 changes: 7 additions & 5 deletions docs/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,15 +340,17 @@ When developing or modifying playback, cue synchronization, or timeline visualiz
2. `mouseDownPosRef`: Tracks drag displacement with a 4px threshold and self-resetting ref hygiene (`mouseDownPosRef.current = null`), ensuring drag gestures never trigger dismissals.
3. `ScriptLineComponent` cue span `onClick` suppresses `onSelectCue` if an active native selection exists, preserving drag selections that cross existing cues.

18. **Cues JSON Editor & LLM Sync Schema Invariants (`RawCuesModal.tsx`, `cues.schema.json`, `cues.prompt.ts`)**:
18. **Cues JSON Editor & LLM Sync Schema Invariants (`RawCuesModal.tsx`, `cues.schema.json`, `cues.prompt.ts`, `vite.config.ts`)**:
- **Single Source of Truth (SSOT) via Vite Asset Plugin**:
- `src/schemas/cues.schema.json` and `src/schemas/cues.prompt.ts` are the sole canonical sources; do **not** re-introduce duplicate files in `public/`. `cuesAssetsPlugin` in `vite.config.ts` serves `/schema.json` and `/sync-prompt.txt` in dev middleware and emits them to `dist/` during production builds.
- **Minimal Canonical Schema vs. Prompt Domain Rules**:
- `cues.schema.json` (and `public/schema.json`) must remain strictly a minimal structural data contract defining types, enums (`type: dialogue | action | sound | ...`), and required properties (`startTime`, `endTime`, `selectedText`, `type`).
- Avoid embedding conversational descriptions or instructions in JSON schema field `description` tags; excessive meta-text degrades token sampling quality during LLM constrained decoding (e.g. Gemini JSON Schema mode).
- Business logic—such as verbatim substring copying from `<ScriptText>` and `(minutes * 60) + seconds` timecode math—belongs strictly in `cues.prompt.ts` (`CUES_SYNC_PROMPT` / `public/sync-prompt.txt`).
- `cues.schema.json` must remain strictly a Gemini-compatible structural data contract defining types, enums (`dialogue | action | camera | shot | audio | vfx | transition | environment`), nullable `speaker`, and required properties (`id`, `type`, `speaker`, `selectedText`, `startTime`, `endTime`).
- Avoid embedding conversational descriptions or `$schema` meta-keys that degrade token sampling or compatibility during LLM constrained decoding (e.g. Gemini Structured Output).
- Business logic—such as verbatim substring copying from `<ScriptText>`, `[[STAGING]]` block exclusion, chronological sorting, `endTime > startTime`, speaker extension stripping, `(minutes * 60) + seconds` timecode math, and the 8 category definitions—belongs strictly in `cues.prompt.ts` (`CUES_SYNC_PROMPT`).
- **External Draft Guidance Separation**:
- Draft baseline notices ("This prompt provides a baseline draft. You are encouraged to customize it...") must reside cleanly outside the markdown prompt text in the UI to keep copied prompts pure and ready for system instructions.
- **Segmented Sub-View Architecture (`prompt` | `schema` | `split`)**:
- Provide a top-level segmented sub-view switcher within the Prompt & Schema tab. Full-width views (`prompt` or `schema`) allow single-column reading with zero horizontal scrollbar clipping on schema lines; `split` remains available for side-by-side inspection on wide screens.
- Provide a top-level segmented sub-view switcher within the Prompt & Schema tab. Full-width views (`prompt` or `schema`) allow single-column reading with zero horizontal scrollbar clipping on schema lines; `split` remains available for side-by-side inspection on wide screens. Keep a single Copy button inside each panel header without duplicate toolbar copy buttons or redundant tab-switch links.
- **Modal Footer Action Stability & Text Wrap Prevention**:
- Modal footer actions must use `whitespace-nowrap`, matching vertical padding (`py-2`), and Title Case typography (e.g., `Go to JSON Data →`) to guarantee buttons never wrap across multiple lines or distort footer height.
- Footer buttons are context-aware: displaying `Cancel` & `Apply Cues (N)` on the `JSON Data` tab, and `Close` & `Go to JSON Data →` on the `Sync Prompt & Schema` tab.
Expand Down
6 changes: 3 additions & 3 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ The UI layer coordinates video playback, real-time highlighting, user interactio
- **Left Column (Schema Reference & Guide)**: Displays compact visual cue schema reference (Essential Fields `startTime`, `endTime`, `selectedText`, `type`; collapsible Optional & Auto-Calc Fields; and quick example payload with copy and insert actions).
- **Right Column (Dual-Tab Workstation)**:
- **`JSON Data` Tab**: Full-height textarea with line counter, live schema validation pill (`{ cues } detected`, `N cues ready`, error diagnostics without blocking `alert()`), and `[ ✨ Format JSON ]` 2-space indentation standardizer with automatic `{ cues: [...] }` unwrapping.
- **`Sync Prompt & Schema` Tab**: Dedicated AI/Gemini synchronization workspace featuring a compact 3-step setup guide with public file links (`/sync-prompt.txt`, `/schema.json`), inline draft baseline guidance, segmented full-width code viewports (`[ 📄 Sync Prompt ]`, `[ 🤖 Gemini Schema ]`, and `[ ◫ Split ]`), and synchronized 1-click copy actions.
- **`Sync Prompt & Schema` Tab**: Dedicated AI/Gemini synchronization workspace featuring a compact 3-step setup guide with SSOT asset links (`/sync-prompt.txt`, `/schema.json` served by `cuesAssetsPlugin`), inline draft baseline guidance, segmented full-width code viewports (`[ 📄 Sync Prompt ]`, `[ 🤖 Gemini Schema ]`, and `[ ◫ Split ]`), and a single Copy action inside each panel header.
- **Context-Aware Footer**: Adapts footer actions per tab (`Cancel` & `Apply Cues (N)` on JSON Data; `Close` & `Go to JSON Data →` on Sync Prompt & Schema), styled with `whitespace-nowrap` and Title Case typography.
8. **`OverlapPicker.tsx`**: Floating context popup for selecting which overlapping cue to edit at a shared position.
9. **`DeleteConfirmationModal.tsx`**: Confirmation dialog with cue text preview prior to permanent deletion styled via `UI_TOKENS`.
Expand Down Expand Up @@ -353,8 +353,8 @@ The UI layer coordinates video playback, real-time highlighting, user interactio

### Type Definitions & Data Schemas
- **`src/types/script.ts`**: Defines 14 domain interfaces and types: `Cue`, `TimingSettings`, `ColorCategory`, `AppState`, `ScriptWidthPresetId`, `ScriptWidthPreset`, `ScrollFocusPresetId`, `ScrollFocusPreset`, `TextSelection`, `DeleteConfirmationState`, `ResetConfirmationState`, `OverlapPickerState`, `AlternativeLocation`, and `AppMode`.
- **`src/schemas/cues.schema.json` & `public/schema.json`**: Modular JSON schema contract defining the canonical cue data structure for LLM structured output decoding (array of objects with `id`, `type`, `speaker`, `selectedText`, `startTime`, `endTime`).
- **`src/schemas/cues.prompt.ts` & `public/sync-prompt.txt`**: Canonical video-to-script synchronization prompt (`CUES_SYNC_PROMPT`) enforcing strict verbatim `<ScriptText>` substring copying and `(minutes * 60) + seconds` timecode math.
- **`src/schemas/cues.schema.json`**: Single Source of Truth (SSOT) JSON schema contract defining the canonical cue data structure for Gemini structured output decoding (array of objects with `id`, `type`, nullable `speaker`, `selectedText`, `startTime`, `endTime`), served/emitted at `/schema.json` by `cuesAssetsPlugin` in `vite.config.ts`.
- **`src/schemas/cues.prompt.ts`**: Single Source of Truth (SSOT) video-to-script synchronization prompt (`CUES_SYNC_PROMPT`) enforcing strict verbatim `<ScriptText>` substring copying, `[[STAGING]]` block exclusion, chronological sorting, `endTime > startTime`, `(minutes * 60) + seconds` timecode math, speaker extension stripping, and 8 cue type definitions, served/emitted at `/sync-prompt.txt` by `cuesAssetsPlugin` in `vite.config.ts`.
- **`src/examples.ts`**: Defines the `Example` and `ExampleSection` schemas and holds the built-in catalogue metadata.

### Reference Documentation & Conceptual Specifications (`docs/articles/`)
Expand Down
Loading
Loading