@lingjingai/scriptctl 0.63.19 → 0.64.0
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/README.md +62 -2
- package/changes/0.63.20.md +20 -0
- package/changes/0.64.0.md +16 -0
- package/dist/bin.js +1 -1
- package/dist/chunk-5T4VIFJR.js +984 -0
- package/dist/cli.d.ts +18 -3
- package/dist/cli.js +1 -1
- package/dist/review-agent.js +70 -56
- package/package.json +25 -21
- package/skills/scriptctl/SKILL.md +17 -4
- package/skills/scriptctl/references/ingest-workflow.md +19 -3
- package/dist/chunk-YOCQDDQC.js +0 -823
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingjingai/scriptctl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.0",
|
|
4
4
|
"description": "剧本阶段统一 CLI:素材转 Script v4,并兼容 Script v3 的本地写作、精修、校验和发布。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -22,6 +22,20 @@
|
|
|
22
22
|
"engines": {
|
|
23
23
|
"node": ">=22.22.0"
|
|
24
24
|
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "pnpm run clean && pnpm --filter @lingjingai/screenplay build && pnpm --filter @lingjingai/review-agent build && tsc && node scripts/bundle.mjs",
|
|
27
|
+
"clean": "rm -rf dist packages/screenplay/dist packages/review-agent/dist",
|
|
28
|
+
"postinstall": "node scripts/install-skill.mjs",
|
|
29
|
+
"install-skill": "node scripts/install-skill.mjs",
|
|
30
|
+
"prepublishOnly": "pnpm run build",
|
|
31
|
+
"pretest": "pnpm run build",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"pretest:coverage": "pnpm run build",
|
|
34
|
+
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov --report-dir=coverage vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"surface:snapshot": "node scripts/scriptctl-surface-snapshot.mjs"
|
|
38
|
+
},
|
|
25
39
|
"dependencies": {
|
|
26
40
|
"@anthropic-ai/sdk": "^0.111.0",
|
|
27
41
|
"@google/genai": "^2.11.0",
|
|
@@ -32,22 +46,26 @@
|
|
|
32
46
|
"https-proxy-agent": "^9.1.0",
|
|
33
47
|
"jszip": "^3.10.1",
|
|
34
48
|
"nanoid": "^5.1.16",
|
|
49
|
+
"pdf-lib": "^1.17.1",
|
|
35
50
|
"proper-lockfile": "^4.1.2",
|
|
36
51
|
"undici": "^7.16.0",
|
|
37
|
-
"yaml": "^2.8.1"
|
|
52
|
+
"yaml": "^2.8.1",
|
|
53
|
+
"zod": "^4.5.4"
|
|
38
54
|
},
|
|
39
55
|
"devDependencies": {
|
|
56
|
+
"@lingjingai/review-agent": "workspace:*",
|
|
57
|
+
"@lingjingai/screenplay": "workspace:*",
|
|
58
|
+
"@types/jsdom": "^30.0.0",
|
|
40
59
|
"@types/node": "^20.14.0",
|
|
41
60
|
"@types/proper-lockfile": "^4.1.4",
|
|
42
61
|
"c8": "^11.0.0",
|
|
43
62
|
"esbuild": "^0.28.2",
|
|
44
63
|
"javascript-obfuscator": "^5.7.0",
|
|
64
|
+
"jsdom": "^30.1.0",
|
|
45
65
|
"rollup": "^4.63.2",
|
|
46
66
|
"rollup-plugin-dts": "^6.5.1",
|
|
47
67
|
"typescript": "^5.5.0",
|
|
48
|
-
"vitest": "^2.0.0"
|
|
49
|
-
"@lingjingai/review-agent": "0.1.0",
|
|
50
|
-
"@lingjingai/screenplay": "0.1.0"
|
|
68
|
+
"vitest": "^2.0.0"
|
|
51
69
|
},
|
|
52
70
|
"keywords": [
|
|
53
71
|
"scriptctl",
|
|
@@ -63,20 +81,6 @@
|
|
|
63
81
|
"@ai-sdk/google": "^4.0.63",
|
|
64
82
|
"@ai-sdk/openai-compatible": "^3.0.48",
|
|
65
83
|
"@ai-sdk/provider": "^4.0.4",
|
|
66
|
-
"@mastra/core": "^1.64.0"
|
|
67
|
-
"zod": "^4.5.4"
|
|
68
|
-
},
|
|
69
|
-
"scripts": {
|
|
70
|
-
"build": "pnpm run clean && pnpm --filter @lingjingai/screenplay build && pnpm --filter @lingjingai/review-agent build && tsc && node scripts/bundle.mjs",
|
|
71
|
-
"clean": "rm -rf dist packages/screenplay/dist packages/review-agent/dist",
|
|
72
|
-
"postinstall": "node scripts/install-skill.mjs",
|
|
73
|
-
"install-skill": "node scripts/install-skill.mjs",
|
|
74
|
-
"pretest": "pnpm run build",
|
|
75
|
-
"test": "vitest run",
|
|
76
|
-
"pretest:coverage": "pnpm run build",
|
|
77
|
-
"test:coverage": "c8 --reporter=text --reporter=html --reporter=lcov --report-dir=coverage vitest run",
|
|
78
|
-
"test:watch": "vitest",
|
|
79
|
-
"typecheck": "tsc --noEmit",
|
|
80
|
-
"surface:snapshot": "node scripts/scriptctl-surface-snapshot.mjs"
|
|
84
|
+
"@mastra/core": "^1.64.0"
|
|
81
85
|
}
|
|
82
|
-
}
|
|
86
|
+
}
|
|
@@ -14,7 +14,7 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
Agent 直接运行命令并阅读结果就是正常用法,默认文本输出即为给人和给 agent 看的形态。
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
原创建稿、外部剧本导入、视频拉片和漫画转录均遵循 [人物身份与剧情外貌阶段](references/production-writing-standard.md#人物身份与剧情外貌阶段):角色身份与当前外貌阶段分开表达,阶段变化及回忆按剧情绑定。
|
|
18
18
|
|
|
19
19
|
## 地址
|
|
20
20
|
|
|
@@ -210,6 +210,7 @@ scriptctl ingest -s <素材> -w <workspace> # 素材转 Script v4
|
|
|
210
210
|
scriptctl synopsis generate -p "$S" --apply # LLM 补全剧与分集梗概
|
|
211
211
|
scriptctl audit-assets -p "$S" # LLM 全剧资产一致性审计
|
|
212
212
|
scriptctl review -p "$S" -s <视频目录> # 派发 agent 逐集审核并修正
|
|
213
|
+
scriptctl review -p "$S" -s <漫画ingest工作区> # 对照 PDF 逐话审核并修正
|
|
213
214
|
scriptctl create --title "…" -p "$S" # 从零建空剧本
|
|
214
215
|
scriptctl view -w <workspace> # 渲染或起审阅页
|
|
215
216
|
scriptctl checkout / status / publish # 远端工作副本
|
|
@@ -217,7 +218,9 @@ scriptctl checkout / status / publish # 远端工作副本
|
|
|
217
218
|
|
|
218
219
|
`ingest` 见 [references/ingest-workflow.md](references/ingest-workflow.md)。
|
|
219
220
|
|
|
220
|
-
`ingest`
|
|
221
|
+
单个 PDF 或分话 PDF 目录自动进入漫画 ingest;`--step` 完成下一话,重跑续接已接受进度。漫画正文通过 `extend.scriptctl.source` 保存原 PDF 页码及画格/气泡/文字区域,`view` 可点击正文定位并高亮原页区域。文档模型通过 `ingest.comic-serial` 配置,内置路由为 NNYYAI `gemini-3.8-flash`,使用 `NNYYAI_API_KEY`、base64 PDF 与 `responseSchema`。
|
|
222
|
+
|
|
223
|
+
`ingest` 的 Gemini 文本、结构化工具、视频和 PDF 文档请求先用配置的主模型,再按 3.8 Flash →
|
|
221
224
|
3.7 Flash → 3.6 Flash 补齐未试模型,全部失败后使用豆包。Gemini 按 provider 的
|
|
222
225
|
`maxAttempts` 重试暂时性错误,豆包最多尝试 3 次;明确拒绝时换模型,用户取消时停止。
|
|
223
226
|
豆包需要 `ARK_API_KEY`,`ARK_MODEL` 可指定端点。
|
|
@@ -227,12 +230,12 @@ scriptctl checkout / status / publish # 远端工作副本
|
|
|
227
230
|
|
|
228
231
|
逐集审核同时明确动作叙述的人物指代:依据资产、上下文与原片证据,将可确认的称呼、别名和代词写成资产正式名;普通词义、台词和画面文字原文保留,歧义记 unresolved。全剧收敛核对人物合并、更名后的叙述名称一致性。具体边界见 [references/video-transcript-repair.md](references/video-transcript-repair.md)。
|
|
229
232
|
|
|
230
|
-
`.review/asr/episode-N/` 保存成功 ASR 缓存及每次对比的正文、原始响应、前后时间与缺漏报告。源视频经 ffprobe 确认无音轨时,发出 `asr-skipped`(`reason=source_no_audio`),保留台词与时间并继续画面审核;分集结果保留“ASR 校时未执行”的未解决项,说明无法核验实际发声时间、漏词或无字幕画外音。探测、解码及服务错误仍作为失败集处理。`asr-compared` 仅表示对比完成,带 `episode_number` 的 `asr-applied` 表示本集校时已落盘,不等于 Agent 审核完成。`--episodes` 只重跑指定集的 ASR 和审核,`--converge-only`
|
|
233
|
+
`.review/asr/episode-N/` 保存成功 ASR 缓存及每次对比的正文、原始响应、前后时间与缺漏报告。源视频经 ffprobe 确认无音轨时,发出 `asr-skipped`(`reason=source_no_audio`),保留台词与时间并继续画面审核;分集结果保留“ASR 校时未执行”的未解决项,说明无法核验实际发声时间、漏词或无字幕画外音。探测、解码及服务错误仍作为失败集处理。`asr-compared` 仅表示对比完成,带 `episode_number` 的 `asr-applied` 表示本集校时已落盘,不等于 Agent 审核完成。`--episodes` 只重跑指定集的 ASR 和审核,`--converge-only` 只做全剧收敛。纯剧本和原文对照审核不执行 ASR;`--check` 不发模型请求。
|
|
231
234
|
|
|
232
235
|
审核 Agent、ASR 文本比对和原片核对先使用所选 Gemini,再按 3.8 / 3.7 / 3.6 Flash 尝试其余模型,最后进入豆包。Gemini 沿用 provider 的 `maxAttempts`,豆包最多尝试三次;使用 `ARK_API_KEY` 和可选 `ARK_MODEL`。模型切换发生在当前调用内,保留成功工具操作;原片核对复用同一片段,响应和用量按实际模型记录。
|
|
233
236
|
|
|
234
237
|
`review` 一个进程审完整本剧:剧本只解析一次进内存,按集扇出,最后单线程做全剧收敛。
|
|
235
|
-
给 `-s`
|
|
238
|
+
给 `-s` 按来源选择文本、漫画或视频核对,不给就检查剧本内部一致性,
|
|
236
239
|
媒体工具不注册。每集**先落盘再输出**一行 NDJSON 到 stdout(`{"type":"episode",…}`,末行
|
|
237
240
|
`{"type":"done",…}`)——收到一行就代表那一集的修改已经在文件里,中途挂掉只丢没报告的集。
|
|
238
241
|
`--episodes 3,7` 续跑指定集,`--converge-only` 只做全剧收敛,`--concurrency` 控同时在飞的集数,`--check` 只验模型与
|
|
@@ -240,6 +243,16 @@ agent 是否就绪。**Agent 不要自己调 `review` 去审自己正在改的
|
|
|
240
243
|
agent 并直接改文件。
|
|
241
244
|
抽帧工具的时间参数始终是 JSON 数组,单帧也一样;参数调用错误回传给审核 agent 修正,不作为图片结果处理,也不据此把整集标记完成。
|
|
242
245
|
|
|
246
|
+
漫画 review 的 `-s` 支持漫画 ingest 工作区,或原 PDF 文件/目录(剧本旁需有 ingest `manifest.json`)。通过 `document_id` 和 PDF SHA-256 核实来源,保留 Script v4 的页码/区域扩展字段。默认 `review-comic` profile 走 NNYYAI,需要 `NNYYAI_API_KEY`;自定义 LLM 配置需定义该 profile 或用 `--model` 显式指定。`--episodes` 只要求所选话的 PDF,`--converge-only` 仅处理全局身份与资产一致性。
|
|
247
|
+
|
|
248
|
+
漫画 Agent 使用原页及局部图片逐页检查遗漏,再对照 action 核对正文、说话人、心声类别、顺序和来源。需要 `pdftoppm`;图片在 `review-pages/`,结果在 `.review/comic/episode-N.json` 和 `global.json`。新增 action 同时写来源,跨页引用保留全部页与区域。`viewed_pages` 只记录图片已加载;未看完整页集会留下 unresolved,不能据此宣称整话通过。漫画不生成时间戳,不执行 ASR;运行由 `--max-steps` 和 `--episode-timeout-ms` 限制。视频保留原有 ASR、校时和媒体预算流程。
|
|
249
|
+
|
|
250
|
+
纯剧本使用独立的审核指令与剧本工具:检查内部结构、引用和设定冲突,不要求时间戳;需要外部事实才能判定的内容保持 unresolved。`review --check` 的 `review_kind` 明确本次选择 script / text / comic / video。
|
|
251
|
+
|
|
252
|
+
文本 review 的 `-s` 指向文本 ingest 工作区,或对应的 txt/md/docx(剧本旁需有完整工作区)。原文快照为 `pass1/source.txt`,通过 manifest 的 SHA-256 核验;既有 v4 产物按 `v4_identity_map.json`、`pass1/body_start.json` 恢复原文位置。保留这些文件,不按正文相似度或当前 action 序号猜来源。默认 `review-text` profile 使用官方 Gemini,`--model` 可显式选择已有 profile。
|
|
253
|
+
|
|
254
|
+
文本 Agent 先用 `text_range` 顺序读本集原文检查遗漏,再以 `source` / `search_source` 反查 action。来源是完整规范化原文的 1-based 闭区间,保存于 `extend.scriptctl.source.ranges`(`start_line` / `end_line`)。ingest 提供 chunk 级候选窗口,需读原文确认;台词保持原语言,动作允许忠实的简体中文转述。插入遗漏内容必须同时绑定原文。`.review/text/episode-N.json` 和 `global.json` 保存结论与已读/未读行窗口,加载不代表正确,未读完整保留 unresolved。
|
|
255
|
+
|
|
243
256
|
## 版本边界
|
|
244
257
|
|
|
245
258
|
读取 `script.json.version`:`4` 是新建与 ingest 的默认方言,`3` 是线上既有项目的
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
# ingest workflow — 素材直转入库(文本 /
|
|
1
|
+
# ingest workflow — 素材直转入库(文本 / 视频 / 漫画)
|
|
2
2
|
|
|
3
|
-
适用:有外部素材要**转成 Script v4 并入库**。统一入口 `scriptctl ingest`,按 source 类型自动分流文本 /
|
|
3
|
+
适用:有外部素材要**转成 Script v4 并入库**。统一入口 `scriptctl ingest`,按 source 类型自动分流文本 / 视频 / 漫画;各管线最终都产出 v4 `script.json`。视频、小说和非标准剧本统一执行 [production-writing-standard.md](production-writing-standard.md)。
|
|
4
4
|
|
|
5
5
|
```
|
|
6
6
|
ingest -s <file|dir> → 标准化复核 → view / ingest status → publish
|
|
7
7
|
(抽取,产 workspace/script.json) (内容完成门) (自查/看进度) (校验+入库)
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
-
- 支持输入:**文本** txt / md / docx;**视频** 单个正片文件或**分集目录**(默认凭证为 `GEMINI_API_KEY`,也可用下文 provider 参数覆盖)。编号分集目录必须组成从第 1 集开始、无缺集的 `1..N`
|
|
10
|
+
- 支持输入:**文本** txt / md / docx;**视频** 单个正片文件或**分集目录**(默认凭证为 `GEMINI_API_KEY`,也可用下文 provider 参数覆盖)。编号分集目录必须组成从第 1 集开始、无缺集的 `1..N` 连续序列。**漫画** 单个 PDF 或分话 PDF 目录自动进入漫画流程,按来源话号排序,支持第 00 话。PDF 与视频混合的目录会被拒绝;json/xlsx 不支持。
|
|
11
11
|
- `ingest` **不入库**:只产 `workspace/script.json`(默认工作区 `workspace`,可 `-w` 改)。入库是独立的 `publish`。
|
|
12
12
|
- 产物随后就是普通剧本:任何读写动词加 `-p workspace/script.json` 即可精修。
|
|
13
13
|
|
|
@@ -20,6 +20,22 @@ scriptctl ingest -s uploads/剧本.docx
|
|
|
20
20
|
scriptctl ingest -s uploads/正片/
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
### 漫画 PDF
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
scriptctl ingest -s 漫画目录/ -w workspace --step
|
|
27
|
+
scriptctl ingest -s 漫画目录/ -w workspace
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
每个 PDF 是一话,整话连续阅读;内部 episode 按阅读顺序编号,来源文件名和话号保留在标题及 manifest。
|
|
31
|
+
逐话维护人物身份、持续造型和剧情上下文。`--step` 只接受下一话,同源同工作区重跑从失败话续接,支持尾部追加。
|
|
32
|
+
模型通过 `ingest.comic-serial` 路由配置,内置为 NNYYAI `gemini-3.8-flash`(`NNYYAI_API_KEY`),通过 base64 直接提交 PDF 并使用 `responseSchema`。失败后在同一 NNYYAI 渠道按 3.8 / 3.7 / 3.6 Flash 补齐未尝试模型,最后使用豆包 PDF 理解(`ARK_API_KEY`、可选 `ARK_MODEL`)。自定义 PDF provider 可设置 `documentUploadMode`(`file-api` / `base64`)和 `documentResponseSchemaField`(`responseJsonSchema` / `responseSchema`)。模型切换保留同一 PDF 与 Schema,用户取消立即停止,实际模型与用量进入账本;每个文件最多 50 MB、1000 页。模型输入副本 `ep/*.input.pdf` 带坐标网格,帮助定位长条页内区域;原 PDF 和审阅图保持原样。
|
|
33
|
+
每条 action 用 `extend.scriptctl.source` 保存 `document_id`、`pages` 和 `regions`。每个 region 包含物理页码 `page`、区域类型 `kind`(`panel` / `bubble` / `text`)及 `box`(`top/left/bottom/right`,相对完整物理页归一化为 0–1000)。分离的画格和跨页气泡可关联多个区域。
|
|
34
|
+
对白、心声和画面文字保留原文;动作叙述使用简体中文。页码覆盖和 Script 校验通过后才接受本话,仍需对照原页抽查漏格、说话人及小字。
|
|
35
|
+
`ep/*.response.json` 保留模型响应;`checkpoint.json` 原子保存已接受上下文和身份映射;`context.json` 供阅读。
|
|
36
|
+
`scriptctl view -w workspace` 使用 Poppler(`pdftoppm`)把已转录话的 PDF 渲染为本地原页图片,按来源哈希缓存到 `review-pages/`,生成漫画与正文并排的审阅页。
|
|
37
|
+
点击正文卡片或来源标签,自动滚动并高亮对应画格、气泡或文字区域;点击原页区域回到对应正文。多个区域可分别点击,浏览器地址保留正文、页码和区域,刷新可恢复位置。只有页码的来源会明确显示「仅页码」。
|
|
38
|
+
|
|
23
39
|
### 视频分批追加
|
|
24
40
|
|
|
25
41
|
分集目录可以只放前几集先跑;后续把连续的新集加到同一目录,再对同一 workspace
|