dsh-project-mcp-manager 0.7.1 → 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 +21 -2
- package/docs/README.zh.md +18 -2
- package/docs/design/proposal-runtime-robustness-and-json-interop.md +3 -1
- package/docs/guide/service.md +95 -0
- package/docs/guide/service.zh.md +88 -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-write.d.ts +32 -0
- package/lib/mcp-file.d.ts +46 -0
- package/lib/model.d.ts +277 -0
- package/lib/project-root.d.ts +4 -0
- package/lib/registry.d.ts +439 -0
- package/lib/registry.js +17 -0
- package/lib/service.d.ts +41 -0
- package/lib/service.js +5 -0
- package/lib/status.d.ts +20 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -43,6 +43,9 @@ Feature documentation lives in `docs/`, English and Chinese side by side:
|
|
|
43
43
|
- [`${VAR}` expansion](docs/guide/env-expansion.md) — mount-time interpolation and
|
|
44
44
|
its diagnostics.
|
|
45
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.
|
|
46
49
|
|
|
47
50
|
Design and release records (Chinese): [dsh 0.2.0-rc.2 adaptation](docs/design/adaptation-dsh-0.2.0-rc.2.md) ·
|
|
48
51
|
[dsh 0.1.6-alpha.2 adaptation plan](docs/design/adaptation-dsh-0.1.6-alpha.2.md) ·
|
|
@@ -51,6 +54,7 @@ Design and release records (Chinese): [dsh 0.2.0-rc.2 adaptation](docs/design/ad
|
|
|
51
54
|
[dsh 0.1.2-rc.1 adaptation](docs/design/adaptation-dsh-0.1.2-rc1.md) ·
|
|
52
55
|
[JSON config layer proposal](docs/design/proposal-json-mcp-config.md) ·
|
|
53
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) ·
|
|
54
58
|
[v0.7.1 release notes](docs/releases/v0.7.1.md) ·
|
|
55
59
|
[v0.7.0 release notes](docs/releases/v0.7.0.md) ·
|
|
56
60
|
[v0.6.0 release notes](docs/releases/v0.6.0.md) ·
|
|
@@ -90,7 +94,7 @@ dsh plugin --profile web add dsh-project-mcp-manager@latest
|
|
|
90
94
|
|
|
91
95
|
# Install a specific version (check available versions with
|
|
92
96
|
# npm view dsh-project-mcp-manager versions)
|
|
93
|
-
dsh plugin --profile web add dsh-project-mcp-manager@0.7.
|
|
97
|
+
dsh plugin --profile web add dsh-project-mcp-manager@0.7.2
|
|
94
98
|
```
|
|
95
99
|
|
|
96
100
|
**Option 2: install directly with pnpm** (equivalent to option 1):
|
|
@@ -117,7 +121,7 @@ pnpm add link:<path-to-your-dsh-mcp-project-source> # e.g. D:\dev\dsh-mcp-proj
|
|
|
117
121
|
> trigger the bundle reconcile.
|
|
118
122
|
|
|
119
123
|
**Upgrading / pinning versions**: re-run the `add` command from option 1 with
|
|
120
|
-
the desired version suffix — `@latest` upgrades to the newest release, `@0.7.
|
|
124
|
+
the desired version suffix — `@latest` upgrades to the newest release, `@0.7.2`
|
|
121
125
|
pins to a specific version. v0.7.x needs dsh 0.2.0-rc.2 (the `0.2.0` line).
|
|
122
126
|
dsh 0.1.5 keeps working with plugin `@0.6.0`.
|
|
123
127
|
|
|
@@ -179,6 +183,21 @@ pnpm test # node test/test-model.mjs / test-mcp-file / test-json-file /
|
|
|
179
183
|
falls back to the owner project (subagents), then to the project containing
|
|
180
184
|
the dsh process cwd. Released when the session is destroyed.
|
|
181
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
|
+
|
|
182
201
|
## Security boundary
|
|
183
202
|
|
|
184
203
|
`stdio` lines in `.dsh/mcp.yml`, `.dsh/mcp.json` and `.mcp.json` spawn their
|
package/docs/README.zh.md
CHANGED
|
@@ -36,6 +36,8 @@ client 决定。** v0.7.x 面向 dsh `0.2.0` 线(从 0.2.0-rc.2 起)。仍
|
|
|
36
36
|
全局装载 vs 项目装载,以及只读的遗留 Claude Code 层。
|
|
37
37
|
- [`${VAR}` 展开](guide/env-expansion.zh.md)——装载时插值与对应诊断。
|
|
38
38
|
- [CLI `dsh-mcp`](guide/cli.zh.md)——作用域、写入格式与独占契约。
|
|
39
|
+
- [查询面](guide/service.zh.md)——`ctx.projectMcp`、`projectMcp/updated` 事件、
|
|
40
|
+
包入口导出的视图类型,以及对配套 UI 的语义化版本承诺。
|
|
39
41
|
|
|
40
42
|
设计与发布记录(中文):[dsh 0.2.0-rc.2 适配记录](design/adaptation-dsh-0.2.0-rc.2.md) ·
|
|
41
43
|
[dsh 0.1.6-alpha.2 适配方案](design/adaptation-dsh-0.1.6-alpha.2.md) ·
|
|
@@ -44,6 +46,7 @@ client 决定。** v0.7.x 面向 dsh `0.2.0` 线(从 0.2.0-rc.2 起)。仍
|
|
|
44
46
|
[dsh 0.1.2-rc.1 适配记录](design/adaptation-dsh-0.1.2-rc1.md) ·
|
|
45
47
|
[JSON 配置层设计提案](design/proposal-json-mcp-config.md) ·
|
|
46
48
|
[运行时稳健性与 JSON 互通提案](design/proposal-runtime-robustness-and-json-interop.md) ·
|
|
49
|
+
[v0.7.2 发布说明](releases/v0.7.2.md) ·
|
|
47
50
|
[v0.7.1 发布说明](releases/v0.7.1.md) ·
|
|
48
51
|
[v0.7.0 发布说明](releases/v0.7.0.md) ·
|
|
49
52
|
[v0.6.0 发布说明](releases/v0.6.0.md) ·
|
|
@@ -79,7 +82,7 @@ npm install -g deepseek-ai/dsh # 或从 GitHub 源码安装
|
|
|
79
82
|
dsh plugin --profile web add dsh-project-mcp-manager@latest
|
|
80
83
|
|
|
81
84
|
# 安装指定版本(版本号可先 npm view dsh-project-mcp-manager versions 查看)
|
|
82
|
-
dsh plugin --profile web add dsh-project-mcp-manager@0.7.
|
|
85
|
+
dsh plugin --profile web add dsh-project-mcp-manager@0.7.2
|
|
83
86
|
```
|
|
84
87
|
|
|
85
88
|
**方式二:直接 pnpm 安装**(与方式一等价):
|
|
@@ -104,7 +107,7 @@ pnpm add link:<你的 dsh-mcp-project 源码目录> # 例如 D:\dev\dsh-mcp-pr
|
|
|
104
107
|
> `dsh-project-mcp-manager` 行)触发 bundle reconcile。
|
|
105
108
|
|
|
106
109
|
**升级/锁定版本**:重跑方式一的 `add` 命令并带上目标版本后缀——`@latest`
|
|
107
|
-
升级到最新,`@0.7.
|
|
110
|
+
升级到最新,`@0.7.2` 锁定到指定版本。v0.7.x 需要 dsh 0.2.0-rc.2(`0.2.0` 线)。
|
|
108
111
|
dsh 0.1.5 继续用插件 `@0.6.0`。
|
|
109
112
|
|
|
110
113
|
## 构建与测试
|
|
@@ -148,6 +151,19 @@ pnpm test # node 直跑 test/ 下六个 .mjs(model / mcp-file / json-
|
|
|
148
151
|
自身行压制过的全局服务器;会话无 cwd 时回退 owner 项目(子代理),再回退 dsh
|
|
149
152
|
进程 cwd 所在项目。会话销毁时释放。
|
|
150
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
|
+
|
|
151
167
|
## 安全边界
|
|
152
168
|
|
|
153
169
|
`.dsh/mcp.yml`、`.dsh/mcp.json` 与 `.mcp.json` 中的 `stdio` 行会在 dsh
|
|
@@ -238,6 +238,8 @@
|
|
|
238
238
|
**提案**:以官方 storageDomain/service 模式 `ctx.provide("projectMcp", { snapshot, serverView, globalState, reload })`,并补类型声明合并。插件现有导出面(`inject = ["tools","agents"]`、`globalNames()`、`activeProfile()`)保持不变。
|
|
239
239
|
|
|
240
240
|
> **落地口径(v0.6.0)**:`snapshot` / `serverView` / `globalState` 进 enqueue 与对账互斥,按上一轮 `lastScanFiles` / `userLayer` 内存拼装,不读盘、不跑 `reconcileAll`;`reload` 才对账一次。
|
|
241
|
+
>
|
|
242
|
+
> **后续口径**:配套 UI 独立成包后即为稳定消费方。方法、`projectMcp/updated`(对账成功结束、无载荷)与包入口导出的视图类型按语义化版本承诺;UI 包以精确版本 peer-depend 本包。浏览器 SSE 仍由 UI 自建。见 [查询面](../guide/service.zh.md)。上面「不承诺稳定 API」只保留为 v0.6.0 当时的裁决。
|
|
241
243
|
|
|
242
244
|
**风险**:服务名与稳定性承诺需评审;`reload` 的语义限定为"触发一次 reconcileAll"。
|
|
243
245
|
|
|
@@ -375,6 +377,6 @@ C3 本轮跳过。
|
|
|
375
377
|
2. **A4 键名与语法**:`tools.allow`/`tools.deny`,同时读取 `includeTools`/`excludeTools`;**完整 glob**(`*`、`**`、`?`、`[…]`)。
|
|
376
378
|
3. **A5 作用域**:允许 `--scope project|user|profile`;缺省 **project**(与 `add` 一致)。
|
|
377
379
|
4. **B1 卸载策略**:无会话且非进程 cwd 后 **5 分钟宽限**再卸载。
|
|
378
|
-
5. **B3 服务名与稳定性**:服务名 `projectMcp
|
|
380
|
+
5. **B3 服务名与稳定性**:服务名 `projectMcp`。v0.6.0 落地时不承诺稳定 API;配套 UI 独立成包后改为对它按语义化版本承诺,见 [查询面](../guide/service.zh.md)。
|
|
379
381
|
6. **C1 opt-in**:**只报错**,无 `sseAsStreamableHttp`,无环境开关。
|
|
380
382
|
7. **C3 默认值与层序**:**本轮不做**(不读 `.vscode/mcp.json`)。
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Query surface (`projectMcp`)
|
|
2
|
+
|
|
3
|
+
English | [中文](service.zh.md)
|
|
4
|
+
|
|
5
|
+
[← README](../../README.md) | Related: [configuration sources and layers](layers.md) · [CLI `dsh-mcp`](cli.md)
|
|
6
|
+
|
|
7
|
+
Other plugins and the companion UI read mount state through the cordis service
|
|
8
|
+
`ctx.projectMcp`. This package stays in-process: it emits one event when a
|
|
9
|
+
reconcile finishes. The browser still uses the SSE channel the companion UI
|
|
10
|
+
builds itself.
|
|
11
|
+
|
|
12
|
+
## Methods
|
|
13
|
+
|
|
14
|
+
| Method | Behavior |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `snapshot()` | In-memory partitions from the previous reconcile (project files and the user layer). Joins the reconcile queue, does not read disk, and does not start a reconcile. |
|
|
17
|
+
| `serverView(projectRoot, rawName)` | One row's in-memory view. Same queue rules as `snapshot()`. |
|
|
18
|
+
| `globalState(rawName)` | Live global-layer state for that raw name, or `undefined` for a project row. |
|
|
19
|
+
| `reload()` | One full reconcile (`reconcileNow`). |
|
|
20
|
+
|
|
21
|
+
`snapshot()` / `serverView()` / `globalState()` do not emit.
|
|
22
|
+
|
|
23
|
+
## Event
|
|
24
|
+
|
|
25
|
+
After every **successful** `reconcileAll` — including a fingerprint hit that
|
|
26
|
+
still runs the health check, session deny sweep, tool budget, and summary —
|
|
27
|
+
the registry emits:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
ctx.on("projectMcp/updated", async () => {
|
|
31
|
+
const snapshot = await ctx.projectMcp.snapshot();
|
|
32
|
+
});
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The event name is `PROJECT_MCP_UPDATED_EVENT` (`"projectMcp/updated"`). There
|
|
36
|
+
is no payload and no diff. Dispatch is synchronous and does not await a
|
|
37
|
+
listener's promise. The listener reads `snapshot()` or `serverView()` and
|
|
38
|
+
compares with what it last pushed. An early return (`disposed`) or a throw
|
|
39
|
+
inside reconcile does not emit. A listener that throws is logged
|
|
40
|
+
(`项目 MCP 变更事件投递失败:…`) and does not fail the reconcile.
|
|
41
|
+
|
|
42
|
+
## Types
|
|
43
|
+
|
|
44
|
+
Named view types are exported from the package entry. The `exports` map does
|
|
45
|
+
not allow a deep import of `lib/registry.js`.
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import {
|
|
49
|
+
PROJECT_MCP_SERVICE,
|
|
50
|
+
PROJECT_MCP_UPDATED_EVENT,
|
|
51
|
+
type FiberPhaseView,
|
|
52
|
+
type McpRowSource,
|
|
53
|
+
type McpScopeInfo,
|
|
54
|
+
type McpServerRuntimeView,
|
|
55
|
+
type McpServerView,
|
|
56
|
+
type McpTransport,
|
|
57
|
+
type PatchRow,
|
|
58
|
+
type ProjectFileState,
|
|
59
|
+
type ProjectMcpService,
|
|
60
|
+
type ProjectServerPhase,
|
|
61
|
+
type ProjectServerState,
|
|
62
|
+
type ReconnectConfig,
|
|
63
|
+
type ToolFilter,
|
|
64
|
+
} from "dsh-project-mcp-manager";
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`ProjectFileState` is what `snapshot()` returns. Each row is an
|
|
68
|
+
`McpServerRuntimeView` (`McpServerView` plus `source`, `fiberPhase`,
|
|
69
|
+
`skipReason`, and `toolCount`). `globalState()` returns `ProjectServerState`.
|
|
70
|
+
|
|
71
|
+
## Semver for the companion UI
|
|
72
|
+
|
|
73
|
+
`projectMcp`'s methods, the `projectMcp/updated` event, and the view types
|
|
74
|
+
exported above follow semantic versioning **for the companion UI**:
|
|
75
|
+
|
|
76
|
+
| Bump | What it means for this surface |
|
|
77
|
+
|---|---|
|
|
78
|
+
| patch | Fixes that keep the methods, the event, and the view shape. |
|
|
79
|
+
| minor | Additive fields, methods, or events. |
|
|
80
|
+
| major | Removals, renames, or a change in meaning. |
|
|
81
|
+
|
|
82
|
+
The companion UI lists this package as a peer dependency pinned to the **same
|
|
83
|
+
exact version** (no `^` or `~`). When the surface and the UI move, they move
|
|
84
|
+
together:
|
|
85
|
+
|
|
86
|
+
```json
|
|
87
|
+
{
|
|
88
|
+
"peerDependencies": {
|
|
89
|
+
"dsh-project-mcp-manager": "<exact version of this package>"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Replace the placeholder with the version in this package's `package.json` at
|
|
95
|
+
the release the UI is built against.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# 查询面(`projectMcp`)
|
|
2
|
+
|
|
3
|
+
[English](service.md) | 中文
|
|
4
|
+
|
|
5
|
+
[← 返回 README](../README.zh.md) | 相关:[配置来源与分层](layers.zh.md) · [CLI `dsh-mcp`](cli.zh.md)
|
|
6
|
+
|
|
7
|
+
其它插件和配套 UI 经 cordis 服务 `ctx.projectMcp` 读装载状态。本包只在进程内
|
|
8
|
+
发事件:对账成功结束时通知一次。浏览器仍走配套 UI 自己建的 SSE,本包不打开那条通道。
|
|
9
|
+
|
|
10
|
+
## 方法
|
|
11
|
+
|
|
12
|
+
| 方法 | 行为 |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `snapshot()` | 上一轮对账的内存分区(项目文件与用户层)。进对账队列,不读盘,不发起对账。 |
|
|
15
|
+
| `serverView(projectRoot, rawName)` | 一行的内存 view。排队规则与 `snapshot()` 相同。 |
|
|
16
|
+
| `globalState(rawName)` | 该原名的全局层运行态;项目行返回 `undefined`。 |
|
|
17
|
+
| `reload()` | 一次全量对账(`reconcileNow`)。 |
|
|
18
|
+
|
|
19
|
+
`snapshot()` / `serverView()` / `globalState()` 不发事件。
|
|
20
|
+
|
|
21
|
+
## 事件
|
|
22
|
+
|
|
23
|
+
每次 **成功** 的 `reconcileAll` 结束都会 emit——指纹未变、因而跳过重读、但仍跑完
|
|
24
|
+
健康巡检、会话 deny、工具预算和摘要的那一轮也算。注册表调用:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
ctx.on("projectMcp/updated", async () => {
|
|
28
|
+
const snapshot = await ctx.projectMcp.snapshot();
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
事件名是 `PROJECT_MCP_UPDATED_EVENT`(`"projectMcp/updated"`)。无载荷,也不带
|
|
33
|
+
diff。派发是同步的,不会等待监听方返回的 Promise。监听方读 `snapshot()` 或
|
|
34
|
+
`serverView()`,和自己上次推出去的结果比较。对账中途因 `disposed` 返回,或对账
|
|
35
|
+
内部抛错,都不发。监听方抛错会记一条 `项目 MCP 变更事件投递失败:…`,对账本身
|
|
36
|
+
仍算成功。
|
|
37
|
+
|
|
38
|
+
## 类型
|
|
39
|
+
|
|
40
|
+
具名视图类型从包入口导出。`exports` 不开放 `lib/registry.js` 深导入。
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import {
|
|
44
|
+
PROJECT_MCP_SERVICE,
|
|
45
|
+
PROJECT_MCP_UPDATED_EVENT,
|
|
46
|
+
type FiberPhaseView,
|
|
47
|
+
type McpRowSource,
|
|
48
|
+
type McpScopeInfo,
|
|
49
|
+
type McpServerRuntimeView,
|
|
50
|
+
type McpServerView,
|
|
51
|
+
type McpTransport,
|
|
52
|
+
type PatchRow,
|
|
53
|
+
type ProjectFileState,
|
|
54
|
+
type ProjectMcpService,
|
|
55
|
+
type ProjectServerPhase,
|
|
56
|
+
type ProjectServerState,
|
|
57
|
+
type ReconnectConfig,
|
|
58
|
+
type ToolFilter,
|
|
59
|
+
} from "dsh-project-mcp-manager";
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`snapshot()` 的元素类型是 `ProjectFileState`。每一行是 `McpServerRuntimeView`
|
|
63
|
+
(`McpServerView` 再加 `source`、`fiberPhase`、`skipReason`、`toolCount`)。
|
|
64
|
+
`globalState()` 返回 `ProjectServerState`。
|
|
65
|
+
|
|
66
|
+
## 对配套 UI 的语义化版本
|
|
67
|
+
|
|
68
|
+
`projectMcp` 的方法、`projectMcp/updated`,以及上面导出的视图类型,**对配套 UI**
|
|
69
|
+
按语义化版本承诺:
|
|
70
|
+
|
|
71
|
+
| 版本位 | 对这个面意味着 |
|
|
72
|
+
|---|---|
|
|
73
|
+
| patch | 修复,方法、事件和视图形状不变。 |
|
|
74
|
+
| minor | 只增加字段、方法或事件。 |
|
|
75
|
+
| major | 删除、改名,或改变含义。 |
|
|
76
|
+
|
|
77
|
+
配套 UI 把本包写成 peer dependency,并锁定到**同一精确版本**(不要写 `^` 或 `~`)。
|
|
78
|
+
查询面和 UI 一起动时,两边版本一起动:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"peerDependencies": {
|
|
83
|
+
"dsh-project-mcp-manager": "<本包的精确版本>"
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
把占位符换成 UI 所配套的那一版里、本包 `package.json` 的 `version`。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# 发布说明 v0.7.2(查询面推送)
|
|
2
|
+
|
|
3
|
+
[← 返回 README](../README.zh.md) | 相关:[查询面](../guide/service.zh.md) ·
|
|
4
|
+
[v0.7.1 发布说明](v0.7.1.md)
|
|
5
|
+
|
|
6
|
+
**发布日期**:2026-10-02 | **区间**:`v0.7.1 → v0.7.2`
|
|
7
|
+
**宿主**:dsh `0.2.0` 线(从 `0.2.0-rc.2` 起),与 v0.7.1 相同。装载语义不变。
|
|
8
|
+
|
|
9
|
+
v0.7.2 让配套 UI 不用再定时轮询 `snapshot()`。对账成功结束时发一条进程内事件,
|
|
10
|
+
视图类型从包入口具名导出。浏览器 SSE 仍由 UI 包自建。
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 亮点速览
|
|
15
|
+
|
|
16
|
+
| 主题 | 一句话 |
|
|
17
|
+
|---|---|
|
|
18
|
+
| 变更事件 | 对账成功结束 `ctx.emit("projectMcp/updated")`,无载荷;监听方再读 `snapshot()` |
|
|
19
|
+
| 具名类型 | 包入口导出 `ProjectFileState`、`McpServerRuntimeView`、`McpServerView`、`McpRowSource` 等,并开始生成 `.d.ts` |
|
|
20
|
+
| 稳定性 | 方法、事件与这些视图类型对配套 UI 按语义化版本承诺;UI 包以同一精确版本 peer-depend |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 变更明细
|
|
25
|
+
|
|
26
|
+
- **变更事件**:每次成功的 `reconcileAll` 结束(含指纹未变、跳过重读但仍跑完巡检的那一轮)
|
|
27
|
+
emit `projectMcp/updated`。查询方法本身不发。监听方抛错记一条
|
|
28
|
+
`项目 MCP 变更事件投递失败:…`,对账仍算成功。
|
|
29
|
+
- **类型出口**:`declaration` 打开后 `lib/index.d.ts` 才存在;`package.json` 的 `types`
|
|
30
|
+
指向它。`exports` 仍不开放 `lib/` 深导入。
|
|
31
|
+
- **配套 UI**:查询面从「不承诺稳定」改为对该消费方按语义化版本演进。patch 保持形状,
|
|
32
|
+
minor 只增加,major 才删除或改名。peer 写成精确版本,不要 `^` / `~`。
|
|
33
|
+
|
|
34
|
+
## 验证
|
|
35
|
+
|
|
36
|
+
`pnpm test` 六套全绿(model 33 / mcp-file 7 / json-file 13 / json-write 6 /
|
|
37
|
+
registry 48 / cli 21)。
|
package/lib/cli.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export interface CliIo {
|
|
3
|
+
out(line: string): void;
|
|
4
|
+
err(line: string): void;
|
|
5
|
+
}
|
|
6
|
+
export interface CliDeps {
|
|
7
|
+
/** 用户主目录(测试注入):给出时用户层固定为 `<home>/.dsh`,忽略 `$DSH_HOME`。 */
|
|
8
|
+
home?: string;
|
|
9
|
+
/** 项目根解析(默认向上找 .git,测试注入)。 */
|
|
10
|
+
resolveProjectRoot?: (cwd: string) => Promise<string>;
|
|
11
|
+
/** `import --from -` 的 stdin(测试注入;缺省读 `process.stdin`)。 */
|
|
12
|
+
readStdin?: () => Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
interface ParsedArgs {
|
|
15
|
+
positional: string[];
|
|
16
|
+
/** 未显式给出时为 undefined:list 展示全部层;add/remove/get 缺省按 project。 */
|
|
17
|
+
scope?: "project" | "user" | "profile";
|
|
18
|
+
/** 写入格式:缺省时取 DSH_MCP_CLI_FORMAT,再缺省 yml。 */
|
|
19
|
+
format?: "yml" | "json";
|
|
20
|
+
/** --scope profile 的目标 profile 名。 */
|
|
21
|
+
profile?: string;
|
|
22
|
+
transport: "stdio" | "http";
|
|
23
|
+
env: Record<string, string>;
|
|
24
|
+
headers: Record<string, string>;
|
|
25
|
+
cwd?: string;
|
|
26
|
+
help: boolean;
|
|
27
|
+
/** import 输入:文件路径或 `-`(stdin)。 */
|
|
28
|
+
from?: string;
|
|
29
|
+
dryRun: boolean;
|
|
30
|
+
overwrite: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** CLI 写入格式的默认值开关:`yml`(默认)或 `json`;`--format` 优先。 */
|
|
33
|
+
export declare const CLI_FORMAT_ENV = "DSH_MCP_CLI_FORMAT";
|
|
34
|
+
/**
|
|
35
|
+
* 手搓 argv 解析(零依赖):`--` 之后全按位置参数;未知「选项」视为服务器命令行
|
|
36
|
+
* token 透传(刻意策略:宁可透传也不误伤 spawn 参数)。
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseArgs(argv: string[]): ParsedArgs | {
|
|
39
|
+
error: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function runCli(argv: string[], io: CliIo, deps?: CliDeps): Promise<number>;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** dsh 家目录重定位环境变量。 */
|
|
2
|
+
export declare const DSH_HOME_ENV = "DSH_HOME";
|
|
3
|
+
/** 显式指定 profile 名的环境变量(覆盖自动解析;CLI/无 profile 启动场景用)。 */
|
|
4
|
+
export declare const PROFILE_ENV = "DSH_MCP_PROFILE";
|
|
5
|
+
/** 原生受管块文件名(项目层 `<root>/.dsh/mcp.yml` 与用户层 `<dshHome>/mcp.yml` 同名)。 */
|
|
6
|
+
export declare const MCP_YML_FILE = "mcp.yml";
|
|
7
|
+
/** 项目/用户层配置目录名(项目层为 `<root>/.dsh`)。 */
|
|
8
|
+
export declare const DSH_DIR = ".dsh";
|
|
9
|
+
/** 诊断文件名(项目层写 `<root>/.dsh/`,全局层写 `<dshHome>/`)。 */
|
|
10
|
+
export declare const DIAG_FILE = ".mcp-diag.json";
|
|
11
|
+
/**
|
|
12
|
+
* dsh 家目录:`DSH_HOME` 非空则取其绝对化值,否则 `<home>/.dsh`。
|
|
13
|
+
* 显式传入的 home 只影响缺省分支——注入方(测试/CLI `--home`)想完全接管路径时
|
|
14
|
+
* 应直接给 dshHome。
|
|
15
|
+
*/
|
|
16
|
+
export declare function dshHomeDir(home?: string, env?: NodeJS.ProcessEnv): string;
|
|
17
|
+
/**
|
|
18
|
+
* 注入优先的 dsh 家目录:显式给出的 home(CLI `deps.home`、测试注入)视为完整接管,
|
|
19
|
+
* 直接取 `<home>/.dsh`;未给出时才解析 `DSH_HOME`。注入点若被 env 反超,注入就失去
|
|
20
|
+
* 隔离意义(测试会读到真实用户配置)。
|
|
21
|
+
*/
|
|
22
|
+
export declare function dshHomeFor(home: string | undefined, env?: NodeJS.ProcessEnv): string;
|
|
23
|
+
/** 用户层(全局装载)三个来源文件的路径。 */
|
|
24
|
+
export interface UserLayerPaths {
|
|
25
|
+
mcpYml: string;
|
|
26
|
+
mcpJson: string;
|
|
27
|
+
profilesDir: string;
|
|
28
|
+
}
|
|
29
|
+
/** dsh 家目录 → 用户层三个来源路径。 */
|
|
30
|
+
export declare function userLayerPathsIn(dshHome: string): UserLayerPaths;
|
|
31
|
+
/** profile 层配置文件路径(`<dshHome>/profiles/<name>/mcp.json`)。 */
|
|
32
|
+
export declare function profileMcpJsonFile(profilesDir: string, profile: string): string;
|
|
33
|
+
/** 对方插件全局存储路径(`$DSH_HOME/dsh-mcp.json`);本插件不读取内容,只在存在时诊断。 */
|
|
34
|
+
export declare function foreignUserMcpJsonFile(dshHome: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* 合法 profile 名:字母数字开头,其后允许字母数字、`.`、`_`、`-`。
|
|
37
|
+
* 用于把外部输入(`DSH_MCP_PROFILE`)挡在 profiles 目录内——`..`、
|
|
38
|
+
* `../../somewhere`、绝对路径都会被拒。
|
|
39
|
+
*/
|
|
40
|
+
export declare const PROFILE_NAME_RE: RegExp;
|
|
41
|
+
/** profile 名是否可安全拼进 profiles 目录(显式拒绝 `.` 与 `..`)。 */
|
|
42
|
+
export declare function isValidProfileName(name: string): boolean;
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dsh-project-mcp-manager —— 独立项目级 MCP 自动加载插件(宿主半区,无 UI)。
|
|
3
|
+
*
|
|
4
|
+
* 用法:在项目根创建 <projectRoot>/.dsh/mcp.yml(原生受管块,格式与
|
|
5
|
+
* profile cordis.patch.yml 一致)或 .dsh/mcp.json(JSON 方言),在该项目
|
|
6
|
+
* 开启 dsh 会话时自动装载其中的 MCP 服务器(经 @deepseek-ai/dsh-mcp-client),
|
|
7
|
+
* 文件改动经 watch 热重载。
|
|
8
|
+
*
|
|
9
|
+
* 装载模型见 README 与 docs/guide/layers.md;查询面见 docs/guide/service.md;
|
|
10
|
+
* 运行时行为见 registry.ts 的类注释。
|
|
11
|
+
*/
|
|
12
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
13
|
+
export { bindProjectMcpService, PROJECT_MCP_SERVICE, PROJECT_MCP_UPDATED_EVENT, type ProjectMcpService } from "./service.js";
|
|
14
|
+
export type { FiberPhaseView, McpServerRuntimeView, ProjectFileState, ProjectServerPhase, ProjectServerState } from "./registry.js";
|
|
15
|
+
export type { McpScopeInfo, McpServerView, McpTransport, ReconnectConfig, ToolFilter } from "./model.js";
|
|
16
|
+
export type { PatchRow } from "./mcp-file.js";
|
|
17
|
+
export type { McpRowSource } from "./json-file.js";
|
|
18
|
+
export declare const name = "dsh-project-mcp-manager";
|
|
19
|
+
/** agents 为硬依赖:宿主启动早期插件行先于 agents 服务装载时,等待其就绪后再 apply,
|
|
20
|
+
* 保证构造时的 liveAgents 补扫能看到已恢复/已存在的会话。 */
|
|
21
|
+
export declare const inject: string[];
|
|
22
|
+
/** 显式指定 profile 名的环境变量(实现在 dsh-paths.ts,registry 的校验共用)。 */
|
|
23
|
+
export { PROFILE_ENV } from "./dsh-paths.js";
|
|
24
|
+
export declare function apply(ctx: Context): void;
|
package/lib/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { MCP_PLUGIN_NAME } from "./mcp-file.js";
|
|
|
2
2
|
import { PROFILE_ENV } from "./dsh-paths.js";
|
|
3
3
|
import { ProjectMcpRegistry, profileNameFromConfigPath } from "./registry.js";
|
|
4
4
|
import { bindProjectMcpService, PROJECT_MCP_SERVICE } from "./service.js";
|
|
5
|
-
export { bindProjectMcpService, PROJECT_MCP_SERVICE } from "./service.js";
|
|
5
|
+
export { bindProjectMcpService, PROJECT_MCP_SERVICE, PROJECT_MCP_UPDATED_EVENT } from "./service.js";
|
|
6
6
|
export const name = "dsh-project-mcp-manager";
|
|
7
7
|
/** agents 为硬依赖:宿主启动早期插件行先于 agents 服务装载时,等待其就绪后再 apply,
|
|
8
8
|
* 保证构造时的 liveAgents 补扫能看到已恢复/已存在的会话。 */
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type PatchRow } from "./mcp-file.js";
|
|
3
|
+
import { type McpServerInput } from "./model.js";
|
|
4
|
+
/** DSH 自有 JSON 配置文件名(位于 `<root>/.dsh/`、`$DSH_HOME/`、`$DSH_HOME/profiles/<name>/`)。 */
|
|
5
|
+
export declare const JSON_MCP_FILE = "mcp.json";
|
|
6
|
+
/** 对方插件(`@wingsky-1/dsh-mcp-manager`)的全局存储文件名(位于 `$DSH_HOME/`)。 */
|
|
7
|
+
export declare const FOREIGN_MCP_JSON_FILE = "dsh-mcp.json";
|
|
8
|
+
/** 对方 `{version, servers}` 存储格式的可执行诊断(本插件不读取该方言)。 */
|
|
9
|
+
export declare const FOREIGN_MCP_FORMAT_HINT = "\u8BE5\u6587\u4EF6\u7591\u4F3C @wingsky-1/dsh-mcp-manager \u7684\u5B58\u50A8\u683C\u5F0F\uFF08{version, servers}\uFF09\uFF0C\u672C\u63D2\u4EF6\u4E0D\u8BFB\u53D6\u3002\u5EFA\u8BAE\u6539\u7528 mcpServers \u65B9\u8A00\uFF0C\u6216\u6539\u7528 .dsh/mcp.yml";
|
|
10
|
+
/** 对方文件名里误写了本插件 `mcpServers`:不装载,提示改用 mcp.json。 */
|
|
11
|
+
export declare const FOREIGN_MCP_WRONG_FILE_HINT = "\u8BE5\u6587\u4EF6\u540D\u4E3A dsh-mcp.json\uFF08@wingsky-1/dsh-mcp-manager \u7684\u5168\u5C40\u5B58\u50A8\uFF09\uFF0C\u672C\u63D2\u4EF6\u4E0D\u4ECE\u6B64\u8DEF\u5F84\u88C5\u8F7D\u3002\u8BF7\u628A mcpServers \u5199\u5230 mcp.json";
|
|
12
|
+
/**
|
|
13
|
+
* 检测对方插件的存储格式。本插件方言文件(mcp.json / .mcp.json)里一旦有
|
|
14
|
+
* `mcpServers`(即便同时有 `servers`)就不告警。对方文件名 `dsh-mcp.json`
|
|
15
|
+
* 即使写了 `mcpServers` 也不装载,并提示改用 mcp.json。缺 `mcpServers` 且顶层
|
|
16
|
+
* 是 `servers` 数组,或同时有 `version` 与 `servers`,认定为对方格式。
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectForeignMcpFormat(value: Record<string, unknown>, fileName?: string): string | undefined;
|
|
19
|
+
/** 遗留 Claude Code project 层文件名(位于项目根,与 `.dsh/` 并列,只读)。 */
|
|
20
|
+
export declare const CC_PROJECT_FILE = ".mcp.json";
|
|
21
|
+
/** 置为 "1" 时跳过遗留 `<projectRoot>/.mcp.json` 的读取与监听;DSH 自有 JSON 层不受影响。 */
|
|
22
|
+
export declare const IGNORE_MCP_JSON_ENV = "DSH_MCP_IGNORE_MCP_JSON";
|
|
23
|
+
/** 遗留 CC 项目层是否启用:默认开,`DSH_MCP_IGNORE_MCP_JSON=1` 关。 */
|
|
24
|
+
export declare function mcpJsonLayerEnabled(env?: NodeJS.ProcessEnv): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* 配置行来源。数组顺序即影子优先序(先到先得):
|
|
27
|
+
* `dsh-project` > `dsh-project-json` > `cc-project` > `dsh-profile-user` > `dsh-user-yml` > `dsh-user`。
|
|
28
|
+
* 前三者是项目层(按项目装载、按会话隔离),后三者是用户层(宿主级全局装载)。
|
|
29
|
+
*/
|
|
30
|
+
export type McpRowSource = "dsh-project" | "dsh-project-json" | "cc-project" | "dsh-profile-user" | "dsh-user-yml" | "dsh-user";
|
|
31
|
+
/** 带来源标记的配置行:主管线合并与快照展示用。disabled=true 的行参与占名
|
|
32
|
+
* (遮蔽下层同名)但不进入装载集合。 */
|
|
33
|
+
export interface SourcedRow {
|
|
34
|
+
rawName: string;
|
|
35
|
+
row: PatchRow;
|
|
36
|
+
source: McpRowSource;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface JsonReadResult {
|
|
40
|
+
rows: SourcedRow[];
|
|
41
|
+
/** 单条坏条目(sse/缺字段/坏名字)的报错,逐条收集,不影响其余条目。 */
|
|
42
|
+
entryErrors: string[];
|
|
43
|
+
/** 整文件级错误(不存在=正常空结果;解析失败等)。消息不含文件内容。 */
|
|
44
|
+
fileError?: string;
|
|
45
|
+
/**
|
|
46
|
+
* 文件存在、缺 `mcpServers`、且顶层像 `{version, servers}`(对方插件存储格式)时的
|
|
47
|
+
* 诊断。缺 `mcpServers` 仍是合法空层;此字段只为「配了但不生效」提供可执行说明。
|
|
48
|
+
*/
|
|
49
|
+
formatHint?: string;
|
|
50
|
+
}
|
|
51
|
+
/** stdio 空 cwd 的解析策略:项目层=项目根;用户层=继承宿主工作目录。 */
|
|
52
|
+
export type JsonCwdPolicy = "project" | "host";
|
|
53
|
+
export interface JsonReadOptions {
|
|
54
|
+
source: McpRowSource;
|
|
55
|
+
cwdPolicy: JsonCwdPolicy;
|
|
56
|
+
/** 项目根(cwdPolicy="project" 时空 cwd 的落点;用户层传空串)。 */
|
|
57
|
+
projectRoot: string;
|
|
58
|
+
/** true:缺 `mcpServers` 报文件级错误(遗留 CC 文件语义);false:视为空层。 */
|
|
59
|
+
requireMcpServers?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 单条目宽松 schema:未知字段(timeout/scope 等生态附加键)容忍并忽略。
|
|
63
|
+
* `type` 缺省视为 stdio(有 url/httpUrl 无 command 时按 http 推断)。
|
|
64
|
+
* `transport` 与 `httpUrl` 为原生/Gemini 方言别名,由 jsonEntryToInput 归一。
|
|
65
|
+
*/
|
|
66
|
+
export declare const jsonServerEntrySchema: z.ZodObject<{
|
|
67
|
+
type: z.ZodOptional<z.ZodString>;
|
|
68
|
+
transport: z.ZodOptional<z.ZodString>;
|
|
69
|
+
command: z.ZodOptional<z.ZodString>;
|
|
70
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
71
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
72
|
+
cwd: z.ZodOptional<z.ZodString>;
|
|
73
|
+
url: z.ZodOptional<z.ZodString>;
|
|
74
|
+
httpUrl: z.ZodOptional<z.ZodString>;
|
|
75
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
76
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
78
|
+
toolCallTimeoutMs: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
failOnStartupError: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
maxInstructionBytes: z.ZodOptional<z.ZodNumber>;
|
|
81
|
+
reconnect: z.ZodOptional<z.ZodObject<{
|
|
82
|
+
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
83
|
+
initialDelayMs: z.ZodOptional<z.ZodNumber>;
|
|
84
|
+
maxDelayMs: z.ZodOptional<z.ZodNumber>;
|
|
85
|
+
maxAttempts: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
}, z.core.$strip>>;
|
|
87
|
+
tools: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
allow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
89
|
+
deny: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
90
|
+
}, z.core.$strip>>;
|
|
91
|
+
includeTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
92
|
+
excludeTools: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
93
|
+
}, z.core.$loose>;
|
|
94
|
+
export type JsonServerEntry = z.infer<typeof jsonServerEntrySchema>;
|
|
95
|
+
/** 单条 JSON 条目 → 官方输入。坏条目返回 `{ error }` 由调用方逐条收集。 */
|
|
96
|
+
export declare function jsonEntryToInput(name: string, entry: JsonServerEntry, options: JsonReadOptions): {
|
|
97
|
+
input: McpServerInput;
|
|
98
|
+
} | {
|
|
99
|
+
error: string;
|
|
100
|
+
};
|
|
101
|
+
/** `mcpServers` 值 → SourcedRow 列表;坏条目逐条报错跳过。 */
|
|
102
|
+
export declare function parseJsonServersValue(mcpServers: unknown, options: JsonReadOptions): {
|
|
103
|
+
rows: SourcedRow[];
|
|
104
|
+
entryErrors: string[];
|
|
105
|
+
};
|
|
106
|
+
/** 通用 JSON 方言读取:文件缺失 → 空结果;坏条目逐条报错。 */
|
|
107
|
+
export declare function readJsonRows(path: string, options: JsonReadOptions): Promise<JsonReadResult>;
|
|
108
|
+
/** 读 DSH 自有 JSON 层(缺 `mcpServers` 视为空层)。 */
|
|
109
|
+
export declare function readDshJsonFile(path: string, options: JsonReadOptions): Promise<JsonReadResult>;
|
|
110
|
+
/** 读遗留 `<projectRoot>/.mcp.json`(CC project scope;缺 `mcpServers` 报文件级错误)。 */
|
|
111
|
+
export declare function readMcpJsonFile(path: string, projectRoot: string): Promise<JsonReadResult>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type McpServerInput } from "./model.js";
|
|
2
|
+
/**
|
|
3
|
+
* `mcpServers` 映射。值类型是 unknown 而非对象:文件里可能存在非对象条目
|
|
4
|
+
* (`"legacy": "node x.js"` 这类手写错误),读-改-写必须原样带过,不能顺手删。
|
|
5
|
+
* 写入方(CLI)只新增/删除自己指名的键。
|
|
6
|
+
*/
|
|
7
|
+
export type JsonServers = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* 读 JSON 文档:缺失/空文件 → `{}`;解析失败或顶层非对象 → 抛错(消息不含文件内容)。
|
|
10
|
+
* 调用方据此拒绝写入,避免把无法解析的文件覆盖掉。
|
|
11
|
+
*/
|
|
12
|
+
export declare function readJsonDocument(path: string): Promise<Record<string, unknown>>;
|
|
13
|
+
/**
|
|
14
|
+
* 读现有 `mcpServers` 映射(缺失/null → 空映射;顶层非对象 → 抛错)。
|
|
15
|
+
* 条目一律保留(含非对象的坏条目):CLI 的判重要能看见坏条目占用的名字,
|
|
16
|
+
* `remove <坏条目名>` 也才能把它清掉。装载侧的坏条目过滤在 json-file.ts。
|
|
17
|
+
*/
|
|
18
|
+
export declare function readJsonServers(path: string): Promise<JsonServers>;
|
|
19
|
+
/**
|
|
20
|
+
* 锁内读-改-写 `mcpServers`:mutate 收到锁内的最新映射,返回值(或原地修改)即写回值。
|
|
21
|
+
* 加锁 + 原子写;写前自校验(序列化结果必须可解析回来)。返回写回后的映射。
|
|
22
|
+
*/
|
|
23
|
+
export declare function updateJsonServers(path: string, mutate: (servers: JsonServers) => JsonServers | void): Promise<JsonServers>;
|
|
24
|
+
/** 整体替换 `mcpServers`(保留其余顶层键与键序)。 */
|
|
25
|
+
export declare function writeJsonServers(path: string, servers: JsonServers): Promise<JsonServers>;
|
|
26
|
+
/**
|
|
27
|
+
* 官方输入 → JSON 条目(Cursor/CC 方言 + DSH 透传键)。
|
|
28
|
+
* 缺省值不落盘(`args: []`、空 `env`/`headers`、空或 "." 的 `cwd`、默认
|
|
29
|
+
* `toolCallTimeoutMs`/`failOnStartupError`/`maxInstructionBytes`/`reconnect`),保持文件简洁可读。
|
|
30
|
+
* `${VAR}` 原样保留,装载时才展开——凭据不落盘。
|
|
31
|
+
*/
|
|
32
|
+
export declare function toJsonEntry(input: McpServerInput): Record<string, unknown>;
|