Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{
"name": "capcut-cli",
"source": "./",
"description": "Edit CapCut and JianYing projects from Claude Code — subtitles, timing, speed, volume, transitions, masks, templates, cut long-form to shorts."
"description": "Edit CapCut and JianYing (剪映) projects from Claude Code — subtitles and SRT/ASS import, timing, speed, volume, keyframes, masks, filters and effects, templates, lint --fix, render previews, and cutting long-form to shorts."
}
]
}
9 changes: 6 additions & 3 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "capcut-cli",
"version": "0.1.4",
"description": "Edit CapCut and JianYing projects from Claude Code — subtitles, timing, speed, volume, templates, cut long-form to shorts.",
"version": "0.2.0",
"description": "Edit CapCut and JianYing (剪映) projects from Claude Code — subtitles and SRT/ASS import, timing, speed, volume, keyframes, masks, filters and effects, templates, lint --fix, render previews, and cutting long-form to shorts.",
"author": {
"name": "René Zander",
"url": "https://github.com/renezander030"
Expand All @@ -18,7 +18,10 @@
"timeline",
"templates",
"shorts",
"automation"
"automation",
"剪映",
"agent-skill",
"claude-code-plugin"
],
"skills": "./skills/"
}
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,19 @@ All notable changes to capcut-cli are documented here. The format follows [Keep

## [Unreleased]

## [0.24.0] — 2026-09-18

### Added

- `lint` holds captions written in Chinese, Japanese or Korean to their own limits: 16 characters per line and 9 per second for Chinese, 13 and 4 for Japanese, 16 and 12 for Korean, in place of the Latin 42 and 20 that let a 32-character Chinese line pass. Messages name the applied default (`>16, zh default`), `--fix` re-wraps between characters, and an explicit `--max-chars` / `--max-cps` applies to every script. Library: `captionScript`, `captionLimits`, `scriptLimitsExcept`, `CJK_SCRIPT_LIMITS`, and `LintOptions.scriptLimits` (`null` keeps the Latin limits everywhere).
- `init`, `quickstart` and `compile` report what the drafts folder held when the skeleton was chosen (`template.store`: `projects`, `readable`, `markerless`, `encrypted`, `unreadable`). When every project is encrypted (JianYing 6.0+) and nothing could seed the draft, they say so — a WARNING on stderr, `template.warning` in the JSON, the quickstart `create` step and the compile `warnings` list — and name what is known about the bundled template on that app.
- `lint` reports `template-unverified-store` (info) for a bundled-template draft in a drafts folder whose projects are all encrypted: nothing could have seeded it and no version can be compared, so it is unverified for that app rather than stale.
- README (English and Chinese) documents the one-command agent install, `npx skills add renezander030/capcut-cli`, and the Claude Code plugin route. The `capcut-edit` skill also triggers on Chinese requests (剪映, 字幕, 草稿).

### Changed

- English and Chinese quickstarts now link to the maintainer's GitHub profile for more practical AI agent tools.
- Claude Code plugin manifest 0.2.0: description and keywords match the current command surface.

## [0.23.0] — 2026-09-11

Expand Down
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,23 @@ JSON in, JSON out: every command reads and writes the local draft store directly
- **Queue runner** — `capcut serve` reads JSONL jobs from stdin, for [n8n / Make / Coze](./examples/serve-automation.md)
- **Agent sandbox (experimental)** — build [`capcut-core.wasm`](https://github.com/renezander030/capcut-cli/tree/master/wasm/capcut-core) for three read-only MCP tools with zero filesystem, network, environment, clock, random, stdio, or process imports

### Give your agent the skill

One command installs the `capcut-edit` skill into Claude Code, Codex, Cursor, OpenCode and the other agents the [`skills`](https://skills.sh) installer supports:

```bash
npx skills add renezander030/capcut-cli
```

Claude Code can also load it as a plugin:

```
/plugin marketplace add renezander030/capcut-cli
/plugin install capcut-cli@capcut-cli
```

The skill teaches the agent every command, the progressive-disclosure habit (inspect first, never dump a whole draft), where the draft store lives on macOS and Windows, and the deterministic scripts for fades, Ken Burns and long-to-short cuts. It triggers on English and Chinese requests alike (剪映, 字幕, 草稿).

### Capability-free Wasm tools for agents

**Using an AI assistant with capcut-cli? Give it a safer “look, don’t touch” mode.**
Expand All @@ -86,7 +103,7 @@ The host reads a draft and passes its JSON as tool input. The component itself h

## Release notes

> **New in v0.22.0:** nine items mined from what users are hitting across this repo, its forks and the wider CapCut/JianYing tooling. `register --materials` writes the `draft_materials` registration CapCut 9.1 reads to decide what is imported — the fix for every clip showing as "file inaccessible" with a relink prompt ([pyCapCut#13](https://github.com/GuanYixuan/pyCapCut/issues/13)). `export-timeline --captions markers` carries caption cues into the NLE as OTIO timeline markers, and `import-timeline` rebuilds the text track from them (OTIO has no title schema — [OpenTimelineIO#62](https://github.com/AcademySoftwareFoundation/OpenTimelineIO/issues/62), open since 2017). `caption --script` keeps whisper's word timing but uses your script's wording. `detect-retakes` finds the sentence the speaker fluffed and said again, with the window / min-words / similarity guards that keep it from collapsing a timeline. Plus `render --soft-captions` (a toggleable mov_text stream), `matting` (smart background removal on a clip's material), `init --ratio 9:16` for portrait drafts, IR-style keyframe aliases (`scale`, `x`, `y`, `opacity`) and `--easing hold`. No command was removed and no existing output changed shape. Full details in the [changelog](./CHANGELOG.md).
> **New in v0.24.0:** captions in Chinese, Japanese and Korean are held to their own limits — `lint` flags a 32-character Chinese line and a 15 chars/s cue that the Latin defaults (42, 20) let through, and `--fix` re-wraps between characters (zh 16/9, ja 13/4, ko 16/12; an explicit `--max-chars` / `--max-cps` still applies everywhere). On a JianYing 6.0+ drafts folder, where every app-written project is encrypted, `init` / `quickstart` / `compile` now say that none could seed the new draft (`template.store`, a WARNING) and `lint` reports `template-unverified-store` instead of nothing. Plus a one-command agent install: `npx skills add renezander030/capcut-cli`. Full details in the [changelog](./CHANGELOG.md).

> **New in v0.23.0:** drafts that open on the CapCut you actually have. A draft built from the bundled 6.5.0 template is refused by CapCut 8.4+, 8.7 Windows and 9.3 as "from an unusual path" ([#67](https://github.com/renezander030/capcut-cli/issues/67), [#111](https://github.com/renezander030/capcut-cli/issues/111) — the real 8.7 Windows round-trip, negative with the bundled template and positive with one captured from the installed app). `init`, `quickstart` and `compile` now seed new drafts from the newest app-authored project in your drafts folder by default (its version markers and settings, none of its content, never its `Timelines/` mirrors); `migrate --from-store` restamps drafts built earlier, and `lint` reports the stale signature as `template-stale`. Media gets its `local_material_id` link to `draft_materials` at add time — the key JianYing 5.9+ and CapCut 9.3 resolve local clips by ([JmsLdrn/capcut-mcp#1](https://github.com/JmsLdrn/capcut-mcp/issues/1)) — and `lint --fix` writes it for existing drafts (`media-unlinked`). Plus `source-range-exceeds-material`, a `compile --check` that names flat `text-style` keys ([#110](https://github.com/renezander030/capcut-cli/issues/110)), the macOS permission hint on `media-outside-draft`, and `init` stamping both timeline mirrors so `register` accepts its own drafts. No command was removed and no existing output changed shape. Full details in the [changelog](./CHANGELOG.md).

Expand Down
19 changes: 18 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,26 @@ JSON 进、JSON 出:每个命令都直接读写本地草稿存储,不用 MCP
- **库(Library)** —— `import { loadDraft, lintDraft, saveDraft } from "capcut-cli"`(带类型、零依赖)
- **队列执行器** —— `capcut serve` 从 stdin 读取 JSONL 任务,对接 [n8n / Make / Coze](./examples/serve-automation.md)

### 把它装进你的 Agent

一条命令即可把 `capcut-edit` 技能装进 Claude Code、Codex、Cursor、OpenCode 以及 [`skills`](https://skills.sh) 安装器支持的其他 Agent:

```bash
npx skills add renezander030/capcut-cli
```

Claude Code 也可以把它作为插件加载:

```
/plugin marketplace add renezander030/capcut-cli
/plugin install capcut-cli@capcut-cli
```

这个技能会教 Agent 每条命令、渐进式读取的习惯(先看概要,绝不整份倒出草稿)、macOS 与 Windows 上草稿目录的位置,以及淡入淡出、Ken Burns、长视频切短的确定性脚本。中英文请求都能触发(剪映、字幕、草稿)。

## 发布说明

> **v0.22.0 新增:** 九项来自本仓库、其分支及更广泛 CapCut/剪映工具生态中真实用户痛点的功能。`register --materials` 会写入 CapCut 9.1 用来判断素材是否已导入的 `draft_materials` 登记——修复所有片段显示为"文件无法访问"并要求重新链接的问题([pyCapCut#13](https://github.com/GuanYixuan/pyCapCut/issues/13))。`export-timeline --captions markers` 把字幕作为 OTIO 时间线标记带进 NLE,`import-timeline` 再由这些标记重建文本轨道(OTIO 没有字幕/标题 schema——[OpenTimelineIO#62](https://github.com/AcademySoftwareFoundation/OpenTimelineIO/issues/62),自 2017 年悬而未决)。`caption --script` 保留 whisper 的逐词时间,但采用你的脚本文字。`detect-retakes` 找出说错后重说的句子,并以窗口、最少词数、相似度三道守卫防止误剪整条时间线。另有 `render --soft-captions`(可开关的 mov_text 字幕流)、`matting`(对片段素材开启智能抠像)、`init --ratio 9:16`(竖版草稿)、IR 风格的关键帧属性别名(`scale`、`x`、`y`、`opacity`)与 `--easing hold`。没有删除任何命令,现有输出结构均未改变。详见[更新日志](./CHANGELOG.md)。
> **v0.24.0 新增:** 中文、日文、韩文字幕按各自的规范检查 —— `lint` 会指出 32 字的中文单行和每秒 15 字的字幕(拉丁默认的 42 字 / 每秒 20 字会放过它们),`--fix` 按字重新折行(zh 16/9、ja 13/4、ko 16/12;显式传入 `--max-chars` / `--max-cps` 仍对所有文字生效)。在剪映 6.0+ 的草稿目录里(应用写出的项目全部加密),`init` / `quickstart` / `compile` 现在会明确说明没有任何项目可作为种子(`template.store` 与 WARNING),`lint` 会报告 `template-unverified-store` 而不是沉默。另外,一条命令即可把它装进 Agent:`npx skills add renezander030/capcut-cli`。完整说明见[更新日志](./CHANGELOG.md)。

> **v0.23.0 新增:** 生成的草稿能在你实际安装的 CapCut 里打开。用内置 6.5.0 模板生成的草稿会被 CapCut 8.4+、8.7 Windows 和 9.3 以"项目来自异常路径"拒绝([#67](https://github.com/renezander030/capcut-cli/issues/67)、[#111](https://github.com/renezander030/capcut-cli/issues/111)——这是等待已久的 8.7 Windows 真机验证:内置模板失败,从已安装应用捕获的模板成功)。`init`、`quickstart` 与 `compile` 现在默认以草稿目录中最新的应用生成项目为种子(保留其版本标记与设置,不带任何内容,绝不复制其 `Timelines/` 镜像);`migrate --from-store` 为旧版本生成的草稿重新盖上标记,`lint` 以 `template-stale` 报告过期签名。素材在添加时即写入 `draft_materials` 并回填 `local_material_id`——剪映 5.9+ 与 CapCut 9.3 正是靠这个键定位本地素材([JmsLdrn/capcut-mcp#1](https://github.com/JmsLdrn/capcut-mcp/issues/1)),已有草稿可用 `lint --fix` 补链(`media-unlinked`)。另有 `source-range-exceeds-material` 检查、能指出扁平 `text-style` 键的 `compile --check`([#110](https://github.com/renezander030/capcut-cli/issues/110))、`media-outside-draft` 的 macOS 权限提示,以及 `init` 同时盖章两份时间线镜像,使 `register` 接受自己生成的草稿。没有删除任何命令,现有输出结构均未改变。详见[更新日志](./CHANGELOG.md)。

Expand Down
6 changes: 3 additions & 3 deletions docs/command-reference.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "capcut-cli",
"version": "0.23.0",
"version": "0.24.0",
"schema_version": 2,
"description": "Edit CapCut/JianYing draft_content.json directly. JSON in, JSON out.",
"global_flags": [
Expand Down Expand Up @@ -134,7 +134,7 @@
],
"type": "number",
"required": false,
"description": "Maximum caption characters per line.",
"description": "Maximum caption characters per line. Unset, CJK captions use their own defaults: 16 (zh), 13 (ja), 16 (ko).",
"default": 42
},
{
Expand Down Expand Up @@ -164,7 +164,7 @@
],
"type": "number",
"required": false,
"description": "Maximum caption reading speed in characters per second (0 disables).",
"description": "Maximum caption reading speed in characters per second (0 disables). Unset, CJK captions use 9 (zh), 4 (ja), 12 (ko).",
"default": 20
},
{
Expand Down
5 changes: 5 additions & 0 deletions docs/jianying-encryption.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,8 @@ Revisit only if **all** of these hold:
decryptor that silently breaks is worse than an honest "not supported."

Until then: detect, explain, and collect fixtures. Do not decrypt.

## What the CLI says on such a store (0.24.0)

- `init`, `quickstart` and `compile` count the folder's projects in `template.store` (`encrypted` is the JianYing 6.0+ payloads). When none could seed the new draft, a WARNING names the fallback to the bundled template and `template.warning` carries the same text.
- `lint` reports `template-unverified-store` (info) for such a draft: not stale, since there is no readable version to compare against, but unverified for the app that wrote those projects. Opening the draft in JianYing is the test; 11.4 (macOS) is reported to open and upgrade it in place.
5 changes: 5 additions & 0 deletions docs/jianying-encryption.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,8 @@
3. 有维护者愿意承诺持续跟踪剪映的版本更新 —— 因为一个悄悄失效的解密器,比诚实地说「不支持」更糟糕。

在那之前:只检测、说明情况、收集 fixture。不解密。

## 在这样的草稿目录里,CLI 会告诉你什么(0.24.0)

- `init`、`quickstart` 与 `compile` 会在 `template.store` 里统计目录中的项目(`encrypted` 即剪映 6.0+ 的加密文件)。当没有任何项目可作为新草稿的种子时,会用 WARNING 说明已回退到内置模板,`template.warning` 携带同样的文字。
- `lint` 会对这样的草稿报告 `template-unverified-store`(info):它不算"过期"(没有可读的版本可比较),但对写出这些项目的应用来说尚未验证。在剪映里打开草稿才是真正的检验;据报告 11.4(macOS)能打开并就地升级。
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "capcut-cli",
"version": "0.23.0",
"version": "0.24.0",
"description": "Independent, unofficial CLI to create and edit CapCut projects — build drafts from scratch, add video/audio/text, subtitles, timing, speed, volume, templates, cut long-form to shorts. No API needed. Not affiliated with ByteDance.",
"type": "module",
"bin": {
Expand Down
2 changes: 1 addition & 1 deletion skills/capcut-edit/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: capcut-edit
description: Edit CapCut / JianYing video projects — read and write subtitles, timing, speed, volume, templates, animations (fade/ken-burns), and cut long-form to shorts. Use when the user mentions capcut, jianying, subtitles, video editing, draft_content.json, draft_info.json, or cutting videos.
description: Edit CapCut / JianYing video projects — read and write subtitles, timing, speed, volume, templates, animations (fade/ken-burns), and cut long-form to shorts. Use when the user mentions capcut, jianying, subtitles, video editing, draft_content.json, draft_info.json, or cutting videos — in English or Chinese (剪映, 字幕, 草稿, 剪辑, 切片, 视频编辑).
---

# capcut-edit
Expand Down
18 changes: 14 additions & 4 deletions src/command-specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,22 @@ export function commandNames(): CommandName[] {

const optionsByCommand: Record<string, OptionSpec[]> = {
lint: [
option("max_chars", ["--max-chars"], "number", "Maximum caption characters per line.", { default: 42 }),
option(
"max_chars",
["--max-chars"],
"number",
"Maximum caption characters per line. Unset, CJK captions use their own defaults: 16 (zh), 13 (ja), 16 (ko).",
{ default: 42 },
),
option("max_cue_secs", ["--max-cue-secs"], "number", "Maximum caption duration in seconds.", { default: 7 }),
option("min_gap_ms", ["--min-gap-ms"], "number", "Minimum caption gap in milliseconds.", { default: 0 }),
option("max_cps", ["--max-cps"], "number", "Maximum caption reading speed in characters per second (0 disables).", {
default: 20,
}),
option(
"max_cps",
["--max-cps"],
"number",
"Maximum caption reading speed in characters per second (0 disables). Unset, CJK captions use 9 (zh), 4 (ja), 12 (ko).",
{ default: 20 },
),
option("safe_area", ["--safe-area"], "number", "Vertical safe-area fraction for captions (0 disables).", {
default: 0.85,
}),
Expand Down
1 change: 1 addition & 0 deletions src/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ export function compileDraft(spec: CompileSpec, opts: CompileOptions): CompileRe
seed: opts.seed,
});
const { filePath } = init;
if (init.template.warning) warnings.push(init.template.warning);
const { draft } = loadDraft(filePath);

// Canvas + fps from the spec.
Expand Down
Loading
Loading