From f6def4295eff51f1c8cb357ac4221639a82cb6de Mon Sep 17 00:00:00 2001 From: Vance Ingalls Date: Wed, 25 Mar 2026 20:58:36 -0700 Subject: [PATCH] feat(cli): add blank template option, smart defaults for video vs audio - Blank template: minimal scaffolding (root composition, video, audio, GSAP timeline) with __VIDEO_SRC__ and __VIDEO_DURATION__ placeholders - Template defaults: video uploads default to "blank" (user brings their own content), audio-only defaults to "warm-grain" (motion graphics template since there's no video to show) - Audio-only projects now tracked with isAudioOnly flag Co-Authored-By: Claude Opus 4.6 (1M context) --- packages/cli/package.json | 2 +- packages/cli/src/commands/init.ts | 10 +- .../blank/compositions/captions.html | 92 +++++++++++++++++++ packages/cli/src/templates/blank/index.html | 44 +++++++++ packages/cli/src/templates/generators.ts | 3 +- 5 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 packages/cli/src/templates/blank/compositions/captions.html create mode 100644 packages/cli/src/templates/blank/index.html diff --git a/packages/cli/package.json b/packages/cli/package.json index a38f1f7cad..47a01544ea 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -14,7 +14,7 @@ "build": "bun run build:studio && tsup && bun run build:runtime && bun run build:copy", "build:studio": "cd ../studio && bun run build", "build:runtime": "tsx scripts/build-runtime.ts", - "build:copy": "mkdir -p dist/studio dist/docs dist/templates && cp -r ../studio/dist/* dist/studio/ && cp -r src/templates/warm-grain src/templates/play-mode src/templates/swiss-grid src/templates/vignelli dist/templates/ && (cp src/docs/*.md dist/docs/ 2>/dev/null || true)", + "build:copy": "mkdir -p dist/studio dist/docs dist/templates && cp -r ../studio/dist/* dist/studio/ && cp -r src/templates/blank src/templates/warm-grain src/templates/play-mode src/templates/swiss-grid src/templates/vignelli dist/templates/ && (cp src/docs/*.md dist/docs/ 2>/dev/null || true)", "typecheck": "tsc --noEmit" }, "dependencies": { diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index 90344add7e..61aa5bbf98 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -559,6 +559,7 @@ export default defineCommand({ let localVideoName: string | undefined; let sourceFilePath: string | undefined; let videoDuration: number | undefined; + let isAudioOnly = false; if (videoFlag) { const videoPath = resolve(videoFlag); @@ -612,8 +613,8 @@ export default defineCommand({ localVideoName = result.localVideoName; videoDuration = result.meta.durationSeconds; } else { - // Audio file — copy to assets/ - + // Audio file — copy to project root + isAudioOnly = true; copyFileSync(filePath, resolve(destDir, basename(filePath))); clack.log.info(`Audio copied to ${c.accent(basename(filePath))}`); } @@ -662,7 +663,8 @@ export default defineCommand({ } } - // 3. Pick template — single list for all templates + // 3. Pick template — default depends on media type + const defaultTemplate = isAudioOnly ? "warm-grain" : "blank"; const templateResult = await clack.select({ message: "Pick a template", options: TEMPLATES.map((t) => ({ @@ -670,7 +672,7 @@ export default defineCommand({ label: t.label, hint: t.hint, })), - initialValue: TEMPLATES[0]?.id, + initialValue: defaultTemplate as TemplateId, }); if (clack.isCancel(templateResult)) { clack.cancel("Setup cancelled."); diff --git a/packages/cli/src/templates/blank/compositions/captions.html b/packages/cli/src/templates/blank/compositions/captions.html new file mode 100644 index 0000000000..2b557abd4d --- /dev/null +++ b/packages/cli/src/templates/blank/compositions/captions.html @@ -0,0 +1,92 @@ + diff --git a/packages/cli/src/templates/blank/index.html b/packages/cli/src/templates/blank/index.html new file mode 100644 index 0000000000..d4f2bef916 --- /dev/null +++ b/packages/cli/src/templates/blank/index.html @@ -0,0 +1,44 @@ +
+ + + +
+ + + +
diff --git a/packages/cli/src/templates/generators.ts b/packages/cli/src/templates/generators.ts index 8d2657477d..11e5396ca2 100644 --- a/packages/cli/src/templates/generators.ts +++ b/packages/cli/src/templates/generators.ts @@ -1,4 +1,4 @@ -export type TemplateId = "warm-grain" | "play-mode" | "swiss-grid" | "vignelli"; +export type TemplateId = "blank" | "warm-grain" | "play-mode" | "swiss-grid" | "vignelli"; export interface TemplateOption { id: TemplateId; @@ -7,6 +7,7 @@ export interface TemplateOption { } export const TEMPLATES: TemplateOption[] = [ + { id: "blank", label: "Blank", hint: "Empty composition — just the scaffolding" }, { id: "warm-grain", label: "Warm Grain", hint: "Cream aesthetic with grain texture" }, { id: "play-mode", label: "Play Mode", hint: "Playful elastic animations" }, { id: "swiss-grid", label: "Swiss Grid", hint: "Structured grid layout" },