@lalalic/markcut 2.2.9 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lalalic/markcut",
3
- "version": "2.2.9",
3
+ "version": "2.3.0",
4
4
  "description": "Markdown-to-video engine. Describe scenes in markdown, get a rendered video.",
5
5
  "bin": {
6
6
  "markcut": "bin/markcut"
@@ -23,11 +23,6 @@ see [docs/markdown-descriptive.md](docs/markdown-descriptive.md) for full detail
23
23
  ### Video Variants
24
24
  - define variants for different video configurations, such as different languages, aspects, platforms
25
25
 
26
-
27
- ### Templates
28
- - Templates in ``docs/templates/`` provide ready-to-use video structures for `orchestrator` agents, use them as starting point to create your own videos.
29
-
30
-
31
26
  ### Viral Story requires
32
27
  - **Hooks** : why should the viewer watch this?
33
28
  - **Conflict** : what challenges or obstacles do the characters face?
@@ -36,11 +31,22 @@ see [docs/markdown-descriptive.md](docs/markdown-descriptive.md) for full detail
36
31
  - **Call to action** : what should the viewer do next?
37
32
  - **Open ending** : does the story leave room for interpretation or continuation?
38
33
 
34
+ ### TTS, TTI, TTV, STT media generation
35
+ markcut implements a **media generation pipeline** to generate TTS, TTI, TTV, STT media automatically.
36
+ - `npx @lalalic/markcut --show-clis` to see the default CLIs for TTS, TTI, TTV, STT media generation.
37
+ - `orchestrator` agent DONT generate media directly
38
+
39
39
  ## 3. CLI
40
40
 
41
41
  ```bash
42
42
  npx @lalalic/markcut <command> [options]
43
43
  npx @lalalic/markcut --help # get overall information
44
+ npx @lalalic/markcut --show-clis # get command specific information
45
+ npx @lalalic/markcut preview <file> # assemble and preview the video with a local server, and chat to edit the video and auto refresh
46
+ npx @lalalic/markcut render <file> # render the video to mp4
47
+ npx @lalalic/markcut vision <folder> # vision understanding medias in folder
48
+ npx @lalalic/markcut vision <folder> --label # full pipeline vision understanding medias in folder, and provide ui to label the medias with text, time ranges
49
+
44
50
  ```
45
51
 
46
52
  ---
@@ -60,8 +66,6 @@ some common issues (photo or video can't be displayed, audio missing), take belo
60
66
  | Topic | File |
61
67
  |-------|------|
62
68
  | Markdown descriptive format (primary authoring format) | [docs/markdown-descriptive.md](docs/markdown-descriptive.md) |
63
- | Label system (browse, label, export labels.json) | [docs/label-mode.md](docs/label-mode.md) |
64
- | Player servers (label + edit mode) | [docs/edit-mode.md](docs/edit-mode.md) |
65
69
 
66
70
 
67
71
  ## common used components
@@ -1,220 +0,0 @@
1
- # Watch Mode
2
-
3
- > `preview <file.md> --edit` — live editing loop with AI-assisted JSON editing.
4
-
5
- Edit mode gives you a browser player that **automatically reloads** when the source file changes, plus an **edit input** that calls an AI coding agent (pi) to make changes on your behalf.
6
-
7
- Generated artifacts (TTS audio, compiled includes, component bundles) are
8
- stored under `.markcut/` next to the source file — see [SKILL.md](../SKILL.md) for the full layout.
9
-
10
- ## Quickstart
11
-
12
- ```bash
13
- cd remotion-engine
14
- npm run preview -- sample-visual.json --edit
15
- # → Browser opens, terminal blocks until you close it
16
- ```
17
-
18
- ## Architecture
19
-
20
- ```
21
- ┌─────────────┐ HTTP ┌──────────────────┐ spawn ┌──────────┐
22
- │ Browser │◄──────────────►│ player/server │◄────────────►│ pi CLI │
23
- │ (Chrome) │ SSE │ .mjs (Node) │ one-shot │ (agent) │
24
- └──────┬──────┘ └────────┬─────────┘ └──────────┘
25
- │ │
26
- │ POST /api/edit │ fs.watchFile
27
- │ {text: "make text bigger"} │ (poll every 500ms)
28
- │ │
29
- │ GET /api/video-data ▼
30
- │ ← stream tree JSON ┌──────────────┐
31
- │ │ stream tree │
32
- │ EventSource │ .json (file) │
33
- │ /api/events └──────────────┘
34
- │ ← {type:"reload"} ▲
35
- │ │
36
- │ window.dispatchEvent │ pi edits
37
- │ ("refresh-player") │ this file
38
- │ │
39
- ```
40
-
41
- ## File: `src/player/server.mjs`
42
-
43
- ### Server startup (`cli.mjs` → `server.mjs`)
44
-
45
- ```
46
- node src/render/cli.mjs preview file.json --edit --port 3031
47
- ```
48
-
49
- 1. `cli.mjs` spawns `server.mjs` with `--edit` flag
50
- 2. `server.mjs` parses `file.json` to build a recursive tree description
51
- 3. Starts `fs.watchFile(file.json, {interval:500})` — polls every 500ms for changes
52
- 4. Starts HTTP server on specified port
53
- 5. Auto-opens browser via `open http://localhost:PORT`
54
-
55
- ### Page served
56
-
57
- The HTML page loads two scripts:
58
-
59
- | Script | Source | Role |
60
- |--------|--------|------|
61
- | `player.js` | Bundled esbuild output from `src/player/browser.tsx` | Renders the stream tree using `@remotion/player` with `MarkCut` |
62
- | Inline script | Generated by `getHtml()` in `server.mjs` | Watch-mode UI controls (close button, edit input, SSE) |
63
-
64
- ### Edit flow
65
-
66
- ```
67
- Browser Server pi CLI
68
- │ │ │
69
- │── POST /api/edit ────────────► │ │
70
- │ {text: "make text bigger"} │ │
71
- │ │── spawn("pi", ["-p", prompt])│
72
- │ │ prompt includes: │
73
- │ │ • full tree description │
74
- │ │ (recursive, any depth) │
75
- │ │ • edit history │
76
- │ │ • knowledge (all stream │
77
- │ │ types, components, │
78
- │ │ schema, styling guide) │
79
- │ │ • edit request │
80
- │ │ │
81
- │ │ pi can edit ANY field on │
82
- │ │ ANY node in the tree │
83
- │ │ ├── edits file.json
84
- │ │ └── exits
85
- │ │◄── exit code 0 │
86
- │◄── {done:true, output:"..."} ──┤ │
87
- │ │ │
88
- │ suppressReload = true │ │
89
- │ header shows "Changed text..." │ │
90
- │ │ │
91
- │ (fs.watchFile fires SSE │ │
92
- │ but suppressReload=true │ │
93
- │ so it's ignored) │ │
94
- │ │ │
95
- │ after 4s: │ │
96
- │ dispatchEvent("refresh-player")│ │
97
- │ → player re-fetches /api/data │ │
98
- │ → re-renders with new JSON │ │
99
- ```
100
-
101
- ### Key design decisions
102
-
103
- **Why in-place refresh instead of `location.reload()`?**
104
- - Timeline playback continues uninterrupted
105
- - Status text persists until next edit
106
- - No page flash
107
-
108
- **Why `suppressReload`?**
109
- - SSE fires ~500ms after pi edits the file
110
- - API response arrives at the same time
111
- - `suppressReload` flag ignores the SSE event during edit
112
- - The client reloads itself after showing the summary
113
-
114
- ## File: `src/player/browser.tsx`
115
-
116
- The bundled player app:
117
-
118
- 1. Fetches `/api/video-data` on mount
119
- 2. Renders the stream tree using `@remotion/player` with `MarkCut`
120
- 3. Listens for `"refresh-player"` custom DOM event
121
- 4. On refresh event: re-fetches data, re-renders in-place
122
-
123
- ## File: `src/render/cli.mjs`
124
-
125
- The CLI routes `--edit` flag to the player server:
126
-
127
- ```javascript
128
- if (args.edit) {
129
- const serverArgs = ["src/player/server.mjs", file, "--edit", `--port=${port}`];
130
- const child = spawn("node", serverArgs, { cwd: ROOT, stdio: "inherit" });
131
- // ...blocks until server exits...
132
- }
133
- ```
134
-
135
- ## API Endpoints
136
-
137
- | Endpoint | Method | Description |
138
- |----------|--------|-------------|
139
- | `/api/video-data` | GET | Returns the raw stream tree JSON file |
140
- | `/api/scenes` | GET | Returns parsed scenes array with timing |
141
- | `/api/video-info` | GET | Returns scenes + totalDuration + mode flags |
142
- | `/api/edit` | POST | Accepts `{text}` → spawns pi to edit the JSON → file watcher triggers → SSE reload |
143
- | `/api/shutdown` | POST | Kills the server process, unblocking the agent |
144
- | `/api/events` | GET | SSE stream — sends `{type:"reload"}` when file changes |
145
- | `/api/labels` | GET/POST | (label mode only) Save/load scene labels |
146
-
147
- ## The pi prompt
148
-
149
- Each edit call sends a structured prompt with a **recursive tree description** instead of a flat scene list:
150
-
151
- ```
152
- You are editing sample-visual.json, a Remotion stream tree JSON.
153
-
154
- The stream tree (indentation shows nesting; timing in seconds):
155
- root "root" (1080×1920, 30fps, series, transition:fade)
156
- folder "scene-1" (parallel)
157
- component GradientBackground {type:"radial",animated:true,noise:true} [05s, bg]
158
- component AnimatedHeadline {"text":"Hello Remotion",...} [0.54.5s]
159
- folder "scene-2" (parallel)
160
- component GradientBackground {type:"linear",animated:true} [05s, bg]
161
- subtitle "This text is styled with CSS" fontSize:52 [0.54.5s]
162
- ...
163
-
164
- Previous edits:
165
- 1. make scene 1 headline text orange
166
-
167
- Edit request: make scene 1 headline text bigger
168
-
169
- --- Knowledge ---
170
- You can edit ANY field on ANY node in the JSON...
171
- Stream types: root, folder, video, audio, image, subtitle, component, effect, rhythm, map
172
- ...
173
- IMPORTANT: Read the full existing JSON file before editing. Only edit the JSON file. You can change, add, or remove any field on any node. Output ONLY a one-line summary of what specific change you made.
174
- ```
175
-
176
- The tree description walks the JSON recursively, showing:
177
- - **Nesting depth** via indentation
178
- - **Type** and **id/name** of each node
179
- - **Key fields** (dimensions, fps, theme, series/parallel, transitions)
180
- - **Timing** from leaf span (`[start→end]`)
181
- - **isBackground** flag (`[bg]`)
182
- - **Component props** and node-specific fields (fontSize, fit, style, volume, etc.)
183
-
184
- This means pi can edit **any aspect of the JSON** ÔÇö not just scene props. Nested folders, effects, rhythms, maps, actions, styles, themes, global stylesheets, audio config ÔÇö everything is visible and editable.
185
-
186
- ## Session context
187
-
188
- The server maintains `editHistory[]` — every edit is appended. On each call, previous edits are included so pi knows what was done before:
189
-
190
- ```
191
- Previous edits:
192
- 1. make scene 1 headline text orange
193
- 2. change background from radial to linear gradient
194
- 3. add 3D angle to device mockup in scene 4
195
- ```
196
-
197
- This gives pi enough context to make coherent changes across multiple edit rounds.
198
-
199
- ## Close / tab-close
200
-
201
- | Action | What happens |
202
- |--------|-------------|
203
- | Click **✕** | `sendBeacon("/api/shutdown")` → server exits → agent unblocks |
204
- | Close **tab** | SSE connection drops → 3s grace → server exits |
205
- | Close **browser** | Same as tab close |
206
-
207
- ## Label mode (`--label`)
208
-
209
- `preview <file.json> --label` starts the same player but with a **label input** instead of the edit input. Labels are saved to `labels.json` next to the source file. No AI editing, no file watching.
210
-
211
- ## Build
212
-
213
- The browser bundle is built with esbuild:
214
-
215
- ```bash
216
- bash scripts/build-player.sh
217
- # → src/player/bundle/player.js
218
- ```
219
-
220
- The bundle includes React, @remotion/player, MarkCut, all 13 built-in components, themes, templates, and the duration utility. It is served as a static file by the player server.
@@ -1,112 +0,0 @@
1
- # Label System
2
-
3
- Interactive media labeling before understanding clips in json stream tree.
4
- The stream tree follow rules, see [docs/json-descriptive.md](docs/json-descriptive.md) for full details .
5
-
6
- ## Overview
7
-
8
- The label player lets you load a stream tree, browse its clips, and attach descriptive labels to each clip's media.
9
- The output is an updated `labels.json` file with `description` fields populated.
10
-
11
- ## Usage
12
-
13
- ```bash
14
- # Label from a stream tree JSON or labels.json
15
- npx markcut preview labels.json --label
16
-
17
- # Specify port
18
- npx markcut preview labels.json --label --port 3031
19
- ```
20
-
21
- ### Labels Persistence
22
- The stream tree follow rules, see [docs/json-descriptive.md](docs/json-descriptive.md) for full details .
23
- Labels are saved to the source file.
24
-
25
- ```json
26
- {
27
- "root": {
28
- "id": "root",
29
- "type": "root",
30
- "children": [
31
- {
32
- "id": "scene-1",
33
- "type": "folder",
34
- "children": [
35
- {
36
- "id": "scene-1-media",
37
- "type": "image",
38
- "src": "/media/photo.jpg",
39
- "start": 0, "end": 5,
40
- "description": "Best group shot from the campfire"
41
- }
42
- ]
43
- },
44
- {
45
- "id": "scene-2",
46
- "type": "folder",
47
- "children": [
48
- {
49
- "id": "scene-2-media",
50
- "type": "video",
51
- "src": "/media/clip.mp4",
52
- "start": 0, "end": 5,
53
- "description": "Sunset timelapse — use for intro"
54
- }
55
- ]
56
- }
57
- ]
58
- }
59
- }
60
- ```
61
-
62
- The `description` field on each media leaf node holds the label text.
63
-
64
- ## Workflow
65
-
66
- ```
67
- Stream tree JSON (labels.json)
68
-
69
-
70
- ─── preview --label ───→ Browse & label clips
71
- │ │
72
- │ ▼
73
- │ Updated labels.json
74
- │ │
75
- ▼ ▼
76
- Use in Storyboard ──────→ Assemble → Render
77
- ```
78
-
79
- 1. **Prepare** a stream tree JSON with scenes
80
- 2. **Label** with `preview --label` to add descriptions to each scene
81
- 3. **Export** labels are saved alongside the source file
82
- 4. **Use** the labeled scenes in your storyboard or assembly workflow
83
-
84
- ## API Endpoints
85
-
86
- | Endpoint | Method | Description |
87
- |----------|--------|-------------|
88
- | `/api/video-data` | GET | Returns the raw stream tree JSON |
89
- | `/api/video-info` | GET | Returns scenes array with timing + totalDuration |
90
- | `/api/labels` | GET | Returns the current stream tree with descriptions |
91
- | `/api/labels` | POST | Saves updated descriptions ({descriptions: {index: "text"}}) |
92
- | `/api/shutdown` | POST | Kills the server |
93
- | `/api/events` | GET | SSE events (reload on file change) |
94
-
95
- ## Implementation
96
-
97
- Source: `src/player/server.mjs` (unified server, use `--label` flag)
98
- UI controls: `src/player/components/LabelControls.tsx` (React component)
99
-
100
- - Built on Node.js `http` module (no Express dependency)
101
- - Serves bundled `player.js` (esbuild output from `src/player/browser.tsx`)
102
- - Labels saved atomically to disk on each POST
103
- - Supports stream tree JSON, descriptive JSON, and markdown input
104
- - React components in `src/player/components/` replace the old HTML-based `ui/` directory
105
-
106
- ## Reference
107
-
108
- | Topic | Link |
109
- |-------|------|
110
- | Storyboard (video planning) | [storyboard.md](storyboard.md) |
111
- | Stream tree types | `SKILL.md` |
112
- | Dynamic components | [dynamic-components.md](dynamic-components.md) |