Doramagic 项目包 · 项目说明书

agent-add 项目

生成时间:2026-05-14 05:41:02 UTC

项目首页

agent-add 是一个跨平台的命令行工具,用于将 AI Agent 资产(MCP 服务器、Skills、Prompts、Commands、Sub-agents)安装到各种 AI 编程辅助工具中。该工具通过统一的接口屏蔽了不同宿主(Host)之间的差异,开发者只需一条命令即可将资产安装到指定的 AI 编程环境中。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 支持的资产类型

继续阅读本节完整说明和来源证据。

章节 支持的宿主环境

继续阅读本节完整说明和来源证据。

章节 整体架构

继续阅读本节完整说明和来源证据。

项目概述

agent-add 是一个跨平台的命令行工具,用于将 AI Agent 资产(MCP 服务器、Skills、Prompts、Commands、Sub-agents)安装到各种 AI 编程辅助工具中。该工具通过统一的接口屏蔽了不同宿主(Host)之间的差异,开发者只需一条命令即可将资产安装到指定的 AI 编程环境中。

资料来源:README.md

核心能力

支持的资产类型

资产类型说明安装方式
MCPModel Context Protocol 服务器配置JSON 配置合并
Skill可复用的 Agent 技能目录目录递归复制
Prompt规则文件 / 系统提示词追加写入或独立文件
Command斜杠命令定义独立文件安装
Sub-agent子代理配置YAML + Markdown 混合格式

资料来源:src/installer.ts

支持的宿主环境

agent-add 目前支持 18 种 AI 编程宿主:

宿主配置格式说明
cursorAGENTS.mdCursor IDE
claude-codeCLAUDE.mdAnthropic Claude Code
claude-desktopJSONClaude Desktop 应用
windsurf独立目录Windsurf AI IDE
github-copilot配置文件GitHub Copilot
gemini配置文件Google Gemini
roo-code独立目录Roo Code
kilo-code配置文件Kilo Code
qwen-code配置文件通义千问编码助手
opencode配置文件OpenCode
augment配置文件Augment Code
kiro配置文件Kiro AI
tabnine配置文件Tabnine
kimi配置文件Kimi 编程助手
trae配置文件Trae IDE
openclaw配置文件OpenClaw
codexTOMLOpenAI Codex
vibeTOMLVibe Coding 工具

资料来源:src/hosts/README.md

系统架构

整体架构

graph TD
    A[CLI 输入] --> B[显式标志能力检查]
    B --> C[资产描述符解析]
    C --> D[源解析器]
    D --> E[验证层]
    E --> F[安装处理器]
    F --> G[宿主适配器]
    G --> H[文件系统写入]
    
    D --> D1[MCP 处理器]
    D --> D2[Skill 处理器]
    D --> D3[Prompt 处理器]
    D --> D4[Command 处理器]
    D --> D5[Sub-agent 处理器]

核心模块

模块路径职责
CLIsrc/cli.ts命令行参数解析、TTY 检测、交互式宿主选择
安装器src/installer.ts编排核心:输入解析 → 能力检查 → 源解析 → 验证 → 处理器执行 → 汇总
宿主适配层src/hosts/18 种宿主适配器,实现 HostAdapter 接口
资产处理器src/assets/5 种资产类型处理器
源解析器src/source/本地路径、Git URL、HTTP 文件、内联内容的统一解析
清单解析器src/manifest/parser.tsPack Manifest JSON 格式验证与解析
工具函数helpers/utils.ts通用辅助函数

资料来源:README.md

安装流程

命令行用法

# 安装 MCP 服务器
npx -y agent-add --host cursor --mcp ./mcp/playwright.json

# 安装 Skill 目录
npx -y agent-add --host claude-code --skill ./skills/my-skill

# 安装 Prompt 规则文件
npx -y agent-add --host windsurf --prompt ./rules/code-review.md

# 从 Pack Manifest 批量安装
npx -y agent-add --host cursor --pack ./manifest.json

资料来源:README.md

数据流处理

flowchart LR
    subgraph 输入层
        A1[CLI 标志] --> A3[AssetDescriptor]
        A2[Pack Manifest] --> A3
    end
    
    subgraph 解析层
        A3 --> B1[ResolvedSource]
        B1 --> B2[安装作业队列]
    end
    
    subgraph 执行层
        B2 --> C1[MCP 处理器]
        B2 --> C2[Skill 处理器]
        B2 --> C3[Prompt 处理器]
        B2 --> C4[Command 处理器]
        B2 --> C5[Sub-agent 处理器]
    end
    
    subgraph 输出层
        C1 --> D1[InstallResult]
        C2 --> D1
        C3 --> D1
        C4 --> D1
        C5 --> D1
        D1 --> E[Summary 输出]
    end

状态与结果

状态说明
written资产已成功写入
exists资产已存在,无需更新
updated资产已更新
conflict存在冲突(手动解决)
skipped宿主不支持该资产类型
error安装过程中发生错误

资料来源:src/installer.ts

关键设计决策

原子化 JSON 写入

MCP 配置文件使用临时文件 + 重命名的原子写入策略,确保多进程并发写入时的数据一致性:

// 临时文件写入 → 原子重命名
const tempPath = `${configPath}.tmp.${Date.now()}`;
await fs.promises.writeFile(tempPath, JSON.stringify(merged, null, 2));
await fs.promises.rename(tempPath, configPath);

资料来源:README.md

标记块追加策略

Prompt 类型资产在追加模式下使用 HTML 注释标记实现幂等追加:

<!-- agent-add:code-review-rules -->
# Code Review Rules
...
<!-- /agent-add:code-review-rules -->

重复安装时,工具会自动识别并更新对应标记块内容,而非重复追加。

资料来源:README.md

内联源支持

源类型格式特征支持的资产
内联 JSON{ 开头MCP
内联 Markdown包含 \nPrompt / Command / Sub-agent
HTTP 文件URL 格式Skill 除外全部支持
本地路径相对/绝对路径全部支持

资料来源:src/source/infer-name.ts

非 TTY 严格模式

CI 环境必须显式指定 --host 参数,否则工具将退出并返回错误码 2:

// 非 TTY 环境未指定 host
if (!process.stdin.isTTY && !host) {
  process.stderr.write('agent-add error: --host flag required in non-TTY environment\n');
  process.exit(2);
}

资料来源:src/cli.ts

Pack Manifest 清单

格式规范

{
  "name": "namespace/pack-name",
  "assets": [
    { "type": "mcp",      "source": "https://github.com/...#path/to/config.json" },
    { "type": "skill",    "source": "./local/skills/pdf" },
    { "type": "prompt",   "source": "https://raw.githubusercontent.com/..." },
    { "type": "command",  "source": "[email protected]:...#tools/security.md" },
    { "type": "subAgent", "source": "...#categories/backend.md" }
  ]
}

字段规格

字段必填说明
name格式:namespace/pack-name,仅允许 [a-zA-Z0-9_-]
assets至少 1 个元素
assets[].typemcp \skill \prompt \command \subAgent
assets[].source资产来源(URL、路径、内联内容)

资料来源:src/manifest/parser.ts

项目技术栈

组件版本用途
TypeScript^5.9.3类型安全开发
Commander^14.0.3命令行参数解析
Vitest^4.1.0单元测试框架
Zod^4.3.6数据验证
smol-toml^1.6.1TOML 解析(Codex/Vibe)
YAML^2.8.2YAML 前端解析
tsup^8.5.1构建工具

资料来源:package.json

宿主适配器接口

interface HostAdapter {
  id: string;              // 唯一标识符
  name: string;             // 宿主名称
  assets: AssetCapability;  // 支持的资产类型映射
  mcpWriteStrategy: 'json' | 'toml';  // MCP 配置写入策略
}

interface AssetCapability {
  mcp?: { supported: boolean; reason?: string };
  skill?: { supported: boolean; reason?: string };
  prompt?: { supported: boolean; reason?: string };
  command?: { supported: boolean; reason?: string };
  subAgent?: { supported: boolean; reason?: string };
}

资料来源:src/hosts/types.ts

快速开始

开发环境搭建

# 克隆仓库
git clone https://github.com/pea3nut/agent-add.git
cd agent-add

# 安装依赖
npm install

# 构建项目
npm run build

# 安装开发资产(scenario-test 等)
npm run install:vibe

运行测试

命令说明
npm test运行所有单元测试和集成测试
npm run test:contract仅运行 CLI 黑盒契约测试
npx vitest run tests/unit/hosts/cursor.test.ts运行单个测试文件

资料来源:README.md

贡献指南

场景测试

场景测试使用 Gherkin .feature 文件定义,由 AI Agent 通过 scenario-test 执行:

/scenario-exec tests/features/core    # 核心资产行为测试
/scenario-exec tests/features/host    # 跨宿主兼容性测试

每个场景在隔离的临时目录中运行,运行配置定义于 tests/features/scenario-run-config.md

添加新宿主

  1. src/hosts/ 下创建 <id>.ts 实现 HostAdapter 接口
  2. src/hosts/README.md 中更新宿主能力矩阵
  3. tests/unit/hosts/ 下创建对应的单元测试
  4. src/hosts/index.ts 中注册新宿主
重要:adapter 实现必须与 README.md 中的字段值完全一致。

资料来源:[README.md](https://github.com/pea3nut/agent-add/blob/main/README.md)

安装与快速开始

agent-add 是一个跨宿主 AI Agent 工具包安装器 CLI 工具,能够将 MCP(Model Context Protocol)、Skill、Prompt、Command、Sub-agent 等资产安装到不同的 AI Agent 宿主环境中。使用一条命令即可完成资产的安装、配置和管理。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 方式一:npx 免安装(推荐)

继续阅读本节完整说明和来源证据。

章节 方式二:全局安装

继续阅读本节完整说明和来源证据。

章节 方式三:本地项目安装

继续阅读本节完整说明和来源证据。

概述

agent-add 是一个跨宿主 AI Agent 工具包安装器 CLI 工具,能够将 MCP(Model Context Protocol)、Skill、Prompt、Command、Sub-agent 等资产安装到不同的 AI Agent 宿主环境中。使用一条命令即可完成资产的安装、配置和管理。

当前支持的宿主环境包括:Cursor、Claude Code、Claude Desktop、Windsurf、GitHub Copilot、Gemini、Roo Code、Kilo Code、Qwen Code、OpenCode、Augment、Kiro、Tabnine、Kimi、Trae、OpenClaw、Codex(TOML)、Vibe(TOML)等 18 种主流 AI 编程工具。

资料来源:src/hosts/README.md:1

系统要求

要求说明
Node.js 版本>= 18
包管理器npm、yarn、pnpm 均可
网络需要访问 GitHub/GitLab 或相关资源 URL
TTY 环境CI 环境需显式指定 --host,否则退出错误码 2

资料来源:package.json:28

安装方式

方式一:npx 免安装(推荐)

最便捷的使用方式,无需预先安装,直接通过 npx 调用:

npx -y agent-add --host cursor --mcp <source>

npx -y 参数确保自动确认安装提示。

资料来源:README.md:1

方式二:全局安装

将工具安装到系统全局环境,随时可用:

npm install -g agent-add

安装完成后可直接调用:

agent-add --host claude-code --mcp <source>

方式三:本地项目安装

将工具作为项目开发依赖安装:

npm install --save-dev agent-add

package.json 中配置快捷脚本:

{
  "scripts": {
    "setup": "agent-add -- --pack vibe/manifest.json"
  }
}

资料来源:package.json:41

构建与开发

如果从源码克隆项目,需要先构建:

npm install
npm run build

构建完成后会生成单文件 CJS 捆绑包 dist/index.js

开发模式

支持热重载开发模式:

npm run dev            # tsup --watch 监听模式
npm run install:vibe   # 通过 pack manifest 安装开发资产

资料来源:README.md:7

基本使用流程

工作流程图

graph TD
    A[开始] --> B[指定宿主 --host]
    B --> C{资产来源类型}
    C -->|Git URL| D[解析 #path 提取资源]
    C -->|HTTP URL| E[下载远程文件]
    C -->|本地路径| F[访问本地文件/目录]
    C -->|内联内容| G[写入临时文件]
    D --> H[验证资产有效性]
    E --> H
    F --> H
    G --> H
    H --> I{资产类型}
    I -->|MCP| J[写入 JSON/TOML 配置]
    I -->|Skill| K[复制目录到 skills/]
    I -->|Prompt| L[追加或创建文件]
    I -->|Command| M[写入 commands/]
    I -->|Sub-agent| N[写入 subagents/]
    J --> O[完成安装]
    K --> O
    L --> O
    M --> O
    N --> O

核心参数说明

参数必填说明
--host <id>CI 环境必填目标宿主标识符,如 cursorclaude-code
--mcp <source>MCP 配置文件来源
--skill <source>Skill 技能包目录来源
--prompt <source>Prompt 规则文件来源
--command <source>Command 命令文件来源
--sub-agent <source>Sub-agent 子代理来源
--pack <source>Pack 清单文件(批量安装)
-V, --version显示版本号
-h, --help显示帮助信息

资料来源:src/cli.ts:1

宿主选择规则

环境行为
TTY 交互环境--host 时显示交互式选择菜单
CI/非 TTY 环境必须显式指定 --host,否则退出码 2

资料来源:src/cli.ts:1

资产安装示例

安装 MCP 服务器

# 从 GitHub 仓库安装
npx -y agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#.mcp.json'

# 从本地 JSON 文件安装
npx -y agent-add --host cursor --mcp './mcps/playwright.json'

# 内联 JSON 安装(MCP 专用)
npx -y agent-add --host cursor --mcp '{"playwright":{"command":"npx","args":["@playwright/mcp@latest"]}}'

资料来源:README.md:40

安装 Skill 技能包

# 从 GitHub 仓库安装
npx -y agent-add --host cursor --skill 'https://github.com/anthropics/skills.git#skills/webapp-testing'

# 从本地目录安装
npx -y agent-add --host cursor --skill './my-skill'
注意:Skill 必须指向目录来源,不支持内联内容或直接 HTTP URL。

资料来源:src/installer.ts:1

安装 Prompt 规则文件

# 内联 Markdown(适用于 Claude Code)
npx -y agent-add --host claude-code \
  --prompt $'# Code Review Rules\n\nAlways review for security issues first.'

# 从 HTTP URL 安装
npx -y agent-add --host cursor \
  --prompt 'https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs-react-tailwind/.cursorrules'

资料来源:README.md:50

安装 Command 命令

# 从 GitHub 仓库安装
npx -y agent-add --host cursor \
  --command 'https://github.com/wshobson/commands.git#tools/security-scan.md'

安装 Sub-agent 子代理

# 从 VoltAgent 仓库安装
npx -y agent-add --host cursor \
  --sub-agent 'https://github.com/VoltAgent/awesome-claude-code-subagents.git#categories/01-core-development/backend-developer.md'

批量安装(Pack 清单)

# 安装 Pack 清单中定义的所有资产
npx -y agent-add --host cursor --pack 'https://github.com/pea3nut/scenario-test.git'

Pack 清单格式示例:

{
  "name": "my-team/frontend-pack",
  "assets": [
    { "type": "mcp",      "source": "https://github.com/modelcontextprotocol/servers.git#.mcp.json" },
    { "type": "skill",    "source": "https://github.com/anthropics/skills.git#skills/pdf" },
    { "type": "prompt",   "source": "https://raw.githubusercontent.com/..." },
    { "type": "command",   "source": "https://github.com/...#tools/security-scan.md" },
    { "type": "subAgent",  "source": "https://github.com/...#categories/01-core-development/backend-developer.md" }
  ]
}

资料来源:README.md:70

资产名称推断规则

agent-add 根据来源自动推断资产名称:

来源类型推断规则示例
包含 #path使用 # 后的最后一段(去除扩展名)...git#skills/pdfpdf
Git URL 无 #使用仓库名称(去除 .git 后缀)...playwright.gitplaywright
本地路径/HTTP使用文件名(去除扩展名)./mcps/playwright.jsonplaywright
内联 JSON { 开头提取顶层 key 作为名称{"playwright":{...}}playwright
内联 Markdown 包含 \n提取第一个 # Heading 并转 kebab-case# Code Reviewcode-review

资料来源:src/source/infer-name.ts:1

输出状态说明

每次安装操作后会显示摘要,包含以下状态:

状态含义
written新资产已写入
exists资产已存在,无需更新
updated资产已更新
conflict存在冲突,需要手动处理
skipped宿主不支持该资产类型
error安装过程中发生错误

安装结果包含冲突或错误时,CLI 退出码为 1;其他情况退出码为 0。

资料来源:src/cli.ts:1

错误处理

错误类型退出码说明
宿主不支持该资产类型2显式指定了不支持的资产类型
资产来源无效2来源格式错误或无法解析
缺少必需文件2如 Skill 目录缺少 SKILL.md
CI 环境未指定宿主2非 TTY 环境必须 --host
冲突或错误1安装有冲突或错误

资料来源:src/installer.ts:1

常见问题

Q: 安装 MCP 时报错 "MCP 来源文件不存在"

确保 MCP 来源文件扩展名为 .json,且路径正确。agent-add 不支持其他格式的 MCP 配置。

Q: Skill 安装失败

检查 Skill 目录中是否包含 SKILL.md 文件,这是必需的标识文件。

Q: 提示宿主不支持某资产类型

查看 src/hosts/README.md 确认该宿主支持的功能列表,不同宿主支持的资产类型不同。

Q: CI 环境安装失败

确保在 CI 环境中显式指定 --host 参数,否则程序会退出并提示错误。

相关文档

资料来源:[src/hosts/README.md:1]()

核心功能使用指南

agent-add 是一款用于向 AI 编码助手安装资产的命令行工具,支持 18 种主流开发环境。该工具通过统一的 CLI 接口简化了 MCP 服务器、Skill、Prompt、Command 和 Sub-agent 五类资产的安装流程。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 数据流总览

继续阅读本节完整说明和来源证据。

章节 核心数据类型

继续阅读本节完整说明和来源证据。

章节 CLI 参数定义

继续阅读本节完整说明和来源证据。

概述

agent-add 是一款用于向 AI 编码助手安装资产的命令行工具,支持 18 种主流开发环境。该工具通过统一的 CLI 接口简化了 MCP 服务器、Skill、Prompt、Command 和 Sub-agent 五类资产的安装流程。

核心功能模块包括:命令行解析宿主检测来源解析资产验证安装执行结果汇总

资料来源:src/installer.ts:1-50

安装流程架构

数据流总览

graph TD
    A[CLI 参数解析] --> B[显式标志能力检查]
    B --> C[AssetDescriptor 数组]
    C --> D[来源解析]
    D --> E[ResolvedSource 数组]
    E --> F[资产验证]
    F --> G[InstallJob 数组]
    G --> H[安装执行]
    H --> I[InstallResult 数组]
    I --> J[结果汇总输出]
    
    K[--pack 清单文件] -.-> C
    L[--mcp/skill/prompt/command/sub-agent 标志] -.-> C

核心数据类型

类型名称用途关键字段
CliInputCLI 原始输入host, pack[], mcp[], skill[], prompt[], command[], subAgent[]
AssetDescriptor资产描述符assetType, source, fromExplicitFlag
ResolvedSource已解析来源type, originalSource, localPath, tempDir
InstallJob安装任务assetType, assetName, resolvedSource, host
InstallResult安装结果job, status, reason?

资料来源:src/installer.ts:20-45

命令行接口

CLI 参数定义

agent-add 采用 Commander.js 构建 CLI,定义了六类资产安装标志:

.option('--pack <source>', 'Install an Agent Pack manifest', collect, [])
.option('--mcp <source>', 'Install an MCP Server', collect, [])
.option('--skill <source>', 'Install a Skill', collect, [])
.option('--prompt <source>', 'Install a Prompt', collect, [])
.option('--command <source>', 'Install a Command', collect, [])
.option('--sub-agent <source>', 'Install a Sub-agent', collect, [])
.option('--host <host>', 'Target host ID', collect, [])

所有资产标志均支持重复使用(多次安装同类型资产)并可自由组合。

输入验证

const hasAssetFlags =
  cliInput.pack.length > 0 ||
  cliInput.mcp.length > 0 ||
  cliInput.skill.length > 0 ||
  cliInput.prompt.length > 0 ||
  cliInput.command.length > 0 ||
  cliInput.subAgent.length > 0;

if (!hasAssetFlags) {
  process.stderr.write(
    'agent-add error: No asset flags provided. Use --pack, --mcp, --skill, --prompt, --command, or --sub-agent.\n',
  );
  process.exit(2);
}

资料来源:src/cli.ts:1-30

宿主检测与选择

宿主注册表

宿主适配器通过注册表统一管理:

const hostRegistry = new Map<string, HostAdapter>([
  ['cursor', new CursorAdapter()],
  ['claude-code', new ClaudeCodeAdapter()],
  ['claude-desktop', new ClaudeDesktopAdapter()],
  // ... 共18种宿主
]);

宿主选择逻辑

场景行为
显式指定 --host直接使用指定宿主 ID
TTY 环境无 --host交互式选择宿主
非 TTY 环境无 --host输出错误并退出(exit 2)
if (cliInput.host) {
  hostId = cliInput.host;
} else if (!process.stdout.isTTY) {
  const validIds = getValidHostIds().join(', ');
  process.stderr.write(
    `agent-add error: Non-TTY environment requires explicit --host flag.\n`
  );
  process.exit(2);
}

资料来源:src/hosts/index.ts:1-25

宿主能力矩阵

每种宿主声明其支持的资产类型:

interface HostAdapter {
  id: string;
  displayName: string;
  docs: string;
  assets: {
    mcp: AssetCapability;
    skill: AssetCapability;
    prompt: AssetCapability;
    command: AssetCapability;
    subAgent: AssetCapability;
  };
}

interface AssetCapability {
  supported: boolean;
  configFile?: string;
  installDir?: string;
  writeStrategy?: 'append' | 'standalone';
  reason?: string;
}

资料来源:src/hosts/types.ts:1-20

来源解析系统

支持的来源类型

类型格式说明
local绝对/相对路径本地文件系统
gitGit URL + #pathGit 仓库文件/目录
http-fileHTTP(S) URL远程文件下载
inline-json{"name":{...}}内联 JSON(MCP 专用)
inline-md含换行符的 Markdown内联 Prompt/Command/Sub-agent

名称推断规则

来源字符串到资产名称的转换规则:

来源格式推断逻辑示例
内联 JSON提取顶层键名{"playwright":{...}}playwright
内联 Markdown首行 # 标题 转 kebab-case# Code Reviewcode-review
Git URL + #pathpath 最后段去扩展名...git#skills/pdfpdf
Git URL 无 #仓库名去 .git...playwright.gitplaywright
本地路径/HTTP文件名去扩展名./mcps/playwright.jsonplaywright
export function inferName(source: string): string {
  const s = source.trim();
  
  // 内联 JSON:提取顶层键
  if (s.startsWith('{')) {
    const parsed = JSON.parse(s);
    const unwrapped = unwrapMcpServers(obj);
    if (unwrapped) return unwrapped.name;
    // ...
  }
  
  // 内联 Markdown:提取 # 标题
  if (s.includes('\n')) {
    const match = s.match(/^#\s+(.+)/m);
    if (match) return kebabCase(match[1]);
  }
  
  // Git URL / 本地路径 / HTTP
  // ...
}

资料来源:src/source/infer-name.ts:1-40

来源解析流程

graph LR
    A[来源字符串] --> B{是否内联 JSON?}
    B -->|是| C[创建临时文件]
    B -->|否| D{包含换行符?}
    D -->|是| E[内联 Markdown]
    D -->|否| F{Git URL?}
    F -->|是| G[克隆到临时目录]
    F -->|否| H{HTTP URL?}
    H -->|是| I[下载到临时目录]
    H -->|否| J[使用本地路径]
    
    C --> K[返回 ResolvedSource]
    E --> K
    G --> K
    I --> K
    J --> K

资产验证

验证规则

资产类型验证项错误信息
skill目录内必须包含 SKILL.mdSkill 资产必须指向目录来源(本地路径或 Git URL),不支持内联内容或直接 HTTP(S) URL
skill不支持 http-file/inline-json/inline-md 来源Skill 目录内缺少 SKILL.md 文件
mcp文件必须存在且扩展名为 .jsonMCP 来源文件不存在 / MCP 来源文件扩展名必须为 .json
async function validateAsset(
  assetType: AssetType,
  resolved: ResolvedSource,
): Promise<string | null> {
  if (assetType === 'skill') {
    if (resolved.type === 'http-file' || resolved.type === 'inline-json' || resolved.type === 'inline-md') {
      return 'Skill 资产必须指向目录来源(本地路径或 Git URL),不支持内联内容或直接 HTTP(S) URL';
    }
    const skillMdPath = path.join(resolved.localPath, 'SKILL.md');
    try {
      await fs.promises.access(skillMdPath);
    } catch {
      return `Skill 目录内缺少 SKILL.md 文件(期望路径:${skillMdPath})`;
    }
    return null;
  }
  // ...
}

资料来源:src/installer.ts:60-80

安装执行

资产处理器注册

function getHandler(assetType: AssetType) {
  switch (assetType) {
    case 'mcp': return mcpHandler;
    case 'skill': return skillHandler;
    case 'prompt': return promptHandler;
    case 'command': return commandHandler;
    case 'subAgent': return subAgentHandler;
  }
}

安装结果状态

状态含义
written新资产写入成功
exists资产已存在,无变更
updated资产内容更新
conflict存在冲突需人工处理
skipped宿主不支持该资产类型
error安装过程出错

跳过逻辑

当宿主不支持某类资产时:

const capability = host.assets[item.assetType];
if (!capability.supported) {
  skippedResults.push({
    job: { ... },
    status: 'skipped',
    reason: capability.reason ?? `Host ${host.id} 不支持 ${item.assetType} 类型资产`,
  });
  continue;
}

资料来源:src/installer.ts:85-95

清单文件处理

清单格式

{
  "name": "namespace/pack-name",
  "assets": [
    { "type": "mcp", "source": "https://..." },
    { "type": "skill", "source": "..." }
  ]
}

清单解析流程

graph TD
    A[解析 --pack 清单] --> B[验证清单结构]
    B --> C[展平为 AssetDescriptor 数组]
    C --> D[合并到主输入]
    D --> E[继续标准安装流程]

字段规范

字段必填说明
name格式 namespace/pack-name,仅允许 [a-zA-Z0-9_-]
assets至少包含 1 项
assets[].typemcp \skill \prompt \command \subAgent
assets[].source资产来源字符串

资料来源:src/manifest/parser.ts:1-30

环境变量

变量名用途
AGENT_ADD_HOME覆盖 os.homedir() 返回值,用于将 Claude Desktop / Codex 宿主安装路径重定向到临时目录,实现测试隔离

资料来源:vibe/system-prompt.md:1-5

错误处理

退出码规范

退出码含义
0所有资产安装成功
1存在冲突(conflict)或错误(error)
2参数错误、验证失败、来源无效
const hasConflicts = summary.results.some((r) => r.status === 'conflict');
const hasErrors = summary.results.some((r) => r.status === 'error');

if (hasErrors || hasConflicts) {
  process.exit(1);
}

资料来源:src/cli.ts:35-45

使用示例

单资产安装

# 安装 MCP 服务器
npx -y agent-add --host cursor --mcp ./mcps/playwright.json

# 安装 Skill
npx -y agent-add --host claude-code --skill ./skills/webapp-testing

# 安装 Prompt
npx -y agent-add --host claude-code --prompt 'https://raw.githubusercontent.com/.../rules.md'

清单批量安装

npx -y agent-add --host cursor --pack ./manifests/frontend.json

组合使用

npx -y agent-add \
  --host claude-code \
  --mcp ./mcps/playwright.json \
  --skill ./skills/webapp-testing \
  --prompt '# Code Review Rules\n\nAlways review for security issues first.'

资料来源:[src/installer.ts:1-50]()

源格式与名称推断

agent-add 项目中的源格式与名称推断模块负责将用户提供的各种来源标识符解析为统一的内部表示,并自动推断资产名称。该模块是整个安装流程的入口处理层,位于 src/source/ 目录下。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 源类型分类

继续阅读本节完整说明和来源证据。

章节 类型识别流程

继续阅读本节完整说明和来源证据。

章节 推断规则优先级

继续阅读本节完整说明和来源证据。

概述

agent-add 项目中的源格式与名称推断模块负责将用户提供的各种来源标识符解析为统一的内部表示,并自动推断资产名称。该模块是整个安装流程的入口处理层,位于 src/source/ 目录下。

源解析系统的核心职责包括:

  • 识别源类型:根据源字符串的特征(前缀、URL格式、内联内容格式)判断其类型
  • 解析源内容:将源内容下载或读取到临时目录,供后续安装流程使用
  • 推断资产名称:根据源的特征自动生成符合规范的资产名称

资料来源:src/source/index.ts

源类型体系

agent-add 支持多种源格式,通过检测源字符串的特征自动识别其类型。

源类型分类

源类型识别规则特征支持的资产类型
inline-json{ 开头JSON 对象字面量仅 MCP
inline-md包含 \nMarkdown 内容Prompt/Command/Sub-agent
git-sshgit@ 开头SSH 协议格式所有类型
git-httpshttps://http:// 开头,且包含 .gitHTTPS 协议所有类型
http-filehttps://http:// 开头,且不包含 .gitHTTP 文件 URL除 Skill 外的所有类型
local其他情况本地文件路径所有类型

资料来源:src/source/index.ts

类型识别流程

graph TD
    A[输入源字符串] --> B{以 `{` 开头?}
    B -->|是| C{包含 `\n`?}
    B -->|否| D{以 `git@` 开头?}
    C -->|是| E[inline-md]
    C -->|否| F[inline-json]
    D -->|是| G[git-ssh]
    D -->|否| H{以 `http` 开头?}
    H -->|是| I{包含 `.git`?}
    I -->|是| J[git-https]
    I -->|否| K[http-file]
    H -->|否| L[local]
    
    style E fill:#90EE90
    style F fill:#87CEEB
    style G fill:#FFD700
    style J fill:#FFD700
    style K fill:#FFA500
    style L fill:#DDA0DD

名称推断规则

名称推断模块 infer-name.ts 负责从源字符串中提取或生成资产名称。不同源类型遵循不同的命名规则。

推断规则优先级

优先级条件命名规则示例
0内联 JSON提取单个顶层键{"playwright":{...}}playwright
0内联 Markdown提取首个 # Heading 并转 kebab-case# Code Reviewcode-review
1包含 #path使用 # 后的路径段(去掉扩展名)...git#skills/pdfpdf
2Git URL 无 #path提取仓库名(去掉 .git 后缀)...playwright.gitplaywright
3本地路径/HTTP 文件提取文件名(去掉扩展名)./mcps/playwright.jsonplaywright

资料来源:src/source/infer-name.ts

详细规则说明

#### 内联 JSON(inline-json)

当源以 { 开头时,系统将其解析为 JSON 对象。如果格式为 {"<name>":{...}},直接提取 <name> 作为资产名称。

// 有效的内联 JSON 格式
{"playwright":{"command":"npx","args":["@playwright/mcp@latest"]}}
// 推断名称: playwright

如果 JSON 包含 mcpServers 包装格式,系统会自动展开后提取名称:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}
// 推断名称: playwright

资料来源:src/source/infer-name.ts:14-35

#### 内联 Markdown(inline-md)

当源包含换行符 \n 时,系统将其识别为内联 Markdown。名称从首个 # Heading 提取,并转换为 kebab-case 格式:

# Code Review Rules
// 推断名称: code-review

限制:内联 Markdown 格式仅支持 Prompt、Command 和 Sub-agent 类型的资产,不支持 Skill 类型。资料来源:src/source/index.ts

#### Git URL 路径引用(#path)

Git 源支持 #path 语法指定仓库内的子路径。名称从 # 后的路径段提取,去掉文件扩展名:

https://github.com/anthropics/skills.git#skills/webapp-testing
// 推断名称: webapp-testing
https://github.com/modelcontextprotocol/servers.git#.mcp.json
// 推断名称: mcp.json → mcp

资料来源:src/source/infer-name.ts:36-40

#### Git URL 无路径引用

如果 Git URL 不包含 #path,系统从仓库 URL 中提取名称:

https://github.com/anthropics/skills.git
// 推断名称: skills
[email protected]:anthropics/claude-code-skills.git
// 推断名称: claude-code-skills

#### 本地路径和 HTTP 文件

对于本地文件路径或普通 HTTP 文件 URL,名称从文件名提取:

./mcps/playwright.json
// 推断名称: playwright
https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs/.cursorrules
// 推断名称: .cursorrules → cursorrules

源解析器实现

模块结构

graph LR
    A[src/source/index.ts] --> B[infer-name.ts]
    A --> C[git.ts]
    A --> D[http-file.ts]
    A --> E[local.ts]
    A --> F[inline.ts]
    
    C --> G[解析 Git 仓库]
    D --> H[下载 HTTP 文件]
    E --> I[读取本地文件]
    F --> J[写入临时文件]

Git 解析器

git.ts 负责处理 Git 仓库源的解析,支持稀疏检出(sparse checkout)功能。

核心功能

  • 支持 git@ SSH 格式和 https:// HTTP 格式
  • 支持 #path 语法指定子目录或文件
  • 使用 git init + git remote add + git fetch + git checkout 实现稀疏检出

资料来源:src/source/git.ts

HTTP 文件解析器

http-file.ts 负责从 HTTP/HTTPS URL 下载单个文件。

限制

  • 仅支持 Prompt、Command、Sub-agent 和 MCP 类型的资产
  • 不支持 Skill 类型资产(HTTP 源安装 Skill 会导致错误,退出码 2)

资料来源:src/source/index.tssrc/source/http-file.ts

本地路径解析器

local.ts 负责读取本地文件系统中的源文件或目录。

功能

  • 支持单个文件路径
  • 支持目录路径(会递归处理目录内容)
  • 对于目录源,系统会遍历目录并将每个文件作为独立资产处理

资料来源:src/source/local.ts

内联内容解析器

inline.ts 负责将内联内容写入临时文件,供后续处理流程使用。

处理流程

  1. 根据内容类型(JSON 或 Markdown)确定文件扩展名
  2. 在系统临时目录中创建唯一命名的临时文件
  3. 将内容写入临时文件
  4. 返回临时文件路径,供后续处理使用

资料来源:src/source/inline.ts

错误处理

内联 JSON 解析错误

// 如果 JSON 格式错误
内联 JSON 解析失败。格式应为 {"<name>":{...}},例如:{"playwright":{"command":"npx","args":["-y","@playwright/mcp"]}}

内联类型不匹配

// HTTP 源安装 Skill 时
agent-add error: HTTP sources cannot install Skill assets
// 内联源安装 Skill 时
agent-add error: Inline sources cannot install Skill assets

名称推断失败

当无法从源字符串推断有效名称时,系统会报错并退出。

与其他模块的交互

源解析模块位于 agent-add 安装流程的前端,解析结果传递给后续模块:

graph TD
    A[CLI 入口] --> B[源格式识别]
    B --> C{识别源类型}
    C --> D[名称推断]
    D --> E[解析源内容]
    E --> F[验证资产]
    F --> G[构建安装任务]
    G --> H[执行安装]
    
    D --> D1[infer-name.ts]
    E --> E1[git.ts / http-file.ts / local.ts / inline.ts]

资料来源:src/installer.ts

最佳实践

源格式选择建议

场景推荐格式示例
MCP 服务器配置内联 JSON{"playwright":{"command":"npx","args":["@playwright/mcp"]}}
简单 Prompt内联 Markdown--prompt $'# Review Rules\n\nCheck for bugs...'
复杂/可复用的资产Git URLhttps://github.com/org/skills.git#skills/pdf
本地开发测试本地路径./my-skill/
团队共享资源HTTP URLhttps://team.com/rules/code-review.md

名称规范

  • 资产名称只能包含 [a-zA-Z0-9_-] 字符
  • MCP 类型:名称从配置文件键名推断
  • 其他类型:使用 kebab-case 格式

资料来源:[src/source/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/index.ts)

系统架构总览

agent-add 是一个跨主机(Host)的 AI 代理资产安装工具,用于将 MCP Servers、Skills、Prompts、Commands、Sub-agents 等资产统一安装到不同的 AI 编程工具中。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 4.1 数据模型

继续阅读本节完整说明和来源证据。

章节 4.2 源类型(Source Types)

继续阅读本节完整说明和来源证据。

章节 5.1 CLI 层(src/cli.ts)

继续阅读本节完整说明和来源证据。

1. 项目概述

agent-add 是一个跨主机(Host)的 AI 代理资产安装工具,用于将 MCP Servers、Skills、Prompts、Commands、Sub-agents 等资产统一安装到不同的 AI 编程工具中。

项目核心目标是解决 AI 代理生态碎片化问题——每种 AI 工具(如 Cursor、Claude Code、Windsurf 等)都有自己独立的资产配置格式和存储路径,agent-add 通过抽象适配层实现了一次定义,多端安装的能力。

2. 系统架构图

graph TD
    subgraph CLI层
        A[CLI 入口] --> B[Commander 解析]
        B --> C[TTY 检测]
        C --> D{非 TTY 环境?}
        D -->|是| E[强制要求 --host 参数]
        D -->|否| F[交互式选择 Host]
    end

    subgraph 核心处理层
        G[CLI Input] --> H[显式标志能力检查]
        H --> I[Source 解析]
        I --> J[资产验证]
        J --> K[构建 InstallJob]
        K --> L[分发到对应 Handler]
    end

    subgraph 资产处理层
        L --> M[MCP Handler]
        L --> N[Skill Handler]
        L --> O[Prompt Handler]
        L --> P[Command Handler]
        L --> Q[Sub-agent Handler]
    end

    subgraph Host 适配层
        M --> R[Cursor Adapter]
        M --> S[Claude Code Adapter]
        M --> T[Codex Adapter]
        M --> U[Vibe Adapter]
        N --> R
        O --> R
        O --> S
    end

    R --> V[结果汇总]
    S --> V
    T --> V
    U --> V
    V --> W[Summary 输出]

3. 目录结构

agent-add/
├── src/
│   ├── index.ts              # 程序入口,创建 Commander 实例
│   ├── cli.ts                # CLI 参数定义与解析
│   ├── installer.ts          # 核心编排逻辑
│   ├── hosts/                # 主机适配层
│   │   ├── types.ts          # HostAdapter 接口定义
│   │   ├── index.ts          # 主机注册表
│   │   ├── README.md         # 能力矩阵(唯一信源)
│   │   ├── cursor.ts
│   │   ├── claude-code.ts
│   │   ├── vibe.ts           # TOML 格式支持
│   │   └── ...               # 其他 15 种主机适配器
│   ├── assets/               # 资产处理器
│   │   ├── mcp.ts           # MCP 配置安装
│   │   ├── skill.ts         # Skill 目录安装
│   │   ├── prompt.ts        # Prompt 文件安装
│   │   ├── command.ts       # Command 文件安装
│   │   └── sub-agent.ts     # Sub-agent 文件安装
│   ├── source/              # 源解析模块
│   │   ├── resolve.ts       # 源解析器
│   │   └── infer-name.ts   # 资产名称推断
│   ├── utils/               # 工具函数
│   │   └── unwrap-mcp-servers.js  # MCP 配置解包
│   └── summary.ts           # 结果格式化输出
├── tests/
│   ├── unit/                # 单元测试
│   └── features/            # Gherkin 场景测试
└── bin/
    └── agent-add.js         # 编译后的可执行文件

4. 核心数据流

graph LR
    A[CLI Flags / --pack Manifest] --> B[AssetDescriptor]
    B --> C[ResolvedSource]
    C --> D[InstallJob]
    D --> E[InstallResult]
    E --> F[Summary]
    
    A1[显式标志能力检查] -.->|exit 2| A
    C1[验证失败] -.->|exit 2| C
    D1[不支持的资产] -.->|skip| D

4.1 数据模型

模型描述字段
CliInputCLI 参数输入pack, mcp, skill, prompt, command, subAgent, host
AssetDescriptor资产描述符assetType, source, fromExplicitFlag
ResolvedSource解析后的源type, localPath, tempDir, originalSource
InstallJob安装任务assetType, assetName, resolvedSource, host
InstallResult安装结果job, status, reason

4.2 源类型(Source Types)

类型描述格式示例
local本地文件系统路径./mcps/playwright.json
gitGit 仓库 URLhttps://github.com/...#path/to/asset
http-fileHTTP/HTTPS 直接下载https://example.com/config.json
inline-json内联 JSON(MCP 专用){"name":{"command":"npx","args":[...]}}
inline-md内联 Markdown(Prompt/Command/Sub-agent 专用)# Title\n\nContent...

5. 模块详解

5.1 CLI 层(src/cli.ts)

CLI 层负责用户交互和参数验证:

// 核心参数定义(资料来源:src/cli.ts)
.option('--pack <source>', 'Install an Agent Pack manifest')
.option('--mcp <source>', 'Install an MCP Server')
.option('--skill <source>', 'Install a Skill directory')
.option('--prompt <source>', 'Install a Prompt file')
.option('--command <source>', 'Install a Command')
.option('--sub-agent <source>', 'Install a Sub-agent')
.option('--host <host>', 'Target host ID')

TTY 检测逻辑

  • TTY 环境:用户可交互选择 Host
  • 非 TTY 环境(CI):必须显式指定 --host,否则退出并报错

5.2 安装编排器(src/installer.ts)

编排器是系统的核心,负责串联整个安装流程:

阶段函数职责
1解析输入CliInput 转换为 AssetDescriptor[]
2源解析将源字符串解析为 ResolvedSource[]
3验证检查资产有效性(文件存在、格式正确)
4作业构建根据 Host 能力过滤,生成 InstallJob[]
5处理器分发调用对应的 AssetHandler
6结果汇总聚合所有安装结果并输出

5.3 主机适配层(src/hosts/)

classDiagram
    class HostAdapter {
        <<interface>>
        +id: string
        +displayName: string
        +docs: string
        +assets: Record~AssetType, AssetCapability~
    }
    
    class AssetCapability {
        +supported: boolean
        +writeStrategy: WriteStrategy
        +installDir?: string
        +configFile?: string
        +reason?: string
    }
    
    HostAdapter o-- AssetCapability
    
    CursorAdapter ..|> HostAdapter
    ClaudeCodeAdapter ..|> HostAdapter
    VibeAdapter ..|> HostAdapter

当前支持的 18 种主机

主机 ID配置文件格式资产类型支持
cursorJSONMCP, Prompt, Command, Sub-agent
claude-codeJSONMCP, Prompt, Command, Sub-agent
claude-desktopJSONMCP only
windsurfJSONMCP, Prompt, Command
roo-codeJSONMCP, Prompt, Command
codexTOMLMCP, Prompt
vibeTOMLMCP, Prompt
kimiJSONMCP, Prompt
traeJSONMCP, Prompt
openclawJSONMCP, Prompt
geminiJSONMCP, Prompt
github-copilotJSONMCP, Prompt
kilo-codeJSONMCP, Prompt
qwen-codeJSONMCP, Prompt
opencodeJSONMCP, Prompt
augmentJSONMCP, Prompt
kiroJSONMCP, Prompt
tabnineJSONMCP, Prompt

5.4 资产处理器层(src/assets/)

每种资产类型都有独立的处理器,统一实现 AssetHandler 接口:

flowchart LR
    subgraph AssetHandlers
        A[MCP Handler] -->|JSON shallow merge| A1[atomic write]
        B[Skill Handler] -->|directory copy| B1[SKILL.md validation]
        C[Prompt Handler] -->|marker append| C1[HTML 标记追加]
        D[Command Handler] -->|file write| D1[frontmatter parse]
        E[Sub-agent Handler] -->|host specialization| E1[agent-add/* 提升]
    end
处理器写入策略关键特性
mcp.ts原子写入JSON 浅合并、.toml 自动识别
skill.ts目录复制递归复制、SKILL.md 存在性验证
prompt.ts追加或独立文件HTML 标记块(幂等追加)
command.ts文件写入YAML frontmatter 解析
sub-agent.ts文件写入agent-add/<host>/* 主机专用字段提升

6. 关键设计决策

6.1 原子 JSON 写入

MCP 配置文件使用临时文件 + 重命名的原子操作保证写入安全:

写入流程:config.json → .config.json.tmp → atomic rename → config.json

6.2 幂等追加策略

Prompt 资产使用 HTML 注释标记实现幂等追加:

<!-- agent-add:code-review-rules -->
# Code Review Rules
...
<!-- /agent-add:code-review-rules -->

6.3 TOML 格式自动识别

mcp.ts 检测文件扩展名,.toml 文件自动路由到 TOML 处理路径:

扩展名解析方式
.json标准 JSON 解析
.tomlsmol-toml 库解析

6.4 显式标志能力拒绝

installer.ts 在构建作业前检查主机的显式标志能力声明:

  • supported: false → 输出错误信息 + README 链接,退出码 2
  • --pack 源跳过此检查

7. 错误处理

错误场景退出码处理方式
非 TTY 环境未指定 --host2stderr 输出有效 Host 列表
无效的资产标志2stderr 提示有效选项
源解析失败2stderr 输出详细错误
资产验证失败2stderr 输出验证原因
安装冲突1列出冲突项
安装错误1列出错误详情

8. 扩展指南

8.1 添加新主机

  1. 创建 src/hosts/<id>.ts,实现 HostAdapter 接口
  2. src/hosts/index.ts 注册
  3. 更新 src/hosts/README.md 能力矩阵
  4. 创建 tests/unit/hosts/<id>.test.ts 单元测试

8.2 添加新资产类型

  1. src/assets/ 创建新处理器
  2. 实现 AssetHandler 接口
  3. src/installer.ts 添加分发逻辑

9. 相关文档

来源:https://github.com/pea3nut/agent-add / 项目说明书

Source 模块详解

Source 模块是 agent-add 项目的核心组件之一,负责将用户提供的资产来源(source)解析为可操作的本地文件路径。该模块支持多种来源类型,包括本地路径、Git 仓库、HTTP URL 以及内联内容,并为每种类型实现了专门的解析逻辑。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 目录结构

继续阅读本节完整说明和来源证据。

章节 核心接口

继续阅读本节完整说明和来源证据。

章节 1. 本地路径解析

继续阅读本节完整说明和来源证据。

模块概述

Source 模块是 agent-add 项目的核心组件之一,负责将用户提供的资产来源(source)解析为可操作的本地文件路径。该模块支持多种来源类型,包括本地路径、Git 仓库、HTTP URL 以及内联内容,并为每种类型实现了专门的解析逻辑。

Source 模块在整个安装流程中的位置至关重要:

CLI 输入(--mcp/--skill/--prompt/--command/--sub-agent/--pack)
    ↓
[Source 模块] ← 资产来源解析
    ↓
ResolvedSource[](包含 localPath 和 tempDir)
    ↓
验证与安装

资料来源:src/installer.ts

支持的来源类型

根据源码分析,Source 模块支持以下六种来源类型:

类型标识描述
本地路径local本地文件系统路径
Git SSHgit-sshgit@ 开头的 SSH 地址
Git HTTPSgit-httpshttps://http:// 开头的 Git 地址
HTTP 文件http-file直接的 HTTP/HTTPS 文件 URL
内联 JSONinline-json{ 开头的内联 JSON 字符串(仅限 MCP)
内联 Markdowninline-md包含换行符的内联 Markdown(Prompt/Command/Sub-agent)

资料来源:vibe/system-prompt.md

模块架构

目录结构

src/source/
├── index.ts              # 统一入口,类型检测与路由分发
├── local.ts              # 本地路径解析
├── git.ts                # Git 仓库解析(支持稀疏检出)
├── http-file.ts          # HTTP URL 下载解析
├── inline.ts             # 内联内容转临时文件
└── expand-directory.ts   # 目录展开(支持 glob 模式)

核心接口

Source 模块的核心接口返回 ResolvedSource 数据结构:

interface ResolvedSource {
  type: SourceType;           // 来源类型标识
  localPath: string;          // 本地文件路径
  tempDir?: string;           // 临时目录路径(内联内容专用)
  originalSource: string;     // 原始输入字符串
}

资料来源:src/source/index.ts

来源类型解析详解

1. 本地路径解析

本地路径解析器(local.ts)处理相对路径和绝对路径的本地文件系统引用。

工作流程:

graph TD
    A[输入 source] --> B{是否为绝对路径?}
    B -->|是| C[直接返回绝对路径]
    B -->|否| D[相对于 cwd 解析]
    D --> E{路径存在?}
    E -->|是| F[返回解析后路径]
    E -->|否| G[抛出错误: 文件不存在]

关键约束:

  • 路径必须存在且可访问
  • Skill 类型资产的本地路径必须包含 SKILL.md 文件

资料来源:src/source/local.ts

2. Git 仓库解析

Git 解析器(git.ts)支持从 Git 仓库获取资产,支持稀疏检出(sparse checkout)语法。

Git URL 格式支持:

格式示例解析结果
SSH 格式[email protected]:user/repo.git仓库名 repo
HTTPS 格式https://github.com/user/repo.git仓库名 repo
带路径引用...git#path/to/asset使用路径最后段作为名称

稀疏检出功能:

使用 # 语法可以只检出仓库中的特定路径:

# 检出仓库中的 skills/pdf 目录
npx -y agent-add --skill 'https://github.com/anthropics/skills.git#skills/pdf'

Git 解析器会自动执行稀疏检出,只下载指定路径的内容。

资料来源:src/source/git.ts

3. HTTP 文件解析

HTTP 解析器(http-file.ts)从远程 URL 下载文件内容。

使用限制:

⚠️ 重要约束:HTTP 来源类型不支持 Skill 资产类型。尝试使用 HTTP URL 安装 Skill 会导致安装失败并返回错误码 2。
graph TD
    A[HTTP URL] --> B{资产类型?}
    B -->|skill| C[返回错误: 不支持]
    B -->|其他类型| D[下载到临时文件]
    D --> E[返回 tempDir 路径]

资料来源:src/source/http-file.ts 资料来源:vibe/system-prompt.md

4. 内联内容解析

内联解析器(inline.ts)将命令行中直接传入的内容写入临时文件。

两种内联格式:

格式识别特征适用资产
内联 JSON字符串以 { 开头MCP
内联 Markdown字符串包含 \n 且无 JSON 特征Prompt/Command/Sub-agent

内联 JSON 示例:

npx -y agent-add --mcp '{"playwright":{"command":"npx","args":["@playwright/mcp"]}}'

解析后生成临时文件,资产名称从 JSON 对象的顶级键提取。

内联 Markdown 示例:

npx -y agent-add --prompt $'# Code Review\n\nAlways review for security issues first.'

解析后生成临时文件,资产名称从第一个 # 标题 提取并转换为 kebab-case。

资料来源:src/source/inline.ts

5. 目录展开

expand-directory.ts 提供了目录批量展开功能,支持 glob 模式匹配。

典型应用场景:

当用户提供的 source 是包含多个资产的目录时,该模块负责:

  1. 扫描目录下的所有匹配文件
  2. 为每个匹配项生成独立的 ResolvedSource
  3. 保持目录结构在资产名称中(如 dirName/assetName

资料来源:src/source/expand-directory.ts

资产名称推断

infer-name.ts 模块负责从来源字符串推断资产名称,这是确保正确安装的关键步骤。

推断规则优先级

优先级来源类型推断规则
0内联 JSON提取单个顶级键作为名称
0内联 Markdown提取第一个 # 标题 并转为 kebab-case
1# 路径使用路径最后段(去除扩展名)
2Git URL使用仓库名(去除 .git 后缀)
3本地路径/HTTP使用文件名(去除扩展名)

名称转换示例

原始来源推断名称
...git#skills/pdfpdf
...playwright.gitplaywright
./mcps/playwright.jsonplaywright
# Code Reviewcode-review

资料来源:src/source/infer-name.ts

类型验证流程

验证时机

在 Source 模块解析完成后,installer.ts 会对每个 ResolvedSource 进行资产特定的验证:

sequenceDiagram
    participant CLI as CLI 输入
    participant Source as Source 模块
    participant Validator as 验证器
    participant Installer as 安装器

    CLI->>Source: 传入 source 字符串
    Source->>Source: 解析为 ResolvedSource
    Source->>Validator: 调用 validateAsset()
    Validator->>Validator: 根据资产类型验证
    alt 验证通过
        Validator-->>Installer: 返回 null
    else 验证失败
        Validator-->>Installer: 返回错误消息
        Installer->>Installer: 输出错误并 exit(2)
    end

各资产类型的验证规则

资产类型必需验证失败条件
skillSKILL.md 存在目录内缺少 SKILL.md
mcp文件存在 + 扩展名文件不存在或非 .json 扩展名
prompt无特殊验证
command无特殊验证
subAgent无特殊验证

Skill 类型的额外限制:

if (assetType === 'skill') {
  if (resolved.type === 'http-file' || 
      resolved.type === 'inline-json' || 
      resolved.type === 'inline-md') {
    return 'Skill 资产必须指向目录来源(本地路径或 Git URL),不支持内联内容或直接 HTTP(S) URL';
  }
  // 验证 SKILL.md 存在
}

资料来源:src/installer.ts

错误处理

Source 模块的错误处理遵循统一的退出码规范:

退出码含义触发场景
0成功所有资产安装成功
1部分成功存在冲突或错误但可继续
2严重错误参数错误、验证失败、不支持的配置

常见错误消息:

  • MCP 来源文件不存在:<path> — MCP 文件路径无效
  • MCP 来源文件扩展名必须为 .json — 文件类型错误
  • Skill 目录内缺少 SKILL.md 文件 — Skill 目录结构不完整
  • 内联 JSON 解析失败 — JSON 格式错误

与其他模块的集成

数据流图

graph LR
    subgraph Source模块
        A[local.ts] --> D[index.ts]
        B[git.ts] --> D
        C[http-file.ts] --> D
        E[inline.ts] --> D
        F[expand-directory.ts] --> D
    end

    subgraph Installer模块
        D --> G[validateAsset]
        G --> H[创建 InstallJob]
    end

    subgraph 资产处理器
        H --> I[mcp.ts]
        H --> J[skill.ts]
        H --> K[prompt.ts]
    end

关键集成点

  1. CLI 层 (src/cli.ts):接收用户输入,调用 runInstaller()
  2. 安装编排层 (src/installer.ts):协调 Source 解析、验证、安装
  3. 资产处理层 (src/assets/*.ts):消费 Source 模块的解析结果

总结

Source 模块是 agent-add 架构中负责来源抽象的关键层,它:

  • 提供了六种统一的来源类型抽象
  • 实现了健壮的错误处理和验证机制
  • 支持复杂的 Git 稀疏检出场景
  • 为内联内容提供了透明的临时文件机制

理解 Source 模块的工作原理对于调试安装问题、扩展支持新的来源类型,以及深入理解整个 agent-add 系统都至关重要。

资料来源:[src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)

Host 适配器系统

Host 适配器系统是 agent-add 的核心抽象层,负责将安装逻辑与具体的 AI 编程工具(Host)解耦。该系统定义了每种 Host 支持的资产类型、安装路径、写入策略等配置,使 agent-add 能够以统一的方式向不同 Host 安装 MCP Servers、Skills、Prompts、Commands 和 Sub-agents。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 核心组件

继续阅读本节完整说明和来源证据。

章节 目录结构

继续阅读本节完整说明和来源证据。

章节 HostAdapter 接口

继续阅读本节完整说明和来源证据。

概述

Host 适配器系统是 agent-add 的核心抽象层,负责将安装逻辑与具体的 AI 编程工具(Host)解耦。该系统定义了每种 Host 支持的资产类型、安装路径、写入策略等配置,使 agent-add 能够以统一的方式向不同 Host 安装 MCP Servers、Skills、Prompts、Commands 和 Sub-agents。

系统当前支持 18 种主流 AI 编程工具,包括 Cursor、Claude Code、Windsurf、GitHub Copilot 等,形成了完整的主机适配矩阵。

架构设计

核心组件

graph TD
    A[CLI 输入] --> B[installer.ts]
    B --> C[Host 注册表]
    C --> D{Host 检测?}
    D -->|是| E[detect-hosts.ts]
    D -->|否| F[使用 --host 参数]
    E --> G[返回 HostAdapter]
    F --> G
    G --> H[资产处理器]
    H --> I[MCP 处理器]
    H --> J[Skill 处理器]
    H --> K[Prompt 处理器]
    H --> L[Command 处理器]
    H --> M[Sub-agent 处理器]

目录结构

src/
├── hosts/                    # Host 适配器系统核心
│   ├── index.ts              # Host 注册表(Map<id, HostAdapter>)
│   ├── types.ts              # 核心类型定义
│   ├── README.md             # 主机能力矩阵(单一信息源)
│   ├── cursor.ts             # Cursor 适配器
│   ├── claude-code.ts        # Claude Code 适配器
│   ├── windsurf.ts           # Windsurf 适配器
│   ├── codex.ts              # Codex CLI 适配器
│   └── <id>.ts               # 其他主机适配器
└── utils/
    └── detect-hosts.ts       # 自动检测当前环境中的 Host

核心类型定义

HostAdapter 接口

src/hosts/types.ts 定义了 HostAdapter 接口,所有主机适配器必须实现此接口:

interface HostAdapter {
  readonly id: string;                    // 主机唯一标识符
  readonly displayName: string;            // 显示名称
  readonly docs: string;                  // 官方文档链接
  readonly detection: HostDetection;      // 检测配置
  readonly assets: Record<AssetType, AssetCapability>;  // 资产能力配置
}

资产能力配置

interface AssetCapability {
  supported: boolean;
  reason?: string;                    // 不支持时说明原因
  configFile?: ConfigFilePaths;       // 配置文件路径(支持多平台)
  configKey?: string;                 // 配置键名
  writeStrategy?: WriteStrategy;      // 写入策略
  targetFile?: string;                // 目标文件名
  installDir?: string;                // 安装目录
  entryFile?: string;                 // 入口文件
  fileExtension?: string;             // 文件扩展名
}

资产类型枚举

类型说明用途
mcpMCP Server 配置安装 MCP 服务器
skillSkill 目录安装可复用技能包
prompt规则/系统提示安装提示词规则
command斜杠命令安装自定义命令
subAgent子代理配置安装子代理

写入策略

策略说明适用场景
inject-json-key向 JSON 配置注入键值MCP JSON 配置
toml-array向 TOML 数组追加Codex/Vibe MCP TOML
append-with-marker使用 HTML 注释标记追加Cursor AGENTS.md 等
create-file-in-dir在目录中创建文件Windsurf 规则文件
copy-file复制文件到目标目录Skill、Command 等

Host 注册表

src/hosts/index.ts 维护着一个 Map<id, HostAdapter> 类型的注册表,所有适配器在此注册后即可被系统识别和使用。

graph LR
    A[主机适配器文件] --> B[index.ts 注册]
    B --> C[hostRegistry Map]
    C --> D[installer.ts 查询]
    C --> E[detect-hosts.ts 检测]

注册表示例结构:

const hostRegistry = new Map<string, HostAdapter>([
  ['cursor', new CursorAdapter()],
  ['claude-code', new ClaudeCodeAdapter()],
  ['windsurf', new WindsurfAdapter()],
  ['codex', new CodexAdapter()],
  // ... 其他适配器
]);

支持的主机列表

根据 src/hosts/README.md 中的能力矩阵,当前支持以下 18 种主机:

主机 ID显示名称MCPPromptSkillCommandSub-agent
cursorCursor
claude-codeClaude Code
claude-desktopClaude Desktop
windsurfWindsurf
github-copilotGitHub Copilot
geminiGemini Code
roo-codeRoo Code
kilo-codeKilo Code
qwen-codeQwen Code
opencodeOpenCode
augmentAugment Code
kiroKiro
tabnineTabnine
kimiKimi
traeTrae
openclawOpenClaw
codexCodex CLI
vibeVibe

主机检测机制

src/utils/detect-hosts.ts 实现了自动检测当前环境中已安装的 Host 功能。检测逻辑基于各主机的特征路径:

// 检测配置示例
const detection = {
  paths: ['~/.cursor/', '.cursor/']  // Cursor 检测路径
};

检测优先级

  1. 显式指定优先:用户通过 --host <id> 参数显式指定主机
  2. 自动检测次之:非 TTY 环境下(如 CI)必须显式指定,否则退出
  3. 交互选择兜底:TTY 环境下提供交互式主机选择菜单

适配器实现示例

Cursor 适配器 (`src/hosts/cursor.ts`)

export class CursorAdapter implements HostAdapter {
  readonly id = 'cursor';
  readonly displayName = 'Cursor';
  readonly docs = 'https://cursor.com';
  readonly detection = {
    paths: ['~/.cursor/', '.cursor/'],
  };
  readonly assets: Record<AssetType, AssetCapability> = {
    mcp: {
      supported: true,
      configFile: {
        darwin: '~/Library/Application Support/Cursor/User/globalStorage/sao-team.mcp-server-cli/hosts.json',
        linux: '~/.cursor/globalStorage/sao-team.mcp-server-cli/hosts.json',
        win32: '%APPDATA%\\Cursor\\User\\globalStorage\\sao-team.mcp-server-cli\\hosts.json',
      },
      writeStrategy: 'inject-json-key',
    },
    prompt: {
      supported: true,
      targetFile: 'AGENTS.md',
      writeStrategy: 'append-with-marker',
    },
    skill: {
      supported: true,
      installDir: '.cursor/skills/',
      entryFile: 'SKILL.md',
      writeStrategy: 'copy-file',
    },
    command: {
      supported: true,
      installDir: '.cursor/commands/',
      writeStrategy: 'copy-file',
    },
    subAgent: {
      supported: true,
      installDir: '.cursor/agents/',
      writeStrategy: 'copy-file',
    },
  };
}

Codex 适配器 (`src/hosts/codex.ts`)

Codex 适配器展示了 TOML 配置的特殊处理:

export class CodexAdapter implements HostAdapter {
  readonly id = 'codex';
  readonly displayName = 'Codex CLI';
  readonly docs = 'https://github.com/openai/codex';
  readonly assets: Record<AssetType, AssetCapability> = {
    mcp: {
      supported: true,
      configFile: {
        darwin: '~/.codex/config.toml',
        linux: '~/.codex/config.toml',
        win32: '%USERPROFILE%\\.codex\\config.toml',
      },
      configKey: 'mcp_servers',
      writeStrategy: 'inject-json-key',
    },
    subAgent: {
      supported: true,
      installDir: '.codex/agents/',
      fileExtension: '.toml',
      writeStrategy: 'copy-file',
    },
  };
}

新增主机适配器指南

根据 src/hosts/README.md 的贡献指南,新增主机需要完成以下步骤:

步骤 1:创建适配器文件

src/hosts/<id>.ts 中创建适配器类,实现 HostAdapter 接口:

import type { HostAdapter, AssetCapability, AssetType } from './types.js';

const NOT_SUPPORTED = (reason: string): AssetCapability => ({
  supported: false,
  reason,
});

export class XxxAdapter implements HostAdapter {
  readonly id = 'xxx';
  readonly displayName = 'Xxx';
  readonly docs = 'https://xxx.com/docs';
  readonly detection = {
    paths: ['~/.xxx/'],
  };
  readonly assets: Record<AssetType, AssetCapability> = {
    mcp: { /* 配置 */ },
    prompt: { /* 配置 */ },
    skill: { /* 配置 */ },
    command: { /* 配置 */ },
    subAgent: { /* 配置 */ },
  };
}

步骤 2:注册到索引

src/hosts/index.tshostRegistry Map 中添加新条目:

['xxx', new XxxAdapter()]

步骤 3:更新能力矩阵

src/hosts/README.md 中添加新主机的行和详细说明。

步骤 4:添加单元测试

创建 tests/unit/hosts/<id>.test.ts,验证所有字段值与 README.md 完全一致。

安装流程中的角色

graph TD
    A[CLI flags / --pack Manifest] --> B[显式标志能力检查]
    B --> C[不支持则 exit 2]
    C --> D[AssetDescriptor[]]
    D --> E[源解析]
    E --> F[验证]
    F --> G[InstallJob[]]
    G --> H[跳过不支持的资产]
    H --> I[执行写入]
    I --> J[InstallResult[]]
    J --> K[Summary 输出]

installer.ts 中的关键逻辑会根据 host adapter 的配置决定:

  1. 能力检查:验证目标主机是否支持该资产类型
  2. 路径解析:根据 configFileinstallDir 确定写入路径
  3. 策略选择:根据 writeStrategy 选择对应的写入方式
  4. 结果记录:返回 skipped/written/exists/updated/conflict/error 等状态

不支持的资产处理

当主机不支持特定资产类型时,适配器使用 NOT_SUPPORTED(reason) 辅助函数返回配置:

command: NOT_SUPPORTED('Codex CLI does not support custom slash commands via files.')

installer.ts 会检测此配置并将相应资产标记为 skipped,同时输出原因说明。资料来源:src/hosts/codex.ts:8-10

关键设计决策

决策说明来源
能力矩阵单一信息源src/hosts/README.md 是唯一的权威配置文档src/hosts/README.md:1
原子写入MCP 配置使用临时文件+重命名确保安全vibe/system-prompt.md:1
标记块追加Prompt 使用 HTML 注释实现幂等追加vibe/system-prompt.md:1
TOML 自动分发.toml 扩展名自动走 smol-toml 路径src/hosts/codex.ts:1
非 TTY 严格模式CI 环境必须显式指定 --hostsrc/hosts/README.md:1

总结

Host 适配器系统通过统一的接口抽象,使 agent-add 能够以插件式架构支持多种 AI 编程工具。系统设计遵循以下原则:

  • 可扩展性:新增主机只需实现 HostAdapter 接口并注册
  • 一致性:能力矩阵作为单一信息源,确保文档与实现同步
  • 容错性:不支持的资产优雅降级为 skipped 状态
  • 安全性:原子写入操作避免配置损坏风险

该系统已覆盖市场上主流的 18 种 AI 编程工具,并预留了完善的扩展机制以支持未来可能出现的新工具。

来源:https://github.com/pea3nut/agent-add / 项目说明书

CLI 参考文档

agent-add 是一个跨宿主 AI Agent 资源安装 CLI 工具,支持将 MCP、Skill、Prompt、Command、Sub-agent 等资源安装到不同的 AI 代理宿主(如 Cursor、Claude Code、Claude Desktop 等)。CLI 模块是该工具的入口层,负责命令行参数解析、宿主检测和安装流程的编排。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 入口流程

继续阅读本节完整说明和来源证据。

章节 核心数据结构

继续阅读本节完整说明和来源证据。

章节 资产安装选项

继续阅读本节完整说明和来源证据。

概述

agent-add 是一个跨宿主 AI Agent 资源安装 CLI 工具,支持将 MCP、Skill、Prompt、Command、Sub-agent 等资源安装到不同的 AI 代理宿主(如 Cursor、Claude Code、Claude Desktop 等)。CLI 模块是该工具的入口层,负责命令行参数解析、宿主检测和安装流程的编排。

CLI 模块的核心职责包括:

  • 定义所有命令行选项和子命令
  • 检测运行环境(TTY / Non-TTY)
  • 提供交互式宿主选择功能
  • 收集用户输入并调用安装器核心逻辑
  • 输出安装结果摘要

源码位置src/cli.ts 资料来源:src/cli.ts:1-1

命令行接口架构

入口流程

CLI 模块采用 Commander.js 框架构建命令行界面。入口点为 src/index.ts,通过 createProgram() 创建程序实例并异步解析命令行参数。

graph TD
    A[Node.js 进程启动] --> B[src/index.ts 入口]
    B --> C[createProgram 创建程序]
    C --> D[program.parseAsync 解析 argv]
    D --> E{是否有资产标志?}
    E -->|否| F[输出错误并退出 2]
    E -->|是| G{是否指定 --host?}
    G -->|是| H[使用指定宿主]
    G -->|否| I{是否为 TTY 环境?}
    I -->|否| J[输出错误并退出 2]
    I -->|是| K[交互式选择宿主]
    H --> L[runInstaller 执行安装]
    K --> L
    L --> M[printSummary 输出摘要]
    M --> N[是否存在冲突或错误?]
    N -->|是| O[exit 1]
    N -->|否| P[正常退出 0]

资料来源:src/index.ts:1-10 资料来源:src/cli.ts:1-100

核心数据结构

CLI 模块使用 TypeScript 接口定义输入输出的数据结构:

interface CliInput {
  mcp: string[];
  skill: string[];
  prompt: string[];
  command: string[];
  subAgent: string[];
  pack: string[];
  host?: string;
}
属性类型描述
mcpstring[]MCP 服务器配置源列表
skillstring[]Skill 目录源列表
promptstring[]Prompt 文件源列表
commandstring[]Command 文件源列表
subAgentstring[]Sub-agent 文件源列表
packstring[]Pack 清单文件源列表
host`string \undefined`目标宿主 ID(可选)

资料来源:src/cli.ts:30-50

命令行选项

资产安装选项

agent-add 支持通过以下标志安装不同类型的资源,所有选项均支持重复使用以安装多个同类型资源:

选项说明可重复
--pack <source>安装 Agent Pack 清单(批量安装)
--mcp <source>安装 MCP 服务器配置
--skill <source>安装 Skill 目录
--prompt <source>安装 Prompt 文件(系统提示词)
--command <source>安装 Command 文件(斜杠命令)
--sub-agent <source>安装 Sub-agent 文件

资料来源:src/cli.ts:60-80

宿主指定选项

选项说明必需性
--host <host>指定目标宿主 IDTTY 环境可选,CI 环境必填

支持的宿主 ID 包括:cursorclaude-codeclaude-desktopwindsurfgithub-copilotgeminiroo-codekilo-codeqwen-codeopencodeaugmentkirotabninekimitraeopenclawcodexvibe

资料来源:src/cli.ts:82 资料来源:src/hosts/README.md

辅助选项

选项说明
-V, --version显示版本号
-h, --help显示帮助信息

输入验证规则

资产标志检测

CLI 模块在解析参数后首先检查是否提供了至少一个资产安装标志:

const hasAssetFlags =
  cliInput.pack.length > 0 ||
  cliInput.mcp.length > 0 ||
  cliInput.skill.length > 0 ||
  cliInput.prompt.length > 0 ||
  cliInput.command.length > 0 ||
  cliInput.subAgent.length > 0;

if (!hasAssetFlags) {
  process.stderr.write(
    'agent-add error: No asset flags provided. Use --pack, --mcp, --skill, --prompt, --command, or --sub-agent.\n',
  );
  process.exit(2);
}

错误条件:未提供任何资产安装标志时,程序输出错误信息并以退出码 2 终止。

资料来源:src/cli.ts:85-100

宿主指定检测

graph TD
    A[解析 CLI 参数] --> B{--host 是否指定?}
    B -->|是| C[使用指定 hostId]
    B -->|否| D{是否为 TTY?}
    D -->|否| E[输出错误: CI 环境必须指定 --host]
    D -->|是| F[进入交互式选择流程]
    E --> G[exit 2]
    F --> H[显示宿主选择列表]
    H --> I[用户选择宿主]
    I --> C

CLI 环境检测逻辑:

if (cliInput.host) {
  hostId = cliInput.host;
} else if (!process.stdout.isTTY) {
  const validIds = getValidHostIds().join(', ');
  process.stderr.write(
    `agent-add error: No host specified. In non-TTY environments, you must explicitly specify --host.\n` +
    `Valid hosts: ${validIds}\n`,
  );
  process.exit(2);
}

错误条件:在非 TTY 环境下(如 CI/CD 流水线)未指定 --host 参数时,程序输出可用宿主列表并以退出码 2 终止。

资料来源:src/cli.ts:100-115

宿主选择流程

交互式选择

当在 TTY 环境下未指定 --host 时,CLI 提供交互式宿主选择功能:

const hostSelection = await inquirer.createPromptModule()({
  type: 'select',
  message: 'Select a host to install to:',
  choices: getValidHostIds(),
});

hostId = hostSelection.host;

用户通过上下箭头选择目标宿主,按 Enter 确认。

资料来源:src/cli.ts:55-58

有效宿主 ID 获取

getValidHostIds() 函数从宿主注册表中获取所有已注册的有效宿主 ID:

import { hostRegistry } from './hosts/index.js';

export function getValidHostIds(): string[] {
  return [...hostRegistry.keys()];
}

资料来源:src/cli.ts:15-20

安装流程编排

安装执行

选定宿主后,CLI 模块调用 runInstaller() 函数执行实际的安装逻辑:

const cwd = process.cwd();
const summary = await runInstaller(cliInput, host, cwd);
printSummary(summary);
  • cwd:当前工作目录,作为相对路径解析的基准
  • cliInput:解析后的 CLI 输入参数
  • host:选定的宿主适配器实例

资料来源:src/cli.ts:120-123

结果处理

安装完成后,CLI 根据结果状态决定退出码:

graph TD
    A[runInstaller 执行完成] --> B[printSummary 输出摘要]
    B --> C{是否有冲突?}
    B --> D{是否有错误?}
    C -->|是| E[exit 1]
    D -->|是| E
    C -->|否| F{是否有错误?}
    F -->|是| E
    F -->|否| G[正常退出 0]
    D -->|否| C

错误检测逻辑:

const hasConflicts = summary.results.some((r) => r.status === 'conflict');
const hasErrors = summary.results.some((r) => r.status === 'error');

if (hasErrors || hasConflicts) {
  process.exit(1);
}
退出码条件说明
0无冲突、无错误安装全部成功或部分资源已存在
1存在冲突或错误需用户介入解决
2CLI 参数错误无效参数或缺少必需参数

资料来源:src/cli.ts:125-132

使用示例

基本安装

# 安装 MCP 服务器
npx -y agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#python/playwright'

# 安装 Skill
npx -y agent-add --host claude-code --skill './my-skill'

# 安装 Prompt(内联 Markdown)
npx -y agent-add --host cursor \
  --prompt $'# Code Review Rules\n\nAlways review for security issues first.'

# 安装 Command
npx -y agent-add --host cursor --command 'https://github.com/wshobson/commands.git#tools/security-scan.md'

批量安装(Pack)

# 从 Pack 清单批量安装
npx -y agent-add --host cursor --pack 'https://github.com/anthropics/skills.git#skills/webapp-testing'

# 组合使用
npx -y agent-add --host cursor \
  --pack 'https://github.com/my-team/packs.git#frontend' \
  --mcp '{"playwright":{"command":"npx","args":["@playwright/mcp"]}}'

CI 环境使用

# .github/workflows/install-agents.yml
- name: Install Agent Assets
  run: |
    npx -y agent-add --host cursor --pack './configs/agent-pack.json'

CI 环境下必须显式指定 --host 参数。

编译与运行

项目脚本

package.json 中定义了以下与 CLI 相关的脚本:

脚本说明源码
npm run build使用 tsup 构建,输出 dist/index.js(单文件 CJS bundle)tsup 配置
npm run devtsup watch 开发模式-
npm test运行 vitest 单元和集成测试-
npm run test:contract仅运行 CLI 黑盒契约测试-

资料来源:package.json:20-35

CLI 入口点

项目通过 bin/agent-add.js 作为 CLI 入口:

{
  "bin": {
    "agent-add": "./dist/index.js"
  }
}

dist/index.js 是编译后的入口文件,定义了 shebang 和模块引用。

资料来源:package.json:8-11

运行时依赖

CLI 运行所需的依赖:

依赖版本用途
commander^14.0.3命令行参数解析
@inquirer/select^5.1.2交互式宿主选择
yaml^2.8.2YAML 文件解析(Skill/Command/Sub-agent)
zod^4.3.6配置验证
smol-toml^1.6.1TOML 文件读写(Codex/Vibe)

资料来源:package.json:30-45

模块关系图

graph TD
    subgraph "入口层"
        A[bin/agent-add.js] --> B[src/index.ts]
        B --> C[src/cli.ts]
    end
    
    subgraph "宿主层"
        C --> D[src/hosts/index.ts]
        D --> E[src/hosts/cursor.ts]
        D --> F[src/hosts/claude-code.ts]
        D --> G[src/hosts/...其他宿主]
    end
    
    subgraph "安装层"
        C --> H[src/installer.ts]
        H --> I[src/assets/mcp.ts]
        H --> J[src/assets/skill.ts]
        H --> K[src/assets/prompt.ts]
        H --> L[src/assets/command.ts]
        H --> M[src/assets/sub-agent.ts]
    end
    
    subgraph "工具层"
        H --> N[src/source/resolve-source.ts]
        H --> O[src/source/infer-name.ts]
        H --> P[src/hosts/summary.ts]
    end
    
    C --> Q[@inquirer/select 交互选择]
    H --> R[fs 文件系统操作]

错误处理

CLI 层错误

错误类型错误信息退出码处理方式
无资产标志agent-add error: No asset flags provided...2添加至少一个资产安装选项
Non-TTY 未指定宿主agent-add error: No host specified...2添加 --host <id> 参数
无效宿主 ID宿主验证失败2使用有效宿主 ID
安装器内部错误agent-add error: <message>2检查错误信息并重试

资料来源:src/cli.ts:90-95 资料来源:src/cli.ts:105-110

安装层错误

安装器核心 (src/installer.ts) 负责处理以下错误:

  • 资源解析失败
  • 资产验证失败
  • 文件系统操作失败
  • 资产类型不支持

安装层错误统一通过 process.stderr.write() 输出并以退出码 2 终止。

资料来源:src/installer.ts:1-50

最佳实践

  1. CI 环境:始终显式指定 --host 参数,避免交互式选择导致的阻塞
  2. 批量安装:优先使用 --pack 选项,通过清单文件管理多个资源
  3. 内联内容:对于简单配置,可使用内联 JSON/Markdown 避免额外文件
  4. 版本管理:使用 npm run build 确保最新代码编译后再执行
  5. 测试验证:修改 CLI 代码后运行 npm test 验证兼容性

资料来源:[src/index.ts:1-10]()

Pack Manifest 格式规范

Pack Manifest 是一种 JSON 格式的配置文件,用于捆绑和分发多个 agent-add 资产(Asset)。开发者可以将 MCP Server、Skill、Prompt、Command、Sub-agent 等多种类型的资产打包为单个 Manifest 文件,通过 agent-add --pack <source 命令一次性安装全部资产。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 格式要求

继续阅读本节完整说明和来源证据。

章节 字符限制

继续阅读本节完整说明和来源证据。

章节 错误处理

继续阅读本节完整说明和来源证据。

概述

Pack Manifest 是一种 JSON 格式的配置文件,用于捆绑和分发多个 agent-add 资产(Asset)。开发者可以将 MCP Server、Skill、Prompt、Command、Sub-agent 等多种类型的资产打包为单个 Manifest 文件,通过 agent-add --pack <source> 命令一次性安装全部资产。

Manifest 文件简化了资产分发流程,尤其适合团队共享或跨项目复用。接收方只需一条命令即可完成所有资产的安装。

核心数据结构

{
  "name": "namespace/pack-name",
  "assets": [
    { "type": "<asset-type>", "source": "<source-uri>" }
  ]
}
字段类型必填说明
namestring格式为 namespace/pack-name,命名空间与包名之间用斜杠分隔
assetsarray资产数组,至少包含 1 个元素

name 字段规范

格式要求

Manifest 的 name 字段必须符合 namespace/pack-name 格式,其中:

  • 命名空间(namespace):标识资产包的分发组织或作者
  • 包名(pack-name):标识具体的资产包

字符限制

name 字段仅允许使用以下字符:[a-zA-Z0-9_-]

示例:

{
  "name": "my-team/frontend-pack",
  "assets": [...]
}

错误处理

name 字段不符合规范时,agent-add 将输出错误信息并以退出码 2 终止:

agent-add error: Manifest name must match namespace/pack-name format

资料来源:src/manifest/parser.ts:32-36

assets 数组规范

资产类型

assets[].type 字段定义资产类型,可选值如下:

type 值说明来源格式
mcpMCP Server 配置JSON 文件
skillSkill 目录包含 SKILL.md 的目录
promptPrompt/规则文件Markdown 文件
command命令文件Markdown 文件
subAgent子代理配置Markdown 文件

source 字段

source 字段支持多种来源格式,agent-add 根据前缀自动识别来源类型:

来源格式类型标识说明
本地目录路径local-dir本地文件系统目录
https:// 开头http-fileHTTP/HTTPS URL 下载
git@.git 结尾gitGit 仓库 URL
{ 开头inline-json内联 JSON(MCP 类型专用)
包含 \ninline-md内联 Markdown(Prompt/Command/Sub-agent 专用)

来源名称推断规则

资产名称(asset name)根据 source 字段自动推断:

graph TD
    A[source 输入] --> B{包含 `#` 路径锚点?}
    B -->|是| C[取 `#` 后的最后一段<br/>移除扩展名]
    B -->|否| D{Git URL?}
    D -->|是| E[取仓库名<br/>移除 `.git` 后缀]
    D -->|否| F[取文件名<br/>移除扩展名]
    C --> G[推断为 asset name]
    E --> G
    F --> G
来源格式推断规则示例
#path取最后路径段,去扩展名...git#skills/pdfpdf
Git URL 无 #取仓库名,去 .git...playwright.gitplaywright
本地路径/HTTP取文件名,去扩展名./mcps/playwright.jsonplaywright
内联 JSON取顶层键名{"playwright":{...}}playwright
内联 Markdown取首个 # 标题,转 kebab-case# Code Reviewcode-review

资料来源:src/source/infer-name.ts:1-53

完整示例

基础示例

{
  "name": "my-team/frontend-pack",
  "assets": [
    { "type": "mcp", "source": "https://github.com/modelcontextprotocol/servers.git#.mcp.json" },
    { "type": "skill", "source": "https://github.com/anthropics/skills.git#skills/pdf" },
    { "type": "prompt", "source": "https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs-react-tailwind/.cursorrules" },
    { "type": "command", "source": "https://github.com/wshobson/commands.git#tools/security-scan.md" },
    { "type": "subAgent", "source": "https://github.com/VoltAgent/awesome-claude-code-subagents.git#categories/01-core-development/backend-developer.md" }
  ]
}

实际使用示例

以下示例来自 vibe 开发包:

{
  "name": "agent-add/vibe",
  "assets": [
    { "type": "subAgent", "source": "https://github.com/pea3nut/scenario-test.git#sub-agents/verify-host-readme" },
    { "type": "prompt", "source": "vibe/system-prompt.md" },
    { "type": "command", "source": "vibe/tasks/verify-host-readme.md" }
  ]
}

资料来源:vibe/manifest.json

安装流程

处理流程

graph TD
    A[--pack <source>] --> B[下载/读取 Manifest]
    B --> C[解析 JSON]
    C --> D{解析成功?}
    D -->|失败| E[输出 Zod 验证错误<br/>exit 2]
    D -->|成功| F[遍历 assets 数组]
    F --> G[解析 source URI]
    G --> H{验证资产类型}
    H -->|无效| I[输出错误<br/>exit 2]
    H -->|有效| J[推断 asset name]
    J --> K[分发至各资产处理器]

显式标志能力检查

使用 --pack 安装时,Manifest 中的资产会被分发到对应的处理器。如果某些资产类型目标主机不支持,该资产会被静默跳过(skipped),而不是报错退出。

这与显式标志(如 --mcp--skill)的行为不同——显式标志会在主机不支持时直接报错退出。

验证规则

#### 资产类型验证

不支持的 type 值会触发错误:

agent-add error: Unsupported asset type: '<bad-type>'. Supported: mcp, skill, prompt, command, subAgent

#### Skill 特殊限制

Skill 类型的资产不支持以下来源格式:

  • http-file:HTTP/HTTPS URL
  • inline-json:内联 JSON
  • inline-md:内联 Markdown

Skill 必须指向目录来源(本地路径或 Git URL)。

#### MCP 特殊限制

MCP 类型的资产必须满足以下条件:

  • 来源文件必须存在
  • 文件扩展名必须为 .json

#### 缺失字段处理

if (isTypeField) {
  // 输出不支持的类型错误
} else if (isNameField && message.includes('namespace/pack-name')) {
  // 输出名称格式错误
} else {
  // 输出缺失字段错误
  process.stderr.write(`agent-add error: Manifest missing required field: ${fieldPath || 'unknown'}\n`);
}

资料来源:src/manifest/parser.ts:12-44

字段验证规范

Zod Schema 验证

Manifest 使用 Zod 进行运行时验证,关键规则包括:

规则字段错误信息
必填nameManifest missing required field: name
格式nameManifest name must match namespace/pack-name format
必填assetsManifest missing required field: assets
非空assets至少包含 1 个元素
必填assets[].typeManifest missing required field: assets[].type
枚举assets[].typeUnsupported asset type: '<value>'
必填assets[].sourceManifest missing required field: assets[].source

错误信息输出格式

所有错误均输出至 stderr,格式为:

agent-add error: <具体错误描述>
  <额外信息或修复建议>

与 CLI 参数的对比

特性--pack显式标志
安装多个同类型资产✓ (多次使用)
组合不同类型资产
不支持的资产处理静默跳过报错退出 (exit 2)
来源格式仅目录/URL支持内联内容

最佳实践

  1. 命名规范:使用有意义的 namespace(如团队名、作者名),使包名具有描述性
  2. 来源可靠性:优先使用稳定的 Git URL,避免直接引用可能失效的 HTTP URL
  3. 版本锁定:Git 来源可使用 #ref 语法锁定特定版本或 commit
  4. 资产组织:相关资产放在同一 Manifest 中,减少分发复杂度

参考资料

资料来源:[src/manifest/parser.ts:32-36]()

资产开发者指南

资产开发者指南是 agent-add 项目为第三方开发者提供的文件格式规范文档。该指南定义了 agent-add 所支持的五种资产类型的结构要求、命名规则和格式约束,使开发者能够创建可被 agent-add 正确安装和分发的 MCP 服务器、Skill、Prompt、Command 和 Sub-agent 资产。

章节 相关页面

继续阅读本节完整说明和来源证据。

章节 支持的 JSON 格式

继续阅读本节完整说明和来源证据。

章节 TOML 配置支持

继续阅读本节完整说明和来源证据。

章节 名称推断规则

继续阅读本节完整说明和来源证据。

概述

资产开发者指南是 agent-add 项目为第三方开发者提供的文件格式规范文档。该指南定义了 agent-add 所支持的五种资产类型的结构要求、命名规则和格式约束,使开发者能够创建可被 agent-add 正确安装和分发的 MCP 服务器、Skill、Prompt、Command 和 Sub-agent 资产。

agent-add 作为跨主机的 AI 工具资产安装器,支持 18 种主流 AI 编程工具(包括 Cursor、Claude Code、Codex 等),资产开发者通过遵循本指南创建的资产,可实现一次编写、多端复用的分发目标。资料来源:README.md:98-115

资产类型概述

agent-add 支持的资产类型及其核心特征如下:

资产类型用途安装目标写入策略
MCPModel Context Protocol 服务器配置主机 MCP 配置文件JSON 浅合并或 TOML 注入
Skill可复用的 Agent 技能包技能目录目录递归复制
Prompt规则文件/系统提示词AGENTS.md 或规则目录HTML 标记追加或独立文件
Command斜杠命令定义commands 目录独立文件写入
Sub-agent子代理配置agents 目录TOML 文件写入

MCP 配置文件规范

支持的 JSON 格式

MCP 资产支持两种 JSON 格式,agent-add 会自动检测并解析:

{
  "command": "npx",
  "args": ["@playwright/mcp@latest"],
  "env": {}
}

格式 A 为内层配置(单服务器),资产名称从文件名推断:playwright.json → 名称为 playwright。资料来源:README.md:105-113

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

格式 B 为完整配置包装,agent-add 自动解包 mcpServers 并提取内部服务器名称和配置。资料来源:README.md:115-120

TOML 配置支持

Codex 和 Vibe 等主机使用 TOML 格式存储 MCP 配置。agent-add 在检测到 .toml 扩展名时自动调度到 smol-toml 处理路径。资料来源:vibe/system-prompt.md:17

名称推断规则

资产名称推断遵循以下优先级规则:

场景推断逻辑示例
源包含 #path取路径最后段(去除扩展名)...git#skills/pdfpdf
Git URL 无 #path取仓库名(去除 .git 后缀)...playwright.gitplaywright
本地路径/HTTP URL取文件名(去除扩展名)./mcps/playwright.jsonplaywright

资料来源:src/source/infer-name.ts:1-40

验证规则

MCP 资产在安装前必须通过以下验证:

  1. 文件存在性检查:MCP 来源文件必须存在于本地路径
  2. 扩展名验证:文件扩展名必须为 .json
  3. 来源类型限制http-fileinline-jsoninline-md 类型的来源不允许安装为 Skill 类型资产,但 MCP 允许 inline-json(格式为 {"name":{...}},key 为资产名称)资料来源:src/installer.ts:78-85

Skill 资产规范

目录结构要求

Skill 必须是一个完整的目录,目录内必须包含 SKILL.md 文件作为入口点:

my-skill/
├── SKILL.md      # 必需:技能元数据和描述
├── helpers/
│   └── utils.py  # 可选:辅助脚本
└── templates/
    └── report.md # 可选:模板文件
<!-- SKILL.md -->

资料来源:[src/source/infer-name.ts:1-40]()

失败模式与踩坑日记

保留 Doramagic 在发现、验证和编译中沉淀的项目专属风险,不把社区讨论只当作装饰信息。

medium 社区讨论暴露的待验证问题:I built a CLI that installs MCP, skills, prompts, commands and sub ...

这类外部讨论可能代表真实用户在安装、配置、升级或生产使用时遇到阻力;发布前不能只依赖官方 README。

medium 可能修改宿主 AI 配置

安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。

medium 能力判断依赖假设

假设不成立时,用户拿不到承诺的能力。

medium 维护活跃度未知

新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。

Pitfall Log / 踩坑日志

项目:pea3nut/agent-add

摘要:发现 9 个潜在踩坑项,其中 0 个为 high/blocking;最高优先级:安装坑 - 社区讨论暴露的待验证问题:I built a CLI that installs MCP, skills, prompts, commands and sub ...。

1. 安装坑 · 社区讨论暴露的待验证问题:I built a CLI that installs MCP, skills, prompts, commands and sub ...

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:I built a CLI that installs MCP, skills, prompts, commands and sub ... 6 Apr 2026 · Project & Supported Tools. The source code is hosted on GitHub: https://github.com/pea3nut/agent-add ... r/mcp - I built a tool that auto- ...
  • 对用户的影响:这类外部讨论可能代表真实用户在安装、配置、升级或生产使用时遇到阻力;发布前不能只依赖官方 README。
  • 建议检查:Pack Agent 需要打开来源链接,确认问题是否仍然存在,并把验证结论写入说明书和边界卡。
  • 证据:social_signal:reddit | ssig_6d54ef81557a451081be71b052d0e31b | https://www.reddit.com/r/ClaudeAI/comments/1sdrk6k/i_built_a_cli_that_installs_mcp_skills_prompts/ | I built a CLI that installs MCP, skills, prompts, commands and sub ...

2. 配置坑 · 可能修改宿主 AI 配置

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主,或安装命令涉及用户配置目录。
  • 对用户的影响:安装可能改变本机 AI 工具行为,用户需要知道写入位置和回滚方法。
  • 建议检查:列出会写入的配置文件、目录和卸载/回滚步骤。
  • 防护动作:涉及宿主配置目录时必须给回滚路径,不能只给安装命令。
  • 证据:capability.host_targets | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | host_targets=mcp_host, claude, claude_code, cursor, chatgpt

3. 能力坑 · 能力判断依赖假设

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:README/documentation is current enough for a first validation pass.
  • 对用户的影响:假设不成立时,用户拿不到承诺的能力。
  • 建议检查:将假设转成下游验证清单。
  • 防护动作:假设必须转成验证项;没有验证结果前不能写成事实。
  • 证据:capability.assumptions | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | README/documentation is current enough for a first validation pass.

4. 维护坑 · 维护活跃度未知

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:未记录 last_activity_observed。
  • 对用户的影响:新项目、停更项目和活跃项目会被混在一起,推荐信任度下降。
  • 建议检查:补 GitHub 最近 commit、release、issue/PR 响应信号。
  • 防护动作:维护活跃度未知时,推荐强度不能标为高信任。
  • 证据:evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | last_activity_observed missing

5. 安全/权限坑 · 下游验证发现风险项

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:下游已经要求复核,不能在页面中弱化。
  • 建议检查:进入安全/权限治理复核队列。
  • 防护动作:下游风险存在时必须保持 review/recommendation 降级。
  • 证据:downstream_validation.risk_items | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | no_demo; severity=medium

6. 安全/权限坑 · 存在安全注意事项

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:No sandbox install has been executed yet; downstream must verify before user use.
  • 对用户的影响:用户安装前需要知道权限边界和敏感操作。
  • 建议检查:转成明确权限清单和安全审查提示。
  • 防护动作:安全注意事项必须面向用户前置展示。
  • 证据:risks.safety_notes | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | No sandbox install has been executed yet; downstream must verify before user use.

7. 安全/权限坑 · 存在评分风险

  • 严重度:medium
  • 证据强度:source_linked
  • 发现:no_demo
  • 对用户的影响:风险会影响是否适合普通用户安装。
  • 建议检查:把风险写入边界卡,并确认是否需要人工复核。
  • 防护动作:评分风险必须进入边界卡,不能只作为内部分数。
  • 证据:risks.scoring_risks | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | no_demo; severity=medium

8. 维护坑 · issue/PR 响应质量未知

  • 严重度:low
  • 证据强度:source_linked
  • 发现:issue_or_pr_quality=unknown。
  • 对用户的影响:用户无法判断遇到问题后是否有人维护。
  • 建议检查:抽样最近 issue/PR,判断是否长期无人处理。
  • 防护动作:issue/PR 响应未知时,必须提示维护风险。
  • 证据:evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | issue_or_pr_quality=unknown

9. 维护坑 · 发布节奏不明确

  • 严重度:low
  • 证据强度:source_linked
  • 发现:release_recency=unknown。
  • 对用户的影响:安装命令和文档可能落后于代码,用户踩坑概率升高。
  • 建议检查:确认最近 release/tag 和 README 安装命令是否一致。
  • 防护动作:发布节奏未知或过期时,安装说明必须标注可能漂移。
  • 证据:evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | release_recency=unknown

来源:Doramagic 发现、验证与编译记录