@waterwx/dsh-novel-forge 1.10.1 → 2.0.1-alpha

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 (56) hide show
  1. package/README.md +8 -3
  2. package/assets/styles/guoman-2d-gufeng.webp +0 -0
  3. package/assets/styles/guoman-3d-tianyuan.webp +0 -0
  4. package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
  5. package/assets/styles/hyperreal-3d.webp +0 -0
  6. package/assets/styles/sandiao-qban.webp +0 -0
  7. package/assets/styles/urban-lightreal-3d.webp +0 -0
  8. package/lib/client.js +3456 -2133
  9. package/lib/index.js +1975 -438
  10. package/lib/types/ai-scan.d.ts +36 -0
  11. package/lib/types/assets.d.ts +1 -1
  12. package/lib/types/client/api.d.ts +8 -1
  13. package/lib/types/client/index.d.ts +1 -1
  14. package/lib/types/client/panel/AuthorHome.d.ts +4 -2
  15. package/lib/types/client/panel/FlowGuide.d.ts +6 -5
  16. package/lib/types/client/panel/MangaRoleLibrary.d.ts +3 -1
  17. package/lib/types/client/panel/MangaWorkspace.d.ts +2 -5
  18. package/lib/types/client/panel/PropLibrary.d.ts +8 -0
  19. package/lib/types/client/panel/SceneLibrary.d.ts +3 -1
  20. package/lib/types/client/panel/SettingsView.d.ts +4 -2
  21. package/lib/types/engine.d.ts +50 -21
  22. package/lib/types/index.d.ts +2 -2
  23. package/lib/types/manga-genre-rules.d.ts +22 -0
  24. package/lib/types/novel-context.d.ts +80 -0
  25. package/lib/types/prompt-utils.d.ts +35 -0
  26. package/lib/types/protocol.d.ts +104 -12
  27. package/lib/types/review-policy.d.ts +97 -0
  28. package/lib/types/style-library.d.ts +3 -3
  29. package/package.json +21 -24
  30. package/src/ai-scan.ts +179 -0
  31. package/src/assets.ts +353 -9
  32. package/src/client/api.ts +11 -1
  33. package/src/client/index.ts +1 -1
  34. package/src/client/mount.tsx +1 -1
  35. package/src/client/panel/AdaptModeView.tsx +2 -2
  36. package/src/client/panel/AssistantTab.tsx +1 -1
  37. package/src/client/panel/AuthorHome.tsx +5 -3
  38. package/src/client/panel/FlowGuide.tsx +15 -14
  39. package/src/client/panel/MangaRoleLibrary.tsx +1002 -810
  40. package/src/client/panel/MangaWorkspace.tsx +715 -359
  41. package/src/client/panel/ModelManager.tsx +1 -1
  42. package/src/client/panel/NovelPanel.tsx +4620 -4655
  43. package/src/client/panel/PropLibrary.tsx +175 -0
  44. package/src/client/panel/SceneLibrary.tsx +453 -396
  45. package/src/client/panel/SettingsView.tsx +24 -30
  46. package/src/client/panel/StoryboardTab.tsx +6 -0
  47. package/src/client/panel/panel.module.css +165 -4
  48. package/src/engine.ts +796 -286
  49. package/src/index.ts +9 -7
  50. package/src/manga-genre-rules.ts +87 -0
  51. package/src/novel-context.ts +287 -0
  52. package/src/prompt-utils.ts +73 -0
  53. package/src/protocol.ts +2233 -2148
  54. package/src/review-policy.ts +161 -0
  55. package/src/routes.ts +3419 -3359
  56. package/src/style-library.ts +32 -26
@@ -0,0 +1,36 @@
1
+ /**
2
+ * 本地 AI 味扫描器(不调 LLM,确定性检测)
3
+ *
4
+ * 用途:生成/润色后自动扫描,结果作为「事实锚点」注入审稿提示词,
5
+ * 让 LLM 做判断而非机械统计。也可用于 UI 展示 AI 味指标。
6
+ */
7
+ export interface AiScanResult {
8
+ /** 总评分 0-100,越高越像 AI 写的 */
9
+ aiScore: number;
10
+ /** 命中的套话及次数 */
11
+ clicheHits: Array<{
12
+ word: string;
13
+ count: number;
14
+ }>;
15
+ /** 段落长度方差(过高=段落过于整齐) */
16
+ paragraphLengthVariance: number;
17
+ /** 连续解释性叙事段数(≥3 视为问题) */
18
+ consecutiveExpositoryParagraphs: number;
19
+ /** 句式重复率(相同开头句式占比) */
20
+ sentenceRepetitionRate: number;
21
+ /** 过长段落数(>300字) */
22
+ longParagraphCount: number;
23
+ /** 过短段落数(<20字) */
24
+ shortParagraphCount: number;
25
+ /** 对话占比(0-1) */
26
+ dialogueRatio: number;
27
+ /** 问题摘要,可直接注入审稿提示词 */
28
+ summary: string;
29
+ }
30
+ export declare function scanAiFlavor(text: string): AiScanResult;
31
+ /** 扫描前后对比(润色时用) */
32
+ export declare function compareAiScan(before: AiScanResult, after: AiScanResult): {
33
+ improved: boolean;
34
+ deltaScore: number;
35
+ details: string[];
36
+ };
@@ -23,7 +23,7 @@ export declare const BUILTIN_PLOT_BEATS: PlotBeatTemplate[];
23
23
  export declare function emptyProjectAssets(): ProjectAssets;
24
24
  /** 合并项目资产与内置库:返回「生效的反 AI 规则」(内置全局 + 项目自定义)。 */
25
25
  export declare function effectiveAntiAiRules(assets: ProjectAssets | undefined): AntiAiRule[];
26
- /** 把生效规则渲染成提示词块(压缩:avoid/fix 截断,省 token)。 */
26
+ /** 把生效规则渲染成提示词块(禁止/鼓励分列,压缩省 token)。 */
27
27
  export declare function renderAntiAiRules(assets: ProjectAssets | undefined): string;
28
28
  /** 渲染题材与推进模式提示词块。 */
29
29
  export declare function renderGenreAndProgression(assets: ProjectAssets | undefined): string;
@@ -74,7 +74,7 @@ export declare class NovelApi {
74
74
  ok: boolean;
75
75
  filled: number;
76
76
  }>;
77
- /** 设定圣经局部修补。 */
77
+ /** 道藏局部修补。 */
78
78
  biblePatch(patch: import('../protocol.ts').BiblePatchRequest): Promise<{
79
79
  bible: import('../protocol.ts').StoryBible;
80
80
  }>;
@@ -116,10 +116,17 @@ export declare class NovelApi {
116
116
  roles(req: import('../protocol.ts').RolesRequest): Promise<import('../protocol.ts').RolesResponse>;
117
117
  /** 漫剧角色库:从分镜提名 / 建卡 / 更新 / 删除 / 形象锚点 / 精修提示词。 */
118
118
  mangaRoles(req: import('../protocol.ts').MangaRolesRequest): Promise<import('../protocol.ts').MangaRolesResponse>;
119
+ /** 导出「即梦素材包」落盘到资产库 manga-assets/素材包/。 */
120
+ exportPackage(chapterNo: number, title: string, markdown: string): Promise<{
121
+ ok: boolean;
122
+ file: string;
123
+ }>;
119
124
  /** 场景库:AI 提炼 / 采纳 / 更新 / 删除 / 图集。 */
120
125
  scenes(req: import('../protocol.ts').ScenesRequest): Promise<import('../protocol.ts').ScenesResponse>;
121
126
  /** 视觉世界观规则:提炼 / 保存。 */
122
127
  visualRules(req: import('../protocol.ts').VisualRulesRequest): Promise<import('../protocol.ts').VisualRulesResponse>;
128
+ /** 道具库:从已写章节提炼常驻道具 / 保存清单。 */
129
+ mangaProps(req: import('../protocol.ts').MangaPropsRequest): Promise<import('../protocol.ts').MangaPropsResponse>;
123
130
  /** 小说简介:AI 生成/补全(partial 留空 = 全量),或手动保存。 */
124
131
  blurb(action: 'generate' | 'save', text?: string, partial?: string): Promise<{
125
132
  blurb: string;
@@ -4,7 +4,7 @@
4
4
  * problems are logged, never thrown — the web shell fails the whole boot when
5
5
  * a plugin apply throws.
6
6
  */
7
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
7
+ import type { Context as ClientContext } from '@deepseek-ai/cordis';
8
8
  /** Required services (fiber inject waiting). */
9
9
  export declare const inject: string[];
10
10
  /**
@@ -1,7 +1,7 @@
1
1
  import type { NovelApi } from '../api.ts';
2
2
  import type { BookshelfSnapshot } from '../../protocol.ts';
3
3
  import { type ProgressLine } from './ProgressConsole.tsx';
4
- export declare function AuthorHome({ api, shelf, onOpenBook, onReadBook, onAddBook, onImportBook, onOpenSettings, onTheme, onBackground, onOpacity, adaptEnabled, progress, busy, busyLabel, liveBar, onClearProgress }: {
4
+ export declare function AuthorHome({ api, shelf, onOpenBook, onReadBook, onAddBook, onImportBook, onOpenSettings, onTheme, onBackground, onOpacity, onEndfieldAccent, adaptEnabled, progress, busy, busyLabel, liveBar, onClearProgress }: {
5
5
  api: NovelApi;
6
6
  shelf: BookshelfSnapshot;
7
7
  onOpenBook: (id: string) => void;
@@ -11,11 +11,13 @@ export declare function AuthorHome({ api, shelf, onOpenBook, onReadBook, onAddBo
11
11
  /** 兼容旧入口:首页设置现为独立设置页,此回调保留但不再使用。 */
12
12
  onOpenSettings?: () => void;
13
13
  /** 主题/模式/密度变化回调(供面板根容器实时生效)。 */
14
- onTheme?: (theme: 'liquid' | 'neumorph' | 'macos' | 'clay', mode: 'system' | 'light' | 'dark', density: 'comfort' | 'compact' | 'spacious') => void;
14
+ onTheme?: (theme: 'liquid' | 'neumorph' | 'macos' | 'clay' | 'endfield', mode: 'system' | 'light' | 'dark', density: 'comfort' | 'compact' | 'spacious') => void;
15
15
  /** 自定义背景变化回调。 */
16
16
  onBackground?: (bg: string | undefined, blur: number) => void;
17
17
  /** 玻璃透明度变化回调。 */
18
18
  onOpacity?: (n: number) => void;
19
+ /** 终末地强调色变化回调。 */
20
+ onEndfieldAccent?: (accent: 'valley' | 'wuling') => void;
19
21
  /** 是否启用改编模式(默认 false=隐藏入口)。 */
20
22
  adaptEnabled?: boolean;
21
23
  /** AI 进度实时状态(与书内共享同一份)。 */
@@ -1,11 +1,11 @@
1
1
  /**
2
2
  * 漫剧工作台·全流程步骤条(唯一导航,方案X):
3
- * ①创建方案 → ②视觉规则 → ③剧情骨架 → ④分镜表 → ⑤导入角色 → ⑥角色定妆 → ⑦视频提示词 → ⑧场景库 → ⑨导出使用。
3
+ * ①创建方案 → ②一键生成 → ③分镜 → ④角色定妆 → ⑤场景底图 → ⑥导出使用。
4
4
  * 每个步骤对应一个独立页面主体;完成度自动判定(读 project 现有字段)。
5
5
  */
6
6
  import type { ProjectState } from '../../protocol.ts';
7
7
  /** 步骤 → 页面主体的一一对应目标。 */
8
- export type FlowTarget = 'plan' | 'rules' | 'skeleton' | 'table' | 'import' | 'makeup' | 'prompts' | 'scenes' | 'export';
8
+ export type FlowTarget = 'plan' | 'rules' | 'skeleton' | 'table' | 'import' | 'makeup' | 'prompts' | 'scenes' | 'props' | 'export';
9
9
  export interface FlowStep {
10
10
  no: number;
11
11
  label: string;
@@ -13,9 +13,10 @@ export interface FlowStep {
13
13
  done: boolean;
14
14
  target: FlowTarget;
15
15
  }
16
- /** 依据 project 数据计算 9 步完成度(与存储顺序无关,按生产顺序排列)。 */
17
- export declare function computeFlowSteps(project: ProjectState | null): FlowStep[];
18
- export declare function FlowGuide({ project, onNavigate, }: {
16
+ /** 依据 project 数据计算 6 步完成度(与存储顺序无关,按生产顺序排列)。 */
17
+ export declare function computeFlowSteps(project: ProjectState | null, exported?: boolean): FlowStep[];
18
+ export declare function FlowGuide({ project, onNavigate, exported, }: {
19
19
  project: ProjectState | null;
20
20
  onNavigate: (target: FlowTarget) => void;
21
+ exported?: boolean;
21
22
  }): import("react").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import type { NovelApi } from '../api.ts';
2
2
  import type { ImageModelConfig, ProjectState } from '../../protocol.ts';
3
- export declare function MangaRoleLibrary({ api, project, refresh, styleId, filterId, imageApiEnabled, imageModels, focus, showCards, onProgress, }: {
3
+ export declare function MangaRoleLibrary({ api, project, refresh, styleId, filterId, focus, showCards, chapterNo: externalChapter, onProgress, }: {
4
4
  api: NovelApi;
5
5
  project: ProjectState | null;
6
6
  refresh: () => void | Promise<void>;
@@ -14,5 +14,7 @@ export declare function MangaRoleLibrary({ api, project, refresh, styleId, filte
14
14
  focus?: 'import' | 'cards';
15
15
  /** 是否显示「已建漫剧卡」列表(第⑤步导入页可隐藏,只留导入区)。 */
16
16
  showCards?: boolean;
17
+ /** 全局当前章节(从工作台顶部导航条传入)。 */
18
+ chapterNo?: number | null;
17
19
  onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
18
20
  }): import("react").JSX.Element;
@@ -1,15 +1,12 @@
1
1
  import type { NovelApi } from '../api.ts';
2
- import type { ChapterPlan, ImageModelConfig, ProjectState } from '../../protocol.ts';
3
- export declare function MangaWorkspace({ api, project, chapters, onProjectChanged, imageApiEnabled, imageModels, onProgress, }: {
2
+ import type { ChapterPlan, ProjectState } from '../../protocol.ts';
3
+ export declare function MangaWorkspace({ api, project, chapters, onProjectChanged, onProgress, }: {
4
4
  api: NovelApi;
5
5
  project: ProjectState | null;
6
6
  chapters: ChapterPlan[];
7
7
  /** 方案/资产变更已持久化后触发(刷新项目)。 */
8
8
  onProjectChanged?: () => void | Promise<void>;
9
9
  /** 是否启用生图(漫剧卡出定妆图)。 */
10
- imageApiEnabled?: boolean;
11
- /** 生图模型库(出定妆图时可选择模型)。 */
12
- imageModels?: ImageModelConfig[];
13
10
  /** 上报到「AI进度」控制台(漫剧工作台内所有 LLM/方案操作)。 */
14
11
  onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
15
12
  }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import type { NovelApi } from '../api.ts';
2
+ import type { ProjectState } from '../../protocol.ts';
3
+ export declare function PropLibrary({ api, project, refresh, onProgress, }: {
4
+ api: NovelApi;
5
+ project: ProjectState | null;
6
+ refresh: () => void | Promise<void>;
7
+ onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
8
+ }): import("react").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  import type { NovelApi } from '../api.ts';
2
2
  import type { ProjectState } from '../../protocol.ts';
3
- export declare function SceneLibrary({ api, project, refresh, styleId, filterId, onProgress, }: {
3
+ export declare function SceneLibrary({ api, project, refresh, styleId, filterId, chapterNo: externalChapter, onProgress, }: {
4
4
  api: NovelApi;
5
5
  project: ProjectState | null;
6
6
  /** 场景库变更已持久化后触发(刷新项目)。 */
@@ -9,6 +9,8 @@ export declare function SceneLibrary({ api, project, refresh, styleId, filterId,
9
9
  styleId?: string;
10
10
  /** 可选滤镜风格 id。 */
11
11
  filterId?: string;
12
+ /** 全局当前章节(从工作台顶部导航条传入)。 */
13
+ chapterNo?: number | null;
12
14
  /** 上报到「AI进度」控制台。 */
13
15
  onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
14
16
  }): import("react").JSX.Element;
@@ -1,14 +1,16 @@
1
1
  import type { NovelApi } from '../api.ts';
2
2
  type SettingsTab = 'model' | 'writing' | 'image' | 'files' | 'appearance';
3
3
  type ThemeMode = 'system' | 'light' | 'dark';
4
- type ThemeName = 'liquid' | 'neumorph' | 'macos' | 'clay';
4
+ type ThemeName = 'liquid' | 'neumorph' | 'macos' | 'clay' | 'endfield';
5
+ type EndfieldAccent = 'valley' | 'wuling';
5
6
  type ThemeDensity = 'comfort' | 'compact' | 'spacious';
6
- export declare function SettingsView({ api, onTheme, onSettingsTab, onEditorFontSize, onBackground, onOpacity }: {
7
+ export declare function SettingsView({ api, onTheme, onSettingsTab, onEditorFontSize, onBackground, onOpacity, onEndfieldAccent }: {
7
8
  api: NovelApi;
8
9
  onTheme?: (theme: ThemeName, mode: ThemeMode, density: ThemeDensity) => void;
9
10
  onSettingsTab?: (tab: SettingsTab) => void;
10
11
  onEditorFontSize?: (n: number) => void;
11
12
  onBackground?: (bg: string | undefined, blur: number) => void;
12
13
  onOpacity?: (n: number) => void;
14
+ onEndfieldAccent?: (accent: EndfieldAccent) => void;
13
15
  }): import("react").JSX.Element;
14
16
  export {};
@@ -7,12 +7,12 @@
7
7
  */
8
8
  /**
9
9
  * 内容合规红线(平台硬性要求):所有书籍、所有章节无条件生效,
10
- * 优先级高于单书大纲/圣经中的任何设定与作者自定义红线。
10
+ * 优先级高于单书大纲/道藏中的任何设定与作者自定义红线。
11
11
  * 注入点:章节生成系统提示 + 审稿系统提示(命中即 high)。
12
12
  */
13
13
  export declare const COMPLIANCE_REDLINES: ReadonlyArray<string>;
14
14
  import type { Context } from '@deepseek-ai/cordis';
15
- import type { AdaptationDimension, AdaptAnalyzeResponse, AdaptationMapping, AdaptationRules, AdaptProposeResponse, AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, StoryboardSkeleton, StoryboardTable, StoryboardPrompt, AddModelRequest, AddModelResponse, LlmModelsResponse, LlmVendorsResponse, LlmProvidersResponse, RemoveProviderRequest, RemoveProviderResponse, LlmTestResponse, MangaRoleCandidate, Volume, WorldState, AdaptMaterializeRequest, AdaptMaterializeResponse, AdaptMaterializeSaveRequest, AdaptMaterializeSaveResponse } from './protocol.ts';
15
+ import type { AdaptationDimension, AdaptAnalyzeResponse, AdaptationMapping, AdaptationRules, AdaptProposeResponse, AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, StoryboardSkeleton, StoryboardTable, StoryboardPrompt, AddModelRequest, AddModelResponse, LlmModelsResponse, LlmVendorsResponse, LlmProvidersResponse, RemoveProviderRequest, RemoveProviderResponse, LlmTestResponse, MangaRoleCandidate, Prop, Volume, WorldState, AdaptMaterializeRequest, AdaptMaterializeResponse, AdaptMaterializeSaveRequest, AdaptMaterializeSaveResponse } from './protocol.ts';
16
16
  /** Project state file name inside the output dir. */
17
17
  export declare const PROJECT_FILE = "novel-project.json";
18
18
  /** Chapter output file name, e.g. 第001章_开篇.md */
@@ -70,7 +70,7 @@ export declare function refreshPlotlineProgress(ctx: Context, config: NovelConfi
70
70
  /** ✨ AI 从全书提炼角色库:大纲 + 道藏 + 编年录 + 章节摘要 → 结构化角色清单。 */
71
71
  export declare function extractRoles(ctx: Context, config: NovelConfig, project: ProjectState): Promise<RoleRecord[]>;
72
72
  /** ✨ AI 从全书提炼场景库:正文/编年录 → 高频重要场景的结构化视觉锚点。 */
73
- export declare function extractScenes(ctx: Context, config: NovelConfig, project: ProjectState, styleId?: string, filterId?: string): Promise<SceneCard[]>;
73
+ export declare function extractScenes(ctx: Context, config: NovelConfig, project: ProjectState, chapterNo?: number, styleId?: string, filterId?: string): Promise<SceneCard[]>;
74
74
  /** 从 txt/md 全本文本拆章(纯逻辑,不落盘):识别章节头、剥离重复标题、去重、排序并统一重新编号。 */
75
75
  export declare function splitBookText(raw: string): Array<{
76
76
  no: number;
@@ -104,6 +104,8 @@ export interface RoleVisualPrompt {
104
104
  en: string;
105
105
  tags: string[];
106
106
  source: string;
107
+ /** 即梦/生图通用负面提示词。 */
108
+ negativePrompt?: string;
107
109
  /** 该角色所需情绪表情清单(6-12 个,如 疲惫/麻木/压抑悲伤)。 */
108
110
  expressions?: string[];
109
111
  /** 四类精修提示词(立绘/四视图/表情/细节,一次提炼直接产出)。 */
@@ -140,13 +142,6 @@ export declare function suggestOutlines(ctx: Context, config: NovelConfig, idea:
140
142
  * @param budgetTokens token 预算上限(超过即截断章节取样)。
141
143
  */
142
144
  export declare function breakdownBook(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, scope?: string, preset?: 'quick' | 'standard', budgetTokens?: number): Promise<BreakdownResponse>;
143
- /** 生图接口连通性测试(设置页模型条目用):GET {baseURL}/models,计时返回延迟。 */
144
- export declare function testImageEndpoint(baseURL: string, apiKey: string, model?: string): Promise<{
145
- ok: boolean;
146
- ms: number;
147
- message?: string;
148
- modelFound?: boolean;
149
- }>;
150
145
  /** 对选中的提供商/模型发一次最小真实调用(maxTokens=16),验证 Key / 端点 / 模型可用。 */
151
146
  export declare function testLlmModel(ctx: Context, provider: string, model: string): Promise<LlmTestResponse>;
152
147
  /** 运行时厂商目录:DSH pi-ai 可配置提供方 + 内置适配器,作为「添加模型」下拉。 */
@@ -162,10 +157,11 @@ export declare function removeLlmProvider(ctx: Context, req: RemoveProviderReque
162
157
  * 写入 DSH 凭据 refs,并(必要时)注册/更新 llm-pi-ai provider 路由。
163
158
  */
164
159
  export declare function registerLlmModel(ctx: Context, req: AddModelRequest): Promise<AddModelResponse>;
165
- /** 小说角色库:生成角色定妆图并写回角色卡(imageUrl)。 */
166
- export declare function generateRoleReferenceImage(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, name: string, style?: string, modelId?: string): Promise<string>;
167
- /** 漫剧角色卡:生成定妆图并写回漫剧卡(imageUrl)。 */
168
- export declare function generateMangaRoleReferenceImage(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, cardId: string, style?: string, modelId?: string): Promise<string>;
160
+ /** 获取当前激活漫剧方案的风格(styleId + filterId),用于生图/提示词兜底。 */
161
+ export declare function getActiveMangaStyle(project: ProjectState): {
162
+ styleId?: string;
163
+ filterId?: string;
164
+ };
169
165
  /** 🩺 剧情健康检查:基于已写章节数/各线状态/编年录,判断是否需要新线及添加时机。 */
170
166
  export declare function analyzePlotlineHealth(ctx: Context, config: NovelConfig, project: ProjectState): Promise<PlotlineHealthReport>;
171
167
  /** ✨ AI 剧情方案:基于健康检查结果设计下一阶段方向与建议新线。 */
@@ -208,6 +204,7 @@ export declare function generateChapterStream(ctx: Context, config: NovelConfig,
208
204
  frame: 'done';
209
205
  file: string;
210
206
  chars: number;
207
+ warn?: string;
211
208
  }, void, unknown>;
212
209
  /** Generate a chapter summary (narrative memory). */
213
210
  export declare function summarizeChapter(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number): Promise<string>;
@@ -216,6 +213,11 @@ export declare function summarizeChapter(ctx: Context, config: NovelConfig, proj
216
213
  * 只做画面层:景别/机位运镜/时长/画面/台词/音效/光效 + 状态连续;禁止改剧情(骨架只读)。
217
214
  */
218
215
  export declare function generateStoryboardTable(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number, skeleton: StoryboardSkeleton, styleId?: string, filterId?: string): Promise<StoryboardTable>;
216
+ /**
217
+ * 提炼常驻道具(跨镜头需一致):从已写章节正文识别反复出现的关键道具 + 一行统一外观描述。
218
+ * 生成分镜提示词前自动调用,若道具库为空则补齐;道具库存 project.props,注入提示词保持跨镜头一致。
219
+ */
220
+ export declare function extractProps(ctx: Context, config: NovelConfig, project: ProjectState): Promise<Prop[]>;
219
221
  /**
220
222
  * 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。
221
223
  * 每镜头一段:风格词块(基底+滤镜)+ 画面内容(角色动作/服装标志物)+ 机位运镜 + 光效。
@@ -292,11 +294,6 @@ export declare function materializeAdaptedBook(ctx: Context, config: NovelConfig
292
294
  }): Promise<Omit<AdaptMaterializeResponse, 'book'>>;
293
295
  /** 把预览/微调后的新书资料写入输出目录并返回摘要(书架登记由路由负责)。 */
294
296
  export declare function saveMaterializedBook(outDir: string, bookName: string, data: Omit<AdaptMaterializeSaveRequest, 'bookName' | 'outputDir'>): Omit<AdaptMaterializeSaveResponse, 'book'>;
295
- /**
296
- * 摘要 + 事实抽取合并为一次 LLM 调用(省一次调用与一次正文输入,
297
- * 批量生成时整体开销约省 25%)。
298
- * @returns 摘要与新增事实条数(失败返回空,调用方 best-effort)。
299
- */
300
297
  export declare function summarizeAndExtractFacts(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number): Promise<{
301
298
  summary: string;
302
299
  factCount: number;
@@ -325,7 +322,7 @@ export declare function generateBlurb(ctx: Context, config: NovelConfig, project
325
322
  export declare function bookOverview(project: ProjectState, scope?: 'recent' | 'full' | number): string;
326
323
  /** 一条影响分析结果(改动波及处)。 */
327
324
  export interface ImpactItem {
328
- /** 位置:章节号 / 大纲 / 设定圣经 / 大世界 / 事实库 / 简介。 */
325
+ /** 位置:章节号 / 大纲 / 道藏 / 大世界 / 事实库 / 简介。 */
329
326
  location: string;
330
327
  /** 原文片段(定位用)。 */
331
328
  quote: string;
@@ -341,7 +338,7 @@ export interface ImpactItem {
341
338
  export declare function analyzeImpact(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, change: string): Promise<ImpactItem[]>;
342
339
  /** 把大世界结构化数据渲染成提示词块(境界体系按顺序强约束)。 */
343
340
  export declare function renderWorld(world: WorldState | undefined): string;
344
- /** AI 提炼大世界:从大纲 + 设定圣经生成结构化境界体系/区域/势力。 */
341
+ /** AI 提炼大世界:从大纲 + 道藏生成结构化境界体系/区域/势力。 */
345
342
  export declare function extractWorld(ctx: Context, config: NovelConfig, project: ProjectState): Promise<WorldState>;
346
343
  /**
347
344
  * 事实库回填:对历史已生成章节批量抽取事实(无事实记录的旧章节)。
@@ -371,3 +368,35 @@ export declare function exportBook(outputDir: string, project: ProjectState, for
371
368
  chars: number;
372
369
  chapters: number;
373
370
  };
371
+ /** 漫剧资产库根目录:outputDir/manga-assets */
372
+ export declare function mangaAssetsDir(outputDir: string): string;
373
+ /** 保存角色定妆图到资产库:manga-assets/角色/角色名/标签.png */
374
+ export declare function saveMangaRoleImage(outputDir: string, roleName: string, label: string, dataUrl: string): string;
375
+ /** 保存角色提示词到资产库:manga-assets/角色/角色名/提示词.txt */
376
+ export declare function saveMangaRolePrompt(outputDir: string, roleName: string, zh: string, en: string, negative?: string): string;
377
+ /** 保存场景底图到资产库:manga-assets/场景/场景名.png */
378
+ export declare function saveMangaSceneImage(outputDir: string, sceneName: string, label: string, dataUrl: string): string;
379
+ /** 保存分镜即梦脚本到资产库:manga-assets/分镜脚本/第N章-标题.md */
380
+ export declare function saveMangaStoryboardScript(outputDir: string, chapterNo: number, title: string, markdown: string): string;
381
+ /** 保存「即梦素材包」到资产库:manga-assets/素材包/第N章-标题·即梦素材包.md */
382
+ export declare function saveMangaAssetPackage(outputDir: string, chapterNo: number, title: string, markdown: string): string;
383
+ /** 保存场景中文生图提示词到资产库:manga-assets/场景/场景名/提示词.txt */
384
+ export declare function saveMangaScenePrompt(outputDir: string, sceneName: string, zh: string, negative?: string): string;
385
+ /** 保存逐镜即梦提示词到资产库:manga-assets/分镜脚本/第N章-标题-提示词.md */
386
+ export declare function saveMangaChapterPrompts(outputDir: string, chapterNo: number, title: string, markdown: string): string;
387
+ export interface AutoGenerateResult {
388
+ chapterNo: number;
389
+ skeletonBeats: number;
390
+ shotCount: number;
391
+ promptCount: number;
392
+ importedRoles: number;
393
+ needMakeupRoles: number;
394
+ extraRoles: number;
395
+ pendingCandidates: number;
396
+ pendingRoleNames: string[];
397
+ }
398
+ /**
399
+ * 一键生成:骨架 → 分镜表 → 角色提名 → 自动导入(匹配成功的)→ 自动分级 → 视频提示词。
400
+ * 匹配模糊/小说库缺失的角色保留在候选列表,不自动导入。
401
+ */
402
+ export declare function autoGenerateMangaChapter(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number, styleId?: string, filterId?: string): Promise<AutoGenerateResult>;
@@ -18,7 +18,7 @@ export declare const inject: string[];
18
18
  * settings surface edits. Spelled here rather than imported: the browser half
19
19
  * spells the same value and must not depend on a Host package.
20
20
  */
21
- export declare const NOVEL_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
21
+ export declare const NOVEL_SETTINGS_NAMESPACE: "dsh-novel-forge";
22
22
  /** Plugin config, validated by the same-named schemastery schema. */
23
23
  export interface Config {
24
24
  /** When true (default), a system-prompt section announces the plugin to every agent. */
@@ -68,7 +68,7 @@ export interface Config {
68
68
  }
69
69
  export declare const Config: z<Config>;
70
70
  /** Model-facing announcement: plugin presence, capabilities, and limits. */
71
- export declare const NOVEL_GUIDANCE = "\u672C\u673A\u5DF2\u5B89\u88C5 dsh-novel-forge \u63D2\u4EF6\uFF08AI \u7F16\u8BD1\u5C0F\u8BF4\u5DE5\u4F5C\u53F0\uFF09\uFF1A\u4FA7\u8FB9\u680F\u300C\u5C0F\u8BF4\u5DE5\u574A\u300D\u5165\u53E3\u3002\u80FD\u529B\uFF1A\u8BFB\u53D6 docx \u5927\u7EB2\u6216\u7C98\u8D34\u5927\u7EB2\u6587\u672C\uFF1B\u7528 LLM \u63D0\u70BC\u9053\u85CF\uFF08\u4EBA\u8BBE/\u4E16\u754C\u89C2/\u91D1\u624B\u6307\u89C4\u5219/\u5199\u4F5C\u7EA2\u7EBF\uFF0C\u5373\u8BBE\u5B9A\u5723\u7ECF\uFF09\uFF1B\u751F\u6210\u5377\u8BA1\u5212\u4E0E\u7AE0\u8282\u8BA1\u5212\uFF1B\u9010\u7AE0\u8C03\u7528 LLM \u751F\u6210 3000-4000 \u5B57\u6B63\u6587\u5E76\u4FDD\u5B58\u4E3A Markdown\uFF08\u9ED8\u8BA4\u8F93\u51FA\u5230\u7528\u6237\u4E3B\u76EE\u5F55 ~/.dsh/novels\uFF09\uFF1B\u6BCF\u7AE0\u81EA\u52A8\u751F\u6210\u6458\u8981\uFF08\u53D9\u4E8B\u8BB0\u5FC6\uFF09\u3001\u81EA\u52A8 AI \u5BA1\u7A3F\uFF08\u4EBA\u8BBE/\u8BBE\u5B9A/\u7EA2\u7EBF/\u6587\u7B14/\u723D\u70B9/\u903B\u8F91\uFF09\uFF0C\u652F\u6301\u6309\u5BA1\u7A3F\u610F\u89C1\u91CD\u5199\u3001\u53BB AI \u5473\u6DA6\u8272\u3001\u6697\u7EBF\uFF08\u4F0F\u7B14\uFF09\u7BA1\u7406\u3001\u6279\u91CF\u8FDE\u5199\u4E0E\u5168\u672C\u5BFC\u51FA\uFF08txt/md\uFF09\u3002\u9650\u5236\uFF1A\u751F\u6210\u6D88\u8017 LLM API \u989D\u5EA6\uFF1B\u8F93\u51FA\u76EE\u5F55\u4E0E\u6A21\u578B\u53EF\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u4FEE\u6539\uFF1B\u7AE0\u8282\u6B63\u6587\u8D28\u91CF\u53D6\u51B3\u4E8E\u5927\u7EB2\u5B8C\u6574\u5EA6\u3002\u7528\u6237\u63D0\u5230\u300C\u5C0F\u8BF4 / \u5927\u7EB2 / \u5199\u5C0F\u8BF4 / \u7AE0\u8282 / \u5BA1\u7A3F / \u6DA6\u8272\u300D\u65F6\u5373\u6307\u672C\u63D2\u4EF6\uFF0C\u8BF7\u636E\u6B64\u534F\u4F5C\u3002";
71
+ export declare const NOVEL_GUIDANCE = "\u672C\u673A\u5DF2\u5B89\u88C5 dsh-novel-forge \u63D2\u4EF6\uFF08AI \u7F16\u8BD1\u5C0F\u8BF4\u5DE5\u4F5C\u53F0\uFF09\uFF1A\u4FA7\u8FB9\u680F\u300C\u5C0F\u8BF4\u5DE5\u574A\u300D\u5165\u53E3\u3002\u80FD\u529B\uFF1A\u8BFB\u53D6 docx \u5927\u7EB2\u6216\u7C98\u8D34\u5927\u7EB2\u6587\u672C\uFF1B\u7528 LLM \u63D0\u70BC\u9053\u85CF\uFF08\u4EBA\u8BBE/\u4E16\u754C\u89C2/\u91D1\u624B\u6307\u89C4\u5219/\u5199\u4F5C\u7EA2\u7EBF\uFF09\uFF1B\u751F\u6210\u5377\u8BA1\u5212\u4E0E\u7AE0\u8282\u8BA1\u5212\uFF1B\u9010\u7AE0\u8C03\u7528 LLM \u751F\u6210 3000-4000 \u5B57\u6B63\u6587\u5E76\u4FDD\u5B58\u4E3A Markdown\uFF08\u9ED8\u8BA4\u8F93\u51FA\u5230\u7528\u6237\u4E3B\u76EE\u5F55 ~/.dsh/novels\uFF09\uFF1B\u6BCF\u7AE0\u81EA\u52A8\u751F\u6210\u6458\u8981\uFF08\u53D9\u4E8B\u8BB0\u5FC6\uFF09\u3001\u81EA\u52A8 AI \u5BA1\u7A3F\uFF08\u4EBA\u8BBE/\u8BBE\u5B9A/\u7EA2\u7EBF/\u6587\u7B14/\u723D\u70B9/\u903B\u8F91\uFF09\uFF0C\u652F\u6301\u6309\u5BA1\u7A3F\u610F\u89C1\u91CD\u5199\u3001\u53BB AI \u5473\u6DA6\u8272\u3001\u6697\u7EBF\uFF08\u4F0F\u7B14\uFF09\u7BA1\u7406\u3001\u6279\u91CF\u8FDE\u5199\u4E0E\u5168\u672C\u5BFC\u51FA\uFF08txt/md\uFF09\u3002\u9650\u5236\uFF1A\u751F\u6210\u6D88\u8017 LLM API \u989D\u5EA6\uFF1B\u8F93\u51FA\u76EE\u5F55\u4E0E\u6A21\u578B\u53EF\u5728\u63D2\u4EF6\u8BBE\u7F6E\u4E2D\u4FEE\u6539\uFF1B\u7AE0\u8282\u6B63\u6587\u8D28\u91CF\u53D6\u51B3\u4E8E\u5927\u7EB2\u5B8C\u6574\u5EA6\u3002\u7528\u6237\u63D0\u5230\u300C\u5C0F\u8BF4 / \u5927\u7EB2 / \u5199\u5C0F\u8BF4 / \u7AE0\u8282 / \u5BA1\u7A3F / \u6DA6\u8272\u300D\u65F6\u5373\u6307\u672C\u63D2\u4EF6\uFF0C\u8BF7\u636E\u6B64\u534F\u4F5C\u3002";
72
72
  /** Resolve a config-like value into the full runtime config. */
73
73
  export declare function resolveConfig(value: Partial<Config> | undefined): NovelConfig;
74
74
  /**
@@ -0,0 +1,22 @@
1
+ /**
2
+ * 题材规则库(可插拔)—— 漫剧分镜/提示词生成的「题材专用规则」。
3
+ * 参考短剧工业导演规范:不同题材用不同的视觉语言 / 打斗 / 特效规则,
4
+ * 按漫剧方案的 genre 注入 generateStoryboardPrompts,避免「一套模板跑所有题材」。
5
+ * 每个题材给一组「生成提示词时必须遵守的题材规则」;未选题材则不注入(走通用规则)。
6
+ */
7
+ export interface GenreRule {
8
+ /** 题材 id。 */
9
+ id: string;
10
+ /** 题材名(展示)。 */
11
+ label: string;
12
+ /** 该题材的生成提示词核心规则(每行一条,注入生成时)。 */
13
+ rules: string[];
14
+ }
15
+ /** 内置题材(通用题材 default 为空规则)。 */
16
+ export declare const GENRES: GenreRule[];
17
+ /** 通用题材(空规则,走通用生成)。 */
18
+ export declare const DEFAULT_GENRE: GenreRule;
19
+ /** 按题材 id 取规则(未找到返回通用)。 */
20
+ export declare function getGenreRules(id?: string): string[];
21
+ /** 取题材 label(展示用)。 */
22
+ export declare function getGenreLabel(id?: string): string;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * 统一上下文组装与相关设定检索
3
+ *
4
+ * 取代各阶段各自拼装 prompt,消除「生成看得到、审稿看不到」的断层。
5
+ * 所有阶段通过 buildChapterContext 获取同一来源的事实与设定。
6
+ */
7
+ import type { ProjectState, ChapterPlan, StoryBible, RoleRecord, ChapterFact, Foreshadow, Plotline } from './protocol';
8
+ export interface ChapterContext {
9
+ /** 平台合规红线(永远全量) */
10
+ complianceRedLines: string[];
11
+ /** 本书写作红线(永远全量) */
12
+ bookRedLines: string[];
13
+ /** 当前章相关角色卡(全量信息) */
14
+ relevantRoles: Array<{
15
+ name: string;
16
+ role: string;
17
+ traits: string[];
18
+ goals?: string;
19
+ knowledge?: string[];
20
+ }>;
21
+ /** 当前章相关道藏规则 */
22
+ relevantWorldRules: string[];
23
+ /** 活跃剧情线 */
24
+ activePlotlines: Plotline[];
25
+ /** 未回收伏笔 */
26
+ activeForeshadows: Foreshadow[];
27
+ /** 上一章结尾原文 */
28
+ prevChapterTail: string;
29
+ /** 上一章摘要 */
30
+ prevChapterSummary?: string;
31
+ /** 最近事实(近因记忆,top20) */
32
+ recentFacts: string[];
33
+ /** 相关旧事实(按本章 beats 检索,top15) */
34
+ relatedFacts: string[];
35
+ /** 当前卷大纲 */
36
+ currentVolumeOutline: string;
37
+ /** 本章 beats */
38
+ beats: string;
39
+ /** 本章标题 */
40
+ chapterTitle: string;
41
+ }
42
+ export interface ContextBuildOptions {
43
+ /** 阶段:writing/review/revise/polish/plan */
44
+ stage?: 'writing' | 'review' | 'revise' | 'polish' | 'plan';
45
+ /** 是否注入完整角色卡(false 时只注入角色名+定位) */
46
+ fullRoleCards?: boolean;
47
+ /** 相关事实检索上限 */
48
+ relatedFactsLimit?: number;
49
+ /** 最近事实数量 */
50
+ recentFactsLimit?: number;
51
+ }
52
+ /**
53
+ * 相关事实检索:trigram 重合度 + 角色名命中加权 + 近因加权
54
+ * 从 generateChapterStream 抽取,扩展为通用函数。
55
+ */
56
+ export declare function retrieveRelatedFacts(facts: ChapterFact[], beatsText: string, roleNames: string[], limit?: number): string[];
57
+ /**
58
+ * 相关角色检索:beats 中出现的角色 + 主角/主要反派永远全量
59
+ */
60
+ export declare function retrieveRelevantRoles(bible: StoryBible | undefined, roles: RoleRecord[] | undefined, beatsText: string): ChapterContext['relevantRoles'];
61
+ /**
62
+ * 构建章节统一上下文
63
+ *
64
+ * 各阶段调用此函数获取同一来源的事实与设定,消除上下文断层。
65
+ * 检索结果不足时自动回退全量,保证不丢失关键信息。
66
+ */
67
+ export declare function buildChapterContext(project: ProjectState, chapter: ChapterPlan, outputDir: string, options?: ContextBuildOptions): ChapterContext;
68
+ /**
69
+ * 将上下文渲染为 prompt 文本块
70
+ * 各阶段可按需选择注入哪些块。
71
+ */
72
+ export declare function renderContextBlocks(ctx: ChapterContext): {
73
+ rolesBlock: string;
74
+ worldRulesBlock: string;
75
+ factsBlock: string;
76
+ plotlinesBlock: string;
77
+ foreshadowsBlock: string;
78
+ continuityBlock: string;
79
+ redLinesBlock: string;
80
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 提示词共享常量与工具
3
+ *
4
+ * 所有 JSON 输出规则、通用约束集中在此,避免各阶段重复定义、互相打架。
5
+ */
6
+ /** JSON 输出规则(所有要求模型输出 JSON 的地方共用) */
7
+ export declare const JSON_OUTPUT_RULES: string[];
8
+ /** JSON 输出规则的紧凑版(适合放在提示词末尾) */
9
+ export declare const JSON_OUTPUT_RULES_COMPACT: string;
10
+ /**
11
+ * 估算 prompt 的 token 数(粗略估算,用于上下文预算控制)
12
+ * 中文约 1.7 字/token,英文约 4 字符/token
13
+ */
14
+ export declare function estimateTokens(text: string): number;
15
+ /**
16
+ * 按 token 预算截断文本(保留开头,末尾加省略标记)
17
+ * 用于控制单块上下文不超预算。
18
+ */
19
+ export declare function truncateByTokens(text: string, maxTokens: number, marker?: string): string;
20
+ /** 通用「只改表达不改情节」约束(润色/局部修订共用) */
21
+ export declare const EXPRESSION_ONLY_RULE: string[];
22
+ /** 章节上下文各阶段的 token 预算(粗略,用于控制注入量) */
23
+ export declare const CONTEXT_BUDGET: {
24
+ /** 章节生成:道藏+角色+大纲+事实+伏笔 */
25
+ readonly writing: 12000;
26
+ /** AI 审稿:道藏+角色+事实+正文 */
27
+ readonly review: 10000;
28
+ /** 修订:原意见+相关事实+目标正文 */
29
+ readonly revise: 8000;
30
+ /** 润色:风格资产+原正文 */
31
+ readonly polish: 6000;
32
+ /** 分章规划:大纲+道藏+角色+近期事实 */
33
+ readonly plan: 15000;
34
+ };
35
+ export type ContextStage = keyof typeof CONTEXT_BUDGET;