dsh-update-status 0.2.1 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/README.md +47 -10
- package/README.zh.md +47 -11
- package/assets/update-panel.png +0 -0
- package/assets/update-panel.zh.png +0 -0
- package/bin/dsh-update-status-service.mjs +5 -0
- package/docs/platform-acceptance.md +48 -0
- package/docs/service-supervision.md +129 -0
- package/lib/client.js +575 -37
- package/lib/client.js.map +1 -1
- package/lib/index.js +302 -9
- package/lib/service-cli.js +634 -0
- package/package.json +11 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.3.1 — 2026-10-07
|
|
6
|
+
|
|
7
|
+
Verified DeepSeek Harness: `0.2.1-alpha.1` (the current release, and the one this profile runs), also `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1` and `0.1.7-alpha.2`. Release notes: [`docs/releases/v0.3.1.md`](docs/releases/v0.3.1.md).
|
|
8
|
+
|
|
9
|
+
- **The settings page states the restart precondition.** `UpdateSettings` rendered the shared `RestartControl` but not the promise note that the panel carries, so an enabled button there had no explanation; it now reuses `panel.readOnly` under the action row.
|
|
10
|
+
- **Long work labels no longer push the confirm buttons out of the card.** A job label is an entire shell command; `.dus-restart-work li` is clamped to two lines (`-webkit-line-clamp: 2`) while keeping full text selectable in the DOM, and `tests/client/styles.spec.ts` locks the rule.
|
|
11
|
+
- **New `docs/platform-acceptance.md`**: the three-step real-machine check for Linux and Windows (plan → install → user-stops-DSH → activate), with the status commands to consult and the uninstall path. Linked from both READMEs.
|
|
12
|
+
- **Both READMEs de-AI-ified** (per the project's writing rule): the 0.3.0 compatibility description went from a ~400-character paragraph of internals to one user-facing sentence, and the supervised-restart section now reads as instructions rather than mechanism.
|
|
13
|
+
- **`docs/releases/v0.3.0.md` rewritten and the published GitHub Release body updated to match**: bilingual, one-line compatibility conclusion, three user-facing bullets, no internal identifiers or test counts.
|
|
14
|
+
|
|
15
|
+
## 0.3.0 — 2026-10-07
|
|
16
|
+
|
|
17
|
+
Verified DeepSeek Harness: `0.2.1-alpha.1` (the current release, and the one this profile runs), also `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1` and `0.1.7-alpha.2`. Full bilingual release notes: [`docs/releases/v0.3.0.md`](docs/releases/v0.3.0.md).
|
|
18
|
+
|
|
19
|
+
- **Opt-in, supervised DSH Web restart.** The update panel and settings page gain a guarded Restart control. It is disabled unless the current Host proves it is running under an explicitly installed user-level supervisor; the Host independently checks that fact, lists active agents/jobs/terminals, requires force confirmation for interruption, and exits only after its authenticated RPC response is sent. The browser waits for a different process instance ID before refreshing.
|
|
20
|
+
- **Explicit cross-platform user-service CLI.** `dsh-update-status-service` renders/stages user-level launchd, systemd-user, or Windows Task Scheduler definitions from absolute Node/DSH paths. `plan --dry-run` writes nothing; `install` preflights without starting; `activate` refuses an occupied port and never kills an existing DSH. Full setup and removal guidance lives in [`docs/service-supervision.md`](docs/service-supervision.md).
|
|
21
|
+
- **The activity gate no longer refuses on an isolate-scoped terminal registry.** On a real macOS host the first Restart click reported *active work could not be inspected* and disabled itself. `dsh-terminal` is composed **inside each agent** with `isolate: terminals`, so a root-level `ctx.get('terminals')` is `undefined` by construction — not a failed inspection. Terminals are now enumerated through each live agent's own context; a registry a Host simply does not provide means that Host owns no such work, while an unreadable or throwing one still fails closed. Five host specs cover the real-machine shape, including the live-PTY-of-an-idle-agent case.
|
|
22
|
+
- **The README illustrations show the current panel**, in the language of each README: the running `0.2.1-alpha.1` reported up to date, its last-checked time, and the new guarded **Restart** action beside Check for updates and Release notes.
|
|
23
|
+
- **The suite now runs on macOS and Windows in CI**, which required dropping POSIX path assumptions from the service-plan specs and the shadowed-peer guard's symlink privilege dependency.
|
|
24
|
+
- **Public promise updated**: from "read-only, never restarts" to "read-only plus one guarded restart after you explicitly install a user-level service".
|
|
25
|
+
|
|
5
26
|
## 0.2.1 — 2026-10-06
|
|
6
27
|
|
|
7
28
|
Verified DeepSeek Harness: `0.2.1-alpha.1` (the current release, and the one this profile runs), also `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1` and `0.1.7-alpha.2`. Full bilingual release notes: [`docs/releases/v0.2.1.md`](docs/releases/v0.2.1.md).
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<h1 align="center">DSH Update Status</h1>
|
|
2
2
|
|
|
3
|
-
<p align="center">A
|
|
3
|
+
<p align="center">A DSH Web version-status panel with copy-only upgrade guidance and opt-in, supervised safe restart.</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<a href="https://www.npmjs.com/package/dsh-update-status"><img src="https://img.shields.io/npm/v/dsh-update-status?label=npm&color=CB3837" alt="npm version"></a>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<a href="#install">Install</a> ·
|
|
16
16
|
<a href="#usage">Usage</a> ·
|
|
17
17
|
<a href="#update-check">Update check</a> ·
|
|
18
|
+
<a href="#supervised-restart">Supervised restart</a> ·
|
|
18
19
|
<a href="#lan--non-loopback-pages">LAN pages</a> ·
|
|
19
20
|
<a href="#compatibility">Compatibility</a> ·
|
|
20
21
|
<a href="#configuration">Configuration</a> ·
|
|
@@ -24,12 +25,12 @@
|
|
|
24
25
|
<a href="docs/RELEASING.md">Release guide</a>
|
|
25
26
|
</p>
|
|
26
27
|
|
|
27
|
-
> DSH Update Status is a community plugin for DeepSeek Harness. It does not modify DSH core
|
|
28
|
+
> DSH Update Status is a community plugin for DeepSeek Harness. It does not modify DSH core, install or upgrade DSH, roll back DSH packages, download releases, or replace DSH files. It can request a **safe restart only after you explicitly install a verified user-level service** to supervise the current DSH Web process.
|
|
28
29
|
|
|
29
|
-
It shadows only the expanded sidebar brand name with `DeepSeek` plus a compact version chip that fits the 24px brand row, leaving the official fish mark untouched. A green dot next to the version means the running release is the newest one npm publishes; a breathing amber dot means a newer release exists — stable, release candidate or alpha. Tap the chip for the running version, the newer release, whether this plugin was verified against it,
|
|
30
|
+
It shadows only the expanded sidebar brand name with `DeepSeek` plus a compact version chip that fits the 24px brand row, leaving the official fish mark untouched. A green dot next to the version means the running release is the newest one npm publishes; a breathing amber dot means a newer release exists — stable, release candidate or alpha. Tap the chip for the running version, the newer release, whether this plugin was verified against it, a copy-only upgrade command pinned to that exact version, and the guarded **Restart** control that appears once you have installed user-level supervision.
|
|
30
31
|
|
|
31
32
|
<p align="center">
|
|
32
|
-
<img src="./assets/update-panel.png" width="400" alt="DSH Update Status panel: cache duration, the running 0.2.
|
|
33
|
+
<img src="./assets/update-panel.png" width="400" alt="DSH Update Status panel: cache duration, the running 0.2.1-alpha.1 reported up to date with its last-checked time, the actions Check for updates, Release notes and Restart, and a note that restart is available only under a user-installed service">
|
|
33
34
|
</p>
|
|
34
35
|
|
|
35
36
|
## Features
|
|
@@ -45,6 +46,7 @@ It shadows only the expanded sidebar brand name with `DeepSeek` plus a compact v
|
|
|
45
46
|
- **Copy-only guidance** — generates an installation-kind-aware command for the exact newer version it found, never a dist-tag that can move, and never executes it.
|
|
46
47
|
- **Cache without polling** — one Host check on mount, a configurable 30–1,440 minute cache, single-flight registry access, and no frontend polling. Only the Check for updates button bypasses the cache.
|
|
47
48
|
- **Mobile-safe panel** — uses a modal browser top layer so the scrollable, safe-area-aware bottom sheet stays above the DSH drawer.
|
|
49
|
+
- **Supervised safe restart** — after a one-time service setup, the panel can restart DSH for you: it warns about the work it would interrupt, and refuses outright when DSH was started by hand or by the desktop app.
|
|
48
50
|
|
|
49
51
|
## Install
|
|
50
52
|
|
|
@@ -85,7 +87,7 @@ dsh plugin --profile web add "link:$(pwd)"
|
|
|
85
87
|
3. Read the running version. When it is the newest release npm publishes, the panel says so and offers nothing to run.
|
|
86
88
|
4. When a newer release exists — stable, release candidate or alpha — the panel names it, its publish date, and whether this plugin was verified against it.
|
|
87
89
|
5. Copy the generated command, which is pinned to that exact version, and run it yourself in a terminal on the computer hosting DSH.
|
|
88
|
-
6.
|
|
90
|
+
6. After the package-manager command completes, use the panel's **Restart** control only if you have completed [supervised restart](#supervised-restart); otherwise restart DSH yourself.
|
|
89
91
|
|
|
90
92
|
Example commands generated for a global install:
|
|
91
93
|
|
|
@@ -124,6 +126,38 @@ The plugin asks the npm registry for `@deepseek-ai/dsh` once per cache window, k
|
|
|
124
126
|
|
|
125
127
|
Nothing here installs anything. Choosing to follow a channel — and the `channel` preference that stored it — was removed in `0.2.0`.
|
|
126
128
|
|
|
129
|
+
## Supervised restart
|
|
130
|
+
|
|
131
|
+
A plugin cannot restart DSH on its own: it lives inside the very process it would have to replace. So the button only works once your operating system owns that process — and every OS already ships a way to do that.
|
|
132
|
+
|
|
133
|
+
The shortest safe setup is explicit and terminal-driven:
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
# 1. Inspect the complete native-service plan. This writes and starts nothing.
|
|
137
|
+
dsh plugin --profile web exec dsh-update-status-service plan \
|
|
138
|
+
--workspace "$PWD" --dry-run
|
|
139
|
+
|
|
140
|
+
# 2. Stage the user-service definition. This still does not start it.
|
|
141
|
+
dsh plugin --profile web exec dsh-update-status-service install \
|
|
142
|
+
--workspace "$PWD"
|
|
143
|
+
|
|
144
|
+
# 3. Stop the terminal-started dsh web yourself, then activate the service.
|
|
145
|
+
dsh plugin --profile web exec dsh-update-status-service activate \
|
|
146
|
+
--workspace "$PWD"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`activate` stops if the port is still busy instead of killing anything, so the DSH you are already using is never taken down by surprise. From then on, **Restart** lists what is running, asks for a second confirmation when something is, and lets DSH exit; the service starts it again and the page comes back on its own.
|
|
150
|
+
|
|
151
|
+
| Platform | User-level owner | Starts | Restart works after setup | Notes |
|
|
152
|
+
| --- | --- | --- | --- | --- |
|
|
153
|
+
| macOS | `launchd` LaunchAgent | at user login | Yes | First verified target; no administrator account required. |
|
|
154
|
+
| Linux | `systemd --user` | at user login | Implemented; verify on your host | `loginctl enable-linger` is optional for running after logout and is never enabled automatically. The unit template is render-tested but has not been run on a real Linux host yet. |
|
|
155
|
+
| Windows | Task Scheduler + current-user wrapper | at user logon | Template supplied; verify on Windows before production use | No administrator account required. |
|
|
156
|
+
|
|
157
|
+
The generated service files contain absolute paths and **no secrets** — never your API keys, npm tokens, cookies or proxy credentials. Native files, logs, status and removal: [user-service supervision](docs/service-supervision.md). To check Linux or Windows on your own machine: [platform acceptance](docs/platform-acceptance.md).
|
|
158
|
+
|
|
159
|
+
A restart interrupts running work and does not save it. If DSH cannot list what is running, or was started by hand or by the desktop app, it refuses to restart at all — a web page cannot talk it into it.
|
|
160
|
+
|
|
127
161
|
## LAN / non-loopback pages
|
|
128
162
|
|
|
129
163
|
DSH disables Host settings persistence for any page whose origin is not a loopback authority (the official `dsh-client-ui-settings` README states it plainly: *Non-loopback pages get no durable settings*). Every entry-addressed form (`ctx.configForms.get(id)`, the DSH 0.1.7 successor of the removed `settingsScope` service) is then pinned to `memory`, answers `unavailable`, and never sends `settings.describe`, and `connection.isLoopback` reads false for the whole page.
|
|
@@ -137,13 +171,15 @@ If you want DSH's stock policy instead (a non-loopback page never persists setti
|
|
|
137
171
|
|
|
138
172
|
## Compatibility
|
|
139
173
|
|
|
140
|
-
Current release: plugin **`0.
|
|
174
|
+
Current release: plugin **`0.3.1`** is verified against DeepSeek Harness **`0.2.1-alpha.1`** (the current release), **`0.2.0-rc.2`**, **`0.2.0-rc.1`**, **`0.1.7-rc.2`**, **`0.1.7-rc.1`** and **`0.1.7-alpha.2`**.
|
|
141
175
|
|
|
142
176
|
### Which plugin version goes with which DeepSeek Harness version
|
|
143
177
|
|
|
144
178
|
| Plugin | Verified DeepSeek Harness | On npm | What that version is |
|
|
145
179
|
| --- | --- | --- | --- |
|
|
146
|
-
| **`0.
|
|
180
|
+
| **`0.3.1`** | `0.2.1-alpha.1`, `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | `latest` | Small patch: the settings page explains restart too, long job labels can no longer push the buttons away, and there is now a Linux/Windows check page |
|
|
181
|
+
| **`0.3.0`** | `0.2.1-alpha.1`, `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Adds **Restart** to the panel, plus the one-command service setup it requires (`dsh-update-status-service`). Without that service the button stays disabled and says why. Verified end to end on macOS |
|
|
182
|
+
| **`0.2.1`** | `0.2.1-alpha.1`, `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Fixes the blank brand row: hiding the version chip disposes the `sidebar.brand.name` registration instead of leaving an empty occupant, so DSH's own fish mark and wordmark come back; the settings hint says so |
|
|
147
183
|
| **`0.2.0`** | `0.2.1-alpha.1`, `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | One release line instead of a channel catalogue: the Host keeps only the newest version any npm dist-tag points at (stable, release candidate or alpha) and the panel simply reports the running version, or names the newer release with a command pinned to it; the `channel` preference, the channel list and the per-channel select are gone, and the settings section shows the same single answer |
|
|
148
184
|
| **`0.1.12`** | `0.2.0-rc.2`, `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Declares compatibility with the running `0.2.0-rc.2`: audits all 7 packages in `dsh.client.inject` across rc.1 → rc.2 (only three files differ, and no surface this plugin uses is among them), adds `0.2.0-rc.2` to the verified list so following `latest` no longer shows the *not verified compatible* advisory, and re-verifies the chip, panel and settings section in a real browser on a disposable profile; zero code change |
|
|
149
185
|
| **`0.1.11`** | `0.2.0-rc.1`, `0.1.7-rc.2`, `0.1.7-rc.1`, `0.1.7-alpha.2` | published | Declaration release for the DSH `0.2.0` line: audits the `0.1.7-rc.2` → `0.2.0-rc.1` delta for every package in `dsh.client.inject` (version bumps and two additive client changes — no surface this plugin uses changed), adds the running `0.2.0-rc.1` to the verified list, and widens the load-bearing ranges to `<0.3.0` so the `0.2.0` stable cannot silently drop the plugin; zero code change |
|
|
@@ -165,7 +201,7 @@ Current release: plugin **`0.2.1`** is verified against DeepSeek Harness **`0.2.
|
|
|
165
201
|
- Match them explicitly when it matters:
|
|
166
202
|
|
|
167
203
|
```sh
|
|
168
|
-
dsh plugin --profile web add dsh-update-status@0.
|
|
204
|
+
dsh plugin --profile web add dsh-update-status@0.3.1 # DSH 0.2.1-alpha.1
|
|
169
205
|
dsh plugin --profile web add dsh-update-status@0.2.0 # DSH 0.2.1-alpha.1, 0.2.0-rc.2, 0.2.0-rc.1, 0.1.7-rc.2, 0.1.7-rc.1 or 0.1.7-alpha.2
|
|
170
206
|
dsh plugin --profile web add dsh-update-status@0.1.12 # DSH 0.2.0-rc.2, 0.2.0-rc.1, 0.1.7-rc.2, 0.1.7-rc.1 or 0.1.7-alpha.2
|
|
171
207
|
dsh plugin --profile web add dsh-update-status@0.1.11 # DSH 0.2.0-rc.1, 0.1.7-rc.2, 0.1.7-rc.1 or 0.1.7-alpha.2
|
|
@@ -182,7 +218,7 @@ Current release: plugin **`0.2.1`** is verified against DeepSeek Harness **`0.2.
|
|
|
182
218
|
- Two declarations make the verified lines load at all, and a test keeps them honest:
|
|
183
219
|
- `dsh.engines.dsh` and `peerDependencies['@deepseek-ai/dsh-settings']` both declare `>=0.1.7-alpha.2 <0.3.0`, which admits all six verified releases. The lower bound names the alpha on purpose — under node-semver's default prerelease rule a range like `>=0.1.6-0 <0.2.0` does **not** admit `0.1.7-alpha.2`. The upper bound moved from `<0.2.0` to `<0.3.0` in `0.1.11` for the mirror-image reason: DSH refuses an incompatible bundle at profile load, and a plain `<0.2.0` excludes the `0.2.0` stable, so the day DSH `0.2.0` shipped the plugin would have been silently dropped. DSH evaluates the range with `includePrerelease: true`, so `0.2.0-rc.2` was already inside it and `0.1.12` needed no range change; conversely, a bundle that enumerates `... || 0.2.0-rc.1 || >=0.2.0 <0.3.0` is refused on rc.2, because `>=0.2.0` does not admit a `0.2.0` prerelease.
|
|
184
220
|
- `@deepseek-ai/schemastery` is a **peer**, not a plain dependency: DSH 0.1.7 resolves only a linked plugin's peer dependencies from the running installation, so a `link:` install of this directory would otherwise fail to import the Host half.
|
|
185
|
-
- Per-release notes — what changed, who is affected, what to do — are hand-written in Chinese and English and become the GitHub Release body: [`v0.2.1`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.1.md) · [`v0.2.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.0.md) · [`v0.1.12`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.12.md) · [`v0.1.11`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.11.md) · [`v0.1.10`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.10.md) · [`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md) (covers the never-published `0.1.2`).
|
|
221
|
+
- Per-release notes — what changed, who is affected, what to do — are hand-written in Chinese and English and become the GitHub Release body: [`v0.3.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.3.1.md) · [v0.3.0](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.3.0.md) · [`v0.2.1`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.1.md) · [`v0.2.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.0.md) · [`v0.1.12`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.12.md) · [`v0.1.11`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.11.md) · [`v0.1.10`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.10.md) · [`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md) (covers the never-published `0.1.2`).
|
|
186
222
|
|
|
187
223
|
## Configuration
|
|
188
224
|
|
|
@@ -234,7 +270,8 @@ rm -rf ~/.dsh/profiles/<profile>/node_modules/dsh-update-status/node_modules
|
|
|
234
270
|
- There is no public Remote Service and no model Tool.
|
|
235
271
|
- No package-manager process is spawned by plugin code.
|
|
236
272
|
- `canApplyInPlace` is always `false`.
|
|
237
|
-
-
|
|
273
|
+
- The plugin never installs, upgrades, rolls back, or replaces DSH files. Its separate, explicitly invoked service CLI stages only current-user service definitions; it never kills an occupied DSH port.
|
|
274
|
+
- Restart requests travel over DSH's authenticated channel and are re-checked by the Host itself: a hand-started, desktop, or un-inspectable DSH refuses to exit even when a page asks it to.
|
|
238
275
|
- A failed refresh retains the last good cache and displays a warning; a cold failure still shows the local version.
|
|
239
276
|
|
|
240
277
|
## Uninstall
|
package/README.zh.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<h1 align="center">DSH Update Status</h1>
|
|
2
2
|
|
|
3
|
-
<p align="center">DeepSeek Harness Web
|
|
3
|
+
<p align="center">DeepSeek Harness Web 的版本状态、仅复制升级提示,以及需用户级服务监督的安全重启。</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<a href="https://www.npmjs.com/package/dsh-update-status"><img src="https://img.shields.io/npm/v/dsh-update-status?label=npm&color=CB3837" alt="npm 版本"></a>
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
<a href="#安装">安装</a> ·
|
|
16
16
|
<a href="#使用">使用</a> ·
|
|
17
17
|
<a href="#更新检查">更新检查</a> ·
|
|
18
|
+
<a href="#受监督的重启">受监督的重启</a> ·
|
|
18
19
|
<a href="#局域网非回环页面访问">局域网访问</a> ·
|
|
19
20
|
<a href="#兼容性">兼容性</a> ·
|
|
20
21
|
<a href="#配置">配置</a> ·
|
|
@@ -24,12 +25,12 @@
|
|
|
24
25
|
<a href="docs/RELEASING.md">发布指南</a>
|
|
25
26
|
</p>
|
|
26
27
|
|
|
27
|
-
> DSH Update Status 是 DeepSeek Harness 社区插件。它不修改 DSH
|
|
28
|
+
> DSH Update Status 是 DeepSeek Harness 社区插件。它不修改 DSH 核心,不会安装或升级 DSH、回滚 DSH 包、下载 release 或替换 DSH 文件;只有你显式安装并接管了当前 DSH Web 的用户级后台服务后,它才会请求一次受限的安全重启。
|
|
28
29
|
|
|
29
|
-
插件只把展开侧栏中的品牌名称换成适配 24px 品牌行的 `DeepSeek + 版本芯片`,官方鱼标保持不变。版本号旁的**绿点**表示正在运行的版本就是 npm 上最新的那一版;**橙色呼吸圆点**表示线上有更新的版本——无论是稳定版、RC 还是 Alpha
|
|
30
|
+
插件只把展开侧栏中的品牌名称换成适配 24px 品牌行的 `DeepSeek + 版本芯片`,官方鱼标保持不变。版本号旁的**绿点**表示正在运行的版本就是 npm 上最新的那一版;**橙色呼吸圆点**表示线上有更新的版本——无论是稳定版、RC 还是 Alpha。点击芯片即可看到当前运行版本、更新的版本、本插件是否验证过它、钉在该确切版本上的“仅复制”升级命令,以及只有装好用户级监督后才会出现的**重启**按钮。
|
|
30
31
|
|
|
31
32
|
<p align="center">
|
|
32
|
-
<img src="./assets/update-panel.png" width="400" alt="DSH
|
|
33
|
+
<img src="./assets/update-panel.zh.png" width="400" alt="DSH 更新状态面板:缓存时长、正在运行的 0.2.1-alpha.1 显示已是最新与上次检查时间、检查更新/发布说明/重启三个操作,以及“只有受用户级服务监督时才允许安全重启”的说明">
|
|
33
34
|
</p>
|
|
34
35
|
|
|
35
36
|
## 功能
|
|
@@ -45,7 +46,7 @@
|
|
|
45
46
|
- **仅复制命令**:根据安装来源,为**找到的那个确切版本**生成命令,不用会移动的 dist-tag,也从不执行。
|
|
46
47
|
- **缓存但不轮询**:Host 挂载时检查一次,缓存可设为 30–1,440 分钟并合并并发请求;前端没有轮询,只有“检查更新”按钮绕过缓存。
|
|
47
48
|
- **移动端可靠**:详情使用浏览器 modal top layer;底部 sheet 可滚动、适配 safe area,并保持在 DSH 抽屉上方。
|
|
48
|
-
|
|
49
|
+
- **受监督的安全重启**:一次性装好后台服务后,面板就能替你重启 DSH——它会先提醒会中断哪些工作,而终端直启或桌面应用托管的 DSH 会被直接拒绝。
|
|
49
50
|
## 安装
|
|
50
51
|
|
|
51
52
|
要求:
|
|
@@ -85,7 +86,7 @@ dsh plugin --profile web add "link:$(pwd)"
|
|
|
85
86
|
3. 看当前运行版本。当它就是 npm 上最新的那一版时,面板会直接说明,并且不提供任何要执行的命令。
|
|
86
87
|
4. 当线上有更新的版本——稳定版、RC 或 Alpha 都一样——面板会给出它的版本号、发布时间,以及本插件是否验证过它。
|
|
87
88
|
5. 复制生成的命令(已钉在该确切版本上),在**运行 DSH 的那台电脑**的终端中自行执行。
|
|
88
|
-
6.
|
|
89
|
+
6. 包管理器命令完成后,只有已完成[受监督的重启](#受监督的重启)接管时才使用面板里的**重启**;否则仍由你自行重启 DSH。
|
|
89
90
|
|
|
90
91
|
全局安装时可能生成:
|
|
91
92
|
|
|
@@ -124,6 +125,38 @@ npm install -g @deepseek-ai/dsh@0.2.1-alpha.1
|
|
|
124
125
|
|
|
125
126
|
这里不会安装任何东西。跟随某条通道——以及保存它的 `channel` 偏好——已在 `0.2.0` 移除。
|
|
126
127
|
|
|
128
|
+
## 受监督的重启
|
|
129
|
+
|
|
130
|
+
插件没法自己重启 DSH:它就住在那个要被换掉的进程里。所以只有让操作系统来托管这个进程,按钮才有意义——而每个系统本来就自带这个能力。
|
|
131
|
+
|
|
132
|
+
最短且安全的接管流程是显式在终端执行:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
# 1. 只预览完整的原生服务计划:不写文件,不启动服务。
|
|
136
|
+
dsh plugin --profile web exec dsh-update-status-service plan \
|
|
137
|
+
--workspace "$PWD" --dry-run
|
|
138
|
+
|
|
139
|
+
# 2. 只落盘用户服务定义:仍然不会启动它。
|
|
140
|
+
dsh plugin --profile web exec dsh-update-status-service install \
|
|
141
|
+
--workspace "$PWD"
|
|
142
|
+
|
|
143
|
+
# 3. 由你自己在旧终端停止直启的 dsh web,再激活服务。
|
|
144
|
+
dsh plugin --profile web exec dsh-update-status-service activate \
|
|
145
|
+
--workspace "$PWD"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`activate` 发现端口还被占着就停手,绝不去杀进程,所以你正在用的 DSH 不会被突然掐掉。这之后就交给**重启**按钮:它先列出正在跑的东西,有东西在跑时再问一次,然后才让 DSH 退出;服务把新的拉起来,页面自己回来。
|
|
149
|
+
|
|
150
|
+
| 平台 | 用户级拥有者 | 启动时机 | 接管后页面重启 | 说明 |
|
|
151
|
+
| --- | --- | --- | --- | --- |
|
|
152
|
+
| macOS | `launchd` LaunchAgent | 用户登录 | 可以 | 已真机验证;不需要管理员。 |
|
|
153
|
+
| Linux | `systemd --user` | 用户登录 | 已实现;请在你自己机器上验证 | 想在登出后继续运行,可自行开启 `loginctl enable-linger`(本插件不会替你开)。 |
|
|
154
|
+
| Windows | 任务计划程序 + 当前用户 wrapper | 用户登录 | 已实现;请在你自己机器上验证 | 不需要管理员。 |
|
|
155
|
+
|
|
156
|
+
生成的服务文件里只有绝对路径,**没有密钥**——不会带上你终端里的 API key、npm token、cookie 或代理凭据。原生文件、日志、状态与卸载见[用户服务监督说明](docs/service-supervision.md);想在 Linux 或 Windows 上自己确认,见[跨平台验收步骤](docs/platform-acceptance.md)。
|
|
157
|
+
|
|
158
|
+
重启会中断正在跑的工作,且不会保存。如果 DSH 列不出正在跑什么,或者它本来就是终端直启、桌面应用托管的,它会直接拒绝重启——网页端说什么都没用。
|
|
159
|
+
|
|
127
160
|
## 局域网(非回环页面)访问
|
|
128
161
|
|
|
129
162
|
DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Host 设置持久化(官方 `dsh-client-ui-settings` README 原文:*Non-loopback pages get no durable settings*):所有按条目寻址的设置表单(`ctx.configForms.get(id)`,DSH 0.1.7 中已移除的 `settingsScope` 服务的继任者)此时被固定为 `memory`,直接返回 `unavailable`,并且从此不发 `settings.describe`;整页的 `connection.isLoopback` 也都是 false。
|
|
@@ -137,13 +170,15 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
|
|
|
137
170
|
|
|
138
171
|
## 兼容性
|
|
139
172
|
|
|
140
|
-
当前发布:插件 **`0.
|
|
173
|
+
当前发布:插件 **`0.3.1`** 已针对 DeepSeek Harness **`0.2.1-alpha.1`**(当前发布版)、**`0.2.0-rc.2`**、**`0.2.0-rc.1`**、**`0.1.7-rc.2`**、**`0.1.7-rc.1`** 与 **`0.1.7-alpha.2`** 验证。
|
|
141
174
|
|
|
142
175
|
### 插件版本与 DeepSeek Harness 版本的对应关系
|
|
143
176
|
|
|
144
177
|
| 插件版本 | 已验证的 DeepSeek Harness | npm 发布状态 | 该版本是什么 |
|
|
145
178
|
| --- | --- | --- | --- |
|
|
146
|
-
| **`0.
|
|
179
|
+
| **`0.3.1`** | `0.2.1-alpha.1`、`0.2.0-rc.2`、`0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | `latest` | 小补丁:设置页也说明重启前提,会中断的任务列表不再把按钮挤走;新增 Linux/Windows 自验步骤 |
|
|
180
|
+
| **`0.3.0`** | `0.2.1-alpha.1`、`0.2.0-rc.2`、`0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 新增受监督的**重启**按钮与跨平台用户级服务 CLI(`plan`/`install`/`activate`/`status`/`stop`/`uninstall`)。没有用户级服务接管时按钮保持禁用;Host 会自行复核监督标记与平台身份、列出正在运行的 Agent/Job/终端,读不完整就拒绝。已在 macOS 真机跑通闭环:强制重启 → 退出码 `42` → launchd 拉起 → 页面自动刷新。公开承诺从「只读、绝不重启」变为「只读 + 安装用户级服务后的一次受限重启」 |
|
|
181
|
+
| **`0.2.1`** | `0.2.1-alpha.1`、`0.2.0-rc.2`、`0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 修复「取消勾选后品牌行空白」:隐藏版本芯片时改为注销 `sidebar.brand.name` 注册,而不是留一个空白占用者,DSH 官方的鱼标与字标因此会回来;设置里的说明同步更新 |
|
|
147
182
|
| **`0.2.0`** | `0.2.1-alpha.1`、`0.2.0-rc.2`、`0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 从「通道目录」改为「一条发布线」:Host 只保留 npm 全部 dist-tag 里最新的那个版本(稳定版、RC、Alpha 一视同仁),面板直接显示当前运行版本;有更新时给出更新版本号与钉在它上面的命令。`channel` 偏好、通道列表与通道下拉框全部移除,设置区块显示同一份结论 |
|
|
148
183
|
| **`0.1.12`** | `0.2.0-rc.2`、`0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | 声明兼容正在运行的 `0.2.0-rc.2`:逐包核对 `dsh.client.inject` 里 7 个包在 rc.1 → rc.2 之间的差异(仅 3 个文件有实质改动,本插件用到的接口面无一变化),把 `0.2.0-rc.2` 加入已验证清单,消除跟随 `latest` 时的「尚未验证兼容」提示;并在一次性 profile + 真实浏览器里实测芯片、面板与设置区块;代码零改动 |
|
|
149
184
|
| **`0.1.11`** | `0.2.0-rc.1`、`0.1.7-rc.2`、`0.1.7-rc.1`、`0.1.7-alpha.2` | 已发布 | DSH `0.2.0` 线的声明发布:逐包核对 `dsh.client.inject` 里每个宿主包在 `0.1.7-rc.2` → `0.2.0-rc.1` 之间的差异(仅版本号与两处纯增量的客户端改动,本插件用到的接口面无一变化),把正在运行的 `0.2.0-rc.1` 加入已验证清单,并把两处承重范围放宽到 `<0.3.0`,避免 DSH `0.2.0` 正式版发布当天插件被静默丢弃;代码零改动 |
|
|
@@ -165,7 +200,7 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
|
|
|
165
200
|
- 需要精确对应时显式指定版本:
|
|
166
201
|
|
|
167
202
|
```sh
|
|
168
|
-
dsh plugin --profile web add dsh-update-status@0.
|
|
203
|
+
dsh plugin --profile web add dsh-update-status@0.3.1 # DSH 0.2.1-alpha.1
|
|
169
204
|
dsh plugin --profile web add dsh-update-status@0.2.0 # DSH 0.2.1-alpha.1、0.2.0-rc.2、0.2.0-rc.1、0.1.7-rc.2、0.1.7-rc.1 或 0.1.7-alpha.2
|
|
170
205
|
dsh plugin --profile web add dsh-update-status@0.1.12 # DSH 0.2.0-rc.2、0.2.0-rc.1、0.1.7-rc.2、0.1.7-rc.1 或 0.1.7-alpha.2
|
|
171
206
|
dsh plugin --profile web add dsh-update-status@0.1.11 # DSH 0.2.0-rc.1、0.1.7-rc.2、0.1.7-rc.1 或 0.1.7-alpha.2
|
|
@@ -182,7 +217,7 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
|
|
|
182
217
|
- 有两处声明让已验证的版本线能正常加载,并由测试守住:
|
|
183
218
|
- `dsh.engines.dsh` 与 `peerDependencies['@deepseek-ai/dsh-settings']` 都声明 `>=0.1.7-alpha.2 <0.3.0`,六个已验证版本都在范围内。下界特意写成这个 alpha:按 node-semver 默认的预发布规则,`>=0.1.6-0 <0.2.0` 这样的范围**并不接纳** `0.1.7-alpha.2`。上界在 `0.1.11` 从 `<0.2.0` 放宽到 `<0.3.0` 是同一件事的镜像:DSH 会在 profile 加载时拒绝不兼容的 bundle,而裸的 `<0.2.0` 恰好排除 `0.2.0` 正式版——DSH `0.2.0` 发布当天插件就会被静默丢弃。DSH 判定时使用 `includePrerelease: true`,所以 `0.2.0-rc.2` 本来就在这个范围内,`0.1.12` 无需再动范围;反过来说,把范围写成 `... || 0.2.0-rc.1 || >=0.2.0 <0.3.0` 这类枚举的插件会因为 `>=0.2.0` 不接纳 `0.2.0` 预发布而被 rc.2 拒载。
|
|
184
219
|
- `@deepseek-ai/schemastery` 是 **peer**,不是普通依赖:DSH 0.1.7 只从运行安装解析 link 插件的 peer 依赖,否则 `link:` 安装会连 Host 半边都 import 失败。
|
|
185
|
-
- 每个版本的中英文详细说明(改了什么、影响谁、需要做什么)手写后直接作为 GitHub Release 正文:[`v0.2.1`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.1.md) · [`v0.2.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.0.md) · [`v0.1.12`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.12.md) · [`v0.1.11`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.11.md) · [`v0.1.10`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.10.md) · [`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md)(含从未发布的 `0.1.2`)。
|
|
220
|
+
- 每个版本的中英文详细说明(改了什么、影响谁、需要做什么)手写后直接作为 GitHub Release 正文:[`v0.3.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.3.1.md) · [v0.3.0](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.3.0.md) · [`v0.2.1`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.1.md) · [`v0.2.0`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.2.0.md) · [`v0.1.12`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.12.md) · [`v0.1.11`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.11.md) · [`v0.1.10`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.10.md) · [`v0.1.9`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.9.md) · [`v0.1.8`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.8.md) · [`v0.1.7`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.7.md) · [`v0.1.6`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.6.md) · [`v0.1.5`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.5.md) · [`v0.1.4`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.4.md) · [`v0.1.3`](https://github.com/idoall/dsh-update-status/blob/main/docs/releases/v0.1.3.md)(含从未发布的 `0.1.2`)。
|
|
186
221
|
|
|
187
222
|
## 配置
|
|
188
223
|
|
|
@@ -234,7 +269,8 @@ rm -rf ~/.dsh/profiles/<profile>/node_modules/dsh-update-status/node_modules
|
|
|
234
269
|
- 不注册公共 Remote Service,也不注册模型 Tool。
|
|
235
270
|
- 插件代码不会启动 npm/pnpm 子进程。
|
|
236
271
|
- `canApplyInPlace` 恒为 `false`。
|
|
237
|
-
-
|
|
272
|
+
- 插件不会安装、升级、回滚或替换 DSH 文件。单独、显式执行的服务 CLI 只会落盘当前用户的服务定义,绝不会杀掉占用端口的 DSH。
|
|
273
|
+
- 重启是只接受 POST 的已认证 Connection RPC,并由服务端同时检查明确的原生服务标记与平台身份;终端直启、桌面版、未知环境或无法完整检查活动工作时均拒绝退出。
|
|
238
274
|
- 刷新失败时保留最后一次成功缓存并显示警告;冷启动失败也会保留本地版本信息。
|
|
239
275
|
|
|
240
276
|
## 卸载
|
package/assets/update-panel.png
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Verifying on Linux or Windows
|
|
2
|
+
|
|
3
|
+
macOS is verified on a real machine. The Linux and Windows service templates are generated and covered by tests, but **have not been run on those systems yet** — that is what this page is for.
|
|
4
|
+
|
|
5
|
+
Three steps, each one safe to stop at. If a step fails, the section below says what to look at.
|
|
6
|
+
|
|
7
|
+
## 1. Look first — writes nothing
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
dsh plugin --profile web exec dsh-update-status-service plan --workspace "$PWD" --dry-run
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Check the printed Node path, DSH path and port against what you actually run. Override any of them with `--node`, `--dsh`, `--port`.
|
|
14
|
+
|
|
15
|
+
## 2. Write the service definition — still starts nothing
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
dsh plugin --profile web exec dsh-update-status-service install --workspace "$PWD"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
It runs a boot precheck that does not bind the port. If that precheck fails, nothing is written.
|
|
22
|
+
|
|
23
|
+
## 3. Stop your terminal's `dsh web` yourself, then
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
dsh plugin --profile web exec dsh-update-status-service activate --workspace "$PWD"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
It refuses to start while the port is still busy — that is deliberate, so the DSH you are using is never pushed aside.
|
|
30
|
+
|
|
31
|
+
Then reopen the Web UI and check that **Restart** in the update panel is enabled (not greyed out). That is the whole acceptance test: restart availability means the running process was recognised as service-managed.
|
|
32
|
+
|
|
33
|
+
## Where to look when something is off
|
|
34
|
+
|
|
35
|
+
| Platform | Status command |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| Linux | `systemctl --user status dsh-update-status-web.service` and `journalctl --user -u dsh-update-status-web.service -f` |
|
|
38
|
+
| Windows | Task Scheduler → **DSH Update Status Web**, or `schtasks /Query /TN "DSH Update Status Web" /V /FO LIST` |
|
|
39
|
+
|
|
40
|
+
If **Restart** stays greyed out after activating, the running process was not recognised as the service's process. For an issue report, include the `plan` output and the status output above.
|
|
41
|
+
|
|
42
|
+
## Removing it again
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
dsh plugin --profile web exec dsh-update-status-service uninstall --workspace "$PWD"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
That removes only the definition this tool created. Logs are kept.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# User-service supervision
|
|
2
|
+
|
|
3
|
+
The **Restart** control in DSH Update Status can safely request `process.exit(42)`, but a plugin runs inside the process it is asking to restart. It cannot relaunch itself. For a page restart to recover, DSH Web must therefore be owned by an external, **user-level** service manager.
|
|
4
|
+
|
|
5
|
+
This document describes the explicit, opt-in setup. The plugin never installs a service on its own, never kills a terminal-started DSH instance, and never copies shell secrets (such as API keys, npm tokens, or proxy credentials) into a service definition.
|
|
6
|
+
|
|
7
|
+
## Quick path
|
|
8
|
+
|
|
9
|
+
1. Install the plugin and build or install a version that includes the service CLI.
|
|
10
|
+
2. Preview the exact plan; this writes nothing and starts nothing:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
dsh plugin --profile web exec dsh-update-status-service plan \
|
|
14
|
+
--workspace "$PWD" --dry-run
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
3. Stage the native user-service definition. This still does **not** start it:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
dsh plugin --profile web exec dsh-update-status-service install \
|
|
21
|
+
--workspace "$PWD"
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
4. In the terminal that currently owns `dsh web`, stop it yourself with `Ctrl-C` after active work has finished.
|
|
25
|
+
5. Activate the staged service:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
dsh plugin --profile web exec dsh-update-status-service activate \
|
|
29
|
+
--workspace "$PWD"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
`activate` refuses to run while the requested port is occupied. It never kills an existing process; this prevents an `EADDRINUSE` crash loop.
|
|
33
|
+
|
|
34
|
+
6. Reopen the normal Web URL. The update panel should report a restart-capable supervised process. Perform the first real page restart yourself while present, then confirm that the page reconnects.
|
|
35
|
+
|
|
36
|
+
Use `status`, `stop`, and `uninstall` with the same `--workspace` argument for later maintenance. `uninstall` preserves logs.
|
|
37
|
+
|
|
38
|
+
> `dsh plugin --profile web exec` is pnpm's profile-local executable runner. Do not assume `dsh-update-status-service` is globally installed.
|
|
39
|
+
|
|
40
|
+
## What the installer records
|
|
41
|
+
|
|
42
|
+
The staged definition contains only explicit, non-secret launch facts:
|
|
43
|
+
|
|
44
|
+
- absolute Node and DSH CLI paths;
|
|
45
|
+
- profile, workspace, host, port, and `--no-open`;
|
|
46
|
+
- `DSH_HOME` when explicitly configured;
|
|
47
|
+
- an explicit `DSH_WEB_SUPERVISOR=dsh-update-status` marker;
|
|
48
|
+
- private stdout/stderr log paths.
|
|
49
|
+
|
|
50
|
+
It intentionally does **not** inherit the full terminal environment. If your DSH startup requires secret environment variables, configure them through your operating system's secret-management mechanism before activating the service; do not paste secrets into this plugin's configuration or issue tracker.
|
|
51
|
+
|
|
52
|
+
## macOS — LaunchAgent
|
|
53
|
+
|
|
54
|
+
The CLI stages a current-user plist at:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
~/Library/LaunchAgents/com.idoall.dsh-update-status.web.plist
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
It runs at login (`RunAtLoad`) and keeps DSH alive (`KeepAlive`). The plugin accepts page restart only when both the explicit marker and launchd's `XPC_SERVICE_NAME=com.idoall.dsh-update-status.web` identify the current process. A terminal process that merely has a similarly named environment variable is refused.
|
|
61
|
+
|
|
62
|
+
Useful native inspection commands:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
launchctl print "gui/$(id -u)/com.idoall.dsh-update-status.web"
|
|
66
|
+
launchctl kickstart -k "gui/$(id -u)/com.idoall.dsh-update-status.web"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Use the plugin CLI `stop` or `uninstall`, not `kill`, to intentionally stop a `KeepAlive` service. Killing the DSH child alone asks launchd to start it again.
|
|
70
|
+
|
|
71
|
+
## Linux — systemd user service
|
|
72
|
+
|
|
73
|
+
The CLI stages:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
~/.config/systemd/user/dsh-update-status-web.service
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
It uses `Restart=on-failure`, so DSH's restart exit code causes systemd to relaunch it. It is a **user** service: normally it starts after that user logs in.
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
systemctl --user status dsh-update-status-web.service
|
|
83
|
+
journalctl --user -u dsh-update-status-web.service -f
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
To keep it alive after logout, a machine administrator may enable user lingering:
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
loginctl enable-linger "$USER"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The CLI deliberately does not enable lingering, because that changes account-level system behavior.
|
|
93
|
+
|
|
94
|
+
## Windows — Task Scheduler
|
|
95
|
+
|
|
96
|
+
The CLI stages a current-user Task Scheduler definition and a PowerShell wrapper below:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
%LOCALAPPDATA%\dsh-update-status\
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The task starts at user logon with least privilege. The wrapper owns the long-running DSH child and restarts it after an intentional restart or unexpected exit. Use Task Scheduler to inspect the task named **DSH Update Status Web**.
|
|
103
|
+
|
|
104
|
+
Windows behavior must be verified on a Windows host before it is described as production-supported; use `plan --dry-run` to inspect the generated XML and wrapper first.
|
|
105
|
+
|
|
106
|
+
## Restart behavior and limits
|
|
107
|
+
|
|
108
|
+
The panel's flow is deliberately conservative:
|
|
109
|
+
|
|
110
|
+
1. It verifies that the **current** DSH process is supervised.
|
|
111
|
+
2. It lists running agents, jobs, and terminals. If this inspection is incomplete, restart is refused.
|
|
112
|
+
3. If work is running, a second **Force restart** confirmation is required. A restart interrupts that work; it does not save or resume it.
|
|
113
|
+
4. The Host returns an accepted response, then exits with code `42` after a short grace period.
|
|
114
|
+
5. The browser polls for a different process instance ID for up to 60 seconds, then reloads.
|
|
115
|
+
|
|
116
|
+
If recovery times out, inspect the native service status and logs. An environment whose web authentication token is process-scoped may require reopening the URL printed in the service log; this plugin cannot universally promise that an existing browser cookie survives every DSH deployment.
|
|
117
|
+
|
|
118
|
+
## Repair and removal
|
|
119
|
+
|
|
120
|
+
Node/NVM upgrades can change the absolute Node path captured in a service definition. Re-run `plan --dry-run`, compare it with `status`, then stage a replacement only after reviewing the changed path. Do not edit a service definition while it is running.
|
|
121
|
+
|
|
122
|
+
To remove supervision without deleting DSH profiles, sessions, or plugin preferences:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
dsh plugin --profile web exec dsh-update-status-service uninstall \
|
|
126
|
+
--workspace "$PWD"
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The command removes only the definition and receipt created by this installer. It preserves logs for diagnosis.
|