Files
bilin/docs/superpowers/specs/2026-07-08-bilin-v11-writer-toolkit-design.md
T
bing 027d7c7559 docs: add v1.1 writer toolkit design spec for templates, import, and export
Capture chapter templates, txt/md/docx import, submission presets, and global inspiration capture for the daily writing workflow release.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-08 11:05:06 +08:00

16 KiB
Raw Blame History

笔临 v1.1 作家日更工具包 设计规格

版本1.0
日期2026-07-08
范围:§10 章节模板 + §11.1 书籍导入(txt/md/docx+ §20.2 投稿导出预设 + §20.6 全局灵感捕获增强
前置v1.0.0 已交付(4adafa1:P7 角色关系图谱 + P9 写作分析)
参考design/readme.md v1.1 §10 / §11.1 / §20.2 / §20.6、design/ui_pc.html #templateModal / #importModal / #exportModal / #inspirationModal

目标版本v1.1.0


1. 背景与目标

1.1 阶段定位

v1.0.0 已完成「看数据」能力(关系图谱、写作分析、POV)。design/readme.md §20.7 审查清单仍有多项 有 UI 原型、无真实实现 的作家刚需:

  • 主页「导入书籍」为 comingSoon
  • 章节模板 / 快速新建章仅有 #templateModal 静态原型
  • 导出模态「复制到剪贴板(网文投稿格式)」无后端
  • 灵感捕获 Ctrl+Shift+I 仅编辑器内可用,保存后会跳转侧栏打断心流

本阶段(v1.1.0)交付 作家日更工具包,形成「写得更快 → 发得更顺 → 灵感不漏」闭环。

1.2 已确认决策(Brainstorming 2026-07-08

维度 决策
方向 方案 B:作家日更工具包
MVP 边界 方案 A(完整四模块):模板 + txt/md/docx 导入 + 投稿预设 + 灵感增强
模板存储 GlobalSettings.chapterTemplates[];内置模板代码常量合并展示
模板解析 渲染进程 chapter-template.ts 替换变量后 chapter.create + chapter.update
docx 解析 mammothdocx → HTML,保留 bold/italic
md 解析 markedmd → HTML
导入分章 自动正则 / 双换行 / 自定义正则 三档
大文件 >20MB 导入前二次确认;进度条 IPC 事件
投稿导出 单章复制剪贴板 + 另存 .txt;内置「通用网文」预设
投稿预设存储 GlobalSettings.submissionPresets[]
灵感增强 快捷键全局可用;未开书时模态内选书;保存后仅 toast、不跳转
置顶 灵感模态最高 z-index;不新建独立 BrowserWindow

1.3 验收标准

用户能完成:

  1. 在章节列表点击「快速新建」,选择模板并输入标题,创建章节且编辑器自动填入模板正文(含变量替换)
  2. 在设置页创建/编辑/删除自定义章节模板;内置模板只读展示
  3. 主页「导入书籍」选择 .txt / .md / .docx,预览分章结果,确认后创建新书并导入全部章节
  4. 导入 >20MB 文件前看到确认提示;导入过程显示进度
  5. 编辑器内 Ctrl+Shift+E 打开导出模态,选择「通用网文」预设,复制到剪贴板 得到段首空两格 + # 第N章 标题 格式纯文本
  6. 设置页自定义投稿预设(标题格式、段首缩进、段落间距),导出时应用
  7. 在主页按 Ctrl+Shift+I 唤起灵感捕获,选择书籍后保存,仅 toast 确认、焦点不打断原界面
  8. 编辑器内灵感捕获行为与 7 一致(不再自动跳转灵感面板)

1.4 本规格不实现(明确排除)

归属
.novel / .novel-all 项目包导入导出 v1.2+
PDF / Word 全书导出、分卷批量投稿复制 v1.2+
§11.2 完整导出矩阵(docx 目录、PDF 排版) v1.2+
§20.5 敏感词合规、预设内敏感词替换规则 v1.2+
§20.3 角色弧线简报 v1.2+(图谱深化线)
§5.7 故事时间线、§5.8 连续阅读模式 v1.2+
导入 .novel v1.2+
平台 API 直连投稿 永久 YAGNI
模板变量 {outlineItem} 自动关联当前章大纲 v1.1 留空字符串(无关联时);手动关联后续

2. 架构

2.1 进程模型

┌─────────────────────────────────────────────────────────────────────┐
│ 渲染进程                                                             │
│  · TemplateQuickCreateModal / TemplateSettingsTab                   │
│  · ImportBookModal                                                   │
│  · ExportModal + SubmissionPresetSettingsTab                         │
│  · InspirationModal(增强:全局唤起、选书、无跳转)                     │
│  · chapter-template.ts / submission-formatter.ts(纯函数)           │
└──────────────────────────────┬──────────────────────────────────────┘
                             │ IPC
┌────────────────────────────▼────────────────────────────────────────┐
│ 主进程                                                               │
│  · ImportService(读文件、分章、创建书+卷+章批量写入)                  │
│  · ExportService(HTML→纯文本、应用投稿预设、写剪贴板/文件)            │
│  · BookRegistryService(已有 create/open                           │
│  · GlobalSettingsService(扩展 chapterTemplates / submissionPresets)│
│  · dialog.showOpenDialog / clipboard                                 │
└─────────────────────────────────────────────────────────────────────┘

2.2 模块边界

模块 职责 依赖
chapter-template.ts 变量替换、章节号计算 GlobalSettings, 书籍 volumes/chapters/settings
ImportService 解析文件、分章、创建书 BookRegistry, ChapterRepository, mammoth, marked
ExportService 单章格式化、剪贴板、存盘 ChapterRepository, GlobalSettings
SubmissionFormatter HTML 剥离、段首缩进、标题行 纯函数,主/渲染均可调用
TemplateQuickCreateModal 选模板 → IPC 创建章 chapter.create/update
ImportBookModal 选文件 → preview → execute import.*
ExportModal 选预设 → 复制/存盘 export.*

原则

  • 导入/导出重 IO 与解析放主进程;模板变量替换可在渲染进程(减少 IPC 往返)
  • 导入失败整事务回滚:书未创建或创建后写章失败则 registry.delete(bookId)
  • 剪贴板写入仅主进程(Electron clipboard API

3. 数据模型

3.1 GlobalSettings 扩展

export interface ChapterTemplate {
  id: string
  name: string
  body: string
  defaultStatus?: ChapterStatus
  builtin?: boolean
}

export interface SubmissionPreset {
  id: string
  name: string
  titleFormat: string       // 默认 "# 第{chapterNumber}章 {chapterTitle}"
  indentParagraphs: boolean   // 段首两全角空格
  includeAuthorsNote: boolean // 保留「作者的话」段(检测 —— 分隔)
  paragraphGap: 'single' | 'double'
}

// GlobalSettings 追加:
chapterTemplates?: ChapterTemplate[]
submissionPresets?: SubmissionPreset[]
defaultSubmissionPresetId?: string

内置模板src/shared/builtin-templates.ts,不写入 JSON):

id name body 摘要
builtin-generic 通用模板 ## 第{chapterNumber}章 {chapterTitle}\n\n
builtin-webnovel 网文常用 正文 + \n\n——\n作者的话:\n

内置投稿预设

id name 规则
builtin-webnovel 通用网文 titleFormat: "# 第{chapterNumber}章 {chapterTitle}", indentParagraphs: true, paragraphGap: 'double'

GlobalSettingsService 读取时合并内置项;用户不可删除内置项。

3.2 模板变量

变量 来源
{chapterNumber} 目标卷 chapters.length + 1
{chapterTitle} 用户输入
{penName} settings.penName
{date} localDateString()
{volumeName} 当前卷 name
{previousChapterTitle} 同卷上一章 title,首章 ""
{outlineItem} v1.1 固定 ""(章节创建时无 outline 关联)
{characterList} 当前卷内 settings.type=characterchapterIds 与卷内任一章有交集的 name,逗号连接

3.3 导入分章

export type ImportSplitMode = 'auto' | 'paragraph' | 'regex'

export interface ImportChapterPreview {
  title: string
  contentHtml: string
  wordCount: number
}

export interface ImportPreviewResult {
  fileName: string
  fileSizeBytes: number
  chapters: ImportChapterPreview[]
  warnings: string[]
}

export interface ImportExecuteParams {
  filePath: string
  bookName: string
  category: string
  splitMode: ImportSplitMode
  customRegex?: string
}

自动分章正则(依次尝试,命中即用):

  1. /^#\s*第.+章[^\n]*/gmMarkdown 标题)
  2. /^第[一二三四五六七八九十百千零〇\d]+章[^\n]*/gm(纯文本章标题行)

paragraph 模式:按 \n\s*\n 分段;标题取段首非空行,截断 50 字。

首章前导内容:合并入第一章 warnings 提示,不丢弃。


4. IPC

4.1 通道

IMPORT_PICK_FILE: 'import:pickFile'
IMPORT_PREVIEW: 'import:preview'
IMPORT_EXECUTE: 'import:execute'
IMPORT_PROGRESS: 'import:progress'   // main → renderer event

EXPORT_FORMAT_CHAPTER: 'export:formatChapter'
EXPORT_COPY_CLIPBOARD: 'export:copyClipboard'
EXPORT_SAVE_TXT: 'export:saveTxt'

4.2 载荷

// import:pickFile → { canceled, filePath? }
// import:preview → { filePath, splitMode, customRegex? } → ImportPreviewResult
// import:execute → ImportExecuteParams → { bookId }
// import:progress → { phase: 'parsing'|'writing', current, total }

// export:formatChapter → { bookId, chapterId, presetId } → { text }
// export:copyClipboard → { text } → void
// export:saveTxt → { text, defaultName } → { savedPath? }

5. UI 规格

5.1 TemplateQuickCreateModal

  • 入口:章节列表底部 data-testid="chapter-quick-new"
  • 布局:参考 #templateModal 卡片网格 + 标题输入
  • 流程:选模板 → 输入标题 → 创建 → switchTarget 到新章

5.2 设置页 — 章节模板 Tab

  • data-testid="settings-chapter-templates"
  • 列表:内置 + 自定义;自定义可编辑 body(textarea)、删除
  • 新建:setting-template-add

5.3 ImportBookModal

  • 入口:主页 home.importBook(替换 comingSoon
  • data-testid="import-book-modal"
  • 字段:文件路径(浏览)、书名、分类、分章规则下拉、自定义正则输入(regex 模式显示)
  • 预览区:章数 + 前 5 章标题列表
  • 20MBimport-large-file-confirm 对话框

  • 进度:import-progress-bar

5.4 ExportModal

  • 入口:编辑器工具栏 data-testid="export-chapter" + 快捷键 exportBook
  • data-testid="export-modal"
  • 折叠区「投稿预设」:export-preset-select
  • 操作:export-copy-clipboard / export-save-txt
  • 预览:格式化后前 500 字纯文本

5.5 设置页 — 投稿预设 Tab

  • data-testid="settings-submission-presets"
  • 字段:名称、标题格式、段首缩进 checkbox、段落间距 select

5.6 InspirationModal 增强

  • App.tsxcaptureInspiration 移除 view !== 'editor' 限制
  • 未开书:显示 inspiration-book-select(书籍列表下拉,默认 lastOpenedAt 最新)
  • 保存后:删除 switchTarget + setSidebarPanel('inspiration');仅 showToast + setOpen(false)
  • 样式:inspiration-modal--capture 提升 z-index(高于 TopBar

6. 依赖

用途
mammoth docx → HTML
marked md → HTML

均在主进程 ImportService 使用;electron-vite 打包时 external 或 bundle 按现有惯例。


7. 测试

用例 ID 层级 场景 预期
UT-TEMPL-01 单元 解析含 {chapterNumber} {chapterTitle} 正确替换
UT-TEMPL-02 单元 {volumeName} 替换 卷名正确
UT-TEMPL-03 单元 {characterList} 卷内角色 逗号列表
IT-TEMPL-01 集成 模板快速新建写入 DB content 含替换后正文
UT-IMPORT-01 单元 txt 自动分章 3 章 chapters.length === 3
UT-IMPORT-02 单元 md 转 HTML <p>
UT-IMPORT-03 单元 docx mammoth 非空 HTML
IT-IMPORT-01 集成 execute 创建书+章 registry.open 章数匹配
UT-EXPORT-01 单元 段首空两格 每段    前缀
UT-EXPORT-02 单元 标题格式 # 第1章 标题
IT-EXPORT-01 集成 copyClipboard 剪贴板非空
E2E-TEMPL-01 E2E 快速新建章 编辑器有模板内容
E2E-IMPORT-01 E2E 导入 txt 新书可见多章
E2E-EXPORT-01 E2E 复制投稿格式 剪贴板含章标题
E2E-INSP-01 E2E 主页 Ctrl+Shift+I 保存 toast,不跳编辑器

8. i18n 键(节选)

"template.title": "章节模板",
"template.quickNew": "模板新建章",
"template.builtin": "内置",
"template.custom": "自定义",
"import.title": "导入书籍",
"import.pickFile": "浏览文件",
"import.splitAuto": "自动识别章节",
"import.splitParagraph": "双换行分段",
"import.splitRegex": "自定义正则",
"import.largeFileConfirm": "文件较大({{size}}),导入可能需要 30 秒至 2 分钟,是否继续?",
"import.progress": "正在导入 {{current}}/{{total}}",
"export.title": "导出章节",
"export.submissionPresets": "投稿预设",
"export.copyClipboard": "复制到剪贴板",
"export.saveTxt": "另存为文本",
"export.copied": "已复制到剪贴板",
"submission.title": "投稿预设",
"submission.titleFormat": "标题格式",
"submission.indent": "段首空两格",
"inspiration.selectBook": "关联书籍",
"inspiration.saved": "灵感已保存"

9. 文件清单

文件 职责
src/shared/types.ts ChapterTemplate, SubmissionPreset, Import/Export DTO
src/shared/builtin-templates.ts 内置模板与投稿预设
src/shared/ipc-channels.ts import.* / export.*
src/main/services/import.service.ts 解析 + 分章 + 创建书
src/main/services/export.service.ts 格式化 + 剪贴板/存盘
src/main/lib/submission-formatter.ts HTML → 投稿纯文本
src/main/lib/chapter-splitter.ts 分章逻辑
src/main/ipc/handlers/import.handler.ts 导入 IPC
src/main/ipc/handlers/export.handler.ts 导出 IPC
src/renderer/lib/chapter-template.ts 模板变量替换
src/renderer/components/chapter/TemplateQuickCreateModal.tsx 快速新建
src/renderer/components/import/ImportBookModal.tsx 导入 UI
src/renderer/components/export/ExportModal.tsx 导出 UI
src/renderer/components/settings/TemplateSettingsTab.tsx 模板管理
src/renderer/components/settings/SubmissionPresetTab.tsx 投稿预设管理
src/renderer/components/inspiration/InspirationModal.tsx 增强
src/renderer/components/home/HomePage.tsx 接入导入
src/renderer/components/layout/EditorLayout.tsx 导出入口
tests/main/chapter-template.test.ts UT-TEMPL-*
tests/main/chapter-splitter.test.ts UT-IMPORT-01
tests/main/submission-formatter.test.ts UT-EXPORT-*
tests/main/import.service.test.ts IT-IMPORT-01
e2e/chapter-template.spec.ts E2E-TEMPL-01
e2e/import-book.spec.ts E2E-IMPORT-01
e2e/export-submission.spec.ts E2E-EXPORT-01
e2e/inspiration-capture.spec.ts E2E-INSP-01

10. 实现顺序建议

  1. 类型 + 内置常量 + chapter-template.ts + 快速新建 UI
  2. SubmissionFormatter + ExportService + ExportModal + 设置 Tab
  3. InspirationModal 增强(独立、改动小)
  4. ImportService + ImportBookModal(依赖 mammoth/marked,放最后)

目标版本号:实现完成后 package.json / README / 关于页 → v1.1.0


11. Spec 自检

检查项 状态
无 TBD/TODO 占位
与方案 A 四模块一致
.novel 明确排除
单章投稿导出范围明确
IPC/数据模型无矛盾
测试用例覆盖四模块