UNPKG

aiwg

Version:

Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo

183 lines 6.5 kB
/** * Shared platform directory path utilities * * Provides consistent path resolution for agents, commands, and skills across all platforms. */ import { join } from 'path'; import { homedir } from 'os'; /** * Get the commands directory for a given platform * * @param platform - Target platform * @param projectPath - Project root directory * @returns Full path to commands directory */ export function getCommandsDirectory(platform, projectPath) { const dirs = { 'claude': '.claude/commands', 'factory': '.factory/commands', 'cursor': '.cursor/commands', 'codex': '.codex/commands', // Codex commands are a static built-in enum in codex-rs; .codex/commands/ files are not auto-scanned. Path keeps writing per ADR-1 always-deploy invariant — files remain operator-visible and bridged via AGENTS.md links. See #1104. 'copilot': '.github/agents', 'hermes': '', // Hermes commands are statically registered in Python; no file-based command directory 'opencode': '.opencode/command', // OpenCode scans .opencode/command/**/*.md via ConfigCommand.load() (PUW-006 #1107) 'openclaw': join(homedir(), '.openclaw', 'commands'), 'warp': '.warp/commands', // Not natively discovered — content delivered via WARP.md 'windsurf': '.windsurf/workflows', 'generic': 'commands', }; const dir = dirs[platform]; if (!dir) return ''; // Absolute paths (home-dir providers) are returned as-is if (dir.startsWith('/')) return dir; return join(projectPath, dir); } /** * Get the agents directory for a given platform * * @param platform - Target platform * @param projectPath - Project root directory * @returns Full path to agents directory */ export function getAgentsDirectory(platform, projectPath) { const dirs = { 'claude': '.claude/agents', 'factory': '.factory/droids', 'cursor': '.cursor/agents', 'codex': '.codex/agents', 'copilot': '.github/agents', 'hermes': '', // Aggregated into AGENTS.md at project root 'opencode': '', // OpenCode agents are scanned via {agent,agents}/**/*.md glob (#773); not used by this getter — see PROVIDER_PATHS in src/cli/handlers/use.ts 'openclaw': join(homedir(), '.openclaw', 'agents'), 'warp': '.warp/agents', // Not natively discovered — content delivered via WARP.md 'windsurf': '.windsurf/agents', 'generic': 'agents', }; const dir = dirs[platform]; if (!dir) return ''; if (dir.startsWith('/')) return dir; return join(projectPath, dir); } /** * Get the skills directory for a given platform * * Skills are mainly a Claude concept; other platforms map to commands/agents. * * @param platform - Target platform * @param projectPath - Project root directory * @returns Full path to skills directory */ export function getSkillsDirectory(platform, projectPath) { const dirs = { 'claude': '.claude/skills', 'factory': '.factory/skills', 'cursor': '.cursor/skills', 'codex': '.codex/skills', 'copilot': '.github/skills', 'hermes': join(homedir(), '.hermes', 'skills'), 'opencode': '.opencode/skill', 'openclaw': join(homedir(), '.openclaw', 'skills'), 'warp': '.warp/skills', 'windsurf': '.windsurf/skills', 'generic': 'skills', }; const dir = dirs[platform]; if (!dir) return ''; if (dir.startsWith('/')) return dir; return join(projectPath, dir); } /** * Get the file extension for artifacts on a given platform * * @param platform - Target platform * @returns File extension (with dot) */ export function getFileExtension(platform) { if (platform === 'cursor') return '.json'; return '.md'; } /** * Get the rules/config directory for a given platform * * @param platform - Target platform * @param projectPath - Project root directory * @returns Full path to rules/config directory */ export function getRulesDirectory(platform, projectPath) { const dirs = { 'claude': '.claude/rules', 'factory': '.factory/rules', 'cursor': '.cursor/rules', 'codex': '.codex/rules', 'copilot': '.github/copilot-rules', 'hermes': '', // Not applicable — Hermes uses AGENTS.md 'opencode': '.opencode/rule', 'openclaw': join(homedir(), '.openclaw', 'rules'), 'warp': '.warp/rules', // Not natively discovered — content delivered via WARP.md 'windsurf': '.windsurf/rules', 'generic': 'rules', }; const dir = dirs[platform]; if (!dir) return ''; if (dir.startsWith('/')) return dir; return join(projectPath, dir); } /** * Check if platform uses aggregated files (vs individual files) * * @param platform - Target platform * @returns True if platform uses aggregated agent/command files */ export function usesAggregatedFiles(platform) { return platform === 'windsurf' || platform === 'warp'; } /** * Get the main config file name for a platform * * @param platform - Target platform * @returns Config file name */ export function getConfigFileName(platform) { const configs = { 'claude': 'CLAUDE.md', 'factory': 'AGENTS.md', 'cursor': 'AGENTS.md', // PUW-037 (#1138): .cursorrules deprecated; Cursor reads AGENTS.md + .cursor/rules/ MDC files 'codex': 'AGENTS.md', 'copilot': 'copilot-instructions.md', 'hermes': 'AGENTS.md', 'opencode': 'AGENTS.md', 'openclaw': 'AGENTS.md', 'warp': 'WARP.md', 'windsurf': '.windsurfrules', 'generic': 'README.md', }; return configs[platform]; } /** * Get all platform directories for a project * * @param platform - Target platform * @param projectPath - Project root directory * @returns Object with all platform-specific directories */ export function getPlatformDirectories(platform, projectPath) { return { agents: getAgentsDirectory(platform, projectPath), commands: getCommandsDirectory(platform, projectPath), skills: getSkillsDirectory(platform, projectPath), rules: getRulesDirectory(platform, projectPath), extension: getFileExtension(platform), config: join(projectPath, getConfigFileName(platform)), aggregated: usesAggregatedFiles(platform), }; } //# sourceMappingURL=platform-paths.js.map