dsh-update-plugin 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,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to `dsh-update-plugin` are documented in this file.
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
5
+ and this project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+
11
+ - **Send test reminder / 测试更新提醒** button in the settings page: opens the
12
+ sidebar tab, sends a browser notification (permission required) and shows the
13
+ update badge for 10 seconds, so the reminder can be verified without a real
14
+ release.
15
+
16
+ ## [0.1.0] - 2026-09-12
17
+
18
+ ### Added
19
+
20
+ - **Settings → General** row titled **Check for Updates... / 检查更新**, registered
21
+ through the public `settings.general.item` slot.
22
+ - Full **Settings → Check for Updates...** section page with status, update
23
+ channel, minimum release age, profile details, backup list and rollback.
24
+ - Native DSH right-sidebar tab (`sidebarRightTabs` / `sidebarRight`) with a live
25
+ badge when an update is available and a compact check/update panel.
26
+ - Built-in update logic (no Homebrew or separate shell script needed):
27
+ all npm dist-tags, channel selection (`auto` / `stable` / `next` / `alpha`),
28
+ `$DSH_HOME/profiles/*` discovery, npm/pnpm CLI detection, per-profile
29
+ `dsh plugin --profile <name> update --latest` with a `pnpm update` fallback.
30
+ - Automatic backups under `~/.dsh/update-backups/` plus one-click rollback of
31
+ profile manifests, lockfiles, dependencies and the previous CLI version.
32
+ - Host endpoints under `/api/dsh-update-plugin/`: `status`, `update`, `config`,
33
+ `backups`, `rollback`; all mutating endpoints are loopback and same-origin
34
+ only.
35
+ - Two documented fallbacks: the plugin can always be upgraded from the terminal
36
+ (`dsh plugin --profile web add dsh-update-plugin@latest`), and a broken plugin
37
+ cannot break DSH itself.
38
+
39
+ ### Changed
40
+
41
+ - Installation documentation insists on `dsh plugin add` (not plain `pnpm add`)
42
+ so the package joins `dsh.profile.bundles`, and documents the pnpm
43
+ `minimumReleaseAge` workaround (`--config.minimum-release-age=0`).
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-update-all 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,151 @@
1
+ # dsh-update-plugin
2
+
3
+ English | [中文](README.zh-CN.md)
4
+
5
+ A DSH Web plugin that adds **Check for Updates...** (「检查更新」in Chinese) to
6
+ **Settings → General**, right next to Permission, Language, Appearance and Font
7
+ Size.
8
+
9
+ From one row you can check for a newer DeepSeek Harness release and update:
10
+
11
+ - the global `@deepseek-ai/dsh` CLI and every bundled `@deepseek-ai/dsh-*` package;
12
+ - every profile's plugins under `~/.dsh/profiles/*`.
13
+
14
+ The update logic is built into the plugin. It does **not** require Homebrew or a
15
+ separately installed `dsh-update-all` script.
16
+
17
+ ![Check for Updates... in Settings → General](assets/screenshots/general-en.webp)
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ # from npm (once published)
23
+ dsh plugin --profile web add dsh-update-plugin
24
+
25
+ # from a local checkout / this repository
26
+ dsh plugin --profile web add /path/to/dsh-update-all/plugin
27
+ ```
28
+
29
+ If pnpm refuses the install because its `minimumReleaseAge` policy rejects an
30
+ already-updated lockfile entry (for example right after you used
31
+ `dsh-update-all --min-age 0`), rerun the command with the policy relaxed for
32
+ that single install:
33
+
34
+ ```bash
35
+ dsh plugin --profile web add /path/to/dsh-update-all/plugin --config.minimum-release-age=0
36
+ ```
37
+
38
+ > **Always mount with `dsh plugin add`, not plain `pnpm add`.** The official
39
+ > command also appends the package to `dsh.profile.bundles`; a bare `pnpm add`
40
+ > only installs the dependency, so the Settings row never appears. If you
41
+ already used `pnpm add`, run the `dsh plugin ... add` command again — it is
42
+ idempotent and performs the bundle reconciliation.
43
+
44
+ Then restart DSH Web, open **Settings → General**, and look for the
45
+ **Check for Updates...** row.
46
+
47
+ ## Usage
48
+
49
+ - **Settings → General** shows a quick **Check for Updates...** row.
50
+ - **Settings → Check for Updates...** (left navigation) is the full page: status,
51
+ update channel, minimum release age, profiles, backups and rollback.
52
+ - A native **right-sidebar tab** shows a badge when an update is available; click
53
+ it to check or update without leaving the conversation.
54
+ - The status card has a **Send test reminder** button: it opens the sidebar tab,
55
+ sends a browser notification (permission required), and shows the update badge
56
+ for 10 seconds so you can verify the reminder without a real release.
57
+ - The row shows the current and newest versions plus the number of profiles.
58
+ - **Check for updates** refreshes the status (it also refreshes after
59
+ reconnecting).
60
+ - **Update now** updates the CLI and then every profile with dependencies.
61
+ The host creates a backup under `~/.dsh/update-backups/` before changing
62
+ anything.
63
+ - The full page lets you choose the update channel (`auto`, `stable`, `next`,
64
+ `alpha`), set a `minimumReleaseAge` (minutes), list profiles, and roll back to
65
+ any backup.
66
+ - After a successful update or rollback, restart DSH Web to load the new code.
67
+
68
+ The update only runs when the page is loopback and same-origin; a remote DSH Web
69
+ session can read the version but cannot start an update.
70
+
71
+ ## Fallbacks
72
+
73
+ Two fallbacks are built in on purpose:
74
+
75
+ 1. **The plugin can always be upgraded from the terminal**, even when the
76
+ Settings row is broken or hidden:
77
+ ```bash
78
+ dsh plugin --profile web add dsh-update-plugin@latest
79
+ ```
80
+ 2. **A broken plugin never breaks DSH itself.** If the Settings slot or the
81
+ browser bundle contract changes, the row disappears or shows an error; the
82
+ rest of DSH keeps working. The manual commands shown in the row are always:
83
+ ```bash
84
+ dsh plugin --profile web update --latest
85
+ dsh plugin --profile web add dsh-update-plugin@latest
86
+ ```
87
+
88
+ ## Troubleshooting
89
+
90
+ - **The Settings row/page is missing, or Save/backups return `HTTP 404`.**
91
+ The browser half can hot-reload, but the host half (`lib/index.js`) is loaded
92
+ when DSH starts. Fully restart DSH (stop and start `dsh web`, or restart DSH
93
+ Desktop), then hard-refresh the browser.
94
+ - **The right-sidebar tab is not in the `+` menu.** It is registered through the
95
+ native `sidebarRightTabs` API, which requires DSH 0.1.5-rc.1 or newer.
96
+ - **The install command is rejected by pnpm `minimumReleaseAge`.** Add
97
+ `--config.minimum-release-age=0` to that single `dsh plugin add` command.
98
+
99
+ ## Compatibility
100
+
101
+ | DSH version | Status |
102
+ | --- | --- |
103
+ | `0.1.0-rc.8` | expected to work |
104
+ | `0.1.1-rc.2` | expected to work |
105
+ | `0.1.2-rc.1` | expected to work |
106
+ | `0.1.5-rc.1` | expected to work |
107
+ | `0.1.5-rc.2` | tested |
108
+
109
+ DSH is pre-1.0, so a major release may rename a client slot or change a public
110
+ service. When that happens this plugin needs a small compatibility release; the
111
+ fallback commands above keep users unblocked meanwhile.
112
+
113
+ ## How it works
114
+
115
+ - **Client half** (`lib/client.js`) registers into the public
116
+ `settings.general.item` slot used by the native General rows, and talks to two
117
+ loopback endpoints.
118
+ - **Host half** (`lib/index.js`, `lib/update-core.js`) resolves the newest
119
+ version across all npm dist-tags (or a chosen channel), discovers profiles,
120
+ backs them up, updates the CLI with npm or pnpm, and updates each profile
121
+ through `dsh plugin --profile <name> update --latest` (with a `pnpm update`
122
+ fallback).
123
+ - Host endpoints: `/status`, `/update`, `/config`, `/backups` and `/rollback`
124
+ under `/api/dsh-update-plugin/`.
125
+ - Only Node built-ins are used, so there is no extra dependency to trust.
126
+
127
+ ## Release
128
+
129
+ 1. Bump `version` in `plugin/package.json` and add the release notes.
130
+ 2. Commit, then tag and push:
131
+ ```bash
132
+ git tag plugin-vX.Y.Z
133
+ git push origin plugin-vX.Y.Z
134
+ ```
135
+ 3. The **Publish plugin** workflow publishes the package to npm. It needs a
136
+ repository secret named `NPM_TOKEN` with publish rights for
137
+ `dsh-update-plugin`.
138
+
139
+ ## Development
140
+
141
+ ```bash
142
+ cd plugin
143
+ npm test # node --test test/*.test.mjs
144
+ node --check lib/index.js
145
+ node --check lib/client.js
146
+ node --check lib/update-core.js
147
+ ```
148
+
149
+ ## License
150
+
151
+ [MIT](LICENSE)
@@ -0,0 +1,134 @@
1
+ # dsh-update-plugin
2
+
3
+ [English](README.md) | 中文
4
+
5
+ 一个 DSH Web 插件,在 **设置 → 通用设置** 里加入一行「检查更新」,和权限、语言、
6
+ 外观、字号大小同级。
7
+
8
+ 在这一行里可以检查并更新:
9
+
10
+ - 全局 `@deepseek-ai/dsh` CLI 以及随包的 `@deepseek-ai/dsh-*`;
11
+ - `~/.dsh/profiles/*` 下每个 profile 的插件。
12
+
13
+ 更新逻辑完整内置在插件里,**不依赖 Homebrew,也不依赖单独安装的
14
+ `dsh-update-all` 脚本**。
15
+
16
+ ![设置 → 通用设置里的「检查更新」](assets/screenshots/general-zh.webp)
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ # 从 npm 安装(发布之后)
22
+ dsh plugin --profile web add dsh-update-plugin
23
+
24
+ # 从本仓库 / 本地目录安装
25
+ dsh plugin --profile web add /path/to/dsh-update-all/plugin
26
+ ```
27
+
28
+ 如果 pnpm 的 `minimumReleaseAge` 策略因为 lockfile 里已有较新的条目而拒绝安装
29
+ (例如刚用过 `dsh-update-all --min-age 0`),给这一次安装临时放开策略即可:
30
+
31
+ ```bash
32
+ dsh plugin --profile web add /path/to/dsh-update-all/plugin --config.minimum-release-age=0
33
+ ```
34
+
35
+ > **一定要用 `dsh plugin add` 挂载,不要只用 `pnpm add`。** 官方命令还会把包
36
+ > 追加到 `dsh.profile.bundles`;直接 `pnpm add` 只装依赖,不写 bundle 列表,
37
+ > 设置里就不会出现这一行。如果已经用 `pnpm add` 装过,再执行一次
38
+ > `dsh plugin ... add` 即可,它会完成挂载(幂等)。
39
+
40
+ 然后重启 DSH Web,打开 **设置 → 通用设置**,就能看到「检查更新」这一行。
41
+
42
+ ## 使用
43
+
44
+ - **设置 → 通用设置** 里有快捷的「检查更新」一行。
45
+ - **设置 → 检查更新**(左侧导航)是完整页面:状态、更新频道、最小释出时间、
46
+ profiles、备份和回滚。
47
+ - **右侧边栏**有一个原生 tab,有更新时显示角标,点击即可检查或更新,不必离开
48
+ 当前会话。
49
+ - 状态卡片里有 **测试更新提醒** 按钮:会打开侧边栏 tab、发送浏览器通知
50
+ (需要授权),并显示 10 秒的更新角标,方便验证提醒效果,不用等真实新版本。
51
+ - 行内显示当前版本、最新版本和 profile 数量。
52
+ - **检查更新**:刷新状态。
53
+ - **立即更新**:先更新 CLI,再更新每个有依赖的 profile;更新前会自动把
54
+ `package.json` / `pnpm-lock.yaml` 备份到 `~/.dsh/update-backups/`。
55
+ - 完整页面可以选择更新频道(`auto` / `stable` / `next` / `alpha`)、设置
56
+ `minimumReleaseAge`(分钟)、查看 profile 列表,并回滚到任意备份。
57
+ - 更新或回滚成功后重启 DSH Web 加载新代码。
58
+
59
+ 只有 loopback 且同源的页面可以触发更新;远程访问只能查看版本状态,不能执行更新。
60
+
61
+ ## 两个兜底
62
+
63
+ 这两条是特意内置的保险:
64
+
65
+ 1. **插件永远可以从终端独立升级**,即使设置里的那一行坏了或不见了:
66
+ ```bash
67
+ dsh plugin --profile web add dsh-update-plugin@latest
68
+ ```
69
+ 2. **插件坏了不会拖垮 DSH 本体**。如果 DSH 大版本改了客户端槽或 bundle 契约,
70
+ 这一行最多不显示或显示错误,DSH 其他部分不受影响。行内始终提供手动命令:
71
+ ```bash
72
+ dsh plugin --profile web update --latest
73
+ dsh plugin --profile web add dsh-update-plugin@latest
74
+ ```
75
+
76
+ ## 常见问题
77
+
78
+ - **设置里没有这一行/这一页,或者 Save、备份接口报 `HTTP 404`。**
79
+ 浏览器半边可以热加载,但宿主半边(`lib/index.js`)是 DSH 启动时加载的。
80
+ 需要完整重启 DSH(停掉再启动 `dsh web`,或重启 DSH Desktop),然后硬刷新浏览器。
81
+ - **右侧边栏 `+` 菜单里没有这个 tab。**
82
+ 它使用 DSH 原生的 `sidebarRightTabs` API,需要 DSH 0.1.5-rc.1 及以上。
83
+ - **安装时被 pnpm `minimumReleaseAge` 拦截。**
84
+ 在那一次 `dsh plugin add` 命令后加 `--config.minimum-release-age=0`。
85
+
86
+ ## 兼容性
87
+
88
+ | DSH 版本 | 状态 |
89
+ | --- | --- |
90
+ | `0.1.0-rc.8` | 预期可用 |
91
+ | `0.1.1-rc.2` | 预期可用 |
92
+ | `0.1.2-rc.1` | 预期可用 |
93
+ | `0.1.5-rc.1` | 预期可用 |
94
+ | `0.1.5-rc.2` | 已测试 |
95
+
96
+ DSH 目前是 0.x,大版本可能重命名客户端槽或调整公开服务。届时插件需要发一个小的
97
+ 兼容版本;在适配完成前,上面的两个兜底命令保证用户不会被卡住。
98
+
99
+ ## 实现方式
100
+
101
+ - **浏览器半边**(`lib/client.js`)注册到官方公开的 `settings.general.item`
102
+ 槽,和原生的通用设置行使用同一套机制;只和两个 loopback 接口通信。
103
+ - **宿主半边**(`lib/index.js`、`lib/update-core.js`)按频道解析 npm
104
+ dist-tags、动态发现 profile、备份、用 npm 或 pnpm 更新 CLI,再用
105
+ `dsh plugin --profile <name> update --latest` 更新每个 profile(失败时回退
106
+ `pnpm update`)。
107
+ - 宿主接口:`/api/dsh-update-plugin/` 下的 `/status`、`/update`、`/config`、
108
+ `/backups`、`/rollback`。
109
+ - 只使用 Node 内置模块,没有额外需要信任的依赖。
110
+
111
+ ## 发布
112
+
113
+ 1. 修改 `plugin/package.json` 里的 `version`,补充发布说明。
114
+ 2. 提交后打 tag 并推送:
115
+ ```bash
116
+ git tag plugin-vX.Y.Z
117
+ git push origin plugin-vX.Y.Z
118
+ ```
119
+ 3. **Publish plugin** workflow 会把插件发布到 npm。需要在仓库 secret 里配置
120
+ `NPM_TOKEN`,并确保它对 `dsh-update-plugin` 有发布权限。
121
+
122
+ ## 开发
123
+
124
+ ```bash
125
+ cd plugin
126
+ node --test test/
127
+ node --check lib/index.js
128
+ node --check lib/client.js
129
+ node --check lib/update-core.js
130
+ ```
131
+
132
+ ## 许可证
133
+
134
+ [MIT](LICENSE)
@@ -0,0 +1,10 @@
1
+ # dsh-update-plugin bundle patch
2
+ #
3
+ # Installed with the official CLI:
4
+ #
5
+ # dsh plugin --profile <name> add dsh-update-plugin
6
+ #
7
+ # — appends this single insert (one plugin row) to the bundle stack.
8
+ - insert:
9
+ - id: dsh-update-plugin
10
+ name: dsh-update-plugin