跳转到内容

选择安装 Manifest 管道

选择安装 Manifest 管道

学习目标

本章要解决什么问题:理解 ECC 如何在 246 个技能、61 个代理、76 个命令中只安装用户需要的部分。

读完本章后,你将了解:

  • Manifest 驱动的模块化安装架构
  • Profile 系统(full / minimal / custom)
  • 依赖展开与目标过滤
  • 安装状态持久化与 doctor / repair / uninstall

前置知识

本章涉及插件系统的基础知识,建议先阅读:


项目实践

为什么需要选择性安装

ECC 包含大量文件:

  • skills/ — 246 个技能目录
  • agents/ — 61 个代理定义
  • commands/ — 76 个命令
  • rules/ — 12 种语言的规则集
  • scripts/ — 40+ 个 Node.js 脚本
  • hooks/ — 完整钩子系统

全量安装(--profile full)会复制所有文件到 ~/.claude/ 下的插件目录。但很多用户只需要其中一部分(如只想要 TypeScript 相关的规则和几个核心技能)。

Manifest 架构

核心文件职责

文件职责
manifests/install-modules.json模块目录 + 路径列表(如 skills: ["tdd-workflow", "continuous-learning-v2", ...]
manifests/install-profiles.jsonProfile 定义 → 模块列表映射(如 full: ["skills", "agents", "commands", "rules", "hooks"]
scripts/lib/install/request.jsCLI 参数解析 + 请求规范化(--profile full → 模块列表)
scripts/lib/install/runtime.js从规范化请求分派到安装计划创建
scripts/lib/install-executor.js参数转换、遗留兼容、操作具体化、文件系统变更、状态写入
scripts/lib/install-manifests.js模块/Profile 目录加载 + 依赖展开
scripts/lib/install-targets/目标根目录和目的地路径脚手架
scripts/lib/install-state.jsSchema 支持的安装状态读写
scripts/lib/install-lifecycle.js基于已存储操作的 doctor/repair/uninstall
scripts/lib/install-lifecycle.jsdoctor/repair/uninstall 行为(从存储的操作派生)

Profile 系统

ECC 提供三种安装配置文件:

Profile包含内容适用场景
full所有模块完整功能,适合专业用户
minimal核心技能 + 基础规则轻量安装,适合新用户
custom用户自选模块精确控制,按需安装

安装命令示例:

Terminal window
# 全量安装
bash install.sh --profile full
# 最小安装
bash install.sh --profile minimal
# 自定义模块安装
bash install.sh --modules skills:tdd-workflow,rules:typescript,hooks

依赖展开

模块之间可能存在依赖。例如安装 skills:django-tdd 可能依赖 rules:python。安装管道自动处理依赖展开:

用户请求: --modules skills:django-tdd
依赖展开:
- skills:django-tdd (显式请求)
- rules:python (django-tdd 的依赖)
- hooks (django-tdd 的依赖)
目标过滤: 仅安装用户目标 Harness 支持的模块
执行: 复制文件到 ~/.claude/plugins/...

安装状态持久化

每次安装操作都写入 SQLite 状态存储:

-- 简化的状态 schema
CREATE TABLE install_operations (
id INTEGER PRIMARY KEY,
module TEXT NOT NULL, -- 模块名
operation TEXT NOT NULL, -- "install" | "update" | "remove"
target TEXT NOT NULL, -- 安装目标
timestamp TEXT NOT NULL,
version TEXT -- 模块版本
);

这使得以下命令成为可能:

Terminal window
# 查看当前安装状态
node scripts/list-installed.js
# 诊断安装问题
node scripts/doctor.js
# 修复损坏的安装
node scripts/repair.js
# 卸载特定模块
node scripts/uninstall.js --modules skills:tdd-workflow

遗留兼容

ECC 保留了旧的 ecc-install 兼容路径(指向 install.sh),同时支持新的 Manifest 安装模式:

Terminal window
# 旧方式(仍可用)
bash install.sh --target claude --modules hooks-runtime
# 新方式(推荐)
ecc install --profile full

问题与规避

Manifest 路径指向不存在的文件

问题install-modules.json 中声明的路径在仓库中不存在(文件被删除但未更新 Manifest)。

ECC 的规避:CI 验证脚本 scripts/ci/validate-install-manifests.js 检查所有 Manifest 路径是否存在。

依赖循环

问题:模块 A 依赖 B,B 依赖 A,导致无限展开。

规避方案:Manifest 系统在安装计划阶段检测循环依赖并报错。

卸载时残留文件

问题:卸载模块后,生成的文件(如 learned skills)可能残留。

规避方案install-lifecycle.js 中的 uninstall 操作只移除 Manifest 跟踪的文件。本地生成的文件(learned/imported/evolved)不受影响,因为它们不在仓库 Manifest 中。


设计取舍

为什么用 JSON Manifest 而非 npm 依赖?

ECC 的选择安装系统超出了 npm 的依赖模型:

  • npm 的依赖是”安装这个包及其所有依赖”
  • ECC 需要的是”安装这个模块及其依赖,但只针对特定 Harness”
  • npm 无法表达条件展开和目标感知

JSON Manifest 的优势

  • 明确声明每个模块的路径
  • 支持 Profile → 模块的映射
  • 支持运行时依赖展开

代价:需要自己实现安装管道,而非直接使用 npm install

为什么保留遗留兼容?

install.sh 的旧路径仍然存在:

  • 原因:已有用户和文档使用旧路径,突然移除会破坏
  • 代价:需要维护两套安装模式
  • ECC 的选择:旧路径指向新管道,而非旧实现。install.sh 现在是薄 shell,内部调用新的安装管道

SQLite vs JSON 状态文件

安装状态使用 SQLite 存储:

  • 优势:查询能力、并发安全、Schema 约束
  • 代价:比 JSON 文件重
  • 为什么选 SQLite:安装/卸载/doctor 需要查询能力(“已安装了哪些模块”、“模块 X 安装了哪些文件”),JSON 文件不支持高效查询

参考来源

  • 源码验证: manifests/install-modules.json — 模块目录定义
  • 源码验证: manifests/install-profiles.json — Profile 定义
  • 源码验证: scripts/lib/install/ 目录 — 安装管道实现
  • 源码验证: scripts/ci/validate-install-manifests.js — CI 验证
  • 源码验证: scripts/install-apply.js, scripts/install-plan.js — CLI 入口