DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Reading Companion — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins
R

dsh-reading-companion

Reading Companion

DSH 本地阅读 + AI 陪读插件:导入本地 TXT、自动生成目录、按进度滚动阅读,并以「不剧透」的书友口吻陪你聊感想,把「原文摘抄—我的感想—AI 回应」写成结构化 Markdown 笔记。Local-ebook reader with a spoiler-safe AI reading companion for DeepSeek Harness (DSH).

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:xling001/dsh-reading-companion#a3be7a302a8f71baa79c34cb55d6c42b762d197e
README兼容性版本

兼容性与来源证明

Reading Companion 以 dsh-reading-companion 发布,当前版本为 2.0.4。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/25

版本

2.0.4stable
2026/9/25
最新版
2.0.4
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/25
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题

README

dsh-reading-companion

DeepSeek Harness(DSH)的本地 TXT 阅读器 + 不剧透的 AI 陪读。 导入本地 TXT、自动生成目录、按章阅读并记住进度;边读边和 AI 聊感想——而它只知道你读过的部分。选中的「原文摘抄 — 我的感想 — AI 回应」会沉淀成结构化 Markdown 笔记,连同 AI 的「背景认识」一起导出到 Obsidian 之类的笔记库。

本地 TXT → 自动目录 → 正文阅读 → 进度持久化 → 绑定会话陪读
→ 三层防剧透 → 摘抄笔记 + 自动 tag → 背景认识增量补齐 → 导出到笔记库

书架与聊天窗口:左侧会话里陪读 AI 在聊感想,右侧书架列出导入的书与阅读进度

怎么用 · 导出的笔记 · 背景认识 · 防剧透 · 安装 · 数据目录 · 开发

更新说明

v2.0.4

  • 发笔记不再空手而归:缺口超过阈值时,先自动补完开头 30 章,剩下的提示你去面板手动补。
  • 进度跟着「你正在看的那一章」:修掉"跳章后不滚动 → 缺口算错、闸门不弹、按钮变灰"这一串问题; 面板同时显示「读到第 N 章 · 记忆到第 M 章」。
  • 笔记列表改成真翻页:每页 10 条、能往回翻;每条笔记加了「回到第 N 章」。
  • 新增「人物」卡:背景认识里"只含你读到部分"的按人视图。
  • 导出改进:每本书一个文件夹;"压缩前"一代一个文件,不再出现重复的那一份。

更早的版本、每条改动的原因与实测数据都在 docs/design-v1.md 的修订块里。

缘起

本插件最初是为了更好地阅读某本小说而设计。

它是什么

它把一本书装进 DSH 的右侧栏,让「读」和「聊」在同一屏发生:左边是你的会话,右边是书。

特性你会得到什么
纯本地原书、笔记、AI 的理解都在你自己的磁盘上;没有账号、没有云、没有书源
不剧透AI 只能看到你读到的部分,三层机制保证(见 防剧透)
读长篇不心疼额度它读的是随进度增量补齐的「背景认识」,不是每章一次调用;一千多章也能一路读下去
笔记是成品摘抄 + 你的感想 + AI 回应,带章节与 tag;可分页浏览,并能一键跳回对应章节
导出是干净的笔记增量追加(不覆盖你在笔记库里的批注)、背景整份快照;文件名自带书名

怎么用

四个地方,各管一件事。

① 书架:导入、绑定、分类

把 TXT 丢进 $DSH_HOME/dsh-reading-companion/inbox/ 点「扫描导入目录」,或直接粘一个绝对路径。 每本书显示章数、体积、编码与阅读进度;点「跳过去」进正文,也可以先选个分类、绑定一个会话。

② 正文:选中一段,点「记笔记」

顶部是上一章 / 下一章 / 设置 / 笔记 / 字体(Aa)。在正文里选中一段,浮动条会自动弹出 「已选 N 字」与「记笔记」——点它会带着这段原文与该章节号进入笔记页。

正文页:选中一段后自动弹出「已选 46 字」与「记笔记」按钮

③ 笔记页:摘抄 → 感想 → AI 回应

四段式:原文摘抄(自动填)、我的感想、tag(按感想里的词确定性打分,可自己加)、 AI 回应(可选,留空就不落盘)。按钮依次是「发到会话去聊」「抓取选中文字作回应」「保存草稿」, 以及落盘用的「写入笔记」与「导出背景与全部笔记」。换笔记存放位置也在这一页。

笔记页:笔记保存位置、原文摘抄、我的感想、tag、AI 回应,以及发到会话/抓取回应/保存草稿/写入笔记/导出按钮

附:给某个情节生成一张插图(可选)

不用改插件、也不用装东西——在会话里说就行。

  • 先聊清楚,再单独发一句生图请求。 先确认它理解对了那个瞬间,再让它画。
  • 情节它本来就有。 发笔记时当前章全文已经在它的上下文里;要画更早的章,加一句定位或贴两句原文。
  • 长相它没有。 小说很少写发色、服饰、年龄。一次锁定、之后复用:写「书友设定」(persona.md) 最稳(那节按你写的原样注入,吃的不是背景那份预算);写进 background.md 的人物条目也行, 但没有章号的条目在预算不够时最先被丢。
  • 别说"你去读人物卡"。 那张卡是给你看的视图,它看不到;它的人物信息来自 background.md。 想让它抓住谁,直接点名字。

再加一句保险:"以本章原文为准,不要自己加没写过的设定"。能不能真的生图取决于你那条模型路由,插件不参与。

④ 设置(「陪读模式」页):绑定、人设、预览、记忆

右侧栏「+」里选「陪读模式」:绑定会话、写「书友设定」(你想要的口吻与关注点)、 点「查看 AI 现在能看到什么」逐字复核注入给模型的内容、看背景认识记住到第几章、 以及这本书的讨论时间线。

设置页:陪读会话绑定、书友设定、AI 视角预览、背景认识(记忆)与人物卡、讨论历史

防剧透:三层

层强度管什么
提示词守则常驻,不受任何开关影响不主动说后续、不猜、分清自己知道与不知道
路径闸(spoilerGate)硬保证参数指向本书 content.txt / source.txt / chapters.json 的调用一律拒绝,与会话归属无关
联网闸(webGate)启发式 / 可关见下

它每轮实际拿到的只有三样:本章全文、上一章结尾、那份背景认识——外加你贴过去的摘抄。 你还没读到的地方,它字面上拿不到:路径闸连"模型自己想办法去读文件"这条路都堵了(../ 之类的绕过也挡,有专测)。 想亲眼验证就点设置页的「查看 AI 现在能看到什么」。

联网闸是启发式:扫工具参数里有没有书名、人物名、"结局/剧透"这类词,能挡住无心之失, 挡不住刻意查询——这一点写在守则里,也写在 docs/design-v1.md 里,不装成"绝对防得住"。

导出的笔记长什么样

点「导出背景与全部笔记」之后,落到 <你指定的导出目录>/陪读导出_<书名>/,文件名是 <书名>-笔记.md: 一份带章节与 tag 的摘抄本,可以直接丢进 Obsidian。

导出到 Obsidian 的读书笔记:章节标题、tag、原文摘抄、我的感想、AI 回应

  • 只追加,绝不覆盖。 你在笔记库里写的批注、加的双链,重复导出一个字都不会被碰。
  • 绝不往陌生文件里写。 每个导出文件头部有一条 <!-- drc-export book=… --> 标记;目标属于别的书、 或者压根没有标记(那是你自己写的文件),一律拒绝并报错。
  • 手写的、没有 id 的笔记块不导出,并会明说几条。

背景认识(记忆)

它是陪读 AI 对这本书的理解,一份随进度只增不减的 Markdown:

## 人物关系
- 甲 → 乙:救下之后收为徒(第 3 章)
## 人物
### 甲
- `第2章` 借六岁女童之身重生,处境贫苦
- `第29章` 潭边第一次无法再掩饰心意
## 世界观 / ## 文风 / ## 前文脉络 / ## 通用概念(兜底)
  • 写入 background.md,你可以直接打开读、也可以改——AI 记错了,改一行就是纠正。
  • 面板里另有一份只读视图「人物」卡:只含你读到的部分,按主体归堆、标注最新章号。 它的判定就是分区:只有 ## 人物 一节里的主体出卡。想让某个名字进出这张列表,改 background.md 的归属即可。
  • 缺口大时不硬补:从目录跳到很靠后的一章(缺口超过 50 章)会先拦一下,让你选 「这些我都读过 / 只记最近这一段 / 先不补」——把没读到的章节写进记忆是不可逆的。 而发笔记那一路不会空手而归:它会自动把开头 30 章跑完,再告诉你去面板补剩下的。
  • 压缩是唯一会删内容的一步,所以要过四条硬校验(保名 / 保主体 / 保号 / 真的变小), 任何一条不过就整批丢弃、文件一字不动;每次压缩前还会留一代带时间戳的备份,一份不删, 导出时一代不漏地跟出去。

导出到 Obsidian 的背景认识:人物关系与人物条目,每条都带章号

想要"最完整的那一版":把历代并起来。 每一代都是完整快照(不是增量),压缩只做删除与合并, 所以越早的那一代覆盖的章更少、但每条更细——"历代 + 当前"的并集才是最详细的那份。 但压缩后的条目没有 id、没有稳定标题,章号区间也可能被改写,"哪条对应哪条"无法可靠判定, 所以插件刻意不做自动合并。推荐做法:读完之后,把陪读文件夹(或导出的那组 -背景-压缩前-<时间戳>.md)交给 AI 或别的工具合并,并且保留原文件。可以直接用这段话:

把这本书的这几份背景认识合并成一份最详细的版本。输入:background.md(最新,已压缩) 与 background.bak.*.md(历代压缩前快照,越早的通常越详细)。规则: ① 以并集为目标——任何一代里出现过的条目都要保留; ② 同一主体下按章号对齐;同一章号有多个版本时取更详细的那一条; ③ 不要发明输入里没有的内容,也不要按你的小说知识补充; ④ 两条冲突时并存并标注; ⑤ 输出到新文件,一个输入文件都不要改; ⑥ 最后列出:补回了多少条、多少条无法对应、哪些章号有冲突。

安装

[!IMPORTANT] 前置:dsh-better-sidebar ≥ 0.19.0(本仓库在 0.19.1 上验证)。 本插件自己不画侧边栏——它只是往别人提供的右侧栏里注册一个页签,那个接口(sidebarRightTabs) 由它发布。缺了它的表现很坑:右侧栏「+」里看不到「陪读模式」,而控制台没有任何报错。

另需 DSH ≥ 0.1.5-rc.2、Node ≥ 22.19。

先确认你的 profile 名

你用的面profile 名profile 目录
DSH Desktopdesktop$DSH_HOME/profiles/desktop
DSH Web(dsh web)web$DSH_HOME/profiles/web

$DSH_HOME 默认是 ~/.dsh(Windows:C:\Users\<你>\.dsh)。别把 --profile desktop 抄给用 Web 的人: 内置模板只有 acp / web / headless / sdk / sdk-minimal,desktop 是 DSH Desktop 自建的。

装(推荐让 DSH 自己装)

把下面整段复制到 DSH 对话框里发出去,它会自己找 profile、检查并补齐前置、装好、核对 manifest:

请帮我把 DSH 插件 dsh-reading-companion 装进我当前的 profile。

1. 先确定 profile 目录:我用的是 DSH Desktop,profile 名应该是 desktop;如果我的环境实际属于别的面,
   请告诉我正确的 profile 名再继续。目录 = $DSH_HOME/profiles/<profile 名>,$DSH_HOME 默认 ~/.dsh。
   确认该目录下确实有 package.json 和 cordis.yml。
2. 检查前置插件 dsh-better-sidebar(需要 >= 0.19.0)。先看 profile 的 package.json 里
   dependencies 与 dsh.profile.bundles 有没有它。没有就先装,并告诉我最终版本号:
   dsh plugin --profile <profile 名> add dsh-better-sidebar
   这一步不能跳过:本插件的界面完全依赖它发布的 sidebarRightTabs 服务,缺了它右侧栏不会出现
   「陪读模式」,而且不会报任何错。
3. 装本插件:
   dsh plugin --profile <profile 名> add "github:xling001/dsh-reading-companion"
   (这条命令会把包加进 dependencies,并在 pnpm 跑完后自动把 dsh-reading-companion 补进
     package.json 的 dsh.profile.bundles。)
4. 装完核对 profile 的 package.json 这两处:dependencies 里有 "dsh-reading-companion"、
   dsh.profile.bundles 里有 "dsh-reading-companion"。缺哪条补哪条。
   不要改动其它插件的依赖,也不要调换 bundles 里已有条目的顺序。
5. 最后告诉我需要重启 DSH Desktop,以及重启后怎么验证装好了。
或者:命令行 / 手工 / 本地开发
# 前置(没装过才需要)
dsh plugin --profile desktop add dsh-better-sidebar   # Web 换成 --profile web

# DSH Desktop / DSH Web
dsh plugin --profile desktop add "github:xling001/dsh-reading-companion"
dsh plugin --profile web     add "github:xling001/dsh-reading-companion"

dsh plugin 只做一件事:把剩余参数转发给 profile 目录里的 pnpm。所以你不用手动改 bundles ——pnpm 结束后,DSH 会把「声明了 dsh.bundle 的依赖」自动补进去。从 GitHub 装时若 pnpm 提示构建脚本 被拦下,把它打印的 key 加到 $DSH_HOME/profiles/<profile>/pnpm-workspace.yaml 的 allowBuilds 下重跑一次 (本插件没有构建步骤,正常不会遇到)。

手工等价操作:把本包加进 profile 的 dependencies("dsh-reading-companion": "file:/abs/path/…"), 并把包名加进 dsh.profile.bundles,然后在该目录跑 pnpm/npm 安装。Windows 路径注意: file: 依赖请用正斜杠。

本地开发(改完即生效)用仓库自带脚本——它只碰自己那一个键,并在 profile 的 node_modules 里建一个目录联接指向本仓库,所以不需要跑 pnpm install,也不会打扰 profile 里已有的其它插件:

node scripts/link-into-profile.mjs --profile desktop --dry-run   # 先看将要做什么
node scripts/link-into-profile.mjs --profile desktop             # 实际写入
node scripts/link-into-profile.mjs --profile desktop --unlink    # 完全回滚

⚠️ 装完必须重启 DSH Desktop

dsh.profile.bundles 只在启动时读取一次。patchReload: "live" 只覆盖 cordis.patch.yml 的改动, 覆盖不了"新增一个 bundle"。刷新页面不够,要重启应用(dsh web 同理:重启那个进程)。

验证

  1. 打开任意会话,点右侧栏的「+」;
  2. 列表里应出现「陪读模式」(一本摊开的书的图标);
  3. 点开进入书架视图。

看不到时按顺序查:前置装了没?(这一步最容易被漏)→ 重启了没?(右侧栏选择器的条目 完全由插件注册的 guide 数组构建,看不到就是客户端半边没挂上)→ 都没有看控制台报错,请开 issue。

接着导一本书、读一章、记一条笔记。最短全流程与发版前的真机回归清单在 docs/manual-testing.md。

关闭与卸载

本插件是纯加法的:不替换任何宿主自带的行,也不接管既有服务。

  • 临时关闭:把 dsh-reading-companion 从 profile 的 dsh.profile.bundles 里删掉,改完重启。
  • 彻底卸载:dsh plugin --profile desktop remove dsh-reading-companion(Web 换成 --profile web), 或用 node scripts/link-into-profile.mjs --unlink。
  • 数据不会被卸载删除:书库与笔记都在独立目录里,删插件不删书。

数据目录

人可读的东西跟着会话工作区走,大文件留在插件目录。

<会话工作区>/陪读_<书名>/          # ★ 你的笔记在这里
  notes.md                          # 结构化读书笔记(只追加,永不重写)
  background.md                     # 陪读 AI 的背景认识(条目只增不减)
  persona.md                        # 你写给 AI 的「书友设定」
  background.bak.<时间戳>.md        # 每次压缩前留一代,一份不删
  README.md / .dsh-reading-companion.json   # 自动生成的说明 / 认领标记
$DSH_HOME/dsh-reading-companion/      # 默认;可用 cordis.patch.yml 的 storageDir 覆盖
  inbox/                              # 把 TXT 丢这里,点「扫描导入」
  library.json / bindings.json / drafts.json / categories.json
  books/<bookId>/
    meta.json                         # 书名/编码/字数/章节数/解析告警
    source.txt                        # 原书原始字节(只读,永不改写)—— MB 级
    content.txt                       # 解码并归一化换行后的 UTF-8 全文 —— MB 级
    chapters.json                     # 章节索引(标题 + 精确的字符/字节区间)
    discussions.jsonl                 # 讨论时间线(每行一条摘要)
    notes.md / background.md / persona.md   # ← 迁移期间的安全网副本

拿不到工作区时(还没绑定、或路径失效)退回插件目录,笔记照样写得进去,「笔记」页会把实际路径 与回落原因摊给你看,并给一个「重新检测位置」。两本书绝不会写进同一份笔记:每本书一个文件夹, 同一工作区里两本不同的书同名时后来者变成 陪读_<书名>_<bookId 前 6 位>(有专测钉住)。 迁移是复制,不是移动——老文件原样保留作安全网,你确认没问题后可以自己删。

bookId = 源文件 sha256 的前 16 位,所以同一份文件重复导入是幂等的:命中已有记录、不重复落盘、 更不会覆盖你写过的笔记。

正文字体

右上角「Aa」展开:字号(13–30px)、行距(1.2–2.6)、字体(宋体 / 黑体 / 楷体 / 等宽)。 偏好存在浏览器本地(localStorage),切章、重开面板都不变。字体栈只列系统自带字体。

三个刻意的排版选择:行宽用 em(36em,跟着字号走,所以调字号时每行字数不变)、 章节标题也用 em(写死 px 的话字号调到 20px 后标题会比正文小,层级反向)、标题后第一段保留 2em 缩进。

隐私

  • 原书 TXT、章节索引、笔记 md 全程留在本地,不上传任何服务器。
  • 只有你主动发送感想时,被裁切过的那段正文才会随对话进入模型请求——裁切范围是「前文 + 本章已读」, 不包含后续剧情。
  • 导出只写到你指定的那个目录,也只在你点了按钮之后才写;导出不会改动陪读文件夹里的任何东西。
  • ⚠️ 导入接口是一条本地文件读取面。 POST /library/import 接受一个绝对路径并把它读进书库—— 插件自己没有鉴权,这一条完全依赖宿主的渲染器令牌门。想把可导入范围收窄,在 cordis.patch.yml 里配 importRoots(非空时只接受落在这些根目录内的路径;判定走真实路径,用链接绕不过去)。

开发

没有构建步骤、没有运行时依赖。 浏览器半边是宿主模块加载器认的惰性 CJS 信封 (window.__ModuleLoader__.load({ id, factory })),唯一外部依赖是壳提供的 require('react'); 宿主半边只用 node: 内置模块。所以 lib/ 就是源码,改完重启 DSH Desktop 即生效。

npm test                                  # 跑全部测试
npm run test:no-isolation                 # 受限沙箱里(无法 spawn 子进程)用这个
node scripts/reindex-books.mjs            # 预演:让书架里已有的书吃到新切分规则
node scripts/reindex-books.mjs --apply    # 真的落盘(先把要改的文件备份到 backups/)
node scripts/clean-background-note.mjs --file <background.md 路径>   # 清理注释残留(默认预览)

切分规则的改动不会自动作用于已导入的书(导入是幂等的),所以老书要么删掉重导(丢笔记、丢进度), 要么就地重切。代码结构、测试清单、以及客户端测试替身的盲区都在 CONTRIBUTING.md。

后续计划

AI 页边批注。 给陪读 AI 一个 annotate(原文, 批注) 工具,让它也能给某段原文写批注。 一条硬要求:入库前必须校验「那段原文真的是本章子串」——否则 AI 编一段不存在的原文,批注就挂在空气上。

贡献者

贡献者负责
xling001功能设计、方案取舍、真机验证
AI(DSH 内的编码 agent)代码实现、测试、文档

本仓库的代码主要由 AI 编写。 人类作者负责提出要解决什么问题、在几个方案之间做选择、以及在真机上发现"哪里不对"。

与同类插件的区别,以及参考了哪些插件

同类里定位最接近的是 dsh-reader(用 DOM 选择器 冒充插槽,在本机 DSH 上中央列会被清空,且没有任何 AI 机制)与 dsh-novel-forge(创作工具台,本项目只读)。 本项目只往官方插槽注册,页签落在右侧栏、不接管中央列,因此与 dsh-tavern 这类插件共存无冲突。

借鉴过的(出处都在源码注释里,grep dsh- 就能找到):dsh-reader 的编码探测顺序、章节正则基线与 "inbox 扫描导入"形态,以及它几个真实故障的反面教训;dsh-novel-forge 的"把正文放进右侧栏页签"路线; dsh-better-sidebar 的页签注册接口;dsh-tavern 的路径闸做法与共存矩阵;dsh-adaptive-context 的一条踩坑形状(压缩失败不该阻塞补齐)。只做过定位对比、没有借鉴具体机制的:dsh-novel-solo、dsh-talebook-plugin。

许可

MIT