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

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

## 目录

- [项目首页](#p-home)
- [安装与快速开始](#p-installation)
- [核心功能使用指南](#p-usage)
- [源格式与名称推断](#p-source-formats)
- [系统架构总览](#p-arch)
- [Source 模块详解](#p-source-module)
- [Host 适配器系统](#p-host-system)
- [CLI 参考文档](#p-cli-ref)
- [Pack Manifest 格式规范](#p-pack-manifest)
- [资产开发者指南](#p-asset-dev)

<a id='p-home'></a>

## 项目首页

### 相关页面

相关主题：[安装与快速开始](#p-installation), [核心功能使用指南](#p-usage), [系统架构总览](#p-arch)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [README.md](https://github.com/pea3nut/agent-add/blob/main/README.md)
- [package.json](https://github.com/pea3nut/agent-add/blob/main/package.json)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [src/manifest/parser.ts](https://github.com/pea3nut/agent-add/blob/main/src/manifest/parser.ts)
- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
</details>

# 项目首页

## 项目概述

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

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

## 核心能力

### 支持的资产类型

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

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

### 支持的宿主环境

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

| 宿主 | 配置格式 | 说明 |
|-----|---------|------|
| `cursor` | AGENTS.md | Cursor IDE |
| `claude-code` | CLAUDE.md | Anthropic Claude Code |
| `claude-desktop` | JSON | Claude 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 |
| `codex` | TOML | OpenAI Codex |
| `vibe` | TOML | Vibe Coding 工具 |

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

## 系统架构

### 整体架构

```mermaid
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 处理器]
```

### 核心模块

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

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

## 安装流程

### 命令行用法

```bash
# 安装 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](https://github.com/pea3nut/agent-add/blob/main/README.md)

### 数据流处理

```mermaid
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](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)

## 关键设计决策

### 原子化 JSON 写入

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

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

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

### 标记块追加策略

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

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

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

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

### 内联源支持

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

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

### 非 TTY 严格模式

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

```typescript
// 非 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](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)

## Pack Manifest 清单

### 格式规范

```json
{
  "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": "git@github.com:...#tools/security.md" },
    { "type": "subAgent", "source": "...#categories/backend.md" }
  ]
}
```

### 字段规格

| 字段 | 必填 | 说明 |
|-----|-----|------|
| `name` | 是 | 格式：`namespace/pack-name`，仅允许 `[a-zA-Z0-9_-]` |
| `assets` | 是 | 至少 1 个元素 |
| `assets[].type` | 是 | `mcp` \| `skill` \| `prompt` \| `command` \| `subAgent` |
| `assets[].source` | 是 | 资产来源（URL、路径、内联内容） |

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

## 项目技术栈

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

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

## 宿主适配器接口

```typescript
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](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)

## 快速开始

### 开发环境搭建

```bash
# 克隆仓库
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](https://github.com/pea3nut/agent-add/blob/main/README.md)

## 贡献指南

### 场景测试

场景测试使用 Gherkin `.feature` 文件定义，由 AI Agent 通过 [scenario-test](https://github.com/pea3nut/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 中的字段值完全一致。

---

<a id='p-installation'></a>

## 安装与快速开始

### 相关页面

相关主题：[核心功能使用指南](#p-usage), [CLI 参考文档](#p-cli-ref)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [package.json](https://github.com/pea3nut/agent-add/blob/main/package.json)
- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/index.ts)
- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/hosts/README.md](https://github.com/pea3nut/agent-add/blob/main/src/hosts/README.md)
- [README.md](https://github.com/pea3nut/agent-add/blob/main/README.md)
</details>

# 安装与快速开始

## 概述

`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` 调用：

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

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

资料来源：[README.md:1]()

### 方式二：全局安装

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

```bash
npm install -g agent-add
```

安装完成后可直接调用：

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

### 方式三：本地项目安装

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

```bash
npm install --save-dev agent-add
```

在 `package.json` 中配置快捷脚本：

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

资料来源：[package.json:41]()

## 构建与开发

如果从源码克隆项目，需要先构建：

```bash
npm install
npm run build
```

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

### 开发模式

支持热重载开发模式：

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

资料来源：[README.md:7]()

## 基本使用流程

### 工作流程图

```mermaid
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 环境必填 | 目标宿主标识符，如 `cursor`、`claude-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 服务器

```bash
# 从 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 技能包

```bash
# 从 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 规则文件

```bash
# 内联 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 命令

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

### 安装 Sub-agent 子代理

```bash
# 从 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 清单）

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

Pack 清单格式示例：

```json
{
  "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/pdf` → `pdf` |
| Git URL 无 `#` | 使用仓库名称（去除 `.git` 后缀） | `...playwright.git` → `playwright` |
| 本地路径/HTTP | 使用文件名（去除扩展名） | `./mcps/playwright.json` → `playwright` |
| 内联 JSON `{` 开头 | 提取顶层 key 作为名称 | `{"playwright":{...}}` → `playwright` |
| 内联 Markdown 包含 `\n` | 提取第一个 `# Heading` 并转 kebab-case | `# Code Review` → `code-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` 参数，否则程序会退出并提示错误。

## 相关文档

- [宿主适配器开发指南](./host-adapter-guide.md) - 如何添加新的宿主支持
- [资产类型规范](./asset-specifications.md) - 各资产类型的详细格式说明
- [Pack 清单规范](./pack-manifest.md) - Pack 清单文件格式详解
- [测试指南](./testing.md) - 单元测试和集成测试说明

---

<a id='p-usage'></a>

## 核心功能使用指南

### 相关页面

相关主题：[源格式与名称推断](#p-source-formats), [Host 适配器系统](#p-host-system), [CLI 参考文档](#p-cli-ref)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/hosts/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/index.ts)
- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
- [src/manifest/parser.ts](https://github.com/pea3nut/agent-add/blob/main/src/manifest/parser.ts)
</details>

# 核心功能使用指南

## 概述

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

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

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

## 安装流程架构

### 数据流总览

```mermaid
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
```

### 核心数据类型

| 类型名称 | 用途 | 关键字段 |
|---------|------|---------|
| `CliInput` | CLI 原始输入 | `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，定义了六类资产安装标志：

```typescript
.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, [])
```

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

### 输入验证

```typescript
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]()

## 宿主检测与选择

### 宿主注册表

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

```typescript
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） |

```typescript
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]()

### 宿主能力矩阵

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

```typescript
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` | 绝对/相对路径 | 本地文件系统 |
| `git` | Git URL + `#path` | Git 仓库文件/目录 |
| `http-file` | HTTP(S) URL | 远程文件下载 |
| `inline-json` | `{"name":{...}}` | 内联 JSON（MCP 专用） |
| `inline-md` | 含换行符的 Markdown | 内联 Prompt/Command/Sub-agent |

### 名称推断规则

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

| 来源格式 | 推断逻辑 | 示例 |
|----------|----------|------|
| 内联 JSON | 提取顶层键名 | `{"playwright":{...}}` → `playwright` |
| 内联 Markdown | 首行 `# 标题` 转 kebab-case | `# Code Review` → `code-review` |
| Git URL + `#path` | path 最后段去扩展名 | `...git#skills/pdf` → `pdf` |
| Git URL 无 `#` | 仓库名去 `.git` | `...playwright.git` → `playwright` |
| 本地路径/HTTP | 文件名去扩展名 | `./mcps/playwright.json` → `playwright` |

```typescript
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]()

### 来源解析流程

```mermaid
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.md` | `Skill 资产必须指向目录来源（本地路径或 Git URL），不支持内联内容或直接 HTTP(S) URL` |
| `skill` | 不支持 `http-file`/`inline-json`/`inline-md` 来源 | `Skill 目录内缺少 SKILL.md 文件` |
| `mcp` | 文件必须存在且扩展名为 `.json` | `MCP 来源文件不存在` / `MCP 来源文件扩展名必须为 .json` |

```typescript
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]()

## 安装执行

### 资产处理器注册

```typescript
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` | 安装过程出错 |

### 跳过逻辑

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

```typescript
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]()

## 清单文件处理

### 清单格式

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

### 清单解析流程

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

### 字段规范

| 字段 | 必填 | 说明 |
|------|------|------|
| `name` | 是 | 格式 `namespace/pack-name`，仅允许 `[a-zA-Z0-9_-]` |
| `assets` | 是 | 至少包含 1 项 |
| `assets[].type` | 是 | `mcp` \| `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` | 参数错误、验证失败、来源无效 |

```typescript
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]()

## 使用示例

### 单资产安装

```bash
# 安装 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'
```

### 清单批量安装

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

### 组合使用

```bash
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.'

---

<a id='p-source-formats'></a>

## 源格式与名称推断

### 相关页面

相关主题：[Source 模块详解](#p-source-module), [资产开发者指南](#p-asset-dev)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/source/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/index.ts)
- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/source/git.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/git.ts)
- [src/source/http-file.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/http-file.ts)
- [src/source/local.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/local.ts)
- [src/source/inline.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/inline.ts)
</details>

# 源格式与名称推断

## 概述

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

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

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

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

## 源类型体系

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

### 源类型分类

| 源类型 | 识别规则 | 特征 | 支持的资产类型 |
|--------|----------|------|----------------|
| `inline-json` | 以 `{` 开头 | JSON 对象字面量 | 仅 MCP |
| `inline-md` | 包含 `\n` | Markdown 内容 | Prompt/Command/Sub-agent |
| `git-ssh` | 以 `git@` 开头 | SSH 协议格式 | 所有类型 |
| `git-https` | 以 `https://` 或 `http://` 开头，且包含 `.git` | HTTPS 协议 | 所有类型 |
| `http-file` | 以 `https://` 或 `http://` 开头，且不包含 `.git` | HTTP 文件 URL | 除 Skill 外的所有类型 |
| `local` | 其他情况 | 本地文件路径 | 所有类型 |

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

### 类型识别流程

```mermaid
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 Review` → `code-review` |
| 1 | 包含 `#path` | 使用 `#` 后的路径段（去掉扩展名） | `...git#skills/pdf` → `pdf` |
| 2 | Git URL 无 `#path` | 提取仓库名（去掉 `.git` 后缀） | `...playwright.git` → `playwright` |
| 3 | 本地路径/HTTP 文件 | 提取文件名（去掉扩展名） | `./mcps/playwright.json` → `playwright` |

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

### 详细规则说明

#### 内联 JSON（inline-json）

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

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

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

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

资料来源：[src/source/infer-name.ts:14-35](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)

#### 内联 Markdown（inline-md）

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

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

**限制**：内联 Markdown 格式仅支持 Prompt、Command 和 Sub-agent 类型的资产，不支持 Skill 类型。资料来源：[src/source/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/index.ts)

#### Git URL 路径引用（#path）

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

```bash
https://github.com/anthropics/skills.git#skills/webapp-testing
// 推断名称: webapp-testing
```

```bash
https://github.com/modelcontextprotocol/servers.git#.mcp.json
// 推断名称: mcp.json → mcp
```

资料来源：[src/source/infer-name.ts:36-40](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)

#### Git URL 无路径引用

如果 Git URL 不包含 `#path`，系统从仓库 URL 中提取名称：

```bash
https://github.com/anthropics/skills.git
// 推断名称: skills
```

```bash
git@github.com:anthropics/claude-code-skills.git
// 推断名称: claude-code-skills
```

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

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

```bash
./mcps/playwright.json
// 推断名称: playwright
```

```bash
https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs/.cursorrules
// 推断名称: .cursorrules → cursorrules
```

## 源解析器实现

### 模块结构

```mermaid
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](https://github.com/pea3nut/agent-add/blob/main/src/source/git.ts)

### HTTP 文件解析器

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

**限制**：

- 仅支持 Prompt、Command、Sub-agent 和 MCP 类型的资产
- **不支持** Skill 类型资产（HTTP 源安装 Skill 会导致错误，退出码 2）

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

### 本地路径解析器

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

**功能**：

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

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

### 内联内容解析器

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

**处理流程**：

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

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

## 错误处理

### 内联 JSON 解析错误

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

### 内联类型不匹配

```typescript
// HTTP 源安装 Skill 时
agent-add error: HTTP sources cannot install Skill assets
```

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

### 名称推断失败

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

## 与其他模块的交互

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

```mermaid
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](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)

## 最佳实践

### 源格式选择建议

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

### 名称规范

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

---

<a id='p-arch'></a>

## 系统架构总览

### 相关页面

相关主题：[Source 模块详解](#p-source-module), [Host 适配器系统](#p-host-system), [核心功能使用指南](#p-usage)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/index.ts)
- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
- [src/hosts/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/index.ts)
- [src/assets/mcp.ts](https://github.com/pea3nut/agent-add/blob/main/src/assets/mcp.ts)
- [src/assets/skill.ts](https://github.com/pea3nut/agent-add/blob/main/src/assets/skill.ts)
- [src/assets/prompt.ts](https://github.com/pea3nut/agent-add/blob/main/src/assets/prompt.ts)
</details>

# 系统架构总览

## 1. 项目概述

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

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

## 2. 系统架构图

```mermaid
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. 核心数据流

```mermaid
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 数据模型

| 模型 | 描述 | 字段 |
|------|------|------|
| `CliInput` | CLI 参数输入 | `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` |
| `git` | Git 仓库 URL | `https://github.com/...#path/to/asset` |
| `http-file` | HTTP/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 层负责用户交互和参数验证：

```typescript
// 核心参数定义（资料来源：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/）

```mermaid
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 | 配置文件格式 | 资产类型支持 |
|---------|-------------|-------------|
| `cursor` | JSON | MCP, Prompt, Command, Sub-agent |
| `claude-code` | JSON | MCP, Prompt, Command, Sub-agent |
| `claude-desktop` | JSON | MCP only |
| `windsurf` | JSON | MCP, Prompt, Command |
| `roo-code` | JSON | MCP, Prompt, Command |
| `codex` | TOML | MCP, Prompt |
| `vibe` | TOML | MCP, Prompt |
| `kimi` | JSON | MCP, Prompt |
| `trae` | JSON | MCP, Prompt |
| `openclaw` | JSON | MCP, Prompt |
| `gemini` | JSON | MCP, Prompt |
| `github-copilot` | JSON | MCP, Prompt |
| `kilo-code` | JSON | MCP, Prompt |
| `qwen-code` | JSON | MCP, Prompt |
| `opencode` | JSON | MCP, Prompt |
| `augment` | JSON | MCP, Prompt |
| `kiro` | JSON | MCP, Prompt |
| `tabnine` | JSON | MCP, Prompt |

### 5.4 资产处理器层（src/assets/）

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

```mermaid
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 注释标记实现幂等追加：

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

### 6.3 TOML 格式自动识别

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

| 扩展名 | 解析方式 |
|--------|----------|
| `.json` | 标准 JSON 解析 |
| `.toml` | smol-toml 库解析 |

### 6.4 显式标志能力拒绝

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

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

## 7. 错误处理

| 错误场景 | 退出码 | 处理方式 |
|----------|--------|----------|
| 非 TTY 环境未指定 `--host` | 2 | stderr 输出有效 Host 列表 |
| 无效的资产标志 | 2 | stderr 提示有效选项 |
| 源解析失败 | 2 | stderr 输出详细错误 |
| 资产验证失败 | 2 | stderr 输出验证原因 |
| 安装冲突 | 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. 相关文档

- [README.md](https://github.com/pea3nut/agent-add/blob/main/README.md) - 项目主文档
- [src/hosts/README.md](https://github.com/pea3nut/agent-add/blob/main/src/hosts/README.md) - 主机能力矩阵（唯一信源）
- [vibe/system-prompt.md](https://github.com/pea3nut/agent-add/blob/main/vibe/system-prompt.md) - 系统设计提示

---

<a id='p-source-module'></a>

## Source 模块详解

### 相关页面

相关主题：[系统架构总览](#p-arch), [源格式与名称推断](#p-source-formats)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/source/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/index.ts)
- [src/source/git.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/git.ts)
- [src/source/http-file.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/http-file.ts)
- [src/source/local.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/local.ts)
- [src/source/inline.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/inline.ts)
- [src/source/expand-directory.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/expand-directory.ts)
</details>

# Source 模块详解

## 模块概述

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

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

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

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

## 支持的来源类型

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

| 类型 | 标识 | 描述 |
|------|------|------|
| 本地路径 | `local` | 本地文件系统路径 |
| Git SSH | `git-ssh` | `git@` 开头的 SSH 地址 |
| Git HTTPS | `git-https` | `https://` 或 `http://` 开头的 Git 地址 |
| HTTP 文件 | `http-file` | 直接的 HTTP/HTTPS 文件 URL |
| 内联 JSON | `inline-json` | 以 `{` 开头的内联 JSON 字符串（仅限 MCP） |
| 内联 Markdown | `inline-md` | 包含换行符的内联 Markdown（Prompt/Command/Sub-agent） |

资料来源：[vibe/system-prompt.md](https://github.com/pea3nut/agent-add/blob/main/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` 数据结构：

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

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

## 来源类型解析详解

### 1. 本地路径解析

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

**工作流程：**

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

**关键约束：**
- 路径必须存在且可访问
- Skill 类型资产的本地路径必须包含 `SKILL.md` 文件

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

### 2. Git 仓库解析

Git 解析器（`git.ts`）支持从 Git 仓库获取资产，支持稀疏检出（sparse checkout）语法。

**Git URL 格式支持：**

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

**稀疏检出功能：**

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

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

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

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

### 3. HTTP 文件解析

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

**使用限制：**

> ⚠️ **重要约束**：HTTP 来源类型**不支持** Skill 资产类型。尝试使用 HTTP URL 安装 Skill 会导致安装失败并返回错误码 2。

```mermaid
graph TD
    A[HTTP URL] --> B{资产类型?}
    B -->|skill| C[返回错误: 不支持]
    B -->|其他类型| D[下载到临时文件]
    D --> E[返回 tempDir 路径]
```

资料来源：[src/source/http-file.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/http-file.ts)  
资料来源：[vibe/system-prompt.md](https://github.com/pea3nut/agent-add/blob/main/vibe/system-prompt.md)

### 4. 内联内容解析

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

**两种内联格式：**

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

**内联 JSON 示例：**

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

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

**内联 Markdown 示例：**

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

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

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

### 5. 目录展开

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

**典型应用场景：**

当用户提供的 source 是包含多个资产的目录时，该模块负责：
1. 扫描目录下的所有匹配文件
2. 为每个匹配项生成独立的 `ResolvedSource`
3. 保持目录结构在资产名称中（如 `dirName/assetName`）

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

## 资产名称推断

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

### 推断规则优先级

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

### 名称转换示例

| 原始来源 | 推断名称 |
|----------|----------|
| `...git#skills/pdf` | `pdf` |
| `...playwright.git` | `playwright` |
| `./mcps/playwright.json` | `playwright` |
| `# Code Review` → | `code-review` |

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

## 类型验证流程

### 验证时机

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

```mermaid
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
```

### 各资产类型的验证规则

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

**Skill 类型的额外限制：**

```typescript
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](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)

## 错误处理

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

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

**常见错误消息：**

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

## 与其他模块的集成

### 数据流图

```mermaid
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 系统都至关重要。

---

<a id='p-host-system'></a>

## Host 适配器系统

### 相关页面

相关主题：[系统架构总览](#p-arch), [核心功能使用指南](#p-usage), [CLI 参考文档](#p-cli-ref)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/hosts/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/index.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
- [src/hosts/cursor.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/cursor.ts)
- [src/hosts/claude-code.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/claude-code.ts)
- [src/hosts/windsurf.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/windsurf.ts)
- [src/hosts/codex.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/codex.ts)
- [src/hosts/README.md](https://github.com/pea3nut/agent-add/blob/main/src/hosts/README.md)
- [src/utils/detect-hosts.ts](https://github.com/pea3nut/agent-add/blob/main/src/utils/detect-hosts.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
</details>

# Host 适配器系统

## 概述

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

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

## 架构设计

### 核心组件

```mermaid
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` 接口，所有主机适配器必须实现此接口：

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

### 资产能力配置

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

### 资产类型枚举

| 类型 | 说明 | 用途 |
|------|------|------|
| `mcp` | MCP Server 配置 | 安装 MCP 服务器 |
| `skill` | Skill 目录 | 安装可复用技能包 |
| `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>` 类型的注册表，所有适配器在此注册后即可被系统识别和使用。

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

注册表示例结构：

```typescript
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 | 显示名称 | MCP | Prompt | Skill | Command | Sub-agent |
|---------|----------|-----|--------|-------|---------|-----------|
| cursor | Cursor | ✅ | ✅ | ✅ | ✅ | ✅ |
| claude-code | Claude Code | ✅ | ✅ | ✅ | ✅ | ✅ |
| claude-desktop | Claude Desktop | ✅ | ❌ | ❌ | ❌ | ❌ |
| windsurf | Windsurf | ✅ | ✅ | ❌ | ❌ | ❌ |
| github-copilot | GitHub Copilot | ✅ | ✅ | ❌ | ❌ | ❌ |
| gemini | Gemini Code | ✅ | ✅ | ❌ | ❌ | ❌ |
| roo-code | Roo Code | ✅ | ✅ | ❌ | ❌ | ❌ |
| kilo-code | Kilo Code | ✅ | ✅ | ❌ | ❌ | ❌ |
| qwen-code | Qwen Code | ✅ | ✅ | ❌ | ❌ | ❌ |
| opencode | OpenCode | ✅ | ✅ | ❌ | ❌ | ❌ |
| augment | Augment Code | ✅ | ✅ | ❌ | ❌ | ❌ |
| kiro | Kiro | ✅ | ✅ | ❌ | ❌ | ❌ |
| tabnine | Tabnine | ✅ | ✅ | ❌ | ❌ | ❌ |
| kimi | Kimi | ✅ | ✅ | ❌ | ❌ | ❌ |
| trae | Trae | ✅ | ✅ | ❌ | ❌ | ❌ |
| openclaw | OpenClaw | ✅ | ✅ | ❌ | ❌ | ❌ |
| codex | Codex CLI | ✅ | ✅ | ✅ | ❌ | ✅ |
| vibe | Vibe | ✅ | ❌ | ❌ | ❌ | ❌ |

## 主机检测机制

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

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

### 检测优先级

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

## 适配器实现示例

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

```typescript
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 配置的特殊处理：

```typescript
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` 接口：

```typescript
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.ts` 的 `hostRegistry` Map 中添加新条目：

```typescript
['xxx', new XxxAdapter()]
```

### 步骤 3：更新能力矩阵

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

### 步骤 4：添加单元测试

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

## 安装流程中的角色

```mermaid
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. **路径解析**：根据 `configFile` 或 `installDir` 确定写入路径
3. **策略选择**：根据 `writeStrategy` 选择对应的写入方式
4. **结果记录**：返回 `skipped`/`written`/`exists`/`updated`/`conflict`/`error` 等状态

## 不支持的资产处理

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

```typescript
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 环境必须显式指定 --host | [src/hosts/README.md:1]() |

## 总结

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

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

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

---

<a id='p-cli-ref'></a>

## CLI 参考文档

### 相关页面

相关主题：[核心功能使用指南](#p-usage), [安装与快速开始](#p-installation), [Pack Manifest 格式规范](#p-pack-manifest)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [src/index.ts](https://github.com/pea3nut/agent-add/blob/main/src/index.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
- [package.json](https://github.com/pea3nut/agent-add/blob/main/package.json)
</details>

# 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()` 创建程序实例并异步解析命令行参数。

```mermaid
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 接口定义输入输出的数据结构：

```typescript
interface CliInput {
  mcp: string[];
  skill: string[];
  prompt: string[];
  command: string[];
  subAgent: string[];
  pack: string[];
  host?: string;
}
```

| 属性 | 类型 | 描述 |
|------|------|------|
| `mcp` | `string[]` | MCP 服务器配置源列表 |
| `skill` | `string[]` | Skill 目录源列表 |
| `prompt` | `string[]` | Prompt 文件源列表 |
| `command` | `string[]` | Command 文件源列表 |
| `subAgent` | `string[]` | Sub-agent 文件源列表 |
| `pack` | `string[]` | 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>` | 指定目标宿主 ID | TTY 环境可选，CI 环境必填 |

支持的宿主 ID 包括：`cursor`、`claude-code`、`claude-desktop`、`windsurf`、`github-copilot`、`gemini`、`roo-code`、`kilo-code`、`qwen-code`、`opencode`、`augment`、`kiro`、`tabnine`、`kimi`、`trae`、`openclaw`、`codex`、`vibe`。

资料来源：[src/cli.ts:82]()
资料来源：[src/hosts/README.md]()

### 辅助选项

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

## 输入验证规则

### 资产标志检测

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

```typescript
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]()

### 宿主指定检测

```mermaid
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 环境检测逻辑：

```typescript
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 提供交互式宿主选择功能：

```typescript
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：

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

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

资料来源：[src/cli.ts:15-20]()

## 安装流程编排

### 安装执行

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

```typescript
const cwd = process.cwd();
const summary = await runInstaller(cliInput, host, cwd);
printSummary(summary);
```

- `cwd`：当前工作目录，作为相对路径解析的基准
- `cliInput`：解析后的 CLI 输入参数
- `host`：选定的宿主适配器实例

资料来源：[src/cli.ts:120-123]()

### 结果处理

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

```mermaid
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
```

错误检测逻辑：

```typescript
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 | 存在冲突或错误 | 需用户介入解决 |
| 2 | CLI 参数错误 | 无效参数或缺少必需参数 |

资料来源：[src/cli.ts:125-132]()

## 使用示例

### 基本安装

```bash
# 安装 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）

```bash
# 从 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 环境使用

```yaml
# .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 dev` | tsup watch 开发模式 | - |
| `npm test` | 运行 vitest 单元和集成测试 | - |
| `npm run test:contract` | 仅运行 CLI 黑盒契约测试 | - |

资料来源：[package.json:20-35]()

### CLI 入口点

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

```json
{
  "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.2 | YAML 文件解析（Skill/Command/Sub-agent） |
| `zod` | ^4.3.6 | 配置验证 |
| `smol-toml` | ^1.6.1 | TOML 文件读写（Codex/Vibe） |

资料来源：[package.json:30-45]()

## 模块关系图

```mermaid
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` 验证兼容性

---

<a id='p-pack-manifest'></a>

## Pack Manifest 格式规范

### 相关页面

相关主题：[资产开发者指南](#p-asset-dev), [CLI 参考文档](#p-cli-ref)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/manifest/parser.ts](https://github.com/pea3nut/agent-add/blob/main/src/manifest/parser.ts)
- [src/manifest/schema.ts](https://github.com/pea3nut/agent-add/blob/main/src/manifest/schema.ts)
- [vibe/manifest.json](https://github.com/pea3nut/agent-add/blob/main/vibe/manifest.json)
- [README.md](https://github.com/pea3nut/agent-add/blob/main/README.md)
- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
</details>

# Pack Manifest 格式规范

## 概述

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

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

## 核心数据结构

```json
{
  "name": "namespace/pack-name",
  "assets": [
    { "type": "<asset-type>", "source": "<source-uri>" }
  ]
}
```

| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `name` | string | 是 | 格式为 `namespace/pack-name`，命名空间与包名之间用斜杠分隔 |
| `assets` | array | 是 | 资产数组，至少包含 1 个元素 |

## name 字段规范

### 格式要求

Manifest 的 `name` 字段必须符合 `namespace/pack-name` 格式，其中：

- **命名空间（namespace）**：标识资产包的分发组织或作者
- **包名（pack-name）**：标识具体的资产包

### 字符限制

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

**示例：**

```json
{
  "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 值 | 说明 | 来源格式 |
|---------|------|----------|
| `mcp` | MCP Server 配置 | JSON 文件 |
| `skill` | Skill 目录 | 包含 SKILL.md 的目录 |
| `prompt` | Prompt/规则文件 | Markdown 文件 |
| `command` | 命令文件 | Markdown 文件 |
| `subAgent` | 子代理配置 | Markdown 文件 |

### source 字段

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

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

### 来源名称推断规则

资产名称（asset name）根据 `source` 字段自动推断：

```mermaid
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/pdf` → `pdf` |
| Git URL 无 `#` | 取仓库名，去 `.git` | `...playwright.git` → `playwright` |
| 本地路径/HTTP | 取文件名，去扩展名 | `./mcps/playwright.json` → `playwright` |
| 内联 JSON | 取顶层键名 | `{"playwright":{...}}` → `playwright` |
| 内联 Markdown | 取首个 `#` 标题，转 kebab-case | `# Code Review` → `code-review` |

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

## 完整示例

### 基础示例

```json
{
  "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 开发包：

```json
{
  "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]()

## 安装流程

### 处理流程

```mermaid
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`

#### 缺失字段处理

```typescript
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 进行运行时验证，关键规则包括：

| 规则 | 字段 | 错误信息 |
|------|------|----------|
| 必填 | `name` | Manifest missing required field: name |
| 格式 | `name` | Manifest name must match namespace/pack-name format |
| 必填 | `assets` | Manifest missing required field: assets |
| 非空 | `assets` | 至少包含 1 个元素 |
| 必填 | `assets[].type` | Manifest missing required field: assets[].type |
| 枚举 | `assets[].type` | Unsupported asset type: '<value>' |
| 必填 | `assets[].source` | Manifest 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 中，减少分发复杂度

## 参考资料

- [Manifest 解析器实现](src/manifest/parser.ts)
- [Manifest Schema 定义](src/manifest/schema.ts)
- [名称推断逻辑](src/source/infer-name.ts)
- [安装器核心逻辑](src/installer.ts)
- [vibe 开发包示例](vibe/manifest.json)

---

<a id='p-asset-dev'></a>

## 资产开发者指南

### 相关页面

相关主题：[Pack Manifest 格式规范](#p-pack-manifest), [源格式与名称推断](#p-source-formats)

<details>
<summary>相关源码文件</summary>

以下源码文件用于生成本页说明：

- [src/source/infer-name.ts](https://github.com/pea3nut/agent-add/blob/main/src/source/infer-name.ts)
- [src/installer.ts](https://github.com/pea3nut/agent-add/blob/main/src/installer.ts)
- [src/hosts/types.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/types.ts)
- [src/hosts/codex.ts](https://github.com/pea3nut/agent-add/blob/main/src/hosts/codex.ts)
- [src/cli.ts](https://github.com/pea3nut/agent-add/blob/main/src/cli.ts)
- [README.md](https://github.com/pea3nut/agent-add/blob/main/README.md)
</details>

# 资产开发者指南

## 概述

资产开发者指南是 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 支持的资产类型及其核心特征如下：

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

## MCP 配置文件规范

### 支持的 JSON 格式

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

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

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

```json
{
  "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/pdf` → `pdf` |
| Git URL 无 `#path` | 取仓库名（去除 `.git` 后缀） | `...playwright.git` → `playwright` |
| 本地路径/HTTP URL | 取文件名（去除扩展名） | `./mcps/playwright.json` → `playwright` |

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

### 验证规则

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

1. **文件存在性检查**：MCP 来源文件必须存在于本地路径
2. **扩展名验证**：文件扩展名必须为 `.json`
3. **来源类型限制**：`http-file`、`inline-json`、`inline-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 # 可选：模板文件
```

```markdown
<!-- SKILL.md -->
---
name: my-skill
description: A reusable agent skill.
---

# Skill: my-skill

This skill does something useful.
```

整个目录会被递归复制到主机的技能目录（如 `.cursor/skills/my-skill/`）。资料来源：[README.md:85-96]()

### 验证规则

Skill 资产具有最严格的来源限制：

```typescript
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}）`;
  }
}
```

Skill 资产**必须**使用目录来源（本地路径或 Git URL），不支持内联内容或直接的 HTTP(S) URL 下载。资料来源：[src/installer.ts:56-65]()

### 主机适配差异

不同主机的 Skill 安装路径和策略不同：

```typescript
skill: {
  supported: true,
  installDir: '.codex/skills/',
  entryFile: 'SKILL.md',
  writeStrategy: 'copy-file',
}
```

Codex 适配器将 Skill 安装到 `.codex/skills/` 目录，使用 `copy-file` 写入策略。资料来源：[src/hosts/codex.ts:28-31]()

## Prompt 资产规范

### 格式要求

Prompt 是纯 Markdown 文件，无特殊格式要求：

```markdown
# Code Review Rules

Always review for security issues first.
Use bullet points for lists.
```

agent-add 自动根据主机选择写入策略。资料来源：[README.md:98-103]()

### 写入策略

#### 追加模式

Cursor、Claude Code 等主机使用追加模式，Content 被包装在 HTML 注释标记中并追加到文件，确保幂等性：

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

#### 独立文件模式

Windsurf、Roo Code 等主机使用独立文件模式，在规则目录中创建 `<name>.md` 文件：

```typescript
prompt: {
  supported: true,
  targetFile: 'AGENTS.md',
  writeStrategy: 'append-with-marker',
}
```

资料来源：[src/hosts/codex.ts:22-25]()

## Command 资产规范

### 格式要求

Command 文件支持可选的 YAML frontmatter：

```markdown
---
description: Run a comprehensive code review.
---

# code-review

Review the current file for bugs, security issues, and style violations.
```

安装到主机的 commands 目录（如 `.cursor/commands/code-review.md`）。资料来源：[README.md:133-139]()

## Sub-agent 资产规范

### 格式要求

Sub-agent 文件使用 Markdown + YAML frontmatter 格式，支持 **`agent-add/<host>/<key>` 主机特化语法**——单个文件可为不同主机提供不同的 frontmatter 字段值。资料来源：[README.md:141-154]()

### 主机特化示例

```markdown
---
name: playwright-tester
description: A playwright testing agent.
agent-add/cursor/model: fast
agent-get/claude-code/model: haiku
---

# Playwright Test Agent

Plan and generate Playwright tests.
```

安装过程中 agent-add 会：
1. **提升**匹配的 `agent-add/<host>/*` 值为顶层键
2. **移除**所有 `agent-add/*` 前缀的键

资料来源：[README.md:154-163]()

## Pack 清单规范

### 文件格式

Pack 是一个 JSON 文件，捆绑多个资产用于分发：

```json
{
  "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" }
  ]
}
```

### 字段规范

| 字段 | 必填 | 描述 |
|------|------|------|
| `name` | 是 | 格式 `namespace/pack-name`，仅允许 `[a-zA-Z0-9_-]` |
| `assets` | 是 | 至少 1 个元素 |
| `assets[].type` | 是 | `mcp` \| `skill` \| `prompt` \| `command` \| `subAgent` |
| `assets[].source` | 是 | 来源路径、URL 或内联内容 |

### CLI 安装方式

```bash
npx -y agent-add --host cursor --pack 'https://github.com/anthropics/skills.git#skills/webapp-testing'
```

多个 pack 可以与显式标志自由组合使用：

```bash
npx -y agent-add --host cursor \
  --pack './my-pack.json' \
  --mcp './mcps/playwright.json'
```

资料来源：[src/cli.ts:22-33]()

## 来源解析架构

### 解析流程

```mermaid
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[摘要输出]
```

### 解析类型判定

| 源格式 | 检测规则 | 解析类型 |
|--------|---------|---------|
| 以 `{` 开头 | JSON 解析 | `inline-json` |
| 包含 `\n` | 非 JSON | `inline-md` |
| Git URL 含 `#path` | 路径提取 | `git-file` 或 `git-dir` |
| 本地路径 | 文件系统访问 | `local-file` 或 `local-dir` |
| HTTP(S) URL | 网络请求 | `http-file` |

`inline-json` 仅适用于 MCP 资产，`inline-md` 仅适用于 Prompt/Command/Sub-agent。资料来源：[vibe/system-prompt.md:22-24]()

## 关键设计决策

### 原子 JSON 写入

MCP 配置使用临时文件 + 重命名的策略确保写入安全：

```typescript
// mcp.ts 使用 temp file + rename
await fs.promises.writeFile(tempPath, JSON.stringify(config, null, 2));
await fs.promises.rename(tempPath, configFile);
```

资料来源：[vibe/system-prompt.md:18]()

### 标记块幂等追加

Prompt 的 `append-with-marker` 策略使用 `<!-- agent-add:<name> -->` HTML 注释确保幂等性：

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

重复安装不会导致内容重复追加。资料来源：[vibe/system-prompt.md:19]()

### 显式标志拒绝

`installer.ts` 在构建任务前检查显式标志能力声明。`supported: false` 会输出错误信息和 README 链接并以退出码 2 终止。`--pack` 来源不受此检查约束。资料来源：[vibe/system-prompt.md:21]()

### 非 TTY 严格模式

CI 环境必须显式指定 `--host`，否则以退出码 2 终止。这确保自动化环境中不会误用默认主机。资料来源：[vibe/system-prompt.md:23]()

## 主机能力矩阵

添加新主机适配器时，必须遵循以下贡献流程：

1. **创建适配器文件**：`src/hosts/<id>.ts`
   - 导出实现 `HostAdapter` 接口的类
   - 硬编码所有配置字段
   - 对不支持的资产类型使用 `NOT_SUPPORTED(reason)` 辅助函数

2. **注册到 index.ts**：将 `['<id>', new XxxAdapter()]` 添加到 `src/hosts/index.ts` 的 `hostRegistry` Map

3. **更新 README**：在能力矩阵表中添加行，并在详情区添加新主机段

4. **添加单元测试**：创建 `tests/unit/hosts/<id>.test.ts`，验证每个字段值与 README 完全一致

```typescript
export class CodexAdapter implements HostAdapter {
  readonly id = 'codex';
  readonly displayName = 'Codex CLI';
  readonly docs = 'https://github.com/openai/codex';
  readonly detection = { paths: ['~/.codex/'] };
  readonly assets: Record<AssetType, AssetCapability> = {
    mcp: {
      supported: true,
      configFile: { darwin: '~/.codex/config.toml', ... },
      configKey: 'mcp_servers',
      writeStrategy: 'inject-json-key',
    },
    // ...
  };
}
```

资料来源：[src/hosts/codex.ts:1-45](), [src/hosts/README.md:350-365]()

## 快速参考

### 常用安装命令

```bash
# MCP 服务器
npx -y agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#.mcp.json'

# Skill 目录
npx -y agent-add --host cursor --skill 'https://github.com/anthropics/skills.git#skills/webapp-testing'

# Prompt 规则
npx -y agent-add --host claude-code --prompt 'https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs-react-tailwind/.cursorrules'

# 斜杠命令
npx -y agent-add --host cursor --command 'https://github.com/wshobson/commands.git#tools/security-scan.md'

# 子代理
npx -y agent-add --host cursor --sub-agent 'https://github.com/VoltAgent/awesome-claude-code-subagents.git#categories/01-core-development/backend-developer.md'
```

### 退出码规范

| 退出码 | 含义 |
|-------|------|
| 0 | 安装成功，无冲突 |
| 1 | 存在冲突或错误 |
| 2 | 参数错误或不支持的资产类型 |

资料来源：[src/cli.ts:41-46]()

---

---

## Doramagic 踩坑日志

项目：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

<!-- canonical_name: pea3nut/agent-add; human_manual_source: deepwiki_human_wiki -->
