dsh-update-status 0.1.3 → 0.1.5
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 +80 -11
- package/README.zh.md +80 -11
- package/assets/sidebar-chip.png +0 -0
- package/assets/update-panel.png +0 -0
- package/docs/RELEASING.md +1 -1
- package/lib/client.js +78 -9
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +20 -0
- package/lib/index.js +11 -2
- package/package.json +4 -2
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.1.5 — 2026-09-18
|
|
6
|
+
|
|
7
|
+
Verified DeepSeek Harness: `0.1.6-alpha.2` (also `0.1.6-alpha.1` and `0.1.5-rc.1`). Full bilingual release notes: [`docs/releases/v0.1.5.md`](docs/releases/v0.1.5.md).
|
|
8
|
+
|
|
9
|
+
- **The up-to-date state is now a green circle.** The dot beside the version used the chip's `currentColor`, which on the light shell is near-black and on the dark shell near-white: a dot that reads as "off" rather than "you are current". It now uses the theme's success token (`--dsw-alias-state-success-primary`, `#22c55e` in both themes) and is a flat 5px circle — no glow, no animation, so "nothing to do" can never be confused with the update signal. The dot carries a new `data-state` (the value `visualState` already computes), and the precedence is explicit: up-to-date is declared first, then the neutral grey **checking** pulse, then the amber **update** halo, so an in-flight check and a pending update are untouched by this change. The failed-read state keeps the chip's own label colour on the red fill.
|
|
10
|
+
- **An advisory notice no longer repaints the chip — the red chip was a classification bug.** DSH `0.1.6-alpha.2` shipped after this bundle's verified list, so the Host honestly reported *"alpha 是预览通道,版本 0.1.6-alpha.2 尚未验证与本插件兼容。"* and the client treated **any** `warning` as a failure: the whole version chip turned solid red (`#ec1313`) on a perfectly healthy read — exactly the "the background colour changed again" surprise the breathing dot was meant to remove. The Host now labels each warning with a `warningKind`: `failure` when it could not produce a usable answer (registry read failed, channel unpublished, versions not SemVer-comparable), `notice` when the answer is complete and the text is merely advisory (an unverified preview). Only `failure` can repaint the chip. A Host older than the field sends none, and the client then keeps the previous "any warning is a problem" behaviour rather than dropping a real failure. The classification moved out of the TSX component into `src/shared/visual-state.ts` so it is unit-tested: advisory → `current`, failure → `problem`, legacy payload → `problem`.
|
|
11
|
+
- **Verified against DSH `0.1.6-alpha.2`**, so the running release is recognised instead of flagged: `0.1.6-alpha.2` joins `VERIFIED_DSH_VERSIONS` and `package.json`'s `dsh.compatibility.dshReleases`. A new spec compares the two lists, because their drifting apart is silent.
|
|
12
|
+
- **The version chip is now a neutral second-level surface.** It used `label-primary` as its fill with `label-primary-inverted` text, which on the dark shell is a near-white pill with dark text — a white frame that swallowed the amber halo and fought the warn colour. The chip now uses `button-floating-hover`, the one palette surface that is grey in **both** themes (`#f1f3f5` light / `#353638` dark), with `label-primary` text (`#0f1115` light / `#f9fafb` dark): a light grey chip on the light shell, a dark grey chip with white text on the dark one.
|
|
13
|
+
- **Light, dark and system are followed automatically, and hover no longer inverts in light mode.** Every rendered colour is a DSH semantic token, so the chip, dot, halo, footer ring and panel follow whichever appearance DSH resolves — including `system`, which tracks the OS — with no plugin-side theme detection and no media query to keep in sync. The old hover used `brightness(1.08)`, which only ever brightens: on the light shell it drove the grey chip to pure white, i.e. made it vanish. Hover now mixes the theme's own label colour into the surface (darkens in light mode, lightens in dark mode) inside an `@supports (background:color-mix(…))` guard, keeping the brightness filter as the fallback for an engine without `color-mix`. Measured: `#f1f3f5` → `#dfe1e3` light, `#353638` → `#454648` dark.
|
|
14
|
+
- **The error chip label is theme-correct.** It still repaints red, but now uses the shell's own badge pattern (`bg-layer-3` label) instead of hard-coded white: white on the dark red of the light theme, dark on the light red of the dark theme — both readable, unlike the fixed white text it replaces.
|
|
15
|
+
- **A pending update no longer repaints the version chip.** The chip used to flip to a solid amber fill (`warn-primary`) the moment a newer release existed, which recoloured the whole brand row for a state that is not a chip state. The chip now keeps its normal fill in every state, and the only signal is the amber dot beside the version: a 6px dot with a soft halo whose scale and glow breathe together on a 1.6s cycle. The halo is mixed from the theme's own warn colour (`color-mix`) with a literal amber declaration in front of it, so the glow always matches the dot and still renders on an engine without `color-mix`. `prefers-reduced-motion` holds the glow still instead of animating it.
|
|
16
|
+
- Styling invariants are locked by `tests/client/styles.spec.ts`: no `data-update` fill rule on the chip, the chip's grey surface and theme label, the theme-mixed hover with its brightness fallback, the error label, the dot's own animation and halo (with its fallback), the update state outranking the loading state, and the reduced-motion escape hatch.
|
|
17
|
+
|
|
18
|
+
## 0.1.4 — 2026-09-16
|
|
19
|
+
|
|
20
|
+
Verified DeepSeek Harness: `0.1.6-alpha.1` (also `0.1.5-rc.1`). Full bilingual release notes: [`docs/releases/v0.1.4.md`](docs/releases/v0.1.4.md).
|
|
21
|
+
|
|
22
|
+
- **Channel-selection deadlock fixed.** `visibleChannelReleases` dropped every channel whose version equalled the running release. While running the release published on `alpha`, the `alpha` row therefore disappeared from both the detail panel and the settings select — the one channel an operator on that line wants to follow could only be seen by already following it. A row is now hidden only when an earlier row already shows the same version; channels that all point at the running release still collapse to one.
|
|
23
|
+
- **The preference write path is now covered by tests.** A report of a stored `channel` changing without a gesture prompted a full audit: the only two write sites are the panel's per-channel button and the settings select, and no effect, timer or mount path writes. `tests/client/entry.spec.ts` mounts the real client entry with the official `settingsScope` seam present and asserts that a persisted preference is applied by *reading* and that mount plus teardown issue zero `set()` calls.
|
|
24
|
+
- No change to the status read, to LAN (non-loopback) behaviour, or to the Host document shape.
|
|
25
|
+
|
|
5
26
|
## 0.1.3 — 2026-09-16
|
|
6
27
|
|
|
7
28
|
Verified DeepSeek Harness: `0.1.6-alpha.1` (also `0.1.5-rc.1`). Full bilingual release notes: [`docs/releases/v0.1.3.md`](docs/releases/v0.1.3.md).
|
package/README.md
CHANGED
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
<a href="#features">Features</a> ·
|
|
15
15
|
<a href="#install">Install</a> ·
|
|
16
16
|
<a href="#usage">Usage</a> ·
|
|
17
|
+
<a href="#release-channels">Release channels</a> ·
|
|
18
|
+
<a href="#lan--non-loopback-pages">LAN pages</a> ·
|
|
19
|
+
<a href="#compatibility">Compatibility</a> ·
|
|
20
|
+
<a href="#configuration">Configuration</a> ·
|
|
21
|
+
<a href="#troubleshooting">Troubleshooting</a> ·
|
|
17
22
|
<a href="#security-boundary">Security</a> ·
|
|
18
23
|
<a href="#uninstall">Uninstall</a> ·
|
|
19
24
|
<a href="docs/RELEASING.md">Release guide</a>
|
|
@@ -21,17 +26,21 @@
|
|
|
21
26
|
|
|
22
27
|
> DSH Update Status is a community plugin for DeepSeek Harness. It does not modify DSH core and it never installs, restarts, rolls back, downloads, or replaces DSH files.
|
|
23
28
|
|
|
24
|
-
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. Tap the chip to inspect npm release channels, compatibility status, and a copy-only command for the selected channel.
|
|
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 there is nothing to do, and a breathing amber dot means a newer release is available. Tap the chip to inspect npm release channels, compatibility status, and a copy-only command for the selected channel.
|
|
25
30
|
|
|
26
31
|
<p align="center">
|
|
27
|
-
<img src="./assets/update-panel.png" width="
|
|
32
|
+
<img src="./assets/update-panel.png" width="400" alt="DSH Update Status panel: cache duration, the running 0.1.6-alpha.2 on the alpha channel, a latest row that does not match the followed channel, compatibility labels, and a copy-only upgrade command">
|
|
28
33
|
</p>
|
|
29
34
|
|
|
30
35
|
## Features
|
|
31
36
|
|
|
32
37
|
- **Visible version status** — shows the running DSH version in the expanded sidebar and a fallback action in the collapsed rail.
|
|
38
|
+
- **Quiet update signal** — a pending update never repaints the version chip. Only an amber dot with a soft halo next to the version breathes (scale + glow; the animation is disabled under `prefers-reduced-motion`), so a new release reads as one small light instead of a recoloured brand row.
|
|
39
|
+
- **Three dot states, one glance** — with nothing to do the dot beside the version is a plain **green circle** (the theme's success colour, not the text colour, so a dark shell no longer paints a dot that reads as "off"). While a check is running it is the neutral grey pulse; a pending update is the amber halo. Only the update state animates or glows, and only a failed status read repaints the chip, in red.
|
|
40
|
+
- **Neutral chip surface** — the chip is a grey second-level surface in both themes (`#f1f3f5` light / `#353638` dark) with the theme's normal label colour, so the dark shell gets a dark grey chip with white text rather than a white pill that hides the amber halo.
|
|
41
|
+
- **Light, dark, or system — followed automatically** — every colour the plugin renders is a DSH semantic token, so the chip, the dot, its halo, the footer ring and the panel all resolve through whatever appearance DSH is using. Set DSH to light, to dark, or to system and the plugin switches with the shell: no plugin-side theme setting, no media query to keep in sync. Hover lifts the chip in both directions (darkened in light mode, lightened in dark mode) by mixing the theme's label colour into the surface.
|
|
33
42
|
- **Stable and preview discovery** — reads npm dist-tags `latest`, `next`, and `alpha` in one registry request; `latest` is the default.
|
|
34
|
-
- **Useful choices only** —
|
|
43
|
+
- **Useful choices only** — de-duplicates rows by version, keeps `latest` and the channel you follow, and never hides the channel that matches the release you are running.
|
|
35
44
|
- **In-panel channel selection** — select a meaningful stable, candidate, or preview release directly in the panel; the preference is stored by the DSH Host.
|
|
36
45
|
- **Compatibility labels** — explicitly verified versions are marked verified; unknown preview compatibility is marked unverified rather than claimed safe.
|
|
37
46
|
- **Copy-only guidance** — generates an installation-kind-aware `@latest`, `@next`, or `@alpha` command but never executes it.
|
|
@@ -44,7 +53,7 @@ Requirements:
|
|
|
44
53
|
|
|
45
54
|
- DeepSeek Harness with the Web profile
|
|
46
55
|
- Node.js 20 or newer
|
|
47
|
-
- Verified DSH release: `0.1.6-alpha.
|
|
56
|
+
- Verified DSH release: `0.1.6-alpha.2` (also verified on `0.1.6-alpha.1` and `0.1.5-rc.1`)
|
|
48
57
|
|
|
49
58
|
With an installed `dsh` command:
|
|
50
59
|
|
|
@@ -74,8 +83,8 @@ dsh plugin --profile web add "link:$(pwd)"
|
|
|
74
83
|
|
|
75
84
|
1. Open the DSH sidebar drawer. The official fish remains in place; the name row shows `DeepSeek` plus the current version badge.
|
|
76
85
|
2. Tap the badge. The update panel opens without triggering the parent New Session action.
|
|
77
|
-
3. Review
|
|
78
|
-
4. Select `alpha` or another
|
|
86
|
+
3. Review the offered channels. Rows are de-duplicated by version, `latest` and the channel you follow are always listed, and the channel matching the release you are running stays selectable.
|
|
87
|
+
4. Select `alpha` or another channel to follow it. The choice is stored by the DSH Host and only affects future checks; an unverified preview stays clearly marked.
|
|
79
88
|
5. Copy the generated command and run it yourself in a terminal on the computer hosting DSH.
|
|
80
89
|
6. Restart DSH yourself after the package-manager command completes.
|
|
81
90
|
|
|
@@ -89,6 +98,23 @@ npm install -g @deepseek-ai/dsh@alpha
|
|
|
89
98
|
|
|
90
99
|
The plugin displays one command that matches the detected installation kind and selected channel. It does not run these commands.
|
|
91
100
|
|
|
101
|
+
### What the dot means
|
|
102
|
+
|
|
103
|
+
The dot beside the version carries the whole status, and only the update state animates:
|
|
104
|
+
|
|
105
|
+
| Dot | State | Meaning |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| green circle | up to date | The followed channel points at the running release. The chip keeps its normal fill. |
|
|
108
|
+
| grey pulse | checking | A status read is in flight (first mount, a channel change, or **Check for updates**). |
|
|
109
|
+
| amber dot with a halo | update | The followed channel points at a newer release. Copy the command, run it yourself, restart DSH. |
|
|
110
|
+
| chip turns red | failed read | The plugin could not determine the state: the registry read failed, the channel is unpublished, or the versions are not SemVer-comparable. An *unverified* release is not this case — it is an advisory shown only in the panel. |
|
|
111
|
+
|
|
112
|
+
<p align="center">
|
|
113
|
+
<img src="./assets/sidebar-chip.png" width="300" alt="The version chip in a light shell (grey chip, dark text) and a dark shell (dark grey chip, white text), each showing the green up-to-date dot">
|
|
114
|
+
</p>
|
|
115
|
+
|
|
116
|
+
The chip itself is a neutral second-level surface — grey in both themes, with the theme's own label colour — so the amber halo always reads against it, and it never changes colour to announce an update.
|
|
117
|
+
|
|
92
118
|
## Release channels
|
|
93
119
|
|
|
94
120
|
| Channel | Purpose | Compatibility treatment |
|
|
@@ -99,6 +125,16 @@ The plugin displays one command that matches the detected installation kind and
|
|
|
99
125
|
|
|
100
126
|
The plugin honors npm dist-tags. It does not pick the numerically greatest version from registry history.
|
|
101
127
|
|
|
128
|
+
### What the panel offers
|
|
129
|
+
|
|
130
|
+
The detail panel and the settings select render the same rows:
|
|
131
|
+
|
|
132
|
+
- `latest` and the channel you currently follow are always present.
|
|
133
|
+
- Any other channel appears only when its version differs from every row above it, so a registry that points several tags at one release still reads as one choice.
|
|
134
|
+
- The channel that currently points at the release you are running stays selectable. Before `0.1.4` a row whose version equalled the running release was hidden, so an operator on an `alpha` build could not follow the `alpha` line: that row only existed once they already followed it, which left `latest` as the only other row to click.
|
|
135
|
+
|
|
136
|
+
Following a channel is a statement about **future** releases — it decides which dist-tag this plugin compares against and which command it generates. It never changes what is installed and never installs anything.
|
|
137
|
+
|
|
102
138
|
## LAN / non-loopback pages
|
|
103
139
|
|
|
104
140
|
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*). `settingsScope` then answers `unavailable` and never sends `settings.describe`, and `connection.isLoopback` reads false for the whole page.
|
|
@@ -112,27 +148,30 @@ If you want DSH's stock policy instead (a non-loopback page never persists setti
|
|
|
112
148
|
|
|
113
149
|
## Compatibility
|
|
114
150
|
|
|
115
|
-
Current release: plugin **`0.1.
|
|
151
|
+
Current release: plugin **`0.1.5`** is verified against DeepSeek Harness **`0.1.6-alpha.2`**.
|
|
116
152
|
|
|
117
153
|
### Which plugin version goes with which DeepSeek Harness version
|
|
118
154
|
|
|
119
155
|
| Plugin | Verified DeepSeek Harness | On npm | What that version is |
|
|
120
156
|
| --- | --- | --- | --- |
|
|
121
|
-
| **`0.1.
|
|
157
|
+
| **`0.1.5`** | `0.1.6-alpha.2`, `0.1.6-alpha.1`, `0.1.5-rc.1` | `latest` | One dot carries every state (green up to date, grey checking, amber breathing update), neutral grey chip surface in both themes, and advisory notices no longer repaint the chip |
|
|
158
|
+
| `0.1.4` | `0.1.6-alpha.1`, `0.1.5-rc.1` | published | Fixes the unselectable "channel you are running"; preference writes locked by tests |
|
|
159
|
+
| `0.1.3` | `0.1.6-alpha.1`, `0.1.5-rc.1` | published | Carries the `0.1.2` LAN (non-loopback) fix, re-verified on 0.1.6 and locked by tests |
|
|
122
160
|
| `0.1.2` | `0.1.5-rc.1` | **never published** | Removed the `connection.isLoopback` gate, so LAN pages work |
|
|
123
161
|
| `0.1.1` | `0.1.5-rc.1` | published | The previous npm `latest`; the plugin is inert on LAN/non-loopback pages |
|
|
124
162
|
| `0.1.0` | `0.1.2-rc.1` | published | First release |
|
|
125
163
|
|
|
126
|
-
- **Verified DeepSeek Harness** is the exact DSH release that plugin build was tested against. A
|
|
164
|
+
- **Verified DeepSeek Harness** is the exact DSH release that plugin build was tested against. The list has one source of truth in two places — `VERIFIED_DSH_VERSIONS` in [`src/shared/types.ts`](src/shared/types.ts) and `dsh.compatibility.dshReleases` in [`package.json`](package.json) — and a test keeps them identical. A release that is not on the list is not declared compatible: verify it manually first, and if it turns out incompatible, disable or uninstall the plugin rather than patching DSH core. A release that is merely *not listed yet* is reported as **unverified**: that is an advisory in the panel only, and it never repaints the chip — an operator who upgrades DSH ahead of this plugin keeps a normal chip.
|
|
127
165
|
- **On npm** is what `dsh plugin --profile web add dsh-update-status@latest` actually installs. A version that exists in this repository but not on npm is a development state, not a release.
|
|
128
166
|
- Match them explicitly when it matters:
|
|
129
167
|
|
|
130
168
|
```sh
|
|
131
|
-
dsh plugin --profile web add dsh-update-status@0.1.
|
|
169
|
+
dsh plugin --profile web add dsh-update-status@0.1.5 # DSH 0.1.6-alpha.2, 0.1.6-alpha.1 or 0.1.5-rc.1
|
|
170
|
+
dsh plugin --profile web add dsh-update-status@0.1.4 # DSH 0.1.6-alpha.1 or 0.1.5-rc.1
|
|
132
171
|
dsh plugin --profile web add dsh-update-status@0.1.0 # DSH 0.1.2-rc.1 only
|
|
133
172
|
```
|
|
134
173
|
|
|
135
|
-
- Per-release notes — what changed, who is affected, what to do — are hand-written in Chinese and English
|
|
174
|
+
- 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.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`).
|
|
136
175
|
|
|
137
176
|
## Configuration
|
|
138
177
|
|
|
@@ -144,6 +183,36 @@ Current release: plugin **`0.1.3`** is verified against DeepSeek Harness **`0.1.
|
|
|
144
183
|
|
|
145
184
|
**Settings → Version & updates** lets the local operator hide the plugin's sidebar entry and select a release channel. The panel also supports direct channel selection and a cache-duration input. Changing the duration does not issue a request; only a later normal read can refresh an expired cache, while **Check for updates** always performs an immediate manual refresh.
|
|
146
185
|
|
|
186
|
+
A preference is written only by your own selection in the panel or in that settings section. The plugin has no automatic write path — no effect, timer, or mount-time write — and `tests/client/entry.spec.ts` mounts the real client entry to keep it that way. The values live in the `dsh-update-status` namespace of `~/.dsh/settings.yaml`; edit or remove them there to reset a preference, and DSH reloads the document on the next change.
|
|
187
|
+
|
|
188
|
+
## Troubleshooting
|
|
189
|
+
|
|
190
|
+
**The chip shows a version that is not what I just installed, and tapping it does nothing.**
|
|
191
|
+
That is the `connection.isLoopback` gate from plugin `0.1.1` and earlier: on a non-loopback page such as a LAN bridge (`dsh-bridge`, `dsh-lan-proxy`) the whole plugin goes inert and the chip falls back to this bundle's declared compatible release. Check what is installed and upgrade:
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
node -p "require(process.env.HOME + '/.dsh/profiles/web/node_modules/dsh-update-status/package.json').version" # 0.1.3 or newer
|
|
195
|
+
dsh plugin --profile web add dsh-update-status@latest
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**The chip turned red right after I upgraded DSH.**
|
|
199
|
+
On `0.1.5` and newer a red chip means one thing: the plugin could not determine the update state — the registry read failed, the channel is unpublished, or the versions are not SemVer-comparable. Up to `0.1.4` the rule was broader: the client treated **any** warning as a problem, and *"this preview has not been verified against the plugin"* is exactly the warning a DSH release newer than the plugin's list produces. Upgrading DSH ahead of the plugin therefore painted the chip red even though the read had succeeded. `0.1.5` splits the two — `failure` still repaints, an advisory stays in the panel — so upgrade if you keep DSH ahead of this plugin:
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
dsh plugin --profile web add dsh-update-status@latest
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Until then, following a channel whose release is on the verified list avoids the warning.
|
|
206
|
+
|
|
207
|
+
**The channel I want is missing from the list.**
|
|
208
|
+
Rows are de-duplicated by version: when two tags point at the same release only the first is rendered. Selecting `latest` first re-projects the cache and can surface a preview row that was collapsed behind it. `0.1.4` also stopped hiding the channel that matches the running release.
|
|
209
|
+
|
|
210
|
+
**The version never changes.**
|
|
211
|
+
The Host caches one registry response, 360 minutes by default, and only a normal read can expire it. Press **Check for updates** for an immediate refresh, or lower `cacheTtlMinutes`. A failed check keeps the last good cache and shows the warning next to the version.
|
|
212
|
+
|
|
213
|
+
**Nothing reaches the npm registry.**
|
|
214
|
+
The plugin reports the failure and still shows the locally detected running version. Registry access is HTTPS-only to `registry.npmjs.org`; a proxy or offline host produces that warning rather than a wrong version.
|
|
215
|
+
|
|
147
216
|
## Security boundary
|
|
148
217
|
|
|
149
218
|
- Registry access is limited to HTTPS `registry.npmjs.org`; redirects are rejected.
|
package/README.zh.md
CHANGED
|
@@ -14,6 +14,11 @@
|
|
|
14
14
|
<a href="#功能">功能</a> ·
|
|
15
15
|
<a href="#安装">安装</a> ·
|
|
16
16
|
<a href="#使用">使用</a> ·
|
|
17
|
+
<a href="#发布通道">发布通道</a> ·
|
|
18
|
+
<a href="#局域网非回环页面访问">局域网访问</a> ·
|
|
19
|
+
<a href="#兼容性">兼容性</a> ·
|
|
20
|
+
<a href="#配置">配置</a> ·
|
|
21
|
+
<a href="#故障排查">故障排查</a> ·
|
|
17
22
|
<a href="#安全边界">安全边界</a> ·
|
|
18
23
|
<a href="#卸载">卸载</a> ·
|
|
19
24
|
<a href="docs/RELEASING.md">发布指南</a>
|
|
@@ -21,17 +26,21 @@
|
|
|
21
26
|
|
|
22
27
|
> DSH Update Status 是 DeepSeek Harness 社区插件。它不修改 DSH 核心,也绝不会安装、重启、回滚、下载或替换 DSH 文件。
|
|
23
28
|
|
|
24
|
-
插件只把展开侧栏中的品牌名称换成适配 24px 品牌行的 `DeepSeek +
|
|
29
|
+
插件只把展开侧栏中的品牌名称换成适配 24px 品牌行的 `DeepSeek + 版本芯片`,官方鱼标保持不变。版本号旁的**绿点**表示无事可做,**橙色呼吸圆点**表示线上有新版本。点击芯片可查看 npm 发布通道、兼容性状态,以及与所选通道对应的“仅复制”命令。
|
|
25
30
|
|
|
26
31
|
<p align="center">
|
|
27
|
-
<img src="./assets/update-panel.png" width="
|
|
32
|
+
<img src="./assets/update-panel.png" width="400" alt="DSH Update Status 面板:缓存时长、正在运行的 0.1.6-alpha.2(alpha 通道)、与所选通道不一致的 latest 行、兼容性标签和仅复制的升级命令">
|
|
28
33
|
</p>
|
|
29
34
|
|
|
30
35
|
## 功能
|
|
31
36
|
|
|
32
37
|
- **侧栏版本状态**:展开侧栏显示当前 DSH 版本,收起轨道提供状态入口。
|
|
38
|
+
- **安静的更新提示**:有新版本时**不改变版本 Badge 的背景**,只在版本号旁保留一个带小光晕的橙色圆点做放大缩小的呼吸动画(`prefers-reduced-motion` 下停用动画),让新版本表现为一盏小灯,而不是整条品牌行换色。
|
|
39
|
+
- **一眼三态**:没有可做的事时,版本号旁是**纯绿色小圆圈**(取主题 success 色,不再跟随文字色——暗色外壳下不会再出现一个看起来像「熄灭」的深色点);检查中是中性灰呼吸点;有新版本才是橙色光晕呼吸点。只有更新态会动、会发光,也只有状态读取失败才会把 Badge 重绘成红色。
|
|
40
|
+
- **中性版本底框**:Badge 在明暗两套主题下都用灰色二级面(浅色 `#f1f3f5` / 深色 `#353638`)配主题常规文字色,所以暗色下是「深灰底 + 白字」,不再是会把橙色光晕吃掉的白框;只有状态读取失败时才会重绘成红色。
|
|
41
|
+
- **浅色 / 深色 / 跟随系统,自动适配**:插件渲染的每个颜色都是 DSH 语义令牌,Badge、圆点、光晕、收起轨道圆环与面板都按 DSH 当前外观解析。DSH 设为浅色、深色或跟随系统,插件就跟着切换——插件侧没有自己的主题开关,也没有需要同步的媒体查询。hover 在两个方向上都是「抬起」:浅色下压深、深色下提亮(把主题文字色按比例混进底色实现)。
|
|
33
42
|
- **稳定版与预览版发现**:一次 registry 请求读取 npm dist-tags `latest`、`next`、`alpha`,默认选择 `latest`。
|
|
34
|
-
-
|
|
43
|
+
- **只展示有意义的选择**:按版本号去重;`latest` 与你当前跟随的通道始终保留,并且**不会隐藏与你正在运行的版本相符的那条通道**。
|
|
35
44
|
- **弹窗内直接选择通道**:可直接选择有价值的稳定版、候选版或预览版;偏好由 DSH Host 持久化。
|
|
36
45
|
- **兼容性标识**:明确验证过的版本显示“已验证兼容”;未知预览版显示“尚未验证兼容”,不冒充安全升级。
|
|
37
46
|
- **仅复制命令**:根据安装来源和通道生成 `@latest`、`@next` 或 `@alpha` 命令,但从不执行。
|
|
@@ -44,7 +53,7 @@
|
|
|
44
53
|
|
|
45
54
|
- 带 Web profile 的 DeepSeek Harness
|
|
46
55
|
- Node.js 20 或更新版本
|
|
47
|
-
- 已验证的 DSH 版本:`0.1.6-alpha.
|
|
56
|
+
- 已验证的 DSH 版本:`0.1.6-alpha.2`(同时验证了 `0.1.6-alpha.1` 与 `0.1.5-rc.1`)
|
|
48
57
|
|
|
49
58
|
已经安装 `dsh` 命令:
|
|
50
59
|
|
|
@@ -74,8 +83,8 @@ dsh plugin --profile web add "link:$(pwd)"
|
|
|
74
83
|
|
|
75
84
|
1. 打开 DSH 左侧抽屉。官方鱼标仍在;名称行显示 `DeepSeek + 当前版本 Badge`。
|
|
76
85
|
2. 点击 Badge。面板打开时不会触发外层“新建会话”按钮。
|
|
77
|
-
3.
|
|
78
|
-
4.
|
|
86
|
+
3. 查看可选的通道。列表按版本号去重,`latest` 与你当前跟随的通道始终在列,且与你正在运行的版本相符的那条通道一定可选。
|
|
87
|
+
4. 想跟随某个通道(例如 `alpha`)就在面板里直接选它。该选择由 DSH Host 持久化,只影响后续检查;未验证兼容的预览版仍会明确标注。
|
|
79
88
|
5. 复制生成的命令,在**运行 DSH 的那台电脑**的终端中自行执行。
|
|
80
89
|
6. 包管理器命令完成后,由你自行重启 DSH。
|
|
81
90
|
|
|
@@ -89,6 +98,23 @@ npm install -g @deepseek-ai/dsh@alpha
|
|
|
89
98
|
|
|
90
99
|
插件只显示与检测到的安装方式和所选通道匹配的一条命令,不会运行这些命令。
|
|
91
100
|
|
|
101
|
+
### 圆点含义
|
|
102
|
+
|
|
103
|
+
版本号旁那颗圆点承载全部状态,且只有更新态会动:
|
|
104
|
+
|
|
105
|
+
| 圆点 | 状态 | 含义 |
|
|
106
|
+
| --- | --- | --- |
|
|
107
|
+
| 绿色小圆圈 | 已是最新 | 你跟随的通道指向正在运行的版本,芯片保持原底色。 |
|
|
108
|
+
| 灰点呼吸 | 检查中 | 状态读取正在进行(首次挂载、切换通道,或点了**检查更新**)。 |
|
|
109
|
+
| 橙色圆点 + 光晕 | 有更新 | 你跟随的通道指向更新的版本。自行复制命令、执行,然后重启 DSH。 |
|
|
110
|
+
| 芯片变红 | 读取失败 | 插件无法判定状态:registry 读取失败、该通道未发布,或两个版本无法按 SemVer 比较。**未验证兼容**不属于这一档——它只是面板里的提示。 |
|
|
111
|
+
|
|
112
|
+
<p align="center">
|
|
113
|
+
<img src="./assets/sidebar-chip.png" width="300" alt="版本芯片在浅色外壳(浅灰底、深色字)与深色外壳(深灰底、白字)下的样子,右侧都是表示已是最新的绿点">
|
|
114
|
+
</p>
|
|
115
|
+
|
|
116
|
+
芯片本身是中性二级面——两套主题都是灰色,文字用主题常规色——所以橙色光晕始终看得清,而且它绝不会为了宣布更新而改变颜色。
|
|
117
|
+
|
|
92
118
|
## 发布通道
|
|
93
119
|
|
|
94
120
|
| 通道 | 用途 | 兼容性处理 |
|
|
@@ -99,6 +125,16 @@ npm install -g @deepseek-ai/dsh@alpha
|
|
|
99
125
|
|
|
100
126
|
插件严格遵循 npm dist-tag,不会从 registry 历史版本中自行挑选 SemVer 最大值。
|
|
101
127
|
|
|
128
|
+
### 面板里会出现哪些行
|
|
129
|
+
|
|
130
|
+
详情面板与设置页下拉框渲染的是同一份列表:
|
|
131
|
+
|
|
132
|
+
- `latest` 与你当前跟随的通道始终保留。
|
|
133
|
+
- 其它通道只有在版本号与它上面的每一行都不同时才出现,因此多个 dist-tag 指向同一版本时仍然只呈现为一个选择。
|
|
134
|
+
- 与你**正在运行的版本**相符的那条通道一定可选。在 `0.1.4` 之前,版本号等于运行版本的通道会被隐藏:运行 `alpha` 构建的人因此无法关注 `alpha` 线——那行只有在他已关注之后才存在,剩下能点的只有 `latest`。
|
|
135
|
+
|
|
136
|
+
跟随通道是对**将来**的声明:它决定本插件用哪个 dist-tag 做比较、生成哪条升级命令;它不会改变已安装的版本,也不会安装任何东西。
|
|
137
|
+
|
|
102
138
|
## 局域网(非回环页面)访问
|
|
103
139
|
|
|
104
140
|
DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Host 设置持久化(官方 `dsh-client-ui-settings` README 原文:*Non-loopback pages get no durable settings*):`settingsScope` 直接返回 `unavailable`,并且从此不发 `settings.describe`;整页的 `connection.isLoopback` 也都是 false。
|
|
@@ -112,27 +148,30 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
|
|
|
112
148
|
|
|
113
149
|
## 兼容性
|
|
114
150
|
|
|
115
|
-
当前发布:插件 **`0.1.
|
|
151
|
+
当前发布:插件 **`0.1.5`** 已针对 DeepSeek Harness **`0.1.6-alpha.2`** 验证。
|
|
116
152
|
|
|
117
153
|
### 插件版本与 DeepSeek Harness 版本的对应关系
|
|
118
154
|
|
|
119
155
|
| 插件版本 | 已验证的 DeepSeek Harness | npm 发布状态 | 该版本是什么 |
|
|
120
156
|
| --- | --- | --- | --- |
|
|
121
|
-
| **`0.1.
|
|
157
|
+
| **`0.1.5`** | `0.1.6-alpha.2`、`0.1.6-alpha.1`、`0.1.5-rc.1` | `latest` | 一颗圆点承载全部状态(绿=已是最新、灰=检查中、橙=有新版本)、两套主题都用中性灰底框、提示性告警不再重绘芯片 |
|
|
158
|
+
| `0.1.4` | `0.1.6-alpha.1`、`0.1.5-rc.1` | 已发布 | 修复「正在运行的通道不可选」;偏好写入路径补齐回归测试 |
|
|
159
|
+
| `0.1.3` | `0.1.6-alpha.1`、`0.1.5-rc.1` | 已发布 | 含 `0.1.2` 的局域网(非回环)修复,并在 0.1.6 上复验、补上回归测试 |
|
|
122
160
|
| `0.1.2` | `0.1.5-rc.1` | **未发布** | 移除 `connection.isLoopback` 门控,局域网页面可用 |
|
|
123
161
|
| `0.1.1` | `0.1.5-rc.1` | 已发布 | 此前 npm 上的 `latest`;局域网/非回环页面下插件整体不可用 |
|
|
124
162
|
| `0.1.0` | `0.1.2-rc.1` | 已发布 | 首个版本 |
|
|
125
163
|
|
|
126
|
-
- **已验证的 DeepSeek Harness** 是该插件构建实际测试过的确切 DSH
|
|
164
|
+
- **已验证的 DeepSeek Harness** 是该插件构建实际测试过的确切 DSH 版本。这份清单只有两个存放处——[`src/shared/types.ts`](src/shared/types.ts) 的 `VERIFIED_DSH_VERSIONS` 与 [`package.json`](package.json) 的 `dsh.compatibility.dshReleases`——并有测试保证两者一致。未列出的 DSH 版本不会被宣称为兼容:请先人工验证;确认不兼容时请禁用或卸载插件,不要修改 DSH 核心。若只是**尚未列入**,插件会标为「尚未验证兼容」:这是**只出现在面板里**的提示,绝不会重绘芯片——DSH 升级快于插件时,芯片依然保持正常外观。
|
|
127
165
|
- **npm 发布状态** 是 `dsh plugin --profile web add dsh-update-status@latest` 实际会装到的版本。只存在于本仓库、尚未发布到 npm 的版本属于开发状态,不是发布版本。
|
|
128
166
|
- 需要精确对应时显式指定版本:
|
|
129
167
|
|
|
130
168
|
```sh
|
|
131
|
-
dsh plugin --profile web add dsh-update-status@0.1.
|
|
169
|
+
dsh plugin --profile web add dsh-update-status@0.1.5 # DSH 0.1.6-alpha.2、0.1.6-alpha.1 或 0.1.5-rc.1
|
|
170
|
+
dsh plugin --profile web add dsh-update-status@0.1.4 # DSH 0.1.6-alpha.1 或 0.1.5-rc.1
|
|
132
171
|
dsh plugin --profile web add dsh-update-status@0.1.0 # 仅 DSH 0.1.2-rc.1
|
|
133
172
|
```
|
|
134
173
|
|
|
135
|
-
-
|
|
174
|
+
- 每个版本的中英文详细说明(改了什么、影响谁、需要做什么)手写后直接作为 GitHub Release 正文:[`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`)。
|
|
136
175
|
|
|
137
176
|
## 配置
|
|
138
177
|
|
|
@@ -144,6 +183,36 @@ DSH 对来源不是 loopback(`localhost` / `127.0.0.1`)的页面会关闭 Ho
|
|
|
144
183
|
|
|
145
184
|
**设置 → 版本与更新** 可隐藏本插件侧栏入口和选择发布通道;详情面板中也能直接切换通道和填写缓存时长。修改缓存时长不会请求网络;只在之后普通读取且缓存已到期时更新,“检查更新”始终是立即手动检查。
|
|
146
185
|
|
|
186
|
+
偏好只会在你于面板或该设置区块中主动选择时写入。插件没有任何自动写入路径——没有 effect、定时器,也不在挂载时写入,并由 `tests/client/entry.spec.ts` 挂载真实客户端入口长期守住这一点。这些值存放在 `~/.dsh/settings.yaml` 的 `dsh-update-status` 命名空间里;要重置某个偏好,直接在那里修改或删除即可,DSH 会在下次变更时重新加载该文档。
|
|
187
|
+
|
|
188
|
+
## 故障排查
|
|
189
|
+
|
|
190
|
+
**胶囊显示的版本不是我刚装的,而且点了没有反应。**
|
|
191
|
+
这是插件 `0.1.1` 及更早版本的 `connection.isLoopback` 门控:在非回环页面(如 `dsh-bridge`、`dsh-lan-proxy` 这类局域网转发)上整个插件会失效,胶囊退回显示本包声明的兼容版本。先确认已装版本再升级:
|
|
192
|
+
|
|
193
|
+
```sh
|
|
194
|
+
node -p "require(process.env.HOME + '/.dsh/profiles/web/node_modules/dsh-update-status/package.json').version" # 需要 0.1.3 或更新
|
|
195
|
+
dsh plugin --profile web add dsh-update-status@latest
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**升级 DSH 之后芯片变红了。**
|
|
199
|
+
在 `0.1.5` 及更新版本上,红色只代表一件事:插件无法判定状态——registry 读取失败、该通道未发布,或两个版本无法按 SemVer 比较。`0.1.4` 及更早版本的判定更宽:客户端把**任何**警告都当成故障,而「这个预览版尚未验证与本插件兼容」正是 DSH 版本比插件清单更新时必然产生的警告。所以「DSH 先升级、插件还没跟上」就会把芯片涂红,哪怕读取其实成功了。`0.1.5` 把两者分开——`failure` 仍然重绘,提示只留在面板——因此长期让 DSH 领先的用法请升级:
|
|
200
|
+
|
|
201
|
+
```sh
|
|
202
|
+
dsh plugin --profile web add dsh-update-status@latest
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
在那之前,跟随一个发布版在已验证清单里的通道即可避免该警告。
|
|
206
|
+
|
|
207
|
+
**想要的通道不在列表里。**
|
|
208
|
+
列表按版本号去重:两个 dist-tag 指向同一版本时只渲染第一个。先选一次 `latest` 会重新投影缓存,可能让被折叠在后面的预览行出现。另外 `0.1.4` 起,与运行版本相符的那条通道不再被隐藏。
|
|
209
|
+
|
|
210
|
+
**版本一直不变。**
|
|
211
|
+
Host 会缓存一次 registry 响应,默认 360 分钟,且只有普通读取才会判断到期。点**检查更新**可立即刷新,或调小 `cacheTtlMinutes`。检查失败时会保留上一次成功缓存,并在版本号旁显示警告。
|
|
212
|
+
|
|
213
|
+
**完全连不上 npm registry。**
|
|
214
|
+
插件会报告失败,并仍然显示本地检测到的运行版本。registry 访问只允许 HTTPS 的 `registry.npmjs.org`;代理或离线环境会给出这条警告,而不是编造一个版本号。
|
|
215
|
+
|
|
147
216
|
## 安全边界
|
|
148
217
|
|
|
149
218
|
- registry 访问只允许 HTTPS `registry.npmjs.org`,并拒绝重定向。
|
|
Binary file
|
package/assets/update-panel.png
CHANGED
|
Binary file
|
package/docs/RELEASING.md
CHANGED
|
@@ -133,7 +133,7 @@ The final command must print:
|
|
|
133
133
|
dsh-update-status X.Y.Z web
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
Then install the package in a disposable DSH profile and manually verify the sidebar badge, panel, release-channel selection, cache-duration setting, and mobile drawer behavior:
|
|
136
|
+
Then install the package in a disposable DSH profile and manually verify the sidebar badge, its three dot states (green when up to date, grey pulse while checking, amber halo when a newer release exists — the chip fill itself must not change), the panel, release-channel selection, cache-duration setting, and mobile drawer behavior:
|
|
137
137
|
|
|
138
138
|
```sh
|
|
139
139
|
TEST_HOME="$(mktemp -d)"
|
package/lib/client.js
CHANGED
|
@@ -12,8 +12,16 @@ window.__ModuleLoader__.load({
|
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Reduce raw dist-tags to user-meaningful choices without losing Host facts.
|
|
15
|
-
* The selected channel and stable return path are
|
|
16
|
-
*
|
|
15
|
+
* The selected channel and stable return path are always present; every other
|
|
16
|
+
* row must carry a version no earlier row already shows.
|
|
17
|
+
*
|
|
18
|
+
* A channel is deliberately NOT hidden just because it currently points at the
|
|
19
|
+
* release that is running. Following a channel is a statement about future
|
|
20
|
+
* releases, and `currentVersion` still rides the input for the caller's own
|
|
21
|
+
* rendering, but filtering on it created a deadlock: while running the version
|
|
22
|
+
* published on `alpha`, the `alpha` row disappeared, so the one channel a user
|
|
23
|
+
* on that line would want to follow could never be selected — the only way to
|
|
24
|
+
* see it was to already follow it.
|
|
17
25
|
*/
|
|
18
26
|
function visibleChannelReleases(status) {
|
|
19
27
|
const ordered = [...status.channels].sort((left, right) => CHANNEL_ORDER[left.channel] - CHANNEL_ORDER[right.channel]);
|
|
@@ -21,7 +29,7 @@ window.__ModuleLoader__.load({
|
|
|
21
29
|
const visible = ordered.filter((release) => mandatory.has(release.channel));
|
|
22
30
|
const seenVersions = new Set(visible.map((release) => release.version).filter((version) => version !== null));
|
|
23
31
|
for (const release of ordered) {
|
|
24
|
-
if (mandatory.has(release.channel) || release.version === null
|
|
32
|
+
if (mandatory.has(release.channel) || release.version === null) continue;
|
|
25
33
|
if (seenVersions.has(release.version)) continue;
|
|
26
34
|
visible.push(release);
|
|
27
35
|
seenVersions.add(release.version);
|
|
@@ -80,6 +88,25 @@ window.__ModuleLoader__.load({
|
|
|
80
88
|
return null;
|
|
81
89
|
}
|
|
82
90
|
//#endregion
|
|
91
|
+
//#region src/shared/visual-state.ts
|
|
92
|
+
/**
|
|
93
|
+
* Only a read the plugin could not complete is a chip-level problem.
|
|
94
|
+
*
|
|
95
|
+
* An advisory notice — a preview channel this bundle has not been verified against,
|
|
96
|
+
* say — leaves the chip surface alone and belongs in the panel. Repainting the brand
|
|
97
|
+
* row for a plugin-side bookkeeping fact is the surprise the breathing dot replaced:
|
|
98
|
+
* an operator who upgrades DSH ahead of this bundle must not watch the chip turn red.
|
|
99
|
+
*
|
|
100
|
+
* A Host older than `warningKind` sends no field at all; `undefined` then keeps the
|
|
101
|
+
* previous behaviour (any warning is a problem) rather than silently dropping a real
|
|
102
|
+
* failure on the floor.
|
|
103
|
+
*/
|
|
104
|
+
function isChipProblem(status) {
|
|
105
|
+
if (status === null) return false;
|
|
106
|
+
if (status.warningKind === void 0) return status.warning !== null;
|
|
107
|
+
return status.warningKind === "failure";
|
|
108
|
+
}
|
|
109
|
+
//#endregion
|
|
83
110
|
//#region src/client/i18n.ts
|
|
84
111
|
const DICTIONARY = {
|
|
85
112
|
"brand.status": {
|
|
@@ -410,7 +437,7 @@ window.__ModuleLoader__.load({
|
|
|
410
437
|
}
|
|
411
438
|
function visualState(status, loading, error) {
|
|
412
439
|
if (loading) return "loading";
|
|
413
|
-
if (error !== null || status
|
|
440
|
+
if (error !== null || isChipProblem(status)) return status?.hasUpdate === true ? "update" : "problem";
|
|
414
441
|
return status?.hasUpdate === true ? "update" : "current";
|
|
415
442
|
}
|
|
416
443
|
function badgeLabel(status, loading, error) {
|
|
@@ -458,6 +485,7 @@ window.__ModuleLoader__.load({
|
|
|
458
485
|
children: shortVersion(version)
|
|
459
486
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
460
487
|
className: "dus-dot",
|
|
488
|
+
"data-state": state,
|
|
461
489
|
"data-update": snapshot.status?.hasUpdate === true || void 0,
|
|
462
490
|
"data-loading": snapshot.loading || void 0,
|
|
463
491
|
"aria-hidden": "true"
|
|
@@ -486,6 +514,7 @@ window.__ModuleLoader__.load({
|
|
|
486
514
|
children: "↟"
|
|
487
515
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
488
516
|
className: "dus-dot dus-footer-dot",
|
|
517
|
+
"data-state": state,
|
|
489
518
|
"data-update": snapshot.status?.hasUpdate === true || void 0,
|
|
490
519
|
"data-loading": state === "loading" || void 0
|
|
491
520
|
})]
|
|
@@ -933,6 +962,7 @@ window.__ModuleLoader__.load({
|
|
|
933
962
|
const latestVersion = record.latestVersion === null ? null : stringOrNull(record.latestVersion);
|
|
934
963
|
const checkedAt = record.checkedAt === null ? null : stringOrNull(record.checkedAt);
|
|
935
964
|
const warning = record.warning === null ? null : stringOrNull(record.warning);
|
|
965
|
+
const warningKind = record.warningKind === "failure" || record.warningKind === "notice" ? record.warningKind : void 0;
|
|
936
966
|
const publishedAt = record.publishedAt === null ? null : stringOrNull(record.publishedAt);
|
|
937
967
|
if (record.latestVersion !== null && latestVersion === null || record.checkedAt !== null && checkedAt === null || record.warning !== null && warning === null || record.publishedAt !== null && publishedAt === null) return void 0;
|
|
938
968
|
const channels = [];
|
|
@@ -956,6 +986,7 @@ window.__ModuleLoader__.load({
|
|
|
956
986
|
cached: record.cached,
|
|
957
987
|
checkedAt,
|
|
958
988
|
warning,
|
|
989
|
+
warningKind,
|
|
959
990
|
installKind: record.installKind,
|
|
960
991
|
upgradeCommand: record.upgradeCommand,
|
|
961
992
|
releaseUrl: record.releaseUrl,
|
|
@@ -1553,17 +1584,55 @@ window.__ModuleLoader__.load({
|
|
|
1553
1584
|
const UPDATE_STATUS_CSS = `
|
|
1554
1585
|
.dus-brand-name{align-items:center;gap:6px;height:24px;max-width:100%;min-width:0;display:inline-flex}
|
|
1555
1586
|
.dus-brand-deepseek{font-size:14px;font-weight:650;letter-spacing:-.015em;line-height:24px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1556
|
-
|
|
1587
|
+
/* The chip is a NEUTRAL SECOND-LEVEL SURFACE, never a high-contrast pill. It used
|
|
1588
|
+
to be label-primary + label-primary-inverted, which is a near-white box with dark
|
|
1589
|
+
text on the dark shell — a white frame that swallows the amber halo and fights the
|
|
1590
|
+
warn colour. --dsw-alias-button-floating-hover is the one palette surface that is
|
|
1591
|
+
grey in BOTH themes (#f1f3f5 light / #353638 dark), matching the reference: a light
|
|
1592
|
+
grey chip on the light shell, a dark grey chip with white text on the dark one. The
|
|
1593
|
+
sibling button-floating-fill is pure white in light mode and changes nothing there.
|
|
1594
|
+
Text stays label-primary (#0f1115 light / #f9fafb dark), so it is never low-contrast.
|
|
1595
|
+
Every colour here is a theme token, so the chip follows whatever appearance DSH
|
|
1596
|
+
resolves — light, dark, or system-follows-the-OS — with no plugin-side detection,
|
|
1597
|
+
no media query and no per-theme branch to keep in sync. */
|
|
1598
|
+
.dus-badge{--dus-badge-surface:var(--dsw-alias-button-floating-hover,#f1f3f5);align-items:center;background:var(--dus-badge-surface);border:0;border-radius:4px;color:var(--dsw-alias-label-primary,#0f1115);cursor:pointer;display:inline-flex;flex:none;font-family:var(--ds-font-family-code,var(--dsw-font-family-mono,ui-monospace,SFMono-Regular,Menlo,monospace));font-size:10px;font-variant-numeric:tabular-nums;font-weight:600;gap:4px;height:16px;line-height:16px;max-width:140px;outline:none;padding:0 6px;touch-action:manipulation;user-select:none;white-space:nowrap}
|
|
1557
1599
|
.dus-badge:focus-visible,.dus-footer-button:focus-visible,.dus-action:focus-visible,.dus-close:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:2px}
|
|
1600
|
+
/* Hover has to read as "raised" in BOTH themes. brightness() only ever brightens, and on
|
|
1601
|
+
the light shell it turns the grey chip pure white — the chip all but disappears. Mixing
|
|
1602
|
+
a little of the theme's own label colour into the surface darkens it in light mode and
|
|
1603
|
+
lightens it in dark mode, so one declaration stays correct in both. The brightness
|
|
1604
|
+
filter remains the fallback: an engine without color-mix drops only the second
|
|
1605
|
+
declaration, never the whole hover rule. */
|
|
1558
1606
|
.dus-badge:hover{filter:brightness(1.08)}
|
|
1559
|
-
.dus-badge
|
|
1560
|
-
|
|
1607
|
+
@supports (background:color-mix(in srgb,red 50%,transparent)){.dus-badge:hover{background:color-mix(in srgb,var(--dsw-alias-label-primary) 8%,var(--dus-badge-surface));filter:none}}
|
|
1608
|
+
/* The failure state is the one deliberate repaint, and it follows the shell's own
|
|
1609
|
+
badge pattern (brokenBadge): error fill with a bg-layer-3 label, which is white
|
|
1610
|
+
text on the dark red of the light theme and dark text on the light red of the dark
|
|
1611
|
+
theme — readable in both, unlike the fixed white text it replaces. */
|
|
1612
|
+
.dus-badge[data-error=true]{background:var(--dsw-alias-state-error-primary,#dc2626);color:var(--dsw-alias-bg-layer-3,#fff)}
|
|
1561
1613
|
.dus-badge-version{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
1562
1614
|
.dus-dot{background:currentColor;border-radius:50%;display:inline-block;flex:0 0 auto;height:5px;opacity:.9;width:5px}
|
|
1563
|
-
|
|
1615
|
+
/* An available update repaints NOTHING: the chip keeps its normal fill and only
|
|
1616
|
+
the amber dot breathes. The halo is animated with the dot so the glow grows
|
|
1617
|
+
and shrinks as one light, never as a separate ripple. The update state is
|
|
1618
|
+
declared AFTER the loading state, so a re-check on a known update keeps the
|
|
1619
|
+
amber glow instead of falling back to the neutral loading pulse.
|
|
1620
|
+
Each box-shadow is declared twice: a literal amber first for any engine
|
|
1621
|
+
without color-mix, then the halo mixed from the theme's own warn colour so the
|
|
1622
|
+
glow always matches the dot in both light and dark themes. */
|
|
1623
|
+
/* The dot carries the whole status. Three states, in precedence order:
|
|
1624
|
+
up to date = a plain green circle (success token, never the text colour, so a
|
|
1625
|
+
dark theme no longer paints a black dot that reads as "off"); checking = the
|
|
1626
|
+
neutral grey pulse; a pending update = the amber dot below, which is the only
|
|
1627
|
+
state allowed to breathe or glow.
|
|
1628
|
+
The up-to-date rule is declared BEFORE loading and update: equal specificity, so
|
|
1629
|
+
the later, louder states win if two ever land on the same dot. */
|
|
1630
|
+
.dus-dot[data-state=current]{background:var(--dsw-alias-state-success-primary,#22c55e);opacity:1}
|
|
1564
1631
|
.dus-dot[data-loading=true]{animation:dus-pulse .9s ease-in-out infinite}
|
|
1632
|
+
.dus-dot[data-update=true]{--dus-update-color:var(--dsw-alias-state-warn-primary,#f59e0b);animation:dus-update-pulse 1.6s ease-in-out infinite;background:var(--dus-update-color);height:6px;opacity:1;width:6px}
|
|
1565
1633
|
@keyframes dus-pulse{0%,100%{opacity:.45;transform:scale(.82)}50%{opacity:1;transform:scale(1.15)}}
|
|
1566
|
-
@
|
|
1634
|
+
@keyframes dus-update-pulse{0%,100%{box-shadow:0 0 2px 0 rgba(245,158,11,.4);box-shadow:0 0 2px 0 color-mix(in srgb,var(--dus-update-color) 45%,transparent);transform:scale(.8)}50%{box-shadow:0 0 7px 2px rgba(245,158,11,.72);box-shadow:0 0 7px 2px color-mix(in srgb,var(--dus-update-color) 72%,transparent);transform:scale(1.15)}}
|
|
1635
|
+
@media (prefers-reduced-motion:reduce){.dus-dot[data-update=true],.dus-dot[data-loading=true]{animation:none}.dus-dot[data-update=true]{box-shadow:0 0 5px 1px rgba(245,158,11,.6);box-shadow:0 0 5px 1px color-mix(in srgb,var(--dus-update-color) 62%,transparent)}}
|
|
1567
1636
|
.dus-footer-button{align-items:center;background:transparent;border:0;border-radius:10px;color:var(--dsw-alias-label-secondary);cursor:pointer;display:flex;height:44px;justify-content:center;min-height:44px;min-width:44px;padding:0;position:relative;touch-action:manipulation;width:44px}
|
|
1568
1637
|
.dus-footer-button:hover{background:var(--dsw-alias-button-floating-hover);color:var(--dsw-alias-label-primary)}
|
|
1569
1638
|
.dus-footer-icon{font-size:18px;line-height:1}
|