dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
DeepSeek Harness 插件:更好的 DSH 文件夹 —— 自动整理工作区,把同一上级目录下的工作区汇合成可折叠的文件夹节点(复用内置「按工作区树」视图,不覆盖官方 UI)。
自动整理 DSH 工作区:把同一个上级目录下的多个工作区汇合成一个可折叠的文件夹节点。
仓库:https://github.com/huguangyu666/dsh-plugin-better-folders
DSH 的工作区(Workspace)=「一个项目目录 + 跑在它下面的会话」。真实使用中这些目录往往成堆地躺在同一个父目录里:
C:\Users\me\Documents\MyProjects\plugin-workspace
C:\Users\me\Documents\MyProjects\dsh-plugin-memory
C:\Users\me\Documents\MyProjects\demo-app
C:\Users\me\Documents\MyProjects\quant
... ← 十几个同级目录
C:\Users\me\code\sandbox
C:\Users\me\code\webapp
侧边栏默认的「按工作区」是平铺的,十几个同级目录排成一大列,找起来很累。
本插件把它们汇合成:
📁 MyProjects ← 自动生成的文件夹节点
├ plugin-workspace
├ dsh-plugin-memory
├ demo-app
└ quant
📁 code
├ sandbox
└ webapp
notes ← 单个工作区保持原样
DSH 侧边栏自带 「按工作区树」 视图(groupBy = "workspace-tree",由
@deepseek-ai/dsh-client-ui-workspace 提供):它会把每个工作区挂到最近的已注册祖先工作区下面。
所以「把相同上一级目录的工作区汇合在一起」在本插件里等价于:
把那个共同的上级目录本身注册成一个工作区(文件夹节点)。
注册完,内置树视图会自动把子工作区嵌进去 —— 插件不需要、也没有去覆盖官方 UI,因此 不会出现「插件一挂,侧边栏白屏」这类事故。
| 能力 | 入口 |
|---|---|
| 一键整理 / 预览 / 还原 | 设置 → 插件 → 更好的 DSH 文件夹 |
| 侧边栏快捷整理按钮 | 侧边栏底部 📁 整理文件夹 |
| 对话斜杠指令 | /folders status | plan | organize | unmerge |
| Agent 原生工具 | organize_workspaces(action: status / plan / apply / unmerge) |
| 自动整理 | 工作区列表变化后自动汇合(可关) |
| 原生设置表单 | 设置命名空间 better-folders |
| 配置 | 默认 | 含义 |
|---|---|---|
enabled | true | 插件总开关 |
autoOrganize | true | 工作区列表变化后自动整理 |
minChildren | 2 | 至少多少个同级工作区才汇合出一个文件夹节点 |
maxDepth | 1 | 向上追溯几级目录寻找共同上级(1 = 只看直接上级) |
autoTreeView | true | 整理后把侧边栏切到「按工作区树」视图 |
keepOrder | true | 把文件夹节点排在它的第一个子工作区之前 |
关于向上级联(已内置防护):如果某上级目录本身也是一个工作区、且它下面正好还有 另一个工作区,那么它也会被当作一个汇合点。为了避免「每建一层就在更上一层凑出新配对、 一路级联到盘符根」,插件对自己创建的文件夹节点做了排除:它们不再算作上一层的 同级成员。用户自己注册的父级工作区不受此限制(例如你已把
sandbox建成工作区, 它仍会正常挂在code下)。根目录(C:\、/)永远不建节点。
「按上级目录汇合」由磁盘层级决定,你只能被动接受。表是你自己定的集合:
📋 性能对比 ← 只是一个名字,不是目录
├ 测试区\titan性能测试 ← 真实工作区
├ 测试区\官方性能对照
└ 测试区\coder单独测试
入口就在侧边栏 「工作区」标题行:
工作区 📁 📋 🔍 ⚙ 📁+
↑ ↑
整理 表
那一行官方没有对外槽位(搜索 / 视图选项 / 添加工作区都是组件内部写死的)。插件用的是 只读测量 + 浮层贴合:只读取该行的位置,把按钮浮在它左边,不修改官方 DOM, 因此不会和 React 的协调打架。图标取自官方组件库
@deepseek-ai/dsh-client-ui-primitives,尺寸/圆角/悬停全部对齐原生按钮。 万一某天 DSH 大改版导致定位失败,会自动退回侧边栏底部的「整理文件夹」按钮。
也可以用指令:
/folders tables # 列出所有表
/folders tables new 性能对比 # 建表
/folders tables add 性能对比 titan # 把工作区加进去(按路径片段匹配)
/folders tables remove 性能对比 titan # 移出
/folders tables rename 性能对比 A/B # 改名
/folders tables delete 性能对比 # 删表(不删任何东西)
或让模型调用工具 manage_workspace_tables。
workspaceRegistry.create(),从不删除任何工作区、目录或会话历史。unmerge 只删除本插件自己创建过、且没有任何会话的文件夹节点
(记录在 ~/.dsh/better-folders/state.json)。用户手动建的工作区、已经在里面开过会话
的节点,一律保留。autoOrganize 置为 false,把「要不要继续自动整理」的决定权交回你(在面板里一键就能重开)。domain/changed 触发的自动整理会自然收敛。# 1) 构建
npm install # 只装 esbuild
npm run build
# 2) 跑测试
npm test
# 3) 装进 profile(默认 web),带备份与 dump-config 复核
node tools/install-into-profile.mjs --profile web --dry-run # 先看将执行什么
node tools/install-into-profile.mjs --profile web
装完重启 DSH(插件在启动时装配)。
从 GitHub 克隆安装:
git clone https://github.com/huguangyu666/dsh-plugin-better-folders.git
cd dsh-plugin-better-folders
npm install && npm run build
node tools/install-into-profile.mjs --profile web
卸载:
node tools/install-into-profile.mjs --profile web --uninstall
装上并重启(桌面版需刷新页面加载客户端半)之后,通常什么都不用做:
autoTreeView 是开的、且确实存在可汇合的
目录,就把侧边栏切到「按工作区树」。这一步是能不能看出效果的关键 ——
整理本身只注册工作区,真正的视觉汇合由内置树视图完成;不切视图的话,侧边栏
只会平白多出几个条目,反而更乱。手动操作:
autoTreeView 开着,侧边栏会自动切到「按工作区树」。
若没切过去(客户端服务不可用时会退回写 localStorage),手动选
视图选项 → 分组方式 → 按工作区树,或刷新页面。没看到效果时先查这三件事:① 插件装的是不是当前正在用的那个 profile (桌面版用
desktop,dsh web用web);② 客户端半加载了没(刷新页面); ③ 侧边栏分组方式是不是「按工作区树」。立刻手动见效:侧边栏 视图选项 → 分组方式 → 按工作区树。整理只是把上级目录 注册成工作区,真正的视觉汇合由这个内置视图完成;只要切过去,文件夹节点就会把同级 工作区收进去。
排查「点了没反应」:客户端半会把能力探测结果写到
~/.dsh/better-folders/diag.json(/better-folders/api/diag),不需要开 DevTools。
对话里也可以:
/folders # 查看现状
/folders plan # 预览
/folders organize # 执行整理
/folders unmerge # 还原
面板与侧边栏按钮通过同源接口驱动(ctx.webServer 注册的 prefix 路由):
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /better-folders/api/status | 现状 + 分组 + 已建节点 + 上次运行结果 |
| GET | /better-folders/api/settings | 当前配置 |
| POST | /better-folders/api/settings | 写入配置(部分字段) |
| POST | /better-folders/api/preview | 预览计划,不写入 |
| POST | /better-folders/api/apply | 执行整理 |
| POST | /better-folders/api/unmerge | 还原 |
dsh-plugin-better-folders/
├── src/
│ ├── plan.js # 纯分组算法 + 整理器(零外部依赖,可单测)
│ ├── index.js # Host 端:设置 / 自动整理 / HTTP API / 工具 / 指令 / 提示词
│ └── client-source.js # Client 端:设置面板 + 侧边栏按钮 + 树视图切换
├── lib/ # esbuild 产物(lib/index.js + lib/client.js)
├── test/
│ ├── contract.test.mjs # 包元数据 / patch / 产物契约
│ ├── plan.test.mjs # 分组算法与整理器
│ └── mock-lifecycle.test.mjs # Fake Context 生命周期与工具/指令行为
├── tools/install-into-profile.mjs
├── build.mjs
├── cordis.patch.yml
└── package.json
inject 只声明 workspaceRegistry。settings / webServer / tools /
commands / systemPrompt 全部通过 ctx.inject(...) 按需挂载 —— 在 headless profile
里没有 webServer 时,插件依然能提供工具与指令,而不是整个挂掉。@deepseek-ai/schemastery 懒加载:DSH 运行时会提供;本地裸跑测试时加载失败只会
降级为「没有原生设置表单」,不影响整理能力。fs.writeFileSync(..., 'utf8'),不经过 PowerShell
的 Set-Content,避免 DSH 启动时 JSON.parse 被 BOM 打挂。ctx.uiWorkspace.view.setGroupBy('workspace-tree')
即时生效;不可用时退回改写 localStorage 的 dsh.workspace.view.v5(下次刷新生效)。npm test
32 个用例覆盖:路径规范化(Windows / POSIX / UNC)、汇合计划(同级 / 多级 / 已注册父目录 / 根目录保护 / 顺序锚点)、整理器(预览 / 应用 / 幂等 / 还原 / 会话保护 / 用户工作区保护)、 Fake Context 生命周期(工具 / 指令 / 提示词 / 路由注册与行为)。
MIT