@program-video/cli 0.1.11 → 0.2.1
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/AGENTS.md +206 -86
- package/dist/binary-manager-HSC2WG4R.js +17 -0
- package/dist/binary-manager-HSC2WG4R.js.map +1 -0
- package/dist/captions-V3I4YG3Q.js +14 -0
- package/dist/captions-V3I4YG3Q.js.map +1 -0
- package/dist/chunk-2H7UOFLK.js +11 -0
- package/dist/chunk-2H7UOFLK.js.map +1 -0
- package/dist/chunk-2PMNEXGG.js +414 -0
- package/dist/chunk-2PMNEXGG.js.map +1 -0
- package/dist/chunk-C3UUQWKV.js +15917 -0
- package/dist/chunk-C3UUQWKV.js.map +1 -0
- package/dist/chunk-WMJSGRMP.js +348 -0
- package/dist/chunk-WMJSGRMP.js.map +1 -0
- package/dist/chunk-Z5WNLASJ.js +322 -0
- package/dist/chunk-Z5WNLASJ.js.map +1 -0
- package/dist/index.js +6947 -2136
- package/dist/index.js.map +1 -1
- package/dist/src-JFTCRPDH.js +157 -0
- package/dist/src-JFTCRPDH.js.map +1 -0
- package/dist/trim-silence-ELVHI2IN.js +238 -0
- package/dist/trim-silence-ELVHI2IN.js.map +1 -0
- package/package.json +15 -5
package/AGENTS.md
CHANGED
|
@@ -1,132 +1,252 @@
|
|
|
1
|
-
# Program CLI - AI Agent
|
|
1
|
+
# Program CLI - AI Agent Guide
|
|
2
2
|
|
|
3
|
-
> CLI for Program.
|
|
3
|
+
> Local-only CLI for the Program desktop app. All operations go through the local Convex backend at `http://127.0.0.1:3210`. No cloud, no auth, no cost.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
# 1. Authenticate (opens browser, user enters code)
|
|
9
|
-
npx @program-video/cli auth login
|
|
10
|
-
|
|
11
|
-
# 2. Create a project
|
|
12
|
-
npx @program-video/cli project create --title "My Video" --json
|
|
7
|
+
The Program desktop app must be running. The CLI talks to its local backend.
|
|
13
8
|
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
```bash
|
|
10
|
+
# Verify the backend is reachable
|
|
11
|
+
program template list --json
|
|
16
12
|
```
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
If you get "Local backend not available", the desktop app isn't running.
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
## Tool Execution
|
|
17
|
+
|
|
18
|
+
All composition and generation operations use the `tool exec` pattern:
|
|
21
19
|
|
|
22
20
|
```bash
|
|
23
|
-
|
|
21
|
+
program tool exec <toolName> --project <compositionId> --params '<json>' --json
|
|
24
22
|
```
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
### List available tools
|
|
27
25
|
|
|
28
26
|
```bash
|
|
29
|
-
|
|
27
|
+
program tool list --json
|
|
30
28
|
```
|
|
31
29
|
|
|
32
|
-
|
|
33
|
-
- The URL to visit (e.g., `https://program.video/device`)
|
|
34
|
-
- The code to enter (e.g., `ABCD-1234`)
|
|
30
|
+
## Node Graph Editing
|
|
35
31
|
|
|
36
|
-
|
|
32
|
+
Video and image scenes can carry a first-class node graph in `scene.metadata.nodeGraph`.
|
|
33
|
+
Use the dedicated `program node ...` commands for graph work instead of hand-editing the raw JSON.
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
```bash
|
|
36
|
+
# Inspect a composition, then inspect the scene graph
|
|
37
|
+
program tool exec assessComposition --project <id> --json
|
|
38
|
+
program node list --project <id> --scene <sceneId> --json
|
|
39
|
+
|
|
40
|
+
# Add nodes
|
|
41
|
+
program node add prompt --project <id> --scene <sceneId> --config '{"prompt":"Describe the shot"}' --json
|
|
42
|
+
program node add reference-image --project <id> --scene <sceneId> --config '{"imageUrl":"localasset://localhost/..."}' --json
|
|
43
|
+
program node add reference-video --project <id> --scene <sceneId> --config '{"videoUrl":"localasset://localhost/..."}' --json
|
|
44
|
+
program node add model-select --project <id> --scene <sceneId> --config '{"model":"alibaba/wan-v2.6-t2v","provider":"ai-gateway"}' --json
|
|
45
|
+
program node add generate-video --project <id> --scene <sceneId> --json
|
|
46
|
+
program node add generate-image --project <id> --scene <sceneId> --json
|
|
47
|
+
program node add number-value --project <id> --scene <sceneId> --config '{"value":5}' --json
|
|
48
|
+
|
|
49
|
+
# Update node config
|
|
50
|
+
program node config <nodeId> --project <id> --scene <sceneId> --set '{"prompt":"Updated prompt"}' --json
|
|
51
|
+
|
|
52
|
+
# Connect nodes by handle
|
|
53
|
+
program node connect <promptNodeId> <referenceImageNodeId> --project <id> --scene <sceneId> --source-handle prompt --target-handle prompt --json
|
|
54
|
+
program node connect <promptNodeId> <generateNodeId> --project <id> --scene <sceneId> --source-handle prompt --target-handle prompt --json
|
|
55
|
+
program node connect <referenceImageNodeId> <generateNodeId> --project <id> --scene <sceneId> --source-handle imageUrl --target-handle imageUrl --json
|
|
56
|
+
program node connect <referenceVideoNodeId> <sceneOutputNodeId> --project <id> --scene <sceneId> --source-handle videoUrl --target-handle media --json
|
|
57
|
+
program node connect <generateVideoNodeId> <sceneOutputNodeId> --project <id> --scene <sceneId> --source-handle videoUrl --target-handle media --json
|
|
58
|
+
program node connect <generateVideoNodeId> <sceneOutputNodeId> --project <id> --scene <sceneId> --source-handle duration --target-handle duration --json
|
|
59
|
+
|
|
60
|
+
# Clean up / arrange / run
|
|
61
|
+
program node disconnect <sourceNodeId> <targetNodeId> --project <id> --scene <sceneId> --json
|
|
62
|
+
program node remove <nodeId> --project <id> --scene <sceneId> --json
|
|
63
|
+
program node autolayout --project <id> --scene <sceneId> --json
|
|
64
|
+
program node execute --project <id> --scene <sceneId> --json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Important graph conventions:
|
|
68
|
+
- `scene-output` uses `media` as the canonical asset input for both image and video sources.
|
|
69
|
+
- Prompt nodes, reference-image nodes, reference-video nodes, model-select nodes, and number-value nodes are legitimate graph primitives and should not be treated as legacy.
|
|
70
|
+
- Prefer the node commands when the user wants to scaffold or edit generation pipelines for a scene.
|
|
39
71
|
|
|
40
|
-
##
|
|
72
|
+
## Available Tools
|
|
41
73
|
|
|
42
|
-
###
|
|
74
|
+
### Composition Tools
|
|
43
75
|
|
|
44
76
|
```bash
|
|
45
|
-
#
|
|
46
|
-
|
|
77
|
+
# Read full composition data
|
|
78
|
+
program tool exec readComposition --project <id> --json
|
|
79
|
+
|
|
80
|
+
# Get lightweight overview with scene summaries
|
|
81
|
+
program tool exec assessComposition --project <id> --json
|
|
82
|
+
|
|
83
|
+
# Add a code scene
|
|
84
|
+
program tool exec addScene --project <id> --params '{
|
|
85
|
+
"title": "Intro",
|
|
86
|
+
"duration": 5,
|
|
87
|
+
"code": "export default () => <h1>Hello</h1>"
|
|
88
|
+
}' --json
|
|
89
|
+
|
|
90
|
+
# Add a video scene
|
|
91
|
+
program tool exec addScene --project <id> --params '{
|
|
92
|
+
"type": "video_scene",
|
|
93
|
+
"title": "B-Roll",
|
|
94
|
+
"url": "https://example.com/video.mp4",
|
|
95
|
+
"duration": 5,
|
|
96
|
+
"start": 0,
|
|
97
|
+
"layer": 1
|
|
98
|
+
}' --json
|
|
99
|
+
|
|
100
|
+
# Add an audio scene
|
|
101
|
+
program tool exec addScene --project <id> --params '{
|
|
102
|
+
"type": "audio_scene",
|
|
103
|
+
"title": "Narration",
|
|
104
|
+
"url": "/audio-cache/scene-trimmed.wav",
|
|
105
|
+
"duration": 10
|
|
106
|
+
}' --json
|
|
107
|
+
|
|
108
|
+
# Update scene code
|
|
109
|
+
program tool exec updateScene --project <id> --params '{
|
|
110
|
+
"sceneId": "<scene-id>",
|
|
111
|
+
"code": "export default () => <h1>Updated</h1>"
|
|
112
|
+
}' --json
|
|
113
|
+
|
|
114
|
+
# Delete a scene
|
|
115
|
+
program tool exec deleteScene --project <id> --params '{"sceneId": "<scene-id>"}' --json
|
|
116
|
+
|
|
117
|
+
# Delete all scenes
|
|
118
|
+
program tool exec deleteAllScenes --project <id> --json
|
|
119
|
+
|
|
120
|
+
# Update composition metadata
|
|
121
|
+
program tool exec setMetadata --project <id> --params '{
|
|
122
|
+
"title": "My Video",
|
|
123
|
+
"duration": 30,
|
|
124
|
+
"fps": 30,
|
|
125
|
+
"width": 1080,
|
|
126
|
+
"height": 1920
|
|
127
|
+
}' --json
|
|
128
|
+
```
|
|
47
129
|
|
|
48
|
-
|
|
49
|
-
npx @program-video/cli project list --json
|
|
130
|
+
### Generation Tools
|
|
50
131
|
|
|
51
|
-
|
|
52
|
-
|
|
132
|
+
```bash
|
|
133
|
+
# Generate speech (TTS via Replicate chatterbox-turbo)
|
|
134
|
+
program tool exec generateSpeech --project <id> --params '{
|
|
135
|
+
"text": "Welcome to the show",
|
|
136
|
+
"voice": "Ethan"
|
|
137
|
+
}' --json
|
|
138
|
+
|
|
139
|
+
# Generate speech and attach to existing audio scene
|
|
140
|
+
program tool exec generateSpeech --project <id> --params '{
|
|
141
|
+
"text": "Scene narration",
|
|
142
|
+
"voice": "Ethan",
|
|
143
|
+
"sceneId": "<existing-audio-scene-id>"
|
|
144
|
+
}' --json
|
|
145
|
+
|
|
146
|
+
# Transcribe audio (local whisper, word-level timestamps)
|
|
147
|
+
program tool exec transcribeAudio --params '{
|
|
148
|
+
"filePath": "/tmp/program-video-cache/audio/scene-trimmed.wav",
|
|
149
|
+
"model": "base"
|
|
150
|
+
}' --json
|
|
53
151
|
```
|
|
54
152
|
|
|
55
|
-
### Tools
|
|
153
|
+
### Utility Tools
|
|
56
154
|
|
|
57
155
|
```bash
|
|
58
|
-
# List
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
156
|
+
# List all compositions
|
|
157
|
+
program tool exec listCompositions --json
|
|
158
|
+
program tool exec listCompositions --params '{"limit": 10}' --json
|
|
159
|
+
|
|
160
|
+
# Trim silence from composition audio scenes
|
|
161
|
+
program tool exec trimSilence --project <id> --json
|
|
162
|
+
program tool exec trimSilence --project <id> --params '{
|
|
163
|
+
"sceneId": "<audio-scene-id>",
|
|
164
|
+
"silenceDuration": "0.25",
|
|
165
|
+
"threshold": "-30dB"
|
|
166
|
+
}' --json
|
|
167
|
+
|
|
168
|
+
# Build caption overlay from transcripts
|
|
169
|
+
program tool exec buildCaptions --project <id> --json
|
|
170
|
+
program tool exec buildCaptions --project <id> --params '{
|
|
171
|
+
"accentWords": "important,highlight",
|
|
172
|
+
"style": "tiktok"
|
|
173
|
+
}' --json
|
|
174
|
+
|
|
175
|
+
# Generate subtitles end to end (local transcription + captions scene)
|
|
176
|
+
program tool exec generateSubtitles --project <id> --json
|
|
177
|
+
program tool exec generateSubtitles --project <id> --params '{
|
|
178
|
+
"sceneId": "<audio-or-video-scene-id>",
|
|
179
|
+
"style": "tiktok",
|
|
180
|
+
"accentWords": "ai,program"
|
|
181
|
+
}' --json
|
|
182
|
+
|
|
183
|
+
# List available models
|
|
184
|
+
program tool exec listSpeechModels --json
|
|
185
|
+
program tool exec listVideoModels --json
|
|
186
|
+
program tool exec listImageModels --json
|
|
63
187
|
```
|
|
64
188
|
|
|
65
|
-
|
|
66
|
-
- `addScene` - Add a scene with React/Remotion code
|
|
67
|
-
- `updateScene` - Modify an existing scene
|
|
68
|
-
- `deleteScene` - Remove a scene
|
|
69
|
-
- `generateSpeech` - Generate text-to-speech audio
|
|
70
|
-
- `readComposition` - Get current composition state
|
|
189
|
+
## Templates
|
|
71
190
|
|
|
72
|
-
|
|
191
|
+
Templates are reusable workflow definitions with ordered steps.
|
|
73
192
|
|
|
74
193
|
```bash
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
194
|
+
program template list --json
|
|
195
|
+
program template use <id>
|
|
196
|
+
program template get <id> --json
|
|
197
|
+
program template create --name "My Workflow" --steps '[]' --json
|
|
198
|
+
program template update <id> --name "New Name" --json
|
|
199
|
+
program template run <id> --json
|
|
80
200
|
```
|
|
81
201
|
|
|
82
|
-
|
|
202
|
+
## Research
|
|
83
203
|
|
|
84
204
|
```bash
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# Check workflow status
|
|
92
|
-
npx @program-video/cli workflow status <executionId> --json
|
|
205
|
+
program research add <url> [--note "Why this matters"] --json
|
|
206
|
+
program research list [--platform youtube] [--limit 20] --json
|
|
207
|
+
program research analyze <id-or-url> --json
|
|
208
|
+
program research probe <id-or-url> --json
|
|
209
|
+
program research to-template <id> --json
|
|
93
210
|
```
|
|
94
211
|
|
|
95
|
-
##
|
|
212
|
+
## Audio Production Workflow
|
|
96
213
|
|
|
97
|
-
|
|
214
|
+
The recommended sequence for producing audio in a composition:
|
|
98
215
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
216
|
+
1. **Generate TTS** for each scene's narration
|
|
217
|
+
```bash
|
|
218
|
+
program tool exec generateSpeech --project <id> --params '{
|
|
219
|
+
"text": "Scene narration",
|
|
220
|
+
"voice": "Ethan"
|
|
221
|
+
}' --json
|
|
222
|
+
```
|
|
105
223
|
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
"error": "Error message"
|
|
111
|
-
}
|
|
112
|
-
```
|
|
224
|
+
2. **Trim silence** from audio scenes
|
|
225
|
+
```bash
|
|
226
|
+
program tool exec trimSilence --project <id> --json
|
|
227
|
+
```
|
|
113
228
|
|
|
114
|
-
|
|
229
|
+
3. **Transcribe** each trimmed audio file
|
|
230
|
+
```bash
|
|
231
|
+
program tool exec transcribeAudio --params '{
|
|
232
|
+
"filePath": "/tmp/program-video-cache/audio/<scene-id>-trimmed.wav",
|
|
233
|
+
"output": "/tmp/program-video-cache/audio/<scene-id>-transcript.json"
|
|
234
|
+
}' --json
|
|
235
|
+
```
|
|
115
236
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
5. **Generate speech**: `tool exec generateSpeech --project <id> --params '{"text":"..."}' --json`
|
|
121
|
-
6. **Send status**: `message send "Video complete!" --project <id> --json`
|
|
237
|
+
4. **Build captions** from transcripts
|
|
238
|
+
```bash
|
|
239
|
+
program tool exec buildCaptions --project <id> --json
|
|
240
|
+
```
|
|
122
241
|
|
|
123
242
|
## Important Notes
|
|
124
243
|
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
244
|
+
- **Always use `--json`** for structured, parseable output
|
|
245
|
+
- **`--project` accepts a composition ID** (in local mode, compositions are the projects)
|
|
246
|
+
- **Voice names are case-sensitive** — "Ethan" not "ethan"
|
|
247
|
+
- **Audio files cached at** `/tmp/program-video-cache/audio/`
|
|
248
|
+
- **Replicate URLs expire** within hours — files are downloaded and cached immediately
|
|
249
|
+
- **Local whisper** requires `pip install openai-whisper`
|
|
250
|
+
- **ffmpeg required** for trim-silence and audio duration detection
|
|
251
|
+
- **Trim before transcribe** — silence at the start throws off timestamp alignment
|
|
252
|
+
- **Audio file validation** — if a downloaded file is < 1000 bytes, the Replicate URL likely expired
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
checkSetup,
|
|
4
|
+
getBinPath,
|
|
5
|
+
getWhisperModelPath,
|
|
6
|
+
resolveBinary,
|
|
7
|
+
setupAll
|
|
8
|
+
} from "./chunk-WMJSGRMP.js";
|
|
9
|
+
import "./chunk-2H7UOFLK.js";
|
|
10
|
+
export {
|
|
11
|
+
checkSetup,
|
|
12
|
+
getBinPath,
|
|
13
|
+
getWhisperModelPath,
|
|
14
|
+
resolveBinary,
|
|
15
|
+
setupAll
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=binary-manager-HSC2WG4R.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
buildCaptionEntries,
|
|
4
|
+
captionsCommand,
|
|
5
|
+
generateCaptionCode
|
|
6
|
+
} from "./chunk-Z5WNLASJ.js";
|
|
7
|
+
import "./chunk-2PMNEXGG.js";
|
|
8
|
+
import "./chunk-2H7UOFLK.js";
|
|
9
|
+
export {
|
|
10
|
+
buildCaptionEntries,
|
|
11
|
+
captionsCommand,
|
|
12
|
+
generateCaptionCode
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=captions-V3I4YG3Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
__export
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=chunk-2H7UOFLK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|