@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.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  中文 | [English](README.en.md)
4
4
 
5
- DSH Doctor 面向 DSH 与插件使用者,帮助快速找出导致 DSH 启动异常或升级后不可用的插件,集中说明每个插件的问题、影响与处理方式,并检查常见的 profile 配置和版本漂移。诊断默认完全只读;只有显式使用 `--fix`、核对并确认精确的修复计划后才会执行,文件修改会先创建备份。
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
- Doctor 不要求 `dsh` 必须是全局命令。它会按顺序查找 `--dsh-command` 或 `DSH_DOCTOR_DSH_COMMAND` 指定的命令、显式 `--harness-root` 中的 CLI、profile 共享安装或 npx 缓存留下的链接、当前项目安装、PATH,最后是自动识别出的 Harness 源码工作区。DSH Desktop 内置运行时或其他特殊安装可以通过 `--dsh-command /path/to/dsh`(也接受官方包的 `lib/bin.js`)明确指定。找不到 CLI 时仍会完成只读诊断,但不会提供或执行无法验证的命令型修复。
26
+ ---
27
27
 
28
- ## 工作方式
28
+ ## 插件迁移:0.1.1 → 0.1.2
29
29
 
30
- 一次完整流程分为四步:
30
+ ### migrate 命令
31
31
 
32
- 1. `dsh-doctor` 只读检查当前 DSH Home、profile、插件和 Harness 版本。
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
- Doctor 不会加载待检查插件,也不会在普通诊断时修改配置。无法确定正确结果的操作,例如猜测凭据、重写损坏 YAML 或直接移除插件,只会给出建议。
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
- 1. `--lang zh|en`
44
- 2. `DSH_DOCTOR_LANG`
45
- 3. 当前 DSH Home `settings.yaml` `locale.preference`
46
- 4. 终端或系统 locale
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 --lang zh
50
- dsh-doctor --lang en
51
- DSH_DOCTOR_LANG=zh dsh-doctor
96
+ npx skills add bruc3van/dsh-doctor
52
97
  ```
53
98
 
54
- `--json` 始终保留稳定的英文消息与诊断 code,避免语言变化破坏脚本。
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
- ## DSH 升级后的插件兼容性
103
+ ## 诊断
57
104
 
58
- DSH 更新后,Doctor 会把每个 profile 插件归入一个明确状态,并在文本与 JSON 报告中汇总:
105
+ ### 诊断模型
59
106
 
60
- - `incompatible`:已经发现会阻断插件加载或 Harness 启动的错误,例如插件未安装,或注入了已删除的 client runtime。
61
- - `risk`:发现当前版本风险,例如 Harness peer range 不接受新版本、仍依赖已删除的 DSH 包、Node.js 不兼容,或安装版本发生漂移。
62
- - `unknown`:插件没有通过 `peerDependencies` 声明 Harness 兼容范围,或声明对应的当前 package 版本无法解析;Doctor 无法证明它支持升级后的 DSH,但不会把未知误报成故障。
63
- - `compatible`:插件声明的兼容范围接受当前 Harness,且没有发现插件相关错误或警告。
107
+ `diagnose` 从空树开始,按当前 DSH 的正式顺序组合配置:
108
+
109
+ ```text
110
+ bundle layers → profile cordis.patch.yml → home cordis.patch.yml → CLI overlays
111
+ ```
64
112
 
65
- 兼容性检查覆盖所有 profile 直接插件,不再只检查带 `dsh.client` 的前端插件;纯 bundle 或服务端插件引用旧 Harness API 也会被报告。建议 DSH 升级后先运行一次 `dsh-doctor`,再根据精确的 update 建议决定是否执行 `dsh-doctor --fix`。
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 --profile web
73
- dsh-doctor --home /path/to/.dsh
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
- dsh-doctor --fix --yes --json
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
- `--repair` `--fix` 的别名。`--yes` 只有和 `--fix` 一起使用才有效。
178
+ Doctor 只接受属于当前 profile patch 的时间戳恢复文件。
179
+
180
+ ### 安全删除
87
181
 
88
- ## 当前检查范围
182
+ 删除是独立动作,永远不会由通用 `--fix --yes` 推断:
89
183
 
90
- - profile `package.json` 的 JSON 根结构、依赖表、bundle 列表和 reload 生命周期
91
- - profile、home bundle `cordis.patch.yml` 语法与顶层结构,包括 `!!js` 表达式
92
- - `settings.yaml` `.credentials.yaml` 的安全结构检查;凭据诊断不输出秘密值
93
- - profile 依赖、bundle 声明、patch 文件和 client bundle 是否存在
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
- 每条可执行修复都包含稳定 ID、风险级别、说明和精确目标:
191
+ ```sh
192
+ dsh plugin --profile web remove @scope/plugin
193
+ ```
107
194
 
108
- - 文件修复在确认前展示路径,确认后再次校验 SHA-256 指纹。
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
- 首期只自动处理确定性操作,例如把已安装 bundle 恢复到 manifest 列表,或运行明确的 profile install/update。损坏 JSON/YAML、凭据值和插件移除只给建议,不猜测应该删除或改成什么。
197
+ ---
118
198
 
119
- ## 退出码
199
+ ## 历史基线
120
200
 
121
- - `0`:没有阻断错误;warning 仍会显示
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
- - 静态扫描只识别代码中的字面量 `require("package")`;动态依赖需要未来的 bundle 元数据协议。
128
- - 配置检查覆盖语法和 Doctor 能稳定对齐的结构,并按当前 Harness patch 算法做无执行组合检查;不会求值 `!!js`,也不会加载第三方插件。
129
- - 版本兼容以插件 `peerDependencies` 和当前可解析 Harness package 版本为依据;未声明兼容范围或无法解析对应当前版本的插件只能做结构检查。
130
- - lockfile 检查只对 profile 的直接依赖 importer 做确定性交叉验证,不递归扫描整个 npm 依赖树。
131
- - 真实启动探针尚未启用;即使复制 `DSH_HOME`,第三方插件仍可能访问网络、绝对路径或启动外部进程,不能宣称无副作用。
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
- node src/cli.mjs --help
248
+ npm pack --dry-run
139
249
  ```
140
250
 
141
- 新包需要先由 `@bruc3van` 对应的 npm 账号完成一次 `npm publish --access public`,创建公开包页面。然后在 npm 包设置中添加 GitHub Actions Trusted Publisher:Organization or user `bruc3van`,Repository 为 `dsh-doctor`,Workflow filename 为 `release.yml`,Environment 留空,Allowed actions 只启用 `npm publish`。
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
+ }