DSH 开发工具箱
当前版本 1.6.4 · 变更记录见 CHANGELOG.md(在这里写版本号,是因为
package.json 里那个数字用户看不到,而"我装的这版新不新"是他们会问的第一个问题)。
给 DSH(DeepSeek Harness) 插件开发者的一小组工具,外加一份随插件分发的开发经验库。
装一次,之后你自己开关里面的每个小工具。
它解决什么问题
开发 DSH 插件时会遇到很多文档里没写、只能踩出来的坑,比如:
- 复制到剪贴板为什么静默失败
- 为什么改了插件代码、重启插件却没生效(其实是必须重启客户端)
- 为什么自己建的 agent 收到消息却永远不执行
- 为什么悬浮框会疯狂闪烁
每个人各踩一遍、各花几小时,是纯浪费。
所以这个插件做三件事:
- 界面定位 —— 按 Alt 悬浮任意界面元素,显示它的名字与完整路径,一键复制
- 开发经验库 —— 89 条实测踩出来的坑,装插件就自动获得;而且索引会注入到 AI 助手的提示词里,让它也少犯同样的错
- 两道关卡注入到 AI 的工作流里 —— 动手前的强制自检(先查官方文档 / 查框架实现 / 找现成写法), 开工前的需求对齐(四要素确认 → 规划 → 再确认才动手)
- 任务验收闭环 —— 声称"做完/修好"之前先跑验证:验收条件、真实退出码、覆盖范围都进账本,
状态只由执行事实推导(没有入口能把某条标成"已通过";改了没验、验了又改都会如实暴露)。
只能人眼看的条件写
manual: true:它保持"未验证"、不阻塞完成,但会列在manualPending里
安装
前置
- 已安装 DSH 桌面客户端
- 会把插件装进你的 DSH profile
步骤(推荐:从 GitHub 直接装,一行地址)
打开 DSH → 侧边栏 插件 页面 → Add plugin
填入:
github:eighteentang/dsh-plugin-dev-tools确认插件列表里出现 dsh-plugin-dev-tools 且为启用状态
重启一次客户端(DSH 按文件路径缓存已加载的模块,必须重启才加载新代码)
不需要构建授权。 这个插件是纯 JavaScript,没有
build/prepare脚本, 所以 pnpm 没有脚本要跑,也就不会要求你在pnpm-workspace.yaml里加allowBuilds。 (带 TypeScript 构建的插件才需要那一步。)
备选:本地路径安装
想改代码、或者网络不通时用这个:
- 下载本仓库(
Code→Download ZIP,或git clone) - 把
dev-tools这个文件夹放到一个长期保留的位置 (路径里不要有中文和空格,例如D:\dsh-plugins\dev-tools) - 插件页 → Add plugin → 填那个文件夹的绝对路径,例如
D:\dsh-plugins\dev-tools - 同样需要重启一次客户端
⚠️ 用本地路径装时,DSH 会把它记成
link:形式 —— 这种方式不会安装该包的依赖。 本插件零依赖,所以没影响;但如果你在改它、并加了依赖,记得手动补。
确认装好了
打开 设置 → 开发工具,应该看到一个总开关和几个小工具。
用法
界面定位(Alt + 悬浮)
- 把鼠标放到想定位的界面元素上,按一下 Alt
- 浮框出现在光标旁,显示它属于哪个区域、完整 CSS 路径、尺寸
- 浮框不会跟着鼠标走 —— 你可以从容地把鼠标移到「复制」按钮上
- 也可以按
Ctrl+Alt+C直接复制,不用瞄准按钮 - 点浮框外面收起;再按 Alt 重新定位
复制出来的内容长这样,可以直接贴给 AI 助手或同事:
【界面定位】会话标题右侧工具区
slot: conversation.session.header.utilities
元素: button.dvt-header-btn
路径: div > div > header > div > button.dvt-header-btn
尺寸: 32×32 top=48 left=2490
说明: dev-tools 的 ⟳ 重启按钮渲染在这里
看到「(未收录的元素)」说明那个位置还没登记过名字 —— 把复制到的路径发给我们,就能给它起个名字,以后大家都用那个叫法。
重启按钮(⟳)
位置:会话标题右侧、那排小图标(在应用打开 / 定时任务 / 下载日志)的最右边。
点它 → 确认 → 结束 DSH 宿主进程 → DSH 弹出恢复框 → 在那里选「重启」(约 7 秒)或「退出」。
那个框不是报错,是正常流程 —— DSH 外壳把"宿主进程终止"一律当异常处理, 所以任何结束宿主的操作都会经过它。
为什么不能做成"全自动重启":DSH 没有对外的重启接口。本轮复核过:
它的重启原语是 app.relaunch() + quitWithoutConfirmation(),只被崩溃恢复对象调用;
当前版本 51 个 preload 通道里没有 restart / quit / shutdown;应用菜单里的
「重启应用与 Host」被 development 包着,安装版不存在。
自己 kill 外壳再拉起要慢 9 倍(实测 64 秒 vs 7 秒),还可能撞单实例锁 —— 所以仍然交给官方那个框。
2026-11-07 之前这里是侧边栏底部的 💀「结束进程」按钮;用户要求换成顶部 ⟳ 并去掉 💀。
开发模式总开关
打开后三件事生效:
- 注入"动手前的强制自检清单" —— AI 每次动手前要先查官方文档、查框架实现、 找现成写法可抄;并且明确"搜不到不等于不存在"
- 注入"开工前定需求"流程 —— 用户提出"我想做一个 XX"时,先对齐四要素 (名字 / 用途 / 使用场景 / 工作空间),确认后才规划,规划再确认才动手
- 注册
record_experience工具 —— AI 踩到新坑时可以直接记进经验库
关掉后这些立即撤下(不是隐藏,是真正注销),注入的内容变成 0 字符。
注入的体量:开着时约 6.6 千字符/次(自检清单 + 工作流约 1.8 千字符,经验索引约 4.8 千字符)。 经验库全文(216 KB / 12.1 万字符 —— 前者是磁盘字节、后者是文本长度, 中文一字三字节,两者差约 1.8 倍,别混)不进上下文,AI 需要细节时自己去读; 索引才进上下文,而且它按固定预算装配 —— 经验库继续变长也不会把提示词撑爆。
开发经验库
这是本插件最有价值的部分。
它在 experience/经验库.md,随插件分发 ——
你装插件就自动获得。而且它的索引会被注入到 AI 助手的提示词里,
所以 AI 也会知道"有这些坑存在",而不是重新踩一遍。
当前版本
打开 设置 → 开发工具,页面里会显示:
开发经验库 [⟳ 刷新]
版本 2026-11-07
条数 89 条
更新于 2026-11-07
指纹 62d686b8
注入索引 8 / 88 条带描述 · 4798 / 4800 字符
那个 ⟳ 是「刷新」按钮(重新读取经验库),不是重启按钮。 它存在的意义:你替换掉经验库文件后,不用重启客户端就能看到新数字。
「注入索引」那行告诉你:进提示词的是"全部标题 + 最近若干条的描述", 不是每条都带症状/解法(预算只有 4800 字符)。要查某条全文,用下面的搜索框。
同一个卡片里还有搜索框:输入关键词直接查库,返回编号 + 命中片段, 不用开一轮对话(对应宿主只读接口
/dev-tools/experience/search)。
想要新版怎么办
- 到本仓库看
experience/经验库.md有没有更新 - 有就下载、直接替换掉插件文件夹里的那一份
- 回到设置页点「⟳ 刷新」—— 不用重启客户端
怎么判断"是不是有更新":比对设置页显示的条数与指纹。 只看日期不够 —— 有人可能只是修正了一条旧经验(条数没变,但内容变了)。
怎么贡献一条经验
踩到新坑后:
- 在
experience/经验库.md末尾追加一条(格式照抄现有的) - 更新文件顶部注释里的
entries(条数)、updatedAt(日期)、fingerprint(指纹) - 提 PR
格式(固定格式是为了能被脚本解析并注入提示词):
## E15 · 一句话标题(写症状,不要写"要注意 XX")
- **范围**:通用 | 项目特定 —— 可选,缺省为"通用"
- **症状**:你会看到什么现象
- **解法**:该怎么做
- **细节**:可选补充(为什么、怎么查、实测案例)
写作标准:
| 要 | 不要 |
|---|---|
| 写具体症状("点复制按钮没反应,粘贴是空的") | 写原则("要注意剪贴板权限") |
| 写可执行的解法(给命令、给函数名) | 写方向("建议参考框架实现") |
| 一条一个坑 | 一条混好几个问题 |
原则 AI 本来就知道,具体症状才能让它对上号。
标注 范围:项目特定 的条目不会被注入到别人的提示词里 ——
它们只留在文件里作范例(讲的是某个具体产品的架构取舍,对别人没参考价值)。
目录结构
dev-tools/
├─ package.json 插件清单(声明"我是插件"、入口、浏览器半)
├─ cordis.patch.yml 加载器行声明
├─ index.js 宿主半(跑在 DSH 主进程里)
├─ client.js 客户端半(跑在页面里,**必须单文件、零 import**)
├─ app-control.js 应用控制接口(quit)+ 经验库/诊断/会话摘要/验收账本等只读路由
├─ dev-rule.js 提示词注入(自检清单 + 验收闭环规则)+ 开发模式状态
├─ workflow.js "开工前定需求"那段注入文本
├─ experience.js 经验库解析、索引生成、追加条目
├─ experience-tool.js record_experience / search_experience 工具
├─ acceptance.js 任务验收与验证闭环(三个工具 + 账本;状态只能由执行事实推导)
├─ self-check.js 「改了没生效」自证(加载时刻 + 内容哈希)
├─ session-digest.js 会话摘要(整轮中断 / 工具失败 / 最近改了什么)
├─ log-channel.js 宿主日志落盘(console.log 桌面端不落盘)
├─ DESIGN.md 设计取舍与已知限制("为什么这么写")
├─ templates/
│ └─ requirement-template.md 需求模板正文(连按两次反引号插入)
└─ experience/
├─ 经验库.md ← 89 条实测踩坑(随插件分发)
└─ README.md 经验库的使用与贡献说明
设计取舍与已知限制
这部分已经拆到独立文件,避免把"怎么用"和"为什么这样设计"混在一起:
→ DESIGN.md —— 已知限制、为什么有些做法看起来奇怪、 开发诊断的技术原理(哈希判定 / 代码与数据分开 / 服务清单的边界)。
「开发诊断」tab:为什么我的改动没生效
改完代码行为没变,然后开始瞎猜(ESM 缓存?路径不对?热重载没开?)—— 这个 tab 就是为了让这件事不用猜。
去哪找:会话区顶部的 tab 条上,注册即出现(在「对话轨迹 / 上下文」右边), 不需要先去任何引导页挑一次。
它分四块:
- 需要你做什么 —— 只有"要重启"这类需要你动手的事
- 这次会话出了什么问题 —— 整轮中断 / 工具失败 / 审批被拒(来自会话日志)
- 最近改了什么、为什么 —— git 提交(为什么)+ 未提交改动(原因未记录)
- 技术细节(默认折叠)—— 环境 / 文件哈希比对 / 进程里的服务 / 经验库 / 宿主日志
右上角**「复制诊断 JSON」**把整页数据一键拷走,贴给别人排查比自己念强。
第 4 块里的"宿主日志"不能省:宿主插件的 console.log 桌面端不落盘,
这是唯一的观察窗口(日志在 ~/.dsh/dev-tools.log,512 KB 滚一代)。
宿主侧接口
GET http://127.0.0.1:8800/dev-tools/self-check 直接返回同一份 JSON(只读)。
加载时还会往 ~/.dsh/dev-tools-selfcheck.log 写一条加载记录 ——
宿主插件的 console.log 桌面端不落盘,不自己记就等于没有。
No comments yet. Be the first to write one.