feat(mcp/parity): DSH 桌面 GUI 按工作区连项目地址(会话级插件,P9) #26

Merged
lanrtop merged 3 commits from feat/agent-client-parity-p9 into master 2026-10-02 15:37:48 +08:00
Owner

目标

蓝图 agent-client-parity P9:让 DSH 桌面版(GUI)按工作区连到炼境的项目专用地址,在 enterprise 工作区新建的会话也能直接用开发变量等项目工具。

为什么要用插件

DSH 桌面版只有一个后台进程,启动目录固定。托管块里的 !!js 只在启动时求值一次,拿不到会话信息,所以只改托管块做不到按工作区切换。

DSH 自带「Agent 作用域」:每个会话都带着自己的工作目录,会话创建时会触发 agent/created。插件在这时按工作目录匹配炼境登记的项目白名单,命中才在该会话作用域挂项目地址,同名工具覆盖全局 lian-jing,其他会话不受影响。web 和 acp 这类多工作区模式也一并受益。

改动

  • src-tauri/resources/dsh/lianjing-session-mcp.v1.mjs:会话级插件,随二进制打包。刷新 DSH 托管块时写到 %USERPROFILE%\.lian-jing\dsh\。
  • 托管块:在全局行之后追加插件条目。条目 id 与文件名同一版本号,带「插件文件存在才启用」的守卫,port、shim、roots 以 JSON 写入。
  • 白名单:同时写入登记路径的规范形态(junction、8.3 短名),因为 GUI 给出的工作目录是真实路径。
  • 插件防御措施:
    • headless 模式交给全局行处理;
    • DSH 接口不符时降级为只有全局工具;
    • 取认证不超过 3 秒,整次挂载不超过 5 秒;
    • 所有回调都吞掉异常;
    • 带工具限制的子代理不挂载。

自验

  • cargo test:247 passed。
  • vitest:16 passed,其中插件用例 8 条;typecheck 通过。
  • 端到端:临时 DSH_HOME,用从真实 ~/.dsh 复制的完整托管块和桩服务,认证经真实稳定入口获取。
    • DSH 0.2.0-rc.2 和 0.1.5-rc.2 上,项目子目录会话都带认证连上项目地址,其他目录的会话没有任何请求;
    • 插件文件缺失时,两个版本都能正常启动。
  • 对抗审查:11 个 agent,6 条成立(均为 low),已全部修复。

没验什么

  • DSH 桌面 GUI 内的实际效果:挂载的工具是否对会话模型可见,改托管块后能否热加载。这两点只有代码阅读结论,加上 ACP 探针实测,需要人在 GUI 里终验。
  • 在 0.1.x 上,工具在会话创建后约几十毫秒才就绪,极端情况下首轮请求可能只看到全局工具。
  • 插件依赖 DSH 的内部接口,DSH 升级后可能失效。失效时插件会降级,并在 stderr 打 [lian-jing] 提示。
  • 已知的无关问题:mcp_server 的 scoped_mcp_create_pull_request_uses_synthetic_credential 在全量并行测试中偶发失败,单独跑能通过。

人终验

重启 DSH 桌面版,在 enterprise 工作区新建会话,让它实际调用 list_project_dev_variables 和 read_project_test_account(name=LJ_PROBE_NONEXISTENT),第二步应返回「开发需求未登记」。再到其他工作区新建会话,应看不到开发变量工具。

🤖 Generated with Claude Code

## 目标 蓝图 agent-client-parity **P9**:让 DSH 桌面版(GUI)按工作区连到炼境的项目专用地址,在 enterprise 工作区新建的会话也能直接用开发变量等项目工具。 ## 为什么要用插件 DSH 桌面版只有一个后台进程,启动目录固定。托管块里的 `!!js` 只在启动时求值一次,拿不到会话信息,所以只改托管块做不到按工作区切换。 DSH 自带「Agent 作用域」:每个会话都带着自己的工作目录,会话创建时会触发 `agent/created`。插件在这时按工作目录匹配炼境登记的项目白名单,命中才在**该会话作用域**挂项目地址,同名工具覆盖全局 lian-jing,其他会话不受影响。web 和 acp 这类多工作区模式也一并受益。 ## 改动 - `src-tauri/resources/dsh/lianjing-session-mcp.v1.mjs`:会话级插件,随二进制打包。刷新 DSH 托管块时写到 `%USERPROFILE%\.lian-jing\dsh\`。 - 托管块:在全局行之后追加插件条目。条目 id 与文件名同一版本号,带「插件文件存在才启用」的守卫,port、shim、roots 以 JSON 写入。 - 白名单:同时写入登记路径的规范形态(junction、8.3 短名),因为 GUI 给出的工作目录是真实路径。 - 插件防御措施: - headless 模式交给全局行处理; - DSH 接口不符时降级为只有全局工具; - 取认证不超过 3 秒,整次挂载不超过 5 秒; - 所有回调都吞掉异常; - 带工具限制的子代理不挂载。 ## 自验 - `cargo test`:247 passed。 - `vitest`:16 passed,其中插件用例 8 条;typecheck 通过。 - 端到端:临时 DSH_HOME,用从真实 ~/.dsh 复制的完整托管块和桩服务,认证经真实稳定入口获取。 - DSH 0.2.0-rc.2 和 0.1.5-rc.2 上,项目子目录会话都带认证连上项目地址,其他目录的会话没有任何请求; - 插件文件缺失时,两个版本都能正常启动。 - 对抗审查:11 个 agent,6 条成立(均为 low),已全部修复。 ## 没验什么 - **DSH 桌面 GUI 内的实际效果**:挂载的工具是否对会话模型可见,改托管块后能否热加载。这两点只有代码阅读结论,加上 ACP 探针实测,需要人在 GUI 里终验。 - 在 0.1.x 上,工具在会话创建后约几十毫秒才就绪,极端情况下首轮请求可能只看到全局工具。 - 插件依赖 DSH 的内部接口,DSH 升级后可能失效。失效时插件会降级,并在 stderr 打 `[lian-jing]` 提示。 - 已知的无关问题:`mcp_server` 的 `scoped_mcp_create_pull_request_uses_synthetic_credential` 在全量并行测试中偶发失败,单独跑能通过。 ## 人终验 重启 DSH 桌面版,在 enterprise 工作区新建会话,让它实际调用 `list_project_dev_variables` 和 `read_project_test_account(name=LJ_PROBE_NONEXISTENT)`,第二步应返回「开发需求未登记」。再到其他工作区新建会话,应看不到开发变量工具。 🤖 Generated with [Claude Code](https://claude.com/claude-code)
lanrtop added 2 commits 2026-10-02 14:07:16 +08:00
DSH 桌面版只有一个 Host 进程、启动目录固定,托管块的 !!js 只在启动时求值,拿不到会话信息;
web/acp 同样一个进程服务多个工作区。改由炼境分发一个会话级插件:会话创建(agent/created)时
按会话工作目录匹配炼境登记的项目白名单,命中才在该会话作用域挂连项目专用地址的 mcp-client,
同名工具覆盖全局 lian-jing,其他会话不受影响。

- 插件随二进制打包(resources/dsh/lianjing-session-mcp.v1.mjs),刷新 DSH 托管块时写到
  %USERPROFILE%\.lian-jing\dsh\;文件名带版本号(Node 按 URL 缓存 ESM)
- 托管块在全局行之后追加插件条目(port、shim、roots 以 JSON 写入);插件文件写失败时只保留全局行
- 插件防御:headless 交给全局行;特性探测不符即降级为全局;取认证 ≤3 秒、整次挂载 ≤5 秒;
  所有回调吞掉异常(Host 对未处理异常会崩溃,agent/created 串行失败会让会话创建失败)
- 块外手写的 lianjing-session-mcp 条目同样拒绝覆盖

验证:cargo test 246 passed;vitest 插件用例 6 条通过、typecheck 通过;端到端在 DSH 0.2.0-rc.2
与 0.1.5-rc.2 上,项目会话经真实稳定入口带认证连上项目地址,其他会话无请求。

Feature-Confirmed: true
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix(mcp/parity): P9 审查修复——受限子代理不挂载、条目 id 带版本、插件缺失守卫、规范路径键
All checks were successful
Push & PR Check / check (push) Successful in 1m6s
Push & PR Check / check (pull_request) Successful in 1m4s
fe0458fe97
对抗审查(11 个 agent,6 条成立,均 low):
- 受限子代理(toolFilter)会绕过限制:挂在子代理自己作用域的工具不受过滤。改为经 tools.view 判断,
  受限或无法判断即不挂;根会话与未受限子代理照常挂载
- 版本号只编进文件名时,运行中的 DSH 不会重载新插件(同 id 只改 name 不重载):条目 id 改为
  lianjing-session-mcp-v1,与文件名同一版本;新增内容哈希测试,改插件漏升版本即失败;块外手写按前缀拒绝
- 插件文件缺失时 DSH 0.1.x 启动失败:条目加 `disabled: !!js` 文件存在性守卫
- GUI 会话工作目录是 realpath:白名单同时写入登记路径的规范形态(junction、8.3 短名)
- 补测试:分层停止哨兵、取认证失败与超时(.cmd 夹具)、受限/未受限/无法判断的子代理
- 蓝图如实更正首轮端到端只有插件一行;补测完整托管块

验证:cargo test 247 passed;vitest 16 passed(插件 8 条)、typecheck 通过;完整托管块端到端在
DSH 0.2.0-rc.2 与 0.1.5-rc.2 上项目会话带认证连上项目地址、其他会话无请求;插件文件缺失时两版都正常启动。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lanrtop added 1 commit 2026-10-02 15:32:32 +08:00
docs(blueprint/agent-client-parity): P9 人终验通过,标记完成
All checks were successful
Push & PR Check / check (push) Successful in 1m4s
Push & PR Check / check (pull_request) Successful in 1m6s
f8d658b790
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lanrtop merged commit 79853b71f2 into master 2026-10-02 15:37:48 +08:00
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: lanrtop/dev-manager-tauri#26
No description provided.