@gitruck/cli 0.2.2 → 0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gitruck/cli",
3
- "version": "0.2.2",
3
+ "version": "0.2.4",
4
4
  "description": "同合云成片流水线 CLI —— agent 驱动云端任务、产物拉回本地、三方工程文件(客户端/剪映/PR)互通。",
5
5
  "license": "MIT",
6
6
  "author": "Gitruck (同合云)",
@@ -47,7 +47,7 @@
47
47
  "build": "bun build ./src/index.ts --target=node --outfile dist/index.js",
48
48
  "typecheck": "tsc --noEmit",
49
49
  "prepublishOnly": "bun run build",
50
- "test": "esbuild src/lib/chunk-upload.ts --bundle --platform=node --format=esm --outfile=.test-build/chunk-upload.mjs && node --test \"test/*.test.mjs\""
50
+ "test": "esbuild src/lib/chunk-upload.ts src/lib/render.ts src/lib/cloud.ts src/lib/materialize.ts src/lib/projection.ts src/lib/splitdoc.ts src/lib/gtrk-writeback.ts --bundle --platform=node --format=esm --outdir=.test-build --out-extension:.js=.mjs && esbuild src/commands/split.ts --bundle --platform=node --format=esm --outdir=.test-build --out-extension:.js=.mjs && node --test \"test/*.test.mjs\""
51
51
  },
52
52
  "devDependencies": {
53
53
  "bun-types": "^1.1.0",
@@ -5,7 +5,7 @@ description: 智能口播剪辑闭环——把一条口播原视频(毛片)通
5
5
 
6
6
  # 口播剪辑(gtrk-oralcut)
7
7
 
8
- 把用户的口播毛片,用 `gtrk` CLI 跑通「上传 → 云端智能口播剪辑 → 拉回三方工程文件 打开」,再把产物目录 + 三端打开方式回给用户。**CLI 是手、你是脑。**
8
+ 把用户的口播毛片,用 `gtrk` CLI 跑通「**本地抽音频/720p只传抽出物(毛片永不上传)** → 云端智能口播剪辑 → 拉回三方工程文件 →(可选)**本地 ffmpeg 渲染成片**」,再把产物目录 + 三端打开方式回给用户。**CLI 是手、你是脑。**
9
9
 
10
10
  > **本 skill 已含你需要的全部信息**(参数、取值、执行、读报告、排错),照它做即可,不用也无法去查外部文档。(源仓库另有一份更全的工具无关版 `AGENT.md`,那是给在仓库里开发的人看的,与你无关。)
11
11
 
@@ -17,6 +17,16 @@ description: 智能口播剪辑闭环——把一条口播原视频(毛片)通
17
17
  - 报云端连不上 / 剪映目录没配 → 照提示让用户处理。
18
18
  - 全绿就往下走。
19
19
 
20
+ ### ffmpeg 依赖(本地抽音频 / 渲染必需,缺了你来装)
21
+
22
+ oralcut 现在**本地预处理**(探原片几何 + 抽 16k 单声道 mp3 / 压 720p 代理)和 **本地渲染**都靠 `ffmpeg`/`ffprobe`。看 `gtrk doctor` 里「本地渲染 (ffmpeg)」这行:
23
+
24
+ - **已就绪** → 往下走。
25
+ - **未找到** → 你来装(CLI 不自下不自分发):**先确认确实没有**(doctor 已查过 `~/.gitruck/ffmpeg` 与系统 PATH),缺了再拉 `ffmpeg` + `ffprobe` 两个可执行文件放到 `~/.gitruck/ffmpeg/`(Windows 即 `ffmpeg.exe`/`ffprobe.exe`)。
26
+ - **国内用户优先国内加速站点**:GitHub 官方静态构建(BtbN / gyan.dev)直连慢,走 GitHub 加速代理(pass-through)或同合云自建镜像拉,下载后**核对 sha256**。
27
+ - 装好复跑 `gtrk doctor` 确认转绿。
28
+ - 用户自己装过 ffmpeg 并配了 PATH → doctor 会从系统探到直接用;**绝不去改用户的环境变量/PATH**(CLI 一律绝对路径调用)。若装在别处,用 `--ffmpeg-path <目录>` 指给它。
29
+
20
30
  ## 把用户的话变成一次调用
21
31
 
22
32
  > **每次调用都必须带 `--json`**(成功时 stdout 只出一行结果 JSON、人读日志转 stderr),你才能解析结果 + 读报告。不是可选项。
@@ -37,11 +47,12 @@ description: 智能口播剪辑闭环——把一条口播原视频(毛片)通
37
47
  | 有稿对齐(更准) | `--script <txt>`(或毛片同名 `.txt` 自动) | 10–50000 字 · 缺省无稿重建 | 有稿逐字对齐质量最佳;无稿智能重建终稿 |
38
48
  | 换语种 | `--lang <码>` | `zh-CN`/`en-US`/`ja-JP`… · 默认 `zh-CN` | 不传即 CLI 默认发 `zh-CN`;主推中文,余语种尽力而为 |
39
49
  | 产哪些工程格式 | `--formats <逗号列表>` | `xml`/`fcpxml`/`otio`/`jianying`/`capcut`/`gtrk` · CLI 缺省 `gtrk,jianying,xml` | 可多选 |
40
- | 顺带渲个成片视频 | `--render` | 开关 · 缺省不渲 | 加它则额外出 mp4 成片 |
41
- | 成片画质 | `--crf <n>`(配 `--render`) | 整数 14–28 · `18` | 越小越清晰 / 越大体积越小 |
42
- | 成片编码 | `--codec <c>`(配 `--render`) | `h264` · `h264` | 当前仅 h264 |
50
+ | 顺带出成片视频 | `--render` | 开关 · 缺省不渲 | **本地** ffmpeg 按 gtrk EDL 渲染 mp4(毛片仍不上传、云端不渲染);需 ffmpeg 就绪 |
51
+ | 成片画质 | `--crf <n>`(配 `--render`) | 整数 14–28 · `18` | 本地渲染用;越小越清晰 / 越大体积越小 |
52
+ | 成片编码 | `--codec <c>`(配 `--render`) | `h264` · `h264` | 本地渲染用;当前仅 h264 |
53
+ | 指定 ffmpeg 位置 | `--ffmpeg-path <目录>` | 路径 · 缺省 `~/.gitruck/ffmpeg`→系统 | 用户 ffmpeg 装在非标准位置时指给它 |
43
54
  | 节奏松紧 | `--preset <名>` | `steady`/`concise`/`compact` · 默认 `concise` | 不传即 CLI 默认发 `concise`(精练);见下方预设表,铺底后可逐项覆盖 |
44
- | **剪不准 / 剪掉真内容 / 有话没剪进去** | `--visual-assist` | 开关 · 关 | **视觉找补兜底**:画面说话检测保护疑似漏识别段不被误剪并重识别捞回(需说话人面部基本可见);会增加处理耗时(与主识别并行、约两者较大值),但不额外计费、绝不凭空生成 |
55
+ | **剪不准 / 剪掉真内容 / 有话没剪进去** | `--visual-assist` | 开关 · 关 | 开则**本地改传 720p 代理**(非上传原片)+ **视觉找补兜底**:画面说话检测保护疑似漏识别段不被误剪并重识别捞回(需说话人面部基本可见);上传体量比纯音频大、处理耗时增加,但不额外计费、绝不凭空生成 |
45
56
  | 别随说话人节奏自适应 | `--no-adaptive-rhythm` | 一元 flag:传即关闭 · 自适应默认开 | 是否定 flag(不接受 `=值` 赋值);关了改用固定标点停顿表 |
46
57
  | 剪映草稿目录(非标准位置) | `--jianying-draft-dir <目录>`(或 `auto`) | 路径 · 读 init 配置 / 自动探测 | 出剪映可直开草稿需要它 |
47
58
  | 工程落盘到别处 | `--out <目录>`(或 `-o`) | 路径 · 缺省 `<毛片同目录>/<毛片名>-video-project-<时间戳>` | 想把产物放指定位置时用 |
@@ -79,7 +90,7 @@ gtrk oralcut "<毛片绝对路径>" [--script "<txt路径>"] [--preset steady|co
79
90
  ```
80
91
 
81
92
  - `--json`:人读日志走 stderr,**成功时 stdout 只有一行结果 JSON**:
82
- `{ ok, outDir, files:{gtrk:[],jianying:[],xml:[]}, jianyingDraftPath, report, errors, taskId, fileId }`
93
+ `{ ok, outDir, files:{gtrk:[],jianying:[],xml:[]}, jianyingDraftPath, rendered, report, errors, taskId, fileId }`(`rendered`=本地渲染成片路径,未开 `--render` 时为 `null`)
83
94
  - **命令失败**(毛片路径错 / 鉴权失败 / 参数越界 6016 等)→ **进程非 0 退出、报错打到 stderr、stdout 无 JSON**。先看退出码,非 0 就把 stderr 的报错如实回给用户、别当成功。
84
95
  - 默认会自动打开产物目录(用户能直接看到文件);纯脚本/无头环境才加 `--no-open`。
85
96
  - 云端处理是分钟级,耐心等命令返回。
@@ -0,0 +1,148 @@
1
+ ---
2
+ name: gtrk-splitter
3
+ description: 视觉拆分派单器——把一条已剪好的口播工程(gtrk + transcript)拆成 beat 级「视觉拆分稿」,为每个连续文稿段指定唯一主层(A_ROLL 真人出镜 / RRV_MG 动态图 / AI_DRAMA 再现 / FILM_BROLL 影视素材)+ 辅助层,产机器可消费的派单清单(RRV 槽位 / B-roll 检索队列 / AI 动画队列)驱动后续铺轨。当用户想「文稿视觉化拆分 / 视觉拆分稿 / beat 时间线 / 派分镜 / A-roll B-roll 分配 / 哪些段做动态图·哪些做 AI 再现·哪些用影视素材 / 给这条口播派单」时使用本 skill。凡涉及把口播成片拆成分镜派工,优先用本 skill 驱动 gtrk CLI 的 `split` 命令,绝不手写时码、绝不抄原文定位。
4
+ ---
5
+
6
+ # 视觉拆分派单器(gtrk-splitter)
7
+
8
+ 把一条**已经剪好的口播工程**(`gtrk` 工程文件 + `transcript.json` 句级词表),拆成一份可直接派工的 **beat 级视觉拆分稿**,再交给 `gtrk split` 校验落地,产出机器可消费的派单清单。**CLI 是手(投影/校验/落地/写时码),你是脑(切 beat、选 lane、写 handoff)。**
9
+
10
+ > **本 skill 已含你需要的全部信息**(流程、字段契约、枚举、拆分方法论、铁律)。字段细节与升级规则读 `references/field-schema.md`;模仿文档形态读 `references/example-visual-split.json`(《过拟合》20-beat 金样,机器 JSON)与 `references/example-visual-split.md`(同一金样的人读版式参照)。
11
+
12
+ ## 三条铁律(先记死,再动手)
13
+
14
+ 1. **只引用视图里存在的 utterance id**:beat 的文稿范围 = `span:{from:"u0007", to:"u0011"}`(utterance id 区间)。id 必须来自 `gtrk split --project` 导出的投影视图,**不许臆造**(`u9999` 一定被硬拒)。
15
+ 2. **绝不抄原句文字作定位**:旧版用「前锚点……后锚点」原文片段定位——**已退役**。锚点文字会诱发幻觉、会和实拍漂移。一律用 id 区间。
16
+ 3. **绝不自造/推算任何时码**:拆分稿里**不写任何秒级时码字段**。轨道时码由 `gtrk split` 落地时现场投影写入 `struct_meta.split` / `dispatch.json`。你只管语义(lane / 叙事功能 / handoff),时间线交给 CLI。
17
+
18
+ ## 前置:确认工程 + CLI
19
+
20
+ - 需要一个 **oralcut 产物目录**(跑过 `gtrk oralcut` 得到的目录),里面有 `gtrk/project.gtrk` 与 `transcript/transcript.json`。没有 transcript(旧任务)→ 让用户用新版本重跑 `gtrk oralcut`(恒出 transcript)。
21
+ - `gtrk` 命令找不到 → 让用户装 `npm i -g @gitruck/cli@latest`。
22
+ - 用户可以先在客户端手调切点再保存——**每次拆分都基于「发起那一刻」的时间线投影**,所见即所得。
23
+
24
+ ## 完整流程(取视图 → 拆分 → 落地 → 修正循环 ≤3 轮)
25
+
26
+ ### 1. 取投影视图(你的唯一创作输入)
27
+
28
+ ```bash
29
+ gtrk split --project "<oralcut产物目录>" --json
30
+ ```
31
+
32
+ - 产 `<目录>/split/view.json` 并在 stdout 回一行结果 JSON。**读 `view.json` 文件**(大稿更稳),不要只解析终端。
33
+ - 视图结构:`{transcript_hash, projected_at, utterances:[{id, text, track_st, track_ed, dropped, kept_words, total_words}]}`。
34
+ - `id` = 你要引用的 utterance id(如 `u0007`)。
35
+ - `text` = 该句文字(**只用来读懂内容、判断在哪切 beat**,绝不复制进拆分稿)。
36
+ - `dropped:true` = 这句在当前时间线上已被剪掉——**别把它划进任何 beat 的 span**(划了落地会跳过/收缩)。
37
+ - `track_st/track_ed` = 轨道时码(**只读,帮你感知节奏/时长**,不要抄进拆分稿)。
38
+ - **透传 `transcript_hash`**:拆分稿的 `transcript_hash` 必须原样等于视图里的 `transcript_hash`(hash 链,错版硬拒)。
39
+
40
+ ### 2. 通读全片,按视觉职责切 beat
41
+
42
+ 按下面「拆分方法论」把连续的 utterance 分成若干 beat。一个 beat 覆盖**连续的 id 区间**(可跨多句),但**不能跨前后两处拼接**。beat 之间允许留空隙(未覆盖段默认 A_ROLL 底轨直出),**不许重叠**。
43
+
44
+ ### 3. 写拆分稿 JSON
45
+
46
+ 按 `references/field-schema.md` 的契约写。骨架:
47
+
48
+ ```json
49
+ {
50
+ "contract_version": "v1",
51
+ "transcript_hash": "<原样透传视图里的 transcript_hash>",
52
+ "beats": [
53
+ {
54
+ "id": "B01",
55
+ "span": { "from": "u0001", "to": "u0003" },
56
+ "base_track": "真人出镜",
57
+ "lane": "A_ROLL",
58
+ "narrative": "mirror-hook",
59
+ "container_stage": "none",
60
+ "rhythm": "平稳 -> 停顿",
61
+ "visual_task": "主持人直视镜头带观众做实验",
62
+ "irreplaceability": "必须真人出镜",
63
+ "aux_layers": [
64
+ { "type": "quote-card", "mount": { "from": "u0001", "to": "u0002" }, "role": "金句提炼", "necessity": "强建议" }
65
+ ]
66
+ }
67
+ ],
68
+ "queues": { "a_roll": [], "rrv_mg": [], "ai_drama": [], "film_broll": [] }
69
+ }
70
+ ```
71
+
72
+ 关键:
73
+ - `lane` 四选一 `A_ROLL | RRV_MG | AI_DRAMA | FILM_BROLL`;`base_track` 三选一 `真人出镜 | 口播继续 | 旁白主导`。
74
+ - **handoff 按 lane 分型**(校验器会硬查):
75
+ - `RRV_MG` → `handoff:{slug_hint?, theme?, bg?, duration_hint}`,**`duration_hint`(秒)必填**。
76
+ - `FILM_BROLL` → `handoff:{queries:[...非空], shots?, per_shot_sec?, exclude?}`,**`queries` 非空必填**。
77
+ - `AI_DRAMA` → `handoff:{narrative?, theme?, emotion_stage?, platform?, shot_count?}`,全可选(下游 ai-drama-prompter 有推断默认)。
78
+ - `A_ROLL` → **无 handoff**(写了会被警告忽略)。
79
+
80
+ ### 4. 落地校验
81
+
82
+ ```bash
83
+ gtrk split "<拆分稿.json>" --project "<oralcut产物目录>" --md --json
84
+ ```
85
+
86
+ - 成功:写回 `.gtrk` 的 `struct_meta.split`(投影快照)+ 产 `split/dispatch.json`(派单清单)+ `--md` 的 `split/visual-split.md`(人读稿)。stdout 回结果 JSON。
87
+ - 失败:**进程非 0 退出、stderr 打逐条错误、无任何写入**。
88
+
89
+ ### 5. 修正循环(≤3 轮)
90
+
91
+ 校验失败时,**按 stderr 里逐条错误(每条含 beat id + 原因)修正拆分稿并重试**,上限 3 轮。常见错误与改法:
92
+ - `span.to 引用了不存在的 utterance id u9999` → 该 id 不在视图里,换成视图里真实存在的 id。
93
+ - `区间倒序` → `from` 的 id 序晚于 `to`,对调或修正。
94
+ - `B02 与 B03 区间重叠` → 收窄其中一个 beat 的 span,让区间不相交。
95
+ - `transcript_hash 不匹配` → 转写已变更:**重新跑第 1 步导出视图**,用新 hash 重拆(别硬改 hash 蒙混)。
96
+ - `FILM_BROLL 缺检索 query` / `RRV_MG 缺 duration_hint` → 补齐对应 handoff 必填字段。
97
+
98
+ **3 轮仍失败 → 把错误原样呈给用户**,不静默降级、不绕过校验。
99
+
100
+ ### 6. 回报 dispatch 摘要
101
+
102
+ 落地成功后,读 `split/dispatch.json` + 结果 JSON 的 `beats`,向用户交代:
103
+ - 各车道 beat 数(A_ROLL / RRV_MG / AI_DRAMA / FILM_BROLL)。
104
+ - **被跳过的 beat**(span 内 utterance 全被剪,`beats.skipped[]`)及原因。
105
+ - **被收缩的 beat**(部分被剪、按存活句包络收窄,`beats.shrunk[]`)——提示人工复核。
106
+ - 下游各拿各的:`dispatch.rrv_mg`(RRV 槽位表,`composition_id` 已按 `<工程slug>-<beatId>` 命名)/ `dispatch.film_broll`(B-roll 检索队列)/ `dispatch.ai_drama`(AI 动画队列)。
107
+
108
+ ---
109
+
110
+ ## 拆分方法论(沿《实在界漫游指南》视觉语法精华)
111
+
112
+ ### 四车道语义(lane 四选一)
113
+
114
+ - **`A_ROLL`(真人出镜)**:信任感来自「观众看见真人正在说」。优先给:体验式钩子、立场转换、关键悬念、情绪抱持、理论升华、结尾发问。
115
+ - **`RRV_MG`(Real Roam Viz 动态图)**:主要任务是「让观众看懂结构」。优先给:容器概念展开、抽象结构翻译、多概念映射、网络/流程/关系图、容器反转、回扣时的系统动态图。
116
+ - **`AI_DRAMA`(AI 再现)**:靠「演绎一个具体历史瞬间」成立。优先给:历史事件再现、理论家/名人/时代场景的动作演绎、有明确年代·人物·地点暗示的桥段。
117
+ - **`FILM_BROLL`(影视素材)**:靠「沉浸感、情绪、现实质感」成立。优先给:日常痛感、都市情绪、社会事件氛围、关系案例沉浸——不适合 MG 讲解、也不需要历史 reenactment 的段落。
118
+
119
+ ### 八叙事功能(narrative)
120
+
121
+ `mirror-hook`(镜像钩子)· `demolition`(拆解)· `container-translation`(容器翻译)· `abyssal-fall`(坠入深渊)· `holding`(抱持)· `reversal-elevation`(反转升华)· `callback-closure`(回扣收束)· `typography-emphasis`(文字强调)。按叙事职责分类,不按形状分类。
122
+
123
+ ### 七容器阶段(container_stage)
124
+
125
+ 若全片有「容器贯穿线」,为每个 beat 标一个阶段:`none`(未调用)· `seed`(首次登场)· `expand`(讲清容器本身)· `translate`(用容器翻译理论)· `rupture`(推向真相/谷底)· `flip`(希望面/结构反转)· `callback`(意象被重新调回)。容器线应贯穿三幕,而不是只在中间出现一次。
126
+
127
+ ### 切分触发器(何时切出新 beat)
128
+
129
+ 遇任一即考虑切:**主层改变** / **叙事功能改变** / **容器阶段改变** / 出现停顿·静音·金句·发问 / 解释职责从「讲感受」变「讲结构」 / 某辅助层升级为主要理解入口。**不要因一个逗号句号就切——只在视觉职责变化时切。**
130
+
131
+ ### 辅助层七类(aux_layers)
132
+
133
+ `quote-card`(金句卡)· `term-callout`(术语解释)· `network-diagram`(关系图)· `archive-caption`(档案标注)· `pause-card`(停顿卡)· `data-annotation`(数据标注)· `timeline-tag`(年份/时间标注)。辅助层不是装饰,是补充理解职责。挂载范围三型:`"same_beat"`(同 beat)/ `{from,to}`(id 区间)/ `{trigger:"uNNNN"}`(触发点)。
134
+
135
+ ### 升级规则(辅助层 → 主层)
136
+
137
+ 辅助层满足任一条件时,**别再当辅助层**,切出下一个 beat 并把它升级为新 `lane` 主层:连续 2-3 秒成为主要理解入口 / 视觉上占据主体 / 观众看不到它就无法理解当前论证。前文意象在后文被重新调用时,**不要合并两段文稿**——在后文 beat 里写 `callback_of:"B07"`。
138
+
139
+ ## 自检(落地前)
140
+
141
+ - 有没有机械按句号切?(只在视觉职责变化时切)
142
+ - 有没有任何 beat 同时承担两种主职责?(一个 beat 只允许一个 lane)
143
+ - 有没有把本该真人承接的段落全交给 b-roll?
144
+ - span 里有没有混进 `dropped:true` 的句子?(会被跳过/收缩)
145
+ - beat 之间有没有重叠?id 区间有没有倒序?
146
+ - FILM_BROLL 有没有 queries?RRV_MG 有没有 duration_hint?
147
+ - `transcript_hash` 是不是原样透传自视图?
148
+ - 拆分稿里有没有混进任何秒级时码字段?(必须零时码)