dsh-update-status 0.1.0

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 ADDED
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ ## 0.1.0 — 2026-09-10
6
+
7
+ - Added a static DeepSeek Harness Web Cordis plugin with a read-only Host update-status service.
8
+ - Added npm `latest`, `next`, and `alpha` dist-tag discovery through one HTTPS-allowlisted, timeout-bounded registry request.
9
+ - Added a six-hour process cache, single-flight behavior, prerelease-aware SemVer comparison, and failed-refresh fallback.
10
+ - Added `sidebar.brand.name` replacement (`DeepSeek + status Badge`) without replacing the official fish mark.
11
+ - Added a collapsed-rail `sidebar.footer.action` fallback.
12
+ - Added a modal top-layer detail panel and safe-area-aware mobile bottom sheet that stays above the sidebar drawer.
13
+ - Added persisted channel selection in Settings and directly in the detail panel.
14
+ - Added meaningful-channel filtering: redundant same-version candidates are hidden and duplicate releases favor `latest`.
15
+ - Added verified/unverified compatibility labels and channel-specific copy-only commands.
16
+ - Added automated tests for Host RPC, registry parsing, caching, channel projection, client stores, SemVer, and channel presentation.
17
+
18
+ No package-manager execution, automatic installation, restart, rollback, release download, or in-place file replacement is implemented.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-update-status contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,149 @@
1
+ <h1 align="center">DSH Update Status</h1>
2
+
3
+ <p align="center">A read-only version badge and release-channel guide for the DeepSeek Harness Web sidebar.</p>
4
+
5
+ <p align="center">
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>
7
+ <a href="https://github.com/idoall/dsh-update-status/actions/workflows/ci.yml"><img src="https://github.com/idoall/dsh-update-status/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
8
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0F172A" alt="MIT"></a>
9
+ </p>
10
+
11
+ <p align="center">English | <a href="README.zh.md">中文</a></p>
12
+
13
+ <p align="center">
14
+ <a href="#features">Features</a> ·
15
+ <a href="#install">Install</a> ·
16
+ <a href="#usage">Usage</a> ·
17
+ <a href="#security-boundary">Security</a> ·
18
+ <a href="#uninstall">Uninstall</a> ·
19
+ <a href="docs/RELEASING.md">Release guide</a>
20
+ </p>
21
+
22
+ > 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
+
24
+ It replaces only the expanded sidebar wordmark text with `DeepSeek` plus a compact version badge while leaving the official fish mark untouched. Tap the badge to inspect npm release channels, compatibility status, and a copy-only command for the selected channel.
25
+
26
+ <p align="center">
27
+ <img src="./assets/update-panel.png" width="500" alt="DSH Update Status panel showing the current stable release, an alpha preview, compatibility labels, and a copy-only upgrade command">
28
+ </p>
29
+
30
+ ## Features
31
+
32
+ - **Visible version status** — shows the running DSH version in the expanded sidebar and a fallback action in the collapsed rail.
33
+ - **Stable and preview discovery** — reads npm dist-tags `latest`, `next`, and `alpha` in one registry request; `latest` is the default.
34
+ - **Useful choices only** — hides a non-selected candidate when it equals the running version, and collapses duplicate releases in favor of `latest`.
35
+ - **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
+ - **Compatibility labels** — explicitly verified versions are marked verified; unknown preview compatibility is marked unverified rather than claimed safe.
37
+ - **Copy-only guidance** — generates an installation-kind-aware `@latest`, `@next`, or `@alpha` command but never executes it.
38
+ - **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.
39
+ - **Mobile-safe panel** — uses a modal browser top layer so the scrollable, safe-area-aware bottom sheet stays above the DSH drawer.
40
+
41
+ ## Install
42
+
43
+ Requirements:
44
+
45
+ - DeepSeek Harness with the Web profile
46
+ - Node.js 20 or newer
47
+ - Verified DSH release: `0.1.2-rc.1`
48
+
49
+ With an installed `dsh` command:
50
+
51
+ ```sh
52
+ dsh plugin --profile web add dsh-update-status@latest
53
+ ```
54
+
55
+ From a DeepSeek Harness source checkout:
56
+
57
+ ```sh
58
+ corepack enable
59
+ pnpm install
60
+ pnpm dsh plugin --profile web add dsh-update-status@latest
61
+ ```
62
+
63
+ Restart the existing DSH process after installation, then refresh its Web GUI. Do not start a second Web server for this plugin.
64
+
65
+ Local development link:
66
+
67
+ ```sh
68
+ pnpm install --frozen-lockfile
69
+ pnpm run build
70
+ dsh plugin --profile web add "link:$(pwd)"
71
+ ```
72
+
73
+ ## Usage
74
+
75
+ 1. Open the DSH sidebar drawer. The official fish remains in place; the name row shows `DeepSeek` plus the current version badge.
76
+ 2. Tap the badge. The update panel opens without triggering the parent New Session action.
77
+ 3. Review meaningful channels. If `next` points to the same release as the running/stable version, it is intentionally omitted.
78
+ 4. Select `alpha` or another available channel if you want to evaluate it. An unverified preview remains clearly marked.
79
+ 5. Copy the generated command and run it yourself in a terminal on the computer hosting DSH.
80
+ 6. Restart DSH yourself after the package-manager command completes.
81
+
82
+ Example commands generated for a global install:
83
+
84
+ ```sh
85
+ npm install -g @deepseek-ai/dsh@latest
86
+ npm install -g @deepseek-ai/dsh@next
87
+ npm install -g @deepseek-ai/dsh@alpha
88
+ ```
89
+
90
+ The plugin displays one command that matches the detected installation kind and selected channel. It does not run these commands.
91
+
92
+ ## Release channels
93
+
94
+ | Channel | Purpose | Compatibility treatment |
95
+ | --- | --- | --- |
96
+ | `latest` | Default stable/candidate recommended by the DSH npm package | Verified only when explicitly declared by this plugin |
97
+ | `next` | Candidate release when it differs meaningfully from the running/stable release | May be unverified |
98
+ | `alpha` | Opt-in preview for early evaluation | Unverified unless explicitly declared otherwise |
99
+
100
+ The plugin honors npm dist-tags. It does not pick the numerically greatest version from registry history.
101
+
102
+ ## Compatibility
103
+
104
+ | Plugin | Verified DeepSeek Harness |
105
+ | --- | --- |
106
+ | `0.1.0` | `0.1.2-rc.1` |
107
+
108
+ A newer DSH version is not automatically declared compatible. Verify it manually first. If the plugin is incompatible, disable or uninstall it rather than patching DSH core.
109
+
110
+ ## Configuration
111
+
112
+ | Option | Default | Range / behavior |
113
+ | --- | --- | --- |
114
+ | `cacheTtlMinutes` | `360` | 30–1,440 minutes; expires only for the next on-demand read, never a background timer |
115
+ | `channel` | `latest` | `latest`, `next`, or `alpha` |
116
+ | `sidebarEnabled` | `true` | Hides only this plugin's sidebar entry |
117
+
118
+ **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.
119
+
120
+ ## Security boundary
121
+
122
+ - Registry access is limited to HTTPS `registry.npmjs.org`; redirects are rejected.
123
+ - The Host returns ordinary JSON over the authenticated DSH Connection RPC channel.
124
+ - There is no public Remote Service and no model Tool.
125
+ - No package-manager process is spawned by plugin code.
126
+ - `canApplyInPlace` is always `false`.
127
+ - There is no Update now button, automatic install, restart, rollback, or release-file replacement.
128
+ - A failed refresh retains the last good cache and displays a warning; a cold failure still shows the local version.
129
+
130
+ ## Uninstall
131
+
132
+ ```sh
133
+ dsh plugin --profile web remove dsh-update-status
134
+ ```
135
+
136
+ Restart DSH and refresh the Web GUI. If desired, remove the `dsh-update-status` settings namespace from `~/.dsh/settings.yaml` after uninstalling.
137
+
138
+ ## Development
139
+
140
+ ```sh
141
+ pnpm install --frozen-lockfile
142
+ pnpm run test
143
+ pnpm run build
144
+ pnpm pack --dry-run
145
+ ```
146
+
147
+ Release tags use npm Trusted Publishing with GitHub OIDC. See [docs/RELEASING.md](docs/RELEASING.md) to configure npm’s Trusted Publisher once, then push a matching `vX.Y.Z` tag; no long-lived npm token is stored in this repository.
148
+
149
+ MIT. See [LICENSE](LICENSE).
package/README.zh.md ADDED
@@ -0,0 +1,149 @@
1
+ <h1 align="center">DSH Update Status</h1>
2
+
3
+ <p align="center">DeepSeek Harness Web 侧栏中的只读版本状态 Badge 与发布通道指南。</p>
4
+
5
+ <p align="center">
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>
7
+ <a href="https://github.com/idoall/dsh-update-status/actions/workflows/ci.yml"><img src="https://github.com/idoall/dsh-update-status/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
8
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0F172A" alt="MIT"></a>
9
+ </p>
10
+
11
+ <p align="center"><a href="README.md">English</a> | 中文</p>
12
+
13
+ <p align="center">
14
+ <a href="#功能">功能</a> ·
15
+ <a href="#安装">安装</a> ·
16
+ <a href="#使用">使用</a> ·
17
+ <a href="#安全边界">安全边界</a> ·
18
+ <a href="#卸载">卸载</a> ·
19
+ <a href="docs/RELEASING.md">发布指南</a>
20
+ </p>
21
+
22
+ > DSH Update Status 是 DeepSeek Harness 社区插件。它不修改 DSH 核心,也绝不会安装、重启、回滚、下载或替换 DSH 文件。
23
+
24
+ 插件只把展开侧栏中的完整名称文字换成 `DeepSeek + 版本 Badge`,官方鱼标保持不变。点击 Badge 可查看 npm 发布通道、兼容性状态,以及与所选通道对应的“仅复制”命令。
25
+
26
+ <p align="center">
27
+ <img src="./assets/update-panel.png" width="500" alt="DSH Update Status 面板:当前稳定版、alpha 预览版、兼容性标签和仅复制的升级命令">
28
+ </p>
29
+
30
+ ## 功能
31
+
32
+ - **侧栏版本状态**:展开侧栏显示当前 DSH 版本,收起轨道提供状态入口。
33
+ - **稳定版与预览版发现**:一次 registry 请求读取 npm dist-tags `latest`、`next`、`alpha`,默认选择 `latest`。
34
+ - **只展示有意义的选择**:非当前候选与运行版本相同时隐藏;多个通道指向同一版本时优先保留 `latest`。
35
+ - **弹窗内直接选择通道**:可直接选择有价值的稳定版、候选版或预览版;偏好由 DSH Host 持久化。
36
+ - **兼容性标识**:明确验证过的版本显示“已验证兼容”;未知预览版显示“尚未验证兼容”,不冒充安全升级。
37
+ - **仅复制命令**:根据安装来源和通道生成 `@latest`、`@next` 或 `@alpha` 命令,但从不执行。
38
+ - **缓存但不轮询**:Host 挂载时检查一次,缓存可设为 30–1,440 分钟并合并并发请求;前端没有轮询,只有“检查更新”按钮绕过缓存。
39
+ - **移动端可靠**:详情使用浏览器 modal top layer;底部 sheet 可滚动、适配 safe area,并保持在 DSH 抽屉上方。
40
+
41
+ ## 安装
42
+
43
+ 要求:
44
+
45
+ - 带 Web profile 的 DeepSeek Harness
46
+ - Node.js 20 或更新版本
47
+ - 已验证的 DSH 版本:`0.1.2-rc.1`
48
+
49
+ 已经安装 `dsh` 命令:
50
+
51
+ ```sh
52
+ dsh plugin --profile web add dsh-update-status@latest
53
+ ```
54
+
55
+ 直接使用 DeepSeek Harness 源码:
56
+
57
+ ```sh
58
+ corepack enable
59
+ pnpm install
60
+ pnpm dsh plugin --profile web add dsh-update-status@latest
61
+ ```
62
+
63
+ 安装后重启原有 DSH 进程,再刷新 Web GUI。不要为本插件启动第二个 Web server。
64
+
65
+ 本地开发 link:
66
+
67
+ ```sh
68
+ pnpm install --frozen-lockfile
69
+ pnpm run build
70
+ dsh plugin --profile web add "link:$(pwd)"
71
+ ```
72
+
73
+ ## 使用
74
+
75
+ 1. 打开 DSH 左侧抽屉。官方鱼标仍在;名称行显示 `DeepSeek + 当前版本 Badge`。
76
+ 2. 点击 Badge。面板打开时不会触发外层“新建会话”按钮。
77
+ 3. 查看有意义的通道。如果 `next` 与当前运行版/稳定版相同,它会被主动隐藏。
78
+ 4. 想体验预览版时,在面板中选择 `alpha`。未验证兼容的版本仍会明确警告。
79
+ 5. 复制生成的命令,在**运行 DSH 的那台电脑**的终端中自行执行。
80
+ 6. 包管理器命令完成后,由你自行重启 DSH。
81
+
82
+ 全局安装时可能生成:
83
+
84
+ ```sh
85
+ npm install -g @deepseek-ai/dsh@latest
86
+ npm install -g @deepseek-ai/dsh@next
87
+ npm install -g @deepseek-ai/dsh@alpha
88
+ ```
89
+
90
+ 插件只显示与检测到的安装方式和所选通道匹配的一条命令,不会运行这些命令。
91
+
92
+ ## 发布通道
93
+
94
+ | 通道 | 用途 | 兼容性处理 |
95
+ | --- | --- | --- |
96
+ | `latest` | DSH npm 包推荐的默认稳定/候选版本 | 只有本插件明确声明过才显示已验证 |
97
+ | `next` | 与当前运行版/稳定版确实不同时的候选版本 | 可能尚未验证 |
98
+ | `alpha` | 用户主动选择的早期预览版 | 除非明确声明,否则显示尚未验证 |
99
+
100
+ 插件严格遵循 npm dist-tag,不会从 registry 历史版本中自行挑选 SemVer 最大值。
101
+
102
+ ## 兼容性
103
+
104
+ | 插件版本 | 已验证的 DeepSeek Harness |
105
+ | --- | --- |
106
+ | `0.1.0` | `0.1.2-rc.1` |
107
+
108
+ 更高 DSH 版本不会被自动宣称为兼容,需要人工验证。不兼容时请禁用或卸载插件,不要修改 DSH 核心。
109
+
110
+ ## 配置
111
+
112
+ | 选项 | 默认值 | 范围 / 行为 |
113
+ | --- | --- | --- |
114
+ | `cacheTtlMinutes` | `360` | 30–1,440 分钟;仅在下一次按需读取时判断是否到期,绝不启动后台定时器 |
115
+ | `channel` | `latest` | `latest`、`next` 或 `alpha` |
116
+ | `sidebarEnabled` | `true` | 只隐藏本插件自己的侧栏入口 |
117
+
118
+ **设置 → 版本与更新** 可隐藏本插件侧栏入口和选择发布通道;详情面板中也能直接切换通道和填写缓存时长。修改缓存时长不会请求网络;只在之后普通读取且缓存已到期时更新,“检查更新”始终是立即手动检查。
119
+
120
+ ## 安全边界
121
+
122
+ - registry 访问只允许 HTTPS `registry.npmjs.org`,并拒绝重定向。
123
+ - Host 只通过 DSH 已认证的 Connection RPC 返回普通 JSON。
124
+ - 不注册公共 Remote Service,也不注册模型 Tool。
125
+ - 插件代码不会启动 npm/pnpm 子进程。
126
+ - `canApplyInPlace` 恒为 `false`。
127
+ - 没有“立即更新”、自动安装、重启、回滚或 release 文件替换。
128
+ - 刷新失败时保留最后一次成功缓存并显示警告;冷启动失败也会保留本地版本信息。
129
+
130
+ ## 卸载
131
+
132
+ ```sh
133
+ dsh plugin --profile web remove dsh-update-status
134
+ ```
135
+
136
+ 重启 DSH 并刷新 Web GUI。如需清除偏好,可在卸载后从 `~/.dsh/settings.yaml` 删除 `dsh-update-status` 命名空间。
137
+
138
+ ## 开发
139
+
140
+ ```sh
141
+ pnpm install --frozen-lockfile
142
+ pnpm run test
143
+ pnpm run build
144
+ pnpm pack --dry-run
145
+ ```
146
+
147
+ 发布 tag 使用 npm Trusted Publishing 与 GitHub OIDC。请按 [docs/RELEASING.md](docs/RELEASING.md) 在 npm 网站一次性绑定 Trusted Publisher,随后推送匹配的 `vX.Y.Z` tag;仓库不保存长期 npm token。
148
+
149
+ MIT,详见 [LICENSE](LICENSE)。
Binary file
@@ -0,0 +1,5 @@
1
+ # The host half is a plain static Cordis plugin. package.json's dsh.client
2
+ # declaration loads the built ./client browser half into the current Web GUI.
3
+ - insert:
4
+ - id: dsh-update-status
5
+ name: dsh-update-status
@@ -0,0 +1,114 @@
1
+ # Releasing dsh-update-status
2
+
3
+ Releases are built from immutable Git tags and published by GitHub Actions. npm packages are immutable: never reuse a version that npm has accepted.
4
+
5
+ ## First release bootstrap
6
+
7
+ npm cannot authorize Trusted Publishing for a package until that package exists and has an npm-side Trusted Publisher configured. For the initial `0.1.0` bootstrap only, the release workflow uses the repository `NPM_TOKEN` secret through `NODE_AUTH_TOKEN`.
8
+
9
+ The token must belong to the npm account or organization that owns `dsh-update-status`, have publish permission, and satisfy that account’s 2FA/automation requirements. Never put it in a source file, local `.npmrc`, issue, or workflow log. After `0.1.0` succeeds, configure OIDC as below and remove the Secret before the next version.
10
+
11
+ ## One-time npm Trusted Publisher configuration after first publish
12
+
13
+ After the first package exists at [npmjs.com](https://www.npmjs.com/), add a **Trusted Publisher**:
14
+
15
+ | npm field | Value |
16
+ | --- | --- |
17
+ | Provider | GitHub Actions |
18
+ | Owner | `idoall` |
19
+ | Repository | `dsh-update-status` |
20
+ | Workflow filename | `release.yml` |
21
+ | Environment | Leave blank |
22
+
23
+ The workflow path must be `.github/workflows/release.yml`. After confirming the Trusted Publisher is active, change the publish step back to OIDC (remove `NODE_AUTH_TOKEN`), retain `id-token: write`, remove the repository `NPM_TOKEN` Secret, and test the next release with a new version/tag.
24
+
25
+ ## What a release tag does
26
+
27
+ Pushing a tag matching `v*` triggers [`.github/workflows/release.yml`](../.github/workflows/release.yml):
28
+
29
+ 1. Require `vX.Y.Z` to exactly match `package.json`’s `X.Y.Z` version.
30
+ 2. Install dependencies with a frozen lockfile, run tests, build, and pack exactly one `.tgz` artifact.
31
+ 3. Upload that artifact and `SHA256SUMS` as a GitHub Actions artifact.
32
+ 4. Publish that same artifact to npm with the bootstrap token and the `latest` dist-tag. After the first successful publish and npm-side configuration, later releases use Trusted Publishing (GitHub OIDC).
33
+ 5. Create (or update) the GitHub Release and attach the tarball and checksum **only after** the publish job succeeds.
34
+
35
+ If `dsh-update-status@X.Y.Z` already exists on npm, the immutable npm package is left unchanged and the workflow continues safely to the GitHub Release step.
36
+
37
+ ## Before every release
38
+
39
+ Never release an uncommitted worktree or reuse a published npm version.
40
+
41
+ ```sh
42
+ git switch main
43
+ git pull --ff-only
44
+ git status --short
45
+ pnpm install --frozen-lockfile
46
+ pnpm run verify
47
+ node -p "require('./package.json').version"
48
+ ```
49
+
50
+ `git status --short` must be empty, and the printed version must be the intended unpublished version.
51
+
52
+ For an extra local artifact check:
53
+
54
+ ```sh
55
+ rm -rf .tmp/release && mkdir -p .tmp/release
56
+ pnpm pack --pack-destination .tmp/release
57
+ shasum -a 256 .tmp/release/dsh-update-status-*.tgz
58
+ npm pack --dry-run .tmp/release/dsh-update-status-*.tgz
59
+ ```
60
+
61
+ Before the first release, verify npm does not already own the exact version:
62
+
63
+ ```sh
64
+ VERSION="$(node -p "require('./package.json').version")"
65
+ npm view "dsh-update-status@$VERSION" version || true
66
+ ```
67
+
68
+ ## Publish a version
69
+
70
+ After npm Trusted Publishing is configured and the matching source commit is on `main`:
71
+
72
+ ```sh
73
+ VERSION="$(node -p "require('./package.json').version")"
74
+ git tag -a "v$VERSION" -m "dsh-update-status v$VERSION"
75
+ git push origin "v$VERSION"
76
+ ```
77
+
78
+ Watch the **Release** workflow in GitHub Actions. It publishes npm and creates the GitHub Release; do not run `npm publish` locally for a tag-managed release.
79
+
80
+ ## Verify the public package
81
+
82
+ After the workflow succeeds:
83
+
84
+ ```sh
85
+ VERSION="$(node -p "require('./package.json').version")"
86
+ npm view "dsh-update-status@$VERSION" name version dist-tags repository --json
87
+ npm view dsh-update-status dist-tags --json
88
+
89
+ VERIFY_DIR="$(mktemp -d)"
90
+ cd "$VERIFY_DIR"
91
+ npm pack "dsh-update-status@$VERSION"
92
+ npm install --ignore-scripts "./dsh-update-status-$VERSION.tgz"
93
+ node -e "const p=require('./node_modules/dsh-update-status/package.json'); console.log(p.name,p.version,p.dsh?.client?.platform)"
94
+ ```
95
+
96
+ The final command must print:
97
+
98
+ ```text
99
+ dsh-update-status X.Y.Z web
100
+ ```
101
+
102
+ 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:
103
+
104
+ ```sh
105
+ TEST_HOME="$(mktemp -d)"
106
+ DSH_HOME="$TEST_HOME" dsh plugin --profile web add "dsh-update-status@$VERSION"
107
+ DSH_HOME="$TEST_HOME" dsh web
108
+ ```
109
+
110
+ Stop the disposable DSH Web process after verification. The plugin remains advisory: it does not install, restart, roll back, download, or replace DSH files.
111
+
112
+ ## Candidate builds without publication
113
+
114
+ Use **Actions → Build release candidate → Run workflow** to make a downloadable package and checksum without publishing npm or creating a GitHub Release. This is useful for pre-tag DSH UI verification.