@luchenglong/cli-bridge 0.2.2 → 0.2.3

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/CHANGELOG.md CHANGED
@@ -9,6 +9,39 @@ GitHub Release(`scripts/verify.mjs` 在 CI 与 prepack 双重锁一致)。
9
9
  > - CodeBuddy 线:[docs/history/codebuddy/CHANGELOG.md](docs/history/codebuddy/CHANGELOG.md)(终版 1.6.2)
10
10
  > - MiMo 线:[docs/history/mimo/CHANGELOG.md](docs/history/mimo/CHANGELOG.md)(终版 1.2.9)
11
11
 
12
+ ## [0.2.3] - 2026-10-15
13
+
14
+ ### Added
15
+ - **第四个 provider:OpenCode**(`opencode`)。四形态全量交付:描述符
16
+ `providers/opencode.mjs`、preset `opencode-first`、`dynamic/opencode.host.js`、
17
+ MCP 面 `mcp/providers/opencode.mjs`。工具面 = `opencode_run` /
18
+ `opencode_continue` / `opencode_status` + **opencode_models**(列出本机可用模型)。
19
+ - **opencode_models**:执行 `opencode models` 取模型列表,支持 `freeOnly` /
20
+ `provider` 过滤;**免费模型优先排序**(`-free` 后缀)。CLI 缺失/未登录时明确
21
+ 返回 `ok:false` 与可操作错误,**绝不凭空伪造模型列表**。
22
+ - **设置面板可选「用哪个 opencode」与「默认模型」**:三个字段均为可自定义下拉 ——
23
+ `binPath`(下拉列出实测探测到的候选路径)、`defaultModel`(实时调
24
+ `opencode models` 填充)、`defaultAgent`(build / plan)。
25
+
26
+ ### Changed
27
+ - **exe 解析优先级统一**:env `OPENCODE_BIN`/`OPENCODE_CLI` > 桌面版 V2 已知路径
28
+ (`ai.opencode.desktop/cli/<ver>-<arch>/`,版本按 semver 降序)> PATH 查找
29
+ `opencode-cli`。二进制名是 **`opencode-cli`**(V2 桌面版),不做 `opencode.exe`
30
+ 兜底 —— V1/V2 不能并存安装,兜底会误命中另一个版本。
31
+ - 单一 id 轴(契约 §3.1)落到测试:keystone 四个测试文件原先硬编码三家 id 列表,
32
+ 改为全部从 `PROVIDER_IDS` / `providerMeta()` 派生 —— 以后新增 provider 零改动。
33
+
34
+ ### Fixed
35
+ - **opencode 事件解析的两个真实缺陷**(端到端测试捕获,单元测试当时全绿):
36
+ ① 文本在 `part.text` 而非顶层,原实现取 `parsed.text` 恒为 undefined → 响应体为空;
37
+ ② 正文(`text` 事件)与统计(`step_finish` 事件的 `cost`/`tokens`)在**不同**事件里,
38
+ 且原实现倒序遍历会在读到 `text` 前先命中末尾的 `step_finish` 并返回 → 回填恒空,
39
+ 表现为「成功但正文为空」。改为**正向**扫完全流再决策,命中终态事件时回填末段文本。
40
+ - 更正 opencode CLI 事实(按本机实测 v2.0.29 而非文档推断):**不存在 `result` 事件**
41
+ (终止判据是退出码 0/1/130)、`run` 子命令**无 `--prompt`**(`-p` 是 `--password`)、
42
+ V2 **无 `--variant`**(并入 `--model provider/model#variant`)、V2 **无 `--dir`**
43
+ (cwd 靠 spawn 工作目录)。
44
+
12
45
  ## [0.2.2] - 2026-10-10
13
46
 
14
47
  ### Changed
@@ -22,6 +55,16 @@ GitHub Release(`scripts/verify.mjs` 在 CI 与 prepack 双重锁一致)。
22
55
  ### Fixed
23
56
  - React hook 顺序红线:tab 状态声明置于 `if (!view)` 早期 return 之前(否则 view 加载
24
57
  瞬间 hook 数量变化 → 面板崩溃),`client-ui-surface` 静态锁。
58
+ - **首发 npm 的 scoped 包可见性**:`package.json` 补 `publishConfig.access = "public"`。
59
+ 此前只有 RELEASE-SOP 要求命令行 `npm publish --access public`;走 GUI/插件通道发布时不带该
60
+ 参数,npm 按私有包处理 → `E402 Payment Required`。写入 package.json 后任何发布通道都正确。
61
+
62
+ ### 发布(2026-10-14)
63
+ - **首发 npm**:`@luchenglong/cli-bridge@0.2.2`(统一包首次发布;registry 上 `latest=0.2.2`,
64
+ shasum `362d506e`,58 files / 320.1 kB)。npm 首次创建 scoped 包返回 `PUT 202 Accepted`
65
+ ("may take a few minutes to become available")—— 属正常,勿重复发布。
66
+ - **旧包已 deprecated**(三条均已在 registry 生效,显示迁移提示):`agy-first-bridge`(终版 1.7.1)、
67
+ `codebuddy-first-bridge`(终版 1.6.2)、`mimo-first-bridge`(终版 1.2.9)。
25
68
 
26
69
  ## [0.2.1] - 2026-10-10
27
70
 
package/README.md CHANGED
@@ -137,6 +137,7 @@ npm run check # 三闸门全量
137
137
 
138
138
  ## 文档
139
139
 
140
+ - **[docs/HANDOVER.md](docs/HANDOVER.md) — 交接文档**(接手先读:状态快照 / 代码地图 / 红线 / 生效时机 / 排障手册 / 遗留项)
140
141
  - [docs/INSTALL.md](docs/INSTALL.md) — 安装与接线(含旧包迁移)
141
142
  - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) — 三形态共享内核设计、状态机与红线论证
142
143
  - [docs/MIGRATION.md](docs/MIGRATION.md) — 从三个旧包迁移对照表
@@ -0,0 +1,226 @@
1
+ # HANDOVER — @luchenglong/cli-bridge 交接文档
2
+
3
+ > 面向接手这个仓库/这台机器的下一个人(或下一个 Agent)。
4
+ > 目标:**不读完所有历史也能安全改动、发布、排障**。历史事故与红线集中在 §5 与 §10。
5
+ > 最近一次更新:2026-10-15(0.2.2 首发 npm + 旧包 deprecated + 旧仓归档之后)。
6
+
7
+ ---
8
+
9
+ ## 1. 这是什么
10
+
11
+ `@luchenglong/cli-bridge` 把**本机三个编码 CLI**(agy / CodeBuddy / MiMo)以同一套 provider
12
+ 描述符接入 DSH,并有四种落地形态(preset / 动态宿主 / 家级宿主插件+指示灯 / MCP stdio server)。
13
+ 它由三个旧包(`agy-first-bridge` / `codebuddy-first-bridge` / `mimo-first-bridge`)合并而来,
14
+ 旧包的工具名、预设 id、策略文案**逐字保留**(兼容承诺,见 §5)。
15
+
16
+ ## 2. 当前状态快照
17
+
18
+ | 项 | 值 |
19
+ | --- | --- |
20
+ | 版本 | **0.2.2**(三处版本锁:`package.json` / `mcp/cli-bridge-mcp.mjs` 的 `SERVER_VERSION` / `CHANGELOG.md` 顶部;`verify.mjs` 机器比对) |
21
+ | npm | `@luchenglong/cli-bridge@0.2.2`(`latest`;2026-10-14 首次发布,shasum `362d506e0b85dd7014bb8b3fc1100bf3a6d0d1d5`,58 files / 320.1 kB) |
22
+ | GitHub | `new-256/cli-bridge`,`main` @ `520194c`;tag `v0.1.0` / `v0.2.1` / `v0.2.2` |
23
+ | 旧包 | 三个都已在 npm 标 **deprecated**(提示迁移到统一包):`agy-first-bridge@1.7.1`、`codebuddy-first-bridge@1.6.2`、`mimo-first-bridge@1.2.9` |
24
+ | 旧仓 | `new-256/agy-first-bridge`、`new-256/mimo-first-bridge`:README 顶部已加迁移横幅且 **archived(只读)**;`codebuddy-first-bridge` 在 GitHub 上不存在 |
25
+ | 测试 | **271 pass / 0 fail**(28 个 `*.test.mjs`),四闸门 `npm run check` 全绿 |
26
+ | 本机运行时 | DSH Desktop,宿主 **2026-10-14 22:35 重启后加载 0.2.2**;`dsh-home/profiles/web` 以 `file:` 依赖 + pnpm 快照部署 |
27
+
28
+ **交接时点唯一未完成项**:家级补丁里四条 MCP 行刚被恢复,**需重启 DSH 才生效**(§7.3、§11)。
29
+
30
+ ## 3. 五分钟上手
31
+
32
+ ```powershell
33
+ cd "C:\Users\lcl\Desktop\DSH插件开发\CLI Bridge"
34
+
35
+ npm run check # 四闸门:build --check / verify / node --test / mcp --check
36
+ node mcp/cli-bridge-mcp.mjs --check # MCP 自检(含 scheduling 快照)
37
+ node scripts/build.mjs # 改了模板/providers 后必须重跑,生成物要进同一个 commit
38
+
39
+ # 活体探针(DSH 运行中;$env:DSH_WEB_URL 是当前 GUI 地址,端口每次启动可能变)
40
+ Invoke-WebRequest "$env:DSH_WEB_URL/cli-bridge/status" -UseBasicParsing | Select-Object -Expand Content
41
+ Invoke-WebRequest "$env:DSH_WEB_URL/cli-bridge/settings" -UseBasicParsing | Select-Object -Expand Content
42
+ ```
43
+
44
+ 设置面板:DSH「设置 → CLI Bridge 桥接」→ 横向标签 `总设置 | AGY | CB | MIMO`。
45
+ 「总设置」= 调度(勾选启用 + `↑↓` 优先级),其余 = 各 CLI 偏好与诊断。
46
+
47
+ ## 4. 代码地图(改哪里)
48
+
49
+ | 路径 | 职责 | 谁维护 |
50
+ | --- | --- | --- |
51
+ | `providers/registry.mjs` | **唯一 id 轴** `PROVIDER_IDS`;新 provider 第一站 | keystone(Lead 单作者) |
52
+ | `providers/<id>.mjs` | 描述符:工具/policy/settings meta/mcp/diagnose/回退 | 每 provider 作者 |
53
+ | `core/bridge-kit.mjs` | 共享内核:状态引擎、runner、限流、回退弹窗、MCP payload(**零 import**) | keystone |
54
+ | `core/scheduling.mjs` | 调度单源(无 import → 可整段内联进沙箱) | keystone |
55
+ | `home-plugin/cli-bridge-indicator/lib/index.mjs` | 宿主半:状态机 + HTTP 路由 + 收集器 + 门禁 | keystone |
56
+ | `…/lib/settings.mjs` | 设置读写/掩码/旧文件迁移/`_scheduling` 区 | keystone |
57
+ | `…/lib/preset-declarations.mjs` | 声明制注册三个 preset(恒注册,顺序按优先级) | keystone |
58
+ | `…/lib/client.js` | 浏览器半:pill / 弹窗 / 设置标签页(**红线:load id ≡ 包名**) | keystone |
59
+ | `preset/<dir>/` | preset 形态(`plugin-list.mjs` 是唯一权威源 + 生成物 `*.yml`) | 生成物入库 |
60
+ | `dynamic/<id>.host.{js,template.mjs}` | 动态沙箱宿主(模板 → 生成物) | 生成物入库 |
61
+ | `mcp/cli-bridge-mcp.mjs` + `mcp/providers/<id>.mjs` | 统一 MCP server(一个 server 暴露三家) | keystone |
62
+ | `mcp/{agy,codebuddy,mimo}-mcp-server.mjs` | 旧包兼容入口(等价 `--provider=<id>`) | keystone |
63
+ | `scripts/build.mjs` / `verify.mjs` / `deploy.mjs` | 生成 / 发布红线 / 本地暂存部署 | keystone |
64
+ | `deploy/legacy-mcp/` | **家级 `bin\` 服务器材料的权威副本**(`bin\` 不入 git) | keystone |
65
+ | `tests/keystone/` | 红线行为测试(client 面、状态机、路由、门禁、legacy MCP) | keystone |
66
+ | `tests/{agy,codebuddy,mimo}/`、`tests/core/` | 各 provider 与内核回归 | provider 作者 |
67
+
68
+ ## 5. 不可动的契约(红线)
69
+
70
+ 1. **client 注册 id ≡ 包名**:`lib/client.js` 的 `window.__ModuleLoader__.load({ id: "@luchenglong/cli-bridge" })`
71
+ 逐字不变。不等 → client combo 加载失败 → **整屏插件页崩溃**(agy v1.6.1 / codebuddy v1.1.8 事故)。
72
+ `verify.mjs` + `tests/keystone/client-id.test.mjs` + `client-ui-surface.test.mjs` 三重机器锁。
73
+ 2. **对外语义 verbatim**:工具名 `<id>_run/_continue/_status`、入参 schema、preset id
74
+ (`cordis-agy` / `codebuddy-first` / `cordis-mimo`)、POLICY 文案(如 codebuddy `POLICY_TEXT` 6970B)。
75
+ 要改 = 大版本 + `docs/MIGRATION.md` 补条目。
76
+ 3. **模板占位符各恰一次**:`/*__KIT__*/`、`/*__PROVIDER__*/`、`/*__SCHED__*/`;生成物
77
+ (`dynamic/*.host.js`、`preset/*/agent.cordis.yml`、`preset.yml`)**必须入库**,`build --check` 漂移即红。
78
+ 4. **单一 id 轴**:任何地方需要 id 列表都从 `providers/registry.mjs` 派生(`build.mjs`、
79
+ `preset-declarations`、client 的 `providerMetas()` 都已改为派生)。禁止第二处硬编码三家 id。
80
+ 5. **零运行时依赖**,且**禁止新增 `@deepseek-ai/dsh*` peer 依赖**(`verify.mjs` + 测试双锁)。
81
+ 6. **家级 `bin\` 三个服务器与 `deploy/legacy-mcp/` 副本逐字节一致**(`tests/keystone/legacy-mcp-gate.test.mjs`)。
82
+ 7. **失败要响亮(开发期)**:不写静默降级/兜底;门禁只做「注册/不注册」,不改工具语义。
83
+
84
+ ## 6. 调度(0.2.0+)实现要点
85
+
86
+ 用户目标:**选择启用哪些 CLI(数量)+ 排定调用优先级**,且加第 N 家 CLI 时零改动。
87
+
88
+ - **落盘**:`{DSH_HOME}/cli-bridge-settings.json` 顶层 `_scheduling = { enabled, priority }`
89
+ (下划线前缀 = 非 provider 分区,旧代码整区忽略 → 纯增量兼容)。
90
+ - **语义**:`enabled` 是集合(数组顺序无意义);`priority` 的**数组顺序即优先级**;
91
+ 派生 `order = priority ∩ enabled`。
92
+ - **fail-open**:文件缺失/坏值/无 fs → 全部启用(读不到 ≠ 全关);只有**显式** `enabled: []` 是全关。
93
+ - **钉住优先**:env `CLI_BRIDGE_PROVIDER` / `--provider=<id>`(MCP 薄封装)优先级最高;
94
+ 宿主形态传 `ignorePin`,避免被全局 env 反噬。
95
+ - **四个生效面**:
96
+ 1. `preset/<id>/cli-bridge.mjs` 与 `dynamic/*.host.js` 的 `apply()` 首行门禁(禁用面零注册);
97
+ `preset-declarations` 的注册顺序 = 优先级顺序;
98
+ 2. 统一 MCP `selectedProviders()` 按 `enabled` 过滤、按 `order` 排序(**启动读一次**);
99
+ 3. 家级 `bin\*-mcp-server.mjs` 经 `bin\cli-bridge-scheduling.mjs` 的 `filterTools()` **每请求现读**
100
+ (面板改完立即生效,无需重启子进程);mimo 的 dispatch 层单独加了拒调文本;
101
+ 4. `GET /cli-bridge/status` 与 `/cli-bridge/settings` 每次轮询现读并附 `scheduling` 快照。
102
+ - **客户端**:`providerMetas()` 以视图 `scheduling.all ∪ providers 键` 为权威 id 轴(本地 `PROVIDERS`
103
+ 降级为 fallback,仅补 presetId/展示 label);标签页一排点击切换;`stale` 项目(>10 分钟无活动)
104
+ 不再渲染常亮 pill(弹窗里仍保留历史)。
105
+
106
+ ## 7. 本机运行环境接线现状(机器特定)
107
+
108
+ ### 7.1 安装形态
109
+
110
+ - `dsh-home/profiles/web/package.json`:`"@luchenglong/cli-bridge": "file:C:/Users/lcl/Desktop/DSH插件开发/CLI Bridge"`,
111
+ 并在 `dsh.profile.bundles` 登记 → 包内 `cordis.patch.yml` 作为 bundle 层自动挂载(宿主半 + 浏览器半 + 三 preset)。
112
+ - **改完必须刷新快照**(pnpm 对 `file:` 依赖按**版本**键控缓存):
113
+ ```powershell
114
+ $installed = "$env:APPDATA\DSH Desktop\dsh-home\profiles\web\node_modules\@luchenglong\cli-bridge"
115
+ Remove-Item $installed -Recurse -Force
116
+ Push-Location "$env:APPDATA\DSH Desktop\dsh-home\profiles\web"; pnpm install --prefer-offline; Pop-Location
117
+ # 校验:Get-FileHash 对比仓库与快照同名文件
118
+ ```
119
+
120
+ ### 7.2 生效时机(**最容易踩**)
121
+
122
+ | 改动 | 生效方式 |
123
+ | --- | --- |
124
+ | `lib/client.js`(浏览器半) | **刷新页面(F5)** 即生效,不用重启 |
125
+ | `lib/index.mjs`、`lib/settings.mjs`、`preset-declarations.mjs` | **必须重启 DSH**(宿主启动时加载) |
126
+ | `dsh-home/cordis.patch.yml`(家级补丁/插件行) | **必须重启 DSH** |
127
+ | 家级 `bin\*-mcp-server.mjs` | 子进程重启;但调度门禁是**每请求**读盘,改设置不用重启 |
128
+ | 统一 `mcp/cli-bridge-mcp.mjs` | 子进程重启后读新配置 |
129
+
130
+ ### 7.3 家级补丁(`dsh-home\cordis.patch.yml`)
131
+
132
+ 活跃 8 条:`session-cleaner`、`local-llm-bridge`、`bot-gateway`、`mobile-companion`,
133
+ 以及 **四条 MCP 行**:`mcp-agy-global` / `mcp-codebuddy-global` / `mcp-playwright-global` / `mcp-mimo-global`
134
+ (2026-10-14 从注释状态恢复;备份 `cordis.patch.yml.bak-before-mcp-restore-20261014-234959`)。
135
+
136
+ ⚠️ 该文件里 agy/codebuddy/playwright **各另有一份注释留档副本**(历史)。启用时**只能启用一份**,
137
+ 否则同 id 重复 → loader 致命错误。改完必须用规范 YAML 解析器验证:
138
+
139
+ ```powershell
140
+ node -e "const y=require('$env:APPDATA/DSH Desktop/backend/dsh/node_modules/yaml');const d=y.parse(require('fs').readFileSync('$env:APPDATA/DSH Desktop/dsh-home/cordis.patch.yml','utf8'));const ids=[];for(const e of d)for(const k of Object.keys(e))for(const i of e[k])ids.push(i.id);console.log(d.length, ids.join(','), 'dup:', ids.filter((x,n)=>ids.indexOf(x)!==n))"
141
+ ```
142
+
143
+ ### 7.4 家级 MCP 材料
144
+
145
+ `dsh-home\bin\agy-mcp-server.mjs`、`bin\codebuddy-mcp-server.mjs`、`bin\cli-bridge-scheduling.mjs`(门禁 helper)、
146
+ `bin\mimo-mcp\{mcp\mimo-mcp-server.mjs,core\*}`、`plugins\playwright-mcp\`(含浏览器内核 `browsers\`)。
147
+ 这些是**稳定副本**(仓库/包体变动不影响),但其权威源在仓库 `deploy/legacy-mcp/` + `mcp/`。
148
+
149
+ ### 7.5 状态与设置
150
+
151
+ - 设置文件:`dsh-home\cli-bridge-settings.json`(交接时:`enabled=[codebuddy,agy]`、
152
+ `priority=[agy,codebuddy,mimo]` → `order=[agy,codebuddy]`,即 **mimo 停用、agy 优先级最高**)。
153
+ - 状态路由:`GET /cli-bridge/status`(含 `scheduling`);旧路由 `/<id>-indicator/status` 仍返回裸桶。
154
+ - GUI 需要登录态;**用 HTTP 探针即可**(不要把无凭据浏览器指向 GUI,会 401)。
155
+
156
+ ## 8. 发布流程
157
+
158
+ 见 `docs/RELEASE-SOP.md`(铁律 + 逐步命令)。要点:
159
+
160
+ 1. `npm run check` 全绿 → 版本三锁同步(含 `CHANGELOG.md` 顶部)→ `node scripts/build.mjs` → commit → tag → push;
161
+ 2. **scoped 包可见性权威开关是 `package.json` 的 `publishConfig.access="public"`**
162
+ (0.2.2 首发踩坑:只靠命令行 `--access public` 时,走 GUI/插件通道发布不带该参数 → `E402 Payment Required`);
163
+ 3. 发布后可 `npm deprecate <old>@* "<msg>"` 迁移旧包;**先发布后弃用,顺序不可倒置**;
164
+ 4. npm 首次创建 scoped 包返回 `PUT 202 Accepted`("may take a few minutes")**属正常,勿重复发布**。
165
+
166
+ 本机发布通道:DSH 工具 `repo_push_access`(GUI 插件 “repo-push-access”,凭据存 DSH 凭据库)。
167
+
168
+ ## 9. 凭据与安全
169
+
170
+ - 凭据库:`dsh-home\.credentials.yaml`。**键必须形如 `<scope>/<id>`**
171
+ (如 `repo-push-access/github-com`、`repo-push-access/registry-npmjs-org`)——
172
+ 曾因键写成 `repo-push-access:github.com` 导致凭据文档整体不可读 → DSH 启动致命错 + profile 被隔离为
173
+ `profiles.broken-*`。
174
+ - 命令行侧**没有** npm/GitHub 登录态;需要 CLI 操作时从凭据库取用,**不要把 token 打进日志/翻译稿**。
175
+ - 仓库内不得出现任何 token;`.credentials.yaml` 及其备份不入库。
176
+
177
+ ## 10. 排障手册(症状 → 原因 → 处置)
178
+
179
+ | 症状 | 原因 | 处置 |
180
+ | --- | --- | --- |
181
+ | 设置面板白屏 / 整个插件页崩 | client.js 引用了未声明标识符,或 load id ≠ 包名 | 跑 `tests/keystone/client-ui-surface.test.mjs`(含标识符扫描)与 `client-id.test.mjs` |
182
+ | 面板没有横向标签 / 没有调度卡 | 浏览器仍在用旧 client.js | F5 刷新;核对 `GET /cli-bridge/settings` 是否含 `scheduling`(不含=宿主也是旧代码 → 重启) |
183
+ | 面板改了启用/优先级但没生效 | ①POST 未成功 ②宿主形态需重启会话 ③统一 MCP 子进程需重启 | 看 `cli-bridge-settings.json` 是否写入 `_scheduling`;家级 `bin\` 服务器无需重启(每请求读盘) |
184
+ | 指示灯长期亮着 | 陈旧项目(>10 分钟无活动)驱动了顶层聚合 | 0.2.1 已修(客户端过滤 + 服务端聚合只看新鲜项目);复发查 `projects[].stale` 与 `PROJECT_TTL_MS` |
185
+ | `pnpm install` 后还是旧代码 | `file:` 依赖按版本键控缓存 | 先 `Remove-Item` 快照目录再 `pnpm install --prefer-offline`,然后哈希比对 |
186
+ | npm 发布 `E402 Payment Required` | scoped 包按私有发布 | `package.json` 加 `publishConfig.access="public"` |
187
+ | npm 发布后 `npm view` 404 | 首次创建 scoped 包在 processing / CDN 负缓存 | 看 npm 日志 `…\.npm-cache\_logs\*` 的 `PUT 202`;等几分钟,别重复发 |
188
+ | 家级补丁报 `Sequence item without - indicator` | 解除注释时把**段落注释**也剥了(前导 `#` 被误删) | 从 `*.bak-*` 还原,按**条目行区间**精确剥离;用 §7.3 的 YAML 校验命令 |
189
+ | 会话里没有 `mcp__*` 工具 | 家级补丁四条 MCP 行被注释 / 未重启 / 子进程未起 | 检查补丁活跃 id、重启 DSH、`Get-CimInstance Win32_Process` 找 node 子进程 |
190
+ | 出现 `profiles.broken-*` | 启动期插件激活失败被桌面壳隔离 | 看 `dsh-home\logs\startup-*.log` 定位首个 error;历史根因是凭据键格式 |
191
+
192
+ ## 11. 待办与已知遗留
193
+
194
+ 1. **重启 DSH** —— 恢复的四条 MCP 行需要重启才注册(交接时点刚改完配置,尚未重启)。
195
+ 重启后:新会话出现 `mcp__agy__*`(4 个,含 quota)、`mcp__codebuddy__*`(3)、`mcp__playwright__*`;
196
+ `mcp__mimo__*` 因调度停用而**工具面为空**(这是设计行为,不是故障)。
197
+ 2. 可选:`repo-push-access` 插件写临时 npmrc 时带的 `always-auth=true` 触发 npm 11 弃用警告
198
+ (源码在 `C:\Users\lcl\Desktop\DSH插件开发\git推送管理\repo-push-access`);删掉该行即可静音。
199
+ 3. 可选:npm 上的 0.2.2 比仓库少 2 个**纯文档** commit(发布后的 release notes/SOP 补充);
200
+ 如需 npm 侧完全一致,可发 0.2.3(无功能改动)。
201
+ 4. `dsh-home\profiles.broken-*` 是历史隔离物(用户数据,未清理)。
202
+
203
+ ## 12. 事故史速查(后来者避坑)
204
+
205
+ - **client 注册 id 必须等于包名**:旧包曾因 id 不匹配导致整屏崩溃 → 现在三重机器锁。
206
+ - **一次 edit 失败没复查**:渲染引用了未定义的 handler → 白屏,`node --check` 查不出 →
207
+ 新增「渲染引用标识符必须已声明」静态测试。
208
+ - **React hook 顺序**:tab 的 `useState` 曾放在 `if (!view) return` 之后 → view 加载瞬间 hook 数量变化 → 崩面板;
209
+ 现在有「hook 必须在早期 return 之前」的静态锁。
210
+ - **profile 隔离会吞掉用户层补丁**:`profiles/web/cordis.patch.yml` 曾随隔离重建丢失 →
211
+ 机器级配置一律写 `dsh-home\cordis.patch.yml`(家级,不受隔离影响)。
212
+ - **双源挂载**:家级 `file://` 行与 bundle 层同时声明同一 id → `multiple active Loader sources` 致命错误;
213
+ 统一包只走 bundle 层,家级只保留注释留档。
214
+ - **MCP 反复丢失**:家级三条 MCP 行曾在隔离重建中消失且被当基线固化;恢复时误留成注释 →
215
+ 本次已恢复为活跃行(§7.3)。
216
+
217
+ ---
218
+
219
+ ### 交接最小检查单
220
+
221
+ - [ ] `npm run check` 全绿(271 测试)
222
+ - [ ] `node mcp/cli-bridge-mcp.mjs --check` 显示 `scheduling.source`
223
+ - [ ] `GET $env:DSH_WEB_URL/cli-bridge/status` 返回三家 + `scheduling`
224
+ - [ ] 重启 DSH 后确认四条 MCP 工具面(含 mimo 为空)
225
+ - [ ] 设置面板能勾选/排序/保存,且 `cli-bridge-settings.json` 落盘
226
+ - [ ] 知道红线在 §5、生效时机在 §7.2、排障在 §10
@@ -5,8 +5,11 @@
5
5
 
6
6
  ## 0. 铁律(违反任何一条都不要发布)
7
7
 
8
- 1. **npm publish 必须带 `--access public`**:包是 `@luchenglong` scope,scoped 包默认
9
- restricted,漏了直接 402/私有可见性事故。
8
+ 1. **scoped 包可见性 = `package.json` 的 `publishConfig.access = "public"`**:包是
9
+ `@luchenglong` scope,scoped 包默认 restricted。**权威开关必须写在 package.json 里**
10
+ (0.2.2 首发踩坑:SOP 只要求命令行 `--access public`,但走 GUI/插件通道发布时不带该
11
+ 参数 → npm 按私有包处理 → `E402 Payment Required`)。命令行仍建议显式带
12
+ `--access public` 双保险,漏了也不会再翻车。
10
13
  2. **client 注册 id === 包名**(`@luchenglong/cli-bridge`,红线 4)。`scripts/verify.mjs`
11
14
  与 `tests/keystone/client-id.test.mjs` 双重机器闸门。改包名必须同改 client.js 的
12
15
  `__ModuleLoader__.load({ id })`,否则 client combo 加载失败 → DSH 启动致命屏(agy
@@ -1112,7 +1112,7 @@ function isBridgeEnabled(selfId, ids, io) {
1112
1112
  }
1113
1113
 
1114
1114
 
1115
- const SCHED_ALL_IDS = ["agy","codebuddy","mimo"]
1115
+ const SCHED_ALL_IDS = ["agy","codebuddy","mimo","opencode"]
1116
1116
 
1117
1117
 
1118
1118
  return {
@@ -1644,7 +1644,7 @@ function isBridgeEnabled(selfId, ids, io) {
1644
1644
  }
1645
1645
 
1646
1646
 
1647
- const SCHED_ALL_IDS = ["agy","codebuddy","mimo"]
1647
+ const SCHED_ALL_IDS = ["agy","codebuddy","mimo","opencode"]
1648
1648
 
1649
1649
 
1650
1650
  return {
@@ -1584,7 +1584,7 @@ function isBridgeEnabled(selfId, ids, io) {
1584
1584
  }
1585
1585
 
1586
1586
 
1587
- const SCHED_ALL_IDS = ["agy","codebuddy","mimo"]
1587
+ const SCHED_ALL_IDS = ["agy","codebuddy","mimo","opencode"]
1588
1588
 
1589
1589
 
1590
1590
  return {