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

178 lines (174 loc) 7.49 kB
/** * Regenerate Context Files Handler (#1266) * * `aiwg regenerate` — regenerates the cross-provider context files * (AIWG.md + AGENTS.md) without redeploying frameworks, agents, skills, or * commands. Use when context drifts (e.g., editing CLAUDE.md, adding a * framework manifest entry) and you want a fast, focused refresh. * * Scope: context-only. For full redeploy use `aiwg refresh` or `aiwg use`. * * Flags: * --dry-run Print what would change without writing * --provider <name> Target provider (default: auto-detect) * --force Overwrite operator-modified context files (backs up first) * --no-aiwg-md Skip AIWG.md emission * --no-agents-md Skip AGENTS.md emission * * @source @src/cli/router.ts * @issue #1266 */ import * as path from 'path'; import { handlerResultFromError } from '../errors.js'; import * as ui from '../ui.js'; import { generate as generateContextFiles, discoverDeployedArtifacts, shouldEmitContextFiles, } from '../../smiths/context-pipeline/index.js'; // Provider detection mirrors the one in steward.ts (#1262 fix). Kept inline // because they're invoked in different contexts; consolidation can come later. function detectProviderFromEnv() { if (process.env.CLAUDE_CODE_VERSION || process.env.ANTHROPIC_API_KEY) return 'claude'; if (process.env.OPENAI_API_KEY && !process.env.CURSOR_TRACE_ID) return 'codex'; if (process.env.CURSOR_TRACE_ID || process.env.CURSOR_VERSION) return 'cursor'; if (process.env.WINDSURF_VERSION) return 'windsurf'; if (process.env.WARP_SESSION_ID || process.env.WARP_TERMINAL) return 'warp'; if (process.env.COPILOT_AGENT || process.env.GITHUB_COPILOT_TOKEN) return 'copilot'; if (process.env.OPENCLAW_VERSION) return 'openclaw'; if (process.env.FACTORY_AGENT_ID) return 'factory'; if (process.env.OPENCODE_VERSION) return 'opencode'; return 'claude'; } // Minimal provider paths — only what the generator needs to discover deployed // artifacts. Mirrors PROVIDER_PATHS in use.ts; consolidating is a separate // follow-up. const PROVIDER_PATHS_MIN = { claude: { agents: '.claude/agents', skills: '.claude/.aiwg/skills', rules: '.claude/rules', behaviors: '' }, codex: { agents: '.codex/agents', skills: '.agents/skills', rules: '.codex/rules', behaviors: '' }, copilot: { agents: '.github/agents', skills: '.github/.aiwg/skills', rules: '.github/instructions', behaviors: '' }, cursor: { agents: '.cursor/agents', skills: '.cursor/.aiwg/skills', rules: '.cursor/rules', behaviors: '' }, factory: { agents: '.factory/droids', skills: '.factory/.aiwg/skills', rules: '.factory/rules', behaviors: '' }, opencode: { agents: '.opencode/agent', skills: '.opencode/.aiwg/skill', rules: '.opencode/rule', behaviors: '' }, warp: { agents: '.warp/agents', skills: '.warp/.aiwg/skills', rules: '.warp/rules', behaviors: '' }, windsurf: { agents: '.windsurf/agents', skills: '.windsurf/.aiwg/skills', rules: '.windsurf/rules', behaviors: '' }, }; async function handleRegenerate(args, cwd) { if (args.includes('--help') || args.includes('-h')) { console.log(` aiwg regenerate — Regenerate cross-provider context files (AIWG.md + AGENTS.md) Usage: aiwg regenerate [options] Scope: Context-only. Regenerates AIWG.md and AGENTS.md at project root using the canonical context pipeline. Does NOT redeploy frameworks, agents, skills, or commands — use 'aiwg refresh' for that. Options: --dry-run Print what would change; no writes --provider <name> Target provider (default: auto-detect from env) --force Overwrite operator-modified files (backs up first) --no-aiwg-md Skip AIWG.md emission --no-agents-md Skip AGENTS.md emission --help, -h Show this help Examples: aiwg regenerate aiwg regenerate --dry-run aiwg regenerate --provider codex aiwg regenerate --force --no-agents-md `); return; } const dryRun = args.includes('--dry-run'); const force = args.includes('--force'); const skipAiwgMd = args.includes('--no-aiwg-md'); const skipAgentsMd = args.includes('--no-agents-md'); const providerFlag = args.indexOf('--provider'); const provider = providerFlag >= 0 && args[providerFlag + 1] ? args[providerFlag + 1] : detectProviderFromEnv(); const target = cwd; console.log(`${ui.brandMark()} aiwg regenerate${dryRun ? ' (dry run)' : ''}`); console.log(` Provider: ${provider}`); console.log(` Target: ${target}`); if (!shouldEmitContextFiles(provider)) { console.log(` Skip: context files are not emitted for provider '${provider}' (claude uses CLAUDE.md natively; openclaw is home-dir-only).`); return; } if (dryRun) { const aiwgMd = path.join(target, 'AIWG.md'); const agentsMd = path.join(target, 'AGENTS.md'); console.log(''); console.log(` Would regenerate:`); console.log(` - ${path.join(target, '.aiwg', 'AIWG.md')}`); if (!skipAiwgMd) console.log(` - ${aiwgMd}`); if (!skipAgentsMd) console.log(` - ${agentsMd}`); if (provider === 'copilot' && !skipAgentsMd) console.log(` - ${path.join(target, '.github', 'copilot-instructions.md')}`); if (force) console.log(` (with --force: any operator-modified files are backed up first)`); console.log(''); console.log(` Dry run complete — no changes made`); return; } const paths = PROVIDER_PATHS_MIN[provider] ?? PROVIDER_PATHS_MIN.claude; const sections = await discoverDeployedArtifacts(target, { agents: paths.agents, rules: paths.rules, skills: paths.skills, behaviors: paths.behaviors, }); const result = await generateContextFiles({ provider: provider, projectPath: target, sections, detectExistingFiles: true, force, skip: { aiwgMd: skipAiwgMd, agentsMd: skipAgentsMd }, }); if (result.agentsMdPath) { console.log(` OK Wrote AGENTS.md (${result.agentsMdBytes} bytes)`); } if (result.aiwgMdPath) { console.log(` OK Wrote AIWG.md`); } if (result.normalizedAiwgMdPath) { console.log(` OK Wrote .aiwg/AIWG.md`); } for (const w of result.warnings) { console.log(` context-pipeline: ${w}`); } for (const b of result.backupPaths) { console.log(` Backup created: ${b}`); } if (!result.agentsMdPath && !result.aiwgMdPath) { console.log(` No files regenerated (all skipped or refused without --force).`); } else { console.log(` Regenerate complete`); } } export const regenerateHandler = { id: 'regenerate', name: 'Regenerate Context Files', description: 'Regenerate AIWG.md + AGENTS.md without redeploying frameworks (#1266)', category: 'maintenance', aliases: [], async execute(ctx) { try { await handleRegenerate(ctx.args, ctx.cwd); return { exitCode: 0 }; } catch (error) { return handlerResultFromError(error); } }, }; export const regenerateHandlers = [regenerateHandler]; //# sourceMappingURL=regenerate.js.map