@waterwx/dsh-novel-forge 1.4.1 → 1.6.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 (50) hide show
  1. package/assets/styles/arcane-thick-3d.webp +0 -0
  2. package/assets/styles/chinese-ink.webp +0 -0
  3. package/assets/styles/clay-stopmotion-3d.webp +0 -0
  4. package/assets/styles/dark-ghibli.webp +0 -0
  5. package/assets/styles/dark-gothic-3d.webp +0 -0
  6. package/assets/styles/film-photo.webp +0 -0
  7. package/assets/styles/guofeng-heavy.webp +0 -0
  8. package/assets/styles/horror-game-3d.webp +0 -0
  9. package/assets/styles/japan-cel-dark.webp +0 -0
  10. package/assets/styles/korean-webtoon.webp +0 -0
  11. package/assets/styles/low-cyberpunk-3d.webp +0 -0
  12. package/assets/styles/nextgen-cg.webp +0 -0
  13. package/assets/styles/noir-film.webp +0 -0
  14. package/assets/styles/openworld-survival.webp +0 -0
  15. package/assets/styles/paper-cut-3d.webp +0 -0
  16. package/assets/styles/pixar-adult-3d.webp +0 -0
  17. package/assets/styles/pop-marvel-2d.webp +0 -0
  18. package/assets/styles/shinkai-anime.webp +0 -0
  19. package/assets/styles/tactical-stealth.webp +0 -0
  20. package/assets/styles/vaporwave-3d.webp +0 -0
  21. package/assets/styles/vhs90.webp +0 -0
  22. package/lib/client.js +10541 -8910
  23. package/lib/client.js.map +1 -1
  24. package/lib/index.js +763 -36
  25. package/lib/index.js.map +1 -1
  26. package/lib/types/client/api.d.ts +8 -0
  27. package/lib/types/client/panel/MangaWorkspace.d.ts +13 -0
  28. package/lib/types/client/panel/NovelPanel.d.ts +1 -1
  29. package/lib/types/client/panel/RoleVisualPanel.d.ts +13 -0
  30. package/lib/types/client/panel/SceneLibrary.d.ts +14 -0
  31. package/lib/types/client/panel/StoryboardTab.d.ts +15 -0
  32. package/lib/types/client/panel/StyleCard.d.ts +8 -0
  33. package/lib/types/client/panel/StyleGallery.d.ts +1 -0
  34. package/lib/types/engine.d.ts +20 -4
  35. package/lib/types/protocol.d.ts +159 -0
  36. package/lib/types/style-library.d.ts +33 -0
  37. package/package.json +2 -1
  38. package/src/client/api.ts +20 -0
  39. package/src/client/panel/MangaWorkspace.tsx +293 -0
  40. package/src/client/panel/NovelPanel.tsx +8 -638
  41. package/src/client/panel/RoleVisualPanel.tsx +468 -0
  42. package/src/client/panel/SceneLibrary.tsx +395 -0
  43. package/src/client/panel/StoryboardTab.tsx +370 -0
  44. package/src/client/panel/StyleCard.tsx +90 -0
  45. package/src/client/panel/StyleGallery.tsx +58 -0
  46. package/src/client/panel/panel.module.css +12 -12
  47. package/src/engine.ts +377 -25
  48. package/src/protocol.ts +174 -0
  49. package/src/routes.ts +193 -3
  50. package/src/style-library.ts +78 -0
@@ -18,6 +18,14 @@ export declare class NovelApi {
18
18
  }>;
19
19
  /** 反推大纲:从已写章节正文反向生成全书总纲(NDJSON 流)。 */
20
20
  outlineReverse(onFrame: (frame: JobFrame) => void): Promise<void>;
21
+ /** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
22
+ storyboardTable(chapterNo: number, skeleton: import('../protocol.ts').StoryboardSkeleton, styleId?: string, filterId?: string): Promise<import('../protocol.ts').StoryboardTableResponse>;
23
+ /** 漫剧方案管理:create / remove / activate。 */
24
+ manhuaPlans(req: import('../protocol.ts').MangaPlansRequest): Promise<import('../protocol.ts').MangaPlansResponse>;
25
+ /** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
26
+ storyboardPrompts(chapterNo: number, table: import('../protocol.ts').StoryboardTable, styleId?: string, filterId?: string): Promise<import('../protocol.ts').StoryboardPromptsResponse>;
27
+ /** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
28
+ storyboardSkeleton(chapterNo: number): Promise<import('../protocol.ts').StoryboardSkeletonResponse>;
21
29
  /** 开书想法 → AI 大纲:生成 count 个方案(换批时传 exclude 避开已暂留方向)。 */
22
30
  outlineSuggest(idea: string, count?: number, exclude?: string[]): Promise<import('../protocol.ts').OutlineSuggestResponse>;
23
31
  /** 拆书分析:对已写章节做结构/人物/文风/卖点体检。 */
@@ -0,0 +1,13 @@
1
+ import type { NovelApi } from '../api.ts';
2
+ import type { ChapterPlan, ProjectState } from '../../protocol.ts';
3
+ export declare function MangaWorkspace({ api, project, chapters, onProjectChanged, imageApiEnabled, onProgress, }: {
4
+ api: NovelApi;
5
+ project: ProjectState | null;
6
+ chapters: ChapterPlan[];
7
+ /** 方案/资产变更已持久化后触发(刷新项目)。 */
8
+ onProjectChanged?: () => void | Promise<void>;
9
+ /** 是否启用豆包生图。 */
10
+ imageApiEnabled?: boolean;
11
+ /** 上报到「工作进度」控制台(漫剧工作台内所有 LLM/方案操作)。 */
12
+ onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
13
+ }): import("react").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import type { NovelApi } from '../api.ts';
2
2
  import type { PanelController } from './controller.ts';
3
3
  /** The panel's tab identifiers. */
4
- export type NovelTab = 'workflow' | 'overview' | 'blurb' | 'plan' | 'bible' | 'world' | 'foreshadow' | 'assistant' | 'settings' | 'characters' | 'roles' | 'facts' | 'plotlines' | 'reviews' | 'progress' | 'breakdown' | 'roleImage' | 'scenes' | 'assetsGenre' | 'assetsProgression' | 'assetsTemplates' | 'assetsRules' | 'assetsStyle' | 'run' | 'book' | 'assets';
4
+ export type NovelTab = 'workflow' | 'overview' | 'blurb' | 'plan' | 'bible' | 'world' | 'foreshadow' | 'assistant' | 'settings' | 'characters' | 'roles' | 'facts' | 'plotlines' | 'reviews' | 'progress' | 'breakdown' | 'assetsGenre' | 'assetsProgression' | 'assetsTemplates' | 'assetsRules' | 'assetsStyle' | 'run' | 'manhua' | 'book' | 'assets';
5
5
  /** Panel shell props. */
6
6
  export interface NovelPanelProps {
7
7
  /** The panel state owner (open/close/toggle). */
@@ -0,0 +1,13 @@
1
+ import type { NovelApi } from '../api.ts';
2
+ import type { ProjectState } from '../../protocol.ts';
3
+ export declare function RoleVisualPanel({ api, project, refresh, styleId, filterId, imageApiEnabled, onGotoRoles, onProgress, }: {
4
+ api: NovelApi;
5
+ project: ProjectState | null;
6
+ refresh: () => void | Promise<void>;
7
+ styleId?: string;
8
+ filterId?: string;
9
+ imageApiEnabled?: boolean;
10
+ onGotoRoles?: () => void;
11
+ /** 上报到「工作进度」控制台(角色形象页 / 漫剧工作台共用)。 */
12
+ onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,14 @@
1
+ import type { NovelApi } from '../api.ts';
2
+ import type { ProjectState } from '../../protocol.ts';
3
+ export declare function SceneLibrary({ api, project, refresh, styleId, filterId, onProgress, }: {
4
+ api: NovelApi;
5
+ project: ProjectState | null;
6
+ /** 场景库变更已持久化后触发(刷新项目)。 */
7
+ refresh: () => void | Promise<void>;
8
+ /** 提炼场景时的漫剧基底风格 id(提示词按方案风格措辞)。 */
9
+ styleId?: string;
10
+ /** 可选滤镜风格 id。 */
11
+ filterId?: string;
12
+ /** 上报到「工作进度」控制台。 */
13
+ onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
14
+ }): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import type { NovelApi } from '../api.ts';
2
+ import type { ChapterPlan, ProjectState } from '../../protocol.ts';
3
+ export declare function StoryboardTab({ api, project, chapters, onProjectChanged, styleId, filterId, onProgress, }: {
4
+ api: NovelApi;
5
+ project: ProjectState | null;
6
+ chapters: ChapterPlan[];
7
+ /** 生成成功且已持久化后触发(刷新项目,切章/重进可恢复)。 */
8
+ onProjectChanged?: () => void | Promise<void>;
9
+ /** 漫剧基底风格 id(画面措辞随风格)。 */
10
+ styleId?: string;
11
+ /** 可选滤镜风格 id。 */
12
+ filterId?: string;
13
+ /** 上报到「工作进度」控制台(分镜三步生成)。 */
14
+ onProgress?: (text: string, kind?: 'info' | 'done' | 'error') => void;
15
+ }): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import type { ArtStyle } from '../../style-library.ts';
2
+ export declare function StyleCard({ style, selected, onClick, }: {
3
+ style: ArtStyle;
4
+ /** 选中态(高亮边框)。 */
5
+ selected?: boolean;
6
+ /** 点击卡片(选风格)。 */
7
+ onClick?: () => void;
8
+ }): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function StyleGallery(): import("react").JSX.Element;
@@ -12,7 +12,7 @@
12
12
  */
13
13
  export declare const COMPLIANCE_REDLINES: ReadonlyArray<string>;
14
14
  import type { Context } from '@deepseek-ai/cordis';
15
- import type { AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, Volume, WorldState } from './protocol.ts';
15
+ import type { AuditIssue, AuthorReview, BreakdownResponse, ChapterPlan, Foreshadow, NovelConfig, OutlineCandidate, Plotline, PlotlineHealthReport, PlotlinePlan, ProjectState, ReviewReport, RoleRecord, RoleStatusCard, SceneCard, StoryBible, StoryboardSkeleton, StoryboardTable, StoryboardPrompt, Volume, WorldState } 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): Promise<SceneCard[]>;
73
+ export declare function extractScenes(ctx: Context, config: NovelConfig, project: ProjectState, styleId?: string, filterId?: string): Promise<SceneCard[]>;
74
74
  /** 从 txt/md 全本文本拆章(纯逻辑,不落盘):识别章节头、剥离重复标题、去重、排序并统一重新编号。 */
75
75
  export declare function splitBookText(raw: string): Array<{
76
76
  no: number;
@@ -113,12 +113,12 @@ export interface RoleVisualPrompt {
113
113
  * 为单个角色提炼「动漫形象描述词」:扫描该角色出场的已写章节正文,
114
114
  * 截取含外貌描写的段落,交给 LLM 提炼中文描述 + 英文绘图标签。
115
115
  */
116
- export declare function extractRoleVisual(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, roleName: string): Promise<RoleVisualPrompt>;
116
+ export declare function extractRoleVisual(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, roleName: string, styleId?: string, filterId?: string): Promise<RoleVisualPrompt>;
117
117
  /**
118
118
  * 角色四类生图提示词精修包(promptKit):以锚点 + 表情清单 + 视觉规则为输入,
119
119
  * LLM 产出 立绘/四视图/表情×N/细节 四套 zh+en 提示词(比前端拼装更精炼)。
120
120
  */
121
- export declare function generateRolePromptKit(ctx: Context, config: NovelConfig, project: ProjectState, roleName: string): Promise<RoleRecord['promptKit']>;
121
+ export declare function generateRolePromptKit(ctx: Context, config: NovelConfig, project: ProjectState, roleName: string, styleId?: string, filterId?: string): Promise<RoleRecord['promptKit']>;
122
122
  /** ✨ 从道藏/红线提炼「视觉世界观规则」:生图/生视频必须遵守的设定纠偏(如"商品=人,禁止常规超市商品")。 */
123
123
  export declare function extractVisualRules(ctx: Context, config: NovelConfig, project: ProjectState): Promise<string[]>;
124
124
  /**
@@ -182,6 +182,22 @@ export declare function generateChapterStream(ctx: Context, config: NovelConfig,
182
182
  }, void, unknown>;
183
183
  /** Generate a chapter summary (narrative memory). */
184
184
  export declare function summarizeChapter(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number): Promise<string>;
185
+ /**
186
+ * 分镜·导演级:剧情骨架 → 分镜表(镜头级)。
187
+ * 只做画面层:景别/机位运镜/时长/画面/台词/音效/光效 + 状态连续;禁止改剧情(骨架只读)。
188
+ */
189
+ export declare function generateStoryboardTable(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number, skeleton: StoryboardSkeleton, styleId?: string, filterId?: string): Promise<StoryboardTable>;
190
+ /**
191
+ * 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。
192
+ * 每镜头一段:风格词块(基底+滤镜)+ 画面内容(角色动作/服装标志物)+ 机位运镜 + 光效。
193
+ * 提示词聚焦画面与镜头(视频模型无音频,台词/音效不注入)。
194
+ */
195
+ export declare function generateStoryboardPrompts(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number, table: StoryboardTable, styleId?: string, filterId?: string): Promise<StoryboardPrompt[]>;
196
+ /**
197
+ * 分镜·编剧级:单章 → 剧情骨架(节拍链)。
198
+ * 只做故事层(事件/情绪/功能/因果),不做画面;导演级分镜在其上展开。
199
+ */
200
+ export declare function generateStoryboardSkeleton(ctx: Context, config: NovelConfig, project: ProjectState, outputDir: string, chapterNo: number): Promise<StoryboardSkeleton>;
185
201
  /**
186
202
  * 反向推大纲:从已写章节正文反推出全书总纲(分卷 + 章节要点 + 主线/人物弧线/伏笔清单)。
187
203
  * 两阶段:分批提取章节事件摘要 → 汇总生成大纲。不修改章节/设定,只返回大纲文本。
@@ -41,6 +41,14 @@ export declare const NOVEL_API: {
41
41
  readonly bookshelfImportText: "/api/dsh-novel-forge/bookshelf/import-text";
42
42
  /** 导入 txt/md 全本:拆章预览(不落盘)。 */
43
43
  readonly bookshelfImportTextPreview: "/api/dsh-novel-forge/bookshelf/import-text/preview";
44
+ /** 漫剧方案管理:create/remove/activate。 */
45
+ readonly manhuaPlans: "/api/dsh-novel-forge/manhua/plans";
46
+ /** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
47
+ readonly storyboardSkeleton: "/api/dsh-novel-forge/storyboard/skeleton";
48
+ /** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
49
+ readonly storyboardTable: "/api/dsh-novel-forge/storyboard/table";
50
+ /** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
51
+ readonly storyboardPrompts: "/api/dsh-novel-forge/storyboard/prompts";
44
52
  /** 重置项目(可选携带新大纲):清空设定/卷/章节/伏笔/资产/事实库。 */
45
53
  readonly reset: "/api/dsh-novel-forge/reset";
46
54
  /** 全书一致性质检:LLM 扫描已生成章节,输出矛盾问题清单。 */
@@ -190,6 +198,141 @@ export interface BookImportTextPreviewResponse {
190
198
  /** 因内容过短被跳过的章节标题列表。 */
191
199
  skipped: string[];
192
200
  }
201
+ /** 分镜·编剧级:剧情骨架中的一节拍。 */
202
+ export interface StoryboardBeat {
203
+ /** 节拍 id(如 b1、b2)。 */
204
+ id: string;
205
+ /** 事件一句话(发生了什么)。 */
206
+ event: string;
207
+ /** 情绪走向(如 压抑→隐忍→惊惧)。 */
208
+ emotion: string;
209
+ /** 叙事功能:铺垫/冲突/转折/高潮/收束/伏笔/人物塑造。 */
210
+ function: string;
211
+ /** 因果:承接上一节拍的原因(可选)。 */
212
+ cause?: string;
213
+ }
214
+ /** 分镜·编剧级:单章剧情骨架。 */
215
+ export interface StoryboardSkeleton {
216
+ chapterNo: number;
217
+ /** 本章弧线一句话(起承转合)。 */
218
+ arc: string;
219
+ /** 剧情节拍链(时间顺序,因果连贯)。 */
220
+ beats: StoryboardBeat[];
221
+ }
222
+ /** POST /storyboard/skeleton 请求:生成单章剧情骨架。 */
223
+ export interface StoryboardSkeletonRequest {
224
+ chapterNo: number;
225
+ }
226
+ /** POST /storyboard/skeleton 响应。 */
227
+ export interface StoryboardSkeletonResponse {
228
+ skeleton: StoryboardSkeleton;
229
+ }
230
+ /** 分镜·导演级:一个镜头。 */
231
+ export interface StoryboardShot {
232
+ /** 镜头 id(如 s1、s2)。 */
233
+ id: string;
234
+ /** 挂载的节拍 id(骨架中的 b1…)。 */
235
+ beatId: string;
236
+ /** 景别:远景/全景/中景/近景/特写。 */
237
+ shot: string;
238
+ /** 机位与运镜(如 低机位仰拍 + 缓慢推近)。 */
239
+ camera: string;
240
+ /** 时长(秒,1-12)。 */
241
+ duration: number;
242
+ /** 画面内容:角色动作 + 表情 + 服装/标志物。 */
243
+ visual: string;
244
+ /** 台词/旁白(无则空字符串)。 */
245
+ line: string;
246
+ /** 音效(无则空字符串)。 */
247
+ sound: string;
248
+ /** 光效(如 雨夜顶光 + 手机屏幕冷光)。 */
249
+ light: string;
250
+ /** 承接上一镜头结尾状态(位置/动作/情绪/服装)。 */
251
+ prevState: string;
252
+ /** 本镜头结束状态。 */
253
+ nextState: string;
254
+ }
255
+ /** 分镜·导演级:单章分镜表。 */
256
+ export interface StoryboardTable {
257
+ chapterNo: number;
258
+ shots: StoryboardShot[];
259
+ /** 生成时注入的场景卡名称(前端标注消费关系)。 */
260
+ usedScenes?: string[];
261
+ }
262
+ /** POST /storyboard/table 请求:骨架 → 分镜表。 */
263
+ export interface StoryboardTableRequest {
264
+ chapterNo: number;
265
+ /** 编剧级骨架(前端已生成/编辑后的版本)。 */
266
+ skeleton: StoryboardSkeleton;
267
+ /** 漫剧方案基底风格 id(style-library);提供时按风格措辞画面描述。 */
268
+ styleId?: string;
269
+ /** 可选滤镜风格 id(stackable)。 */
270
+ filterId?: string;
271
+ }
272
+ /** POST /storyboard/table 响应。 */
273
+ export interface StoryboardTableResponse {
274
+ table: StoryboardTable;
275
+ }
276
+ /** 分镜·提示词级:一个镜头的即梦视频提示词。 */
277
+ export interface StoryboardPrompt {
278
+ /** 对应镜头 id(s1…)。 */
279
+ shotId: string;
280
+ /** 即梦/视频模型可粘贴的中文提示词(画面+运镜+光效+风格词块)。 */
281
+ text: string;
282
+ }
283
+ /** 分镜持久化:单章的分镜产出(骨架 + 分镜表 + 视频提示词,可分别存在)。 */
284
+ export interface ChapterStoryboard {
285
+ chapterNo: number;
286
+ skeleton?: StoryboardSkeleton;
287
+ table?: StoryboardTable;
288
+ prompts?: StoryboardPrompt[];
289
+ updatedAt: string;
290
+ }
291
+ /** POST /storyboard/prompts 请求:分镜表 → 视频提示词。 */
292
+ export interface StoryboardPromptsRequest {
293
+ chapterNo: number;
294
+ /** 分镜表(前端已生成的镜头列表)。 */
295
+ table: StoryboardTable;
296
+ /** 基底风格 id。 */
297
+ styleId?: string;
298
+ /** 可选滤镜风格 id。 */
299
+ filterId?: string;
300
+ }
301
+ /** POST /storyboard/prompts 响应。 */
302
+ export interface StoryboardPromptsResponse {
303
+ prompts: StoryboardPrompt[];
304
+ }
305
+ /** 漫剧方案:同一本书的多套视觉演绎(基底风格 + 可选滤镜)。 */
306
+ export interface MangaPlan {
307
+ /** 方案 id。 */
308
+ id: string;
309
+ /** 方案名(如《保质期》3D 皮克斯版)。 */
310
+ name: string;
311
+ /** 基底风格 id(style-library 中非 stackable 风格)。 */
312
+ styleId: string;
313
+ /** 可选滤镜风格 id(style-library 中 stackable 风格)。 */
314
+ filterId?: string;
315
+ /** 是否激活(分镜/角色图生成时使用)。 */
316
+ active: boolean;
317
+ createdAt: string;
318
+ updatedAt: string;
319
+ }
320
+ /** POST /manhua/plans 请求:漫剧方案管理。 */
321
+ export interface MangaPlansRequest {
322
+ op: 'create' | 'remove' | 'activate';
323
+ /** create:方案名。 */
324
+ name?: string;
325
+ /** create:基底风格 id。 */
326
+ styleId?: string;
327
+ /** create:可选滤镜风格 id。 */
328
+ filterId?: string;
329
+ /** remove/activate:方案 id。 */
330
+ id?: string;
331
+ }
332
+ /** POST /manhua/plans 响应。 */
333
+ export interface MangaPlansResponse {
334
+ plans: MangaPlan[];
335
+ }
193
336
  /** Chapter lifecycle states (the writing pipeline's state machine). */
194
337
  export type ChapterStatus = 'pending' | 'generating' | 'written' | 'reviewing' | 'approved' | 'rejected' | 'error';
195
338
  /** One chapter in the plan. */
@@ -593,6 +736,8 @@ export interface RoleRecord {
593
736
  en: string;
594
737
  };
595
738
  };
739
+ /** 生成形象锚点/精修提示词时的漫剧方案基底风格 id(= 方案 styleId;用于检测旧风格并提示重生成)。 */
740
+ promptStyleId?: string;
596
741
  /** 漫画/漫剧重要性:main=必须建卡保证一致;support=有锚点即可;extra=路人随机生成不约束。 */
597
742
  importance?: 'main' | 'support' | 'extra';
598
743
  }
@@ -633,10 +778,16 @@ export interface SceneCard {
633
778
  source?: string;
634
779
  /** 场景图集(图像锚点):全景/局部/氛围 等。 */
635
780
  gallery?: RoleImage[];
781
+ /** 生成时的漫剧方案基底风格 id(场景卡随方案风格措辞)。 */
782
+ styleId?: string;
636
783
  }
637
784
  /** POST /scenes 请求:场景库提炼 / 采纳 / 更新 / 删除 / 图集。 */
638
785
  export interface ScenesRequest {
639
786
  op: 'extract' | 'adopt' | 'update' | 'remove' | 'image' | 'removeImage';
787
+ /** op='extract' 时的漫剧基底风格 id(场景卡按方案风格措辞)。 */
788
+ styleId?: string;
789
+ /** op='extract' 时的可选滤镜风格 id。 */
790
+ filterId?: string;
640
791
  /** adopt / update 时传入的场景卡(adopt 可修改后采纳)。 */
641
792
  scene?: SceneCard;
642
793
  /** remove / image 时的场景名。 */
@@ -674,6 +825,10 @@ export interface RolesRequest {
674
825
  label?: string;
675
826
  /** op='imageGenerate' 时的漫画风格预设 id(用于统一角色图与漫画页风格)。 */
676
827
  style?: string;
828
+ /** op='visual' / op='promptKit' 时的漫剧基底风格 id(角色图按方案风格重出)。 */
829
+ styleId?: string;
830
+ /** op='visual' / op='promptKit' 时的可选滤镜风格 id。 */
831
+ filterId?: string;
677
832
  }
678
833
  /** POST /roles 响应。 */
679
834
  export interface RolesResponse {
@@ -805,6 +960,10 @@ export interface ProjectState {
805
960
  scenes?: SceneCard[];
806
961
  /** 视觉世界观规则(生图/生视频必须遵守,从道藏提炼,注入所有提示词)。 */
807
962
  visualRules?: string[];
963
+ /** 分镜工作台产出(骨架/分镜表,按章持久化,刷新/切换不丢)。 */
964
+ storyboards?: ChapterStoryboard[];
965
+ /** 漫剧方案列表(同一本书的多套视觉演绎:基底风格 + 可选滤镜)。 */
966
+ mangaPlans?: MangaPlan[];
808
967
  /** 人物志:角色当前状态聚合结果(从编年录刷新后存档,打开页面直接显示)。 */
809
968
  roleStatus?: RoleStatusCard[];
810
969
  /** 漫剧分镜结果缓存:章号 → 分镜(持久化,刷新不丢)。 */
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 风格库(内置模板):漫剧方案的视觉基底 + 可叠加滤镜。
3
+ * 字段来自通用风格模板(豆包整理),keywords 即风格前缀词块,生成时直接套用。
4
+ */
5
+ export type StyleCategory = '3d' | 'game' | '2d' | 'film' | 'craft';
6
+ export interface ArtStyle {
7
+ id: string;
8
+ /** 风格名(用户可见)。 */
9
+ name: string;
10
+ category: StyleCategory;
11
+ /** 特点一句话(卡片展示)。 */
12
+ traits: string;
13
+ /** 风格关键词/前缀(生成角色图/视频提示词时套用)。 */
14
+ keywords: string;
15
+ /** 是否可作为滤镜叠加在基底风格之上(影视实验类;缺省 false)。 */
16
+ stackable?: boolean;
17
+ /** 默认推荐排序权重(0-1,推荐池排序参考)。 */
18
+ weight?: number;
19
+ }
20
+ export declare const STYLE_CATEGORIES: ReadonlyArray<{
21
+ id: StyleCategory;
22
+ label: string;
23
+ icon: string;
24
+ desc: string;
25
+ }>;
26
+ /** 内置风格模板(18 个)。 */
27
+ export declare const STYLE_LIBRARY: ArtStyle[];
28
+ /** 按分类取风格。 */
29
+ export declare function stylesByCategory(category: StyleCategory): ArtStyle[];
30
+ /** 取单个风格(未找到返回 undefined)。 */
31
+ export declare function findStyle(id: string): ArtStyle | undefined;
32
+ /** 按基底 + 滤镜拼接风格关键词(角色图/分镜/视频提示词共用;缺省回退 3D 动漫)。 */
33
+ export declare function styleKeywords(styleId?: string, filterId?: string): string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@waterwx/dsh-novel-forge",
3
3
  "description": "AI 编译小说工作台 for the dsh web GUI: import a novel outline (docx/text), plan chapters with LLM, generate chapter by chapter (3000-4000 chars each), and save every chapter as Markdown into your chosen output folder.",
4
- "version": "1.4.1",
4
+ "version": "1.6.0",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "node": "^22.19.0 || >=24.0.0"
@@ -81,6 +81,7 @@
81
81
  "lib/**/*.d.ts",
82
82
  "lib/**/*.d.ts.map",
83
83
  "src",
84
+ "assets/styles",
84
85
  "scripts/patch-schemastery.mjs",
85
86
  "cordis.patch.yml",
86
87
  "README.md"
package/src/client/api.ts CHANGED
@@ -80,6 +80,26 @@ export class NovelApi {
80
80
  await this.streamJob(NOVEL_API.outlineReverse, {}, onFrame)
81
81
  }
82
82
 
83
+ /** 分镜·导演级:骨架 → 分镜表(镜头级)。 */
84
+ async storyboardTable(chapterNo: number, skeleton: import('../protocol.ts').StoryboardSkeleton, styleId?: string, filterId?: string): Promise<import('../protocol.ts').StoryboardTableResponse> {
85
+ return postJson<import('../protocol.ts').StoryboardTableResponse>(NOVEL_API.storyboardTable, { chapterNo, skeleton, styleId, filterId })
86
+ }
87
+
88
+ /** 漫剧方案管理:create / remove / activate。 */
89
+ async manhuaPlans(req: import('../protocol.ts').MangaPlansRequest): Promise<import('../protocol.ts').MangaPlansResponse> {
90
+ return postJson<import('../protocol.ts').MangaPlansResponse>(NOVEL_API.manhuaPlans, req)
91
+ }
92
+
93
+ /** 分镜·提示词级:分镜表 → 即梦可粘贴视频提示词。 */
94
+ async storyboardPrompts(chapterNo: number, table: import('../protocol.ts').StoryboardTable, styleId?: string, filterId?: string): Promise<import('../protocol.ts').StoryboardPromptsResponse> {
95
+ return postJson<import('../protocol.ts').StoryboardPromptsResponse>(NOVEL_API.storyboardPrompts, { chapterNo, table, styleId, filterId })
96
+ }
97
+
98
+ /** 分镜·编剧级:单章 → 剧情骨架(节拍链)。 */
99
+ async storyboardSkeleton(chapterNo: number): Promise<import('../protocol.ts').StoryboardSkeletonResponse> {
100
+ return postJson<import('../protocol.ts').StoryboardSkeletonResponse>(NOVEL_API.storyboardSkeleton, { chapterNo })
101
+ }
102
+
83
103
  /** 开书想法 → AI 大纲:生成 count 个方案(换批时传 exclude 避开已暂留方向)。 */
84
104
  async outlineSuggest(idea: string, count?: number, exclude?: string[]): Promise<import('../protocol.ts').OutlineSuggestResponse> {
85
105
  return postJson<import('../protocol.ts').OutlineSuggestResponse>(NOVEL_API.outlineSuggest, { idea, count, exclude })