dev-manager-tauri/.blueprint/modules/toolchain-capability-pack.md
lanrtop cd9d5ffc57 chore(blueprint/toolchain): 收口工具链能力包状态
同步 PR #16 已合并事实,将 T9 与模块进度标记为完成。
2026-09-23 03:19:06 +09:00

16 KiB
Raw Blame History

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

设计决策:项目工具链契约、解析与 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: done
  • 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: 环境工具弹窗能看懂期望/实际版本、来源路径和准备结果。"
  • done_note: "2026-09-22:运行态 MCP 对 Enterprise 返回 Node 24.19.0、pnpm 9.15.0 且均为 compliant_unmanaged,由此发现并修复 Windows .cmd wrapper 版本探测;pnpm typecheck 通过。用户截图完成 human_verify,并要求将模态框扩大到 92vw/max-w-5xl、88vh/max-h-900px,确认信息密度与滚动体验符合预期。复盘待炼境 MCP 在本会话可用后回填。"

✅ 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: done
  • 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 阻塞。"
  • done_note: "2026-09-22:PR #11 合并后,通过炼境 apply_onboarding_pack 为 Enterprise 写入最小 mise.toml、升级 AGENTS/skill/capability-packs,verify_onboarding 12/12;Windows 用户级安装 mise 2026.9.12 后,get_toolchain_status 为 ready_managed。消费者 CLI 实测 Node v24.19.0、pnpm 9.15.0、pnpm check:toolchain exit 0,package.json/pnpm-lock.yaml 零非预期改动;新 Codex 会话可直接通过 mise 使用项目版本,不再被 bundled pnpm 11 阻塞。Enterprise 主线经 PR #173–#175 收敛,合并提交 a2e85f50 的 Gitea main CI #529 中 agent 与 deploy-impact 成功,agent 在业务检查前完成 Node/pnpm 安装及工具链断言;纯蓝图变更未触发 API/Web 部署。"

✅ T8. 炼境自身工具链契约闭环

  • status: done
  • complexity: M
  • files: .nvmrc, package.json, mise.toml, .gitea/workflows/pr-check.yml, .blueprint/modules/toolchain-capability-pack.md, .blueprint/manifest.yaml
  • acceptance: "agent_verify: [CLI] mise exec -- node --version → v24.19.0,mise exec -- pnpm --version → 9.15.0;[炼境能力本体] get_toolchain_status(dev-manager-tauri) → Node/pnpm 均为 ready_managed 且 executable 指向 mise 安装目录;[项目验证] pnpm typecheck 与 cargo test --lib 通过;[Gitea CI] pnpm/action-setup 与 setup-node 只消费 packageManager/.nvmrc,PR CI 通过;[Git] git diff -- pnpm-lock.yaml → 空。"
  • decision_note: "版本事实继续使用开放标准声明:.nvmrc 固定 Node,package.json#packageManager 固定 pnpm;mise.toml 仅启用 idiomatic version file 读取,不复制版本,也不新增 engines 第二事实来源。"
  • done_note: "2026-09-22:炼境自身新增 .nvmrc 24.19.0、packageManager pnpm@9.15.0 与最小 mise resolver。CLI 命中 mise 安装目录,typecheck 通过、Rust 151/151;真实 MCP get_toolchain_status 验收 Node/pnpm 均为 ready_managed,pnpm-lock.yaml 零改动。首次 push CI #120 精确暴露 pnpm 双版本来源,修复后 push #122 与 PR #123 均成功,PR #15 以 head 23e9c297ca 经安全门禁合并为 96f88a8。"
  • retrospective: "【复盘】炼境自身工具链契约闭环|任务类型: 架构调整|复杂度: M|实际轮数: 3轮(预估 1 轮)|是否返工: 是|返工原因: Gitea workflow 同时硬编码 pnpm 9 与读取 packageManager,pnpm/action-setup 拒绝双版本来源|有效策略: 本地与 MCP 后继续让真实 push/PR CI 消费契约,门禁暴露 adapter 漂移并以单一事实来源修复|遗留风险: distribute_cicd 的通用 web_ssh/tauri_oss/pr_ci 模板仍硬编码 pnpm 9 与默认 Node 20,需另立兼容旧项目的任务,不能混入“炼境自身”T8|auto_applied_rules: R02, R11, R13|rule_effectiveness: R02=有效, R11=有效, R13=有效"

✅ T9. 通用 CI 分发模板消费项目工具链契约

  • status: done
  • complexity: M
  • depends: T1. Node/pnpm 工具链契约解析器, T8. 炼境自身工具链契约闭环
  • files: src-tauri/src/commands/cicd.rs, src/components/dashboard/CicdModal.tsx, docs/tauri-cicd-guide.md, .blueprint/modules/toolchain-capability-pack.md, .blueprint/manifest.yaml
  • acceptance: "agent_verify: [cargo test] 临时项目提供 .nvmrc + package.json#packageManager 时,web_ssh/tauri_oss/pr_ci 模板使用 node-version-file 且 pnpm/action-setup 不重复写 version;只有部分声明时逐工具消费契约,完全缺失时保持已保存 Node 版本或 Node 20 + pnpm 9 的旧项目回退;冲突声明拒绝生成并返回证据;cargo test --lib 与 pnpm typecheck 通过,git diff -- pnpm-lock.yaml 为空。human_verify: CI/CD 模态框明确标注 Node 输入仅为无项目声明时的兼容回退版本。"
  • decision_note: "CI adapter 复用 parse_toolchain_contract,不复制解析规则;项目声明是第一事实源,CicdConfig 只保留旧项目回退语义。"
  • done_note: "2026-09-23:实现提交 9bf2d579 通过 PR #16 合并为 7c87b86;web_ssh、tauri_oss、pr_ci 模板统一消费项目工具链契约,旧项目回退与冲突拒绝路径保留。后续 T10 的 PR #17 也在同一 master 基线上通过 CI,蓝图状态现与 Git 事实收口。"

执行顺序

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

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