From d2a0ba9d3b7e6651ec60bc6d143c97aa71a742e3 Mon Sep 17 00:00:00 2001 From: pratyush Date: Sat, 30 May 2026 22:42:54 +0530 Subject: [PATCH 1/3] FEAT: Add 'templates' command to list bundled templates --- README.md | 3 +- src/index.ts | 55 ++++++++++++++++++++++++++++++++++++- test/showTemplates.test.mjs | 32 +++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 test/showTemplates.test.mjs diff --git a/README.md b/README.md index d7c20a9..152e754 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,8 @@ Status of every feature shipped. ✅ = implemented, ⬜ = roadmap. Section ancho ### Templates - ✅ [`save-template`](#templates) · [`apply-template`](#templates) — extract any segment as reusable JSON; restamp with new timing / position / text -- ✅ 3 templates ship in [`templates/`](./templates/): `gold-title`, `end-card`, `subscribe-cta` +- ✅ [`template`](#templates) — List avaliable templates that can be used +- ✅ 6 templates ship in [`templates/`](./templates/): `gold-title`, `end-card`, `subscribe-cta`, `hook-question`, `lower-third`, `caption-pop` ### Import & discovery - ✅ [`import-srt`](#import-srt-subtitles-phase-3) — one cue per text segment; file, stdin, or `--style-ref` mirror diff --git a/src/index.ts b/src/index.ts index c6c7971..48cdea7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ #!/usr/bin/env node -import { existsSync, readFileSync, writeFileSync } from "node:fs"; +import { existsSync, readFileSync, writeFileSync, readdirSync } from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; import { parseAss } from "./ass.js"; import { captionDraft } from "./caption.js"; import { removeChroma, setChroma } from "./chroma.js"; @@ -250,6 +252,9 @@ Templates: apply-template [text override] Stamp a template into a project at the given time Options: --x --y (override position) + templates + Show available templates in the template library. + Use -H for a table. Project: cut --out @@ -1925,6 +1930,48 @@ function cmdDoctor(flags: Flags): boolean { return report.ok; } +function cmdTemplates(flags: Flags): void { + const cliDir = path.dirname(fileURLToPath(import.meta.url)); + const templatesPath = path.join(cliDir, "..", "templates"); + + if (!existsSync(templatesPath)) { + die(`Templates directory not found: ${templatesPath}`); + } + + const descriptions: Record = { + "caption-pop": "word-highlight pop captions", + "lower-third": "name/title lower third", + "hook-question": "opening hook question card", + "gold-title": "gold title card", + "end-card": "end / outro card", + "subscribe-cta": "subscribe call-to-action", + }; + + const entries = readdirSync(templatesPath) + .filter((f) => f.endsWith(".json")) + .map((f) => { + const slug = path.basename(f, ".json"); + return { + slug, + description: descriptions[slug] ?? slug.replace(/-/g, " "), + }; + }); + + if (flags.human) { + if (entries.length === 0) { + console.log("No bundled templates found."); + return; + } + console.log(`${"Slug".padEnd(33)} Description`); + for (const e of entries) { + console.log(`${e.slug.padEnd(33)} ${e.description}`); + } + process.stderr.write(`\n${entries.length} templates\n`); + } else { + out(entries, flags); + } +} + // --- Main --- async function main(): Promise { @@ -1967,6 +2014,12 @@ async function main(): Promise { process.exit(0); } + // `templates` list all available templates + if (cmd === "templates") { + cmdTemplates(flags); + process.exit(0); + } + // init doesn't need an existing project if (cmd === "init") { const name = projectPath; // positional[1] is the name for init diff --git a/test/showTemplates.test.mjs b/test/showTemplates.test.mjs new file mode 100644 index 0000000..65b3b2f --- /dev/null +++ b/test/showTemplates.test.mjs @@ -0,0 +1,32 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import { spawnCli } from "./helpers/spawn-cli.mjs"; + +describe("capcut available templates", () => { + it("lists available templates as JSON by default", () => { + const r = spawnCli(["templates"]); + + assert.equal(r.status, 0, `stderr: ${r.stderr}`); + assert.ok(r.json, "stdout should be valid JSON"); + assert.ok(Array.isArray(r.json)); + + const slugs = r.json.map((t) => t.slug); + + assert.ok(slugs.includes("caption-pop")); + assert.ok(slugs.includes("lower-third")); + assert.ok(slugs.includes("hook-question")); + assert.ok(slugs.includes("gold-title")); + assert.ok(slugs.includes("end-card")); + assert.ok(slugs.includes("subscribe-cta")); + }); + + it("renders a human-readable layout with -H", () => { + const r = spawnCli(["templates", "-H"]); + + assert.equal(r.status, 0); + + assert.match(r.stdout, /Slug/); + assert.match(r.stdout, /caption-pop/); + assert.match(r.stdout, /gold-title/); + }); +}); From 16bc9800721958ff2e6c55d4ec97eade121cd8fe Mon Sep 17 00:00:00 2001 From: CaptainLevi25 <118070179+CaptainLevi25@users.noreply.github.com> Date: Sun, 31 May 2026 00:24:39 +0530 Subject: [PATCH 2/3] Fix: Spelling mistake in Readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 152e754..cad857f 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Status of every feature shipped. ✅ = implemented, ⬜ = roadmap. Section ancho ### Templates - ✅ [`save-template`](#templates) · [`apply-template`](#templates) — extract any segment as reusable JSON; restamp with new timing / position / text -- ✅ [`template`](#templates) — List avaliable templates that can be used +- ✅ [`template`](#templates) — List available templates that can be used - ✅ 6 templates ship in [`templates/`](./templates/): `gold-title`, `end-card`, `subscribe-cta`, `hook-question`, `lower-third`, `caption-pop` ### Import & discovery From 8366b38a59414e3cdf9adeffb9fedcace3cf4719 Mon Sep 17 00:00:00 2001 From: Rene Zander Date: Sun, 31 May 2026 06:44:16 +0000 Subject: [PATCH 3/3] fix: sort node:fs imports (lint) and correct README command label Co-Authored-By: Claude Opus 4.8 (1M context) --- README.md | 2 +- src/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cad857f..455c766 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ Status of every feature shipped. ✅ = implemented, ⬜ = roadmap. Section ancho ### Templates - ✅ [`save-template`](#templates) · [`apply-template`](#templates) — extract any segment as reusable JSON; restamp with new timing / position / text -- ✅ [`template`](#templates) — List available templates that can be used +- ✅ [`templates`](#templates) — List available templates that can be used - ✅ 6 templates ship in [`templates/`](./templates/): `gold-title`, `end-card`, `subscribe-cta`, `hook-question`, `lower-third`, `caption-pop` ### Import & discovery diff --git a/src/index.ts b/src/index.ts index 3ae0858..b2b3682 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,6 @@ #!/usr/bin/env node -import { existsSync, readFileSync, writeFileSync, readdirSync } from "node:fs"; +import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { parseAss } from "./ass.js";