Skip to content

Releases

v0.33.1

Choose a tag to compare

@github-actions github-actions released this 06 Nov 11:50
8c02657

What's Changed

  • Release v0.33.1: Windows-safe anonymize test and complete v0.33.0 docs by @renezander030 in #173

Full Changelog: v0.33.0...v0.33.1

v0.33.0

Choose a tag to compare

@github-actions github-actions released this 06 Nov 11:23
54991a5

What's Changed

  • fix(text-style): apply --font-size, --color, --align, --x, --y without a preset by @abdullahmalik853-web in #166
  • feat: add zero-dep ByteDance CapCut cloud subtitle translation by @datnt-97 in #169
  • fix(translate): harden CapCut cloud translation from #169 by @renezander030 in #170
  • fix(store): leave the CLI's own process chain out of the editor-open guard by @renezander030 in #171
  • Release v0.33.0: caption coverage and cache, delivery gates, draft-change diff, shareable fixtures by @renezander030 in #172

New Contributors

Full Changelog: v0.32.0...v0.33.0

v0.32.0

Choose a tag to compare

@github-actions github-actions released this 29 Oct 19:47
6521c89

What's Changed

  • Include the fake CLI in Python source distributions by @renezander030 in #160
  • docs: More from René block (agent tools) in README and README.zh-CN by @renezander030 in #161
  • chore(deps-dev): bump @biomejs/biome from 2.5.15 to 2.6.2 in the dev-dependencies group by @dependabot[bot] in #162
  • docs(readme): play the captioned output example inline by @renezander030 in #164
  • Release v0.32.0: validate timing, translation and subtitle inputs by @renezander030 in #165

Full Changelog: v0.31.1...v0.32.0

v0.31.1

Choose a tag to compare

@github-actions github-actions released this 23 Oct 13:40
a7bccff

What's Changed

  • Release v0.31.1: ffmpeg on the runners for the packed-tarball smoke by @renezander030 in #159

Full Changelog: v0.31.0...v0.31.1

v0.30.0 — per-command help, journal-checked undo, whisper.cpp word timings

Choose a tag to compare

@renezander030 renezander030 released this 16 Oct 09:22
02a20fa

Added

  • capcut <command> --help, capcut <command> -h and capcut help <command> print that command's usage, options, global options, output, prerequisites and exit codes, rendered from the same registry as describe and the command reference. Before, none of the 87 commands printed its own help: 79 read --help as an argument and failed (add-text --help: "No draft found at: --help"), and 8 ran instead (doctor --help ran the checks). capcut help alone, or an unknown command, prints the full help.
  • restore --list reports integrity per step: intact (the snapshot still matches the before_sha256 the write journal recorded), changed (it was rewritten after the CLI saved it), or unverified (no journal entry). restore and restore --step N results carry the same field.
  • caption --words reads whisper.cpp full JSON (whisper-cli -ojf, transcription[].tokens[]) and reports words_format: "whisper-cpp". Words are built from the tokens as in caption --audio; a segment whose tokens cannot be split into words stays one entry with its own timing.
  • test/fixtures/jianying-9-0-0-windows/ — a real JianYing 9.0.0 (Windows) project captured after the app opened a tool-written draft: the plaintext draft_info.json primary alongside the draft_content.json / template-2.tmp / draft_meta_info.json mirrors the app rewrote into encrypted blobs, plus the materialised Timelines/ layout. A regression test pins that the encrypted mirrors are reported as unparseable rather than breaking canonical selection, and docs/version-support.md gains a JianYing 9.0.0 (Windows) row (evidence: reported; storage shape fixture-backed). The write guard is deliberately unchanged — one machine's capture is not a round-trip claim.

Changed

  • With --karaoke or --word-reveal, caption runs whisper.cpp with -ojf and times each word from its tokens instead of splitting each segment evenly. A token that starts with a space opens a word and any other token (a sub-word piece, punctuation) continues it; in Chinese and Japanese every token is its own word. [_BEG_] / [_TT_n] tokens are skipped, a word stamped with zero length runs to the next word's start, and a segment whose tokens do not spell its text keeps the even split. Plain -oj output parses as before.
  • translate defaults to claude-haiku-5-5 (was claude-haiku-4-5-20251001), with a 16,000-token response budget and low effort.

Fixed

  • restore no longer puts back the app's own save state after the app saved the project (#151). History snapshots were a second name (hard link) for <draft>.bak, which CapCut 9.5 rewrites in place when it saves; each snapshot is now its own file. restore and restore --step N check the file against the write journal first and refuse one that changed since the CLI wrote it with refused [backup-changed] / refused [snapshot-changed]; the .bak refusal points at --step 1 when that snapshot is intact, and --force-write restores the file as it is. Snapshots written by earlier versions that still share bytes with a rewritten .bak list as changed.

v0.29.0 — aligner word timings, reviewed batch plans, render fidelity and lint checks

Choose a tag to compare

@renezander030 renezander030 released this 09 Oct 13:21
648f469

v0.29.0

Added

  • caption --words <file.json|-> builds captions from word timings produced by an external aligner, so Whisper does not have to be installed. The format is detected automatically: Whisper / whisper.cpp segments[].words[], WhisperX word_segments[], or a plain {word|text|char, start, end} array with times in seconds, start_ms/end_ms or start_time/end_time (per-character forced-aligner output). The result reports words_format, words_skipped and source_words. Entries without timing are skipped; entries that end before they start or go back in time are refused with refused [words-invalid] naming the entry. Grouping, CJK joining without spaces, --script, --karaoke and --word-reveal behave exactly as with Whisper words. --words cannot be combined with --audio, --from-segment, --audio-stream, --ffmpeg-cmd or --whisper-*.
  • batch <project> --plan <plan.json> < ops.jsonl validates the operations under dry-run without touching the draft and writes a reviewable plan: project, draft_sha256, the normalized operations, operations_sha256 (over key-sorted JSON) and a per-operation preview. batch <project> --apply-plan <plan.json> reads no stdin and applies the plan through the normal transactional batch. It refuses with refused [plan-draft-changed] when the draft changed since the plan was written, refused [plan-tampered] when the operations no longer match their hash, and refused [plan-project-mismatch] when the plan names another project. Without --continue-on-error a failing operation writes no plan.
  • render (including --dry-run) reports a fidelity census of what the proxy leaves out compared with the app: faithful, expected_duration_us, the checked categories, and per dropped category a count, up to 20 segment ids and a hint (missing media, closed main-track gaps, uncomposited overlay tracks, unburned text, stickers, transitions, effects, filters, masks, keyframes, text/video animations, blend modes, chroma key, matting). render --strict refuses with refused [render-unfaithful] before anything is written.
  • After a real render, render probes the written file with ffprobe (--ffprobe-cmd selects the binary) and reports verification: { verified, duration_us, expected_duration_us, drift_us, tolerance_us, within_tolerance }, with a tolerance of one frame at the render fps. When ffprobe is missing or cannot read the file it reports verified: false with a reason. render --verify exits non-zero on drift beyond tolerance or an unverifiable file; the file stays on disk and the JSON result is still printed.
  • tts --lexicon <file.json> applies pronunciation rules ({"rules":[{"text","say","case_sensitive"?}]} or a bare array) to the text handed to the TTS engine only: longest match first, at word boundaries for rule edges that are word characters (SQL never fires inside MySQLite; CJK rules match anywhere). Malformed lexicons refuse with refused [lexicon-invalid], and equal-length rules that say different things at the same position refuse with refused [lexicon-ambiguous], both before any engine runs. The result reports lexicon: { rules, applied, spoken_text } with offsets in UTF-16 code units into the trimmed text. Works with --text and --text-file.
  • lint reports segment-overlap (error) when two segments on the same non-text track (video, audio, sticker, effect, filter …) overlap, naming the track, both segment ids and the overlap in µs. lint --fix repairs overlaps of at most one frame at the draft's fps (the independent-rounding overlap) by ending the earlier segment where the next begins, keeping its source duration in proportion to speed. Wider overlaps are reported, not fixed. Text tracks keep caption-overlap.
  • lint reports segment-offscreen (warning) for video, photo, sticker and text segments that cannot be seen: the clip's box lies entirely outside the canvas (material size fitted into canvas_config, rotation allowed for), a scale axis is 0, or opacity is 0. Segments whose position, scale or alpha is keyframed are not judged on that property. No --fix.
  • Every undo-history snapshot now records what made it: .capcut-cli-history/<draft>.journal.jsonl gets { index, time, command, argv, before_sha256, after_sha256 } per write (library callers record command: null), trimmed together with the snapshots. restore --list shows command, argv and time per step; older snapshots without a journal line list with nulls. A torn or unreadable journal never breaks a write or a restore.
  • Whisper-free caption routes are documented in docs/quickstart.zh-CN.md (不装 Whisper 的字幕路线) and examples/short-video-narration.md: the app's own auto captions followed by restyle / export-srt, import-srt, and caption --words.

Changed

  • doctor's Whisper hint names caption --words and import-srt as routes that work without Whisper. The check's status is unchanged.
  • lint --frame-grid --fix derives repaired source durations through the same helper as the new overlap repair: at speed 1 nothing changes; on clips at other speeds whose source duration matched target × speed (within 1%), the source duration now follows the snapped target duration instead of being left as it was.

This coordinated release comprises npm capcut-cli@0.29.0 and the Wasm component attached here with its checksum, license, and third-party notices. The Python client is unchanged (PyPI capcut==0.1.3).

Validation: 1,210 CLI tests pass with one platform-specific skip, and all 13 CI jobs pass. The packed tarball passes the release smoke test.

Merged in #142. All 13 checks pass on the tagged source: CI.

v0.28.0 — active timelines, app-created projects and client fixes

Choose a tag to compare

@renezander030 renezander030 released this 04 Oct 06:19
cb348ed

v0.28.0

Added

  • --active-timeline explicitly follows a validated Timelines/project.json pointer on app builds without a verified storage fixture (#50). Invalid, deleted, symlinked or conflicting selected timelines are refused; normal defaults and write guards remain unchanged. Writes keep root and active IDs and preserve other timelines.

  • compile --into <project> populates an existing empty project created in CapCut (#52). It preserves project identity, per-document app markers and unknown settings, stages content-correct media, and commits imported-media registration with timeline writes. Failed copies and commits clean up only newly owned assets; the shared store index is never rewritten. --check, --plan and --dry-run validate both spec and destination without writing. Nested layouts require active selection. Desktop acceptance on these opt-in paths remains unverified.

  • describe --compact emits a small command discovery index with names, summaries, usage, and write status. describe --command <name> returns complete contracts for selected commands; repeat the flag for several names. The full v2 command contract remains the default. Python client v0.1.3 forwards these options through capcut.describe(compact=True, command="compile").

Fixed

  • Python client v0.1.3 parses quoted Windows CAPCUT_CLI paths without retaining surrounding quotes or losing backslashes. Escaped quotes, trailing backslashes, and empty arguments follow Windows argv quoting; malformed quotes fail before spawning a process. POSIX command quoting and shell-free execution remain unchanged. Python client regression tests now run on Linux, macOS, and Windows, including Python 3.9 and 3.14.

This coordinated release comprises npm capcut-cli@0.28.0, PyPI capcut==0.1.3, and the Wasm component attached here with its checksum, license, and third-party notices.

Validation: 1,134 CLI tests pass with one platform-specific skip, 19 Python tests pass, and all 13 CI jobs pass. Packed npm installation, real FFmpeg compilation into an app-created shell, Python wheel integration, and twine check pass.

The new opt-in CapCut paths still require a desktop open/save/close/reopen acceptance check; issues #50 and #52 remain open.

Merged in #139. All 13 checks pass on the tagged source: CI.

v0.27.0

Choose a tag to compare

@renezander030 renezander030 released this 03 Oct 13:58
f85efa3

v0.27.0 — 2026-10-03

Added

  • relink --dir <folder> --recursive searches nested media folders. Duplicate basenames are reported in ambiguous and left unchanged; prefix remapping matches whole path components, and directory symlinks are not followed.

Fixed

  • replace-media stages the requested bytes even when a different file with the same basename already exists. Occupied hash filenames are checked by content; dry runs create no asset directories or files, and directories/non-media segments are rejected before mutation.
  • Replacement and relink refresh changed media's local_material_id links and imported-media entries when a readable draft_meta_info.json exists. Sidecar and timeline writes share conflict checks, backups, and rollback; existing and unrelated import entries are preserved. Bare timelines still use register --materials --apply to create registration metadata.
  • compile derives target durations from rounded start and end boundaries, keeping adjacent fractional-second clips contiguous across text, video, audio, photos, and timed operations.
  • Compile operation payloads are checked with the same builders used by real writes before creating output. Failed builds remove only the output directory created by that invocation; successful builds register in the project index after the draft is saved.
  • serve binds a job ID to its effective command payload and execution settings. Identical submissions still deduplicate; reusing an ID for a different job returns a failure without executing the conflicting job.
  • Queue project locks resolve project roots, relative paths, timeline files, and symlink aliases so concurrent writers to the same project serialize.
  • Queue input and limits reject malformed or non-finite values. Combined child output is checked again at exit before reading it, so a fast process cannot bypass the configured capture threshold. Overflow results omit captured output; the threshold is polled during execution and is not a hard disk quota.
  • import-timeline resolves relative media references against the OTIO document's directory and decodes local file: URLs, including escaped spaces. Remote URLs and inaccessible references remain placeholders.

Install: npm install -g capcut-cli@0.27.0

The optional capability-free WebAssembly component and its checksums and license notices are attached below. It provides read-only inspection, linting, and diff operations through a compatible host.

v0.26.1 — active timelines, compile fixes, and fixture redaction

Choose a tag to compare

@renezander030 renezander030 released this 03 Oct 12:12
44b35c4

Fixes

  • fixture redacts JSON-escaped Windows home paths, including embedded JSON, and automatically checks every generated bundle for recognizable residual private values. Failed checks return a nonzero exit status and are recorded in SANITIZE_REPORT.json (#134).
  • compile handles ratio-only and explicit-dimension canvases consistently. Material and sidecar durations use the full probed source duration; segments keep their requested lengths and source in-points. Invalid speed-adjusted source ranges are refused before creating a draft (#133).
  • On the fixture-backed CapCut 8.7.0 Windows layout, the CLI follows the validated active timeline pointer and synchronizes its readable mirrors and root copies while preserving document IDs and other timelines. Assets and metadata stay at the project root; sync-timelines repairs in the active → root direction (#50).

Install

npm install -g capcut-cli@0.26.1
capcut --version

Verification and compatibility

All 1,017 tests passed locally. CI passed on Node 18/20/22 and Windows/macOS/Linux, including the capability-free Wasm component. The packed npm release was installed separately and checked against the three fixes.

The active-timeline change is scoped to the evidenced Windows 8.7.0 layout. Other builds retain their existing behavior. A patched CapCut desktop open/close confirmation remains pending in #50; file-level tests do not establish desktop compatibility.

See the end-to-end verification guide and changelog.

v0.26.0

Choose a tag to compare

@renezander030 renezander030 released this 25 Sep 07:39
e98e3d8

Highlights

  • Frame-grid linting and repair with lint --frame-grid --fix.
  • Character-level Chinese/Japanese script alignment and a --min-script-match write gate.
  • Multi-stream transcription through caption --audio-stream.
  • Boundary-safe ripple removal and partial-timeline shifting.
  • Automatic FFmpeg filter scripts for large proxy renders.
  • Nested OTIO timeline import.
  • CRF or target-bitrate render controls.
  • Editable progressive captions with caption --word-reveal.
  • Atomic project-wide text styling with restyle --preset.

Also included: richer draft-store diagnostics in doctor, a complete narrated-short workflow, and the new dependency-free Python client.

Install

npm install -g capcut-cli@0.26.0
pip install capcut==0.1.1

See CHANGELOG.md for full behavior and compatibility details.