@waterwx/dsh-novel-forge 2.0.0-alpha.1 → 2.0.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.
Files changed (206) hide show
  1. package/README.md +286 -285
  2. package/lib/client.js +19561 -19439
  3. package/lib/index.js +8159 -4456
  4. package/lib/types/action-guard.d.ts +61 -0
  5. package/lib/types/ai-scan.d.ts +0 -6
  6. package/lib/types/assets.d.ts +20 -9
  7. package/lib/types/assistant.d.ts +29 -0
  8. package/lib/types/author-assets.d.ts +1 -3
  9. package/lib/types/bookshelf.d.ts +13 -3
  10. package/lib/types/client/api.d.ts +136 -27
  11. package/lib/types/client/chip-prefs.d.ts +36 -0
  12. package/lib/types/client/docx.d.ts +2 -2
  13. package/lib/types/client/llmLive.d.ts +31 -0
  14. package/lib/types/client/locales.d.ts +15 -70
  15. package/lib/types/client/mount.d.ts +0 -2
  16. package/lib/types/client/panel/AiTag.d.ts +1 -0
  17. package/lib/types/client/panel/AssistantTab.d.ts +4 -1
  18. package/lib/types/client/panel/AuthorHome.d.ts +13 -11
  19. package/lib/types/client/panel/BookAnalysisView.d.ts +4 -0
  20. package/lib/types/client/panel/CmdPalette.d.ts +12 -0
  21. package/lib/types/client/panel/CreateBookView.d.ts +5 -1
  22. package/lib/types/client/panel/DirectorView.d.ts +7 -0
  23. package/lib/types/client/panel/IdeaInspirationView.d.ts +6 -0
  24. package/lib/types/client/panel/KnowledgeBaseView.d.ts +4 -0
  25. package/lib/types/client/panel/LiveFeedLog.d.ts +13 -0
  26. package/lib/types/client/panel/MarketRadarView.d.ts +5 -0
  27. package/lib/types/client/panel/ModelManager.d.ts +2 -2
  28. package/lib/types/client/panel/NovelPanel.d.ts +6 -1
  29. package/lib/types/client/panel/PageHeader.d.ts +18 -0
  30. package/lib/types/client/panel/PromptSlotsView.d.ts +11 -0
  31. package/lib/types/client/panel/SettingsView.d.ts +12 -9
  32. package/lib/types/client/panel/ShelfView.d.ts +10 -1
  33. package/lib/types/client/panel/SubPage.d.ts +27 -0
  34. package/lib/types/client/panel/TensionView.d.ts +18 -0
  35. package/lib/types/client/panel/TimelineView.d.ts +18 -0
  36. package/lib/types/client/panel/helpers.d.ts +5 -3
  37. package/lib/types/client/panel/market-radar-state.d.ts +56 -0
  38. package/lib/types/client/panel/toast.d.ts +2 -0
  39. package/lib/types/client/panel/views.d.ts +21 -35
  40. package/lib/types/client/run-status.d.ts +21 -0
  41. package/lib/types/client/sidebar-entry.d.ts +0 -2
  42. package/lib/types/docx-core.d.ts +16 -0
  43. package/lib/types/docx.d.ts +2 -3
  44. package/lib/types/engine.d.ts +78 -103
  45. package/lib/types/global-assets.d.ts +6 -0
  46. package/lib/types/home.d.ts +11 -0
  47. package/lib/types/index.d.ts +26 -12
  48. package/lib/types/llm-live.d.ts +70 -0
  49. package/lib/types/llm-retry.d.ts +38 -0
  50. package/lib/types/market-radar-scan.d.ts +18 -0
  51. package/lib/types/market-radar-sources.d.ts +31 -0
  52. package/lib/types/migrate-output.d.ts +25 -0
  53. package/lib/types/model-capability.d.ts +93 -0
  54. package/lib/types/output-budget.d.ts +86 -0
  55. package/lib/types/prompt-slots.d.ts +57 -0
  56. package/lib/types/prompting.d.ts +10 -0
  57. package/lib/types/protocol.d.ts +816 -601
  58. package/lib/types/revision.d.ts +76 -0
  59. package/lib/types/routes.d.ts +9 -3
  60. package/lib/types/run.d.ts +23 -1
  61. package/lib/types/settings-persist.d.ts +59 -0
  62. package/lib/types/snapshots.d.ts +46 -0
  63. package/lib/types/stage-contract.d.ts +58 -0
  64. package/lib/types/tension.d.ts +53 -0
  65. package/lib/types/timeline.d.ts +37 -0
  66. package/package.json +50 -25
  67. package/src/action-guard.ts +127 -0
  68. package/src/ai-scan.ts +0 -24
  69. package/src/assets.ts +1801 -879
  70. package/src/assistant.ts +1098 -770
  71. package/src/author-assets.ts +131 -147
  72. package/src/bookshelf.ts +193 -167
  73. package/src/client/api.ts +767 -617
  74. package/src/client/chip-prefs.ts +121 -0
  75. package/src/client/docx.ts +32 -69
  76. package/src/client/index.ts +2 -0
  77. package/src/client/llmLive.ts +111 -0
  78. package/src/client/locales.ts +15 -274
  79. package/src/client/mount.tsx +3 -2
  80. package/src/client/panel/AdaptModeView.tsx +535 -520
  81. package/src/client/panel/AiTag.tsx +7 -0
  82. package/src/client/panel/AssetsTab.tsx +448 -458
  83. package/src/client/panel/AssistantTab.tsx +355 -301
  84. package/src/client/panel/AuthorAssetsView.tsx +205 -207
  85. package/src/client/panel/AuthorHome.tsx +309 -204
  86. package/src/client/panel/BookAnalysisView.tsx +63 -0
  87. package/src/client/panel/CmdPalette.tsx +102 -0
  88. package/src/client/panel/CreateBookView.tsx +366 -352
  89. package/src/client/panel/DirectorView.tsx +200 -0
  90. package/src/client/panel/GlobalAssetLibraryView.tsx +168 -172
  91. package/src/client/panel/IdeaInspirationView.tsx +76 -0
  92. package/src/client/panel/ImportModal.tsx +302 -302
  93. package/src/client/panel/KnowledgeBaseView.tsx +125 -0
  94. package/src/client/panel/LiveFeedLog.tsx +204 -0
  95. package/src/client/panel/MarketRadarView.tsx +415 -0
  96. package/src/client/panel/ModelManager.tsx +205 -205
  97. package/src/client/panel/NovelPanel.tsx +3144 -2205
  98. package/src/client/panel/PageHeader.tsx +37 -0
  99. package/src/client/panel/ProgressConsole.tsx +63 -64
  100. package/src/client/panel/PromptSlotsView.tsx +97 -0
  101. package/src/client/panel/ReaderView.tsx +306 -306
  102. package/src/client/panel/RunPanel.tsx +56 -24
  103. package/src/client/panel/SettingsView.tsx +175 -106
  104. package/src/client/panel/ShelfView.tsx +63 -39
  105. package/src/client/panel/SubPage.tsx +42 -0
  106. package/src/client/panel/TensionView.tsx +212 -0
  107. package/src/client/panel/TimelineView.tsx +208 -0
  108. package/src/client/panel/WorldTab.tsx +202 -202
  109. package/src/client/panel/helpers.ts +7 -5
  110. package/src/client/panel/market-radar-state.ts +79 -0
  111. package/src/client/panel/panel.module.css +5767 -4360
  112. package/src/client/panel/toast.ts +51 -0
  113. package/src/client/panel/views.tsx +316 -314
  114. package/src/client/run-status.ts +171 -0
  115. package/src/client/sidebar-entry.ts +3 -3
  116. package/src/docx-core.ts +53 -0
  117. package/src/docx.ts +44 -83
  118. package/src/engine.ts +1197 -1638
  119. package/src/global-assets.ts +58 -0
  120. package/src/home.ts +33 -0
  121. package/src/index.ts +181 -101
  122. package/src/llm-live.ts +245 -0
  123. package/src/llm-retry.ts +77 -0
  124. package/src/market-radar-scan.ts +35 -0
  125. package/src/market-radar-sources.ts +173 -0
  126. package/src/migrate-output.ts +76 -0
  127. package/src/model-capability.ts +215 -0
  128. package/src/novel-context.ts +286 -287
  129. package/src/output-budget.ts +147 -0
  130. package/src/prompt-slots.ts +125 -0
  131. package/src/prompting.ts +26 -0
  132. package/src/protocol.ts +835 -614
  133. package/src/revision.ts +283 -0
  134. package/src/routes.ts +1286 -910
  135. package/src/run.ts +113 -17
  136. package/src/settings-persist.ts +114 -0
  137. package/src/snapshots.ts +174 -0
  138. package/src/stage-contract.ts +186 -0
  139. package/src/tension.ts +251 -0
  140. package/src/timeline.ts +159 -0
  141. package/assets/styles/arcane-thick-3d.webp +0 -0
  142. package/assets/styles/chinese-ink.webp +0 -0
  143. package/assets/styles/clay-stopmotion-3d.webp +0 -0
  144. package/assets/styles/dark-ghibli.webp +0 -0
  145. package/assets/styles/dark-gothic-3d.webp +0 -0
  146. package/assets/styles/film-photo.webp +0 -0
  147. package/assets/styles/guofeng-heavy.webp +0 -0
  148. package/assets/styles/guoman-2d-gufeng.webp +0 -0
  149. package/assets/styles/guoman-3d-tianyuan.webp +0 -0
  150. package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
  151. package/assets/styles/horror-game-3d.webp +0 -0
  152. package/assets/styles/hyperreal-3d.webp +0 -0
  153. package/assets/styles/japan-cel-dark.webp +0 -0
  154. package/assets/styles/korean-webtoon.webp +0 -0
  155. package/assets/styles/low-cyberpunk-3d.webp +0 -0
  156. package/assets/styles/nextgen-cg.webp +0 -0
  157. package/assets/styles/noir-film.webp +0 -0
  158. package/assets/styles/openworld-survival.webp +0 -0
  159. package/assets/styles/paper-cut-3d.webp +0 -0
  160. package/assets/styles/pixar-adult-3d.webp +0 -0
  161. package/assets/styles/pop-marvel-2d.webp +0 -0
  162. package/assets/styles/sandiao-qban.webp +0 -0
  163. package/assets/styles/shinkai-anime.webp +0 -0
  164. package/assets/styles/tactical-stealth.webp +0 -0
  165. package/assets/styles/urban-lightreal-3d.webp +0 -0
  166. package/assets/styles/vaporwave-3d.webp +0 -0
  167. package/assets/styles/vhs90.webp +0 -0
  168. package/lib/types/client/panel/BookshelfBar.d.ts +0 -11
  169. package/lib/types/client/panel/FlowGuide.d.ts +0 -22
  170. package/lib/types/client/panel/MangaRoleLibrary.d.ts +0 -20
  171. package/lib/types/client/panel/MangaWorkspace.d.ts +0 -12
  172. package/lib/types/client/panel/ModelPicker.d.ts +0 -11
  173. package/lib/types/client/panel/ProgressHomeView.d.ts +0 -5
  174. package/lib/types/client/panel/PropLibrary.d.ts +0 -8
  175. package/lib/types/client/panel/SceneLibrary.d.ts +0 -16
  176. package/lib/types/client/panel/StoryboardTab.d.ts +0 -19
  177. package/lib/types/client/panel/StyleCard.d.ts +0 -8
  178. package/lib/types/client/panel/StyleGallery.d.ts +0 -1
  179. package/lib/types/comic-presets.d.ts +0 -12
  180. package/lib/types/manga-genre-rules.d.ts +0 -22
  181. package/lib/types/prompt-utils.d.ts +0 -35
  182. package/lib/types/review-policy.d.ts +0 -97
  183. package/lib/types/shot-language.d.ts +0 -46
  184. package/lib/types/story-beat-language.d.ts +0 -35
  185. package/lib/types/style-library.d.ts +0 -33
  186. package/skills/chapter-batch/SKILL.md +0 -81
  187. package/src/client/mount.tsx._new +0 -97
  188. package/src/client/mount.tsx._nf +0 -97
  189. package/src/client/mount.tsx._tmp +0 -97
  190. package/src/client/panel/BookshelfBar.tsx +0 -170
  191. package/src/client/panel/FlowGuide.tsx +0 -84
  192. package/src/client/panel/MangaRoleLibrary.tsx +0 -1002
  193. package/src/client/panel/MangaWorkspace.tsx +0 -715
  194. package/src/client/panel/ProgressHomeView.tsx +0 -87
  195. package/src/client/panel/PropLibrary.tsx +0 -175
  196. package/src/client/panel/SceneLibrary.tsx +0 -453
  197. package/src/client/panel/StoryboardTab.tsx +0 -472
  198. package/src/client/panel/StyleCard.tsx +0 -90
  199. package/src/client/panel/StyleGallery.tsx +0 -58
  200. package/src/comic-presets.ts +0 -67
  201. package/src/manga-genre-rules.ts +0 -87
  202. package/src/prompt-utils.ts +0 -73
  203. package/src/review-policy.ts +0 -161
  204. package/src/shot-language.ts +0 -181
  205. package/src/story-beat-language.ts +0 -130
  206. package/src/style-library.ts +0 -84
package/src/protocol.ts CHANGED
@@ -4,16 +4,6 @@
4
4
  * state file format, and the NDJSON generation stream frames all live here so
5
5
  * both halves spell exactly one vocabulary.
6
6
  */
7
- import type {
8
- ShotSizeId,
9
- CameraMoveId,
10
- CompositionId,
11
- LightingId,
12
- } from './shot-language.ts'
13
- import type {
14
- StoryFunctionId,
15
- EmotionId,
16
- } from './story-beat-language.ts'
17
7
 
18
8
  /** The /api/dsh-novel-forge route family (same-origin, loopback-fenced). */
19
9
  export const NOVEL_API = {
@@ -25,6 +15,34 @@ export const NOVEL_API = {
25
15
  bible: '/api/dsh-novel-forge/bible',
26
16
  assets: '/api/dsh-novel-forge/assets',
27
17
  styleEngine: '/api/dsh-novel-forge/style-engine',
18
+ styleFormula: '/api/dsh-novel-forge/style-formula',
19
+ styleDetect: '/api/dsh-novel-forge/style-detect',
20
+ knowledge: '/api/dsh-novel-forge/knowledge',
21
+ bookAnalysis: '/api/dsh-novel-forge/book-analysis',
22
+ ideaInspiration: '/api/dsh-novel-forge/idea-inspiration',
23
+ ideaInspirationMarket: '/api/dsh-novel-forge/idea-inspiration/market',
24
+ director: '/api/dsh-novel-forge/director',
25
+ directorTodos: '/api/dsh-novel-forge/director/todos',
26
+ llmLive: '/api/dsh-novel-forge/llm-live/stream',
27
+ /** 查看某次调用实际发送的 Prompt(按 sessionId)。 */
28
+ llmPrompt: '/api/dsh-novel-forge/llm-live/prompt',
29
+ /** 清零本次运行的用量账本。 */
30
+ usageReset: '/api/dsh-novel-forge/usage/reset',
31
+ /** 章节历史版本(快照)。 */
32
+ snapshot: '/api/dsh-novel-forge/snapshot',
33
+ /** 修订指令合并(POST:汇总审稿/时间线/张力为一轮)。 */
34
+ revisionPlan: '/api/dsh-novel-forge/revision/plan',
35
+ /** 张力曲线(GET 数据 / POST 设置)。 */
36
+ tension: '/api/dsh-novel-forge/tension',
37
+ /** 提示词槽位(GET 列表 / POST 写入)。 */
38
+ promptSlots: '/api/dsh-novel-forge/prompt-slots',
39
+ /** 故事时间线(GET 列表 / POST 操作)。 */
40
+ timeline: '/api/dsh-novel-forge/timeline',
41
+ marketRadar: '/api/dsh-novel-forge/market-radar',
42
+ marketRadarScan: '/api/dsh-novel-forge/market-radar/scan',
43
+ marketRadarApply: '/api/dsh-novel-forge/market-radar/apply',
44
+ marketRadarSync: '/api/dsh-novel-forge/market-radar/foundation-sync',
45
+ marketRadarBrief: '/api/dsh-novel-forge/market-radar/brief',
28
46
  generate: '/api/dsh-novel-forge/generate',
29
47
  review: '/api/dsh-novel-forge/review',
30
48
  rewrite: '/api/dsh-novel-forge/rewrite',
@@ -52,22 +70,6 @@ export const NOVEL_API = {
52
70
  bookshelfImportText: '/api/dsh-novel-forge/bookshelf/import-text',
53
71
  /** 导入 txt/md 全本:拆章预览(不落盘)。 */
54
72
  bookshelfImportTextPreview: '/api/dsh-novel-forge/bookshelf/import-text/preview',
55
- /** 漫剧方案管理:create/remove/activate。 */
56
- manhuaPlans: '/api/dsh-novel-forge/manhua/plans',
57
- /** 漫剧角色库:从分镜提名(规则+LLM两段式)/ 建卡 / 更新 / 删除 / 形象锚点 / 精修提示词。 */
58
- mangaRoles: '/api/dsh-novel-forge/manga/roles',
59
- /** 漫剧道具库:从已写章节提炼常驻道具(跨镜头需一致)/ 保存清单。 */
60
- mangaProps: '/api/dsh-novel-forge/manga/props',
61
- /** 导出「即梦素材包」落盘到资产库 manga-assets/素材包/。 */
62
- exportPackage: '/api/dsh-novel-forge/manga/export-package',
63
- /** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
64
- storyboardSkeleton: '/api/dsh-novel-forge/storyboard/skeleton',
65
- /** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
66
- storyboardTable: '/api/dsh-novel-forge/storyboard/table',
67
- /** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
68
- storyboardPrompts: '/api/dsh-novel-forge/storyboard/prompts',
69
- /** 生图接口连通性测试(设置页每个模型条目用)。 */
70
- imageTest: '/api/dsh-novel-forge/image-test',
71
73
  /** LLM 模型连通性测试:真实最小调用,验证 Key / 端点 / 模型可用。 */
72
74
  llmTest: '/api/dsh-novel-forge/llm-test',
73
75
  /** 添加模型:厂商直填 key 或自定义路由,写进 DSH 凭据与 llm-pi-ai 路由。 */
@@ -94,16 +96,14 @@ export const NOVEL_API = {
94
96
  blurb: '/api/dsh-novel-forge/blurb',
95
97
  /** 重命名当前书(同步项目与书架条目)。 */
96
98
  rename: '/api/dsh-novel-forge/rename',
97
- /** 大世界:AI 提炼 / 保存结构化数据(境界/区域/势力)。 */
99
+ /** 大世界:提炼 / 保存结构化数据(境界/区域/势力)。 */
98
100
  world: '/api/dsh-novel-forge/world',
99
101
  /** 封面:GET 读取(dataUrl)/ POST 上传或移除。 */
100
102
  cover: '/api/dsh-novel-forge/blurb/cover',
101
103
  /** 剧情线管理:增删改 + 关联章节。 */
102
104
  plotlines: '/api/dsh-novel-forge/plotlines',
103
- /** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
105
+ /** 角色库:提炼 / 采纳 / 更新 / 删除。 */
104
106
  roles: '/api/dsh-novel-forge/roles',
105
- scenes: '/api/dsh-novel-forge/scenes',
106
- visualRules: '/api/dsh-novel-forge/visual-rules',
107
107
  /** 作者复盘补跑:对已写章节补齐 authorReview(全书流式 / 单章 JSON)。 */
108
108
  reviewBackfill: '/api/dsh-novel-forge/review/backfill',
109
109
  /** 章节复位:generating 卡死 → pending(可重新生成)。 */
@@ -112,15 +112,12 @@ export const NOVEL_API = {
112
112
  chapterApprove: '/api/dsh-novel-forge/chapter/approve',
113
113
  /** 敏感词检查:全书已写章节或指定文本。 */
114
114
  sensitiveCheck: '/api/dsh-novel-forge/sensitive-check',
115
- /** 开书想法 → AI 补全大纲:输入一句话想法,生成 2-3 个可选大纲方案。 */
115
+ /** 开书想法 → 补全大纲:输入一句话想法,生成 2-3 个可选大纲方案。 */
116
116
  outlineSuggest: '/api/dsh-novel-forge/outline/suggest',
117
117
  /** 反推大纲:从已写章节正文反向生成全书总纲(NDJSON 流)。 */
118
118
  outlineReverse: '/api/dsh-novel-forge/outline/reverse',
119
119
  /** 拆书分析:对已写章节做结构/人物/文风/卖点四维体检(两阶段:源笔记→分节分析)。 */
120
120
  breakdown: '/api/dsh-novel-forge/breakdown',
121
- /** 漫剧分镜生成:章节 → 角色锚点 + 分镜表(可适配豆包/Seedance/SD)。 */
122
- /** 漫剧分集计划:读一卷 → 按故事弧线分集(高潮拆集/过渡并章)。 */
123
- /** 漫画脚本:章节 → 分页分格漫画脚本(含角色视觉锚点)。 */
124
121
  /** 生产单:启动批量生产(计划补足 + 逐章生成 + 被拒分级处理)。 */
125
122
  runStart: '/api/dsh-novel-forge/run/start',
126
123
  /** 生产单控制:pause / resume / stop。 */
@@ -128,6 +125,10 @@ export const NOVEL_API = {
128
125
  /** 生产单状态(含进度统计与日志)。 */
129
126
  runStatus: '/api/dsh-novel-forge/run/status',
130
127
  config: '/api/dsh-novel-forge/config',
128
+ /** 输出目录迁移:dryRun 预览 / 确认后搬文件并联动配置与书架。 */
129
+ moveOutputDir: '/api/dsh-novel-forge/move-output-dir',
130
+ /** 本书参数:POST {} 读取;POST {patch} 合并保存(存 novel-project.json)。 */
131
+ bookSettings: '/api/dsh-novel-forge/book-settings',
131
132
  openFolder: '/api/dsh-novel-forge/open-folder',
132
133
  /** 插件自更新:在 DSH profile 目录拉取最新 npm 版(下载后需重启 DSH 生效)。 */
133
134
  pluginUpdate: '/api/dsh-novel-forge/plugin/update',
@@ -228,7 +229,7 @@ export interface BookImportTextRequest {
228
229
  text?: string
229
230
  /** 模式二:原文件名(txt/md),用于推断书名与显示。 */
230
231
  fileName?: string
231
- /** 输出目录;缺省为 ~/.dsh/novels/书名。 */
232
+ /** 输出目录;缺省为「输出目录」设置下的书名子目录。 */
232
233
  outputDir?: string
233
234
  }
234
235
 
@@ -260,312 +261,6 @@ export interface BookImportTextPreviewResponse {
260
261
  skipped: string[]
261
262
  }
262
263
 
263
- /** 分镜·编剧级:剧情骨架中的一节拍。 */
264
- export interface StoryboardBeat {
265
- /** 节拍 id(如 b1、b2)。 */
266
- id: string
267
- /** 事件一句话(发生了什么)。 */
268
- event: string
269
- /** 情绪走向(情绪词 id 数组,来自 story-beat-language 词库,链式)。 */
270
- emotion: EmotionId[]
271
- /** 叙事功能(枚举 id,来自 story-beat-language 词库)。 */
272
- function: StoryFunctionId
273
- /** 因果:承接上一节拍的原因(可选)。 */
274
- cause?: string
275
- }
276
-
277
- /** 分镜·编剧级:单章剧情骨架。 */
278
- export interface StoryboardSkeleton {
279
- chapterNo: number
280
- /** 本章弧线一句话(起承转合)。 */
281
- arc: string
282
- /** 剧情节拍链(时间顺序,因果连贯)。 */
283
- beats: StoryboardBeat[]
284
- /** 本章全部出镜角色(正文中的确切称谓,去重;漫剧角色库提名地基)。 */
285
- characters?: string[]
286
- }
287
-
288
- /** POST /storyboard/skeleton 请求:生成单章剧情骨架。 */
289
- export interface StoryboardSkeletonRequest {
290
- chapterNo: number
291
- }
292
-
293
- /** POST /storyboard/skeleton 响应。 */
294
- export interface StoryboardSkeletonResponse {
295
- skeleton: StoryboardSkeleton
296
- }
297
-
298
- /** 分镜·导演级:一个镜头。 */
299
- export interface StoryboardShot {
300
- /** 镜头 id(如 s1、s2)。 */
301
- id: string
302
- /** 挂载的节拍 id(骨架中的 b1…)。 */
303
- beatId: string
304
- /** 景别(枚举 id,来自 shot-language 词库)。 */
305
- shot: ShotSizeId
306
- /** 机位与运镜(枚举 id 数组,来自 shot-language 词库)。 */
307
- camera: CameraMoveId[]
308
- /** 构图(可选,枚举 id)。 */
309
- composition?: CompositionId
310
- /** 时长(秒,即梦白名单:5/6/7/8/10)。 */
311
- duration: number
312
- /** 画面内容:角色动作 + 表情 + 服装/标志物 + 主体位置。 */
313
- visual: string
314
- /** 台词/旁白(无则空字符串)。 */
315
- line: string
316
- /** 音效(无则空字符串)。 */
317
- sound: string
318
- /** 光效(枚举 id 数组,来自 shot-language 词库)。 */
319
- light: LightingId[]
320
- /** 承接上一镜头结尾状态(位置/动作/情绪/服装)。 */
321
- prevState: string
322
- /** 本镜头结束状态。 */
323
- nextState: string
324
- /** 本镜头出镜角色(引用小说库规范名/漫剧卡名,1-4 个;漫剧角色库提名地基)。 */
325
- characters?: string[]
326
- /** 本镜头已绑定漫剧卡的 id(定妆图引用,供出图/生视频时按卡取参考图)。 */
327
- mangaRoleIds?: string[]
328
- /** 即梦自然语言运镜描述(如「镜头从中景缓慢推进到近景」),提示词层直接使用,无需再转换。 */
329
- jimengCamera?: string
330
- /** 本镜参考图 id 列表(角色定妆图+场景图),即梦图生视频时逐条投喂。 */
331
- referenceImageIds?: string[]
332
- }
333
-
334
- /** 分镜·导演级:单章分镜表。 */
335
- export interface StoryboardTable {
336
- chapterNo: number
337
- shots: StoryboardShot[]
338
- /** 生成时注入的场景卡名称(前端标注消费关系)。 */
339
- usedScenes?: string[]
340
- /** 本章全部出镜角色(各镜头 characters 去重汇总;骨架有则兜底)。 */
341
- characters?: string[]
342
- /** 本章已绑定漫剧卡的 id(去重汇总,定妆图引用)。 */
343
- mangaRoleIds?: string[]
344
- }
345
-
346
- /** POST /storyboard/table 请求:骨架 → 分镜表。 */
347
- export interface StoryboardTableRequest {
348
- chapterNo: number
349
- /** 编剧级骨架(前端已生成/编辑后的版本)。 */
350
- skeleton: StoryboardSkeleton
351
- /** 漫剧方案基底风格 id(style-library);提供时按风格措辞画面描述。 */
352
- styleId?: string
353
- /** 可选滤镜风格 id(stackable)。 */
354
- filterId?: string
355
- }
356
-
357
- /** POST /storyboard/table 响应。 */
358
- export interface StoryboardTableResponse {
359
- table: StoryboardTable
360
- }
361
-
362
- /** 分镜·提示词级:一个镜头的即梦视频提示词。 */
363
- export interface StoryboardPrompt {
364
- /** 对应镜头 id(s1…)。 */
365
- shotId: string
366
- /** 即梦/视频模型可粘贴的中文提示词(画面+运镜+光效+风格词块)。 */
367
- text: string
368
- /** 本镜头绑定的漫剧卡 id(定妆图引用:出图/生视频时按卡取 imageUrl/立绘)。 */
369
- mangaRoleIds?: string[]
370
- /** Seedance 专用:运镜方式(推/拉/摇/移/跟/升降/固定,含具体起止)。 */
371
- camera?: string
372
- /** Seedance 专用:运动幅度(轻微/中等/强烈)。 */
373
- motion?: 'low' | 'medium' | 'high'
374
- /** 负面提示词(即梦末尾追加:不要文字/水印/变形/多手/多指等)。 */
375
- negativePrompt?: string
376
- /** 本镜头场景名(绑定场景底图参考)。 */
377
- sceneName?: string
378
- }
379
-
380
- /** 分镜持久化:单章的分镜产出(骨架 + 分镜表 + 视频提示词,可分别存在)。 */
381
- export interface ChapterStoryboard {
382
- chapterNo: number
383
- skeleton?: StoryboardSkeleton
384
- table?: StoryboardTable
385
- prompts?: StoryboardPrompt[]
386
- updatedAt: string
387
- }
388
-
389
- /** POST /storyboard/prompts 请求:分镜表 → 视频提示词。 */
390
- export interface StoryboardPromptsRequest {
391
- chapterNo: number
392
- /** 分镜表(前端已生成的镜头列表)。 */
393
- table: StoryboardTable
394
- /** 基底风格 id。 */
395
- styleId?: string
396
- /** 可选滤镜风格 id。 */
397
- filterId?: string
398
- }
399
-
400
- /** POST /storyboard/prompts 响应。 */
401
- export interface StoryboardPromptsResponse {
402
- prompts: StoryboardPrompt[]
403
- }
404
-
405
- /** 漫剧方案:同一本书的多套视觉演绎(基底风格 + 可选滤镜)。 */
406
- export interface MangaPlan {
407
- /** 方案 id。 */
408
- id: string
409
- /** 方案名(如《保质期》3D 皮克斯版)。 */
410
- name: string
411
- /** 基底风格 id(style-library 中非 stackable 风格)。 */
412
- styleId: string
413
- /** 可选滤镜风格 id(style-library 中 stackable 风格)。 */
414
- filterId?: string
415
- /** 可选题材(玄幻/武侠/二次元/都市/科幻...),注入对应题材生成规则。 */
416
- genre?: string
417
- /** 是否激活(分镜/角色图生成时使用)。 */
418
- active: boolean
419
- createdAt: string
420
- updatedAt: string
421
- }
422
-
423
- /** POST /manhua/plans 请求:漫剧方案管理。 */
424
- export interface MangaPlansRequest {
425
- op: 'create' | 'remove' | 'activate'
426
- /** create:方案名。 */
427
- name?: string
428
- /** create:基底风格 id。 */
429
- styleId?: string
430
- /** create:可选滤镜风格 id。 */
431
- filterId?: string
432
- /** create:题材(注入对应题材规则)。 */
433
- genre?: string
434
- /** remove/activate:方案 id。 */
435
- id?: string
436
- }
437
-
438
- /** POST /manhua/plans 响应。 */
439
- export interface MangaPlansResponse {
440
- plans: MangaPlan[]
441
- }
442
-
443
- /** 漫剧角色卡:制作角色(要建模/出图/锁一致性的「上镜角色」),与小说角色库弱关联。 */
444
- export interface MangaRoleCard {
445
- /** 稳定 id。 */
446
- id: string
447
- /** 来源小说角色名(只读追溯,非强外键;禁止反向写回小说库)。 */
448
- sourceRoleName?: string
449
- /** 漫剧用名(可短剧化改名)。 */
450
- name: string
451
- /** 身份一句话。 */
452
- identity: string
453
- /** 核心功能:主角/导师/感情线/反派/搭档/线人/功能性。 */
454
- coreFunction: 'protagonist' | 'mentor' | 'love_interest' | 'antagonist' | 'sidekick' | 'informant' | 'functional'
455
- /** 与主角的关系。 */
456
- protagonistRelation: 'enemy' | 'friend' | 'mentor' | 'lover' | 'exploit' | 'neutral'
457
- /** 口头禅/说话方式(配音一致性)。 */
458
- speechStyle: string
459
- /** ≤3 个极致性格标签。 */
460
- traits: string[]
461
- /** 1-2 个辨识度外貌点。 */
462
- appearance: string
463
- /** 角色定妆级别:protagonist主角(完整四件套) / supporting配角(仅立绘) / extra路人(不做定妆)。默认 protagonist。 */
464
- tier?: 'protagonist' | 'supporting' | 'extra'
465
- /** 3-5 个关键剧情节点。 */
466
- keyScenes: string[]
467
- /** 上场集数(分镜提名导入时记录)。 */
468
- appearsInEpisodes: number[]
469
- /** 待匹配 → 待确认 → 已导入 → 已定妆 → 已归档。 */
470
- status: 'pending_match' | 'pending_confirm' | 'imported' | 'anchored' | 'archived'
471
- /** 形象资产(沿用小说角色库同款结构)。 */
472
- imagePrompt?: RoleRecord['imagePrompt']
473
- /** 情绪表情清单(锚点提炼时产出)。 */
474
- expressions?: string[]
475
- /** 四类精修生图提示词(立绘/四视图/表情/细节)。 */
476
- promptKit?: RoleRecord['promptKit']
477
- /** 角色参考图。 */
478
- imageUrl?: string
479
- /** 图集(图像锚点)。 */
480
- gallery?: RoleImage[]
481
- /** 生成锚点/精修时的方案风格 id(旧风格检测用)。 */
482
- promptStyleId?: string
483
- createdAt: string
484
- updatedAt: string
485
- }
486
-
487
- /** 分镜提名 → 小说角色库匹配的一条候选。 */
488
- export interface MangaRoleCandidate {
489
- /** 分镜里的原始称谓(正文确切用法)。 */
490
- rawName: string
491
- /** matched=命中小说角色;ambiguous=多个候选待定;not_in_library=小说库没有;already_imported=已建漫剧卡(跳过)。 */
492
- verdict: 'matched' | 'ambiguous' | 'not_in_library' | 'already_imported'
493
- /** 规则阶段候选短名单(≤5,精确名优先 + 身份/简称匹配)。 */
494
- matches: Array<{ roleName: string; reason: string }>
495
- /** LLM/规则确认的命中角色名(ambiguous 时可能为空)。 */
496
- matchedRoleName?: string
497
- /** not_in_library 时给出建议:backfill=正文有该称谓但小说库漏提炼(回小说库补);manga_new=漫剧新增角色(直接建卡)。 */
498
- novelHint?: 'backfill' | 'manga_new'
499
- /** 智能分级:protagonist=主角(必做定妆)、supporting=配角(建议做定妆)、extra=路人/功能性(默认不导入,折叠显示)。 */
500
- tier?: 'protagonist' | 'supporting' | 'extra'
501
- /** 采纳时预填的漫剧卡建议。 */
502
- suggested: {
503
- name: string
504
- identity: string
505
- coreFunction: MangaRoleCard['coreFunction']
506
- protagonistRelation: MangaRoleCard['protagonistRelation']
507
- speechStyle: string
508
- traits: string[]
509
- appearance: string
510
- keyScenes: string[]
511
- }
512
- }
513
-
514
- /** POST /manga/roles 请求:漫剧角色库操作。 */
515
- export interface MangaRolesRequest {
516
- op: 'nominate' | 'adopt' | 'update' | 'remove' | 'visual' | 'promptKit' | 'image' | 'removeImage' | 'imageGenerate' | 'mode' | 'autoGenerate' | 'openAssets'
517
- /** op='mode':短剧精简模式开关。 */
518
- shortDramaMode?: boolean
519
- /** op='nominate':从哪章分镜提名角色。 */
520
- chapterNo?: number
521
- /** op='adopt' / op='update':漫剧角色卡。 */
522
- card?: MangaRoleCard
523
- /** op='remove' / 'visual' / 'promptKit' / 'image' / 'removeImage' / 'imageGenerate':漫剧卡 id。 */
524
- id?: string
525
- /** op='visual' / 'promptKit':漫剧方案基底风格 id。 */
526
- styleId?: string
527
- /** 可选滤镜风格 id。 */
528
- filterId?: string
529
- /** op='image':定妆图 dataURL。 */
530
- dataUrl?: string
531
- /** op='image':图集用途标签(立绘/四视图/表情-x/场景/细节);缺省视为角色参考图(imageUrl)。 */
532
- label?: string
533
- /** op='imageGenerate':漫画风格预设 id(可选)。 */
534
- style?: string
535
- /** op='imageGenerate':生图模型库条目 id(缺省用启用条目)。 */
536
- modelId?: string
537
-
538
- /** op='autoGenerate' 时返回一键生成结果。 */
539
- autoGenerate?: {
540
- chapterNo: number
541
- skeletonBeats: number
542
- shotCount: number
543
- promptCount: number
544
- importedRoles: number
545
- needMakeupRoles: number
546
- extraRoles: number
547
- pendingCandidates: number
548
- pendingRoleNames: string[]
549
- }}
550
-
551
- /** POST /manga/roles 响应。 */
552
- export interface MangaRolesResponse {
553
- cards: MangaRoleCard[]
554
- /** op='nominate' 时的 AI 提名候选。 */
555
- candidates?: MangaRoleCandidate[]
556
- /** op='visual' 时的形象锚点(已写入漫剧卡)。 */
557
- visual?: RoleRecord['imagePrompt']
558
- /** op='promptKit' 时的四类精修提示词包(已写入漫剧卡)。 */
559
- promptKit?: RoleRecord['promptKit']
560
- /** op='image' / 'imageGenerate' 时的定妆图 dataURL(已写入漫剧卡)。 */
561
- imageUrl?: string
562
- /** op='mode' 时的短剧精简模式状态。 */
563
- shortDramaMode?: boolean
564
- /** op='autoGenerate' 时返回一键生成结果。 */
565
- autoGenerate?: { chapterNo: number; skeletonBeats: number; shotCount: number; promptCount: number; importedRoles: number; needMakeupRoles: number; extraRoles: number; pendingCandidates: number; pendingRoleNames: string[] }
566
- }
567
-
568
-
569
264
  /** Chapter lifecycle states (the writing pipeline's state machine). */
570
265
  export type ChapterStatus =
571
266
  | 'pending' // planned, not started
@@ -588,6 +283,18 @@ export interface ChapterPlan {
588
283
  beats: string
589
284
  /** Target character count (defaults to the configured chapter size). */
590
285
  targetChars: number
286
+ /** 本章必达项(必须推进的局面/关系/信息/风险/决策变化)。 */
287
+ mustAdvance?: string[]
288
+ /** 本章必须保持/不得破坏的项(如人物状态、已有伏笔不提前揭)。 */
289
+ mustPreserve?: string[]
290
+ /** 本章不可违背的人物硬事实(身份/阵营/境界/当前位置/知情度)。 */
291
+ characterHardFacts?: string[]
292
+ /** 伏笔操作指令(seed/touch/pressure/partial_reveal/payoff/forbid)。 */
293
+ payoffDirectives?: Array<{ no?: number; operation?: 'seed' | 'touch' | 'pressure' | 'partial_reveal' | 'payoff' | 'forbid'; text?: string }>
294
+ /** 章末钩子要求(悬念/反转/新线索/未闭合选择)。 */
295
+ endingHook?: string
296
+ /** 本章义务合约(人类可读摘要,供生成与审稿共同锚定)。 */
297
+ obligation?: string
591
298
  /** Generation/review state. */
592
299
  status: ChapterStatus
593
300
  /** 进入 generating 的时间(用于超时自动复位;未在生成时无此字段)。 */
@@ -604,6 +311,10 @@ export interface ChapterPlan {
604
311
  review?: ReviewReport
605
312
  /** 作者复盘:钩子兑现/结尾钩子/剧情线推进/连续性/节奏趋势(生成后自动)。 */
606
313
  authorReview?: AuthorReview
314
+ /** 本章目标张力 0-100(规划或作者设定;用于张力曲线)。 */
315
+ tension?: number
316
+ /** 本章实际张力 0-100(审稿时模型打分;缺省时回落到 review.tension)。 */
317
+ tensionActual?: number
607
318
  /**
608
319
  * 待确认草稿:润色(去AI味)或整章重写的产物正文。生成时先存这里,
609
320
  * 用户看过对比后点「采纳」才覆盖正文文件;点「放弃」则丢弃。刷新页面不丢失。
@@ -627,23 +338,46 @@ export interface AuthorReview {
627
338
  continuity: string
628
339
  /** 近期节奏趋势提示(拖沓/爽点密度等)。 */
629
340
  trend: string
341
+ /** 本章发生的关键状态变化(人物状态/世界局面/关系/资源),用于回灌整本与事实库。 */
342
+ stateChanges?: string[]
343
+ /** 本章新引入或升级的冲突(供整本控制层与后续卷节奏参考)。 */
344
+ newConflicts?: string[]
345
+ /** 本章埋下/推进的新线索(供知识与伏笔系统回灌)。 */
346
+ clues?: string[]
347
+ /** 本章缺席但值得注意的角色及风险(卷级职责/缺席风险)。 */
348
+ absentRisks?: string[]
630
349
  /** 复盘时间。 */
631
350
  reviewedAt: string
632
351
  }
633
352
 
634
- /** 审稿维度(结构化定位问题类别;与 review-policy.ts 的 REVIEW_DIMENSIONS 对齐)。 */
353
+ /** 审稿维度(结构化定位问题类别)。权威清单是 reviewSystemPrompt 里的九条维度。 */
635
354
  export type ReviewDimension = 'character' | 'setting' | 'redline' | 'writing' | 'pacing' | 'logic' | 'anti-ai' | 'presentation' | 'compliance'
636
355
 
637
356
  /** One review finding. */
357
+ /** 问题严重度(审稿 / 时间线 / 张力共用)。 */
358
+ export type Severity = 'high' | 'medium' | 'low'
359
+
638
360
  export interface ReviewIssue {
639
361
  /** Severity: high = must fix, medium = should fix, low = suggestion. */
640
- severity: 'high' | 'medium' | 'low'
362
+ severity: Severity
641
363
  /** 问题维度(可选;缺省由前端按 item 推断)。 */
642
364
  dimension?: ReviewDimension
643
365
  /** What the problem is. */
644
366
  item: string
645
367
  /** Concrete suggestion for fixing it. */
646
368
  suggestion: string
369
+ /** 命中的反 AI 规则名(结构化,便于统计)。 */
370
+ ruleName?: string
371
+ /** 规则类别:forbidden / risk / encourage。 */
372
+ ruleType?: 'forbidden' | 'risk' | 'encourage'
373
+ /** 问题细分类(如 套话 句式 段落 心理 设定)。 */
374
+ category?: string
375
+ /** 命中的原文摘录。 */
376
+ excerpt?: string
377
+ /** 判定理由。 */
378
+ reason?: string
379
+ /** 是否可自动改写。 */
380
+ canAutoRewrite?: boolean
647
381
  }
648
382
 
649
383
  /** AI review report for one chapter. */
@@ -656,6 +390,14 @@ export interface ReviewReport {
656
390
  verdict: string
657
391
  /** Individual findings. */
658
392
  issues: ReviewIssue[]
393
+ /** 风险分 0-100(越高越需人工处理;源自 LLM 复核与本地扫描)。 */
394
+ riskScore?: number
395
+ /** 本地 AI 味指数 0-100(越高越像 AI;LLM 复核锚点,供 UI 展示)。 */
396
+ aiFlavor?: number
397
+ /** 本地扫描命中的高频套话(按次数降序,取前若干)。 */
398
+ aiPhrases?: Array<{ word: string; count: number }>
399
+ /** 本章张力 0-100(审稿模型评分;用于张力曲线的"实际"值)。 */
400
+ tension?: number
659
401
  /** When the review ran. */
660
402
  reviewedAt: string
661
403
  }
@@ -672,6 +414,146 @@ export interface Volume {
672
414
  chapterStart: number
673
415
  /** Last chapter number (inclusive). */
674
416
  chapterEnd: number
417
+ /** 卷级战略(这一卷的定位/承转,如「立威卷」「冲突升级卷」)。 */
418
+ strategy?: string
419
+ /** 卷节奏板(这一卷的节奏安排:起-承-转-合/爽点密度/关键节点)。 */
420
+ pacing?: string
421
+ }
422
+
423
+ /** 开书定盘:面向读者的承诺与流派定位(生成/规划均可引用)。 */
424
+ export interface BookContract {
425
+ /** 一句话卖点/题材承诺。 */
426
+ promise?: string
427
+ /** 主推进模式名(从推进模式库选)。 */
428
+ primaryModeName?: string
429
+ /** 辅助推进模式名。 */
430
+ secondaryModeNames?: string[]
431
+ /** 整体文风基调(一句话)。 */
432
+ tone?: string
433
+ /** 目标平台(如「番茄」)。 */
434
+ targetPlatform?: string
435
+ }
436
+
437
+ /** 书内知识库文档(供生成/规划时检索注入的参考资料)。 */
438
+ export interface KnowledgeDoc {
439
+ id: string
440
+ title: string
441
+ content: string
442
+ updatedAt: string
443
+ }
444
+
445
+ /** POST /knowledge request:增删改知识库文档。 */
446
+ export interface KnowledgeRequest {
447
+ action: 'add' | 'remove' | 'replace'
448
+ doc?: { id?: string; title: string; content: string }
449
+ id?: string
450
+ }
451
+
452
+ /** POST /book-analysis request。 */
453
+ export interface BookAnalysisRequest {
454
+ text: string
455
+ }
456
+
457
+ /** 书分析/拆书结果。 */
458
+ export interface BookAnalysisResult {
459
+ sellingPoints: string[]
460
+ structure: string[]
461
+ lessons: string[]
462
+ risks: string[]
463
+ }
464
+
465
+ /** POST /idea-inspiration request。 */
466
+ export interface IdeaInspirationRequest {
467
+ idea: string
468
+ count?: number
469
+ }
470
+
471
+ /** 创意灵感结果:多方向开书灵感。 */
472
+ export interface IdeaInspirationResult {
473
+ ideas: Array<{ title: string; hook: string; genre: string; pov: string; payoff: string }>
474
+ }
475
+
476
+ /** POST /director request。 */
477
+ export interface DirectorRequest {
478
+ focus?: string
479
+ }
480
+
481
+ /** 自动导演编排建议(下一卷/阶段编排 + 修复再平衡)。 */
482
+ export interface DirectorAdvice {
483
+ summary: string
484
+ nextArc: string[]
485
+ pacing: string
486
+ risks: string[]
487
+ fixes: string[]
488
+ }
489
+
490
+ /** 自动导演「采纳」后生成的书内待办项。 */
491
+ export interface DirectorTodo {
492
+ id: string
493
+ text: string
494
+ /** 来源:风险 或 修复。 */
495
+ source: 'risk' | 'fix'
496
+ done: boolean
497
+ createdAt: string
498
+ }
499
+
500
+ /** 题材雷达:单条市场信号。 */
501
+ export interface MarketRadarSignal {
502
+ id: string
503
+ kind: 'genre' | 'protagonist' | 'advantage' | 'opening' | 'relationship' | 'title_pattern' | 'opportunity' | 'crowding'
504
+ title: string
505
+ detail: string
506
+ /** 趋势:current / rising / stable / falling。 */
507
+ direction?: 'current' | 'rising' | 'stable' | 'falling'
508
+ /** 是否建议优先考虑。 */
509
+ recommended?: boolean
510
+ }
511
+
512
+ /** 题材雷达:生产底座(引用内置题材/推进模式库,或给出新资产)。 */
513
+ export interface ProductionFoundation {
514
+ genre: { existingId?: string; name: string; description: string; template?: string }
515
+ primaryStoryMode: { existingId?: string; name: string; driver: string; readerExpectation: string }
516
+ secondaryStoryMode?: { existingId?: string; name: string; driver: string; readerExpectation: string }
517
+ }
518
+
519
+ /** 题材雷达:开书创意简报(可执行,严禁照搬具体作品/命名)。 */
520
+ export interface MarketCreativeBrief {
521
+ promptBlock: string
522
+ openingIdea: string
523
+ coreAdvantage: string
524
+ bookSellingPoint: string
525
+ first30ChapterPromise: string
526
+ }
527
+
528
+ /** 题材雷达结果。 */
529
+ export interface MarketRadarResult {
530
+ signals: MarketRadarSignal[]
531
+ productionFoundation: ProductionFoundation
532
+ /** 开书创意简报(可选;用「用信号创作」接口单独生成)。 */
533
+ creativeBrief?: MarketCreativeBrief
534
+ /**
535
+ * 本次分析的报告 id(服务端生成)。
536
+ *
537
+ * 前端据此判断「是否换了一份新报告」:只有报告变了才重置信号勾选,否则重渲染/
538
+ * 轮询会把作者手选的信号冲掉。缺省(旧版产物)时前端按「首次看到」处理。
539
+ */
540
+ reportId?: string
541
+ }
542
+
543
+ /** POST /market-radar request。 */
544
+ export interface MarketRadarRequest {
545
+ platform?: string
546
+ genre?: string
547
+ keywords?: string
548
+ feedText?: string
549
+ /** 已扫描的上榜记录(来自真实榜单抓取),用于让分析基于真实榜单证据。 */
550
+ candidates?: Array<{ title: string; author?: string; tags?: string[]; synopsis?: string; category?: string; heatLabel?: string }>
551
+ }
552
+
553
+ /** POST /market-radar/brief request:用选中的信号 + 影响模式生成开书创意。 */
554
+ export interface MarketRadarBriefRequest {
555
+ influenceMode: 'follow_hot' | 'differentiate' | 'light'
556
+ signals: MarketRadarSignal[]
675
557
  }
676
558
 
677
559
  /** A character card from the story bible. */
@@ -705,6 +587,175 @@ export interface StoryBible {
705
587
  }
706
588
 
707
589
  /** A planted/active/resolved foreshadowing thread. */
590
+ /** 修订建议来源:审稿 / 时间线 / 张力。 */
591
+ export type RevisionSource = 'review' | 'timeline' | 'tension'
592
+
593
+ /** 一条待修订条目(合并层排序后的最小单位)。 */
594
+ export interface RevisionItem {
595
+ /** 稳定 id(source:chapter:index)。 */
596
+ id: string
597
+ source: RevisionSource
598
+ severity: Severity
599
+ /** 归属章节号(0 = 全书级)。 */
600
+ chapterNo: number
601
+ item: string
602
+ suggestion: string
603
+ /** 去重时合并掉的同类条数(>=2 时展示)。 */
604
+ count?: number
605
+ }
606
+
607
+ /** POST /revision/plan 请求:把该章三类建议合并成一份修订指令。 */
608
+ export interface RevisionPlanRequest {
609
+ op: 'plan'
610
+ chapterNo?: number
611
+ /** 显式指定的审稿意见(面板勾选后传入;缺省取已落盘报告)。 */
612
+ reviewIssues?: ReviewIssue[]
613
+ includeTimeline?: boolean
614
+ includeTension?: boolean
615
+ bookId?: string
616
+ }
617
+
618
+ /** POST /revision/plan 响应。 */
619
+ export interface RevisionPlanResponse {
620
+ chapterNo: number
621
+ items: RevisionItem[]
622
+ /** 唯一修订指令(面板直接把它交给 /rewrite)。 */
623
+ instruction: string
624
+ counts: Record<RevisionSource, number>
625
+ /** 因上限被截断的条数。 */
626
+ omitted: number
627
+ /** 验证基准(复核时逐条核对本轮下发的全部条目)。 */
628
+ baseline: ReviewReport
629
+ /** 一行摘要。 */
630
+ summary: string
631
+ }
632
+
633
+ /**
634
+ * 张力曲线形状预设:
635
+ * `escalation` 递进爬升 / `suspense` 悬疑加压 / `wave` 波浪呼吸 /
636
+ * `frontLoad` 前紧后稳 / `flat` 平稳推进 / `custom` 自定义。
637
+ */
638
+ export type TensionCurvePreset = 'escalation' | 'suspense' | 'wave' | 'frontLoad' | 'flat' | 'custom'
639
+
640
+ /** 张力曲线配置(随项目保存)。 */
641
+ export interface TensionCurveConfig {
642
+ preset: TensionCurvePreset
643
+ /** preset=custom 时的逐章采样(0-100;缺省按章节数取默认值)。 */
644
+ custom?: number[]
645
+ }
646
+
647
+ /** 张力曲线的一条问题(实际 vs 目标 / 曲线形状)。 */
648
+ export interface TensionIssue {
649
+ severity: 'high' | 'medium' | 'low'
650
+ chapters: number[]
651
+ item: string
652
+ suggestion: string
653
+ }
654
+
655
+ /** 张力曲线数据点(面板绘图用)。 */
656
+ export interface TensionCurvePoint {
657
+ no: number
658
+ title: string
659
+ /** 目标张力。 */
660
+ target?: number
661
+ /** 实际张力(审稿打分)。 */
662
+ actual?: number
663
+ /** 参考曲线在此处的取值。 */
664
+ reference?: number
665
+ }
666
+
667
+ /** GET /tension 响应。 */
668
+ export interface TensionResponse {
669
+ preset: TensionCurvePreset
670
+ points: TensionCurvePoint[]
671
+ /** 规则核对发现的问题。 */
672
+ issues: TensionIssue[]
673
+ }
674
+
675
+ /** POST /tension 请求。 */
676
+ export interface TensionRequest {
677
+ op: 'preset' | 'set' | 'clear'
678
+ preset?: TensionCurvePreset
679
+ chapterNo?: number
680
+ /** op=set 时的目标张力(0-100)。 */
681
+ tension?: number
682
+ }
683
+
684
+ /** 允许作者编辑的提示词槽位 id(白名单)。 */
685
+ export type PromptSlotId = 'styleExtra' | 'antiAiExtra' | 'dialogueExtra' | 'endingHookExtra'
686
+
687
+ /** 一个提示词槽位的当前内容。 */
688
+ export interface PromptSlotState {
689
+ id: PromptSlotId
690
+ label: string
691
+ hint: string
692
+ placeholder: string
693
+ maxChars: number
694
+ value: string
695
+ }
696
+
697
+ /** GET /prompt-slots 响应。 */
698
+ export interface PromptSlotsResponse {
699
+ slots: PromptSlotState[]
700
+ }
701
+
702
+ /** POST /prompt-slots 请求:设置或清空一个槽位。 */
703
+ export interface PromptSlotsRequest {
704
+ id: PromptSlotId
705
+ /** 空串 = 清空该槽位(恢复默认)。 */
706
+ value: string
707
+ }
708
+
709
+ /**
710
+ * 故事时间线事件:从章节正文抽取的「故事内时间点 + 地点 + 参与角色 + 事件」。
711
+ * 用途:后续章节的时间连续性与地点衔接(比编年录更强调"顺序")。
712
+ */
713
+ export interface TimelineEvent {
714
+ /** 稳定 id(时间线内唯一)。 */
715
+ id: string
716
+ /** 所属章节号。 */
717
+ chapterNo: number
718
+ /** 故事内时间点(如「第三日黄昏」「入宗三个月后」「同日夜」)。 */
719
+ time: string
720
+ /** 相对顺序(同书内递增;无法判断时缺省)。用于检测时间倒流。 */
721
+ order?: number
722
+ /** 地点。 */
723
+ place: string
724
+ /** 参与角色(角色名)。 */
725
+ characters: string[]
726
+ /** 事件一句话。 */
727
+ event: string
728
+ /** 来源:模型抽取 / 作者手改。 */
729
+ source: 'extracted' | 'manual'
730
+ createdAt: string
731
+ }
732
+
733
+ /** 时间线矛盾(规则初筛 + AI 复核)。 */
734
+ export interface TimelineIssue {
735
+ severity: 'high' | 'medium' | 'low'
736
+ /** 定位到的章节(可多个)。 */
737
+ chapters: number[]
738
+ /** 问题描述。 */
739
+ item: string
740
+ /** 建议修法。 */
741
+ suggestion: string
742
+ }
743
+
744
+ /** GET /timeline 响应。 */
745
+ export interface TimelineResponse {
746
+ events: TimelineEvent[]
747
+ /** 规则初筛发现的问题(瞬时计算,不落盘)。 */
748
+ issues?: TimelineIssue[]
749
+ }
750
+
751
+ /** POST /timeline 请求:op=extract 抽单章 / check 全量检查 / update 手改 / remove 删除 / clear 清空。 */
752
+ export interface TimelineRequest {
753
+ op: 'extract' | 'check' | 'update' | 'remove' | 'clear'
754
+ chapterNo?: number
755
+ event?: TimelineEvent
756
+ id?: string
757
+ }
758
+
708
759
  export interface Foreshadow {
709
760
  /** Stable id. */
710
761
  id: string
@@ -746,6 +797,8 @@ export interface AuditResponse {
746
797
  auditedChapters: number
747
798
  /** 质检时间。 */
748
799
  auditedAt: string
800
+ /** 本次质检使用的模型(auditModel 或全局 model)。 */
801
+ model?: string
749
802
  }
750
803
 
751
804
  /** 全书质检的实时状态(通过 /status 暴露给面板/外部读取)。 */
@@ -817,7 +870,7 @@ export interface PlotlineHealthReport {
817
870
  }>
818
871
  }
819
872
 
820
- /** AI 剧情方案:下一阶段目标 + 建议新线。 */
873
+ /** 剧情方案:下一阶段目标 + 建议新线。 */
821
874
  export interface PlotlinePlan {
822
875
  /** 下一阶段(未来 5-10 章)剧情方向。 */
823
876
  direction: string
@@ -828,7 +881,7 @@ export interface PlotlinePlan {
828
881
  /** POST /plotlines 响应。 */
829
882
  export interface PlotlinesResponse {
830
883
  plotlines: Plotline[]
831
- /** op=suggest 时的 AI 建议候选线。 */
884
+ /** op=suggest 时的 建议候选线。 */
832
885
  suggestions?: Plotline[]
833
886
  /** op=health 时的健康检查报告。 */
834
887
  health?: PlotlineHealthReport
@@ -949,7 +1002,7 @@ export interface RoleStatusCard {
949
1002
  appearances: number
950
1003
  }
951
1004
 
952
- /** 角色库条目(主表:作者维护 + AI 提炼 + 编年录自动聚合)。 */
1005
+ /** 角色库条目(主表:作者维护 + 提炼 + 编年录自动聚合)。 */
953
1006
  export interface RoleRecord {
954
1007
  /** 角色名(唯一键)。 */
955
1008
  name: string
@@ -969,192 +1022,17 @@ export interface RoleRecord {
969
1022
  knowledge: string[]
970
1023
  /** 首次出场章节(编年录聚合,可手动修正)。 */
971
1024
  firstChapter?: number
972
- /** 动漫形象描述词(AI 绘图用:中文描述 + 英文标签 + 关键外貌标签)。 */
973
- imagePrompt?: {
974
- /** 中文外貌描述:连贯一段(发色/瞳色/服装/气质/标志物)。 */
975
- zh: string
976
- /** 英文绘图标签:booru 风格逗号分隔。 */
977
- en: string
978
- /** 中文关键标签(发色/瞳色/服装/气质/标志物)。 */
979
- tags: string[]
980
- /** 依据来源说明(哪几章哪些描写)。 */
981
- source?: string
982
- /** 即梦/生图通用负面提示词(低质量/变形/多手/文字水印等)。 */
983
- negativePrompt?: string
984
- }
985
- /** 角色参考图(dataURL 或 URL)。用于漫画/漫剧出图时锁定角色一致性。 */
986
- imageUrl?: string
987
- /** 角色图集(图像锚点):立绘/四视图/表情/场景/细节等,label 标注用途。 */
988
- gallery?: RoleImage[]
989
- /** 该角色所需的情绪表情清单(提炼时 LLM 补全 6-12 个,如"疲惫/麻木/压抑悲伤")。 */
990
- expressions?: string[]
991
- /** LLM 精修的四类生图提示词包(前端拼装版之外的高质量版,promptKit 接口生成)。 */
992
- promptKit?: {
993
- /** 立绘:全身/半身正视图。 */
994
- portrait?: { zh: string; en: string }
995
- /** 四视图:正面/侧面/背面设定表。 */
996
- sheet?: { zh: string; en: string }
997
- /** 表情:同一脸部锚换情绪,每表情一段。 */
998
- expressions?: { name: string; zh: string; en: string }[]
999
- /** 细节:标志物局部特写。 */
1000
- details?: { zh: string; en: string }
1001
- }
1002
- /** 生成形象锚点/精修提示词时的漫剧方案基底风格 id(= 方案 styleId;用于检测旧风格并提示重生成)。 */
1003
- promptStyleId?: string
1004
- /** 漫画/漫剧重要性:main=必须建卡保证一致;support=有锚点即可;extra=路人随机生成不约束。 */
1005
- importance?: 'main' | 'support' | 'extra'
1006
- }
1007
-
1008
- /** 角色图集条目:一张已定型的角色图(图像锚点)。 */
1009
- export interface RoleImage {
1010
- /** 用途标签:立绘 / 四视图 / 表情-疲惫 / 场景 / 细节 等。 */
1011
- label: string
1012
- /** dataURL 或 URL。 */
1013
- dataUrl: string
1014
- }
1015
-
1016
- /** 道具卡:常驻道具(跨镜头需保持一致),含一行统一描述。 */
1017
- export interface Prop {
1018
- /** 道具名(如「外卖电动车」)。 */
1019
- name: string
1020
- /** 外观/统一描述(注入提示词保持一致)。 */
1021
- desc: string
1022
- }
1023
-
1024
- /** POST /manga/props 请求。 */
1025
- export interface MangaPropsRequest {
1026
- op: 'extract' | 'save'
1027
- /** op=save 时的道具清单(整体替换)。 */
1028
- props?: Prop[]
1029
- }
1030
-
1031
- /** POST /manga/props 响应。 */
1032
- export interface MangaPropsResponse {
1033
- props: Prop[]
1034
- }
1035
-
1036
- /** 场景库条目:从正文提炼的「镜头场景」视觉锚点(漫剧分镜/生图用)。 */
1037
- export interface SceneCard {
1038
- /** 场景名(唯一键),如「旧茶渡·地下石殿」。 */
1039
- name: string
1040
- /** 一句话定位:空间/氛围/功能。 */
1041
- summary: string
1042
- /** 幕归属:第一幕·后场 / 第二幕·卖场 / …(便于按剧情段落组织)。 */
1043
- act?: string
1044
- /** 时间光态:夜间闭店后 / 雨夜 / 凌晨 / 频闪灯… */
1045
- moment?: string
1046
- /** 关键情节镜头 1-3 条:该场景拍什么(人物动作+情绪+镜头推进)。 */
1047
- beats?: string[]
1048
- /** 人物在场状态:主角/关键角色在该场景的状态一句话。 */
1049
- characterState?: string
1050
- /** 环境构成:空间结构/陈设/标志物。 */
1051
- elements: string[]
1052
- /** 色调与光影(含 HEX 色板,可空)。 */
1053
- palette: string[]
1054
- /** 氛围关键词:压抑/神秘/空旷… */
1055
- moods: string[]
1056
- /** 中文生图提示词(连贯一段,写实电影感)。 */
1057
- zh: string
1058
- /** 英文生图提示词(逗号分隔标签)。 */
1059
- en: string
1060
- /** 关键标签。 */
1061
- tags: string[]
1062
- /** 依据来源(哪几章哪些描写)。 */
1063
- source?: string
1064
- /** 场景图集(图像锚点):全景/局部/氛围 等。 */
1065
- gallery?: RoleImage[]
1066
- /** 生成时的漫剧方案基底风格 id(场景卡随方案风格措辞)。 */
1067
- styleId?: string
1068
-
1069
- /** 场景分级:core核心场景(反复出现,精修多图)/ secondary次要场景(1-2次,一张图)/ passing路过场景(不做图)。 */
1070
- tier?: 'core' | 'secondary' | 'passing'
1071
- /** 负面提示词(场景生图/生视频用,默认无人物无文字无水印)。 */
1072
- negativePrompt?: string
1073
- /** 出场章节列表(用于自动分级统计)。 */
1074
- appearsInChapters?: number[]}
1075
-
1076
- /** POST /scenes 请求:场景库提炼 / 采纳 / 更新 / 删除 / 图集。 */
1077
- export interface ScenesRequest {
1078
- op: 'extract' | 'adopt' | 'update' | 'remove' | 'image' | 'removeImage' | 'imageGenerate'
1079
- /** op='extract' 时的漫剧基底风格 id(场景卡按方案风格措辞)。 */
1080
- styleId?: string
1081
- /** op='extract' 时的可选滤镜风格 id。 */
1082
- filterId?: string
1083
- /** op='extract' 时按章提取;不传则全书提取(前4章)。 */
1084
- chapterNo?: number
1085
- /** adopt / update 时传入的场景卡(adopt 可修改后采纳)。 */
1086
- scene?: SceneCard
1087
- /** remove / image 时的场景名。 */
1088
- name?: string
1089
- /** op='image' 时的图片 dataURL 与用途标签(全景/局部/氛围)。 */
1090
- dataUrl?: string
1091
- label?: string
1092
- /** op='imageGenerate' 时的生图模型 id(缺省用启用模型)。 */
1093
- modelId?: string
1094
- }
1095
-
1096
- /** POST /visual-rules 请求:视觉世界观规则提炼 / 保存。 */
1097
- export interface VisualRulesRequest {
1098
- op: 'extract' | 'save'
1099
- /** op=save 时的规则数组。 */
1100
- rules?: string[]
1101
- }
1102
-
1103
- /** POST /visual-rules 响应。 */
1104
- export interface VisualRulesResponse {
1105
- rules: string[]
1106
- }
1107
-
1108
- /** POST /scenes 响应。 */
1109
- export interface ScenesResponse {
1110
- scenes: SceneCard[]
1111
- /** op=extract 时的 AI 候选场景。 */
1112
- candidates?: SceneCard[]
1113
- /** op=imageGenerate 时返回的生成图 dataURL。 */
1114
- dataUrl?: string
1115
1025
  }
1116
1026
 
1117
- /** POST /roles 请求:角色库增删改 + AI 提炼 + 参考图上传。 */
1027
+ /** POST /roles 请求:角色库增删改 + 提炼 + 参考图上传。 */
1118
1028
  export interface RolesRequest {
1119
- op: 'extract' | 'adopt' | 'update' | 'remove' | 'visual' | 'image' | 'removeImage' | 'imageGenerate' | 'promptKit'
1029
+ op: 'extract' | 'adopt' | 'update' | 'remove'
1120
1030
  /** adopt / update 时传入的角色(adopt 可修改后采纳)。 */
1121
1031
  role?: RoleRecord
1122
1032
  /** remove 时的角色名。 */
1123
1033
  name?: string
1124
- /** op='image' 时的参考图 dataURL。 */
1125
- dataUrl?: string
1126
- /** op='image' 时的图集用途标签(立绘/四视图/表情-x/场景/细节);缺省视为角色参考图(imageUrl)。 */
1127
- label?: string
1128
- /** op='imageGenerate' 时的漫画风格预设 id(用于统一角色图与漫画页风格)。 */
1129
- style?: string
1130
- /** op='imageGenerate' 时指定生图模型库条目 id(缺省用启用条目)。 */
1131
- modelId?: string
1132
- /** op='visual' / op='promptKit' 时的漫剧基底风格 id(角色图按方案风格重出)。 */
1133
- styleId?: string
1134
- /** op='visual' / op='promptKit' 时的可选滤镜风格 id。 */
1135
- filterId?: string
1136
- }
1137
-
1138
- /** POST /image-test 请求:测一个生图接口的连通性与延迟(不落盘)。 */
1139
- export interface ImageTestRequest {
1140
- /** OpenAI 兼容生图接口地址。 */
1141
- baseURL: string
1142
- /** API Key。 */
1143
- apiKey: string
1144
- /** 模型 id(顺带校验是否在接口模型列表里,可选)。 */
1145
- model?: string
1146
1034
  }
1147
1035
 
1148
- /** POST /image-test 响应。 */
1149
- export interface ImageTestResponse {
1150
- ok: boolean
1151
- /** 连通延迟(毫秒)。 */
1152
- ms?: number
1153
- /** 失败原因。 */
1154
- message?: string
1155
- /** 模型 id 是否出现在接口的模型列表(探测成功时才有)。 */
1156
- modelFound?: boolean
1157
- }
1158
1036
 
1159
1037
  /** POST /llm-test 请求:对选中的提供商/模型发一次最小真实调用。 */
1160
1038
  export interface LlmTestRequest {
@@ -1178,12 +1056,6 @@ export interface RolesResponse {
1178
1056
  roles: RoleRecord[]
1179
1057
  /** op=extract 时的 AI 候选角色。 */
1180
1058
  candidates?: RoleRecord[]
1181
- /** op=visual 时的动漫形象描述词(已写入角色卡)。 */
1182
- visual?: RoleRecord['imagePrompt']
1183
- /** op=promptKit 时的四类提示词精修包(已写入角色卡)。 */
1184
- promptKit?: RoleRecord['promptKit']
1185
- /** op=image 时的角色参考图 dataURL。 */
1186
- imageUrl?: string
1187
1059
  }
1188
1060
 
1189
1061
  /** POST /bible/patch 请求:局部修补道藏。 */
@@ -1195,10 +1067,10 @@ export interface BiblePatchRequest {
1195
1067
  characters?: CharacterCard[]
1196
1068
  }
1197
1069
 
1198
- /** POST /blurb 请求:AI 生成/补全或手动保存小说简介。 */
1070
+ /** POST /blurb 请求:生成/补全或手动保存小说简介。 */
1199
1071
  export interface BlurbRequest {
1200
1072
  action: 'generate' | 'save'
1201
- /** 已写好的开头(AI 补全时使用;留空 = 全量生成)。 */
1073
+ /** 已写好的开头(补全时使用;留空 = 全量生成)。 */
1202
1074
  partial?: string
1203
1075
  /** 手动保存的完整简介(action=save 时)。 */
1204
1076
  text?: string
@@ -1270,7 +1142,7 @@ export interface WorldState {
1270
1142
  factions: WorldFaction[]
1271
1143
  }
1272
1144
 
1273
- /** POST /world 请求:AI 提炼或手动保存。 */
1145
+ /** POST /world 请求:提炼或手动保存。 */
1274
1146
  export interface WorldRequest {
1275
1147
  action: 'generate' | 'save'
1276
1148
  /** action=save 时的完整世界数据。 */
@@ -1302,57 +1174,61 @@ export interface ProjectState {
1302
1174
  assets?: ProjectAssets
1303
1175
  /** 事实库/时间线:每章生成后抽取,注入后续章节保持一致性。 */
1304
1176
  facts?: ChapterFact[]
1305
- /** 小说简介(面向读者的作品门面,AI 生成或手动保存)。 */
1177
+ /** 书内知识库文档(可检索资料/设定/参考)。 */
1178
+ knowledgeDocs?: KnowledgeDoc[]
1179
+ /** 自动导演待办:风险/修复「采纳」后生成的随手清单。 */
1180
+ todos?: DirectorTodo[]
1181
+ /** 小说简介(面向读者的作品门面,生成或手动保存)。 */
1306
1182
  blurb?: string
1183
+ /** 开书定盘:书籍级承诺与流派定位(前30章承诺/主副模式/文风/平台)。 */
1184
+ bookContract?: BookContract
1307
1185
  /** 封面文件名(相对输出目录,如 cover.png)。 */
1308
1186
  coverPath?: string
1309
1187
  /** 大世界结构化数据(境界体系/区域/势力)。 */
1310
1188
  world?: WorldState
1311
1189
  /** 剧情线(主线/支线/人物线/悬念线)。 */
1312
1190
  plotlines?: Plotline[]
1313
- /** 角色库(作者维护 + AI 提炼的主表)。 */
1191
+ /** 角色库(作者维护 + 提炼的主表)。 */
1314
1192
  roles?: RoleRecord[]
1315
- /** 漫剧角色库(制作角色投影:从分镜提名导入,独立于小说角色库)。 */
1316
- mangaRoles?: MangaRoleCard[]
1317
- /** 短剧精简模式:漫剧角色库按 5-8 上镜角色 / 功能标签 / 关系闭环 / 人设极致化约束。 */
1318
- shortDramaMode?: boolean
1319
- /** 场景库(作者维护 + AI 提炼的主表)。 */
1320
- scenes?: SceneCard[]
1321
- /** 道具库:常驻道具(如外卖电动车/外卖箱),统一描述,注入提示词保持跨镜头一致。 */
1322
- props?: Prop[]
1323
- /** 视觉世界观规则(生图/生视频必须遵守,从道藏提炼,注入所有提示词)。 */
1324
- visualRules?: string[]
1325
- /** 分镜工作台产出(骨架/分镜表,按章持久化,刷新/切换不丢)。 */
1326
- storyboards?: ChapterStoryboard[]
1327
- /** 漫剧方案列表(同一本书的多套视觉演绎:基底风格 + 可选滤镜)。 */
1328
- mangaPlans?: MangaPlan[]
1329
1193
  /** 人物志:角色当前状态聚合结果(从编年录刷新后存档,打开页面直接显示)。 */
1330
1194
  roleStatus?: RoleStatusCard[]
1331
- /** 漫剧分镜结果缓存:章号 → 分镜(持久化,刷新不丢)。 */
1332
- /** 漫剧分集计划缓存:卷号/0=全书 → 分集计划(持久化,刷新不丢)。 */
1333
- /** 漫画脚本缓存:章号 → 漫画脚本(持久化,刷新不丢)。 */
1195
+ /** 故事时间线(逐章抽取:时间点 / 地点 / 参与角色 / 事件)。 */
1196
+ timeline?: TimelineEvent[]
1197
+ /** 张力曲线配置(形状预设 + 自定义采样)。 */
1198
+ tensionCurve?: TensionCurveConfig
1199
+ /** 作者自定义的提示词槽位(白名单见 prompt-slots.ts)。 */
1200
+ promptSlots?: Partial<Record<PromptSlotId, string>>
1201
+ /** 本书参数(写作/审稿/推理/模型快切;未设字段回退全局 config)。 */
1202
+ bookSettings?: BookSettings
1334
1203
  /** ISO timestamps. */
1335
1204
  createdAt: string
1336
1205
  updatedAt: string
1337
1206
  }
1338
1207
 
1339
- /** 生图模型配置(模型库条目,可多套并存,启用一条生效)。 */
1340
- export interface ImageModelConfig {
1341
- /** 条目 id(本地唯一)。 */
1342
- id: string
1343
- /** 展示名(如「豆包 Seedream」「即梦」)。 */
1344
- name: string
1345
- /** OpenAI 兼容生图接口地址(如 https://ark.cn-beijing.volces.com/api/v3)。 */
1346
- baseURL: string
1347
- /** API Key。 */
1348
- apiKey: string
1349
- /** 生图模型 id(如 doubao-seedream-5-0-pro-260628)。 */
1350
- model: string
1351
- /** 是否启用(同时只启用一条)。 */
1352
- enabled: boolean
1208
+ /** 本书参数(存 novel-project.json.bookSettings;未设字段回退全局 config)。 */
1209
+ export interface BookSettings {
1210
+ /** 本书使用的提供方路由(快切器写入)。 */
1211
+ provider?: string
1212
+ /** 本书使用的主模型 id。 */
1213
+ model?: string
1214
+ /** 本书写作推理档位。 */
1215
+ reasoningEffort?: 'off' | 'low' | 'high' | 'max'
1216
+ /** 本书分析类任务推理档位。 */
1217
+ analysisReasoning?: 'off' | 'low' | 'high' | 'max'
1218
+ /** 本书每章目标字数。 */
1219
+ chapterChars?: number
1220
+ /** 本书单章最大输出 tokens。 */
1221
+ maxTokens?: number
1222
+ /** 本书审稿通过分。 */
1223
+ reviewPassScore?: number
1224
+ /** 本书是否写完自动审稿。 */
1225
+ autoReview?: boolean
1226
+ /** 本书是否自动作者复盘。 */
1227
+ autoAuthorReview?: boolean
1228
+ /** 本书是否修稿后自动复审。 */
1229
+ autoReviewAfterRevise?: boolean
1353
1230
  }
1354
1231
 
1355
- /** Runtime config surface exposed to the panel (subset of plugin Config). */
1356
1232
  /** 手动添加的模型库条目(只存插件内,不改 DSH 全局)。 */
1357
1233
  export interface SavedModel {
1358
1234
  /** 唯一 id(前端生成的短 id)。 */
@@ -1383,7 +1259,9 @@ export interface LlmVendor {
1383
1259
 
1384
1260
  /** 预置的常见厂商(id=provider 路由;添加模型下拉兜底用,其余厂商由运行时目录动态补充)。 */
1385
1261
  export const LLM_VENDORS: LlmVendor[] = [
1386
- { id: 'deepseek-official', name: 'DeepSeek', route: 'deepseek-official', apiKeyEnv: 'DEEPSEEK_API_KEY', defaultModel: 'deepseek-v4-flash', models: ['deepseek-v4-flash', 'deepseek-v4-pro', 'deepseek-chat', 'deepseek-reasoner'], builtin: true },
1262
+ // 注意:本列表只是「运行时目录不可用」时的兜底建议值;实际以 ctx.llm.listModels() 为准
1263
+ // (见 engine.ts listLlmVendors),避免 DSH 侧模型改名后这里的条目过期。
1264
+ { id: 'deepseek-official', name: 'DeepSeek', route: 'deepseek-official', apiKeyEnv: 'DEEPSEEK_API_KEY', defaultModel: 'deepseek-flash', models: ['deepseek-flash', 'deepseek-v4-pro'], builtin: true },
1387
1265
  { id: 'zai-coding-cn', name: '智谱 GLM', route: 'zai-coding-cn', apiKeyEnv: 'ZAI_CODING_CN_API_KEY', defaultModel: 'glm-5.3-flash', models: ['glm-4.5-air', 'glm-4.7', 'glm-5-turbo', 'glm-5.1', 'glm-5.2', 'glm-5.3', 'glm-5.3-flash', 'glm-5v-turbo'] },
1388
1266
  { id: 'qwen-token-plan-cn', name: '千问百炼', route: 'qwen-token-plan-cn', apiKeyEnv: 'QWEN_TOKEN_PLAN_CN_API_KEY', defaultModel: 'qwen3.7-max', models: ['qwen3.6-flash', 'qwen3.6-plus', 'qwen3.7-max', 'qwen3.7-plus', 'qwen3.8-max', 'qwen3.8-max-preview'] },
1389
1267
  { id: 'openrouter', name: 'OpenRouter', route: 'openrouter', apiKeyEnv: 'OPENROUTER_API_KEY', defaultModel: 'z-ai/glm-5.3-flash', models: ['z-ai/glm-4.6', 'z-ai/glm-4.7', 'z-ai/glm-5', 'z-ai/glm-5-turbo', 'z-ai/glm-5.1', 'z-ai/glm-5.2', 'z-ai/glm-5.3-flash', 'auto', 'deepseek/deepseek-v4-flash', 'anthropic/claude-sonnet-4.6'] },
@@ -1434,24 +1312,6 @@ export interface RemoveProviderResponse {
1434
1312
  message?: string
1435
1313
  }
1436
1314
 
1437
- /** GET /llm-providers 响应:当前已注册的提供方路由。 */
1438
- export interface LlmProvidersResponse {
1439
- providers: { id: string; name: string }[]
1440
- }
1441
-
1442
- /** POST /llm-remove 请求:移除一个提供方(unset key + 移除 llm-pi-ai 路由)。 */
1443
- export interface RemoveProviderRequest {
1444
- provider: string
1445
- /** 该提供方对应的 DSH 凭据引用名(用于 unset)。 */
1446
- apiKeyEnv?: string
1447
- }
1448
-
1449
- /** POST /llm-remove 响应。 */
1450
- export interface RemoveProviderResponse {
1451
- ok: boolean
1452
- message?: string
1453
- }
1454
-
1455
1315
  /** POST /llm-add 请求:添加一个模型(厂商直填 key,或自定义路由)。 */
1456
1316
  export interface AddModelRequest {
1457
1317
  mode: 'vendor' | 'custom'
@@ -1487,8 +1347,21 @@ export interface NovelConfig {
1487
1347
  outputDir: string
1488
1348
  /** LLM provider route (e.g. deepseek-official). */
1489
1349
  provider: string
1490
- /** LLM model id (e.g. deepseek-v4-flash). */
1350
+ /** LLM model id (e.g. deepseek-flash). */
1491
1351
  model: string
1352
+ /** 生成正文用模型(缺省用 model)。 */
1353
+ generateModel?: string
1354
+ /** 审稿用模型(缺省用 model;建议用更强的 reasoner/pro)。 */
1355
+ reviewModel?: string
1356
+ /** 全书质检(审计)用模型(缺省用 model)。 */
1357
+ auditModel?: string
1358
+ /**
1359
+ * 备用模型:主模型调用失败(网络/限流/额度/服务不可用)时自动切换重试一次。
1360
+ * 留空表示不切换。批量连写时能显著减少"整批中断"。
1361
+ */
1362
+ fallbackModel?: string
1363
+ /** 是否在出章后自动抽取故事时间线(失败不阻断出章)。默认开。 */
1364
+ autoTimeline?: boolean
1492
1365
  /** LLM reasoning effort: off = no thinking; low/high/max = thinking intensity. */
1493
1366
  reasoningEffort: 'off' | 'low' | 'high' | 'max'
1494
1367
  /** 分析类任务(提炼/拆书/反推大纲等)的推理档位;默认 low,不受上面写作档位影响。 */
@@ -1505,16 +1378,6 @@ export interface NovelConfig {
1505
1378
  autoAuthorReview: boolean
1506
1379
  /** 修订/润色产出草稿后是否自动附带一次 AI 审查(工作区显示新稿评分与剩余问题)。 */
1507
1380
  autoReviewAfterRevise: boolean
1508
- /** 生图模型库(多套并存,启用一条生效;旧 imageApiKey/imageApiModel 自动迁移为一条)。 */
1509
- imageModels?: ImageModelConfig[]
1510
- /** 运行时生效的生图接口地址(= 启用条目,兼容旧代码读取)。 */
1511
- imageBaseUrl?: string
1512
- /** 运行时生效的生图 API Key(= 启用条目,兼容旧代码读取)。 */
1513
- imageApiKey?: string
1514
- /** 运行时生效的生图模型 id(= 启用条目,兼容旧代码读取)。 */
1515
- imageApiModel?: string
1516
- /** 是否启用生图(= 存在启用条目)。 */
1517
- imageApiEnabled?: boolean
1518
1381
  /** 自定义背景图(URL 或 dataURL 或服务端路径引用;空 = 使用主题默认背景)。 */
1519
1382
  themeBackground?: string
1520
1383
  /** 自定义背景遮罩/模糊强度 0-80(0 = 不遮罩)。 */
@@ -1527,7 +1390,180 @@ export interface NovelConfig {
1527
1390
  savedModels?: SavedModel[]
1528
1391
  }
1529
1392
 
1393
+ /** POST /move-output-dir request:dryRun=true 仅预览;确认时须带 to。 */
1394
+ export interface MoveOutputDirRequest {
1395
+ /** 新输出目录(绝对路径)。 */
1396
+ to?: string
1397
+ /** 只列出当前目录内容,不搬移。 */
1398
+ dryRun?: boolean
1399
+ }
1400
+
1401
+ /** POST /move-output-dir response。 */
1402
+ export interface MoveOutputDirResponse {
1403
+ from: string
1404
+ to?: string
1405
+ /** 当前(或迁移后)目录内容清单。 */
1406
+ files: string[]
1407
+ bytes: number
1408
+ /** 联动重指向的书架条目数。 */
1409
+ movedBooks: number
1410
+ /** settings 默认输出目录是否同步更新。 */
1411
+ defaultUpdated: boolean
1412
+ }
1413
+
1414
+ /** POST /book-settings request:patch 省略 = 读取;字段传 null = 删除本书覆盖(回退全局)。 */
1415
+ export interface BookSettingsRequest {
1416
+ patch?: { [K in keyof BookSettings]?: BookSettings[K] | null }
1417
+ }
1418
+
1419
+ /** POST /book-settings response。 */
1420
+ export interface BookSettingsResponse {
1421
+ /** 本书已设置的参数(未设字段缺省 = 回退全局)。 */
1422
+ settings: BookSettings
1423
+ /** 应用回退链后的生效配置(全局 + 本书覆盖)。 */
1424
+ effective: NovelConfig
1425
+ /** 当前是否有打开的书。 */
1426
+ hasBook: boolean
1427
+ }
1428
+
1530
1429
  /** GET /status response. */
1430
+ /**
1431
+ * 创作阶段契约(宿主计算的「当前阶段 → 本轮允许的动作」)。
1432
+ * 计算逻辑在 stage-contract.ts;这里是宿主与面板/助手共享的线上形状。
1433
+ */
1434
+ export interface StageInfo {
1435
+ /** 阶段标识。 */
1436
+ id: 'outline' | 'bible' | 'plan' | 'write' | 'wait' | 'review' | 'revise' | 'export'
1437
+ /** 中文阶段名。 */
1438
+ label: string
1439
+ /** 建议的下一步动作(助手工具名;无对应工具时为空数组)。 */
1440
+ recommend: string[]
1441
+ /** 本阶段允许的写操作(作者只说了「继续」时的唯一命令集)。 */
1442
+ allow: string[]
1443
+ /** 为什么处于该阶段。 */
1444
+ reason: string
1445
+ }
1446
+
1447
+ // ------------------------------------------------------------ LLM 实况 / 用量
1448
+
1449
+ /** 单次 LLM 调用的 token 用量(来自 dsh-llm 的 usage chunk)。 */
1450
+ export interface LlmTokenUsage {
1451
+ inputTokens: number
1452
+ outputTokens: number
1453
+ /** 供应商给出的总用量(缺失时由输入+输出推导)。 */
1454
+ totalTokens?: number
1455
+ /** 思考(reasoning)通道用量。 */
1456
+ reasoningTokens?: number
1457
+ /** 命中缓存的输入用量。 */
1458
+ cacheReadTokens?: number
1459
+ }
1460
+
1461
+ /** LLM 实况帧:宿主 → 浏览器的 SSE 事件(每次调用一组 session_* 事件)。 */
1462
+ export interface LlmLiveFrame {
1463
+ type: 'session_started' | 'output_delta' | 'reasoning_delta' | 'phase_changed' | 'session_completed'
1464
+ /** 宿主生成,形如 ll-<base36>-<n>。 */
1465
+ sessionId: string
1466
+ /** 本次调用用途(如 正文生成/审稿/章节规划)。 */
1467
+ label?: string
1468
+ /** 使用模型。 */
1469
+ model?: string
1470
+ /** 事件时间(ISO)。 */
1471
+ at: string
1472
+ /** session_started:交互上下文。 */
1473
+ context?: { taskId?: string; interactionId: string }
1474
+ /** output_delta / reasoning_delta:本次增量文本。 */
1475
+ content?: string
1476
+ /** session 累计字符数。 */
1477
+ totalChars?: number
1478
+ /** reasoning 累计字符数。 */
1479
+ totalReasoningChars?: number
1480
+ /** phase_changed:新阶段。 */
1481
+ phase?: 'requesting' | 'streaming' | 'completed' | 'failed'
1482
+ /** phase_changed:阶段描述。 */
1483
+ phaseMessage?: string
1484
+ /** session_completed:最终预览(截断)。 */
1485
+ preview?: string
1486
+ /** session_completed:失败信息。 */
1487
+ error?: string
1488
+ /** session_completed:本次用量(供应商未上报时缺省)。 */
1489
+ usage?: LlmTokenUsage
1490
+ /** session_completed:本次调用耗时(毫秒)。 */
1491
+ elapsedMs?: number
1492
+ /** session_completed:首字耗时(毫秒;未拿到文本时缺省)。 */
1493
+ firstTokenMs?: number
1494
+ /** session_started:是否已记录可查看的 Prompt(面板据此显示「查看 Prompt」)。 */
1495
+ hasPrompt?: boolean
1496
+ /** session_started:Prompt 字符数(system + user)。 */
1497
+ promptChars?: number
1498
+ }
1499
+
1500
+ /** 按用途分组的用量。 */
1501
+ export interface LlmUsageBucket {
1502
+ label: string
1503
+ calls: number
1504
+ failed: number
1505
+ inputTokens: number
1506
+ outputTokens: number
1507
+ reasoningTokens: number
1508
+ elapsedMs: number
1509
+ }
1510
+
1511
+ /** 本次运行(进程内,重启归零)的 LLM 用量汇总。 */
1512
+ export interface LlmUsageSummary {
1513
+ calls: number
1514
+ failed: number
1515
+ inputTokens: number
1516
+ outputTokens: number
1517
+ reasoningTokens: number
1518
+ totalTokens: number
1519
+ elapsedMs: number
1520
+ /** 供应商未上报 usage 的调用次数(用于说明数据为何不完整)。 */
1521
+ callsWithoutUsage: number
1522
+ byLabel: LlmUsageBucket[]
1523
+ }
1524
+
1525
+ /** 一次调用的 Prompt 记录(供面板查看「实际发送了什么」)。 */
1526
+ export interface LlmPromptRecord {
1527
+ sessionId: string
1528
+ label?: string
1529
+ model?: string
1530
+ at: string
1531
+ system?: string
1532
+ user?: string
1533
+ /** system + user 的字符数(记录被截断时仍给出原始长度)。 */
1534
+ chars: number
1535
+ /** 记录本身是否被截断。 */
1536
+ truncated?: boolean
1537
+ }
1538
+
1539
+ /** 章节历史版本(快照):覆盖写入前自动留存,可回滚。 */
1540
+ export interface ChapterSnapshot {
1541
+ id: string
1542
+ chapterNo: number
1543
+ /** 快照文件(相对书目录)。 */
1544
+ file: string
1545
+ /** 留存原因(生成覆盖 / 采纳草稿 / 修订 / 手工)。 */
1546
+ reason: string
1547
+ chars: number
1548
+ at: string
1549
+ }
1550
+
1551
+ /** GET /snapshot 响应。 */
1552
+ export interface SnapshotResponse {
1553
+ snapshots: ChapterSnapshot[]
1554
+ /** 快照占用字节数。 */
1555
+ bytes: number
1556
+ }
1557
+
1558
+ /** POST /snapshot 请求:op=create 手工存档 / restore 回滚 / remove 删除 / prune 只留最近 N 个。 */
1559
+ export interface SnapshotRequest {
1560
+ op: 'create' | 'restore' | 'remove' | 'prune'
1561
+ chapterNo?: number
1562
+ id?: string
1563
+ /** prune:每章保留数量。 */
1564
+ keep?: number
1565
+ }
1566
+
1531
1567
  export interface StatusResponse {
1532
1568
  config: NovelConfig
1533
1569
  /** The persisted project, when one exists in the output dir. */
@@ -1536,11 +1572,26 @@ export interface StatusResponse {
1536
1572
  generatedFiles: string[]
1537
1573
  /** 全书质检实时状态(用于面板/外部读取进度)。 */
1538
1574
  audit?: AuditStatus
1575
+ /** 宿主按项目真实状态算出的创作阶段(面板角标 / 外部自动化共用)。 */
1576
+ stage?: StageInfo
1577
+ /** 本次运行(进程内)的 LLM 用量汇总:调用次数 / 输入·输出·思考 token / 耗时。 */
1578
+ usage?: LlmUsageSummary
1579
+ /**
1580
+ * 截断声明:本次响应中被裁掉的字段说明(如「编年录:共 320 条,仅返回最近 80 条」)。
1581
+ * 消费方不得把缺失字段当作"不存在",需要完整数据时走专用接口。
1582
+ */
1583
+ truncations?: string[]
1539
1584
  }
1540
1585
 
1541
1586
  /** 生产单状态(生产单 = 区间批量生产执行器:计划补足 + 逐章生成 + 被拒分级处理)。 */
1542
1587
  export interface RunState {
1543
1588
  runId: string
1589
+ /**
1590
+ * 本批次归属的书名(可选,兼容旧 run-state.json)。
1591
+ * 生产单是全局单实例,而 /run/status 恢复时会扫书架取第一个有 run-state 的目录,
1592
+ * 因此"这是哪本书的批次"必须显式带上,否则芯片/面板只能显示一个无法归属的状态。
1593
+ */
1594
+ bookName?: string
1544
1595
  /** 区间起点(含)。 */
1545
1596
  startNo: number
1546
1597
  /** 区间终点(含)。 */
@@ -1715,13 +1766,41 @@ export interface ChapterResponse {
1715
1766
  }
1716
1767
 
1717
1768
  /** POST /export request/response. */
1769
+ /**
1770
+ * 导出范围:
1771
+ * - `book` 整本正文(txt / md)
1772
+ * - `settings` 项目设定(总纲 / 道藏 / 大世界 / 写作资产 / 卷首语)
1773
+ * - `plan` 规划(卷计划 + 章节计划,含每章目标/要点/钩子/硬事实)
1774
+ * - `characters` 角色(角色库 + 人物志当前状态)
1775
+ * - `review` 质检记录(逐章审稿 + 作者复盘 + 伏笔/剧情线状态)
1776
+ * - `project` 项目 JSON(完整状态,用于备份/迁移;仅 json 格式)
1777
+ */
1778
+ export type ExportScope = 'book' | 'settings' | 'plan' | 'characters' | 'review' | 'project'
1779
+
1780
+ /** 导出范围全集(宿主校验用;顺序即 UI 展示顺序)。 */
1781
+ export const EXPORT_SCOPE_VALUES: readonly ExportScope[] = ['book', 'settings', 'plan', 'characters', 'review', 'project']
1782
+
1783
+ /** 导出范围的中文标签。 */
1784
+ export const EXPORT_SCOPE_LABELS: Record<ExportScope, string> = {
1785
+ book: '整本正文',
1786
+ settings: '项目设定',
1787
+ plan: '规划(卷/章节)',
1788
+ characters: '角色',
1789
+ review: '质检记录',
1790
+ project: '项目备份 JSON',
1791
+ }
1792
+
1718
1793
  export interface ExportRequest {
1719
- format: 'txt' | 'md'
1794
+ format: 'txt' | 'md' | 'json'
1795
+ /** 缺省 `book`(兼容旧调用)。 */
1796
+ scope?: ExportScope
1720
1797
  }
1721
1798
  export interface ExportResponse {
1722
1799
  file: string
1723
1800
  chars: number
1724
1801
  chapters: number
1802
+ scope: ExportScope
1803
+ format: 'txt' | 'md' | 'json'
1725
1804
  }
1726
1805
 
1727
1806
  /** POST /config request: patch any subset of the runtime config. */
@@ -1730,6 +1809,13 @@ export interface ConfigPatch {
1730
1809
  outputDir?: string
1731
1810
  provider?: string
1732
1811
  model?: string
1812
+ generateModel?: string
1813
+ reviewModel?: string
1814
+ auditModel?: string
1815
+ /** 备用模型(主模型失败时自动切换重试一次;空串 = 关闭)。 */
1816
+ fallbackModel?: string
1817
+ /** 出章后自动抽取故事时间线(默认开)。 */
1818
+ autoTimeline?: boolean
1733
1819
  reasoningEffort?: 'off' | 'low' | 'high' | 'max'
1734
1820
  analysisReasoning?: 'off' | 'low' | 'high' | 'max'
1735
1821
  chapterChars?: number
@@ -1738,9 +1824,6 @@ export interface ConfigPatch {
1738
1824
  autoReview?: boolean
1739
1825
  autoAuthorReview?: boolean
1740
1826
  autoReviewAfterRevise?: boolean
1741
- imageApiKey?: string
1742
- imageApiModel?: string
1743
- imageApiEnabled?: boolean
1744
1827
  /** 自定义背景图(URL / dataURL / 服务端路径引用)。 */
1745
1828
  themeBackground?: string
1746
1829
  /** 自定义背景遮罩/模糊强度 0-80。 */
@@ -1748,12 +1831,20 @@ export interface ConfigPatch {
1748
1831
  /** 玻璃透明度 0-100(100=当前原样)。 */
1749
1832
  themeOpacity?: number
1750
1833
  enableAdaptMode?: boolean
1751
- /** 生图模型库(完整替换保存)。 */
1752
- imageModels?: ImageModelConfig[]
1753
1834
  /** 手动添加的模型库(完整替换保存)。 */
1754
1835
  savedModels?: SavedModel[]
1755
1836
  }
1756
1837
 
1838
+ /** POST /config response: the config the host will read next, plus persistence caveats. */
1839
+ export interface ConfigResponse {
1840
+ config: NovelConfig
1841
+ /**
1842
+ * 已生效但**未持久化**时的说明(宿主 settings 段不可寻址:段 id 未知或宿主
1843
+ * 未登记)。有值时设置只在本次进程内有效,重启回退,面板照此提示用户。
1844
+ */
1845
+ settingsWarning?: string
1846
+ }
1847
+
1757
1848
  // ------------------------------------------------------------ assistant
1758
1849
 
1759
1850
  /** One assistant conversation message (persisted per project). */
@@ -1778,6 +1869,8 @@ export type AssistantFrame =
1778
1869
  | { type: 'tool'; name: string; status: 'start' | 'done' | 'error'; detail?: string }
1779
1870
  /** Live output while a tool runs (e.g. chapter text being generated). */
1780
1871
  | { type: 'toolDelta'; name: string; text: string }
1872
+ /** 工具完整结果(供前端渲染成结构化卡片,如拆书/导演)。 */
1873
+ | { type: 'toolResult'; name: string; text: string }
1781
1874
  | { type: 'done' }
1782
1875
  | { type: 'error'; message: string }
1783
1876
 
@@ -1790,16 +1883,22 @@ export interface AssistantHistoryResponse {
1790
1883
 
1791
1884
  /** 题材基底库:一本书属于哪个阅读市场。树形(题材→子题材→下级)。 */
1792
1885
  export interface GenreNode {
1886
+ /** 稳定标识(内置库交叉引用)。 */
1887
+ id?: string
1793
1888
  /** 题材名称(标签,如「仙侠修真」「都市异能」)。 */
1794
1889
  name: string
1795
1890
  /** 题材特征、常见爽点、叙事重心或读者期待。 */
1796
1891
  description: string
1892
+ /** 该题材的写法指引(开书定盘/卷计划用,区别于「读者期待」)。 */
1893
+ template?: string
1797
1894
  /** 子题材。 */
1798
1895
  children: GenreNode[]
1799
1896
  }
1800
1897
 
1801
1898
  /** 推进模式库:读者为什么继续看下一章。 */
1802
1899
  export interface ProgressionMode {
1900
+ /** 稳定标识(与内置库交叉引用)。 */
1901
+ key?: string
1803
1902
  /** 模式名称(如「升级变强」「经营扩张」「解谜揭露」)。 */
1804
1903
  name: string
1805
1904
  /** 核心驱动力:靠什么制造追读动力。 */
@@ -1812,12 +1911,34 @@ export interface ProgressionMode {
1812
1911
  risks: string[]
1813
1912
  /** 主模式或辅助模式。 */
1814
1913
  primary: boolean
1914
+ /** 该模式的写法指引(开书定盘/卷计划用)。 */
1915
+ template?: string
1916
+ /** 推进单位序列(每章如何推进,如「立威→打破质疑→扩大影响→碾压」)。 */
1917
+ progressionUnits?: string[]
1918
+ /** 允许出现的冲突形态。 */
1919
+ allowedConflictForms?: string[]
1920
+ /** 应避免的冲突形态(跑偏信号)。 */
1921
+ forbiddenConflictForms?: string[]
1922
+ /** 冲突烈度上限(low/medium/high),用于卷/章计划和审稿对齐。 */
1923
+ conflictCeiling?: 'low' | 'medium' | 'high'
1924
+ /** 单章推进单位说明。 */
1925
+ chapterUnit?: string
1926
+ /** 卷末应兑现的回报。 */
1927
+ volumeReward?: string
1928
+ /** 主驱动必须持续出现的信号(读者期待确认)。 */
1929
+ mandatorySignals?: string[]
1930
+ /** 反信号:出现即跑偏。 */
1931
+ antiSignals?: string[]
1932
+ /** 优先用的问题解决方式。 */
1933
+ resolutionStyle?: string
1815
1934
  }
1816
1935
 
1817
1936
  /** 反 AI 规则:一条「要避免的问题 + 修正方向」。 */
1818
1937
  export interface AntiAiRule {
1819
1938
  /** 规则名(如「禁止解释型心理描写」「AI 高频套话」)。 */
1820
1939
  name: string
1940
+ /** 稳定标识(与 defaultAntiAiRuleKeys 交叉引用;缺省用 name)。 */
1941
+ key?: string
1821
1942
  /** 要避免的表达问题,具体可检查。 */
1822
1943
  avoid: string
1823
1944
  /** 推荐修正方向。 */
@@ -1826,15 +1947,60 @@ export interface AntiAiRule {
1826
1947
  detectPatterns?: string[]
1827
1948
  /** 是否内置全局规则(内置规则随插件发布,项目规则为用户自定义)。 */
1828
1949
  builtin?: boolean
1829
- /** 规则类型:forbidden=禁止类(命中即问题)/ encourage=鼓励类(不命中不算错,只作建议)。缺省按名称「鼓励」前缀推断。 */
1830
- severity?: 'forbidden' | 'encourage'
1950
+ /** 规则类别:forbidden=禁止类(命中即问题)/ risk=风险类(需注意但不硬伤)/ encourage=鼓励类(不命中不算错,只作建议)。 */
1951
+ severity?: 'forbidden' | 'risk' | 'encourage'
1952
+ /** 问题严重度(用于审稿优先级;缺省按类别推断)。 */
1953
+ riskLevel?: 'low' | 'medium' | 'high'
1954
+ /** 生成时直接注入的约束指令(缺失时回退到 avoid)。 */
1955
+ promptInstruction?: string
1956
+ /** 是否允许自动改写(risk 类通常 false)。 */
1957
+ autoRewrite?: boolean
1958
+ /** 是否为全局基线规则(新书默认启用,防止规则丢失后降级)。 */
1959
+ globalBaselineEnabled?: boolean
1831
1960
  /** 是否启用(缺省 true)。 */
1832
1961
  enabled?: boolean
1833
1962
  /** 作用域(缺省 all)。 */
1834
1963
  scope?: Array<'writing' | 'review' | 'polish' | 'all'>
1835
1964
  }
1836
1965
 
1837
- /** 预置写法模板(来自 AI-Novel-Writing-Assistant 内置数据,一键绑定无需样本文本)。 */
1966
+ /** 预置叙事风格模板(一键绑定无需样本文本)。 */
1967
+ export interface StyleTemplateNarrativeRules {
1968
+ progressionMode?: string
1969
+ sceneUnitPattern?: string[]
1970
+ multiPov?: boolean
1971
+ looping?: boolean
1972
+ endingStyle?: string
1973
+ povSwitchStyle?: string
1974
+ summary?: string
1975
+ }
1976
+
1977
+ export interface StyleTemplateCharacterRules {
1978
+ allowSelfReflection?: boolean
1979
+ emotionExpression?: string
1980
+ defenseMechanisms?: string[]
1981
+ facePriority?: boolean
1982
+ dialogueStyle?: string
1983
+ summary?: string
1984
+ }
1985
+
1986
+ export interface StyleTemplateLanguageRules {
1987
+ register?: string
1988
+ roughness?: number
1989
+ allowIncompleteSentences?: boolean
1990
+ allowSwearing?: boolean
1991
+ sentenceVariation?: string
1992
+ allowUselessDetails?: boolean
1993
+ summary?: string
1994
+ }
1995
+
1996
+ export interface StyleTemplateRhythmRules {
1997
+ pace?: string
1998
+ paragraphDensity?: string
1999
+ allowFragmentedFlow?: boolean
2000
+ actionOverExplanation?: boolean
2001
+ summary?: string
2002
+ }
2003
+
1838
2004
  export interface StyleTemplate {
1839
2005
  /** 模板 key(如 power-up-escalation)。 */
1840
2006
  key: string
@@ -1846,18 +2012,42 @@ export interface StyleTemplate {
1846
2012
  category: string
1847
2013
  /** 适用题材。 */
1848
2014
  applicableGenres: string[]
1849
- /** 叙述规则。 */
2015
+ /** 标签(便于筛选)。 */
2016
+ tags?: string[]
2017
+ /** 一句话分析(模板定位说明)。 */
2018
+ analysisMarkdown?: string
2019
+ /** 叙述规则(结构化)。 */
2020
+ narrative?: StyleTemplateNarrativeRules
2021
+ /** 角色规则(结构化)。 */
2022
+ character?: StyleTemplateCharacterRules
2023
+ /** 语言规则(结构化)。 */
2024
+ language?: StyleTemplateLanguageRules
2025
+ /** 节奏规则(结构化)。 */
2026
+ rhythm?: StyleTemplateRhythmRules
2027
+ /** 叙述规则(扁平,兼容旧数据)。 */
1850
2028
  proseRules: string[]
1851
- /** 角色/台词规则。 */
2029
+ /** 角色/台词规则(扁平,兼容旧数据)。 */
1852
2030
  dialogueRules: string[]
1853
- /** 语言规则。 */
2031
+ /** 语言规则(扁平,兼容旧数据)。 */
1854
2032
  languageRules: string[]
1855
- /** 节奏规则。 */
2033
+ /** 节奏规则(扁平,兼容旧数据)。 */
1856
2034
  rhythmRules: string[]
1857
2035
  /** 该模板默认绑定的反 AI 规则 key(内置规则名)。 */
1858
2036
  defaultAntiAiRuleKeys: string[]
1859
2037
  }
1860
2038
 
2039
+ /** 起始风格画像:无样本文本也能快速绑定一套写法。 */
2040
+ export interface StarterStyleProfile {
2041
+ /** stable key(如 starter-power-up)。 */
2042
+ key: string
2043
+ /** 绑定到的写法模板 key。 */
2044
+ templateKey: string
2045
+ /** 画像名。 */
2046
+ name: string
2047
+ /** 画像说明。 */
2048
+ description: string
2049
+ }
2050
+
1861
2051
  /** 剧情桥段库:可复用的情节套路/桥段(作者阅读经验沉淀,与书内 Plotline 不同层)。 */
1862
2052
  export interface PlotBeatTemplate {
1863
2053
  /** 模板 key(如 face-slap / exit-wedding)。 */
@@ -1896,6 +2086,32 @@ export interface StyleAsset {
1896
2086
  boundaries: string[]
1897
2087
  /** 来源样本文本(可空)。 */
1898
2088
  sourceText?: string
2089
+ /** 仿写预设:imitate=高保真仿写 / balanced=平衡 / transfer=迁移(去指纹)。 */
2090
+ preset?: 'imitate' | 'balanced' | 'transfer'
2091
+ /** 指纹风险:仿写时照搬原作独特表达的风险。 */
2092
+ fingerprintRisk?: 'low' | 'medium' | 'high'
2093
+ /** 净化后的写作指引(可安全用于生成,去掉了会暴露来源的具体细节)。 */
2094
+ writingGuidance?: string[]
2095
+ /** 禁止照搬的原作特有实体(人名/地名/核心设定句式),生成时需避开。 */
2096
+ forbiddenEntities?: string[]
2097
+ /** 创建时间。 */
2098
+ createdAt: string
2099
+ }
2100
+
2101
+ /** 写作公式(从样本文本分层提取的"这套文怎么写"浓缩,供生成/改写复用)。 */
2102
+ export interface StyleFormula {
2103
+ /** 稳定 key。 */
2104
+ key: string
2105
+ /** 公式名。 */
2106
+ name: string
2107
+ /** 提取深度:basic=骨架 / standard=完整 / deep=逐句细化。 */
2108
+ depth: 'basic' | 'standard' | 'deep'
2109
+ /** 重点聚焦域(如 开场/对话/节奏/爽点密度)。 */
2110
+ focusAreas: string[]
2111
+ /** 公式正文(Markdown)。 */
2112
+ formula: string
2113
+ /** 应用指引(生成/改写时如何套用)。 */
2114
+ applyGuidance: string
1899
2115
  /** 创建时间。 */
1900
2116
  createdAt: string
1901
2117
  }
@@ -1912,6 +2128,8 @@ export interface ProjectAssets {
1912
2128
  antiAiRules: AntiAiRule[]
1913
2129
  /** 绑定的写法资产。 */
1914
2130
  styleAssets: StyleAsset[]
2131
+ /** 写作公式(分层提取:basic/standard/deep)。 */
2132
+ styleFormulas?: StyleFormula[]
1915
2133
  /** 资产更新时间。 */
1916
2134
  updatedAt?: string
1917
2135
  }
@@ -1927,6 +2145,8 @@ export interface AssetsResponse {
1927
2145
  styleTemplates: StyleTemplate[]
1928
2146
  /** 内置推进模式候选。 */
1929
2147
  progressionLibrary: ProgressionMode[]
2148
+ /** 起始风格画像(无样本文本快速绑定写法)。 */
2149
+ starterStyleProfiles: StarterStyleProfile[]
1930
2150
  /** 内置剧情桥段库(可复用套路)。 */
1931
2151
  plotBeatLibrary: PlotBeatTemplate[]
1932
2152
  }
@@ -1938,6 +2158,7 @@ export interface AssetsPatch {
1938
2158
  auxiliaryProgressions?: ProgressionMode[]
1939
2159
  antiAiRules?: AntiAiRule[]
1940
2160
  styleAssets?: StyleAsset[]
2161
+ styleFormulas?: StyleFormula[]
1941
2162
  }
1942
2163
 
1943
2164
  /** POST /style-engine request:从样本文本提取写法资产。 */
@@ -2012,8 +2233,8 @@ export interface AdaptationDimension {
2012
2233
  current: string
2013
2234
  /** 该值在正文中的出现证据(章节/频次,可空)。 */
2014
2235
  evidence?: string
2015
- /** AI 建议的候选新值(可空)。 */
2016
- candidates?: string[]
2236
+ /** 建议的候选新值(可空,每套含名称与一句话说明)。 */
2237
+ candidates?: Array<{ name: string; desc?: string }>
2017
2238
  /** 联动影响说明(改了会影响哪些章节/角色/伏笔/术语)。 */
2018
2239
  impact: string
2019
2240
  /** 风险评级。 */
@@ -2135,7 +2356,7 @@ export interface AdaptSaveRequest {
2135
2356
  text: string
2136
2357
  /** 新书名(缺省为「改编新书」;建议用「<原著>·改编版」)。 */
2137
2358
  bookName?: string
2138
- /** 新书输出目录(缺省 ~/.dsh/novels/书名)。 */
2359
+ /** 新书输出目录(缺省为「输出目录」设置下的书名子目录)。 */
2139
2360
  outputDir?: string
2140
2361
  /** 可附带反推大纲(写进新项目,便于后续续写/编辑)。 */
2141
2362
  outline?: string
@@ -2161,7 +2382,7 @@ export interface AdaptMaterializeRequest {
2161
2382
  text: string
2162
2383
  /** 新书名(缺省为「<源书名>·改编版」)。 */
2163
2384
  bookName?: string
2164
- /** 新书输出目录(缺省 ~/.dsh/novels/书名)。 */
2385
+ /** 新书输出目录(缺省为「输出目录」设置下的书名子目录)。 */
2165
2386
  outputDir?: string
2166
2387
  /** 反推大纲(来自分析;缺少时用源文章题兜底)。 */
2167
2388
  outline?: string
@@ -2197,7 +2418,7 @@ export interface AdaptMaterializeResponse {
2197
2418
  export interface AdaptMaterializeSaveRequest {
2198
2419
  /** 新书名(缺省为「改编版」)。 */
2199
2420
  bookName?: string
2200
- /** 新书输出目录(缺省 ~/.dsh/novels/书名)。 */
2421
+ /** 新书输出目录(缺省为「输出目录」设置下的书名子目录)。 */
2201
2422
  outputDir?: string
2202
2423
  /** 改编后总纲。 */
2203
2424
  outline: string