Bundle
dsh-plugin-dev-tools
DSH 开发工具箱:按 Alt 悬浮查看界面元素归属、把踩过的坑记进随插件分发的经验库、开发模式下自动注入动手前的自检清单。
- Source
- eighteentang
- License
- MIT
- Updated
- Updated 24 days ago
Readme
# DSH 开发工具箱
给 [DSH(DeepSeek Harness)](https://deepseek-harness.github.io/deepseek-harness/) 插件开发者的一小组工具,外加一份**随插件分发的开发经验库**。
装一次,之后你自己开关里面的每个小工具。
---
## 它解决什么问题
开发 DSH 插件时会遇到很多**文档里没写、只能踩出来**的坑,比如:
- 复制到剪贴板为什么静默失败
- 为什么改了插件代码、重启插件却没生效(其实是必须重启**客户端**)
- 为什么自己建的 agent 收到消息却永远不执行
- 为什么悬浮框会疯狂闪烁
每个人各踩一遍、各花几小时,是纯浪费。
**所以这个插件做三件事**:
1. **界面定位** —— 按 Alt 悬浮任意界面元素,显示它的名字与完整路径,一键复制
2. **开发经验库** —— 23 条实测踩出来的坑,装插件就自动获得;而且**索引会注入到 AI 助手的提示词里**,让它也少犯同样的错
3. **两道关卡注入到 AI 的工作流里** ——
**动手前**的强制自检(先查官方文档 / 查框架实现 / 找现成写法),
**开工前**的需求对齐(四要素确认 → 规划 → 再确认才动手)
---
## 安装
### 前置
- 已安装 DSH 桌面客户端
- 会把插件装进你的 DSH profile
### 步骤(推荐:从 GitHub 直接装,一行地址)
1. 打开 DSH → 侧边栏 **插件** 页面 → **Add plugin**
2. 填入:
```
github:eighteentang/dsh-plugin-dev-tools
```
3. 确认插件列表里出现 **dsh-plugin-dev-tools** 且为**启用**状态
4. **重启一次客户端**(DSH 按文件路径缓存已加载的模块,必须重启才加载新代码)
> **不需要构建授权。** 这个插件是纯 JavaScript,没有 `build`/`prepare` 脚本,
> 所以 pnpm 没有脚本要跑,也就不会要求你在 `pnpm-workspace.yaml` 里加 `allowBuilds`。
> (带 TypeScript 构建的插件才需要那一步。)
### 备选:本地路径安装
想改代码、或者网络不通时用这个:
1. **下载本仓库**(`Code` → `Download ZIP`,或 `git clone`)
2. 把 **`dev-tools` 这个文件夹**放到一个长期保留的位置
(路径里不要有中文和空格,例如 `D:\dsh-plugins\dev-tools`)
3. 插件页 → **Add plugin** → 填**那个文件夹的绝对路径**,例如 `D:\dsh-plugins\dev-tools`
4. 同样需要**重启一次客户端**
> ⚠️ 用本地路径装时,DSH 会把它记成 `link:` 形式 —— **这种方式不会安装该包的依赖**。
> 本插件零依赖,所以没影响;但如果你在改它、并加了依赖,记得手动补。
### 确认装好了
打开 **设置 → 开发工具**,应该看到一个总开关和几个小工具。
---
## 用法
### 界面定位(Alt + 悬浮)
1. 把鼠标放到想定位的界面元素上,**按一下 Alt**
2. 浮框出现在光标旁,显示它属于哪个区域、完整 CSS 路径、尺寸
3. 浮框**不会跟着鼠标走** —— 你可以从容地把鼠标移到「复制」按钮上
4. 也可以按 `Ctrl+Alt+C` 直接复制,不用瞄准按钮
5. 点浮框外面收起;再按 Alt 重新定位
**复制出来的内容长这样**,可以直接贴给 AI 助手或同事:
```
【界面定位】侧边栏底部动作区
slot: sidebar.footer.action
元素: div.dvt-controls
路径: body > div.app > div.sidebar > div.dvt-controls
尺寸: 120×26 top=720 left=12
说明: 💀 结束进程按钮渲染在这里
```
看到「**(未收录的元素)**」说明那个位置还没登记过名字 ——
把复制到的路径发给我们,就能给它起个名字,以后大家都用那个叫法。
### 结束进程按钮(💀)
侧边栏底部的一个 💀 按钮:**结束 DSH 宿主进程**。
点它 → 确认 → DSH 弹出**恢复框** → 在那里选「重启」(干净的自动重启,约 7 秒)或「退出」。
**那个框不是报错,是正常流程** —— DSH 外壳把"宿主进程终止"一律当异常处理,
所以任何结束宿主的操作都会经过它。
**为什么不做成"直接重启"按钮**:DSH **没有对外的重启接口**。
它的重启原语是 `app.relaunch() + quitWithoutConfirmation()`,写在 `lib/main.js` 的
崩溃恢复对象里,**只被 `fail()` 调用,没有任何 IPC 暴露**
(42 个 preload 通道里没有 restart / quit / shutdown)。
自己 kill 进程再拉起要慢 9 倍(实测 64 秒 vs 7 秒),所以不如把选择交给官方那个框。
### 开发模式总开关
打开后三件事生效:
1. **注入"动手前的强制自检清单"** —— AI 每次动手前要先查官方文档、查框架实现、
找现成写法可抄;并且明确"搜不到不等于不存在"
2. **注入"开工前定需求"流程** —— 用户提出"我想做一个 XX"时,先对齐四要素
(名字 / 用途 / 使用场景 / 工作空间),确认后才规划,规划再确认才动手
3. **注册 `record_experience` 工具** —— AI 踩到新坑时可以直接记进经验库
关掉后这些立即撤下(不是隐藏,是**真正注销**),注入的内容变成 0 字符。
**注入的体量**:开着时约 5.5 KB/次(自检清单 + 工作流约 1.8 KB,经验索引约 3.7 KB)。
经验库**全文**(约 17 KB)不进上下文,AI 需要细节时自己去读。
---
## 开发经验库
**这是本插件最有价值的部分。**
它在 [`experience/经验库.md`](experience/经验库.md),**随插件分发** ——
你装插件就自动获得。而且它的**索引会被注入到 AI 助手的提示词里**,
所以 AI 也会知道"有这些坑存在",而不是重新踩一遍。
### 当前版本
打开 **设置 → 开发工具**,页面里会显示:
```
开发经验库 [⟳ 刷新]
版本 2026-09-26
条数 23 条
更新于 2026-09-26
指纹 b941c37b
```
> **那个 ⟳ 是「刷新」按钮**(重新读取经验库),不是重启按钮。
> 它存在的意义:你替换掉经验库文件后,不用重启客户端就能看到新数字。
### 想要新版怎么办
1. 到本仓库看 `experience/经验库.md` 有没有更新
2. 有就**下载、直接替换掉插件文件夹里的那一份**
3. 回到设置页点「**⟳ 刷新**」—— **不用重启客户端**
**怎么判断"是不是有更新"**:比对设置页显示的**条数**与**指纹**。
只看日期不够 —— 有人可能只是**修正**了一条旧经验(条数没变,但内容变了)。
### 怎么贡献一条经验
踩到新坑后:
1. 在 `experience/经验库.md` **末尾追加一条**(格式照抄现有的)
2. 更新文件顶部注释里的 `entries`(条数)、`updatedAt`(日期)、`fingerprint`(指纹)
3. 提 PR
**格式**(固定格式是为了能被脚本解析并注入提示词):
```markdown
## E15 · 一句话标题(写症状,不要写"要注意 XX")
- **范围**:通用 | 项目特定 —— 可选,缺省为"通用"
- **症状**:你会看到什么现象
- **解法**:该怎么做
- **细节**:可选补充(为什么、怎么查、实测案例)
```
**写作标准**:
| 要 | 不要 |
|---|---|
| 写**具体症状**("点复制按钮没反应,粘贴是空的") | 写原则("要注意剪贴板权限") |
| 写**可执行的解法**(给命令、给函数名) | 写方向("建议参考框架实现") |
| 一条一个坑 | 一条混好几个问题 |
**原则 AI 本来就知道,具体症状才能让它对上号。**
标注 `范围:项目特定` 的条目**不会**被注入到别人的提示词里 ——
它们只留在文件里作范例(讲的是某个具体产品的架构取舍,对别人没参考价值)。
---
## 目录结构
```
dev-tools/
├─ package.json 插件清单(声明"我是插件"、入口、浏览器半)
├─ cordis.patch.yml 加载器行声明
├─ index.js 宿主半(跑在 DSH 主进程里)
├─ client.js 客户端半(跑在页面里,**必须单文件、零 import**)
├─ app-control.js 结束进程接口 + 经验库查询 + 诊断接口
├─ dev-rule.js 提示词注入(自检清单)+ 开发模式状态
├─ workflow.js "开工前定需求"那段注入文本
├─ experience.js 经验库解析、索引生成、追加条目
├─ experience-tool.js record_experience 工具
└─ experience/
├─ 经验库.md ← 23 条实测踩坑(随插件分发)
└─ README.md 经验库的使用与贡献说明
```
---
## 已知限制与设计取舍
- **结束进程会弹一次恢复框**:DSH 桌面外壳把"宿主进程被终止"一律当异常。
插件侧无法消除(框架没有对外的重启接口)。所以这里索性不做"重启按钮",
只做"结束进程",把重启/退出交给那个框选
- **经验库的项目特定条目不进提示词**:这是有意的(避免占别人的 context)
- **经验索引里的"解法"只截 60 字**("症状"给 100 字):症状用来"对上号",
解法只用来判断值不值得去读全文。这样索引从 4.4 KB 降到 3.7 KB
- **`Config` 无法被内省**:因为外部插件 import 不到 asar 内部的
`@deepseek-ai/schemastery`,只能手写 Standard Schema,于是
`Config.listConfigs` 显示 `status: "unsupported"`。功能不受影响
- **本地路径安装是 `link:` 形式,不会安装依赖**:本插件零依赖所以没影响
---
## 关于"为什么有些做法看起来奇怪"
源码里那些注释不是装饰。它们记录了**实测踩出来的坑**,比如:
- 为什么 `ctx.inject(deps, cb)` 不能用 `ctx.get(deps)` 代替
- 为什么 `tools.register` 的 `parameters` 必须是 JSON Schema 而不是简写
- 为什么开关状态放内存而不是文件
- 为什么 `useEffect` 的依赖数组里不能放它自己 setState 的 state
- 为什么 `single` 槽位可以用更低的 `priority` 遮蔽 shipped 的注册
- 为什么 CSS 注释里不能出现反引号、也不能让 markdown 加粗紧贴路径
(前者截断模板字符串,后者凑出 `*/` 提前结束注释 —— 都实测踩过)
改代码前读一下注释,能省下你重新踩一遍的时间。
**更详细的事故记录**在 `experience/经验库.md`,23 条,每条都是踩出来的。
---
## 许可证
[MIT](LICENSE)
Install
dsh plugin --profile web add github:eighteentang/dsh-plugin-dev-tools
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-plugin-dev-tools from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.