dsh-agent-processes
Verifieddsh-agent-processes Β· v1.0.2 Β· MIT Β· Web UI
Host-owned process & port lifecycle for DeepSeek Harness local agents (start/stop/list/logs/wait-ready + dock chip + Processes rightbar).
Install
dsh plugin add dsh-agent-processes Confirm the layer applied with dsh --profile default --dump-config β see the install guide.
Source
Tags
Creators
Readme
dsh-agent-processes
Host-owned process & port lifecycle for local coding agents in the DeepSeek Harness web UI.
Long-lived local processes started through raw bash become zombies: the agent
forgets the PID, the port stays held, the next start hits EADDRINUSE, and the
agent rewrites code around a bug that was really a port. This plugin gives the
agent first-class hands β start / stop / list / logs / wait-ready with a
persistent vault β plus a Processes rightbar and composer dock chip for the
human.
Related plugins (same dual-face dsh.bundle shape for the web rightbar / dock):
| Plugin | Repo |
|---|---|
| Long-horizon task status | dsh-local-long-horizon |
| NVIDIA GPU util / VRAM / power | dsh-gpu-monitor-nvml |
| Local LLM endpoint / slot health | dsh-slot-health |
This package: dsh-agent-processes.
Verified against DeepSeek Harness 0.1.7-rc.2 (dsh web).
Requirements
- DeepSeek Harness web profile (
dsh web). - Node.js β₯ 20 to build.
Screenshots
Light theme, matching the DSH default.
| Pane + chat (mid-run) | Processes pane (fullscreen) |
|---|---|
![]() |
![]() |
| Dock chip (rightbar closed, chat metrics active) |
|---|
![]() |
What you see
- Processes rightbar β follows the open chat workspace. Per-record card: status dot (green running / amber starting / red crashed / grey stopped), id + port, pid + age, command, cwd basename, log preview, and Kill / Restart / Clear.
- Dock chip β on the chat metrics strip when the rightbar is closed and
something is running for the followed workspace (
Processes Β· :3000,Processes Β· 3 running, β¦). Click opens the pane. - Tracked reclaim β starting with a
portstops any tracked holder of that port first; foreign (untracked) holders are refused, never killed.
Install
From npm (recommended)
dsh plugin --profile web add dsh-agent-processes
# restart dsh web (or rely on live patch reload), then hard-refresh the browser
From GitHub
dsh plugin --profile web add github:janpauldahlke/dsh-agent-processes
From a git checkout (developers)
git clone https://github.com/janpauldahlke/dsh-agent-processes.git
cd dsh-agent-processes
npm install && npm run build
dsh plugin --profile web add "$(pwd)"
Restart (or boot) dsh web so the host + client faces load:
env -u DSH_WEB_URL -u DSH_SHELL -u DSH_SESSION_ID dsh web --no-open
Uninstall:
dsh plugin --profile web remove dsh-agent-processes
# restart the web instance that had the plugin
No harness file: dependencies β the host registers tools on the live
ctx.tools service provided by dsh. Rebuild lib/ after edits; client changes
hot-load, host changes need a web-shell restart.
Agent tools
| Tool | Purpose |
|---|---|
process_start |
Spawn + track; optional port wait / reclaim |
process_stop |
SIGTERM β 3s grace β SIGKILL (process group) |
process_list |
All tracked records (liveness re-checked) |
process_logs |
Tail a record's captured log |
process_wait_ready |
Poll until 127.0.0.1:port accepts (or timeout) |
process_ping |
Plugin liveness probe |
process_start with port:
- Reclaim β stop every tracked, live holder of that port; report ids in
reclaimed[]. - Foreign check β if the port still accepts connections, refuse with a typed error (no kill).
- Readiness β TCP connect to
127.0.0.1:P(default timeout 15s). Timeout is a success-shaped result witherror: 'port-timeout'; the process is left running.
Records store lossless argv so UI / route restart re-runs the same command
under the same id.
Surfaces
| Surface | Path / name |
|---|---|
| Vault | ~/.dsh/storages/dsh-agent-processes/processes.json |
| Logs | ~/.dsh/storages/dsh-agent-processes/logs/<id>.log |
| HTTP | GET / POST /api/dsh-agent-processes |
| UI | Rightbar Processes + composer dock chip |
GET /api/dsh-agent-processes
β { ok, package, version, storageRoot, count, processes: [β¦] }
POST /api/dsh-agent-processes { "action": "stop" | "restart" | "remove", "id": "β¦" }
The pane polls every 2s (refcounted β stops when the last viewer unmounts).
Recommended AGENTS.md snippet
## Long-lived processes β use dsh-agent-processes
For anything that stays up (dev servers, watchers, long `node` servers):
- Start with `process_start` (include `port` if it listens). It reclaims tracked
holders of that port, refuses foreign ones, and waits for TCP readiness β
do **not** start long-lived processes with raw `bash` or backgrounded `&`.
- Before assuming a port is free, check `process_list`; after starting, use
`process_wait_ready` instead of `sleep`.
- Stop with `process_stop`. Read `process_logs` when something looks wrong.
- On crash or port failure: read `process_logs`, fix, `process_start` again,
verify with `process_wait_ready`.
- Never kill untracked PIDs; if a foreign process holds the port, free it
manually or start on another port.
Architecture
Dual-face package (same bar as the other web rightbar / dock plugins):
- Host (
lib/index.js, ESM) β vault, tools, HTTP route. - Client (
lib/client.js, CJS ModuleLoader factory) β rightbar + dock chip. - Glue β
cordis.patch.yml+dsh.bundle/dsh.clientinpackage.json.
dsh-agent-processes/
βββ package.json
βββ build.mjs
βββ cordis.patch.yml
βββ media/ # README screenshots
βββ scripts/ # shippable lifecycle smoke
βββ test/ # node --test (vault + service)
βββ src/host/ # vault, service, tools, route
βββ src/client/ # pane + dock chip
βββ src/shared/ # shared types
βββ lib/ # built artifacts (required at runtime)
Develop / test
npm test # node --test (vault + service; real child processes)
npm run smoke # shippable lifecycle smoke (start β ready β reclaim β foreign refuse)
Limitations
- Tracked-only kill scope β never signals a PID it does not track; foreign port holders are refused, not killed.
- Crash detection is by liveness probe (sampler + on-request recheck), not by signal watching.
- No log rotation β logs are append-only.
- No per-session isolation β vault is per web profile; UI scoping is by cwd.
- Stretch (not in v0): read-only top-N system process card.
Contributing
See CONTRIBUTING.md for setup, layout, and PR expectations.
License
MIT β see LICENSE.


