前言¶
在 DeepSeek Harness(DSH)里用智能体跑前端或脚本时,常见流程是拉起 vite、next dev、文件监听或隧道。一轮对话结束、会话关闭后,这些进程往往仍在监听 5173、3000 等端口。下一次再启动开发服务就会遇到 EADDRINUSE,只好在任务管理器或 ps 里逐个猜哪个 node 是该杀的。
单纯「按端口号杀进程」的工具只能告诉你谁在占端口,却很难判断该不该杀:会不会误杀本机 MySQL、会不会把正在跑的 Harness 自己干掉、占端口的进程是否和当前工作区有关。dsh-reaper 是 DSH 社区插件(维护者 11111353535,分类为工作流),在盘点本机监听端点的基础上,为每个占用者打上归属与风险等级,先给出计划,只有在显式确认后才发送信号回收端口。
这是什么¶
dsh-reaper 的定位是:为 DeepSeek Harness 清点监听端点,把占用者与当前会话、工作区、系统服务区分开,预览将要终止的进程树,并在用户确认后回收端口。README 中的一句话概括是:找回智能体会话留下却未归还的孤儿开发服务与监听进程。
插件通过 Cordis 向 Harness 注册工具与斜杠命令;实现为纯 ESM JavaScript(lib/),依赖 node:* 与 @deepseek-ai/dsh-tools,由宿主解析,不捆绑可能覆盖宿主版本的依赖。
核心能力¶
扫描与分级¶
只读扫描会枚举本机监听端点(默认 TCP;配置或参数可包含 UDP),并结合进程表做归属判断。每个端点会得到一个 verdict,用于决定能否纳入「安全批量回收」:
| verdict | 含义 | all: true 时是否默认选中 |
|---|---|---|
agent-spawned |
源自当前 Harness 宿主进程的子进程 | 是 |
workspace |
命令行中出现当前工作区路径 | 是 |
dev-server |
形似开发服务、监听或隧道 | 否 |
unattributed |
在监听但无法归因到本会话 | 否 |
system |
系统进程或知名服务端口(如 3306) | 否 |
protected |
命中 neverKill / protectPorts,或持有 Harness 进程树 |
否 |
两条规则保证分级可信:扫描从自身 pid 向上遍历,拒绝终止整条祖先链及 Harness 所在进程树;持有知名服务端口的进程记为 system,all: true 不会选中,备注为 left alone 而非暗示可强制覆盖。
回收与安全默认值¶
回收是破坏性操作,默认极为保守:
- 未传
confirm: true时只计算并返回计划,不向任何进程发信号。 - 计划包含完整后代闭包:杀
npm run dev包装进程而不杀子进程会留下仍占端口的进程,插件按「最深子进程优先」排序后再发信号。 - 对 Harness 进程树、pid 0–4、
neverKill匹配项、protectPorts上的占用者一律拒绝,即使用户显式传入 pid 也不可覆盖,并返回原因。 - 默认先发
SIGTERM;仅当force: true时才升级为SIGKILL,仍存活的进程会在结果中报告。 - 发信号后会重新探测端口,报告
ports confirmed free或ports still held。
扫描在 Windows、Linux、macOS 上分别使用 PowerShell/netstat 回退、ss、lsof 等最佳努力枚举;某一数据源失败会在结果末尾以 degraded: ... 说明,归因可能变弱但不会静默失败。
安装与配置¶
在 DSH 中安装(命令来自官方 README):
dsh plugin add https://github.com/11111353535/dsh-reaper
若从本地目录安装而非 Git 托管地址,使用绝对路径:
dsh plugin add /absolute/path/to/dsh-reaper
按 profile 调参时,在安装器写入的 ~/.dsh/profiles/<profile>/cordis.patch.yml 对应条目中增加 config,例如:
- insert:
- id: reaper
name: 'dsh-reaper'
config:
neverKill: ['my-precious-daemon']
protectPorts: [80, 443, 19387]
includeUdp: false
graceMs: 3000
scanTimeoutMs: 20000
| 配置项 | 默认值 | 说明 |
|---|---|---|
neverKill |
[] |
进程名或命令行子串,命中则永不发信号 |
protectPorts |
[] |
占用这些端口的进程一律拒绝;Harness 自身 Web 端口会自动加入 |
includeUdp |
false |
是否枚举 UDP;开发服务多为 TCP |
graceMs |
3000 |
SIGTERM 后等待多久再视为仍存活 |
scanTimeoutMs |
20000 |
单次系统枚举的时间上限 |
典型用法¶
斜杠命令¶
/reap # 仅盘点
/reap --all # 预览本会话可置信归因的全部端点
/reap --all --confirm # 确认后执行回收
/reap 5173 # 预览回收单个端口
/reap 5173 3001 --confirm --force
盘点输出示例(来自 README,环境为 win32)会列出监听端点数、进程数、可回收数量,并按端口展示 verdict、pid、运行时长与命令行;系统服务与受保护进程会附带说明行。
工具接口¶
reaper_scan:只读全量扫描。可选includeUdp、workspace(默认当前会话工作区)。reaper_reap:生成计划;confirm: true时执行。支持pids、ports、all(仅agent-spawned与workspace)、force、confirm(默认false)。reaper_free_port:针对单个 TCP 端口。端口已空闲则直接说明;无法归因或受保护则报告原因而不猜测。
智能体在对话中也可直接调用上述工具,行为与斜杠命令一致:先预览,再确认。
适用场景与注意¶
适合经常在 DSH 里让智能体启动/重启开发服务、又反复遇到端口占用的开发者。也适合在结束一轮长会话前,用 /reap 看清本机还有哪些监听与当前工作区或 Harness 相关,再决定是否 --all --confirm。
使用前请注意:
- 插件以当前 DSH 进程权限运行,发信号的对象是操作系统上的真实进程;安装前建议阅读 GitHub 仓库 源码与 MIT 许可证。
- 社区目录 SkillHub 插件页 与 GitHub 为独立信息源,与 DeepSeek / 幻方无官方从属关系;星标与版本以各页面当时显示为准(package.json 当前版本为 0.1.0)。
- 勿指望用端口号或 pid 绕过
protected/system保护;需要长期保留的守护进程应写入neverKill或protectPorts。
结尾¶
dsh-reaper 把「谁占着端口」和「能不能杀」拆开处理:先分级、再闭包计划、最后才在确认后回收,并验证端口是否释放。若你主要在 DSH 工作流里做本地开发,它是对付 EADDRINUSE 与孤儿 node 进程的一条可核对路径。