#!/usr/bin/env node
import { Command, Option } from 'commander';
import { existsSync, readFileSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
// Lazy import helpers - commands are loaded on-demand to reduce startup time (~10x faster --help)
// Each command module is only imported when its action handler is invoked.
const lazy = {
    init: () => import('../cli/init.js').then((m) => m.initCommand),
    analyze: () => import('../cli/analyze.js').then((m) => m.analyzeCommand),
    generate: () => import('../cli/generate.js').then((m) => m.generateCommand),
    memory: () => import('../cli/memory.js').then((m) => m.memoryCommand),
    worktree: () => import('../cli/worktree.js').then((m) => m.worktreeCommand),
    sync: () => import('../cli/sync.js').then((m) => m.syncCommand),
    droids: () => import('../cli/droids.js').then((m) => m.droidsCommand),
    coord: () => import('../cli/coord.js').then((m) => m.coordCommand),
    agent: () => import('../cli/agent.js').then((m) => m.agentCommand),
    deploy: () => import('../cli/deploy.js').then((m) => m.deployCommand),
    task: () => import('../cli/task.js').then((m) => m.taskCommand),
    model: () => import('../cli/model.js').then((m) => m.registerModelCommands),
    mcpRouter: () => import('../cli/mcp-router.js').then((m) => m.mcpRouterCommand),
    dashboard: () => import('../cli/dashboard.js').then((m) => m.dashboardCommand),
    hooks: () => import('../cli/hooks.js'),
    patterns: () => import('../cli/patterns.js').then((m) => m.patternsCommand),
    skill: () => import('../cli/skill.js').then((m) => m.skillCommand),
    setup: () => import('../cli/setup.js').then((m) => m.setupCommand),
    setupMcpRouter: () => import('../cli/setup-mcp-router.js').then((m) => m.setupMcpRouter),
    compliance: () => import('../cli/compliance.js').then((m) => m.complianceCommand),
    schemaDiff: () => import('../cli/schema-diff.js').then((m) => m.registerSchemaDiffCommand),
    rtk: () => import('../cli/rtk.js'),
    toolCalls: () => import('../cli/tool-calls.js').then((m) => m.toolCallsCommand),
    policy: () => import('../cli/policy.js').then((m) => m.registerPolicyCommands),
    expertRoute: () => import('../cli/expert-route.js').then((m) => m.expertRouteCommand),
    harness: () => import('../cli/harness.js').then((m) => m.harnessCommand),
    ideate: () => import('../cli/ideate.js').then((m) => m.ideateCommand),
    deliver: () => import('../cli/deliver.js').then((m) => m.deliverCommand),
};
// Read version from package.json
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));
const program = new Command();
program
    .name('uap')
    .description('Universal AI agent memory system for Claude Code, Factory.AI, VSCode, and OpenCode')
    .version(packageJson.version);
program
    .command('init')
    .description('Initialize agent context in the current project')
    .option('-p, --platform <platforms...>', 'Target platforms (claude, factory, vscode, opencode, omp, all)', ['all'])
    .option('--web', 'Generate AGENT.md for web platforms (claude.ai, factory.ai)')
    .option('--no-memory', 'Skip memory system setup')
    .option('--no-worktrees', 'Skip worktree workflow setup')
    .option('--patterns', 'Enable pattern RAG setup (auto-detected by default)')
    .option('--no-patterns', 'Skip pattern RAG setup')
    .option('--pipeline-only', 'Enforce pipeline-only infrastructure changes (no direct kubectl/terraform)')
    .option('--systemd-services', 'Optionally scaffold user systemd services for llama.cpp and anthropic proxy')
    .option('-f, --force', 'Overwrite existing configuration')
    .action(async (options) => {
    const cmd = await lazy.init();
    await cmd(options);
});
program
    .command('setup')
    .description('Full one-command setup: init + start Qdrant + install Python deps + index patterns')
    .option('-p, --platform <platforms...>', 'Target platforms (claude, factory, vscode, opencode, omp, cline, codex, aider, continue, windsurf, zed, copilot, jetbrains, swe-agent, all)', ['all'])
    .option('--no-patterns', 'Skip pattern RAG setup')
    .option('--no-memory', 'Skip memory system setup')
    .option('--systemd-services', 'Optionally scaffold user systemd services for llama.cpp and anthropic proxy')
    .option('-d, --project-dir <path>', 'Target project directory (defaults to current working directory)')
    .option('-i, --interactive', 'Run interactive setup wizard with feature toggles')
    .action(async (options) => {
    (await lazy.setup())(options);
});
program
    .command('analyze')
    .description('Analyze project structure and generate metadata')
    .option('-o, --output <format>', 'Output format (json, yaml, md)', 'json')
    .option('--save', 'Save analysis to .uap.analysis.json')
    .action(async (options) => {
    (await lazy.analyze())(options);
});
program
    .command('generate')
    .description('Generate or update CLAUDE.md and related files')
    .option('-f, --force', 'Overwrite existing files without confirmation')
    .option('-d, --dry-run', 'Show what would be generated without writing')
    .option('-p, --platform <platform>', 'Generate for specific platform only')
    .option('--template <template>', 'Template to use (default or custom)')
    .option('--sections <sections>', 'Comma-separated sections to include')
    .option('--web', 'Generate AGENT.md for web platforms (claude.ai, factory.ai)')
    .option('--pipeline-only', 'Enforce pipeline-only infrastructure changes (no direct kubectl/terraform)')
    .action(async (options) => {
    (await lazy.generate())(options);
});
program
    .command('memory')
    .description('Manage agent memory system')
    .addCommand(new Command('status').description('Show memory system status').action(async () => {
    (await lazy.memory())('status');
}))
    .addCommand(new Command('start')
    .description('Start memory services (Qdrant container)')
    .action(async () => {
    (await lazy.memory())('start');
}))
    .addCommand(new Command('stop').description('Stop memory services').action(async () => {
    (await lazy.memory())('stop');
}))
    .addCommand(new Command('query')
    .description('Query long-term memory')
    .argument('<search>', 'Search term')
    .option('-n, --limit <number>', 'Max results', '10')
    .option('-k, --top-k <number>', 'Alias for --limit', '10')
    .option('-t, --threshold <number>', 'Minimum similarity score (0-1)', '0.35')
    .action(async (search, options) => {
    (await lazy.memory())('query', { search, ...options });
}))
    .addCommand(new Command('store')
    .description('Store a memory (applies write gate unless --force)')
    .argument('<content>', 'Memory content')
    .option('-t, --tags <tags>', 'Comma-separated tags')
    .option('-i, --importance <number>', 'Importance score (1-10)', '5')
    .option('-f, --force', 'Bypass write gate (store without quality check)')
    .action(async (content, options) => {
    (await lazy.memory())('store', { content, ...options });
}))
    .addCommand(new Command('prepopulate')
    .description('Prepopulate memory from documentation and git history')
    .option('--docs', 'Import from documentation only')
    .option('--git', 'Import from git history only')
    .option('-n, --limit <number>', 'Limit git commits to analyze', '500')
    .option('--since <date>', 'Only analyze commits since date (e.g., "2024-01-01")')
    .option('-v, --verbose', 'Show detailed output')
    .action(async (options) => {
    (await lazy.memory())('prepopulate', options);
}))
    .addCommand(new Command('promote')
    .description('Review and promote daily log entries to working/semantic memory')
    .action(async (options) => {
    (await lazy.memory())('promote', options);
}))
    .addCommand(new Command('correct')
    .description('Correct a memory (propagates across all tiers, marks old as superseded)')
    .argument('<search>', 'Search term to find the memory to correct')
    .option('-c, --correction <text>', 'The corrected content')
    .option('-r, --reason <reason>', 'Reason for correction')
    .action(async (search, options) => {
    (await lazy.memory())('correct', { search, ...options });
}))
    .addCommand(new Command('maintain')
    .description('Run maintenance: decay, prune stale, archive old, remove duplicates')
    .option('-v, --verbose', 'Show detailed output')
    .action(async (options) => {
    (await lazy.memory())('maintain', options);
}));
// Pattern RAG Commands
program
    .command('patterns')
    .description('Manage pattern RAG (on-demand pattern retrieval via Qdrant)')
    .addCommand(new Command('status')
    .description('Show pattern RAG status and collection info')
    .action(async () => {
    (await lazy.patterns())('status');
}))
    .addCommand(new Command('index')
    .description('Index patterns from CLAUDE.md into Qdrant')
    .option('-v, --verbose', 'Show detailed output')
    .action(async (options) => {
    (await lazy.patterns())('index', options);
}))
    .addCommand(new Command('query')
    .description('Query patterns by task description')
    .argument('<search>', 'Task description to match')
    .option('-n, --top <number>', 'Number of results', '2')
    .option('--min-score <number>', 'Minimum similarity score', '0.35')
    .option('--format <format>', 'Output format (text, json, context)', 'text')
    .action(async (search, options) => {
    (await lazy.patterns())('query', { search, ...options });
}))
    .addCommand(new Command('generate')
    .description('Generate Python index/query scripts from config')
    .option('-f, --force', 'Overwrite existing scripts')
    .action(async (options) => {
    (await lazy.patterns())('generate', options);
}));
program
    .command('worktree')
    .description('Manage git worktrees')
    .addCommand(new Command('create')
    .description('Create a new worktree for a feature')
    .argument('<slug>', 'Feature slug (e.g., add-user-auth)')
    .option('-f, --from <branch>', 'Base branch (defaults to current)')
    .option('-d, --description <description>', 'Optional worktree description')
    .action(async (slug, options) => {
    (await lazy.worktree())('create', { slug, ...options });
}))
    .addCommand(new Command('list').description('List all worktrees').action(async () => {
    (await lazy.worktree())('list');
}))
    .addCommand(new Command('pr')
    .description('Create PR from worktree')
    .argument('<id>', 'Worktree ID')
    .option('--draft', 'Create as draft PR')
    .action(async (id, options) => {
    (await lazy.worktree())('pr', { id, ...options });
}))
    .addCommand(new Command('finish')
    .description('Sync, merge PR, and auto-cleanup worktree')
    .argument('<id>', 'Worktree ID')
    .action(async (id) => {
    (await lazy.worktree())('finish', { id });
}))
    .addCommand(new Command('cleanup')
    .description('Remove worktree and delete branch')
    .argument('<id>', 'Worktree ID')
    .action(async (id) => {
    (await lazy.worktree())('cleanup', { id });
}))
    .addCommand(new Command('ensure')
    .description('Check if working inside a worktree')
    .option('--strict', 'Exit with code 1 if not in a worktree (for use as a gate)')
    .action(async (options) => {
    (await lazy.worktree())('ensure', { strict: options.strict });
}))
    .addCommand(new Command('prune')
    .description('Prune stale worktrees older than specified days')
    .option('-o, --older-than <days>', 'Only prune worktrees older than N days', '30')
    .option('-f, --force', 'Skip confirmation prompt')
    .option('-n, --dry-run', 'Preview without making changes')
    .action(async (options) => {
    (await lazy.worktree())('prune', {
        olderThan: parseInt(options.olderThan, 10),
        force: options.force ?? false,
        dryRun: options.dryRun ?? false,
    });
}));
program
    .command('sync')
    .description('Sync configuration between platforms')
    .option('--from <platform>', 'Source platform (claude, factory, vscode, opencode)')
    .option('--to <platform>', 'Target platform(s)')
    .option('--dry-run', 'Preview changes without writing files')
    .action(async (options) => {
    (await lazy.sync())(options);
});
program
    .command('droids')
    .description('Manage custom droids/agents')
    .addCommand(new Command('list').description('List all droids').action(async () => {
    (await lazy.droids())('list');
}))
    .addCommand(new Command('add')
    .description('Add a new droid')
    .argument('<name>', 'Droid name')
    .option('-t, --template <template>', 'Use built-in template')
    .action(async (name, options) => {
    (await lazy.droids())('add', { name, ...options });
}))
    .addCommand(new Command('import')
    .description('Import droids from another platform')
    .argument('<path>', 'Path to import from')
    .action(async (path) => {
    (await lazy.droids())('import', { path });
}))
    .addCommand(new Command('validate')
    .description('Validate droid files against capability-router expectations')
    .option('-q, --quiet', 'Suppress report output (exit code only)')
    .action(async (options) => {
    (await lazy.droids())('validate', options);
}));
program
    .command('expert-route')
    .description('Recommend an expert droid chain for a task description')
    .argument('<description...>', 'Task description (quoted or space-separated)')
    .option('-f, --files <files...>', 'Affected file paths to refine routing')
    .option('--json', 'Emit JSON instead of a human-readable report')
    .action(async (descriptionParts, options) => {
    const description = descriptionParts.join(' ');
    const cmd = await lazy.expertRoute();
    await cmd(description, options);
});
// Fable-parity delivery loop
program
    .command('deliver')
    .description('Convergence loop: iterate a model against real completion gates until delivery')
    .argument('<instruction...>', 'Task instruction for the model')
    .option('--max-turns <n>', 'Maximum execute→verify iterations', '5')
    .option('-m, --model <preset>', 'Model preset id (default: $UAP_DELIVER_MODEL or qwen35-a3b)')
    .option('--project-root <path>', 'Project whose gates define delivery (default: cwd)')
    .option('--endpoint <url>', 'Override the model endpoint (OpenAI-compatible /v1)')
    .option('--temperature <t>', 'Sampling temperature (default: execution-profile value)')
    .option('--gates <ids>', 'Comma-separated gate subset (build,typecheck,test,lint)')
    .option('--candidates <n>', 'Best-of-N exploration: candidates per turn (2-8)')
    .option('--critic', 'Structured critique of failed turns (extra model call per failure)')
    .option('--practices', 'Inject learned best-practice cards and record new ones on success')
    .option('--no-semantic', 'Use keyword (not embedding) retrieval for practice cards')
    .option('--escalate', 'Escalation ladder on stagnation (widen exploration -> critic -> stronger model)')
    .option('--escalate-model <preset>', 'Stronger model preset for escalation (default: $UAP_ESCALATE_MODEL)')
    .option('--dry-run', 'Show detected gates and plan without calling the model')
    .option('--json', 'Emit JSON result')
    .action(async (instructionParts, options) => {
    const cmd = await lazy.deliver();
    await cmd(instructionParts.join(' '), options);
});
// HALO harness-optimization commands
const harness = program
    .command('harness')
    .description('HALO harness optimization: analyze execution traces for systemic failures');
harness
    .command('analyze')
    .description('Run the HALO engine over collected traces (wraps the `halo` CLI)')
    .option('-t, --traces <file>', 'Trace JSONL file (default: $UAP_HALO_TRACE_PATH or .uap/halo/traces.jsonl)')
    .option('-p, --prompt <prompt>', 'Question to ask HALO about the traces')
    .option('--json', 'Request JSON output from HALO')
    .action(async (options) => {
    const cmd = await lazy.harness();
    await cmd('analyze', options);
});
harness
    .command('status')
    .description('Show HALO trace collection state (enabled, path, span count)')
    .option('--json', 'Emit JSON instead of a human-readable report')
    .action(async (options) => {
    const cmd = await lazy.harness();
    await cmd('status', options);
});
// Open-collider divergent-ideation commands
const ideate = program
    .command('ideate')
    .description('Divergent ideation (open-collider): generate non-trivial ideas for hard problems');
ideate
    .command('setup')
    .description('Scaffold an ideation project under projects/<name>/')
    .argument('<name>', 'Project name')
    .option('--force', 'Overwrite an existing project')
    .option('--json', 'Emit JSON instead of a human-readable report')
    .action(async (name, options) => {
    const cmd = await lazy.ideate();
    await cmd('setup', name, options);
});
ideate
    .command('run')
    .description('Drive the brainstorm flow for a project (Skill mode is free)')
    .argument('<name>', 'Project name')
    .action(async (name, options) => {
    const cmd = await lazy.ideate();
    await cmd('run', name, options);
});
ideate
    .command('ideas')
    .description('Print the curated ideas produced for a project')
    .argument('<name>', 'Project name')
    .option('--json', 'Emit JSON instead of a human-readable report')
    .action(async (name, options) => {
    const cmd = await lazy.ideate();
    await cmd('ideas', name, options);
});
// Agent Coordination Commands
program
    .command('coord')
    .description('Agent coordination and status')
    .addCommand(new Command('status')
    .description('Show coordination status (agents, claims, deploys)')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.coord())('status', options);
}))
    .addCommand(new Command('flush')
    .description('Force execute all pending deploys')
    .action(async (options) => {
    (await lazy.coord())('flush', options);
}))
    .addCommand(new Command('cleanup')
    .description('Clean up stale agents and expired data')
    .action(async (options) => {
    (await lazy.coord())('cleanup', options);
}));
program
    .command('agent')
    .description('Agent lifecycle, work coordination, and communication')
    .addCommand(new Command('register')
    .description('Register a new agent (each agent works in isolated worktree)')
    .option('-n, --name <name>', 'Agent name (required)')
    .option('-i, --id <id>', 'Stable agent ID (optional; generated if omitted). Use a known ID so other agents can address this one directly.')
    .option('-c, --capabilities <caps>', 'Comma-separated capabilities')
    .option('-w, --worktree <branch>', 'Git worktree branch this agent is using')
    .action(async (options) => {
    (await lazy.agent())('register', options);
}))
    .addCommand(new Command('heartbeat')
    .description('Send heartbeat for an agent')
    .option('-i, --id <id>', 'Agent ID (required)')
    .action(async (options) => {
    (await lazy.agent())('heartbeat', options);
}))
    .addCommand(new Command('status')
    .description('Show agent status')
    .option('-i, --id <id>', 'Agent ID (optional, shows all if omitted)')
    .action(async (options) => {
    (await lazy.agent())('status', options);
}))
    .addCommand(new Command('announce')
    .description('Announce intent to work on a resource (informational, enables overlap detection)')
    .option('-i, --id <id>', 'Agent ID (required)')
    .option('-r, --resource <resource>', 'Resource path (file/directory) to work on')
    .option('--intent <intent>', 'Work intent: editing, reviewing, refactoring, testing, documenting')
    .option('-d, --description <desc>', 'Description of planned changes')
    .option('-f, --files <files>', 'Comma-separated list of files that will be affected')
    .option('--minutes <minutes>', 'Estimated time to complete (in minutes)')
    .action(async (options) => {
    (await lazy.agent())('announce', options);
}))
    .addCommand(new Command('complete')
    .description('Mark work as complete on a resource (notifies other agents)')
    .option('-i, --id <id>', 'Agent ID (required)')
    .option('-r, --resource <resource>', 'Resource that work is complete on')
    .action(async (options) => {
    (await lazy.agent())('complete', options);
}))
    .addCommand(new Command('overlaps')
    .description('Check for overlapping work (merge conflict risk assessment)')
    .option('-r, --resource <resource>', 'Resource to check (omit to show all active work)')
    .action(async (options) => {
    (await lazy.agent())('overlaps', options);
}))
    .addCommand(new Command('broadcast')
    .description('Broadcast a message to all agents')
    .option('-i, --id <id>', 'Agent ID (required)')
    .option('-c, --channel <channel>', 'Channel: broadcast, deploy, review, coordination')
    .option('-m, --message <message>', 'Message payload (JSON or string)')
    .option('-p, --priority <priority>', 'Priority 1-10', '5')
    .action(async (options) => {
    (await lazy.agent())('broadcast', options);
}))
    .addCommand(new Command('send')
    .description('Send a direct message to another agent')
    .option('-i, --id <id>', 'Sender agent ID (required)')
    .option('-t, --to <to>', 'Recipient agent ID (required)')
    .option('-m, --message <message>', 'Message payload (JSON or string)')
    .option('-p, --priority <priority>', 'Priority 1-10', '5')
    .action(async (options) => {
    (await lazy.agent())('send', options);
}))
    .addCommand(new Command('receive')
    .description('Receive pending messages')
    .option('-i, --id <id>', 'Agent ID (required)')
    .option('-c, --channel <channel>', 'Filter by channel')
    .option('--no-mark-read', 'Do not mark messages as read')
    .action(async (options) => {
    (await lazy.agent())('receive', options);
}))
    .addCommand(new Command('deregister')
    .description('Deregister an agent')
    .option('-i, --id <id>', 'Agent ID (required)')
    .action(async (options) => {
    (await lazy.agent())('deregister', options);
}));
program
    .command('deploy')
    .description('Deployment batching and execution')
    .addCommand(new Command('queue')
    .description('Queue a deploy action for batching')
    .option('-a, --agent-id <id>', 'Agent ID (required)')
    .option('-t, --action-type <type>', 'Action type: commit, push, merge, deploy, workflow')
    .option('--target <target>', 'Target (branch, environment, workflow name)')
    .option('-m, --message <message>', 'Commit message (for commit action)')
    .option('-f, --files <files>', 'Comma-separated files (for commit action)')
    .option('-r, --remote <remote>', 'Git remote (for push action)', 'origin')
    .option('--force', 'Force push (for push action)')
    .option('--ref <ref>', 'Git ref (for workflow action)')
    .option('--inputs <inputs>', 'Workflow inputs as JSON (for workflow action)')
    .option('-p, --priority <priority>', 'Priority 1-10', '5')
    .action(async (options) => {
    (await lazy.deploy())('queue', options);
}))
    .addCommand(new Command('batch')
    .description('Create a batch from pending deploy actions')
    .option('-v, --verbose', 'Show detailed batch info')
    .action(async (options) => {
    (await lazy.deploy())('batch', options);
}))
    .addCommand(new Command('execute')
    .description('Execute a deploy batch')
    .option('-b, --batch-id <id>', 'Batch ID (required)')
    .option('--dry-run', 'Show what would be executed without running')
    .action(async (options) => {
    (await lazy.deploy())('execute', options);
}))
    .addCommand(new Command('status')
    .description('Show deploy queue status')
    .option('-v, --verbose', 'Show detailed status')
    .action(async (options) => {
    (await lazy.deploy())('status', options);
}))
    .addCommand(new Command('flush')
    .description('Flush all pending deploys (batch and execute)')
    .option('-v, --verbose', 'Show detailed results')
    .option('--dry-run', 'Show what would be executed without running')
    .action(async (options) => {
    (await lazy.deploy())('flush', options);
}))
    .addCommand(new Command('config')
    .description('Show deploy batch configuration (window settings)')
    .action(async (options) => {
    (await lazy.deploy())('config', options);
}))
    .addCommand(new Command('set-config')
    .description('Set deploy batch configuration (window settings)')
    .option('--message <json>', 'JSON object with window settings, e.g. {"commit":60000,"push":3000}')
    .action(async (options) => {
    (await lazy.deploy())('set-config', options);
}))
    .addCommand(new Command('urgent')
    .description('Enable or disable urgent mode (fast batch windows)')
    .option('--on', 'Enable urgent mode')
    .option('--off', 'Disable urgent mode (default)')
    .action(async (options) => {
    (await lazy.deploy())('urgent', { force: options.on, remote: options.off });
}));
// Task Management
program
    .command('task')
    .description('Task management (superior alternative to Beads)')
    .addCommand(new Command('create')
    .description('Create a new task')
    .option('-t, --title <title>', 'Task title (required)')
    .option('-d, --description <desc>', 'Task description')
    .option('--type <type>', 'Type: task, bug, feature, epic, chore, story', 'task')
    .option('-p, --priority <priority>', 'Priority: 0-4 (P0=critical, P4=backlog)', '2')
    .option('-l, --labels <labels>', 'Comma-separated labels')
    .option('--parent <parent>', 'Parent task ID (for hierarchy)')
    .option('-n, --notes <notes>', 'Markdown notes')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.task())('create', options);
}))
    .addCommand(new Command('list')
    .description('List tasks')
    .option('-s, --filter-status <status>', 'Filter by status (comma-separated)')
    .option('--status <status>', 'Alias for --filter-status')
    .option('--filter-type <type>', 'Filter by type (comma-separated)')
    .option('--filter-priority <priority>', 'Filter by priority (comma-separated)')
    .option('-a, --filter-assignee <assignee>', 'Filter by assignee')
    .option('-l, --filter-labels <labels>', 'Filter by labels (comma-separated)')
    .option('--search <search>', 'Search in title/description')
    .option('--show-blocked', 'Show only blocked tasks')
    .option('--show-ready', 'Show only ready tasks')
    .option('-v, --verbose', 'Show more details')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    const filterStatus = options.filterStatus ?? options.status;
    (await lazy.task())('list', { ...options, filterStatus });
}))
    .addCommand(new Command('show')
    .description('Show task details')
    .argument('<id>', 'Task ID')
    .option('-v, --verbose', 'Show history')
    .option('--json', 'Output as JSON')
    .action(async (id, options) => {
    (await lazy.task())('show', { id, ...options });
}))
    .addCommand(new Command('update')
    .description('Update a task')
    .argument('<id>', 'Task ID')
    .option('-t, --title <title>', 'New title')
    .option('-d, --description <desc>', 'New description')
    .option('--type <type>', 'New type')
    .option('-s, --status <status>', 'New status: open, in_progress, blocked, done, wont_do')
    .option('-p, --priority <priority>', 'New priority (0-4)')
    .option('-a, --assignee <assignee>', 'Assign to agent (use "none" to unassign)')
    .option('-w, --worktree <worktree>', 'Set worktree branch')
    .option('-l, --labels <labels>', 'New labels (comma-separated)')
    .option('-n, --notes <notes>', 'New notes')
    .action(async (id, options) => {
    (await lazy.task())('update', { id, ...options });
}))
    .addCommand(new Command('close')
    .description('Close a task (mark as done)')
    .argument('<id>', 'Task ID')
    .option('-r, --reason <reason>', 'Closure reason')
    .action(async (id, options) => {
    (await lazy.task())('close', { id, ...options });
}))
    .addCommand(new Command('delete')
    .description('Delete a task')
    .argument('<id>', 'Task ID')
    .action(async (id) => {
    (await lazy.task())('delete', { id });
}))
    .addCommand(new Command('ready')
    .description('List tasks ready to work on (no blockers)')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.task())('ready', options);
}))
    .addCommand(new Command('blocked')
    .description('List blocked tasks')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.task())('blocked', options);
}))
    .addCommand(new Command('dep')
    .description('Add a dependency between tasks')
    .option('-f, --from <from>', 'Dependent task (the task that is blocked)')
    .option('-t, --to <to>', 'Blocking task (the task that must complete first)')
    .option('--dep-type <type>', 'Dependency type: blocks, related, discovered_from', 'blocks')
    .action(async (options) => {
    (await lazy.task())('dep', options);
}))
    .addCommand(new Command('undep')
    .description('Remove a dependency between tasks')
    .option('-f, --from <from>', 'Dependent task')
    .option('-t, --to <to>', 'Blocking task')
    .action(async (options) => {
    (await lazy.task())('undep', options);
}))
    .addCommand(new Command('claim')
    .description('Claim a task (assign + announce work + create worktree)')
    .argument('<id>', 'Task ID')
    .option('-b, --branch <branch>', 'Worktree branch name')
    .action(async (id, options) => {
    (await lazy.task())('claim', { id, ...options });
}))
    .addCommand(new Command('release')
    .description('Release a task (mark complete + announce)')
    .argument('<id>', 'Task ID')
    .option('-r, --reason <reason>', 'Completion reason')
    .action(async (id, options) => {
    (await lazy.task())('release', { id, ...options });
}))
    .addCommand(new Command('stats')
    .description('Show task statistics')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.task())('stats', options);
}))
    .addCommand(new Command('board')
    .description('Show tasks as a kanban board')
    .action(async (options) => {
    (await lazy.task())('board', options);
}))
    .addCommand(new Command('sync')
    .description('Sync tasks with JSONL file (for git versioning)')
    .action(async (options) => {
    (await lazy.task())('sync', options);
}))
    .addCommand(new Command('compact')
    .description('Compact old closed tasks into summaries')
    .option('--days <days>', 'Compact tasks older than N days', '90')
    .action(async (options) => {
    (await lazy.task())('compact', options);
}));
// Compliance - protocol verification and auto-fix
program
    .command('compliance')
    .description('UAP protocol compliance checking, auditing, and auto-fix')
    .addCommand(new Command('check')
    .description('Run compliance check (schema, memory, Qdrant, worktrees, secrets)')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.compliance())('check', options);
}))
    .addCommand(new Command('report')
    .description('Generate detailed compliance report')
    .option('-o, --output <path>', 'Output file path')
    .option('-f, --format <format>', 'Format: text, markdown, json', 'text')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.compliance())('report', options);
}))
    .addCommand(new Command('audit')
    .description('Deep compliance audit with verbose output')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.compliance())('audit', options);
}))
    .addCommand(new Command('fix')
    .description('Auto-fix compliance issues (schema migrations, Qdrant collections, worktree cleanup)')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.compliance())('fix', options);
}));
program
    .command('coordination')
    .description('Coordination overlap checks and resolution')
    .addCommand(new Command('check')
    .description('Check for overlapping work between agents')
    .option('--agents <agents>', 'Comma-separated agent ids or names')
    .option('-r, --resource <resource>', 'Resource to check')
    .option('-v, --verbose', 'Show detailed overlap analysis')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.coord())('check', options);
}))
    .addCommand(new Command('resolve')
    .description('Resolve identified overlaps')
    .argument('<overlapId>', 'Overlap identifier (resource path)')
    .option('--action <action>', 'Resolution action: assign, merge, delegate')
    .option('--json', 'Output as JSON')
    .action(async (overlapId, options) => {
    (await lazy.coord())('resolve', { overlapId, ...options });
}));
program
    .command('skill')
    .description('Skill management and loading')
    .addCommand(new Command('list')
    .description('List available skills')
    .option('-c, --category <category>', 'Filter by category')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.skill())('list', options);
}))
    .addCommand(new Command('load')
    .description('Load a specific skill for current session')
    .argument('<skill>', 'Skill name')
    .option('-c, --category <category>', 'Filter by category')
    .action(async (skill, options) => {
    (await lazy.skill())('load', { skill, ...options });
}));
program
    .command('update')
    .description('Update CLAUDE.md, memory system, and all related components')
    .option('--dry-run', 'Show what would be updated without making changes')
    .option('--skip-memory', 'Skip memory system updates')
    .option('--skip-qdrant', 'Skip Qdrant collection updates')
    .option('--pipeline-only', 'Enforce pipeline-only infrastructure changes (no direct kubectl/terraform)')
    .option('-v, --verbose', 'Show detailed update information')
    .action(async (options) => {
    const { updateCommand } = await import('../cli/update.js');
    await updateCommand(options);
});
// Dashboard - rich data visualisation and progress tracking
program
    .command('dashboard')
    .alias('dash')
    .description('Rich data visualisation dashboard for tasks, agents, memory, and progress')
    .addCommand(new Command('overview')
    .description('Full system overview with charts and progress bars')
    .option('-v, --verbose', 'Show detailed information')
    .option('--compact', 'Compact output for narrow terminals')
    .action(async (options) => {
    (await lazy.dashboard())('overview', options);
}))
    .addCommand(new Command('tasks')
    .description('Task breakdown with charts, progress bars, and hierarchy trees')
    .option('-v, --verbose', 'Show detailed information')
    .option('--compact', 'Compact output')
    .action(async (options) => {
    (await lazy.dashboard())('tasks', options);
}))
    .addCommand(new Command('agents')
    .description('Agent activity, resource claims, and coordination status')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('agents', options);
}))
    .addCommand(new Command('memory')
    .description('Memory system health, capacity, and layer architecture')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('memory', options);
}))
    .addCommand(new Command('progress')
    .description('Completion tracking with per-priority and per-type progress')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('progress', options);
}))
    .addCommand(new Command('serve')
    .description('Start web-based dashboard server with real-time updates')
    .option('-p, --port <number>', 'Port to listen on (default: 3847)', '3847')
    .action(async (options) => {
    (await lazy.dashboard())('serve', { port: parseInt(options.port) });
}))
    .addCommand(new Command('stats')
    .description('Session context consumption stats with per-tool breakdown')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('stats', options);
}))
    .addCommand(new Command('session')
    .description('Live UAP session state: infrastructure, patterns, skills, git, policies')
    .option('-v, --verbose', 'Show detailed information')
    .option('--compact', 'Compact summary box (for post-task / pre-compact)')
    .action(async (options) => {
    (await lazy.dashboard())('session', options);
}))
    .addCommand(new Command('benchmark')
    .description('Benchmark results and performance comparison dashboard')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('benchmark', options);
}))
    .addCommand(new Command('policies')
    .description('Policy enforcement status and compliance dashboard')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('policies', options);
}))
    .addCommand(new Command('models')
    .description('Multi-model architecture status and routing analytics')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('models', options);
}))
    .addCommand(new Command('export')
    .description('Export dashboard data as JSON for external analysis')
    .option('-o, --output <path>', 'Output file path')
    .action(async (options) => {
    (await lazy.dashboard())('export', options);
}))
    .addCommand(new Command('history')
    .description('Session history and trend analysis')
    .option('-v, --verbose', 'Show detailed information')
    .action(async (options) => {
    (await lazy.dashboard())('history', options);
}));
// Multi-Model Architecture commands - visible in --help, loaded on demand
{
    const modelCmd = program
        .command('model')
        .description('Multi-model architecture management (status, route, plan, compare, presets, select, export, health)')
        .action(async () => {
        // Re-register with full subcommands and re-parse
        const cmds = program.commands;
        const idx = cmds.findIndex((c) => c.name() === 'model');
        if (idx >= 0)
            cmds.splice(idx, 1);
        const registerModelFn = await lazy.model();
        registerModelFn(program);
        await program.parseAsync(process.argv);
    });
    // Show help for model subcommands when invoked without action
    modelCmd.addHelpText('after', '\n  Run `uap model <subcommand>` for details.');
}
// MCP Router - Lightweight hierarchical router for 98%+ token reduction
program
    .command('mcp-router')
    .description('MCP Router - hierarchical router for 98%+ token reduction')
    .addCommand(new Command('start')
    .description('Start the MCP router as a stdio server')
    .option('-c, --config <path>', 'Path to mcp.json config file')
    .option('-v, --verbose', 'Enable verbose logging')
    .action(async (options) => {
    (await lazy.mcpRouter())('start', options);
}))
    .addCommand(new Command('stats')
    .description('Show router statistics (servers, tools, token savings)')
    .option('-c, --config <path>', 'Path to mcp.json config file')
    .option('-v, --verbose', 'Enable verbose logging')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.mcpRouter())('stats', options);
}))
    .addCommand(new Command('discover')
    .description('Discover tools matching a query')
    .option('-q, --query <query>', 'Search query (required)')
    .option('-s, --server <server>', 'Filter to specific server')
    .option('-l, --limit <limit>', 'Max results', '10')
    .option('-c, --config <path>', 'Path to mcp.json config file')
    .option('-v, --verbose', 'Enable verbose logging')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.mcpRouter())('discover', options);
}))
    .addCommand(new Command('list')
    .description('List configured MCP servers')
    .option('-c, --config <path>', 'Path to mcp.json config file')
    .option('--json', 'Output as JSON')
    .action(async (options) => {
    (await lazy.mcpRouter())('list', options);
}));
// Session Hooks - automatic memory injection and pre-compaction flush
program
    .command('hooks')
    .description('Manage session hooks for Claude Code, Factory.AI, Cursor, VSCode, OpenCode, Codex, ForgeCode, Oh-My-Pi, Hermes')
    .addCommand(new Command('install')
    .description('Install UAP session hooks')
    .option('-t, --target <target>', 'Target platform: claude, factory, cursor, vscode, opencode, codex, forgecode, omp, hermes (default: all)')
    .option('-p, --platform <platform>', 'Alias for --target (claude, factory, cursor, vscode, opencode, codex, forgecode, omp, hermes)')
    .action((options) => lazy
    .hooks()
    .then((m) => m.hooksCommand('install', {
    target: (options.target ?? options.platform),
}))))
    .addCommand(new Command('status')
    .description('Show hooks installation status')
    .option('-t, --target <target>', 'Target platform: claude, factory, cursor, vscode, opencode, codex, forgecode, omp, hermes (default: all)')
    .option('-p, --platform <platform>', 'Alias for --target (claude, factory, cursor, vscode, opencode, codex, forgecode, omp, hermes)')
    .action((options) => lazy
    .hooks()
    .then((m) => m.hooksCommand('status', {
    target: (options.target ?? options.platform),
}))))
    .addCommand(new Command('doctor')
    .description('Audit policy-gate coverage across platforms (exit non-zero on gaps)')
    .option('-t, --target <target>', 'Audit a single platform (default: all)')
    .option('-p, --platform <platform>', 'Alias for --target')
    .action((options) => lazy
    .hooks()
    .then((m) => m.hooksCommand('doctor', {
    target: (options.target ?? options.platform),
}))));
// Qwen3.5 Tool Call Fixes - performance optimizations for tool calling
const toolCallsCmd = new Command('tool-calls');
toolCallsCmd.description('Manage Qwen3.5 tool call fixes and chat templates');
toolCallsCmd.addCommand(new Command('setup').description('Install chat templates and Python scripts').action(async () => {
    (await lazy.toolCalls())('setup');
}));
toolCallsCmd.addCommand(new Command('test')
    .description('Run reliability test suite')
    .addOption(new Option('--verbose', 'Verbose output'))
    .action(async () => {
    (await lazy.toolCalls())('test');
}));
toolCallsCmd.addCommand(new Command('status').description('Check current configuration').action(async () => {
    (await lazy.toolCalls())('status');
}));
toolCallsCmd.addCommand(new Command('fix').description('Apply template fixes to existing templates').action(async () => {
    (await lazy.toolCalls())('fix');
}));
program.addCommand(toolCallsCmd);
// RTK (Rust Token Killer) - CLI proxy for 60-90% token savings
const rtkCmd = new Command('rtk');
rtkCmd.description('Manage RTK (Rust Token Killer) integration for token optimization');
rtkCmd.addCommand(new Command('install')
    .description('Install RTK CLI proxy for 60-90% token savings')
    .option('--force', 'Force reinstall')
    .option('--method <method>', 'Installation method (npm, cargo, binary)')
    .action(async (options) => {
    const rtk = await lazy.rtk();
    await rtk.installRTK({
        force: !!options.force,
        method: options.method,
    });
}));
rtkCmd.addCommand(new Command('status').description('Check RTK installation and token savings').action(async () => {
    const rtk = await lazy.rtk();
    await rtk.checkRTKStatus();
}));
rtkCmd.addCommand(new Command('help').description('Show RTK usage information').action(async () => {
    const rtk = await lazy.rtk();
    rtk.showRTKHelp();
}));
program.addCommand(rtkCmd);
// MCP Setup - Configure MCP Router for all platforms
program
    .command('mcp-setup')
    .description('Configure MCP Router for all AI harnesses (Claude, Factory, VSCode, Cursor)')
    .option('--force', 'Force replace existing MCP configurations')
    .option('--verbose', 'Enable verbose output')
    .action(async (options) => {
    const fn = await lazy.setupMcpRouter();
    await fn({ force: !!options.force, verbose: !!options.verbose });
});
// Schema-diff and policy commands - visible in --help, loaded on demand
program
    .command('schema-diff')
    .description('Detect breaking schema changes between branches')
    .option('-b, --base <branch>', 'Base branch/commit to compare against', 'HEAD~1')
    .action(async (_options) => {
    const { registerSchemaDiffCommand } = await import('../cli/schema-diff.js');
    // Remove stub and register real command
    const cmds = program.commands;
    const idx = cmds.findIndex((c) => c.name() === 'schema-diff');
    if (idx >= 0)
        cmds.splice(idx, 1);
    registerSchemaDiffCommand(program);
    await program.parseAsync(process.argv);
});
{
    // The policy command is lazy-loaded but needs to accept arbitrary sub-flags
    // like `-p <id> -c <file>` without strict validation — otherwise commander
    // rejects them before the action can register the real subcommands.
    const policyCmd = program
        .command('policy')
        .description('UAP policy management (list, install, enable, disable, status, add-tool, check, audit, toggle, stage, level)')
        .allowUnknownOption(true)
        .allowExcessArguments(true)
        .action(async () => {
        const cmds = program.commands;
        const idx = cmds.findIndex((c) => c.name() === 'policy');
        if (idx >= 0)
            cmds.splice(idx, 1);
        const registerPolicyFn = await lazy.policy();
        registerPolicyFn(program);
        await program.parseAsync(process.argv);
    });
    policyCmd.addHelpText('after', '\n  Run `uap policy <subcommand>` for details.');
}
// UAP for Oh-My-Pi - dashboard and controls for omp users
const uapOmpCmd = new Command('uap-omp');
uapOmpCmd.description('UAP integration commands for oh-my-pi (omp) users');
// Dashboard command
uapOmpCmd.addCommand(new Command('dashboard')
    .description('Show UAP dashboard with tasks, agents, memory, and worktrees')
    .action(async () => {
    try {
        const uapOmpDir = process.env.HOME + '/.uap/omp';
        const dashboardScript = `${uapOmpDir}/commands/uap-dashboard.sh`;
        if (existsSync(dashboardScript)) {
            execSync(`bash "${dashboardScript}"`, { stdio: 'inherit' });
        }
        else {
            console.error('UAP dashboard not installed. Run: uap-omp install');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error showing dashboard:', err.message);
    }
}));
// Memory command
uapOmpCmd.addCommand(new Command('memory')
    .description('Manage UAP memory for oh-my-pi')
    .addCommand(new Command('status').description('Show memory status').action(() => {
    try {
        const uapOmpDir = process.env.HOME + '/.uap/omp';
        const dbPath = `${uapOmpDir}/memory/short_term.db`;
        if (existsSync(dbPath)) {
            execSync(`sqlite3 "${dbPath}" "SELECT COUNT(*) as total, COUNT(DISTINCT type) as types FROM memories;"`, {
                stdio: 'inherit',
            });
        }
        else {
            console.log('No memory database found. Run: uap-omp install');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error checking memory:', err.message);
    }
}))
    .addCommand(new Command('query')
    .description('Query memory for relevant context')
    .argument('<search>', 'Search term')
    .option('-n, --limit <number>', 'Max results', '5')
    .action((search, options) => {
    try {
        const uapOmpDir = process.env.HOME + '/.uap/omp';
        const dbPath = `${uapOmpDir}/memory/short_term.db`;
        if (existsSync(dbPath)) {
            // Sanitize search term to prevent SQL injection
            const sanitizedSearch = search.replace(/'/g, "''");
            const sanitizedLimit = parseInt(options.limit, 10) || 5;
            execSync(`sqlite3 "${dbPath}" "SELECT content, type, importance FROM memories WHERE content LIKE '%${sanitizedSearch}%' ORDER BY importance DESC LIMIT ${sanitizedLimit};"`, {
                stdio: 'inherit',
            });
        }
        else {
            console.log('No memory database found. Run: uap-omp install');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error querying memory:', err.message);
    }
})));
// Worktree command
uapOmpCmd.addCommand(new Command('worktree')
    .description('Manage UAP worktrees for oh-my-pi')
    .addCommand(new Command('list').description('List active worktrees').action(() => {
    try {
        const uapOmpDir = process.env.HOME + '/.uap/omp';
        const worktreesFile = `${uapOmpDir}/worktrees.json`;
        if (existsSync(worktreesFile)) {
            execSync(`cat "${worktreesFile}" | jq '.'`, { stdio: 'inherit' });
        }
        else {
            console.log('No worktrees tracked. Run: uap-omp install');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error listing worktrees:', err.message);
    }
}))
    .addCommand(new Command('create')
    .description('Create a new worktree')
    .argument('<slug>', 'Worktree slug')
    .action((slug) => {
    try {
        execSync(`uap worktree create ${slug}`, { stdio: 'inherit' });
    }
    catch (error) {
        const err = error;
        console.error('Error creating worktree:', err.message);
    }
})));
// Hooks command
uapOmpCmd.addCommand(new Command('hooks')
    .description('Manage UAP hooks for oh-my-pi')
    .addCommand(new Command('install').description('Install UAP hooks for oh-my-pi').action(() => {
    try {
        const scriptPath = join(__dirname, '../../scripts/omp/uap-omp.sh');
        if (existsSync(scriptPath)) {
            execSync(`bash "${scriptPath}" install`, { stdio: 'inherit' });
        }
        else {
            console.error('UAP hooks script not found. Please rebuild with: npm run build');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error installing hooks:', err.message);
    }
}))
    .addCommand(new Command('status').description('Show hook installation status').action(() => {
    try {
        const scriptPath = join(__dirname, '../../scripts/omp/uap-omp.sh');
        if (existsSync(scriptPath)) {
            execSync(`bash "${scriptPath}" status`, { stdio: 'inherit' });
        }
        else {
            console.error('UAP hooks script not found. Please rebuild with: npm run build');
        }
    }
    catch (error) {
        const err = error;
        console.error('Error checking hook status:', err.message);
    }
})));
program.addCommand(uapOmpCmd);
program.parse();
//# sourceMappingURL=cli.js.map