import { A as skillAgents, D as getUniversalSkillAgents, E as getSkillAgentTypes, O as isSkillAgentType, S as detectInstalledSkillAgents, T as getSkillAgentDir, a as filterSkillsByName, b as sanitizeName, h as cloneRepo, i as discoverSkills, j as CANONICAL_SKILLS_DIR, k as isUniversalSkillAgent, m as cleanupTempDir, n as installSkillsFromSource, r as parseSkillSource, v as fetchWellKnownSkills, y as fetchSkillManifestFromUrl } from "./skill-Bmk5QJQs.js"; import { t as toErrorMessage } from "./to-error-message-Bg0SEUet.js"; import { D as resolveMcpAgentAlias, a as installMcpServer, i as listInstalledMcpServers, l as parseMcpSource, n as removeMcpServer, v as detectGloballyInstalledMcpAgents, x as getMcpAgentTypes, y as detectProjectInstalledMcpAgents } from "./mcp-D24Z3PhI.js"; import { a as readAgentsMd, i as removeAgentsMdSection, n as upsertAgentsMdSection, p as listAgentsMdDescriptors, r as symlinkClaudeToAgents, s as resolveAgentsMdFilePath } from "./agents-md-DAu7ZRfo.js"; import { existsSync, readFileSync, writeFileSync } from "node:fs"; import { homedir } from "node:os"; import { basename, join } from "node:path"; import { mkdir, readdir, rm, stat, writeFile } from "node:fs/promises"; import { Command } from "commander"; import pc from "picocolors"; import prompts from "prompts"; //#region src/cli/utils/logger.ts const logger = { info: (message) => { console.log(pc.cyan("ℹ"), message); }, success: (message) => { console.log(pc.green("✔"), message); }, warn: (message) => { console.log(pc.yellow("⚠"), message); }, error: (message) => { console.error(pc.red("✖"), message); } }; //#endregion //#region src/cli/commands/doc/resolve-agent.ts const knownAgents = new Set(listAgentsMdDescriptors().map((descriptor) => descriptor.agent)); const isAgentsMdAgent = (value) => knownAgents.has(value); const resolveAgentsMdAgent = (value) => { if (value === void 0) return void 0; if (!isAgentsMdAgent(value)) throw new Error(`Unknown agent "${value}"`); return value; }; //#endregion //#region src/cli/commands/doc/init.ts const TEMPLATE = `# AGENTS.md This document is the source of truth for AI coding agents working in this repository. ## Project overview Short description of what this project does. ## Setup commands \`\`\`bash pnpm install pnpm dev \`\`\` ## Conventions - Describe coding style, framework, and patterns agents should follow. - Link to any other docs that are relevant. ## Testing \`\`\`bash pnpm test \`\`\` `; const docInitCommand = new Command("init").description("Create an AGENTS.md (or agent-specific variant) in the current directory").option("-a, --agent ", "Agent to target (defaults to universal AGENTS.md)").action((options) => { try { const filePath = resolveAgentsMdFilePath({ cwd: process.cwd(), agent: resolveAgentsMdAgent(options.agent) }); if (existsSync(filePath)) { logger.warn(`${pc.cyan(filePath)} already exists`); return; } writeFileSync(filePath, TEMPLATE, "utf-8"); logger.success(`Created ${pc.bold(filePath)}`); } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/doc/read.ts const docReadCommand = new Command("read").description("Read the current AGENTS.md (or agent-specific variant) and list its sections").option("-a, --agent ", "Agent variant to read (claude-code, cursor, codex, ...)").option("-f, --file ", "Explicit file path (overrides --agent)").option("--json", "Output as JSON").action((options) => { try { const document = readAgentsMd({ agent: resolveAgentsMdAgent(options.agent), file: options.file, cwd: process.cwd() }); if (options.json) { console.log(JSON.stringify({ path: document.path, sections: document.sections.map((section) => ({ heading: section.heading, level: section.level, body: section.body })) }, null, 2)); return; } if (!document.content) { logger.warn(`No file at ${pc.cyan(document.path)}`); return; } logger.info(pc.bold(document.path)); for (const section of document.sections) { const prefix = "#".repeat(section.level); console.log(` ${pc.dim(prefix)} ${section.heading}`); } } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/doc/remove-section.ts const docRemoveSectionCommand = new Command("remove-section").alias("rm-section").description("Remove a section from an AGENTS.md file").argument("", "Section heading to remove").option("-a, --agent ", "Agent variant to target").option("-f, --file ", "Explicit file path (overrides --agent)").action((heading, options) => { try { if (removeAgentsMdSection({ heading, agent: resolveAgentsMdAgent(options.agent), file: options.file, cwd: process.cwd() })) logger.success(`Removed ${pc.bold(heading)}`); else logger.warn(`Section ${pc.bold(heading)} not found`); } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/doc/set-section.ts const MIN_HEADING_LEVEL = 1; const MAX_HEADING_LEVEL = 6; const isValidPlacement = (value) => value === "append" || value === "prepend" || value === "replace"; const docSetSectionCommand = new Command("set-section").description("Create or replace a section in an AGENTS.md file").argument("", "Section heading (used as the Markdown heading)").option("-a, --agent ", "Agent variant to target").option("-f, --file ", "Explicit file path (overrides --agent)").option("--body ", "Inline body content").option("--body-file ", "Read body from a file").option("--placement ", "append, prepend, or replace (default: replace)").option("--level ", "Heading level (1-6, default: 2)").action((heading, options) => { try { const agent = resolveAgentsMdAgent(options.agent); const body = options.body ?? (options.bodyFile ? readFileSync(options.bodyFile, "utf-8") : ""); if (!body.trim()) throw new Error("Body is empty. Provide --body or --body-file with content."); const placement = options.placement ?? "replace"; if (!isValidPlacement(placement)) throw new Error(`Invalid placement "${placement}" (expected: append, prepend, replace)`); const level = options.level ? Number.parseInt(options.level, 10) : 2; if (!Number.isInteger(level) || level < MIN_HEADING_LEVEL || level > MAX_HEADING_LEVEL) throw new Error(`Invalid heading level "${options.level}" (expected: ${MIN_HEADING_LEVEL}-${MAX_HEADING_LEVEL})`); const filePath = upsertAgentsMdSection({ heading, body, agent, file: options.file, placement, level, cwd: process.cwd() }); logger.success(`Updated ${pc.bold(heading)} in ${pc.cyan(filePath)}`); } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/doc/symlink-claude.ts const docSymlinkClaudeCommand = new Command("symlink-claude").description("Create a CLAUDE.md → AGENTS.md symlink (migration helper)").option("--overwrite", "Replace an existing CLAUDE.md (backs it up first)").option("--backup ", "Backup filename if overwriting (default: CLAUDE.md.bak)").action(async (options) => { try { const result = await symlinkClaudeToAgents({ cwd: process.cwd(), overwrite: Boolean(options.overwrite), backupName: options.backup }); if (result.alreadyLinked) { logger.info(`CLAUDE.md already points to AGENTS.md`); return; } if (result.created) { const suffix = result.backedUpTo ? ` (backed up existing to ${pc.dim(result.backedUpTo)})` : ""; logger.success(`Linked ${pc.cyan(result.claudePath)} → AGENTS.md${suffix}`); return; } logger.warn(`CLAUDE.md already exists at ${pc.cyan(result.claudePath)}. Pass --overwrite to replace it.`); process.exitCode = 1; } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/doc/index.ts const docCommand = new Command("agents-md").alias("doc").description("Manage AGENTS.md / CLAUDE.md / GEMINI.md / Cursor rules").addCommand(docInitCommand).addCommand(docReadCommand).addCommand(docSetSectionCommand).addCommand(docRemoveSectionCommand).addCommand(docSymlinkClaudeCommand); //#endregion //#region src/cli/utils/format-agent-list.ts const formatAgentList = (agentList, emptyLabel = "(none)") => agentList.length === 0 ? emptyLabel : agentList.join(", "); //#endregion //#region src/cli/utils/parse-mcp-agent-list.ts const parseMcpAgentList = (input) => { if (!input || input.length === 0) return void 0; if (input.includes("*")) return getMcpAgentTypes(); const resolved = []; for (const value of input) { const agentType = resolveMcpAgentAlias(value); if (!agentType) throw new Error(`Unknown MCP agent "${value}"`); resolved.push(agentType); } return resolved; }; //#endregion //#region src/cli/commands/mcp/add.ts const parseKeyValueList = (entries, separator) => { if (!entries || entries.length === 0) return {}; const result = {}; for (const entry of entries) { const splitIndex = entry.indexOf(separator); if (splitIndex === -1) throw new Error(`Invalid entry "${entry}": expected "${separator}" separator`); const key = entry.slice(0, splitIndex).trim(); const value = entry.slice(splitIndex + separator.length).trim(); if (!key) throw new Error(`Invalid entry "${entry}": empty key`); result[key] = value; } return result; }; const resolveTransport = (input) => { if (!input) return void 0; if (input === "http" || input === "sse") return input; throw new Error(`Unsupported transport "${input}" (expected: http, sse)`); }; const detectCandidateAgents = (cwd, isGlobal) => isGlobal ? detectGloballyInstalledMcpAgents() : detectProjectInstalledMcpAgents(cwd); const mcpAddCommand = new Command("add").description("Add an MCP server to coding agents").argument("", "Remote URL, npm package, or command line").option("-a, --agent ", "Target specific agents (use '*' for all)").option("-g, --global", "Install to user-level config instead of project").option("-t, --transport ", "Transport type for remote servers (http or sse)").option("--header ", "HTTP header (Key: Value), repeatable").option("--env ", "Env var for stdio servers (KEY=VALUE), repeatable").option("-n, --name ", "Server name override").option("-y, --yes", "Skip all prompts").option("--all", "Install to all supported agents").action((source, options) => { try { const parsed = parseMcpSource(source); const cwd = process.cwd(); const isGlobal = Boolean(options.global); let agentTypes = options.all ? getMcpAgentTypes() : parseMcpAgentList(options.agent); if (!agentTypes) { const detected = detectCandidateAgents(cwd, isGlobal); if (detected.length === 0) { logger.warn(`No ${isGlobal ? "global" : "project"}-installed MCP agents detected. Pass ${pc.cyan("-a ")} (e.g. ${pc.cyan("-a cursor")}) or ${pc.cyan("--all")} to install.`); process.exitCode = 1; return; } agentTypes = detected; logger.info(`Detected ${isGlobal ? "global" : "project"} agents: ${pc.cyan(formatAgentList(detected, "(none detected)"))}`); } const result = installMcpServer({ source, name: options.name, agents: agentTypes, global: isGlobal, cwd, transport: resolveTransport(options.transport), headers: parseKeyValueList(options.header, ":"), env: parseKeyValueList(options.env, "=") }); logger.info(`Installing ${pc.bold(result.serverName)} (${pc.cyan(parsed.type)}) to ${pc.cyan(String(result.results.length))} agent(s)`); for (const record of result.results) if (record.success) logger.success(`${pc.cyan(record.agent)} ${pc.dim(record.path)}`); else logger.error(`${pc.cyan(record.agent)}: ${record.error}`); if (result.results.some((record) => !record.success)) process.exitCode = 1; } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/mcp/list.ts const mcpListCommand = new Command("list").alias("ls").description("List installed MCP servers across agents").option("-g, --global", "List global configs instead of project").option("-a, --agent ", "Filter by specific agents").option("--json", "Output as JSON").action((options) => { try { const entries = listInstalledMcpServers({ global: Boolean(options.global), cwd: process.cwd(), agents: parseMcpAgentList(options.agent) }); if (options.json) { console.log(JSON.stringify(entries, null, 2)); return; } if (entries.length === 0) { logger.warn("No MCP servers installed"); return; } const grouped = /* @__PURE__ */ new Map(); for (const entry of entries) { const existing = grouped.get(entry.serverName) ?? []; existing.push(entry); grouped.set(entry.serverName, existing); } for (const [serverName, group] of grouped) { const agentLabels = group.map((record) => record.agent).join(", "); console.log(` ${pc.bold(serverName)} ${pc.dim(`[${agentLabels}]`)}`); const firstPath = group[0]?.path; if (firstPath) console.log(` ${pc.dim(firstPath)}`); } } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/mcp/remove.ts const mcpRemoveCommand = new Command("remove").alias("rm").description("Remove an MCP server from agent configs").argument("", "Server name").option("-g, --global", "Remove from global scope").option("-a, --agent ", "Filter by specific agents (use '*' for all)").option("-y, --yes", "Skip confirmation prompts").action((name, options) => { try { const results = removeMcpServer({ name, agents: parseMcpAgentList(options.agent), global: Boolean(options.global), cwd: process.cwd() }); if (results.length === 0) { logger.warn(`No agent config contained ${pc.bold(name)}`); return; } for (const record of results) if (record.removed) logger.success(`${pc.cyan(record.agent)} removed ${pc.bold(name)} ${pc.dim(record.path)}`); else logger.error(`${pc.cyan(record.agent)}: ${record.error ?? "not found"}`); } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/mcp/index.ts const mcpCommand = new Command("mcp").description("Install, list, and remove MCP servers across coding agents").addCommand(mcpAddCommand).addCommand(mcpListCommand).addCommand(mcpRemoveCommand); //#endregion //#region src/cli/utils/parse-skill-agent-list.ts const parseSkillAgentList = (input) => { if (!input || input.length === 0) return void 0; if (input.includes("*")) return getSkillAgentTypes(); const validated = []; for (const value of input) { if (!isSkillAgentType(value)) throw new Error(`Unknown agent "${value}"`); validated.push(value); } return validated; }; //#endregion //#region src/cli/commands/skill/add.ts const resolveSkillFilter = (input) => { if (!input || input.length === 0) return void 0; if (input.includes("*")) return void 0; return input; }; const resolveTargetAgentsForPrompt = async (requested, yes) => { if (requested) return requested; const installed = await detectInstalledSkillAgents(); const fallback = installed.length > 0 ? installed : getUniversalSkillAgents(); if (yes || !process.stdin.isTTY) return fallback; const rawSelected = (await prompts({ type: "multiselect", name: "agents", message: "Install to which agents?", choices: Object.values(skillAgents).map((agent) => ({ title: agent.displayName, value: agent.name, selected: fallback.includes(agent.name) })), min: 1 })).agents; if (!Array.isArray(rawSelected) || rawSelected.length === 0) { logger.warn("No agents selected, using detected defaults"); return fallback; } const selected = rawSelected.filter((value) => typeof value === "string" && isSkillAgentType(value)); return selected.length > 0 ? selected : fallback; }; const listSkillsInSource = async (source) => { const parsed = parseSkillSource(source); let basePath = ""; let subpath; let cleanup; try { if (parsed.type === "local") basePath = parsed.localPath ?? parsed.url; else if (parsed.type === "url") { basePath = await fetchSkillManifestFromUrl(parsed.url); cleanup = () => cleanupTempDir(basePath); } else if (parsed.type === "well-known") { basePath = await fetchWellKnownSkills(parsed.url); cleanup = () => cleanupTempDir(basePath); } else { basePath = await cloneRepo(parsed.url, parsed.ref); subpath = parsed.subpath; cleanup = () => cleanupTempDir(basePath); } const skills = await discoverSkills(basePath, subpath); const visible = parsed.skillFilter ? filterSkillsByName(skills, [parsed.skillFilter]) : skills; if (visible.length === 0) { logger.warn("No SKILL.md files found in source"); return; } logger.info(`Found ${visible.length} skill${visible.length === 1 ? "" : "s"}`); for (const skill of visible) console.log(` ${pc.bold(skill.name)} ${pc.dim("-")} ${skill.description}`); } finally { await cleanup?.().catch(() => {}); } }; const skillAddCommand = new Command("add").description("Install skills from a source (local path, GitHub, or URL)").argument("", "Source to install skills from").option("-a, --agent ", "Target specific agents (use '*' for all)").option("-s, --skill ", "Install specific skills by name").option("-g, --global", "Install to ~/.agents/skills instead of the project").option("--copy", "Copy files instead of symlinking").option("-y, --yes", "Skip all prompts").option("-l, --list", "List available skills in the source without installing").action(async (source, options) => { try { if (options.list) { await listSkillsInSource(source); return; } const targetAgents = await resolveTargetAgentsForPrompt(parseSkillAgentList(options.agent), Boolean(options.yes)); const skillFilter = resolveSkillFilter(options.skill); const mode = options.copy ? "copy" : "symlink"; logger.info(`Installing from ${pc.cyan(source)} to ${pc.cyan(formatAgentList(targetAgents))}`); const result = await installSkillsFromSource({ source, agents: targetAgents, skills: skillFilter, global: options.global, mode, cwd: process.cwd() }); if (result.skills.length === 0) { logger.warn("No SKILL.md files found in source"); return; } for (const record of result.installed) { const fallbackSuffix = record.symlinkFailed ? pc.dim(" (copied: symlink fallback)") : ""; logger.success(`${pc.bold(record.skill)} → ${pc.cyan(record.agent)}${fallbackSuffix} ${pc.dim(record.path)}`); } for (const record of result.failed) logger.error(`${pc.bold(record.skill)} → ${pc.cyan(record.agent)}: ${record.error}`); if (result.failed.length > 0) process.exitCode = 1; } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/skill/init.ts const renderTemplate = (skillName) => `--- name: ${skillName} description: A brief description of what this skill does and when to use it. --- # ${skillName} Describe what this skill does, when the agent should use it, and the instructions the agent should follow when activated. ## When to use Describe the trigger conditions (e.g. "after finishing a feature", "when the user asks about X", "before committing React code"). ## Instructions 1. First step 2. Second step 3. Additional steps as needed `; const skillInitCommand = new Command("init").description("Create a new SKILL.md in the current directory").argument("[name]", "Skill name (defaults to current directory name)").action(async (nameArg) => { try { const cwd = process.cwd(); const skillName = nameArg || basename(cwd); const hasExplicitName = nameArg !== void 0; const skillDir = hasExplicitName ? join(cwd, skillName) : cwd; const skillFile = join(skillDir, "SKILL.md"); const displayPath = hasExplicitName ? `${skillName}/SKILL.md` : "SKILL.md"; if (existsSync(skillFile)) { logger.warn(`Skill already exists at ${pc.cyan(displayPath)}`); return; } if (hasExplicitName) await mkdir(skillDir, { recursive: true }); await writeFile(skillFile, renderTemplate(skillName), "utf-8"); logger.success(`Initialized skill ${pc.bold(skillName)}`); console.log(` ${pc.dim("Created:")} ${displayPath}`); console.log(); console.log(pc.dim("Next steps:")); console.log(` 1. Edit ${pc.cyan(displayPath)} to define your skill instructions`); console.log(` 2. Update the ${pc.cyan("name")} and ${pc.cyan("description")} frontmatter`); console.log(` 3. Install it locally with ${pc.cyan(`agent-install skill add ./${hasExplicitName ? skillName : "."}`)}`); } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/skill/list.ts const isUsableEntry = async (entry, fullPath) => { if (entry.isDirectory()) return true; if (!entry.isSymbolicLink()) return false; try { return (await stat(fullPath)).isDirectory(); } catch { return false; } }; const scanSkillsInDir = async (baseDir, agentType) => { const entries = await readdir(baseDir, { withFileTypes: true }).catch(() => []); const results = []; for (const entry of entries) { const skillDir = join(baseDir, entry.name); if (!await isUsableEntry(entry, skillDir)) continue; const skills = await discoverSkills(skillDir); for (const skill of skills) results.push({ skill: skill.name, agent: agentType, description: skill.description, path: skill.path }); } return results; }; const dirExists = (path) => { try { return existsSync(path); } catch { return false; } }; const getCanonicalDir = (isGlobal, cwd) => isGlobal ? join(homedir(), CANONICAL_SKILLS_DIR) : join(cwd, CANONICAL_SKILLS_DIR); const collectListEntries = async (options) => { const { isGlobal, cwd, filter } = options; const allEntries = []; const visitedDirs = /* @__PURE__ */ new Set(); const visit = async (dir, agent) => { if (visitedDirs.has(dir)) return; visitedDirs.add(dir); allEntries.push(...await scanSkillsInDir(dir, agent)); }; if (filter) { for (const agentType of filter) await visit(getSkillAgentDir(agentType, { global: isGlobal, cwd }), agentType); return allEntries; } await visit(getCanonicalDir(isGlobal, cwd), "universal"); const installedAgents = new Set(await detectInstalledSkillAgents()); for (const agentType of getSkillAgentTypes()) { if (agentType === "universal") continue; if (isUniversalSkillAgent(agentType)) continue; const baseDir = getSkillAgentDir(agentType, { global: isGlobal, cwd }); if (!installedAgents.has(agentType) && !dirExists(baseDir)) continue; await visit(baseDir, agentType); } return allEntries; }; const skillListCommand = new Command("list").alias("ls").description("List installed skills").option("-g, --global", "List global skills instead of project skills").option("-a, --agent ", "Filter by specific agents").option("--json", "Output as JSON").action(async (options) => { try { const cwd = process.cwd(); const allEntries = await collectListEntries({ isGlobal: Boolean(options.global), cwd, filter: parseSkillAgentList(options.agent) }); if (options.json) { console.log(JSON.stringify(allEntries, null, 2)); return; } if (allEntries.length === 0) { logger.warn("No installed skills found"); return; } const bySkill = /* @__PURE__ */ new Map(); for (const entry of allEntries) { const existing = bySkill.get(entry.skill) ?? []; existing.push(entry); bySkill.set(entry.skill, existing); } const formatAgent = (agent) => agent === "universal" ? "canonical" : skillAgents[agent].displayName; for (const [skillName, entries] of bySkill) { const first = entries[0]; if (!first) continue; const agentLabels = Array.from(new Set(entries.map((entry) => formatAgent(entry.agent)))); const description = first.description || basename(first.path); console.log(` ${pc.bold(skillName)} ${pc.dim(`[${agentLabels.join(", ")}]`)}\n ${pc.dim(description)}`); } } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/skill/remove.ts const skillRemoveCommand = new Command("remove").alias("rm").description("Remove installed skills").argument("[skills...]", "Skills to remove (omit for interactive selection)").option("-g, --global", "Remove from global scope").option("-a, --agent ", "Remove from specific agents (use '*' for all)").option("-y, --yes", "Skip confirmation prompts").action(async (skillArgs, options) => { try { const cwd = process.cwd(); const isGlobal = Boolean(options.global); const agentFilter = parseSkillAgentList(options.agent) ?? getSkillAgentTypes(); let skillNames = skillArgs; if (skillNames.length === 0) { if (options.yes || !process.stdin.isTTY) { logger.warn("No skill names provided"); return; } const response = await prompts({ type: "text", name: "skill", message: "Skill name to remove" }); if (!response.skill) return; skillNames = [response.skill]; } const canonicalBase = isGlobal ? join(homedir(), CANONICAL_SKILLS_DIR) : join(cwd, CANONICAL_SKILLS_DIR); for (const rawName of skillNames) { const sanitized = sanitizeName(rawName); await rm(join(canonicalBase, sanitized), { recursive: true, force: true }).catch(() => {}); for (const agentType of agentFilter) { if (agentType === "universal") continue; await rm(join(getSkillAgentDir(agentType, { global: isGlobal, cwd }), sanitized), { recursive: true, force: true }).catch(() => {}); } logger.success(`Removed ${pc.bold(rawName)}`); } } catch (error) { logger.error(toErrorMessage(error)); process.exitCode = 1; } }); //#endregion //#region src/cli/commands/skill/index.ts const skillCommand = new Command("skill").description("Manage SKILL.md files").addCommand(skillAddCommand).addCommand(skillInitCommand).addCommand(skillListCommand).addCommand(skillRemoveCommand); //#endregion //#region src/cli.ts const VERSION = "0.0.6"; process.on("SIGINT", () => process.exit(0)); process.on("SIGTERM", () => process.exit(0)); const program = new Command().name("agent-install").description("Install SKILL.md files, MCP servers, and AGENTS.md guidance for any coding agent").version(VERSION, "-v, --version", "display the version number"); program.addCommand(skillCommand); program.addCommand(mcpCommand); program.addCommand(docCommand); const main = async () => { await program.parseAsync(); }; main(); //#endregion export {};