# dsh-update-detector

- id: dsh-update-detector
- version: 0.1.3
- developer: DeepSeek Harness
- packageName: dsh-update-detector
- loaderId: dsh-update-detector
- sha256: 85b53fe040df6616ce744445f1cfd7e794311650b1368275ca97978bff412434
- byteSize: 57409
- publishedAt: 2026-08-23T15:09:32.764Z
- updatedAt: 2026-09-21T17:16:40.762Z
- releasedAt: 2026-09-21T17:16:40.762Z
- html: https://addon.dshdo.com/plugins/dsh-update-detector
- json: https://addon.dshdo.com/v1/plugins/dsh-update-detector
- markdown: https://addon.dshdo.com/plugins/dsh-update-detector.md
- tarball: https://addon.dshdo.com/v1/plugins/dsh-update-detector/versions/0.1.3/tarball

## Install

```
curl -fsSL https://addon.dshdo.com/install-plugin-market.sh | sh
# then install catalog id dsh-update-detector in /plugin-market/ and enable it
```

## Description

检测上游 harness 更新，并驱动 update-status.json 状态机。

## Changelog

(none)

## Versions

- 0.1.3 (2026-09-21T17:16:40.762Z)
- 0.1.2 (2026-09-08T09:50:27.484Z): 0.1.2 安全改造：只读检测 + 手动检查。移除自动更新执行链；update/restart/apply/kill 端点明确 not-supported；配置统一分层校验（fail-visible）；检查间隔上限 1..35791 分钟；分支目标按祖先关系判定；非构造型 apply 使返回的清理函数被 Cordis 收集，fiber.dispose 统一反注册页面路由与 RPC。
- 0.1.1 (2026-08-23T15:09:32.764Z): Catalog distribution of the update detector with vendored lib and executor.

## README

# dsh-update-detector

English | [中文](README.zh.md)

Detects Harness updates and serves `/dsh-update/` on the existing Web server. Version 0.1.2 is detect-only: it does not install updates or restart Harness.

## Behavior

A valid configuration schedules a startup check after two seconds and subsequent checks at `checkIntervalMinutes`. Opening the page reads status; its manual-check button requests a coalesced check. A check fetches from `origin` and compares commit ancestry. Fetch updates Git metadata, but the plugin never pulls, checks out, resets, stashes, installs, builds, or restarts Harness.

The default `stable` target accepts only `vX.Y.Z` and `dsh-vX.Y.Z` tags, without leading-zero components or prerelease suffixes. Annotated tags use their peeled commit. A checkout containing the release is not behind; a divergent history or an upstream with no stable tags is reported as unavailable. Branch tracking requires an explicit `ref`, such as `origin/master`.

Tracked changes and ordinary untracked files count as repository dirt. Existing executor states (`busy`, `preparing`, `ready`, `restarting`, `running`) remain read-only and block checks. The archived executor is an inert refusal stub with exit code 3; its LaunchAgent template must not be installed.

## Configuration

Configuration is resolved once per plugin application: defaults, then Cordis `Config`, then `$DSH_HOME/update-config.json`. Unknown keys are ignored. Invalid values, malformed files, and unreadable configuration produce visible problems and disable checks. An explicitly invalid checkout path never selects a different repository. Reapply the plugin or restart the service after changing configuration.

| Key | Accepted Value | Default |
| --- | --- | --- |
| `checkIntervalMinutes` | Number from 1 to 35791 | `360` |
| `maxOutputBytes` | Integer from 1 to 16777216, per command stream | `1048576` |
| `graceMs` | Integer from 1 to 60000, termination grace in milliseconds | `1000` |
| `harnessPath` | Existing local Harness checkout | Local checkout discovery |
| `target` | `stable` or `branch` | `stable` |
| `ref` | Explicit Git ref for branch tracking; cannot start with `-` | Unset |
| `notify` | Boolean, reserved; notifications are not implemented | `true` |

The plugin requires `webServer`, `connection`, and `subprocess`. Commands use the injected managed subprocess service and its scrubbed environment. Fetch and remote-tag queries have 60-second deadlines; local probes have five-second deadlines. Output truncation fails the command instead of comparing a retained tail. Runner status codes are `-1` for execution failure, `-2` for cancellation or timeout, and `-3` for output overflow.

Disposal stops scheduling, deregisters page and RPC handlers, cancels active commands, and waits for process-tree exit and asynchronous deregistration. Concurrent disposers await the same completion. Cancelled checks cannot write durable status after teardown.

## HTTP and RPC

The page supports GET and HEAD at `/dsh-update`, `/dsh-update/`, and `/dsh-update/index.html`. Connection registers the loopback-only `/dsh-update` RPC channel with its trusted-Host and cross-origin checks.

| Endpoint | Behavior |
| --- | --- |
| `status` | Durable status plus a read-only Git dirt probe; invalid configuration skips the probe |
| `readiness` | Configuration, problems, and capabilities without running Git |
| `check` | Coalesced fetch and comparison; invalid configuration, missing checkout, and legacy busy state are refused |
| `update`, `restart`, `apply`, `kill` | Explicit not-supported errors |

RPC requests POST to `/dsh-update/<endpoint>` with JSON `{ "type": "client-request", "rpcId": "request-id", "method": "<endpoint>", "payload": {} }`. Responses use `{ "type": "server-response", "rpcId": "request-id", "result": ... }`. Status persists in `$DSH_HOME/update-status.json`; existing status fields and unknown legacy fields are preserved.

## Development

Run `node --test 'tests/*.test.mjs'`. Tests use temporary homes, fake Git responses, and explicit runner injection. They cover ancestry decisions, configuration rejection, durable state, output bounds, independently gated process-tree exit, repeated disposal, and page/RPC registration. Tests do not fetch the real Harness repository or write its user profile.

## Known Limitations and Deferred Work

The plugin assumes a local checkout and matching host subprocess provider, with `/usr/bin/git` as its default executable. It does not provide an update executor, notifications, or rollback of Harness itself. Replacing plugin files does not prove that the running Node process loaded them; service activation requires a verified reload or restart.

## Model Experience

None, as this plugin contributes no model prompt, tool schema, or model-visible messages.

#### KV Cache effect

The plugin does not alter model requests or their reusable prefixes.

