在使用 DeepSeek Harness (DSH) 时,结束当前会话或关闭 Web 服务需要一种可控的方式。dsh-web-close 插件解决了一个具体问题:在 DSH Web 界面上提供一个常驻的关闭按钮,允许用户通过交互式确认来执行优雅关闭。
这是一个标准 DSH bundle 插件,由 Aclguh 维护,采用 MIT 许可证。它不依赖任何图片资源,通过原生 DOM 实现功能,支持跨平台运行。
核心功能¶
- 常驻自启:作为标准 DSH bundle 插件,安装一次后每次
dsh web启动都会自动加载。 - 界面设计:半透明红色圆形按钮,背景色为
rgba(220,38,38,.42),带有毛玻璃效果和红色描边光晕。图标为内联 SVG 手绘电源符号,无图片资源。 - 位置记忆:按钮默认显示在视口
top: 1234px / left: 306px。支持拖动,位置会写入localStorage(键名为dsh-web-close-pos),刷新或重启浏览器后自动恢复。 - 二次确认:点击按钮后弹出视口居中的确认框,显示目标进程 PID 与地址。包含“取消”和“确认关闭”两个选项。
- 优雅关闭:不使用
kill -9强制终止,而是通过调用 DSH 的appExit机制或发送SIGINT信号,先卸载整棵插件树,再退出进程。 - 关闭标签页:确认关闭后,浏览器侧会自动执行
window.close()尝试关闭当前标签页。若浏览器安全策略阻止,则将页面替换为about:blank。该操作仅作用于当前标签页。
安装与启用¶
安装前请确保已安装 pnpm。
- 克隆仓库到本地。
- 进入仓库根目录。
- 执行安装命令。
dsh plugin --profile web add link:.
注意事项:
* 仓库根目录本身就是插件包,路径不要带子目录(如 link:.\dsh-web-close),否则会被当作普通依赖而非插件。
* 安装后必须重启 dsh web 才能生效。
使用方法¶
- 移动位置:按住按钮拖动,位移超过 4px 才会触发拖动逻辑。
- 恢复默认:如果位置记忆失效或需要重置,在浏览器控制台执行以下命令:
localStorage.removeItem('dsh-web-close-pos')
刷新页面后按钮将回到默认位置。
- 执行关闭:点击按钮 → 在弹窗中确认 → 等待约 0.9 秒 → DSH 进程退出并尝试关闭当前标签页。
技术实现与路由¶
插件运行在 DSH 宿主进程内部(即承载 Web 服务与 Agent 的 node 进程)。它通过以下机制实现优雅关闭:
- 调用
ctx.get('appExit')(0),触发 DSH 启动器的退出逻辑,先 dispose 插件树再退出。 - 触发
process.emit('SIGINT'),命中 DSH 注册的信号处理,执行相同流程。 - 兜底机制调用
process.exit(0)。
插件在 Web 服务器上注册了三个同源路由:
| 路由 | 方法 | 说明 |
|---|---|---|
/dsh-web-close/info.json |
GET | 返回当前进程信息(PID、地址等)。 |
/dsh-web-close/widget.js |
GET | 浏览器端脚本,每次请求从磁盘读取。 |
/dsh-web-close/shutdown |
POST | 接收关闭请求,延迟 0.9 秒后触发关闭逻辑。 |
验证安装¶
可以通过以下命令验证插件是否正确安装并运行。
- 检查配置:
dsh --profile web --dump-config
输出中应包含 `- id: dsh-web-close`。
- 检查服务(默认端口 3080):
curl http://127.0.0.1:3080/dsh-web-close/info.json
返回包含 `"ok":true` 的 JSON。
注意事项¶
- Profile 限制:仅对 web profile 有效,依赖 DSH Web 服务器运行。
- 浏览器安全策略:出于安全限制,脚本通常只能关闭由脚本自身打开的窗口。如果浏览器拒绝自动关闭当前标签页,弹窗中会出现“关闭本页”按钮作为兜底。
- 存储限制:在无痕/隐私模式下,
localStorage不可用,位置记忆仅在当前会话有效。 - 代码热更新:修改
lib/widget.js只需刷新页面;修改lib/index.js需要重启dsh web。