Skip to content

Releases: wbb316/dsh-novel

v0.13.0 · 开书向导 + 设定.json

Choose a tag to compare

@wbb316 wbb316 released this 30 Sep 14:52

v0.13.0

这一版是开书体验版本:把「新建小说」从一个两栏小表单,改成整页的开书向导,
并新增一个机器可读的 设定.json。

为什么值得升:开一本新书时你脑子里那些「主角是谁、这本书什么调子、打算往哪走」,
以前只能硬塞进「一句话简介」里;现在有地方填,而且填完会落成文件 ——
下次写下一章时我读得到,不至于把甜文写成厚重悬疑。


📝 开书向导(单独一页)

点「+ 新建」,不再是列表下面弹出的小框,而是整页切换成向导:

  • 五个折叠区:基本 / 主角 / 世界观 / 大纲 / 进阶,一页滚动到底
  • 任何字段都能留空 —— 先开书、再慢慢补;缺的到「角色 / 设定 / 剧情」页里继续填
  • 4 套模板:校园恋爱 / 都市异能 / 悬疑 / 空白。点一下只补空着的字段,
    绝不覆盖你已经写的(写小说的人中途改主意是常态,覆盖式模板一定会被骂)
  • 「✨ 让 AI 帮我补全」:把这张表丢进对话输入框(走的是「写下一章」同一条路),
    缺的我替你定 —— 主角补成一个有欲望也有弱点的人,世界观补三条规则一条禁忌,
    三幕各补两三句,再往剧情表里放 5~8 个情节点
  • 点「创建这本书」一次性落盘:
    设定.json + 角色.json(主角进"重要"档)+ 人物卡.txt + 世界观.txt + 大纲.txt
    • 剧情.json 的卷纲领(可选顺手建一个空的第一章)

主角那几栏(身份 / 外貌 / 想要什么 / 怕什么 / 秘密 / 说话风格)会拼进角色的 desc,
性格关键词与身份进 tags(面板里显示成小标签)—— 不动角色表的 schema,老项目也读得懂。

⚙️ 新增 设定.json(机器可读的元信息)

字段 干什么用
类型 / 基调 / 视角 「这本书是什么」——续写时的准星
每章目标字数 决定一章写多长(以前只能靠猜)
主线 / 结局 写长篇最容易迷路的两个地方
标签 / 备注 自由记;备注适合放"写作纪律"
  • 面板「设定」页里用表单改(跟向导同一套字段),想手改原文点「直接改 JSON」,
    两边切换时会互相带上当前值(不然切过去看到一片空白,你会以为改动丢了)
  • 写下一章时,novel_context 会先给一段「这本书是什么」,再给大纲 / 世界观 / 角色 / 最近章节
  • 为什么不塞进 大纲.txt:那是你随手写散文的地方。机器要读的东西放 json,两边互不打扰
  • 字段有白名单:多写的键、写错的类型,保存时会被安静地洗掉(不是报错);
    写坏了 JSON 会明确拦住并告诉你哪里不对

🕰️ 老项目不受影响(这条特意做了防呆)

设定.json 没有"老英文名"。如果把它塞进「新名 ↔ 老名」那张对照表,会让每一本新书
都被判成老格式 —— 大纲转头去读根本不存在的 outline.md。所以它是独立的固定文件名,
并且专门写了一条断言盯着这件事:有 设定.json 的书,大纲仍解析到 大纲.txt;
反过来,给你那些老项目(outline.md 那套)存一份 设定.json,也不会把格式带跑。


📦 安装 / 升级

dsh plugin --profile web add github:wbb316/dsh-novel

需要 DSH 0.2.0-rc.1 或更高。装完重启一次 —— 客户端的 bundle 是宿主启动时组合的,
只刷新浏览器看不到新面板。


🧪 测试

17 个测试文件 / 1367 项断言全绿。本次新增:

  • 开书向导的完整链路:模板只补空位、任何字段可留空、返回后再开一次草稿不残留、
    创建后逐个核对落盘的文件(设定 / 角色 desc 拼装 / 世界观禁忌 / 剧情纲领 / 第一章空稿)
  • 设定.json 的读写与洗数据(新增 test-setup.mjs):没有文件也算正常、坏 JSON 被拦住、
    白名单丢掉野键、非法字数归零、标签 trim 与拆分
  • 两条防线:「续写上下文里必须带设定」和「老项目不许被 设定.json 带偏」
  • 顺手修掉一个只有测试能抓到的 bug:向导里同一个 tick 连改两个字段时,闭包里的旧 state
    会把前一次吃掉(测试里连着设「书名 + 简介」,书名就没了;真人粘贴、连点模板同样会中招)。
    现在一律用函数式更新,并留了断言守着

v0.12.0 · 面板迁到宿主原生席位(不再依赖 dsh-better-sidebar)

Choose a tag to compare

@wbb316 wbb316 released this 30 Sep 14:30

v0.12.0

这一版是兼容性版本:把面板从第三方侧栏搬到宿主自带的席位上,并主动声明版本要求。
挑这个版本号是因为面板出现的位置变了(右侧栏 → 左侧栏),你会直接看见。


🔧 改了什么

面板搬到宿主原生席位,不再依赖 dsh-better-sidebar

  • 以前:借 dsh-better-sidebar 的 registerTab() 往右侧栏塞一个页签。
    代价是那个插件一卸面板就没了;它的版本范围一变,连宿主升级都会被它拦住。
  • 现在:用宿主自带的席位系统 —— 左侧栏一行(sidebar.panellist)+ 主区页面(main)。
    面板的入口从右侧栏挪到了左侧栏(那一列图标里的书本图标),点开在主区里用。
  • 老宿主照样能用:没有 ctx.slots 的版本会自动退回原来的右侧栏页签。
    这个回退是"机会主义"的(dsh-better-sidebar 装不装都不影响本插件加载)。

声明版本要求:让宿主替你拦住不兼容

package.json 现在声明了 5 条 @deepseek-ai/dsh-* 的 peerDependencies 和 dsh.engines.dsh。
dsh 0.2.0 起,宿主启动时会检查每个插件的这些范围:不满足就直接拒绝加载并说明原因,
而不是像以前那样"跑起来看着没事、某天突然坏掉"。


📦 安装 / 升级

dsh plugin --profile web add github:wbb316/dsh-novel

需要 DSH 0.2.0-rc.1 或更高。装完重启一次 dsh web(宿主要重新组合插件树);
以后只改客户端半的话刷新浏览器即可。


🧪 测试

16 个测试文件 / 1281 项断言全绿。本次新增两类断言:

  • 8 条盯原生席位注册:席位没被声明之前不许注册、左侧栏条目的 id 与主区页面的 key
    必须对齐、图标必须带 data-dsh-panel-entry 锚点、有原生席位时不许再重复挂旧页签、
    主区页面要能真渲染出面板。以前只测了"回退路",等于没测主路 —— 这次补上了。
  • 18 条盯清单不变式(新增 test-manifest.mjs):dsh.client.inject 只能写有客户端半的包 id、
    客户端半的 exports.inject 只能写服务名、两组不许写混、peerDependencies 与
    dsh.engines.dsh 必须齐全。写这一版时我把两处 inject 都写成了包 id(其中
    @deepseek-ai/dsh-client-ui-slots 还是纯库,没有客户端半)——那会让宿主永远等不到这个模块,
    面板凭空消失而且控制台不报错。这个文件就是那次事故的护栏(把 bug 造回去,它会红 3 条)。

v0.11.2 · 剧情任务栏 + 角色分档 + 改名全文替换(附三个修复)

Choose a tag to compare

@wbb316 wbb316 released this 29 Sep 14:49

v0.11.2

这一版把 9 月 29 日这一天的改动一起发了:新增「📋 剧情」页和角色分档,改角色名会全文替换,
另外修了三个用起来会卡住的地方。


✨ 新功能

📋 剧情(任务栏)

把大纲拆成一条条情节点,按卷分组显示:

  • 一个情节点可以挂 0~N 章(一个剧情写好几章);一章也能挂好几个情节点
  • 点 ☐ / ☑ 手动标记写完;另外插件会按「挂的章节都有正文」算出自动已写
    (手勾优先;把正文删了,自动那勾会自己掉)
  • 每卷可以写一段纲领(这一卷这十几章往哪走)
  • 情节点里能勾「出场角色」——遇到剧情里提到、但角色表里没有的名字,就地「+ 记成路人」
  • 点「✍️ 写下一章」时,请求会自动带上还没写的情节点 + 本卷纲领

数据存在 <小说>\剧情.json,同时生成一份人可读的 剧情.txt;大纲.txt 不受影响,还是随手写散文的地方。

👥 角色分「重要 / 不重要」两档

  • 角色页顶上是两个入口:「重要的角色(N)」「不重要的角色(N)」,点哪个看哪个,
    关系也只显示跟这一档有关的
  • 剧情里出现过的每个人都该在角色表里:带名字的路人也记,放「不重要」并标明身份(比如「路人」);
    不写分档时会按身份猜(路人 / 龙套 / 群众 → 不重要)
  • 人物卡 .txt 也按两档分节(只有一档时不加小标题,输出跟以前一样)

✏️ 改角色名 = 全文替换(会动正文,所以先算再问)

  • 在名字框改了名字不会直接生效:先弹出确认,把「会改哪几个文件、各几处」列出来
  • 点确定才动,而且先把原件整份备份到 <小说>\_改名备份\<时间>\ 再替换
  • 范围:大纲 / 世界观 / 所有章节正文 / 剧情表的标题与备注
  • 人物卡.txt、剧情.txt 是生成的,不直接改(会跟着重新生成)
  • 只有一个字的名字不做全文替换(「晓」出现在「晓得」里太正常了),只改角色表并在确认框里说明
  • 刚「+ 新角色」还没保存的角色直接改就行(正文里不可能有它)

🐛 修复

  1. 只有一本小说时,书名那一行点不动 —— 小说库(改名 / 删除 / 搜索)的入口被藏起来了。
    现在永远可点。
  2. 角色少于 2 人时,关系区摆着两个只能选自己的下拉框,点了还报错。
    现在直接说明差什么("至少要有 2 个角色"),「到」里也不再列出「从」选的那个人。
  3. 情节点挂在"还没建的卷"上时会整个消失(分组只遍历了磁盘上已有的卷)。
    现在分组会把情节点里提到过的卷也算上。

🧪 测试

15 个测试文件、1255 项断言全绿(不启动 DSH、不占端口)。
哪个文件管哪块、怎么在本地跑,见 README 的
开发和自测。


📦 安装 / 升级

dsh plugin --profile web add github:wbb316/dsh-novel
dsh web

v0.11.1 · 修复:导出的 docx 在 Word 中打不开

Choose a tag to compare

@wbb316 wbb316 released this 29 Sep 04:35

v0.11.1

修复 v0.11.0 导出的 .docx 无法在 Microsoft Word 中打开的问题;
同时清理导出的电子书里残留的 markdown 记号。

如果你在用 v0.11.0:它导出的 docx 是坏的,请更新到这一版。EPUB 不受影响。


🐛 修复

1. .docx 在 Word 里打不开

现象:双击 docx,Word 提示

Word 在试图打开文件时遇到错误。

原因:<w:t> / <w:br> 被直接写在 <w:p> 下面,缺少必需的 <w:r>(run)包裹。
这是非法 OOXML —— 但文件本身是合法 ZIP、XML 也是 well-formed,
所以「解压 + XML 解析」这类检查发现不了,只有 Word 会拒绝打开。

也说明「自动测试全绿」不等于「外部工具能打开」。这一版给仓库补了对应的回归断言。

2. 电子书里残留 markdown 记号

章节和设定读的是原文,导致 Word / 阅读器里会出现 ## 一句话简介、**苏晚**;
老格式项目的章节首行是 # 第1章 xxx,因为带 # 而没被剥掉 → 标题重复两遍。

现在统一走 plainForEbook():先抹掉 markdown 记号,再去掉首行的「第N章 标题」
(电子书的标题由结构提供:卷 = 标题 1、章 = 标题 2,正文里不该再出现一次)。


✅ 验证方式

不是「看着像对」,是拿外部工具实测过的:

验什么 用什么 结果
EPUB 合规 epubcheck 5.1.0(W3C 官方) No errors or warnings detected(0 fatal / 0 error / 0 warning)
DOCX 能开 Microsoft Word(COM 自动化,隐藏窗口、只读打开) 正常打开,卷 = 标题 1、章 = 标题 2、大纲级别正确
正文干净 在 Word 里检索 没有 ##、没有 **,章标题只出现一次

测试用书:一部两章的中文小说(平铺与分卷两种结构都跑过)。


🔍 你可以自己验

# EPUB:W3C 官方的 epubcheck(需要 Java 11+,解开压缩包即可用)
java -jar epubcheck.jar "D:\dsh-novel\我的小说\我的小说.epub"
# 期望输出: No errors or warnings detected.

DOCX 最省事:双击,用 Word / WPS 打开 —— 能翻页、标题有层级、正文里没有 # **,就是对的。

README 里还有一节「🔍 怎么自己验证 EPUB / Word」,含一段隐藏窗口打开 Word 检查页数与样式的脚本。


🧪 测试

13 个测试文件、1088 项断言。本次新增:

  • test-ebook.mjs:每个 w:t / w:br 都必须包在 w:r 里(撤掉修复验证过这条断言确实会失败)
  • test-volume.mjs:plainForEbook() 的抹记号 / 去标题 / 无标题正文原样保留

📦 安装 / 升级

dsh plugin --profile web add github:wbb316/dsh-novel
dsh web

v0.11.0 · 卷/章 + 关系图自动布局 + 图片头像 + EPUB/Word 导出

Choose a tag to compare

@wbb316 wbb316 released this 28 Sep 16:10

dsh-novel v0.11.0 · 卷 / 章、关系图自动布局、图片头像、EPUB · Word

⚠️ 已知问题:这一版导出的 .docx 打不开

请使用 v0.11.1 或更高版本。

导出的 docx 在 Microsoft Word 中会提示"Word 在试图打开文件时遇到错误"
(<w:t> 缺少 <w:r> 包裹,属于非法 OOXML)。EPUB 不受影响。
详情与修复见 v0.11.1 的更新说明。

上一版「还没做」里的前四项,这一版全做完了(只剩多设备同步)。

老项目(平铺章节的小说)一个字都不用改:拿到的章节名还是原来那串,
想分卷再点「+ 新建卷」。


📚 卷 / 章

卷 = chapters\ 下的一个子目录:

chapters\第001章-开场.txt                ← 未分卷(平铺)
chapters\第一卷 恋爱练习\第002章-x.txt     ← 第一卷里的第 2 章
  • 章节号全局连续 —— 第002章 进了第一卷也还是第002章,所以挪卷、删章都不会撞名
  • 面板里章节按卷分组显示,卷标题自带 +(往这卷加章)/ 🖊(改名)/ 🗑️(删卷)
  • 把章节拖到别的卷标题上 = 挪进那一卷(松手自动重新编号)
  • 卷名排序认中文数字:第一卷 < 第二卷 < 第十卷 < 第十一卷(不会出现"第10卷排在第二卷前面")
  • 删卷 = 整卷进回收站(跟删章节一个规矩,能捞回来)
  • 导出 / 迁移 / 老格式一键转换都跟着认卷

🕸️ 关系图自动布局(力导向)

不再"摆一个圈":关系多的角色居中、关系近的挨着(Fruchterman-Reingold 简化版,纯手写零依赖)。

  • 用固定种子,同样的角色/关系每次摆出来一模一样(不会刷一次界面跳一下)
  • 收尾会按最小间距把圆点推开,名字不会叠在一起
  • 手动拖过的位置照旧优先;点「🕸 自动布局」清掉手动位置、回到自动结果

🖼️ 图片头像

  • 头像可以是 emoji / 姓氏(纯文本,永远可用),也可以上传图片
  • 图片存成文件 <小说>\头像\<角色id>.png,角色.json 里只记路径
    (角色.json 是留着给你用记事本改的,塞 base64 就毁了)
  • 关系图的圆点直接画图片头像;没有图片就自动退回 emoji
  • 只认 png / jpg / webp / gif,≤ 2MB

📕 导出 EPUB / Word

点「⬇ 导出」选格式:

格式 内容
设定集.txt 大纲 + 世界观 + 人物卡 + 章节清单(纯文本)
EPUB 能直接丢进阅读器:设定当卷首、卷 = 分组、一章一节
Word 卷 = 标题 1、章 = 标题 2、中文友好字体

EPUB/DOCX 是自己写的 ZIP 打包器(只用 Node 内置的 zlib,零依赖)。

🧪 测试

13 个测试文件、1083 项断言,全部不启动 DSH、不占端口:

测试 断言 管什么
test-api.mjs 63 假 req/res 打真路由(只读 + 400 错误路径)
test-avatar.mjs 55 新:图片头像(上传 / 出图 / 换格式 / 删除 / 坏输入 / 脏数据)
test-bom.mjs 31 BOM 守卫(复刻 dsh web 启动那一步)
test-cast.mjs 52 角色 / 关系纯函数
test-client.mjs 295 迷你 React 挂载面板,fetch 桩打到真路由
test-config.mjs 47 保存位置
test-cordis.mjs 16 真 cordis 生命周期(路由注入钩子)
test-ebook.mjs 90 新:EPUB / DOCX(自写 readZip 逐字节往返比对)
test-library.mjs 80 小说库记忆(纯逻辑)
test-save.mjs 195 写盘全链路
test-schema.mjs 1 工具 JSON Schema
test-stream.mjs 66 流式缓冲(半截 JSON 抠字符串)
test-volume.mjs 92 新:卷 / 章(含跨卷挪动、卷名排序、回收站)

EPUB 还做了独立交叉验证:用 Windows 自己的 Expand-Archive 解开,条目齐全、
mimetype 原文正确、中文不乱码、& < 转义正确 —— 不是"自己写自己验"。

📦 安装 / 升级

dsh plugin --profile web add github:wbb316/dsh-novel
dsh web

⚠️ 已知限制(v0.11.0 发布后补记)

  • 本版导出的 docx 无法在 Word 中打开 —— 见顶部告示,v0.11.1 已修复
  • EPUB 已用 epubcheck 5.1.0(W3C 官方)验证:无错误、无警告
  • 不支持 ZIP64(> 4GB 或 > 65535 个条目);EPUB 无封面图;DOCX 无页码与目录
  • 多设备同步未实现(小说库记忆保存在浏览器本地,换设备是另一套)

补充说明:发布时的验证方式是「ZIP 可解压 + XML 可解析 + 90 项自动断言全绿」,
但这类检查发现不了 OOXML 的内容模型问题 —— Word 拒绝打开就是被这种检查漏掉的。
现在 EPUB 用 epubcheck、DOCX 用 Word 实测,且把这两条都写成了回归测试。

v0.10.1 · 修 BOM(带 BOM 的 package.json 会让 dsh web 起不来)+ 章节新建/正文编辑、老格式迁移、导出设定集、角色头像

Choose a tag to compare

@wbb316 wbb316 released this 28 Sep 15:40

dsh-novel v0.10.1 · 小说创作台 🖋️

DSH 插件:管你的小说项目(大纲 / 世界观 / 角色 & 关系 / 章节)——
一半给 agent 用(5 个 novel_* 工具),一半给人用(右侧栏「小说」面板)。
点一下就让 AI 带着大纲和角色关系接着写,边写边看它流出来的字。

这是第一个 Release,所以把 0.10.0 那轮新功能和 0.10.1 的 BOM 修复一起发了。


🐛 修复:文件开头有 UTF-8 BOM,会让整个 dsh web 起不来

症状:dsh web 启动后 3080 根本没监听(浏览器就是打不开),日志里是

SyntaxError: Unexpected token '', "{"name"... is not valid JSON

根因:dsh-app-boot 在 loadProfileDirectory 里对每个 bundle 做
JSON.parse(readFileSync(pkg, "utf8")),而 JSON.parse 不认 BOM。
0.10.0 的 package.json 开头恰好带了 EF BB BF(Windows 侧工具写的:记事本
「另存为 UTF-8」、PowerShell 5.1 的 Set-Content -Encoding UTF8 / Out-File 都会加),
于是 composeProfile 阶段就抛错退出 —— 报错完全指不到「是某个插件的 package.json 有问题」,
能查很久。

⚠️ 装了 0.10.0 的,dsh web 会起不来,更新到这一版即可。

这一版两头都堵上了:

  • 清掉仓库里所有文件的 BOM(package.json / README.md / lib/index.js / 两个测试文件)
  • 新增 lib/text.js:从磁盘读进来的文本一律先去 BOM —— ~/.dsh-novel/config.json、
    角色.json、大纲 / 世界观 / 章节正文、请求体全走它
    (也就是说:你用记事本改 角色.json,也不会再把插件打瘸)
  • 新增 test-bom.mjs:仓库体检 + 照原样复刻 dsh web 启动那一步 + 走真路由读带 BOM 的用户文件
  • 新增 .editorconfig(charset = utf-8,VS Code 保存即无 BOM)
  • README 踩坑清单从 17 条加到 18 条,把这个坑写进去了

✨ 新功能(0.10.0)

能干什么
✍️ 章节自己写 「+ 新章节」建个空章节,直接在面板里写正文(Ctrl+S 保存,.txt 按纯文本存);改名 / 删除 / 按住拖动排序(松手自动重新编号)
👥 角色头像 头像 1~4 个字符(emoji 或姓氏),会画在关系图的圆点上
🕸️ 关系图 节点可以拖,位置记在本地;关系用「从谁 → 什么关系 → 到谁」
⇪ 老格式一键迁移 老项目(outline.md 那套)在设定页会提示,点一下转成新格式,原件搬进 _旧格式备份\,不删
⬇ 导出设定集 把大纲 + 世界观 + 人物卡 + 章节清单合成一个 设定集.txt 放进小说目录

早几个版本里已经有的:📚 小说库(换书 / 记住每本读到哪 / 就地改名删除,删除 = 移到回收站)、
🎬 一键续写 + 流式直播(章节正文是当工具参数流出来的,从半截 JSON 里抠 content)、
📂 保存位置可配置(目录不存在自动创建)、自动刷新档位(实时 / 普通 / 省电 / 关闭 / 自定义)。

🧪 测试

10 个测试文件、796 项断言,全绿。全部不启动 DSH、不占端口:

测试 断言 管什么
test-api.mjs 63 假 req/res 打真路由(只读 + 400 错误路径)
test-bom.mjs 31 BOM 守卫
test-cast.mjs 52 角色 / 关系纯函数、脏数据、指错人、渲染纯文本人物卡
test-client.mjs 245 迷你 React 挂载面板(含子组件),fetch 桩打到真路由
test-config.mjs 47 保存位置:自动建目录、夹取、环境变量优先、坏配置兜底
test-cordis.mjs 16 真 cordis:先给 tools、后给 webServer,验证注入钩子会自己触发
test-library.mjs 80 小说库记忆(纯逻辑):记住 / 回落 / 按库分组 / 坏数据
test-save.mjs 195 写盘全链路(新建 / 角色 / 存稿 / 改名 / 删除)
test-schema.mjs 1 工具的 JSON Schema 是否合法
test-stream.mjs 66 流式缓冲:帧折叠、半截 JSON 抠字符串、preview 降级

说明:test-save / test-api 跑在你真实的小说库里(只建 __自测* 临时作品,
跑完连挪进回收站的痕都清干净);其余跑在系统临时目录。

📦 安装 / 更新

dsh plugin --profile web add github:wbb316/dsh-novel
dsh web

前置条件

说明
DSH 0.1.5 或更高(用到了 agent/assistant-stream 流式帧)
Node >= 20
dsh-better-sidebar 侧栏面板的容器;不装的话 5 个工具照常可用,只是没有面板

⚠️ 还没做

  • 章节的多级结构(卷 / 章)—— 现在只有平铺的章节
  • 关系图的自动布局(按关系亲疏摆位,而不是圆圈)
  • 角色头像用图片(现在只能是 emoji / 字符,因为要保证项目里只有纯文本 + json)
  • 导出成 epub / docx(现在只导出 设定集.txt)
  • 多设备同步(小说库记忆存在浏览器本地,手机上打开是另一套)