dev-manager-tauri/.blueprint/modules/architecture-evolution.md
lanrtop d1b9b0564e
All checks were successful
Push & PR Check / check (push) Successful in 1m2s
Push & PR Check / check (pull_request) Successful in 59s
feat(onboard/parity): 客户端适配器注册表与三端结构化注入结果,onboard 模块投影无关适应度测试(P8b、A1a)
一键接入(P8)编排前置:Claude local 与 DSH 托管块的成败原来只写日志,inject_mcp
笼统回「已配置 Codex 与 Claude」,失败会被报成成功(R4)。

- 新增 src-tauri/src/onboard/:ClientId、ClientOutcome(converged/applied/refreshed/
  removed/manual_kept/other_project/not_installed/skipped/missing/unavailable/
  needs_human/failed)、ClientAdapter(detect/static_status/apply)与 registry();
  适应度测试 onboard_module_is_projection_free 机器校验本体不依赖投影层
- 三端适配器实现在 mcp_inject,注册表反向接入;注入经 registry() 逐端 apply,
  新增 inject_project_mcp_report,inject_project_mcp 签名与「Codex 失败即整体失败」
  语义不变
- sync_claude_local / ensure_dsh_patch 抽出依赖注入版,每条分支返回结构化结果,
  日志类别与文案不变;upsert_codex_mcp_config 返回 converged/applied/manual_kept
- verify_onboarding(MCP)附加 clients 只读三端状态,不计入 checks、不影响 pass;
  inject_mcp 回执逐端列出实际结果
- 行为变化(有意):Codex 手写同名 server 改记 manual_kept 不再阻断 Claude/DSH;
  WSL 项目 Claude local 记 skipped 不再起 CLI
- 新增 9 条测试(假 CLI 覆盖 Claude 全部分支、临时 DSH 目录四态);cargo test
  295 passed;契约同步 project-context.yaml,AGENTS.md 架构速查补 onboard/

Feature-Confirmed: true
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:25:04 +09:00

6.4 KiB
Raw Blame History

id name status progress
architecture-evolution 炼境架构演进 planned 0

概述

2026-10-01 评估结论:现有技术栈(Tauri v2 + Rust + React/TS + SQLite)适合「管家 / agent 客户端兼容层」方针,不换栈。常驻托盘服务、凭据安全、单文件分发、cargo test 快速回归都是 Rust/Tauri 的强项;真正的难点在 Windows 与各客户端自身机制(cmd 引号与 %VAR% 展开、CRLF、Claude 配置作用域、DSH !!js、Node 拒绝直接执行 .cmd),与语言无关。Electron 全 Node 栈(与三家客户端同生态、JSON/YAML 顺手)因常驻内存大、凭据需原生模块且须整体重写而否决;Go、Python 无明显收益。

本模块收集比「换语言」更影响实现效率的结构性改进,按收益排序。

任务拆解

📋 A1 — 本体与投影分离(2026-10-03 改写为三段:A1a / A1b / A1c)

  • status: todo
  • complexity: L(已拆,见下)
  • 原卡:core crate + CLI——「业务逻辑位于不依赖 Tauri 的 core crate;同一 exe 或独立 cli 在炼境界面未运行时可执行 onboard / probe / diagnostics」。原「为什么」:核心逻辑写在 Tauri 应用内,炼境不运行时 agent 与脚本无法调用;拆分后 Tauri 界面、MCP 服务、命令行成为同一本体的三个投影。
  • 改写理由(2026-10-03 agent-client-parity P8 设计评审,docs/tasks/2026-10-03-p8-onboarding-oneclick-design.md §5):
    1. P8 与 P4 的验收载体是 Tauri command 和 MCP,本来就跑在炼境进程里;探针测的是「客户端连上运行中的炼境 MCP」,炼境离线时无物可测——「界面不运行也能用的 CLI」对它们没有用例。
    2. 离线写入有实际危害:MCP_OP_LOCK、DSH_PATCH_LOCK 与凭据存储的锁只在进程内有效,~/.claude.json(经 claude CLI)、~/.dsh/cordis.patch.yml、Credential Manager、SQLite 会被两个进程竞争写;agent 从 MSIX 客户端里调用时 AppData 写入可能被重定向(P3 已实证)。
    3. 真正的耦合是全局 pool()(约 293 处、43 个文件)和进程内静态锁,拆 crate 解决不了;A1 是 L 级,会与 A4、P6 大面积冲突,把 P8 推迟数周。
    4. 复用主 exe 做 CLI 还要处理控制台挂接(release 为 windows_subsystem="windows")和 single-instance,那是拆 crate 时才需要解决的设计问题。 结论:P8 需要的是 A1 的原则(本体不依赖投影),不是 crate 拆分。

✅ A1a — onboard/ 模块的投影无关约束(随 agent-client-parity P8b 落地)

  • status: done
  • verification: "2026-10-03(分支 feat/agent-client-parity-p8):src-tauri/src/onboard/mod.rs 内 onboard_module_is_projection_free 逐个读取 onboard/*.rs,出现 tauri::、db::pool(、#[tauri::command] 即失败(模式拼接书写,测试自身不命中);当前 mod.rs 与 clients.rs 通过。ProcessRunner、ClientLocator 尚未引入(P4d 引入时同受此约束);三端适配器实现暂在 mcp_inject(需其私有辅助函数),按绞杀者模式在 P8d 起逐步迁入。"
  • complexity: S
  • depends: agent-client-parity P8b
  • acceptance: "agent_verify: [cargo test] onboard_module_is_projection_free——src-tauri/src/onboard/ 下的源码不含 tauri::、db::pool(、#[tauri::command];连接、CredentialStore、ProcessRunner、ClientLocator 都由调用方注入,结果一律是 serde 结构体。"
  • 说明:由 P8b 承载实现,P8b ✅ 时本卡同步 ✅。存量代码不扩散旧写法,旧入口按绞杀者模式逐步改成薄包装;A1-ready 由测试机器校验,而不是靠约定。

📋 A1b — CLI 薄客户端(按需)

  • status: todo
  • complexity: M
  • acceptance: "agent_verify: [CLI] 由真实需求定义;探针场景已由 agent-client-parity P4e 的 pnpm probe:clients(调用全局 MCP 的薄脚本,不新增协议面)覆盖。"
  • 触发:「会话启动时 MCP 没连上、需要第二通道」被证明是常态时,再做 Rust console 版 lianjing.exe 与 skill 降级说明(需升接入包版本、全部子项目重新分发)。

📋 A1c — core crate 拆分(触发式,届时先 /architect)

  • status: todo
  • complexity: L(先 /architect 再拆)
  • acceptance: "agent_verify: [cargo test] 业务逻辑位于不依赖 Tauri 的 core crate;具体验收在触发后的 /architect 设计中定义。"
  • 触发条件(满足任一即启动):① 需要在没有 Tauri/WebView 的环境(例如 Linux CI)里跑本体;② 确实需要离线写入,并且跨进程锁和包上下文检测已经具备;③ cargo test 的编译时延成为主要的反馈延迟;④ 出现第三个独立的消费者。

📋 A2 — 前后端类型契约自动生成

  • status: todo
  • complexity: M
  • files: src-tauri/src/commands/、src/lib/commands.ts
  • acceptance: "agent_verify: [pnpm typecheck] commands.ts 的参数与返回类型由 Rust 定义生成(tauri-specta 或 ts-rs),新增 command 不再手抄类型;删改 Rust 字段时 typecheck 报出所有受影响处。"
  • 为什么:现由规则 R01 要求手动同步 commands.ts,易漏;对应四支柱「可推理」。

📋 A3 — 配置文本生成模板化

  • status: todo
  • complexity: M
  • files: src-tauri/src/mcp_inject.rs、src-tauri/resources/
  • acceptance: "agent_verify: [cargo test] Codex 托管块、DSH 托管块、shim 等由模板(如 minijinja)渲染,并有「渲染结果是合法 YAML/TOML/JSON」测试。"
  • 为什么:2026-10-01 实现 P1 时在 Rust 中手拼 YAML/JS,出现缩进被字符串续行吞掉、转义少一个反斜杠两个缺陷(均被测试拦下)。模板能从写法上避免这类问题。

📋 A4 — MCP 协议改用官方 Rust SDK(rmcp)

  • status: todo
  • complexity: M
  • files: src-tauri/src/mcp_server.rs、src-tauri/src/mcp_tools.rs
  • acceptance: "agent_verify: [cargo test + 三端无头探针] 换用 rmcp 后 scoped 路由、敏感读取认证、SSE 与 streamable HTTP 行为不变,三端 A–F 矩阵不回退。"
  • 为什么:现为手写 JSON-RPC + SSE。各客户端对 MCP 的支持持续演进(streamable HTTP、认证、服务器说明等),自维护协议细节的成本会上升。

附:调用外部进程的 Tauri command 统一 async

  • 同步 Tauri command 跑在主线程,内部调用 claude CLI 等外部进程会卡界面;agent-client-parity 审查已两次发现此类问题。新增此类 command 默认 async,存量随相关改动迁移,不单独立卡。