agent-skills-standard 2.4.2 ā 2.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -20
- package/dist/index.js +57 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/services/FeedbackService.ts","../src/commands/feedback.ts","../src/constants/enums.ts","../src/constants/skills.ts","../src/constants/index.ts","../src/services/ConfigService.ts","../src/services/HookService.ts","../src/commands/hooks.ts","../src/services/DetectionService.ts","../src/services/InitService.ts","../src/services/GithubService.ts","../src/services/RegistryService.ts","../src/commands/init.ts","../src/services/SkillService.ts","../src/commands/list-skills.ts","../src/services/McpConfigService.ts","../src/commands/mcp.ts","../src/services/AgentBridgeService.ts","../src/services/IndexContentBuilder.ts","../src/services/IndexGeneratorService.ts","../src/constants/security.ts","../src/services/MetadataReader.ts","../src/services/IndexGeneratorServiceImpl.ts","../src/services/SkillSyncService.ts","../src/services/utils/WorkflowTransformer.ts","../src/services/WorkflowSyncService.ts","../src/services/utils/SpecialistTransformer.ts","../src/services/SpecialistSyncService.ts","../src/services/GitService.ts","../src/services/utils/MarkdownUtils.ts","../src/services/SyncService.ts","../src/commands/sync.ts","../package.json","../src/commands/upgrade.ts","../src/services/SkillDiscoveryService.ts","../src/services/validation/rules.ts","../src/services/SkillValidator.ts","../src/commands/validate-skills.ts","../src/index.ts"],"sourcesContent":["/**\n * Structure of the feedback data payload submitted to the backend.\n * Contains both required issue details and optional context gathered by the AI.\n */\nexport interface FeedbackData {\n /** The specific skill ID that had the issue */\n skill: string;\n /** Detailed description of the problem */\n issue: string;\n\n /** Multi-line context about where the error occurred */\n context?: string;\n /** The AI model used when the issue was detected */\n model?: string;\n /** Proposed fix or improvement */\n suggestion?: string;\n\n /** Exact instruction from the skill that was misinterpreted */\n skillInstruction?: string;\n /** What the AI actually did instead of following the skill */\n actualAction?: string;\n /** Rationale for choosing the incorrect path */\n decisionReason?: string;\n\n /** List of other active skills at the time of the error */\n loadedSkills?: string;\n\n /** Why the violation happened: AMBIGUOUS_RULE | MISSING_COVERAGE | OUTDATED_GUIDANCE | COMPETING_RULES | PATTERN_MISMATCH */\n rootCause?: string;\n /** One sentence: what the user was trying to achieve */\n userIntent?: string;\n /** What change to the SKILL.md would prevent this violation next time */\n skillGap?: string;\n}\n\n/**\n * Service to handle automated feedback reporting via Proxy Backend.\n * Follows SOLID & KISS: Strictly handles API communication.\n */\nexport class FeedbackService {\n /**\n * Allowed origin prefix for the feedback API to prevent SSRF.\n * Only requests to this domain (or its subdomains) are permitted.\n */\n private static readonly ALLOWED_ORIGIN =\n 'https://agent-skills-feedback.vercel.app';\n\n /**\n * Resolves the API URL from environment variables.\n */\n getApiUrl(): string | undefined {\n return process.env.FEEDBACK_API_URL;\n }\n\n /**\n * Validates if the given URL is safe and points to the allowed feedback origin.\n * @param url The URL to validate\n * @returns boolean\n */\n private isSafeUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isHttps = parsed.protocol === 'https:';\n const isVercelHostname =\n parsed.hostname === 'agent-skills-feedback.vercel.app' ||\n parsed.hostname.endsWith('.agent-skills-feedback.vercel.app');\n\n return isHttps && isVercelHostname;\n } catch {\n return false;\n }\n }\n\n /**\n * Submits feedback data to the backend for automatic GitHub Issue creation.\n * Internal proxy handles GitHub tokens, keeping client-side logic tokenless.\n *\n * @param data The feedback payload\n * @returns boolean indicating submission success\n */\n async submit(data: FeedbackData): Promise<boolean> {\n const apiUrl = this.getApiUrl();\n\n if (!apiUrl) return false;\n\n // Validate origin to prevent SSRF/Data Exfiltration (Finding Security-NIT)\n if (!this.isSafeUrl(apiUrl)) {\n if (process.env.DEBUG) {\n console.warn(`[FeedbackService] Disallowed API URL origin: ${apiUrl}`);\n }\n return false;\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'agent-skills-standard-cli',\n },\n body: JSON.stringify(data),\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { FeedbackData, FeedbackService } from '../services/FeedbackService';\n\n/**\n * Command for automated skill feedback reporting.\n * Follows KISS: Minimal user output, focusing on functional submission.\n */\nexport class FeedbackCommand {\n private feedbackService: FeedbackService;\n\n constructor(feedbackService?: FeedbackService) {\n this.feedbackService = feedbackService || new FeedbackService();\n }\n\n async run(options: {\n skill?: string;\n issue?: string;\n model?: string;\n context?: string;\n suggestion?: string;\n skillInstruction?: string;\n actualAction?: string;\n decisionReason?: string;\n loadedSkills?: string;\n rootCause?: string;\n userIntent?: string;\n skillGap?: string;\n }) {\n console.log(pc.bold(pc.blue('\\nš£ Agent Skills Feedback Reporter\\n')));\n\n let {\n skill,\n issue,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n } = options;\n\n // Interactive mode if mandatory options are missing\n if (!skill || !issue) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'skill',\n message:\n 'Which skill ID has the issue? (e.g., flutter/bloc-state-management)',\n when: !skill,\n validate: (input: string) =>\n input.trim().length > 0 || 'Skill ID is required',\n },\n {\n type: 'input',\n name: 'issue',\n message: 'What is the issue? (Brief description)',\n when: !issue,\n validate: (input: string) =>\n input.trim().length > 0 || 'Issue description is required',\n },\n {\n type: 'input',\n name: 'model',\n message: 'AI Model name (optional, e.g., Claude 3.5 Sonnet)',\n when: !model,\n },\n {\n type: 'input',\n name: 'context',\n message: 'Any extra context? (optional, e.g., framework versions)',\n when: !context,\n },\n {\n type: 'input',\n name: 'suggestion',\n message: 'Any suggested improvement? (optional)',\n when: !suggestion,\n },\n {\n type: 'input',\n name: 'skillInstruction',\n message: 'Exact quote from skill (optional)',\n when: !skillInstruction,\n },\n {\n type: 'input',\n name: 'actualAction',\n message: 'What you did instead (optional)',\n when: !actualAction,\n },\n {\n type: 'input',\n name: 'decisionReason',\n message: 'Why you chose this approach (optional)',\n when: !decisionReason,\n },\n {\n type: 'input',\n name: 'loadedSkills',\n message: 'All active skills (optional)',\n when: !loadedSkills,\n },\n {\n type: 'list',\n name: 'rootCause',\n message: 'Root cause of the violation (optional)',\n when: !rootCause,\n choices: [\n { name: 'Skip', value: '' },\n 'AMBIGUOUS_RULE',\n 'MISSING_COVERAGE',\n 'OUTDATED_GUIDANCE',\n 'COMPETING_RULES',\n 'PATTERN_MISMATCH',\n ],\n },\n {\n type: 'input',\n name: 'userIntent',\n message: 'What was the user trying to achieve? (optional)',\n when: !userIntent,\n },\n {\n type: 'input',\n name: 'skillGap',\n message: 'What change to the skill would prevent this? (optional)',\n when: !skillGap,\n },\n ]);\n\n skill = skill || (answers.skill as string);\n issue = issue || (answers.issue as string);\n model = model || (answers.model as string);\n context = context || (answers.context as string);\n suggestion = suggestion || (answers.suggestion as string);\n skillInstruction =\n skillInstruction || (answers.skillInstruction as string);\n actualAction = actualAction || (answers.actualAction as string);\n decisionReason = decisionReason || (answers.decisionReason as string);\n loadedSkills = loadedSkills || (answers.loadedSkills as string);\n rootCause = rootCause || (answers.rootCause as string) || undefined;\n userIntent = userIntent || (answers.userIntent as string);\n skillGap = skillGap || (answers.skillGap as string);\n\n await this.submit({\n skill: skill!,\n issue: issue!,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n });\n } else {\n await this.submit({\n skill,\n issue,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n });\n }\n }\n\n private async submit(data: FeedbackData) {\n const apiUrl = this.feedbackService.getApiUrl();\n\n if (!apiUrl) {\n console.log(pc.yellow('\\nā ļø Feedback API not configured.'));\n console.log(\n pc.gray(\n 'Please set the ' +\n pc.bold('FEEDBACK_API_URL') +\n ' environment variable.',\n ),\n );\n return;\n }\n\n console.log(pc.gray(`š¤ Sending feedback to ${apiUrl}...`));\n\n const success = await this.feedbackService.submit(data);\n\n if (success) {\n console.log(pc.green('\\nā
Feedback has been sent successfully!'));\n console.log(\n pc.gray('Thank you for helping improve the Agent Skills Standard.\\n'),\n );\n } else {\n console.log(pc.red('\\nā Failed to send feedback.'));\n console.log(\n pc.gray(\n `Please check that the Feedback API is reachable: ${pc.cyan(apiUrl)}\\n`,\n ),\n );\n }\n }\n}\n","export enum Agent {\n Cursor = 'cursor',\n Trae = 'trae',\n Claude = 'claude',\n Copilot = 'copilot',\n Antigravity = 'antigravity',\n Codex = 'codex',\n OpenCode = 'opencode',\n Gemini = 'gemini',\n Roo = 'roo',\n Windsurf = 'windsurf',\n Kiro = 'kiro',\n}\n\nexport enum Framework {\n Flutter = 'flutter',\n NestJS = 'nestjs',\n Golang = 'golang',\n NextJS = 'nextjs',\n React = 'react',\n ReactNative = 'react-native',\n Angular = 'angular',\n SpringBoot = 'spring-boot',\n Android = 'android',\n iOS = 'ios',\n Laravel = 'laravel',\n}\n","import { Framework } from './enums';\n\n/**\n * SkillDetection defines how to automatically enable a skill based on project dependencies.\n */\nexport interface SkillDetection {\n /** The skill ID as defined in the registry (e.g., 'riverpod-state-management') */\n id: string;\n /** List of npm or pub packages that indicate this skill is used */\n packages: string[];\n /** Optional list of root folder/file paths (relative to cwd). If any exist, the skill is detected. */\n files?: string[];\n}\n\n/**\n * Registry of automatic skill detection rules grouped by framework.\n */\nexport const SKILL_DETECTION_REGISTRY: Record<string, SkillDetection[]> = {\n [Framework.Flutter]: [\n {\n id: 'flutter-riverpod-state-management',\n packages: ['flutter_riverpod', 'riverpod'],\n },\n {\n id: 'flutter-bloc-state-management',\n packages: ['flutter_bloc', 'bloc'],\n },\n {\n id: 'flutter-auto-route-navigation',\n packages: ['auto_route'],\n },\n {\n id: 'flutter-go-router-navigation',\n packages: ['go_router'],\n },\n {\n id: 'flutter-getx-navigation',\n packages: ['get'], // Special handling for exact match required\n },\n {\n id: 'flutter-getx-state-management',\n packages: ['get'], // Special handling for exact match required\n },\n {\n id: 'flutter-localization',\n packages: ['easy_localization'],\n },\n {\n id: 'flutter-retrofit-networking',\n packages: ['retrofit'],\n },\n {\n id: 'flutter-dependency-injection',\n packages: ['get_it', 'injectable'],\n },\n ],\n [Framework.NestJS]: [\n {\n id: 'nestjs-caching',\n packages: ['@nestjs/cache-manager', 'cache-manager'],\n },\n {\n id: 'nestjs-database',\n packages: ['@nestjs/typeorm', '@nestjs/prisma', '@nestjs/mongoose'],\n },\n {\n id: 'nestjs-security',\n packages: ['@nestjs/passport', 'passport', 'helmet'],\n },\n ],\n [Framework.Android]: [\n {\n id: 'android-compose',\n packages: ['androidx.compose.ui'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-navigation',\n packages: ['androidx.navigation:navigation-compose'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-legacy-navigation',\n packages: [\n 'androidx.navigation:navigation-fragment',\n 'androidx.navigation:navigation-ui',\n ],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-di',\n packages: ['hilt-android', 'dagger-android'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-persistence',\n packages: ['androidx.room:room-runtime'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-networking',\n packages: ['retrofit'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-concurrency',\n packages: ['kotlinx-coroutines-android'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n ],\n [Framework.iOS]: [\n {\n id: 'ios-networking',\n packages: ['Alamofire', 'Moya'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-dependency-injection',\n packages: ['Swinject', 'Resolver'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-persistence',\n packages: ['Realm', 'CoreData', 'SQLite.swift'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-state-management',\n packages: ['ComposableArchitecture', 'CombineRuntime'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-ui-navigation',\n packages: ['Coordinator', 'Router'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n ],\n [Framework.ReactNative]: [\n {\n id: 'react-native-navigation',\n packages: ['@react-navigation/native'],\n },\n {\n id: 'react-native-state-management',\n packages: ['zustand', '@reduxjs/toolkit'],\n },\n {\n id: 'react-native-deployment',\n packages: ['react-native-code-push', 'expo-updates'],\n },\n {\n id: 'react-native-security',\n packages: ['react-native-keychain', 'react-native-ssl-pinning'],\n },\n {\n id: 'react-native-performance',\n packages: ['react-native-fast-image'],\n },\n ],\n [Framework.Laravel]: [\n {\n id: 'laravel-api',\n packages: ['laravel/sanctum', 'laravel/passport'],\n },\n {\n id: 'laravel-background-processing',\n packages: ['laravel/horizon'],\n },\n {\n id: 'laravel-testing',\n packages: ['pestphp/pest', 'phpunit/phpunit'],\n },\n {\n id: 'laravel-tooling',\n packages: ['laravel/pint', 'laravel/sail'],\n },\n {\n id: 'laravel-database-expert',\n packages: ['laravel/framework'], // Always present, but used for sub-skill mapping\n },\n ],\n [Framework.NextJS]: [\n {\n id: 'nextjs-pages-router',\n packages: [],\n files: ['pages', 'src/pages'],\n },\n {\n id: 'nextjs-server-components',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-server-actions',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-data-fetching',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-i18n',\n packages: ['next-intl', 'react-intl', 'next-translate', 'i18next'],\n files: [\n 'middleware.ts',\n 'app/[lang]',\n 'pages/[locale]',\n 'next.config.js',\n ],\n },\n ],\n [Framework.React]: [\n {\n id: 'react-styling',\n packages: ['tailwind', 'antd', 'sass', 'styled-components', 'emotion'],\n },\n {\n id: 'react-state-management',\n packages: [\n 'redux',\n '@reduxjs/toolkit',\n 'zustand',\n 'mobx',\n 'recoil',\n 'jotai',\n ],\n },\n {\n id: 'react-testing',\n packages: [\n 'jest',\n 'vitest',\n '@testing-library/react',\n 'cypress',\n 'playwright',\n ],\n },\n ],\n database: [\n {\n id: 'database-postgresql',\n packages: ['pg', 'pgx', 'postgres', 'sequelize', 'typeorm', 'prisma'],\n },\n {\n id: 'database-mongodb',\n packages: ['mongodb', 'mongoose'],\n },\n {\n id: 'database-redis',\n packages: ['redis', 'ioredis', 'predis'],\n },\n ],\n};\n","import { Agent, Framework } from './enums';\n\nexport { Agent, Framework };\n\nexport const UNIVERSAL_SKILLS = ['common'];\nexport const BACKEND_FRAMEWORKS: Framework[] = [\n Framework.NestJS,\n Framework.Golang,\n Framework.SpringBoot,\n Framework.Laravel,\n];\n\nexport const FRONTEND_FRAMEWORKS: Framework[] = [\n Framework.React,\n Framework.NextJS,\n Framework.Angular,\n];\n\nexport const MOBILE_FRAMEWORKS: Framework[] = [\n Framework.Flutter,\n Framework.Android,\n Framework.iOS,\n Framework.ReactNative,\n];\n\nexport const FRONTEND_REACT_FRAMEWORKS: Framework[] = [\n Framework.NextJS,\n Framework.ReactNative,\n];\n\n/**\n * Sub-skills to exclude from the `common` category based on the selected framework type.\n * Backend: exclude web-only and mobile-only skills.\n * Frontend: exclude backend-only and mobile-only skills.\n * Mobile: exclude web-only and backend-only skills.\n */\nexport const COMMON_SKILL_EXCLUDES: Record<\n 'backend' | 'frontend' | 'mobile',\n string[]\n> = {\n backend: [\n 'common-accessibility',\n 'common-mobile-animation',\n 'common-mobile-ux-core',\n 'common-store-changelog',\n 'common-ui-design',\n ],\n frontend: [\n 'common-observability',\n 'common-mobile-animation',\n 'common-mobile-ux-core',\n 'common-store-changelog',\n ],\n mobile: [\n 'common-accessibility',\n 'common-api-design',\n 'common-observability',\n 'common-system-design',\n ],\n};\n\n/**\n * Classifies a framework ID into its platform type for skill exclusion purposes.\n * Returns null for unknown/hybrid frameworks ā no exclusions are applied.\n */\nexport function getFrameworkType(\n framework: string,\n): 'backend' | 'frontend' | 'mobile' | null {\n if (BACKEND_FRAMEWORKS.includes(framework as Framework)) return 'backend';\n if (MOBILE_FRAMEWORKS.includes(framework as Framework)) return 'mobile';\n if (FRONTEND_FRAMEWORKS.includes(framework as Framework)) return 'frontend';\n return null;\n}\n\nexport const DEFAULT_REGISTER =\n 'https://github.com/HoangNguyen0403/agent-skills-standard';\n\nexport const DEFAULT_WORKFLOWS = [\n 'sdlc',\n 'brainstorm-feature',\n 'code-review',\n 'codebase-review',\n 'design-solution',\n 'deploy-release',\n 'plan-feature',\n 'implementation-readiness',\n 'review-ticket',\n 'traceability-audit',\n 'session-report',\n 'publish-notes',\n 'retro-learn',\n 'skill-benchmark',\n 'pentest',\n 'dev-fix',\n 'implement-feature',\n 'verify-work',\n 'verify-bug',\n 'security-test',\n];\n\n// Configurable via ENV or hardcoded for production convenience\n/**\n * Defines how workflows are delivered to each agent platform.\n * Workflows are user-invoked multi-step procedures (not passive rules).\n * - 'native': Direct markdown workflow files, executed by the agent's workflow runner (Antigravity, Kiro)\n * - 'command': Custom slash command files ā inline the procedure (Claude: .claude/commands/*.md)\n * - 'toml': TOML command files ā reference the workflow by path (Gemini: .gemini/commands/*.toml)\n * - 'prompt': Reusable prompt files (Copilot: .github/prompts/*.prompt.md)\n * - 'none': Agent has no verified user-invoked command system\n */\nexport type WorkflowFormat =\n | 'native'\n | 'command'\n | 'toml'\n | 'prompt'\n | 'skill'\n | 'none';\n\nexport interface AgentDefinition {\n id: Agent;\n name: string;\n path: string;\n ruleFile: string;\n ruleExtension: string;\n ruleFileName?: string;\n frontmatterStyle: 'cursor' | 'copilot' | 'none';\n detectionFiles: string[];\n /** How workflows should be transformed for this agent */\n workflowFormat: WorkflowFormat;\n /** Directory where transformed workflows are written (relative to cwd) */\n workflowPath: string;\n /** Directory where native specialist agent personas are written (optional) */\n agentPath?: string;\n /** Relative path to pre-edit hook reminder script (if supported) */\n hookScriptPath?: string;\n /** Relative path to hook configuration JSON file (if supported) */\n hookConfigPath?: string;\n}\n\nexport interface FrameworkDefinition {\n id: Framework;\n name: string;\n languages: string[];\n detectionFiles: string[];\n detectionDependencies?: string[];\n languageDetection?: Record<string, string[]>;\n}\n\nexport const getAgentDefinition = (id: Agent): AgentDefinition => {\n switch (id) {\n case Agent.Cursor:\n return {\n id,\n name: 'Cursor',\n path: '.cursor/skills',\n ruleFile: '.cursor/rules',\n ruleExtension: '.mdc',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.cursor', '.cursorrules'],\n workflowFormat: 'skill',\n workflowPath: '.cursor/skills',\n agentPath: '.cursor/agents',\n hookScriptPath: '.cursor/hooks/preedit-skill-loader.js',\n hookConfigPath: '.cursor/hooks.json',\n };\n case Agent.Trae:\n return {\n id,\n name: 'Trae',\n path: '.trae/skills',\n ruleFile: '.trae/rules',\n ruleExtension: '.mdc',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.trae'],\n workflowFormat: 'skill',\n workflowPath: '.trae/skills',\n };\n case Agent.Claude:\n return {\n id,\n name: 'Claude Code',\n path: '.claude/skills',\n ruleFile: '.',\n ruleExtension: '.md',\n ruleFileName: 'CLAUDE.md',\n frontmatterStyle: 'none',\n detectionFiles: ['.claude'],\n workflowFormat: 'command',\n workflowPath: '.claude/commands',\n agentPath: '.claude/agents',\n hookScriptPath: '.claude/hooks/preedit-skill-loader.js',\n hookConfigPath: '.claude/settings.json',\n };\n case Agent.Copilot:\n return {\n id,\n name: 'GitHub Copilot',\n path: '.github/skills',\n ruleFile: '.github/instructions',\n ruleExtension: '.instructions.md',\n frontmatterStyle: 'copilot',\n detectionFiles: ['.github'],\n workflowFormat: 'prompt',\n workflowPath: '.github/prompts',\n agentPath: '.github/copilot-agents',\n hookScriptPath: '.github/hooks/preedit-skill-loader.js',\n hookConfigPath: '.github/hooks.json',\n };\n case Agent.Antigravity:\n return {\n id,\n name: 'Antigravity',\n path: '.agents/skills',\n ruleFile: '.agents/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.agents'],\n workflowFormat: 'native',\n workflowPath: '.agents/workflows',\n };\n case Agent.Codex:\n return {\n id,\n name: 'Codex',\n path: '.codex/skills',\n ruleFile: '.codex/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.codex'],\n workflowFormat: 'skill',\n workflowPath: '.codex/skills',\n agentPath: '.codex/agents',\n hookScriptPath: '.codex/hooks/preedit-skill-loader.js',\n hookConfigPath: '.codex/hooks.json',\n };\n case Agent.OpenCode:\n return {\n id,\n name: 'OpenCode',\n path: '.opencode/skills',\n ruleFile: '.opencode/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.opencode'],\n workflowFormat: 'command',\n workflowPath: '.opencode/commands',\n agentPath: '.opencode/agents',\n };\n case Agent.Gemini:\n return {\n id,\n name: 'Gemini',\n path: '.gemini/skills',\n ruleFile: '.gemini/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.gemini'],\n workflowFormat: 'toml',\n workflowPath: '.gemini/commands',\n agentPath: '.gemini/agents',\n hookScriptPath: '.gemini/hooks/preedit-skill-loader.js',\n hookConfigPath: '.gemini/hooks.json',\n };\n case Agent.Roo:\n return {\n id,\n name: 'Roo Code',\n path: '.roo/skills',\n ruleFile: '.roo/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.roo'],\n workflowFormat: 'command',\n workflowPath: '.roo/commands',\n };\n case Agent.Windsurf:\n return {\n id,\n name: 'Windsurf',\n path: '.windsurf/skills',\n ruleFile: '.windsurf/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.windsurf'],\n workflowFormat: 'none',\n workflowPath: '',\n hookScriptPath: '.windsurf/hooks/preedit-skill-loader.js',\n hookConfigPath: '.windsurf/hooks.json',\n };\n case Agent.Kiro:\n return {\n id,\n name: 'Kiro',\n path: '.kiro/skills',\n ruleFile: '.kiro/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.kiro'],\n workflowFormat: 'native',\n workflowPath: '.agents/workflows',\n agentPath: '.kiro/agents',\n hookScriptPath: '.kiro/hooks/ags-skill-loader.md',\n };\n }\n};\n\nexport const getFrameworkDefinition = (id: Framework): FrameworkDefinition => {\n switch (id) {\n case Framework.Flutter:\n return {\n id,\n name: 'Flutter',\n languages: ['dart'],\n detectionFiles: ['pubspec.yaml'],\n };\n case Framework.NestJS:\n return {\n id,\n name: 'NestJS',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['nest-cli.json'],\n detectionDependencies: ['@nestjs/core'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.Golang:\n return {\n id,\n name: 'Go (Golang)',\n languages: ['go'],\n detectionFiles: ['go.mod'],\n };\n case Framework.NextJS:\n return {\n id,\n name: 'Next.js',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['next.config.js', 'next.config.mjs'],\n detectionDependencies: ['next'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.React:\n return {\n id,\n name: 'React',\n languages: ['typescript', 'javascript'],\n detectionFiles: [],\n detectionDependencies: ['react', 'react-dom'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.ReactNative:\n return {\n id,\n name: 'React Native',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['metro.config.js'],\n detectionDependencies: ['react-native'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.Angular:\n return {\n id,\n name: 'Angular',\n languages: ['typescript'],\n detectionFiles: ['angular.json'],\n };\n case Framework.SpringBoot:\n return {\n id,\n name: 'Spring Boot',\n languages: ['java', 'kotlin'],\n detectionFiles: ['pom.xml', 'build.gradle', 'build.gradle.kts'],\n languageDetection: {\n kotlin: ['src/main/kotlin', 'build.gradle.kts'],\n java: ['src/main/java'],\n },\n };\n case Framework.Android:\n return {\n id,\n name: 'Android',\n languages: ['kotlin', 'java'],\n detectionFiles: [\n 'build.gradle',\n 'build.gradle.kts',\n 'AndroidManifest.xml',\n ],\n languageDetection: {\n kotlin: ['src/main/kotlin', 'build.gradle.kts'],\n java: ['src/main/java'],\n },\n };\n case Framework.iOS:\n return {\n id,\n name: 'iOS (Swift/SwiftUI)',\n languages: ['swift'],\n detectionFiles: [\n 'Podfile',\n 'Package.swift',\n 'project.pbxproj',\n 'Info.plist',\n ],\n languageDetection: {\n swift: ['.swift'],\n },\n };\n case Framework.Laravel:\n return {\n id,\n name: 'Laravel',\n languages: ['php', 'javascript'],\n detectionFiles: ['composer.json', 'artisan'],\n detectionDependencies: ['laravel/framework'],\n languageDetection: {\n php: ['.php'],\n javascript: ['resources/js', 'vite.config.js'],\n },\n };\n }\n};\n\nexport const SUPPORTED_AGENTS: AgentDefinition[] =\n Object.values(Agent).map(getAgentDefinition);\n\nexport const SUPPORTED_FRAMEWORKS: FrameworkDefinition[] = Object.values(\n Framework,\n).map(getFrameworkDefinition);\n\nexport { SKILL_DETECTION_REGISTRY } from './skills';\nexport type { SkillDetection } from './skills';\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport { z } from 'zod';\nimport {\n Agent,\n BACKEND_FRAMEWORKS,\n COMMON_SKILL_EXCLUDES,\n DEFAULT_REGISTER,\n Framework,\n FrameworkDefinition,\n FRONTEND_REACT_FRAMEWORKS,\n getFrameworkType,\n SKILL_DETECTION_REGISTRY,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\nimport { CategoryConfig, SkillConfig } from '../models/config';\nimport { RegistryMetadata } from '../models/types';\n\nconst McpScopeSchema = z.enum(['project', 'user', 'snippets-only', 'disabled']);\n\nconst McpConfigSchema = z.object({\n enabled: z.boolean(),\n scope: McpScopeSchema,\n prompted: z.boolean(),\n version: z.string().optional(),\n snippets: z.boolean().optional(),\n});\n\nconst SkillConfigSchema = z.object({\n registry: z.string().url(),\n agents: z.preprocess(\n (val) => {\n if (Array.isArray(val)) {\n return val.map((a) =>\n typeof a === 'string' && a.toLowerCase() === 'openai' ? 'codex' : a,\n );\n }\n return val;\n },\n z.array(z.nativeEnum(Agent)).optional(),\n ),\n skills: z.record(\n z.string(), // Category name\n z.object({\n ref: z.string().optional(),\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n }),\n ),\n custom_overrides: z.array(z.string()).optional(),\n workflows: z.union([z.boolean(), z.array(z.string())]).optional(),\n mcp: McpConfigSchema.optional(),\n});\n\nconst DEFAULT_SDLC_SUPPORT_CATEGORIES = ['quality-engineering'] as const;\n\n/**\n * Service for managing the `.skillsrc` configuration file.\n * Handles loading, saving, and initial construction of the configuration based on project metadata.\n */\nexport class ConfigService {\n private getCategoryRef(\n category: string,\n metadata: Partial<RegistryMetadata>,\n ): string {\n const categoryMetadata = metadata.categories?.[category];\n if (!categoryMetadata?.version) return 'main';\n return `${categoryMetadata.tag_prefix || ''}${categoryMetadata.version}`;\n }\n\n /**\n * Loads and validates the skill configuration from the workspace.\n * @param cwd Current working directory\n * @returns The parsed SkillConfig or null if not found\n * @throws Error if the configuration format is invalid\n */\n async loadConfig(cwd: string = process.cwd()): Promise<SkillConfig | null> {\n const configPath = path.join(cwd, '.skillsrc');\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n try {\n const content = await fs.readFile(configPath, 'utf8');\n const rawConfig = yaml.load(content) as Record<string, unknown>;\n\n // Backward compatibility & self-healing migration for legacy 'openai' agent configs\n if (rawConfig && Array.isArray(rawConfig.agents)) {\n let needsMigration = false;\n const updatedAgents = rawConfig.agents.map((agent: unknown) => {\n if (typeof agent === 'string' && agent.toLowerCase() === 'openai') {\n needsMigration = true;\n return Agent.Codex;\n }\n return agent;\n });\n\n if (needsMigration) {\n rawConfig.agents = updatedAgents;\n await fs.outputFile(configPath, yaml.dump(rawConfig));\n }\n }\n\n // Validate with Zod\n const parsed = SkillConfigSchema.safeParse(rawConfig);\n\n if (!parsed.success) {\n throw new Error(`Invalid .skillsrc format: ${parsed.error.message}`);\n }\n\n return parsed.data as SkillConfig;\n } catch (error) {\n throw new Error(`Failed to load config: ${error}`);\n }\n }\n\n /**\n * Saves the provided configuration to the `.skillsrc` file.\n * @param config The configuration to save\n * @param cwd Current working directory\n */\n async saveConfig(\n config: SkillConfig,\n cwd: string = process.cwd(),\n ): Promise<void> {\n const configPath = path.join(cwd, '.skillsrc');\n await fs.outputFile(configPath, yaml.dump(config));\n }\n\n /**\n * Constructs an initial configuration object based on project analysis.\n * @param framework The primary framework detected\n * @param agents List of enabled AI agents\n * @param registry Registry URL\n * @param metadata Registry metadata for versioning and prefixes\n * @param languages Detected programming languages\n * @param workflows List of workflow names to sync\n * @returns A fresh SkillConfig object\n */\n buildInitialConfig(\n framework: string,\n agents: Agent[],\n registry: string,\n metadata: Partial<RegistryMetadata>,\n languages: string[] = [],\n workflows: string[] = [],\n ): SkillConfig {\n const skills: Record<string, CategoryConfig> = {};\n\n // Add main framework\n skills[framework] = {\n ref: metadata.categories?.[framework]?.version\n ? `${metadata.categories[framework].tag_prefix || ''}${metadata.categories[framework].version}`\n : 'main',\n };\n\n // Specialized Logic: Frontend React-based projects must inherently sync the React category natively.\n if (\n FRONTEND_REACT_FRAMEWORKS.includes(framework as Framework) &&\n metadata.categories?.['react']\n ) {\n skills['react'] = {\n ref: metadata.categories['react'].version\n ? `${metadata.categories['react'].tag_prefix || ''}${metadata.categories['react'].version}`\n : 'main',\n };\n }\n\n // Add associated languages (e.g., typescript, javascript)\n for (const lang of languages) {\n if (metadata.categories?.[lang]) {\n skills[lang] = {\n ref: `${metadata.categories[lang].tag_prefix || ''}${metadata.categories[lang].version}`,\n };\n }\n }\n\n // Add common category if available, with framework-appropriate exclusions\n if (metadata.categories?.['common']) {\n const frameworkType = getFrameworkType(framework);\n const commonExcludes = frameworkType\n ? COMMON_SKILL_EXCLUDES[frameworkType]\n : [];\n\n skills['common'] = {\n ref: `${metadata.categories['common'].tag_prefix || ''}${metadata.categories['common'].version}`,\n ...(commonExcludes.length > 0 && { exclude: commonExcludes }),\n };\n }\n\n for (const category of DEFAULT_SDLC_SUPPORT_CATEGORIES) {\n if (metadata.categories?.[category] && !skills[category]) {\n skills[category] = {\n ref: this.getCategoryRef(category, metadata),\n };\n }\n }\n\n // Add database category for backend frameworks\n if (\n BACKEND_FRAMEWORKS.includes(framework as Framework) &&\n metadata.categories?.['database']\n ) {\n skills['database'] = {\n ref: metadata.categories['database'].version\n ? `${metadata.categories['database'].tag_prefix || ''}${metadata.categories['database'].version}`\n : 'main',\n };\n }\n\n return {\n registry,\n agents,\n skills,\n custom_overrides: [],\n workflows: workflows.length > 0 ? workflows : false, // Array if specific, false if empty\n };\n }\n\n /**\n * Identifies sub-skills to exclude based on the absence of their required package dependencies.\n * Scans all categories defined in the config.\n * @param config The current configuration\n * @param projectDeps Current set of project dependencies\n */\n applyDependencyExclusions(\n config: SkillConfig,\n projectDeps: Set<string>,\n cwd: string = process.cwd(),\n ) {\n const depsArray = Array.from(projectDeps);\n\n for (const categoryId in config.skills) {\n const category = config.skills[categoryId];\n const detections = SKILL_DETECTION_REGISTRY[categoryId] || [];\n if (detections.length === 0) continue;\n\n const exclusions = new Set<string>(category.exclude || []);\n\n for (const detection of detections) {\n const hasDeps = this.hasDependency(detection.packages, depsArray);\n const hasDirs = this.hasFiles(detection.files, cwd);\n if (!hasDeps || !hasDirs) {\n exclusions.add(detection.id);\n }\n }\n\n if (exclusions.size > 0) {\n category.exclude = Array.from(exclusions);\n }\n }\n }\n\n /**\n * Automatically re-enables skills that were previously excluded if their dependencies\n * are now present in the project. Scans all categories.\n */\n reconcileDependencies(\n config: SkillConfig,\n projectDeps: Set<string>,\n cwd: string = process.cwd(),\n ): string[] {\n const totalReenabled: string[] = [];\n const allKnownCategories = Object.keys(SKILL_DETECTION_REGISTRY);\n const depsArray = Array.from(projectDeps);\n\n for (const categoryId of allKnownCategories) {\n const hasMetaFramework = Object.keys(config.skills).some((f) =>\n [Framework.Flutter, Framework.ReactNative].includes(f as Framework),\n );\n\n let category = config.skills[categoryId];\n\n // Skip platform-specific categories if a meta-framework is already present\n // unless the category is already active (we still want to reconcile its sub-skills)\n if (\n hasMetaFramework &&\n [Framework.Android, Framework.iOS].includes(categoryId as Framework)\n ) {\n if (!category) continue;\n }\n\n const detections = SKILL_DETECTION_REGISTRY[categoryId] || [];\n if (detections.length === 0) continue;\n\n const isNewCategory = !category;\n if (isNewCategory) {\n // First check if this is a supported framework and we don't have its base dependencies\n const frameworkDef = SUPPORTED_FRAMEWORKS.find(\n (f: FrameworkDefinition) => f.id === categoryId,\n );\n if (frameworkDef) {\n const hasBaseDeps =\n frameworkDef.detectionDependencies &&\n frameworkDef.detectionDependencies.length > 0\n ? this.hasDependency(\n frameworkDef.detectionDependencies,\n depsArray,\n )\n : false;\n\n const hasBaseFiles =\n frameworkDef.detectionFiles &&\n frameworkDef.detectionFiles.length > 0\n ? frameworkDef.detectionFiles.some((file) =>\n fs.existsSync(path.join(cwd, file)),\n )\n : false;\n\n if (!hasBaseDeps && !hasBaseFiles) {\n continue; // Skip enabling this category if its base framework isn't detected\n }\n }\n\n const shouldEnableCategory = detections.some(\n (detection) =>\n this.hasDependency(detection.packages, depsArray) &&\n this.hasFiles(detection.files, cwd),\n );\n\n if (shouldEnableCategory) {\n config.skills[categoryId] = { ref: 'main' };\n category = config.skills[categoryId];\n\n const exclusions = detections\n .filter(\n (d) =>\n !this.hasDependency(d.packages, depsArray) ||\n !this.hasFiles(d.files, cwd),\n )\n .map((d) => d.id);\n\n if (exclusions.length > 0) {\n category.exclude = exclusions;\n }\n totalReenabled.push(categoryId);\n }\n continue;\n }\n\n // Existing category reconciliation\n if (!category.exclude) continue;\n\n const currentExclusions = new Set(category.exclude);\n const reenabled: string[] = [];\n\n for (const detection of detections) {\n if (\n currentExclusions.has(detection.id) &&\n this.hasDependency(detection.packages, depsArray) &&\n this.hasFiles(detection.files, cwd)\n ) {\n currentExclusions.delete(detection.id);\n reenabled.push(`${categoryId}/${detection.id}`);\n }\n }\n\n if (reenabled.length > 0) {\n category.exclude =\n currentExclusions.size > 0\n ? Array.from(currentExclusions)\n : undefined;\n totalReenabled.push(...reenabled);\n }\n }\n\n return totalReenabled;\n }\n\n /**\n * Checks if ANY of the required files exist in the project directory.\n */\n private hasFiles(files: string[] | undefined, cwd: string): boolean {\n if (!files || files.length === 0) return true; // If no files required, assume condition met\n for (const file of files) {\n if (fs.existsSync(path.join(cwd, file))) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Checks if ANY of the required dependencies are found in the project.\n */\n private hasDependency(packages: string[], projectDeps: string[]): boolean {\n if (packages.length === 0) return true; // If no packages are required, condition met\n return projectDeps.some((d) =>\n packages.some((pkg) => {\n const depLower = d.toLowerCase();\n const pkgLower = pkg.toLowerCase();\n\n // Exact match\n if (depLower === pkgLower) return true;\n\n // Skip fuzzy matching for short names to avoid noise\n if (pkg.length <= 3) return false;\n\n // Handle scoped packages: @scope/package matches package\n if (depLower.includes('/') && depLower.split('/').pop() === pkgLower)\n return true;\n\n // Handle framework-prefixed packages (e.g. @nestjs/core, flask-cors)\n // Only match if the package is a standalone word in the dependency name\n const parts = depLower.split(/[-/_]/);\n return parts.includes(pkgLower);\n }),\n );\n }\n\n /**\n * Retrieves the registry URL from configuration or returns the default.\n * @param cwd Current working directory\n */\n async getRegistryUrl(cwd: string = process.cwd()): Promise<string> {\n const config = await this.loadConfig(cwd).catch(() => null);\n return config?.registry || DEFAULT_REGISTER;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { Agent, getAgentDefinition } from '../constants';\n\n// āā Embedded hook templates āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n/**\n * Universal PreToolUse hook script (Node.js / JavaScript).\n * Reminds AI agents to call load_skills_for_files() before any code edit.\n * Guaranteed to execute on any machine running agent-skills-standard.\n * Always exits 0 to never block work.\n */\nexport const UNIVERSAL_SKILL_LOADER_JS = `#!/usr/bin/env node\n/**\n * PreToolUse hook: remind AI agent to call load_skills_for_files() before any code edit.\n * Installed by agent-skills-standard (ags sync). Remove via: ags hooks uninstall\n * Guaranteed to execute on any system with Node.js. Always exits 0 to never block work.\n */\nconst fs = require('fs');\nconst path = require('path');\n\nconst REPO_ROOT = process.env.CLAUDE_PROJECT_DIR || path.resolve(__dirname, '../../');\nconst EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);\nconst SKIP_DIRS = [\n path.resolve(REPO_ROOT, '.claude'),\n path.resolve(REPO_ROOT, '.gemini'),\n path.resolve(REPO_ROOT, '.codex'),\n path.resolve(REPO_ROOT, '.github'),\n path.resolve(REPO_ROOT, '.cursor'),\n path.resolve(REPO_ROOT, '.roo'),\n path.resolve(REPO_ROOT, '.trae'),\n path.resolve(REPO_ROOT, '.opencode'),\n path.resolve(REPO_ROOT, '.kiro'),\n path.resolve(REPO_ROOT, '.windsurf'),\n path.resolve(REPO_ROOT, '.agents'),\n path.resolve(REPO_ROOT, '.vscode'),\n];\nconst SKIP_FILES = [\n path.resolve(REPO_ROOT, 'AGENTS.md'),\n path.resolve(REPO_ROOT, 'CLAUDE.md'),\n];\n\nfunction shouldSkip(filePath) {\n try {\n const real = path.resolve(filePath);\n if (SKIP_DIRS.some(d => real.startsWith(d))) return true;\n if (SKIP_FILES.includes(real)) return true;\n return false;\n } catch {\n return false;\n }\n}\n\nlet input = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', chunk => { input += chunk; });\nprocess.stdin.on('end', () => {\n try {\n const data = JSON.parse(input);\n if (!EDIT_TOOLS.has(data.tool_name)) process.exit(0);\n\n const filePath = data.tool_input?.file_path || '';\n if (!filePath || shouldSkip(filePath)) process.exit(0);\n\n const fileName = path.basename(filePath);\n console.log(\n '[SKILL TRIGGER] Editing: ' + fileName + '\\\\n' +\n '-> Call load_skills_for_files(files=[ \"' + filePath + '\" ]) on the ' +\n 'agent-skills-standard MCP. It returns applicable SKILL.md rules, ' +\n 'or nothing if no skills match this file type.'\n );\n process.exit(0);\n } catch {\n process.exit(0);\n }\n});\n`;\n\n/**\n * Kiro hook spec (Markdown + YAML frontmatter).\n * File-save trigger ā advisory only (cannot block edits).\n * Placed at .kiro/hooks/ags-skill-loader.md\n */\nexport const KIRO_HOOK_MD = `---\nenabled: true\nname: ags-skill-loader\ndescription: Load matching skill rules from agent-skills-standard before editing source files\ntriggers:\n - type: file_change\n fileFilter: \"**/*\"\ninstructions: |\n Before editing any source file, call load_skills_for_files(files=[<absolute_file_path>])\n on the agent-skills-standard MCP server. It returns applicable SKILL.md rules for the\n file being edited, or nothing if no skills match. Apply all returned rules strictly.\n---\n`;\n\n// āā Constants āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nconst CLAUDE_MCP_PERMISSION = 'mcp__agent-skills-standard__*';\nconst KIRO_HOOK_REL = '.kiro/hooks/ags-skill-loader.md';\n\n// āā Types āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nexport interface HookWriteReport {\n writes: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Agents with no hook system ā skills delivered via rules files only. */\n unsupported: Agent[];\n}\n\nexport interface HookStatusRow {\n agent: Agent;\n installed: boolean;\n files: string[];\n}\n\n// āā Service āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n/**\n * Installs and removes AI-agent lifecycle hooks for the skill-loader reminder.\n *\n * Supported hook systems:\n * Claude Code ā PreToolUse hook (blocking-capable, fires before every Edit/Write)\n * Cursor ā PreToolUse hook\n * Windsurf ā PreToolUse hook\n * Gemini ā PreToolUse hook\n * Codex ā PreToolUse hook\n * Copilot ā PreToolUse hook\n * Kiro ā File-save spec hook (advisory, cannot block edits)\n *\n * All other agents in the supported-agents list have no programmatic hook system;\n * they receive the MCP trigger via their rules file (CLAUDE.md, .cursor/rules, etc.)\n * which is written by SyncService ā no separate hook file is needed.\n *\n * Settings writes are idempotent and merge existing content.\n * Claude hook script is created once and preserved if customized.\n * Kiro hook markdown stays in sync with the embedded template.\n */\nexport class HookService {\n async install(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<HookWriteReport> {\n const report: HookWriteReport = { writes: [], unsupported: [] };\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n await this.installKiroHook(opts.rootDir, report);\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookScriptPath && def.hookConfigPath) {\n await this.installStandardHookConfig({\n rootDir: opts.rootDir,\n agent,\n scriptRelPath: def.hookScriptPath,\n configRelPath: def.hookConfigPath,\n hookCmd:\n agent === Agent.Claude\n ? 'node \"$CLAUDE_PROJECT_DIR/.claude/hooks/preedit-skill-loader.js\"'\n : `node \"${def.hookScriptPath}\"`,\n report,\n });\n } else {\n report.unsupported.push(agent);\n }\n }\n\n return report;\n }\n\n async uninstall(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<{ removed: Array<{ agent: Agent; file: string }> }> {\n const removed: Array<{ agent: Agent; file: string }> = [];\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n const abs = path.join(opts.rootDir, KIRO_HOOK_REL);\n if (await fs.pathExists(abs)) {\n await fs.remove(abs);\n removed.push({ agent, file: KIRO_HOOK_REL });\n }\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookConfigPath) {\n const files = await this.uninstallStandardHookConfig(\n opts.rootDir,\n def.hookConfigPath,\n );\n removed.push(...files.map((f) => ({ agent, file: f })));\n }\n }\n\n return { removed };\n }\n\n async status(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<HookStatusRow[]> {\n const rows: HookStatusRow[] = [];\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n const exists = await fs.pathExists(\n path.join(opts.rootDir, KIRO_HOOK_REL),\n );\n rows.push({ agent, installed: exists, files: [KIRO_HOOK_REL] });\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookScriptPath && def.hookConfigPath) {\n rows.push(\n await this.standardHookStatus(\n opts.rootDir,\n agent,\n def.hookScriptPath,\n def.hookConfigPath,\n ),\n );\n }\n }\n\n return rows;\n }\n\n // āā Standard Python/JSON Hook System (Claude, Codex, Copilot) āāāāāāāāāāāāāāāā\n\n private async installStandardHookConfig(opts: {\n rootDir: string;\n agent: Agent;\n scriptRelPath: string;\n configRelPath: string;\n hookCmd: string;\n report: HookWriteReport;\n }): Promise<void> {\n const scriptAbs = path.join(opts.rootDir, opts.scriptRelPath);\n const scriptExists = await fs.pathExists(scriptAbs);\n await fs.ensureDir(path.dirname(scriptAbs));\n\n // Clean up legacy Python script if present\n const legacyPyAbs = scriptAbs.replace(/\\.js$/, '.py');\n if (await fs.pathExists(legacyPyAbs)) {\n await fs.remove(legacyPyAbs).catch(() => {});\n }\n\n if (!scriptExists) {\n await fs.writeFile(scriptAbs, UNIVERSAL_SKILL_LOADER_JS);\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.scriptRelPath,\n action: 'added',\n });\n } else {\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.scriptRelPath,\n action: 'skipped-existing',\n });\n }\n\n const configAbs = path.join(opts.rootDir, opts.configRelPath);\n const configExists = await fs.pathExists(configAbs);\n const existing = await this.readJson(configAbs);\n let changed = false;\n\n // Add MCP permission (idempotent)\n const permissions = this.ensureObject(existing, 'permissions');\n const allow = this.ensureArray<string>(permissions, 'allow');\n if (!allow.includes(CLAUDE_MCP_PERMISSION)) {\n permissions['allow'] = [CLAUDE_MCP_PERMISSION, ...allow];\n changed = true;\n }\n\n // Add PreToolUse hook entry (idempotent ā guard by script path fragment)\n const hooks = this.ensureObject(existing, 'hooks');\n const preToolUse = this.ensureArray<Record<string, unknown>>(\n hooks,\n 'PreToolUse',\n );\n if (!this.claudeHookEntryExists(preToolUse)) {\n preToolUse.unshift({\n matcher: 'Edit|Write|MultiEdit|NotebookEdit',\n hooks: [{ type: 'command', command: opts.hookCmd, timeout: 5 }],\n });\n changed = true;\n }\n\n if (changed) {\n await this.writeAtomic(configAbs, existing);\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.configRelPath,\n action: configExists ? 'updated' : 'added',\n });\n } else {\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.configRelPath,\n action: 'skipped-existing',\n });\n }\n }\n\n private async uninstallStandardHookConfig(\n rootDir: string,\n configRelPath: string,\n ): Promise<string[]> {\n const removed: string[] = [];\n const configAbs = path.join(rootDir, configRelPath);\n if (!(await fs.pathExists(configAbs))) return removed;\n\n const data = await this.readJson(configAbs);\n let changed = false;\n\n const permissions = this.ensureObject(data, 'permissions');\n const allow = this.ensureArray<string>(permissions, 'allow');\n if (allow.includes(CLAUDE_MCP_PERMISSION)) {\n permissions['allow'] = allow.filter((p) => p !== CLAUDE_MCP_PERMISSION);\n changed = true;\n }\n\n const hooks = this.ensureObject(data, 'hooks');\n const preToolUse = this.ensureArray<Record<string, unknown>>(\n hooks,\n 'PreToolUse',\n );\n const filtered = preToolUse.filter(\n (entry) => !this.claudeHookEntryMatches(entry),\n );\n if (filtered.length !== preToolUse.length) {\n hooks['PreToolUse'] = filtered;\n changed = true;\n }\n\n if (changed) {\n await this.writeAtomic(configAbs, data);\n removed.push(configRelPath);\n }\n\n return removed;\n }\n\n private async standardHookStatus(\n rootDir: string,\n agent: Agent,\n scriptRelPath: string,\n configRelPath: string,\n ): Promise<HookStatusRow> {\n const scriptExists = await fs.pathExists(path.join(rootDir, scriptRelPath));\n const registeredInSettings = await this.claudeHookIsRegistered(\n path.join(rootDir, configRelPath),\n );\n return {\n agent,\n installed: scriptExists && registeredInSettings,\n files: [scriptRelPath, configRelPath],\n };\n }\n\n private async claudeHookIsRegistered(settingsAbs: string): Promise<boolean> {\n if (!(await fs.pathExists(settingsAbs))) return false;\n const data = await this.readJson(settingsAbs);\n const hooks = data['hooks'] as Record<string, unknown> | undefined;\n if (!hooks) return false;\n const preToolUse = hooks['PreToolUse'] as\n | Array<Record<string, unknown>>\n | undefined;\n if (!Array.isArray(preToolUse)) return false;\n return this.claudeHookEntryExists(preToolUse);\n }\n\n private claudeHookEntryExists(\n entries: Array<Record<string, unknown>>,\n ): boolean {\n return entries.some((entry) => this.claudeHookEntryMatches(entry));\n }\n\n private claudeHookEntryMatches(entry: Record<string, unknown>): boolean {\n const entryHooks = (entry['hooks'] ?? []) as Array<Record<string, unknown>>;\n return entryHooks.some((h) =>\n (h['command'] as string | undefined)?.includes('preedit-skill-loader'),\n );\n }\n\n // āā Kiro āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n private async installKiroHook(\n rootDir: string,\n report: HookWriteReport,\n ): Promise<void> {\n const hookAbs = path.join(rootDir, KIRO_HOOK_REL);\n const exists = await fs.pathExists(hookAbs);\n await fs.ensureDir(path.dirname(hookAbs));\n if (!exists) {\n await fs.writeFile(hookAbs, KIRO_HOOK_MD);\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'added',\n });\n return;\n }\n\n const current = await fs.readFile(hookAbs, 'utf8');\n if (current !== KIRO_HOOK_MD) {\n await fs.writeFile(hookAbs, KIRO_HOOK_MD);\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'updated',\n });\n return;\n }\n\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'skipped-existing',\n });\n }\n\n // āā Utilities āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n private async readJson(abs: string): Promise<Record<string, unknown>> {\n if (!(await fs.pathExists(abs))) return {};\n return (await fs.readJson(abs).catch(() => ({}))) as Record<\n string,\n unknown\n >;\n }\n\n private ensureObject(\n parent: Record<string, unknown>,\n key: string,\n ): Record<string, unknown> {\n if (\n typeof parent[key] !== 'object' ||\n parent[key] === null ||\n Array.isArray(parent[key])\n ) {\n parent[key] = {};\n }\n return parent[key] as Record<string, unknown>;\n }\n\n private ensureArray<T>(parent: Record<string, unknown>, key: string): T[] {\n if (!Array.isArray(parent[key])) {\n parent[key] = [];\n }\n return parent[key] as T[];\n }\n\n private async writeAtomic(abs: string, data: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(abs));\n const tmp = `${abs}.tmp`;\n await fs.writeJson(tmp, data, { spaces: 2 });\n await fs.move(tmp, abs, { overwrite: true });\n }\n}\n","import pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport { HookService, HookWriteReport } from '../services/HookService';\n\n/**\n * `ags hooks <action>` ā manage the PreToolUse skill-loader hook for\n * Claude Code (and Kiro advisory hook) without editing files by hand.\n *\n * Sub-actions:\n * status Show which hook files are installed for each agent\n * install Write hook script + register in .claude/settings.json\n * uninstall Deregister from .claude/settings.json (preserves hook script)\n */\nexport class HooksCommand {\n private configService: ConfigService;\n private hookService: HookService;\n\n constructor(configService?: ConfigService, hookService?: HookService) {\n this.configService = configService ?? new ConfigService();\n this.hookService = hookService ?? new HookService();\n }\n\n async run(action: string): Promise<void> {\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(\n pc.red(\n 'ā .skillsrc not found. Run `agent-skills-standard init` first.',\n ),\n );\n return;\n }\n\n const cwd = process.cwd();\n const agents = config.agents ?? [];\n\n switch (action) {\n case 'status':\n return this.actionStatus(cwd, agents);\n case 'install':\n return this.actionInstall(cwd, agents);\n case 'uninstall':\n return this.actionUninstall(cwd, agents);\n default:\n console.log(\n pc.red(`Unknown action: ${action}`),\n '\\nValid actions: status, install, uninstall',\n );\n }\n }\n\n // ---- actions ----\n\n private async actionStatus(cwd: string, agents: Agent[]): Promise<void> {\n const rows = await this.hookService.status({ rootDir: cwd, agents });\n\n console.log(pc.bold('\\nšŖ Hook installation status\\n'));\n\n if (rows.length === 0) {\n console.log(pc.gray(' (no agents configured)'));\n return;\n }\n\n for (const row of rows) {\n const badge = row.installed\n ? pc.green('ā installed')\n : pc.gray('ā not installed');\n console.log(` ${row.agent.padEnd(12)} ${badge}`);\n for (const f of row.files) {\n console.log(` ${pc.gray(f)}`);\n }\n }\n }\n\n private async actionInstall(cwd: string, agents: Agent[]): Promise<void> {\n console.log(pc.cyan('\\nšŖ Installing skill-loader hooks...'));\n const report = await this.hookService.install({ rootDir: cwd, agents });\n this.printReport(report);\n }\n\n private async actionUninstall(cwd: string, agents: Agent[]): Promise<void> {\n const { removed } = await this.hookService.uninstall({\n rootDir: cwd,\n agents,\n });\n if (removed.length === 0) {\n console.log(pc.gray('Nothing to remove.'));\n return;\n }\n console.log(pc.green('ā
Removed hook files:'));\n for (const r of removed) {\n console.log(` - ${pc.cyan(r.agent)} ā ${pc.gray(r.file)}`);\n }\n }\n\n // ---- output ----\n\n private printReport(report: HookWriteReport): void {\n for (const w of report.writes) {\n const tag =\n w.action === 'added'\n ? pc.green('+ added ')\n : w.action === 'updated'\n ? pc.cyan('~ updated ')\n : pc.gray('= up-to-date');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n `\\n(skipped ā no hook support: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n const added = report.writes.filter((w) => w.action !== 'skipped-existing');\n if (added.length > 0) {\n console.log(pc.green('\\nā
Hooks installed.'));\n console.log(\n pc.gray(\n ' Hooks fire before every Edit/Write ā Claude will be reminded to load skills.',\n ),\n );\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport {\n FrameworkDefinition,\n SUPPORTED_AGENTS,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\n\n/**\n * Service for detecting project frameworks, languages, AI agents, and dependencies.\n * It uses a combination of file existence checks and package metadata analysis.\n */\nexport class DetectionService {\n /**\n * Detects supported frameworks based on characteristic files and dependencies.\n * @returns A record of framework IDs and their detection status (boolean)\n */\n async detectFrameworks(): Promise<Record<string, boolean>> {\n const cwd = process.cwd();\n // Gather root and immediate subdirectories to support monorepos\n const dirsToScan = [cwd];\n try {\n const entries = await fs.readdir(cwd, { withFileTypes: true });\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !entry.name.startsWith('.') &&\n entry.name !== 'node_modules'\n ) {\n dirsToScan.push(path.join(cwd, entry.name));\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.debug(\n `[DetectionService] Failed to read directory entries: ${error}`,\n );\n }\n }\n\n const packageDepsMaps = await Promise.all(\n dirsToScan.map((dir) => this.readPackageJsonDeps(dir)),\n );\n\n // Merge all deps\n const allPackageDeps = {};\n for (const deps of packageDepsMaps) {\n Object.assign(allPackageDeps, deps);\n }\n\n const detectionPromises = SUPPORTED_FRAMEWORKS.map(async (framework) => {\n // 1. Check characteristic files in parallel across all scanned directories\n let detected = false;\n for (const dir of dirsToScan) {\n if (detected) break;\n const fileChecks = framework.detectionFiles.map((file) =>\n fs.pathExists(path.join(dir, file)),\n );\n const fileResults = await Promise.all(fileChecks);\n if (fileResults.some((exists) => exists)) {\n detected = true;\n }\n }\n\n // 2. Check dependencies (if not yet detected)\n if (\n !detected &&\n framework.detectionDependencies &&\n framework.detectionDependencies.length > 0\n ) {\n detected = framework.detectionDependencies.some((dep) =>\n Object.prototype.hasOwnProperty.call(allPackageDeps, dep),\n );\n }\n\n return { id: framework.id, detected };\n });\n\n const results = await Promise.all(detectionPromises);\n return results.reduce(\n (acc, { id, detected }) => ({ ...acc, [id]: detected }),\n {},\n );\n }\n\n async detectLanguages(framework: FrameworkDefinition): Promise<string[]> {\n if (!framework.languageDetection) {\n return framework.languages;\n }\n\n const languageEntries = Object.entries(\n framework.languageDetection as Record<string, string[]>,\n );\n\n const detectionResults = await Promise.all(\n languageEntries.map(async ([lang, files]) => {\n const fileChecks = files.map((file) =>\n fs.pathExists(path.join(process.cwd(), file)),\n );\n const results = await Promise.all(fileChecks);\n return { lang, detected: results.some((exists) => exists) };\n }),\n );\n\n const detectedLanguages = detectionResults\n .filter((r) => r.detected)\n .map((r) => r.lang);\n\n return detectedLanguages.length > 0\n ? detectedLanguages\n : framework.languages;\n }\n\n /**\n * Detects enabled AI agents in the workspace by looking for their configuration files.\n * @returns A record of agent IDs and their detection status (boolean)\n */\n async detectAgents(): Promise<Record<string, boolean>> {\n const detectionPromises = SUPPORTED_AGENTS.map(async (agent) => {\n const fileChecks = agent.detectionFiles.map((file) =>\n fs.pathExists(path.join(process.cwd(), file)),\n );\n const results = await Promise.all(fileChecks);\n return { id: agent.id, detected: results.some((exists) => exists) };\n });\n\n const results = await Promise.all(detectionPromises);\n return results.reduce(\n (acc, { id, detected }) => ({ ...acc, [id]: detected }),\n {},\n );\n }\n\n /**\n * Aggregates project dependencies from various build systems (NPM, Pub, Gradle, Maven).\n * @returns A set of all detected package names/identifiers\n */\n async getProjectDeps(): Promise<Set<string>> {\n const cwd = process.cwd();\n const results = await Promise.all([\n this.parsePackageJson(cwd),\n this.parsePubspecYaml(cwd),\n this.parseGradleDependencies(cwd),\n this.parseVersionCatalogs(cwd),\n this.parseMavenPom(cwd),\n ]);\n\n const combined = new Set<string>();\n for (const set of results) {\n for (const item of set) combined.add(item);\n }\n return combined;\n }\n\n private async parsePackageJson(cwd: string): Promise<Set<string>> {\n const depsMap = await this.readPackageJsonDeps(cwd);\n return new Set(Object.keys(depsMap));\n }\n\n private async readPackageJsonDeps(\n cwd: string,\n ): Promise<Record<string, string>> {\n const packageJsonPath = path.join(cwd, 'package.json');\n if (!(await fs.pathExists(packageJsonPath))) return {};\n\n try {\n const pkg = await fs.readJson(packageJsonPath);\n return {\n ...(pkg.dependencies || {}),\n ...(pkg.devDependencies || {}),\n };\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to read package.json:', error);\n return {};\n }\n }\n\n private async parsePubspecYaml(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const pubspecPath = path.join(cwd, 'pubspec.yaml');\n if (!(await fs.pathExists(pubspecPath))) return set;\n\n try {\n const content = await fs.readFile(pubspecPath, 'utf8');\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n let sectionIndent: number | null = null;\n\n for (const line of lines) {\n const sectionMatch = line.match(\n /^(\\s*)(dependencies|dev_dependencies)\\s*:/,\n );\n if (sectionMatch) {\n currentSection = sectionMatch[2];\n sectionIndent = sectionMatch[1].length;\n continue;\n }\n\n if (!currentSection || sectionIndent === null) continue;\n const entryMatch = line.match(/^(\\s*)([a-zA-Z0-9_\\-@\\\\/]+)\\s*:/);\n if (!entryMatch) continue;\n\n const indent = entryMatch[1].length;\n const key = entryMatch[2];\n if (indent > sectionIndent && key !== 'sdk' && key !== 'flutter') {\n set.add(key);\n }\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to parse pubspec.yaml:', error);\n }\n return set;\n }\n\n private async parseGradleDependencies(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const gradleRegex =\n /(?:implementation|api|ksp|kapt|annotationProcessor|compileOnly|runtimeOnly)\\s*\\(?\\s*['\"]([^'\":\\s]+)(?::[^'\"]*)?['\"]\\s*\\)?/g;\n\n const scanDir = async (dir: string, depth: number) => {\n if (depth > 2) return; // Reduced depth for performance\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (\n [\n 'node_modules',\n '.git',\n 'build',\n '.gradle',\n 'ios',\n 'macos',\n ].includes(entry.name)\n )\n continue;\n await scanDir(path.join(dir, entry.name), depth + 1);\n } else if (\n entry.name === 'build.gradle' ||\n entry.name === 'build.gradle.kts'\n ) {\n const content = await fs.readFile(\n path.join(dir, entry.name),\n 'utf8',\n );\n gradleRegex.lastIndex = 0;\n let match;\n while ((match = gradleRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n }\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to scan gradle dependencies:', error);\n }\n };\n\n await scanDir(cwd, 0);\n return set;\n }\n\n private async parseVersionCatalogs(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const tomlPaths = [\n path.join(cwd, 'gradle', 'libs.versions.toml'),\n path.join(cwd, 'gradle.libs.versions.toml'),\n ];\n\n for (const tomlPath of tomlPaths) {\n if (!(await fs.pathExists(tomlPath))) continue;\n try {\n const content = await fs.readFile(tomlPath, 'utf8');\n const moduleRegex = /module\\s*=\\s*['\"]([^'\":\\s]+)(?::[^'\"]*)?['\"]/g;\n const groupRegex = /group\\s*=\\s*['\"]([^'\":\\s]+)['\"]/g;\n let match;\n while ((match = moduleRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n while ((match = groupRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to parse version catalogs:', error);\n }\n }\n return set;\n }\n\n private async parseMavenPom(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const pomPath = path.join(cwd, 'pom.xml');\n if (!(await fs.pathExists(pomPath))) return set;\n\n try {\n const content = await fs.readFile(pomPath, 'utf8');\n const regex =\n /<dependency>[\\s\\S]*?<artifactId>([^<]+)<\\/artifactId>[\\s\\S]*?<\\/dependency>/g;\n let match;\n while ((match = regex.exec(content)) !== null) {\n set.add(match[1]);\n }\n } catch (error) {\n if (process.env.DEBUG) console.debug('Failed to parse maven pom:', error);\n }\n return set;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport {\n Agent,\n DEFAULT_WORKFLOWS,\n SUPPORTED_AGENTS,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\nimport { RegistryMetadata } from '../models/types';\nimport { ConfigService } from './ConfigService';\nimport { DetectionService } from './DetectionService';\n\n/**\n * Contextual data gathered during project discovery to inform the initialization prompt.\n */\nexport interface InitContext {\n /** Map of framework IDs and whether they were detected in the workspace */\n frameworkDetection: Record<string, boolean>;\n /** Map of agent IDs and whether they were detected in the workspace */\n agentDetection: Record<string, boolean>;\n}\n/**\n * User responses gathered from the initialization prompt.\n */\nexport interface InitAnswers {\n /** The primary framework ID chosen by the user */\n framework: string;\n /** List of AI agents to enable for the project */\n agents: Agent[];\n /** The URL of the skill registry to use */\n registry: string;\n /** Whether to enable the MCP integration (consent step). */\n mcpEnabled?: boolean;\n /** Scope of MCP writes the user consented to. Only meaningful when mcpEnabled=true. */\n mcpScope?: 'project' | 'user' | 'snippets-only' | 'disabled';\n}\n\n/**\n * Service for orchestrating the project initialization process.\n * Handles environment discovery, prompt choice generation, and initial config creation.\n */\nexport class InitService {\n private detectionService = new DetectionService();\n private configService = new ConfigService();\n\n /**\n * Performs environmental discovery to identify existing frameworks and agents.\n * @returns An InitContext containing detection results\n */\n async getInitializationContext(): Promise<InitContext> {\n const [frameworkDetection, agentDetection] = await Promise.all([\n this.detectionService.detectFrameworks(),\n this.detectionService.detectAgents(),\n ]);\n\n return { frameworkDetection, agentDetection };\n }\n\n /**\n * Transforms the initialization context and registry metadata into choices for the interactive prompt.\n * @param context The discovered initialization context\n * @param supportedCategories List of categories currently supported by the registry\n * @returns Formatted choices and the default framework ID\n */\n getPromptChoices(context: InitContext, supportedCategories: string[]) {\n const frameworkChoices = SUPPORTED_FRAMEWORKS.map((f) => ({\n name: supportedCategories.includes(f.id)\n ? f.name\n : `${f.name} (Coming Soon)`,\n value: f.id,\n }));\n\n const agentChoices = SUPPORTED_AGENTS.map((a) => ({\n name: `${a.name} (${a.path}/)`,\n value: a.id,\n checked: context.agentDetection[a.id] ?? false,\n }));\n\n const defaultFramework =\n SUPPORTED_FRAMEWORKS.find((f) => context.frameworkDetection[f.id])?.id ||\n 'flutter';\n\n return {\n frameworkChoices,\n agentChoices,\n defaultFramework,\n };\n }\n\n /**\n * Orchestrates the construction, validation, and saving of the initial `.skillsrc` configuration.\n * @param answers The user's prompt responses\n * @param metadata Registry metadata for versioning\n * @param cwd Current working directory\n */\n async buildAndSaveConfig(\n answers: InitAnswers,\n metadata: Partial<RegistryMetadata>,\n cwd: string = process.cwd(),\n ) {\n const frameworkId = answers.framework;\n const frameworkDef = SUPPORTED_FRAMEWORKS.find((f) => f.id === frameworkId);\n\n const languages = frameworkDef\n ? await this.detectionService.detectLanguages(frameworkDef)\n : [];\n\n const includeWorkflows = answers.agents.includes(Agent.Antigravity);\n\n const config = this.configService.buildInitialConfig(\n frameworkId,\n answers.agents,\n answers.registry,\n metadata,\n languages,\n includeWorkflows ? DEFAULT_WORKFLOWS : [],\n );\n\n const projectDeps = await this.detectionService.getProjectDeps();\n this.configService.applyDependencyExclusions(config, projectDeps);\n this.configService.reconcileDependencies(config, projectDeps);\n\n // Persist the user's MCP consent decision (if asked).\n if (answers.mcpScope !== undefined) {\n config.mcp = {\n enabled: answers.mcpEnabled === true,\n scope: answers.mcpEnabled === false ? 'disabled' : answers.mcpScope,\n prompted: true,\n };\n }\n\n const commentHeader = `# Auto-detected configuration generated by agent-skills-standard init\n#\n# Presence in 'skills' list = Active. To disable a skill, remove it from the list.\n# 'exclude': IDs of sub-skills to skip during sync (auto-populated with undetected skills).\n# 'custom_overrides': IDs of skills to PROTECT. Use this if you have modified a standard \n# skill locally and don't want the CLI to overwrite it.\n#\n# Run 'ags list-skills' to view all available skills.\n#\n# SDLC support skills such as quality-engineering are included by default.\n# Specialist definitions are synced separately as native sub-agents, not skills.\n#\n`;\n const configPath = path.join(cwd, '.skillsrc');\n await fs.outputFile(configPath, commentHeader + yaml.dump(config));\n }\n}\n","import fetch from 'cross-fetch';\nimport pc from 'picocolors';\nimport { GitHubTreeResponse } from '../models/types';\n\n/**\n * Service for interacting with the GitHub API and fetching raw file content.\n * Handles repository tree discovery, file downloads, and URL parsing.\n */\nexport class GithubService {\n private baseUrl = 'https://api.github.com';\n private rawBaseUrl = 'https://raw.githubusercontent.com';\n\n constructor(private token?: string) {}\n\n private get headers() {\n const h: Record<string, string> = {\n Accept: 'application/vnd.github.v3+json',\n };\n if (this.token) {\n h.Authorization = `token ${this.token}`;\n }\n return h;\n }\n\n /**\n * Fetches the recursive Git tree for a repository.\n * @param owner Repository owner\n * @param repo Repository name\n * @param ref Git reference (branch, tag, or commit SHA)\n * @returns The tree data or null if not found\n */\n async getRepoTree(\n owner: string,\n repo: string,\n ref: string,\n ): Promise<GitHubTreeResponse | null> {\n const url = `${this.baseUrl}/repos/${owner}/${repo}/git/trees/${ref}?recursive=1`;\n try {\n const res = await fetch(url, { headers: this.headers });\n if (!res.ok) {\n if (res.status === 404) return null;\n throw new Error(`GitHub API Error: ${res.status} ${res.statusText}`);\n }\n return (await res.json()) as GitHubTreeResponse;\n } catch (error) {\n console.error(pc.red(`Failed to fetch repo tree: ${error}`));\n return null;\n }\n }\n\n /**\n * Fetches the raw content of a file from GitHub using raw.githubusercontent.com.\n * @param owner Repository owner\n * @param repo Repository name\n * @param ref Git reference\n * @param path Path to the file\n * @returns File content as string or null if not found\n */\n async getRawFile(\n owner: string,\n repo: string,\n ref: string,\n path: string,\n ): Promise<string | null> {\n const url = `${this.rawBaseUrl}/${owner}/${repo}/${ref}/${path}`;\n try {\n const res = await fetch(url);\n if (!res.ok) return null;\n return await res.text();\n } catch (error) {\n console.error(pc.red(`Failed to fetch file ${path}: ${error}`));\n return null;\n }\n }\n\n /**\n * Retrieves the latest release tag name for a repository.\n * @param owner Repository owner\n * @param repo Repository name\n */\n async getLatestReleaseTag(\n owner: string,\n repo: string,\n ): Promise<string | null> {\n try {\n const res = await fetch(\n `${this.baseUrl}/repos/${owner}/${repo}/releases/latest`,\n {\n headers: this.headers,\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as { tag_name: string };\n return data.tag_name;\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[GithubService] Failed to fetch latest release: ${error}`,\n );\n }\n return null;\n }\n }\n\n /**\n * Fetches basic repository information, such as the default branch.\n * @param owner Repository owner\n * @param repo Repository name\n */\n async getRepoInfo(\n owner: string,\n repo: string,\n ): Promise<{ default_branch: string } | null> {\n const url = `${this.baseUrl}/repos/${owner}/${repo}`;\n try {\n const res = await fetch(url, { headers: this.headers });\n if (!res.ok) return null;\n return (await res.json()) as { default_branch: string };\n } catch (error) {\n console.error(pc.red(`Failed to fetch repo info: ${error}`));\n return null;\n }\n }\n\n /**\n * Downloads multiple files concurrently with a limit.\n */\n async downloadFilesConcurrent(\n tasks: { owner: string; repo: string; ref: string; path: string }[],\n concurrency: number = 10,\n ): Promise<{ path: string; content: string }[]> {\n const results: { path: string; content: string }[] = [];\n const pool = [...tasks];\n const executing: Promise<void>[] = [];\n\n const worker = async () => {\n while (pool.length > 0) {\n const task = pool.shift();\n if (!task) break;\n\n const content = await this.getRawFile(\n task.owner,\n task.repo,\n task.ref,\n task.path,\n );\n if (content !== null) {\n results.push({ path: task.path, content });\n }\n }\n };\n\n // Spawn workers\n for (let i = 0; i < Math.min(concurrency, tasks.length); i++) {\n executing.push(worker());\n }\n\n await Promise.all(executing);\n return results;\n }\n\n /**\n * Parses a GitHub URL into owner and repository name.\n * @param url The GitHub URL to parse\n * @returns Object containing owner and repo, or null if invalid\n */\n static parseGitHubUrl(url: string): { owner: string; repo: string } | null {\n const m = url.match(/github\\.com\\/([^/]+)\\/([^/]+)/i);\n if (!m) return null;\n return { owner: m[1], repo: m[2].replace(/\\.git$/, '') };\n }\n}\n","import path from 'path';\nimport { GitHubTreeItem, RegistryMetadata } from '../models/types';\nimport { GithubService } from './GithubService';\n\n/**\n * Service for discovering and querying the skill registry (repository).\n * It identifies available categories, metadata, and framework-specific skills.\n */\nexport class RegistryService {\n private githubService: GithubService;\n\n constructor() {\n this.githubService = new GithubService(process.env.GITHUB_TOKEN);\n }\n\n /**\n * Discovers the registry structure by scanning the repository tree.\n * Identifies available categories, global metadata, and workflows.\n * @param registryUrl The GitHub URL of the registry\n * @returns Discovered registry components\n */\n async discoverRegistry(registryUrl: string): Promise<{\n categories: string[];\n metadata: Partial<RegistryMetadata>;\n workflows: string[];\n }> {\n let categories: string[] = ['flutter', 'dart'];\n let metadata: Partial<RegistryMetadata> = {};\n\n try {\n const parsed = GithubService.parseGitHubUrl(registryUrl);\n if (parsed) {\n let branch = 'main';\n const repoInfo = await this.githubService.getRepoInfo(\n parsed.owner,\n parsed.repo,\n );\n if (repoInfo && repoInfo.default_branch) {\n branch = repoInfo.default_branch;\n }\n\n const treeResult = await this.githubService.getRepoTree(\n parsed.owner,\n parsed.repo,\n branch,\n );\n\n if (treeResult && Array.isArray(treeResult.tree)) {\n const allFiles = treeResult.tree || [];\n const foundCategories = new Set<string>();\n allFiles.forEach((f: GitHubTreeItem) => {\n if (f.path.startsWith('skills/') && f.type === 'tree') {\n const parts = f.path.split('/');\n if (parts.length === 2) foundCategories.add(parts[1]);\n }\n });\n if (foundCategories.size > 0)\n categories = Array.from(foundCategories);\n\n const workflows = allFiles\n .filter(\n (f) =>\n f.path.startsWith('.agents/workflows/') &&\n f.path.endsWith('.md'),\n )\n .map((f) => path.basename(f.path, '.md'));\n\n const metaContent = await this.githubService.getRawFile(\n parsed.owner,\n parsed.repo,\n branch,\n 'skills/metadata.json',\n );\n if (metaContent) {\n metadata = JSON.parse(metaContent) as RegistryMetadata;\n }\n\n return { categories, metadata, workflows };\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[RegistryService] Registry discovery failed: ${error}`);\n }\n }\n\n return { categories, metadata, workflows: [] };\n }\n\n /**\n * Fetches a list of available skill folders for a specific framework.\n * @param registryUrl The GitHub URL of the registry\n * @param framework The framework ID to query\n * @returns List of skill folder names\n */\n async getFrameworkSkills(\n registryUrl: string,\n framework: string,\n ): Promise<string[]> {\n try {\n const parsed = GithubService.parseGitHubUrl(registryUrl);\n if (!parsed) return [];\n\n const treeResult = await this.githubService.getRepoTree(\n parsed.owner,\n parsed.repo,\n 'main',\n );\n\n if (!treeResult || !Array.isArray(treeResult.tree)) return [];\n\n return Array.from(\n new Set(\n treeResult.tree\n .filter((f: GitHubTreeItem) =>\n f.path.startsWith(`skills/${framework}/`),\n )\n .map((f: GitHubTreeItem) => f.path.split('/')[2])\n .filter(Boolean),\n ),\n );\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[RegistryService] Failed to get framework skills for ${framework}: ${error}`,\n );\n }\n return [];\n }\n }\n}\n","import fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { DEFAULT_REGISTER } from '../constants';\nimport { InitAnswers, InitService } from '../services/InitService';\nimport { RegistryService } from '../services/RegistryService';\n\n/**\n * Command for initializing the agent-skills-standard configuration in a project.\n * It guides the user through environment detection and creates the `.skillsrc` file.\n */\nexport class InitCommand {\n private initService: InitService;\n private registryService: RegistryService;\n\n constructor(initService?: InitService, registryService?: RegistryService) {\n this.initService = initService || new InitService();\n this.registryService = registryService || new RegistryService();\n }\n\n /**\n * Executes the initialization flow.\n * Checks for existing config, discovers the environment, prompts the user, and saves the configuration.\n */\n async run() {\n const configPath = path.join(process.cwd(), '.skillsrc');\n\n // 1. Check for existing config\n if (await fs.pathExists(configPath)) {\n const { overwrite } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'overwrite',\n message: '.skillsrc already exists. Do you want to overwrite it?',\n default: false,\n },\n ]);\n if (!overwrite) {\n console.log(pc.yellow('Aborted.'));\n return;\n }\n }\n\n // 2. Gather context data\n const context = await this.initService.getInitializationContext();\n const { categories, metadata } =\n await this.registryService.discoverRegistry(DEFAULT_REGISTER);\n\n // 3. Prepare Choices\n const { frameworkChoices, agentChoices, defaultFramework } =\n this.initService.getPromptChoices(context, categories);\n\n // 4. Prompt User\n const answers = await inquirer.prompt<InitAnswers>([\n {\n type: 'list',\n name: 'framework',\n message: 'Select Framework:',\n choices: frameworkChoices,\n default: defaultFramework,\n },\n {\n type: 'checkbox',\n name: 'agents',\n message: 'Select AI Agents you use:',\n choices: agentChoices,\n },\n {\n type: 'input',\n name: 'registry',\n message: 'Skills Registry URL:',\n default: DEFAULT_REGISTER,\n },\n ]);\n\n // 4b. MCP consent step\n this.printMcpValueProp();\n const mcpDecision = await inquirer.prompt<{\n mcpEnabled: boolean;\n mcpScope: 'project' | 'user' | 'snippets-only';\n }>([\n {\n type: 'confirm',\n name: 'mcpEnabled',\n message: 'Enable MCP server integration?',\n default: true,\n },\n {\n type: 'list',\n name: 'mcpScope',\n message: 'Where should sync write MCP configs?',\n when: (a) => a.mcpEnabled === true,\n choices: [\n {\n name: 'project (recommended) ā only files inside this project (.mcp.json, .cursor/mcp.json, etc.)',\n value: 'project',\n },\n {\n name: 'user ā also $HOME files (~/.cursor/mcp.json, ~/.gemini/settings.json) ā sync prompts each',\n value: 'user',\n },\n {\n name: 'snippets-only ā never edits any runtime config; just generates ./mcp-config-snippets/*.json',\n value: 'snippets-only',\n },\n ],\n default: 'project',\n },\n ]);\n answers.mcpEnabled = mcpDecision.mcpEnabled;\n answers.mcpScope = mcpDecision.mcpEnabled\n ? mcpDecision.mcpScope\n : 'disabled';\n\n // 5. Build and Save\n await this.initService.buildAndSaveConfig(answers, metadata);\n\n console.log(pc.green('\\nā
Initialized .skillsrc with your preferences!'));\n console.log(pc.gray(` Selected framework: ${answers.framework}`));\n if (answers.mcpEnabled) {\n console.log(\n pc.gray(` MCP integration: enabled (scope: ${answers.mcpScope})`),\n );\n } else {\n console.log(\n pc.gray(\n ` MCP integration: disabled (change later via \\`ags mcp enable\\`)`,\n ),\n );\n }\n console.log(\n pc.cyan(\n '\\nNext step: Run `agent-skills-standard sync` to install skills and wire MCP.',\n ),\n );\n }\n\n private printMcpValueProp(): void {\n console.log(pc.bold('\\nš MCP server setup\\n'));\n console.log(\n 'agent-skills-standard ships an optional MCP server that serves your skills',\n );\n console.log('to AI agents at runtime. Quick comparison:\\n');\n console.log(pc.bold(' WITHOUT MCP') + ' (skills as static files only)');\n console.log(pc.green(' ā') + ' Zero setup overhead');\n console.log(\n pc.red(' ā') +\n ' Sub-agents (Claude Code tdd-implementer, architecture-guard, etc.)',\n );\n console.log(\n ' do NOT inherit AGENTS.md ā they often skip skill loading entirely',\n );\n console.log(\n pc.red(' ā') + ' No audit trail of which skills were consulted',\n );\n console.log(\n pc.red(' ā') +\n ' False findings in code review (agent uses pre-training defaults)\\n',\n );\n console.log(pc.bold(' WITH MCP') + ' (runtime tool calls)');\n console.log(\n pc.green(' ā') +\n ' Sub-agents in EVERY runtime can call load_skills_for_files',\n );\n console.log(\n pc.green(' ā') +\n \" Returns matched SKILL.md as a tool response ā can't be silently skipped\",\n );\n console.log(\n pc.green(' ā') +\n ' audit_session_compliance gives you a receipt of what was loaded',\n );\n console.log(\n pc.gray(' -') + ' Adds one more process to your AI runtime config\\n',\n );\n }\n}\n","import { SKILL_DETECTION_REGISTRY } from '../constants';\nimport { RegistryService } from './RegistryService';\n\n/**\n * Represents a skill with its detection status in the current project.\n */\nexport interface SkillWithStatus {\n /** The name/ID of the skill */\n name: string;\n /**\n * Status of the skill:\n * - detected: Required dependencies found\n * - not-detected: Required dependencies missing\n * - no-rule: No automated detection rule exists for this skill\n */\n status: 'detected' | 'not-detected' | 'no-rule';\n}\n\n/**\n * Service for managing skill status and availability.\n * Maps registry skills to project dependencies to determine detection status.\n */\nexport class SkillService {\n private registryService = new RegistryService();\n\n /**\n * Retrieves a list of skills for a framework with their detection status.\n * @param framework The framework to filter by\n * @param registryUrl The registry URL\n * @param projectDeps Set of detected project dependencies\n * @returns Array of skills with validated status\n */\n async getSkillsWithStatus(\n framework: string,\n registryUrl: string,\n projectDeps: Set<string>,\n ): Promise<SkillWithStatus[]> {\n // 1. Get available skills (Remote + Fallback)\n let skillFolders = await this.registryService.getFrameworkSkills(\n registryUrl,\n framework,\n );\n\n const detectRules = SKILL_DETECTION_REGISTRY[framework] || [];\n\n // Fallback: use detection registry skill ids if remote fetch returned nothing\n if (!skillFolders || skillFolders.length === 0) {\n skillFolders = detectRules.map((s) => s.id);\n }\n\n // 2. Map to Status\n const skills = skillFolders.sort().map((skillName) => {\n const rule = detectRules.find((x) => x.id === skillName);\n\n let status: SkillWithStatus['status'] = 'no-rule';\n if (rule) {\n const depsArray = Array.from(projectDeps);\n const isPresent = this.hasDependency(rule.packages, depsArray);\n status = isPresent ? 'detected' : 'not-detected';\n }\n\n return { name: skillName, status };\n });\n\n return skills;\n }\n\n /**\n * Checks if ANY of the required dependencies are found in the project.\n * Uses the same word-boundary matching logic as ConfigService.hasDependency().\n */\n private hasDependency(packages: string[], projectDeps: string[]): boolean {\n if (packages.length === 0) return true;\n return projectDeps.some((d) =>\n packages.some((pkg) => {\n const depLower = d.toLowerCase();\n const pkgLower = pkg.toLowerCase();\n if (depLower === pkgLower) return true;\n if (pkg.length <= 3) return false;\n if (depLower.includes('/') && depLower.split('/').pop() === pkgLower)\n return true;\n const parts = depLower.split(/[-/_]/);\n return parts.includes(pkgLower);\n }),\n );\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { Framework, SUPPORTED_FRAMEWORKS } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport { DetectionService } from '../services/DetectionService';\nimport { SkillService } from '../services/SkillService';\n\n/**\n * Command for listing available skills in the registry.\n * It detects the project's dependencies and identifies which skills have matching rules.\n */\nexport class ListSkillsCommand {\n private configService: ConfigService;\n private detectionService: DetectionService;\n private skillService: SkillService;\n\n constructor(\n configService?: ConfigService,\n detectionService?: DetectionService,\n skillService?: SkillService,\n ) {\n this.configService = configService || new ConfigService();\n this.detectionService = detectionService || new DetectionService();\n this.skillService = skillService || new SkillService();\n }\n\n /**\n * Executes the skill listing flow.\n * Prompts for framework selection, fetches matching skills from the registry, and displays their status.\n */\n async run(options: { framework?: string } = {}) {\n // 1. Get framework choice from user\n let framework = options.framework;\n\n // Validate framework if provided via options\n if (framework) {\n const isSupported = SUPPORTED_FRAMEWORKS.some((f) => f.id === framework);\n if (!isSupported) {\n const validFrameworks = SUPPORTED_FRAMEWORKS.map((f) => f.id).join(\n ', ',\n );\n console.error(\n pc.red(\n `Invalid framework \"${framework}\". Supported frameworks are: ${validFrameworks}.`,\n ),\n );\n process.exit(1);\n }\n }\n\n if (!framework) {\n const choices = SUPPORTED_FRAMEWORKS.map((f) => ({\n name: f.name,\n value: f.id,\n }));\n\n const answer = await inquirer.prompt([\n {\n type: 'list',\n name: 'framework',\n message: 'Select framework to list available skills for:',\n choices,\n default: choices.find((c) => c.value === Framework.Flutter)?.value,\n },\n ]);\n framework = answer.framework;\n }\n\n if (!framework) return;\n\n // 2. Load context\n const projectDeps = await this.detectionService.getProjectDeps();\n const registryUrl = await this.configService.getRegistryUrl();\n\n console.log(pc.green(`\\nAvailable skills for ${framework}:`));\n\n // 3. Fetch skills with status\n const skills = await this.skillService.getSkillsWithStatus(\n framework,\n registryUrl,\n projectDeps,\n );\n\n // 4. Output results\n for (const skill of skills) {\n const mark =\n skill.status === 'no-rule'\n ? pc.yellow('no-rule')\n : skill.status === 'detected'\n ? pc.green('detected')\n : pc.gray('not-detected');\n\n console.log(`- ${skill.name} (${mark})`);\n }\n\n console.log(\n '\\nTip: Use the .skillsrc exclude array to disable/enable sub-skills before running sync.',\n );\n }\n}\n","import fs from 'fs-extra';\nimport os from 'os';\nimport path from 'path';\nimport { Agent } from '../constants';\nimport { McpConfig } from '../models/config';\n\n/**\n * Per-runtime MCP config-file location and JSON path.\n *\n * `projectFile` ā path RELATIVE to the project root (we may write here freely\n * if scope is 'project' or 'user').\n * `userFile` ā ABSOLUTE path under $HOME (we only write here if scope is\n * 'user' AND the user confirms each write).\n * `key` ā dotted JSON path under which servers are registered.\n *\n * `null` for either path means that runtime does not support that scope; in that\n * case we either skip (project scope) or surface only via snippet generation.\n */\nexport interface McpTarget {\n agent: Agent;\n /** Project-scope path, relative to project root. */\n projectFile: string | null;\n /** User-scope path, absolute (resolved at call time so $HOME is current). */\n userFile: string | null;\n /** Dotted JSON path where MCP servers live (e.g. \"mcpServers\", \"experimental.modelContextProtocolServers\"). */\n key: string;\n /** Whether the runtime stores servers as a map (key = server name) or a list. */\n shape: 'map' | 'list';\n}\n\nexport const SERVER_NAME = 'agent-skills-standard';\nexport const PACKAGE = 'agent-skills-standard-mcp';\n\nconst getTargets = (home = os.homedir()): Record<string, McpTarget> => {\n const HOME = home;\n return {\n [Agent.Claude]: {\n agent: Agent.Claude,\n projectFile: '.mcp.json',\n userFile: path.join(HOME, '.claude', '.mcp.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Cursor]: {\n agent: Agent.Cursor,\n projectFile: '.cursor/mcp.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n if (process.platform === 'linux') {\n return path.join(\n HOME,\n '.config',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n return path.join(HOME, '.cursor', 'mcp.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Antigravity]: {\n agent: Agent.Antigravity,\n projectFile: '.antigravity/mcp_config.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Local',\n 'Google',\n 'Antigravity',\n 'mcp_config.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Google',\n 'Antigravity',\n 'mcp_config.json',\n );\n }\n return path.join(HOME, '.gemini', 'antigravity', 'mcp_config.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Kiro]: {\n agent: Agent.Kiro,\n projectFile: '.kiro/settings/mcp.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Kiro',\n 'settings',\n 'mcp.json',\n );\n }\n return path.join(HOME, '.kiro', 'settings', 'mcp.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Windsurf]: {\n agent: Agent.Windsurf,\n projectFile: '.codeium/windsurf/mcp_config.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Codeium',\n 'Windsurf',\n 'mcp_config.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Codeium',\n 'Windsurf',\n 'mcp_config.json',\n );\n }\n return path.join(HOME, '.codeium', 'windsurf', 'mcp_config.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Trae]: {\n agent: Agent.Trae,\n projectFile: '.trae/mcp.json',\n userFile: null,\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Roo]: {\n agent: Agent.Roo,\n projectFile: '.roo/mcp_config.json',\n userFile: null,\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Gemini]: {\n agent: Agent.Gemini,\n projectFile: '.gemini/settings.json',\n userFile: path.join(HOME, '.gemini', 'settings.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Copilot]: {\n agent: Agent.Copilot,\n projectFile: '.github/mcp.json',\n userFile: (() => {\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n if (process.platform === 'linux') {\n return path.join(\n HOME,\n '.config',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n return null;\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.OpenCode]: {\n agent: Agent.OpenCode,\n projectFile: '.opencode/mcp_config.json',\n userFile: path.join(HOME, '.opencode', 'mcp_config.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Codex]: {\n agent: Agent.Codex,\n projectFile: '.codex/mcp_config.json',\n userFile: path.join(HOME, '.codex', 'mcp_config.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n };\n};\n\n/** What a sync/install pass actually did, returned for reporting. */\nexport interface McpWriteReport {\n /** Agents whose project-scope config was written or updated. */\n projectWrites: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Agents whose user-scope config was written (only happens with explicit consent). */\n userWrites: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Snippet files produced under `mcp-config-snippets/`. */\n snippets: Array<{ agent: Agent; file: string }>;\n /** Agents we asked about but the user declined. */\n declined: Array<{ agent: Agent; file: string }>;\n /** Agents that have no MCP support and were skipped. */\n unsupported: Agent[];\n}\n\nexport interface UserScopePrompt {\n (agent: Agent, file: string): Promise<boolean>;\n}\n\n/**\n * Owns all MCP-config writes. Pure logic ā never prompts the user directly.\n * The caller (sync command, mcp subcommand) supplies a `userScopePrompt`\n * callback that is invoked ONLY when the user has chosen `scope: 'user'` AND\n * a user-home file is about to be modified.\n */\nexport class McpConfigService {\n /** Returns the standard MCP server entry our CLI proposes. */\n buildEntry(version?: string): { command: string; args: string[] } {\n const spec = version ? `${PACKAGE}@${version}` : PACKAGE;\n return { command: 'npx', args: ['-y', spec] };\n }\n\n /** For testing: allows overriding the home directory. */\n private testHome: string | null = null;\n setHomeForTesting(home: string | null): void {\n this.testHome = home;\n }\n\n private getTargets(): Record<string, McpTarget> {\n return getTargets(this.testHome ?? undefined);\n }\n\n /**\n * Write MCP configs for the given agents based on the configured scope.\n * Always safe-merge (never overwrite other servers, never replace whole files).\n */\n async install(opts: {\n rootDir: string;\n agents: Agent[];\n mcp: McpConfig;\n /** Required when mcp.scope === 'user'. Called per file before any write. */\n userScopePrompt?: UserScopePrompt;\n }): Promise<McpWriteReport> {\n const report: McpWriteReport = {\n projectWrites: [],\n userWrites: [],\n snippets: [],\n declined: [],\n unsupported: [],\n };\n const { rootDir, agents, mcp } = opts;\n\n if (mcp.scope === 'disabled' || !mcp.enabled) {\n return report;\n }\n\n const TARGETS = this.getTargets();\n const entry = this.buildEntry(mcp.version);\n // Only generate snippets if:\n // 1. scope is 'snippets-only'\n // 2. user explicitly requested snippets via mcp.snippets flag\n if (mcp.scope === 'snippets-only' || mcp.snippets) {\n await this.generateSnippets(rootDir, agents, entry, report);\n }\n\n if (mcp.scope === 'snippets-only') {\n return report;\n }\n\n for (const agent of agents) {\n const target = TARGETS[agent];\n if (!target) {\n report.unsupported.push(agent);\n continue;\n }\n\n // Project-scope writes ā always allowed when scope is project or user.\n if (target.projectFile) {\n const abs = path.join(rootDir, target.projectFile);\n const action = await this.mergeFile(abs, target, entry);\n report.projectWrites.push({ agent, file: target.projectFile, action });\n }\n\n // User-scope writes ā only with scope === 'user' AND per-file consent.\n if (mcp.scope === 'user' && target.userFile) {\n const ok = opts.userScopePrompt\n ? await opts.userScopePrompt(agent, target.userFile)\n : false;\n if (!ok) {\n report.declined.push({ agent, file: target.userFile });\n continue;\n }\n const action = await this.mergeFile(target.userFile, target, entry);\n report.userWrites.push({ agent, file: target.userFile, action });\n }\n }\n\n return report;\n }\n\n /**\n * Remove our MCP entry from configs we may have added it to. Other entries\n * in the same file are untouched.\n */\n async uninstall(opts: {\n rootDir: string;\n agents: Agent[];\n /** Where to remove from. 'all' removes from BOTH project and user files. */\n from: 'project' | 'user' | 'all';\n }): Promise<{ removed: Array<{ agent: Agent; file: string }> }> {\n const removed: Array<{ agent: Agent; file: string }> = [];\n const TARGETS = this.getTargets();\n for (const agent of opts.agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n\n const candidates: Array<{ abs: string; rel: string }> = [];\n if (\n target.projectFile &&\n (opts.from === 'project' || opts.from === 'all')\n ) {\n candidates.push({\n abs: path.join(opts.rootDir, target.projectFile),\n rel: target.projectFile,\n });\n }\n if (target.userFile && (opts.from === 'user' || opts.from === 'all')) {\n candidates.push({ abs: target.userFile, rel: target.userFile });\n }\n\n for (const { abs, rel } of candidates) {\n if (!(await fs.pathExists(abs))) continue;\n const removedHere = await this.removeFromFile(abs, target);\n if (removedHere) removed.push({ agent, file: rel });\n }\n }\n return { removed };\n }\n\n /** Snapshot what's currently installed. Read-only. */\n async status(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<Array<{ agent: Agent; project?: boolean; user?: boolean }>> {\n const out: Array<{ agent: Agent; project?: boolean; user?: boolean }> = [];\n const TARGETS = this.getTargets();\n for (const agent of opts.agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n const row: { agent: Agent; project?: boolean; user?: boolean } = {\n agent,\n };\n if (target.projectFile) {\n row.project = await this.hasOurEntry(\n path.join(opts.rootDir, target.projectFile),\n target,\n );\n }\n if (target.userFile) {\n row.user = await this.hasOurEntry(target.userFile, target);\n }\n out.push(row);\n }\n return out;\n }\n\n // ---- private helpers ----\n\n private async generateSnippets(\n rootDir: string,\n agents: Agent[],\n entry: { command: string; args: string[] },\n report: McpWriteReport,\n ): Promise<void> {\n const dir = path.join(rootDir, 'mcp-config-snippets');\n await fs.ensureDir(dir);\n const TARGETS = this.getTargets();\n for (const agent of agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n const file = path.join(dir, `${agent}.json`);\n const snippet = this.buildFreshDoc(target, entry);\n await fs.writeJson(file, snippet, { spaces: 2 });\n report.snippets.push({ agent, file: path.relative(rootDir, file) });\n }\n }\n\n /**\n * Read-modify-write a config file. Only the SERVER_NAME key is touched.\n * Never replaces or removes other entries.\n */\n private async mergeFile(\n abs: string,\n target: McpTarget,\n entry: { command: string; args: string[] },\n ): Promise<'added' | 'updated' | 'skipped-existing'> {\n const existing = (await fs.pathExists(abs))\n ? ((await fs.readJson(abs).catch(() => ({}))) as Record<string, unknown>)\n : {};\n\n const container = this.ensurePathContainer(existing, target);\n\n if (target.shape === 'map') {\n const map = container as Record<string, unknown>;\n const previous = map[SERVER_NAME];\n const next = entry;\n if (previous && deepEqual(previous, next)) {\n return 'skipped-existing';\n }\n map[SERVER_NAME] = next;\n await this.writeAtomic(abs, existing);\n return previous ? 'updated' : 'added';\n } else {\n // shape === 'list'\n const list = container as Array<Record<string, unknown>>;\n const idx = list.findIndex((item) => item.name === SERVER_NAME);\n const next = {\n name: SERVER_NAME,\n transport: { type: 'stdio', ...entry },\n };\n if (idx >= 0) {\n if (deepEqual(list[idx], next)) return 'skipped-existing';\n list[idx] = next;\n await this.writeAtomic(abs, existing);\n return 'updated';\n }\n list.push(next);\n await this.writeAtomic(abs, existing);\n return 'added';\n }\n }\n\n private async removeFromFile(\n abs: string,\n target: McpTarget,\n ): Promise<boolean> {\n const data = (await fs.readJson(abs).catch(() => null)) as Record<\n string,\n unknown\n > | null;\n if (!data) return false;\n const container = this.ensurePathContainer(data, target);\n if (target.shape === 'map') {\n const map = container as Record<string, unknown>;\n if (!(SERVER_NAME in map)) return false;\n delete map[SERVER_NAME];\n await this.writeAtomic(abs, data);\n return true;\n } else {\n const list = container as Array<Record<string, unknown>>;\n const before = list.length;\n const filtered = list.filter((item) => item.name !== SERVER_NAME);\n if (filtered.length === before) return false;\n this.setNestedValue(data, target.key, filtered);\n await this.writeAtomic(abs, data);\n return true;\n }\n }\n\n private async hasOurEntry(abs: string, target: McpTarget): Promise<boolean> {\n if (!(await fs.pathExists(abs))) return false;\n const data = (await fs.readJson(abs).catch(() => null)) as Record<\n string,\n unknown\n > | null;\n if (!data) return false;\n const container = this.getNestedValue(data, target.key);\n if (!container) return false;\n if (target.shape === 'map') {\n return Boolean((container as Record<string, unknown>)[SERVER_NAME]);\n }\n return (container as Array<Record<string, unknown>>).some(\n (item) => item.name === SERVER_NAME,\n );\n }\n\n private buildFreshDoc(\n target: McpTarget,\n entry: { command: string; args: string[] },\n ): Record<string, unknown> {\n const doc: Record<string, unknown> = {};\n const container =\n target.shape === 'map'\n ? { [SERVER_NAME]: entry }\n : [{ name: SERVER_NAME, transport: { type: 'stdio', ...entry } }];\n this.setNestedValue(doc, target.key, container);\n return doc;\n }\n\n private ensurePathContainer(\n data: Record<string, unknown>,\n target: McpTarget,\n ): unknown {\n const existing = this.getNestedValue(data, target.key);\n if (existing) {\n if (target.shape === 'map') {\n if (\n typeof existing === 'object' &&\n existing !== null &&\n !Array.isArray(existing)\n ) {\n return existing;\n }\n } else if (target.shape === 'list') {\n if (Array.isArray(existing)) {\n return existing;\n }\n }\n // Type mismatch: replace it\n }\n const fresh: unknown = target.shape === 'map' ? {} : [];\n this.setNestedValue(data, target.key, fresh);\n return fresh;\n }\n\n private getNestedValue(\n data: Record<string, unknown>,\n dotted: string,\n ): unknown {\n const parts = dotted.split('.');\n let cur: unknown = data;\n for (const p of parts) {\n if (p === '__proto__' || p === 'constructor' || p === 'prototype') {\n throw new Error(\n `Prototype pollution attempt detected in key: ${dotted}`,\n );\n }\n if (typeof cur !== 'object' || cur === null) return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n }\n\n private setNestedValue(\n data: Record<string, unknown>,\n dotted: string,\n value: unknown,\n ): void {\n const parts = dotted.split('.');\n let cur = data;\n for (let i = 0; i < parts.length - 1; i++) {\n const p = parts[i];\n if (p === '__proto__' || p === 'constructor' || p === 'prototype') {\n throw new Error(\n `Prototype pollution attempt detected in key: ${dotted}`,\n );\n }\n if (typeof cur[p] !== 'object' || cur[p] === null) {\n cur[p] = {};\n }\n cur = cur[p] as Record<string, unknown>;\n }\n\n const last = parts[parts.length - 1];\n if (\n last === '__proto__' ||\n last === 'constructor' ||\n last === 'prototype'\n ) {\n throw new Error(`Prototype pollution attempt detected in key: ${dotted}`);\n }\n cur[last] = value;\n }\n\n private async writeAtomic(abs: string, data: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(abs));\n const tmp = `${abs}.tmp`;\n await fs.writeJson(tmp, data, { spaces: 2 });\n await fs.move(tmp, abs, { overwrite: true });\n }\n}\n\n/** Default mcp config block used when none is present in `.skillsrc`. */\nexport function defaultMcpConfig(): McpConfig {\n return { enabled: false, scope: 'snippets-only', prompted: false };\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n","import inquirer from 'inquirer';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport {\n McpConfigService,\n defaultMcpConfig,\n} from '../services/McpConfigService';\nimport { McpScope, SkillConfig } from '../models/config';\n\nconst VALID_SCOPES: McpScope[] = [\n 'project',\n 'user',\n 'snippets-only',\n 'disabled',\n];\n\n/**\n * `ags mcp <action>` ā manage the optional MCP server integration without\n * editing `.skillsrc` by hand.\n *\n * Sub-actions:\n * status Show current scope, enabled state, and which configs are wired\n * enable Set mcp.enabled=true; install configs at the configured scope\n * disable Set mcp.enabled=false; existing configs are NOT removed\n * scope <scope> Change scope: project | user | snippets-only | disabled\n * install [--scope=...] One-shot install at the given (or configured) scope\n * uninstall [--from=...] Remove our entry from configs (project | user | all)\n * snippets Generate fresh snippet files in ./mcp-config-snippets/\n */\nexport class McpCommand {\n private configService: ConfigService;\n private mcpService: McpConfigService;\n\n constructor(configService?: ConfigService, mcpService?: McpConfigService) {\n this.configService = configService ?? new ConfigService();\n this.mcpService = mcpService ?? new McpConfigService();\n }\n\n async run(\n action: string,\n options: Record<string, string> = {},\n ): Promise<void> {\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(\n pc.red(\n 'ā .skillsrc not found. Run `agent-skills-standard init` first.',\n ),\n );\n return;\n }\n\n const cwd = process.cwd();\n const agents = config.agents ?? [];\n\n switch (action) {\n case 'status':\n return this.actionStatus(config, cwd);\n case 'enable':\n return this.actionEnable(config);\n case 'disable':\n return this.actionDisable(config);\n case 'scope':\n return this.actionScope(config, options);\n case 'install':\n return this.actionInstall(config, agents, cwd, options);\n case 'uninstall':\n return this.actionUninstall(config, agents, cwd, options);\n case 'snippets':\n return this.actionSnippets(config, agents, cwd);\n default:\n console.log(\n pc.red(`Unknown action: ${action}`),\n '\\nValid actions: status, enable, disable, scope, install, uninstall, snippets',\n );\n }\n }\n\n // ---- actions ----\n\n private async actionStatus(config: SkillConfig, cwd: string): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const agents = config.agents ?? [];\n const rows = await this.mcpService.status({ rootDir: cwd, agents });\n\n console.log(pc.bold('\\nš MCP integration status\\n'));\n console.log(` enabled : ${mcp.enabled ? pc.green('yes') : pc.gray('no')}`);\n console.log(` scope : ${pc.cyan(mcp.scope)}`);\n console.log(` prompted: ${mcp.prompted ? 'yes' : 'no'}`);\n if (mcp.version) console.log(` version : ${mcp.version}`);\n\n if (rows.length === 0) {\n console.log(pc.gray('\\n (no agents configured)'));\n return;\n }\n console.log('\\n Per-agent installation state:');\n let installedAnywhere = false;\n for (const row of rows) {\n const project =\n row.project === undefined\n ? 'ā'\n : row.project\n ? pc.green('ā')\n : pc.gray('ā');\n const user =\n row.user === undefined ? 'ā' : row.user ? pc.green('ā') : pc.gray('ā');\n if (row.project === true || row.user === true) installedAnywhere = true;\n console.log(\n ` ${row.agent.padEnd(12)} project: ${project} user: ${user}`,\n );\n }\n\n // Surface the consent-vs-runtime-config mismatch the user might miss.\n // The MCP block in AGENTS.md is now unconditional, so AI agents will\n // discover the MCP either way ā but the consent flag is what controls\n // whether `sync` keeps the runtime configs in step.\n if (!mcp.enabled && installedAnywhere) {\n console.log(\n pc.yellow(\n '\\nā ļø Mismatch detected: .skillsrc says mcp.enabled=false, but the MCP entry IS present in at least one runtime config.',\n ),\n );\n console.log(\n pc.gray(\n ' The MCP will work, but `sync` will not keep its config in step. Consider one of:',\n ),\n );\n console.log(\n pc.gray(\n ' ⢠`ags mcp enable` ā opt the project in (CLI keeps configs in step)',\n ),\n );\n console.log(\n pc.gray(\n ' ⢠`ags mcp uninstall --from project` ā remove the manual entry if it was unintended',\n ),\n );\n } else if (mcp.enabled && !installedAnywhere) {\n console.log(\n pc.yellow(\n '\\nā ļø Mismatch detected: .skillsrc says mcp.enabled=true, but no runtime config has the MCP registered.',\n ),\n );\n console.log(\n pc.gray(\n ' Run `ags mcp install` to write the entries, or `ags mcp disable` to clear the consent flag.',\n ),\n );\n }\n }\n\n private async actionEnable(config: SkillConfig): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n if (mcp.scope === 'disabled') {\n console.log(\n pc.yellow(\n 'ā ļø scope is currently \"disabled\". Set a real scope first: `ags mcp scope project`',\n ),\n );\n return;\n }\n config.mcp = { ...mcp, enabled: true, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.green('ā
MCP enabled.'));\n console.log(\n pc.gray(\n ' Run `ags mcp install` to write configs now, or it happens on next `sync`.',\n ),\n );\n }\n\n private async actionDisable(config: SkillConfig): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n config.mcp = { ...mcp, enabled: false, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.yellow('š MCP disabled.'));\n console.log(\n pc.gray(\n ' Existing config entries were NOT removed. Use `ags mcp uninstall` to clean them.',\n ),\n );\n }\n\n private async actionScope(\n config: SkillConfig,\n options: Record<string, string>,\n ): Promise<void> {\n const scope = options.scope ?? options._?.[0];\n if (!scope || !VALID_SCOPES.includes(scope as McpScope)) {\n console.log(pc.red(`Invalid scope. Valid: ${VALID_SCOPES.join(' | ')}`));\n return;\n }\n const mcp = config.mcp ?? defaultMcpConfig();\n config.mcp = { ...mcp, scope: scope as McpScope, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.green(`ā
MCP scope set to \"${scope}\".`));\n if (scope === 'user') {\n console.log(\n pc.yellow(\n 'ā ļø user-scope writes will be prompted per file during `sync` or `install`.',\n ),\n );\n }\n }\n\n private async actionInstall(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n options: Record<string, string>,\n ): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const scopeOverride = options.scope as McpScope | undefined;\n const effectiveScope = scopeOverride ?? mcp.scope;\n if (scopeOverride && !VALID_SCOPES.includes(scopeOverride)) {\n console.log(\n pc.red(`Invalid --scope value. Valid: ${VALID_SCOPES.join(' | ')}`),\n );\n return;\n }\n if (effectiveScope === 'disabled') {\n console.log(pc.yellow('Scope is \"disabled\" ā nothing to install.'));\n return;\n }\n\n const userPrompt = async (agent: Agent, file: string): Promise<boolean> => {\n const { ok } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'ok',\n message: `Write user-scope MCP config for ${pc.cyan(agent)} at ${pc.gray(file)}?`,\n default: false,\n },\n ]);\n return ok;\n };\n\n const report = await this.mcpService.install({\n rootDir: cwd,\n agents,\n mcp: { ...mcp, enabled: true, scope: effectiveScope },\n userScopePrompt: userPrompt,\n });\n\n this.printReport(report, cwd);\n }\n\n private async actionUninstall(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n options: Record<string, string>,\n ): Promise<void> {\n const from = (options.from as 'project' | 'user' | 'all') ?? 'project';\n if (!['project', 'user', 'all'].includes(from)) {\n console.log(pc.red('--from must be: project | user | all'));\n return;\n }\n const { removed } = await this.mcpService.uninstall({\n rootDir: cwd,\n agents,\n from,\n });\n if (removed.length === 0) {\n console.log(pc.gray(`Nothing to remove at scope \"${from}\".`));\n return;\n }\n console.log(pc.green(`ā
Removed agent-skills MCP entry from:`));\n for (const r of removed) {\n console.log(` - ${pc.cyan(r.agent)} ā ${pc.gray(r.file)}`);\n }\n }\n\n private async actionSnippets(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n ): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const report = await this.mcpService.install({\n rootDir: cwd,\n agents,\n mcp: { ...mcp, enabled: true, scope: 'snippets-only' },\n });\n if (report.snippets.length === 0) {\n console.log(\n pc.gray('No snippets generated (no supported agents in .skillsrc).'),\n );\n return;\n }\n console.log(pc.green(`ā
Generated ${report.snippets.length} snippet(s):`));\n for (const s of report.snippets) {\n console.log(` - ${pc.cyan(s.agent)} ā ${pc.gray(s.file)}`);\n }\n }\n\n // ---- output ----\n\n private printReport(\n report: Awaited<ReturnType<McpConfigService['install']>>,\n cwd: string,\n ): void {\n if (report.projectWrites.length > 0) {\n console.log(pc.bold('\\nš Project-scope writes:'));\n for (const w of report.projectWrites) {\n const tag =\n w.action === 'added'\n ? pc.green('+ added ')\n : w.action === 'updated'\n ? pc.cyan('~ updated ')\n : pc.gray('= up-to-date');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n }\n if (report.userWrites.length > 0) {\n console.log(pc.bold('\\nš User-scope writes:'));\n for (const w of report.userWrites) {\n console.log(\n ` ${pc.green('+ wrote ')} ${w.agent.padEnd(12)} ${pc.gray(path.relative(cwd, w.file))}`,\n );\n }\n }\n if (report.declined.length > 0) {\n console.log(pc.bold('\\nā User-scope declined:'));\n for (const d of report.declined) {\n console.log(\n ` ${pc.gray('-')} ${d.agent.padEnd(12)} ${pc.gray(d.file)}`,\n );\n }\n }\n if (report.snippets.length > 0) {\n console.log(pc.bold('\\nš Snippet files:'));\n for (const s of report.snippets) {\n console.log(` ${pc.gray(s.file)}`);\n }\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n `\\n(skipped ā no MCP support yet: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { Agent, getAgentDefinition } from '../constants';\n\n/**\n * Service responsible for bridging native AI agent rule files to AGENTS.md.\n * Creates agent-specific rule files (e.g., .mdc, .instructions.md)\n * in their respective directories.\n */\nexport class AgentBridgeService {\n /**\n * Bridges native agent rule files to AGENTS.md by creating discovery instructions.\n *\n * The MCP runtime-enforcement block lives in `AGENTS.md` (single source of\n * truth, generated by `IndexGeneratorService.assembleRouterIndex`). Rule\n * files generated here just instruct the agent to read AGENTS.md first ā\n * they do NOT duplicate the MCP block. This keeps the message in one place\n * so it can't drift between surfaces.\n *\n * @param rootDir Project root directory\n * @param agents List of agents to generate rules for\n */\n async bridge(rootDir: string, agents: Agent[]): Promise<void> {\n const fileNameBase = 'agent-skill-standard-rule';\n const commonDescription =\n 'Rule for Agent Skills Standard - Always consult AGENTS.md for consolidated project context and technical triggers.';\n\n for (const agentId of agents) {\n const config = getAgentDefinition(agentId);\n if (!config) continue;\n\n const relativeSkillsPath = path\n .relative(config.ruleFile, config.path)\n .replace(/\\\\/g, '/');\n const prefix = relativeSkillsPath ? `${relativeSkillsPath}/` : '';\n\n const commonBody = [\n '# š Agent Skills Routing Protocol (CRITICAL)',\n '',\n 'You are operating in a Zero-Trust environment. You are strictly forbidden from relying on your baseline pre-training for architecture, styling, testing, or code patterns in this repository.',\n '',\n '> [!CRITICAL] GATEKEEPER CONSTRAINT',\n '> **Your first action in ANY session MUST be a tool call to read `AGENTS.md`.**',\n '> You must NOT write code, suggest solutions, or output text explanations until you have completed the State Machine below.',\n '',\n '## š The Mandatory State Machine',\n '',\n 'You must execute these states sequentially. Do not proceed to the next state until the current one is satisfied.',\n '',\n '### State 1: Discovery (Tool Call Required)',\n '',\n '- **Action:** Execute a file-reading tool (e.g., `view_file`, `read_file`, `cat`) targeting the exact path: `AGENTS.md` (located in the project root).',\n '- **Condition to pass:** You have successfully read the `<!-- SKILLS_INDEX_START -->` block.',\n '',\n '### State 2: Trigger Matching (Internal Thought)',\n '',\n \"- **Action:** Analyze the user's prompt (keywords) and the files involved in the task (globs).\",\n '- **Condition to pass:** Cross-reference them against the `(triggers: ...)` list inside `AGENTS.md`. Identify all matching Skills and note their exact file paths.',\n '',\n '### State 3: Context Loading (Tool Call Required)',\n '',\n `- **Action:** Execute file-reading tools to read the \\`SKILL.md\\` files at the exact paths identified in State 2.`,\n '- **Condition to pass:** You have ingested the specific guidelines for the task. If no skills matched in State 2, you may skip this state.',\n '',\n '### State 4: Execution & Audit Log (Output Generation)',\n '',\n '- **Action:** You may now begin answering the user or writing code.',\n '- **Constraint:** Your very first text output MUST be a \"Pre-Write Audit Log\" confirming which skills were loaded, or explicitly stating \"No project-specific skills applicable.\"',\n '',\n '## Self-Learning Protocol',\n '',\n `At the end of any multi-step task with user corrections, load and run **[common/common-session-retrospective](${prefix}common/common-session-retrospective/SKILL.md)** to capture skill gaps and prevent repeat rework.`,\n '',\n ].join('\\n');\n\n // SAFETY: Only write if the agent is detected in the project\n // This prevents creating unused directories.\n let detected = false;\n for (const file of config.detectionFiles) {\n if (await fs.pathExists(path.join(rootDir, file))) {\n detected = true;\n break;\n }\n }\n\n if (!detected) continue;\n\n const ruleFilePath = path.join(\n rootDir,\n config.ruleFile,\n config.ruleFileName || `${fileNameBase}${config.ruleExtension}`,\n );\n\n // Ensure directory exists (e.g. .cursor/rules inside .cursor)\n await fs.ensureDir(path.dirname(ruleFilePath));\n\n let content = '';\n\n switch (config.frontmatterStyle) {\n case 'cursor':\n content += `---\\ndescription: ${commonDescription}\\nglobs: ['**/*']\\nalwaysApply: true\\n---\\n\\n`;\n break;\n case 'copilot':\n content += `---\\ndescription: ${commonDescription}\\napplyTo: '**/*'\\n---\\n\\n`;\n break;\n case 'none':\n // No frontmatter\n break;\n }\n\n const isClaude = agentId === Agent.Claude;\n\n if (isClaude) {\n const claudeProtocol = [\n '',\n '## Agent Protocol',\n '',\n 'See `AGENTS.md` for the Zero-Trust skill loading protocol (applies to all AI agents) and the MCP runtime-enforcement section (when enabled).',\n '',\n '## Self-Learning Protocol',\n '',\n `At the end of any multi-step task with user corrections, load and run **[common/common-session-retrospective](${prefix}common/common-session-retrospective/SKILL.md)** to capture skill gaps and prevent repeat rework.`,\n '',\n ].join('\\n');\n\n const claudePath = path.join(rootDir, 'CLAUDE.md');\n if (await fs.pathExists(claudePath)) {\n const existingContent = await fs.readFile(claudePath, 'utf8');\n if (\n existingContent &&\n !existingContent.includes('## Agent Protocol')\n ) {\n await fs.appendFile(claudePath, claudeProtocol);\n }\n } else {\n await fs.outputFile(claudePath, claudeProtocol.trimStart());\n }\n // Also write the full Zero-Trust rules to the rule directory if it's not the root\n // But for Claude, CLAUDE.md IS the rule file.\n // The user wants CLAUDE.md to refer to AGENTS.md.\n continue;\n }\n\n content += commonBody;\n\n await fs.outputFile(ruleFilePath, content);\n }\n }\n}\n","import { MetadataReader, SkillMetadata } from './MetadataReader';\n\n/**\n * Service for building the markdown content of AGENTS.md and _INDEX.md files.\n * Handles formatting, ordering, and template injection.\n */\nexport class IndexContentBuilder {\n private metadataReader: MetadataReader;\n\n constructor(metadataReader: MetadataReader) {\n this.metadataReader = metadataReader;\n }\n\n /**\n * Derives foundational composite IDs for a skill based on registry-owned naming rules.\n * Only applies to non-common skills. Deduplicates against explicit composites.\n */\n public deriveFoundationalComposites(\n category: string,\n skill: string,\n explicitComposites: string[],\n rules: Record<string, string[]>,\n ): string[] {\n if (category === 'common') return [];\n const derived: string[] = [];\n for (const [foundational, patterns] of Object.entries(rules)) {\n const matches = patterns.some((p) => skill.includes(p));\n if (matches && !explicitComposites.includes(foundational)) {\n derived.push(foundational);\n }\n }\n return derived;\n }\n\n /**\n * Formats a single skill into a list item for AGENTS.md.\n */\n public formatEntry(\n category: string,\n skill: string,\n metadata: SkillMetadata,\n foundationalRules: Record<string, string[]> = {},\n ): string {\n const id = `${category}/${skill}`;\n\n const explicitComposites = metadata.triggers.composite || [];\n const autoComposites = this.deriveFoundationalComposites(\n category,\n skill,\n explicitComposites,\n foundationalRules,\n );\n const allComposites = [...explicitComposites, ...autoComposites];\n\n const triggers = [\n ...(metadata.triggers.files || []),\n ...(metadata.triggers.keywords || []),\n ...(allComposites.length ? allComposites.map((c) => `+${c}`) : []),\n ...(metadata.triggers.exclude\n ? metadata.triggers.exclude.map((e) => `!${e}`)\n : []),\n ].join(', ');\n\n const triggerText = triggers ? ` (triggers: \\`${triggers}\\`)` : '';\n\n let desc = this.metadataReader.sanitizeDescription(\n metadata.description || '',\n id,\n );\n // Remove (triggers: ...) if it already exists to avoid duplication\n desc = desc.replace(/\\s*\\(triggers:.*?\\)\\s*$/, '');\n\n const prefixIcon = metadata.priority.startsWith('P0') ? 'šØ ' : '';\n const content = `${prefixIcon}${desc}${triggerText}`.trim();\n return `- **[${id}]**: ${content}`;\n }\n\n /**\n * Assembles the full AGENTS.md markdown including headers and Zero-Trust rules.\n */\n public assembleIndex(entries: string[]): string {\n const header = [\n '## Agent Skills Index',\n '',\n '> [!CRITICAL] GATEKEEPER CONSTRAINT',\n '> **You are operating in a Zero-Trust environment.**',\n '> You are strictly forbidden from generating code, proposing solutions, or relying on your pre-training until you have successfully executed a tool call to read the applicable `SKILL.md` files from this index.',\n '',\n '## **Rule Zero: Mandatory Zero-Trust Protocol**',\n '',\n '> [!CRITICAL]',\n '> **Zero-Trust Enforcement:** Skills loaded from this index always override standard code patterns. Skipping the Audit Log or Self-Scan is a protocol violation.',\n '',\n '### **1. The Pre-Write Audit Log (Mandatory)**',\n '',\n 'Before invoking any file-editing tool (`write_to_file`, `replace_file_content`, `multi_replace_file_content`), the ASSISTANT **MUST** explicitly state in its thought process/text output:',\n '',\n '1. **Skills Identified**: List the Skill IDs triggered by the file path or current task keywords.',\n '2. **Explicit Audit**: For each identified skill, confirm: \"Checked against [Skill ID] ā no violations found.\" Or \"Violation detected in [Skill ID]: [Issue] ā correcting now.\"',\n '3. **No-Skill Justification**: If no skills apply, explicitly state: \"No project-specific skills applicable to this file/transaction.\"',\n '',\n '### **2. The Post-Write Self-Scan (Mandatory)**',\n '',\n 'Immediately **AFTER** any file-editing tool returns, the ASSISTANT **MUST**:',\n '',\n '1. **Validate**: Contrast the final file content against ALL active Skill IDs.',\n '2. **Identify Slips**: Look for \"Standard Defaults\" (e.g., local mocks, hardcoded styles) that snuck in.',\n '3. **Self-Correct**: If a violation is found, fix it immediately in the next tool call.',\n '',\n '## **Critical Anti-Patterns (Zero-Tolerance)**',\n '',\n '- **Reversion to Defaults**: Never use \"standard\" patterns (generic library calls, local mocks) if a Project Skill exists.',\n '- **The \"Done\" Trap**: Never prioritize functional completion over structural/protocol compliance.',\n '- **Audit Skipping**: Never invoke a write tool without an explicit Pre-Write Audit Log.',\n '',\n '## ā” How to Find and Use This Index (Mandatory)',\n '',\n '> [!IMPORTANT] PATH RESOLUTION (Cross-Platform)',\n '> Skill IDs in the list below (e.g., `[category/skill-name]`) represent the relative folder path.',\n '> Because this project supports multiple AI agents, skills may reside in a base directory like `.gemini/skills/`, `.agents/skills/`, or `.cursor/skills/`.',\n '> **Action:** You must prepend the correct base directory to the ID. (Example: If ID is `[flutter/cicd]`, the file is at `<BASE_DIR>/flutter/cicd/SKILL.md`). Use your file search tools (e.g., `list_directory` or `find`) if you are unsure of the base directory.',\n '',\n '| Trigger Type | What to match | Required Action |',\n '| --- | --- | --- |',\n '| **File glob** (e.g. `**/*.ts`) | Files you are currently editing match the pattern | Call `view_file` on `<BASE_DIR>/[Skill ID]/SKILL.md` |',\n \"| **Keyword** (e.g. `auth`, `refactor`) | These words appear in the user\\\\'s request | Call `view_file` on `<BASE_DIR>/[Skill ID]/SKILL.md` |\",\n '| **Composite** (e.g. `+other/skill`) | Another listed skill is already active | Also load this skill via `view_file` |',\n '',\n '> [!TIP]',\n '> **Indirect phrasing still counts.** Match keywords by intent, not just exact words.',\n '> Examples: \"make it faster\" ā `performance`, \"broken query\" ā `database`, \"login flow\" ā `auth`, \"clean up this file\" ā `refactor`.',\n '',\n '### List of Available Skills',\n '',\n ].join('\\n');\n\n return `${header}\\n${entries.join('\\n')}\\n`;\n }\n}\n","/**\n * Subset of the registry's metadata.json that the IndexGeneratorService needs at\n * index-generation time. Provided by the caller (e.g. SyncService) so the file\n * never needs to be written to disk inside the user's project.\n */\nexport interface RemoteMetadata {\n file_routing?: Record<string, string[]>;\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n foundational_composite_rules?: Record<string, string[]>;\n}\n\n/**\n * Metadata structure for a skill, extracted from the frontmatter and content of a SKILL.md file.\n */\nexport interface SkillMetadata {\n /** The human-readable name of the skill. */\n name: string;\n /** A brief summary of what the skill covers. */\n description: string;\n /** The priority level (e.g., P0, P1) determining its critical importance. */\n priority: string;\n /** Trigger conditions for when this skill should be activated. */\n triggers: {\n /** Glob patterns of files that trigger this skill. */\n files?: string[];\n /** List of keywords that trigger this skill. */\n keywords?: string[];\n /** Other skill IDs that, when active, also trigger this skill. */\n composite?: string[];\n /** Patterns to explicitly exclude from triggering this skill. */\n exclude?: string[];\n };\n}\n\n/**\n * Interface definition for IndexGeneratorService.\n */\nexport abstract class IndexGeneratorService {\n abstract withMetadata(metadata: RemoteMetadata): this;\n\n abstract generate(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<string>;\n\n abstract generateCategoryIndex(\n baseDir: string,\n category: string,\n ): Promise<string>;\n\n abstract generateAllCategoryIndices(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<Record<string, string>>;\n\n abstract assembleRouterIndex(\n baseDir: string,\n allowedCategories?: string[],\n mcpEnabled?: boolean,\n ): Promise<string>;\n\n abstract assembleIndex(entries: string[]): string;\n\n abstract sanitizeDescription(desc: string, skillId?: string): string;\n}\n","/**\n * Centralized patterns for detecting and sanitizing prompt injection.\n * Shared between the CLI and CI scanning scripts.\n */\n\nexport const INJECTION_PATTERNS: RegExp[] = [\n /ignore\\s+(?:all\\s+|previous\\s+|prior\\s+)*(?:instructions?|rules?|guidance)/gi,\n /you\\s+(?:must|should|shall|will)\\s+(?:now|immediately)\\b/gi,\n /^(?:system|user|assistant)\\s*:/gim,\n /(?:^|\\n)\\s*-{3,}\\s*(?:\\n|$)/g,\n /<(?:script|iframe|style)[^>]*\\s*>[\\s\\S]*?<\\/(?:script|iframe|style)[^>]*\\s*>/gi,\n];\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport { INJECTION_PATTERNS } from '../constants/security';\n\n/**\n * Subset of the registry's metadata.json that the IndexGeneratorService needs at\n * index-generation time. Provided by the caller (e.g. SyncService) so the file\n * never needs to be written to disk inside the user's project.\n */\nexport interface RemoteMetadata {\n file_routing?: Record<string, string[]>;\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n foundational_composite_rules?: Record<string, string[]>;\n}\n\n/**\n * Metadata structure for a skill, extracted from the frontmatter and content of a SKILL.md file.\n */\nexport interface SkillMetadata {\n /** The human-readable name of the skill. */\n name: string;\n /** A brief summary of what the skill covers. */\n description: string;\n /** The priority level (e.g., P0, P1) determining its critical importance. */\n priority: string;\n /** Trigger conditions for when this skill should be activated. */\n triggers: {\n /** Glob patterns of files that trigger this skill. */\n files?: string[];\n /** List of keywords that trigger this skill. */\n keywords?: string[];\n /** Other skill IDs that, when active, also trigger this skill. */\n composite?: string[];\n /** Patterns to explicitly exclude from triggering this skill. */\n exclude?: string[];\n };\n}\n\n/**\n * Service for loading and providing consolidated metadata for index generation.\n * Handles both remote-injected metadata and local file-system fallbacks.\n */\nexport class MetadataReader {\n private remoteMetadata?: RemoteMetadata;\n\n constructor(remote?: RemoteMetadata) {\n this.remoteMetadata = remote;\n }\n\n /**\n * Loads foundational composite rules. Uses injected remote metadata when available;\n * falls back to reading metadata.json from baseDir.\n */\n async loadFoundationalRules(\n baseDir: string,\n ): Promise<Record<string, string[]>> {\n if (this.remoteMetadata?.foundational_composite_rules !== undefined) {\n return this.remoteMetadata.foundational_composite_rules;\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n foundational_composite_rules?: Record<string, string[]>;\n };\n return parsed.foundational_composite_rules ?? {};\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[MetadataReader] Failed to load foundational rules: ${error}`,\n );\n }\n }\n return {};\n }\n\n /**\n * Loads file routing rules. Uses injected remote metadata when available;\n * falls back to reading metadata.json from baseDir.\n */\n async loadFileRouting(baseDir: string): Promise<Record<string, string[]>> {\n if (this.remoteMetadata?.file_routing !== undefined) {\n return this.remoteMetadata.file_routing;\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n file_routing?: Record<string, string[]>;\n };\n return parsed.file_routing ?? {};\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[MetadataReader] Failed to load file routing: ${error}`);\n }\n }\n return {};\n }\n\n /**\n * Loads broad glob patterns and base language skill mappings. Uses injected remote\n * metadata when available; falls back to reading metadata.json from baseDir.\n */\n async loadTierConfig(baseDir: string): Promise<{\n broadGlobs: string[];\n baseSkills: Record<string, string>;\n }> {\n if (this.remoteMetadata !== undefined) {\n return {\n broadGlobs: this.remoteMetadata.broad_globs ?? [],\n baseSkills: this.remoteMetadata.base_language_skills ?? {},\n };\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n };\n return {\n broadGlobs: parsed.broad_globs ?? [],\n baseSkills: parsed.base_language_skills ?? {},\n };\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[MetadataReader] Failed to load tier config: ${error}`);\n }\n }\n return { broadGlobs: [], baseSkills: {} };\n }\n\n /**\n * Parses a SKILL.md file to extract its metadata (frontmatter + priority).\n */\n async parseSkill(skillPath: string): Promise<SkillMetadata | null> {\n try {\n const content = await fs.readFile(skillPath, 'utf8');\n const frontmatterMatch = content.match(\n /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/,\n );\n\n if (!frontmatterMatch) return null;\n\n const fm = yaml.load(frontmatterMatch[1]) as Record<string, unknown>;\n const body = frontmatterMatch[2];\n\n const priorityMatch = body.match(/## \\*\\*Priority:\\s*([^*]+)\\*\\*/);\n const priority = priorityMatch ? priorityMatch[1].trim() : 'P1';\n\n const metadata = (fm?.metadata || {}) as Record<string, unknown>;\n const rawTriggers = (metadata?.triggers || {}) as Record<string, unknown>;\n\n const triggers: {\n files?: string[];\n keywords?: string[];\n composite?: string[];\n exclude?: string[];\n } = {\n files: Array.isArray(rawTriggers.files)\n ? (rawTriggers.files as string[])\n : [],\n keywords: Array.isArray(rawTriggers.keywords)\n ? (rawTriggers.keywords as string[])\n : [],\n composite: Array.isArray(rawTriggers.composite)\n ? (rawTriggers.composite as string[])\n : [],\n exclude: Array.isArray(rawTriggers.exclude)\n ? (rawTriggers.exclude as string[])\n : [],\n };\n\n const hasStructured =\n (triggers.files?.length || 0) > 0 ||\n (triggers.keywords?.length || 0) > 0;\n const description =\n typeof fm.description === 'string' ? fm.description : '';\n\n if (!hasStructured && description) {\n const descTrigs = description.match(/\\(triggers:\\s*`?(.*?)`?\\)\\s*$/);\n if (descTrigs) {\n const rawParts = descTrigs[1].split(',');\n const parts: string[] = [];\n let current = '';\n let braceCount = 0;\n\n for (let i = 0; i < rawParts.length; i++) {\n const p = rawParts[i];\n braceCount += (p.match(/{/g) || []).length;\n braceCount -= (p.match(/}/g) || []).length;\n current += (current ? ',' : '') + p;\n\n if (braceCount === 0) {\n parts.push(current.trim());\n current = '';\n }\n }\n if (current) parts.push(current.trim());\n\n const files = parts.filter(\n (p) =>\n p.includes('*') ||\n p.includes('/') ||\n p.includes('{') ||\n /\\.\\w+$/.test(p),\n );\n const keywords = parts.filter(\n (p) =>\n !p.includes('*') &&\n !p.includes('/') &&\n !p.includes('{') &&\n !/\\.\\w+$/.test(p),\n );\n\n if (files.length > 0) triggers.files = files;\n if (keywords.length > 0) triggers.keywords = keywords;\n }\n }\n\n return {\n name: typeof fm.name === 'string' ? fm.name : '',\n description,\n priority,\n triggers,\n };\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[MetadataReader] Failed to parse skill at ${skillPath}: ${error}`,\n );\n }\n return null;\n }\n }\n\n /**\n * Sanitizes a skill description to prevent indirect prompt injection.\n */\n sanitizeDescription(desc: string, skillId: string = 'unknown'): string {\n let sanitized = desc;\n let wasModified = false;\n\n for (const pattern of INJECTION_PATTERNS) {\n if (pattern.test(sanitized)) {\n wasModified = true;\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n pattern.lastIndex = 0;\n }\n\n if (wasModified) {\n process.stderr.write(\n `[SECURITY] Prompt injection pattern stripped from skill description: ${skillId}\\n`,\n );\n }\n\n return sanitized;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { IndexContentBuilder } from './IndexContentBuilder';\nimport { IndexGeneratorService, RemoteMetadata } from './IndexGeneratorService';\nimport { MetadataReader } from './MetadataReader';\n\n/**\n * Enhanced IndexGeneratorService that delegates to MetadataReader and IndexContentBuilder.\n * Maintains compatibility with existing callers.\n */\nexport class IndexGeneratorServiceImpl extends IndexGeneratorService {\n private reader: MetadataReader;\n private builder: IndexContentBuilder;\n\n constructor(remoteMetadata?: RemoteMetadata) {\n super();\n this.reader = new MetadataReader(remoteMetadata);\n this.builder = new IndexContentBuilder(this.reader);\n }\n\n /** Overridable metadata injection */\n withMetadata(metadata: RemoteMetadata): this {\n this.reader = new MetadataReader(metadata);\n this.builder = new IndexContentBuilder(this.reader);\n return this;\n }\n\n async generate(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<string> {\n const entries = new Set<string>();\n const foundationalRules = await this.reader.loadFoundationalRules(baseDir);\n\n if (!(await fs.pathExists(baseDir))) return this.assembleIndex([]);\n\n let categories = await fs.readdir(baseDir);\n categories = categories.filter((category) => {\n if (category.startsWith('.')) return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(category) &&\n category !== 'common'\n ) {\n return false;\n }\n return true;\n });\n\n categories.sort();\n\n for (const category of categories) {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.stat(categoryPath)).isDirectory()) continue;\n\n const skills = await fs.readdir(categoryPath);\n skills.sort();\n for (const skill of skills) {\n const skillPath = path.join(categoryPath, skill, 'SKILL.md');\n const isRegistrySkill = await fs.pathExists(skillPath);\n const isStandaloneSkill =\n !isRegistrySkill &&\n skill.endsWith('.md') &&\n skill !== '_INDEX.md' &&\n !(await fs.stat(path.join(categoryPath, skill))).isDirectory();\n\n const targetPath = isRegistrySkill\n ? skillPath\n : path.join(categoryPath, skill);\n if (!isRegistrySkill && !isStandaloneSkill) continue;\n\n const metadata = await this.reader.parseSkill(targetPath);\n if (metadata) {\n const skillId = isStandaloneSkill ? skill.replace('.md', '') : skill;\n const entry = this.builder.formatEntry(\n category,\n skillId,\n metadata,\n foundationalRules,\n );\n entries.add(entry);\n }\n }\n }\n\n return this.assembleIndex(Array.from(entries));\n }\n\n public assembleIndex(entries: string[]): string {\n return this.builder.assembleIndex(entries);\n }\n\n /**\n * Sanitizes a skill description to prevent indirect prompt injection.\n */\n public sanitizeDescription(\n desc: string,\n skillId: string = 'unknown',\n ): string {\n return this.reader.sanitizeDescription(desc, skillId);\n }\n\n /**\n * Generates all _INDEX.md files for categories found in baseDir.\n */\n async generateAllCategoryIndices(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<Record<string, string>> {\n if (!(await fs.pathExists(baseDir))) return {};\n\n let categories = await fs.readdir(baseDir);\n categories = categories.filter((c) => {\n if (c.startsWith('.') || c === '_INDEX.md') return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(c) &&\n c !== 'common'\n ) {\n return false;\n }\n return true;\n });\n categories.sort();\n\n const result: Record<string, string> = {};\n for (const category of categories) {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.stat(categoryPath)).isDirectory()) continue;\n\n const index = await this.generateCategoryIndex(baseDir, category);\n if (index) result[category] = index;\n }\n return result;\n }\n\n async generateCategoryIndex(\n baseDir: string,\n category: string,\n ): Promise<string> {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.pathExists(categoryPath))) return '';\n\n const { broadGlobs, baseSkills } =\n await this.reader.loadTierConfig(baseDir);\n const baseSkillForCategory = baseSkills[category];\n\n const entries = await fs.readdir(categoryPath);\n entries.sort();\n\n const fileMatchRows: string[] = [];\n const keywordMatchRows: string[] = [];\n\n for (const entryName of entries) {\n if (entryName.startsWith('.') || entryName === '_INDEX.md') continue;\n\n const skillPath = path.join(categoryPath, entryName, 'SKILL.md');\n const isRegistrySkill = await fs.pathExists(skillPath);\n const isStandaloneSkill =\n !isRegistrySkill &&\n entryName.endsWith('.md') &&\n !(await fs.stat(path.join(categoryPath, entryName))).isDirectory();\n\n if (!isRegistrySkill && !isStandaloneSkill) continue;\n\n const targetPath = isRegistrySkill\n ? skillPath\n : path.join(categoryPath, entryName);\n const skillId = isStandaloneSkill\n ? entryName.replace('.md', '')\n : entryName;\n\n const metadata = await this.reader.parseSkill(targetPath);\n if (!metadata) continue;\n\n const isBaseSkill = skillId === baseSkillForCategory;\n const allFiles = metadata.triggers.files || [];\n const kwTrigs = (metadata.triggers.keywords || []).join(', ') || 'ā';\n const prefix = metadata.priority.startsWith('P0') ? '**' : '';\n const suffix = prefix ? '**' : '';\n\n const specificFiles = allFiles.filter((f) => !broadGlobs.includes(f));\n const hasBroadGlob = allFiles.some((f) => broadGlobs.includes(f));\n\n if (isBaseSkill || (specificFiles.length > 0 && !hasBroadGlob)) {\n const displayFiles = isBaseSkill\n ? allFiles.map((f) => `\\`${f}\\``).join(', ')\n : specificFiles.map((f) => `\\`${f}\\``).join(', ');\n fileMatchRows.push(\n `| ${prefix}${skillId}${suffix} | ${displayFiles || 'ā'} | ${kwTrigs} |`,\n );\n } else if (specificFiles.length > 0 && hasBroadGlob) {\n const displayFiles = specificFiles.map((f) => `\\`${f}\\``).join(', ');\n fileMatchRows.push(\n `| ${prefix}${skillId}${suffix} | ${displayFiles} | ${kwTrigs} |`,\n );\n } else {\n keywordMatchRows.push(`| ${prefix}${skillId}${suffix} | ${kwTrigs} |`);\n }\n }\n\n if (fileMatchRows.length === 0 && keywordMatchRows.length === 0) return '';\n\n const lines = [\n `<!-- AUTO-GENERATED from SKILL.md frontmatters ā do not edit manually -->`,\n `# ${category} Skills Index`,\n '',\n ];\n\n if (fileMatchRows.length > 0) {\n lines.push(\n `## File Match (auto-check against the file you are editing)`,\n '',\n '| Skill | File pattern | Keywords |',\n '| ----- | ------------ | -------- |',\n ...fileMatchRows,\n '',\n );\n }\n\n if (keywordMatchRows.length > 0) {\n lines.push(\n `## Keyword Match (only when user's request mentions these)`,\n '',\n '| Skill | Match when user mentions |',\n '| ----- | ----------------------- |',\n ...keywordMatchRows,\n '',\n );\n }\n\n lines.push(\n `> Load matched skills: \\`<SKILLS>/${category}/<skill>/SKILL.md\\`. Load ALL that match ā the tier model already filters irrelevant ones.`,\n '',\n );\n\n return lines.join('\\n');\n }\n\n async assembleRouterIndex(\n baseDir: string,\n allowedCategories?: string[],\n mcpEnabled: boolean = false,\n ): Promise<string> {\n const fileRouting = await this.reader.loadFileRouting(baseDir);\n\n let availableCategories: string[] = [];\n if (await fs.pathExists(baseDir)) {\n const dirs = await fs.readdir(baseDir);\n availableCategories = dirs.filter((d) => {\n if (d.startsWith('.') || d === '_INDEX.md') return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(d) &&\n d !== 'common'\n ) {\n return false;\n }\n return true;\n });\n }\n\n const routerRows: string[] = [];\n const coveredCategories = new Set<string>();\n\n const extGrouped = new Map<string, string[]>();\n for (const [ext, cats] of Object.entries(fileRouting)) {\n if (ext === '_comment') continue;\n const filtered = cats.filter((c: string) =>\n availableCategories.includes(c),\n );\n if (filtered.length === 0) continue;\n\n const key = filtered.sort().join('+');\n if (!extGrouped.has(key)) extGrouped.set(key, []);\n extGrouped.get(key)!.push(ext);\n filtered.forEach((c) => coveredCategories.add(c));\n }\n\n const formatRouterPattern = (ext: string): string => {\n if (ext.startsWith('_')) return `\\`*${ext}\\``;\n return `\\`*.${ext}\\``;\n };\n\n for (const [catKey, exts] of extGrouped) {\n const cats = catKey.split('+');\n const extDisplay = exts.map((e) => formatRouterPattern(e)).join(', ');\n const catDisplay = cats\n .map((c) => `\\`<SKILLS>/${c}/_INDEX.md\\``)\n .join(', ');\n routerRows.push(`| ${extDisplay} | ${catDisplay} |`);\n }\n\n if (availableCategories.includes('common')) {\n coveredCategories.add('common');\n routerRows.push(\n '| Any file (keyword match) | `<SKILLS>/common/_INDEX.md` |',\n );\n }\n\n if (availableCategories.includes('quality-engineering')) {\n coveredCategories.add('quality-engineering');\n routerRows.push(\n '| QE workflow | `<SKILLS>/quality-engineering/_INDEX.md` |',\n );\n }\n\n // The MCP block is always present (not conditional on .skillsrc.mcp.enabled)\n // because:\n // 1. .skillsrc.mcp.enabled records CLI consent to manage configs ā it's\n // orthogonal to whether the MCP is actually registered at runtime.\n // 2. A user can manually register the MCP in their runtime config without\n // ever touching .skillsrc; we don't want AGENTS.md to be silent about\n // it in that case.\n // 3. The AI can self-check via its tool list before calling ā the\n // \"If ... is registered\" phrasing makes the instruction correct in\n // both states.\n // 4. Tooltip-only ā when `mcpEnabled` is true (CLI-managed), we\n // add a confirmation note that this project ships with MCP support.\n const mcpStatusNote = mcpEnabled\n ? '> [!TIP] **This project has the MCP server enabled in `.skillsrc`** ā `sync` keeps your runtime configs in step. Run `ags mcp status` to verify per-agent installation.'\n : '> [!NOTE] To enable MCP-managed installs in this project, run `ags mcp enable` (or edit `.skillsrc`). The MCP works fine if you registered it manually too.';\n\n const mcpBlock = [\n '## š Runtime Enforcement via MCP',\n '',\n \"If the `agent-skills-standard` MCP server is registered in your runtime (check your tool list ā look for `load_skills_for_files`), **prefer those tools over manually walking the router below**. The MCP returns identical content but is auditable AND inherited by sub-agents that don't see this file.\",\n '',\n '| Tool | When to call it |',\n '| --- | --- |',\n '| `list_workflows()` | At the start of any task or session to discover available standard operating procedures |',\n '| `get_workflow(name)` | Once a relevant workflow is identified to retrieve exact step-by-step instructions |',\n '| `load_skills_for_files(files=[...])` | Before editing/reviewing any source file |',\n '| `load_skills_for_keywords(keywords=[...])` | Planning before files are chosen |',\n '| `get_skill(category, name)` | Direct lookup when you know the skill id |',\n '| `audit_session_compliance()` | Before declaring a task complete |',\n '',\n \"> [!IMPORTANT] **Sub-agents don't inherit this `AGENTS.md` ā they do inherit the MCP.** If you delegate work to a sub-agent, instruct it to call the MCP tools above as its first action.\",\n '',\n mcpStatusNote,\n '',\n 'If `load_skills_for_files` is **not** in your tool list, the MCP is not registered ā fall back to the router table below.',\n '',\n '---',\n '',\n ].join('\\n');\n\n const header = [\n '## Agent Skills Index',\n '',\n '> [!CRITICAL] Zero-Trust: Read the matching `SKILL.md` BEFORE writing any code.',\n '> Skills from this index override pre-training patterns. If no skill matches, state: \"No project-specific skills applicable.\"',\n '',\n '> š” **Global Token Optimization**: If the `rtk` CLI tool is installed, actively prepend it to verbose development commands (e.g. `rtk npm test`, `rtk grep`). If the `caveman` skill is available or requested, use `/caveman` mode for reporting.',\n '',\n mcpBlock,\n '## Skill Resolution Protocol',\n '',\n 'Each `_INDEX.md` has two sections - follow both:',\n '',\n '1. **Match file type** -> find the category index in the router table below.',\n '2. **Read the `_INDEX.md`** -> it has two sections:',\n ' - **File Match**: auto-check these against the file you are editing (path pattern match).',\n \" - **Keyword Match**: only check if the user's request mentions these concepts.\",\n '3. **Load ALL matched `SKILL.md`** -> read every matched skill before writing code. The tier model keeps matches focused.',\n '',\n \"> `<SKILLS>` = your agent's skill directory (e.g., `.claude/skills/`, `.cursor/skills/`, `.gemini/skills/`).\",\n '',\n '| File type | Read category index |',\n '| --------- | ------------------- |',\n ...routerRows,\n '',\n '> [!NOTE] **Test/spec file precedence:** `.spec.ts`, `.test.ts` -> use the `common` row (takes precedence over the generic `*.ts` row). `.spec.tsx`, `.test.tsx` -> use the `react` row (takes precedence over the generic `*.tsx` row).',\n '',\n '> [!TIP] **Indirect phrasing counts.** \"make it faster\" -> performance, \"broken query\" -> database, \"login flow\" -> auth.',\n '',\n ].join('\\n');\n\n return header;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig, SkillEntry } from '../models/config';\nimport { CollectedSkill, GitHubTreeItem } from '../models/types';\nimport { GithubService } from './GithubService';\n\n/**\n * Service responsible for synchronizing agent skills from a remote registry.\n */\nexport class SkillSyncService {\n constructor(private githubService: GithubService) {}\n\n /**\n * Assembles skills from the remote registry based on provided categories and configuration.\n */\n async assembleSkills(\n categories: string[],\n config: SkillConfig,\n ): Promise<CollectedSkill[]> {\n const collected: CollectedSkill[] = [];\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n\n if (!githubMatch) {\n console.log(pc.red('Error: Only GitHub registries supported.'));\n return [];\n }\n\n const { owner, repo } = githubMatch;\n\n for (const category of categories) {\n const catConfig = config.skills[category];\n const ref = catConfig.ref || 'main';\n\n console.log(pc.gray(` - Discovering ${category} (${ref})...`));\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) {\n console.log(pc.red(` ā Failed to fetch ${category}@${ref}.`));\n continue;\n }\n\n const foldersToSync = this.identifyFoldersToSync(\n category,\n catConfig,\n treeData.tree,\n );\n\n for (const absOrRelSkill of foldersToSync) {\n const skill = await this.fetchSkill(\n owner,\n repo,\n ref,\n category,\n absOrRelSkill,\n treeData.tree,\n );\n if (skill) collected.push(skill);\n }\n }\n\n return collected;\n }\n\n /**\n * Writes collected skills to target agent paths.\n */\n async writeSkills(\n skills: CollectedSkill[],\n config: SkillConfig,\n agents: Agent[],\n ) {\n const overrides = config.custom_overrides || [];\n\n // Group skills by category to know which folders to prune\n const fetchedSkillsByCategory: Record<string, Set<string>> = {};\n for (const skill of skills) {\n if (!fetchedSkillsByCategory[skill.category]) {\n fetchedSkillsByCategory[skill.category] = new Set();\n }\n fetchedSkillsByCategory[skill.category].add(skill.skill);\n }\n\n for (const agentId of agents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || !agentDef.path) continue;\n\n const basePath = agentDef.path;\n await fs.ensureDir(basePath);\n\n // Clean up orphaned skills inside categories we are syncing\n // Default to prune: true if not specified\n const shouldPrune = config.prune !== false;\n\n if (shouldPrune) {\n for (const category of Object.keys(fetchedSkillsByCategory)) {\n const categoryPath = path.join(basePath, category);\n if (await fs.pathExists(categoryPath)) {\n const existingDirs = await fs.readdir(categoryPath);\n for (const dir of existingDirs) {\n // If the folder is not in the newly fetched list, it might be orphaned\n if (!fetchedSkillsByCategory[category].has(dir)) {\n const fullPath = path.join(categoryPath, dir);\n // Do not delete if it's protected by custom_overrides\n if (!this.isOverridden(fullPath, overrides)) {\n await fs.remove(fullPath);\n }\n }\n }\n }\n }\n }\n\n for (const skill of skills) {\n await this.writeSkillForAgent(agentId, skill, overrides, basePath);\n }\n console.log(pc.gray(` - Updated ${basePath}/ (${agentDef.name})`));\n }\n }\n\n private async writeSkillForAgent(\n agentId: string,\n skill: CollectedSkill,\n overrides: string[],\n basePath: string,\n ) {\n const isKiro = agentId === Agent.Kiro;\n const kiroFolder = `${skill.category}-${skill.skill}`;\n const skillPath = isKiro\n ? path.join(basePath, kiroFolder)\n : path.join(basePath, skill.category, skill.skill);\n\n await fs.ensureDir(skillPath);\n\n for (const fileItem of skill.files) {\n const targetFilePath = path.join(skillPath, fileItem.name);\n\n if (this.isOverridden(targetFilePath, overrides)) {\n console.log(\n pc.yellow(\n ` ā ļø Skipping overridden: ${this.normalizePath(targetFilePath)}`,\n ),\n );\n continue;\n }\n\n if (!this.isPathSafe(targetFilePath, skillPath)) {\n console.log(\n pc.red(` ā Security Error: Invalid path ${fileItem.name}`),\n );\n continue;\n }\n\n let content = fileItem.content;\n if (isKiro && fileItem.name === 'SKILL.md') {\n content = this.transformSkillForKiro(content, skill.category);\n }\n\n await fs.outputFile(targetFilePath, content);\n }\n }\n\n private async fetchSkill(\n owner: string,\n repo: string,\n ref: string,\n category: string,\n absOrRelSkill: string,\n tree: GitHubTreeItem[],\n ): Promise<CollectedSkill | null> {\n const [sourceCat, skillName] = absOrRelSkill.includes('/')\n ? absOrRelSkill.split('/')\n : [category, absOrRelSkill];\n\n const prefix = `skills/${sourceCat}/${skillName}/`;\n const skillSourceFiles = tree.filter(\n (f) => f.path.startsWith(prefix) && f.type === 'blob',\n );\n\n const downloadTasks = skillSourceFiles\n .filter((f) => {\n const rel = f.path.replace(prefix, '');\n return rel === 'SKILL.md' || /^(references|scripts|assets)\\//.test(rel);\n })\n .map((f) => ({ owner, repo, ref, path: f.path }));\n\n const files =\n await this.githubService.downloadFilesConcurrent(downloadTasks);\n if (files.length === 0) return null;\n\n console.log(\n pc.gray(\n ` + Fetched ${sourceCat}/${skillName} (${files.length} files)`,\n ),\n );\n\n return {\n category: sourceCat,\n skill: skillName,\n files: files.map((f) => ({\n name: f.path.replace(prefix, ''),\n content: f.content,\n })),\n };\n }\n\n private identifyFoldersToSync(\n category: string,\n catConfig: SkillEntry,\n tree: GitHubTreeItem[],\n ): string[] {\n const skillFolders = new Set(\n tree\n .filter((f) => f.path.startsWith(`skills/${category}/`))\n .map((f) => f.path.split('/')[2])\n .filter(Boolean),\n );\n\n const folders = Array.from(skillFolders).filter((folder) => {\n if (catConfig.include && !catConfig.include.includes(folder))\n return false;\n if (catConfig.exclude && catConfig.exclude.includes(folder)) return false;\n return true;\n });\n\n if (catConfig.include) {\n catConfig.include\n .filter((i) => i.includes('/'))\n .forEach((absSkill) =>\n this.expandAbsoluteInclude(absSkill, folders, tree),\n );\n }\n\n return folders;\n }\n\n private expandAbsoluteInclude(\n absSkill: string,\n folders: string[],\n tree: GitHubTreeItem[],\n ) {\n const [targetCat, targetSkill] = absSkill.split('/');\n if (!targetCat || !targetSkill) return;\n\n if (targetSkill === '*') {\n const catSkills = new Set(\n tree\n .filter((f) => f.path.startsWith(`skills/${targetCat}/`))\n .map((f) => f.path.split('/')[2])\n .filter(Boolean),\n );\n\n catSkills.forEach((s) => {\n const fullPath = `${targetCat}/${s}`;\n if (!folders.includes(fullPath)) folders.push(fullPath);\n });\n } else if (!folders.includes(absSkill)) {\n if (\n tree.some((f) =>\n f.path.startsWith(`skills/${targetCat}/${targetSkill}/`),\n )\n ) {\n folders.push(absSkill);\n } else {\n console.log(\n pc.yellow(\n ` ā ļø Absolute include ${absSkill} not found in repository.`,\n ),\n );\n }\n }\n }\n\n private transformSkillForKiro(content: string, category: string): string {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) return content;\n\n const [fullMatch, frontmatter] = frontmatterMatch;\n const body = content.slice(fullMatch.length);\n\n const name = frontmatter.match(/^name:\\s*(.+)$/m)?.[1].trim() || '';\n const description =\n frontmatter.match(/^description:\\s*(.+)$/m)?.[1].trim() || '';\n const displayName = `${category.charAt(0).toUpperCase() + category.slice(1)} - ${name}`;\n\n return `---\\nname: ${displayName}\\ndescription: ${description}\\n---` + body;\n }\n\n private isOverridden(targetPath: string, overrides: string[]): boolean {\n const rel = this.normalizePath(targetPath);\n return overrides.some((o) => {\n const op = o.replace(/\\\\/g, '/').replace(/\\/$/, '');\n return (\n rel === op ||\n rel.startsWith(`${op}/`) ||\n rel.includes(`/${op}/`) ||\n rel.endsWith(`/${op}`)\n );\n });\n }\n\n private isPathSafe(targetPath: string, skillPath: string): boolean {\n const resolvedBase = path.resolve(skillPath) + path.sep;\n return path.resolve(targetPath).startsWith(resolvedBase);\n }\n\n private normalizePath(p: string): string {\n return path.relative(process.cwd(), p).replace(/\\\\/g, '/');\n }\n}\n","import { WorkflowFormat } from '../../constants';\n\ninterface WorkflowSource {\n /** Original filename (e.g., 'code-review.md') */\n name: string;\n /** Raw markdown content from .agents/workflows/ */\n content: string;\n}\n\nexport interface ParsedWorkflow {\n /** Workflow key without extension (e.g., 'code-review') */\n key: string;\n /** Original filename with extension (e.g., 'code-review.md') */\n fileName: string;\n /** Description parsed from frontmatter if present */\n description: string;\n /** Workflow markdown body (frontmatter removed) */\n body: string;\n /** Original raw workflow markdown content */\n rawContent: string;\n}\n\ninterface TransformedWorkflow {\n /** Target filename for the agent */\n name: string;\n /** Transformed content in the agent's native format */\n content: string;\n}\n\n/**\n * Transforms workflow markdown into each agent's native user-invoked command format.\n *\n * Workflows are NOT rules or agents ā they are multi-step procedures the user\n * explicitly invokes (e.g., \"run code-review\"). Each agent has a different mechanism:\n *\n * - native: Keep as-is in .agents/workflows/ (Antigravity, Kiro)\n * - command: Claude Code custom slash command (.claude/commands/*.md)\n * User invokes via /command-name. Supports $ARGUMENTS for parameters.\n * - toml: Gemini CLI command file (.gemini/commands/*.toml)\n * Points to the .agents/workflows/ source via a prompt field.\n * - prompt: Copilot reusable prompt file (.github/prompts/*.prompt.md)\n * User invokes via /prompt-name in Copilot chat.\n * - none: Agent has no verified user-invoked command system ā skip.\n */\nexport class WorkflowTransformer {\n static parse(source: WorkflowSource): ParsedWorkflow {\n const { description, body } = this.parseSource(source.content);\n const key = source.name.replace(/\\.md$/, '');\n return {\n key,\n fileName: source.name,\n description,\n body,\n rawContent: source.content,\n };\n }\n\n static transform(\n source: WorkflowSource,\n format: WorkflowFormat,\n workflowSourcePath: string = '.agents/workflows',\n ): TransformedWorkflow | null {\n const parsed = this.parse(source);\n return this.transformParsed(parsed, format, workflowSourcePath);\n }\n\n static transformParsed(\n parsed: ParsedWorkflow,\n format: WorkflowFormat,\n workflowSourcePath: string = '.agents/workflows',\n ): TransformedWorkflow | null {\n if (format === 'none') return null;\n\n const { description, body } = parsed;\n const baseName = parsed.key;\n\n switch (format) {\n case 'native':\n return { name: parsed.fileName, content: parsed.rawContent };\n\n case 'command':\n return {\n name: `${baseName}.md`,\n content: this.toMarkdownCommand(baseName, description, body),\n };\n\n case 'toml':\n return {\n name: `${baseName}.toml`,\n content: this.toGeminiCommand(\n baseName,\n description,\n workflowSourcePath,\n ),\n };\n\n case 'prompt':\n return {\n name: `${baseName}.prompt.md`,\n content: this.toCopilotPrompt(description, body),\n };\n\n case 'skill':\n return {\n name: 'SKILL.md',\n content: this.toSkillMarkdown(baseName, description, body),\n };\n }\n }\n\n private static parseSource(content: string): {\n description: string;\n body: string;\n } {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!match) return { description: '', body: content };\n\n const descMatch = match[1].match(/description:\\s*(.+)/);\n return {\n description: descMatch ? descMatch[1].trim() : '',\n body: match[2],\n };\n }\n\n /**\n * Markdown-based custom slash command format.\n * Used by Claude Code (.claude/commands/), Roo Code (.roo/commands/), and OpenCode (.opencode/commands/).\n * User invokes via /<name> [arguments]\n * Use $ARGUMENTS as a universal placeholder for user input instructions.\n */\n private static toMarkdownCommand(\n name: string,\n description: string,\n body: string,\n ): string {\n const title = name\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n\n return `# ${title}\n\n${description}\n\n**Input:** $ARGUMENTS\n\n## Instructions\n\nExecute the following steps for **$ARGUMENTS**.\n\n${body}`;\n }\n\n /**\n * Gemini CLI TOML command format.\n * Lives at .gemini/commands/<name>.toml\n * References the workflow source file via prompt.\n * User invokes via /<name> [arguments]\n */\n private static toGeminiCommand(\n name: string,\n description: string,\n workflowSourcePath: string,\n ): string {\n const escapedDescription = description\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"');\n return `description = \"${escapedDescription}\"\nprompt = \"\"\"\nPlease execute the workflow defined in \\`${workflowSourcePath}/${name}.md\\` for: {{args}}\n\nFollow the exact steps in the workflow file.\n\"\"\"\n`;\n }\n\n /**\n * GitHub Copilot reusable prompt format.\n * Lives at .github/prompts/<name>.prompt.md\n * User invokes via /prompt-name in Copilot chat.\n */\n private static toCopilotPrompt(description: string, body: string): string {\n return `---\\ndescription: \"${description}\"\\n---\\n${body}`;\n }\n\n /**\n * Agent Skill (SKILL.md) format.\n * Used by Cursor, Trae, and Codex.\n * Lives at <workflowPath>/<name>/SKILL.md\n * Invoked through each platform's skill mechanism.\n */\n private static toSkillMarkdown(\n name: string,\n description: string,\n body: string,\n ): string {\n const normalizedDescription =\n description || `Workflow skill for ${name.replace(/-/g, ' ')}.`;\n const escapedDescription = normalizedDescription\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"');\n const title = name\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n\n return `---\nname: ${name}\ndescription: \"${escapedDescription}\"\nmetadata:\n triggers:\n keywords:\n - ${name.replace(/-/g, ' ')}\n - workflow\n---\n# ${title} Skill\n\n> [!IMPORTANT]\n> ${normalizedDescription}\n\n## Instructions\n\nWhen the user asks to perform this workflow, execute the following steps:\n\n${body}\n`;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, DEFAULT_WORKFLOWS, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { GithubService } from './GithubService';\nimport { WorkflowTransformer } from './utils/WorkflowTransformer';\n\n/**\n * Service responsible for synchronizing agent workflows from a remote registry.\n */\nexport class WorkflowSyncService {\n constructor(private githubService: GithubService) {}\n\n /**\n * Reconciles workflows by discovering new ones in the registry and adding them to the config.\n */\n async reconcileWorkflows(config: SkillConfig): Promise<boolean> {\n if (config.workflows === false) return false;\n\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return false;\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) return false;\n\n const availableWorkflows = treeData.tree\n .filter(\n (f) =>\n f.path.startsWith('.agents/workflows/') && f.path.endsWith('.md'),\n )\n .map((f) => path.basename(f.path, '.md'));\n\n if (availableWorkflows.length === 0) return false;\n\n let changed = false;\n\n if (Array.isArray(config.workflows)) {\n const currentWorkflows = config.workflows as string[];\n const newWorkflows = availableWorkflows.filter(\n (wf) =>\n !currentWorkflows.includes(wf) && DEFAULT_WORKFLOWS.includes(wf),\n );\n\n if (newWorkflows.length > 0) {\n config.workflows = [...currentWorkflows, ...newWorkflows];\n console.log(\n pc.yellow(\n `⨠Workflows Discovered: Adding [${newWorkflows.join(', ')}] to .skillsrc.`,\n ),\n );\n changed = true;\n }\n } else if (config.workflows === undefined) {\n const defaultWorkflows = availableWorkflows.filter((wf) =>\n DEFAULT_WORKFLOWS.includes(wf),\n );\n config.workflows = defaultWorkflows;\n console.log(\n pc.yellow(\n `⨠Workflows Initialized: Adding [${defaultWorkflows.join(', ')}] to .skillsrc.`,\n ),\n );\n changed = true;\n } else if (config.workflows === true) {\n // If it's true, we keep it true to sync everything from the registry.\n // We don't overwrite it with the default list.\n const newWorkflows = availableWorkflows.filter(\n (wf) => !DEFAULT_WORKFLOWS.includes(wf),\n );\n if (newWorkflows.length > 0) {\n console.log(\n pc.cyan(\n `ā¹ļø Registry has ${availableWorkflows.length} workflows (including ${newWorkflows.length} non-default). Syncing all because 'workflows: true' is set.`,\n ),\n );\n }\n }\n\n return changed;\n }\n\n /**\n * Assembles workflows from the remote registry.\n */\n async assembleWorkflows(config: SkillConfig): Promise<CollectedSkill[]> {\n if (!config.workflows) return [];\n\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return [];\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n\n console.log(pc.gray(` - Discovering workflows (${ref})...`));\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) {\n console.log(pc.red(` ā Failed to fetch workflows@${ref}.`));\n return [];\n }\n\n const workflowFiles = treeData.tree.filter((f) => {\n if (!f.path.startsWith('.agents/workflows/') || !f.path.endsWith('.md'))\n return false;\n\n if (typeof config.workflows === 'boolean') return config.workflows;\n if (Array.isArray(config.workflows)) {\n return config.workflows.includes(path.basename(f.path, '.md'));\n }\n return false;\n });\n\n const files = await this.githubService.downloadFilesConcurrent(\n workflowFiles.map((f) => ({ owner, repo, ref, path: f.path })),\n );\n\n if (files.length > 0) {\n console.log(pc.gray(` + Fetched ${files.length} workflows`));\n return [\n {\n category: '.agents',\n skill: 'workflows',\n files: files.map((f) => ({\n name: path.basename(f.path),\n content: f.content,\n })),\n },\n ];\n } else {\n if (workflowFiles.length > 0) {\n console.log(\n pc.red(\n ` ā Failed to download ${workflowFiles.length} matched workflows.`,\n ),\n );\n } else {\n console.log(\n pc.gray(` ā¹ļø No matching workflows found in registry.`),\n );\n }\n }\n\n return [];\n }\n\n /**\n * Writes collected workflows from `.agents/workflows/*.md` to each active\n * agent's native invocation surface.\n * - Antigravity/Kiro: keep native markdown workflows\n * - Claude/Roo/OpenCode: markdown command files\n * - Gemini: TOML command files\n * - Copilot: prompt files\n * - Cursor/Trae/Codex: skill folders with SKILL.md\n */\n async writeWorkflows(\n workflows: CollectedSkill[],\n config: SkillConfig,\n agents?: Agent[],\n ) {\n if (workflows.length === 0) return;\n\n const overrides = config.custom_overrides || [];\n const targetAgents = agents || [Agent.Antigravity];\n\n for (const agentId of targetAgents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || agentDef.workflowFormat === 'none') continue;\n\n const workflowDir = path.join(process.cwd(), agentDef.workflowPath);\n await fs.ensureDir(workflowDir);\n\n // Calculate relative path from workflow dir to the source workflow files (.agents/workflows)\n // This is used by Gemini (TOML) to reference the canonical markdown source.\n const sourceWorkflowDir = path.join(process.cwd(), '.agents/workflows');\n const workflowSourceRelative = path.relative(\n workflowDir,\n sourceWorkflowDir,\n );\n\n let written = 0;\n for (const wf of workflows) {\n if (wf.skill !== 'workflows') continue;\n\n for (const fileItem of wf.files) {\n const parsed = WorkflowTransformer.parse({\n name: fileItem.name,\n content: fileItem.content,\n });\n const transformed = WorkflowTransformer.transformParsed(\n parsed,\n agentDef.workflowFormat,\n workflowSourceRelative,\n );\n if (!transformed) continue;\n\n let targetFilePath: string;\n if (agentDef.workflowFormat === 'skill') {\n const workflowName = fileItem.name.replace(/\\.md$/, '');\n targetFilePath = path.join(\n workflowDir,\n workflowName,\n transformed.name,\n );\n } else {\n targetFilePath = path.join(workflowDir, transformed.name);\n }\n\n if (!this.isPathSafe(targetFilePath, workflowDir)) {\n console.log(\n pc.red(` ā Security Error: Invalid path ${targetFilePath}`),\n );\n continue;\n }\n\n if (this.isOverridden(targetFilePath, overrides)) {\n continue;\n }\n\n await fs.outputFile(targetFilePath, transformed.content);\n written++;\n }\n }\n\n if (written > 0) {\n console.log(\n pc.green(\n ` ā
${written} workflows synced to ${agentDef.workflowPath}/ (${agentDef.name})`,\n ),\n );\n }\n }\n }\n\n private isPathSafe(targetPath: string, subPath: string): boolean {\n const resolvedBase = path.resolve(subPath) + path.sep;\n return path.resolve(targetPath).startsWith(resolvedBase);\n }\n\n private isOverridden(targetPath: string, overrides: string[]): boolean {\n const rel = this.normalizePath(targetPath);\n return overrides.some((o) => {\n const op = o.replace(/\\\\/g, '/').replace(/\\/$/, '');\n return (\n rel === op ||\n rel.startsWith(`${op}/`) ||\n rel.includes(`/${op}/`) ||\n rel.endsWith(`/${op}`)\n );\n });\n }\n\n private normalizePath(p: string): string {\n return path.relative(process.cwd(), p).replace(/\\\\/g, '/');\n }\n}\n","import yaml from 'js-yaml';\nimport { Agent, getAgentDefinition } from '../../constants';\n\ninterface SpecialistSource {\n name: string;\n content: string;\n}\n\ninterface TransformedSpecialist {\n name: string;\n content: string;\n}\n\n/**\n * Transforms specialist skill markdown into platform-specific agent personas.\n */\nexport class SpecialistTransformer {\n static transform(\n source: SpecialistSource,\n agentId: Agent,\n ): TransformedSpecialist | null {\n const agentDef = getAgentDefinition(agentId);\n if (!agentDef) return null;\n\n const parts = source.content.split('---');\n if (parts.length < 3) return null;\n\n const metadata = yaml.load(parts[1]) as Record<string, unknown>;\n const body = parts.slice(2).join('---').trim();\n const baseName = source.name.replace(/^specialist-/, '');\n const fullName = source.name;\n\n const description =\n metadata.description || `Specialist persona for ${baseName}`;\n\n switch (agentId) {\n case Agent.Claude:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\n---\\n\\n${body}`,\n };\n\n case Agent.Cursor:\n return {\n name: `${fullName}.mdc`,\n content: `---\\ndescription: ${description}\\nglobs: [\"**/*\"]\\n---\\n# Specialist: ${baseName}\\n\\n${body}`,\n };\n\n case Agent.Copilot:\n return {\n name: `${fullName}.instructions.md`,\n content: `---\\ndescription: \"${description}\"\\napplyTo: \"**/*\"\\n---\\n\\n${body}`,\n };\n\n case Agent.OpenCode:\n return {\n name: `${baseName}.md`,\n content: `---\\ndescription: \"${description}\"\\nmode: subagent\\n---\\n\\n${body}`,\n };\n\n case Agent.Gemini:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\nkind: local\\n---\\n\\n${body}`,\n };\n\n case Agent.Kiro:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\n---\\n\\n${body}`,\n };\n\n case Agent.Codex: // Codex\n return {\n name: `${baseName}.toml`,\n content: `name = \"${baseName}\"\\ndescription = \"${description}\"\\nsandbox_mode = \"read-only\"\\ndeveloper_instructions = \"\"\"\\n${body}\\n\"\"\"`,\n };\n\n default:\n return {\n name: `${baseName}${agentDef.ruleExtension || '.md'}`,\n content: body,\n };\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { GithubService } from './GithubService';\nimport { SpecialistTransformer } from './utils/SpecialistTransformer';\n\n/**\n * Service responsible for syncing specialist skills from the internal registry\n * to native agent configuration directories.\n */\nexport class SpecialistSyncService {\n constructor(\n private githubService = new GithubService(process.env.GITHUB_TOKEN),\n ) {}\n\n async assembleSpecialists(config: SkillConfig): Promise<CollectedSkill[]> {\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return [];\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) return [];\n\n const skillFiles = treeData.tree.filter(\n (item) =>\n item.type === 'blob' &&\n item.path.startsWith('skills/specialists/') &&\n item.path.endsWith('/SKILL.md'),\n );\n\n const specialists: CollectedSkill[] = [];\n for (const file of skillFiles) {\n const parts = file.path.split('/');\n const specialistName = parts[2];\n if (!specialistName) continue;\n\n const content = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n file.path,\n );\n if (!content) continue;\n\n specialists.push({\n category: 'specialists',\n skill: specialistName,\n files: [{ name: 'SKILL.md', content }],\n });\n }\n\n return specialists;\n }\n\n async syncCollectedSpecialists(\n rootDir: string,\n agents: Agent[],\n specialists: CollectedSkill[],\n ): Promise<void> {\n if (specialists.length === 0) return;\n\n for (const agentId of agents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || !agentDef.agentPath) continue;\n\n const targetDir = path.join(rootDir, agentDef.agentPath);\n await fs.ensureDir(targetDir);\n\n let syncedCount = 0;\n for (const specialist of specialists) {\n const skillFile = specialist.files.find(\n (file) => file.name === 'SKILL.md',\n );\n if (!skillFile) continue;\n\n const transformed = SpecialistTransformer.transform(\n { name: specialist.skill, content: skillFile.content },\n agentId,\n );\n if (!transformed) continue;\n\n await fs.outputFile(\n path.join(targetDir, transformed.name),\n transformed.content,\n );\n syncedCount++;\n }\n\n if (syncedCount > 0) {\n console.log(\n pc.green(\n ` ā
${syncedCount} specialists synced to ${agentDef.agentPath}/ (${agentDef.name})`,\n ),\n );\n }\n }\n }\n\n /**\n * Syncs all specialists from a source directory to active agents.\n * @param rootDir Project root directory\n * @param agents List of agents to sync for\n * @param sourceDir Optional custom source directory for specialists\n */\n async syncSpecialists(\n rootDir: string,\n agents: Agent[],\n sourceDir?: string,\n ): Promise<void> {\n const specialistsDir =\n sourceDir || path.join(rootDir, 'skills/specialists');\n if (!(await fs.pathExists(specialistsDir))) return;\n\n const specialistFolders = (await fs.readdir(specialistsDir)).filter((f) => {\n return fs.statSync(path.join(specialistsDir, f)).isDirectory();\n });\n\n const collected: CollectedSkill[] = [];\n for (const folder of specialistFolders) {\n const skillPath = path.join(specialistsDir, folder, 'SKILL.md');\n if (!(await fs.pathExists(skillPath))) continue;\n\n const content = await fs.readFile(skillPath, 'utf8');\n collected.push({\n category: 'specialists',\n skill: folder,\n files: [{ name: 'SKILL.md', content }],\n });\n }\n\n return this.syncCollectedSpecialists(rootDir, agents, collected);\n }\n}\n","import { execFileSync, execSync } from 'child_process';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Service for handling Git operations within the project.\n * Provides a clean interface for querying changed and untracked files.\n */\nexport class GitService {\n /**\n * Finds the root of the project by looking for .git or pnpm-workspace.yaml.\n */\n findProjectRoot(startDir: string = process.cwd()): string {\n let currentDir = startDir;\n while (currentDir !== path.parse(currentDir).root) {\n if (\n fs.existsSync(path.join(currentDir, 'pnpm-workspace.yaml')) ||\n fs.existsSync(path.join(currentDir, '.git'))\n ) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return startDir;\n }\n\n /**\n * Retrieves a list of files that have changed compared to the base branch or HEAD.\n * Handles both CI (GitHub Actions) and local development environments.\n * @param rootDir The root directory of the repository\n * @returns Array of relative file paths\n */\n getChangedFiles(rootDir: string): string[] {\n try {\n if (process.env.GITHUB_BASE_REF) {\n // CI environment: Compare against the base branch.\n // Validate GITHUB_BASE_REF against safe branch-name characters to prevent\n // shell command injection (OWASP A03) before interpolating into git args.\n const baseRef = process.env.GITHUB_BASE_REF;\n if (!/^[\\w./:-]+$/.test(baseRef)) {\n if (process.env.DEBUG) {\n console.warn(\n 'GITHUB_BASE_REF contains unsafe characters; skipping CI diff.',\n );\n }\n return [];\n }\n try {\n execFileSync('git', ['fetch', 'origin', baseRef, '--depth=1'], {\n cwd: rootDir,\n stdio: 'ignore',\n });\n } catch {\n // Ignore fetch failures\n }\n const output = execFileSync(\n 'git',\n ['diff', '--name-only', `origin/${baseRef}...HEAD`],\n { cwd: rootDir, encoding: 'utf8' },\n );\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n } else {\n // Local environment: Compare against HEAD\n const output = execSync('git diff --name-only HEAD', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn('Git failure while getting changed files:', error);\n }\n return [];\n }\n }\n\n /**\n * Retrieves a list of untracked files in the repository.\n * @param rootDir The root directory of the repository\n * @returns Array of relative file paths\n */\n getUntrackedFiles(rootDir: string): string[] {\n try {\n const output = execSync('git ls-files --others --exclude-standard', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn('Git failure while getting untracked files:', error);\n }\n return [];\n }\n }\n\n /**\n * Retrieves the URL of the 'origin' remote.\n * @param rootDir The root directory of the repository\n */\n getRemoteUrl(rootDir: string): string | null {\n try {\n const output = execSync('git remote get-url origin', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output.trim();\n } catch {\n return null;\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Utility functions for manipulating markdown content\n */\nexport class MarkdownUtils {\n /**\n * Injects the generated index into target documentation files (e.g., AGENTS.md).\n * It uses HTML comments as markers for safe injection and replacement.\n * @param rootDir Project root directory\n * @param targets Array of target file names\n * @param indexContent The markdown content to inject\n */\n static async injectIndex(\n rootDir: string,\n targets: string[],\n indexContent: string,\n ): Promise<void> {\n for (const target of targets) {\n const targetPath = path.join(rootDir, target);\n let content = '';\n\n if (await fs.pathExists(targetPath)) {\n content = await fs.readFile(targetPath, 'utf8');\n const markerStart = '<!-- SKILLS_INDEX_START -->';\n const markerEnd = '<!-- SKILLS_INDEX_END -->';\n\n const startIndex = content.indexOf(markerStart);\n const endIndex = content.indexOf(markerEnd);\n\n if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {\n // Both markers exist and are in the correct order\n const preMarker = content.substring(\n 0,\n startIndex + markerStart.length,\n );\n const postMarker = content.substring(endIndex);\n content = `${preMarker}\\n${indexContent}\\n${postMarker}`;\n } else if (startIndex !== -1 || endIndex !== -1) {\n // One of the markers is missing or they are out of order\n content = content.replace(markerStart, '').replace(markerEnd, '');\n content =\n content.trimEnd() +\n `\\n\\n${markerStart}\\n${indexContent}\\n${markerEnd}\\n`;\n } else {\n // No markers found\n content =\n content.trimEnd() +\n `\\n\\n${markerStart}\\n${indexContent}\\n${markerEnd}\\n`;\n }\n } else {\n content = `<!-- SKILLS_INDEX_START -->\\n${indexContent}\\n<!-- SKILLS_INDEX_END -->\\n`;\n }\n\n await fs.outputFile(targetPath, content);\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { AgentBridgeService } from './AgentBridgeService';\nimport { ConfigService } from './ConfigService';\nimport { DetectionService } from './DetectionService';\nimport { GithubService } from './GithubService';\nimport { IndexGeneratorServiceImpl } from './IndexGeneratorServiceImpl';\nimport { SkillSyncService } from './SkillSyncService';\nimport { WorkflowSyncService } from './WorkflowSyncService';\nimport { SpecialistSyncService } from './SpecialistSyncService';\nimport { GitService } from './GitService';\nimport { MarkdownUtils } from './utils/MarkdownUtils';\n\n/**\n * Service responsible for coordinating the synchronization of agent skills and workflows.\n * It acts as a facade, delegating specialized synchronization tasks to SkillSyncService\n * and WorkflowSyncService.\n */\nexport class SyncService {\n private configService = new ConfigService();\n private detectionService = new DetectionService();\n private githubService = new GithubService(process.env.GITHUB_TOKEN);\n private skillSyncService = new SkillSyncService(this.githubService);\n private workflowSyncService = new WorkflowSyncService(this.githubService);\n private specialistSyncService = new SpecialistSyncService();\n private gitService = new GitService();\n\n async reconcileConfig(\n config: SkillConfig,\n projectDeps: Set<string>,\n ): Promise<boolean> {\n const reenabled = this.configService.reconcileDependencies(\n config,\n projectDeps,\n );\n if (reenabled.length > 0) {\n console.log(pc.cyan('\\nš Dependencies changed, re-enabling skills:'));\n for (const skill of reenabled) {\n console.log(pc.gray(` - ${skill}`));\n }\n return true;\n }\n return false;\n }\n\n async reconcileWorkflows(config: SkillConfig): Promise<boolean> {\n return this.workflowSyncService.reconcileWorkflows(config);\n }\n\n async assembleSkills(\n categories: string[],\n config: SkillConfig,\n ): Promise<CollectedSkill[]> {\n await this.warnIfSyncingFromSameRepo(config);\n const skillCategories = categories.filter(\n (category) => category !== 'specialists',\n );\n return this.skillSyncService.assembleSkills(skillCategories, config);\n }\n\n private async warnIfSyncingFromSameRepo(config: SkillConfig) {\n const remoteUrl = this.gitService.getRemoteUrl(process.cwd());\n if (!remoteUrl) return;\n\n const remoteMatch = GithubService.parseGitHubUrl(remoteUrl);\n const registryMatch = GithubService.parseGitHubUrl(config.registry);\n\n if (\n remoteMatch &&\n registryMatch &&\n remoteMatch.owner === registryMatch.owner &&\n remoteMatch.repo === registryMatch.repo\n ) {\n console.log(\n pc.yellow(\n `\\nā ļø Note: You are syncing from the registry repository itself (${remoteMatch.owner}/${remoteMatch.repo}).`,\n ),\n );\n console.log(\n pc.gray(\n ` 'ags sync' pulls from GitHub. If you have unpushed local changes, they will be overwritten by the remote versions.`,\n ),\n );\n }\n }\n\n async writeSkills(\n skills: CollectedSkill[],\n config: SkillConfig,\n ): Promise<void> {\n await this.cleanupOldFolders();\n const agents = await this.resolveTargetAgents(config);\n return this.skillSyncService.writeSkills(skills, config, agents);\n }\n\n async assembleWorkflows(config: SkillConfig): Promise<CollectedSkill[]> {\n return this.workflowSyncService.assembleWorkflows(config);\n }\n\n async writeWorkflows(\n workflows: CollectedSkill[],\n config: SkillConfig,\n ): Promise<void> {\n const agents = await this.resolveTargetAgents(config);\n return this.workflowSyncService.writeWorkflows(workflows, config, agents);\n }\n\n async syncSpecialists(config: SkillConfig): Promise<void> {\n const agents = await this.resolveTargetAgents(config);\n if (agents.length === 0) return;\n\n const localRegistrySource = path.join(process.cwd(), 'skills/specialists');\n if (await fs.pathExists(localRegistrySource)) {\n return this.specialistSyncService.syncSpecialists(\n process.cwd(),\n agents,\n localRegistrySource,\n );\n }\n\n const specialists =\n await this.specialistSyncService.assembleSpecialists(config);\n return this.specialistSyncService.syncCollectedSpecialists(\n process.cwd(),\n agents,\n specialists,\n );\n }\n\n async applyIndices(\n config: SkillConfig,\n targetAgents?: Agent[],\n ): Promise<void> {\n const agents = targetAgents || (await this.resolveTargetAgents(config));\n if (agents.length === 0) return;\n\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agents[0]);\n if (!agentDef) {\n console.log(\n pc.yellow(` ā ļø Agent definition not found for ${agents[0]}.`),\n );\n }\n\n try {\n const generator = new IndexGeneratorServiceImpl();\n // Use agent path if available, otherwise fallback to .cursor/skills as a reasonable default\n const baseDir = agentDef\n ? path.join(process.cwd(), agentDef.path)\n : path.join(process.cwd(), '.cursor/skills');\n\n const allowedCategories = Object.keys(config.skills || {});\n\n // Fetch metadata.json from the registry's default branch and inject it into the\n // generator in-memory. This gives assembleRouterIndex the file_routing, broad_globs,\n // and base_language_skills it needs without writing anything to disk.\n const githubMatch = config.registry\n ? GithubService.parseGitHubUrl(config.registry)\n : null;\n if (githubMatch) {\n const { owner, repo } = githubMatch;\n const repoInfo = await this.githubService.getRepoInfo(owner, repo);\n const ref = repoInfo?.default_branch || 'main';\n const metaRaw = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n 'skills/metadata.json',\n );\n if (metaRaw) {\n try {\n generator.withMetadata(JSON.parse(metaRaw));\n } catch {\n // Malformed JSON ā continue without remote metadata; router falls back to file\n }\n }\n }\n\n // Generate per-category _INDEX.md files for all target agents\n const categoryIndices = await generator.generateAllCategoryIndices(\n baseDir,\n allowedCategories,\n );\n for (const agentId of agents) {\n const def = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!def) continue;\n const agentBase = path.join(process.cwd(), def.path);\n for (const [category, indexContent] of Object.entries(\n categoryIndices as Record<string, string>,\n )) {\n const indexMdPath = path.join(agentBase, category, '_INDEX.md');\n await fs.outputFile(indexMdPath, indexContent);\n }\n }\n if (Object.keys(categoryIndices).length > 0) {\n console.log(\n pc.green(\n ` ā
Generated _INDEX.md for ${Object.keys(categoryIndices).length} categories.`,\n ),\n );\n }\n\n // Generate router-style AGENTS.md (compact, scalable). When MCP is\n // enabled in .skillsrc, the router gets a \"Runtime Enforcement via MCP\"\n // section so AI agents (and sub-agents that read AGENTS.md) are told to\n // prefer the MCP tool calls.\n const mcpEnabled = config.mcp?.enabled === true;\n const routerIndex = await generator.assembleRouterIndex(\n baseDir,\n allowedCategories,\n mcpEnabled,\n );\n await MarkdownUtils.injectIndex(\n process.cwd(),\n ['AGENTS.md'],\n routerIndex,\n );\n console.log(pc.green(' ā
AGENTS.md router index updated.'));\n\n // Apply to sub-projects if any\n const serverDir = path.join(process.cwd(), 'server');\n if (await fs.pathExists(serverDir)) {\n await MarkdownUtils.injectIndex(serverDir, ['AGENTS.md'], routerIndex);\n console.log(pc.green(' ā
server/AGENTS.md router index updated.'));\n }\n\n const bridgeService = new AgentBridgeService();\n await bridgeService.bridge(process.cwd(), agents);\n } catch (error) {\n console.log(pc.yellow(` ā ļø Failed to update index: ${error}`));\n }\n }\n\n async checkForUpdates(config: SkillConfig): Promise<Record<string, string>> {\n const { owner, repo } = GithubService.parseGitHubUrl(config.registry) || {};\n if (!owner || !repo) return {};\n\n const info = await this.githubService.getRepoInfo(owner, repo);\n const ref = info?.default_branch || 'main';\n\n const metadataRaw = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n 'skills/metadata.json',\n );\n if (!metadataRaw) return {};\n\n const remoteMeta = JSON.parse(metadataRaw);\n const updates: Record<string, string> = {};\n\n for (const [cat, catConfig] of Object.entries(config.skills)) {\n const remoteMetaCat = remoteMeta.categories?.[cat];\n if (!remoteMetaCat?.version) continue;\n\n const latestRef = `${remoteMetaCat.tag_prefix || ''}${remoteMetaCat.version}`;\n if (catConfig.ref !== latestRef) {\n updates[cat] = latestRef;\n }\n }\n\n return updates;\n }\n\n public async resolveTargetAgents(config: SkillConfig): Promise<Agent[]> {\n if (config.agents && config.agents.length > 0) {\n return config.agents;\n }\n\n const detectedMap = await this.detectionService.detectAgents();\n const detected = Object.entries(detectedMap)\n .filter(([, enabled]) => enabled)\n .map(([id]) => id as Agent);\n\n if (detected.length > 0) {\n return detected;\n }\n\n // Return empty if no agents are detected and none are configured.\n // This ensures we never create \"ghost\" directories in the workspace.\n return [];\n }\n\n private async cleanupOldFolders(): Promise<void> {\n const oldPath = path.join(process.cwd(), '.agent');\n const newPath = path.join(process.cwd(), '.agents');\n\n if (await fs.pathExists(oldPath)) {\n try {\n // Merge old content into the new folder without overwriting user files.\n await fs.copy(oldPath, newPath, {\n overwrite: false,\n errorOnExist: false,\n });\n\n await fs.remove(oldPath);\n console.log(pc.gray(' - Migrated and cleaned up old .agent folder.'));\n } catch (error) {\n if (process.env.DEBUG) {\n console.debug(\n `Failed to migrate/cleanup old .agent folder: ${error}`,\n );\n }\n }\n }\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { McpScope, SkillConfig } from '../models/config';\nimport { ConfigService } from '../services/ConfigService';\nimport { DetectionService } from '../services/DetectionService';\nimport {\n McpConfigService,\n defaultMcpConfig,\n} from '../services/McpConfigService';\nimport { HookService } from '../services/HookService';\nimport { SyncService } from '../services/SyncService';\n\n/**\n * Command for synchronizing skills and workflows from the remote registry to the local workspace.\n * It handles configuration re-detection, fetching files, writing to disk, and updating indices.\n */\nexport class SyncCommand {\n private configService: ConfigService;\n private detectionService: DetectionService;\n private syncService: SyncService;\n private mcpService: McpConfigService;\n private hookService: HookService;\n\n constructor(\n configService?: ConfigService,\n detectionService?: DetectionService,\n syncService?: SyncService,\n mcpService?: McpConfigService,\n hookService?: HookService,\n ) {\n this.configService = configService || new ConfigService();\n this.detectionService = detectionService || new DetectionService();\n this.syncService = syncService || new SyncService();\n this.mcpService = mcpService || new McpConfigService();\n this.hookService = hookService || new HookService();\n }\n\n /**\n * Executes the synchronization flow.\n * Reconciles dependencies, fetches skills and workflows from the registry, and updates AGENTS.md.\n */\n async run(options: { yes?: boolean; snippets?: boolean } = {}) {\n try {\n // 1. Load Config\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(pc.red('ā Error: .skillsrc not found. Run `init` first.'));\n return;\n }\n\n // 2. Dynamic Update Configuration (Re-detection)\n const projectDeps = await this.detectionService.getProjectDeps();\n const skillsChanged = await this.syncService.reconcileConfig(\n config,\n projectDeps,\n );\n const workflowsChanged =\n await this.syncService.reconcileWorkflows(config);\n\n if (skillsChanged || workflowsChanged) {\n await this.configService.saveConfig(config);\n }\n\n // 3. Check for updates\n const updates = await this.syncService.checkForUpdates(config);\n\n if (updates && Object.keys(updates).length > 0) {\n console.log(pc.yellow('\\nš New skill versions detected:'));\n for (const [cat, ref] of Object.entries(updates)) {\n console.log(\n pc.gray(` - ${cat}: ${config.skills[cat].ref} -> ${ref}`),\n );\n }\n\n let update = options.yes;\n if (update === undefined) {\n if (!process.stdin.isTTY) {\n console.log(\n pc.cyan(\n 'ā¹ļø Non-interactive environment detected. Skipping version updates. Use --yes to auto-confirm.',\n ),\n );\n update = false;\n } else {\n const answer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'update',\n message: 'Do you want to update .skillsrc with these versions?',\n default: true,\n },\n ]);\n update = answer.update;\n }\n }\n\n if (update) {\n for (const [cat, ref] of Object.entries(updates)) {\n config.skills[cat].ref = ref;\n }\n await this.configService.saveConfig(config);\n console.log(pc.green('ā
.skillsrc updated.'));\n } else {\n console.log(\n pc.cyan('ā¹ļø Skipping version updates, staying on pinned refs.'),\n );\n }\n }\n\n console.log(pc.cyan(`š Syncing skills from ${config.registry}...`));\n\n // 4. Assemble skills from remote registry\n const enabledCategories = Object.keys(config.skills);\n const skills = await this.syncService.assembleSkills(\n enabledCategories,\n config,\n );\n\n // 4b. Assemble workflows\n const workflows = await this.syncService.assembleWorkflows(config);\n\n // 5. Write skills and workflows to target\n await this.syncService.writeSkills(skills, config);\n await this.syncService.writeWorkflows(workflows, config);\n\n // 5b. Sync specialists (sub-agents)\n await this.syncService.syncSpecialists(config);\n\n // 6. Automatically apply framework-specific indices to AGENTS.md\n await this.syncService.applyIndices(config, config.agents);\n\n console.log(pc.green('ā
All skills synced successfully!'));\n\n // 7. MCP integration (consent-respecting ā see McpConfigService).\n await this.runMcpPhase(config, options);\n\n // 8. Hook installation ā always runs; idempotent.\n await this.runHookPhase(config);\n } catch (error) {\n if (error instanceof Error) {\n console.error(pc.red('ā Sync failed:'), error.message);\n } else {\n console.error(pc.red('ā Sync failed:'), String(error));\n }\n }\n }\n\n /**\n * Phase 7 ā MCP integration. Three paths:\n * A. Never prompted yet: ask once now (with full value-prop), persist decision.\n * B. Already prompted, mcp.enabled=true: dispatch install at the configured scope.\n * C. Already prompted, mcp.enabled=false: skip silently.\n *\n * In non-interactive mode (no TTY) and never-prompted: skip with a hint, do\n * not assume consent. Users can opt in later via `ags mcp enable`.\n */\n private async runMcpPhase(\n config: SkillConfig,\n options: { yes?: boolean; snippets?: boolean },\n ): Promise<void> {\n const mcp = config.mcp ? { ...config.mcp } : defaultMcpConfig();\n const agents = config.agents ?? [];\n\n const snippetOnlyOverride =\n options.snippets === true && (!mcp.enabled || mcp.scope === 'disabled');\n if (snippetOnlyOverride) {\n mcp.enabled = true;\n mcp.scope = 'snippets-only';\n mcp.snippets = true;\n } else if (options.snippets !== undefined) {\n mcp.snippets = options.snippets;\n }\n\n if (\n !snippetOnlyOverride &&\n (!mcp.prompted || (!mcp.enabled && mcp.prompted))\n ) {\n if (!process.stdin.isTTY && !options.yes) {\n if (!mcp.prompted) {\n console.log(\n pc.gray(\n '\\nā¹ļø MCP integration not yet configured. Run `ags mcp enable` (or `ags mcp scope project`) when ready.',\n ),\n );\n }\n return;\n }\n\n // If already prompted but disabled, we ask again if they want to enable it now.\n // This ensures they aren't \"stuck\" in a disabled state just because they said no once.\n // Pass true for wasDisabled only if it was already prompted AND it is currently disabled.\n const decided = await this.promptMcpConsent(\n options,\n mcp.prompted && !mcp.enabled,\n );\n config.mcp = {\n enabled: decided.enabled,\n scope: decided.enabled ? decided.scope : 'disabled',\n prompted: true,\n };\n await this.configService.saveConfig(config);\n }\n\n const finalMcp = config.mcp ? { ...config.mcp } : defaultMcpConfig();\n if (snippetOnlyOverride) {\n finalMcp.enabled = true;\n finalMcp.scope = 'snippets-only';\n finalMcp.snippets = true;\n } else if (options.snippets !== undefined) {\n finalMcp.snippets = options.snippets;\n }\n\n if (!finalMcp.enabled || finalMcp.scope === 'disabled') {\n return;\n }\n\n const userScopePrompt = options.yes\n ? async () => true\n : async (agent: Agent, file: string): Promise<boolean> => {\n const { ok } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'ok',\n message: `Write user-scope MCP config for ${pc.cyan(agent)} at ${pc.gray(file)}?`,\n default: false,\n },\n ]);\n return ok;\n };\n\n console.log(pc.cyan('\\nš Wiring MCP server...'));\n const report = await this.mcpService.install({\n rootDir: process.cwd(),\n agents,\n mcp: finalMcp,\n userScopePrompt,\n });\n\n for (const w of report.projectWrites) {\n const tag =\n w.action === 'added'\n ? pc.green(' + added ')\n : w.action === 'updated'\n ? pc.cyan(' ~ updated ')\n : pc.gray(' = up-to-date');\n console.log(`${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n for (const w of report.userWrites) {\n console.log(\n ` ${pc.green('+ wrote ')} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`,\n );\n }\n for (const d of report.declined) {\n console.log(\n ` ${pc.gray('- ')} ${d.agent.padEnd(12)} ${pc.gray(d.file)} (declined)`,\n );\n }\n if (report.snippets.length > 0) {\n console.log(\n pc.gray(\n ` ${report.snippets.length} snippet(s) written to ./mcp-config-snippets/`,\n ),\n );\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n ` (skipped ā no MCP support yet: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n }\n\n private async promptMcpConsent(\n options: {\n yes?: boolean;\n },\n wasDisabled = false,\n ): Promise<{ enabled: boolean; scope: McpScope }> {\n if (options.yes) {\n // Conservative default for --yes: opt in at project scope (the recommended choice).\n return { enabled: true, scope: 'project' };\n }\n console.log(pc.bold('\\nš MCP server setup\\n'));\n if (wasDisabled) {\n console.log(\n pc.yellow(\n 'MCP integration is currently disabled. Would you like to enable it now?',\n ),\n );\n }\n console.log(\n 'agent-skills-standard ships an optional MCP server that serves your skills',\n );\n console.log('to AI agents at runtime. Quick comparison:\\n');\n console.log(\n pc.bold(' WITHOUT MCP:') +\n ' sub-agents skip skill loading; no audit trail',\n );\n console.log(\n pc.bold(' WITH MCP: ') +\n ' every sub-agent can call load_skills_for_files; auditable\\n',\n );\n\n const decision = await inquirer.prompt<{\n enabled: boolean;\n scope: McpScope;\n }>([\n {\n type: 'confirm',\n name: 'enabled',\n message: 'Enable MCP server integration?',\n default: true,\n },\n {\n type: 'list',\n name: 'scope',\n message: 'Where should sync write MCP configs?',\n when: (a) => a.enabled === true,\n choices: [\n {\n name: 'project (recommended) ā only files inside this project',\n value: 'project',\n },\n {\n name: 'user ā also $HOME files (sync prompts each)',\n value: 'user',\n },\n {\n name: 'snippets-only ā never edits any runtime config',\n value: 'snippets-only',\n },\n ],\n default: 'project',\n },\n ]);\n return decision;\n }\n\n /**\n * Phase 8 ā Hook installation.\n * Idempotent: registers the Claude PreToolUse entry and keeps managed hook\n * files up to date. Claude's script is preserved if already customized; Kiro's\n * markdown hook is kept in sync with the embedded template.\n */\n private async runHookPhase(config: SkillConfig): Promise<void> {\n const agents = config.agents ?? [];\n if (agents.length === 0) return;\n\n const mcp = config.mcp ?? defaultMcpConfig();\n if (!mcp.enabled || mcp.scope === 'disabled') {\n await this.hookService.uninstall({ rootDir: process.cwd(), agents });\n return;\n }\n\n const report = await this.hookService.install({\n rootDir: process.cwd(),\n agents,\n });\n\n const writes = report.writes.filter((w) => w.action !== 'skipped-existing');\n if (writes.length === 0) return;\n\n console.log(pc.cyan('\\nšŖ Updating skill-loader hooks...'));\n for (const w of writes) {\n const tag =\n w.action === 'added' ? pc.green('+ added ') : pc.cyan('~ updated ');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n }\n}\n","{\n \"name\": \"agent-skills-standard\",\n \"version\": \"2.4.2\",\n \"description\": \"A CLI to manage and sync AI agent skills standard for Cursor, Claude, Copilot, Windsurf, and more.\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"agent-skills-standard\": \"dist/index.js\",\n \"ags\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"vite build\",\n \"start\": \"node dist/index.js\",\n \"dev\": \"tsx src/index.ts\",\n \"validate\": \"tsx src/index.ts validate\",\n \"validate:all\": \"tsx src/index.ts validate --all\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"lint\": \"eslint \\\"src/**/*.ts\\\" --fix\",\n \"lint:check\": \"eslint \\\"src/**/*.ts\\\"\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:cov\": \"vitest run --coverage\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"keywords\": [\n \"ai\",\n \"agent\",\n \"cursor\",\n \"claude\",\n \"copilot\",\n \"cli\",\n \"antigravity\"\n ],\n \"author\": \"Hoang Nguyen\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"commander\": \"^11.1.0\",\n \"cross-fetch\": \"^4.1.0\",\n \"dotenv\": \"^17.2.3\",\n \"fs-extra\": \"^11.2.0\",\n \"inquirer\": \"^8.2.5\",\n \"js-yaml\": \"^4.1.0\",\n \"picocolors\": \"^1.0.0\",\n \"zod\": \"^3.22.4\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"vite\": \"^7.0.0\",\n \"vitest\": \"^4.0.17\"\n }\n}\n","import { execSync } from 'child_process';\nimport pc from 'picocolors';\nimport pkg from '../../package.json';\n\n/**\n * Command for upgrading the `agent-skills-standard` CLI to the latest version.\n * It checks the latest version on npm and performs the upgrade using the detected package manager.\n */\nexport class UpgradeCommand {\n private currentVersion = pkg.version;\n\n /**\n * Executes the upgrade flow.\n * @param options Command options, including `dryRun` to check for updates without installing.\n */\n async run(options: { dryRun?: boolean }) {\n console.log(pc.cyan('š Checking for updates...'));\n\n const currentVersion = this.currentVersion;\n let latestVersion: string | null = null;\n\n try {\n latestVersion = execSync('npm view agent-skills-standard version', {\n encoding: 'utf8',\n }).trim();\n } catch {\n console.log(pc.red('ā Failed to check for updates via npm.'));\n return;\n }\n\n if (!latestVersion) {\n console.log(pc.red('ā Could not determine latest version.'));\n return;\n }\n\n // Validate semver to prevent command injection or unexpected behavior\n const semverRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$/;\n if (!semverRegex.test(latestVersion)) {\n console.log(\n pc.red(`ā Invalid version received from npm: ${latestVersion}`),\n );\n return;\n }\n\n console.log(pc.gray(` Current version: ${currentVersion}`));\n console.log(pc.gray(` Latest version: ${latestVersion}`));\n\n if (currentVersion === latestVersion) {\n console.log(pc.green('⨠You are already using the latest version!'));\n return;\n }\n\n if (options.dryRun) {\n console.log(\n pc.yellow(\n `š A new version (${latestVersion}) is available! Run without --dry-run to upgrade.`,\n ),\n );\n return;\n }\n\n const pm = this.detectPackageManager();\n const upgradeCmd = this.getUpgradeCommand(pm, latestVersion);\n\n console.log(pc.yellow(`š¦ Upgrading to v${latestVersion} using ${pm}...`));\n\n try {\n console.log(pc.gray(` Running: ${upgradeCmd}`));\n\n try {\n execSync(upgradeCmd, { stdio: 'inherit' });\n } catch {\n console.log(\n pc.yellow(\n `ā ļø Failed to install v${latestVersion}. Retrying with @latest...`,\n ),\n );\n const fallbackCmd = this.getUpgradeCommand(pm, 'latest');\n execSync(fallbackCmd, { stdio: 'inherit' });\n }\n\n // Soft Verification\n try {\n const output = execSync('ags -V', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n const lines = output.split('\\n');\n const installedVersion = lines[lines.length - 1].trim();\n\n if (installedVersion.includes(latestVersion)) {\n console.log(\n pc.green(`ā
Successfully upgraded to v${latestVersion}!`),\n );\n } else {\n console.log(\n '\\n' +\n pc.yellow(\n `ā ļø Installation complete, but 'ags -V' still reports v${installedVersion}.`,\n ),\n );\n console.log(\n pc.gray(\n ' This is common if multiple versions are installed or your shell needs a restart.',\n ),\n );\n console.log(\n pc.cyan(\n `š Recommendation: Restart your terminal or run: ${pc.bold(this.getUpgradeCommand(pm, latestVersion) + ' --force')}`,\n ),\n );\n }\n } catch {\n console.log(pc.green('\\nā
Upgrade command finished.'));\n console.log(\n pc.gray(\n \" (Unable to verify version automatically, please check with 'ags -V')\",\n ),\n );\n }\n\n console.log(\n pc.cyan(\n '\\nNote: You may need to restart your terminal session for changes to take effect.',\n ),\n );\n } catch {\n console.log('\\n' + pc.red('ā Automatic upgrade failed.'));\n this.printManualInstructions(pm, latestVersion);\n }\n }\n\n private detectPackageManager(): 'npm' | 'pnpm' | 'yarn' {\n const execPath = process.argv[1] || '';\n\n // 1. Check if we are running from a pnpm global bin\n if (\n execPath.includes('pnpm') ||\n (process.env.npm_config_user_agent || '').includes('pnpm')\n ) {\n return 'pnpm';\n }\n\n // 2. Check if we are running from a yarn global bin\n if (\n execPath.includes('yarn') ||\n (process.env.npm_config_user_agent || '').includes('yarn')\n ) {\n return 'yarn';\n }\n\n // 3. Check for nvm or npm paths\n if (execPath.includes('nvm') || execPath.includes('npm')) {\n return 'npm';\n }\n\n // Fallback: Check for existing binaries, but default to npm for maximum safety\n try {\n execSync('pnpm --version', { stdio: 'ignore' });\n // Only return pnpm if we're reasonably sure it's configured (avoiding PATH issues)\n if (execPath.includes('pnpm')) return 'pnpm';\n } catch {\n // pnpm not available or not configured for this path\n }\n\n return 'npm';\n }\n\n private getUpgradeCommand(\n pm: 'npm' | 'pnpm' | 'yarn',\n version: string,\n ): string {\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g agent-skills-standard@${version}`;\n case 'yarn':\n return `yarn global add agent-skills-standard@${version}`;\n default:\n // Default to npm install -g\n return `npm install -g agent-skills-standard@${version}`;\n }\n }\n\n private printManualInstructions(\n pm: 'npm' | 'pnpm' | 'yarn',\n version: string,\n ) {\n const isWindows = process.platform === 'win32';\n const sudoPrefix = isWindows ? '' : 'sudo ';\n\n console.log(pc.yellow('Possible reasons:'));\n console.log(pc.gray(' - Permission denied (requires sudo/administrator)'));\n console.log(pc.gray(' - Network connectivity issues'));\n console.log(pc.gray(` - ${pm} is not configured for global installs`));\n\n console.log(\n '\\n' + pc.cyan('š Please run the following command manually:'),\n );\n console.log(\n pc.white(\n pc.bold(` ${sudoPrefix}${this.getUpgradeCommand(pm, version)}`),\n ),\n );\n\n if (pm !== 'npm') {\n console.log(pc.gray('\\nAlternative (npm):'));\n console.log(\n pc.gray(\n ` ${sudoPrefix}npm install -g agent-skills-standard@${version}`,\n ),\n );\n }\n\n console.log(pc.gray('\\nOr run via npx (no install required):'));\n console.log(pc.gray(` npx agent-skills-standard@${version} sync`));\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { GitService } from './GitService';\n\n/**\n * Service for discovering skill files within the repository.\n * Handles recursive directory scanning and integration with Git for change detection.\n */\nexport class SkillDiscoveryService {\n private gitService = new GitService();\n\n /**\n * Finds all SKILL.md files in the repository.\n * @param skillsDir The directory to search within\n * @returns Array of absolute paths to skill files\n */\n async findAllSkills(skillsDir: string): Promise<string[]> {\n const skillFiles: string[] = [];\n\n const findRecursive = async (dir: string) => {\n try {\n const items = await fs.readdir(dir);\n\n for (const item of items) {\n const fullPath = path.join(dir, item);\n try {\n const stat = await fs.stat(fullPath);\n\n if (stat.isDirectory()) {\n await findRecursive(fullPath);\n } else if (item === 'SKILL.md') {\n skillFiles.push(fullPath);\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`Failed to stat path: ${fullPath}`, error);\n }\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`Failed to read directory: ${dir}`, error);\n }\n }\n };\n\n if (await fs.pathExists(skillsDir)) {\n await findRecursive(skillsDir);\n }\n\n return skillFiles;\n }\n\n /**\n * Finds skills that have been changed or are untracked in Git.\n * @returns Array of absolute paths to changed skill files\n */\n async findChangedSkills(): Promise<string[]> {\n const rootDir = this.gitService.findProjectRoot();\n const changedRelative = this.gitService.getChangedFiles(rootDir);\n const untrackedRelative = this.gitService.getUntrackedFiles(rootDir);\n\n const isSkillFile = (file: string) =>\n file.startsWith('skills/') && file.endsWith('SKILL.md');\n\n const allChangedAbsolute = [...changedRelative, ...untrackedRelative]\n .filter(isSkillFile)\n .map((file) => path.join(rootDir, file));\n\n // Simple deduplication\n return Array.from(new Set(allChangedAbsolute));\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { RuleResult, ValidationRule } from './types';\n\n/**\n * Enforces a maximum line count for skill files to ensure token efficiency.\n */\nexport class SizeRule implements ValidationRule {\n name = 'Size Limit';\n constructor(private maxLines: number = 100) {}\n\n async validate(content: string): Promise<RuleResult> {\n const lines = content.split('\\n');\n if (lines.length > this.maxLines) {\n return {\n passed: false,\n errors: [\n `SKILL.md too large (${lines.length} lines > ${this.maxLines} limit)`,\n ],\n warnings: [],\n };\n }\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Validates frontmatter presence and required fields.\n */\nexport class FrontmatterRule implements ValidationRule {\n name = 'Frontmatter';\n\n async validate(content: string): Promise<RuleResult> {\n const result: RuleResult = { passed: true, errors: [], warnings: [] };\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\n if (!frontmatterMatch) {\n return {\n passed: false,\n errors: ['Missing or invalid frontmatter'],\n warnings: [],\n };\n }\n\n const frontmatter = frontmatterMatch[1];\n\n if (!frontmatter.includes('name:')) {\n result.errors.push('Missing \"name\" field in frontmatter');\n result.passed = false;\n }\n\n if (!frontmatter.includes('description:')) {\n result.errors.push('Missing \"description\" field in frontmatter');\n result.passed = false;\n } else {\n const descMatch = frontmatter.match(/description:\\s*(.+)/);\n if (descMatch && descMatch[1].length > 1024) {\n result.errors.push(\n `Description too long (${descMatch[1].length} chars > 1024 limit)`,\n );\n result.passed = false;\n }\n }\n\n return result;\n }\n}\n\n/**\n * Recommends imperative mood over conversational style.\n */\nexport class InstructionsStyleRule implements ValidationRule {\n name = 'Instruction Style';\n\n async validate(content: string): Promise<RuleResult> {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n const body = frontmatterMatch ? frontmatterMatch[2] : content;\n const bodyLines = body.split('\\n');\n let isInCodeBlock = false;\n let hasConversationalStyle = false;\n\n const conversationalPatterns =\n /^(?:\\s*[-*+]\\s*|\\s*\\d+\\.\\s*)(?:you should|please|let's|we can|I recommend)/i;\n\n for (const line of bodyLines) {\n if (line.trim().startsWith('```')) {\n isInCodeBlock = !isInCodeBlock;\n continue;\n }\n if (isInCodeBlock) continue;\n\n if (conversationalPatterns.test(line)) {\n hasConversationalStyle = true;\n break;\n }\n }\n\n if (hasConversationalStyle) {\n return {\n passed: true,\n errors: [],\n warnings: [\n 'Consider using imperative mood instead of conversational style in instructions',\n ],\n };\n }\n\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Ensures the mandatory priority section is present.\n */\nexport class PriorityRule implements ValidationRule {\n name = 'Priority Section';\n\n async validate(content: string): Promise<RuleResult> {\n if (!content.includes('## **Priority:')) {\n return {\n passed: false,\n errors: ['Missing priority section'],\n warnings: [],\n };\n }\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Validates the directory structure surrounding the skill file.\n */\nexport class DirectoryStructureRule implements ValidationRule {\n name = 'Directory Structure';\n\n async validate(_content: string, filePath: string): Promise<RuleResult> {\n const result: RuleResult = { passed: true, errors: [], warnings: [] };\n const skillDir = path.dirname(filePath);\n\n // Check scripts\n const scriptsDir = path.join(skillDir, 'scripts');\n if (await fs.pathExists(scriptsDir)) {\n const scriptFiles = await fs.readdir(scriptsDir);\n for (const file of scriptFiles) {\n if (!['.py', '.js', '.ts', '.sh'].includes(path.extname(file))) {\n result.warnings.push(`Script without standard extension: ${file}`);\n }\n }\n }\n\n // Check references\n const refsDir = path.join(skillDir, 'references');\n if (await fs.pathExists(refsDir)) {\n const refFiles = await fs.readdir(refsDir);\n if (refFiles.filter((f) => f.endsWith('.md')).length === 0) {\n result.warnings.push(\n 'References directory exists but contains no .md files',\n );\n }\n }\n\n return result;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { GitService } from './GitService';\nimport { SkillDiscoveryService } from './SkillDiscoveryService';\nimport {\n DirectoryStructureRule,\n FrontmatterRule,\n InstructionsStyleRule,\n PriorityRule,\n SizeRule,\n} from './validation/rules';\nimport { ValidationRule } from './validation/types';\n\n/**\n * Result of validating a single skill file.\n */\nexport interface SkillValidationResult {\n /** Relative path to the skill file. */\n file: string;\n /** List of validation error messages. */\n errors: string[];\n /** List of validation warning messages. */\n warnings: string[];\n /** Whether the file passed all mandatory validation rules. */\n passed: boolean;\n}\n\n/**\n * Aggregated summary of all validation results.\n */\nexport interface ValidationSummary {\n /** Total number of skills validated. */\n total: number;\n /** Number of skills that passed validation. */\n passed: number;\n /** Number of skills that failed validation. */\n failed: number;\n /** Cumulative number of warnings across all skills. */\n warnings: number;\n}\n\n/**\n * Service for validating skill files (SKILL.md) and repository metadata.\n * Enforces size limits, frontmatter requirements, and imperative instruction style.\n * Uses a Rule Pattern for modular validation.\n */\nexport class SkillValidator {\n private results: SkillValidationResult[] = [];\n private skillDiscovery = new SkillDiscoveryService();\n private gitService = new GitService();\n private rules: ValidationRule[] = [\n new SizeRule(),\n new FrontmatterRule(),\n new InstructionsStyleRule(),\n new PriorityRule(),\n new DirectoryStructureRule(),\n ];\n\n /**\n * Runs the complete validation suite.\n * @param validateAll Whether to validate all skills or just changed ones\n * @returns Exit code (0 for success, 1 for failure)\n */\n async run(validateAll: boolean = false): Promise<number> {\n try {\n const summary = await this.validateAllSkills(validateAll);\n this.printSummary(summary);\n return summary.failed > 0 ? 1 : 0;\n } catch (error) {\n console.error(\n pc.red(\n `ā Validation error: ${error instanceof Error ? error.stack : error}`,\n ),\n );\n return 1;\n }\n }\n\n /**\n * Validates all identified skill files in the repository.\n * @param validateAll Whether to validate all skills or just changed ones\n * @returns Summary of validation results\n */\n async validateAllSkills(\n validateAll: boolean = false,\n ): Promise<ValidationSummary> {\n const rootDir = this.gitService.findProjectRoot();\n const skillsDir = path.join(rootDir, 'skills');\n\n if (!(await fs.pathExists(skillsDir))) {\n throw new Error(`skills/ directory not found (searched at ${skillsDir})`);\n }\n\n const skillFiles = validateAll\n ? await this.skillDiscovery.findAllSkills(skillsDir)\n : await this.skillDiscovery.findChangedSkills();\n\n console.log(\n pc.blue(\n `š Found ${skillFiles.length} ${validateAll ? '' : 'changed '}skills to validate\\n`,\n ),\n );\n\n for (const skillFile of skillFiles) {\n const result = await this.validateSkill(skillFile);\n this.results.push(result);\n\n if (result.passed) {\n console.log(pc.green(`ā
${result.file}`));\n result.warnings.forEach((warning) =>\n console.log(pc.yellow(` ā ļø ${warning}`)),\n );\n } else {\n console.log(pc.red(`ā ${result.file}`));\n result.errors.forEach((error) => console.log(pc.red(` ā ${error}`)));\n }\n }\n\n await this.validateMetadata(rootDir);\n\n return this.generateSummary();\n }\n\n private async validateSkill(\n skillFile: string,\n ): Promise<SkillValidationResult> {\n const rootDir = this.gitService.findProjectRoot();\n const result: SkillValidationResult = {\n file: path.relative(rootDir, skillFile),\n errors: [],\n warnings: [],\n passed: true,\n };\n\n try {\n const content = await fs.readFile(skillFile, 'utf8');\n\n for (const rule of this.rules) {\n const ruleResult = await rule.validate(content, skillFile);\n if (!ruleResult.passed) {\n result.passed = false;\n }\n result.errors.push(...ruleResult.errors);\n result.warnings.push(...ruleResult.warnings);\n }\n } catch (error) {\n result.errors.push(\n `Failed to read or validate file: ${error instanceof Error ? error.message : error}`,\n );\n result.passed = false;\n }\n\n return result;\n }\n\n private async validateMetadata(rootDir: string): Promise<void> {\n const metadataPath = path.join(rootDir, 'skills', 'metadata.json');\n\n try {\n if (!(await fs.pathExists(metadataPath))) {\n throw new Error('skills/metadata.json not found');\n }\n\n const metadata = await fs.readJson(metadataPath);\n if (!metadata.categories) {\n throw new Error('metadata.json missing \"categories\" field');\n }\n\n for (const [category, config] of Object.entries(metadata.categories)) {\n const catConfig = config as { version?: string; tag_prefix?: string };\n\n if (!catConfig.version || !catConfig.tag_prefix) {\n throw new Error(\n `Category \"${category}\" missing required fields (version, tag_prefix) in metadata.json`,\n );\n }\n\n console.log(\n pc.green(\n `ā
Category metadata valid: ${category} (v${catConfig.version}, ${catConfig.tag_prefix})`,\n ),\n );\n }\n } catch (error) {\n throw new Error(\n `Metadata validation failed: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n\n private generateSummary(): ValidationSummary {\n const summary: ValidationSummary = {\n total: this.results.length,\n passed: 0,\n failed: 0,\n warnings: 0,\n };\n\n for (const result of this.results) {\n if (result.passed) {\n summary.passed++;\n } else {\n summary.failed++;\n }\n summary.warnings += result.warnings.length;\n }\n\n return summary;\n }\n\n printSummary(summary: ValidationSummary): void {\n console.log('\\n' + '='.repeat(50));\n console.log(pc.blue('š VALIDATION SUMMARY'));\n console.log('='.repeat(50));\n\n console.log(pc.green(`Passed: ${summary.passed}`));\n console.log(pc.red(`Failed: ${summary.failed}`));\n\n if (summary.failed > 0) {\n console.log(\n '\\n' + pc.red('ā Validation failed! Please fix the errors above.'),\n );\n } else {\n console.log('\\n' + pc.green('ā
All skills passed validation!'));\n\n if (summary.warnings > 0) {\n console.log(\n pc.yellow(\n `ā ļø ${summary.warnings} warnings found. Consider addressing them for better token efficiency.`,\n ),\n );\n }\n }\n }\n}\n","import { SkillValidator } from '../services/SkillValidator';\n\n/**\n * Command for validating the integrity and format of skills in the local directory.\n * Useful for development and CI/CD pipelines to ensure skills follow the standard.\n */\nexport class ValidateCommand {\n /**\n * Executes the validation flow.\n * @param options Command options, including `all` to validate all skills instead of only changed ones.\n */\n async run(options: { all?: boolean } = {}) {\n const validator = new SkillValidator();\n const exitCode = await validator.run(options.all ?? false);\n process.exit(exitCode);\n }\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport dotenv from 'dotenv';\nimport { FeedbackCommand } from './commands/feedback';\nimport { HooksCommand } from './commands/hooks';\nimport { InitCommand } from './commands/init';\nimport { ListSkillsCommand } from './commands/list-skills';\nimport { McpCommand } from './commands/mcp';\nimport { SyncCommand } from './commands/sync';\nimport { UpgradeCommand } from './commands/upgrade';\nimport { ValidateCommand } from './commands/validate-skills';\n\n// Load .env from current directory (for development and other env vars)\ndotenv.config();\n\nconst program = new Command();\n\nprogram\n .name('agent-skills-standard')\n .description(\n 'A CLI to manage and sync AI agent skills for Cursor, Claude, Copilot, Windsurf, and more.',\n )\n .version('2.4.2');\n\nprogram\n .command('init')\n .description('Initialize a .skillsrc configuration file interactively')\n .action(async () => {\n const init = new InitCommand();\n await init.run();\n });\n\nprogram\n .command('sync')\n .description('Sync skills to AI Agent skill directories')\n .option(\n '-y, --yes',\n 'Automatically confirm interactive prompts (e.g. update versions)',\n )\n .option(\n '--snippets',\n 'Generate JSON config snippets in ./mcp-config-snippets/; if MCP is disabled, run snippet-only mode',\n )\n .action(async (options) => {\n const sync = new SyncCommand();\n await sync.run(options);\n });\n\nprogram\n .command('list-skills')\n .description('List available framework skills and detection status')\n .option('-f, --framework <framework>', 'The framework to list skills for')\n .action(async (options) => {\n const cmd = new ListSkillsCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('validate')\n .description('Validate skill format and token efficiency standards')\n .option('--all', 'Validate all skills instead of only changed ones')\n .action(async (options) => {\n const cmd = new ValidateCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('feedback')\n .description('Report skill improvement opportunities or AI agent mistakes')\n .option(\n '--skill <skill>',\n 'The skill ID (e.g., flutter/bloc-state-management)',\n )\n .option('--issue <issue>', 'Brief description of the issue')\n .option('--model <model>', 'AI agent model (e.g., Claude 3.5 Sonnet)')\n .option('--context <context>', 'Additional context (e.g., framework version)')\n .option('--suggestion <suggestion>', 'Suggested improvement')\n .option(\n '--skill-instruction <instruction>',\n 'Exact quote from skill that was violated (AI auto-report)',\n )\n .option(\n '--actual-action <action>',\n 'What you actually did instead of following skill (AI auto-report)',\n )\n .option(\n '--decision-reason <reason>',\n 'Why you chose this approach instead (AI auto-report)',\n )\n .option(\n '--loaded-skills <skills>',\n 'Comma-separated list of currently loaded skills (platform-provided)',\n )\n .option(\n '--root-cause <cause>',\n 'Why the violation happened: AMBIGUOUS_RULE | MISSING_COVERAGE | OUTDATED_GUIDANCE | COMPETING_RULES | PATTERN_MISMATCH',\n )\n .option('--user-intent <intent>', 'What the user was trying to achieve')\n .option(\n '--skill-gap <gap>',\n 'What change to the SKILL.md would prevent this violation next time',\n )\n .action(async (options: Record<string, string>) => {\n const cmd = new FeedbackCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('upgrade')\n .description('Upgrade the CLI to the latest version')\n .option('--dry-run', 'Check for updates without installing')\n .action(async (options) => {\n const cmd = new UpgradeCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('mcp <action> [scope]')\n .description(\n 'Manage the optional MCP server integration. Actions: status | enable | disable | scope <project|user|snippets-only|disabled> | install | uninstall | snippets',\n )\n .option(\n '--scope <scope>',\n 'Override scope for install (project|user|snippets-only|disabled)',\n )\n .option(\n '--from <from>',\n 'For uninstall: project | user | all (default: project)',\n )\n .action(\n async (\n action: string,\n positional: string | undefined,\n opts: Record<string, string>,\n ) => {\n // Allow `ags mcp scope project` (positional) AND `ags mcp scope --scope project`.\n const merged: Record<string, string> = { ...opts };\n if (positional) merged.scope = opts.scope ?? positional;\n const cmd = new McpCommand();\n await cmd.run(action, merged);\n },\n );\n\nprogram\n .command('hooks <action>')\n .description(\n 'Manage the PreToolUse skill-loader hook. Actions: status | install | uninstall',\n )\n .action(async (action: string) => {\n const cmd = new HooksCommand();\n await cmd.run(action);\n });\n\nprogram.parse();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/services/FeedbackService.ts","../src/commands/feedback.ts","../src/constants/enums.ts","../src/constants/skills.ts","../src/constants/index.ts","../src/services/ConfigService.ts","../src/services/HookService.ts","../src/commands/hooks.ts","../src/services/DetectionService.ts","../src/services/InitService.ts","../src/services/GithubService.ts","../src/services/RegistryService.ts","../src/commands/init.ts","../src/services/SkillService.ts","../src/commands/list-skills.ts","../src/services/McpConfigService.ts","../src/commands/mcp.ts","../src/services/AgentBridgeService.ts","../src/services/IndexContentBuilder.ts","../src/services/IndexGeneratorService.ts","../src/constants/security.ts","../src/services/MetadataReader.ts","../src/services/IndexGeneratorServiceImpl.ts","../src/services/SkillSyncService.ts","../src/services/utils/WorkflowTransformer.ts","../src/services/WorkflowSyncService.ts","../src/services/utils/SpecialistTransformer.ts","../src/services/SpecialistSyncService.ts","../src/services/GitService.ts","../src/services/utils/MarkdownUtils.ts","../src/services/SyncService.ts","../src/commands/sync.ts","../package.json","../src/commands/upgrade.ts","../src/services/SkillDiscoveryService.ts","../src/services/validation/rules.ts","../src/services/SkillValidator.ts","../src/commands/validate-skills.ts","../src/index.ts"],"sourcesContent":["/**\n * Structure of the feedback data payload submitted to the backend.\n * Contains both required issue details and optional context gathered by the AI.\n */\nexport interface FeedbackData {\n /** The specific skill ID that had the issue */\n skill: string;\n /** Detailed description of the problem */\n issue: string;\n\n /** Multi-line context about where the error occurred */\n context?: string;\n /** The AI model used when the issue was detected */\n model?: string;\n /** Proposed fix or improvement */\n suggestion?: string;\n\n /** Exact instruction from the skill that was misinterpreted */\n skillInstruction?: string;\n /** What the AI actually did instead of following the skill */\n actualAction?: string;\n /** Rationale for choosing the incorrect path */\n decisionReason?: string;\n\n /** List of other active skills at the time of the error */\n loadedSkills?: string;\n\n /** Why the violation happened: AMBIGUOUS_RULE | MISSING_COVERAGE | OUTDATED_GUIDANCE | COMPETING_RULES | PATTERN_MISMATCH */\n rootCause?: string;\n /** One sentence: what the user was trying to achieve */\n userIntent?: string;\n /** What change to the SKILL.md would prevent this violation next time */\n skillGap?: string;\n}\n\n/**\n * Service to handle automated feedback reporting via Proxy Backend.\n * Follows SOLID & KISS: Strictly handles API communication.\n */\nexport class FeedbackService {\n /**\n * Allowed origin prefix for the feedback API to prevent SSRF.\n * Only requests to this domain (or its subdomains) are permitted.\n */\n private static readonly ALLOWED_ORIGIN =\n 'https://agent-skills-feedback.vercel.app';\n\n /**\n * Resolves the API URL from environment variables.\n */\n getApiUrl(): string | undefined {\n return process.env.FEEDBACK_API_URL;\n }\n\n /**\n * Validates if the given URL is safe and points to the allowed feedback origin.\n * @param url The URL to validate\n * @returns boolean\n */\n private isSafeUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isHttps = parsed.protocol === 'https:';\n const isVercelHostname =\n parsed.hostname === 'agent-skills-feedback.vercel.app' ||\n parsed.hostname.endsWith('.agent-skills-feedback.vercel.app');\n\n return isHttps && isVercelHostname;\n } catch {\n return false;\n }\n }\n\n /**\n * Submits feedback data to the backend for automatic GitHub Issue creation.\n * Internal proxy handles GitHub tokens, keeping client-side logic tokenless.\n *\n * @param data The feedback payload\n * @returns boolean indicating submission success\n */\n async submit(data: FeedbackData): Promise<boolean> {\n const apiUrl = this.getApiUrl();\n\n if (!apiUrl) return false;\n\n // Validate origin to prevent SSRF/Data Exfiltration (Finding Security-NIT)\n if (!this.isSafeUrl(apiUrl)) {\n if (process.env.DEBUG) {\n console.warn(`[FeedbackService] Disallowed API URL origin: ${apiUrl}`);\n }\n return false;\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'agent-skills-standard-cli',\n },\n body: JSON.stringify(data),\n });\n\n return response.ok;\n } catch {\n return false;\n }\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { FeedbackData, FeedbackService } from '../services/FeedbackService';\n\n/**\n * Command for automated skill feedback reporting.\n * Follows KISS: Minimal user output, focusing on functional submission.\n */\nexport class FeedbackCommand {\n private feedbackService: FeedbackService;\n\n constructor(feedbackService?: FeedbackService) {\n this.feedbackService = feedbackService || new FeedbackService();\n }\n\n async run(options: {\n skill?: string;\n issue?: string;\n model?: string;\n context?: string;\n suggestion?: string;\n skillInstruction?: string;\n actualAction?: string;\n decisionReason?: string;\n loadedSkills?: string;\n rootCause?: string;\n userIntent?: string;\n skillGap?: string;\n }) {\n console.log(pc.bold(pc.blue('\\nš£ Agent Skills Feedback Reporter\\n')));\n\n let {\n skill,\n issue,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n } = options;\n\n // Interactive mode if mandatory options are missing\n if (!skill || !issue) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'skill',\n message:\n 'Which skill ID has the issue? (e.g., flutter/bloc-state-management)',\n when: !skill,\n validate: (input: string) =>\n input.trim().length > 0 || 'Skill ID is required',\n },\n {\n type: 'input',\n name: 'issue',\n message: 'What is the issue? (Brief description)',\n when: !issue,\n validate: (input: string) =>\n input.trim().length > 0 || 'Issue description is required',\n },\n {\n type: 'input',\n name: 'model',\n message: 'AI Model name (optional, e.g., Claude 3.5 Sonnet)',\n when: !model,\n },\n {\n type: 'input',\n name: 'context',\n message: 'Any extra context? (optional, e.g., framework versions)',\n when: !context,\n },\n {\n type: 'input',\n name: 'suggestion',\n message: 'Any suggested improvement? (optional)',\n when: !suggestion,\n },\n {\n type: 'input',\n name: 'skillInstruction',\n message: 'Exact quote from skill (optional)',\n when: !skillInstruction,\n },\n {\n type: 'input',\n name: 'actualAction',\n message: 'What you did instead (optional)',\n when: !actualAction,\n },\n {\n type: 'input',\n name: 'decisionReason',\n message: 'Why you chose this approach (optional)',\n when: !decisionReason,\n },\n {\n type: 'input',\n name: 'loadedSkills',\n message: 'All active skills (optional)',\n when: !loadedSkills,\n },\n {\n type: 'list',\n name: 'rootCause',\n message: 'Root cause of the violation (optional)',\n when: !rootCause,\n choices: [\n { name: 'Skip', value: '' },\n 'AMBIGUOUS_RULE',\n 'MISSING_COVERAGE',\n 'OUTDATED_GUIDANCE',\n 'COMPETING_RULES',\n 'PATTERN_MISMATCH',\n ],\n },\n {\n type: 'input',\n name: 'userIntent',\n message: 'What was the user trying to achieve? (optional)',\n when: !userIntent,\n },\n {\n type: 'input',\n name: 'skillGap',\n message: 'What change to the skill would prevent this? (optional)',\n when: !skillGap,\n },\n ]);\n\n skill = skill || (answers.skill as string);\n issue = issue || (answers.issue as string);\n model = model || (answers.model as string);\n context = context || (answers.context as string);\n suggestion = suggestion || (answers.suggestion as string);\n skillInstruction =\n skillInstruction || (answers.skillInstruction as string);\n actualAction = actualAction || (answers.actualAction as string);\n decisionReason = decisionReason || (answers.decisionReason as string);\n loadedSkills = loadedSkills || (answers.loadedSkills as string);\n rootCause = rootCause || (answers.rootCause as string) || undefined;\n userIntent = userIntent || (answers.userIntent as string);\n skillGap = skillGap || (answers.skillGap as string);\n\n await this.submit({\n skill: skill!,\n issue: issue!,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n });\n } else {\n await this.submit({\n skill,\n issue,\n model,\n context,\n suggestion,\n skillInstruction,\n actualAction,\n decisionReason,\n loadedSkills,\n rootCause,\n userIntent,\n skillGap,\n });\n }\n }\n\n private async submit(data: FeedbackData) {\n const apiUrl = this.feedbackService.getApiUrl();\n\n if (!apiUrl) {\n console.log(pc.yellow('\\nā ļø Feedback API not configured.'));\n console.log(\n pc.gray(\n 'Please set the ' +\n pc.bold('FEEDBACK_API_URL') +\n ' environment variable.',\n ),\n );\n return;\n }\n\n console.log(pc.gray(`š¤ Sending feedback to ${apiUrl}...`));\n\n const success = await this.feedbackService.submit(data);\n\n if (success) {\n console.log(pc.green('\\nā
Feedback has been sent successfully!'));\n console.log(\n pc.gray('Thank you for helping improve the Agent Skills Standard.\\n'),\n );\n } else {\n console.log(pc.red('\\nā Failed to send feedback.'));\n console.log(\n pc.gray(\n `Please check that the Feedback API is reachable: ${pc.cyan(apiUrl)}\\n`,\n ),\n );\n }\n }\n}\n","export enum Agent {\n Cursor = 'cursor',\n Trae = 'trae',\n Claude = 'claude',\n Copilot = 'copilot',\n Antigravity = 'antigravity',\n Codex = 'codex',\n OpenCode = 'opencode',\n Gemini = 'gemini',\n Roo = 'roo',\n Windsurf = 'windsurf',\n Kiro = 'kiro',\n}\n\nexport enum Framework {\n Flutter = 'flutter',\n NestJS = 'nestjs',\n Golang = 'golang',\n NextJS = 'nextjs',\n React = 'react',\n ReactNative = 'react-native',\n Angular = 'angular',\n SpringBoot = 'spring-boot',\n Android = 'android',\n iOS = 'ios',\n Laravel = 'laravel',\n}\n","import { Framework } from './enums';\n\n/**\n * SkillDetection defines how to automatically enable a skill based on project dependencies.\n */\nexport interface SkillDetection {\n /** The skill ID as defined in the registry (e.g., 'riverpod-state-management') */\n id: string;\n /** List of npm or pub packages that indicate this skill is used */\n packages: string[];\n /** Optional list of root folder/file paths (relative to cwd). If any exist, the skill is detected. */\n files?: string[];\n}\n\n/**\n * Registry of automatic skill detection rules grouped by framework.\n */\nexport const SKILL_DETECTION_REGISTRY: Record<string, SkillDetection[]> = {\n [Framework.Flutter]: [\n {\n id: 'flutter-riverpod-state-management',\n packages: ['flutter_riverpod', 'riverpod'],\n },\n {\n id: 'flutter-bloc-state-management',\n packages: ['flutter_bloc', 'bloc'],\n },\n {\n id: 'flutter-auto-route-navigation',\n packages: ['auto_route'],\n },\n {\n id: 'flutter-go-router-navigation',\n packages: ['go_router'],\n },\n {\n id: 'flutter-getx-navigation',\n packages: ['get'], // Special handling for exact match required\n },\n {\n id: 'flutter-getx-state-management',\n packages: ['get'], // Special handling for exact match required\n },\n {\n id: 'flutter-localization',\n packages: ['easy_localization'],\n },\n {\n id: 'flutter-retrofit-networking',\n packages: ['retrofit'],\n },\n {\n id: 'flutter-dependency-injection',\n packages: ['get_it', 'injectable'],\n },\n ],\n [Framework.NestJS]: [\n {\n id: 'nestjs-caching',\n packages: ['@nestjs/cache-manager', 'cache-manager'],\n },\n {\n id: 'nestjs-database',\n packages: ['@nestjs/typeorm', '@nestjs/prisma', '@nestjs/mongoose'],\n },\n {\n id: 'nestjs-security',\n packages: ['@nestjs/passport', 'passport', 'helmet'],\n },\n ],\n [Framework.Android]: [\n {\n id: 'android-compose',\n packages: ['androidx.compose.ui'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-navigation',\n packages: ['androidx.navigation:navigation-compose'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-legacy-navigation',\n packages: [\n 'androidx.navigation:navigation-fragment',\n 'androidx.navigation:navigation-ui',\n ],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-di',\n packages: ['hilt-android', 'dagger-android'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-persistence',\n packages: ['androidx.room:room-runtime'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-networking',\n packages: ['retrofit'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n {\n id: 'android-concurrency',\n packages: ['kotlinx-coroutines-android'],\n files: ['android', 'build.gradle', 'build.gradle.kts'],\n },\n ],\n [Framework.iOS]: [\n {\n id: 'ios-networking',\n packages: ['Alamofire', 'Moya'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-dependency-injection',\n packages: ['Swinject', 'Resolver'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-persistence',\n packages: ['Realm', 'CoreData', 'SQLite.swift'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-state-management',\n packages: ['ComposableArchitecture', 'CombineRuntime'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n {\n id: 'ios-ui-navigation',\n packages: ['Coordinator', 'Router'],\n files: ['ios', 'Podfile', 'Package.swift'],\n },\n ],\n [Framework.ReactNative]: [\n {\n id: 'react-native-navigation',\n packages: ['@react-navigation/native'],\n },\n {\n id: 'react-native-state-management',\n packages: ['zustand', '@reduxjs/toolkit'],\n },\n {\n id: 'react-native-deployment',\n packages: ['react-native-code-push', 'expo-updates'],\n },\n {\n id: 'react-native-security',\n packages: ['react-native-keychain', 'react-native-ssl-pinning'],\n },\n {\n id: 'react-native-performance',\n packages: ['react-native-fast-image'],\n },\n ],\n [Framework.Laravel]: [\n {\n id: 'laravel-api',\n packages: ['laravel/sanctum', 'laravel/passport'],\n },\n {\n id: 'laravel-background-processing',\n packages: ['laravel/horizon'],\n },\n {\n id: 'laravel-testing',\n packages: ['pestphp/pest', 'phpunit/phpunit'],\n },\n {\n id: 'laravel-tooling',\n packages: ['laravel/pint', 'laravel/sail'],\n },\n {\n id: 'laravel-database-expert',\n packages: ['laravel/framework'], // Always present, but used for sub-skill mapping\n },\n ],\n [Framework.NextJS]: [\n {\n id: 'nextjs-pages-router',\n packages: [],\n files: ['pages', 'src/pages'],\n },\n {\n id: 'nextjs-server-components',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-server-actions',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-data-fetching',\n packages: [],\n files: ['app', 'src/app'],\n },\n {\n id: 'nextjs-i18n',\n packages: ['next-intl', 'react-intl', 'next-translate', 'i18next'],\n files: [\n 'middleware.ts',\n 'app/[lang]',\n 'pages/[locale]',\n 'next.config.js',\n ],\n },\n ],\n [Framework.React]: [\n {\n id: 'react-styling',\n packages: ['tailwind', 'antd', 'sass', 'styled-components', 'emotion'],\n },\n {\n id: 'react-state-management',\n packages: [\n 'redux',\n '@reduxjs/toolkit',\n 'zustand',\n 'mobx',\n 'recoil',\n 'jotai',\n ],\n },\n {\n id: 'react-testing',\n packages: [\n 'jest',\n 'vitest',\n '@testing-library/react',\n 'cypress',\n 'playwright',\n ],\n },\n ],\n database: [\n {\n id: 'database-postgresql',\n packages: ['pg', 'pgx', 'postgres', 'sequelize', 'typeorm', 'prisma'],\n },\n {\n id: 'database-mongodb',\n packages: ['mongodb', 'mongoose'],\n },\n {\n id: 'database-redis',\n packages: ['redis', 'ioredis', 'predis'],\n },\n ],\n};\n","import { Agent, Framework } from './enums';\n\nexport { Agent, Framework };\n\nexport const UNIVERSAL_SKILLS = ['common'];\nexport const BACKEND_FRAMEWORKS: Framework[] = [\n Framework.NestJS,\n Framework.Golang,\n Framework.SpringBoot,\n Framework.Laravel,\n];\n\nexport const FRONTEND_FRAMEWORKS: Framework[] = [\n Framework.React,\n Framework.NextJS,\n Framework.Angular,\n];\n\nexport const MOBILE_FRAMEWORKS: Framework[] = [\n Framework.Flutter,\n Framework.Android,\n Framework.iOS,\n Framework.ReactNative,\n];\n\nexport const FRONTEND_REACT_FRAMEWORKS: Framework[] = [\n Framework.NextJS,\n Framework.ReactNative,\n];\n\n/**\n * Sub-skills to exclude from the `common` category based on the selected framework type.\n * Backend: exclude web-only and mobile-only skills.\n * Frontend: exclude backend-only and mobile-only skills.\n * Mobile: exclude web-only and backend-only skills.\n */\nexport const COMMON_SKILL_EXCLUDES: Record<\n 'backend' | 'frontend' | 'mobile',\n string[]\n> = {\n backend: [\n 'common-accessibility',\n 'common-mobile-animation',\n 'common-mobile-ux-core',\n 'common-store-changelog',\n 'common-ui-design',\n ],\n frontend: [\n 'common-observability',\n 'common-mobile-animation',\n 'common-mobile-ux-core',\n 'common-store-changelog',\n ],\n mobile: [\n 'common-accessibility',\n 'common-api-design',\n 'common-observability',\n 'common-system-design',\n ],\n};\n\n/**\n * Classifies a framework ID into its platform type for skill exclusion purposes.\n * Returns null for unknown/hybrid frameworks ā no exclusions are applied.\n */\nexport function getFrameworkType(\n framework: string,\n): 'backend' | 'frontend' | 'mobile' | null {\n if (BACKEND_FRAMEWORKS.includes(framework as Framework)) return 'backend';\n if (MOBILE_FRAMEWORKS.includes(framework as Framework)) return 'mobile';\n if (FRONTEND_FRAMEWORKS.includes(framework as Framework)) return 'frontend';\n return null;\n}\n\nexport const DEFAULT_REGISTER =\n 'https://github.com/HoangNguyen0403/agent-skills-standard';\n\nexport const DEFAULT_WORKFLOWS = [\n 'sdlc',\n 'brainstorm-feature',\n 'code-review',\n 'codebase-review',\n 'design-solution',\n 'deploy-release',\n 'plan-feature',\n 'implementation-readiness',\n 'review-ticket',\n 'traceability-audit',\n 'session-report',\n 'publish-notes',\n 'retro-learn',\n 'skill-benchmark',\n 'pentest',\n 'dev-fix',\n 'implement-feature',\n 'verify-work',\n 'verify-bug',\n 'security-test',\n];\n\n// Configurable via ENV or hardcoded for production convenience\n/**\n * Defines how workflows are delivered to each agent platform.\n * Workflows are user-invoked multi-step procedures (not passive rules).\n * - 'native': Direct markdown workflow files, executed by the agent's workflow runner (Antigravity, Kiro)\n * - 'command': Custom slash command files ā inline the procedure (Claude: .claude/commands/*.md)\n * - 'toml': TOML command files ā reference the workflow by path (Gemini: .gemini/commands/*.toml)\n * - 'prompt': Reusable prompt files (Copilot: .github/prompts/*.prompt.md)\n * - 'none': Agent has no verified user-invoked command system\n */\nexport type WorkflowFormat =\n | 'native'\n | 'command'\n | 'toml'\n | 'prompt'\n | 'skill'\n | 'none';\n\nexport interface AgentDefinition {\n id: Agent;\n name: string;\n path: string;\n ruleFile: string;\n ruleExtension: string;\n ruleFileName?: string;\n frontmatterStyle: 'cursor' | 'copilot' | 'none';\n detectionFiles: string[];\n /** How workflows should be transformed for this agent */\n workflowFormat: WorkflowFormat;\n /** Directory where transformed workflows are written (relative to cwd) */\n workflowPath: string;\n /** Directory where native specialist agent personas are written (optional) */\n agentPath?: string;\n /** Relative path to pre-edit hook reminder script (if supported) */\n hookScriptPath?: string;\n /** Relative path to hook configuration JSON file (if supported) */\n hookConfigPath?: string;\n}\n\nexport interface FrameworkDefinition {\n id: Framework;\n name: string;\n languages: string[];\n detectionFiles: string[];\n detectionDependencies?: string[];\n languageDetection?: Record<string, string[]>;\n}\n\nexport const getAgentDefinition = (id: Agent): AgentDefinition => {\n switch (id) {\n case Agent.Cursor:\n return {\n id,\n name: 'Cursor',\n path: '.cursor/skills',\n ruleFile: '.cursor/rules',\n ruleExtension: '.mdc',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.cursor', '.cursorrules'],\n workflowFormat: 'skill',\n workflowPath: '.cursor/skills',\n agentPath: '.cursor/agents',\n hookScriptPath: '.cursor/hooks/preedit-skill-loader.js',\n hookConfigPath: '.cursor/hooks.json',\n };\n case Agent.Trae:\n return {\n id,\n name: 'Trae',\n path: '.trae/skills',\n ruleFile: '.trae/rules',\n ruleExtension: '.mdc',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.trae'],\n workflowFormat: 'skill',\n workflowPath: '.trae/skills',\n };\n case Agent.Claude:\n return {\n id,\n name: 'Claude Code',\n path: '.claude/skills',\n ruleFile: '.',\n ruleExtension: '.md',\n ruleFileName: 'CLAUDE.md',\n frontmatterStyle: 'none',\n detectionFiles: ['.claude'],\n workflowFormat: 'command',\n workflowPath: '.claude/commands',\n agentPath: '.claude/agents',\n hookScriptPath: '.claude/hooks/preedit-skill-loader.js',\n hookConfigPath: '.claude/settings.json',\n };\n case Agent.Copilot:\n return {\n id,\n name: 'GitHub Copilot',\n path: '.github/skills',\n ruleFile: '.github/instructions',\n ruleExtension: '.instructions.md',\n frontmatterStyle: 'copilot',\n detectionFiles: ['.github'],\n workflowFormat: 'prompt',\n workflowPath: '.github/prompts',\n agentPath: '.github/copilot-agents',\n hookScriptPath: '.github/hooks/preedit-skill-loader.js',\n hookConfigPath: '.github/hooks.json',\n };\n case Agent.Antigravity:\n return {\n id,\n name: 'Antigravity',\n path: '.agents/skills',\n ruleFile: '.agents/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.agents'],\n workflowFormat: 'native',\n workflowPath: '.agents/workflows',\n };\n case Agent.Codex:\n return {\n id,\n name: 'Codex',\n path: '.codex/skills',\n ruleFile: '.codex/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.codex'],\n workflowFormat: 'skill',\n workflowPath: '.codex/skills',\n agentPath: '.codex/agents',\n hookScriptPath: '.codex/hooks/preedit-skill-loader.js',\n hookConfigPath: '.codex/hooks.json',\n };\n case Agent.OpenCode:\n return {\n id,\n name: 'OpenCode',\n path: '.opencode/skills',\n ruleFile: '.opencode/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.opencode'],\n workflowFormat: 'command',\n workflowPath: '.opencode/commands',\n agentPath: '.opencode/agents',\n };\n case Agent.Gemini:\n return {\n id,\n name: 'Gemini',\n path: '.gemini/skills',\n ruleFile: '.gemini/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.gemini'],\n workflowFormat: 'toml',\n workflowPath: '.gemini/commands',\n agentPath: '.gemini/agents',\n hookScriptPath: '.gemini/hooks/preedit-skill-loader.js',\n hookConfigPath: '.gemini/hooks.json',\n };\n case Agent.Roo:\n return {\n id,\n name: 'Roo Code',\n path: '.roo/skills',\n ruleFile: '.roo/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.roo'],\n workflowFormat: 'command',\n workflowPath: '.roo/commands',\n };\n case Agent.Windsurf:\n return {\n id,\n name: 'Windsurf',\n path: '.windsurf/skills',\n ruleFile: '.windsurf/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.windsurf'],\n workflowFormat: 'none',\n workflowPath: '',\n hookScriptPath: '.windsurf/hooks/preedit-skill-loader.js',\n hookConfigPath: '.windsurf/hooks.json',\n };\n case Agent.Kiro:\n return {\n id,\n name: 'Kiro',\n path: '.kiro/skills',\n ruleFile: '.kiro/rules',\n ruleExtension: '.md',\n frontmatterStyle: 'cursor',\n detectionFiles: ['.kiro'],\n workflowFormat: 'native',\n workflowPath: '.agents/workflows',\n agentPath: '.kiro/agents',\n hookScriptPath: '.kiro/hooks/ags-skill-loader.md',\n };\n }\n};\n\nexport const getFrameworkDefinition = (id: Framework): FrameworkDefinition => {\n switch (id) {\n case Framework.Flutter:\n return {\n id,\n name: 'Flutter',\n languages: ['dart'],\n detectionFiles: ['pubspec.yaml'],\n };\n case Framework.NestJS:\n return {\n id,\n name: 'NestJS',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['nest-cli.json'],\n detectionDependencies: ['@nestjs/core'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.Golang:\n return {\n id,\n name: 'Go (Golang)',\n languages: ['go'],\n detectionFiles: ['go.mod'],\n };\n case Framework.NextJS:\n return {\n id,\n name: 'Next.js',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['next.config.js', 'next.config.mjs'],\n detectionDependencies: ['next'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.React:\n return {\n id,\n name: 'React',\n languages: ['typescript', 'javascript'],\n detectionFiles: [],\n detectionDependencies: ['react', 'react-dom'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.ReactNative:\n return {\n id,\n name: 'React Native',\n languages: ['typescript', 'javascript'],\n detectionFiles: ['metro.config.js'],\n detectionDependencies: ['react-native'],\n languageDetection: {\n typescript: ['tsconfig.json'],\n javascript: ['jsconfig.json'],\n },\n };\n case Framework.Angular:\n return {\n id,\n name: 'Angular',\n languages: ['typescript'],\n detectionFiles: ['angular.json'],\n };\n case Framework.SpringBoot:\n return {\n id,\n name: 'Spring Boot',\n languages: ['java', 'kotlin'],\n detectionFiles: ['pom.xml', 'build.gradle', 'build.gradle.kts'],\n languageDetection: {\n kotlin: ['src/main/kotlin', 'build.gradle.kts'],\n java: ['src/main/java'],\n },\n };\n case Framework.Android:\n return {\n id,\n name: 'Android',\n languages: ['kotlin', 'java'],\n detectionFiles: [\n 'build.gradle',\n 'build.gradle.kts',\n 'AndroidManifest.xml',\n ],\n languageDetection: {\n kotlin: ['src/main/kotlin', 'build.gradle.kts'],\n java: ['src/main/java'],\n },\n };\n case Framework.iOS:\n return {\n id,\n name: 'iOS (Swift/SwiftUI)',\n languages: ['swift'],\n detectionFiles: [\n 'Podfile',\n 'Package.swift',\n 'project.pbxproj',\n 'Info.plist',\n ],\n languageDetection: {\n swift: ['.swift'],\n },\n };\n case Framework.Laravel:\n return {\n id,\n name: 'Laravel',\n languages: ['php', 'javascript'],\n detectionFiles: ['composer.json', 'artisan'],\n detectionDependencies: ['laravel/framework'],\n languageDetection: {\n php: ['.php'],\n javascript: ['resources/js', 'vite.config.js'],\n },\n };\n }\n};\n\nexport const SUPPORTED_AGENTS: AgentDefinition[] =\n Object.values(Agent).map(getAgentDefinition);\n\nexport const SUPPORTED_FRAMEWORKS: FrameworkDefinition[] = Object.values(\n Framework,\n).map(getFrameworkDefinition);\n\nexport { SKILL_DETECTION_REGISTRY } from './skills';\nexport type { SkillDetection } from './skills';\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport { z } from 'zod';\nimport {\n Agent,\n BACKEND_FRAMEWORKS,\n COMMON_SKILL_EXCLUDES,\n DEFAULT_REGISTER,\n Framework,\n FrameworkDefinition,\n FRONTEND_REACT_FRAMEWORKS,\n getFrameworkType,\n SKILL_DETECTION_REGISTRY,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\nimport { CategoryConfig, SkillConfig } from '../models/config';\nimport { RegistryMetadata } from '../models/types';\n\nconst McpScopeSchema = z.enum(['project', 'user', 'snippets-only', 'disabled']);\n\nconst McpConfigSchema = z.object({\n enabled: z.boolean(),\n scope: McpScopeSchema,\n prompted: z.boolean(),\n version: z.string().optional(),\n snippets: z.boolean().optional(),\n});\n\nconst SkillConfigSchema = z.object({\n registry: z.string().url(),\n agents: z.preprocess(\n (val) => {\n if (Array.isArray(val)) {\n return val.map((a) =>\n typeof a === 'string' && a.toLowerCase() === 'openai' ? 'codex' : a,\n );\n }\n return val;\n },\n z.array(z.nativeEnum(Agent)).optional(),\n ),\n skills: z.record(\n z.string(), // Category name\n z.object({\n ref: z.string().optional(),\n include: z.array(z.string()).optional(),\n exclude: z.array(z.string()).optional(),\n }),\n ),\n custom_overrides: z.array(z.string()).optional(),\n workflows: z.union([z.boolean(), z.array(z.string())]).optional(),\n mcp: McpConfigSchema.optional(),\n});\n\nconst DEFAULT_SDLC_SUPPORT_CATEGORIES = ['quality-engineering'] as const;\n\n/**\n * Service for managing the `.skillsrc` configuration file.\n * Handles loading, saving, and initial construction of the configuration based on project metadata.\n */\nexport class ConfigService {\n private getCategoryRef(\n category: string,\n metadata: Partial<RegistryMetadata>,\n ): string {\n const categoryMetadata = metadata.categories?.[category];\n if (!categoryMetadata?.version) return 'main';\n return `${categoryMetadata.tag_prefix || ''}${categoryMetadata.version}`;\n }\n\n /**\n * Loads and validates the skill configuration from the workspace.\n * @param cwd Current working directory\n * @returns The parsed SkillConfig or null if not found\n * @throws Error if the configuration format is invalid\n */\n async loadConfig(cwd: string = process.cwd()): Promise<SkillConfig | null> {\n const configPath = path.join(cwd, '.skillsrc');\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n try {\n const content = await fs.readFile(configPath, 'utf8');\n const rawConfig = yaml.load(content) as Record<string, unknown>;\n\n // Backward compatibility & self-healing migration for legacy 'openai' agent configs\n if (rawConfig && Array.isArray(rawConfig.agents)) {\n let needsMigration = false;\n const updatedAgents = rawConfig.agents.map((agent: unknown) => {\n if (typeof agent === 'string' && agent.toLowerCase() === 'openai') {\n needsMigration = true;\n return Agent.Codex;\n }\n return agent;\n });\n\n if (needsMigration) {\n rawConfig.agents = updatedAgents;\n await fs.outputFile(configPath, yaml.dump(rawConfig));\n }\n }\n\n // Validate with Zod\n const parsed = SkillConfigSchema.safeParse(rawConfig);\n\n if (!parsed.success) {\n throw new Error(`Invalid .skillsrc format: ${parsed.error.message}`);\n }\n\n return parsed.data as SkillConfig;\n } catch (error) {\n throw new Error(`Failed to load config: ${error}`);\n }\n }\n\n /**\n * Saves the provided configuration to the `.skillsrc` file.\n * @param config The configuration to save\n * @param cwd Current working directory\n */\n async saveConfig(\n config: SkillConfig,\n cwd: string = process.cwd(),\n ): Promise<void> {\n const configPath = path.join(cwd, '.skillsrc');\n await fs.outputFile(configPath, yaml.dump(config));\n }\n\n /**\n * Constructs an initial configuration object based on project analysis.\n * @param framework The primary framework detected\n * @param agents List of enabled AI agents\n * @param registry Registry URL\n * @param metadata Registry metadata for versioning and prefixes\n * @param languages Detected programming languages\n * @param workflows List of workflow names to sync\n * @returns A fresh SkillConfig object\n */\n buildInitialConfig(\n framework: string,\n agents: Agent[],\n registry: string,\n metadata: Partial<RegistryMetadata>,\n languages: string[] = [],\n workflows: string[] = [],\n ): SkillConfig {\n const skills: Record<string, CategoryConfig> = {};\n\n // Add main framework\n skills[framework] = {\n ref: metadata.categories?.[framework]?.version\n ? `${metadata.categories[framework].tag_prefix || ''}${metadata.categories[framework].version}`\n : 'main',\n };\n\n // Specialized Logic: Frontend React-based projects must inherently sync the React category natively.\n if (\n FRONTEND_REACT_FRAMEWORKS.includes(framework as Framework) &&\n metadata.categories?.['react']\n ) {\n skills['react'] = {\n ref: metadata.categories['react'].version\n ? `${metadata.categories['react'].tag_prefix || ''}${metadata.categories['react'].version}`\n : 'main',\n };\n }\n\n // Add associated languages (e.g., typescript, javascript)\n for (const lang of languages) {\n if (metadata.categories?.[lang]) {\n skills[lang] = {\n ref: `${metadata.categories[lang].tag_prefix || ''}${metadata.categories[lang].version}`,\n };\n }\n }\n\n // Add common category if available, with framework-appropriate exclusions\n if (metadata.categories?.['common']) {\n const frameworkType = getFrameworkType(framework);\n const commonExcludes = frameworkType\n ? COMMON_SKILL_EXCLUDES[frameworkType]\n : [];\n\n skills['common'] = {\n ref: `${metadata.categories['common'].tag_prefix || ''}${metadata.categories['common'].version}`,\n ...(commonExcludes.length > 0 && { exclude: commonExcludes }),\n };\n }\n\n for (const category of DEFAULT_SDLC_SUPPORT_CATEGORIES) {\n if (metadata.categories?.[category] && !skills[category]) {\n skills[category] = {\n ref: this.getCategoryRef(category, metadata),\n };\n }\n }\n\n // Add database category for backend frameworks\n if (\n BACKEND_FRAMEWORKS.includes(framework as Framework) &&\n metadata.categories?.['database']\n ) {\n skills['database'] = {\n ref: metadata.categories['database'].version\n ? `${metadata.categories['database'].tag_prefix || ''}${metadata.categories['database'].version}`\n : 'main',\n };\n }\n\n return {\n registry,\n agents,\n skills,\n custom_overrides: [],\n workflows: workflows.length > 0 ? workflows : false, // Array if specific, false if empty\n };\n }\n\n /**\n * Identifies sub-skills to exclude based on the absence of their required package dependencies.\n * Scans all categories defined in the config.\n * @param config The current configuration\n * @param projectDeps Current set of project dependencies\n */\n applyDependencyExclusions(\n config: SkillConfig,\n projectDeps: Set<string>,\n cwd: string = process.cwd(),\n ) {\n const depsArray = Array.from(projectDeps);\n\n for (const categoryId in config.skills) {\n const category = config.skills[categoryId];\n const detections = SKILL_DETECTION_REGISTRY[categoryId] || [];\n if (detections.length === 0) continue;\n\n const exclusions = new Set<string>(category.exclude || []);\n\n for (const detection of detections) {\n const hasDeps = this.hasDependency(detection.packages, depsArray);\n const hasDirs = this.hasFiles(detection.files, cwd);\n if (!hasDeps || !hasDirs) {\n exclusions.add(detection.id);\n }\n }\n\n if (exclusions.size > 0) {\n category.exclude = Array.from(exclusions);\n }\n }\n }\n\n /**\n * Automatically re-enables skills that were previously excluded if their dependencies\n * are now present in the project. Scans all categories.\n */\n reconcileDependencies(\n config: SkillConfig,\n projectDeps: Set<string>,\n cwd: string = process.cwd(),\n ): string[] {\n const totalReenabled: string[] = [];\n const allKnownCategories = Object.keys(SKILL_DETECTION_REGISTRY);\n const depsArray = Array.from(projectDeps);\n\n for (const categoryId of allKnownCategories) {\n const hasMetaFramework = Object.keys(config.skills).some((f) =>\n [Framework.Flutter, Framework.ReactNative].includes(f as Framework),\n );\n\n let category = config.skills[categoryId];\n\n // Skip platform-specific categories if a meta-framework is already present\n // unless the category is already active (we still want to reconcile its sub-skills)\n if (\n hasMetaFramework &&\n [Framework.Android, Framework.iOS].includes(categoryId as Framework)\n ) {\n if (!category) continue;\n }\n\n const detections = SKILL_DETECTION_REGISTRY[categoryId] || [];\n if (detections.length === 0) continue;\n\n const isNewCategory = !category;\n if (isNewCategory) {\n // First check if this is a supported framework and we don't have its base dependencies\n const frameworkDef = SUPPORTED_FRAMEWORKS.find(\n (f: FrameworkDefinition) => f.id === categoryId,\n );\n if (frameworkDef) {\n const hasBaseDeps =\n frameworkDef.detectionDependencies &&\n frameworkDef.detectionDependencies.length > 0\n ? this.hasDependency(\n frameworkDef.detectionDependencies,\n depsArray,\n )\n : false;\n\n const hasBaseFiles =\n frameworkDef.detectionFiles &&\n frameworkDef.detectionFiles.length > 0\n ? frameworkDef.detectionFiles.some((file) =>\n fs.existsSync(path.join(cwd, file)),\n )\n : false;\n\n if (!hasBaseDeps && !hasBaseFiles) {\n continue; // Skip enabling this category if its base framework isn't detected\n }\n }\n\n const shouldEnableCategory = detections.some(\n (detection) =>\n this.hasDependency(detection.packages, depsArray) &&\n this.hasFiles(detection.files, cwd),\n );\n\n if (shouldEnableCategory) {\n config.skills[categoryId] = { ref: 'main' };\n category = config.skills[categoryId];\n\n const exclusions = detections\n .filter(\n (d) =>\n !this.hasDependency(d.packages, depsArray) ||\n !this.hasFiles(d.files, cwd),\n )\n .map((d) => d.id);\n\n if (exclusions.length > 0) {\n category.exclude = exclusions;\n }\n totalReenabled.push(categoryId);\n }\n continue;\n }\n\n // Existing category reconciliation\n if (!category.exclude) continue;\n\n const currentExclusions = new Set(category.exclude);\n const reenabled: string[] = [];\n\n for (const detection of detections) {\n if (\n currentExclusions.has(detection.id) &&\n this.hasDependency(detection.packages, depsArray) &&\n this.hasFiles(detection.files, cwd)\n ) {\n currentExclusions.delete(detection.id);\n reenabled.push(`${categoryId}/${detection.id}`);\n }\n }\n\n if (reenabled.length > 0) {\n category.exclude =\n currentExclusions.size > 0\n ? Array.from(currentExclusions)\n : undefined;\n totalReenabled.push(...reenabled);\n }\n }\n\n return totalReenabled;\n }\n\n /**\n * Checks if ANY of the required files exist in the project directory.\n */\n private hasFiles(files: string[] | undefined, cwd: string): boolean {\n if (!files || files.length === 0) return true; // If no files required, assume condition met\n for (const file of files) {\n if (fs.existsSync(path.join(cwd, file))) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Checks if ANY of the required dependencies are found in the project.\n */\n private hasDependency(packages: string[], projectDeps: string[]): boolean {\n if (packages.length === 0) return true; // If no packages are required, condition met\n return projectDeps.some((d) =>\n packages.some((pkg) => {\n const depLower = d.toLowerCase();\n const pkgLower = pkg.toLowerCase();\n\n // Exact match\n if (depLower === pkgLower) return true;\n\n // Skip fuzzy matching for short names to avoid noise\n if (pkg.length <= 3) return false;\n\n // Handle scoped packages: @scope/package matches package\n if (depLower.includes('/') && depLower.split('/').pop() === pkgLower)\n return true;\n\n // Handle framework-prefixed packages (e.g. @nestjs/core, flask-cors)\n // Only match if the package is a standalone word in the dependency name\n const parts = depLower.split(/[-/_]/);\n return parts.includes(pkgLower);\n }),\n );\n }\n\n /**\n * Retrieves the registry URL from configuration or returns the default.\n * @param cwd Current working directory\n */\n async getRegistryUrl(cwd: string = process.cwd()): Promise<string> {\n const config = await this.loadConfig(cwd).catch(() => null);\n return config?.registry || DEFAULT_REGISTER;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { Agent, getAgentDefinition } from '../constants';\n\n// āā Embedded hook templates āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n/**\n * Universal PreToolUse hook script (Node.js / JavaScript).\n * Reminds AI agents to call load_skills_for_files() before any code edit.\n * Guaranteed to execute on any machine running agent-skills-standard.\n * Always exits 0 to never block work.\n */\nexport const UNIVERSAL_SKILL_LOADER_JS = `#!/usr/bin/env node\n/**\n * PreToolUse hook: remind AI agent to call load_skills_for_files() before any code edit.\n * Installed by agent-skills-standard (ags sync). Remove via: ags hooks uninstall\n * Guaranteed to execute on any system with Node.js. Always exits 0 to never block work.\n */\nconst fs = require('fs');\nconst path = require('path');\n\nconst REPO_ROOT = process.env.CLAUDE_PROJECT_DIR || path.resolve(__dirname, '../../');\nconst EDIT_TOOLS = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit']);\nconst SKIP_DIRS = [\n path.resolve(REPO_ROOT, '.claude'),\n path.resolve(REPO_ROOT, '.gemini'),\n path.resolve(REPO_ROOT, '.codex'),\n path.resolve(REPO_ROOT, '.github'),\n path.resolve(REPO_ROOT, '.cursor'),\n path.resolve(REPO_ROOT, '.roo'),\n path.resolve(REPO_ROOT, '.trae'),\n path.resolve(REPO_ROOT, '.opencode'),\n path.resolve(REPO_ROOT, '.kiro'),\n path.resolve(REPO_ROOT, '.windsurf'),\n path.resolve(REPO_ROOT, '.agents'),\n path.resolve(REPO_ROOT, '.vscode'),\n];\nconst SKIP_FILES = [\n path.resolve(REPO_ROOT, 'AGENTS.md'),\n path.resolve(REPO_ROOT, 'CLAUDE.md'),\n];\n\nfunction shouldSkip(filePath) {\n try {\n const real = path.resolve(filePath);\n if (SKIP_DIRS.some(d => real.startsWith(d))) return true;\n if (SKIP_FILES.includes(real)) return true;\n return false;\n } catch {\n return false;\n }\n}\n\nlet input = '';\nprocess.stdin.setEncoding('utf8');\nprocess.stdin.on('data', chunk => { input += chunk; });\nprocess.stdin.on('end', () => {\n try {\n const data = JSON.parse(input);\n if (!EDIT_TOOLS.has(data.tool_name)) process.exit(0);\n\n const filePath = data.tool_input?.file_path || '';\n if (!filePath || shouldSkip(filePath)) process.exit(0);\n\n const fileName = path.basename(filePath);\n console.log(\n '[SKILL TRIGGER] Editing: ' + fileName + '\\\\n' +\n '-> Call load_skills_for_files(files=[ \"' + filePath + '\" ]) on the ' +\n 'agent-skills-standard MCP. It returns applicable SKILL.md rules, ' +\n 'or nothing if no skills match this file type.'\n );\n process.exit(0);\n } catch {\n process.exit(0);\n }\n});\n`;\n\n/**\n * Kiro hook spec (Markdown + YAML frontmatter).\n * File-save trigger ā advisory only (cannot block edits).\n * Placed at .kiro/hooks/ags-skill-loader.md\n */\nexport const KIRO_HOOK_MD = `---\nenabled: true\nname: ags-skill-loader\ndescription: Load matching skill rules from agent-skills-standard before editing source files\ntriggers:\n - type: file_change\n fileFilter: \"**/*\"\ninstructions: |\n Before editing any source file, call load_skills_for_files(files=[<absolute_file_path>])\n on the agent-skills-standard MCP server. It returns applicable SKILL.md rules for the\n file being edited, or nothing if no skills match. Apply all returned rules strictly.\n---\n`;\n\n// āā Constants āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nconst CLAUDE_MCP_PERMISSION = 'mcp__agent-skills-standard__*';\nconst KIRO_HOOK_REL = '.kiro/hooks/ags-skill-loader.md';\n\n// āā Types āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\nexport interface HookWriteReport {\n writes: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Agents with no hook system ā skills delivered via rules files only. */\n unsupported: Agent[];\n}\n\nexport interface HookStatusRow {\n agent: Agent;\n installed: boolean;\n files: string[];\n}\n\n// āā Service āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n/**\n * Installs and removes AI-agent lifecycle hooks for the skill-loader reminder.\n *\n * Supported hook systems:\n * Claude Code ā PreToolUse hook (blocking-capable, fires before every Edit/Write)\n * Cursor ā PreToolUse hook\n * Windsurf ā PreToolUse hook\n * Gemini ā PreToolUse hook\n * Codex ā PreToolUse hook\n * Copilot ā PreToolUse hook\n * Kiro ā File-save spec hook (advisory, cannot block edits)\n *\n * All other agents in the supported-agents list have no programmatic hook system;\n * they receive the MCP trigger via their rules file (CLAUDE.md, .cursor/rules, etc.)\n * which is written by SyncService ā no separate hook file is needed.\n *\n * Settings writes are idempotent and merge existing content.\n * Claude hook script is created once and preserved if customized.\n * Kiro hook markdown stays in sync with the embedded template.\n */\nexport class HookService {\n async install(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<HookWriteReport> {\n const report: HookWriteReport = { writes: [], unsupported: [] };\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n await this.installKiroHook(opts.rootDir, report);\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookScriptPath && def.hookConfigPath) {\n await this.installStandardHookConfig({\n rootDir: opts.rootDir,\n agent,\n scriptRelPath: def.hookScriptPath,\n configRelPath: def.hookConfigPath,\n hookCmd:\n agent === Agent.Claude\n ? 'node \"$CLAUDE_PROJECT_DIR/.claude/hooks/preedit-skill-loader.js\"'\n : `node \"${def.hookScriptPath}\"`,\n report,\n });\n } else {\n report.unsupported.push(agent);\n }\n }\n\n return report;\n }\n\n async uninstall(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<{ removed: Array<{ agent: Agent; file: string }> }> {\n const removed: Array<{ agent: Agent; file: string }> = [];\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n const abs = path.join(opts.rootDir, KIRO_HOOK_REL);\n if (await fs.pathExists(abs)) {\n await fs.remove(abs);\n removed.push({ agent, file: KIRO_HOOK_REL });\n }\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookConfigPath) {\n const files = await this.uninstallStandardHookConfig(\n opts.rootDir,\n def.hookConfigPath,\n );\n removed.push(...files.map((f) => ({ agent, file: f })));\n }\n }\n\n return { removed };\n }\n\n async status(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<HookStatusRow[]> {\n const rows: HookStatusRow[] = [];\n\n for (const agent of opts.agents) {\n if (agent === Agent.Kiro) {\n const exists = await fs.pathExists(\n path.join(opts.rootDir, KIRO_HOOK_REL),\n );\n rows.push({ agent, installed: exists, files: [KIRO_HOOK_REL] });\n continue;\n }\n\n const def = getAgentDefinition(agent);\n if (def.hookScriptPath && def.hookConfigPath) {\n rows.push(\n await this.standardHookStatus(\n opts.rootDir,\n agent,\n def.hookScriptPath,\n def.hookConfigPath,\n ),\n );\n }\n }\n\n return rows;\n }\n\n // āā Standard Python/JSON Hook System (Claude, Codex, Copilot) āāāāāāāāāāāāāāāā\n\n private async installStandardHookConfig(opts: {\n rootDir: string;\n agent: Agent;\n scriptRelPath: string;\n configRelPath: string;\n hookCmd: string;\n report: HookWriteReport;\n }): Promise<void> {\n const scriptAbs = path.join(opts.rootDir, opts.scriptRelPath);\n const scriptExists = await fs.pathExists(scriptAbs);\n await fs.ensureDir(path.dirname(scriptAbs));\n\n // Clean up legacy Python script if present\n const legacyPyAbs = scriptAbs.replace(/\\.js$/, '.py');\n if (await fs.pathExists(legacyPyAbs)) {\n await fs.remove(legacyPyAbs).catch(() => {});\n }\n\n if (!scriptExists) {\n await fs.writeFile(scriptAbs, UNIVERSAL_SKILL_LOADER_JS);\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.scriptRelPath,\n action: 'added',\n });\n } else {\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.scriptRelPath,\n action: 'skipped-existing',\n });\n }\n\n const configAbs = path.join(opts.rootDir, opts.configRelPath);\n const configExists = await fs.pathExists(configAbs);\n const existing = await this.readJson(configAbs);\n let changed = false;\n\n // Add MCP permission (idempotent)\n const permissions = this.ensureObject(existing, 'permissions');\n const allow = this.ensureArray<string>(permissions, 'allow');\n if (!allow.includes(CLAUDE_MCP_PERMISSION)) {\n permissions['allow'] = [CLAUDE_MCP_PERMISSION, ...allow];\n changed = true;\n }\n\n // Add PreToolUse hook entry (idempotent ā guard by script path fragment)\n const hooks = this.ensureObject(existing, 'hooks');\n const preToolUse = this.ensureArray<Record<string, unknown>>(\n hooks,\n 'PreToolUse',\n );\n if (!this.claudeHookEntryExists(preToolUse)) {\n preToolUse.unshift({\n matcher: 'Edit|Write|MultiEdit|NotebookEdit',\n hooks: [{ type: 'command', command: opts.hookCmd, timeout: 5 }],\n });\n changed = true;\n }\n\n if (changed) {\n await this.writeAtomic(configAbs, existing);\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.configRelPath,\n action: configExists ? 'updated' : 'added',\n });\n } else {\n opts.report.writes.push({\n agent: opts.agent,\n file: opts.configRelPath,\n action: 'skipped-existing',\n });\n }\n }\n\n private async uninstallStandardHookConfig(\n rootDir: string,\n configRelPath: string,\n ): Promise<string[]> {\n const removed: string[] = [];\n const configAbs = path.join(rootDir, configRelPath);\n if (!(await fs.pathExists(configAbs))) return removed;\n\n const data = await this.readJson(configAbs);\n let changed = false;\n\n const permissions = this.ensureObject(data, 'permissions');\n const allow = this.ensureArray<string>(permissions, 'allow');\n if (allow.includes(CLAUDE_MCP_PERMISSION)) {\n permissions['allow'] = allow.filter((p) => p !== CLAUDE_MCP_PERMISSION);\n changed = true;\n }\n\n const hooks = this.ensureObject(data, 'hooks');\n const preToolUse = this.ensureArray<Record<string, unknown>>(\n hooks,\n 'PreToolUse',\n );\n const filtered = preToolUse.filter(\n (entry) => !this.claudeHookEntryMatches(entry),\n );\n if (filtered.length !== preToolUse.length) {\n hooks['PreToolUse'] = filtered;\n changed = true;\n }\n\n if (changed) {\n await this.writeAtomic(configAbs, data);\n removed.push(configRelPath);\n }\n\n return removed;\n }\n\n private async standardHookStatus(\n rootDir: string,\n agent: Agent,\n scriptRelPath: string,\n configRelPath: string,\n ): Promise<HookStatusRow> {\n const scriptExists = await fs.pathExists(path.join(rootDir, scriptRelPath));\n const registeredInSettings = await this.claudeHookIsRegistered(\n path.join(rootDir, configRelPath),\n );\n return {\n agent,\n installed: scriptExists && registeredInSettings,\n files: [scriptRelPath, configRelPath],\n };\n }\n\n private async claudeHookIsRegistered(settingsAbs: string): Promise<boolean> {\n if (!(await fs.pathExists(settingsAbs))) return false;\n const data = await this.readJson(settingsAbs);\n const hooks = data['hooks'] as Record<string, unknown> | undefined;\n if (!hooks) return false;\n const preToolUse = hooks['PreToolUse'] as\n | Array<Record<string, unknown>>\n | undefined;\n if (!Array.isArray(preToolUse)) return false;\n return this.claudeHookEntryExists(preToolUse);\n }\n\n private claudeHookEntryExists(\n entries: Array<Record<string, unknown>>,\n ): boolean {\n return entries.some((entry) => this.claudeHookEntryMatches(entry));\n }\n\n private claudeHookEntryMatches(entry: Record<string, unknown>): boolean {\n const entryHooks = (entry['hooks'] ?? []) as Array<Record<string, unknown>>;\n return entryHooks.some((h) =>\n (h['command'] as string | undefined)?.includes('preedit-skill-loader'),\n );\n }\n\n // āā Kiro āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n private async installKiroHook(\n rootDir: string,\n report: HookWriteReport,\n ): Promise<void> {\n const hookAbs = path.join(rootDir, KIRO_HOOK_REL);\n const exists = await fs.pathExists(hookAbs);\n await fs.ensureDir(path.dirname(hookAbs));\n if (!exists) {\n await fs.writeFile(hookAbs, KIRO_HOOK_MD);\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'added',\n });\n return;\n }\n\n const current = await fs.readFile(hookAbs, 'utf8');\n if (current !== KIRO_HOOK_MD) {\n await fs.writeFile(hookAbs, KIRO_HOOK_MD);\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'updated',\n });\n return;\n }\n\n report.writes.push({\n agent: Agent.Kiro,\n file: KIRO_HOOK_REL,\n action: 'skipped-existing',\n });\n }\n\n // āā Utilities āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n\n private async readJson(abs: string): Promise<Record<string, unknown>> {\n if (!(await fs.pathExists(abs))) return {};\n return (await fs.readJson(abs).catch(() => ({}))) as Record<\n string,\n unknown\n >;\n }\n\n private ensureObject(\n parent: Record<string, unknown>,\n key: string,\n ): Record<string, unknown> {\n if (\n typeof parent[key] !== 'object' ||\n parent[key] === null ||\n Array.isArray(parent[key])\n ) {\n parent[key] = {};\n }\n return parent[key] as Record<string, unknown>;\n }\n\n private ensureArray<T>(parent: Record<string, unknown>, key: string): T[] {\n if (!Array.isArray(parent[key])) {\n parent[key] = [];\n }\n return parent[key] as T[];\n }\n\n private async writeAtomic(abs: string, data: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(abs));\n const tmp = `${abs}.tmp`;\n await fs.writeJson(tmp, data, { spaces: 2 });\n await fs.move(tmp, abs, { overwrite: true });\n }\n}\n","import pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport { HookService, HookWriteReport } from '../services/HookService';\n\n/**\n * `ags hooks <action>` ā manage the PreToolUse skill-loader hook for\n * Claude Code (and Kiro advisory hook) without editing files by hand.\n *\n * Sub-actions:\n * status Show which hook files are installed for each agent\n * install Write hook script + register in .claude/settings.json\n * uninstall Deregister from .claude/settings.json (preserves hook script)\n */\nexport class HooksCommand {\n private configService: ConfigService;\n private hookService: HookService;\n\n constructor(configService?: ConfigService, hookService?: HookService) {\n this.configService = configService ?? new ConfigService();\n this.hookService = hookService ?? new HookService();\n }\n\n async run(action: string): Promise<void> {\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(\n pc.red(\n 'ā .skillsrc not found. Run `agent-skills-standard init` first.',\n ),\n );\n return;\n }\n\n const cwd = process.cwd();\n const agents = config.agents ?? [];\n\n switch (action) {\n case 'status':\n return this.actionStatus(cwd, agents);\n case 'install':\n return this.actionInstall(cwd, agents);\n case 'uninstall':\n return this.actionUninstall(cwd, agents);\n default:\n console.log(\n pc.red(`Unknown action: ${action}`),\n '\\nValid actions: status, install, uninstall',\n );\n }\n }\n\n // ---- actions ----\n\n private async actionStatus(cwd: string, agents: Agent[]): Promise<void> {\n const rows = await this.hookService.status({ rootDir: cwd, agents });\n\n console.log(pc.bold('\\nšŖ Hook installation status\\n'));\n\n if (rows.length === 0) {\n console.log(pc.gray(' (no agents configured)'));\n return;\n }\n\n for (const row of rows) {\n const badge = row.installed\n ? pc.green('ā installed')\n : pc.gray('ā not installed');\n console.log(` ${row.agent.padEnd(12)} ${badge}`);\n for (const f of row.files) {\n console.log(` ${pc.gray(f)}`);\n }\n }\n }\n\n private async actionInstall(cwd: string, agents: Agent[]): Promise<void> {\n console.log(pc.cyan('\\nšŖ Installing skill-loader hooks...'));\n const report = await this.hookService.install({ rootDir: cwd, agents });\n this.printReport(report);\n }\n\n private async actionUninstall(cwd: string, agents: Agent[]): Promise<void> {\n const { removed } = await this.hookService.uninstall({\n rootDir: cwd,\n agents,\n });\n if (removed.length === 0) {\n console.log(pc.gray('Nothing to remove.'));\n return;\n }\n console.log(pc.green('ā
Removed hook files:'));\n for (const r of removed) {\n console.log(` - ${pc.cyan(r.agent)} ā ${pc.gray(r.file)}`);\n }\n }\n\n // ---- output ----\n\n private printReport(report: HookWriteReport): void {\n for (const w of report.writes) {\n const tag =\n w.action === 'added'\n ? pc.green('+ added ')\n : w.action === 'updated'\n ? pc.cyan('~ updated ')\n : pc.gray('= up-to-date');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n `\\n(skipped ā no hook support: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n const added = report.writes.filter((w) => w.action !== 'skipped-existing');\n if (added.length > 0) {\n console.log(pc.green('\\nā
Hooks installed.'));\n console.log(\n pc.gray(\n ' Hooks fire before every Edit/Write ā Claude will be reminded to load skills.',\n ),\n );\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport {\n FrameworkDefinition,\n SUPPORTED_AGENTS,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\n\n/**\n * Service for detecting project frameworks, languages, AI agents, and dependencies.\n * It uses a combination of file existence checks and package metadata analysis.\n */\nexport class DetectionService {\n /**\n * Detects supported frameworks based on characteristic files and dependencies.\n * @returns A record of framework IDs and their detection status (boolean)\n */\n async detectFrameworks(): Promise<Record<string, boolean>> {\n const cwd = process.cwd();\n // Gather root and immediate subdirectories to support monorepos\n const dirsToScan = [cwd];\n try {\n const entries = await fs.readdir(cwd, { withFileTypes: true });\n for (const entry of entries) {\n if (\n entry.isDirectory() &&\n !entry.name.startsWith('.') &&\n entry.name !== 'node_modules'\n ) {\n dirsToScan.push(path.join(cwd, entry.name));\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.debug(\n `[DetectionService] Failed to read directory entries: ${error}`,\n );\n }\n }\n\n const packageDepsMaps = await Promise.all(\n dirsToScan.map((dir) => this.readPackageJsonDeps(dir)),\n );\n\n // Merge all deps\n const allPackageDeps = {};\n for (const deps of packageDepsMaps) {\n Object.assign(allPackageDeps, deps);\n }\n\n const detectionPromises = SUPPORTED_FRAMEWORKS.map(async (framework) => {\n // 1. Check characteristic files in parallel across all scanned directories\n let detected = false;\n for (const dir of dirsToScan) {\n if (detected) break;\n const fileChecks = framework.detectionFiles.map((file) =>\n fs.pathExists(path.join(dir, file)),\n );\n const fileResults = await Promise.all(fileChecks);\n if (fileResults.some((exists) => exists)) {\n detected = true;\n }\n }\n\n // 2. Check dependencies (if not yet detected)\n if (\n !detected &&\n framework.detectionDependencies &&\n framework.detectionDependencies.length > 0\n ) {\n detected = framework.detectionDependencies.some((dep) =>\n Object.prototype.hasOwnProperty.call(allPackageDeps, dep),\n );\n }\n\n return { id: framework.id, detected };\n });\n\n const results = await Promise.all(detectionPromises);\n return results.reduce(\n (acc, { id, detected }) => ({ ...acc, [id]: detected }),\n {},\n );\n }\n\n async detectLanguages(framework: FrameworkDefinition): Promise<string[]> {\n if (!framework.languageDetection) {\n return framework.languages;\n }\n\n const languageEntries = Object.entries(\n framework.languageDetection as Record<string, string[]>,\n );\n\n const detectionResults = await Promise.all(\n languageEntries.map(async ([lang, files]) => {\n const fileChecks = files.map((file) =>\n fs.pathExists(path.join(process.cwd(), file)),\n );\n const results = await Promise.all(fileChecks);\n return { lang, detected: results.some((exists) => exists) };\n }),\n );\n\n const detectedLanguages = detectionResults\n .filter((r) => r.detected)\n .map((r) => r.lang);\n\n return detectedLanguages.length > 0\n ? detectedLanguages\n : framework.languages;\n }\n\n /**\n * Detects enabled AI agents in the workspace by looking for their configuration files.\n * @returns A record of agent IDs and their detection status (boolean)\n */\n async detectAgents(): Promise<Record<string, boolean>> {\n const detectionPromises = SUPPORTED_AGENTS.map(async (agent) => {\n const fileChecks = agent.detectionFiles.map((file) =>\n fs.pathExists(path.join(process.cwd(), file)),\n );\n const results = await Promise.all(fileChecks);\n return { id: agent.id, detected: results.some((exists) => exists) };\n });\n\n const results = await Promise.all(detectionPromises);\n return results.reduce(\n (acc, { id, detected }) => ({ ...acc, [id]: detected }),\n {},\n );\n }\n\n /**\n * Aggregates project dependencies from various build systems (NPM, Pub, Gradle, Maven).\n * @returns A set of all detected package names/identifiers\n */\n async getProjectDeps(): Promise<Set<string>> {\n const cwd = process.cwd();\n const results = await Promise.all([\n this.parsePackageJson(cwd),\n this.parsePubspecYaml(cwd),\n this.parseGradleDependencies(cwd),\n this.parseVersionCatalogs(cwd),\n this.parseMavenPom(cwd),\n ]);\n\n const combined = new Set<string>();\n for (const set of results) {\n for (const item of set) combined.add(item);\n }\n return combined;\n }\n\n private async parsePackageJson(cwd: string): Promise<Set<string>> {\n const depsMap = await this.readPackageJsonDeps(cwd);\n return new Set(Object.keys(depsMap));\n }\n\n private async readPackageJsonDeps(\n cwd: string,\n ): Promise<Record<string, string>> {\n const packageJsonPath = path.join(cwd, 'package.json');\n if (!(await fs.pathExists(packageJsonPath))) return {};\n\n try {\n const pkg = await fs.readJson(packageJsonPath);\n return {\n ...(pkg.dependencies || {}),\n ...(pkg.devDependencies || {}),\n };\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to read package.json:', error);\n return {};\n }\n }\n\n private async parsePubspecYaml(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const pubspecPath = path.join(cwd, 'pubspec.yaml');\n if (!(await fs.pathExists(pubspecPath))) return set;\n\n try {\n const content = await fs.readFile(pubspecPath, 'utf8');\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n let sectionIndent: number | null = null;\n\n for (const line of lines) {\n const sectionMatch = line.match(\n /^(\\s*)(dependencies|dev_dependencies)\\s*:/,\n );\n if (sectionMatch) {\n currentSection = sectionMatch[2];\n sectionIndent = sectionMatch[1].length;\n continue;\n }\n\n if (!currentSection || sectionIndent === null) continue;\n const entryMatch = line.match(/^(\\s*)([a-zA-Z0-9_\\-@\\\\/]+)\\s*:/);\n if (!entryMatch) continue;\n\n const indent = entryMatch[1].length;\n const key = entryMatch[2];\n if (indent > sectionIndent && key !== 'sdk' && key !== 'flutter') {\n set.add(key);\n }\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to parse pubspec.yaml:', error);\n }\n return set;\n }\n\n private async parseGradleDependencies(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const gradleRegex =\n /(?:implementation|api|ksp|kapt|annotationProcessor|compileOnly|runtimeOnly)\\s*\\(?\\s*['\"]([^'\":\\s]+)(?::[^'\"]*)?['\"]\\s*\\)?/g;\n\n const scanDir = async (dir: string, depth: number) => {\n if (depth > 2) return; // Reduced depth for performance\n try {\n const entries = await fs.readdir(dir, { withFileTypes: true });\n for (const entry of entries) {\n if (entry.isDirectory()) {\n if (\n [\n 'node_modules',\n '.git',\n 'build',\n '.gradle',\n 'ios',\n 'macos',\n ].includes(entry.name)\n )\n continue;\n await scanDir(path.join(dir, entry.name), depth + 1);\n } else if (\n entry.name === 'build.gradle' ||\n entry.name === 'build.gradle.kts'\n ) {\n const content = await fs.readFile(\n path.join(dir, entry.name),\n 'utf8',\n );\n gradleRegex.lastIndex = 0;\n let match;\n while ((match = gradleRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n }\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to scan gradle dependencies:', error);\n }\n };\n\n await scanDir(cwd, 0);\n return set;\n }\n\n private async parseVersionCatalogs(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const tomlPaths = [\n path.join(cwd, 'gradle', 'libs.versions.toml'),\n path.join(cwd, 'gradle.libs.versions.toml'),\n ];\n\n for (const tomlPath of tomlPaths) {\n if (!(await fs.pathExists(tomlPath))) continue;\n try {\n const content = await fs.readFile(tomlPath, 'utf8');\n const moduleRegex = /module\\s*=\\s*['\"]([^'\":\\s]+)(?::[^'\"]*)?['\"]/g;\n const groupRegex = /group\\s*=\\s*['\"]([^'\":\\s]+)['\"]/g;\n let match;\n while ((match = moduleRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n while ((match = groupRegex.exec(content)) !== null) {\n set.add(match[1]);\n }\n } catch (error) {\n if (process.env.DEBUG)\n console.debug('Failed to parse version catalogs:', error);\n }\n }\n return set;\n }\n\n private async parseMavenPom(cwd: string): Promise<Set<string>> {\n const set = new Set<string>();\n const pomPath = path.join(cwd, 'pom.xml');\n if (!(await fs.pathExists(pomPath))) return set;\n\n try {\n const content = await fs.readFile(pomPath, 'utf8');\n const regex =\n /<dependency>[\\s\\S]*?<artifactId>([^<]+)<\\/artifactId>[\\s\\S]*?<\\/dependency>/g;\n let match;\n while ((match = regex.exec(content)) !== null) {\n set.add(match[1]);\n }\n } catch (error) {\n if (process.env.DEBUG) console.debug('Failed to parse maven pom:', error);\n }\n return set;\n }\n}\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport {\n Agent,\n DEFAULT_WORKFLOWS,\n SUPPORTED_AGENTS,\n SUPPORTED_FRAMEWORKS,\n} from '../constants';\nimport { RegistryMetadata } from '../models/types';\nimport { ConfigService } from './ConfigService';\nimport { DetectionService } from './DetectionService';\n\n/**\n * Contextual data gathered during project discovery to inform the initialization prompt.\n */\nexport interface InitContext {\n /** Map of framework IDs and whether they were detected in the workspace */\n frameworkDetection: Record<string, boolean>;\n /** Map of agent IDs and whether they were detected in the workspace */\n agentDetection: Record<string, boolean>;\n}\n/**\n * User responses gathered from the initialization prompt.\n */\nexport interface InitAnswers {\n /** The primary framework ID chosen by the user */\n framework: string;\n /** List of AI agents to enable for the project */\n agents: Agent[];\n /** The URL of the skill registry to use */\n registry: string;\n /** Whether to enable the MCP integration (consent step). */\n mcpEnabled?: boolean;\n /** Scope of MCP writes the user consented to. Only meaningful when mcpEnabled=true. */\n mcpScope?: 'project' | 'user' | 'snippets-only' | 'disabled';\n}\n\n/**\n * Service for orchestrating the project initialization process.\n * Handles environment discovery, prompt choice generation, and initial config creation.\n */\nexport class InitService {\n private detectionService = new DetectionService();\n private configService = new ConfigService();\n\n /**\n * Performs environmental discovery to identify existing frameworks and agents.\n * @returns An InitContext containing detection results\n */\n async getInitializationContext(): Promise<InitContext> {\n const [frameworkDetection, agentDetection] = await Promise.all([\n this.detectionService.detectFrameworks(),\n this.detectionService.detectAgents(),\n ]);\n\n return { frameworkDetection, agentDetection };\n }\n\n /**\n * Transforms the initialization context and registry metadata into choices for the interactive prompt.\n * @param context The discovered initialization context\n * @param supportedCategories List of categories currently supported by the registry\n * @returns Formatted choices and the default framework ID\n */\n getPromptChoices(context: InitContext, supportedCategories: string[]) {\n const frameworkChoices = SUPPORTED_FRAMEWORKS.map((f) => ({\n name: supportedCategories.includes(f.id)\n ? f.name\n : `${f.name} (Coming Soon)`,\n value: f.id,\n }));\n\n const agentChoices = SUPPORTED_AGENTS.map((a) => ({\n name: `${a.name} (${a.path}/)`,\n value: a.id,\n checked: context.agentDetection[a.id] ?? false,\n }));\n\n const defaultFramework =\n SUPPORTED_FRAMEWORKS.find((f) => context.frameworkDetection[f.id])?.id ||\n 'flutter';\n\n return {\n frameworkChoices,\n agentChoices,\n defaultFramework,\n };\n }\n\n /**\n * Orchestrates the construction, validation, and saving of the initial `.skillsrc` configuration.\n * @param answers The user's prompt responses\n * @param metadata Registry metadata for versioning\n * @param cwd Current working directory\n */\n async buildAndSaveConfig(\n answers: InitAnswers,\n metadata: Partial<RegistryMetadata>,\n cwd: string = process.cwd(),\n ) {\n const frameworkId = answers.framework;\n const frameworkDef = SUPPORTED_FRAMEWORKS.find((f) => f.id === frameworkId);\n\n const languages = frameworkDef\n ? await this.detectionService.detectLanguages(frameworkDef)\n : [];\n\n const includeWorkflows = answers.agents.includes(Agent.Antigravity);\n\n const config = this.configService.buildInitialConfig(\n frameworkId,\n answers.agents,\n answers.registry,\n metadata,\n languages,\n includeWorkflows ? DEFAULT_WORKFLOWS : [],\n );\n\n const projectDeps = await this.detectionService.getProjectDeps();\n this.configService.applyDependencyExclusions(config, projectDeps);\n this.configService.reconcileDependencies(config, projectDeps);\n\n // Persist the user's MCP consent decision (if asked).\n if (answers.mcpScope !== undefined) {\n config.mcp = {\n enabled: answers.mcpEnabled === true,\n scope: answers.mcpEnabled === false ? 'disabled' : answers.mcpScope,\n prompted: true,\n };\n }\n\n const commentHeader = `# Auto-detected configuration generated by agent-skills-standard init\n#\n# Presence in 'skills' list = Active. To disable a skill, remove it from the list.\n# 'exclude': IDs of sub-skills to skip during sync (auto-populated with undetected skills).\n# 'custom_overrides': IDs of skills to PROTECT. Use this if you have modified a standard \n# skill locally and don't want the CLI to overwrite it.\n#\n# Run 'ags list-skills' to view all available skills.\n#\n# SDLC support skills such as quality-engineering are included by default.\n# Specialist definitions are synced separately as native sub-agents, not skills.\n#\n`;\n const configPath = path.join(cwd, '.skillsrc');\n await fs.outputFile(configPath, commentHeader + yaml.dump(config));\n }\n}\n","import fetch from 'cross-fetch';\nimport pc from 'picocolors';\nimport { GitHubTreeResponse } from '../models/types';\n\n/**\n * Service for interacting with the GitHub API and fetching raw file content.\n * Handles repository tree discovery, file downloads, and URL parsing.\n */\nexport class GithubService {\n private baseUrl = 'https://api.github.com';\n private rawBaseUrl = 'https://raw.githubusercontent.com';\n\n constructor(private token?: string) {}\n\n private get headers() {\n const h: Record<string, string> = {\n Accept: 'application/vnd.github.v3+json',\n };\n if (this.token) {\n h.Authorization = `token ${this.token}`;\n }\n return h;\n }\n\n /**\n * Fetches the recursive Git tree for a repository.\n * @param owner Repository owner\n * @param repo Repository name\n * @param ref Git reference (branch, tag, or commit SHA)\n * @returns The tree data or null if not found\n */\n async getRepoTree(\n owner: string,\n repo: string,\n ref: string,\n ): Promise<GitHubTreeResponse | null> {\n const url = `${this.baseUrl}/repos/${owner}/${repo}/git/trees/${ref}?recursive=1`;\n try {\n const res = await fetch(url, { headers: this.headers });\n if (!res.ok) {\n if (res.status === 404) return null;\n throw new Error(`GitHub API Error: ${res.status} ${res.statusText}`);\n }\n return (await res.json()) as GitHubTreeResponse;\n } catch (error) {\n console.error(pc.red(`Failed to fetch repo tree: ${error}`));\n return null;\n }\n }\n\n /**\n * Fetches the raw content of a file from GitHub using raw.githubusercontent.com.\n * @param owner Repository owner\n * @param repo Repository name\n * @param ref Git reference\n * @param path Path to the file\n * @returns File content as string or null if not found\n */\n async getRawFile(\n owner: string,\n repo: string,\n ref: string,\n path: string,\n ): Promise<string | null> {\n const url = `${this.rawBaseUrl}/${owner}/${repo}/${ref}/${path}`;\n try {\n const res = await fetch(url);\n if (!res.ok) return null;\n return await res.text();\n } catch (error) {\n console.error(pc.red(`Failed to fetch file ${path}: ${error}`));\n return null;\n }\n }\n\n /**\n * Retrieves the latest release tag name for a repository.\n * @param owner Repository owner\n * @param repo Repository name\n */\n async getLatestReleaseTag(\n owner: string,\n repo: string,\n ): Promise<string | null> {\n try {\n const res = await fetch(\n `${this.baseUrl}/repos/${owner}/${repo}/releases/latest`,\n {\n headers: this.headers,\n },\n );\n if (!res.ok) return null;\n const data = (await res.json()) as { tag_name: string };\n return data.tag_name;\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[GithubService] Failed to fetch latest release: ${error}`,\n );\n }\n return null;\n }\n }\n\n /**\n * Fetches basic repository information, such as the default branch.\n * @param owner Repository owner\n * @param repo Repository name\n */\n async getRepoInfo(\n owner: string,\n repo: string,\n ): Promise<{ default_branch: string } | null> {\n const url = `${this.baseUrl}/repos/${owner}/${repo}`;\n try {\n const res = await fetch(url, { headers: this.headers });\n if (!res.ok) return null;\n return (await res.json()) as { default_branch: string };\n } catch (error) {\n console.error(pc.red(`Failed to fetch repo info: ${error}`));\n return null;\n }\n }\n\n /**\n * Downloads multiple files concurrently with a limit.\n */\n async downloadFilesConcurrent(\n tasks: { owner: string; repo: string; ref: string; path: string }[],\n concurrency: number = 10,\n ): Promise<{ path: string; content: string }[]> {\n const results: { path: string; content: string }[] = [];\n const pool = [...tasks];\n const executing: Promise<void>[] = [];\n\n const worker = async () => {\n while (pool.length > 0) {\n const task = pool.shift();\n if (!task) break;\n\n const content = await this.getRawFile(\n task.owner,\n task.repo,\n task.ref,\n task.path,\n );\n if (content !== null) {\n results.push({ path: task.path, content });\n }\n }\n };\n\n // Spawn workers\n for (let i = 0; i < Math.min(concurrency, tasks.length); i++) {\n executing.push(worker());\n }\n\n await Promise.all(executing);\n return results;\n }\n\n /**\n * Parses a GitHub URL into owner and repository name.\n * @param url The GitHub URL to parse\n * @returns Object containing owner and repo, or null if invalid\n */\n static parseGitHubUrl(url: string): { owner: string; repo: string } | null {\n const m = url.match(/github\\.com\\/([^/]+)\\/([^/]+)/i);\n if (!m) return null;\n return { owner: m[1], repo: m[2].replace(/\\.git$/, '') };\n }\n}\n","import path from 'path';\nimport { GitHubTreeItem, RegistryMetadata } from '../models/types';\nimport { GithubService } from './GithubService';\n\n/**\n * Service for discovering and querying the skill registry (repository).\n * It identifies available categories, metadata, and framework-specific skills.\n */\nexport class RegistryService {\n private githubService: GithubService;\n\n constructor() {\n this.githubService = new GithubService(process.env.GITHUB_TOKEN);\n }\n\n /**\n * Discovers the registry structure by scanning the repository tree.\n * Identifies available categories, global metadata, and workflows.\n * @param registryUrl The GitHub URL of the registry\n * @returns Discovered registry components\n */\n async discoverRegistry(registryUrl: string): Promise<{\n categories: string[];\n metadata: Partial<RegistryMetadata>;\n workflows: string[];\n }> {\n let categories: string[] = ['flutter', 'dart'];\n let metadata: Partial<RegistryMetadata> = {};\n\n try {\n const parsed = GithubService.parseGitHubUrl(registryUrl);\n if (parsed) {\n let branch = 'main';\n const repoInfo = await this.githubService.getRepoInfo(\n parsed.owner,\n parsed.repo,\n );\n if (repoInfo && repoInfo.default_branch) {\n branch = repoInfo.default_branch;\n }\n\n const treeResult = await this.githubService.getRepoTree(\n parsed.owner,\n parsed.repo,\n branch,\n );\n\n if (treeResult && Array.isArray(treeResult.tree)) {\n const allFiles = treeResult.tree || [];\n const foundCategories = new Set<string>();\n allFiles.forEach((f: GitHubTreeItem) => {\n if (f.path.startsWith('skills/') && f.type === 'tree') {\n const parts = f.path.split('/');\n if (parts.length === 2) foundCategories.add(parts[1]);\n }\n });\n if (foundCategories.size > 0)\n categories = Array.from(foundCategories);\n\n const workflows = allFiles\n .filter(\n (f) =>\n f.path.startsWith('.agents/workflows/') &&\n f.path.endsWith('.md'),\n )\n .map((f) => path.basename(f.path, '.md'));\n\n const metaContent = await this.githubService.getRawFile(\n parsed.owner,\n parsed.repo,\n branch,\n 'skills/metadata.json',\n );\n if (metaContent) {\n metadata = JSON.parse(metaContent) as RegistryMetadata;\n }\n\n return { categories, metadata, workflows };\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[RegistryService] Registry discovery failed: ${error}`);\n }\n }\n\n return { categories, metadata, workflows: [] };\n }\n\n /**\n * Fetches a list of available skill folders for a specific framework.\n * @param registryUrl The GitHub URL of the registry\n * @param framework The framework ID to query\n * @returns List of skill folder names\n */\n async getFrameworkSkills(\n registryUrl: string,\n framework: string,\n ): Promise<string[]> {\n try {\n const parsed = GithubService.parseGitHubUrl(registryUrl);\n if (!parsed) return [];\n\n const treeResult = await this.githubService.getRepoTree(\n parsed.owner,\n parsed.repo,\n 'main',\n );\n\n if (!treeResult || !Array.isArray(treeResult.tree)) return [];\n\n return Array.from(\n new Set(\n treeResult.tree\n .filter((f: GitHubTreeItem) =>\n f.path.startsWith(`skills/${framework}/`),\n )\n .map((f: GitHubTreeItem) => f.path.split('/')[2])\n .filter(Boolean),\n ),\n );\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[RegistryService] Failed to get framework skills for ${framework}: ${error}`,\n );\n }\n return [];\n }\n }\n}\n","import fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { DEFAULT_REGISTER } from '../constants';\nimport { InitAnswers, InitService } from '../services/InitService';\nimport { RegistryService } from '../services/RegistryService';\n\n/**\n * Command for initializing the agent-skills-standard configuration in a project.\n * It guides the user through environment detection and creates the `.skillsrc` file.\n */\nexport class InitCommand {\n private initService: InitService;\n private registryService: RegistryService;\n\n constructor(initService?: InitService, registryService?: RegistryService) {\n this.initService = initService || new InitService();\n this.registryService = registryService || new RegistryService();\n }\n\n /**\n * Executes the initialization flow.\n * Checks for existing config, discovers the environment, prompts the user, and saves the configuration.\n */\n async run() {\n const configPath = path.join(process.cwd(), '.skillsrc');\n\n // 1. Check for existing config\n if (await fs.pathExists(configPath)) {\n const { overwrite } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'overwrite',\n message: '.skillsrc already exists. Do you want to overwrite it?',\n default: false,\n },\n ]);\n if (!overwrite) {\n console.log(pc.yellow('Aborted.'));\n return;\n }\n }\n\n // 2. Gather context data\n const context = await this.initService.getInitializationContext();\n const { categories, metadata } =\n await this.registryService.discoverRegistry(DEFAULT_REGISTER);\n\n // 3. Prepare Choices\n const { frameworkChoices, agentChoices, defaultFramework } =\n this.initService.getPromptChoices(context, categories);\n\n // 4. Prompt User\n const answers = await inquirer.prompt<InitAnswers>([\n {\n type: 'list',\n name: 'framework',\n message: 'Select Framework:',\n choices: frameworkChoices,\n default: defaultFramework,\n },\n {\n type: 'checkbox',\n name: 'agents',\n message: 'Select AI Agents you use:',\n choices: agentChoices,\n },\n {\n type: 'input',\n name: 'registry',\n message: 'Skills Registry URL:',\n default: DEFAULT_REGISTER,\n },\n ]);\n\n // 4b. MCP consent step\n this.printMcpValueProp();\n const mcpDecision = await inquirer.prompt<{\n mcpEnabled: boolean;\n mcpScope: 'project' | 'user' | 'snippets-only';\n }>([\n {\n type: 'confirm',\n name: 'mcpEnabled',\n message: 'Enable MCP server integration?',\n default: true,\n },\n {\n type: 'list',\n name: 'mcpScope',\n message: 'Where should sync write MCP configs?',\n when: (a) => a.mcpEnabled === true,\n choices: [\n {\n name: 'project (recommended) ā only files inside this project (.mcp.json, .cursor/mcp.json, etc.)',\n value: 'project',\n },\n {\n name: 'user ā also $HOME files (~/.cursor/mcp.json, ~/.gemini/settings.json) ā sync prompts each',\n value: 'user',\n },\n {\n name: 'snippets-only ā never edits any runtime config; just generates ./mcp-config-snippets/*.json',\n value: 'snippets-only',\n },\n ],\n default: 'project',\n },\n ]);\n answers.mcpEnabled = mcpDecision.mcpEnabled;\n answers.mcpScope = mcpDecision.mcpEnabled\n ? mcpDecision.mcpScope\n : 'disabled';\n\n // 5. Build and Save\n await this.initService.buildAndSaveConfig(answers, metadata);\n\n console.log(pc.green('\\nā
Initialized .skillsrc with your preferences!'));\n console.log(pc.gray(` Selected framework: ${answers.framework}`));\n if (answers.mcpEnabled) {\n console.log(\n pc.gray(` MCP integration: enabled (scope: ${answers.mcpScope})`),\n );\n } else {\n console.log(\n pc.gray(\n ` MCP integration: disabled (change later via \\`ags mcp enable\\`)`,\n ),\n );\n }\n console.log(\n pc.cyan(\n '\\nNext step: Run `agent-skills-standard sync` to install skills and wire MCP.',\n ),\n );\n }\n\n private printMcpValueProp(): void {\n console.log(pc.bold('\\nš MCP server setup\\n'));\n console.log(\n 'agent-skills-standard ships an optional MCP server that serves your skills',\n );\n console.log('to AI agents at runtime. Quick comparison:\\n');\n console.log(pc.bold(' WITHOUT MCP') + ' (skills as static files only)');\n console.log(pc.green(' ā') + ' Zero setup overhead');\n console.log(\n pc.red(' ā') +\n ' Sub-agents (Claude Code tdd-implementer, architecture-guard, etc.)',\n );\n console.log(\n ' do NOT inherit AGENTS.md ā they often skip skill loading entirely',\n );\n console.log(\n pc.red(' ā') + ' No audit trail of which skills were consulted',\n );\n console.log(\n pc.red(' ā') +\n ' False findings in code review (agent uses pre-training defaults)\\n',\n );\n console.log(pc.bold(' WITH MCP') + ' (runtime tool calls)');\n console.log(\n pc.green(' ā') +\n ' Sub-agents in EVERY runtime can call load_skills_for_files',\n );\n console.log(\n pc.green(' ā') +\n \" Returns matched SKILL.md as a tool response ā can't be silently skipped\",\n );\n console.log(\n pc.green(' ā') +\n ' audit_session_compliance gives you a receipt of what was loaded',\n );\n console.log(\n pc.gray(' -') + ' Adds one more process to your AI runtime config\\n',\n );\n }\n}\n","import { SKILL_DETECTION_REGISTRY } from '../constants';\nimport { RegistryService } from './RegistryService';\n\n/**\n * Represents a skill with its detection status in the current project.\n */\nexport interface SkillWithStatus {\n /** The name/ID of the skill */\n name: string;\n /**\n * Status of the skill:\n * - detected: Required dependencies found\n * - not-detected: Required dependencies missing\n * - no-rule: No automated detection rule exists for this skill\n */\n status: 'detected' | 'not-detected' | 'no-rule';\n}\n\n/**\n * Service for managing skill status and availability.\n * Maps registry skills to project dependencies to determine detection status.\n */\nexport class SkillService {\n private registryService = new RegistryService();\n\n /**\n * Retrieves a list of skills for a framework with their detection status.\n * @param framework The framework to filter by\n * @param registryUrl The registry URL\n * @param projectDeps Set of detected project dependencies\n * @returns Array of skills with validated status\n */\n async getSkillsWithStatus(\n framework: string,\n registryUrl: string,\n projectDeps: Set<string>,\n ): Promise<SkillWithStatus[]> {\n // 1. Get available skills (Remote + Fallback)\n let skillFolders = await this.registryService.getFrameworkSkills(\n registryUrl,\n framework,\n );\n\n const detectRules = SKILL_DETECTION_REGISTRY[framework] || [];\n\n // Fallback: use detection registry skill ids if remote fetch returned nothing\n if (!skillFolders || skillFolders.length === 0) {\n skillFolders = detectRules.map((s) => s.id);\n }\n\n // 2. Map to Status\n const skills = skillFolders.sort().map((skillName) => {\n const rule = detectRules.find((x) => x.id === skillName);\n\n let status: SkillWithStatus['status'] = 'no-rule';\n if (rule) {\n const depsArray = Array.from(projectDeps);\n const isPresent = this.hasDependency(rule.packages, depsArray);\n status = isPresent ? 'detected' : 'not-detected';\n }\n\n return { name: skillName, status };\n });\n\n return skills;\n }\n\n /**\n * Checks if ANY of the required dependencies are found in the project.\n * Uses the same word-boundary matching logic as ConfigService.hasDependency().\n */\n private hasDependency(packages: string[], projectDeps: string[]): boolean {\n if (packages.length === 0) return true;\n return projectDeps.some((d) =>\n packages.some((pkg) => {\n const depLower = d.toLowerCase();\n const pkgLower = pkg.toLowerCase();\n if (depLower === pkgLower) return true;\n if (pkg.length <= 3) return false;\n if (depLower.includes('/') && depLower.split('/').pop() === pkgLower)\n return true;\n const parts = depLower.split(/[-/_]/);\n return parts.includes(pkgLower);\n }),\n );\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { Framework, SUPPORTED_FRAMEWORKS } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport { DetectionService } from '../services/DetectionService';\nimport { SkillService } from '../services/SkillService';\n\n/**\n * Command for listing available skills in the registry.\n * It detects the project's dependencies and identifies which skills have matching rules.\n */\nexport class ListSkillsCommand {\n private configService: ConfigService;\n private detectionService: DetectionService;\n private skillService: SkillService;\n\n constructor(\n configService?: ConfigService,\n detectionService?: DetectionService,\n skillService?: SkillService,\n ) {\n this.configService = configService || new ConfigService();\n this.detectionService = detectionService || new DetectionService();\n this.skillService = skillService || new SkillService();\n }\n\n /**\n * Executes the skill listing flow.\n * Prompts for framework selection, fetches matching skills from the registry, and displays their status.\n */\n async run(options: { framework?: string } = {}) {\n // 1. Get framework choice from user\n let framework = options.framework;\n\n // Validate framework if provided via options\n if (framework) {\n const isSupported = SUPPORTED_FRAMEWORKS.some((f) => f.id === framework);\n if (!isSupported) {\n const validFrameworks = SUPPORTED_FRAMEWORKS.map((f) => f.id).join(\n ', ',\n );\n console.error(\n pc.red(\n `Invalid framework \"${framework}\". Supported frameworks are: ${validFrameworks}.`,\n ),\n );\n process.exit(1);\n }\n }\n\n if (!framework) {\n const choices = SUPPORTED_FRAMEWORKS.map((f) => ({\n name: f.name,\n value: f.id,\n }));\n\n const answer = await inquirer.prompt([\n {\n type: 'list',\n name: 'framework',\n message: 'Select framework to list available skills for:',\n choices,\n default: choices.find((c) => c.value === Framework.Flutter)?.value,\n },\n ]);\n framework = answer.framework;\n }\n\n if (!framework) return;\n\n // 2. Load context\n const projectDeps = await this.detectionService.getProjectDeps();\n const registryUrl = await this.configService.getRegistryUrl();\n\n console.log(pc.green(`\\nAvailable skills for ${framework}:`));\n\n // 3. Fetch skills with status\n const skills = await this.skillService.getSkillsWithStatus(\n framework,\n registryUrl,\n projectDeps,\n );\n\n // 4. Output results\n for (const skill of skills) {\n const mark =\n skill.status === 'no-rule'\n ? pc.yellow('no-rule')\n : skill.status === 'detected'\n ? pc.green('detected')\n : pc.gray('not-detected');\n\n console.log(`- ${skill.name} (${mark})`);\n }\n\n console.log(\n '\\nTip: Use the .skillsrc exclude array to disable/enable sub-skills before running sync.',\n );\n }\n}\n","import fs from 'fs-extra';\nimport os from 'os';\nimport path from 'path';\nimport { Agent } from '../constants';\nimport { McpConfig } from '../models/config';\n\n/**\n * Per-runtime MCP config-file location and JSON path.\n *\n * `projectFile` ā path RELATIVE to the project root (we may write here freely\n * if scope is 'project' or 'user').\n * `userFile` ā ABSOLUTE path under $HOME (we only write here if scope is\n * 'user' AND the user confirms each write).\n * `key` ā dotted JSON path under which servers are registered.\n *\n * `null` for either path means that runtime does not support that scope; in that\n * case we either skip (project scope) or surface only via snippet generation.\n */\nexport interface McpTarget {\n agent: Agent;\n /** Project-scope path, relative to project root. */\n projectFile: string | null;\n /** User-scope path, absolute (resolved at call time so $HOME is current). */\n userFile: string | null;\n /** Dotted JSON path where MCP servers live (e.g. \"mcpServers\", \"experimental.modelContextProtocolServers\"). */\n key: string;\n /** Whether the runtime stores servers as a map (key = server name) or a list. */\n shape: 'map' | 'list';\n}\n\nexport const SERVER_NAME = 'agent-skills-standard';\nexport const PACKAGE = 'agent-skills-standard-mcp';\n\nconst getTargets = (home = os.homedir()): Record<string, McpTarget> => {\n const HOME = home;\n return {\n [Agent.Claude]: {\n agent: Agent.Claude,\n projectFile: '.mcp.json',\n userFile: path.join(HOME, '.claude', '.mcp.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Cursor]: {\n agent: Agent.Cursor,\n projectFile: '.cursor/mcp.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n if (process.platform === 'linux') {\n return path.join(\n HOME,\n '.config',\n 'Cursor',\n 'User',\n 'globalStorage',\n 'mcp.json',\n );\n }\n return path.join(HOME, '.cursor', 'mcp.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Antigravity]: {\n agent: Agent.Antigravity,\n projectFile: '.antigravity/mcp_config.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Local',\n 'Google',\n 'Antigravity',\n 'mcp_config.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Google',\n 'Antigravity',\n 'mcp_config.json',\n );\n }\n return path.join(HOME, '.gemini', 'antigravity', 'mcp_config.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Kiro]: {\n agent: Agent.Kiro,\n projectFile: '.kiro/settings/mcp.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Kiro',\n 'settings',\n 'mcp.json',\n );\n }\n return path.join(HOME, '.kiro', 'settings', 'mcp.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Windsurf]: {\n agent: Agent.Windsurf,\n projectFile: '.codeium/windsurf/mcp_config.json',\n userFile: (() => {\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Codeium',\n 'Windsurf',\n 'mcp_config.json',\n );\n }\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Codeium',\n 'Windsurf',\n 'mcp_config.json',\n );\n }\n return path.join(HOME, '.codeium', 'windsurf', 'mcp_config.json');\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Trae]: {\n agent: Agent.Trae,\n projectFile: '.trae/mcp.json',\n userFile: null,\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Roo]: {\n agent: Agent.Roo,\n projectFile: '.roo/mcp_config.json',\n userFile: null,\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Gemini]: {\n agent: Agent.Gemini,\n projectFile: '.gemini/settings.json',\n userFile: path.join(HOME, '.gemini', 'settings.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Copilot]: {\n agent: Agent.Copilot,\n projectFile: '.github/mcp.json',\n userFile: (() => {\n if (process.platform === 'darwin') {\n return path.join(\n HOME,\n 'Library',\n 'Application Support',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n if (process.platform === 'win32') {\n return path.join(\n HOME,\n 'AppData',\n 'Roaming',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n if (process.platform === 'linux') {\n return path.join(\n HOME,\n '.config',\n 'Code',\n 'User',\n 'globalStorage',\n 'github.copilot-chat',\n 'mcp.json',\n );\n }\n return null;\n })(),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.OpenCode]: {\n agent: Agent.OpenCode,\n projectFile: '.opencode/mcp_config.json',\n userFile: path.join(HOME, '.opencode', 'mcp_config.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n [Agent.Codex]: {\n agent: Agent.Codex,\n projectFile: '.codex/mcp_config.json',\n userFile: path.join(HOME, '.codex', 'mcp_config.json'),\n key: 'mcpServers',\n shape: 'map',\n },\n };\n};\n\n/** What a sync/install pass actually did, returned for reporting. */\nexport interface McpWriteReport {\n /** Agents whose project-scope config was written or updated. */\n projectWrites: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Agents whose user-scope config was written (only happens with explicit consent). */\n userWrites: Array<{\n agent: Agent;\n file: string;\n action: 'added' | 'updated' | 'skipped-existing';\n }>;\n /** Snippet files produced under `mcp-config-snippets/`. */\n snippets: Array<{ agent: Agent; file: string }>;\n /** Agents we asked about but the user declined. */\n declined: Array<{ agent: Agent; file: string }>;\n /** Agents that have no MCP support and were skipped. */\n unsupported: Agent[];\n}\n\nexport interface UserScopePrompt {\n (agent: Agent, file: string): Promise<boolean>;\n}\n\n/**\n * Owns all MCP-config writes. Pure logic ā never prompts the user directly.\n * The caller (sync command, mcp subcommand) supplies a `userScopePrompt`\n * callback that is invoked ONLY when the user has chosen `scope: 'user'` AND\n * a user-home file is about to be modified.\n */\nexport class McpConfigService {\n /** Returns the standard MCP server entry our CLI proposes. */\n buildEntry(version?: string): { command: string; args: string[] } {\n const spec = version ? `${PACKAGE}@${version}` : PACKAGE;\n return { command: 'npx', args: ['-y', spec] };\n }\n\n /** For testing: allows overriding the home directory. */\n private testHome: string | null = null;\n setHomeForTesting(home: string | null): void {\n this.testHome = home;\n }\n\n private getTargets(): Record<string, McpTarget> {\n return getTargets(this.testHome ?? undefined);\n }\n\n /**\n * Write MCP configs for the given agents based on the configured scope.\n * Always safe-merge (never overwrite other servers, never replace whole files).\n */\n async install(opts: {\n rootDir: string;\n agents: Agent[];\n mcp: McpConfig;\n /** Required when mcp.scope === 'user'. Called per file before any write. */\n userScopePrompt?: UserScopePrompt;\n }): Promise<McpWriteReport> {\n const report: McpWriteReport = {\n projectWrites: [],\n userWrites: [],\n snippets: [],\n declined: [],\n unsupported: [],\n };\n const { rootDir, agents, mcp } = opts;\n\n if (mcp.scope === 'disabled' || !mcp.enabled) {\n return report;\n }\n\n const TARGETS = this.getTargets();\n const entry = this.buildEntry(mcp.version);\n // Only generate snippets if:\n // 1. scope is 'snippets-only'\n // 2. user explicitly requested snippets via mcp.snippets flag\n if (mcp.scope === 'snippets-only' || mcp.snippets) {\n await this.generateSnippets(rootDir, agents, entry, report);\n }\n\n if (mcp.scope === 'snippets-only') {\n return report;\n }\n\n for (const agent of agents) {\n const target = TARGETS[agent];\n if (!target) {\n report.unsupported.push(agent);\n continue;\n }\n\n // Project-scope writes ā always allowed when scope is project or user.\n if (target.projectFile) {\n const abs = path.join(rootDir, target.projectFile);\n const action = await this.mergeFile(abs, target, entry);\n report.projectWrites.push({ agent, file: target.projectFile, action });\n }\n\n // User-scope writes ā only with scope === 'user' AND per-file consent.\n if (mcp.scope === 'user' && target.userFile) {\n const ok = opts.userScopePrompt\n ? await opts.userScopePrompt(agent, target.userFile)\n : false;\n if (!ok) {\n report.declined.push({ agent, file: target.userFile });\n continue;\n }\n const action = await this.mergeFile(target.userFile, target, entry);\n report.userWrites.push({ agent, file: target.userFile, action });\n }\n }\n\n return report;\n }\n\n /**\n * Remove our MCP entry from configs we may have added it to. Other entries\n * in the same file are untouched.\n */\n async uninstall(opts: {\n rootDir: string;\n agents: Agent[];\n /** Where to remove from. 'all' removes from BOTH project and user files. */\n from: 'project' | 'user' | 'all';\n }): Promise<{ removed: Array<{ agent: Agent; file: string }> }> {\n const removed: Array<{ agent: Agent; file: string }> = [];\n const TARGETS = this.getTargets();\n for (const agent of opts.agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n\n const candidates: Array<{ abs: string; rel: string }> = [];\n if (\n target.projectFile &&\n (opts.from === 'project' || opts.from === 'all')\n ) {\n candidates.push({\n abs: path.join(opts.rootDir, target.projectFile),\n rel: target.projectFile,\n });\n }\n if (target.userFile && (opts.from === 'user' || opts.from === 'all')) {\n candidates.push({ abs: target.userFile, rel: target.userFile });\n }\n\n for (const { abs, rel } of candidates) {\n if (!(await fs.pathExists(abs))) continue;\n const removedHere = await this.removeFromFile(abs, target);\n if (removedHere) removed.push({ agent, file: rel });\n }\n }\n return { removed };\n }\n\n /** Snapshot what's currently installed. Read-only. */\n async status(opts: {\n rootDir: string;\n agents: Agent[];\n }): Promise<Array<{ agent: Agent; project?: boolean; user?: boolean }>> {\n const out: Array<{ agent: Agent; project?: boolean; user?: boolean }> = [];\n const TARGETS = this.getTargets();\n for (const agent of opts.agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n const row: { agent: Agent; project?: boolean; user?: boolean } = {\n agent,\n };\n if (target.projectFile) {\n row.project = await this.hasOurEntry(\n path.join(opts.rootDir, target.projectFile),\n target,\n );\n }\n if (target.userFile) {\n row.user = await this.hasOurEntry(target.userFile, target);\n }\n out.push(row);\n }\n return out;\n }\n\n // ---- private helpers ----\n\n private async generateSnippets(\n rootDir: string,\n agents: Agent[],\n entry: { command: string; args: string[] },\n report: McpWriteReport,\n ): Promise<void> {\n const dir = path.join(rootDir, 'mcp-config-snippets');\n await fs.ensureDir(dir);\n const TARGETS = this.getTargets();\n for (const agent of agents) {\n const target = TARGETS[agent];\n if (!target) continue;\n const file = path.join(dir, `${agent}.json`);\n const snippet = this.buildFreshDoc(target, entry);\n await fs.writeJson(file, snippet, { spaces: 2 });\n report.snippets.push({ agent, file: path.relative(rootDir, file) });\n }\n }\n\n /**\n * Read-modify-write a config file. Only the SERVER_NAME key is touched.\n * Never replaces or removes other entries.\n */\n private async mergeFile(\n abs: string,\n target: McpTarget,\n entry: { command: string; args: string[] },\n ): Promise<'added' | 'updated' | 'skipped-existing'> {\n const existing = (await fs.pathExists(abs))\n ? ((await fs.readJson(abs).catch(() => ({}))) as Record<string, unknown>)\n : {};\n\n const container = this.ensurePathContainer(existing, target);\n\n if (target.shape === 'map') {\n const map = container as Record<string, unknown>;\n const previous = map[SERVER_NAME];\n const next = entry;\n if (previous && deepEqual(previous, next)) {\n return 'skipped-existing';\n }\n map[SERVER_NAME] = next;\n await this.writeAtomic(abs, existing);\n return previous ? 'updated' : 'added';\n } else {\n // shape === 'list'\n const list = container as Array<Record<string, unknown>>;\n const idx = list.findIndex((item) => item.name === SERVER_NAME);\n const next = {\n name: SERVER_NAME,\n transport: { type: 'stdio', ...entry },\n };\n if (idx >= 0) {\n if (deepEqual(list[idx], next)) return 'skipped-existing';\n list[idx] = next;\n await this.writeAtomic(abs, existing);\n return 'updated';\n }\n list.push(next);\n await this.writeAtomic(abs, existing);\n return 'added';\n }\n }\n\n private async removeFromFile(\n abs: string,\n target: McpTarget,\n ): Promise<boolean> {\n const data = (await fs.readJson(abs).catch(() => null)) as Record<\n string,\n unknown\n > | null;\n if (!data) return false;\n const container = this.ensurePathContainer(data, target);\n if (target.shape === 'map') {\n const map = container as Record<string, unknown>;\n if (!(SERVER_NAME in map)) return false;\n delete map[SERVER_NAME];\n await this.writeAtomic(abs, data);\n return true;\n } else {\n const list = container as Array<Record<string, unknown>>;\n const before = list.length;\n const filtered = list.filter((item) => item.name !== SERVER_NAME);\n if (filtered.length === before) return false;\n this.setNestedValue(data, target.key, filtered);\n await this.writeAtomic(abs, data);\n return true;\n }\n }\n\n private async hasOurEntry(abs: string, target: McpTarget): Promise<boolean> {\n if (!(await fs.pathExists(abs))) return false;\n const data = (await fs.readJson(abs).catch(() => null)) as Record<\n string,\n unknown\n > | null;\n if (!data) return false;\n const container = this.getNestedValue(data, target.key);\n if (!container) return false;\n if (target.shape === 'map') {\n return Boolean((container as Record<string, unknown>)[SERVER_NAME]);\n }\n return (container as Array<Record<string, unknown>>).some(\n (item) => item.name === SERVER_NAME,\n );\n }\n\n private buildFreshDoc(\n target: McpTarget,\n entry: { command: string; args: string[] },\n ): Record<string, unknown> {\n const doc: Record<string, unknown> = {};\n const container =\n target.shape === 'map'\n ? { [SERVER_NAME]: entry }\n : [{ name: SERVER_NAME, transport: { type: 'stdio', ...entry } }];\n this.setNestedValue(doc, target.key, container);\n return doc;\n }\n\n private ensurePathContainer(\n data: Record<string, unknown>,\n target: McpTarget,\n ): unknown {\n const existing = this.getNestedValue(data, target.key);\n if (existing) {\n if (target.shape === 'map') {\n if (\n typeof existing === 'object' &&\n existing !== null &&\n !Array.isArray(existing)\n ) {\n return existing;\n }\n } else if (target.shape === 'list') {\n if (Array.isArray(existing)) {\n return existing;\n }\n }\n // Type mismatch: replace it\n }\n const fresh: unknown = target.shape === 'map' ? {} : [];\n this.setNestedValue(data, target.key, fresh);\n return fresh;\n }\n\n private getNestedValue(\n data: Record<string, unknown>,\n dotted: string,\n ): unknown {\n const parts = dotted.split('.');\n let cur: unknown = data;\n for (const p of parts) {\n if (p === '__proto__' || p === 'constructor' || p === 'prototype') {\n throw new Error(\n `Prototype pollution attempt detected in key: ${dotted}`,\n );\n }\n if (typeof cur !== 'object' || cur === null) return undefined;\n cur = (cur as Record<string, unknown>)[p];\n }\n return cur;\n }\n\n private setNestedValue(\n data: Record<string, unknown>,\n dotted: string,\n value: unknown,\n ): void {\n const parts = dotted.split('.');\n let cur = data;\n for (let i = 0; i < parts.length - 1; i++) {\n const p = parts[i];\n if (p === '__proto__' || p === 'constructor' || p === 'prototype') {\n throw new Error(\n `Prototype pollution attempt detected in key: ${dotted}`,\n );\n }\n if (typeof cur[p] !== 'object' || cur[p] === null) {\n cur[p] = {};\n }\n cur = cur[p] as Record<string, unknown>;\n }\n\n const last = parts[parts.length - 1];\n if (\n last === '__proto__' ||\n last === 'constructor' ||\n last === 'prototype'\n ) {\n throw new Error(`Prototype pollution attempt detected in key: ${dotted}`);\n }\n cur[last] = value;\n }\n\n private async writeAtomic(abs: string, data: unknown): Promise<void> {\n await fs.ensureDir(path.dirname(abs));\n const tmp = `${abs}.tmp`;\n await fs.writeJson(tmp, data, { spaces: 2 });\n await fs.move(tmp, abs, { overwrite: true });\n }\n}\n\n/** Default mcp config block used when none is present in `.skillsrc`. */\nexport function defaultMcpConfig(): McpConfig {\n return { enabled: false, scope: 'snippets-only', prompted: false };\n}\n\nfunction deepEqual(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n","import inquirer from 'inquirer';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { ConfigService } from '../services/ConfigService';\nimport {\n McpConfigService,\n defaultMcpConfig,\n} from '../services/McpConfigService';\nimport { McpScope, SkillConfig } from '../models/config';\n\nconst VALID_SCOPES: McpScope[] = [\n 'project',\n 'user',\n 'snippets-only',\n 'disabled',\n];\n\n/**\n * `ags mcp <action>` ā manage the optional MCP server integration without\n * editing `.skillsrc` by hand.\n *\n * Sub-actions:\n * status Show current scope, enabled state, and which configs are wired\n * enable Set mcp.enabled=true; install configs at the configured scope\n * disable Set mcp.enabled=false; existing configs are NOT removed\n * scope <scope> Change scope: project | user | snippets-only | disabled\n * install [--scope=...] One-shot install at the given (or configured) scope\n * uninstall [--from=...] Remove our entry from configs (project | user | all)\n * snippets Generate fresh snippet files in ./mcp-config-snippets/\n */\nexport class McpCommand {\n private configService: ConfigService;\n private mcpService: McpConfigService;\n\n constructor(configService?: ConfigService, mcpService?: McpConfigService) {\n this.configService = configService ?? new ConfigService();\n this.mcpService = mcpService ?? new McpConfigService();\n }\n\n async run(\n action: string,\n options: Record<string, string> = {},\n ): Promise<void> {\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(\n pc.red(\n 'ā .skillsrc not found. Run `agent-skills-standard init` first.',\n ),\n );\n return;\n }\n\n const cwd = process.cwd();\n const agents = config.agents ?? [];\n\n switch (action) {\n case 'status':\n return this.actionStatus(config, cwd);\n case 'enable':\n return this.actionEnable(config);\n case 'disable':\n return this.actionDisable(config);\n case 'scope':\n return this.actionScope(config, options);\n case 'install':\n return this.actionInstall(config, agents, cwd, options);\n case 'uninstall':\n return this.actionUninstall(config, agents, cwd, options);\n case 'snippets':\n return this.actionSnippets(config, agents, cwd);\n default:\n console.log(\n pc.red(`Unknown action: ${action}`),\n '\\nValid actions: status, enable, disable, scope, install, uninstall, snippets',\n );\n }\n }\n\n // ---- actions ----\n\n private async actionStatus(config: SkillConfig, cwd: string): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const agents = config.agents ?? [];\n const rows = await this.mcpService.status({ rootDir: cwd, agents });\n\n console.log(pc.bold('\\nš MCP integration status\\n'));\n console.log(` enabled : ${mcp.enabled ? pc.green('yes') : pc.gray('no')}`);\n console.log(` scope : ${pc.cyan(mcp.scope)}`);\n console.log(` prompted: ${mcp.prompted ? 'yes' : 'no'}`);\n if (mcp.version) console.log(` version : ${mcp.version}`);\n\n if (rows.length === 0) {\n console.log(pc.gray('\\n (no agents configured)'));\n return;\n }\n console.log('\\n Per-agent installation state:');\n let installedAnywhere = false;\n for (const row of rows) {\n const project =\n row.project === undefined\n ? 'ā'\n : row.project\n ? pc.green('ā')\n : pc.gray('ā');\n const user =\n row.user === undefined ? 'ā' : row.user ? pc.green('ā') : pc.gray('ā');\n if (row.project === true || row.user === true) installedAnywhere = true;\n console.log(\n ` ${row.agent.padEnd(12)} project: ${project} user: ${user}`,\n );\n }\n\n // Surface the consent-vs-runtime-config mismatch the user might miss.\n // The MCP block in AGENTS.md is now unconditional, so AI agents will\n // discover the MCP either way ā but the consent flag is what controls\n // whether `sync` keeps the runtime configs in step.\n if (!mcp.enabled && installedAnywhere) {\n console.log(\n pc.yellow(\n '\\nā ļø Mismatch detected: .skillsrc says mcp.enabled=false, but the MCP entry IS present in at least one runtime config.',\n ),\n );\n console.log(\n pc.gray(\n ' The MCP will work, but `sync` will not keep its config in step. Consider one of:',\n ),\n );\n console.log(\n pc.gray(\n ' ⢠`ags mcp enable` ā opt the project in (CLI keeps configs in step)',\n ),\n );\n console.log(\n pc.gray(\n ' ⢠`ags mcp uninstall --from project` ā remove the manual entry if it was unintended',\n ),\n );\n } else if (mcp.enabled && !installedAnywhere) {\n console.log(\n pc.yellow(\n '\\nā ļø Mismatch detected: .skillsrc says mcp.enabled=true, but no runtime config has the MCP registered.',\n ),\n );\n console.log(\n pc.gray(\n ' Run `ags mcp install` to write the entries, or `ags mcp disable` to clear the consent flag.',\n ),\n );\n }\n }\n\n private async actionEnable(config: SkillConfig): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n if (mcp.scope === 'disabled') {\n console.log(\n pc.yellow(\n 'ā ļø scope is currently \"disabled\". Set a real scope first: `ags mcp scope project`',\n ),\n );\n return;\n }\n config.mcp = { ...mcp, enabled: true, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.green('ā
MCP enabled.'));\n console.log(\n pc.gray(\n ' Run `ags mcp install` to write configs now, or it happens on next `sync`.',\n ),\n );\n }\n\n private async actionDisable(config: SkillConfig): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n config.mcp = { ...mcp, enabled: false, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.yellow('š MCP disabled.'));\n console.log(\n pc.gray(\n ' Existing config entries were NOT removed. Use `ags mcp uninstall` to clean them.',\n ),\n );\n }\n\n private async actionScope(\n config: SkillConfig,\n options: Record<string, string>,\n ): Promise<void> {\n const scope = options.scope ?? options._?.[0];\n if (!scope || !VALID_SCOPES.includes(scope as McpScope)) {\n console.log(pc.red(`Invalid scope. Valid: ${VALID_SCOPES.join(' | ')}`));\n return;\n }\n const mcp = config.mcp ?? defaultMcpConfig();\n config.mcp = { ...mcp, scope: scope as McpScope, prompted: true };\n await this.configService.saveConfig(config);\n console.log(pc.green(`ā
MCP scope set to \"${scope}\".`));\n if (scope === 'user') {\n console.log(\n pc.yellow(\n 'ā ļø user-scope writes will be prompted per file during `sync` or `install`.',\n ),\n );\n }\n }\n\n private async actionInstall(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n options: Record<string, string>,\n ): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const scopeOverride = options.scope as McpScope | undefined;\n const effectiveScope = scopeOverride ?? mcp.scope;\n if (scopeOverride && !VALID_SCOPES.includes(scopeOverride)) {\n console.log(\n pc.red(`Invalid --scope value. Valid: ${VALID_SCOPES.join(' | ')}`),\n );\n return;\n }\n if (effectiveScope === 'disabled') {\n console.log(pc.yellow('Scope is \"disabled\" ā nothing to install.'));\n return;\n }\n\n const userPrompt = async (agent: Agent, file: string): Promise<boolean> => {\n const { ok } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'ok',\n message: `Write user-scope MCP config for ${pc.cyan(agent)} at ${pc.gray(file)}?`,\n default: false,\n },\n ]);\n return ok;\n };\n\n const report = await this.mcpService.install({\n rootDir: cwd,\n agents,\n mcp: { ...mcp, enabled: true, scope: effectiveScope },\n userScopePrompt: userPrompt,\n });\n\n this.printReport(report, cwd);\n }\n\n private async actionUninstall(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n options: Record<string, string>,\n ): Promise<void> {\n const from = (options.from as 'project' | 'user' | 'all') ?? 'project';\n if (!['project', 'user', 'all'].includes(from)) {\n console.log(pc.red('--from must be: project | user | all'));\n return;\n }\n const { removed } = await this.mcpService.uninstall({\n rootDir: cwd,\n agents,\n from,\n });\n if (removed.length === 0) {\n console.log(pc.gray(`Nothing to remove at scope \"${from}\".`));\n return;\n }\n console.log(pc.green(`ā
Removed agent-skills MCP entry from:`));\n for (const r of removed) {\n console.log(` - ${pc.cyan(r.agent)} ā ${pc.gray(r.file)}`);\n }\n }\n\n private async actionSnippets(\n config: SkillConfig,\n agents: Agent[],\n cwd: string,\n ): Promise<void> {\n const mcp = config.mcp ?? defaultMcpConfig();\n const report = await this.mcpService.install({\n rootDir: cwd,\n agents,\n mcp: { ...mcp, enabled: true, scope: 'snippets-only' },\n });\n if (report.snippets.length === 0) {\n console.log(\n pc.gray('No snippets generated (no supported agents in .skillsrc).'),\n );\n return;\n }\n console.log(pc.green(`ā
Generated ${report.snippets.length} snippet(s):`));\n for (const s of report.snippets) {\n console.log(` - ${pc.cyan(s.agent)} ā ${pc.gray(s.file)}`);\n }\n }\n\n // ---- output ----\n\n private printReport(\n report: Awaited<ReturnType<McpConfigService['install']>>,\n cwd: string,\n ): void {\n if (report.projectWrites.length > 0) {\n console.log(pc.bold('\\nš Project-scope writes:'));\n for (const w of report.projectWrites) {\n const tag =\n w.action === 'added'\n ? pc.green('+ added ')\n : w.action === 'updated'\n ? pc.cyan('~ updated ')\n : pc.gray('= up-to-date');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n }\n if (report.userWrites.length > 0) {\n console.log(pc.bold('\\nš User-scope writes:'));\n for (const w of report.userWrites) {\n console.log(\n ` ${pc.green('+ wrote ')} ${w.agent.padEnd(12)} ${pc.gray(path.relative(cwd, w.file))}`,\n );\n }\n }\n if (report.declined.length > 0) {\n console.log(pc.bold('\\nā User-scope declined:'));\n for (const d of report.declined) {\n console.log(\n ` ${pc.gray('-')} ${d.agent.padEnd(12)} ${pc.gray(d.file)}`,\n );\n }\n }\n if (report.snippets.length > 0) {\n console.log(pc.bold('\\nš Snippet files:'));\n for (const s of report.snippets) {\n console.log(` ${pc.gray(s.file)}`);\n }\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n `\\n(skipped ā no MCP support yet: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { Agent, getAgentDefinition } from '../constants';\n\n/**\n * Service responsible for bridging native AI agent rule files to AGENTS.md.\n * Creates agent-specific rule files (e.g., .mdc, .instructions.md)\n * in their respective directories.\n */\nexport class AgentBridgeService {\n /**\n * Bridges native agent rule files to AGENTS.md by creating discovery instructions.\n *\n * The MCP runtime-enforcement block lives in `AGENTS.md` (single source of\n * truth, generated by `IndexGeneratorService.assembleRouterIndex`). Rule\n * files generated here just instruct the agent to read AGENTS.md first ā\n * they do NOT duplicate the MCP block. This keeps the message in one place\n * so it can't drift between surfaces.\n *\n * @param rootDir Project root directory\n * @param agents List of agents to generate rules for\n */\n async bridge(rootDir: string, agents: Agent[]): Promise<void> {\n const fileNameBase = 'agent-skill-standard-rule';\n const commonDescription =\n 'Rule for Agent Skills Standard - Always consult AGENTS.md for consolidated project context and technical triggers.';\n\n for (const agentId of agents) {\n const config = getAgentDefinition(agentId);\n if (!config) continue;\n\n const relativeSkillsPath = path\n .relative(config.ruleFile, config.path)\n .replace(/\\\\/g, '/');\n const prefix = relativeSkillsPath ? `${relativeSkillsPath}/` : '';\n\n const commonBody = [\n '# š Agent Skills Routing Protocol (CRITICAL)',\n '',\n 'You are operating in a Zero-Trust environment. You are strictly forbidden from relying on your baseline pre-training for architecture, styling, testing, or code patterns in this repository.',\n '',\n '> [!CRITICAL] GATEKEEPER CONSTRAINT',\n '> **Your first action in ANY session MUST be a tool call to read `AGENTS.md`.**',\n '> You must NOT write code, suggest solutions, or output text explanations until you have completed the State Machine below.',\n '',\n '## š The Mandatory State Machine',\n '',\n 'You must execute these states sequentially. Do not proceed to the next state until the current one is satisfied.',\n '',\n '### State 1: Discovery (Tool Call Required)',\n '',\n '- **Action:** Execute a file-reading tool (e.g., `view_file`, `read_file`, `cat`) targeting the exact path: `AGENTS.md` (located in the project root).',\n '- **Condition to pass:** You have successfully read the `<!-- SKILLS_INDEX_START -->` block.',\n '',\n '### State 2: Trigger Matching (Internal Thought)',\n '',\n \"- **Action:** Analyze the user's prompt (keywords) and the files involved in the task (globs).\",\n '- **Condition to pass:** Cross-reference them against the `(triggers: ...)` list inside `AGENTS.md`. Identify all matching Skills and note their exact file paths.',\n '',\n '### State 3: Context Loading (Tool Call Required)',\n '',\n `- **Action:** Execute file-reading tools to read the \\`SKILL.md\\` files at the exact paths identified in State 2.`,\n '- **Condition to pass:** You have ingested the specific guidelines for the task. If no skills matched in State 2, you may skip this state.',\n '',\n '### State 4: Execution & Audit Log (Output Generation)',\n '',\n '- **Action:** You may now begin answering the user or writing code.',\n '- **Constraint:** Your very first text output MUST be a \"Pre-Write Audit Log\" confirming which skills were loaded, or explicitly stating \"No project-specific skills applicable.\"',\n '',\n '## Self-Learning Protocol',\n '',\n `At the end of any multi-step task with user corrections, load and run **[common/common-session-retrospective](${prefix}common/common-session-retrospective/SKILL.md)** to capture skill gaps and prevent repeat rework.`,\n '',\n ].join('\\n');\n\n // SAFETY: Only write if the agent is detected in the project\n // This prevents creating unused directories.\n let detected = false;\n for (const file of config.detectionFiles) {\n if (await fs.pathExists(path.join(rootDir, file))) {\n detected = true;\n break;\n }\n }\n\n if (!detected) continue;\n\n const ruleFilePath = path.join(\n rootDir,\n config.ruleFile,\n config.ruleFileName || `${fileNameBase}${config.ruleExtension}`,\n );\n\n // Ensure directory exists (e.g. .cursor/rules inside .cursor)\n await fs.ensureDir(path.dirname(ruleFilePath));\n\n let content = '';\n\n switch (config.frontmatterStyle) {\n case 'cursor':\n content += `---\\ndescription: ${commonDescription}\\nglobs: ['**/*']\\nalwaysApply: true\\n---\\n\\n`;\n break;\n case 'copilot':\n content += `---\\ndescription: ${commonDescription}\\napplyTo: '**/*'\\n---\\n\\n`;\n break;\n case 'none':\n // No frontmatter\n break;\n }\n\n const isClaude = agentId === Agent.Claude;\n\n if (isClaude) {\n const claudeProtocol = [\n '',\n '## Agent Protocol',\n '',\n 'See `AGENTS.md` for the Zero-Trust skill loading protocol (applies to all AI agents) and the MCP runtime-enforcement section (when enabled).',\n '',\n '## Self-Learning Protocol',\n '',\n `At the end of any multi-step task with user corrections, load and run **[common/common-session-retrospective](${prefix}common/common-session-retrospective/SKILL.md)** to capture skill gaps and prevent repeat rework.`,\n '',\n ].join('\\n');\n\n const claudePath = path.join(rootDir, 'CLAUDE.md');\n if (await fs.pathExists(claudePath)) {\n const existingContent = await fs.readFile(claudePath, 'utf8');\n if (\n existingContent &&\n !existingContent.includes('## Agent Protocol')\n ) {\n await fs.appendFile(claudePath, claudeProtocol);\n }\n } else {\n await fs.outputFile(claudePath, claudeProtocol.trimStart());\n }\n // Also write the full Zero-Trust rules to the rule directory if it's not the root\n // But for Claude, CLAUDE.md IS the rule file.\n // The user wants CLAUDE.md to refer to AGENTS.md.\n continue;\n }\n\n content += commonBody;\n\n await fs.outputFile(ruleFilePath, content);\n }\n }\n}\n","import { MetadataReader, SkillMetadata } from './MetadataReader';\n\n/**\n * Service for building the markdown content of AGENTS.md and _INDEX.md files.\n * Handles formatting, ordering, and template injection.\n */\nexport class IndexContentBuilder {\n private metadataReader: MetadataReader;\n\n constructor(metadataReader: MetadataReader) {\n this.metadataReader = metadataReader;\n }\n\n /**\n * Derives foundational composite IDs for a skill based on registry-owned naming rules.\n * Only applies to non-common skills. Deduplicates against explicit composites.\n */\n public deriveFoundationalComposites(\n category: string,\n skill: string,\n explicitComposites: string[],\n rules: Record<string, string[]>,\n ): string[] {\n if (category === 'common') return [];\n const derived: string[] = [];\n for (const [foundational, patterns] of Object.entries(rules)) {\n const matches = patterns.some((p) => skill.includes(p));\n if (matches && !explicitComposites.includes(foundational)) {\n derived.push(foundational);\n }\n }\n return derived;\n }\n\n /**\n * Formats a single skill into a list item for AGENTS.md.\n */\n public formatEntry(\n category: string,\n skill: string,\n metadata: SkillMetadata,\n foundationalRules: Record<string, string[]> = {},\n ): string {\n const id = `${category}/${skill}`;\n\n const explicitComposites = metadata.triggers.composite || [];\n const autoComposites = this.deriveFoundationalComposites(\n category,\n skill,\n explicitComposites,\n foundationalRules,\n );\n const allComposites = [...explicitComposites, ...autoComposites];\n\n const triggers = [\n ...(metadata.triggers.files || []),\n ...(metadata.triggers.keywords || []),\n ...(allComposites.length ? allComposites.map((c) => `+${c}`) : []),\n ...(metadata.triggers.exclude\n ? metadata.triggers.exclude.map((e) => `!${e}`)\n : []),\n ].join(', ');\n\n const triggerText = triggers ? ` (triggers: \\`${triggers}\\`)` : '';\n\n let desc = this.metadataReader.sanitizeDescription(\n metadata.description || '',\n id,\n );\n // Remove (triggers: ...) if it already exists to avoid duplication\n desc = desc.replace(/\\s*\\(triggers:.*?\\)\\s*$/, '');\n\n const prefixIcon = metadata.priority.startsWith('P0') ? 'šØ ' : '';\n const content = `${prefixIcon}${desc}${triggerText}`.trim();\n return `- **[${id}]**: ${content}`;\n }\n\n /**\n * Assembles the full AGENTS.md markdown including headers and Zero-Trust rules.\n */\n public assembleIndex(entries: string[]): string {\n const header = [\n '## Agent Skills Index',\n '',\n '> [!CRITICAL] GATEKEEPER CONSTRAINT',\n '> **You are operating in a Zero-Trust environment.**',\n '> You are strictly forbidden from generating code, proposing solutions, or relying on your pre-training until you have successfully executed a tool call to read the applicable `SKILL.md` files from this index.',\n '',\n '## **Rule Zero: Mandatory Zero-Trust Protocol**',\n '',\n '> [!CRITICAL]',\n '> **Zero-Trust Enforcement:** Skills loaded from this index always override standard code patterns. Skipping the Audit Log or Self-Scan is a protocol violation.',\n '',\n '### **1. The Pre-Write Audit Log (Mandatory)**',\n '',\n 'Before invoking any file-editing tool (`write_to_file`, `replace_file_content`, `multi_replace_file_content`), the ASSISTANT **MUST** explicitly state in its thought process/text output:',\n '',\n '1. **Skills Identified**: List the Skill IDs triggered by the file path or current task keywords.',\n '2. **Explicit Audit**: For each identified skill, confirm: \"Checked against [Skill ID] ā no violations found.\" Or \"Violation detected in [Skill ID]: [Issue] ā correcting now.\"',\n '3. **No-Skill Justification**: If no skills apply, explicitly state: \"No project-specific skills applicable to this file/transaction.\"',\n '',\n '### **2. The Post-Write Self-Scan (Mandatory)**',\n '',\n 'Immediately **AFTER** any file-editing tool returns, the ASSISTANT **MUST**:',\n '',\n '1. **Validate**: Contrast the final file content against ALL active Skill IDs.',\n '2. **Identify Slips**: Look for \"Standard Defaults\" (e.g., local mocks, hardcoded styles) that snuck in.',\n '3. **Self-Correct**: If a violation is found, fix it immediately in the next tool call.',\n '',\n '## **Critical Anti-Patterns (Zero-Tolerance)**',\n '',\n '- **Reversion to Defaults**: Never use \"standard\" patterns (generic library calls, local mocks) if a Project Skill exists.',\n '- **The \"Done\" Trap**: Never prioritize functional completion over structural/protocol compliance.',\n '- **Audit Skipping**: Never invoke a write tool without an explicit Pre-Write Audit Log.',\n '',\n '## ā” How to Find and Use This Index (Mandatory)',\n '',\n '> [!IMPORTANT] PATH RESOLUTION (Cross-Platform)',\n '> Skill IDs in the list below (e.g., `[category/skill-name]`) represent the relative folder path.',\n '> Because this project supports multiple AI agents, skills may reside in a base directory like `.gemini/skills/`, `.agents/skills/`, or `.cursor/skills/`.',\n '> **Action:** You must prepend the correct base directory to the ID. (Example: If ID is `[flutter/cicd]`, the file is at `<BASE_DIR>/flutter/cicd/SKILL.md`). Use your file search tools (e.g., `list_directory` or `find`) if you are unsure of the base directory.',\n '',\n '| Trigger Type | What to match | Required Action |',\n '| --- | --- | --- |',\n '| **File glob** (e.g. `**/*.ts`) | Files you are currently editing match the pattern | Call `view_file` on `<BASE_DIR>/[Skill ID]/SKILL.md` |',\n \"| **Keyword** (e.g. `auth`, `refactor`) | These words appear in the user\\\\'s request | Call `view_file` on `<BASE_DIR>/[Skill ID]/SKILL.md` |\",\n '| **Composite** (e.g. `+other/skill`) | Another listed skill is already active | Also load this skill via `view_file` |',\n '',\n '> [!TIP]',\n '> **Indirect phrasing still counts.** Match keywords by intent, not just exact words.',\n '> Examples: \"make it faster\" ā `performance`, \"broken query\" ā `database`, \"login flow\" ā `auth`, \"clean up this file\" ā `refactor`.',\n '',\n '### List of Available Skills',\n '',\n ].join('\\n');\n\n return `${header}\\n${entries.join('\\n')}\\n`;\n }\n}\n","/**\n * Subset of the registry's metadata.json that the IndexGeneratorService needs at\n * index-generation time. Provided by the caller (e.g. SyncService) so the file\n * never needs to be written to disk inside the user's project.\n */\nexport interface RemoteMetadata {\n file_routing?: Record<string, string[]>;\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n foundational_composite_rules?: Record<string, string[]>;\n}\n\n/**\n * Metadata structure for a skill, extracted from the frontmatter and content of a SKILL.md file.\n */\nexport interface SkillMetadata {\n /** The human-readable name of the skill. */\n name: string;\n /** A brief summary of what the skill covers. */\n description: string;\n /** The priority level (e.g., P0, P1) determining its critical importance. */\n priority: string;\n /** Trigger conditions for when this skill should be activated. */\n triggers: {\n /** Glob patterns of files that trigger this skill. */\n files?: string[];\n /** List of keywords that trigger this skill. */\n keywords?: string[];\n /** Other skill IDs that, when active, also trigger this skill. */\n composite?: string[];\n /** Patterns to explicitly exclude from triggering this skill. */\n exclude?: string[];\n };\n}\n\n/**\n * Interface definition for IndexGeneratorService.\n */\nexport abstract class IndexGeneratorService {\n abstract withMetadata(metadata: RemoteMetadata): this;\n\n abstract generate(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<string>;\n\n abstract generateCategoryIndex(\n baseDir: string,\n category: string,\n ): Promise<string>;\n\n abstract generateAllCategoryIndices(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<Record<string, string>>;\n\n abstract assembleRouterIndex(\n baseDir: string,\n allowedCategories?: string[],\n mcpEnabled?: boolean,\n ): Promise<string>;\n\n abstract assembleIndex(entries: string[]): string;\n\n abstract sanitizeDescription(desc: string, skillId?: string): string;\n}\n","/**\n * Centralized patterns for detecting and sanitizing prompt injection.\n * Shared between the CLI and CI scanning scripts.\n */\n\nexport const INJECTION_PATTERNS: RegExp[] = [\n /ignore\\s+(?:all\\s+|previous\\s+|prior\\s+)*(?:instructions?|rules?|guidance)/gi,\n /you\\s+(?:must|should|shall|will)\\s+(?:now|immediately)\\b/gi,\n /^(?:system|user|assistant)\\s*:/gim,\n /(?:^|\\n)\\s*-{3,}\\s*(?:\\n|$)/g,\n /<(?:script|iframe|style)[^>]*\\s*>[\\s\\S]*?<\\/(?:script|iframe|style)[^>]*\\s*>/gi,\n];\n","import fs from 'fs-extra';\nimport yaml from 'js-yaml';\nimport path from 'path';\nimport { INJECTION_PATTERNS } from '../constants/security';\n\n/**\n * Subset of the registry's metadata.json that the IndexGeneratorService needs at\n * index-generation time. Provided by the caller (e.g. SyncService) so the file\n * never needs to be written to disk inside the user's project.\n */\nexport interface RemoteMetadata {\n file_routing?: Record<string, string[]>;\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n foundational_composite_rules?: Record<string, string[]>;\n}\n\n/**\n * Metadata structure for a skill, extracted from the frontmatter and content of a SKILL.md file.\n */\nexport interface SkillMetadata {\n /** The human-readable name of the skill. */\n name: string;\n /** A brief summary of what the skill covers. */\n description: string;\n /** The priority level (e.g., P0, P1) determining its critical importance. */\n priority: string;\n /** Trigger conditions for when this skill should be activated. */\n triggers: {\n /** Glob patterns of files that trigger this skill. */\n files?: string[];\n /** List of keywords that trigger this skill. */\n keywords?: string[];\n /** Other skill IDs that, when active, also trigger this skill. */\n composite?: string[];\n /** Patterns to explicitly exclude from triggering this skill. */\n exclude?: string[];\n };\n}\n\n/**\n * Service for loading and providing consolidated metadata for index generation.\n * Handles both remote-injected metadata and local file-system fallbacks.\n */\nexport class MetadataReader {\n private remoteMetadata?: RemoteMetadata;\n\n constructor(remote?: RemoteMetadata) {\n this.remoteMetadata = remote;\n }\n\n /**\n * Loads foundational composite rules. Uses injected remote metadata when available;\n * falls back to reading metadata.json from baseDir.\n */\n async loadFoundationalRules(\n baseDir: string,\n ): Promise<Record<string, string[]>> {\n if (this.remoteMetadata?.foundational_composite_rules !== undefined) {\n return this.remoteMetadata.foundational_composite_rules;\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n foundational_composite_rules?: Record<string, string[]>;\n };\n return parsed.foundational_composite_rules ?? {};\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[MetadataReader] Failed to load foundational rules: ${error}`,\n );\n }\n }\n return {};\n }\n\n /**\n * Loads file routing rules. Uses injected remote metadata when available;\n * falls back to reading metadata.json from baseDir.\n */\n async loadFileRouting(baseDir: string): Promise<Record<string, string[]>> {\n if (this.remoteMetadata?.file_routing !== undefined) {\n return this.remoteMetadata.file_routing;\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n file_routing?: Record<string, string[]>;\n };\n return parsed.file_routing ?? {};\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[MetadataReader] Failed to load file routing: ${error}`);\n }\n }\n return {};\n }\n\n /**\n * Loads broad glob patterns and base language skill mappings. Uses injected remote\n * metadata when available; falls back to reading metadata.json from baseDir.\n */\n async loadTierConfig(baseDir: string): Promise<{\n broadGlobs: string[];\n baseSkills: Record<string, string>;\n }> {\n if (this.remoteMetadata !== undefined) {\n return {\n broadGlobs: this.remoteMetadata.broad_globs ?? [],\n baseSkills: this.remoteMetadata.base_language_skills ?? {},\n };\n }\n try {\n const metaPath = path.join(baseDir, 'metadata.json');\n if (await fs.pathExists(metaPath)) {\n const raw = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(raw) as {\n broad_globs?: string[];\n base_language_skills?: Record<string, string>;\n };\n return {\n broadGlobs: parsed.broad_globs ?? [],\n baseSkills: parsed.base_language_skills ?? {},\n };\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`[MetadataReader] Failed to load tier config: ${error}`);\n }\n }\n return { broadGlobs: [], baseSkills: {} };\n }\n\n /**\n * Parses a SKILL.md file to extract its metadata (frontmatter + priority).\n */\n async parseSkill(skillPath: string): Promise<SkillMetadata | null> {\n try {\n const content = await fs.readFile(skillPath, 'utf8');\n const frontmatterMatch = content.match(\n /^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n([\\s\\S]*)$/,\n );\n\n if (!frontmatterMatch) return null;\n\n const fm = yaml.load(frontmatterMatch[1]) as Record<string, unknown>;\n const body = frontmatterMatch[2];\n\n const priorityMatch = body.match(/## \\*\\*Priority:\\s*([^*]+)\\*\\*/);\n const priority = priorityMatch ? priorityMatch[1].trim() : 'P1';\n\n const metadata = (fm?.metadata || {}) as Record<string, unknown>;\n const rawTriggers = (metadata?.triggers || {}) as Record<string, unknown>;\n\n const triggers: {\n files?: string[];\n keywords?: string[];\n composite?: string[];\n exclude?: string[];\n } = {\n files: Array.isArray(rawTriggers.files)\n ? (rawTriggers.files as string[])\n : [],\n keywords: Array.isArray(rawTriggers.keywords)\n ? (rawTriggers.keywords as string[])\n : [],\n composite: Array.isArray(rawTriggers.composite)\n ? (rawTriggers.composite as string[])\n : [],\n exclude: Array.isArray(rawTriggers.exclude)\n ? (rawTriggers.exclude as string[])\n : [],\n };\n\n const hasStructured =\n (triggers.files?.length || 0) > 0 ||\n (triggers.keywords?.length || 0) > 0;\n const description =\n typeof fm.description === 'string' ? fm.description : '';\n\n if (!hasStructured && description) {\n const descTrigs = description.match(/\\(triggers:\\s*`?(.*?)`?\\)\\s*$/);\n if (descTrigs) {\n const rawParts = descTrigs[1].split(',');\n const parts: string[] = [];\n let current = '';\n let braceCount = 0;\n\n for (let i = 0; i < rawParts.length; i++) {\n const p = rawParts[i];\n braceCount += (p.match(/{/g) || []).length;\n braceCount -= (p.match(/}/g) || []).length;\n current += (current ? ',' : '') + p;\n\n if (braceCount === 0) {\n parts.push(current.trim());\n current = '';\n }\n }\n if (current) parts.push(current.trim());\n\n const files = parts.filter(\n (p) =>\n p.includes('*') ||\n p.includes('/') ||\n p.includes('{') ||\n /\\.\\w+$/.test(p),\n );\n const keywords = parts.filter(\n (p) =>\n !p.includes('*') &&\n !p.includes('/') &&\n !p.includes('{') &&\n !/\\.\\w+$/.test(p),\n );\n\n if (files.length > 0) triggers.files = files;\n if (keywords.length > 0) triggers.keywords = keywords;\n }\n }\n\n return {\n name: typeof fm.name === 'string' ? fm.name : '',\n description,\n priority,\n triggers,\n };\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(\n `[MetadataReader] Failed to parse skill at ${skillPath}: ${error}`,\n );\n }\n return null;\n }\n }\n\n /**\n * Sanitizes a skill description to prevent indirect prompt injection.\n */\n sanitizeDescription(desc: string, skillId: string = 'unknown'): string {\n let sanitized = desc;\n let wasModified = false;\n\n for (const pattern of INJECTION_PATTERNS) {\n if (pattern.test(sanitized)) {\n wasModified = true;\n sanitized = sanitized.replace(pattern, '[REDACTED]');\n }\n pattern.lastIndex = 0;\n }\n\n if (wasModified) {\n process.stderr.write(\n `[SECURITY] Prompt injection pattern stripped from skill description: ${skillId}\\n`,\n );\n }\n\n return sanitized;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { IndexContentBuilder } from './IndexContentBuilder';\nimport { IndexGeneratorService, RemoteMetadata } from './IndexGeneratorService';\nimport { MetadataReader } from './MetadataReader';\n\n/**\n * Enhanced IndexGeneratorService that delegates to MetadataReader and IndexContentBuilder.\n * Maintains compatibility with existing callers.\n */\nexport class IndexGeneratorServiceImpl extends IndexGeneratorService {\n private reader: MetadataReader;\n private builder: IndexContentBuilder;\n\n constructor(remoteMetadata?: RemoteMetadata) {\n super();\n this.reader = new MetadataReader(remoteMetadata);\n this.builder = new IndexContentBuilder(this.reader);\n }\n\n /** Overridable metadata injection */\n withMetadata(metadata: RemoteMetadata): this {\n this.reader = new MetadataReader(metadata);\n this.builder = new IndexContentBuilder(this.reader);\n return this;\n }\n\n async generate(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<string> {\n const entries = new Set<string>();\n const foundationalRules = await this.reader.loadFoundationalRules(baseDir);\n\n if (!(await fs.pathExists(baseDir))) return this.assembleIndex([]);\n\n let categories = await fs.readdir(baseDir);\n categories = categories.filter((category) => {\n if (category.startsWith('.')) return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(category) &&\n category !== 'common'\n ) {\n return false;\n }\n return true;\n });\n\n categories.sort();\n\n for (const category of categories) {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.stat(categoryPath)).isDirectory()) continue;\n\n const skills = await fs.readdir(categoryPath);\n skills.sort();\n for (const skill of skills) {\n const skillPath = path.join(categoryPath, skill, 'SKILL.md');\n const isRegistrySkill = await fs.pathExists(skillPath);\n const isStandaloneSkill =\n !isRegistrySkill &&\n skill.endsWith('.md') &&\n skill !== '_INDEX.md' &&\n !(await fs.stat(path.join(categoryPath, skill))).isDirectory();\n\n const targetPath = isRegistrySkill\n ? skillPath\n : path.join(categoryPath, skill);\n if (!isRegistrySkill && !isStandaloneSkill) continue;\n\n const metadata = await this.reader.parseSkill(targetPath);\n if (metadata) {\n const skillId = isStandaloneSkill ? skill.replace('.md', '') : skill;\n const entry = this.builder.formatEntry(\n category,\n skillId,\n metadata,\n foundationalRules,\n );\n entries.add(entry);\n }\n }\n }\n\n return this.assembleIndex(Array.from(entries));\n }\n\n public assembleIndex(entries: string[]): string {\n return this.builder.assembleIndex(entries);\n }\n\n /**\n * Sanitizes a skill description to prevent indirect prompt injection.\n */\n public sanitizeDescription(\n desc: string,\n skillId: string = 'unknown',\n ): string {\n return this.reader.sanitizeDescription(desc, skillId);\n }\n\n /**\n * Generates all _INDEX.md files for categories found in baseDir.\n */\n async generateAllCategoryIndices(\n baseDir: string,\n allowedCategories?: string[],\n ): Promise<Record<string, string>> {\n if (!(await fs.pathExists(baseDir))) return {};\n\n let categories = await fs.readdir(baseDir);\n categories = categories.filter((c) => {\n if (c.startsWith('.') || c === '_INDEX.md') return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(c) &&\n c !== 'common'\n ) {\n return false;\n }\n return true;\n });\n categories.sort();\n\n const result: Record<string, string> = {};\n for (const category of categories) {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.stat(categoryPath)).isDirectory()) continue;\n\n const index = await this.generateCategoryIndex(baseDir, category);\n if (index) result[category] = index;\n }\n return result;\n }\n\n async generateCategoryIndex(\n baseDir: string,\n category: string,\n ): Promise<string> {\n const categoryPath = path.join(baseDir, category);\n if (!(await fs.pathExists(categoryPath))) return '';\n\n const { broadGlobs, baseSkills } =\n await this.reader.loadTierConfig(baseDir);\n const baseSkillForCategory = baseSkills[category];\n\n const entries = await fs.readdir(categoryPath);\n entries.sort();\n\n const fileMatchRows: string[] = [];\n const keywordMatchRows: string[] = [];\n\n for (const entryName of entries) {\n if (entryName.startsWith('.') || entryName === '_INDEX.md') continue;\n\n const skillPath = path.join(categoryPath, entryName, 'SKILL.md');\n const isRegistrySkill = await fs.pathExists(skillPath);\n const isStandaloneSkill =\n !isRegistrySkill &&\n entryName.endsWith('.md') &&\n !(await fs.stat(path.join(categoryPath, entryName))).isDirectory();\n\n if (!isRegistrySkill && !isStandaloneSkill) continue;\n\n const targetPath = isRegistrySkill\n ? skillPath\n : path.join(categoryPath, entryName);\n const skillId = isStandaloneSkill\n ? entryName.replace('.md', '')\n : entryName;\n\n const metadata = await this.reader.parseSkill(targetPath);\n if (!metadata) continue;\n\n const isBaseSkill = skillId === baseSkillForCategory;\n const allFiles = metadata.triggers.files || [];\n const kwTrigs = (metadata.triggers.keywords || []).join(', ') || 'ā';\n const prefix = metadata.priority.startsWith('P0') ? '**' : '';\n const suffix = prefix ? '**' : '';\n\n const specificFiles = allFiles.filter((f) => !broadGlobs.includes(f));\n const hasBroadGlob = allFiles.some((f) => broadGlobs.includes(f));\n\n if (isBaseSkill || (specificFiles.length > 0 && !hasBroadGlob)) {\n const displayFiles = isBaseSkill\n ? allFiles.map((f) => `\\`${f}\\``).join(', ')\n : specificFiles.map((f) => `\\`${f}\\``).join(', ');\n fileMatchRows.push(\n `| ${prefix}${skillId}${suffix} | ${displayFiles || 'ā'} | ${kwTrigs} |`,\n );\n } else if (specificFiles.length > 0 && hasBroadGlob) {\n const displayFiles = specificFiles.map((f) => `\\`${f}\\``).join(', ');\n fileMatchRows.push(\n `| ${prefix}${skillId}${suffix} | ${displayFiles} | ${kwTrigs} |`,\n );\n } else {\n keywordMatchRows.push(`| ${prefix}${skillId}${suffix} | ${kwTrigs} |`);\n }\n }\n\n if (fileMatchRows.length === 0 && keywordMatchRows.length === 0) return '';\n\n const lines = [\n `<!-- AUTO-GENERATED from SKILL.md frontmatters ā do not edit manually -->`,\n `# ${category} Skills Index`,\n '',\n ];\n\n if (fileMatchRows.length > 0) {\n lines.push(\n `## File Match (auto-check against the file you are editing)`,\n '',\n '| Skill | File pattern | Keywords |',\n '| ----- | ------------ | -------- |',\n ...fileMatchRows,\n '',\n );\n }\n\n if (keywordMatchRows.length > 0) {\n lines.push(\n `## Keyword Match (only when user's request mentions these)`,\n '',\n '| Skill | Match when user mentions |',\n '| ----- | ----------------------- |',\n ...keywordMatchRows,\n '',\n );\n }\n\n lines.push(\n `> Load matched skills: \\`<SKILLS>/${category}/<skill>/SKILL.md\\`. Load ALL that match ā the tier model already filters irrelevant ones.`,\n '',\n );\n\n return lines.join('\\n');\n }\n\n async assembleRouterIndex(\n baseDir: string,\n allowedCategories?: string[],\n mcpEnabled: boolean = false,\n ): Promise<string> {\n const fileRouting = await this.reader.loadFileRouting(baseDir);\n\n let availableCategories: string[] = [];\n if (await fs.pathExists(baseDir)) {\n const dirs = await fs.readdir(baseDir);\n availableCategories = dirs.filter((d) => {\n if (d.startsWith('.') || d === '_INDEX.md') return false;\n if (\n allowedCategories &&\n !allowedCategories.includes(d) &&\n d !== 'common'\n ) {\n return false;\n }\n return true;\n });\n }\n\n const routerRows: string[] = [];\n const coveredCategories = new Set<string>();\n\n const extGrouped = new Map<string, string[]>();\n for (const [ext, cats] of Object.entries(fileRouting)) {\n if (ext === '_comment') continue;\n const filtered = cats.filter((c: string) =>\n availableCategories.includes(c),\n );\n if (filtered.length === 0) continue;\n\n const key = filtered.sort().join('+');\n if (!extGrouped.has(key)) extGrouped.set(key, []);\n extGrouped.get(key)!.push(ext);\n filtered.forEach((c) => coveredCategories.add(c));\n }\n\n const formatRouterPattern = (ext: string): string => {\n if (ext.startsWith('_')) return `\\`*${ext}\\``;\n return `\\`*.${ext}\\``;\n };\n\n for (const [catKey, exts] of extGrouped) {\n const cats = catKey.split('+');\n const extDisplay = exts.map((e) => formatRouterPattern(e)).join(', ');\n const catDisplay = cats\n .map((c) => `\\`<SKILLS>/${c}/_INDEX.md\\``)\n .join(', ');\n routerRows.push(`| ${extDisplay} | ${catDisplay} |`);\n }\n\n if (availableCategories.includes('common')) {\n coveredCategories.add('common');\n routerRows.push(\n '| Any file (keyword match) | `<SKILLS>/common/_INDEX.md` |',\n );\n }\n\n if (availableCategories.includes('quality-engineering')) {\n coveredCategories.add('quality-engineering');\n routerRows.push(\n '| QE workflow | `<SKILLS>/quality-engineering/_INDEX.md` |',\n );\n }\n\n // The MCP block is always present (not conditional on .skillsrc.mcp.enabled)\n // because:\n // 1. .skillsrc.mcp.enabled records CLI consent to manage configs ā it's\n // orthogonal to whether the MCP is actually registered at runtime.\n // 2. A user can manually register the MCP in their runtime config without\n // ever touching .skillsrc; we don't want AGENTS.md to be silent about\n // it in that case.\n // 3. The AI can self-check via its tool list before calling ā the\n // \"If ... is registered\" phrasing makes the instruction correct in\n // both states.\n // 4. Tooltip-only ā when `mcpEnabled` is true (CLI-managed), we\n // add a confirmation note that this project ships with MCP support.\n const mcpStatusNote = mcpEnabled\n ? '> [!TIP] **This project has the MCP server enabled in `.skillsrc`** ā `sync` keeps your runtime configs in step. Run `ags mcp status` to verify per-agent installation.'\n : '> [!NOTE] To enable MCP-managed installs in this project, run `ags mcp enable` (or edit `.skillsrc`). The MCP works fine if you registered it manually too.';\n\n const mcpBlock = [\n '## š Runtime Enforcement via MCP',\n '',\n \"If the `agent-skills-standard` MCP server is registered in your runtime (check your tool list ā look for `load_skills_for_files`), **prefer those tools over manually walking the router below**. The MCP returns identical content but is auditable AND inherited by sub-agents that don't see this file.\",\n '',\n '| Tool | When to call it |',\n '| --- | --- |',\n '| `list_workflows()` | At the start of any task or session to discover available standard operating procedures |',\n '| `get_workflow(name)` | Once a relevant workflow is identified to retrieve exact step-by-step instructions |',\n '| `load_skills_for_files(files=[...])` | Before editing/reviewing any source file |',\n '| `load_skills_for_keywords(keywords=[...])` | Planning before files are chosen |',\n '| `get_skill(category, name)` | Direct lookup when you know the skill id |',\n '| `audit_session_compliance()` | Before declaring a task complete |',\n '',\n \"> [!IMPORTANT] **Sub-agents don't inherit this `AGENTS.md` ā they do inherit the MCP.** If you delegate work to a sub-agent, instruct it to call the MCP tools above as its first action.\",\n '',\n mcpStatusNote,\n '',\n 'If `load_skills_for_files` is **not** in your tool list, the MCP is not registered ā fall back to the router table below.',\n '',\n '---',\n '',\n ].join('\\n');\n\n const header = [\n '## Agent Skills Index',\n '',\n '> [!CRITICAL] Zero-Trust: Read the matching `SKILL.md` BEFORE writing any code.',\n '> Skills from this index override pre-training patterns. If no skill matches, state: \"No project-specific skills applicable.\"',\n '',\n '> š” **Global Token Optimization**: If the `rtk` CLI tool is installed, actively prepend it to verbose development commands (e.g. `rtk npm test`, `rtk grep`). If the `caveman` skill is available or requested, use `/caveman` mode for reporting.',\n '',\n mcpBlock,\n '## Skill Resolution Protocol',\n '',\n 'Each `_INDEX.md` has two sections - follow both:',\n '',\n '1. **Match file type** -> find the category index in the router table below.',\n '2. **Read the `_INDEX.md`** -> it has two sections:',\n ' - **File Match**: auto-check these against the file you are editing (path pattern match).',\n \" - **Keyword Match**: only check if the user's request mentions these concepts.\",\n '3. **Load ALL matched `SKILL.md`** -> read every matched skill before writing code. The tier model keeps matches focused.',\n '',\n \"> `<SKILLS>` = your agent's skill directory (e.g., `.claude/skills/`, `.cursor/skills/`, `.gemini/skills/`).\",\n '',\n '| File type | Read category index |',\n '| --------- | ------------------- |',\n ...routerRows,\n '',\n '> [!NOTE] **Test/spec file precedence:** `.spec.ts`, `.test.ts` -> use the `common` row (takes precedence over the generic `*.ts` row). `.spec.tsx`, `.test.tsx` -> use the `react` row (takes precedence over the generic `*.tsx` row).',\n '',\n '> [!TIP] **Indirect phrasing counts.** \"make it faster\" -> performance, \"broken query\" -> database, \"login flow\" -> auth.',\n '',\n ].join('\\n');\n\n return header;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig, SkillEntry } from '../models/config';\nimport { CollectedSkill, GitHubTreeItem } from '../models/types';\nimport { GithubService } from './GithubService';\n\n/**\n * Service responsible for synchronizing agent skills from a remote registry.\n */\nexport class SkillSyncService {\n constructor(private githubService: GithubService) {}\n\n /**\n * Assembles skills from the remote registry based on provided categories and configuration.\n */\n async assembleSkills(\n categories: string[],\n config: SkillConfig,\n ): Promise<CollectedSkill[]> {\n const collected: CollectedSkill[] = [];\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n\n if (!githubMatch) {\n console.log(pc.red('Error: Only GitHub registries supported.'));\n return [];\n }\n\n const { owner, repo } = githubMatch;\n\n for (const category of categories) {\n const catConfig = config.skills[category];\n const ref = catConfig.ref || 'main';\n\n console.log(pc.gray(` - Discovering ${category} (${ref})...`));\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) {\n console.log(pc.red(` ā Failed to fetch ${category}@${ref}.`));\n continue;\n }\n\n const foldersToSync = this.identifyFoldersToSync(\n category,\n catConfig,\n treeData.tree,\n );\n\n for (const absOrRelSkill of foldersToSync) {\n const skill = await this.fetchSkill(\n owner,\n repo,\n ref,\n category,\n absOrRelSkill,\n treeData.tree,\n );\n if (skill) collected.push(skill);\n }\n }\n\n return collected;\n }\n\n /**\n * Writes collected skills to target agent paths.\n */\n async writeSkills(\n skills: CollectedSkill[],\n config: SkillConfig,\n agents: Agent[],\n ) {\n const overrides = config.custom_overrides || [];\n\n // Group skills by category to know which folders to prune\n const fetchedSkillsByCategory: Record<string, Set<string>> = {};\n for (const skill of skills) {\n if (!fetchedSkillsByCategory[skill.category]) {\n fetchedSkillsByCategory[skill.category] = new Set();\n }\n fetchedSkillsByCategory[skill.category].add(skill.skill);\n }\n\n for (const agentId of agents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || !agentDef.path) continue;\n\n const basePath = agentDef.path;\n await fs.ensureDir(basePath);\n\n // Clean up orphaned skills inside categories we are syncing\n // Default to prune: true if not specified\n const shouldPrune = config.prune !== false;\n\n if (shouldPrune) {\n for (const category of Object.keys(fetchedSkillsByCategory)) {\n const categoryPath = path.join(basePath, category);\n if (await fs.pathExists(categoryPath)) {\n const existingDirs = await fs.readdir(categoryPath);\n for (const dir of existingDirs) {\n // If the folder is not in the newly fetched list, it might be orphaned\n if (!fetchedSkillsByCategory[category].has(dir)) {\n const fullPath = path.join(categoryPath, dir);\n // Do not delete if it's protected by custom_overrides\n if (!this.isOverridden(fullPath, overrides)) {\n await fs.remove(fullPath);\n }\n }\n }\n }\n }\n }\n\n for (const skill of skills) {\n await this.writeSkillForAgent(agentId, skill, overrides, basePath);\n }\n console.log(pc.gray(` - Updated ${basePath}/ (${agentDef.name})`));\n }\n }\n\n private async writeSkillForAgent(\n agentId: string,\n skill: CollectedSkill,\n overrides: string[],\n basePath: string,\n ) {\n const isKiro = agentId === Agent.Kiro;\n const kiroFolder = `${skill.category}-${skill.skill}`;\n const skillPath = isKiro\n ? path.join(basePath, kiroFolder)\n : path.join(basePath, skill.category, skill.skill);\n\n await fs.ensureDir(skillPath);\n\n for (const fileItem of skill.files) {\n const targetFilePath = path.join(skillPath, fileItem.name);\n\n if (this.isOverridden(targetFilePath, overrides)) {\n console.log(\n pc.yellow(\n ` ā ļø Skipping overridden: ${this.normalizePath(targetFilePath)}`,\n ),\n );\n continue;\n }\n\n if (!this.isPathSafe(targetFilePath, skillPath)) {\n console.log(\n pc.red(` ā Security Error: Invalid path ${fileItem.name}`),\n );\n continue;\n }\n\n let content = fileItem.content;\n if (isKiro && fileItem.name === 'SKILL.md') {\n content = this.transformSkillForKiro(content, skill.category);\n }\n\n await fs.outputFile(targetFilePath, content);\n }\n }\n\n private async fetchSkill(\n owner: string,\n repo: string,\n ref: string,\n category: string,\n absOrRelSkill: string,\n tree: GitHubTreeItem[],\n ): Promise<CollectedSkill | null> {\n const [sourceCat, skillName] = absOrRelSkill.includes('/')\n ? absOrRelSkill.split('/')\n : [category, absOrRelSkill];\n\n const prefix = `skills/${sourceCat}/${skillName}/`;\n const skillSourceFiles = tree.filter(\n (f) => f.path.startsWith(prefix) && f.type === 'blob',\n );\n\n const downloadTasks = skillSourceFiles\n .filter((f) => {\n const rel = f.path.replace(prefix, '');\n return rel === 'SKILL.md' || /^(references|scripts|assets)\\//.test(rel);\n })\n .map((f) => ({ owner, repo, ref, path: f.path }));\n\n const files =\n await this.githubService.downloadFilesConcurrent(downloadTasks);\n if (files.length === 0) return null;\n\n console.log(\n pc.gray(\n ` + Fetched ${sourceCat}/${skillName} (${files.length} files)`,\n ),\n );\n\n return {\n category: sourceCat,\n skill: skillName,\n files: files.map((f) => ({\n name: f.path.replace(prefix, ''),\n content: f.content,\n })),\n };\n }\n\n private identifyFoldersToSync(\n category: string,\n catConfig: SkillEntry,\n tree: GitHubTreeItem[],\n ): string[] {\n const skillFolders = new Set(\n tree\n .filter((f) => f.path.startsWith(`skills/${category}/`))\n .map((f) => f.path.split('/')[2])\n .filter(Boolean),\n );\n\n const folders = Array.from(skillFolders).filter((folder) => {\n if (catConfig.include && !catConfig.include.includes(folder))\n return false;\n if (catConfig.exclude && catConfig.exclude.includes(folder)) return false;\n return true;\n });\n\n if (catConfig.include) {\n catConfig.include\n .filter((i) => i.includes('/'))\n .forEach((absSkill) =>\n this.expandAbsoluteInclude(absSkill, folders, tree),\n );\n }\n\n return folders;\n }\n\n private expandAbsoluteInclude(\n absSkill: string,\n folders: string[],\n tree: GitHubTreeItem[],\n ) {\n const [targetCat, targetSkill] = absSkill.split('/');\n if (!targetCat || !targetSkill) return;\n\n if (targetSkill === '*') {\n const catSkills = new Set(\n tree\n .filter((f) => f.path.startsWith(`skills/${targetCat}/`))\n .map((f) => f.path.split('/')[2])\n .filter(Boolean),\n );\n\n catSkills.forEach((s) => {\n const fullPath = `${targetCat}/${s}`;\n if (!folders.includes(fullPath)) folders.push(fullPath);\n });\n } else if (!folders.includes(absSkill)) {\n if (\n tree.some((f) =>\n f.path.startsWith(`skills/${targetCat}/${targetSkill}/`),\n )\n ) {\n folders.push(absSkill);\n } else {\n console.log(\n pc.yellow(\n ` ā ļø Absolute include ${absSkill} not found in repository.`,\n ),\n );\n }\n }\n }\n\n private transformSkillForKiro(content: string, category: string): string {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---/);\n if (!frontmatterMatch) return content;\n\n const [fullMatch, frontmatter] = frontmatterMatch;\n const body = content.slice(fullMatch.length);\n\n const name = frontmatter.match(/^name:\\s*(.+)$/m)?.[1].trim() || '';\n const description =\n frontmatter.match(/^description:\\s*(.+)$/m)?.[1].trim() || '';\n const displayName = `${category.charAt(0).toUpperCase() + category.slice(1)} - ${name}`;\n\n return `---\\nname: ${displayName}\\ndescription: ${description}\\n---` + body;\n }\n\n private isOverridden(targetPath: string, overrides: string[]): boolean {\n const rel = this.normalizePath(targetPath);\n return overrides.some((o) => {\n const op = o.replace(/\\\\/g, '/').replace(/\\/$/, '');\n return (\n rel === op ||\n rel.startsWith(`${op}/`) ||\n rel.includes(`/${op}/`) ||\n rel.endsWith(`/${op}`)\n );\n });\n }\n\n private isPathSafe(targetPath: string, skillPath: string): boolean {\n const resolvedBase = path.resolve(skillPath) + path.sep;\n return path.resolve(targetPath).startsWith(resolvedBase);\n }\n\n private normalizePath(p: string): string {\n return path.relative(process.cwd(), p).replace(/\\\\/g, '/');\n }\n}\n","import { WorkflowFormat } from '../../constants';\n\ninterface WorkflowSource {\n /** Original filename (e.g., 'code-review.md') */\n name: string;\n /** Raw markdown content from .agents/workflows/ */\n content: string;\n}\n\nexport interface ParsedWorkflow {\n /** Workflow key without extension (e.g., 'code-review') */\n key: string;\n /** Original filename with extension (e.g., 'code-review.md') */\n fileName: string;\n /** Description parsed from frontmatter if present */\n description: string;\n /** Workflow markdown body (frontmatter removed) */\n body: string;\n /** Original raw workflow markdown content */\n rawContent: string;\n}\n\ninterface TransformedWorkflow {\n /** Target filename for the agent */\n name: string;\n /** Transformed content in the agent's native format */\n content: string;\n}\n\n/**\n * Transforms workflow markdown into each agent's native user-invoked command format.\n *\n * Workflows are NOT rules or agents ā they are multi-step procedures the user\n * explicitly invokes (e.g., \"run code-review\"). Each agent has a different mechanism:\n *\n * - native: Keep as-is in .agents/workflows/ (Antigravity, Kiro)\n * - command: Claude Code custom slash command (.claude/commands/*.md)\n * User invokes via /command-name. Supports $ARGUMENTS for parameters.\n * - toml: Gemini CLI command file (.gemini/commands/*.toml)\n * Points to the .agents/workflows/ source via a prompt field.\n * - prompt: Copilot reusable prompt file (.github/prompts/*.prompt.md)\n * User invokes via /prompt-name in Copilot chat.\n * - none: Agent has no verified user-invoked command system ā skip.\n */\nexport class WorkflowTransformer {\n static parse(source: WorkflowSource): ParsedWorkflow {\n const { description, body } = this.parseSource(source.content);\n const key = source.name.replace(/\\.md$/, '');\n return {\n key,\n fileName: source.name,\n description,\n body,\n rawContent: source.content,\n };\n }\n\n static transform(\n source: WorkflowSource,\n format: WorkflowFormat,\n workflowSourcePath: string = '.agents/workflows',\n ): TransformedWorkflow | null {\n const parsed = this.parse(source);\n return this.transformParsed(parsed, format, workflowSourcePath);\n }\n\n static transformParsed(\n parsed: ParsedWorkflow,\n format: WorkflowFormat,\n workflowSourcePath: string = '.agents/workflows',\n ): TransformedWorkflow | null {\n if (format === 'none') return null;\n\n const { description, body } = parsed;\n const baseName = parsed.key;\n\n switch (format) {\n case 'native':\n return { name: parsed.fileName, content: parsed.rawContent };\n\n case 'command':\n return {\n name: `${baseName}.md`,\n content: this.toMarkdownCommand(baseName, description, body),\n };\n\n case 'toml':\n return {\n name: `${baseName}.toml`,\n content: this.toGeminiCommand(\n baseName,\n description,\n workflowSourcePath,\n ),\n };\n\n case 'prompt':\n return {\n name: `${baseName}.prompt.md`,\n content: this.toCopilotPrompt(description, body),\n };\n\n case 'skill':\n return {\n name: 'SKILL.md',\n content: this.toSkillMarkdown(baseName, description, body),\n };\n }\n }\n\n private static parseSource(content: string): {\n description: string;\n body: string;\n } {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n if (!match) return { description: '', body: content };\n\n const descMatch = match[1].match(/description:\\s*(.+)/);\n return {\n description: descMatch ? descMatch[1].trim() : '',\n body: match[2],\n };\n }\n\n /**\n * Markdown-based custom slash command format.\n * Used by Claude Code (.claude/commands/), Roo Code (.roo/commands/), and OpenCode (.opencode/commands/).\n * User invokes via /<name> [arguments]\n * Use $ARGUMENTS as a universal placeholder for user input instructions.\n */\n private static toMarkdownCommand(\n name: string,\n description: string,\n body: string,\n ): string {\n const title = name\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n\n return `# ${title}\n\n${description}\n\n**Input:** $ARGUMENTS\n\n## Instructions\n\nExecute the following steps for **$ARGUMENTS**.\n\n${body}`;\n }\n\n /**\n * Gemini CLI TOML command format.\n * Lives at .gemini/commands/<name>.toml\n * References the workflow source file via prompt.\n * User invokes via /<name> [arguments]\n */\n private static toGeminiCommand(\n name: string,\n description: string,\n workflowSourcePath: string,\n ): string {\n const escapedDescription = description\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"');\n return `description = \"${escapedDescription}\"\nprompt = \"\"\"\nPlease execute the workflow defined in \\`${workflowSourcePath}/${name}.md\\` for: {{args}}\n\nFollow the exact steps in the workflow file.\n\"\"\"\n`;\n }\n\n /**\n * GitHub Copilot reusable prompt format.\n * Lives at .github/prompts/<name>.prompt.md\n * User invokes via /prompt-name in Copilot chat.\n */\n private static toCopilotPrompt(description: string, body: string): string {\n return `---\\ndescription: \"${description}\"\\n---\\n${body}`;\n }\n\n /**\n * Agent Skill (SKILL.md) format.\n * Used by Cursor, Trae, and Codex.\n * Lives at <workflowPath>/<name>/SKILL.md\n * Invoked through each platform's skill mechanism.\n */\n private static toSkillMarkdown(\n name: string,\n description: string,\n body: string,\n ): string {\n const normalizedDescription =\n description || `Workflow skill for ${name.replace(/-/g, ' ')}.`;\n const escapedDescription = normalizedDescription\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"');\n const title = name\n .split('-')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n\n return `---\nname: ${name}\ndescription: \"${escapedDescription}\"\nmetadata:\n triggers:\n keywords:\n - ${name.replace(/-/g, ' ')}\n - workflow\n---\n# ${title} Skill\n\n> [!IMPORTANT]\n> ${normalizedDescription}\n\n## Instructions\n\nWhen the user asks to perform this workflow, execute the following steps:\n\n${body}\n`;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, DEFAULT_WORKFLOWS, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { GithubService } from './GithubService';\nimport { WorkflowTransformer } from './utils/WorkflowTransformer';\n\n/**\n * Service responsible for synchronizing agent workflows from a remote registry.\n */\nexport class WorkflowSyncService {\n constructor(private githubService: GithubService) {}\n\n /**\n * Reconciles workflows by discovering new ones in the registry and adding them to the config.\n */\n async reconcileWorkflows(config: SkillConfig): Promise<boolean> {\n if (config.workflows === false) return false;\n\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return false;\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) return false;\n\n const availableWorkflows = treeData.tree\n .filter(\n (f) =>\n f.path.startsWith('.agents/workflows/') && f.path.endsWith('.md'),\n )\n .map((f) => path.basename(f.path, '.md'));\n\n if (availableWorkflows.length === 0) return false;\n\n let changed = false;\n\n if (Array.isArray(config.workflows)) {\n const currentWorkflows = config.workflows as string[];\n const newWorkflows = availableWorkflows.filter(\n (wf) =>\n !currentWorkflows.includes(wf) && DEFAULT_WORKFLOWS.includes(wf),\n );\n\n if (newWorkflows.length > 0) {\n config.workflows = [...currentWorkflows, ...newWorkflows];\n console.log(\n pc.yellow(\n `⨠Workflows Discovered: Adding [${newWorkflows.join(', ')}] to .skillsrc.`,\n ),\n );\n changed = true;\n }\n } else if (config.workflows === undefined) {\n const defaultWorkflows = availableWorkflows.filter((wf) =>\n DEFAULT_WORKFLOWS.includes(wf),\n );\n config.workflows = defaultWorkflows;\n console.log(\n pc.yellow(\n `⨠Workflows Initialized: Adding [${defaultWorkflows.join(', ')}] to .skillsrc.`,\n ),\n );\n changed = true;\n } else if (config.workflows === true) {\n // If it's true, we keep it true to sync everything from the registry.\n // We don't overwrite it with the default list.\n const newWorkflows = availableWorkflows.filter(\n (wf) => !DEFAULT_WORKFLOWS.includes(wf),\n );\n if (newWorkflows.length > 0) {\n console.log(\n pc.cyan(\n `ā¹ļø Registry has ${availableWorkflows.length} workflows (including ${newWorkflows.length} non-default). Syncing all because 'workflows: true' is set.`,\n ),\n );\n }\n }\n\n return changed;\n }\n\n /**\n * Assembles workflows from the remote registry.\n */\n async assembleWorkflows(config: SkillConfig): Promise<CollectedSkill[]> {\n if (!config.workflows) return [];\n\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return [];\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n\n console.log(pc.gray(` - Discovering workflows (${ref})...`));\n\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) {\n console.log(pc.red(` ā Failed to fetch workflows@${ref}.`));\n return [];\n }\n\n const workflowFiles = treeData.tree.filter((f) => {\n if (!f.path.startsWith('.agents/workflows/') || !f.path.endsWith('.md'))\n return false;\n\n if (typeof config.workflows === 'boolean') return config.workflows;\n if (Array.isArray(config.workflows)) {\n return config.workflows.includes(path.basename(f.path, '.md'));\n }\n return false;\n });\n\n const files = await this.githubService.downloadFilesConcurrent(\n workflowFiles.map((f) => ({ owner, repo, ref, path: f.path })),\n );\n\n if (files.length > 0) {\n console.log(pc.gray(` + Fetched ${files.length} workflows`));\n return [\n {\n category: '.agents',\n skill: 'workflows',\n files: files.map((f) => ({\n name: path.basename(f.path),\n content: f.content,\n })),\n },\n ];\n } else {\n if (workflowFiles.length > 0) {\n console.log(\n pc.red(\n ` ā Failed to download ${workflowFiles.length} matched workflows.`,\n ),\n );\n } else {\n console.log(\n pc.gray(` ā¹ļø No matching workflows found in registry.`),\n );\n }\n }\n\n return [];\n }\n\n /**\n * Writes collected workflows from `.agents/workflows/*.md` to each active\n * agent's native invocation surface.\n * - Antigravity/Kiro: keep native markdown workflows\n * - Claude/Roo/OpenCode: markdown command files\n * - Gemini: TOML command files\n * - Copilot: prompt files\n * - Cursor/Trae/Codex: skill folders with SKILL.md\n */\n async writeWorkflows(\n workflows: CollectedSkill[],\n config: SkillConfig,\n agents?: Agent[],\n ) {\n if (workflows.length === 0) return;\n\n const overrides = config.custom_overrides || [];\n const targetAgents = agents || [Agent.Antigravity];\n\n for (const agentId of targetAgents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || agentDef.workflowFormat === 'none') continue;\n\n const workflowDir = path.join(process.cwd(), agentDef.workflowPath);\n await fs.ensureDir(workflowDir);\n\n // Calculate relative path from workflow dir to the source workflow files (.agents/workflows)\n // This is used by Gemini (TOML) to reference the canonical markdown source.\n const sourceWorkflowDir = path.join(process.cwd(), '.agents/workflows');\n const workflowSourceRelative = path.relative(\n workflowDir,\n sourceWorkflowDir,\n );\n\n let written = 0;\n for (const wf of workflows) {\n if (wf.skill !== 'workflows') continue;\n\n for (const fileItem of wf.files) {\n const parsed = WorkflowTransformer.parse({\n name: fileItem.name,\n content: fileItem.content,\n });\n const transformed = WorkflowTransformer.transformParsed(\n parsed,\n agentDef.workflowFormat,\n workflowSourceRelative,\n );\n if (!transformed) continue;\n\n let targetFilePath: string;\n if (agentDef.workflowFormat === 'skill') {\n const workflowName = fileItem.name.replace(/\\.md$/, '');\n targetFilePath = path.join(\n workflowDir,\n workflowName,\n transformed.name,\n );\n } else {\n targetFilePath = path.join(workflowDir, transformed.name);\n }\n\n if (!this.isPathSafe(targetFilePath, workflowDir)) {\n console.log(\n pc.red(` ā Security Error: Invalid path ${targetFilePath}`),\n );\n continue;\n }\n\n if (this.isOverridden(targetFilePath, overrides)) {\n continue;\n }\n\n await fs.outputFile(targetFilePath, transformed.content);\n written++;\n }\n }\n\n if (written > 0) {\n console.log(\n pc.green(\n ` ā
${written} workflows synced to ${agentDef.workflowPath}/ (${agentDef.name})`,\n ),\n );\n }\n }\n }\n\n private isPathSafe(targetPath: string, subPath: string): boolean {\n const resolvedBase = path.resolve(subPath) + path.sep;\n return path.resolve(targetPath).startsWith(resolvedBase);\n }\n\n private isOverridden(targetPath: string, overrides: string[]): boolean {\n const rel = this.normalizePath(targetPath);\n return overrides.some((o) => {\n const op = o.replace(/\\\\/g, '/').replace(/\\/$/, '');\n return (\n rel === op ||\n rel.startsWith(`${op}/`) ||\n rel.includes(`/${op}/`) ||\n rel.endsWith(`/${op}`)\n );\n });\n }\n\n private normalizePath(p: string): string {\n return path.relative(process.cwd(), p).replace(/\\\\/g, '/');\n }\n}\n","import yaml from 'js-yaml';\nimport { Agent, getAgentDefinition } from '../../constants';\n\ninterface SpecialistSource {\n name: string;\n content: string;\n}\n\ninterface TransformedSpecialist {\n name: string;\n content: string;\n}\n\n/**\n * Transforms specialist skill markdown into platform-specific agent personas.\n */\nexport class SpecialistTransformer {\n static transform(\n source: SpecialistSource,\n agentId: Agent,\n ): TransformedSpecialist | null {\n const agentDef = getAgentDefinition(agentId);\n if (!agentDef) return null;\n\n const parts = source.content.split('---');\n if (parts.length < 3) return null;\n\n const metadata = yaml.load(parts[1]) as Record<string, unknown>;\n const body = parts.slice(2).join('---').trim();\n const baseName = source.name.replace(/^specialist-/, '');\n const fullName = source.name;\n\n const description =\n metadata.description || `Specialist persona for ${baseName}`;\n\n switch (agentId) {\n case Agent.Claude:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\n---\\n\\n${body}`,\n };\n\n case Agent.Cursor:\n return {\n name: `${fullName}.mdc`,\n content: `---\\ndescription: ${description}\\nglobs: [\"**/*\"]\\n---\\n# Specialist: ${baseName}\\n\\n${body}`,\n };\n\n case Agent.Copilot:\n return {\n name: `${fullName}.instructions.md`,\n content: `---\\ndescription: \"${description}\"\\napplyTo: \"**/*\"\\n---\\n\\n${body}`,\n };\n\n case Agent.OpenCode:\n return {\n name: `${baseName}.md`,\n content: `---\\ndescription: \"${description}\"\\nmode: subagent\\n---\\n\\n${body}`,\n };\n\n case Agent.Gemini:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\nkind: local\\n---\\n\\n${body}`,\n };\n\n case Agent.Kiro:\n return {\n name: `${baseName}.md`,\n content: `---\\nname: ${baseName}\\ndescription: \"${description}\"\\n---\\n\\n${body}`,\n };\n\n case Agent.Codex: // Codex\n return {\n name: `${baseName}.toml`,\n content: `name = \"${baseName}\"\\ndescription = \"${description}\"\\nsandbox_mode = \"read-only\"\\ndeveloper_instructions = \"\"\"\\n${body}\\n\"\"\"`,\n };\n\n default:\n return {\n name: `${baseName}${agentDef.ruleExtension || '.md'}`,\n content: body,\n };\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { GithubService } from './GithubService';\nimport { SpecialistTransformer } from './utils/SpecialistTransformer';\n\n/**\n * Service responsible for syncing specialist skills from the internal registry\n * to native agent configuration directories.\n */\nexport class SpecialistSyncService {\n constructor(\n private githubService = new GithubService(process.env.GITHUB_TOKEN),\n ) {}\n\n async assembleSpecialists(config: SkillConfig): Promise<CollectedSkill[]> {\n const githubMatch = GithubService.parseGitHubUrl(config.registry);\n if (!githubMatch) return [];\n\n const { owner, repo } = githubMatch;\n const ref =\n (await this.githubService.getRepoInfo(owner, repo))?.default_branch ||\n 'main';\n const treeData = await this.githubService.getRepoTree(owner, repo, ref);\n if (!treeData) return [];\n\n const skillFiles = treeData.tree.filter(\n (item) =>\n item.type === 'blob' &&\n item.path.startsWith('skills/specialists/') &&\n item.path.endsWith('/SKILL.md'),\n );\n\n const specialists: CollectedSkill[] = [];\n for (const file of skillFiles) {\n const parts = file.path.split('/');\n const specialistName = parts[2];\n if (!specialistName) continue;\n\n const content = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n file.path,\n );\n if (!content) continue;\n\n specialists.push({\n category: 'specialists',\n skill: specialistName,\n files: [{ name: 'SKILL.md', content }],\n });\n }\n\n return specialists;\n }\n\n async syncCollectedSpecialists(\n rootDir: string,\n agents: Agent[],\n specialists: CollectedSkill[],\n ): Promise<void> {\n if (specialists.length === 0) return;\n\n for (const agentId of agents) {\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!agentDef || !agentDef.agentPath) continue;\n\n const targetDir = path.join(rootDir, agentDef.agentPath);\n await fs.ensureDir(targetDir);\n\n let syncedCount = 0;\n for (const specialist of specialists) {\n const skillFile = specialist.files.find(\n (file) => file.name === 'SKILL.md',\n );\n if (!skillFile) continue;\n\n const transformed = SpecialistTransformer.transform(\n { name: specialist.skill, content: skillFile.content },\n agentId,\n );\n if (!transformed) continue;\n\n await fs.outputFile(\n path.join(targetDir, transformed.name),\n transformed.content,\n );\n syncedCount++;\n }\n\n if (syncedCount > 0) {\n console.log(\n pc.green(\n ` ā
${syncedCount} specialists synced to ${agentDef.agentPath}/ (${agentDef.name})`,\n ),\n );\n }\n }\n }\n\n /**\n * Syncs all specialists from a source directory to active agents.\n * @param rootDir Project root directory\n * @param agents List of agents to sync for\n * @param sourceDir Optional custom source directory for specialists\n */\n async syncSpecialists(\n rootDir: string,\n agents: Agent[],\n sourceDir?: string,\n ): Promise<void> {\n const specialistsDir =\n sourceDir || path.join(rootDir, 'skills/specialists');\n if (!(await fs.pathExists(specialistsDir))) return;\n\n const specialistFolders = (await fs.readdir(specialistsDir)).filter((f) => {\n return fs.statSync(path.join(specialistsDir, f)).isDirectory();\n });\n\n const collected: CollectedSkill[] = [];\n for (const folder of specialistFolders) {\n const skillPath = path.join(specialistsDir, folder, 'SKILL.md');\n if (!(await fs.pathExists(skillPath))) continue;\n\n const content = await fs.readFile(skillPath, 'utf8');\n collected.push({\n category: 'specialists',\n skill: folder,\n files: [{ name: 'SKILL.md', content }],\n });\n }\n\n return this.syncCollectedSpecialists(rootDir, agents, collected);\n }\n}\n","import { execFileSync, execSync } from 'child_process';\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Service for handling Git operations within the project.\n * Provides a clean interface for querying changed and untracked files.\n */\nexport class GitService {\n /**\n * Finds the root of the project by looking for .git or pnpm-workspace.yaml.\n */\n findProjectRoot(startDir: string = process.cwd()): string {\n let currentDir = startDir;\n while (currentDir !== path.parse(currentDir).root) {\n if (\n fs.existsSync(path.join(currentDir, 'pnpm-workspace.yaml')) ||\n fs.existsSync(path.join(currentDir, '.git'))\n ) {\n return currentDir;\n }\n currentDir = path.dirname(currentDir);\n }\n return startDir;\n }\n\n /**\n * Retrieves a list of files that have changed compared to the base branch or HEAD.\n * Handles both CI (GitHub Actions) and local development environments.\n * @param rootDir The root directory of the repository\n * @returns Array of relative file paths\n */\n getChangedFiles(rootDir: string): string[] {\n try {\n if (process.env.GITHUB_BASE_REF) {\n // CI environment: Compare against the base branch.\n // Validate GITHUB_BASE_REF against safe branch-name characters to prevent\n // shell command injection (OWASP A03) before interpolating into git args.\n const baseRef = process.env.GITHUB_BASE_REF;\n if (!/^[\\w./:-]+$/.test(baseRef)) {\n if (process.env.DEBUG) {\n console.warn(\n 'GITHUB_BASE_REF contains unsafe characters; skipping CI diff.',\n );\n }\n return [];\n }\n try {\n execFileSync('git', ['fetch', 'origin', baseRef, '--depth=1'], {\n cwd: rootDir,\n stdio: 'ignore',\n });\n } catch {\n // Ignore fetch failures\n }\n const output = execFileSync(\n 'git',\n ['diff', '--name-only', `origin/${baseRef}...HEAD`],\n { cwd: rootDir, encoding: 'utf8' },\n );\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n } else {\n // Local environment: Compare against HEAD\n const output = execSync('git diff --name-only HEAD', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn('Git failure while getting changed files:', error);\n }\n return [];\n }\n }\n\n /**\n * Retrieves a list of untracked files in the repository.\n * @param rootDir The root directory of the repository\n * @returns Array of relative file paths\n */\n getUntrackedFiles(rootDir: string): string[] {\n try {\n const output = execSync('git ls-files --others --exclude-standard', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output\n .split('\\n')\n .map((f) => f.trim())\n .filter((f) => f !== '' && fs.existsSync(path.join(rootDir, f)));\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn('Git failure while getting untracked files:', error);\n }\n return [];\n }\n }\n\n /**\n * Retrieves the URL of the 'origin' remote.\n * @param rootDir The root directory of the repository\n */\n getRemoteUrl(rootDir: string): string | null {\n try {\n const output = execSync('git remote get-url origin', {\n cwd: rootDir,\n encoding: 'utf8',\n });\n return output.trim();\n } catch {\n return null;\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Utility functions for manipulating markdown content\n */\nexport class MarkdownUtils {\n /**\n * Injects the generated index into target documentation files (e.g., AGENTS.md).\n * It uses HTML comments as markers for safe injection and replacement.\n * @param rootDir Project root directory\n * @param targets Array of target file names\n * @param indexContent The markdown content to inject\n */\n static async injectIndex(\n rootDir: string,\n targets: string[],\n indexContent: string,\n ): Promise<void> {\n for (const target of targets) {\n const targetPath = path.join(rootDir, target);\n let content = '';\n\n if (await fs.pathExists(targetPath)) {\n content = await fs.readFile(targetPath, 'utf8');\n const markerStart = '<!-- SKILLS_INDEX_START -->';\n const markerEnd = '<!-- SKILLS_INDEX_END -->';\n\n const startIndex = content.indexOf(markerStart);\n const endIndex = content.indexOf(markerEnd);\n\n if (startIndex !== -1 && endIndex !== -1 && startIndex < endIndex) {\n // Both markers exist and are in the correct order\n const preMarker = content.substring(\n 0,\n startIndex + markerStart.length,\n );\n const postMarker = content.substring(endIndex);\n content = `${preMarker}\\n${indexContent}\\n${postMarker}`;\n } else if (startIndex !== -1 || endIndex !== -1) {\n // One of the markers is missing or they are out of order\n content = content.replace(markerStart, '').replace(markerEnd, '');\n content =\n content.trimEnd() +\n `\\n\\n${markerStart}\\n${indexContent}\\n${markerEnd}\\n`;\n } else {\n // No markers found\n content =\n content.trimEnd() +\n `\\n\\n${markerStart}\\n${indexContent}\\n${markerEnd}\\n`;\n }\n } else {\n content = `<!-- SKILLS_INDEX_START -->\\n${indexContent}\\n<!-- SKILLS_INDEX_END -->\\n`;\n }\n\n await fs.outputFile(targetPath, content);\n }\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { Agent, SUPPORTED_AGENTS } from '../constants';\nimport { SkillConfig } from '../models/config';\nimport { CollectedSkill } from '../models/types';\nimport { AgentBridgeService } from './AgentBridgeService';\nimport { ConfigService } from './ConfigService';\nimport { DetectionService } from './DetectionService';\nimport { GithubService } from './GithubService';\nimport { IndexGeneratorServiceImpl } from './IndexGeneratorServiceImpl';\nimport { SkillSyncService } from './SkillSyncService';\nimport { WorkflowSyncService } from './WorkflowSyncService';\nimport { SpecialistSyncService } from './SpecialistSyncService';\nimport { GitService } from './GitService';\nimport { MarkdownUtils } from './utils/MarkdownUtils';\n\n/**\n * Service responsible for coordinating the synchronization of agent skills and workflows.\n * It acts as a facade, delegating specialized synchronization tasks to SkillSyncService\n * and WorkflowSyncService.\n */\nexport class SyncService {\n private configService = new ConfigService();\n private detectionService = new DetectionService();\n private githubService = new GithubService(process.env.GITHUB_TOKEN);\n private skillSyncService = new SkillSyncService(this.githubService);\n private workflowSyncService = new WorkflowSyncService(this.githubService);\n private specialistSyncService = new SpecialistSyncService();\n private gitService = new GitService();\n\n async reconcileConfig(\n config: SkillConfig,\n projectDeps: Set<string>,\n ): Promise<boolean> {\n const reenabled = this.configService.reconcileDependencies(\n config,\n projectDeps,\n );\n if (reenabled.length > 0) {\n console.log(pc.cyan('\\nš Dependencies changed, re-enabling skills:'));\n for (const skill of reenabled) {\n console.log(pc.gray(` - ${skill}`));\n }\n return true;\n }\n return false;\n }\n\n async reconcileWorkflows(config: SkillConfig): Promise<boolean> {\n return this.workflowSyncService.reconcileWorkflows(config);\n }\n\n async assembleSkills(\n categories: string[],\n config: SkillConfig,\n ): Promise<CollectedSkill[]> {\n await this.warnIfSyncingFromSameRepo(config);\n const skillCategories = categories.filter(\n (category) => category !== 'specialists',\n );\n return this.skillSyncService.assembleSkills(skillCategories, config);\n }\n\n private async warnIfSyncingFromSameRepo(config: SkillConfig) {\n const remoteUrl = this.gitService.getRemoteUrl(process.cwd());\n if (!remoteUrl) return;\n\n const remoteMatch = GithubService.parseGitHubUrl(remoteUrl);\n const registryMatch = GithubService.parseGitHubUrl(config.registry);\n\n if (\n remoteMatch &&\n registryMatch &&\n remoteMatch.owner === registryMatch.owner &&\n remoteMatch.repo === registryMatch.repo\n ) {\n console.log(\n pc.yellow(\n `\\nā ļø Note: You are syncing from the registry repository itself (${remoteMatch.owner}/${remoteMatch.repo}).`,\n ),\n );\n console.log(\n pc.gray(\n ` 'ags sync' pulls from GitHub. If you have unpushed local changes, they will be overwritten by the remote versions.`,\n ),\n );\n }\n }\n\n async writeSkills(\n skills: CollectedSkill[],\n config: SkillConfig,\n ): Promise<void> {\n await this.cleanupOldFolders();\n const agents = await this.resolveTargetAgents(config);\n return this.skillSyncService.writeSkills(skills, config, agents);\n }\n\n async assembleWorkflows(config: SkillConfig): Promise<CollectedSkill[]> {\n return this.workflowSyncService.assembleWorkflows(config);\n }\n\n async writeWorkflows(\n workflows: CollectedSkill[],\n config: SkillConfig,\n ): Promise<void> {\n const agents = await this.resolveTargetAgents(config);\n return this.workflowSyncService.writeWorkflows(workflows, config, agents);\n }\n\n async syncSpecialists(config: SkillConfig): Promise<void> {\n const agents = await this.resolveTargetAgents(config);\n if (agents.length === 0) return;\n\n const localRegistrySource = path.join(process.cwd(), 'skills/specialists');\n if (await fs.pathExists(localRegistrySource)) {\n return this.specialistSyncService.syncSpecialists(\n process.cwd(),\n agents,\n localRegistrySource,\n );\n }\n\n const specialists =\n await this.specialistSyncService.assembleSpecialists(config);\n return this.specialistSyncService.syncCollectedSpecialists(\n process.cwd(),\n agents,\n specialists,\n );\n }\n\n async applyIndices(\n config: SkillConfig,\n targetAgents?: Agent[],\n ): Promise<void> {\n const agents = targetAgents || (await this.resolveTargetAgents(config));\n if (agents.length === 0) return;\n\n const agentDef = SUPPORTED_AGENTS.find((a) => a.id === agents[0]);\n if (!agentDef) {\n console.log(\n pc.yellow(` ā ļø Agent definition not found for ${agents[0]}.`),\n );\n }\n\n try {\n const generator = new IndexGeneratorServiceImpl();\n // Use agent path if available, otherwise fallback to .cursor/skills as a reasonable default\n const baseDir = agentDef\n ? path.join(process.cwd(), agentDef.path)\n : path.join(process.cwd(), '.cursor/skills');\n\n const allowedCategories = Object.keys(config.skills || {});\n\n // Fetch metadata.json from the registry's default branch and inject it into the\n // generator in-memory. This gives assembleRouterIndex the file_routing, broad_globs,\n // and base_language_skills it needs without writing anything to disk.\n const githubMatch = config.registry\n ? GithubService.parseGitHubUrl(config.registry)\n : null;\n if (githubMatch) {\n const { owner, repo } = githubMatch;\n const repoInfo = await this.githubService.getRepoInfo(owner, repo);\n const ref = repoInfo?.default_branch || 'main';\n const metaRaw = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n 'skills/metadata.json',\n );\n if (metaRaw) {\n try {\n generator.withMetadata(JSON.parse(metaRaw));\n } catch {\n // Malformed JSON ā continue without remote metadata; router falls back to file\n }\n }\n }\n\n // Generate per-category _INDEX.md files for all target agents\n const categoryIndices = await generator.generateAllCategoryIndices(\n baseDir,\n allowedCategories,\n );\n for (const agentId of agents) {\n const def = SUPPORTED_AGENTS.find((a) => a.id === agentId);\n if (!def) continue;\n const agentBase = path.join(process.cwd(), def.path);\n for (const [category, indexContent] of Object.entries(\n categoryIndices as Record<string, string>,\n )) {\n const indexMdPath = path.join(agentBase, category, '_INDEX.md');\n await fs.outputFile(indexMdPath, indexContent);\n }\n }\n if (Object.keys(categoryIndices).length > 0) {\n console.log(\n pc.green(\n ` ā
Generated _INDEX.md for ${Object.keys(categoryIndices).length} categories.`,\n ),\n );\n }\n\n // Generate router-style AGENTS.md (compact, scalable). When MCP is\n // enabled in .skillsrc, the router gets a \"Runtime Enforcement via MCP\"\n // section so AI agents (and sub-agents that read AGENTS.md) are told to\n // prefer the MCP tool calls.\n const mcpEnabled = config.mcp?.enabled === true;\n const routerIndex = await generator.assembleRouterIndex(\n baseDir,\n allowedCategories,\n mcpEnabled,\n );\n await MarkdownUtils.injectIndex(\n process.cwd(),\n ['AGENTS.md'],\n routerIndex,\n );\n console.log(pc.green(' ā
AGENTS.md router index updated.'));\n\n // Apply to sub-projects if any\n const serverDir = path.join(process.cwd(), 'server');\n if (await fs.pathExists(serverDir)) {\n await MarkdownUtils.injectIndex(serverDir, ['AGENTS.md'], routerIndex);\n console.log(pc.green(' ā
server/AGENTS.md router index updated.'));\n }\n\n const bridgeService = new AgentBridgeService();\n await bridgeService.bridge(process.cwd(), agents);\n } catch (error) {\n console.log(pc.yellow(` ā ļø Failed to update index: ${error}`));\n }\n }\n\n async checkForUpdates(config: SkillConfig): Promise<Record<string, string>> {\n const { owner, repo } = GithubService.parseGitHubUrl(config.registry) || {};\n if (!owner || !repo) return {};\n\n const info = await this.githubService.getRepoInfo(owner, repo);\n const ref = info?.default_branch || 'main';\n\n const metadataRaw = await this.githubService.getRawFile(\n owner,\n repo,\n ref,\n 'skills/metadata.json',\n );\n if (!metadataRaw) return {};\n\n const remoteMeta = JSON.parse(metadataRaw);\n const updates: Record<string, string> = {};\n\n for (const [cat, catConfig] of Object.entries(config.skills)) {\n const remoteMetaCat = remoteMeta.categories?.[cat];\n if (!remoteMetaCat?.version) continue;\n\n const latestRef = `${remoteMetaCat.tag_prefix || ''}${remoteMetaCat.version}`;\n if (catConfig.ref !== latestRef) {\n updates[cat] = latestRef;\n }\n }\n\n return updates;\n }\n\n public async resolveTargetAgents(config: SkillConfig): Promise<Agent[]> {\n if (config.agents && config.agents.length > 0) {\n return config.agents;\n }\n\n const detectedMap = await this.detectionService.detectAgents();\n const detected = Object.entries(detectedMap)\n .filter(([, enabled]) => enabled)\n .map(([id]) => id as Agent);\n\n if (detected.length > 0) {\n return detected;\n }\n\n // Return empty if no agents are detected and none are configured.\n // This ensures we never create \"ghost\" directories in the workspace.\n return [];\n }\n\n private async cleanupOldFolders(): Promise<void> {\n const oldPath = path.join(process.cwd(), '.agent');\n const newPath = path.join(process.cwd(), '.agents');\n\n if (await fs.pathExists(oldPath)) {\n try {\n // Merge old content into the new folder without overwriting user files.\n await fs.copy(oldPath, newPath, {\n overwrite: false,\n errorOnExist: false,\n });\n\n await fs.remove(oldPath);\n console.log(pc.gray(' - Migrated and cleaned up old .agent folder.'));\n } catch (error) {\n if (process.env.DEBUG) {\n console.debug(\n `Failed to migrate/cleanup old .agent folder: ${error}`,\n );\n }\n }\n }\n }\n}\n","import inquirer from 'inquirer';\nimport pc from 'picocolors';\nimport { Agent } from '../constants';\nimport { McpScope, SkillConfig } from '../models/config';\nimport { ConfigService } from '../services/ConfigService';\nimport { DetectionService } from '../services/DetectionService';\nimport {\n McpConfigService,\n defaultMcpConfig,\n} from '../services/McpConfigService';\nimport { HookService } from '../services/HookService';\nimport { SyncService } from '../services/SyncService';\n\n/**\n * Command for synchronizing skills and workflows from the remote registry to the local workspace.\n * It handles configuration re-detection, fetching files, writing to disk, and updating indices.\n */\nexport class SyncCommand {\n private configService: ConfigService;\n private detectionService: DetectionService;\n private syncService: SyncService;\n private mcpService: McpConfigService;\n private hookService: HookService;\n\n constructor(\n configService?: ConfigService,\n detectionService?: DetectionService,\n syncService?: SyncService,\n mcpService?: McpConfigService,\n hookService?: HookService,\n ) {\n this.configService = configService || new ConfigService();\n this.detectionService = detectionService || new DetectionService();\n this.syncService = syncService || new SyncService();\n this.mcpService = mcpService || new McpConfigService();\n this.hookService = hookService || new HookService();\n }\n\n /**\n * Executes the synchronization flow.\n * Reconciles dependencies, fetches skills and workflows from the registry, and updates AGENTS.md.\n */\n async run(options: { yes?: boolean; snippets?: boolean } = {}) {\n try {\n // 1. Load Config\n const config = await this.configService.loadConfig();\n if (!config) {\n console.log(pc.red('ā Error: .skillsrc not found. Run `init` first.'));\n return;\n }\n\n // 2. Dynamic Update Configuration (Re-detection)\n const projectDeps = await this.detectionService.getProjectDeps();\n const skillsChanged = await this.syncService.reconcileConfig(\n config,\n projectDeps,\n );\n const workflowsChanged =\n await this.syncService.reconcileWorkflows(config);\n\n if (skillsChanged || workflowsChanged) {\n await this.configService.saveConfig(config);\n }\n\n // 3. Check for updates\n const updates = await this.syncService.checkForUpdates(config);\n\n if (updates && Object.keys(updates).length > 0) {\n console.log(pc.yellow('\\nš New skill versions detected:'));\n for (const [cat, ref] of Object.entries(updates)) {\n console.log(\n pc.gray(` - ${cat}: ${config.skills[cat].ref} -> ${ref}`),\n );\n }\n\n let update = options.yes;\n if (update === undefined) {\n if (!process.stdin.isTTY) {\n console.log(\n pc.cyan(\n 'ā¹ļø Non-interactive environment detected. Skipping version updates. Use --yes to auto-confirm.',\n ),\n );\n update = false;\n } else {\n const answer = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'update',\n message: 'Do you want to update .skillsrc with these versions?',\n default: true,\n },\n ]);\n update = answer.update;\n }\n }\n\n if (update) {\n for (const [cat, ref] of Object.entries(updates)) {\n config.skills[cat].ref = ref;\n }\n await this.configService.saveConfig(config);\n console.log(pc.green('ā
.skillsrc updated.'));\n } else {\n console.log(\n pc.cyan('ā¹ļø Skipping version updates, staying on pinned refs.'),\n );\n }\n }\n\n console.log(pc.cyan(`š Syncing skills from ${config.registry}...`));\n\n // 4. Assemble skills from remote registry\n const enabledCategories = Object.keys(config.skills);\n const skills = await this.syncService.assembleSkills(\n enabledCategories,\n config,\n );\n\n // 4b. Assemble workflows\n const workflows = await this.syncService.assembleWorkflows(config);\n\n // 5. Write skills and workflows to target\n await this.syncService.writeSkills(skills, config);\n await this.syncService.writeWorkflows(workflows, config);\n\n // 5b. Sync specialists (sub-agents)\n await this.syncService.syncSpecialists(config);\n\n // 6. Automatically apply framework-specific indices to AGENTS.md\n await this.syncService.applyIndices(config, config.agents);\n\n console.log(pc.green('ā
All skills synced successfully!'));\n\n // 7. MCP integration (consent-respecting ā see McpConfigService).\n await this.runMcpPhase(config, options);\n\n // 8. Hook installation ā always runs; idempotent.\n await this.runHookPhase(config);\n } catch (error) {\n if (error instanceof Error) {\n console.error(pc.red('ā Sync failed:'), error.message);\n } else {\n console.error(pc.red('ā Sync failed:'), String(error));\n }\n }\n }\n\n /**\n * Phase 7 ā MCP integration. Three paths:\n * A. Never prompted yet: ask once now (with full value-prop), persist decision.\n * B. Already prompted, mcp.enabled=true: dispatch install at the configured scope.\n * C. Already prompted, mcp.enabled=false: skip silently.\n *\n * In non-interactive mode (no TTY) and never-prompted: skip with a hint, do\n * not assume consent. Users can opt in later via `ags mcp enable`.\n */\n private async runMcpPhase(\n config: SkillConfig,\n options: { yes?: boolean; snippets?: boolean },\n ): Promise<void> {\n const mcp = config.mcp ? { ...config.mcp } : defaultMcpConfig();\n const agents = config.agents ?? [];\n\n const snippetOnlyOverride =\n options.snippets === true && (!mcp.enabled || mcp.scope === 'disabled');\n if (snippetOnlyOverride) {\n mcp.enabled = true;\n mcp.scope = 'snippets-only';\n mcp.snippets = true;\n } else if (options.snippets !== undefined) {\n mcp.snippets = options.snippets;\n }\n\n if (\n !snippetOnlyOverride &&\n (!mcp.prompted || (!mcp.enabled && mcp.prompted))\n ) {\n if (!process.stdin.isTTY && !options.yes) {\n if (!mcp.prompted) {\n console.log(\n pc.gray(\n '\\nā¹ļø MCP integration not yet configured. Run `ags mcp enable` (or `ags mcp scope project`) when ready.',\n ),\n );\n }\n return;\n }\n\n // If already prompted but disabled, we ask again if they want to enable it now.\n // This ensures they aren't \"stuck\" in a disabled state just because they said no once.\n // Pass true for wasDisabled only if it was already prompted AND it is currently disabled.\n const decided = await this.promptMcpConsent(\n options,\n mcp.prompted && !mcp.enabled,\n );\n config.mcp = {\n enabled: decided.enabled,\n scope: decided.enabled ? decided.scope : 'disabled',\n prompted: true,\n };\n await this.configService.saveConfig(config);\n }\n\n const finalMcp = config.mcp ? { ...config.mcp } : defaultMcpConfig();\n if (snippetOnlyOverride) {\n finalMcp.enabled = true;\n finalMcp.scope = 'snippets-only';\n finalMcp.snippets = true;\n } else if (options.snippets !== undefined) {\n finalMcp.snippets = options.snippets;\n }\n\n if (!finalMcp.enabled || finalMcp.scope === 'disabled') {\n return;\n }\n\n const userScopePrompt = options.yes\n ? async () => true\n : async (agent: Agent, file: string): Promise<boolean> => {\n const { ok } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'ok',\n message: `Write user-scope MCP config for ${pc.cyan(agent)} at ${pc.gray(file)}?`,\n default: false,\n },\n ]);\n return ok;\n };\n\n console.log(pc.cyan('\\nš Wiring MCP server...'));\n const report = await this.mcpService.install({\n rootDir: process.cwd(),\n agents,\n mcp: finalMcp,\n userScopePrompt,\n });\n\n for (const w of report.projectWrites) {\n const tag =\n w.action === 'added'\n ? pc.green(' + added ')\n : w.action === 'updated'\n ? pc.cyan(' ~ updated ')\n : pc.gray(' = up-to-date');\n console.log(`${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n for (const w of report.userWrites) {\n console.log(\n ` ${pc.green('+ wrote ')} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`,\n );\n }\n for (const d of report.declined) {\n console.log(\n ` ${pc.gray('- ')} ${d.agent.padEnd(12)} ${pc.gray(d.file)} (declined)`,\n );\n }\n if (report.snippets.length > 0) {\n console.log(\n pc.gray(\n ` ${report.snippets.length} snippet(s) written to ./mcp-config-snippets/`,\n ),\n );\n }\n if (report.unsupported.length > 0) {\n console.log(\n pc.gray(\n ` (skipped ā no MCP support yet: ${report.unsupported.join(', ')})`,\n ),\n );\n }\n }\n\n private async promptMcpConsent(\n options: {\n yes?: boolean;\n },\n wasDisabled = false,\n ): Promise<{ enabled: boolean; scope: McpScope }> {\n if (options.yes) {\n // Conservative default for --yes: opt in at project scope (the recommended choice).\n return { enabled: true, scope: 'project' };\n }\n console.log(pc.bold('\\nš MCP server setup\\n'));\n if (wasDisabled) {\n console.log(\n pc.yellow(\n 'MCP integration is currently disabled. Would you like to enable it now?',\n ),\n );\n }\n console.log(\n 'agent-skills-standard ships an optional MCP server that serves your skills',\n );\n console.log('to AI agents at runtime. Quick comparison:\\n');\n console.log(\n pc.bold(' WITHOUT MCP:') +\n ' sub-agents skip skill loading; no audit trail',\n );\n console.log(\n pc.bold(' WITH MCP: ') +\n ' every sub-agent can call load_skills_for_files; auditable\\n',\n );\n\n const decision = await inquirer.prompt<{\n enabled: boolean;\n scope: McpScope;\n }>([\n {\n type: 'confirm',\n name: 'enabled',\n message: 'Enable MCP server integration?',\n default: true,\n },\n {\n type: 'list',\n name: 'scope',\n message: 'Where should sync write MCP configs?',\n when: (a) => a.enabled === true,\n choices: [\n {\n name: 'project (recommended) ā only files inside this project',\n value: 'project',\n },\n {\n name: 'user ā also $HOME files (sync prompts each)',\n value: 'user',\n },\n {\n name: 'snippets-only ā never edits any runtime config',\n value: 'snippets-only',\n },\n ],\n default: 'project',\n },\n ]);\n return decision;\n }\n\n /**\n * Phase 8 ā Hook installation.\n * Idempotent: registers the Claude PreToolUse entry and keeps managed hook\n * files up to date. Claude's script is preserved if already customized; Kiro's\n * markdown hook is kept in sync with the embedded template.\n */\n private async runHookPhase(config: SkillConfig): Promise<void> {\n const agents = config.agents ?? [];\n if (agents.length === 0) return;\n\n const mcp = config.mcp ?? defaultMcpConfig();\n if (!mcp.enabled || mcp.scope === 'disabled') {\n await this.hookService.uninstall({ rootDir: process.cwd(), agents });\n return;\n }\n\n const report = await this.hookService.install({\n rootDir: process.cwd(),\n agents,\n });\n\n const writes = report.writes.filter((w) => w.action !== 'skipped-existing');\n if (writes.length === 0) return;\n\n console.log(pc.cyan('\\nšŖ Updating skill-loader hooks...'));\n for (const w of writes) {\n const tag =\n w.action === 'added' ? pc.green('+ added ') : pc.cyan('~ updated ');\n console.log(` ${tag} ${w.agent.padEnd(12)} ${pc.gray(w.file)}`);\n }\n }\n}\n","{\n \"name\": \"agent-skills-standard\",\n \"version\": \"2.4.4\",\n \"description\": \"A CLI to manage and sync AI agent skills standard for Cursor, Claude, Copilot, Windsurf, and more.\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"agent-skills-standard\": \"dist/index.js\",\n \"ags\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"vite build\",\n \"start\": \"node dist/index.js\",\n \"dev\": \"tsx src/index.ts\",\n \"validate\": \"tsx src/index.ts validate\",\n \"validate:all\": \"tsx src/index.ts validate --all\",\n \"format\": \"prettier --write \\\"src/**/*.ts\\\"\",\n \"format:check\": \"prettier --check \\\"src/**/*.ts\\\"\",\n \"lint\": \"eslint \\\"src/**/*.ts\\\" --fix\",\n \"lint:check\": \"eslint \\\"src/**/*.ts\\\"\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:cov\": \"vitest run --coverage\",\n \"prepublishOnly\": \"pnpm build\"\n },\n \"keywords\": [\n \"ai\",\n \"agent\",\n \"cursor\",\n \"claude\",\n \"copilot\",\n \"cli\",\n \"antigravity\"\n ],\n \"author\": \"Hoang Nguyen\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"commander\": \"^11.1.0\",\n \"cross-fetch\": \"^4.1.0\",\n \"dotenv\": \"^17.2.3\",\n \"fs-extra\": \"^11.2.0\",\n \"inquirer\": \"^8.2.5\",\n \"js-yaml\": \"^4.1.0\",\n \"picocolors\": \"^1.0.0\",\n \"zod\": \"^3.22.4\"\n },\n \"devDependencies\": {\n \"@vitest/coverage-v8\": \"^4.0.17\",\n \"vite\": \"^7.0.0\",\n \"vitest\": \"^4.0.17\"\n }\n}\n","import { execSync } from 'child_process';\nimport path from 'path';\nimport pc from 'picocolors';\nimport pkg from '../../package.json';\n\n/**\n * Command for upgrading the `agent-skills-standard` CLI to the latest version.\n * It checks the latest version on npm and performs the upgrade using the detected package manager.\n */\nexport class UpgradeCommand {\n private currentVersion = pkg.version;\n\n /**\n * Executes the upgrade flow.\n * @param options Command options, including `dryRun` to check for updates without installing.\n */\n async run(options: { dryRun?: boolean }) {\n console.log(pc.cyan('š Checking for updates...'));\n\n const currentVersion = this.currentVersion;\n let latestVersion: string | null = null;\n\n try {\n latestVersion = execSync('npm view agent-skills-standard version', {\n encoding: 'utf8',\n }).trim();\n } catch {\n console.log(pc.red('ā Failed to check for updates via npm.'));\n return;\n }\n\n if (!latestVersion) {\n console.log(pc.red('ā Could not determine latest version.'));\n return;\n }\n\n // Validate semver to prevent command injection or unexpected behavior\n const semverRegex = /^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.]+)?(\\+[a-zA-Z0-9.]+)?$/;\n if (!semverRegex.test(latestVersion)) {\n console.log(\n pc.red(`ā Invalid version received from npm: ${latestVersion}`),\n );\n return;\n }\n\n console.log(pc.gray(` Current version: ${currentVersion}`));\n console.log(pc.gray(` Latest version: ${latestVersion}`));\n\n if (currentVersion === latestVersion) {\n console.log(pc.green('⨠You are already using the latest version!'));\n return;\n }\n\n if (options.dryRun) {\n console.log(\n pc.yellow(\n `š A new version (${latestVersion}) is available! Run without --dry-run to upgrade.`,\n ),\n );\n return;\n }\n\n const pm = this.detectPackageManager();\n const upgradeCmd = this.getUpgradeCommand(pm, latestVersion);\n\n console.log(pc.yellow(`š¦ Upgrading to v${latestVersion} using ${pm}...`));\n\n try {\n console.log(pc.gray(` Running: ${upgradeCmd}`));\n\n try {\n execSync(upgradeCmd, { stdio: 'inherit' });\n } catch {\n console.log(\n pc.yellow(\n `ā ļø Failed to install v${latestVersion}. Retrying with @latest...`,\n ),\n );\n const fallbackCmd = this.getUpgradeCommand(pm, 'latest');\n execSync(fallbackCmd, { stdio: 'inherit' });\n }\n\n if (pm === 'pnpm') {\n const installedVersion = this.getInstalledVersionFromPnpm(latestVersion);\n\n if (installedVersion !== latestVersion) {\n console.log(\n '\\n' +\n pc.red(\n `ā pnpm install completed, but the installed package still reports v${installedVersion ?? 'unknown'}.`,\n ),\n );\n console.log(\n pc.gray(\n ' This means the global install itself is stale or incomplete, not just the shell shim.',\n ),\n );\n this.printShellMismatchHint();\n return;\n }\n\n try {\n const output = execSync('ags -V', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n const lines = output.split('\\n');\n const shellVersion = lines[lines.length - 1].trim();\n\n if (shellVersion.includes(latestVersion)) {\n console.log(\n pc.green(`ā
Successfully upgraded to v${latestVersion}!`),\n );\n } else {\n console.log(\n '\\n' +\n pc.yellow(\n `ā ļø pnpm installed v${latestVersion}, but 'ags -V' still reports v${shellVersion}.`,\n ),\n );\n console.log(\n pc.gray(\n ' Your shell is still resolving a stale shim or PATH entry.',\n ),\n );\n this.printShellMismatchHint();\n }\n } catch {\n console.log(pc.green('\\nā
Upgrade command finished.'));\n console.log(\n pc.gray(\n \" (Installed version verified via pnpm; please check the shell command with 'ags -V')\",\n ),\n );\n }\n } else {\n // Soft Verification\n try {\n const output = execSync('ags -V', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n const lines = output.split('\\n');\n const installedVersion = lines[lines.length - 1].trim();\n\n if (installedVersion.includes(latestVersion)) {\n console.log(\n pc.green(`ā
Successfully upgraded to v${latestVersion}!`),\n );\n } else {\n const resolvedBinary = execSync('type -a ags', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n\n console.log(\n '\\n' +\n pc.yellow(\n `ā ļø Installation complete, but 'ags -V' still reports v${installedVersion}.`,\n ),\n );\n console.log(\n pc.gray(\n ' This usually means your shell is still resolving a stale shim or PATH entry.',\n ),\n );\n console.log(pc.gray(` Resolved binary:\\n${resolvedBinary}`));\n console.log(\n pc.cyan(\n `š Recommendation: make sure ${pc.bold('~/Library/pnpm')} comes before ${pc.bold('~/Library/pnpm/bin')} in PATH, then run ${pc.bold('hash -r')} and recheck with 'ags -V'.`,\n ),\n );\n }\n } catch {\n console.log(pc.green('\\nā
Upgrade command finished.'));\n console.log(\n pc.gray(\n \" (Unable to verify version automatically, please check with 'ags -V')\",\n ),\n );\n }\n }\n\n console.log(\n pc.cyan(\n '\\nNote: You may need to restart your terminal session for changes to take effect.',\n ),\n );\n } catch {\n console.log('\\n' + pc.red('ā Automatic upgrade failed.'));\n this.printManualInstructions(pm, latestVersion);\n }\n }\n\n private detectPackageManager(): 'npm' | 'pnpm' | 'yarn' {\n const execPath = process.argv[1] || '';\n\n // 1. Check if we are running from a pnpm global bin\n if (\n execPath.includes('pnpm') ||\n (process.env.npm_config_user_agent || '').includes('pnpm')\n ) {\n return 'pnpm';\n }\n\n // 2. Check if we are running from a yarn global bin\n if (\n execPath.includes('yarn') ||\n (process.env.npm_config_user_agent || '').includes('yarn')\n ) {\n return 'yarn';\n }\n\n // 3. Check for nvm or npm paths\n if (execPath.includes('nvm') || execPath.includes('npm')) {\n return 'npm';\n }\n\n // Fallback: Check for existing binaries, but default to npm for maximum safety\n try {\n execSync('pnpm --version', { stdio: 'ignore' });\n // Only return pnpm if we're reasonably sure it's configured (avoiding PATH issues)\n if (execPath.includes('pnpm')) return 'pnpm';\n } catch {\n // pnpm not available or not configured for this path\n }\n\n return 'npm';\n }\n\n private getUpgradeCommand(\n pm: 'npm' | 'pnpm' | 'yarn',\n version: string,\n ): string {\n switch (pm) {\n case 'pnpm':\n return `pnpm add -g agent-skills-standard@${version}`;\n case 'yarn':\n return `yarn global add agent-skills-standard@${version}`;\n default:\n // Default to npm install -g\n return `npm install -g agent-skills-standard@${version}`;\n }\n }\n\n private getInstalledVersionFromPnpm(\n version: string,\n ): string | null {\n try {\n const globalRoot = execSync('pnpm root -g', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n const packageJsonPath = path.join(\n globalRoot,\n '.pnpm',\n `agent-skills-standard@${version}`,\n 'node_modules',\n 'agent-skills-standard',\n 'package.json',\n );\n const output = execSync(\n `node -p \"require(${JSON.stringify(packageJsonPath)}).version\"`,\n {\n encoding: 'utf8',\n stdio: 'pipe',\n },\n ).trim();\n return output || null;\n } catch {\n return null;\n }\n }\n\n private printShellMismatchHint(): void {\n const resolvedBinary = execSync('type -a ags', {\n encoding: 'utf8',\n stdio: 'pipe',\n }).trim();\n\n console.log(pc.gray(` Resolved binary:\\n${resolvedBinary}`));\n console.log(\n pc.cyan(\n `š Recommendation: make sure ${pc.bold('~/Library/pnpm')} comes before ${pc.bold('~/Library/pnpm/bin')} in PATH, then run ${pc.bold('hash -r')} and recheck with 'ags -V'.`,\n ),\n );\n }\n\n private printManualInstructions(\n pm: 'npm' | 'pnpm' | 'yarn',\n version: string,\n ) {\n const isWindows = process.platform === 'win32';\n const sudoPrefix = isWindows ? '' : 'sudo ';\n\n console.log(pc.yellow('Possible reasons:'));\n console.log(pc.gray(' - Permission denied (requires sudo/administrator)'));\n console.log(pc.gray(' - Network connectivity issues'));\n console.log(pc.gray(` - ${pm} is not configured for global installs`));\n\n console.log(\n '\\n' + pc.cyan('š Please run the following command manually:'),\n );\n console.log(\n pc.white(\n pc.bold(` ${sudoPrefix}${this.getUpgradeCommand(pm, version)}`),\n ),\n );\n\n if (pm !== 'npm') {\n console.log(pc.gray('\\nAlternative (npm):'));\n console.log(\n pc.gray(\n ` ${sudoPrefix}npm install -g agent-skills-standard@${version}`,\n ),\n );\n }\n\n console.log(pc.gray('\\nOr run via npx (no install required):'));\n console.log(pc.gray(` npx agent-skills-standard@${version} sync`));\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { GitService } from './GitService';\n\n/**\n * Service for discovering skill files within the repository.\n * Handles recursive directory scanning and integration with Git for change detection.\n */\nexport class SkillDiscoveryService {\n private gitService = new GitService();\n\n /**\n * Finds all SKILL.md files in the repository.\n * @param skillsDir The directory to search within\n * @returns Array of absolute paths to skill files\n */\n async findAllSkills(skillsDir: string): Promise<string[]> {\n const skillFiles: string[] = [];\n\n const findRecursive = async (dir: string) => {\n try {\n const items = await fs.readdir(dir);\n\n for (const item of items) {\n const fullPath = path.join(dir, item);\n try {\n const stat = await fs.stat(fullPath);\n\n if (stat.isDirectory()) {\n await findRecursive(fullPath);\n } else if (item === 'SKILL.md') {\n skillFiles.push(fullPath);\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`Failed to stat path: ${fullPath}`, error);\n }\n }\n }\n } catch (error) {\n if (process.env.DEBUG) {\n console.warn(`Failed to read directory: ${dir}`, error);\n }\n }\n };\n\n if (await fs.pathExists(skillsDir)) {\n await findRecursive(skillsDir);\n }\n\n return skillFiles;\n }\n\n /**\n * Finds skills that have been changed or are untracked in Git.\n * @returns Array of absolute paths to changed skill files\n */\n async findChangedSkills(): Promise<string[]> {\n const rootDir = this.gitService.findProjectRoot();\n const changedRelative = this.gitService.getChangedFiles(rootDir);\n const untrackedRelative = this.gitService.getUntrackedFiles(rootDir);\n\n const isSkillFile = (file: string) =>\n file.startsWith('skills/') && file.endsWith('SKILL.md');\n\n const allChangedAbsolute = [...changedRelative, ...untrackedRelative]\n .filter(isSkillFile)\n .map((file) => path.join(rootDir, file));\n\n // Simple deduplication\n return Array.from(new Set(allChangedAbsolute));\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { RuleResult, ValidationRule } from './types';\n\n/**\n * Enforces a maximum line count for skill files to ensure token efficiency.\n */\nexport class SizeRule implements ValidationRule {\n name = 'Size Limit';\n constructor(private maxLines: number = 100) {}\n\n async validate(content: string): Promise<RuleResult> {\n const lines = content.split('\\n');\n if (lines.length > this.maxLines) {\n return {\n passed: false,\n errors: [\n `SKILL.md too large (${lines.length} lines > ${this.maxLines} limit)`,\n ],\n warnings: [],\n };\n }\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Validates frontmatter presence and required fields.\n */\nexport class FrontmatterRule implements ValidationRule {\n name = 'Frontmatter';\n\n async validate(content: string): Promise<RuleResult> {\n const result: RuleResult = { passed: true, errors: [], warnings: [] };\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n\n if (!frontmatterMatch) {\n return {\n passed: false,\n errors: ['Missing or invalid frontmatter'],\n warnings: [],\n };\n }\n\n const frontmatter = frontmatterMatch[1];\n\n if (!frontmatter.includes('name:')) {\n result.errors.push('Missing \"name\" field in frontmatter');\n result.passed = false;\n }\n\n if (!frontmatter.includes('description:')) {\n result.errors.push('Missing \"description\" field in frontmatter');\n result.passed = false;\n } else {\n const descMatch = frontmatter.match(/description:\\s*(.+)/);\n if (descMatch && descMatch[1].length > 1024) {\n result.errors.push(\n `Description too long (${descMatch[1].length} chars > 1024 limit)`,\n );\n result.passed = false;\n }\n }\n\n return result;\n }\n}\n\n/**\n * Recommends imperative mood over conversational style.\n */\nexport class InstructionsStyleRule implements ValidationRule {\n name = 'Instruction Style';\n\n async validate(content: string): Promise<RuleResult> {\n const frontmatterMatch = content.match(/^---\\n([\\s\\S]*?)\\n---\\n([\\s\\S]*)$/);\n const body = frontmatterMatch ? frontmatterMatch[2] : content;\n const bodyLines = body.split('\\n');\n let isInCodeBlock = false;\n let hasConversationalStyle = false;\n\n const conversationalPatterns =\n /^(?:\\s*[-*+]\\s*|\\s*\\d+\\.\\s*)(?:you should|please|let's|we can|I recommend)/i;\n\n for (const line of bodyLines) {\n if (line.trim().startsWith('```')) {\n isInCodeBlock = !isInCodeBlock;\n continue;\n }\n if (isInCodeBlock) continue;\n\n if (conversationalPatterns.test(line)) {\n hasConversationalStyle = true;\n break;\n }\n }\n\n if (hasConversationalStyle) {\n return {\n passed: true,\n errors: [],\n warnings: [\n 'Consider using imperative mood instead of conversational style in instructions',\n ],\n };\n }\n\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Ensures the mandatory priority section is present.\n */\nexport class PriorityRule implements ValidationRule {\n name = 'Priority Section';\n\n async validate(content: string): Promise<RuleResult> {\n if (!content.includes('## **Priority:')) {\n return {\n passed: false,\n errors: ['Missing priority section'],\n warnings: [],\n };\n }\n return { passed: true, errors: [], warnings: [] };\n }\n}\n\n/**\n * Validates the directory structure surrounding the skill file.\n */\nexport class DirectoryStructureRule implements ValidationRule {\n name = 'Directory Structure';\n\n async validate(_content: string, filePath: string): Promise<RuleResult> {\n const result: RuleResult = { passed: true, errors: [], warnings: [] };\n const skillDir = path.dirname(filePath);\n\n // Check scripts\n const scriptsDir = path.join(skillDir, 'scripts');\n if (await fs.pathExists(scriptsDir)) {\n const scriptFiles = await fs.readdir(scriptsDir);\n for (const file of scriptFiles) {\n if (!['.py', '.js', '.ts', '.sh'].includes(path.extname(file))) {\n result.warnings.push(`Script without standard extension: ${file}`);\n }\n }\n }\n\n // Check references\n const refsDir = path.join(skillDir, 'references');\n if (await fs.pathExists(refsDir)) {\n const refFiles = await fs.readdir(refsDir);\n if (refFiles.filter((f) => f.endsWith('.md')).length === 0) {\n result.warnings.push(\n 'References directory exists but contains no .md files',\n );\n }\n }\n\n return result;\n }\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport pc from 'picocolors';\nimport { GitService } from './GitService';\nimport { SkillDiscoveryService } from './SkillDiscoveryService';\nimport {\n DirectoryStructureRule,\n FrontmatterRule,\n InstructionsStyleRule,\n PriorityRule,\n SizeRule,\n} from './validation/rules';\nimport { ValidationRule } from './validation/types';\n\n/**\n * Result of validating a single skill file.\n */\nexport interface SkillValidationResult {\n /** Relative path to the skill file. */\n file: string;\n /** List of validation error messages. */\n errors: string[];\n /** List of validation warning messages. */\n warnings: string[];\n /** Whether the file passed all mandatory validation rules. */\n passed: boolean;\n}\n\n/**\n * Aggregated summary of all validation results.\n */\nexport interface ValidationSummary {\n /** Total number of skills validated. */\n total: number;\n /** Number of skills that passed validation. */\n passed: number;\n /** Number of skills that failed validation. */\n failed: number;\n /** Cumulative number of warnings across all skills. */\n warnings: number;\n}\n\n/**\n * Service for validating skill files (SKILL.md) and repository metadata.\n * Enforces size limits, frontmatter requirements, and imperative instruction style.\n * Uses a Rule Pattern for modular validation.\n */\nexport class SkillValidator {\n private results: SkillValidationResult[] = [];\n private skillDiscovery = new SkillDiscoveryService();\n private gitService = new GitService();\n private rules: ValidationRule[] = [\n new SizeRule(),\n new FrontmatterRule(),\n new InstructionsStyleRule(),\n new PriorityRule(),\n new DirectoryStructureRule(),\n ];\n\n /**\n * Runs the complete validation suite.\n * @param validateAll Whether to validate all skills or just changed ones\n * @returns Exit code (0 for success, 1 for failure)\n */\n async run(validateAll: boolean = false): Promise<number> {\n try {\n const summary = await this.validateAllSkills(validateAll);\n this.printSummary(summary);\n return summary.failed > 0 ? 1 : 0;\n } catch (error) {\n console.error(\n pc.red(\n `ā Validation error: ${error instanceof Error ? error.stack : error}`,\n ),\n );\n return 1;\n }\n }\n\n /**\n * Validates all identified skill files in the repository.\n * @param validateAll Whether to validate all skills or just changed ones\n * @returns Summary of validation results\n */\n async validateAllSkills(\n validateAll: boolean = false,\n ): Promise<ValidationSummary> {\n const rootDir = this.gitService.findProjectRoot();\n const skillsDir = path.join(rootDir, 'skills');\n\n if (!(await fs.pathExists(skillsDir))) {\n throw new Error(`skills/ directory not found (searched at ${skillsDir})`);\n }\n\n const skillFiles = validateAll\n ? await this.skillDiscovery.findAllSkills(skillsDir)\n : await this.skillDiscovery.findChangedSkills();\n\n console.log(\n pc.blue(\n `š Found ${skillFiles.length} ${validateAll ? '' : 'changed '}skills to validate\\n`,\n ),\n );\n\n for (const skillFile of skillFiles) {\n const result = await this.validateSkill(skillFile);\n this.results.push(result);\n\n if (result.passed) {\n console.log(pc.green(`ā
${result.file}`));\n result.warnings.forEach((warning) =>\n console.log(pc.yellow(` ā ļø ${warning}`)),\n );\n } else {\n console.log(pc.red(`ā ${result.file}`));\n result.errors.forEach((error) => console.log(pc.red(` ā ${error}`)));\n }\n }\n\n await this.validateMetadata(rootDir);\n\n return this.generateSummary();\n }\n\n private async validateSkill(\n skillFile: string,\n ): Promise<SkillValidationResult> {\n const rootDir = this.gitService.findProjectRoot();\n const result: SkillValidationResult = {\n file: path.relative(rootDir, skillFile),\n errors: [],\n warnings: [],\n passed: true,\n };\n\n try {\n const content = await fs.readFile(skillFile, 'utf8');\n\n for (const rule of this.rules) {\n const ruleResult = await rule.validate(content, skillFile);\n if (!ruleResult.passed) {\n result.passed = false;\n }\n result.errors.push(...ruleResult.errors);\n result.warnings.push(...ruleResult.warnings);\n }\n } catch (error) {\n result.errors.push(\n `Failed to read or validate file: ${error instanceof Error ? error.message : error}`,\n );\n result.passed = false;\n }\n\n return result;\n }\n\n private async validateMetadata(rootDir: string): Promise<void> {\n const metadataPath = path.join(rootDir, 'skills', 'metadata.json');\n\n try {\n if (!(await fs.pathExists(metadataPath))) {\n throw new Error('skills/metadata.json not found');\n }\n\n const metadata = await fs.readJson(metadataPath);\n if (!metadata.categories) {\n throw new Error('metadata.json missing \"categories\" field');\n }\n\n for (const [category, config] of Object.entries(metadata.categories)) {\n const catConfig = config as { version?: string; tag_prefix?: string };\n\n if (!catConfig.version || !catConfig.tag_prefix) {\n throw new Error(\n `Category \"${category}\" missing required fields (version, tag_prefix) in metadata.json`,\n );\n }\n\n console.log(\n pc.green(\n `ā
Category metadata valid: ${category} (v${catConfig.version}, ${catConfig.tag_prefix})`,\n ),\n );\n }\n } catch (error) {\n throw new Error(\n `Metadata validation failed: ${error instanceof Error ? error.message : error}`,\n );\n }\n }\n\n private generateSummary(): ValidationSummary {\n const summary: ValidationSummary = {\n total: this.results.length,\n passed: 0,\n failed: 0,\n warnings: 0,\n };\n\n for (const result of this.results) {\n if (result.passed) {\n summary.passed++;\n } else {\n summary.failed++;\n }\n summary.warnings += result.warnings.length;\n }\n\n return summary;\n }\n\n printSummary(summary: ValidationSummary): void {\n console.log('\\n' + '='.repeat(50));\n console.log(pc.blue('š VALIDATION SUMMARY'));\n console.log('='.repeat(50));\n\n console.log(pc.green(`Passed: ${summary.passed}`));\n console.log(pc.red(`Failed: ${summary.failed}`));\n\n if (summary.failed > 0) {\n console.log(\n '\\n' + pc.red('ā Validation failed! Please fix the errors above.'),\n );\n } else {\n console.log('\\n' + pc.green('ā
All skills passed validation!'));\n\n if (summary.warnings > 0) {\n console.log(\n pc.yellow(\n `ā ļø ${summary.warnings} warnings found. Consider addressing them for better token efficiency.`,\n ),\n );\n }\n }\n }\n}\n","import { SkillValidator } from '../services/SkillValidator';\n\n/**\n * Command for validating the integrity and format of skills in the local directory.\n * Useful for development and CI/CD pipelines to ensure skills follow the standard.\n */\nexport class ValidateCommand {\n /**\n * Executes the validation flow.\n * @param options Command options, including `all` to validate all skills instead of only changed ones.\n */\n async run(options: { all?: boolean } = {}) {\n const validator = new SkillValidator();\n const exitCode = await validator.run(options.all ?? false);\n process.exit(exitCode);\n }\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport dotenv from 'dotenv';\nimport { FeedbackCommand } from './commands/feedback';\nimport { HooksCommand } from './commands/hooks';\nimport { InitCommand } from './commands/init';\nimport { ListSkillsCommand } from './commands/list-skills';\nimport { McpCommand } from './commands/mcp';\nimport { SyncCommand } from './commands/sync';\nimport { UpgradeCommand } from './commands/upgrade';\nimport { ValidateCommand } from './commands/validate-skills';\n\n// Load .env from current directory (for development and other env vars)\ndotenv.config();\n\nconst program = new Command();\n\nprogram\n .name('agent-skills-standard')\n .description(\n 'A CLI to manage and sync AI agent skills for Cursor, Claude, Copilot, Windsurf, and more.',\n )\n .version('2.4.4');\n\nprogram\n .command('init')\n .description('Initialize a .skillsrc configuration file interactively')\n .action(async () => {\n const init = new InitCommand();\n await init.run();\n });\n\nprogram\n .command('sync')\n .description('Sync skills to AI Agent skill directories')\n .option(\n '-y, --yes',\n 'Automatically confirm interactive prompts (e.g. update versions)',\n )\n .option(\n '--snippets',\n 'Generate JSON config snippets in ./mcp-config-snippets/; if MCP is disabled, run snippet-only mode',\n )\n .action(async (options) => {\n const sync = new SyncCommand();\n await sync.run(options);\n });\n\nprogram\n .command('list-skills')\n .description('List available framework skills and detection status')\n .option('-f, --framework <framework>', 'The framework to list skills for')\n .action(async (options) => {\n const cmd = new ListSkillsCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('validate')\n .description('Validate skill format and token efficiency standards')\n .option('--all', 'Validate all skills instead of only changed ones')\n .action(async (options) => {\n const cmd = new ValidateCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('feedback')\n .description('Report skill improvement opportunities or AI agent mistakes')\n .option(\n '--skill <skill>',\n 'The skill ID (e.g., flutter/bloc-state-management)',\n )\n .option('--issue <issue>', 'Brief description of the issue')\n .option('--model <model>', 'AI agent model (e.g., Claude 3.5 Sonnet)')\n .option('--context <context>', 'Additional context (e.g., framework version)')\n .option('--suggestion <suggestion>', 'Suggested improvement')\n .option(\n '--skill-instruction <instruction>',\n 'Exact quote from skill that was violated (AI auto-report)',\n )\n .option(\n '--actual-action <action>',\n 'What you actually did instead of following skill (AI auto-report)',\n )\n .option(\n '--decision-reason <reason>',\n 'Why you chose this approach instead (AI auto-report)',\n )\n .option(\n '--loaded-skills <skills>',\n 'Comma-separated list of currently loaded skills (platform-provided)',\n )\n .option(\n '--root-cause <cause>',\n 'Why the violation happened: AMBIGUOUS_RULE | MISSING_COVERAGE | OUTDATED_GUIDANCE | COMPETING_RULES | PATTERN_MISMATCH',\n )\n .option('--user-intent <intent>', 'What the user was trying to achieve')\n .option(\n '--skill-gap <gap>',\n 'What change to the SKILL.md would prevent this violation next time',\n )\n .action(async (options: Record<string, string>) => {\n const cmd = new FeedbackCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('upgrade')\n .description('Upgrade the CLI to the latest version')\n .option('--dry-run', 'Check for updates without installing')\n .action(async (options) => {\n const cmd = new UpgradeCommand();\n await cmd.run(options);\n });\n\nprogram\n .command('mcp <action> [scope]')\n .description(\n 'Manage the optional MCP server integration. Actions: status | enable | disable | scope <project|user|snippets-only|disabled> | install | uninstall | snippets',\n )\n .option(\n '--scope <scope>',\n 'Override scope for install (project|user|snippets-only|disabled)',\n )\n .option(\n '--from <from>',\n 'For uninstall: project | user | all (default: project)',\n )\n .action(\n async (\n action: string,\n positional: string | undefined,\n opts: Record<string, string>,\n ) => {\n // Allow `ags mcp scope project` (positional) AND `ags mcp scope --scope project`.\n const merged: Record<string, string> = { ...opts };\n if (positional) merged.scope = opts.scope ?? positional;\n const cmd = new McpCommand();\n await cmd.run(action, merged);\n },\n );\n\nprogram\n .command('hooks <action>')\n .description(\n 'Manage the PreToolUse skill-loader hook. Actions: status | install | uninstall',\n )\n .action(async (action: string) => {\n const cmd = new HooksCommand();\n await cmd.run(action);\n });\n\nprogram.parse();\n"],"mappings":"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"}
|