dsh-harness-updater
English | 简体中文
Agent harness updates for DeepSeek Harness. Detects the locally installed
Claude Code and
Codex CLI, compares them against the
latest published versions, prompts in the DSH web UI, and — on your explicit
click — runs the correct channel-specific upgrade command.
Inspired by the provider maintenance model of T3 Code.
What it does
- Detects each harness on
PATH (Windows .cmd/.ps1 shim aware) and probes
<harness> --version with a bounded timeout.
- Classifies the install channel from the resolved binary path:
native installer, npm / pnpm / bun global, Homebrew, or manual-only.
- Checks npm (
registry.npmjs.org/<pkg>/latest) for the latest version with a
4 s timeout and a 1 h cache. Fully disabled via settings when offline.
- Prompts: a persistent Updates card in DSH Settings → Plugins lists each
harness with
current → latest and an in-place Update button. Under DSH
Native it also shows the native app's own self-update status.
- Updates on click only — never silently. The runner serializes per channel lock,
enforces a hard timeout with process-tree termination, caps captured output, then
re-probes to verify and reports
succeeded, unchanged, or failed.
| Detected channel | Update command |
|---|
| Claude native (~/.local/bin/claude*) | claude update |
| npm global | npm install -g <pkg>@latest |
| pnpm global | pnpm add -g <pkg>@latest |
| bun global | bun install -g <pkg>@latest |
| Homebrew | brew upgrade claude-code / brew upgrade --cask codex |
| anything else (WinGet, standalone installers) | manual: copyable hint, no one-click |
The updater invokes npm with explicit arguments and lets npm run the package
lifecycle required to install the CLI.
Safety model
- Every route is loopback + same-origin gated; updates are POST-only mutations.
- One update per harness at a time; updates sharing a package manager queue behind
a shared lock instead of racing.
DISABLE_UPDATES=1 in the Harness environment blocks all automatic paths.
- Child processes are killed as a tree on timeout (Unix signals / taskkill /t /f).
- Updates are never started without a user click; nothing runs on a timer.
Install (local development)
Reference the plugin from your DSH profile:
// ~/.dsh/profiles/web/package.json
"dependencies": { "dsh-harness-updater": "link:C:/path/to/dsh-harness-updater" }
Add the bundled patch entry (the repo's cordis.patch.yml inserts it), run
pnpm install in the profile, then restart DSH Web (host half).
Development
pnpm install
pnpm check # typecheck + build + test
Configuration
All fields are editable in DSH Settings → Plugins → Harness updater (restart applies):
| Field | Default | Meaning |
|---|
| enableUpdateChecks | true | Query npm for latest versions |
| statusRefreshIntervalMs | 900000 | Background status poll interval (min 60000) |
| hoverRefreshMinAgeMs | 30000 | Min age before a forced refresh is allowed (min 5000) |
| probeTimeoutMs | 5000 | Timeout for each --version probe (min 1000) |
| latestTimeoutMs | 4000 | Timeout for each registry lookup (min 1000) |
| latestVersionTtlMs | 3600000 | Registry result cache lifetime (min 30000) |
| updateTimeoutMs | 300000 | Hard timeout for an update command (min 30000) |
| claudeCommand / codexCommand / npmCommand | claude/codex/npm | Executables to use |
License
MIT