reygent-code 1.0.1 → 1.1.1

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/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/child-registry.ts","../src/debug.ts","../src/config.ts","../src/agents.ts","../src/skills.ts","../src/chesstrace/config.ts","../src/task.ts","../src/providers/claude.ts","../src/providers/gemini.ts","../src/providers/codex.ts","../src/providers/openrouter.ts","../src/providers/index.ts","../src/model.ts","../src/telemetry-override.ts","../src/commands/agent.ts","../src/spec.ts","../src/linear.ts","../src/jira.ts","../src/env.ts","../src/chesstrace/index.ts","../src/chesstrace/events.ts","../src/terminal-reset.ts","../src/chesstrace/backends/sqlite.ts","../src/chesstrace/backends/dual.ts","../src/project-detection.ts","../src/telemetry-lifecycle.ts","../src/commands/generate-spec.ts","../src/knowledge/loader.ts","../src/test-env.ts","../src/telemetry-helpers.ts","../src/spawn.ts","../src/planner.ts","../src/generate-spec.ts","../src/live-status.ts","../src/commands/spec.ts","../src/cursor-aware-input.ts","../src/paste-state.ts","../src/pasteable-input.ts","../src/format.ts","../src/commands/run.ts","../src/implement.ts","../src/gate.ts","../src/pr-create.ts","../src/branch-type.ts","../src/pr-review.ts","../src/diff-split.ts","../src/security-review.ts","../src/usage.ts","../src/pricing.ts","../src/knowledge/analyzer.ts","../src/knowledge/manager.ts","../src/retry-prompt.ts","../src/commands/init.ts","../src/commands/skills.ts","../src/registry.ts","../src/commands/review-work.ts","../src/spec-prefix.ts","../src/commands/review-comments.ts","../src/commands/config.ts","../src/commands/telemetry.ts","../src/commands/analyze.ts","../src/telemetry-path.ts","../src/commands/last.ts","../src/commands/knowledge.ts","../src/input-with-timeout.ts","../src/chesstrace/prompt.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport { killAllChildrenProcesses } from \"./child-registry.js\";\nimport { setDebug } from \"./debug.js\";\nimport { setModelOverride, setProviderOverride, validateModel } from \"./model.js\";\nimport { getProvider, PROVIDER_NAMES } from \"./providers/index.js\";\nimport { setTelemetryOverride, isValidTelemetryLevel } from \"./telemetry-override.js\";\nimport { agentCommand } from \"./commands/agent.js\";\nimport { generateSpecCommand } from \"./commands/generate-spec.js\";\nimport { specCommand } from \"./commands/spec.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { registerSkillsCommand } from \"./commands/skills.js\";\nimport { reviewWorkCommand } from \"./commands/review-work.js\";\nimport { reviewCommentsCommand } from \"./commands/review-comments.js\";\nimport { configCommand } from \"./commands/config.js\";\nimport { registerTelemetryCommand } from \"./commands/telemetry.js\";\nimport { registerAnalyzeCommand } from \"./commands/analyze.js\";\nimport { registerLastCommand } from \"./commands/last.js\";\nimport { registerKnowledgeCommand } from \"./commands/knowledge.js\";\nimport { isValidType, VALID_BRANCH_TYPES } from \"./branch-type.js\";\nimport { shouldPromptForTelemetry, promptForTelemetryOptIn } from \"./chesstrace/prompt.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"),\n);\n\nconst program = new Command();\n\nprogram\n .name(\"reygent\")\n .description(\"Reygent CLI tool\")\n .version(pkg.version)\n .option(\"--debug\", \"Show full stack traces on errors (or set REYGENT_DEBUG=1)\")\n .option(\"--model <id>\", \"Model ID (e.g. claude-sonnet-4-5, gemini-2.5-pro, gpt-5.4)\")\n .option(\"--provider <name>\", `AI provider (${PROVIDER_NAMES.join(\", \")})`)\n .option(\"--no-telemetry\", \"Disable telemetry for this run\")\n .option(\"--telemetry-level <level>\", \"Override telemetry level (minimal, standard, verbose)\")\n .option(\"--telemetry-verbose\", \"Shorthand for --telemetry-level verbose\")\n .addHelpText(\"after\", `\n${chalk.yellow(\"Disclaimer:\")} This software is provided \"as is\" with no warranty. AI-generated output should be reviewed by a human. See LICENSE for full terms.`);\n\nprogram\n .command(\"init\")\n .description(\"Initialize .reygent folder with default agent and skill config\")\n .option(\"--dry-run\", \"Preview what files would be created without writing anything\", false)\n .action(initCommand);\n\nprogram\n .command(\"generate-spec\")\n .description(\"Generate a full markdown spec from a short description\")\n .argument(\"[description]\", \"Short description of the feature to spec out\")\n .option(\"--output <file>\", \"Output file path\")\n .option(\"--skip-clarification\", \"Skip clarifying questions and generate spec directly\", false)\n .action(generateSpecCommand);\n\nprogram\n .command(\"spec\")\n .description(\"Load a spec from a markdown file, Jira issue, or Linear issue\")\n .argument(\"<source>\", \"Path to a markdown file, issue key (e.g. PROJ-123), or Linear URL\")\n .option(\"--clarify\", \"Run planner with clarification loop to evaluate spec\", false)\n .option(\"--source <name>\", \"Issue source provider (jira, linear, local) — skips interactive prompt\")\n .action(specCommand);\n\nprogram\n .command(\"agent\")\n .description(\"Start an interactive agent session\")\n .argument(\"[name]\", \"Agent name (dev, qe, planner, security-reviewer, pr-reviewer, adhoc)\")\n .option(\"--spec <source>\", \"Path to a markdown file, issue key, or Linear URL\")\n .action(agentCommand);\n\nprogram\n .command(\"run\")\n .description(\"Run the reygent workflow from spec to reviewed PR\")\n .option(\"--spec <source>\", \"Path to a markdown file, issue key, or Linear URL (prompts if omitted in interactive mode)\")\n .option(\"--type <type>\", \"Branch type (feat, fix, chore, refactor, docs, test, style, perf) — skips interactive prompt\")\n .option(\"--dry-run\", \"Preview workflow stages without executing\", false)\n .option(\"--security-threshold <level>\", \"Minimum severity to fail security review (CRITICAL, HIGH, MEDIUM, LOW)\", \"HIGH\")\n .option(\"--auto-approve\", \"Auto-approve all file edits and actions without prompting\", false)\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .option(\"--skip-clarification\", \"Skip planner clarification and make assumptions\", false)\n .option(\"--max-retries <count>\", \"Max retry attempts when gate tests fail\", \"2\")\n .option(\"--verbose\", \"Show detailed per-agent token and cost breakdown\", false)\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.type && !isValidType(opts.type)) {\n console.error(chalk.red(`Error: Invalid --type \"${opts.type}\". Must be one of: ${VALID_BRANCH_TYPES.join(\", \")} (or feature/bugfix aliases)`));\n process.exit(1);\n }\n })\n .action(runCommand);\n\nprogram\n .command(\"review-work\")\n .description(\"Review current branch and post summary to PR/MR\")\n .option(\"--spec <source>\", \"Spec source with provider prefix (jira:KEY, linear:ID, markdown:FILE) — file paths auto-infer markdown:\")\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .action(reviewWorkCommand);\n\nprogram\n .command(\"review-comments\")\n .description(\"Fetch PR/MR review comments and address them with an agent\")\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .option(\"--auto-approve\", \"Auto-approve plan and execute without prompting\", false)\n .option(\"--retry-commits <count>\", \"Max retries for pre-commit hook failures (default: 3)\", (val) => {\n const num = parseInt(val, 10);\n if (isNaN(num) || num < 0 || num > 10) {\n throw new Error(\"--retry-commits must be between 0 and 10\");\n }\n return num;\n })\n .action(reviewCommentsCommand);\n\nprogram\n .command(\"config\")\n .description(\"Configure default provider, model, and per-agent overrides\")\n .action(configCommand);\n\nregisterTelemetryCommand(program);\nregisterAnalyzeCommand(program);\nregisterLastCommand(program);\nregisterSkillsCommand(program);\nregisterKnowledgeCommand(program);\n\n// Show header on commands that do actual work (not --help or --version)\nconst isHelpOrVersion = process.argv.includes(\"--help\") ||\n process.argv.includes(\"-h\") ||\n process.argv.includes(\"--version\") ||\n process.argv.includes(\"-V\") ||\n process.argv.length <= 2;\n\nif (!isHelpOrVersion) {\n console.log(chalk.bold.cyan(`\\nreygent`) + chalk.gray(` v${pkg.version}`) + \"\\n\");\n}\n\n// Set debug flag, provider, model, and telemetry overrides before any command action runs\nprogram.hook(\"preAction\", async () => {\n if (program.opts().debug) {\n setDebug(true);\n }\n\n try {\n const providerFlag = program.opts().provider;\n if (providerFlag) {\n try {\n // Validate provider name\n getProvider(providerFlag);\n setProviderOverride(providerFlag);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n program.error(message);\n }\n }\n\n // Apply telemetry flag overrides (validate before model to avoid partial execution)\n const noTelemetry = program.opts().telemetry === false;\n const telemetryLevelFlag = program.opts().telemetryLevel;\n const telemetryVerbose = program.opts().telemetryVerbose === true;\n\n if (noTelemetry) {\n setTelemetryOverride({ disabled: true });\n } else if (telemetryVerbose) {\n setTelemetryOverride({ level: \"verbose\" });\n } else if (telemetryLevelFlag) {\n if (!isValidTelemetryLevel(telemetryLevelFlag)) {\n program.error(\n `Invalid --telemetry-level \"${telemetryLevelFlag}\". Must be one of: minimal, standard, verbose`\n );\n }\n setTelemetryOverride({ level: telemetryLevelFlag });\n }\n\n const modelFlag = program.opts().model;\n if (modelFlag) {\n try {\n const resolved = validateModel(modelFlag, providerFlag);\n setModelOverride(resolved);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n program.error(message);\n }\n }\n } catch (err) {\n // Unexpected error in validation - log but continue to telemetry prompt\n if (program.opts().debug) {\n console.error(chalk.gray(\"Validation error:\"), err);\n }\n }\n\n // Show telemetry opt-in prompt on first run (unless --no-telemetry flag set)\n const noTelemetry = program.opts().telemetry === false;\n if (!noTelemetry && shouldPromptForTelemetry()) {\n try {\n await promptForTelemetryOptIn();\n } catch (err) {\n // Ctrl+C from inquirer\n if (err && typeof err === \"object\" && \"name\" in err && (err as { name: string }).name === \"ExitPromptError\") {\n console.log(chalk.yellow(\"\\nTelemetry setup cancelled.\"));\n process.exit(0);\n }\n // Other errors shouldn't block command execution\n if (program.opts().debug) {\n console.error(chalk.gray(\"Telemetry prompt failed:\"), err);\n }\n }\n }\n});\n\n// Fallback SIGINT handler: kill child processes when no live-status handler is active\nprocess.on(\"SIGINT\", () => {\n killAllChildrenProcesses();\n process.exit(130);\n});\n\nprogram.parse();\n","import type { ChildProcess } from \"node:child_process\";\n\nconst activeChildProcesses = new Set<ChildProcess>();\n\nexport function registerChildProcess(child: ChildProcess): void {\n activeChildProcesses.add(child);\n child.on(\"close\", () => {\n activeChildProcesses.delete(child);\n });\n child.on(\"error\", () => {\n activeChildProcesses.delete(child);\n });\n}\n\nexport function killAllChildrenProcesses(): void {\n for (const child of activeChildProcesses) {\n try {\n // Kill entire process group to catch spawned descendants (e.g., vitest)\n if (child.pid && process.platform !== \"win32\") {\n process.kill(-child.pid, \"SIGTERM\");\n } else {\n child.kill(\"SIGTERM\");\n }\n } catch {\n // Already dead — ignore\n }\n }\n activeChildProcesses.clear();\n}\n\n// Kill orphaned child processes on any exit path\nprocess.on(\"exit\", () => {\n killAllChildrenProcesses();\n});\n\n// Handle SIGINT (Ctrl+C) and SIGTERM\nprocess.on(\"SIGINT\", () => {\n killAllChildrenProcesses();\n process.exit(130); // Standard exit code for SIGINT\n});\n\nprocess.on(\"SIGTERM\", () => {\n killAllChildrenProcesses();\n process.exit(143); // Standard exit code for SIGTERM\n});\n","let debugEnabled = false;\n\nexport function setDebug(enabled: boolean): void {\n debugEnabled = enabled;\n}\n\nexport function isDebug(): boolean {\n return debugEnabled || process.env.REYGENT_DEBUG === \"1\";\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport chalk from \"chalk\";\nimport { z } from \"zod\";\nimport type { AgentConfig } from \"./agents.js\";\nimport { builtinAgents } from \"./agents.js\";\nimport { discoverSkills, skillToAgentConfig } from \"./skills.js\";\nimport type { TelemetryUserConfig } from \"./chesstrace/config.js\";\nimport { TelemetryUserConfigSchema, DEFAULT_TELEMETRY_CONFIG } from \"./chesstrace/config.js\";\n\nexport interface SkillsConfig {\n path?: string;\n disabled?: string[];\n}\n\nexport interface ReygentConfig {\n agents?: AgentConfig[];\n skills?: SkillsConfig;\n model?: string;\n provider?: string;\n telemetry?: TelemetryUserConfig;\n}\n\nconst KNOWN_ROLES = [\"developer\", \"general\", \"quality-engineer\", \"security-reviewer\", \"reviewer\", \"planner\"] as const;\n\nconst AgentConfigSchema = z.object({\n name: z.string(),\n description: z.string(),\n systemPrompt: z.string(),\n tools: z.array(z.string()),\n role: z.string().refine(\n (role) => {\n if (!KNOWN_ROLES.includes(role as typeof KNOWN_ROLES[number])) {\n console.log(chalk.yellow(`Warning: unknown agent role \"${role}\"`));\n }\n return true; // Allow all roles, just warn\n },\n { message: \"Role validation warning\" }\n ),\n provider: z.string().optional(),\n model: z.string().optional(),\n});\n\nconst ReygentConfigSchema = z.object({\n provider: z.string().optional(),\n model: z.string().optional(),\n agents: z.array(AgentConfigSchema).optional(),\n skills: z.object({\n path: z.string().optional(),\n disabled: z.array(z.string()).optional(),\n }).optional(),\n telemetry: TelemetryUserConfigSchema.optional(),\n});\n\n/**\n * Resolve config: local .reygent/config.json → global ~/.reygent/config.json → built-in agents.\n */\nexport function loadConfig(): ReygentConfig {\n const localConfigPath = findLocalConfig(process.cwd());\n\n if (localConfigPath) {\n try {\n const raw = readFileSync(localConfigPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n const config = ReygentConfigSchema.parse(parsed);\n return {\n agents: config.agents ?? builtinAgents,\n skills: config.skills ?? {},\n model: config.model,\n provider: config.provider,\n // Apply default telemetry config when local config lacks telemetry field.\n // This preserves partial configs — existing local config.json without telemetry field gets defaults.\n telemetry: config.telemetry ?? DEFAULT_TELEMETRY_CONFIG,\n };\n } catch (err) {\n throw new Error(\n `Failed to parse local config at ${localConfigPath}: ${(err as Error).message}`,\n );\n }\n }\n\n // Try global config\n const globalConfigPath = findGlobalConfig();\n if (globalConfigPath) {\n try {\n const raw = readFileSync(globalConfigPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n const config = ReygentConfigSchema.parse(parsed);\n return {\n agents: config.agents ?? builtinAgents,\n skills: config.skills ?? {},\n model: config.model,\n provider: config.provider,\n // Apply default telemetry config when global config lacks telemetry field.\n // This preserves partial configs — existing global config.json without telemetry field gets defaults.\n telemetry: config.telemetry ?? DEFAULT_TELEMETRY_CONFIG,\n };\n } catch (err) {\n if (err instanceof z.ZodError) {\n const issues = err.issues.map((issue) => {\n const path = issue.path.join(\".\");\n return ` ${path}: ${issue.message}`;\n }).join(\"\\n\");\n throw new Error(\n `Invalid global config at ${globalConfigPath}:\\n${issues}`,\n );\n }\n throw new Error(\n `Failed to parse global config at ${globalConfigPath}: ${(err as Error).message}`,\n );\n }\n }\n\n // No config at all — use builtins\n return {\n agents: builtinAgents,\n skills: {},\n telemetry: DEFAULT_TELEMETRY_CONFIG,\n };\n}\n\n/**\n * Search upward from startDir to find .reygent/config.json\n */\nfunction findLocalConfig(startDir: string): string | null {\n const configDir = findLocalConfigDir(startDir);\n if (!configDir) return null;\n const configPath = join(configDir, \"config.json\");\n return existsSync(configPath) ? configPath : null;\n}\n\n/**\n * Return path to ~/.reygent/config.json if it exists, null otherwise.\n */\nexport function findGlobalConfig(): string | null {\n const configPath = resolveGlobalConfigPath();\n return existsSync(configPath) ? configPath : null;\n}\n\n/**\n * Return the canonical path to ~/.reygent/config.json (whether it exists or not).\n */\nexport function resolveGlobalConfigPath(): string {\n return join(resolveGlobalConfigDir(), \"config.json\");\n}\n\n/**\n * Search upward from startDir to find .reygent/ directory.\n */\nexport function findLocalConfigDir(startDir: string): string | null {\n let currentDir = startDir;\n const root = \"/\";\n\n while (currentDir !== root) {\n const reygentDir = join(currentDir, \".reygent\");\n if (existsSync(reygentDir)) {\n return reygentDir;\n }\n\n const parentDir = join(currentDir, \"..\");\n if (parentDir === currentDir) break;\n currentDir = parentDir;\n }\n\n return null;\n}\n\n/**\n * Resolve the global ~/.reygent directory path.\n */\nexport function resolveGlobalConfigDir(): string {\n return join(homedir(), \".reygent\");\n}\n\n/**\n * Resolve skills directory for given scope.\n * Global always returns a path (~/.reygent/skills/).\n * Local returns null if no .reygent/ dir found.\n */\nexport function resolveSkillsDir(scope: \"local\" | \"global\"): string | null {\n if (scope === \"global\") {\n return join(resolveGlobalConfigDir(), \"skills\");\n }\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) return null;\n const config = loadConfig();\n return resolveSkillsPath(config, configDir);\n}\n\n/**\n * Resolve skills directory path from config.\n */\nexport function resolveSkillsPath(config: ReygentConfig, configDir: string): string {\n const skillsRelPath = config.skills?.path ?? \"skills\";\n return join(configDir, skillsRelPath);\n}\n\n/**\n * Discover skills and convert to AgentConfig[].\n * Scans local skills first, then global ~/.reygent/skills/.\n * Local takes precedence over global on name conflict.\n */\nexport function getSkillsAsAgents(): AgentConfig[] {\n const config = loadConfig();\n const disabled = config.skills?.disabled ?? [];\n const seenNames = new Set<string>();\n const agents: AgentConfig[] = [];\n\n // Local skills\n const localConfigDir = findLocalConfigDir(process.cwd());\n if (localConfigDir) {\n const localSkillsPath = resolveSkillsPath(config, localConfigDir);\n const localManifests = discoverSkills(localSkillsPath);\n for (const m of localManifests) {\n if (disabled.includes(m.name)) continue;\n seenNames.add(m.name);\n agents.push(skillToAgentConfig(m));\n }\n }\n\n // Global skills\n const globalSkillsPath = join(resolveGlobalConfigDir(), \"skills\");\n const globalManifests = discoverSkills(globalSkillsPath);\n for (const m of globalManifests) {\n if (disabled.includes(m.name)) continue;\n if (seenNames.has(m.name)) continue; // local takes precedence\n agents.push(skillToAgentConfig(m));\n }\n\n return agents;\n}\n\n/**\n * Get resolved agents (local or builtin), merged with skills.\n */\nexport function getAgents(): AgentConfig[] {\n const config = loadConfig();\n const configAgents = config.agents ?? [];\n const skillAgents = getSkillsAsAgents();\n\n const configNames = new Set(configAgents.map((a) => a.name));\n const merged = [...configAgents];\n\n for (const skill of skillAgents) {\n if (configNames.has(skill.name)) {\n console.log(\n chalk.yellow(`Warning: skill \"${skill.name}\" shadowed by config agent with same name`),\n );\n continue;\n }\n merged.push(skill);\n }\n\n return merged;\n}\n","export interface AgentConfig {\n name: string;\n description: string;\n systemPrompt: string;\n tools: string[];\n role: string;\n provider?: string;\n model?: string;\n}\n\nexport const builtinAgents: AgentConfig[] = [\n {\n name: \"dev\",\n description: \"Write, edit, and refactor implementation code\",\n systemPrompt:\n \"You are the Dev agent. Your role is to write, edit, and refactor implementation code based on the spec and planner output provided. Write clean, well-structured code that follows the project's existing conventions. Include unit tests alongside your implementation. Do not modify functional test files — those belong to the QE agent.\",\n tools: [\"read\", \"write\", \"bash\", \"search\"],\n role: \"developer\",\n },\n {\n name: \"qe\",\n description:\n \"Write functional tests only — never touches implementation files\",\n systemPrompt:\n \"You are the QE agent. Your role is to write functional and integration tests based on the spec and planner output provided. You must NEVER modify implementation source files — only create and edit test files. Ensure tests cover acceptance criteria, edge cases, and error paths defined in the spec.\",\n tools: [\"read\", \"write\", \"bash\"],\n role: \"quality-engineer\",\n },\n {\n name: \"security-reviewer\",\n description: \"Security and vulnerability review\",\n systemPrompt:\n \"You are the Security Reviewer agent. Your role is to review the codebase for security vulnerabilities, injection risks, insecure defaults, and other OWASP Top 10 issues. You operate in read-only mode — do not modify any files. Produce a structured findings report with severity levels (CRITICAL, HIGH, MEDIUM, LOW) for each issue found.\",\n tools: [\"read\", \"bash\"],\n role: \"security-reviewer\",\n },\n {\n name: \"adhoc\",\n description: \"Freeform one-off commands\",\n systemPrompt:\n \"You are the Adhoc agent. You execute freeform, one-off instructions provided by the user. Follow the instructions precisely and use all available tools as needed to complete the task.\",\n tools: [\"read\", \"write\", \"bash\", \"search\"],\n role: \"general\",\n },\n {\n name: \"planner\",\n description: \"Validate and normalise specs, produce structured breakdowns\",\n systemPrompt:\n \"You are the Planner agent. Your role is to validate and normalise the incoming spec into a structured breakdown of goals, tasks, constraints, and definition of done. If the spec is ambiguous or missing acceptance criteria, flag the issues clearly. Do not write or modify any code — your output is a structured plan for downstream agents.\",\n tools: [\"read\"],\n role: \"planner\",\n },\n {\n name: \"pr-reviewer\",\n description: \"PR creation, pushing, and code review\",\n systemPrompt:\n \"You are the PR Reviewer agent. Your role is to create git branches, commit changes, open pull requests via gh, and review diffs. When reviewing, produce structured findings including a summary, inline comments grouped by file, and a recommendation (approve, request changes, or comment).\",\n tools: [\"read\", \"git\", \"gh\"],\n role: \"reviewer\",\n },\n];\n","import { readFileSync, readdirSync, statSync, existsSync } from \"node:fs\";\nimport { join, basename, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { AgentConfig } from \"./agents.js\";\n\nexport interface SkillManifest {\n name: string;\n description: string;\n license?: string;\n compatibility?: string;\n metadata?: Record<string, string>;\n allowedTools?: string[];\n body: string;\n skillPath: string;\n}\n\nconst SKILL_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst MAX_SKILL_NAME_LENGTH = 64;\n\n/**\n * Validate skill name: lowercase, hyphens, 1-64 chars,\n * no consecutive/leading/trailing hyphens.\n */\nexport function validateSkillName(name: string): boolean {\n if (!name || name.length > MAX_SKILL_NAME_LENGTH) return false;\n if (name.includes(\"--\")) return false;\n return SKILL_NAME_RE.test(name);\n}\n\n/**\n * Parse SKILL.md content into a SkillManifest.\n * Expects YAML frontmatter delimited by --- lines.\n */\nexport function parseSkillMd(content: string, skillPath: string): SkillManifest {\n const trimmed = content.trim();\n if (!trimmed.startsWith(\"---\")) {\n throw new Error(\"SKILL.md must start with YAML frontmatter (---)\");\n }\n\n const endIndex = trimmed.indexOf(\"---\", 3);\n if (endIndex === -1) {\n throw new Error(\"SKILL.md frontmatter missing closing ---\");\n }\n\n const yamlStr = trimmed.slice(3, endIndex).trim();\n const body = trimmed.slice(endIndex + 3).trim();\n\n let frontmatter: Record<string, unknown>;\n try {\n frontmatter = parseYaml(yamlStr);\n } catch (err) {\n throw new Error(`Invalid YAML in SKILL.md frontmatter: ${(err as Error).message}`);\n }\n\n if (!frontmatter || typeof frontmatter !== \"object\") {\n throw new Error(\"SKILL.md frontmatter must be a YAML object\");\n }\n\n const name = frontmatter.name;\n const description = frontmatter.description;\n\n if (typeof name !== \"string\" || !name) {\n throw new Error(\"SKILL.md frontmatter requires 'name' (string)\");\n }\n if (typeof description !== \"string\" || !description) {\n throw new Error(\"SKILL.md frontmatter requires 'description' (string)\");\n }\n\n if (!validateSkillName(name)) {\n throw new Error(\n `Invalid skill name \"${name}\": must be 1-64 lowercase chars, hyphens allowed (no consecutive/leading/trailing)`,\n );\n }\n\n // allowed-tools: spec uses space-separated string, but we also accept arrays\n const rawTools = frontmatter[\"allowed-tools\"];\n let allowedTools: string[] | undefined;\n if (rawTools !== undefined) {\n if (typeof rawTools === \"string\") {\n allowedTools = rawTools.split(/\\s+/).filter(Boolean);\n } else if (Array.isArray(rawTools)) {\n allowedTools = rawTools\n .map((tool, index) => {\n if (typeof tool !== \"string\") {\n const type = tool === null ? \"null\" : Array.isArray(tool) ? \"array\" : typeof tool;\n throw new Error(\n `SKILL.md 'allowed-tools' array entries must be strings; found ${type} at index ${index}`,\n );\n }\n return tool.trim();\n })\n .filter(Boolean);\n } else {\n throw new Error(\"SKILL.md 'allowed-tools' must be a space-separated string or array\");\n }\n }\n\n const metadata = frontmatter.metadata;\n if (metadata !== undefined && (typeof metadata !== \"object\" || metadata === null)) {\n throw new Error(\"SKILL.md 'metadata' must be an object\");\n }\n\n return {\n name,\n description,\n license: typeof frontmatter.license === \"string\" ? frontmatter.license : undefined,\n compatibility: typeof frontmatter.compatibility === \"string\" ? frontmatter.compatibility : undefined,\n metadata: metadata as Record<string, string> | undefined,\n allowedTools: allowedTools as string[] | undefined,\n body,\n skillPath,\n };\n}\n\n/**\n * Strip tool qualifiers: \"Bash(git:*)\" → \"bash\", lowercase, dedup.\n */\nexport function mapToolNames(allowedTools: string[]): string[] {\n const mapped = allowedTools.map((tool) => {\n const parenIndex = tool.indexOf(\"(\");\n const base = parenIndex !== -1 ? tool.slice(0, parenIndex) : tool;\n return base.toLowerCase().trim();\n });\n return [...new Set(mapped)];\n}\n\n/**\n * Load a single skill from a directory containing SKILL.md.\n */\nexport function loadSkillFromDirectory(dirPath: string): SkillManifest {\n const absPath = resolve(dirPath);\n const skillMdPath = join(absPath, \"SKILL.md\");\n\n if (!existsSync(skillMdPath)) {\n throw new Error(`No SKILL.md found in ${absPath}`);\n }\n\n const content = readFileSync(skillMdPath, \"utf-8\");\n const manifest = parseSkillMd(content, absPath);\n\n const dirName = basename(absPath);\n if (manifest.name !== dirName) {\n throw new Error(\n `Skill name \"${manifest.name}\" does not match directory name \"${dirName}\"`,\n );\n }\n\n return manifest;\n}\n\n/**\n * Scan a directory for subdirectories containing SKILL.md.\n * Returns all valid manifests, logs warnings for invalid ones.\n */\nexport function discoverSkills(skillsPath: string): SkillManifest[] {\n const absPath = resolve(skillsPath);\n\n if (!existsSync(absPath)) {\n return [];\n }\n\n const entries = readdirSync(absPath);\n const manifests: SkillManifest[] = [];\n\n for (const entry of entries) {\n const entryPath = join(absPath, entry);\n\n try {\n const stat = statSync(entryPath);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n\n const skillMdPath = join(entryPath, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const manifest = loadSkillFromDirectory(entryPath);\n manifests.push(manifest);\n } catch {\n // Skip invalid skills silently — config.ts handles warnings\n }\n }\n\n return manifests;\n}\n\n/**\n * Convert a SkillManifest to an AgentConfig.\n */\nexport function skillToAgentConfig(skill: SkillManifest): AgentConfig {\n const tools = skill.allowedTools ? mapToolNames(skill.allowedTools) : [\"read\"];\n const role = skill.metadata?.role ?? \"skill\";\n\n return {\n name: skill.name,\n description: skill.description,\n systemPrompt: skill.body,\n tools,\n role,\n };\n}\n","import { z } from 'zod';\n\n/**\n * Telemetry level enumeration\n * - minimal: Only critical events (errors, warnings). Use in CI environments or production deployments where bandwidth/storage is limited.\n * - standard: Normal usage events including commands, success/failure outcomes. Use for interactive development and typical debugging workflows.\n * - verbose: Detailed diagnostic events including timing, internal state transitions, API calls. Use when troubleshooting specific issues or developing Reygent itself.\n */\nexport type TelemetryConfigLevel = 'minimal' | 'standard' | 'verbose';\n\n/**\n * Storage backend type\n */\nexport type TelemetryBackend = 'sqlite';\n\n/**\n * Telemetry user configuration (stored in .reygent/config.json)\n */\nexport interface TelemetryUserConfig {\n /**\n * Enable/disable telemetry (undefined = unset, prompts on first run)\n */\n enabled?: boolean;\n\n /**\n * Telemetry capture level\n */\n level: TelemetryConfigLevel;\n\n /**\n * Storage backend\n */\n backend: TelemetryBackend;\n\n /**\n * Retention period in days\n */\n retention: number;\n}\n\n/**\n * Zod schema for telemetry user configuration\n */\nexport const TelemetryUserConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: z.enum(['minimal', 'standard', 'verbose']),\n backend: z.enum(['sqlite']),\n retention: z.number().int().positive(),\n});\n\n/**\n * Default telemetry configuration\n */\nexport const DEFAULT_TELEMETRY_CONFIG: TelemetryUserConfig = {\n enabled: undefined,\n level: 'standard',\n backend: 'sqlite',\n retention: 30,\n};\n","import type { SpecPayload } from \"./spec.js\";\n\nexport type AgentName =\n | \"dev\"\n | \"qe\"\n | \"security-reviewer\"\n | \"planner\"\n | \"pr-reviewer\"\n | \"adhoc\";\n\nexport type StageKind =\n | { kind: \"agent\"; agent: AgentName }\n | { kind: \"parallel\"; agents: AgentName[] }\n | { kind: \"gate\"; agent: AgentName; condition: string };\n\nexport interface TaskStage {\n name: string;\n description: string;\n execution: StageKind;\n}\n\nexport interface StageResult {\n stage: string;\n success: boolean;\n output: string;\n}\n\nexport interface PlannerOutput {\n goals: string[];\n tasks: string[];\n constraints: string[];\n dod: string[];\n}\n\nexport interface PlannerClarification {\n needsClarification: true;\n questions: string[];\n}\n\nexport type PlannerResult = PlannerOutput | PlannerClarification;\n\nexport interface DevOutput {\n files: string[];\n}\n\nexport interface QEOutput {\n testFiles: string[];\n}\n\nexport interface ImplementOutput {\n dev: DevOutput | null;\n qe: QEOutput | null;\n}\n\nexport interface GateResult {\n passed: boolean;\n output: string;\n}\n\nexport interface GateOutput {\n unitTests?: GateResult;\n functionalTests?: GateResult;\n}\n\nexport type Severity = \"CRITICAL\" | \"HIGH\" | \"MEDIUM\" | \"LOW\";\n\nexport interface SecurityFinding {\n severity: Severity;\n description: string;\n location?: { file: string; line?: number };\n}\n\nexport interface SecurityReviewOutput {\n severity: Severity;\n findings: SecurityFinding[];\n}\n\nexport interface PRCreateOutput {\n branch: string;\n commitMessage: string;\n prUrl: string;\n prNumber: number;\n}\n\nexport interface PRReviewComment {\n file: string;\n line: number | null;\n comment: string;\n}\n\nexport interface PRReviewOutput {\n summary: string;\n comments: PRReviewComment[];\n recommendedActions: string[];\n}\n\nexport interface TaskContext {\n spec: SpecPayload;\n plan?: PlannerOutput;\n implement?: ImplementOutput;\n gates?: GateOutput;\n securityReview?: SecurityReviewOutput;\n prCreate?: PRCreateOutput;\n prReview?: PRReviewOutput;\n results: StageResult[];\n}\n\nexport class TaskError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskError\";\n }\n}\n\nexport const PIPELINE: readonly TaskStage[] = [\n {\n name: \"plan\",\n description: \"Generate structured plan from spec\",\n execution: { kind: \"agent\", agent: \"planner\" },\n },\n {\n name: \"implement\",\n description: \"Implement code and write functional tests in parallel\",\n execution: { kind: \"parallel\", agents: [\"dev\", \"qe\"] },\n },\n {\n name: \"gate-unit-tests\",\n description: \"Verify unit tests pass\",\n execution: { kind: \"gate\", agent: \"dev\", condition: \"unit-tests-pass\" },\n },\n {\n name: \"gate-functional-tests\",\n description: \"Verify functional tests pass\",\n execution: {\n kind: \"gate\",\n agent: \"qe\",\n condition: \"functional-tests-pass\",\n },\n },\n {\n name: \"security-review\",\n description: \"Security and vulnerability review\",\n execution: { kind: \"agent\", agent: \"security-reviewer\" },\n },\n {\n name: \"pr-create\",\n description: \"Create pull request\",\n execution: { kind: \"agent\", agent: \"pr-reviewer\" },\n },\n {\n name: \"pr-review\",\n description: \"Review pull request\",\n execution: { kind: \"agent\", agent: \"pr-reviewer\" },\n },\n] as const;\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport { constants } from \"node:os\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { UsageInfo } from \"../usage.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\ninterface StreamAssistantMessage {\n type: \"assistant\";\n message: {\n content: Array<\n | { type: \"tool_use\"; name: string; input: Record<string, unknown> }\n | { type: \"text\"; text: string }\n >;\n };\n}\n\nexport interface StreamResultMessage {\n type: \"result\";\n subtype: string;\n result: string;\n is_error?: boolean;\n api_error_status?: number;\n total_cost_usd?: number;\n duration_ms?: number;\n num_turns?: number;\n input_tokens?: number;\n output_tokens?: number;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\ntype StreamEvent = StreamAssistantMessage | StreamResultMessage | { type: string };\n\nfunction formatToolDetail(name: string, input: Record<string, unknown>): string {\n switch (name) {\n case \"Read\":\n case \"Write\":\n case \"Edit\":\n return typeof input.file_path === \"string\" ? input.file_path : \"\";\n case \"Bash\": {\n const cmd = typeof input.command === \"string\" ? input.command : \"\";\n return cmd.length > 80 ? cmd.slice(0, 80) + \"…\" : cmd;\n }\n case \"Glob\":\n return typeof input.pattern === \"string\" ? input.pattern : \"\";\n case \"Grep\":\n return typeof input.pattern === \"string\" ? `/${input.pattern}/` : \"\";\n default:\n return \"\";\n }\n}\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"claude-sonnet-4-5-20250929\", label: \"Sonnet 4.5 (recommended)\" },\n { id: \"claude-opus-4-6\", label: \"Opus 4.6\" },\n { id: \"claude-haiku-4-5-20251001\", label: \"Haiku 4.5\" },\n { id: \"claude-sonnet-4-20250514\", label: \"Sonnet 4\" },\n { id: \"claude-3-5-sonnet-20241022\", label: \"3.5 Sonnet\" },\n { id: \"claude-3-5-haiku-20241022\", label: \"3.5 Haiku\" },\n { id: \"claude-3-opus-20240229\", label: \"3 Opus\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {\n \"claude-sonnet-4-5\": \"claude-sonnet-4-5-20250929\",\n \"claude-haiku-4-5\": \"claude-haiku-4-5-20251001\",\n \"claude-sonnet-4\": \"claude-sonnet-4-20250514\",\n \"claude-3-5-sonnet\": \"claude-3-5-sonnet-20241022\",\n \"claude-3.5-sonnet\": \"claude-3-5-sonnet-20241022\",\n \"claude-3-5-haiku\": \"claude-3-5-haiku-20241022\",\n \"claude-3.5-haiku\": \"claude-3-5-haiku-20241022\",\n \"claude-3-opus\": \"claude-3-opus-20240229\",\n};\n\nconst DEFAULT_MODEL = \"claude-sonnet-4-5-20250929\";\n\n/** Extract token counts from a Claude CLI stream result message. */\nexport function extractTokenUsage(msg: StreamResultMessage): {\n inputTokens: number | undefined;\n outputTokens: number | undefined;\n cachedTokens: number | undefined;\n cacheWriteTokens: number | undefined;\n} {\n const usageData = msg.usage;\n const hasInput = usageData?.input_tokens !== undefined ||\n usageData?.cache_creation_input_tokens !== undefined ||\n usageData?.cache_read_input_tokens !== undefined ||\n msg.input_tokens !== undefined;\n const baseInput = usageData?.input_tokens ?? msg.input_tokens ?? 0;\n const cacheCreation = usageData?.cache_creation_input_tokens ?? 0;\n const cacheRead = usageData?.cache_read_input_tokens ?? 0;\n const inputTokens = hasInput ? baseInput + cacheCreation + cacheRead : undefined;\n // outputTokens: no cache fields apply to output, so undefined means \"no data\"\n const outputTokens = usageData?.output_tokens ?? msg.output_tokens;\n\n const cachedTokens = usageData?.cache_read_input_tokens !== undefined\n ? usageData.cache_read_input_tokens\n : undefined;\n const cacheWriteTokens = usageData?.cache_creation_input_tokens !== undefined\n ? usageData.cache_creation_input_tokens\n : undefined;\n\n return { inputTokens, outputTokens, cachedTokens, cacheWriteTokens };\n}\n\n// Safe argv limit for interactive --append-system-prompt\nconst MAX_PROMPT_BYTES = 200_000;\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const claudeAdapter: ProviderAdapter = {\n name: \"claude\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"claude\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"claude CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"claude CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const args = [\n \"-p\", options.prompt,\n \"--output-format\", \"stream-json\",\n \"--verbose\",\n \"--model\", options.model,\n ];\n if (options.autoApprove) {\n args.push(\"--allowedTools\", \"Bash\", \"Edit\", \"Write\", \"Read\", \"Glob\", \"Grep\");\n }\n\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n const child = spawn(\"claude\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let resultText = \"\";\n let resultErrorMessage: string | undefined;\n let resultApiErrorStatus: number | undefined;\n let resultUsage: UsageInfo | undefined;\n const textChunks: string[] = [];\n const name = options.agentName;\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n let stdoutEnded = false;\n let stderrEnded = false;\n let processExitCode: number | null = null;\n\n const maybeResolve = () => {\n if (stdoutEnded && stderrEnded && processExitCode !== null) {\n clearTimeout(timeout);\n const stdout = resultText || textChunks.join(\"\\n\");\n resolve({\n stdout,\n exitCode: processExitCode,\n usage: resultUsage,\n errorMessage: resultErrorMessage,\n apiErrorStatus: resultApiErrorStatus,\n });\n }\n };\n\n const stdoutRL = createInterface({ input: child.stdout! });\n stdoutRL.on(\"line\", (line) => {\n if (!line.trim()) return;\n\n let event: StreamEvent;\n try {\n event = JSON.parse(line) as StreamEvent;\n } catch {\n console.log(chalk.gray(`[${name}]`), line);\n return;\n }\n\n if (event.type === \"assistant\") {\n const msg = event as StreamAssistantMessage;\n for (const block of msg.message.content) {\n if (block.type === \"tool_use\") {\n const detail = formatToolDetail(block.name, block.input);\n if (options.onActivity) {\n options.onActivity({ agent: name, tool: block.name, detail: detail || undefined });\n } else {\n const suffix = detail ? ` ${chalk.gray(detail)}` : \"\";\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${chalk.cyan(\"→\")} ${chalk.blue(block.name)}${suffix}\\n`);\n }\n } else if (block.type === \"text\") {\n if (!options.quiet && !options.onActivity) {\n console.log(chalk.gray(`[${name}]`), block.text);\n }\n textChunks.push(block.text);\n }\n }\n } else if (event.type === \"result\") {\n const msg = event as StreamResultMessage;\n resultText = msg.result;\n if (msg.is_error) {\n resultErrorMessage = msg.result;\n resultApiErrorStatus = msg.api_error_status;\n }\n\n const { inputTokens, outputTokens, cachedTokens, cacheWriteTokens } = extractTokenUsage(msg);\n const hasUsage =\n msg.total_cost_usd !== undefined ||\n msg.duration_ms !== undefined ||\n msg.num_turns !== undefined ||\n inputTokens !== undefined ||\n outputTokens !== undefined;\n\n if (hasUsage) {\n resultUsage = {\n ...(msg.total_cost_usd !== undefined ? { costUsd: msg.total_cost_usd } : {}),\n ...(msg.duration_ms !== undefined ? { durationMs: msg.duration_ms } : {}),\n ...(msg.num_turns !== undefined ? { numTurns: msg.num_turns } : {}),\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(cachedTokens !== undefined ? { cachedTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n provider: \"claude\",\n };\n }\n }\n });\n stdoutRL.on(\"close\", () => {\n stdoutEnded = true;\n maybeResolve();\n });\n\n const stderrRL = createInterface({ input: child.stderr! });\n stderrRL.on(\"line\", (line) => {\n if (options.onActivity) {\n options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${line}\\n`);\n }\n });\n stderrRL.on(\"close\", () => {\n stderrEnded = true;\n maybeResolve();\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n processExitCode = code ?? 1;\n maybeResolve();\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n const promptBytes = Buffer.byteLength(systemPrompt);\n\n if (promptBytes > MAX_PROMPT_BYTES) {\n throw new TaskError(\n `System prompt too large (${promptBytes} bytes, limit ${MAX_PROMPT_BYTES}). ` +\n `Try a smaller spec or split into sections.`,\n );\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(\n \"claude\",\n [\"--append-system-prompt\", systemPrompt, \"--model\", model],\n {\n stdio: \"inherit\",\n detached: false, // Keep in same process group so we can kill descendants\n },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start ${this.name} CLI: ${err.message}. Is ${this.name} installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code, signal) => {\n if (signal) {\n const sigNum = constants.signals[signal];\n resolve(sigNum ? 128 + sigNum : 1);\n } else {\n resolve(code ?? 0);\n }\n });\n });\n },\n};\n","import { spawn } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"gemini-2.5-pro\", label: \"Gemini 2.5 Pro (recommended)\" },\n { id: \"gemini-2.5-flash\", label: \"Gemini 2.5 Flash\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"gemini-2.5-pro\";\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const geminiAdapter: ProviderAdapter = {\n name: \"gemini\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"gemini\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"gemini CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"gemini CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n const args = [\"-p\", options.prompt, \"--output-format\", \"json\"];\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n\n const name = options.agentName;\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n // Gemini CLI requires workspace trust for non-interactive spawns;\n // without this it exits 55 when stdin is not a TTY.\n const child = spawn(\"gemini\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n env: { ...process.env, GEMINI_CLI_TRUST_WORKSPACE: \"true\" },\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let stdout = \"\";\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n child.stdout!.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n\n const stderrChunks: string[] = [];\n child.stderr!.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrChunks.push(text);\n if (options.onActivity) {\n const line = text.trim();\n if (line) options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${text}`);\n }\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn gemini — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n const durationMs = Math.max(0, Date.now() - startTime);\n\n // Try to parse Gemini JSON output\n let resultText = stdout;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cachedTokens: number | undefined;\n let errorMessage: string | undefined;\n let apiErrorStatus: number | undefined;\n\n try {\n const parsed = JSON.parse(stdout) as {\n response?: string;\n text?: string;\n error?: { message?: string; code?: number; status?: number };\n usage_metadata?: {\n prompt_token_count?: number;\n candidates_token_count?: number;\n cached_content_token_count?: number;\n };\n input_tokens?: number;\n output_tokens?: number;\n };\n resultText = parsed.response ?? parsed.text ?? stdout;\n inputTokens = parsed.usage_metadata?.prompt_token_count ?? parsed.input_tokens;\n outputTokens = parsed.usage_metadata?.candidates_token_count ?? parsed.output_tokens;\n cachedTokens = parsed.usage_metadata?.cached_content_token_count;\n\n // Extract error details if present\n if (parsed.error) {\n errorMessage = parsed.error.message;\n // Gemini error codes can be numeric (HTTP status) or string codes\n // Map known codes to HTTP status for consistent handling\n let statusCode = parsed.error.status;\n if (parsed.error.code) {\n if (typeof parsed.error.code === \"number\") {\n // Gemini often returns HTTP status codes directly\n statusCode = parsed.error.code;\n } else if (typeof parsed.error.code === \"string\") {\n // String error codes - map to HTTP status\n const code = parsed.error.code.toLowerCase();\n if (code === \"not_found\" || code === \"model_not_found\") {\n statusCode = 404;\n } else if (code === \"permission_denied\" || code === \"unauthenticated\") {\n statusCode = 403;\n } else if (code === \"invalid_api_key\" || code === \"invalid_authentication\") {\n statusCode = 401;\n } else if (code === \"resource_exhausted\" || code === \"rate_limit_exceeded\") {\n statusCode = 429;\n } else if (code === \"internal\" || code === \"server_error\") {\n statusCode = 500;\n } else if (code === \"invalid_argument\") {\n statusCode = 400;\n }\n }\n }\n apiErrorStatus = statusCode;\n }\n } catch {\n // Raw text output — use as-is\n }\n\n // If exitCode non-zero and no structured error, try stderr\n if (code !== 0 && !errorMessage && stderrChunks.length > 0) {\n const stderr = stderrChunks.join(\"\").trim();\n if (stderr) {\n errorMessage = stderr;\n }\n }\n\n resolve({\n stdout: resultText,\n exitCode: code ?? 1,\n usage: {\n durationMs,\n inputTokens,\n outputTokens,\n cachedTokens,\n provider: \"gemini\",\n },\n errorMessage,\n apiErrorStatus,\n });\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n return new Promise((resolve, reject) => {\n // Gemini CLI has no --system-prompt flag; use -i to inject instructions\n // then continue interactively\n const child = spawn(\n \"gemini\",\n [\"--model\", model, \"-i\", `Follow these instructions for this session:\\n\\n${systemPrompt}`],\n { stdio: \"inherit\", env: { ...process.env, GEMINI_CLI_TRUST_WORKSPACE: \"true\" } },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start gemini CLI: ${err.message}. Is gemini installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code) => {\n resolve(code ?? 0);\n });\n });\n },\n};\n","import { spawn } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"gpt-5.4\", label: \"gpt-5.4\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"gpt-5.4\";\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const codexAdapter: ProviderAdapter = {\n name: \"codex\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"codex\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"codex CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"codex CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n const args = [\"exec\", options.prompt, \"--json\"];\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n if (options.autoApprove) {\n args.push(\"--full-auto\");\n }\n\n const name = options.agentName;\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n const child = spawn(\"codex\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let stdout = \"\";\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n child.stdout!.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n\n const stderrChunks: string[] = [];\n child.stderr!.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrChunks.push(text);\n if (options.onActivity) {\n const line = text.trim();\n if (line) options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${text}`);\n }\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn codex — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n const durationMs = Math.max(0, Date.now() - startTime);\n\n // Try to parse Codex JSON output\n let resultText = stdout;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cachedTokens: number | undefined;\n let errorMessage: string | undefined;\n let apiErrorStatus: number | undefined;\n\n try {\n const parsed = JSON.parse(stdout) as {\n response?: string;\n text?: string;\n error?: { message?: string; code?: string; status?: number };\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n prompt_tokens_details?: { cached_tokens?: number };\n };\n input_tokens?: number;\n output_tokens?: number;\n cached_tokens?: number;\n };\n resultText = parsed.response ?? parsed.text ?? stdout;\n inputTokens = parsed.usage?.prompt_tokens ?? parsed.input_tokens;\n outputTokens = parsed.usage?.completion_tokens ?? parsed.output_tokens;\n cachedTokens = parsed.usage?.prompt_tokens_details?.cached_tokens ?? parsed.cached_tokens;\n\n // Extract error details if present\n if (parsed.error) {\n errorMessage = parsed.error.message;\n // OpenAI error codes are strings like \"model_not_found\", map common ones to HTTP status\n // Try exact match first, then fallback to partial match\n if (typeof parsed.error.code === \"string\") {\n const code = parsed.error.code;\n // Exact matches for known codes\n if (code === \"model_not_found\" || code === \"invalid_model\") {\n apiErrorStatus = 404;\n } else if (code === \"invalid_api_key\" || code === \"invalid_request_error\") {\n apiErrorStatus = 401;\n } else if (code === \"rate_limit_exceeded\") {\n apiErrorStatus = 429;\n } else if (code === \"insufficient_quota\") {\n apiErrorStatus = 402;\n } else if (code === \"server_error\") {\n apiErrorStatus = 500;\n }\n // Fallback: partial match for unexpected variations\n else if (code.includes(\"not_found\")) {\n apiErrorStatus = 404;\n } else if (code.includes(\"auth\") || code.includes(\"unauthorized\")) {\n apiErrorStatus = 401;\n }\n }\n apiErrorStatus = apiErrorStatus ?? parsed.error.status;\n }\n } catch {\n // Raw text output — use as-is\n }\n\n // If exitCode non-zero and no structured error, try stderr\n if (code !== 0 && !errorMessage && stderrChunks.length > 0) {\n const stderr = stderrChunks.join(\"\").trim();\n if (stderr) {\n errorMessage = stderr;\n }\n }\n\n resolve({\n stdout: resultText,\n exitCode: code ?? 1,\n usage: {\n durationMs,\n inputTokens,\n outputTokens,\n cachedTokens,\n // Note: cacheWriteTokens not extracted — OpenAI doesn't currently expose this field\n provider: \"codex\",\n },\n errorMessage,\n apiErrorStatus,\n });\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n return new Promise((resolve, reject) => {\n // Codex CLI has no --system-prompt flag; pass instructions as initial prompt\n const child = spawn(\n \"codex\",\n [\"--model\", model, systemPrompt],\n { stdio: \"inherit\" },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start codex CLI: ${err.message}. Is codex installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code) => {\n resolve(code ?? 0);\n });\n });\n },\n};\n","import chalk from \"chalk\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\n// OpenRouter supports 200+ models — no whitelist needed.\n// model.ts already special-cases openrouter to skip validation.\nconst SUPPORTED_MODELS: ModelEntry[] = [];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"anthropic/claude-sonnet-4-5\";\n\nconst OPENROUTER_API_URL = \"https://openrouter.ai/api/v1/chat/completions\";\n\nexport const openrouterAdapter: ProviderAdapter = {\n name: \"openrouter\",\n type: \"api\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n const key = process.env.OPENROUTER_API_KEY;\n if (key && key.length > 0) {\n return { available: true };\n }\n return { available: false, reason: \"OPENROUTER_API_KEY environment variable not set\" };\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n const apiKey = process.env.OPENROUTER_API_KEY;\n if (!apiKey) {\n throw new TaskError(\n `${options.agentName}: OPENROUTER_API_KEY environment variable not set`,\n );\n }\n\n const name = options.agentName;\n\n // Warn about file system limitations for agents with write tools\n if (!options.quiet) {\n console.error(\n chalk.yellow(`[${name}] Warning: OpenRouter is an API provider — no file system access. `) +\n chalk.yellow(`Tool calls (Bash, Write, Edit) will not work.`),\n );\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n const startTime = Date.now();\n\n options.onActivity?.({ agent: name, detail: \"API request...\" });\n\n // Heartbeat every 5s during long waits to prevent stale elapsed time\n const heartbeat = setInterval(() => {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n options.onActivity?.({ agent: name, detail: `API request (${elapsed}s)...` });\n }, 5000);\n\n try {\n const response = await fetch(OPENROUTER_API_URL, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"HTTP-Referer\": \"https://github.com/andrewevans0102/reygent\",\n \"X-Title\": \"reygent\",\n },\n body: JSON.stringify({\n model: options.model,\n messages: [\n ...(options.systemPrompt\n ? [{ role: \"system\", content: options.systemPrompt }]\n : []),\n { role: \"user\", content: options.prompt },\n ],\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n clearInterval(heartbeat);\n\n if (!response.ok) {\n const body = await response.text();\n throw new TaskError(\n `${name}: OpenRouter API returned ${response.status} — ${body}`,\n );\n }\n\n const data = await response.json() as {\n choices?: Array<{ message?: { content?: string } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_cost?: number;\n cache_discount?: number;\n prompt_tokens_details?: { cached_tokens?: number };\n };\n total_cost?: number;\n };\n\n const content = data.choices?.[0]?.message?.content ?? \"\";\n const usage = data.usage;\n const durationMs = Date.now() - startTime;\n const costUsd = usage?.total_cost ?? data.total_cost;\n\n // OpenRouter reports cache activity via cache_discount or prompt_tokens_details\n const cachedTokens = usage?.prompt_tokens_details?.cached_tokens;\n const cacheDiscount = usage?.cache_discount;\n\n return {\n stdout: content,\n exitCode: 0,\n usage: {\n durationMs,\n inputTokens: usage?.prompt_tokens,\n outputTokens: usage?.completion_tokens,\n costUsd,\n cachedTokens,\n cacheDiscount: cacheDiscount && cacheDiscount > 0 ? cacheDiscount : undefined,\n provider: \"openrouter\",\n },\n };\n } catch (err) {\n clearTimeout(timeout);\n clearInterval(heartbeat);\n if (err instanceof TaskError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"aborted\")) {\n throw new TaskError(`${name}: timed out after ${options.timeoutMs}ms`);\n }\n throw new TaskError(`${name}: OpenRouter API request failed — ${message}`);\n }\n },\n\n async spawnInteractive(_systemPrompt: string, _model: string): Promise<number> {\n throw new TaskError(\n \"OpenRouter is an API provider and does not support interactive sessions. \" +\n \"Use a CLI provider (claude, gemini, codex) for interactive mode.\",\n );\n },\n};\n","import { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, ProviderName } from \"./types.js\";\nimport { claudeAdapter } from \"./claude.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { codexAdapter } from \"./codex.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\n\nexport type { ProviderAdapter, ProviderName, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst providers: Record<ProviderName, ProviderAdapter> = {\n claude: claudeAdapter,\n gemini: geminiAdapter,\n codex: codexAdapter,\n openrouter: openrouterAdapter,\n};\n\nexport const PROVIDER_NAMES = Object.keys(providers) as ProviderName[];\n\nexport function getProvider(name: string): ProviderAdapter {\n const adapter = providers[name as ProviderName];\n if (!adapter) {\n const valid = PROVIDER_NAMES.join(\", \");\n throw new TaskError(`Unknown provider: \"${name}\". Valid providers: ${valid}`);\n }\n return adapter;\n}\n","import { loadConfig } from \"./config.js\";\nimport { TaskError } from \"./task.js\";\nimport { getProvider } from \"./providers/index.js\";\nimport type { ModelEntry } from \"./providers/types.js\";\n\n// Re-export for backward compat\nexport type { ModelEntry };\n\n// Legacy exports — delegate to Claude adapter\nexport const SUPPORTED_MODELS: ModelEntry[] = getProvider(\"claude\").supportedModels;\nexport const DEFAULT_MODEL = getProvider(\"claude\").defaultModel;\n\nlet modelOverride: string | null = null;\nlet providerOverride: string | null = null;\n\nexport function setModelOverride(id: string): void {\n modelOverride = id;\n}\n\nexport function setProviderOverride(name: string): void {\n providerOverride = name;\n}\n\n/**\n * Resolve alias for a given provider. Falls back to identity if no alias found.\n */\nexport function resolveAlias(id: string, providerName?: string): string {\n const provider = getProvider(providerName ?? resolveProvider());\n return provider.shortAliases[id] ?? id;\n}\n\n/**\n * Validate model ID against a provider's supported models.\n * If provider not specified, uses resolved provider.\n * Pass-through providers (openrouter) accept any model.\n */\nexport function validateModel(id: string, providerName?: string): string {\n const name = providerName ?? resolveProvider();\n const provider = getProvider(name);\n const resolved = provider.shortAliases[id] ?? id;\n\n // OpenRouter accepts any model slug — pass-through\n if (name === \"openrouter\") return resolved;\n\n const valid = provider.supportedModels.some((m) => m.id === resolved);\n if (!valid) {\n const list = provider.supportedModels.map((m) => ` ${m.id} — ${m.label}`).join(\"\\n\");\n const aliases = Object.entries(provider.shortAliases)\n .map(([alias, full]) => ` ${alias} → ${full}`)\n .join(\"\\n\");\n let msg = `Unknown model: ${id}\\n\\nSupported models for ${name}:\\n${list}`;\n if (aliases) msg += `\\n\\nShort aliases:\\n${aliases}`;\n throw new TaskError(msg);\n }\n return resolved;\n}\n\nexport function getConfigModel(): string | null {\n const config = loadConfig();\n return config.model ?? null;\n}\n\n/**\n * Resolve provider: CLI flag → config → \"claude\"\n */\nexport function resolveProvider(agentProvider?: string): string {\n if (agentProvider) return agentProvider;\n if (providerOverride) return providerOverride;\n const config = loadConfig();\n return config.provider ?? \"claude\";\n}\n\n/**\n * Get model from override or config. Returns null if neither set.\n */\nexport function getModel(providerName?: string): string | null {\n if (modelOverride) return modelOverride;\n const configModel = getConfigModel();\n if (configModel) {\n return validateModel(configModel, providerName);\n }\n return null;\n}\n\n/**\n * Resolve model: override → config → provider default.\n */\nexport async function resolveModel(providerName?: string): Promise<string> {\n const name = providerName ?? resolveProvider();\n const model = getModel(name);\n if (model) return model;\n\n // Use provider default when no explicit model configured\n return getProvider(name).defaultModel;\n}\n","import type { TelemetryConfigLevel } from \"./chesstrace/config.js\";\nimport { DEFAULT_TELEMETRY_CONFIG } from \"./chesstrace/config.js\";\n\n/**\n * Runtime telemetry overrides from CLI flags\n */\nexport interface TelemetryOverride {\n /** --no-telemetry flag: completely disable telemetry */\n disabled?: boolean;\n /** --telemetry-level flag: override configured level */\n level?: TelemetryConfigLevel;\n}\n\n/**\n * Telemetry user configuration (subset)\n */\nexport interface TelemetryConfig {\n telemetry?: {\n enabled?: boolean;\n level?: TelemetryConfigLevel;\n };\n}\n\n/**\n * Resolved telemetry settings\n */\nexport interface ResolvedTelemetry {\n enabled: boolean;\n level: TelemetryConfigLevel;\n}\n\n/**\n * Module-level telemetry override state.\n *\n * **Design rationale:** CLI flags parsed in src/cli.ts must propagate to src/commands/run.ts.\n * Module-level state provides simplest mechanism without threading parameters through commander.js.\n *\n * **Thread safety:** Safe for CLI single-instance use. Tests must call resetTelemetryOverride()\n * between test cases to avoid state pollution.\n */\nlet telemetryOverride: TelemetryOverride = {};\n\n/**\n * Set telemetry runtime override (from CLI flags)\n */\nexport function setTelemetryOverride(override: TelemetryOverride): void {\n telemetryOverride = override;\n}\n\n/**\n * Get current telemetry runtime override\n */\nexport function getTelemetryOverride(): TelemetryOverride {\n return telemetryOverride;\n}\n\n/**\n * Reset telemetry override (for testing)\n *\n * **Important:** Call this in test teardown to prevent state leakage between tests.\n */\nexport function resetTelemetryOverride(): void {\n telemetryOverride = {};\n}\n\n/**\n * Validate telemetry level string\n */\nexport function isValidTelemetryLevel(level: string): level is TelemetryConfigLevel {\n return level === \"minimal\" || level === \"standard\" || level === \"verbose\";\n}\n\n/**\n * Resolve telemetry enabled status and level from config and overrides.\n * Applies CLI flag precedence: --no-telemetry disables, otherwise config enabled state used.\n * Level precedence: override.level > config.level > default.\n *\n * @param override - CLI flag overrides\n * @param config - User configuration\n * @returns Resolved telemetry settings\n */\nexport function resolveTelemetryEnabled(\n override: TelemetryOverride,\n config: TelemetryConfig\n): ResolvedTelemetry {\n const enabled = override.disabled === true ? false : config.telemetry?.enabled === true;\n const level = override.level ?? config.telemetry?.level ?? DEFAULT_TELEMETRY_CONFIG.level;\n\n return { enabled, level };\n}\n","import { select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { getAgents } from \"../config.js\";\nimport type { AgentConfig } from \"../agents.js\";\nimport { isDebug } from \"../debug.js\";\nimport { resolveModel, resolveProvider, validateModel } from \"../model.js\";\nimport { getProvider } from \"../providers/index.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\n\ninterface AgentOptions {\n spec?: string;\n}\n\nexport async function agentCommand(\n name: string | undefined,\n options: AgentOptions,\n): Promise<void> {\n return withTelemetry('agent', async () => {\n try {\n const agents = getAgents();\n let agent: AgentConfig;\n\n if (name) {\n const found = agents.find((a) => a.name === name);\n if (!found) {\n const validNames = agents.map((a) => a.name).join(\", \");\n console.log(chalk.red.bold(\"Error:\"), `Unknown agent \"${name}\". Valid agents: ${validNames}`);\n process.exit(1);\n }\n agent = found;\n } else {\n if (agents.length === 0) {\n throw new TaskError(\"No agents configured. Add agents to .reygent/config.json or check built-in agents.\");\n }\n if (!process.stdin.isTTY) {\n const validNames = agents.map((a) => a.name);\n // Truncate long agent lists for readability\n const displayNames = validNames.length > 5\n ? `${validNames.slice(0, 5).join(\", \")}, ... (${validNames.length - 5} more)`\n : validNames.join(\", \");\n console.log(chalk.red.bold(\"Error:\"), `Agent name required in non-interactive mode. Valid agents: ${displayNames}`);\n if (validNames.length > 5) {\n console.log(chalk.gray(\" Run 'reygent list' to see all agents.\"));\n }\n process.exit(1);\n }\n resetTerminalForInput();\n agent = await select({\n message: \"Select agent:\",\n choices: agents.map((a) => ({\n name: `${a.name} — ${a.description}`,\n value: a,\n })),\n });\n }\n\n let systemPrompt = agent.systemPrompt;\n\n if (options.spec) {\n const spec = await loadSpec(options.spec);\n systemPrompt += `\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}`;\n }\n\n const providerName = resolveProvider(agent.provider);\n const provider = getProvider(providerName);\n const modelId = agent.model\n ? validateModel(agent.model, providerName)\n : await resolveModel(providerName);\n\n console.log(\n chalk.bold.cyan(`\\nStarting session with ${agent.name} agent`) +\n chalk.gray(` (${providerName}/${modelId})`) +\n \"\\n\",\n );\n\n const exitCode = await provider.spawnInteractive(systemPrompt, modelId);\n process.exit(exitCode);\n } catch (err) {\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { basename, extname, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport { isLinearUrl, extractLinearId, readLinearSpec } from \"./linear.js\";\nimport { readJiraSpec } from \"./jira.js\";\nimport { loadEnvFile } from \"./env.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nexport interface MarkdownSpecPayload {\n source: \"markdown\";\n content: string;\n title: string;\n}\n\nexport interface JiraSpecPayload {\n source: \"jira\";\n issueKey: string;\n content: string;\n title: string;\n issueType?: string;\n}\n\nexport interface LinearSpecPayload {\n source: \"linear\";\n issueId: string;\n content: string;\n title: string;\n issueType?: string;\n labels?: string[];\n}\n\nexport type SpecPayload = MarkdownSpecPayload | JiraSpecPayload | LinearSpecPayload;\n\nexport type SpecProvider = \"jira\" | \"linear\" | \"local\";\n\nexport class SpecError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecError\";\n }\n}\n\nexport function readSpec(filePath: string): MarkdownSpecPayload {\n const resolved = resolve(process.cwd(), filePath);\n\n if (!existsSync(resolved)) {\n throw new SpecError(`File not found: ${resolved}`);\n }\n\n const ext = extname(resolved).toLowerCase();\n if (ext !== \".md\" && ext !== \".markdown\") {\n console.log(chalk.yellow(\"Warning:\"), `${basename(resolved)} is not a .md file`);\n }\n\n const content = readFileSync(resolved, \"utf-8\");\n\n if (!content.trim()) {\n throw new SpecError(`Spec file is empty: ${resolved}`);\n }\n\n const trimmed = content.trim();\n\n if (/^[A-Z]{2,}-\\d+$/.test(trimmed)) {\n throw new SpecError(\n `Spec file contains only a ticket reference (${trimmed}). Please provide the full spec content.`,\n );\n }\n\n if (/^https:\\/\\/linear\\.app\\/.+$/.test(trimmed)) {\n throw new SpecError(\n `Spec file contains only a Linear URL. Please provide the full spec content.`,\n );\n }\n\n const headingMatch = content.match(/^# (.+)$/m);\n const title = headingMatch\n ? headingMatch[1].trim()\n : basename(resolved, extname(resolved));\n\n return { source: \"markdown\", content, title };\n}\n\nexport const ISSUE_KEY_PATTERN = /^[A-Z]+-\\d+$/;\n\nexport async function loadSpec(source: string, provider?: SpecProvider): Promise<SpecPayload> {\n const trace = getChesstrace();\n try { trace.emit(Events.SPEC_FETCH, { source, provider: provider ?? 'auto' }); } catch { /* swallow */ }\n\n try {\n let result: SpecPayload;\n\n // When provider is explicitly set, route directly\n if (provider === \"local\") {\n result = readSpec(source);\n } else if (provider === \"linear\") {\n loadEnvFile();\n if (isLinearUrl(source)) {\n const issueId = extractLinearId(source);\n result = readLinearSpec(issueId);\n } else {\n result = await readLinearSpec(source);\n }\n } else if (provider === \"jira\") {\n loadEnvFile();\n result = await readJiraSpec(source);\n } else if (isLinearUrl(source)) {\n // Legacy auto-detection when no provider specified (used by other commands)\n loadEnvFile();\n const issueId = extractLinearId(source);\n result = await readLinearSpec(issueId);\n } else if (ISSUE_KEY_PATTERN.test(source)) {\n loadEnvFile();\n const hasLinear = !!process.env.LINEAR_API_KEY;\n const hasJira = !!(process.env.JIRA_URL && process.env.JIRA_EMAIL && process.env.JIRA_API_TOKEN);\n\n if (hasLinear && !hasJira) {\n result = await readLinearSpec(source);\n } else if (hasJira) {\n result = await readJiraSpec(source);\n } else {\n throw new SpecError(\n `No issue tracker configured for \"${source}\".\\n\\n` +\n `Add one of the following to your .env file:\\n\\n` +\n ` For Linear:\\n` +\n ` LINEAR_API_KEY=lin_api_...\\n\\n` +\n ` For Jira:\\n` +\n ` JIRA_URL=https://your-domain.atlassian.net\\n` +\n ` JIRA_EMAIL=your-email@example.com\\n` +\n ` JIRA_API_TOKEN=your-jira-token`,\n );\n }\n } else {\n result = readSpec(source);\n }\n\n try { trace.emit(Events.SPEC_PARSE, { source: result.source, title: result.title }); } catch { /* swallow */ }\n return result;\n } catch (err) {\n try { trace.emit(Events.SPEC_ERROR, { source, error: err instanceof Error ? err.message : String(err) }); } catch { /* swallow */ }\n throw err;\n }\n}\n","import { LinearSpecPayload, SpecError } from \"./spec.js\";\n\nconst LINEAR_URL_PATTERN =\n /^https:\\/\\/linear\\.app\\/[^/]+\\/issue\\/([A-Z]+-\\d+)/;\n\nexport function isLinearUrl(input: string): boolean {\n return LINEAR_URL_PATTERN.test(input);\n}\n\nexport function extractLinearId(url: string): string {\n const match = url.match(LINEAR_URL_PATTERN);\n if (!match) {\n throw new SpecError(`Could not extract issue ID from Linear URL: ${url}`);\n }\n return match[1];\n}\n\ninterface LinearIssue {\n id: string;\n identifier: string;\n title: string;\n description?: string;\n labels?: {\n nodes: Array<{\n name: string;\n }>;\n };\n children?: {\n nodes: Array<{\n id: string;\n identifier: string;\n title: string;\n description?: string;\n }>;\n };\n}\n\ninterface LinearResponse {\n data?: {\n issues?: {\n nodes: LinearIssue[];\n };\n };\n errors?: Array<{ message: string }>;\n}\n\nexport async function readLinearSpec(\n issueId: string,\n): Promise<LinearSpecPayload> {\n const apiKey = process.env.LINEAR_API_KEY;\n\n if (!apiKey) {\n throw new SpecError(\n `LINEAR_API_KEY is not configured.\\n\\n` +\n `Add the following to your .env file:\\n\\n` +\n ` LINEAR_API_KEY=lin_api_xxxxxxxx\\n\\n` +\n `Get an API key at: https://linear.app/settings/api`,\n );\n }\n\n const match = issueId.match(/^([A-Z]+)-(\\d+)$/);\n if (!match) {\n throw new SpecError(\n `Invalid issue identifier format: ${issueId}. Expected format: TEAM-123`,\n );\n }\n const teamKey = match[1];\n const issueNumber = parseInt(match[2], 10);\n\n const query = `\n query($teamKey: String!, $number: Float!) {\n issues(filter: { number: { eq: $number }, team: { key: { eq: $teamKey } } }, first: 1) {\n nodes {\n id\n identifier\n title\n description\n labels {\n nodes {\n name\n }\n }\n children {\n nodes {\n id\n identifier\n title\n description\n }\n }\n }\n }\n }\n `;\n\n try {\n const response = await fetch(\"https://api.linear.app/graphql\", {\n method: \"POST\",\n headers: {\n \"Authorization\": apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query,\n variables: { teamKey, number: issueNumber },\n }),\n });\n\n if (!response.ok) {\n throw new SpecError(\n `Linear API error (${response.status}): ${response.statusText}`,\n );\n }\n\n const data = await response.json() as LinearResponse;\n\n if (data.errors && data.errors.length > 0) {\n const errorMsg = data.errors.map(e => e.message).join(\", \");\n throw new SpecError(`Linear GraphQL error: ${errorMsg}`);\n }\n\n const nodes = data.data?.issues?.nodes;\n if (!nodes || nodes.length === 0) {\n throw new SpecError(`Issue not found: ${issueId}`);\n }\n\n const issue = nodes[0];\n const title = issue.title || issueId;\n const description = issue.description || \"\";\n\n const parts = [`# ${title}`, description];\n\n // Include sub-issues if present\n const children = issue.children?.nodes || [];\n if (children.length > 0) {\n const subSection = children\n .map((sub) => {\n const subTitle = sub.title || sub.identifier || \"Untitled\";\n const subDesc = sub.description ? `\\n${sub.description}` : \"\";\n return `- **${subTitle}**${subDesc}`;\n })\n .join(\"\\n\");\n parts.push(`## Sub-issues\\n\\n${subSection}`);\n }\n\n const content = parts.filter(p => p.trim()).join(\"\\n\\n\");\n\n // Extract issue type from labels (bug, feature, etc) using partial match\n const labels = issue.labels?.nodes || [];\n const labelNames = labels.map(l => l.name);\n const typeLabel = labels.find(l => {\n const lower = l.name.toLowerCase();\n return [\"bug\", \"feature\", \"enhancement\", \"fix\", \"chore\", \"refactor\", \"doc\", \"test\", \"style\", \"perf\"].some(\n keyword => lower.includes(keyword)\n );\n });\n const issueType = typeLabel?.name;\n\n return { source: \"linear\", issueId, title, content, issueType, labels: labelNames };\n } catch (err) {\n if (err instanceof SpecError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new SpecError(`Failed to fetch Linear issue: ${message}`);\n }\n}\n","import { JiraSpecPayload, SpecError } from \"./spec.js\";\n\nconst JIRA_KEY_PATTERN = /^[A-Z]+-\\d+$/;\n\nexport function isJiraKey(input: string): boolean {\n return JIRA_KEY_PATTERN.test(input);\n}\n\ninterface JiraIssueFields {\n summary: string;\n description?: string | { content: unknown[] };\n issuetype?: { name: string };\n [key: string]: unknown;\n}\n\ninterface JiraIssueResponse {\n key: string;\n fields: JiraIssueFields;\n}\n\nfunction parseADF(adf: { content: unknown[] }): string {\n // Convert Atlassian Document Format to plain text\n const lines: string[] = [];\n\n function walk(node: any): void {\n if (!node) return;\n\n if (node.type === \"text\") {\n lines.push(node.text || \"\");\n } else if (node.type === \"paragraph\") {\n const textContent = node.content\n ?.map((n: any) => n.text || \"\")\n .join(\"\") || \"\";\n if (textContent.trim()) lines.push(textContent);\n } else if (Array.isArray(node.content)) {\n node.content.forEach(walk);\n }\n }\n\n if (Array.isArray(adf.content)) {\n adf.content.forEach(walk);\n }\n\n return lines.join(\"\\n\\n\");\n}\n\nexport async function readJiraSpec(issueKey: string): Promise<JiraSpecPayload> {\n const jiraUrl = process.env.JIRA_URL;\n const jiraEmail = process.env.JIRA_EMAIL;\n const jiraToken = process.env.JIRA_API_TOKEN;\n\n if (!jiraUrl || !jiraEmail || !jiraToken) {\n throw new SpecError(\n `Jira API credentials not configured.\\n\\n` +\n `Add the following to your .env file:\\n\\n` +\n ` JIRA_URL=https://your-company.atlassian.net\\n` +\n ` JIRA_EMAIL=you@company.com\\n` +\n ` JIRA_API_TOKEN=your-api-token\\n\\n` +\n `Get an API token at: https://id.atlassian.com/manage-profile/security/api-tokens`,\n );\n }\n\n const auth = Buffer.from(`${jiraEmail}:${jiraToken}`).toString(\"base64\");\n const url = `${jiraUrl}/rest/api/3/issue/${issueKey}`;\n\n try {\n const response = await fetch(url, {\n headers: {\n \"Authorization\": `Basic ${auth}`,\n \"Accept\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new SpecError(\n `Jira API error (${response.status}): ${errorText}`,\n );\n }\n\n const data = await response.json() as JiraIssueResponse;\n const title = data.fields.summary || issueKey;\n\n let description = \"\";\n if (data.fields.description) {\n if (typeof data.fields.description === \"string\") {\n description = data.fields.description;\n } else if (typeof data.fields.description === \"object\" && \"content\" in data.fields.description) {\n description = parseADF(data.fields.description as { content: unknown[] });\n }\n }\n\n // Check common custom field names for acceptance criteria\n const acceptanceCriteria =\n (data.fields.acceptanceCriteria as string | undefined) ||\n (data.fields.acceptance_criteria as string | undefined) ||\n (data.fields.customfield_10001 as string | undefined) ||\n \"\";\n\n const parts = [`# ${title}`, description];\n if (acceptanceCriteria) {\n parts.push(`## Acceptance Criteria\\n\\n${acceptanceCriteria}`);\n }\n\n const content = parts.filter(p => p.trim()).join(\"\\n\\n\");\n const issueType = data.fields.issuetype?.name;\n\n return { source: \"jira\", issueKey, title, content, issueType };\n } catch (err) {\n if (err instanceof SpecError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new SpecError(`Failed to fetch Jira issue: ${message}`);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport function loadEnvFile(): void {\n const envPath = resolve(process.cwd(), \".env\");\n if (!existsSync(envPath)) return;\n\n const content = readFileSync(envPath, \"utf-8\");\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n const value = trimmed\n .slice(eqIndex + 1)\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\");\n if (!process.env[key]) process.env[key] = value;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport chalk from 'chalk';\nimport type { StorageBackend, EventFilter, RunSummary } from './backends/types.js';\nimport type { TelemetryEvent, TelemetryLevel } from './events.js';\nimport { EVENT_LEVELS, categoryFromEvent } from './events.js';\n\n/**\n * Configuration for Chesstrace telemetry\n */\nexport interface TelemetryConfig {\n /**\n * Telemetry level to capture (0=minimal, 1=standard, 2=verbose)\n */\n level: TelemetryLevel;\n\n /**\n * Retention period in days (default: 30)\n */\n retentionDays?: number;\n\n /**\n * Optional callback for swallowed errors (for debugging)\n */\n onError?: (err: unknown, operation: string) => void;\n}\n\n/**\n * Core Chesstrace class for telemetry event emission and lifecycle management\n */\nexport class Chesstrace {\n private config: TelemetryConfig;\n private backend: StorageBackend | null = null;\n private currentRunId: string | null = null;\n private initPromise: Promise<void> | null = null;\n private rawEventBuffer: Array<{ event: string; data: Record<string, unknown> }> = [];\n private eventBuffer: TelemetryEvent[] = [];\n private closed = false;\n private flushed = false;\n\n constructor(config: TelemetryConfig) {\n this.config = config;\n }\n\n /**\n * Initialize storage backend\n */\n async init(backend: StorageBackend): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n this.backend = backend;\n await backend.init();\n\n // Auto-prune old events based on retention config\n const retentionDays = this.config.retentionDays ?? 30;\n const olderThan = Date.now() - retentionDays * 24 * 60 * 60 * 1000;\n try {\n const deleted = await backend.prune(olderThan);\n if (deleted > 0) {\n console.log(chalk.gray(`Pruned ${deleted} event(s) older than ${retentionDays} days`));\n }\n } catch (err) {\n this.config.onError?.(err, 'auto-prune');\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Generate and store new run ID\n */\n async startRun(): Promise<string> {\n this.currentRunId = randomUUID();\n\n // Process buffered raw events (emitted before startRun)\n const rawBuffered = this.rawEventBuffer.splice(0);\n if (rawBuffered.length > 0 && this.backend) {\n const events: TelemetryEvent[] = [];\n for (const { event, data } of rawBuffered) {\n const minLevel = EVENT_LEVELS[event];\n if (minLevel !== undefined && minLevel <= this.config.level) {\n events.push({\n id: randomUUID(),\n runId: this.currentRunId,\n timestamp: Date.now(),\n category: categoryFromEvent(event),\n event,\n minLevel,\n data,\n });\n }\n }\n if (events.length > 0) {\n this.eventBuffer.push(...events);\n }\n }\n\n return this.currentRunId;\n }\n\n /**\n * Emit telemetry event with level filtering\n */\n emit(event: string, data: Record<string, unknown> = {}): void {\n // Reset flushed flag when new events arrive\n this.flushed = false;\n\n // Buffer raw events before init or before startRun\n if (!this.backend || !this.currentRunId) {\n this.rawEventBuffer.push({ event, data });\n return;\n }\n\n // Filter by level\n const minLevel = EVENT_LEVELS[event];\n if (minLevel === undefined || minLevel > this.config.level) {\n return;\n }\n\n const telemetryEvent: TelemetryEvent = {\n id: randomUUID(),\n runId: this.currentRunId,\n timestamp: Date.now(),\n category: categoryFromEvent(event),\n event,\n minLevel,\n data,\n };\n\n this.eventBuffer.push(telemetryEvent);\n }\n\n /**\n * Flush buffered events to backend\n */\n async flush(): Promise<void> {\n if (!this.backend) {\n return;\n }\n\n const buffered = this.eventBuffer.splice(0);\n if (buffered.length > 0) {\n try {\n await this.backend.writeBatch(buffered);\n } catch (err) {\n this.config.onError?.(err, 'writeBatch');\n }\n }\n\n try {\n await this.backend.flush();\n } catch (err) {\n this.config.onError?.(err, 'flush');\n }\n\n this.flushed = true;\n }\n\n /**\n * Query events from backend\n */\n async query(filter: EventFilter): Promise<TelemetryEvent[]> {\n if (!this.backend) {\n return [];\n }\n\n try {\n return await this.backend.query(filter);\n } catch (err) {\n return [];\n }\n }\n\n /**\n * List all runs with summary metadata\n */\n async listRuns(): Promise<RunSummary[]> {\n if (!this.backend) {\n return [];\n }\n\n try {\n return await this.backend.listRuns();\n } catch (err) {\n return [];\n }\n }\n\n /**\n * Prune events older than specified days\n * @param days - Number of days to retain\n * @returns Number of events deleted\n */\n async prune(days: number): Promise<number> {\n if (!this.backend) {\n return 0;\n }\n\n const olderThan = Date.now() - days * 24 * 60 * 60 * 1000;\n\n try {\n return await this.backend.prune(olderThan);\n } catch (err) {\n return 0;\n }\n }\n\n /**\n * Close backend and flush remaining events\n */\n async close(): Promise<void> {\n if (this.backend) {\n // Only flush if not already flushed or if buffer has new events\n if (!this.flushed || this.eventBuffer.length > 0) {\n await this.flush();\n }\n\n try {\n await this.backend.close();\n } catch (err) {\n this.config.onError?.(err, 'close');\n }\n }\n\n this.closed = true;\n }\n\n /**\n * Check if telemetry is enabled (backend initialized and not closed)\n */\n isEnabled(): boolean {\n return this.backend !== null && !this.closed;\n }\n}\n\n// Singleton instance and config tracking\nlet instance: Chesstrace | null = null;\nlet instanceConfig: TelemetryConfig | undefined = undefined;\n\n/**\n * Get global Chesstrace singleton.\n *\n * **Singleton behavior:** First call creates instance with provided config (or default `{ level: 0 }`).\n * Subsequent calls return same instance and ignore config parameter.\n *\n * **Config mismatch warning:** If called with different config after initialization, logs warning\n * to stderr. Caller must call `resetChesstrace()` first to reinitialize with new config.\n *\n * @param config - Config to use when creating new instance (only used on first call)\n * @returns Chesstrace singleton instance\n *\n * @example\n * ```ts\n * // First call creates instance\n * const trace1 = getChesstrace({ level: TelemetryLevel.standard });\n *\n * // Subsequent calls return same instance, config ignored\n * const trace2 = getChesstrace({ level: TelemetryLevel.verbose }); // Warns!\n *\n * // Reset to reinitialize with different config\n * resetChesstrace();\n * const trace3 = getChesstrace({ level: TelemetryLevel.verbose }); // OK\n * ```\n */\nexport function getChesstrace(config?: TelemetryConfig): Chesstrace {\n if (!instance) {\n const finalConfig = config ?? { level: 0 };\n instance = new Chesstrace(finalConfig);\n instanceConfig = finalConfig;\n } else if (config && JSON.stringify(config) !== JSON.stringify(instanceConfig)) {\n // Config mismatch detected\n console.warn(\n '[Chesstrace] Warning: getChesstrace() called with different config after initialization. ' +\n 'Existing instance returned; new config ignored. Call resetChesstrace() first to reinitialize.'\n );\n }\n return instance;\n}\n\n/**\n * Reset global Chesstrace singleton (for testing)\n */\nexport function resetChesstrace(): void {\n instance = null;\n instanceConfig = undefined;\n}\n","/**\n * Telemetry level enumeration\n */\nexport enum TelemetryLevel {\n minimal = 0,\n standard = 1,\n verbose = 2,\n}\n\n/**\n * Telemetry event categories\n */\nexport type TelemetryCategory =\n | 'command'\n | 'agent'\n | 'llm'\n | 'git'\n | 'spec'\n | 'error'\n | 'performance'\n | 'pipeline'\n | 'usage'\n | 'gate'\n | 'tool'\n | 'knowledge'\n | 'review';\n\n/**\n * Core telemetry event interface\n */\nexport interface TelemetryEvent {\n id: string;\n runId: string;\n timestamp: number;\n category: TelemetryCategory;\n event: string;\n minLevel: TelemetryLevel;\n data: Record<string, unknown>;\n}\n\n/**\n * Event name constants\n */\nexport const Events = {\n // Command events (minimal level)\n COMMAND_START: 'command.start',\n COMMAND_END: 'command.end',\n COMMAND_ERROR: 'command.error',\n\n // Agent events (standard level)\n AGENT_START: 'agent.start',\n AGENT_END: 'agent.end',\n AGENT_ERROR: 'agent.error',\n AGENT_TOOL_CALL: 'agent.tool_call',\n /** Emitted when agent spawn begins - { agent, provider, model, stage? } */\n AGENT_SPAWN: 'agent.spawn',\n /** Emitted when agent spawn completes or errors - { agent, stage?, exitCode, duration, success } */\n AGENT_COMPLETE: 'agent.complete',\n /** Emitted when agent spawn exceeds timeout - { agent, stage?, timeoutMs } */\n AGENT_TIMEOUT: 'agent.timeout',\n\n // LLM events (verbose level)\n LLM_REQUEST: 'llm.request',\n LLM_RESPONSE: 'llm.response',\n LLM_TOKEN_USAGE: 'llm.token_usage',\n LLM_ERROR: 'llm.error',\n\n // Git events (standard level)\n GIT_BRANCH_CREATE: 'git.branch_create',\n GIT_COMMIT: 'git.commit',\n GIT_PUSH: 'git.push',\n GIT_ERROR: 'git.error',\n\n // Spec events (standard level)\n SPEC_FETCH: 'spec.fetch',\n SPEC_PARSE: 'spec.parse',\n SPEC_ERROR: 'spec.error',\n\n // Error events (minimal level)\n ERROR_UNHANDLED: 'error.unhandled',\n ERROR_VALIDATION: 'error.validation',\n /** Emitted on TaskError catch - { type, message, stage, agent } */\n ERROR_TASK: 'error.task',\n /** Emitted on JSON parse failures - { agent, expectedFormat, received } */\n ERROR_PARSE: 'error.parse',\n /** Emitted when provider unavailable - { provider, reason } */\n ERROR_PROVIDER: 'error.provider',\n\n // Performance events (verbose level)\n PERF_METRIC: 'performance.metric',\n PERF_DURATION: 'performance.duration',\n\n // Pipeline events (standard level)\n PIPELINE_START: 'pipeline.start',\n PIPELINE_END: 'pipeline.end',\n PIPELINE_STAGE_START: 'pipeline.stage_start',\n PIPELINE_STAGE_END: 'pipeline.stage_end',\n\n // Usage events (verbose level)\n USAGE_TOKENS: 'usage.tokens',\n USAGE_COST: 'usage.cost',\n // Gate events (standard level)\n /** Emitted after each gate execution - { gateName, passed, attempt } */\n GATE_RESULT: 'gate.result',\n /** Emitted when gate retry triggered - { gateName, attempt, maxRetries, failureSnippet } */\n GATE_RETRY: 'gate.retry',\n\n // Tool events\n /** Emitted on each tool invocation - { agent, tool, detail? } (standard level) */\n TOOL_INVOKE: 'tool.invoke',\n /** Emitted on each tool invocation with full input/output - { agent, tool, input?, output? } (verbose level) */\n TOOL_INVOKE_FULL: 'tool.invoke.full',\n /** Emitted at stage end with aggregate tool counts - { stage, toolCounts } (minimal level) */\n TOOL_SUMMARY: 'tool.summary',\n\n // Knowledge events (standard level)\n /** Emitted when knowledge consulted before agent spawn - { agent, stage?, entries, entryCount } */\n KNOWLEDGE_CONSULTED: 'knowledge.consulted',\n /** Emitted when knowledge prevents failure - { entry, agent, evidence } (minimal level) */\n KNOWLEDGE_PREVENTED_FAILURE: 'knowledge.prevented_failure',\n /** Emitted when knowledge-based run succeeds - { entries_used, agent, stage } (standard level) */\n KNOWLEDGE_SUCCESS: 'knowledge.success',\n\n // Review events (standard level)\n /** Emitted when diff budget applied - { filesIncluded, filesExcluded, tokensUsed, tokensAvailable, excludedFilesList } */\n REVIEW_DIFF_BUDGET: 'review.diff_budget',\n} as const;\n\n/**\n * Mapping of event names to their minimum telemetry level\n */\nexport const EVENT_LEVELS: Record<string, TelemetryLevel> = {\n // Command events - minimal\n [Events.COMMAND_START]: TelemetryLevel.minimal,\n [Events.COMMAND_END]: TelemetryLevel.minimal,\n [Events.COMMAND_ERROR]: TelemetryLevel.minimal,\n\n // Agent events - standard\n [Events.AGENT_START]: TelemetryLevel.standard,\n [Events.AGENT_END]: TelemetryLevel.standard,\n [Events.AGENT_ERROR]: TelemetryLevel.standard,\n [Events.AGENT_TOOL_CALL]: TelemetryLevel.standard,\n [Events.AGENT_SPAWN]: TelemetryLevel.standard,\n [Events.AGENT_COMPLETE]: TelemetryLevel.standard,\n [Events.AGENT_TIMEOUT]: TelemetryLevel.standard,\n\n // LLM events - verbose\n [Events.LLM_REQUEST]: TelemetryLevel.verbose,\n [Events.LLM_RESPONSE]: TelemetryLevel.verbose,\n [Events.LLM_TOKEN_USAGE]: TelemetryLevel.verbose,\n [Events.LLM_ERROR]: TelemetryLevel.verbose,\n\n // Git events - standard\n [Events.GIT_BRANCH_CREATE]: TelemetryLevel.standard,\n [Events.GIT_COMMIT]: TelemetryLevel.standard,\n [Events.GIT_PUSH]: TelemetryLevel.standard,\n [Events.GIT_ERROR]: TelemetryLevel.standard,\n\n // Spec events - standard\n [Events.SPEC_FETCH]: TelemetryLevel.standard,\n [Events.SPEC_PARSE]: TelemetryLevel.standard,\n [Events.SPEC_ERROR]: TelemetryLevel.standard,\n\n // Error events - minimal\n [Events.ERROR_UNHANDLED]: TelemetryLevel.minimal,\n [Events.ERROR_VALIDATION]: TelemetryLevel.minimal,\n [Events.ERROR_TASK]: TelemetryLevel.minimal,\n [Events.ERROR_PARSE]: TelemetryLevel.minimal,\n [Events.ERROR_PROVIDER]: TelemetryLevel.minimal,\n\n // Performance events - verbose\n [Events.PERF_METRIC]: TelemetryLevel.verbose,\n [Events.PERF_DURATION]: TelemetryLevel.verbose,\n\n // Pipeline events - standard\n [Events.PIPELINE_START]: TelemetryLevel.standard,\n [Events.PIPELINE_END]: TelemetryLevel.standard,\n [Events.PIPELINE_STAGE_START]: TelemetryLevel.standard,\n [Events.PIPELINE_STAGE_END]: TelemetryLevel.standard,\n\n // Usage events - verbose\n [Events.USAGE_TOKENS]: TelemetryLevel.verbose,\n [Events.USAGE_COST]: TelemetryLevel.verbose,\n // Gate events - standard\n [Events.GATE_RESULT]: TelemetryLevel.standard,\n [Events.GATE_RETRY]: TelemetryLevel.standard,\n\n // Tool events\n [Events.TOOL_INVOKE]: TelemetryLevel.standard,\n [Events.TOOL_INVOKE_FULL]: TelemetryLevel.verbose,\n [Events.TOOL_SUMMARY]: TelemetryLevel.minimal,\n\n // Knowledge events\n [Events.KNOWLEDGE_CONSULTED]: TelemetryLevel.standard,\n [Events.KNOWLEDGE_PREVENTED_FAILURE]: TelemetryLevel.minimal,\n [Events.KNOWLEDGE_SUCCESS]: TelemetryLevel.standard,\n\n // Review events\n [Events.REVIEW_DIFF_BUDGET]: TelemetryLevel.standard,\n};\n\n/**\n * Extract category from event name\n * @param event - Event name (e.g., \"command.start\")\n * @returns Category portion before the dot\n */\nexport function categoryFromEvent(event: string): TelemetryCategory {\n const category = event.split('.')[0];\n\n // Validate category is valid TelemetryCategory\n const validCategories: TelemetryCategory[] = [\n 'command',\n 'agent',\n 'llm',\n 'git',\n 'spec',\n 'error',\n 'performance',\n 'pipeline',\n 'usage',\n 'gate',\n 'tool',\n 'knowledge',\n 'review',\n ];\n\n if (validCategories.includes(category as TelemetryCategory)) {\n return category as TelemetryCategory;\n }\n\n throw new Error(`Invalid event category: ${category}`);\n}\n","/**\n * Reset terminal state before user input prompts.\n *\n * After ora spinners finish, terminal cursor/stdin state can be inconsistent.\n * This causes two classes of bugs:\n * 1. Pasted text corrupts the prompt (buffered input from during spinner)\n * 2. Cursor gets \"stuck\" — typing only moves back and forth on one line\n * (readline's cursor tracker is desynced from actual terminal state)\n *\n * This function ensures a clean slate for the next readline/inquirer prompt:\n * - SGR text attributes are reset (no color/bold leaking from spinner)\n * - Cursor is visible\n * - stdin is not in raw mode (ora/stdin-discarder may leave it set)\n * - Current line is fully cleared and cursor is at column 0\n */\nexport function resetTerminalForInput(): void {\n // Reset all SGR text attributes (bold, color, underline, etc.)\n process.stdout.write('\\x1b[0m');\n\n // Show cursor (ora hides it while spinning)\n process.stdout.write('\\x1b[?25h');\n\n // Ensure stdin is not stuck in raw mode — readline/inquirer manage their own\n // raw mode and will break if stdin is already raw when they start.\n // Only disable raw mode if stdin is paused (not actively managed by readline).\n if (process.stdin.isTTY && process.stdin.isRaw && process.stdin.isPaused()) {\n process.stdin.setRawMode(false);\n }\n\n // Move to column 0 and clear the entire line (not just cursor-to-end)\n process.stdout.write('\\r\\x1b[2K');\n}\n","import Database from 'better-sqlite3';\nimport { join, dirname } from 'node:path';\nimport { existsSync, mkdirSync, statSync } from 'node:fs';\nimport type { StorageBackend, EventFilter, RunSummary } from './types.js';\nimport type { TelemetryEvent, TelemetryCategory } from '../events.js';\nimport { findLocalConfigDir, resolveGlobalConfigDir } from '../../config.js';\n\n/**\n * Max DB size in bytes (50MB default, prevents disk exhaustion)\n */\nconst MAX_DB_SIZE_BYTES = 50 * 1024 * 1024;\n\n/**\n * Max events per run (prevents event spam attacks)\n */\nconst MAX_EVENTS_PER_RUN = 10000;\n\n/**\n * SQLite storage backend for telemetry events\n */\nexport class SqliteBackend implements StorageBackend {\n private db: Database.Database | null = null;\n private dbPath: string;\n\n constructor(scope: 'local' | 'global' = 'local', explicitPath?: string) {\n this.dbPath = explicitPath ?? this.resolveDbPath(scope);\n }\n\n /**\n * Resolve database file path based on scope\n * Local: .reygent/chesstrace.db (search upward from cwd)\n * Global: ~/.reygent/chesstrace.db\n */\n private resolveDbPath(scope: 'local' | 'global'): string {\n if (scope === 'local') {\n const configDir = findLocalConfigDir(process.cwd());\n if (configDir) {\n return join(configDir, 'chesstrace.db');\n }\n // Fallback to global if no local .reygent found\n scope = 'global';\n }\n\n const globalDir = resolveGlobalConfigDir();\n // Ensure global .reygent directory exists\n if (!existsSync(globalDir)) {\n mkdirSync(globalDir, { recursive: true });\n }\n return join(globalDir, 'chesstrace.db');\n }\n\n /**\n * Initialize database schema and indexes\n */\n async init(): Promise<void> {\n // Ensure parent directory exists\n const dbDir = dirname(this.dbPath);\n if (!existsSync(dbDir)) {\n mkdirSync(dbDir, { recursive: true });\n }\n\n this.db = new Database(this.dbPath);\n\n // Enable WAL mode for better concurrency\n this.db.pragma('journal_mode = WAL');\n\n // Create events table\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n category TEXT NOT NULL,\n event TEXT NOT NULL,\n min_level INTEGER NOT NULL,\n data TEXT NOT NULL\n )\n `);\n\n // Create indexes for efficient querying\n this.db.exec(`\n CREATE INDEX IF NOT EXISTS idx_events_run_id ON events(run_id);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_events_category ON events(category);\n CREATE INDEX IF NOT EXISTS idx_events_event ON events(event);\n `);\n }\n\n /**\n * Check if database size exceeds limit\n */\n private checkDbSize(): boolean {\n if (!existsSync(this.dbPath)) return true;\n try {\n const stats = statSync(this.dbPath);\n return stats.size < MAX_DB_SIZE_BYTES;\n } catch (err) {\n // File deleted between existsSync and statSync (race condition)\n // Treat as valid (file doesn't exist = no size limit hit)\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] checkDbSize stat failed (file deleted?):', err instanceof Error ? err.message : String(err));\n }\n return true;\n }\n }\n\n /**\n * Check if run has exceeded event limit (prevents spam)\n */\n private checkRunEventLimit(runId: string): boolean {\n if (!this.db) return false;\n const result = this.db.prepare('SELECT COUNT(*) as count FROM events WHERE run_id = ?').get(runId) as { count: number };\n return result.count < MAX_EVENTS_PER_RUN;\n }\n\n /**\n * Prune old events to free space (keeps last 180 days)\n */\n private pruneOldEvents(): void {\n if (!this.db) return;\n const cutoffMs = Date.now() - (180 * 24 * 60 * 60 * 1000);\n this.db.prepare('DELETE FROM events WHERE timestamp < ?').run(cutoffMs);\n this.db.pragma('vacuum');\n }\n\n /**\n * Write single event to database\n */\n async write(event: TelemetryEvent): Promise<void> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n // Security: Check DB size limit\n if (!this.checkDbSize()) {\n // Attempt to prune old events\n this.pruneOldEvents();\n // If still too large after pruning, skip write silently\n if (!this.checkDbSize()) {\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] DB size limit hit, skipping write (event:', event.event, ')');\n }\n return;\n }\n }\n\n // Security: Check per-run event limit (prevent spam)\n if (!this.checkRunEventLimit(event.runId)) {\n return;\n }\n\n const stmt = this.db.prepare(`\n INSERT INTO events (id, run_id, timestamp, category, event, min_level, data)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n event.id,\n event.runId,\n event.timestamp,\n event.category,\n event.event,\n event.minLevel,\n JSON.stringify(event.data),\n );\n }\n\n /**\n * Write multiple events in a transaction\n */\n async writeBatch(events: TelemetryEvent[]): Promise<void> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n // Security: Check DB size limit\n if (!this.checkDbSize()) {\n this.pruneOldEvents();\n if (!this.checkDbSize()) {\n return;\n }\n }\n\n const stmt = this.db.prepare(`\n INSERT INTO events (id, run_id, timestamp, category, event, min_level, data)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const transaction = this.db.transaction((events: TelemetryEvent[]) => {\n for (const event of events) {\n // Security: Check per-run limit for each event\n if (!this.checkRunEventLimit(event.runId)) {\n continue;\n }\n\n stmt.run(\n event.id,\n event.runId,\n event.timestamp,\n event.category,\n event.event,\n event.minLevel,\n JSON.stringify(event.data),\n );\n }\n });\n\n transaction(events);\n }\n\n /**\n * Query events matching filter criteria\n */\n async query(filter: EventFilter): Promise<TelemetryEvent[]> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter.runId !== undefined) {\n conditions.push('run_id = ?');\n params.push(filter.runId);\n }\n\n if (filter.category !== undefined) {\n conditions.push('category = ?');\n params.push(filter.category);\n }\n\n if (filter.event !== undefined) {\n conditions.push('event = ?');\n params.push(filter.event);\n }\n\n if (filter.minLevel !== undefined) {\n conditions.push('min_level >= ?');\n params.push(filter.minLevel);\n }\n\n if (filter.startTime !== undefined) {\n conditions.push('timestamp >= ?');\n params.push(filter.startTime);\n }\n\n if (filter.endTime !== undefined) {\n conditions.push('timestamp <= ?');\n params.push(filter.endTime);\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const sql = `SELECT * FROM events ${whereClause} ORDER BY timestamp ASC`;\n\n const rows = this.db.prepare(sql).all(...params) as Array<{\n id: string;\n run_id: string;\n timestamp: number;\n category: TelemetryCategory;\n event: string;\n min_level: number;\n data: string;\n }>;\n\n return rows.map((row) => ({\n id: row.id,\n runId: row.run_id,\n timestamp: row.timestamp,\n category: row.category,\n event: row.event,\n minLevel: row.min_level,\n data: JSON.parse(row.data) as Record<string, unknown>,\n }));\n }\n\n /**\n * List all runs with summary metadata\n */\n async listRuns(): Promise<RunSummary[]> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const sql = `\n SELECT\n run_id,\n MIN(timestamp) as start_time,\n MAX(timestamp) as end_time,\n COUNT(*) as event_count,\n GROUP_CONCAT(DISTINCT category) as categories\n FROM events\n GROUP BY run_id\n ORDER BY start_time DESC\n `;\n\n const rows = this.db.prepare(sql).all() as Array<{\n run_id: string;\n start_time: number;\n end_time: number;\n event_count: number;\n categories: string;\n }>;\n\n return rows.map((row) => ({\n runId: row.run_id,\n startTime: row.start_time,\n endTime: row.end_time,\n eventCount: row.event_count,\n categories: row.categories.split(',') as TelemetryCategory[],\n }));\n }\n\n /**\n * Flush pending writes (SQLite auto-commits, so this is a no-op)\n */\n async flush(): Promise<void> {\n // SQLite auto-commits after each transaction, so nothing to flush\n }\n\n /**\n * Prune events older than timestamp\n * @param olderThan - Unix timestamp in milliseconds\n * @returns Number of events deleted\n */\n async prune(olderThan: number): Promise<number> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const stmt = this.db.prepare('DELETE FROM events WHERE timestamp < ?');\n const result = stmt.run(olderThan);\n return result.changes;\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Get database file path (useful for debugging/testing)\n */\n getDbPath(): string {\n return this.dbPath;\n }\n}\n","import type { StorageBackend, EventFilter, RunSummary } from './types.js';\nimport type { TelemetryEvent } from '../events.js';\nimport { SqliteBackend } from './sqlite.js';\n\n/**\n * Dual backend that writes to both local and global storage.\n * Used when running in a project - writes telemetry to both\n * project-specific db and global aggregate db.\n *\n * Set REYGENT_GLOBAL_TELEMETRY=false to disable global writes (security).\n */\nexport class DualBackend implements StorageBackend {\n private localBackend: SqliteBackend;\n private globalBackend: SqliteBackend | null;\n private globalEnabled: boolean;\n\n constructor(projectRoot: string) {\n // Local backend stores project-specific telemetry in chesstrace.db\n this.localBackend = new SqliteBackend('local', `${projectRoot}/.reygent/chesstrace.db`);\n\n // Global backend opt-out for security (prevent cross-project data leakage)\n this.globalEnabled = process.env.REYGENT_GLOBAL_TELEMETRY !== 'false';\n this.globalBackend = this.globalEnabled ? new SqliteBackend('global') : null;\n }\n\n async init(): Promise<void> {\n const tasks = [this.localBackend.init()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.init());\n }\n await Promise.all(tasks);\n }\n\n async write(event: TelemetryEvent): Promise<void> {\n // Write to both, but don't fail if one fails\n const tasks = [this.localBackend.write(event)];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.write(event));\n }\n const results = await Promise.allSettled(tasks);\n\n // Log failures in debug mode\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n results.forEach((result, idx) => {\n if (result.status === 'rejected') {\n const backend = idx === 0 ? 'local' : 'global';\n console.error(`[debug:telemetry] Dual backend ${backend} write failed:`, result.reason instanceof Error ? result.reason.message : String(result.reason));\n }\n });\n }\n }\n\n async writeBatch(events: TelemetryEvent[]): Promise<void> {\n const tasks = [this.localBackend.writeBatch(events)];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.writeBatch(events));\n }\n const results = await Promise.allSettled(tasks);\n\n // Log failures in debug mode\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n results.forEach((result, idx) => {\n if (result.status === 'rejected') {\n const backend = idx === 0 ? 'local' : 'global';\n console.error(`[debug:telemetry] Dual backend ${backend} writeBatch failed:`, result.reason instanceof Error ? result.reason.message : String(result.reason));\n }\n });\n }\n }\n\n async query(filter?: EventFilter): Promise<TelemetryEvent[]> {\n // Query from local only (project-specific data)\n return this.localBackend.query(filter);\n }\n\n async getRunSummaries(limit?: number): Promise<RunSummary[]> {\n // Get summaries from local only\n return this.localBackend.getRunSummaries(limit);\n }\n\n getEvents(): TelemetryEvent[] {\n // Get events from local only\n return this.localBackend.getEvents();\n }\n\n async flush(): Promise<void> {\n const tasks = [this.localBackend.flush()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.flush());\n }\n await Promise.all(tasks);\n }\n\n async close(): Promise<void> {\n const tasks = [this.localBackend.close()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.close());\n }\n await Promise.all(tasks);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, dirname, parse } from 'node:path';\n\n/**\n * Project markers that indicate a project root directory.\n * Checked in order of specificity.\n */\nconst PROJECT_MARKERS = [\n '.reygent', // Reygent already initialized\n '.git', // Git repository\n 'package.json', // Node.js project\n 'pyproject.toml', // Python project\n 'Cargo.toml', // Rust project\n 'go.mod', // Go project\n 'Gemfile', // Ruby project\n 'composer.json', // PHP project\n 'pom.xml', // Java/Maven project\n 'build.gradle', // Java/Gradle project\n];\n\n/**\n * Max number of directories to traverse upward (security limit)\n */\nconst MAX_TRAVERSAL_DEPTH = 10;\n\n/**\n * Search upward from startDir to find project root.\n * Returns project root directory if found, null otherwise.\n *\n * Searches for common project markers (.git, package.json, etc.)\n * starting from startDir and walking up the directory tree.\n * Limited to MAX_TRAVERSAL_DEPTH levels to prevent excessive filesystem traversal.\n */\nexport function findProjectRoot(startDir: string): string | null {\n let currentDir = startDir;\n const root = parse(currentDir).root;\n let depth = 0;\n\n while (currentDir !== root && depth < MAX_TRAVERSAL_DEPTH) {\n // Check if any project marker exists in current directory\n for (const marker of PROJECT_MARKERS) {\n if (existsSync(join(currentDir, marker))) {\n return currentDir;\n }\n }\n\n // Move up one directory\n currentDir = dirname(currentDir);\n depth++;\n }\n\n // Hit traversal limit - log for debugging\n if (depth >= MAX_TRAVERSAL_DEPTH && (process.env.REYGENT_DEBUG === '1')) {\n console.error(`[debug] findProjectRoot: MAX_TRAVERSAL_DEPTH (${MAX_TRAVERSAL_DEPTH}) reached from ${startDir}`);\n }\n\n return null;\n}\n\n/**\n * Check if currently in a project (has project root).\n */\nexport function isInProject(startDir: string = process.cwd()): boolean {\n return findProjectRoot(startDir) !== null;\n}\n","import { getChesstrace, resetChesstrace } from './chesstrace/index.js';\nimport type { Chesstrace } from './chesstrace/index.js';\nimport { Events, TelemetryLevel } from './chesstrace/events.js';\nimport { DualBackend } from './chesstrace/backends/dual.js';\nimport { SqliteBackend } from './chesstrace/backends/sqlite.js';\nimport { loadConfig } from './config.js';\nimport { getTelemetryOverride, resolveTelemetryEnabled } from './telemetry-override.js';\nimport { findProjectRoot } from './project-detection.js';\nimport { isDebug } from './debug.js';\n\n/**\n * Context passed to command body within withTelemetry wrapper.\n */\nexport interface TelemetryContext {\n chesstrace: Chesstrace | null;\n}\n\n/**\n * Wrap a command body with telemetry lifecycle management.\n *\n * - Resolves config + overrides, creates backend, calls init() + startRun()\n * - Emits COMMAND_START before body, COMMAND_END on success, COMMAND_ERROR on throw\n * - Guarantees flush() + close() in finally\n * - If telemetry disabled or init fails, runs body with chesstrace: null\n *\n * Note: run.ts keeps its own inline init (has .reygent/ auto-creation + knowledge update logic).\n */\nexport async function withTelemetry<T>(\n commandName: string,\n body: (ctx: TelemetryContext) => Promise<T>,\n): Promise<T> {\n let chesstrace: Chesstrace | null = null;\n const startTime = Date.now();\n\n try {\n const config = loadConfig();\n const telemetryOverride = getTelemetryOverride();\n const { enabled, level: levelStr } = resolveTelemetryEnabled(telemetryOverride, config);\n const telemetryLevel = TelemetryLevel[levelStr];\n\n if (enabled) {\n // Reset singleton to avoid config mismatch warnings from prior commands\n resetChesstrace();\n chesstrace = getChesstrace({ level: telemetryLevel, retentionDays: config.telemetry?.retention ?? 30 });\n\n const projectRoot = findProjectRoot(process.cwd());\n const backend = projectRoot\n ? new DualBackend(projectRoot)\n : new SqliteBackend('global');\n\n await chesstrace.init(backend);\n await chesstrace.startRun();\n }\n } catch (err) {\n if (isDebug()) {\n console.error('[telemetry] init failed:', err);\n }\n chesstrace = null;\n }\n\n // Emit COMMAND_START\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_START, { command: commandName });\n } catch {\n // Swallow emit errors\n }\n }\n\n try {\n const result = await body({ chesstrace });\n\n // Emit COMMAND_END on success\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_END, {\n command: commandName,\n success: true,\n durationMs: Date.now() - startTime,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n return result;\n } catch (err) {\n // Emit COMMAND_ERROR on throw\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_ERROR, {\n command: commandName,\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - startTime,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n throw err;\n } finally {\n if (chesstrace) {\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n }\n}\n","import { createInterface } from \"node:readline\";\nimport { writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport { isDebug } from \"../debug.js\";\nimport { generateSpec, runClarification } from \"../generate-spec.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\n\nasync function prompt(question: string, fallback?: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(question, resolve);\n });\n rl.close();\n return answer.trim() || fallback || \"\";\n}\n\nexport async function generateSpecCommand(\n description: string | undefined,\n options: { output?: string; skipClarification: boolean },\n): Promise<void> {\n return withTelemetry('generate-spec', async () => {\n try {\n if (!description) {\n description = await prompt(\"Feature description: \");\n if (!description) {\n console.log(chalk.red.bold(\"Error:\"), \"Description is required.\");\n process.exit(1);\n }\n }\n\n let output = options.output;\n if (!output) {\n output = await prompt(\"Output file path (spec.md): \", \"spec.md\");\n }\n\n let clarificationAnswers: string | undefined;\n\n if (!options.skipClarification) {\n // Clarification loop\n let attempts = 0;\n const maxAttempts = 3;\n let ready = false;\n\n while (!ready && attempts < maxAttempts) {\n attempts++;\n const clarifyStatus = createLiveStatus(\"Checking if clarification needed...\");\n\n let result: Awaited<ReturnType<typeof runClarification>>;\n try {\n result = await runClarification(description!, clarificationAnswers, clarifyStatus.onActivity);\n } catch (err) {\n clarifyStatus.fail(chalk.red(\"Failed to check clarification needs\"));\n if (err instanceof TaskError) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new TaskError(`Clarification check failed: ${message}`);\n }\n\n if (\"ready\" in result && result.ready) {\n clarifyStatus.succeed(chalk.green(\"No clarification needed\"));\n ready = true;\n break;\n }\n\n if (\"needsClarification\" in result && result.needsClarification) {\n clarifyStatus.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\nClarifying questions:\\n\"));\n\n const answers: string[] = [];\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n try {\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n const answer = await new Promise<string>((resolve) => {\n rl.question(` [${i + 1}/${result.questions.length}] ${question}\\n > `, resolve);\n });\n\n if (answer.trim().toLowerCase() === \"abort\" || answer.trim().toLowerCase() === \"cancel\") {\n console.log(chalk.red(\"Aborted.\"));\n process.exit(0);\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n }\n } finally {\n rl.close();\n }\n\n clarificationAnswers = answers.join(\"\\n\\n\");\n\n if (attempts < maxAttempts) {\n console.log(chalk.blue(\"\\nRe-checking with your answers...\\n\"));\n }\n }\n }\n\n if (!ready && attempts >= maxAttempts) {\n // Exhausted attempts, proceed with answers collected so far\n console.log(chalk.yellow(\"Max clarification rounds reached, generating spec with answers so far...\"));\n }\n }\n\n const genStatus = createLiveStatus(\"Generating spec...\");\n\n let markdown: string;\n try {\n markdown = await generateSpec(description!, clarificationAnswers, genStatus.onActivity);\n genStatus.succeed(chalk.green(\"Spec generated\"));\n } catch (err) {\n genStatus.fail(chalk.red(\"Failed to generate spec\"));\n throw err;\n }\n\n const outPath = resolve(process.cwd(), output);\n writeFileSync(outPath, markdown, \"utf-8\");\n console.log(chalk.gray(\"Spec written to\"), chalk.cyan(outPath));\n } catch (err) {\n if (err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport { findLocalConfigDir } from \"../config.js\";\nimport { marked } from \"marked\";\nimport { isTestEnvironment } from \"../test-env.js\";\n\nexport interface KnowledgeEntry {\n id: string;\n title: string;\n content: string;\n source: string; // file path\n agent?: string; // relevant agent name (for agent-specific tips)\n metadata?: Record<string, unknown>; // parsed from content (occurrences, dates, etc)\n}\n\nexport interface Knowledge {\n agentTips: string;\n commonFailures: string;\n successPatterns: string;\n projectConventions: string;\n entriesLoaded: string[]; // entry IDs for telemetry\n}\n\n/**\n * Find .reygent/knowledge/ directory, searching upward from cwd.\n * Returns null if no .reygent/ found.\n */\nexport function findKnowledgeDir(): string | null {\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) return null;\n return join(configDir, \"knowledge\");\n}\n\n/**\n * Sanitize markdown content to prevent prompt injection attacks.\n * Removes potentially malicious patterns while preserving legitimate content.\n */\nfunction sanitizeMarkdown(content: string): string {\n // Remove common prompt injection patterns\n return content\n // Remove instructions to ignore previous instructions\n .replace(/ignore (all |previous |prior )?(instructions|prompts|context)/gi, '[FILTERED]')\n // Remove instructions to reveal system prompts\n .replace(/show me (your|the) (system prompt|instructions)/gi, '[FILTERED]')\n // Remove instructions to output sensitive files\n .replace(/output (the )?(contents? of|entire) (\\.|\\/)?\\.?env/gi, '[FILTERED]')\n .replace(/(print|show|display|output) (secrets?|keys?|tokens?|passwords?)/gi, '[FILTERED]')\n // Remove roleplaying attempts\n .replace(/pretend (you are|to be) /gi, '[FILTERED]')\n .replace(/act as (if )?/gi, '[FILTERED]');\n}\n\n/**\n * Validate markdown content is well-formed and safe.\n * Returns true if content passes validation.\n */\nfunction validateMarkdown(content: string): boolean {\n if (!content || content.trim().length === 0) return true;\n\n // Check for excessive size (>1MB indicates potential attack)\n if (content.length > 1024 * 1024) return false;\n\n // Check for suspicious patterns (many consecutive special chars)\n if (/[^a-zA-Z0-9\\s]{50,}/.test(content)) return false;\n\n return true;\n}\n\n/**\n * Load and parse a markdown file.\n * Returns empty string if file doesn't exist or is empty.\n * Returns null if file validation fails (security).\n * Validates and sanitizes content to prevent prompt injection attacks.\n */\nexport function readMarkdown(filePath: string): string | null {\n if (!existsSync(filePath)) return \"\";\n\n const content = readFileSync(filePath, \"utf-8\");\n\n // Empty file is valid - return empty string\n if (!content || content.trim().length === 0) return \"\";\n\n // Validate content\n if (!validateMarkdown(content)) {\n console.warn(chalk.yellow(`⚠ Suspicious content detected in ${filePath}, skipping`));\n return null;\n }\n\n // Sanitize content\n return sanitizeMarkdown(content);\n}\n\n/**\n * Parse markdown content into structured entries.\n * Each top-level ## heading becomes an entry.\n * Returns array of entries with id, title, content.\n */\nexport function parseMarkdownEntries(markdown: string, source: string): KnowledgeEntry[] {\n if (!markdown.trim()) return [];\n\n let tokens;\n try {\n tokens = marked.lexer(markdown);\n } catch (err) {\n // Malformed markdown - return empty array instead of crashing\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'knowledge') {\n console.warn(`[debug:knowledge] Failed to parse markdown from ${source}:`, err instanceof Error ? err.message : String(err));\n }\n return [];\n }\n\n const entries: KnowledgeEntry[] = [];\n let currentEntry: Partial<KnowledgeEntry> | null = null;\n let currentContent: string[] = [];\n\n for (const token of tokens) {\n if (token.type === \"heading\" && token.depth === 2) {\n // Save previous entry\n if (currentEntry) {\n entries.push({\n id: currentEntry.id!,\n title: currentEntry.title!,\n content: currentContent.join(\"\\n\").trim(),\n source,\n });\n }\n\n // Start new entry\n const title = token.text;\n const id = slugify(title);\n currentEntry = { id, title, source };\n currentContent = [];\n } else if (currentEntry) {\n // Accumulate content for current entry\n currentContent.push(token.raw);\n }\n }\n\n // Save final entry\n if (currentEntry) {\n entries.push({\n id: currentEntry.id!,\n title: currentEntry.title!,\n content: currentContent.join(\"\\n\").trim(),\n source,\n });\n }\n\n return entries;\n}\n\n/**\n * Slugify string: lowercase, replace spaces with dashes, remove non-alphanumeric.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"\");\n}\n\n/**\n * Filter markdown entries by agent name.\n * Searches for agent name in entry content (case-insensitive).\n * Matches both \"Agent: name\" and \"**Agent**: name\" formats.\n */\nexport function filterByAgent(markdown: string, agentName: string, source: string): string {\n const entries = parseMarkdownEntries(markdown, source);\n const agentLower = agentName.toLowerCase();\n const filtered = entries.filter((entry) => {\n const contentLower = entry.content.toLowerCase();\n // Match \"Agent: name\" or \"**Agent**: name\"\n return contentLower.includes(`agent: ${agentLower}`) ||\n contentLower.includes(`**agent**: ${agentLower}`);\n });\n\n if (filtered.length === 0) return \"\";\n\n // Reconstruct markdown from filtered entries\n return filtered.map((entry) => `## ${entry.title}\\n\\n${entry.content}`).join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Filter markdown entries by recency (last N days).\n * Searches for \"Last seen: YYYY-MM-DD\" in entry content.\n * Handles both bold (**Last seen**:) and plain (Last seen:) formats.\n */\nexport function filterByRecency(markdown: string, source: string, days: number): string {\n const entries = parseMarkdownEntries(markdown, source);\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n\n const filtered = entries.filter((entry) => {\n // Match both **Last seen**: and Last seen: formats\n const match = entry.content.match(/(?:\\*\\*)?Last seen(?:\\*\\*)?:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n if (!match) return false; // No date found, exclude\n\n const lastSeen = new Date(match[1]);\n return lastSeen >= cutoffDate;\n });\n\n if (filtered.length === 0) return \"\";\n\n return filtered.map((entry) => `## ${entry.title}\\n\\n${entry.content}`).join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Load knowledge for specific agent and stage.\n * Returns Knowledge object with relevant sections and entry IDs.\n */\nexport async function loadKnowledge(agentName: string, stage?: string): Promise<Knowledge> {\n const knowledgeDir = findKnowledgeDir();\n\n // If no knowledge dir, return empty knowledge and suggest initialization\n if (!knowledgeDir) {\n if (!isTestEnvironment() && process.env.REYGENT_DEBUG !== 'knowledge') {\n console.warn(chalk.yellow(\"⚠ No knowledge directory found. Run 'reygent init' to create .reygent/knowledge/\"));\n }\n return {\n agentTips: \"\",\n commonFailures: \"\",\n successPatterns: \"\",\n projectConventions: \"\",\n entriesLoaded: [],\n };\n }\n\n if (!existsSync(knowledgeDir)) {\n return {\n agentTips: \"\",\n commonFailures: \"\",\n successPatterns: \"\",\n projectConventions: \"\",\n entriesLoaded: [],\n };\n }\n\n const entriesLoaded: string[] = [];\n\n // Load agent-specific tips (always relevant)\n const agentTipsPath = join(knowledgeDir, \"agents\", `${agentName}.md`);\n const agentTips = readMarkdown(agentTipsPath);\n if (agentTips) {\n const entries = parseMarkdownEntries(agentTips, agentTipsPath);\n entriesLoaded.push(...entries.map((e) => `${agentName}:${e.id}`));\n }\n\n // Load stage-relevant failures (filter by agent)\n const failuresPath = join(knowledgeDir, \"common-failures.md\");\n const allFailures = readMarkdown(failuresPath);\n const relevantFailures = filterByAgent(allFailures, agentName, failuresPath);\n if (relevantFailures) {\n const entries = parseMarkdownEntries(relevantFailures, failuresPath);\n entriesLoaded.push(...entries.map((e) => `failures:${e.id}`));\n }\n\n // Load recent success patterns (last 30 days)\n const patternsPath = join(knowledgeDir, \"success-patterns.md\");\n const allPatterns = readMarkdown(patternsPath);\n const recentPatterns = filterByRecency(allPatterns, patternsPath, 30);\n if (recentPatterns) {\n const entries = parseMarkdownEntries(recentPatterns, patternsPath);\n entriesLoaded.push(...entries.map((e) => `patterns:${e.id}`));\n }\n\n // Load project conventions (always relevant)\n const conventionsPath = join(knowledgeDir, \"project-conventions.md\");\n const projectConventions = readMarkdown(conventionsPath);\n if (projectConventions) {\n const entries = parseMarkdownEntries(projectConventions, conventionsPath);\n entriesLoaded.push(...entries.map((e) => `conventions:${e.id}`));\n }\n\n return {\n agentTips,\n commonFailures: relevantFailures,\n successPatterns: recentPatterns,\n projectConventions,\n entriesLoaded,\n };\n}\n\n/**\n * List all knowledge files in the knowledge directory.\n * Returns array of relative paths (e.g., \"common-failures.md\", \"agents/dev.md\").\n */\nexport function listKnowledgeFiles(): string[] {\n const knowledgeDir = findKnowledgeDir();\n if (!knowledgeDir || !existsSync(knowledgeDir)) return [];\n\n const files: string[] = [];\n\n function scan(dir: string, prefix: string = \"\") {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n const relativePath = prefix ? `${prefix}/${entry}` : entry;\n\n if (stat.isDirectory()) {\n scan(fullPath, relativePath);\n } else if (stat.isFile() && entry.endsWith(\".md\")) {\n files.push(relativePath);\n }\n }\n }\n\n scan(knowledgeDir);\n return files.sort();\n}\n\n/**\n * Search knowledge files for a query string.\n * Returns array of matching entries with file path and excerpt.\n */\nexport interface SearchResult {\n file: string;\n entry: KnowledgeEntry;\n excerpt: string; // snippet showing match context\n}\n\nexport function searchKnowledge(query: string): SearchResult[] {\n const knowledgeDir = findKnowledgeDir();\n if (!knowledgeDir || !existsSync(knowledgeDir)) return [];\n\n const files = listKnowledgeFiles();\n const results: SearchResult[] = [];\n const queryLower = query.toLowerCase();\n\n for (const file of files) {\n const filePath = join(knowledgeDir, file);\n const content = readMarkdown(filePath);\n const entries = parseMarkdownEntries(content, filePath);\n\n for (const entry of entries) {\n const titleMatch = entry.title.toLowerCase().includes(queryLower);\n const contentMatch = entry.content.toLowerCase().includes(queryLower);\n\n if (titleMatch || contentMatch) {\n // Extract excerpt (50 chars before and after match)\n const matchIndex = entry.content.toLowerCase().indexOf(queryLower);\n const start = Math.max(0, matchIndex - 50);\n const end = Math.min(entry.content.length, matchIndex + query.length + 50);\n const excerpt = \"...\" + entry.content.slice(start, end) + \"...\";\n\n results.push({ file, entry, excerpt });\n }\n }\n }\n\n return results;\n}\n","/**\n * Test environment detection utility.\n * Provides a single source of truth for checking if code is running in a test environment.\n */\n\n/**\n * Check if code is running in a test environment (vitest, jest, etc).\n *\n * Uses multiple signals:\n * - NODE_ENV === 'test' (common convention)\n * - VITEST === 'true' (vitest-specific)\n *\n * Note: We use process.env string checks instead of import.meta.env because:\n * 1. NODE_ENV is a runtime environment variable, not a build-time constant\n * 2. Test runners (vitest) set these at runtime, not during bundling\n * 3. import.meta.env is for Vite/bundler build-time constants\n */\nexport function isTestEnvironment(): boolean {\n return process.env.NODE_ENV === 'test' || process.env.VITEST === 'true';\n}\n","import { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { isDebug } from \"./debug.js\";\n\nexport interface ErrorTaskOptions {\n agent?: string;\n errorMessage?: string;\n apiErrorStatus?: number;\n}\n\n/**\n * Emit ERROR_TASK event to chesstrace if available.\n * Common pattern extracted from generate-spec.ts, planner.ts, implement.ts, etc.\n */\nexport function emitErrorTask(\n message: string,\n stage: string,\n options?: ErrorTaskOptions,\n): void {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message,\n stage,\n ...(options?.agent && { agent: options.agent }),\n ...(options?.errorMessage && { errorMessage: options.errorMessage }),\n ...(options?.apiErrorStatus && { apiErrorStatus: options.apiErrorStatus }),\n });\n } catch (err) {\n // Swallow emit errors to prevent telemetry from breaking main logic\n // Log to stderr in debug mode to help diagnose broken telemetry backends\n if (isDebug()) {\n const errMsg = err instanceof Error ? err.message : String(err);\n console.error(`[DEBUG] Telemetry emit failed (ERROR_TASK): ${errMsg}`);\n }\n }\n }\n}\n","import { getProvider } from \"./providers/index.js\";\nimport { resolveModel, resolveProvider } from \"./model.js\";\nimport { TaskError } from \"./task.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { loadKnowledge } from \"./knowledge/loader.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\n/**\n * Result returned by provider adapter spawn() method.\n * See Provider Adapter Contract in CLAUDE.md for full details.\n */\nexport interface SpawnResult {\n /** Agent output text (JSON, markdown, or plain text depending on agent) */\n stdout: string;\n /** Exit code: 0 for success, non-zero for failure */\n exitCode: number;\n /** Optional cost/token telemetry for usage tracking */\n usage?: UsageInfo;\n /** Clean error message from provider API (e.g., \"Model not available\"). Only present on errors. */\n errorMessage?: string;\n /** HTTP status code from API error (e.g., 404, 401, 429). Only present on API errors. */\n apiErrorStatus?: number;\n}\n\n/**\n * Check if model name looks malformed (obvious user input error).\n * Returns true if model is clearly invalid, false if it could be a valid custom model.\n */\nfunction looksLikeMalformedModel(model?: string): boolean {\n if (!model) return false;\n // Obvious signs of malformation: empty after trim, contains spaces, starts/ends with special chars\n const trimmed = model.trim();\n if (trimmed.length === 0) return true;\n if (/\\s/.test(trimmed)) return true;\n if (/^[^a-zA-Z0-9]|[^a-zA-Z0-9]$/.test(trimmed)) return true;\n // Very short model names (< 3 chars) are likely typos\n if (trimmed.length < 3) return true;\n return false;\n}\n\n/**\n * Build a detail string from a SpawnResult for error messages.\n * Includes errorMessage from the provider and raw stdout as fallback.\n */\nexport function formatExitDetail(result: SpawnResult, model?: string): string {\n if (result.errorMessage) {\n const status = result.apiErrorStatus ? ` (HTTP ${result.apiErrorStatus})` : \"\";\n let detail = `\\n ${result.errorMessage}${status}`;\n // Only show model selection tip if:\n // 1. It's a 404 error with \"not available\" pattern AND\n // 2. Model name looks malformed (obvious typo/error)\n // This avoids confusing users who intentionally use custom models not yet synced by provider\n if (result.apiErrorStatus === 404 && /not available/i.test(result.errorMessage) && looksLikeMalformedModel(model)) {\n detail += `\\n Tip: edit .reygent/config.json \"model\" field, or run \\`reygent config\\` to pick a supported model.`;\n }\n return detail;\n }\n const trimmed = result.stdout.trim();\n if (!trimmed) return \"\";\n const truncated = trimmed.slice(0, 500);\n const suffix = trimmed.length > 500 ? \"...\" : \"\";\n return `\\n ${truncated}${suffix}`;\n}\n\nexport interface SpawnOptions {\n quiet?: boolean;\n autoApprove?: boolean;\n provider?: string;\n model?: string;\n systemPrompt?: string;\n onActivity?: (event: ActivityEvent) => void;\n stage?: string;\n}\n\n/**\n * Spawns an agent in stream mode with a single prompt.\n * Interactive mode (via spawnInteractive) does not support onActivity\n * since it's used for terminal sessions where live status is not applicable.\n */\nexport async function spawnAgentStream(\n name: string,\n prompt: string,\n timeoutMs: number,\n options?: SpawnOptions,\n): Promise<SpawnResult> {\n const providerName = options?.provider ?? resolveProvider();\n const adapter = getProvider(providerName);\n const chesstrace = getChesstrace();\n\n const { available, reason } = await adapter.isAvailable();\n if (!available) {\n // Emit error.provider and error.task before throwing\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PROVIDER, {\n provider: providerName,\n reason,\n });\n }\n emitErrorTask(\n `Provider \"${providerName}\" is not available: ${reason}`,\n options?.stage ?? \"spawn\",\n { agent: name },\n );\n throw new TaskError(`Provider \"${providerName}\" is not available: ${reason}`);\n }\n\n const modelId = options?.model ?? await resolveModel(providerName);\n const startTime = Date.now();\n\n // Emit agent.spawn event before spawning\n if (chesstrace) {\n chesstrace.emit(Events.AGENT_SPAWN, {\n agent: name,\n provider: providerName,\n model: modelId,\n stage: options?.stage,\n });\n }\n\n // Load knowledge for agent\n const knowledge = await loadKnowledge(name, options?.stage);\n\n // Inject knowledge into system prompt if any exists\n let enhancedSystemPrompt = options?.systemPrompt;\n if (knowledge.entriesLoaded.length > 0) {\n const knowledgeSections: string[] = [];\n\n if (knowledge.commonFailures) {\n knowledgeSections.push(`### Common Failures to Avoid\\n${knowledge.commonFailures}`);\n }\n if (knowledge.successPatterns) {\n knowledgeSections.push(`### Success Patterns to Follow\\n${knowledge.successPatterns}`);\n }\n if (knowledge.agentTips) {\n knowledgeSections.push(`### Agent-Specific Tips (${name})\\n${knowledge.agentTips}`);\n }\n if (knowledge.projectConventions) {\n knowledgeSections.push(`### Project Conventions\\n${knowledge.projectConventions}`);\n }\n\n if (knowledgeSections.length > 0) {\n const knowledgeBlock = `\\n\\n## Project-Specific Knowledge\\n\\n${knowledgeSections.join(\"\\n\\n\")}\\n\\n---\\n\\n**Important**: Review above knowledge before proceeding. Avoid documented pitfalls.`;\n enhancedSystemPrompt = (enhancedSystemPrompt || \"\") + knowledgeBlock;\n }\n\n // Emit knowledge consultation event\n if (chesstrace) {\n chesstrace.emit(Events.KNOWLEDGE_CONSULTED, {\n agent: name,\n stage: options?.stage,\n entries: knowledge.entriesLoaded,\n entryCount: knowledge.entriesLoaded.length,\n });\n }\n }\n\n // Track timeout state to prevent duplicate events\n let timedOut = false;\n\n // Setup timeout handler\n const timeoutHandle = setTimeout(() => {\n timedOut = true;\n if (chesstrace) {\n chesstrace.emit(Events.AGENT_TIMEOUT, {\n agent: name,\n stage: options?.stage,\n timeoutMs,\n });\n }\n }, timeoutMs);\n\n try {\n const result = await adapter.spawn({\n prompt,\n systemPrompt: enhancedSystemPrompt,\n model: modelId,\n autoApprove: options?.autoApprove,\n quiet: options?.quiet,\n timeoutMs,\n agentName: name,\n onActivity: options?.onActivity,\n });\n\n // Clear timeout immediately after spawn completes\n clearTimeout(timeoutHandle);\n\n // Only emit complete if timeout didn't fire\n if (!timedOut && chesstrace) {\n const duration = Date.now() - startTime;\n chesstrace.emit(Events.AGENT_COMPLETE, {\n agent: name,\n stage: options?.stage,\n exitCode: result.exitCode,\n duration,\n success: result.exitCode === 0,\n });\n }\n\n return result;\n } catch (err) {\n // Clear timeout immediately\n clearTimeout(timeoutHandle);\n\n // Only emit complete if timeout didn't fire\n if (!timedOut && chesstrace) {\n const duration = Date.now() - startTime;\n chesstrace.emit(Events.AGENT_COMPLETE, {\n agent: name,\n stage: options?.stage,\n exitCode: -1,\n duration,\n success: false,\n });\n }\n\n throw err;\n }\n}\n","import { getAgents } from \"./config.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type { PlannerOutput, PlannerClarification, PlannerResult } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport function extractJSON(text: string): string {\n const trimmed = text.trim();\n\n // Try exact match: entire string is a fenced block\n const exact = trimmed.match(/^```(?:json)?\\s*\\n([\\s\\S]*?)\\n```$/);\n if (exact) return exact[1];\n\n // Try embedded fence: find last ```json ... ``` block in output\n const fences = [...trimmed.matchAll(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/g)];\n if (fences.length > 0) return fences[fences.length - 1][1];\n\n // Try raw JSON object: find last { ... } block\n const lastBrace = trimmed.lastIndexOf(\"}\");\n if (lastBrace !== -1) {\n // Walk backwards to find matching opening brace\n let depth = 0;\n for (let i = lastBrace; i >= 0; i--) {\n if (trimmed[i] === \"}\") depth++;\n if (trimmed[i] === \"{\") depth--;\n if (depth === 0) return trimmed.slice(i, lastBrace + 1);\n }\n }\n\n return trimmed;\n}\n\nexport interface PlannerOptions {\n makeAssumptions?: boolean;\n onActivity?: (event: ActivityEvent) => void;\n}\n\nfunction buildPrompt(spec: SpecPayload, previousAnswers?: string, options?: PlannerOptions): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let clarificationContext = \"\";\n if (previousAnswers) {\n clarificationContext = `\n\n## Previous Clarifications\n\n${previousAnswers}\n\nUse these clarifications to inform your plan.`;\n }\n\n const assumptionMode = options?.makeAssumptions === true;\n const clarificationInstructions = assumptionMode\n ? `\nIMPORTANT: Do NOT ask for clarification. If the spec is ambiguous or missing design decisions, make reasonable assumptions based on industry best practices and common patterns. Document your assumptions in the constraints field.`\n : `\nIMPORTANT: If spec is ambiguous or missing key design decisions, prefer \"needsClarification\" over hard failure. Ask specific questions about:\n- Authentication/authorization approach\n- Data storage/persistence strategy\n- API design decisions (REST vs GraphQL, pagination, filtering)\n- Error handling patterns\n- Scalability/performance requirements\n- Integration points with existing systems`;\n\n return `${systemPrompt}\n\n---\n\nBelow is the raw spec to analyse. Return ONLY valid JSON matching one of three shapes:\n\n**Valid spec (can create plan):**\n\\`\\`\\`json\n{ \"valid\": true, \"goals\": [\"...\"], \"tasks\": [\"...\"], \"constraints\": [\"...\"], \"dod\": [\"...\"] }\n\\`\\`\\`\n\n**Needs clarification (spec ambiguous or missing design decisions):**\n\\`\\`\\`json\n{ \"valid\": false, \"needsClarification\": true, \"questions\": [\"What auth method?\", \"Support pagination?\"] }\n\\`\\`\\`\n\n**Invalid spec (fundamental issues, cannot proceed):**\n\\`\\`\\`json\n{ \"valid\": false, \"errors\": [\"...\"] }\n\\`\\`\\`\n${clarificationInstructions}\n\nEach array must contain at least one non-empty string. Do not include any text outside the JSON object.\n\n---\n\n**Spec title:** ${spec.title}\n\n**Spec content:**\n${spec.content}${clarificationContext}`;\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n value.every((item) => typeof item === \"string\" && item.trim().length > 0)\n );\n}\n\nexport async function runPlanner(\n spec: SpecPayload,\n previousAnswers?: string,\n options?: PlannerOptions,\n): Promise<{ result: PlannerResult; usage?: UsageInfo }> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildPrompt(spec, previousAnswers, options);\n const spawnResult = await spawnAgentStream(\"planner\", prompt, 300_000, { quiet: true, onActivity: options?.onActivity, provider: plannerAgent?.provider, model: plannerAgent?.model });\n const { stdout: raw, exitCode, usage, errorMessage, apiErrorStatus } = spawnResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(spawnResult, plannerAgent?.model);\n emitErrorTask(\n `Planner: agent exited with code ${exitCode}${detail}`,\n \"plan\",\n { agent: \"planner\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`Planner: agent exited with code ${exitCode}${detail}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(raw));\n } catch (err) {\n // Emit error.parse before throwing\n const cleaned = extractJSON(raw);\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"planner\",\n expectedFormat: 'JSON object with valid/goals/tasks/constraints/dod or needsClarification/questions',\n received: cleaned.slice(0, 500),\n });\n }\n throw new TaskError(\"Planner: failed to parse result as JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (obj.valid === false) {\n // Check if needs clarification\n if (obj.needsClarification === true && Array.isArray(obj.questions)) {\n const questions = (obj.questions as unknown[]).filter(\n (q) => typeof q === \"string\" && q.trim().length > 0,\n ) as string[];\n\n if (questions.length > 0) {\n return { result: { needsClarification: true, questions }, usage };\n }\n }\n\n // Hard failure\n const errors = Array.isArray(obj.errors)\n ? (obj.errors as string[]).join(\"\\n - \")\n : \"unknown validation error\";\n emitErrorTask(\n `Planner: spec validation failed:\\n - ${errors}`,\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n `Planner: spec validation failed:\\n - ${errors}`,\n );\n }\n\n if (obj.valid !== true) {\n emitErrorTask(\n \"Planner: unexpected response — missing 'valid' field\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n \"Planner: unexpected response — missing 'valid' field\",\n );\n }\n\n const { goals, tasks, constraints, dod } = obj;\n\n const chesstrace = getChesstrace();\n if (!isNonEmptyStringArray(goals)) {\n emitErrorTask(\n \"Planner: 'goals' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'goals' must be a non-empty string array\");\n }\n if (!isNonEmptyStringArray(tasks)) {\n emitErrorTask(\n \"Planner: 'tasks' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'tasks' must be a non-empty string array\");\n }\n if (!isNonEmptyStringArray(constraints)) {\n emitErrorTask(\n \"Planner: 'constraints' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n \"Planner: 'constraints' must be a non-empty string array\",\n );\n }\n if (!isNonEmptyStringArray(dod)) {\n emitErrorTask(\n \"Planner: 'dod' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'dod' must be a non-empty string array\");\n }\n\n return { result: { goals, tasks, constraints, dod }, usage };\n}\n","import { getAgents } from \"./config.js\";\nimport { isDebug } from \"./debug.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport { TaskError } from \"./task.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport interface ClarificationResult {\n needsClarification: true;\n questions: string[];\n}\n\nexport interface ReadyResult {\n ready: true;\n}\n\nexport type ClarificationResponse = ClarificationResult | ReadyResult;\n\nfunction buildClarificationPrompt(description: string, previousAnswers?: string): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let answersContext = \"\";\n if (previousAnswers) {\n answersContext = `\n\n## Previous Clarifications\n\n${previousAnswers}\n\nConsider these answers. If you still have unresolved questions, ask them. Otherwise return ready.`;\n }\n\n return `${systemPrompt}\n\n---\n\nYou are preparing to generate a detailed markdown spec from a short description. Before generating, decide if you need clarifying questions.\n\nReturn ONLY valid JSON matching one of two shapes:\n\n**No questions needed (description is clear enough):**\n\\`\\`\\`json\n{ \"ready\": true }\n\\`\\`\\`\n\n**Need more information:**\n\\`\\`\\`json\n{ \"needsClarification\": true, \"questions\": [\"What authentication method?\", \"Should it support pagination?\"] }\n\\`\\`\\`\n\nAsk about things like:\n- Target users and use cases\n- Technical constraints or preferences\n- Integration points with existing systems\n- Scale and performance requirements\n- Authentication/authorization needs\n- Error handling expectations\n\nKeep questions specific and actionable (max 5). Do not include any text outside the JSON object.\n\n---\n\n**Description:** ${description}${answersContext}`;\n}\n\nfunction buildGeneratePrompt(description: string, clarificationAnswers?: string): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let answersContext = \"\";\n if (clarificationAnswers) {\n answersContext = `\n\n## Clarification Answers\n\n${clarificationAnswers}\n\nUse these answers to make the spec more precise and targeted.`;\n }\n\n return `${systemPrompt}\n\n---\n\nYou are generating a full markdown spec from a short description. Output ONLY the raw markdown content (no fences, no wrapper). The spec must include:\n\n- A top-level heading (\\`# Title\\`)\n- An **Overview** section explaining the feature\n- A **Requirements** section with a bulleted list\n- An **Acceptance Criteria** section with a bulleted list\n- A **Constraints** section noting any technical or process constraints\n\nBe specific and actionable. Expand the description into concrete requirements that a development team could implement without further clarification.\n\n---\n\n**Description:** ${description}${answersContext}`;\n}\n\nexport async function runClarification(\n description: string,\n previousAnswers?: string,\n onActivity?: (event: ActivityEvent) => void,\n): Promise<ClarificationResponse> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildClarificationPrompt(description, previousAnswers);\n const clarifyResult = await spawnAgentStream(\"generate-spec\", prompt, 120_000, { quiet: true, onActivity });\n const { stdout: raw, exitCode, errorMessage, apiErrorStatus } = clarifyResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(clarifyResult, plannerAgent?.model);\n emitErrorTask(\n `generate-spec: agent exited with code ${exitCode}${detail}`,\n \"clarification\",\n { agent: \"generate-spec\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`generate-spec: agent exited with code ${exitCode}${detail}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(raw));\n } catch {\n throw new TaskError(\"generate-spec: failed to parse clarification response as JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n if (isDebug()) {\n console.error(\"Clarification response malformed (not an object), falling back to ready. Raw:\", raw);\n }\n return { ready: true };\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (obj.ready === true) {\n return { ready: true };\n }\n\n if (obj.needsClarification === true && Array.isArray(obj.questions)) {\n const questions = (obj.questions as unknown[]).filter(\n (q) => typeof q === \"string\" && q.trim().length > 0,\n ) as string[];\n\n if (questions.length > 0) {\n return { needsClarification: true, questions };\n }\n }\n\n // Default to ready if response doesn't match expected shapes\n if (isDebug()) {\n console.error(\"Clarification response didn't match expected shape, falling back to ready. Parsed:\", parsed);\n }\n return { ready: true };\n}\n\nexport async function generateSpec(\n description: string,\n clarificationAnswers?: string,\n onActivity?: (event: ActivityEvent) => void,\n): Promise<string> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildGeneratePrompt(description, clarificationAnswers);\n const specResult = await spawnAgentStream(\"generate-spec\", prompt, 120_000, { onActivity });\n const { stdout, exitCode, errorMessage, apiErrorStatus } = specResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(specResult, plannerAgent?.model);\n emitErrorTask(\n `generate-spec: agent exited with code ${exitCode}${detail}`,\n \"generate\",\n { agent: \"generate-spec\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`generate-spec: agent exited with code ${exitCode}${detail}`);\n }\n\n if (!stdout) {\n throw new TaskError(\"generate-spec: empty result from agent\");\n }\n\n return stdout;\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { killAllChildrenProcesses } from \"./child-registry.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { resetTerminalForInput } from \"./terminal-reset.js\";\n\nexport type { ActivityEvent };\n\nconst TRACK_LENGTH = 4;\n\nconst PAW_POSITIONS = [0, 1, 2, 3, 2, 1];\n\n// Ref-counting for SIGINT handlers to prevent multiple instances racing\nlet sigintHandlerCount = 0;\nlet globalSigintHandler: (() => void) | null = null;\n\nexport function formatElapsed(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, \"0\")}s`;\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return `${hours}h ${String(remainMinutes).padStart(2, \"0\")}m`;\n}\n\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[\\d+m/g, \"\");\n}\n\nfunction truncateToWidth(text: string, maxWidth: number): string {\n const visible = stripAnsi(text);\n if (visible.length <= maxWidth) return text;\n\n // Truncate visible portion and append ellipsis\n const truncated = visible.slice(0, maxWidth - 1) + \"…\";\n\n // Re-apply original color to truncated text\n // Simple heuristic: if original text started with ANSI, wrap truncated in same\n const ansiMatch = text.match(/^(\\x1b\\[\\d+m)/);\n if (ansiMatch) {\n return ansiMatch[1] + truncated + \"\\x1b[0m\";\n }\n return truncated;\n}\n\nexport function buildAnimationFrame(\n position: number,\n label: string,\n elapsed: string,\n lastActivity?: ActivityEvent,\n): string {\n const track = Array.from({ length: TRACK_LENGTH }, (_, i) =>\n i === position ? chalk.yellowBright(\"🐾\") : chalk.gray(\"·\"),\n ).join(\" \");\n\n const mainLine = `${track} ${chalk.blue(label)} ${chalk.gray(elapsed)}`;\n\n if (lastActivity) {\n const parts = [lastActivity.agent];\n if (lastActivity.tool) parts.push(lastActivity.tool);\n if (lastActivity.detail) parts.push(lastActivity.detail.replace(/[\\r\\n]+/g, \" \"));\n const activityText = chalk.cyan(parts.join(\" → \"));\n\n // Combine on single line with separator to prevent cursor misalignment\n const terminalWidth = process.stdout.columns || 120;\n const separator = chalk.gray(\" | \");\n const combined = `${mainLine}${separator}${activityText}`;\n\n // Truncate if combined line exceeds terminal width\n return truncateToWidth(combined, terminalWidth - 2);\n }\n\n return mainLine;\n}\n\nexport interface LiveStatus {\n onActivity: (event: ActivityEvent) => void;\n succeed: (msg: string) => void;\n fail: (msg: string) => void;\n warn: (msg: string) => void;\n info: (msg: string) => void;\n stop: () => void;\n start: () => void;\n}\n\nexport function createLiveStatus(label: string): LiveStatus {\n const spinner = ora({\n spinner: { frames: [\"\"], interval: 200 },\n text: \"\",\n discardStdin: false,\n }).start();\n\n let frameIndex = 0;\n let lastActivity: ActivityEvent | undefined;\n const startTime = Date.now();\n\n // Debounce activity events to max 5 Hz (200ms)\n let lastActivityTime = 0;\n const MIN_ACTIVITY_INTERVAL = 200;\n\n function render() {\n const pos = PAW_POSITIONS[frameIndex % PAW_POSITIONS.length];\n const elapsed = formatElapsed(Date.now() - startTime);\n spinner.text = buildAnimationFrame(pos, label, elapsed, lastActivity);\n }\n\n render();\n\n let interval: ReturnType<typeof setInterval> | null = null;\n\n function createInterval() {\n // Guard against double creation\n if (interval) return interval;\n\n const id = setInterval(() => {\n frameIndex++;\n render();\n }, 200);\n id.unref();\n return id;\n }\n\n interval = createInterval();\n\n function cleanup() {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n\n // Decrement ref count and remove global handler if last instance\n if (sigintHandlerCount > 0) {\n sigintHandlerCount--;\n if (sigintHandlerCount === 0 && globalSigintHandler) {\n process.removeListener(\"SIGINT\", globalSigintHandler);\n globalSigintHandler = null;\n }\n }\n }\n\n function onSigInt() {\n cleanup();\n killAllChildrenProcesses();\n spinner.stop();\n process.exit(130);\n }\n\n // Install global SIGINT handler with ref-counting\n if (!globalSigintHandler) {\n globalSigintHandler = onSigInt;\n process.on(\"SIGINT\", globalSigintHandler);\n }\n sigintHandlerCount++;\n\n return {\n onActivity(event: ActivityEvent) {\n // Debounce to prevent spam from high-frequency tools\n const now = Date.now();\n if (now - lastActivityTime < MIN_ACTIVITY_INTERVAL) {\n // Update lastActivity but don't re-render yet\n lastActivity = {\n ...event,\n detail: event.detail?.slice(0, 80), // Defensive truncation\n };\n return;\n }\n\n lastActivityTime = now;\n lastActivity = {\n ...event,\n detail: event.detail?.slice(0, 80), // Cap detail length\n };\n render();\n },\n succeed(msg: string) {\n cleanup();\n spinner.succeed(msg);\n resetTerminalForInput();\n },\n fail(msg: string) {\n cleanup();\n spinner.fail(msg);\n resetTerminalForInput();\n },\n warn(msg: string) {\n cleanup();\n spinner.warn(msg);\n resetTerminalForInput();\n },\n info(msg: string) {\n cleanup();\n spinner.info(msg);\n resetTerminalForInput();\n },\n stop() {\n cleanup();\n spinner.stop();\n resetTerminalForInput();\n },\n start() {\n spinner.start();\n if (!interval) {\n interval = createInterval();\n }\n\n // Re-increment ref count when restarting\n if (globalSigintHandler) {\n sigintHandlerCount++;\n } else {\n globalSigintHandler = onSigInt;\n process.on(\"SIGINT\", globalSigintHandler);\n sigintHandlerCount++;\n }\n\n render();\n },\n };\n}\n","import chalk from \"chalk\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { ExitPromptError } from \"@inquirer/core\";\nimport { isDebug } from \"../debug.js\";\nimport { wrapText } from \"../format.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { loadSpec, SpecError, ISSUE_KEY_PATTERN } from \"../spec.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { runPlanner } from \"../planner.js\";\nimport { TaskError } from \"../task.js\";\nimport type { PlannerOutput } from \"../task.js\";\nimport type { SpecProvider } from \"../spec.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\n\nconst VALID_PROVIDERS: SpecProvider[] = [\"jira\", \"linear\", \"local\"];\n\ninterface SpecCommandOptions {\n clarify?: boolean;\n source?: string;\n}\n\n/**\n * Infer provider when unambiguous, or return undefined to trigger prompt.\n * Returns undefined only for ambiguous issue keys (e.g. ENG-123).\n */\nfunction inferProvider(source: string): SpecProvider | undefined {\n if (/^https:\\/\\/linear\\.app\\//.test(source)) {\n return \"linear\";\n }\n if (ISSUE_KEY_PATTERN.test(source)) {\n return undefined; // ambiguous — needs prompt\n }\n return \"local\"; // file path or anything else\n}\n\nexport async function specCommand(source: string, options: SpecCommandOptions): Promise<void> {\n return withTelemetry('spec', async () => {\n try {\n // Validate --source flag if given\n if (options.source !== undefined) {\n if (!VALID_PROVIDERS.includes(options.source as SpecProvider)) {\n console.log(\n chalk.red.bold(\"Error:\"),\n `Invalid source provider \"${options.source}\". Must be one of: ${VALID_PROVIDERS.join(\", \")}`,\n );\n process.exit(1);\n }\n }\n\n // Resolve provider: flag > inference > prompt\n let provider: SpecProvider | undefined = options.source as SpecProvider | undefined;\n\n // Validate source format matches explicit provider if given\n if (provider) {\n const hasMdExt = /\\.(md|markdown)$/i.test(source);\n const isLinearUrl = /^https:\\/\\/linear\\.app\\//.test(source);\n const isIssueKey = ISSUE_KEY_PATTERN.test(source);\n\n // Only warn for clear mismatches\n if (provider === \"local\" && isLinearUrl) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" is a Linear URL, but --source=local treats it as a file path.`,\n );\n } else if (provider === \"linear\" && hasMdExt) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" ends in .md/.markdown, but --source=linear treats it as a Linear issue ID.`,\n );\n } else if (provider === \"jira\" && hasMdExt) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" ends in .md/.markdown, but --source=jira treats it as a Jira issue key.`,\n );\n }\n }\n\n if (!provider) {\n provider = inferProvider(source);\n }\n\n if (!provider) {\n // Need to prompt — check for TTY\n if (!process.stdin.isTTY) {\n console.log(\n chalk.red.bold(\"Error:\"),\n `Cannot determine provider for \"${source}\" in non-interactive mode. Use --source <jira|linear|local>.`,\n );\n process.exit(1);\n }\n\n resetTerminalForInput();\n provider = await select<SpecProvider>({\n message: \"Which provider is this issue from?\",\n choices: [\n { name: \"Jira\", value: \"jira\" },\n { name: \"Linear\", value: \"linear\" },\n { name: \"Local file\", value: \"local\" },\n ],\n });\n }\n\n const spec = await loadSpec(source, provider);\n\n if (!options.clarify) {\n // Original behavior: just output spec JSON\n console.log(JSON.stringify(spec, null, 2));\n return;\n }\n\n // Run planner with clarification loop\n const status = createLiveStatus(\"running planner...\");\n\n let plan: PlannerOutput | null = null;\n let clarificationAnswers = \"\";\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!plan && attempts < maxAttempts) {\n attempts++;\n const { result } = await runPlanner(spec, clarificationAnswers, { onActivity: status.onActivity });\n\n if (\"needsClarification\" in result && result.needsClarification) {\n status.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\nPlanner needs clarification:\\n\"));\n\n const answers: string[] = [];\n\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n console.log(` [${i + 1}/${result.questions.length}] ${question}`);\n resetTerminalForInput();\n const answer = await pasteableInput({ message: \">\" });\n\n if (answer.toLowerCase() === \"abort\" || answer.toLowerCase() === \"cancel\") {\n throw new TaskError(\"Planner: clarification aborted by user\");\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n }\n clarificationAnswers = answers.join(\"\\n\\n\");\n console.log(chalk.blue(\"\\nRe-running planner with clarifications...\\n\"));\n status.start();\n } else {\n plan = result as PlannerOutput;\n }\n }\n\n if (!plan) {\n status.fail(chalk.red(\"Planner failed\"));\n throw new TaskError(`Planner: failed to create valid plan after ${maxAttempts} attempts`);\n }\n\n status.succeed(chalk.green(\"Plan created\"));\n\n const cols = process.stdout.columns || 80;\n console.log(chalk.cyan(\"\\nGoals:\"));\n for (const g of plan.goals) console.log(` ${chalk.gray(\"-\")} ${wrapText(g, 4, cols)}`);\n console.log(chalk.cyan(\"\\nTasks:\"));\n for (const t of plan.tasks) console.log(` ${chalk.gray(\"-\")} ${wrapText(t, 4, cols)}`);\n console.log(chalk.cyan(\"\\nConstraints:\"));\n for (const c of plan.constraints) console.log(` ${chalk.gray(\"-\")} ${wrapText(c, 4, cols)}`);\n console.log(chalk.cyan(\"\\nDefinition of Done:\"));\n for (const d of plan.dod) console.log(` ${chalk.gray(\"-\")} ${wrapText(d, 4, cols)}`);\n } catch (err) {\n if (err instanceof ExitPromptError) {\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","/**\n * Custom input prompt based on @inquirer/input v5.0.11.\n *\n * Fixes two cursor-tracking bugs in @inquirer/core's ScreenManager:\n *\n * 1. `checkCursorPos()` only corrects the column on keypress, never the row.\n * When arrow keys / Home / End don't change `rl.line`, `useState` skips\n * the re-render and the cursor stays on the wrong visual row.\n * Fix: track `rl.cursor` in a separate `useState`. When cursor position\n * changes, `useState` sees a new value → triggers `handleChange()` →\n * full `render()` → correct row+column positioning.\n *\n * 2. When prompt + input exceeds terminal width, `breakLines()` inserts `\\n`\n * at the width boundary. `screen.render()` then calculates the prompt via\n * `lastLine(content)`, but if `rl.line` spans across the inserted `\\n`,\n * the prompt becomes shorter than `rl.line`, the `setPrompt()` call uses\n * an empty string, and `getCursorPos()` returns wrong column values.\n * Fix: render user input on a separate line from the prompt message during\n * active editing, so `breakLines` never splits `rl.line` across lines.\n *\n * Also handles paste injection: when pasteState.pending is true,\n * the accumulated text is inserted directly into rl.line (bypassing\n * readline's per-character processing) and a single render fires.\n */\nimport {\n createPrompt,\n useState,\n useKeypress,\n useEffect,\n usePrefix,\n isBackspaceKey,\n isEnterKey,\n isTabKey,\n makeTheme,\n type Theme,\n} from \"@inquirer/core\";\nimport type { PartialDeep } from \"@inquirer/type\";\nimport { pasteState } from \"./paste-state.js\";\n\ntype InputTheme = {\n validationFailureMode: \"keep\" | \"clear\";\n};\n\ntype InputConfig = {\n message: string;\n default?: string;\n prefill?: \"tab\" | \"editable\";\n required?: boolean;\n transformer?: (value: string, opts: { isFinal: boolean }) => string;\n validate?: (value: string) => boolean | string | Promise<string | boolean>;\n theme?: PartialDeep<Theme<InputTheme>>;\n pattern?: RegExp;\n patternError?: string;\n};\n\nconst inputTheme: InputTheme = {\n validationFailureMode: \"keep\",\n};\n\nexport default createPrompt<string, InputConfig>((config, done) => {\n const { prefill = \"tab\" } = config;\n const theme = makeTheme(inputTheme, config.theme);\n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"done\">(\"idle\");\n const [defaultValue, setDefaultValue] = useState<string>(\n String(config.default ?? \"\"),\n );\n const [errorMsg, setError] = useState<string | undefined>();\n const [value, setValue] = useState<string>(\"\");\n const [, setCursorPos] = useState<number>(0);\n const prefix = usePrefix({ status, theme });\n\n async function validate(val: string): Promise<true | string> {\n const { required, pattern, patternError = \"Invalid input\" } = config;\n if (required && !val) {\n return \"You must provide a value\";\n }\n if (pattern && !pattern.test(val)) {\n return patternError;\n }\n if (typeof config.validate === \"function\") {\n return (await config.validate(val)) || \"You must provide a valid value\";\n }\n return true;\n }\n\n useKeypress(async (key, rl) => {\n if (status !== \"idle\") {\n return;\n }\n\n // --- Paste injection: insert accumulated text into rl.line directly ---\n if (pasteState.pending) {\n const text = pasteState.text;\n pasteState.pending = false;\n pasteState.text = \"\";\n\n // Insert at current cursor position\n const before = rl.line.slice(0, rl.cursor);\n const after = rl.line.slice(rl.cursor);\n rl.line = before + text + after;\n rl.cursor = before.length + text.length;\n\n setDefaultValue(\"\");\n setValue(rl.line);\n setError(undefined);\n setCursorPos(rl.cursor);\n return;\n }\n\n if (isEnterKey(key)) {\n const answer = value || defaultValue;\n setStatus(\"loading\");\n const isValid = await validate(answer);\n if (isValid === true) {\n setValue(answer);\n setStatus(\"done\");\n done(answer);\n } else {\n if (theme.validationFailureMode === \"clear\") {\n setValue(\"\");\n } else {\n rl.write(value);\n }\n setError(isValid);\n setStatus(\"idle\");\n }\n } else if (isBackspaceKey(key) && !value) {\n setDefaultValue(\"\");\n } else if (isTabKey(key) && !value) {\n setDefaultValue(\"\");\n rl.clearLine(0);\n rl.write(defaultValue);\n setValue(defaultValue);\n } else {\n setValue(rl.line);\n setError(undefined);\n setCursorPos(rl.cursor); // force re-render on cursor movement\n }\n });\n\n useEffect((rl) => {\n if (prefill === \"editable\" && defaultValue) {\n rl.write(defaultValue);\n setValue(defaultValue);\n }\n }, []);\n\n const message = theme.style.message(config.message, status);\n let formattedValue = value;\n if (typeof config.transformer === \"function\") {\n formattedValue = config.transformer(value, { isFinal: status === \"done\" });\n } else if (status === \"done\") {\n formattedValue = theme.style.answer(value);\n }\n\n let defaultStr: string | undefined;\n if (defaultValue && status !== \"done\" && !value) {\n defaultStr = theme.style.defaultAnswer(defaultValue);\n }\n\n let error = \"\";\n if (errorMsg) {\n error = theme.style.error(errorMsg);\n }\n\n // When status is \"done\", render everything on one line (standard @inquirer\n // completion display — no cursor interaction, so wrapping is harmless).\n if (status === \"done\") {\n return [\n [prefix, message, defaultStr, formattedValue]\n .filter((v) => v !== undefined)\n .join(\" \"),\n error,\n ];\n }\n\n // During active editing, render input on its own line. This prevents\n // @inquirer/core's breakLines() from splitting rl.line across visual\n // lines, which would break screen.render()'s cursor positioning math\n // (see bug #2 in the file header).\n const promptLine = [prefix, message, defaultStr]\n .filter((v) => v !== undefined)\n .join(\" \");\n\n return [promptLine + \"\\n\" + formattedValue, error];\n});\n","/**\n * Shared paste state between pasteable-input and cursor-aware-input.\n *\n * pasteable-input accumulates pasted text here (bypassing readline).\n * cursor-aware-input checks `pending` on each keypress — when true,\n * it injects the text into rl.line directly and triggers one render.\n *\n * Separate module avoids circular dependency between the two.\n */\nexport const pasteState = {\n /** True when accumulated paste text is ready to be consumed. */\n pending: false,\n /** Accumulated paste content (newlines replaced with spaces). */\n text: \"\",\n};\n","import cursorAwareInput from \"./cursor-aware-input.js\";\nimport { pasteState } from \"./paste-state.js\";\n\nconst PASTE_START = \"\\x1b[200~\";\nconst PASTE_END = \"\\x1b[201~\";\nconst PASTE_BRACKET_ON = \"\\x1b[?2004h\";\nconst PASTE_BRACKET_OFF = \"\\x1b[?2004l\";\n\n/**\n * Paste-aware wrapper around cursor-aware input.\n *\n * Problem: readline treats every \\r / \\n as Enter (submit), and each\n * character triggers a separate keypress → re-render cycle. Pasting\n * text causes immediate submission (trailing newline) and visible\n * cursor jumping (N renders for N characters).\n *\n * Solution: enable terminal *bracketed paste mode* so the terminal\n * wraps pasted content in \\x1b[200~ … \\x1b[201~ markers. We patch\n * stdin.emit to intercept 'data' events. Instead of forwarding pasted\n * characters to readline (which would process them one-by-one), we\n * accumulate the text in a shared pasteState object. After the paste\n * ends we emit a single synthetic keypress; cursor-aware-input detects\n * the pending paste, injects the text into rl.line directly, and\n * triggers exactly one render. Zero intermediate redraws.\n */\nexport async function pasteableInput(\n config: Parameters<typeof cursorAwareInput>[0],\n context?: Parameters<typeof cursorAwareInput>[1],\n): Promise<string> {\n const stdin = process.stdin;\n let inPaste = false;\n let justPasted = false; // stays true for one chunk after paste ends\n\n // Enable bracketed paste mode\n if (stdin.isTTY) {\n process.stdout.write(PASTE_BRACKET_ON);\n }\n\n // Temporarily patch stdin.emit to intercept 'data' events for paste\n // handling while preserving all TTY properties for readline/inquirer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const originalEmit = stdin.emit as (...args: any[]) => boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function patchedEmit(this: typeof stdin, event: string | symbol, ...args: any[]): boolean {\n if (event === \"data\") {\n let chunk = args[0];\n let str: string = Buffer.isBuffer(chunk) ? chunk.toString(\"utf-8\") : String(chunk);\n const wasPasting = inPaste;\n const wasJustPasted = justPasted;\n justPasted = false;\n\n // Detect and strip paste-start marker\n const startIdx = str.indexOf(PASTE_START);\n if (startIdx !== -1) {\n inPaste = true;\n str = str.slice(0, startIdx) + str.slice(startIdx + PASTE_START.length);\n }\n\n // Detect and strip paste-end marker\n const endIdx = str.indexOf(PASTE_END);\n if (endIdx !== -1) {\n str = str.slice(0, endIdx) + str.slice(endIdx + PASTE_END.length);\n inPaste = false;\n justPasted = true;\n }\n\n // --- Paste content: accumulate, don't forward to readline ---\n if (wasPasting || startIdx !== -1) {\n str = str.replace(/\\r?\\n|\\r/g, \" \");\n pasteState.text += str;\n\n if (!inPaste) {\n // Paste complete — trim trailing whitespace from accumulated\n // text (clipboard often appends a newline → trailing space).\n pasteState.text = pasteState.text.trimEnd();\n pasteState.pending = true;\n\n // Emit synthetic keypress so cursor-aware-input's useKeypress\n // fires once, picks up the pending text, and renders.\n // Empty string → readline's _ttyWrite is a no-op.\n // checkCursorPos sees no change (rl.line hasn't changed yet).\n originalEmit.apply(this, [\"keypress\", \"\", { name: \"\" }]);\n }\n return false; // swallow data event — don't send to readline\n }\n\n // --- Straggling newline after paste-end (arrives in next chunk) ---\n if (wasJustPasted) {\n if (/^(\\r?\\n|\\r)+$/.test(str)) {\n return false; // swallow pure newline stragglers\n }\n // Non-newline content right after paste — fall through to normal\n }\n\n // --- Regular keystroke: forward unchanged ---\n if (str.length === 0) {\n return false;\n }\n args[0] = Buffer.from(str, \"utf-8\");\n }\n return originalEmit.apply(this, [event, ...args]);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stdin.emit = patchedEmit as any;\n\n try {\n return await cursorAwareInput(config, context);\n } finally {\n stdin.emit = originalEmit;\n if (stdin.isTTY) {\n process.stdout.write(PASTE_BRACKET_OFF);\n }\n inPaste = false;\n justPasted = false;\n pasteState.pending = false;\n pasteState.text = \"\";\n }\n}\n","/** Strip ANSI escape codes for accurate visual length measurement. */\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\n/**\n * Word-wrap text to fit terminal width, preserving indentation on continuation lines.\n *\n * @param text Text to wrap (may contain ANSI codes)\n * @param indent Number of columns reserved for the prefix on continuation lines\n * @param maxWidth Terminal width (columns)\n * @param continuationPrefix Optional string to prepend to continuation lines instead of spaces\n */\nexport function wrapText(text: string, indent: number, maxWidth: number, continuationPrefix?: string): string {\n const available = maxWidth - indent;\n if (available <= 20 || stripAnsi(text).length <= available) return text;\n\n const words = text.split(\" \");\n const wrappedLines: string[] = [];\n let currentLine = \"\";\n\n for (const word of words) {\n if (currentLine.length === 0) {\n currentLine = word;\n } else if (stripAnsi(currentLine).length + 1 + stripAnsi(word).length <= available) {\n currentLine += \" \" + word;\n } else {\n wrappedLines.push(currentLine);\n currentLine = word;\n }\n }\n if (currentLine) wrappedLines.push(currentLine);\n\n const pad = continuationPrefix ?? \" \".repeat(indent);\n return wrappedLines.join(\"\\n\" + pad);\n}\n","import { createInterface } from \"node:readline\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { isDebug } from \"../debug.js\";\nimport { wrapText } from \"../format.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { runUnitTestGate, runFunctionalTestGate } from \"../gate.js\";\nimport { runImplement } from \"../implement.js\";\nimport type { FailureContext } from \"../implement.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { runPlanner } from \"../planner.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { runPRCreate } from \"../pr-create.js\";\nimport { normalizeType, detectTypeFromJiraIssueType, detectTypeFromLinearLabels, VALID_BRANCH_TYPES, type BranchType } from \"../branch-type.js\";\nimport { runPRReview, formatPRReviewTerminal, postPRReviewComment } from \"../pr-review.js\";\nimport { runSecurityReview, formatFindings } from \"../security-review.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { PIPELINE, TaskError } from \"../task.js\";\nimport type { Severity, StageResult, TaskContext, PlannerOutput } from \"../task.js\";\nimport { UsageTracker, printUsageSummary, printVerboseUsage } from \"../usage.js\";\nimport { Chesstrace, getChesstrace } from \"../chesstrace/index.js\";\nimport { Events, TelemetryLevel } from \"../chesstrace/events.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getTelemetryOverride, resolveTelemetryEnabled } from \"../telemetry-override.js\";\nimport { analyzeFailurePatterns, analyzeSuccessPatterns } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { findProjectRoot } from \"../project-detection.js\";\nimport { DualBackend } from \"../chesstrace/backends/dual.js\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { isTestEnvironment } from \"../test-env.js\";\nimport { promptForRetry } from \"../retry-prompt.js\";\n\nconst VALID_SEVERITIES = new Set<string>([\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"]);\n\n/**\n * Emit stage.end event with duration and success status\n * Also emits tool.summary if toolTracker provided\n *\n * Note: Empty summaries (no tool calls) emit tool.summary with empty toolCounts object.\n * This is acceptable behavior and tested in tool-tracking-integration.test.ts\n */\nfunction emitStageEnd(\n chesstrace: Chesstrace | null,\n stageName: string,\n stageStartTime: number,\n success: boolean,\n metadata?: { cost?: number; outputSummary?: string },\n toolTracker?: ToolTracker,\n): void {\n if (!chesstrace) return;\n try {\n // Emit tool.summary before stage end\n if (toolTracker) {\n const summary = toolTracker.getSummary();\n if (Object.keys(summary).length > 0) {\n chesstrace.emit(Events.TOOL_SUMMARY, {\n stage: stageName,\n toolCounts: summary,\n });\n }\n }\n\n chesstrace.emit(Events.PIPELINE_STAGE_END, {\n stage: stageName,\n success,\n durationMs: Date.now() - stageStartTime,\n ...(metadata && { metadata }),\n });\n } catch {\n // Swallow emit errors\n }\n}\n\n/**\n * Update knowledge base from recent telemetry data.\n * Extracts patterns from last 7 days and adds to knowledge files.\n * Runs silently - no output unless errors occur.\n *\n * Only updates if in a project (has .git, package.json, etc.).\n * Uses project root directory for knowledge files.\n */\nasync function updateKnowledgeFromTelemetry(): Promise<void> {\n try {\n // Check if in a project - skip if not\n const projectRoot = findProjectRoot(process.cwd());\n if (!projectRoot) {\n // Not in a project - skip knowledge update\n return;\n }\n\n const backend = new SqliteBackend(\"local\", `${projectRoot}/.reygent/chesstrace.db`);\n await backend.init();\n\n const since = Date.now() - 7 * 24 * 60 * 60 * 1000; // Last 7 days\n\n // Extract failure patterns\n const failurePatterns = analyzeFailurePatterns(backend, since);\n const topFailures = failurePatterns.slice(0, 3); // Top 3 only\n\n for (const pattern of topFailures) {\n for (const agent of pattern.agents) {\n try {\n await addFailureEntry(projectRoot, {\n issue: pattern.pattern,\n solution: \"Review telemetry for details\",\n agent: agent as any,\n });\n } catch {\n // Ignore duplicate entries\n }\n }\n }\n\n // Extract success patterns\n const successPatterns = analyzeSuccessPatterns(backend, since, 0.85);\n const topSuccess = successPatterns.slice(0, 3); // Top 3 only\n\n for (const pattern of topSuccess) {\n try {\n await addPatternEntry(projectRoot, {\n description: pattern.pattern,\n successRate: Math.round(pattern.successRate * 100),\n });\n } catch {\n // Ignore duplicate entries\n }\n }\n\n await backend.close();\n } catch (err) {\n // Silently fail - don't interrupt user workflow\n // Log for debugging if REYGENT_DEBUG=knowledge enabled\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'knowledge') {\n console.error('[debug:knowledge] updateKnowledgeFromTelemetry failed:', err instanceof Error ? err.message : String(err));\n }\n }\n}\n\n/**\n * Tool call tracking data structure\n */\ninterface ToolTracker {\n /** Map of agent -> tool -> count */\n counts: Map<string, Map<string, number>>;\n /** Record a tool invocation */\n record(agent: string, tool: string): void;\n /** Get summary of tool counts per agent */\n getSummary(): Record<string, Record<string, number>>;\n}\n\nfunction createToolTracker(): ToolTracker {\n const counts = new Map<string, Map<string, number>>();\n\n return {\n counts,\n record(agent: string, tool: string) {\n if (!counts.has(agent)) {\n counts.set(agent, new Map());\n }\n const agentMap = counts.get(agent)!;\n agentMap.set(tool, (agentMap.get(tool) ?? 0) + 1);\n },\n getSummary() {\n const summary: Record<string, Record<string, number>> = {};\n for (const [agent, toolMap] of counts) {\n summary[agent] = Object.fromEntries(toolMap);\n }\n return summary;\n },\n };\n}\n\n/**\n * Truncate string to max length for telemetry events.\n * Exported for use in tests to ensure consistent truncation behavior.\n */\nexport function truncateToolData(str: string | undefined, maxLen: number): string | undefined {\n if (!str) return undefined;\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen);\n}\n\n/**\n * Helper to merge agentOptions with onActivity callback from a LiveStatus instance.\n * Reduces boilerplate from repeated `{ ...agentOptions, onActivity: status.onActivity }` pattern.\n * Also wires tool invocation telemetry.\n */\nfunction withActivity(\n agentOptions: { autoApprove: boolean },\n status: { onActivity: (event: import(\"../live-status.js\").ActivityEvent) => void },\n toolTracker?: ToolTracker,\n): { autoApprove: boolean; onActivity: (event: import(\"../live-status.js\").ActivityEvent) => void } {\n return {\n ...agentOptions,\n onActivity: (event) => {\n // Call original live status handler\n status.onActivity(event);\n\n // Emit tool telemetry if tool present\n if (event.tool) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n // Standard level: tool.invoke with agent, tool, detail\n chesstrace.emit(Events.TOOL_INVOKE, {\n agent: event.agent,\n tool: event.tool,\n detail: event.detail,\n });\n\n // Verbose level: tool.invoke.full with truncated detail\n // Note: ActivityEvent doesn't carry input/output fields separately,\n // so detail field serves as proxy for tool parameters/results\n chesstrace.emit(Events.TOOL_INVOKE_FULL, {\n agent: event.agent,\n tool: event.tool,\n detail: truncateToolData(event.detail, 500),\n });\n } catch {\n // Swallow telemetry errors\n }\n }\n\n // Track tool count if tracker provided\n if (toolTracker) {\n toolTracker.record(event.agent, event.tool);\n }\n }\n },\n };\n}\n\ninterface RunOptions {\n spec?: string;\n type?: string;\n dryRun: boolean;\n securityThreshold: string;\n autoApprove: boolean;\n insecure: boolean;\n skipClarification: boolean;\n maxRetries: string;\n verbose: boolean;\n}\n\nconst MAX_TEST_OUTPUT_CHARS = 8000;\n\nfunction truncateForPrompt(output: string): string {\n if (output.length <= MAX_TEST_OUTPUT_CHARS) return output;\n const half = Math.floor(MAX_TEST_OUTPUT_CHARS / 2);\n return (\n output.slice(0, half) +\n \"\\n\\n... [truncated] ...\\n\\n\" +\n output.slice(-half)\n );\n}\n\ninterface RetryGateOptions {\n gateName: string;\n gateRunner: (attempt: number) => Promise<{ gate: import(\"../task.js\").GateResult; usage?: import(\"../usage.js\").UsageInfo }>;\n agentsToRun: Array<\"dev\" | \"qe\">;\n context: TaskContext;\n agentOptions: { autoApprove: boolean };\n maxRetries: number;\n autoApprove: boolean;\n stageName: string;\n tracker: UsageTracker;\n verbose: boolean;\n toolTracker: ToolTracker;\n}\n\nasync function retryGate(opts: RetryGateOptions): Promise<import(\"../task.js\").GateResult> {\n const { gateName, gateRunner, agentsToRun, context, agentOptions, maxRetries, autoApprove, stageName, tracker, verbose, toolTracker } = opts;\n\n let attempt = 0;\n\n // Retry loop - continue until test passes or user aborts\n while (true) {\n attempt++;\n const lastOutput = context.gates?.[gateName === \"unit tests\" ? \"unitTests\" : \"functionalTests\"]?.output ?? \"\";\n\n // Check if exceeded max retries or prompt user\n await promptForRetry({\n taskName: gateName,\n attempt,\n maxRetries,\n autoApprove,\n telemetry: {\n stageName,\n agentName: gateName === \"unit tests\" ? \"gate:unit-tests\" : \"gate:functional-tests\",\n },\n });\n\n // Emit gate.retry telemetry after user approves\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n const failureSnippet = lastOutput.length > 500\n ? lastOutput.slice(-500)\n : lastOutput;\n chesstrace.emit(Events.GATE_RETRY, {\n gateName,\n attempt,\n maxRetries,\n failureSnippet,\n });\n } catch (err) {\n if (verbose) {\n console.error(\"[telemetry]\", err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n const attemptDisplay = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n console.log(chalk.yellow(`\\nRetrying ${gateName} (attempt ${attemptDisplay})...`));\n\n const failureContext: FailureContext = {\n gateName,\n testOutput: truncateForPrompt(lastOutput),\n attempt,\n maxAttempts: maxRetries > 0 ? maxRetries : 0,\n };\n\n const status = createLiveStatus(`re-running ${agentsToRun.join(\" + \")} agent(s)...`);\n const { implement: retryResult, usages: retryUsages } = await runImplement(\n context.spec,\n context.plan!,\n withActivity(agentOptions, status, toolTracker),\n { failureContext, agentsToRun },\n );\n\n // Record retry implementation usage\n for (const u of retryUsages) {\n if (u.usage) tracker.record(u.agent, `${stageName}-retry`, u.usage);\n }\n\n // Merge results into context\n if (retryResult.dev && context.implement) {\n context.implement.dev = retryResult.dev;\n }\n if (retryResult.qe && context.implement) {\n context.implement.qe = retryResult.qe;\n }\n status.succeed(chalk.green(\"Retry implementation complete\"));\n\n // Re-run gate\n const retryStatus = createLiveStatus(`re-running ${gateName}...`);\n const { gate: gateResult, usage: gateUsage } = await gateRunner(attempt + 1);\n\n const gateAgentName =\n gateName === \"unit tests\" ? \"gate:unit-tests\" : \"gate:functional-tests\";\n if (gateUsage) tracker.record(gateAgentName, `${stageName}-retry`, gateUsage);\n\n if (!context.gates) context.gates = {};\n if (gateName === \"unit tests\") {\n context.gates.unitTests = gateResult;\n } else {\n context.gates.functionalTests = gateResult;\n }\n\n if (gateResult.passed) {\n retryStatus.succeed(chalk.green(`${gateName} PASSED on retry ${attempt}`));\n return gateResult;\n }\n\n const attemptDisplayFail = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n retryStatus.fail(chalk.red(`${gateName} FAILED (retry ${attemptDisplayFail})`));\n }\n}\n\nasync function promptLinearSpec(): Promise<string> {\n loadEnvFile();\n if (!process.env.LINEAR_API_KEY) {\n console.log(chalk.red.bold(\"Error:\"), \"LINEAR_API_KEY not set. Add it to your .env file.\");\n process.exit(1);\n }\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Linear issue URL or ID (e.g. ENG-123):\",\n validate: (v) => {\n const trimmed = v.trim();\n if (!trimmed) return \"Required\";\n if (/^https:\\/\\/linear\\.app\\/.+/.test(trimmed)) return true;\n if (/^[A-Z]+-\\d+$/i.test(trimmed)) return true;\n return \"Enter a Linear URL or issue ID (e.g. ENG-123)\";\n },\n });\n return value.trim();\n}\n\nasync function promptJiraSpec(): Promise<string> {\n loadEnvFile();\n const missing: string[] = [];\n if (!process.env.JIRA_URL) missing.push(\"JIRA_URL\");\n if (!process.env.JIRA_EMAIL) missing.push(\"JIRA_EMAIL\");\n if (!process.env.JIRA_API_TOKEN) missing.push(\"JIRA_API_TOKEN\");\n if (missing.length > 0) {\n console.log(chalk.red.bold(\"Error:\"), `Missing env vars: ${missing.join(\", \")}. Add them to your .env file.`);\n process.exit(1);\n }\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Jira issue key (e.g. PROJ-123):\",\n validate: (v) => {\n const trimmed = v.trim();\n if (!trimmed) return \"Required\";\n if (/^[A-Z]+-\\d+$/i.test(trimmed)) return true;\n return \"Enter a Jira issue key (e.g. PROJ-123)\";\n },\n });\n return value.trim();\n}\n\nasync function promptMarkdownSpec(): Promise<string> {\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Path to markdown spec file:\",\n validate: (v) => (v.trim() ? true : \"Required\"),\n });\n return value.trim();\n}\n\nasync function promptForSpec(): Promise<string> {\n resetTerminalForInput();\n const source = await select({\n message: \"Where is the workflow spec?\",\n choices: [\n { name: \"Local Markdown file\", value: \"markdown\" },\n { name: \"Linear issue\", value: \"linear\" },\n { name: \"Jira issue\", value: \"jira\" },\n ],\n });\n\n switch (source) {\n case \"linear\":\n return promptLinearSpec();\n case \"jira\":\n return promptJiraSpec();\n case \"markdown\":\n default:\n return promptMarkdownSpec();\n }\n}\n\nexport async function runCommand(options: RunOptions): Promise<void> {\n const pipelineStartTime = Date.now();\n\n // Initialize tracker and context early for error handling\n const tracker = new UsageTracker();\n let context: TaskContext | undefined;\n\n // Load config and check if telemetry is enabled\n const config = loadConfig();\n const telemetryOverride = getTelemetryOverride();\n\n // Apply CLI flag overrides\n const { enabled: telemetryEnabled, level: telemetryLevelStr } = resolveTelemetryEnabled(\n telemetryOverride,\n config\n );\n const telemetryLevel = TelemetryLevel[telemetryLevelStr];\n\n let chesstrace: Chesstrace | null = null;\n\n // Detect if in a project and auto-create .reygent/ if needed\n const projectRoot = findProjectRoot(process.cwd());\n let createdReygentDir = false;\n\n if (projectRoot) {\n const reygentDir = join(projectRoot, '.reygent');\n if (!existsSync(reygentDir)) {\n try {\n mkdirSync(reygentDir, { recursive: true });\n createdReygentDir = true;\n } catch (err) {\n // Failed to create - will fall back to global\n if (isDebug()) {\n console.error(chalk.gray(\"Failed to create .reygent:\"), err);\n }\n }\n }\n }\n\n // Initialize telemetry backend only if enabled\n if (telemetryEnabled) {\n try {\n const retentionDays = config.telemetry?.retention ?? 30;\n chesstrace = getChesstrace({ level: telemetryLevel, retentionDays });\n\n // Use dual backend if in project, otherwise global\n const backend = projectRoot\n ? new DualBackend(projectRoot)\n : new SqliteBackend('global');\n\n await chesstrace.init(backend);\n await chesstrace.startRun();\n\n // Show message if created .reygent/ for first time\n if (createdReygentDir) {\n console.log(chalk.green(\"✓\"), chalk.gray(\"Created .reygent/ for local knowledge learning\"));\n console.log(\"\");\n }\n } catch (err) {\n // Telemetry init failed - continue without telemetry\n if (isDebug()) {\n console.error(chalk.gray(\"Telemetry init failed:\"), err);\n }\n chesstrace = null;\n }\n }\n\n const commandStartTime = Date.now();\n\n try {\n let specSource = options.spec;\n if (!specSource) {\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"--spec is required in non-interactive environments.\");\n await chesstrace?.close();\n process.exit(1);\n }\n specSource = await promptForSpec();\n }\n const spec = await loadSpec(specSource);\n\n // Skip telemetry in dry-run mode\n if (options.dryRun) {\n console.log(chalk.yellow.bold(\"[dry-run]\"), \"No changes will be made.\\n\");\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Specification\"));\n console.log(chalk.cyan(\"│\"), chalk.bold(spec.title));\n console.log(chalk.cyan(\"│\"), chalk.gray(`source: ${spec.source}`));\n console.log(chalk.cyan(\"└─\"));\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Workflow Stages\"));\n\n for (let i = 0; i < PIPELINE.length; i++) {\n const stage = PIPELINE[i];\n const isLast = i === PIPELINE.length - 1;\n const prefix = isLast ? \"└─\" : \"├─\";\n const continuation = isLast ? \" \" : \"│ \";\n\n console.log(chalk.cyan(prefix), chalk.bold.white(stage.name));\n console.log(chalk.cyan(continuation), chalk.gray(stage.description));\n\n // Format execution details\n let execInfo = \"\";\n if (stage.execution.kind === \"agent\") {\n execInfo = chalk.blue(`agent: ${stage.execution.agent}`);\n } else if (stage.execution.kind === \"parallel\") {\n execInfo = chalk.magenta(`parallel: ${stage.execution.agents.join(\", \")}`);\n } else if (stage.execution.kind === \"gate\") {\n execInfo = chalk.yellow(`gate: ${stage.execution.condition} (${stage.execution.agent})`);\n }\n\n console.log(chalk.cyan(continuation), execInfo);\n\n if (!isLast) {\n console.log(chalk.cyan(\"│\"));\n }\n }\n\n console.log(\"\");\n return;\n }\n\n // Emit COMMAND_START after dry-run check\n if (chesstrace) {\n try { chesstrace.emit(Events.COMMAND_START, { command: 'run' }); } catch { /* swallow */ }\n }\n\n // Initialize context after dry-run check\n context = { spec, results: [] };\n\n const threshold = options.securityThreshold.toUpperCase();\n if (!VALID_SEVERITIES.has(threshold)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid --security-threshold \"${options.securityThreshold}\". Must be one of: CRITICAL, HIGH, MEDIUM, LOW`);\n process.exit(1);\n }\n\n // Prompt for permission mode if not specified\n let autoApprove = options.autoApprove;\n if (!autoApprove) {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n \"\\nAgents will write files and run commands. Auto-approve all actions? (y/n) \",\n resolve,\n );\n });\n rl.close();\n\n autoApprove = answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n console.log(\"\");\n }\n\n // Prompt for clarification preference if not specified\n let skipClarification = options.skipClarification;\n if (!skipClarification && !options.dryRun) {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n \"Skip clarifying questions and make assumptions? (y/n) \",\n resolve,\n );\n });\n rl.close();\n\n skipClarification = answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n console.log(\"\");\n }\n\n const maxRetries = Math.max(0, parseInt(options.maxRetries, 10) || 0);\n\n const agentOptions = { autoApprove };\n\n // Emit pipeline.start\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_START, {\n spec: {\n source: spec.source,\n title: spec.title,\n },\n options: {\n autoApprove,\n skipClarification,\n maxRetries,\n securityThreshold: options.securityThreshold,\n insecure: options.insecure,\n },\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n for (const stage of PIPELINE) {\n const stageStartTime = Date.now();\n const toolTracker = createToolTracker();\n\n // Emit pipeline.stage.start\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_STAGE_START, {\n stage: stage.name,\n description: stage.description,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n if (stage.name === \"plan\") {\n const status = createLiveStatus(\"running planner...\");\n\n let plan: PlannerOutput | null = null;\n\n if (skipClarification) {\n // Skip clarification, make assumptions\n const { result, usage: planUsage } = await runPlanner(\n context.spec,\n undefined,\n { makeAssumptions: true, ...withActivity(agentOptions, status, toolTracker) },\n );\n if (\"needsClarification\" in result && result.needsClarification) {\n status.fail(chalk.red(\"Planner asked questions despite skip flag\"));\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Planner: unexpected clarification request in assumption mode\",\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Planner: unexpected clarification request in assumption mode\");\n }\n plan = result as PlannerOutput;\n if (planUsage) tracker.record(\"planner\", \"plan\", planUsage);\n } else {\n // Run clarification loop\n let clarificationAnswers = \"\";\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!plan && attempts < maxAttempts) {\n attempts++;\n const { result, usage: planUsage } = await runPlanner(\n context.spec,\n clarificationAnswers,\n withActivity(agentOptions, status, toolTracker),\n );\n if (planUsage) tracker.record(\"planner\", \"plan\", planUsage);\n\n if (\"needsClarification\" in result && result.needsClarification) {\n status.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\nPlanner needs clarification:\\n\"));\n\n const answers: string[] = [];\n\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n console.log(` [${i + 1}/${result.questions.length}] ${question}`);\n resetTerminalForInput();\n const answer = await pasteableInput({ message: \">\" });\n\n if (answer.toLowerCase() === \"abort\" || answer.toLowerCase() === \"cancel\") {\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Planner: clarification aborted by user\",\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Planner: clarification aborted by user\");\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n }\n clarificationAnswers = answers.join(\"\\n\\n\");\n console.log(chalk.blue(\"\\nRe-running planner with clarifications...\\n\"));\n status.start();\n } else {\n plan = result as PlannerOutput;\n }\n }\n\n if (!plan) {\n status.fail(chalk.red(\"Planner failed\"));\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `Planner: failed to create valid plan after ${maxAttempts} attempts`,\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\n `Planner: failed to create valid plan after ${maxAttempts} attempts`,\n );\n }\n }\n\n status.succeed(chalk.green(\"Plan created\"));\n context.plan = plan;\n\n const cols = process.stdout.columns || 80;\n console.log(chalk.cyan(\"\\nGoals:\"));\n for (const g of plan.goals) console.log(` ${chalk.gray(\"-\")} ${wrapText(g, 4, cols)}`);\n console.log(chalk.cyan(\"\\nTasks:\"));\n for (const t of plan.tasks) console.log(` ${chalk.gray(\"-\")} ${wrapText(t, 4, cols)}`);\n console.log(chalk.cyan(\"\\nConstraints:\"));\n for (const c of plan.constraints) console.log(` ${chalk.gray(\"-\")} ${wrapText(c, 4, cols)}`);\n console.log(chalk.cyan(\"\\nDefinition of Done:\"));\n for (const d of plan.dod) console.log(` ${chalk.gray(\"-\")} ${wrapText(d, 4, cols)}`);\n console.log();\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(plan),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"implement\") {\n if (!context.plan) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Implement: plan stage must run before implement\",\n stage: \"implement\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Implement: plan stage must run before implement\");\n }\n\n const implStatus = createLiveStatus(\"spawning dev and qe agents...\");\n const { implement: impl, usages: implUsages } = await runImplement(\n context.spec,\n context.plan,\n withActivity(agentOptions, implStatus, toolTracker),\n );\n context.implement = impl;\n\n for (const u of implUsages) {\n if (u.usage) tracker.record(u.agent, \"implement\", u.usage);\n }\n\n let devSuccess = impl.dev !== null;\n let qeSuccess = impl.qe !== null;\n\n if (devSuccess && qeSuccess) {\n implStatus.succeed(chalk.green(\"Implementation complete\"));\n } else {\n implStatus.warn(chalk.yellow(\"Implementation partially failed\"));\n }\n\n if (impl.dev) {\n console.log(chalk.gray(\"dev files:\"), impl.dev.files.join(\", \") || chalk.gray(\"(none)\"));\n }\n if (impl.qe) {\n console.log(chalk.gray(\"qe test files:\"), impl.qe.testFiles.join(\", \") || chalk.gray(\"(none)\"));\n }\n\n // Retry loop for failed agents\n let attempt = 0;\n while (!devSuccess || !qeSuccess) {\n attempt++;\n\n const failedAgents = [\n !devSuccess ? \"dev\" : null,\n !qeSuccess ? \"qe\" : null,\n ].filter(Boolean).join(\", \");\n\n // Check if exceeded max retries or prompt user\n await promptForRetry({\n taskName: `${failedAgents} agent(s)`,\n attempt,\n maxRetries,\n autoApprove,\n telemetry: {\n stageName: stage.name,\n agentName: !devSuccess ? \"dev\" : \"qe\",\n },\n });\n\n // Determine which agents to retry\n const agentsToRetry: Array<\"dev\" | \"qe\"> = [];\n if (!devSuccess) agentsToRetry.push(\"dev\");\n if (!qeSuccess) agentsToRetry.push(\"qe\");\n\n const attemptDisplay = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n console.log(chalk.yellow(`\\nRetrying ${agentsToRetry.join(\" + \")} agent(s) (attempt ${attemptDisplay})...`));\n\n const retryStatus = createLiveStatus(`re-running ${agentsToRetry.join(\" + \")} agent(s)...`);\n try {\n const { implement: retryImpl, usages: retryUsages } = await runImplement(\n context.spec,\n context.plan,\n withActivity(agentOptions, retryStatus, toolTracker),\n { agentsToRun: agentsToRetry },\n );\n\n for (const u of retryUsages) {\n if (u.usage) tracker.record(u.agent, `${stage.name}-retry`, u.usage);\n }\n\n // Merge results\n if (retryImpl.dev && !devSuccess) {\n context.implement!.dev = retryImpl.dev;\n devSuccess = true;\n }\n if (retryImpl.qe && !qeSuccess) {\n context.implement!.qe = retryImpl.qe;\n qeSuccess = true;\n }\n\n if (devSuccess && qeSuccess) {\n retryStatus.succeed(chalk.green(\"Implementation complete on retry\"));\n if (context.implement!.dev) {\n console.log(chalk.gray(\"dev files:\"), context.implement!.dev.files.join(\", \") || chalk.gray(\"(none)\"));\n }\n if (context.implement!.qe) {\n console.log(chalk.gray(\"qe test files:\"), context.implement!.qe.testFiles.join(\", \") || chalk.gray(\"(none)\"));\n }\n } else {\n retryStatus.warn(chalk.yellow(`Retry ${attempt} partially failed`));\n }\n } catch {\n retryStatus.fail(chalk.red(`Retry ${attempt} failed`));\n }\n }\n\n context.results.push({\n stage: stage.name,\n success: devSuccess && qeSuccess,\n output: JSON.stringify(context.implement),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, devSuccess && qeSuccess, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"gate-unit-tests\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"gate-unit-tests: implement stage must run first\",\n stage: \"gate-unit-tests\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"gate-unit-tests: implement stage must run first\");\n }\n\n const unitStatus = createLiveStatus(\"running unit tests...\");\n const { gate: unitGateResult, usage: unitGateUsage } = await runUnitTestGate(\n context,\n { ...withActivity(agentOptions, unitStatus, toolTracker), attempt: 1, verbose: options.verbose },\n );\n let gateResult = unitGateResult;\n\n if (unitGateUsage) tracker.record(\"gate:unit-tests\", stage.name, unitGateUsage);\n\n if (!context.gates) context.gates = {};\n context.gates.unitTests = gateResult;\n\n if (gateResult.passed) {\n unitStatus.succeed(chalk.green(\"Unit tests PASSED\"));\n context.results.push({\n stage: stage.name,\n success: true,\n output: gateResult.output,\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n unitStatus.fail(chalk.red(\"Unit tests FAILED\"));\n\n // Retry loop — dev agent only for unit test failures\n try {\n gateResult = await retryGate({\n gateName: \"unit tests\",\n gateRunner: (attempt) => runUnitTestGate(context, { ...agentOptions, attempt, verbose: options.verbose }),\n agentsToRun: [\"dev\"],\n context,\n agentOptions,\n maxRetries,\n autoApprove,\n stageName: stage.name,\n tracker,\n verbose: options.verbose,\n toolTracker,\n });\n } catch (err) {\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n throw err;\n }\n\n context.results.push({\n stage: stage.name,\n success: gateResult.passed,\n output: gateResult.output,\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, gateResult.passed, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"gate-functional-tests\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"gate-functional-tests: implement stage must run first\",\n stage: \"gate-functional-tests\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"gate-functional-tests: implement stage must run first\");\n }\n\n const funcStatus = createLiveStatus(\"running functional tests...\");\n const { gate: funcGateResult, usage: funcGateUsage } = await runFunctionalTestGate(\n context,\n { ...withActivity(agentOptions, funcStatus, toolTracker), attempt: 1, verbose: options.verbose },\n );\n let gateResult = funcGateResult;\n\n if (funcGateUsage) tracker.record(\"gate:functional-tests\", stage.name, funcGateUsage);\n\n if (!context.gates) context.gates = {};\n context.gates.functionalTests = gateResult;\n\n if (gateResult.passed) {\n funcStatus.succeed(chalk.green(\"Functional tests PASSED\"));\n context.results.push({\n stage: stage.name,\n success: true,\n output: gateResult.output,\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n funcStatus.fail(chalk.red(\"Functional tests FAILED\"));\n console.log(gateResult.output);\n\n // Retry loop — both dev + qe agents for functional test failures\n try {\n gateResult = await retryGate({\n gateName: \"functional tests\",\n gateRunner: (attempt) => runFunctionalTestGate(context, { ...agentOptions, attempt, verbose: options.verbose }),\n agentsToRun: [\"dev\", \"qe\"],\n context,\n agentOptions,\n maxRetries,\n autoApprove,\n stageName: stage.name,\n tracker,\n verbose: options.verbose,\n toolTracker,\n });\n } catch (err) {\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n throw err;\n }\n\n context.results.push({\n stage: stage.name,\n success: gateResult.passed,\n output: gateResult.output,\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, gateResult.passed, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"security-review\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"security-review: implement stage must run first\",\n stage: \"security-review\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"security-review: implement stage must run first\");\n }\n\n const secStatus = createLiveStatus(\"running security review...\");\n const { output, passed, usage: secUsage } = await runSecurityReview(\n context,\n threshold as Severity,\n withActivity(agentOptions, secStatus, toolTracker),\n );\n if (secUsage) tracker.record(\"security-review\", stage.name, secUsage);\n context.securityReview = output;\n\n if (passed) {\n secStatus.succeed(chalk.green(\"Security review PASSED\"));\n } else {\n secStatus.fail(chalk.red(\"Security review FAILED\"));\n }\n\n console.log(\"\");\n console.log(chalk.cyan.bold(`Security Findings (${output.findings.length}):`));\n console.log(formatFindings(output.findings, threshold as Severity));\n console.log(\"\");\n\n if (passed) {\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(output),\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n console.log(chalk.yellow(`Findings at or above ${threshold} threshold`));\n context.results.push({\n stage: stage.name,\n success: false,\n output: JSON.stringify(output),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n\n if (autoApprove) {\n console.log(chalk.yellow(\"Auto-approved — bypassing security gate...\"));\n } else {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(\"\\nSecurity review failed. Continue with PR creation anyway? (y/n) \"),\n resolve,\n );\n });\n rl.close();\n\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n console.log(chalk.red(\"Aborted by user.\"));\n process.exit(1);\n }\n\n console.log(chalk.yellow(\"Bypassed by user — continuing...\"));\n }\n continue;\n }\n\n if (stage.name === \"pr-create\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"pr-create: implement stage must run first\",\n stage: \"pr-create\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"pr-create: implement stage must run first\");\n }\n\n // Determine branch type\n let branchType: BranchType;\n\n // Check if --type flag was provided\n if (options.type) {\n // Validation already done in CLI hook, just normalize\n branchType = normalizeType(options.type);\n } else {\n // Try auto-detection from issue type\n let autoDetected: BranchType | null = null;\n\n if (context.spec.source === \"jira\" && context.spec.issueType) {\n autoDetected = detectTypeFromJiraIssueType(context.spec.issueType);\n } else if (context.spec.source === \"linear\" && \"labels\" in context.spec && context.spec.labels) {\n autoDetected = detectTypeFromLinearLabels(context.spec.labels);\n }\n\n if (autoDetected) {\n // Issue type detected - use it without prompting\n branchType = autoDetected;\n } else {\n // No auto-detection - prompt user\n resetTerminalForInput();\n branchType = await select({\n message: \"Select branch type:\",\n choices: VALID_BRANCH_TYPES.map(t => ({ name: t, value: t })),\n }) as BranchType;\n }\n }\n\n const spinner = ora(chalk.blue(\"creating pull request...\")).start();\n const prResult = await runPRCreate(context, { insecure: options.insecure, branchType });\n context.prCreate = prResult;\n spinner.succeed(chalk.green(\"PR created\"));\n\n console.log(chalk.gray(\"branch:\"), chalk.cyan(prResult.branch));\n console.log(chalk.gray(\"PR:\"), chalk.blue(prResult.prUrl));\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(prResult),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"pr-review\") {\n const prStatus = createLiveStatus(\"reviewing pull request...\");\n const { output: reviewOutput, usage: prUsage } = await runPRReview(\n context,\n withActivity(agentOptions, prStatus, toolTracker),\n );\n context.prReview = reviewOutput;\n if (prUsage) tracker.record(\"pr-review\", stage.name, prUsage);\n prStatus.succeed(chalk.green(\"PR review complete\"));\n\n console.log(formatPRReviewTerminal(reviewOutput));\n\n const commentSpinner = ora(chalk.blue(\"posting review comment to PR...\")).start();\n try {\n await postPRReviewComment(context, reviewOutput);\n commentSpinner.succeed(chalk.green(\"Review posted to PR\"));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n commentSpinner.fail(chalk.yellow(`Could not post review to PR: ${msg}`));\n }\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(reviewOutput),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n const result: StageResult = {\n stage: stage.name,\n success: true,\n output: \"skipped\",\n };\n console.log(chalk.gray(`[${stage.name}] skipped`));\n context.results.push(result);\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n }\n\n // Emit pipeline.end\n const allSuccess = context.results.every((r) => r.success);\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_END, {\n success: allSuccess,\n totalDurationMs: Date.now() - pipelineStartTime,\n totalCost: tracker.getTotalCost(),\n });\n } catch {\n // Swallow emit errors\n }\n\n // Emit COMMAND_END on success\n try {\n chesstrace.emit(Events.COMMAND_END, {\n command: 'run',\n success: allSuccess,\n durationMs: Date.now() - commandStartTime,\n });\n } catch {\n // Swallow emit errors\n }\n\n // Flush and close telemetry\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n\n // Update knowledge base from telemetry\n await updateKnowledgeFromTelemetry();\n\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n\n // Print usage summary after pipeline completes\n printUsageSummary(tracker);\n if (options.verbose) {\n printVerboseUsage(tracker);\n }\n } catch (err) {\n // Emit error.task telemetry for TaskError\n if (chesstrace && err instanceof TaskError) {\n try {\n // Extract stage from context if available\n const stage = context?.results[context.results.length - 1]?.stage ?? \"unknown\";\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: err.message,\n stage,\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n // Emit COMMAND_ERROR + pipeline.end with failure status\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_ERROR, {\n command: 'run',\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - commandStartTime,\n });\n } catch {\n // Swallow emit errors\n }\n\n try {\n if (context) {\n chesstrace.emit(Events.PIPELINE_END, {\n success: false,\n totalDurationMs: Date.now() - pipelineStartTime,\n totalCost: tracker?.getTotalCost() ?? 0,\n });\n }\n } catch {\n // Swallow emit errors\n }\n\n // Flush and close telemetry even on error\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n\n // Update knowledge base from telemetry\n await updateKnowledgeFromTelemetry();\n\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n\n // In test env, re-throw instead of process.exit to allow test assertions.\n // We check runtime environment variables (NODE_ENV, VITEST) rather than import.meta.env\n // because test runners set these at runtime, not during bundling. See src/test-env.ts.\n const isTest = isTestEnvironment();\n\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n if (isTest) throw err;\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n if (isTest) throw err;\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n if (isTest) throw err;\n process.exit(2);\n }\n}\n","import chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport type { SpawnResult } from \"./spawn.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type {\n PlannerOutput,\n DevOutput,\n QEOutput,\n ImplementOutput,\n} from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport type { SpawnResult };\n\n/**\n * Extract head and tail of agent output for error display.\n *\n * For long outputs, shows first 150 and last 150 characters to capture\n * both the initial error context and the final failure message.\n * In debug mode, full output is already printed, so this is for quick\n * terminal feedback during normal operation.\n */\nfunction getFailureSummary(stdout: string, maxLen = 300): string {\n const trimmed = stdout.trim();\n if (!trimmed) return \"\";\n if (trimmed.length <= maxLen) return trimmed;\n\n // Show head + tail for better context\n const halfLen = Math.floor(maxLen / 2);\n const head = trimmed.slice(0, halfLen);\n const tail = trimmed.slice(-halfLen);\n return `${head}…${tail}`;\n}\n\nconst AGENT_TIMEOUT_MS = 15 * 60 * 1000;\n\n/**\n * Options for spawning agents via spawnAgent() wrapper.\n * This interface mirrors SpawnOptions from spawn.ts and adds semantic clarity\n * for callers in the implement module. Changes to SpawnOptions should be\n * reflected here to maintain compatibility.\n */\nexport interface AgentSpawnOptions {\n autoApprove?: boolean;\n quiet?: boolean;\n provider?: string;\n model?: string;\n onActivity?: (event: ActivityEvent) => void;\n stage?: string;\n}\n\nexport interface FailureContext {\n gateName: string;\n testOutput: string;\n attempt: number;\n maxAttempts: number;\n}\n\nexport interface RetryOptions {\n failureContext?: FailureContext;\n agentsToRun?: Array<\"dev\" | \"qe\">;\n}\n\nexport function spawnAgent(\n name: string,\n prompt: string,\n options?: AgentSpawnOptions,\n): Promise<SpawnResult> {\n return spawnAgentStream(name, prompt, AGENT_TIMEOUT_MS, options);\n}\n\nfunction buildRetrySection(failureContext: FailureContext): string {\n return `\n\n---\n\n## RETRY (attempt ${failureContext.attempt}/${failureContext.maxAttempts})\n\nThe previous implementation failed the **${failureContext.gateName}** gate. Review the test output below, identify what went wrong, and fix the issues.\n\n**Test output:**\n\\`\\`\\`\n${failureContext.testOutput}\n\\`\\`\\`\n\nFocus on fixing the failures above. Do not rewrite code that already works.`;\n}\n\nfunction buildDevPrompt(\n systemPrompt: string,\n spec: SpecPayload,\n plan: PlannerOutput,\n failureContext?: FailureContext,\n): string {\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}\n\n---\n\nWhen you are finished, output a JSON block with the list of files you created or modified:\n\n\\`\\`\\`json\n{ \"files\": [\"src/example.ts\", \"src/example.test.ts\"] }\n\\`\\`\\``;\n\n if (failureContext) {\n prompt += buildRetrySection(failureContext);\n }\n\n return prompt;\n}\n\nfunction buildQEPrompt(\n systemPrompt: string,\n spec: SpecPayload,\n plan: PlannerOutput,\n failureContext?: FailureContext,\n): string {\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}\n\n---\n\nWhen you are finished, output a JSON block with the list of test files you created or modified:\n\n\\`\\`\\`json\n{ \"testFiles\": [\"tests/example.test.ts\"] }\n\\`\\`\\``;\n\n if (failureContext) {\n prompt += buildRetrySection(failureContext);\n }\n\n return prompt;\n}\n\nfunction extractDevOutput(stdout: string): DevOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(/\\{\\s*\"files\"\\s*:\\s*\\[.*?\\]\\s*\\}/s);\n if (match) {\n try {\n const parsed = JSON.parse(match[0]) as { files: unknown };\n if (Array.isArray(parsed.files)) {\n return { files: parsed.files.filter((f) => typeof f === \"string\") };\n }\n } catch (err) {\n // Emit error.parse before falling through\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"dev\",\n expectedFormat: '{ \"files\": [\"...\"] }',\n received: match[0].slice(0, 500),\n });\n }\n // fall through\n }\n }\n return { files: [] };\n}\n\nfunction extractQEOutput(stdout: string): QEOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(/\\{\\s*\"testFiles\"\\s*:\\s*\\[.*?\\]\\s*\\}/s);\n if (match) {\n try {\n const parsed = JSON.parse(match[0]) as { testFiles: unknown };\n if (Array.isArray(parsed.testFiles)) {\n return {\n testFiles: parsed.testFiles.filter((f) => typeof f === \"string\"),\n };\n }\n } catch (err) {\n // Emit error.parse before falling through\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"qe\",\n expectedFormat: '{ \"testFiles\": [\"...\"] }',\n received: match[0].slice(0, 500),\n });\n }\n // fall through\n }\n }\n return { testFiles: [] };\n}\n\nexport interface ImplementResult {\n implement: ImplementOutput;\n usages: Array<{ agent: string; usage?: UsageInfo }>;\n}\n\nexport async function runImplement(\n spec: SpecPayload,\n plan: PlannerOutput,\n options?: AgentSpawnOptions,\n retryOptions?: RetryOptions,\n): Promise<ImplementResult> {\n const agents = getAgents();\n const devAgent = agents.find((a) => a.name === \"dev\");\n const qeAgent = agents.find((a) => a.name === \"qe\");\n\n if (!devAgent || !qeAgent) {\n emitErrorTask(\n \"Implement: missing dev or qe agent config\",\n options?.stage ?? \"implement\",\n { agent: \"implement\" },\n );\n throw new TaskError(\"Implement: missing dev or qe agent config\");\n }\n\n const agentsToRun = retryOptions?.agentsToRun ?? [\"dev\", \"qe\"];\n const failureContext = retryOptions?.failureContext;\n\n const runDev = agentsToRun.includes(\"dev\");\n const runQE = agentsToRun.includes(\"qe\");\n\n const devPrompt = runDev\n ? buildDevPrompt(devAgent.systemPrompt, spec, plan, failureContext)\n : \"\";\n const qePrompt = runQE\n ? buildQEPrompt(qeAgent.systemPrompt, spec, plan, failureContext)\n : \"\";\n\n let dev: DevOutput | null = null;\n let qe: QEOutput | null = null;\n const usages: Array<{ agent: string; usage?: UsageInfo }> = [];\n\n if (options?.autoApprove) {\n // Parallel: no stdin needed\n const promises: Promise<PromiseSettledResult<SpawnResult>>[] = [];\n\n if (runDev) {\n promises.push(\n spawnAgent(\"dev\", devPrompt, { ...options, provider: devAgent.provider, model: devAgent.model, stage: \"implement\" }).then(\n (v) => ({ status: \"fulfilled\" as const, value: v }),\n (e) => ({ status: \"rejected\" as const, reason: e }),\n ),\n );\n }\n if (runQE) {\n promises.push(\n spawnAgent(\"qe\", qePrompt, { ...options, provider: qeAgent.provider, model: qeAgent.model, stage: \"implement\" }).then(\n (v) => ({ status: \"fulfilled\" as const, value: v }),\n (e) => ({ status: \"rejected\" as const, reason: e }),\n ),\n );\n }\n\n const results = await Promise.all(promises);\n let idx = 0;\n\n if (runDev) {\n const devResult = results[idx++];\n if (devResult.status === \"fulfilled\") {\n usages.push({ agent: \"dev\", usage: devResult.value.usage });\n if (devResult.value.exitCode === 0) {\n dev = extractDevOutput(devResult.value.stdout);\n } else {\n const detail = formatExitDetail(devResult.value, devAgent.model);\n console.log(chalk.red(\"dev agent failed:\"), `exit code ${devResult.value.exitCode}${detail}`);\n // Show stdout context when errorMessage is terse (< 50 chars) or missing\n if (!devResult.value.errorMessage || (devResult.value.errorMessage.length < 50)) {\n const summary = getFailureSummary(devResult.value.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } else {\n console.log(chalk.red(\"dev agent failed:\"), devResult.reason);\n }\n }\n\n if (runQE) {\n const qeResult = results[idx++];\n if (qeResult.status === \"fulfilled\") {\n usages.push({ agent: \"qe\", usage: qeResult.value.usage });\n if (qeResult.value.exitCode === 0) {\n qe = extractQEOutput(qeResult.value.stdout);\n } else {\n const detail = formatExitDetail(qeResult.value, qeAgent.model);\n console.log(chalk.red(\"qe agent failed:\"), `exit code ${qeResult.value.exitCode}${detail}`);\n // Show stdout context when errorMessage is terse (< 50 chars) or missing\n if (!qeResult.value.errorMessage || (qeResult.value.errorMessage.length < 50)) {\n const summary = getFailureSummary(qeResult.value.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } else {\n console.log(chalk.red(\"qe agent failed:\"), qeResult.reason);\n }\n }\n } else {\n // Sequential: stdin inherited so user can approve each edit\n if (runDev) {\n console.log(chalk.blue(\"Running dev agent (approve edits as prompted)...\"));\n try {\n const devResult = await spawnAgent(\"dev\", devPrompt, { ...options, provider: devAgent.provider, model: devAgent.model, stage: \"implement\" });\n if (devResult.exitCode === 0) {\n dev = extractDevOutput(devResult.stdout);\n }\n usages.push({ agent: \"dev\", usage: devResult.usage });\n if (devResult.exitCode !== 0) {\n const detail = formatExitDetail(devResult);\n console.log(chalk.red(\"dev agent failed:\"), `exit code ${devResult.exitCode}${detail}`);\n if (!devResult.errorMessage) {\n const summary = getFailureSummary(devResult.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } catch (err) {\n console.log(chalk.red(\"dev agent failed:\"), err);\n }\n }\n\n if (runQE) {\n console.log(chalk.blue(\"Running qe agent (approve edits as prompted)...\"));\n try {\n const qeResult = await spawnAgent(\"qe\", qePrompt, { ...options, provider: qeAgent.provider, model: qeAgent.model, stage: \"implement\" });\n if (qeResult.exitCode === 0) {\n qe = extractQEOutput(qeResult.stdout);\n }\n usages.push({ agent: \"qe\", usage: qeResult.usage });\n if (qeResult.exitCode !== 0) {\n const detail = formatExitDetail(qeResult);\n console.log(chalk.red(\"qe agent failed:\"), `exit code ${qeResult.exitCode}${detail}`);\n if (!qeResult.errorMessage) {\n const summary = getFailureSummary(qeResult.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } catch (err) {\n console.log(chalk.red(\"qe agent failed:\"), err);\n }\n }\n }\n\n // Only fail if both requested agents failed\n const chesstrace = getChesstrace();\n if ((runDev && dev === null) && (runQE && qe === null)) {\n emitErrorTask(\n \"Implement: all requested agents failed\",\n options?.stage ?? \"implement\",\n { agent: \"implement\" },\n );\n throw new TaskError(\"Implement: all requested agents failed\");\n }\n if (runDev && !runQE && dev === null) {\n emitErrorTask(\n \"Implement: dev agent failed\",\n options?.stage ?? \"implement\",\n { agent: \"dev\" },\n );\n throw new TaskError(\"Implement: dev agent failed\");\n }\n if (!runDev && runQE && qe === null) {\n emitErrorTask(\n \"Implement: qe agent failed\",\n options?.stage ?? \"implement\",\n { agent: \"qe\" },\n );\n throw new TaskError(\"Implement: qe agent failed\");\n }\n\n return { implement: { dev, qe }, usages };\n}\n","import { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { TaskError } from \"./task.js\";\nimport type { GateResult, TaskContext } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\n/* ------------------------------------------------------------------ */\n/* Shared gate utility */\n/* ------------------------------------------------------------------ */\n\nexport async function runGate(\n agentName: string,\n prompt: string,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n const result = await spawnAgent(agentName, prompt, options);\n\n const hasPass = result.stdout.includes(\"GATE_RESULT:PASS\");\n const hasFail = result.stdout.includes(\"GATE_RESULT:FAIL\");\n\n const passed = result.exitCode === 0 && hasPass && !hasFail;\n\n // Emit gate.result telemetry\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.GATE_RESULT, {\n gateName: agentName,\n passed,\n attempt: options?.attempt ?? 1,\n });\n } catch (err) {\n if (options?.verbose) {\n console.error(\"[telemetry]\", err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n return { gate: { passed, output: result.stdout }, usage: result.usage };\n}\n\n/* ------------------------------------------------------------------ */\n/* Unit-tests gate */\n/* ------------------------------------------------------------------ */\n\nfunction buildUnitTestGatePrompt(context: TaskContext): string {\n const files = context.implement!.dev!.files;\n const filesList = files.length > 0\n ? files.map((f) => `- ${f}`).join(\"\\n\")\n : \"(no new files — dev agent found work already complete)\";\n\n return `You are in **test-execution mode**.\n\n## Rules\n- DO NOT write or modify any source code or test code.\n- Your ONLY job is to find the project's test runner and execute the unit tests.\n\n## Files written by the Dev agent\n${filesList}\n\n## Instructions\n1. Identify the test runner used by this project (e.g. vitest, jest, mocha, npm test).\n2. Run the unit tests. Stream the full output.\n3. After the test run completes, emit exactly one of the following as the **last line** of your output:\n - \\`GATE_RESULT:PASS\\` — if ALL unit tests passed\n - \\`GATE_RESULT:FAIL\\` — if ANY unit test failed or the runner returned a non-zero exit code\n\nDo NOT emit both markers. Do NOT omit the marker.`;\n}\n\nexport async function runUnitTestGate(\n context: TaskContext,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n if (!context.implement) {\n throw new TaskError(\n \"gate:unit-tests: implement stage has not run\",\n );\n }\n\n if (!context.implement.dev) {\n throw new TaskError(\n \"gate:unit-tests: dev output is null — dev agent failed during implement\",\n );\n }\n\n const prompt = buildUnitTestGatePrompt(context);\n return runGate(\"gate:unit-tests\", prompt, options);\n}\n\n/* ------------------------------------------------------------------ */\n/* Functional-tests gate */\n/* ------------------------------------------------------------------ */\n\nfunction buildFunctionalTestGatePrompt(context: TaskContext): string {\n const testFiles = context.implement!.qe!.testFiles;\n const filesList = testFiles.length > 0\n ? testFiles.map((f) => `- ${f}`).join(\"\\n\")\n : \"(no new test files — qe agent found tests already complete)\";\n\n return `You are in **test-execution mode**.\n\n## Rules\n- DO NOT write or modify any source code or test code.\n- Your ONLY job is to find the project's test runner and execute the functional tests.\n\n## Test files written by the QE agent\n${filesList}\n\n## Instructions\n1. Identify the test runner used by this project (e.g. vitest, jest, mocha, npm test).\n2. Run the functional tests${testFiles.length > 0 ? \" listed above\" : \"\"}. Stream the full output.\n3. After the test run completes, emit exactly one of the following as the **last line** of your output:\n - \\`GATE_RESULT:PASS\\` — if ALL functional tests passed\n - \\`GATE_RESULT:FAIL\\` — if ANY functional test failed or the runner returned a non-zero exit code\n\nDo NOT emit both markers. Do NOT omit the marker.`;\n}\n\nexport async function runFunctionalTestGate(\n context: TaskContext,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n if (!context.implement) {\n throw new TaskError(\n \"gate:functional-tests: implement stage has not run\",\n );\n }\n\n if (!context.implement.qe) {\n throw new TaskError(\n \"gate:functional-tests: qe output is null — qe agent failed during implement\",\n );\n }\n\n const prompt = buildFunctionalTestGatePrompt(context);\n return runGate(\"gate:functional-tests\", prompt, options);\n}\n","import { execFile } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { request as httpsRequest } from \"node:https\";\nimport { rootCertificates } from \"node:tls\";\nimport { loadEnvFile } from \"./env.js\";\nimport type { BranchType as CanonicalBranchType } from \"./branch-type.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type { PRCreateOutput, TaskContext } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nfunction exec(\n cmd: string,\n args: string[],\n opts?: { timeout?: number },\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { timeout: opts?.timeout, maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `pr-create: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve({ stdout, stderr });\n },\n );\n });\n}\n\nexport type Platform = \"github\" | \"gitlab\";\n\nexport interface RemoteInfo {\n platform: Platform;\n host: string;\n owner: string;\n repo: string;\n}\n\nexport async function resolveToken(host: string): Promise<string> {\n const { execFile: execFileCb } = await import(\"node:child_process\");\n return new Promise((resolve, reject) => {\n const child = execFileCb(\n \"git\",\n [\"credential\", \"fill\"],\n { maxBuffer: 1024 * 1024 },\n (error, stdout) => {\n if (error) {\n reject(\n new TaskError(\n `pr-create: failed to retrieve credentials for ${host} via git credential fill.\\n` +\n \"Configure a credential helper: https://git-scm.com/doc/credential-helpers\",\n ),\n );\n return;\n }\n const passwordLine = stdout\n .split(\"\\n\")\n .find((l) => l.startsWith(\"password=\"));\n if (!passwordLine) {\n reject(\n new TaskError(\n `pr-create: no password/token found from git credential fill for ${host}.`,\n ),\n );\n return;\n }\n resolve(passwordLine.slice(\"password=\".length).trim());\n },\n );\n child.stdin?.write(`protocol=https\\nhost=${host}\\n\\n`);\n child.stdin?.end();\n });\n}\n\nexport function parseRemote(remoteUrl: string): RemoteInfo {\n const url = remoteUrl.trim();\n\n // SSH: git@github.com:owner/repo.git\n const sshMatch = url.match(/^git@([^:]+):([^/]+)\\/([^/.]+?)(\\.git)?$/);\n if (sshMatch) {\n const host = sshMatch[1];\n const platform: Platform = host.includes(\"gitlab\") ? \"gitlab\" : \"github\";\n return { platform, host, owner: sshMatch[2], repo: sshMatch[3] };\n }\n\n // HTTPS: https://github.com/owner/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/([^/]+)\\/([^/]+)\\/([^/.]+?)(\\.git)?$/);\n if (httpsMatch) {\n const host = httpsMatch[1];\n const platform: Platform = host.includes(\"gitlab\") ? \"gitlab\" : \"github\";\n return { platform, host, owner: httpsMatch[2], repo: httpsMatch[3] };\n }\n\n throw new TaskError(`pr-create: cannot parse remote URL: ${url}`);\n}\n\nexport async function createPR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n if (opts.remote.platform === \"gitlab\") {\n return createGitLabMR(opts);\n }\n return createGitHubPR(opts);\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n ca?: string[];\n}\n\nasync function resolveTlsOptions(hostname?: string): Promise<TlsOptions> {\n // Respect GIT_SSL_NO_VERIFY env var\n if (process.env.GIT_SSL_NO_VERIFY) return { rejectUnauthorized: false };\n // Respect NODE_TLS_REJECT_UNAUTHORIZED if explicitly set\n if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === \"0\") return { rejectUnauthorized: false };\n\n const { execFile: ef } = await import(\"node:child_process\");\n const gitConfig = (args: string[]): Promise<string> =>\n new Promise((res, rej) => {\n ef(\"git\", args, {}, (err, stdout) => {\n if (err) rej(err);\n else res(stdout.trim());\n });\n });\n\n // Check if sslVerify is explicitly disabled\n const sslVerifyDisabled = await (async () => {\n if (hostname) {\n try {\n const v = await gitConfig([\n \"config\", \"--bool\", \"--get-urlmatch\", \"http.sslVerify\", `https://${hostname}/`,\n ]);\n if (v === \"false\") return true;\n } catch { /* fall through */ }\n }\n try {\n const v = await gitConfig([\"config\", \"--bool\", \"http.sslVerify\"]);\n if (v === \"false\") return true;\n } catch { /* not set */ }\n return false;\n })();\n\n if (sslVerifyDisabled) return { rejectUnauthorized: false };\n\n // Load custom CA bundle from git config (http.sslCAInfo)\n // This is how git trusts corporate/internal CAs\n const caPath = await (async () => {\n if (hostname) {\n try {\n return await gitConfig([\n \"config\", \"--get-urlmatch\", \"http.sslCAInfo\", `https://${hostname}/`,\n ]);\n } catch { /* fall through */ }\n }\n try {\n return await gitConfig([\"config\", \"http.sslCAInfo\"]);\n } catch { /* not set */ }\n return null;\n })();\n\n if (caPath) {\n try {\n const customCa = readFileSync(caPath, \"utf-8\");\n // Combine Node's default CAs with the custom bundle so both are trusted\n return { ca: [...rootCertificates, customCa] };\n } catch {\n // CA file unreadable — fall through to defaults\n }\n }\n\n return {};\n}\n\nfunction doHttpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n tlsOpts: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, \"utf-8\");\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"POST\",\n headers: { ...headers, \"Content-Length\": bodyBuf.byteLength },\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction isSslError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const code = (err as NodeJS.ErrnoException).code ?? \"\";\n return (\n code === \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\" ||\n code === \"DEPTH_ZERO_SELF_SIGNED_CERT\" ||\n code === \"SELF_SIGNED_CERT_IN_CHAIN\" ||\n code === \"ERR_TLS_CERT_ALTNAME_INVALID\" ||\n code === \"CERT_HAS_EXPIRED\" ||\n err.message.includes(\"self-signed\") ||\n err.message.includes(\"certificate\")\n );\n}\n\nasync function httpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n opts?: { insecure?: boolean },\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n const tlsOpts: TlsOptions = opts?.insecure\n ? { rejectUnauthorized: false }\n : await resolveTlsOptions(parsed.hostname);\n\n try {\n return await doHttpsPost(url, headers, body, tlsOpts);\n } catch (err) {\n if (!opts?.insecure && isSslError(err)) {\n return doHttpsPost(url, headers, body, { rejectUnauthorized: false });\n }\n throw err;\n }\n}\n\nasync function createGitHubPR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n const { host, owner, repo } = opts.remote;\n const apiBase =\n host === \"github.com\"\n ? \"https://api.github.com\"\n : `https://${host}/api/v3`;\n const body = JSON.stringify({\n title: opts.title,\n body: opts.body,\n head: opts.head,\n base: opts.base,\n });\n const { status, text } = await httpsPost(\n `${apiBase}/repos/${owner}/${repo}/pulls`,\n {\n Authorization: `Bearer ${opts.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"reygent\",\n },\n body,\n { insecure: opts.insecure },\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`pr-create: GitHub API error ${status}: ${text}`);\n }\n const data = JSON.parse(text) as { html_url: string; number: number };\n return { prUrl: data.html_url, prNumber: data.number };\n}\n\nasync function createGitLabMR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n const { host, owner, repo } = opts.remote;\n const projectPath = encodeURIComponent(`${owner}/${repo}`);\n const body = JSON.stringify({\n title: opts.title,\n description: opts.body,\n source_branch: opts.head,\n target_branch: opts.base,\n });\n const { status, text } = await httpsPost(\n `https://${host}/api/v4/projects/${projectPath}/merge_requests`,\n {\n Authorization: `Bearer ${opts.token}`,\n \"Content-Type\": \"application/json\",\n },\n body,\n { insecure: opts.insecure },\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`pr-create: GitLab API error ${status}: ${text}`);\n }\n const data = JSON.parse(text) as { web_url: string; iid: number };\n return { prUrl: data.web_url, prNumber: data.iid };\n}\n\n/**\n * @deprecated Import BranchType from branch-type.ts instead\n */\nexport type BranchType = \"feat\" | \"fix\" | \"chore\" | \"refactor\" | \"docs\" | \"test\" | \"style\" | \"perf\";\n\n/**\n * @deprecated Use detectTypeFromJiraIssueType or detectTypeFromLinearLabels from branch-type.ts instead\n */\nexport function mapIssueTypeToBranchType(issueType?: string): BranchType | null {\n if (!issueType) return null;\n\n const normalized = issueType.toLowerCase();\n\n // Map common issue type names to conventional prefixes\n if (normalized.includes(\"bug\") || normalized.includes(\"fix\")) return \"fix\";\n if (normalized.includes(\"feature\") || normalized.includes(\"story\") || normalized.includes(\"enhancement\")) return \"feat\";\n if (normalized.includes(\"chore\") || normalized.includes(\"task\")) return \"chore\";\n if (normalized.includes(\"refactor\")) return \"refactor\";\n if (normalized.includes(\"doc\")) return \"docs\";\n if (normalized.includes(\"test\")) return \"test\";\n if (normalized.includes(\"style\")) return \"style\";\n if (normalized.includes(\"perf\") || normalized.includes(\"performance\")) return \"perf\";\n\n return null;\n}\n\n/**\n * @deprecated Use deriveBranchNameWithType from branch-type.ts instead\n */\nexport function deriveBranchName(spec: SpecPayload, branchType: BranchType): string {\n switch (spec.source) {\n case \"jira\":\n return `${branchType}/${spec.issueKey}`;\n case \"linear\":\n return `${branchType}/${spec.issueId}`;\n case \"markdown\": {\n const slug = spec.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${branchType}/${slug}`;\n }\n }\n}\n\nexport function buildCommitMessage(context: TaskContext, branchType: CanonicalBranchType): string {\n const spec = context.spec;\n const plan = context.plan;\n\n let scope: string | null = null;\n switch (spec.source) {\n case \"jira\":\n scope = spec.issueKey;\n break;\n case \"linear\":\n scope = spec.issueId;\n break;\n case \"markdown\":\n scope = null;\n break;\n }\n\n const subject = scope\n ? `${branchType}(${scope}): ${spec.title}`\n : `${branchType}: ${spec.title}`;\n\n if (!plan) return subject;\n\n const lines = [subject, \"\"];\n if (plan.goals.length > 0) {\n lines.push(\"Goals:\");\n for (const g of plan.goals) lines.push(`- ${g}`);\n lines.push(\"\");\n }\n if (plan.tasks.length > 0) {\n lines.push(\"Tasks:\");\n for (const t of plan.tasks) lines.push(`- ${t}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function buildPRBody(context: TaskContext): string {\n const plan = context.plan;\n const impl = context.implement;\n const security = context.securityReview;\n\n const sections: string[] = [];\n\n sections.push(\"## Summary\");\n sections.push(\"\");\n sections.push(context.spec.title);\n sections.push(\"\");\n\n if (plan) {\n if (plan.goals.length > 0) {\n sections.push(\"## Goals\");\n sections.push(\"\");\n for (const g of plan.goals) sections.push(`- ${g}`);\n sections.push(\"\");\n }\n if (plan.tasks.length > 0) {\n sections.push(\"## Tasks\");\n sections.push(\"\");\n for (const t of plan.tasks) sections.push(`- [x] ${t}`);\n sections.push(\"\");\n }\n }\n\n if (impl) {\n const devFiles = impl.dev?.files ?? [];\n if (devFiles.length > 0) {\n sections.push(\"## Files Changed\");\n sections.push(\"\");\n for (const f of devFiles) sections.push(`- \\`${f}\\``);\n sections.push(\"\");\n }\n\n const testFiles = impl.qe?.testFiles ?? [];\n if (testFiles.length > 0) {\n sections.push(\"## Test Files\");\n sections.push(\"\");\n for (const f of testFiles) sections.push(`- \\`${f}\\``);\n sections.push(\"\");\n }\n }\n\n\n const prReview = context.prReview;\n if (prReview) {\n sections.push(\"## PR Review\");\n sections.push(\"\");\n sections.push(prReview.summary);\n sections.push(\"\");\n\n if (prReview.comments.length > 0) {\n sections.push(\"### Review Comments\");\n sections.push(\"\");\n\n const byFile = new Map<string, typeof prReview.comments>();\n for (const c of prReview.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n for (const [file, comments] of byFile) {\n sections.push(`**${file}**`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n sections.push(`- \\`${file}${lineRef}\\`: ${c.comment}`);\n }\n sections.push(\"\");\n }\n }\n\n if (prReview.recommendedActions.length > 0) {\n sections.push(\"### Recommended Actions\");\n sections.push(\"\");\n for (const action of prReview.recommendedActions) {\n sections.push(`- ${action}`);\n }\n sections.push(\"\");\n }\n }\n\n sections.push(\"---\");\n sections.push(\"*Created by [reygent](https://github.com/andrewevans0102/reygent)*\");\n\n return sections.join(\"\\n\");\n}\n\nexport async function runPRCreate(\n context: TaskContext,\n opts?: { insecure?: boolean; branchType?: BranchType },\n): Promise<PRCreateOutput> {\n loadEnvFile();\n\n const { stdout: remoteUrlForToken } = await exec(\"git\", [\n \"remote\",\n \"get-url\",\n \"origin\",\n ]);\n const remoteForToken = parseRemote(remoteUrlForToken);\n const token = await resolveToken(remoteForToken.host);\n\n if (!opts?.branchType) {\n throw new TaskError(\"pr-create: branchType is required\");\n }\n\n const branch = deriveBranchName(context.spec, opts.branchType);\n const commitMessage = buildCommitMessage(context, opts.branchType);\n const prBody = buildPRBody(context);\n const prTitle = context.spec.title;\n\n // Get default branch\n let baseBranch: string;\n try {\n const { stdout: defaultBranch } = await exec(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n baseBranch = defaultBranch.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: auto-set origin/HEAD and retry\n try {\n await exec(\"git\", [\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const { stdout: defaultBranch } = await exec(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n baseBranch = defaultBranch.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Final fallback: try common default branches\n const { stdout: branches } = await exec(\"git\", [\n \"branch\",\n \"-r\",\n \"--list\",\n \"origin/main\",\n \"origin/master\",\n ]);\n const match = branches.trim().match(/origin\\/(main|master)/);\n if (match) {\n baseBranch = match[1];\n } else {\n throw new TaskError(\n \"pr-create: cannot determine default branch. Set with: git remote set-head origin <branch>\",\n );\n }\n }\n }\n\n // Stage all changes\n await exec(\"git\", [\"add\", \"-A\"]);\n\n // Verify there's something to commit\n const { stdout: status } = await exec(\"git\", [\"status\", \"--porcelain\"]);\n if (!status.trim()) {\n throw new TaskError(\"pr-create: no changes to commit\");\n }\n\n // Check if branch exists locally\n const { stdout: localBranches } = await exec(\"git\", [\"branch\", \"--list\", branch]);\n const branchExists = localBranches.trim().length > 0;\n\n if (branchExists) {\n // Delete existing local branch\n try {\n await exec(\"git\", [\"branch\", \"-D\", branch]);\n } catch {\n // If deletion fails, branch might be current branch - ignore\n }\n }\n\n // Create branch and commit\n const trace = getChesstrace();\n await exec(\"git\", [\"checkout\", \"-b\", branch]);\n try { trace.emit(Events.GIT_BRANCH_CREATE, { branch }); } catch { /* swallow */ }\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n try { trace.emit(Events.GIT_COMMIT, { branch, messageSubject: commitMessage.split('\\n')[0] }); } catch { /* swallow */ }\n\n // Check if branch exists remotely and delete it\n try {\n const { stdout: remoteBranches } = await exec(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branch,\n ]);\n if (remoteBranches.trim().length > 0) {\n // Remote branch exists - delete it\n await exec(\"git\", [\"push\", \"origin\", \"--delete\", branch]);\n }\n } catch {\n // Remote branch doesn't exist or delete failed - continue\n }\n\n // Push with timeout\n try {\n await exec(\"git\", [\"push\", \"-u\", \"origin\", branch], { timeout: 60_000 });\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n } catch (pushErr) {\n try { trace.emit(Events.GIT_ERROR, { operation: \"push\", error: pushErr instanceof Error ? pushErr.message : String(pushErr) }); } catch { /* swallow */ }\n throw pushErr;\n }\n\n const { prUrl, prNumber } = await createPR({\n remote: remoteForToken,\n title: prTitle,\n body: prBody,\n head: branch,\n base: baseBranch,\n token,\n insecure: opts?.insecure,\n });\n\n return { branch, commitMessage, prUrl, prNumber };\n}\n","import type { SpecPayload } from \"./spec.js\";\n\n/**\n * Valid conventional commit type prefixes for branch names\n */\nexport const VALID_BRANCH_TYPES = [\n \"feat\",\n \"fix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n \"style\",\n \"perf\",\n] as const;\n\nexport type BranchType = typeof VALID_BRANCH_TYPES[number];\n\n/**\n * Long-form aliases that normalize to short conventional types\n */\nconst TYPE_ALIASES: Record<string, BranchType> = {\n feature: \"feat\",\n bugfix: \"fix\",\n};\n\n/**\n * Normalize type input to canonical conventional commit prefix\n * @throws Error if type is invalid\n */\nexport function normalizeType(type: string): BranchType {\n const lower = type.toLowerCase().trim();\n\n // Check if it's a long-form alias\n if (lower in TYPE_ALIASES) {\n return TYPE_ALIASES[lower];\n }\n\n // Check if it's already a valid type\n if (VALID_BRANCH_TYPES.includes(lower as BranchType)) {\n return lower as BranchType;\n }\n\n throw new Error(\n `Invalid branch type: ${type}. Valid types: ${VALID_BRANCH_TYPES.join(\", \")}, feature, bugfix`\n );\n}\n\n/**\n * Check if a type string is valid (without throwing)\n */\nexport function isValidType(type: string): boolean {\n try {\n normalizeType(type);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Detect branch type from Jira issue type field\n * Uses partial matching (e.g., \"Bug Fix\" matches \"bug\")\n * Returns null if type cannot be mapped\n */\nexport function detectTypeFromJiraIssueType(issueType: string): BranchType | null {\n const lower = issueType.toLowerCase();\n\n if (lower.includes(\"bug\") || lower.includes(\"fix\")) return \"fix\";\n if (lower.includes(\"story\") || lower.includes(\"feature\") || lower.includes(\"enhancement\")) return \"feat\";\n if (lower.includes(\"task\") || lower.includes(\"chore\")) return \"chore\";\n if (lower.includes(\"refactor\") || lower.includes(\"technical debt\")) return \"refactor\";\n if (lower.includes(\"doc\")) return \"docs\";\n if (lower.includes(\"test\")) return \"test\";\n if (lower.includes(\"style\")) return \"style\";\n if (lower.includes(\"perf\") || lower.includes(\"performance\")) return \"perf\";\n\n return null;\n}\n\n/**\n * Detect branch type from Linear issue labels\n * Returns null if no matching label found\n * Priority order: bug > feature > others\n */\nexport function detectTypeFromLinearLabels(labels: string[]): BranchType | null {\n const lower = labels.map(l => l.toLowerCase());\n\n // Priority order: bug > feature > others\n if (lower.some(l => l.includes(\"bug\"))) return \"fix\";\n if (lower.some(l => l.includes(\"feature\"))) return \"feat\";\n if (lower.some(l => l.includes(\"chore\") || l.includes(\"maintenance\"))) return \"chore\";\n if (lower.some(l => l.includes(\"refactor\") || l.includes(\"tech-debt\"))) return \"refactor\";\n if (lower.some(l => l.includes(\"doc\"))) return \"docs\";\n\n return null;\n}\n\n/**\n * Derive branch name with type prefix from spec payload\n * @param spec - Spec payload from jira, linear, or markdown\n * @param type - Branch type prefix\n * @returns Full branch name like \"feat/PROJ-123\" or \"fix/add-user-auth\"\n */\nexport function deriveBranchNameWithType(spec: SpecPayload, type: BranchType): string {\n const prefix = type;\n\n if (spec.source === \"jira\") {\n return `${prefix}/${spec.issueKey}`;\n }\n\n if (spec.source === \"linear\") {\n return `${prefix}/${spec.issueId}`;\n }\n\n // Markdown source - slugify title\n const slug = spec.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n\n return `${prefix}/${slug}`;\n}\n\n/**\n * Derive branch name from spec with type detection\n * Tries auto-detection from issueType/labels, falls back to typeOverride\n * @throws Error if no type can be determined\n */\nexport function deriveBranchFromSpec(\n spec: SpecPayload,\n typeOverride?: string,\n): string {\n let type: BranchType | null = null;\n\n // CLI flag takes priority\n if (typeOverride) {\n type = normalizeType(typeOverride);\n } else {\n // Try auto-detection\n if (spec.source === \"jira\" && spec.issueType) {\n type = detectTypeFromJiraIssueType(spec.issueType);\n } else if (spec.source === \"linear\" && \"labels\" in spec && spec.labels) {\n type = detectTypeFromLinearLabels(spec.labels);\n }\n }\n\n if (!type) {\n throw new Error(\"Branch type is required\");\n }\n\n return deriveBranchNameWithType(spec, type);\n}\n\n/**\n * Prompt user for branch type interactively\n * @param promptFn - Prompt function from @inquirer/prompts\n * @param detectedType - Optional auto-detected type to use as default\n * @param opts - Options including skipPrompt flag\n * @returns Normalized branch type\n */\nexport async function promptForType(\n promptFn: (config: {\n message: string;\n choices: { name: string; value: string }[];\n default?: string\n }) => Promise<string | null | undefined>,\n detectedType: BranchType | null,\n opts: { skipPrompt?: boolean } = {},\n): Promise<BranchType> {\n if (opts.skipPrompt) {\n if (!detectedType) {\n throw new Error(\"Branch type is required\");\n }\n return detectedType;\n }\n\n const choices = VALID_BRANCH_TYPES.map(t => ({ name: t, value: t }));\n const config = {\n message: \"Select branch type:\",\n choices,\n default: detectedType ?? undefined,\n };\n\n const response = await promptFn(config);\n\n if (response === null) {\n throw new Error(\"Branch creation cancelled\");\n }\n\n if (response === undefined || !response.trim()) {\n throw new Error(\"Branch type is required\");\n }\n\n return normalizeType(response.trim());\n}\n","import { execFile } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { wrapText } from \"./format.js\";\nimport { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { PRReviewComment, PRReviewOutput, TaskContext } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n} from \"./diff-split.js\";\n\ninterface PRReviewPromptInput {\n stat: string;\n log: string;\n includedDiffs: { file: string; diff: string }[];\n excludedFiles: string[];\n}\n\nfunction buildPRReviewPrompt(\n systemPrompt: string,\n context: TaskContext,\n input: PRReviewPromptInput,\n): string {\n const goals = context.plan?.goals ?? [];\n const tasks = context.plan?.tasks ?? [];\n\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${context.spec.title}\n\n${context.spec.content}\n\n---\n\n## Planner Output\n\n**Goals:**\n${goals.length > 0 ? goals.map((g) => `- ${g}`).join(\"\\n\") : \"- (none)\"}\n\n**Tasks:**\n${tasks.length > 0 ? tasks.map((t) => `- ${t}`).join(\"\\n\") : \"- (none)\"}\n\n---\n\n## Branch Summary\n\n### Changed Files\n\n\\`\\`\\`\n${input.stat}\n\\`\\`\\`\n\n### Commits\n\n\\`\\`\\`\n${input.log}\n\\`\\`\\``;\n\n if (input.includedDiffs.length > 0) {\n prompt += `\n\n## File Diffs\n\n`;\n for (const f of input.includedDiffs) {\n prompt += `\\`\\`\\`diff\n${f.diff}\n\\`\\`\\`\n\n`;\n }\n }\n\n if (input.excludedFiles.length > 0) {\n prompt += `\n### Files not shown (too large for context)\n\n${input.excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n }\n\n prompt += `\n\n---\n\n## Instructions\n\n1. Review the changes above in the context of the spec and planner goals.\n2. Check for correctness, potential bugs, style issues, and whether the implementation meets the spec.\n3. For files not shown, note any concerns based on the stat summary and commit messages.\n4. When you are finished, output a single JSON block with your review:\n\n\\`\\`\\`json\n{\n \"summary\": \"Brief overall assessment of the PR\",\n \"comments\": [\n {\n \"file\": \"src/example.ts\",\n \"line\": 42,\n \"comment\": \"Description of the issue or suggestion\"\n }\n ],\n \"recommendedActions\": [\n \"Action item 1\",\n \"Action item 2\"\n ]\n}\n\\`\\`\\`\n\n- \\`summary\\` is a brief overall assessment of the PR.\n- \\`comments\\` is an array of inline review comments. \\`line\\` may be null if the comment applies to the whole file.\n- \\`recommendedActions\\` is a list of suggested follow-up actions.\n- Do NOT output any text after the JSON block.`;\n\n return prompt;\n}\n\nexport function extractPRReviewOutput(stdout: string): PRReviewOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(\n /\\{\\s*\"summary\"\\s*:\\s*\"[^\"]*\"[\\s\\S]*?\"recommendedActions\"\\s*:\\s*\\[[\\s\\S]*?\\]\\s*\\}/,\n );\n if (!match) {\n throw new TaskError(\n \"pr-review: failed to extract JSON output from agent response\",\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[0]);\n } catch {\n throw new TaskError(\"pr-review: extracted block is not valid JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (typeof obj.summary !== \"string\") {\n throw new TaskError(\"pr-review: 'summary' must be a string\");\n }\n\n if (!Array.isArray(obj.comments)) {\n throw new TaskError(\"pr-review: 'comments' must be an array\");\n }\n\n if (!Array.isArray(obj.recommendedActions)) {\n throw new TaskError(\"pr-review: 'recommendedActions' must be an array\");\n }\n\n const comments: PRReviewComment[] = (obj.comments as unknown[]).map(\n (c, i) => {\n const comment = c as Record<string, unknown>;\n if (typeof comment.file !== \"string\") {\n throw new TaskError(`pr-review: comments[${i}] missing 'file'`);\n }\n if (typeof comment.comment !== \"string\") {\n throw new TaskError(`pr-review: comments[${i}] missing 'comment'`);\n }\n return {\n file: comment.file,\n line: typeof comment.line === \"number\" ? comment.line : null,\n comment: comment.comment,\n };\n },\n );\n\n const recommendedActions = (obj.recommendedActions as unknown[]).map(\n (a, i) => {\n if (typeof a !== \"string\") {\n throw new TaskError(\n `pr-review: recommendedActions[${i}] must be a string`,\n );\n }\n return a;\n },\n );\n\n return { summary: obj.summary, comments, recommendedActions };\n}\n\nexport function formatPRReviewOutput(output: PRReviewOutput): string {\n const lines: string[] = [];\n\n lines.push(\"# 🐱 Reygent PR Review\");\n lines.push(\"\");\n lines.push(\"## Summary\");\n lines.push(output.summary);\n lines.push(\"\");\n\n if (output.comments.length > 0) {\n lines.push(\"## Comments\");\n\n const byFile = new Map<string, PRReviewComment[]>();\n for (const c of output.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n for (const [file, comments] of byFile) {\n lines.push(`\\n### ${file}`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n lines.push(` - ${file}${lineRef}: ${c.comment}`);\n }\n }\n lines.push(\"\");\n }\n\n if (output.recommendedActions.length > 0) {\n lines.push(\"## Recommended Actions\");\n for (const action of output.recommendedActions) {\n lines.push(` - ${action}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n\nexport function formatPRReviewTerminal(output: PRReviewOutput): string {\n const lines: string[] = [];\n const cols = process.stdout.columns || 80;\n\n lines.push(\"\");\n lines.push(chalk.cyan.bold(\"Summary\"));\n // summary indent = 2\n lines.push(` ${wrapText(output.summary, 2, cols)}`);\n lines.push(\"\");\n\n if (output.comments.length > 0) {\n lines.push(chalk.cyan.bold(`Comments (${output.comments.length}):`));\n\n const byFile = new Map<string, PRReviewComment[]>();\n for (const c of output.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n // comment text indent = 6 (4 spaces + bullet + space)\n const commentIndent = 6;\n for (const [file, comments] of byFile) {\n lines.push(\"\");\n lines.push(` ${chalk.bold(file)}`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n const prefix = lineRef ? `${lineRef} ` : \"\";\n const wrapped = wrapText(prefix + c.comment, commentIndent, cols);\n // Re-apply chalk to the line ref portion of first line\n const display = c.line !== null\n ? chalk.gray(`:${c.line}`) + \" \" + wrapped.slice(prefix.length)\n : wrapped;\n lines.push(` ${chalk.yellow(\"•\")} ${display}`);\n }\n }\n lines.push(\"\");\n }\n\n if (output.recommendedActions.length > 0) {\n lines.push(chalk.cyan.bold(\"Recommended Actions:\"));\n lines.push(\"\");\n // action indent = 4 (2 spaces + dash + space)\n for (const action of output.recommendedActions) {\n lines.push(` ${chalk.gray(\"-\")} ${wrapText(action, 4, cols)}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction exec(\n cmd: string,\n args: string[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `pr-review: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nfunction getDiff(prNumber: number): Promise<string> {\n return exec(\"gh\", [\"pr\", \"diff\", String(prNumber)]);\n}\n\n/** Get diff stat for a PR by diffing against the PR base branch */\nasync function getPRDiffStat(prNumber: number): Promise<string> {\n try {\n const baseBranch = (await exec(\"gh\", [\n \"pr\", \"view\", String(prNumber), \"--json\", \"baseRefName\", \"--jq\", \".baseRefName\",\n ])).trim();\n return (await exec(\"git\", [\"diff\", \"--stat\", `origin/${baseBranch}...HEAD`])).trim();\n } catch (err) {\n if (process.env.DEBUG) {\n console.warn(\"getPRDiffStat failed:\", err instanceof Error ? err.message : String(err));\n }\n return \"\";\n }\n}\n\n/** Get commit log for a PR by logging against the PR base branch */\nasync function getPRCommitLog(prNumber: number): Promise<string> {\n try {\n const baseBranch = (await exec(\"gh\", [\n \"pr\", \"view\", String(prNumber), \"--json\", \"baseRefName\", \"--jq\", \".baseRefName\",\n ])).trim();\n return (await exec(\"git\", [\"log\", `origin/${baseBranch}..HEAD`, \"--oneline\"])).trim();\n } catch (err) {\n if (process.env.DEBUG) {\n console.warn(\"getPRCommitLog failed:\", err instanceof Error ? err.message : String(err));\n }\n return \"\";\n }\n}\n\n/**\n * Detect PR number from current git branch via GitHub CLI.\n * Returns the PR number or throws if no PR is found.\n */\nasync function detectPRFromBranch(): Promise<{ prNumber: number; branch: string }> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch) {\n throw new TaskError(\n \"pr-review: not on a branch — cannot auto-detect PR number\",\n );\n }\n\n let prJson: string;\n try {\n prJson = await exec(\"gh\", [\"pr\", \"view\", \"--json\", \"number\", \"--jq\", \".number\"]);\n } catch {\n throw new TaskError(\n `pr-review: no open PR found for branch \"${branch}\". Create a PR first or provide a PR number.`,\n );\n }\n\n const prNumber = parseInt(prJson.trim(), 10);\n if (isNaN(prNumber) || prNumber <= 0) {\n throw new TaskError(\n `pr-review: could not parse PR number from branch \"${branch}\"`,\n );\n }\n\n return { prNumber, branch };\n}\n\n/**\n * Resolve the PR number from context or by detecting from the current branch.\n */\nasync function resolvePRNumber(context: TaskContext): Promise<number> {\n if (context.prCreate) {\n return context.prCreate.prNumber;\n }\n console.log(chalk.blue(\"No PR number provided — detecting from current branch...\"));\n const detected = await detectPRFromBranch();\n console.log(chalk.green(`Found PR #${detected.prNumber} on branch \"${detected.branch}\"`));\n return detected.prNumber;\n}\n\nexport async function runPRReview(\n context: TaskContext,\n options?: AgentSpawnOptions,\n): Promise<{ output: PRReviewOutput; usage?: UsageInfo }> {\n const prNumber = await resolvePRNumber(context);\n\n const agents = getAgents();\n const agent = agents.find((a) => a.name === \"pr-reviewer\");\n if (!agent) {\n throw new TaskError(\"pr-review: missing pr-reviewer agent config\");\n }\n\n const [diff, stat, log] = await Promise.all([\n getDiff(prNumber),\n getPRDiffStat(prNumber),\n getPRCommitLog(prNumber),\n ]);\n\n // Split diff by file and select within budget\n const fileDiffs = splitDiffByFile(diff);\n const reservedTokens = estimateTokens(agent.systemPrompt) + estimateTokens(stat) + estimateTokens(log) + 2000;\n const { included, excluded } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens);\n\n const prompt = buildPRReviewPrompt(agent.systemPrompt, context, {\n stat,\n log,\n includedDiffs: included,\n excludedFiles: excluded,\n });\n const result = await spawnAgent(\"pr-review\", prompt, { ...options, quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `pr-review: agent exited with code ${result.exitCode}`,\n );\n }\n\n return { output: extractPRReviewOutput(result.stdout), usage: result.usage };\n}\n\n/**\n * Post a formatted PR review as a comment on the pull request.\n */\nexport async function postPRReviewComment(\n context: TaskContext,\n review: PRReviewOutput,\n): Promise<void> {\n const prNumber = await resolvePRNumber(context);\n const body = formatPRReviewOutput(review) +\n \"\\n\\n---\\n*Review by [reygent](https://github.com/andrewevans0102/reygent)*\";\n await exec(\"gh\", [\"pr\", \"comment\", String(prNumber), \"--body\", body]);\n}\n","/**\n * Utilities for splitting unified diffs by file and selecting\n * per-file diffs within a token budget.\n */\n\nexport interface FileDiff {\n /** File path from the diff header (prefers b/ path) */\n file: string;\n /** Full unified diff text for this file, including header */\n diff: string;\n /** Estimated token count */\n tokens: number;\n}\n\n/**\n * Approximate tokens — ~4 chars per token.\n *\n * This is a rough average that works across most content types but can vary\n * significantly depending on the text characteristics:\n * - Code with many identifiers/keywords may be closer to 3 chars/token\n * - Prose or repetitive patterns may be closer to 5 chars/token\n * - This estimation is intentionally conservative for budget calculations\n *\n * If budget decisions consistently exclude too many or too few files,\n * tune this ratio based on telemetry feedback and actual provider tokenization.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Safe context budget across all providers (80k tokens).\n *\n * This conservative limit ensures reviews work reliably across all supported\n * providers while leaving headroom for:\n * - Prompt instructions and templates (~2-3k tokens)\n * - Review comment formatting and metadata (~1-2k tokens)\n * - Provider response generation (reviews can be lengthy)\n *\n * Provider-specific context windows:\n * - Claude Opus 4.6: 200k tokens\n * - Claude Sonnet 3.5: 200k tokens\n * - Gemini 2.0 Flash: 1M tokens\n * - GPT-4 Turbo: 128k tokens\n *\n * The 80k limit is set well below the smallest provider window (GPT-4 Turbo)\n * to ensure consistent behavior. For very large PRs (100+ files, 10k+ lines),\n * consider splitting into multiple focused reviews or increasing this constant\n * after validating against real-world telemetry data.\n */\nexport const MAX_REVIEW_TOKENS = 80_000;\n\n/**\n * Reserved token overhead for prompt templates and formatting.\n *\n * This accounts for:\n * - Review prompt instructions and structure (~1k tokens)\n * - Comment formatting and metadata (~500-1k tokens)\n * - Headroom for prompt template expansion (~500 tokens)\n *\n * If prompt templates grow significantly, increase this value or calculate\n * dynamically from actual prompt size.\n */\nexport const RESERVED_PROMPT_TOKENS = 2_000;\n\n/**\n * Split a unified diff into per-file chunks.\n * Each chunk starts with `diff --git` and includes everything\n * up to (but not including) the next `diff --git`.\n */\nexport function splitDiffByFile(rawDiff: string): FileDiff[] {\n if (!rawDiff.trim()) return [];\n\n const files: FileDiff[] = [];\n // Split on diff headers, keeping the delimiter\n const parts = rawDiff.split(/^(?=diff --git )/m);\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed || !trimmed.startsWith(\"diff --git \")) continue;\n\n // Extract file path from \"diff --git a/path b/path\"\n const headerMatch = trimmed.match(/^diff --git a\\/(.+?) b\\/(.+)/m);\n const file = headerMatch ? headerMatch[2] : \"unknown\";\n\n files.push({\n file,\n diff: trimmed,\n tokens: estimateTokens(trimmed),\n });\n }\n\n return files;\n}\n\n/**\n * Greedily select file diffs that fit within a token budget.\n * Returns included diffs and names of excluded files.\n */\nexport function selectDiffsWithinBudget(\n files: FileDiff[],\n budgetTokens: number,\n reservedTokens: number,\n): { included: FileDiff[]; excluded: string[] } {\n const available = budgetTokens - reservedTokens;\n const included: FileDiff[] = [];\n const excluded: string[] = [];\n let used = 0;\n\n for (const f of files) {\n if (used + f.tokens <= available) {\n included.push(f);\n used += f.tokens;\n } else {\n excluded.push(f.file);\n }\n }\n\n return { included, excluded };\n}\n","import chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { wrapText } from \"./format.js\";\nimport { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type {\n Severity,\n SecurityFinding,\n SecurityReviewOutput,\n TaskContext,\n} from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\n\nconst SEVERITY_ORDER: Record<Severity, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function severityAtOrAbove(\n severity: Severity,\n threshold: Severity,\n): boolean {\n return SEVERITY_ORDER[severity] >= SEVERITY_ORDER[threshold];\n}\n\nfunction buildSecurityReviewPrompt(\n systemPrompt: string,\n context: TaskContext,\n): string {\n const devFiles = context.implement?.dev?.files ?? [];\n const qeFiles = context.implement?.qe?.testFiles ?? [];\n\n return `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${context.spec.title}\n\n${context.spec.content}\n\n---\n\n## Files to review\n\n**Implementation files (dev):**\n${devFiles.length > 0 ? devFiles.map((f) => `- ${f}`).join(\"\\n\") : \"- (none)\"}\n\n**Test files (qe):**\n${qeFiles.length > 0 ? qeFiles.map((f) => `- ${f}`).join(\"\\n\") : \"- (none)\"}\n\n---\n\n## Instructions\n\n1. Read each file listed above.\n2. Analyse the code for security vulnerabilities, including but not limited to the OWASP Top 10: injection, broken authentication, sensitive data exposure, XXE, broken access control, security misconfiguration, XSS, insecure deserialization, using components with known vulnerabilities, and insufficient logging.\n3. For each finding, assign a severity: CRITICAL, HIGH, MEDIUM, or LOW.\n4. When you are finished, output a single JSON block with your findings:\n\n\\`\\`\\`json\n{\n \"severity\": \"HIGH\",\n \"findings\": [\n {\n \"severity\": \"HIGH\",\n \"description\": \"SQL injection in user input handler\",\n \"location\": { \"file\": \"src/db.ts\", \"line\": 42 }\n }\n ]\n}\n\\`\\`\\`\n\n- The top-level \\`severity\\` is the highest severity among all findings, or \"LOW\" if there are no findings.\n- If no issues are found, return \\`{ \"severity\": \"LOW\", \"findings\": [] }\\`.\n- Do NOT output any text after the JSON block.`;\n}\n\nexport function extractSecurityReviewOutput(\n stdout: string,\n): SecurityReviewOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(\n /\\{\\s*\"severity\"\\s*:\\s*\"[^\"]+\"\\s*,\\s*\"findings\"\\s*:\\s*\\[[\\s\\S]*?\\]\\s*\\}/,\n );\n if (!match) {\n throw new TaskError(\n \"security-review: failed to extract JSON output from agent response\",\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[0]);\n } catch {\n throw new TaskError(\n \"security-review: extracted block is not valid JSON\",\n );\n }\n\n const obj = parsed as Record<string, unknown>;\n\n const validSeverities = new Set([\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"]);\n\n if (typeof obj.severity !== \"string\" || !validSeverities.has(obj.severity)) {\n throw new TaskError(\n \"security-review: invalid top-level severity in output\",\n );\n }\n\n if (!Array.isArray(obj.findings)) {\n throw new TaskError(\"security-review: 'findings' must be an array\");\n }\n\n const findings: SecurityFinding[] = (obj.findings as unknown[]).map(\n (f, i) => {\n const finding = f as Record<string, unknown>;\n if (\n typeof finding.severity !== \"string\" ||\n !validSeverities.has(finding.severity)\n ) {\n throw new TaskError(\n `security-review: finding[${i}] has invalid severity`,\n );\n }\n if (typeof finding.description !== \"string\") {\n throw new TaskError(\n `security-review: finding[${i}] missing description`,\n );\n }\n\n const result: SecurityFinding = {\n severity: finding.severity as Severity,\n description: finding.description,\n };\n\n if (finding.location && typeof finding.location === \"object\") {\n const loc = finding.location as Record<string, unknown>;\n if (typeof loc.file === \"string\") {\n result.location = {\n file: loc.file,\n ...(typeof loc.line === \"number\" ? { line: loc.line } : {}),\n };\n }\n }\n\n return result;\n },\n );\n\n return { severity: obj.severity as Severity, findings };\n}\n\nexport function formatFindings(\n findings: SecurityFinding[],\n threshold: Severity,\n): string {\n if (findings.length === 0) {\n return chalk.gray(\" No findings.\");\n }\n\n return findings\n .map((f) => {\n const isBlocking = severityAtOrAbove(f.severity, threshold);\n const marker = isBlocking ? chalk.red.bold(\"!! \") : \" \";\n\n let severityLabel: string;\n switch (f.severity) {\n case \"CRITICAL\":\n severityLabel = chalk.red.bold(`[${f.severity}]`);\n break;\n case \"HIGH\":\n severityLabel = chalk.red(`[${f.severity}]`);\n break;\n case \"MEDIUM\":\n severityLabel = chalk.yellow(`[${f.severity}]`);\n break;\n case \"LOW\":\n severityLabel = chalk.blue(`[${f.severity}]`);\n break;\n }\n\n const loc = f.location\n ? chalk.gray(\n ` (${f.location.file}${f.location.line ? `:${f.location.line}` : \"\"})`,\n )\n : \"\";\n\n const cols = process.stdout.columns || 80;\n // marker (3) + severity label visible width (~8) + space = ~12 indent\n const indent = 12;\n return `${marker}${severityLabel} ${wrapText(f.description, indent, cols)}${loc}`;\n })\n .join(\"\\n\");\n}\n\nexport async function runSecurityReview(\n context: TaskContext,\n threshold: Severity,\n options?: AgentSpawnOptions,\n): Promise<{ output: SecurityReviewOutput; passed: boolean; usage?: UsageInfo }> {\n const agents = getAgents();\n const agent = agents.find((a) => a.name === \"security-reviewer\");\n if (!agent) {\n throw new TaskError(\"security-review: missing security-reviewer agent config\");\n }\n\n const prompt = buildSecurityReviewPrompt(agent.systemPrompt, context);\n const result = await spawnAgent(\"security-review\", prompt, { ...options, quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `security-review: agent exited with code ${result.exitCode}`,\n );\n }\n\n const output = extractSecurityReviewOutput(result.stdout);\n\n const hasBlockingFinding = output.findings.some((f) =>\n severityAtOrAbove(f.severity, threshold),\n );\n\n return { output, passed: !hasBlockingFinding, usage: result.usage };\n}\n","import chalk from \"chalk\";\nimport { wrapText } from \"./format.js\";\nimport { PROVIDER_PRICING, type ProviderName } from \"./pricing.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nexport interface UsageInfo {\n costUsd?: number;\n durationMs?: number;\n numTurns?: number;\n inputTokens?: number;\n outputTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n cacheDiscount?: number;\n provider?: ProviderName;\n}\n\nexport interface AgentUsageEntry {\n agent: string;\n stage: string;\n usage: UsageInfo;\n}\n\nexport class UsageTracker {\n private entries: AgentUsageEntry[] = [];\n\n record(agent: string, stage: string, usage: UsageInfo): void {\n this.entries.push({ agent, stage, usage });\n\n // Emit telemetry events (no-op if telemetry disabled)\n const chesstrace = getChesstrace();\n if (!chesstrace || !chesstrace.isEnabled()) {\n return;\n }\n\n // Emit usage.tokens event\n chesstrace.emit(Events.USAGE_TOKENS, {\n agent,\n stage,\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n cachedTokens: usage.cachedTokens ?? 0,\n cacheWriteTokens: usage.cacheWriteTokens ?? 0,\n provider: usage.provider,\n });\n\n // Calculate cache savings and emit usage.cost event\n const cacheSavingsUsd = calculateCacheSavings(usage);\n chesstrace.emit(Events.USAGE_COST, {\n agent,\n stage,\n costUsd: usage.costUsd,\n cacheSavingsUsd,\n });\n }\n\n getTotalCost(): number {\n return this.entries.reduce((sum, e) => sum + (e.usage.costUsd ?? 0), 0);\n }\n\n getByAgent(): Map<string, { cost: number; inputTokens: number; outputTokens: number; cachedTokens: number; cacheWriteTokens: number; calls: number; provider?: ProviderName }> {\n const map = new Map<string, { cost: number; inputTokens: number; outputTokens: number; cachedTokens: number; cacheWriteTokens: number; calls: number; provider?: ProviderName }>();\n for (const entry of this.entries) {\n const existing = map.get(entry.agent) ?? { cost: 0, inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, calls: 0 };\n existing.cost += entry.usage.costUsd ?? 0;\n existing.inputTokens += entry.usage.inputTokens ?? 0;\n existing.outputTokens += entry.usage.outputTokens ?? 0;\n existing.cachedTokens += entry.usage.cachedTokens ?? 0;\n existing.cacheWriteTokens += entry.usage.cacheWriteTokens ?? 0;\n existing.calls += 1;\n if (entry.usage.provider) existing.provider = entry.usage.provider;\n map.set(entry.agent, existing);\n }\n return map;\n }\n\n getEntries(): AgentUsageEntry[] {\n return [...this.entries];\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes === 0) return `${seconds}s`;\n return `${minutes}m ${seconds}s`;\n}\n\nfunction formatCost(usd: number): string {\n if (usd > 0 && usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n\nfunction formatTokenCount(n: number): string {\n if (n >= 1000) {\n return n.toLocaleString(\"en-US\");\n }\n return String(n);\n}\n\n\n/** Estimate dollar savings from cached tokens for a single entry. */\nexport function calculateCacheSavings(usage: UsageInfo): number {\n // OpenRouter reports cacheDiscount as a dollar amount — use directly when cachedTokens is absent\n if (usage.cacheDiscount && usage.cacheDiscount > 0 && (usage.cachedTokens ?? 0) === 0) {\n return usage.cacheDiscount;\n }\n const cached = usage.cachedTokens ?? 0;\n if (cached === 0) return 0;\n const provider = usage.provider ?? \"claude\";\n const discount = PROVIDER_PRICING[provider]?.cacheDiscountRate ?? 0.50;\n const costPerMillion = PROVIDER_PRICING[provider]?.inputCostPerMillion ?? 3.00;\n return (cached / 1_000_000) * costPerMillion * discount;\n}\n\n/** Providers where caching is reliable enough to warn when absent. */\nconst CACHE_WARN_PROVIDERS = new Set<ProviderName>([\"claude\", \"codex\"]);\n\n/**\n * Print warnings if caching appears inactive for providers that support it.\n * Only warns when inputTokens > 0 and cachedTokens is 0.\n */\nexport function printCacheWarnings(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n const warned = new Set<string>();\n\n for (const entry of entries) {\n const { agent, usage } = entry;\n const provider = usage.provider;\n if (!provider || !CACHE_WARN_PROVIDERS.has(provider)) continue;\n if (warned.has(agent)) continue;\n\n const hasInput = (usage.inputTokens ?? 0) > 0;\n const noCacheHit = (usage.cachedTokens ?? 0) === 0;\n if (hasInput && noCacheHit) {\n console.error(\n chalk.yellow(\"⚠\") +\n chalk.yellow(` [${agent}] Prompt caching appears inactive for ${provider} provider. `) +\n chalk.yellow(\"Repeated context is not being cached — costs may be higher than expected.\"),\n );\n warned.add(agent);\n }\n }\n}\n\nexport function printUsageSummary(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n if (entries.length === 0) return;\n\n const totalCost = tracker.getTotalCost();\n const totalDuration = entries.reduce((sum, e) => sum + (e.usage.durationMs ?? 0), 0);\n const totalInput = entries.reduce((sum, e) => sum + (e.usage.inputTokens ?? 0), 0);\n const totalOutput = entries.reduce((sum, e) => sum + (e.usage.outputTokens ?? 0), 0);\n const totalCached = entries.reduce((sum, e) => sum + (e.usage.cachedTokens ?? 0), 0);\n const totalSavings = entries.reduce((sum, e) => sum + calculateCacheSavings(e.usage), 0);\n const byAgent = tracker.getByAgent();\n\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Usage Summary\"));\n console.log(chalk.cyan(\"│\") + ` Total cost: ${chalk.bold(formatCost(totalCost))}`);\n console.log(chalk.cyan(\"│\") + ` Duration: ${formatDuration(totalDuration)}`);\n if (totalInput > 0 || totalOutput > 0) {\n const cachedSuffix = totalCached > 0\n ? ` / ${formatTokenCount(totalCached)} cached`\n : \"\";\n console.log(chalk.cyan(\"│\") + ` Tokens: ${formatTokenCount(totalInput)} in / ${formatTokenCount(totalOutput)} out${cachedSuffix}`);\n }\n if (totalSavings > 0 && Math.round(totalSavings * 100) >= 1) {\n console.log(chalk.cyan(\"│\") + ` Cache saves: ${chalk.green(formatCost(totalSavings))}`);\n }\n console.log(chalk.cyan(\"│\"));\n console.log(chalk.cyan(\"│\") + ` By agent:`);\n\n for (const [agent, stats] of byAgent) {\n const callLabel = stats.calls === 1 ? \"1 call\" : `${stats.calls} calls`;\n const prefix = chalk.cyan(\"│\") + \" \";\n\n // First line: agent name, cost, calls\n console.log(prefix + `${agent.padEnd(12)} ${formatCost(stats.cost).padStart(7)} (${callLabel})`);\n\n // Second line: token breakdown (if present)\n if (stats.inputTokens > 0 || stats.outputTokens > 0) {\n const tokenParts: string[] = [];\n tokenParts.push(`${formatTokenCount(stats.inputTokens)} in`);\n tokenParts.push(`${formatTokenCount(stats.outputTokens)} out`);\n if (stats.cachedTokens > 0) {\n tokenParts.push(`${formatTokenCount(stats.cachedTokens)} cached`);\n }\n console.log(prefix + chalk.gray(` ${tokenParts.join(\" / \")}`));\n }\n\n // Third line: cache savings and hit rate (if present)\n const agentSavings = stats.cachedTokens > 0 && stats.provider\n ? calculateCacheSavings({ cachedTokens: stats.cachedTokens, provider: stats.provider })\n : 0;\n const hitRate = stats.inputTokens > 0 && stats.cachedTokens > 0\n ? Math.round((stats.cachedTokens / stats.inputTokens) * 100)\n : 0;\n\n if (agentSavings > 0 || hitRate > 0) {\n const parts: string[] = [];\n if (agentSavings > 0) parts.push(chalk.green(formatCost(agentSavings) + \" saved\"));\n if (hitRate > 0) parts.push(chalk.green(hitRate + \"% hit\"));\n console.log(prefix + ` ${parts.join(\" \")}`);\n }\n }\n\n console.log(chalk.cyan(\"└─\"));\n\n // Print cache warnings after summary\n printCacheWarnings(tracker);\n}\n\nexport function printVerboseUsage(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n if (entries.length === 0) return;\n\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Detailed Usage\") + chalk.gray(\" (--verbose)\"));\n\n for (const entry of entries) {\n const { agent, stage, usage } = entry;\n const tokens = (usage.inputTokens || usage.outputTokens)\n ? ` ${formatTokenCount(usage.inputTokens ?? 0)} in / ${formatTokenCount(usage.outputTokens ?? 0)} out`\n : \"\";\n console.log(\n chalk.cyan(\"│\") +\n ` ${chalk.bold(agent)} ${chalk.gray(`(${stage})`)} ` +\n `${formatCost(usage.costUsd ?? 0)} ${formatDuration(usage.durationMs ?? 0)} ${usage.numTurns ?? 0} turns${tokens}`,\n );\n\n // Show cache metadata in verbose mode\n const hasCacheData = (usage.cachedTokens ?? 0) > 0 || (usage.cacheWriteTokens ?? 0) > 0 || (usage.cacheDiscount ?? 0) > 0;\n if (hasCacheData) {\n const savings = calculateCacheSavings(usage);\n const parts: string[] = [];\n if (usage.cachedTokens !== undefined && usage.cachedTokens >= 0) parts.push(`cached: ${formatTokenCount(usage.cachedTokens)}`);\n if (usage.cacheWriteTokens !== undefined && usage.cacheWriteTokens >= 0) parts.push(`cache_write: ${formatTokenCount(usage.cacheWriteTokens)}`);\n if (usage.cacheDiscount !== undefined && usage.cacheDiscount > 0) parts.push(`cache_discount: ${formatCost(usage.cacheDiscount)}`);\n if (savings > 0) parts.push(`saved: ${formatCost(savings)}`);\n if (usage.provider) parts.push(`provider: ${usage.provider}`);\n console.log(\n chalk.cyan(\"│\") +\n ` ${chalk.gray(\"cache: { \" + parts.join(\", \") + \" }\")}`,\n );\n }\n }\n\n console.log(chalk.cyan(\"└─\"));\n}\n","export type ProviderName = \"claude\" | \"codex\" | \"openrouter\" | \"gemini\";\n\nexport interface ProviderPricing {\n /** Cost per 1M input tokens (USD) */\n inputCostPerMillion: number;\n /** Cost per 1M output tokens (USD) */\n outputCostPerMillion: number;\n /** Fraction saved on cached tokens (0.90 = 90% savings) */\n cacheDiscountRate: number;\n /** Whether provider supports prompt caching */\n supportsCaching: boolean;\n /** Default model this pricing applies to */\n defaultModel: string;\n /** URL to provider's pricing page for verification */\n pricingUrl: string;\n /** Date this pricing was last verified (ISO format) */\n lastVerified: string;\n}\n\nexport const PROVIDER_PRICING: Record<ProviderName, ProviderPricing> = {\n claude: {\n inputCostPerMillion: 3.00,\n outputCostPerMillion: 15.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"claude-sonnet-4-5-20250929\",\n pricingUrl: \"https://www.anthropic.com/pricing\",\n lastVerified: \"2026-05-08\",\n },\n codex: {\n inputCostPerMillion: 1.25,\n outputCostPerMillion: 10.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"gpt-5.4\",\n pricingUrl: \"https://openai.com/api/pricing/\",\n lastVerified: \"2026-05-08\",\n },\n openrouter: {\n inputCostPerMillion: 3.00,\n outputCostPerMillion: 15.00,\n cacheDiscountRate: 0.50,\n supportsCaching: true,\n defaultModel: \"anthropic/claude-sonnet-4-5\",\n pricingUrl: \"https://openrouter.ai/models\",\n lastVerified: \"2025-05-04\",\n },\n gemini: {\n inputCostPerMillion: 1.25,\n outputCostPerMillion: 10.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"gemini-2.5-pro\",\n pricingUrl: \"https://ai.google.dev/pricing\",\n lastVerified: \"2026-05-08\",\n },\n};\n","import type { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\n\nexport interface FailurePattern {\n pattern: string;\n occurrences: number;\n runIds: string[];\n agents: string[];\n lastSeen: number;\n suggestedEntry: string;\n}\n\nexport interface SuccessPattern {\n pattern: string;\n successRate: number;\n observations: number;\n lastSeen: number;\n suggestedEntry: string;\n}\n\n/**\n * Analyze telemetry for recurring failure patterns.\n * Groups error events by message pattern and agent.\n */\nexport function analyzeFailurePatterns(\n db: SqliteBackend,\n sinceMs: number,\n): FailurePattern[] {\n const events = db.getEvents();\n const errorEvents = events.filter(\n (e) =>\n e.category === \"error\" &&\n e.timestamp >= sinceMs &&\n (e.event === Events.ERROR_TASK || e.event === Events.AGENT_ERROR),\n );\n\n // Group by error message pattern\n const patterns = new Map<string, FailurePattern>();\n\n for (const event of errorEvents) {\n const message = event.data.message as string;\n const agent = event.data.agent as string;\n const runId = event.runId;\n\n if (!message || !agent) continue;\n\n // Extract pattern (first 100 chars of message, normalized)\n const pattern = normalizeErrorPattern(message);\n\n const existing = patterns.get(pattern);\n if (existing) {\n existing.occurrences++;\n if (!existing.runIds.includes(runId)) {\n existing.runIds.push(runId);\n }\n if (!existing.agents.includes(agent)) {\n existing.agents.push(agent);\n }\n existing.lastSeen = Math.max(existing.lastSeen, event.timestamp);\n } else {\n patterns.set(pattern, {\n pattern,\n occurrences: 1,\n runIds: [runId],\n agents: [agent],\n lastSeen: event.timestamp,\n suggestedEntry: generateFailureEntry(pattern, agent),\n });\n }\n }\n\n // Return patterns with >1 occurrence, sorted by frequency\n return Array.from(patterns.values())\n .filter((p) => p.occurrences > 1)\n .sort((a, b) => b.occurrences - a.occurrences);\n}\n\n/**\n * Analyze telemetry for success patterns.\n * Identifies high-success-rate agent/stage combinations and tool sequences.\n */\nexport function analyzeSuccessPatterns(\n db: SqliteBackend,\n sinceMs: number,\n minSuccessRate: number = 0.8,\n): SuccessPattern[] {\n const events = db.getEvents();\n const completeEvents = events.filter(\n (e) =>\n e.event === Events.AGENT_COMPLETE && e.timestamp >= sinceMs,\n );\n\n // Group by agent+stage\n const patterns = new Map<\n string,\n { successes: number; failures: number; lastSeen: number; toolSequences: string[][] }\n >();\n\n for (const event of completeEvents) {\n const agent = event.data.agent as string;\n const stage = (event.data.stage as string) || \"unknown\";\n const success = event.data.success as boolean;\n const runId = event.runId;\n\n const key = `${agent}:${stage}`;\n const existing = patterns.get(key) || {\n successes: 0,\n failures: 0,\n lastSeen: 0,\n toolSequences: [],\n };\n\n if (success) {\n existing.successes++;\n // Extract tool sequence for this successful run\n const toolSequence = extractToolSequence(events, runId, agent);\n if (toolSequence.length > 0) {\n existing.toolSequences.push(toolSequence);\n }\n } else {\n existing.failures++;\n }\n existing.lastSeen = Math.max(existing.lastSeen, event.timestamp);\n patterns.set(key, existing);\n }\n\n // Filter by success rate and convert to SuccessPattern\n const successPatterns: SuccessPattern[] = [];\n\n for (const [key, stats] of patterns.entries()) {\n const total = stats.successes + stats.failures;\n const successRate = stats.successes / total;\n\n if (successRate >= minSuccessRate && total >= 3) {\n const [agent, stage] = key.split(\":\");\n const commonSequence = findCommonToolSequence(stats.toolSequences);\n successPatterns.push({\n pattern: `${agent} in ${stage} stage`,\n successRate,\n observations: total,\n lastSeen: stats.lastSeen,\n suggestedEntry: generateSuccessEntry(agent, stage, successRate, total, commonSequence),\n });\n }\n }\n\n return successPatterns.sort((a, b) => b.successRate - a.successRate);\n}\n\n/**\n * Measure knowledge effectiveness by comparing success rates.\n * Returns success rate when knowledge consulted vs baseline.\n */\nexport function measureKnowledgeEffectiveness(db: SqliteBackend, sinceMs: number): {\n withKnowledge: number;\n baseline: number;\n improvement: number;\n consultedRuns: number;\n baselineRuns: number;\n} {\n const events = db.getEvents();\n\n // Get runs that consulted knowledge\n const knowledgeEvents = events.filter(\n (e) =>\n e.event === Events.KNOWLEDGE_CONSULTED && e.timestamp >= sinceMs,\n );\n const consultedRunIds = new Set(knowledgeEvents.map((e) => e.runId));\n\n // Get pipeline end events\n const pipelineEnds = events.filter(\n (e) =>\n e.event === Events.PIPELINE_END && e.timestamp >= sinceMs,\n );\n\n let consultedSuccess = 0;\n let consultedTotal = 0;\n let baselineSuccess = 0;\n let baselineTotal = 0;\n\n for (const event of pipelineEnds) {\n const success = event.data.success as boolean;\n const runId = event.runId;\n\n if (consultedRunIds.has(runId)) {\n consultedTotal++;\n if (success) consultedSuccess++;\n } else {\n baselineTotal++;\n if (success) baselineSuccess++;\n }\n }\n\n const withKnowledge = consultedTotal > 0 ? consultedSuccess / consultedTotal : 0;\n const baseline = baselineTotal > 0 ? baselineSuccess / baselineTotal : 0;\n const improvement = withKnowledge - baseline;\n\n return {\n withKnowledge,\n baseline,\n improvement,\n consultedRuns: consultedTotal,\n baselineRuns: baselineTotal,\n };\n}\n\n/**\n * Sanitize error message to remove sensitive data (tokens, paths, emails)\n */\nfunction sanitizeErrorMessage(message: string): string {\n return message\n // API keys, tokens, secrets (20+ alphanumeric chars with word boundaries to avoid base64 false positives)\n .replace(/\\b[A-Za-z0-9+/=_-]{20,}\\b/g, '[REDACTED_TOKEN]')\n // User home paths\n .replace(/\\/Users\\/[^/\\s]+/g, '/Users/***')\n .replace(/\\/home\\/[^/\\s]+/g, '/home/***')\n .replace(/C:\\\\Users\\\\[^\\\\]+/g, 'C:\\\\Users\\\\***')\n // Email addresses\n .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g, '***@***.***')\n // IP addresses\n .replace(/\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g, '***.***.***.**')\n // Common env var patterns\n .replace(/(password|secret|key|token|api[_-]?key)=[^\\s]+/gi, '$1=[REDACTED]');\n}\n\n/**\n * Normalize error message to pattern (first 100 chars, trimmed, sanitized)\n */\nfunction normalizeErrorPattern(message: string): string {\n const sanitized = sanitizeErrorMessage(message);\n return sanitized.slice(0, 100).trim();\n}\n\n/**\n * Generate failure entry template\n */\nfunction generateFailureEntry(pattern: string, agent: string): string {\n const today = new Date().toISOString().split(\"T\")[0];\n return `\n## ${pattern}\n**Occurrences**: X runs\n**Last seen**: ${today}\n**Agent**: ${agent}\n\n**Solution**: [Add solution description here]\n\n**Example**:\n\\`\\`\\`\n[Add code example here]\n\\`\\`\\`\n`;\n}\n\n/**\n * Generate success entry template\n */\nfunction generateSuccessEntry(\n agent: string,\n stage: string,\n successRate: number,\n observations: number,\n commonSequence?: string[],\n): string {\n const today = new Date().toISOString().split(\"T\")[0];\n const pct = Math.round(successRate * 100);\n const sequenceText = commonSequence && commonSequence.length > 0\n ? `\n\n**Common tool sequence**:\n${commonSequence.map((tool, i) => `${i + 1}. ${tool}`).join('\\n')}`\n : '';\n\n return `\n## ${agent} in ${stage} stage (${pct}% success)\n**Observations**: ${observations} runs\n**Last seen**: ${today}\n**Success rate**: ${pct}%\n\n**Pattern**:\n[Describe what makes this approach successful]${sequenceText}\n\n**Recommended approach**:\n[Add recommendation here]\n`;\n}\n\n/**\n * Extract tool sequence from events for a given run and agent\n */\nfunction extractToolSequence(events: TelemetryEvent[], runId: string, agent: string): string[] {\n const agentEvents = events.filter(\n (e) => e.runId === runId && e.data.agent === agent && e.event === Events.TOOL_CALL\n );\n\n return agentEvents\n .sort((a, b) => a.timestamp - b.timestamp)\n .map((e) => e.data.tool as string)\n .filter((tool): tool is string => !!tool);\n}\n\n/**\n * Find common tool sequence across multiple runs\n */\nfunction findCommonToolSequence(sequences: string[][]): string[] | undefined {\n if (sequences.length === 0) return undefined;\n\n // Find the most common sequence pattern\n const sequenceMap = new Map<string, number>();\n\n for (const seq of sequences) {\n const key = seq.join('->');\n sequenceMap.set(key, (sequenceMap.get(key) || 0) + 1);\n }\n\n // Return most common sequence if it appears in >50% of runs\n const threshold = sequences.length * 0.5;\n for (const [key, count] of sequenceMap.entries()) {\n if (count >= threshold) {\n return key.split('->');\n }\n }\n\n return undefined;\n}\n\n/**\n * Suggest knowledge entries from failure patterns.\n * Returns formatted entries ready to add to common-failures.md\n */\nexport function suggestFromFailures(\n db: SqliteBackend,\n sinceMs: number,\n limit: number = 5,\n): string[] {\n const patterns = analyzeFailurePatterns(db, sinceMs);\n return patterns.slice(0, limit).map((p) => p.suggestedEntry);\n}\n\n/**\n * Suggest knowledge entries from success patterns.\n * Returns formatted entries ready to add to success-patterns.md\n */\nexport function suggestFromSuccesses(\n db: SqliteBackend,\n sinceMs: number,\n minSuccessRate: number = 0.85,\n limit: number = 5,\n): string[] {\n const patterns = analyzeSuccessPatterns(db, sinceMs, minSuccessRate);\n return patterns.slice(0, limit).map((p) => p.suggestedEntry);\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { AgentName } from '../agents.js';\n\nexport interface FailureEntryOptions {\n issue: string;\n solution: string;\n agent: AgentName;\n example?: string;\n}\n\nexport interface PatternEntryOptions {\n description: string;\n approach?: string;\n successRate?: number;\n}\n\n/**\n * Check if path exists\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse markdown to extract entries with metadata\n */\ninterface ParsedEntry {\n title: string;\n occurrences?: number;\n lastSeen: string;\n agent?: string;\n successRate?: number;\n fullContent: string;\n}\n\nfunction parseEntries(markdown: string): ParsedEntry[] {\n const entries: ParsedEntry[] = [];\n const sections = markdown.split(/^## /m).filter(s => s.trim());\n\n for (const section of sections) {\n const lines = section.split('\\n');\n const title = lines[0]?.trim() || 'Untitled';\n\n const occurrenceMatch = section.match(/\\*\\*Occurrences\\*\\*:\\s*(\\d+)/);\n const lastSeenMatch = section.match(/\\*\\*Last seen\\*\\*:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n const agentMatch = section.match(/\\*\\*Agent\\*\\*:\\s*(\\w+)/);\n const successRateMatch = section.match(/\\*\\*Success rate\\*\\*:\\s*(\\d+)%/);\n\n // Validate date format - use default if invalid\n let lastSeen = new Date().toISOString().split('T')[0];\n if (lastSeenMatch) {\n const parsedDate = new Date(lastSeenMatch[1]);\n if (!isNaN(parsedDate.getTime())) {\n lastSeen = lastSeenMatch[1];\n }\n }\n\n entries.push({\n title,\n occurrences: occurrenceMatch ? parseInt(occurrenceMatch[1], 10) : undefined,\n lastSeen,\n agent: agentMatch ? agentMatch[1] : undefined,\n successRate: successRateMatch ? parseInt(successRateMatch[1], 10) : undefined,\n fullContent: '## ' + section,\n });\n }\n\n return entries;\n}\n\n/**\n * Prune old entries that haven't been seen in days\n */\nfunction pruneOldEntries(entries: ParsedEntry[], maxAgeDays: number): ParsedEntry[] {\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - maxAgeDays);\n const cutoffStr = cutoff.toISOString().split('T')[0];\n\n return entries.filter(entry => entry.lastSeen >= cutoffStr);\n}\n\n/**\n * Limit entries to max count, keeping most recent\n */\nfunction limitEntries(entries: ParsedEntry[], maxEntries: number): ParsedEntry[] {\n return entries\n .sort((a, b) => b.lastSeen.localeCompare(a.lastSeen))\n .slice(0, maxEntries);\n}\n\n/**\n * Ensures the knowledge directory structure exists.\n * Creates .reygent/knowledge/ and subdirectories if missing.\n */\nexport async function ensureKnowledgeDir(baseDir: string): Promise<void> {\n const knowledgeDir = path.join(baseDir, '.reygent', 'knowledge');\n const agentsDir = path.join(knowledgeDir, 'agents');\n\n await fs.mkdir(knowledgeDir, { recursive: true });\n await fs.mkdir(agentsDir, { recursive: true });\n\n // Create initial template files if they don't exist\n const templates = [\n {\n file: path.join(knowledgeDir, 'common-failures.md'),\n content: `# Common Failures\n\nThis file documents recurring errors and their solutions.\n\n---\n`,\n },\n {\n file: path.join(knowledgeDir, 'success-patterns.md'),\n content: `# Success Patterns\n\nThis file captures proven approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(knowledgeDir, 'project-conventions.md'),\n content: `# Project Conventions\n\nDocument project-specific rules, patterns, and conventions here.\n\nExamples:\n- Code style preferences\n- Architecture decisions\n- Naming conventions\n- Testing strategies\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'dev.md'),\n content: `# Dev Agent Tips\n\n## Common Failures\n\nDocument dev-specific errors here.\n\n## Success Patterns\n\nDocument approaches that work well for development tasks.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'qe.md'),\n content: `# QE Agent Tips\n\n## Common Failures\n\nDocument QE-specific errors here.\n\n## Success Patterns\n\nDocument testing approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'planner.md'),\n content: `# Planner Agent Tips\n\n## Common Failures\n\nDocument planning-specific errors here.\n\n## Success Patterns\n\nDocument planning approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'pr-reviewer.md'),\n content: `# PR Reviewer Agent Tips\n\n## Common Failures\n\nDocument review-specific errors here.\n\n## Success Patterns\n\nDocument review approaches that work well.\n\n---\n`,\n },\n ];\n\n for (const { file, content } of templates) {\n if (!(await pathExists(file))) {\n await fs.writeFile(file, content, 'utf8');\n }\n }\n}\n\n/**\n * Adds a failure entry to common-failures.md.\n * Updates existing entry if duplicate found, otherwise adds new.\n * Prunes entries older than 90 days and limits to 50 entries.\n */\nexport async function addFailureEntry(\n baseDir: string,\n options: FailureEntryOptions\n): Promise<void> {\n const filePath = path.join(baseDir, '.reygent', 'knowledge', 'common-failures.md');\n\n // Ensure file exists\n if (!(await pathExists(filePath))) {\n await ensureKnowledgeDir(baseDir);\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const timestamp = new Date().toISOString().split('T')[0];\n\n // Parse existing entries\n const entries = parseEntries(content);\n\n // Check for duplicate (same title and agent)\n const existingIndex = entries.findIndex(\n e => e.title === options.issue && e.agent === options.agent\n );\n\n if (existingIndex !== -1) {\n // Update existing entry\n const existing = entries[existingIndex];\n const newOccurrences = (existing.occurrences || 1) + 1;\n\n entries[existingIndex].fullContent = `\n## ${options.issue}\n**Occurrences**: ${newOccurrences} runs\n**Last seen**: ${timestamp}\n**Agent**: ${options.agent}\n\n**Solution**: ${options.solution}\n${\n options.example\n ? `\n**Example**:\n\\`\\`\\`\n${options.example}\n\\`\\`\\`\n`\n : ''\n}\n---\n`;\n entries[existingIndex].lastSeen = timestamp;\n entries[existingIndex].occurrences = newOccurrences;\n } else {\n // Add new entry\n entries.push({\n title: options.issue,\n occurrences: 1,\n lastSeen: timestamp,\n agent: options.agent,\n fullContent: `\n## ${options.issue}\n**Occurrences**: 1 run\n**Last seen**: ${timestamp}\n**Agent**: ${options.agent}\n\n**Solution**: ${options.solution}\n${\n options.example\n ? `\n**Example**:\n\\`\\`\\`\n${options.example}\n\\`\\`\\`\n`\n : ''\n}\n---\n`,\n });\n }\n\n // Prune old entries (90 days) and limit to 50\n let managedEntries = pruneOldEntries(entries, 90);\n managedEntries = limitEntries(managedEntries, 50);\n\n // Rebuild file\n const header = '# Common Failures\\n\\nThis file documents recurring errors and their solutions.\\n\\n---\\n';\n const newContent = header + managedEntries.map(e => e.fullContent).join('\\n');\n\n await fs.writeFile(filePath, newContent, 'utf8');\n}\n\n/**\n * Adds a success pattern entry to success-patterns.md.\n * Updates existing entry if duplicate found, otherwise adds new.\n * Prunes entries older than 60 days and limits to 30 entries.\n */\nexport async function addPatternEntry(\n baseDir: string,\n options: PatternEntryOptions\n): Promise<void> {\n const filePath = path.join(baseDir, '.reygent', 'knowledge', 'success-patterns.md');\n\n // Ensure file exists\n if (!(await pathExists(filePath))) {\n await ensureKnowledgeDir(baseDir);\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const timestamp = new Date().toISOString().split('T')[0];\n\n // Parse existing entries\n const entries = parseEntries(content);\n\n // Check for duplicate (same title)\n const existingIndex = entries.findIndex(e => e.title === options.description);\n\n if (existingIndex !== -1) {\n // Update existing entry\n entries[existingIndex].fullContent = `\n## ${options.description}\n**Last seen**: ${timestamp}\n${options.successRate ? `**Success rate**: ${options.successRate}%` : ''}\n\n${\n options.approach\n ? `**Approach**:\n${options.approach}\n`\n : ''\n}\n---\n`;\n entries[existingIndex].lastSeen = timestamp;\n if (options.successRate) {\n entries[existingIndex].successRate = options.successRate;\n }\n } else {\n // Add new entry\n entries.push({\n title: options.description,\n lastSeen: timestamp,\n successRate: options.successRate,\n fullContent: `\n## ${options.description}\n**Last seen**: ${timestamp}\n${options.successRate ? `**Success rate**: ${options.successRate}%` : ''}\n\n${\n options.approach\n ? `**Approach**:\n${options.approach}\n`\n : ''\n}\n---\n`,\n });\n }\n\n // Prune old entries (60 days) and limit to 30\n let managedEntries = pruneOldEntries(entries, 60);\n managedEntries = limitEntries(managedEntries, 30);\n\n // Rebuild file\n const header = '# Success Patterns\\n\\nThis file captures proven approaches that work well.\\n\\n---\\n';\n const newContent = header + managedEntries.map(e => e.fullContent).join('\\n');\n\n await fs.writeFile(filePath, newContent, 'utf8');\n}\n","import { createInterface } from \"node:readline\";\nimport chalk from \"chalk\";\nimport { resetTerminalForInput } from \"./terminal-reset.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { TaskError } from \"./task.js\";\nimport { isTestEnvironment } from \"./test-env.js\";\n\nexport interface RetryPromptOptions {\n /** Name of the task/gate that failed (e.g., \"unit tests\", \"dev agent\") */\n taskName: string;\n /** Current attempt number (1-indexed) */\n attempt: number;\n /** Maximum retry attempts configured (0 = disabled) */\n maxRetries: number;\n /** Skip prompts and auto-approve retries */\n autoApprove?: boolean;\n /** Telemetry event details */\n telemetry?: {\n stageName: string;\n agentName: string;\n };\n}\n\n/**\n * Shared retry prompt logic for gates and implement loops.\n *\n * Handles three scenarios:\n * 1. Test/non-interactive mode: throw immediately\n * 2. Exceeded max retries: prompt to continue or abort\n * 3. Within retry limit: prompt to retry or abort (unless auto-approved)\n *\n * @returns true if user wants to retry, throws TaskError if user declines or test mode\n */\nexport async function promptForRetry(options: RetryPromptOptions): Promise<boolean> {\n const { taskName, attempt, maxRetries, autoApprove = false, telemetry } = options;\n\n // No retries configured - throw immediately\n if (maxRetries === 0) {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed (retries disabled)`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed (retries disabled)`);\n }\n\n const exceededMax = attempt > maxRetries;\n\n // In test/non-interactive mode with exceeded retries, throw immediately\n if (exceededMax && (isTestEnvironment() || !process.stdin.isTTY)) {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed after ${maxRetries} retries`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed after ${maxRetries} retries`);\n }\n\n // Interactive mode with exceeded retries: prompt to continue\n if (exceededMax) {\n resetTerminalForInput();\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(`\\n${taskName} failed after ${maxRetries} retries. Continue retrying? (y/n) `),\n resolve,\n );\n });\n rl.close();\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed after ${maxRetries} retries`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed - user declined to retry after ${maxRetries} attempts`);\n }\n console.log(chalk.blue(\"\\nContinuing retries...\\n\"));\n return true;\n }\n\n // Not exceeded max yet: prompt if not auto-approved\n if (!autoApprove) {\n resetTerminalForInput();\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const attemptInfo = maxRetries > 0\n ? `(attempt ${attempt}/${maxRetries})`\n : `(attempt ${attempt})`;\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(`\\n${taskName} failed. Retry? ${attemptInfo} (y/n) `),\n resolve,\n );\n });\n rl.close();\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n console.log(chalk.red(\"Aborted by user.\"));\n process.exit(1);\n }\n }\n\n return true;\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { ExitPromptError } from \"@inquirer/core\";\nimport { select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { builtinAgents } from \"../agents.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport { isDebug } from \"../debug.js\";\nimport { DEFAULT_MODEL } from \"../model.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { ensureKnowledgeDir } from \"../knowledge/manager.js\";\n\nexport async function initCommand(options: { dryRun: boolean } = { dryRun: false }): Promise<void> {\n const targetDir = join(process.cwd(), \".reygent\");\n const configPath = join(targetDir, \"config.json\");\n\n const skillsDir = join(targetDir, \"skills\");\n\n const defaultConfig: ReygentConfig = {\n agents: builtinAgents,\n skills: { path: \"skills\" },\n model: DEFAULT_MODEL,\n };\n\n if (options.dryRun) {\n console.log(chalk.yellow.bold(\"[dry-run]\"), \"No changes will be made.\\n\");\n console.log(chalk.bold(\"Would create:\"));\n console.log(chalk.gray(\" dir: \"), chalk.cyan(targetDir));\n console.log(chalk.gray(\" dir: \"), chalk.cyan(skillsDir));\n console.log(chalk.gray(\" file: \"), chalk.cyan(configPath));\n console.log(\"\");\n console.log(chalk.bold(\"Config preview:\"));\n console.log(chalk.gray(JSON.stringify(defaultConfig, null, 2)));\n console.log(\"\");\n return;\n }\n\n try {\n if (existsSync(targetDir)) {\n console.log(chalk.yellow.bold(\"Warning:\"), `.reygent folder already exists`);\n console.log(chalk.gray(` Path: ${targetDir}\\n`));\n\n if (existsSync(configPath)) {\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"Cannot prompt in non-interactive mode. Use --dry-run to preview or remove existing .reygent/ first.\");\n process.exit(1);\n }\n resetTerminalForInput();\n const action = await select({\n message: \"Existing config found. What would you like to do?\",\n choices: [\n { name: \"Reset to defaults\", value: \"reset\" },\n { name: \"Edit config (reygent config)\", value: \"edit\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n });\n\n if (action === \"cancel\") {\n console.log(chalk.gray(\"No changes made.\\n\"));\n return;\n }\n\n if (action === \"edit\") {\n console.log(chalk.cyan(\"Run\"), chalk.bold(\"reygent config\"), chalk.cyan(\"to edit your configuration.\\n\"));\n return;\n }\n\n // action === \"reset\" — fall through to creation logic\n console.log(chalk.cyan(\"Resetting config to defaults...\\n\"));\n } else {\n console.log(chalk.cyan(\"No config.json found. Creating default config...\\n\"));\n }\n }\n\n const spinnerText = existsSync(targetDir) ? \"Writing config\" : \"Creating .reygent folder\";\n const spinner = ora(spinnerText).start();\n\n try {\n // Create folders\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n if (!existsSync(skillsDir)) {\n mkdirSync(skillsDir, { recursive: true });\n }\n\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2) + \"\\n\", \"utf-8\");\n\n spinner.text = \"Creating knowledge directory\";\n await ensureKnowledgeDir(process.cwd());\n\n // Create .gitignore for auto-generated files\n const gitignorePath = join(targetDir, \".gitignore\");\n const gitignoreContent = `# Auto-generated knowledge files (generated from local telemetry)\nknowledge/common-failures.md\nknowledge/success-patterns.md\n\n# Keep these files in source control:\n# - config.json (shared agent config)\n# - skills/ (custom team skills)\n# - knowledge/project-conventions.md (user-written rules)\n# - knowledge/agents/*.md (curated agent tips)\n`;\n writeFileSync(gitignorePath, gitignoreContent, \"utf-8\");\n\n spinner.succeed(chalk.green(\"Initialized .reygent folder\"));\n\n console.log(\"\");\n console.log(chalk.bold(\"Next steps:\"));\n console.log(chalk.gray(\" • Edit\"), chalk.cyan(\".reygent/config.json\"), chalk.gray(\"to customize agents\"));\n console.log(chalk.gray(\" • Add custom agents to the\"), chalk.cyan(\"agents\"), chalk.gray(\"array\"));\n console.log(chalk.gray(\" • Add skills to\"), chalk.cyan(\".reygent/skills/\"), chalk.gray(\"(each in its own folder with SKILL.md)\"));\n console.log(chalk.gray(\" • Populate\"), chalk.cyan(\".reygent/knowledge/\"), chalk.gray(\"with project conventions\"));\n console.log(chalk.gray(\" • Run\"), chalk.cyan(\"reygent agent <name>\"), chalk.gray(\"to use your local config\"));\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed: ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n } catch (err) {\n // Ctrl+C from inquirer\n if (err instanceof ExitPromptError) {\n console.log(chalk.yellow(\"\\nInitialization cancelled.\"));\n process.exit(0);\n }\n throw err;\n }\n}\n","import { Command } from \"commander\";\nimport { existsSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { validateSkillName } from \"../skills.js\";\nimport { resolveGlobalConfigDir, resolveSkillsDir } from \"../config.js\";\nimport {\n listRemoteSkills,\n fetchSkillManifest,\n fetchSkillFiles,\n checkCompatibility,\n} from \"../registry.js\";\nimport { isDebug } from \"../debug.js\";\n\nfunction getVersion(): string {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n return pkg.version;\n}\n\nfunction scanInstalledDir(dir: string, names: Set<string>): void {\n if (!existsSync(dir)) return;\n try {\n for (const entry of readdirSync(dir)) {\n const entryPath = join(dir, entry);\n try {\n if (statSync(entryPath).isDirectory() && existsSync(join(entryPath, \"SKILL.md\"))) {\n names.add(entry);\n }\n } catch { /* skip */ }\n }\n } catch { /* skip */ }\n}\n\nfunction getInstalledSkillNames(): Set<string> {\n const names = new Set<string>();\n const localDir = resolveSkillsDir(\"local\");\n if (localDir) scanInstalledDir(localDir, names);\n const globalDir = resolveSkillsDir(\"global\");\n if (globalDir) scanInstalledDir(globalDir, names);\n return names;\n}\n\nasync function listAction(): Promise<void> {\n const spinner = ora(\"Fetching skills from registry...\").start();\n\n try {\n const skills = await listRemoteSkills();\n const installed = getInstalledSkillNames();\n\n spinner.succeed(chalk.green(`Found ${skills.length} skill${skills.length !== 1 ? \"s\" : \"\"}`));\n console.log(\"\");\n\n if (skills.length === 0) {\n console.log(chalk.gray(\" No skills available in registry.\"));\n console.log(\"\");\n return;\n }\n\n for (const skill of skills) {\n const badge = installed.has(skill.name) ? chalk.green(\" [installed]\") : \"\";\n const version = skill.version ? chalk.gray(` v${skill.version}`) : \"\";\n console.log(` ${chalk.bold.cyan(skill.name)}${version}${badge}`);\n console.log(` ${skill.description}`);\n if (skill.license) {\n console.log(` ${chalk.gray(`License: ${skill.license}`)}`);\n }\n console.log(\"\");\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to fetch skills: ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n\nasync function addAction(name: string, options: { global: boolean }): Promise<void> {\n if (!validateSkillName(name)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid skill name \"${name}\"`);\n process.exit(1);\n }\n\n // Resolve target directory\n let targetBase: string;\n if (options.global) {\n targetBase = join(resolveGlobalConfigDir(), \"skills\");\n } else {\n const localSkillsDir = resolveSkillsDir(\"local\");\n if (!localSkillsDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n console.log(chalk.gray(\" Run\"), chalk.cyan(\"reygent init\"), chalk.gray(\"first, or use\"), chalk.cyan(\"--global\"));\n process.exit(1);\n }\n targetBase = localSkillsDir;\n }\n\n const targetDir = join(targetBase, name);\n\n if (existsSync(targetDir)) {\n console.log(chalk.red.bold(\"Error:\"), `Skill \"${name}\" already installed at ${targetDir}`);\n process.exit(1);\n }\n\n const spinner = ora(`Installing ${name}...`).start();\n\n try {\n // Fetch manifest for compatibility check\n spinner.text = `Checking compatibility for ${name}...`;\n const manifest = await fetchSkillManifest(name);\n const version = getVersion();\n const compatible = checkCompatibility(manifest.compatibility, version);\n\n if (!compatible) {\n spinner.warn(\n chalk.yellow(`Skill \"${name}\" requires ${manifest.compatibility}, you have v${version}`),\n );\n console.log(chalk.yellow(\" Installing anyway — some features may not work.\\n\"));\n spinner.start(`Downloading ${name}...`);\n }\n\n // Fetch all files\n spinner.text = `Downloading ${name}...`;\n const files = await fetchSkillFiles(name);\n\n // Write files\n spinner.text = `Writing files...`;\n for (const file of files) {\n const filePath = join(targetDir, file.path);\n const fileDir = dirname(filePath);\n mkdirSync(fileDir, { recursive: true });\n writeFileSync(filePath, file.content, \"utf-8\");\n }\n\n spinner.succeed(chalk.green(`Installed \"${name}\" (${files.length} files)`));\n console.log(\"\");\n console.log(chalk.gray(\" Location:\"), chalk.cyan(targetDir));\n console.log(chalk.gray(\" Usage: \"), chalk.cyan(`reygent agent ${name}`));\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to install \"${name}\": ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n\nasync function removeAction(name: string, options: { global: boolean }): Promise<void> {\n if (!validateSkillName(name)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid skill name \"${name}\"`);\n process.exit(1);\n }\n\n let targetBase: string;\n if (options.global) {\n targetBase = join(resolveGlobalConfigDir(), \"skills\");\n } else {\n const localSkillsDir = resolveSkillsDir(\"local\");\n if (!localSkillsDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n process.exit(1);\n }\n targetBase = localSkillsDir;\n }\n\n const targetDir = join(targetBase, name);\n\n if (!existsSync(targetDir)) {\n console.log(chalk.red.bold(\"Error:\"), `Skill \"${name}\" not found at ${targetDir}`);\n process.exit(1);\n }\n\n try {\n rmSync(targetDir, { recursive: true, force: true });\n console.log(chalk.green(`Removed \"${name}\" from ${targetDir}`));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Error:\"), `Failed to remove \"${name}\": ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(1);\n }\n}\n\nexport function registerSkillsCommand(program: Command): void {\n const skills = program\n .command(\"skills\")\n .description(\"Manage skills from the reygent-skills registry\");\n\n skills\n .command(\"list\")\n .description(\"List available skills in the registry\")\n .action(listAction);\n\n skills\n .command(\"add\")\n .description(\"Install a skill from the registry\")\n .argument(\"<name>\", \"Skill name to install\")\n .option(\"--global\", \"Install to ~/.reygent/skills/ instead of local\", false)\n .action(addAction);\n\n skills\n .command(\"remove\")\n .description(\"Remove an installed skill\")\n .argument(\"<name>\", \"Skill name to remove\")\n .option(\"--global\", \"Remove from ~/.reygent/skills/ instead of local\", false)\n .action(removeAction);\n}\n","import { execFileSync } from \"node:child_process\";\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n mkdirSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseSkillMd } from \"./skills.js\";\nimport type { SkillManifest } from \"./skills.js\";\nimport { resolveGlobalConfigDir } from \"./config.js\";\n\nconst REGISTRY_REPO_URL = \"https://github.com/andrewevans0102/reygent-skills.git\";\n\nexport interface RegistrySkillEntry {\n name: string;\n description: string;\n license?: string;\n compatibility?: string;\n version?: string;\n}\n\nexport interface SkillFile {\n path: string;\n content: string;\n}\n\n/**\n * Path to the local registry cache directory.\n */\nfunction getCacheDir(): string {\n return join(resolveGlobalConfigDir(), \"cache\", \"registry\");\n}\n\n/**\n * Run a git command, throwing a clear error if git is not installed.\n */\nfunction runGit(args: string[], cwd?: string): string {\n try {\n return execFileSync(\"git\", args, {\n cwd,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n } catch (err: unknown) {\n const error = err as NodeJS.ErrnoException;\n if (error.code === \"ENOENT\") {\n throw new Error(\n \"Git is not installed or not found in PATH. Install git to use the skills registry.\",\n );\n }\n throw err;\n }\n}\n\n/**\n * Ensure registry cache exists and is up to date.\n * Always attempts a fresh pull when called — this should only be\n * triggered by explicit user interaction (skills list/add/remove).\n * Falls back to stale cache if pull fails (offline, etc.).\n */\nfunction ensureCache(): string {\n const cacheDir = getCacheDir();\n const gitDir = join(cacheDir, \".git\");\n\n if (!existsSync(gitDir)) {\n // First time — clone\n const parentDir = join(cacheDir, \"..\");\n mkdirSync(parentDir, { recursive: true });\n runGit([\"clone\", \"--depth\", \"1\", REGISTRY_REPO_URL, cacheDir]);\n return cacheDir;\n }\n\n // Pull latest on every explicit skills command\n try {\n runGit([\"pull\", \"--ff-only\"], cacheDir);\n } catch {\n // Offline or conflict — use existing cache silently\n }\n\n return cacheDir;\n}\n\n/**\n * List all skills available in the remote registry.\n */\nexport async function listRemoteSkills(): Promise<RegistrySkillEntry[]> {\n const cacheDir = ensureCache();\n const entries = readdirSync(cacheDir);\n const skills: RegistrySkillEntry[] = [];\n\n for (const entry of entries) {\n if (entry.startsWith(\".\")) continue;\n\n const entryPath = join(cacheDir, entry);\n if (!statSync(entryPath).isDirectory()) continue;\n\n const skillMdPath = join(entryPath, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const content = readFileSync(skillMdPath, \"utf-8\");\n const manifest = parseSkillMd(content, entry);\n skills.push({\n name: manifest.name,\n description: manifest.description,\n license: manifest.license,\n compatibility: manifest.compatibility,\n version: manifest.metadata?.version,\n });\n } catch {\n // Skip skills with invalid SKILL.md\n }\n }\n\n return skills;\n}\n\n/**\n * Fetch SKILL.md manifest for a single skill.\n */\nexport async function fetchSkillManifest(skillName: string): Promise<SkillManifest> {\n const cacheDir = ensureCache();\n const skillMdPath = join(cacheDir, skillName, \"SKILL.md\");\n\n if (!existsSync(skillMdPath)) {\n throw new Error(`Skill not found in registry: ${skillName}`);\n }\n\n const content = readFileSync(skillMdPath, \"utf-8\");\n return parseSkillMd(content, skillName);\n}\n\n/**\n * Fetch all files for a skill, recursing into subdirectories.\n */\nexport async function fetchSkillFiles(skillName: string): Promise<SkillFile[]> {\n const cacheDir = ensureCache();\n const skillDir = join(cacheDir, skillName);\n\n if (!existsSync(skillDir) || !statSync(skillDir).isDirectory()) {\n throw new Error(`Skill not found in registry: ${skillName}`);\n }\n\n const files: SkillFile[] = [];\n\n function walkDir(dir: string, prefix: string): void {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n if (entry.startsWith(\".\")) continue;\n const fullPath = join(dir, entry);\n const relativePath = prefix ? `${prefix}/${entry}` : entry;\n\n if (statSync(fullPath).isDirectory()) {\n walkDir(fullPath, relativePath);\n } else {\n files.push({\n path: relativePath,\n content: readFileSync(fullPath, \"utf-8\"),\n });\n }\n }\n }\n\n walkDir(skillDir, \"\");\n return files;\n}\n\n/**\n * Check if a compatibility string (e.g. \">=0.1.0\") is satisfied by reygentVersion.\n * Only supports >=X.Y.Z format. Undefined compatibility = always compatible.\n */\nexport function checkCompatibility(\n compatibility: string | undefined,\n reygentVersion: string,\n): boolean {\n if (!compatibility) return true;\n\n const match = compatibility.match(/^>=\\s*(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return true; // Unknown format — assume compatible\n\n const [, reqMajor, reqMinor, reqPatch] = match.map(Number);\n const verMatch = reygentVersion.match(/^(\\d+)\\.(\\d+)\\.(\\d+)/);\n if (!verMatch) return true;\n\n const [, curMajor, curMinor, curPatch] = verMatch.map(Number);\n\n if (curMajor !== reqMajor) return curMajor > reqMajor;\n if (curMinor !== reqMinor) return curMinor > reqMinor;\n return curPatch >= reqPatch;\n}\n","import { execFile } from \"node:child_process\";\nimport { request as httpsRequest } from \"node:https\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { getAgents } from \"../config.js\";\nimport { spawnAgent } from \"../implement.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { isDebug } from \"../debug.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport type { ActivityEvent } from \"../providers/types.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { parseRemote, resolveToken } from \"../pr-create.js\";\nimport type { RemoteInfo } from \"../pr-create.js\";\nimport {\n runPRReview,\n postPRReviewComment,\n extractPRReviewOutput,\n formatPRReviewTerminal,\n formatPRReviewOutput,\n} from \"../pr-review.js\";\nimport type { PRReviewOutput, TaskContext } from \"../task.js\";\nimport { TaskError } from \"../task.js\";\nimport { parseSpecWithPrefix, SpecPrefixError } from \"../spec-prefix.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n RESERVED_PROMPT_TOKENS,\n} from \"../diff-split.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { Events } from \"../chesstrace/events.js\";\n\ninterface ReviewWorkOptions {\n spec?: string;\n /**\n * Skip SSL certificate verification for API calls.\n * Note: Only applies to GitLab MR detection/posting via HTTPS API.\n * Does not affect gh CLI operations (GitHub PR workflow).\n */\n insecure?: boolean;\n}\n\nfunction exec(\n cmd: string,\n args: string[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 50 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `review-work: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nasync function getCurrentBranch(): Promise<string> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch || !branch.trim()) {\n throw new TaskError(\"review-work: not on a branch (detached HEAD?)\");\n }\n return branch;\n}\n\nasync function getDefaultBranch(): Promise<string> {\n try {\n const ref = (\n await exec(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"])\n ).trim();\n return ref.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: check for common defaults\n try {\n const branches = (\n await exec(\"git\", [\"branch\", \"-r\", \"--list\", \"origin/main\", \"origin/master\"])\n ).trim();\n const match = branches.match(/origin\\/(main|master)/);\n if (match) return match[1];\n } catch {\n // ignore\n }\n return \"main\";\n }\n}\n\nasync function detectGitHubPR(): Promise<number | null> {\n try {\n const json = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number\",\n \"--jq\",\n \".number\",\n ]);\n const num = parseInt(json.trim(), 10);\n return isNaN(num) || num <= 0 ? null : num;\n } catch {\n return null;\n }\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n}\n\nfunction httpsGet(\n url: string,\n headers: Record<string, string>,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"GET\",\n headers,\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nfunction httpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, \"utf-8\");\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"POST\",\n headers: { ...headers, \"Content-Length\": bodyBuf.byteLength },\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.write(bodyBuf);\n req.end();\n });\n}\n\nasync function detectGitLabMR(\n remote: RemoteInfo,\n token: string,\n branch: string,\n insecure?: boolean,\n): Promise<number | null> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const encodedBranch = encodeURIComponent(branch);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests?source_branch=${encodedBranch}&state=opened`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n try {\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) return null;\n const mrs = JSON.parse(text) as Array<{ iid: number }>;\n return mrs.length > 0 ? mrs[0].iid : null;\n } catch {\n return null;\n }\n}\n\nasync function getGitDiff(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"diff\", `${baseBranch}...HEAD`]);\n}\n\nasync function getGitStat(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"diff\", \"--stat\", `${baseBranch}...HEAD`]);\n}\n\nasync function getGitLog(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"log\", `${baseBranch}..HEAD`, \"--oneline\"]);\n}\n\nasync function postGitLabComment(\n remote: RemoteInfo,\n token: string,\n mrIid: number,\n body: string,\n insecure?: boolean,\n): Promise<void> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests/${mrIid}/notes`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n const { status, text } = await httpsPost(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n JSON.stringify({ body }),\n tlsOpts,\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`review-work: GitLab API error ${status}: ${text}`);\n }\n}\n\ninterface ReviewPromptInput {\n stat: string;\n log: string;\n includedDiffs: { file: string; diff: string }[];\n excludedFiles: string[];\n spec?: { title: string; content: string };\n}\n\nfunction buildReviewPrompt(\n systemPrompt: string,\n input: ReviewPromptInput,\n): string {\n let prompt = systemPrompt;\n\n if (input.spec) {\n prompt += `\n\n---\n\n## Spec\n\n**Title:** ${input.spec.title}\n\n${input.spec.content}\n\n---`;\n }\n\n prompt += `\n\n## Branch Summary\n\n### Changed Files\n\n\\`\\`\\`\n${input.stat}\n\\`\\`\\`\n\n### Commits\n\n\\`\\`\\`\n${input.log}\n\\`\\`\\``;\n\n if (input.includedDiffs.length > 0) {\n prompt += `\n\n## File Diffs\n\n`;\n for (const f of input.includedDiffs) {\n prompt += `\\`\\`\\`diff\n${f.diff}\n\\`\\`\\`\n\n`;\n }\n }\n\n if (input.excludedFiles.length > 0) {\n prompt += `\n### Files not shown (${input.excludedFiles.length} excluded due to size)\n\n${input.excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n }\n\n prompt += `\n\n---\n\n## Instructions\n\n1. Review the changes above${input.spec ? \" in the context of the spec\" : \"\"}.\n2. Check for correctness, potential bugs, style issues${input.spec ? \", and whether the implementation meets the spec\" : \"\"}.\n3. For files not shown, note any concerns based on the stat summary and commit messages.\n4. When you are finished, output a single JSON block with your review:\n\n\\`\\`\\`json\n{\n \"summary\": \"Brief overall assessment of the PR\",\n \"comments\": [\n {\n \"file\": \"src/example.ts\",\n \"line\": 42,\n \"comment\": \"Description of the issue or suggestion\"\n }\n ],\n \"recommendedActions\": [\n \"Action item 1\",\n \"Action item 2\"\n ]\n}\n\\`\\`\\`\n\n- \\`summary\\` is a brief overall assessment of the PR.\n- \\`comments\\` is an array of inline review comments. \\`line\\` may be null if the comment applies to the whole file.\n- \\`recommendedActions\\` is a list of suggested follow-up actions.\n- Do NOT output any text after the JSON block.`;\n\n return prompt;\n}\n\nasync function runAgentReview(\n baseBranch: string,\n spec?: { title: string; content: string },\n onActivity?: (event: ActivityEvent) => void,\n): Promise<PRReviewOutput> {\n const agents = getAgents();\n const agent = agents.find((a) => a.role === \"reviewer\");\n if (!agent) {\n throw new TaskError(\"review-work: no agent with role 'reviewer' found in config\");\n }\n\n const [diff, stat, log] = await Promise.all([\n getGitDiff(baseBranch),\n getGitStat(baseBranch),\n getGitLog(baseBranch),\n ]);\n\n if (!diff.trim()) {\n throw new TaskError(\"review-work: no changes found\");\n }\n\n // Split diff by file and select within budget\n const fileDiffs = splitDiffByFile(diff);\n const reservedTokens = estimateTokens(agent.systemPrompt) + estimateTokens(stat) + estimateTokens(log) + RESERVED_PROMPT_TOKENS;\n const { included, excluded } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens);\n\n // Debug logging and telemetry for diff budget decisions\n const totalDiffTokens = included.reduce((sum, f) => sum + f.tokens, 0);\n const excludedTokens = fileDiffs.filter(f => excluded.includes(f.file)).reduce((sum, f) => sum + f.tokens, 0);\n const availableTokens = MAX_REVIEW_TOKENS - reservedTokens;\n\n if (isDebug()) {\n console.log(\n `[DEBUG] Diff budget: ${totalDiffTokens}/${availableTokens} tokens used ` +\n `(${included.length}/${fileDiffs.length} files included, ${excluded.length} excluded for ${excludedTokens} tokens)`\n );\n if (excluded.length > 0) {\n console.log(`[DEBUG] Excluded files: ${excluded.join(\", \")}`);\n }\n }\n\n // Emit telemetry event\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.REVIEW_DIFF_BUDGET, {\n filesIncluded: included.length,\n filesExcluded: excluded.length,\n tokensUsed: totalDiffTokens,\n tokensAvailable: availableTokens,\n excludedFilesList: excluded,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n const prompt = buildReviewPrompt(agent.systemPrompt, {\n stat: stat.trim(),\n log: log.trim(),\n includedDiffs: included,\n excludedFiles: excluded,\n spec,\n });\n const result = await spawnAgent(\"pr-review\", prompt, { quiet: true, onActivity, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `review-work: agent exited with code ${result.exitCode}`,\n );\n }\n\n return extractPRReviewOutput(result.stdout);\n}\n\nexport async function reviewWorkCommand(\n options: ReviewWorkOptions,\n): Promise<void> {\n try {\n // Verify we're in a git repo\n try {\n await exec(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"]);\n } catch {\n console.log(chalk.red.bold(\"Error:\"), \"Not inside a git repository.\");\n process.exit(1);\n }\n\n loadEnvFile();\n\n // Load spec if provided\n let spec: { title: string; content: string } | undefined;\n if (options.spec) {\n const spinner = ora(\"Loading spec...\").start();\n try {\n const parsed = parseSpecWithPrefix(options.spec);\n const loaded = await loadSpec(parsed.identifier, parsed.provider);\n spec = { title: loaded.title, content: loaded.content };\n spinner.succeed(chalk.green(`Spec loaded: ${loaded.title}`));\n } catch (err) {\n spinner.fail(chalk.red(\"Failed to load spec\"));\n throw err;\n }\n }\n\n // Detect platform\n const remoteUrl = (\n await exec(\"git\", [\"remote\", \"get-url\", \"origin\"])\n ).trim();\n const remote = parseRemote(remoteUrl);\n const branch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n console.log(\n chalk.gray(` Platform: ${remote.platform}`) +\n chalk.gray(` | Branch: ${branch}`) +\n chalk.gray(` | Base: ${defaultBranch}`),\n );\n console.log();\n\n if (remote.platform === \"github\") {\n // GitHub path\n const spinner = ora(\"Checking for open PR...\").start();\n const prNumber = await detectGitHubPR();\n\n if (prNumber !== null) {\n spinner.succeed(chalk.green(`Found PR #${prNumber}`));\n\n // Build minimal TaskContext for runPRReview\n const context: TaskContext = {\n spec: spec\n ? { source: \"markdown\" as const, title: spec.title, content: spec.content }\n : { source: \"markdown\" as const, title: \"Review\", content: \"\" },\n prCreate: {\n branch,\n commitMessage: \"\",\n prUrl: \"\",\n prNumber,\n },\n results: [],\n };\n\n console.log();\n const prReviewStatus = createLiveStatus(\"Running PR review...\");\n const { output } = await runPRReview(context, { quiet: true, onActivity: prReviewStatus.onActivity });\n prReviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n\n const postSpinner = ora(\"Posting review comment to PR...\").start();\n try {\n await postPRReviewComment(context, output);\n postSpinner.succeed(chalk.green(`Review posted to PR #${prNumber}`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n postSpinner.fail(chalk.red(`Failed to post comment: ${msg}`));\n }\n } else {\n spinner.info(chalk.yellow(\"No open PR found for this branch\"));\n console.log();\n\n const reviewStatus = createLiveStatus(\"Running review...\");\n let output: PRReviewOutput;\n try {\n output = await runAgentReview(defaultBranch, spec, reviewStatus.onActivity);\n } catch (err) {\n if (err instanceof TaskError && err.message.includes(\"no changes found\")) {\n reviewStatus.stop();\n console.log(chalk.yellow(\"No changes found against\"), chalk.bold(defaultBranch));\n return;\n }\n throw err;\n }\n reviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n console.log(chalk.gray(\"No PR found — review printed to console only.\"));\n }\n } else {\n // GitLab path\n const spinner = ora(\"Checking for open MR...\").start();\n let token: string;\n try {\n token = await resolveToken(remote.host);\n } catch (err) {\n if (isDebug()) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(chalk.gray(`[debug] Token resolution failed: ${msg}`));\n }\n spinner.info(chalk.yellow(\"Could not resolve GitLab token — skipping MR detection\"));\n token = \"\";\n }\n\n const mrIid = token\n ? await detectGitLabMR(remote, token, branch, options.insecure)\n : null;\n\n if (mrIid !== null) {\n spinner.succeed(chalk.green(`Found MR !${mrIid}`));\n } else {\n spinner.info(chalk.yellow(\"No open MR found for this branch\"));\n }\n\n console.log();\n const glReviewStatus = createLiveStatus(\"Running review...\");\n let output: PRReviewOutput;\n try {\n output = await runAgentReview(defaultBranch, spec, glReviewStatus.onActivity);\n } catch (err) {\n if (err instanceof TaskError && err.message.includes(\"no changes found\")) {\n glReviewStatus.stop();\n console.log(chalk.yellow(\"No changes found against\"), chalk.bold(defaultBranch));\n return;\n }\n throw err;\n }\n glReviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n\n if (mrIid !== null && token) {\n const postSpinner = ora(\"Posting review comment to MR...\").start();\n try {\n const body =\n formatPRReviewOutput(output) +\n \"\\n\\n---\\n*Review by [reygent](https://github.com/andrewevans0102/reygent)*\";\n await postGitLabComment(remote, token, mrIid, body, options.insecure);\n postSpinner.succeed(chalk.green(`Review posted to MR !${mrIid}`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n postSpinner.fail(chalk.red(`Failed to post comment: ${msg}`));\n }\n } else {\n console.log(chalk.gray(\"No MR found — review printed to console only.\"));\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof SpecPrefixError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n","import { SpecProvider } from \"./spec.js\";\n\nexport class SpecPrefixError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecPrefixError\";\n }\n}\n\nexport interface ParsedSpecSource {\n provider: SpecProvider;\n identifier: string;\n}\n\nexport const VALID_PREFIXES = [\"jira:\", \"linear:\", \"markdown:\"] as const;\n\n/**\n * Parse spec source with required provider prefix.\n * Format: <provider>:<source>\n *\n * Examples:\n * jira:ENG-123\n * linear:DT-275\n * markdown:./test-spec.md\n *\n * Auto-infers markdown: for file paths ending in .md or starting with ./ or /\n */\nexport function parseSpecWithPrefix(input: string): ParsedSpecSource {\n // Check for explicit prefix first\n const colonIndex = input.indexOf(\":\");\n if (colonIndex !== -1) {\n const prefix = input.substring(0, colonIndex + 1);\n const identifier = input.substring(colonIndex + 1);\n\n if (!identifier.trim()) {\n throw new SpecPrefixError(`Empty source after \"${prefix}\" prefix`);\n }\n\n switch (prefix) {\n case \"jira:\":\n return { provider: \"jira\", identifier };\n case \"linear:\":\n return { provider: \"linear\", identifier };\n case \"markdown:\":\n return { provider: \"local\", identifier };\n default:\n throw new SpecPrefixError(\n `Invalid prefix \"${prefix}\". Must be one of: ${VALID_PREFIXES.join(\", \")}`\n );\n }\n }\n\n // Auto-infer markdown: prefix for file paths\n if (isFilePath(input)) {\n return { provider: \"local\", identifier: input };\n }\n\n // No prefix and not a file path\n throw new SpecPrefixError(\n `Source prefix required. Valid formats:\\n` +\n ` jira:PROJ-123\\n` +\n ` linear:DT-275\\n` +\n ` markdown:./spec.md\\n` +\n `Or use file path (ends in .md or starts with ./ or /)`\n );\n}\n\n/**\n * Check if input looks like a file path.\n * Returns true for:\n * - Paths ending in .md or .markdown (case insensitive)\n * - Paths starting with ./ or /\n */\nfunction isFilePath(input: string): boolean {\n if (/\\.(md|markdown)$/i.test(input)) return true;\n if (input.startsWith(\"./\") || input.startsWith(\"/\")) return true;\n return false;\n}\n","import { execFile } from \"node:child_process\";\nimport { request as httpsRequest } from \"node:https\";\nimport chalk from \"chalk\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { wrapText } from \"../format.js\";\nimport { getAgents } from \"../config.js\";\nimport { spawnAgent } from \"../implement.js\";\nimport { extractJSON } from \"../planner.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport type { ActivityEvent } from \"../live-status.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { isDebug } from \"../debug.js\";\nimport { parseRemote, resolveToken } from \"../pr-create.js\";\nimport type { RemoteInfo } from \"../pr-create.js\";\nimport type { PlannerOutput } from \"../task.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n RESERVED_PROMPT_TOKENS,\n} from \"../diff-split.js\";\nimport type { FileDiff } from \"../diff-split.js\";\n\ninterface ReviewCommentsOptions {\n insecure?: boolean;\n autoApprove?: boolean;\n retryCommits?: number;\n}\n\ninterface ReviewComment {\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt: string;\n}\n\ninterface ClassifiedComment extends ReviewComment {\n isSecurity: boolean;\n}\n\n// ── Security comment classification ──\n\n// Primary keywords: high-confidence security signals — any single match triggers isSecurity\nconst PRIMARY_SECURITY_KEYWORDS = [\n \"xss\", \"cross-site scripting\", \"csrf\", \"cross-site request forgery\",\n \"sql injection\", \"sqli\", \"command injection\", \"code injection\",\n \"path traversal\", \"directory traversal\",\n \"ssrf\", \"server-side request forgery\",\n \"xxe\", \"rce\", \"remote code execution\",\n \"deserialization\", \"idor\",\n \"auth bypass\",\n \"privilege escalation\", \"broken access control\",\n \"session fixation\", \"session hijacking\",\n \"token expir\", \"token leak\",\n \"hardcoded secret\", \"hardcoded password\", \"hardcoded key\",\n \"api key\", \"credential\", \"plaintext password\",\n \"weak hash\", \"md5\", \"sha1\",\n \"insecure random\", \"math.random\",\n \"sanitiz\", \"unsanitized\", \"unescaped\",\n \"untrusted input\", \"tainted\",\n \"innerhtml\", \"dangerouslysetinnerhtml\", \"eval(\",\n \"content-security-policy\", \"csp\",\n \"security header\", \"httponly\", \"secure flag\",\n \"vulnerability\", \"exploit\", \"attack vector\",\n \"owasp\", \"cve\", \"cwe\",\n \"security risk\", \"security issue\", \"security concern\",\n \"security review\", \"security finding\",\n \"denial of service\",\n \"information disclosure\", \"data leak\", \"data exposure\",\n \"sensitive data\",\n];\n\n// Secondary keywords: broad terms that only flag when 2+ secondaries co-occur\n// or when paired with at least 1 primary keyword\nconst SECONDARY_SECURITY_KEYWORDS = [\n \"authentication\", \"authorization\",\n \"jwt\", \"cors\",\n \"dos\", \"race condition\",\n];\n\nfunction classifyComment(body: string): boolean {\n const lower = body.toLowerCase();\n\n const hasPrimary = PRIMARY_SECURITY_KEYWORDS.some((kw) => lower.includes(kw));\n if (hasPrimary) return true;\n\n const secondaryMatches = SECONDARY_SECURITY_KEYWORDS.filter((kw) =>\n lower.includes(kw),\n );\n\n // Require 2+ secondary keywords to co-occur\n return secondaryMatches.length >= 2;\n}\n\nfunction classifyComments(comments: ReviewComment[]): ClassifiedComment[] {\n return comments.map((c) => ({\n ...c,\n isSecurity: classifyComment(c.body),\n }));\n}\n\n// ── Private helpers (self-contained, matches review-work.ts convention) ──\n\nfunction exec(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 50 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `review-comments: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || stdout || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nasync function getCurrentBranch(): Promise<string> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch) {\n throw new TaskError(\"review-comments: not on a branch (detached HEAD?)\");\n }\n return branch;\n}\n\nasync function getDefaultBranch(): Promise<string> {\n try {\n const ref = (\n await exec(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"])\n ).trim();\n return ref.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n try {\n const branches = (\n await exec(\"git\", [\"branch\", \"-r\", \"--list\", \"origin/main\", \"origin/master\"])\n ).trim();\n const match = branches.match(/origin\\/(main|master)/);\n if (match) return match[1];\n } catch {\n // ignore\n }\n return \"main\";\n }\n}\n\nasync function detectGitHubPR(): Promise<number | null> {\n try {\n const json = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number\",\n \"--jq\",\n \".number\",\n ]);\n const num = parseInt(json.trim(), 10);\n return isNaN(num) || num <= 0 ? null : num;\n } catch {\n return null;\n }\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n}\n\nfunction httpsGet(\n url: string,\n headers: Record<string, string>,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"GET\",\n headers,\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nasync function detectGitLabMR(\n remote: RemoteInfo,\n token: string,\n branch: string,\n insecure?: boolean,\n): Promise<number | null> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const encodedBranch = encodeURIComponent(branch);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests?source_branch=${encodedBranch}&state=opened`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n try {\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) return null;\n const mrs = JSON.parse(text) as Array<{ iid: number }>;\n return mrs.length > 0 ? mrs[0].iid : null;\n } catch {\n return null;\n }\n}\n\n// ── Comment fetching ──\n\nasync function fetchGitHubComments(): Promise<ReviewComment[]> {\n const raw = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"comments,reviews\",\n ]);\n const data = JSON.parse(raw) as {\n comments?: Array<{\n author?: { login?: string };\n body?: string;\n createdAt?: string;\n }>;\n reviews?: Array<{\n author?: { login?: string };\n body?: string;\n state?: string;\n createdAt?: string;\n comments?: Array<{\n author?: { login?: string };\n body?: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }>;\n }>;\n };\n\n const comments: ReviewComment[] = [];\n\n // Issue-level comments\n if (data.comments) {\n for (const c of data.comments) {\n if (!c.body?.trim()) continue;\n comments.push({\n author: c.author?.login ?? \"unknown\",\n body: c.body,\n createdAt: c.createdAt ?? \"\",\n });\n }\n }\n\n // Review-level: top-level review body + inline comments\n if (data.reviews) {\n for (const r of data.reviews) {\n if (r.body?.trim()) {\n comments.push({\n author: r.author?.login ?? \"unknown\",\n body: r.body,\n createdAt: r.createdAt ?? \"\",\n });\n }\n if (r.comments) {\n for (const ic of r.comments) {\n if (!ic.body?.trim()) continue;\n comments.push({\n author: ic.author?.login ?? r.author?.login ?? \"unknown\",\n body: ic.body,\n path: ic.path,\n line: ic.line,\n createdAt: ic.createdAt ?? \"\",\n });\n }\n }\n }\n }\n\n return comments;\n}\n\nasync function fetchGitLabComments(\n remote: RemoteInfo,\n token: string,\n mrIid: number,\n insecure?: boolean,\n): Promise<ReviewComment[]> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests/${mrIid}/notes?per_page=100`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`review-comments: GitLab API error ${status}: ${text}`);\n }\n\n const notes = JSON.parse(text) as Array<{\n author?: { username?: string };\n body?: string;\n system?: boolean;\n created_at?: string;\n position?: {\n new_path?: string;\n new_line?: number | null;\n };\n }>;\n\n const comments: ReviewComment[] = [];\n for (const n of notes) {\n // Skip system-generated notes\n if (n.system) continue;\n if (!n.body?.trim()) continue;\n\n comments.push({\n author: n.author?.username ?? \"unknown\",\n body: n.body,\n path: n.position?.new_path,\n line: n.position?.new_line,\n createdAt: n.created_at ?? \"\",\n });\n }\n\n return comments;\n}\n\n// ── Display ──\n\nfunction displayCommentSummary(comments: ClassifiedComment[]): void {\n const securityCount = comments.filter((c) => c.isSecurity).length;\n const generalCount = comments.length - securityCount;\n\n console.log(chalk.bold(` ${comments.length} review comment(s) found`));\n if (securityCount > 0) {\n console.log(\n chalk.yellow(` ⚠ ${securityCount} security-related`) +\n chalk.gray(` | ${generalCount} general`),\n );\n }\n console.log();\n\n for (const c of comments) {\n const location = c.path\n ? chalk.cyan(` ${c.path}${c.line ? `:${c.line}` : \"\"}`)\n : chalk.gray(\" (general)\");\n const tag = c.isSecurity ? chalk.bgYellow.black(\" SEC \") + \" \" : \"\";\n console.log(` ${tag}${chalk.bold(c.author)} ${location}`);\n\n // Truncate long comments for summary display\n const cols = process.stdout.columns || 80;\n const preview = c.body.length > 200\n ? c.body.slice(0, 200) + \"...\"\n : c.body;\n for (const line of preview.split(\"\\n\")) {\n console.log(chalk.gray(` ${wrapText(line, 4, cols)}`));\n }\n console.log();\n }\n}\n\n// ── Plan generation ──\n\nfunction formatCommentBlock(comments: ClassifiedComment[]): string {\n const securityComments = comments.filter((c) => c.isSecurity);\n const generalComments = comments.filter((c) => !c.isSecurity);\n\n const formatOne = (c: ClassifiedComment) => {\n const loc = c.path ? `File: ${c.path}${c.line ? `:${c.line}` : \"\"}` : \"General\";\n return `- **${c.author}** (${loc}): ${c.body}`;\n };\n\n let block = \"\";\n if (securityComments.length > 0) {\n block += `### Security Comments (PRIORITY — must be addressed)\\n\\n`;\n block += securityComments.map(formatOne).join(\"\\n\");\n block += \"\\n\\n\";\n }\n if (generalComments.length > 0) {\n block += `### General Comments\\n\\n`;\n block += generalComments.map(formatOne).join(\"\\n\");\n }\n return block;\n}\n\nfunction buildPlanPrompt(\n systemPrompt: string,\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n): string {\n const hasSecurityComments = comments.some((c) => c.isSecurity);\n\n const securityPlanInstruction = hasSecurityComments\n ? \" Security-related comments are marked as priority — ensure concrete fix tasks are generated for each one. Apply secure coding practices (input validation, output encoding, least privilege, etc.) when planning fixes.\"\n : \"\";\n\n let diffSection = \"\";\n if (includedDiffs.length > 0) {\n diffSection += `## Current Diff (branch vs base)\\n\\n`;\n for (const f of includedDiffs) {\n diffSection += `\\`\\`\\`diff\\n${f.diff}\\n\\`\\`\\`\\n\\n`;\n }\n }\n if (excludedFiles.length > 0) {\n diffSection += `### Files not shown (too large for context)\\n\\n${excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\\n`;\n }\n\n return `${systemPrompt}\n\n---\n\n## Review Comments to Address\n\n${formatCommentBlock(comments)}\n\n---\n\n${diffSection}\n---\n\n## Instructions\n\nAnalyze the review comments above in the context of the current diff. Create a plan to address each comment.${securityPlanInstruction} Return ONLY valid JSON:\n\n\\`\\`\\`json\n{ \"valid\": true, \"goals\": [\"...\"], \"tasks\": [\"...\"], \"constraints\": [\"...\"], \"dod\": [\"...\"] }\n\\`\\`\\`\n\n- **goals**: High-level objectives (e.g., \"Address all review feedback\")\n- **tasks**: Specific actionable steps to fix/change code per reviewer comments\n- **constraints**: Things to preserve or avoid breaking\n- **dod**: How to verify each comment has been addressed\n\nEach array must contain at least one non-empty string. Do not include any text outside the JSON object.`;\n}\n\nfunction buildPlanPromptWithFeedback(\n systemPrompt: string,\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n feedback: string,\n): string {\n const base = buildPlanPrompt(systemPrompt, comments, includedDiffs, excludedFiles);\n return `${base}\n\n---\n\n## User Feedback on Previous Plan\n\nThe user reviewed the previous plan and provided this feedback. Incorporate it into your revised plan:\n\n${feedback}`;\n}\n\nasync function generatePlan(\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n feedback?: string,\n): Promise<PlannerOutput> {\n const agents = getAgents();\n const agent = agents.find((a) => a.role === \"planner\");\n if (!agent) {\n throw new TaskError(\"review-comments: no agent with role 'planner' found in config\");\n }\n\n const prompt = feedback\n ? buildPlanPromptWithFeedback(agent.systemPrompt, comments, includedDiffs, excludedFiles, feedback)\n : buildPlanPrompt(agent.systemPrompt, comments, includedDiffs, excludedFiles);\n\n const result = await spawnAgent(\"planner\", prompt, { quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(`review-comments: planner agent exited with code ${result.exitCode}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(result.stdout));\n } catch {\n throw new TaskError(\"review-comments: failed to parse planner output as JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj.valid !== true) {\n const errors = Array.isArray(obj.errors)\n ? (obj.errors as string[]).join(\"\\n - \")\n : \"planner returned invalid plan\";\n throw new TaskError(`review-comments: plan generation failed:\\n - ${errors}`);\n }\n\n const plan: PlannerOutput = {\n goals: Array.isArray(obj.goals) ? (obj.goals as string[]) : [],\n tasks: Array.isArray(obj.tasks) ? (obj.tasks as string[]) : [],\n constraints: Array.isArray(obj.constraints) ? (obj.constraints as string[]) : [],\n dod: Array.isArray(obj.dod) ? (obj.dod as string[]) : [],\n };\n\n if (plan.goals.length === 0 || plan.tasks.length === 0) {\n throw new TaskError(\"review-comments: planner returned empty goals or tasks\");\n }\n\n return plan;\n}\n\n// ── Plan display and approval ──\n\nfunction displayPlan(plan: PlannerOutput): void {\n const cols = process.stdout.columns || 80;\n console.log(chalk.bold(\"\\n Plan to Address Review Comments\\n\"));\n\n console.log(chalk.bold.blue(\" Goals:\"));\n for (const g of plan.goals) {\n console.log(` - ${wrapText(g, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Tasks:\"));\n for (const t of plan.tasks) {\n console.log(` - ${wrapText(t, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Constraints:\"));\n for (const c of plan.constraints) {\n console.log(` - ${wrapText(c, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Definition of Done:\"));\n for (const d of plan.dod) {\n console.log(` - ${wrapText(d, 6, cols)}`);\n }\n console.log();\n}\n\n// ── Execution ──\n\nfunction buildDevPrompt(\n systemPrompt: string,\n comments: ClassifiedComment[],\n plan: PlannerOutput,\n userInstructions?: string,\n): string {\n const hasSecurityComments = comments.some((c) => c.isSecurity);\n\n const securityDevInstruction = hasSecurityComments\n ? \" Pay special attention to security-related comments — apply secure coding practices and ensure fixes do not introduce new vulnerabilities.\"\n : \"\";\n\n let prompt = `${systemPrompt}\n\n---\n\n## Review Comments to Address\n\n${formatCommentBlock(comments)}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}`;\n\n if (userInstructions) {\n prompt += `\n\n---\n\n## Additional Instructions from User\n\n${userInstructions}`;\n }\n\n prompt += `\n\n---\n\nImplement the tasks above to address the review comments.${securityDevInstruction} When you are finished, output a JSON block with the list of files you created or modified:\n\n\\`\\`\\`json\n{ \"files\": [\"src/example.ts\"] }\n\\`\\`\\``;\n\n return prompt;\n}\n\nasync function executeWithDevAgent(\n comments: ClassifiedComment[],\n plan: PlannerOutput,\n autoApprove?: boolean,\n onActivity?: (event: ActivityEvent) => void,\n userInstructions?: string,\n): Promise<void> {\n const agents = getAgents();\n const devAgent = agents.find((a) => a.name === \"dev\");\n if (!devAgent) {\n throw new TaskError(\"review-comments: no agent named 'dev' found in config\");\n }\n\n const prompt = buildDevPrompt(devAgent.systemPrompt, comments, plan, userInstructions);\n\n const result = await spawnAgent(\"dev\", prompt, { autoApprove, quiet: true, onActivity, provider: devAgent.provider, model: devAgent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(`review-comments: dev agent exited with code ${result.exitCode}`);\n }\n\n // Extract files changed\n try {\n const parsed = JSON.parse(extractJSON(result.stdout)) as { files?: string[] };\n if (parsed.files && parsed.files.length > 0) {\n console.log();\n console.log(chalk.bold(\" Files modified:\"));\n for (const f of parsed.files) {\n console.log(` - ${chalk.cyan(f)}`);\n }\n }\n } catch {\n // Non-critical — agent may not output structured JSON\n }\n}\n\n// ── Main command ──\n\nexport async function reviewCommentsCommand(\n options: ReviewCommentsOptions,\n): Promise<void> {\n return withTelemetry('review-comments', async () => {\n try {\n // 1. Verify git repo\n try {\n await exec(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"]);\n } catch {\n console.log(chalk.red.bold(\"Error:\"), \"Not inside a git repository.\");\n process.exit(1);\n }\n\n loadEnvFile();\n\n // 2. Detect platform\n const remoteUrl = (\n await exec(\"git\", [\"remote\", \"get-url\", \"origin\"])\n ).trim();\n const remote = parseRemote(remoteUrl);\n const branch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n console.log(\n chalk.gray(` Platform: ${remote.platform}`) +\n chalk.gray(` | Branch: ${branch}`) +\n chalk.gray(` | Base: ${defaultBranch}`),\n );\n console.log();\n\n // 3. Check for PR/MR and fetch comments\n let comments: ReviewComment[] = [];\n\n if (remote.platform === \"github\") {\n const spinner = createLiveStatus(\"checking for open PR...\");\n const prNumber = await detectGitHubPR();\n\n if (prNumber === null) {\n spinner.fail(chalk.red(\"No open PR found for this branch\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n spinner.succeed(chalk.green(`Found PR #${prNumber}`));\n\n console.log();\n const commentSpinner = createLiveStatus(\"fetching review comments...\");\n comments = await fetchGitHubComments();\n\n if (comments.length === 0) {\n commentSpinner.info(chalk.yellow(\"No review comments found on this PR\"));\n return;\n }\n commentSpinner.succeed(chalk.green(`Fetched ${comments.length} comment(s)`));\n } else {\n // GitLab\n const spinner = createLiveStatus(\"checking for open MR...\");\n let token: string;\n try {\n token = await resolveToken(remote.host);\n } catch (err) {\n if (isDebug()) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(chalk.gray(`[debug] Token resolution failed: ${msg}`));\n }\n spinner.fail(chalk.red(\"Could not resolve GitLab token\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n\n const mrIid = await detectGitLabMR(remote, token, branch, options.insecure);\n if (mrIid === null) {\n spinner.fail(chalk.red(\"No open MR found for this branch\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n spinner.succeed(chalk.green(`Found MR !${mrIid}`));\n\n console.log();\n const commentSpinner = createLiveStatus(\"fetching review comments...\");\n comments = await fetchGitLabComments(remote, token, mrIid, options.insecure);\n\n if (comments.length === 0) {\n commentSpinner.info(chalk.yellow(\"No review comments found on this MR\"));\n return;\n }\n commentSpinner.succeed(chalk.green(`Fetched ${comments.length} comment(s)`));\n }\n\n // 6. Classify and display comment summary\n const classified = classifyComments(comments);\n console.log();\n displayCommentSummary(classified);\n\n // 7. Get git diff for context (token-budgeted)\n const diffSpinner = createLiveStatus(\"generating diff...\");\n const rawDiff = await exec(\"git\", [\"diff\", `${defaultBranch}...HEAD`]);\n let includedDiffs: FileDiff[] = [];\n let excludedFiles: string[] = [];\n if (!rawDiff.trim()) {\n diffSpinner.warn(chalk.yellow(\"No diff found against base branch\"));\n } else {\n const fileDiffs = splitDiffByFile(rawDiff);\n const reservedTokens = estimateTokens(formatCommentBlock(classified)) + RESERVED_PROMPT_TOKENS;\n ({ included: includedDiffs, excluded: excludedFiles } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens));\n\n // Debug logging and telemetry for diff budget decisions\n const totalDiffTokens = includedDiffs.reduce((sum, f) => sum + f.tokens, 0);\n const excludedTokens = fileDiffs.filter(f => excludedFiles.includes(f.file)).reduce((sum, f) => sum + f.tokens, 0);\n const availableTokens = MAX_REVIEW_TOKENS - reservedTokens;\n\n if (isDebug()) {\n console.log(\n `[DEBUG] Diff budget: ${totalDiffTokens}/${availableTokens} tokens used ` +\n `(${includedDiffs.length}/${fileDiffs.length} files included, ${excludedFiles.length} excluded for ${excludedTokens} tokens)`\n );\n if (excludedFiles.length > 0) {\n console.log(`[DEBUG] Excluded files: ${excludedFiles.join(\", \")}`);\n }\n }\n\n // Emit telemetry event\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.REVIEW_DIFF_BUDGET, {\n filesIncluded: includedDiffs.length,\n filesExcluded: excludedFiles.length,\n tokensUsed: totalDiffTokens,\n tokensAvailable: availableTokens,\n excludedFilesList: excludedFiles,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n if (excludedFiles.length > 0) {\n diffSpinner.succeed(chalk.green(`Diff loaded (${includedDiffs.length} files included, ${excludedFiles.length} excluded for size)`));\n } else {\n diffSpinner.succeed(chalk.green(\"Diff loaded\"));\n }\n }\n\n // 8. Generate plan\n let plan: PlannerOutput;\n {\n const planSpinner = createLiveStatus(\"generating plan...\");\n plan = await generatePlan(classified, includedDiffs, excludedFiles);\n planSpinner.succeed(chalk.green(\"Plan generated\"));\n }\n\n displayPlan(plan);\n\n // 9. Approval loop with additional instructions support\n let userInstructions: string | undefined;\n\n if (!options.autoApprove) {\n resetTerminalForInput();\n let approved = false;\n while (!approved) {\n const action = await select({\n message: \"How would you like to proceed?\",\n choices: [\n { name: \"Approve — execute plan\", value: \"approve\" },\n { name: \"Provide feedback — regenerate plan\", value: \"feedback\" },\n { name: \"Add instructions — pass extra guidance to dev agent\", value: \"instructions\" },\n { name: \"Reject — exit without changes\", value: \"reject\" },\n ],\n });\n\n if (action === \"approve\") {\n approved = true;\n } else if (action === \"feedback\") {\n resetTerminalForInput();\n const feedback = await pasteableInput({\n message: \"Enter your feedback:\",\n });\n if (feedback.trim()) {\n const planSpinner = createLiveStatus(\"regenerating plan...\");\n plan = await generatePlan(classified, includedDiffs, excludedFiles, feedback);\n planSpinner.succeed(chalk.green(\"Plan regenerated\"));\n displayPlan(plan);\n }\n } else if (action === \"instructions\") {\n resetTerminalForInput();\n const extra = await pasteableInput({\n message: \"Enter additional instructions for the dev agent:\",\n });\n if (extra.trim()) {\n userInstructions = userInstructions\n ? `${userInstructions}\\n\\n${extra.trim()}`\n : extra.trim();\n console.log(chalk.green(\" Instructions saved. They will be included when executing.\"));\n const displayText = userInstructions.length > 200\n ? userInstructions.slice(0, 200) + \"...\"\n : userInstructions;\n console.log(chalk.gray(` Current instructions:\\n ${displayText.split(\"\\n\").join(\"\\n \")}`));\n console.log();\n }\n } else {\n console.log(chalk.yellow(\"\\n Rejected. No changes made.\\n\"));\n return;\n }\n }\n }\n\n // 10. Execute\n console.log();\n const execStatus = createLiveStatus(\"addressing review comments...\");\n\n // User approved the plan (or --auto-approve was set), so dev agent can write freely\n await executeWithDevAgent(classified, plan, true, execStatus.onActivity, userInstructions);\n execStatus.succeed(chalk.green(\"Dev agent finished\"));\n\n // 11. Commit and push changes\n console.log();\n const pushSpinner = createLiveStatus(\"committing and pushing...\");\n const trace = getChesstrace();\n const commitMessage = \"fix: address PR review comments\";\n const maxRetries = options.retryCommits ?? 3;\n let committed = false;\n try {\n await exec(\"git\", [\"add\", \"-A\"]);\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n committed = true;\n } catch (commitErr) {\n const msg = commitErr instanceof Error ? commitErr.message : String(commitErr);\n if (msg.includes(\"nothing to commit\")) {\n // Agent may have committed already — check if we have unpushed commits\n try {\n const ahead = await exec(\"git\", [\n \"rev-list\", \"--count\", `origin/${branch}..HEAD`,\n ]);\n if (parseInt(ahead.trim(), 10) > 0) {\n await exec(\"git\", [\"push\", \"origin\", branch]);\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n pushSpinner.succeed(chalk.green(\"Changes pushed.\"));\n } else {\n pushSpinner.warn(chalk.yellow(\"No changes were made by the dev agent.\"));\n }\n } catch {\n pushSpinner.warn(chalk.yellow(\"Nothing to commit or push.\"));\n }\n } else {\n // Pre-commit hook likely failed and may have modified files — retry with re-staging\n let retryCount = 0;\n while (retryCount < maxRetries) {\n retryCount++;\n pushSpinner.text = `pre-commit hook failed, re-staging and retrying (${retryCount}/${maxRetries})...`;\n try {\n await exec(\"git\", [\"add\", \"-A\"]);\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n committed = true;\n break;\n } catch (retryErr) {\n const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);\n if (retryCount >= maxRetries) {\n try { trace.emit(Events.GIT_ERROR, { operation: \"commit\", error: retryMsg, retriesExhausted: maxRetries }); } catch { /* swallow */ }\n pushSpinner.fail(chalk.red(`Commit failed after ${maxRetries} retries: ${retryMsg}`));\n }\n }\n }\n }\n }\n\n if (committed) {\n try { trace.emit(Events.GIT_COMMIT, { branch, messageSubject: commitMessage }); } catch { /* swallow */ }\n try {\n await exec(\"git\", [\"push\", \"origin\", branch]);\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n pushSpinner.succeed(chalk.green(\"Changes committed and pushed.\"));\n } catch (pushErr) {\n const pushMsg = pushErr instanceof Error ? pushErr.message : String(pushErr);\n try { trace.emit(Events.GIT_ERROR, { operation: \"push\", error: pushMsg }); } catch { /* swallow */ }\n pushSpinner.fail(chalk.red(`Push failed: ${pushMsg}`));\n }\n }\n\n console.log();\n console.log(chalk.green.bold(\" Done!\"), chalk.gray(\"Review comments addressed.\"));\n console.log();\n } catch (err) {\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n process.exit(0);\n }\n if (err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n\n// Exported for unit testing\nexport {\n classifyComments,\n classifyComment,\n buildDevPrompt,\n PRIMARY_SECURITY_KEYWORDS,\n SECONDARY_SECURITY_KEYWORDS,\n};\nexport type { ReviewComment, ClassifiedComment };\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, lstatSync, renameSync, unlinkSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport chalk from \"chalk\";\nimport { select, confirm } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { findLocalConfigDir, resolveGlobalConfigPath } from \"../config.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport type { AgentConfig } from \"../agents.js\";\nimport { builtinAgents } from \"../agents.js\";\nimport { PROVIDER_NAMES, getProvider } from \"../providers/index.js\";\nimport { isDebug } from \"../debug.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\n\n/** Agent categories for grouped display */\nconst AGENT_CATEGORIES: { label: string; color: (s: string) => string; roles: string[] }[] = [\n {\n label: \"Development\",\n color: chalk.blue,\n roles: [\"developer\", \"general\"],\n },\n {\n label: \"Testing & Review\",\n color: chalk.magenta,\n roles: [\"quality-engineer\", \"security-reviewer\", \"reviewer\"],\n },\n {\n label: \"Planning\",\n color: chalk.yellow,\n roles: [\"planner\"],\n },\n];\n\ninterface AgentGroup {\n label: string;\n color: (s: string) => string;\n agentIndices: number[];\n}\n\nfunction categorizeAgents(agents: AgentConfig[]): AgentGroup[] {\n const groups: AgentGroup[] = [];\n const assigned = new Set<number>();\n\n for (const category of AGENT_CATEGORIES) {\n const indices: number[] = [];\n for (let i = 0; i < agents.length; i++) {\n if (assigned.has(i)) continue;\n if (category.roles.includes(agents[i]!.role)) {\n indices.push(i);\n assigned.add(i);\n }\n }\n if (indices.length > 0) {\n groups.push({\n label: category.label,\n color: category.color,\n agentIndices: indices,\n });\n }\n }\n\n // Uncategorized agents go into \"Other\"\n const remaining: number[] = [];\n for (let i = 0; i < agents.length; i++) {\n if (!assigned.has(i)) remaining.push(i);\n }\n if (remaining.length > 0) {\n groups.push({\n label: \"Other\",\n color: chalk.gray,\n agentIndices: remaining,\n });\n }\n\n return groups;\n}\n\n/** Map role to a colored badge string */\nfunction roleBadge(role: string): string {\n const badges: Record<string, (s: string) => string> = {\n \"developer\": chalk.bgBlue.white,\n \"general\": chalk.bgBlue.white,\n \"quality-engineer\": chalk.bgMagenta.white,\n \"security-reviewer\": chalk.bgRed.white,\n \"reviewer\": chalk.bgMagenta.white,\n \"planner\": chalk.bgYellow.black,\n };\n const colorFn = badges[role] ?? chalk.bgGray.white;\n return colorFn(` ${role} `);\n}\n\nexport async function configCommand(): Promise<void> {\n try {\n await runConfig();\n } catch (err) {\n // Ctrl+C from inquirer\n if (err && typeof err === \"object\" && \"name\" in err && (err as { name: string }).name === \"ExitPromptError\") {\n console.log(chalk.yellow(\"\\nConfiguration cancelled.\"));\n process.exit(0);\n }\n throw err;\n }\n}\n\nasync function runConfig(): Promise<void> {\n // Check for interactive environment before prompting\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"config command requires interactive mode.\");\n console.log(chalk.gray(\" Edit\"), chalk.cyan(\".reygent/config.json\"), chalk.gray(\"or\"), chalk.cyan(\"~/.reygent/config.json\"), chalk.gray(\"directly.\"));\n process.exit(1);\n }\n\n // 1. Scope selection\n const scope = await select({\n message: \"Configuration scope:\",\n choices: [\n { name: `Local ${chalk.gray(\"— .reygent/config.json (this project)\")}`, value: \"local\" as const },\n { name: `Global ${chalk.gray(\"— ~/.reygent/config.json (all projects)\")}`, value: \"global\" as const },\n ],\n });\n\n let configPath: string;\n\n if (scope === \"local\") {\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n console.log(chalk.gray(\" Run\"), chalk.cyan(\"reygent init\"), chalk.gray(\"first.\"));\n console.log(\"\");\n process.exit(1);\n }\n configPath = join(configDir, \"config.json\");\n } else {\n configPath = resolveGlobalConfigPath();\n const globalDir = dirname(configPath);\n mkdirSync(globalDir, { recursive: true });\n }\n\n // 2. Load raw JSON (preserve unknown fields)\n let rawConfig: Record<string, unknown> = {};\n const fileExists = existsSync(configPath);\n\n if (fileExists) {\n try {\n const content = readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } catch (err) {\n if (err instanceof SyntaxError) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid JSON in ${configPath}`);\n console.log(chalk.gray(\" Parse error:\"), err.message);\n process.exit(2);\n }\n if (err && typeof err === \"object\" && \"code\" in err && (err as { code?: string }).code === \"EACCES\") {\n console.log(chalk.red.bold(\"Error:\"), `Permission denied: ${configPath}`);\n process.exit(2);\n }\n console.log(chalk.red.bold(\"Error:\"), `Failed to read ${configPath}`);\n if (isDebug()) console.error(err);\n process.exit(2);\n }\n } else {\n // Initialize empty config with sensible defaults\n rawConfig = {\n provider: \"claude\",\n model: \"claude-sonnet-4-5\",\n };\n }\n\n // Initialize agents array before loop to ensure it always exists in output\n rawConfig.agents = (rawConfig.agents as AgentConfig[] | undefined) ?? builtinAgents;\n const agents: AgentConfig[] = rawConfig.agents as AgentConfig[];\n\n // 3. Check provider availability\n const availability: Record<string, { available: boolean; reason?: string }> = {};\n for (const name of PROVIDER_NAMES) {\n const provider = getProvider(name);\n availability[name] = await provider.isAvailable();\n }\n\n // 4. Show current config\n const currentProvider = (rawConfig.provider as string | undefined) ?? \"(not set)\";\n const currentModel = (rawConfig.model as string | undefined) ?? \"(not set)\";\n console.log(chalk.bold(\"Current config:\"));\n console.log(chalk.gray(\" Scope: \"), chalk.cyan(scope));\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(currentProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(currentModel));\n console.log(\"\");\n\n // 5. Select default provider\n const providerChoices = PROVIDER_NAMES.map((name) => {\n const status = availability[name];\n const badge = status?.available ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const hint = !status?.available && status?.reason ? chalk.gray(` — ${status.reason}`) : \"\";\n return {\n name: `${badge} ${name}${hint}`,\n value: name,\n };\n });\n\n resetTerminalForInput();\n let selectedProvider = await select({\n message: \"Default provider:\",\n choices: providerChoices,\n default: rawConfig.provider as string | undefined,\n });\n\n // Warn if selected provider unavailable\n if (!availability[selectedProvider]?.available) {\n const reason = availability[selectedProvider]?.reason ?? \"unknown reason\";\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(`Provider ${selectedProvider} is unavailable (${reason})`));\n resetTerminalForInput();\n const proceed = await confirm({\n message: \"Continue with this provider anyway?\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.yellow(\"\\nConfiguration cancelled.\"));\n process.exit(0);\n }\n }\n\n // 6. Select default model\n const provider = getProvider(selectedProvider);\n let selectedModel: string;\n\n if (provider.supportedModels.length === 0) {\n // OpenRouter or similar — free-text input\n resetTerminalForInput();\n selectedModel = await pasteableInput({\n message: \"Model ID:\",\n default: (rawConfig.model as string | undefined) ?? provider.defaultModel,\n });\n } else {\n resetTerminalForInput();\n const modelChoices = provider.supportedModels.map((m) => ({\n name: `${m.id} — ${m.label}`,\n value: m.id,\n }));\n selectedModel = await select({\n message: \"Default model:\",\n choices: modelChoices,\n default: (rawConfig.model as string | undefined) ?? provider.defaultModel,\n });\n }\n\n // 7. Per-agent overrides — grouped by category\n const updatedAgents = [...agents];\n const categorized = categorizeAgents(agents);\n\n for (const group of categorized) {\n console.log(\"\");\n console.log(group.color(chalk.bold(`── ${group.label} ──`)));\n\n for (const agentIndex of group.agentIndices) {\n const agent = updatedAgents[agentIndex]!;\n const agentProvider = agent.provider ?? selectedProvider;\n const agentModel = agent.model ?? selectedModel;\n\n console.log(\"\");\n console.log(chalk.bold(agent.name), roleBadge(agent.role));\n console.log(chalk.gray(` ${agent.description}`));\n console.log(\n chalk.gray(\" Tools:\"),\n agent.tools.map((t) => chalk.cyan(t)).join(chalk.gray(\", \")),\n );\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(agentProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(agentModel));\n\n const hasOverride = agent.provider !== undefined || agent.model !== undefined;\n resetTerminalForInput();\n const action = await select({\n message: `Configure ${agent.name}:`,\n choices: [\n { name: \"Keep current\", value: \"keep\" },\n { name: \"Customize\", value: \"customize\" },\n ...(hasOverride ? [{ name: \"Clear overrides\", value: \"clear\" }] : []),\n ],\n default: \"keep\",\n });\n\n if (action === \"keep\") {\n continue;\n } else if (action === \"clear\") {\n // Remove provider/model overrides from this agent\n const { provider: _p, model: _m, ...rest } = agent;\n updatedAgents[agentIndex] = rest as AgentConfig;\n continue;\n }\n\n // action === \"customize\"\n resetTerminalForInput();\n const agentProviderChoice = await select({\n message: `Provider for ${agent.name}:`,\n choices: providerChoices,\n default: agent.provider ?? selectedProvider,\n });\n\n // Warn if selected provider unavailable\n if (!availability[agentProviderChoice]?.available) {\n const reason = availability[agentProviderChoice]?.reason ?? \"unknown reason\";\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(`Provider ${agentProviderChoice} is unavailable (${reason})`));\n resetTerminalForInput();\n const proceed = await confirm({\n message: \"Continue with this provider anyway?\",\n default: false,\n });\n if (!proceed) {\n continue; // Skip customization for this agent\n }\n }\n\n const agentProviderAdapter = getProvider(agentProviderChoice);\n let agentModelChoice: string;\n\n if (agentProviderAdapter.supportedModels.length === 0) {\n resetTerminalForInput();\n agentModelChoice = await pasteableInput({\n message: `Model ID for ${agent.name}:`,\n default: agent.model ?? agentProviderAdapter.defaultModel,\n });\n } else {\n resetTerminalForInput();\n const agentModelChoices = agentProviderAdapter.supportedModels.map((m) => ({\n name: `${m.id} — ${m.label}`,\n value: m.id,\n }));\n agentModelChoice = await select({\n message: `Model for ${agent.name}:`,\n choices: agentModelChoices,\n default: agent.model ?? agentProviderAdapter.defaultModel,\n });\n }\n\n updatedAgents[agentIndex] = { ...agent, provider: agentProviderChoice, model: agentModelChoice };\n }\n }\n\n // 8. Merge into raw config (only touch provider, model, and agent provider/model)\n rawConfig.provider = selectedProvider;\n rawConfig.model = selectedModel;\n\n // Match agents by name instead of index to handle length mismatches\n const rawAgents = rawConfig.agents as Record<string, unknown>[];\n for (const updatedAgent of updatedAgents) {\n const rawAgent = rawAgents.find((r) => r.name === updatedAgent.name);\n if (rawAgent) {\n // Update or remove provider/model fields\n if (updatedAgent.provider !== undefined) {\n rawAgent.provider = updatedAgent.provider;\n } else {\n delete rawAgent.provider;\n }\n if (updatedAgent.model !== undefined) {\n rawAgent.model = updatedAgent.model;\n } else {\n delete rawAgent.model;\n }\n }\n }\n\n // 9. Write config (atomic write to prevent TOCTOU race)\n try {\n const tempPath = `${configPath}.tmp.${randomBytes(8).toString(\"hex\")}`;\n\n try {\n // Write to temp file\n writeFileSync(tempPath, JSON.stringify(rawConfig, null, 2) + \"\\n\", \"utf-8\");\n\n // Security: verify temp file is not symlink\n const tempStats = lstatSync(tempPath);\n if (tempStats.isSymbolicLink()) {\n unlinkSync(tempPath);\n throw new Error(`Security: temp file became symlink`);\n }\n\n // Atomic rename\n renameSync(tempPath, configPath);\n } catch (err) {\n // Clean up temp file on error\n try {\n unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Error:\"), `Failed to write config: ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n\n // 10. Summary\n console.log(\"\");\n console.log(chalk.green.bold(\"✓\"), chalk.bold(\"Config updated\"));\n console.log(chalk.gray(\" Scope: \"), chalk.cyan(scope));\n console.log(chalk.gray(\" File: \"), chalk.gray(configPath));\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(selectedProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(selectedModel));\n\n const overriddenAgents = updatedAgents.filter((a) => a.provider || a.model);\n if (overriddenAgents.length > 0) {\n console.log(chalk.gray(\" Agent overrides:\"));\n for (const a of overriddenAgents) {\n const parts: string[] = [];\n if (a.provider) parts.push(`provider=${a.provider}`);\n if (a.model) parts.push(`model=${a.model}`);\n console.log(chalk.gray(` ${a.name}:`), chalk.cyan(parts.join(\", \")));\n }\n }\n console.log(\"\");\n}\n","import { Command } from \"commander\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { writeFileSync } from \"node:fs\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig, resolveGlobalConfigPath, findLocalConfigDir } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { join } from \"node:path\";\n\n/**\n * Validate UUID format\n */\nfunction isValidUuid(value: string): boolean {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(value);\n}\n\n/**\n * Parse duration string like \"30d\", \"7d\", \"1d\" into days\n */\nfunction parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)d$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like \"30d\", \"7d\", \"1d\".`);\n }\n return Number.parseInt(match[1], 10);\n}\n\n/**\n * Format bytes to human-readable size\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;\n}\n\n/**\n * Format timestamp to human-readable date\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(\"T\", \" \").replace(/\\.\\d{3}Z$/, \"\");\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\n/**\n * Get database size in bytes\n */\nfunction getDbSize(dbPath: string): number {\n try {\n const stats = statSync(dbPath);\n return stats.size;\n } catch {\n return 0;\n }\n}\n\n/**\n * reygent telemetry status - show config, run count, DB size\n */\nasync function statusCommand() {\n const spinner = ora(\"Loading telemetry status...\").start();\n\n try {\n const config = loadConfig();\n const telemetryConfig = config.telemetry;\n\n if (!telemetryConfig) {\n spinner.fail(chalk.red(\"Telemetry configuration not found\"));\n return;\n }\n\n // Initialize backend to get database info\n const backendType = telemetryConfig.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const runs = await backend.listRuns();\n const dbPath = backend.getDbPath();\n const dbSize = getDbSize(dbPath);\n\n await backend.close();\n\n spinner.succeed(chalk.green(\"Telemetry status loaded\"));\n\n console.log();\n console.log(chalk.bold(\"Telemetry Configuration\"));\n console.log(` Enabled: ${telemetryConfig.enabled === undefined ? chalk.yellow(\"unset (will prompt)\") : telemetryConfig.enabled ? chalk.green(\"yes\") : chalk.red(\"no\")}`);\n console.log(` Level: ${chalk.cyan(telemetryConfig.level)}`);\n console.log(` Backend: ${chalk.cyan(telemetryConfig.backend)}`);\n console.log(` Retention: ${chalk.cyan(`${telemetryConfig.retention} days`)}`);\n\n console.log();\n console.log(chalk.bold(\"Storage\"));\n console.log(` Database: ${chalk.gray(dbPath)}`);\n console.log(` Size: ${chalk.cyan(formatBytes(dbSize))}`);\n console.log(` Runs: ${chalk.cyan(runs.length.toString())}`);\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load telemetry status: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry runs [--limit N] - list recent runs (table format)\n */\nasync function runsCommand(options: { limit?: string }) {\n const spinner = ora(\"Loading telemetry runs...\").start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const allRuns = await backend.listRuns();\n await backend.close();\n\n let limit = allRuns.length;\n if (options.limit) {\n const parsed = Number.parseInt(options.limit, 10);\n if (isNaN(parsed) || parsed < 1) {\n spinner.fail(chalk.red(`Invalid limit: ${options.limit}. Must be positive integer.`));\n process.exit(1);\n }\n limit = parsed;\n }\n const runs = allRuns.slice(0, limit);\n\n spinner.succeed(chalk.green(`Loaded ${runs.length} run(s)`));\n\n if (runs.length === 0) {\n console.log(chalk.yellow(\"\\nNo telemetry runs found\"));\n return;\n }\n\n console.log();\n const table = new Table({\n head: [\n chalk.cyan(\"Run ID\"),\n chalk.cyan(\"Start Time\"),\n chalk.cyan(\"Duration\"),\n chalk.cyan(\"Events\"),\n chalk.cyan(\"Categories\"),\n ],\n colWidths: [38, 20, 12, 10, 30],\n });\n\n for (const run of runs) {\n const duration = run.endTime - run.startTime;\n table.push([\n run.runId,\n formatTimestamp(run.startTime),\n formatDuration(duration),\n run.eventCount.toString(),\n run.categories.join(\", \"),\n ]);\n }\n\n console.log(table.toString());\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load runs: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry show <runId> - detailed chronological event log\n */\nasync function showCommand(runId: string) {\n if (!isValidUuid(runId)) {\n console.error(chalk.red(`Invalid run ID format: ${runId}. Must be valid UUID.`));\n process.exit(1);\n }\n\n const spinner = ora(`Loading events for run ${runId}...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const events = await backend.query({ runId });\n await backend.close();\n\n if (events.length === 0) {\n spinner.fail(chalk.yellow(`No events found for run ${runId}`));\n return;\n }\n\n spinner.succeed(chalk.green(`Loaded ${events.length} event(s) for run ${runId}`));\n\n console.log();\n console.log(chalk.bold(`Events for run ${runId}`));\n console.log(chalk.gray(`Total events: ${events.length}`));\n console.log();\n\n for (const event of events) {\n const timestamp = formatTimestamp(event.timestamp);\n const category = chalk.cyan(`[${event.category}]`);\n const eventName = chalk.bold(event.event);\n const dataStr = Object.keys(event.data).length > 0 ? JSON.stringify(event.data, null, 2) : \"\";\n\n console.log(`${chalk.gray(timestamp)} ${category} ${eventName}`);\n if (dataStr) {\n // Apply gray color to entire data block for visual distinction\n const grayData = dataStr.split('\\n').map(line => chalk.gray(line)).join('\\n');\n console.log(grayData);\n }\n console.log();\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load events: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Export event data as JSON\n */\nfunction exportJson(events: TelemetryEvent[]): string {\n return JSON.stringify(events, null, 2);\n}\n\n/**\n * Export event data as CSV\n */\nfunction exportCsv(events: TelemetryEvent[]): string {\n const lines: string[] = [];\n lines.push(\"id,runId,timestamp,category,event,minLevel,data\");\n\n for (const event of events) {\n const dataStr = JSON.stringify(event.data).replace(/\"/g, '\"\"');\n lines.push(\n `\"${event.id}\",\"${event.runId}\",\"${event.timestamp}\",\"${event.category}\",\"${event.event}\",\"${event.minLevel}\",\"${dataStr}\"`,\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * reygent telemetry export <runId> [--format json|csv] - export run data\n */\nasync function exportCommand(runId: string, options: { format?: string; output?: string }) {\n if (!isValidUuid(runId)) {\n console.error(chalk.red(`Invalid run ID format: ${runId}. Must be valid UUID.`));\n process.exit(1);\n }\n\n const format = options.format ?? \"json\";\n const spinner = ora(`Exporting run ${runId} as ${format.toUpperCase()}...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const events = await backend.query({ runId });\n await backend.close();\n\n if (events.length === 0) {\n spinner.fail(chalk.yellow(`No events found for run ${runId}`));\n return;\n }\n\n const data = format === \"json\" ? exportJson(events) : exportCsv(events);\n\n if (options.output) {\n writeFileSync(options.output, data, \"utf-8\");\n spinner.succeed(chalk.green(`Exported ${events.length} events to ${options.output}`));\n } else {\n spinner.succeed(chalk.green(`Exported ${events.length} events`));\n console.log();\n console.log(data);\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed to export run: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry prune [--older-than 30d] - delete old data\n */\nasync function pruneCommand(options: { olderThan?: string }) {\n const duration = options.olderThan ?? \"30d\";\n const days = parseDuration(duration);\n\n const spinner = ora(`Pruning events older than ${days} days...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const olderThan = Date.now() - days * 24 * 60 * 60 * 1000;\n const deleted = await backend.prune(olderThan);\n\n await backend.close();\n\n spinner.succeed(chalk.green(`Pruned ${deleted} event(s) older than ${days} days`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to prune events: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry enable - enable telemetry in config\n */\nasync function enableCommand() {\n const spinner = ora(\"Enabling telemetry...\").start();\n\n try {\n // Check for local config first\n const localConfigDir = findLocalConfigDir(process.cwd());\n const configPath = localConfigDir\n ? join(localConfigDir, \"config.json\")\n : resolveGlobalConfigPath();\n\n const config = loadConfig();\n\n config.telemetry = config.telemetry ?? {\n level: \"standard\",\n backend: \"sqlite\",\n retention: 30,\n };\n config.telemetry.enabled = true;\n\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n const scope = localConfigDir ? \"local\" : \"global\";\n spinner.succeed(chalk.green(`Telemetry enabled (${scope} config)`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to enable telemetry: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry disable - disable telemetry in config\n */\nasync function disableCommand() {\n const spinner = ora(\"Disabling telemetry...\").start();\n\n try {\n // Check for local config first\n const localConfigDir = findLocalConfigDir(process.cwd());\n const configPath = localConfigDir\n ? join(localConfigDir, \"config.json\")\n : resolveGlobalConfigPath();\n\n const config = loadConfig();\n\n config.telemetry = config.telemetry ?? {\n level: \"standard\",\n backend: \"sqlite\",\n retention: 30,\n };\n config.telemetry.enabled = false;\n\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n const scope = localConfigDir ? \"local\" : \"global\";\n spinner.succeed(chalk.green(`Telemetry disabled (${scope} config)`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to disable telemetry: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Register telemetry command and subcommands\n */\nexport function registerTelemetryCommand(program: Command): void {\n const telemetry = program\n .command(\"telemetry\")\n .description(\"Manage telemetry data and configuration\");\n\n telemetry\n .command(\"status\")\n .description(\"Show telemetry configuration and storage status\")\n .action(statusCommand);\n\n telemetry\n .command(\"runs\")\n .description(\"List recent telemetry runs\")\n .option(\"--limit <n>\", \"Limit number of runs to display\")\n .action(runsCommand);\n\n telemetry\n .command(\"show\")\n .description(\"Show detailed event log for a specific run\")\n .argument(\"<runId>\", \"Run ID to display\")\n .action(showCommand);\n\n telemetry\n .command(\"export\")\n .description(\"Export run data to JSON or CSV\")\n .argument(\"<runId>\", \"Run ID to export\")\n .addOption(\n program\n .createOption(\"--format <type>\", \"Export format\")\n .choices([\"json\", \"csv\"])\n .default(\"json\")\n )\n .option(\"--output <file>\", \"Output file path (prints to stdout if omitted)\")\n .action(exportCommand);\n\n telemetry\n .command(\"prune\")\n .description(\"Delete old telemetry data\")\n .option(\"--older-than <duration>\", \"Delete events older than duration (e.g., 30d, 7d)\", \"30d\")\n .action(pruneCommand);\n\n telemetry\n .command(\"enable\")\n .description(\"Enable telemetry in configuration\")\n .action(enableCommand);\n\n telemetry\n .command(\"disable\")\n .description(\"Disable telemetry in configuration\")\n .action(disableCommand);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport { analyzeFailurePatterns, analyzeSuccessPatterns } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { getLocalTelemetryPath } from \"../telemetry-path.js\";\n\n/**\n * Cost estimation constants\n */\n// Conservative estimate of retry cost as fraction of total monthly spend\n// Based on typical gate retry patterns adding ~10% overhead\nconst RETRY_COST_ESTIMATE_MULTIPLIER = 0.1;\n\n// Conservative estimate of recoverable failure cost as fraction of failed spend\n// Assumes ~50% of failures preventable through config/prompt improvements\nconst POTENTIAL_SAVINGS_MULTIPLIER = 0.5;\n\ninterface AnalyzeOptions {\n agent?: string;\n since?: string;\n limit?: string;\n stage?: string;\n minSuccessRate?: string;\n byAgent?: boolean;\n showRuns?: boolean;\n compareModels?: boolean;\n updateKnowledge?: boolean;\n}\n\n/**\n * Parse duration string like \"30d\", \"7d\" into timestamp\n */\nfunction parseSince(since: string): number {\n const match = since.match(/^(\\d+)d$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${since}. Use format like \"30d\", \"7d\".`);\n }\n const days = Number.parseInt(match[1], 10);\n return Date.now() - days * 24 * 60 * 60 * 1000;\n}\n\n/**\n * Format timestamp to relative time\n */\nfunction formatRelativeTime(timestamp: number): string {\n const now = Date.now();\n const diff = now - timestamp;\n const days = Math.floor(diff / (24 * 60 * 60 * 1000));\n const hours = Math.floor(diff / (60 * 60 * 1000));\n\n if (days > 0) return `${days} day${days > 1 ? \"s\" : \"\"} ago`;\n if (hours > 0) return `${hours} hour${hours > 1 ? \"s\" : \"\"} ago`;\n return \"< 1 hour ago\";\n}\n\n/**\n * Format duration in milliseconds\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`;\n return `${seconds}s`;\n}\n\n/**\n * Format USD cost\n */\nfunction formatCost(usd: number): string {\n return `$${usd.toFixed(2)}`;\n}\n\n/**\n * Format percentage\n */\nfunction formatPercent(value: number): string {\n return `${Math.round(value * 100)}%`;\n}\n\n/**\n * Group events by key function\n */\nfunction groupBy<T>(items: T[], keyFn: (item: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const item of items) {\n const key = keyFn(item);\n const group = groups.get(key) ?? [];\n group.push(item);\n groups.set(key, group);\n }\n return groups;\n}\n\n/**\n * Filter events by category or event type\n */\nfunction filterEvents(\n events: TelemetryEvent[],\n criteria: { category?: string; event?: string }\n): TelemetryEvent[] {\n return events.filter(e => {\n if (criteria.category && e.category !== criteria.category) return false;\n if (criteria.event && e.event !== criteria.event) return false;\n return true;\n });\n}\n\n/**\n * Get backend instance\n */\nasync function getBackend(): Promise<SqliteBackend> {\n // Match writer path from run.ts\n const dbPath = getLocalTelemetryPath(process.cwd());\n const backend = new SqliteBackend(\"local\", dbPath);\n await backend.init();\n return backend;\n}\n\n/**\n * Check if telemetry is enabled\n */\nfunction checkTelemetryEnabled(config: ReturnType<typeof loadConfig>): void {\n if (!config.telemetry?.enabled) {\n console.log(chalk.yellow(\"\\nTelemetry is disabled. Enable with:\"));\n console.log(chalk.cyan(\" reygent telemetry enable\\n\"));\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze failures - show common failure patterns\n */\nexport async function analyzeFailures(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing failure patterns...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n // Query all error events\n const allEvents = await backend.query({ startTime: since });\n const errorEvents = filterEvents(allEvents, { category: \"error\" });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n\n await backend.close();\n\n if (errorEvents.length === 0) {\n spinner.succeed(chalk.green(\"No failures found\"));\n console.log(chalk.yellow(\"\\nNo error events in telemetry data\"));\n return;\n }\n\n const totalRuns = new Set(pipelineEvents.map(e => e.runId)).size;\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${errorEvents.length} error(s) from ${totalRuns} run(s)`));\n\n console.log();\n console.log(chalk.bold(`Failure Analysis (last ${days} days, ${totalRuns} runs)`));\n console.log();\n\n // Group by event type\n const patternGroups = groupBy(errorEvents, e => e.event);\n\n // Sort by occurrence count\n const sortedPatterns = Array.from(patternGroups.entries())\n .sort((a, b) => b[1].length - a[1].length);\n\n // Apply limit\n const limit = options.limit ? Number.parseInt(options.limit, 10) : sortedPatterns.length;\n const topPatterns = sortedPatterns.slice(0, limit);\n\n console.log(chalk.bold(\"Top Failure Patterns:\"));\n console.log();\n\n for (let i = 0; i < topPatterns.length; i++) {\n const [eventName, events] = topPatterns[i];\n const agentGroups = groupBy(events, e => (e.data.agent as string) || \"unknown\");\n const mostRecent = events.reduce((a, b) => a.timestamp > b.timestamp ? a : b);\n\n console.log(chalk.cyan(`${i + 1}. ${eventName}`) + chalk.gray(` (${events.length} occurrences)`));\n\n // Show agent breakdown\n const agentSummary = Array.from(agentGroups.entries())\n .map(([agent, events]) => `${agent} (${events.length})`)\n .join(\", \");\n console.log(` Agents: ${agentSummary}`);\n\n // Show common message if available\n const messages = events\n .map(e => e.data.message as string)\n .filter(Boolean);\n if (messages.length > 0) {\n const commonMsg = messages[0] ?? \"Unknown error\";\n console.log(` Common: \"${commonMsg}\"`);\n }\n\n // Show most recent\n console.log(` Most recent: run ${mostRecent.runId.substring(0, 8)} (${formatRelativeTime(mostRecent.timestamp)})`);\n console.log();\n }\n\n // Recommendations\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Parse error recommendations\n const parseErrors = errorEvents.filter(e => e.event === Events.ERROR_PARSE);\n if (parseErrors.length > 0) {\n const parseAgents = new Set(parseErrors.map(e => e.data.agent as string));\n for (const agent of parseAgents) {\n const count = parseErrors.filter(e => e.data.agent === agent).length;\n recommendations.push(`• ${agent} has ${count} parse failure(s) - review output format expectations`);\n }\n }\n\n // Gate retry recommendations\n const gateRetries = allEvents.filter(e => e.event === Events.GATE_RETRY);\n if (gateRetries.length > 0) {\n const gateGroups = groupBy(gateRetries, e => e.data.gateName as string);\n for (const [gateName, events] of gateGroups) {\n const avgAttempts = events.reduce((sum, e) => sum + (e.data.attempt as number), 0) / events.length;\n recommendations.push(`• ${gateName} requires ${avgAttempts.toFixed(1)} avg retries - consider relaxing criteria`);\n }\n }\n\n // Provider error recommendations\n const providerErrors = errorEvents.filter(e => e.event === Events.ERROR_PROVIDER);\n if (providerErrors.length > 0) {\n const reasons = providerErrors.map(e => e.data.reason as string).filter(Boolean);\n if (reasons.some(r => r.includes(\"rate limit\"))) {\n recommendations.push(\"• Rate limits hit during peak hours - consider request throttling\");\n }\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n // Update knowledge if requested\n if (options.updateKnowledge) {\n const updateSpinner = ora(\"Updating knowledge base...\").start();\n\n try {\n // Reopen backend for analyzer (was closed earlier)\n const analysisBackend = await getBackend();\n // Use analyzer to extract structured patterns\n const patterns = analyzeFailurePatterns(analysisBackend, since);\n await analysisBackend.close();\n\n if (patterns.length === 0) {\n updateSpinner.info(chalk.yellow(\"No recurring patterns to add\"));\n } else {\n let addedCount = 0;\n const limit = options.limit ? Number.parseInt(options.limit, 10) : 5;\n\n for (const pattern of patterns.slice(0, limit)) {\n // Add entry for each agent affected\n for (const agent of pattern.agents) {\n await addFailureEntry(process.cwd(), {\n issue: pattern.pattern,\n solution: \"Review telemetry for details\",\n agent: agent as any,\n });\n addedCount++;\n }\n }\n\n updateSpinner.succeed(chalk.green(`Added ${addedCount} failure pattern(s) to knowledge base`));\n console.log(chalk.gray(` See .reygent/knowledge/common-failures.md`));\n console.log();\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n updateSpinner.fail(chalk.red(`Failed to update knowledge: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeFailures knowledge update error:', err);\n }\n }\n }\n\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to analyze failures: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeFailures error:', err);\n }\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze success - extract patterns from successful runs\n */\nexport async function analyzeSuccess(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing success patterns...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n const agentSpawnEvents = filterEvents(allEvents, { event: Events.AGENT_SPAWN });\n const agentCompleteEvents = filterEvents(allEvents, { event: Events.AGENT_COMPLETE });\n\n await backend.close();\n\n const successfulRuns = pipelineEvents.filter(e => e.data.success === true);\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n if (successfulRuns.length === 0) {\n spinner.succeed(chalk.yellow(\"No successful runs found\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Analyzed ${successfulRuns.length} successful run(s)`));\n\n console.log();\n console.log(chalk.bold(`Success Analysis (last ${days} days, ${successfulRuns.length} successful runs)`));\n console.log();\n\n // Agent Performance\n console.log(chalk.bold(\"Agent Performance:\"));\n console.log();\n\n const agentStats = new Map<string, {\n spawns: number;\n completions: number;\n successes: number;\n totalDuration: number;\n models: Map<string, number>;\n }>();\n\n for (const spawn of agentSpawnEvents) {\n const agent = spawn.data.agent as string;\n const model = spawn.data.model as string;\n\n const stats = agentStats.get(agent) || {\n spawns: 0,\n completions: 0,\n successes: 0,\n totalDuration: 0,\n models: new Map(),\n };\n\n stats.spawns++;\n stats.models.set(model, (stats.models.get(model) || 0) + 1);\n agentStats.set(agent, stats);\n }\n\n for (const complete of agentCompleteEvents) {\n const agent = complete.data.agent as string;\n const success = complete.data.success === true;\n const duration = complete.data.duration as number;\n\n const stats = agentStats.get(agent);\n if (stats) {\n stats.completions++;\n if (success) stats.successes++;\n if (duration) stats.totalDuration += duration;\n }\n }\n\n for (const [agent, stats] of agentStats) {\n const successRate = stats.completions > 0 ? stats.successes / stats.completions : 0;\n const avgDuration = stats.completions > 0 ? stats.totalDuration / stats.completions : 0;\n\n // Apply min success rate filter if provided\n if (options.minSuccessRate) {\n const minRate = Number.parseFloat(options.minSuccessRate) / 100;\n if (successRate < minRate) continue;\n }\n\n // Apply --stage filter if provided\n if (options.stage) {\n // Filter agent events by stage\n const stageEvents = allEvents.filter(e =>\n e.data.stage === options.stage &&\n (e.event === Events.AGENT_SPAWN || e.event === Events.AGENT_COMPLETE)\n );\n const stageAgents = new Set(stageEvents.map(e => e.data.agent as string));\n if (!stageAgents.has(agent)) continue;\n }\n\n console.log(chalk.cyan(`${agent}:`));\n console.log(` Runs: ${stats.completions}`);\n console.log(` Success rate: ${formatPercent(successRate)} (${stats.successes} success, ${stats.completions - stats.successes} failures)`);\n console.log(` Avg duration: ${formatDuration(avgDuration)}`);\n\n const modelDist = Array.from(stats.models.entries())\n .map(([model, count]) => `${model} (${Math.round(count / stats.completions * 100)}%)`)\n .join(\", \");\n console.log(` Model distribution: ${modelDist}`);\n console.log();\n }\n\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Find best performers\n const sortedAgents = Array.from(agentStats.entries())\n .filter(([_, stats]) => stats.completions > 0)\n .map(([agent, stats]) => ({\n agent,\n successRate: stats.successes / stats.completions,\n completions: stats.completions,\n }))\n .sort((a, b) => b.successRate - a.successRate);\n\n if (sortedAgents.length > 0) {\n const best = sortedAgents[0];\n if (best.successRate >= 0.9) {\n recommendations.push(`• ${best.agent}: Best performer (${formatPercent(best.successRate)} success)`);\n }\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n // Update knowledge if requested\n if (options.updateKnowledge) {\n const updateSpinner = ora(\"Updating knowledge base...\").start();\n\n try {\n // Reopen backend for analyzer (was closed earlier)\n const analysisBackend = await getBackend();\n // Use analyzer to extract structured patterns\n const minRate = options.minSuccessRate ? Number.parseFloat(options.minSuccessRate) / 100 : 0.8;\n const patterns = analyzeSuccessPatterns(analysisBackend, since, minRate);\n await analysisBackend.close();\n\n if (patterns.length === 0) {\n updateSpinner.info(chalk.yellow(\"No high-success patterns to add\"));\n } else {\n let addedCount = 0;\n const limit = 5; // Top 5 patterns\n\n for (const pattern of patterns.slice(0, limit)) {\n await addPatternEntry(process.cwd(), {\n description: pattern.pattern,\n successRate: Math.round(pattern.successRate * 100),\n });\n addedCount++;\n }\n\n updateSpinner.succeed(chalk.green(`Added ${addedCount} success pattern(s) to knowledge base`));\n console.log(chalk.gray(` See .reygent/knowledge/success-patterns.md`));\n console.log();\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n updateSpinner.fail(chalk.red(`Failed to update knowledge: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeSuccess knowledge update error:', err);\n }\n }\n }\n\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to analyze success: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeSuccess error:', err);\n }\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze costs - cost breakdown and optimization\n */\nexport async function analyzeCosts(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing costs...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const costEvents = filterEvents(allEvents, { event: Events.USAGE_COST });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n\n await backend.close();\n\n if (costEvents.length === 0) {\n spinner.succeed(chalk.yellow(\"No cost data found\"));\n console.log(chalk.gray(\"\\nEnable verbose telemetry to track costs:\"));\n console.log(chalk.cyan(\" reygent run --telemetry-level verbose\\n\"));\n return;\n }\n\n const totalRuns = new Set(pipelineEvents.map(e => e.runId)).size;\n const successfulRuns = pipelineEvents.filter(e => e.data.success === true).length;\n const failedRuns = totalRuns - successfulRuns;\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${costEvents.length} cost event(s)`));\n\n console.log();\n console.log(chalk.bold(`Cost Analysis (last ${days} days, ${totalRuns} runs)`));\n console.log();\n\n // Calculate total costs\n const totalCost = costEvents.reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n\n // Separate successful vs failed run costs\n const successRunIds = new Set(\n pipelineEvents.filter(e => e.data.success === true).map(e => e.runId)\n );\n const successCost = costEvents\n .filter(e => successRunIds.has(e.runId))\n .reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n const failedCost = totalCost - successCost;\n\n console.log(chalk.bold(\"Total Spend:\"), chalk.cyan(formatCost(totalCost)));\n console.log(`Successful runs: ${formatCost(successCost)} (${formatPercent(successCost / totalCost)})`);\n console.log(`Failed runs: ${formatCost(failedCost)} (${formatPercent(failedCost / totalCost)} - wasted)`);\n console.log();\n\n // Cost by stage (if available)\n if (options.byAgent) {\n console.log(chalk.bold(\"Cost by Agent:\"));\n const agentCosts = new Map<string, { cost: number; runs: Set<string> }>();\n\n for (const event of costEvents) {\n const agent = event.data.agent as string || \"unknown\";\n const cost = event.data.costUsd as number;\n const existing = agentCosts.get(agent) || { cost: 0, runs: new Set() };\n existing.cost += cost;\n existing.runs.add(event.runId);\n agentCosts.set(agent, existing);\n }\n\n const sortedAgents = Array.from(agentCosts.entries())\n .sort((a, b) => b[1].cost - a[1].cost);\n\n for (const [agent, data] of sortedAgents) {\n const percent = (data.cost / totalCost) * 100;\n const avgCost = data.cost / data.runs.size;\n console.log(` ${agent}: ${formatCost(data.cost)} (${percent.toFixed(0)}%) - ${data.runs.size} runs, avg ${formatCost(avgCost)}/run`);\n }\n console.log();\n } else {\n console.log(chalk.bold(\"Cost by Stage:\"));\n const stageCosts = new Map<string, { cost: number; runs: Set<string> }>();\n\n for (const event of costEvents) {\n const stage = (event.data.stage as string) ?? \"unknown\";\n const cost = event.data.costUsd as number;\n const existing = stageCosts.get(stage) || { cost: 0, runs: new Set() };\n existing.cost += cost;\n existing.runs.add(event.runId);\n stageCosts.set(stage, existing);\n }\n\n const sortedStages = Array.from(stageCosts.entries())\n .sort((a, b) => b[1].cost - a[1].cost);\n\n for (const [stage, data] of sortedStages) {\n const percent = (data.cost / totalCost) * 100;\n const avgCost = data.cost / data.runs.size;\n console.log(` ${stage}: ${formatCost(data.cost)} (${percent.toFixed(0)}%) - ${data.runs.size} runs, avg ${formatCost(avgCost)}/run`);\n }\n console.log();\n }\n\n // Expensive failures\n if (failedRuns > 0 && options.showRuns) {\n console.log(chalk.bold(\"Expensive Failures (top 3):\"));\n\n const failedRunIds = new Set(\n pipelineEvents\n .filter(e => e.data.success !== true)\n .map(e => e.runId)\n );\n\n const failureRunCosts = new Map<string, number>();\n for (const event of costEvents) {\n if (failedRunIds.has(event.runId)) {\n const existing = failureRunCosts.get(event.runId) || 0;\n failureRunCosts.set(event.runId, existing + (event.data.costUsd as number));\n }\n }\n\n // Build Map for O(1) stage lookups\n const runIdToStage = new Map<string, string>();\n for (const event of allEvents) {\n if (event.event === Events.PIPELINE_STAGE_END) {\n runIdToStage.set(event.runId, (event.data.stage as string) || \"unknown\");\n }\n }\n\n const topFailures = Array.from(failureRunCosts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3);\n\n for (let i = 0; i < topFailures.length; i++) {\n const [runId, cost] = topFailures[i];\n const stage = runIdToStage.get(runId) || \"unknown stage\";\n console.log(` ${i + 1}. run ${runId.substring(0, 8)}: ${formatCost(cost)} (${stage})`);\n }\n console.log();\n }\n\n // Optimization opportunities\n console.log(chalk.bold(\"Optimization Opportunities:\"));\n const recommendations: string[] = [];\n\n if (failedCost > 0) {\n const wastePercent = (failedCost / totalCost) * 100;\n recommendations.push(`• ${formatPercent(failedCost / totalCost)} spend on failed runs - see 'reygent analyze failures' to reduce`);\n }\n\n const gateRetries = allEvents.filter(e => e.event === Events.GATE_RETRY);\n if (gateRetries.length > 0) {\n const monthlyCost = (totalCost / days) * 30;\n const retryCostEst = monthlyCost * RETRY_COST_ESTIMATE_MULTIPLIER;\n recommendations.push(`• Gate retry loops cost ~${formatCost(retryCostEst)}/month - review gate criteria`);\n }\n\n const potentialSavings = failedCost * POTENTIAL_SAVINGS_MULTIPLIER;\n if (potentialSavings > 0) {\n const monthlySavings = (potentialSavings / days) * 30;\n recommendations.push(`\\nPotential Savings: ${formatCost(monthlySavings)}/month (${formatPercent(potentialSavings / totalCost)})`);\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to analyze costs: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze agents - agent-specific performance breakdown\n */\nexport async function analyzeAgents(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing agent performance...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const agentSpawnEvents = filterEvents(allEvents, { event: Events.AGENT_SPAWN });\n const agentCompleteEvents = filterEvents(allEvents, { event: Events.AGENT_COMPLETE });\n const errorEvents = filterEvents(allEvents, { category: \"error\" });\n const costEvents = filterEvents(allEvents, { event: Events.USAGE_COST });\n\n await backend.close();\n\n if (agentSpawnEvents.length === 0) {\n spinner.succeed(chalk.yellow(\"No agent data found\"));\n return;\n }\n\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${agentSpawnEvents.length} agent spawn(s)`));\n\n console.log();\n console.log(chalk.bold(`Agent Performance Analysis (last ${days} days)`));\n console.log();\n\n // Build per-agent stats\n interface AgentStats {\n spawns: number;\n completions: number;\n successes: number;\n failures: number;\n totalDuration: number;\n totalCost: number;\n models: Map<string, number>;\n errorTypes: Map<string, number>;\n }\n\n const agentStats = new Map<string, AgentStats>();\n\n // Process spawns\n for (const spawn of agentSpawnEvents) {\n const agent = spawn.data.agent as string;\n const model = spawn.data.model as string;\n\n const stats = agentStats.get(agent) || {\n spawns: 0,\n completions: 0,\n successes: 0,\n failures: 0,\n totalDuration: 0,\n totalCost: 0,\n models: new Map(),\n errorTypes: new Map(),\n };\n\n stats.spawns++;\n stats.models.set(model, (stats.models.get(model) || 0) + 1);\n agentStats.set(agent, stats);\n }\n\n // Process completions\n for (const complete of agentCompleteEvents) {\n const agent = complete.data.agent as string;\n const success = complete.data.success === true;\n const duration = complete.data.duration as number;\n\n const stats = agentStats.get(agent);\n if (stats) {\n stats.completions++;\n if (success) {\n stats.successes++;\n } else {\n stats.failures++;\n }\n if (duration) stats.totalDuration += duration;\n }\n }\n\n // Process errors\n for (const error of errorEvents) {\n const agent = error.data.agent as string;\n const stats = agentStats.get(agent);\n if (stats) {\n const errorType = error.event;\n stats.errorTypes.set(errorType, (stats.errorTypes.get(errorType) || 0) + 1);\n }\n }\n\n // Process costs\n for (const cost of costEvents) {\n const agent = cost.data.agent as string;\n const stats = agentStats.get(agent);\n if (stats) {\n stats.totalCost += cost.data.costUsd as number;\n }\n }\n\n // Filter by specific agent if provided\n let agentsToShow: [string, AgentStats][];\n if (options.agent) {\n const requestedStats = agentStats.get(options.agent);\n if (!requestedStats) {\n spinner.warn(chalk.yellow(`Agent \"${options.agent}\" not found in telemetry data`));\n console.log(chalk.gray(`\\nAvailable agents: ${Array.from(agentStats.keys()).join(\", \")}`));\n return;\n }\n agentsToShow = [[options.agent, requestedStats]];\n } else {\n agentsToShow = Array.from(agentStats.entries());\n }\n\n // Display agent stats\n for (const [agent, stats] of agentsToShow) {\n\n const successRate = stats.completions > 0 ? stats.successes / stats.completions : 0;\n const avgDuration = stats.completions > 0 ? stats.totalDuration / stats.completions : 0;\n const avgCost = stats.completions > 0 ? stats.totalCost / stats.completions : 0;\n\n console.log(chalk.bold.cyan(agent + \":\"));\n console.log(` Runs: ${stats.completions}`);\n console.log(` Success rate: ${formatPercent(successRate)} (${stats.successes} success, ${stats.failures} failures)`);\n console.log(` Avg duration: ${formatDuration(avgDuration)}`);\n\n if (stats.totalCost > 0) {\n console.log(` Avg cost: ${formatCost(avgCost)}`);\n }\n\n const modelDist = Array.from(stats.models.entries())\n .map(([model, count]) => `${model} (${Math.round(count / stats.spawns * 100)}%)`)\n .join(\", \");\n console.log(` Model distribution: ${modelDist}`);\n\n // Compare models if requested\n if (options.compareModels && stats.models.size > 1) {\n console.log(`\\n Model Comparison:`);\n\n // Build model-specific stats\n const modelPerformance = new Map<string, { successes: number; failures: number; totalDuration: number; totalCost: number; count: number }>();\n\n for (const complete of agentCompleteEvents) {\n if (complete.data.agent !== agent) continue;\n\n // Find corresponding spawn to get model\n const spawn = agentSpawnEvents.find(s =>\n s.runId === complete.runId &&\n s.data.agent === agent &&\n s.timestamp <= complete.timestamp\n );\n\n if (!spawn) continue;\n const model = spawn.data.model as string;\n\n const perf = modelPerformance.get(model) || { successes: 0, failures: 0, totalDuration: 0, totalCost: 0, count: 0 };\n perf.count++;\n if (complete.data.success === true) {\n perf.successes++;\n } else {\n perf.failures++;\n }\n if (complete.data.duration) {\n perf.totalDuration += complete.data.duration as number;\n }\n\n // Find costs for this completion\n const runCosts = costEvents.filter(c => c.runId === complete.runId && c.data.agent === agent);\n for (const costEvent of runCosts) {\n perf.totalCost += costEvent.data.costUsd as number;\n }\n\n modelPerformance.set(model, perf);\n }\n\n for (const [model, perf] of modelPerformance) {\n const successRate = perf.count > 0 ? perf.successes / perf.count : 0;\n const avgDuration = perf.count > 0 ? perf.totalDuration / perf.count : 0;\n const avgCost = perf.count > 0 ? perf.totalCost / perf.count : 0;\n\n console.log(` ${model}: ${formatPercent(successRate)} success, avg ${formatDuration(avgDuration)}, avg ${formatCost(avgCost)}`);\n }\n console.log();\n }\n\n if (stats.errorTypes.size > 0) {\n const topErrors = Array.from(stats.errorTypes.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3)\n .map(([type, count]) => `${type} (${count})`)\n .join(\", \");\n console.log(` Top failures: ${topErrors}`);\n }\n\n console.log();\n }\n\n // Recommendations\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Find agents with high error rates\n for (const [agent, stats] of agentStats) {\n if (stats.completions > 0) {\n const failureRate = stats.failures / stats.completions;\n if (failureRate > 0.2 && stats.errorTypes.size > 0) {\n const topError = Array.from(stats.errorTypes.entries())\n .sort((a, b) => b[1] - a[1])[0];\n recommendations.push(`• ${agent}: High failure rate (${formatPercent(failureRate)}) - review ${topError[0]} errors`);\n }\n }\n }\n\n // Find best performer\n const sortedBySuccess = Array.from(agentStats.entries())\n .filter(([_, stats]) => stats.completions > 0)\n .map(([agent, stats]) => ({\n agent,\n successRate: stats.successes / stats.completions,\n }))\n .sort((a, b) => b.successRate - a.successRate);\n\n if (sortedBySuccess.length > 0 && sortedBySuccess[0].successRate >= 0.9) {\n recommendations.push(`• ${sortedBySuccess[0].agent}: Best performer (${formatPercent(sortedBySuccess[0].successRate)} success)`);\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to analyze agents: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Register analyze command and subcommands\n */\nexport function registerAnalyzeCommand(program: Command): void {\n const analyze = program\n .command(\"analyze\")\n .description(\"Analyze telemetry data for insights into failures, successes, costs, and performance\");\n\n analyze\n .command(\"failures\")\n .description(\"Show common failure patterns from telemetry\")\n .option(\"--agent <name>\", \"Filter by specific agent\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--limit <n>\", \"Show top N patterns\")\n .option(\"--update-knowledge\", \"Add patterns to .reygent/knowledge/common-failures.md\")\n .action(analyzeFailures);\n\n analyze\n .command(\"success\")\n .description(\"Extract patterns from successful runs\")\n .option(\"--stage <name>\", \"Filter by pipeline stage\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--min-success-rate <pct>\", \"Only show patterns above threshold (e.g., 85)\")\n .option(\"--update-knowledge\", \"Add patterns to .reygent/knowledge/success-patterns.md\")\n .action(analyzeSuccess);\n\n analyze\n .command(\"costs\")\n .description(\"Cost breakdown and optimization recommendations\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--by-agent\", \"Group by agent instead of stage\")\n .option(\"--show-runs\", \"List individual expensive runs\")\n .action(analyzeCosts);\n\n analyze\n .command(\"agents\")\n .description(\"Agent-specific performance breakdown\")\n .option(\"--agent <name>\", \"Show specific agent only\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--compare-models\", \"Compare model performance within agent\")\n .action(analyzeAgents);\n}\n","import { findProjectRoot } from \"./project-detection.js\";\n\n/**\n * Get telemetry database path for current context.\n * Returns project-local path if in project, undefined for global fallback.\n *\n * @param cwd - Current working directory to search from\n * @returns Absolute path to .reygent/chesstrace.db if in project, undefined otherwise\n */\nexport function getLocalTelemetryPath(cwd: string): string | undefined {\n const projectRoot = findProjectRoot(cwd);\n return projectRoot ? `${projectRoot}/.reygent/chesstrace.db` : undefined;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport { getLocalTelemetryPath } from \"../telemetry-path.js\";\n\ninterface LastOptions {\n verbose?: boolean;\n output?: boolean;\n errors?: boolean;\n json?: boolean;\n}\n\n/**\n * Format timestamp to readable date\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(\"T\", \" \").replace(/\\.\\d{3}Z$/, \"\");\n}\n\n/**\n * Format duration in milliseconds\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\n/**\n * Format USD cost\n */\nfunction formatCost(usd: number): string {\n return `$${usd.toFixed(4)}`;\n}\n\n/**\n * Check if telemetry is enabled\n */\nfunction checkTelemetryEnabled(config: ReturnType<typeof loadConfig>): void {\n if (!config.telemetry?.enabled) {\n console.log(chalk.yellow(\"\\nTelemetry disabled. Enable with:\"));\n console.log(chalk.cyan(\" reygent telemetry enable\\n\"));\n process.exit(1);\n }\n}\n\n/**\n * Display quick summary of latest run\n */\nfunction displaySummary(runId: string, events: TelemetryEvent[]): void {\n const pipelineEnd = events.find(e => e.event === Events.PIPELINE_END);\n const pipelineStart = events.find(e => e.event === Events.PIPELINE_START);\n const errorEvents = events.filter(e => e.category === \"error\");\n const costEvents = events.filter(e => e.event === Events.USAGE_COST);\n const agentSpawns = events.filter(e => e.event === Events.AGENT_SPAWN);\n\n const success = pipelineEnd?.data.success === true;\n const startTime = pipelineStart?.timestamp ?? events[0]?.timestamp ?? 0;\n const endTime = pipelineEnd?.timestamp ?? events[events.length - 1]?.timestamp ?? 0;\n const duration = endTime - startTime;\n\n const totalCost = costEvents.reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n const agents = [...new Set(agentSpawns.map(e => e.data.agent as string))];\n\n console.log();\n console.log(chalk.bold(\"Latest Run Summary\"));\n console.log();\n console.log(` Run ID: ${chalk.cyan(runId.substring(0, 8))}`);\n console.log(` Status: ${success ? chalk.green(\"Success\") : chalk.red(\"Failed\")}`);\n console.log(` Started: ${chalk.gray(formatTimestamp(startTime))}`);\n console.log(` Duration: ${formatDuration(duration)}`);\n console.log(` Agents: ${agents.join(\", \") || \"none\"}`);\n\n if (totalCost > 0) {\n console.log(` Cost: ${formatCost(totalCost)}`);\n }\n\n if (errorEvents.length > 0) {\n console.log();\n console.log(chalk.red(` Errors: ${errorEvents.length} error(s)`));\n\n const errorSummary = errorEvents.slice(0, 3).map(e => {\n const msg = e.data.message as string || e.event;\n return ` • ${msg}`;\n }).join(\"\\n\");\n console.log(errorSummary);\n\n if (errorEvents.length > 3) {\n console.log(` ... and ${errorEvents.length - 3} more`);\n }\n }\n\n console.log();\n}\n\n/**\n * Display verbose details\n */\nfunction displayVerbose(runId: string, events: TelemetryEvent[]): void {\n console.log();\n console.log(chalk.bold(`Detailed Event Log (${events.length} events)`));\n console.log();\n\n const table = new Table({\n head: [\n chalk.cyan(\"Time\"),\n chalk.cyan(\"Category\"),\n chalk.cyan(\"Event\"),\n chalk.cyan(\"Details\"),\n ],\n colWidths: [20, 15, 30, 50],\n wordWrap: true,\n });\n\n for (const event of events) {\n const timestamp = formatTimestamp(event.timestamp);\n const details = Object.keys(event.data).length > 0\n ? JSON.stringify(event.data).substring(0, 100)\n : \"\";\n\n table.push([\n chalk.gray(timestamp),\n event.category,\n event.event,\n chalk.gray(details),\n ]);\n }\n\n console.log(table.toString());\n console.log();\n}\n\n/**\n * Display only output\n */\nfunction displayOutput(events: TelemetryEvent[]): void {\n const pipelineEnd = events.find(e => e.event === Events.PIPELINE_END);\n const agentCompletes = events.filter(e => e.event === Events.AGENT_COMPLETE);\n\n console.log();\n console.log(chalk.bold(\"Run Output\"));\n console.log();\n\n if (pipelineEnd?.data.output) {\n console.log(pipelineEnd.data.output);\n } else if (agentCompletes.length > 0) {\n for (const complete of agentCompletes) {\n const agent = complete.data.agent as string;\n const output = complete.data.output as string;\n if (output) {\n console.log(chalk.cyan(`[${agent}]`));\n console.log(output);\n console.log();\n }\n }\n } else {\n console.log(chalk.yellow(\"No output captured\"));\n }\n\n console.log();\n}\n\n/**\n * Display only errors\n */\nfunction displayErrors(events: TelemetryEvent[]): void {\n const errorEvents = events.filter(e => e.category === \"error\");\n\n console.log();\n console.log(chalk.bold(`Errors (${errorEvents.length})`));\n console.log();\n\n if (errorEvents.length === 0) {\n console.log(chalk.green(\"No errors in this run\"));\n console.log();\n return;\n }\n\n for (const error of errorEvents) {\n const timestamp = formatTimestamp(error.timestamp);\n const message = error.data.message as string || \"Unknown error\";\n const agent = error.data.agent as string || \"unknown\";\n\n console.log(chalk.gray(timestamp) + chalk.red(` [${error.event}]`) + ` ${agent}`);\n console.log(` ${message}`);\n\n if (error.data.stack) {\n console.log(chalk.gray(` ${error.data.stack}`));\n }\n console.log();\n }\n}\n\n/**\n * Output as JSON\n */\nfunction displayJson(runId: string, events: TelemetryEvent[]): void {\n const output = {\n runId,\n eventCount: events.length,\n events,\n };\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Internal implementation for testing\n */\nexport async function lastCommandImpl(\n options: LastOptions,\n testBackend?: SqliteBackend\n): Promise<void> {\n const spinner = ora(\"Loading latest run...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n // Determine backend path - match writer path from run.ts\n const backend = testBackend ?? new SqliteBackend(\"local\", getLocalTelemetryPath(process.cwd()));\n if (!testBackend) {\n await backend.init();\n }\n\n const runs = await backend.listRuns();\n\n if (runs.length === 0) {\n spinner.fail(chalk.yellow(\"No telemetry runs found\"));\n console.log(chalk.gray(\"\\nRun a reygent command to generate telemetry data\"));\n if (!testBackend) {\n await backend.close();\n }\n return;\n }\n\n const latestRun = runs[0];\n const events = await backend.query({ runId: latestRun.runId });\n\n if (!testBackend) {\n await backend.close();\n }\n\n spinner.succeed(chalk.green(`Loaded latest run: ${latestRun.runId.substring(0, 8)}`));\n\n // Display based on options\n if (options.json) {\n displayJson(latestRun.runId, events);\n } else if (options.output) {\n displayOutput(events);\n } else if (options.errors) {\n displayErrors(events);\n } else if (options.verbose) {\n displayVerbose(latestRun.runId, events);\n } else {\n displaySummary(latestRun.runId, events);\n }\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load latest run: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * CLI command wrapper\n */\nexport async function lastCommand(options: LastOptions): Promise<void> {\n return lastCommandImpl(options);\n}\n\n/**\n * Register last command\n */\nexport function registerLastCommand(program: Command): void {\n program\n .command(\"last\")\n .description(\"Show details of the most recent run\")\n .option(\"--verbose\", \"Show full event log with timestamps and details\", false)\n .option(\"--output\", \"Show only the final output from the run\", false)\n .option(\"--errors\", \"Show only errors from the run\", false)\n .option(\"--json\", \"Output as JSON for machine parsing\", false)\n .action(lastCommand);\n}\n","import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { select, confirm } from '@inquirer/prompts';\nimport { inputWithTimeout, InputTimeoutError } from '../input-with-timeout.js';\nimport {\n findKnowledgeDir,\n listKnowledgeFiles,\n readMarkdown,\n searchKnowledge,\n parseMarkdownEntries,\n} from \"../knowledge/loader.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { measureKnowledgeEffectiveness } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { AgentName, builtinAgents } from \"../agents.js\";\n\n/**\n * Register knowledge subcommands under main CLI program\n */\nexport function registerKnowledgeCommand(program: Command) {\n const knowledge = program\n .command(\"knowledge\")\n .description(\"Manage living documentation in .reygent/knowledge/\");\n\n knowledge\n .command(\"list\")\n .description(\"List all knowledge files\")\n .action(listCommand);\n\n knowledge\n .command(\"show\")\n .description(\"Show specific knowledge file\")\n .argument(\"<file>\", \"Knowledge file to show (e.g., common-failures, agents/dev)\")\n .action(showCommand);\n\n knowledge\n .command(\"search\")\n .description(\"Search knowledge files for a query\")\n .argument(\"<query>\", \"Search query\")\n .action(searchCommand);\n\n knowledge\n .command(\"edit\")\n .description(\"Edit knowledge file in $EDITOR\")\n .argument(\"<file>\", \"Knowledge file to edit (e.g., common-failures, agents/dev)\")\n .action(editCommand);\n\n knowledge\n .command(\"add-failure\")\n .description(\"Document a failure pattern (interactive)\")\n .option(\"--run-id <id>\", \"Run ID to extract failure from\")\n .option(\"--issue <text>\", \"Issue description\")\n .option(\"--solution <text>\", \"Solution description\")\n .option(\"--agent <name>\", \"Affected agent\")\n .action(addFailureCommand);\n\n knowledge\n .command(\"add-pattern\")\n .description(\"Document a success pattern (interactive)\")\n .option(\"--run-id <id>\", \"Run ID to extract pattern from\")\n .option(\"--description <text>\", \"Pattern description\")\n .action(addPatternCommand);\n\n knowledge\n .command(\"stats\")\n .description(\"Show knowledge base statistics and effectiveness\")\n .option(\"--since <days>\", \"Time window in days (e.g., 30d)\", \"30d\")\n .action(statsCommand);\n}\n\n/**\n * List all knowledge files\n */\nasync function listCommand() {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.yellow(\"No .reygent/knowledge/ directory found.\"));\n console.log(\n chalk.gray(\"Run from a project with .reygent/ or create one with:\"),\n );\n console.log(chalk.cyan(\" reygent init\"));\n return;\n }\n\n const files = listKnowledgeFiles();\n\n if (files.length === 0) {\n console.log(chalk.yellow(\"No knowledge files found.\"));\n return;\n }\n\n console.log(chalk.bold(\"\\nKnowledge Files:\"));\n console.log();\n\n const table = new Table({\n head: [chalk.cyan(\"File\"), chalk.cyan(\"Type\")],\n colWidths: [40, 30],\n });\n\n for (const file of files) {\n const type = file.startsWith(\"agents/\")\n ? \"Agent-specific\"\n : file.replace(\".md\", \"\").replace(/-/g, \" \");\n table.push([file, type]);\n }\n\n console.log(table.toString());\n console.log();\n console.log(chalk.gray(`View file: ${chalk.white(\"reygent knowledge show <file>\")}`));\n console.log(chalk.gray(`Search: ${chalk.white(\"reygent knowledge search <query>\")}`));\n}\n\n/**\n * Show specific knowledge file\n */\nasync function showCommand(file: string) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n // Normalize file path (add .md if missing)\n const normalizedFile = file.endsWith(\".md\") ? file : `${file}.md`;\n const filePath = join(knowledgeDir, normalizedFile);\n\n try {\n const content = readMarkdown(filePath);\n if (content === null) {\n console.log(chalk.red(`Knowledge file validation failed: ${normalizedFile}`));\n console.log(chalk.gray(\"File may contain suspicious content or be malformed.\"));\n process.exit(1);\n }\n if (content === \"\") {\n console.log(chalk.yellow(`Knowledge file is empty or not found: ${normalizedFile}`));\n console.log(chalk.gray(\"Available files:\"));\n const files = listKnowledgeFiles();\n files.forEach((f) => console.log(chalk.gray(` - ${f}`)));\n process.exit(1);\n }\n\n console.log(chalk.bold(`\\n${normalizedFile}\\n`));\n console.log(content);\n console.log();\n } catch (err) {\n console.log(chalk.red(`Failed to read ${normalizedFile}: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Search knowledge files\n */\nasync function searchCommand(query: string) {\n const spinner = ora(`Searching for \"${query}\"...`).start();\n\n try {\n const results = searchKnowledge(query);\n\n if (results.length === 0) {\n spinner.fail(chalk.yellow(\"No matches found.\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Found ${results.length} match(es)`));\n console.log();\n\n for (const result of results) {\n console.log(chalk.bold.cyan(`${result.file}`));\n console.log(chalk.bold(` ${result.entry.title}`));\n console.log(chalk.gray(` ${result.excerpt}`));\n console.log();\n }\n } catch (err) {\n spinner.fail(chalk.red(`Search failed: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Edit knowledge file in $EDITOR\n */\nasync function editCommand(file: string) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n const normalizedFile = file.endsWith(\".md\") ? file : `${file}.md`;\n const filePath = join(knowledgeDir, normalizedFile);\n\n const editor = process.env.EDITOR || \"vi\";\n\n console.log(chalk.cyan(`Opening ${normalizedFile} in ${editor}...`));\n\n try {\n execSync(`${editor} \"${filePath}\"`, { stdio: \"inherit\" });\n console.log(chalk.green(\"File saved.\"));\n } catch (err) {\n console.log(chalk.red(`Failed to open editor: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Add failure documentation (interactive/manual)\n */\nasync function addFailureCommand(options: {\n runId?: string;\n issue?: string;\n solution?: string;\n agent?: string;\n example?: string;\n}) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n console.log(chalk.gray(\"Run 'reygent init' to create knowledge directory.\"));\n process.exit(1);\n }\n\n // Interactive prompts if options not provided\n let issue = options.issue;\n let solution = options.solution;\n let agent = options.agent as AgentName | undefined;\n let example = options.example;\n\n if (!issue) {\n try {\n issue = await inputWithTimeout({\n message: 'What is the issue/error?',\n validate: (value) => value.trim() !== '' || 'Issue description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!solution) {\n try {\n solution = await inputWithTimeout({\n message: 'What is the solution/fix?',\n validate: (value) => value.trim() !== '' || 'Solution description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!agent) {\n const agentChoices = builtinAgents.map((a) => ({ value: a.name, name: a.name }));\n agent = await select({\n message: 'Which agent does this apply to?',\n choices: agentChoices,\n }) as AgentName;\n }\n\n if (!example) {\n const addExample = await confirm({\n message: 'Add a code example?',\n default: false,\n });\n\n if (addExample) {\n try {\n example = await inputWithTimeout({\n message: 'Enter code example:',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n // Use manager to add entry\n const baseDir = knowledgeDir.replace('/.reygent/knowledge', '');\n await addFailureEntry(baseDir, {\n issue,\n solution,\n agent,\n example,\n });\n\n console.log(chalk.green(\"✓ Failure documented\"));\n console.log(chalk.gray(` File: common-failures.md`));\n console.log(chalk.gray(` Agent: ${agent}`));\n}\n\n/**\n * Add success pattern (interactive/manual)\n */\nasync function addPatternCommand(options: {\n runId?: string;\n description?: string;\n approach?: string;\n successRate?: number;\n}) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n console.log(chalk.gray(\"Run 'reygent init' to create knowledge directory.\"));\n process.exit(1);\n }\n\n // Interactive prompts if options not provided\n let description = options.description;\n let approach = options.approach;\n let successRate = options.successRate;\n\n if (!description) {\n try {\n description = await inputWithTimeout({\n message: 'Describe the success pattern:',\n validate: (value) => value.trim() !== '' || 'Description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!approach) {\n const addApproach = await confirm({\n message: 'Add detailed approach?',\n default: false,\n });\n\n if (addApproach) {\n try {\n approach = await inputWithTimeout({\n message: 'Describe the approach:',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n if (successRate === undefined) {\n const addRate = await confirm({\n message: 'Add success rate?',\n default: false,\n });\n\n if (addRate) {\n try {\n const rateStr = await inputWithTimeout({\n message: 'Enter success rate (0-100):',\n validate: (value) => {\n const num = parseFloat(value);\n return (!isNaN(num) && num >= 0 && num <= 100) || 'Must be a number between 0 and 100';\n },\n });\n successRate = parseFloat(rateStr);\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n // Use manager to add entry\n const baseDir = knowledgeDir.replace('/.reygent/knowledge', '');\n await addPatternEntry(baseDir, {\n description,\n approach,\n successRate,\n });\n\n console.log(chalk.green(\"✓ Pattern documented\"));\n console.log(chalk.gray(` File: success-patterns.md`));\n}\n\n/**\n * Show knowledge base statistics\n */\nasync function statsCommand(options: { since?: string }) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n const spinner = ora(\"Calculating knowledge base stats...\").start();\n\n try {\n // Parse since parameter\n const since = options.since || \"30d\";\n const match = since.match(/^(\\d+)d$/);\n if (!match) {\n spinner.fail(chalk.red(`Invalid --since format: ${since}. Use format like \"30d\".`));\n process.exit(1);\n }\n const days = Number.parseInt(match[1], 10);\n const sinceMs = Date.now() - days * 24 * 60 * 60 * 1000;\n\n // Get knowledge file counts\n const files = listKnowledgeFiles();\n const totalEntries = files.reduce((count, file) => {\n const filePath = join(knowledgeDir, file);\n const content = readMarkdown(filePath);\n const entries = parseMarkdownEntries(content, filePath);\n return count + entries.length;\n }, 0);\n\n // Get effectiveness metrics from telemetry\n const chesstrace = getChesstrace();\n if (!chesstrace) {\n spinner.fail(chalk.yellow(\"Telemetry not available. Cannot calculate effectiveness.\"));\n console.log();\n console.log(chalk.bold(\"Knowledge Base Stats\"));\n console.log();\n console.log(`Files: ${files.length}`);\n console.log(`Total entries: ${totalEntries}`);\n return;\n }\n\n const backend = chesstrace.getBackend();\n const effectiveness = measureKnowledgeEffectiveness(backend, sinceMs);\n\n spinner.succeed(chalk.green(\"Stats calculated\"));\n console.log();\n console.log(chalk.bold(\"Knowledge Base Stats\"));\n console.log();\n\n // File stats\n console.log(chalk.cyan(\"Files:\"), files.length);\n console.log(chalk.cyan(\"Total entries:\"), totalEntries);\n console.log();\n\n // Usage stats\n console.log(chalk.bold(`Usage (last ${days} days):`));\n console.log(chalk.cyan(\" Consulted runs:\"), effectiveness.consultedRuns);\n console.log(chalk.cyan(\" Baseline runs:\"), effectiveness.baselineRuns);\n console.log();\n\n // Effectiveness\n if (effectiveness.consultedRuns > 0 || effectiveness.baselineRuns > 0) {\n const withKnowledgePct = Math.round(effectiveness.withKnowledge * 100);\n const baselinePct = Math.round(effectiveness.baseline * 100);\n const improvementPct = Math.round(effectiveness.improvement * 100);\n\n console.log(chalk.bold(\"Effectiveness:\"));\n console.log(chalk.cyan(\" Success rate with knowledge:\"), `${withKnowledgePct}%`);\n console.log(chalk.cyan(\" Baseline success rate:\"), `${baselinePct}%`);\n\n const improvementColor = effectiveness.improvement > 0 ? chalk.green : effectiveness.improvement < 0 ? chalk.red : chalk.gray;\n console.log(chalk.cyan(\" Improvement:\"), improvementColor(`${improvementPct > 0 ? \"+\" : \"\"}${improvementPct}%`));\n } else {\n console.log(chalk.gray(\"No runs found in time window to measure effectiveness.\"));\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to calculate stats: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n","/**\n * Wrapper for @inquirer/prompts input() with timeout support\n */\nimport { input } from '@inquirer/prompts';\n\nconst DEFAULT_TIMEOUT_MS = 60000; // 60 seconds\n\nexport class InputTimeoutError extends Error {\n constructor(message: string = 'Input prompt timed out') {\n super(message);\n this.name = 'InputTimeoutError';\n }\n}\n\n/**\n * Prompts for input with optional timeout.\n * Throws InputTimeoutError if timeout exceeded.\n */\nexport async function inputWithTimeout(\n config: Parameters<typeof input>[0],\n timeoutMs: number = DEFAULT_TIMEOUT_MS\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new InputTimeoutError(`Input prompt timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n input(config)\n .then(result => {\n clearTimeout(timer);\n resolve(result);\n })\n .catch(err => {\n clearTimeout(timer);\n reject(err);\n });\n });\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, lstatSync, renameSync, unlinkSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { findLocalConfigDir, resolveGlobalConfigPath } from \"../config.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport { isDebug } from \"../debug.js\";\n\n/**\n * Check if telemetry opt-in prompt should be shown.\n *\n * CRITICAL: This function REQUIRES a TTY (interactive terminal). It will never\n * prompt in non-interactive environments (CI, piped input, automated scripts).\n *\n * Returns true when:\n * 1. stdin is a TTY (interactive terminal)\n * 2. telemetry.enabled is undefined in config\n *\n * Returns false in all other cases, including non-TTY environments.\n */\nexport function shouldPromptForTelemetry(): boolean {\n // CRITICAL: Never prompt in non-TTY environments (CI, piped input, etc.)\n if (!process.stdin.isTTY) {\n return false;\n }\n\n // Find config path (local takes precedence)\n const localConfigDir = findLocalConfigDir(process.cwd());\n let configPath: string | null = null;\n\n if (localConfigDir) {\n const localPath = join(localConfigDir, \"config.json\");\n if (existsSync(localPath)) {\n configPath = localPath;\n }\n }\n\n if (!configPath) {\n const globalPath = resolveGlobalConfigPath();\n if (existsSync(globalPath)) {\n configPath = globalPath;\n }\n }\n\n // No config file exists → enabled is undefined → should prompt\n if (!configPath) {\n return true;\n }\n\n // Read config to check telemetry.enabled\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as ReygentConfig;\n\n // Prompt if telemetry field missing or enabled is undefined\n if (!parsed.telemetry || parsed.telemetry.enabled === undefined) {\n return true;\n }\n\n return false;\n } catch (err) {\n // If config parse fails, prompt user to regenerate valid config\n if (isDebug()) {\n console.error(chalk.gray(`Failed to read config at ${configPath}:`), err);\n }\n return true;\n }\n}\n\n/**\n * Prompt user to opt into telemetry and save choice to config.\n * Saves to local config if .reygent/ dir exists, else global.\n */\nexport async function promptForTelemetryOptIn(): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\"First-run telemetry setup\"));\n console.log(chalk.gray(\"Reygent can collect local usage data to help diagnose issues.\"));\n console.log(chalk.gray(\"Data is stored locally in SQLite and never sent to external servers.\"));\n console.log(\"\");\n\n const enabled = await confirm({\n message: \"Enable local telemetry?\",\n default: false,\n });\n\n await saveTelemetryChoice(enabled);\n\n console.log(\"\");\n if (enabled) {\n console.log(chalk.green(\"✓\"), \"Local telemetry enabled\");\n } else {\n console.log(chalk.gray(\"✓\"), \"Local telemetry disabled\");\n }\n console.log(\"\");\n}\n\n/**\n * Save telemetry choice to config (local if exists, else global).\n */\nasync function saveTelemetryChoice(enabled: boolean): Promise<void> {\n const localConfigDir = findLocalConfigDir(process.cwd());\n let configPath: string;\n let configDir: string;\n\n if (localConfigDir) {\n configPath = join(localConfigDir, \"config.json\");\n configDir = localConfigDir;\n } else {\n configPath = resolveGlobalConfigPath();\n configDir = dirname(configPath);\n mkdirSync(configDir, { recursive: true });\n }\n\n // Load existing config or create new one\n let rawConfig: Record<string, unknown> = {};\n if (existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } catch (err) {\n if (isDebug()) {\n console.error(chalk.gray(`Failed to parse config at ${configPath}:`), err);\n }\n // Continue with empty config\n }\n }\n\n // Merge telemetry.enabled into config\n const telemetry = (rawConfig.telemetry as Record<string, unknown> | undefined) ?? {};\n telemetry.enabled = enabled;\n\n // Apply defaults if missing\n telemetry.level = telemetry.level ?? \"standard\";\n telemetry.backend = telemetry.backend ?? \"sqlite\";\n telemetry.retention = telemetry.retention ?? 30;\n\n rawConfig.telemetry = telemetry;\n\n // Atomic write\n try {\n const tempPath = `${configPath}.tmp.${randomBytes(8).toString(\"hex\")}`;\n\n try {\n writeFileSync(tempPath, JSON.stringify(rawConfig, null, 2) + \"\\n\", \"utf-8\");\n\n // Security: verify temp file is not symlink\n const tempStats = lstatSync(tempPath);\n if (tempStats.isSymbolicLink()) {\n unlinkSync(tempPath);\n throw new Error(\"Security: temp file became symlink\");\n }\n\n renameSync(tempPath, configPath);\n } catch (err) {\n // Clean up temp file on error\n try {\n unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.yellow(\"Warning:\"), `Failed to save telemetry config: ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n console.log(chalk.gray(\"Command will continue without saving telemetry preference.\"));\n // Don't throw - allow command execution to continue\n }\n}\n"],"mappings":"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","names":["readFileSync","dirname","join","fileURLToPath","chalk","existsSync","readFileSync","join","z","z","readFileSync","path","join","existsSync","chalk","input","resolve","chalk","spawn","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","availabilityCache","resolve","spawn","chalk","code","spawn","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","availabilityCache","resolve","spawn","chalk","code","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","chalk","SUPPORTED_MODELS","DEFAULT_MODEL","chalk","existsSync","readFileSync","basename","resolve","chalk","input","existsSync","readFileSync","resolve","chalk","TelemetryLevel","chalk","resolve","existsSync","chalk","basename","readFileSync","join","dirname","existsSync","statSync","join","existsSync","dirname","statSync","events","existsSync","join","dirname","telemetryOverride","chalk","createInterface","resolve","chalk","existsSync","readFileSync","readdirSync","statSync","join","chalk","join","existsSync","readFileSync","chalk","readdirSync","statSync","prompt","prompt","chesstrace","prompt","chalk","chalk","createInterface","resolve","chalk","chalk","select","stripAnsi","chalk","isLinearUrl","select","createInterface","join","chalk","ora","select","chalk","prompt","chalk","prompt","readFileSync","resolve","readFileSync","execFile","chalk","input","prompt","chalk","exec","resolve","execFile","chalk","chalk","prompt","chalk","chalk","existsSync","mkdirSync","createInterface","chalk","createInterface","resolve","chalk","chalk","select","telemetryOverride","join","existsSync","mkdirSync","createInterface","resolve","result","chesstrace","ora","existsSync","mkdirSync","writeFileSync","join","ExitPromptError","select","chalk","ora","join","DEFAULT_MODEL","chalk","existsSync","select","ora","mkdirSync","writeFileSync","ExitPromptError","existsSync","mkdirSync","writeFileSync","readdirSync","statSync","readFileSync","join","dirname","chalk","ora","existsSync","readFileSync","readdirSync","statSync","mkdirSync","join","join","existsSync","mkdirSync","readdirSync","statSync","readFileSync","__dirname","dirname","pkg","readFileSync","join","existsSync","readdirSync","statSync","ora","chalk","mkdirSync","writeFileSync","program","execFile","httpsRequest","chalk","ora","input","exec","resolve","execFile","httpsRequest","httpsPost","input","prompt","chalk","ora","execFile","httpsRequest","chalk","select","exec","resolve","execFile","getCurrentBranch","getDefaultBranch","detectGitHubPR","httpsGet","httpsRequest","detectGitLabMR","chalk","prompt","buildDevPrompt","select","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","chalk","select","chalk","select","join","dirname","mkdirSync","existsSync","readFileSync","provider","writeFileSync","statSync","writeFileSync","chalk","ora","join","formatDuration","statSync","ora","chalk","writeFileSync","program","chalk","ora","formatDuration","formatCost","chalk","ora","events","limit","spawn","successRate","avgDuration","avgCost","program","chalk","ora","Table","formatTimestamp","formatDuration","formatCost","checkTelemetryEnabled","chalk","Table","ora","program","join","chalk","ora","Table","select","confirm","resolve","program","showCommand","chalk","Table","join","ora","select","confirm","existsSync","readFileSync","writeFileSync","mkdirSync","lstatSync","renameSync","unlinkSync","join","dirname","randomBytes","confirm","chalk","join","existsSync","readFileSync","chalk","confirm","dirname","mkdirSync","randomBytes","writeFileSync","lstatSync","unlinkSync","renameSync","dirname","fileURLToPath","readFileSync","join","chalk","noTelemetry"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/child-registry.ts","../src/debug.ts","../src/model.ts","../src/config.ts","../src/agents.ts","../src/skills.ts","../src/chesstrace/config.ts","../src/task.ts","../src/providers/claude.ts","../src/providers/gemini.ts","../src/providers/codex.ts","../src/providers/openrouter.ts","../src/providers/index.ts","../src/telemetry-override.ts","../src/commands/agent.ts","../src/spec.ts","../src/linear.ts","../src/jira.ts","../src/env.ts","../src/chesstrace/index.ts","../src/chesstrace/events.ts","../src/terminal-reset.ts","../src/chesstrace/backends/sqlite.ts","../src/chesstrace/backends/dual.ts","../src/project-detection.ts","../src/telemetry-lifecycle.ts","../src/commands/generate-spec.ts","../src/knowledge/loader.ts","../src/test-env.ts","../src/telemetry-helpers.ts","../src/spawn.ts","../src/planner.ts","../src/generate-spec.ts","../src/live-status.ts","../src/format.ts","../src/commands/spec.ts","../src/cursor-aware-input.ts","../src/paste-state.ts","../src/pasteable-input.ts","../src/commands/run.ts","../src/implement.ts","../src/gate.ts","../src/pr-create.ts","../src/branch-type.ts","../src/pr-review.ts","../src/diff-split.ts","../src/security-review.ts","../src/usage.ts","../src/pricing.ts","../src/knowledge/analyzer.ts","../src/knowledge/manager.ts","../src/retry-prompt.ts","../src/commands/init.ts","../src/commands/skills.ts","../src/registry.ts","../src/commands/review-work.ts","../src/spec-prefix.ts","../src/commands/review-comments.ts","../src/commands/config.ts","../src/commands/telemetry.ts","../src/commands/analyze.ts","../src/telemetry-path.ts","../src/commands/last.ts","../src/commands/knowledge.ts","../src/input-with-timeout.ts","../src/chesstrace/prompt.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport { killAllChildrenProcesses } from \"./child-registry.js\";\nimport { setDebug } from \"./debug.js\";\nimport { setModelOverride, setProviderOverride, validateModel } from \"./model.js\";\nimport { getProvider, PROVIDER_NAMES } from \"./providers/index.js\";\nimport { setTelemetryOverride, isValidTelemetryLevel } from \"./telemetry-override.js\";\nimport { agentCommand } from \"./commands/agent.js\";\nimport { generateSpecCommand } from \"./commands/generate-spec.js\";\nimport { specCommand } from \"./commands/spec.js\";\nimport { runCommand } from \"./commands/run.js\";\nimport { initCommand } from \"./commands/init.js\";\nimport { registerSkillsCommand } from \"./commands/skills.js\";\nimport { reviewWorkCommand } from \"./commands/review-work.js\";\nimport { reviewCommentsCommand } from \"./commands/review-comments.js\";\nimport { configCommand } from \"./commands/config.js\";\nimport { registerTelemetryCommand } from \"./commands/telemetry.js\";\nimport { registerAnalyzeCommand } from \"./commands/analyze.js\";\nimport { registerLastCommand } from \"./commands/last.js\";\nimport { registerKnowledgeCommand } from \"./commands/knowledge.js\";\nimport { isValidType, VALID_BRANCH_TYPES } from \"./branch-type.js\";\nimport { shouldPromptForTelemetry, promptForTelemetryOptIn } from \"./chesstrace/prompt.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"),\n);\n\nconst program = new Command();\n\nprogram\n .name(\"reygent\")\n .description(\"Reygent CLI tool\")\n .version(pkg.version)\n .option(\"--debug\", \"Show full stack traces on errors (or set REYGENT_DEBUG=1)\")\n .option(\"--model <id>\", \"Model ID (e.g. claude-sonnet-4-5, gemini-2.5-pro, gpt-5.4)\")\n .option(\"--provider <name>\", `AI provider (${PROVIDER_NAMES.join(\", \")})`)\n .option(\"--no-telemetry\", \"Disable telemetry for this run\")\n .option(\"--telemetry-level <level>\", \"Override telemetry level (minimal, standard, verbose)\")\n .option(\"--telemetry-verbose\", \"Shorthand for --telemetry-level verbose\")\n .addHelpText(\"after\", `\n${chalk.yellow(\"Disclaimer:\")} This software is provided \"as is\" with no warranty. AI-generated output should be reviewed by a human. See LICENSE for full terms.`);\n\nprogram\n .command(\"init\")\n .description(\"Initialize .reygent folder with default agent and skill config\")\n .option(\"--dry-run\", \"Preview what files would be created without writing anything\", false)\n .action(initCommand);\n\nprogram\n .command(\"generate-spec\")\n .description(\"Generate a full markdown spec from a short description\")\n .argument(\"[description]\", \"Short description of the feature to spec out\")\n .option(\"--output <file>\", \"Output file path\")\n .option(\"--skip-clarification\", \"Skip clarifying questions and generate spec directly\", false)\n .action(generateSpecCommand);\n\nprogram\n .command(\"spec\")\n .description(\"Load a spec from a markdown file, Jira issue, or Linear issue\")\n .argument(\"<source>\", \"Path to a markdown file, issue key (e.g. PROJ-123), or Linear URL\")\n .option(\"--clarify\", \"Run planner with clarification loop to evaluate spec\", false)\n .option(\"--source <name>\", \"Issue source provider (jira, linear, local) — skips interactive prompt\")\n .action(specCommand);\n\nprogram\n .command(\"agent\")\n .description(\"Start an interactive agent session\")\n .argument(\"[name]\", \"Agent name (dev, qe, planner, security-reviewer, pr-reviewer, adhoc)\")\n .option(\"--spec <source>\", \"Path to a markdown file, issue key, or Linear URL\")\n .action(agentCommand);\n\nprogram\n .command(\"run\")\n .description(\"Run the reygent workflow from spec to reviewed PR\")\n .option(\"--spec <source>\", \"Path to a markdown file, issue key, or Linear URL (prompts if omitted in interactive mode)\")\n .option(\"--type <type>\", \"Branch type (feat, fix, chore, refactor, docs, test, style, perf) — skips interactive prompt\")\n .option(\"--dry-run\", \"Preview workflow stages without executing\", false)\n .option(\"--security-threshold <level>\", \"Minimum severity to fail security review (CRITICAL, HIGH, MEDIUM, LOW)\", \"HIGH\")\n .option(\"--auto-approve\", \"Auto-approve all file edits and actions without prompting\", false)\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .option(\"--skip-clarification\", \"Skip planner clarification and make assumptions\", false)\n .option(\"--max-retries <count>\", \"Max retry attempts when gate tests fail\", \"2\")\n .option(\"--verbose\", \"Show detailed per-agent token and cost breakdown\", false)\n .hook(\"preAction\", (thisCommand) => {\n const opts = thisCommand.opts();\n if (opts.type && !isValidType(opts.type)) {\n console.error(chalk.red(`Error: Invalid --type \"${opts.type}\". Must be one of: ${VALID_BRANCH_TYPES.join(\", \")} (or feature/bugfix aliases)`));\n process.exit(1);\n }\n })\n .action(runCommand);\n\nprogram\n .command(\"review-work\")\n .description(\"Review current branch and post summary to PR/MR\")\n .option(\"--spec <source>\", \"Spec source with provider prefix (jira:KEY, linear:ID, markdown:FILE) — file paths auto-infer markdown:\")\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .action(reviewWorkCommand);\n\nprogram\n .command(\"review-comments\")\n .description(\"Fetch PR/MR review comments and address them with an agent\")\n .option(\"--insecure\", \"Skip SSL certificate verification for API calls\", false)\n .option(\"--auto-approve\", \"Auto-approve plan and execute without prompting\", false)\n .option(\"--retry-commits <count>\", \"Max retries for pre-commit hook failures (default: 3)\", (val) => {\n const num = parseInt(val, 10);\n if (isNaN(num) || num < 0 || num > 10) {\n throw new Error(\"--retry-commits must be between 0 and 10\");\n }\n return num;\n })\n .action(reviewCommentsCommand);\n\nprogram\n .command(\"config\")\n .description(\"Configure default provider, model, and per-agent overrides\")\n .action(configCommand);\n\nregisterTelemetryCommand(program);\nregisterAnalyzeCommand(program);\nregisterLastCommand(program);\nregisterSkillsCommand(program);\nregisterKnowledgeCommand(program);\n\n// Show header on commands that do actual work (not --help or --version)\nconst isHelpOrVersion = process.argv.includes(\"--help\") ||\n process.argv.includes(\"-h\") ||\n process.argv.includes(\"--version\") ||\n process.argv.includes(\"-V\") ||\n process.argv.length <= 2;\n\nif (!isHelpOrVersion) {\n console.log(chalk.bold.cyan(`\\nreygent`) + chalk.gray(` v${pkg.version}`) + \"\\n\");\n}\n\n// Set debug flag, provider, model, and telemetry overrides before any command action runs\nprogram.hook(\"preAction\", async () => {\n if (program.opts().debug) {\n setDebug(true);\n }\n\n try {\n const providerFlag = program.opts().provider;\n if (providerFlag) {\n try {\n // Validate provider name\n getProvider(providerFlag);\n setProviderOverride(providerFlag);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n program.error(message);\n }\n }\n\n // Apply telemetry flag overrides (validate before model to avoid partial execution)\n const noTelemetry = program.opts().telemetry === false;\n const telemetryLevelFlag = program.opts().telemetryLevel;\n const telemetryVerbose = program.opts().telemetryVerbose === true;\n\n if (noTelemetry) {\n setTelemetryOverride({ disabled: true });\n } else if (telemetryVerbose) {\n setTelemetryOverride({ level: \"verbose\" });\n } else if (telemetryLevelFlag) {\n if (!isValidTelemetryLevel(telemetryLevelFlag)) {\n program.error(\n `Invalid --telemetry-level \"${telemetryLevelFlag}\". Must be one of: minimal, standard, verbose`\n );\n }\n setTelemetryOverride({ level: telemetryLevelFlag });\n }\n\n const modelFlag = program.opts().model;\n if (modelFlag) {\n try {\n const resolved = validateModel(modelFlag, providerFlag);\n setModelOverride(resolved);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n program.error(message);\n }\n }\n } catch (err) {\n // Unexpected error in validation - log but continue to telemetry prompt\n if (program.opts().debug) {\n console.error(chalk.gray(\"Validation error:\"), err);\n }\n }\n\n // Show telemetry opt-in prompt on first run (unless --no-telemetry flag set)\n const noTelemetry = program.opts().telemetry === false;\n if (!noTelemetry && shouldPromptForTelemetry()) {\n try {\n await promptForTelemetryOptIn();\n } catch (err) {\n // Ctrl+C from inquirer\n if (err && typeof err === \"object\" && \"name\" in err && (err as { name: string }).name === \"ExitPromptError\") {\n console.log(chalk.yellow(\"\\nTelemetry setup cancelled.\"));\n process.exit(0);\n }\n // Other errors shouldn't block command execution\n if (program.opts().debug) {\n console.error(chalk.gray(\"Telemetry prompt failed:\"), err);\n }\n }\n }\n});\n\n// Fallback SIGINT handler: kill child processes when no live-status handler is active\nprocess.on(\"SIGINT\", () => {\n killAllChildrenProcesses();\n process.exit(130);\n});\n\nprogram.parse();\n","import type { ChildProcess } from \"node:child_process\";\n\nconst activeChildProcesses = new Set<ChildProcess>();\n\nexport function registerChildProcess(child: ChildProcess): void {\n activeChildProcesses.add(child);\n child.on(\"close\", () => {\n activeChildProcesses.delete(child);\n });\n child.on(\"error\", () => {\n activeChildProcesses.delete(child);\n });\n}\n\nexport function killAllChildrenProcesses(): void {\n for (const child of activeChildProcesses) {\n try {\n // Kill entire process group to catch spawned descendants (e.g., vitest)\n if (child.pid && process.platform !== \"win32\") {\n process.kill(-child.pid, \"SIGTERM\");\n } else {\n child.kill(\"SIGTERM\");\n }\n } catch {\n // Already dead — ignore\n }\n }\n activeChildProcesses.clear();\n}\n\n// Kill orphaned child processes on any exit path\nprocess.on(\"exit\", () => {\n killAllChildrenProcesses();\n});\n\n// Handle SIGINT (Ctrl+C) and SIGTERM\nprocess.on(\"SIGINT\", () => {\n killAllChildrenProcesses();\n process.exit(130); // Standard exit code for SIGINT\n});\n\nprocess.on(\"SIGTERM\", () => {\n killAllChildrenProcesses();\n process.exit(143); // Standard exit code for SIGTERM\n});\n","let debugEnabled = false;\n\nexport function setDebug(enabled: boolean): void {\n debugEnabled = enabled;\n}\n\nexport function isDebug(): boolean {\n return debugEnabled || process.env.REYGENT_DEBUG === \"1\";\n}\n","import chalk from \"chalk\";\nimport { loadConfig } from \"./config.js\";\nimport { TaskError } from \"./task.js\";\nimport { getProvider } from \"./providers/index.js\";\nimport type { ModelEntry } from \"./providers/types.js\";\n\n// Re-export for backward compat\nexport type { ModelEntry };\n\n// Legacy exports — delegate to Claude adapter\nexport const SUPPORTED_MODELS: ModelEntry[] = getProvider(\"claude\").supportedModels;\nexport const DEFAULT_MODEL = getProvider(\"claude\").defaultModel;\n\nlet modelOverride: string | null = null;\nlet providerOverride: string | null = null;\n\n// Track warned custom models to avoid repeated warnings in same session\nconst warnedCustomModels = new Set<string>();\n\nexport function setModelOverride(id: string): void {\n modelOverride = id;\n}\n\nexport function setProviderOverride(name: string): void {\n providerOverride = name;\n}\n\n/**\n * Resolve alias for a given provider. Falls back to identity if no alias found.\n */\nexport function resolveAlias(id: string, providerName?: string): string {\n const provider = getProvider(providerName ?? resolveProvider());\n return provider.shortAliases[id] ?? id;\n}\n\n/**\n * Validate model ID against a provider's supported models.\n * If provider not specified, uses resolved provider.\n * Pass-through providers (openrouter) accept any model.\n * Custom models (not in supported list) trigger a warning but are allowed.\n */\nexport function validateModel(id: string, providerName?: string): string {\n const name = providerName ?? resolveProvider();\n const provider = getProvider(name);\n const resolved = provider.shortAliases[id] ?? id;\n\n // OpenRouter accepts any model slug — pass-through\n if (name === \"openrouter\") return resolved;\n\n // Check if model in supported list\n const valid = provider.supportedModels.some((m) => m.id === resolved);\n if (!valid) {\n // Allow custom models but warn user only once per model per session\n const warningKey = `${name}:${resolved}`;\n if (!warnedCustomModels.has(warningKey)) {\n const list = provider.supportedModels.map((m) => ` ${m.id} — ${m.label}`).join(\"\\n\");\n const aliases = Object.entries(provider.shortAliases)\n .map(([alias, full]) => ` ${alias} → ${full}`)\n .join(\"\\n\");\n console.log(chalk.yellow(\"Warning:\"), `\"${id}\" not in ${name} supported models list. Using custom model.`);\n console.log(chalk.gray(\"Supported models for\"), chalk.cyan(name) + chalk.gray(\":\"));\n console.log(list);\n if (aliases) {\n console.log(chalk.gray(\"\\nShort aliases:\"));\n console.log(aliases);\n }\n console.log(\"\");\n warnedCustomModels.add(warningKey);\n }\n }\n return resolved;\n}\n\nexport function getConfigModel(): string | null {\n const config = loadConfig();\n return config.model ?? null;\n}\n\n/**\n * Resolve provider: CLI flag → config → \"claude\"\n */\nexport function resolveProvider(agentProvider?: string): string {\n if (agentProvider) return agentProvider;\n if (providerOverride) return providerOverride;\n const config = loadConfig();\n return config.provider ?? \"claude\";\n}\n\n/**\n * Get model from override or config. Returns null if neither set.\n */\nexport function getModel(providerName?: string): string | null {\n if (modelOverride) return modelOverride;\n const configModel = getConfigModel();\n if (configModel) {\n return validateModel(configModel, providerName);\n }\n return null;\n}\n\n/**\n * Resolve model: override → config → provider default.\n */\nexport async function resolveModel(providerName?: string): Promise<string> {\n const name = providerName ?? resolveProvider();\n const model = getModel(name);\n if (model) return model;\n\n // Use provider default when no explicit model configured\n return getProvider(name).defaultModel;\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport chalk from \"chalk\";\nimport { z } from \"zod\";\nimport type { AgentConfig } from \"./agents.js\";\nimport { builtinAgents } from \"./agents.js\";\nimport { discoverSkills, skillToAgentConfig } from \"./skills.js\";\nimport type { TelemetryUserConfig } from \"./chesstrace/config.js\";\nimport { TelemetryUserConfigSchema, DEFAULT_TELEMETRY_CONFIG } from \"./chesstrace/config.js\";\n\nexport interface SkillsConfig {\n path?: string;\n disabled?: string[];\n}\n\nexport interface ReygentConfig {\n agents?: AgentConfig[];\n skills?: SkillsConfig;\n model?: string;\n provider?: string;\n telemetry?: TelemetryUserConfig;\n}\n\nconst KNOWN_ROLES = [\"developer\", \"general\", \"quality-engineer\", \"security-reviewer\", \"reviewer\", \"planner\"] as const;\n\nconst AgentConfigSchema = z.object({\n name: z.string(),\n description: z.string(),\n systemPrompt: z.string(),\n tools: z.array(z.string()),\n role: z.string().refine(\n (role) => {\n if (!KNOWN_ROLES.includes(role as typeof KNOWN_ROLES[number])) {\n console.log(chalk.yellow(`Warning: unknown agent role \"${role}\"`));\n }\n return true; // Allow all roles, just warn\n },\n { message: \"Role validation warning\" }\n ),\n provider: z.string().optional(),\n model: z.string().optional(),\n});\n\nconst ReygentConfigSchema = z.object({\n provider: z.string().optional(),\n model: z.string().optional(),\n agents: z.array(AgentConfigSchema).optional(),\n skills: z.object({\n path: z.string().optional(),\n disabled: z.array(z.string()).optional(),\n }).optional(),\n telemetry: TelemetryUserConfigSchema.optional(),\n});\n\n/**\n * Resolve config: local .reygent/config.json → global ~/.reygent/config.json → built-in agents.\n */\nexport function loadConfig(): ReygentConfig {\n const localConfigPath = findLocalConfig(process.cwd());\n\n if (localConfigPath) {\n try {\n const raw = readFileSync(localConfigPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n const config = ReygentConfigSchema.parse(parsed);\n return {\n agents: config.agents ?? builtinAgents,\n skills: config.skills ?? {},\n model: config.model,\n provider: config.provider,\n // Apply default telemetry config when local config lacks telemetry field.\n // This preserves partial configs — existing local config.json without telemetry field gets defaults.\n telemetry: config.telemetry ?? DEFAULT_TELEMETRY_CONFIG,\n };\n } catch (err) {\n throw new Error(\n `Failed to parse local config at ${localConfigPath}: ${(err as Error).message}`,\n );\n }\n }\n\n // Try global config\n const globalConfigPath = findGlobalConfig();\n if (globalConfigPath) {\n try {\n const raw = readFileSync(globalConfigPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n const config = ReygentConfigSchema.parse(parsed);\n return {\n agents: config.agents ?? builtinAgents,\n skills: config.skills ?? {},\n model: config.model,\n provider: config.provider,\n // Apply default telemetry config when global config lacks telemetry field.\n // This preserves partial configs — existing global config.json without telemetry field gets defaults.\n telemetry: config.telemetry ?? DEFAULT_TELEMETRY_CONFIG,\n };\n } catch (err) {\n if (err instanceof z.ZodError) {\n const issues = err.issues.map((issue) => {\n const path = issue.path.join(\".\");\n return ` ${path}: ${issue.message}`;\n }).join(\"\\n\");\n throw new Error(\n `Invalid global config at ${globalConfigPath}:\\n${issues}`,\n );\n }\n throw new Error(\n `Failed to parse global config at ${globalConfigPath}: ${(err as Error).message}`,\n );\n }\n }\n\n // No config at all — use builtins\n return {\n agents: builtinAgents,\n skills: {},\n telemetry: DEFAULT_TELEMETRY_CONFIG,\n };\n}\n\n/**\n * Search upward from startDir to find .reygent/config.json\n */\nfunction findLocalConfig(startDir: string): string | null {\n const configDir = findLocalConfigDir(startDir);\n if (!configDir) return null;\n const configPath = join(configDir, \"config.json\");\n return existsSync(configPath) ? configPath : null;\n}\n\n/**\n * Return path to ~/.reygent/config.json if it exists, null otherwise.\n */\nexport function findGlobalConfig(): string | null {\n const configPath = resolveGlobalConfigPath();\n return existsSync(configPath) ? configPath : null;\n}\n\n/**\n * Return the canonical path to ~/.reygent/config.json (whether it exists or not).\n */\nexport function resolveGlobalConfigPath(): string {\n return join(resolveGlobalConfigDir(), \"config.json\");\n}\n\n/**\n * Search upward from startDir to find .reygent/ directory.\n */\nexport function findLocalConfigDir(startDir: string): string | null {\n let currentDir = startDir;\n const root = \"/\";\n\n while (currentDir !== root) {\n const reygentDir = join(currentDir, \".reygent\");\n if (existsSync(reygentDir)) {\n return reygentDir;\n }\n\n const parentDir = join(currentDir, \"..\");\n if (parentDir === currentDir) break;\n currentDir = parentDir;\n }\n\n return null;\n}\n\n/**\n * Resolve the global ~/.reygent directory path.\n */\nexport function resolveGlobalConfigDir(): string {\n return join(homedir(), \".reygent\");\n}\n\n/**\n * Resolve skills directory for given scope.\n * Global always returns a path (~/.reygent/skills/).\n * Local returns null if no .reygent/ dir found.\n */\nexport function resolveSkillsDir(scope: \"local\" | \"global\"): string | null {\n if (scope === \"global\") {\n return join(resolveGlobalConfigDir(), \"skills\");\n }\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) return null;\n const config = loadConfig();\n return resolveSkillsPath(config, configDir);\n}\n\n/**\n * Resolve skills directory path from config.\n */\nexport function resolveSkillsPath(config: ReygentConfig, configDir: string): string {\n const skillsRelPath = config.skills?.path ?? \"skills\";\n return join(configDir, skillsRelPath);\n}\n\n/**\n * Discover skills and convert to AgentConfig[].\n * Scans local skills first, then global ~/.reygent/skills/.\n * Local takes precedence over global on name conflict.\n */\nexport function getSkillsAsAgents(): AgentConfig[] {\n const config = loadConfig();\n const disabled = config.skills?.disabled ?? [];\n const seenNames = new Set<string>();\n const agents: AgentConfig[] = [];\n\n // Local skills\n const localConfigDir = findLocalConfigDir(process.cwd());\n if (localConfigDir) {\n const localSkillsPath = resolveSkillsPath(config, localConfigDir);\n const localManifests = discoverSkills(localSkillsPath);\n for (const m of localManifests) {\n if (disabled.includes(m.name)) continue;\n seenNames.add(m.name);\n agents.push(skillToAgentConfig(m));\n }\n }\n\n // Global skills\n const globalSkillsPath = join(resolveGlobalConfigDir(), \"skills\");\n const globalManifests = discoverSkills(globalSkillsPath);\n for (const m of globalManifests) {\n if (disabled.includes(m.name)) continue;\n if (seenNames.has(m.name)) continue; // local takes precedence\n agents.push(skillToAgentConfig(m));\n }\n\n return agents;\n}\n\n/**\n * Get resolved agents (local or builtin), merged with skills.\n */\nexport function getAgents(): AgentConfig[] {\n const config = loadConfig();\n const configAgents = config.agents ?? [];\n const skillAgents = getSkillsAsAgents();\n\n const configNames = new Set(configAgents.map((a) => a.name));\n const merged = [...configAgents];\n\n for (const skill of skillAgents) {\n if (configNames.has(skill.name)) {\n console.log(\n chalk.yellow(`Warning: skill \"${skill.name}\" shadowed by config agent with same name`),\n );\n continue;\n }\n merged.push(skill);\n }\n\n return merged;\n}\n","export interface AgentConfig {\n name: string;\n description: string;\n systemPrompt: string;\n tools: string[];\n role: string;\n provider?: string;\n model?: string;\n}\n\nexport const builtinAgents: AgentConfig[] = [\n {\n name: \"dev\",\n description: \"Write, edit, and refactor implementation code\",\n systemPrompt:\n \"You are the Dev agent. Your role is to write, edit, and refactor implementation code based on the spec and planner output provided. Write clean, well-structured code that follows the project's existing conventions. Include unit tests alongside your implementation. Do not modify functional test files — those belong to the QE agent.\",\n tools: [\"read\", \"write\", \"bash\", \"search\"],\n role: \"developer\",\n },\n {\n name: \"qe\",\n description:\n \"Write functional tests only — never touches implementation files\",\n systemPrompt:\n \"You are the QE agent. Your role is to write functional and integration tests based on the spec and planner output provided. You must NEVER modify implementation source files — only create and edit test files. Ensure tests cover acceptance criteria, edge cases, and error paths defined in the spec.\",\n tools: [\"read\", \"write\", \"bash\"],\n role: \"quality-engineer\",\n },\n {\n name: \"security-reviewer\",\n description: \"Security and vulnerability review\",\n systemPrompt:\n \"You are the Security Reviewer agent. Your role is to review the codebase for security vulnerabilities, injection risks, insecure defaults, and other OWASP Top 10 issues. You operate in read-only mode — do not modify any files. Produce a structured findings report with severity levels (CRITICAL, HIGH, MEDIUM, LOW) for each issue found.\",\n tools: [\"read\", \"bash\"],\n role: \"security-reviewer\",\n },\n {\n name: \"adhoc\",\n description: \"Freeform one-off commands\",\n systemPrompt:\n \"You are the Adhoc agent. You execute freeform, one-off instructions provided by the user. Follow the instructions precisely and use all available tools as needed to complete the task.\",\n tools: [\"read\", \"write\", \"bash\", \"search\"],\n role: \"general\",\n },\n {\n name: \"planner\",\n description: \"Validate and normalise specs, produce structured breakdowns\",\n systemPrompt:\n \"You are the Planner agent. Your role is to validate and normalise the incoming spec into a structured breakdown of goals, tasks, constraints, and definition of done. If the spec is ambiguous or missing acceptance criteria, flag the issues clearly. Do not write or modify any code — your output is a structured plan for downstream agents.\",\n tools: [\"read\"],\n role: \"planner\",\n },\n {\n name: \"pr-reviewer\",\n description: \"PR creation, pushing, and code review\",\n systemPrompt:\n \"You are the PR Reviewer agent. Your role is to create git branches, commit changes, open pull requests via gh, and review diffs. When reviewing, produce structured findings including a summary, inline comments grouped by file, and a recommendation (approve, request changes, or comment).\",\n tools: [\"read\", \"git\", \"gh\"],\n role: \"reviewer\",\n },\n];\n","import { readFileSync, readdirSync, statSync, existsSync } from \"node:fs\";\nimport { join, basename, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { AgentConfig } from \"./agents.js\";\n\nexport interface SkillManifest {\n name: string;\n description: string;\n license?: string;\n compatibility?: string;\n metadata?: Record<string, string>;\n allowedTools?: string[];\n body: string;\n skillPath: string;\n}\n\nconst SKILL_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;\nconst MAX_SKILL_NAME_LENGTH = 64;\n\n/**\n * Validate skill name: lowercase, hyphens, 1-64 chars,\n * no consecutive/leading/trailing hyphens.\n */\nexport function validateSkillName(name: string): boolean {\n if (!name || name.length > MAX_SKILL_NAME_LENGTH) return false;\n if (name.includes(\"--\")) return false;\n return SKILL_NAME_RE.test(name);\n}\n\n/**\n * Parse SKILL.md content into a SkillManifest.\n * Expects YAML frontmatter delimited by --- lines.\n */\nexport function parseSkillMd(content: string, skillPath: string): SkillManifest {\n const trimmed = content.trim();\n if (!trimmed.startsWith(\"---\")) {\n throw new Error(\"SKILL.md must start with YAML frontmatter (---)\");\n }\n\n const endIndex = trimmed.indexOf(\"---\", 3);\n if (endIndex === -1) {\n throw new Error(\"SKILL.md frontmatter missing closing ---\");\n }\n\n const yamlStr = trimmed.slice(3, endIndex).trim();\n const body = trimmed.slice(endIndex + 3).trim();\n\n let frontmatter: Record<string, unknown>;\n try {\n frontmatter = parseYaml(yamlStr);\n } catch (err) {\n throw new Error(`Invalid YAML in SKILL.md frontmatter: ${(err as Error).message}`);\n }\n\n if (!frontmatter || typeof frontmatter !== \"object\") {\n throw new Error(\"SKILL.md frontmatter must be a YAML object\");\n }\n\n const name = frontmatter.name;\n const description = frontmatter.description;\n\n if (typeof name !== \"string\" || !name) {\n throw new Error(\"SKILL.md frontmatter requires 'name' (string)\");\n }\n if (typeof description !== \"string\" || !description) {\n throw new Error(\"SKILL.md frontmatter requires 'description' (string)\");\n }\n\n if (!validateSkillName(name)) {\n throw new Error(\n `Invalid skill name \"${name}\": must be 1-64 lowercase chars, hyphens allowed (no consecutive/leading/trailing)`,\n );\n }\n\n // allowed-tools: spec uses space-separated string, but we also accept arrays\n const rawTools = frontmatter[\"allowed-tools\"];\n let allowedTools: string[] | undefined;\n if (rawTools !== undefined) {\n if (typeof rawTools === \"string\") {\n allowedTools = rawTools.split(/\\s+/).filter(Boolean);\n } else if (Array.isArray(rawTools)) {\n allowedTools = rawTools\n .map((tool, index) => {\n if (typeof tool !== \"string\") {\n const type = tool === null ? \"null\" : Array.isArray(tool) ? \"array\" : typeof tool;\n throw new Error(\n `SKILL.md 'allowed-tools' array entries must be strings; found ${type} at index ${index}`,\n );\n }\n return tool.trim();\n })\n .filter(Boolean);\n } else {\n throw new Error(\"SKILL.md 'allowed-tools' must be a space-separated string or array\");\n }\n }\n\n const metadata = frontmatter.metadata;\n if (metadata !== undefined && (typeof metadata !== \"object\" || metadata === null)) {\n throw new Error(\"SKILL.md 'metadata' must be an object\");\n }\n\n return {\n name,\n description,\n license: typeof frontmatter.license === \"string\" ? frontmatter.license : undefined,\n compatibility: typeof frontmatter.compatibility === \"string\" ? frontmatter.compatibility : undefined,\n metadata: metadata as Record<string, string> | undefined,\n allowedTools: allowedTools as string[] | undefined,\n body,\n skillPath,\n };\n}\n\n/**\n * Strip tool qualifiers: \"Bash(git:*)\" → \"bash\", lowercase, dedup.\n */\nexport function mapToolNames(allowedTools: string[]): string[] {\n const mapped = allowedTools.map((tool) => {\n const parenIndex = tool.indexOf(\"(\");\n const base = parenIndex !== -1 ? tool.slice(0, parenIndex) : tool;\n return base.toLowerCase().trim();\n });\n return [...new Set(mapped)];\n}\n\n/**\n * Load a single skill from a directory containing SKILL.md.\n */\nexport function loadSkillFromDirectory(dirPath: string): SkillManifest {\n const absPath = resolve(dirPath);\n const skillMdPath = join(absPath, \"SKILL.md\");\n\n if (!existsSync(skillMdPath)) {\n throw new Error(`No SKILL.md found in ${absPath}`);\n }\n\n const content = readFileSync(skillMdPath, \"utf-8\");\n const manifest = parseSkillMd(content, absPath);\n\n const dirName = basename(absPath);\n if (manifest.name !== dirName) {\n throw new Error(\n `Skill name \"${manifest.name}\" does not match directory name \"${dirName}\"`,\n );\n }\n\n return manifest;\n}\n\n/**\n * Scan a directory for subdirectories containing SKILL.md.\n * Returns all valid manifests, logs warnings for invalid ones.\n */\nexport function discoverSkills(skillsPath: string): SkillManifest[] {\n const absPath = resolve(skillsPath);\n\n if (!existsSync(absPath)) {\n return [];\n }\n\n const entries = readdirSync(absPath);\n const manifests: SkillManifest[] = [];\n\n for (const entry of entries) {\n const entryPath = join(absPath, entry);\n\n try {\n const stat = statSync(entryPath);\n if (!stat.isDirectory()) continue;\n } catch {\n continue;\n }\n\n const skillMdPath = join(entryPath, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const manifest = loadSkillFromDirectory(entryPath);\n manifests.push(manifest);\n } catch {\n // Skip invalid skills silently — config.ts handles warnings\n }\n }\n\n return manifests;\n}\n\n/**\n * Convert a SkillManifest to an AgentConfig.\n */\nexport function skillToAgentConfig(skill: SkillManifest): AgentConfig {\n const tools = skill.allowedTools ? mapToolNames(skill.allowedTools) : [\"read\"];\n const role = skill.metadata?.role ?? \"skill\";\n\n return {\n name: skill.name,\n description: skill.description,\n systemPrompt: skill.body,\n tools,\n role,\n };\n}\n","import { z } from 'zod';\n\n/**\n * Telemetry level enumeration\n * - minimal: Only critical events (errors, warnings). Use in CI environments or production deployments where bandwidth/storage is limited.\n * - standard: Normal usage events including commands, success/failure outcomes. Use for interactive development and typical debugging workflows.\n * - verbose: Detailed diagnostic events including timing, internal state transitions, API calls. Use when troubleshooting specific issues or developing Reygent itself.\n */\nexport type TelemetryConfigLevel = 'minimal' | 'standard' | 'verbose';\n\n/**\n * Storage backend type\n */\nexport type TelemetryBackend = 'sqlite';\n\n/**\n * Telemetry user configuration (stored in .reygent/config.json)\n */\nexport interface TelemetryUserConfig {\n /**\n * Enable/disable telemetry (undefined = unset, prompts on first run)\n */\n enabled?: boolean;\n\n /**\n * Telemetry capture level\n */\n level: TelemetryConfigLevel;\n\n /**\n * Storage backend\n */\n backend: TelemetryBackend;\n\n /**\n * Retention period in days\n */\n retention: number;\n}\n\n/**\n * Zod schema for telemetry user configuration\n */\nexport const TelemetryUserConfigSchema = z.object({\n enabled: z.boolean().optional(),\n level: z.enum(['minimal', 'standard', 'verbose']),\n backend: z.enum(['sqlite']),\n retention: z.number().int().positive(),\n});\n\n/**\n * Default telemetry configuration\n */\nexport const DEFAULT_TELEMETRY_CONFIG: TelemetryUserConfig = {\n enabled: undefined,\n level: 'standard',\n backend: 'sqlite',\n retention: 30,\n};\n","import type { SpecPayload } from \"./spec.js\";\n\nexport type AgentName =\n | \"dev\"\n | \"qe\"\n | \"security-reviewer\"\n | \"planner\"\n | \"pr-reviewer\"\n | \"adhoc\";\n\nexport type StageKind =\n | { kind: \"agent\"; agent: AgentName }\n | { kind: \"parallel\"; agents: AgentName[] }\n | { kind: \"gate\"; agent: AgentName; condition: string };\n\nexport interface TaskStage {\n name: string;\n description: string;\n execution: StageKind;\n}\n\nexport interface StageResult {\n stage: string;\n success: boolean;\n output: string;\n}\n\nexport interface PlannerOutput {\n goals: string[];\n tasks: string[];\n constraints: string[];\n dod: string[];\n}\n\nexport interface PlannerClarification {\n needsClarification: true;\n questions: string[];\n}\n\nexport type PlannerResult = PlannerOutput | PlannerClarification;\n\nexport interface DevOutput {\n files: string[];\n}\n\nexport interface QEOutput {\n testFiles: string[];\n}\n\nexport interface ImplementOutput {\n dev: DevOutput | null;\n qe: QEOutput | null;\n}\n\nexport interface GateResult {\n passed: boolean;\n output: string;\n}\n\nexport interface GateOutput {\n unitTests?: GateResult;\n functionalTests?: GateResult;\n}\n\nexport type Severity = \"CRITICAL\" | \"HIGH\" | \"MEDIUM\" | \"LOW\";\n\nexport interface SecurityFinding {\n severity: Severity;\n description: string;\n location?: { file: string; line?: number };\n}\n\nexport interface SecurityReviewOutput {\n severity: Severity;\n findings: SecurityFinding[];\n}\n\nexport interface PRCreateOutput {\n branch: string;\n commitMessage: string;\n prUrl: string;\n prNumber: number;\n}\n\nexport interface PRReviewComment {\n file: string;\n line: number | null;\n comment: string;\n}\n\nexport interface PRReviewOutput {\n summary: string;\n comments: PRReviewComment[];\n recommendedActions: string[];\n}\n\nexport interface TaskContext {\n spec: SpecPayload;\n plan?: PlannerOutput;\n implement?: ImplementOutput;\n gates?: GateOutput;\n securityReview?: SecurityReviewOutput;\n prCreate?: PRCreateOutput;\n prReview?: PRReviewOutput;\n results: StageResult[];\n}\n\nexport class TaskError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"TaskError\";\n }\n}\n\nexport const PIPELINE: readonly TaskStage[] = [\n {\n name: \"plan\",\n description: \"Generate structured plan from spec\",\n execution: { kind: \"agent\", agent: \"planner\" },\n },\n {\n name: \"implement\",\n description: \"Implement code and write functional tests in parallel\",\n execution: { kind: \"parallel\", agents: [\"dev\", \"qe\"] },\n },\n {\n name: \"gate-unit-tests\",\n description: \"Verify unit tests pass\",\n execution: { kind: \"gate\", agent: \"dev\", condition: \"unit-tests-pass\" },\n },\n {\n name: \"gate-functional-tests\",\n description: \"Verify functional tests pass\",\n execution: {\n kind: \"gate\",\n agent: \"qe\",\n condition: \"functional-tests-pass\",\n },\n },\n {\n name: \"security-review\",\n description: \"Security and vulnerability review\",\n execution: { kind: \"agent\", agent: \"security-reviewer\" },\n },\n {\n name: \"pr-create\",\n description: \"Create pull request\",\n execution: { kind: \"agent\", agent: \"pr-reviewer\" },\n },\n {\n name: \"pr-review\",\n description: \"Review pull request\",\n execution: { kind: \"agent\", agent: \"pr-reviewer\" },\n },\n] as const;\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport { constants } from \"node:os\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { UsageInfo } from \"../usage.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\ninterface StreamAssistantMessage {\n type: \"assistant\";\n message: {\n content: Array<\n | { type: \"tool_use\"; name: string; input: Record<string, unknown> }\n | { type: \"text\"; text: string }\n >;\n };\n}\n\nexport interface StreamResultMessage {\n type: \"result\";\n subtype: string;\n result: string;\n is_error?: boolean;\n api_error_status?: number;\n total_cost_usd?: number;\n duration_ms?: number;\n num_turns?: number;\n input_tokens?: number;\n output_tokens?: number;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\ntype StreamEvent = StreamAssistantMessage | StreamResultMessage | { type: string };\n\nfunction formatToolDetail(name: string, input: Record<string, unknown>): string {\n switch (name) {\n case \"Read\":\n case \"Write\":\n case \"Edit\":\n return typeof input.file_path === \"string\" ? input.file_path : \"\";\n case \"Bash\": {\n const cmd = typeof input.command === \"string\" ? input.command : \"\";\n return cmd.length > 80 ? cmd.slice(0, 80) + \"…\" : cmd;\n }\n case \"Glob\":\n return typeof input.pattern === \"string\" ? input.pattern : \"\";\n case \"Grep\":\n return typeof input.pattern === \"string\" ? `/${input.pattern}/` : \"\";\n default:\n return \"\";\n }\n}\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"claude-sonnet-4-5-20250929\", label: \"Sonnet 4.5 (recommended)\" },\n { id: \"claude-opus-4-6\", label: \"Opus 4.6\" },\n { id: \"claude-haiku-4-5-20251001\", label: \"Haiku 4.5\" },\n { id: \"claude-sonnet-4-20250514\", label: \"Sonnet 4\" },\n { id: \"claude-3-5-sonnet-20241022\", label: \"3.5 Sonnet\" },\n { id: \"claude-3-5-haiku-20241022\", label: \"3.5 Haiku\" },\n { id: \"claude-3-opus-20240229\", label: \"3 Opus\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {\n \"claude-sonnet-4-5\": \"claude-sonnet-4-5-20250929\",\n \"claude-haiku-4-5\": \"claude-haiku-4-5-20251001\",\n \"claude-sonnet-4\": \"claude-sonnet-4-20250514\",\n \"claude-3-5-sonnet\": \"claude-3-5-sonnet-20241022\",\n \"claude-3.5-sonnet\": \"claude-3-5-sonnet-20241022\",\n \"claude-3-5-haiku\": \"claude-3-5-haiku-20241022\",\n \"claude-3.5-haiku\": \"claude-3-5-haiku-20241022\",\n \"claude-3-opus\": \"claude-3-opus-20240229\",\n};\n\nconst DEFAULT_MODEL = \"claude-sonnet-4-5-20250929\";\n\n// Track Vertex AI detection to log only once per session\nlet vertexAiLoggedForClaude = false;\n\n/** Extract token counts from a Claude CLI stream result message. */\nexport function extractTokenUsage(msg: StreamResultMessage): {\n inputTokens: number | undefined;\n outputTokens: number | undefined;\n cachedTokens: number | undefined;\n cacheWriteTokens: number | undefined;\n} {\n const usageData = msg.usage;\n const hasInput = usageData?.input_tokens !== undefined ||\n usageData?.cache_creation_input_tokens !== undefined ||\n usageData?.cache_read_input_tokens !== undefined ||\n msg.input_tokens !== undefined;\n const baseInput = usageData?.input_tokens ?? msg.input_tokens ?? 0;\n const cacheCreation = usageData?.cache_creation_input_tokens ?? 0;\n const cacheRead = usageData?.cache_read_input_tokens ?? 0;\n const inputTokens = hasInput ? baseInput + cacheCreation + cacheRead : undefined;\n // outputTokens: no cache fields apply to output, so undefined means \"no data\"\n const outputTokens = usageData?.output_tokens ?? msg.output_tokens;\n\n const cachedTokens = usageData?.cache_read_input_tokens !== undefined\n ? usageData.cache_read_input_tokens\n : undefined;\n const cacheWriteTokens = usageData?.cache_creation_input_tokens !== undefined\n ? usageData.cache_creation_input_tokens\n : undefined;\n\n return { inputTokens, outputTokens, cachedTokens, cacheWriteTokens };\n}\n\n// Safe argv limit for interactive --append-system-prompt\nconst MAX_PROMPT_BYTES = 200_000;\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const claudeAdapter: ProviderAdapter = {\n name: \"claude\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"claude\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"claude CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"claude CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const args = [\n \"-p\", options.prompt,\n \"--output-format\", \"stream-json\",\n \"--verbose\",\n \"--model\", options.model,\n ];\n if (options.autoApprove) {\n args.push(\"--allowedTools\", \"Bash\", \"Edit\", \"Write\", \"Read\", \"Glob\", \"Grep\");\n }\n\n const name = options.agentName;\n\n // Detect Vertex AI configuration for Claude via Model Garden\n const vertexProject = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;\n const vertexRegion = process.env.GOOGLE_CLOUD_REGION;\n const hasVertexConfig = !!vertexProject;\n\n // Log Vertex AI detection only once per session to avoid spam\n if (hasVertexConfig && !options.quiet && !vertexAiLoggedForClaude) {\n const region = vertexRegion ?? \"(using CLI default)\";\n process.stderr.write(\n chalk.gray(`[${name}] Vertex AI detected: project=${vertexProject}, region=${region}\\n`)\n );\n vertexAiLoggedForClaude = true;\n }\n\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n const child = spawn(\"claude\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let resultText = \"\";\n let resultErrorMessage: string | undefined;\n let resultApiErrorStatus: number | undefined;\n let resultUsage: UsageInfo | undefined;\n const textChunks: string[] = [];\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n let stdoutEnded = false;\n let stderrEnded = false;\n let processExitCode: number | null = null;\n\n const maybeResolve = () => {\n if (stdoutEnded && stderrEnded && processExitCode !== null) {\n clearTimeout(timeout);\n const stdout = resultText || textChunks.join(\"\\n\");\n resolve({\n stdout,\n exitCode: processExitCode,\n usage: resultUsage,\n errorMessage: resultErrorMessage,\n apiErrorStatus: resultApiErrorStatus,\n });\n }\n };\n\n const stdoutRL = createInterface({ input: child.stdout! });\n stdoutRL.on(\"line\", (line) => {\n if (!line.trim()) return;\n\n let event: StreamEvent;\n try {\n event = JSON.parse(line) as StreamEvent;\n } catch {\n console.log(chalk.gray(`[${name}]`), line);\n return;\n }\n\n if (event.type === \"assistant\") {\n const msg = event as StreamAssistantMessage;\n for (const block of msg.message.content) {\n if (block.type === \"tool_use\") {\n const detail = formatToolDetail(block.name, block.input);\n if (options.onActivity) {\n options.onActivity({ agent: name, tool: block.name, detail: detail || undefined });\n } else {\n const suffix = detail ? ` ${chalk.gray(detail)}` : \"\";\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${chalk.cyan(\"→\")} ${chalk.blue(block.name)}${suffix}\\n`);\n }\n } else if (block.type === \"text\") {\n if (!options.quiet && !options.onActivity) {\n console.log(chalk.gray(`[${name}]`), block.text);\n }\n textChunks.push(block.text);\n }\n }\n } else if (event.type === \"result\") {\n const msg = event as StreamResultMessage;\n resultText = msg.result;\n if (msg.is_error) {\n resultErrorMessage = msg.result;\n resultApiErrorStatus = msg.api_error_status;\n }\n\n const { inputTokens, outputTokens, cachedTokens, cacheWriteTokens } = extractTokenUsage(msg);\n const hasUsage =\n msg.total_cost_usd !== undefined ||\n msg.duration_ms !== undefined ||\n msg.num_turns !== undefined ||\n inputTokens !== undefined ||\n outputTokens !== undefined;\n\n if (hasUsage) {\n resultUsage = {\n ...(msg.total_cost_usd !== undefined ? { costUsd: msg.total_cost_usd } : {}),\n ...(msg.duration_ms !== undefined ? { durationMs: msg.duration_ms } : {}),\n ...(msg.num_turns !== undefined ? { numTurns: msg.num_turns } : {}),\n ...(inputTokens !== undefined ? { inputTokens } : {}),\n ...(outputTokens !== undefined ? { outputTokens } : {}),\n ...(cachedTokens !== undefined ? { cachedTokens } : {}),\n ...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),\n provider: \"claude\",\n };\n }\n }\n });\n stdoutRL.on(\"close\", () => {\n stdoutEnded = true;\n maybeResolve();\n });\n\n const stderrRL = createInterface({ input: child.stderr! });\n stderrRL.on(\"line\", (line) => {\n if (options.onActivity) {\n options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${line}\\n`);\n }\n });\n stderrRL.on(\"close\", () => {\n stderrEnded = true;\n maybeResolve();\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n processExitCode = code ?? 1;\n maybeResolve();\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n const promptBytes = Buffer.byteLength(systemPrompt);\n\n if (promptBytes > MAX_PROMPT_BYTES) {\n throw new TaskError(\n `System prompt too large (${promptBytes} bytes, limit ${MAX_PROMPT_BYTES}). ` +\n `Try a smaller spec or split into sections.`,\n );\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(\n \"claude\",\n [\"--append-system-prompt\", systemPrompt, \"--model\", model],\n {\n stdio: \"inherit\",\n detached: false, // Keep in same process group so we can kill descendants\n },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start ${this.name} CLI: ${err.message}. Is ${this.name} installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code, signal) => {\n if (signal) {\n const sigNum = constants.signals[signal];\n resolve(sigNum ? 128 + sigNum : 1);\n } else {\n resolve(code ?? 0);\n }\n });\n });\n },\n};\n","import { spawn } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"gemini-2.5-pro\", label: \"Gemini 2.5 Pro (recommended)\" },\n { id: \"gemini-2.5-flash\", label: \"Gemini 2.5 Flash\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"gemini-2.5-pro\";\n\n// Track Vertex AI detection to log only once per session\nlet vertexAiLoggedForGemini = false;\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const geminiAdapter: ProviderAdapter = {\n name: \"gemini\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"gemini\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"gemini CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"gemini CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n const args = [\"-p\", options.prompt, \"--output-format\", \"json\"];\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n\n const name = options.agentName;\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n\n // Detect Vertex AI configuration\n const vertexProject = process.env.GOOGLE_CLOUD_PROJECT || process.env.GCLOUD_PROJECT;\n const vertexRegion = process.env.GOOGLE_CLOUD_REGION;\n const hasVertexConfig = !!vertexProject;\n\n // Log Vertex AI detection only once per session to avoid spam\n if (hasVertexConfig && !options.quiet && !vertexAiLoggedForGemini) {\n const region = vertexRegion ?? \"(using CLI default)\";\n process.stderr.write(\n chalk.gray(`[${name}] Vertex AI detected: project=${vertexProject}, region=${region}\\n`)\n );\n vertexAiLoggedForGemini = true;\n }\n\n // Gemini CLI requires workspace trust for non-interactive spawns;\n // without this it exits 55 when stdin is not a TTY.\n const child = spawn(\"gemini\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n env: { ...process.env, GEMINI_CLI_TRUST_WORKSPACE: \"true\" },\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let stdout = \"\";\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n child.stdout!.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n\n const stderrChunks: string[] = [];\n child.stderr!.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrChunks.push(text);\n if (options.onActivity) {\n const line = text.trim();\n if (line) options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${text}`);\n }\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn gemini — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n const durationMs = Math.max(0, Date.now() - startTime);\n\n // Try to parse Gemini JSON output\n let resultText = stdout;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cachedTokens: number | undefined;\n let errorMessage: string | undefined;\n let apiErrorStatus: number | undefined;\n\n try {\n const parsed = JSON.parse(stdout) as {\n response?: string;\n text?: string;\n error?: { message?: string; code?: number; status?: number };\n usage_metadata?: {\n prompt_token_count?: number;\n candidates_token_count?: number;\n cached_content_token_count?: number;\n };\n input_tokens?: number;\n output_tokens?: number;\n };\n resultText = parsed.response ?? parsed.text ?? stdout;\n inputTokens = parsed.usage_metadata?.prompt_token_count ?? parsed.input_tokens;\n outputTokens = parsed.usage_metadata?.candidates_token_count ?? parsed.output_tokens;\n cachedTokens = parsed.usage_metadata?.cached_content_token_count;\n\n // Extract error details if present\n if (parsed.error) {\n errorMessage = parsed.error.message;\n // Gemini error codes can be numeric (HTTP status) or string codes\n // Map known codes to HTTP status for consistent handling\n let statusCode = parsed.error.status;\n if (parsed.error.code) {\n if (typeof parsed.error.code === \"number\") {\n // Gemini often returns HTTP status codes directly\n statusCode = parsed.error.code;\n } else if (typeof parsed.error.code === \"string\") {\n // String error codes - map to HTTP status\n const code = parsed.error.code.toLowerCase();\n if (code === \"not_found\" || code === \"model_not_found\") {\n statusCode = 404;\n } else if (code === \"permission_denied\" || code === \"unauthenticated\") {\n statusCode = 403;\n } else if (code === \"invalid_api_key\" || code === \"invalid_authentication\") {\n statusCode = 401;\n } else if (code === \"resource_exhausted\" || code === \"rate_limit_exceeded\") {\n statusCode = 429;\n } else if (code === \"internal\" || code === \"server_error\") {\n statusCode = 500;\n } else if (code === \"invalid_argument\") {\n statusCode = 400;\n }\n }\n }\n apiErrorStatus = statusCode;\n }\n } catch {\n // Raw text output — use as-is\n }\n\n // If exitCode non-zero and no structured error, try stderr\n if (code !== 0 && !errorMessage && stderrChunks.length > 0) {\n const stderr = stderrChunks.join(\"\").trim();\n if (stderr) {\n errorMessage = stderr;\n }\n }\n\n resolve({\n stdout: resultText,\n exitCode: code ?? 1,\n usage: {\n durationMs,\n inputTokens,\n outputTokens,\n cachedTokens,\n provider: \"gemini\",\n },\n errorMessage,\n apiErrorStatus,\n });\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n return new Promise((resolve, reject) => {\n // Gemini CLI has no --system-prompt flag; use -i to inject instructions\n // then continue interactively\n const child = spawn(\n \"gemini\",\n [\"--model\", model, \"-i\", `Follow these instructions for this session:\\n\\n${systemPrompt}`],\n { stdio: \"inherit\", env: { ...process.env, GEMINI_CLI_TRUST_WORKSPACE: \"true\" } },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start gemini CLI: ${err.message}. Is gemini installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code) => {\n resolve(code ?? 0);\n });\n });\n },\n};\n","import { spawn } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { registerChildProcess } from \"../child-registry.js\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst SUPPORTED_MODELS: ModelEntry[] = [\n { id: \"gpt-5.4\", label: \"gpt-5.4\" },\n];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"gpt-5.4\";\n\nlet availabilityCache: { available: boolean; reason?: string } | null = null;\n\nexport const codexAdapter: ProviderAdapter = {\n name: \"codex\",\n type: \"cli\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n if (availabilityCache) return availabilityCache;\n\n const result = await new Promise<{ available: boolean; reason?: string }>((resolve) => {\n const child = spawn(\"which\", [\"codex\"], { stdio: \"pipe\" });\n child.on(\"close\", (code) => {\n if (code === 0) {\n resolve({ available: true });\n } else {\n resolve({ available: false, reason: \"codex CLI not found in PATH\" });\n }\n });\n child.on(\"error\", () => {\n resolve({ available: false, reason: \"codex CLI not found in PATH\" });\n });\n });\n\n availabilityCache = result;\n return result;\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const startTime = Date.now();\n const args = [\"exec\", options.prompt, \"--json\"];\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n if (options.autoApprove) {\n args.push(\"--full-auto\");\n }\n\n const name = options.agentName;\n const stdinMode = options.autoApprove === false ? \"inherit\" : \"ignore\";\n const child = spawn(\"codex\", args, {\n stdio: [stdinMode, \"pipe\", \"pipe\"],\n detached: false, // Keep in same process group so we can kill descendants\n });\n registerChildProcess(child);\n\n let stdout = \"\";\n\n const timeout = setTimeout(() => {\n // Kill entire process group to catch spawned descendants\n if (child.pid && process.platform !== \"win32\") {\n try {\n process.kill(-child.pid, \"SIGTERM\");\n } catch {\n child.kill();\n }\n } else {\n child.kill();\n }\n reject(new TaskError(`${name}: timed out after ${options.timeoutMs}ms`));\n }, options.timeoutMs);\n\n child.stdout!.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n\n const stderrChunks: string[] = [];\n child.stderr!.on(\"data\", (chunk: Buffer) => {\n const text = chunk.toString();\n stderrChunks.push(text);\n if (options.onActivity) {\n const line = text.trim();\n if (line) options.onActivity({ agent: name, detail: line.slice(0, 80) });\n } else {\n process.stderr.write(`${chalk.gray(`[${name}]`)} ${text}`);\n }\n });\n\n child.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new TaskError(`${name}: failed to spawn codex — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timeout);\n const durationMs = Math.max(0, Date.now() - startTime);\n\n // Try to parse Codex JSON output\n let resultText = stdout;\n let inputTokens: number | undefined;\n let outputTokens: number | undefined;\n let cachedTokens: number | undefined;\n let errorMessage: string | undefined;\n let apiErrorStatus: number | undefined;\n\n try {\n const parsed = JSON.parse(stdout) as {\n response?: string;\n text?: string;\n error?: { message?: string; code?: string; status?: number };\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n prompt_tokens_details?: { cached_tokens?: number };\n };\n input_tokens?: number;\n output_tokens?: number;\n cached_tokens?: number;\n };\n resultText = parsed.response ?? parsed.text ?? stdout;\n inputTokens = parsed.usage?.prompt_tokens ?? parsed.input_tokens;\n outputTokens = parsed.usage?.completion_tokens ?? parsed.output_tokens;\n cachedTokens = parsed.usage?.prompt_tokens_details?.cached_tokens ?? parsed.cached_tokens;\n\n // Extract error details if present\n if (parsed.error) {\n errorMessage = parsed.error.message;\n // OpenAI error codes are strings like \"model_not_found\", map common ones to HTTP status\n // Try exact match first, then fallback to partial match\n if (typeof parsed.error.code === \"string\") {\n const code = parsed.error.code;\n // Exact matches for known codes\n if (code === \"model_not_found\" || code === \"invalid_model\") {\n apiErrorStatus = 404;\n } else if (code === \"invalid_api_key\" || code === \"invalid_request_error\") {\n apiErrorStatus = 401;\n } else if (code === \"rate_limit_exceeded\") {\n apiErrorStatus = 429;\n } else if (code === \"insufficient_quota\") {\n apiErrorStatus = 402;\n } else if (code === \"server_error\") {\n apiErrorStatus = 500;\n }\n // Fallback: partial match for unexpected variations\n else if (code.includes(\"not_found\")) {\n apiErrorStatus = 404;\n } else if (code.includes(\"auth\") || code.includes(\"unauthorized\")) {\n apiErrorStatus = 401;\n }\n }\n apiErrorStatus = apiErrorStatus ?? parsed.error.status;\n }\n } catch {\n // Raw text output — use as-is\n }\n\n // If exitCode non-zero and no structured error, try stderr\n if (code !== 0 && !errorMessage && stderrChunks.length > 0) {\n const stderr = stderrChunks.join(\"\").trim();\n if (stderr) {\n errorMessage = stderr;\n }\n }\n\n resolve({\n stdout: resultText,\n exitCode: code ?? 1,\n usage: {\n durationMs,\n inputTokens,\n outputTokens,\n cachedTokens,\n // Note: cacheWriteTokens not extracted — OpenAI doesn't currently expose this field\n provider: \"codex\",\n },\n errorMessage,\n apiErrorStatus,\n });\n });\n });\n },\n\n async spawnInteractive(systemPrompt: string, model: string): Promise<number> {\n return new Promise((resolve, reject) => {\n // Codex CLI has no --system-prompt flag; pass instructions as initial prompt\n const child = spawn(\n \"codex\",\n [\"--model\", model, systemPrompt],\n { stdio: \"inherit\" },\n );\n registerChildProcess(child);\n\n child.on(\"error\", (err) => {\n reject(\n new TaskError(\n `Failed to start codex CLI: ${err.message}. Is codex installed?`,\n ),\n );\n });\n\n child.on(\"close\", (code) => {\n resolve(code ?? 0);\n });\n });\n },\n};\n","import chalk from \"chalk\";\nimport { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\n// OpenRouter supports 200+ models — no whitelist needed.\n// model.ts already special-cases openrouter to skip validation.\nconst SUPPORTED_MODELS: ModelEntry[] = [];\n\nconst SHORT_ALIASES: Record<string, string> = {};\n\nconst DEFAULT_MODEL = \"anthropic/claude-sonnet-4-5\";\n\nconst OPENROUTER_API_URL = \"https://openrouter.ai/api/v1/chat/completions\";\n\nexport const openrouterAdapter: ProviderAdapter = {\n name: \"openrouter\",\n type: \"api\",\n defaultModel: DEFAULT_MODEL,\n supportedModels: SUPPORTED_MODELS,\n shortAliases: SHORT_ALIASES,\n\n async isAvailable() {\n const key = process.env.OPENROUTER_API_KEY;\n if (key && key.length > 0) {\n return { available: true };\n }\n return { available: false, reason: \"OPENROUTER_API_KEY environment variable not set\" };\n },\n\n async spawn(options: SpawnAdapterOptions): Promise<SpawnResult> {\n const apiKey = process.env.OPENROUTER_API_KEY;\n if (!apiKey) {\n throw new TaskError(\n `${options.agentName}: OPENROUTER_API_KEY environment variable not set`,\n );\n }\n\n const name = options.agentName;\n\n // Warn about file system limitations for agents with write tools\n if (!options.quiet) {\n console.error(\n chalk.yellow(`[${name}] Warning: OpenRouter is an API provider — no file system access. `) +\n chalk.yellow(`Tool calls (Bash, Write, Edit) will not work.`),\n );\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n const startTime = Date.now();\n\n options.onActivity?.({ agent: name, detail: \"API request...\" });\n\n // Heartbeat every 5s during long waits to prevent stale elapsed time\n const heartbeat = setInterval(() => {\n const elapsed = Math.floor((Date.now() - startTime) / 1000);\n options.onActivity?.({ agent: name, detail: `API request (${elapsed}s)...` });\n }, 5000);\n\n try {\n const response = await fetch(OPENROUTER_API_URL, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n \"HTTP-Referer\": \"https://github.com/andrewevans0102/reygent\",\n \"X-Title\": \"reygent\",\n },\n body: JSON.stringify({\n model: options.model,\n messages: [\n ...(options.systemPrompt\n ? [{ role: \"system\", content: options.systemPrompt }]\n : []),\n { role: \"user\", content: options.prompt },\n ],\n }),\n signal: controller.signal,\n });\n\n clearTimeout(timeout);\n clearInterval(heartbeat);\n\n if (!response.ok) {\n const body = await response.text();\n throw new TaskError(\n `${name}: OpenRouter API returned ${response.status} — ${body}`,\n );\n }\n\n const data = await response.json() as {\n choices?: Array<{ message?: { content?: string } }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_cost?: number;\n cache_discount?: number;\n prompt_tokens_details?: { cached_tokens?: number };\n };\n total_cost?: number;\n };\n\n const content = data.choices?.[0]?.message?.content ?? \"\";\n const usage = data.usage;\n const durationMs = Date.now() - startTime;\n const costUsd = usage?.total_cost ?? data.total_cost;\n\n // OpenRouter reports cache activity via cache_discount or prompt_tokens_details\n const cachedTokens = usage?.prompt_tokens_details?.cached_tokens;\n const cacheDiscount = usage?.cache_discount;\n\n return {\n stdout: content,\n exitCode: 0,\n usage: {\n durationMs,\n inputTokens: usage?.prompt_tokens,\n outputTokens: usage?.completion_tokens,\n costUsd,\n cachedTokens,\n cacheDiscount: cacheDiscount && cacheDiscount > 0 ? cacheDiscount : undefined,\n provider: \"openrouter\",\n },\n };\n } catch (err) {\n clearTimeout(timeout);\n clearInterval(heartbeat);\n if (err instanceof TaskError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n if (message.includes(\"aborted\")) {\n throw new TaskError(`${name}: timed out after ${options.timeoutMs}ms`);\n }\n throw new TaskError(`${name}: OpenRouter API request failed — ${message}`);\n }\n },\n\n async spawnInteractive(_systemPrompt: string, _model: string): Promise<number> {\n throw new TaskError(\n \"OpenRouter is an API provider and does not support interactive sessions. \" +\n \"Use a CLI provider (claude, gemini, codex) for interactive mode.\",\n );\n },\n};\n","import { TaskError } from \"../task.js\";\nimport type { ProviderAdapter, ProviderName } from \"./types.js\";\nimport { claudeAdapter } from \"./claude.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { codexAdapter } from \"./codex.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\n\nexport type { ProviderAdapter, ProviderName, SpawnAdapterOptions, SpawnResult, ModelEntry } from \"./types.js\";\n\nconst providers: Record<ProviderName, ProviderAdapter> = {\n claude: claudeAdapter,\n gemini: geminiAdapter,\n codex: codexAdapter,\n openrouter: openrouterAdapter,\n};\n\nexport const PROVIDER_NAMES = Object.keys(providers) as ProviderName[];\n\nexport function getProvider(name: string): ProviderAdapter {\n const adapter = providers[name as ProviderName];\n if (!adapter) {\n const valid = PROVIDER_NAMES.join(\", \");\n throw new TaskError(`Unknown provider: \"${name}\". Valid providers: ${valid}`);\n }\n return adapter;\n}\n","import type { TelemetryConfigLevel } from \"./chesstrace/config.js\";\nimport { DEFAULT_TELEMETRY_CONFIG } from \"./chesstrace/config.js\";\n\n/**\n * Runtime telemetry overrides from CLI flags\n */\nexport interface TelemetryOverride {\n /** --no-telemetry flag: completely disable telemetry */\n disabled?: boolean;\n /** --telemetry-level flag: override configured level */\n level?: TelemetryConfigLevel;\n}\n\n/**\n * Telemetry user configuration (subset)\n */\nexport interface TelemetryConfig {\n telemetry?: {\n enabled?: boolean;\n level?: TelemetryConfigLevel;\n };\n}\n\n/**\n * Resolved telemetry settings\n */\nexport interface ResolvedTelemetry {\n enabled: boolean;\n level: TelemetryConfigLevel;\n}\n\n/**\n * Module-level telemetry override state.\n *\n * **Design rationale:** CLI flags parsed in src/cli.ts must propagate to src/commands/run.ts.\n * Module-level state provides simplest mechanism without threading parameters through commander.js.\n *\n * **Thread safety:** Safe for CLI single-instance use. Tests must call resetTelemetryOverride()\n * between test cases to avoid state pollution.\n */\nlet telemetryOverride: TelemetryOverride = {};\n\n/**\n * Set telemetry runtime override (from CLI flags)\n */\nexport function setTelemetryOverride(override: TelemetryOverride): void {\n telemetryOverride = override;\n}\n\n/**\n * Get current telemetry runtime override\n */\nexport function getTelemetryOverride(): TelemetryOverride {\n return telemetryOverride;\n}\n\n/**\n * Reset telemetry override (for testing)\n *\n * **Important:** Call this in test teardown to prevent state leakage between tests.\n */\nexport function resetTelemetryOverride(): void {\n telemetryOverride = {};\n}\n\n/**\n * Validate telemetry level string\n */\nexport function isValidTelemetryLevel(level: string): level is TelemetryConfigLevel {\n return level === \"minimal\" || level === \"standard\" || level === \"verbose\";\n}\n\n/**\n * Resolve telemetry enabled status and level from config and overrides.\n * Applies CLI flag precedence: --no-telemetry disables, otherwise config enabled state used.\n * Level precedence: override.level > config.level > default.\n *\n * @param override - CLI flag overrides\n * @param config - User configuration\n * @returns Resolved telemetry settings\n */\nexport function resolveTelemetryEnabled(\n override: TelemetryOverride,\n config: TelemetryConfig\n): ResolvedTelemetry {\n const enabled = override.disabled === true ? false : config.telemetry?.enabled === true;\n const level = override.level ?? config.telemetry?.level ?? DEFAULT_TELEMETRY_CONFIG.level;\n\n return { enabled, level };\n}\n","import { select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { getAgents } from \"../config.js\";\nimport type { AgentConfig } from \"../agents.js\";\nimport { isDebug } from \"../debug.js\";\nimport { resolveModel, resolveProvider, validateModel } from \"../model.js\";\nimport { getProvider } from \"../providers/index.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\n\ninterface AgentOptions {\n spec?: string;\n}\n\nexport async function agentCommand(\n name: string | undefined,\n options: AgentOptions,\n): Promise<void> {\n return withTelemetry('agent', async () => {\n try {\n const agents = getAgents();\n let agent: AgentConfig;\n\n if (name) {\n const found = agents.find((a) => a.name === name);\n if (!found) {\n const validNames = agents.map((a) => a.name).join(\", \");\n console.log(chalk.red.bold(\"Error:\"), `Unknown agent \"${name}\". Valid agents: ${validNames}`);\n process.exit(1);\n }\n agent = found;\n } else {\n if (agents.length === 0) {\n throw new TaskError(\"No agents configured. Add agents to .reygent/config.json or check built-in agents.\");\n }\n if (!process.stdin.isTTY) {\n const validNames = agents.map((a) => a.name);\n // Truncate long agent lists for readability\n const displayNames = validNames.length > 5\n ? `${validNames.slice(0, 5).join(\", \")}, ... (${validNames.length - 5} more)`\n : validNames.join(\", \");\n console.log(chalk.red.bold(\"Error:\"), `Agent name required in non-interactive mode. Valid agents: ${displayNames}`);\n if (validNames.length > 5) {\n console.log(chalk.gray(\" Run 'reygent list' to see all agents.\"));\n }\n process.exit(1);\n }\n resetTerminalForInput();\n agent = await select({\n message: \"Select agent:\",\n choices: agents.map((a) => ({\n name: `${a.name} — ${a.description}`,\n value: a,\n })),\n });\n }\n\n let systemPrompt = agent.systemPrompt;\n\n if (options.spec) {\n const spec = await loadSpec(options.spec);\n systemPrompt += `\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}`;\n }\n\n const providerName = resolveProvider(agent.provider);\n const provider = getProvider(providerName);\n const modelId = agent.model\n ? validateModel(agent.model, providerName)\n : await resolveModel(providerName);\n\n console.log(\n chalk.bold.cyan(`\\nStarting session with ${agent.name} agent`) +\n chalk.gray(` (${providerName}/${modelId})`) +\n \"\\n\",\n );\n\n const exitCode = await provider.spawnInteractive(systemPrompt, modelId);\n process.exit(exitCode);\n } catch (err) {\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { basename, extname, resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport { isLinearUrl, extractLinearId, readLinearSpec } from \"./linear.js\";\nimport { readJiraSpec } from \"./jira.js\";\nimport { loadEnvFile } from \"./env.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nexport interface MarkdownSpecPayload {\n source: \"markdown\";\n content: string;\n title: string;\n}\n\nexport interface JiraSpecPayload {\n source: \"jira\";\n issueKey: string;\n content: string;\n title: string;\n issueType?: string;\n}\n\nexport interface LinearSpecPayload {\n source: \"linear\";\n issueId: string;\n content: string;\n title: string;\n issueType?: string;\n labels?: string[];\n}\n\nexport type SpecPayload = MarkdownSpecPayload | JiraSpecPayload | LinearSpecPayload;\n\nexport type SpecProvider = \"jira\" | \"linear\" | \"local\";\n\nexport class SpecError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecError\";\n }\n}\n\nexport function readSpec(filePath: string): MarkdownSpecPayload {\n const resolved = resolve(process.cwd(), filePath);\n\n if (!existsSync(resolved)) {\n throw new SpecError(`File not found: ${resolved}`);\n }\n\n const ext = extname(resolved).toLowerCase();\n if (ext !== \".md\" && ext !== \".markdown\") {\n console.log(chalk.yellow(\"Warning:\"), `${basename(resolved)} is not a .md file`);\n }\n\n const content = readFileSync(resolved, \"utf-8\");\n\n if (!content.trim()) {\n throw new SpecError(`Spec file is empty: ${resolved}`);\n }\n\n const trimmed = content.trim();\n\n if (/^[A-Z]{2,}-\\d+$/.test(trimmed)) {\n throw new SpecError(\n `Spec file contains only a ticket reference (${trimmed}). Please provide the full spec content.`,\n );\n }\n\n if (/^https:\\/\\/linear\\.app\\/.+$/.test(trimmed)) {\n throw new SpecError(\n `Spec file contains only a Linear URL. Please provide the full spec content.`,\n );\n }\n\n const headingMatch = content.match(/^# (.+)$/m);\n const title = headingMatch\n ? headingMatch[1].trim()\n : basename(resolved, extname(resolved));\n\n return { source: \"markdown\", content, title };\n}\n\nexport const ISSUE_KEY_PATTERN = /^[A-Z]+-\\d+$/;\n\nexport async function loadSpec(source: string, provider?: SpecProvider): Promise<SpecPayload> {\n const trace = getChesstrace();\n try { trace.emit(Events.SPEC_FETCH, { source, provider: provider ?? 'auto' }); } catch { /* swallow */ }\n\n try {\n let result: SpecPayload;\n\n // When provider is explicitly set, route directly\n if (provider === \"local\") {\n result = readSpec(source);\n } else if (provider === \"linear\") {\n loadEnvFile();\n if (isLinearUrl(source)) {\n const issueId = extractLinearId(source);\n result = readLinearSpec(issueId);\n } else {\n result = await readLinearSpec(source);\n }\n } else if (provider === \"jira\") {\n loadEnvFile();\n result = await readJiraSpec(source);\n } else if (isLinearUrl(source)) {\n // Legacy auto-detection when no provider specified (used by other commands)\n loadEnvFile();\n const issueId = extractLinearId(source);\n result = await readLinearSpec(issueId);\n } else if (ISSUE_KEY_PATTERN.test(source)) {\n loadEnvFile();\n const hasLinear = !!process.env.LINEAR_API_KEY;\n const hasJira = !!(process.env.JIRA_URL && process.env.JIRA_EMAIL && process.env.JIRA_API_TOKEN);\n\n if (hasLinear && !hasJira) {\n result = await readLinearSpec(source);\n } else if (hasJira) {\n result = await readJiraSpec(source);\n } else {\n throw new SpecError(\n `No issue tracker configured for \"${source}\".\\n\\n` +\n `Add one of the following to your .env file:\\n\\n` +\n ` For Linear:\\n` +\n ` LINEAR_API_KEY=lin_api_...\\n\\n` +\n ` For Jira:\\n` +\n ` JIRA_URL=https://your-domain.atlassian.net\\n` +\n ` JIRA_EMAIL=your-email@example.com\\n` +\n ` JIRA_API_TOKEN=your-jira-token`,\n );\n }\n } else {\n result = readSpec(source);\n }\n\n try { trace.emit(Events.SPEC_PARSE, { source: result.source, title: result.title }); } catch { /* swallow */ }\n return result;\n } catch (err) {\n try { trace.emit(Events.SPEC_ERROR, { source, error: err instanceof Error ? err.message : String(err) }); } catch { /* swallow */ }\n throw err;\n }\n}\n","import { LinearSpecPayload, SpecError } from \"./spec.js\";\n\nconst LINEAR_URL_PATTERN =\n /^https:\\/\\/linear\\.app\\/[^/]+\\/issue\\/([A-Z]+-\\d+)/;\n\nexport function isLinearUrl(input: string): boolean {\n return LINEAR_URL_PATTERN.test(input);\n}\n\nexport function extractLinearId(url: string): string {\n const match = url.match(LINEAR_URL_PATTERN);\n if (!match) {\n throw new SpecError(`Could not extract issue ID from Linear URL: ${url}`);\n }\n return match[1];\n}\n\ninterface LinearIssue {\n id: string;\n identifier: string;\n title: string;\n description?: string;\n labels?: {\n nodes: Array<{\n name: string;\n }>;\n };\n children?: {\n nodes: Array<{\n id: string;\n identifier: string;\n title: string;\n description?: string;\n }>;\n };\n}\n\ninterface LinearResponse {\n data?: {\n issues?: {\n nodes: LinearIssue[];\n };\n };\n errors?: Array<{ message: string }>;\n}\n\nexport async function readLinearSpec(\n issueId: string,\n): Promise<LinearSpecPayload> {\n const apiKey = process.env.LINEAR_API_KEY;\n\n if (!apiKey) {\n throw new SpecError(\n `LINEAR_API_KEY is not configured.\\n\\n` +\n `Add the following to your .env file:\\n\\n` +\n ` LINEAR_API_KEY=lin_api_xxxxxxxx\\n\\n` +\n `Get an API key at: https://linear.app/settings/api`,\n );\n }\n\n const match = issueId.match(/^([A-Z]+)-(\\d+)$/);\n if (!match) {\n throw new SpecError(\n `Invalid issue identifier format: ${issueId}. Expected format: TEAM-123`,\n );\n }\n const teamKey = match[1];\n const issueNumber = parseInt(match[2], 10);\n\n const query = `\n query($teamKey: String!, $number: Float!) {\n issues(filter: { number: { eq: $number }, team: { key: { eq: $teamKey } } }, first: 1) {\n nodes {\n id\n identifier\n title\n description\n labels {\n nodes {\n name\n }\n }\n children {\n nodes {\n id\n identifier\n title\n description\n }\n }\n }\n }\n }\n `;\n\n try {\n const response = await fetch(\"https://api.linear.app/graphql\", {\n method: \"POST\",\n headers: {\n \"Authorization\": apiKey,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n query,\n variables: { teamKey, number: issueNumber },\n }),\n });\n\n if (!response.ok) {\n throw new SpecError(\n `Linear API error (${response.status}): ${response.statusText}`,\n );\n }\n\n const data = await response.json() as LinearResponse;\n\n if (data.errors && data.errors.length > 0) {\n const errorMsg = data.errors.map(e => e.message).join(\", \");\n throw new SpecError(`Linear GraphQL error: ${errorMsg}`);\n }\n\n const nodes = data.data?.issues?.nodes;\n if (!nodes || nodes.length === 0) {\n throw new SpecError(`Issue not found: ${issueId}`);\n }\n\n const issue = nodes[0];\n const title = issue.title || issueId;\n const description = issue.description || \"\";\n\n const parts = [`# ${title}`, description];\n\n // Include sub-issues if present\n const children = issue.children?.nodes || [];\n if (children.length > 0) {\n const subSection = children\n .map((sub) => {\n const subTitle = sub.title || sub.identifier || \"Untitled\";\n const subDesc = sub.description ? `\\n${sub.description}` : \"\";\n return `- **${subTitle}**${subDesc}`;\n })\n .join(\"\\n\");\n parts.push(`## Sub-issues\\n\\n${subSection}`);\n }\n\n const content = parts.filter(p => p.trim()).join(\"\\n\\n\");\n\n // Extract issue type from labels (bug, feature, etc) using partial match\n const labels = issue.labels?.nodes || [];\n const labelNames = labels.map(l => l.name);\n const typeLabel = labels.find(l => {\n const lower = l.name.toLowerCase();\n return [\"bug\", \"feature\", \"enhancement\", \"fix\", \"chore\", \"refactor\", \"doc\", \"test\", \"style\", \"perf\"].some(\n keyword => lower.includes(keyword)\n );\n });\n const issueType = typeLabel?.name;\n\n return { source: \"linear\", issueId, title, content, issueType, labels: labelNames };\n } catch (err) {\n if (err instanceof SpecError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new SpecError(`Failed to fetch Linear issue: ${message}`);\n }\n}\n","import { JiraSpecPayload, SpecError } from \"./spec.js\";\n\nconst JIRA_KEY_PATTERN = /^[A-Z]+-\\d+$/;\n\nexport function isJiraKey(input: string): boolean {\n return JIRA_KEY_PATTERN.test(input);\n}\n\ninterface JiraIssueFields {\n summary: string;\n description?: string | { content: unknown[] };\n issuetype?: { name: string };\n [key: string]: unknown;\n}\n\ninterface JiraIssueResponse {\n key: string;\n fields: JiraIssueFields;\n}\n\nfunction parseADF(adf: { content: unknown[] }): string {\n // Convert Atlassian Document Format to plain text\n const lines: string[] = [];\n\n function walk(node: any): void {\n if (!node) return;\n\n if (node.type === \"text\") {\n lines.push(node.text || \"\");\n } else if (node.type === \"paragraph\") {\n const textContent = node.content\n ?.map((n: any) => n.text || \"\")\n .join(\"\") || \"\";\n if (textContent.trim()) lines.push(textContent);\n } else if (Array.isArray(node.content)) {\n node.content.forEach(walk);\n }\n }\n\n if (Array.isArray(adf.content)) {\n adf.content.forEach(walk);\n }\n\n return lines.join(\"\\n\\n\");\n}\n\nexport async function readJiraSpec(issueKey: string): Promise<JiraSpecPayload> {\n const jiraUrl = process.env.JIRA_URL;\n const jiraEmail = process.env.JIRA_EMAIL;\n const jiraToken = process.env.JIRA_API_TOKEN;\n\n if (!jiraUrl || !jiraEmail || !jiraToken) {\n throw new SpecError(\n `Jira API credentials not configured.\\n\\n` +\n `Add the following to your .env file:\\n\\n` +\n ` JIRA_URL=https://your-company.atlassian.net\\n` +\n ` JIRA_EMAIL=you@company.com\\n` +\n ` JIRA_API_TOKEN=your-api-token\\n\\n` +\n `Get an API token at: https://id.atlassian.com/manage-profile/security/api-tokens`,\n );\n }\n\n const auth = Buffer.from(`${jiraEmail}:${jiraToken}`).toString(\"base64\");\n const url = `${jiraUrl}/rest/api/3/issue/${issueKey}`;\n\n try {\n const response = await fetch(url, {\n headers: {\n \"Authorization\": `Basic ${auth}`,\n \"Accept\": \"application/json\",\n },\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => \"Unknown error\");\n throw new SpecError(\n `Jira API error (${response.status}): ${errorText}`,\n );\n }\n\n const data = await response.json() as JiraIssueResponse;\n const title = data.fields.summary || issueKey;\n\n let description = \"\";\n if (data.fields.description) {\n if (typeof data.fields.description === \"string\") {\n description = data.fields.description;\n } else if (typeof data.fields.description === \"object\" && \"content\" in data.fields.description) {\n description = parseADF(data.fields.description as { content: unknown[] });\n }\n }\n\n // Check common custom field names for acceptance criteria\n const acceptanceCriteria =\n (data.fields.acceptanceCriteria as string | undefined) ||\n (data.fields.acceptance_criteria as string | undefined) ||\n (data.fields.customfield_10001 as string | undefined) ||\n \"\";\n\n const parts = [`# ${title}`, description];\n if (acceptanceCriteria) {\n parts.push(`## Acceptance Criteria\\n\\n${acceptanceCriteria}`);\n }\n\n const content = parts.filter(p => p.trim()).join(\"\\n\\n\");\n const issueType = data.fields.issuetype?.name;\n\n return { source: \"jira\", issueKey, title, content, issueType };\n } catch (err) {\n if (err instanceof SpecError) throw err;\n const message = err instanceof Error ? err.message : String(err);\n throw new SpecError(`Failed to fetch Jira issue: ${message}`);\n }\n}\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport function loadEnvFile(): void {\n const envPath = resolve(process.cwd(), \".env\");\n if (!existsSync(envPath)) return;\n\n const content = readFileSync(envPath, \"utf-8\");\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n const eqIndex = trimmed.indexOf(\"=\");\n if (eqIndex === -1) continue;\n const key = trimmed.slice(0, eqIndex).trim();\n const value = trimmed\n .slice(eqIndex + 1)\n .trim()\n .replace(/^[\"']|[\"']$/g, \"\");\n if (!process.env[key]) process.env[key] = value;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport chalk from 'chalk';\nimport type { StorageBackend, EventFilter, RunSummary } from './backends/types.js';\nimport type { TelemetryEvent, TelemetryLevel } from './events.js';\nimport { EVENT_LEVELS, categoryFromEvent } from './events.js';\n\n/**\n * Configuration for Chesstrace telemetry\n */\nexport interface TelemetryConfig {\n /**\n * Telemetry level to capture (0=minimal, 1=standard, 2=verbose)\n */\n level: TelemetryLevel;\n\n /**\n * Retention period in days (default: 30)\n */\n retentionDays?: number;\n\n /**\n * Optional callback for swallowed errors (for debugging)\n */\n onError?: (err: unknown, operation: string) => void;\n}\n\n/**\n * Core Chesstrace class for telemetry event emission and lifecycle management\n */\nexport class Chesstrace {\n private config: TelemetryConfig;\n private backend: StorageBackend | null = null;\n private currentRunId: string | null = null;\n private initPromise: Promise<void> | null = null;\n private rawEventBuffer: Array<{ event: string; data: Record<string, unknown> }> = [];\n private eventBuffer: TelemetryEvent[] = [];\n private closed = false;\n private flushed = false;\n\n constructor(config: TelemetryConfig) {\n this.config = config;\n }\n\n /**\n * Initialize storage backend\n */\n async init(backend: StorageBackend): Promise<void> {\n if (this.initPromise) {\n return this.initPromise;\n }\n\n this.initPromise = (async () => {\n this.backend = backend;\n await backend.init();\n\n // Auto-prune old events based on retention config\n const retentionDays = this.config.retentionDays ?? 30;\n const olderThan = Date.now() - retentionDays * 24 * 60 * 60 * 1000;\n try {\n const deleted = await backend.prune(olderThan);\n if (deleted > 0) {\n console.log(chalk.gray(`Pruned ${deleted} event(s) older than ${retentionDays} days`));\n }\n } catch (err) {\n this.config.onError?.(err, 'auto-prune');\n }\n })();\n\n return this.initPromise;\n }\n\n /**\n * Generate and store new run ID\n */\n async startRun(): Promise<string> {\n this.currentRunId = randomUUID();\n\n // Process buffered raw events (emitted before startRun)\n const rawBuffered = this.rawEventBuffer.splice(0);\n if (rawBuffered.length > 0 && this.backend) {\n const events: TelemetryEvent[] = [];\n for (const { event, data } of rawBuffered) {\n const minLevel = EVENT_LEVELS[event];\n if (minLevel !== undefined && minLevel <= this.config.level) {\n events.push({\n id: randomUUID(),\n runId: this.currentRunId,\n timestamp: Date.now(),\n category: categoryFromEvent(event),\n event,\n minLevel,\n data,\n });\n }\n }\n if (events.length > 0) {\n this.eventBuffer.push(...events);\n }\n }\n\n return this.currentRunId;\n }\n\n /**\n * Emit telemetry event with level filtering\n */\n emit(event: string, data: Record<string, unknown> = {}): void {\n // Reset flushed flag when new events arrive\n this.flushed = false;\n\n // Buffer raw events before init or before startRun\n if (!this.backend || !this.currentRunId) {\n this.rawEventBuffer.push({ event, data });\n return;\n }\n\n // Filter by level\n const minLevel = EVENT_LEVELS[event];\n if (minLevel === undefined || minLevel > this.config.level) {\n return;\n }\n\n const telemetryEvent: TelemetryEvent = {\n id: randomUUID(),\n runId: this.currentRunId,\n timestamp: Date.now(),\n category: categoryFromEvent(event),\n event,\n minLevel,\n data,\n };\n\n this.eventBuffer.push(telemetryEvent);\n }\n\n /**\n * Flush buffered events to backend\n */\n async flush(): Promise<void> {\n if (!this.backend) {\n return;\n }\n\n const buffered = this.eventBuffer.splice(0);\n if (buffered.length > 0) {\n try {\n await this.backend.writeBatch(buffered);\n } catch (err) {\n this.config.onError?.(err, 'writeBatch');\n }\n }\n\n try {\n await this.backend.flush();\n } catch (err) {\n this.config.onError?.(err, 'flush');\n }\n\n this.flushed = true;\n }\n\n /**\n * Query events from backend\n */\n async query(filter: EventFilter): Promise<TelemetryEvent[]> {\n if (!this.backend) {\n return [];\n }\n\n try {\n return await this.backend.query(filter);\n } catch (err) {\n return [];\n }\n }\n\n /**\n * List all runs with summary metadata\n */\n async listRuns(): Promise<RunSummary[]> {\n if (!this.backend) {\n return [];\n }\n\n try {\n return await this.backend.listRuns();\n } catch (err) {\n return [];\n }\n }\n\n /**\n * Prune events older than specified days\n * @param days - Number of days to retain\n * @returns Number of events deleted\n */\n async prune(days: number): Promise<number> {\n if (!this.backend) {\n return 0;\n }\n\n const olderThan = Date.now() - days * 24 * 60 * 60 * 1000;\n\n try {\n return await this.backend.prune(olderThan);\n } catch (err) {\n return 0;\n }\n }\n\n /**\n * Close backend and flush remaining events\n */\n async close(): Promise<void> {\n if (this.backend) {\n // Only flush if not already flushed or if buffer has new events\n if (!this.flushed || this.eventBuffer.length > 0) {\n await this.flush();\n }\n\n try {\n await this.backend.close();\n } catch (err) {\n this.config.onError?.(err, 'close');\n }\n }\n\n this.closed = true;\n }\n\n /**\n * Check if telemetry is enabled (backend initialized and not closed)\n */\n isEnabled(): boolean {\n return this.backend !== null && !this.closed;\n }\n}\n\n// Singleton instance and config tracking\nlet instance: Chesstrace | null = null;\nlet instanceConfig: TelemetryConfig | undefined = undefined;\n\n/**\n * Get global Chesstrace singleton.\n *\n * **Singleton behavior:** First call creates instance with provided config (or default `{ level: 0 }`).\n * Subsequent calls return same instance and ignore config parameter.\n *\n * **Config mismatch warning:** If called with different config after initialization, logs warning\n * to stderr. Caller must call `resetChesstrace()` first to reinitialize with new config.\n *\n * @param config - Config to use when creating new instance (only used on first call)\n * @returns Chesstrace singleton instance\n *\n * @example\n * ```ts\n * // First call creates instance\n * const trace1 = getChesstrace({ level: TelemetryLevel.standard });\n *\n * // Subsequent calls return same instance, config ignored\n * const trace2 = getChesstrace({ level: TelemetryLevel.verbose }); // Warns!\n *\n * // Reset to reinitialize with different config\n * resetChesstrace();\n * const trace3 = getChesstrace({ level: TelemetryLevel.verbose }); // OK\n * ```\n */\nexport function getChesstrace(config?: TelemetryConfig): Chesstrace {\n if (!instance) {\n const finalConfig = config ?? { level: 0 };\n instance = new Chesstrace(finalConfig);\n instanceConfig = finalConfig;\n } else if (config && JSON.stringify(config) !== JSON.stringify(instanceConfig)) {\n // Config mismatch detected\n console.warn(\n '[Chesstrace] Warning: getChesstrace() called with different config after initialization. ' +\n 'Existing instance returned; new config ignored. Call resetChesstrace() first to reinitialize.'\n );\n }\n return instance;\n}\n\n/**\n * Reset global Chesstrace singleton (for testing)\n */\nexport function resetChesstrace(): void {\n instance = null;\n instanceConfig = undefined;\n}\n","/**\n * Telemetry level enumeration\n */\nexport enum TelemetryLevel {\n minimal = 0,\n standard = 1,\n verbose = 2,\n}\n\n/**\n * Telemetry event categories\n */\nexport type TelemetryCategory =\n | 'command'\n | 'agent'\n | 'llm'\n | 'git'\n | 'spec'\n | 'error'\n | 'performance'\n | 'pipeline'\n | 'usage'\n | 'gate'\n | 'tool'\n | 'knowledge'\n | 'review';\n\n/**\n * Core telemetry event interface\n */\nexport interface TelemetryEvent {\n id: string;\n runId: string;\n timestamp: number;\n category: TelemetryCategory;\n event: string;\n minLevel: TelemetryLevel;\n data: Record<string, unknown>;\n}\n\n/**\n * Event name constants\n */\nexport const Events = {\n // Command events (minimal level)\n COMMAND_START: 'command.start',\n COMMAND_END: 'command.end',\n COMMAND_ERROR: 'command.error',\n\n // Agent events (standard level)\n AGENT_START: 'agent.start',\n AGENT_END: 'agent.end',\n AGENT_ERROR: 'agent.error',\n AGENT_TOOL_CALL: 'agent.tool_call',\n /** Emitted when agent spawn begins - { agent, provider, model, stage? } */\n AGENT_SPAWN: 'agent.spawn',\n /** Emitted when agent spawn completes or errors - { agent, stage?, exitCode, duration, success } */\n AGENT_COMPLETE: 'agent.complete',\n /** Emitted when agent spawn exceeds timeout - { agent, stage?, timeoutMs } */\n AGENT_TIMEOUT: 'agent.timeout',\n\n // LLM events (verbose level)\n LLM_REQUEST: 'llm.request',\n LLM_RESPONSE: 'llm.response',\n LLM_TOKEN_USAGE: 'llm.token_usage',\n LLM_ERROR: 'llm.error',\n\n // Git events (standard level)\n GIT_BRANCH_CREATE: 'git.branch_create',\n GIT_COMMIT: 'git.commit',\n GIT_PUSH: 'git.push',\n GIT_ERROR: 'git.error',\n\n // Spec events (standard level)\n SPEC_FETCH: 'spec.fetch',\n SPEC_PARSE: 'spec.parse',\n SPEC_ERROR: 'spec.error',\n\n // Error events (minimal level)\n ERROR_UNHANDLED: 'error.unhandled',\n ERROR_VALIDATION: 'error.validation',\n /** Emitted on TaskError catch - { type, message, stage, agent } */\n ERROR_TASK: 'error.task',\n /** Emitted on JSON parse failures - { agent, expectedFormat, received } */\n ERROR_PARSE: 'error.parse',\n /** Emitted when provider unavailable - { provider, reason } */\n ERROR_PROVIDER: 'error.provider',\n\n // Performance events (verbose level)\n PERF_METRIC: 'performance.metric',\n PERF_DURATION: 'performance.duration',\n\n // Pipeline events (standard level)\n PIPELINE_START: 'pipeline.start',\n PIPELINE_END: 'pipeline.end',\n PIPELINE_STAGE_START: 'pipeline.stage_start',\n PIPELINE_STAGE_END: 'pipeline.stage_end',\n\n // Usage events (verbose level)\n USAGE_TOKENS: 'usage.tokens',\n USAGE_COST: 'usage.cost',\n // Gate events (standard level)\n /** Emitted after each gate execution - { gateName, passed, attempt } */\n GATE_RESULT: 'gate.result',\n /** Emitted when gate retry triggered - { gateName, attempt, maxRetries, failureSnippet } */\n GATE_RETRY: 'gate.retry',\n\n // Tool events\n /** Emitted on each tool invocation - { agent, tool, detail? } (standard level) */\n TOOL_INVOKE: 'tool.invoke',\n /** Emitted on each tool invocation with full input/output - { agent, tool, input?, output? } (verbose level) */\n TOOL_INVOKE_FULL: 'tool.invoke.full',\n /** Emitted at stage end with aggregate tool counts - { stage, toolCounts } (minimal level) */\n TOOL_SUMMARY: 'tool.summary',\n\n // Knowledge events (standard level)\n /** Emitted when knowledge consulted before agent spawn - { agent, stage?, entries, entryCount } */\n KNOWLEDGE_CONSULTED: 'knowledge.consulted',\n /** Emitted when knowledge prevents failure - { entry, agent, evidence } (minimal level) */\n KNOWLEDGE_PREVENTED_FAILURE: 'knowledge.prevented_failure',\n /** Emitted when knowledge-based run succeeds - { entries_used, agent, stage } (standard level) */\n KNOWLEDGE_SUCCESS: 'knowledge.success',\n\n // Review events (standard level)\n /** Emitted when diff budget applied - { filesIncluded, filesExcluded, tokensUsed, tokensAvailable, excludedFilesList } */\n REVIEW_DIFF_BUDGET: 'review.diff_budget',\n} as const;\n\n/**\n * Mapping of event names to their minimum telemetry level\n */\nexport const EVENT_LEVELS: Record<string, TelemetryLevel> = {\n // Command events - minimal\n [Events.COMMAND_START]: TelemetryLevel.minimal,\n [Events.COMMAND_END]: TelemetryLevel.minimal,\n [Events.COMMAND_ERROR]: TelemetryLevel.minimal,\n\n // Agent events - standard\n [Events.AGENT_START]: TelemetryLevel.standard,\n [Events.AGENT_END]: TelemetryLevel.standard,\n [Events.AGENT_ERROR]: TelemetryLevel.standard,\n [Events.AGENT_TOOL_CALL]: TelemetryLevel.standard,\n [Events.AGENT_SPAWN]: TelemetryLevel.standard,\n [Events.AGENT_COMPLETE]: TelemetryLevel.standard,\n [Events.AGENT_TIMEOUT]: TelemetryLevel.standard,\n\n // LLM events - verbose\n [Events.LLM_REQUEST]: TelemetryLevel.verbose,\n [Events.LLM_RESPONSE]: TelemetryLevel.verbose,\n [Events.LLM_TOKEN_USAGE]: TelemetryLevel.verbose,\n [Events.LLM_ERROR]: TelemetryLevel.verbose,\n\n // Git events - standard\n [Events.GIT_BRANCH_CREATE]: TelemetryLevel.standard,\n [Events.GIT_COMMIT]: TelemetryLevel.standard,\n [Events.GIT_PUSH]: TelemetryLevel.standard,\n [Events.GIT_ERROR]: TelemetryLevel.standard,\n\n // Spec events - standard\n [Events.SPEC_FETCH]: TelemetryLevel.standard,\n [Events.SPEC_PARSE]: TelemetryLevel.standard,\n [Events.SPEC_ERROR]: TelemetryLevel.standard,\n\n // Error events - minimal\n [Events.ERROR_UNHANDLED]: TelemetryLevel.minimal,\n [Events.ERROR_VALIDATION]: TelemetryLevel.minimal,\n [Events.ERROR_TASK]: TelemetryLevel.minimal,\n [Events.ERROR_PARSE]: TelemetryLevel.minimal,\n [Events.ERROR_PROVIDER]: TelemetryLevel.minimal,\n\n // Performance events - verbose\n [Events.PERF_METRIC]: TelemetryLevel.verbose,\n [Events.PERF_DURATION]: TelemetryLevel.verbose,\n\n // Pipeline events - standard\n [Events.PIPELINE_START]: TelemetryLevel.standard,\n [Events.PIPELINE_END]: TelemetryLevel.standard,\n [Events.PIPELINE_STAGE_START]: TelemetryLevel.standard,\n [Events.PIPELINE_STAGE_END]: TelemetryLevel.standard,\n\n // Usage events - verbose\n [Events.USAGE_TOKENS]: TelemetryLevel.verbose,\n [Events.USAGE_COST]: TelemetryLevel.verbose,\n // Gate events - standard\n [Events.GATE_RESULT]: TelemetryLevel.standard,\n [Events.GATE_RETRY]: TelemetryLevel.standard,\n\n // Tool events\n [Events.TOOL_INVOKE]: TelemetryLevel.standard,\n [Events.TOOL_INVOKE_FULL]: TelemetryLevel.verbose,\n [Events.TOOL_SUMMARY]: TelemetryLevel.minimal,\n\n // Knowledge events\n [Events.KNOWLEDGE_CONSULTED]: TelemetryLevel.standard,\n [Events.KNOWLEDGE_PREVENTED_FAILURE]: TelemetryLevel.minimal,\n [Events.KNOWLEDGE_SUCCESS]: TelemetryLevel.standard,\n\n // Review events\n [Events.REVIEW_DIFF_BUDGET]: TelemetryLevel.standard,\n};\n\n/**\n * Extract category from event name\n * @param event - Event name (e.g., \"command.start\")\n * @returns Category portion before the dot\n */\nexport function categoryFromEvent(event: string): TelemetryCategory {\n const category = event.split('.')[0];\n\n // Validate category is valid TelemetryCategory\n const validCategories: TelemetryCategory[] = [\n 'command',\n 'agent',\n 'llm',\n 'git',\n 'spec',\n 'error',\n 'performance',\n 'pipeline',\n 'usage',\n 'gate',\n 'tool',\n 'knowledge',\n 'review',\n ];\n\n if (validCategories.includes(category as TelemetryCategory)) {\n return category as TelemetryCategory;\n }\n\n throw new Error(`Invalid event category: ${category}`);\n}\n","/**\n * Reset terminal state before user input prompts.\n *\n * After ora spinners finish, terminal cursor/stdin state can be inconsistent.\n * This causes two classes of bugs:\n * 1. Pasted text corrupts the prompt (buffered input from during spinner)\n * 2. Cursor gets \"stuck\" — typing only moves back and forth on one line\n * (readline's cursor tracker is desynced from actual terminal state)\n *\n * This function ensures a clean slate for the next readline/inquirer prompt:\n * - SGR text attributes are reset (no color/bold leaking from spinner)\n * - Cursor is visible\n * - stdin is not in raw mode (ora/stdin-discarder may leave it set)\n * - Current line is fully cleared and cursor is at column 0\n */\nexport function resetTerminalForInput(): void {\n // Reset all SGR text attributes (bold, color, underline, etc.)\n process.stdout.write('\\x1b[0m');\n\n // Show cursor (ora hides it while spinning)\n process.stdout.write('\\x1b[?25h');\n\n // Ensure stdin is not stuck in raw mode — readline/inquirer manage their own\n // raw mode and will break if stdin is already raw when they start.\n // Only disable raw mode if stdin is paused (not actively managed by readline).\n if (process.stdin.isTTY && process.stdin.isRaw && process.stdin.isPaused()) {\n process.stdin.setRawMode(false);\n }\n\n // Move to column 0 and clear the entire line (not just cursor-to-end)\n process.stdout.write('\\r\\x1b[2K');\n}\n","import Database from 'better-sqlite3';\nimport { join, dirname } from 'node:path';\nimport { existsSync, mkdirSync, statSync } from 'node:fs';\nimport type { StorageBackend, EventFilter, RunSummary } from './types.js';\nimport type { TelemetryEvent, TelemetryCategory } from '../events.js';\nimport { findLocalConfigDir, resolveGlobalConfigDir } from '../../config.js';\n\n/**\n * Max DB size in bytes (50MB default, prevents disk exhaustion)\n */\nconst MAX_DB_SIZE_BYTES = 50 * 1024 * 1024;\n\n/**\n * Max events per run (prevents event spam attacks)\n */\nconst MAX_EVENTS_PER_RUN = 10000;\n\n/**\n * SQLite storage backend for telemetry events\n */\nexport class SqliteBackend implements StorageBackend {\n private db: Database.Database | null = null;\n private dbPath: string;\n\n constructor(scope: 'local' | 'global' = 'local', explicitPath?: string) {\n this.dbPath = explicitPath ?? this.resolveDbPath(scope);\n }\n\n /**\n * Resolve database file path based on scope\n * Local: .reygent/chesstrace.db (search upward from cwd)\n * Global: ~/.reygent/chesstrace.db\n */\n private resolveDbPath(scope: 'local' | 'global'): string {\n if (scope === 'local') {\n const configDir = findLocalConfigDir(process.cwd());\n if (configDir) {\n return join(configDir, 'chesstrace.db');\n }\n // Fallback to global if no local .reygent found\n scope = 'global';\n }\n\n const globalDir = resolveGlobalConfigDir();\n // Ensure global .reygent directory exists\n if (!existsSync(globalDir)) {\n mkdirSync(globalDir, { recursive: true });\n }\n return join(globalDir, 'chesstrace.db');\n }\n\n /**\n * Initialize database schema and indexes\n */\n async init(): Promise<void> {\n // Ensure parent directory exists\n const dbDir = dirname(this.dbPath);\n if (!existsSync(dbDir)) {\n mkdirSync(dbDir, { recursive: true });\n }\n\n this.db = new Database(this.dbPath);\n\n // Enable WAL mode for better concurrency\n this.db.pragma('journal_mode = WAL');\n\n // Create events table\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n run_id TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n category TEXT NOT NULL,\n event TEXT NOT NULL,\n min_level INTEGER NOT NULL,\n data TEXT NOT NULL\n )\n `);\n\n // Create indexes for efficient querying\n this.db.exec(`\n CREATE INDEX IF NOT EXISTS idx_events_run_id ON events(run_id);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n CREATE INDEX IF NOT EXISTS idx_events_category ON events(category);\n CREATE INDEX IF NOT EXISTS idx_events_event ON events(event);\n `);\n }\n\n /**\n * Check if database size exceeds limit\n */\n private checkDbSize(): boolean {\n if (!existsSync(this.dbPath)) return true;\n try {\n const stats = statSync(this.dbPath);\n return stats.size < MAX_DB_SIZE_BYTES;\n } catch (err) {\n // File deleted between existsSync and statSync (race condition)\n // Treat as valid (file doesn't exist = no size limit hit)\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] checkDbSize stat failed (file deleted?):', err instanceof Error ? err.message : String(err));\n }\n return true;\n }\n }\n\n /**\n * Check if run has exceeded event limit (prevents spam)\n */\n private checkRunEventLimit(runId: string): boolean {\n if (!this.db) return false;\n const result = this.db.prepare('SELECT COUNT(*) as count FROM events WHERE run_id = ?').get(runId) as { count: number };\n return result.count < MAX_EVENTS_PER_RUN;\n }\n\n /**\n * Prune old events to free space (keeps last 180 days)\n */\n private pruneOldEvents(): void {\n if (!this.db) return;\n const cutoffMs = Date.now() - (180 * 24 * 60 * 60 * 1000);\n this.db.prepare('DELETE FROM events WHERE timestamp < ?').run(cutoffMs);\n this.db.pragma('vacuum');\n }\n\n /**\n * Write single event to database\n */\n async write(event: TelemetryEvent): Promise<void> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n // Security: Check DB size limit\n if (!this.checkDbSize()) {\n // Attempt to prune old events\n this.pruneOldEvents();\n // If still too large after pruning, skip write silently\n if (!this.checkDbSize()) {\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] DB size limit hit, skipping write (event:', event.event, ')');\n }\n return;\n }\n }\n\n // Security: Check per-run event limit (prevent spam)\n if (!this.checkRunEventLimit(event.runId)) {\n return;\n }\n\n const stmt = this.db.prepare(`\n INSERT INTO events (id, run_id, timestamp, category, event, min_level, data)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n event.id,\n event.runId,\n event.timestamp,\n event.category,\n event.event,\n event.minLevel,\n JSON.stringify(event.data),\n );\n }\n\n /**\n * Write multiple events in a transaction\n */\n async writeBatch(events: TelemetryEvent[]): Promise<void> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n // Security: Check DB size limit\n if (!this.checkDbSize()) {\n this.pruneOldEvents();\n if (!this.checkDbSize()) {\n return;\n }\n }\n\n const stmt = this.db.prepare(`\n INSERT INTO events (id, run_id, timestamp, category, event, min_level, data)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n `);\n\n const transaction = this.db.transaction((events: TelemetryEvent[]) => {\n for (const event of events) {\n // Security: Check per-run limit for each event\n if (!this.checkRunEventLimit(event.runId)) {\n continue;\n }\n\n stmt.run(\n event.id,\n event.runId,\n event.timestamp,\n event.category,\n event.event,\n event.minLevel,\n JSON.stringify(event.data),\n );\n }\n });\n\n transaction(events);\n }\n\n /**\n * Query events matching filter criteria\n */\n async query(filter: EventFilter): Promise<TelemetryEvent[]> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (filter.runId !== undefined) {\n conditions.push('run_id = ?');\n params.push(filter.runId);\n }\n\n if (filter.category !== undefined) {\n conditions.push('category = ?');\n params.push(filter.category);\n }\n\n if (filter.event !== undefined) {\n conditions.push('event = ?');\n params.push(filter.event);\n }\n\n if (filter.minLevel !== undefined) {\n conditions.push('min_level >= ?');\n params.push(filter.minLevel);\n }\n\n if (filter.startTime !== undefined) {\n conditions.push('timestamp >= ?');\n params.push(filter.startTime);\n }\n\n if (filter.endTime !== undefined) {\n conditions.push('timestamp <= ?');\n params.push(filter.endTime);\n }\n\n const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';\n const sql = `SELECT * FROM events ${whereClause} ORDER BY timestamp ASC`;\n\n const rows = this.db.prepare(sql).all(...params) as Array<{\n id: string;\n run_id: string;\n timestamp: number;\n category: TelemetryCategory;\n event: string;\n min_level: number;\n data: string;\n }>;\n\n return rows.map((row) => ({\n id: row.id,\n runId: row.run_id,\n timestamp: row.timestamp,\n category: row.category,\n event: row.event,\n minLevel: row.min_level,\n data: JSON.parse(row.data) as Record<string, unknown>,\n }));\n }\n\n /**\n * List all runs with summary metadata\n */\n async listRuns(): Promise<RunSummary[]> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const sql = `\n SELECT\n run_id,\n MIN(timestamp) as start_time,\n MAX(timestamp) as end_time,\n COUNT(*) as event_count,\n GROUP_CONCAT(DISTINCT category) as categories\n FROM events\n GROUP BY run_id\n ORDER BY start_time DESC\n `;\n\n const rows = this.db.prepare(sql).all() as Array<{\n run_id: string;\n start_time: number;\n end_time: number;\n event_count: number;\n categories: string;\n }>;\n\n return rows.map((row) => ({\n runId: row.run_id,\n startTime: row.start_time,\n endTime: row.end_time,\n eventCount: row.event_count,\n categories: row.categories.split(',') as TelemetryCategory[],\n }));\n }\n\n /**\n * Flush pending writes (SQLite auto-commits, so this is a no-op)\n */\n async flush(): Promise<void> {\n // SQLite auto-commits after each transaction, so nothing to flush\n }\n\n /**\n * Prune events older than timestamp\n * @param olderThan - Unix timestamp in milliseconds\n * @returns Number of events deleted\n */\n async prune(olderThan: number): Promise<number> {\n if (!this.db) {\n throw new Error('Database not initialized. Call init() first.');\n }\n\n const stmt = this.db.prepare('DELETE FROM events WHERE timestamp < ?');\n const result = stmt.run(olderThan);\n return result.changes;\n }\n\n /**\n * Close database connection\n */\n async close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n }\n }\n\n /**\n * Get database file path (useful for debugging/testing)\n */\n getDbPath(): string {\n return this.dbPath;\n }\n}\n","import type { StorageBackend, EventFilter, RunSummary } from './types.js';\nimport type { TelemetryEvent } from '../events.js';\nimport { SqliteBackend } from './sqlite.js';\n\n/**\n * Dual backend that writes to both local and global storage.\n * Used when running in a project - writes telemetry to both\n * project-specific db and global aggregate db.\n *\n * Set REYGENT_GLOBAL_TELEMETRY=false to disable global writes (security).\n */\nexport class DualBackend implements StorageBackend {\n private localBackend: SqliteBackend;\n private globalBackend: SqliteBackend | null;\n private globalEnabled: boolean;\n\n constructor(projectRoot: string) {\n // Local backend stores project-specific telemetry in chesstrace.db\n this.localBackend = new SqliteBackend('local', `${projectRoot}/.reygent/chesstrace.db`);\n\n // Global backend opt-out for security (prevent cross-project data leakage)\n this.globalEnabled = process.env.REYGENT_GLOBAL_TELEMETRY !== 'false';\n this.globalBackend = this.globalEnabled ? new SqliteBackend('global') : null;\n }\n\n async init(): Promise<void> {\n const tasks = [this.localBackend.init()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.init());\n }\n await Promise.all(tasks);\n }\n\n async write(event: TelemetryEvent): Promise<void> {\n // Write to both, but don't fail if one fails\n const tasks = [this.localBackend.write(event)];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.write(event));\n }\n const results = await Promise.allSettled(tasks);\n\n // Log failures in debug mode\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n results.forEach((result, idx) => {\n if (result.status === 'rejected') {\n const backend = idx === 0 ? 'local' : 'global';\n console.error(`[debug:telemetry] Dual backend ${backend} write failed:`, result.reason instanceof Error ? result.reason.message : String(result.reason));\n }\n });\n }\n }\n\n async writeBatch(events: TelemetryEvent[]): Promise<void> {\n const tasks = [this.localBackend.writeBatch(events)];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.writeBatch(events));\n }\n const results = await Promise.allSettled(tasks);\n\n // Log failures in debug mode\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n results.forEach((result, idx) => {\n if (result.status === 'rejected') {\n const backend = idx === 0 ? 'local' : 'global';\n console.error(`[debug:telemetry] Dual backend ${backend} writeBatch failed:`, result.reason instanceof Error ? result.reason.message : String(result.reason));\n }\n });\n }\n }\n\n async query(filter?: EventFilter): Promise<TelemetryEvent[]> {\n // Query from local only (project-specific data)\n return this.localBackend.query(filter);\n }\n\n async getRunSummaries(limit?: number): Promise<RunSummary[]> {\n // Get summaries from local only\n return this.localBackend.getRunSummaries(limit);\n }\n\n getEvents(): TelemetryEvent[] {\n // Get events from local only\n return this.localBackend.getEvents();\n }\n\n async flush(): Promise<void> {\n const tasks = [this.localBackend.flush()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.flush());\n }\n await Promise.all(tasks);\n }\n\n async close(): Promise<void> {\n const tasks = [this.localBackend.close()];\n if (this.globalBackend) {\n tasks.push(this.globalBackend.close());\n }\n await Promise.all(tasks);\n }\n}\n","import { existsSync } from 'node:fs';\nimport { join, dirname, parse } from 'node:path';\n\n/**\n * Project markers that indicate a project root directory.\n * Checked in order of specificity.\n */\nconst PROJECT_MARKERS = [\n '.reygent', // Reygent already initialized\n '.git', // Git repository\n 'package.json', // Node.js project\n 'pyproject.toml', // Python project\n 'Cargo.toml', // Rust project\n 'go.mod', // Go project\n 'Gemfile', // Ruby project\n 'composer.json', // PHP project\n 'pom.xml', // Java/Maven project\n 'build.gradle', // Java/Gradle project\n];\n\n/**\n * Max number of directories to traverse upward (security limit)\n */\nconst MAX_TRAVERSAL_DEPTH = 10;\n\n/**\n * Search upward from startDir to find project root.\n * Returns project root directory if found, null otherwise.\n *\n * Searches for common project markers (.git, package.json, etc.)\n * starting from startDir and walking up the directory tree.\n * Limited to MAX_TRAVERSAL_DEPTH levels to prevent excessive filesystem traversal.\n */\nexport function findProjectRoot(startDir: string): string | null {\n let currentDir = startDir;\n const root = parse(currentDir).root;\n let depth = 0;\n\n while (currentDir !== root && depth < MAX_TRAVERSAL_DEPTH) {\n // Check if any project marker exists in current directory\n for (const marker of PROJECT_MARKERS) {\n if (existsSync(join(currentDir, marker))) {\n return currentDir;\n }\n }\n\n // Move up one directory\n currentDir = dirname(currentDir);\n depth++;\n }\n\n // Hit traversal limit - log for debugging\n if (depth >= MAX_TRAVERSAL_DEPTH && (process.env.REYGENT_DEBUG === '1')) {\n console.error(`[debug] findProjectRoot: MAX_TRAVERSAL_DEPTH (${MAX_TRAVERSAL_DEPTH}) reached from ${startDir}`);\n }\n\n return null;\n}\n\n/**\n * Check if currently in a project (has project root).\n */\nexport function isInProject(startDir: string = process.cwd()): boolean {\n return findProjectRoot(startDir) !== null;\n}\n","import { getChesstrace, resetChesstrace } from './chesstrace/index.js';\nimport type { Chesstrace } from './chesstrace/index.js';\nimport { Events, TelemetryLevel } from './chesstrace/events.js';\nimport { DualBackend } from './chesstrace/backends/dual.js';\nimport { SqliteBackend } from './chesstrace/backends/sqlite.js';\nimport { loadConfig } from './config.js';\nimport { getTelemetryOverride, resolveTelemetryEnabled } from './telemetry-override.js';\nimport { findProjectRoot } from './project-detection.js';\nimport { isDebug } from './debug.js';\n\n/**\n * Context passed to command body within withTelemetry wrapper.\n */\nexport interface TelemetryContext {\n chesstrace: Chesstrace | null;\n}\n\n/**\n * Wrap a command body with telemetry lifecycle management.\n *\n * - Resolves config + overrides, creates backend, calls init() + startRun()\n * - Emits COMMAND_START before body, COMMAND_END on success, COMMAND_ERROR on throw\n * - Guarantees flush() + close() in finally\n * - If telemetry disabled or init fails, runs body with chesstrace: null\n *\n * Note: run.ts keeps its own inline init (has .reygent/ auto-creation + knowledge update logic).\n */\nexport async function withTelemetry<T>(\n commandName: string,\n body: (ctx: TelemetryContext) => Promise<T>,\n): Promise<T> {\n let chesstrace: Chesstrace | null = null;\n const startTime = Date.now();\n\n try {\n const config = loadConfig();\n const telemetryOverride = getTelemetryOverride();\n const { enabled, level: levelStr } = resolveTelemetryEnabled(telemetryOverride, config);\n const telemetryLevel = TelemetryLevel[levelStr];\n\n if (enabled) {\n // Reset singleton to avoid config mismatch warnings from prior commands\n resetChesstrace();\n chesstrace = getChesstrace({ level: telemetryLevel, retentionDays: config.telemetry?.retention ?? 30 });\n\n const projectRoot = findProjectRoot(process.cwd());\n const backend = projectRoot\n ? new DualBackend(projectRoot)\n : new SqliteBackend('global');\n\n await chesstrace.init(backend);\n await chesstrace.startRun();\n }\n } catch (err) {\n if (isDebug()) {\n console.error('[telemetry] init failed:', err);\n }\n chesstrace = null;\n }\n\n // Emit COMMAND_START\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_START, { command: commandName });\n } catch {\n // Swallow emit errors\n }\n }\n\n try {\n const result = await body({ chesstrace });\n\n // Emit COMMAND_END on success\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_END, {\n command: commandName,\n success: true,\n durationMs: Date.now() - startTime,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n return result;\n } catch (err) {\n // Emit COMMAND_ERROR on throw\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_ERROR, {\n command: commandName,\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - startTime,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n throw err;\n } finally {\n if (chesstrace) {\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n }\n}\n","import { createInterface } from \"node:readline\";\nimport { writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport chalk from \"chalk\";\nimport { isDebug } from \"../debug.js\";\nimport { generateSpec, runClarification } from \"../generate-spec.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\nimport { wrapText } from \"../format.js\";\n\nasync function prompt(question: string, fallback?: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(question, resolve);\n });\n rl.close();\n return answer.trim() || fallback || \"\";\n}\n\nexport async function generateSpecCommand(\n description: string | undefined,\n options: { output?: string; skipClarification: boolean },\n): Promise<void> {\n return withTelemetry('generate-spec', async () => {\n try {\n if (!description) {\n description = await prompt(\"Feature description: \");\n if (!description) {\n console.log(chalk.red.bold(\"Error:\"), \"Description is required.\");\n process.exit(1);\n }\n }\n\n let output = options.output;\n if (!output) {\n output = await prompt(\"Output file path (spec.md): \", \"spec.md\");\n }\n\n let clarificationAnswers: string | undefined;\n\n if (!options.skipClarification) {\n // Clarification loop\n let attempts = 0;\n const maxAttempts = 3;\n let ready = false;\n\n while (!ready && attempts < maxAttempts) {\n attempts++;\n const clarifyStatus = createLiveStatus(\"Checking if clarification needed...\");\n\n let result: Awaited<ReturnType<typeof runClarification>>;\n try {\n result = await runClarification(description!, clarificationAnswers, clarifyStatus.onActivity);\n } catch (err) {\n clarifyStatus.fail(chalk.red(\"Failed to check clarification needs\"));\n if (err instanceof TaskError) {\n throw err;\n }\n const message = err instanceof Error ? err.message : String(err);\n throw new TaskError(`Clarification check failed: ${message}`);\n }\n\n if (\"ready\" in result && result.ready) {\n clarifyStatus.succeed(chalk.green(\"No clarification needed\"));\n ready = true;\n break;\n }\n\n if (\"needsClarification\" in result && result.needsClarification) {\n clarifyStatus.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\n━━━ Clarifying Questions ━━━\\n\"));\n\n const answers: string[] = [];\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const termWidth = Math.max(process.stdout.columns || 80, 40);\n\n try {\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n\n // Add empty line before first question for consistency\n if (i === 0) {\n console.log();\n }\n\n const counter = chalk.cyan(`Question ${i + 1} of ${result.questions.length}`);\n console.log(counter);\n\n // Wrap question text to terminal width with 2-space indent\n const wrapped = wrapText(question, 2, termWidth, \" \");\n console.log(` ${wrapped}`);\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(chalk.gray(\"> \"), resolve);\n });\n\n if (answer.trim().toLowerCase() === \"abort\" || answer.trim().toLowerCase() === \"cancel\") {\n console.log(chalk.red(\"\\nAborted.\"));\n process.exit(0);\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n\n // Add spacing between questions except after last one\n if (i < result.questions.length - 1) {\n console.log();\n }\n }\n } finally {\n rl.close();\n }\n\n clarificationAnswers = answers.join(\"\\n\\n\");\n\n if (attempts < maxAttempts) {\n console.log(chalk.blue(\"\\n━━━ Re-checking with your answers ━━━\\n\"));\n }\n }\n }\n\n if (!ready && attempts >= maxAttempts) {\n // Exhausted attempts, proceed with answers collected so far\n console.log(chalk.yellow(\"Max clarification rounds reached, generating spec with answers so far...\"));\n }\n }\n\n const genStatus = createLiveStatus(\"Generating spec...\");\n\n let markdown: string;\n try {\n markdown = await generateSpec(description!, clarificationAnswers, genStatus.onActivity);\n genStatus.succeed(chalk.green(\"Spec generated\"));\n } catch (err) {\n genStatus.fail(chalk.red(\"Failed to generate spec\"));\n throw err;\n }\n\n const outPath = resolve(process.cwd(), output);\n writeFileSync(outPath, markdown, \"utf-8\");\n console.log(chalk.gray(\"Spec written to\"), chalk.cyan(outPath));\n } catch (err) {\n if (err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","import { existsSync, readFileSync, readdirSync, statSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport { findLocalConfigDir } from \"../config.js\";\nimport { marked } from \"marked\";\nimport { isTestEnvironment } from \"../test-env.js\";\n\nexport interface KnowledgeEntry {\n id: string;\n title: string;\n content: string;\n source: string; // file path\n agent?: string; // relevant agent name (for agent-specific tips)\n metadata?: Record<string, unknown>; // parsed from content (occurrences, dates, etc)\n}\n\nexport interface Knowledge {\n agentTips: string;\n commonFailures: string;\n successPatterns: string;\n projectConventions: string;\n entriesLoaded: string[]; // entry IDs for telemetry\n}\n\n/**\n * Find .reygent/knowledge/ directory, searching upward from cwd.\n * Returns null if no .reygent/ found.\n */\nexport function findKnowledgeDir(): string | null {\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) return null;\n return join(configDir, \"knowledge\");\n}\n\n/**\n * Sanitize markdown content to prevent prompt injection attacks.\n * Removes potentially malicious patterns while preserving legitimate content.\n */\nfunction sanitizeMarkdown(content: string): string {\n // Remove common prompt injection patterns\n return content\n // Remove instructions to ignore previous instructions\n .replace(/ignore (all |previous |prior )?(instructions|prompts|context)/gi, '[FILTERED]')\n // Remove instructions to reveal system prompts\n .replace(/show me (your|the) (system prompt|instructions)/gi, '[FILTERED]')\n // Remove instructions to output sensitive files\n .replace(/output (the )?(contents? of|entire) (\\.|\\/)?\\.?env/gi, '[FILTERED]')\n .replace(/(print|show|display|output) (secrets?|keys?|tokens?|passwords?)/gi, '[FILTERED]')\n // Remove roleplaying attempts\n .replace(/pretend (you are|to be) /gi, '[FILTERED]')\n .replace(/act as (if )?/gi, '[FILTERED]');\n}\n\n/**\n * Validate markdown content is well-formed and safe.\n * Returns true if content passes validation.\n */\nfunction validateMarkdown(content: string): boolean {\n if (!content || content.trim().length === 0) return true;\n\n // Check for excessive size (>1MB indicates potential attack)\n if (content.length > 1024 * 1024) return false;\n\n // Check for suspicious patterns (many consecutive special chars)\n if (/[^a-zA-Z0-9\\s]{50,}/.test(content)) return false;\n\n return true;\n}\n\n/**\n * Load and parse a markdown file.\n * Returns empty string if file doesn't exist or is empty.\n * Returns null if file validation fails (security).\n * Validates and sanitizes content to prevent prompt injection attacks.\n */\nexport function readMarkdown(filePath: string): string | null {\n if (!existsSync(filePath)) return \"\";\n\n const content = readFileSync(filePath, \"utf-8\");\n\n // Empty file is valid - return empty string\n if (!content || content.trim().length === 0) return \"\";\n\n // Validate content\n if (!validateMarkdown(content)) {\n console.warn(chalk.yellow(`⚠ Suspicious content detected in ${filePath}, skipping`));\n return null;\n }\n\n // Sanitize content\n return sanitizeMarkdown(content);\n}\n\n/**\n * Parse markdown content into structured entries.\n * Each top-level ## heading becomes an entry.\n * Returns array of entries with id, title, content.\n */\nexport function parseMarkdownEntries(markdown: string, source: string): KnowledgeEntry[] {\n if (!markdown.trim()) return [];\n\n let tokens;\n try {\n tokens = marked.lexer(markdown);\n } catch (err) {\n // Malformed markdown - return empty array instead of crashing\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'knowledge') {\n console.warn(`[debug:knowledge] Failed to parse markdown from ${source}:`, err instanceof Error ? err.message : String(err));\n }\n return [];\n }\n\n const entries: KnowledgeEntry[] = [];\n let currentEntry: Partial<KnowledgeEntry> | null = null;\n let currentContent: string[] = [];\n\n for (const token of tokens) {\n if (token.type === \"heading\" && token.depth === 2) {\n // Save previous entry\n if (currentEntry) {\n entries.push({\n id: currentEntry.id!,\n title: currentEntry.title!,\n content: currentContent.join(\"\\n\").trim(),\n source,\n });\n }\n\n // Start new entry\n const title = token.text;\n const id = slugify(title);\n currentEntry = { id, title, source };\n currentContent = [];\n } else if (currentEntry) {\n // Accumulate content for current entry\n currentContent.push(token.raw);\n }\n }\n\n // Save final entry\n if (currentEntry) {\n entries.push({\n id: currentEntry.id!,\n title: currentEntry.title!,\n content: currentContent.join(\"\\n\").trim(),\n source,\n });\n }\n\n return entries;\n}\n\n/**\n * Slugify string: lowercase, replace spaces with dashes, remove non-alphanumeric.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/[^a-z0-9-]/g, \"\");\n}\n\n/**\n * Filter markdown entries by agent name.\n * Searches for agent name in entry content (case-insensitive).\n * Matches both \"Agent: name\" and \"**Agent**: name\" formats.\n */\nexport function filterByAgent(markdown: string, agentName: string, source: string): string {\n const entries = parseMarkdownEntries(markdown, source);\n const agentLower = agentName.toLowerCase();\n const filtered = entries.filter((entry) => {\n const contentLower = entry.content.toLowerCase();\n // Match \"Agent: name\" or \"**Agent**: name\"\n return contentLower.includes(`agent: ${agentLower}`) ||\n contentLower.includes(`**agent**: ${agentLower}`);\n });\n\n if (filtered.length === 0) return \"\";\n\n // Reconstruct markdown from filtered entries\n return filtered.map((entry) => `## ${entry.title}\\n\\n${entry.content}`).join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Filter markdown entries by recency (last N days).\n * Searches for \"Last seen: YYYY-MM-DD\" in entry content.\n * Handles both bold (**Last seen**:) and plain (Last seen:) formats.\n */\nexport function filterByRecency(markdown: string, source: string, days: number): string {\n const entries = parseMarkdownEntries(markdown, source);\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - days);\n\n const filtered = entries.filter((entry) => {\n // Match both **Last seen**: and Last seen: formats\n const match = entry.content.match(/(?:\\*\\*)?Last seen(?:\\*\\*)?:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n if (!match) return false; // No date found, exclude\n\n const lastSeen = new Date(match[1]);\n return lastSeen >= cutoffDate;\n });\n\n if (filtered.length === 0) return \"\";\n\n return filtered.map((entry) => `## ${entry.title}\\n\\n${entry.content}`).join(\"\\n\\n---\\n\\n\");\n}\n\n/**\n * Load knowledge for specific agent and stage.\n * Returns Knowledge object with relevant sections and entry IDs.\n */\nexport async function loadKnowledge(agentName: string, stage?: string): Promise<Knowledge> {\n const knowledgeDir = findKnowledgeDir();\n\n // If no knowledge dir, return empty knowledge and suggest initialization\n if (!knowledgeDir) {\n if (!isTestEnvironment() && process.env.REYGENT_DEBUG !== 'knowledge') {\n console.warn(chalk.yellow(\"⚠ No knowledge directory found. Run 'reygent init' to create .reygent/knowledge/\"));\n }\n return {\n agentTips: \"\",\n commonFailures: \"\",\n successPatterns: \"\",\n projectConventions: \"\",\n entriesLoaded: [],\n };\n }\n\n if (!existsSync(knowledgeDir)) {\n return {\n agentTips: \"\",\n commonFailures: \"\",\n successPatterns: \"\",\n projectConventions: \"\",\n entriesLoaded: [],\n };\n }\n\n const entriesLoaded: string[] = [];\n\n // Load agent-specific tips (always relevant)\n const agentTipsPath = join(knowledgeDir, \"agents\", `${agentName}.md`);\n const agentTips = readMarkdown(agentTipsPath);\n if (agentTips) {\n const entries = parseMarkdownEntries(agentTips, agentTipsPath);\n entriesLoaded.push(...entries.map((e) => `${agentName}:${e.id}`));\n }\n\n // Load stage-relevant failures (filter by agent)\n const failuresPath = join(knowledgeDir, \"common-failures.md\");\n const allFailures = readMarkdown(failuresPath);\n const relevantFailures = filterByAgent(allFailures, agentName, failuresPath);\n if (relevantFailures) {\n const entries = parseMarkdownEntries(relevantFailures, failuresPath);\n entriesLoaded.push(...entries.map((e) => `failures:${e.id}`));\n }\n\n // Load recent success patterns (last 30 days)\n const patternsPath = join(knowledgeDir, \"success-patterns.md\");\n const allPatterns = readMarkdown(patternsPath);\n const recentPatterns = filterByRecency(allPatterns, patternsPath, 30);\n if (recentPatterns) {\n const entries = parseMarkdownEntries(recentPatterns, patternsPath);\n entriesLoaded.push(...entries.map((e) => `patterns:${e.id}`));\n }\n\n // Load project conventions (always relevant)\n const conventionsPath = join(knowledgeDir, \"project-conventions.md\");\n const projectConventions = readMarkdown(conventionsPath);\n if (projectConventions) {\n const entries = parseMarkdownEntries(projectConventions, conventionsPath);\n entriesLoaded.push(...entries.map((e) => `conventions:${e.id}`));\n }\n\n return {\n agentTips,\n commonFailures: relevantFailures,\n successPatterns: recentPatterns,\n projectConventions,\n entriesLoaded,\n };\n}\n\n/**\n * List all knowledge files in the knowledge directory.\n * Returns array of relative paths (e.g., \"common-failures.md\", \"agents/dev.md\").\n */\nexport function listKnowledgeFiles(): string[] {\n const knowledgeDir = findKnowledgeDir();\n if (!knowledgeDir || !existsSync(knowledgeDir)) return [];\n\n const files: string[] = [];\n\n function scan(dir: string, prefix: string = \"\") {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n const fullPath = join(dir, entry);\n const stat = statSync(fullPath);\n const relativePath = prefix ? `${prefix}/${entry}` : entry;\n\n if (stat.isDirectory()) {\n scan(fullPath, relativePath);\n } else if (stat.isFile() && entry.endsWith(\".md\")) {\n files.push(relativePath);\n }\n }\n }\n\n scan(knowledgeDir);\n return files.sort();\n}\n\n/**\n * Search knowledge files for a query string.\n * Returns array of matching entries with file path and excerpt.\n */\nexport interface SearchResult {\n file: string;\n entry: KnowledgeEntry;\n excerpt: string; // snippet showing match context\n}\n\nexport function searchKnowledge(query: string): SearchResult[] {\n const knowledgeDir = findKnowledgeDir();\n if (!knowledgeDir || !existsSync(knowledgeDir)) return [];\n\n const files = listKnowledgeFiles();\n const results: SearchResult[] = [];\n const queryLower = query.toLowerCase();\n\n for (const file of files) {\n const filePath = join(knowledgeDir, file);\n const content = readMarkdown(filePath);\n const entries = parseMarkdownEntries(content, filePath);\n\n for (const entry of entries) {\n const titleMatch = entry.title.toLowerCase().includes(queryLower);\n const contentMatch = entry.content.toLowerCase().includes(queryLower);\n\n if (titleMatch || contentMatch) {\n // Extract excerpt (50 chars before and after match)\n const matchIndex = entry.content.toLowerCase().indexOf(queryLower);\n const start = Math.max(0, matchIndex - 50);\n const end = Math.min(entry.content.length, matchIndex + query.length + 50);\n const excerpt = \"...\" + entry.content.slice(start, end) + \"...\";\n\n results.push({ file, entry, excerpt });\n }\n }\n }\n\n return results;\n}\n","/**\n * Test environment detection utility.\n * Provides a single source of truth for checking if code is running in a test environment.\n */\n\n/**\n * Check if code is running in a test environment (vitest, jest, etc).\n *\n * Uses multiple signals:\n * - NODE_ENV === 'test' (common convention)\n * - VITEST === 'true' (vitest-specific)\n *\n * Note: We use process.env string checks instead of import.meta.env because:\n * 1. NODE_ENV is a runtime environment variable, not a build-time constant\n * 2. Test runners (vitest) set these at runtime, not during bundling\n * 3. import.meta.env is for Vite/bundler build-time constants\n */\nexport function isTestEnvironment(): boolean {\n return process.env.NODE_ENV === 'test' || process.env.VITEST === 'true';\n}\n","import { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { isDebug } from \"./debug.js\";\n\nexport interface ErrorTaskOptions {\n agent?: string;\n errorMessage?: string;\n apiErrorStatus?: number;\n}\n\n/**\n * Emit ERROR_TASK event to chesstrace if available.\n * Common pattern extracted from generate-spec.ts, planner.ts, implement.ts, etc.\n */\nexport function emitErrorTask(\n message: string,\n stage: string,\n options?: ErrorTaskOptions,\n): void {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message,\n stage,\n ...(options?.agent && { agent: options.agent }),\n ...(options?.errorMessage && { errorMessage: options.errorMessage }),\n ...(options?.apiErrorStatus && { apiErrorStatus: options.apiErrorStatus }),\n });\n } catch (err) {\n // Swallow emit errors to prevent telemetry from breaking main logic\n // Log to stderr in debug mode to help diagnose broken telemetry backends\n if (isDebug()) {\n const errMsg = err instanceof Error ? err.message : String(err);\n console.error(`[DEBUG] Telemetry emit failed (ERROR_TASK): ${errMsg}`);\n }\n }\n }\n}\n","import { getProvider } from \"./providers/index.js\";\nimport { resolveModel, resolveProvider } from \"./model.js\";\nimport { TaskError } from \"./task.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { loadKnowledge } from \"./knowledge/loader.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\n/**\n * Result returned by provider adapter spawn() method.\n * See Provider Adapter Contract in CLAUDE.md for full details.\n */\nexport interface SpawnResult {\n /** Agent output text (JSON, markdown, or plain text depending on agent) */\n stdout: string;\n /** Exit code: 0 for success, non-zero for failure */\n exitCode: number;\n /** Optional cost/token telemetry for usage tracking */\n usage?: UsageInfo;\n /** Clean error message from provider API (e.g., \"Model not available\"). Only present on errors. */\n errorMessage?: string;\n /** HTTP status code from API error (e.g., 404, 401, 429). Only present on API errors. */\n apiErrorStatus?: number;\n}\n\n/**\n * Check if model name looks malformed (obvious user input error).\n * Returns true if model is clearly invalid, false if it could be a valid custom model.\n */\nfunction looksLikeMalformedModel(model?: string): boolean {\n if (!model) return false;\n // Obvious signs of malformation: empty after trim, contains spaces, starts/ends with special chars\n const trimmed = model.trim();\n if (trimmed.length === 0) return true;\n if (/\\s/.test(trimmed)) return true;\n if (/^[^a-zA-Z0-9]|[^a-zA-Z0-9]$/.test(trimmed)) return true;\n // Very short model names (< 3 chars) are likely typos\n if (trimmed.length < 3) return true;\n return false;\n}\n\n/**\n * Build a detail string from a SpawnResult for error messages.\n * Includes errorMessage from the provider and raw stdout as fallback.\n */\nexport function formatExitDetail(result: SpawnResult, model?: string): string {\n if (result.errorMessage) {\n const status = result.apiErrorStatus ? ` (HTTP ${result.apiErrorStatus})` : \"\";\n let detail = `\\n ${result.errorMessage}${status}`;\n // Only show model selection tip if:\n // 1. It's a 404 error with \"not available\" pattern AND\n // 2. Model name looks malformed (obvious typo/error)\n // This avoids confusing users who intentionally use custom models not yet synced by provider\n if (result.apiErrorStatus === 404 && /not available/i.test(result.errorMessage) && looksLikeMalformedModel(model)) {\n detail += `\\n Tip: edit .reygent/config.json \"model\" field, or run \\`reygent config\\` to pick a supported model.`;\n }\n return detail;\n }\n const trimmed = result.stdout.trim();\n if (!trimmed) return \"\";\n const truncated = trimmed.slice(0, 500);\n const suffix = trimmed.length > 500 ? \"...\" : \"\";\n return `\\n ${truncated}${suffix}`;\n}\n\nexport interface SpawnOptions {\n quiet?: boolean;\n autoApprove?: boolean;\n provider?: string;\n model?: string;\n systemPrompt?: string;\n onActivity?: (event: ActivityEvent) => void;\n stage?: string;\n}\n\n/**\n * Spawns an agent in stream mode with a single prompt.\n * Interactive mode (via spawnInteractive) does not support onActivity\n * since it's used for terminal sessions where live status is not applicable.\n */\nexport async function spawnAgentStream(\n name: string,\n prompt: string,\n timeoutMs: number,\n options?: SpawnOptions,\n): Promise<SpawnResult> {\n const providerName = options?.provider ?? resolveProvider();\n const adapter = getProvider(providerName);\n const chesstrace = getChesstrace();\n\n const { available, reason } = await adapter.isAvailable();\n if (!available) {\n // Emit error.provider and error.task before throwing\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PROVIDER, {\n provider: providerName,\n reason,\n });\n }\n emitErrorTask(\n `Provider \"${providerName}\" is not available: ${reason}`,\n options?.stage ?? \"spawn\",\n { agent: name },\n );\n throw new TaskError(`Provider \"${providerName}\" is not available: ${reason}`);\n }\n\n const modelId = options?.model ?? await resolveModel(providerName);\n const startTime = Date.now();\n\n // Emit agent.spawn event before spawning\n if (chesstrace) {\n chesstrace.emit(Events.AGENT_SPAWN, {\n agent: name,\n provider: providerName,\n model: modelId,\n stage: options?.stage,\n });\n }\n\n // Load knowledge for agent\n const knowledge = await loadKnowledge(name, options?.stage);\n\n // Inject knowledge into system prompt if any exists\n let enhancedSystemPrompt = options?.systemPrompt;\n if (knowledge.entriesLoaded.length > 0) {\n const knowledgeSections: string[] = [];\n\n if (knowledge.commonFailures) {\n knowledgeSections.push(`### Common Failures to Avoid\\n${knowledge.commonFailures}`);\n }\n if (knowledge.successPatterns) {\n knowledgeSections.push(`### Success Patterns to Follow\\n${knowledge.successPatterns}`);\n }\n if (knowledge.agentTips) {\n knowledgeSections.push(`### Agent-Specific Tips (${name})\\n${knowledge.agentTips}`);\n }\n if (knowledge.projectConventions) {\n knowledgeSections.push(`### Project Conventions\\n${knowledge.projectConventions}`);\n }\n\n if (knowledgeSections.length > 0) {\n const knowledgeBlock = `\\n\\n## Project-Specific Knowledge\\n\\n${knowledgeSections.join(\"\\n\\n\")}\\n\\n---\\n\\n**Important**: Review above knowledge before proceeding. Avoid documented pitfalls.`;\n enhancedSystemPrompt = (enhancedSystemPrompt || \"\") + knowledgeBlock;\n }\n\n // Emit knowledge consultation event\n if (chesstrace) {\n chesstrace.emit(Events.KNOWLEDGE_CONSULTED, {\n agent: name,\n stage: options?.stage,\n entries: knowledge.entriesLoaded,\n entryCount: knowledge.entriesLoaded.length,\n });\n }\n }\n\n // Track timeout state to prevent duplicate events\n let timedOut = false;\n\n // Setup timeout handler\n const timeoutHandle = setTimeout(() => {\n timedOut = true;\n if (chesstrace) {\n chesstrace.emit(Events.AGENT_TIMEOUT, {\n agent: name,\n stage: options?.stage,\n timeoutMs,\n });\n }\n }, timeoutMs);\n\n try {\n const result = await adapter.spawn({\n prompt,\n systemPrompt: enhancedSystemPrompt,\n model: modelId,\n autoApprove: options?.autoApprove,\n quiet: options?.quiet,\n timeoutMs,\n agentName: name,\n onActivity: options?.onActivity,\n });\n\n // Clear timeout immediately after spawn completes\n clearTimeout(timeoutHandle);\n\n // Only emit complete if timeout didn't fire\n if (!timedOut && chesstrace) {\n const duration = Date.now() - startTime;\n chesstrace.emit(Events.AGENT_COMPLETE, {\n agent: name,\n stage: options?.stage,\n exitCode: result.exitCode,\n duration,\n success: result.exitCode === 0,\n });\n }\n\n return result;\n } catch (err) {\n // Clear timeout immediately\n clearTimeout(timeoutHandle);\n\n // Only emit complete if timeout didn't fire\n if (!timedOut && chesstrace) {\n const duration = Date.now() - startTime;\n chesstrace.emit(Events.AGENT_COMPLETE, {\n agent: name,\n stage: options?.stage,\n exitCode: -1,\n duration,\n success: false,\n });\n }\n\n throw err;\n }\n}\n","import { getAgents } from \"./config.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type { PlannerOutput, PlannerClarification, PlannerResult } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport function extractJSON(text: string): string {\n const trimmed = text.trim();\n\n // Try exact match: entire string is a fenced block\n const exact = trimmed.match(/^```(?:json)?\\s*\\n([\\s\\S]*?)\\n```$/);\n if (exact) return exact[1];\n\n // Try embedded fence: find last ```json ... ``` block in output\n const fences = [...trimmed.matchAll(/```(?:json)?\\s*\\n([\\s\\S]*?)\\n```/g)];\n if (fences.length > 0) return fences[fences.length - 1][1];\n\n // Try raw JSON object: find last { ... } block\n const lastBrace = trimmed.lastIndexOf(\"}\");\n if (lastBrace !== -1) {\n // Walk backwards to find matching opening brace\n let depth = 0;\n for (let i = lastBrace; i >= 0; i--) {\n if (trimmed[i] === \"}\") depth++;\n if (trimmed[i] === \"{\") depth--;\n if (depth === 0) return trimmed.slice(i, lastBrace + 1);\n }\n }\n\n return trimmed;\n}\n\nexport interface PlannerOptions {\n makeAssumptions?: boolean;\n onActivity?: (event: ActivityEvent) => void;\n}\n\nfunction buildPrompt(spec: SpecPayload, previousAnswers?: string, options?: PlannerOptions): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let clarificationContext = \"\";\n if (previousAnswers) {\n clarificationContext = `\n\n## Previous Clarifications\n\n${previousAnswers}\n\nUse these clarifications to inform your plan.`;\n }\n\n const assumptionMode = options?.makeAssumptions === true;\n const clarificationInstructions = assumptionMode\n ? `\nIMPORTANT: Do NOT ask for clarification. If the spec is ambiguous or missing design decisions, make reasonable assumptions based on industry best practices and common patterns. Document your assumptions in the constraints field.`\n : `\nIMPORTANT: If spec is ambiguous or missing key design decisions, prefer \"needsClarification\" over hard failure. Ask specific questions about:\n- Authentication/authorization approach\n- Data storage/persistence strategy\n- API design decisions (REST vs GraphQL, pagination, filtering)\n- Error handling patterns\n- Scalability/performance requirements\n- Integration points with existing systems`;\n\n return `${systemPrompt}\n\n---\n\nBelow is the raw spec to analyse. Return ONLY valid JSON matching one of three shapes:\n\n**Valid spec (can create plan):**\n\\`\\`\\`json\n{ \"valid\": true, \"goals\": [\"...\"], \"tasks\": [\"...\"], \"constraints\": [\"...\"], \"dod\": [\"...\"] }\n\\`\\`\\`\n\n**Needs clarification (spec ambiguous or missing design decisions):**\n\\`\\`\\`json\n{ \"valid\": false, \"needsClarification\": true, \"questions\": [\"What auth method?\", \"Support pagination?\"] }\n\\`\\`\\`\n\n**Invalid spec (fundamental issues, cannot proceed):**\n\\`\\`\\`json\n{ \"valid\": false, \"errors\": [\"...\"] }\n\\`\\`\\`\n${clarificationInstructions}\n\nEach array must contain at least one non-empty string. Do not include any text outside the JSON object.\n\n---\n\n**Spec title:** ${spec.title}\n\n**Spec content:**\n${spec.content}${clarificationContext}`;\n}\n\nfunction isNonEmptyStringArray(value: unknown): value is string[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n value.every((item) => typeof item === \"string\" && item.trim().length > 0)\n );\n}\n\nexport async function runPlanner(\n spec: SpecPayload,\n previousAnswers?: string,\n options?: PlannerOptions,\n): Promise<{ result: PlannerResult; usage?: UsageInfo }> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildPrompt(spec, previousAnswers, options);\n const spawnResult = await spawnAgentStream(\"planner\", prompt, 300_000, { quiet: true, onActivity: options?.onActivity, provider: plannerAgent?.provider, model: plannerAgent?.model });\n const { stdout: raw, exitCode, usage, errorMessage, apiErrorStatus } = spawnResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(spawnResult, plannerAgent?.model);\n emitErrorTask(\n `Planner: agent exited with code ${exitCode}${detail}`,\n \"plan\",\n { agent: \"planner\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`Planner: agent exited with code ${exitCode}${detail}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(raw));\n } catch (err) {\n // Emit error.parse before throwing\n const cleaned = extractJSON(raw);\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"planner\",\n expectedFormat: 'JSON object with valid/goals/tasks/constraints/dod or needsClarification/questions',\n received: cleaned.slice(0, 500),\n });\n }\n throw new TaskError(\"Planner: failed to parse result as JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (obj.valid === false) {\n // Check if needs clarification\n if (obj.needsClarification === true && Array.isArray(obj.questions)) {\n const questions = (obj.questions as unknown[]).filter(\n (q) => typeof q === \"string\" && q.trim().length > 0,\n ) as string[];\n\n if (questions.length > 0) {\n return { result: { needsClarification: true, questions }, usage };\n }\n }\n\n // Hard failure\n const errors = Array.isArray(obj.errors)\n ? (obj.errors as string[]).join(\"\\n - \")\n : \"unknown validation error\";\n emitErrorTask(\n `Planner: spec validation failed:\\n - ${errors}`,\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n `Planner: spec validation failed:\\n - ${errors}`,\n );\n }\n\n if (obj.valid !== true) {\n emitErrorTask(\n \"Planner: unexpected response — missing 'valid' field\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n \"Planner: unexpected response — missing 'valid' field\",\n );\n }\n\n const { goals, tasks, constraints, dod } = obj;\n\n const chesstrace = getChesstrace();\n if (!isNonEmptyStringArray(goals)) {\n emitErrorTask(\n \"Planner: 'goals' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'goals' must be a non-empty string array\");\n }\n if (!isNonEmptyStringArray(tasks)) {\n emitErrorTask(\n \"Planner: 'tasks' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'tasks' must be a non-empty string array\");\n }\n if (!isNonEmptyStringArray(constraints)) {\n emitErrorTask(\n \"Planner: 'constraints' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\n \"Planner: 'constraints' must be a non-empty string array\",\n );\n }\n if (!isNonEmptyStringArray(dod)) {\n emitErrorTask(\n \"Planner: 'dod' must be a non-empty string array\",\n \"plan\",\n { agent: \"planner\" },\n );\n throw new TaskError(\"Planner: 'dod' must be a non-empty string array\");\n }\n\n return { result: { goals, tasks, constraints, dod }, usage };\n}\n","import { getAgents } from \"./config.js\";\nimport { isDebug } from \"./debug.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport { TaskError } from \"./task.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport interface ClarificationResult {\n needsClarification: true;\n questions: string[];\n}\n\nexport interface ReadyResult {\n ready: true;\n}\n\nexport type ClarificationResponse = ClarificationResult | ReadyResult;\n\nfunction buildClarificationPrompt(description: string, previousAnswers?: string): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let answersContext = \"\";\n if (previousAnswers) {\n answersContext = `\n\n## Previous Clarifications\n\n${previousAnswers}\n\nConsider these answers. If you still have unresolved questions, ask them. Otherwise return ready.`;\n }\n\n return `${systemPrompt}\n\n---\n\nYou are preparing to generate a detailed markdown spec from a short description. Before generating, decide if you need clarifying questions.\n\nReturn ONLY valid JSON matching one of two shapes:\n\n**No questions needed (description is clear enough):**\n\\`\\`\\`json\n{ \"ready\": true }\n\\`\\`\\`\n\n**Need more information:**\n\\`\\`\\`json\n{ \"needsClarification\": true, \"questions\": [\"What authentication method?\", \"Should it support pagination?\"] }\n\\`\\`\\`\n\nAsk about things like:\n- Target users and use cases\n- Technical constraints or preferences\n- Integration points with existing systems\n- Scale and performance requirements\n- Authentication/authorization needs\n- Error handling expectations\n\nKeep questions specific and actionable (max 5). Do not include any text outside the JSON object.\n\n---\n\n**Description:** ${description}${answersContext}`;\n}\n\nfunction buildGeneratePrompt(description: string, clarificationAnswers?: string): string {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const systemPrompt = plannerAgent?.systemPrompt ?? \"\";\n\n let answersContext = \"\";\n if (clarificationAnswers) {\n answersContext = `\n\n## Clarification Answers\n\n${clarificationAnswers}\n\nUse these answers to make the spec more precise and targeted.`;\n }\n\n return `${systemPrompt}\n\n---\n\nYou are generating a full markdown spec from a short description. Output ONLY the raw markdown content (no fences, no wrapper). The spec must include:\n\n- A top-level heading (\\`# Title\\`)\n- An **Overview** section explaining the feature\n- A **Requirements** section with a bulleted list\n- An **Acceptance Criteria** section with a bulleted list\n- A **Constraints** section noting any technical or process constraints\n\nBe specific and actionable. Expand the description into concrete requirements that a development team could implement without further clarification.\n\n---\n\n**Description:** ${description}${answersContext}`;\n}\n\nexport async function runClarification(\n description: string,\n previousAnswers?: string,\n onActivity?: (event: ActivityEvent) => void,\n): Promise<ClarificationResponse> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildClarificationPrompt(description, previousAnswers);\n const clarifyResult = await spawnAgentStream(\"generate-spec\", prompt, 120_000, { quiet: true, onActivity });\n const { stdout: raw, exitCode, errorMessage, apiErrorStatus } = clarifyResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(clarifyResult, plannerAgent?.model);\n emitErrorTask(\n `generate-spec: agent exited with code ${exitCode}${detail}`,\n \"clarification\",\n { agent: \"generate-spec\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`generate-spec: agent exited with code ${exitCode}${detail}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(raw));\n } catch {\n throw new TaskError(\"generate-spec: failed to parse clarification response as JSON\");\n }\n\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n if (isDebug()) {\n console.error(\"Clarification response malformed (not an object), falling back to ready. Raw:\", raw);\n }\n return { ready: true };\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (obj.ready === true) {\n return { ready: true };\n }\n\n if (obj.needsClarification === true && Array.isArray(obj.questions)) {\n const questions = (obj.questions as unknown[]).filter(\n (q) => typeof q === \"string\" && q.trim().length > 0,\n ) as string[];\n\n if (questions.length > 0) {\n return { needsClarification: true, questions };\n }\n }\n\n // Default to ready if response doesn't match expected shapes\n if (isDebug()) {\n console.error(\"Clarification response didn't match expected shape, falling back to ready. Parsed:\", parsed);\n }\n return { ready: true };\n}\n\nexport async function generateSpec(\n description: string,\n clarificationAnswers?: string,\n onActivity?: (event: ActivityEvent) => void,\n): Promise<string> {\n const agents = getAgents();\n const plannerAgent = agents.find((a) => a.name === \"planner\");\n const prompt = buildGeneratePrompt(description, clarificationAnswers);\n const specResult = await spawnAgentStream(\"generate-spec\", prompt, 120_000, { onActivity });\n const { stdout, exitCode, errorMessage, apiErrorStatus } = specResult;\n\n if (exitCode !== 0) {\n const detail = formatExitDetail(specResult, plannerAgent?.model);\n emitErrorTask(\n `generate-spec: agent exited with code ${exitCode}${detail}`,\n \"generate\",\n { agent: \"generate-spec\", errorMessage, apiErrorStatus },\n );\n throw new TaskError(`generate-spec: agent exited with code ${exitCode}${detail}`);\n }\n\n if (!stdout) {\n throw new TaskError(\"generate-spec: empty result from agent\");\n }\n\n return stdout;\n}\n","import chalk from \"chalk\";\nimport ora from \"ora\";\nimport { killAllChildrenProcesses } from \"./child-registry.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { resetTerminalForInput } from \"./terminal-reset.js\";\n\nexport type { ActivityEvent };\n\nconst TRACK_LENGTH = 4;\n\nconst PAW_POSITIONS = [0, 1, 2, 3, 2, 1];\n\n// Ref-counting for SIGINT handlers to prevent multiple instances racing\nlet sigintHandlerCount = 0;\nlet globalSigintHandler: (() => void) | null = null;\n\nexport function formatElapsed(ms: number): string {\n const totalSeconds = Math.floor(ms / 1000);\n if (totalSeconds < 60) return `${totalSeconds}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, \"0\")}s`;\n const hours = Math.floor(minutes / 60);\n const remainMinutes = minutes % 60;\n return `${hours}h ${String(remainMinutes).padStart(2, \"0\")}m`;\n}\n\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[\\d+m/g, \"\");\n}\n\nfunction truncateToWidth(text: string, maxWidth: number): string {\n const visible = stripAnsi(text);\n if (visible.length <= maxWidth) return text;\n\n // Truncate visible portion and append ellipsis\n const truncated = visible.slice(0, maxWidth - 1) + \"…\";\n\n // Re-apply original color to truncated text\n // Simple heuristic: if original text started with ANSI, wrap truncated in same\n const ansiMatch = text.match(/^(\\x1b\\[\\d+m)/);\n if (ansiMatch) {\n return ansiMatch[1] + truncated + \"\\x1b[0m\";\n }\n return truncated;\n}\n\nexport function buildAnimationFrame(\n position: number,\n label: string,\n elapsed: string,\n lastActivity?: ActivityEvent,\n): string {\n const track = Array.from({ length: TRACK_LENGTH }, (_, i) =>\n i === position ? chalk.yellowBright(\"🐾\") : chalk.gray(\"·\"),\n ).join(\" \");\n\n const mainLine = `${track} ${chalk.blue(label)} ${chalk.gray(elapsed)}`;\n\n if (lastActivity) {\n const parts = [lastActivity.agent];\n if (lastActivity.tool) parts.push(lastActivity.tool);\n if (lastActivity.detail) parts.push(lastActivity.detail.replace(/[\\r\\n]+/g, \" \"));\n const activityText = chalk.cyan(parts.join(\" → \"));\n\n // Combine on single line with separator to prevent cursor misalignment\n const terminalWidth = process.stdout.columns || 120;\n const separator = chalk.gray(\" | \");\n const combined = `${mainLine}${separator}${activityText}`;\n\n // Truncate if combined line exceeds terminal width\n return truncateToWidth(combined, terminalWidth - 2);\n }\n\n return mainLine;\n}\n\nexport interface LiveStatus {\n onActivity: (event: ActivityEvent) => void;\n succeed: (msg: string) => void;\n fail: (msg: string) => void;\n warn: (msg: string) => void;\n info: (msg: string) => void;\n stop: () => void;\n start: () => void;\n}\n\nexport function createLiveStatus(label: string): LiveStatus {\n const spinner = ora({\n spinner: { frames: [\"\"], interval: 200 },\n text: \"\",\n discardStdin: false,\n }).start();\n\n let frameIndex = 0;\n let lastActivity: ActivityEvent | undefined;\n const startTime = Date.now();\n\n // Debounce activity events to max 5 Hz (200ms)\n let lastActivityTime = 0;\n const MIN_ACTIVITY_INTERVAL = 200;\n\n function render() {\n const pos = PAW_POSITIONS[frameIndex % PAW_POSITIONS.length];\n const elapsed = formatElapsed(Date.now() - startTime);\n spinner.text = buildAnimationFrame(pos, label, elapsed, lastActivity);\n }\n\n render();\n\n let interval: ReturnType<typeof setInterval> | null = null;\n\n function createInterval() {\n // Guard against double creation\n if (interval) return interval;\n\n const id = setInterval(() => {\n frameIndex++;\n render();\n }, 200);\n id.unref();\n return id;\n }\n\n interval = createInterval();\n\n function cleanup() {\n if (interval) {\n clearInterval(interval);\n interval = null;\n }\n\n // Decrement ref count and remove global handler if last instance\n if (sigintHandlerCount > 0) {\n sigintHandlerCount--;\n if (sigintHandlerCount === 0 && globalSigintHandler) {\n process.removeListener(\"SIGINT\", globalSigintHandler);\n globalSigintHandler = null;\n }\n }\n }\n\n function onSigInt() {\n cleanup();\n killAllChildrenProcesses();\n spinner.stop();\n process.exit(130);\n }\n\n // Install global SIGINT handler with ref-counting\n if (!globalSigintHandler) {\n globalSigintHandler = onSigInt;\n process.on(\"SIGINT\", globalSigintHandler);\n }\n sigintHandlerCount++;\n\n return {\n onActivity(event: ActivityEvent) {\n // Debounce to prevent spam from high-frequency tools\n const now = Date.now();\n if (now - lastActivityTime < MIN_ACTIVITY_INTERVAL) {\n // Update lastActivity but don't re-render yet\n lastActivity = {\n ...event,\n detail: event.detail?.slice(0, 80), // Defensive truncation\n };\n return;\n }\n\n lastActivityTime = now;\n lastActivity = {\n ...event,\n detail: event.detail?.slice(0, 80), // Cap detail length\n };\n render();\n },\n succeed(msg: string) {\n cleanup();\n spinner.succeed(msg);\n resetTerminalForInput();\n },\n fail(msg: string) {\n cleanup();\n spinner.fail(msg);\n resetTerminalForInput();\n },\n warn(msg: string) {\n cleanup();\n spinner.warn(msg);\n resetTerminalForInput();\n },\n info(msg: string) {\n cleanup();\n spinner.info(msg);\n resetTerminalForInput();\n },\n stop() {\n cleanup();\n spinner.stop();\n resetTerminalForInput();\n },\n start() {\n spinner.start();\n if (!interval) {\n interval = createInterval();\n }\n\n // Re-increment ref count when restarting\n if (globalSigintHandler) {\n sigintHandlerCount++;\n } else {\n globalSigintHandler = onSigInt;\n process.on(\"SIGINT\", globalSigintHandler);\n sigintHandlerCount++;\n }\n\n render();\n },\n };\n}\n","/** Strip ANSI escape codes for accurate visual length measurement. */\nfunction stripAnsi(str: string): string {\n // eslint-disable-next-line no-control-regex\n return str.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n}\n\n/**\n * Word-wrap text to fit terminal width, preserving indentation on continuation lines.\n *\n * @param text Text to wrap (may contain ANSI codes)\n * @param indent Number of columns reserved for the prefix on continuation lines\n * @param maxWidth Terminal width (columns)\n * @param continuationPrefix Optional string to prepend to continuation lines instead of spaces\n */\nexport function wrapText(text: string, indent: number, maxWidth: number, continuationPrefix?: string): string {\n // Handle edge cases\n if (!text || text.trim().length === 0) return text || \"\";\n if (maxWidth <= 0) return text;\n if (indent < 0) indent = 0;\n\n const available = maxWidth - indent;\n\n // If available width is too narrow, force wrap anyway (don't return original)\n // Otherwise check if text fits without wrapping\n if (available > 20 && stripAnsi(text).length <= available) return text;\n\n // Minimum available width to prevent pathological cases\n const minAvailable = Math.max(available, 10);\n\n const words = text.split(\" \");\n const wrappedLines: string[] = [];\n let currentLine = \"\";\n\n for (const word of words) {\n if (currentLine.length === 0) {\n currentLine = word;\n } else if (stripAnsi(currentLine).length + 1 + stripAnsi(word).length <= minAvailable) {\n currentLine += \" \" + word;\n } else {\n wrappedLines.push(currentLine);\n currentLine = word;\n }\n }\n if (currentLine) wrappedLines.push(currentLine);\n\n const pad = continuationPrefix ?? \" \".repeat(indent);\n return wrappedLines.join(\"\\n\" + pad);\n}\n","import chalk from \"chalk\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { ExitPromptError } from \"@inquirer/core\";\nimport { isDebug } from \"../debug.js\";\nimport { wrapText } from \"../format.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { loadSpec, SpecError, ISSUE_KEY_PATTERN } from \"../spec.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { runPlanner } from \"../planner.js\";\nimport { TaskError } from \"../task.js\";\nimport type { PlannerOutput } from \"../task.js\";\nimport type { SpecProvider } from \"../spec.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\n\nconst VALID_PROVIDERS: SpecProvider[] = [\"jira\", \"linear\", \"local\"];\n\ninterface SpecCommandOptions {\n clarify?: boolean;\n source?: string;\n}\n\n/**\n * Infer provider when unambiguous, or return undefined to trigger prompt.\n * Returns undefined only for ambiguous issue keys (e.g. ENG-123).\n */\nfunction inferProvider(source: string): SpecProvider | undefined {\n if (/^https:\\/\\/linear\\.app\\//.test(source)) {\n return \"linear\";\n }\n if (ISSUE_KEY_PATTERN.test(source)) {\n return undefined; // ambiguous — needs prompt\n }\n return \"local\"; // file path or anything else\n}\n\nexport async function specCommand(source: string, options: SpecCommandOptions): Promise<void> {\n return withTelemetry('spec', async () => {\n try {\n // Validate --source flag if given\n if (options.source !== undefined) {\n if (!VALID_PROVIDERS.includes(options.source as SpecProvider)) {\n console.log(\n chalk.red.bold(\"Error:\"),\n `Invalid source provider \"${options.source}\". Must be one of: ${VALID_PROVIDERS.join(\", \")}`,\n );\n process.exit(1);\n }\n }\n\n // Resolve provider: flag > inference > prompt\n let provider: SpecProvider | undefined = options.source as SpecProvider | undefined;\n\n // Validate source format matches explicit provider if given\n if (provider) {\n const hasMdExt = /\\.(md|markdown)$/i.test(source);\n const isLinearUrl = /^https:\\/\\/linear\\.app\\//.test(source);\n const isIssueKey = ISSUE_KEY_PATTERN.test(source);\n\n // Only warn for clear mismatches\n if (provider === \"local\" && isLinearUrl) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" is a Linear URL, but --source=local treats it as a file path.`,\n );\n } else if (provider === \"linear\" && hasMdExt) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" ends in .md/.markdown, but --source=linear treats it as a Linear issue ID.`,\n );\n } else if (provider === \"jira\" && hasMdExt) {\n console.log(\n chalk.yellow(\"Warning:\"),\n `Source \"${source}\" ends in .md/.markdown, but --source=jira treats it as a Jira issue key.`,\n );\n }\n }\n\n if (!provider) {\n provider = inferProvider(source);\n }\n\n if (!provider) {\n // Need to prompt — check for TTY\n if (!process.stdin.isTTY) {\n console.log(\n chalk.red.bold(\"Error:\"),\n `Cannot determine provider for \"${source}\" in non-interactive mode. Use --source <jira|linear|local>.`,\n );\n process.exit(1);\n }\n\n resetTerminalForInput();\n provider = await select<SpecProvider>({\n message: \"Which provider is this issue from?\",\n choices: [\n { name: \"Jira\", value: \"jira\" },\n { name: \"Linear\", value: \"linear\" },\n { name: \"Local file\", value: \"local\" },\n ],\n });\n }\n\n const spec = await loadSpec(source, provider);\n\n if (!options.clarify) {\n // Original behavior: just output spec JSON\n console.log(JSON.stringify(spec, null, 2));\n return;\n }\n\n // Run planner with clarification loop\n const status = createLiveStatus(\"running planner...\");\n\n let plan: PlannerOutput | null = null;\n let clarificationAnswers = \"\";\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!plan && attempts < maxAttempts) {\n attempts++;\n const { result } = await runPlanner(spec, clarificationAnswers, { onActivity: status.onActivity });\n\n if (\"needsClarification\" in result && result.needsClarification) {\n status.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\nPlanner needs clarification:\\n\"));\n\n const answers: string[] = [];\n\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n console.log(` [${i + 1}/${result.questions.length}] ${question}`);\n resetTerminalForInput();\n const answer = await pasteableInput({ message: \">\" });\n\n if (answer.toLowerCase() === \"abort\" || answer.toLowerCase() === \"cancel\") {\n throw new TaskError(\"Planner: clarification aborted by user\");\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n }\n clarificationAnswers = answers.join(\"\\n\\n\");\n console.log(chalk.blue(\"\\nRe-running planner with clarifications...\\n\"));\n status.start();\n } else {\n plan = result as PlannerOutput;\n }\n }\n\n if (!plan) {\n status.fail(chalk.red(\"Planner failed\"));\n throw new TaskError(`Planner: failed to create valid plan after ${maxAttempts} attempts`);\n }\n\n status.succeed(chalk.green(\"Plan created\"));\n\n const cols = process.stdout.columns || 80;\n console.log(chalk.cyan(\"\\nGoals:\"));\n for (const g of plan.goals) console.log(` ${chalk.gray(\"-\")} ${wrapText(g, 4, cols)}`);\n console.log(chalk.cyan(\"\\nTasks:\"));\n for (const t of plan.tasks) console.log(` ${chalk.gray(\"-\")} ${wrapText(t, 4, cols)}`);\n console.log(chalk.cyan(\"\\nConstraints:\"));\n for (const c of plan.constraints) console.log(` ${chalk.gray(\"-\")} ${wrapText(c, 4, cols)}`);\n console.log(chalk.cyan(\"\\nDefinition of Done:\"));\n for (const d of plan.dod) console.log(` ${chalk.gray(\"-\")} ${wrapText(d, 4, cols)}`);\n } catch (err) {\n if (err instanceof ExitPromptError) {\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n","/**\n * Custom input prompt based on @inquirer/input v5.0.11.\n *\n * Fixes two cursor-tracking bugs in @inquirer/core's ScreenManager:\n *\n * 1. `checkCursorPos()` only corrects the column on keypress, never the row.\n * When arrow keys / Home / End don't change `rl.line`, `useState` skips\n * the re-render and the cursor stays on the wrong visual row.\n * Fix: track `rl.cursor` in a separate `useState`. When cursor position\n * changes, `useState` sees a new value → triggers `handleChange()` →\n * full `render()` → correct row+column positioning.\n *\n * 2. When prompt + input exceeds terminal width, `breakLines()` inserts `\\n`\n * at the width boundary. `screen.render()` then calculates the prompt via\n * `lastLine(content)`, but if `rl.line` spans across the inserted `\\n`,\n * the prompt becomes shorter than `rl.line`, the `setPrompt()` call uses\n * an empty string, and `getCursorPos()` returns wrong column values.\n * Fix: render user input on a separate line from the prompt message during\n * active editing, so `breakLines` never splits `rl.line` across lines.\n *\n * Also handles paste injection: when pasteState.pending is true,\n * the accumulated text is inserted directly into rl.line (bypassing\n * readline's per-character processing) and a single render fires.\n */\nimport {\n createPrompt,\n useState,\n useKeypress,\n useEffect,\n usePrefix,\n isBackspaceKey,\n isEnterKey,\n isTabKey,\n makeTheme,\n type Theme,\n} from \"@inquirer/core\";\nimport type { PartialDeep } from \"@inquirer/type\";\nimport { pasteState } from \"./paste-state.js\";\n\ntype InputTheme = {\n validationFailureMode: \"keep\" | \"clear\";\n};\n\ntype InputConfig = {\n message: string;\n default?: string;\n prefill?: \"tab\" | \"editable\";\n required?: boolean;\n transformer?: (value: string, opts: { isFinal: boolean }) => string;\n validate?: (value: string) => boolean | string | Promise<string | boolean>;\n theme?: PartialDeep<Theme<InputTheme>>;\n pattern?: RegExp;\n patternError?: string;\n};\n\nconst inputTheme: InputTheme = {\n validationFailureMode: \"keep\",\n};\n\nexport default createPrompt<string, InputConfig>((config, done) => {\n const { prefill = \"tab\" } = config;\n const theme = makeTheme(inputTheme, config.theme);\n const [status, setStatus] = useState<\"idle\" | \"loading\" | \"done\">(\"idle\");\n const [defaultValue, setDefaultValue] = useState<string>(\n String(config.default ?? \"\"),\n );\n const [errorMsg, setError] = useState<string | undefined>();\n const [value, setValue] = useState<string>(\"\");\n const [, setCursorPos] = useState<number>(0);\n const prefix = usePrefix({ status, theme });\n\n async function validate(val: string): Promise<true | string> {\n const { required, pattern, patternError = \"Invalid input\" } = config;\n if (required && !val) {\n return \"You must provide a value\";\n }\n if (pattern && !pattern.test(val)) {\n return patternError;\n }\n if (typeof config.validate === \"function\") {\n return (await config.validate(val)) || \"You must provide a valid value\";\n }\n return true;\n }\n\n useKeypress(async (key, rl) => {\n if (status !== \"idle\") {\n return;\n }\n\n // --- Paste injection: insert accumulated text into rl.line directly ---\n if (pasteState.pending) {\n const text = pasteState.text;\n pasteState.pending = false;\n pasteState.text = \"\";\n\n // Insert at current cursor position\n const before = rl.line.slice(0, rl.cursor);\n const after = rl.line.slice(rl.cursor);\n rl.line = before + text + after;\n rl.cursor = before.length + text.length;\n\n setDefaultValue(\"\");\n setValue(rl.line);\n setError(undefined);\n setCursorPos(rl.cursor);\n return;\n }\n\n if (isEnterKey(key)) {\n const answer = value || defaultValue;\n setStatus(\"loading\");\n const isValid = await validate(answer);\n if (isValid === true) {\n setValue(answer);\n setStatus(\"done\");\n done(answer);\n } else {\n if (theme.validationFailureMode === \"clear\") {\n setValue(\"\");\n } else {\n rl.write(value);\n }\n setError(isValid);\n setStatus(\"idle\");\n }\n } else if (isBackspaceKey(key) && !value) {\n setDefaultValue(\"\");\n } else if (isTabKey(key) && !value) {\n setDefaultValue(\"\");\n rl.clearLine(0);\n rl.write(defaultValue);\n setValue(defaultValue);\n } else {\n setValue(rl.line);\n setError(undefined);\n setCursorPos(rl.cursor); // force re-render on cursor movement\n }\n });\n\n useEffect((rl) => {\n if (prefill === \"editable\" && defaultValue) {\n rl.write(defaultValue);\n setValue(defaultValue);\n }\n }, []);\n\n const message = theme.style.message(config.message, status);\n let formattedValue = value;\n if (typeof config.transformer === \"function\") {\n formattedValue = config.transformer(value, { isFinal: status === \"done\" });\n } else if (status === \"done\") {\n formattedValue = theme.style.answer(value);\n }\n\n let defaultStr: string | undefined;\n if (defaultValue && status !== \"done\" && !value) {\n defaultStr = theme.style.defaultAnswer(defaultValue);\n }\n\n let error = \"\";\n if (errorMsg) {\n error = theme.style.error(errorMsg);\n }\n\n // When status is \"done\", render everything on one line (standard @inquirer\n // completion display — no cursor interaction, so wrapping is harmless).\n if (status === \"done\") {\n return [\n [prefix, message, defaultStr, formattedValue]\n .filter((v) => v !== undefined)\n .join(\" \"),\n error,\n ];\n }\n\n // During active editing, render input on its own line. This prevents\n // @inquirer/core's breakLines() from splitting rl.line across visual\n // lines, which would break screen.render()'s cursor positioning math\n // (see bug #2 in the file header).\n const promptLine = [prefix, message, defaultStr]\n .filter((v) => v !== undefined)\n .join(\" \");\n\n return [promptLine + \"\\n\" + formattedValue, error];\n});\n","/**\n * Shared paste state between pasteable-input and cursor-aware-input.\n *\n * pasteable-input accumulates pasted text here (bypassing readline).\n * cursor-aware-input checks `pending` on each keypress — when true,\n * it injects the text into rl.line directly and triggers one render.\n *\n * Separate module avoids circular dependency between the two.\n */\nexport const pasteState = {\n /** True when accumulated paste text is ready to be consumed. */\n pending: false,\n /** Accumulated paste content (newlines replaced with spaces). */\n text: \"\",\n};\n","import cursorAwareInput from \"./cursor-aware-input.js\";\nimport { pasteState } from \"./paste-state.js\";\n\nconst PASTE_START = \"\\x1b[200~\";\nconst PASTE_END = \"\\x1b[201~\";\nconst PASTE_BRACKET_ON = \"\\x1b[?2004h\";\nconst PASTE_BRACKET_OFF = \"\\x1b[?2004l\";\n\n/**\n * Paste-aware wrapper around cursor-aware input.\n *\n * Problem: readline treats every \\r / \\n as Enter (submit), and each\n * character triggers a separate keypress → re-render cycle. Pasting\n * text causes immediate submission (trailing newline) and visible\n * cursor jumping (N renders for N characters).\n *\n * Solution: enable terminal *bracketed paste mode* so the terminal\n * wraps pasted content in \\x1b[200~ … \\x1b[201~ markers. We patch\n * stdin.emit to intercept 'data' events. Instead of forwarding pasted\n * characters to readline (which would process them one-by-one), we\n * accumulate the text in a shared pasteState object. After the paste\n * ends we emit a single synthetic keypress; cursor-aware-input detects\n * the pending paste, injects the text into rl.line directly, and\n * triggers exactly one render. Zero intermediate redraws.\n */\nexport async function pasteableInput(\n config: Parameters<typeof cursorAwareInput>[0],\n context?: Parameters<typeof cursorAwareInput>[1],\n): Promise<string> {\n const stdin = process.stdin;\n let inPaste = false;\n let justPasted = false; // stays true for one chunk after paste ends\n\n // Enable bracketed paste mode\n if (stdin.isTTY) {\n process.stdout.write(PASTE_BRACKET_ON);\n }\n\n // Temporarily patch stdin.emit to intercept 'data' events for paste\n // handling while preserving all TTY properties for readline/inquirer.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const originalEmit = stdin.emit as (...args: any[]) => boolean;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function patchedEmit(this: typeof stdin, event: string | symbol, ...args: any[]): boolean {\n if (event === \"data\") {\n let chunk = args[0];\n let str: string = Buffer.isBuffer(chunk) ? chunk.toString(\"utf-8\") : String(chunk);\n const wasPasting = inPaste;\n const wasJustPasted = justPasted;\n justPasted = false;\n\n // Detect and strip paste-start marker\n const startIdx = str.indexOf(PASTE_START);\n if (startIdx !== -1) {\n inPaste = true;\n str = str.slice(0, startIdx) + str.slice(startIdx + PASTE_START.length);\n }\n\n // Detect and strip paste-end marker\n const endIdx = str.indexOf(PASTE_END);\n if (endIdx !== -1) {\n str = str.slice(0, endIdx) + str.slice(endIdx + PASTE_END.length);\n inPaste = false;\n justPasted = true;\n }\n\n // --- Paste content: accumulate, don't forward to readline ---\n if (wasPasting || startIdx !== -1) {\n str = str.replace(/\\r?\\n|\\r/g, \" \");\n pasteState.text += str;\n\n if (!inPaste) {\n // Paste complete — trim trailing whitespace from accumulated\n // text (clipboard often appends a newline → trailing space).\n pasteState.text = pasteState.text.trimEnd();\n pasteState.pending = true;\n\n // Emit synthetic keypress so cursor-aware-input's useKeypress\n // fires once, picks up the pending text, and renders.\n // Empty string → readline's _ttyWrite is a no-op.\n // checkCursorPos sees no change (rl.line hasn't changed yet).\n originalEmit.apply(this, [\"keypress\", \"\", { name: \"\" }]);\n }\n return false; // swallow data event — don't send to readline\n }\n\n // --- Straggling newline after paste-end (arrives in next chunk) ---\n if (wasJustPasted) {\n if (/^(\\r?\\n|\\r)+$/.test(str)) {\n return false; // swallow pure newline stragglers\n }\n // Non-newline content right after paste — fall through to normal\n }\n\n // --- Regular keystroke: forward unchanged ---\n if (str.length === 0) {\n return false;\n }\n args[0] = Buffer.from(str, \"utf-8\");\n }\n return originalEmit.apply(this, [event, ...args]);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stdin.emit = patchedEmit as any;\n\n try {\n return await cursorAwareInput(config, context);\n } finally {\n stdin.emit = originalEmit;\n if (stdin.isTTY) {\n process.stdout.write(PASTE_BRACKET_OFF);\n }\n inPaste = false;\n justPasted = false;\n pasteState.pending = false;\n pasteState.text = \"\";\n }\n}\n","import { createInterface } from \"node:readline\";\nimport { join } from \"node:path\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { isDebug } from \"../debug.js\";\nimport { wrapText } from \"../format.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { runUnitTestGate, runFunctionalTestGate } from \"../gate.js\";\nimport { runImplement } from \"../implement.js\";\nimport type { FailureContext } from \"../implement.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport { runPlanner } from \"../planner.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { runPRCreate } from \"../pr-create.js\";\nimport { normalizeType, detectTypeFromJiraIssueType, detectTypeFromLinearLabels, VALID_BRANCH_TYPES, type BranchType } from \"../branch-type.js\";\nimport { runPRReview, formatPRReviewTerminal, postPRReviewComment } from \"../pr-review.js\";\nimport { runSecurityReview, formatFindings } from \"../security-review.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { PIPELINE, TaskError } from \"../task.js\";\nimport type { Severity, StageResult, TaskContext, PlannerOutput } from \"../task.js\";\nimport { UsageTracker, printUsageSummary, printVerboseUsage } from \"../usage.js\";\nimport { Chesstrace, getChesstrace } from \"../chesstrace/index.js\";\nimport { Events, TelemetryLevel } from \"../chesstrace/events.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport { loadConfig } from \"../config.js\";\nimport { getTelemetryOverride, resolveTelemetryEnabled } from \"../telemetry-override.js\";\nimport { analyzeFailurePatterns, analyzeSuccessPatterns } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { findProjectRoot } from \"../project-detection.js\";\nimport { DualBackend } from \"../chesstrace/backends/dual.js\";\nimport { existsSync, mkdirSync } from \"node:fs\";\nimport { isTestEnvironment } from \"../test-env.js\";\nimport { promptForRetry } from \"../retry-prompt.js\";\n\nconst VALID_SEVERITIES = new Set<string>([\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"]);\n\n/**\n * Emit stage.end event with duration and success status\n * Also emits tool.summary if toolTracker provided\n *\n * Note: Empty summaries (no tool calls) emit tool.summary with empty toolCounts object.\n * This is acceptable behavior and tested in tool-tracking-integration.test.ts\n */\nfunction emitStageEnd(\n chesstrace: Chesstrace | null,\n stageName: string,\n stageStartTime: number,\n success: boolean,\n metadata?: { cost?: number; outputSummary?: string },\n toolTracker?: ToolTracker,\n): void {\n if (!chesstrace) return;\n try {\n // Emit tool.summary before stage end\n if (toolTracker) {\n const summary = toolTracker.getSummary();\n if (Object.keys(summary).length > 0) {\n chesstrace.emit(Events.TOOL_SUMMARY, {\n stage: stageName,\n toolCounts: summary,\n });\n }\n }\n\n chesstrace.emit(Events.PIPELINE_STAGE_END, {\n stage: stageName,\n success,\n durationMs: Date.now() - stageStartTime,\n ...(metadata && { metadata }),\n });\n } catch {\n // Swallow emit errors\n }\n}\n\n/**\n * Update knowledge base from recent telemetry data.\n * Extracts patterns from last 7 days and adds to knowledge files.\n * Runs silently - no output unless errors occur.\n *\n * Only updates if in a project (has .git, package.json, etc.).\n * Uses project root directory for knowledge files.\n */\nasync function updateKnowledgeFromTelemetry(): Promise<void> {\n try {\n // Check if in a project - skip if not\n const projectRoot = findProjectRoot(process.cwd());\n if (!projectRoot) {\n // Not in a project - skip knowledge update\n return;\n }\n\n const backend = new SqliteBackend(\"local\", `${projectRoot}/.reygent/chesstrace.db`);\n await backend.init();\n\n const since = Date.now() - 7 * 24 * 60 * 60 * 1000; // Last 7 days\n\n // Extract failure patterns\n const failurePatterns = analyzeFailurePatterns(backend, since);\n const topFailures = failurePatterns.slice(0, 3); // Top 3 only\n\n for (const pattern of topFailures) {\n for (const agent of pattern.agents) {\n try {\n await addFailureEntry(projectRoot, {\n issue: pattern.pattern,\n solution: \"Review telemetry for details\",\n agent: agent as any,\n });\n } catch {\n // Ignore duplicate entries\n }\n }\n }\n\n // Extract success patterns\n const successPatterns = analyzeSuccessPatterns(backend, since, 0.85);\n const topSuccess = successPatterns.slice(0, 3); // Top 3 only\n\n for (const pattern of topSuccess) {\n try {\n await addPatternEntry(projectRoot, {\n description: pattern.pattern,\n successRate: Math.round(pattern.successRate * 100),\n });\n } catch {\n // Ignore duplicate entries\n }\n }\n\n await backend.close();\n } catch (err) {\n // Silently fail - don't interrupt user workflow\n // Log for debugging if REYGENT_DEBUG=knowledge enabled\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'knowledge') {\n console.error('[debug:knowledge] updateKnowledgeFromTelemetry failed:', err instanceof Error ? err.message : String(err));\n }\n }\n}\n\n/**\n * Tool call tracking data structure\n */\ninterface ToolTracker {\n /** Map of agent -> tool -> count */\n counts: Map<string, Map<string, number>>;\n /** Record a tool invocation */\n record(agent: string, tool: string): void;\n /** Get summary of tool counts per agent */\n getSummary(): Record<string, Record<string, number>>;\n}\n\nfunction createToolTracker(): ToolTracker {\n const counts = new Map<string, Map<string, number>>();\n\n return {\n counts,\n record(agent: string, tool: string) {\n if (!counts.has(agent)) {\n counts.set(agent, new Map());\n }\n const agentMap = counts.get(agent)!;\n agentMap.set(tool, (agentMap.get(tool) ?? 0) + 1);\n },\n getSummary() {\n const summary: Record<string, Record<string, number>> = {};\n for (const [agent, toolMap] of counts) {\n summary[agent] = Object.fromEntries(toolMap);\n }\n return summary;\n },\n };\n}\n\n/**\n * Truncate string to max length for telemetry events.\n * Exported for use in tests to ensure consistent truncation behavior.\n */\nexport function truncateToolData(str: string | undefined, maxLen: number): string | undefined {\n if (!str) return undefined;\n if (str.length <= maxLen) return str;\n return str.slice(0, maxLen);\n}\n\n/**\n * Helper to merge agentOptions with onActivity callback from a LiveStatus instance.\n * Reduces boilerplate from repeated `{ ...agentOptions, onActivity: status.onActivity }` pattern.\n * Also wires tool invocation telemetry.\n */\nfunction withActivity(\n agentOptions: { autoApprove: boolean },\n status: { onActivity: (event: import(\"../live-status.js\").ActivityEvent) => void },\n toolTracker?: ToolTracker,\n): { autoApprove: boolean; onActivity: (event: import(\"../live-status.js\").ActivityEvent) => void } {\n return {\n ...agentOptions,\n onActivity: (event) => {\n // Call original live status handler\n status.onActivity(event);\n\n // Emit tool telemetry if tool present\n if (event.tool) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n // Standard level: tool.invoke with agent, tool, detail\n chesstrace.emit(Events.TOOL_INVOKE, {\n agent: event.agent,\n tool: event.tool,\n detail: event.detail,\n });\n\n // Verbose level: tool.invoke.full with truncated detail\n // Note: ActivityEvent doesn't carry input/output fields separately,\n // so detail field serves as proxy for tool parameters/results\n chesstrace.emit(Events.TOOL_INVOKE_FULL, {\n agent: event.agent,\n tool: event.tool,\n detail: truncateToolData(event.detail, 500),\n });\n } catch {\n // Swallow telemetry errors\n }\n }\n\n // Track tool count if tracker provided\n if (toolTracker) {\n toolTracker.record(event.agent, event.tool);\n }\n }\n },\n };\n}\n\ninterface RunOptions {\n spec?: string;\n type?: string;\n dryRun: boolean;\n securityThreshold: string;\n autoApprove: boolean;\n insecure: boolean;\n skipClarification: boolean;\n maxRetries: string;\n verbose: boolean;\n}\n\nconst MAX_TEST_OUTPUT_CHARS = 8000;\n\nfunction truncateForPrompt(output: string): string {\n if (output.length <= MAX_TEST_OUTPUT_CHARS) return output;\n const half = Math.floor(MAX_TEST_OUTPUT_CHARS / 2);\n return (\n output.slice(0, half) +\n \"\\n\\n... [truncated] ...\\n\\n\" +\n output.slice(-half)\n );\n}\n\ninterface RetryGateOptions {\n gateName: string;\n gateRunner: (attempt: number) => Promise<{ gate: import(\"../task.js\").GateResult; usage?: import(\"../usage.js\").UsageInfo }>;\n agentsToRun: Array<\"dev\" | \"qe\">;\n context: TaskContext;\n agentOptions: { autoApprove: boolean };\n maxRetries: number;\n autoApprove: boolean;\n stageName: string;\n tracker: UsageTracker;\n verbose: boolean;\n toolTracker: ToolTracker;\n}\n\nasync function retryGate(opts: RetryGateOptions): Promise<import(\"../task.js\").GateResult> {\n const { gateName, gateRunner, agentsToRun, context, agentOptions, maxRetries, autoApprove, stageName, tracker, verbose, toolTracker } = opts;\n\n let attempt = 0;\n\n // Retry loop - continue until test passes or user aborts\n while (true) {\n attempt++;\n const lastOutput = context.gates?.[gateName === \"unit tests\" ? \"unitTests\" : \"functionalTests\"]?.output ?? \"\";\n\n // Check if exceeded max retries or prompt user\n await promptForRetry({\n taskName: gateName,\n attempt,\n maxRetries,\n autoApprove,\n telemetry: {\n stageName,\n agentName: gateName === \"unit tests\" ? \"gate:unit-tests\" : \"gate:functional-tests\",\n },\n });\n\n // Emit gate.retry telemetry after user approves\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n const failureSnippet = lastOutput.length > 500\n ? lastOutput.slice(-500)\n : lastOutput;\n chesstrace.emit(Events.GATE_RETRY, {\n gateName,\n attempt,\n maxRetries,\n failureSnippet,\n });\n } catch (err) {\n if (verbose) {\n console.error(\"[telemetry]\", err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n const attemptDisplay = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n console.log(chalk.yellow(`\\nRetrying ${gateName} (attempt ${attemptDisplay})...`));\n\n const failureContext: FailureContext = {\n gateName,\n testOutput: truncateForPrompt(lastOutput),\n attempt,\n maxAttempts: maxRetries > 0 ? maxRetries : 0,\n };\n\n const status = createLiveStatus(`re-running ${agentsToRun.join(\" + \")} agent(s)...`);\n const { implement: retryResult, usages: retryUsages } = await runImplement(\n context.spec,\n context.plan!,\n withActivity(agentOptions, status, toolTracker),\n { failureContext, agentsToRun },\n );\n\n // Record retry implementation usage\n for (const u of retryUsages) {\n if (u.usage) tracker.record(u.agent, `${stageName}-retry`, u.usage);\n }\n\n // Merge results into context\n if (retryResult.dev && context.implement) {\n context.implement.dev = retryResult.dev;\n }\n if (retryResult.qe && context.implement) {\n context.implement.qe = retryResult.qe;\n }\n status.succeed(chalk.green(\"Retry implementation complete\"));\n\n // Re-run gate\n const retryStatus = createLiveStatus(`re-running ${gateName}...`);\n const { gate: gateResult, usage: gateUsage } = await gateRunner(attempt + 1);\n\n const gateAgentName =\n gateName === \"unit tests\" ? \"gate:unit-tests\" : \"gate:functional-tests\";\n if (gateUsage) tracker.record(gateAgentName, `${stageName}-retry`, gateUsage);\n\n if (!context.gates) context.gates = {};\n if (gateName === \"unit tests\") {\n context.gates.unitTests = gateResult;\n } else {\n context.gates.functionalTests = gateResult;\n }\n\n if (gateResult.passed) {\n retryStatus.succeed(chalk.green(`${gateName} PASSED on retry ${attempt}`));\n return gateResult;\n }\n\n const attemptDisplayFail = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n retryStatus.fail(chalk.red(`${gateName} FAILED (retry ${attemptDisplayFail})`));\n }\n}\n\nasync function promptLinearSpec(): Promise<string> {\n loadEnvFile();\n if (!process.env.LINEAR_API_KEY) {\n console.log(chalk.red.bold(\"Error:\"), \"LINEAR_API_KEY not set. Add it to your .env file.\");\n process.exit(1);\n }\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Linear issue URL or ID (e.g. ENG-123):\",\n validate: (v) => {\n const trimmed = v.trim();\n if (!trimmed) return \"Required\";\n if (/^https:\\/\\/linear\\.app\\/.+/.test(trimmed)) return true;\n if (/^[A-Z]+-\\d+$/i.test(trimmed)) return true;\n return \"Enter a Linear URL or issue ID (e.g. ENG-123)\";\n },\n });\n return value.trim();\n}\n\nasync function promptJiraSpec(): Promise<string> {\n loadEnvFile();\n const missing: string[] = [];\n if (!process.env.JIRA_URL) missing.push(\"JIRA_URL\");\n if (!process.env.JIRA_EMAIL) missing.push(\"JIRA_EMAIL\");\n if (!process.env.JIRA_API_TOKEN) missing.push(\"JIRA_API_TOKEN\");\n if (missing.length > 0) {\n console.log(chalk.red.bold(\"Error:\"), `Missing env vars: ${missing.join(\", \")}. Add them to your .env file.`);\n process.exit(1);\n }\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Jira issue key (e.g. PROJ-123):\",\n validate: (v) => {\n const trimmed = v.trim();\n if (!trimmed) return \"Required\";\n if (/^[A-Z]+-\\d+$/i.test(trimmed)) return true;\n return \"Enter a Jira issue key (e.g. PROJ-123)\";\n },\n });\n return value.trim();\n}\n\nasync function promptMarkdownSpec(): Promise<string> {\n resetTerminalForInput();\n const value = await pasteableInput({\n message: \"Path to markdown spec file:\",\n validate: (v) => (v.trim() ? true : \"Required\"),\n });\n return value.trim();\n}\n\nasync function promptForSpec(): Promise<string> {\n resetTerminalForInput();\n const source = await select({\n message: \"Where is the workflow spec?\",\n choices: [\n { name: \"Local Markdown file\", value: \"markdown\" },\n { name: \"Linear issue\", value: \"linear\" },\n { name: \"Jira issue\", value: \"jira\" },\n ],\n });\n\n switch (source) {\n case \"linear\":\n return promptLinearSpec();\n case \"jira\":\n return promptJiraSpec();\n case \"markdown\":\n default:\n return promptMarkdownSpec();\n }\n}\n\nexport async function runCommand(options: RunOptions): Promise<void> {\n const pipelineStartTime = Date.now();\n\n // Initialize tracker and context early for error handling\n const tracker = new UsageTracker();\n let context: TaskContext | undefined;\n\n // Load config and check if telemetry is enabled\n const config = loadConfig();\n const telemetryOverride = getTelemetryOverride();\n\n // Apply CLI flag overrides\n const { enabled: telemetryEnabled, level: telemetryLevelStr } = resolveTelemetryEnabled(\n telemetryOverride,\n config\n );\n const telemetryLevel = TelemetryLevel[telemetryLevelStr];\n\n let chesstrace: Chesstrace | null = null;\n\n // Detect if in a project and auto-create .reygent/ if needed\n const projectRoot = findProjectRoot(process.cwd());\n let createdReygentDir = false;\n\n if (projectRoot) {\n const reygentDir = join(projectRoot, '.reygent');\n if (!existsSync(reygentDir)) {\n try {\n mkdirSync(reygentDir, { recursive: true });\n createdReygentDir = true;\n } catch (err) {\n // Failed to create - will fall back to global\n if (isDebug()) {\n console.error(chalk.gray(\"Failed to create .reygent:\"), err);\n }\n }\n }\n }\n\n // Initialize telemetry backend only if enabled\n if (telemetryEnabled) {\n try {\n const retentionDays = config.telemetry?.retention ?? 30;\n chesstrace = getChesstrace({ level: telemetryLevel, retentionDays });\n\n // Use dual backend if in project, otherwise global\n const backend = projectRoot\n ? new DualBackend(projectRoot)\n : new SqliteBackend('global');\n\n await chesstrace.init(backend);\n await chesstrace.startRun();\n\n // Show message if created .reygent/ for first time\n if (createdReygentDir) {\n console.log(chalk.green(\"✓\"), chalk.gray(\"Created .reygent/ for local knowledge learning\"));\n console.log(\"\");\n }\n } catch (err) {\n // Telemetry init failed - continue without telemetry\n if (isDebug()) {\n console.error(chalk.gray(\"Telemetry init failed:\"), err);\n }\n chesstrace = null;\n }\n }\n\n const commandStartTime = Date.now();\n\n try {\n let specSource = options.spec;\n if (!specSource) {\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"--spec is required in non-interactive environments.\");\n await chesstrace?.close();\n process.exit(1);\n }\n specSource = await promptForSpec();\n }\n const spec = await loadSpec(specSource);\n\n // Skip telemetry in dry-run mode\n if (options.dryRun) {\n console.log(chalk.yellow.bold(\"[dry-run]\"), \"No changes will be made.\\n\");\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Specification\"));\n console.log(chalk.cyan(\"│\"), chalk.bold(spec.title));\n console.log(chalk.cyan(\"│\"), chalk.gray(`source: ${spec.source}`));\n console.log(chalk.cyan(\"└─\"));\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Workflow Stages\"));\n\n for (let i = 0; i < PIPELINE.length; i++) {\n const stage = PIPELINE[i];\n const isLast = i === PIPELINE.length - 1;\n const prefix = isLast ? \"└─\" : \"├─\";\n const continuation = isLast ? \" \" : \"│ \";\n\n console.log(chalk.cyan(prefix), chalk.bold.white(stage.name));\n console.log(chalk.cyan(continuation), chalk.gray(stage.description));\n\n // Format execution details\n let execInfo = \"\";\n if (stage.execution.kind === \"agent\") {\n execInfo = chalk.blue(`agent: ${stage.execution.agent}`);\n } else if (stage.execution.kind === \"parallel\") {\n execInfo = chalk.magenta(`parallel: ${stage.execution.agents.join(\", \")}`);\n } else if (stage.execution.kind === \"gate\") {\n execInfo = chalk.yellow(`gate: ${stage.execution.condition} (${stage.execution.agent})`);\n }\n\n console.log(chalk.cyan(continuation), execInfo);\n\n if (!isLast) {\n console.log(chalk.cyan(\"│\"));\n }\n }\n\n console.log(\"\");\n return;\n }\n\n // Emit COMMAND_START after dry-run check\n if (chesstrace) {\n try { chesstrace.emit(Events.COMMAND_START, { command: 'run' }); } catch { /* swallow */ }\n }\n\n // Initialize context after dry-run check\n context = { spec, results: [] };\n\n const threshold = options.securityThreshold.toUpperCase();\n if (!VALID_SEVERITIES.has(threshold)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid --security-threshold \"${options.securityThreshold}\". Must be one of: CRITICAL, HIGH, MEDIUM, LOW`);\n process.exit(1);\n }\n\n // Prompt for permission mode if not specified\n let autoApprove = options.autoApprove;\n if (!autoApprove) {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n \"\\nAgents will write files and run commands. Auto-approve all actions? (y/n) \",\n resolve,\n );\n });\n rl.close();\n\n autoApprove = answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n console.log(\"\");\n }\n\n // Prompt for clarification preference if not specified\n let skipClarification = options.skipClarification;\n if (!skipClarification && !options.dryRun) {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n \"Skip clarifying questions and make assumptions? (y/n) \",\n resolve,\n );\n });\n rl.close();\n\n skipClarification = answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n console.log(\"\");\n }\n\n const maxRetries = Math.max(0, parseInt(options.maxRetries, 10) || 0);\n\n const agentOptions = { autoApprove };\n\n // Emit pipeline.start\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_START, {\n spec: {\n source: spec.source,\n title: spec.title,\n },\n options: {\n autoApprove,\n skipClarification,\n maxRetries,\n securityThreshold: options.securityThreshold,\n insecure: options.insecure,\n },\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n for (const stage of PIPELINE) {\n const stageStartTime = Date.now();\n const toolTracker = createToolTracker();\n\n // Emit pipeline.stage.start\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_STAGE_START, {\n stage: stage.name,\n description: stage.description,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n if (stage.name === \"plan\") {\n const status = createLiveStatus(\"running planner...\");\n\n let plan: PlannerOutput | null = null;\n\n if (skipClarification) {\n // Skip clarification, make assumptions\n const { result, usage: planUsage } = await runPlanner(\n context.spec,\n undefined,\n { makeAssumptions: true, ...withActivity(agentOptions, status, toolTracker) },\n );\n if (\"needsClarification\" in result && result.needsClarification) {\n status.fail(chalk.red(\"Planner asked questions despite skip flag\"));\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Planner: unexpected clarification request in assumption mode\",\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Planner: unexpected clarification request in assumption mode\");\n }\n plan = result as PlannerOutput;\n if (planUsage) tracker.record(\"planner\", \"plan\", planUsage);\n } else {\n // Run clarification loop\n let clarificationAnswers = \"\";\n let attempts = 0;\n const maxAttempts = 3;\n\n while (!plan && attempts < maxAttempts) {\n attempts++;\n const { result, usage: planUsage } = await runPlanner(\n context.spec,\n clarificationAnswers,\n withActivity(agentOptions, status, toolTracker),\n );\n if (planUsage) tracker.record(\"planner\", \"plan\", planUsage);\n\n if (\"needsClarification\" in result && result.needsClarification) {\n status.stop();\n resetTerminalForInput();\n console.log(chalk.yellow(\"\\nPlanner needs clarification:\\n\"));\n\n const answers: string[] = [];\n\n for (let i = 0; i < result.questions.length; i++) {\n const question = result.questions[i];\n console.log(` [${i + 1}/${result.questions.length}] ${question}`);\n resetTerminalForInput();\n const answer = await pasteableInput({ message: \">\" });\n\n if (answer.toLowerCase() === \"abort\" || answer.toLowerCase() === \"cancel\") {\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Planner: clarification aborted by user\",\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Planner: clarification aborted by user\");\n }\n\n answers.push(`Q: ${question}\\nA: ${answer}`);\n }\n clarificationAnswers = answers.join(\"\\n\\n\");\n console.log(chalk.blue(\"\\nRe-running planner with clarifications...\\n\"));\n status.start();\n } else {\n plan = result as PlannerOutput;\n }\n }\n\n if (!plan) {\n status.fail(chalk.red(\"Planner failed\"));\n // Emit error.task before throwing\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `Planner: failed to create valid plan after ${maxAttempts} attempts`,\n stage: \"plan\",\n agent: \"planner\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\n `Planner: failed to create valid plan after ${maxAttempts} attempts`,\n );\n }\n }\n\n status.succeed(chalk.green(\"Plan created\"));\n context.plan = plan;\n\n const cols = process.stdout.columns || 80;\n console.log(chalk.cyan(\"\\nGoals:\"));\n for (const g of plan.goals) console.log(` ${chalk.gray(\"-\")} ${wrapText(g, 4, cols)}`);\n console.log(chalk.cyan(\"\\nTasks:\"));\n for (const t of plan.tasks) console.log(` ${chalk.gray(\"-\")} ${wrapText(t, 4, cols)}`);\n console.log(chalk.cyan(\"\\nConstraints:\"));\n for (const c of plan.constraints) console.log(` ${chalk.gray(\"-\")} ${wrapText(c, 4, cols)}`);\n console.log(chalk.cyan(\"\\nDefinition of Done:\"));\n for (const d of plan.dod) console.log(` ${chalk.gray(\"-\")} ${wrapText(d, 4, cols)}`);\n console.log();\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(plan),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"implement\") {\n if (!context.plan) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"Implement: plan stage must run before implement\",\n stage: \"implement\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"Implement: plan stage must run before implement\");\n }\n\n const implStatus = createLiveStatus(\"spawning dev and qe agents...\");\n const { implement: impl, usages: implUsages } = await runImplement(\n context.spec,\n context.plan,\n withActivity(agentOptions, implStatus, toolTracker),\n );\n context.implement = impl;\n\n for (const u of implUsages) {\n if (u.usage) tracker.record(u.agent, \"implement\", u.usage);\n }\n\n let devSuccess = impl.dev !== null;\n let qeSuccess = impl.qe !== null;\n\n if (devSuccess && qeSuccess) {\n implStatus.succeed(chalk.green(\"Implementation complete\"));\n } else {\n implStatus.warn(chalk.yellow(\"Implementation partially failed\"));\n }\n\n if (impl.dev) {\n console.log(chalk.gray(\"dev files:\"), impl.dev.files.join(\", \") || chalk.gray(\"(none)\"));\n }\n if (impl.qe) {\n console.log(chalk.gray(\"qe test files:\"), impl.qe.testFiles.join(\", \") || chalk.gray(\"(none)\"));\n }\n\n // Retry loop for failed agents\n let attempt = 0;\n while (!devSuccess || !qeSuccess) {\n attempt++;\n\n const failedAgents = [\n !devSuccess ? \"dev\" : null,\n !qeSuccess ? \"qe\" : null,\n ].filter(Boolean).join(\", \");\n\n // Check if exceeded max retries or prompt user\n await promptForRetry({\n taskName: `${failedAgents} agent(s)`,\n attempt,\n maxRetries,\n autoApprove,\n telemetry: {\n stageName: stage.name,\n agentName: !devSuccess ? \"dev\" : \"qe\",\n },\n });\n\n // Determine which agents to retry\n const agentsToRetry: Array<\"dev\" | \"qe\"> = [];\n if (!devSuccess) agentsToRetry.push(\"dev\");\n if (!qeSuccess) agentsToRetry.push(\"qe\");\n\n const attemptDisplay = maxRetries > 0\n ? `${attempt}/${maxRetries}`\n : `${attempt}`;\n console.log(chalk.yellow(`\\nRetrying ${agentsToRetry.join(\" + \")} agent(s) (attempt ${attemptDisplay})...`));\n\n const retryStatus = createLiveStatus(`re-running ${agentsToRetry.join(\" + \")} agent(s)...`);\n try {\n const { implement: retryImpl, usages: retryUsages } = await runImplement(\n context.spec,\n context.plan,\n withActivity(agentOptions, retryStatus, toolTracker),\n { agentsToRun: agentsToRetry },\n );\n\n for (const u of retryUsages) {\n if (u.usage) tracker.record(u.agent, `${stage.name}-retry`, u.usage);\n }\n\n // Merge results\n if (retryImpl.dev && !devSuccess) {\n context.implement!.dev = retryImpl.dev;\n devSuccess = true;\n }\n if (retryImpl.qe && !qeSuccess) {\n context.implement!.qe = retryImpl.qe;\n qeSuccess = true;\n }\n\n if (devSuccess && qeSuccess) {\n retryStatus.succeed(chalk.green(\"Implementation complete on retry\"));\n if (context.implement!.dev) {\n console.log(chalk.gray(\"dev files:\"), context.implement!.dev.files.join(\", \") || chalk.gray(\"(none)\"));\n }\n if (context.implement!.qe) {\n console.log(chalk.gray(\"qe test files:\"), context.implement!.qe.testFiles.join(\", \") || chalk.gray(\"(none)\"));\n }\n } else {\n retryStatus.warn(chalk.yellow(`Retry ${attempt} partially failed`));\n }\n } catch {\n retryStatus.fail(chalk.red(`Retry ${attempt} failed`));\n }\n }\n\n context.results.push({\n stage: stage.name,\n success: devSuccess && qeSuccess,\n output: JSON.stringify(context.implement),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, devSuccess && qeSuccess, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"gate-unit-tests\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"gate-unit-tests: implement stage must run first\",\n stage: \"gate-unit-tests\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"gate-unit-tests: implement stage must run first\");\n }\n\n const unitStatus = createLiveStatus(\"running unit tests...\");\n const { gate: unitGateResult, usage: unitGateUsage } = await runUnitTestGate(\n context,\n { ...withActivity(agentOptions, unitStatus, toolTracker), attempt: 1, verbose: options.verbose },\n );\n let gateResult = unitGateResult;\n\n if (unitGateUsage) tracker.record(\"gate:unit-tests\", stage.name, unitGateUsage);\n\n if (!context.gates) context.gates = {};\n context.gates.unitTests = gateResult;\n\n if (gateResult.passed) {\n unitStatus.succeed(chalk.green(\"Unit tests PASSED\"));\n context.results.push({\n stage: stage.name,\n success: true,\n output: gateResult.output,\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n unitStatus.fail(chalk.red(\"Unit tests FAILED\"));\n\n // Retry loop — dev agent only for unit test failures\n try {\n gateResult = await retryGate({\n gateName: \"unit tests\",\n gateRunner: (attempt) => runUnitTestGate(context, { ...agentOptions, attempt, verbose: options.verbose }),\n agentsToRun: [\"dev\"],\n context,\n agentOptions,\n maxRetries,\n autoApprove,\n stageName: stage.name,\n tracker,\n verbose: options.verbose,\n toolTracker,\n });\n } catch (err) {\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n throw err;\n }\n\n context.results.push({\n stage: stage.name,\n success: gateResult.passed,\n output: gateResult.output,\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, gateResult.passed, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"gate-functional-tests\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"gate-functional-tests: implement stage must run first\",\n stage: \"gate-functional-tests\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"gate-functional-tests: implement stage must run first\");\n }\n\n const funcStatus = createLiveStatus(\"running functional tests...\");\n const { gate: funcGateResult, usage: funcGateUsage } = await runFunctionalTestGate(\n context,\n { ...withActivity(agentOptions, funcStatus, toolTracker), attempt: 1, verbose: options.verbose },\n );\n let gateResult = funcGateResult;\n\n if (funcGateUsage) tracker.record(\"gate:functional-tests\", stage.name, funcGateUsage);\n\n if (!context.gates) context.gates = {};\n context.gates.functionalTests = gateResult;\n\n if (gateResult.passed) {\n funcStatus.succeed(chalk.green(\"Functional tests PASSED\"));\n context.results.push({\n stage: stage.name,\n success: true,\n output: gateResult.output,\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n funcStatus.fail(chalk.red(\"Functional tests FAILED\"));\n console.log(gateResult.output);\n\n // Retry loop — both dev + qe agents for functional test failures\n try {\n gateResult = await retryGate({\n gateName: \"functional tests\",\n gateRunner: (attempt) => runFunctionalTestGate(context, { ...agentOptions, attempt, verbose: options.verbose }),\n agentsToRun: [\"dev\", \"qe\"],\n context,\n agentOptions,\n maxRetries,\n autoApprove,\n stageName: stage.name,\n tracker,\n verbose: options.verbose,\n toolTracker,\n });\n } catch (err) {\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n throw err;\n }\n\n context.results.push({\n stage: stage.name,\n success: gateResult.passed,\n output: gateResult.output,\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, gateResult.passed, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"security-review\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"security-review: implement stage must run first\",\n stage: \"security-review\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"security-review: implement stage must run first\");\n }\n\n const secStatus = createLiveStatus(\"running security review...\");\n const { output, passed, usage: secUsage } = await runSecurityReview(\n context,\n threshold as Severity,\n withActivity(agentOptions, secStatus, toolTracker),\n );\n if (secUsage) tracker.record(\"security-review\", stage.name, secUsage);\n context.securityReview = output;\n\n if (passed) {\n secStatus.succeed(chalk.green(\"Security review PASSED\"));\n } else {\n secStatus.fail(chalk.red(\"Security review FAILED\"));\n }\n\n console.log(\"\");\n console.log(chalk.cyan.bold(`Security Findings (${output.findings.length}):`));\n console.log(formatFindings(output.findings, threshold as Severity));\n console.log(\"\");\n\n if (passed) {\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(output),\n });\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n console.log(chalk.yellow(`Findings at or above ${threshold} threshold`));\n context.results.push({\n stage: stage.name,\n success: false,\n output: JSON.stringify(output),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, false, undefined, toolTracker);\n\n if (autoApprove) {\n console.log(chalk.yellow(\"Auto-approved — bypassing security gate...\"));\n } else {\n resetTerminalForInput();\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(\"\\nSecurity review failed. Continue with PR creation anyway? (y/n) \"),\n resolve,\n );\n });\n rl.close();\n\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n console.log(chalk.red(\"Aborted by user.\"));\n process.exit(1);\n }\n\n console.log(chalk.yellow(\"Bypassed by user — continuing...\"));\n }\n continue;\n }\n\n if (stage.name === \"pr-create\") {\n if (!context.implement) {\n // Emit error.task before throwing\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: \"pr-create: implement stage must run first\",\n stage: \"pr-create\",\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n throw new TaskError(\"pr-create: implement stage must run first\");\n }\n\n // Determine branch type\n let branchType: BranchType;\n\n // Check if --type flag was provided\n if (options.type) {\n // Validation already done in CLI hook, just normalize\n branchType = normalizeType(options.type);\n } else {\n // Try auto-detection from issue type\n let autoDetected: BranchType | null = null;\n\n if (context.spec.source === \"jira\" && context.spec.issueType) {\n autoDetected = detectTypeFromJiraIssueType(context.spec.issueType);\n } else if (context.spec.source === \"linear\" && \"labels\" in context.spec && context.spec.labels) {\n autoDetected = detectTypeFromLinearLabels(context.spec.labels);\n }\n\n if (autoDetected) {\n // Issue type detected - use it without prompting\n branchType = autoDetected;\n } else {\n // No auto-detection - prompt user\n resetTerminalForInput();\n branchType = await select({\n message: \"Select branch type:\",\n choices: VALID_BRANCH_TYPES.map(t => ({ name: t, value: t })),\n }) as BranchType;\n }\n }\n\n const spinner = ora(chalk.blue(\"creating pull request...\")).start();\n const prResult = await runPRCreate(context, { insecure: options.insecure, branchType });\n context.prCreate = prResult;\n spinner.succeed(chalk.green(\"PR created\"));\n\n console.log(chalk.gray(\"branch:\"), chalk.cyan(prResult.branch));\n console.log(chalk.gray(\"PR:\"), chalk.blue(prResult.prUrl));\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(prResult),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n if (stage.name === \"pr-review\") {\n const prStatus = createLiveStatus(\"reviewing pull request...\");\n const { output: reviewOutput, usage: prUsage } = await runPRReview(\n context,\n withActivity(agentOptions, prStatus, toolTracker),\n );\n context.prReview = reviewOutput;\n if (prUsage) tracker.record(\"pr-review\", stage.name, prUsage);\n prStatus.succeed(chalk.green(\"PR review complete\"));\n\n console.log(formatPRReviewTerminal(reviewOutput));\n\n const commentSpinner = ora(chalk.blue(\"posting review comment to PR...\")).start();\n try {\n await postPRReviewComment(context, reviewOutput);\n commentSpinner.succeed(chalk.green(\"Review posted to PR\"));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n commentSpinner.fail(chalk.yellow(`Could not post review to PR: ${msg}`));\n }\n\n context.results.push({\n stage: stage.name,\n success: true,\n output: JSON.stringify(reviewOutput),\n });\n\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n continue;\n }\n\n const result: StageResult = {\n stage: stage.name,\n success: true,\n output: \"skipped\",\n };\n console.log(chalk.gray(`[${stage.name}] skipped`));\n context.results.push(result);\n emitStageEnd(chesstrace, stage.name, stageStartTime, true, undefined, toolTracker);\n }\n\n // Emit pipeline.end\n const allSuccess = context.results.every((r) => r.success);\n if (chesstrace) {\n try {\n chesstrace.emit(Events.PIPELINE_END, {\n success: allSuccess,\n totalDurationMs: Date.now() - pipelineStartTime,\n totalCost: tracker.getTotalCost(),\n });\n } catch {\n // Swallow emit errors\n }\n\n // Emit COMMAND_END on success\n try {\n chesstrace.emit(Events.COMMAND_END, {\n command: 'run',\n success: allSuccess,\n durationMs: Date.now() - commandStartTime,\n });\n } catch {\n // Swallow emit errors\n }\n\n // Flush and close telemetry\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n\n // Update knowledge base from telemetry\n await updateKnowledgeFromTelemetry();\n\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n\n // Print usage summary after pipeline completes\n printUsageSummary(tracker);\n if (options.verbose) {\n printVerboseUsage(tracker);\n }\n } catch (err) {\n // Emit error.task telemetry for TaskError\n if (chesstrace && err instanceof TaskError) {\n try {\n // Extract stage from context if available\n const stage = context?.results[context.results.length - 1]?.stage ?? \"unknown\";\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: err.message,\n stage,\n agent: \"pipeline\",\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n // Emit COMMAND_ERROR + pipeline.end with failure status\n if (chesstrace) {\n try {\n chesstrace.emit(Events.COMMAND_ERROR, {\n command: 'run',\n error: err instanceof Error ? err.message : String(err),\n durationMs: Date.now() - commandStartTime,\n });\n } catch {\n // Swallow emit errors\n }\n\n try {\n if (context) {\n chesstrace.emit(Events.PIPELINE_END, {\n success: false,\n totalDurationMs: Date.now() - pipelineStartTime,\n totalCost: tracker?.getTotalCost() ?? 0,\n });\n }\n } catch {\n // Swallow emit errors\n }\n\n // Flush and close telemetry even on error\n try {\n await chesstrace.flush();\n } catch {\n // Swallow flush errors\n }\n\n // Update knowledge base from telemetry\n await updateKnowledgeFromTelemetry();\n\n try {\n await chesstrace.close();\n } catch {\n // Swallow close errors\n }\n }\n\n // In test env, re-throw instead of process.exit to allow test assertions.\n // We check runtime environment variables (NODE_ENV, VITEST) rather than import.meta.env\n // because test runners set these at runtime, not during bundling. See src/test-env.ts.\n const isTest = isTestEnvironment();\n\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n if (isTest) throw err;\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n if (isTest) throw err;\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n if (isTest) throw err;\n process.exit(2);\n }\n}\n","import chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { ActivityEvent } from \"./providers/types.js\";\nimport { spawnAgentStream, formatExitDetail } from \"./spawn.js\";\nimport type { SpawnResult } from \"./spawn.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type {\n PlannerOutput,\n DevOutput,\n QEOutput,\n ImplementOutput,\n} from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { emitErrorTask } from \"./telemetry-helpers.js\";\n\nexport type { SpawnResult };\n\n/**\n * Extract head and tail of agent output for error display.\n *\n * For long outputs, shows first 150 and last 150 characters to capture\n * both the initial error context and the final failure message.\n * In debug mode, full output is already printed, so this is for quick\n * terminal feedback during normal operation.\n */\nfunction getFailureSummary(stdout: string, maxLen = 300): string {\n const trimmed = stdout.trim();\n if (!trimmed) return \"\";\n if (trimmed.length <= maxLen) return trimmed;\n\n // Show head + tail for better context\n const halfLen = Math.floor(maxLen / 2);\n const head = trimmed.slice(0, halfLen);\n const tail = trimmed.slice(-halfLen);\n return `${head}…${tail}`;\n}\n\nconst AGENT_TIMEOUT_MS = 15 * 60 * 1000;\n\n/**\n * Options for spawning agents via spawnAgent() wrapper.\n * This interface mirrors SpawnOptions from spawn.ts and adds semantic clarity\n * for callers in the implement module. Changes to SpawnOptions should be\n * reflected here to maintain compatibility.\n */\nexport interface AgentSpawnOptions {\n autoApprove?: boolean;\n quiet?: boolean;\n provider?: string;\n model?: string;\n onActivity?: (event: ActivityEvent) => void;\n stage?: string;\n}\n\nexport interface FailureContext {\n gateName: string;\n testOutput: string;\n attempt: number;\n maxAttempts: number;\n}\n\nexport interface RetryOptions {\n failureContext?: FailureContext;\n agentsToRun?: Array<\"dev\" | \"qe\">;\n}\n\nexport function spawnAgent(\n name: string,\n prompt: string,\n options?: AgentSpawnOptions,\n): Promise<SpawnResult> {\n return spawnAgentStream(name, prompt, AGENT_TIMEOUT_MS, options);\n}\n\nfunction buildRetrySection(failureContext: FailureContext): string {\n return `\n\n---\n\n## RETRY (attempt ${failureContext.attempt}/${failureContext.maxAttempts})\n\nThe previous implementation failed the **${failureContext.gateName}** gate. Review the test output below, identify what went wrong, and fix the issues.\n\n**Test output:**\n\\`\\`\\`\n${failureContext.testOutput}\n\\`\\`\\`\n\nFocus on fixing the failures above. Do not rewrite code that already works.`;\n}\n\nfunction buildDevPrompt(\n systemPrompt: string,\n spec: SpecPayload,\n plan: PlannerOutput,\n failureContext?: FailureContext,\n): string {\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}\n\n---\n\nWhen you are finished, output a JSON block with the list of files you created or modified:\n\n\\`\\`\\`json\n{ \"files\": [\"src/example.ts\", \"src/example.test.ts\"] }\n\\`\\`\\``;\n\n if (failureContext) {\n prompt += buildRetrySection(failureContext);\n }\n\n return prompt;\n}\n\nfunction buildQEPrompt(\n systemPrompt: string,\n spec: SpecPayload,\n plan: PlannerOutput,\n failureContext?: FailureContext,\n): string {\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${spec.title}\n\n${spec.content}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}\n\n---\n\nWhen you are finished, output a JSON block with the list of test files you created or modified:\n\n\\`\\`\\`json\n{ \"testFiles\": [\"tests/example.test.ts\"] }\n\\`\\`\\``;\n\n if (failureContext) {\n prompt += buildRetrySection(failureContext);\n }\n\n return prompt;\n}\n\nfunction extractDevOutput(stdout: string): DevOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(/\\{\\s*\"files\"\\s*:\\s*\\[.*?\\]\\s*\\}/s);\n if (match) {\n try {\n const parsed = JSON.parse(match[0]) as { files: unknown };\n if (Array.isArray(parsed.files)) {\n return { files: parsed.files.filter((f) => typeof f === \"string\") };\n }\n } catch (err) {\n // Emit error.parse before falling through\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"dev\",\n expectedFormat: '{ \"files\": [\"...\"] }',\n received: match[0].slice(0, 500),\n });\n }\n // fall through\n }\n }\n return { files: [] };\n}\n\nfunction extractQEOutput(stdout: string): QEOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(/\\{\\s*\"testFiles\"\\s*:\\s*\\[.*?\\]\\s*\\}/s);\n if (match) {\n try {\n const parsed = JSON.parse(match[0]) as { testFiles: unknown };\n if (Array.isArray(parsed.testFiles)) {\n return {\n testFiles: parsed.testFiles.filter((f) => typeof f === \"string\"),\n };\n }\n } catch (err) {\n // Emit error.parse before falling through\n const chesstrace = getChesstrace();\n if (chesstrace) {\n chesstrace.emit(Events.ERROR_PARSE, {\n agent: \"qe\",\n expectedFormat: '{ \"testFiles\": [\"...\"] }',\n received: match[0].slice(0, 500),\n });\n }\n // fall through\n }\n }\n return { testFiles: [] };\n}\n\nexport interface ImplementResult {\n implement: ImplementOutput;\n usages: Array<{ agent: string; usage?: UsageInfo }>;\n}\n\nexport async function runImplement(\n spec: SpecPayload,\n plan: PlannerOutput,\n options?: AgentSpawnOptions,\n retryOptions?: RetryOptions,\n): Promise<ImplementResult> {\n const agents = getAgents();\n const devAgent = agents.find((a) => a.name === \"dev\");\n const qeAgent = agents.find((a) => a.name === \"qe\");\n\n if (!devAgent || !qeAgent) {\n emitErrorTask(\n \"Implement: missing dev or qe agent config\",\n options?.stage ?? \"implement\",\n { agent: \"implement\" },\n );\n throw new TaskError(\"Implement: missing dev or qe agent config\");\n }\n\n const agentsToRun = retryOptions?.agentsToRun ?? [\"dev\", \"qe\"];\n const failureContext = retryOptions?.failureContext;\n\n const runDev = agentsToRun.includes(\"dev\");\n const runQE = agentsToRun.includes(\"qe\");\n\n const devPrompt = runDev\n ? buildDevPrompt(devAgent.systemPrompt, spec, plan, failureContext)\n : \"\";\n const qePrompt = runQE\n ? buildQEPrompt(qeAgent.systemPrompt, spec, plan, failureContext)\n : \"\";\n\n let dev: DevOutput | null = null;\n let qe: QEOutput | null = null;\n const usages: Array<{ agent: string; usage?: UsageInfo }> = [];\n\n if (options?.autoApprove) {\n // Parallel: no stdin needed\n const promises: Promise<PromiseSettledResult<SpawnResult>>[] = [];\n\n if (runDev) {\n promises.push(\n spawnAgent(\"dev\", devPrompt, { ...options, provider: devAgent.provider, model: devAgent.model, stage: \"implement\" }).then(\n (v) => ({ status: \"fulfilled\" as const, value: v }),\n (e) => ({ status: \"rejected\" as const, reason: e }),\n ),\n );\n }\n if (runQE) {\n promises.push(\n spawnAgent(\"qe\", qePrompt, { ...options, provider: qeAgent.provider, model: qeAgent.model, stage: \"implement\" }).then(\n (v) => ({ status: \"fulfilled\" as const, value: v }),\n (e) => ({ status: \"rejected\" as const, reason: e }),\n ),\n );\n }\n\n const results = await Promise.all(promises);\n let idx = 0;\n\n if (runDev) {\n const devResult = results[idx++];\n if (devResult.status === \"fulfilled\") {\n usages.push({ agent: \"dev\", usage: devResult.value.usage });\n if (devResult.value.exitCode === 0) {\n dev = extractDevOutput(devResult.value.stdout);\n } else {\n const detail = formatExitDetail(devResult.value, devAgent.model);\n console.log(chalk.red(\"dev agent failed:\"), `exit code ${devResult.value.exitCode}${detail}`);\n // Show stdout context when errorMessage is terse (< 50 chars) or missing\n if (!devResult.value.errorMessage || (devResult.value.errorMessage.length < 50)) {\n const summary = getFailureSummary(devResult.value.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } else {\n console.log(chalk.red(\"dev agent failed:\"), devResult.reason);\n }\n }\n\n if (runQE) {\n const qeResult = results[idx++];\n if (qeResult.status === \"fulfilled\") {\n usages.push({ agent: \"qe\", usage: qeResult.value.usage });\n if (qeResult.value.exitCode === 0) {\n qe = extractQEOutput(qeResult.value.stdout);\n } else {\n const detail = formatExitDetail(qeResult.value, qeAgent.model);\n console.log(chalk.red(\"qe agent failed:\"), `exit code ${qeResult.value.exitCode}${detail}`);\n // Show stdout context when errorMessage is terse (< 50 chars) or missing\n if (!qeResult.value.errorMessage || (qeResult.value.errorMessage.length < 50)) {\n const summary = getFailureSummary(qeResult.value.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } else {\n console.log(chalk.red(\"qe agent failed:\"), qeResult.reason);\n }\n }\n } else {\n // Sequential: stdin inherited so user can approve each edit\n if (runDev) {\n console.log(chalk.blue(\"Running dev agent (approve edits as prompted)...\"));\n try {\n const devResult = await spawnAgent(\"dev\", devPrompt, { ...options, provider: devAgent.provider, model: devAgent.model, stage: \"implement\" });\n if (devResult.exitCode === 0) {\n dev = extractDevOutput(devResult.stdout);\n }\n usages.push({ agent: \"dev\", usage: devResult.usage });\n if (devResult.exitCode !== 0) {\n const detail = formatExitDetail(devResult);\n console.log(chalk.red(\"dev agent failed:\"), `exit code ${devResult.exitCode}${detail}`);\n if (!devResult.errorMessage) {\n const summary = getFailureSummary(devResult.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } catch (err) {\n console.log(chalk.red(\"dev agent failed:\"), err);\n }\n }\n\n if (runQE) {\n console.log(chalk.blue(\"Running qe agent (approve edits as prompted)...\"));\n try {\n const qeResult = await spawnAgent(\"qe\", qePrompt, { ...options, provider: qeAgent.provider, model: qeAgent.model, stage: \"implement\" });\n if (qeResult.exitCode === 0) {\n qe = extractQEOutput(qeResult.stdout);\n }\n usages.push({ agent: \"qe\", usage: qeResult.usage });\n if (qeResult.exitCode !== 0) {\n const detail = formatExitDetail(qeResult);\n console.log(chalk.red(\"qe agent failed:\"), `exit code ${qeResult.exitCode}${detail}`);\n if (!qeResult.errorMessage) {\n const summary = getFailureSummary(qeResult.stdout);\n if (summary) console.log(chalk.gray(\" ↳\"), chalk.gray(summary));\n }\n }\n } catch (err) {\n console.log(chalk.red(\"qe agent failed:\"), err);\n }\n }\n }\n\n // Only fail if both requested agents failed\n const chesstrace = getChesstrace();\n if ((runDev && dev === null) && (runQE && qe === null)) {\n emitErrorTask(\n \"Implement: all requested agents failed\",\n options?.stage ?? \"implement\",\n { agent: \"implement\" },\n );\n throw new TaskError(\"Implement: all requested agents failed\");\n }\n if (runDev && !runQE && dev === null) {\n emitErrorTask(\n \"Implement: dev agent failed\",\n options?.stage ?? \"implement\",\n { agent: \"dev\" },\n );\n throw new TaskError(\"Implement: dev agent failed\");\n }\n if (!runDev && runQE && qe === null) {\n emitErrorTask(\n \"Implement: qe agent failed\",\n options?.stage ?? \"implement\",\n { agent: \"qe\" },\n );\n throw new TaskError(\"Implement: qe agent failed\");\n }\n\n return { implement: { dev, qe }, usages };\n}\n","import { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { TaskError } from \"./task.js\";\nimport type { GateResult, TaskContext } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\n/* ------------------------------------------------------------------ */\n/* Shared gate utility */\n/* ------------------------------------------------------------------ */\n\nexport async function runGate(\n agentName: string,\n prompt: string,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n const result = await spawnAgent(agentName, prompt, options);\n\n const hasPass = result.stdout.includes(\"GATE_RESULT:PASS\");\n const hasFail = result.stdout.includes(\"GATE_RESULT:FAIL\");\n\n const passed = result.exitCode === 0 && hasPass && !hasFail;\n\n // Emit gate.result telemetry\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.GATE_RESULT, {\n gateName: agentName,\n passed,\n attempt: options?.attempt ?? 1,\n });\n } catch (err) {\n if (options?.verbose) {\n console.error(\"[telemetry]\", err instanceof Error ? err.message : String(err));\n }\n }\n }\n\n return { gate: { passed, output: result.stdout }, usage: result.usage };\n}\n\n/* ------------------------------------------------------------------ */\n/* Unit-tests gate */\n/* ------------------------------------------------------------------ */\n\nfunction buildUnitTestGatePrompt(context: TaskContext): string {\n const files = context.implement!.dev!.files;\n const filesList = files.length > 0\n ? files.map((f) => `- ${f}`).join(\"\\n\")\n : \"(no new files — dev agent found work already complete)\";\n\n return `You are in **test-execution mode**.\n\n## Rules\n- DO NOT write or modify any source code or test code.\n- Your ONLY job is to find the project's test runner and execute the unit tests.\n\n## Files written by the Dev agent\n${filesList}\n\n## Instructions\n1. Identify the test runner used by this project (e.g. vitest, jest, mocha, npm test).\n2. Run the unit tests. Stream the full output.\n3. After the test run completes, emit exactly one of the following as the **last line** of your output:\n - \\`GATE_RESULT:PASS\\` — if ALL unit tests passed\n - \\`GATE_RESULT:FAIL\\` — if ANY unit test failed or the runner returned a non-zero exit code\n\nDo NOT emit both markers. Do NOT omit the marker.`;\n}\n\nexport async function runUnitTestGate(\n context: TaskContext,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n if (!context.implement) {\n throw new TaskError(\n \"gate:unit-tests: implement stage has not run\",\n );\n }\n\n if (!context.implement.dev) {\n throw new TaskError(\n \"gate:unit-tests: dev output is null — dev agent failed during implement\",\n );\n }\n\n const prompt = buildUnitTestGatePrompt(context);\n return runGate(\"gate:unit-tests\", prompt, options);\n}\n\n/* ------------------------------------------------------------------ */\n/* Functional-tests gate */\n/* ------------------------------------------------------------------ */\n\nfunction buildFunctionalTestGatePrompt(context: TaskContext): string {\n const testFiles = context.implement!.qe!.testFiles;\n const filesList = testFiles.length > 0\n ? testFiles.map((f) => `- ${f}`).join(\"\\n\")\n : \"(no new test files — qe agent found tests already complete)\";\n\n return `You are in **test-execution mode**.\n\n## Rules\n- DO NOT write or modify any source code or test code.\n- Your ONLY job is to find the project's test runner and execute the functional tests.\n\n## Test files written by the QE agent\n${filesList}\n\n## Instructions\n1. Identify the test runner used by this project (e.g. vitest, jest, mocha, npm test).\n2. Run the functional tests${testFiles.length > 0 ? \" listed above\" : \"\"}. Stream the full output.\n3. After the test run completes, emit exactly one of the following as the **last line** of your output:\n - \\`GATE_RESULT:PASS\\` — if ALL functional tests passed\n - \\`GATE_RESULT:FAIL\\` — if ANY functional test failed or the runner returned a non-zero exit code\n\nDo NOT emit both markers. Do NOT omit the marker.`;\n}\n\nexport async function runFunctionalTestGate(\n context: TaskContext,\n options?: AgentSpawnOptions & { attempt?: number; verbose?: boolean },\n): Promise<{ gate: GateResult; usage?: UsageInfo }> {\n if (!context.implement) {\n throw new TaskError(\n \"gate:functional-tests: implement stage has not run\",\n );\n }\n\n if (!context.implement.qe) {\n throw new TaskError(\n \"gate:functional-tests: qe output is null — qe agent failed during implement\",\n );\n }\n\n const prompt = buildFunctionalTestGatePrompt(context);\n return runGate(\"gate:functional-tests\", prompt, options);\n}\n","import { execFile } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { request as httpsRequest } from \"node:https\";\nimport { rootCertificates } from \"node:tls\";\nimport { loadEnvFile } from \"./env.js\";\nimport type { BranchType as CanonicalBranchType } from \"./branch-type.js\";\nimport type { SpecPayload } from \"./spec.js\";\nimport type { PRCreateOutput, TaskContext } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nfunction exec(\n cmd: string,\n args: string[],\n opts?: { timeout?: number },\n): Promise<{ stdout: string; stderr: string }> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { timeout: opts?.timeout, maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `pr-create: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve({ stdout, stderr });\n },\n );\n });\n}\n\nexport type Platform = \"github\" | \"gitlab\";\n\nexport interface RemoteInfo {\n platform: Platform;\n host: string;\n owner: string;\n repo: string;\n}\n\nexport async function resolveToken(host: string): Promise<string> {\n const { execFile: execFileCb } = await import(\"node:child_process\");\n return new Promise((resolve, reject) => {\n const child = execFileCb(\n \"git\",\n [\"credential\", \"fill\"],\n { maxBuffer: 1024 * 1024 },\n (error, stdout) => {\n if (error) {\n reject(\n new TaskError(\n `pr-create: failed to retrieve credentials for ${host} via git credential fill.\\n` +\n \"Configure a credential helper: https://git-scm.com/doc/credential-helpers\",\n ),\n );\n return;\n }\n const passwordLine = stdout\n .split(\"\\n\")\n .find((l) => l.startsWith(\"password=\"));\n if (!passwordLine) {\n reject(\n new TaskError(\n `pr-create: no password/token found from git credential fill for ${host}.`,\n ),\n );\n return;\n }\n resolve(passwordLine.slice(\"password=\".length).trim());\n },\n );\n child.stdin?.write(`protocol=https\\nhost=${host}\\n\\n`);\n child.stdin?.end();\n });\n}\n\nexport function parseRemote(remoteUrl: string): RemoteInfo {\n const url = remoteUrl.trim();\n\n // SSH: git@github.com:owner/repo.git\n const sshMatch = url.match(/^git@([^:]+):([^/]+)\\/([^/.]+?)(\\.git)?$/);\n if (sshMatch) {\n const host = sshMatch[1];\n const platform: Platform = host.includes(\"gitlab\") ? \"gitlab\" : \"github\";\n return { platform, host, owner: sshMatch[2], repo: sshMatch[3] };\n }\n\n // HTTPS: https://github.com/owner/repo.git\n const httpsMatch = url.match(/^https?:\\/\\/([^/]+)\\/([^/]+)\\/([^/.]+?)(\\.git)?$/);\n if (httpsMatch) {\n const host = httpsMatch[1];\n const platform: Platform = host.includes(\"gitlab\") ? \"gitlab\" : \"github\";\n return { platform, host, owner: httpsMatch[2], repo: httpsMatch[3] };\n }\n\n throw new TaskError(`pr-create: cannot parse remote URL: ${url}`);\n}\n\nexport async function createPR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n if (opts.remote.platform === \"gitlab\") {\n return createGitLabMR(opts);\n }\n return createGitHubPR(opts);\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n ca?: string[];\n}\n\nasync function resolveTlsOptions(hostname?: string): Promise<TlsOptions> {\n // Respect GIT_SSL_NO_VERIFY env var\n if (process.env.GIT_SSL_NO_VERIFY) return { rejectUnauthorized: false };\n // Respect NODE_TLS_REJECT_UNAUTHORIZED if explicitly set\n if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === \"0\") return { rejectUnauthorized: false };\n\n const { execFile: ef } = await import(\"node:child_process\");\n const gitConfig = (args: string[]): Promise<string> =>\n new Promise((res, rej) => {\n ef(\"git\", args, {}, (err, stdout) => {\n if (err) rej(err);\n else res(stdout.trim());\n });\n });\n\n // Check if sslVerify is explicitly disabled\n const sslVerifyDisabled = await (async () => {\n if (hostname) {\n try {\n const v = await gitConfig([\n \"config\", \"--bool\", \"--get-urlmatch\", \"http.sslVerify\", `https://${hostname}/`,\n ]);\n if (v === \"false\") return true;\n } catch { /* fall through */ }\n }\n try {\n const v = await gitConfig([\"config\", \"--bool\", \"http.sslVerify\"]);\n if (v === \"false\") return true;\n } catch { /* not set */ }\n return false;\n })();\n\n if (sslVerifyDisabled) return { rejectUnauthorized: false };\n\n // Load custom CA bundle from git config (http.sslCAInfo)\n // This is how git trusts corporate/internal CAs\n const caPath = await (async () => {\n if (hostname) {\n try {\n return await gitConfig([\n \"config\", \"--get-urlmatch\", \"http.sslCAInfo\", `https://${hostname}/`,\n ]);\n } catch { /* fall through */ }\n }\n try {\n return await gitConfig([\"config\", \"http.sslCAInfo\"]);\n } catch { /* not set */ }\n return null;\n })();\n\n if (caPath) {\n try {\n const customCa = readFileSync(caPath, \"utf-8\");\n // Combine Node's default CAs with the custom bundle so both are trusted\n return { ca: [...rootCertificates, customCa] };\n } catch {\n // CA file unreadable — fall through to defaults\n }\n }\n\n return {};\n}\n\nfunction doHttpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n tlsOpts: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, \"utf-8\");\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"POST\",\n headers: { ...headers, \"Content-Length\": bodyBuf.byteLength },\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.write(bodyBuf);\n req.end();\n });\n}\n\nfunction isSslError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n const code = (err as NodeJS.ErrnoException).code ?? \"\";\n return (\n code === \"UNABLE_TO_VERIFY_LEAF_SIGNATURE\" ||\n code === \"DEPTH_ZERO_SELF_SIGNED_CERT\" ||\n code === \"SELF_SIGNED_CERT_IN_CHAIN\" ||\n code === \"ERR_TLS_CERT_ALTNAME_INVALID\" ||\n code === \"CERT_HAS_EXPIRED\" ||\n err.message.includes(\"self-signed\") ||\n err.message.includes(\"certificate\")\n );\n}\n\nasync function httpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n opts?: { insecure?: boolean },\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n const tlsOpts: TlsOptions = opts?.insecure\n ? { rejectUnauthorized: false }\n : await resolveTlsOptions(parsed.hostname);\n\n try {\n return await doHttpsPost(url, headers, body, tlsOpts);\n } catch (err) {\n if (!opts?.insecure && isSslError(err)) {\n return doHttpsPost(url, headers, body, { rejectUnauthorized: false });\n }\n throw err;\n }\n}\n\nasync function createGitHubPR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n const { host, owner, repo } = opts.remote;\n const apiBase =\n host === \"github.com\"\n ? \"https://api.github.com\"\n : `https://${host}/api/v3`;\n const body = JSON.stringify({\n title: opts.title,\n body: opts.body,\n head: opts.head,\n base: opts.base,\n });\n const { status, text } = await httpsPost(\n `${apiBase}/repos/${owner}/${repo}/pulls`,\n {\n Authorization: `Bearer ${opts.token}`,\n Accept: \"application/vnd.github+json\",\n \"X-GitHub-Api-Version\": \"2022-11-28\",\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"reygent\",\n },\n body,\n { insecure: opts.insecure },\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`pr-create: GitHub API error ${status}: ${text}`);\n }\n const data = JSON.parse(text) as { html_url: string; number: number };\n return { prUrl: data.html_url, prNumber: data.number };\n}\n\nasync function createGitLabMR(opts: {\n remote: RemoteInfo;\n title: string;\n body: string;\n head: string;\n base: string;\n token: string;\n insecure?: boolean;\n}): Promise<{ prUrl: string; prNumber: number }> {\n const { host, owner, repo } = opts.remote;\n const projectPath = encodeURIComponent(`${owner}/${repo}`);\n const body = JSON.stringify({\n title: opts.title,\n description: opts.body,\n source_branch: opts.head,\n target_branch: opts.base,\n });\n const { status, text } = await httpsPost(\n `https://${host}/api/v4/projects/${projectPath}/merge_requests`,\n {\n Authorization: `Bearer ${opts.token}`,\n \"Content-Type\": \"application/json\",\n },\n body,\n { insecure: opts.insecure },\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`pr-create: GitLab API error ${status}: ${text}`);\n }\n const data = JSON.parse(text) as { web_url: string; iid: number };\n return { prUrl: data.web_url, prNumber: data.iid };\n}\n\n/**\n * @deprecated Import BranchType from branch-type.ts instead\n */\nexport type BranchType = \"feat\" | \"fix\" | \"chore\" | \"refactor\" | \"docs\" | \"test\" | \"style\" | \"perf\";\n\n/**\n * @deprecated Use detectTypeFromJiraIssueType or detectTypeFromLinearLabels from branch-type.ts instead\n */\nexport function mapIssueTypeToBranchType(issueType?: string): BranchType | null {\n if (!issueType) return null;\n\n const normalized = issueType.toLowerCase();\n\n // Map common issue type names to conventional prefixes\n if (normalized.includes(\"bug\") || normalized.includes(\"fix\")) return \"fix\";\n if (normalized.includes(\"feature\") || normalized.includes(\"story\") || normalized.includes(\"enhancement\")) return \"feat\";\n if (normalized.includes(\"chore\") || normalized.includes(\"task\")) return \"chore\";\n if (normalized.includes(\"refactor\")) return \"refactor\";\n if (normalized.includes(\"doc\")) return \"docs\";\n if (normalized.includes(\"test\")) return \"test\";\n if (normalized.includes(\"style\")) return \"style\";\n if (normalized.includes(\"perf\") || normalized.includes(\"performance\")) return \"perf\";\n\n return null;\n}\n\n/**\n * @deprecated Use deriveBranchNameWithType from branch-type.ts instead\n */\nexport function deriveBranchName(spec: SpecPayload, branchType: BranchType): string {\n switch (spec.source) {\n case \"jira\":\n return `${branchType}/${spec.issueKey}`;\n case \"linear\":\n return `${branchType}/${spec.issueId}`;\n case \"markdown\": {\n const slug = spec.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n return `${branchType}/${slug}`;\n }\n }\n}\n\nexport function buildCommitMessage(context: TaskContext, branchType: CanonicalBranchType): string {\n const spec = context.spec;\n const plan = context.plan;\n\n let scope: string | null = null;\n switch (spec.source) {\n case \"jira\":\n scope = spec.issueKey;\n break;\n case \"linear\":\n scope = spec.issueId;\n break;\n case \"markdown\":\n scope = null;\n break;\n }\n\n const subject = scope\n ? `${branchType}(${scope}): ${spec.title}`\n : `${branchType}: ${spec.title}`;\n\n if (!plan) return subject;\n\n const lines = [subject, \"\"];\n if (plan.goals.length > 0) {\n lines.push(\"Goals:\");\n for (const g of plan.goals) lines.push(`- ${g}`);\n lines.push(\"\");\n }\n if (plan.tasks.length > 0) {\n lines.push(\"Tasks:\");\n for (const t of plan.tasks) lines.push(`- ${t}`);\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function buildPRBody(context: TaskContext): string {\n const plan = context.plan;\n const impl = context.implement;\n const security = context.securityReview;\n\n const sections: string[] = [];\n\n sections.push(\"## Summary\");\n sections.push(\"\");\n sections.push(context.spec.title);\n sections.push(\"\");\n\n if (plan) {\n if (plan.goals.length > 0) {\n sections.push(\"## Goals\");\n sections.push(\"\");\n for (const g of plan.goals) sections.push(`- ${g}`);\n sections.push(\"\");\n }\n if (plan.tasks.length > 0) {\n sections.push(\"## Tasks\");\n sections.push(\"\");\n for (const t of plan.tasks) sections.push(`- [x] ${t}`);\n sections.push(\"\");\n }\n }\n\n if (impl) {\n const devFiles = impl.dev?.files ?? [];\n if (devFiles.length > 0) {\n sections.push(\"## Files Changed\");\n sections.push(\"\");\n for (const f of devFiles) sections.push(`- \\`${f}\\``);\n sections.push(\"\");\n }\n\n const testFiles = impl.qe?.testFiles ?? [];\n if (testFiles.length > 0) {\n sections.push(\"## Test Files\");\n sections.push(\"\");\n for (const f of testFiles) sections.push(`- \\`${f}\\``);\n sections.push(\"\");\n }\n }\n\n\n const prReview = context.prReview;\n if (prReview) {\n sections.push(\"## PR Review\");\n sections.push(\"\");\n sections.push(prReview.summary);\n sections.push(\"\");\n\n if (prReview.comments.length > 0) {\n sections.push(\"### Review Comments\");\n sections.push(\"\");\n\n const byFile = new Map<string, typeof prReview.comments>();\n for (const c of prReview.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n for (const [file, comments] of byFile) {\n sections.push(`**${file}**`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n sections.push(`- \\`${file}${lineRef}\\`: ${c.comment}`);\n }\n sections.push(\"\");\n }\n }\n\n if (prReview.recommendedActions.length > 0) {\n sections.push(\"### Recommended Actions\");\n sections.push(\"\");\n for (const action of prReview.recommendedActions) {\n sections.push(`- ${action}`);\n }\n sections.push(\"\");\n }\n }\n\n sections.push(\"---\");\n sections.push(\"*Created by [reygent](https://github.com/andrewevans0102/reygent)*\");\n\n return sections.join(\"\\n\");\n}\n\nexport async function runPRCreate(\n context: TaskContext,\n opts?: { insecure?: boolean; branchType?: BranchType },\n): Promise<PRCreateOutput> {\n loadEnvFile();\n\n const { stdout: remoteUrlForToken } = await exec(\"git\", [\n \"remote\",\n \"get-url\",\n \"origin\",\n ]);\n const remoteForToken = parseRemote(remoteUrlForToken);\n const token = await resolveToken(remoteForToken.host);\n\n if (!opts?.branchType) {\n throw new TaskError(\"pr-create: branchType is required\");\n }\n\n const branch = deriveBranchName(context.spec, opts.branchType);\n const commitMessage = buildCommitMessage(context, opts.branchType);\n const prBody = buildPRBody(context);\n const prTitle = context.spec.title;\n\n // Get default branch\n let baseBranch: string;\n try {\n const { stdout: defaultBranch } = await exec(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n baseBranch = defaultBranch.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: auto-set origin/HEAD and retry\n try {\n await exec(\"git\", [\"remote\", \"set-head\", \"origin\", \"-a\"]);\n const { stdout: defaultBranch } = await exec(\"git\", [\n \"symbolic-ref\",\n \"refs/remotes/origin/HEAD\",\n ]);\n baseBranch = defaultBranch.trim().replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Final fallback: try common default branches\n const { stdout: branches } = await exec(\"git\", [\n \"branch\",\n \"-r\",\n \"--list\",\n \"origin/main\",\n \"origin/master\",\n ]);\n const match = branches.trim().match(/origin\\/(main|master)/);\n if (match) {\n baseBranch = match[1];\n } else {\n throw new TaskError(\n \"pr-create: cannot determine default branch. Set with: git remote set-head origin <branch>\",\n );\n }\n }\n }\n\n // Stage all changes\n await exec(\"git\", [\"add\", \"-A\"]);\n\n // Verify there's something to commit\n const { stdout: status } = await exec(\"git\", [\"status\", \"--porcelain\"]);\n if (!status.trim()) {\n throw new TaskError(\"pr-create: no changes to commit\");\n }\n\n // Check if branch exists locally\n const { stdout: localBranches } = await exec(\"git\", [\"branch\", \"--list\", branch]);\n const branchExists = localBranches.trim().length > 0;\n\n if (branchExists) {\n // Delete existing local branch\n try {\n await exec(\"git\", [\"branch\", \"-D\", branch]);\n } catch {\n // If deletion fails, branch might be current branch - ignore\n }\n }\n\n // Create branch and commit\n const trace = getChesstrace();\n await exec(\"git\", [\"checkout\", \"-b\", branch]);\n try { trace.emit(Events.GIT_BRANCH_CREATE, { branch }); } catch { /* swallow */ }\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n try { trace.emit(Events.GIT_COMMIT, { branch, messageSubject: commitMessage.split('\\n')[0] }); } catch { /* swallow */ }\n\n // Check if branch exists remotely and delete it\n try {\n const { stdout: remoteBranches } = await exec(\"git\", [\n \"ls-remote\",\n \"--heads\",\n \"origin\",\n branch,\n ]);\n if (remoteBranches.trim().length > 0) {\n // Remote branch exists - delete it\n await exec(\"git\", [\"push\", \"origin\", \"--delete\", branch]);\n }\n } catch {\n // Remote branch doesn't exist or delete failed - continue\n }\n\n // Push with timeout\n try {\n await exec(\"git\", [\"push\", \"-u\", \"origin\", branch], { timeout: 60_000 });\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n } catch (pushErr) {\n try { trace.emit(Events.GIT_ERROR, { operation: \"push\", error: pushErr instanceof Error ? pushErr.message : String(pushErr) }); } catch { /* swallow */ }\n throw pushErr;\n }\n\n const { prUrl, prNumber } = await createPR({\n remote: remoteForToken,\n title: prTitle,\n body: prBody,\n head: branch,\n base: baseBranch,\n token,\n insecure: opts?.insecure,\n });\n\n return { branch, commitMessage, prUrl, prNumber };\n}\n","import type { SpecPayload } from \"./spec.js\";\n\n/**\n * Valid conventional commit type prefixes for branch names\n */\nexport const VALID_BRANCH_TYPES = [\n \"feat\",\n \"fix\",\n \"chore\",\n \"refactor\",\n \"docs\",\n \"test\",\n \"style\",\n \"perf\",\n] as const;\n\nexport type BranchType = typeof VALID_BRANCH_TYPES[number];\n\n/**\n * Long-form aliases that normalize to short conventional types\n */\nconst TYPE_ALIASES: Record<string, BranchType> = {\n feature: \"feat\",\n bugfix: \"fix\",\n};\n\n/**\n * Normalize type input to canonical conventional commit prefix\n * @throws Error if type is invalid\n */\nexport function normalizeType(type: string): BranchType {\n const lower = type.toLowerCase().trim();\n\n // Check if it's a long-form alias\n if (lower in TYPE_ALIASES) {\n return TYPE_ALIASES[lower];\n }\n\n // Check if it's already a valid type\n if (VALID_BRANCH_TYPES.includes(lower as BranchType)) {\n return lower as BranchType;\n }\n\n throw new Error(\n `Invalid branch type: ${type}. Valid types: ${VALID_BRANCH_TYPES.join(\", \")}, feature, bugfix`\n );\n}\n\n/**\n * Check if a type string is valid (without throwing)\n */\nexport function isValidType(type: string): boolean {\n try {\n normalizeType(type);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Detect branch type from Jira issue type field\n * Uses partial matching (e.g., \"Bug Fix\" matches \"bug\")\n * Returns null if type cannot be mapped\n */\nexport function detectTypeFromJiraIssueType(issueType: string): BranchType | null {\n const lower = issueType.toLowerCase();\n\n if (lower.includes(\"bug\") || lower.includes(\"fix\")) return \"fix\";\n if (lower.includes(\"story\") || lower.includes(\"feature\") || lower.includes(\"enhancement\")) return \"feat\";\n if (lower.includes(\"task\") || lower.includes(\"chore\")) return \"chore\";\n if (lower.includes(\"refactor\") || lower.includes(\"technical debt\")) return \"refactor\";\n if (lower.includes(\"doc\")) return \"docs\";\n if (lower.includes(\"test\")) return \"test\";\n if (lower.includes(\"style\")) return \"style\";\n if (lower.includes(\"perf\") || lower.includes(\"performance\")) return \"perf\";\n\n return null;\n}\n\n/**\n * Detect branch type from Linear issue labels\n * Returns null if no matching label found\n * Priority order: bug > feature > others\n */\nexport function detectTypeFromLinearLabels(labels: string[]): BranchType | null {\n const lower = labels.map(l => l.toLowerCase());\n\n // Priority order: bug > feature > others\n if (lower.some(l => l.includes(\"bug\"))) return \"fix\";\n if (lower.some(l => l.includes(\"feature\"))) return \"feat\";\n if (lower.some(l => l.includes(\"chore\") || l.includes(\"maintenance\"))) return \"chore\";\n if (lower.some(l => l.includes(\"refactor\") || l.includes(\"tech-debt\"))) return \"refactor\";\n if (lower.some(l => l.includes(\"doc\"))) return \"docs\";\n\n return null;\n}\n\n/**\n * Derive branch name with type prefix from spec payload\n * @param spec - Spec payload from jira, linear, or markdown\n * @param type - Branch type prefix\n * @returns Full branch name like \"feat/PROJ-123\" or \"fix/add-user-auth\"\n */\nexport function deriveBranchNameWithType(spec: SpecPayload, type: BranchType): string {\n const prefix = type;\n\n if (spec.source === \"jira\") {\n return `${prefix}/${spec.issueKey}`;\n }\n\n if (spec.source === \"linear\") {\n return `${prefix}/${spec.issueId}`;\n }\n\n // Markdown source - slugify title\n const slug = spec.title\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 60);\n\n return `${prefix}/${slug}`;\n}\n\n/**\n * Derive branch name from spec with type detection\n * Tries auto-detection from issueType/labels, falls back to typeOverride\n * @throws Error if no type can be determined\n */\nexport function deriveBranchFromSpec(\n spec: SpecPayload,\n typeOverride?: string,\n): string {\n let type: BranchType | null = null;\n\n // CLI flag takes priority\n if (typeOverride) {\n type = normalizeType(typeOverride);\n } else {\n // Try auto-detection\n if (spec.source === \"jira\" && spec.issueType) {\n type = detectTypeFromJiraIssueType(spec.issueType);\n } else if (spec.source === \"linear\" && \"labels\" in spec && spec.labels) {\n type = detectTypeFromLinearLabels(spec.labels);\n }\n }\n\n if (!type) {\n throw new Error(\"Branch type is required\");\n }\n\n return deriveBranchNameWithType(spec, type);\n}\n\n/**\n * Prompt user for branch type interactively\n * @param promptFn - Prompt function from @inquirer/prompts\n * @param detectedType - Optional auto-detected type to use as default\n * @param opts - Options including skipPrompt flag\n * @returns Normalized branch type\n */\nexport async function promptForType(\n promptFn: (config: {\n message: string;\n choices: { name: string; value: string }[];\n default?: string\n }) => Promise<string | null | undefined>,\n detectedType: BranchType | null,\n opts: { skipPrompt?: boolean } = {},\n): Promise<BranchType> {\n if (opts.skipPrompt) {\n if (!detectedType) {\n throw new Error(\"Branch type is required\");\n }\n return detectedType;\n }\n\n const choices = VALID_BRANCH_TYPES.map(t => ({ name: t, value: t }));\n const config = {\n message: \"Select branch type:\",\n choices,\n default: detectedType ?? undefined,\n };\n\n const response = await promptFn(config);\n\n if (response === null) {\n throw new Error(\"Branch creation cancelled\");\n }\n\n if (response === undefined || !response.trim()) {\n throw new Error(\"Branch type is required\");\n }\n\n return normalizeType(response.trim());\n}\n","import { execFile } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { wrapText } from \"./format.js\";\nimport { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type { PRReviewComment, PRReviewOutput, TaskContext } from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n} from \"./diff-split.js\";\n\ninterface PRReviewPromptInput {\n stat: string;\n log: string;\n includedDiffs: { file: string; diff: string }[];\n excludedFiles: string[];\n}\n\nfunction buildPRReviewPrompt(\n systemPrompt: string,\n context: TaskContext,\n input: PRReviewPromptInput,\n): string {\n const goals = context.plan?.goals ?? [];\n const tasks = context.plan?.tasks ?? [];\n\n let prompt = `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${context.spec.title}\n\n${context.spec.content}\n\n---\n\n## Planner Output\n\n**Goals:**\n${goals.length > 0 ? goals.map((g) => `- ${g}`).join(\"\\n\") : \"- (none)\"}\n\n**Tasks:**\n${tasks.length > 0 ? tasks.map((t) => `- ${t}`).join(\"\\n\") : \"- (none)\"}\n\n---\n\n## Branch Summary\n\n### Changed Files\n\n\\`\\`\\`\n${input.stat}\n\\`\\`\\`\n\n### Commits\n\n\\`\\`\\`\n${input.log}\n\\`\\`\\``;\n\n if (input.includedDiffs.length > 0) {\n prompt += `\n\n## File Diffs\n\n`;\n for (const f of input.includedDiffs) {\n prompt += `\\`\\`\\`diff\n${f.diff}\n\\`\\`\\`\n\n`;\n }\n }\n\n if (input.excludedFiles.length > 0) {\n prompt += `\n### Files not shown (too large for context)\n\n${input.excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n }\n\n prompt += `\n\n---\n\n## Instructions\n\n1. Review the changes above in the context of the spec and planner goals.\n2. Check for correctness, potential bugs, style issues, and whether the implementation meets the spec.\n3. For files not shown, note any concerns based on the stat summary and commit messages.\n4. When you are finished, output a single JSON block with your review:\n\n\\`\\`\\`json\n{\n \"summary\": \"Brief overall assessment of the PR\",\n \"comments\": [\n {\n \"file\": \"src/example.ts\",\n \"line\": 42,\n \"comment\": \"Description of the issue or suggestion\"\n }\n ],\n \"recommendedActions\": [\n \"Action item 1\",\n \"Action item 2\"\n ]\n}\n\\`\\`\\`\n\n- \\`summary\\` is a brief overall assessment of the PR.\n- \\`comments\\` is an array of inline review comments. \\`line\\` may be null if the comment applies to the whole file.\n- \\`recommendedActions\\` is a list of suggested follow-up actions.\n- Do NOT output any text after the JSON block.`;\n\n return prompt;\n}\n\nexport function extractPRReviewOutput(stdout: string): PRReviewOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(\n /\\{\\s*\"summary\"\\s*:\\s*\"[^\"]*\"[\\s\\S]*?\"recommendedActions\"\\s*:\\s*\\[[\\s\\S]*?\\]\\s*\\}/,\n );\n if (!match) {\n throw new TaskError(\n \"pr-review: failed to extract JSON output from agent response\",\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[0]);\n } catch {\n throw new TaskError(\"pr-review: extracted block is not valid JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n\n if (typeof obj.summary !== \"string\") {\n throw new TaskError(\"pr-review: 'summary' must be a string\");\n }\n\n if (!Array.isArray(obj.comments)) {\n throw new TaskError(\"pr-review: 'comments' must be an array\");\n }\n\n if (!Array.isArray(obj.recommendedActions)) {\n throw new TaskError(\"pr-review: 'recommendedActions' must be an array\");\n }\n\n const comments: PRReviewComment[] = (obj.comments as unknown[]).map(\n (c, i) => {\n const comment = c as Record<string, unknown>;\n if (typeof comment.file !== \"string\") {\n throw new TaskError(`pr-review: comments[${i}] missing 'file'`);\n }\n if (typeof comment.comment !== \"string\") {\n throw new TaskError(`pr-review: comments[${i}] missing 'comment'`);\n }\n return {\n file: comment.file,\n line: typeof comment.line === \"number\" ? comment.line : null,\n comment: comment.comment,\n };\n },\n );\n\n const recommendedActions = (obj.recommendedActions as unknown[]).map(\n (a, i) => {\n if (typeof a !== \"string\") {\n throw new TaskError(\n `pr-review: recommendedActions[${i}] must be a string`,\n );\n }\n return a;\n },\n );\n\n return { summary: obj.summary, comments, recommendedActions };\n}\n\nexport function formatPRReviewOutput(output: PRReviewOutput): string {\n const lines: string[] = [];\n\n lines.push(\"# 🐱 Reygent PR Review\");\n lines.push(\"\");\n lines.push(\"## Summary\");\n lines.push(output.summary);\n lines.push(\"\");\n\n if (output.comments.length > 0) {\n lines.push(\"## Comments\");\n\n const byFile = new Map<string, PRReviewComment[]>();\n for (const c of output.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n for (const [file, comments] of byFile) {\n lines.push(`\\n### ${file}`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n lines.push(` - ${file}${lineRef}: ${c.comment}`);\n }\n }\n lines.push(\"\");\n }\n\n if (output.recommendedActions.length > 0) {\n lines.push(\"## Recommended Actions\");\n for (const action of output.recommendedActions) {\n lines.push(` - ${action}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n\nexport function formatPRReviewTerminal(output: PRReviewOutput): string {\n const lines: string[] = [];\n const cols = process.stdout.columns || 80;\n\n lines.push(\"\");\n lines.push(chalk.cyan.bold(\"Summary\"));\n // summary indent = 2\n lines.push(` ${wrapText(output.summary, 2, cols)}`);\n lines.push(\"\");\n\n if (output.comments.length > 0) {\n lines.push(chalk.cyan.bold(`Comments (${output.comments.length}):`));\n\n const byFile = new Map<string, PRReviewComment[]>();\n for (const c of output.comments) {\n const group = byFile.get(c.file) ?? [];\n group.push(c);\n byFile.set(c.file, group);\n }\n\n // comment text indent = 6 (4 spaces + bullet + space)\n const commentIndent = 6;\n for (const [file, comments] of byFile) {\n lines.push(\"\");\n lines.push(` ${chalk.bold(file)}`);\n for (const c of comments) {\n const lineRef = c.line !== null ? `:${c.line}` : \"\";\n const prefix = lineRef ? `${lineRef} ` : \"\";\n const wrapped = wrapText(prefix + c.comment, commentIndent, cols);\n // Re-apply chalk to the line ref portion of first line\n const display = c.line !== null\n ? chalk.gray(`:${c.line}`) + \" \" + wrapped.slice(prefix.length)\n : wrapped;\n lines.push(` ${chalk.yellow(\"•\")} ${display}`);\n }\n }\n lines.push(\"\");\n }\n\n if (output.recommendedActions.length > 0) {\n lines.push(chalk.cyan.bold(\"Recommended Actions:\"));\n lines.push(\"\");\n // action indent = 4 (2 spaces + dash + space)\n for (const action of output.recommendedActions) {\n lines.push(` ${chalk.gray(\"-\")} ${wrapText(action, 4, cols)}`);\n }\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction exec(\n cmd: string,\n args: string[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 10 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `pr-review: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nfunction getDiff(prNumber: number): Promise<string> {\n return exec(\"gh\", [\"pr\", \"diff\", String(prNumber)]);\n}\n\n/** Get diff stat for a PR by diffing against the PR base branch */\nasync function getPRDiffStat(prNumber: number): Promise<string> {\n try {\n const baseBranch = (await exec(\"gh\", [\n \"pr\", \"view\", String(prNumber), \"--json\", \"baseRefName\", \"--jq\", \".baseRefName\",\n ])).trim();\n return (await exec(\"git\", [\"diff\", \"--stat\", `origin/${baseBranch}...HEAD`])).trim();\n } catch (err) {\n if (process.env.DEBUG) {\n console.warn(\"getPRDiffStat failed:\", err instanceof Error ? err.message : String(err));\n }\n return \"\";\n }\n}\n\n/** Get commit log for a PR by logging against the PR base branch */\nasync function getPRCommitLog(prNumber: number): Promise<string> {\n try {\n const baseBranch = (await exec(\"gh\", [\n \"pr\", \"view\", String(prNumber), \"--json\", \"baseRefName\", \"--jq\", \".baseRefName\",\n ])).trim();\n return (await exec(\"git\", [\"log\", `origin/${baseBranch}..HEAD`, \"--oneline\"])).trim();\n } catch (err) {\n if (process.env.DEBUG) {\n console.warn(\"getPRCommitLog failed:\", err instanceof Error ? err.message : String(err));\n }\n return \"\";\n }\n}\n\n/**\n * Detect PR number from current git branch via GitHub CLI.\n * Returns the PR number or throws if no PR is found.\n */\nasync function detectPRFromBranch(): Promise<{ prNumber: number; branch: string }> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch) {\n throw new TaskError(\n \"pr-review: not on a branch — cannot auto-detect PR number\",\n );\n }\n\n let prJson: string;\n try {\n prJson = await exec(\"gh\", [\"pr\", \"view\", \"--json\", \"number\", \"--jq\", \".number\"]);\n } catch {\n throw new TaskError(\n `pr-review: no open PR found for branch \"${branch}\". Create a PR first or provide a PR number.`,\n );\n }\n\n const prNumber = parseInt(prJson.trim(), 10);\n if (isNaN(prNumber) || prNumber <= 0) {\n throw new TaskError(\n `pr-review: could not parse PR number from branch \"${branch}\"`,\n );\n }\n\n return { prNumber, branch };\n}\n\n/**\n * Resolve the PR number from context or by detecting from the current branch.\n */\nasync function resolvePRNumber(context: TaskContext): Promise<number> {\n if (context.prCreate) {\n return context.prCreate.prNumber;\n }\n console.log(chalk.blue(\"No PR number provided — detecting from current branch...\"));\n const detected = await detectPRFromBranch();\n console.log(chalk.green(`Found PR #${detected.prNumber} on branch \"${detected.branch}\"`));\n return detected.prNumber;\n}\n\nexport async function runPRReview(\n context: TaskContext,\n options?: AgentSpawnOptions,\n): Promise<{ output: PRReviewOutput; usage?: UsageInfo }> {\n const prNumber = await resolvePRNumber(context);\n\n const agents = getAgents();\n const agent = agents.find((a) => a.name === \"pr-reviewer\");\n if (!agent) {\n throw new TaskError(\"pr-review: missing pr-reviewer agent config\");\n }\n\n const [diff, stat, log] = await Promise.all([\n getDiff(prNumber),\n getPRDiffStat(prNumber),\n getPRCommitLog(prNumber),\n ]);\n\n // Split diff by file and select within budget\n const fileDiffs = splitDiffByFile(diff);\n const reservedTokens = estimateTokens(agent.systemPrompt) + estimateTokens(stat) + estimateTokens(log) + 2000;\n const { included, excluded } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens);\n\n const prompt = buildPRReviewPrompt(agent.systemPrompt, context, {\n stat,\n log,\n includedDiffs: included,\n excludedFiles: excluded,\n });\n const result = await spawnAgent(\"pr-review\", prompt, { ...options, quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `pr-review: agent exited with code ${result.exitCode}`,\n );\n }\n\n return { output: extractPRReviewOutput(result.stdout), usage: result.usage };\n}\n\n/**\n * Post a formatted PR review as a comment on the pull request.\n */\nexport async function postPRReviewComment(\n context: TaskContext,\n review: PRReviewOutput,\n): Promise<void> {\n const prNumber = await resolvePRNumber(context);\n const body = formatPRReviewOutput(review) +\n \"\\n\\n---\\n*Review by [reygent](https://github.com/andrewevans0102/reygent)*\";\n await exec(\"gh\", [\"pr\", \"comment\", String(prNumber), \"--body\", body]);\n}\n","/**\n * Utilities for splitting unified diffs by file and selecting\n * per-file diffs within a token budget.\n */\n\nexport interface FileDiff {\n /** File path from the diff header (prefers b/ path) */\n file: string;\n /** Full unified diff text for this file, including header */\n diff: string;\n /** Estimated token count */\n tokens: number;\n}\n\n/**\n * Approximate tokens — ~4 chars per token.\n *\n * This is a rough average that works across most content types but can vary\n * significantly depending on the text characteristics:\n * - Code with many identifiers/keywords may be closer to 3 chars/token\n * - Prose or repetitive patterns may be closer to 5 chars/token\n * - This estimation is intentionally conservative for budget calculations\n *\n * If budget decisions consistently exclude too many or too few files,\n * tune this ratio based on telemetry feedback and actual provider tokenization.\n */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Safe context budget across all providers (80k tokens).\n *\n * This conservative limit ensures reviews work reliably across all supported\n * providers while leaving headroom for:\n * - Prompt instructions and templates (~2-3k tokens)\n * - Review comment formatting and metadata (~1-2k tokens)\n * - Provider response generation (reviews can be lengthy)\n *\n * Provider-specific context windows:\n * - Claude Opus 4.6: 200k tokens\n * - Claude Sonnet 3.5: 200k tokens\n * - Gemini 2.0 Flash: 1M tokens\n * - GPT-4 Turbo: 128k tokens\n *\n * The 80k limit is set well below the smallest provider window (GPT-4 Turbo)\n * to ensure consistent behavior. For very large PRs (100+ files, 10k+ lines),\n * consider splitting into multiple focused reviews or increasing this constant\n * after validating against real-world telemetry data.\n */\nexport const MAX_REVIEW_TOKENS = 80_000;\n\n/**\n * Reserved token overhead for prompt templates and formatting.\n *\n * This accounts for:\n * - Review prompt instructions and structure (~1k tokens)\n * - Comment formatting and metadata (~500-1k tokens)\n * - Headroom for prompt template expansion (~500 tokens)\n *\n * If prompt templates grow significantly, increase this value or calculate\n * dynamically from actual prompt size.\n */\nexport const RESERVED_PROMPT_TOKENS = 2_000;\n\n/**\n * Split a unified diff into per-file chunks.\n * Each chunk starts with `diff --git` and includes everything\n * up to (but not including) the next `diff --git`.\n */\nexport function splitDiffByFile(rawDiff: string): FileDiff[] {\n if (!rawDiff.trim()) return [];\n\n const files: FileDiff[] = [];\n // Split on diff headers, keeping the delimiter\n const parts = rawDiff.split(/^(?=diff --git )/m);\n\n for (const part of parts) {\n const trimmed = part.trim();\n if (!trimmed || !trimmed.startsWith(\"diff --git \")) continue;\n\n // Extract file path from \"diff --git a/path b/path\"\n const headerMatch = trimmed.match(/^diff --git a\\/(.+?) b\\/(.+)/m);\n const file = headerMatch ? headerMatch[2] : \"unknown\";\n\n files.push({\n file,\n diff: trimmed,\n tokens: estimateTokens(trimmed),\n });\n }\n\n return files;\n}\n\n/**\n * Greedily select file diffs that fit within a token budget.\n * Returns included diffs and names of excluded files.\n */\nexport function selectDiffsWithinBudget(\n files: FileDiff[],\n budgetTokens: number,\n reservedTokens: number,\n): { included: FileDiff[]; excluded: string[] } {\n const available = budgetTokens - reservedTokens;\n const included: FileDiff[] = [];\n const excluded: string[] = [];\n let used = 0;\n\n for (const f of files) {\n if (used + f.tokens <= available) {\n included.push(f);\n used += f.tokens;\n } else {\n excluded.push(f.file);\n }\n }\n\n return { included, excluded };\n}\n","import chalk from \"chalk\";\nimport { getAgents } from \"./config.js\";\nimport { wrapText } from \"./format.js\";\nimport { spawnAgent, type AgentSpawnOptions } from \"./implement.js\";\nimport { extractJSON } from \"./planner.js\";\nimport type {\n Severity,\n SecurityFinding,\n SecurityReviewOutput,\n TaskContext,\n} from \"./task.js\";\nimport { TaskError } from \"./task.js\";\nimport type { UsageInfo } from \"./usage.js\";\n\nconst SEVERITY_ORDER: Record<Severity, number> = {\n LOW: 0,\n MEDIUM: 1,\n HIGH: 2,\n CRITICAL: 3,\n};\n\nexport function severityAtOrAbove(\n severity: Severity,\n threshold: Severity,\n): boolean {\n return SEVERITY_ORDER[severity] >= SEVERITY_ORDER[threshold];\n}\n\nfunction buildSecurityReviewPrompt(\n systemPrompt: string,\n context: TaskContext,\n): string {\n const devFiles = context.implement?.dev?.files ?? [];\n const qeFiles = context.implement?.qe?.testFiles ?? [];\n\n return `${systemPrompt}\n\n---\n\n## Spec\n\n**Title:** ${context.spec.title}\n\n${context.spec.content}\n\n---\n\n## Files to review\n\n**Implementation files (dev):**\n${devFiles.length > 0 ? devFiles.map((f) => `- ${f}`).join(\"\\n\") : \"- (none)\"}\n\n**Test files (qe):**\n${qeFiles.length > 0 ? qeFiles.map((f) => `- ${f}`).join(\"\\n\") : \"- (none)\"}\n\n---\n\n## Instructions\n\n1. Read each file listed above.\n2. Analyse the code for security vulnerabilities, including but not limited to the OWASP Top 10: injection, broken authentication, sensitive data exposure, XXE, broken access control, security misconfiguration, XSS, insecure deserialization, using components with known vulnerabilities, and insufficient logging.\n3. For each finding, assign a severity: CRITICAL, HIGH, MEDIUM, or LOW.\n4. When you are finished, output a single JSON block with your findings:\n\n\\`\\`\\`json\n{\n \"severity\": \"HIGH\",\n \"findings\": [\n {\n \"severity\": \"HIGH\",\n \"description\": \"SQL injection in user input handler\",\n \"location\": { \"file\": \"src/db.ts\", \"line\": 42 }\n }\n ]\n}\n\\`\\`\\`\n\n- The top-level \\`severity\\` is the highest severity among all findings, or \"LOW\" if there are no findings.\n- If no issues are found, return \\`{ \"severity\": \"LOW\", \"findings\": [] }\\`.\n- Do NOT output any text after the JSON block.`;\n}\n\nexport function extractSecurityReviewOutput(\n stdout: string,\n): SecurityReviewOutput {\n const cleaned = extractJSON(stdout);\n const match = cleaned.match(\n /\\{\\s*\"severity\"\\s*:\\s*\"[^\"]+\"\\s*,\\s*\"findings\"\\s*:\\s*\\[[\\s\\S]*?\\]\\s*\\}/,\n );\n if (!match) {\n throw new TaskError(\n \"security-review: failed to extract JSON output from agent response\",\n );\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(match[0]);\n } catch {\n throw new TaskError(\n \"security-review: extracted block is not valid JSON\",\n );\n }\n\n const obj = parsed as Record<string, unknown>;\n\n const validSeverities = new Set([\"CRITICAL\", \"HIGH\", \"MEDIUM\", \"LOW\"]);\n\n if (typeof obj.severity !== \"string\" || !validSeverities.has(obj.severity)) {\n throw new TaskError(\n \"security-review: invalid top-level severity in output\",\n );\n }\n\n if (!Array.isArray(obj.findings)) {\n throw new TaskError(\"security-review: 'findings' must be an array\");\n }\n\n const findings: SecurityFinding[] = (obj.findings as unknown[]).map(\n (f, i) => {\n const finding = f as Record<string, unknown>;\n if (\n typeof finding.severity !== \"string\" ||\n !validSeverities.has(finding.severity)\n ) {\n throw new TaskError(\n `security-review: finding[${i}] has invalid severity`,\n );\n }\n if (typeof finding.description !== \"string\") {\n throw new TaskError(\n `security-review: finding[${i}] missing description`,\n );\n }\n\n const result: SecurityFinding = {\n severity: finding.severity as Severity,\n description: finding.description,\n };\n\n if (finding.location && typeof finding.location === \"object\") {\n const loc = finding.location as Record<string, unknown>;\n if (typeof loc.file === \"string\") {\n result.location = {\n file: loc.file,\n ...(typeof loc.line === \"number\" ? { line: loc.line } : {}),\n };\n }\n }\n\n return result;\n },\n );\n\n return { severity: obj.severity as Severity, findings };\n}\n\nexport function formatFindings(\n findings: SecurityFinding[],\n threshold: Severity,\n): string {\n if (findings.length === 0) {\n return chalk.gray(\" No findings.\");\n }\n\n return findings\n .map((f) => {\n const isBlocking = severityAtOrAbove(f.severity, threshold);\n const marker = isBlocking ? chalk.red.bold(\"!! \") : \" \";\n\n let severityLabel: string;\n switch (f.severity) {\n case \"CRITICAL\":\n severityLabel = chalk.red.bold(`[${f.severity}]`);\n break;\n case \"HIGH\":\n severityLabel = chalk.red(`[${f.severity}]`);\n break;\n case \"MEDIUM\":\n severityLabel = chalk.yellow(`[${f.severity}]`);\n break;\n case \"LOW\":\n severityLabel = chalk.blue(`[${f.severity}]`);\n break;\n }\n\n const loc = f.location\n ? chalk.gray(\n ` (${f.location.file}${f.location.line ? `:${f.location.line}` : \"\"})`,\n )\n : \"\";\n\n const cols = process.stdout.columns || 80;\n // marker (3) + severity label visible width (~8) + space = ~12 indent\n const indent = 12;\n return `${marker}${severityLabel} ${wrapText(f.description, indent, cols)}${loc}`;\n })\n .join(\"\\n\");\n}\n\nexport async function runSecurityReview(\n context: TaskContext,\n threshold: Severity,\n options?: AgentSpawnOptions,\n): Promise<{ output: SecurityReviewOutput; passed: boolean; usage?: UsageInfo }> {\n const agents = getAgents();\n const agent = agents.find((a) => a.name === \"security-reviewer\");\n if (!agent) {\n throw new TaskError(\"security-review: missing security-reviewer agent config\");\n }\n\n const prompt = buildSecurityReviewPrompt(agent.systemPrompt, context);\n const result = await spawnAgent(\"security-review\", prompt, { ...options, quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `security-review: agent exited with code ${result.exitCode}`,\n );\n }\n\n const output = extractSecurityReviewOutput(result.stdout);\n\n const hasBlockingFinding = output.findings.some((f) =>\n severityAtOrAbove(f.severity, threshold),\n );\n\n return { output, passed: !hasBlockingFinding, usage: result.usage };\n}\n","import chalk from \"chalk\";\nimport { wrapText } from \"./format.js\";\nimport { PROVIDER_PRICING, type ProviderName } from \"./pricing.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\n\nexport interface UsageInfo {\n costUsd?: number;\n durationMs?: number;\n numTurns?: number;\n inputTokens?: number;\n outputTokens?: number;\n cachedTokens?: number;\n cacheWriteTokens?: number;\n cacheDiscount?: number;\n provider?: ProviderName;\n}\n\nexport interface AgentUsageEntry {\n agent: string;\n stage: string;\n usage: UsageInfo;\n}\n\nexport class UsageTracker {\n private entries: AgentUsageEntry[] = [];\n\n record(agent: string, stage: string, usage: UsageInfo): void {\n this.entries.push({ agent, stage, usage });\n\n // Emit telemetry events (no-op if telemetry disabled)\n const chesstrace = getChesstrace();\n if (!chesstrace || !chesstrace.isEnabled()) {\n return;\n }\n\n // Emit usage.tokens event\n chesstrace.emit(Events.USAGE_TOKENS, {\n agent,\n stage,\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n cachedTokens: usage.cachedTokens ?? 0,\n cacheWriteTokens: usage.cacheWriteTokens ?? 0,\n provider: usage.provider,\n });\n\n // Calculate cache savings and emit usage.cost event\n const cacheSavingsUsd = calculateCacheSavings(usage);\n chesstrace.emit(Events.USAGE_COST, {\n agent,\n stage,\n costUsd: usage.costUsd,\n cacheSavingsUsd,\n });\n }\n\n getTotalCost(): number {\n return this.entries.reduce((sum, e) => sum + (e.usage.costUsd ?? 0), 0);\n }\n\n getByAgent(): Map<string, { cost: number; inputTokens: number; outputTokens: number; cachedTokens: number; cacheWriteTokens: number; calls: number; provider?: ProviderName }> {\n const map = new Map<string, { cost: number; inputTokens: number; outputTokens: number; cachedTokens: number; cacheWriteTokens: number; calls: number; provider?: ProviderName }>();\n for (const entry of this.entries) {\n const existing = map.get(entry.agent) ?? { cost: 0, inputTokens: 0, outputTokens: 0, cachedTokens: 0, cacheWriteTokens: 0, calls: 0 };\n existing.cost += entry.usage.costUsd ?? 0;\n existing.inputTokens += entry.usage.inputTokens ?? 0;\n existing.outputTokens += entry.usage.outputTokens ?? 0;\n existing.cachedTokens += entry.usage.cachedTokens ?? 0;\n existing.cacheWriteTokens += entry.usage.cacheWriteTokens ?? 0;\n existing.calls += 1;\n if (entry.usage.provider) existing.provider = entry.usage.provider;\n map.set(entry.agent, existing);\n }\n return map;\n }\n\n getEntries(): AgentUsageEntry[] {\n return [...this.entries];\n }\n}\n\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n if (minutes === 0) return `${seconds}s`;\n return `${minutes}m ${seconds}s`;\n}\n\nfunction formatCost(usd: number): string {\n if (usd > 0 && usd < 0.01) return `$${usd.toFixed(4)}`;\n return `$${usd.toFixed(2)}`;\n}\n\nfunction formatTokenCount(n: number): string {\n if (n >= 1000) {\n return n.toLocaleString(\"en-US\");\n }\n return String(n);\n}\n\n\n/** Estimate dollar savings from cached tokens for a single entry. */\nexport function calculateCacheSavings(usage: UsageInfo): number {\n // OpenRouter reports cacheDiscount as a dollar amount — use directly when cachedTokens is absent\n if (usage.cacheDiscount && usage.cacheDiscount > 0 && (usage.cachedTokens ?? 0) === 0) {\n return usage.cacheDiscount;\n }\n const cached = usage.cachedTokens ?? 0;\n if (cached === 0) return 0;\n const provider = usage.provider ?? \"claude\";\n const discount = PROVIDER_PRICING[provider]?.cacheDiscountRate ?? 0.50;\n const costPerMillion = PROVIDER_PRICING[provider]?.inputCostPerMillion ?? 3.00;\n return (cached / 1_000_000) * costPerMillion * discount;\n}\n\n/** Providers where caching is reliable enough to warn when absent. */\nconst CACHE_WARN_PROVIDERS = new Set<ProviderName>([\"claude\", \"codex\"]);\n\n/**\n * Print warnings if caching appears inactive for providers that support it.\n * Only warns when inputTokens > 0 and cachedTokens is 0.\n */\nexport function printCacheWarnings(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n const warned = new Set<string>();\n\n for (const entry of entries) {\n const { agent, usage } = entry;\n const provider = usage.provider;\n if (!provider || !CACHE_WARN_PROVIDERS.has(provider)) continue;\n if (warned.has(agent)) continue;\n\n const hasInput = (usage.inputTokens ?? 0) > 0;\n const noCacheHit = (usage.cachedTokens ?? 0) === 0;\n if (hasInput && noCacheHit) {\n console.error(\n chalk.yellow(\"⚠\") +\n chalk.yellow(` [${agent}] Prompt caching appears inactive for ${provider} provider. `) +\n chalk.yellow(\"Repeated context is not being cached — costs may be higher than expected.\"),\n );\n warned.add(agent);\n }\n }\n}\n\nexport function printUsageSummary(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n if (entries.length === 0) return;\n\n const totalCost = tracker.getTotalCost();\n const totalDuration = entries.reduce((sum, e) => sum + (e.usage.durationMs ?? 0), 0);\n const totalInput = entries.reduce((sum, e) => sum + (e.usage.inputTokens ?? 0), 0);\n const totalOutput = entries.reduce((sum, e) => sum + (e.usage.outputTokens ?? 0), 0);\n const totalCached = entries.reduce((sum, e) => sum + (e.usage.cachedTokens ?? 0), 0);\n const totalSavings = entries.reduce((sum, e) => sum + calculateCacheSavings(e.usage), 0);\n const byAgent = tracker.getByAgent();\n\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Usage Summary\"));\n console.log(chalk.cyan(\"│\") + ` Total cost: ${chalk.bold(formatCost(totalCost))}`);\n console.log(chalk.cyan(\"│\") + ` Duration: ${formatDuration(totalDuration)}`);\n if (totalInput > 0 || totalOutput > 0) {\n const cachedSuffix = totalCached > 0\n ? ` / ${formatTokenCount(totalCached)} cached`\n : \"\";\n console.log(chalk.cyan(\"│\") + ` Tokens: ${formatTokenCount(totalInput)} in / ${formatTokenCount(totalOutput)} out${cachedSuffix}`);\n }\n if (totalSavings > 0 && Math.round(totalSavings * 100) >= 1) {\n console.log(chalk.cyan(\"│\") + ` Cache saves: ${chalk.green(formatCost(totalSavings))}`);\n }\n console.log(chalk.cyan(\"│\"));\n console.log(chalk.cyan(\"│\") + ` By agent:`);\n\n for (const [agent, stats] of byAgent) {\n const callLabel = stats.calls === 1 ? \"1 call\" : `${stats.calls} calls`;\n const prefix = chalk.cyan(\"│\") + \" \";\n\n // First line: agent name, cost, calls\n console.log(prefix + `${agent.padEnd(12)} ${formatCost(stats.cost).padStart(7)} (${callLabel})`);\n\n // Second line: token breakdown (if present)\n if (stats.inputTokens > 0 || stats.outputTokens > 0) {\n const tokenParts: string[] = [];\n tokenParts.push(`${formatTokenCount(stats.inputTokens)} in`);\n tokenParts.push(`${formatTokenCount(stats.outputTokens)} out`);\n if (stats.cachedTokens > 0) {\n tokenParts.push(`${formatTokenCount(stats.cachedTokens)} cached`);\n }\n console.log(prefix + chalk.gray(` ${tokenParts.join(\" / \")}`));\n }\n\n // Third line: cache savings and hit rate (if present)\n const agentSavings = stats.cachedTokens > 0 && stats.provider\n ? calculateCacheSavings({ cachedTokens: stats.cachedTokens, provider: stats.provider })\n : 0;\n const hitRate = stats.inputTokens > 0 && stats.cachedTokens > 0\n ? Math.round((stats.cachedTokens / stats.inputTokens) * 100)\n : 0;\n\n if (agentSavings > 0 || hitRate > 0) {\n const parts: string[] = [];\n if (agentSavings > 0) parts.push(chalk.green(formatCost(agentSavings) + \" saved\"));\n if (hitRate > 0) parts.push(chalk.green(hitRate + \"% hit\"));\n console.log(prefix + ` ${parts.join(\" \")}`);\n }\n }\n\n console.log(chalk.cyan(\"└─\"));\n\n // Print cache warnings after summary\n printCacheWarnings(tracker);\n}\n\nexport function printVerboseUsage(tracker: UsageTracker): void {\n const entries = tracker.getEntries();\n if (entries.length === 0) return;\n\n console.log(\"\");\n console.log(chalk.bold.cyan(\"┌─ Detailed Usage\") + chalk.gray(\" (--verbose)\"));\n\n for (const entry of entries) {\n const { agent, stage, usage } = entry;\n const tokens = (usage.inputTokens || usage.outputTokens)\n ? ` ${formatTokenCount(usage.inputTokens ?? 0)} in / ${formatTokenCount(usage.outputTokens ?? 0)} out`\n : \"\";\n console.log(\n chalk.cyan(\"│\") +\n ` ${chalk.bold(agent)} ${chalk.gray(`(${stage})`)} ` +\n `${formatCost(usage.costUsd ?? 0)} ${formatDuration(usage.durationMs ?? 0)} ${usage.numTurns ?? 0} turns${tokens}`,\n );\n\n // Show cache metadata in verbose mode\n const hasCacheData = (usage.cachedTokens ?? 0) > 0 || (usage.cacheWriteTokens ?? 0) > 0 || (usage.cacheDiscount ?? 0) > 0;\n if (hasCacheData) {\n const savings = calculateCacheSavings(usage);\n const parts: string[] = [];\n if (usage.cachedTokens !== undefined && usage.cachedTokens >= 0) parts.push(`cached: ${formatTokenCount(usage.cachedTokens)}`);\n if (usage.cacheWriteTokens !== undefined && usage.cacheWriteTokens >= 0) parts.push(`cache_write: ${formatTokenCount(usage.cacheWriteTokens)}`);\n if (usage.cacheDiscount !== undefined && usage.cacheDiscount > 0) parts.push(`cache_discount: ${formatCost(usage.cacheDiscount)}`);\n if (savings > 0) parts.push(`saved: ${formatCost(savings)}`);\n if (usage.provider) parts.push(`provider: ${usage.provider}`);\n console.log(\n chalk.cyan(\"│\") +\n ` ${chalk.gray(\"cache: { \" + parts.join(\", \") + \" }\")}`,\n );\n }\n }\n\n console.log(chalk.cyan(\"└─\"));\n}\n","export type ProviderName = \"claude\" | \"codex\" | \"openrouter\" | \"gemini\";\n\nexport interface ProviderPricing {\n /** Cost per 1M input tokens (USD) */\n inputCostPerMillion: number;\n /** Cost per 1M output tokens (USD) */\n outputCostPerMillion: number;\n /** Fraction saved on cached tokens (0.90 = 90% savings) */\n cacheDiscountRate: number;\n /** Whether provider supports prompt caching */\n supportsCaching: boolean;\n /** Default model this pricing applies to */\n defaultModel: string;\n /** URL to provider's pricing page for verification */\n pricingUrl: string;\n /** Date this pricing was last verified (ISO format) */\n lastVerified: string;\n}\n\nexport const PROVIDER_PRICING: Record<ProviderName, ProviderPricing> = {\n claude: {\n inputCostPerMillion: 3.00,\n outputCostPerMillion: 15.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"claude-sonnet-4-5-20250929\",\n pricingUrl: \"https://www.anthropic.com/pricing\",\n lastVerified: \"2026-05-08\",\n },\n codex: {\n inputCostPerMillion: 1.25,\n outputCostPerMillion: 10.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"gpt-5.4\",\n pricingUrl: \"https://openai.com/api/pricing/\",\n lastVerified: \"2026-05-08\",\n },\n openrouter: {\n inputCostPerMillion: 3.00,\n outputCostPerMillion: 15.00,\n cacheDiscountRate: 0.50,\n supportsCaching: true,\n defaultModel: \"anthropic/claude-sonnet-4-5\",\n pricingUrl: \"https://openrouter.ai/models\",\n lastVerified: \"2025-05-04\",\n },\n gemini: {\n inputCostPerMillion: 1.25,\n outputCostPerMillion: 10.00,\n cacheDiscountRate: 0.90,\n supportsCaching: true,\n defaultModel: \"gemini-2.5-pro\",\n pricingUrl: \"https://ai.google.dev/pricing\",\n lastVerified: \"2026-05-08\",\n },\n};\n","import type { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\n\nexport interface FailurePattern {\n pattern: string;\n occurrences: number;\n runIds: string[];\n agents: string[];\n lastSeen: number;\n suggestedEntry: string;\n}\n\nexport interface SuccessPattern {\n pattern: string;\n successRate: number;\n observations: number;\n lastSeen: number;\n suggestedEntry: string;\n}\n\n/**\n * Analyze telemetry for recurring failure patterns.\n * Groups error events by message pattern and agent.\n */\nexport function analyzeFailurePatterns(\n db: SqliteBackend,\n sinceMs: number,\n): FailurePattern[] {\n const events = db.getEvents();\n const errorEvents = events.filter(\n (e) =>\n e.category === \"error\" &&\n e.timestamp >= sinceMs &&\n (e.event === Events.ERROR_TASK || e.event === Events.AGENT_ERROR),\n );\n\n // Group by error message pattern\n const patterns = new Map<string, FailurePattern>();\n\n for (const event of errorEvents) {\n const message = event.data.message as string;\n const agent = event.data.agent as string;\n const runId = event.runId;\n\n if (!message || !agent) continue;\n\n // Extract pattern (first 100 chars of message, normalized)\n const pattern = normalizeErrorPattern(message);\n\n const existing = patterns.get(pattern);\n if (existing) {\n existing.occurrences++;\n if (!existing.runIds.includes(runId)) {\n existing.runIds.push(runId);\n }\n if (!existing.agents.includes(agent)) {\n existing.agents.push(agent);\n }\n existing.lastSeen = Math.max(existing.lastSeen, event.timestamp);\n } else {\n patterns.set(pattern, {\n pattern,\n occurrences: 1,\n runIds: [runId],\n agents: [agent],\n lastSeen: event.timestamp,\n suggestedEntry: generateFailureEntry(pattern, agent),\n });\n }\n }\n\n // Return patterns with >1 occurrence, sorted by frequency\n return Array.from(patterns.values())\n .filter((p) => p.occurrences > 1)\n .sort((a, b) => b.occurrences - a.occurrences);\n}\n\n/**\n * Analyze telemetry for success patterns.\n * Identifies high-success-rate agent/stage combinations and tool sequences.\n */\nexport function analyzeSuccessPatterns(\n db: SqliteBackend,\n sinceMs: number,\n minSuccessRate: number = 0.8,\n): SuccessPattern[] {\n const events = db.getEvents();\n const completeEvents = events.filter(\n (e) =>\n e.event === Events.AGENT_COMPLETE && e.timestamp >= sinceMs,\n );\n\n // Group by agent+stage\n const patterns = new Map<\n string,\n { successes: number; failures: number; lastSeen: number; toolSequences: string[][] }\n >();\n\n for (const event of completeEvents) {\n const agent = event.data.agent as string;\n const stage = (event.data.stage as string) || \"unknown\";\n const success = event.data.success as boolean;\n const runId = event.runId;\n\n const key = `${agent}:${stage}`;\n const existing = patterns.get(key) || {\n successes: 0,\n failures: 0,\n lastSeen: 0,\n toolSequences: [],\n };\n\n if (success) {\n existing.successes++;\n // Extract tool sequence for this successful run\n const toolSequence = extractToolSequence(events, runId, agent);\n if (toolSequence.length > 0) {\n existing.toolSequences.push(toolSequence);\n }\n } else {\n existing.failures++;\n }\n existing.lastSeen = Math.max(existing.lastSeen, event.timestamp);\n patterns.set(key, existing);\n }\n\n // Filter by success rate and convert to SuccessPattern\n const successPatterns: SuccessPattern[] = [];\n\n for (const [key, stats] of patterns.entries()) {\n const total = stats.successes + stats.failures;\n const successRate = stats.successes / total;\n\n if (successRate >= minSuccessRate && total >= 3) {\n const [agent, stage] = key.split(\":\");\n const commonSequence = findCommonToolSequence(stats.toolSequences);\n successPatterns.push({\n pattern: `${agent} in ${stage} stage`,\n successRate,\n observations: total,\n lastSeen: stats.lastSeen,\n suggestedEntry: generateSuccessEntry(agent, stage, successRate, total, commonSequence),\n });\n }\n }\n\n return successPatterns.sort((a, b) => b.successRate - a.successRate);\n}\n\n/**\n * Measure knowledge effectiveness by comparing success rates.\n * Returns success rate when knowledge consulted vs baseline.\n */\nexport function measureKnowledgeEffectiveness(db: SqliteBackend, sinceMs: number): {\n withKnowledge: number;\n baseline: number;\n improvement: number;\n consultedRuns: number;\n baselineRuns: number;\n} {\n const events = db.getEvents();\n\n // Get runs that consulted knowledge\n const knowledgeEvents = events.filter(\n (e) =>\n e.event === Events.KNOWLEDGE_CONSULTED && e.timestamp >= sinceMs,\n );\n const consultedRunIds = new Set(knowledgeEvents.map((e) => e.runId));\n\n // Get pipeline end events\n const pipelineEnds = events.filter(\n (e) =>\n e.event === Events.PIPELINE_END && e.timestamp >= sinceMs,\n );\n\n let consultedSuccess = 0;\n let consultedTotal = 0;\n let baselineSuccess = 0;\n let baselineTotal = 0;\n\n for (const event of pipelineEnds) {\n const success = event.data.success as boolean;\n const runId = event.runId;\n\n if (consultedRunIds.has(runId)) {\n consultedTotal++;\n if (success) consultedSuccess++;\n } else {\n baselineTotal++;\n if (success) baselineSuccess++;\n }\n }\n\n const withKnowledge = consultedTotal > 0 ? consultedSuccess / consultedTotal : 0;\n const baseline = baselineTotal > 0 ? baselineSuccess / baselineTotal : 0;\n const improvement = withKnowledge - baseline;\n\n return {\n withKnowledge,\n baseline,\n improvement,\n consultedRuns: consultedTotal,\n baselineRuns: baselineTotal,\n };\n}\n\n/**\n * Sanitize error message to remove sensitive data (tokens, paths, emails)\n */\nfunction sanitizeErrorMessage(message: string): string {\n return message\n // API keys, tokens, secrets (20+ alphanumeric chars with word boundaries to avoid base64 false positives)\n .replace(/\\b[A-Za-z0-9+/=_-]{20,}\\b/g, '[REDACTED_TOKEN]')\n // User home paths\n .replace(/\\/Users\\/[^/\\s]+/g, '/Users/***')\n .replace(/\\/home\\/[^/\\s]+/g, '/home/***')\n .replace(/C:\\\\Users\\\\[^\\\\]+/g, 'C:\\\\Users\\\\***')\n // Email addresses\n .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g, '***@***.***')\n // IP addresses\n .replace(/\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b/g, '***.***.***.**')\n // Common env var patterns\n .replace(/(password|secret|key|token|api[_-]?key)=[^\\s]+/gi, '$1=[REDACTED]');\n}\n\n/**\n * Normalize error message to pattern (first 100 chars, trimmed, sanitized)\n */\nfunction normalizeErrorPattern(message: string): string {\n const sanitized = sanitizeErrorMessage(message);\n return sanitized.slice(0, 100).trim();\n}\n\n/**\n * Generate failure entry template\n */\nfunction generateFailureEntry(pattern: string, agent: string): string {\n const today = new Date().toISOString().split(\"T\")[0];\n return `\n## ${pattern}\n**Occurrences**: X runs\n**Last seen**: ${today}\n**Agent**: ${agent}\n\n**Solution**: [Add solution description here]\n\n**Example**:\n\\`\\`\\`\n[Add code example here]\n\\`\\`\\`\n`;\n}\n\n/**\n * Generate success entry template\n */\nfunction generateSuccessEntry(\n agent: string,\n stage: string,\n successRate: number,\n observations: number,\n commonSequence?: string[],\n): string {\n const today = new Date().toISOString().split(\"T\")[0];\n const pct = Math.round(successRate * 100);\n const sequenceText = commonSequence && commonSequence.length > 0\n ? `\n\n**Common tool sequence**:\n${commonSequence.map((tool, i) => `${i + 1}. ${tool}`).join('\\n')}`\n : '';\n\n return `\n## ${agent} in ${stage} stage (${pct}% success)\n**Observations**: ${observations} runs\n**Last seen**: ${today}\n**Success rate**: ${pct}%\n\n**Pattern**:\n[Describe what makes this approach successful]${sequenceText}\n\n**Recommended approach**:\n[Add recommendation here]\n`;\n}\n\n/**\n * Extract tool sequence from events for a given run and agent\n */\nfunction extractToolSequence(events: TelemetryEvent[], runId: string, agent: string): string[] {\n const agentEvents = events.filter(\n (e) => e.runId === runId && e.data.agent === agent && e.event === Events.TOOL_CALL\n );\n\n return agentEvents\n .sort((a, b) => a.timestamp - b.timestamp)\n .map((e) => e.data.tool as string)\n .filter((tool): tool is string => !!tool);\n}\n\n/**\n * Find common tool sequence across multiple runs\n */\nfunction findCommonToolSequence(sequences: string[][]): string[] | undefined {\n if (sequences.length === 0) return undefined;\n\n // Find the most common sequence pattern\n const sequenceMap = new Map<string, number>();\n\n for (const seq of sequences) {\n const key = seq.join('->');\n sequenceMap.set(key, (sequenceMap.get(key) || 0) + 1);\n }\n\n // Return most common sequence if it appears in >50% of runs\n const threshold = sequences.length * 0.5;\n for (const [key, count] of sequenceMap.entries()) {\n if (count >= threshold) {\n return key.split('->');\n }\n }\n\n return undefined;\n}\n\n/**\n * Suggest knowledge entries from failure patterns.\n * Returns formatted entries ready to add to common-failures.md\n */\nexport function suggestFromFailures(\n db: SqliteBackend,\n sinceMs: number,\n limit: number = 5,\n): string[] {\n const patterns = analyzeFailurePatterns(db, sinceMs);\n return patterns.slice(0, limit).map((p) => p.suggestedEntry);\n}\n\n/**\n * Suggest knowledge entries from success patterns.\n * Returns formatted entries ready to add to success-patterns.md\n */\nexport function suggestFromSuccesses(\n db: SqliteBackend,\n sinceMs: number,\n minSuccessRate: number = 0.85,\n limit: number = 5,\n): string[] {\n const patterns = analyzeSuccessPatterns(db, sinceMs, minSuccessRate);\n return patterns.slice(0, limit).map((p) => p.suggestedEntry);\n}\n","import { promises as fs } from 'fs';\nimport path from 'path';\nimport { AgentName } from '../agents.js';\n\nexport interface FailureEntryOptions {\n issue: string;\n solution: string;\n agent: AgentName;\n example?: string;\n}\n\nexport interface PatternEntryOptions {\n description: string;\n approach?: string;\n successRate?: number;\n}\n\n/**\n * Check if path exists\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Parse markdown to extract entries with metadata\n */\ninterface ParsedEntry {\n title: string;\n occurrences?: number;\n lastSeen: string;\n agent?: string;\n successRate?: number;\n fullContent: string;\n}\n\nfunction parseEntries(markdown: string): ParsedEntry[] {\n const entries: ParsedEntry[] = [];\n const sections = markdown.split(/^## /m).filter(s => s.trim());\n\n for (const section of sections) {\n const lines = section.split('\\n');\n const title = lines[0]?.trim() || 'Untitled';\n\n const occurrenceMatch = section.match(/\\*\\*Occurrences\\*\\*:\\s*(\\d+)/);\n const lastSeenMatch = section.match(/\\*\\*Last seen\\*\\*:\\s*(\\d{4}-\\d{2}-\\d{2})/);\n const agentMatch = section.match(/\\*\\*Agent\\*\\*:\\s*(\\w+)/);\n const successRateMatch = section.match(/\\*\\*Success rate\\*\\*:\\s*(\\d+)%/);\n\n // Validate date format - use default if invalid\n let lastSeen = new Date().toISOString().split('T')[0];\n if (lastSeenMatch) {\n const parsedDate = new Date(lastSeenMatch[1]);\n if (!isNaN(parsedDate.getTime())) {\n lastSeen = lastSeenMatch[1];\n }\n }\n\n entries.push({\n title,\n occurrences: occurrenceMatch ? parseInt(occurrenceMatch[1], 10) : undefined,\n lastSeen,\n agent: agentMatch ? agentMatch[1] : undefined,\n successRate: successRateMatch ? parseInt(successRateMatch[1], 10) : undefined,\n fullContent: '## ' + section,\n });\n }\n\n return entries;\n}\n\n/**\n * Prune old entries that haven't been seen in days\n */\nfunction pruneOldEntries(entries: ParsedEntry[], maxAgeDays: number): ParsedEntry[] {\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - maxAgeDays);\n const cutoffStr = cutoff.toISOString().split('T')[0];\n\n return entries.filter(entry => entry.lastSeen >= cutoffStr);\n}\n\n/**\n * Limit entries to max count, keeping most recent\n */\nfunction limitEntries(entries: ParsedEntry[], maxEntries: number): ParsedEntry[] {\n return entries\n .sort((a, b) => b.lastSeen.localeCompare(a.lastSeen))\n .slice(0, maxEntries);\n}\n\n/**\n * Ensures the knowledge directory structure exists.\n * Creates .reygent/knowledge/ and subdirectories if missing.\n */\nexport async function ensureKnowledgeDir(baseDir: string): Promise<void> {\n const knowledgeDir = path.join(baseDir, '.reygent', 'knowledge');\n const agentsDir = path.join(knowledgeDir, 'agents');\n\n await fs.mkdir(knowledgeDir, { recursive: true });\n await fs.mkdir(agentsDir, { recursive: true });\n\n // Create initial template files if they don't exist\n const templates = [\n {\n file: path.join(knowledgeDir, 'common-failures.md'),\n content: `# Common Failures\n\nThis file documents recurring errors and their solutions.\n\n---\n`,\n },\n {\n file: path.join(knowledgeDir, 'success-patterns.md'),\n content: `# Success Patterns\n\nThis file captures proven approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(knowledgeDir, 'project-conventions.md'),\n content: `# Project Conventions\n\nDocument project-specific rules, patterns, and conventions here.\n\nExamples:\n- Code style preferences\n- Architecture decisions\n- Naming conventions\n- Testing strategies\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'dev.md'),\n content: `# Dev Agent Tips\n\n## Common Failures\n\nDocument dev-specific errors here.\n\n## Success Patterns\n\nDocument approaches that work well for development tasks.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'qe.md'),\n content: `# QE Agent Tips\n\n## Common Failures\n\nDocument QE-specific errors here.\n\n## Success Patterns\n\nDocument testing approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'planner.md'),\n content: `# Planner Agent Tips\n\n## Common Failures\n\nDocument planning-specific errors here.\n\n## Success Patterns\n\nDocument planning approaches that work well.\n\n---\n`,\n },\n {\n file: path.join(agentsDir, 'pr-reviewer.md'),\n content: `# PR Reviewer Agent Tips\n\n## Common Failures\n\nDocument review-specific errors here.\n\n## Success Patterns\n\nDocument review approaches that work well.\n\n---\n`,\n },\n ];\n\n for (const { file, content } of templates) {\n if (!(await pathExists(file))) {\n await fs.writeFile(file, content, 'utf8');\n }\n }\n}\n\n/**\n * Adds a failure entry to common-failures.md.\n * Updates existing entry if duplicate found, otherwise adds new.\n * Prunes entries older than 90 days and limits to 50 entries.\n */\nexport async function addFailureEntry(\n baseDir: string,\n options: FailureEntryOptions\n): Promise<void> {\n const filePath = path.join(baseDir, '.reygent', 'knowledge', 'common-failures.md');\n\n // Ensure file exists\n if (!(await pathExists(filePath))) {\n await ensureKnowledgeDir(baseDir);\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const timestamp = new Date().toISOString().split('T')[0];\n\n // Parse existing entries\n const entries = parseEntries(content);\n\n // Check for duplicate (same title and agent)\n const existingIndex = entries.findIndex(\n e => e.title === options.issue && e.agent === options.agent\n );\n\n if (existingIndex !== -1) {\n // Update existing entry\n const existing = entries[existingIndex];\n const newOccurrences = (existing.occurrences || 1) + 1;\n\n entries[existingIndex].fullContent = `\n## ${options.issue}\n**Occurrences**: ${newOccurrences} runs\n**Last seen**: ${timestamp}\n**Agent**: ${options.agent}\n\n**Solution**: ${options.solution}\n${\n options.example\n ? `\n**Example**:\n\\`\\`\\`\n${options.example}\n\\`\\`\\`\n`\n : ''\n}\n---\n`;\n entries[existingIndex].lastSeen = timestamp;\n entries[existingIndex].occurrences = newOccurrences;\n } else {\n // Add new entry\n entries.push({\n title: options.issue,\n occurrences: 1,\n lastSeen: timestamp,\n agent: options.agent,\n fullContent: `\n## ${options.issue}\n**Occurrences**: 1 run\n**Last seen**: ${timestamp}\n**Agent**: ${options.agent}\n\n**Solution**: ${options.solution}\n${\n options.example\n ? `\n**Example**:\n\\`\\`\\`\n${options.example}\n\\`\\`\\`\n`\n : ''\n}\n---\n`,\n });\n }\n\n // Prune old entries (90 days) and limit to 50\n let managedEntries = pruneOldEntries(entries, 90);\n managedEntries = limitEntries(managedEntries, 50);\n\n // Rebuild file\n const header = '# Common Failures\\n\\nThis file documents recurring errors and their solutions.\\n\\n---\\n';\n const newContent = header + managedEntries.map(e => e.fullContent).join('\\n');\n\n await fs.writeFile(filePath, newContent, 'utf8');\n}\n\n/**\n * Adds a success pattern entry to success-patterns.md.\n * Updates existing entry if duplicate found, otherwise adds new.\n * Prunes entries older than 60 days and limits to 30 entries.\n */\nexport async function addPatternEntry(\n baseDir: string,\n options: PatternEntryOptions\n): Promise<void> {\n const filePath = path.join(baseDir, '.reygent', 'knowledge', 'success-patterns.md');\n\n // Ensure file exists\n if (!(await pathExists(filePath))) {\n await ensureKnowledgeDir(baseDir);\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const timestamp = new Date().toISOString().split('T')[0];\n\n // Parse existing entries\n const entries = parseEntries(content);\n\n // Check for duplicate (same title)\n const existingIndex = entries.findIndex(e => e.title === options.description);\n\n if (existingIndex !== -1) {\n // Update existing entry\n entries[existingIndex].fullContent = `\n## ${options.description}\n**Last seen**: ${timestamp}\n${options.successRate ? `**Success rate**: ${options.successRate}%` : ''}\n\n${\n options.approach\n ? `**Approach**:\n${options.approach}\n`\n : ''\n}\n---\n`;\n entries[existingIndex].lastSeen = timestamp;\n if (options.successRate) {\n entries[existingIndex].successRate = options.successRate;\n }\n } else {\n // Add new entry\n entries.push({\n title: options.description,\n lastSeen: timestamp,\n successRate: options.successRate,\n fullContent: `\n## ${options.description}\n**Last seen**: ${timestamp}\n${options.successRate ? `**Success rate**: ${options.successRate}%` : ''}\n\n${\n options.approach\n ? `**Approach**:\n${options.approach}\n`\n : ''\n}\n---\n`,\n });\n }\n\n // Prune old entries (60 days) and limit to 30\n let managedEntries = pruneOldEntries(entries, 60);\n managedEntries = limitEntries(managedEntries, 30);\n\n // Rebuild file\n const header = '# Success Patterns\\n\\nThis file captures proven approaches that work well.\\n\\n---\\n';\n const newContent = header + managedEntries.map(e => e.fullContent).join('\\n');\n\n await fs.writeFile(filePath, newContent, 'utf8');\n}\n","import { createInterface } from \"node:readline\";\nimport chalk from \"chalk\";\nimport { resetTerminalForInput } from \"./terminal-reset.js\";\nimport { getChesstrace } from \"./chesstrace/index.js\";\nimport { Events } from \"./chesstrace/events.js\";\nimport { TaskError } from \"./task.js\";\nimport { isTestEnvironment } from \"./test-env.js\";\n\nexport interface RetryPromptOptions {\n /** Name of the task/gate that failed (e.g., \"unit tests\", \"dev agent\") */\n taskName: string;\n /** Current attempt number (1-indexed) */\n attempt: number;\n /** Maximum retry attempts configured (0 = disabled) */\n maxRetries: number;\n /** Skip prompts and auto-approve retries */\n autoApprove?: boolean;\n /** Telemetry event details */\n telemetry?: {\n stageName: string;\n agentName: string;\n };\n}\n\n/**\n * Shared retry prompt logic for gates and implement loops.\n *\n * Handles three scenarios:\n * 1. Test/non-interactive mode: throw immediately\n * 2. Exceeded max retries: prompt to continue or abort\n * 3. Within retry limit: prompt to retry or abort (unless auto-approved)\n *\n * @returns true if user wants to retry, throws TaskError if user declines or test mode\n */\nexport async function promptForRetry(options: RetryPromptOptions): Promise<boolean> {\n const { taskName, attempt, maxRetries, autoApprove = false, telemetry } = options;\n\n // No retries configured - throw immediately\n if (maxRetries === 0) {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed (retries disabled)`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed (retries disabled)`);\n }\n\n const exceededMax = attempt > maxRetries;\n\n // In test/non-interactive mode with exceeded retries, throw immediately\n if (exceededMax && (isTestEnvironment() || !process.stdin.isTTY)) {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed after ${maxRetries} retries`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed after ${maxRetries} retries`);\n }\n\n // Interactive mode with exceeded retries: prompt to continue\n if (exceededMax) {\n resetTerminalForInput();\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(`\\n${taskName} failed after ${maxRetries} retries. Continue retrying? (y/n) `),\n resolve,\n );\n });\n rl.close();\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n if (telemetry) {\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.ERROR_TASK, {\n type: \"TaskError\",\n message: `${taskName} failed after ${maxRetries} retries`,\n stage: telemetry.stageName,\n agent: telemetry.agentName,\n });\n } catch {\n // Swallow emit errors\n }\n }\n }\n throw new TaskError(`${taskName} failed - user declined to retry after ${maxRetries} attempts`);\n }\n console.log(chalk.blue(\"\\nContinuing retries...\\n\"));\n return true;\n }\n\n // Not exceeded max yet: prompt if not auto-approved\n if (!autoApprove) {\n resetTerminalForInput();\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n const attemptInfo = maxRetries > 0\n ? `(attempt ${attempt}/${maxRetries})`\n : `(attempt ${attempt})`;\n const answer = await new Promise<string>((resolve) => {\n rl.question(\n chalk.yellow(`\\n${taskName} failed. Retry? ${attemptInfo} (y/n) `),\n resolve,\n );\n });\n rl.close();\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n console.log(chalk.red(\"Aborted by user.\"));\n process.exit(1);\n }\n }\n\n return true;\n}\n","import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { ExitPromptError } from \"@inquirer/core\";\nimport { select } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { builtinAgents } from \"../agents.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport { isDebug } from \"../debug.js\";\nimport { DEFAULT_MODEL } from \"../model.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { ensureKnowledgeDir } from \"../knowledge/manager.js\";\n\nexport async function initCommand(options: { dryRun: boolean } = { dryRun: false }): Promise<void> {\n const targetDir = join(process.cwd(), \".reygent\");\n const configPath = join(targetDir, \"config.json\");\n\n const skillsDir = join(targetDir, \"skills\");\n\n const defaultConfig: ReygentConfig = {\n agents: builtinAgents,\n skills: { path: \"skills\" },\n model: DEFAULT_MODEL,\n };\n\n if (options.dryRun) {\n console.log(chalk.yellow.bold(\"[dry-run]\"), \"No changes will be made.\\n\");\n console.log(chalk.bold(\"Would create:\"));\n console.log(chalk.gray(\" dir: \"), chalk.cyan(targetDir));\n console.log(chalk.gray(\" dir: \"), chalk.cyan(skillsDir));\n console.log(chalk.gray(\" file: \"), chalk.cyan(configPath));\n console.log(\"\");\n console.log(chalk.bold(\"Config preview:\"));\n console.log(chalk.gray(JSON.stringify(defaultConfig, null, 2)));\n console.log(\"\");\n return;\n }\n\n try {\n if (existsSync(targetDir)) {\n console.log(chalk.yellow.bold(\"Warning:\"), `.reygent folder already exists`);\n console.log(chalk.gray(` Path: ${targetDir}\\n`));\n\n if (existsSync(configPath)) {\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"Cannot prompt in non-interactive mode. Use --dry-run to preview or remove existing .reygent/ first.\");\n process.exit(1);\n }\n resetTerminalForInput();\n const action = await select({\n message: \"Existing config found. What would you like to do?\",\n choices: [\n { name: \"Reset to defaults\", value: \"reset\" },\n { name: \"Edit config (reygent config)\", value: \"edit\" },\n { name: \"Cancel\", value: \"cancel\" },\n ],\n });\n\n if (action === \"cancel\") {\n console.log(chalk.gray(\"No changes made.\\n\"));\n return;\n }\n\n if (action === \"edit\") {\n console.log(chalk.cyan(\"Run\"), chalk.bold(\"reygent config\"), chalk.cyan(\"to edit your configuration.\\n\"));\n return;\n }\n\n // action === \"reset\" — fall through to creation logic\n console.log(chalk.cyan(\"Resetting config to defaults...\\n\"));\n } else {\n console.log(chalk.cyan(\"No config.json found. Creating default config...\\n\"));\n }\n }\n\n const spinnerText = existsSync(targetDir) ? \"Writing config\" : \"Creating .reygent folder\";\n const spinner = ora(spinnerText).start();\n\n try {\n // Create folders\n if (!existsSync(targetDir)) {\n mkdirSync(targetDir, { recursive: true });\n }\n if (!existsSync(skillsDir)) {\n mkdirSync(skillsDir, { recursive: true });\n }\n\n writeFileSync(configPath, JSON.stringify(defaultConfig, null, 2) + \"\\n\", \"utf-8\");\n\n spinner.text = \"Creating knowledge directory\";\n await ensureKnowledgeDir(process.cwd());\n\n // Create .gitignore for auto-generated files\n const gitignorePath = join(targetDir, \".gitignore\");\n const gitignoreContent = `# Auto-generated knowledge files (generated from local telemetry)\nknowledge/common-failures.md\nknowledge/success-patterns.md\n\n# Keep these files in source control:\n# - config.json (shared agent config)\n# - skills/ (custom team skills)\n# - knowledge/project-conventions.md (user-written rules)\n# - knowledge/agents/*.md (curated agent tips)\n`;\n writeFileSync(gitignorePath, gitignoreContent, \"utf-8\");\n\n spinner.succeed(chalk.green(\"Initialized .reygent folder\"));\n\n console.log(\"\");\n console.log(chalk.bold(\"Next steps:\"));\n console.log(chalk.gray(\" • Edit\"), chalk.cyan(\".reygent/config.json\"), chalk.gray(\"to customize agents\"));\n console.log(chalk.gray(\" • Add custom agents to the\"), chalk.cyan(\"agents\"), chalk.gray(\"array\"));\n console.log(chalk.gray(\" • Add skills to\"), chalk.cyan(\".reygent/skills/\"), chalk.gray(\"(each in its own folder with SKILL.md)\"));\n console.log(chalk.gray(\" • Populate\"), chalk.cyan(\".reygent/knowledge/\"), chalk.gray(\"with project conventions\"));\n console.log(chalk.gray(\" • Run\"), chalk.cyan(\"reygent agent <name>\"), chalk.gray(\"to use your local config\"));\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed: ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n } catch (err) {\n // Ctrl+C from inquirer\n if (err instanceof ExitPromptError) {\n console.log(chalk.yellow(\"\\nInitialization cancelled.\"));\n process.exit(0);\n }\n throw err;\n }\n}\n","import { Command } from \"commander\";\nimport { existsSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { validateSkillName } from \"../skills.js\";\nimport { resolveGlobalConfigDir, resolveSkillsDir } from \"../config.js\";\nimport {\n listRemoteSkills,\n fetchSkillManifest,\n fetchSkillFiles,\n checkCompatibility,\n} from \"../registry.js\";\nimport { isDebug } from \"../debug.js\";\n\nfunction getVersion(): string {\n const __dirname = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(__dirname, \"..\", \"package.json\"), \"utf-8\"));\n return pkg.version;\n}\n\nfunction scanInstalledDir(dir: string, names: Set<string>): void {\n if (!existsSync(dir)) return;\n try {\n for (const entry of readdirSync(dir)) {\n const entryPath = join(dir, entry);\n try {\n if (statSync(entryPath).isDirectory() && existsSync(join(entryPath, \"SKILL.md\"))) {\n names.add(entry);\n }\n } catch { /* skip */ }\n }\n } catch { /* skip */ }\n}\n\nfunction getInstalledSkillNames(): Set<string> {\n const names = new Set<string>();\n const localDir = resolveSkillsDir(\"local\");\n if (localDir) scanInstalledDir(localDir, names);\n const globalDir = resolveSkillsDir(\"global\");\n if (globalDir) scanInstalledDir(globalDir, names);\n return names;\n}\n\nasync function listAction(): Promise<void> {\n const spinner = ora(\"Fetching skills from registry...\").start();\n\n try {\n const skills = await listRemoteSkills();\n const installed = getInstalledSkillNames();\n\n spinner.succeed(chalk.green(`Found ${skills.length} skill${skills.length !== 1 ? \"s\" : \"\"}`));\n console.log(\"\");\n\n if (skills.length === 0) {\n console.log(chalk.gray(\" No skills available in registry.\"));\n console.log(\"\");\n return;\n }\n\n for (const skill of skills) {\n const badge = installed.has(skill.name) ? chalk.green(\" [installed]\") : \"\";\n const version = skill.version ? chalk.gray(` v${skill.version}`) : \"\";\n console.log(` ${chalk.bold.cyan(skill.name)}${version}${badge}`);\n console.log(` ${skill.description}`);\n if (skill.license) {\n console.log(` ${chalk.gray(`License: ${skill.license}`)}`);\n }\n console.log(\"\");\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to fetch skills: ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n\nasync function addAction(name: string, options: { global: boolean }): Promise<void> {\n if (!validateSkillName(name)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid skill name \"${name}\"`);\n process.exit(1);\n }\n\n // Resolve target directory\n let targetBase: string;\n if (options.global) {\n targetBase = join(resolveGlobalConfigDir(), \"skills\");\n } else {\n const localSkillsDir = resolveSkillsDir(\"local\");\n if (!localSkillsDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n console.log(chalk.gray(\" Run\"), chalk.cyan(\"reygent init\"), chalk.gray(\"first, or use\"), chalk.cyan(\"--global\"));\n process.exit(1);\n }\n targetBase = localSkillsDir;\n }\n\n const targetDir = join(targetBase, name);\n\n if (existsSync(targetDir)) {\n console.log(chalk.red.bold(\"Error:\"), `Skill \"${name}\" already installed at ${targetDir}`);\n process.exit(1);\n }\n\n const spinner = ora(`Installing ${name}...`).start();\n\n try {\n // Fetch manifest for compatibility check\n spinner.text = `Checking compatibility for ${name}...`;\n const manifest = await fetchSkillManifest(name);\n const version = getVersion();\n const compatible = checkCompatibility(manifest.compatibility, version);\n\n if (!compatible) {\n spinner.warn(\n chalk.yellow(`Skill \"${name}\" requires ${manifest.compatibility}, you have v${version}`),\n );\n console.log(chalk.yellow(\" Installing anyway — some features may not work.\\n\"));\n spinner.start(`Downloading ${name}...`);\n }\n\n // Fetch all files\n spinner.text = `Downloading ${name}...`;\n const files = await fetchSkillFiles(name);\n\n // Write files\n spinner.text = `Writing files...`;\n for (const file of files) {\n const filePath = join(targetDir, file.path);\n const fileDir = dirname(filePath);\n mkdirSync(fileDir, { recursive: true });\n writeFileSync(filePath, file.content, \"utf-8\");\n }\n\n spinner.succeed(chalk.green(`Installed \"${name}\" (${files.length} files)`));\n console.log(\"\");\n console.log(chalk.gray(\" Location:\"), chalk.cyan(targetDir));\n console.log(chalk.gray(\" Usage: \"), chalk.cyan(`reygent agent ${name}`));\n console.log(\"\");\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to install \"${name}\": ${message}`));\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n\nasync function removeAction(name: string, options: { global: boolean }): Promise<void> {\n if (!validateSkillName(name)) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid skill name \"${name}\"`);\n process.exit(1);\n }\n\n let targetBase: string;\n if (options.global) {\n targetBase = join(resolveGlobalConfigDir(), \"skills\");\n } else {\n const localSkillsDir = resolveSkillsDir(\"local\");\n if (!localSkillsDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n process.exit(1);\n }\n targetBase = localSkillsDir;\n }\n\n const targetDir = join(targetBase, name);\n\n if (!existsSync(targetDir)) {\n console.log(chalk.red.bold(\"Error:\"), `Skill \"${name}\" not found at ${targetDir}`);\n process.exit(1);\n }\n\n try {\n rmSync(targetDir, { recursive: true, force: true });\n console.log(chalk.green(`Removed \"${name}\" from ${targetDir}`));\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Error:\"), `Failed to remove \"${name}\": ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(1);\n }\n}\n\nexport function registerSkillsCommand(program: Command): void {\n const skills = program\n .command(\"skills\")\n .description(\"Manage skills from the reygent-skills registry\");\n\n skills\n .command(\"list\")\n .description(\"List available skills in the registry\")\n .action(listAction);\n\n skills\n .command(\"add\")\n .description(\"Install a skill from the registry\")\n .argument(\"<name>\", \"Skill name to install\")\n .option(\"--global\", \"Install to ~/.reygent/skills/ instead of local\", false)\n .action(addAction);\n\n skills\n .command(\"remove\")\n .description(\"Remove an installed skill\")\n .argument(\"<name>\", \"Skill name to remove\")\n .option(\"--global\", \"Remove from ~/.reygent/skills/ instead of local\", false)\n .action(removeAction);\n}\n","import { execFileSync } from \"node:child_process\";\nimport {\n existsSync,\n readFileSync,\n readdirSync,\n statSync,\n mkdirSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { parseSkillMd } from \"./skills.js\";\nimport type { SkillManifest } from \"./skills.js\";\nimport { resolveGlobalConfigDir } from \"./config.js\";\n\nconst REGISTRY_REPO_URL = \"https://github.com/andrewevans0102/reygent-skills.git\";\n\nexport interface RegistrySkillEntry {\n name: string;\n description: string;\n license?: string;\n compatibility?: string;\n version?: string;\n}\n\nexport interface SkillFile {\n path: string;\n content: string;\n}\n\n/**\n * Path to the local registry cache directory.\n */\nfunction getCacheDir(): string {\n return join(resolveGlobalConfigDir(), \"cache\", \"registry\");\n}\n\n/**\n * Run a git command, throwing a clear error if git is not installed.\n */\nfunction runGit(args: string[], cwd?: string): string {\n try {\n return execFileSync(\"git\", args, {\n cwd,\n encoding: \"utf-8\",\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n } catch (err: unknown) {\n const error = err as NodeJS.ErrnoException;\n if (error.code === \"ENOENT\") {\n throw new Error(\n \"Git is not installed or not found in PATH. Install git to use the skills registry.\",\n );\n }\n throw err;\n }\n}\n\n/**\n * Ensure registry cache exists and is up to date.\n * Always attempts a fresh pull when called — this should only be\n * triggered by explicit user interaction (skills list/add/remove).\n * Falls back to stale cache if pull fails (offline, etc.).\n */\nfunction ensureCache(): string {\n const cacheDir = getCacheDir();\n const gitDir = join(cacheDir, \".git\");\n\n if (!existsSync(gitDir)) {\n // First time — clone\n const parentDir = join(cacheDir, \"..\");\n mkdirSync(parentDir, { recursive: true });\n runGit([\"clone\", \"--depth\", \"1\", REGISTRY_REPO_URL, cacheDir]);\n return cacheDir;\n }\n\n // Pull latest on every explicit skills command\n try {\n runGit([\"pull\", \"--ff-only\"], cacheDir);\n } catch {\n // Offline or conflict — use existing cache silently\n }\n\n return cacheDir;\n}\n\n/**\n * List all skills available in the remote registry.\n */\nexport async function listRemoteSkills(): Promise<RegistrySkillEntry[]> {\n const cacheDir = ensureCache();\n const entries = readdirSync(cacheDir);\n const skills: RegistrySkillEntry[] = [];\n\n for (const entry of entries) {\n if (entry.startsWith(\".\")) continue;\n\n const entryPath = join(cacheDir, entry);\n if (!statSync(entryPath).isDirectory()) continue;\n\n const skillMdPath = join(entryPath, \"SKILL.md\");\n if (!existsSync(skillMdPath)) continue;\n\n try {\n const content = readFileSync(skillMdPath, \"utf-8\");\n const manifest = parseSkillMd(content, entry);\n skills.push({\n name: manifest.name,\n description: manifest.description,\n license: manifest.license,\n compatibility: manifest.compatibility,\n version: manifest.metadata?.version,\n });\n } catch {\n // Skip skills with invalid SKILL.md\n }\n }\n\n return skills;\n}\n\n/**\n * Fetch SKILL.md manifest for a single skill.\n */\nexport async function fetchSkillManifest(skillName: string): Promise<SkillManifest> {\n const cacheDir = ensureCache();\n const skillMdPath = join(cacheDir, skillName, \"SKILL.md\");\n\n if (!existsSync(skillMdPath)) {\n throw new Error(`Skill not found in registry: ${skillName}`);\n }\n\n const content = readFileSync(skillMdPath, \"utf-8\");\n return parseSkillMd(content, skillName);\n}\n\n/**\n * Fetch all files for a skill, recursing into subdirectories.\n */\nexport async function fetchSkillFiles(skillName: string): Promise<SkillFile[]> {\n const cacheDir = ensureCache();\n const skillDir = join(cacheDir, skillName);\n\n if (!existsSync(skillDir) || !statSync(skillDir).isDirectory()) {\n throw new Error(`Skill not found in registry: ${skillName}`);\n }\n\n const files: SkillFile[] = [];\n\n function walkDir(dir: string, prefix: string): void {\n const entries = readdirSync(dir);\n for (const entry of entries) {\n if (entry.startsWith(\".\")) continue;\n const fullPath = join(dir, entry);\n const relativePath = prefix ? `${prefix}/${entry}` : entry;\n\n if (statSync(fullPath).isDirectory()) {\n walkDir(fullPath, relativePath);\n } else {\n files.push({\n path: relativePath,\n content: readFileSync(fullPath, \"utf-8\"),\n });\n }\n }\n }\n\n walkDir(skillDir, \"\");\n return files;\n}\n\n/**\n * Check if a compatibility string (e.g. \">=0.1.0\") is satisfied by reygentVersion.\n * Only supports >=X.Y.Z format. Undefined compatibility = always compatible.\n */\nexport function checkCompatibility(\n compatibility: string | undefined,\n reygentVersion: string,\n): boolean {\n if (!compatibility) return true;\n\n const match = compatibility.match(/^>=\\s*(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) return true; // Unknown format — assume compatible\n\n const [, reqMajor, reqMinor, reqPatch] = match.map(Number);\n const verMatch = reygentVersion.match(/^(\\d+)\\.(\\d+)\\.(\\d+)/);\n if (!verMatch) return true;\n\n const [, curMajor, curMinor, curPatch] = verMatch.map(Number);\n\n if (curMajor !== reqMajor) return curMajor > reqMajor;\n if (curMinor !== reqMinor) return curMinor > reqMinor;\n return curPatch >= reqPatch;\n}\n","import { execFile } from \"node:child_process\";\nimport { request as httpsRequest } from \"node:https\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport { getAgents } from \"../config.js\";\nimport { spawnAgent } from \"../implement.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { isDebug } from \"../debug.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport type { ActivityEvent } from \"../providers/types.js\";\nimport { loadSpec, SpecError } from \"../spec.js\";\nimport { parseRemote, resolveToken } from \"../pr-create.js\";\nimport type { RemoteInfo } from \"../pr-create.js\";\nimport {\n runPRReview,\n postPRReviewComment,\n extractPRReviewOutput,\n formatPRReviewTerminal,\n formatPRReviewOutput,\n} from \"../pr-review.js\";\nimport type { PRReviewOutput, TaskContext } from \"../task.js\";\nimport { TaskError } from \"../task.js\";\nimport { parseSpecWithPrefix, SpecPrefixError } from \"../spec-prefix.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n RESERVED_PROMPT_TOKENS,\n} from \"../diff-split.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { Events } from \"../chesstrace/events.js\";\n\ninterface ReviewWorkOptions {\n spec?: string;\n /**\n * Skip SSL certificate verification for API calls.\n * Note: Only applies to GitLab MR detection/posting via HTTPS API.\n * Does not affect gh CLI operations (GitHub PR workflow).\n */\n insecure?: boolean;\n}\n\nfunction exec(\n cmd: string,\n args: string[],\n): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 50 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `review-work: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nasync function getCurrentBranch(): Promise<string> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch || !branch.trim()) {\n throw new TaskError(\"review-work: not on a branch (detached HEAD?)\");\n }\n return branch;\n}\n\nasync function getDefaultBranch(): Promise<string> {\n try {\n const ref = (\n await exec(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"])\n ).trim();\n return ref.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n // Fallback: check for common defaults\n try {\n const branches = (\n await exec(\"git\", [\"branch\", \"-r\", \"--list\", \"origin/main\", \"origin/master\"])\n ).trim();\n const match = branches.match(/origin\\/(main|master)/);\n if (match) return match[1];\n } catch {\n // ignore\n }\n return \"main\";\n }\n}\n\nasync function detectGitHubPR(): Promise<number | null> {\n try {\n const json = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number\",\n \"--jq\",\n \".number\",\n ]);\n const num = parseInt(json.trim(), 10);\n return isNaN(num) || num <= 0 ? null : num;\n } catch {\n return null;\n }\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n}\n\nfunction httpsGet(\n url: string,\n headers: Record<string, string>,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"GET\",\n headers,\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nfunction httpsPost(\n url: string,\n headers: Record<string, string>,\n body: string,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const bodyBuf = Buffer.from(body, \"utf-8\");\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"POST\",\n headers: { ...headers, \"Content-Length\": bodyBuf.byteLength },\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.write(bodyBuf);\n req.end();\n });\n}\n\nasync function detectGitLabMR(\n remote: RemoteInfo,\n token: string,\n branch: string,\n insecure?: boolean,\n): Promise<number | null> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const encodedBranch = encodeURIComponent(branch);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests?source_branch=${encodedBranch}&state=opened`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n try {\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) return null;\n const mrs = JSON.parse(text) as Array<{ iid: number }>;\n return mrs.length > 0 ? mrs[0].iid : null;\n } catch {\n return null;\n }\n}\n\nasync function getGitDiff(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"diff\", `${baseBranch}...HEAD`]);\n}\n\nasync function getGitStat(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"diff\", \"--stat\", `${baseBranch}...HEAD`]);\n}\n\nasync function getGitLog(baseBranch: string): Promise<string> {\n return exec(\"git\", [\"log\", `${baseBranch}..HEAD`, \"--oneline\"]);\n}\n\nasync function postGitLabComment(\n remote: RemoteInfo,\n token: string,\n mrIid: number,\n body: string,\n insecure?: boolean,\n): Promise<void> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests/${mrIid}/notes`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n const { status, text } = await httpsPost(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n JSON.stringify({ body }),\n tlsOpts,\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`review-work: GitLab API error ${status}: ${text}`);\n }\n}\n\ninterface ReviewPromptInput {\n stat: string;\n log: string;\n includedDiffs: { file: string; diff: string }[];\n excludedFiles: string[];\n spec?: { title: string; content: string };\n}\n\nfunction buildReviewPrompt(\n systemPrompt: string,\n input: ReviewPromptInput,\n): string {\n let prompt = systemPrompt;\n\n if (input.spec) {\n prompt += `\n\n---\n\n## Spec\n\n**Title:** ${input.spec.title}\n\n${input.spec.content}\n\n---`;\n }\n\n prompt += `\n\n## Branch Summary\n\n### Changed Files\n\n\\`\\`\\`\n${input.stat}\n\\`\\`\\`\n\n### Commits\n\n\\`\\`\\`\n${input.log}\n\\`\\`\\``;\n\n if (input.includedDiffs.length > 0) {\n prompt += `\n\n## File Diffs\n\n`;\n for (const f of input.includedDiffs) {\n prompt += `\\`\\`\\`diff\n${f.diff}\n\\`\\`\\`\n\n`;\n }\n }\n\n if (input.excludedFiles.length > 0) {\n prompt += `\n### Files not shown (${input.excludedFiles.length} excluded due to size)\n\n${input.excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\n`;\n }\n\n prompt += `\n\n---\n\n## Instructions\n\n1. Review the changes above${input.spec ? \" in the context of the spec\" : \"\"}.\n2. Check for correctness, potential bugs, style issues${input.spec ? \", and whether the implementation meets the spec\" : \"\"}.\n3. For files not shown, note any concerns based on the stat summary and commit messages.\n4. When you are finished, output a single JSON block with your review:\n\n\\`\\`\\`json\n{\n \"summary\": \"Brief overall assessment of the PR\",\n \"comments\": [\n {\n \"file\": \"src/example.ts\",\n \"line\": 42,\n \"comment\": \"Description of the issue or suggestion\"\n }\n ],\n \"recommendedActions\": [\n \"Action item 1\",\n \"Action item 2\"\n ]\n}\n\\`\\`\\`\n\n- \\`summary\\` is a brief overall assessment of the PR.\n- \\`comments\\` is an array of inline review comments. \\`line\\` may be null if the comment applies to the whole file.\n- \\`recommendedActions\\` is a list of suggested follow-up actions.\n- Do NOT output any text after the JSON block.`;\n\n return prompt;\n}\n\nasync function runAgentReview(\n baseBranch: string,\n spec?: { title: string; content: string },\n onActivity?: (event: ActivityEvent) => void,\n): Promise<PRReviewOutput> {\n const agents = getAgents();\n const agent = agents.find((a) => a.role === \"reviewer\");\n if (!agent) {\n throw new TaskError(\"review-work: no agent with role 'reviewer' found in config\");\n }\n\n const [diff, stat, log] = await Promise.all([\n getGitDiff(baseBranch),\n getGitStat(baseBranch),\n getGitLog(baseBranch),\n ]);\n\n if (!diff.trim()) {\n throw new TaskError(\"review-work: no changes found\");\n }\n\n // Split diff by file and select within budget\n const fileDiffs = splitDiffByFile(diff);\n const reservedTokens = estimateTokens(agent.systemPrompt) + estimateTokens(stat) + estimateTokens(log) + RESERVED_PROMPT_TOKENS;\n const { included, excluded } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens);\n\n // Debug logging and telemetry for diff budget decisions\n const totalDiffTokens = included.reduce((sum, f) => sum + f.tokens, 0);\n const excludedTokens = fileDiffs.filter(f => excluded.includes(f.file)).reduce((sum, f) => sum + f.tokens, 0);\n const availableTokens = MAX_REVIEW_TOKENS - reservedTokens;\n\n if (isDebug()) {\n console.log(\n `[DEBUG] Diff budget: ${totalDiffTokens}/${availableTokens} tokens used ` +\n `(${included.length}/${fileDiffs.length} files included, ${excluded.length} excluded for ${excludedTokens} tokens)`\n );\n if (excluded.length > 0) {\n console.log(`[DEBUG] Excluded files: ${excluded.join(\", \")}`);\n }\n }\n\n // Emit telemetry event\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.REVIEW_DIFF_BUDGET, {\n filesIncluded: included.length,\n filesExcluded: excluded.length,\n tokensUsed: totalDiffTokens,\n tokensAvailable: availableTokens,\n excludedFilesList: excluded,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n const prompt = buildReviewPrompt(agent.systemPrompt, {\n stat: stat.trim(),\n log: log.trim(),\n includedDiffs: included,\n excludedFiles: excluded,\n spec,\n });\n const result = await spawnAgent(\"pr-review\", prompt, { quiet: true, onActivity, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(\n `review-work: agent exited with code ${result.exitCode}`,\n );\n }\n\n return extractPRReviewOutput(result.stdout);\n}\n\nexport async function reviewWorkCommand(\n options: ReviewWorkOptions,\n): Promise<void> {\n try {\n // Verify we're in a git repo\n try {\n await exec(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"]);\n } catch {\n console.log(chalk.red.bold(\"Error:\"), \"Not inside a git repository.\");\n process.exit(1);\n }\n\n loadEnvFile();\n\n // Load spec if provided\n let spec: { title: string; content: string } | undefined;\n if (options.spec) {\n const spinner = ora(\"Loading spec...\").start();\n try {\n const parsed = parseSpecWithPrefix(options.spec);\n const loaded = await loadSpec(parsed.identifier, parsed.provider);\n spec = { title: loaded.title, content: loaded.content };\n spinner.succeed(chalk.green(`Spec loaded: ${loaded.title}`));\n } catch (err) {\n spinner.fail(chalk.red(\"Failed to load spec\"));\n throw err;\n }\n }\n\n // Detect platform\n const remoteUrl = (\n await exec(\"git\", [\"remote\", \"get-url\", \"origin\"])\n ).trim();\n const remote = parseRemote(remoteUrl);\n const branch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n console.log(\n chalk.gray(` Platform: ${remote.platform}`) +\n chalk.gray(` | Branch: ${branch}`) +\n chalk.gray(` | Base: ${defaultBranch}`),\n );\n console.log();\n\n if (remote.platform === \"github\") {\n // GitHub path\n const spinner = ora(\"Checking for open PR...\").start();\n const prNumber = await detectGitHubPR();\n\n if (prNumber !== null) {\n spinner.succeed(chalk.green(`Found PR #${prNumber}`));\n\n // Build minimal TaskContext for runPRReview\n const context: TaskContext = {\n spec: spec\n ? { source: \"markdown\" as const, title: spec.title, content: spec.content }\n : { source: \"markdown\" as const, title: \"Review\", content: \"\" },\n prCreate: {\n branch,\n commitMessage: \"\",\n prUrl: \"\",\n prNumber,\n },\n results: [],\n };\n\n console.log();\n const prReviewStatus = createLiveStatus(\"Running PR review...\");\n const { output } = await runPRReview(context, { quiet: true, onActivity: prReviewStatus.onActivity });\n prReviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n\n const postSpinner = ora(\"Posting review comment to PR...\").start();\n try {\n await postPRReviewComment(context, output);\n postSpinner.succeed(chalk.green(`Review posted to PR #${prNumber}`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n postSpinner.fail(chalk.red(`Failed to post comment: ${msg}`));\n }\n } else {\n spinner.info(chalk.yellow(\"No open PR found for this branch\"));\n console.log();\n\n const reviewStatus = createLiveStatus(\"Running review...\");\n let output: PRReviewOutput;\n try {\n output = await runAgentReview(defaultBranch, spec, reviewStatus.onActivity);\n } catch (err) {\n if (err instanceof TaskError && err.message.includes(\"no changes found\")) {\n reviewStatus.stop();\n console.log(chalk.yellow(\"No changes found against\"), chalk.bold(defaultBranch));\n return;\n }\n throw err;\n }\n reviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n console.log(chalk.gray(\"No PR found — review printed to console only.\"));\n }\n } else {\n // GitLab path\n const spinner = ora(\"Checking for open MR...\").start();\n let token: string;\n try {\n token = await resolveToken(remote.host);\n } catch (err) {\n if (isDebug()) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(chalk.gray(`[debug] Token resolution failed: ${msg}`));\n }\n spinner.info(chalk.yellow(\"Could not resolve GitLab token — skipping MR detection\"));\n token = \"\";\n }\n\n const mrIid = token\n ? await detectGitLabMR(remote, token, branch, options.insecure)\n : null;\n\n if (mrIid !== null) {\n spinner.succeed(chalk.green(`Found MR !${mrIid}`));\n } else {\n spinner.info(chalk.yellow(\"No open MR found for this branch\"));\n }\n\n console.log();\n const glReviewStatus = createLiveStatus(\"Running review...\");\n let output: PRReviewOutput;\n try {\n output = await runAgentReview(defaultBranch, spec, glReviewStatus.onActivity);\n } catch (err) {\n if (err instanceof TaskError && err.message.includes(\"no changes found\")) {\n glReviewStatus.stop();\n console.log(chalk.yellow(\"No changes found against\"), chalk.bold(defaultBranch));\n return;\n }\n throw err;\n }\n glReviewStatus.succeed(chalk.green(\"Review complete\"));\n\n console.log(formatPRReviewTerminal(output));\n console.log();\n\n if (mrIid !== null && token) {\n const postSpinner = ora(\"Posting review comment to MR...\").start();\n try {\n const body =\n formatPRReviewOutput(output) +\n \"\\n\\n---\\n*Review by [reygent](https://github.com/andrewevans0102/reygent)*\";\n await postGitLabComment(remote, token, mrIid, body, options.insecure);\n postSpinner.succeed(chalk.green(`Review posted to MR !${mrIid}`));\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n postSpinner.fail(chalk.red(`Failed to post comment: ${msg}`));\n }\n } else {\n console.log(chalk.gray(\"No MR found — review printed to console only.\"));\n }\n }\n } catch (err) {\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n process.exit(0);\n }\n if (err instanceof SpecError || err instanceof SpecPrefixError || err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n}\n","import { SpecProvider } from \"./spec.js\";\n\nexport class SpecPrefixError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SpecPrefixError\";\n }\n}\n\nexport interface ParsedSpecSource {\n provider: SpecProvider;\n identifier: string;\n}\n\nexport const VALID_PREFIXES = [\"jira:\", \"linear:\", \"markdown:\"] as const;\n\n/**\n * Parse spec source with required provider prefix.\n * Format: <provider>:<source>\n *\n * Examples:\n * jira:ENG-123\n * linear:DT-275\n * markdown:./test-spec.md\n *\n * Auto-infers markdown: for file paths ending in .md or starting with ./ or /\n */\nexport function parseSpecWithPrefix(input: string): ParsedSpecSource {\n // Check for explicit prefix first\n const colonIndex = input.indexOf(\":\");\n if (colonIndex !== -1) {\n const prefix = input.substring(0, colonIndex + 1);\n const identifier = input.substring(colonIndex + 1);\n\n if (!identifier.trim()) {\n throw new SpecPrefixError(`Empty source after \"${prefix}\" prefix`);\n }\n\n switch (prefix) {\n case \"jira:\":\n return { provider: \"jira\", identifier };\n case \"linear:\":\n return { provider: \"linear\", identifier };\n case \"markdown:\":\n return { provider: \"local\", identifier };\n default:\n throw new SpecPrefixError(\n `Invalid prefix \"${prefix}\". Must be one of: ${VALID_PREFIXES.join(\", \")}`\n );\n }\n }\n\n // Auto-infer markdown: prefix for file paths\n if (isFilePath(input)) {\n return { provider: \"local\", identifier: input };\n }\n\n // No prefix and not a file path\n throw new SpecPrefixError(\n `Source prefix required. Valid formats:\\n` +\n ` jira:PROJ-123\\n` +\n ` linear:DT-275\\n` +\n ` markdown:./spec.md\\n` +\n `Or use file path (ends in .md or starts with ./ or /)`\n );\n}\n\n/**\n * Check if input looks like a file path.\n * Returns true for:\n * - Paths ending in .md or .markdown (case insensitive)\n * - Paths starting with ./ or /\n */\nfunction isFilePath(input: string): boolean {\n if (/\\.(md|markdown)$/i.test(input)) return true;\n if (input.startsWith(\"./\") || input.startsWith(\"/\")) return true;\n return false;\n}\n","import { execFile } from \"node:child_process\";\nimport { request as httpsRequest } from \"node:https\";\nimport chalk from \"chalk\";\nimport { select } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { wrapText } from \"../format.js\";\nimport { getAgents } from \"../config.js\";\nimport { spawnAgent } from \"../implement.js\";\nimport { extractJSON } from \"../planner.js\";\nimport { createLiveStatus } from \"../live-status.js\";\nimport type { ActivityEvent } from \"../live-status.js\";\nimport { loadEnvFile } from \"../env.js\";\nimport { isDebug } from \"../debug.js\";\nimport { parseRemote, resolveToken } from \"../pr-create.js\";\nimport type { RemoteInfo } from \"../pr-create.js\";\nimport type { PlannerOutput } from \"../task.js\";\nimport { TaskError } from \"../task.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\nimport { withTelemetry } from \"../telemetry-lifecycle.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport {\n splitDiffByFile,\n selectDiffsWithinBudget,\n estimateTokens,\n MAX_REVIEW_TOKENS,\n RESERVED_PROMPT_TOKENS,\n} from \"../diff-split.js\";\nimport type { FileDiff } from \"../diff-split.js\";\n\ninterface ReviewCommentsOptions {\n insecure?: boolean;\n autoApprove?: boolean;\n retryCommits?: number;\n}\n\ninterface ReviewComment {\n author: string;\n body: string;\n path?: string;\n line?: number | null;\n createdAt: string;\n}\n\ninterface ClassifiedComment extends ReviewComment {\n isSecurity: boolean;\n}\n\n// ── Security comment classification ──\n\n// Primary keywords: high-confidence security signals — any single match triggers isSecurity\nconst PRIMARY_SECURITY_KEYWORDS = [\n \"xss\", \"cross-site scripting\", \"csrf\", \"cross-site request forgery\",\n \"sql injection\", \"sqli\", \"command injection\", \"code injection\",\n \"path traversal\", \"directory traversal\",\n \"ssrf\", \"server-side request forgery\",\n \"xxe\", \"rce\", \"remote code execution\",\n \"deserialization\", \"idor\",\n \"auth bypass\",\n \"privilege escalation\", \"broken access control\",\n \"session fixation\", \"session hijacking\",\n \"token expir\", \"token leak\",\n \"hardcoded secret\", \"hardcoded password\", \"hardcoded key\",\n \"api key\", \"credential\", \"plaintext password\",\n \"weak hash\", \"md5\", \"sha1\",\n \"insecure random\", \"math.random\",\n \"sanitiz\", \"unsanitized\", \"unescaped\",\n \"untrusted input\", \"tainted\",\n \"innerhtml\", \"dangerouslysetinnerhtml\", \"eval(\",\n \"content-security-policy\", \"csp\",\n \"security header\", \"httponly\", \"secure flag\",\n \"vulnerability\", \"exploit\", \"attack vector\",\n \"owasp\", \"cve\", \"cwe\",\n \"security risk\", \"security issue\", \"security concern\",\n \"security review\", \"security finding\",\n \"denial of service\",\n \"information disclosure\", \"data leak\", \"data exposure\",\n \"sensitive data\",\n];\n\n// Secondary keywords: broad terms that only flag when 2+ secondaries co-occur\n// or when paired with at least 1 primary keyword\nconst SECONDARY_SECURITY_KEYWORDS = [\n \"authentication\", \"authorization\",\n \"jwt\", \"cors\",\n \"dos\", \"race condition\",\n];\n\nfunction classifyComment(body: string): boolean {\n const lower = body.toLowerCase();\n\n const hasPrimary = PRIMARY_SECURITY_KEYWORDS.some((kw) => lower.includes(kw));\n if (hasPrimary) return true;\n\n const secondaryMatches = SECONDARY_SECURITY_KEYWORDS.filter((kw) =>\n lower.includes(kw),\n );\n\n // Require 2+ secondary keywords to co-occur\n return secondaryMatches.length >= 2;\n}\n\nfunction classifyComments(comments: ReviewComment[]): ClassifiedComment[] {\n return comments.map((c) => ({\n ...c,\n isSecurity: classifyComment(c.body),\n }));\n}\n\n// ── Private helpers (self-contained, matches review-work.ts convention) ──\n\nfunction exec(cmd: string, args: string[]): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(\n cmd,\n args,\n { maxBuffer: 50 * 1024 * 1024 },\n (error, stdout, stderr) => {\n if (error) {\n reject(\n new TaskError(\n `review-comments: command failed: ${cmd} ${args.join(\" \")}\\n${stderr || stdout || error.message}`,\n ),\n );\n return;\n }\n resolve(stdout);\n },\n );\n });\n}\n\nasync function getCurrentBranch(): Promise<string> {\n const branch = (await exec(\"git\", [\"branch\", \"--show-current\"])).trim();\n if (!branch) {\n throw new TaskError(\"review-comments: not on a branch (detached HEAD?)\");\n }\n return branch;\n}\n\nasync function getDefaultBranch(): Promise<string> {\n try {\n const ref = (\n await exec(\"git\", [\"symbolic-ref\", \"refs/remotes/origin/HEAD\"])\n ).trim();\n return ref.replace(\"refs/remotes/origin/\", \"\");\n } catch {\n try {\n const branches = (\n await exec(\"git\", [\"branch\", \"-r\", \"--list\", \"origin/main\", \"origin/master\"])\n ).trim();\n const match = branches.match(/origin\\/(main|master)/);\n if (match) return match[1];\n } catch {\n // ignore\n }\n return \"main\";\n }\n}\n\nasync function detectGitHubPR(): Promise<number | null> {\n try {\n const json = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"number\",\n \"--jq\",\n \".number\",\n ]);\n const num = parseInt(json.trim(), 10);\n return isNaN(num) || num <= 0 ? null : num;\n } catch {\n return null;\n }\n}\n\ninterface TlsOptions {\n rejectUnauthorized?: boolean;\n}\n\nfunction httpsGet(\n url: string,\n headers: Record<string, string>,\n tlsOpts?: TlsOptions,\n): Promise<{ status: number; text: string }> {\n const parsed = new URL(url);\n return new Promise((resolve, reject) => {\n const req = httpsRequest(\n {\n hostname: parsed.hostname,\n port: parsed.port || 443,\n path: parsed.pathname + parsed.search,\n method: \"GET\",\n headers,\n ...tlsOpts,\n },\n (res) => {\n const chunks: Buffer[] = [];\n res.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n res.on(\"end\", () =>\n resolve({\n status: res.statusCode ?? 0,\n text: Buffer.concat(chunks).toString(\"utf-8\"),\n }),\n );\n },\n );\n req.on(\"error\", reject);\n req.end();\n });\n}\n\nasync function detectGitLabMR(\n remote: RemoteInfo,\n token: string,\n branch: string,\n insecure?: boolean,\n): Promise<number | null> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const encodedBranch = encodeURIComponent(branch);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests?source_branch=${encodedBranch}&state=opened`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n try {\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) return null;\n const mrs = JSON.parse(text) as Array<{ iid: number }>;\n return mrs.length > 0 ? mrs[0].iid : null;\n } catch {\n return null;\n }\n}\n\n// ── Comment fetching ──\n\nasync function fetchGitHubComments(): Promise<ReviewComment[]> {\n const raw = await exec(\"gh\", [\n \"pr\",\n \"view\",\n \"--json\",\n \"comments,reviews\",\n ]);\n const data = JSON.parse(raw) as {\n comments?: Array<{\n author?: { login?: string };\n body?: string;\n createdAt?: string;\n }>;\n reviews?: Array<{\n author?: { login?: string };\n body?: string;\n state?: string;\n createdAt?: string;\n comments?: Array<{\n author?: { login?: string };\n body?: string;\n path?: string;\n line?: number | null;\n createdAt?: string;\n }>;\n }>;\n };\n\n const comments: ReviewComment[] = [];\n\n // Issue-level comments\n if (data.comments) {\n for (const c of data.comments) {\n if (!c.body?.trim()) continue;\n comments.push({\n author: c.author?.login ?? \"unknown\",\n body: c.body,\n createdAt: c.createdAt ?? \"\",\n });\n }\n }\n\n // Review-level: top-level review body + inline comments\n if (data.reviews) {\n for (const r of data.reviews) {\n if (r.body?.trim()) {\n comments.push({\n author: r.author?.login ?? \"unknown\",\n body: r.body,\n createdAt: r.createdAt ?? \"\",\n });\n }\n if (r.comments) {\n for (const ic of r.comments) {\n if (!ic.body?.trim()) continue;\n comments.push({\n author: ic.author?.login ?? r.author?.login ?? \"unknown\",\n body: ic.body,\n path: ic.path,\n line: ic.line,\n createdAt: ic.createdAt ?? \"\",\n });\n }\n }\n }\n }\n\n return comments;\n}\n\nasync function fetchGitLabComments(\n remote: RemoteInfo,\n token: string,\n mrIid: number,\n insecure?: boolean,\n): Promise<ReviewComment[]> {\n const projectPath = encodeURIComponent(`${remote.owner}/${remote.repo}`);\n const url = `https://${remote.host}/api/v4/projects/${projectPath}/merge_requests/${mrIid}/notes?per_page=100`;\n const tlsOpts: TlsOptions = insecure ? { rejectUnauthorized: false } : {};\n\n const { status, text } = await httpsGet(\n url,\n { Authorization: `Bearer ${token}`, \"Content-Type\": \"application/json\" },\n tlsOpts,\n );\n if (status < 200 || status >= 300) {\n throw new TaskError(`review-comments: GitLab API error ${status}: ${text}`);\n }\n\n const notes = JSON.parse(text) as Array<{\n author?: { username?: string };\n body?: string;\n system?: boolean;\n created_at?: string;\n position?: {\n new_path?: string;\n new_line?: number | null;\n };\n }>;\n\n const comments: ReviewComment[] = [];\n for (const n of notes) {\n // Skip system-generated notes\n if (n.system) continue;\n if (!n.body?.trim()) continue;\n\n comments.push({\n author: n.author?.username ?? \"unknown\",\n body: n.body,\n path: n.position?.new_path,\n line: n.position?.new_line,\n createdAt: n.created_at ?? \"\",\n });\n }\n\n return comments;\n}\n\n// ── Display ──\n\nfunction displayCommentSummary(comments: ClassifiedComment[]): void {\n const securityCount = comments.filter((c) => c.isSecurity).length;\n const generalCount = comments.length - securityCount;\n\n console.log(chalk.bold(` ${comments.length} review comment(s) found`));\n if (securityCount > 0) {\n console.log(\n chalk.yellow(` ⚠ ${securityCount} security-related`) +\n chalk.gray(` | ${generalCount} general`),\n );\n }\n console.log();\n\n for (const c of comments) {\n const location = c.path\n ? chalk.cyan(` ${c.path}${c.line ? `:${c.line}` : \"\"}`)\n : chalk.gray(\" (general)\");\n const tag = c.isSecurity ? chalk.bgYellow.black(\" SEC \") + \" \" : \"\";\n console.log(` ${tag}${chalk.bold(c.author)} ${location}`);\n\n // Truncate long comments for summary display\n const cols = process.stdout.columns || 80;\n const preview = c.body.length > 200\n ? c.body.slice(0, 200) + \"...\"\n : c.body;\n for (const line of preview.split(\"\\n\")) {\n console.log(chalk.gray(` ${wrapText(line, 4, cols)}`));\n }\n console.log();\n }\n}\n\n// ── Plan generation ──\n\nfunction formatCommentBlock(comments: ClassifiedComment[]): string {\n const securityComments = comments.filter((c) => c.isSecurity);\n const generalComments = comments.filter((c) => !c.isSecurity);\n\n const formatOne = (c: ClassifiedComment) => {\n const loc = c.path ? `File: ${c.path}${c.line ? `:${c.line}` : \"\"}` : \"General\";\n return `- **${c.author}** (${loc}): ${c.body}`;\n };\n\n let block = \"\";\n if (securityComments.length > 0) {\n block += `### Security Comments (PRIORITY — must be addressed)\\n\\n`;\n block += securityComments.map(formatOne).join(\"\\n\");\n block += \"\\n\\n\";\n }\n if (generalComments.length > 0) {\n block += `### General Comments\\n\\n`;\n block += generalComments.map(formatOne).join(\"\\n\");\n }\n return block;\n}\n\nfunction buildPlanPrompt(\n systemPrompt: string,\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n): string {\n const hasSecurityComments = comments.some((c) => c.isSecurity);\n\n const securityPlanInstruction = hasSecurityComments\n ? \" Security-related comments are marked as priority — ensure concrete fix tasks are generated for each one. Apply secure coding practices (input validation, output encoding, least privilege, etc.) when planning fixes.\"\n : \"\";\n\n let diffSection = \"\";\n if (includedDiffs.length > 0) {\n diffSection += `## Current Diff (branch vs base)\\n\\n`;\n for (const f of includedDiffs) {\n diffSection += `\\`\\`\\`diff\\n${f.diff}\\n\\`\\`\\`\\n\\n`;\n }\n }\n if (excludedFiles.length > 0) {\n diffSection += `### Files not shown (too large for context)\\n\\n${excludedFiles.map((f) => `- ${f}`).join(\"\\n\")}\\n`;\n }\n\n return `${systemPrompt}\n\n---\n\n## Review Comments to Address\n\n${formatCommentBlock(comments)}\n\n---\n\n${diffSection}\n---\n\n## Instructions\n\nAnalyze the review comments above in the context of the current diff. Create a plan to address each comment.${securityPlanInstruction} Return ONLY valid JSON:\n\n\\`\\`\\`json\n{ \"valid\": true, \"goals\": [\"...\"], \"tasks\": [\"...\"], \"constraints\": [\"...\"], \"dod\": [\"...\"] }\n\\`\\`\\`\n\n- **goals**: High-level objectives (e.g., \"Address all review feedback\")\n- **tasks**: Specific actionable steps to fix/change code per reviewer comments\n- **constraints**: Things to preserve or avoid breaking\n- **dod**: How to verify each comment has been addressed\n\nEach array must contain at least one non-empty string. Do not include any text outside the JSON object.`;\n}\n\nfunction buildPlanPromptWithFeedback(\n systemPrompt: string,\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n feedback: string,\n): string {\n const base = buildPlanPrompt(systemPrompt, comments, includedDiffs, excludedFiles);\n return `${base}\n\n---\n\n## User Feedback on Previous Plan\n\nThe user reviewed the previous plan and provided this feedback. Incorporate it into your revised plan:\n\n${feedback}`;\n}\n\nasync function generatePlan(\n comments: ClassifiedComment[],\n includedDiffs: FileDiff[],\n excludedFiles: string[],\n feedback?: string,\n): Promise<PlannerOutput> {\n const agents = getAgents();\n const agent = agents.find((a) => a.role === \"planner\");\n if (!agent) {\n throw new TaskError(\"review-comments: no agent with role 'planner' found in config\");\n }\n\n const prompt = feedback\n ? buildPlanPromptWithFeedback(agent.systemPrompt, comments, includedDiffs, excludedFiles, feedback)\n : buildPlanPrompt(agent.systemPrompt, comments, includedDiffs, excludedFiles);\n\n const result = await spawnAgent(\"planner\", prompt, { quiet: true, provider: agent.provider, model: agent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(`review-comments: planner agent exited with code ${result.exitCode}`);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(extractJSON(result.stdout));\n } catch {\n throw new TaskError(\"review-comments: failed to parse planner output as JSON\");\n }\n\n const obj = parsed as Record<string, unknown>;\n if (obj.valid !== true) {\n const errors = Array.isArray(obj.errors)\n ? (obj.errors as string[]).join(\"\\n - \")\n : \"planner returned invalid plan\";\n throw new TaskError(`review-comments: plan generation failed:\\n - ${errors}`);\n }\n\n const plan: PlannerOutput = {\n goals: Array.isArray(obj.goals) ? (obj.goals as string[]) : [],\n tasks: Array.isArray(obj.tasks) ? (obj.tasks as string[]) : [],\n constraints: Array.isArray(obj.constraints) ? (obj.constraints as string[]) : [],\n dod: Array.isArray(obj.dod) ? (obj.dod as string[]) : [],\n };\n\n if (plan.goals.length === 0 || plan.tasks.length === 0) {\n throw new TaskError(\"review-comments: planner returned empty goals or tasks\");\n }\n\n return plan;\n}\n\n// ── Plan display and approval ──\n\nfunction displayPlan(plan: PlannerOutput): void {\n const cols = process.stdout.columns || 80;\n console.log(chalk.bold(\"\\n Plan to Address Review Comments\\n\"));\n\n console.log(chalk.bold.blue(\" Goals:\"));\n for (const g of plan.goals) {\n console.log(` - ${wrapText(g, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Tasks:\"));\n for (const t of plan.tasks) {\n console.log(` - ${wrapText(t, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Constraints:\"));\n for (const c of plan.constraints) {\n console.log(` - ${wrapText(c, 6, cols)}`);\n }\n console.log();\n\n console.log(chalk.bold.blue(\" Definition of Done:\"));\n for (const d of plan.dod) {\n console.log(` - ${wrapText(d, 6, cols)}`);\n }\n console.log();\n}\n\n// ── Execution ──\n\nfunction buildDevPrompt(\n systemPrompt: string,\n comments: ClassifiedComment[],\n plan: PlannerOutput,\n userInstructions?: string,\n): string {\n const hasSecurityComments = comments.some((c) => c.isSecurity);\n\n const securityDevInstruction = hasSecurityComments\n ? \" Pay special attention to security-related comments — apply secure coding practices and ensure fixes do not introduce new vulnerabilities.\"\n : \"\";\n\n let prompt = `${systemPrompt}\n\n---\n\n## Review Comments to Address\n\n${formatCommentBlock(comments)}\n\n---\n\n## Plan\n\n**Goals:**\n${plan.goals.map((g) => `- ${g}`).join(\"\\n\")}\n\n**Tasks:**\n${plan.tasks.map((t) => `- ${t}`).join(\"\\n\")}\n\n**Constraints:**\n${plan.constraints.map((c) => `- ${c}`).join(\"\\n\")}\n\n**Definition of Done:**\n${plan.dod.map((d) => `- ${d}`).join(\"\\n\")}`;\n\n if (userInstructions) {\n prompt += `\n\n---\n\n## Additional Instructions from User\n\n${userInstructions}`;\n }\n\n prompt += `\n\n---\n\nImplement the tasks above to address the review comments.${securityDevInstruction} When you are finished, output a JSON block with the list of files you created or modified:\n\n\\`\\`\\`json\n{ \"files\": [\"src/example.ts\"] }\n\\`\\`\\``;\n\n return prompt;\n}\n\nasync function executeWithDevAgent(\n comments: ClassifiedComment[],\n plan: PlannerOutput,\n autoApprove?: boolean,\n onActivity?: (event: ActivityEvent) => void,\n userInstructions?: string,\n): Promise<void> {\n const agents = getAgents();\n const devAgent = agents.find((a) => a.name === \"dev\");\n if (!devAgent) {\n throw new TaskError(\"review-comments: no agent named 'dev' found in config\");\n }\n\n const prompt = buildDevPrompt(devAgent.systemPrompt, comments, plan, userInstructions);\n\n const result = await spawnAgent(\"dev\", prompt, { autoApprove, quiet: true, onActivity, provider: devAgent.provider, model: devAgent.model });\n\n if (result.exitCode !== 0) {\n throw new TaskError(`review-comments: dev agent exited with code ${result.exitCode}`);\n }\n\n // Extract files changed\n try {\n const parsed = JSON.parse(extractJSON(result.stdout)) as { files?: string[] };\n if (parsed.files && parsed.files.length > 0) {\n console.log();\n console.log(chalk.bold(\" Files modified:\"));\n for (const f of parsed.files) {\n console.log(` - ${chalk.cyan(f)}`);\n }\n }\n } catch {\n // Non-critical — agent may not output structured JSON\n }\n}\n\n// ── Main command ──\n\nexport async function reviewCommentsCommand(\n options: ReviewCommentsOptions,\n): Promise<void> {\n return withTelemetry('review-comments', async () => {\n try {\n // 1. Verify git repo\n try {\n await exec(\"git\", [\"rev-parse\", \"--is-inside-work-tree\"]);\n } catch {\n console.log(chalk.red.bold(\"Error:\"), \"Not inside a git repository.\");\n process.exit(1);\n }\n\n loadEnvFile();\n\n // 2. Detect platform\n const remoteUrl = (\n await exec(\"git\", [\"remote\", \"get-url\", \"origin\"])\n ).trim();\n const remote = parseRemote(remoteUrl);\n const branch = await getCurrentBranch();\n const defaultBranch = await getDefaultBranch();\n\n console.log(\n chalk.gray(` Platform: ${remote.platform}`) +\n chalk.gray(` | Branch: ${branch}`) +\n chalk.gray(` | Base: ${defaultBranch}`),\n );\n console.log();\n\n // 3. Check for PR/MR and fetch comments\n let comments: ReviewComment[] = [];\n\n if (remote.platform === \"github\") {\n const spinner = createLiveStatus(\"checking for open PR...\");\n const prNumber = await detectGitHubPR();\n\n if (prNumber === null) {\n spinner.fail(chalk.red(\"No open PR found for this branch\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n spinner.succeed(chalk.green(`Found PR #${prNumber}`));\n\n console.log();\n const commentSpinner = createLiveStatus(\"fetching review comments...\");\n comments = await fetchGitHubComments();\n\n if (comments.length === 0) {\n commentSpinner.info(chalk.yellow(\"No review comments found on this PR\"));\n return;\n }\n commentSpinner.succeed(chalk.green(`Fetched ${comments.length} comment(s)`));\n } else {\n // GitLab\n const spinner = createLiveStatus(\"checking for open MR...\");\n let token: string;\n try {\n token = await resolveToken(remote.host);\n } catch (err) {\n if (isDebug()) {\n const msg = err instanceof Error ? err.message : String(err);\n console.error(chalk.gray(`[debug] Token resolution failed: ${msg}`));\n }\n spinner.fail(chalk.red(\"Could not resolve GitLab token\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n\n const mrIid = await detectGitLabMR(remote, token, branch, options.insecure);\n if (mrIid === null) {\n spinner.fail(chalk.red(\"No open MR found for this branch\"));\n console.log();\n console.log(chalk.yellow(\"Cannot pull review comments without a PR or MR.\"));\n process.exit(1);\n }\n spinner.succeed(chalk.green(`Found MR !${mrIid}`));\n\n console.log();\n const commentSpinner = createLiveStatus(\"fetching review comments...\");\n comments = await fetchGitLabComments(remote, token, mrIid, options.insecure);\n\n if (comments.length === 0) {\n commentSpinner.info(chalk.yellow(\"No review comments found on this MR\"));\n return;\n }\n commentSpinner.succeed(chalk.green(`Fetched ${comments.length} comment(s)`));\n }\n\n // 6. Classify and display comment summary\n const classified = classifyComments(comments);\n console.log();\n displayCommentSummary(classified);\n\n // 7. Get git diff for context (token-budgeted)\n const diffSpinner = createLiveStatus(\"generating diff...\");\n const rawDiff = await exec(\"git\", [\"diff\", `${defaultBranch}...HEAD`]);\n let includedDiffs: FileDiff[] = [];\n let excludedFiles: string[] = [];\n if (!rawDiff.trim()) {\n diffSpinner.warn(chalk.yellow(\"No diff found against base branch\"));\n } else {\n const fileDiffs = splitDiffByFile(rawDiff);\n const reservedTokens = estimateTokens(formatCommentBlock(classified)) + RESERVED_PROMPT_TOKENS;\n ({ included: includedDiffs, excluded: excludedFiles } = selectDiffsWithinBudget(fileDiffs, MAX_REVIEW_TOKENS, reservedTokens));\n\n // Debug logging and telemetry for diff budget decisions\n const totalDiffTokens = includedDiffs.reduce((sum, f) => sum + f.tokens, 0);\n const excludedTokens = fileDiffs.filter(f => excludedFiles.includes(f.file)).reduce((sum, f) => sum + f.tokens, 0);\n const availableTokens = MAX_REVIEW_TOKENS - reservedTokens;\n\n if (isDebug()) {\n console.log(\n `[DEBUG] Diff budget: ${totalDiffTokens}/${availableTokens} tokens used ` +\n `(${includedDiffs.length}/${fileDiffs.length} files included, ${excludedFiles.length} excluded for ${excludedTokens} tokens)`\n );\n if (excludedFiles.length > 0) {\n console.log(`[DEBUG] Excluded files: ${excludedFiles.join(\", \")}`);\n }\n }\n\n // Emit telemetry event\n const chesstrace = getChesstrace();\n if (chesstrace) {\n try {\n chesstrace.emit(Events.REVIEW_DIFF_BUDGET, {\n filesIncluded: includedDiffs.length,\n filesExcluded: excludedFiles.length,\n tokensUsed: totalDiffTokens,\n tokensAvailable: availableTokens,\n excludedFilesList: excludedFiles,\n });\n } catch {\n // Swallow emit errors\n }\n }\n\n if (excludedFiles.length > 0) {\n diffSpinner.succeed(chalk.green(`Diff loaded (${includedDiffs.length} files included, ${excludedFiles.length} excluded for size)`));\n } else {\n diffSpinner.succeed(chalk.green(\"Diff loaded\"));\n }\n }\n\n // 8. Generate plan\n let plan: PlannerOutput;\n {\n const planSpinner = createLiveStatus(\"generating plan...\");\n plan = await generatePlan(classified, includedDiffs, excludedFiles);\n planSpinner.succeed(chalk.green(\"Plan generated\"));\n }\n\n displayPlan(plan);\n\n // 9. Approval loop with additional instructions support\n let userInstructions: string | undefined;\n\n if (!options.autoApprove) {\n resetTerminalForInput();\n let approved = false;\n while (!approved) {\n const action = await select({\n message: \"How would you like to proceed?\",\n choices: [\n { name: \"Approve — execute plan\", value: \"approve\" },\n { name: \"Provide feedback — regenerate plan\", value: \"feedback\" },\n { name: \"Add instructions — pass extra guidance to dev agent\", value: \"instructions\" },\n { name: \"Reject — exit without changes\", value: \"reject\" },\n ],\n });\n\n if (action === \"approve\") {\n approved = true;\n } else if (action === \"feedback\") {\n resetTerminalForInput();\n const feedback = await pasteableInput({\n message: \"Enter your feedback:\",\n });\n if (feedback.trim()) {\n const planSpinner = createLiveStatus(\"regenerating plan...\");\n plan = await generatePlan(classified, includedDiffs, excludedFiles, feedback);\n planSpinner.succeed(chalk.green(\"Plan regenerated\"));\n displayPlan(plan);\n }\n } else if (action === \"instructions\") {\n resetTerminalForInput();\n const extra = await pasteableInput({\n message: \"Enter additional instructions for the dev agent:\",\n });\n if (extra.trim()) {\n userInstructions = userInstructions\n ? `${userInstructions}\\n\\n${extra.trim()}`\n : extra.trim();\n console.log(chalk.green(\" Instructions saved. They will be included when executing.\"));\n const displayText = userInstructions.length > 200\n ? userInstructions.slice(0, 200) + \"...\"\n : userInstructions;\n console.log(chalk.gray(` Current instructions:\\n ${displayText.split(\"\\n\").join(\"\\n \")}`));\n console.log();\n }\n } else {\n console.log(chalk.yellow(\"\\n Rejected. No changes made.\\n\"));\n return;\n }\n }\n }\n\n // 10. Execute\n console.log();\n const execStatus = createLiveStatus(\"addressing review comments...\");\n\n // User approved the plan (or --auto-approve was set), so dev agent can write freely\n await executeWithDevAgent(classified, plan, true, execStatus.onActivity, userInstructions);\n execStatus.succeed(chalk.green(\"Dev agent finished\"));\n\n // 11. Commit and push changes\n console.log();\n const pushSpinner = createLiveStatus(\"committing and pushing...\");\n const trace = getChesstrace();\n const commitMessage = \"fix: address PR review comments\";\n const maxRetries = options.retryCommits ?? 3;\n let committed = false;\n try {\n await exec(\"git\", [\"add\", \"-A\"]);\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n committed = true;\n } catch (commitErr) {\n const msg = commitErr instanceof Error ? commitErr.message : String(commitErr);\n if (msg.includes(\"nothing to commit\")) {\n // Agent may have committed already — check if we have unpushed commits\n try {\n const ahead = await exec(\"git\", [\n \"rev-list\", \"--count\", `origin/${branch}..HEAD`,\n ]);\n if (parseInt(ahead.trim(), 10) > 0) {\n await exec(\"git\", [\"push\", \"origin\", branch]);\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n pushSpinner.succeed(chalk.green(\"Changes pushed.\"));\n } else {\n pushSpinner.warn(chalk.yellow(\"No changes were made by the dev agent.\"));\n }\n } catch {\n pushSpinner.warn(chalk.yellow(\"Nothing to commit or push.\"));\n }\n } else {\n // Pre-commit hook likely failed and may have modified files — retry with re-staging\n let retryCount = 0;\n while (retryCount < maxRetries) {\n retryCount++;\n pushSpinner.text = `pre-commit hook failed, re-staging and retrying (${retryCount}/${maxRetries})...`;\n try {\n await exec(\"git\", [\"add\", \"-A\"]);\n await exec(\"git\", [\"commit\", \"-m\", commitMessage]);\n committed = true;\n break;\n } catch (retryErr) {\n const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);\n if (retryCount >= maxRetries) {\n try { trace.emit(Events.GIT_ERROR, { operation: \"commit\", error: retryMsg, retriesExhausted: maxRetries }); } catch { /* swallow */ }\n pushSpinner.fail(chalk.red(`Commit failed after ${maxRetries} retries: ${retryMsg}`));\n }\n }\n }\n }\n }\n\n if (committed) {\n try { trace.emit(Events.GIT_COMMIT, { branch, messageSubject: commitMessage }); } catch { /* swallow */ }\n try {\n await exec(\"git\", [\"push\", \"origin\", branch]);\n try { trace.emit(Events.GIT_PUSH, { branch }); } catch { /* swallow */ }\n pushSpinner.succeed(chalk.green(\"Changes committed and pushed.\"));\n } catch (pushErr) {\n const pushMsg = pushErr instanceof Error ? pushErr.message : String(pushErr);\n try { trace.emit(Events.GIT_ERROR, { operation: \"push\", error: pushMsg }); } catch { /* swallow */ }\n pushSpinner.fail(chalk.red(`Push failed: ${pushMsg}`));\n }\n }\n\n console.log();\n console.log(chalk.green.bold(\" Done!\"), chalk.gray(\"Review comments addressed.\"));\n console.log();\n } catch (err) {\n if (err instanceof Error && err.name === \"ExitPromptError\") {\n process.exit(0);\n }\n if (err instanceof TaskError) {\n console.log(chalk.red.bold(\"Error:\"), err.message);\n if (isDebug()) console.error(err.stack);\n process.exit(1);\n }\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Internal error:\"), message);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n });\n}\n\n// Exported for unit testing\nexport {\n classifyComments,\n classifyComment,\n buildDevPrompt,\n PRIMARY_SECURITY_KEYWORDS,\n SECONDARY_SECURITY_KEYWORDS,\n};\nexport type { ReviewComment, ClassifiedComment };\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, lstatSync, renameSync, unlinkSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport chalk from \"chalk\";\nimport { select, confirm } from \"@inquirer/prompts\";\nimport { pasteableInput } from \"../pasteable-input.js\";\nimport { findLocalConfigDir, resolveGlobalConfigPath } from \"../config.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport type { AgentConfig } from \"../agents.js\";\nimport { builtinAgents } from \"../agents.js\";\nimport { PROVIDER_NAMES, getProvider } from \"../providers/index.js\";\nimport { isDebug } from \"../debug.js\";\nimport { resetTerminalForInput } from \"../terminal-reset.js\";\n\n/** Agent categories for grouped display */\nconst AGENT_CATEGORIES: { label: string; color: (s: string) => string; roles: string[] }[] = [\n {\n label: \"Development\",\n color: chalk.blue,\n roles: [\"developer\", \"general\"],\n },\n {\n label: \"Testing & Review\",\n color: chalk.magenta,\n roles: [\"quality-engineer\", \"security-reviewer\", \"reviewer\"],\n },\n {\n label: \"Planning\",\n color: chalk.yellow,\n roles: [\"planner\"],\n },\n];\n\ninterface AgentGroup {\n label: string;\n color: (s: string) => string;\n agentIndices: number[];\n}\n\nfunction categorizeAgents(agents: AgentConfig[]): AgentGroup[] {\n const groups: AgentGroup[] = [];\n const assigned = new Set<number>();\n\n for (const category of AGENT_CATEGORIES) {\n const indices: number[] = [];\n for (let i = 0; i < agents.length; i++) {\n if (assigned.has(i)) continue;\n if (category.roles.includes(agents[i]!.role)) {\n indices.push(i);\n assigned.add(i);\n }\n }\n if (indices.length > 0) {\n groups.push({\n label: category.label,\n color: category.color,\n agentIndices: indices,\n });\n }\n }\n\n // Uncategorized agents go into \"Other\"\n const remaining: number[] = [];\n for (let i = 0; i < agents.length; i++) {\n if (!assigned.has(i)) remaining.push(i);\n }\n if (remaining.length > 0) {\n groups.push({\n label: \"Other\",\n color: chalk.gray,\n agentIndices: remaining,\n });\n }\n\n return groups;\n}\n\n/** Map role to a colored badge string */\nfunction roleBadge(role: string): string {\n const badges: Record<string, (s: string) => string> = {\n \"developer\": chalk.bgBlue.white,\n \"general\": chalk.bgBlue.white,\n \"quality-engineer\": chalk.bgMagenta.white,\n \"security-reviewer\": chalk.bgRed.white,\n \"reviewer\": chalk.bgMagenta.white,\n \"planner\": chalk.bgYellow.black,\n };\n const colorFn = badges[role] ?? chalk.bgGray.white;\n return colorFn(` ${role} `);\n}\n\nexport async function configCommand(): Promise<void> {\n try {\n await runConfig();\n } catch (err) {\n // Ctrl+C from inquirer\n if (err && typeof err === \"object\" && \"name\" in err && (err as { name: string }).name === \"ExitPromptError\") {\n console.log(chalk.yellow(\"\\nConfiguration cancelled.\"));\n process.exit(0);\n }\n throw err;\n }\n}\n\nasync function runConfig(): Promise<void> {\n // Check for interactive environment before prompting\n if (!process.stdin.isTTY) {\n console.log(chalk.red.bold(\"Error:\"), \"config command requires interactive mode.\");\n console.log(chalk.gray(\" Edit\"), chalk.cyan(\".reygent/config.json\"), chalk.gray(\"or\"), chalk.cyan(\"~/.reygent/config.json\"), chalk.gray(\"directly.\"));\n process.exit(1);\n }\n\n // 1. Scope selection\n const scope = await select({\n message: \"Configuration scope:\",\n choices: [\n { name: `Local ${chalk.gray(\"— .reygent/config.json (this project)\")}`, value: \"local\" as const },\n { name: `Global ${chalk.gray(\"— ~/.reygent/config.json (all projects)\")}`, value: \"global\" as const },\n ],\n });\n\n let configPath: string;\n\n if (scope === \"local\") {\n const configDir = findLocalConfigDir(process.cwd());\n if (!configDir) {\n console.log(chalk.red.bold(\"Error:\"), \"No .reygent/ directory found.\");\n console.log(chalk.gray(\" Run\"), chalk.cyan(\"reygent init\"), chalk.gray(\"first.\"));\n console.log(\"\");\n process.exit(1);\n }\n configPath = join(configDir, \"config.json\");\n } else {\n configPath = resolveGlobalConfigPath();\n const globalDir = dirname(configPath);\n mkdirSync(globalDir, { recursive: true });\n }\n\n // 2. Load raw JSON (preserve unknown fields)\n let rawConfig: Record<string, unknown> = {};\n const fileExists = existsSync(configPath);\n\n if (fileExists) {\n try {\n const content = readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } catch (err) {\n if (err instanceof SyntaxError) {\n console.log(chalk.red.bold(\"Error:\"), `Invalid JSON in ${configPath}`);\n console.log(chalk.gray(\" Parse error:\"), err.message);\n process.exit(2);\n }\n if (err && typeof err === \"object\" && \"code\" in err && (err as { code?: string }).code === \"EACCES\") {\n console.log(chalk.red.bold(\"Error:\"), `Permission denied: ${configPath}`);\n process.exit(2);\n }\n console.log(chalk.red.bold(\"Error:\"), `Failed to read ${configPath}`);\n if (isDebug()) console.error(err);\n process.exit(2);\n }\n } else {\n // Initialize empty config with sensible defaults\n rawConfig = {\n provider: \"claude\",\n model: \"claude-sonnet-4-5\",\n };\n }\n\n // Initialize agents array before loop to ensure it always exists in output\n rawConfig.agents = (rawConfig.agents as AgentConfig[] | undefined) ?? builtinAgents;\n const agents: AgentConfig[] = rawConfig.agents as AgentConfig[];\n\n // 3. Check provider availability\n const availability: Record<string, { available: boolean; reason?: string }> = {};\n for (const name of PROVIDER_NAMES) {\n const provider = getProvider(name);\n availability[name] = await provider.isAvailable();\n }\n\n // 4. Show current config\n const currentProvider = (rawConfig.provider as string | undefined) ?? \"(not set)\";\n const currentModel = (rawConfig.model as string | undefined) ?? \"(not set)\";\n console.log(chalk.bold(\"Current config:\"));\n console.log(chalk.gray(\" Scope: \"), chalk.cyan(scope));\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(currentProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(currentModel));\n console.log(\"\");\n\n // 5. Select default provider\n const providerChoices = PROVIDER_NAMES.map((name) => {\n const status = availability[name];\n const badge = status?.available ? chalk.green(\"✓\") : chalk.red(\"✗\");\n const hint = !status?.available && status?.reason ? chalk.gray(` — ${status.reason}`) : \"\";\n return {\n name: `${badge} ${name}${hint}`,\n value: name,\n };\n });\n\n resetTerminalForInput();\n let selectedProvider = await select({\n message: \"Default provider:\",\n choices: providerChoices,\n default: rawConfig.provider as string | undefined,\n });\n\n // Warn if selected provider unavailable\n if (!availability[selectedProvider]?.available) {\n const reason = availability[selectedProvider]?.reason ?? \"unknown reason\";\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(`Provider ${selectedProvider} is unavailable (${reason})`));\n resetTerminalForInput();\n const proceed = await confirm({\n message: \"Continue with this provider anyway?\",\n default: false,\n });\n if (!proceed) {\n console.log(chalk.yellow(\"\\nConfiguration cancelled.\"));\n process.exit(0);\n }\n }\n\n // 6. Select default model\n const provider = getProvider(selectedProvider);\n let selectedModel: string;\n\n if (provider.supportedModels.length === 0) {\n // OpenRouter or similar — free-text input only\n resetTerminalForInput();\n selectedModel = await pasteableInput({\n message: \"Model ID:\",\n default: (rawConfig.model as string | undefined) ?? provider.defaultModel,\n });\n } else {\n // Providers with predefined models — offer list + custom option\n resetTerminalForInput();\n const modelChoices = provider.supportedModels.map((m) => ({\n name: `${m.id} — ${m.label}`,\n value: m.id,\n }));\n // Add \"Custom model\" option at end\n modelChoices.push({\n name: chalk.gray(\"Custom model (enter manually)\"),\n value: \"__custom__\",\n });\n\n const modelSelection = await select({\n message: \"Default model:\",\n choices: modelChoices,\n default: (rawConfig.model as string | undefined) ?? provider.defaultModel,\n });\n\n if (modelSelection === \"__custom__\") {\n resetTerminalForInput();\n selectedModel = await pasteableInput({\n message: \"Enter model ID:\",\n default: (rawConfig.model as string | undefined) ?? provider.defaultModel,\n });\n\n // Basic pattern validation for common typos\n if (selectedProvider === \"claude\") {\n // Claude models typically: claude-{family}-{version}[-{date}]\n if (!selectedModel.startsWith(\"claude-\") && !selectedModel.includes(\"projects/\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Claude format. Expected: claude-{family}-{version} or Vertex AI full resource name.\"));\n console.log(chalk.gray(\" Examples: claude-opus-4-6, projects/PROJECT/locations/REGION/publishers/anthropic/models/MODEL\"));\n }\n } else if (selectedProvider === \"gemini\") {\n // Gemini models typically: gemini-{version}-{variant}\n if (!selectedModel.startsWith(\"gemini-\") && !selectedModel.includes(\"projects/\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Gemini format. Expected: gemini-{version}-{variant} or Vertex AI full resource name.\"));\n console.log(chalk.gray(\" Examples: gemini-2.5-pro, projects/PROJECT/locations/REGION/publishers/google/models/MODEL\"));\n }\n } else if (selectedProvider === \"codex\") {\n // Codex models typically: gpt-{version}\n if (!selectedModel.startsWith(\"gpt-\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Codex format. Expected: gpt-{version}\"));\n console.log(chalk.gray(\" Examples: gpt-5.4, gpt-6.0\"));\n }\n }\n } else {\n selectedModel = modelSelection;\n }\n }\n\n // 7. Per-agent overrides — grouped by category\n const updatedAgents = [...agents];\n const categorized = categorizeAgents(agents);\n\n for (const group of categorized) {\n console.log(\"\");\n console.log(group.color(chalk.bold(`── ${group.label} ──`)));\n\n for (const agentIndex of group.agentIndices) {\n const agent = updatedAgents[agentIndex]!;\n const agentProvider = agent.provider ?? selectedProvider;\n const agentModel = agent.model ?? selectedModel;\n\n console.log(\"\");\n console.log(chalk.bold(agent.name), roleBadge(agent.role));\n console.log(chalk.gray(` ${agent.description}`));\n console.log(\n chalk.gray(\" Tools:\"),\n agent.tools.map((t) => chalk.cyan(t)).join(chalk.gray(\", \")),\n );\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(agentProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(agentModel));\n\n const hasOverride = agent.provider !== undefined || agent.model !== undefined;\n resetTerminalForInput();\n const action = await select({\n message: `Configure ${agent.name}:`,\n choices: [\n { name: \"Keep current\", value: \"keep\" },\n { name: \"Customize\", value: \"customize\" },\n ...(hasOverride ? [{ name: \"Clear overrides\", value: \"clear\" }] : []),\n ],\n default: \"keep\",\n });\n\n if (action === \"keep\") {\n continue;\n } else if (action === \"clear\") {\n // Remove provider/model overrides from this agent\n const { provider: _p, model: _m, ...rest } = agent;\n updatedAgents[agentIndex] = rest as AgentConfig;\n continue;\n }\n\n // action === \"customize\"\n resetTerminalForInput();\n const agentProviderChoice = await select({\n message: `Provider for ${agent.name}:`,\n choices: providerChoices,\n default: agent.provider ?? selectedProvider,\n });\n\n // Warn if selected provider unavailable\n if (!availability[agentProviderChoice]?.available) {\n const reason = availability[agentProviderChoice]?.reason ?? \"unknown reason\";\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(`Provider ${agentProviderChoice} is unavailable (${reason})`));\n resetTerminalForInput();\n const proceed = await confirm({\n message: \"Continue with this provider anyway?\",\n default: false,\n });\n if (!proceed) {\n continue; // Skip customization for this agent\n }\n }\n\n const agentProviderAdapter = getProvider(agentProviderChoice);\n let agentModelChoice: string;\n\n if (agentProviderAdapter.supportedModels.length === 0) {\n // Provider has no predefined models — free-text input only\n resetTerminalForInput();\n agentModelChoice = await pasteableInput({\n message: `Model ID for ${agent.name}:`,\n default: agent.model ?? agentProviderAdapter.defaultModel,\n });\n } else {\n // Providers with predefined models — offer list + custom option\n resetTerminalForInput();\n const agentModelChoices = agentProviderAdapter.supportedModels.map((m) => ({\n name: `${m.id} — ${m.label}`,\n value: m.id,\n }));\n // Add \"Custom model\" option at end\n agentModelChoices.push({\n name: chalk.gray(\"Custom model (enter manually)\"),\n value: \"__custom__\",\n });\n\n const agentModelSelection = await select({\n message: `Model for ${agent.name}:`,\n choices: agentModelChoices,\n default: agent.model ?? agentProviderAdapter.defaultModel,\n });\n\n if (agentModelSelection === \"__custom__\") {\n resetTerminalForInput();\n agentModelChoice = await pasteableInput({\n message: `Enter model ID for ${agent.name}:`,\n default: agent.model ?? agentProviderAdapter.defaultModel,\n });\n\n // Basic pattern validation for common typos\n if (agentProviderChoice === \"claude\") {\n if (!agentModelChoice.startsWith(\"claude-\") && !agentModelChoice.includes(\"projects/\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Claude format. Expected: claude-{family}-{version} or Vertex AI full resource name.\"));\n console.log(chalk.gray(\" Examples: claude-opus-4-6, projects/PROJECT/locations/REGION/publishers/anthropic/models/MODEL\"));\n }\n } else if (agentProviderChoice === \"gemini\") {\n if (!agentModelChoice.startsWith(\"gemini-\") && !agentModelChoice.includes(\"projects/\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Gemini format. Expected: gemini-{version}-{variant} or Vertex AI full resource name.\"));\n console.log(chalk.gray(\" Examples: gemini-2.5-pro, projects/PROJECT/locations/REGION/publishers/google/models/MODEL\"));\n }\n } else if (agentProviderChoice === \"codex\") {\n if (!agentModelChoice.startsWith(\"gpt-\")) {\n console.log(chalk.yellow(\"⚠\"), chalk.yellow(\"Model ID doesn't look like Codex format. Expected: gpt-{version}\"));\n console.log(chalk.gray(\" Examples: gpt-5.4, gpt-6.0\"));\n }\n }\n } else {\n agentModelChoice = agentModelSelection;\n }\n }\n\n updatedAgents[agentIndex] = { ...agent, provider: agentProviderChoice, model: agentModelChoice };\n }\n }\n\n // 8. Merge into raw config (only touch provider, model, and agent provider/model)\n rawConfig.provider = selectedProvider;\n rawConfig.model = selectedModel;\n\n // Match agents by name instead of index to handle length mismatches\n const rawAgents = rawConfig.agents as Record<string, unknown>[];\n for (const updatedAgent of updatedAgents) {\n const rawAgent = rawAgents.find((r) => r.name === updatedAgent.name);\n if (rawAgent) {\n // Update or remove provider/model fields\n if (updatedAgent.provider !== undefined) {\n rawAgent.provider = updatedAgent.provider;\n } else {\n delete rawAgent.provider;\n }\n if (updatedAgent.model !== undefined) {\n rawAgent.model = updatedAgent.model;\n } else {\n delete rawAgent.model;\n }\n }\n }\n\n // 9. Write config (atomic write to prevent TOCTOU race)\n try {\n const tempPath = `${configPath}.tmp.${randomBytes(8).toString(\"hex\")}`;\n\n try {\n // Write to temp file\n writeFileSync(tempPath, JSON.stringify(rawConfig, null, 2) + \"\\n\", \"utf-8\");\n\n // Security: verify temp file is not symlink\n const tempStats = lstatSync(tempPath);\n if (tempStats.isSymbolicLink()) {\n unlinkSync(tempPath);\n throw new Error(`Security: temp file became symlink`);\n }\n\n // Atomic rename\n renameSync(tempPath, configPath);\n } catch (err) {\n // Clean up temp file on error\n try {\n unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.red.bold(\"Error:\"), `Failed to write config: ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n process.exit(2);\n }\n\n // 10. Summary\n console.log(\"\");\n console.log(chalk.green.bold(\"✓\"), chalk.bold(\"Config updated\"));\n console.log(chalk.gray(\" Scope: \"), chalk.cyan(scope));\n console.log(chalk.gray(\" File: \"), chalk.gray(configPath));\n console.log(chalk.gray(\" Provider:\"), chalk.cyan(selectedProvider));\n console.log(chalk.gray(\" Model: \"), chalk.cyan(selectedModel));\n\n const overriddenAgents = updatedAgents.filter((a) => a.provider || a.model);\n if (overriddenAgents.length > 0) {\n console.log(chalk.gray(\" Agent overrides:\"));\n for (const a of overriddenAgents) {\n const parts: string[] = [];\n if (a.provider) parts.push(`provider=${a.provider}`);\n if (a.model) parts.push(`model=${a.model}`);\n console.log(chalk.gray(` ${a.name}:`), chalk.cyan(parts.join(\", \")));\n }\n }\n console.log(\"\");\n}\n","import { Command } from \"commander\";\nimport { readFileSync, statSync } from \"node:fs\";\nimport { writeFileSync } from \"node:fs\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig, resolveGlobalConfigPath, findLocalConfigDir } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { join } from \"node:path\";\n\n/**\n * Validate UUID format\n */\nfunction isValidUuid(value: string): boolean {\n const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n return uuidRegex.test(value);\n}\n\n/**\n * Parse duration string like \"30d\", \"7d\", \"1d\" into days\n */\nfunction parseDuration(duration: string): number {\n const match = duration.match(/^(\\d+)d$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${duration}. Use format like \"30d\", \"7d\", \"1d\".`);\n }\n return Number.parseInt(match[1], 10);\n}\n\n/**\n * Format bytes to human-readable size\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;\n}\n\n/**\n * Format timestamp to human-readable date\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(\"T\", \" \").replace(/\\.\\d{3}Z$/, \"\");\n}\n\n/**\n * Format duration in milliseconds to human-readable string\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\n/**\n * Get database size in bytes\n */\nfunction getDbSize(dbPath: string): number {\n try {\n const stats = statSync(dbPath);\n return stats.size;\n } catch {\n return 0;\n }\n}\n\n/**\n * reygent telemetry status - show config, run count, DB size\n */\nasync function statusCommand() {\n const spinner = ora(\"Loading telemetry status...\").start();\n\n try {\n const config = loadConfig();\n const telemetryConfig = config.telemetry;\n\n if (!telemetryConfig) {\n spinner.fail(chalk.red(\"Telemetry configuration not found\"));\n return;\n }\n\n // Initialize backend to get database info\n const backendType = telemetryConfig.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const runs = await backend.listRuns();\n const dbPath = backend.getDbPath();\n const dbSize = getDbSize(dbPath);\n\n await backend.close();\n\n spinner.succeed(chalk.green(\"Telemetry status loaded\"));\n\n console.log();\n console.log(chalk.bold(\"Telemetry Configuration\"));\n console.log(` Enabled: ${telemetryConfig.enabled === undefined ? chalk.yellow(\"unset (will prompt)\") : telemetryConfig.enabled ? chalk.green(\"yes\") : chalk.red(\"no\")}`);\n console.log(` Level: ${chalk.cyan(telemetryConfig.level)}`);\n console.log(` Backend: ${chalk.cyan(telemetryConfig.backend)}`);\n console.log(` Retention: ${chalk.cyan(`${telemetryConfig.retention} days`)}`);\n\n console.log();\n console.log(chalk.bold(\"Storage\"));\n console.log(` Database: ${chalk.gray(dbPath)}`);\n console.log(` Size: ${chalk.cyan(formatBytes(dbSize))}`);\n console.log(` Runs: ${chalk.cyan(runs.length.toString())}`);\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load telemetry status: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry runs [--limit N] - list recent runs (table format)\n */\nasync function runsCommand(options: { limit?: string }) {\n const spinner = ora(\"Loading telemetry runs...\").start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const allRuns = await backend.listRuns();\n await backend.close();\n\n let limit = allRuns.length;\n if (options.limit) {\n const parsed = Number.parseInt(options.limit, 10);\n if (isNaN(parsed) || parsed < 1) {\n spinner.fail(chalk.red(`Invalid limit: ${options.limit}. Must be positive integer.`));\n process.exit(1);\n }\n limit = parsed;\n }\n const runs = allRuns.slice(0, limit);\n\n spinner.succeed(chalk.green(`Loaded ${runs.length} run(s)`));\n\n if (runs.length === 0) {\n console.log(chalk.yellow(\"\\nNo telemetry runs found\"));\n return;\n }\n\n console.log();\n const table = new Table({\n head: [\n chalk.cyan(\"Run ID\"),\n chalk.cyan(\"Start Time\"),\n chalk.cyan(\"Duration\"),\n chalk.cyan(\"Events\"),\n chalk.cyan(\"Categories\"),\n ],\n colWidths: [38, 20, 12, 10, 30],\n });\n\n for (const run of runs) {\n const duration = run.endTime - run.startTime;\n table.push([\n run.runId,\n formatTimestamp(run.startTime),\n formatDuration(duration),\n run.eventCount.toString(),\n run.categories.join(\", \"),\n ]);\n }\n\n console.log(table.toString());\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load runs: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry show <runId> - detailed chronological event log\n */\nasync function showCommand(runId: string) {\n if (!isValidUuid(runId)) {\n console.error(chalk.red(`Invalid run ID format: ${runId}. Must be valid UUID.`));\n process.exit(1);\n }\n\n const spinner = ora(`Loading events for run ${runId}...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const events = await backend.query({ runId });\n await backend.close();\n\n if (events.length === 0) {\n spinner.fail(chalk.yellow(`No events found for run ${runId}`));\n return;\n }\n\n spinner.succeed(chalk.green(`Loaded ${events.length} event(s) for run ${runId}`));\n\n console.log();\n console.log(chalk.bold(`Events for run ${runId}`));\n console.log(chalk.gray(`Total events: ${events.length}`));\n console.log();\n\n for (const event of events) {\n const timestamp = formatTimestamp(event.timestamp);\n const category = chalk.cyan(`[${event.category}]`);\n const eventName = chalk.bold(event.event);\n const dataStr = Object.keys(event.data).length > 0 ? JSON.stringify(event.data, null, 2) : \"\";\n\n console.log(`${chalk.gray(timestamp)} ${category} ${eventName}`);\n if (dataStr) {\n // Apply gray color to entire data block for visual distinction\n const grayData = dataStr.split('\\n').map(line => chalk.gray(line)).join('\\n');\n console.log(grayData);\n }\n console.log();\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load events: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Export event data as JSON\n */\nfunction exportJson(events: TelemetryEvent[]): string {\n return JSON.stringify(events, null, 2);\n}\n\n/**\n * Export event data as CSV\n */\nfunction exportCsv(events: TelemetryEvent[]): string {\n const lines: string[] = [];\n lines.push(\"id,runId,timestamp,category,event,minLevel,data\");\n\n for (const event of events) {\n const dataStr = JSON.stringify(event.data).replace(/\"/g, '\"\"');\n lines.push(\n `\"${event.id}\",\"${event.runId}\",\"${event.timestamp}\",\"${event.category}\",\"${event.event}\",\"${event.minLevel}\",\"${dataStr}\"`,\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n/**\n * reygent telemetry export <runId> [--format json|csv] - export run data\n */\nasync function exportCommand(runId: string, options: { format?: string; output?: string }) {\n if (!isValidUuid(runId)) {\n console.error(chalk.red(`Invalid run ID format: ${runId}. Must be valid UUID.`));\n process.exit(1);\n }\n\n const format = options.format ?? \"json\";\n const spinner = ora(`Exporting run ${runId} as ${format.toUpperCase()}...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const events = await backend.query({ runId });\n await backend.close();\n\n if (events.length === 0) {\n spinner.fail(chalk.yellow(`No events found for run ${runId}`));\n return;\n }\n\n const data = format === \"json\" ? exportJson(events) : exportCsv(events);\n\n if (options.output) {\n writeFileSync(options.output, data, \"utf-8\");\n spinner.succeed(chalk.green(`Exported ${events.length} events to ${options.output}`));\n } else {\n spinner.succeed(chalk.green(`Exported ${events.length} events`));\n console.log();\n console.log(data);\n }\n } catch (err) {\n spinner.fail(chalk.red(`Failed to export run: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry prune [--older-than 30d] - delete old data\n */\nasync function pruneCommand(options: { olderThan?: string }) {\n const duration = options.olderThan ?? \"30d\";\n const days = parseDuration(duration);\n\n const spinner = ora(`Pruning events older than ${days} days...`).start();\n\n try {\n const config = loadConfig();\n const backendType = config.telemetry?.backend === \"sqlite\" ? \"local\" : \"local\";\n const backend = new SqliteBackend(backendType);\n await backend.init();\n\n const olderThan = Date.now() - days * 24 * 60 * 60 * 1000;\n const deleted = await backend.prune(olderThan);\n\n await backend.close();\n\n spinner.succeed(chalk.green(`Pruned ${deleted} event(s) older than ${days} days`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to prune events: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry enable - enable telemetry in config\n */\nasync function enableCommand() {\n const spinner = ora(\"Enabling telemetry...\").start();\n\n try {\n // Check for local config first\n const localConfigDir = findLocalConfigDir(process.cwd());\n const configPath = localConfigDir\n ? join(localConfigDir, \"config.json\")\n : resolveGlobalConfigPath();\n\n const config = loadConfig();\n\n config.telemetry = config.telemetry ?? {\n level: \"standard\",\n backend: \"sqlite\",\n retention: 30,\n };\n config.telemetry.enabled = true;\n\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n const scope = localConfigDir ? \"local\" : \"global\";\n spinner.succeed(chalk.green(`Telemetry enabled (${scope} config)`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to enable telemetry: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent telemetry disable - disable telemetry in config\n */\nasync function disableCommand() {\n const spinner = ora(\"Disabling telemetry...\").start();\n\n try {\n // Check for local config first\n const localConfigDir = findLocalConfigDir(process.cwd());\n const configPath = localConfigDir\n ? join(localConfigDir, \"config.json\")\n : resolveGlobalConfigPath();\n\n const config = loadConfig();\n\n config.telemetry = config.telemetry ?? {\n level: \"standard\",\n backend: \"sqlite\",\n retention: 30,\n };\n config.telemetry.enabled = false;\n\n writeFileSync(configPath, JSON.stringify(config, null, 2), \"utf-8\");\n\n const scope = localConfigDir ? \"local\" : \"global\";\n spinner.succeed(chalk.green(`Telemetry disabled (${scope} config)`));\n } catch (err) {\n spinner.fail(chalk.red(`Failed to disable telemetry: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Register telemetry command and subcommands\n */\nexport function registerTelemetryCommand(program: Command): void {\n const telemetry = program\n .command(\"telemetry\")\n .description(\"Manage telemetry data and configuration\");\n\n telemetry\n .command(\"status\")\n .description(\"Show telemetry configuration and storage status\")\n .action(statusCommand);\n\n telemetry\n .command(\"runs\")\n .description(\"List recent telemetry runs\")\n .option(\"--limit <n>\", \"Limit number of runs to display\")\n .action(runsCommand);\n\n telemetry\n .command(\"show\")\n .description(\"Show detailed event log for a specific run\")\n .argument(\"<runId>\", \"Run ID to display\")\n .action(showCommand);\n\n telemetry\n .command(\"export\")\n .description(\"Export run data to JSON or CSV\")\n .argument(\"<runId>\", \"Run ID to export\")\n .addOption(\n program\n .createOption(\"--format <type>\", \"Export format\")\n .choices([\"json\", \"csv\"])\n .default(\"json\")\n )\n .option(\"--output <file>\", \"Output file path (prints to stdout if omitted)\")\n .action(exportCommand);\n\n telemetry\n .command(\"prune\")\n .description(\"Delete old telemetry data\")\n .option(\"--older-than <duration>\", \"Delete events older than duration (e.g., 30d, 7d)\", \"30d\")\n .action(pruneCommand);\n\n telemetry\n .command(\"enable\")\n .description(\"Enable telemetry in configuration\")\n .action(enableCommand);\n\n telemetry\n .command(\"disable\")\n .description(\"Disable telemetry in configuration\")\n .action(disableCommand);\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport { analyzeFailurePatterns, analyzeSuccessPatterns } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { getLocalTelemetryPath } from \"../telemetry-path.js\";\n\n/**\n * Cost estimation constants\n */\n// Conservative estimate of retry cost as fraction of total monthly spend\n// Based on typical gate retry patterns adding ~10% overhead\nconst RETRY_COST_ESTIMATE_MULTIPLIER = 0.1;\n\n// Conservative estimate of recoverable failure cost as fraction of failed spend\n// Assumes ~50% of failures preventable through config/prompt improvements\nconst POTENTIAL_SAVINGS_MULTIPLIER = 0.5;\n\ninterface AnalyzeOptions {\n agent?: string;\n since?: string;\n limit?: string;\n stage?: string;\n minSuccessRate?: string;\n byAgent?: boolean;\n showRuns?: boolean;\n compareModels?: boolean;\n updateKnowledge?: boolean;\n}\n\n/**\n * Parse duration string like \"30d\", \"7d\" into timestamp\n */\nfunction parseSince(since: string): number {\n const match = since.match(/^(\\d+)d$/);\n if (!match) {\n throw new Error(`Invalid duration format: ${since}. Use format like \"30d\", \"7d\".`);\n }\n const days = Number.parseInt(match[1], 10);\n return Date.now() - days * 24 * 60 * 60 * 1000;\n}\n\n/**\n * Format timestamp to relative time\n */\nfunction formatRelativeTime(timestamp: number): string {\n const now = Date.now();\n const diff = now - timestamp;\n const days = Math.floor(diff / (24 * 60 * 60 * 1000));\n const hours = Math.floor(diff / (60 * 60 * 1000));\n\n if (days > 0) return `${days} day${days > 1 ? \"s\" : \"\"} ago`;\n if (hours > 0) return `${hours} hour${hours > 1 ? \"s\" : \"\"} ago`;\n return \"< 1 hour ago\";\n}\n\n/**\n * Format duration in milliseconds\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n\n if (minutes > 0) return `${minutes}m ${seconds % 60}s`;\n return `${seconds}s`;\n}\n\n/**\n * Format USD cost\n */\nfunction formatCost(usd: number): string {\n return `$${usd.toFixed(2)}`;\n}\n\n/**\n * Format percentage\n */\nfunction formatPercent(value: number): string {\n return `${Math.round(value * 100)}%`;\n}\n\n/**\n * Group events by key function\n */\nfunction groupBy<T>(items: T[], keyFn: (item: T) => string): Map<string, T[]> {\n const groups = new Map<string, T[]>();\n for (const item of items) {\n const key = keyFn(item);\n const group = groups.get(key) ?? [];\n group.push(item);\n groups.set(key, group);\n }\n return groups;\n}\n\n/**\n * Filter events by category or event type\n */\nfunction filterEvents(\n events: TelemetryEvent[],\n criteria: { category?: string; event?: string }\n): TelemetryEvent[] {\n return events.filter(e => {\n if (criteria.category && e.category !== criteria.category) return false;\n if (criteria.event && e.event !== criteria.event) return false;\n return true;\n });\n}\n\n/**\n * Get backend instance\n */\nasync function getBackend(): Promise<SqliteBackend> {\n // Match writer path from run.ts\n const dbPath = getLocalTelemetryPath(process.cwd());\n const backend = new SqliteBackend(\"local\", dbPath);\n await backend.init();\n return backend;\n}\n\n/**\n * Check if telemetry is enabled\n */\nfunction checkTelemetryEnabled(config: ReturnType<typeof loadConfig>): void {\n if (!config.telemetry?.enabled) {\n console.log(chalk.yellow(\"\\nTelemetry is disabled. Enable with:\"));\n console.log(chalk.cyan(\" reygent telemetry enable\\n\"));\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze failures - show common failure patterns\n */\nexport async function analyzeFailures(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing failure patterns...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n // Query all error events\n const allEvents = await backend.query({ startTime: since });\n const errorEvents = filterEvents(allEvents, { category: \"error\" });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n\n await backend.close();\n\n if (errorEvents.length === 0) {\n spinner.succeed(chalk.green(\"No failures found\"));\n console.log(chalk.yellow(\"\\nNo error events in telemetry data\"));\n return;\n }\n\n const totalRuns = new Set(pipelineEvents.map(e => e.runId)).size;\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${errorEvents.length} error(s) from ${totalRuns} run(s)`));\n\n console.log();\n console.log(chalk.bold(`Failure Analysis (last ${days} days, ${totalRuns} runs)`));\n console.log();\n\n // Group by event type\n const patternGroups = groupBy(errorEvents, e => e.event);\n\n // Sort by occurrence count\n const sortedPatterns = Array.from(patternGroups.entries())\n .sort((a, b) => b[1].length - a[1].length);\n\n // Apply limit\n const limit = options.limit ? Number.parseInt(options.limit, 10) : sortedPatterns.length;\n const topPatterns = sortedPatterns.slice(0, limit);\n\n console.log(chalk.bold(\"Top Failure Patterns:\"));\n console.log();\n\n for (let i = 0; i < topPatterns.length; i++) {\n const [eventName, events] = topPatterns[i];\n const agentGroups = groupBy(events, e => (e.data.agent as string) || \"unknown\");\n const mostRecent = events.reduce((a, b) => a.timestamp > b.timestamp ? a : b);\n\n console.log(chalk.cyan(`${i + 1}. ${eventName}`) + chalk.gray(` (${events.length} occurrences)`));\n\n // Show agent breakdown\n const agentSummary = Array.from(agentGroups.entries())\n .map(([agent, events]) => `${agent} (${events.length})`)\n .join(\", \");\n console.log(` Agents: ${agentSummary}`);\n\n // Show common message if available\n const messages = events\n .map(e => e.data.message as string)\n .filter(Boolean);\n if (messages.length > 0) {\n const commonMsg = messages[0] ?? \"Unknown error\";\n console.log(` Common: \"${commonMsg}\"`);\n }\n\n // Show most recent\n console.log(` Most recent: run ${mostRecent.runId.substring(0, 8)} (${formatRelativeTime(mostRecent.timestamp)})`);\n console.log();\n }\n\n // Recommendations\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Parse error recommendations\n const parseErrors = errorEvents.filter(e => e.event === Events.ERROR_PARSE);\n if (parseErrors.length > 0) {\n const parseAgents = new Set(parseErrors.map(e => e.data.agent as string));\n for (const agent of parseAgents) {\n const count = parseErrors.filter(e => e.data.agent === agent).length;\n recommendations.push(`• ${agent} has ${count} parse failure(s) - review output format expectations`);\n }\n }\n\n // Gate retry recommendations\n const gateRetries = allEvents.filter(e => e.event === Events.GATE_RETRY);\n if (gateRetries.length > 0) {\n const gateGroups = groupBy(gateRetries, e => e.data.gateName as string);\n for (const [gateName, events] of gateGroups) {\n const avgAttempts = events.reduce((sum, e) => sum + (e.data.attempt as number), 0) / events.length;\n recommendations.push(`• ${gateName} requires ${avgAttempts.toFixed(1)} avg retries - consider relaxing criteria`);\n }\n }\n\n // Provider error recommendations\n const providerErrors = errorEvents.filter(e => e.event === Events.ERROR_PROVIDER);\n if (providerErrors.length > 0) {\n const reasons = providerErrors.map(e => e.data.reason as string).filter(Boolean);\n if (reasons.some(r => r.includes(\"rate limit\"))) {\n recommendations.push(\"• Rate limits hit during peak hours - consider request throttling\");\n }\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n // Update knowledge if requested\n if (options.updateKnowledge) {\n const updateSpinner = ora(\"Updating knowledge base...\").start();\n\n try {\n // Reopen backend for analyzer (was closed earlier)\n const analysisBackend = await getBackend();\n // Use analyzer to extract structured patterns\n const patterns = analyzeFailurePatterns(analysisBackend, since);\n await analysisBackend.close();\n\n if (patterns.length === 0) {\n updateSpinner.info(chalk.yellow(\"No recurring patterns to add\"));\n } else {\n let addedCount = 0;\n const limit = options.limit ? Number.parseInt(options.limit, 10) : 5;\n\n for (const pattern of patterns.slice(0, limit)) {\n // Add entry for each agent affected\n for (const agent of pattern.agents) {\n await addFailureEntry(process.cwd(), {\n issue: pattern.pattern,\n solution: \"Review telemetry for details\",\n agent: agent as any,\n });\n addedCount++;\n }\n }\n\n updateSpinner.succeed(chalk.green(`Added ${addedCount} failure pattern(s) to knowledge base`));\n console.log(chalk.gray(` See .reygent/knowledge/common-failures.md`));\n console.log();\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n updateSpinner.fail(chalk.red(`Failed to update knowledge: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeFailures knowledge update error:', err);\n }\n }\n }\n\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to analyze failures: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeFailures error:', err);\n }\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze success - extract patterns from successful runs\n */\nexport async function analyzeSuccess(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing success patterns...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n const agentSpawnEvents = filterEvents(allEvents, { event: Events.AGENT_SPAWN });\n const agentCompleteEvents = filterEvents(allEvents, { event: Events.AGENT_COMPLETE });\n\n await backend.close();\n\n const successfulRuns = pipelineEvents.filter(e => e.data.success === true);\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n if (successfulRuns.length === 0) {\n spinner.succeed(chalk.yellow(\"No successful runs found\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Analyzed ${successfulRuns.length} successful run(s)`));\n\n console.log();\n console.log(chalk.bold(`Success Analysis (last ${days} days, ${successfulRuns.length} successful runs)`));\n console.log();\n\n // Agent Performance\n console.log(chalk.bold(\"Agent Performance:\"));\n console.log();\n\n const agentStats = new Map<string, {\n spawns: number;\n completions: number;\n successes: number;\n totalDuration: number;\n models: Map<string, number>;\n }>();\n\n for (const spawn of agentSpawnEvents) {\n const agent = spawn.data.agent as string;\n const model = spawn.data.model as string;\n\n const stats = agentStats.get(agent) || {\n spawns: 0,\n completions: 0,\n successes: 0,\n totalDuration: 0,\n models: new Map(),\n };\n\n stats.spawns++;\n stats.models.set(model, (stats.models.get(model) || 0) + 1);\n agentStats.set(agent, stats);\n }\n\n for (const complete of agentCompleteEvents) {\n const agent = complete.data.agent as string;\n const success = complete.data.success === true;\n const duration = complete.data.duration as number;\n\n const stats = agentStats.get(agent);\n if (stats) {\n stats.completions++;\n if (success) stats.successes++;\n if (duration) stats.totalDuration += duration;\n }\n }\n\n for (const [agent, stats] of agentStats) {\n const successRate = stats.completions > 0 ? stats.successes / stats.completions : 0;\n const avgDuration = stats.completions > 0 ? stats.totalDuration / stats.completions : 0;\n\n // Apply min success rate filter if provided\n if (options.minSuccessRate) {\n const minRate = Number.parseFloat(options.minSuccessRate) / 100;\n if (successRate < minRate) continue;\n }\n\n // Apply --stage filter if provided\n if (options.stage) {\n // Filter agent events by stage\n const stageEvents = allEvents.filter(e =>\n e.data.stage === options.stage &&\n (e.event === Events.AGENT_SPAWN || e.event === Events.AGENT_COMPLETE)\n );\n const stageAgents = new Set(stageEvents.map(e => e.data.agent as string));\n if (!stageAgents.has(agent)) continue;\n }\n\n console.log(chalk.cyan(`${agent}:`));\n console.log(` Runs: ${stats.completions}`);\n console.log(` Success rate: ${formatPercent(successRate)} (${stats.successes} success, ${stats.completions - stats.successes} failures)`);\n console.log(` Avg duration: ${formatDuration(avgDuration)}`);\n\n const modelDist = Array.from(stats.models.entries())\n .map(([model, count]) => `${model} (${Math.round(count / stats.completions * 100)}%)`)\n .join(\", \");\n console.log(` Model distribution: ${modelDist}`);\n console.log();\n }\n\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Find best performers\n const sortedAgents = Array.from(agentStats.entries())\n .filter(([_, stats]) => stats.completions > 0)\n .map(([agent, stats]) => ({\n agent,\n successRate: stats.successes / stats.completions,\n completions: stats.completions,\n }))\n .sort((a, b) => b.successRate - a.successRate);\n\n if (sortedAgents.length > 0) {\n const best = sortedAgents[0];\n if (best.successRate >= 0.9) {\n recommendations.push(`• ${best.agent}: Best performer (${formatPercent(best.successRate)} success)`);\n }\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n // Update knowledge if requested\n if (options.updateKnowledge) {\n const updateSpinner = ora(\"Updating knowledge base...\").start();\n\n try {\n // Reopen backend for analyzer (was closed earlier)\n const analysisBackend = await getBackend();\n // Use analyzer to extract structured patterns\n const minRate = options.minSuccessRate ? Number.parseFloat(options.minSuccessRate) / 100 : 0.8;\n const patterns = analyzeSuccessPatterns(analysisBackend, since, minRate);\n await analysisBackend.close();\n\n if (patterns.length === 0) {\n updateSpinner.info(chalk.yellow(\"No high-success patterns to add\"));\n } else {\n let addedCount = 0;\n const limit = 5; // Top 5 patterns\n\n for (const pattern of patterns.slice(0, limit)) {\n await addPatternEntry(process.cwd(), {\n description: pattern.pattern,\n successRate: Math.round(pattern.successRate * 100),\n });\n addedCount++;\n }\n\n updateSpinner.succeed(chalk.green(`Added ${addedCount} success pattern(s) to knowledge base`));\n console.log(chalk.gray(` See .reygent/knowledge/success-patterns.md`));\n console.log();\n }\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n updateSpinner.fail(chalk.red(`Failed to update knowledge: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeSuccess knowledge update error:', err);\n }\n }\n }\n\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n spinner.fail(chalk.red(`Failed to analyze success: ${errMsg}`));\n if (process.env.REYGENT_DEBUG === '1' || process.env.REYGENT_DEBUG === 'telemetry') {\n console.error('[debug:telemetry] analyzeSuccess error:', err);\n }\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze costs - cost breakdown and optimization\n */\nexport async function analyzeCosts(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing costs...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const costEvents = filterEvents(allEvents, { event: Events.USAGE_COST });\n const pipelineEvents = filterEvents(allEvents, { event: Events.PIPELINE_END });\n\n await backend.close();\n\n if (costEvents.length === 0) {\n spinner.succeed(chalk.yellow(\"No cost data found\"));\n console.log(chalk.gray(\"\\nEnable verbose telemetry to track costs:\"));\n console.log(chalk.cyan(\" reygent run --telemetry-level verbose\\n\"));\n return;\n }\n\n const totalRuns = new Set(pipelineEvents.map(e => e.runId)).size;\n const successfulRuns = pipelineEvents.filter(e => e.data.success === true).length;\n const failedRuns = totalRuns - successfulRuns;\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${costEvents.length} cost event(s)`));\n\n console.log();\n console.log(chalk.bold(`Cost Analysis (last ${days} days, ${totalRuns} runs)`));\n console.log();\n\n // Calculate total costs\n const totalCost = costEvents.reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n\n // Separate successful vs failed run costs\n const successRunIds = new Set(\n pipelineEvents.filter(e => e.data.success === true).map(e => e.runId)\n );\n const successCost = costEvents\n .filter(e => successRunIds.has(e.runId))\n .reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n const failedCost = totalCost - successCost;\n\n console.log(chalk.bold(\"Total Spend:\"), chalk.cyan(formatCost(totalCost)));\n console.log(`Successful runs: ${formatCost(successCost)} (${formatPercent(successCost / totalCost)})`);\n console.log(`Failed runs: ${formatCost(failedCost)} (${formatPercent(failedCost / totalCost)} - wasted)`);\n console.log();\n\n // Cost by stage (if available)\n if (options.byAgent) {\n console.log(chalk.bold(\"Cost by Agent:\"));\n const agentCosts = new Map<string, { cost: number; runs: Set<string> }>();\n\n for (const event of costEvents) {\n const agent = event.data.agent as string || \"unknown\";\n const cost = event.data.costUsd as number;\n const existing = agentCosts.get(agent) || { cost: 0, runs: new Set() };\n existing.cost += cost;\n existing.runs.add(event.runId);\n agentCosts.set(agent, existing);\n }\n\n const sortedAgents = Array.from(agentCosts.entries())\n .sort((a, b) => b[1].cost - a[1].cost);\n\n for (const [agent, data] of sortedAgents) {\n const percent = (data.cost / totalCost) * 100;\n const avgCost = data.cost / data.runs.size;\n console.log(` ${agent}: ${formatCost(data.cost)} (${percent.toFixed(0)}%) - ${data.runs.size} runs, avg ${formatCost(avgCost)}/run`);\n }\n console.log();\n } else {\n console.log(chalk.bold(\"Cost by Stage:\"));\n const stageCosts = new Map<string, { cost: number; runs: Set<string> }>();\n\n for (const event of costEvents) {\n const stage = (event.data.stage as string) ?? \"unknown\";\n const cost = event.data.costUsd as number;\n const existing = stageCosts.get(stage) || { cost: 0, runs: new Set() };\n existing.cost += cost;\n existing.runs.add(event.runId);\n stageCosts.set(stage, existing);\n }\n\n const sortedStages = Array.from(stageCosts.entries())\n .sort((a, b) => b[1].cost - a[1].cost);\n\n for (const [stage, data] of sortedStages) {\n const percent = (data.cost / totalCost) * 100;\n const avgCost = data.cost / data.runs.size;\n console.log(` ${stage}: ${formatCost(data.cost)} (${percent.toFixed(0)}%) - ${data.runs.size} runs, avg ${formatCost(avgCost)}/run`);\n }\n console.log();\n }\n\n // Expensive failures\n if (failedRuns > 0 && options.showRuns) {\n console.log(chalk.bold(\"Expensive Failures (top 3):\"));\n\n const failedRunIds = new Set(\n pipelineEvents\n .filter(e => e.data.success !== true)\n .map(e => e.runId)\n );\n\n const failureRunCosts = new Map<string, number>();\n for (const event of costEvents) {\n if (failedRunIds.has(event.runId)) {\n const existing = failureRunCosts.get(event.runId) || 0;\n failureRunCosts.set(event.runId, existing + (event.data.costUsd as number));\n }\n }\n\n // Build Map for O(1) stage lookups\n const runIdToStage = new Map<string, string>();\n for (const event of allEvents) {\n if (event.event === Events.PIPELINE_STAGE_END) {\n runIdToStage.set(event.runId, (event.data.stage as string) || \"unknown\");\n }\n }\n\n const topFailures = Array.from(failureRunCosts.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3);\n\n for (let i = 0; i < topFailures.length; i++) {\n const [runId, cost] = topFailures[i];\n const stage = runIdToStage.get(runId) || \"unknown stage\";\n console.log(` ${i + 1}. run ${runId.substring(0, 8)}: ${formatCost(cost)} (${stage})`);\n }\n console.log();\n }\n\n // Optimization opportunities\n console.log(chalk.bold(\"Optimization Opportunities:\"));\n const recommendations: string[] = [];\n\n if (failedCost > 0) {\n const wastePercent = (failedCost / totalCost) * 100;\n recommendations.push(`• ${formatPercent(failedCost / totalCost)} spend on failed runs - see 'reygent analyze failures' to reduce`);\n }\n\n const gateRetries = allEvents.filter(e => e.event === Events.GATE_RETRY);\n if (gateRetries.length > 0) {\n const monthlyCost = (totalCost / days) * 30;\n const retryCostEst = monthlyCost * RETRY_COST_ESTIMATE_MULTIPLIER;\n recommendations.push(`• Gate retry loops cost ~${formatCost(retryCostEst)}/month - review gate criteria`);\n }\n\n const potentialSavings = failedCost * POTENTIAL_SAVINGS_MULTIPLIER;\n if (potentialSavings > 0) {\n const monthlySavings = (potentialSavings / days) * 30;\n recommendations.push(`\\nPotential Savings: ${formatCost(monthlySavings)}/month (${formatPercent(potentialSavings / totalCost)})`);\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to analyze costs: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * reygent analyze agents - agent-specific performance breakdown\n */\nexport async function analyzeAgents(options: AnalyzeOptions): Promise<void> {\n const spinner = ora(\"Analyzing agent performance...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n const backend = await getBackend();\n const since = options.since ? parseSince(options.since) : Date.now() - 30 * 24 * 60 * 60 * 1000;\n\n const allEvents = await backend.query({ startTime: since });\n const agentSpawnEvents = filterEvents(allEvents, { event: Events.AGENT_SPAWN });\n const agentCompleteEvents = filterEvents(allEvents, { event: Events.AGENT_COMPLETE });\n const errorEvents = filterEvents(allEvents, { category: \"error\" });\n const costEvents = filterEvents(allEvents, { event: Events.USAGE_COST });\n\n await backend.close();\n\n if (agentSpawnEvents.length === 0) {\n spinner.succeed(chalk.yellow(\"No agent data found\"));\n return;\n }\n\n const days = Math.floor((Date.now() - since) / (24 * 60 * 60 * 1000));\n\n spinner.succeed(chalk.green(`Analyzed ${agentSpawnEvents.length} agent spawn(s)`));\n\n console.log();\n console.log(chalk.bold(`Agent Performance Analysis (last ${days} days)`));\n console.log();\n\n // Build per-agent stats\n interface AgentStats {\n spawns: number;\n completions: number;\n successes: number;\n failures: number;\n totalDuration: number;\n totalCost: number;\n models: Map<string, number>;\n errorTypes: Map<string, number>;\n }\n\n const agentStats = new Map<string, AgentStats>();\n\n // Process spawns\n for (const spawn of agentSpawnEvents) {\n const agent = spawn.data.agent as string;\n const model = spawn.data.model as string;\n\n const stats = agentStats.get(agent) || {\n spawns: 0,\n completions: 0,\n successes: 0,\n failures: 0,\n totalDuration: 0,\n totalCost: 0,\n models: new Map(),\n errorTypes: new Map(),\n };\n\n stats.spawns++;\n stats.models.set(model, (stats.models.get(model) || 0) + 1);\n agentStats.set(agent, stats);\n }\n\n // Process completions\n for (const complete of agentCompleteEvents) {\n const agent = complete.data.agent as string;\n const success = complete.data.success === true;\n const duration = complete.data.duration as number;\n\n const stats = agentStats.get(agent);\n if (stats) {\n stats.completions++;\n if (success) {\n stats.successes++;\n } else {\n stats.failures++;\n }\n if (duration) stats.totalDuration += duration;\n }\n }\n\n // Process errors\n for (const error of errorEvents) {\n const agent = error.data.agent as string;\n const stats = agentStats.get(agent);\n if (stats) {\n const errorType = error.event;\n stats.errorTypes.set(errorType, (stats.errorTypes.get(errorType) || 0) + 1);\n }\n }\n\n // Process costs\n for (const cost of costEvents) {\n const agent = cost.data.agent as string;\n const stats = agentStats.get(agent);\n if (stats) {\n stats.totalCost += cost.data.costUsd as number;\n }\n }\n\n // Filter by specific agent if provided\n let agentsToShow: [string, AgentStats][];\n if (options.agent) {\n const requestedStats = agentStats.get(options.agent);\n if (!requestedStats) {\n spinner.warn(chalk.yellow(`Agent \"${options.agent}\" not found in telemetry data`));\n console.log(chalk.gray(`\\nAvailable agents: ${Array.from(agentStats.keys()).join(\", \")}`));\n return;\n }\n agentsToShow = [[options.agent, requestedStats]];\n } else {\n agentsToShow = Array.from(agentStats.entries());\n }\n\n // Display agent stats\n for (const [agent, stats] of agentsToShow) {\n\n const successRate = stats.completions > 0 ? stats.successes / stats.completions : 0;\n const avgDuration = stats.completions > 0 ? stats.totalDuration / stats.completions : 0;\n const avgCost = stats.completions > 0 ? stats.totalCost / stats.completions : 0;\n\n console.log(chalk.bold.cyan(agent + \":\"));\n console.log(` Runs: ${stats.completions}`);\n console.log(` Success rate: ${formatPercent(successRate)} (${stats.successes} success, ${stats.failures} failures)`);\n console.log(` Avg duration: ${formatDuration(avgDuration)}`);\n\n if (stats.totalCost > 0) {\n console.log(` Avg cost: ${formatCost(avgCost)}`);\n }\n\n const modelDist = Array.from(stats.models.entries())\n .map(([model, count]) => `${model} (${Math.round(count / stats.spawns * 100)}%)`)\n .join(\", \");\n console.log(` Model distribution: ${modelDist}`);\n\n // Compare models if requested\n if (options.compareModels && stats.models.size > 1) {\n console.log(`\\n Model Comparison:`);\n\n // Build model-specific stats\n const modelPerformance = new Map<string, { successes: number; failures: number; totalDuration: number; totalCost: number; count: number }>();\n\n for (const complete of agentCompleteEvents) {\n if (complete.data.agent !== agent) continue;\n\n // Find corresponding spawn to get model\n const spawn = agentSpawnEvents.find(s =>\n s.runId === complete.runId &&\n s.data.agent === agent &&\n s.timestamp <= complete.timestamp\n );\n\n if (!spawn) continue;\n const model = spawn.data.model as string;\n\n const perf = modelPerformance.get(model) || { successes: 0, failures: 0, totalDuration: 0, totalCost: 0, count: 0 };\n perf.count++;\n if (complete.data.success === true) {\n perf.successes++;\n } else {\n perf.failures++;\n }\n if (complete.data.duration) {\n perf.totalDuration += complete.data.duration as number;\n }\n\n // Find costs for this completion\n const runCosts = costEvents.filter(c => c.runId === complete.runId && c.data.agent === agent);\n for (const costEvent of runCosts) {\n perf.totalCost += costEvent.data.costUsd as number;\n }\n\n modelPerformance.set(model, perf);\n }\n\n for (const [model, perf] of modelPerformance) {\n const successRate = perf.count > 0 ? perf.successes / perf.count : 0;\n const avgDuration = perf.count > 0 ? perf.totalDuration / perf.count : 0;\n const avgCost = perf.count > 0 ? perf.totalCost / perf.count : 0;\n\n console.log(` ${model}: ${formatPercent(successRate)} success, avg ${formatDuration(avgDuration)}, avg ${formatCost(avgCost)}`);\n }\n console.log();\n }\n\n if (stats.errorTypes.size > 0) {\n const topErrors = Array.from(stats.errorTypes.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 3)\n .map(([type, count]) => `${type} (${count})`)\n .join(\", \");\n console.log(` Top failures: ${topErrors}`);\n }\n\n console.log();\n }\n\n // Recommendations\n console.log(chalk.bold(\"Recommendations:\"));\n const recommendations: string[] = [];\n\n // Find agents with high error rates\n for (const [agent, stats] of agentStats) {\n if (stats.completions > 0) {\n const failureRate = stats.failures / stats.completions;\n if (failureRate > 0.2 && stats.errorTypes.size > 0) {\n const topError = Array.from(stats.errorTypes.entries())\n .sort((a, b) => b[1] - a[1])[0];\n recommendations.push(`• ${agent}: High failure rate (${formatPercent(failureRate)}) - review ${topError[0]} errors`);\n }\n }\n }\n\n // Find best performer\n const sortedBySuccess = Array.from(agentStats.entries())\n .filter(([_, stats]) => stats.completions > 0)\n .map(([agent, stats]) => ({\n agent,\n successRate: stats.successes / stats.completions,\n }))\n .sort((a, b) => b.successRate - a.successRate);\n\n if (sortedBySuccess.length > 0 && sortedBySuccess[0].successRate >= 0.9) {\n recommendations.push(`• ${sortedBySuccess[0].agent}: Best performer (${formatPercent(sortedBySuccess[0].successRate)} success)`);\n }\n\n if (recommendations.length === 0) {\n console.log(chalk.gray(\" No specific recommendations\"));\n } else {\n for (const rec of recommendations) {\n console.log(rec);\n }\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to analyze agents: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Register analyze command and subcommands\n */\nexport function registerAnalyzeCommand(program: Command): void {\n const analyze = program\n .command(\"analyze\")\n .description(\"Analyze telemetry data for insights into failures, successes, costs, and performance\");\n\n analyze\n .command(\"failures\")\n .description(\"Show common failure patterns from telemetry\")\n .option(\"--agent <name>\", \"Filter by specific agent\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--limit <n>\", \"Show top N patterns\")\n .option(\"--update-knowledge\", \"Add patterns to .reygent/knowledge/common-failures.md\")\n .action(analyzeFailures);\n\n analyze\n .command(\"success\")\n .description(\"Extract patterns from successful runs\")\n .option(\"--stage <name>\", \"Filter by pipeline stage\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--min-success-rate <pct>\", \"Only show patterns above threshold (e.g., 85)\")\n .option(\"--update-knowledge\", \"Add patterns to .reygent/knowledge/success-patterns.md\")\n .action(analyzeSuccess);\n\n analyze\n .command(\"costs\")\n .description(\"Cost breakdown and optimization recommendations\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--by-agent\", \"Group by agent instead of stage\")\n .option(\"--show-runs\", \"List individual expensive runs\")\n .action(analyzeCosts);\n\n analyze\n .command(\"agents\")\n .description(\"Agent-specific performance breakdown\")\n .option(\"--agent <name>\", \"Show specific agent only\")\n .option(\"--since <duration>\", \"Time window (e.g., 7d, 30d)\", \"30d\")\n .option(\"--compare-models\", \"Compare model performance within agent\")\n .action(analyzeAgents);\n}\n","import { findProjectRoot } from \"./project-detection.js\";\n\n/**\n * Get telemetry database path for current context.\n * Returns project-local path if in project, undefined for global fallback.\n *\n * @param cwd - Current working directory to search from\n * @returns Absolute path to .reygent/chesstrace.db if in project, undefined otherwise\n */\nexport function getLocalTelemetryPath(cwd: string): string | undefined {\n const projectRoot = findProjectRoot(cwd);\n return projectRoot ? `${projectRoot}/.reygent/chesstrace.db` : undefined;\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { loadConfig } from \"../config.js\";\nimport { SqliteBackend } from \"../chesstrace/backends/sqlite.js\";\nimport type { TelemetryEvent } from \"../chesstrace/events.js\";\nimport { Events } from \"../chesstrace/events.js\";\nimport { getLocalTelemetryPath } from \"../telemetry-path.js\";\n\ninterface LastOptions {\n verbose?: boolean;\n output?: boolean;\n errors?: boolean;\n json?: boolean;\n}\n\n/**\n * Format timestamp to readable date\n */\nfunction formatTimestamp(timestamp: number): string {\n return new Date(timestamp).toISOString().replace(\"T\", \" \").replace(/\\.\\d{3}Z$/, \"\");\n}\n\n/**\n * Format duration in milliseconds\n */\nfunction formatDuration(ms: number): string {\n const seconds = Math.floor(ms / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n\n if (hours > 0) {\n return `${hours}h ${minutes % 60}m ${seconds % 60}s`;\n }\n if (minutes > 0) {\n return `${minutes}m ${seconds % 60}s`;\n }\n return `${seconds}s`;\n}\n\n/**\n * Format USD cost\n */\nfunction formatCost(usd: number): string {\n return `$${usd.toFixed(4)}`;\n}\n\n/**\n * Check if telemetry is enabled\n */\nfunction checkTelemetryEnabled(config: ReturnType<typeof loadConfig>): void {\n if (!config.telemetry?.enabled) {\n console.log(chalk.yellow(\"\\nTelemetry disabled. Enable with:\"));\n console.log(chalk.cyan(\" reygent telemetry enable\\n\"));\n process.exit(1);\n }\n}\n\n/**\n * Display quick summary of latest run\n */\nfunction displaySummary(runId: string, events: TelemetryEvent[]): void {\n const pipelineEnd = events.find(e => e.event === Events.PIPELINE_END);\n const pipelineStart = events.find(e => e.event === Events.PIPELINE_START);\n const errorEvents = events.filter(e => e.category === \"error\");\n const costEvents = events.filter(e => e.event === Events.USAGE_COST);\n const agentSpawns = events.filter(e => e.event === Events.AGENT_SPAWN);\n\n const success = pipelineEnd?.data.success === true;\n const startTime = pipelineStart?.timestamp ?? events[0]?.timestamp ?? 0;\n const endTime = pipelineEnd?.timestamp ?? events[events.length - 1]?.timestamp ?? 0;\n const duration = endTime - startTime;\n\n const totalCost = costEvents.reduce((sum, e) => sum + (e.data.costUsd as number), 0);\n const agents = [...new Set(agentSpawns.map(e => e.data.agent as string))];\n\n console.log();\n console.log(chalk.bold(\"Latest Run Summary\"));\n console.log();\n console.log(` Run ID: ${chalk.cyan(runId.substring(0, 8))}`);\n console.log(` Status: ${success ? chalk.green(\"Success\") : chalk.red(\"Failed\")}`);\n console.log(` Started: ${chalk.gray(formatTimestamp(startTime))}`);\n console.log(` Duration: ${formatDuration(duration)}`);\n console.log(` Agents: ${agents.join(\", \") || \"none\"}`);\n\n if (totalCost > 0) {\n console.log(` Cost: ${formatCost(totalCost)}`);\n }\n\n if (errorEvents.length > 0) {\n console.log();\n console.log(chalk.red(` Errors: ${errorEvents.length} error(s)`));\n\n const errorSummary = errorEvents.slice(0, 3).map(e => {\n const msg = e.data.message as string || e.event;\n return ` • ${msg}`;\n }).join(\"\\n\");\n console.log(errorSummary);\n\n if (errorEvents.length > 3) {\n console.log(` ... and ${errorEvents.length - 3} more`);\n }\n }\n\n console.log();\n}\n\n/**\n * Display verbose details\n */\nfunction displayVerbose(runId: string, events: TelemetryEvent[]): void {\n console.log();\n console.log(chalk.bold(`Detailed Event Log (${events.length} events)`));\n console.log();\n\n const table = new Table({\n head: [\n chalk.cyan(\"Time\"),\n chalk.cyan(\"Category\"),\n chalk.cyan(\"Event\"),\n chalk.cyan(\"Details\"),\n ],\n colWidths: [20, 15, 30, 50],\n wordWrap: true,\n });\n\n for (const event of events) {\n const timestamp = formatTimestamp(event.timestamp);\n const details = Object.keys(event.data).length > 0\n ? JSON.stringify(event.data).substring(0, 100)\n : \"\";\n\n table.push([\n chalk.gray(timestamp),\n event.category,\n event.event,\n chalk.gray(details),\n ]);\n }\n\n console.log(table.toString());\n console.log();\n}\n\n/**\n * Display only output\n */\nfunction displayOutput(events: TelemetryEvent[]): void {\n const pipelineEnd = events.find(e => e.event === Events.PIPELINE_END);\n const agentCompletes = events.filter(e => e.event === Events.AGENT_COMPLETE);\n\n console.log();\n console.log(chalk.bold(\"Run Output\"));\n console.log();\n\n if (pipelineEnd?.data.output) {\n console.log(pipelineEnd.data.output);\n } else if (agentCompletes.length > 0) {\n for (const complete of agentCompletes) {\n const agent = complete.data.agent as string;\n const output = complete.data.output as string;\n if (output) {\n console.log(chalk.cyan(`[${agent}]`));\n console.log(output);\n console.log();\n }\n }\n } else {\n console.log(chalk.yellow(\"No output captured\"));\n }\n\n console.log();\n}\n\n/**\n * Display only errors\n */\nfunction displayErrors(events: TelemetryEvent[]): void {\n const errorEvents = events.filter(e => e.category === \"error\");\n\n console.log();\n console.log(chalk.bold(`Errors (${errorEvents.length})`));\n console.log();\n\n if (errorEvents.length === 0) {\n console.log(chalk.green(\"No errors in this run\"));\n console.log();\n return;\n }\n\n for (const error of errorEvents) {\n const timestamp = formatTimestamp(error.timestamp);\n const message = error.data.message as string || \"Unknown error\";\n const agent = error.data.agent as string || \"unknown\";\n\n console.log(chalk.gray(timestamp) + chalk.red(` [${error.event}]`) + ` ${agent}`);\n console.log(` ${message}`);\n\n if (error.data.stack) {\n console.log(chalk.gray(` ${error.data.stack}`));\n }\n console.log();\n }\n}\n\n/**\n * Output as JSON\n */\nfunction displayJson(runId: string, events: TelemetryEvent[]): void {\n const output = {\n runId,\n eventCount: events.length,\n events,\n };\n console.log(JSON.stringify(output, null, 2));\n}\n\n/**\n * Internal implementation for testing\n */\nexport async function lastCommandImpl(\n options: LastOptions,\n testBackend?: SqliteBackend\n): Promise<void> {\n const spinner = ora(\"Loading latest run...\").start();\n\n try {\n const config = loadConfig();\n checkTelemetryEnabled(config);\n\n // Determine backend path - match writer path from run.ts\n const backend = testBackend ?? new SqliteBackend(\"local\", getLocalTelemetryPath(process.cwd()));\n if (!testBackend) {\n await backend.init();\n }\n\n const runs = await backend.listRuns();\n\n if (runs.length === 0) {\n spinner.fail(chalk.yellow(\"No telemetry runs found\"));\n console.log(chalk.gray(\"\\nRun a reygent command to generate telemetry data\"));\n if (!testBackend) {\n await backend.close();\n }\n return;\n }\n\n const latestRun = runs[0];\n const events = await backend.query({ runId: latestRun.runId });\n\n if (!testBackend) {\n await backend.close();\n }\n\n spinner.succeed(chalk.green(`Loaded latest run: ${latestRun.runId.substring(0, 8)}`));\n\n // Display based on options\n if (options.json) {\n displayJson(latestRun.runId, events);\n } else if (options.output) {\n displayOutput(events);\n } else if (options.errors) {\n displayErrors(events);\n } else if (options.verbose) {\n displayVerbose(latestRun.runId, events);\n } else {\n displaySummary(latestRun.runId, events);\n }\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to load latest run: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * CLI command wrapper\n */\nexport async function lastCommand(options: LastOptions): Promise<void> {\n return lastCommandImpl(options);\n}\n\n/**\n * Register last command\n */\nexport function registerLastCommand(program: Command): void {\n program\n .command(\"last\")\n .description(\"Show details of the most recent run\")\n .option(\"--verbose\", \"Show full event log with timestamps and details\", false)\n .option(\"--output\", \"Show only the final output from the run\", false)\n .option(\"--errors\", \"Show only errors from the run\", false)\n .option(\"--json\", \"Output as JSON for machine parsing\", false)\n .action(lastCommand);\n}\n","import { Command } from \"commander\";\nimport { join } from \"node:path\";\nimport { readFileSync, writeFileSync } from \"node:fs\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport Table from \"cli-table3\";\nimport { select, confirm } from '@inquirer/prompts';\nimport { inputWithTimeout, InputTimeoutError } from '../input-with-timeout.js';\nimport {\n findKnowledgeDir,\n listKnowledgeFiles,\n readMarkdown,\n searchKnowledge,\n parseMarkdownEntries,\n} from \"../knowledge/loader.js\";\nimport { getChesstrace } from \"../chesstrace/index.js\";\nimport { measureKnowledgeEffectiveness } from \"../knowledge/analyzer.js\";\nimport { addFailureEntry, addPatternEntry } from \"../knowledge/manager.js\";\nimport { AgentName, builtinAgents } from \"../agents.js\";\n\n/**\n * Register knowledge subcommands under main CLI program\n */\nexport function registerKnowledgeCommand(program: Command) {\n const knowledge = program\n .command(\"knowledge\")\n .description(\"Manage living documentation in .reygent/knowledge/\");\n\n knowledge\n .command(\"list\")\n .description(\"List all knowledge files\")\n .action(listCommand);\n\n knowledge\n .command(\"show\")\n .description(\"Show specific knowledge file\")\n .argument(\"<file>\", \"Knowledge file to show (e.g., common-failures, agents/dev)\")\n .action(showCommand);\n\n knowledge\n .command(\"search\")\n .description(\"Search knowledge files for a query\")\n .argument(\"<query>\", \"Search query\")\n .action(searchCommand);\n\n knowledge\n .command(\"edit\")\n .description(\"Edit knowledge file in $EDITOR\")\n .argument(\"<file>\", \"Knowledge file to edit (e.g., common-failures, agents/dev)\")\n .action(editCommand);\n\n knowledge\n .command(\"add-failure\")\n .description(\"Document a failure pattern (interactive)\")\n .option(\"--run-id <id>\", \"Run ID to extract failure from\")\n .option(\"--issue <text>\", \"Issue description\")\n .option(\"--solution <text>\", \"Solution description\")\n .option(\"--agent <name>\", \"Affected agent\")\n .action(addFailureCommand);\n\n knowledge\n .command(\"add-pattern\")\n .description(\"Document a success pattern (interactive)\")\n .option(\"--run-id <id>\", \"Run ID to extract pattern from\")\n .option(\"--description <text>\", \"Pattern description\")\n .action(addPatternCommand);\n\n knowledge\n .command(\"stats\")\n .description(\"Show knowledge base statistics and effectiveness\")\n .option(\"--since <days>\", \"Time window in days (e.g., 30d)\", \"30d\")\n .action(statsCommand);\n}\n\n/**\n * List all knowledge files\n */\nasync function listCommand() {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.yellow(\"No .reygent/knowledge/ directory found.\"));\n console.log(\n chalk.gray(\"Run from a project with .reygent/ or create one with:\"),\n );\n console.log(chalk.cyan(\" reygent init\"));\n return;\n }\n\n const files = listKnowledgeFiles();\n\n if (files.length === 0) {\n console.log(chalk.yellow(\"No knowledge files found.\"));\n return;\n }\n\n console.log(chalk.bold(\"\\nKnowledge Files:\"));\n console.log();\n\n const table = new Table({\n head: [chalk.cyan(\"File\"), chalk.cyan(\"Type\")],\n colWidths: [40, 30],\n });\n\n for (const file of files) {\n const type = file.startsWith(\"agents/\")\n ? \"Agent-specific\"\n : file.replace(\".md\", \"\").replace(/-/g, \" \");\n table.push([file, type]);\n }\n\n console.log(table.toString());\n console.log();\n console.log(chalk.gray(`View file: ${chalk.white(\"reygent knowledge show <file>\")}`));\n console.log(chalk.gray(`Search: ${chalk.white(\"reygent knowledge search <query>\")}`));\n}\n\n/**\n * Show specific knowledge file\n */\nasync function showCommand(file: string) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n // Normalize file path (add .md if missing)\n const normalizedFile = file.endsWith(\".md\") ? file : `${file}.md`;\n const filePath = join(knowledgeDir, normalizedFile);\n\n try {\n const content = readMarkdown(filePath);\n if (content === null) {\n console.log(chalk.red(`Knowledge file validation failed: ${normalizedFile}`));\n console.log(chalk.gray(\"File may contain suspicious content or be malformed.\"));\n process.exit(1);\n }\n if (content === \"\") {\n console.log(chalk.yellow(`Knowledge file is empty or not found: ${normalizedFile}`));\n console.log(chalk.gray(\"Available files:\"));\n const files = listKnowledgeFiles();\n files.forEach((f) => console.log(chalk.gray(` - ${f}`)));\n process.exit(1);\n }\n\n console.log(chalk.bold(`\\n${normalizedFile}\\n`));\n console.log(content);\n console.log();\n } catch (err) {\n console.log(chalk.red(`Failed to read ${normalizedFile}: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Search knowledge files\n */\nasync function searchCommand(query: string) {\n const spinner = ora(`Searching for \"${query}\"...`).start();\n\n try {\n const results = searchKnowledge(query);\n\n if (results.length === 0) {\n spinner.fail(chalk.yellow(\"No matches found.\"));\n return;\n }\n\n spinner.succeed(chalk.green(`Found ${results.length} match(es)`));\n console.log();\n\n for (const result of results) {\n console.log(chalk.bold.cyan(`${result.file}`));\n console.log(chalk.bold(` ${result.entry.title}`));\n console.log(chalk.gray(` ${result.excerpt}`));\n console.log();\n }\n } catch (err) {\n spinner.fail(chalk.red(`Search failed: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Edit knowledge file in $EDITOR\n */\nasync function editCommand(file: string) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n const normalizedFile = file.endsWith(\".md\") ? file : `${file}.md`;\n const filePath = join(knowledgeDir, normalizedFile);\n\n const editor = process.env.EDITOR || \"vi\";\n\n console.log(chalk.cyan(`Opening ${normalizedFile} in ${editor}...`));\n\n try {\n execSync(`${editor} \"${filePath}\"`, { stdio: \"inherit\" });\n console.log(chalk.green(\"File saved.\"));\n } catch (err) {\n console.log(chalk.red(`Failed to open editor: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n\n/**\n * Add failure documentation (interactive/manual)\n */\nasync function addFailureCommand(options: {\n runId?: string;\n issue?: string;\n solution?: string;\n agent?: string;\n example?: string;\n}) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n console.log(chalk.gray(\"Run 'reygent init' to create knowledge directory.\"));\n process.exit(1);\n }\n\n // Interactive prompts if options not provided\n let issue = options.issue;\n let solution = options.solution;\n let agent = options.agent as AgentName | undefined;\n let example = options.example;\n\n if (!issue) {\n try {\n issue = await inputWithTimeout({\n message: 'What is the issue/error?',\n validate: (value) => value.trim() !== '' || 'Issue description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!solution) {\n try {\n solution = await inputWithTimeout({\n message: 'What is the solution/fix?',\n validate: (value) => value.trim() !== '' || 'Solution description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!agent) {\n const agentChoices = builtinAgents.map((a) => ({ value: a.name, name: a.name }));\n agent = await select({\n message: 'Which agent does this apply to?',\n choices: agentChoices,\n }) as AgentName;\n }\n\n if (!example) {\n const addExample = await confirm({\n message: 'Add a code example?',\n default: false,\n });\n\n if (addExample) {\n try {\n example = await inputWithTimeout({\n message: 'Enter code example:',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n // Use manager to add entry\n const baseDir = knowledgeDir.replace('/.reygent/knowledge', '');\n await addFailureEntry(baseDir, {\n issue,\n solution,\n agent,\n example,\n });\n\n console.log(chalk.green(\"✓ Failure documented\"));\n console.log(chalk.gray(` File: common-failures.md`));\n console.log(chalk.gray(` Agent: ${agent}`));\n}\n\n/**\n * Add success pattern (interactive/manual)\n */\nasync function addPatternCommand(options: {\n runId?: string;\n description?: string;\n approach?: string;\n successRate?: number;\n}) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n console.log(chalk.gray(\"Run 'reygent init' to create knowledge directory.\"));\n process.exit(1);\n }\n\n // Interactive prompts if options not provided\n let description = options.description;\n let approach = options.approach;\n let successRate = options.successRate;\n\n if (!description) {\n try {\n description = await inputWithTimeout({\n message: 'Describe the success pattern:',\n validate: (value) => value.trim() !== '' || 'Description required',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n\n if (!approach) {\n const addApproach = await confirm({\n message: 'Add detailed approach?',\n default: false,\n });\n\n if (addApproach) {\n try {\n approach = await inputWithTimeout({\n message: 'Describe the approach:',\n });\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n if (successRate === undefined) {\n const addRate = await confirm({\n message: 'Add success rate?',\n default: false,\n });\n\n if (addRate) {\n try {\n const rateStr = await inputWithTimeout({\n message: 'Enter success rate (0-100):',\n validate: (value) => {\n const num = parseFloat(value);\n return (!isNaN(num) && num >= 0 && num <= 100) || 'Must be a number between 0 and 100';\n },\n });\n successRate = parseFloat(rateStr);\n } catch (err) {\n if (err instanceof InputTimeoutError) {\n console.log(chalk.red('\\n✗ Input timed out'));\n process.exit(1);\n }\n throw err;\n }\n }\n }\n\n // Use manager to add entry\n const baseDir = knowledgeDir.replace('/.reygent/knowledge', '');\n await addPatternEntry(baseDir, {\n description,\n approach,\n successRate,\n });\n\n console.log(chalk.green(\"✓ Pattern documented\"));\n console.log(chalk.gray(` File: success-patterns.md`));\n}\n\n/**\n * Show knowledge base statistics\n */\nasync function statsCommand(options: { since?: string }) {\n const knowledgeDir = findKnowledgeDir();\n\n if (!knowledgeDir) {\n console.log(chalk.red(\"No .reygent/knowledge/ directory found.\"));\n process.exit(1);\n }\n\n const spinner = ora(\"Calculating knowledge base stats...\").start();\n\n try {\n // Parse since parameter\n const since = options.since || \"30d\";\n const match = since.match(/^(\\d+)d$/);\n if (!match) {\n spinner.fail(chalk.red(`Invalid --since format: ${since}. Use format like \"30d\".`));\n process.exit(1);\n }\n const days = Number.parseInt(match[1], 10);\n const sinceMs = Date.now() - days * 24 * 60 * 60 * 1000;\n\n // Get knowledge file counts\n const files = listKnowledgeFiles();\n const totalEntries = files.reduce((count, file) => {\n const filePath = join(knowledgeDir, file);\n const content = readMarkdown(filePath);\n const entries = parseMarkdownEntries(content, filePath);\n return count + entries.length;\n }, 0);\n\n // Get effectiveness metrics from telemetry\n const chesstrace = getChesstrace();\n if (!chesstrace) {\n spinner.fail(chalk.yellow(\"Telemetry not available. Cannot calculate effectiveness.\"));\n console.log();\n console.log(chalk.bold(\"Knowledge Base Stats\"));\n console.log();\n console.log(`Files: ${files.length}`);\n console.log(`Total entries: ${totalEntries}`);\n return;\n }\n\n const backend = chesstrace.getBackend();\n const effectiveness = measureKnowledgeEffectiveness(backend, sinceMs);\n\n spinner.succeed(chalk.green(\"Stats calculated\"));\n console.log();\n console.log(chalk.bold(\"Knowledge Base Stats\"));\n console.log();\n\n // File stats\n console.log(chalk.cyan(\"Files:\"), files.length);\n console.log(chalk.cyan(\"Total entries:\"), totalEntries);\n console.log();\n\n // Usage stats\n console.log(chalk.bold(`Usage (last ${days} days):`));\n console.log(chalk.cyan(\" Consulted runs:\"), effectiveness.consultedRuns);\n console.log(chalk.cyan(\" Baseline runs:\"), effectiveness.baselineRuns);\n console.log();\n\n // Effectiveness\n if (effectiveness.consultedRuns > 0 || effectiveness.baselineRuns > 0) {\n const withKnowledgePct = Math.round(effectiveness.withKnowledge * 100);\n const baselinePct = Math.round(effectiveness.baseline * 100);\n const improvementPct = Math.round(effectiveness.improvement * 100);\n\n console.log(chalk.bold(\"Effectiveness:\"));\n console.log(chalk.cyan(\" Success rate with knowledge:\"), `${withKnowledgePct}%`);\n console.log(chalk.cyan(\" Baseline success rate:\"), `${baselinePct}%`);\n\n const improvementColor = effectiveness.improvement > 0 ? chalk.green : effectiveness.improvement < 0 ? chalk.red : chalk.gray;\n console.log(chalk.cyan(\" Improvement:\"), improvementColor(`${improvementPct > 0 ? \"+\" : \"\"}${improvementPct}%`));\n } else {\n console.log(chalk.gray(\"No runs found in time window to measure effectiveness.\"));\n }\n console.log();\n\n } catch (err) {\n spinner.fail(chalk.red(`Failed to calculate stats: ${(err as Error).message}`));\n process.exit(1);\n }\n}\n","/**\n * Wrapper for @inquirer/prompts input() with timeout support\n */\nimport { input } from '@inquirer/prompts';\n\nconst DEFAULT_TIMEOUT_MS = 60000; // 60 seconds\n\nexport class InputTimeoutError extends Error {\n constructor(message: string = 'Input prompt timed out') {\n super(message);\n this.name = 'InputTimeoutError';\n }\n}\n\n/**\n * Prompts for input with optional timeout.\n * Throws InputTimeoutError if timeout exceeded.\n */\nexport async function inputWithTimeout(\n config: Parameters<typeof input>[0],\n timeoutMs: number = DEFAULT_TIMEOUT_MS\n): Promise<string> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new InputTimeoutError(`Input prompt timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n input(config)\n .then(result => {\n clearTimeout(timer);\n resolve(result);\n })\n .catch(err => {\n clearTimeout(timer);\n reject(err);\n });\n });\n}\n","import { existsSync, readFileSync, writeFileSync, mkdirSync, lstatSync, renameSync, unlinkSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { randomBytes } from \"node:crypto\";\nimport { confirm } from \"@inquirer/prompts\";\nimport chalk from \"chalk\";\nimport { findLocalConfigDir, resolveGlobalConfigPath } from \"../config.js\";\nimport type { ReygentConfig } from \"../config.js\";\nimport { isDebug } from \"../debug.js\";\n\n/**\n * Check if telemetry opt-in prompt should be shown.\n *\n * CRITICAL: This function REQUIRES a TTY (interactive terminal). It will never\n * prompt in non-interactive environments (CI, piped input, automated scripts).\n *\n * Returns true when:\n * 1. stdin is a TTY (interactive terminal)\n * 2. telemetry.enabled is undefined in config\n *\n * Returns false in all other cases, including non-TTY environments.\n */\nexport function shouldPromptForTelemetry(): boolean {\n // CRITICAL: Never prompt in non-TTY environments (CI, piped input, etc.)\n if (!process.stdin.isTTY) {\n return false;\n }\n\n // Find config path (local takes precedence)\n const localConfigDir = findLocalConfigDir(process.cwd());\n let configPath: string | null = null;\n\n if (localConfigDir) {\n const localPath = join(localConfigDir, \"config.json\");\n if (existsSync(localPath)) {\n configPath = localPath;\n }\n }\n\n if (!configPath) {\n const globalPath = resolveGlobalConfigPath();\n if (existsSync(globalPath)) {\n configPath = globalPath;\n }\n }\n\n // No config file exists → enabled is undefined → should prompt\n if (!configPath) {\n return true;\n }\n\n // Read config to check telemetry.enabled\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw) as ReygentConfig;\n\n // Prompt if telemetry field missing or enabled is undefined\n if (!parsed.telemetry || parsed.telemetry.enabled === undefined) {\n return true;\n }\n\n return false;\n } catch (err) {\n // If config parse fails, prompt user to regenerate valid config\n if (isDebug()) {\n console.error(chalk.gray(`Failed to read config at ${configPath}:`), err);\n }\n return true;\n }\n}\n\n/**\n * Prompt user to opt into telemetry and save choice to config.\n * Saves to local config if .reygent/ dir exists, else global.\n */\nexport async function promptForTelemetryOptIn(): Promise<void> {\n console.log(\"\");\n console.log(chalk.bold(\"First-run telemetry setup\"));\n console.log(chalk.gray(\"Reygent can collect local usage data to help diagnose issues.\"));\n console.log(chalk.gray(\"Data is stored locally in SQLite and never sent to external servers.\"));\n console.log(\"\");\n\n const enabled = await confirm({\n message: \"Enable local telemetry?\",\n default: false,\n });\n\n await saveTelemetryChoice(enabled);\n\n console.log(\"\");\n if (enabled) {\n console.log(chalk.green(\"✓\"), \"Local telemetry enabled\");\n } else {\n console.log(chalk.gray(\"✓\"), \"Local telemetry disabled\");\n }\n console.log(\"\");\n}\n\n/**\n * Save telemetry choice to config (local if exists, else global).\n */\nasync function saveTelemetryChoice(enabled: boolean): Promise<void> {\n const localConfigDir = findLocalConfigDir(process.cwd());\n let configPath: string;\n let configDir: string;\n\n if (localConfigDir) {\n configPath = join(localConfigDir, \"config.json\");\n configDir = localConfigDir;\n } else {\n configPath = resolveGlobalConfigPath();\n configDir = dirname(configPath);\n mkdirSync(configDir, { recursive: true });\n }\n\n // Load existing config or create new one\n let rawConfig: Record<string, unknown> = {};\n if (existsSync(configPath)) {\n try {\n const content = readFileSync(configPath, \"utf-8\");\n rawConfig = JSON.parse(content);\n } catch (err) {\n if (isDebug()) {\n console.error(chalk.gray(`Failed to parse config at ${configPath}:`), err);\n }\n // Continue with empty config\n }\n }\n\n // Merge telemetry.enabled into config\n const telemetry = (rawConfig.telemetry as Record<string, unknown> | undefined) ?? {};\n telemetry.enabled = enabled;\n\n // Apply defaults if missing\n telemetry.level = telemetry.level ?? \"standard\";\n telemetry.backend = telemetry.backend ?? \"sqlite\";\n telemetry.retention = telemetry.retention ?? 30;\n\n rawConfig.telemetry = telemetry;\n\n // Atomic write\n try {\n const tempPath = `${configPath}.tmp.${randomBytes(8).toString(\"hex\")}`;\n\n try {\n writeFileSync(tempPath, JSON.stringify(rawConfig, null, 2) + \"\\n\", \"utf-8\");\n\n // Security: verify temp file is not symlink\n const tempStats = lstatSync(tempPath);\n if (tempStats.isSymbolicLink()) {\n unlinkSync(tempPath);\n throw new Error(\"Security: temp file became symlink\");\n }\n\n renameSync(tempPath, configPath);\n } catch (err) {\n // Clean up temp file on error\n try {\n unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw err;\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(chalk.yellow(\"Warning:\"), `Failed to save telemetry config: ${message}`);\n if (isDebug()) console.error(err instanceof Error ? err.stack : err);\n console.log(chalk.gray(\"Command will continue without saving telemetry preference.\"));\n // Don't throw - allow command execution to continue\n }\n}\n"],"mappings":"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","names":["readFileSync","dirname","join","fileURLToPath","chalk","chalk","existsSync","readFileSync","join","z","z","readFileSync","path","join","existsSync","chalk","input","resolve","chalk","spawn","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","availabilityCache","resolve","spawn","chalk","code","spawn","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","availabilityCache","resolve","spawn","chalk","code","chalk","SUPPORTED_MODELS","SHORT_ALIASES","DEFAULT_MODEL","chalk","SUPPORTED_MODELS","DEFAULT_MODEL","chalk","chalk","existsSync","readFileSync","basename","resolve","chalk","input","existsSync","readFileSync","resolve","chalk","TelemetryLevel","chalk","resolve","existsSync","chalk","basename","readFileSync","join","dirname","existsSync","statSync","join","existsSync","dirname","statSync","events","existsSync","join","dirname","telemetryOverride","chalk","createInterface","resolve","chalk","existsSync","readFileSync","readdirSync","statSync","join","chalk","join","existsSync","readFileSync","chalk","readdirSync","statSync","prompt","prompt","chesstrace","prompt","chalk","chalk","stripAnsi","createInterface","resolve","chalk","chalk","select","chalk","isLinearUrl","select","createInterface","join","chalk","ora","select","chalk","prompt","chalk","prompt","readFileSync","resolve","readFileSync","execFile","chalk","input","prompt","chalk","exec","resolve","execFile","chalk","chalk","prompt","chalk","chalk","existsSync","mkdirSync","createInterface","chalk","createInterface","resolve","chalk","chalk","select","telemetryOverride","join","existsSync","mkdirSync","createInterface","resolve","result","chesstrace","ora","existsSync","mkdirSync","writeFileSync","join","ExitPromptError","select","chalk","ora","join","DEFAULT_MODEL","chalk","existsSync","select","ora","mkdirSync","writeFileSync","ExitPromptError","existsSync","mkdirSync","writeFileSync","readdirSync","statSync","readFileSync","join","dirname","chalk","ora","existsSync","readFileSync","readdirSync","statSync","mkdirSync","join","join","existsSync","mkdirSync","readdirSync","statSync","readFileSync","__dirname","dirname","pkg","readFileSync","join","existsSync","readdirSync","statSync","ora","chalk","mkdirSync","writeFileSync","program","execFile","httpsRequest","chalk","ora","input","exec","resolve","execFile","httpsRequest","httpsPost","input","prompt","chalk","ora","execFile","httpsRequest","chalk","select","exec","resolve","execFile","getCurrentBranch","getDefaultBranch","detectGitHubPR","httpsGet","httpsRequest","detectGitLabMR","chalk","prompt","buildDevPrompt","select","existsSync","readFileSync","writeFileSync","mkdirSync","join","dirname","chalk","select","chalk","select","join","dirname","mkdirSync","existsSync","readFileSync","provider","writeFileSync","statSync","writeFileSync","chalk","ora","join","formatDuration","statSync","ora","chalk","writeFileSync","program","chalk","ora","formatDuration","formatCost","chalk","ora","events","limit","spawn","successRate","avgDuration","avgCost","program","chalk","ora","Table","formatTimestamp","formatDuration","formatCost","checkTelemetryEnabled","chalk","Table","ora","program","join","chalk","ora","Table","select","confirm","resolve","program","showCommand","chalk","Table","join","ora","select","confirm","existsSync","readFileSync","writeFileSync","mkdirSync","lstatSync","renameSync","unlinkSync","join","dirname","randomBytes","confirm","chalk","join","existsSync","readFileSync","chalk","confirm","dirname","mkdirSync","randomBytes","writeFileSync","lstatSync","unlinkSync","renameSync","dirname","fileURLToPath","readFileSync","join","chalk","noTelemetry"]}