dev-manager-tauri/.blueprint/modules/toolchain-capability-pack.md
lanrtop 8376bcbfd2 fix(toolchain): 修复 Windows wrapper 版本探测
优先选择 .exe/.cmd/.bat 路径并直接执行版本命令,补充含空格路径测试;运行态 MCP 已确认 Enterprise 的 Node 与 pnpm 版本可正确识别。

Rules-Applied: R07,R08,R10,R13
2026-09-22 01:23:34 +09:00

12 KiB
Raw Blame History

id name status progress
toolchain-capability-pack 项目工具链能力包 in_progress 71

设计决策:项目工具链契约、解析与 Agent 执行闭环 v1

背景

炼境现有 project-env-scan 能识别 .nvmrc、.node-version、Volta 与 lockfile,devtools-scan 能读取本机 Node、pnpm 等实际工具,但两者仍是信息展示:项目声明与当前执行环境没有形成可比较、可准备、可复现的闭环。

Enterprise System 已精确声明 Node 24.19.0 与 pnpm 9.15.0,而 Codex bundled runtime 暴露 pnpm 11.19.0 且无 Corepack。现有 check:toolchain 能正确拦截漂移,却缺少自动选择项目版本的 resolver,导致 Agent 每次会话重复阻塞。

方案选择

方案 取舍 结论
所有项目追随 Codex bundled runtime 初次零配置,但 Codex 升级会反向驱动项目漂移,且无法覆盖其他 IDE/CI 否决
仅 .nvmrc + Corepack 声明简单,但依赖人工切换;Corepack 不保证随 Node/Codex 提供 仅兼容
全量 Dev Container / Docker 开发 复现性强,但对 Windows/Tauri/前端热更新和本地磁盘成本过重 特殊项目可选
标准项目声明 + mise resolver + 炼境能力包 项目继续拥有版本事实;人、Codex、CI、部署通过各自 adapter 消费同一契约 选定

统一模型与边界

项目版本事实
├─ .nvmrc                         Node 精确版本
├─ package.json#packageManager    pnpm 精确版本
├─ package.json#engines           兼容性/门禁
└─ pnpm-lock.yaml                 依赖图(不承担工具版本切换)
          │
          ▼
工具链 adapter
├─ 本机 / Codex:mise
├─ Gitea CI:从同一声明安装对应 Node/pnpm
└─ production:镜像或构建产物固定版本
          │
          ▼
炼境:实时诊断、受控准备、自检报告、UI/MCP 双投影
  • 不新增 .lian-jing/toolchain.* 版本配置,避免第二事实来源。
  • v1 只治理 Node + pnpm;Rust 继续由 rust-toolchain.toml/rustup 管理,其他语言后续按真实需求增加 adapter。
  • 2026-09-22 用户确认炼境执行面只支持 Windows 项目路径;WSL 不再进入能力包、诊断、准备或消费者验收范围。
  • 实际版本与可执行路径实时读取,不写入 SQLite 作为权威状态;既有 project_env_tools 仅保留展示/快照用途。
  • mise.toml 只启用 .nvmrc 与 packageManager 的 idiomatic version file 读取,不重复抄写版本。
  • 缺少 mise 但实际版本匹配时报告 compliant_unmanaged,不能伪报成可复现的 ready_managed。
  • 安装/下载/信任属于机器状态变更:只允许已登记项目、规范化根路径和显式确认;不得自动信任未知仓库,不执行项目自定义 task/hook,不修改 package/lock 文件。
  • 炼境提供能力与证据,不替项目决定升级版本;升级必须单独走 PR。

系统边界变更

  • 新增纯解析层,统一提取项目 Node/pnpm 声明、来源、冲突和 resolver 配置。
  • 新增只读 Tauri command 与 MCP tool get_toolchain_status(project_id),报告 declared/actual/executable/source/status/recommendation。
  • 新增受控 Tauri/MCP 能力 prepare_toolchain(project_id, confirmed),只构造并执行受限的 mise install 路径。
  • 项目环境 UI 增加工具链契约卡和准备入口,与 agent 调用复用同一业务函数。
  • onboarding/能力包增加版本化自检和条件式 Agent 指引:存在 resolver 时通过 mise exec -- pnpm ... 执行。
  • 不新增数据库表,不改变部署协议,不自动迁移项目版本。

验证路径

  • 载体:Tauri command / MCP tool / CLI 消费者验证。
  • 示例:[Tauri command] get_toolchain_status(enterprise_project_id) → declared Node=24.19.0、pnpm=9.15.0,actual pnpm=11.19.0 时 status=mismatch 且返回实际 executable path。
  • 示例:[Tauri command] prepare_toolchain(enterprise_project_id, confirmed=true) → 仅调用受限 mise install,不修改 package.json/pnpm-lock.yaml;再次诊断为 ready_managed。
  • 示例:[CLI] mise exec -- pnpm check:toolchain → Node 24.19.0、pnpm 9.15.0,exit 0。

风险点

  • 未知仓库执行配置:prepare 前校验项目登记、规范化根路径与显式确认;v1 不运行 mise task/hook。
  • Windows PATH/shim 差异:状态必须同时返回版本与 executable path;测试覆盖 .cmd 解析和 Codex fallback 路径。WSL 明确不支持,不增加双路径兼容分支。
  • 多份版本声明冲突:解析器返回 conflict 并拒绝 prepare,不擅自选择其中一份。
  • 下载与磁盘占用:mise 使用用户级缓存、相同版本跨项目复用;UI 在下载前展示预计动作。
  • CI 与本地 adapter 不同:要求共享同一声明并在 CI 首步执行版本断言,不要求 CI 为形式统一而安装 mise。
  • 范围膨胀:v1 不接管依赖安装、数据库、服务启动和部署,只解决运行时/包管理器选择。

任务卡

✅ T1. Node/pnpm 工具链契约解析器

  • status: done
  • complexity: M
  • files: src-tauri/src/commands/toolchain.rs, src-tauri/src/commands/mod.rs
  • acceptance: "[cargo test] 临时目录分别提供 .nvmrc、.node-version、package.json#packageManager/engines 与 mise.toml → 返回 Node/pnpm declared version、source 和 resolver 配置;冲突声明返回 conflict,缺失字段返回 missing,不读取或修改 lockfile。"
  • done_note: "2026-09-22:新增纯解析器与 6 个测试,覆盖一致声明、精确冲突、engines 仅作兼容门禁、mise 直 pin、空项目;首次测试暴露 pnpm 来源优先级,已修正为 packageManager 优先。复盘待炼境 MCP 在本会话可用后回填。"

✅ T2. 只读工具链状态 Tauri command

  • status: done
  • complexity: M
  • depends: T1. Node/pnpm 工具链契约解析器
  • files: src-tauri/src/commands/toolchain.rs, src-tauri/src/lib.rs, src/lib/commands.ts
  • acceptance: "[Tauri command] get_toolchain_status(project_id) → 返回 declared/actual/executable/source/resolver/status/recommendation;项目不存在或路径越界时显式报错;实际版本匹配但无 resolver 时为 compliant_unmanaged,版本不符时为 mismatch。"
  • done_note: "2026-09-22:新增依赖注入业务函数与薄 Tauri command,只接受已登记项目的 Windows 路径,同时解析 executable path 和版本输出;运行态 MCP 自检发现 where pnpm 优先返回无扩展 shim 且 cmd 引号不稳,已改为优先 .exe/.cmd/.bat 并分别使用直接执行或 cmd /D /S /C。WSL 按用户决策明确不支持。复盘待炼境 MCP 在本会话可用后回填。"

✅ T3. MCP 只读诊断投影与契约文档

  • status: done
  • complexity: M
  • depends: T2. 只读工具链状态 Tauri command
  • files: src-tauri/src/mcp_tools.rs, src-tauri/src/commands/toolchain.rs, docs/ai-context/project-context.yaml
  • acceptance: "[MCP tool] get_toolchain_status(project_id) → 与 Tauri command 返回同一状态模型;mise/Codex/Gitea 不可用时返回 unavailable/missing 证据而非伪造 ready;cargo test 覆盖 schema、dispatch 和降级路径。"
  • done_note: "2026-09-22:新增 get_toolchain_status MCP schema/dispatch、必填参数降级测试并同步外部契约映射;定向测试全绿。复盘待炼境 MCP 在本会话可用后回填。"

✅ T4. 受控 mise 工具链准备能力

  • status: done
  • complexity: M
  • depends: T2. 只读工具链状态 Tauri command
  • files: src-tauri/src/commands/toolchain.rs, src-tauri/src/mcp_tools.rs, src-tauri/src/lib.rs, src/lib/commands.ts
  • acceptance: "[Tauri command] prepare_toolchain(project_id, confirmed) → confirmed=false、未知项目、根路径越界或 contract=conflict 时零执行;confirmed=true 时只执行参数化 mise install,不运行项目 task/hook,不修改 package.json/pnpm-lock.yaml,并返回 before/after 状态与命令证据。"
  • done_note: "2026-09-22:新增 Tauri/MCP 受控 prepare_toolchain;resolver 就绪后通过 mise exec 探测项目版本,拒绝未确认、冲突、缺版本、缺 mise 和含自定义 task/hook/plugin 的配置;返回 verified 区分命令成功与二次诊断 ready_managed,定向测试全绿,未实际下载安装。复盘待炼境 MCP 在本会话可用后回填。"

🔴 T5. 项目环境 UI 工具链契约卡

  • status: blocked
  • complexity: M
  • depends: T2. 只读工具链状态 Tauri command, T4. 受控 mise 工具链准备能力
  • files: src/components/dashboard/ProjectEnvModal.tsx, src/lib/commands.ts
  • acceptance: "agent_verify: [pnpm typecheck] ProjectEnvModal 消费 ToolchainStatus 类型且无类型错误;[Tauri command mock/fixture] ready_managed、compliant_unmanaged、mismatch、conflict 分别渲染准确状态与可用动作,prepare 必须经过确认;human_verify: 环境工具弹窗能看懂期望/实际版本、来源路径和准备结果。"
  • blocked_reason: "代码接线与 pnpm typecheck 已通过;隔离分支已启动,运行态 MCP 对 Enterprise 返回 Node 24.19.0、pnpm 9.15.0 且均为 compliant_unmanaged,并由此发现并修复 Windows .cmd wrapper 版本探测;当前 Computer Use 未暴露 Tauri 原生窗口,本项目也不为 React 组件临时引入测试框架,仍缺 human_verify。需在环境工具弹窗终验状态卡与确认按钮。"

✅ T6. Onboarding 与 Codex Skill 条件式工具链指引

  • status: done
  • complexity: M
  • depends: T3. MCP 只读诊断投影与契约文档, T4. 受控 mise 工具链准备能力
  • files: src-tauri/src/commands/onboarding.rs, src-tauri/resources/onboarding/AGENTS.md.tmpl, src-tauri/resources/onboarding/mise.toml.tmpl, src-tauri/resources/onboarding/lefthook.yml.tmpl, src-tauri/resources/onboarding/.lian-jing/capability-packs.json, src-tauri/resources/onboarding/.agents/skills/lian-jing/SKILL.md, plugins/lian-jing-codex/skills/lian-jing/SKILL.md, lefthook.yml
  • acceptance: "[cargo test] 对已有手写 mise.toml 的项目重跑 onboarding → 不覆盖文件并报告 existing/conflict;对明确选择接入且仅有 .nvmrc + packageManager 的临时项目 → 生成不重复版本的 resolver 配置;[Codex Skill] setup 先调用 get_toolchain_status,managed 项目使用 mise exec -- pnpm,unavailable 时明确降级而不宣称已准备。"
  • done_note: "2026-09-22:接入包新增条件式最小 mise resolver、toolchain-node-pnpm v1.0.0 描述符、AGENTS v1.9.0 与两层 Codex Skill 指引;已有 mise.toml 永不覆盖;commit-msg 改用 Lefthook {1} 参数兼容 managed worktree;16 个 onboarding 测试全绿。复盘待炼境 MCP 在本会话可用后回填。"

🔴 T7. Enterprise System 消费者试点与 CI 同源验证

  • status: blocked
  • complexity: M
  • depends: T3. MCP 只读诊断投影与契约文档, T4. 受控 mise 工具链准备能力, T6. Onboarding 与 Codex Skill 条件式工具链指引
  • files: E:/code-project/enterprise-system/mise.toml, E:/code-project/enterprise-system/AGENTS.md, E:/code-project/enterprise-system/.gitea/workflows/ci.yml
  • acceptance: "agent_verify: [CLI] mise exec -- node --version → v24.19.0,mise exec -- pnpm --version → 9.15.0,mise exec -- pnpm check:toolchain → exit 0;[Gitea CI] 从 .nvmrc 与 packageManager 安装精确版本并在业务检查前通过 check:toolchain;package.json 与 pnpm-lock.yaml 无非预期改动;human_verify: 新 Codex 会话进入 Enterprise 后不再因 bundled pnpm 11 阻塞。"
  • blocked_reason: "运行态只读试点已确认 Enterprise 的 Node 24.19.0、pnpm 9.15.0 声明与本机版本匹配,但 resolver=unavailable,因此仍不是跨 Agent 可复现的 ready_managed。写入试点依赖本分支先完成审查、合并并重建炼境;Enterprise 当前另一个会话还有未提交 T3 migration/蓝图改动,现阶段不跨项目写入或混合验证。"

执行顺序

T1 → T2 → T3;T2 → T4 → T5;T3 + T4 → T6;T3 + T4 + T6 → T7。

核心能力先只读、后受控写;炼境实现者验证完成后,必须由 Enterprise System 以消费者角色完成最终闭环。