Doramagic Project Pack · Human Manual
agent-add
Related topics: Getting Started, System Architecture
Introduction
Related topics: Getting Started, System Architecture
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Getting Started, System Architecture
Introduction
agent-add is a unified CLI tool that streamlines the installation and management of AI coding agent assets across multiple host environments. It eliminates the need to manually configure MCP servers, skills, prompts, commands, and sub-agents by automating asset discovery, validation, and deployment to the appropriate host-specific directories.
Purpose and Scope
agent-add addresses the fragmented ecosystem of AI coding assistants by providing a single command-line interface that works with 18 different host environments. Rather than maintaining separate installation instructions for Cursor, Claude Code, Windsurf, and other tools, developers and asset distributors can use agent-add to distribute assets universally.
Core capabilities include:
- Asset Installation: Install MCP servers, skills, prompts, commands, and sub-agents from local paths, Git URLs, or HTTP endpoints
- Host Abstraction: Automatic detection and adaptation for each host's unique configuration format and directory structure
- Pack Distribution: Bundle multiple assets into a single JSON manifest for team-wide distribution
- Atomic Operations: Safe file writes using temp file + rename patterns to prevent corruption
- Idempotent Updates: Marker-based append strategy ensures repeated installations do not create duplicates
Sources: README.md:1-50
Supported Hosts
agent-add supports the following 18 AI coding host environments:
| Host ID | Configuration Format | Install Directory |
|---|---|---|
cursor | JSON | .cursor/ |
claude-code | JSON | .claude/ |
claude-desktop | JSON | ~/Library/Application Support/Claude/ |
windsurf | JSON | .windsurf/rules/ |
github-copilot | JSON | .github/copilot/ |
gemini | JSON | .gemini/ |
roo-code | JSON | .roo/rules/ |
kilo-code | JSON | .kilocode/ |
qwen-code | JSON | .qwen/ |
opencode | JSON | .opencode/ |
augment | JSON | .augment/ |
kiro | JSON | .kiro/ |
tabnine | JSON | .tabnine/ |
kimi | JSON | .kimi/ |
trae | JSON | .trae/ |
openclaw | JSON | .openclaw/ |
codex | TOML | .codex/ |
vibe | TOML | .vibe/ |
Sources: vibe/system-prompt.md:30-35
Supported Asset Types
agent-add manages five distinct asset types, each with host-specific installation strategies:
| Asset Type | Description | Install Behavior |
|---|---|---|
mcp | Model Context Protocol server configurations | JSON shallow merge or TOML array append |
skill | Reusable agent skill directories | Recursive directory copy |
prompt | System prompts or rule files | Append-with-marker or create-file-in-dir |
command | Slash commands | Create in commands directory |
subAgent | Sub-agent configurations | Create in agents directory |
Sources: src/installer.ts:1-50
Architecture Overview
The codebase follows a layered architecture pattern with clear separation of concerns:
graph TD
A[CLI Input] --> B[CLI Parser<br/>src/cli.ts]
B --> C[Installer Core<br/>src/installer.ts]
C --> D[Source Resolution<br/>src/source/]
D --> E[Validation]
E --> F[Host Adapter<br/>src/hosts/]
F --> G[Asset Handler<br/>src/assets/]
G --> H[Filesystem]
I[Pack Manifest] -.-> C
J[18 Host Adapters] -.-> F
K[5 Asset Handlers] -.-> GLayer responsibilities:
| Layer | Module | Responsibility |
|---|---|---|
| Input | src/cli.ts | Commander.js argument parsing, TTY detection, interactive host selection |
| Core | src/installer.ts | Orchestration: input parsing → capability check → source resolution → validation → handler execution → summary |
| Resolution | src/source/ | Local file access, Git URL handling, HTTP fetching, inline content parsing |
| Adaptation | src/hosts/ | Host-specific directory paths, capability declarations, write strategies |
| Execution | src/assets/ | Type-specific installation logic (MCP merge, skill copy, prompt append, etc.) |
Sources: vibe/system-prompt.md:45-65
Core Data Flow
The installation pipeline follows a sequential process from CLI invocation to filesystem write:
graph LR
A[CLI flags / --pack Manifest] --> B[Explicit flag capability check<br/>exit 2 if unsupported]
B --> C[AssetDescriptor[]<br/>type + source]
C --> D[ResolvedSource[]<br/>localPath + tempDir]
D --> E[InstallJob[]<br/>skip unsupported assets]
E --> F[InstallResult[]<br/>written / exists / updated / conflict / skipped / error]
F --> G[Summary output]Processing stages:
- Input Collection: Gather all asset sources from CLI flags and pack manifests
- Capability Validation: Verify each asset type is supported by the target host (exit 2 if explicit flag unsupported)
- Source Resolution: Convert sources to local file paths (git clone, http download, inline temp files)
- Asset Validation: Validate file existence, format compliance, and required metadata
- Job Creation: Build installation jobs, skipping assets with unsupported capabilities
- Execution: Dispatch to appropriate asset handler based on type
- Result Reporting: Output summary with status for each asset
Sources: src/cli.ts:1-80
Write Strategies
Different asset types use different write strategies based on host capabilities:
graph TD
A[Asset Type] --> B{Write Strategy}
B --> C[append-with-marker]
B --> D[create-file-in-dir]
B --> E[atomic-json-merge]
B --> F[directory-copy]
C --> G[HTML comment markers<br/><!-- agent-add:name -->]
D --> H[Create new file<br/>Skip if exists]
E --> I[Temp file + rename<br/>JSON shallow merge]
F --> J[Recursive copy<br/>SKILL.md required]| Strategy | Used By | Behavior |
|---|---|---|
append-with-marker | Prompt (Cursor, Claude Code) | Wraps content in HTML comment markers, idempotent append |
create-file-in-dir | Prompt (Windsurf, Roo Code), Command, Sub-agent | Creates <name>.md in rules/commands/agents directory |
atomic-json-merge | MCP (JSON hosts) | Shallow merge with temp file + rename for safety |
toml-array-append | MCP (Codex, Vibe) | Append to [[mcp_servers]] array |
directory-copy | Skill | Recursive copy to host's skills directory |
Sources: src/installer.ts:50-120
Source Resolution
agent-add accepts assets from multiple source types with automatic detection:
| Source Format | Example | Name Inference |
|---|---|---|
Git URL + #path | https://github.com/user/repo.git#skills/pdf | Last segment after # (strip extension) |
Git URL without # | https://github.com/user/playwright.git | Repo name (strip .git) |
| Local path | ./mcps/playwright.json | Filename (strip extension) |
| HTTP URL | https://example.com/config.json | Filename (strip extension) |
| Inline JSON | {"playwright":{...}} | Top-level key as name |
| Inline Markdown | # Code Review\n\nRules... | First # Heading in kebab-case |
Sources: src/source/infer-name.ts:1-50
Installation and Usage
Quick Install
# Install a single MCP server
npx -y agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#mcp/playwright'
# Install multiple assets
npx -y agent-add --host cursor \
--mcp './configs/mcp.json' \
--skill './skills/pdf' \
--prompt './rules/code-review.md'
# Install from a pack manifest
npx -y agent-add --host claude-code --pack './manifests/frontend-pack.json'
CLI Options
| Flag | Description | Can Repeat |
|---|---|---|
--host <id> | Target host ID (required in CI, optional in TTY) | No |
--pack <source> | Install from a pack manifest | Yes |
--mcp <source> | Install MCP server configuration | Yes |
--skill <source> | Install skill directory | Yes |
--prompt <source> | Install prompt/rule file | Yes |
--command <source> | Install slash command | Yes |
--sub-agent <source> | Install sub-agent file | Yes |
Sources: src/cli.ts:40-60
Key Design Decisions
The architecture reflects several intentional design choices:
Atomic JSON Writes: MCP configuration uses temp file + rename pattern to prevent corruption from interrupted writes. Sources: vibe/system-prompt.md:70-72
Marker-Based Idempotency: Prompt append mode uses <!-- agent-add:<name> --> HTML comment markers, ensuring repeated installations update existing blocks rather than creating duplicates.
Explicit Flag Rejection: When using explicit flags like --mcp, agent-add validates host capability and exits with code 2 if unsupported. Pack sources skip unsupported assets silently instead.
Non-TTY Strict Mode: CI environments must explicitly specify --host to prevent ambiguous behavior in automated pipelines.
Inline Content Support: Prompt/Command/Sub-agent assets support inline content via newline detection, while MCP supports inline JSON via brace detection. HTTP and inline sources are explicitly rejected for Skill type assets.
Sources: src/installer.ts:80-100
Project Structure
agent-add/
├── bin/
│ └── agent-add.js # Compiled entry point
├── src/
│ ├── index.ts # Main entry, program creation
│ ├── cli.ts # Commander definition + TTY detection
│ ├── installer.ts # Orchestration core
│ ├── hosts/ # Host adapter layer (18 hosts)
│ │ ├── types.ts # HostAdapter, AssetCapability types
│ │ ├── index.ts # Host registry (Map<id, HostAdapter>)
│ │ └── <id>.ts # Per-host adapter implementations
│ ├── assets/ # 5 asset type handlers
│ │ ├── mcp.ts # JSON/TOML MCP handling
│ │ ├── skill.ts # Directory copy + validation
│ │ ├── prompt.ts # Append or create-file strategy
│ │ ├── command.ts # Command file creation
│ │ └── subAgent.ts # Sub-agent file creation
│ ├── source/ # Source resolution
│ │ ├── infer-name.ts # Asset name inference
│ │ └── expand-directory.ts # Directory expansion
│ ├── manifest/ # Pack manifest handling
│ │ └── parser.ts # Zod schema validation
│ └── utils/ # Shared utilities
│ └── unwrap-mcp-servers.ts
├── tests/
│ ├── unit/ # Unit tests per module
│ ├── features/ # Gherkin scenario tests
│ └── fixtures/ # Static test fixtures
└── vibe/ # Development assets
├── manifest.json # Dev pack manifest
└── tasks/ # AI task definitions
Sources: README.md:80-100
Development
# Setup
npm install
npm run build
# Run tests
npm test # All unit + integration tests
npm run test:contract # CLI black-box contract tests only
npx vitest run tests/unit/hosts/cursor.test.ts # Single file
# Run scenario tests (Gherkin)
# Use /scenario-exec command in your AI tool:
/scenario-exec tests/features/core
/scenario-exec tests/features/host
Sources: README.md:100-120
Sources: README.md:1-50
Getting Started
Related topics: Introduction, CLI Interface
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Introduction, CLI Interface
Getting Started
Overview
agent-add is a CLI tool that automates the installation of AI agent assets—including MCP servers, skills, prompts, commands, and sub-agents—across 18 different AI coding assistant hosts. It provides a unified interface for installing community assets from Git repositories, local paths, HTTP URLs, or inline content.
The tool handles host-specific installation logic, validates assets before installation, and supports batch installation via pack manifests. Sources: src/index.ts:1-7
Prerequisites
- Node.js: v18 or later
- npm or pnpm for package management
- Access to the target host's configuration directory
Installation
Using npx (Recommended for One-time Use)
npx -y agent-add --help
Global Installation
npm install -g agent-add
# or
pnpm add -g agent-add
Local Installation
npm install
npm run build
The CLI entry point is located at bin/agent-add.js. Sources: README.md
Basic Usage
Interactive Mode
When run in a TTY environment without specifying a host, agent-add prompts for target selection:
npx -y agent-add
The CLI detects available hosts in the current directory and presents an interactive selection menu. Sources: src/cli.ts:56-77
Non-interactive Mode
In CI environments or when a host must be specified explicitly:
npx -y agent-add --host <host-id> [asset-flags...]
If --host is omitted in non-TTY environments, the CLI exits with error code 2. Sources: src/cli.ts:46-55
Supported Hosts
The following 18 hosts are supported:
| Host ID | Type | Notes |
|---|---|---|
cursor | JSON | Cursor IDE |
claude-code | Markdown | Claude Code CLI |
claude-desktop | JSON | Claude Desktop |
windsurf | JSON | Windsurf IDE |
github-copilot | JSON | GitHub Copilot |
gemini | JSON | Google Gemini |
roo-code | JSON | Roo Code |
kilo-code | JSON | Kilo Code |
qwen-code | JSON | Qwen Code |
opencode | JSON | OpenCode |
augment | JSON | Augment |
kiro | JSON | Kiro |
tabnine | JSON | Tabnine |
kimi | JSON | Kimi |
trae | JSON | Trae |
openclaw | JSON | OpenClaw |
codex | TOML | Codex |
vibe | TOML | Vibe |
Sources: README.md
Asset Types
1. MCP Server
Installs Model Context Protocol server configurations.
agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#mcp/playwright'
2. Skill
Installs reusable agent skill directories containing SKILL.md.
agent-add --host cursor --skill './my-skill'
agent-add --host cursor --skill 'https://github.com/anthropics/skills.git#skills/webapp-testing'
Note: Skills must target directory sources (local paths or Git URLs). Inline content or direct HTTP(S) URLs are not supported. Sources: src/installer.ts:80-84
3. Prompt
Installs system prompts or rule files.
agent-add --host claude-code --prompt 'https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs-react-tailwind/.cursorrules'
4. Command
Installs slash commands for AI assistants.
agent-add --host cursor --command 'https://github.com/wshobson/commands.git#tools/security-scan.md'
5. Sub-agent
Installs specialized agent configurations.
agent-add --host cursor --sub-agent 'https://github.com/VoltAgent/awesome-claude-code-subagents.git#categories/01-core-development/backend-developer.md'
Source Specification
agent-add supports multiple source types for each asset:
| Source Type | Syntax Example | Name Inference |
|---|---|---|
| Git URL with path | ...git#skills/pdf | Last segment after #, stripped extension |
| Git URL without path | ...playwright.git | Repository name (strip .git) |
| Local path | ./mcps/playwright.json | Filename (strip extension) |
| HTTP URL | https://example.com/config.json | Filename (strip extension) |
| Inline JSON | {"playwright":{...}} | Single top-level key |
| Inline Markdown | # Heading\nContent | First # Heading, kebab-cased |
Sources: src/source/infer-name.ts:1-41
Pack Manifests
Bundles multiple assets for distribution via a JSON manifest:
{
"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" }
]
}
Install with:
agent-add --host cursor --pack './my-pack.json'
Pack names must follow namespace/pack-name format with only [a-zA-Z0-9_-] characters. Sources: src/manifest/parser.ts:1-31
Workflow Diagram
graph TD
A[CLI Input] --> B{Source Type Detection}
B -->|Git URL| C[Clone to temp]
B -->|Local Path| D[Resolve absolute path]
B -->|HTTP URL| E[Download to temp]
B -->|Inline| F[Write temp file]
C --> G[Validate Asset]
D --> G
E --> G
F --> G
G -->|Invalid| H[Exit 2 with error]
G -->|Valid| I{Check Host Capability}
I -->|Unsupported| J[Skip asset]
I -->|Supported| K[Install to Host]
K --> L[Print Summary]
J --> LExit Codes
| Code | Meaning |
|---|---|
| 0 | Success (all assets installed or already up-to-date) |
| 1 | Partial failure (conflicts or errors occurred) |
| 2 | Fatal error (invalid input, missing host, validation failure) |
Sources: src/cli.ts:27-34
Examples
Install MCP Server from GitHub
npx -y agent-add --host cursor --mcp 'https://github.com/modelcontextprotocol/servers.git#mcp/playwright'
Install Multiple Assets
agent-add --host claude-code \
--mcp 'https://github.com/modelcontextprotocol/servers.git#mcp/playwright' \
--prompt 'https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/nextjs-react-tailwind/.cursorrules' \
--command 'https://github.com/wshobson/commands.git#tools/security-scan.md'
Install Pack Manifest
agent-add --host cursor --pack 'https://github.com/VoltAgent/awesome-claude-code-subagents.git#manifests/backend-dev.json'
Inline MCP Configuration
agent-add --host cursor --mcp '{"playwright":{"command":"npx","args":["@playwright/mcp@latest"]}}'
Directory Expansion
For directories containing multiple assets, agent-add automatically expands them:
agent-add --host cursor --mcp './mcp-servers/'
Each .json file in the directory becomes a separate MCP asset. For skills, it scans for subdirectories containing SKILL.md. Sources: src/source/expand-directory.ts:1-43
Validation
Before installation, agent-add validates:
- MCP: File must exist and have
.jsonextension - Skill: Directory must contain
SKILL.md; cannot use inline or HTTP sources - Prompt/Command/Sub-agent: File must exist
Sources: src/installer.ts:78-107
Next Steps
- Review the Asset Developer Guide for creating distributable assets
- Explore the Host Adapter Architecture for adding new hosts
- Run
agent-add --helpfor complete CLI reference
Sources: README.md
System Architecture
Related topics: Host Integration, Source Resolution
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Host Integration, Source Resolution
System Architecture
agent-add is a cross-host AI agent pack installer CLI tool that enables developers to install MCP (Model Context Protocol), Skill, Prompt, Command, and Sub-agent assets into various AI agent hosts with a single command. The system is built with TypeScript 5.x in strict mode, targeting Node.js 18+ as a CommonJS bundle.
Overview
The architecture follows a layered, pipeline-based design that separates concerns between CLI interface, orchestration logic, host adapters, and asset handlers. The system is stateless—no install state files are maintained—relying instead on filesystem-based idempotency checks.
graph TD
subgraph CLI["CLI Layer"]
CLI_ENTRY["src/index.ts<br/>Entry Point"]
CLI_CMD["src/cli.ts<br/>Commander + TTY Detection"]
end
subgraph Core["Core Pipeline"]
INST["src/installer.ts<br/>Orchestration Core"]
VALIDATE["Validation Layer"]
RESOLVE["src/source/index.ts<br/>Source Resolution"]
end
subgraph Adapters["Host Adapter Layer"]
REGISTRY["src/hosts/index.ts<br/>Host Registry"]
CURSOR["cursor.ts"]
CLAUDE_CODE["claude-code.ts"]
VIBE["vibe.ts"]
CODEX["codex.ts"]
end
subgraph Handlers["Asset Handler Layer"]
MCP["assets/mcp.ts"]
SKILL["assets/skill.ts"]
PROMPT["assets/prompt.ts"]
COMMAND["assets/command.ts"]
SUBAGENT["assets/sub-agent.ts"]
end
CLI_ENTRY --> CLI_CMD
CLI_CMD --> INST
INST --> VALIDATE
INST --> RESOLVE
RESOLVE --> REGISTRY
REGISTRY --> CURSOR
REGISTRY --> CLAUDE_CODE
REGISTRY --> VIBE
REGISTRY --> CODEX
INST --> MCP
INST --> SKILL
INST --> PROMPT
INST --> COMMAND
INST --> SUBAGENTSources: src/index.ts:1-7
Directory Structure
agent-add/
├── src/
│ ├── index.ts # Entry point
│ ├── cli.ts # Commander definition + TTY detection
│ ├── installer.ts # Orchestration core
│ ├── hosts/ # Host adapter layer
│ │ ├── index.ts # Host registry (Map<id, HostAdapter>)
│ │ ├── types.ts # HostAdapter, AssetCapability, WriteStrategy
│ │ ├── README.md # Capability matrix (single source of truth)
│ │ └── <id>.ts # Per-host adapter (18 hosts)
│ ├── assets/ # Asset type handlers
│ │ ├── mcp.ts # JSON shallow merge + atomic write
│ │ ├── skill.ts # Directory copy + SKILL.md validation
│ │ ├── prompt.ts # Marker append or create-file-in-dir
│ │ ├── command.ts # Command file handler
│ │ └── sub-agent.ts # Sub-agent with host specialization
│ └── source/ # Source resolution system
│ ├── index.ts # Source resolution entry
│ ├── infer-name.ts # Asset name inference
│ ├── local.ts # Local file resolution
│ ├── git.ts # Git URL cloning
│ └── http.ts # HTTP/HTTPS download
├── tests/
│ ├── unit/ # Unit tests (vitest)
│ ├── integration/ # Integration tests
│ ├── features/ # Gherkin scenario tests
│ └── fixtures/ # Static test fixtures
└── dist/ # Built output
Sources: README.md:1-45
Core Data Flow
The installation pipeline follows a strict sequential flow from CLI input to final installation result:
graph LR
A["CLI Flags /<br/>--pack Manifest"] --> B["Explicit Flag<br/>Capability Check"]
B --> C["AssetDescriptor[]<br/>(type + source)"]
C --> D["ResolvedSource[]<br/>(localPath + tempDir)"]
D --> E["InstallJob[]<br/>(skip unsupported)"]
E --> F["InstallResult[]<br/>(written/exists/updated/<br/>conflict/skipped/error)"]
F --> G["Summary Output"]Pipeline Stages
| Stage | Input | Output | Key Operations |
|---|---|---|---|
| CLI Parsing | process.argv | CliInput object | TTY detection, host selection |
| Capability Check | CliInput | AssetDescriptor[] | Validates --host exists, checks explicit flags against host capabilities |
| Source Resolution | AssetDescriptor[] | ResolvedSource[] | Downloads Git/HTTP, extracts archives, writes inline sources to temp |
| Job Creation | ResolvedSource[] | InstallJob[] | Filters assets unsupported by target host |
| Handler Execution | InstallJob[] | InstallResult[] | Writes files using host-specific strategies |
| Summary | InstallResult[] | Console output | Formatted install summary |
Sources: src/installer.ts:1-200
Host Adapter Layer
The host adapter layer provides a unified interface for interacting with different AI agent hosts. Each host has specific capabilities, installation paths, and write strategies.
Host Registry
The src/hosts/index.ts file maintains a Map<string, HostAdapter> that maps host IDs to their adapter implementations:
const hostRegistry = new Map<string, HostAdapter>([
['cursor', new CursorAdapter()],
['claude-code', new ClaudeCodeAdapter()],
['claude-desktop', new ClaudeDesktopAdapter()],
['windsurf', new WindsurfAdapter()],
['github-copilot', new GitHubCopilotAdapter()],
['gemini', new GeminiAdapter()],
['roo-code', new RooCodeAdapter()],
['kilo-code', new KiloCodeAdapter()],
['qwen-code', new QwenCodeAdapter()],
['opencode', new OpenCodeAdapter()],
['augment', new AugmentAdapter()],
['kiro', new KiroAdapter()],
['tabnine', new TabnineAdapter()],
['kimi', new KimiAdapter()],
['trae', new TraeAdapter()],
['openclaw', new OpenClawAdapter()],
['codex', new CodexAdapter()],
['vibe', new VibeAdapter()],
]);
Sources: src/hosts/index.ts Sources: src/hosts/README.md:1-100
Supported Hosts
| Host ID | MCP | Prompt | Skill | Command | Sub-agent | Config Format |
|---|---|---|---|---|---|---|
| cursor | ✅ | ✅ | ✅ | ✅ | ✅ | JSON |
| claude-code | ✅ | ✅ | ❌ | ❌ | ❌ | JSON |
| claude-desktop | ✅ | ❌ | ❌ | ❌ | ❌ | JSON |
| windsurf | ✅ | ✅ | ✅ | ❌ | ❌ | JSON |
| github-copilot | ✅ | ❌ | ❌ | ❌ | ❌ | JSON |
| codex | ✅ | ✅ | ❌ | ❌ | ❌ | TOML |
| vibe | ✅ | ✅ | ❌ | ❌ | ❌ | TOML |
Sources: src/hosts/README.md:1-150
HostAdapter Interface
Each host adapter implements the HostAdapter interface with asset-specific capabilities:
interface HostAdapter {
readonly id: string;
readonly displayName: string;
readonly docs: string;
readonly assets: Record<AssetType, AssetCapability>;
}
interface AssetCapability {
supported: boolean;
reason?: string;
configFile?: string;
installDir?: string;
writeStrategy?: WriteStrategy;
baseRulesFile?: string;
}
Sources: src/hosts/types.ts
Write Strategies
The system supports different write strategies for different asset types and hosts:
| Strategy | Description | Used By |
|---|---|---|
append-with-marker | Appends content wrapped in HTML comment markers (<!-- agent-add:name -->) | Cursor, Claude Code |
create-file-in-dir | Creates standalone <name>.md file in rules directory | Windsurf, Roo Code, Kilo Code |
json-merge | Shallow JSON merge for MCP config | Most hosts |
toml-merge | TOML merge for Codex/Vibe | codex, vibe |
Sources: src/hosts/types.ts Sources: src/assets/prompt.ts Sources: src/assets/mcp.ts
Asset Handler Layer
Each asset type has a dedicated handler that implements the AssetHandler interface:
graph TD
H["InstallJob"] --> MCP["MCP Handler"]
H --> SKILL["Skill Handler"]
H --> PROMPT["Prompt Handler"]
H --> COMMAND["Command Handler"]
H --> SUBAGENT["Sub-agent Handler"]
MCP --> MCP_WRITE["Atomic JSON/TOML Write"]
SKILL --> SKILL_COPY["Directory Copy + Validation"]
PROMPT --> PROMPT_STRAT["Marker Append or Create File"]
COMMAND --> COMMAND_WRITE["YAML Frontmatter Parse"]
SUBAGENT --> SUB_WRITE["Host Specialization Processing"]MCP Handler
The MCP handler supports both JSON and TOML formats with automatic format detection:
- JSON format A (inner config): Single server without wrapper
- JSON format B (full config): With
mcpServerswrapper - TOML format: Auto-detected by
.tomlextension
Key behavior:
- Shallow merge for existing configurations
- Atomic write using temp file + rename pattern
- TOML auto-dispatches for Codex and Vibe hosts
Sources: src/assets/mcp.ts Sources: README.md:50-80
Skill Handler
The Skill handler installs entire skill directories:
- Recursively copies directory contents to host's skills directory
- Validates
SKILL.mdexists within the source directory - Asset name becomes the subdirectory name under skills root
- Note: Does not support inline sources, HTTP URLs, or git subpaths
Sources: src/assets/skill.ts Sources: src/installer.ts:50-100
Prompt Handler
The Prompt handler supports two write strategies:
``html <!-- agent-add:code-review-rules --> # Code Review Rules ... <!-- /agent-add:code-review-rules --> ``
- Append Mode (Cursor, Claude Code): Content is wrapped in idempotent HTML markers
- Standalone File Mode (Windsurf, Roo Code): Creates
<name>.mdin rules directory
Sources: src/assets/prompt.ts Sources: README.md:80-120
Sub-agent Handler
The Sub-agent handler supports host specialization using YAML frontmatter:
Sources: src/index.ts:1-7
Host Integration
Related topics: System Architecture, Asset Types
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Asset Types
Host Integration
Overview
The Host Integration layer is the core abstraction in agent-add that enables cross-host compatibility. It provides a unified interface for installing assets (MCP servers, Skills, Prompts, Commands, and Sub-agents) across 18 different AI agent hosts including Cursor, Claude Code, Windsurf, and GitHub Copilot.
Each supported host has a dedicated adapter class that encapsulates:
- Host detection mechanisms
- Asset installation paths
- Configuration file formats
- Write strategies for different asset types
- Platform-specific considerations
This architecture allows agent-add to abstract away the complexities of each host's unique file system structure and configuration format, presenting a single CLI interface to end users.
Architecture
System Architecture
graph TD
subgraph "CLI Layer"
CLI[CLI Input Parsing]
end
subgraph "Core Engine"
INST[Installer]
VAL[Validator]
end
subgraph "Host Adapter Layer"
REG[Host Registry]
CA[Cursor Adapter]
CCA[Claude Code Adapter]
WA[Windsurf Adapter]
OHA[Other Host Adapters]
end
subgraph "Asset Handlers"
MCP[MCP Handler]
SKILL[Skill Handler]
PROMPT[Prompt Handler]
CMD[Command Handler]
SUB[Sub-agent Handler]
end
CLI --> INST
INST --> VAL
VAL --> REG
REG --> CA
REG --> CCA
REG --> WA
REG --> OHA
CA --> MCP
CA --> SKILL
CA --> PROMPT
CA --> CMD
CA --> SUB
CCA --> MCP
CCA --> SKILL
CCA --> PROMPT
CCA --> CMD
CCA --> SUBData Flow
sequenceDiagram
participant CLI as CLI Input
participant INST as Installer
participant HOST as Host Adapter
participant HAND as Asset Handler
participant FS as File System
CLI->>INST: Parse flags + --pack manifest
INST->>INST: Capability check
INST->>INST: Source resolution
INST->>INST: Asset validation
INST->>HOST: Get capabilities for asset type
HOST-->>INST: Return AssetCapability
INST->>INST: Create InstallJob[]
INST->>HAND: Execute install job
HAND->>FS: Write with strategy
FS-->>HAND: Confirm write
HAND-->>INST: InstallResult
INST->>INST: Format summary outputHostAdapter Interface
The HostAdapter interface defines the contract all host implementations must follow.
Interface Definition
// src/hosts/types.ts
export interface HostAdapter {
readonly id: string;
readonly displayName: string;
readonly docs: string;
readonly detection: {
paths: string[];
};
readonly assets: Record<AssetType, AssetCapability>;
}
Property Specification
| Property | Type | Description |
|---|---|---|
id | string | Unique identifier for the host (e.g., "cursor", "claude-code") |
displayName | string | Human-readable name (e.g., "Claude Code") |
docs | string | URL to official documentation |
detection.paths | string[] | Directory paths that indicate this host is active |
assets | Record<AssetType, AssetCapability> | Capability definitions for each asset type |
Sources: src/hosts/types.ts
AssetCapability Types
Each asset type has its own capability configuration within the host adapter.
AssetType Enum
// src/hosts/types.ts
export type AssetType = 'mcp' | 'skill' | 'prompt' | 'command' | 'subAgent';
Capability Structure
// src/hosts/types.ts
export interface AssetCapability {
supported: boolean;
reason?: string; // Required when supported=false
configFile?: ConfigFileSpec; // For MCP
configKey?: string; // For MCP
targetFile?: string; // For Prompt (append mode)
installDir?: string; // For Skill/Command/Sub-agent
entryFile?: string; // For Skill
fileExtension?: string; // For Command/Sub-agent
writeStrategy?: WriteStrategy; // Strategy for writing files
}
export interface ConfigFileSpec {
darwin?: string;
linux?: string;
win32?: string;
}
Supported Asset Types
| Asset Type | Purpose | Install Method |
|---|---|---|
mcp | Model Context Protocol servers | Modify config file (JSON or TOML) |
skill | Reusable agent skill directories | Copy directory recursively |
prompt | System prompts / rule files | Append or create standalone file |
command | Custom slash commands | Copy markdown file |
subAgent | Sub-agent configurations | Copy configuration file |
Sources: src/hosts/types.ts
Write Strategies
The writeStrategy property determines how assets are installed to the host's filesystem.
Strategy Types
| Strategy | Description | Supported Asset Types |
|---|---|---|
inject-json-key | Inject configuration into existing JSON/TOML file | MCP, Prompt (append mode) |
append-with-marker | Append content wrapped in HTML comment markers | Prompt |
copy-file | Copy file directly to target directory | Skill, Command, Sub-agent |
create-file-in-dir | Create file at installDir/<name>.md | Prompt (standalone mode) |
Marker Block Format
When using append-with-marker, content is wrapped in HTML comment markers for idempotent updates:
<!-- agent-add:code-review-rules -->
# Code Review Rules
Always review for security issues first.
<!-- /agent-add:code-review-rules -->
JSON Injection
The inject-json-key strategy performs shallow merging of MCP server configurations:
// Before
{ "mcpServers": { "existing-server": {} } }
// After (injecting playwright)
{ "mcpServers": { "existing-server": {}, "playwright": { "command": "npx", "args": ["@playwright/mcp@latest"] } } }
Host Registry
The host registry maps host IDs to their adapter instances.
classDiagram
class HostRegistry {
+hostRegistry: Map~string, HostAdapter~
+getHost(id: string): HostAdapter
+getValidHostIds(): string[]
}
class HostAdapter {
<<interface>>
+id: string
+displayName: string
+docs: string
+assets: Record~AssetType, AssetCapability~
}
HostRegistry --> HostAdapterRegistry Implementation
// src/hosts/index.ts
const hostRegistry = new Map<string, HostAdapter>([
['cursor', new CursorAdapter()],
['claude-code', new ClaudeCodeAdapter()],
['windsurf', new WindsurfAdapter()],
['github-copilot', new GitHubCopilotAdapter()],
// ... 14 more hosts
]);
Currently Supported Hosts
The system supports 18 hosts across multiple platforms:
| Host ID | Display Name | Config Format |
|---|---|---|
cursor | Cursor AI | JSON |
claude-code | Claude Code | JSON |
claude-desktop | Claude Desktop | JSON |
windsurf | Windsurf | TOML |
github-copilot | GitHub Copilot | JSON |
gemini | Google Gemini | JSON |
roo-code | Roo Code | JSON |
kilo-code | Kilo Code | JSON |
qwen-code | Qwen Code | JSON |
opencode | OpenCode | JSON |
augment | Augment Code | JSON |
kiro | Kiro | JSON |
tabnine | Tabnine | JSON |
kimi | Kimi | JSON |
trae | Trae | JSON |
openclaw | OpenClaw | JSON |
codex | Codex CLI | TOML |
vibe | Vibe | TOML |
Example Host Adapters
Claude Code Adapter
// src/hosts/claude-code.ts
export class ClaudeCodeAdapter implements HostAdapter {
readonly id = 'claude-code';
readonly displayName = 'Claude Code';
readonly docs = 'https://code.claude.com/docs/en';
readonly detection = {
paths: ['.claude/'],
};
readonly assets: Record<AssetType, AssetCapability> = {
mcp: {
supported: true,
configFile: '.mcp.json',
configKey: 'mcpServers',
writeStrategy: 'inject-json-key',
},
skill: {
supported: true,
installDir: '.claude/skills/',
entryFile: 'SKILL.md',
writeStrategy: 'copy-file',
},
prompt: {
supported: true,
targetFile: 'CLAUDE.md',
writeStrategy: 'append-with-marker',
},
command: {
supported: true,
installDir: '.claude/commands/',
fileExtension: '.md',
writeStrategy: 'copy-file',
},
subAgent: {
supported: true,
installDir: '.claude/agents/',
fileExtension: '.md',
writeStrategy: 'copy-file',
},
};
}
Sources: src/hosts/claude-code.ts
Cursor Adapter
// src/hosts/cursor.ts
export class CursorAdapter implements HostAdapter {
readonly id = 'cursor';
readonly displayName = 'Cursor';
readonly docs = 'https://www.cursor.com/docs';
readonly detection = {
paths: ['.cursor/'],
};
readonly assets: Record<AssetType, AssetCapability> = {
mcp: {
supported: true,
configFile: {
darwin: '~/Library/Application Support/Cursor/config/mcp.json',
linux: '~/.config/Cursor/config/mcp.json',
win32: '%APPDATA%\\Cursor\\config\\mcp.json',
},
configKey: 'mcpServers',
writeStrategy: 'inject-json-key',
},
skill: {
supported: true,
installDir: '.cursor/skills/',
entryFile: 'SKILL.md',
writeStrategy: 'copy-file',
},
prompt: {
supported: true,
targetFile: 'AGENTS.md',
writeStrategy: 'append-with-marker',
},
command: {
supported: true,
installDir: '.cursor/commands/',
fileExtension: '.md',
writeStrategy: 'copy-file',
},
subAgent: {
supported: true,
installDir: '.cursor/agents/',
fileExtension: '.md',
writeStrategy: 'copy-file',
},
};
}
Sources: src/hosts/cursor.ts
Unsupported Assets
Hosts that don't support certain asset types use the NOT_SUPPORTED helper:
// src/hosts/github-copilot.ts
const NOT_SUPPORTED = (reason: string): AssetCapability => ({
supported: false,
reason,
});
export class GitHubCopilotAdapter implements HostAdapter {
// ...
readonly assets: Record<AssetType, AssetCapability> = {
mcp: {
supported: true,
configFile: '.github/copilot-instruqt.md',
writeStrategy: 'inject-json-key',
},
command: NOT_SUPPORTED('GitHub Copilot does not support custom slash commands via files.'),
// ...
};
}
Adding a New Host
Contribution Workflow
graph LR
A[Create Adapter] --> B[Register in index.ts]
B --> C[Update README.md]
C --> D[Add Unit Tests]
D --> E[Verify with scenario tests]Step 1: Create the Adapter File
Create src/hosts/<id>.ts with a class implementing HostAdapter:
// src/hosts/new-host.ts
import type { HostAdapter, AssetCapability, AssetType } from './types.js';
const NOT_SUPPORTED = (reason: string): AssetCapability => ({
supported: false,
reason,
});
export class NewHostAdapter implements HostAdapter {
readonly id = 'new-host';
readonly displayName = 'New Host';
readonly docs = 'https://docs.newhost.com';
readonly detection = {
paths: ['.newhost/'],
};
readonly assets: Record<AssetType, AssetCapability> = {
mcp: {
supported: true,
configFile: '.newhost/mcp.json',
configKey: 'mcpServers',
writeStrategy: 'inject-json-key',
},
prompt: NOT_SUPPORTED('New Host does not support prompts.'),
skill: NOT_SUPPORTED('New Host does not support skills.'),
command: NOT_SUPPORTED('New Host does not support commands.'),
subAgent: NOT_SUPPORTED('New Host does not support sub-agents.'),
};
}
Step 2: Register the Adapter
Add to the registry in src/hosts/index.ts:
import { NewHostAdapter } from './new-host.js';
const hostRegistry = new Map<string, HostAdapter>([
// ... existing entries
['new-host', new NewHostAdapter()],
]);
Step 3: Update Documentation
Add a row to the capability matrix in src/hosts/README.md:
| Host | MCP | Prompt | Skill | Command | Sub-agent |
|---|---|---|---|---|---|
| New Host | ✅ .newhost/mcp.json | ❌ | ❌ | ❌ | ❌ |
Step 4: Add Unit Tests
Create tests/unit/hosts/new-host.test.ts:
import { describe, it, expect } from 'vitest';
import { NewHostAdapter } from '../../../src/hosts/new-host.js';
describe('NewHostAdapter', () => {
const adapter = new NewHostAdapter();
it('should have correct id', () => {
expect(adapter.id).toBe('new-host');
});
it('should have correct displayName', () => {
expect(adapter.displayName).toBe('New Host');
});
it('should support MCP', () => {
expect(adapter.assets.mcp.supported).toBe(true);
expect(adapter.assets.mcp.configFile).toBe('.newhost/mcp.json');
});
});
Key Design Decisions
Atomic JSON Writes
MCP configurations use a temp file + rename pattern to ensure atomicity:
graph TD
A[New Config] --> B[Write to temp file]
B --> C[Rename temp to target]
C --> D{Success?}
D -->|Yes| E[Complete]
D -->|No| F[Rollback temp file]Platform-Specific Paths
MCP config files use platform-specific paths:
configFile: {
darwin: '~/Library/Application Support/Cursor/config/mcp.json',
linux: '~/.config/Cursor/config/mcp.json',
win32: '%APPDATA%\\Cursor\\config\\mcp.json',
}
TOML vs JSON Auto-Detection
The system auto-detects TOML format based on file extension:
// src/assets/mcp.ts
if (path.extname(configFile) === '.toml') {
// Use smol-toml for read/write
} else {
// Use standard JSON
}
Explicit Flag Capability Checking
The installer validates that explicitly requested asset types are supported before attempting installation:
// src/installer.ts
if (!capability.supported) {
skippedResults.push({
job: { assetType, assetName, resolvedSource, host },
status: 'skipped',
reason: capability.reason,
});
}
Summary
The Host Integration system provides a scalable architecture for supporting multiple AI agent hosts through a consistent adapter pattern. Key benefits include:
- Single Source of Truth: All host capabilities defined in adapter classes and documented in
src/hosts/README.md - Extensibility: New hosts can be added by implementing the
HostAdapterinterface - Type Safety: TypeScript strict mode ensures adapter implementations match specifications
- Testability: Each adapter has corresponding unit tests verifying exact field values
- Platform Abstraction: Platform-specific paths handled transparently
- Format Flexibility: Supports both JSON and TOML configuration formats
Sources: src/hosts/types.ts
Source Resolution
Related topics: System Architecture, Asset Types
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture, Asset Types
Source Resolution
Overview
Source Resolution is the core subsystem responsible for transforming user-provided source strings into concrete filesystem paths that the installer can process. It acts as an abstraction layer that normalizes diverse input formats—including local paths, Git URLs, HTTP URLs, and inline content—into a unified ResolvedSource data structure.
The resolution pipeline accepts asset sources in multiple formats and outputs temporary directories containing the asset content, ready for downstream handlers to install into host-specific locations. This design decouples asset specification from asset installation, enabling users to reference assets through various convenient syntaxes without understanding host-specific installation mechanics.
Sources: src/source/index.ts
Architecture
The Source Resolution module is located in src/source/ and comprises six specialized modules:
| Module | Purpose |
|---|---|
index.ts | Main entry point; orchestrates resolution pipeline |
git.ts | Resolves Git URLs (SSH and HTTPS) with sparse checkout support |
http-file.ts | Downloads assets from HTTP/HTTPS URLs |
local.ts | Resolves local filesystem paths |
inline.ts | Handles inline JSON and Markdown content |
infer-name.ts | Extracts asset names from source strings |
Sources: src/source/index.ts
Resolution Pipeline
The resolution process follows a sequential pipeline that attempts each resolver until one successfully produces a ResolvedSource:
graph TD
A[User Source String] --> B{Starts with ./ or / or ~?}
B -->|Yes| C[Local Resolver]
B -->|No| D{Starts with http:// or https://?}
D -->|Yes| E[HTTP Resolver]
D -->|No| F{Starts with git@ or ends with .git?}
F -->|Yes| G[Git Resolver]
F -->|No| H{Starts with {?}
H -->|Yes| I[Inline JSON Resolver]
H -->|No| J{Contains \n?}
J -->|Yes| K[Inline Markdown Resolver]
J -->|No| L[Error: Unknown source format]
C --> M[ResolvedSource]
E --> M
G --> M
I --> M
K --> MEach resolver returns a ResolvedSource object containing the original source, resolved local path, and content type:
interface ResolvedSource {
originalSource: string; // The user's original input
localPath: string; // Absolute path to resolved content
type: SourceType; // 'local' | 'git' | 'http-file' | 'inline-json' | 'inline-md'
tempDir?: string; // Temp directory if content was downloaded/generated
}
Sources: src/source/index.ts
Source Types
Local Files and Directories
The local resolver handles filesystem paths beginning with ./, ../, /, or ~. It performs the following operations:
- Path normalization: Expands
~to home directory and resolves relative paths to absolute paths - Existence verification: Confirms the path exists on the filesystem
- Directory detection: For directory sources, scans for matching asset files
// Supported path formats
'./mcps/playwright.json' // Relative path
'/absolute/path/to/file' // Absolute path
'~/dotfiles/mcp.json' // Home directory expansion
'../shared/rules.md' // Parent directory relative path
Sources: src/source/local.ts
Git URLs
The Git resolver supports both SSH and HTTPS Git URLs with optional path fragment syntax for sparse checkout:
| Format | Example | Behavior |
|---|---|---|
| SSH | [email protected]:user/repo.git#path/to/asset | Clones via SSH, extracts specified path |
| HTTPS | https://github.com/user/repo.git#path/to/asset | Clones via HTTPS, extracts specified path |
| Without fragment | [email protected]:user/repo.git | Clones entire repository |
Sparse Checkout Behavior
When a #path fragment is specified, the resolver performs a sparse checkout, downloading only the specified directory or file. This is particularly useful for monorepos where only specific assets are needed.
// Example: Extract only the playwright skill from a monorepo
[email protected]:anthropics/skills.git#skills/playwright
The resolver supports both formats:
- Directory path: Extracts all files within the directory
- File path: Extracts a single file
Sources: src/source/git.ts
HTTP/HTTPS URLs
The HTTP resolver downloads files directly from web URLs. It supports:
- Direct file downloads from any HTTP/HTTPS endpoint
- Automatic filename extraction from URL path
- Integrity verification of downloaded content
Supported Asset Types for HTTP:
| Asset Type | HTTP Support |
|---|---|
| MCP | ✅ Yes |
| Skill | ❌ No (validation rejects) |
| Prompt | ✅ Yes |
| Command | ✅ Yes |
| Sub-agent | ✅ Yes |
Sources: src/source/http-file.ts
Inline Content
Inline sources allow embedding asset content directly in the command line, eliminating the need for separate files or remote URLs. The system auto-detects content type based on format.
#### Inline JSON (MCP Only)
Sources beginning with { are treated as inline JSON. The format supports MCP configuration in two structures:
Format A: Inner config (single server)
{"command":"npx","args":["@playwright/mcp@latest"]}
Asset name is inferred from the MCP config filename.
Format B: Wrapped config with mcpServers
{"mcpServers":{"playwright":{"command":"npx","args":["@playwright/mcp@latest"]}}}
The wrapper is automatically unwrapped and the inner server name becomes the asset name.
# Example command
npx -y agent-add --host cursor \
--mcp '{"playwright":{"command":"npx","args":["@playwright/mcp"]}}'
Sources: src/source/inline.ts
#### Inline Markdown (Prompt/Command/Sub-agent)
Sources containing \n (newline) are treated as inline Markdown. This applies to:
- Prompt files: System prompts and rule files
- Command files: Slash commands
- Sub-agent files: Agent configurations
The asset name is inferred from the first # Heading in the content, converted to kebab-case:
# Code Review Rules
Always review for security first.
→ Asset name: code-review-rules
# Example command
npx -y agent-add --host claude-code \
--prompt $'# Code Review Rules\n\nAlways review for security issues first.'
Sources: src/source/inline.ts Sources: src/source/infer-name.ts
Asset Name Inference
The infer-name.ts module extracts consistent asset names from diverse source formats. This ensures uniform naming regardless of how the asset is referenced.
Name Inference Rules
| Source Type | Rule | Example Input | Inferred Name |
|---|---|---|---|
| Inline JSON | Extract top-level key | {"playwright":{...}} | playwright |
| Inline Markdown | First # Heading → kebab-case | # Code Review | code-review |
Git URL + #path | Last segment, strip extension | ...git#skills/pdf | pdf |
Git URL without # | Repository name, strip .git | ...playwright.git | playwright |
| Local path / HTTP | Filename, strip extension | ./mcps/playwright.json | playwright |
Inline JSON Parsing
When processing inline JSON sources:
- Parse the JSON string into an object
- If the object has an
mcpServerswrapper, unwrap it - Extract the top-level key as the asset name
- If multiple keys exist, throw an error (inline JSON supports single MCP only)
// Single server (inner format) - name from source metadata
{"command":"npx","args":["@playwright/mcp"]} // ❌ No name, requires filename inference
// Single server (wrapped format) - name from key
{"mcpServers":{"playwright":{...}}} // ✅ Name is "playwright"
Sources: src/source/infer-name.ts
Temporary File Management
Source Resolution manages temporary directories to ensure clean operation:
- Downloaded content: HTTP and Git downloads are stored in temporary directories
- Inline content: Generated files (from inline JSON/Markdown) are written to temp files
- Cleanup: Temp directories are cleaned up after installation completes
The AGENT_ADD_HOME environment variable can override the default temp directory location, useful for test isolation:
AGENT_ADD_HOME=/tmp/test-home npx -y agent-add --host cursor --mcp '{"test":{...}}'
Sources: src/source/index.ts
Integration with Installation Pipeline
Source Resolution integrates into the broader installation workflow as follows:
graph LR
A[CLI Input] --> B[Source Resolution]
B --> C[ResolvedSource]
C --> D[Validation]
D --> E[InstallJob Creation]
E --> F[Asset Handler Execution]
F --> G[InstallResult]
B -.->|Inline sources| H[Temp File Generation]
B -.->|Git/HTTP sources| I[Download to Temp]After resolution, the installer.ts module performs validation based on asset type:
- MCP: File must exist and have
.jsonextension - Skill: Must be a directory containing
SKILL.md - Prompt/Command/Sub-agent: No additional validation at this stage
// From src/installer.ts - validation logic
if (assetType === 'skill') {
if (resolved.type === 'http-file' || resolved.type === 'inline-json' || resolved.type === 'inline-md') {
return 'Skill assets must point to directory sources (local path or Git URL)';
}
const skillMdPath = path.join(resolved.localPath, 'SKILL.md');
// ...
}
Sources: src/installer.ts
Error Handling
The resolution system provides specific error messages for common failures:
| Error Condition | Message |
|---|---|
| Inline JSON parse failure | 内联 JSON 解析失败。格式应为 {"<name>":{...}} |
| Inline JSON not object | 内联 JSON 必须为对象类型 |
| Multiple keys in inline JSON | Error listing unsupported multiple keys |
| Directory empty (skill) | No matching files found in directory |
| SKILL.md missing | Skill 目录内缺少 SKILL.md 文件 |
| MCP file missing | MCP 来源文件不存在 |
| MCP wrong extension | MCP 来源文件扩展名必须为 .json |
| HTTP for Skill | Skill 资产必须指向目录来源 |
All errors result in process exit with code 2, ensuring CI/CD pipelines fail fast on configuration issues.
Sources: src/source/infer-name.ts Sources: src/installer.ts
Sources: src/source/index.ts
Asset Types
Related topics: Manifest System, Host Integration
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Manifest System, Host Integration
Asset Types
Asset Types define the categories of installable resources that agent-add can distribute to AI coding assistant hosts. The system supports five distinct asset types, each with specific file formats, validation rules, and installation behaviors.
Overview
agent-add categorizes all distributable resources into five asset types. Each type has a dedicated handler responsible for installation logic, validation, and host-specific write strategies.
graph TD
A[User Input / Pack Manifest] --> B{Asset Type Detection}
B -->|JSON| C[MCP Server]
B -->|Directory + SKILL.md| D[Skill]
B -->|Markdown| E[Prompt]
B -->|Markdown + Frontmatter| F[Command]
B -->|Markdown + Agent Meta| G[Sub-agent]
C --> H[Validation]
D --> H
E --> H
F --> H
G --> H
H --> I[Host Adapter]
I --> J[Write Strategy]
J --> K[Host Filesystem]Supported Asset Types
| Asset Type | Identifier | Source Format | Validation Requirement |
|---|---|---|---|
| MCP Server | mcp | JSON file | .json extension required |
| Skill | skill | Directory | Must contain SKILL.md |
| Prompt | prompt | Markdown file | First # Heading required |
| Command | command | Markdown with YAML frontmatter | Optional description field |
| Sub-agent | subAgent | Markdown with YAML frontmatter | Optional host specialization |
Sources: src/manifest/schema.ts and src/manifest/parser.ts:30-35
MCP Server (`mcp`)
MCP Servers provide Model Context Protocol configurations that enable AI assistants to interact with external tools and services.
Supported JSON Formats
agent-add auto-detects two MCP configuration formats:
Format A: Inner Config (Single Server)
{
"command": "npx",
"args": ["@playwright/mcp@latest"],
"env": {}
}
The asset name is inferred from the filename: playwright.json → name is playwright.
Format B: Full Config with mcpServers Wrapper
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
agent-add automatically unwraps the mcpServers object and extracts the inner server name and configuration. This format currently supports a single server only.
Sources: README.md - Asset Developer Guide
Installation Behavior
- JSON shallow merge: New servers are merged into existing configuration
- Atomic write: Uses temp file + rename for safe writes
- TOML support:
.tomlextension auto-dispatches to TOML parsing path for Codex and Vibe hosts
graph LR
A[MCP JSON Input] --> B{Extension Check}
B -->|.json| C[JSON Handler]
B -->|.toml| D[TOML Handler]
C --> E[Shallow Merge]
D --> E
E --> F[Atomic Write]
F --> G[host mcp config]Skill (`skill`)
Skills are reusable agent capabilities distributed as directory bundles.
Structure Requirements
A valid Skill asset must be a directory containing a SKILL.md file at its root:
helpers/
├── utils.py
└── templates/
└── report.md
The SKILL.md file defines the skill metadata:
Sources: src/manifest/schema.ts and src/manifest/parser.ts:30-35
Manifest System
Related topics: Asset Types, CLI Interface
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Asset Types, CLI Interface
Manifest System
The Manifest System is a core component of agent-add that enables batch installation of multiple assets through a single JSON configuration file. It provides a declarative way to define, distribute, and install a collection of AI agent assets (MCPs, Skills, Prompts, Commands, and Sub-agents) as a single package.
Overview
Agent Packs are JSON files that bundle multiple assets together, allowing developers and teams to share complete asset collections with a single reference. The Manifest System handles parsing, validation, and processing of these pack manifests.
graph TD
A[Pack Manifest JSON] --> B[Manifest Parser]
B --> C{Validation}
C -->|Pass| D[Asset Descriptor Array]
C -->|Fail| E[Error Exit 2]
D --> F[Source Resolver]
F --> G[Install Jobs]
G --> H[Asset Handlers]
H --> I[Host Installation]Manifest File Format
Schema Structure
The manifest schema is defined using Zod for runtime validation. The file path to the schema definition is:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Pack identifier in namespace/pack-name format. Only [a-zA-Z0-9_-] characters allowed |
assets | Asset[] | Yes | Array of asset definitions, minimum 1 item |
Asset Definition
Each asset in the assets array has the following structure:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Asset type: mcp, skill, prompt, command, or subAgent |
source | string | Yes | Source location (Git URL, local path, or HTTP URL) |
Sources: README.md
Example Manifest
{
"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" }
]
}
Sources: README.md
Source Syntax for Manifests
The manifest parser supports multiple source formats that are resolved to local paths:
graph LR
A[Source String] --> B{Format Detection}
B --> C[#path segment]
B --> D[Git URL .git suffix]
B --> E[Local/HTTP path]
C --> F[kebab-case name from path]
D --> G[repo name without .git]
E --> H[filename without extension]Source Resolution Rules
| Source Format | Name Extraction Rule | Example |
|---|---|---|
Git URL with #path | Take last segment after #, strip extension | ...git#skills/pdf → pdf |
Git URL without # | Take repo name, strip .git suffix | ...playwright.git → playwright |
| Local path / HTTP URL | Take filename, strip extension | ./mcps/playwright.json → playwright |
Sources: src/source/infer-name.ts
Inline Sources
Manifests support two inline source formats:
| Format | Detection | Name Source |
|---|---|---|
inline-json | Starts with { | Single top-level JSON key |
inline-md | Contains \n (newlines) | First # Heading in Markdown, converted to kebab-case |
Both inline sources are written to temporary files before following the normal installation flow.
Parser Implementation
Entry Point
The manifest parser is invoked from the installer orchestrator. When --pack flags are detected, the parser processes each manifest file:
sequenceDiagram
participant CLI as CLI Input
participant Inst as Installer
participant MP as Manifest Parser
participant SR as Source Resolver
CLI->>Inst: pack: [manifest.json, ...]
Inst->>MP: parseManifest(filePath)
MP->>MP: Read JSON file
MP->>MP: Zod validation
alt Valid
MP-->>Inst: ManifestData[]
else Invalid
MP->>Inst: Error + Exit 2
end
Inst->>SR: Resolve each asset sourceValidation Flow
The parser performs comprehensive validation using Zod schema validation:
- Schema validation: Checks required fields and types
- Name format validation: Ensures
namematchesnamespace/pack-namepattern - Asset type validation: Verifies all
typefields are in the allowed set - Error reporting: Provides specific error messages with field paths
Sources: src/manifest/parser.ts
Error Handling
The parser provides structured error messages for common validation failures:
| Error Condition | Message |
|---|---|
| Invalid asset type | Unsupported asset type: '<type>'. Supported: mcp, skill, prompt, command, subAgent |
| Invalid name format | Manifest name must match namespace/pack-name format |
| Missing required field | Manifest missing required field: <field path> |
| JSON parse failure | Invalid Manifest format |
Sources: src/manifest/parser.ts
Integration with Installer
Processing Pipeline
graph TD
subgraph Input Processing
A[Pack Manifests] --> B[Parse Each Manifest]
B --> C[Extract Asset Descriptors]
end
subgraph Resolution
C --> D[Resolve Sources]
D --> E[Validate Each Asset]
end
subgraph Job Creation
E --> F{Capability Check}
F -->|Supported| G[Create Install Job]
F -->|Unsupported| H[Skip Result]
end
subgraph Execution
G --> I[Execute Handler]
I --> J[Install Result]
endManifest Processing in Installer
The installer processes manifests in the following sequence:
- Parse: Each manifest file is parsed to extract asset descriptors
- Resolve: Asset sources are resolved to local file paths
- Validate: Each asset is validated according to its type requirements
- Filter: Assets unsupported by the target host are skipped
- Execute: Valid assets are processed by appropriate handlers
Sources: src/installer.ts
Skip Behavior for Pack Sources
Unlike explicit flag sources, pack sources that target unsupported asset types are silently skipped rather than causing errors. This design allows pack authors to create cross-host compatible manifests without requiring per-host manifest files.
Note: This is different from explicit flags, which exit with error code 2 if the asset type is unsupported.
CLI Usage
Installing a Pack
# Single pack installation
npx -y agent-add --host cursor --pack ./manifest.json
# Multiple packs
npx -y agent-add --host claude-code \
--pack ./frontend-pack.json \
--pack ./backend-pack.json
# Combined with explicit assets
npx -y agent-add --host cursor \
--pack ./team-pack.json \
--mcp ./local-mcp.json
All `--pack` Flag Options
| Flag | Description | Collectable |
|---|---|---|
--pack <source> | Install an Agent Pack manifest | Yes (repeatable) |
All asset flags can be repeated and freely combined with --pack.
Development and Testing
Test Coverage
The manifest system is tested through:
| Test Type | Location | Purpose |
|---|---|---|
| Unit tests | tests/unit/ | Parser validation, name inference |
| Contract tests | tests/contract/ | CLI black-box behavior |
| Feature tests | tests/features/ | End-to-end scenarios |
Running Tests
# All unit + integration tests
npm test
# Contract tests only
npm run test:contract
# Single manifest parser test
npx vitest run tests/unit/manifest/parser.test.ts
Development Setup
npm install
npm run build
npm run install:vibe # Installs dev assets via pack manifest
The install:vibe command installs assets defined in vibe/manifest.json, demonstrating the pack manifest system in action.
Related Components
| Component | File | Role |
|---|---|---|
| Schema | src/manifest/schema.ts | Zod schema definition for ManifestData |
| Parser | src/manifest/parser.ts | Parsing and validation logic |
| Name Inference | src/source/infer-name.ts | Extracts asset names from sources |
| Installer | src/installer.ts | Orchestrates manifest processing |
| CLI | src/cli.ts | Command-line argument handling |
Key Design Decisions
| Decision | Rationale |
|---|---|
| Pack sources skip unsupported types | Enables cross-host manifest sharing without per-host variants |
| Explicit flags error on unsupported types | Forces developers to handle host compatibility explicitly |
| Atomic JSON writes for MCP | Ensures config file integrity during concurrent operations |
| Temp file + rename strategy | Provides atomicity for manifest-based MCP installations |
| Zod for schema validation | Runtime type checking with detailed error messages |
Sources: README.md
CLI Interface
Related topics: Getting Started, Manifest System
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Getting Started, Manifest System
CLI Interface
The CLI Interface is the primary user-facing component of agent-add, responsible for command-line argument parsing, host detection, input validation, and orchestrating the installation workflow. It serves as the entry point for all asset installation operations.
Overview
agent-add provides a unified command-line interface for installing MCP servers, Skills, Prompts, Commands, and Sub-agents across 18 different AI agent hosts. The CLI handles argument parsing using the commander library and delegates actual installation logic to the installer module.
graph TD
A[User CLI Command] --> B[bin/agent-add.js]
B --> C[src/index.ts]
C --> D[src/cli.ts - createProgram]
D --> E[program.parseAsync process.argv]
E --> F[Input Validation]
F --> G[runInstaller cliInput, host, cwd]
G --> H[printSummary results]
H --> I[Exit: 0=success, 1=conflict/error, 2=validation]Sources: src/index.ts:1-8
Entry Points
Binary Entry Point
The CLI binary is defined at bin/agent-add.js and serves as the executable entry point for the npm package. It is registered in package.json under the bin field.
#!/usr/bin/env node
import '../dist/index.js';
Sources: bin/agent-add.js
Module Entry Point
The TypeScript module entry at src/index.ts creates the program and handles top-level error catching:
import { createProgram } from './cli.js';
const program = createProgram();
program.parseAsync(process.argv).catch((err: Error) => {
process.stderr.write(`agent-add error: ${err.message}\n`);
process.exit(2);
});
Sources: src/index.ts:1-8
Command Structure
Global Options
| Option | Type | Description |
|---|---|---|
--host <host> | string | Target host ID (cursor, claude-code, claude-desktop, etc.) |
-V, --version | boolean | Show version number |
-h, --help | boolean | Show help information |
Asset Installation Flags
All asset flags can be repeated to install multiple assets of the same type and can be freely combined with --pack:
| Flag | Type | Description |
|---|---|---|
--pack <source> | string[] | Install an Agent Pack manifest |
--mcp <source> | string[] | Install an MCP server config |
--skill <source> | string[] | Install a Skill directory |
--prompt <source> | string[] | Install a Prompt file |
--command <source> | string[] | Install a Command file |
--sub-agent <source> | string[] | Install a Sub-agent file |
Sources: src/cli.ts
Command Definition
The createProgram() function in src/cli.ts defines the Commander program structure:
function createProgram() {
const program = new Command();
program
.name('agent-add')
.description('Install AI agent assets into different hosts')
.argument('[sources...]', 'Sources to install')
.option('--pack <source>', 'Install an Agent Pack manifest', collect, [])
.option('--mcp <source>', 'Install an MCP server', collect, [])
.option('--skill <source>', 'Install a Skill directory', collect, [])
.option('--prompt <source>', 'Install a Prompt file', collect, [])
.option('--command <source>', 'Install a Command file', collect, [])
.option('--sub-agent <source>', 'Install a Sub-agent file', collect, [])
.option('--host <host>', 'Target host ID', collect, [])
.action(async (options) => { /* ... */ });
return program;
}
Sources: src/cli.ts
Input Collection
The collect() helper function accumulates multiple values when flags are repeated:
function collect(value: string, previous: string[]): string[] {
return [...previous, value];
}
This enables usage patterns like:
agent-add --mcp server1.json --mcp server2.json --skill ./my-skill
Sources: src/cli.ts
Input Validation Flow
graph TD
A[Parse CLI Options] --> B{Has Asset Flags?}
B -->|No| C[Error: No asset flags provided]
C --> D[Exit 2]
B -->|Yes| E{Host Specified?}
E -->|No| F{TTY Mode?}
F -->|Yes| G[Interactive Host Selection]
F -->|No| H[Error: --host required in CI]
G --> I[Selected Host]
E -->|Yes| I
I --> J[runInstaller cliInput, host, cwd]
J --> K[printSummary]
K --> L{Results contain errors?}
L -->|Yes| M[Exit 1]
L -->|No| N[Exit 0]Asset Flag Validation
Before proceeding, the CLI verifies at least one asset flag is provided:
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);
}
Sources: src/cli.ts
Host Selection
Explicit Host Specification
When --host is explicitly provided, it is used directly:
if (cliInput.host) {
hostId = cliInput.host;
}
Interactive Host Selection
In TTY (interactive) mode, if no host is specified, the CLI presents an interactive selection menu:
else if (process.stdout.isTTY) {
const selected = await inquirer.prompt([{
type: 'select',
name: 'host',
message: 'Select your AI agent host:',
choices: getValidHostIds(),
}]);
hostId = selected.host;
}
Non-TTY Strict Mode
In CI/non-interactive environments, the CLI requires explicit host specification and exits with code 2 if missing:
else {
const validIds = getValidHostIds().join(', ');
process.stderr.write(
`agent-add error: --host flag required in non-TTY environment. Valid hosts: ${validIds}\n`,
);
process.exit(2);
}
Sources: src/cli.ts
CliInput Data Model
The CliInput interface defines the internal representation of parsed CLI arguments:
interface CliInput {
pack: string[];
mcp: string[];
skill: string[];
prompt: string[];
command: string[];
subAgent: string[];
host?: string;
}
This is populated from the command options and passed to the installer:
const cliInput: CliInput = {
mcp: options.mcp,
skill: options.skill,
prompt: options.prompt,
command: options.command,
subAgent: options.subAgent,
pack: options.pack,
host: options.host,
};
Sources: src/cli.ts
Error Handling
Top-Level Error Handler
The entry point catches all unhandled errors and exits with code 2:
program.parseAsync(process.argv).catch((err: Error) => {
process.stderr.write(`agent-add error: ${err.message}\n`);
process.exit(2);
});
Action-Level Error Handling
The main action also handles install results for conflicts and errors:
const hasConflicts = summary.results.some((r) => r.status === 'conflict');
const hasErrors = summary.results.some((r) => r.status === 'error');
if (hasErrors || hasConflicts) {
process.exit(1);
}
Exit Codes
| Code | Meaning | Trigger |
|---|---|---|
| 0 | Success | All assets installed without errors or conflicts |
| 1 | Partial failure | Install completed but had conflicts or errors |
| 2 | Validation failure | Invalid input, missing flags, or unsupported operations |
Sources: src/index.ts:6 and src/cli.ts
Usage Examples
Install Single Asset
npx -y agent-add --host cursor --mcp ./playwright.json
Install Multiple Assets
npx -y agent-add --host claude-code \
--mcp ./mcp/servers.json \
--skill ./skills/pdf \
--prompt 'https://raw.githubusercontent.com/.../rules.md'
Install via Pack Manifest
npx -y agent-add --host cursor --pack ./manifest.json
Interactive Mode
npx -y agent-add --mcp ./server.json
# (Prompts for host selection if in TTY mode)
Sources: README.md
Package Configuration
The CLI binary is registered in package.json:
{
"bin": {
"agent-add": "./bin/agent-add.js"
},
"type": "module",
"engines": {
"node": ">=18"
}
}
Sources: package.json
Sources: src/index.ts:1-8
Testing
Related topics: Project Configuration
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Project Configuration
Testing
Overview
The agent-add project employs a multi-layered testing strategy to ensure reliability across different host environments and asset types. The testing infrastructure validates the CLI tool's functionality through unit tests, integration tests, contract tests, and scenario-based tests executed by AI agents.
Test Architecture
The testing framework is built on Vitest with a three-tier approach:
graph TD
A[Test Suite] --> B[Unit Tests]
A --> C[Integration Tests]
A --> D[Contract Tests]
A --> E[Scenario Tests]
B --> B1[vitest run]
C --> C1[vitest run]
D --> D1[Black-box CLI tests]
E --> E1[AI Agent execution]
style A fill:#e1f5fe
style D fill:#fff3e0
style E fill:#f3e5f5Test Configuration
The Vitest configuration is defined in vitest.config.ts:
| Configuration Aspect | Value |
|---|---|
| Test Runner | Vitest 4.1.0 |
| TypeScript Target | Node.js 18+ |
| Test Location | tests/ directory |
| Run Command | npm test |
Test Categories
Unit Tests
Unit tests verify individual components in isolation. Each host adapter has corresponding unit tests.
Test Location: tests/unit/hosts/<id>.test.ts
Example - Cursor Host Test:
npx vitest run tests/unit/hosts/cursor.test.ts
Unit tests verify:
- Adapter
id,displayName, anddocsvalues - Asset capabilities match the README matrix
- Supported capabilities have required fields
Integration Tests
Integration tests validate the interaction between components.
Command: npm run test:integration
Contract Tests
Contract tests perform black-box CLI testing without requiring the full test suite.
Command: npm run test:contract
Scenario Tests
Scenario tests use Gherkin .feature files executed by AI agents via scenario-test.
Location Structure:
tests/
├── features/
│ ├── scenario-run-config.md # Run configuration
│ ├── core/ # Core behavior tests (7 .feature files)
│ └── host/ # Host compatibility tests (3 .feature files)
└── fixtures/ # Static test fixtures
Execution Commands:
/scenario-exec tests/features/core
/scenario-exec tests/features/host
Each scenario runs in an isolated temporary directory. The run configuration is defined in tests/features/scenario-run-config.md.
Test Fixtures
Static test fixtures support different asset types:
tests/fixtures/
├── mcp/
├── skill/
├── prompt/
├── command/
├── sub-agent/
└── pack/
Fixtures are used by both unit tests and scenario tests to provide consistent test data.
Development Testing Workflow
Setup
Before running tests, build the project:
npm install
npm run build
Running Tests
| Command | Purpose |
|---|---|
npm test | All unit + integration tests |
npm run test:contract | CLI black-box contract tests only |
npm run test:integration | Integration tests |
npx vitest run tests/unit/hosts/cursor.test.ts | Single unit test file |
Vibe Development Assets
The project uses a custom testing manifest for development:
File: vibe/manifest.json
{
"name": "agent-add/dev-pack",
"assets": [
{ "type": "skill", "source": "https://github.com/pea3nut/scenario-test.git#skills/scenario-test" },
{ "type": "command", "source": "https://github.com/pea3nut/scenario-test.git#commands/scenario-exec.md" },
{ "type": "subAgent", "source": "https://github.com/pea3nut/scenario-test.git#agents/scenario-case-runner.md" },
{ "type": "command", "source": "./vibe/tasks/verify-host-readme.md" },
{ "type": "prompt", "source": "./vibe/system-prompt.md" }
]
}
Install dev assets via:
npm run install:vibe
This installs:
- scenario-test skill: Provides testing infrastructure
- scenario-exec command: Triggers scenario test execution
- scenario-case-runner sub-agent: AI agent that executes scenarios
- verify-host-readme command: Validates host README consistency
- system-prompt: Development system prompt
Host README Verification
The verify-host-readme.md task validates consistency between the host capability matrix in src/hosts/README.md and actual adapter implementations.
Validation Criteria:
- Adapter configuration fields match README matrix values exactly
- Unit tests assert exact values for every field
- New host contributions must update both adapter and README
Linting and Type Checking
Before test execution, validate code quality:
npm run lint # tsc --noEmit type checking
Test Isolation
The testing framework ensures isolation through:
- Temporary directories - Scenario tests run in isolated temp directories
- Temp file writes - MCP config uses temp file + rename for safety
- AGENT_ADD_HOME override - Environment variable redirects install paths for test isolation
Dependencies
Test infrastructure relies on:
| Package | Version | Purpose |
|---|---|---|
| vitest | ^4.1.0 | Test runner |
| tsx | ^4.21.0 | TypeScript execution |
| typescript | ^5.9.3 | Type checking |
| scenario-test | (external) | Scenario test framework |
Source: https://github.com/pea3nut/agent-add / Human Manual
Project Configuration
Related topics: Testing
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Testing
Project Configuration
Overview
The agent-add project uses a multi-layered configuration system to support installing various asset types across 18 different AI coding hosts. The configuration architecture encompasses TypeScript compilation settings, build tooling via tsup, package metadata, host adapter definitions, asset handler configurations, and source resolution strategies.
The project targets Node.js 18+ and compiles to CommonJS format for maximum compatibility with AI coding tool environments. Sources: package.json:17
Build System Configuration
tsup Build Configuration
The project uses tsup for TypeScript bundling, defined in tsup.config.ts:
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['cjs'],
target: 'node18',
clean: true,
sourcemap: true,
dts: false,
outDir: 'dist',
noExternal: [/.*/],
});
| Option | Value | Purpose |
|---|---|---|
entry | ['src/index.ts'] | Single entry point for CLI application |
format | ['cjs'] | CommonJS output format for Node.js compatibility |
target | node18 | Transpile for Node.js 18 environment |
clean | true | Remove previous build artifacts before each build |
sourcemap | true | Generate source maps for debugging |
dts | false | Disable TypeScript declaration generation |
outDir | 'dist' | Output directory for compiled files |
noExternal | [/.*/] | Bundle all dependencies into output |
Sources: tsup.config.ts:1-11
Build Scripts
The npm scripts in package.json define the development workflow:
{
"scripts": {
"build": "tsup",
"dev": "tsx watch src/index.ts",
"test": "vitest run",
"install:vibe": "npx -y agent-add -- --pack vibe/manifest.json"
}
}
| Script | Command | Usage |
|---|---|---|
build | tsup | Compile TypeScript to JavaScript |
dev | tsx watch src/index.ts | Development mode with hot reload |
test | vitest run | Execute unit and integration tests |
install:vibe | agent-add -- --pack vibe/manifest.json | Install development assets via pack manifest |
Sources: package.json:27-31
Package Configuration
Engine Requirements
"engines": {
"node": ">=18"
}
The project requires Node.js 18 or higher due to ES module features and modern JavaScript APIs used throughout the codebase. Sources: package.json:35-37
Core Dependencies
The project relies on several key runtime dependencies:
| Dependency | Version | Purpose |
|---|---|---|
commander | ^14.0.3 | CLI argument parsing |
smol-toml | ^1.6.1 | TOML format parsing for Codex/Vibe hosts |
yaml | ^2.8.2 | YAML frontmatter parsing for sub-agents |
zod | ^4.3.6 | Manifest schema validation |
Development dependencies include TypeScript, vitest for testing, and tsx for development execution. Sources: package.json:11-24
Host Adapter Configuration
Host Adapter Type System
The host configuration system uses a TypeScript interface defined in src/hosts/types.ts:
interface AssetCapability {
supported: boolean;
reason?: string;
configFile?: string;
installDir?: string;
writeStrategy?: 'append-with-marker' | 'create-file-in-dir';
}
interface HostAdapter {
id: string;
displayName: string;
docs: string;
assets: Record<AssetType, AssetCapability>;
}
Sources: src/hosts/types.ts
Host Capability Matrix
The project supports 18 distinct hosts, each with unique capability profiles:
| Host ID | MCP | Prompt | Skill | Command | Sub-agent |
|---|---|---|---|---|---|
cursor | ✅ | ✅ | ✅ | ✅ | ✅ |
claude-code | ✅ | ✅ | ❌ | ✅ | ✅ |
claude-desktop | ✅ | ❌ | ❌ | ❌ | ❌ |
windsurf | ✅ | ✅ | ❌ | ❌ | ❌ |
codex | ✅ | ❌ | ❌ | ❌ | ❌ |
vibe | ✅ | ❌ | ❌ | ❌ | ❌ |
Each host adapter hardcodes its configuration in a dedicated file under src/hosts/<id>.ts and registers in src/hosts/index.ts through the host registry Map. Sources: src/hosts/README.md, src/hosts/index.ts
Write Strategy Configuration
Hosts configure one of two write strategies for prompt assets:
graph TD
A[Prompt Asset] --> B{Write Strategy}
B --> C[append-with-marker]
B --> D[create-file-in-dir]
C --> E[HTML comment markers<br/>Idempotent append]
D --> F[Standalone file creation<br/>Skip if exists]Append with Marker Strategy: Used by Cursor, Claude Code, and similar hosts. Content is wrapped in HTML comment markers:
<!-- agent-add:code-review-rules -->
# Code Review Rules
...
<!-- /agent-add:code-review-rules -->
Create File in Dir Strategy: Used by Windsurf, Roo Code, and similar hosts. Creates <name>.md in the rules directory, skipping if already exists. Sources: src/assets/prompt.ts
Asset Type Configuration
MCP Asset Configuration
MCP assets support two JSON formats:
Format A - Inner Config (Single Server):
{
"command": "npx",
"args": ["@playwright/mcp@latest"],
"env": {}
}
Format B - Full Config with mcpServers Wrapper:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
The system automatically detects .toml extension and dispatches to the TOML handler path for Codex and Vibe hosts. Sources: src/assets/mcp.ts
Skill Asset Configuration
Skills require a specific directory structure with a mandatory SKILL.md file:
<!-- SKILL.md -->Sources: tsup.config.ts:1-11
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
First-time setup may fail or require extra isolation and rollback planning.
First-time setup may fail or require extra isolation and rollback planning.
Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
The project should not be treated as fully validated until this signal is reviewed.
Doramagic Pitfall Log
Doramagic extracted 9 source-linked risk signals. Review them before installing or handing real data to the project.
1. Installation risk: v1.1.0
- Severity: medium
- Finding: Installation risk is backed by a source signal: v1.1.0. Treat it as a review item until the current version is checked.
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: Source-linked evidence: https://github.com/pea3nut/agent-add/releases/tag/1.1.0
2. Installation risk: I built a CLI that installs MCP, skills, prompts, commands and sub ...
- Severity: medium
- Finding: 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- ...
- User impact: First-time setup may fail or require extra isolation and rollback planning.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: 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 ...
3. Configuration risk: Configuration risk needs validation
- Severity: medium
- Finding: Configuration risk is backed by a source signal: Configuration risk needs validation. Treat it as a review item until the current version is checked.
- User impact: Users may get misleading failures or incomplete behavior unless configuration is checked carefully.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.host_targets | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | host_targets=mcp_host, claude, claude_code, cursor, chatgpt
4. Capability assumption: README/documentation is current enough for a first validation pass.
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: The project should not be treated as fully validated until this signal is reviewed.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: capability.assumptions | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | README/documentation is current enough for a first validation pass.
5. Maintenance risk: Maintainer activity is unknown
- Severity: medium
- Finding: Maintenance risk is backed by a source signal: Maintainer activity is unknown. Treat it as a review item until the current version is checked.
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | last_activity_observed missing
6. Security or permission risk: no_demo
- Severity: medium
- Finding: no_demo
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: downstream_validation.risk_items | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | no_demo; severity=medium
7. Security or permission risk: no_demo
- Severity: medium
- Finding: no_demo
- User impact: The project may affect permissions, credentials, data exposure, or host boundaries.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: risks.scoring_risks | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | no_demo; severity=medium
8. Maintenance risk: issue_or_pr_quality=unknown
- Severity: low
- Finding: issue_or_pr_quality=unknown。
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | issue_or_pr_quality=unknown
9. Maintenance risk: release_recency=unknown
- Severity: low
- Finding: release_recency=unknown。
- User impact: Users cannot judge support quality until recent activity, releases, and issue response are checked.
- Recommended check: Open the linked source, confirm whether it still applies to the current version, and keep the first run isolated.
- Evidence: evidence.maintainer_signals | art_7871f43a97e049c0ba0df6fa5a5b6e88 | https://github.com/pea3nut/agent-add#readme | release_recency=unknown
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using agent-add with real data or production workflows.
- v1.1.0 - github / github_release
- I built a CLI that installs MCP, skills, prompts, commands and sub ... - reddit / searxng_indexed
- Configuration risk needs validation - GitHub / issue
Source: Project Pack community evidence and pitfall evidence