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/.ps1shim aware) and probes<harness> --versionwith 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 → latestand 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, orfailed.
| 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=1in 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 |
No comments yet. Be the first to write one.