dsh-plugin-process-guard
本机进程面板:把 agent 启动后一直没有关掉的 Playwright 浏览器和开发服务器(dev server)列出来,按项目归类,并提供释放按钮。
安装
需要先有 DeepSeek Harness(DSH),目前只支持 macOS。
在 DSH 的插件安装界面里填这份仓库的地址:
github:tf961656585/dsh-plugin-process-guard
也可以填这份仓库在本机的绝对路径。装完重启 DSH,左侧栏就会出现「本机进程」。
为什么需要
agent 用 Bash 起 npm run dev、vite、playwright 这类长驻进程时,工具调用一结束(或被中断、超时、切走),子进程通常不会跟着退出:它们会被重新挂到 launchd 下面继续占着端口和内存。表现是端口被占、下次启动报 EADDRINUSE、内存慢慢变少,但没有任何界面能看到"是谁、什么时候、为哪个项目起的"。
这个插件补上这一环:不改变 agent 的启动方式,只把已经存在的进程识别出来,让人能看见并决定什么时候释放。
用法
左侧栏的服务器图标进入「本机进程」面板。图标上的小圆点表示有需要释放的进程。
- 按项目分组,每组显示进程数;每行显示类型、命令、端口、运行时长、来源会话。
- 「详情」展开命令行、进程号、启动链路。
- 「释放」需要点两次(第二次是确认),5 秒内不点就自动取消。
- 「全部释放」只作用于 agent 启动且满足以下任一条件的进程:启动它的命令已经脱离 DSH,或已经运行超过 30 分钟。不会碰你自己从终端起的进程。
- 页面每 12 秒自动刷新;点端口号会打开
http://localhost:<port>。
怎么判断
三类证据,从强到弱:
- 进程环境里还有
DSH_SESSION_ID。子进程继承环境变量,即使脱离、被重新挂到 1 号进程也还在。这是最可靠的归属证据,能直接对上是哪个会话。 - 进程树还能连到当前 DSH 进程。说明启动它的那条命令还在跑(比如后台任务)。
- 进程树连到终端或编辑器(Terminal、iTerm、VS Code、Cursor、Warp 等),或环境里有
TERM_PROGRAM,判为「你启动的」。
三条都不成立时显示「来源不明」,不瞎猜。其他 AI 工具(ZCode、Claude Code、Cursor)留下的环境标记会被识别为「其他 agent 启动」,但不会冒充 DSH。
项目归属:优先用启动会话的工作目录,其次用进程的 cwd(lsof -d cwd),再向上找到最近的 .git / package.json 等标记作为项目根。Playwright 浏览器的 cwd 常常是 /tmp,所以会话工作目录优先。
进程类型:
- Playwright:可执行文件位于
~/Library/Playwright或ms-playwright池,且是主进程(不带--type=)。同一浏览器的 GPU / renderer 子进程归到一组。 - 开发服务器:命令是 vite / next dev / nuxt / astro / webpack serve / react-scripts start / uvicorn /
python -m http.server/ wrangler dev 等常见启动器。node .../node_modules/.bin/vite会被简化显示成vite。 - 应用包(
.app/Contents/)里的进程、DSH 自己及其祖先、别的用户的进程一律不列、不可杀。
释放做了什么
- 释放前重新扫描一次,只对当前快照里仍存在的 pid 动手,避免 pid 被复用后杀错。
- 先对整组进程(启动器 + 服务 + 全部子进程)发
SIGTERM,1.5 秒后仍在的补SIGKILL。 - 永远跳过 DSH 自身、它的祖先、pid 1、其他用户的进程。
- 返回每一组的结果:杀了哪些 pid、还剩几个没退出。
给 agent 的工具
插件注册了 process_manager 工具,能力与面板完全一致:
action=list:列出进程、项目、会话和状态。action=release:传ids(来自 list)或all=true(释放所有需要释放的 agent 进程)。
系统提示里加了一段提醒:收尾前检查并释放这次启动、不再需要的 dev server / Playwright。面板和工具走同一套 Host 方法,不存在两套逻辑。
限制
- 只支持 macOS 本机:依赖
ps、lsof和ps eww读进程环境。 - 进程识别基于命令特征;自定义启动脚本(比如
node server.js且没有经过 npm/vite 这类包装)不会出现在列表里。 - 会话标题来自 DSH 的会话投影缓存;会话已被清理时只显示会话 id。
- 插件不自动杀进程:只在用户点「释放」或 agent 调
release时动手。
结构
host.js Host:扫描缓存、三条 HTTP 路由、process_manager 工具、系统提示
scan.js 进程扫描、归属判定、项目解析、释放
client.js 侧栏图标 + 管理面板
locale/*.json meta.title / meta.description(插件列表用)
test/scan.test.mjs 解析与分类的单元测试
协议
MIT,见 LICENSE。
No comments yet. Be the first to write one.