@bruc3van/dsh-doctor 0.1.6 → 0.5.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/README.en.md +192 -84
- package/README.md +190 -82
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/behavior.md +12 -0
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/config-rules.json +36 -0
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/manifest.json +19 -0
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/packages.json +62 -0
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/services.json +28 -0
- package/migrations/dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2/symbols.json +126 -0
- package/package.json +6 -3
- package/skills/dsh-plugin-upgrade/SKILL.md +98 -0
- package/skills/dsh-plugin-upgrade/evals/evals.json +36 -0
- package/skills/dsh-plugin-upgrade/references/migration-map.md +32 -0
- package/skills/dsh-plugin-upgrade/references/verification.md +27 -0
- package/src/baseline.mjs +69 -0
- package/src/cli.mjs +262 -88
- package/src/config-model.mjs +167 -0
- package/src/doctor.mjs +201 -23
- package/src/i18n.mjs +18 -0
- package/src/migrate-verify.mjs +195 -0
- package/src/migrate.mjs +418 -0
- package/src/migration-catalog.mjs +60 -0
- package/src/recovery.mjs +358 -0
- package/src/redact.mjs +46 -0
- package/src/registry.mjs +61 -0
- package/src/safe-write.mjs +50 -0
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
中文 | [English](README.en.md)
|
|
4
4
|
|
|
5
|
-
DSH Doctor
|
|
5
|
+
DSH Doctor 是面向 DSH 升级事故的诊断与恢复决策工具。它按插件回答:哪里不兼容、哪层配置造成或放大问题、首选修复是什么,以及暂时修不好时能否安全隔离或删除。
|
|
6
6
|
|
|
7
|
-
这是社区维护的第三方工具,不属于 DeepSeek
|
|
7
|
+
这是社区维护的第三方工具,不属于 DeepSeek 官方项目。普通诊断完全只读,也不会加载或执行待检查插件的代码。
|
|
8
8
|
|
|
9
9
|
## 安装
|
|
10
10
|
|
|
@@ -12,132 +12,240 @@ DSH Doctor 面向 DSH 与插件使用者,帮助快速找出导致 DSH 启动
|
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
14
|
npm install --global @bruc3van/dsh-doctor
|
|
15
|
-
dsh-doctor
|
|
15
|
+
dsh-doctor diagnose
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
也可以临时运行:
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
|
-
npx @bruc3van/dsh-doctor
|
|
21
|
+
npx @bruc3van/dsh-doctor diagnose
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
默认检查 `$DSH_HOME/profiles/web`;未设置 `DSH_HOME` 时使用 `~/.dsh`。
|
|
24
|
+
默认检查 `$DSH_HOME/profiles/web`;未设置 `DSH_HOME` 时使用 `~/.dsh`。特殊安装可用 `--dsh-command /path/to/dsh` 指定实际 CLI,源码工作区可用 `--harness-root /path/to/deepseek-harness`。
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
---
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## 插件迁移:0.1.1 → 0.1.2
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
### migrate 命令
|
|
31
31
|
|
|
32
|
-
1.
|
|
33
|
-
2. Doctor 按错误、警告和插件兼容状态展示证据与建议。
|
|
34
|
-
3. `dsh-doctor --fix` 先展示精确的文件修改或 DSH 命令计划,并等待用户确认。
|
|
35
|
-
4. 修复完成后自动重新诊断,以最终状态决定退出码。
|
|
32
|
+
Doctor 内置 `dsh-v0.1.1-rc.2 → dsh-v0.1.2-alpha.2` 的版本化迁移目录,并把升级拆成三个可审计阶段:
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
```sh
|
|
35
|
+
# 阶段 1:只读分析源码、类型导入、manifest、client graph 与构建产物
|
|
36
|
+
dsh-doctor migrate analyze /path/to/plugin \
|
|
37
|
+
--from dsh-v0.1.1-rc.2 \
|
|
38
|
+
--to dsh-v0.1.2-alpha.2 \
|
|
39
|
+
--harness-root /path/to/deepseek-harness
|
|
40
|
+
|
|
41
|
+
# 阶段 2:预览精确改写;加 --yes 才写入并创建时间戳备份
|
|
42
|
+
dsh-doctor migrate apply /path/to/plugin --safe \
|
|
43
|
+
--harness-root /path/to/deepseek-harness
|
|
44
|
+
dsh-doctor migrate apply /path/to/plugin --safe --yes \
|
|
45
|
+
--harness-root /path/to/deepseek-harness
|
|
46
|
+
|
|
47
|
+
# 阶段 3:依次完成静态、构建和隔离运行时验证
|
|
48
|
+
dsh-doctor migrate verify /path/to/plugin --level static \
|
|
49
|
+
--harness-root /path/to/deepseek-harness
|
|
50
|
+
dsh-doctor migrate verify /path/to/plugin --level build --yes \
|
|
51
|
+
--harness-root /path/to/deepseek-harness
|
|
52
|
+
dsh-doctor migrate verify /path/to/plugin --level runtime --yes \
|
|
53
|
+
--harness-root /path/to/deepseek-harness
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
可用 `dsh-doctor migrations list` 确认当前 CLI 包含所需版本对;如未安装,`npx --package=@bruc3van/dsh-doctor dsh-doctor migrations list` 也可完成确认。
|
|
57
|
+
|
|
58
|
+
### 各阶段说明
|
|
59
|
+
|
|
60
|
+
**analyze**:使用 TypeScript AST 扫描,能识别不会出现在 JavaScript bundle 中的 `import type`;同时检查 package 元数据、client graph 声明和构建产物,不因 bundle 干净就推断兼容。
|
|
61
|
+
|
|
62
|
+
**apply --safe**:只迁移 catalog 标记为精确等价的符号,将非移除的 DSH 开发依赖固定到目标版本,并创建时间戳备份。可能补充精确符号迁移所需的新依赖,但不会自动修改已有 peer 范围。Session、Workspace、Conversation 和 pending interaction 属于所有权及生命周期变化,保留为 `MIG_SEMANTIC_API_CHANGE`,不做机械替换。
|
|
63
|
+
|
|
64
|
+
**verify**:
|
|
65
|
+
|
|
66
|
+
| 级别 | 执行内容 |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `static` | 使用 TypeScript AST 检查源码/import、manifest、client graph 与构建产物,不执行项目脚本 |
|
|
69
|
+
| `build` | 执行插件构建脚本,验证产物(需 `build` 或 `pack:check` 成功;仅有 `test`/`typecheck` 不足以证明发布产物) |
|
|
70
|
+
| `runtime` | 打真实 tarball,在临时 `DSH_HOME` 中通过目标 CLI 安装到全新 web profile,核验 CLI 版本、profile manifest、已安装包、bundle 激活与有效配置,执行激活 smoke;不触碰普通用户的 `~/.dsh` |
|
|
38
71
|
|
|
39
|
-
|
|
72
|
+
最高状态为 `analyzed` → `source-migrated` → `artifact-verified` → `runtime-verified`。`runtime-verified` 仍不能替代真实 UI、生命周期与业务行为的验证。失败现场会保留并报告路径;成功后默认清理。
|
|
40
73
|
|
|
41
|
-
|
|
74
|
+
### 主要 API 变化
|
|
42
75
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
76
|
+
`@deepseek-ai/dsh-client-runtime` 已移除,**没有聚合替代包**,各能力迁往:
|
|
77
|
+
|
|
78
|
+
| 原能力 | 0.1.2 归属 | 迁移方式 |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| store 引擎与 equality helpers | `dsh-client-store` | 精确(catalog 已列举符号) |
|
|
81
|
+
| Cordis 客户端 context 类型 | `@deepseek-ai/cordis` `Context` | 精确;保留本地别名 |
|
|
82
|
+
| session 控制/列表/命令 | `dsh-api-session-controller/client` | 语义(需开发者判断) |
|
|
83
|
+
| workspace 状态/命令 | `dsh-api-workspace-controller/client` | 语义 |
|
|
84
|
+
| conversation 组装 | `dsh-client-ui-conversation/client` | 语义 |
|
|
85
|
+
| pending interaction 状态 | ui-session 聚合的各 UI 包 | 语义 |
|
|
86
|
+
|
|
87
|
+
`@deepseek-ai/dsh-host-apiproxy` 也已移除,无兼容替代,浏览器操作改用 API Remotes/API Gateway 原生 Remote 所有者。
|
|
88
|
+
|
|
89
|
+
### dsh-plugin-upgrade skill
|
|
90
|
+
|
|
91
|
+
包内同时提供 [`dsh-plugin-upgrade` skill](skills/dsh-plugin-upgrade/SKILL.md),供编码 Agent(如 Claude Code)驱动完整迁移流程,确保不折叠任何安全阶段门控。Skill 描述触发条件:插件开发者寻求迁移、兼容性评估、API 替换、peer 依赖更新、产物重建或 DSH 0.1.2 运行时验证。
|
|
92
|
+
|
|
93
|
+
可直接从 GitHub 仓库安装到本机支持的编码 Agent:
|
|
47
94
|
|
|
48
95
|
```sh
|
|
49
|
-
dsh-doctor
|
|
50
|
-
dsh-doctor --lang en
|
|
51
|
-
DSH_DOCTOR_LANG=zh dsh-doctor
|
|
96
|
+
npx skills add bruc3van/dsh-doctor
|
|
52
97
|
```
|
|
53
98
|
|
|
54
|
-
`--
|
|
99
|
+
仓库当前只提供一个 skill,`skills` CLI 会发现并安装 `dsh-plugin-upgrade`;需要显式选择时可加 `--skill dsh-plugin-upgrade`。该命令只安装 Agent skill,不会全局安装 DSH Doctor CLI;skill 会优先使用现有 `dsh-doctor`,不存在时按流程通过 `npx @bruc3van/dsh-doctor` 调用匹配的 CLI。
|
|
100
|
+
|
|
101
|
+
---
|
|
55
102
|
|
|
56
|
-
##
|
|
103
|
+
## 诊断
|
|
57
104
|
|
|
58
|
-
|
|
105
|
+
### 诊断模型
|
|
59
106
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
107
|
+
`diagnose` 从空树开始,按当前 DSH 的正式顺序组合配置:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
bundle layers → profile cordis.patch.yml → home cordis.patch.yml → CLI overlays
|
|
111
|
+
```
|
|
64
112
|
|
|
65
|
-
|
|
113
|
+
JSON 同时保留 `currentDefaultTree`、`currentEffectiveTree`、字段级来源、被替换来源和 `config` 整体替换时丢失的字段路径。重点识别:
|
|
66
114
|
|
|
67
|
-
|
|
115
|
+
- 旧 patch、缺失 target、错误 name assertion;
|
|
116
|
+
- 重复 entry id、重复插件 mount;
|
|
117
|
+
- 高层禁用、结构替换、group/config 整体覆盖;
|
|
118
|
+
- bundle 声明与 profile 激活状态冲突;
|
|
119
|
+
- 插件版本、产物、client contract、依赖与运行环境问题。
|
|
120
|
+
|
|
121
|
+
每个 `pluginDiagnoses[]` 都把当前 `status` 与可选 `recovery` 分开。插件即使能够隔离或删除,也不会因此被标记为已经兼容。
|
|
68
122
|
|
|
69
123
|
```sh
|
|
70
|
-
|
|
71
|
-
dsh-doctor
|
|
72
|
-
dsh-doctor --
|
|
73
|
-
|
|
74
|
-
dsh-doctor --dsh-command /path/to/@deepseek-ai/dsh/lib/bin.js
|
|
124
|
+
dsh-doctor diagnose
|
|
125
|
+
dsh-doctor diagnose --json
|
|
126
|
+
dsh-doctor diagnose --check-updates
|
|
127
|
+
```
|
|
75
128
|
|
|
76
|
-
|
|
77
|
-
dsh-doctor --json
|
|
129
|
+
只有 `--check-updates` 和 `recover` 会访问 npm registry。离线诊断只报告 `update.status: "not-checked"`,绝不会把"未检查"写成"没有兼容版本"。
|
|
78
130
|
|
|
79
|
-
|
|
80
|
-
dsh-doctor --fix
|
|
131
|
+
---
|
|
81
132
|
|
|
82
|
-
|
|
83
|
-
|
|
133
|
+
## 恢复决策
|
|
134
|
+
|
|
135
|
+
### 兼容版本检查
|
|
136
|
+
|
|
137
|
+
Doctor 会检查所有已发布版本的 manifest,而不是只看 `latest`,并选出声明兼容当前可解析 DSH package 版本的最高版本。结论仅表示"manifest 声明兼容的候选版本",不代表已经通过真实启动或 UI 验证。
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
dsh-doctor recover @scope/plugin --action check-update
|
|
141
|
+
dsh-doctor recover @scope/plugin --action update # 只预览
|
|
142
|
+
dsh-doctor recover @scope/plugin --action update --yes # 执行精确版本
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 临时与持久隔离
|
|
146
|
+
|
|
147
|
+
没有兼容版本时,默认先生成临时 overlay,再用实际 profile 验证其余功能:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
dsh-doctor recover @scope/plugin --action quarantine
|
|
151
|
+
dsh-doctor recover @scope/plugin --action quarantine --output ./plugin-quarantine.yml
|
|
152
|
+
dsh --profile web --patch ./plugin-quarantine.yml
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
只有所有活跃 entry 均能精确定位、都有唯一非空 id、name assertion 明确,且 bundle 没有改写其他来源 entry 时,Doctor 才会生成 overlay。核心 bundle、存在 client 依赖者或静态检测到提供运行时 Service 但无法证明依赖关系的插件都要求人工审查。overlay 会禁用插件所有已知活跃 entry,使 host 与 client 来源同时退出组合。
|
|
156
|
+
|
|
157
|
+
验证完成后才可持久化:
|
|
158
|
+
|
|
159
|
+
```sh
|
|
160
|
+
# 先预览精确差异
|
|
161
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified
|
|
162
|
+
|
|
163
|
+
# 明确确认后写入 profile/cordis.patch.yml
|
|
164
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified --yes
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
持久写入会追加 profile 层最终生效的禁用覆盖;如果 home 或 CLI overlay 等更高层仍会覆盖它,Doctor 会在写入前拒绝。写入后重新组合配置并逐个验证目标 entry 确实处于 disabled 状态;验证失败会返回非零退出码。写入前重新校验 SHA-256 并原子替换文件。已有 patch 会创建 `.dsh-doctor-<timestamp>.bak`;首次新建 patch 会创建 `.rollback.json`,其中记录目标文件和创建内容哈希,以便只在文件未被再次修改时执行删除式回滚。
|
|
168
|
+
|
|
169
|
+
可先预览并显式恢复备份或回滚记录:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
dsh-doctor recover @scope/plugin --action rollback-quarantine \
|
|
173
|
+
--backup /path/to/cordis.patch.yml.dsh-doctor-...bak
|
|
174
|
+
dsh-doctor recover @scope/plugin --action rollback-quarantine \
|
|
175
|
+
--backup /path/to/cordis.patch.yml.dsh-doctor-...bak --yes
|
|
84
176
|
```
|
|
85
177
|
|
|
86
|
-
|
|
178
|
+
Doctor 只接受属于当前 profile patch 的时间戳恢复文件。
|
|
179
|
+
|
|
180
|
+
### 安全删除
|
|
87
181
|
|
|
88
|
-
|
|
182
|
+
删除是独立动作,永远不会由通用 `--fix --yes` 推断:
|
|
89
183
|
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
- profile `package.json`、`pnpm-lock.yaml` importer 与实际安装版本是否一致
|
|
95
|
-
- 所有直接插件(包括纯 bundle/服务端插件)的 Node.js `engines`、Harness peer range、旧 DSH 依赖与当前运行时是否兼容
|
|
96
|
-
- 当前 DSH CLI、Harness 工作区和 profile 顶层 `@deepseek-ai/dsh-*` 包是否发生版本漂移或残留
|
|
97
|
-
- `dsh.client` 的 `platform`、`immediately`、`inject`、`external` 和 `./client` export contract
|
|
98
|
-
- client bundle 中字面量 `require()` 与 external/module supplier 的一致性
|
|
99
|
-
- 已删除的 Harness client package 引用
|
|
100
|
-
- 第三方插件 peer range 与当前 Harness 实际版本的兼容性
|
|
101
|
-
- Harness installation 优先于 profile 同名 bundle 的真实解析顺序
|
|
102
|
-
- 按 Harness 官方层级顺序静态组合 bundle、profile 和 home patch,检查缺失 target、错误 group insert 与 name assertion;不会加载插件
|
|
184
|
+
```sh
|
|
185
|
+
dsh-doctor recover @scope/plugin --action remove # 只做影响预检
|
|
186
|
+
dsh-doctor recover @scope/plugin --action remove --yes # 显式执行
|
|
187
|
+
```
|
|
103
188
|
|
|
104
|
-
|
|
189
|
+
自动删除要求插件是 profile 直接依赖、不是模板/内置核心 bundle、lockfile 可读、没有会残留的手工 mount 或 dangling patch,并且当前 DSH CLI 可用。执行前会保存已脱敏的诊断快照和临时 quarantine overlay,再调用官方命令:
|
|
105
190
|
|
|
106
|
-
|
|
191
|
+
```sh
|
|
192
|
+
dsh plugin --profile web remove @scope/plugin
|
|
193
|
+
```
|
|
107
194
|
|
|
108
|
-
|
|
109
|
-
- 写入前创建 `.dsh-doctor-<timestamp>.bak` 备份,再通过同目录临时文件原子替换。
|
|
110
|
-
- 外部命令使用固定 argv 调用,不拼接 shell 命令。
|
|
111
|
-
- `--json --fix --yes` 会捕获子命令输出并放入修复结果,保证 stdout 始终只有一个合法 JSON 文档。
|
|
112
|
-
- 命令修复绑定当前诊断的 `DSH_HOME`,并展示解析出的真实 CLI 路径;不会假定 PATH 中存在 `dsh`。
|
|
113
|
-
- 单个命令修复最长运行 10 分钟,超时会终止该动作并把后续动作标记为跳过。
|
|
114
|
-
- 任一步失败即停止后续修复,并保留已经创建的备份。
|
|
115
|
-
- 完成后重新运行全部诊断,以最终状态决定退出码。
|
|
195
|
+
成功后重新诊断并分别验证 dependency、bundle layer 和活跃 entry 已消失,同时保留原版本的精确回滚安装命令。静态检查无法证明不存在动态 Service 依赖、外部数据残留或所有真实业务流程都正常;完成后仍须重启 profile 并验证主要功能。
|
|
116
196
|
|
|
117
|
-
|
|
197
|
+
---
|
|
118
198
|
|
|
119
|
-
##
|
|
199
|
+
## 历史基线
|
|
120
200
|
|
|
121
|
-
|
|
122
|
-
- `1`:发现可能阻断 Harness 启动的问题
|
|
123
|
-
- `2`:参数、运行环境或修复执行失败
|
|
201
|
+
升级前保存基线,升级后比较插件版本、兼容状态、Harness 与 finding 变化:
|
|
124
202
|
|
|
125
|
-
|
|
203
|
+
```sh
|
|
204
|
+
dsh-doctor baseline create
|
|
205
|
+
dsh-doctor baseline compare
|
|
126
206
|
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
|
|
207
|
+
# 自定义基线路径
|
|
208
|
+
dsh-doctor baseline create --output ./before-upgrade.json
|
|
209
|
+
dsh-doctor baseline compare --output ./before-upgrade.json
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
默认基线位于 profile 的 `.dsh-doctor/baseline.json`。基线用于差异归因,不是当前诊断的前提,也不会覆盖当前现场证据。
|
|
213
|
+
|
|
214
|
+
## 旧版确认式修复
|
|
215
|
+
|
|
216
|
+
`--fix` / `--repair` 继续兼容 0.1.x 的确定性 install、update 与 bundle manifest 修复,不会触发 quarantine、持久化隔离或删除。文件动作展示路径并创建备份,命令使用固定 argv、绑定当前 `DSH_HOME`,任一步失败都会停止后续动作。
|
|
217
|
+
|
|
218
|
+
```sh
|
|
219
|
+
dsh-doctor --fix
|
|
220
|
+
dsh-doctor --fix --yes --json
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## 输出与退出码
|
|
226
|
+
|
|
227
|
+
文本支持中文和英文,优先级为 `--lang`、`DSH_DOCTOR_LANG`、DSH 设置和系统 locale。`--json` 始终保留稳定英文 code 和完整的非秘密证据;插件 `config` 值和其他常见秘密字段会替换为 `[REDACTED]`。
|
|
228
|
+
|
|
229
|
+
| 退出码 | 含义 |
|
|
230
|
+
|---|---|
|
|
231
|
+
| `0` | 没有阻断错误,或显式动作成功且静态验证通过 |
|
|
232
|
+
| `1` | 仍有可能阻断启动的问题,或恢复后静态状态不完整 |
|
|
233
|
+
| `2` | 参数、运行环境或动作执行失败 |
|
|
234
|
+
|
|
235
|
+
## 安全边界
|
|
236
|
+
|
|
237
|
+
- 不执行第三方插件,不求值 `!!js`;诊断会解析配置结构,但 JSON、baseline 和恢复快照会脱敏所有插件 `config` 值及其他常见秘密字段,文本报告也不打印配置值;
|
|
238
|
+
- registry 结果只证明 manifest 声明,不证明真实运行兼容;
|
|
239
|
+
- 动态 Service 依赖、外部副作用、真实 UI 和业务流程需要用户验证;
|
|
240
|
+
- patch 精确编辑只处理 Doctor 能安全解析和定位的结构;有歧义时拒绝自动操作;
|
|
241
|
+
- 添加、更新或删除 bundle 后,运行中的 profile 不会自动改变 bundle 集合,必须重启。
|
|
132
242
|
|
|
133
243
|
## 从源码开发
|
|
134
244
|
|
|
135
245
|
```sh
|
|
136
246
|
npm install
|
|
137
247
|
npm run check
|
|
138
|
-
|
|
248
|
+
npm pack --dry-run
|
|
139
249
|
```
|
|
140
250
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
后续发布前,需要在 `CHANGELOG.md` 中增加与版本 tag 同名的中文 `## vX.Y.Z` 条目。推送与 `package.json` 版本一致的 tag 后,workflow 会通过 OIDC 发布 npm 包、生成 provenance,并自动用该中文条目创建或更新 GitHub Release;缺少中文条目时发布流程会失败。不需要保存长期 npm token。
|
|
251
|
+
发布仍使用 GitHub Actions OIDC 与 npm provenance;本地实现和验证不会自动提交、打 tag 或发布。
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# DSH 0.1.1-rc.2 to 0.1.2-alpha.2 behavior migration
|
|
2
|
+
|
|
3
|
+
The old Client Runtime was split by ownership. There is no aggregate replacement package.
|
|
4
|
+
|
|
5
|
+
- Session control, list state, commands, projections, queue and event windows belong to `api-session-controller/client`.
|
|
6
|
+
- Workspace state and commands belong to `api-workspace-controller/client`; navigation policy belongs to `ui-workspace`.
|
|
7
|
+
- Conversation assembly belongs to `ui-conversation`; Chat and Trajectory own their respective projections.
|
|
8
|
+
- Approval and Question own their pending objects; `ui-session` only aggregates domain publications.
|
|
9
|
+
- The store engine belongs to `client-store`; React hook synthesis belongs to the renderer.
|
|
10
|
+
- The Host API Proxy was removed. Unary browser operations live on their natural Remote service owners.
|
|
11
|
+
|
|
12
|
+
An import move is safe only when the catalog marks it `exact`. A `semantic` mapping identifies the new owner but still requires the plugin developer to rewrite behavior and verify the real lifecycle.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"platformModules": [
|
|
3
|
+
"react",
|
|
4
|
+
"react/jsx-runtime",
|
|
5
|
+
"react-dom",
|
|
6
|
+
"react-dom/client",
|
|
7
|
+
"@deepseek-ai/cordis",
|
|
8
|
+
"@deepseek-ai/dsh-client-store",
|
|
9
|
+
"@deepseek-ai/dsh-client-ui-slots",
|
|
10
|
+
"@deepseek-ai/dsh-client-ui-primitives"
|
|
11
|
+
],
|
|
12
|
+
"profilePatchPaths": {
|
|
13
|
+
"web": [
|
|
14
|
+
"packages/bundle/base/cordis.patch.yml",
|
|
15
|
+
"packages/bundle/web-app/cordis.patch.yml"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
"rules": [
|
|
19
|
+
{
|
|
20
|
+
"id": "client-inject-is-informational",
|
|
21
|
+
"note": "dsh.client.inject lists package dependency edges; Cordis service inject controls activation."
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"id": "baseline-external-is-implicit",
|
|
25
|
+
"note": "Platform modules are implicit and must not be repeated in dsh.client.external."
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"id": "feature-values-use-services-or-slots",
|
|
29
|
+
"note": "Feature plugins must not use dsh.client.external as a feature-to-feature value dependency mechanism."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "client-export-required",
|
|
33
|
+
"note": "A web dsh.client declaration requires a published exports[\"./client\"] artifact."
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "dsh-v0.1.1-rc.2__dsh-v0.1.2-alpha.2",
|
|
4
|
+
"from": {
|
|
5
|
+
"ref": "dsh-v0.1.1-rc.2",
|
|
6
|
+
"commit": "b150a551b8d465e31e418e1b2eaf5e79bbb7d28e"
|
|
7
|
+
},
|
|
8
|
+
"to": {
|
|
9
|
+
"ref": "dsh-v0.1.2-alpha.2",
|
|
10
|
+
"commit": "0a53fb55bea101816fa226bb964ae2bed71c343b",
|
|
11
|
+
"version": "0.1.2-alpha.2"
|
|
12
|
+
},
|
|
13
|
+
"description": "DeepSeek Harness 0.1.1-rc.2 to 0.1.2-alpha.2 plugin migration",
|
|
14
|
+
"references": {
|
|
15
|
+
"ownership": ".agents/notes/implemented/architecture/2026-08-20-client-session-conversation-ownership.md",
|
|
16
|
+
"remoteMigration": ".agents/notes/implemented/architecture/2026-08-10-unary-apiproxy-remote-migration.md",
|
|
17
|
+
"clientRules": "packages/client/AGENTS.md"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"removed": [
|
|
3
|
+
"@deepseek-ai/dsh-acp-demo",
|
|
4
|
+
"@deepseek-ai/dsh-acp-snapshot",
|
|
5
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
6
|
+
"@deepseek-ai/dsh-host-apiproxy",
|
|
7
|
+
"@deepseek-ai/dsh-sdk-jsonrpc-demo"
|
|
8
|
+
],
|
|
9
|
+
"added": [
|
|
10
|
+
"@deepseek-ai/dsh-acp-app",
|
|
11
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
12
|
+
"@deepseek-ai/dsh-api-settings-controller",
|
|
13
|
+
"@deepseek-ai/dsh-api-workspace-controller",
|
|
14
|
+
"@deepseek-ai/dsh-client-store",
|
|
15
|
+
"@deepseek-ai/dsh-client-ui-approval",
|
|
16
|
+
"@deepseek-ai/dsh-client-ui-chat",
|
|
17
|
+
"@deepseek-ai/dsh-client-ui-schedule",
|
|
18
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
19
|
+
"@deepseek-ai/dsh-deepseek-llm-api-extensions",
|
|
20
|
+
"@deepseek-ai/dsh-deque",
|
|
21
|
+
"@deepseek-ai/dsh-experimental-agent-team-profile",
|
|
22
|
+
"@deepseek-ai/dsh-experimental-agent-team-web-profile",
|
|
23
|
+
"@deepseek-ai/dsh-experimental-client-ui-agent-team",
|
|
24
|
+
"@deepseek-ai/dsh-experimental-inspector",
|
|
25
|
+
"@deepseek-ai/dsh-experimental-webworker-packer",
|
|
26
|
+
"@deepseek-ai/dsh-experimental-webworker-runtime",
|
|
27
|
+
"@deepseek-ai/dsh-plugin-package-inventory-deepseek",
|
|
28
|
+
"@deepseek-ai/dsh-sdk-app",
|
|
29
|
+
"@deepseek-ai/dsh-sdk-minimal",
|
|
30
|
+
"@deepseek-ai/dsh-session-log-deepseek",
|
|
31
|
+
"@deepseek-ai/dsh-session-snapshot",
|
|
32
|
+
"@deepseek-ai/dsh-util-crypto",
|
|
33
|
+
"@deepseek-ai/dsh-util-time",
|
|
34
|
+
"@deepseek-ai/dsh-util-values",
|
|
35
|
+
"@deepseek-ai/dsh-util-workspace-path",
|
|
36
|
+
"@deepseek-ai/dsh-webhook",
|
|
37
|
+
"@deepseek-ai/dsh-webhook-github",
|
|
38
|
+
"@deepseek-ai/dsh-win32-process"
|
|
39
|
+
],
|
|
40
|
+
"targetVersions": {
|
|
41
|
+
"@deepseek-ai/cordis": "4.0.2",
|
|
42
|
+
"@deepseek-ai/dsh-client-store": "0.1.2-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-session": "0.1.2-alpha.2"
|
|
44
|
+
},
|
|
45
|
+
"semanticReplacements": {
|
|
46
|
+
"@deepseek-ai/dsh-client-runtime": [
|
|
47
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
48
|
+
"@deepseek-ai/dsh-api-workspace-controller",
|
|
49
|
+
"@deepseek-ai/dsh-client-store",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-session",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-chat",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-trajectory",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-approval",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-user-questions"
|
|
56
|
+
],
|
|
57
|
+
"@deepseek-ai/dsh-host-apiproxy": [
|
|
58
|
+
"@deepseek-ai/dsh-api-gateway",
|
|
59
|
+
"@deepseek-ai/dsh-api-remotes"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"services": {
|
|
3
|
+
"sessions": {
|
|
4
|
+
"owner": "@deepseek-ai/dsh-api-session-controller/client",
|
|
5
|
+
"confidence": "semantic",
|
|
6
|
+
"note": "The service name survives, but Session snapshots no longer contain Conversation views or pending interactions."
|
|
7
|
+
},
|
|
8
|
+
"workspaces": {
|
|
9
|
+
"owner": "@deepseek-ai/dsh-api-workspace-controller/client",
|
|
10
|
+
"confidence": "semantic",
|
|
11
|
+
"note": "The service name survives, while cross-domain navigation belongs to ui-workspace."
|
|
12
|
+
},
|
|
13
|
+
"conversation": {
|
|
14
|
+
"owner": "@deepseek-ai/dsh-client-ui-conversation/client",
|
|
15
|
+
"confidence": "semantic",
|
|
16
|
+
"note": "Conversation assembly and input are independent of Session lifecycle snapshots."
|
|
17
|
+
},
|
|
18
|
+
"slots": {
|
|
19
|
+
"owner": "@deepseek-ai/dsh-client-ui-renderer/client",
|
|
20
|
+
"confidence": "semantic",
|
|
21
|
+
"note": "Slot declarations stay in ui-slots; runtime registration and binding belong to ui-renderer."
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"removedHostFacade": {
|
|
25
|
+
"package": "@deepseek-ai/dsh-host-apiproxy",
|
|
26
|
+
"replacementPolicy": "Use the natural business Remote owner through generated api-remotes contributions; there is no replacement facade."
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
{
|
|
2
|
+
"modules": {
|
|
3
|
+
"@deepseek-ai/dsh-client-runtime/client": {
|
|
4
|
+
"ClientContext": {
|
|
5
|
+
"toModule": "@deepseek-ai/cordis",
|
|
6
|
+
"toSymbol": "Context",
|
|
7
|
+
"confidence": "exact",
|
|
8
|
+
"reason": "ClientContext was a type alias of Cordis Context."
|
|
9
|
+
},
|
|
10
|
+
"createSnapshotStore": {
|
|
11
|
+
"toModule": "@deepseek-ai/dsh-client-store",
|
|
12
|
+
"toSymbol": "createSnapshotStore",
|
|
13
|
+
"confidence": "exact",
|
|
14
|
+
"reason": "The React-free store engine moved to client-store."
|
|
15
|
+
},
|
|
16
|
+
"defineStore": {
|
|
17
|
+
"toModule": "@deepseek-ai/dsh-client-store",
|
|
18
|
+
"toSymbol": "defineStore",
|
|
19
|
+
"confidence": "exact",
|
|
20
|
+
"reason": "The declarative store factory moved to client-store."
|
|
21
|
+
},
|
|
22
|
+
"ObservableSnapshot": {
|
|
23
|
+
"toModule": "@deepseek-ai/dsh-client-store",
|
|
24
|
+
"toSymbol": "ObservableSnapshot",
|
|
25
|
+
"confidence": "exact",
|
|
26
|
+
"reason": "The observable store contract moved to client-store."
|
|
27
|
+
},
|
|
28
|
+
"SnapshotStore": {
|
|
29
|
+
"toModule": "@deepseek-ai/dsh-client-store",
|
|
30
|
+
"toSymbol": "SnapshotStore",
|
|
31
|
+
"confidence": "exact",
|
|
32
|
+
"reason": "The writable store contract moved to client-store."
|
|
33
|
+
},
|
|
34
|
+
"shallowEqual": {
|
|
35
|
+
"toModule": "@deepseek-ai/dsh-client-store",
|
|
36
|
+
"toSymbol": "shallowEqual",
|
|
37
|
+
"confidence": "exact",
|
|
38
|
+
"reason": "The store equality helper moved to client-store."
|
|
39
|
+
},
|
|
40
|
+
"SessionId": {
|
|
41
|
+
"toModule": "@deepseek-ai/dsh-session/types",
|
|
42
|
+
"toSymbol": "SessionId",
|
|
43
|
+
"confidence": "exact",
|
|
44
|
+
"reason": "Session identity is owned by the Session domain."
|
|
45
|
+
},
|
|
46
|
+
"ISessions": {
|
|
47
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
48
|
+
"toSymbol": "ISessions",
|
|
49
|
+
"confidence": "semantic",
|
|
50
|
+
"reason": "Session ownership moved to the Session Controller and its snapshots changed."
|
|
51
|
+
},
|
|
52
|
+
"Session": {
|
|
53
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
54
|
+
"toSymbol": "Session",
|
|
55
|
+
"confidence": "semantic",
|
|
56
|
+
"reason": "The Client Session object and lifecycle moved to the Session Controller."
|
|
57
|
+
},
|
|
58
|
+
"SessionBinding": {
|
|
59
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
60
|
+
"toSymbol": "SessionBinding",
|
|
61
|
+
"confidence": "semantic",
|
|
62
|
+
"reason": "Session bindings are now Controller-owned lifetimes."
|
|
63
|
+
},
|
|
64
|
+
"SessionListState": {
|
|
65
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
66
|
+
"toSymbol": "SessionListState",
|
|
67
|
+
"confidence": "semantic",
|
|
68
|
+
"reason": "The list state moved and no longer owns Conversation or pending-interaction facts."
|
|
69
|
+
},
|
|
70
|
+
"SessionSummary": {
|
|
71
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
72
|
+
"toSymbol": "SessionSummary",
|
|
73
|
+
"confidence": "semantic",
|
|
74
|
+
"reason": "The Session summary is now a Controller-owned control snapshot."
|
|
75
|
+
},
|
|
76
|
+
"UseProjection": {
|
|
77
|
+
"toModule": "@deepseek-ai/dsh-api-session-controller/client",
|
|
78
|
+
"toSymbol": "UseProjection",
|
|
79
|
+
"confidence": "semantic",
|
|
80
|
+
"reason": "Projection sources are now exposed by Session Controller bindings and adapted by ui-session."
|
|
81
|
+
},
|
|
82
|
+
"IWorkspaces": {
|
|
83
|
+
"toModule": "@deepseek-ai/dsh-api-workspace-controller/client",
|
|
84
|
+
"toSymbol": "IWorkspaces",
|
|
85
|
+
"confidence": "semantic",
|
|
86
|
+
"reason": "Workspace ownership moved to the Workspace Controller and navigation policy moved to ui-workspace."
|
|
87
|
+
},
|
|
88
|
+
"WorkspaceId": {
|
|
89
|
+
"toModule": "@deepseek-ai/dsh-api-workspace-controller/client",
|
|
90
|
+
"toSymbol": "WorkspaceId",
|
|
91
|
+
"confidence": "semantic",
|
|
92
|
+
"reason": "Workspace identity is re-exported by the Workspace Controller."
|
|
93
|
+
},
|
|
94
|
+
"WorkspaceView": {
|
|
95
|
+
"toModule": "@deepseek-ai/dsh-api-workspace-controller/client",
|
|
96
|
+
"toSymbol": "WorkspaceView",
|
|
97
|
+
"confidence": "semantic",
|
|
98
|
+
"reason": "Workspace snapshots are Controller-owned and their shape changed."
|
|
99
|
+
},
|
|
100
|
+
"ConversationNode": {
|
|
101
|
+
"toModule": "@deepseek-ai/dsh-client-ui-conversation/client",
|
|
102
|
+
"toSymbol": "ConversationNode",
|
|
103
|
+
"confidence": "semantic",
|
|
104
|
+
"reason": "Conversation assembly moved out of Session snapshots into ui-conversation."
|
|
105
|
+
},
|
|
106
|
+
"ConversationSnapshot": {
|
|
107
|
+
"toModule": "@deepseek-ai/dsh-client-ui-conversation/client",
|
|
108
|
+
"toSymbol": "ConversationSnapshot",
|
|
109
|
+
"confidence": "semantic",
|
|
110
|
+
"reason": "Conversation is now an independent target-neutral source."
|
|
111
|
+
},
|
|
112
|
+
"PendingInteraction": {
|
|
113
|
+
"toModule": "@deepseek-ai/dsh-client-ui-session/client",
|
|
114
|
+
"toSymbol": "SessionPendingInteraction",
|
|
115
|
+
"confidence": "semantic",
|
|
116
|
+
"reason": "Approval and Question now publish domain-owned pending interactions through ui-session."
|
|
117
|
+
},
|
|
118
|
+
"PendingWait": {
|
|
119
|
+
"toModule": "@deepseek-ai/dsh-client-ui-session/client",
|
|
120
|
+
"toSymbol": "SessionPendingInteraction",
|
|
121
|
+
"confidence": "semantic",
|
|
122
|
+
"reason": "The Runtime PendingWait aggregate was removed; pending domains own their payloads."
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|