/** * Agent Registry — 53 AI coding agents with metadata. * * Each agent has detection paths, parent company info, and feature support. * Used to determine which agents can install/use verified skills. * * Source of truth for the count: `TOTAL_AGENTS` (derived from AGENTS_REGISTRY.length). * The numbers in this header are documentation only; tests assert against TOTAL_AGENTS. */ import type { FormatTransformer } from "../installer/transformers/index.js"; export interface FeatureSupport { /** Supports slash commands */ slashCommands: boolean; /** Supports hooks/lifecycle events */ hooks: boolean; /** Supports MCP (Model Context Protocol) */ mcp: boolean; /** Supports custom system prompts (CLAUDE.md, AGENTS.md, etc.) */ customSystemPrompt: boolean; } /** Definition for a single AI coding agent */ export interface AgentDefinition { /** Unique agent identifier */ id: string; /** Human-readable display name */ displayName: string; /** Local skills directory path pattern (relative to project) */ localSkillsDir: string; /** Global skills directory path pattern */ globalSkillsDir: string; /** Whether this agent supports the universal skill format */ isUniversal: boolean; /** Detect whether the agent is installed. * * 0706 T-002: historically this was a literal shell string (e.g. `'which * claude'`) executed through `exec()`. That pipes through `cmd.exe` on * Windows where `which`, `~`, `&&`, `2>/dev/null`, etc. don't exist, so * detection returned empty on Windows. New preferred form is a function * that returns a boolean (using `detectBinary()` + direct fs probes). * * The string form is retained as a legacy escape hatch so this change is * non-breaking for any external consumer who built their own registry * row with a shell string. `detectInstalledAgents()` handles both shapes. */ detectInstalled: string | (() => Promise); /** Parent company or organization */ parentCompany: string; /** Feature support matrix */ featureSupport: FeatureSupport; /** Directory path for cached plugin installations (agent-specific) */ pluginCacheDir?: string; /** 0786 (AC-US2-06, T-012): Marketplace dir is the catalog of *available* * plugins — NEVER use this for installed-status detection. Installed plugins * live under `pluginCacheDir`. This field exists so future UI can offer * "Install from marketplace" affordances based on catalog presence. * * Layout differs from pluginCacheDir: cache holds INSTALLED plugins at * `{dir}/{marketplace}/{plugin}/`, marketplaces hold SOURCES at * `{dir}/{marketplace}/plugins/{plugin}/` (extra `/plugins/` segment). */ pluginMarketplaceDir?: string; /** Win32 override for POSIX-only globalSkillsDir entries (0686 AC-US7-03). * When set, `resolveGlobalSkillsDir` uses this on win32 instead of the * deterministic `~/.config/X/` → `%APPDATA%/X/` fallback. Ignored on * darwin + linux so POSIX hosts retain existing behavior. */ win32PathOverride?: string; /** 0694 (AC-US4-01): Web-only "agents" with no local CLI. When true, * install commands MUST refuse and Studio renders a "Remote" badge * instead of install affordances. The catalog still lists the entry * so users searching for the brand can discover it. */ isRemoteOnly?: boolean; /** 0845 T-001 (AC-US4-01): Install tier. * - 1 = drop-in SKILL.md (Claude Code, Codex, Antigravity, ...) * - 2 = format-converted (Cursor .mdc, Windsurf, Copilot, ...) * - 3 = clipboard-only cloud tools (ChatGPT, v0, bolt.new) * When absent the agent is treated as Tier 1. */ tier?: 1 | 2 | 3; /** 0845 T-001 (AC-US4-01): Install surface. * - "filesystem" → write to disk under globalSkillsDir / localSkillsDir * - "clipboard" → emit a paste-ready blob; no disk write * - undefined → defaults to "filesystem" if NOT isRemoteOnly, * otherwise excluded from getSupportedAgents() * This field — not isRemoteOnly — is the gate Studio uses to decide * whether to surface an install affordance. See ADR-0845-01. */ installMode?: "filesystem" | "clipboard"; /** 0845 T-001 (AC-US4-01): Pure function transforming a parsed * SKILL.md into the list of files to write under the agent's * install root. Only set for Tier 2 agents. */ formatTransformer?: FormatTransformer; /** F7: project-scope Tier-2 install-root override, relative to * projectRoot. Used when the tool reads transformed output from a * directory that is NOT the parent of `localSkillsDir` — VS Code * Copilot reads `.github/instructions/`, but `localSkillsDir` is * `.github/copilot/skills`. Ignored for user scope. Subject to the * same path-traversal guard as `localSkillsDir`. */ localInstallRoot?: string; /** 0845 T-001 (AC-US4-01): Tier 3 only — URL of the tool's docs page * explaining how to paste the exported blob. */ pasteInstructionsUrl?: string; /** 0845 T-001: Tier 3 only — link to the tool's docs landing page. */ docsUrl?: string; } /** 0694 (AC-US1-04): Backward-compat alias map for renamed agent ids. * Consumed by `getAgent()` so existing scripts/lockfiles continue to work * after a rename. Keys are legacy ids, values are current canonical ids. */ export declare const LEGACY_AGENT_IDS: Readonly>; /** * Complete registry of 53 AI coding agents. * * 8 universal agents, 45 non-universal agents. * Use TOTAL_AGENTS for programmatic access to the count. */ export declare const AGENTS_REGISTRY: AgentDefinition[]; /** Total number of registered agents */ export declare const TOTAL_AGENTS: number; export declare const NON_AGENT_CONFIG_DIRS: readonly [".specweave", ".vscode", ".idea", ".zed", ".devcontainer", ".github", ".agents", ".agent"]; /** Profile for generating skills targeted at a specific agent */ export interface AgentCreationProfile { agent: AgentDefinition; /** Claude-specific frontmatter fields to remove for this agent */ stripFields: string[]; /** Agent-specific guidance to inject into the generation prompt */ addGuidance: string[]; /** Feature support snapshot for generation context */ featureSupport: FeatureSupport; } /** * Filter agents by feature requirements. * Returns agents where ALL specified features are true (AND logic). * Empty requirements object returns all agents. */ export declare function filterAgentsByFeatures(requirements: Partial): AgentDefinition[]; /** * Get the creation profile for a specific agent. * Returns guidance on what to strip/add when generating skills for this agent. * * - Claude Code: empty stripFields, empty addGuidance (full feature support) * - Non-Claude: stripFields lists Claude-specific fields, addGuidance warns about unsupported features */ export declare function getAgentCreationProfile(agentId: string): AgentCreationProfile | undefined; /** * Returns all universal agents (support the universal skill format). */ export declare function getUniversalAgents(): AgentDefinition[]; /** * Returns all non-universal agents. */ export declare function getNonUniversalAgents(): AgentDefinition[]; /** * Gets a single agent by ID. Honors `LEGACY_AGENT_IDS` so callers using a * renamed legacy id (e.g. `github-copilot`) still resolve to the current * canonical entry (e.g. `github-copilot-ext`). * * @param id - Agent identifier (current or legacy alias) * @returns The agent definition, or undefined if not found */ export declare function getAgent(id: string): AgentDefinition | undefined; /** * 0694 (AC-US4-03): Returns agents that can be installed locally. * Excludes any entry flagged `isRemoteOnly: true` (web-only tools like * Devin / bolt.new / v0 / Replit). Used by `vskill add`, the Studio * AgentScopePicker install affordances, and any caller that needs the * "real" installable agent list. */ export declare function getInstallableAgents(): AgentDefinition[]; /** * Detects which agents are installed on the current system. * * Detection strategy (in order): * 1. Run agent's `detectInstalled` shell command (typically `which `) * 2. Fallback: check if the agent's global config directory exists * (e.g. ~/.cursor, ~/.windsurf — derived from globalSkillsDir parent) * * This two-tier approach catches desktop apps and IDE extensions that * create config directories but don't install CLI binaries in PATH. * * @returns Array of installed agent definitions */ export declare function detectInstalledAgents(): Promise; /** Enriched registry entry returned by getSupportedAgents(). */ export interface SupportedAgent { id: string; displayName: string; /** Whether the agent's binary or config dir was detected on this host. */ detected: boolean; /** Install tier — 1 (drop-in) | 2 (format-converted) | 3 (clipboard). */ tier: 1 | 2 | 3; /** "filesystem" or "clipboard" — defaults populated here so consumers * don't need to repeat the resolution logic. */ installMode: "filesystem" | "clipboard"; /** Tilde-expanded absolute path of the global skills dir. */ resolvedGlobalDir: string; /** Project-relative local skills dir (verbatim from registry). */ resolvedLocalDir: string; /** Tier 3 only — URL of the tool's docs page explaining how to paste. */ pasteInstructionsUrl?: string; /** Tier 3 only — docs landing page for the tool. */ docsUrl?: string; } /** * 0845 (AC-US1-01, AC-US6-02, AC-US6-03): Returns every registered agent * the Studio knows how to install to — Tier 1 / 2 (filesystem) and Tier 3 * (clipboard). Independent of binary detection: undetected agents are * still included, with `detected: false`. * * The exclusion gate is `installMode`. Entries without an explicit * `installMode` default to "filesystem" UNLESS they are flagged * `isRemoteOnly: true` — in which case they are excluded (preserves * the pre-existing semantics for Devin and Replit, which have no * clipboard fallback). Tier 3 entries (chatgpt, bolt-new, v0) are * kept by virtue of setting `installMode: "clipboard"` explicitly. * * Detection probes run in parallel via `Promise.allSettled` * (AC-US6-02). `detectInstalledAgents()` is UNCHANGED (AC-US6-03). */ export declare function getSupportedAgents(): Promise;