跳到主要内容

第 8 章:选择性安装器——从复制文件到解析计划

为什么 ECC 需要 installer

ECC 资产多、目标多、安装级别多。直接 cp -R 会遇到:重复安装、宿主路径不一致、用户现有配置被覆盖、插件和手工安装叠加、版本漂移后无法 repair。新安装器因此采用“请求 → 解析 → 执行 → 状态”的四阶段。

三种 manifest

文件角色
install-components.json面向用户的 81 个选择项,按 baseline / language / framework / capability / agent / skill / locale 分类
install-modules.json34 个实际安装单元,声明 kind、paths、targets、依赖、成本和稳定性
install-profiles.json7 个预设组合:minimal、opencode、core、developer、security、research、full

component 是产品语言,例如 capability:security;module 是执行语言,例如 security。一个 component 可以映射到一个或多个 module,多个 component 也可以共享同一 module。这种间接层让用户选择不会被物理目录结构绑死。

解析依赖闭包

developer profile 为例,除了 rules、agents、commands、hooks、platform 和 workflow,还会带上 framework-language、database、orchestration。解析器需要:

  1. 读取 profile 的 module 列表。
  2. 递归补齐每个 module 的 dependencies。
  3. 去重并保持 resolution order。
  4. 按 target 过滤不支持当前宿主的 module。
  5. 将用户 --with / --without / --skills 选择合并到请求。
profile / modules / components

normalized request

dependency closure

target filtering

ordered operations

Plan 与 Apply 分开

scripts/install-plan.js 是只读预览入口,可列出 profile、module、component,也可以输出 JSON。scripts/install-apply.js 才执行复制、合并和状态写入。CLI 的 --dry-run 会贯穿这条链路,适合在写入用户目录前检查结果。

安装计划里的 operation 不是简单的“源路径 → 目标路径”,还会记录策略和 ownership,例如递归复制、JSON merge、scaffold-only。对 OpenCode,生命周期还会在需要时构建 .opencode/dist payload。

Install-state 是可修复性的基础

状态 schema ecc.install.v1 记录:

{
"schemaVersion": "ecc.install.v1",
"target": {"id": "claude", "root": "...", "installStatePath": "..."},
"request": {"profile": "developer", "modules": [], "includeComponents": []},
"resolution": {"selectedModules": [], "skippedModules": []},
"source": {"repoVersion": "2.1.0", "manifestVersion": 1},
"operations": []
}

于是:doctor 可以判断 managed files 是否缺失或漂移;repair 可以从可信 repo source 恢复;uninstall 只删除状态中记录的 managed files。install-lifecycle.js 还会拒绝越过 trusted root 的 source path 和 final symlink,避免 repair 成为路径穿越或任意覆盖入口。

旧安装路径如何共存

install.sh 只是 legacy shell wrapper:解析自身真实路径、必要时安装 npm 依赖,然后把参数交给 scripts/install-apply.js。这样保留了 bash ./install.sh ... 的用户习惯,同时将真实逻辑集中到 Node runtime,获得 Windows/macOS/Linux 的一致性。

源码定位