DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Hnqhj /

Hnqhj/dsh-library

Verified

DeepSeek Harness 的本地产出资料库插件 —— 三栏页面浏览检索预览整理,收拢对话与项目产出的文档/表格/图片,零第三方依赖,助手只可存不可改

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@00b3c284
dsh-library 图标

资料库 · dsh-library

DeepSeek Harness 的本地产出资料库插件。

把每次对话、每个项目产出的东西收进一处:文档、表格、图片、音视频、链接、附件 —— 以自带页面的样子出现在 DSH 里,可浏览、可检索、可预览、可整理,也能让助手读取并按路径引用。

version license node platform tests deps


目录

功能一览 · 界面 · 快速开始 · 配置 · 架构 · HTTP API · 文档直接预览 · 安全设计 · 测试 · 路线图 · 与资产库的边界 · 排障 FAQ


功能一览

能力 说明
🗂 三栏主页面 左目录树 / 中列表(网格与列表可切换)/ 右内容预览,视觉与 DSH 原生页面同一批零件
🔍 整库检索 按文件名、路径、标签、备注全文搜索;类型 / 目录 / 标签三组筛选 chip 可叠加,计数随口径实时变化
👁 文档直接预览 Markdown、Excel(.xlsx / .csv / .tsv)、Word(.docx)、JSON 与代码文件在页内直接查看,不下载、不跳走
🏷 标签与备注 每条资料可打标签、写备注;支持批量标注(一次最多 2000 条)
📥 多种入库 拖拽进页面、系统文件选择、新建文档/文件夹、「从目录导入」批量复制
🤝 助手可存不可改 助手能把新产出存进库,但不可修改 / 移动 / 删除已有资料 —— 整理权在人
🌗 明暗自适应 配色只读 DSH 设计令牌 --dsw-alias-*,跟随宿主主题与密度设置
🧩 零第三方依赖 运行时只依赖 Node 内置模块与 DSH 自身提供的平台件,xlsx/docx 解析基于 node:zlib 手写最小 zip 读取器

界面

三栏布局 —— 左树 / 中列表 / 右内容,点开任意一条是页内「放大卡片」:

三栏布局与表格预览

网格视图,媒体卡片带类型角标与标签:

网格视图

右栏直接预览 Markdown / Word / Excel / 代码(真实渲染,非截图拼接):

Markdown Word 文档
Markdown 预览 Word 预览

快速开始

前置:Node.js ≥ 22、已安装 DeepSeek Harness、本仓库已在本地。

# 1) 装进 profile(官方 CLI 负责 bundle 层)
& 'F:\DSH\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop add 'D:\dsh-library'

然后编辑 C:\Users\<你>\.dsh\profiles\desktop\package.json:

  1. 把依赖规格从 link: 改成 file:(file: 让 pnpm 复制成实体目录,解析链才完整);
  2. 把 dsh-library 加进 dsh.profile.bundles 数组 —— 不加这一行,插件不会进组合配置树。
{
  "dependencies": { "dsh-library": "file:D:/dsh-library" },
  "dsh": { "profile": { "bundles": ["…", "dsh-library"] } }
}
# 2) 同步一次,然后完全重启 DSH(托盘也退出)
& 'F:\DSH\resources\runtime\cli\bin\dsh.cmd' plugin --profile desktop install

重启后侧边栏出现「资料库」入口即成功。改完源码不生效、或想核对安装状态,见排障 FAQ。

配置

cordis.patch.yml 里按行 id 覆盖(全部字段都有默认值,不配也能跑):

- id: library
  name: dsh-library
  config:
    root: 'D:/dsh-library-data'   # '' = 退回 <DSH_HOME>/library
    includeHidden: false
    maxDepth: 8
    maxFiles: 20000
    pageSize: 60
    cacheMs: 1500            # 扫描缓存毫秒数;写操作会立刻作废缓存,要绝对实时就设 0
    maxUploadBytes: 67108864  # 单次入库上限(64 MB)
    allowAgentSave: true     # 助手可把新产出存进库
    allowAgentModify: false  # 助手不可改动 / 移动 / 删除已有资料

库根解析顺序:显式配置 → 出厂默认(lib/config.js 的 LIBRARY_DEFAULTS.root)→ 显式 '' 退回 <DSH_HOME>/library。 出厂默认刻意写死一个非系统盘路径:库根放错会静默留在 C 盘上,等用户发现时已经积了几 GB —— 把默认值与补丁层设成同一处,堵掉这个失败模式。换机器时两处一起改。

架构

插件分两半,同包不同进程侧:

dsh-library/
├── index.js              # 宿主半入口:激活、配置、路由挂载
├── lib/
│   ├── config.js         # 配置默认值与解析
│   ├── scan.js           # 递归扫描 + 目录汇总(唯一事实来源)
│   ├── store.js          # .library-index.json(只存人的输入:标签/备注/来源)
│   ├── service.js        # 内核:快照缓存、列表/搜索、文档解析、写操作
│   ├── routes.js         # HTTP 面:15 个端点,先过信任栅栏再干活
│   ├── paths.js          # 路径归一化与包含检查(安全核心)
│   ├── kinds.js          # 类型目录(未收录扩展名归 file,不是忽略)
│   ├── names.js          # 名称校验与去重(名字 (2).ext,Windows 保留名)
│   └── office.js         # 零依赖 xlsx/docx 解析(自写最小 zip 读取器)
└── client.js             # 浏览器半:三栏面板,经 window.__ModuleLoader__ 注入

原生感的来源 —— DSH 的界面本身由槽位组合而成,一个原生页面只有一种做法:

侧边栏条目  slots.inject('sidebar.panellist')  →  register({ id, order, label }, Icon)
页面本体    slots.inject('main')               →  register({ key: <同一个 id> }, Panel)

同一个 id 连接两者,点击侧边栏即切换页面。没有修改 DSH 安装本体(那会被应用更新覆盖)——所谓「内置」是走插件组合层,体验上与自带页面无差别。

扫描是唯一事实来源,索引只保存人的输入:

<库根>/
├── .library-index.json     # 标签 / 备注 / 来源;扫描自动跳过它
├── 分组/
│   ├── 笔记.md
│   └── 2026/
│       └── 截图.png
└── 附件.zip

你在文件管理器里删掉或改名,资料库下一轮扫描就跟着变,不会留下幽灵条目;扫描默认跳过点开头条目、node_modules / .git、Office 临时文件与系统垃圾。

HTTP API

一条前缀路由承载全部端点,全部先过浏览器信任栅栏:

端点 说明
GET /api/library/status 库根、条目统计、能力清单(面板按能力禁用控件,不报错)
GET /api/library/items 列目录或搜索。scope / parent / q / kind / tag / sort / dir / limit / offset / recent
GET /api/library/item?path= 单条详情(含绝对路径,供助手引用)
GET /api/library/tree 分组树 + 最近添加
GET /api/library/facets?scope= chip 行计数 —— 按范围统计而非按当前页,翻页数字不会漂
GET /api/library/document?path= 文档内容解析,四类出口见下表
GET /api/library/file?path= 文件流。Range / If-None-Match / HEAD / download=1 全支持
POST /api/library/mkdir /create /upload 入库三件套,只新增不覆盖(重名自动 名字 (2).ext)
GET /api/library/external?dir= 库外目录候选清单(只读扫描)
POST /api/library/import 从库外目录成批复制进来(只复制不移动,逐份报错不整体失败)
POST /api/library/annotate 标签 / 备注 / 来源,单条与批量同端点
POST /api/library/rescan 强制重扫
POST /api/library/reveal 系统文件管理器定位资料。唯一离开进程的端点,受 allowReveal 开关控制
细节约定(为什么这样设计)
  • scope 用「键是否存在」区分模式:出现了 scope 键 = 检索模式(递归找文件),没出现 = 子项模式(只列直接子项)。子树比较用 scope + '/' 前缀而不是裸 startsWith,否则 图片集/ 里的东西会被算进 图片/。
  • /facets 不能由面板自己数:面板手里只有当前一页,自数的计数会随翻页变化。chip 说的是「这个范围里有多少」,不是「这一页里有多少」。
  • /annotate 批量契约:请求给路径 paths,响应回条目 items + missing(已不存在、没改成的路径),面板据此报「已更新 5 项,有 1 份没改成」。命中为空时不碰磁盘,避免造出空条目。
  • /reveal 三道收口:配置开关(关掉时按钮整个不出现)→ resolveInside 挡路径逃逸 → 隐藏段 403;再 stat 确认存在才 spawn,且只 spawn 不经 shell——shell: true 等于把文件名当命令行片段解释。

文档直接预览

/document 按扩展名把文件解成结构化内容,右栏直接查看:

扩展名 返回 渲染
.md { text } 官方 MarkdownText
.xlsx / .csv / .tsv { sheets: [{ name, rows }] } 页内表格(多工作表可切)
.docx { blocks: [...] } heading / list / paragraph / table 按文档顺序
.json 与代码 { text } 官方 CodeBlock(语法高亮)

失败按 code 分级而不是合成一句「打不开」,因为处置方式完全不同: ENCRYPTED(422) → 去密码另存;NOT_XLSX / CORRUPT 等(422) → 重新导出;UNSUPPORTED(415) → 换格式;TOO_LARGE(413) → 下载。

三条实现约束:CSV 用状态机解析(引号内换行/逗号、"" 转义,split('\n') 三种全错);文本上限 512 KB 只读前 N 字节,截断是正常结果(truncated: true + 界面一行小字)而非错误态;语义失败统一 4xx 而不是 5xx——5xx 的运维口径会指向「资料库自己坏了」。

安全设计

所有能从库根读到字节的路径都过同一套收口,缺一不可:

  1. 路径包含检查(resolveInside):归一化后必须仍落在库根内,..、盘符、绝对路径一律拒绝。Windows 上大小写不敏感 + 给根补分隔符(否则 C:\lib2 会被 C:\lib 判成在内);逃逸校验在解码之后(%2E%2E 还原成 .. 也要拦住)。
  2. 隐藏段拒绝:任何一段以点开头直接 403 —— 索引文件与库根元数据不在可读范围。
  3. HTML / SVG 强制 CSP: sandbox:能携带脚本的格式在流式返回时加沙箱头。少了它,「在资料库里预览一个页面」就等于在 DSH 页面所属的源里执行别人写的脚本。
  4. 信任栅栏按请求解析:裸 Web 路由不继承 Connection 服务的 Host/Origin 检查,每个请求先过栅栏再做任何工作(Connection 行可能在路由注册之后才激活,快照式捕获会留永久空洞)。
  5. 助手权限收窄:allowAgentSave 只开「往里放新东西」;整理、改名、删除一律由人在页面上做。

入库四端点只新增不覆盖;写入先落 .part 临时文件再改名(.part 本就在扫描跳过规则里,写一半失败不会留下半截文件);批量导入只认普通文件(lstat,符号链接跳过)。

测试

五套离线测试、500+ 项断言,不启动 DSH 也能跑:

npm test        # logic / scan / client / host / office 五套
npm run check   # 只读诊断真实库根
套件 覆盖
logic 内核纯逻辑:路径、名称、类型
scan 扫描、目录汇总、跳过规则、截断
client 面板交互:迷你渲染器按依赖数组真实跑 effect,导航/筛选/拖拽/批量都过一遍
host HTTP 面:真实起 http 服务器走真 socket(假 response 验不了 Range 与流)
office xlsx/docx 解析:正常、损坏、加密、格式错配、截断
给插件开发者的三条血泪教训(测试为什么长这样)
  1. 样式表必须渲染进元素树(h('style', null, STYLE))。宿主不会顺手执行你写在模块作用域里的模板字符串——CSS 只在元素树里出现浏览器才建样式表,否则真机上是无样式的裸 HTML,而 className 断言全绿。契约测试有四条断言守着这件事。
  2. file: 装法是副本不是软链,pnpm 不按内容哈希检测目录依赖变更——改完源码必须手动同步,否则「磁盘上全对、界面上没变化」。
  3. 离线替身测不出真机契约错配(例:宿主 locale 只认字符串模板词条)。给面板包一层 class 错误边界、componentDidCatch 把堆栈渲染成可见文本,真机一次就拿到根因。

路线图

阶段 内容 状态
1–3 插件骨架、宿主半(库根/扫描/索引/HTTP)、页面与入库 ✅ 完成
5 页内放大卡片、视觉重做、/facets、批量标注、/reveal ✅ 完成
6 离屏渲染 + 无头截图验证链(README 截图即产自这条链) ✅ 完成
7 三栏布局 + 四类文档直接预览、零依赖 Office 解析 ✅ 完成
8 助手工具:概览 / 检索 / 取用 / 保存 ⏳ 待办
9 进阶:合集(一组资料当一个整体检索)、参照图钉 ⏳ 待办
— 从交付文件卡片一键收进资料库 ⏳ 需先还原会话记录里的真实路径,单独评估

与资产库的边界

dsh-asset-library(项目素材索引)与本插件(跨会话资料库)独立并存、互不依赖、不互相替代:

资产库 资料库(本插件)
管什么 项目目录里的素材 对话与项目产出的资料
文件在哪 原地不动,只索引 收进中央实体库,是真实副本
语义 浏览与筛选 归档与复用

资料库是跨会话的中央库,刻意不注册任何右侧栏停靠面——从「一次会话的侧栏」打开跨会话的库,坐标系不对。契约测试有一条断言守着「不注册右侧栏 tab」别悄悄回来。

排障 FAQ

改完源码为什么不生效?

file: 装的是副本(profiles\desktop\node_modules\dsh-library),且 pnpm 不按内容哈希检测目录依赖变更——dsh plugin install 会回 "Already up to date" 但什么都不拷。每次改完源码跑一次同步:

powershell -NoProfile -ExecutionPolicy Bypass -File "D:\dsh-library\tools\sync-all.ps1"

宿主半与面板都需要完全重启 DSH。客户端模块是进程启动时注入的,刷新窗口或重开对话都不会重新加载它。托盘图标还在就是没退干净。

想核对安装状态但不启动 DSH?
node tools/install-check.mjs    # 只读,26 项

它查磁盘状态:profile 声明、lock 条目、文件是否同步、插件自身声明、库根位置、两个注册席位。它查不了「DSH 进程里加载没加载」——/api/library/* 是进程内虚拟路由,不监听 TCP 端口,curl 不出来,最后一步只能重启后在界面上确认。

侧栏入口消失了?

按顺序查:① package.json 的 dsh.profile.bundles 数组里有没有 dsh-library(没有就永远不会挂载);② 是否完全重启过 DSH;③ node tools/install-check.mjs 看文件是否同步齐。参见同系列 dsh-plugin-development 经验:入口消失最常见的原因是 bundles 缺条目与没退干净。


License · MIT · 由 Hnqhj 维护

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout
—/ 5

No ratings yet

Verified DSH bundle

Commit 00b3c28401f8

Community comments

No comments yet. Be the first to write one.