@waterwx/dsh-novel-forge 2.1.2-alpha → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +278 -368
- package/lib/client.js +19568 -21381
- package/lib/index.js +5158 -3958
- package/lib/types/action-guard.d.ts +61 -0
- package/lib/types/ai-scan.d.ts +80 -12
- package/lib/types/assets.d.ts +7 -9
- package/lib/types/assistant.d.ts +25 -0
- package/lib/types/author-assets.d.ts +1 -3
- package/lib/types/bookshelf.d.ts +13 -3
- package/lib/types/client/api.d.ts +49 -29
- package/lib/types/client/chip-prefs.d.ts +36 -0
- package/lib/types/client/docx.d.ts +2 -2
- package/lib/types/client/llmLive.d.ts +12 -14
- package/lib/types/client/locales.d.ts +12 -67
- package/lib/types/client/mount.d.ts +0 -2
- package/lib/types/client/panel/AdaptModeView.d.ts +1 -1
- package/lib/types/client/panel/AiTag.d.ts +1 -0
- package/lib/types/client/panel/AssetsTab.d.ts +1 -1
- package/lib/types/client/panel/AssistantTab.d.ts +4 -1
- package/lib/types/client/panel/AuthorAssetsView.d.ts +1 -1
- package/lib/types/client/panel/AuthorHome.d.ts +12 -12
- package/lib/types/client/panel/CmdPalette.d.ts +12 -0
- package/lib/types/client/panel/CreateBookView.d.ts +1 -1
- package/lib/types/client/panel/GlobalAssetLibraryView.d.ts +1 -1
- package/lib/types/client/panel/ImportModal.d.ts +1 -1
- package/lib/types/client/panel/LiveFeedLog.d.ts +8 -0
- package/lib/types/client/panel/ModelManager.d.ts +2 -2
- package/lib/types/client/panel/NovelPanel.d.ts +7 -2
- package/lib/types/client/panel/PageHeader.d.ts +18 -0
- package/lib/types/client/panel/ProgressConsole.d.ts +1 -1
- package/lib/types/client/panel/PromptSlotsView.d.ts +11 -0
- package/lib/types/client/panel/ReaderView.d.ts +1 -1
- package/lib/types/client/panel/RunPanel.d.ts +1 -1
- package/lib/types/client/panel/SettingsView.d.ts +13 -10
- package/lib/types/client/panel/ShelfView.d.ts +11 -2
- package/lib/types/client/panel/SubPage.d.ts +27 -0
- package/lib/types/client/panel/TensionView.d.ts +18 -0
- package/lib/types/client/panel/TimelineView.d.ts +18 -0
- package/lib/types/client/panel/WorldTab.d.ts +1 -1
- package/lib/types/client/panel/helpers.d.ts +5 -3
- package/lib/types/client/panel/market-radar-state.d.ts +56 -0
- package/lib/types/client/panel/outline-markdown.d.ts +112 -0
- package/lib/types/client/panel/status-badge.d.ts +13 -0
- package/lib/types/client/panel/storage-parse.d.ts +46 -0
- package/lib/types/client/panel/toast.d.ts +2 -0
- package/lib/types/client/panel/usePersistentState.d.ts +17 -0
- package/lib/types/client/panel/views.d.ts +21 -35
- package/lib/types/client/run-status.d.ts +21 -0
- package/lib/types/client/sidebar-entry.d.ts +0 -2
- package/lib/types/digest-parse.d.ts +29 -0
- package/lib/types/docx-core.d.ts +16 -0
- package/lib/types/docx.d.ts +2 -3
- package/lib/types/engine.d.ts +122 -103
- package/lib/types/home.d.ts +11 -0
- package/lib/types/index.d.ts +21 -13
- package/lib/types/llm-live.d.ts +62 -36
- package/lib/types/llm-retry.d.ts +38 -0
- package/lib/types/market-radar-scan.d.ts +0 -1
- package/lib/types/market-radar-sources.d.ts +1 -1
- package/lib/types/migrate-output.d.ts +25 -0
- package/lib/types/model-capability.d.ts +119 -0
- package/lib/types/model-request.d.ts +36 -0
- package/lib/types/output-budget.d.ts +86 -0
- package/lib/types/plotline-align.d.ts +35 -0
- package/lib/types/prompt-slots.d.ts +57 -0
- package/lib/types/prompting.d.ts +2 -27
- package/lib/types/protocol.d.ts +479 -595
- package/lib/types/revision.d.ts +76 -0
- package/lib/types/routes.d.ts +9 -3
- package/lib/types/run-selection.d.ts +51 -0
- package/lib/types/run.d.ts +31 -0
- package/lib/types/settings-persist.d.ts +59 -0
- package/lib/types/snapshots.d.ts +46 -0
- package/lib/types/stage-contract.d.ts +58 -0
- package/lib/types/stream-fallback.d.ts +60 -0
- package/lib/types/strip-headings.d.ts +33 -0
- package/lib/types/style-fingerprint.d.ts +78 -0
- package/lib/types/tension.d.ts +53 -0
- package/lib/types/timeline.d.ts +37 -0
- package/package.json +41 -28
- package/assets/styles/arcane-thick-3d.webp +0 -0
- package/assets/styles/chinese-ink.webp +0 -0
- package/assets/styles/clay-stopmotion-3d.webp +0 -0
- package/assets/styles/dark-ghibli.webp +0 -0
- package/assets/styles/dark-gothic-3d.webp +0 -0
- package/assets/styles/film-photo.webp +0 -0
- package/assets/styles/guofeng-heavy.webp +0 -0
- package/assets/styles/guoman-2d-gufeng.webp +0 -0
- package/assets/styles/guoman-3d-tianyuan.webp +0 -0
- package/assets/styles/guoman-3d-xuanhuan.webp +0 -0
- package/assets/styles/horror-game-3d.webp +0 -0
- package/assets/styles/hyperreal-3d.webp +0 -0
- package/assets/styles/japan-cel-dark.webp +0 -0
- package/assets/styles/korean-webtoon.webp +0 -0
- package/assets/styles/low-cyberpunk-3d.webp +0 -0
- package/assets/styles/nextgen-cg.webp +0 -0
- package/assets/styles/noir-film.webp +0 -0
- package/assets/styles/openworld-survival.webp +0 -0
- package/assets/styles/paper-cut-3d.webp +0 -0
- package/assets/styles/pixar-adult-3d.webp +0 -0
- package/assets/styles/pop-marvel-2d.webp +0 -0
- package/assets/styles/sandiao-qban.webp +0 -0
- package/assets/styles/shinkai-anime.webp +0 -0
- package/assets/styles/tactical-stealth.webp +0 -0
- package/assets/styles/urban-lightreal-3d.webp +0 -0
- package/assets/styles/vaporwave-3d.webp +0 -0
- package/assets/styles/vhs90.webp +0 -0
- package/lib/types/client/panel/BookshelfBar.d.ts +0 -11
- package/lib/types/client/panel/FlowGuide.d.ts +0 -22
- package/lib/types/client/panel/MangaRoleLibrary.d.ts +0 -20
- package/lib/types/client/panel/MangaWorkspace.d.ts +0 -12
- package/lib/types/client/panel/ModelPicker.d.ts +0 -11
- package/lib/types/client/panel/ProgressHomeView.d.ts +0 -5
- package/lib/types/client/panel/PropLibrary.d.ts +0 -8
- package/lib/types/client/panel/SceneLibrary.d.ts +0 -16
- package/lib/types/client/panel/StoryboardTab.d.ts +0 -19
- package/lib/types/client/panel/StyleCard.d.ts +0 -8
- package/lib/types/client/panel/StyleGallery.d.ts +0 -1
- package/lib/types/comic-presets.d.ts +0 -12
- package/lib/types/manga-genre-rules.d.ts +0 -22
- package/lib/types/prompt-utils.d.ts +0 -35
- package/lib/types/review-policy.d.ts +0 -97
- package/lib/types/shot-language.d.ts +0 -46
- package/lib/types/src/ai-scan.d.ts +0 -36
- package/lib/types/src/assets.d.ts +0 -37
- package/lib/types/src/assistant.d.ts +0 -45
- package/lib/types/src/author-assets.d.ts +0 -25
- package/lib/types/src/bookshelf.d.ts +0 -42
- package/lib/types/src/client/api.d.ts +0 -234
- package/lib/types/src/client/docx.d.ts +0 -15
- package/lib/types/src/client/index.d.ts +0 -14
- package/lib/types/src/client/locales.d.ts +0 -212
- package/lib/types/src/client/mount.d.ts +0 -9
- package/lib/types/src/client/panel/AdaptModeView.d.ts +0 -5
- package/lib/types/src/client/panel/AssetsTab.d.ts +0 -12
- package/lib/types/src/client/panel/AssistantTab.d.ts +0 -7
- package/lib/types/src/client/panel/AuthorAssetsView.d.ts +0 -4
- package/lib/types/src/client/panel/AuthorHome.d.ts +0 -32
- package/lib/types/src/client/panel/BookshelfBar.d.ts +0 -11
- package/lib/types/src/client/panel/CreateBookView.d.ts +0 -9
- package/lib/types/src/client/panel/FlowGuide.d.ts +0 -22
- package/lib/types/src/client/panel/GlobalAssetLibraryView.d.ts +0 -4
- package/lib/types/src/client/panel/ImportModal.d.ts +0 -7
- package/lib/types/src/client/panel/MangaRoleLibrary.d.ts +0 -20
- package/lib/types/src/client/panel/MangaWorkspace.d.ts +0 -12
- package/lib/types/src/client/panel/ModelManager.d.ts +0 -14
- package/lib/types/src/client/panel/NovelPanel.d.ts +0 -13
- package/lib/types/src/client/panel/ProgressConsole.d.ts +0 -17
- package/lib/types/src/client/panel/ProgressHomeView.d.ts +0 -5
- package/lib/types/src/client/panel/PropLibrary.d.ts +0 -8
- package/lib/types/src/client/panel/ReaderView.d.ts +0 -8
- package/lib/types/src/client/panel/ReasoningSection.d.ts +0 -10
- package/lib/types/src/client/panel/RunPanel.d.ts +0 -5
- package/lib/types/src/client/panel/SceneLibrary.d.ts +0 -16
- package/lib/types/src/client/panel/SettingsView.d.ts +0 -16
- package/lib/types/src/client/panel/ShelfView.d.ts +0 -15
- package/lib/types/src/client/panel/StoryboardTab.d.ts +0 -19
- package/lib/types/src/client/panel/StyleCard.d.ts +0 -8
- package/lib/types/src/client/panel/StyleGallery.d.ts +0 -1
- package/lib/types/src/client/panel/WorldTab.d.ts +0 -10
- package/lib/types/src/client/panel/controller.d.ts +0 -19
- package/lib/types/src/client/panel/helpers.d.ts +0 -18
- package/lib/types/src/client/panel/views.d.ts +0 -77
- package/lib/types/src/client/sidebar-entry.d.ts +0 -13
- package/lib/types/src/client/text.d.ts +0 -9
- package/lib/types/src/comic-presets.d.ts +0 -12
- package/lib/types/src/docx.d.ts +0 -19
- package/lib/types/src/engine.d.ts +0 -402
- package/lib/types/src/index.d.ts +0 -79
- package/lib/types/src/manga-genre-rules.d.ts +0 -22
- package/lib/types/src/novel-context.d.ts +0 -80
- package/lib/types/src/prompt-utils.d.ts +0 -35
- package/lib/types/src/protocol.d.ts +0 -2176
- package/lib/types/src/review-policy.d.ts +0 -97
- package/lib/types/src/routes.d.ts +0 -29
- package/lib/types/src/run.d.ts +0 -32
- package/lib/types/src/shot-language.d.ts +0 -46
- package/lib/types/src/story-beat-language.d.ts +0 -35
- package/lib/types/src/style-library.d.ts +0 -33
- package/lib/types/story-beat-language.d.ts +0 -35
- package/lib/types/style-library.d.ts +0 -33
- package/src/ai-scan.ts +0 -179
- package/src/assets.ts +0 -1774
- package/src/assistant.ts +0 -915
- package/src/author-assets.ts +0 -147
- package/src/bookshelf.ts +0 -167
- package/src/client/api.ts +0 -716
- package/src/client/css-modules.d.ts +0 -8
- package/src/client/docx.ts +0 -69
- package/src/client/index.ts +0 -34
- package/src/client/llmLive.ts +0 -101
- package/src/client/locales.ts +0 -418
- package/src/client/mount.tsx +0 -97
- package/src/client/mount.tsx._new +0 -97
- package/src/client/mount.tsx._nf +0 -97
- package/src/client/mount.tsx._tmp +0 -97
- package/src/client/panel/AdaptModeView.tsx +0 -535
- package/src/client/panel/AssetsTab.tsx +0 -458
- package/src/client/panel/AssistantTab.tsx +0 -339
- package/src/client/panel/AuthorAssetsView.tsx +0 -208
- package/src/client/panel/AuthorHome.tsx +0 -234
- package/src/client/panel/BookAnalysisView.tsx +0 -60
- package/src/client/panel/BookshelfBar.tsx +0 -170
- package/src/client/panel/CreateBookView.tsx +0 -371
- package/src/client/panel/DirectorView.tsx +0 -200
- package/src/client/panel/FlowGuide.tsx +0 -84
- package/src/client/panel/GlobalAssetLibraryView.tsx +0 -172
- package/src/client/panel/IdeaInspirationView.tsx +0 -71
- package/src/client/panel/ImportModal.tsx +0 -303
- package/src/client/panel/KnowledgeBaseView.tsx +0 -73
- package/src/client/panel/LiveFeedLog.tsx +0 -76
- package/src/client/panel/MangaRoleLibrary.tsx +0 -1002
- package/src/client/panel/MangaWorkspace.tsx +0 -715
- package/src/client/panel/MarketRadarView.tsx +0 -374
- package/src/client/panel/ModelManager.tsx +0 -205
- package/src/client/panel/NovelPanel.tsx +0 -4721
- package/src/client/panel/ProgressConsole.tsx +0 -63
- package/src/client/panel/ProgressHomeView.tsx +0 -87
- package/src/client/panel/PropLibrary.tsx +0 -175
- package/src/client/panel/ReaderView.tsx +0 -306
- package/src/client/panel/ReasoningSection.tsx +0 -31
- package/src/client/panel/RunPanel.tsx +0 -204
- package/src/client/panel/SceneLibrary.tsx +0 -453
- package/src/client/panel/SettingsView.tsx +0 -289
- package/src/client/panel/ShelfView.tsx +0 -242
- package/src/client/panel/StoryboardTab.tsx +0 -472
- package/src/client/panel/StyleCard.tsx +0 -90
- package/src/client/panel/StyleGallery.tsx +0 -58
- package/src/client/panel/WorldTab.tsx +0 -202
- package/src/client/panel/controller.ts +0 -45
- package/src/client/panel/helpers.ts +0 -67
- package/src/client/panel/panel.module.css +0 -4359
- package/src/client/panel/views.tsx +0 -314
- package/src/client/sidebar-entry.ts +0 -122
- package/src/client/text.ts +0 -28
- package/src/comic-presets.ts +0 -67
- package/src/docx.ts +0 -83
- package/src/engine.ts +0 -5636
- package/src/global-assets.ts +0 -59
- package/src/index.ts +0 -346
- package/src/llm-live.ts +0 -68
- package/src/manga-genre-rules.ts +0 -87
- package/src/market-radar-scan.ts +0 -41
- package/src/market-radar-sources.ts +0 -173
- package/src/novel-context.ts +0 -287
- package/src/prompt-utils.ts +0 -73
- package/src/prompting.ts +0 -159
- package/src/protocol.ts +0 -2565
- package/src/review-policy.ts +0 -161
- package/src/routes.ts +0 -3939
- package/src/run.ts +0 -338
- package/src/shot-language.ts +0 -181
- package/src/story-beat-language.ts +0 -130
- package/src/style-library.ts +0 -84
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 大纲 / 正文的轻量 Markdown 解析(零依赖、可离线单测)。
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么不用现成的库
|
|
5
|
+
*
|
|
6
|
+
* 插件不引第三方依赖(`package.json` 只有宿主 peer),而大纲是**受控文本**:
|
|
7
|
+
* 内容由本插件自己的 prompt 产出或作者手写,不是任意的用户 markdown。
|
|
8
|
+
* 拉一个 markdown 库进来(marked / markdown-it ≈ 100KB+)只为一个只读预览,
|
|
9
|
+
* 不划算;而自己写又必须**只实现真实用到的语法**,否则就是自造半吊子。
|
|
10
|
+
*
|
|
11
|
+
* ## 实际要支持什么(由真实产物倒推,不是凭想象)
|
|
12
|
+
*
|
|
13
|
+
* 看 `H:/novels/还债疯了/_outline.md` 的真实形态:
|
|
14
|
+
* - 大量**中文序号小标题**独立成行:「一、书名与题材定位」「二、金手指与核心机制」。
|
|
15
|
+
* 旧解析器只认 `#`,这些全被塞进一个 `<p>`,整份大纲在页面上是一堵墙。
|
|
16
|
+
* - 顶格书名独占一行(《还债疯了》)后接空行。
|
|
17
|
+
* - 冒号开头的**定义式条目**:「人情债与识海:救人即触发…」。
|
|
18
|
+
* - LLM 被明确要求**不输出换行符**,所以段落内会挤很长的句子
|
|
19
|
+
* (实测最长 700+ 字),必须靠标点断句才读得下去。
|
|
20
|
+
*
|
|
21
|
+
* 加上作者手写时会用的:`- / * / 1.` 列表、`**加粗**`、`*斜体*`、`` `代码` ``、
|
|
22
|
+
* `> 引用`、`|` 表格、`---` 分隔、` ``` ` 代码块。
|
|
23
|
+
*
|
|
24
|
+
* ## 设计约束
|
|
25
|
+
*
|
|
26
|
+
* 1. **永不抛错**:任何看不懂的输入都退化为普通段落,渲染器不能因为一个畸形
|
|
27
|
+
* 字符整页白屏。
|
|
28
|
+
* 2. **纯函数、无 React**:解析结果只含数据,渲染交给调用方。这样解析规则可以
|
|
29
|
+
* 完全离线验证,不必拉起整个面板。
|
|
30
|
+
* 3. **行内标记只做切分,不生成 HTML**:返回「片段数组」(普通文本 / 加粗 /
|
|
31
|
+
* 斜体 / 行内代码),由 React 渲染成元素——绝不用 dangerouslySetInnerHTML。
|
|
32
|
+
*/
|
|
33
|
+
/** 行内片段:把一段文本按 `**粗**` / `*斜*` / `` `码` `` 切分。 */
|
|
34
|
+
export type InlineSpan = {
|
|
35
|
+
kind: 'text';
|
|
36
|
+
text: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'strong';
|
|
39
|
+
text: string;
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'em';
|
|
42
|
+
text: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'code';
|
|
45
|
+
text: string;
|
|
46
|
+
};
|
|
47
|
+
/** 块级节点类型。 */
|
|
48
|
+
export type MdBlock = {
|
|
49
|
+
type: 'heading';
|
|
50
|
+
level: 1 | 2 | 3 | 4;
|
|
51
|
+
spans: InlineSpan[];
|
|
52
|
+
id: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'para';
|
|
55
|
+
spans: InlineSpan[];
|
|
56
|
+
id: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'list';
|
|
59
|
+
ordered: boolean;
|
|
60
|
+
items: MdListItem[];
|
|
61
|
+
id: string;
|
|
62
|
+
} | {
|
|
63
|
+
type: 'quote';
|
|
64
|
+
spans: InlineSpan[];
|
|
65
|
+
id: string;
|
|
66
|
+
} | {
|
|
67
|
+
type: 'code';
|
|
68
|
+
lang: string;
|
|
69
|
+
text: string;
|
|
70
|
+
id: string;
|
|
71
|
+
} | {
|
|
72
|
+
type: 'table';
|
|
73
|
+
header: string[];
|
|
74
|
+
rows: string[][];
|
|
75
|
+
id: string;
|
|
76
|
+
} | {
|
|
77
|
+
type: 'hr';
|
|
78
|
+
id: string;
|
|
79
|
+
};
|
|
80
|
+
/** 列表项:支持一层嵌套(`- 外层` / ` - 内层`),再深就压平。 */
|
|
81
|
+
export interface MdListItem {
|
|
82
|
+
/** 主行内容(已解析行内标记)。 */
|
|
83
|
+
spans: InlineSpan[];
|
|
84
|
+
/** 嵌套子项。 */
|
|
85
|
+
children: MdListItem[];
|
|
86
|
+
}
|
|
87
|
+
/** 解析结果。 */
|
|
88
|
+
export interface MdDoc {
|
|
89
|
+
blocks: MdBlock[];
|
|
90
|
+
/** 目录项(heading level<=3)。 */
|
|
91
|
+
toc: Array<{
|
|
92
|
+
level: number;
|
|
93
|
+
text: string;
|
|
94
|
+
id: string;
|
|
95
|
+
}>;
|
|
96
|
+
}
|
|
97
|
+
/** 去掉 markdown 标记后的纯文本(用于生成目录文字与 slug)。 */
|
|
98
|
+
export declare function stripInline(text: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* 解析行内标记为片段数组。
|
|
101
|
+
*
|
|
102
|
+
* 顺序有讲究:先剥行内代码(其内容不该再被解析),再剥加粗,最后剥斜体。
|
|
103
|
+
* 未闭合的标记按普通文本处理——宁可少强调,不可渲染出残缺标签。
|
|
104
|
+
*/
|
|
105
|
+
export declare function parseInline(text: string): InlineSpan[];
|
|
106
|
+
/**
|
|
107
|
+
* 解析一段 Markdown 为块序列。
|
|
108
|
+
*
|
|
109
|
+
* @param text - 原始文本。
|
|
110
|
+
* @returns 块序列 + 目录。
|
|
111
|
+
*/
|
|
112
|
+
export declare function parseMarkdown(text: string): MdDoc;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** 徽章的语义色调——决定颜色,与具体 CSS 类名解耦。 */
|
|
2
|
+
export type StatusTone = 'pending' | 'active' | 'written' | 'done' | 'rejected' | 'error';
|
|
3
|
+
/** 色调 → CSS module 类名(两处界面共用同一份,不再各写一遍)。 */
|
|
4
|
+
export declare const BADGE_CLASS: Record<StatusTone, string>;
|
|
5
|
+
/**
|
|
6
|
+
* 取某章状态的色调。
|
|
7
|
+
*
|
|
8
|
+
* 未知状态一律按 `error` 处理:显式失败优于静默伪装成"正常/待写"。
|
|
9
|
+
* 状态集合由 protocol 定义并可能扩展,所以这里不能写死穷尽分支。
|
|
10
|
+
*/
|
|
11
|
+
export declare function statusTone(status: string): StatusTone;
|
|
12
|
+
/** 取某章状态的徽章类名。 */
|
|
13
|
+
export declare function statusBadgeClass(status: string): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* localStorage 值的解析 / 校验(纯函数,零依赖,可离线单测)。
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么单独成文件
|
|
5
|
+
*
|
|
6
|
+
* `usePersistentState.ts` 需要 React,而本插件的测试环境是 node
|
|
7
|
+
* (vitest.config.ts `environment: 'node'`,无 jsdom),import React 会直接失败。
|
|
8
|
+
* 但这个模块真正容易出错的地方**不在 hook 本身**(`useState` + `useCallback`
|
|
9
|
+
* 是标准写法),而在**校验逻辑**:一旦校验写漏,脏数据会被写进 localStorage,
|
|
10
|
+
* 之后每次启动都读到它,且没有恢复路径——作者只能手动清缓存。
|
|
11
|
+
*
|
|
12
|
+
* 所以把校验做成零依赖的纯函数,让「最容易错的部分」可以完整验证。
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* 受枚举约束的字符串。
|
|
16
|
+
*
|
|
17
|
+
* @param raw - localStorage 里的原始字符串。
|
|
18
|
+
* @param allowed - 合法值集合。
|
|
19
|
+
* @returns 合法则返回该值;否则 undefined(调用方应回落默认值)。
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseEnum<T extends string>(raw: string, allowed: readonly T[]): T | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* 受上下界约束的整数。
|
|
24
|
+
*
|
|
25
|
+
* 先 `Number.isFinite` 再四舍五入——顺序很关键:先取整的话
|
|
26
|
+
* `NaN` 会被 `Math.round` 变成 `NaN` 之外的怪值,或被 `||` 当成 0 误收。
|
|
27
|
+
*
|
|
28
|
+
* @param raw - localStorage 里的原始字符串。
|
|
29
|
+
* @param min - 下界(含)。
|
|
30
|
+
* @param max - 上界(含)。
|
|
31
|
+
* @returns 合法则返回整数;否则 undefined。
|
|
32
|
+
*/
|
|
33
|
+
export declare function parseIntInRange(raw: string, min: number, max: number): number | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* 解析一个 JSON 对象,字段逐个校验,缺失/错类型回落默认值。
|
|
36
|
+
*
|
|
37
|
+
* 用于悬浮窗位置尺寸这类**结构固定但字段可能残缺**的数据。之所以不直接
|
|
38
|
+
* `JSON.parse` 后强转(`as {x?: unknown}`),是因为那样 `NaN` / 字符串 / `null`
|
|
39
|
+
* 都会被放过去,最终变成一个 `left: NaNpx` 的悬浮窗——不报错,只是不见了。
|
|
40
|
+
*
|
|
41
|
+
* @param raw - localStorage 里的原始字符串。
|
|
42
|
+
* @param keys - 需要的字段名。
|
|
43
|
+
* @param fallback - 各字段的默认值(与 keys 一一对应)。
|
|
44
|
+
* @returns 校验通过的完整对象;解析失败返回 undefined。
|
|
45
|
+
*/
|
|
46
|
+
export declare function parseNumberRecord<K extends string>(raw: string, keys: readonly K[], fallback: Record<K, number>): Record<K, number> | undefined;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface PersistentStateOptions<T> {
|
|
2
|
+
/** localStorage 键。 */
|
|
3
|
+
key: string;
|
|
4
|
+
/** 读取时的解析与校验;返回 undefined 表示「数据不可用」,用默认值。 */
|
|
5
|
+
parse: (raw: string) => T | undefined;
|
|
6
|
+
/** 写入时的序列化。 */
|
|
7
|
+
serialize: (value: T) => string;
|
|
8
|
+
/** 读取失败 / 无数据 / 校验不过时的默认值。 */
|
|
9
|
+
fallback: T;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 一个与 localStorage 同步的 state。
|
|
13
|
+
*
|
|
14
|
+
* @returns `[当前值, 设置函数]`。设置函数会同步写回 localStorage。
|
|
15
|
+
*/
|
|
16
|
+
export declare function usePersistentState<T>(options: PersistentStateOptions<T>): [T, (next: T | ((prev: T) => T)) => void];
|
|
17
|
+
export { parseEnum, parseIntInRange } from './storage-parse.ts';
|
|
@@ -1,36 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 纯展示组件(views):所有状态与事件处理器都留在 NovelPanel,
|
|
3
|
-
* 这里只接收 props 渲染。便于单独维护与复用。
|
|
4
|
-
*/
|
|
5
1
|
import type { ReactElement } from 'react';
|
|
6
|
-
import type {
|
|
7
|
-
/**
|
|
8
|
-
export declare function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
detailTitle?: string;
|
|
18
|
-
}): ReactElement;
|
|
19
|
-
/** 待办队列行。 */
|
|
20
|
-
export declare function TodoRow(props: {
|
|
21
|
-
tone: 'danger' | 'warning' | 'info' | 'success';
|
|
22
|
-
title: string;
|
|
23
|
-
description: string;
|
|
24
|
-
actionLabel: string;
|
|
25
|
-
disabled: boolean;
|
|
26
|
-
onAction: () => void;
|
|
27
|
-
}): ReactElement;
|
|
28
|
-
/** 全书质检问题行。 */
|
|
29
|
-
export declare function AuditIssueRow(props: {
|
|
30
|
-
issue: AuditIssue;
|
|
31
|
-
disabled: boolean;
|
|
32
|
-
onFix: () => void;
|
|
33
|
-
}): ReactElement;
|
|
2
|
+
import type { Plotline, PlotlineHealthReport, PlotlinePlan, RoleRecord, RoleStatusCard } from '../../protocol.ts';
|
|
3
|
+
/** 滑轨胶囊导航(B5-5):active 高亮为滑动指示块,随选中项平移。 */
|
|
4
|
+
export declare function SlideNav<T extends string>(props: {
|
|
5
|
+
ariaLabel: string;
|
|
6
|
+
items: ReadonlyArray<{
|
|
7
|
+
id: T;
|
|
8
|
+
label: ReactElement | string;
|
|
9
|
+
}>;
|
|
10
|
+
active: T;
|
|
11
|
+
onSelect: (id: T) => void;
|
|
12
|
+
}): JSX.Element;
|
|
34
13
|
/** 剧情线卡片(列表主体)。 */
|
|
35
14
|
export declare function PlotlineCard(props: {
|
|
36
15
|
line: Plotline;
|
|
@@ -54,24 +33,31 @@ export declare function RoleCard(props: {
|
|
|
54
33
|
onEdit: () => void;
|
|
55
34
|
onRemove: () => void;
|
|
56
35
|
}): ReactElement;
|
|
57
|
-
/**
|
|
36
|
+
/** 剧情健康检查报告面板。 */
|
|
58
37
|
export declare function PlotlineHealthPanel(props: {
|
|
59
38
|
report: PlotlineHealthReport;
|
|
60
39
|
disabled: boolean;
|
|
61
40
|
onPlan: () => void;
|
|
62
41
|
onClose: () => void;
|
|
63
42
|
}): ReactElement;
|
|
64
|
-
/**
|
|
43
|
+
/** 剧情方案面板。 */
|
|
65
44
|
export declare function PlotlinePlanPanel(props: {
|
|
66
45
|
plan: PlotlinePlan;
|
|
67
46
|
disabled: boolean;
|
|
68
47
|
onAdopt: (suggestion: Plotline) => void;
|
|
69
48
|
onClose: () => void;
|
|
70
49
|
}): ReactElement;
|
|
71
|
-
/**
|
|
50
|
+
/** 建议剧情线面板。 */
|
|
72
51
|
export declare function PlotlineSuggestionPanel(props: {
|
|
73
52
|
suggestions: Plotline[];
|
|
74
53
|
disabled: boolean;
|
|
75
54
|
onAdopt: (suggestion: Plotline) => void;
|
|
76
55
|
onClose: () => void;
|
|
77
56
|
}): ReactElement;
|
|
57
|
+
/** 空状态基元:图标 + 标题 + 可选提示。compact 变体用于列表/卡片内嵌场景。 */
|
|
58
|
+
export declare function EmptyState(props: {
|
|
59
|
+
icon?: string;
|
|
60
|
+
title: string;
|
|
61
|
+
hint?: string;
|
|
62
|
+
compact?: boolean;
|
|
63
|
+
}): ReactElement;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 运行状态芯片:固定在页面顶部的「小说工坊生成状态」小徽标。
|
|
3
|
+
* 轮询 /run/status,实时显示 生成中/暂停/完成/停止/出错 + 当前章号;
|
|
4
|
+
* 点击可打开/关闭小说工坊面板。独立 DOM 注入,不触碰主面板逻辑,挂载失败静默降级。
|
|
5
|
+
* 显示偏好(关 / 仅生成中暂停时 / 总是)存在 localStorage,见 chip-prefs.ts:
|
|
6
|
+
* 书架页「设置 · 全局 → 外观与主题」里有对应下拉,选择即时生效(跨标签页也同步)。
|
|
7
|
+
*
|
|
8
|
+
* P0 重写说明(原实现的三个问题):
|
|
9
|
+
* 1. 整块背景染状态色 + 固定白字 → 浅色主题下「白字配亮底」对比度崩坏。
|
|
10
|
+
* 现在改为「玻璃底 + 主题前景色文字 + 左侧状态色点」,状态只由色点承载,
|
|
11
|
+
* 文字永远跟随主题,任何深浅色下都可读。
|
|
12
|
+
* 2. 样式写死在 JS 的 inline style 里,切主题纹丝不动。
|
|
13
|
+
* 现在改用 CSS Module class,配色走 --nf-chip-* 令牌,
|
|
14
|
+
* 由 body[data-ds-dark-theme] 跟随宿主深浅色。
|
|
15
|
+
* 3. role="button" 却没有 tabindex、没有键盘处理,键盘用户完全用不了。
|
|
16
|
+
* 现在补 tabindex + Enter/Space 激活 + aria-label/live。
|
|
17
|
+
*/
|
|
18
|
+
import type { NovelApi } from './api.ts';
|
|
19
|
+
import type { PanelController } from './panel/controller.ts';
|
|
20
|
+
/** 生成一个固定顶部的状态芯片并开始轮询。返回 dispose。 */
|
|
21
|
+
export declare function mountRunStatus(controller: PanelController, api: NovelApi): () => void;
|
|
@@ -4,8 +4,6 @@
|
|
|
4
4
|
* sibling plugin entries and self-heals via MutationObserver.
|
|
5
5
|
*/
|
|
6
6
|
import type { PanelController } from './panel/controller.ts';
|
|
7
|
-
/** Stable data attribute identifying the injected entry row. */
|
|
8
|
-
export declare const ENTRY_SELECTOR = "[data-dsh-novelforge-entry]";
|
|
9
7
|
/**
|
|
10
8
|
* Mount the sidebar entry, waiting for the shell and self-healing on
|
|
11
9
|
* re-renders.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 章节「摘要 + 事实 + 时间线」合并抽取的**解析收敛层**。
|
|
3
|
+
*
|
|
4
|
+
* ## 为什么独立成文件
|
|
5
|
+
*
|
|
6
|
+
* 合并后一次 LLM 调用要parse 三个字段,最容易出错的地方不是「怎么调模型」,
|
|
7
|
+
* 而是**「模型返回畸形 JSON 时怎么收敛」**:字段缺失、类型不对、数组里混null、
|
|
8
|
+
* runaway 长文本。任何一项坏掉都不该拖垮另外两项。
|
|
9
|
+
*
|
|
10
|
+
* 这层逻辑必须能被离线验证,而 engine.ts 依赖宿主包 `@deepseek-ai/dsh-llm`
|
|
11
|
+
* (脱离 dsh 环境直接import 失败)。所以规则层放这里,保持零依赖。
|
|
12
|
+
*/
|
|
13
|
+
/** 把 LLM 返回的原始 facts 收敛为合法事实条目(过滤过短项、截断超长项)。 */
|
|
14
|
+
export declare function parseFactLines(raw: unknown): string[];
|
|
15
|
+
/** 把 LLM 返回的原始 timeline 收敛为对象数组(剔除非对象成员)。 */
|
|
16
|
+
export declare function parseTimelineItems(raw: unknown): Record<string, unknown>[];
|
|
17
|
+
/**
|
|
18
|
+
* timeline 单项的字段映射:缺失/错类型一律回落到安全默认,绝不产出 undefined 字段。
|
|
19
|
+
*
|
|
20
|
+
* @param item - 模型给出的原始项。
|
|
21
|
+
* @param index - 该项在数组中的下标;模型没给 `order` 时用它兜底,保证章内序号连续。
|
|
22
|
+
*/
|
|
23
|
+
export declare function mapTimelineItem(item: Record<string, unknown>, index: number): {
|
|
24
|
+
time: string;
|
|
25
|
+
order: number;
|
|
26
|
+
place: string;
|
|
27
|
+
characters: string[];
|
|
28
|
+
event: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* docx 文本提取共享核心:服务端(src/docx.ts)与浏览器端(src/client/docx.ts)
|
|
3
|
+
* 共用 XML → 纯文本的解析逻辑,避免两份实现漂移。
|
|
4
|
+
* zip 解压入口因运行时不同(fflate vs fflate/browser,浏览器端必须走 browser
|
|
5
|
+
* 入口以避开 node:module 的 require 探测)留在两端各自处理。
|
|
6
|
+
*/
|
|
7
|
+
/** 解码 docx 正文实际会用到的少量 XML 实体。 */
|
|
8
|
+
export declare function decodeEntities(text: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* 从 word/document.xml 的 XML 字符串提取纯文本:每个 <w:p> 段落一行,
|
|
11
|
+
* <w:tab>/<w:br> 保留为空白符;表格与嵌套结构按文档顺序拍平
|
|
12
|
+
* (它们的段落同样是 <w:p>)。
|
|
13
|
+
* @param xml - document.xml 解码后的字符串。
|
|
14
|
+
* @returns 正文文本(空文本时抛错)。
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractDocxTextFromXml(xml: string): string;
|
package/lib/types/docx.d.ts
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* docx outline extraction: a .docx is a zip whose word/document.xml holds the
|
|
3
3
|
* body text in <w:t> runs inside <w:p> paragraphs. We unzip with fflate and
|
|
4
4
|
* walk the XML with a tiny tokenizer — no heavyweight XML/DOM dependency.
|
|
5
|
+
* XML 解析共享核心在 ./docx-core.ts(与浏览器端同源)。
|
|
5
6
|
*/
|
|
6
7
|
/**
|
|
7
|
-
* Extract plain text from a docx buffer: one line per <w:p> paragraph
|
|
8
|
-
* <w:tab>/<w:br> preserved as whitespace. Tables and nested structures are
|
|
9
|
-
* flattened in document order (their paragraphs are just <w:p> too).
|
|
8
|
+
* Extract plain text from a docx buffer: one line per <w:p> paragraph.
|
|
10
9
|
* @param buffer - the raw .docx bytes.
|
|
11
10
|
* @returns the body text.
|
|
12
11
|
*/
|