{"_id":"@caizhiyuan/dsh-tool-monitor","_rev":"6-f245127d111870b143b5762ec1734187","name":"@caizhiyuan/dsh-tool-monitor","dist-tags":{"latest":"0.5.1"},"versions":{"0.1.0":{"name":"@caizhiyuan/dsh-tool-monitor","version":"0.1.0","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"license":"MIT","_id":"@caizhiyuan/dsh-tool-monitor@0.1.0","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"dist":{"shasum":"bb8d70ed47926311fcb24ad3ad9613ba5565f385","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.1.0.tgz","fileCount":5,"integrity":"sha512-RMwyyKIk1pOjqjWiFjJuTvyDj0ClWzp36vWvFIVdri+h7SR4KqHrn1se8D/Ip/A1jJgYGDniEHLsqr0ij7laXg==","signatures":[{"sig":"MEYCIQDwKoVAsRjNmP6Z3/VcBLxJka7U8P6USPN8cuHuUrQaCgIhAL3UoaVpJsfSMM7ZdGleUBszasdDqMuge4SIGZ81IHUe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57486},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"2732e9244511560f2b131e2ff35eecf7bff7d801","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tool-monitor_0.1.0_1787899246857_0.17013071104834232","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@caizhiyuan/dsh-tool-monitor","version":"0.2.0","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"license":"MIT","_id":"@caizhiyuan/dsh-tool-monitor@0.2.0","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"dist":{"shasum":"48661c75c2b139beb97c9c7beb3d532f5b495ad8","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.2.0.tgz","fileCount":5,"integrity":"sha512-ltOAfugCnGj8EnAYnqBhcFOz3gkguDq271POf4e2Qtb5hIS2Jrhb1BewtSSIarUqcKW7vG8p04cmPEIrWZxBWg==","signatures":[{"sig":"MEUCIB3jLpKUaotoy6MCKjBrS9nbIIG7sPm9+wDjBUlyuvsFAiEAu/nzSVJFAebdd04JwRryupohB/ax3oL5jNBfPTh4+8c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":62504},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"d98fd6f9f66f5041779a9c01c83af25c8143b9cb","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tool-monitor_0.2.0_1788320189009_0.9069780877911076","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@caizhiyuan/dsh-tool-monitor","version":"0.2.1","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"license":"MIT","_id":"@caizhiyuan/dsh-tool-monitor@0.2.1","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"dist":{"shasum":"cbf8233f8532ba825b2c0b3f3b76f1e84b539931","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.2.1.tgz","fileCount":5,"integrity":"sha512-tNq0GRCHiUkjdza3Vhk39YWQCn535yXQeSP7bdMBDiQXzlnic5fvahkyum2Vvt62o60U84PnJukila1wN+9r5Q==","signatures":[{"sig":"MEQCIFxE6Bhy7EIlgVPBxNinDtKQH2iy9sg8aryLnFJajRWRAiAm0iw8W/OB6sp+S9yDcKR051P2KQJtZ3Mp7s+8jLsFmw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":67739},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"358f93f1d3a16571f076b6f9d1820195758824b4","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tool-monitor_0.2.1_1788924746143_0.3330416046224782","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@caizhiyuan/dsh-tool-monitor","version":"0.3.0","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"license":"MIT","_id":"@caizhiyuan/dsh-tool-monitor@0.3.0","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dsh":{"client":{"inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"dist":{"shasum":"1486b8d9cbfe1043fe581d9dcc4818e4a2bb276a","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.3.0.tgz","fileCount":5,"integrity":"sha512-3VCzWunSJM0YwstiFkdWi+Ae0drc7/Y14+uM50c3hrzZd0ESXdOLlpcCrBgq91bTJlTS7/HR5VHeu5+awZNyzQ==","signatures":[{"sig":"MEUCIQDTlmMGqJL7997U16ozCJLTkN7BsSh/gC8sFBhywiwx/QIgPSTKFcDibfO6BtA2d6U/w3s/iQXPPpfOA38Q53fjqUI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70208},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json"},"gitHead":"f360c8509e5b3550e224d89816a6fcb9766c0ba7","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tool-monitor_0.3.0_1789525413761_0.4109378685787166","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@caizhiyuan/dsh-tool-monitor","version":"0.5.0","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"license":"MIT","_id":"@caizhiyuan/dsh-tool-monitor@0.5.0","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"dist":{"shasum":"5fddcdebb01358b3ce2fa351535824f761e7ca06","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.5.0.tgz","fileCount":6,"integrity":"sha512-rnuCogoWxuSORz4dVFjIoOw8aEDFtF6Eca7LByj50swsGcxDhlivPw/6RaqPQrm1Y9T4JaEIgsrk64RyaPGB4Q==","signatures":[{"sig":"MEYCIQCbSuGvj+Exf/FSoMKXdV+09kJmXPOw8IF1JJrpkmbHKQIhAM4kFIIHM7HGoel9gWenMomxoK/JDDMJ+eXuqXDICqbt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCyDK6IlnX3mlcbjNc7Z9MsVTWKvNIA7N6DJxuJXc1jCgIgNqsNagQn0xyE+P1i2+P1O1J7K9RqsrtUpIG+9XlTUpQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":82618},"main":"lib/index.js","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"00596a286a48ecd822e202f86f58a0b5bfc125f4","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.22.0+sha512.1ff870c4c6133dfd88fb2afc46dd13d47f09c9794b438c6fdb47ca98caf3bc16381ee0be93a091b8e3824cf01f889f46d7d9e20910fb0be1ab0fb5baa80dd621","peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"tmp":"tmp/dsh-tool-monitor_0.5.0_1791425114022_0.2349300834277881","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"_id":"@caizhiyuan/dsh-tool-monitor@0.5.1","dsh":{"bundle":{"patch":"./cordis.patch.yml"},"client":{"inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"],"external":["react","@deepseek-ai/cordis"],"platform":"web"}},"bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"dist":{"shasum":"683ba3c3965c6c0214825874b6079182f2f7023d","tarball":"https://registry.npmjs.org/@caizhiyuan/dsh-tool-monitor/-/dsh-tool-monitor-0.5.1.tgz","fileCount":6,"integrity":"sha512-TolaNCzicryXbH6D2rmWM5DyoEe+erowNW2yeQCUTfCkAHlhYPgeLpd17pEI2YFK898izPVT07RR1DVdmEDglg==","signatures":[{"sig":"MEUCIQD9JyDkSTgdMpiF8K0VyqZKv25+h2WXQkVbf7JK9xal7QIgaS2RDRkzixdnEN7Zppel2vGjPZlnzz1QYPn+62mBXUE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDXXXhnl1DXVapacVMwfOaa046bkMnB4CKvdnYqzlG6oAiEA/8ospUHZpmE1CsF87i80BtfFSKnVoSmumyARaX2Yfdc="}],"unpackedSize":82657},"main":"lib/index.js","name":"@caizhiyuan/dsh-tool-monitor","type":"module","exports":{".":"./lib/index.js","./client":"./lib/client.js","./package.json":"./package.json","./cordis.patch.yml":"./cordis.patch.yml"},"gitHead":"dfbc2bd4bbad46d2297fbb8b2767298e0ad4df65","license":"MIT","version":"0.5.1","_npmUser":{"name":"caizhiyuan","email":"substitute826@gmail.com"},"homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"_npmVersion":"10.9.2","description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","directories":{},"maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"_nodeVersion":"22.14.0","dependencies":{"ws":"*"},"_hasShrinkwrap":false,"packageManager":"pnpm@11.22.0+sha512.1ff870c4c6133dfd88fb2afc46dd13d47f09c9794b438c6fdb47ca98caf3bc16381ee0be93a091b8e3824cf01f889f46d7d9e20910fb0be1ab0fb5baa80dd621","peerDependencies":{"@deepseek-ai/cordis":"*","@deepseek-ai/dsh-llm":"*","@deepseek-ai/dsh-tools":"*","@deepseek-ai/schemastery":"*"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dsh-tool-monitor_0.5.1_1791425602976_0.09666489889674357"}}},"time":{"created":"2026-08-28T06:40:46.691Z","modified":"2026-10-08T02:13:23.240Z","0.1.0":"2026-08-28T06:40:46.996Z","0.2.0":"2026-09-02T03:36:29.137Z","0.2.1":"2026-09-09T03:32:26.320Z","0.3.0":"2026-09-16T02:23:33.961Z","0.5.0":"2026-10-08T02:05:14.106Z","0.5.1":"2026-10-08T02:13:23.060Z"},"bugs":{"url":"https://github.com/substitute525/dsh-tool-monitor/issues"},"license":"MIT","homepage":"https://github.com/substitute525/dsh-tool-monitor#readme","keywords":["dsh","dsh-plugin","deepseek-harness","monitor","background","websocket"],"repository":{"url":"git+https://github.com/substitute525/dsh-tool-monitor.git","type":"git"},"description":"DeepSeek Harness plugin: background file/command/WebSocket monitors that wake the owning session on new output and show a live monitor list in the Web session header over a dedicated WebSocket. Host core + Web client half, no build step.","maintainers":[{"name":"caizhiyuan","email":"substitute826@gmail.com"}],"readme":"# dsh-tool-monitor\r\n\r\n> 一个 **dsh-plugin**：后台监听**文件**、**命令输出**或**WebSocket**，输出到达时唤醒所属会话，并在 Web 会话头部提供实时监听的列表与输出查看面板。MIT License。\r\n\r\n## 功能\r\n\r\n- **后台监听**：`monitor_start` 对 `file`、`command` 或 `ws` 发起后台监听，返回 `monitor_id` 后立即继续。\r\n- **触发唤醒**：默认在监听到**任意新输出**时唤醒；可用 `pattern`（JS 正则）限定只对匹配输出触发。\r\n- **WebSocket (`ws`) 模式**：\r\n  - text frame → 一个**事件**，整体呈现文本；多行 frame 保持为一个整体事件，不会被拆散。\r\n  - binary frame → 只报 `[binary frame, N bytes]`，内容不解析透传。\r\n  - socket 关闭 → 结束监控，并展示 close code（正常关闭 `1000/1001` → `completed`；异常如 `1006/1011` → `failed`），方便判断正常还是异常。\r\n  - 错误/异常 → 在关闭之前先浮出（不受 `pattern` 过滤），让你看到失败原因。\r\n  - 可通过 `protocols` 提供子协议数组，按 WebSocket 规范（RFC 6455）协商子协议。\r\n- **模型可见的四个工具**（宿主层注册，所有 preset 的所有会话可用）：\r\n  - `monitor_start` — 启动监听。参数：`source`(file|command|ws)、`path`/`command`/`url`、`protocols`(ws 子协议数组，可选)、`duration_seconds`(0=持续到会话/插件停止)、`interval_ms`(默认3000，对 ws 无意义/忽略)、`pattern`(正则，仅匹配触发)、`initial_snapshot`(file 现有内容作为首批)、`one_shot`(首次触发后自动停止)、`max_chars`(缓冲尾保留，默认4000)\r\n  - `monitor_read(id)` — 增量读取（消费游标，同 `job_output`）\r\n  - `monitor_stop(id)` — 停止（command 会杀后台进程）\r\n  - `monitor_list()` — 本会话可见的监听器\r\n- **Web 会话头部**：提供「N 个监听器」控件，点开列出每个监听（状态点 / 时长 / 详情 / 停止钮），点某行按需展示保留输出。\r\n\r\n## 机制\r\n\r\n- **宿主自注册表**：monitor 存于插件自己的 `Map`（id 形如 `monitor-N`），状态词 `running / stopped / completed / failed`，**不写入 `ctx.jobs`**，因此不会出现在框架的「后台任务」列表里。file/command 走轮询 tick；`ws` 为事件驱动，连接一个出站 `WebSocket`（`ws` 包的客户端），text/binary/error/close 各自映射为通知与终态。\r\n- **自有 WebSocket 推送**：宿主用公开缝 `ctx.get('webServer').registerUpgrade({ path: '/tool-monitor/ws' })` 注册专属 WS 端点，再用 `ws` 包的 `WebSocketServer.handleUpgrade` 握手。每次注册表变化（启动 / 停止 / 结束 / 移除）就给该会话的连接推一份 `{ type:'snapshot', monitors:[...] }`；新连接建立先发一次 baseline；**loopback 校验**拒绝非本地来源；插件卸载时注销路由。\r\n- **客户端**：2s 轮询宿主 `/tool-monitor/list`（优先走 harness 的 `connection.rpc`，取不到该服务时回退为同源 `fetch` 打同一路由，认证随连接走）；**不用自有 WebSocket** —— 桌面版 UI 跑在 `dsh-app:` scheme 下，它不是 ws scheme（`new WebSocket(\"dsh-app://…\")` 会抛错），而启动参数里的 `--fetch-schemes=dsh-app` 允许 fetch。头部按钮复用框架的 `StateDot` + `IconChevronDownOutlineRegular`，**图标按名字在运行时探测、取不到就跳过该图标**（曾因写了并不存在的 `IconChevronDownOutline14`，`React.createElement(undefined)` 在渲染期抛 \"Element type is invalid\"，导致整个 slot 条目被 `abdicate` —— 永久退出投影，控件再也不显示），与「后台任务」等控件视觉一致。\r\n- **输出按需读取**：模型端走 `monitor_read`（增量、消费游标）；Web 端点开行时经 `/tool-monitor` RPC `read`（保留窗口、非消费）。**输出不随推送下传**。\r\n- **唤醒（无次数上限）**：构造 `UserMessage`（source `{kind:'plugin:tool-monitor', form:'notice', summary}`）。owner **空闲** → 立即 `owner.followup(msg)` 唤醒；owner **忙** → 通知存入插件自有队列（`pending`，**不**进 agent inbox），待该 owner 转为 `idle`（监听 `agent/status`）时把队列**按 monitor 分组、合并成一条** `followup` 发出。因此忙时不会被反复打断，也不会因中断/取消丢消息；**没有唤醒预算**，不会出现\"跑几次后不再唤醒\"。`agent/disposed` 或插件卸载会停止其所有监听。\r\n\r\n## 安装\r\n\r\n本包声明了 `dsh.bundle.patch`（`./cordis.patch.yml`），因此它是**完整的组合包（bundle）**：装进 profile 后会自动成为一层 profile layer 并插入自己，不需要再手工改 profile 的 `cordis.patch.yml`。\r\n\r\n```bash\r\n# 1) 从 npm 安装\r\ndsh plugin --profile web add @caizhiyuan/dsh-tool-monitor\r\n\r\n# 1b) 或从源码安装（开发用；link 后改源码即生效，宿主改动仍需重启）\r\ndsh plugin --profile web add link:W:/图南/dsh-tool-monitor\r\n\r\n# 2) 重启 dsh（宿主模块 + 新 client bundle 生效；client 部分刷新页面加载）\r\n```\r\n\r\n`dsh plugin add` 会把包名追加进 `profiles\\web\\package.json` 的 `dsh.profile.bundles`，并校验 `dsh.bundle.patch` 指向的 patch 文件可解析；GUI 里的插件管理器走同一条路径（`installBundle`）。\r\n\r\n> 若包只声明 `dsh.client` 而没有 `dsh.bundle`，安装会被拒（`declares no dsh.bundle`），因为 profile 的 layer 栈只接受声明了 `dsh.bundle.patch` 的组合包。\r\n>\r\n> 前提：dsh profile 需已组合 `webServer`（Web 版默认有）；headless 无 `webServer` 时插件仍可用（模型工具正常），只是没有 WS 推送。\r\n\r\n## 结构\r\n\r\n- `lib/index.js` — Host 插件：`{name:'tool-monitor', inject:[...], Config(zod), apply}`；自注册表、每 tick 轮询（file/command）、出站 `ws` 客户端（source=ws）、忙时排队 + 空闲合并投递、`agent/disposed` 清理、`/tool-monitor/ws` 端点、`/tool-monitor` RPC（read/stop，直接注册在 webServer 前缀路由上，绕开 `connection.rpc.handle` 在 cordis>=4 的 inject 限制）。\r\n- `lib/client.js` — Web 客户端半部（`window.__ModuleLoader__` 格式）：会话头部注册 `monitor-list`（order 30），连自有 WS 收 snapshot，点开查看/停止。\r\n- `cordis.patch.yml` — 组合包 patch：`dsh.bundle.patch` 指向它，内容为把本包 insert 进 profile layer 栈。\r\n- 无构建步骤（`\"type\":\"module\"`，纯 ESM / 模块加载器格式）。\r\n\r\n## 开源协议\r\n\r\n[MIT](LICENSE)\r\n","readmeFilename":"README.md"}