@argo-video/cli 0.1.0 → 0.1.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/LICENSE +21 -0
- package/README.md +2 -2
- package/dist/asset-server.d.ts +7 -0
- package/dist/asset-server.d.ts.map +1 -0
- package/dist/asset-server.js +66 -0
- package/dist/asset-server.js.map +1 -0
- package/dist/captions.d.ts +17 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +23 -0
- package/dist/captions.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +87 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +44 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +74 -0
- package/dist/config.js.map +1 -0
- package/dist/export.d.ts +18 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +64 -0
- package/dist/export.js.map +1 -0
- package/dist/fixtures.d.ts +13 -0
- package/dist/fixtures.d.ts.map +1 -0
- package/dist/fixtures.js +36 -0
- package/dist/fixtures.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +2 -0
- package/dist/init.d.ts.map +1 -0
- package/{src/init.ts → dist/init.js} +39 -54
- package/dist/init.js.map +1 -0
- package/dist/narration.d.ts +9 -0
- package/dist/narration.d.ts.map +1 -0
- package/dist/narration.js +27 -0
- package/dist/narration.js.map +1 -0
- package/dist/overlays/index.d.ts +8 -0
- package/dist/overlays/index.d.ts.map +1 -0
- package/dist/overlays/index.js +34 -0
- package/dist/overlays/index.js.map +1 -0
- package/dist/overlays/manifest.d.ts +5 -0
- package/dist/overlays/manifest.d.ts.map +1 -0
- package/dist/overlays/manifest.js +52 -0
- package/dist/overlays/manifest.js.map +1 -0
- package/dist/overlays/motion.d.ts +4 -0
- package/dist/overlays/motion.d.ts.map +1 -0
- package/dist/overlays/motion.js +25 -0
- package/dist/overlays/motion.js.map +1 -0
- package/dist/overlays/templates.d.ts +7 -0
- package/dist/overlays/templates.d.ts.map +1 -0
- package/dist/overlays/templates.js +98 -0
- package/dist/overlays/templates.js.map +1 -0
- package/dist/overlays/types.d.ts +42 -0
- package/dist/overlays/types.d.ts.map +1 -0
- package/dist/overlays/types.js +25 -0
- package/dist/overlays/types.js.map +1 -0
- package/dist/overlays/zones.d.ts +15 -0
- package/dist/overlays/zones.d.ts.map +1 -0
- package/dist/overlays/zones.js +69 -0
- package/dist/overlays/zones.js.map +1 -0
- package/dist/pipeline.d.ts +3 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +93 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/record.d.ts +14 -0
- package/dist/record.d.ts.map +1 -0
- package/dist/record.js +100 -0
- package/dist/record.js.map +1 -0
- package/dist/tts/align.d.ts +17 -0
- package/dist/tts/align.d.ts.map +1 -0
- package/dist/tts/align.js +40 -0
- package/dist/tts/align.js.map +1 -0
- package/dist/tts/cache.d.ts +31 -0
- package/dist/tts/cache.d.ts.map +1 -0
- package/dist/tts/cache.js +51 -0
- package/dist/tts/cache.js.map +1 -0
- package/dist/tts/engine.d.ts +41 -0
- package/dist/tts/engine.d.ts.map +1 -0
- package/dist/tts/engine.js +108 -0
- package/dist/tts/engine.js.map +1 -0
- package/dist/tts/generate.d.ts +20 -0
- package/dist/tts/generate.d.ts.map +1 -0
- package/dist/tts/generate.js +58 -0
- package/dist/tts/generate.js.map +1 -0
- package/dist/tts/kokoro.d.ts +13 -0
- package/dist/tts/kokoro.d.ts.map +1 -0
- package/dist/tts/kokoro.js +46 -0
- package/dist/tts/kokoro.js.map +1 -0
- package/package.json +13 -1
- package/.claude/settings.local.json +0 -34
- package/DESIGN.md +0 -261
- package/docs/enhancement-proposal.md +0 -262
- package/docs/superpowers/plans/2026-03-12-argo.md +0 -208
- package/docs/superpowers/plans/2026-03-12-editorial-overlay-system.md +0 -1560
- package/docs/superpowers/plans/2026-03-13-npm-rename-skill-showcase.md +0 -499
- package/docs/superpowers/specs/2026-03-13-npm-rename-skill-showcase-design.md +0 -109
- package/skills/argo-demo-creator.md +0 -355
- package/src/asset-server.ts +0 -81
- package/src/captions.ts +0 -36
- package/src/cli.ts +0 -97
- package/src/config.ts +0 -125
- package/src/export.ts +0 -93
- package/src/fixtures.ts +0 -50
- package/src/index.ts +0 -41
- package/src/narration.ts +0 -31
- package/src/overlays/index.ts +0 -54
- package/src/overlays/manifest.ts +0 -68
- package/src/overlays/motion.ts +0 -27
- package/src/overlays/templates.ts +0 -121
- package/src/overlays/types.ts +0 -73
- package/src/overlays/zones.ts +0 -82
- package/src/pipeline.ts +0 -120
- package/src/record.ts +0 -123
- package/src/tts/align.ts +0 -75
- package/src/tts/cache.ts +0 -65
- package/src/tts/engine.ts +0 -147
- package/src/tts/generate.ts +0 -83
- package/src/tts/kokoro.ts +0 -51
- package/tests/asset-server.test.ts +0 -67
- package/tests/captions.test.ts +0 -76
- package/tests/cli.test.ts +0 -131
- package/tests/config.test.ts +0 -150
- package/tests/e2e/fake-server.ts +0 -45
- package/tests/e2e/record.e2e.test.ts +0 -131
- package/tests/export.test.ts +0 -155
- package/tests/fixtures.test.ts +0 -74
- package/tests/init.test.ts +0 -77
- package/tests/narration.test.ts +0 -120
- package/tests/overlays/index.test.ts +0 -73
- package/tests/overlays/manifest.test.ts +0 -120
- package/tests/overlays/motion.test.ts +0 -34
- package/tests/overlays/templates.test.ts +0 -69
- package/tests/overlays/types.test.ts +0 -36
- package/tests/overlays/zones.test.ts +0 -49
- package/tests/pipeline.test.ts +0 -177
- package/tests/record.test.ts +0 -87
- package/tests/tts/align.test.ts +0 -118
- package/tests/tts/cache.test.ts +0 -110
- package/tests/tts/engine.test.ts +0 -204
- package/tests/tts/generate.test.ts +0 -177
- package/tests/tts/kokoro.test.ts +0 -25
- package/tsconfig.json +0 -19
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
# Enhancement Proposal: Editorial Overlay System
|
|
2
|
-
|
|
3
|
-
## Summary
|
|
4
|
-
|
|
5
|
-
Argo's current caption system renders a single bottom-centered text pill. That's enough for narration subtitles but not for editorial demo videos where text feels composed into the frame — headline cards with kicker/title/body hierarchy, callout annotations, image-backed panels at different screen positions.
|
|
6
|
-
|
|
7
|
-
This proposal evolves `src/captions.ts` from a single-style caption helper into a zone-based overlay system with pluggable templates.
|
|
8
|
-
|
|
9
|
-
## Goals
|
|
10
|
-
|
|
11
|
-
- Make captions feel designed, not appended.
|
|
12
|
-
- Support editorial overlays: headline cards, callouts, image-backed panels.
|
|
13
|
-
- Keep narration timing and overlay visuals separate so demos stay easy to author.
|
|
14
|
-
- Preserve the simple default path — `showCaption` and `withCaption` continue to work unchanged.
|
|
15
|
-
|
|
16
|
-
## Current System
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
captions.ts
|
|
20
|
-
├── OVERLAY_ID = 'argo-caption-overlay' ← single element, replaced on each call
|
|
21
|
-
├── CAPTION_STYLES = { ... } ← one hardcoded style object
|
|
22
|
-
├── injectOverlay(page, text) ← creates div, sets textContent + styles
|
|
23
|
-
├── showCaption(page, scene, text, dur) ← inject → wait → remove
|
|
24
|
-
├── withCaption(page, scene, text, action) ← inject → action → remove (try/finally)
|
|
25
|
-
└── hideCaption(page) ← remove by ID
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Limitations:
|
|
29
|
-
- One overlay type, one placement, one visual treatment.
|
|
30
|
-
- Single DOM element — showing a new caption removes the previous one globally.
|
|
31
|
-
- No support for images, rich cards, or animation.
|
|
32
|
-
- No way to have two overlays visible simultaneously (e.g., subtitle + headline card).
|
|
33
|
-
|
|
34
|
-
## Design Decisions
|
|
35
|
-
|
|
36
|
-
### Zone-based coexistence
|
|
37
|
-
|
|
38
|
-
Overlays are placed into **zones**. Each zone is a screen region that holds at most one overlay at a time. Showing an overlay in a zone automatically replaces any existing overlay in that zone, but overlays in different zones coexist independently.
|
|
39
|
-
|
|
40
|
-
Zones:
|
|
41
|
-
- `bottom-center` (default — current caption position)
|
|
42
|
-
- `top-left`
|
|
43
|
-
- `top-right`
|
|
44
|
-
- `bottom-left`
|
|
45
|
-
- `bottom-right`
|
|
46
|
-
- `center`
|
|
47
|
-
|
|
48
|
-
DOM IDs become `argo-overlay-{zone}` instead of the current single `argo-caption-overlay`.
|
|
49
|
-
|
|
50
|
-
This gives editorial power (subtitle + headline card visible simultaneously) without requiring manual dismissal of every overlay.
|
|
51
|
-
|
|
52
|
-
### Asset injection via local server
|
|
53
|
-
|
|
54
|
-
Image overlays (`image-card`) reference local files like `assets/diagram.png`. These need to be accessible inside the Playwright browser context.
|
|
55
|
-
|
|
56
|
-
**Approach: local asset server.** A tiny HTTP server (same pattern as the E2E fake server) serves files from the project's asset directory during recording. It starts automatically before `record` and stops after.
|
|
57
|
-
|
|
58
|
-
Why not base64 data URIs: a 2MB screenshot becomes ~2.7MB of serialized DOM, slowing `page.evaluate`. Asset server keeps the DOM clean and scales to many images.
|
|
59
|
-
|
|
60
|
-
### Templates, not a theme system
|
|
61
|
-
|
|
62
|
-
v1 ships with hardcoded visual presets per template — no theme tokens. Each template has one opinionated look that works well on dark and light backgrounds. Theme customization (typography, colors, spacing tokens) is a future enhancement once real usage patterns emerge.
|
|
63
|
-
|
|
64
|
-
### Motion: two presets only
|
|
65
|
-
|
|
66
|
-
CSS animations during Playwright recording are frame-rate dependent. v1 supports two safe presets:
|
|
67
|
-
- `fade-in` — opacity 0→1 over 300ms
|
|
68
|
-
- `slide-in` — translateX + opacity over 400ms
|
|
69
|
-
|
|
70
|
-
Staggered multi-element reveals (kicker, then title, then body) are deferred to v2 — they require careful timing coordination that's hard to get right at variable recording FPS.
|
|
71
|
-
|
|
72
|
-
## Overlay Templates
|
|
73
|
-
|
|
74
|
-
### `lower-third` (default)
|
|
75
|
-
|
|
76
|
-
The current caption style, refined. Bottom-center translucent pill with text.
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
┌─────────────────────────────────────────┐
|
|
80
|
-
│ │
|
|
81
|
-
│ │
|
|
82
|
-
│ │
|
|
83
|
-
│ ┌─────────────────────────────┐ │
|
|
84
|
-
│ │ Caption text here │ │
|
|
85
|
-
│ └─────────────────────────────┘ │
|
|
86
|
-
└─────────────────────────────────────────┘
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Fields: `text`
|
|
90
|
-
|
|
91
|
-
### `headline-card`
|
|
92
|
-
|
|
93
|
-
A card with optional kicker (small caps label), title (large), and body (smaller). Backdrop blur + translucent background.
|
|
94
|
-
|
|
95
|
-
```
|
|
96
|
-
┌─────────────────────────────────────────┐
|
|
97
|
-
│ ┌──────────────────────┐ │
|
|
98
|
-
│ │ KICKER LABEL │ │
|
|
99
|
-
│ │ Title text here │ │
|
|
100
|
-
│ │ Body text here │ │
|
|
101
|
-
│ └──────────────────────┘ │
|
|
102
|
-
│ │
|
|
103
|
-
└─────────────────────────────────────────┘
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Fields: `kicker?`, `title`, `body?`
|
|
107
|
-
|
|
108
|
-
### `callout`
|
|
109
|
-
|
|
110
|
-
A compact annotation bubble for pointing out UI elements. Meant for short text.
|
|
111
|
-
|
|
112
|
-
Fields: `text`
|
|
113
|
-
|
|
114
|
-
### `image-card`
|
|
115
|
-
|
|
116
|
-
An image with optional title and body caption below it. Image loaded from the asset server.
|
|
117
|
-
|
|
118
|
-
```
|
|
119
|
-
┌─────────────────────────────────────────┐
|
|
120
|
-
│ ┌─────────────────┐ │
|
|
121
|
-
│ │ ┌───────────┐ │ │
|
|
122
|
-
│ │ │ image │ │ │
|
|
123
|
-
│ │ └───────────┘ │ │
|
|
124
|
-
│ │ Title │ │
|
|
125
|
-
│ │ Body text │ │
|
|
126
|
-
│ └─────────────────┘ │
|
|
127
|
-
└─────────────────────────────────────────┘
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Fields: `src`, `title?`, `body?`
|
|
131
|
-
|
|
132
|
-
## Authoring Model
|
|
133
|
-
|
|
134
|
-
### Overlay manifest (`demos/example.overlays.json`)
|
|
135
|
-
|
|
136
|
-
A new file, separate from the voiceover manifest. Maps scenes to overlay cues.
|
|
137
|
-
|
|
138
|
-
```json
|
|
139
|
-
[
|
|
140
|
-
{
|
|
141
|
-
"scene": "intro",
|
|
142
|
-
"type": "lower-third",
|
|
143
|
-
"text": "Hacker News — the front page of the internet"
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
"scene": "browse",
|
|
147
|
-
"type": "headline-card",
|
|
148
|
-
"placement": "top-left",
|
|
149
|
-
"kicker": "LOCAL EXECUTION",
|
|
150
|
-
"title": "WebGPU + Transformers.js",
|
|
151
|
-
"body": "Models cache after first load.",
|
|
152
|
-
"motion": "slide-in"
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
"scene": "rerank",
|
|
156
|
-
"type": "image-card",
|
|
157
|
-
"placement": "top-right",
|
|
158
|
-
"src": "assets/rerank-diagram.png",
|
|
159
|
-
"title": "Cross-encoder reranking"
|
|
160
|
-
}
|
|
161
|
-
]
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Rules:
|
|
165
|
-
- `scene` links to `narration.mark()` calls in the demo script.
|
|
166
|
-
- `type` selects the template. Default: `lower-third`.
|
|
167
|
-
- `placement` selects the zone. Default: `bottom-center`.
|
|
168
|
-
- `motion` selects the entrance animation. Default: none (instant appear).
|
|
169
|
-
- Template-specific fields (`kicker`, `title`, `body`, `src`, `text`) vary by type.
|
|
170
|
-
|
|
171
|
-
### Programmatic API
|
|
172
|
-
|
|
173
|
-
The existing `showCaption`/`withCaption` API stays unchanged as sugar for `lower-third` overlays. New overlays are shown via a new function:
|
|
174
|
-
|
|
175
|
-
```ts
|
|
176
|
-
import { showOverlay, hideOverlay, withOverlay } from 'argo';
|
|
177
|
-
|
|
178
|
-
// Show a headline card in the top-left zone
|
|
179
|
-
await showOverlay(page, 'browse', {
|
|
180
|
-
type: 'headline-card',
|
|
181
|
-
placement: 'top-left',
|
|
182
|
-
kicker: 'LOCAL EXECUTION',
|
|
183
|
-
title: 'WebGPU + Transformers.js',
|
|
184
|
-
motion: 'slide-in',
|
|
185
|
-
}, 4000);
|
|
186
|
-
|
|
187
|
-
// Hide a specific zone
|
|
188
|
-
await hideOverlay(page, 'top-left');
|
|
189
|
-
|
|
190
|
-
// Overlay around an action
|
|
191
|
-
await withOverlay(page, 'rerank', {
|
|
192
|
-
type: 'image-card',
|
|
193
|
-
placement: 'top-right',
|
|
194
|
-
src: 'assets/diagram.png',
|
|
195
|
-
title: 'Reranking pipeline',
|
|
196
|
-
}, async () => {
|
|
197
|
-
await page.click('.rerank-button');
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Backward compatibility: `showCaption(page, scene, text, dur)` becomes equivalent to `showOverlay(page, scene, { type: 'lower-third', text }, dur)`.
|
|
202
|
-
|
|
203
|
-
### Auto-overlay from manifest
|
|
204
|
-
|
|
205
|
-
When a `<demo>.overlays.json` file exists alongside the voiceover manifest, the recording fixture automatically injects overlays at their matching `narration.mark()` timestamps. This means users can define overlays purely in JSON without touching the demo script — the programmatic API is for advanced use only.
|
|
206
|
-
|
|
207
|
-
## Implementation Plan
|
|
208
|
-
|
|
209
|
-
### Phase 1: Zone-based overlay renderer
|
|
210
|
-
|
|
211
|
-
1. Refactor `src/captions.ts` → `src/overlays.ts`
|
|
212
|
-
- Replace single `OVERLAY_ID` with `argo-overlay-{zone}` scheme
|
|
213
|
-
- Extract template rendering into a `renderTemplate(type, fields)` → HTML+styles function
|
|
214
|
-
- Implement `lower-third` template (current caption style, now zone-aware)
|
|
215
|
-
- Implement `showOverlay`, `hideOverlay`, `withOverlay`
|
|
216
|
-
- Re-export `showCaption`, `withCaption`, `hideCaption` as thin wrappers
|
|
217
|
-
|
|
218
|
-
2. Add CSS animation injection for `fade-in` and `slide-in` presets
|
|
219
|
-
|
|
220
|
-
3. Update `src/index.ts` exports
|
|
221
|
-
|
|
222
|
-
### Phase 2: Editorial templates
|
|
223
|
-
|
|
224
|
-
4. Implement `headline-card` template (kicker + title + body, backdrop blur)
|
|
225
|
-
5. Implement `callout` template
|
|
226
|
-
6. Implement `image-card` template
|
|
227
|
-
|
|
228
|
-
### Phase 3: Asset server + image support
|
|
229
|
-
|
|
230
|
-
7. Extract `tests/e2e/fake-server.ts` pattern into `src/asset-server.ts`
|
|
231
|
-
- Serves files from a configurable asset directory
|
|
232
|
-
- Auto-starts before recording, auto-stops after
|
|
233
|
-
- Only starts if an overlay manifest references image assets
|
|
234
|
-
|
|
235
|
-
8. Wire asset server URL into `image-card` template `src` resolution
|
|
236
|
-
|
|
237
|
-
### Phase 4: Manifest-driven overlays
|
|
238
|
-
|
|
239
|
-
9. Define overlay manifest schema and loader in `src/overlays/manifest.ts`
|
|
240
|
-
10. Wire manifest loading into the recording fixture
|
|
241
|
-
- If `<demo>.overlays.json` exists, auto-inject overlays at matching scene marks
|
|
242
|
-
|
|
243
|
-
### Phase 5: Polish
|
|
244
|
-
|
|
245
|
-
11. Update `argo init` templates with overlay examples
|
|
246
|
-
12. Update README with overlay documentation
|
|
247
|
-
13. Add tests for each template, zone management, and manifest loading
|
|
248
|
-
|
|
249
|
-
## Migration
|
|
250
|
-
|
|
251
|
-
- `showCaption`, `withCaption`, `hideCaption` remain exported and unchanged.
|
|
252
|
-
- Existing demos work without modification.
|
|
253
|
-
- The overlay manifest is optional — demos without one behave exactly as before.
|
|
254
|
-
- `src/captions.ts` is replaced by `src/overlays.ts` but all original exports are preserved.
|
|
255
|
-
|
|
256
|
-
## Out of Scope (v1)
|
|
257
|
-
|
|
258
|
-
- Theme tokens / custom styling
|
|
259
|
-
- Staggered multi-element animation
|
|
260
|
-
- Overlay transitions (exit animations)
|
|
261
|
-
- Overlay positioning relative to DOM elements (e.g., "anchor to this button")
|
|
262
|
-
- Video-time overlays via ffmpeg (all overlays render in-browser during recording)
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
# Argo Implementation Plan
|
|
2
|
-
|
|
3
|
-
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
-
|
|
5
|
-
**Goal:** Build Argo — a CLI + library that turns Playwright demo scripts into polished product demo videos with AI-generated voiceover.
|
|
6
|
-
|
|
7
|
-
**Architecture:** Four-stage pipeline (TTS → Record → Align → Export) orchestrated by a CLI. Library exports Playwright fixtures and helpers for authoring demos. Kokoro TTS via Transformers.js for local voiceover generation, ffmpeg for final video export.
|
|
8
|
-
|
|
9
|
-
**Tech Stack:** TypeScript, Playwright, @huggingface/transformers (Kokoro TTS), ffmpeg (system dep), commander (CLI), vitest (testing)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## File Structure
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
argo/
|
|
17
|
-
├── src/
|
|
18
|
-
│ ├── index.ts # Public library exports
|
|
19
|
-
│ ├── cli.ts # CLI entry point — commander program
|
|
20
|
-
│ ├── fixtures.ts # Playwright test fixture (injects narration)
|
|
21
|
-
│ ├── narration.ts # NarrationTimeline class
|
|
22
|
-
│ ├── captions.ts # DOM caption overlay helpers
|
|
23
|
-
│ ├── tts/
|
|
24
|
-
│ │ ├── engine.ts # TTSEngine interface + WAV utilities + MockTTSEngine
|
|
25
|
-
│ │ ├── kokoro.ts # Kokoro TTS via @huggingface/transformers
|
|
26
|
-
│ │ ├── cache.ts # ClipCache — SHA-256 content-addressed caching
|
|
27
|
-
│ │ ├── generate.ts # generateClips — reads manifest, checks cache, calls engine
|
|
28
|
-
│ │ └── align.ts # Clip alignment with overlap prevention
|
|
29
|
-
│ ├── record.ts # Playwright recording wrapper
|
|
30
|
-
│ ├── export.ts # ffmpeg video+audio merge
|
|
31
|
-
│ ├── pipeline.ts # Orchestrates TTS→record→align→export
|
|
32
|
-
│ ├── config.ts # ArgoConfig type, defineConfig(), loadConfig(), demosProject()
|
|
33
|
-
│ └── init.ts # Scaffolding: creates demos/, example files, config
|
|
34
|
-
├── tests/
|
|
35
|
-
│ ├── config.test.ts
|
|
36
|
-
│ ├── narration.test.ts
|
|
37
|
-
│ ├── captions.test.ts
|
|
38
|
-
│ ├── fixtures.test.ts
|
|
39
|
-
│ ├── export.test.ts
|
|
40
|
-
│ ├── pipeline.test.ts
|
|
41
|
-
│ ├── cli.test.ts
|
|
42
|
-
│ ├── init.test.ts
|
|
43
|
-
│ └── tts/
|
|
44
|
-
│ ├── engine.test.ts
|
|
45
|
-
│ ├── kokoro.test.ts
|
|
46
|
-
│ ├── cache.test.ts
|
|
47
|
-
│ ├── generate.test.ts
|
|
48
|
-
│ └── align.test.ts
|
|
49
|
-
├── bin/
|
|
50
|
-
│ └── argo.js # CLI bin shim
|
|
51
|
-
├── package.json
|
|
52
|
-
├── tsconfig.json
|
|
53
|
-
└── .gitignore
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Chunk 1: Foundation (Tasks 1-4)
|
|
59
|
-
|
|
60
|
-
### Task 1: Project Setup
|
|
61
|
-
|
|
62
|
-
**Files:** Create: `package.json`, `tsconfig.json`, `bin/argo.js`, `.gitignore`, `src/index.ts`, `src/cli.ts`
|
|
63
|
-
|
|
64
|
-
- [ ] **Step 1.1:** Create package.json with type: module, ESM config, dependencies (commander, @huggingface/transformers), peer deps (playwright, @playwright/test), dev deps (typescript, vitest)
|
|
65
|
-
- [ ] **Step 1.2:** Create tsconfig.json (target ES2022, module NodeNext, outDir dist, strict)
|
|
66
|
-
- [ ] **Step 1.3:** Create bin/argo.js shim: `#!/usr/bin/env node` + `import('../dist/cli.js')`
|
|
67
|
-
- [ ] **Step 1.4:** Create .gitignore (node_modules, dist, .argo, videos, *.tsbuildinfo)
|
|
68
|
-
- [ ] **Step 1.5:** Create placeholder src/index.ts and src/cli.ts
|
|
69
|
-
- [ ] **Step 1.6:** npm install and verify tsc --noEmit passes
|
|
70
|
-
- [ ] **Step 1.7:** Commit: "chore: project setup with deps, tsconfig, and bin shim"
|
|
71
|
-
|
|
72
|
-
### Task 2: Config System
|
|
73
|
-
|
|
74
|
-
**Files:** Create: `src/config.ts`, Test: `tests/config.test.ts`
|
|
75
|
-
|
|
76
|
-
- [ ] **Step 2.1:** Write failing tests for defineConfig (defaults, merging, custom engine), demosProject (returns Playwright project), loadConfig (defaults, .js, .mjs, explicit path)
|
|
77
|
-
- [ ] **Step 2.2:** Run tests — verify they fail
|
|
78
|
-
- [ ] **Step 2.3:** Implement ArgoConfig types, defineConfig (deep merge with defaults), demosProject helper, loadConfig (searches for argo.config.ts/.js/.mjs, dynamic import)
|
|
79
|
-
- [ ] **Step 2.4:** Run tests — verify they pass
|
|
80
|
-
- [ ] **Step 2.5:** Commit: "feat: config system with defineConfig, loadConfig, and demosProject"
|
|
81
|
-
|
|
82
|
-
### Task 3: NarrationTimeline
|
|
83
|
-
|
|
84
|
-
**Files:** Create: `src/narration.ts`, Test: `tests/narration.test.ts`
|
|
85
|
-
|
|
86
|
-
- [ ] **Step 3.1:** Write failing tests: start sets t=0, mark records elapsed ms, mark throws before start, mark throws on duplicate, getTimings returns copy, flush writes JSON and creates dirs
|
|
87
|
-
- [ ] **Step 3.2:** Run tests — verify they fail
|
|
88
|
-
- [ ] **Step 3.3:** Implement NarrationTimeline with Map-based timings, Date.now() tracking
|
|
89
|
-
- [ ] **Step 3.4:** Run tests — verify they pass
|
|
90
|
-
- [ ] **Step 3.5:** Commit: "feat: NarrationTimeline with start, mark, getTimings, and flush"
|
|
91
|
-
|
|
92
|
-
### Task 4: Caption Helpers
|
|
93
|
-
|
|
94
|
-
**Files:** Create: `src/captions.ts`, Test: `tests/captions.test.ts`
|
|
95
|
-
|
|
96
|
-
- [ ] **Step 4.1:** Write failing tests: showCaption injects+waits+removes, hideCaption removes, withCaption wraps action, withCaption cleans up on throw
|
|
97
|
-
- [ ] **Step 4.2:** Run tests — verify they fail
|
|
98
|
-
- [ ] **Step 4.3:** Implement showCaption/hideCaption/withCaption using page.evaluate with styled overlay div
|
|
99
|
-
- [ ] **Step 4.4:** Run tests — verify they pass
|
|
100
|
-
- [ ] **Step 4.5:** Commit: "feat: caption helpers (showCaption, hideCaption, withCaption)"
|
|
101
|
-
|
|
102
|
-
---
|
|
103
|
-
|
|
104
|
-
## Chunk 2: TTS System (Tasks 5-8)
|
|
105
|
-
|
|
106
|
-
### Task 5: TTS Engine Interface + WAV Utilities
|
|
107
|
-
|
|
108
|
-
**Files:** Create: `src/tts/engine.ts`, Test: `tests/tts/engine.test.ts`
|
|
109
|
-
|
|
110
|
-
- [ ] **Step 5.1:** Write failing tests: createWavBuffer (valid header, correct data size, preserves samples), parseWavHeader (round-trip, rejects small/invalid), MockTTSEngine (interface compliance, valid WAV, records calls)
|
|
111
|
-
- [ ] **Step 5.2:** Run tests — verify they fail
|
|
112
|
-
- [ ] **Step 5.3:** Implement TTSEngine interface, createWavBuffer (mono 24kHz 32-bit float), parseWavHeader (find data chunk), createMockTTSEngine
|
|
113
|
-
- [ ] **Step 5.4:** Run tests — verify they pass
|
|
114
|
-
- [ ] **Step 5.5:** Commit: "feat(tts): TTSEngine interface, WAV utilities, and MockTTSEngine"
|
|
115
|
-
|
|
116
|
-
### Task 6: Kokoro TTS Engine
|
|
117
|
-
|
|
118
|
-
**Files:** Create: `src/tts/kokoro.ts`, Test: `tests/tts/kokoro.test.ts`
|
|
119
|
-
|
|
120
|
-
- [ ] **Step 6.1:** Implement KokoroEngine: lazy-loads pipeline from @huggingface/transformers, generates WAV via createWavBuffer
|
|
121
|
-
- [ ] **Step 6.2:** Write integration test (skipped in CI): generates valid WAV, throws on empty text
|
|
122
|
-
- [ ] **Step 6.3:** Commit: "feat(tts): KokoroEngine with lazy model loading"
|
|
123
|
-
|
|
124
|
-
### Task 7: Clip Caching
|
|
125
|
-
|
|
126
|
-
**Files:** Create: `src/tts/cache.ts`, Test: `tests/tts/cache.test.ts`
|
|
127
|
-
|
|
128
|
-
- [ ] **Step 7.1:** Write failing tests: isCached false/true, getCachedClip null/buffer, invalidation on text/voice/speed change, independent per demo
|
|
129
|
-
- [ ] **Step 7.2:** Run tests — verify they fail
|
|
130
|
-
- [ ] **Step 7.3:** Implement ClipCache: SHA-256 hash of {scene,text,voice,speed}, stores in .argo/<demo>/clips/<hash>.wav
|
|
131
|
-
- [ ] **Step 7.4:** Run tests — verify they pass
|
|
132
|
-
- [ ] **Step 7.5:** Commit: "feat(tts): ClipCache with SHA-256 content-addressed caching"
|
|
133
|
-
|
|
134
|
-
### Task 8: TTS Generate Command
|
|
135
|
-
|
|
136
|
-
**Files:** Create: `src/tts/generate.ts`, Test: `tests/tts/generate.test.ts`
|
|
137
|
-
|
|
138
|
-
- [ ] **Step 8.1:** Write failing tests: generates all entries, uses cache on rerun, regenerates only changed, applies defaults, throws on missing file/invalid JSON/missing fields
|
|
139
|
-
- [ ] **Step 8.2:** Run tests — verify they fail
|
|
140
|
-
- [ ] **Step 8.3:** Implement generateClips: read manifest, validate entries, check cache, call engine, cache results
|
|
141
|
-
- [ ] **Step 8.4:** Run tests — verify they pass
|
|
142
|
-
- [ ] **Step 8.5:** Commit: "feat(tts): generateClips with manifest parsing and cache integration"
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
## Chunk 3: Recording & Alignment (Tasks 9-10)
|
|
147
|
-
|
|
148
|
-
### Task 9: Playwright Fixtures
|
|
149
|
-
|
|
150
|
-
**Files:** Create: `src/fixtures.ts`, Test: `tests/fixtures.test.ts`
|
|
151
|
-
|
|
152
|
-
- [ ] **Step 9.1:** Write failing tests: createNarrationFixture (creates timeline, starts, provides, flushes; flushes on throw), demoType (types with delay, custom delay)
|
|
153
|
-
- [ ] **Step 9.2:** Run tests — verify they fail
|
|
154
|
-
- [ ] **Step 9.3:** Implement createNarrationFixture factory, demoType helper (pressSequentially), test.extend with narration fixture
|
|
155
|
-
- [ ] **Step 9.4:** Run tests — verify they pass
|
|
156
|
-
- [ ] **Step 9.5:** Commit: "feat: Playwright fixtures with narration injection and demoType"
|
|
157
|
-
|
|
158
|
-
### Task 10: Alignment
|
|
159
|
-
|
|
160
|
-
**Files:** Create: `src/tts/align.ts`, Test: `tests/tts/align.test.ts`
|
|
161
|
-
|
|
162
|
-
- [ ] **Step 10.1:** Write failing tests: places clips at timestamps, prevents overlap with 100ms gap, correct output buffer duration, mixes samples at correct positions, handles empty, orders by timestamp, skips unknown scenes
|
|
163
|
-
- [ ] **Step 10.2:** Run tests — verify they fail
|
|
164
|
-
- [ ] **Step 10.3:** Implement alignClips: filter/sort by timing, overlap prevention, create silence buffer, mix samples
|
|
165
|
-
- [ ] **Step 10.4:** Run tests — verify they pass
|
|
166
|
-
- [ ] **Step 10.5:** Commit: "feat(tts): clip alignment with overlap prevention and sample mixing"
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## Chunk 4: Export, Pipeline, CLI & Init (Tasks 11-14)
|
|
171
|
-
|
|
172
|
-
### Task 11: Export (ffmpeg)
|
|
173
|
-
|
|
174
|
-
**Files:** Create: `src/export.ts`, Test: `tests/export.test.ts`
|
|
175
|
-
|
|
176
|
-
- [ ] **Step 11.1:** Write failing tests: checkFfmpeg (available/missing), exportVideo (correct args, custom config, missing files, non-zero exit)
|
|
177
|
-
- [ ] **Step 11.2:** Run tests — verify they fail
|
|
178
|
-
- [ ] **Step 11.3:** Implement checkFfmpeg (execSync ffmpeg -version), exportVideo (spawnSync with -c:v libx264 -preset -crf -c:a aac -shortest)
|
|
179
|
-
- [ ] **Step 11.4:** Run tests — verify they pass
|
|
180
|
-
- [ ] **Step 11.5:** Commit: "feat: ffmpeg export with configurable encoding options"
|
|
181
|
-
|
|
182
|
-
### Task 12: Pipeline Orchestration
|
|
183
|
-
|
|
184
|
-
**Files:** Create: `src/pipeline.ts`, Test: `tests/pipeline.test.ts`
|
|
185
|
-
|
|
186
|
-
- [ ] **Step 12.1:** Write failing tests: calls all steps in order (tts → record → export), checks ffmpeg first
|
|
187
|
-
- [ ] **Step 12.2:** Implement runPipeline: checkFfmpeg, then generateClips → record → alignClips → exportVideo with console progress
|
|
188
|
-
- [ ] **Step 12.3:** Run tests — verify they pass
|
|
189
|
-
- [ ] **Step 12.4:** Commit: "feat: pipeline orchestration for end-to-end demo generation"
|
|
190
|
-
|
|
191
|
-
### Task 13: CLI
|
|
192
|
-
|
|
193
|
-
**Files:** Create: `src/cli.ts`, Test: `tests/cli.test.ts`
|
|
194
|
-
|
|
195
|
-
- [ ] **Step 13.1:** Write failing tests: record/tts generate/tts align/export/pipeline/init commands call correct functions, --config passes to loadConfig
|
|
196
|
-
- [ ] **Step 13.2:** Implement createProgram with commander: all commands as thin wrappers that load config and delegate
|
|
197
|
-
- [ ] **Step 13.3:** Run tests — verify they pass
|
|
198
|
-
- [ ] **Step 13.4:** Commit: "feat: CLI with commander for all pipeline commands"
|
|
199
|
-
|
|
200
|
-
### Task 14: Init + Library Exports
|
|
201
|
-
|
|
202
|
-
**Files:** Create: `src/init.ts`, Modify: `src/index.ts`, Test: `tests/init.test.ts`
|
|
203
|
-
|
|
204
|
-
- [ ] **Step 14.1:** Write failing tests: creates demos/, example.demo.ts, example.voiceover.json, argo.config.ts; does not overwrite existing
|
|
205
|
-
- [ ] **Step 14.2:** Implement init: writeIfMissing for each scaffold file with template content
|
|
206
|
-
- [ ] **Step 14.3:** Update src/index.ts: export test, expect, demoType, NarrationTimeline, showCaption, hideCaption, withCaption, defineConfig, demosProject, TTSEngine type
|
|
207
|
-
- [ ] **Step 14.4:** Run all tests: `npx vitest run`
|
|
208
|
-
- [ ] **Step 14.5:** Commit: "feat: init scaffolding and complete library exports"
|