@bruc3van/dsh-doctor 0.1.5 → 0.5.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/README.en.md +80 -84
- package/README.md +130 -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 +272 -85
- package/src/config-model.mjs +167 -0
- package/src/doctor.mjs +235 -31
- 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.en.md
CHANGED
|
@@ -2,142 +2,138 @@
|
|
|
2
2
|
|
|
3
3
|
[中文](README.md) | English
|
|
4
4
|
|
|
5
|
-
DSH Doctor
|
|
5
|
+
DSH Doctor is a diagnostic and recovery-decision tool for DSH upgrade incidents. For each plugin, it explains the incompatibility, the configuration layer that caused or amplified it, the preferred repair, and whether temporary isolation or removal can be proven safe enough to offer.
|
|
6
6
|
|
|
7
|
-
This is a community-maintained third-party tool
|
|
7
|
+
This is a community-maintained third-party tool, not an official DeepSeek project. Normal diagnosis is read-only and never loads or executes inspected plugin code.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Install
|
|
10
10
|
|
|
11
11
|
Node.js `22.19+` or `24+` is required:
|
|
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
|
+
The default target is `$DSH_HOME/profiles/web`, falling back to `~/.dsh`. Use `--dsh-command /path/to/dsh` for a special installation or `--harness-root /path/to/deepseek-harness` for a source checkout.
|
|
19
|
+
|
|
20
|
+
## Upgrade a plugin from 0.1.1 to 0.1.2
|
|
21
|
+
|
|
22
|
+
Doctor ships a versioned `dsh-v0.1.1-rc.2 → dsh-v0.1.2-alpha.2` migration catalog and exposes three auditable stages:
|
|
19
23
|
|
|
20
24
|
```sh
|
|
21
|
-
|
|
25
|
+
dsh-doctor migrate analyze /path/to/plugin --harness-root /path/to/deepseek-harness
|
|
26
|
+
|
|
27
|
+
dsh-doctor migrate apply /path/to/plugin --safe --harness-root /path/to/deepseek-harness
|
|
28
|
+
dsh-doctor migrate apply /path/to/plugin --safe --yes --harness-root /path/to/deepseek-harness
|
|
29
|
+
|
|
30
|
+
dsh-doctor migrate verify /path/to/plugin --level static --harness-root /path/to/deepseek-harness
|
|
31
|
+
dsh-doctor migrate verify /path/to/plugin --level build --yes --harness-root /path/to/deepseek-harness
|
|
32
|
+
dsh-doctor migrate verify /path/to/plugin --level runtime --yes --harness-root /path/to/deepseek-harness
|
|
22
33
|
```
|
|
23
34
|
|
|
24
|
-
|
|
35
|
+
Analysis uses the TypeScript AST and therefore sees type-only imports that disappear from JavaScript bundles. Safe apply only rewrites catalog-confirmed exact moves, pins non-removed DSH development dependencies to the target, and creates timestamped backups. It may add dependencies required by exact symbol moves, but it does not automatically change existing peer ranges. Session, Workspace, Conversation, and pending-interaction ownership changes remain explicit semantic tasks.
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
`artifact-verified` requires a successful `build` or `pack:check`; `test`/`typecheck` alone cannot prove a publishable artifact. Runtime verification packs the real plugin and installs it with the target DSH CLI under a temporary `DSH_HOME`; it verifies the CLI version, profile manifest, resolved installed package, activated bundle, effective config, and activation smoke, so a no-op command cannot claim success. It never touches the normal `~/.dsh`. Failed workspaces are retained and reported. `runtime-verified` still does not prove real UI, lifecycle, or business behavior.
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
The package also includes the [`dsh-plugin-upgrade` skill](skills/dsh-plugin-upgrade/SKILL.md) so coding agents can drive this workflow without collapsing its safety gates.
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
## Diagnosis model
|
|
31
42
|
|
|
32
|
-
|
|
33
|
-
2. Doctor reports evidence and recommendations by severity and plugin compatibility state.
|
|
34
|
-
3. `dsh-doctor --fix` shows the exact file edits or DSH command plan and waits for confirmation.
|
|
35
|
-
4. After applying confirmed repairs, Doctor runs the full diagnosis again and determines the exit code from the final state.
|
|
43
|
+
Version 0.4.0 composes the configuration from an empty tree in the same order as current DSH:
|
|
36
44
|
|
|
37
|
-
|
|
45
|
+
```text
|
|
46
|
+
bundle layers → profile cordis.patch.yml → home cordis.patch.yml → CLI overlays
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The JSON report retains `currentDefaultTree`, `currentEffectiveTree`, field-level provenance, replaced sources, and paths removed by whole-`config` replacement. It diagnoses stale patches, duplicate ids and mounts, higher-layer disabling or replacement, bundle/profile conflicts, plugin versions and artifacts, client contracts, dependencies, and runtime issues.
|
|
50
|
+
|
|
51
|
+
Every `pluginDiagnoses[]` object keeps current `status` separate from `recovery`. Being removable does not make an incompatible plugin compatible.
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
dsh-doctor diagnose
|
|
55
|
+
dsh-doctor diagnose --json
|
|
56
|
+
dsh-doctor diagnose --check-updates
|
|
57
|
+
```
|
|
38
58
|
|
|
39
|
-
|
|
59
|
+
Only `--check-updates` and `recover` contact the npm registry. Offline diagnosis reports `update.status: "not-checked"`; it never turns “not checked” into “no compatible version.”
|
|
40
60
|
|
|
41
|
-
|
|
61
|
+
## Compatible-version search
|
|
42
62
|
|
|
43
|
-
|
|
44
|
-
2. `DSH_DOCTOR_LANG`
|
|
45
|
-
3. `locale.preference` in the active DSH Home's `settings.yaml`
|
|
46
|
-
4. Terminal or system locale
|
|
63
|
+
Doctor checks all published manifests instead of trusting `latest`, then selects the highest version whose declared peer ranges accept the resolvable active DSH packages. This is only a manifest-declared candidate, not proof from a real startup or UI test.
|
|
47
64
|
|
|
48
65
|
```sh
|
|
49
|
-
dsh-doctor --
|
|
50
|
-
dsh-doctor --
|
|
51
|
-
|
|
66
|
+
dsh-doctor recover @scope/plugin --action check-update
|
|
67
|
+
dsh-doctor recover @scope/plugin --action update # preview
|
|
68
|
+
dsh-doctor recover @scope/plugin --action update --yes # exact version
|
|
52
69
|
```
|
|
53
70
|
|
|
54
|
-
|
|
71
|
+
## Quarantine
|
|
55
72
|
|
|
56
|
-
|
|
73
|
+
When no compatible release is available, generate and test a temporary overlay first:
|
|
57
74
|
|
|
58
75
|
```sh
|
|
59
|
-
|
|
60
|
-
dsh-doctor
|
|
61
|
-
dsh
|
|
62
|
-
|
|
63
|
-
dsh-doctor --dsh-command /path/to/@deepseek-ai/dsh/lib/bin.js
|
|
76
|
+
dsh-doctor recover @scope/plugin --action quarantine
|
|
77
|
+
dsh-doctor recover @scope/plugin --action quarantine --output ./plugin-quarantine.yml
|
|
78
|
+
dsh --profile web --patch ./plugin-quarantine.yml
|
|
79
|
+
```
|
|
64
80
|
|
|
65
|
-
|
|
66
|
-
dsh-doctor --json
|
|
81
|
+
Doctor only generates it when every active entry is mapped precisely, has a unique non-empty id and an exact name assertion, and the bundle does not rewrite entries owned by another layer. Core bundles, declared client dependents, and plugins statically detected as runtime Service providers with unproven dependents require manual review.
|
|
67
82
|
|
|
68
|
-
|
|
69
|
-
dsh-doctor --fix
|
|
83
|
+
After testing the overlay, persistence is separately gated:
|
|
70
84
|
|
|
71
|
-
|
|
72
|
-
dsh-doctor
|
|
85
|
+
```sh
|
|
86
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified
|
|
87
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified --yes
|
|
73
88
|
```
|
|
74
89
|
|
|
75
|
-
|
|
90
|
+
Persistence appends the final winning profile-layer disable override and refuses the write when a home or CLI overlay would still outrank it. It then recomposes the configuration and verifies every exact target is disabled; failed verification returns a nonzero exit code. The write rechecks SHA-256 and atomically replaces the profile patch. An existing patch gets a `.dsh-doctor-<timestamp>.bak`; a first-time file gets a `.rollback.json` containing its target and created-content hash, allowing deletion rollback only while the file is unchanged.
|
|
76
91
|
|
|
77
|
-
|
|
92
|
+
Preview and explicitly restore that backup or rollback record with `recover <package> --action rollback-quarantine --backup <path>`, adding `--yes` to apply it. Doctor only accepts timestamped recovery files belonging to the selected profile patch.
|
|
78
93
|
|
|
79
|
-
|
|
94
|
+
## Safe removal
|
|
80
95
|
|
|
81
|
-
|
|
82
|
-
- `risk`: Doctor found a current-version risk, such as a Harness peer range that rejects the new version, a dependency on a removed DSH package, an unsupported Node.js version, or installation drift.
|
|
83
|
-
- `unknown`: The plugin does not declare a Harness compatibility range through `peerDependencies`, or the active package version for a declared peer cannot be resolved. Doctor cannot prove it supports the upgraded DSH, but does not report uncertainty as a failure.
|
|
84
|
-
- `compatible`: The declared compatibility ranges accept the active Harness and no plugin-related errors or warnings were found.
|
|
96
|
+
Removal is always explicit and can never be inferred by legacy `--fix --yes`:
|
|
85
97
|
|
|
86
|
-
|
|
98
|
+
```sh
|
|
99
|
+
dsh-doctor recover @scope/plugin --action remove # impact preview
|
|
100
|
+
dsh-doctor recover @scope/plugin --action remove --yes
|
|
101
|
+
```
|
|
87
102
|
|
|
88
|
-
|
|
103
|
+
Automatic removal requires a direct profile dependency, a readable lockfile, a non-core bundle, no manual mount or dangling patch that would remain, and a working current DSH CLI. Before the official `dsh plugin --profile <name> remove <package>` command runs, Doctor saves a redacted diagnostic snapshot and quarantine overlay. It then re-diagnoses dependency, bundle-layer, and active-entry absence and reports the exact rollback install command.
|
|
89
104
|
|
|
90
|
-
|
|
91
|
-
- Syntax and top-level structure of profile, home, and bundle `cordis.patch.yml` files, including `!!js` expressions
|
|
92
|
-
- Safe structural checks for `settings.yaml` and `.credentials.yaml`; credential diagnostics never expose secret values
|
|
93
|
-
- Presence of profile dependencies, bundle declarations, patch files, and client bundles
|
|
94
|
-
- Consistency among the profile `package.json`, the `pnpm-lock.yaml` importer, and installed versions
|
|
95
|
-
- Node.js `engines`, Harness peer ranges, and obsolete DSH dependencies for all direct plugins, including bundle-only and server-side plugins
|
|
96
|
-
- Version drift and stale top-level `@deepseek-ai/dsh-*` packages across the active DSH CLI, Harness workspace, and profile
|
|
97
|
-
- The `platform`, `immediately`, `inject`, `external`, and `./client` export contract for `dsh.client`
|
|
98
|
-
- Consistency between literal `require()` calls in client bundles and external or module suppliers
|
|
99
|
-
- References to removed Harness client packages
|
|
100
|
-
- Third-party plugin peer ranges against actual active Harness versions
|
|
101
|
-
- Real resolution precedence where the Harness installation wins over a profile-local bundle with the same name
|
|
102
|
-
- Static composition of bundle, profile, and home patches in official Harness order, including missing targets, invalid group inserts, and name assertions, without loading plugins
|
|
105
|
+
Static analysis cannot prove the absence of dynamic Service dependencies, external data, or regressions in every real workflow. Restart the profile and validate its main functions after any bundle update or removal.
|
|
103
106
|
|
|
104
|
-
##
|
|
107
|
+
## Baselines
|
|
105
108
|
|
|
106
|
-
|
|
109
|
+
```sh
|
|
110
|
+
dsh-doctor baseline create
|
|
111
|
+
dsh-doctor baseline compare
|
|
112
|
+
dsh-doctor baseline create --output ./before-upgrade.json
|
|
113
|
+
```
|
|
107
114
|
|
|
108
|
-
-
|
|
109
|
-
- Doctor creates a `.dsh-doctor-<timestamp>.bak` backup before replacing a file atomically through a temporary file in the same directory.
|
|
110
|
-
- External commands use fixed argument arrays and never construct shell commands.
|
|
111
|
-
- `--json --fix --yes` captures subprocess output in the repair result so stdout remains exactly one valid JSON document.
|
|
112
|
-
- Command repairs bind the diagnosed `DSH_HOME` and show the resolved CLI path instead of assuming `dsh` exists on PATH.
|
|
113
|
-
- Each command repair has a 10-minute limit; a timeout terminates that action and marks subsequent actions as skipped.
|
|
114
|
-
- A failed repair stops later actions and preserves backups already created.
|
|
115
|
-
- Doctor runs every diagnostic again after repairs and uses the final state for its exit code.
|
|
115
|
+
The default baseline is `.dsh-doctor/baseline.json` inside the profile. It compares Harness state, package versions and compatibility, and introduced or resolved finding codes. It supplements current evidence; it is never required for diagnosis.
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
## Legacy confirmed repairs
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
`--fix` and `--repair` remain compatible with deterministic 0.1.x install, update, and bundle-manifest repairs. They never quarantine or remove a plugin. File actions are hash-checked, backed up, and atomically replaced; commands use fixed argv and the selected `DSH_HOME`.
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
- `1`: Doctor found a problem that may prevent Harness from starting
|
|
123
|
-
- `2`: Invalid arguments, an operational failure, or a failed repair
|
|
121
|
+
## Output, exit codes, and boundaries
|
|
124
122
|
|
|
125
|
-
|
|
123
|
+
Text output supports Chinese and English. `--json` keeps stable English codes and complete non-secret evidence; plugin `config` values and other common secret fields are replaced with `[REDACTED]`.
|
|
126
124
|
|
|
127
|
-
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
|
|
131
|
-
-
|
|
125
|
+
- `0`: no blocking error, or an explicit action passed static verification;
|
|
126
|
+
- `1`: a possible startup blocker remains, or recovery verification is incomplete;
|
|
127
|
+
- `2`: argument, environment, or action execution failure.
|
|
128
|
+
|
|
129
|
+
Doctor does not execute third-party plugins or evaluate `!!js`. It parses configuration structure, but redacts every plugin `config` value plus other common secret fields from JSON, baselines, and recovery snapshots; text reports do not print configuration values. Registry compatibility is declarative only. Dynamic services, external side effects, real UI behavior, and business workflows require real user validation. Ambiguous YAML or plugin ownership causes an automatic action to be refused.
|
|
132
130
|
|
|
133
131
|
## Development
|
|
134
132
|
|
|
135
133
|
```sh
|
|
136
134
|
npm install
|
|
137
135
|
npm run check
|
|
138
|
-
|
|
136
|
+
npm pack --dry-run
|
|
139
137
|
```
|
|
140
138
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
Before each later release, add a Chinese `## vX.Y.Z` entry matching the version tag to `CHANGELOG.md`. Pushing a tag that matches `package.json` makes the workflow publish through OIDC with npm provenance and automatically create or update the GitHub Release from that Chinese entry. The release fails if the entry is missing or contains no Chinese text. No long-lived npm token is required.
|
|
139
|
+
Publishing uses GitHub Actions OIDC and npm provenance. Local implementation and verification do not commit, tag, or publish automatically.
|
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,180 @@ 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
|
+
## 插件从 0.1.1 升级到 0.1.2
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Doctor 内置 `dsh-v0.1.1-rc.2 → dsh-v0.1.2-alpha.2` 的版本化迁移目录,并把升级拆成三个可审计阶段:
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
```sh
|
|
31
|
+
# 1. 只读分析源码、类型导入、manifest、client graph 与构建产物
|
|
32
|
+
dsh-doctor migrate analyze /path/to/plugin \
|
|
33
|
+
--harness-root /path/to/deepseek-harness
|
|
34
|
+
|
|
35
|
+
# 2. 预览 catalog 确认为 exact 的改写;加入 --yes 才写入并创建备份
|
|
36
|
+
dsh-doctor migrate apply /path/to/plugin --safe \
|
|
37
|
+
--harness-root /path/to/deepseek-harness
|
|
38
|
+
dsh-doctor migrate apply /path/to/plugin --safe --yes \
|
|
39
|
+
--harness-root /path/to/deepseek-harness
|
|
40
|
+
|
|
41
|
+
# 3. 依次完成静态、构建和隔离运行时验证
|
|
42
|
+
dsh-doctor migrate verify /path/to/plugin --level static \
|
|
43
|
+
--harness-root /path/to/deepseek-harness
|
|
44
|
+
dsh-doctor migrate verify /path/to/plugin --level build --yes \
|
|
45
|
+
--harness-root /path/to/deepseek-harness
|
|
46
|
+
dsh-doctor migrate verify /path/to/plugin --level runtime --yes \
|
|
47
|
+
--harness-root /path/to/deepseek-harness
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`analyze` 使用 TypeScript AST,因此能识别不会出现在 JavaScript bundle 中的 `import type`。`apply --safe` 只迁移 catalog 标记为精确等价的符号,并把非移除的 DSH 开发依赖固定到目标版本;例如 store 工具迁往 `dsh-client-store`,`ClientContext` 迁往 Cordis `Context` 并保留本地别名。它可能补充精确符号迁移需要的新依赖,但不会自动修改已有 peer 的版本范围。Session、Workspace、Conversation 和 pending interaction 属于所有权及生命周期变化,会保留为 `MIG_SEMANTIC_API_CHANGE`,不会被机械替换。
|
|
51
|
+
|
|
52
|
+
`artifact-verified` 至少要求成功执行 `build` 或 `pack:check`,仅有 `test`/`typecheck` 不足以证明发布产物。`runtime` 会从插件仓库打真实 tarball,在临时 `DSH_HOME` 中通过目标 DSH CLI 安装到全新 web profile、组合配置并做激活 smoke,不触碰普通用户的 `~/.dsh`;它还会核验目标 CLI 版本、profile manifest、安装后的包、bundle 激活和有效配置证据,不能由一个只返回成功码的空脚本伪造。失败现场会保留并报告路径;成功后默认清理。最高状态分为 `analyzed`、`source-migrated`、`artifact-verified` 和 `runtime-verified`;真实 UI、生命周期与业务行为仍需单独验证。
|
|
53
|
+
|
|
54
|
+
仓库还随包提供 [`dsh-plugin-upgrade` skill](skills/dsh-plugin-upgrade/SKILL.md),用于指导编码 Agent 严格按上述阶段帮助插件开发者升级。
|
|
31
55
|
|
|
32
|
-
|
|
33
|
-
2. Doctor 按错误、警告和插件兼容状态展示证据与建议。
|
|
34
|
-
3. `dsh-doctor --fix` 先展示精确的文件修改或 DSH 命令计划,并等待用户确认。
|
|
35
|
-
4. 修复完成后自动重新诊断,以最终状态决定退出码。
|
|
56
|
+
## 0.4.0 的诊断模型
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
`diagnose` 从空树开始,按当前 DSH 的正式顺序组合:
|
|
38
59
|
|
|
39
|
-
|
|
60
|
+
```text
|
|
61
|
+
bundle layers → profile cordis.patch.yml → home cordis.patch.yml → CLI overlays
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
JSON 同时保留 `currentDefaultTree`、`currentEffectiveTree`、字段级来源、被替换来源和 `config` 整体替换时丢失的字段路径。重点识别:
|
|
40
65
|
|
|
41
|
-
|
|
66
|
+
- 旧 patch、缺失 target、错误 name assertion;
|
|
67
|
+
- 重复 entry id、重复插件 mount;
|
|
68
|
+
- 高层禁用、结构替换、group/config 整体覆盖;
|
|
69
|
+
- bundle 声明与 profile 激活状态冲突;
|
|
70
|
+
- 插件版本、产物、client contract、依赖与运行环境问题。
|
|
42
71
|
|
|
43
|
-
|
|
44
|
-
2. `DSH_DOCTOR_LANG`
|
|
45
|
-
3. 当前 DSH Home 中 `settings.yaml` 的 `locale.preference`
|
|
46
|
-
4. 终端或系统 locale
|
|
72
|
+
每个 `pluginDiagnoses[]` 都把当前 `status` 与可选 `recovery` 分开。插件即使能够隔离或删除,也不会因此被标记为已经兼容。
|
|
47
73
|
|
|
48
74
|
```sh
|
|
49
|
-
dsh-doctor
|
|
50
|
-
dsh-doctor --
|
|
51
|
-
|
|
75
|
+
dsh-doctor diagnose
|
|
76
|
+
dsh-doctor diagnose --json
|
|
77
|
+
dsh-doctor diagnose --check-updates
|
|
52
78
|
```
|
|
53
79
|
|
|
54
|
-
`--
|
|
80
|
+
只有 `--check-updates` 和 `recover` 会访问 npm registry。离线诊断只报告 `update.status: "not-checked"`,绝不会把“未检查”写成“没有兼容版本”。
|
|
55
81
|
|
|
56
|
-
##
|
|
82
|
+
## 兼容版本检查
|
|
57
83
|
|
|
58
|
-
DSH
|
|
84
|
+
Doctor 会检查所有已发布版本的 manifest,而不是只看 `latest`,并选出声明兼容当前可解析 DSH package 版本的最高版本。结论仅表示“manifest 声明兼容的候选版本”,不代表已经通过真实启动或 UI 验证。更新始终绑定精确版本:
|
|
59
85
|
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
86
|
+
```sh
|
|
87
|
+
dsh-doctor recover @scope/plugin --action check-update
|
|
88
|
+
dsh-doctor recover @scope/plugin --action update # 只预览
|
|
89
|
+
dsh-doctor recover @scope/plugin --action update --yes # 执行精确版本
|
|
90
|
+
```
|
|
64
91
|
|
|
65
|
-
|
|
92
|
+
## 临时与持久隔离
|
|
66
93
|
|
|
67
|
-
|
|
94
|
+
没有兼容版本时,默认先生成临时 overlay,再用实际 profile 验证其余功能:
|
|
68
95
|
|
|
69
96
|
```sh
|
|
70
|
-
|
|
71
|
-
dsh-doctor
|
|
72
|
-
dsh
|
|
73
|
-
|
|
74
|
-
dsh-doctor --dsh-command /path/to/@deepseek-ai/dsh/lib/bin.js
|
|
97
|
+
dsh-doctor recover @scope/plugin --action quarantine
|
|
98
|
+
dsh-doctor recover @scope/plugin --action quarantine --output ./plugin-quarantine.yml
|
|
99
|
+
dsh --profile web --patch ./plugin-quarantine.yml
|
|
100
|
+
```
|
|
75
101
|
|
|
76
|
-
|
|
77
|
-
dsh-doctor --json
|
|
102
|
+
只有所有活跃 entry 均能精确定位、都有唯一非空 id、name assertion 明确,且 bundle 没有改写其他来源 entry 时,Doctor 才会生成 overlay。核心 bundle、存在 client 依赖者或静态检测到提供运行时 Service 但无法证明依赖关系的插件都要求人工审查。overlay 会禁用插件所有已知活跃 entry,使 host 与 client 来源同时退出组合。
|
|
78
103
|
|
|
79
|
-
|
|
80
|
-
dsh-doctor --fix
|
|
104
|
+
验证完成后才可持久化:
|
|
81
105
|
|
|
82
|
-
|
|
83
|
-
|
|
106
|
+
```sh
|
|
107
|
+
# 先预览精确差异
|
|
108
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified
|
|
109
|
+
|
|
110
|
+
# 明确确认后写入 profile/cordis.patch.yml
|
|
111
|
+
dsh-doctor recover @scope/plugin --action persist-quarantine --verified --yes
|
|
84
112
|
```
|
|
85
113
|
|
|
86
|
-
|
|
114
|
+
持久写入会追加 profile 层最终生效的禁用覆盖;如果 home 或 CLI overlay 等更高层仍会覆盖它,Doctor 会在写入前拒绝。写入后重新组合配置并逐个验证目标 entry 确实处于 disabled 状态;验证失败会返回非零退出码。写入前重新校验 SHA-256 并原子替换文件。已有 patch 会创建 `.dsh-doctor-<timestamp>.bak`;首次新建 patch 会创建 `.rollback.json`,其中记录目标文件和创建内容哈希,以便只在文件未被再次修改时执行删除式回滚。旧的 `disabled: true` 不会自动过期,所以插件升级后应重新诊断并决定是否撤销。
|
|
87
115
|
|
|
88
|
-
|
|
116
|
+
可先预览并显式恢复该次备份或回滚记录;Doctor 只接受属于当前 profile patch 的时间戳恢复文件:
|
|
89
117
|
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
|
|
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;不会加载插件
|
|
118
|
+
```sh
|
|
119
|
+
dsh-doctor recover @scope/plugin --action rollback-quarantine --backup /path/to/cordis.patch.yml.dsh-doctor-...bak
|
|
120
|
+
dsh-doctor recover @scope/plugin --action rollback-quarantine --backup /path/to/cordis.patch.yml.dsh-doctor-...bak --yes
|
|
121
|
+
# 首次新建时,把上面的 .bak 换成命令返回的 .rollback.json
|
|
122
|
+
```
|
|
103
123
|
|
|
104
|
-
##
|
|
124
|
+
## 安全删除
|
|
105
125
|
|
|
106
|
-
|
|
126
|
+
删除是独立动作,永远不会由通用 `--fix --yes` 推断:
|
|
107
127
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
-
|
|
111
|
-
|
|
112
|
-
- 命令修复绑定当前诊断的 `DSH_HOME`,并展示解析出的真实 CLI 路径;不会假定 PATH 中存在 `dsh`。
|
|
113
|
-
- 单个命令修复最长运行 10 分钟,超时会终止该动作并把后续动作标记为跳过。
|
|
114
|
-
- 任一步失败即停止后续修复,并保留已经创建的备份。
|
|
115
|
-
- 完成后重新运行全部诊断,以最终状态决定退出码。
|
|
128
|
+
```sh
|
|
129
|
+
dsh-doctor recover @scope/plugin --action remove # 只做影响预检
|
|
130
|
+
dsh-doctor recover @scope/plugin --action remove --yes # 显式执行
|
|
131
|
+
```
|
|
116
132
|
|
|
117
|
-
|
|
133
|
+
自动删除要求插件是 profile 直接依赖、不是模板/内置核心 bundle、lockfile 可读、没有会残留的手工 mount 或 dangling patch,并且当前 DSH CLI 可用。执行前会保存已脱敏的诊断快照和临时 quarantine overlay,再调用官方命令:
|
|
118
134
|
|
|
119
|
-
|
|
135
|
+
```sh
|
|
136
|
+
dsh plugin --profile web remove @scope/plugin
|
|
137
|
+
```
|
|
120
138
|
|
|
121
|
-
|
|
122
|
-
- `1`:发现可能阻断 Harness 启动的问题
|
|
123
|
-
- `2`:参数、运行环境或修复执行失败
|
|
139
|
+
成功后重新诊断并分别验证 dependency、bundle layer 和活跃 entry 已消失,同时保留原版本的精确回滚安装命令。静态检查无法证明不存在动态 Service 依赖、外部数据残留或所有真实业务流程都正常;完成后仍须重启 profile 并验证主要功能。
|
|
124
140
|
|
|
125
|
-
##
|
|
141
|
+
## 历史基线
|
|
126
142
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
143
|
+
升级前保存基线,升级后比较插件版本、兼容状态、Harness 与 finding 变化:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
dsh-doctor baseline create
|
|
147
|
+
dsh-doctor baseline compare
|
|
148
|
+
|
|
149
|
+
# 自定义基线路径
|
|
150
|
+
dsh-doctor baseline create --output ./before-upgrade.json
|
|
151
|
+
dsh-doctor baseline compare --output ./before-upgrade.json
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
默认基线位于 profile 的 `.dsh-doctor/baseline.json`。基线用于差异归因,不是当前诊断的前提,也不会覆盖当前现场证据。
|
|
155
|
+
|
|
156
|
+
## 旧版确认式修复
|
|
157
|
+
|
|
158
|
+
`--fix` / `--repair` 继续兼容 0.1.x 的确定性 install、update 与 bundle manifest 修复:
|
|
159
|
+
|
|
160
|
+
```sh
|
|
161
|
+
dsh-doctor --fix
|
|
162
|
+
dsh-doctor --fix --yes --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
它不会触发 quarantine、持久化隔离或删除。文件动作展示路径并创建备份,命令使用固定 argv、绑定当前 `DSH_HOME`,任一步失败都会停止后续动作。
|
|
166
|
+
|
|
167
|
+
## 输出与退出码
|
|
168
|
+
|
|
169
|
+
文本支持中文和英文,优先级为 `--lang`、`DSH_DOCTOR_LANG`、DSH 设置和系统 locale。`--json` 始终保留稳定英文 code 和完整的非秘密证据;插件 `config` 值和其他常见秘密字段会替换为 `[REDACTED]`。
|
|
170
|
+
|
|
171
|
+
- `0`:没有阻断错误,或显式动作成功且静态验证通过;
|
|
172
|
+
- `1`:仍有可能阻断启动的问题,或恢复后静态状态不完整;
|
|
173
|
+
- `2`:参数、运行环境或动作执行失败。
|
|
174
|
+
|
|
175
|
+
## 安全边界
|
|
176
|
+
|
|
177
|
+
- 不执行第三方插件,不求值 `!!js`;诊断会解析配置结构,但 JSON、baseline 和恢复快照会脱敏所有插件 `config` 值及其他常见秘密字段,文本报告也不打印配置值;
|
|
178
|
+
- registry 结果只证明 manifest 声明,不证明真实运行兼容;
|
|
179
|
+
- 动态 Service 依赖、外部副作用、真实 UI 和业务流程需要用户验证;
|
|
180
|
+
- patch 精确编辑只处理 Doctor 能安全解析和定位的结构;有歧义时拒绝自动操作;
|
|
181
|
+
- 添加、更新或删除 bundle 后,运行中的 profile 不会自动改变 bundle 集合,必须重启。
|
|
132
182
|
|
|
133
183
|
## 从源码开发
|
|
134
184
|
|
|
135
185
|
```sh
|
|
136
186
|
npm install
|
|
137
187
|
npm run check
|
|
138
|
-
|
|
188
|
+
npm pack --dry-run
|
|
139
189
|
```
|
|
140
190
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
后续发布前,需要在 `CHANGELOG.md` 中增加与版本 tag 同名的中文 `## vX.Y.Z` 条目。推送与 `package.json` 版本一致的 tag 后,workflow 会通过 OIDC 发布 npm 包、生成 provenance,并自动用该中文条目创建或更新 GitHub Release;缺少中文条目时发布流程会失败。不需要保存长期 npm token。
|
|
191
|
+
发布仍使用 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
|
+
}
|