capcut-cli-david
v1.3.0
Published
Fork of capcut-cli — CapCut/JianYing draft CLI extended with creation primitives (keyframes, Ken Burns) and the psycho-build pipeline for the TikTok paranoia niche.
Maintainers
Readme
capcut-cli-david
One CLI to build, edit, and inspect CapCut
draft_content.jsonprojects — combiningcutcli's creation power (keyframes, Ken Burns, animations) withcapcut-cli's inspection surface (segments, tracks, SRT export), plus apsycho-buildYAML pipeline for assembling complete TikTok-format vertical shorts in one command.
Why this exists
There are two existing tools in this space and each covers half the surface. Rene Zander's capcut-cli is excellent at inspecting existing drafts — segments, tracks, materials, SRT export — but is effectively read-only when it comes to creation primitives. The closed-source cutcli Go binary covers the creation half — keyframes, Ken Burns, animations, stickers, filters — but offers nothing for inspection or pipelined assembly.
capcut-cli-david is the fork that does both. One binary (capcut-david), zero runtime dependencies, fully scriptable. On top of the union of those two surfaces, it ships a psycho-build command that consumes a single YAML manifest (images + audio + captions) and produces a complete TikTok-format (1080×1920) vertical draft — deterministic via --seed, ready to open in CapCut.
The audience: anyone scripting CapCut drafts. TikTok creators automating shorts, video automation pipelines, AI-driven video assembly, and Claude Code skills (a bundled capcut-david skill ships in the package).
Comparison
| Feature | cutcli (upstream Go) | capcut-cli (renezander030) | capcut-cli-david |
|---|---|---|---|
| Inspect segments / tracks / materials | ❌ | ✅ | ✅ |
| Export SRT | ❌ | ✅ | ✅ |
| Edit (shift / speed / volume / trim / opacity / set-text) | partial | ✅ | ✅ |
| Add video / audio / text | ✅ | ✅ | ✅ |
| Keyframes (add-keyframe, any property) | ✅ (mid-level API) | ❌ | ✅ (CLI flag) |
| Ken Burns (ken-burns) | ✅ (manual keyframes) | ❌ | ✅ (one command) |
| Templates (save / apply) | ❌ | ✅ | ✅ |
| Long-form → short (cut) | ❌ | ✅ | ✅ |
| Batch JSONL stdin (batch) | ❌ | ✅ | ✅ |
| YAML manifest pipeline (psycho-build) | ❌ | ❌ | ✅ |
| Test suite | minimal | minimal | 212 tests, 93%+ coverage |
| Schema reference docs | partial (zh-CN) | minimal | full (docs/draft-schema/) |
| Lint / typecheck / CI matrix | none | none | Biome 2 + tsc + Node 18/20/22 × Ubuntu/macOS/Windows |
| Node version | n/a (Go) | ≥ 18 | ≥ 18 |
| Runtime deps | n/a | minimal | zero |
| License | unclear | MIT | MIT |
(Rows for cutcli reflect the closed-source Go binary's observed output and may be incomplete.)
Install
npm install -g capcut-cli-david
# CLI binary: capcut-david
capcut-david --helpRequires Node ≥ 18. Zero runtime dependencies.
Quickstart
Inspect an existing draft
capcut-david info ./MyProject -H
capcut-david tracks ./MyProject -H
capcut-david segments ./MyProject --track text
capcut-david export-srt ./MyProject > subs.srtAdd Ken Burns to a still image
capcut-david add-video ./MyProject ./photo.jpg 0s 4s
# Take the segment id printed above, then:
capcut-david ken-burns ./MyProject <segment-id> --from 1.0 --to 1.15Build a complete TikTok draft from YAML
capcut-david psycho-build examples/psycho/manifest.example.yaml \
--out ./build/my-short \
--seed 42--seed makes the build deterministic — same manifest + same seed → byte-identical draft, so you can diff outputs in CI. See examples/psycho/ for the full manifest example and minimal asset stubs.
A minimal manifest:
title: Paranoia Spiral
resolution: { width: 1080, height: 1920 }
fps: 30
images:
- { path: ./assets/img1.jpg, duration: 3s, ken_burns: { from: 1.0, to: 1.3, curve: ease-out } }
- { path: ./assets/img2.jpg, duration: 3s, ken_burns: { from: 1.3, to: 1.0, curve: ease-out } }
voice: { path: ./assets/narration.mp3, volume: 1.0 }
music: { path: ./assets/ambient.mp3, volume: 0.25 } # statically ducked
captions:
srt: ./assets/captions.srt
style: { font_size: 24, color: "#FFD700", align: 0 }Commands
Full index — group by family. For per-flag reference, run capcut-david <command> --help.
Inspect
| Command | Purpose |
|---|---|
| info <project> | Draft summary: resolution, fps, duration, track + material counts |
| tracks <project> | List tracks with id, type, segment count |
| materials <project> [--type <t>] | List materials filtered by type (videos / audios / texts / …) |
| segments <project> [--track <id>] | List segments, optionally filtered to one track |
| segment <project> <id> | Detailed dump of a single segment |
| material <project> <id> | Detailed dump of a single material |
| texts <project> | All text segments with their content |
| export-srt <project> | Emit captions as SRT to stdout |
Edit (writes .bak before mutating)
| Command | Purpose |
|---|---|
| set-text <project> <id> "<text>" | Replace text content of a text segment |
| shift <project> <id> <±duration> | Shift a single segment in time |
| shift-all --offset <±duration> [--track <t>] | Shift every segment (optionally per-track) |
| speed <project> <id> <factor> | Re-time a video/audio segment |
| volume <project> <id> <0..1> | Set audio segment volume |
| trim <project> <id> <start> <end> | Trim a segment to a sub-range |
| opacity <project> <id> <0..1> | Set visual segment opacity |
| cut <project> <start> <end> --out <file> | Long-form → short clipping |
Create
| Command | Purpose |
|---|---|
| init <name> --drafts <dir> | Bootstrap an empty draft directory |
| add-video <project> <path> <start> <end> | Append a video/image segment |
| add-audio <project> <path> <start> <end> [--volume] | Append an audio segment |
| add-text <project> <start> <end> "<text>" [--font-size --color] | Append a text segment |
| save-template <project> <id> <name> --out <file> | Extract a segment as reusable template |
| apply-template <project> <template> <start> <end> "<text>" | Apply a saved template |
Animate (Phase C)
| Command | Purpose |
|---|---|
| add-keyframe <project> <id> <time> --property <p> --value <v> [--curve <c>] | Insert one keyframe on scale_x/scale_y/position_x/position_y/rotation/alpha. Curves: linear, ease-in, ease-out, ease-in-out. |
| ken-burns <project> <id> --from <s> --to <s> [--curve <c>] | Paired scale_x + scale_y keyframes from t=0 to t=segment.duration. Default curve ease-out (CapCut "Cubic Out"). |
Batch
| Command | Purpose |
|---|---|
| batch <project> | Read JSONL ops on stdin ({"cmd": "...", ...}), apply atomically |
Pipeline (Phase D)
| Command | Purpose |
|---|---|
| psycho-build <manifest.yaml> [--out <dir>] [--seed <n>] | Full TikTok-format draft from a YAML manifest |
Output modes
JSON (default), human-readable (-H / --human), quiet (-q / --quiet).
capcut-david texts ./project | jq '.[].text'
capcut-david info ./project -H
capcut-david set-text ./project a1b2c3 "Fixed" -q && echo doneTime formats
1.5s, 500ms, +0.5s, -1s, 1:30, 0:05.5. Negative offsets allowed where they make sense (e.g. shift).
IDs
Segment and material IDs are UUIDs. The first 6+ chars work as a prefix match.
Documentation
docs/draft-schema/— reverse-engineered reference for CapCut'sdraft_content.json(the JSON Bible)skills/capcut-david/SKILL.md— Claude Code skill for AI assistants (recipes + cookbook)CHANGELOG.md— release history (Keep a Changelog 1.1, SemVer 2.0)examples/psycho/— Quickstart manifest for thepsycho-buildpipeline
Compatibility
- CapCut: 5.x+ desktop on Windows + macOS. Both the
cutcli-emitted draft shape (new_version: 167.x) and the CapCut-UI-emitted shape (169.x) load. - JianYing: 5.x is presumed-equivalent to CapCut 5.x. JianYing 6+ is unsupported — the on-disk
draft_content.jsonis encrypted;capcut-davidexits non-zero with a documented error. SeeCOMPATIBILITY.md§5. - Node: ≥ 18 (
engines.nodeinpackage.json). CI matrix covers Node 18 / 20 / 22 on Ubuntu / macOS / Windows. - Runtime deps: zero. Built entirely on the Node standard library.
- Encoding: UTF-8 without BOM. Never re-save edited drafts via PowerShell
Out-Filewithout-Encoding utf8— CapCut refuses BOM-prefixed JSON.
Project status
| Phase | Goal | Version | State |
|---|---|---|---|
| A | Fork + restructure baseline | 0.1.0 | shipped |
| B | Fixture-backed test suite (102 tests) | 0.2.0 | shipped |
| C | add-keyframe + ken-burns (33 new tests) | 0.3.0 | shipped |
| D | psycho-build YAML pipeline (39 new tests, 212 total) | 0.4.0 | shipped |
| E | SKILL.md + polished docs + 1.0 graduation | 1.0.0 | in progress (0.5.0 → 1.0.0-rc.N → 1.0.0) |
Aggregate test coverage on src/commands/* + src/draft.ts: 93%+ lines, 91%+ functions (CI gate: 80%).
Contributing
PRs welcome for bug fixes, schema validation, additional fixtures, and portability fixes. For new commands or behavioral changes, open an issue first to discuss scope and the upstream-sync implication.
- Follow Conventional Commits.
- Run
npm test && npm run lint && npm run typecheckbefore submitting. - Portable bug fixes that apply to upstream
capcut-cliare landed there too where reasonable — seeUPSTREAM.md§4 (PR-back policy).
Acknowledgements
capcut-cliby renezander030 — the upstream this fork is built on. Provides the inspection surface and the modular draft helpers that everything else extends.cutcli— closed-source Go binary whose draft output informed the schema reverse-engineering and inspired the creation primitives. No code copied; behaviour reproduced from on-disk JSON observation.- CapCut by ByteDance — the upstream product. This project is unaffiliated with ByteDance and operates only against locally-stored draft files.
