🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

侧栏小说书架 good-saltfish/dsh-novel-shelf

DeepSeek Harness
good-saltfish12 天前有提交已提供中文文档扫描:含敏感能力

在右侧栏读本地 txt 小说,与项目界面并存不切换

30.7/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add good-saltfish/dsh-novel-shelf
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · ui
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 12 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 6 处,展示前 6 条)
  • 读取本地文件
    lib/host.js:598
    const raw = readFileSync(settingsFile(), 'utf8');
  • 读取本地文件
    lib/host.js:626
    const raw = readFileSync(settingsFile(), 'utf8');
  • 发起网络请求
    lib/host.js:784
    response = await fetch(url, {
  • 发起网络请求
    lib/host.js:1085
    const res = await fetch(url, { signal: controller.signal });
  • 发起网络请求
    lib/client.js:291
    fetch(routeUrl(`${API_PREFIX}/client.log`), {
  • 发起网络请求
    lib/client.js:301
    const res = await fetch(routeUrl(`${API_PREFIX}/${method}`), {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

在 DSH(DeepSeek Harness)右侧栏里读本地 txt 小说,与 novel-reader 共用书架、批注与阅读进度。

README

由 DeepSeek 最新模型翻译生成
dsh-novel-shelf 办公摸鱼专用:在 DSH(DeepSeek Harness)右侧栏里看本地 txt 小说,边看小说边做项目。英文版:README.en.md DSH 右侧栏中的「小说书架」面板 DSH 整体界面,右侧栏打开「小说书架」 功能 / Features - 右侧栏阅读:作为 DSH 原生右栏标签打开,不开新窗口、不切应用,主界面继续留着你的项目,小说和干活同时进行。 - 本地 txt 书架:按绝对路径加入书架,插件只读取文件,不上传、不外发。 - 自带三本书:装上就有《十日终焉》《我在精神病院学斩神》《我不是戏神》三本,首次打开右栏时自动装进书架,不用自己找文件、不用配置路径。想删就删,删了不会再回来。 - 章节切分:识别「第 N 章 / 节 / 回 / 卷 / 篇」标题;识别不到时按长度分段兜底。 - 编码探测:UTF-8 / UTF-8 BOM / UTF-16LE / UTF-16BE / GB18030 自动判定。 - 全书搜索:章节内全文匹配,命中给出章节名与上下文片段。 - 阅读进度:章节号与滚动比例自动回写,重开自动回到原处。 - 五套配色:白 / 护眼绿 / 米黄 / 深灰 / 纯黑,与 novel-reader 的 body[data-theme] 同名同色。
展开完整文档(README 剩余 1 节)
dsh-novel-shelf

办公摸鱼专用:在 DSH(DeepSeek Harness)右侧栏里看本地 txt 小说,边看小说边做项目。英文版:README.en.md

DSH 右侧栏中的「小说书架」面板

DSH 整体界面,右侧栏打开「小说书架」

功能 / Features

- 右侧栏阅读:作为 DSH 原生右栏标签打开,不开新窗口、不切应用,主界面继续留着你的项目,小说和干活同时进行。
- 本地 txt 书架:按绝对路径加入书架,插件只读取文件,不上传、不外发。
- 自带三本书:装上就有《十日终焉》《我在精神病院学斩神》《我不是戏神》三本,首次打开右栏时自动装进书架,不用自己找文件、不用配置路径。想删就删,删了不会再回来。
- 章节切分:识别「第 N 章 / 节 / 回 / 卷 / 篇」标题;识别不到时按长度分段兜底。
- 编码探测:UTF-8 / UTF-8 BOM / UTF-16LE / UTF-16BE / GB18030 自动判定。
- 全书搜索:章节内全文匹配,命中给出章节名与上下文片段。
- 阅读进度:章节号与滚动比例自动回写,重开自动回到原处。
- 五套配色:白 / 护眼绿 / 米黄 / 深灰 / 纯黑,与 novel-reader 的 body[data-theme] 同名同色。
- 与 novel-reader 共用数据:读写 %APPDATA%/novel-reader 下的 books.json、settings.json、annotations/.json,两边切换主题/进度即时同步。
- 零依赖:只用 Node 内置模块与 DSH 宿主自带的服务,不引入第三方运行时依赖,不做网络请求。

内置书目是怎么装上的 / How the bundled books work

插件 bundle 里带一个 books/ 目录(约 7.3 MB,三本 txt),随安装包一起分发。绝不把本机的 D:\... 绝对路径写进书架——换台机器路径不存在,书架会直接坏掉。所以流程是:

1. 首次读取书架(library.get)时,host 半边检查 books.json 里缺哪本内置书;
2. 缺的那几本从 bundle 的 books/ 复制到 %APPDATA%/novel-reader/books/<书名>.txt;
3. 再把这份数据目录内的副本路径写进 books.json,书架里就出现了。

三条硬约束:幂等(按书名判重,不会重复加)、失败不影响书架(某本复制失败只 console.warn 后继续)、用户删过的不会再回来(删一本就把书名记进 removed-bundled.json)。测试用环境变量 NOVEL_SHELF_BOOKS_DIR 把 bundle 目录指到沙箱,所以单测不依赖真实仓库里的小说。

安装 / Install

方式一:插件市场(推荐)

在 DSH 的插件市场里搜索 dsh-novel-shelf,点安装。

方式二:命令行

dsh plugin --profile desktop add good-saltfish/dsh-novel-shelf

方式三:从源码安装

git clone https://github.com/good-saltfish/dsh-novel-shelf
dsh plugin --profile desktop add link:<仓库路径>

方式四:手动装 tarball

从 Releases 下载 dsh-novel-shelf-<版本>.tgz,然后:

dsh plugin --profile desktop add file:<tgz 路径>

装完必须刷新 DSH 页面。插件的 client 半边是随页面加载的,安装或升级都不会热替换已加载的模块。刷新后右栏会出现「小说书架」标签。

使用步骤 / Usage steps

1. 打开右栏:点 DSH 界面右上角的右栏按钮,展开右侧列。
2. 切到「小说书架」标签:右栏顶部标签栏里选「小说书架」,进入书架页。
3. 三本内置书已经在架:第一次打开时,插件自带的《十日终焉》《我在精神病院学斩神》《我不是戏神》会自动复制到本机数据目录并加进书架,点开就能读。
4. 继续加书:在输入框里填本地 txt 的绝对路径(例如 D:\books\foo.txt),按回车。书名会出现在列表里。
5. 开始读:点书名进入阅读页,当前章节正文直接显示在右栏里。
6. 翻章与导航:顶部「上一章 / 下一章」翻章,标题栏右侧的目录按钮展开章节列表,搜索框做全书全文检索(回车搜索,命中会给出章节名与上下文片段)。
7. 调阅读体验:底部滑块调字号,底部五个色板切换背景(白 / 护眼 / 米黄 / 深灰 / 纯黑)。
8. 进度自动保存:章节号与滚动比例写回 %APPDATA%/novel-reader/annotations/<id>.json,关掉再开自动回到原处。

右侧栏宽度有限,直接把窗口拉宽或切到更宽的布局阅读更舒服。

它是怎么工作的 / How it works

理解这几步有助于自己改这个插件:

1. Host 半边(lib/host.js) 在 ctx.effect() 里用 ctx.webServer.register({kind:'prefix', path:'/novel-shelf/api'}) 挂一条前缀路由,对外提供 8 个方法:library.get / library.add / library.remove / book.open / book.chapter / book.save / settings.save / book.search。
2. 每条请求先过信任栅栏:ctx.connection.requestRejection(req) 判定是否来自可信的浏览器会话(命令行直连一律 403),再叠加 Sec-Fetch-Site 跨站拒绝;方法名用 Object.hasOwn(api, method) 做白名单,Object.hasOwn 防的是 POST /novel-shelf/api/constructor 这类原型成员命中;请求体上限 1 MiB。
3. Host 半边做真正的 IO:读盘、编码探测、章节切分、全文检索、JSON 落盘(写临时文件再 rename;读到损坏 JSON 先备份成 .corrupt-<时间戳> 再回退,不静默覆盖)。路径一律 path.resolve 归一。
4. Client 半边(lib/client.js) 通过 window.__ModuleLoader__.load({id:'dsh-novel-shelf', factory}) 挂载。它先 ctx.inject(['sidebarRight','sidebarRightTabs'], ...) 拿到右栏标签注册表,注册一个 tab 类型(id = dsh-novel-shelf/reader,kind = dsh-novel-shelf:reader),再通过 ctx.slots.inject('sidebar.right.pane.tab', ...) 占用两个 keyed 座位(正文与标题)。
5. 座位注入回调必须返回清理函数,否则宿主不会真正占位,面板会退化成宿主占位文案「这类内容还没有可用的查看方式」。这是 DSH 右栏插件最容易踩的坑。
6. 面板调 API:client 侧把路径拼成 novel-shelf/api/<method>(去掉前导斜杠,挂在 document.baseURI 下),POST JSON,收到 {ok:true,value} 或 {ok:false,error}。
7. 主题与设置共享:主题、字号、行距都写进 %APPDATA%/novel-reader/settings.json,桌面版 novel-reader 读同一份文件,所以两边即时同步。

数据位置 / Data layout

| 文件 | 内容 |
| %APPDATA%/novel-reader/books.json | 书架(路径、名称、大小、加入时间) |
| %APPDATA%/novel-reader/books/ | 内置三本书的本机副本(首次打开书架时从 bundle 复制过来) |
| %APPDATA%/novel-reader/removed-bundled.json | 你主动删掉的内置书名,删过就不会再自动装回来 |
| %APPDATA%/novel-reader/settings.json | 主题、字号、行距、最后阅读的书 |
| %APPDATA%/novel-reader/annotations/<id>.json | 每本书的批注与阅读进度 |
| %APPDATA%/novel-reader/plugin-client.log | 插件 client 半边的运行诊断日志(只含标签与计数,不含正文) |

Windows 用 %APPDATA%,macOS 用 ~/Library/Application Support/novel-reader,Linux 用 ~/.config/novel-reader。

JSON 文件损坏时插件会先备份为 .corrupt-<时间戳> 再回退到空值,不会静默覆盖原数据。

隐私 / Privacy

- 全部数据留在本机插件数据目录,插件不做任何网络请求。
- 宿主路由带官方信任栅栏(ctx.connection.requestRejection)与跨站请求拒绝,命令行直连会被拒。
- 只接受 .txt;请求体上限 1 MiB;API 方法白名单用 Object.hasOwn 防原型成员。

开发 / Development

目录结构

lib/host.js 宿主半边:文件 IO、编码探测、章节切分、全文检索、JSON 落盘、HTTP 路由 lib/client.js 客户端半边:右栏标签注册、书架/阅读页组件、五套主题样式 books/ 内置的三本 txt(约 7.3 MB,随 bundle 分发,首次运行时复制到数据目录) locale/zh.json 中文文案 locale/en.json 英文文案 test/hosttest.mjs 宿主半边单测 test/smoke.mjs 客户端半边交互冒烟(自带极简 React 桩) screenshots.json 插件市场截图声明

跑测试

npm test # host 半边单测 + client 半边交互冒烟(自带极简 React 桩,无需 DSH 运行时)

打包与本地安装

npm pack --pack-destination .
dsh plugin --profile desktop add file:.\dsh-novel-shelf-0.1.0.tgz

改完 client 半边记得刷新页面再验证;改完 host 半边需要重装 bundle。

发一个版本

npm version patch
npm pack --pack-destination .
gh release upload v0.1.1 dsh-novel-shelf-0.1.1.tgz --repo good-saltfish/dsh-novel-shelf

Release 资产名建议带版本号(dsh-novel-shelf-<版本>.tgz),目录条目里用固定版本路径 releases/download/v<版本>/<资产名>,避免 latest/download/ 在下个版本时 404。

提交到插件市场后:那个红灯不会自己变绿

Submission gate 会卡仓库年龄 1 天,这是硬门槛,过了就行。但它是快照式的,只在 push 时重跑。

理论上有个 regate.yml 每 6 小时重跑一次红灯,但它有 MAX_RERUNS=20 上限、且按 PR 号升序处理。这个目录现在编号已到八千多、排队很长,你的 PR 极可能排在 20 名之外 —— 于是"约 24 小时后自动转绿"这句话对队列尾部不成立,红灯会一直挂着没人推。
所以仓库满 1 天后,自己往 fork 分支推一个空 commit 触发一次重跑:

git commit --allow-empty -m "chore: re-trigger the submission gate (repository is now a day old)"
git -c http.version=HTTP/1.1 push origin <分支名>

空 commit 不改任何文件,只是让 CI 重新判定一次 —— 年龄够了就立刻转绿,PR 状态从 UNSTABLE 变 CLEAN。

推不上 GitHub(Recv failure: Connection was reset)时加 -c http.version=HTTP/1.1,实测能治。

另外:合并是维护者的手动动作。全绿之后没人 review 就只是排队,PR 下留一句礼貌的评论是唯一合规的推进方式。条目合进 upstream main 之前,插件市场搜不到 —— 市场读的是 data/plugins/.yml,不在 main 上就是 404。

License

MIT
预览分享卡片长什么样 ↓good-saltfish/dsh-novel-shelf
分享 · DeepSeek Harness Hub
good-saltfish/dsh-novel-shelf

在右侧栏读本地 txt 小说,与项目界面并存不切换

这是你的仓库?认领条目

回到顶部