dsh-novel-write-engine 0.0.0-stage → 0.1.1

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,137 @@
1
1
  {
2
2
  "name": "dsh-novel-write-engine",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.1",
4
+ "description": "Novel writing engine for DeepSeek Harness: state machine, gates, rulepacks and ledgers moved from prompts into code.",
5
+ "keywords": [
6
+ "dsh-plugin",
7
+ "deepseek-harness",
8
+ "novel",
9
+ "writing"
10
+ ],
11
+ "homepage": "https://github.com/ThzxxArt/dsh-novel-write-engine#readme",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/ThzxxArt/dsh-novel-write-engine.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/ThzxxArt/dsh-novel-write-engine/issues"
18
+ },
19
+ "type": "module",
20
+ "license": "MIT",
21
+ "packageManager": "pnpm@11.28.9",
22
+ "main": "./lib/index.js",
23
+ "types": "./lib/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./lib/index.d.ts",
27
+ "default": "./lib/index.js"
28
+ },
29
+ "./client": {
30
+ "types": "./lib/types/client/index.d.ts",
31
+ "default": "./lib/client.js"
32
+ },
33
+ "./cordis.patch.yml": "./cordis.patch.yml",
34
+ "./presets/*.patch.yml": "./presets/*.patch.yml",
35
+ "./rulepacks/*": "./rulepacks/*",
36
+ "./briefs/*": "./briefs/*",
37
+ "./skill": "./skills/entry.md",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "lib",
42
+ "presets",
43
+ "rulepacks",
44
+ "briefs",
45
+ "skills",
46
+ "cordis.patch.yml",
47
+ "README.md",
48
+ "LICENSE",
49
+ "CHANGELOG.md"
50
+ ],
51
+ "dsh": {
52
+ "bundle": {
53
+ "patch": [
54
+ "./cordis.patch.yml",
55
+ "./presets/novel-write-engine.patch.yml"
56
+ ]
57
+ },
58
+ "client": {
59
+ "platform": "web",
60
+ "inject": [
61
+ "@deepseek-ai/dsh-client-ui-sidebar",
62
+ "@deepseek-ai/dsh-client-ui-layout"
63
+ ],
64
+ "external": [
65
+ "react",
66
+ "react/jsx-runtime"
67
+ ]
68
+ }
69
+ },
70
+ "engines": {
71
+ "node": ">=24.9.0",
72
+ "dsh": ">=0.2.1-rc.2 <0.3.0-0"
73
+ },
74
+ "scripts": {
75
+ "build": "tsdown && tsdown -c tsdown.client.config.ts && tsc -p tsconfig.client.json",
76
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
77
+ "lint": "eslint . && prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"scripts/**/*.mjs\"",
78
+ "test": "vitest run",
79
+ "test:coverage": "vitest run --coverage && node scripts/check-coverage.mjs",
80
+ "test:isolated": "node scripts/check-isolated.mjs",
81
+ "validate:rulepack": "node scripts/validate-rulepack.mjs",
82
+ "check:preset": "node scripts/check-preset.mjs",
83
+ "check:pack": "node scripts/check-pack.mjs",
84
+ "check:artifacts": "node scripts/check-artifacts.mjs",
85
+ "check:install": "node scripts/check-install.mjs",
86
+ "check:host": "node scripts/check-host.mjs",
87
+ "check:hygiene": "node scripts/check-hygiene.mjs"
88
+ },
89
+ "dependencies": {
90
+ "yaml": "^2.6.0"
91
+ },
92
+ "peerDependencies": {
93
+ "@deepseek-ai/cordis": "^4.0.1",
94
+ "@deepseek-ai/dsh-client-ui-layout": "^0.2.0-rc.1 || ^0.2.1-rc.1",
95
+ "@deepseek-ai/dsh-client-ui-renderer": "^0.2.0-rc.1 || ^0.2.1-rc.1",
96
+ "@deepseek-ai/dsh-client-ui-slots": "^0.2.0-rc.1 || ^0.2.1-rc.1",
97
+ "@deepseek-ai/dsh-skill": "^0.2.0-rc.1 || ^0.2.1-rc.1",
98
+ "@deepseek-ai/schemastery": "^3.18.5",
99
+ "@deepseek-ai/dsh-tools": "^0.2.0-rc.1 || ^0.2.1-rc.1",
100
+ "react": "^18.0.0 || ^19.0.0"
101
+ },
102
+ "peerDependenciesMeta": {
103
+ "@deepseek-ai/dsh-client-ui-layout": {
104
+ "optional": true
105
+ },
106
+ "@deepseek-ai/dsh-client-ui-renderer": {
107
+ "optional": true
108
+ },
109
+ "@deepseek-ai/dsh-client-ui-slots": {
110
+ "optional": true
111
+ },
112
+ "react": {
113
+ "optional": true
114
+ }
115
+ },
116
+ "devDependencies": {
117
+ "@deepseek-ai/cordis": "4.0.5",
118
+ "@deepseek-ai/cordis-plugin-loader": "1.0.3",
119
+ "@deepseek-ai/dsh-agent-preset-registry": "0.2.1-rc.3",
120
+ "@deepseek-ai/dsh-skill": "0.2.1-rc.3",
121
+ "@deepseek-ai/dsh-tools": "0.2.1-rc.3",
122
+ "@deepseek-ai/schemastery": "3.18.5",
123
+ "@types/node": "^22.10.0",
124
+ "@types/react": "^18.3.0",
125
+ "@types/react-dom": "18.3.0",
126
+ "@vitest/coverage-v8": "^3.0.0",
127
+ "eslint": "^9.15.0",
128
+ "happy-dom": "^15.11.0",
129
+ "prettier": "^3.3.0",
130
+ "react": "^18.3.1",
131
+ "react-dom": "18.3.1",
132
+ "tsdown": "^0.22.0",
133
+ "typescript": "^5.6.0",
134
+ "typescript-eslint": "^8.15.0",
135
+ "vitest": "^3.0.0"
136
+ }
137
+ }
@@ -0,0 +1,56 @@
1
+ - insert:
2
+ - id: preset-novel-write-engine
3
+ name: '@deepseek-ai/dsh-agent-preset'
4
+ config:
5
+ id: novel-write-engine
6
+ name: 网文工坊
7
+ description: 网文创作专用会话:18 个小说工具全开,无文件写权限,门控与字数由引擎裁决。
8
+ order: 20
9
+ plugins:
10
+ - id: persona
11
+ name: '@deepseek-ai/dsh-persona'
12
+ config:
13
+ prefix: |-
14
+ 你是「网文工坊」的主笔,一位只认数字与状态的网文作者。
15
+
16
+ - 每章先看状态:novel_status 与 novel_brief 说了什么就按什么做,不凭记忆推测进度。
17
+ - 正文只经 novel_write_draft,改稿只经 novel_revise;归档只走 novel_archive,且必须带 state_delta。没有别的写入口。
18
+ - 字数、引号、格式、门控结论一律以引擎返回为准,不要自己估算,也不要复述旧数字。
19
+ - 评审每一分都要指到具体扣分项;指不出来就不要扣。
20
+ - 设定、前章细节、伏笔状态拿不准就查 novel_state,不许编。
21
+ - { id: time-context, name: '@deepseek-ai/dsh-time-context' }
22
+ - { id: tool-skill, name: '@deepseek-ai/dsh-tool-skill' }
23
+ - { id: tool-ask-user, name: '@deepseek-ai/dsh-tool-ask-user' }
24
+ - {
25
+ id: tool-todo,
26
+ name: '@deepseek-ai/dsh-tool-todo',
27
+ config: { allowParallelInProgress: false },
28
+ }
29
+ - { id: present, name: '@deepseek-ai/dsh-tool-present' }
30
+ - {
31
+ id: tool-web,
32
+ name: '@deepseek-ai/dsh-tool-web',
33
+ config: { fetch: true, searchTimeoutMs: 60000 },
34
+ }
35
+ - id: compaction
36
+ name: cordis:group
37
+ group: true
38
+ isolate: { compaction: true, toolResultPruner: true }
39
+ config:
40
+ - { id: compaction-basic, name: '@deepseek-ai/dsh-compaction-basic' }
41
+ - { id: command-compact, name: '@deepseek-ai/dsh-command-compact' }
42
+ - id: tool-result-pruner
43
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
44
+ config: { thresholdChars: 8192, headChars: 4096, tailChars: 1024 }
45
+ - id: delegation
46
+ name: cordis:group
47
+ group: true
48
+ isolate: { workflowEngine: true }
49
+ config:
50
+ - { id: tool-subagent-control, name: '@deepseek-ai/dsh-tool-subagent-control' }
51
+ - id: tool-subagent
52
+ name: '@deepseek-ai/dsh-tool-subagent'
53
+ config: { provider: spawn, toolName: subagent, modelSelection: true, modelDiscovery: true }
54
+ - id: tool-subagent-fork
55
+ name: '@deepseek-ai/dsh-tool-subagent'
56
+ config: { provider: fork, toolName: subagent_fork }
@@ -0,0 +1,231 @@
1
+ schema_version: 1
2
+ name: default
3
+ version: "1.0.0"
4
+
5
+ lexicon:
6
+ zero_tolerance:
7
+ - { term: "总而言之", note: "AI 套话" }
8
+ - { term: "不可否认", note: "AI 套话" }
9
+ - { term: "不禁", note: "AI 套话" }
10
+ - { term: "仿佛", note: "AI 套话" }
11
+ - { term: "似乎", note: "AI 套话" }
12
+ - { term: "嘴角微微上扬", note: "模板动作" }
13
+ - { term: "眼中闪过一丝", note: "模板表情" }
14
+ - { term: "心中暗道", note: "模板心理" }
15
+ - { term: "殊不知", note: "叙事套话" }
16
+ - { term: "与此同时", note: "转场套话" }
17
+ - { term: "话虽如此", note: "转折套话" }
18
+ - { term: "换句话说", note: "解释套话" }
19
+ - { term: "与此同时的", note: "重复表达" }
20
+ - { term: "油然而生", note: "成语套话" }
21
+ - { term: "不由自主", note: "成语套话" }
22
+ - { term: "若有所思", note: "成语套话" }
23
+ - { term: "意味深长", note: "成语套话" }
24
+ - { term: "哭笑不得", note: "成语套话" }
25
+ - { term: "五味杂陈", note: "成语套话" }
26
+ - { term: "如释重负", note: "成语套话" }
27
+ - { term: "醍醐灌顶", note: "成语套话" }
28
+ - { term: "恍然大悟", note: "成语套话" }
29
+ - { term: "电光火石", note: "成语套话" }
30
+ - { term: "千钧一发", note: "成语套话" }
31
+ - { term: "浑然不觉", note: "成语套话" }
32
+ - { term: "不置可否", note: "成语套话" }
33
+ - { term: "若有所思地", note: "成语套话" }
34
+ - { term: "深吸一口气", note: "模板动作" }
35
+ - { term: "缓缓开口", note: "模板动作" }
36
+ - { term: "淡淡说道", note: "模板台词" }
37
+ - { term: "冷冷地说", note: "模板台词" }
38
+ - { term: "微微一笑", note: "模板动作" }
39
+ - { term: "眉头一皱", note: "模板动作" }
40
+ - { term: "心中一凛", note: "模板心理" }
41
+ - { term: "心头一震", note: "模板心理" }
42
+ - { term: "后背发凉", note: "模板生理" }
43
+ - { term: "头皮发麻", note: "模板生理" }
44
+ - { term: "瞳孔骤缩", note: "模板生理" }
45
+ - { term: "倒吸一口凉气", note: "模板生理" }
46
+ - { term: "空气仿佛凝固", note: "模板环境" }
47
+ - { term: "死一般的寂静", note: "模板环境" }
48
+ - { term: "时间仿佛静止", note: "模板环境" }
49
+ - { term: "命运的齿轮", note: "叙事套话" }
50
+ - { term: "一波未平一波又起", note: "叙事套话" }
51
+ - { term: "说来话长", note: "叙事套话" }
52
+ - { term: "果然不出所料", note: "叙事套话" }
53
+ - { term: "果不其然", note: "叙事套话" }
54
+ - { term: "毫无意外", note: "叙事套话" }
55
+ - { term: "显而易见", note: "叙事套话" }
56
+ - { term: "显而易见地", note: "叙事套话" }
57
+ - { term: "不容置疑", note: "叙事套话" }
58
+ - { term: "毋庸置疑", note: "叙事套话" }
59
+ - { term: "众所周知", note: "元叙述" }
60
+ - { term: "值得一提的是", note: "元叙述" }
61
+ - { term: "需要指出的是", note: "元叙述" }
62
+ - { term: "让我们", note: "读者侵入" }
63
+ - { term: "读者朋友们", note: "读者侵入" }
64
+ - { term: "各位看官", note: "读者侵入" }
65
+ - { term: "话说回来", note: "转场套话" }
66
+ - { term: "另一方面", note: "转场套话" }
67
+ - { term: "正因如此", note: "解释套话" }
68
+ - { term: "正是因为", note: "解释套话" }
69
+
70
+ soft:
71
+ - { term: "犹如", limit: 1 }
72
+ - { term: "宛若", limit: 1 }
73
+ - { term: "宛如", limit: 1 }
74
+ - { term: "仿佛置身", limit: 1 }
75
+ - { term: "瞬间", limit: 3 }
76
+ - { term: "立刻", limit: 4 }
77
+ - { term: "顿时", limit: 4 }
78
+ - { term: "猛地", limit: 3 }
79
+ - { term: "陡然", limit: 2 }
80
+ - { term: "骤然", limit: 2 }
81
+ - { term: "缓缓", limit: 4 }
82
+ - { term: "轻轻", limit: 4 }
83
+ - { term: "微微", limit: 4 }
84
+ - { term: "淡淡", limit: 3 }
85
+ - { term: "冷冷", limit: 3 }
86
+ - { term: "默默", limit: 3 }
87
+ - { term: "静静", limit: 3 }
88
+ - { term: "深深", limit: 3 }
89
+ - { term: "紧紧", limit: 3 }
90
+ - { term: "死死", limit: 2 }
91
+
92
+ contextual:
93
+ - { term: "赋能", limit: 2, genres: [都市现代, 游戏系统] }
94
+ - { term: "闭环", limit: 2, genres: [都市现代, 科幻] }
95
+ - { term: "颗粒度", limit: 1, genres: [都市现代] }
96
+ - { term: "对齐", limit: 2, genres: [都市现代] }
97
+ - { term: "灵根", limit: 6, genres: [玄幻修仙] }
98
+ - { term: "灵气", limit: 8, genres: [玄幻修仙] }
99
+ - { term: "副本", limit: 8, genres: [游戏系统, 无限流] }
100
+ - { term: "系统提示", limit: 6, genres: [游戏系统, 无限流] }
101
+
102
+ meta_narration:
103
+ - { term: "不难看出" }
104
+ - { term: "可以看出" }
105
+ - { term: "由此可见" }
106
+ - { term: "话说" }
107
+ - { term: "且说" }
108
+ - { term: "却说" }
109
+
110
+ reader_intrusion:
111
+ - { pattern: "我们(?:可以)?看(?:到)?(?:这里|下面|接下来|这一幕|这个|这场|这段)" }
112
+ - { pattern: "各位读者" }
113
+ - { pattern: "屏幕前的" }
114
+
115
+ god_view:
116
+ - { pattern: "这注定是" }
117
+ - { pattern: "当时的.{0,4}还不知道" }
118
+ - { pattern: "多年以后" }
119
+ - { pattern: "命运早已" }
120
+
121
+ conclusion_first:
122
+ verbs: [感到, 觉得, 知道, 明白, 意识到, 发现, 察觉]
123
+ causals: [因为, 所以, 于是, 因此, 由于]
124
+
125
+ format:
126
+ paragraph_max_words: 90
127
+ forbid_markdown: true
128
+ forbid_semicolon: true
129
+ forbid_english_ellipsis: true
130
+ title:
131
+ pattern: "^第\\d+章\\s"
132
+ min_chars: 4
133
+ max_chars: 8
134
+ system_labels:
135
+ - "Day\\s*\\d+"
136
+ - "第[0-9一二三四五六七八九十百]+卷"
137
+ - "作者(?:按|说)?"
138
+ - "读者"
139
+ - "书友"
140
+ scene_separators: ["———", "***", "…………"]
141
+ markdown_markers: ["#", "**", "---", ">", "|"]
142
+
143
+ punctuation:
144
+ dash:
145
+ base: { 战斗/动作章: 3, 日常过渡章: 4, 情感爆发章: 6, 纯叙事章: 3 }
146
+ scale_words: 3000
147
+ token: "——"
148
+ period_density: { min: 1.5, max: 8 }
149
+ ellipsis_run: { max: 1, token: "……" }
150
+ uniform_sentence: { min_sentences: 8, ratio: 0.6 }
151
+ consecutive_le: { max: 3, char: "了" }
152
+ dialogue_dominant_ratio: 0.60
153
+
154
+ semantics:
155
+ adjective_density:
156
+ max: 4
157
+ adjectives: [美丽, 漂亮, 英俊, 巨大, 渺小, 愤怒, 悲伤, 开心, 恐怖, 温柔, 冰冷, 炙热, 明亮, 昏暗]
158
+ pleasure_density:
159
+ min: 1
160
+ keywords: [打脸, 逆袭, 震惊, 哗然, 跪, 服气, 反转, 暴涨, 秒杀, 碾压, 掌声, 惊呼, 目瞪口呆, 傻眼]
161
+ window: 600
162
+ sensory_density:
163
+ min: 2
164
+ senses: [看, 听, 闻, 触, 尝, 冷, 热, 香, 臭, 疼, 痒, 麻, 亮, 暗, 声, 响]
165
+ window: 800
166
+ water_words:
167
+ window: 150
168
+ threshold: 0.35
169
+ scene_thresholds:
170
+ 战斗/动作章: 0.25
171
+ 日常过渡章: 0.35
172
+ 情感爆发章: 0.30
173
+ 纯叙事章: 0.40
174
+ terms: [的就是, 的时候, 时候, 一个, 一种, 一些, 这个, 那个, 这样, 那样, 其实, 确实, 真的, 非常, 十分]
175
+
176
+ platform:
177
+ fanqie: { words_per_chapter: [2000, 3000], dialogue_ratio: [0.40, 0.60] }
178
+ qidian: { words_per_chapter: [2000, 3500], dialogue_ratio: [0.30, 0.50] }
179
+ qimao: { words_per_chapter: [1500, 2500], dialogue_ratio: [0.45, 0.65] }
180
+ jinjiang: { words_per_chapter: [2500, 4000], dialogue_ratio: [0.35, 0.55] }
181
+
182
+ genres:
183
+ 玄幻修仙: { note: "力量体系必须自洽;升级要有代价,境界不能靠形容词抬升。" }
184
+ 都市现代: { note: "现实都市,冲突来自资源、关系与规则;爽点要落在可验证的行动上。" }
185
+ 西方奇幻: { note: "种族、语言与力量来源要建条目;奇观不能替代人物选择。" }
186
+ 悬疑推理: { note: "线索先于解答出现;每个伏笔都要在归档台账中可核销。" }
187
+ 科幻: { note: "技术设定只写对情节有用的部分;禁止用术语代替冲突。" }
188
+ 游戏系统: { note: "系统提示是世界观内文本;奖励与惩罚必须可追踪。" }
189
+ 历史架空: { note: "礼制、称谓与器物要经得起基本推敲;不写现代口号。" }
190
+ 无限流: { note: "副本规则先立后破;每次通关都要付出可记账的代价。" }
191
+ 轻小说: { note: "关系推进靠具体互动,不靠内心独白宣布;对话要能区分说话人。" }
192
+ 军事: { note: "战术细节服务于人物选择;不写武器参数清单。" }
193
+ 末世流: { note: "生存资源必须记账;恐惧来自规则崩塌,不靠突然的音效式形容词。" }
194
+ 言情: { note: "亲密关系按阶梯推进;单次独白要短,情绪落在动作上。" }
195
+
196
+ crosschapter:
197
+ duplicate_similarity: 0.9
198
+ duplicate_advisory: 0.75
199
+ duplicate_min_chars: 20
200
+ foreshadow_min_dormancy: 2
201
+ foreshadow_dormant_after: 20
202
+ check_time: true
203
+ lock_similarity: 0.75
204
+
205
+ quality:
206
+ dimensions:
207
+ - { id: R-W-01, max: 15 }
208
+ - { id: R-W-02, max: 10 }
209
+ - { id: R-W-03, max: 10 }
210
+ - { id: R-W-04, max: 20 }
211
+ - { id: R-W-05, max: 15 }
212
+ - { id: R-W-12, max: 20 }
213
+ - { id: R-W-11, max: 10 }
214
+ - { id: R-W-13, max: 15 }
215
+ - { id: R-W-14, max: 10 }
216
+ - { id: R-W-15, max: 10 }
217
+ - { id: R-W-06, max: 4 }
218
+ - { id: R-W-07, max: 4 }
219
+ - { id: R-W-08, max: 4 }
220
+ - { id: R-W-09, max: 2 }
221
+ - { id: R-W-10, max: 1 }
222
+
223
+ exclusions:
224
+ - { pair: [META_NARRATION, LEX_ZERO_TOLERANCE], family: meta }
225
+ - { pair: [READER_INTRUSION, LEX_ZERO_TOLERANCE], family: reader }
226
+ - { pair: [GOD_VIEW, CONCLUSION_FIRST], family: perspective }
227
+ - { pair: [DUPLICATE_PARAGRAPH, FS_REVISITED_TOO_SOON], family: repetition }
228
+ - { pair: [RESOURCE_MISMATCH, TIME_REGRESSION], family: continuity }
229
+ - { pair: [LEX_SOFT_LIMIT, LEX_ZERO_TOLERANCE], family: style }
230
+
231
+ exemptions: []
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: novel-write-engine
3
+ description: 引擎版小说创作流程——状态、门控、字数与写盘入口全部由插件裁决。用于任何「写小说 / 写第 N 章 / 续写 / 改稿 / 归档」任务。
4
+ ---
5
+
6
+ # 网文工坊(引擎版)
7
+
8
+ 你不是在「帮用户写小说」,你是在**驱动一台有状态的引擎**。状态由引擎维护,你只负责内容与调用。
9
+
10
+ ## 六条铁律
11
+
12
+ 1. **先看状态,再动笔。** 任何创作动作前先 `novel_status`;每章开工先 `novel_brief <阶段>`。
13
+ 2. **正文只有两个写入口。** `novel_write_draft`(初稿)与 `novel_revise`(修订)。`novel_amend` 只改状态文档,不写正文;没有第四条路。
14
+ 3. **字数与门控以引擎返回为准。** 不要自己估算字数,不要复述旧数字。
15
+ 4. **评审每一分都要定位。** 指不到「第 N 段」的扣分不要写;证据要逐字引用。
16
+ 5. **不编设定。** 人物、地点、伏笔、资源状态拿不准就 `novel_state` 查。
17
+ 6. **归档是一次事务,且必须核销。** `novel_archive` 必须带 `state_delta`:本章每个角色/伏笔/事件/新设定/关系逐条声明 `created|updated|no_change`;不要手工拼章节索引或交接文件。
18
+
19
+ ## 流程路由
20
+
21
+ | 当前阶段 | 任务书 | 下一动作 |
22
+ | ---------------- | ---------------- | -------------------- |
23
+ | idle | `novel_brief P1` | `novel_plan_world` |
24
+ | P2 | `novel_brief P2` | `novel_plan_chapter` |
25
+ | P3 | `novel_brief P3` | `novel_write_draft` |
26
+ | P4 | `novel_brief P4` | `novel_review` |
27
+ | P5 | `novel_brief P5` | `novel_revise` |
28
+ | P6 | `novel_brief P6` | `novel_check` |
29
+ | ready_to_archive | `novel_brief P8` | `novel_archive` |
30
+ | done | — | 下一章从 P1 开始 |
31
+
32
+ 拿不准就走 `novel_pipeline`,它直接告诉你调什么、传什么。任务书缺失或 digest 过期时,它第一步会返回 `novel_brief`;照它给的 `args` 领取后再继续,不要直接调用被门控的写工具。
33
+
34
+ ## 工具速查
35
+
36
+ | 工具 | 用途 |
37
+ | --- | --- |
38
+ | `novel_init` | 建项目 |
39
+ | `novel_status` | 当前章/阶段/阻塞/下一步 |
40
+ | `novel_brief` | 取阶段任务书与上下文 |
41
+ | `novel_plan_world` | P1 世界观计划 |
42
+ | `novel_plan_chapter` | P2 章节计划 |
43
+ | `novel_write_draft` | P3 初稿 |
44
+ | `novel_review` | P4 十五维评分 |
45
+ | `novel_revise` | P5 修订 |
46
+ | `novel_check` | P6 一致性校验 |
47
+ | `novel_archive` | 归档事务 |
48
+ | `novel_word_count` | 字数口径 |
49
+ | `novel_state` | 只读台账/计划/评审 |
50
+ | `novel_amend` | 受控改状态文档 |
51
+ | `novel_rollback` | 回退阶段 |
52
+ | `novel_diff` | 与备份/文本对比 |
53
+ | `novel_export` | md/txt/epub |
54
+ | `novel_audit` | 事务审计 |
55
+ | `novel_pipeline` | 推荐下一步与参数 |
56
+
57
+ ## 工具怎么用
58
+
59
+ - 参数是 JSON 对象;`summary`、`dimensions`、`issues`、`proof` 是结构化对象,按任务书字段填。
60
+ - `novel_check` 必须带四个语义项(`L2-SCENE-ANCHOR` / `L2-CHARACTER-STATE` / `L2-CAUSALITY` / `L2-VOICE`),每项都要有正文逐字引用;缺一项即校验不过。
61
+ - 失败分三类:参数错(改参数)、门控没过(改正文)、系统故障(查目录/稍后重试)。错误消息里的 code 说明属于哪类。
62
+ - 门控失败会一次列出**全部**阻塞项;一次改完再交,不要逐条试。
63
+
64
+ ## 交付
65
+
66
+ - 每章归档后,用户在面板「网文工坊」看到章节表与阻塞区。
67
+ - 导出:`novel_export md|txt|epub`。
68
+ - 不要在对话里重复整章正文;工具结果已经可见。