dsh-project-mcp-manager 0.6.0 → 0.7.2
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 +45 -9
- package/docs/README.zh.md +39 -6
- package/docs/code-review/review-feat-adapt-dsh-0.2.0-rc.2.zh.md +190 -0
- package/docs/design/adaptation-dsh-0.1.6-alpha.2.md +262 -0
- package/docs/design/adaptation-dsh-0.2.0-rc.2.md +89 -0
- package/docs/design/proposal-runtime-robustness-and-json-interop.md +3 -1
- package/docs/guide/env-expansion.md +7 -0
- package/docs/guide/env-expansion.zh.md +5 -0
- package/docs/guide/format.md +7 -2
- package/docs/guide/format.zh.md +6 -2
- package/docs/guide/service.md +95 -0
- package/docs/guide/service.zh.md +88 -0
- package/docs/releases/v0.7.0.md +41 -0
- package/docs/releases/v0.7.1.md +49 -0
- package/docs/releases/v0.7.2.md +37 -0
- package/lib/cli.d.ts +42 -0
- package/lib/dsh-paths.d.ts +42 -0
- package/lib/index.d.ts +24 -0
- package/lib/index.js +1 -1
- package/lib/json-file.d.ts +111 -0
- package/lib/json-file.js +3 -0
- package/lib/json-write.d.ts +32 -0
- package/lib/json-write.js +3 -1
- package/lib/mcp-file.d.ts +46 -0
- package/lib/model.d.ts +277 -0
- package/lib/model.js +12 -1
- package/lib/project-root.d.ts +4 -0
- package/lib/registry.d.ts +439 -0
- package/lib/registry.js +57 -29
- package/lib/service.d.ts +41 -0
- package/lib/service.js +5 -0
- package/lib/status.d.ts +20 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -9,10 +9,21 @@ session opens in that project. Changes to the file hot-reload into the running
|
|
|
9
9
|
dsh process, and tool visibility is scoped per session cwd. No UI — core
|
|
10
10
|
functionality only.
|
|
11
11
|
|
|
12
|
-
**Capability boundary
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
**Capability boundary** (dsh ≥ 0.2.0-rc.2): the official client owns the
|
|
13
|
+
protocol, reconnect, tool names, resources, and server instructions. Shipped
|
|
14
|
+
profiles already mount shared MCP resource tools. Official configuration is
|
|
15
|
+
a profile-layer Cordis patch (with that layer's own HMR) plus
|
|
16
|
+
`plugin_manager`. This plugin still owns what the host does not:
|
|
17
|
+
|
|
18
|
+
1. Project-level discovery of `<projectRoot>/.dsh/mcp.yml`, `.dsh/mcp.json`,
|
|
19
|
+
and the read-only legacy `.mcp.json`.
|
|
20
|
+
2. Tool visibility isolated by session cwd.
|
|
21
|
+
3. The MCP file format and the `dsh-mcp` CLI.
|
|
22
|
+
|
|
23
|
+
Project-file hot reload is this plugin's file watcher. It does not replace
|
|
24
|
+
official profile HMR. **Transport types are decided by the official client.**
|
|
25
|
+
v0.7.x targets the dsh `0.2.0` line starting at 0.2.0-rc.2. Hosts still on
|
|
26
|
+
dsh 0.1.5 should stay on plugin v0.6.0.
|
|
16
27
|
|
|
17
28
|
If this plugin is useful, a GitHub
|
|
18
29
|
[star](https://github.com/wldxiaobai/dsh-project-mcp-manager) is appreciated.
|
|
@@ -32,12 +43,20 @@ Feature documentation lives in `docs/`, English and Chinese side by side:
|
|
|
32
43
|
- [`${VAR}` expansion](docs/guide/env-expansion.md) — mount-time interpolation and
|
|
33
44
|
its diagnostics.
|
|
34
45
|
- [CLI `dsh-mcp`](docs/guide/cli.md) — scopes, write formats, ownership contract.
|
|
46
|
+
- [Query surface](docs/guide/service.md) — `ctx.projectMcp`, the
|
|
47
|
+
`projectMcp/updated` event, exported view types, and the semver contract for
|
|
48
|
+
the companion UI.
|
|
35
49
|
|
|
36
|
-
Design and release records (Chinese): [dsh 0.
|
|
50
|
+
Design and release records (Chinese): [dsh 0.2.0-rc.2 adaptation](docs/design/adaptation-dsh-0.2.0-rc.2.md) ·
|
|
51
|
+
[dsh 0.1.6-alpha.2 adaptation plan](docs/design/adaptation-dsh-0.1.6-alpha.2.md) ·
|
|
52
|
+
[dsh 0.1.5-rc.2 adaptation](docs/design/adaptation-dsh-0.1.5-rc2.md) ·
|
|
37
53
|
[dsh 0.1.5-rc.1 adaptation](docs/design/adaptation-dsh-0.1.5-rc1.md) ·
|
|
38
54
|
[dsh 0.1.2-rc.1 adaptation](docs/design/adaptation-dsh-0.1.2-rc1.md) ·
|
|
39
55
|
[JSON config layer proposal](docs/design/proposal-json-mcp-config.md) ·
|
|
40
56
|
[Runtime robustness & JSON interop proposal](docs/design/proposal-runtime-robustness-and-json-interop.md) ·
|
|
57
|
+
[v0.7.2 release notes](docs/releases/v0.7.2.md) ·
|
|
58
|
+
[v0.7.1 release notes](docs/releases/v0.7.1.md) ·
|
|
59
|
+
[v0.7.0 release notes](docs/releases/v0.7.0.md) ·
|
|
41
60
|
[v0.6.0 release notes](docs/releases/v0.6.0.md) ·
|
|
42
61
|
[v0.4.3 release notes](docs/releases/v0.4.3.md) ·
|
|
43
62
|
[v0.4.2 release notes](docs/releases/v0.4.2.md) ·
|
|
@@ -47,7 +66,8 @@ Design and release records (Chinese): [dsh 0.1.5-rc.2 adaptation](docs/design/ad
|
|
|
47
66
|
|
|
48
67
|
Code review records (Chinese): [TypeScript changes since v0.3.1](docs/code-review/ts-review-since-v0.3.1.zh.md) ·
|
|
49
68
|
[v0.4.3 to v0.6.0](docs/code-review/ts-review-v0.4.3-to-v0.6.0.zh.md) ·
|
|
50
|
-
[7e0088d to 804662f (fix follow-up)](docs/code-review/ts-review-7e0088d-to-804662f.zh.md)
|
|
69
|
+
[7e0088d to 804662f (fix follow-up)](docs/code-review/ts-review-7e0088d-to-804662f.zh.md) ·
|
|
70
|
+
[feat/adapt-dsh-0.2.0-rc.2 (v0.7.0)](docs/code-review/review-feat-adapt-dsh-0.2.0-rc.2.zh.md).
|
|
51
71
|
|
|
52
72
|
## Installation (mount into a profile)
|
|
53
73
|
|
|
@@ -74,7 +94,7 @@ dsh plugin --profile web add dsh-project-mcp-manager@latest
|
|
|
74
94
|
|
|
75
95
|
# Install a specific version (check available versions with
|
|
76
96
|
# npm view dsh-project-mcp-manager versions)
|
|
77
|
-
dsh plugin --profile web add dsh-project-mcp-manager@0.
|
|
97
|
+
dsh plugin --profile web add dsh-project-mcp-manager@0.7.2
|
|
78
98
|
```
|
|
79
99
|
|
|
80
100
|
**Option 2: install directly with pnpm** (equivalent to option 1):
|
|
@@ -101,8 +121,9 @@ pnpm add link:<path-to-your-dsh-mcp-project-source> # e.g. D:\dev\dsh-mcp-proj
|
|
|
101
121
|
> trigger the bundle reconcile.
|
|
102
122
|
|
|
103
123
|
**Upgrading / pinning versions**: re-run the `add` command from option 1 with
|
|
104
|
-
the desired version suffix — `@latest` upgrades to the newest release, `@0.
|
|
105
|
-
pins to a specific version.
|
|
124
|
+
the desired version suffix — `@latest` upgrades to the newest release, `@0.7.2`
|
|
125
|
+
pins to a specific version. v0.7.x needs dsh 0.2.0-rc.2 (the `0.2.0` line).
|
|
126
|
+
dsh 0.1.5 keeps working with plugin `@0.6.0`.
|
|
106
127
|
|
|
107
128
|
## Build & test
|
|
108
129
|
|
|
@@ -162,6 +183,21 @@ pnpm test # node test/test-model.mjs / test-mcp-file / test-json-file /
|
|
|
162
183
|
falls back to the owner project (subagents), then to the project containing
|
|
163
184
|
the dsh process cwd. Released when the session is destroyed.
|
|
164
185
|
|
|
186
|
+
## Query surface
|
|
187
|
+
|
|
188
|
+
Other plugins and the companion UI read mount state from `ctx.projectMcp`
|
|
189
|
+
(`snapshot`, `serverView`, `globalState`, `reload`). Queries are the previous
|
|
190
|
+
reconcile's memory; they do not read disk. A successful reconcile emits
|
|
191
|
+
`projectMcp/updated` with no payload. The listener calls `snapshot()` and
|
|
192
|
+
diffs. This package does not open a browser SSE channel.
|
|
193
|
+
|
|
194
|
+
That surface — the methods, the event, and the view types re-exported from the
|
|
195
|
+
package entry (`ProjectFileState`, `McpServerRuntimeView`, `McpServerView`,
|
|
196
|
+
`McpRowSource`, and the types those views name) — follows semantic versioning
|
|
197
|
+
for the companion UI. The UI package peer-depends on
|
|
198
|
+
`dsh-project-mcp-manager` at the **same exact version** (no `^` or `~`).
|
|
199
|
+
Details: [query surface](docs/guide/service.md).
|
|
200
|
+
|
|
165
201
|
## Security boundary
|
|
166
202
|
|
|
167
203
|
`stdio` lines in `.dsh/mcp.yml`, `.dsh/mcp.json` and `.mcp.json` spawn their
|
package/docs/README.zh.md
CHANGED
|
@@ -7,8 +7,19 @@
|
|
|
7
7
|
`@deepseek-ai/dsh-mcp-client`),文件改动热重载到运行中的 dsh 进程,并按
|
|
8
8
|
会话 cwd 控制工具可见性。无 UI,仅具备核心功能。
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
**能力边界**(dsh ≥ 0.2.0-rc.2):协议、重连、工具名、resources 与服务器
|
|
11
|
+
instructions 归官方 client。发行版 profile 已经装了共享的 MCP 资源工具。官方
|
|
12
|
+
配置是 profile 层 Cordis patch(该层自有 HMR)加上 `plugin_manager`。宿主还没做、
|
|
13
|
+
仍由本插件负责的是:
|
|
14
|
+
|
|
15
|
+
1. 项目级发现:`<projectRoot>/.dsh/mcp.yml`、`.dsh/mcp.json`,以及只读的遗留
|
|
16
|
+
`.mcp.json`。
|
|
17
|
+
2. 按会话 cwd 隔离工具可见性。
|
|
18
|
+
3. MCP 专用配置格式和 `dsh-mcp` CLI。
|
|
19
|
+
|
|
20
|
+
项目文件热重载是本插件自己的文件监听,不替代官方 profile HMR。**传输类型由官方
|
|
21
|
+
client 决定。** v0.7.x 面向 dsh `0.2.0` 线(从 0.2.0-rc.2 起)。仍在 dsh 0.1.5
|
|
22
|
+
上的宿主继续用插件 v0.6.0。
|
|
12
23
|
|
|
13
24
|
若这个插件对你有帮助,欢迎给仓库点一颗
|
|
14
25
|
[star](https://github.com/wldxiaobai/dsh-project-mcp-manager)。遇到问题、宿主
|
|
@@ -25,12 +36,19 @@
|
|
|
25
36
|
全局装载 vs 项目装载,以及只读的遗留 Claude Code 层。
|
|
26
37
|
- [`${VAR}` 展开](guide/env-expansion.zh.md)——装载时插值与对应诊断。
|
|
27
38
|
- [CLI `dsh-mcp`](guide/cli.zh.md)——作用域、写入格式与独占契约。
|
|
39
|
+
- [查询面](guide/service.zh.md)——`ctx.projectMcp`、`projectMcp/updated` 事件、
|
|
40
|
+
包入口导出的视图类型,以及对配套 UI 的语义化版本承诺。
|
|
28
41
|
|
|
29
|
-
设计与发布记录(中文):[dsh 0.
|
|
42
|
+
设计与发布记录(中文):[dsh 0.2.0-rc.2 适配记录](design/adaptation-dsh-0.2.0-rc.2.md) ·
|
|
43
|
+
[dsh 0.1.6-alpha.2 适配方案](design/adaptation-dsh-0.1.6-alpha.2.md) ·
|
|
44
|
+
[dsh 0.1.5-rc.2 适配记录](design/adaptation-dsh-0.1.5-rc2.md) ·
|
|
30
45
|
[dsh 0.1.5-rc.1 适配记录](design/adaptation-dsh-0.1.5-rc1.md) ·
|
|
31
46
|
[dsh 0.1.2-rc.1 适配记录](design/adaptation-dsh-0.1.2-rc1.md) ·
|
|
32
47
|
[JSON 配置层设计提案](design/proposal-json-mcp-config.md) ·
|
|
33
48
|
[运行时稳健性与 JSON 互通提案](design/proposal-runtime-robustness-and-json-interop.md) ·
|
|
49
|
+
[v0.7.2 发布说明](releases/v0.7.2.md) ·
|
|
50
|
+
[v0.7.1 发布说明](releases/v0.7.1.md) ·
|
|
51
|
+
[v0.7.0 发布说明](releases/v0.7.0.md) ·
|
|
34
52
|
[v0.6.0 发布说明](releases/v0.6.0.md) ·
|
|
35
53
|
[v0.4.3 发布说明](releases/v0.4.3.md) ·
|
|
36
54
|
[v0.4.2 发布说明](releases/v0.4.2.md) ·
|
|
@@ -40,7 +58,8 @@
|
|
|
40
58
|
|
|
41
59
|
代码审查记录(中文):[v0.3.1 以来 TypeScript 变更审查](code-review/ts-review-since-v0.3.1.zh.md) ·
|
|
42
60
|
[v0.4.3 至 v0.6.0](code-review/ts-review-v0.4.3-to-v0.6.0.zh.md) ·
|
|
43
|
-
[7e0088d 至 804662f(审查落地复查)](code-review/ts-review-7e0088d-to-804662f.zh.md)
|
|
61
|
+
[7e0088d 至 804662f(审查落地复查)](code-review/ts-review-7e0088d-to-804662f.zh.md) ·
|
|
62
|
+
[feat/adapt-dsh-0.2.0-rc.2(v0.7.0)](code-review/review-feat-adapt-dsh-0.2.0-rc.2.zh.md)。
|
|
44
63
|
|
|
45
64
|
## 安装(挂载到 profile)
|
|
46
65
|
|
|
@@ -63,7 +82,7 @@ npm install -g deepseek-ai/dsh # 或从 GitHub 源码安装
|
|
|
63
82
|
dsh plugin --profile web add dsh-project-mcp-manager@latest
|
|
64
83
|
|
|
65
84
|
# 安装指定版本(版本号可先 npm view dsh-project-mcp-manager versions 查看)
|
|
66
|
-
dsh plugin --profile web add dsh-project-mcp-manager@0.
|
|
85
|
+
dsh plugin --profile web add dsh-project-mcp-manager@0.7.2
|
|
67
86
|
```
|
|
68
87
|
|
|
69
88
|
**方式二:直接 pnpm 安装**(与方式一等价):
|
|
@@ -88,7 +107,8 @@ pnpm add link:<你的 dsh-mcp-project 源码目录> # 例如 D:\dev\dsh-mcp-pr
|
|
|
88
107
|
> `dsh-project-mcp-manager` 行)触发 bundle reconcile。
|
|
89
108
|
|
|
90
109
|
**升级/锁定版本**:重跑方式一的 `add` 命令并带上目标版本后缀——`@latest`
|
|
91
|
-
升级到最新,`@0.
|
|
110
|
+
升级到最新,`@0.7.2` 锁定到指定版本。v0.7.x 需要 dsh 0.2.0-rc.2(`0.2.0` 线)。
|
|
111
|
+
dsh 0.1.5 继续用插件 `@0.6.0`。
|
|
92
112
|
|
|
93
113
|
## 构建与测试
|
|
94
114
|
|
|
@@ -131,6 +151,19 @@ pnpm test # node 直跑 test/ 下六个 .mjs(model / mcp-file / json-
|
|
|
131
151
|
自身行压制过的全局服务器;会话无 cwd 时回退 owner 项目(子代理),再回退 dsh
|
|
132
152
|
进程 cwd 所在项目。会话销毁时释放。
|
|
133
153
|
|
|
154
|
+
## 查询面
|
|
155
|
+
|
|
156
|
+
其它插件和配套 UI 从 `ctx.projectMcp`(`snapshot`、`serverView`、`globalState`、
|
|
157
|
+
`reload`)读装载状态。查询看到的是上一轮对账的内存,不读盘。对账成功结束时 emit
|
|
158
|
+
`projectMcp/updated`,无载荷。监听方再调 `snapshot()` 自己 diff。本包不打开浏览器
|
|
159
|
+
SSE。
|
|
160
|
+
|
|
161
|
+
这个面——方法、事件,以及从包入口再导出的视图类型(`ProjectFileState`、
|
|
162
|
+
`McpServerRuntimeView`、`McpServerView`、`McpRowSource`,以及这些视图点名的类型)
|
|
163
|
+
——对配套 UI 按语义化版本承诺。UI 包把 `dsh-project-mcp-manager` 写成
|
|
164
|
+
peer dependency,并锁定到**同一精确版本**(不要写 `^` 或 `~`)。详见
|
|
165
|
+
[查询面](guide/service.zh.md)。
|
|
166
|
+
|
|
134
167
|
## 安全边界
|
|
135
168
|
|
|
136
169
|
`.dsh/mcp.yml`、`.dsh/mcp.json` 与 `.mcp.json` 中的 `stdio` 行会在 dsh
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# 代码审查:feat/adapt-dsh-0.2.0-rc.2(v0.7.0,适配 dsh 0.2.0-rc.2)
|
|
2
|
+
|
|
3
|
+
[← 返回 README](../README.zh.md) | 相关:[上一轮审查(7e0088d 至 804662f)](ts-review-7e0088d-to-804662f.zh.md) ·
|
|
4
|
+
[dsh 0.2.0-rc.2 适配记录](../design/adaptation-dsh-0.2.0-rc.2.md) ·
|
|
5
|
+
[v0.7.0 发布说明](../releases/v0.7.0.md)
|
|
6
|
+
|
|
7
|
+
**审查日期**:2026-09-30 | **分支**:`feat/adapt-dsh-0.2.0-rc.2`(HEAD `1d586a9`)
|
|
8
|
+
**基线**:`dev`(merge-base `1af9887`)| **静态分析**:SonarCloud PR #13
|
|
9
|
+
([issues 列表](https://sonarcloud.io/project/issues?id=wldxiaobai_dsh-project-mcp-manager&pullRequest=13&issueStatuses=OPEN%2CCONFIRMED&s=IMPACT_RANK),
|
|
10
|
+
OPEN/CONFIRMED 共 24 条,技术债合计 120 min)
|
|
11
|
+
|
|
12
|
+
**范围**:4 个 commit,21 文件 `+583 / −954`。代码逻辑只动了 4 个 `src` 文件
|
|
13
|
+
(`model.ts` +23、`registry.ts` +1/−8、`json-file.ts` +2、`json-write.ts` +2/−1),
|
|
14
|
+
其余是依赖、锁文件与文档。
|
|
15
|
+
|
|
16
|
+
| commit | 内容 |
|
|
17
|
+
|---|---|
|
|
18
|
+
| `aea9aea` | `dsh-mcp-client` `^0.1.5-rc.1` → `^0.2.0-rc.2`,cordis `^4.0.2` → `^4.0.4`,重写 `minimumReleaseAgeExclude` |
|
|
19
|
+
| `1893ec5` | 删除 `agent/session-start` 监听 |
|
|
20
|
+
| `b2f945e` | 透传可选 `maxInstructionBytes`(yml / JSON / view / CLI 写 JSON) |
|
|
21
|
+
| `1d586a9` | 版本 0.7.0、CHANGELOG、README、适配记录、发布说明 |
|
|
22
|
+
|
|
23
|
+
**关于 PR #13 的口径**:GitHub 上 PR #13 是 `dev → main`(标题 "Dev",无描述),
|
|
24
|
+
6 个 commit、21 文件 `+844 / −953`。这与本地 `origin/dev..feat/adapt-dsh-0.2.0-rc.2`
|
|
25
|
+
的统计完全一致,即 PR #13 = 本分支 4 个 commit + `1af9887`(0.1.6-alpha.2 方案文档)
|
|
26
|
+
+ `e76eb1c`(README 提示)。因此 Sonar 结果可以直接对应本分支。
|
|
27
|
+
|
|
28
|
+
**方法**:通读 `dev...feat` 全部 diff 与相关上下文;逐条对照 Sonar 问题所在行;
|
|
29
|
+
本地验证见第 5 节。
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 1. 结论
|
|
34
|
+
|
|
35
|
+
**可以合入,建议先处理 S1(未处理的 Promise)。** 本分支自身的改动小而准:
|
|
36
|
+
依赖范围、事件删除、新字段透传三处都和适配记录里的上游变化一一对应,测试覆盖了
|
|
37
|
+
新字段的透传与缺省省略。
|
|
38
|
+
|
|
39
|
+
Sonar 的 24 条问题**没有一条落在本分支改动的行上**:它们全在 `dev` 已有代码里
|
|
40
|
+
(创建日期 2026-08-22 至 2026-09-12,早于本分支),因为 PR 碰了 `registry.ts`
|
|
41
|
+
而被一并列出(S9381/S9382/S9383 是较新的规则编号)。其中只有 3 条 S9383 是真实的
|
|
42
|
+
可靠性问题,其余属于有意设计或风格项。
|
|
43
|
+
|
|
44
|
+
| 级别 | 数量 | 说明 |
|
|
45
|
+
|---|---|---|
|
|
46
|
+
| 中 | 1 | S1:构造函数里三处 `enqueue(...)` 未处理 rejection(Sonar S9383 ×3) |
|
|
47
|
+
| 低 | 5 | 分支自身 B1–B4;Sonar S7503 / S9381 风格项 |
|
|
48
|
+
| 接受现状 | 15 | Sonar S9382「循环内 await」:串行化是装载语义的一部分 |
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## 2. Sonar 问题逐条研判
|
|
53
|
+
|
|
54
|
+
### 2.1 S9383 Promise 未处理(BUG,可靠性·中)×3 —— **应修**
|
|
55
|
+
|
|
56
|
+
位置:[registry.ts:784](../../src/registry.ts#L784)、[:792](../../src/registry.ts#L792)、[:798](../../src/registry.ts#L798)。
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
ctx.on("agent/created", ({ agent }: any) => {
|
|
60
|
+
if (agent === undefined) return;
|
|
61
|
+
this.enqueue(async () => { ... await this.reconcileAll(); }); // 返回值被丢弃
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`enqueue()` 返回的是 `run`([registry.ts:849-853](../../src/registry.ts#L849-L853)),
|
|
66
|
+
链尾 `this.chain` 吞掉了错误,但 `run` 本身仍会 reject。只要 `resolveProject` 之后的
|
|
67
|
+
`reconcileAll()` 抛出(chokidar `syncWatcher`、`scanProject` 中未捕获的 I/O 等),
|
|
68
|
+
就会产生 unhandled rejection。Node 15+ 默认对 unhandled rejection 直接终止进程;
|
|
69
|
+
宿主是否装了全局处理器本次没有核实,但插件不应依赖这一点。
|
|
70
|
+
|
|
71
|
+
同文件其他调用点(`kick`、`scheduleGraceUnmount`、`kickSweep`、`trackMount`)都已
|
|
72
|
+
`.catch(() => {})`,这三处是遗漏。本分支删除的 `agent/session-start` 监听恰好是第四处
|
|
73
|
+
同类问题,删掉后数量从 4 降到 3。
|
|
74
|
+
|
|
75
|
+
建议:
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
void this.enqueue(async () => { ... }).catch((error) => {
|
|
79
|
+
this.ctx.logger.warn(`项目 MCP 对账失败:${error instanceof Error ? error.message : String(error)}`);
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
比 `.catch(() => {})` 多记一条日志,方便定位。可以顺手抽一个
|
|
84
|
+
`private schedule(work)` 统一所有「后台入队」调用。
|
|
85
|
+
|
|
86
|
+
### 2.2 S7503 async 箭头函数里没有 await(CODE_SMELL,低)×2
|
|
87
|
+
|
|
88
|
+
位置:[registry.ts:2208](../../src/registry.ts#L2208)(`serverView`)、[:2240](../../src/registry.ts#L2240)(`snapshot`)。
|
|
89
|
+
|
|
90
|
+
`this.enqueue(async () => this.serverViewFromMemory(...))`:`async` 只是为了满足
|
|
91
|
+
`enqueue` 的 `() => Promise<T>` 签名。行为正确。可改为
|
|
92
|
+
`this.enqueue(() => Promise.resolve(this.serverViewFromMemory(...)))`,
|
|
93
|
+
或者放宽 `enqueue` 的签名为 `() => T | Promise<T>`。优先级低。
|
|
94
|
+
|
|
95
|
+
### 2.3 S9381 嵌套 Promise(CODE_SMELL,低)×2
|
|
96
|
+
|
|
97
|
+
位置:[registry.ts:1826](../../src/registry.ts#L1826)、[:1835](../../src/registry.ts#L1835),
|
|
98
|
+
在 `trackMount` 的 `fiber.then(onActive, onFailed)` 回调里再 `enqueue(...).catch()`。
|
|
99
|
+
|
|
100
|
+
这是有意的:fiber settle 时刻不在对账链上,诊断写必须排回链里以免 RMW 竞态(代码注释
|
|
101
|
+
已写明)。不需要改语义。想消掉告警可以抽 `private enqueueDiag(container, event)`,
|
|
102
|
+
回调里只调一个同步方法。
|
|
103
|
+
|
|
104
|
+
### 2.4 S9382 循环内 await(CODE_SMELL,可维护性·低)×15 —— **建议在 Sonar 标记 Accepted**
|
|
105
|
+
|
|
106
|
+
| 行 | 位置 | 能否并行 | 理由 |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| 800 | 构造补扫 `resolveProject` | 可以但无收益 | 一次性,会话数很小 |
|
|
109
|
+
| 903 | `knownProjects` 的 `findProjectRoot` | 可以 | 只读,`Promise.all` 安全 |
|
|
110
|
+
| 1150、1998 | `liveMountKeys` / `sweepRestrictions` 的 `resolveProject` | 可以但无收益 | 大多命中 `agentProjects` 缓存 |
|
|
111
|
+
| 1251 | 指纹 `statConfigFile` | **可以** | 纯只读 stat,每轮对账都跑,项目多时收益最明显 |
|
|
112
|
+
| 1298、1302 | `scanProject` | 不建议 | 会写诊断、改 `configReadCount`,并发后测试口径和日志顺序会变 |
|
|
113
|
+
| 1320 | 逐项目 `reconcileProject` | 不可以 | 生效名预留与装载顺序依赖串行 |
|
|
114
|
+
| 1589、1600 | 先 unmount 再 mount | **不可以** | AGENTS.md 明确要求同名先释放预留再装载 |
|
|
115
|
+
| 1714、1719 | `writeSummaries` 逐文件写 | 可以但无收益 | 各自有锁,数量小 |
|
|
116
|
+
| 1885、1934 | 健康巡检 remount | 不可以 | 逐条 unmount/mount 改动容器状态 |
|
|
117
|
+
| 2159、2174 | `waitForState` 轮询 `delay(200)` | 不适用 | 轮询本来就要逐次等待(测试辅助) |
|
|
118
|
+
| test-json-file.mjs:258 | 逐文件读 `lib/*.js` | 不适用 | 测试代码 |
|
|
119
|
+
|
|
120
|
+
只有 1251(以及可选的 903)值得改成 `Promise.all`,其余都是装载正确性依赖的串行化。
|
|
121
|
+
建议把其余 13 条在 Sonar 标为 Accepted 并附上「串行化是 reconcile 语义」的理由,
|
|
122
|
+
避免后续有人「按 Sonar 优化」时破坏 unmount → mount 顺序。
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## 3. 分支自身的发现
|
|
127
|
+
|
|
128
|
+
### B1(低)`DEFAULT_MAX_INSTRUCTION_BYTES` 是死导出
|
|
129
|
+
|
|
130
|
+
[model.ts:193](../../src/model.ts#L193) 导出了 `32768`,注释说「用于文档与对照」,但
|
|
131
|
+
`src/` 与 `test/` 里没有任何引用。它和上游默认一旦漂移,也没有东西会报错。
|
|
132
|
+
建议删掉,或者在测试里用它断言 `patchRowToView` 缺省时不出现该键,让它有实际用途。
|
|
133
|
+
|
|
134
|
+
### B2(低)`agent/session-start` 删除后缺少回归测试
|
|
135
|
+
|
|
136
|
+
删除本身正确(dsh 0.2 已移除该事件,`agent/created` 带 `source`)。但
|
|
137
|
+
[test-registry.mjs](../../test/test-registry.mjs) 里没有针对 `agent/created` 的用例,
|
|
138
|
+
`resume` / `compact` / `clear` 这些原先靠 session-start 兜底的边沿只有 headless 实机验证。
|
|
139
|
+
建议补一条:fake ctx 触发 `agent/created`(带 `source: "resume"`、已有 `session.header.cwd`),
|
|
140
|
+
断言项目被挂载且 deny 被应用。
|
|
141
|
+
|
|
142
|
+
### B3(低)`maxInstructionBytes` 变化会拆连接,无测试
|
|
143
|
+
|
|
144
|
+
`canonicalConfig` 只剥 `tools`,所以改 `maxInstructionBytes` 会触发 unmount → mount。
|
|
145
|
+
这是正确行为(官方只在连接时读取),但值得一条 `planProjectChanges` 单测固化,
|
|
146
|
+
防止以后有人把它当作「非连接字段」加进剥离列表。
|
|
147
|
+
|
|
148
|
+
### B4(低)view 透传不校验
|
|
149
|
+
|
|
150
|
+
[model.ts:684](../../src/model.ts#L684) 的 `patchRowToView` 只判 `typeof === "number"`,
|
|
151
|
+
手写 yml 里的 `0` 或 `1.5` 会原样出现在 `dsh-mcp get` 里,而装载侧
|
|
152
|
+
(`inputFromPatchRow` → zod)会拒绝并记 `config-invalid`。与 `toolCallTimeoutMs`
|
|
153
|
+
等字段现有口径一致,可以接受;如果要改,应该所有数值字段一起改。
|
|
154
|
+
|
|
155
|
+
### 其他确认项(无问题)
|
|
156
|
+
|
|
157
|
+
- **依赖范围**:`^0.2.0-rc.2` 能解析到 `0.2.0` 正式版与后续 `0.2.x`,不会跨到 `0.3`,
|
|
158
|
+
符合「`0.2.0` 线」的表述。锁文件缩减 ~950 行来自 client 0.2 换掉了一批直接依赖
|
|
159
|
+
(适配记录第 2 节已说明)。
|
|
160
|
+
- **无 `peerDependencies` / `engines`**:0.1.5 宿主装上 v0.7.0 只会在 pnpm 那里看到
|
|
161
|
+
client 的 peer 警告,插件本身不拦。现在靠 README / CHANGELOG 告知「0.1.5 用 v0.6.0」。
|
|
162
|
+
可以考虑在 `activate` 时检测宿主版本并给一条明确告警,但不是本次必须。
|
|
163
|
+
- **缺省不落键**:`toOfficialConfig`、`toJsonEntry`、`patchRowToView`、`inputFromPatchRow`
|
|
164
|
+
四处口径一致,测试覆盖了「缺省不存在该键」和「设置后往返保留」。
|
|
165
|
+
- **文档**:中英文 format / env-expansion 同步;stdio 环境清洗的说明对用户有实际价值
|
|
166
|
+
(只放在环境里、没写进 `env` 的凭据在 0.2 下子进程拿不到了),建议在发布说明里
|
|
167
|
+
把这点列为「升级注意」而非普通变化。
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## 4. 修复优先级建议
|
|
172
|
+
|
|
173
|
+
1. **合入前**:S1(三处 `enqueue` 加 `.catch` + 日志)。改动 3 行,关掉 3 条 Sonar BUG。
|
|
174
|
+
2. **合入前可选**:B1 删死导出;PR #13 补标题与描述(目前标题是 "Dev"、描述为空)。
|
|
175
|
+
3. **后续**:B2、B3 补测试;指纹 stat(1251)改 `Promise.all`;S7503 / S9381 小重构。
|
|
176
|
+
4. **Sonar 操作**:其余 13 条 S9382 标 Accepted 并写理由。
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## 5. 本地验证
|
|
181
|
+
|
|
182
|
+
| 检查 | 结果 |
|
|
183
|
+
|---|---|
|
|
184
|
+
| `tsc --noEmit` | 通过 |
|
|
185
|
+
| 编译到临时目录与 `lib/` 逐文件比哈希 | 11 个 `.js` 全部一致,`lib/` 即本分支源码的产物 |
|
|
186
|
+
| 六套测试(node 直接跑) | 全部通过:model 33 / mcp-file 7 / json-file 13 / json-write 6 / registry 46 / cli 21 |
|
|
187
|
+
|
|
188
|
+
未能执行的部分:`pnpm test` 因 pnpm store 锁文件无访问权限失败,`npm run build` 因
|
|
189
|
+
`lib/` 被占用无法清空(疑似宿主 junction 正在加载),所以改为上面的等价验证。
|
|
190
|
+
headless 实机结论引用自适配记录,本次没有复跑。
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# 适配方案:dsh v0.1.6-alpha.2
|
|
2
|
+
|
|
3
|
+
[← 返回 README](../README.zh.md) | 相关:[dsh 0.1.5-rc.2 适配记录](adaptation-dsh-0.1.5-rc2.md)
|
|
4
|
+
|
|
5
|
+
**状态**:设计决策记录。决策已按 dsh **0.2.0-rc.2** 落地,见
|
|
6
|
+
[v0.7.0 适配记录](adaptation-dsh-0.2.0-rc.2.md)。依赖下限是 `^0.2.0-rc.2`
|
|
7
|
+
(`0.2.0` 元组),不是本文当时写的 `^0.1.6-alpha.2`。**对比基线**:上游 `c291e7961a`
|
|
8
|
+
(`dsh-v0.1.5-rc.2` + 139 提交,即 v0.6.0 的适配基线)→ `dsh-v0.1.6-alpha.2`
|
|
9
|
+
(`ddefc45fbc`,区间 1548 提交)。**记录日期**:2026-09-14。
|
|
10
|
+
本文只定决策与理由,不含实施步骤;实施后按仓库惯例另写验证结论。
|
|
11
|
+
|
|
12
|
+
## 0. 结论一览
|
|
13
|
+
|
|
14
|
+
| # | 决策 | 一句话 |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| D1 | 依赖下限抬到 `^0.1.6-alpha.2`,v0.7.0 支持 dsh ≥ 0.1.6-alpha.2 | 0.1.5 用户停留在 v0.6.0(在 0.1.6 宿主上行为等价,无需回补) |
|
|
17
|
+
| D2 | 删除 `agent/session-start` 监听 | 该事件已从上游删除;其职责由 `agent/created`(新增 `source`)完整吸收 |
|
|
18
|
+
| D3 | 镜像新增可选字段 `maxInstructionBytes` | 现状会静默剥离用户配置,违背字段镜像原则 |
|
|
19
|
+
| D4 | 官方行为收紧只做文档与诊断交代,不改装载逻辑 | 均为 client 内部行为,与能力边界声明一致 |
|
|
20
|
+
| D5 | 重述定位:官方机制关系 + 三点留白 | README 能力边界章节改写 |
|
|
21
|
+
| D6 | 发 v0.7.0(minor),不等 0.1.6 正式版 | 范围 `^0.1.6-alpha.2` 已覆盖 0.1.6 元组后续全部版本 |
|
|
22
|
+
| D7 | 验证设计见 §3 各决策验证要点与 §4 | 单宿主矩阵 + resume 边回归 |
|
|
23
|
+
|
|
24
|
+
## 1. 上游变更与本插件的关系
|
|
25
|
+
|
|
26
|
+
### 1.1 `@deepseek-ai/dsh-mcp-client`(区间 15 个提交)
|
|
27
|
+
|
|
28
|
+
- **MCP SDK 整体更换**:`@modelcontextprotocol/sdk ^1.12.0` → `@modelcontextprotocol/client`
|
|
29
|
+
精确 pin `2.0.0`;协议协商升级(自动选 2026-07-28 协议并回落),stdio 协商先起临时
|
|
30
|
+
探测进程再起服务进程;tools/list 分页移交 SDK。
|
|
31
|
+
- **Config 纯新增、零删除**:两个 transport 分支各新增可选 `maxInstructionBytes`
|
|
32
|
+
(int ≥ 1,默认 32768;`packages/mcp/mcp-client/src/index.ts:129,139`)。传输集合仍为
|
|
33
|
+
`stdio | streamable-http`(无 sse);`serverName` 正则、`command/args/env/cwd`、
|
|
34
|
+
`url/headers`、`toolCallTimeoutMs`、`failOnStartupError`、`reconnect.*`(默认
|
|
35
|
+
500/30000/10)与工具名 `mcp__<serverName>__<raw>` 全部未变。
|
|
36
|
+
- **行为收紧**:legacy `toolResult` 归一化删除(非规范 tools/call 结果直接抛错);
|
|
37
|
+
服务器 instructions 超 `maxInstructionBytes` 拒绝该次连接。
|
|
38
|
+
- **行为修复**:无 tools capability 的资源型服务器从"连接失败进重连"变为"空工具集
|
|
39
|
+
保持连接"。
|
|
40
|
+
- **新能力**:新文件 `server-context.ts` 经可选注入(`mcpResources`、`systemPrompt`)
|
|
41
|
+
为每个实例注册 MCP resources provider 与 `mcp:<serverName>` 系统提示节;新导出
|
|
42
|
+
`createMcpToolDefinition`;新增可选 peer `dsh-mcp-resources`、`dsh-system-prompt`;
|
|
43
|
+
`zod` 移入 devDependencies。
|
|
44
|
+
- **不变**:命名导出函数插件形态(`name`/`inject = ['tools']`/`Config`/`apply`);
|
|
45
|
+
serverName 预留按 `scopeOf(ctx)` 作用域(两版相同);重连策略本体(退避、共享
|
|
46
|
+
预算、串行 sync 队列)未变。
|
|
47
|
+
|
|
48
|
+
### 1.2 mcp-resources 与 profile 装配
|
|
49
|
+
|
|
50
|
+
新包 `@deepseek-ai/dsh-mcp-resources` 进入 base bundle(
|
|
51
|
+
`packages/bundle/base/cordis.patch.yml:478`),所有 shipped profile 默认装载:三个共享
|
|
52
|
+
工具 `list_mcp_resources` / `list_mcp_resource_templates` / `read_mcp_resource`。它是
|
|
53
|
+
纯消费端,不做任何配置装载;**第三方编程式挂载的 client 实例自动获得资源工具与
|
|
54
|
+
提示节**(官方范例即 `packages/experimental/browser-use-runtime/src/mcp.ts`)。
|
|
55
|
+
**mcp-client 本身仍是 opt-in**(`apps/cli/tests/profile-mcp.spec.ts` 断言所有 shipped
|
|
56
|
+
profile 中 mcp-client 行数为 0)。装配生态其余变化:官方 `plugin_manager` 工具 +
|
|
57
|
+
"configuration-only bundle" 模式(官方 skill 教模型自助连 MCP);HMR 配置热重载默认
|
|
58
|
+
开启;`dsh plugin` CLI 与 bundle patch 合成机制不变。
|
|
59
|
+
|
|
60
|
+
### 1.3 宿主核心事件面
|
|
61
|
+
|
|
62
|
+
**`agent/session-start` 事件被删除**(旧 `packages/core/agent/src/runtime-types.ts:316`
|
|
63
|
+
→ 新版无此声明),职责并入 `agent/created`:payload 变为
|
|
64
|
+
`{ agent, source: 'startup'|'resume'|'clear'|'compact', signal? }`,经 `ctx.serial`
|
|
65
|
+
串行派发(`packages/core/agent/src/index.ts:533-553`),每个 agent 条目 announce 一次。
|
|
66
|
+
`agent/disposed` 保留不变。cordis `ctx.on` 不校验事件名
|
|
67
|
+
(`vendor/cordis/src/events.ts:288`)——对已删除事件的监听**不抛错、静默永不触发**。
|
|
68
|
+
`tools.restrict` / `tools.schemas` 签名不变;插件入口 `inject = ["tools","agents"]`
|
|
69
|
+
所依赖的服务面不变。
|
|
70
|
+
|
|
71
|
+
### 1.4 与本插件无关(知悉即可)
|
|
72
|
+
|
|
73
|
+
`packages/experimental` 下的 browser-use/computer-use MCP 驱动为实验性浏览器/电脑
|
|
74
|
+
使用 provider,只消费 mcp-client,与项目级装载无关。`docs/user/guide/mcp-memory.md`
|
|
75
|
+
代表的官方推荐配置方式(`$DSH_HOME` 层 cordis.patch.yml / `--patch` overlay)不含
|
|
76
|
+
项目级发现。
|
|
77
|
+
|
|
78
|
+
## 2. 兼容性矩阵
|
|
79
|
+
|
|
80
|
+
| 插件依赖点 | 0.1.6-alpha.2 现状 | 结论 |
|
|
81
|
+
|---|---|---|
|
|
82
|
+
| `ctx.plugin(mcpClient, config)` 挂载路径与 `apply` 签名 | 未变 | 兼容 |
|
|
83
|
+
| `toOfficialConfig()` 生成的全部字段 | Config 纯新增,旧字段全保留 | 兼容 |
|
|
84
|
+
| 传输集合 `stdio \| streamable-http`、别名与报错文案派生 | 未变 | 兼容,注释中的版本号表述需更新 |
|
|
85
|
+
| `MAX_TIMER_DELAY_MS` / reconnect 上限镜像 | 官方 `resolveReconnectPolicy` 未变 | 兼容 |
|
|
86
|
+
| serverName 正则与 `mcp__<名>__<工具>` 前缀 | 未变 | 兼容(effectiveName 策略不动) |
|
|
87
|
+
| `tools.restrict({deny})` 精确名展开 / `tools.schemas()` | 签名未变 | 兼容 |
|
|
88
|
+
| `agent/created` / `agent/disposed` 监听(解构 `{ agent }`) | payload 新增字段,serial 派发 | 兼容(见 D2) |
|
|
89
|
+
| `agent/session-start` 监听(`src/registry.ts:796`) | **事件已删除,监听静默失效** | 需处理(D2) |
|
|
90
|
+
| 依赖范围 `^0.1.5-rc.1` 解析 `0.1.6-alpha.2` | **不可解析**(semver 预发布规则) | 需处理(D1) |
|
|
91
|
+
| 用户在配置行写 `maxInstructionBytes` | 官方支持,但本插件 schema 会剥离 | 需处理(D3) |
|
|
92
|
+
| zod 直接依赖 | 官方移入 devDeps 不影响本插件(自声明 `zod@^4`) | 兼容 |
|
|
93
|
+
| `dsh plugin` CLI 安装入口 / bundle patch 挂载 | 不变 | 兼容 |
|
|
94
|
+
|
|
95
|
+
## 3. 设计决策
|
|
96
|
+
|
|
97
|
+
### D1 支持矩阵与依赖范围:抬下限 `^0.1.6-alpha.2`
|
|
98
|
+
|
|
99
|
+
**问题**。semver 预发布规则下,`^0.1.5-rc.1` 只能解析 `0.1.5` 元组的预发布与正式版,
|
|
100
|
+
解析不到 `0.1.6-alpha.*`(与 0.1.2 → 0.1.5 时"必须改范围"是同一局面,见
|
|
101
|
+
[rc.2 记录 §2](adaptation-dsh-0.1.5-rc2.md))。若不改:0.1.6 宿主 profile 内安装本
|
|
102
|
+
插件会产生嵌套的 0.1.5-rc.2 副本——旧协议协商、旧行为,且**拿不到 mcp-resources
|
|
103
|
+
协同**(server-context 注册只存在于新代码);双副本还意味着两份模块级
|
|
104
|
+
`activeServerNames` WeakMap,serverName 预留彼此不可见。
|
|
105
|
+
|
|
106
|
+
**决策**。依赖范围抬到 `^0.1.6-alpha.2`;v0.7.0 的支持矩阵定为 **dsh ≥
|
|
107
|
+
0.1.6-alpha.2**;0.1.5 宿主用户继续使用 v0.6.0(npm 两个版本并存,安装文档已按需
|
|
108
|
+
指定版本)。
|
|
109
|
+
|
|
110
|
+
**理由**。
|
|
111
|
+
|
|
112
|
+
1. **宿主副本一致性是挂载路径的正确性前提**。本插件经
|
|
113
|
+
`ctx.plugin(mcpClient, config)` 装载(`src/registry.ts:1762`),必须与宿主共享同一
|
|
114
|
+
份 client 实现;嵌套副本的模块级状态(serverName 预留、SDK Client 类)会与宿主
|
|
115
|
+
副本分叉。抬下限后 0.1.6 宿主内 range 直接命中宿主已解析版本,唯一副本。
|
|
116
|
+
2. **与 0.1.2 → 0.1.5 的既定先例一致**(当时直接抬下限 `^0.1.5-rc.1`),仓库已有
|
|
117
|
+
心智模型与文档表述。
|
|
118
|
+
3. **`^0.1.6-alpha.2` 覆盖 0.1.6 元组后续全部版本**(alpha 后续、rc、正式版均可
|
|
119
|
+
解析),0.1.6 周期内不再需要动范围;0.1.7 出现时按惯例重新评估。
|
|
120
|
+
4. **否决 OR 范围**(`^0.1.5-rc.1 || ^0.1.6-alpha.2`):解析器对 OR 范围独立选版时
|
|
121
|
+
取满足范围的最高版本,0.1.5 宿主内反而嵌套 0.1.6 副本,"双向复用"依赖解析器
|
|
122
|
+
实现细节而不可依赖;且双宿主测试矩阵翻倍,收益仅剩"0.1.5 用户装新版插件"——
|
|
123
|
+
该人群升级插件却没有升级宿主的动机本来就弱。
|
|
124
|
+
5. **否决维持现状**:嵌套旧副本在目标宿主(0.1.6)上丢失本版本最重要的协同收益
|
|
125
|
+
(mcp-resources 自动作用于插件挂载的 server),等于适配目的落空。
|
|
126
|
+
|
|
127
|
+
**后果**。v0.7.0 起README 安装示例的版本说明需注明支持矩阵;0.1.5 用户是稳定人群,
|
|
128
|
+
v0.6.0 在 0.1.6 宿主上的行为等价性论证见 D2,不构成回补义务。
|
|
129
|
+
|
|
130
|
+
### D2 事件面:删除 `agent/session-start`,收敛到 `agent/created`
|
|
131
|
+
|
|
132
|
+
**事实**。上游删除了该事件;本插件在 `src/registry.ts:796` 的监听在新宿主上是
|
|
133
|
+
**静默死代码**(cordis 不校验事件名,不抛错、永不触发)。新 `agent/created` 的
|
|
134
|
+
payload 携带 `source: 'startup'|'resume'|'clear'|'compact'`,经 `ctx.serial` 串行
|
|
135
|
+
派发、每个 agent 条目 announce 一次——即原 `agent/session-start`(含恢复/重挂场景
|
|
136
|
+
补扫)的职责被完整吸收。
|
|
137
|
+
|
|
138
|
+
**决策**。删除该监听,不新增替代注册;现有 `agent/created` 监听
|
|
139
|
+
(`src/registry.ts:781`:`resolveProject` + `reconcileAll`,同步 enqueue)保持原样,
|
|
140
|
+
不改为 await。需要区分边类型的将来需求由 `payload.source` 满足,当前不需要。
|
|
141
|
+
|
|
142
|
+
**理由**。
|
|
143
|
+
|
|
144
|
+
1. 并集保留(两个事件都注册)只在"同时支持新旧宿主"时才有意义;D1 已把支持矩阵
|
|
145
|
+
抬到 0.1.6+,新宿主上 `created(source)` 覆盖全部四条边,死监听没有存在理由。
|
|
146
|
+
2. 监听保持同步 enqueue、不阻塞 serial 派发:装载是尽力而为的 reconcile,不应
|
|
147
|
+
阻塞 agent 激活时序——与旧版行为一致,新版 serial 语义下这一点反而更值得守住。
|
|
148
|
+
3. v0.6.0 在 0.1.6 宿主上的行为等价性:session-start 监听变死代码,但其补扫职责
|
|
149
|
+
由 `created(source=resume|…)` 覆盖,`agent/disposed` 与构造时 `liveAgents()` 补扫
|
|
150
|
+
不变——**旧版插件在新宿主上无行为回归**,这支持 D1 的"0.1.5 用户停留 v0.6.0"
|
|
151
|
+
并降低本次适配的紧迫性。
|
|
152
|
+
|
|
153
|
+
**验证要点**。resume / clear / compact 三条边各触发一次 reconcile(对应旧
|
|
154
|
+
session-start 的全部职责面);插件先于 agent 加载、晚于 agent 加载(热更)两个
|
|
155
|
+
时序的补扫不回归。
|
|
156
|
+
|
|
157
|
+
### D3 新配置字段 `maxInstructionBytes` 的镜像透传
|
|
158
|
+
|
|
159
|
+
**事实**。官方 Config 新增可选 `maxInstructionBytes`(int ≥ 1,默认 32768);
|
|
160
|
+
超限的处置是**拒绝该次连接**——这是一个用户可调的失败模式。本插件的
|
|
161
|
+
`mcpServerInputSchema` 无此字段,zod 默认 strip:用户在 `.dsh/mcp.yml` / JSON 方言
|
|
162
|
+
里写了会被**静默剥离**,永远落回官方默认,且用户无从自救。
|
|
163
|
+
|
|
164
|
+
**决策**。按既有的字段镜像原则(与 `MAX_TIMER_DELAY_MS`、`SUPPORTED_MCP_TRANSPORTS`
|
|
165
|
+
同性质,见 AGENTS.md「关键行为约定」)透传三处:
|
|
166
|
+
|
|
167
|
+
1. `mcpServerInputSchema`(`src/model.ts`)加可选 `maxInstructionBytes`
|
|
168
|
+
(`z.number().int().min(1).optional()`)——只镜像官方存在的边界(int ≥ 1),
|
|
169
|
+
不发明官方没有的上界;
|
|
170
|
+
2. `toOfficialConfig()` 有值时写入该键,缺省不写键(让官方默认生效,不复制
|
|
171
|
+
默认值——默认值属于官方,复制会漂移);
|
|
172
|
+
3. JSON 方言白名单 `jsonServerEntrySchema` + `passthroughKeys()`
|
|
173
|
+
(`src/json-file.ts:132-156`)加同名键。
|
|
174
|
+
|
|
175
|
+
**CLI 不加参数**。理由:`dsh-mcp` CLI 面板输入项面向最常用路径,instructions 字节
|
|
176
|
+
调优是高级场景,写配置文件即可;保持 CLI 表面积稳定(与 `reconnect` 子字段不进
|
|
177
|
+
CLI 同一口径)。
|
|
178
|
+
|
|
179
|
+
**文档**。`docs/guide/format*.md` 字段表补一行:语义(含归属头的服务器 instructions
|
|
180
|
+
字节上限)、默认 32768、超限行为(该服务器连接失败,进官方重连;本插件健康巡检
|
|
181
|
+
按既有 0 工具退避逻辑处理,连续失败满 3 次 `give-up`)。
|
|
182
|
+
|
|
183
|
+
### D4 官方行为收紧:只做文档与诊断交代,不改装载逻辑
|
|
184
|
+
|
|
185
|
+
三条收紧均为 client 内部行为,本插件不拦截、不包装(与 README「能力边界:
|
|
186
|
+
传输类型由官方 client 决定」同一分工):
|
|
187
|
+
|
|
188
|
+
1. **legacy `toolResult` 服务器**(旧版容忍、新版每次调用抛 invalid MCP result):
|
|
189
|
+
文档 FAQ 加一条——升级 0.1.6 后某服务器调用开始报错是服务器端返回非规范结果,
|
|
190
|
+
修复方向在服务器侧(返回规范 content 数组);本插件的 `plugin-throw` /
|
|
191
|
+
健康巡检诊断口径不变(调用期错误不经过插件)。
|
|
192
|
+
2. **instructions 超限拒绝连接**:连接失败走官方重连 → 本插件健康巡检(fiber 世代
|
|
193
|
+
0 工具退避)→ remount 循环 → `give-up`,既有链路自然覆盖;D3 落地后用户可通过
|
|
194
|
+
调大 `maxInstructionBytes` 自救,文档与该字段说明合并交代。
|
|
195
|
+
3. **stdio 协商探测进程**:启动期子进程数与日志文案变化(官方日志新增
|
|
196
|
+
"transport closure could not be confirmed…" 等);本插件无进程数断言,仅文档
|
|
197
|
+
提示一句,避免用户误判为插件行为。
|
|
198
|
+
|
|
199
|
+
### D5 定位重述:官方机制的关系与三点留白
|
|
200
|
+
|
|
201
|
+
**官方已覆盖**(v0.7.0 文档需要承认,避免用户误判被取代):全局/每 profile 声明
|
|
202
|
+
(`$DSH_HOME` 层 `cordis.patch.yml`)、配置热重载(官方 HMR 默认开,作用于
|
|
203
|
+
**profile 配置层**)、运行时装载(`plugin_manager` + configuration-only bundle,官方
|
|
204
|
+
skill 教模型自助)、协议/重连/分页/instructions/resources 全部收进官方
|
|
205
|
+
mcp-client + mcp-resources。
|
|
206
|
+
|
|
207
|
+
**本插件的三点留白**(README「能力边界」章节改写方向):
|
|
208
|
+
|
|
209
|
+
1. **项目级配置发现**:`<projectRoot>/.dsh/mcp.yml|json`(含只读遗留 `.mcp.json`)
|
|
210
|
+
——团队可版本化共享的 per-repo 配置;官方配置全部锚在 `$DSH_HOME` profile 层。
|
|
211
|
+
2. **按会话 cwd 隔离工具可见性**:官方有 scope 机制但无 cwd→配置/scope 的自动映射。
|
|
212
|
+
3. **MCP 专用友好格式 + `dsh-mcp` CLI**:官方要求用户写 Cordis patch 语法(insert
|
|
213
|
+
包装、`!!js`),对普通用户门槛高;官方无 MCP 专用 CLI。
|
|
214
|
+
|
|
215
|
+
**热重载叙述边界**:项目文件热重载(本插件 chokidar,监视对象不在官方 HMR 的
|
|
216
|
+
profile 配置面内,机制不冲突)vs profile 配置热重载(官方 HMR)——文档明确两者
|
|
217
|
+
分工,不再笼统说"热重载"。
|
|
218
|
+
|
|
219
|
+
**协同收益**:升级依赖后(D1),本插件挂载的每个 server 自动获得三个资源工具与
|
|
220
|
+
`mcp:<serverName>` 提示节(mcp-resources 已默认在所有 profile)——README 定位章节
|
|
221
|
+
作为"与官方机制互补"的例证写入。本插件继续不碰协议层与 resources 粘合。
|
|
222
|
+
|
|
223
|
+
### D6 版本与发布策略:v0.7.0,不等 0.1.6 正式版
|
|
224
|
+
|
|
225
|
+
**决策**。以 v0.7.0(minor)发布本次适配;`package.json` 与 `CHANGELOG.md` 同步
|
|
226
|
+
(仓库既定规则)。
|
|
227
|
+
|
|
228
|
+
**理由**。范围抬升(D1)与新字段透传(D3)是行为面变化,不是 bug 修复,minor
|
|
229
|
+
合适;0.6.x 打补丁号会造成"同版本号不同依赖范围"的混乱。alpha dist-tag 已在 npm
|
|
230
|
+
发布,alpha 宿主用户现在就能撞上嵌套副本问题,没有理由压着不发。上游 API 是
|
|
231
|
+
pre-stable(官方 AGENTS 明示),alpha → rc 之间 Config/事件面可能再变:本方案的
|
|
232
|
+
决策框架(§3)按增量核对即可复用,`^0.1.6-alpha.2` 范围已覆盖 0.1.6 元组后续
|
|
233
|
+
版本,官方再动 Config 字段时按 D3 的镜像流程处理,不需要等正式版再一次性做大改。
|
|
234
|
+
|
|
235
|
+
### D7 验证设计(不含步骤)
|
|
236
|
+
|
|
237
|
+
- **单宿主矩阵**:dsh 0.1.6-alpha.2(支持矩阵抬升后不再跑 0.1.5 矩阵);`test/`
|
|
238
|
+
六套全量 + 手工场景。
|
|
239
|
+
- **resume/clear/compact 边回归**:D2 的职责迁移验证;含插件先于/晚于 agent 加载
|
|
240
|
+
两个时序。
|
|
241
|
+
- **`maxInstructionBytes` 端到端**:yml 行与 JSON 行各写一个显式值 → 装载 → 断言
|
|
242
|
+
client 收到该键;缺省行断言键不出现(官方默认生效)。
|
|
243
|
+
- **副本唯一性**:0.1.6 宿主 profile 内安装 v0.7.0 后,
|
|
244
|
+
`pnpm why @deepseek-ai/dsh-mcp-client` 应只有宿主一份。
|
|
245
|
+
- **mcp-resources 协同烟测**:挂载一个带 instructions 的 fixture server,确认
|
|
246
|
+
`mcp:<serverName>` 提示节与资源工具出现(验证 D1 副本一致性带来的协同生效)。
|
|
247
|
+
|
|
248
|
+
## 4. 风险与开放问题
|
|
249
|
+
|
|
250
|
+
1. **pre-stable API**:本方案按 0.1.6-alpha.2 快照决策;0.1.6-rc / 正式发布时官方
|
|
251
|
+
Config、事件面、peer 集合仍可能变动,按 §3 框架增量核对(重点:Config 字段、
|
|
252
|
+
`agent/created` payload、mcp-client peer 清单)。
|
|
253
|
+
2. **战略风险**:官方方向是"一切皆 Cordis 组合 + plugin_manager 自服务"。若上游
|
|
254
|
+
未来补项目级配置发现(本插件留白一),核心价值被替代;D5 的三点留白是当前的
|
|
255
|
+
差异化底线,README 定位随官方演进持续校准。
|
|
256
|
+
3. **嵌套副本的实际解析行为未实测**(0.1.5 宿主安装 v0.7.0 的边缘场景):已通过
|
|
257
|
+
支持矩阵声明规避(该组合不在支持范围),README 版本说明写清即可,不做兼容
|
|
258
|
+
测试投入。
|
|
259
|
+
4. **官方新增可选 peer 的传递影响**:mcp-client 新增 `dsh-mcp-resources` /
|
|
260
|
+
`dsh-system-prompt` 可选 peer,宿主 profile 内两者默认在装载(前者进 base
|
|
261
|
+
bundle),无需本插件干预;若用户在极简 profile(sdk-minimal 之外的自定义组合)
|
|
262
|
+
中缺装,server-context 静默不注册属官方设计,不构成本插件的问题面。
|