@gitruck/cli 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # 更新日志
2
2
 
3
+ ## 1.2.4(2026-09-14)
4
+
5
+ ### `gtrk mg` 文字模板三口:`fetch --source text` / `compile` / `edit`(add-text-template-source)
6
+
7
+ 同合云自己 clean-room 重写的文字特效模板库进了 CLI。与中性块 `registry` 那条路**刻意不同**:
8
+ 文字模板 MUST NOT 走机械改写——中性块来自第三方、要替字体换色板才合规;文字模板的块**自带 IR**,
9
+ 一旦直接改 HTML 字节,它就从 `ir` 态掉成 `detached`,云端再也调不动。改内容只有两条路:
10
+
11
+ ```bash
12
+ gtrk mg fetch --source text 打字机 # 候选态:只列不取(--offline 用本地目录)
13
+ gtrk mg fetch --source text --pick tfx-title-typeline # 取块态:三源择优取,逐字节校 sha256
14
+ gtrk mg compile ./mg-fetch/tfx-title-typeline.ir.json # 改完 IR 重编译(L0,本地跑、0 积分、零请求)
15
+ gtrk mg edit ./mg-fetch/xxx.html --say "打字机快一倍,副标改成青色" --n 3 # 云端改写(2 积分/候选)
16
+ ```
17
+
18
+ `--n` 只收 1 或 3,**它就是计费单位数**。改写被拒绝(模型说「词表里做不到」)同样计费——
19
+ 那是为了不让「拒绝」变成免费试探,但拒绝理由会原文给你,不会只丢一句失败。
20
+
21
+ ### 文字模板目录:随包兜底 + 远端择新 + 8 个人话分类(add-text-template-source / add-text-template-category)
22
+
23
+ 目录走「远端择新、随包兜底」:扩批是纯写 IR 的轮次,不该被 CLI 发版卡住,所以**随包那份会过期,
24
+ 这是设计**——运行时按 `version` 择新,随包只在三源都不可达时顶上。本版随包 **v2026-09-14.11 / 103 件**。
25
+
26
+ 分类从 37 个收成 8 个:`F`/`M`/`R` 是内部来源编号(喵影家族 / MAD 图鉴技法号 / 参考视频),
27
+ 用户看不懂,而且 93 件摊出 37 个分类里有 16 个只有 1 件。改由**目录下发** `category`
28
+ (快照脚本算,两端只读不算——各算一份会漂且漂了不报错),判据是规则不是手工名单:
29
+ 满 7 件才配独立、其余进「其他」、总数 ≤8。`family` 保留供溯源、仍进检索干草堆
30
+ (老用户按 F02 搜不该搜不到)。
31
+
32
+ ### IR 编译默认走本地,`--remote` 留给排查与对拍(move-text-ir-compiler-to-client)
33
+
34
+ `gtrk mg compile` 此前每次都要打一趟服务端。现在 L0 编译在本地跑完:**零请求、零延迟、断网可用**。
35
+ TS 编译器是 Python 正本的第二实现,靠一道**逐字节等价闸**钉住(全量金样两侧逐字节相同,
36
+ 本版 103/103)。
37
+
38
+ ⚠️ `--remote` **MUST NOT 下线**:它是等价闸的参照系,也是真机上排查「本地编出来的和服务端一样吗」
39
+ 时手上唯一的另一条路。
40
+
41
+ ### IR 词表 v0.2:八项新表达 + 片段引用槽位(add-text-ir-vocabulary-v02)
42
+
43
+ `mask` 收数组(多条并存)/ `feather` 收两元数组(不等量羽化)/ `animTarget:"inner"`(蒙版钉死、
44
+ 内容在后面滚)/ `repeatText` / `charRoll`(逐字滚码落定)/ `sweep`(扫光)/ `shape.glow` /
45
+ `anim` 新增 `skx`·`sky`,外加 **`runs[].slot`**。
46
+
47
+ `runs[].slot` 修的是一个缺口:`brush-title` / `caption-emoji-arrow` / `caption-keyword` 三颗的文字
48
+ 写在 `runs[].t` 字面量里,**此前没有任何字段能改**。现在它们的槽位回来了。
49
+
50
+ ⚠️ **`blur` 通道判否,且这是有射程的口径**:`filter: blur()` 被补间驱动正是 `gtrk mg lint` 的
51
+ `c-filter-animated` 所指、r69 真渲实测 **+36.2%** 的最贵形态。往后任何要 `filter` 的通道
52
+ (`drop-shadow` / `saturate` …)一律先找零卷积等价物,真找不到再单独拍板。
53
+
54
+ ### `gtrk tool mad`:技法点名 `--technique` 与目录检索 `--search`
55
+
56
+ 一键剪 MAD 此前只能让它自己挑技法。现在可以点名,也可以先查目录看有哪些
57
+ (语义匹配仍留给 Agent,命令面只做目录检索)。
58
+
59
+ ### 其他
60
+
61
+ - `gtrk mg lint`:内嵌 IR 的**两代载体都认**——换载体那次产物字节全变,只认新的会把线上已发的颗粒
62
+ 整批判成 `detached`。
63
+
64
+ ## 1.2.3(2026-09-13)
65
+
66
+ > ℹ️ **本节是补写的**。1.2.3 当时发到了 npm 却没进更新日志(包里那份 CHANGELOG 顶到 1.2.2 为止)。
67
+ > 补写口径是**发布产物实证**、不是按提交时间猜:拉 `@gitruck/cli@1.2.3` 的 tarball 逐项 grep,
68
+ > 确认 `text-template` / `compileIrBody` / `--technique` **一个都不在**(同时 `pip` 42 处、
69
+ > `subtitle_line_split` 3 处命中,证明探针本身能响)——文字模板那批全部落在 1.2.4。
70
+
71
+ ### `gtrk mg lint`:新增非致命哨兵 `x-soft-alpha`(fix-alpha-delivery-discipline)
72
+
73
+ 颗粒里只要有**半透明面积**(`rgba`/`hsla` 半透明色、`#RRGGBBAA`、渐变到 `transparent`、
74
+ 带 blur 的 `text-shadow`/`box-shadow`、静态 `opacity<1`),lint 会提醒一句。
75
+
76
+ **恒非致命、不要求改写**——半透明本身完全合法。它提醒的是交付纪律:剪映的 qtrle 交付依赖渲染管线
77
+ 在编码前**预乘 alpha**(剪映按预乘合成,直通 alpha 的软边会塌成实心,2026-09-14 真机实证)。
78
+ 所以**剪映路径的真机验收 MUST 用这颗颗粒本身验,MUST NOT 拿实心颗粒代验**——实心颗粒对预乘错配
79
+ 结构性失明,验了也是白验。
80
+
81
+ ⚠️ 颗粒与 CLI **MUST NOT 自行预乘**,那会双重压暗。预乘是渲染管线那一侧的事。
82
+
83
+ 哨兵刻意**不认** GSAP 补间参数里的 `opacity:0`:淡入淡出的端点是 0/1,不是驻留的半透明面积。
84
+
85
+ 契约 `gsap-emit-v1.md` 同批增补「Alpha 交付口径」一节,`gtrk-mg` 图纸补剪映预乘纪律。
86
+
3
87
  ## 1.2.2(2026-09-13)
4
88
 
5
89
  ### `gtrk subtitle lay` 云端拆行:`subtitle_type` 直传预设 id,PascalCase 映射表删除(link-subtitle-lay-cloud-line-split §6.2)
package/README.en.md CHANGED
@@ -36,10 +36,10 @@
36
36
  | 📦 | `gtrk deps` | Runtime assets: `status` shows where ffmpeg/fonts come from and under which licence, `install` fetches them from the Gitruck Cloud mirror (**must be triggered explicitly — never a silent auto-download**) |
37
37
  | 🤖 | `gtrk skills install` | Installs the 18 bundled CLI skills into the agents detected on this machine, via the generic `skills` adapter plus a gtrk supplement layer; `--all` covers every registered host; `gtrk skills recommend --scene <id>` browses the bundled third-party skill catalog (snapshot, offline, recommend-only) and `gtrk skills add <owner/repo>` installs through the adapter and registers the skill in the show config `style.skills` |
38
38
  | ⬆️ | `gtrk upgrade` | Upgrade the CLI to the latest version + refresh skills (config preserved); `--check` only reports |
39
- | 🎞️ | `gtrk render` | Render a gtrk project (EDL) locally → finished mp4 (requires ffmpeg); composites **every visible overlay layer** in contract z-order (B-roll and other overlay video tracks + MG particles; `hidden` tracks stay out); output frames are allocated against the **cumulative** timeline (per-clip rounding never accumulates, so the picture cannot drift away from the voiceover); runs a QC pass afterwards and writes `.qc.json` (`--no-qc` skips it); picture-in-picture clips get their `clip_transform` (scale / position / rotation / opacity), `border_radius` corners and `clip_mask` shape masks (ellipse / rounded rectangle / heart / diamond / star, feathered) composited locally, visually matching the client preview. ⚠️ MG particles that miss the cache are cloud-rendered and **billed** (estimate + confirmation first; `--no-particles` renders particle-free at zero cost) |
39
+ | 🎞️ | `gtrk render` | Render a gtrk project (EDL) locally → finished mp4 (requires ffmpeg); composites **every visible overlay layer** in contract z-order (B-roll and other overlay video tracks + MG particles; `hidden` tracks stay out); output frames are allocated against the **cumulative** timeline (per-clip rounding never accumulates, so the picture cannot drift away from the voiceover); runs a QC pass afterwards and writes `.qc.json` (`--no-qc` skips it); picture-in-picture clips get their `clip_transform` (scale / position / rotation / opacity), `border_radius` corners and `clip_mask` shape masks (ellipse / rounded rectangle / heart / diamond / star, feathered) composited locally, visually matching the client preview. ⚠️ MG particles that miss the cache are cloud-rendered and **billed** (estimate + confirmation first; `--no-particles` renders particle-free at zero cost) |
40
40
  | 🔬 | `gtrk qc <cut>` | Final-cut QC: one decoding pass over the whole file for flash frames, black/frozen frames, clipping, silence and audio/video drift, each with a timecode; `--gtrk <project>` enables project-aware detection of **intra-clip cuts**, `--fail-on error\|warn\|never` gates pipelines via the exit code |
41
41
  | 🔎 | `gtrk matrix` | B-roll retrieval + **candidate track laying**: consumes the FILM_BROLL dispatch → produces a candidate list + downloads preview proxies and lays N candidate tracks (`--lay N`, default 1; open it in opencut and toggle track visibility to compare; `--lay 0` produces the list only); `matrix search "<query>"` is a one-off ad-hoc search; `matrix fetch <clip_id...>` pulls raw footage during the fine cut (free re-signing + download for already-granted materials, drag straight into Jianying); **local-footage mode**: `matrix index --dirs <folders>` builds a slice-free index → `--local --dirs` retrieves and lays tracks (**your footage never leaves your machine**) → `matrix lay` consumes the (editable) plan; `matrix describe` understands candidates on demand |
42
- | 🎨 | `gtrk mg` | MG motion-graphics particle laying: consumes the MG dispatch → lays html-particle assets (transparent overlay / full-screen bed, produced by your show's MG skill) into the `.gtrk` `beat_track`; `mg lint <particle.html>` runs the statically checkable subset of the house rules, `mg status --project <dir>` is an orchestration dashboard; `mg render <particle.html> --duration <sec>` renders a single particle in the cloud, independent of any project, into a Jianying-readable qtrle transparent MOV (the fine-cut supplement channel); aux overlay particles can be layered on the same span (one beat derives a main particle plus `-aux<n>`). The old name `gtrk rrv` remains as a deprecated alias; `gtrk mg fetch` pulls neutral block skeletons from the HyperFrames registry (offline snapshot candidates, three-source fetch with our mirror first, mechanical rewrite then lint) |
42
+ | 🎨 | `gtrk mg` | MG motion-graphics particle laying: consumes the MG dispatch → lays html-particle assets (transparent overlay / full-screen bed, produced by your show's MG skill) into the `.gtrk` `beat_track`; `mg lint <particle.html>` runs the statically checkable subset of the house rules, `mg status --project <dir>` is an orchestration dashboard; `mg render <particle.html> --duration <sec>` renders a single particle in the cloud, independent of any project, into a Jianying-readable qtrle transparent MOV (the fine-cut supplement channel); aux overlay particles can be layered on the same span (one beat derives a main particle plus `-aux<n>`). The old name `gtrk rrv` remains as a deprecated alias; `gtrk mg fetch` pulls neutral block skeletons from the HyperFrames registry (offline snapshot candidates, three-source fetch with our mirror first, mechanical rewrite then lint); `gtrk mg fetch --source text` pulls Tonghe's own text-effect templates (finished, no mechanical rewrite), paired with `gtrk mg compile` (edit the IR and recompile, 0 credits) and `gtrk mg edit --say` (natural-language rewrite, billed per candidate) |
43
43
  | 🎙️ | `gtrk project init` | Audio-first project bootstrap: build a `.gtrk` project from a voice-over — main path `--tts-task <task_id>` references a completed TTS task (fetches the audio plus sentence timecodes directly, zero ASR); fallback path `--audio`+`--transcript` takes your own voice-over as a pair. Once landed, `gtrk split --project` continues the production pipeline as usual |
44
44
  | 🎼 | `gtrk audio lay` / `tighten` | Audio-track atoms: `lay` appends an audio track to a `.gtrk` project (BGM/score; idempotent same-source replacement, no track pile-up); `--beat-align` runs cloud analysis and **pins the BGM’s emotional peak onto the cut’s climax**, tiling outward on bar lines and tiling **not at all** when both sides are already long enough (billed once; the climax comes from the `split.beats` criterion chain and can be overridden with `--climax <track-sec>`; `--no-loop` lays only the anchored span and leaves head/tail silence; without a key / on failure / when the track has no highlight it degrades to no anchoring and the command still succeeds). `tighten` tightens the pauses between sentences in the voice-over (purely local, zero billing; only silence straddling a sentence boundary is compressed, within-sentence breaths untouched) |
45
45
  | 🎯 | `gtrk audio align` | Audio-video alignment part (fully local, zero billing): cross-correlates an external audio recording (lav mic / recorder) against the video to measure offset + confidence; high confidence swaps the track directly (video stream untouched byte-for-byte), low confidence emits an alignment project for the client timeline, then `--resume` reads the confirmed offset back; `--offset` swaps at an explicit offset |
@@ -148,7 +148,7 @@ Chain names above: *口播链* = talking-head (you shot yourself: short-form mon
148
148
  | ③ | "**lay the B-roll base**" (two legs, one stage) | `/gtrk-matrix` → `gtrk matrix` → film/local-footage candidate tracks laid; `/gtrk-ai-drama` (skill, no command) → four-part description docs (Chinese/English blocks) | **pick/adjust B-roll in opencut** (toggle track visibility to compare); generate AI clips on an external platform and **drop them back in by hand** |
149
149
  | ④ | "B-roll is settled, **check the composition**" | samples frames from the **merged three-source base layer** (an agent discipline, no dedicated command) | **confirm the composition** (subject position / safe areas / facing / brightness) |
150
150
  | ⑤ | "composition looks good, **lay the MG**" | `/gtrk-mg` → `gtrk mg` → MG (incl. ov) stacked on the settled base layer | fine-tune particles (by hand in opencut) |
151
- | ⑥ | "**produce the final cut**" | either path works: the desktop client's production chain (multi-lane compositing + cloud particle rendering / **Jianying export**), or `gtrk render` (composites every visible overlay locally into mp4; billed when particles miss the cache); both share one particle cache | final polish inside the client |
151
+ | ⑥ | "**produce the final cut**" | either path works: the desktop client's production chain (multi-lane compositing + cloud particle rendering / **Jianying export**), or `gtrk render` (composites every visible overlay locally into mp4; billed when particles miss the cache); both share one particle cache | final polish inside the client |
152
152
 
153
153
  > The order exists for a reason: **AI scene clips belong to the base-layer B-roll family, not to an overlay layer** — the only overlay layer in the pipeline is MG (incl. ov). MG placement shapes itself around the picture and **depends on the final composition of the base layer**, so all three sources (film / local / AI) must land and the composition must be checked before MG goes on. Skip lanes you do not need (an empty queue in `dispatch` simply lays nothing).
154
154
  >
@@ -196,11 +196,11 @@ CLI 写 .gtrk ─▶ 客户端打开(自动感知外部改动、先存脏改再
196
196
  | **Re-inserting AI re-enactment** | AI clips generated on external platforms are **dragged into the AI_DRAMA lane by hand** and aligned to their spans (`/gtrk-ai-drama` only emits description docs; the footage is produced externally — see SOP ③: it belongs to the base-layer stage, and MG waits until it has landed) |
197
197
  | **Final production** | Multi-lane compositing (overlay / MG / cloud-rendered particles stacked) plus Jianying draft export both live in the client's production chain |
198
198
 
199
- > **`gtrk render` now composites overlays (since 1.1.10).** It stacks **every visible** overlay layer in contract z-order (ascending `track_index`) — overlay video tracks (B-roll candidates, AI re-enactment) and MG particles alike. Tracks you hid in the client (`hidden`) stay out of the cut.
200
- >
201
- > **The particle half is billed**: the CLI has no HTML render engine, so particles are baked into transparent MOVs in the cloud and composited locally. Metering = **unique particles × cache misses** (by the minute); on a miss you get an estimate and a confirmation prompt first (`--yes` skips it; under `--json` an explicit `--yes` is required). **A second render hits the cache entirely ⇒ zero billing**; the cache shares the same key and location as the client's Jianying export (`<project dir>/.tonghe-cache/particles/`), so particles baked by either side are reused by the other. To avoid spending, `--no-particles` renders without particles (overlay video tracks are still composited — that part is local and free).
202
- >
203
- > **Jianying draft export still lives in the client's production chain** (`gtrk render` only emits mp4).
199
+ > **`gtrk render` now composites overlays (since 1.1.10).** It stacks **every visible** overlay layer in contract z-order (ascending `track_index`) — overlay video tracks (B-roll candidates, AI re-enactment) and MG particles alike. Tracks you hid in the client (`hidden`) stay out of the cut.
200
+ >
201
+ > **The particle half is billed**: the CLI has no HTML render engine, so particles are baked into transparent MOVs in the cloud and composited locally. Metering = **unique particles × cache misses** (by the minute); on a miss you get an estimate and a confirmation prompt first (`--yes` skips it; under `--json` an explicit `--yes` is required). **A second render hits the cache entirely ⇒ zero billing**; the cache shares the same key and location as the client's Jianying export (`<project dir>/.tonghe-cache/particles/`), so particles baked by either side are reused by the other. To avoid spending, `--no-particles` renders without particles (overlay video tracks are still composited — that part is local and free).
202
+ >
203
+ > **Jianying draft export still lives in the client's production chain** (`gtrk render` only emits mp4).
204
204
 
205
205
  ## Upgrading
206
206
 
@@ -275,7 +275,7 @@ Then just say "**cut a version of this talking-head**", or explicitly pick `gtrk
275
275
  | ⑤ | `/gtrk-mg` | `gtrk mg` | **MG (incl. ov) goes on last** (stacked on the settled, composition-checked base layer) |
276
276
  | — | `/gtrk-style-maker` | (no command, builds a show) | A one-time interview that builds your show's style system (skill family + show config, see next section) |
277
277
  | ③′ | "**screen-recording PiP**" | `gtrk pip lay` | Mirror the talking-head rough cut's cut points onto a screen recording / second camera recorded in sync: lays a full-frame companion track + a muted picture-in-picture copy of the talking head (ellipse / rounded rectangle / heart / diamond / star mask, optional corner radius); purely local, zero billing; when alignment confidence is low it writes an alignment project for the client to drag into place, then `--resume` |
278
- | — | (wrap-up) | `gtrk render` | Render a gtrk project locally → finished mp4 (overlays and MG particles included; particles that miss the cache are cloud-rendered and billed, `--no-particles` skips them) |
278
+ | — | (wrap-up) | `gtrk render` | Render a gtrk project locally → finished mp4 (overlays and MG particles included; particles that miss the cache are cloud-rendered and billed, `--no-particles` skips them) |
279
279
  | ✂️ | `/gtrk-long2short` | `gtrk long2short` | Long-to-short rough cut: semantic segment selection + jump cuts → per-clip client/Jianying/Premiere projects (the raw file is never uploaded); **not part of the production SOP**, usable standalone at any time |
280
280
  | 📝 | `/gtrk-transcript` | `gtrk transcript` | Local video / voice-over audio → one Markdown file with an agent-written summary, timecoded record and plain text; **not part of the production SOP** |
281
281
  | 🧰 | `/gtrk-tools` | `gtrk tool <name>` | The single-shot tool family (image-to-camera-move / image & video matting …) — single request, single result, **not part of the production SOP**, usable standalone at any time |
@@ -346,24 +346,24 @@ Run `gtrk doctor` any time for a self-check:
346
346
  ✅ 剪映草稿目录:C:\Users\…\com.lveditor.draft
347
347
  ```
348
348
 
349
- ### Enum catalog (`--refresh-catalog`)
350
-
351
- `gtrk doctor` shows an “enum catalog” row: the CLI fetches the **complete set of public enum values**
352
- from the server (subtitle styles and colours, language codes, project formats, rhythm presets,
353
- task availability, …), stores it at `~/.gitruck/catalog.json`, and refreshes it every 24 hours.
354
-
355
- With it, a bad `--subtitle-type` is rejected **before the upload starts**, with the currently valid
356
- values listed. When the server adds a new style, you get it without upgrading the CLI.
357
-
358
- ```bash
359
- gtrk doctor --refresh-catalog # refetch now, ignoring the 24h freshness window
360
- ```
361
-
362
- **Failing to fetch it never blocks you**: the CLI falls back to the last snapshot; with no snapshot at
363
- all it **skips local validation and submits anyway**, letting the server decide — the server-side
364
- whitelist is always the single source of truth. Set `GITRUCK_CATALOG_OFFLINE=1` to disable the fetch
365
- entirely.
366
-
349
+ ### Enum catalog (`--refresh-catalog`)
350
+
351
+ `gtrk doctor` shows an “enum catalog” row: the CLI fetches the **complete set of public enum values**
352
+ from the server (subtitle styles and colours, language codes, project formats, rhythm presets,
353
+ task availability, …), stores it at `~/.gitruck/catalog.json`, and refreshes it every 24 hours.
354
+
355
+ With it, a bad `--subtitle-type` is rejected **before the upload starts**, with the currently valid
356
+ values listed. When the server adds a new style, you get it without upgrading the CLI.
357
+
358
+ ```bash
359
+ gtrk doctor --refresh-catalog # refetch now, ignoring the 24h freshness window
360
+ ```
361
+
362
+ **Failing to fetch it never blocks you**: the CLI falls back to the last snapshot; with no snapshot at
363
+ all it **skips local validation and submits anyway**, letting the server decide — the server-side
364
+ whitelist is always the single source of truth. Set `GITRUCK_CATALOG_OFFLINE=1` to disable the fetch
365
+ entirely.
366
+
367
367
  ### Crash reports, and how to turn them off
368
368
 
369
369
  When gtrk crashes (uncaught exception / unhandled promise rejection / a program defect reaching the top-level exit) it automatically sends one report so we can locate the defect. **On by default; you are told once, when you first configure the CLI.**
@@ -606,7 +606,7 @@ Consumes the `dispatch.mg` dispatch landed by `gtrk split`, laying html-particle
606
606
  - **House rule ⑧, repeated-primitive merging** (`8-primitive-merge`, **always non-fatal, never blocks laying**): identifies mergeable batches of `line` / `rect` / `path` / `polyline` / `polygon` that are "created inside a loop, or by a named factory called in a loop; landing under the same parent node; and not driven by per-element animation". Only batches whose purely numeric loop trip counts sum to **≥ 8** under the same parent are reported; when bounds involve `.length` or named constants and cannot be computed it still reports "count unknown" without constant folding; elements with per-element `gsap.set` / tweens, or used as a tween's first argument, are excluded. This item only points out "there is a batch of repeated primitives here that can be merged **losslessly**, pixel-identical after merging" — it is **not a risk verdict**: a hit does not mean the particle will reproduce a defect, and a miss does not mean it is safe. The real criterion remains sampling frames from a real render.
607
607
  - **Callback and seek semantics** (`x-callback-driven` / `x-engine-api-override` / `x-raf-interval`, **always non-fatal, never blocks laying**): aligned with the same-named section of the contract (added 2026-07-26). GSAP `seek(t)` suppresses callbacks by default → tweened properties still interpolate, but DOM writes inside `onUpdate` do not run, and the failure mode is **the picture freezing at its initial state rather than going black**. The contract places the guarantee on the **engine side** (fixing a frame MUST use `seek(t,false)` / `time(t)` / `progress(p)`), so a particle **driving its picture from callbacks is a compliant style**; these three lint items are merely **sentinels**: `x-callback-driven` = callbacks write the DOM with no seek fallback anywhere (it stays silent when a fallback exists, to avoid nagging); `x-engine-api-override` = the particle overrides `tl.seek` at runtime or replaces `__timelines[…]` with a wrapper object (which would override the engine's explicit `seek(t,true)` and stops working the moment the engine switches to `time()`/`progress()`; a transitional state); `x-raf-interval` = it contains `requestAnimationFrame(` / `setInterval(` (its own clock is not driven by seek, i.e. frozen). All three MUST NOT be fatal — "driving the picture from callbacks" is not a violation.
608
608
  - **status** (`gtrk mg status --project <dir>`): summarizes the MG pipeline — total beats in `dispatch.mg` / how many source HTML files exist / how many are laid into `.gtrk`, annotating each beat (missing HTML / produced but not laid / laid).
609
- - **render** (`gtrk mg render <particle.html> --duration <sec> [--out <dir>] [--yes]`): renders a single particle in the cloud, **independent of any project**, into a Jianying-readable qtrle transparent alpha MOV (the fine-cut supplement channel — when the rough cut is already exported to Jianying and one more motion graphic is needed, you can add it without going back to the client app). The chain = lint upfront (envelope = `--duration`; any fatal item is blocked locally, zero submission, zero billing) → **billing-estimate confirmation** (live price lookup; the CLI has no local HTML render engine, so the cloud billed task is the only path for standalone particles; `--yes` skips the prompt) → inline submission to the cloud → `<composition_id>.mov` landed with `task.json`/`result.json` breadcrumbs (recoverable by task_id after a crash). **Scope**: qtrle only for now (`--format webm` is explicitly refused — Jianying cannot read VP8-alpha), 1920×1080 particles only (the contract has no portrait/odd-canvas opening), and `--duration` is required. The output never enters `.gtrk` and never lands in the Jianying draft folder; qtrle is lossless and relatively large, suited to seconds-long particles. Note it shares a word with `gtrk render` (full-video rendering) but is a different thing.
609
+ - **render** (`gtrk mg render <particle.html> --duration <sec> [--out <dir>] [--yes]`): renders a single particle in the cloud, **independent of any project**, into a Jianying-readable qtrle transparent alpha MOV (the fine-cut supplement channel — when the rough cut is already exported to Jianying and one more motion graphic is needed, you can add it without going back to the client app). The chain = lint upfront (envelope = `--duration`; any fatal item is blocked locally, zero submission, zero billing) → **billing-estimate confirmation** (live price lookup; the CLI has no local HTML render engine, so the cloud billed task is the only path for standalone particles; `--yes` skips the prompt) → inline submission to the cloud → `<composition_id>.mov` landed with `task.json`/`result.json` breadcrumbs (recoverable by task_id after a crash). **Scope**: qtrle only for now (`--format webm` is explicitly refused — Jianying cannot read VP8-alpha), 1920×1080 particles only (the contract has no portrait/odd-canvas opening), and `--duration` is required. The output never enters `.gtrk` and never lands in the Jianying draft folder; qtrle is lossless and relatively large, suited to seconds-long particles. Note it shares a word with `gtrk render` (full-video rendering) but is a different thing.
610
610
  - **fetch** (`gtrk mg fetch <query|block> [--top 3] [--all]` / `gtrk mg fetch --pick <block> --slot <beat> --project <dir>` / `--pick <block> --as <composition_id> --duration <sec> [--out <dir>]`): the **neutral particle source** from the HyperFrames registry — MG without a show skill. Candidate mode is **offline** (the snapshot ships with the package, pinned to a source commit) and lists 2–3 blocks per query with compat flags and poster links; pick mode fetches the block through three sources in order (our mirror first, then jsdelivr, then GitHub raw; 5 s each, **sha256-verified per source**, nothing is written if all three fail) → eight mechanical rewrites (`<template>` wrap / id rename / drop data-start and fit the slot / sink the solid backdrop into a child / swap GSAP to the contract CDN / swap fonts to a CJK font provable in our runtime mirror / fit duration to the slot / letterbox scaling, never stretch) → `gtrk mg lint` (fatal items block the write) → lands at `<project>/mg/<composition_id>.html`. **A skeleton is not a deliverable**: the returned `editable` (copy / number arrays / colors) MUST be rewritten for the beat and the show before laying. The contract currently accepts 1920×1080 particles only; `excluded` blocks are refused, `review` blocks (canvas / house-rule 8 shapes) can be fetched but need a real render check. `GITRUCK_MG_REGISTRY_BASE` overrides the fetch prefix.
611
611
 
612
612
  `--json` output: `{ ok, mode:"lay"|"lint"|"status", … }` (each mode carries its own fields, e.g. `laid` / `skipped` when laying, per-beat status for `status`). Laying mode additionally carries **`track_total`** (how many laid particles currently exist on the track), **`kept`** / **`kept_ids`** (how many are **left over from the previous round** and not re-laid this time, plus their `composition_id` list) and **`removed`** (how many old self-produced particles were stripped this run) — `laid` (this run), `track_total` (total on the track) and `kept` (left over) **must be read together**, and `track_total = laid + kept` always holds. Reading `laid` alone makes "lay 1, strip 20" look identical to "patch in 1", and reading only the first two hides the cost that "a few particles on the track are not from this round" (`kept_ids` and `skipped` overlap: something that failed to land this round is still there from the previous one). When not fully green it also carries a machine-readable **`reason`**: `skipped` (some were not laid) / `empty_queue` (**write-back refused**, the project was not modified, with `refused:true` and `blocked[]`) / `no_project` (project missing, nothing laid). Runs that actually wrote back also carry **`integrity`** (the material-on-disk self-check, identical in name and shape to `gtrk matrix`; see the previous section).
@@ -725,48 +725,50 @@ The seven shared video tools — black-border removal, aspect adaptation, stabil
725
725
  - `gtrk tool video_face_track ./talk.mp4 --params-json '{"time_ranges":[{"begin_time":0,"end_time":30000}]}'` — face tracking / identity clustering, optionally limited to time ranges (**in milliseconds**; GPU heavy).
726
726
  - `gtrk tool audio_tts_clone --text "欢迎收听本期节目" --speaker narrator` — text to voice-over audio (the voice list is in the website docs).
727
727
  - `gtrk tool audio_tts_clone --text-file 稿子.txt --speaker sweet_female --output-format mp3` — long-form synthesis; by default it follows the speed and segmentation tuned for the chosen voice.
728
- - `gtrk tool mad ./素材 [--bgm 歌.mp3] [--duration 20] [--seed 42] [--refresh] [--json]` — one-click MAD: scan the material folder → auto-select techniques → a single `.jsx` (run it once in AE 2020+ to get the master-composition project). `--seed` makes it reproducible; `result.json` records the seed, data version, degradation tier and chosen techniques.
728
+ - `gtrk tool mad ./素材 [--bgm 歌.mp3] [--duration 20] [--seed 42] [--technique name,…] [--refresh] [--json]` — one-click MAD: scan the material folder → select techniques → a single `.jsx` (run it once in AE 2020+ to get the master-composition project). `--seed` makes it reproducible; `result.json` records the seed, data version, degradation tier and chosen techniques.
729
+ - `gtrk tool mad --technique <name | alias | pid,…>` — build from only the named techniques (without it, selection is rule-based sampling). An ambiguous or unknown name fails with a candidate list and writes nothing; a named technique with no windows in the pool is reported and skipped, the rest still build.
730
+ - `gtrk tool mad --search <keyword> [--json]` — look up the technique catalog without building anything: substring match over technique names, aliases and categories, listing name, category, `pid`, catalog frequency and pool window count. Mutually exclusive with `--technique`; both are free of charge and need no API key.
729
731
  - Common flags: `--out <dir>` overrides the output folder, `--param k=v` (repeatable) / `--params-json '<object>'` pass cloud parameters through, `--reupload` ignores the upload cache, `--json` is machine-readable, `--ffmpeg-path <dir>` points at an ffmpeg directory.
730
732
  - Cloud-type tools without a key → an error pointing you at `gtrk init`. A failed artifact download (e.g. an expired link 404) → `result.json` records `errors` with `ok=false`, and `task.json` is kept so you can recover by `taskId`.
731
733
  - Cleanup, upscaling and interpolation are long-running GPU jobs, and their descriptors poll for up to 4 hours. A wait timeout does not mean the job was cancelled; keep `task.json` / `result.json` and recover by `taskId` instead of re-running and paying twice.
732
734
 
733
735
  The companion skill is `/gtrk-tools` (one skill covering the whole tool family).
734
736
 
735
- ### `gtrk render <project.gtrk>` — render the finished video locally
736
-
737
- ```
738
- gtrk render <gtrk> [-o <out.mp4>] [--crf <n>] [--codec <c>] [--ffmpeg-path <dir>]
739
- [--no-qc] [--no-particles] [--particle-concurrency <n>] [-y|--yes]
740
- [--no-open] [--json]
741
- ```
742
-
743
- Treats the `.gtrk` as an EDL and renders it with local ffmpeg. **Footage always comes from the local originals** (`materials[].path`); the cloud never produces the finished file.
744
-
745
- **What gets composited**: the base track (the lowest `track_index` that is not the black bed) plus every audio source, then **every visible overlay layer** stacked in contract z-order (ascending `track_index`, larger = closer to the front) — overlay video tracks (B-roll candidates, AI re-enactment) and the MG particles on `beat_track`.
746
-
747
- - **Visibility reads the `hidden` field only** (the client's "eye" toggle): a hidden track stays out of the cut entirely and is reported. The renderer never guesses which track belongs in the picture.
748
- - **When several candidate tracks are visible, the topmost one wins** (exactly what the client preview shows). To pick a different one, hide or delete tracks in the client.
749
- - Missing overlay footage (e.g. B-roll proxies not fully downloaded) **degrades instead of blocking**: that clip is not composited, a warning is printed, and the render still completes.
750
-
751
- **The particle half is billed** (the only cloud egress of this command):
752
-
753
- | Topic | How it works |
754
- |---|---|
755
- | Why the cloud | The CLI has no HTML render engine; particle pixels are authoritative in Gitruck Cloud's Hyperframes. Only the **particle HTML text** is uploaded — never the footage itself |
756
- | Metering | **unique particles × cache misses** (`html_render_simple`, per minute). A particle used N times on the timeline is baked once |
757
- | Cache | `<project dir>/.tonghe-cache/particles/<sha256>.mov`, sharing **the same key and location** as the client's Jianying export chain ⇒ whatever either side bakes, the other reuses |
758
- | Confirmation | Any miss triggers an estimate (total / unique / misses / billed minutes) and a prompt; `--yes` skips it. **A full cache hit never prompts** (a free operation should not add friction) |
759
- | `--json` | With misses and no `--yes`, the command **refuses** (machine mode has no stdin; it will not silently submit a billed task) |
760
- | Escape hatch | `--no-particles` renders particle-free at zero cost; overlay video tracks are **still composited** (that part is purely local) |
761
- | Declining | Exits with zero cloud calls and zero file writes |
762
-
763
- `--particle-concurrency <n>` (1–8, default 6) tunes particle render concurrency.
764
-
765
- The `--json` result carries `particles: {total,unique,cached,rendered,billedMinutes,skipped[]}` and
766
- `overlay: {layers,particles,hiddenSkipped,missingMaterialSkipped,particleUnavailable}` — **everything skipped has a machine-readable path**, so "65 particles laid, none in the cut, exit code 0" cannot happen quietly.
767
-
768
- A QC pass runs automatically afterwards and writes `.qc.json` (`--no-qc` skips it); QC findings are reported but never change the render's exit semantics (use `gtrk qc --fail-on` for a hard gate).
769
-
737
+ ### `gtrk render <project.gtrk>` — render the finished video locally
738
+
739
+ ```
740
+ gtrk render <gtrk> [-o <out.mp4>] [--crf <n>] [--codec <c>] [--ffmpeg-path <dir>]
741
+ [--no-qc] [--no-particles] [--particle-concurrency <n>] [-y|--yes]
742
+ [--no-open] [--json]
743
+ ```
744
+
745
+ Treats the `.gtrk` as an EDL and renders it with local ffmpeg. **Footage always comes from the local originals** (`materials[].path`); the cloud never produces the finished file.
746
+
747
+ **What gets composited**: the base track (the lowest `track_index` that is not the black bed) plus every audio source, then **every visible overlay layer** stacked in contract z-order (ascending `track_index`, larger = closer to the front) — overlay video tracks (B-roll candidates, AI re-enactment) and the MG particles on `beat_track`.
748
+
749
+ - **Visibility reads the `hidden` field only** (the client's "eye" toggle): a hidden track stays out of the cut entirely and is reported. The renderer never guesses which track belongs in the picture.
750
+ - **When several candidate tracks are visible, the topmost one wins** (exactly what the client preview shows). To pick a different one, hide or delete tracks in the client.
751
+ - Missing overlay footage (e.g. B-roll proxies not fully downloaded) **degrades instead of blocking**: that clip is not composited, a warning is printed, and the render still completes.
752
+
753
+ **The particle half is billed** (the only cloud egress of this command):
754
+
755
+ | Topic | How it works |
756
+ |---|---|
757
+ | Why the cloud | The CLI has no HTML render engine; particle pixels are authoritative in Gitruck Cloud's Hyperframes. Only the **particle HTML text** is uploaded — never the footage itself |
758
+ | Metering | **unique particles × cache misses** (`html_render_simple`, per minute). A particle used N times on the timeline is baked once |
759
+ | Cache | `<project dir>/.tonghe-cache/particles/<sha256>.mov`, sharing **the same key and location** as the client's Jianying export chain ⇒ whatever either side bakes, the other reuses |
760
+ | Confirmation | Any miss triggers an estimate (total / unique / misses / billed minutes) and a prompt; `--yes` skips it. **A full cache hit never prompts** (a free operation should not add friction) |
761
+ | `--json` | With misses and no `--yes`, the command **refuses** (machine mode has no stdin; it will not silently submit a billed task) |
762
+ | Escape hatch | `--no-particles` renders particle-free at zero cost; overlay video tracks are **still composited** (that part is purely local) |
763
+ | Declining | Exits with zero cloud calls and zero file writes |
764
+
765
+ `--particle-concurrency <n>` (1–8, default 6) tunes particle render concurrency.
766
+
767
+ The `--json` result carries `particles: {total,unique,cached,rendered,billedMinutes,skipped[]}` and
768
+ `overlay: {layers,particles,hiddenSkipped,missingMaterialSkipped,particleUnavailable}` — **everything skipped has a machine-readable path**, so "65 particles laid, none in the cut, exit code 0" cannot happen quietly.
769
+
770
+ A QC pass runs automatically afterwards and writes `.qc.json` (`--no-qc` skips it); QC findings are reported but never change the render's exit semantics (use `gtrk qc --fail-on` for a hard gate).
771
+
770
772
  ### Other
771
773
 
772
774
  - `gtrk install [--api-key … -y --skill-agents codex,cursor --all-agents --copy-skills --skills-dir …]` — install everything in one command (skills + config + health check), modelled on Feishu's `lark-cli install`.
@@ -780,7 +782,7 @@ A QC pass runs automatically afterwards and writes `.qc.json` (`--no-qc` skips i
780
782
  - Fonts land in `~/.gitruck/fonts` and are supplied to burn-in through the ffmpeg `ass` filter's `fontsdir` — **never installed into the system font table, never written to the registry, never requiring administrator rights**.
781
783
  - The distributed ffmpeg is a GPLv3 build, and the corresponding source is provided alongside the binaries (see `SOURCE.md` at the distribution point); **downloads carry no additional usage restrictions**.
782
784
  - `gtrk upgrade [--check]` — upgrade the CLI to the latest version + refresh skills (config preserved); `--check` only reports.
783
- - `gtrk skills install [--agents codex,workbuddy,comate,…] [--all] [--copy] [--dir <skills dir>]` — install/refresh agent skills on their own; by default the generic adapter and the gtrk supplement layer detect hosts automatically.
785
+ - `gtrk skills install [--agents codex,workbuddy,comate,…] [--all] [--copy] [--dir <skills dir>]` — install/refresh agent skills on their own; by default the generic adapter and the gtrk supplement layer detect hosts automatically.
784
786
  - `gtrk skills recommend [--scene <id>] [--json]` — third-party skill catalog: without `--scene` lists the nine scenes (hook / mg-explainer / kinetic-text / data-viz / map / ai-drama / collage / caption / principles); with a scene prints entries by tier (purpose / install command / license and dependencies / register command). **Recommend, never bundle**: the catalog ships with the package with a snapshot date, no network, no state; stars and licenses are as of the snapshot, installing is your call. GPL / AGPL / non-commercial / unlicensed / MCP-SaaS-only skills are excluded.
785
787
  - `gtrk skills add <owner/repo> [--skill <name>]... [--produces MG|AI_DRAMA|FILM_BROLL|script|none] [--column <id>] [--agents ...] [--all] [--copy]` — installs a third-party skill through the generic `skills` adapter and, on success, **appends** `{id, ref: "<owner/repo>#<skill>", produces, status: "third-party"}` to the show config `style.skills` (idempotent per ref, nothing is registered on failure; `--produces` defaults to the catalog value, repos outside the catalog register with `routing:"none"`), after which `gtrk mg` / `/gtrk-ai-drama` resolve it by `produces`.
786
788
 
package/README.md CHANGED
@@ -36,10 +36,10 @@
36
36
  | 📦 | `gtrk deps` | 运行时资产:`status` 查 ffmpeg/字体的来源与授权,`install` 从同合云镜像装(**须显式触发,绝不静默自动下载**) |
37
37
  | 🤖 | `gtrk skills install` | 通过通用 `skills` 适配器和 gtrk 补充层,把 18 个 CLI 自带 skill 装进本机检测到的主流 Agent;`--all` 可覆盖全部已登记宿主;`gtrk skills recommend --scene <id>` 查第三方 skill 推荐目录(随包快照、不联网、只推荐不打包),`gtrk skills add <owner/repo>` 透传安装并登记进栏目配置 `style.skills` |
38
38
  | ⬆️ | `gtrk upgrade` | 升级 CLI 到最新版 + 刷新 skill(配置保留);`--check` 只查不装 |
39
- | 🎞️ | `gtrk render` | 本地渲染 gtrk 工程(EDL)→ 成片 mp4(需 ffmpeg);按契约 z 序合成**全部可见叠加层**(B-roll 等 overlay 视频轨 + MG 颗粒,`hidden` 的轨不进片);输出帧按时间线**累计对齐**(逐段取整误差不累加,画面不会对配音渐进失步);渲完自动质检并落 `.qc.json`(`--no-qc` 跳过);画中画 clip 的 `clip_transform`(缩放 / 落位 / 旋转 / 透明)、`border_radius` 圆角与 `clip_mask` 形状蒙版(圆 / 圆角方 / 爱心 / 菱形 / 星形,带羽化)随工程本地合成,与客户端预览观感等价。⚠️ 未命中缓存的 MG 颗粒要云渲**有计费**(先预估要确认;`--no-particles` 零计费出无颗粒版) |
39
+ | 🎞️ | `gtrk render` | 本地渲染 gtrk 工程(EDL)→ 成片 mp4(需 ffmpeg);按契约 z 序合成**全部可见叠加层**(B-roll 等 overlay 视频轨 + MG 颗粒,`hidden` 的轨不进片);输出帧按时间线**累计对齐**(逐段取整误差不累加,画面不会对配音渐进失步);渲完自动质检并落 `.qc.json`(`--no-qc` 跳过);画中画 clip 的 `clip_transform`(缩放 / 落位 / 旋转 / 透明)、`border_radius` 圆角与 `clip_mask` 形状蒙版(圆 / 圆角方 / 爱心 / 菱形 / 星形,带羽化)随工程本地合成,与客户端预览观感等价。⚠️ 未命中缓存的 MG 颗粒要云渲**有计费**(先预估要确认;`--no-particles` 零计费出无颗粒版) |
40
40
  | 🔬 | `gtrk qc <成片>` | 成片质检:单趟扫全片查闪帧/黑帧/冻结/爆音/静音/音画不同步,带时码定位;`--gtrk <工程>` 开工程感知识别**段内跳切**,`--fail-on error\|warn\|never` 供管线门控 |
41
41
  | 🔎 | `gtrk matrix` | B-roll 检索+**候选铺轨**:消费 FILM_BROLL 派单 → 产候选清单 + 下载 preview 代理铺 N 条候选轨(`--lay N` 默认 1,opencut 打开即可用轨道小眼睛对比;`--lay 0` 只出清单);`matrix search "<词>"` 单条 ad-hoc;`matrix fetch <clip_id...>` 精剪期拉原片(已授予素材免费重签+下载落盘,直接拖进剪映);**本地素材模式**:`matrix index --dirs <素材夹>` 免切片建索引 → `--local --dirs` 检索铺轨(**素材本体不上云**)→ `matrix lay` 消费(可编辑的)plan;`matrix describe` 按需理解候选 |
42
- | 🎨 | `gtrk mg` | MG 动态图颗粒铺轨:消费 MG 派单 → 把 html-particle 颗粒(透明叠加 / 满屏底层,由你栏目的 MG 生产 skill 所产)铺进 `.gtrk` 的 beat_track;`mg lint <颗粒.html>` 铁律静态子集校验、`mg status --project <dir>` 编排看板(缺 HTML / 已产未铺 / 已铺);`mg render <颗粒.html> --duration <sec>` 脱离工程独立云渲单颗颗粒为剪映可读 qtrle 透明 MOV(精剪补给口);aux 叠层颗粒同段多铺(一 beat 派生主 + `-aux<n>`)。旧名 `gtrk rrv` 保留为弃用别名;`gtrk mg fetch` 从 Hyperframes registry 取中性块骨架(快照随包离线候选、三源取块我方镜像优先、机械改写后过 lint) |
42
+ | 🎨 | `gtrk mg` | MG 动态图颗粒铺轨:消费 MG 派单 → 把 html-particle 颗粒(透明叠加 / 满屏底层,由你栏目的 MG 生产 skill 所产)铺进 `.gtrk` 的 beat_track;`mg lint <颗粒.html>` 铁律静态子集校验、`mg status --project <dir>` 编排看板(缺 HTML / 已产未铺 / 已铺);`mg render <颗粒.html> --duration <sec>` 脱离工程独立云渲单颗颗粒为剪映可读 qtrle 透明 MOV(精剪补给口);aux 叠层颗粒同段多铺(一 beat 派生主 + `-aux<n>`)。旧名 `gtrk rrv` 保留为弃用别名;`gtrk mg fetch` 从 Hyperframes registry 取中性块骨架(快照随包离线候选、三源取块我方镜像优先、机械改写后过 lint);`gtrk mg fetch --source text` 取同合云自家的文字特效模板(开箱即成品、不做机械改写),配 `gtrk mg compile`(改 IR 重编译,0 积分)与 `gtrk mg edit --say`(自然语言改写,按候选计费) |
43
43
  | 🎙️ | `gtrk project init` | 音频驱动工程起盘:从一条配音建 `.gtrk` 工程——主路 `--tts-task <task_id>` 引用已完成的 TTS 配音任务(直取产物音频+句级时码,零 ASR);兜底 `--audio`+`--transcript` 自备配音成对给。落好即可 `gtrk split --project` 接成片流水线 |
44
44
  | 🎼 | `gtrk audio lay` / `tighten` | 音频轨零件:`lay` 往 `.gtrk` 工程追加一条音频轨(BGM/配乐上轨,同源幂等替换不堆轨);`--beat-align` 云端分析把 **BGM 的情绪峰值压到成片的高潮点上**,锚点前后按小节线平铺补齐、两侧都够长时零平铺(计费一次;高潮点取自 `split.beats` 的判据链,可用 `--climax <轨秒>` 覆盖;`--no-loop` 只放锚点那一段、头尾留白;无 Key / 失败 / 曲子缺高潮点自动降级为不锚定,命令不失败)。`tighten` 收紧配音的句间停顿(纯本地零计费,只压跨句界的静音、句内换气不动) |
45
45
  | 🎯 | `gtrk audio align` | 音画对轨零件(纯本地零计费):外录音轨(领夹麦/录音笔)与视频互相关测偏移+置信度;高置信直接换轨(视频流零像素改动),低置信产对齐工程交客户端拖齐后 `--resume` 读回;`--offset` 显式偏移直换 |
@@ -145,7 +145,7 @@ gtrk transcript "D:/素材/采访视频.mp4"
145
145
  | ③ | 「**铺 B-roll 底轨**」(两条腿同一阶段) | `/gtrk-matrix` → `gtrk matrix` → 影视/本地素材候选轨铺入;`/gtrk-ai-drama`(skill,无命令)→ 四段描述稿(中英分块) | **opencut 里挑选/调整 B-roll**(小眼睛切换对比);AI 片段去外部平台出片、**手动回铺** |
146
146
  | ④ | 「B-roll 齐了,**抽帧看看构图**」 | 对**三源合并后的最终底轨**抽帧(agent 纪律,无专属命令) | **确认构图**(主体位置 / 安全区 / 朝向 / 明暗) |
147
147
  | ⑤ | 「构图没问题,**铺 MG**」 | `/gtrk-mg` → `gtrk mg` → MG(含 ov)叠在已定稿的底轨之上 | 精修颗粒(opencut 手调) |
148
- | ⑥ | 「**出成片**」 | 两条路都行:客户端出片链(多车道合成 + 颗粒云渲 / **导剪映**),或 `gtrk render`(本地叠全部可见叠加层出 mp4,颗粒未命中缓存时计费);两端共用同一份颗粒缓存 | 客户端里精修定稿 |
148
+ | ⑥ | 「**出成片**」 | 两条路都行:客户端出片链(多车道合成 + 颗粒云渲 / **导剪映**),或 `gtrk render`(本地叠全部可见叠加层出 mp4,颗粒未命中缓存时计费);两端共用同一份颗粒缓存 | 客户端里精修定稿 |
149
149
 
150
150
  > **次序有理由**:**AI 情景片段属于底轨 B-roll 画面家族,不是叠加层**——整条管线里唯一的叠加层是 MG(含 ov)。MG 的排版是「因势象形避主体」、**依赖底轨的最终画面构图**,所以三源(影视 / 本地 / AI)必须全落齐、构图核过,才轮到 MG。用不到的车道跳过(`dispatch` 里该队列为空就不铺)。
151
151
  >
@@ -193,11 +193,11 @@ CLI 写 .gtrk ─▶ 客户端打开(自动感知外部改动、先存脏改再
193
193
  | **AI 再现回铺** | 外部平台出的 AI 片段**手动拖进 AI_DRAMA 车道**对齐区间(`/gtrk-ai-drama` 只吐描述稿,片在外部平台出,见 SOP ③——它属底轨阶段,MG 要等它落位后才铺) |
194
194
  | **最终出片** | 多车道合成(overlay / MG / particle 云渲叠起来)+ 剪映草稿导出,都在客户端出片链 |
195
195
 
196
- > **`gtrk render` 现在会合成叠加层了(1.1.10 起)。** 它按契约 z 序(`track_index` 升序)把**全部可见**的叠加层叠进成片——overlay 视频轨(B-roll 候选 / AI 再现回铺)与 MG 颗粒都在内;在客户端关了「小眼睛」(`hidden`)的轨不进片。
197
- >
198
- > **颗粒那一段有计费**:CLI 没有 HTML 渲染引擎,颗粒要送同合云烤成透明 MOV 再本地叠。计量 = **唯一颗粒数 × 未命中缓存数**(按分钟),未命中时会先出预估并要你确认(`--yes` 跳过;`--json` 下必须显式 `--yes`)。**第二次渲染全命中缓存 ⇒ 零计费**;缓存与客户端导出剪映时那份**同键同落点**(`<工程目录>/.tonghe-cache/particles/`),所以客户端烤过的颗粒 CLI 直接命中、反之亦然。不想花钱用 `--no-particles` 出无颗粒版(overlay 视频轨照常合成,那部分零计费、纯本地)。
199
- >
200
- > **剪映草稿导出仍在客户端出片链**(`gtrk render` 只出 mp4)。
196
+ > **`gtrk render` 现在会合成叠加层了(1.1.10 起)。** 它按契约 z 序(`track_index` 升序)把**全部可见**的叠加层叠进成片——overlay 视频轨(B-roll 候选 / AI 再现回铺)与 MG 颗粒都在内;在客户端关了「小眼睛」(`hidden`)的轨不进片。
197
+ >
198
+ > **颗粒那一段有计费**:CLI 没有 HTML 渲染引擎,颗粒要送同合云烤成透明 MOV 再本地叠。计量 = **唯一颗粒数 × 未命中缓存数**(按分钟),未命中时会先出预估并要你确认(`--yes` 跳过;`--json` 下必须显式 `--yes`)。**第二次渲染全命中缓存 ⇒ 零计费**;缓存与客户端导出剪映时那份**同键同落点**(`<工程目录>/.tonghe-cache/particles/`),所以客户端烤过的颗粒 CLI 直接命中、反之亦然。不想花钱用 `--no-particles` 出无颗粒版(overlay 视频轨照常合成,那部分零计费、纯本地)。
199
+ >
200
+ > **剪映草稿导出仍在客户端出片链**(`gtrk render` 只出 mp4)。
201
201
 
202
202
  ## 升级
203
203
 
@@ -270,7 +270,7 @@ gtrk skills install --copy
270
270
  | ⑤ | `/gtrk-mg` | `gtrk mg` | **MG(含 ov)最后叠上**(叠在已定稿、构图已核的底轨之上) |
271
271
  | — | `/gtrk-style-maker` | (无命令,建栏目) | 一次性访谈式建你栏目的风格体系(skill 家族 + 栏目配置,见下节) |
272
272
  | ③′ | 「**屏录画中画**」 | `gtrk pip lay` | 把口播粗剪的切点镜像到同步录的屏录 / 第二机位,铺屏录满幅轨 + 人像画中画副本轨(圆 / 圆角方 / 爱心 / 菱形 / 星形蒙版,可圆角);纯本地零计费;低置信时产对齐工程让客户端拖齐后 `--resume` |
273
- | — | (收口) | `gtrk render` | 本地渲染 gtrk 工程 → 成片 mp4(含 overlay 与 MG 颗粒;颗粒未命中缓存时云渲计费,`--no-particles` 可跳过) |
273
+ | — | (收口) | `gtrk render` | 本地渲染 gtrk 工程 → 成片 mp4(含 overlay 与 MG 颗粒;颗粒未命中缓存时云渲计费,`--no-particles` 可跳过) |
274
274
  | ✂️ | `/gtrk-long2short` | `gtrk long2short` | 长剪短·粗剪:长视频语义选段+跳剪 → 逐 clip 出客户端/剪映/PR 三方工程(毛片不上传),**不在成片 SOP 序列内**、随时可独立用 |
275
275
  | 📝 | `/gtrk-transcript` | `gtrk transcript` | 本地视频/配音音频 → 一个含 Agent 总结、时码记录和纯文本的 Markdown,**不在成片 SOP 序列内** |
276
276
  | 🧰 | `/gtrk-tools` | `gtrk tool <name>` | 单点工具族(图转运镜 / 图片·视频抠像…)——单发单收,**不在成片 SOP 序列内**、随时可独立用 |
@@ -341,21 +341,21 @@ gtrk init --api-key <KEY> --jianying-draft-dir auto -y
341
341
  ✅ 剪映草稿目录:C:\Users\…\com.lveditor.draft
342
342
  ```
343
343
 
344
- ### 枚举清单(`--refresh-catalog`)
345
-
346
- `gtrk doctor` 里有一行「枚举清单」:CLI 从服务端拉一份**对外枚举的全集**(字幕样式与颜色、语种码、
347
- 工程文件格式、节奏预设、任务可用性等),落在 `~/.gitruck/catalog.json`,24 小时自动刷新。
348
-
349
- 有了它,`--subtitle-type` 这类参数传错时**在上传之前**就告诉你,并列出当前可用值;
350
- 服务端新增一种样式,你不必升级 CLI 就能用上。
351
-
352
- ```bash
353
- gtrk doctor --refresh-catalog # 立刻重拉(无视 24 小时新鲜期)
354
- ```
355
-
356
- **拉不到清单不影响使用**:CLI 会沿用上一次的快照;完全没有快照时**跳过本地校验、直接提交**,
357
- 由服务端裁决——服务端白名单永远是唯一真相源。要彻底关掉这次拉取,设 `GITRUCK_CATALOG_OFFLINE=1`。
358
-
344
+ ### 枚举清单(`--refresh-catalog`)
345
+
346
+ `gtrk doctor` 里有一行「枚举清单」:CLI 从服务端拉一份**对外枚举的全集**(字幕样式与颜色、语种码、
347
+ 工程文件格式、节奏预设、任务可用性等),落在 `~/.gitruck/catalog.json`,24 小时自动刷新。
348
+
349
+ 有了它,`--subtitle-type` 这类参数传错时**在上传之前**就告诉你,并列出当前可用值;
350
+ 服务端新增一种样式,你不必升级 CLI 就能用上。
351
+
352
+ ```bash
353
+ gtrk doctor --refresh-catalog # 立刻重拉(无视 24 小时新鲜期)
354
+ ```
355
+
356
+ **拉不到清单不影响使用**:CLI 会沿用上一次的快照;完全没有快照时**跳过本地校验、直接提交**,
357
+ 由服务端裁决——服务端白名单永远是唯一真相源。要彻底关掉这次拉取,设 `GITRUCK_CATALOG_OFFLINE=1`。
358
+
359
359
  ### 崩溃报告与关闭方式
360
360
 
361
361
  gtrk 崩溃时(未捕获异常 / 未处理的 Promise 拒绝 / 顶层出口的程序缺陷)会自动上报一条报告,帮我们定位缺陷。**默认开启,首次配置时会告知一次。**
@@ -596,7 +596,7 @@ gtrk matrix lay --project <目录> [--plan <path>] # ③ 消费(
596
596
 
597
597
  ### `gtrk mg` — MG 动态图颗粒(铺轨 / lint / status / render)
598
598
 
599
- 消费 `gtrk split` 落地的 `dispatch.mg` 派单,把**你栏目的 MG 生产 skill** 产的 html-particle 颗粒铺进 `.gtrk` 工程的 `beat_track`。四种模式按首个 positional 分派:**无参 = 铺轨**、`mg lint <file>` = 单文件校验、`mg status` = 编排看板、`mg render <file>` = 独立颗粒云渲(脱离工程,精剪补给口)。旧名 `gtrk rrv` 保留为弃用别名(会打提示,建议改用 `gtrk mg`)。
599
+ 消费 `gtrk split` 落地的 `dispatch.mg` 派单,把**你栏目的 MG 生产 skill** 产的 html-particle 颗粒铺进 `.gtrk` 工程的 `beat_track`。六种模式按首个 positional 分派:**无参 = 铺轨**、`mg lint <file>` = 单文件校验、`mg status` = 编排看板、`mg render <file>` = 独立颗粒云渲(脱离工程,精剪补给口)、`mg compile <ir.json>` = 改 IR 重编译文字模板、`mg edit <file> --say` = 自然语言改写文字模板。旧名 `gtrk rrv` 保留为弃用别名(会打提示,建议改用 `gtrk mg`)。
600
600
 
601
601
  | 参数 | 作用 | 缺省 |
602
602
  |---|---|---|
@@ -622,8 +622,11 @@ gtrk matrix lay --project <目录> [--plan <path>] # ③ 消费(
622
622
  - **铁律⑧重复图元合并**(`8-primitive-merge`,**恒非致命、不拦铺轨**):识别「循环体内创建,或由循环调用具名工厂创建;落到同一父节点;且没有逐元素动画驱动」的可合并 `line` / `rect` / `path` / `polyline` / `polygon` 批次。同一父节点的纯数字循环 trip count 累加后 **≥ 8** 才报数;边界含 `.length` / 具名常量而算不出时仍报「条数未知」,不做常量折叠;逐元素 `gsap.set` / tween 或被 tween 首实参使用的元素数组会被排除。本项只提示「这里有一批可**无损**合并的重复图元,合并后画面逐像素不变」,**不是风险判定**:命中不代表该颗粒会复现缺陷,未命中也不代表安全,真判据仍是真渲染出片抽帧。
623
623
  - **回调与 seek 语义**(`x-callback-driven` / `x-engine-api-override` / `x-raf-interval`,**恒非致命、不拦铺轨**):对齐契约同名一节(2026-07-26 增补)。GSAP `seek(t)` 默认抑制回调 → 补间属性照常插值、但 `onUpdate` 里的 DOM 写入不执行,翻车形态是**画面定在初始态而非黑屏**。契约把保证压在**引擎侧**(定帧 MUST 用 `seek(t,false)` / `time(t)` / `progress(p)`),故颗粒**用回调驱动画面是合规写法**;lint 这三项只是**哨兵**:`x-callback-driven` = 回调写 DOM 且无任何 seek 兜底(有兜底则沉默,避免重复提醒);`x-engine-api-override` = 颗粒运行时覆写 `tl.seek` 或把 `__timelines[…]` 换成包装对象(会推翻引擎显式传的 `seek(t,true)`,且引擎改走 `time()`/`progress()` 即失效,属过渡态);`x-raf-interval` = 含 `requestAnimationFrame(` / `setInterval(`(自有时钟不被 seek,等于冻结)。三项 MUST NOT 致命——「用回调驱动画面」不是违规。
624
624
  - **status**(`gtrk mg status --project <dir>`):汇总 MG 流水线——`dispatch.mg` beat 总数 / 已产源 HTML 数 / 已铺进 `.gtrk` 数,并逐 beat 标注(缺 HTML / 已产未铺 / 已铺)。
625
- - **render**(`gtrk mg render <颗粒.html> --duration <sec> [--out <dir>] [--yes]`):**脱离工程**把单颗颗粒云渲成剪映可读的 qtrle 透明 alpha MOV(精剪补给口——粗剪导剪映后缺一颗动态图,不回客户端就能补)。链路 = lint 前置(包络 = `--duration`,任一致命项本地拦截、零提交零计费)→ **计费预估确认**(实时查价;CLI 无本地 HTML 渲染引擎,独立颗粒唯一路 = 云渲计费任务,`--yes` 跳过确认)→ 内联提交云端 → `<composition_id>.mov` 落盘 + `task.json`/`result.json` 面包屑(崩溃可凭 task_id 恢复)。**射程**:首发只出 qtrle(`--format webm` 明确拒绝,剪映不吃 VP8-alpha)、只收 1920×1080 颗粒(契约未开竖屏/异形口)、`--duration` 必填。产物不进 `.gtrk`、不写剪映草稿目录;qtrle 无损体积偏大,适合秒级颗粒。注意与 `gtrk render`(整片成片渲染)同词不同物。
625
+ - **render**(`gtrk mg render <颗粒.html> --duration <sec> [--out <dir>] [--yes]`):**脱离工程**把单颗颗粒云渲成剪映可读的 qtrle 透明 alpha MOV(精剪补给口——粗剪导剪映后缺一颗动态图,不回客户端就能补)。链路 = lint 前置(包络 = `--duration`,任一致命项本地拦截、零提交零计费)→ **计费预估确认**(实时查价;CLI 无本地 HTML 渲染引擎,独立颗粒唯一路 = 云渲计费任务,`--yes` 跳过确认)→ 内联提交云端 → `<composition_id>.mov` 落盘 + `task.json`/`result.json` 面包屑(崩溃可凭 task_id 恢复)。**射程**:首发只出 qtrle(`--format webm` 明确拒绝,剪映不吃 VP8-alpha)、只收 1920×1080 颗粒(契约未开竖屏/异形口)、`--duration` 必填。产物不进 `.gtrk`、不写剪映草稿目录;qtrle 无损体积偏大,适合秒级颗粒。注意与 `gtrk render`(整片成片渲染)同词不同物。
626
626
  - **fetch**(`gtrk mg fetch <检索词|块名> [--top 3] [--all]` / `gtrk mg fetch --pick <块名> --slot <beat> --project <dir>` / `--pick <块名> --as <composition_id> --duration <sec> [--out <dir>]`):**registry 中性颗粒源**——没建栏目也能出 MG。候选态**离线**(快照随包、钉死来源 commit)按检索词列 2–3 件(含 compat 标记与海报链接);取块态按三源顺序取块(我方镜像优先、jsdelivr、GitHub raw,每源 5 s,**逐源 sha256 强校验**,三源皆败零落盘)→ 机械改写八条(`<template>` 包裹 / 改 id / 去 data-start 贴坑位 / 实心底下沉子层 / GSAP 源换契约 CDN / 字体换运行时镜像可证的 CJK 字体 / 时长贴坑位 / 信箱缩放不拉伸)→ `gtrk mg lint` 致命项不过不落盘 → 落 `<project>/mg/<composition_id>.html`。**骨架不是成品**:返回的 `editable`(文案 / 数值数组 / 色值)MUST 按 beat 与栏目改写后再铺。契约当前只收 1920×1080 颗粒,其它画布拒绝;`excluded` 件拒取,`review` 件(canvas / 铁律 8 高危形态)可取但须真渲验收。`GITRUCK_MG_REGISTRY_BASE` 可整体覆盖取块前缀。
627
+ - **fetch --source text**(`gtrk mg fetch --source text <检索词> [--top 3] [--offline]` / `--pick <模板 id> --slot <beat> --project <dir>` / `--pick <模板 id> --as <composition_id> [--out <dir>]`):**同合云自家的文字特效模板库**——与中性块是两条路。模板是我方 clean-room 重写的**成品**(配色与排版已做过),**不做机械改写、MUST NOT 直接改 HTML**。每颗内嵌产生它的 IR 与双哈希,颗粒因此自带出身证明(三态 `ir` / `detached` / `html`);手改一个字节就掉成 `detached`,云端改写会拒绝它(`gtrk mg lint` 报非致命的 `x-ir-detached`)。目录走**远端择新、随包兜底**:优先取镜像上的 `catalog.json` 按 `version` 择新并缓存 24h,三源皆不可达时回落随包那份并**明示**(候选态因此永远离线可用)。取块仍逐源 sha256 强校验,三源皆败零落盘。`GITRUCK_TEXT_TEMPLATE_BASE` 可整体覆盖取块与目录前缀。
628
+ - **compile**(`gtrk mg compile <ir.json> [--out <dir>]`):把 IR 交给云端**确定性编译**成颗粒(**0 积分**)。改字、换色、改字号描边阴影、改时长都走它——改 IR 再编,比手改 HTML 干净,且颗粒保持 `ir` 态(云端还能继续调)。**本地没有编译器**是有意的:第二份编译器意味着第二套产物字节,而三态身份判的就是字节。
629
+ - **edit**(`gtrk mg edit <颗粒.html> --say "<一句话>" [--n 1|3] [--pick <k>] [--yes]`):自然语言改写文字模板颗粒,经云端模型链出候选。`--n` 只收 1 或 3,**它就是计费单位数**(2 积分/候选,首次与改写同价、无免费次数)。`detached` / 无内嵌 IR 的颗粒**本地就拒**,不提交云任务、不花钱。候选带 `scope`:`L1` = 在模板可调范围内、`L2` = 越界即新生成(**不是失败**);服务端说做不到时给一句 `refusal`,命令如实转述并以非 0 退出码区分于网络错误。不给 `--pick` 就只落候选不动原文件;给了才替换并留 `<cid>.bak.html`。
627
630
 
628
631
  `--json` 输出:`{ ok, mode:"lay"|"lint"|"status", … }`(各模式带对应字段,如铺轨的 `laid` / `skipped`、status 的逐 beat 状态)。铺轨模式另带 **`track_total`**(轨上现存已铺数)、**`kept`** / **`kept_ids`**(其中**上轮遗留**、本次没重铺的颗数与 `composition_id` 清单)与 **`removed`**(本次被剥的旧自产颗粒数)——`laid`(本次)、`track_total`(轨上共)与 `kept`(上轮遗留)**要一起读**,恒有 `track_total = laid + kept`;只看 `laid` 会让「铺 1 颗、剥 20 颗」跟「补铺 1 颗」长得一模一样,只看前两个又会漏掉「轨上那几颗不是这一轮的版本」这条代价(`kept_ids` 与 `skipped` 会重叠:这轮没铺成、上一轮那条还在轨上)。非全绿时另带机读 **`reason`**:`skipped`(部分没铺上)/ `empty_queue`(**拒写回**,工程未被改动,另带 `refused:true` 与 `blocked[]`)/ `no_project`(工程缺失未铺轨)。真写回过的运行另带 **`integrity`**(素材落盘自检,与 `gtrk matrix` 同名同形,口径见上节)。
629
632
 
@@ -741,49 +744,51 @@ gtrk matrix lay --project <目录> [--plan <path>] # ③ 消费(
741
744
  - `gtrk tool video_face_track ./talk.mp4 --params-json '{"time_ranges":[{"begin_time":0,"end_time":30000}]}'` — 人脸追踪/身份聚类,可限定时间段(**单位毫秒**;重 GPU)。
742
745
  - `gtrk tool audio_tts_clone --text "欢迎收听本期节目" --speaker narrator` — 文字转配音音频(音色列表见官网文档)。
743
746
  - `gtrk tool audio_tts_clone --text-file 稿子.txt --speaker sweet_female --output-format mp3` — 长文合成,缺省跟随音色调好的语速与切分参数。
744
- - `gtrk tool mad ./素材 [--bgm 歌.mp3] [--duration 20] [--seed 42] [--refresh] [--json]` — 一键剪 MAD:扫素材文件夹 → 自动选技法 → 单一 `.jsx`(AE 2020+ 跑一遍出母合成成片工程)。`--seed` 可复现;`result.json` 记 seed/数据版本/降级档位/选中技法。
747
+ - `gtrk tool mad ./素材 [--bgm 歌.mp3] [--duration 20] [--seed 42] [--technique 技法名,…] [--refresh] [--json]` — 一键剪 MAD:扫素材文件夹 → 选技法 → 单一 `.jsx`(AE 2020+ 跑一遍出母合成成片工程)。`--seed` 可复现;`result.json` 记 seed/数据版本/降级档位/选中技法。
748
+ - `gtrk tool mad --technique <技法名 | 别名 | pid,…>` — 只用点名的技法出片(不点名则按规则抽样)。名字歧义或不存在时报错列候选、零落盘;点到技法池里没有窗口的技法会说明原因并用剩下的继续。
749
+ - `gtrk tool mad --search <关键词> [--json]` — 只查技法目录不出片:按技法名/别名/类目做包含匹配,列出技法名、类目、`pid`、收录次数与池内窗口数。与 `--technique` 互斥;两者都零计费、不需 API Key。
745
750
  - 通用:`--out <dir>` 覆盖产物目录、`--param k=v`(可重复)/`--params-json '<对象>'` 透传云端参数、`--reupload` 忽略上传缓存、`--json` 机读、`--ffmpeg-path <dir>` 指定 ffmpeg 目录。
746
751
  - cloud 型工具缺 Key → 报错引导 `gtrk init`。产物下载失败(如链接过期 404)→ `result.json` 记 `errors`、`ok=false`、`task.json` 保留可凭 `taskId` 恢复。
747
752
  - 净化、超分、插帧为长耗时 GPU 任务,描述器最多轮询 4 小时。等待超时不代表任务取消;保留 `task.json` / `result.json` 并按 `taskId` 恢复,不要直接重跑造成重复计费。
748
753
 
749
754
  配套 skill `/gtrk-tools`(一个 skill 覆盖整个工具族)。
750
755
 
751
- ### `gtrk render <工程.gtrk>` — 本地渲染成片
752
-
753
- ```
754
- gtrk render <gtrk> [-o <out.mp4>] [--crf <n>] [--codec <c>] [--ffmpeg-path <dir>]
755
- [--no-qc] [--no-particles] [--particle-concurrency <n>] [-y|--yes]
756
- [--no-open] [--json]
757
- ```
758
-
759
- 把 `.gtrk` 当 EDL 用本地 ffmpeg 出成片。**素材一律取本地原片**(`materials[].path`),云端不产成片。
760
-
761
- **合成什么**:底轨(`track_index` 最小的非黑底垫轨)+ 全部音源,再按契约 z 序(`track_index` **升序**,越大越靠前)叠**全部可见叠加层**——overlay 视频轨(B-roll 候选 / AI 再现回铺)与 `beat_track` 的 MG 颗粒。
762
-
763
- - **可见性只读 `hidden` 字段**(客户端的「小眼睛」):关掉的轨整条不进片,如实计数告知。渲染器**不猜**哪条该叠。
764
- - **多条候选轨都可见时成片取最上层**(= 客户端预览所见)。要换,在客户端关小眼睛或删轨。
765
- - overlay 素材本地缺失(如 B-roll 代理没下全)**只降级不阻断**:该 clip 不叠 + 告警,片子照出。
766
-
767
- **颗粒那一段有计费**(本命令唯一的云端出口):
768
-
769
- | 事 | 口径 |
770
- |---|---|
771
- | 为什么要上云 | CLI 无 HTML 渲染引擎,颗粒像素权威在同合云 Hyperframes;上行的只有**颗粒 HTML 文本**,素材本体不上行 |
772
- | 计量 | **唯一颗粒数 × 未命中缓存数**(`html_render_simple`,按分钟)。同一颗粒在轨上出现 N 次只烤一次 |
773
- | 缓存 | `<工程目录>/.tonghe-cache/particles/<sha256>.mov`,与**客户端导出剪映**那条链**同键同落点** ⇒ 任一端烤过,另一端直接命中 |
774
- | 确认 | 有未命中即先出预估(总数 / 唯一 / 未命中 / 计费分钟)并要确认;`--yes` 跳过。**全命中不弹确认**(零计费不该有摩擦) |
775
- | `--json` | 有未命中且未给 `--yes` ⇒ **硬拒**(机读模式没有 stdin,不静默提交计费任务) |
776
- | 逃生舱 | `--no-particles` 零计费出无颗粒版;overlay 视频轨**照常合成**(那部分纯本地) |
777
- | 拒绝确认 | 零云端调用、零文件写入退出 |
778
-
779
- `--particle-concurrency <n>`(1–8,默认 6)调颗粒云渲并发。
780
-
781
- `--json` 结果含 `particles: {total,unique,cached,rendered,billedMinutes,skipped[]}` 与
782
- `overlay: {layers,particles,hiddenSkipped,missingMaterialSkipped,particleUnavailable}`——
783
- **跳过了什么都有机读通路**,不会出现「铺了 65 颗、成片一颗没有、退出码 0」。
784
-
785
- 渲完自动质检并落 `.qc.json`(`--no-qc` 跳过);质检结论只呈现、不改渲染退出语义(硬门控走 `gtrk qc --fail-on`)。
786
-
756
+ ### `gtrk render <工程.gtrk>` — 本地渲染成片
757
+
758
+ ```
759
+ gtrk render <gtrk> [-o <out.mp4>] [--crf <n>] [--codec <c>] [--ffmpeg-path <dir>]
760
+ [--no-qc] [--no-particles] [--particle-concurrency <n>] [-y|--yes]
761
+ [--no-open] [--json]
762
+ ```
763
+
764
+ 把 `.gtrk` 当 EDL 用本地 ffmpeg 出成片。**素材一律取本地原片**(`materials[].path`),云端不产成片。
765
+
766
+ **合成什么**:底轨(`track_index` 最小的非黑底垫轨)+ 全部音源,再按契约 z 序(`track_index` **升序**,越大越靠前)叠**全部可见叠加层**——overlay 视频轨(B-roll 候选 / AI 再现回铺)与 `beat_track` 的 MG 颗粒。
767
+
768
+ - **可见性只读 `hidden` 字段**(客户端的「小眼睛」):关掉的轨整条不进片,如实计数告知。渲染器**不猜**哪条该叠。
769
+ - **多条候选轨都可见时成片取最上层**(= 客户端预览所见)。要换,在客户端关小眼睛或删轨。
770
+ - overlay 素材本地缺失(如 B-roll 代理没下全)**只降级不阻断**:该 clip 不叠 + 告警,片子照出。
771
+
772
+ **颗粒那一段有计费**(本命令唯一的云端出口):
773
+
774
+ | 事 | 口径 |
775
+ |---|---|
776
+ | 为什么要上云 | CLI 无 HTML 渲染引擎,颗粒像素权威在同合云 Hyperframes;上行的只有**颗粒 HTML 文本**,素材本体不上行 |
777
+ | 计量 | **唯一颗粒数 × 未命中缓存数**(`html_render_simple`,按分钟)。同一颗粒在轨上出现 N 次只烤一次 |
778
+ | 缓存 | `<工程目录>/.tonghe-cache/particles/<sha256>.mov`,与**客户端导出剪映**那条链**同键同落点** ⇒ 任一端烤过,另一端直接命中 |
779
+ | 确认 | 有未命中即先出预估(总数 / 唯一 / 未命中 / 计费分钟)并要确认;`--yes` 跳过。**全命中不弹确认**(零计费不该有摩擦) |
780
+ | `--json` | 有未命中且未给 `--yes` ⇒ **硬拒**(机读模式没有 stdin,不静默提交计费任务) |
781
+ | 逃生舱 | `--no-particles` 零计费出无颗粒版;overlay 视频轨**照常合成**(那部分纯本地) |
782
+ | 拒绝确认 | 零云端调用、零文件写入退出 |
783
+
784
+ `--particle-concurrency <n>`(1–8,默认 6)调颗粒云渲并发。
785
+
786
+ `--json` 结果含 `particles: {total,unique,cached,rendered,billedMinutes,skipped[]}` 与
787
+ `overlay: {layers,particles,hiddenSkipped,missingMaterialSkipped,particleUnavailable}`——
788
+ **跳过了什么都有机读通路**,不会出现「铺了 65 颗、成片一颗没有、退出码 0」。
789
+
790
+ 渲完自动质检并落 `.qc.json`(`--no-qc` 跳过);质检结论只呈现、不改渲染退出语义(硬门控走 `gtrk qc --fail-on`)。
791
+
787
792
  ### 其它
788
793
 
789
794
  - `gtrk install [--api-key … -y --skill-agents codex,cursor --all-agents --copy-skills --skills-dir …]` — 一条命令装全(skill + 配置 + 体检),对标飞书 `lark-cli install`。
@@ -797,7 +802,7 @@ gtrk render <gtrk> [-o <out.mp4>] [--crf <n>] [--codec <c>] [--ffmpeg-path <dir>
797
802
  - 字体落 `~/.gitruck/fonts`,烧录时经 ffmpeg `ass` 滤镜的 `fontsdir` 供给——**不装进系统字体表、不写注册表、不要管理员权限**。
798
803
  - 分发的 ffmpeg 为 GPLv3 构建,对应源码与二进制同处提供(见分发点 `SOURCE.md`);**下载不附加任何使用限制**。
799
804
  - `gtrk upgrade [--check]` — 升级 CLI 到最新版 + 刷新 skill(配置保留);`--check` 只查不装。
800
- - `gtrk skills install [--agents codex,workbuddy,comate,…] [--all] [--copy] [--dir <skills 目录>]` — 单独安装/刷新 Agent Skills;缺省由通用适配器与 gtrk 补充层自动检测。
805
+ - `gtrk skills install [--agents codex,workbuddy,comate,…] [--all] [--copy] [--dir <skills 目录>]` — 单独安装/刷新 Agent Skills;缺省由通用适配器与 gtrk 补充层自动检测。
801
806
  - `gtrk skills recommend [--scene <id>] [--json]` — 第三方 skill 推荐目录:不带 `--scene` 列九个场景(hook / mg-explainer / kinetic-text / data-viz / map / ai-drama / collage / caption / principles),带场景按 tier 给条目(用途 / 安装命令 / 许可与依赖 / 登记命令)。**只推荐不打包**:目录随包分发、带快照日期、不联网不留痕;star 与许可以仓库页为准,装不装是你的选择。GPL / AGPL / 非商用 / 无许可证 / 只能经 MCP-SaaS 运行的不入目录。
802
807
  - `gtrk skills add <owner/repo> [--skill <name>]... [--produces MG|AI_DRAMA|FILM_BROLL|script|none] [--column <id>] [--agents ...] [--all] [--copy]` — 透传通用 `skills` 适配器安装第三方 skill,成功后把 `{id, ref: "<owner/repo>#<skill>", produces, status: "third-party"}` **追加**进栏目配置 `style.skills`(同 ref 幂等、失败不登记;`--produces` 缺省取目录值,目录外仓登记为 `routing:"none"`),之后 `gtrk mg` / `/gtrk-ai-drama` 按 `produces` 即可解析到它。
803
808