cto-ai-cli 3.1.0 → 3.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/cli/v2/index.ts","../../../src/cli/v2/init.ts","../../../src/engine/config.ts","../../../src/types/config.ts","../../../src/cli/v2/analyze.ts","../../../src/engine/analyzer.ts","../../../src/types/engine.ts","../../../src/engine/tokenizer.ts","../../../src/engine/graph.ts","../../../src/engine/risk.ts","../../../src/cli/v2/interact.ts","../../../src/engine/cache.ts","../../../src/engine/pr-context.ts","../../../src/engine/graph-utils.ts","../../../src/interact/orchestrator.ts","../../../src/engine/selector.ts","../../../src/govern/secrets.ts","../../../src/engine/pruner.ts","../../../src/engine/coverage.ts","../../../src/engine/budget.ts","../../../src/interact/router.ts","../../../src/interact/estimator.ts","../../../src/interact/prompt.ts","../../../src/govern/audit.ts","../../../src/cli/v2/snapshot.ts","../../../src/govern/snapshot.ts","../../../src/cli/v2/audit.ts","../../../src/cli/v2/policy.ts","../../../src/govern/policy.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { initCommand } from './init.js';\nimport { analyzeCommand } from './analyze.js';\nimport { interactCommand } from './interact.js';\nimport { snapshotCommand } from './snapshot.js';\nimport { auditCommand } from './audit.js';\nimport { policyCommand } from './policy.js';\n\nconst CTO_V2_VERSION = '2.0.0';\n\nconst program = new Command();\n\nprogram\n .name('cto')\n .description('CTO — Context Operating System for AI-native Engineering')\n .version(CTO_V2_VERSION, '-v, --version');\n\nprogram.addCommand(initCommand);\nprogram.addCommand(analyzeCommand);\nprogram.addCommand(interactCommand);\nprogram.addCommand(snapshotCommand);\nprogram.addCommand(auditCommand);\nprogram.addCommand(policyCommand);\n\n// Default action — branded help\nprogram.action(() => {\n console.log('');\n console.log(chalk.bold.cyan(' 🧠 CTO v2 — Context Operating System'));\n console.log(chalk.dim(` v${CTO_V2_VERSION}`));\n console.log('');\n console.log(chalk.dim(' AI Interaction Infrastructure for Engineering Teams'));\n console.log(chalk.dim(' Formal risk modeling · Deterministic selection · Enterprise auditability'));\n console.log('');\n console.log(chalk.bold(' Commands:'));\n console.log(chalk.dim(' init Setup CTO for a project'));\n console.log(chalk.dim(' analyze [path] Analyze structure, deps & risk'));\n console.log(chalk.dim(' interact <task> Build optimized AI context'));\n console.log(chalk.dim(' snapshot create|verify|compare|list Reproducible context snapshots'));\n console.log(chalk.dim(' audit list|verify|purge Tamper-evident audit trail'));\n console.log(chalk.dim(' policy show|add|remove|toggle|validate|init Context policies'));\n console.log('');\n console.log(chalk.bold(' Quick Start:'));\n console.log(chalk.dim(' $ cto init'));\n console.log(chalk.dim(' $ cto analyze'));\n console.log(chalk.dim(' $ cto interact \"refactor the auth middleware\"'));\n console.log(chalk.dim(' $ cto snapshot create baseline'));\n console.log('');\n console.log(chalk.dim(' Run cto <command> --help for details'));\n console.log('');\n});\n\nprogram.parse();\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { initProjectConfig } from '../../engine/config.js';\n\nexport const initCommand = new Command('init')\n .description('Initialize CTO v2 for a project')\n .argument('[path]', 'Project path', '.')\n .option('--defaults', 'Skip prompts and use defaults')\n .action(async (path: string, opts: { defaults?: boolean }) => {\n try {\n const projectPath = resolve(path);\n const ctoDir = join(projectPath, '.cto');\n\n console.log('');\n console.log(chalk.bold.cyan(' 🔧 CTO v2.0 — Context Operating System'));\n console.log(chalk.dim(' AI Interaction Infrastructure for Engineering Teams'));\n console.log('');\n\n // Create .cto directory structure + config.yml + policy.yml\n const { configPath, policyPath, created } = await initProjectConfig(projectPath);\n\n // Create .gitignore for .cto\n const gitignorePath = join(ctoDir, '.gitignore');\n const gitignoreContent = [\n '# CTO v2 — local state (do not commit)',\n 'audit/',\n 'snapshots/',\n '',\n '# Config and policy should be committed',\n '!config.yml',\n '!policy.yml',\n '',\n ].join('\\n');\n await writeFile(gitignorePath, gitignoreContent, 'utf-8');\n\n console.log(chalk.green(' ✅ Initialized .cto/ directory'));\n console.log(chalk.dim(` ${ctoDir}/`));\n console.log(chalk.dim(' ├── config.yml (commit this)'));\n console.log(chalk.dim(' ├── policy.yml (commit this)'));\n console.log(chalk.dim(' ├── snapshots/ (local)'));\n console.log(chalk.dim(' └── .gitignore'));\n if (created.length > 0) {\n console.log(chalk.dim(` Created: ${created.length} file(s)`));\n }\n console.log('');\n\n console.log(chalk.bold(' Next steps:'));\n console.log(chalk.dim(' cto analyze — Analyze project structure & risk'));\n console.log(chalk.dim(' cto interact \"refactor auth module\" — Build optimized AI context'));\n console.log(chalk.dim(' cto snapshot create baseline — Save a reproducible snapshot'));\n console.log(chalk.dim(' cto policy show — View context policies'));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { parse as parseYAML, stringify as stringifyYAML } from 'yaml';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\n\n// ===== CONFIG FILE SUPPORT =====\n//\n// Loads and saves .cto/config.yml per the ARCHITECTURE.md spec.\n// Deep-merges user config on top of DEFAULT_CONFIG so partial\n// configs work correctly.\n\nconst CONFIG_DIR = '.cto';\nconst CONFIG_FILE = 'config.yml';\nconst POLICY_FILE = 'policy.yml';\n\nexport function getConfigPath(projectPath: string): string {\n return join(projectPath, CONFIG_DIR, CONFIG_FILE);\n}\n\nexport function getPolicyPath(projectPath: string): string {\n return join(projectPath, CONFIG_DIR, POLICY_FILE);\n}\n\nexport function getCTODir(projectPath: string): string {\n return join(projectPath, CONFIG_DIR);\n}\n\nexport async function loadConfig(projectPath: string): Promise<CTOConfig> {\n const configPath = getConfigPath(projectPath);\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = await readFile(configPath, 'utf-8');\n const userConfig = parseYAML(raw) as Partial<CTOConfig>;\n return deepMerge(DEFAULT_CONFIG, userConfig) as CTOConfig;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(\n projectPath: string,\n config: CTOConfig,\n): Promise<string> {\n const ctoDir = getCTODir(projectPath);\n await mkdir(ctoDir, { recursive: true });\n\n const configPath = getConfigPath(projectPath);\n const yamlContent = stringifyYAML(config, { indent: 2 });\n await writeFile(configPath, yamlContent, 'utf-8');\n return configPath;\n}\n\nexport async function initProjectConfig(projectPath: string): Promise<{\n configPath: string;\n policyPath: string;\n created: string[];\n}> {\n const ctoDir = getCTODir(projectPath);\n await mkdir(join(ctoDir, 'snapshots'), { recursive: true });\n\n const created: string[] = [];\n\n // Create config.yml if it doesn't exist\n const configPath = getConfigPath(projectPath);\n if (!existsSync(configPath)) {\n await saveConfig(projectPath, DEFAULT_CONFIG);\n created.push(configPath);\n }\n\n // Create policy.yml if it doesn't exist\n const policyPath = getPolicyPath(projectPath);\n if (!existsSync(policyPath)) {\n const defaultPolicy = {\n version: '1.0',\n name: 'default',\n rules: [\n {\n id: 'types-always',\n type: 'include-always',\n pattern: '**/types/**',\n reason: 'Type definitions provide essential context',\n enabled: true,\n },\n {\n id: 'no-env',\n type: 'exclude-always',\n pattern: '**/*.env*',\n reason: 'Environment files must never be sent to AI',\n enabled: true,\n },\n {\n id: 'no-secrets',\n type: 'secret-block',\n reason: 'Files with detected secrets are blocked',\n enabled: true,\n },\n {\n id: 'test-budget',\n type: 'budget-limit',\n category: 'test',\n threshold: 20,\n reason: 'Test files should not exceed 20% of budget',\n enabled: true,\n },\n {\n id: 'min-coverage',\n type: 'coverage-minimum',\n threshold: 70,\n reason: 'Warn if context coverage drops below 70%',\n enabled: true,\n },\n ],\n };\n const yamlContent = stringifyYAML(defaultPolicy, { indent: 2 });\n await writeFile(policyPath, yamlContent, 'utf-8');\n created.push(policyPath);\n }\n\n return { configPath, policyPath, created };\n}\n\nexport async function loadPolicyFromYAML(projectPath: string): Promise<import('../types/govern.js').PolicySet | null> {\n const policyPath = getPolicyPath(projectPath);\n if (!existsSync(policyPath)) return null;\n\n try {\n const raw = await readFile(policyPath, 'utf-8');\n return parseYAML(raw) as import('../types/govern.js').PolicySet;\n } catch {\n return null;\n }\n}\n\n// ===== HELPERS =====\n\nfunction deepMerge(target: Record<string, any>, source: Record<string, any>): Record<string, any> {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n source[key] !== null &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n typeof target[key] === 'object' &&\n !Array.isArray(target[key])\n ) {\n result[key] = deepMerge(target[key], source[key]);\n } else if (source[key] !== undefined) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n","// ===== Configuration Types =====\n\nimport type { RiskWeights } from './engine.js';\n\nexport interface CTOConfig {\n version: string;\n\n analysis: {\n extensions: {\n code: string[];\n config: string[];\n docs: string[];\n };\n ignore: {\n dirs: string[];\n patterns: string[];\n };\n maxDepth: number;\n };\n\n risk: {\n weights: RiskWeights;\n };\n\n interaction: {\n defaultBudget: number;\n defaultModel: string;\n };\n\n tokens: {\n method: 'chars4' | 'tiktoken';\n };\n\n governance: {\n auditEnabled: boolean;\n secretDetection: boolean;\n retentionDays: number;\n };\n}\n\nexport const DEFAULT_CONFIG: CTOConfig = {\n version: '2.0',\n\n analysis: {\n extensions: {\n code: ['ts', 'tsx', 'js', 'jsx', 'py', 'go', 'rs', 'java', 'kt', 'rb', 'php', 'c', 'cpp', 'h', 'hpp', 'cs'],\n config: ['json', 'yml', 'yaml', 'toml'],\n docs: ['md', 'txt', 'rst'],\n },\n ignore: {\n dirs: ['node_modules', 'dist', 'build', '.git', 'coverage', '__pycache__', '.next', 'vendor', '.cto'],\n patterns: ['*.min.js', '*.map', '*.lock', '*.generated.*'],\n },\n maxDepth: 20,\n },\n\n risk: {\n weights: {\n hub: 30,\n typeProvider: 25,\n complexity: 15,\n recency: 15,\n config: 10,\n churn: 5,\n },\n },\n\n interaction: {\n defaultBudget: 50_000,\n defaultModel: 'claude-sonnet-4',\n },\n\n tokens: {\n method: 'chars4',\n },\n\n governance: {\n auditEnabled: true,\n secretDetection: true,\n retentionDays: 90,\n },\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve } from 'node:path';\nimport { analyzeProject } from '../../engine/analyzer.js';\n\nexport const analyzeCommand = new Command('analyze')\n .description('Analyze project structure, dependencies, and risk profile')\n .argument('[path]', 'Project path to analyze', '.')\n .option('--json', 'Output as JSON')\n .option('--method <method>', 'Token counting method: chars4 | tiktoken', 'chars4')\n .option('--risk-only', 'Show only risk distribution and top risk files')\n .option('--graph', 'Show detailed dependency graph info (hubs, clusters, orphans)')\n .action(async (path: string, opts: { json?: boolean; method?: string; riskOnly?: boolean; graph?: boolean }) => {\n try {\n const projectPath = resolve(path);\n const method = (opts.method === 'tiktoken' ? 'tiktoken' : 'chars4') as 'chars4' | 'tiktoken';\n\n console.log(chalk.dim(`\\n Analyzing ${projectPath}...\\n`));\n\n const analysis = await analyzeProject(projectPath, { tokens: { method } });\n\n if (opts.json) {\n console.log(JSON.stringify(analysis, null, 2));\n return;\n }\n\n // Summary\n console.log(chalk.bold.cyan(' 📊 Project Analysis'));\n console.log('');\n console.log(` ${chalk.bold('Project:')} ${analysis.projectName}`);\n console.log(` ${chalk.bold('Stack:')} ${analysis.stack.join(', ') || 'Unknown'}`);\n console.log(` ${chalk.bold('Files:')} ${analysis.totalFiles}`);\n console.log(` ${chalk.bold('Tokens:')} ~${Math.round(analysis.totalTokens / 1000)}K`);\n console.log(` ${chalk.bold('Method:')} ${analysis.tokenMethod}`);\n console.log(` ${chalk.bold('Hash:')} ${analysis.hash.substring(0, 12)}`);\n console.log('');\n\n // Risk profile\n const d = analysis.riskProfile.distribution;\n console.log(chalk.bold(' Risk Distribution:'));\n console.log(` ${chalk.red('Critical:')} ${d.critical} ${chalk.yellow('High:')} ${d.high} ${chalk.blue('Medium:')} ${d.medium} ${chalk.dim('Low:')} ${d.low}`);\n console.log(` ${chalk.bold('Overall complexity:')} ${analysis.riskProfile.overallComplexity.toFixed(1)}`);\n console.log('');\n\n if (opts.riskOnly) {\n // --risk-only: skip graph and other info\n console.log(chalk.dim(` Run ${chalk.bold('cto interact')} to build optimized AI context`));\n console.log('');\n return;\n }\n\n // Graph summary\n const g = analysis.graph;\n console.log(chalk.bold(' Dependency Graph:'));\n console.log(` Nodes: ${g.nodes.length} Edges: ${g.edges.length}`);\n console.log(` Hubs: ${g.hubs.length} Leaves: ${g.leaves.length} Orphans: ${g.orphans.length} Clusters: ${g.clusters.length}`);\n\n if (opts.graph) {\n // --graph: show detailed graph info\n if (g.hubs.length > 0) {\n console.log('');\n console.log(chalk.bold(' Hub Files (imported by 3+ files):'));\n for (const hub of g.hubs.slice(0, 15)) {\n console.log(` ${hub.relativePath} — ${hub.dependents} dependents, score ${hub.score}`);\n }\n }\n if (g.clusters.length > 0) {\n console.log('');\n console.log(chalk.bold(' Clusters:'));\n for (const c of g.clusters.slice(0, 10)) {\n console.log(` ${c.name} — ${c.files.length} files, ${Math.round(c.totalTokens / 1000)}K tokens, cohesion ${c.cohesion}`);\n }\n }\n if (g.orphans.length > 0) {\n console.log('');\n console.log(chalk.bold(` Orphans (${g.orphans.length} files with no connections):`));\n for (const o of g.orphans.slice(0, 10)) {\n console.log(` ${chalk.dim(o)}`);\n }\n if (g.orphans.length > 10) {\n console.log(chalk.dim(` ... and ${g.orphans.length - 10} more`));\n }\n }\n }\n console.log('');\n\n // Top risk files\n if (analysis.riskProfile.topRiskFiles.length > 0) {\n console.log(chalk.bold(' Top Risk Files:'));\n for (const f of analysis.riskProfile.topRiskFiles.slice(0, 10)) {\n const impact = f.exclusionImpact;\n const impactColor = impact === 'critical' ? chalk.red : impact === 'high' ? chalk.yellow : chalk.dim;\n console.log(` ${impactColor(`[${impact}]`)} ${f.relativePath} — risk ${f.riskScore}, ~${Math.round(f.tokens / 1000)}K tokens`);\n }\n console.log('');\n }\n\n console.log(chalk.dim(` Run ${chalk.bold('cto interact')} to build optimized AI context`));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, extname, relative, resolve, basename } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type {\n AnalyzedFile,\n FileKind,\n ProjectAnalysis,\n WalkEntry,\n WalkOptions,\n} from '../types/engine.js';\nimport { DEFAULT_RISK_WEIGHTS } from '../types/engine.js';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\nimport { estimateTokens, countTokensChars4 } from './tokenizer.js';\nimport { buildProjectGraph } from './graph.js';\nimport { scoreAllFiles } from './risk.js';\n\n// ===== FILE WALKING =====\n\nfunction matchesPattern(filename: string, patterns: string[]): boolean {\n for (const pattern of patterns) {\n if (pattern.startsWith('*.')) {\n const ext = pattern.slice(1);\n if (filename.endsWith(ext)) return true;\n } else if (filename === pattern) {\n return true;\n }\n }\n return false;\n}\n\nexport async function walkProject(\n rootPath: string,\n options: WalkOptions,\n): Promise<WalkEntry[]> {\n const results: WalkEntry[] = [];\n const { ignoreDirs, ignorePatterns, extensions, maxDepth = 20 } = options;\n const ignoreDirSet = new Set(ignoreDirs);\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > maxDepth) return;\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n const promises: Promise<void>[] = [];\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!ignoreDirSet.has(entry.name) && !entry.name.startsWith('.')) {\n promises.push(walk(fullPath, depth + 1));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).slice(1).toLowerCase();\n if (ext && extensions.includes(ext) && !matchesPattern(entry.name, ignorePatterns)) {\n promises.push(\n (async () => {\n const fileStat = await stat(fullPath).catch(() => null);\n if (!fileStat) return;\n\n let lines = 0;\n try {\n const content = await readFile(fullPath, 'utf-8');\n lines = content.split('\\n').length;\n } catch {\n lines = 0;\n }\n\n results.push({\n path: fullPath,\n relativePath: relative(rootPath, fullPath),\n extension: ext,\n size: fileStat.size,\n lastModified: fileStat.mtime,\n lines,\n });\n })(),\n );\n }\n }\n }\n\n await Promise.all(promises);\n }\n\n await walk(rootPath, 0);\n return results;\n}\n\n// ===== FILE KIND DETECTION =====\n\nconst TYPE_PATTERNS = [/types?\\//i, /\\.d\\.ts$/, /interfaces?\\//i];\nconst TEST_PATTERNS = [/\\.test\\.[jt]sx?$/, /\\.spec\\.[jt]sx?$/, /\\/__tests__\\//, /\\/tests?\\//];\nconst CONFIG_PATTERNS = [/\\.config\\.[jt]s$/, /rc\\.[jt]s$/, /\\.env/, /tsconfig/, /package\\.json$/, /\\.yml$/, /\\.yaml$/, /\\.toml$/];\nconst ENTRY_PATTERNS = [/^index\\.[jt]sx?$/, /^main\\.[jt]sx?$/, /^app\\.[jt]sx?$/, /^server\\.[jt]sx?$/];\n\nexport function classifyFileKind(relativePath: string): FileKind {\n const filename = basename(relativePath);\n\n if (TYPE_PATTERNS.some((p) => p.test(relativePath))) return 'type';\n if (TEST_PATTERNS.some((p) => p.test(relativePath))) return 'test';\n if (CONFIG_PATTERNS.some((p) => p.test(relativePath) || p.test(filename))) return 'config';\n if (ENTRY_PATTERNS.some((p) => p.test(filename))) return 'entry';\n return 'source';\n}\n\n// ===== STACK DETECTION =====\n\nexport function detectStack(files: WalkEntry[]): string[] {\n const stack: string[] = [];\n const extensions = new Set(files.map((f) => f.extension));\n const paths = files.map((f) => f.relativePath.toLowerCase());\n\n if (extensions.has('ts') || extensions.has('tsx')) stack.push('TypeScript');\n else if (extensions.has('js') || extensions.has('jsx')) stack.push('JavaScript');\n if (extensions.has('py')) stack.push('Python');\n if (extensions.has('go')) stack.push('Go');\n if (extensions.has('rs')) stack.push('Rust');\n if (extensions.has('java')) stack.push('Java');\n if (extensions.has('kt')) stack.push('Kotlin');\n if (extensions.has('rb')) stack.push('Ruby');\n if (extensions.has('php')) stack.push('PHP');\n if (extensions.has('cs')) stack.push('C#');\n if (extensions.has('c') || extensions.has('cpp')) stack.push('C/C++');\n\n if (paths.some((p) => p.includes('next.config'))) stack.push('Next.js');\n if (paths.some((p) => p.includes('nuxt.config'))) stack.push('Nuxt');\n if (paths.some((p) => p.includes('angular.json'))) stack.push('Angular');\n\n return stack;\n}\n\n// ===== MAIN ANALYSIS PIPELINE =====\n\nexport async function analyzeProject(\n projectPath: string,\n config?: Partial<CTOConfig>,\n): Promise<ProjectAnalysis> {\n const absPath = resolve(projectPath);\n const projectName = basename(absPath);\n const mergedConfig = mergeConfig(DEFAULT_CONFIG, config);\n\n // 1. Walk project files\n const allExtensions = [\n ...mergedConfig.analysis.extensions.code,\n ...mergedConfig.analysis.extensions.config,\n ...mergedConfig.analysis.extensions.docs,\n ];\n\n const walkEntries = await walkProject(absPath, {\n ignoreDirs: mergedConfig.analysis.ignore.dirs,\n ignorePatterns: mergedConfig.analysis.ignore.patterns,\n extensions: allExtensions,\n maxDepth: mergedConfig.analysis.maxDepth,\n });\n\n // 2. Estimate tokens and build initial AnalyzedFile[]\n const tokenMethod = mergedConfig.tokens.method;\n const files: AnalyzedFile[] = [];\n\n for (const entry of walkEntries) {\n let tokens: number;\n if (tokenMethod === 'tiktoken') {\n try {\n const content = await readFile(entry.path, 'utf-8');\n tokens = estimateTokens(content, entry.size, 'tiktoken');\n } catch {\n tokens = countTokensChars4(entry.size);\n }\n } else {\n tokens = countTokensChars4(entry.size);\n }\n\n files.push({\n path: entry.path,\n relativePath: entry.relativePath,\n extension: entry.extension,\n size: entry.size,\n tokens,\n lines: entry.lines,\n lastModified: entry.lastModified,\n kind: classifyFileKind(entry.relativePath),\n\n // Graph data — populated by graph analysis\n imports: [],\n importedBy: [],\n isHub: false,\n complexity: 0,\n\n // Risk data — populated by risk analysis\n riskScore: 0,\n riskFactors: [],\n exclusionImpact: 'none',\n });\n }\n\n // 3. Build dependency graph (AST-based, best-effort)\n const graph = buildProjectGraph(absPath, files);\n\n // 4. Enrich files with graph data\n for (const file of files) {\n const nodeImports: string[] = [];\n const nodeImportedBy: string[] = [];\n\n for (const edge of graph.edges) {\n if (edge.from === file.relativePath) nodeImports.push(edge.to);\n if (edge.to === file.relativePath) nodeImportedBy.push(edge.from);\n }\n\n file.imports = nodeImports;\n file.importedBy = nodeImportedBy;\n file.isHub = graph.hubs.some((h) => h.relativePath === file.relativePath);\n }\n\n // 5. Score risk for all files\n const riskWeights = mergedConfig.risk.weights;\n scoreAllFiles(files, graph, riskWeights);\n\n // 6. Build risk profile\n const riskProfile = {\n distribution: {\n critical: files.filter((f) => f.riskScore >= 80).length,\n high: files.filter((f) => f.riskScore >= 60 && f.riskScore < 80).length,\n medium: files.filter((f) => f.riskScore >= 30 && f.riskScore < 60).length,\n low: files.filter((f) => f.riskScore < 30).length,\n },\n topRiskFiles: [...files].sort((a, b) => b.riskScore - a.riskScore).slice(0, 10),\n overallComplexity: files.length > 0\n ? files.reduce((s, f) => s + f.complexity, 0) / files.length\n : 0,\n };\n\n // 7. Build analysis hash for determinism\n const totalTokens = files.reduce((s, f) => s + f.tokens, 0);\n const hashInput = files\n .map((f) => `${f.relativePath}:${f.tokens}:${f.riskScore}`)\n .sort()\n .join('|');\n const hash = createHash('sha256').update(hashInput).digest('hex').substring(0, 16);\n\n const stack = detectStack(walkEntries);\n\n return {\n projectPath: absPath,\n projectName,\n analyzedAt: new Date(),\n hash,\n files,\n totalFiles: files.length,\n totalTokens,\n graph,\n riskProfile,\n stack,\n tokenMethod,\n };\n}\n\n// ===== CONFIG MERGE =====\n\nfunction mergeConfig(base: CTOConfig, overrides?: Partial<CTOConfig>): CTOConfig {\n if (!overrides) return base;\n\n return {\n ...base,\n ...overrides,\n analysis: {\n ...base.analysis,\n ...overrides.analysis,\n extensions: {\n ...base.analysis.extensions,\n ...overrides.analysis?.extensions,\n },\n ignore: {\n ...base.analysis.ignore,\n ...overrides.analysis?.ignore,\n },\n },\n risk: {\n ...base.risk,\n ...overrides.risk,\n weights: {\n ...base.risk.weights,\n ...overrides.risk?.weights,\n },\n },\n interaction: {\n ...base.interaction,\n ...overrides.interaction,\n },\n tokens: {\n ...base.tokens,\n ...overrides.tokens,\n },\n governance: {\n ...base.governance,\n ...overrides.governance,\n },\n };\n}\n","// ===== Layer 1: Context Intelligence Engine Types =====\n\n// ===== FILE ANALYSIS =====\n\nexport interface AnalyzedFile {\n path: string;\n relativePath: string;\n extension: string;\n size: number;\n tokens: number;\n lines: number;\n lastModified: Date;\n kind: FileKind;\n\n // Graph data (populated after graph analysis)\n imports: string[];\n importedBy: string[];\n isHub: boolean;\n complexity: number;\n\n // Risk data (populated after risk analysis)\n riskScore: number;\n riskFactors: RiskFactor[];\n exclusionImpact: ExclusionImpact;\n}\n\nexport type FileKind = 'source' | 'type' | 'test' | 'config' | 'entry' | 'asset';\nexport type ExclusionImpact = 'critical' | 'high' | 'medium' | 'low' | 'none';\n\n// ===== PROJECT ANALYSIS =====\n\nexport interface ProjectAnalysis {\n projectPath: string;\n projectName: string;\n analyzedAt: Date;\n hash: string;\n\n files: AnalyzedFile[];\n totalFiles: number;\n totalTokens: number;\n\n graph: ProjectGraph;\n riskProfile: RiskProfile;\n stack: string[];\n tokenMethod: 'chars4' | 'tiktoken';\n}\n\n// ===== DEPENDENCY GRAPH =====\n\nexport interface ProjectGraph {\n nodes: string[];\n edges: GraphEdge[];\n hubs: HubNode[];\n leaves: string[];\n orphans: string[];\n clusters: FileCluster[];\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n type: 'import' | 'export' | 're-export';\n}\n\nexport interface HubNode {\n relativePath: string;\n dependents: number;\n dependencies: number;\n score: number;\n}\n\nexport interface FileCluster {\n id: string;\n name: string;\n files: string[];\n totalTokens: number;\n internalEdges: number;\n externalEdges: number;\n cohesion: number;\n}\n\n// ===== RISK MODEL =====\n\nexport interface RiskProfile {\n distribution: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n };\n topRiskFiles: AnalyzedFile[];\n overallComplexity: number;\n}\n\nexport interface RiskFactor {\n type: RiskFactorType;\n score: number;\n weight: number;\n detail: string;\n}\n\nexport type RiskFactorType =\n | 'hub'\n | 'type-provider'\n | 'complexity'\n | 'recency'\n | 'config'\n | 'churn';\n\nexport interface RiskWeights {\n hub: number;\n typeProvider: number;\n complexity: number;\n recency: number;\n config: number;\n churn: number;\n}\n\nexport const DEFAULT_RISK_WEIGHTS: RiskWeights = {\n hub: 30,\n typeProvider: 25,\n complexity: 15,\n recency: 15,\n config: 10,\n churn: 5,\n};\n\n// ===== CONTEXT COVERAGE =====\n\nexport interface CoverageResult {\n score: number;\n relevantFiles: string[];\n includedRelevant: string[];\n missingRelevant: string[];\n missingCritical: string[];\n explanation: string;\n}\n\n// ===== CONTEXT SELECTION =====\n\nexport interface ContextSelection {\n files: SelectedFile[];\n totalTokens: number;\n budget: number;\n usedPercent: number;\n\n coverage: CoverageResult;\n riskScore: number;\n deterministic: boolean;\n hash: string;\n\n decisions: SelectionDecision[];\n}\n\nexport interface SelectedFile {\n relativePath: string;\n tokens: number;\n originalTokens: number;\n pruneLevel: PruneLevel;\n riskScore: number;\n reason: string;\n}\n\nexport type PruneLevel = 'full' | 'signatures' | 'skeleton' | 'excluded';\n\nexport interface SelectionDecision {\n file: string;\n action: 'include-full' | 'include-signatures' | 'include-skeleton' | 'exclude';\n reason: string;\n alternatives?: string;\n}\n\n// ===== BUDGET =====\n\nexport interface BudgetPlan {\n budget: number;\n used: number;\n remaining: number;\n fillPercent: number;\n files: BudgetEntry[];\n}\n\nexport interface BudgetEntry {\n relativePath: string;\n originalTokens: number;\n allocatedTokens: number;\n pruneLevel: PruneLevel;\n included: boolean;\n reason: string;\n}\n\n// ===== PRUNING =====\n\nexport interface PrunedContent {\n relativePath: string;\n originalTokens: number;\n prunedTokens: number;\n pruneLevel: PruneLevel;\n content: string;\n savingsPercent: number;\n}\n\n// ===== WALKER =====\n\nexport interface WalkEntry {\n path: string;\n relativePath: string;\n extension: string;\n size: number;\n lastModified: Date;\n lines: number;\n}\n\nexport interface WalkOptions {\n ignoreDirs: string[];\n ignorePatterns: string[];\n extensions: string[];\n maxDepth?: number;\n}\n","import { encodingForModel } from 'js-tiktoken';\nimport { readFile, stat } from 'node:fs/promises';\n\nconst CHARS_PER_TOKEN = 4;\n\nlet encoder: ReturnType<typeof encodingForModel> | null = null;\n\nfunction getEncoder() {\n if (!encoder) {\n encoder = encodingForModel('claude-3-5-sonnet-20241022' as Parameters<typeof encodingForModel>[0]);\n }\n return encoder;\n}\n\nexport function countTokensTiktoken(text: string): number {\n try {\n const enc = getEncoder();\n const tokens = enc.encode(text);\n return tokens.length;\n } catch {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n }\n}\n\nexport function countTokensChars4(sizeInBytes: number): number {\n return Math.ceil(sizeInBytes / CHARS_PER_TOKEN);\n}\n\nexport function estimateTokens(\n content: string,\n sizeInBytes: number,\n method: 'chars4' | 'tiktoken' = 'chars4',\n): number {\n if (method === 'tiktoken') {\n return countTokensTiktoken(content);\n }\n return countTokensChars4(sizeInBytes);\n}\n\nexport async function estimateFileTokens(\n filePath: string,\n method: 'chars4' | 'tiktoken' = 'chars4',\n): Promise<number> {\n if (method === 'chars4') {\n const s = await stat(filePath);\n return countTokensChars4(s.size);\n }\n\n try {\n const content = await readFile(filePath, 'utf-8');\n return countTokensTiktoken(content);\n } catch {\n const s = await stat(filePath);\n return countTokensChars4(s.size);\n }\n}\n\nexport function freeEncoder(): void {\n encoder = null;\n}\n","import { Project, SyntaxKind, type SourceFile, type Node } from 'ts-morph';\nimport { resolve, relative, dirname, join, basename } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport type {\n AnalyzedFile,\n ProjectGraph,\n GraphEdge,\n HubNode,\n FileCluster,\n} from '../types/engine.js';\n\nconst TS_EXTENSIONS = new Set(['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs', 'cts', 'cjs']);\n\n// ===== PROJECT CREATION =====\n\nexport function createProject(projectPath: string, filePaths: string[]): Project {\n const tsConfigPath = join(projectPath, 'tsconfig.json');\n const hasTsConfig = existsSync(tsConfigPath);\n\n const project = new Project({\n tsConfigFilePath: hasTsConfig ? tsConfigPath : undefined,\n skipAddingFilesFromTsConfig: true,\n compilerOptions: hasTsConfig\n ? undefined\n : {\n allowJs: true,\n jsx: 4 as any, // JsxEmit.ReactJSX\n esModuleInterop: true,\n moduleResolution: 100 as any, // Bundler\n },\n });\n\n const tsFiles = filePaths.filter((f) => {\n const ext = f.split('.').pop()?.toLowerCase() ?? '';\n return TS_EXTENSIONS.has(ext);\n });\n\n for (const filePath of tsFiles) {\n try {\n project.addSourceFileAtPath(filePath);\n } catch {\n // skip files that can't be parsed\n }\n }\n\n return project;\n}\n\n// ===== DEPENDENCY GRAPH =====\n\nexport function buildProjectGraph(\n projectPath: string,\n files: AnalyzedFile[],\n): ProjectGraph {\n const absPath = resolve(projectPath);\n\n const tsFiles = files\n .filter((f) => TS_EXTENSIONS.has(f.extension))\n .map((f) => f.path);\n\n if (tsFiles.length === 0) {\n return emptyGraph(files);\n }\n\n let project: Project;\n try {\n project = createProject(projectPath, tsFiles);\n } catch {\n return emptyGraph(files);\n }\n\n const edges: GraphEdge[] = [];\n const nodeSet = new Set<string>();\n\n for (const sourceFile of project.getSourceFiles()) {\n const fromRel = relative(absPath, sourceFile.getFilePath());\n if (fromRel.startsWith('..') || fromRel.includes('node_modules')) continue;\n nodeSet.add(fromRel);\n\n // Imports\n for (const imp of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = imp.getModuleSpecifierValue();\n const resolved = resolveImport(sourceFile, moduleSpecifier, absPath);\n if (resolved) {\n nodeSet.add(resolved);\n edges.push({ from: fromRel, to: resolved, type: 'import' });\n }\n }\n\n // Re-exports\n for (const exp of sourceFile.getExportDeclarations()) {\n const moduleSpecifier = exp.getModuleSpecifierValue();\n if (moduleSpecifier) {\n const resolved = resolveImport(sourceFile, moduleSpecifier, absPath);\n if (resolved) {\n nodeSet.add(resolved);\n edges.push({ from: fromRel, to: resolved, type: 're-export' });\n }\n }\n }\n }\n\n const nodes = Array.from(nodeSet);\n\n // Calculate import counts\n const importedByCount = new Map<string, number>();\n const importCount = new Map<string, number>();\n\n for (const edge of edges) {\n importedByCount.set(edge.to, (importedByCount.get(edge.to) ?? 0) + 1);\n importCount.set(edge.from, (importCount.get(edge.from) ?? 0) + 1);\n }\n\n // Identify hubs using normalized in-degree centrality (Freeman, 1978).\n // centrality = in-degree / (N - 1), then combined with out-degree for a\n // \"betweenness-lite\" score: score = (in-degree × 2 + out-degree) / (N - 1 + 1)\n // This normalizes by graph size so hub detection is consistent across projects.\n const N = Math.max(nodes.length, 1);\n const hubs: HubNode[] = nodes\n .map((node) => {\n const inDeg = importedByCount.get(node) ?? 0;\n const outDeg = importCount.get(node) ?? 0;\n // Normalized centrality score (0-100 scale)\n const centrality = N > 1 ? (inDeg / (N - 1)) * 100 : 0;\n const score = Math.round(centrality + outDeg * (100 / (2 * N)));\n return {\n relativePath: node,\n dependents: inDeg,\n dependencies: outDeg,\n score: Math.min(100, score),\n };\n })\n .filter((h) => h.dependents >= 3 || h.score >= 15)\n .sort((a, b) => b.score - a.score);\n\n // Identify leaves (files that import but are not imported by anyone)\n const leaves = nodes.filter(\n (node) => (importedByCount.get(node) ?? 0) === 0 && (importCount.get(node) ?? 0) > 0,\n );\n\n // Identify orphans (files with no connections at all)\n const connectedNodes = new Set<string>();\n for (const edge of edges) {\n connectedNodes.add(edge.from);\n connectedNodes.add(edge.to);\n }\n const allFileNodes = new Set(files.map((f) => f.relativePath));\n const orphans = Array.from(allFileNodes).filter((n) => !connectedNodes.has(n));\n\n // Detect clusters using Union-Find for true connected components,\n // then refine with directory grouping for naming.\n const clusters = detectClusters(nodes, edges, files);\n\n // Enrich files with complexity (AST-based)\n enrichComplexity(project, absPath, files);\n\n return { nodes, edges, hubs, leaves, orphans, clusters };\n}\n\n// ===== CLUSTER DETECTION (Union-Find + directory naming) =====\n\nclass UnionFind {\n parent: Map<string, string>;\n rank: Map<string, number>;\n\n constructor(nodes: string[]) {\n this.parent = new Map();\n this.rank = new Map();\n for (const n of nodes) {\n this.parent.set(n, n);\n this.rank.set(n, 0);\n }\n }\n\n find(x: string): string {\n const p = this.parent.get(x);\n if (p === undefined) return x;\n if (p !== x) {\n this.parent.set(x, this.find(p)); // path compression\n }\n return this.parent.get(x)!;\n }\n\n union(a: string, b: string): void {\n const ra = this.find(a);\n const rb = this.find(b);\n if (ra === rb) return;\n const rankA = this.rank.get(ra) ?? 0;\n const rankB = this.rank.get(rb) ?? 0;\n if (rankA < rankB) {\n this.parent.set(ra, rb);\n } else if (rankA > rankB) {\n this.parent.set(rb, ra);\n } else {\n this.parent.set(rb, ra);\n this.rank.set(ra, rankA + 1);\n }\n }\n}\n\nfunction detectClusters(\n nodes: string[],\n edges: GraphEdge[],\n files: AnalyzedFile[],\n): FileCluster[] {\n // 1. Build connected components using Union-Find (O(E × α(V)))\n const uf = new UnionFind(nodes);\n for (const edge of edges) {\n uf.union(edge.from, edge.to);\n }\n\n // 2. Group by component root\n const components = new Map<string, string[]>();\n for (const node of nodes) {\n const root = uf.find(node);\n if (!components.has(root)) components.set(root, []);\n components.get(root)!.push(node);\n }\n\n // 3. For each component, derive a human-readable name from common directory prefix\n const tokenMap = new Map(files.map((f) => [f.relativePath, f.tokens]));\n const clusters: FileCluster[] = [];\n\n for (const [, groupFiles] of components) {\n if (groupFiles.length < 2) continue;\n\n // Find common directory prefix for naming\n const name = commonPrefix(groupFiles);\n const fileSet = new Set(groupFiles);\n let internalEdges = 0;\n let externalEdges = 0;\n\n for (const edge of edges) {\n const fromIn = fileSet.has(edge.from);\n const toIn = fileSet.has(edge.to);\n if (fromIn && toIn) internalEdges++;\n else if (fromIn || toIn) externalEdges++;\n }\n\n const totalEdges = internalEdges + externalEdges;\n const cohesion = totalEdges > 0 ? internalEdges / totalEdges : 0;\n const totalTokens = groupFiles.reduce((s, f) => s + (tokenMap.get(f) ?? 0), 0);\n\n clusters.push({\n id: name.replace(/[^a-zA-Z0-9]/g, '-') || `cluster-${clusters.length}`,\n name: name || `cluster-${clusters.length}`,\n files: groupFiles,\n totalTokens,\n internalEdges,\n externalEdges,\n cohesion: Math.round(cohesion * 100) / 100,\n });\n }\n\n return clusters.sort((a, b) => b.files.length - a.files.length);\n}\n\nfunction commonPrefix(paths: string[]): string {\n if (paths.length === 0) return '';\n const parts = paths.map((p) => p.split('/'));\n const prefix: string[] = [];\n for (let i = 0; i < parts[0].length - 1; i++) {\n const segment = parts[0][i];\n if (parts.every((p) => p[i] === segment)) {\n prefix.push(segment);\n } else break;\n }\n return prefix.join('/') || parts[0][0];\n}\n\n// ===== COMPLEXITY ANALYSIS =====\n\nfunction enrichComplexity(\n project: Project,\n absPath: string,\n files: AnalyzedFile[],\n): void {\n const fileMap = new Map(files.map((f) => [f.relativePath, f]));\n\n for (const sourceFile of project.getSourceFiles()) {\n const relPath = relative(absPath, sourceFile.getFilePath());\n if (relPath.startsWith('..') || relPath.includes('node_modules')) continue;\n\n const file = fileMap.get(relPath);\n if (!file) continue;\n\n let totalComplexity = 0;\n\n // Function declarations\n for (const func of sourceFile.getFunctions()) {\n totalComplexity += calculateCyclomaticComplexity(func);\n }\n\n // Class methods\n for (const cls of sourceFile.getClasses()) {\n for (const method of cls.getMethods()) {\n totalComplexity += calculateCyclomaticComplexity(method);\n }\n }\n\n // Arrow functions assigned to variables\n for (const varDecl of sourceFile.getVariableDeclarations()) {\n const init = varDecl.getInitializer();\n if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n totalComplexity += calculateCyclomaticComplexity(init);\n }\n }\n\n file.complexity = Math.max(1, totalComplexity);\n }\n}\n\nfunction calculateCyclomaticComplexity(node: Node): number {\n let complexity = 1;\n\n node.forEachDescendant((descendant) => {\n switch (descendant.getKind()) {\n case SyntaxKind.IfStatement:\n case SyntaxKind.ConditionalExpression:\n case SyntaxKind.ForStatement:\n case SyntaxKind.ForInStatement:\n case SyntaxKind.ForOfStatement:\n case SyntaxKind.WhileStatement:\n case SyntaxKind.DoStatement:\n case SyntaxKind.CaseClause:\n case SyntaxKind.CatchClause:\n complexity++;\n break;\n case SyntaxKind.BinaryExpression: {\n // FIX: Check the operator token kind directly instead of getText()\n // to avoid double-counting nested logical expressions.\n // getText() on `a && (b || c)` returns the full text including\n // the inner `||`, which would match both operators from the outer node.\n const opToken = (descendant as any).getOperatorToken?.();\n if (opToken) {\n const kind = opToken.getKind();\n if (\n kind === SyntaxKind.AmpersandAmpersandToken ||\n kind === SyntaxKind.BarBarToken ||\n kind === SyntaxKind.QuestionQuestionToken\n ) {\n complexity++;\n }\n }\n break;\n }\n }\n });\n\n return complexity;\n}\n\n// ===== IMPORT RESOLUTION =====\n\nfunction resolveImport(\n sourceFile: SourceFile,\n moduleSpecifier: string,\n projectRoot: string,\n): string | null {\n if (!moduleSpecifier.startsWith('.')) return null;\n\n const sourceDir = dirname(sourceFile.getFilePath());\n const basePath = resolve(sourceDir, moduleSpecifier);\n\n const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js', '/index.jsx'];\n\n for (const ext of extensions) {\n const candidate = basePath.endsWith(ext) ? basePath : basePath + ext;\n if (existsSync(candidate)) {\n const rel = relative(projectRoot, candidate);\n if (!rel.startsWith('..')) return rel;\n }\n }\n\n // .js → .ts resolution\n if (moduleSpecifier.endsWith('.js')) {\n const tsPath = basePath.replace(/\\.js$/, '.ts');\n if (existsSync(tsPath)) {\n const rel = relative(projectRoot, tsPath);\n if (!rel.startsWith('..')) return rel;\n }\n }\n\n return null;\n}\n\n// ===== HELPERS =====\n\nfunction emptyGraph(files: AnalyzedFile[]): ProjectGraph {\n return {\n nodes: files.map((f) => f.relativePath),\n edges: [],\n hubs: [],\n leaves: [],\n orphans: files.map((f) => f.relativePath),\n clusters: [],\n };\n}\n","import type {\n AnalyzedFile,\n RiskFactor,\n RiskFactorType,\n RiskWeights,\n ExclusionImpact,\n ProjectGraph,\n} from '../types/engine.js';\nimport { DEFAULT_RISK_WEIGHTS } from '../types/engine.js';\n\n// ===== RISK SCORING ENGINE =====\n//\n// Each file gets a riskScore ∈ [0, 100] representing the risk of EXCLUDING it\n// from AI context. Higher score = more dangerous to exclude.\n//\n// riskScore(file) = Σ(factor.score × factor.weight) / Σ(factor.weight)\n\nexport function scoreAllFiles(\n files: AnalyzedFile[],\n graph: ProjectGraph,\n weights: RiskWeights = DEFAULT_RISK_WEIGHTS,\n): void {\n // Pre-compute type provider map: files that export types used by others\n const typeProviderUsage = computeTypeProviderUsage(files, graph);\n\n for (const file of files) {\n const factors = computeRiskFactors(file, graph, typeProviderUsage, weights);\n file.riskFactors = factors;\n file.riskScore = computeWeightedScore(factors);\n file.exclusionImpact = scoreToImpact(file.riskScore);\n }\n}\n\nexport function scoreFile(\n file: AnalyzedFile,\n graph: ProjectGraph,\n weights: RiskWeights = DEFAULT_RISK_WEIGHTS,\n): number {\n const typeProviderUsage = computeTypeProviderUsage([file], graph);\n const factors = computeRiskFactors(file, graph, typeProviderUsage, weights);\n file.riskFactors = factors;\n file.riskScore = computeWeightedScore(factors);\n file.exclusionImpact = scoreToImpact(file.riskScore);\n return file.riskScore;\n}\n\n// ===== FACTOR COMPUTATION =====\n\nfunction computeRiskFactors(\n file: AnalyzedFile,\n graph: ProjectGraph,\n typeProviderUsage: Map<string, number>,\n weights: RiskWeights,\n): RiskFactor[] {\n const factors: RiskFactor[] = [];\n\n // 1. Hub factor — how many files depend on this file\n factors.push(computeHubFactor(file, weights.hub));\n\n // 2. Type provider factor — exports types used by other files\n factors.push(computeTypeProviderFactor(file, typeProviderUsage, weights.typeProvider));\n\n // 3. Complexity factor — cyclomatic complexity\n factors.push(computeComplexityFactor(file, weights.complexity));\n\n // 4. Recency factor — how recently modified\n factors.push(computeRecencyFactor(file, weights.recency));\n\n // 5. Config factor — is it a config or entry point\n factors.push(computeConfigFactor(file, weights.config));\n\n // 6. Churn factor — based on complexity as proxy (git integration deferred)\n factors.push(computeChurnFactor(file, weights.churn));\n\n return factors;\n}\n\nfunction computeHubFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const dependents = file.importedBy.length;\n\n // Logarithmic scaling: score = min(100, 100 × log₂(1 + dependents) / log₂(1 + K))\n // K=12 means 12 dependents → score 100. Based on information theory:\n // each doubling of dependents adds equal marginal risk.\n const K = 12;\n const score = dependents === 0\n ? 0\n : Math.min(100, Math.round(100 * Math.log2(1 + dependents) / Math.log2(1 + K)));\n\n const detail = dependents === 0\n ? 'No dependents'\n : `Hub: ${dependents} file(s) depend on this (score ${score}/100)`;\n\n return { type: 'hub', score, weight, detail };\n}\n\nfunction computeTypeProviderFactor(\n file: AnalyzedFile,\n usage: Map<string, number>,\n weight: number,\n): RiskFactor {\n const isTypeFile = file.kind === 'type';\n const consumers = usage.get(file.relativePath) ?? 0;\n\n let score: number;\n let detail: string;\n\n if (isTypeFile && consumers >= 4) {\n score = 100;\n detail = `Type provider: used by ${consumers} files (critical type source)`;\n } else if (isTypeFile && consumers >= 1) {\n score = 50;\n detail = `Type provider: used by ${consumers} files`;\n } else if (isTypeFile) {\n score = 30;\n detail = 'Type file (no detected consumers)';\n } else {\n score = 0;\n detail = 'Not a type provider';\n }\n\n return { type: 'type-provider', score, weight, detail };\n}\n\nfunction computeComplexityFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const c = file.complexity;\n\n // Logarithmic scaling: score = min(100, 100 × ln(1 + c) / ln(1 + K))\n // K=30 means complexity 30 → score 100. ln provides diminishing returns\n // for very complex files (consistent with McCabe 1976 thresholds).\n const K = 30;\n const score = Math.min(100, Math.round(100 * Math.log(1 + c) / Math.log(1 + K)));\n\n const detail = c >= 30\n ? `Very high complexity: ${c} (AI needs full context)`\n : c >= 10\n ? `High complexity: ${c}`\n : `Complexity: ${c}`;\n\n return { type: 'complexity', score, weight, detail };\n}\n\nfunction computeRecencyFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const now = Date.now();\n const modified = new Date(file.lastModified).getTime();\n const daysAgo = (now - modified) / (1000 * 60 * 60 * 24);\n\n // Exponential decay with half-life of 7 days.\n // score = 100 × 2^(-daysAgo / halfLife)\n // This is the standard temporal decay model used in information retrieval\n // (Lv & Zhai, 2011 — \"Adaptive Relevance Feedback\").\n const HALF_LIFE = 7;\n const score = Math.round(100 * Math.pow(2, -daysAgo / HALF_LIFE));\n\n const detail = daysAgo <= 1\n ? 'Modified today'\n : `Modified ${Math.round(daysAgo)} days ago (decay score ${score})`;\n\n return { type: 'recency', score, weight, detail };\n}\n\nfunction computeConfigFactor(file: AnalyzedFile, weight: number): RiskFactor {\n let score: number;\n let detail: string;\n\n if (file.kind === 'entry') {\n score = 90;\n detail = 'Entry point — critical for understanding app structure';\n } else if (file.kind === 'config') {\n score = 80;\n detail = 'Configuration file — affects runtime behavior';\n } else {\n score = 0;\n detail = 'Regular source file';\n }\n\n return { type: 'config', score, weight, detail };\n}\n\nfunction computeChurnFactor(file: AnalyzedFile, weight: number): RiskFactor {\n // PROXY: Without git integration, approximate churn as geometric mean of\n // complexity signal and recency signal. This avoids double-weighting\n // (since complexity and recency have their own factors) by using the\n // *interaction* term only — high churn requires BOTH high complexity AND\n // recent modification simultaneously.\n //\n // TODO: Replace with real git churn (commit count in last 30 days) when\n // git integration is added. Proxy weight is intentionally low (5%).\n const complexitySignal = Math.min(file.complexity / 20, 1);\n const now = Date.now();\n const daysAgo = (now - new Date(file.lastModified).getTime()) / (1000 * 60 * 60 * 24);\n const recencySignal = Math.pow(2, -daysAgo / 7); // same half-life as recency factor\n\n // Geometric mean ensures both signals must be high for a high score\n const score = Math.round(Math.sqrt(complexitySignal * recencySignal) * 100);\n const detail = score >= 50\n ? 'Likely under active development (complex + recent)'\n : score >= 20\n ? 'Some recent activity'\n : 'Stable — low churn (proxy estimate)';\n\n return { type: 'churn', score, weight, detail };\n}\n\n// ===== HELPERS =====\n\nfunction computeWeightedScore(factors: RiskFactor[]): number {\n let totalWeightedScore = 0;\n let totalWeight = 0;\n\n for (const factor of factors) {\n totalWeightedScore += factor.score * factor.weight;\n totalWeight += factor.weight;\n }\n\n if (totalWeight === 0) return 0;\n return Math.round(totalWeightedScore / totalWeight);\n}\n\nfunction scoreToImpact(score: number): ExclusionImpact {\n if (score >= 80) return 'critical';\n if (score >= 60) return 'high';\n if (score >= 30) return 'medium';\n if (score > 0) return 'low';\n return 'none';\n}\n\nfunction computeTypeProviderUsage(\n files: AnalyzedFile[],\n graph: ProjectGraph,\n): Map<string, number> {\n const usage = new Map<string, number>();\n\n // Count how many files import each type file\n const typeFiles = new Set(\n files.filter((f) => f.kind === 'type').map((f) => f.relativePath),\n );\n\n for (const edge of graph.edges) {\n if (typeFiles.has(edge.to)) {\n usage.set(edge.to, (usage.get(edge.to) ?? 0) + 1);\n }\n }\n\n return usage;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { writeFile } from 'node:fs/promises';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { getCachedAnalysis } from '../../engine/cache.js';\nimport { generatePRContext } from '../../engine/pr-context.js';\nimport { planInteraction } from '../../interact/orchestrator.js';\n\nexport const interactCommand = new Command('interact')\n .description('Build optimized AI context for a task')\n .argument('<task>', 'Description of the task (e.g. \"refactor the auth middleware\")')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-m, --model <model>', 'Force model: claude-haiku-3.5 | claude-sonnet-4 | claude-opus-4')\n .option('--no-cot', 'Disable chain-of-thought in prompt')\n .option('--json', 'Output as JSON')\n .option('--prompt-only', 'Only show the generated prompt')\n .option('-o, --output <target>', 'Output target: stdout | file | clipboard', 'stdout')\n .option('--explain', 'Show detailed decision explanations')\n .option('--pr [branch]', 'PR mode: focus on changed files vs base branch (default: main)')\n .action(async (task: string, opts: {\n path?: string;\n budget?: string;\n model?: string;\n cot?: boolean;\n json?: boolean;\n promptOnly?: boolean;\n output?: string;\n explain?: boolean;\n pr?: string | boolean;\n }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n console.log(chalk.dim(`\\n Analyzing ${projectPath}...`));\n const analysis = await getCachedAnalysis(projectPath);\n\n // PR mode: show PR context summary before planning\n if (opts.pr !== undefined) {\n const baseBranch = typeof opts.pr === 'string' ? opts.pr : 'main';\n console.log(chalk.dim(` PR mode: comparing against ${baseBranch}...\\n`));\n const pr = await generatePRContext(analysis, { baseBranch });\n\n if (!pr.isGitRepo) {\n console.log(chalk.yellow(' ⚠️ Not a git repository. Falling back to normal mode.\\n'));\n } else if (pr.changedFiles.length === 0) {\n console.log(chalk.yellow(` ⚠️ No changed files vs ${baseBranch}. Falling back to normal mode.\\n`));\n } else {\n console.log(chalk.bold.magenta(' 📋 PR Context'));\n console.log(` Branch: ${pr.currentBranch} ← ${baseBranch}`);\n console.log(` Changed: ${pr.changedFiles.length} files | Dependencies: ${pr.dependencyFiles.length} files`);\n console.log(` Tokens: ~${Math.round(pr.totalContextTokens / 1000)}K`);\n if (pr.riskSummary.critical > 0 || pr.riskSummary.high > 0) {\n console.log(chalk.yellow(` ⚠️ ${pr.riskSummary.critical} critical + ${pr.riskSummary.high} high-risk files`));\n }\n console.log('');\n }\n }\n\n console.log(chalk.dim(` Planning interaction for: \"${task}\"\\n`));\n const plan = await planInteraction({\n task,\n analysis,\n budget,\n model: opts.model,\n enableCoT: opts.cot !== false,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(plan, null, 2));\n return;\n }\n\n if (opts.promptOnly) {\n console.log(plan.prompt.rendered);\n return;\n }\n\n // Decisions summary\n console.log(chalk.bold.cyan(' 🧠 Interaction Plan'));\n console.log('');\n\n for (const d of plan.decisions) {\n const icon = d.step === 'classify' ? '🏷️'\n : d.step === 'select-context' ? '📂'\n : d.step === 'choose-model' ? '🤖'\n : d.step === 'build-prompt' ? '📝'\n : d.step === 'estimate-cost' ? '💰'\n : '•';\n console.log(` ${icon} ${chalk.bold(d.step)}: ${d.decision}`);\n console.log(` ${chalk.dim(d.reason)}`);\n }\n console.log('');\n\n // Context summary\n console.log(chalk.bold(' Context:'));\n const ctx = plan.context;\n console.log(` Files: ${ctx.files.length} | Tokens: ~${Math.round(ctx.totalTokens / 1000)}K / ${Math.round(budget / 1000)}K (${ctx.usedPercent.toFixed(1)}%)`);\n console.log(` Coverage: ${ctx.coverage.score}% | Risk: ${ctx.riskScore}/100`);\n\n if (ctx.coverage.missingCritical.length > 0) {\n console.log(chalk.yellow(` ⚠️ Missing critical: ${ctx.coverage.missingCritical.join(', ')}`));\n }\n console.log('');\n\n // File list\n const fullFiles = ctx.files.filter((f) => f.pruneLevel === 'full');\n const sigFiles = ctx.files.filter((f) => f.pruneLevel === 'signatures');\n const skelFiles = ctx.files.filter((f) => f.pruneLevel === 'skeleton');\n\n if (fullFiles.length > 0) {\n console.log(chalk.bold(' Full content:'));\n for (const f of fullFiles) {\n console.log(` ${chalk.green('●')} ${f.relativePath} (~${Math.round(f.tokens / 1000)}K)`);\n }\n }\n if (sigFiles.length > 0) {\n console.log(chalk.bold(' Signatures:'));\n for (const f of sigFiles) {\n console.log(` ${chalk.yellow('○')} ${f.relativePath} (~${Math.round(f.tokens / 1000)}K)`);\n }\n }\n if (skelFiles.length > 0) {\n console.log(chalk.bold(' Skeleton:'));\n for (const f of skelFiles) {\n console.log(` ${chalk.dim('◌')} ${f.relativePath}`);\n }\n }\n console.log('');\n\n // Cost\n console.log(chalk.bold(' Cost Estimate:'));\n console.log(` Model: ${plan.model.model}`);\n console.log(` This interaction: ${plan.cost.formatted}`);\n console.log(` Without optimization: ${plan.cost.withoutOptimization.formatted}`);\n console.log(` ${chalk.green(plan.cost.savings.formatted)}`);\n console.log('');\n\n // Prompt stats\n console.log(chalk.bold(' Prompt:'));\n console.log(` Sections: ${plan.prompt.sections.map((s) => s.id).join(', ')}`);\n console.log(` Prompt tokens: ~${Math.round(plan.prompt.totalTokens / 1000)}K`);\n console.log('');\n\n // --explain: show detailed selection decisions\n if (opts.explain && plan.context.decisions.length > 0) {\n console.log(chalk.bold(' Decisions:'));\n for (const d of plan.context.decisions.slice(0, 20)) {\n const icon = d.action === 'exclude' ? chalk.red('✗') : chalk.green('✓');\n console.log(` ${icon} ${d.file} — ${d.reason}`);\n if (d.alternatives) {\n console.log(chalk.dim(` Alternative: ${d.alternatives}`));\n }\n }\n if (plan.context.decisions.length > 20) {\n console.log(chalk.dim(` ... and ${plan.context.decisions.length - 20} more decisions`));\n }\n console.log('');\n }\n\n // --output: save prompt to file or clipboard\n if (opts.output === 'file') {\n const outPath = join(resolve(opts.path ?? '.'), '.cto', `prompt-${plan.id}.md`);\n await writeFile(outPath, plan.prompt.rendered, 'utf-8');\n console.log(chalk.green(` 💾 Prompt saved to ${outPath}`));\n console.log('');\n } else if (opts.output === 'clipboard') {\n try {\n const { execSync } = await import('node:child_process');\n execSync('pbcopy', { input: plan.prompt.rendered });\n console.log(chalk.green(' 📋 Prompt copied to clipboard'));\n console.log('');\n } catch {\n console.log(chalk.yellow(' ⚠️ Could not copy to clipboard. Use --output file instead.'));\n console.log('');\n }\n }\n\n console.log(chalk.dim(` Use ${chalk.bold('--prompt-only')} to get the full prompt`));\n console.log(chalk.dim(` Use ${chalk.bold('--json')} for machine-readable output`));\n console.log(chalk.dim(` Use ${chalk.bold('--explain')} for detailed selection decisions`));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { createHash } from 'node:crypto';\nimport { readdir, stat } from 'node:fs/promises';\nimport { join, extname, relative, resolve } from 'node:path';\nimport type { ProjectAnalysis } from '../types/engine.js';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\nimport { analyzeProject } from './analyzer.js';\n\n// ===== Analysis Cache =====\n//\n// Problem: analyzeProject() is expensive (file walk + AST parse + token count + graph build).\n// MCP tools and CLI commands call it on every invocation.\n//\n// Solution: Two-level cache with lightweight fingerprint invalidation.\n// 1. Compute a fast fingerprint: hash of (sorted file paths + mtimes)\n// Cost: O(n) readdir + stat, no file reads, no AST, no token counting\n// 2. If fingerprint matches cached entry → return cached analysis (instant)\n// 3. If fingerprint differs → full re-analysis, update cache\n//\n// TTL: Safety net. Even if fingerprint matches, expire after maxAgeMs.\n//\n// Reference: Content-addressable caching (Git object model principle)\n\ninterface CacheEntry {\n analysis: ProjectAnalysis;\n fingerprint: string;\n createdAt: number;\n hits: number;\n}\n\ninterface CacheOptions {\n maxAgeMs: number;\n maxEntries: number;\n enabled: boolean;\n}\n\nconst DEFAULT_CACHE_OPTIONS: CacheOptions = {\n maxAgeMs: 5 * 60 * 1000, // 5 minutes\n maxEntries: 10,\n enabled: true,\n};\n\n// In-memory LRU-ish cache\nconst cache = new Map<string, CacheEntry>();\nlet cacheOptions: CacheOptions = { ...DEFAULT_CACHE_OPTIONS };\n\n// ===== FINGERPRINT =====\n\n// Fast fingerprint: walk directory, collect paths + mtimes, hash them.\n// ~10-100x faster than full analysis (no file reads, no AST, no tokenization).\nasync function computeFingerprint(\n rootPath: string,\n config: CTOConfig = DEFAULT_CONFIG,\n): Promise<string> {\n const entries: string[] = [];\n const allExtensions = new Set([\n ...config.analysis.extensions.code,\n ...config.analysis.extensions.config,\n ...config.analysis.extensions.docs,\n ]);\n const ignoreDirSet = new Set(config.analysis.ignore.dirs);\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > config.analysis.maxDepth) return;\n\n let dirEntries;\n try {\n dirEntries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n const promises: Promise<void>[] = [];\n\n for (const entry of dirEntries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!ignoreDirSet.has(entry.name) && !entry.name.startsWith('.')) {\n promises.push(walk(fullPath, depth + 1));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).slice(1).toLowerCase();\n if (ext && allExtensions.has(ext)) {\n promises.push(\n (async () => {\n try {\n const s = await stat(fullPath);\n const rel = relative(rootPath, fullPath);\n // Include path + mtime + size for change detection\n entries.push(`${rel}:${s.mtimeMs.toFixed(0)}:${s.size}`);\n } catch {\n // skip inaccessible files\n }\n })(),\n );\n }\n }\n }\n\n await Promise.all(promises);\n }\n\n await walk(rootPath, 0);\n\n // Sort for determinism\n entries.sort();\n return createHash('sha256').update(entries.join('|')).digest('hex').substring(0, 16);\n}\n\n// ===== PUBLIC API =====\n\n/**\n * Get a project analysis, using cache when possible.\n *\n * Cache hit: ~1-5ms (fingerprint check only)\n * Cache miss: full analyzeProject() + cache update\n */\nexport async function getCachedAnalysis(\n projectPath: string,\n config?: Partial<CTOConfig>,\n): Promise<ProjectAnalysis> {\n const absPath = resolve(projectPath);\n\n if (!cacheOptions.enabled) {\n return analyzeProject(absPath, config);\n }\n\n const existing = cache.get(absPath);\n\n // Check TTL first (cheap)\n if (existing) {\n const age = Date.now() - existing.createdAt;\n if (age > cacheOptions.maxAgeMs) {\n cache.delete(absPath);\n }\n }\n\n // Compute fingerprint\n const mergedConfig = config\n ? { ...DEFAULT_CONFIG, ...config } as CTOConfig\n : DEFAULT_CONFIG;\n const fingerprint = await computeFingerprint(absPath, mergedConfig);\n\n // Cache hit: fingerprint matches\n const cached = cache.get(absPath);\n if (cached && cached.fingerprint === fingerprint) {\n cached.hits++;\n return cached.analysis;\n }\n\n // Cache miss: full analysis\n const analysis = await analyzeProject(absPath, config);\n\n // Evict oldest entry if at capacity\n if (cache.size >= cacheOptions.maxEntries) {\n const oldest = [...cache.entries()].sort(\n (a, b) => a[1].createdAt - b[1].createdAt,\n )[0];\n if (oldest) cache.delete(oldest[0]);\n }\n\n cache.set(absPath, {\n analysis,\n fingerprint,\n createdAt: Date.now(),\n hits: 0,\n });\n\n return analysis;\n}\n\n/**\n * Invalidate cache for a specific project (e.g., after a known file change).\n */\nexport function invalidateCache(projectPath?: string): void {\n if (projectPath) {\n cache.delete(resolve(projectPath));\n } else {\n cache.clear();\n }\n}\n\n/**\n * Get cache statistics for debugging/monitoring.\n */\nexport function getCacheStats(): {\n entries: number;\n totalHits: number;\n projects: { path: string; hits: number; ageMs: number }[];\n} {\n const now = Date.now();\n const projects = [...cache.entries()].map(([path, entry]) => ({\n path,\n hits: entry.hits,\n ageMs: now - entry.createdAt,\n }));\n\n return {\n entries: cache.size,\n totalHits: projects.reduce((s, p) => s + p.hits, 0),\n projects,\n };\n}\n\n/**\n * Configure cache behavior.\n */\nexport function configureCache(options: Partial<CacheOptions>): void {\n cacheOptions = { ...cacheOptions, ...options };\n if (!cacheOptions.enabled) {\n cache.clear();\n }\n}\n","import { resolve } from 'node:path';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport type { ProjectAnalysis, AnalyzedFile } from '../types/engine.js';\nimport { buildAdjacencyList, bfsBidirectional } from './graph-utils.js';\n\n// ===== PR Context — Git-diff Aware Context Selection =====\n//\n// When the task is \"review this PR\", sending the entire project is wasteful.\n// This module:\n// 1. Extracts changed files from git diff (branch comparison or working dir)\n// 2. Expands to transitive dependencies using BFS on the adjacency list\n// 3. Prioritizes by risk score (high-risk changed files first)\n// 4. Returns a structured PR context with change categorization\n//\n// Complexity: O(|changed| × depth) for BFS expansion\n\nconst exec = promisify(execFile);\n\nasync function git(args: string[], cwd: string): Promise<string> {\n try {\n const { stdout } = await exec('git', args, { cwd, maxBuffer: 10 * 1024 * 1024 });\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n// ===== TYPES =====\n\nexport type ChangeType = 'added' | 'modified' | 'deleted' | 'renamed';\n\nexport interface ChangedFile {\n relativePath: string;\n changeType: ChangeType;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport interface PRContextResult {\n baseBranch: string;\n currentBranch: string;\n isGitRepo: boolean;\n\n changedFiles: ChangedFile[];\n dependencyFiles: string[];\n allRelevantFiles: AnalyzedFile[];\n\n totalChangedTokens: number;\n totalContextTokens: number;\n\n riskSummary: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n maxRiskFile: string;\n maxRiskScore: number;\n };\n\n renderedSummary: string;\n}\n\nexport interface PRContextOptions {\n baseBranch?: string;\n depth?: number;\n includeTests?: boolean;\n}\n\n// ===== GIT OPERATIONS =====\n\nasync function isGitRepo(projectPath: string): Promise<boolean> {\n const result = await git(['rev-parse', '--is-inside-work-tree'], projectPath);\n return result === 'true';\n}\n\nasync function getCurrentBranch(projectPath: string): Promise<string> {\n return git(['rev-parse', '--abbrev-ref', 'HEAD'], projectPath);\n}\n\nasync function getChangedFilesFromDiff(\n projectPath: string,\n baseBranch?: string,\n): Promise<ChangedFile[]> {\n const results = new Map<string, ChangedFile>();\n\n // Working directory changes (unstaged)\n const workingDiff = await git(['diff', '--numstat', 'HEAD'], projectPath);\n parseDiffNumstat(workingDiff, results, 'modified');\n\n // Staged changes\n const stagedDiff = await git(['diff', '--numstat', '--cached'], projectPath);\n parseDiffNumstat(stagedDiff, results, 'modified');\n\n // Untracked files\n const untracked = await git(['ls-files', '--others', '--exclude-standard'], projectPath);\n for (const line of untracked.split('\\n')) {\n const f = line.trim();\n if (f && !results.has(f)) {\n results.set(f, { relativePath: f, changeType: 'added', linesAdded: 0, linesRemoved: 0 });\n }\n }\n\n // Branch comparison (if baseBranch provided)\n if (baseBranch) {\n // Check if base branch exists\n const branchExists = await git(['rev-parse', '--verify', baseBranch], projectPath);\n if (branchExists) {\n const branchDiff = await git(['diff', '--numstat', `${baseBranch}...HEAD`], projectPath);\n parseDiffNumstat(branchDiff, results, 'modified');\n\n // Detect newly added files (in HEAD but not in base)\n const nameStatus = await git(['diff', '--name-status', `${baseBranch}...HEAD`], projectPath);\n for (const line of nameStatus.split('\\n')) {\n const parts = line.trim().split('\\t');\n if (parts.length >= 2) {\n const status = parts[0];\n const filePath = parts[parts.length - 1];\n if (results.has(filePath)) {\n const existing = results.get(filePath)!;\n if (status === 'A') existing.changeType = 'added';\n else if (status === 'D') existing.changeType = 'deleted';\n else if (status.startsWith('R')) existing.changeType = 'renamed';\n }\n }\n }\n }\n }\n\n return [...results.values()];\n}\n\nfunction parseDiffNumstat(\n output: string,\n results: Map<string, ChangedFile>,\n defaultType: ChangeType,\n): void {\n for (const line of output.split('\\n')) {\n const parts = line.trim().split('\\t');\n if (parts.length < 3) continue;\n\n const added = parts[0] === '-' ? 0 : parseInt(parts[0], 10) || 0;\n const removed = parts[1] === '-' ? 0 : parseInt(parts[1], 10) || 0;\n const filePath = parts[2];\n\n if (!filePath) continue;\n\n const existing = results.get(filePath);\n if (existing) {\n existing.linesAdded = Math.max(existing.linesAdded, added);\n existing.linesRemoved = Math.max(existing.linesRemoved, removed);\n } else {\n results.set(filePath, {\n relativePath: filePath,\n changeType: defaultType,\n linesAdded: added,\n linesRemoved: removed,\n });\n }\n }\n}\n\n// ===== MAIN API =====\n\n/**\n * Generate PR-focused context by analyzing git changes and expanding dependencies.\n *\n * @param analysis - Project analysis (from analyzeProject or getCachedAnalysis)\n * @param options - PR context options (baseBranch, depth, includeTests)\n * @returns Structured PR context with changed files, dependencies, risk summary\n */\nexport async function generatePRContext(\n analysis: ProjectAnalysis,\n options: PRContextOptions = {},\n): Promise<PRContextResult> {\n const projectPath = resolve(analysis.projectPath);\n const baseBranch = options.baseBranch ?? 'main';\n const depth = options.depth ?? 2;\n const includeTests = options.includeTests ?? false;\n\n // Check git repo\n const gitRepo = await isGitRepo(projectPath);\n if (!gitRepo) {\n return emptyResult(baseBranch);\n }\n\n const currentBranch = await getCurrentBranch(projectPath);\n\n // 1. Get changed files from git\n const changedFiles = await getChangedFilesFromDiff(projectPath, baseBranch);\n\n if (changedFiles.length === 0) {\n return {\n ...emptyResult(baseBranch),\n currentBranch,\n isGitRepo: true,\n renderedSummary: '# PR Context\\n\\nNo changed files detected.',\n };\n }\n\n // 2. Filter to files that exist in our analysis\n const analysisFileSet = new Set(analysis.files.map((f) => f.relativePath));\n const validChangedPaths = changedFiles\n .filter((c) => c.changeType !== 'deleted' && analysisFileSet.has(c.relativePath))\n .map((c) => c.relativePath);\n\n // 3. Expand dependencies using BFS on adjacency list\n const adj = buildAdjacencyList(analysis.graph.edges);\n const expanded = bfsBidirectional(validChangedPaths, adj, depth);\n\n // Separate changed files from dependency-only files\n const changedSet = new Set(validChangedPaths);\n const dependencyFiles = [...expanded].filter((f) => !changedSet.has(f));\n\n // 4. Filter tests if not included\n const allRelevantPaths = new Set(expanded);\n if (!includeTests) {\n for (const path of allRelevantPaths) {\n const file = analysis.files.find((f) => f.relativePath === path);\n if (file && file.kind === 'test') {\n // Keep if it was directly changed, remove if it's a dependency\n if (!changedSet.has(path)) {\n allRelevantPaths.delete(path);\n }\n }\n }\n }\n\n // 5. Collect AnalyzedFile objects, sorted by risk score (descending)\n const allRelevantFiles = analysis.files\n .filter((f) => allRelevantPaths.has(f.relativePath))\n .sort((a, b) => b.riskScore - a.riskScore);\n\n // 6. Compute token totals\n const changedAnalyzed = allRelevantFiles.filter((f) => changedSet.has(f.relativePath));\n const totalChangedTokens = changedAnalyzed.reduce((s, f) => s + f.tokens, 0);\n const totalContextTokens = allRelevantFiles.reduce((s, f) => s + f.tokens, 0);\n\n // 7. Risk summary\n const riskSummary = {\n critical: allRelevantFiles.filter((f) => f.riskScore >= 80).length,\n high: allRelevantFiles.filter((f) => f.riskScore >= 60 && f.riskScore < 80).length,\n medium: allRelevantFiles.filter((f) => f.riskScore >= 30 && f.riskScore < 60).length,\n low: allRelevantFiles.filter((f) => f.riskScore < 30).length,\n maxRiskFile: allRelevantFiles[0]?.relativePath ?? '',\n maxRiskScore: allRelevantFiles[0]?.riskScore ?? 0,\n };\n\n // 8. Render summary\n const renderedSummary = renderSummary(\n analysis,\n currentBranch,\n baseBranch,\n changedFiles,\n dependencyFiles,\n allRelevantFiles,\n changedSet,\n riskSummary,\n totalChangedTokens,\n totalContextTokens,\n );\n\n return {\n baseBranch,\n currentBranch,\n isGitRepo: true,\n changedFiles,\n dependencyFiles: dependencyFiles.filter((f) => allRelevantPaths.has(f)),\n allRelevantFiles,\n totalChangedTokens,\n totalContextTokens,\n riskSummary,\n renderedSummary,\n };\n}\n\n// ===== RENDERING =====\n\nfunction renderSummary(\n analysis: ProjectAnalysis,\n currentBranch: string,\n baseBranch: string,\n changedFiles: ChangedFile[],\n dependencyFiles: string[],\n allRelevant: AnalyzedFile[],\n changedSet: Set<string>,\n risk: PRContextResult['riskSummary'],\n changedTokens: number,\n totalTokens: number,\n): string {\n const lines: string[] = [];\n\n lines.push(`## PR Context — ${analysis.projectName}`);\n lines.push('');\n lines.push(`**Branch:** ${currentBranch} ← ${baseBranch}`);\n lines.push(`**Changed:** ${changedFiles.length} files | **Dependencies:** ${dependencyFiles.length} files`);\n lines.push(`**Tokens:** ~${Math.round(changedTokens / 1000)}K changed + ~${Math.round((totalTokens - changedTokens) / 1000)}K context = ~${Math.round(totalTokens / 1000)}K total`);\n lines.push('');\n\n // Risk banner\n if (risk.critical > 0 || risk.high > 0) {\n lines.push(`⚠️ **Risk:** ${risk.critical} critical + ${risk.high} high-risk files affected`);\n lines.push(`**Highest risk:** ${risk.maxRiskFile} (score: ${risk.maxRiskScore})`);\n lines.push('');\n }\n\n // Changed files\n lines.push('### Changed Files');\n lines.push('');\n\n const sortedChanged = changedFiles\n .filter((c) => c.changeType !== 'deleted')\n .sort((a, b) => {\n const fa = allRelevant.find((f) => f.relativePath === a.relativePath);\n const fb = allRelevant.find((f) => f.relativePath === b.relativePath);\n return (fb?.riskScore ?? 0) - (fa?.riskScore ?? 0);\n });\n\n for (const c of sortedChanged) {\n const file = allRelevant.find((f) => f.relativePath === c.relativePath);\n const risk = file ? ` risk:${file.riskScore}` : '';\n const delta = c.linesAdded || c.linesRemoved\n ? ` (+${c.linesAdded}/-${c.linesRemoved})`\n : '';\n const badge = c.changeType === 'added' ? ' 🆕' : c.changeType === 'renamed' ? ' 📝' : '';\n lines.push(`- \\`${c.relativePath}\\`${delta}${risk}${badge}`);\n }\n\n // Deleted files\n const deleted = changedFiles.filter((c) => c.changeType === 'deleted');\n if (deleted.length > 0) {\n lines.push('');\n lines.push(`**Deleted:** ${deleted.map((d) => `\\`${d.relativePath}\\``).join(', ')}`);\n }\n\n // Dependencies\n if (dependencyFiles.length > 0) {\n lines.push('');\n lines.push('### Dependencies (included for context)');\n lines.push('');\n\n const depWithInfo = dependencyFiles\n .map((d) => {\n const file = allRelevant.find((f) => f.relativePath === d);\n return { path: d, riskScore: file?.riskScore ?? 0, tokens: file?.tokens ?? 0 };\n })\n .sort((a, b) => b.riskScore - a.riskScore);\n\n for (const d of depWithInfo) {\n lines.push(`- \\`${d.path}\\` risk:${d.riskScore} ~${Math.round(d.tokens / 1000)}K tokens`);\n }\n }\n\n lines.push('');\n lines.push('### Review Focus');\n lines.push('');\n lines.push('- Review changed files for correctness, especially high-risk files');\n lines.push('- Dependencies are included for type/interface context — not for review');\n lines.push(`- ${analysis.totalFiles - allRelevant.length} files excluded (not affected by this change)`);\n\n return lines.join('\\n');\n}\n\n// ===== HELPERS =====\n\nfunction emptyResult(baseBranch: string): PRContextResult {\n return {\n baseBranch,\n currentBranch: '',\n isGitRepo: false,\n changedFiles: [],\n dependencyFiles: [],\n allRelevantFiles: [],\n totalChangedTokens: 0,\n totalContextTokens: 0,\n riskSummary: { critical: 0, high: 0, medium: 0, low: 0, maxRiskFile: '', maxRiskScore: 0 },\n renderedSummary: '# PR Context\\n\\nNot a git repository.',\n };\n}\n","import type { GraphEdge } from '../types/engine.js';\n\n// ===== SHARED GRAPH UTILITIES =====\n\nexport interface AdjacencyList {\n forward: Map<string, string[]>; // file → files it imports\n reverse: Map<string, string[]>; // file → files that import it\n}\n\nexport function buildAdjacencyList(edges: GraphEdge[]): AdjacencyList {\n const forward = new Map<string, string[]>();\n const reverse = new Map<string, string[]>();\n\n for (const edge of edges) {\n if (!forward.has(edge.from)) forward.set(edge.from, []);\n forward.get(edge.from)!.push(edge.to);\n\n if (!reverse.has(edge.to)) reverse.set(edge.to, []);\n reverse.get(edge.to)!.push(edge.from);\n }\n\n return { forward, reverse };\n}\n\nexport function bfsBidirectional(\n seeds: string[],\n adj: AdjacencyList,\n depth: number,\n): Set<string> {\n const result = new Set(seeds);\n let frontier = [...seeds];\n const visited = new Set<string>();\n\n for (let d = 0; d < depth; d++) {\n const nextFrontier: string[] = [];\n\n for (const node of frontier) {\n if (visited.has(node)) continue;\n visited.add(node);\n\n // Forward neighbors (imports)\n const fwd = adj.forward.get(node);\n if (fwd) {\n for (const neighbor of fwd) {\n if (!visited.has(neighbor)) {\n result.add(neighbor);\n nextFrontier.push(neighbor);\n }\n }\n }\n\n // Reverse neighbors (imported by)\n const rev = adj.reverse.get(node);\n if (rev) {\n for (const neighbor of rev) {\n if (!visited.has(neighbor)) {\n result.add(neighbor);\n nextFrontier.push(neighbor);\n }\n }\n }\n }\n\n frontier = nextFrontier;\n }\n\n return result;\n}\n\nexport function matchGlob(path: string, pattern: string): boolean {\n const regexStr = pattern\n .replace(/\\./g, '\\\\.')\n .replace(/\\*\\*/g, '§§')\n .replace(/\\*/g, '[^/]*')\n .replace(/§§/g, '.*')\n .replace(/\\?/g, '.');\n\n try {\n return new RegExp(`^${regexStr}$`).test(path);\n } catch {\n return false;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { InteractionPlan, PlanDecision, TaskType } from '../types/interact.js';\nimport type { ProjectAnalysis } from '../types/engine.js';\nimport type { PolicySet } from '../types/govern.js';\nimport { selectContext } from '../engine/selector.js';\nimport { classifyTask, routeModel } from './router.js';\nimport { estimateCost } from './estimator.js';\nimport { buildPrompt } from './prompt.js';\nimport { logAudit } from '../govern/audit.js';\n\n// ===== INTERACTION ORCHESTRATOR =====\n//\n// The brain of CTO v2. Given a task description:\n// 1. Classify task type\n// 2. Select optimal context (deterministic)\n// 3. Choose best model\n// 4. Build structured prompt\n// 5. Estimate cost\n// 6. Explain all decisions\n\nexport interface OrchestratorInput {\n task: string;\n analysis: ProjectAnalysis;\n budget?: number;\n model?: string;\n policies?: PolicySet;\n depth?: number;\n enableCoT?: boolean;\n enableConstraints?: boolean;\n enableAntiHallucination?: boolean;\n}\n\nexport async function planInteraction(input: OrchestratorInput): Promise<InteractionPlan> {\n const {\n task,\n analysis,\n budget = 50_000,\n model: preferredModel,\n policies,\n depth = 2,\n enableCoT = true,\n enableConstraints = true,\n enableAntiHallucination = true,\n } = input;\n\n const decisions: PlanDecision[] = [];\n\n // 1. CLASSIFY task\n const taskType: TaskType = classifyTask(task);\n decisions.push({\n step: 'classify',\n decision: taskType,\n reason: `Task classified as \"${taskType}\" based on keyword analysis`,\n data: { task, taskType },\n });\n\n // 2. SELECT context (deterministic)\n const context = await selectContext({\n task,\n analysis,\n budget,\n policies,\n depth,\n });\n\n decisions.push({\n step: 'select-context',\n decision: `${context.files.length} files selected (${context.totalTokens} tokens)`,\n reason: `Coverage: ${context.coverage.score}%, Risk: ${context.riskScore}/100`,\n data: {\n filesIncluded: context.files.length,\n tokensUsed: context.totalTokens,\n budget,\n coverage: context.coverage.score,\n risk: context.riskScore,\n },\n });\n\n // 3. CHOOSE model\n const modelChoice = routeModel(taskType, analysis, preferredModel);\n decisions.push({\n step: 'choose-model',\n decision: modelChoice.model,\n reason: modelChoice.reason,\n data: {\n confidence: modelChoice.confidence,\n alternatives: modelChoice.alternatives.length,\n },\n });\n\n // 4. BUILD prompt\n const prompt = buildPrompt({\n task,\n taskType,\n analysis,\n selection: context,\n enableCoT,\n enableConstraints,\n enableAntiHallucination,\n });\n\n decisions.push({\n step: 'build-prompt',\n decision: `${prompt.sections.length} sections, ${prompt.totalTokens} tokens`,\n reason: `Sections: ${prompt.sections.map((s) => s.id).join(', ')}`,\n });\n\n // 5. ESTIMATE cost\n const cost = estimateCost(\n modelChoice.model,\n context.totalTokens + prompt.totalTokens,\n analysis.totalTokens,\n );\n\n decisions.push({\n step: 'estimate-cost',\n decision: cost.formatted,\n reason: cost.savings.formatted,\n data: {\n inputTokens: cost.inputTokens,\n totalCost: cost.totalCost,\n savings: cost.savings.percent,\n },\n });\n\n const plan: InteractionPlan = {\n id: randomUUID().substring(0, 8),\n task,\n taskType,\n timestamp: new Date(),\n context,\n model: modelChoice,\n prompt,\n cost,\n decisions,\n };\n\n // 6. AUDIT LOG — record this interaction for governance\n try {\n await logAudit('interact', analysis.projectPath, {\n interactionId: plan.id,\n task,\n taskType,\n contextHash: context.hash,\n filesIncluded: context.files.length,\n filesExcluded: analysis.totalFiles - context.files.length,\n tokensUsed: context.totalTokens,\n coverageScore: context.coverage.score,\n riskScore: context.riskScore,\n model: modelChoice.model,\n estimatedCost: cost.totalCost,\n });\n } catch {\n // Audit failure should never block the interaction pipeline\n }\n\n return plan;\n}\n","import { createHash } from 'node:crypto';\nimport type {\n AnalyzedFile,\n ProjectAnalysis,\n ContextSelection,\n SelectedFile,\n SelectionDecision,\n PruneLevel,\n CoverageResult,\n} from '../types/engine.js';\nimport type { PolicySet, PolicyRule } from '../types/govern.js';\nimport { scanFileForSecrets } from '../govern/secrets.js';\nimport { pruneFile } from './pruner.js';\nimport { calculateCoverage } from './coverage.js';\nimport { getPruneLevelForRisk } from './budget.js';\nimport { buildAdjacencyList, bfsBidirectional, matchGlob } from './graph-utils.js';\n\n// ===== DETERMINISTIC CONTEXT SELECTION =====\n//\n// Given a task, analysis, budget, and policies → always returns the same file set.\n// No randomness, no heuristics that change over time.\n//\n// Algorithm:\n// 1. Identify target files from task description\n// 2. Expand via dependency graph (BFS, depth=2)\n// 3. Apply policies (include-always, exclude-always)\n// 4. Score & rank by riskScore\n// 5. Greedy allocation with cascading prune levels\n// 6. Validate policies\n// 7. Calculate coverage score\n// 8. Hash for reproducibility\n\nexport interface SelectionInput {\n task: string;\n analysis: ProjectAnalysis;\n budget: number;\n policies?: PolicySet;\n depth?: number;\n}\n\nexport async function selectContext(input: SelectionInput): Promise<ContextSelection> {\n const { task, analysis, budget, policies, depth = 2 } = input;\n const decisions: SelectionDecision[] = [];\n\n // 1. Identify target files from task description\n const targetPaths = identifyTargetFiles(task, analysis.files);\n if (targetPaths.length > 0) {\n decisions.push({\n file: targetPaths.join(', '),\n action: 'include-full',\n reason: `Target file(s) identified from task description`,\n });\n }\n\n // 2. Expand via dependency graph (O(V+E) using adjacency list)\n const adj = buildAdjacencyList(analysis.graph.edges);\n const expandedPaths = targetPaths.length > 0\n ? Array.from(bfsBidirectional(targetPaths, adj, depth))\n : [];\n const expansionCount = expandedPaths.length - targetPaths.length;\n if (expansionCount > 0) {\n decisions.push({\n file: `${expansionCount} dependencies`,\n action: 'include-full',\n reason: `Expanded ${targetPaths.length} target(s) to ${expandedPaths.length} files via dependency graph (depth ${depth})`,\n });\n }\n\n // 2b. Add type providers of expanded files as candidates.\n // This aligns with coverage.ts which counts type providers as \"relevant\".\n // Without this, coverage would flag missing critical type files that the\n // selector never considered as candidates — a consistency bug.\n const allFileMap = new Map(analysis.files.map((f) => [f.relativePath, f]));\n if (targetPaths.length > 0) {\n for (const path of expandedPaths) {\n const file = allFileMap.get(path);\n if (!file) continue;\n for (const imp of file.imports) {\n const impFile = allFileMap.get(imp);\n if (impFile && impFile.kind === 'type') {\n expandedPaths.push(imp);\n }\n }\n }\n }\n\n // 3. Apply policies\n const { mustInclude, mustExclude } = applyPolicies(analysis.files, policies);\n\n // Merge: targets + expanded + must-include → candidate set\n const candidateSet = new Set([...expandedPaths, ...mustInclude]);\n\n // If no targets identified, use all files (filtered by exclude)\n if (targetPaths.length === 0) {\n for (const f of analysis.files) {\n candidateSet.add(f.relativePath);\n }\n }\n\n // Remove must-exclude\n for (const ex of mustExclude) {\n candidateSet.delete(ex);\n decisions.push({\n file: ex,\n action: 'exclude',\n reason: 'Excluded by policy',\n });\n }\n\n // 3b. secret-block: scan candidate files for secrets and exclude them\n const hasSecretBlock = policies?.rules.some(\n (r) => r.type === 'secret-block' && r.enabled,\n );\n if (hasSecretBlock) {\n for (const path of Array.from(candidateSet)) {\n const file = allFileMap.get(path);\n if (!file) continue;\n const findings = await scanFileForSecrets(\n file.path,\n analysis.projectPath,\n );\n if (findings.length > 0) {\n candidateSet.delete(path);\n decisions.push({\n file: path,\n action: 'exclude',\n reason: `Blocked: ${findings.length} secret(s) detected (${findings.map((f) => f.type).join(', ')})`,\n });\n }\n }\n }\n\n // 4. Sort candidates by riskScore descending\n const candidates = Array.from(candidateSet)\n .map((p) => allFileMap.get(p))\n .filter((f): f is AnalyzedFile => f !== undefined)\n .sort((a, b) => {\n // Targets always first\n const aIsTarget = targetPaths.includes(a.relativePath) ? 0 : 1;\n const bIsTarget = targetPaths.includes(b.relativePath) ? 0 : 1;\n if (aIsTarget !== bIsTarget) return aIsTarget - bIsTarget;\n\n // Then must-include\n const aIsMust = mustInclude.has(a.relativePath) ? 0 : 1;\n const bIsMust = mustInclude.has(b.relativePath) ? 0 : 1;\n if (aIsMust !== bIsMust) return aIsMust - bIsMust;\n\n // Then by riskScore\n return b.riskScore - a.riskScore;\n });\n\n // 5. Greedy allocation with cascading prune levels\n const selectedFiles: SelectedFile[] = [];\n let usedTokens = 0;\n\n for (const file of candidates) {\n const isTarget = targetPaths.includes(file.relativePath);\n const isMustInclude = mustInclude.has(file.relativePath);\n const defaultLevel = isTarget ? 'full' : getPruneLevelForRisk(file.riskScore);\n const levels = getCascadeLevels(defaultLevel);\n\n let included = false;\n\n for (const level of levels) {\n if (level === 'excluded') break;\n\n let tokens: number;\n if (level === 'full') {\n tokens = file.tokens;\n } else {\n const pruned = await pruneFile(file, level);\n tokens = pruned.prunedTokens;\n }\n\n if (usedTokens + tokens <= budget) {\n usedTokens += tokens;\n selectedFiles.push({\n relativePath: file.relativePath,\n tokens,\n originalTokens: file.tokens,\n pruneLevel: level,\n riskScore: file.riskScore,\n reason: buildReason(file, level, isTarget, isMustInclude),\n });\n\n if (level !== defaultLevel) {\n decisions.push({\n file: file.relativePath,\n action: `include-${level}` as SelectionDecision['action'],\n reason: `Downgraded from ${defaultLevel} to ${level} due to budget constraint`,\n alternatives: `Would need ${file.tokens - tokens} more tokens for ${defaultLevel}`,\n });\n }\n\n included = true;\n break;\n }\n }\n\n if (!included) {\n decisions.push({\n file: file.relativePath,\n action: 'exclude',\n reason: `Budget exhausted (risk: ${file.riskScore}, needs ${file.tokens} tokens)`,\n });\n }\n }\n\n // 6. Calculate coverage\n const includedPaths = selectedFiles.map((f) => f.relativePath);\n const coverage = calculateCoverage(\n targetPaths,\n includedPaths,\n analysis.files,\n analysis.graph,\n depth,\n );\n\n // 7. Calculate overall risk of the selection (lower = better)\n const includedSet = new Set(includedPaths);\n const excludedFiles = analysis.files.filter(\n (f) => !includedSet.has(f.relativePath),\n );\n const excludedRisk = excludedFiles.length > 0\n ? Math.round(excludedFiles.reduce((s, f) => s + f.riskScore, 0) / excludedFiles.length)\n : 0;\n\n // 8. Hash for determinism\n const hashInput = selectedFiles\n .map((f) => `${f.relativePath}:${f.pruneLevel}`)\n .sort()\n .join('|') + `|budget:${budget}`;\n const hash = createHash('sha256').update(hashInput).digest('hex').substring(0, 16);\n\n return {\n files: selectedFiles,\n totalTokens: usedTokens,\n budget,\n usedPercent: budget > 0 ? Math.round((usedTokens / budget) * 100 * 10) / 10 : 0,\n coverage,\n riskScore: excludedRisk,\n deterministic: true,\n hash,\n decisions,\n };\n}\n\n// ===== TARGET IDENTIFICATION =====\n\nfunction identifyTargetFiles(task: string, files: AnalyzedFile[]): string[] {\n const targets: string[] = [];\n\n // Extract file paths mentioned in the task\n // Matches patterns like: src/foo/bar.ts, ./utils.js, components/Header.tsx\n const pathPattern = /(?:^|\\s|[\"'`])([.\\w/-]+\\.[a-zA-Z]{1,4})(?:\\s|$|[\"'`]|,|:)/g;\n let match: RegExpExecArray | null;\n\n while ((match = pathPattern.exec(task)) !== null) {\n const candidate = match[1];\n // Find matching file\n const found = files.find(\n (f) => f.relativePath === candidate || f.relativePath.endsWith(candidate),\n );\n if (found && !targets.includes(found.relativePath)) {\n targets.push(found.relativePath);\n }\n }\n\n return targets;\n}\n\n// ===== POLICY APPLICATION =====\n\nfunction applyPolicies(\n files: AnalyzedFile[],\n policies?: PolicySet,\n): { mustInclude: Set<string>; mustExclude: Set<string> } {\n const mustInclude = new Set<string>();\n const mustExclude = new Set<string>();\n\n if (!policies) return { mustInclude, mustExclude };\n\n for (const rule of policies.rules) {\n if (!rule.enabled) continue;\n\n if (rule.type === 'include-always' && rule.pattern) {\n for (const file of files) {\n if (matchGlob(file.relativePath, rule.pattern)) {\n mustInclude.add(file.relativePath);\n }\n }\n }\n\n if (rule.type === 'exclude-always' && rule.pattern) {\n for (const file of files) {\n if (matchGlob(file.relativePath, rule.pattern)) {\n mustExclude.add(file.relativePath);\n }\n }\n }\n\n // secret-block is handled separately in applyPoliciesAsync\n // because it requires file I/O (scanning file contents)\n }\n\n return { mustInclude, mustExclude };\n}\n\n// ===== HELPERS =====\n\nfunction getCascadeLevels(startLevel: PruneLevel): PruneLevel[] {\n const all: PruneLevel[] = ['full', 'signatures', 'skeleton', 'excluded'];\n const startIdx = all.indexOf(startLevel);\n return all.slice(startIdx);\n}\n\nfunction buildReason(\n file: AnalyzedFile,\n level: PruneLevel,\n isTarget: boolean,\n isMustInclude: boolean,\n): string {\n if (isTarget) return 'Target file';\n if (isMustInclude) return 'Required by policy';\n\n const impact = file.exclusionImpact;\n const levelStr = level === 'full' ? 'full content' : level;\n\n if (impact === 'critical') return `Critical dependency (risk ${file.riskScore}) — ${levelStr}`;\n if (impact === 'high') return `High-risk dependency (risk ${file.riskScore}) — ${levelStr}`;\n if (impact === 'medium') return `Medium relevance (risk ${file.riskScore}) — ${levelStr}`;\n return `Low relevance (risk ${file.riskScore}) — ${levelStr}`;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, relative } from 'node:path';\nimport type { SecretFinding, SecretType } from '../types/govern.js';\n\n// ===== SECRET DETECTION ENGINE =====\n\ninterface SecretPattern {\n type: SecretType;\n pattern: RegExp;\n severity: SecretFinding['severity'];\n description: string;\n}\n\nconst BUILTIN_PATTERNS: { type: SecretType; source: string; flags: string; severity: SecretFinding['severity']; description: string }[] = [\n // API Keys\n { type: 'api-key', source: '(?:api[_-]?key|apikey)\\\\s*[:=]\\\\s*[\\'\"]?([a-zA-Z0-9_\\\\-]{20,})[\\'\"]?', flags: 'gi', severity: 'critical', description: 'API Key' },\n { type: 'api-key', source: 'sk-[a-zA-Z0-9]{20,}', flags: 'g', severity: 'critical', description: 'OpenAI/Anthropic API Key' },\n { type: 'api-key', source: 'sk-ant-[a-zA-Z0-9\\\\-]{20,}', flags: 'g', severity: 'critical', description: 'Anthropic API Key' },\n\n // AWS\n { type: 'aws-key', source: 'AKIA[0-9A-Z]{16}', flags: 'g', severity: 'critical', description: 'AWS Access Key ID' },\n { type: 'aws-key', source: '(?:aws_secret_access_key|aws_secret)\\\\s*[:=]\\\\s*[\\'\"]?([a-zA-Z0-9/+=]{40})[\\'\"]?', flags: 'gi', severity: 'critical', description: 'AWS Secret Key' },\n\n // Private Keys\n { type: 'private-key', source: '-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----', flags: 'g', severity: 'critical', description: 'Private Key' },\n { type: 'private-key', source: '-----BEGIN OPENSSH PRIVATE KEY-----', flags: 'g', severity: 'critical', description: 'SSH Private Key' },\n\n // Passwords\n { type: 'password', source: '(?:password|passwd|pwd)\\\\s*[:=]\\\\s*[\\'\"]([^\\'\"]{8,})[\\'\"](?!\\\\s*\\\\{)', flags: 'gi', severity: 'high', description: 'Hardcoded Password' },\n { type: 'password', source: '(?:DB_PASSWORD|DATABASE_PASSWORD|MYSQL_PASSWORD|POSTGRES_PASSWORD)\\\\s*[:=]\\\\s*[\\'\"]?([^\\'\"{}\\\\s]{4,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Database Password' },\n\n // Tokens\n { type: 'token', source: '(?:bearer|token|auth_token|access_token|refresh_token)\\\\s*[:=]\\\\s*[\\'\"]([a-zA-Z0-9_\\\\-.]{20,})[\\'\"](?!\\\\s*\\\\{)', flags: 'gi', severity: 'high', description: 'Auth Token' },\n { type: 'token', source: 'ghp_[a-zA-Z0-9]{36}', flags: 'g', severity: 'critical', description: 'GitHub Personal Access Token' },\n { type: 'token', source: 'gho_[a-zA-Z0-9]{36}', flags: 'g', severity: 'critical', description: 'GitHub OAuth Token' },\n { type: 'token', source: 'glpat-[a-zA-Z0-9\\\\-]{20,}', flags: 'g', severity: 'critical', description: 'GitLab Personal Access Token' },\n { type: 'token', source: 'npm_[a-zA-Z0-9]{36}', flags: 'g', severity: 'high', description: 'npm Token' },\n\n // Connection strings\n { type: 'connection-string', source: '(?:mongodb(?:\\\\+srv)?|postgres(?:ql)?|mysql|redis|amqp):\\\\/\\\\/[^\\\\s\\'\"]+:[^\\\\s\\'\"]+@[^\\\\s\\'\"]+', flags: 'gi', severity: 'critical', description: 'Database Connection String' },\n { type: 'connection-string', source: '(?:DATABASE_URL|REDIS_URL|MONGODB_URI)\\\\s*[:=]\\\\s*[\\'\"]?([^\\\\s\\'\"]{10,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Database URL' },\n\n // Environment variables with secrets\n { type: 'env-variable', source: '(?:SECRET|PRIVATE|ENCRYPTION)[_-]?(?:KEY|TOKEN|PASS)\\\\s*[:=]\\\\s*[\\'\"]?([^\\\\s\\'\"]{8,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Secret Environment Variable' },\n];\n\nfunction buildPatterns(customPatterns: string[] = []): SecretPattern[] {\n const patterns: SecretPattern[] = BUILTIN_PATTERNS.map((def) => ({\n type: def.type,\n pattern: new RegExp(def.source, def.flags),\n severity: def.severity,\n description: def.description,\n }));\n\n for (const custom of customPatterns) {\n try {\n patterns.push({\n type: 'custom',\n pattern: new RegExp(custom, 'gi'),\n severity: 'medium',\n description: `Custom pattern: ${custom}`,\n });\n } catch { /* skip invalid regex */ }\n }\n\n return patterns;\n}\n\nexport function scanContentForSecrets(\n content: string,\n filePath: string,\n customPatterns: string[] = [],\n): SecretFinding[] {\n const findings: SecretFinding[] = [];\n const lines = content.split('\\n');\n const allPatterns = buildPatterns(customPatterns);\n\n for (const secretPattern of allPatterns) {\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n secretPattern.pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = secretPattern.pattern.exec(line)) !== null) {\n const matchText = match[0];\n if (isTemplateOrPlaceholder(matchText)) continue;\n\n findings.push({\n type: secretPattern.type,\n file: filePath,\n line: i + 1,\n match: matchText,\n redacted: redactSecret(matchText),\n severity: secretPattern.severity,\n });\n }\n }\n }\n\n return deduplicateFindings(findings);\n}\n\nexport async function scanFileForSecrets(\n filePath: string,\n projectPath: string,\n customPatterns: string[] = [],\n): Promise<SecretFinding[]> {\n try {\n const content = await readFile(filePath, 'utf-8');\n const relPath = relative(resolve(projectPath), resolve(filePath));\n return scanContentForSecrets(content, relPath, customPatterns);\n } catch {\n return [];\n }\n}\n\nexport async function scanProjectForSecrets(\n projectPath: string,\n filePaths: string[],\n customPatterns: string[] = [],\n): Promise<SecretFinding[]> {\n const allFindings: SecretFinding[] = [];\n\n for (const fp of filePaths) {\n const findings = await scanFileForSecrets(fp, projectPath, customPatterns);\n allFindings.push(...findings);\n }\n\n return allFindings.sort((a, b) => {\n const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };\n return severityOrder[a.severity] - severityOrder[b.severity];\n });\n}\n\nexport function sanitizeContent(content: string, customPatterns: string[] = []): string {\n let sanitized = content;\n const allPatterns = buildPatterns(customPatterns);\n\n for (const secretPattern of allPatterns) {\n sanitized = sanitized.replace(secretPattern.pattern, (match) => {\n if (isTemplateOrPlaceholder(match)) return match;\n return redactSecret(match);\n });\n }\n\n return sanitized;\n}\n\nfunction redactSecret(value: string): string {\n if (value.length <= 8) return '***REDACTED***';\n const prefix = value.substring(0, 4);\n const suffix = value.substring(value.length - 2);\n return `${prefix}${'*'.repeat(Math.min(value.length - 6, 20))}${suffix}`;\n}\n\nfunction isTemplateOrPlaceholder(value: string): boolean {\n const placeholders = [\n /\\$\\{.*\\}/, /\\{\\{.*\\}\\}/, /%[sd]/, /<[A-Z_]+>/, /YOUR_.*_HERE/i,\n /\\bCHANGE_ME\\b/i, /\\bPLACEHOLDER\\b/i, /\\bexample\\b/i, /\\bTODO\\b/i, /xxx+/i,\n /\\breplace.?me\\b/i, /\\bdummy\\b/i, /\\btest_?key\\b/i, /\\bsample\\b/i,\n ];\n return placeholders.some((p) => p.test(value));\n}\n\nfunction deduplicateFindings(findings: SecretFinding[]): SecretFinding[] {\n const seen = new Set<string>();\n return findings.filter((f) => {\n const key = `${f.file}:${f.line}:${f.type}:${f.match}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n","import { Project, SyntaxKind, type SourceFile } from 'ts-morph';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { AnalyzedFile, PruneLevel, PrunedContent } from '../types/engine.js';\nimport { countTokensChars4 } from './tokenizer.js';\n\nconst TS_EXTENSIONS = new Set(['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs']);\n\n// ===== PUBLIC API =====\n\nexport async function pruneFile(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n if (level === 'excluded') {\n return emptyResult(file, 'excluded');\n }\n\n if (level === 'full') {\n return fullContent(file);\n }\n\n const ext = file.extension.toLowerCase();\n const isTS = TS_EXTENSIONS.has(ext);\n\n if (isTS) {\n return pruneTypeScript(file, level);\n }\n\n return pruneGeneric(file, level);\n}\n\nexport async function pruneFiles(\n files: AnalyzedFile[],\n levelFn: (file: AnalyzedFile) => PruneLevel,\n): Promise<PrunedContent[]> {\n const results: PrunedContent[] = [];\n\n for (const file of files) {\n const level = levelFn(file);\n const pruned = await pruneFile(file, level);\n results.push(pruned);\n }\n\n return results;\n}\n\n// ===== TYPESCRIPT AST-BASED PRUNING =====\n\nasync function pruneTypeScript(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n let content: string;\n try {\n content = await readFile(file.path, 'utf-8');\n } catch {\n return emptyResult(file, level);\n }\n\n let project: Project;\n try {\n const tsConfigPath = findTsConfig(file.path);\n project = new Project({\n tsConfigFilePath: tsConfigPath,\n skipAddingFilesFromTsConfig: true,\n compilerOptions: tsConfigPath\n ? undefined\n : { allowJs: true, esModuleInterop: true },\n });\n project.createSourceFile(file.path, content, { overwrite: true });\n } catch {\n // Fallback to generic pruning if AST fails\n return pruneGenericFromContent(file, content, level);\n }\n\n const sourceFile = project.getSourceFiles()[0];\n if (!sourceFile) {\n return pruneGenericFromContent(file, content, level);\n }\n\n const prunedContent = level === 'signatures'\n ? extractSignaturesAST(sourceFile)\n : extractSkeletonAST(sourceFile);\n\n const prunedTokens = countTokensChars4(Buffer.byteLength(prunedContent, 'utf-8'));\n const savingsPercent = file.tokens > 0 ? ((file.tokens - prunedTokens) / file.tokens) * 100 : 0;\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens,\n pruneLevel: level,\n content: prunedContent,\n savingsPercent: Math.max(0, savingsPercent),\n };\n}\n\n// ===== SIGNATURES: Keep imports, type defs, function signatures, class outlines =====\n\nfunction extractSignaturesAST(sf: SourceFile): string {\n const parts: string[] = [];\n\n // Imports\n for (const imp of sf.getImportDeclarations()) {\n parts.push(imp.getText());\n }\n\n if (parts.length > 0) parts.push('');\n\n // Type aliases\n for (const ta of sf.getTypeAliases()) {\n addJSDoc(ta, parts);\n parts.push(ta.getText());\n }\n\n // Interfaces\n for (const iface of sf.getInterfaces()) {\n addJSDoc(iface, parts);\n parts.push(iface.getText());\n }\n\n // Enums\n for (const en of sf.getEnums()) {\n addJSDoc(en, parts);\n parts.push(en.getText());\n }\n\n // Function declarations — signature only\n for (const fn of sf.getFunctions()) {\n addJSDoc(fn, parts);\n const isExported = fn.isExported();\n const isAsync = fn.isAsync();\n const name = fn.getName() ?? '<anonymous>';\n const params = fn.getParameters().map((p) => p.getText()).join(', ');\n const returnType = fn.getReturnTypeNode()?.getText();\n const returnStr = returnType ? `: ${returnType}` : '';\n\n const prefix = isExported ? 'export ' : '';\n const asyncStr = isAsync ? 'async ' : '';\n parts.push(`${prefix}${asyncStr}function ${name}(${params})${returnStr} { /* ... */ }`);\n }\n\n // Variable declarations (const/let with arrow functions)\n for (const stmt of sf.getVariableStatements()) {\n for (const decl of stmt.getDeclarations()) {\n const init = decl.getInitializer();\n if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n addJSDoc(stmt, parts);\n const isExported = stmt.isExported();\n const prefix = isExported ? 'export ' : '';\n const kind = stmt.getDeclarationKind();\n const name = decl.getName();\n const typeNode = decl.getTypeNode()?.getText();\n const typeStr = typeNode ? `: ${typeNode}` : '';\n parts.push(`${prefix}${kind} ${name}${typeStr} = /* ... */;`);\n } else {\n // Non-function variables: keep full declaration\n addJSDoc(stmt, parts);\n parts.push(stmt.getText());\n }\n }\n }\n\n // Classes — outline with method signatures\n for (const cls of sf.getClasses()) {\n addJSDoc(cls, parts);\n const isExported = cls.isExported();\n const prefix = isExported ? 'export ' : '';\n const name = cls.getName() ?? '<anonymous>';\n const ext = cls.getExtends()?.getText();\n const impl = cls.getImplements().map((i) => i.getText()).join(', ');\n let header = `${prefix}class ${name}`;\n if (ext) header += ` extends ${ext}`;\n if (impl) header += ` implements ${impl}`;\n header += ' {';\n parts.push(header);\n\n // Properties\n for (const prop of cls.getProperties()) {\n parts.push(` ${prop.getText()}`);\n }\n\n // Constructor\n const ctor = cls.getConstructors()[0];\n if (ctor) {\n const ctorParams = ctor.getParameters().map((p) => p.getText()).join(', ');\n parts.push(` constructor(${ctorParams}) { /* ... */ }`);\n }\n\n // Methods — signature only\n for (const method of cls.getMethods()) {\n const isStatic = method.isStatic();\n const isAsync = method.isAsync();\n const methodName = method.getName();\n const methodParams = method.getParameters().map((p) => p.getText()).join(', ');\n const returnType = method.getReturnTypeNode()?.getText();\n const returnStr = returnType ? `: ${returnType}` : '';\n const staticStr = isStatic ? 'static ' : '';\n const asyncStr = isAsync ? 'async ' : '';\n parts.push(` ${staticStr}${asyncStr}${methodName}(${methodParams})${returnStr} { /* ... */ }`);\n }\n\n parts.push('}');\n }\n\n // Re-exports\n for (const exp of sf.getExportDeclarations()) {\n parts.push(exp.getText());\n }\n\n // Export assignments\n for (const exp of sf.getExportAssignments()) {\n parts.push(exp.getText());\n }\n\n return parts.join('\\n');\n}\n\n// ===== SKELETON: Keep only declarations, no bodies at all =====\n\nfunction extractSkeletonAST(sf: SourceFile): string {\n const parts: string[] = [];\n\n // Imports\n for (const imp of sf.getImportDeclarations()) {\n parts.push(imp.getText());\n }\n\n if (parts.length > 0) parts.push('');\n\n // Type aliases — full\n for (const ta of sf.getTypeAliases()) {\n if (ta.isExported()) parts.push(ta.getText());\n }\n\n // Interfaces — name + extends only\n for (const iface of sf.getInterfaces()) {\n if (!iface.isExported()) continue;\n const ext = iface.getExtends().map((e) => e.getText());\n const extStr = ext.length > 0 ? ` extends ${ext.join(', ')}` : '';\n parts.push(`export interface ${iface.getName()}${extStr} { /* ${iface.getProperties().length} props */ }`);\n }\n\n // Enums — name only\n for (const en of sf.getEnums()) {\n if (!en.isExported()) continue;\n const members = en.getMembers().map((m) => m.getName());\n parts.push(`export enum ${en.getName()} { ${members.join(', ')} }`);\n }\n\n // Functions — name + params only\n for (const fn of sf.getFunctions()) {\n if (!fn.isExported()) continue;\n const name = fn.getName() ?? '<anonymous>';\n const params = fn.getParameters().map((p) => p.getText()).join(', ');\n parts.push(`export function ${name}(${params});`);\n }\n\n // Classes — name + method names only\n for (const cls of sf.getClasses()) {\n if (!cls.isExported()) continue;\n const methods = cls.getMethods().map((m) => m.getName());\n parts.push(`export class ${cls.getName()} { /* methods: ${methods.join(', ')} */ }`);\n }\n\n // Re-exports\n for (const exp of sf.getExportDeclarations()) {\n parts.push(exp.getText());\n }\n\n return parts.join('\\n');\n}\n\n// ===== GENERIC PRUNING (non-TS files) =====\n\nasync function pruneGeneric(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n let content: string;\n try {\n content = await readFile(file.path, 'utf-8');\n } catch {\n return emptyResult(file, level);\n }\n\n return pruneGenericFromContent(file, content, level);\n}\n\nfunction pruneGenericFromContent(\n file: AnalyzedFile,\n content: string,\n level: PruneLevel,\n): PrunedContent {\n const lines = content.split('\\n');\n let result: string[];\n\n if (level === 'signatures') {\n result = lines.filter((line) => {\n const t = line.trim();\n return (\n t === '' ||\n t.startsWith('#') ||\n t.startsWith('//') ||\n t.startsWith('import ') ||\n t.startsWith('from ') ||\n t.startsWith('export ') ||\n t.startsWith('def ') ||\n t.startsWith('async def ') ||\n t.startsWith('class ') ||\n t.startsWith('function ') ||\n t.startsWith('const ') ||\n t.startsWith('let ') ||\n t.startsWith('var ') ||\n /^(pub |fn |struct |enum |impl |mod |use )/.test(t)\n );\n });\n } else {\n // skeleton: even more aggressive — only declarations\n result = lines.filter((line) => {\n const t = line.trim();\n return (\n t.startsWith('import ') ||\n t.startsWith('from ') ||\n t.startsWith('export ') ||\n t.startsWith('def ') ||\n t.startsWith('class ') ||\n t.startsWith('function ') ||\n /^(pub |fn |struct |enum |mod |use )/.test(t)\n );\n });\n }\n\n const prunedContent = result.join('\\n');\n const prunedTokens = countTokensChars4(Buffer.byteLength(prunedContent, 'utf-8'));\n const savingsPercent = file.tokens > 0 ? ((file.tokens - prunedTokens) / file.tokens) * 100 : 0;\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens,\n pruneLevel: level,\n content: prunedContent,\n savingsPercent: Math.max(0, savingsPercent),\n };\n}\n\n// ===== HELPERS =====\n\nasync function fullContent(file: AnalyzedFile): Promise<PrunedContent> {\n let content = '';\n try {\n content = await readFile(file.path, 'utf-8');\n } catch { /* empty */ }\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens: file.tokens,\n pruneLevel: 'full',\n content,\n savingsPercent: 0,\n };\n}\n\nfunction emptyResult(file: AnalyzedFile, level: PruneLevel): PrunedContent {\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens: 0,\n pruneLevel: level,\n content: '',\n savingsPercent: 100,\n };\n}\n\nfunction addJSDoc(node: { getJsDocs?: () => { getText(): string }[] }, parts: string[]): void {\n if (!node.getJsDocs) return;\n const docs = node.getJsDocs();\n if (docs.length > 0) {\n parts.push(docs[0].getText());\n }\n}\n\nfunction findTsConfig(filePath: string): string | undefined {\n let dir = filePath;\n for (let i = 0; i < 10; i++) {\n dir = join(dir, '..');\n const candidate = join(dir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n","import type {\n AnalyzedFile,\n ProjectGraph,\n CoverageResult,\n} from '../types/engine.js';\nimport { buildAdjacencyList, bfsBidirectional } from './graph-utils.js';\n\n// ===== CONTEXT COVERAGE SCORING =====\n//\n// Given a set of included files and a task's target files, calculate\n// how much of the \"relevant universe\" is covered.\n//\n// coverageScore = |includedRelevant| / |relevantFiles| × 100\n//\n// \"Relevant\" = target files + their dependencies (up to `depth` levels)\n// + type providers used by included files.\n\nexport function calculateCoverage(\n targetPaths: string[],\n includedPaths: string[],\n allFiles: AnalyzedFile[],\n graph: ProjectGraph,\n depth: number = 2,\n): CoverageResult {\n // 1. Find all relevant files: targets + their dependency cone\n // Uses adjacency list for O(V+E) BFS instead of scanning all edges per node.\n const adj = buildAdjacencyList(graph.edges);\n const relevantSet = targetPaths.length > 0\n ? bfsBidirectional(targetPaths, adj, depth)\n : new Set<string>();\n const includedSet = new Set(includedPaths);\n\n // Also add type providers used by included files\n const tempFileMap = new Map(allFiles.map((f) => [f.relativePath, f]));\n for (const path of includedPaths) {\n const file = tempFileMap.get(path);\n if (!file) continue;\n\n for (const imp of file.imports) {\n const impFile = tempFileMap.get(imp);\n if (impFile && impFile.kind === 'type') {\n relevantSet.add(imp);\n }\n }\n }\n\n // 2. Calculate coverage\n const relevantFiles = Array.from(relevantSet);\n const includedRelevant = relevantFiles.filter((f) => includedSet.has(f));\n const missingRelevant = relevantFiles.filter((f) => !includedSet.has(f));\n\n // Missing critical = missing files with critical/high exclusion impact\n const missingCritical = missingRelevant.filter((f) => {\n const file = tempFileMap.get(f);\n return file && (file.exclusionImpact === 'critical' || file.exclusionImpact === 'high');\n });\n\n // Risk-weighted coverage: missing a high-risk file hurts more than missing a low-risk one.\n // score = Σ(riskScore of included relevant) / Σ(riskScore of all relevant) × 100\n // Falls back to count-based if no risk data is available.\n const fileMap = new Map(allFiles.map((f) => [f.relativePath, f]));\n let totalRelevantRisk = 0;\n let includedRelevantRisk = 0;\n\n for (const f of relevantFiles) {\n const risk = fileMap.get(f)?.riskScore ?? 1;\n totalRelevantRisk += risk;\n if (includedSet.has(f)) {\n includedRelevantRisk += risk;\n }\n }\n\n const score = totalRelevantRisk > 0\n ? Math.round((includedRelevantRisk / totalRelevantRisk) * 100)\n : relevantFiles.length > 0\n ? Math.round((includedRelevant.length / relevantFiles.length) * 100)\n : 100;\n\n // Build explanation\n let explanation: string;\n if (score >= 90) {\n explanation = `Excellent coverage (${score}%): AI has nearly all relevant context.`;\n } else if (score >= 70) {\n explanation = `Good coverage (${score}%): Most relevant files included.`;\n if (missingCritical.length > 0) {\n explanation += ` Warning: ${missingCritical.length} critical file(s) missing.`;\n }\n } else if (score >= 50) {\n explanation = `Partial coverage (${score}%): Significant context is missing.`;\n if (missingCritical.length > 0) {\n explanation += ` ${missingCritical.length} critical file(s) not included — AI quality will degrade.`;\n }\n } else {\n explanation = `Low coverage (${score}%): Most relevant files are excluded. AI response quality will be poor.`;\n }\n\n return {\n score,\n relevantFiles,\n includedRelevant,\n missingRelevant,\n missingCritical,\n explanation,\n };\n}\n","import type { AnalyzedFile, BudgetPlan, BudgetEntry, PruneLevel } from '../types/engine.js';\nimport { pruneFile } from './pruner.js';\n\n// ===== BUDGET OPTIMIZER =====\n//\n// Greedy knapsack with cascading prune levels.\n// Files are sorted by riskScore (descending) — highest risk first.\n// Each file is tried at progressively smaller prune levels until it fits.\n\nexport function getPruneLevelForRisk(riskScore: number): PruneLevel {\n if (riskScore >= 80) return 'full'; // critical — include everything, no cascading\n if (riskScore >= 60) return 'full'; // high — try full first, can cascade\n if (riskScore >= 30) return 'signatures'; // medium — signatures by default\n return 'skeleton'; // low — skeleton\n}\n\nexport function isCriticalRisk(riskScore: number): boolean {\n return riskScore >= 80;\n}\n\nexport async function optimizeBudget(\n files: AnalyzedFile[],\n budget: number,\n): Promise<BudgetPlan> {\n const entries: BudgetEntry[] = [];\n let used = 0;\n\n // Sort by riskScore descending — most important files first\n const sorted = [...files].sort((a, b) => b.riskScore - a.riskScore);\n\n for (const file of sorted) {\n const defaultLevel = getPruneLevelForRisk(file.riskScore);\n\n // Try cascading prune levels: full → signatures → skeleton → excluded\n const levelsToTry = getCascadeLevels(defaultLevel);\n\n let included = false;\n\n for (const level of levelsToTry) {\n if (level === 'excluded') break;\n\n if (level === 'full') {\n if (used + file.tokens <= budget) {\n used += file.tokens;\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: file.tokens,\n pruneLevel: 'full',\n included: true,\n reason: `Risk ${file.riskScore} — included in full`,\n });\n included = true;\n break;\n }\n } else {\n const pruned = await pruneFile(file, level);\n if (pruned.prunedTokens > 0 && used + pruned.prunedTokens <= budget) {\n used += pruned.prunedTokens;\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: pruned.prunedTokens,\n pruneLevel: level,\n included: true,\n reason: `Risk ${file.riskScore} — pruned to ${level} (budget constraint)`,\n });\n included = true;\n break;\n }\n }\n }\n\n if (!included) {\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: 0,\n pruneLevel: 'excluded',\n included: false,\n reason: `Risk ${file.riskScore} — excluded (budget exhausted, ${file.tokens} tokens)`,\n });\n }\n }\n\n return {\n budget,\n used,\n remaining: budget - used,\n fillPercent: budget > 0 ? Math.round((used / budget) * 100 * 10) / 10 : 0,\n files: entries,\n };\n}\n\n// ===== HELPERS =====\n\nfunction getCascadeLevels(startLevel: PruneLevel): PruneLevel[] {\n const all: PruneLevel[] = ['full', 'signatures', 'skeleton', 'excluded'];\n const startIdx = all.indexOf(startLevel);\n return all.slice(startIdx);\n}\n","import type { TaskType, ModelChoice, ModelSpec, ModelId } from '../types/interact.js';\nimport type { ProjectAnalysis } from '../types/engine.js';\n\n// ===== MODEL REGISTRY =====\n\nexport const MODEL_REGISTRY: ModelSpec[] = [\n {\n id: 'claude-haiku-3.5',\n name: 'Claude 3.5 Haiku',\n tier: 'fast',\n pricing: { inputPerMillion: 0.80, outputPerMillion: 4.00, cacheReadPerMillion: 0.08 },\n contextWindow: 200_000,\n strengths: ['speed', 'simple-tasks', 'low-cost'],\n },\n {\n id: 'claude-sonnet-4',\n name: 'Claude Sonnet 4',\n tier: 'balanced',\n pricing: { inputPerMillion: 3.00, outputPerMillion: 15.00, cacheReadPerMillion: 0.30 },\n contextWindow: 200_000,\n strengths: ['code-generation', 'refactoring', 'balanced-reasoning'],\n },\n {\n id: 'claude-opus-4',\n name: 'Claude Opus 4',\n tier: 'reasoning',\n pricing: { inputPerMillion: 15.00, outputPerMillion: 75.00, cacheReadPerMillion: 1.50 },\n contextWindow: 200_000,\n strengths: ['deep-reasoning', 'architecture', 'complex-debugging'],\n },\n];\n\n// ===== ROUTING RULES =====\n\ninterface RoutingRule {\n task: TaskType;\n defaultModel: ModelId;\n upgradeIf: (analysis: ProjectAnalysis) => boolean;\n upgradeTo: ModelId;\n reason: string;\n upgradeReason: string;\n}\n\nconst ROUTING_RULES: RoutingRule[] = [\n {\n task: 'simple-edit',\n defaultModel: 'claude-haiku-3.5',\n upgradeIf: () => false,\n upgradeTo: 'claude-haiku-3.5',\n reason: 'Simple edits are best handled by fast models',\n upgradeReason: '',\n },\n {\n task: 'docs',\n defaultModel: 'claude-haiku-3.5',\n upgradeIf: (a) => a.totalTokens > 100_000,\n upgradeTo: 'claude-sonnet-4',\n reason: 'Documentation tasks are straightforward',\n upgradeReason: 'Large codebase — Sonnet provides better understanding',\n },\n {\n task: 'test',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.overallComplexity > 15,\n upgradeTo: 'claude-opus-4',\n reason: 'Test generation requires good code understanding',\n upgradeReason: 'High complexity codebase — Opus for better test coverage',\n },\n {\n task: 'debug',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.distribution.critical > 5,\n upgradeTo: 'claude-opus-4',\n reason: 'Debugging requires solid reasoning about code flow',\n upgradeReason: 'Many critical files involved — Opus for deeper analysis',\n },\n {\n task: 'refactor',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.totalFiles > 50 && a.riskProfile.overallComplexity > 10,\n upgradeTo: 'claude-opus-4',\n reason: 'Refactoring needs good structural understanding',\n upgradeReason: 'Large + complex project — Opus for safer refactoring',\n },\n {\n task: 'review',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.distribution.critical > 3,\n upgradeTo: 'claude-opus-4',\n reason: 'Code review benefits from balanced reasoning',\n upgradeReason: 'Critical code under review — Opus for thorough analysis',\n },\n {\n task: 'feature',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.totalFiles > 100,\n upgradeTo: 'claude-opus-4',\n reason: 'Feature development needs code generation + understanding',\n upgradeReason: 'Large codebase — Opus for better integration',\n },\n {\n task: 'architecture',\n defaultModel: 'claude-opus-4',\n upgradeIf: () => false,\n upgradeTo: 'claude-opus-4',\n reason: 'Architecture decisions require deep reasoning',\n upgradeReason: '',\n },\n];\n\n// ===== TASK CLASSIFICATION =====\n\nconst TASK_KEYWORDS: Record<TaskType, string[]> = {\n debug: ['debug', 'fix', 'bug', 'error', 'issue', 'broken', 'crash', 'failing', 'wrong'],\n review: ['review', 'check', 'assess', 'evaluate', 'audit', 'inspect', 'critique'],\n refactor: ['refactor', 'restructure', 'reorganize', 'clean up', 'simplify', 'extract', 'move'],\n test: ['test', 'spec', 'coverage', 'unit test', 'integration test', 'e2e'],\n docs: ['document', 'docs', 'readme', 'jsdoc', 'comment', 'explain'],\n feature: ['add', 'implement', 'create', 'build', 'new', 'feature', 'endpoint'],\n architecture: ['architecture', 'design', 'system', 'structure', 'migrate', 'pattern'],\n 'simple-edit': ['rename', 'typo', 'update', 'change', 'modify', 'tweak', 'adjust'],\n};\n\nexport function classifyTask(taskDescription: string): TaskType {\n const lower = taskDescription.toLowerCase();\n\n // Score each task type by keyword matches\n let bestType: TaskType = 'simple-edit';\n let bestScore = 0;\n\n for (const [type, keywords] of Object.entries(TASK_KEYWORDS) as [TaskType, string[]][]) {\n let score = 0;\n for (const kw of keywords) {\n if (lower.includes(kw)) score++;\n }\n if (score > bestScore) {\n bestScore = score;\n bestType = type;\n }\n }\n\n return bestType;\n}\n\n// ===== MODEL ROUTING =====\n\nexport function routeModel(\n taskType: TaskType,\n analysis: ProjectAnalysis,\n preferredModel?: ModelId,\n): ModelChoice {\n // If user explicitly chose a model, respect it\n if (preferredModel) {\n const spec = MODEL_REGISTRY.find((m) => m.id === preferredModel);\n if (spec) {\n return {\n model: preferredModel,\n reason: 'User-specified model',\n confidence: 1.0,\n alternatives: buildAlternatives(preferredModel, taskType),\n };\n }\n }\n\n // Find routing rule for this task\n const rule = ROUTING_RULES.find((r) => r.task === taskType);\n if (!rule) {\n return {\n model: 'claude-sonnet-4',\n reason: 'Default model for unrecognized task type',\n confidence: 0.5,\n alternatives: buildAlternatives('claude-sonnet-4', taskType),\n };\n }\n\n // Check if upgrade is warranted\n const shouldUpgrade = rule.upgradeIf(analysis);\n const model = shouldUpgrade ? rule.upgradeTo : rule.defaultModel;\n const reason = shouldUpgrade ? rule.upgradeReason : rule.reason;\n\n return {\n model,\n reason,\n confidence: shouldUpgrade ? 0.8 : 0.9,\n alternatives: buildAlternatives(model, taskType),\n };\n}\n\n// ===== HELPERS =====\n\nfunction buildAlternatives(chosenModel: ModelId, taskType: TaskType) {\n return MODEL_REGISTRY\n .filter((m) => m.id !== chosenModel)\n .map((m) => {\n const chosen = MODEL_REGISTRY.find((r) => r.id === chosenModel)!;\n const costDelta = m.pricing.inputPerMillion - chosen.pricing.inputPerMillion;\n const tradeoff = costDelta > 0\n ? `More capable but ${(costDelta / chosen.pricing.inputPerMillion * 100).toFixed(0)}% more expensive`\n : `${Math.abs(costDelta / chosen.pricing.inputPerMillion * 100).toFixed(0)}% cheaper but less capable`;\n\n return { model: m.id, costDelta, tradeoff };\n });\n}\n\nexport function getModelSpec(modelId: ModelId): ModelSpec | undefined {\n return MODEL_REGISTRY.find((m) => m.id === modelId);\n}\n","import type { CostEstimate, ModelId } from '../types/interact.js';\nimport { getModelSpec, MODEL_REGISTRY } from './router.js';\n\n// ===== COST ESTIMATION =====\n\nexport function estimateCost(\n modelId: ModelId,\n inputTokens: number,\n totalProjectTokens: number,\n estimatedOutputRatio: number = 0.3,\n): CostEstimate {\n const spec = getModelSpec(modelId) ?? MODEL_REGISTRY[1]; // fallback to Sonnet\n const estimatedOutputTokens = Math.round(inputTokens * estimatedOutputRatio);\n\n const inputCost = (inputTokens / 1_000_000) * spec.pricing.inputPerMillion;\n const outputCost = (estimatedOutputTokens / 1_000_000) * spec.pricing.outputPerMillion;\n const totalCost = inputCost + outputCost;\n\n // Without optimization = sending all project tokens\n const woInputCost = (totalProjectTokens / 1_000_000) * spec.pricing.inputPerMillion;\n const woOutputCost = (Math.round(totalProjectTokens * estimatedOutputRatio) / 1_000_000) * spec.pricing.outputPerMillion;\n const woTotalCost = woInputCost + woOutputCost;\n\n const tokensSaved = totalProjectTokens - inputTokens;\n const costSaved = woTotalCost - totalCost;\n const savingsPercent = woTotalCost > 0 ? (costSaved / woTotalCost) * 100 : 0;\n\n return {\n model: modelId,\n inputTokens,\n estimatedOutputTokens,\n inputCost: round(inputCost),\n outputCost: round(outputCost),\n totalCost: round(totalCost),\n formatted: formatCost(totalCost),\n\n withoutOptimization: {\n inputTokens: totalProjectTokens,\n totalCost: round(woTotalCost),\n formatted: formatCost(woTotalCost),\n },\n\n savings: {\n tokensSaved: Math.max(0, tokensSaved),\n costSaved: round(Math.max(0, costSaved)),\n percent: Math.max(0, Math.round(savingsPercent)),\n formatted: costSaved > 0\n ? `saved ${formatCost(costSaved)} (${Math.round(savingsPercent)}%)`\n : 'no savings',\n },\n };\n}\n\n// ===== HELPERS =====\n\nfunction round(n: number): number {\n return Math.round(n * 1_000_000) / 1_000_000;\n}\n\nfunction formatCost(cost: number): string {\n if (cost < 0.001) return '<$0.001';\n if (cost < 0.01) return `$${cost.toFixed(4)}`;\n if (cost < 1) return `$${cost.toFixed(3)}`;\n return `$${cost.toFixed(2)}`;\n}\n","import type { StructuredPrompt, PromptSection, TaskType } from '../types/interact.js';\nimport type { ContextSelection, ProjectAnalysis } from '../types/engine.js';\nimport { countTokensChars4 } from '../engine/tokenizer.js';\n\n// ===== STRUCTURED PROMPT BUILDER =====\n//\n// Not templates. Not libraries.\n// Task-aware prompt construction with sections that can be measured and optimized.\n\nexport interface PromptOptions {\n task: string;\n taskType: TaskType;\n analysis: ProjectAnalysis;\n selection: ContextSelection;\n enableCoT?: boolean;\n enableConstraints?: boolean;\n enableAntiHallucination?: boolean;\n}\n\nexport function buildPrompt(options: PromptOptions): StructuredPrompt {\n const {\n task,\n taskType,\n analysis,\n selection,\n enableCoT = true,\n enableConstraints = true,\n enableAntiHallucination = true,\n } = options;\n\n const sections: PromptSection[] = [];\n\n // 1. System section — role priming\n sections.push(buildSystemSection(analysis.stack, taskType));\n\n // 2. Context section — project info + selected files\n sections.push(buildContextSection(analysis, selection));\n\n // 3. Task section — what the user wants\n sections.push(buildTaskSection(task, taskType));\n\n // 4. Constraints section — safety rails\n if (enableConstraints) {\n sections.push(buildConstraintsSection(analysis.stack, taskType));\n }\n\n // 5. Chain-of-thought section\n if (enableCoT) {\n sections.push(buildCoTSection(taskType));\n }\n\n // 6. Anti-hallucination section\n if (enableAntiHallucination) {\n sections.push(buildAntiHallucinationSection());\n }\n\n // 7. Output format section\n sections.push(buildFormatSection(taskType));\n\n const rendered = sections.map((s) => s.content).join('\\n\\n---\\n\\n');\n const totalTokens = sections.reduce((s, sec) => s + sec.tokens, 0);\n\n return { sections, totalTokens, rendered };\n}\n\n// ===== SECTION BUILDERS =====\n\nfunction buildSystemSection(stack: string[], taskType: TaskType): PromptSection {\n const stackStr = stack.length > 0 ? stack.join(', ') : 'software';\n const taskRole = TASK_ROLES[taskType] ?? 'engineer';\n\n const content = [\n `You are a senior ${stackStr} ${taskRole} with deep expertise in clean architecture, testing, and production-quality code.`,\n 'You prioritize correctness, readability, and maintainability.',\n 'You never make assumptions without evidence from the code.',\n ].join(' ');\n\n return makeSection('system', 'system', content);\n}\n\nfunction buildContextSection(\n analysis: ProjectAnalysis,\n selection: ContextSelection,\n): PromptSection {\n const lines: string[] = [];\n\n lines.push(`## Project: ${analysis.projectName}`);\n lines.push(`Stack: ${analysis.stack.join(', ') || 'Unknown'}`);\n lines.push(`Files analyzed: ${analysis.totalFiles} | Tokens: ~${Math.round(analysis.totalTokens / 1000)}K`);\n lines.push(`Context coverage: ${selection.coverage.score}% | Risk score: ${selection.riskScore}/100`);\n lines.push('');\n\n // List included files with their prune levels\n lines.push('### Included Files');\n lines.push('');\n\n const fullFiles = selection.files.filter((f) => f.pruneLevel === 'full');\n const sigFiles = selection.files.filter((f) => f.pruneLevel === 'signatures');\n const skelFiles = selection.files.filter((f) => f.pruneLevel === 'skeleton');\n\n if (fullFiles.length > 0) {\n lines.push('**Full content (read these first):**');\n for (const f of fullFiles) {\n lines.push(`- \\`${f.relativePath}\\` (~${Math.round(f.tokens / 1000)}K tokens) — ${f.reason}`);\n }\n lines.push('');\n }\n\n if (sigFiles.length > 0) {\n lines.push('**Signatures only (reference as needed):**');\n for (const f of sigFiles) {\n lines.push(`- \\`${f.relativePath}\\` (~${Math.round(f.tokens / 1000)}K tokens)`);\n }\n lines.push('');\n }\n\n if (skelFiles.length > 0) {\n lines.push('**Skeleton (structure overview):**');\n for (const f of skelFiles) {\n lines.push(`- \\`${f.relativePath}\\``);\n }\n lines.push('');\n }\n\n if (selection.coverage.missingCritical.length > 0) {\n lines.push('⚠️ **Missing critical files** (not included due to budget):');\n for (const f of selection.coverage.missingCritical) {\n lines.push(`- \\`${f}\\``);\n }\n lines.push('');\n }\n\n const content = lines.join('\\n');\n return makeSection('context', 'context', content);\n}\n\nfunction buildTaskSection(task: string, taskType: TaskType): PromptSection {\n const content = [\n '## Task',\n '',\n task,\n '',\n `Task type: **${taskType}**`,\n ].join('\\n');\n\n return makeSection('task', 'task', content);\n}\n\nfunction buildConstraintsSection(stack: string[], taskType: TaskType): PromptSection {\n const lines: string[] = ['## Constraints', ''];\n\n lines.push('- **Do NOT** delete or modify existing tests unless explicitly asked');\n lines.push('- **Do NOT** change function signatures that are part of the public API');\n lines.push('- **Do NOT** introduce new dependencies without mentioning it');\n lines.push('- **Always** handle errors explicitly (no silent catches)');\n lines.push('- **Always** preserve existing code style and conventions');\n lines.push('- **Prefer** minimal changes — smallest diff that solves the problem');\n\n if (stack.includes('TypeScript')) {\n lines.push('- **Always** use strict TypeScript types (no `any` unless unavoidable)');\n lines.push('- **Always** add explicit return types to exported functions');\n }\n\n if (taskType === 'refactor') {\n lines.push('- **Do NOT** change behavior — refactoring must be behavior-preserving');\n lines.push('- **Verify** all existing tests still pass after changes');\n }\n\n if (taskType === 'test') {\n lines.push('- Use AAA pattern: Arrange, Act, Assert');\n lines.push('- Test boundaries, null/undefined, async errors, type edges');\n lines.push('- Use descriptive test names: \"should [expected] when [condition]\"');\n }\n\n return makeSection('constraints', 'constraints', lines.join('\\n'));\n}\n\nfunction buildCoTSection(taskType: TaskType): PromptSection {\n const steps = COT_STEPS[taskType] ?? COT_STEPS['simple-edit'];\n\n const lines: string[] = ['## Thinking Process', '', 'Before writing any code:'];\n steps.forEach((step, i) => {\n lines.push(`${i + 1}. ${step}`);\n });\n\n return makeSection('cot', 'constraints', lines.join('\\n'));\n}\n\nfunction buildAntiHallucinationSection(): PromptSection {\n const content = [\n '## Important',\n '',\n '- Only reference files, functions, and APIs that exist in the provided context',\n '- If you are unsure about something, say so explicitly',\n '- Do NOT invent function signatures, types, or module paths',\n '- If the context is insufficient to complete the task, explain what is missing',\n ].join('\\n');\n\n return makeSection('anti-hallucination', 'constraints', content);\n}\n\nfunction buildFormatSection(taskType: TaskType): PromptSection {\n const lines: string[] = ['## Output Format', ''];\n\n if (taskType === 'review') {\n lines.push('Provide findings in priority order: Critical > Major > Minor > Nitpick');\n lines.push('For each finding: file, line, issue, and concrete suggestion with code');\n } else if (taskType === 'architecture') {\n lines.push('Present 2-3 options with trade-offs, then recommend one with justification');\n } else if (taskType === 'debug') {\n lines.push('1. Root cause analysis');\n lines.push('2. Minimal fix');\n lines.push('3. Explanation of why the fix works');\n lines.push('4. Edge cases to consider');\n } else {\n lines.push('Provide clean, production-ready code with brief explanations of key decisions');\n }\n\n return makeSection('format', 'format', lines.join('\\n'));\n}\n\n// ===== CONSTANTS =====\n\nconst TASK_ROLES: Record<TaskType, string> = {\n debug: 'debugger',\n review: 'code reviewer',\n refactor: 'architect',\n test: 'test engineer',\n docs: 'technical writer',\n feature: 'engineer',\n architecture: 'systems architect',\n 'simple-edit': 'engineer',\n};\n\nconst COT_STEPS: Record<TaskType, string[]> = {\n debug: [\n '**Reproduce** — Understand the exact symptom and when it occurs',\n '**Hypothesize** — List the most likely root causes (max 3)',\n '**Verify** — Check each hypothesis against the code',\n '**Fix** — Apply the minimal fix that addresses the root cause',\n '**Validate** — Explain why the fix works and what edge cases it covers',\n ],\n review: [\n '**Understand** — Read the code and understand its purpose',\n '**Assess** — Evaluate correctness, readability, performance, security',\n '**Prioritize** — Rank issues by severity (critical > major > minor)',\n '**Suggest** — Provide concrete, actionable improvements with code',\n ],\n refactor: [\n '**Analyze** — Identify code smells and structural issues',\n '**Plan** — Define the target structure before changing anything',\n '**Preserve** — Ensure behavior doesn\\'t change',\n '**Refactor** — Apply changes incrementally',\n '**Verify** — Confirm all existing tests still pass',\n ],\n test: [\n '**Identify** — What needs testing? (happy path, edge cases, errors)',\n '**Structure** — Use AAA pattern: Arrange, Act, Assert',\n '**Cover** — Test boundaries, null/undefined, async errors',\n '**Isolate** — Mock external dependencies, test units independently',\n ],\n docs: [\n '**Read** — Understand the code before documenting',\n '**Structure** — Organize by audience (API users, contributors, operators)',\n '**Write** — Clear, concise, with examples',\n ],\n feature: [\n '**Clarify** — Restate the requirement in your own words',\n '**Design** — Plan the approach (types, interfaces, flow)',\n '**Implement** — Build incrementally, starting with types',\n '**Test** — Write tests alongside implementation',\n '**Integrate** — Ensure no regressions',\n ],\n architecture: [\n '**Context** — Understand current architecture and constraints',\n '**Options** — Present 2-3 viable approaches with trade-offs',\n '**Recommend** — Choose the best and explain why',\n '**Plan** — Define migration steps',\n '**Risks** — Identify risks and mitigation strategies',\n ],\n 'simple-edit': [\n '**Understand** — Read the relevant code',\n '**Plan** — Think before writing',\n '**Implement** — Write clean, well-typed code',\n '**Verify** — Check for edge cases',\n ],\n};\n\n// ===== HELPERS =====\n\nfunction makeSection(\n id: string,\n role: PromptSection['role'],\n content: string,\n): PromptSection {\n const tokens = countTokensChars4(Buffer.byteLength(content, 'utf-8'));\n return { id, role, content, tokens };\n}\n","import { randomUUID, createHash } from 'node:crypto';\nimport { readdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { userInfo } from 'node:os';\nimport { homedir } from 'node:os';\nimport type { AuditEntry, AuditAction } from '../types/govern.js';\n\n// ===== AUDIT TRAIL =====\n//\n// Immutable, tamper-evident audit log for all CTO interactions.\n// Each entry is SHA-256 hashed for integrity verification.\n\nconst CTO_DIR = '.cto-ai';\nconst AUDIT_DIR = 'audit';\nconst MAX_ENTRIES_PER_FILE = 500;\n\nfunction getAuditDir(): string {\n return join(homedir(), CTO_DIR, AUDIT_DIR);\n}\n\nfunction getCurrentAuditFile(): string {\n const date = new Date().toISOString().split('T')[0].replace(/-/g, '');\n return join(getAuditDir(), `audit_${date}.json`);\n}\n\nfunction computeIntegrityHash(entry: Omit<AuditEntry, 'integrityHash'>): string {\n const payload = JSON.stringify({\n id: entry.id,\n timestamp: entry.timestamp,\n action: entry.action,\n user: entry.user,\n projectPath: entry.projectPath,\n details: entry.details,\n });\n return createHash('sha256').update(payload).digest('hex');\n}\n\n// ===== HELPERS (inline to avoid cross-layer deps) =====\n\nasync function ensureDir(dirPath: string): Promise<void> {\n const { mkdir } = await import('node:fs/promises');\n await mkdir(dirPath, { recursive: true });\n}\n\nasync function readJSON<T>(filePath: string): Promise<T | null> {\n const { readFile } = await import('node:fs/promises');\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nasync function writeJSON(filePath: string, data: unknown): Promise<void> {\n const { writeFile } = await import('node:fs/promises');\n await ensureDir(join(filePath, '..'));\n await writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n// ===== PUBLIC API =====\n\nexport async function logAudit(\n action: AuditAction,\n projectPath: string,\n details: Record<string, unknown> = {},\n): Promise<AuditEntry> {\n const auditDir = getAuditDir();\n await ensureDir(auditDir);\n\n let currentUser: string;\n try {\n currentUser = userInfo().username;\n } catch {\n currentUser = process.env.USER ?? process.env.USERNAME ?? 'unknown';\n }\n\n const partialEntry = {\n id: randomUUID().substring(0, 12),\n timestamp: new Date(),\n action,\n user: currentUser,\n projectPath,\n details,\n };\n\n const entry: AuditEntry = {\n ...partialEntry,\n integrityHash: computeIntegrityHash(partialEntry),\n };\n\n const auditFile = getCurrentAuditFile();\n let entries = await readJSON<AuditEntry[]>(auditFile) ?? [];\n entries.push(entry);\n\n if (entries.length > MAX_ENTRIES_PER_FILE) {\n entries = entries.slice(-MAX_ENTRIES_PER_FILE);\n }\n\n await writeJSON(auditFile, entries);\n try { await chmod(auditFile, 0o600); } catch { /* ignore on Windows */ }\n\n return entry;\n}\n\nexport async function getAuditEntries(\n options: {\n projectPath?: string;\n action?: AuditAction;\n since?: Date;\n limit?: number;\n } = {},\n): Promise<AuditEntry[]> {\n const auditDir = getAuditDir();\n let files: string[];\n try {\n files = await readdir(auditDir);\n } catch {\n return [];\n }\n\n const auditFiles = files\n .filter((f) => f.startsWith('audit_') && f.endsWith('.json'))\n .sort()\n .reverse();\n\n const allEntries: AuditEntry[] = [];\n const limit = options.limit ?? 100;\n\n for (const file of auditFiles) {\n if (allEntries.length >= limit) break;\n\n const entries = await readJSON<AuditEntry[]>(join(auditDir, file));\n if (!entries) continue;\n\n for (const entry of entries.reverse()) {\n if (allEntries.length >= limit) break;\n if (options.projectPath && entry.projectPath !== options.projectPath) continue;\n if (options.action && entry.action !== options.action) continue;\n if (options.since && new Date(entry.timestamp) < options.since) continue;\n allEntries.push(entry);\n }\n }\n\n return allEntries;\n}\n\nexport function verifyAuditEntry(entry: AuditEntry): boolean {\n const { integrityHash, ...rest } = entry;\n const expected = computeIntegrityHash(rest as Omit<AuditEntry, 'integrityHash'>);\n return expected === integrityHash;\n}\n\nexport async function verifyAuditIntegrity(): Promise<{\n totalEntries: number;\n validEntries: number;\n invalidEntries: AuditEntry[];\n}> {\n const entries = await getAuditEntries({ limit: 10000 });\n const invalidEntries: AuditEntry[] = [];\n\n for (const entry of entries) {\n if (!verifyAuditEntry(entry)) {\n invalidEntries.push(entry);\n }\n }\n\n return {\n totalEntries: entries.length,\n validEntries: entries.length - invalidEntries.length,\n invalidEntries,\n };\n}\n\nexport async function purgeOldAuditEntries(retentionDays: number): Promise<number> {\n const auditDir = getAuditDir();\n let files: string[];\n try {\n files = await readdir(auditDir);\n } catch {\n return 0;\n }\n\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - retentionDays);\n const cutoffStr = cutoff.toISOString().split('T')[0].replace(/-/g, '');\n\n let purged = 0;\n const { unlink } = await import('node:fs/promises');\n\n for (const file of files) {\n if (!file.startsWith('audit_') || !file.endsWith('.json')) continue;\n const dateStr = file.replace('audit_', '').replace('.json', '');\n if (dateStr < cutoffStr) {\n try {\n await unlink(join(auditDir, file));\n purged++;\n } catch { /* ignore */ }\n }\n }\n\n return purged;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { readFile, writeFile, readdir, mkdir } from 'node:fs/promises';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { selectContext } from '../../engine/selector.js';\nimport { createSnapshot, verifySnapshot, compareSnapshots } from '../../govern/snapshot.js';\nimport type { ContextSnapshot } from '../../types/govern.js';\n\nconst SNAPSHOTS_DIR = '.cto/snapshots';\n\nasync function ensureSnapshotsDir(projectPath: string): Promise<string> {\n const dir = join(projectPath, SNAPSHOTS_DIR);\n await mkdir(dir, { recursive: true });\n return dir;\n}\n\nasync function loadSnapshot(filePath: string): Promise<ContextSnapshot> {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as ContextSnapshot;\n}\n\nexport const snapshotCommand = new Command('snapshot')\n .description('Create and manage reproducible context snapshots')\n .addCommand(\n new Command('create')\n .description('Create a snapshot of current context selection')\n .argument('<name>', 'Snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-t, --task <task>', 'Task description for context selection', 'general review')\n .action(async (name: string, opts: { path?: string; budget?: string; task?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n console.log(chalk.dim(`\\n Analyzing project...`));\n const analysis = await analyzeProject(projectPath);\n\n console.log(chalk.dim(` Selecting context...`));\n const selection = await selectContext({\n task: opts.task ?? 'general review',\n analysis,\n budget,\n });\n\n const snap = createSnapshot(name, analysis, selection, {\n task: opts.task,\n budget,\n createdBy: process.env.USER ?? 'unknown',\n });\n\n const dir = await ensureSnapshotsDir(projectPath);\n const filePath = join(dir, `${name}.json`);\n await writeFile(filePath, JSON.stringify(snap, null, 2), 'utf-8');\n\n console.log('');\n console.log(chalk.bold.cyan(` 📸 Snapshot \"${name}\" created`));\n console.log(` Files: ${snap.files.length}`);\n console.log(` Tokens: ~${Math.round(snap.totalTokens / 1000)}K`);\n console.log(` Coverage: ${snap.coverageScore}%`);\n console.log(` Risk: ${snap.riskScore}/100`);\n console.log(` Hash: ${snap.hash}`);\n console.log(` Saved: ${filePath}`);\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('verify')\n .description('Verify a snapshot against current project state')\n .argument('<name>', 'Snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .action(async (name: string, opts: { path?: string; budget?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n const snapPath = join(projectPath, SNAPSHOTS_DIR, `${name}.json`);\n const snap = await loadSnapshot(snapPath);\n\n console.log(chalk.dim(`\\n Re-analyzing project...`));\n const analysis = await analyzeProject(projectPath);\n\n const selection = await selectContext({\n task: (snap.metadata.task as string) ?? 'general review',\n analysis,\n budget,\n });\n\n const result = await verifySnapshot(snap, analysis, selection);\n\n console.log('');\n if (result.valid) {\n console.log(chalk.bold.green(` ✅ Snapshot \"${name}\" is valid`));\n } else {\n console.log(chalk.bold.red(` ❌ Snapshot \"${name}\" has drifted`));\n }\n\n console.log(` Files checked: ${result.filesChecked}`);\n console.log(` Files matched: ${result.filesMatched}`);\n\n if (result.filesMissing.length > 0) {\n console.log(chalk.yellow(` Missing: ${result.filesMissing.join(', ')}`));\n }\n if (result.filesChanged.length > 0) {\n console.log(chalk.yellow(` Changed: ${result.filesChanged.join(', ')}`));\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('compare')\n .description('Compare two snapshots')\n .argument('<older>', 'Older snapshot name')\n .argument('<newer>', 'Newer snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (older: string, newer: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const dir = join(projectPath, SNAPSHOTS_DIR);\n\n const snap1 = await loadSnapshot(join(dir, `${older}.json`));\n const snap2 = await loadSnapshot(join(dir, `${newer}.json`));\n\n const diff = compareSnapshots(snap1, snap2);\n\n console.log('');\n console.log(chalk.bold.cyan(` 📊 Snapshot Comparison: ${older} → ${newer}`));\n console.log('');\n\n if (diff.added.length > 0) {\n console.log(chalk.green(` Added (${diff.added.length}):`));\n for (const f of diff.added) console.log(` + ${f}`);\n }\n if (diff.removed.length > 0) {\n console.log(chalk.red(` Removed (${diff.removed.length}):`));\n for (const f of diff.removed) console.log(` - ${f}`);\n }\n if (diff.changed.length > 0) {\n console.log(chalk.yellow(` Changed (${diff.changed.length}):`));\n for (const f of diff.changed) console.log(` ~ ${f}`);\n }\n\n console.log('');\n console.log(` Token delta: ${diff.tokenDelta > 0 ? '+' : ''}${diff.tokenDelta}`);\n console.log(` Coverage delta: ${diff.coverageDelta > 0 ? '+' : ''}${diff.coverageDelta}%`);\n console.log(` Risk delta: ${diff.riskDelta > 0 ? '+' : ''}${diff.riskDelta}`);\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('list')\n .description('List saved snapshots')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const dir = join(projectPath, SNAPSHOTS_DIR);\n\n let files: string[];\n try {\n files = await readdir(dir);\n } catch {\n console.log(chalk.dim('\\n No snapshots found. Run `cto snapshot create <name>` first.\\n'));\n return;\n }\n\n const snapFiles = files.filter((f) => f.endsWith('.json')).sort();\n\n if (snapFiles.length === 0) {\n console.log(chalk.dim('\\n No snapshots found.\\n'));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📸 Snapshots (${snapFiles.length})`));\n console.log('');\n\n for (const file of snapFiles) {\n try {\n const snap = await loadSnapshot(join(dir, file));\n const date = new Date(snap.createdAt).toLocaleString();\n console.log(` ${chalk.bold(snap.name)} — ${snap.files.length} files, ~${Math.round(snap.totalTokens / 1000)}K tokens, coverage ${snap.coverageScore}%`);\n console.log(` ${chalk.dim(`Created: ${date} | Hash: ${snap.hash}`)}`);\n } catch {\n console.log(` ${chalk.dim(file)} ${chalk.red('(corrupted)')}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import { randomUUID, createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport type {\n ContextSnapshot,\n SnapshotFile,\n SnapshotVerification,\n} from '../types/govern.js';\nimport type { ContextSelection, ProjectAnalysis } from '../types/engine.js';\n\n// ===== CONTEXT SNAPSHOTS =====\n//\n// Reproducible, verifiable snapshots of context selections.\n// Used for: deterministic mode, audit evidence, before/after comparisons.\n\nexport function createSnapshot(\n name: string,\n analysis: ProjectAnalysis,\n selection: ContextSelection,\n metadata: Record<string, unknown> = {},\n): ContextSnapshot {\n const files: SnapshotFile[] = selection.files.map((f) => ({\n relativePath: f.relativePath,\n hash: hashString(`${f.relativePath}:${f.tokens}:${f.pruneLevel}`),\n tokens: f.tokens,\n pruneLevel: f.pruneLevel,\n }));\n\n const snapshotData = files\n .map((f) => `${f.relativePath}:${f.hash}:${f.pruneLevel}`)\n .sort()\n .join('|');\n\n return {\n id: randomUUID().substring(0, 8),\n name,\n createdAt: new Date(),\n hash: hashString(snapshotData),\n projectHash: analysis.hash,\n analysisHash: analysis.hash,\n selectionHash: selection.hash,\n files,\n totalTokens: selection.totalTokens,\n coverageScore: selection.coverage.score,\n riskScore: selection.riskScore,\n metadata,\n };\n}\n\nexport async function verifySnapshot(\n snapshot: ContextSnapshot,\n currentAnalysis: ProjectAnalysis,\n currentSelection: ContextSelection,\n): Promise<SnapshotVerification> {\n const currentFiles = new Map(\n currentSelection.files.map((f) => [f.relativePath, f]),\n );\n\n let filesMatched = 0;\n const filesMissing: string[] = [];\n const filesChanged: string[] = [];\n\n for (const snapFile of snapshot.files) {\n const current = currentFiles.get(snapFile.relativePath);\n\n if (!current) {\n filesMissing.push(snapFile.relativePath);\n continue;\n }\n\n const currentHash = hashString(\n `${current.relativePath}:${current.tokens}:${current.pruneLevel}`,\n );\n\n if (currentHash === snapFile.hash) {\n filesMatched++;\n } else {\n filesChanged.push(snapFile.relativePath);\n }\n }\n\n // Verify overall hash\n const currentSnapshotData = snapshot.files\n .map((f) => {\n const current = currentFiles.get(f.relativePath);\n if (!current) return `${f.relativePath}:MISSING:MISSING`;\n return `${current.relativePath}:${hashString(`${current.relativePath}:${current.tokens}:${current.pruneLevel}`)}:${current.pruneLevel}`;\n })\n .sort()\n .join('|');\n\n const currentHash = hashString(currentSnapshotData);\n const integrityOk = currentHash === snapshot.hash && filesMissing.length === 0 && filesChanged.length === 0;\n\n return {\n valid: integrityOk,\n snapshotId: snapshot.id,\n filesChecked: snapshot.files.length,\n filesMatched,\n filesMissing,\n filesChanged,\n integrityOk,\n };\n}\n\nexport function compareSnapshots(\n older: ContextSnapshot,\n newer: ContextSnapshot,\n): {\n added: string[];\n removed: string[];\n changed: string[];\n tokenDelta: number;\n coverageDelta: number;\n riskDelta: number;\n} {\n const olderFiles = new Map(older.files.map((f) => [f.relativePath, f]));\n const newerFiles = new Map(newer.files.map((f) => [f.relativePath, f]));\n\n const added: string[] = [];\n const removed: string[] = [];\n const changed: string[] = [];\n\n for (const [path, file] of newerFiles) {\n const old = olderFiles.get(path);\n if (!old) {\n added.push(path);\n } else if (old.hash !== file.hash) {\n changed.push(path);\n }\n }\n\n for (const path of olderFiles.keys()) {\n if (!newerFiles.has(path)) {\n removed.push(path);\n }\n }\n\n return {\n added,\n removed,\n changed,\n tokenDelta: newer.totalTokens - older.totalTokens,\n coverageDelta: newer.coverageScore - older.coverageScore,\n riskDelta: newer.riskScore - older.riskScore,\n };\n}\n\n// ===== HELPERS =====\n\nfunction hashString(input: string): string {\n return createHash('sha256').update(input).digest('hex').substring(0, 16);\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { getAuditEntries, verifyAuditIntegrity, purgeOldAuditEntries } from '../../govern/audit.js';\n\nexport const auditCommand = new Command('audit')\n .description('View and manage the audit trail')\n .addCommand(\n new Command('list')\n .description('List recent audit entries')\n .option('-n, --limit <limit>', 'Number of entries to show', '20')\n .option('-a, --action <action>', 'Filter by action type')\n .option('-p, --project <path>', 'Filter by project path')\n .option('--json', 'Output as JSON')\n .action(async (opts: { limit?: string; action?: string; project?: string; json?: boolean }) => {\n try {\n const entries = await getAuditEntries({\n limit: parseInt(opts.limit ?? '20', 10),\n action: opts.action as any,\n projectPath: opts.project,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n\n if (entries.length === 0) {\n console.log(chalk.dim('\\n No audit entries found.\\n'));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📋 Audit Trail (${entries.length} entries)`));\n console.log('');\n\n for (const entry of entries) {\n const date = new Date(entry.timestamp).toLocaleString();\n const actionColor = entry.action.includes('secret') ? chalk.red\n : entry.action.includes('integrity') ? chalk.yellow\n : chalk.blue;\n\n console.log(` ${chalk.dim(date)} ${actionColor(entry.action)} ${chalk.dim('by')} ${entry.user}`);\n if (entry.projectPath) {\n console.log(` ${chalk.dim(`Project: ${entry.projectPath}`)}`);\n }\n if (entry.tokensUsed) {\n console.log(` ${chalk.dim(`Tokens: ~${Math.round(entry.tokensUsed / 1000)}K | Coverage: ${entry.coverageScore ?? '?'}% | Risk: ${entry.riskScore ?? '?'}`)}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('verify')\n .description('Verify audit trail integrity')\n .action(async () => {\n try {\n console.log(chalk.dim('\\n Verifying audit integrity...\\n'));\n\n const result = await verifyAuditIntegrity();\n\n if (result.invalidEntries.length === 0) {\n console.log(chalk.bold.green(` ✅ Audit trail is intact`));\n } else {\n console.log(chalk.bold.red(` ❌ Audit trail has been tampered with`));\n }\n\n console.log(` Total entries: ${result.totalEntries}`);\n console.log(` Valid: ${result.validEntries}`);\n console.log(` Invalid: ${result.invalidEntries.length}`);\n\n if (result.invalidEntries.length > 0) {\n console.log('');\n console.log(chalk.red(' Tampered entries:'));\n for (const entry of result.invalidEntries.slice(0, 5)) {\n console.log(` ${entry.id} — ${entry.action} at ${new Date(entry.timestamp).toLocaleString()}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('purge')\n .description('Purge old audit entries')\n .option('-d, --days <days>', 'Retention days', '90')\n .action(async (opts: { days?: string }) => {\n try {\n const days = parseInt(opts.days ?? '90', 10);\n const purged = await purgeOldAuditEntries(days);\n\n console.log('');\n if (purged > 0) {\n console.log(chalk.bold(` 🗑️ Purged ${purged} audit file(s) older than ${days} days`));\n } else {\n console.log(chalk.dim(` No audit files older than ${days} days found.`));\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { DEFAULT_POLICY, addRule, removeRule, toggleRule, validateSelection } from '../../govern/policy.js';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { selectContext } from '../../engine/selector.js';\nimport type { PolicySet } from '../../types/govern.js';\n\nconst POLICY_FILE = '.cto/policy.json';\n\nasync function loadPolicy(projectPath: string): Promise<PolicySet> {\n try {\n const content = await readFile(join(projectPath, POLICY_FILE), 'utf-8');\n return JSON.parse(content) as PolicySet;\n } catch {\n return DEFAULT_POLICY;\n }\n}\n\nasync function savePolicy(projectPath: string, policy: PolicySet): Promise<void> {\n const dir = join(projectPath, '.cto');\n await mkdir(dir, { recursive: true });\n await writeFile(join(projectPath, POLICY_FILE), JSON.stringify(policy, null, 2), 'utf-8');\n}\n\nexport const policyCommand = new Command('policy')\n .description('Manage context selection policies')\n .addCommand(\n new Command('show')\n .description('Show current policy rules')\n .option('-p, --path <path>', 'Project path', '.')\n .option('--json', 'Output as JSON')\n .action(async (opts: { path?: string; json?: boolean }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const policy = await loadPolicy(projectPath);\n\n if (opts.json) {\n console.log(JSON.stringify(policy, null, 2));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📜 Policy: ${policy.name} (v${policy.version})`));\n console.log('');\n\n if (policy.rules.length === 0) {\n console.log(chalk.dim(' No rules defined.'));\n }\n\n for (const rule of policy.rules) {\n const status = rule.enabled ? chalk.green('●') : chalk.dim('○');\n const typeColor = rule.type.includes('exclude') ? chalk.red\n : rule.type.includes('include') ? chalk.green\n : chalk.yellow;\n\n console.log(` ${status} ${chalk.bold(rule.id)} — ${typeColor(rule.type)}`);\n console.log(` ${chalk.dim(rule.reason)}`);\n if (rule.pattern) console.log(` ${chalk.dim(`Pattern: ${rule.pattern}`)}`);\n if (rule.threshold != null) console.log(` ${chalk.dim(`Threshold: ${rule.threshold}`)}`);\n if (rule.category) console.log(` ${chalk.dim(`Category: ${rule.category}`)}`);\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('add')\n .description('Add a new policy rule')\n .argument('<id>', 'Rule ID')\n .argument('<type>', 'Rule type: exclude-always | include-always | coverage-minimum | risk-maximum | budget-limit')\n .option('-p, --path <path>', 'Project path', '.')\n .option('--pattern <pattern>', 'Glob pattern for include/exclude rules')\n .option('--threshold <n>', 'Threshold value for metric rules')\n .option('--category <cat>', 'Category for budget-limit rules')\n .option('--reason <reason>', 'Reason for the rule', 'User-defined rule')\n .action(async (id: string, type: string, opts: {\n path?: string;\n pattern?: string;\n threshold?: string;\n category?: string;\n reason?: string;\n }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n\n policy = addRule(policy, {\n id,\n type: type as any,\n pattern: opts.pattern,\n threshold: opts.threshold ? parseInt(opts.threshold, 10) : undefined,\n category: opts.category,\n reason: opts.reason ?? 'User-defined rule',\n enabled: true,\n });\n\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" added (${type})\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('remove')\n .description('Remove a policy rule')\n .argument('<id>', 'Rule ID to remove')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (id: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n policy = removeRule(policy, id);\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" removed\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('toggle')\n .description('Enable or disable a rule')\n .argument('<id>', 'Rule ID')\n .argument('<state>', 'on | off')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (id: string, state: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n policy = toggleRule(policy, id, state === 'on');\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" ${state === 'on' ? 'enabled' : 'disabled'}\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('validate')\n .description('Validate current context selection against policies')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-t, --task <task>', 'Task description', 'general review')\n .action(async (opts: { path?: string; budget?: string; task?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n const policy = await loadPolicy(projectPath);\n\n console.log(chalk.dim('\\n Analyzing project...'));\n const analysis = await analyzeProject(projectPath);\n\n console.log(chalk.dim(' Selecting context...'));\n const selection = await selectContext({\n task: opts.task ?? 'general review',\n analysis,\n budget,\n policies: policy,\n });\n\n const result = validateSelection(selection, policy, analysis.files);\n\n console.log('');\n if (result.passed) {\n console.log(chalk.bold.green(' ✅ Policy validation passed'));\n } else {\n console.log(chalk.bold.red(' ❌ Policy validation failed'));\n }\n\n if (result.violations.length > 0) {\n console.log('');\n console.log(chalk.bold(' Violations:'));\n for (const v of result.violations) {\n const icon = v.severity === 'error' ? chalk.red('✗') : chalk.yellow('⚠');\n console.log(` ${icon} ${v.message}`);\n }\n }\n\n if (result.warnings.length > 0) {\n console.log('');\n console.log(chalk.bold(' Warnings:'));\n for (const w of result.warnings) {\n console.log(` ${chalk.yellow('⚠')} ${w.message}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('init')\n .description('Initialize default policy file')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n await savePolicy(projectPath, DEFAULT_POLICY);\n console.log(chalk.green(`\\n ✅ Default policy initialized at ${join(projectPath, POLICY_FILE)}\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import type {\n PolicySet,\n PolicyRule,\n PolicyRuleType,\n PolicyValidation,\n PolicyViolation,\n PolicyWarning,\n} from '../types/govern.js';\nimport type { ContextSelection, AnalyzedFile } from '../types/engine.js';\nimport { matchGlob } from '../engine/graph-utils.js';\n\n// ===== POLICY ENGINE =====\n//\n// YAML-backed rule engine for controlling what context gets included/excluded.\n// Policies are evaluated after selection to validate compliance.\n\nexport const DEFAULT_POLICY: PolicySet = {\n version: '1.0',\n name: 'default',\n rules: [\n {\n id: 'no-env',\n type: 'exclude-always',\n pattern: '**/*.env*',\n reason: 'Environment files must never be sent to AI',\n enabled: true,\n },\n {\n id: 'no-secrets',\n type: 'secret-block',\n reason: 'Files with detected secrets are blocked',\n enabled: true,\n },\n {\n id: 'min-coverage',\n type: 'coverage-minimum',\n threshold: 70,\n reason: 'Warn if context coverage drops below 70%',\n enabled: true,\n },\n ],\n};\n\n// ===== VALIDATION =====\n\nexport function validateSelection(\n selection: ContextSelection,\n policies: PolicySet,\n allFiles?: AnalyzedFile[],\n): PolicyValidation {\n const violations: PolicyViolation[] = [];\n const warnings: PolicyWarning[] = [];\n\n const includedPaths = new Set(selection.files.map((f) => f.relativePath));\n\n for (const rule of policies.rules) {\n if (!rule.enabled) continue;\n\n switch (rule.type) {\n case 'exclude-always': {\n if (!rule.pattern) break;\n const violatingFiles = selection.files.filter((f) =>\n matchGlob(f.relativePath, rule.pattern!),\n );\n for (const f of violatingFiles) {\n violations.push({\n rule,\n message: `File \"${f.relativePath}\" is included but matches exclude-always pattern \"${rule.pattern}\"`,\n severity: 'error',\n });\n }\n break;\n }\n\n case 'include-always': {\n if (!rule.pattern || !allFiles) break;\n const requiredFiles = allFiles.filter((f) =>\n matchGlob(f.relativePath, rule.pattern!),\n );\n for (const f of requiredFiles) {\n if (!includedPaths.has(f.relativePath)) {\n violations.push({\n rule,\n message: `File \"${f.relativePath}\" matches include-always pattern \"${rule.pattern}\" but is not included`,\n severity: 'warning',\n });\n }\n }\n break;\n }\n\n case 'coverage-minimum': {\n const threshold = rule.threshold ?? 70;\n if (selection.coverage.score < threshold) {\n warnings.push({\n rule,\n message: `Coverage ${selection.coverage.score}% is below minimum ${threshold}%`,\n currentValue: selection.coverage.score,\n threshold,\n });\n }\n break;\n }\n\n case 'risk-maximum': {\n const threshold = rule.threshold ?? 50;\n if (selection.riskScore > threshold) {\n warnings.push({\n rule,\n message: `Exclusion risk ${selection.riskScore}/100 exceeds maximum ${threshold}`,\n currentValue: selection.riskScore,\n threshold,\n });\n }\n break;\n }\n\n case 'budget-limit': {\n if (!rule.category || !rule.threshold) break;\n const categoryFiles = selection.files.filter((f) =>\n fileMatchesCategory(f.relativePath, rule.category!),\n );\n const categoryTokens = categoryFiles.reduce((s, f) => s + f.tokens, 0);\n const categoryPercent = selection.totalTokens > 0\n ? (categoryTokens / selection.totalTokens) * 100\n : 0;\n\n if (categoryPercent > rule.threshold) {\n warnings.push({\n rule,\n message: `Category \"${rule.category}\" uses ${Math.round(categoryPercent)}% of budget (max: ${rule.threshold}%)`,\n currentValue: Math.round(categoryPercent),\n threshold: rule.threshold,\n });\n }\n break;\n }\n }\n }\n\n return {\n passed: violations.filter((v) => v.severity === 'error').length === 0,\n violations,\n warnings,\n };\n}\n\n// ===== POLICY CRUD =====\n\nexport function addRule(policies: PolicySet, rule: PolicyRule): PolicySet {\n return {\n ...policies,\n rules: [...policies.rules, rule],\n };\n}\n\nexport function removeRule(policies: PolicySet, ruleId: string): PolicySet {\n return {\n ...policies,\n rules: policies.rules.filter((r) => r.id !== ruleId),\n };\n}\n\nexport function toggleRule(policies: PolicySet, ruleId: string, enabled: boolean): PolicySet {\n return {\n ...policies,\n rules: policies.rules.map((r) =>\n r.id === ruleId ? { ...r, enabled } : r,\n ),\n };\n}\n\n// ===== HELPERS =====\n\nfunction fileMatchesCategory(path: string, category: string): boolean {\n switch (category) {\n case 'test':\n return /\\.(test|spec)\\.[jt]sx?$/.test(path) || /\\/__tests__\\//.test(path) || /\\/tests?\\//.test(path);\n case 'config':\n return /\\.(config|rc)\\.[jt]s$/.test(path) || /\\.json$/.test(path) || /\\.ya?ml$/.test(path);\n case 'docs':\n return /\\.(md|txt|rst)$/.test(path);\n case 'types':\n return /types?\\//i.test(path) || /\\.d\\.ts$/.test(path);\n default:\n return path.includes(category);\n }\n}\n"],"mappings":"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","names":["Command","chalk","join","writeFile","join","writeFile","Command","chalk","resolve","readFile","stat","join","relative","resolve","basename","readFile","resolve","join","existsSync","join","stat","readFile","relative","basename","resolve","Command","resolve","chalk","Command","chalk","resolve","join","writeFile","createHash","readdir","stat","join","extname","relative","resolve","readdir","join","extname","stat","relative","createHash","resolve","resolve","resolve","risk","randomUUID","createHash","readFile","resolve","relative","Project","SyntaxKind","readFile","existsSync","join","TS_EXTENSIONS","emptyResult","readFile","emptyResult","Project","SyntaxKind","join","existsSync","createHash","createHash","readdir","join","mkdir","readFile","writeFile","randomUUID","Command","resolve","chalk","join","writeFile","Command","chalk","resolve","join","readFile","writeFile","readdir","mkdir","randomUUID","createHash","currentHash","join","mkdir","readFile","Command","resolve","chalk","writeFile","readdir","Command","chalk","Command","chalk","Command","chalk","resolve","join","readFile","writeFile","mkdir","POLICY_FILE","readFile","join","mkdir","writeFile","Command","resolve","chalk","Command","chalk"]}
1
+ {"version":3,"sources":["../../../src/cli/v2/index.ts","../../../src/cli/v2/init.ts","../../../src/engine/config.ts","../../../src/types/config.ts","../../../src/cli/v2/analyze.ts","../../../src/engine/analyzer.ts","../../../src/types/engine.ts","../../../src/engine/tokenizer.ts","../../../src/engine/graph.ts","../../../src/engine/risk.ts","../../../src/cli/v2/interact.ts","../../../src/engine/cache.ts","../../../src/engine/pr-context.ts","../../../src/engine/graph-utils.ts","../../../src/interact/orchestrator.ts","../../../src/engine/selector.ts","../../../src/govern/secrets.ts","../../../src/engine/pruner.ts","../../../src/engine/coverage.ts","../../../src/engine/budget.ts","../../../src/interact/router.ts","../../../src/interact/estimator.ts","../../../src/interact/prompt.ts","../../../src/govern/audit.ts","../../../src/cli/v2/snapshot.ts","../../../src/govern/snapshot.ts","../../../src/cli/v2/audit.ts","../../../src/cli/v2/policy.ts","../../../src/govern/policy.ts"],"sourcesContent":["import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { initCommand } from './init.js';\nimport { analyzeCommand } from './analyze.js';\nimport { interactCommand } from './interact.js';\nimport { snapshotCommand } from './snapshot.js';\nimport { auditCommand } from './audit.js';\nimport { policyCommand } from './policy.js';\n\nconst CTO_V2_VERSION = '2.0.0';\n\nconst program = new Command();\n\nprogram\n .name('cto')\n .description('CTO — Context Operating System for AI-native Engineering')\n .version(CTO_V2_VERSION, '-v, --version');\n\nprogram.addCommand(initCommand);\nprogram.addCommand(analyzeCommand);\nprogram.addCommand(interactCommand);\nprogram.addCommand(snapshotCommand);\nprogram.addCommand(auditCommand);\nprogram.addCommand(policyCommand);\n\n// Default action — branded help\nprogram.action(() => {\n console.log('');\n console.log(chalk.bold.cyan(' 🧠 CTO v2 — Context Operating System'));\n console.log(chalk.dim(` v${CTO_V2_VERSION}`));\n console.log('');\n console.log(chalk.dim(' AI Interaction Infrastructure for Engineering Teams'));\n console.log(chalk.dim(' Formal risk modeling · Deterministic selection · Enterprise auditability'));\n console.log('');\n console.log(chalk.bold(' Commands:'));\n console.log(chalk.dim(' init Setup CTO for a project'));\n console.log(chalk.dim(' analyze [path] Analyze structure, deps & risk'));\n console.log(chalk.dim(' interact <task> Build optimized AI context'));\n console.log(chalk.dim(' snapshot create|verify|compare|list Reproducible context snapshots'));\n console.log(chalk.dim(' audit list|verify|purge Tamper-evident audit trail'));\n console.log(chalk.dim(' policy show|add|remove|toggle|validate|init Context policies'));\n console.log('');\n console.log(chalk.bold(' Quick Start:'));\n console.log(chalk.dim(' $ cto init'));\n console.log(chalk.dim(' $ cto analyze'));\n console.log(chalk.dim(' $ cto interact \"refactor the auth middleware\"'));\n console.log(chalk.dim(' $ cto snapshot create baseline'));\n console.log('');\n console.log(chalk.dim(' Run cto <command> --help for details'));\n console.log('');\n});\n\nprogram.parse();\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { initProjectConfig } from '../../engine/config.js';\n\nexport const initCommand = new Command('init')\n .description('Initialize CTO v2 for a project')\n .argument('[path]', 'Project path', '.')\n .option('--defaults', 'Skip prompts and use defaults')\n .action(async (path: string, opts: { defaults?: boolean }) => {\n try {\n const projectPath = resolve(path);\n const ctoDir = join(projectPath, '.cto');\n\n console.log('');\n console.log(chalk.bold.cyan(' 🔧 CTO v2.0 — Context Operating System'));\n console.log(chalk.dim(' AI Interaction Infrastructure for Engineering Teams'));\n console.log('');\n\n // Create .cto directory structure + config.yml + policy.yml\n const { configPath, policyPath, created } = await initProjectConfig(projectPath);\n\n // Create .gitignore for .cto\n const gitignorePath = join(ctoDir, '.gitignore');\n const gitignoreContent = [\n '# CTO v2 — local state (do not commit)',\n 'audit/',\n 'snapshots/',\n '',\n '# Config and policy should be committed',\n '!config.yml',\n '!policy.yml',\n '',\n ].join('\\n');\n await writeFile(gitignorePath, gitignoreContent, 'utf-8');\n\n console.log(chalk.green(' ✅ Initialized .cto/ directory'));\n console.log(chalk.dim(` ${ctoDir}/`));\n console.log(chalk.dim(' ├── config.yml (commit this)'));\n console.log(chalk.dim(' ├── policy.yml (commit this)'));\n console.log(chalk.dim(' ├── snapshots/ (local)'));\n console.log(chalk.dim(' └── .gitignore'));\n if (created.length > 0) {\n console.log(chalk.dim(` Created: ${created.length} file(s)`));\n }\n console.log('');\n\n console.log(chalk.bold(' Next steps:'));\n console.log(chalk.dim(' cto analyze — Analyze project structure & risk'));\n console.log(chalk.dim(' cto interact \"refactor auth module\" — Build optimized AI context'));\n console.log(chalk.dim(' cto snapshot create baseline — Save a reproducible snapshot'));\n console.log(chalk.dim(' cto policy show — View context policies'));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport { parse as parseYAML, stringify as stringifyYAML } from 'yaml';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\n\n// ===== CONFIG FILE SUPPORT =====\n//\n// Loads and saves .cto/config.yml per the ARCHITECTURE.md spec.\n// Deep-merges user config on top of DEFAULT_CONFIG so partial\n// configs work correctly.\n\nconst CONFIG_DIR = '.cto';\nconst CONFIG_FILE = 'config.yml';\nconst POLICY_FILE = 'policy.yml';\n\nexport function getConfigPath(projectPath: string): string {\n return join(projectPath, CONFIG_DIR, CONFIG_FILE);\n}\n\nexport function getPolicyPath(projectPath: string): string {\n return join(projectPath, CONFIG_DIR, POLICY_FILE);\n}\n\nexport function getCTODir(projectPath: string): string {\n return join(projectPath, CONFIG_DIR);\n}\n\nexport async function loadConfig(projectPath: string): Promise<CTOConfig> {\n const configPath = getConfigPath(projectPath);\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = await readFile(configPath, 'utf-8');\n const userConfig = parseYAML(raw) as Partial<CTOConfig>;\n return deepMerge(DEFAULT_CONFIG, userConfig) as CTOConfig;\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport async function saveConfig(\n projectPath: string,\n config: CTOConfig,\n): Promise<string> {\n const ctoDir = getCTODir(projectPath);\n await mkdir(ctoDir, { recursive: true });\n\n const configPath = getConfigPath(projectPath);\n const yamlContent = stringifyYAML(config, { indent: 2 });\n await writeFile(configPath, yamlContent, 'utf-8');\n return configPath;\n}\n\nexport async function initProjectConfig(projectPath: string): Promise<{\n configPath: string;\n policyPath: string;\n created: string[];\n}> {\n const ctoDir = getCTODir(projectPath);\n await mkdir(join(ctoDir, 'snapshots'), { recursive: true });\n\n const created: string[] = [];\n\n // Create config.yml if it doesn't exist\n const configPath = getConfigPath(projectPath);\n if (!existsSync(configPath)) {\n await saveConfig(projectPath, DEFAULT_CONFIG);\n created.push(configPath);\n }\n\n // Create policy.yml if it doesn't exist\n const policyPath = getPolicyPath(projectPath);\n if (!existsSync(policyPath)) {\n const defaultPolicy = {\n version: '1.0',\n name: 'default',\n rules: [\n {\n id: 'types-always',\n type: 'include-always',\n pattern: '**/types/**',\n reason: 'Type definitions provide essential context',\n enabled: true,\n },\n {\n id: 'no-env',\n type: 'exclude-always',\n pattern: '**/*.env*',\n reason: 'Environment files must never be sent to AI',\n enabled: true,\n },\n {\n id: 'no-secrets',\n type: 'secret-block',\n reason: 'Files with detected secrets are blocked',\n enabled: true,\n },\n {\n id: 'test-budget',\n type: 'budget-limit',\n category: 'test',\n threshold: 20,\n reason: 'Test files should not exceed 20% of budget',\n enabled: true,\n },\n {\n id: 'min-coverage',\n type: 'coverage-minimum',\n threshold: 70,\n reason: 'Warn if context coverage drops below 70%',\n enabled: true,\n },\n ],\n };\n const yamlContent = stringifyYAML(defaultPolicy, { indent: 2 });\n await writeFile(policyPath, yamlContent, 'utf-8');\n created.push(policyPath);\n }\n\n return { configPath, policyPath, created };\n}\n\nexport async function loadPolicyFromYAML(projectPath: string): Promise<import('../types/govern.js').PolicySet | null> {\n const policyPath = getPolicyPath(projectPath);\n if (!existsSync(policyPath)) return null;\n\n try {\n const raw = await readFile(policyPath, 'utf-8');\n return parseYAML(raw) as import('../types/govern.js').PolicySet;\n } catch {\n return null;\n }\n}\n\n// ===== HELPERS =====\n\nfunction deepMerge(target: Record<string, any>, source: Record<string, any>): Record<string, any> {\n const result = { ...target };\n\n for (const key of Object.keys(source)) {\n if (\n source[key] !== null &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n typeof target[key] === 'object' &&\n !Array.isArray(target[key])\n ) {\n result[key] = deepMerge(target[key], source[key]);\n } else if (source[key] !== undefined) {\n result[key] = source[key];\n }\n }\n\n return result;\n}\n","// ===== Configuration Types =====\n\nimport type { RiskWeights } from './engine.js';\n\nexport interface CTOConfig {\n version: string;\n\n analysis: {\n extensions: {\n code: string[];\n config: string[];\n docs: string[];\n };\n ignore: {\n dirs: string[];\n patterns: string[];\n };\n maxDepth: number;\n };\n\n risk: {\n weights: RiskWeights;\n };\n\n interaction: {\n defaultBudget: number;\n defaultModel: string;\n };\n\n tokens: {\n method: 'chars4' | 'tiktoken';\n };\n\n governance: {\n auditEnabled: boolean;\n secretDetection: boolean;\n retentionDays: number;\n };\n}\n\nexport const DEFAULT_CONFIG: CTOConfig = {\n version: '2.0',\n\n analysis: {\n extensions: {\n code: ['ts', 'tsx', 'js', 'jsx', 'py', 'go', 'rs', 'java', 'kt', 'rb', 'php', 'c', 'cpp', 'h', 'hpp', 'cs'],\n config: ['json', 'yml', 'yaml', 'toml'],\n docs: ['md', 'txt', 'rst'],\n },\n ignore: {\n dirs: ['node_modules', 'dist', 'build', '.git', 'coverage', '__pycache__', '.next', 'vendor', '.cto'],\n patterns: ['*.min.js', '*.map', '*.lock', '*.generated.*'],\n },\n maxDepth: 20,\n },\n\n risk: {\n weights: {\n hub: 30,\n typeProvider: 25,\n complexity: 15,\n recency: 15,\n config: 10,\n churn: 5,\n },\n },\n\n interaction: {\n defaultBudget: 50_000,\n defaultModel: 'claude-sonnet-4',\n },\n\n tokens: {\n method: 'chars4',\n },\n\n governance: {\n auditEnabled: true,\n secretDetection: true,\n retentionDays: 90,\n },\n};\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve } from 'node:path';\nimport { analyzeProject } from '../../engine/analyzer.js';\n\nexport const analyzeCommand = new Command('analyze')\n .description('Analyze project structure, dependencies, and risk profile')\n .argument('[path]', 'Project path to analyze', '.')\n .option('--json', 'Output as JSON')\n .option('--method <method>', 'Token counting method: chars4 | tiktoken', 'chars4')\n .option('--risk-only', 'Show only risk distribution and top risk files')\n .option('--graph', 'Show detailed dependency graph info (hubs, clusters, orphans)')\n .action(async (path: string, opts: { json?: boolean; method?: string; riskOnly?: boolean; graph?: boolean }) => {\n try {\n const projectPath = resolve(path);\n const method = (opts.method === 'tiktoken' ? 'tiktoken' : 'chars4') as 'chars4' | 'tiktoken';\n\n console.log(chalk.dim(`\\n Analyzing ${projectPath}...\\n`));\n\n const analysis = await analyzeProject(projectPath, { tokens: { method } });\n\n if (opts.json) {\n console.log(JSON.stringify(analysis, null, 2));\n return;\n }\n\n // Summary\n console.log(chalk.bold.cyan(' 📊 Project Analysis'));\n console.log('');\n console.log(` ${chalk.bold('Project:')} ${analysis.projectName}`);\n console.log(` ${chalk.bold('Stack:')} ${analysis.stack.join(', ') || 'Unknown'}`);\n console.log(` ${chalk.bold('Files:')} ${analysis.totalFiles}`);\n console.log(` ${chalk.bold('Tokens:')} ~${Math.round(analysis.totalTokens / 1000)}K`);\n console.log(` ${chalk.bold('Method:')} ${analysis.tokenMethod}`);\n console.log(` ${chalk.bold('Hash:')} ${analysis.hash.substring(0, 12)}`);\n console.log('');\n\n // Risk profile\n const d = analysis.riskProfile.distribution;\n console.log(chalk.bold(' Risk Distribution:'));\n console.log(` ${chalk.red('Critical:')} ${d.critical} ${chalk.yellow('High:')} ${d.high} ${chalk.blue('Medium:')} ${d.medium} ${chalk.dim('Low:')} ${d.low}`);\n console.log(` ${chalk.bold('Overall complexity:')} ${analysis.riskProfile.overallComplexity.toFixed(1)}`);\n console.log('');\n\n if (opts.riskOnly) {\n // --risk-only: skip graph and other info\n console.log(chalk.dim(` Run ${chalk.bold('cto interact')} to build optimized AI context`));\n console.log('');\n return;\n }\n\n // Graph summary\n const g = analysis.graph;\n console.log(chalk.bold(' Dependency Graph:'));\n console.log(` Nodes: ${g.nodes.length} Edges: ${g.edges.length}`);\n console.log(` Hubs: ${g.hubs.length} Leaves: ${g.leaves.length} Orphans: ${g.orphans.length} Clusters: ${g.clusters.length}`);\n\n if (opts.graph) {\n // --graph: show detailed graph info\n if (g.hubs.length > 0) {\n console.log('');\n console.log(chalk.bold(' Hub Files (imported by 3+ files):'));\n for (const hub of g.hubs.slice(0, 15)) {\n console.log(` ${hub.relativePath} — ${hub.dependents} dependents, score ${hub.score}`);\n }\n }\n if (g.clusters.length > 0) {\n console.log('');\n console.log(chalk.bold(' Clusters:'));\n for (const c of g.clusters.slice(0, 10)) {\n console.log(` ${c.name} — ${c.files.length} files, ${Math.round(c.totalTokens / 1000)}K tokens, cohesion ${c.cohesion}`);\n }\n }\n if (g.orphans.length > 0) {\n console.log('');\n console.log(chalk.bold(` Orphans (${g.orphans.length} files with no connections):`));\n for (const o of g.orphans.slice(0, 10)) {\n console.log(` ${chalk.dim(o)}`);\n }\n if (g.orphans.length > 10) {\n console.log(chalk.dim(` ... and ${g.orphans.length - 10} more`));\n }\n }\n }\n console.log('');\n\n // Top risk files\n if (analysis.riskProfile.topRiskFiles.length > 0) {\n console.log(chalk.bold(' Top Risk Files:'));\n for (const f of analysis.riskProfile.topRiskFiles.slice(0, 10)) {\n const impact = f.exclusionImpact;\n const impactColor = impact === 'critical' ? chalk.red : impact === 'high' ? chalk.yellow : chalk.dim;\n console.log(` ${impactColor(`[${impact}]`)} ${f.relativePath} — risk ${f.riskScore}, ~${Math.round(f.tokens / 1000)}K tokens`);\n }\n console.log('');\n }\n\n console.log(chalk.dim(` Run ${chalk.bold('cto interact')} to build optimized AI context`));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, extname, relative, resolve, basename } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type {\n AnalyzedFile,\n FileKind,\n ProjectAnalysis,\n WalkEntry,\n WalkOptions,\n} from '../types/engine.js';\nimport { DEFAULT_RISK_WEIGHTS } from '../types/engine.js';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\nimport { estimateTokens, countTokensChars4 } from './tokenizer.js';\nimport { buildProjectGraph } from './graph.js';\nimport { scoreAllFiles } from './risk.js';\n\n// ===== FILE WALKING =====\n\nfunction matchesPattern(filename: string, patterns: string[]): boolean {\n for (const pattern of patterns) {\n if (pattern.startsWith('*.')) {\n const ext = pattern.slice(1);\n if (filename.endsWith(ext)) return true;\n } else if (filename === pattern) {\n return true;\n }\n }\n return false;\n}\n\nexport async function walkProject(\n rootPath: string,\n options: WalkOptions,\n): Promise<WalkEntry[]> {\n const results: WalkEntry[] = [];\n const { ignoreDirs, ignorePatterns, extensions, maxDepth = 20 } = options;\n const ignoreDirSet = new Set(ignoreDirs);\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > maxDepth) return;\n\n let entries;\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n const promises: Promise<void>[] = [];\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!ignoreDirSet.has(entry.name) && !entry.name.startsWith('.')) {\n promises.push(walk(fullPath, depth + 1));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).slice(1).toLowerCase();\n if (ext && extensions.includes(ext) && !matchesPattern(entry.name, ignorePatterns)) {\n promises.push(\n (async () => {\n const fileStat = await stat(fullPath).catch(() => null);\n if (!fileStat) return;\n\n let lines = 0;\n try {\n const content = await readFile(fullPath, 'utf-8');\n lines = content.split('\\n').length;\n } catch {\n lines = 0;\n }\n\n results.push({\n path: fullPath,\n relativePath: relative(rootPath, fullPath),\n extension: ext,\n size: fileStat.size,\n lastModified: fileStat.mtime,\n lines,\n });\n })(),\n );\n }\n }\n }\n\n await Promise.all(promises);\n }\n\n await walk(rootPath, 0);\n return results;\n}\n\n// ===== FILE KIND DETECTION =====\n\nconst TYPE_PATTERNS = [/types?\\//i, /\\.d\\.ts$/, /interfaces?\\//i];\nconst TEST_PATTERNS = [/\\.test\\.[jt]sx?$/, /\\.spec\\.[jt]sx?$/, /\\/__tests__\\//, /\\/tests?\\//];\nconst CONFIG_PATTERNS = [/\\.config\\.[jt]s$/, /rc\\.[jt]s$/, /\\.env/, /tsconfig/, /package\\.json$/, /\\.yml$/, /\\.yaml$/, /\\.toml$/];\nconst ENTRY_PATTERNS = [/^index\\.[jt]sx?$/, /^main\\.[jt]sx?$/, /^app\\.[jt]sx?$/, /^server\\.[jt]sx?$/];\n\nexport function classifyFileKind(relativePath: string): FileKind {\n const filename = basename(relativePath);\n\n if (TYPE_PATTERNS.some((p) => p.test(relativePath))) return 'type';\n if (TEST_PATTERNS.some((p) => p.test(relativePath))) return 'test';\n if (CONFIG_PATTERNS.some((p) => p.test(relativePath) || p.test(filename))) return 'config';\n if (ENTRY_PATTERNS.some((p) => p.test(filename))) return 'entry';\n return 'source';\n}\n\n// ===== STACK DETECTION =====\n\nexport function detectStack(files: WalkEntry[]): string[] {\n const stack: string[] = [];\n const extensions = new Set(files.map((f) => f.extension));\n const paths = files.map((f) => f.relativePath.toLowerCase());\n\n if (extensions.has('ts') || extensions.has('tsx')) stack.push('TypeScript');\n else if (extensions.has('js') || extensions.has('jsx')) stack.push('JavaScript');\n if (extensions.has('py')) stack.push('Python');\n if (extensions.has('go')) stack.push('Go');\n if (extensions.has('rs')) stack.push('Rust');\n if (extensions.has('java')) stack.push('Java');\n if (extensions.has('kt')) stack.push('Kotlin');\n if (extensions.has('rb')) stack.push('Ruby');\n if (extensions.has('php')) stack.push('PHP');\n if (extensions.has('cs')) stack.push('C#');\n if (extensions.has('c') || extensions.has('cpp')) stack.push('C/C++');\n\n if (paths.some((p) => p.includes('next.config'))) stack.push('Next.js');\n if (paths.some((p) => p.includes('nuxt.config'))) stack.push('Nuxt');\n if (paths.some((p) => p.includes('angular.json'))) stack.push('Angular');\n\n return stack;\n}\n\n// ===== MAIN ANALYSIS PIPELINE =====\n\nexport async function analyzeProject(\n projectPath: string,\n config?: Partial<CTOConfig>,\n): Promise<ProjectAnalysis> {\n const absPath = resolve(projectPath);\n const projectName = basename(absPath);\n const mergedConfig = mergeConfig(DEFAULT_CONFIG, config);\n\n // 1. Walk project files\n const allExtensions = [\n ...mergedConfig.analysis.extensions.code,\n ...mergedConfig.analysis.extensions.config,\n ...mergedConfig.analysis.extensions.docs,\n ];\n\n const walkEntries = await walkProject(absPath, {\n ignoreDirs: mergedConfig.analysis.ignore.dirs,\n ignorePatterns: mergedConfig.analysis.ignore.patterns,\n extensions: allExtensions,\n maxDepth: mergedConfig.analysis.maxDepth,\n });\n\n // 2. Estimate tokens and build initial AnalyzedFile[]\n const tokenMethod = mergedConfig.tokens.method;\n const files: AnalyzedFile[] = [];\n\n for (const entry of walkEntries) {\n let tokens: number;\n if (tokenMethod === 'tiktoken') {\n try {\n const content = await readFile(entry.path, 'utf-8');\n tokens = estimateTokens(content, entry.size, 'tiktoken');\n } catch {\n tokens = countTokensChars4(entry.size);\n }\n } else {\n tokens = countTokensChars4(entry.size);\n }\n\n files.push({\n path: entry.path,\n relativePath: entry.relativePath,\n extension: entry.extension,\n size: entry.size,\n tokens,\n lines: entry.lines,\n lastModified: entry.lastModified,\n kind: classifyFileKind(entry.relativePath),\n\n // Graph data — populated by graph analysis\n imports: [],\n importedBy: [],\n isHub: false,\n complexity: 0,\n\n // Risk data — populated by risk analysis\n riskScore: 0,\n riskFactors: [],\n exclusionImpact: 'none',\n });\n }\n\n // 3. Build dependency graph (AST-based, best-effort)\n const graph = buildProjectGraph(absPath, files);\n\n // 4. Enrich files with graph data\n for (const file of files) {\n const nodeImports: string[] = [];\n const nodeImportedBy: string[] = [];\n\n for (const edge of graph.edges) {\n if (edge.from === file.relativePath) nodeImports.push(edge.to);\n if (edge.to === file.relativePath) nodeImportedBy.push(edge.from);\n }\n\n file.imports = nodeImports;\n file.importedBy = nodeImportedBy;\n file.isHub = graph.hubs.some((h) => h.relativePath === file.relativePath);\n }\n\n // 5. Score risk for all files\n const riskWeights = mergedConfig.risk.weights;\n scoreAllFiles(files, graph, riskWeights);\n\n // 6. Build risk profile\n const riskProfile = {\n distribution: {\n critical: files.filter((f) => f.riskScore >= 80).length,\n high: files.filter((f) => f.riskScore >= 60 && f.riskScore < 80).length,\n medium: files.filter((f) => f.riskScore >= 30 && f.riskScore < 60).length,\n low: files.filter((f) => f.riskScore < 30).length,\n },\n topRiskFiles: [...files].sort((a, b) => b.riskScore - a.riskScore).slice(0, 10),\n overallComplexity: files.length > 0\n ? files.reduce((s, f) => s + f.complexity, 0) / files.length\n : 0,\n };\n\n // 7. Build analysis hash for determinism\n const totalTokens = files.reduce((s, f) => s + f.tokens, 0);\n const hashInput = files\n .map((f) => `${f.relativePath}:${f.tokens}:${f.riskScore}`)\n .sort()\n .join('|');\n const hash = createHash('sha256').update(hashInput).digest('hex').substring(0, 16);\n\n const stack = detectStack(walkEntries);\n\n return {\n projectPath: absPath,\n projectName,\n analyzedAt: new Date(),\n hash,\n files,\n totalFiles: files.length,\n totalTokens,\n graph,\n riskProfile,\n stack,\n tokenMethod,\n };\n}\n\n// ===== CONFIG MERGE =====\n\nfunction mergeConfig(base: CTOConfig, overrides?: Partial<CTOConfig>): CTOConfig {\n if (!overrides) return base;\n\n return {\n ...base,\n ...overrides,\n analysis: {\n ...base.analysis,\n ...overrides.analysis,\n extensions: {\n ...base.analysis.extensions,\n ...overrides.analysis?.extensions,\n },\n ignore: {\n ...base.analysis.ignore,\n ...overrides.analysis?.ignore,\n },\n },\n risk: {\n ...base.risk,\n ...overrides.risk,\n weights: {\n ...base.risk.weights,\n ...overrides.risk?.weights,\n },\n },\n interaction: {\n ...base.interaction,\n ...overrides.interaction,\n },\n tokens: {\n ...base.tokens,\n ...overrides.tokens,\n },\n governance: {\n ...base.governance,\n ...overrides.governance,\n },\n };\n}\n","// ===== Layer 1: Context Intelligence Engine Types =====\n\n// ===== FILE ANALYSIS =====\n\nexport interface AnalyzedFile {\n path: string;\n relativePath: string;\n extension: string;\n size: number;\n tokens: number;\n lines: number;\n lastModified: Date;\n kind: FileKind;\n\n // Graph data (populated after graph analysis)\n imports: string[];\n importedBy: string[];\n isHub: boolean;\n complexity: number;\n\n // Risk data (populated after risk analysis)\n riskScore: number;\n riskFactors: RiskFactor[];\n exclusionImpact: ExclusionImpact;\n}\n\nexport type FileKind = 'source' | 'type' | 'test' | 'config' | 'entry' | 'asset';\nexport type ExclusionImpact = 'critical' | 'high' | 'medium' | 'low' | 'none';\n\n// ===== PROJECT ANALYSIS =====\n\nexport interface ProjectAnalysis {\n projectPath: string;\n projectName: string;\n analyzedAt: Date;\n hash: string;\n\n files: AnalyzedFile[];\n totalFiles: number;\n totalTokens: number;\n\n graph: ProjectGraph;\n riskProfile: RiskProfile;\n stack: string[];\n tokenMethod: 'chars4' | 'tiktoken';\n}\n\n// ===== DEPENDENCY GRAPH =====\n\nexport interface ProjectGraph {\n nodes: string[];\n edges: GraphEdge[];\n hubs: HubNode[];\n leaves: string[];\n orphans: string[];\n clusters: FileCluster[];\n}\n\nexport interface GraphEdge {\n from: string;\n to: string;\n type: 'import' | 'export' | 're-export';\n}\n\nexport interface HubNode {\n relativePath: string;\n dependents: number;\n dependencies: number;\n score: number;\n}\n\nexport interface FileCluster {\n id: string;\n name: string;\n files: string[];\n totalTokens: number;\n internalEdges: number;\n externalEdges: number;\n cohesion: number;\n}\n\n// ===== RISK MODEL =====\n\nexport interface RiskProfile {\n distribution: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n };\n topRiskFiles: AnalyzedFile[];\n overallComplexity: number;\n}\n\nexport interface RiskFactor {\n type: RiskFactorType;\n score: number;\n weight: number;\n detail: string;\n}\n\nexport type RiskFactorType =\n | 'hub'\n | 'type-provider'\n | 'complexity'\n | 'recency'\n | 'config'\n | 'churn';\n\nexport interface RiskWeights {\n hub: number;\n typeProvider: number;\n complexity: number;\n recency: number;\n config: number;\n churn: number;\n}\n\nexport const DEFAULT_RISK_WEIGHTS: RiskWeights = {\n hub: 30,\n typeProvider: 25,\n complexity: 15,\n recency: 15,\n config: 10,\n churn: 5,\n};\n\n// ===== CONTEXT COVERAGE =====\n\nexport interface CoverageResult {\n score: number;\n relevantFiles: string[];\n includedRelevant: string[];\n missingRelevant: string[];\n missingCritical: string[];\n explanation: string;\n}\n\n// ===== CONTEXT SELECTION =====\n\nexport interface ContextSelection {\n files: SelectedFile[];\n totalTokens: number;\n budget: number;\n usedPercent: number;\n\n coverage: CoverageResult;\n riskScore: number;\n deterministic: boolean;\n hash: string;\n\n decisions: SelectionDecision[];\n}\n\nexport interface SelectedFile {\n relativePath: string;\n tokens: number;\n originalTokens: number;\n pruneLevel: PruneLevel;\n riskScore: number;\n reason: string;\n}\n\nexport type PruneLevel = 'full' | 'signatures' | 'skeleton' | 'excluded';\n\nexport interface SelectionDecision {\n file: string;\n action: 'include-full' | 'include-signatures' | 'include-skeleton' | 'exclude';\n reason: string;\n alternatives?: string;\n}\n\n// ===== BUDGET =====\n\nexport interface BudgetPlan {\n budget: number;\n used: number;\n remaining: number;\n fillPercent: number;\n files: BudgetEntry[];\n}\n\nexport interface BudgetEntry {\n relativePath: string;\n originalTokens: number;\n allocatedTokens: number;\n pruneLevel: PruneLevel;\n included: boolean;\n reason: string;\n}\n\n// ===== PRUNING =====\n\nexport interface PrunedContent {\n relativePath: string;\n originalTokens: number;\n prunedTokens: number;\n pruneLevel: PruneLevel;\n content: string;\n savingsPercent: number;\n}\n\n// ===== WALKER =====\n\nexport interface WalkEntry {\n path: string;\n relativePath: string;\n extension: string;\n size: number;\n lastModified: Date;\n lines: number;\n}\n\nexport interface WalkOptions {\n ignoreDirs: string[];\n ignorePatterns: string[];\n extensions: string[];\n maxDepth?: number;\n}\n","import { encodingForModel } from 'js-tiktoken';\nimport { readFile, stat } from 'node:fs/promises';\n\nconst CHARS_PER_TOKEN = 4;\n\nlet encoder: ReturnType<typeof encodingForModel> | null = null;\n\nfunction getEncoder() {\n if (!encoder) {\n encoder = encodingForModel('claude-3-5-sonnet-20241022' as Parameters<typeof encodingForModel>[0]);\n }\n return encoder;\n}\n\nexport function countTokensTiktoken(text: string): number {\n try {\n const enc = getEncoder();\n const tokens = enc.encode(text);\n return tokens.length;\n } catch {\n return Math.ceil(text.length / CHARS_PER_TOKEN);\n }\n}\n\nexport function countTokensChars4(sizeInBytes: number): number {\n return Math.ceil(sizeInBytes / CHARS_PER_TOKEN);\n}\n\nexport function estimateTokens(\n content: string,\n sizeInBytes: number,\n method: 'chars4' | 'tiktoken' = 'chars4',\n): number {\n if (method === 'tiktoken') {\n return countTokensTiktoken(content);\n }\n return countTokensChars4(sizeInBytes);\n}\n\nexport async function estimateFileTokens(\n filePath: string,\n method: 'chars4' | 'tiktoken' = 'chars4',\n): Promise<number> {\n if (method === 'chars4') {\n const s = await stat(filePath);\n return countTokensChars4(s.size);\n }\n\n try {\n const content = await readFile(filePath, 'utf-8');\n return countTokensTiktoken(content);\n } catch {\n const s = await stat(filePath);\n return countTokensChars4(s.size);\n }\n}\n\nexport function freeEncoder(): void {\n encoder = null;\n}\n","import { Project, SyntaxKind, type SourceFile, type Node } from 'ts-morph';\nimport { resolve, relative, dirname, join, basename } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport type {\n AnalyzedFile,\n ProjectGraph,\n GraphEdge,\n HubNode,\n FileCluster,\n} from '../types/engine.js';\n\nconst TS_EXTENSIONS = new Set(['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs', 'cts', 'cjs']);\n\n// ===== PROJECT CREATION =====\n\nexport function createProject(projectPath: string, filePaths: string[]): Project {\n const tsConfigPath = join(projectPath, 'tsconfig.json');\n const hasTsConfig = existsSync(tsConfigPath);\n\n const project = new Project({\n tsConfigFilePath: hasTsConfig ? tsConfigPath : undefined,\n skipAddingFilesFromTsConfig: true,\n compilerOptions: hasTsConfig\n ? undefined\n : {\n allowJs: true,\n jsx: 4 as any, // JsxEmit.ReactJSX\n esModuleInterop: true,\n moduleResolution: 100 as any, // Bundler\n },\n });\n\n const tsFiles = filePaths.filter((f) => {\n const ext = f.split('.').pop()?.toLowerCase() ?? '';\n return TS_EXTENSIONS.has(ext);\n });\n\n for (const filePath of tsFiles) {\n try {\n project.addSourceFileAtPath(filePath);\n } catch {\n // skip files that can't be parsed\n }\n }\n\n return project;\n}\n\n// ===== DEPENDENCY GRAPH =====\n\nexport function buildProjectGraph(\n projectPath: string,\n files: AnalyzedFile[],\n): ProjectGraph {\n const absPath = resolve(projectPath);\n\n const tsFiles = files\n .filter((f) => TS_EXTENSIONS.has(f.extension))\n .map((f) => f.path);\n\n if (tsFiles.length === 0) {\n return emptyGraph(files);\n }\n\n let project: Project;\n try {\n project = createProject(projectPath, tsFiles);\n } catch {\n return emptyGraph(files);\n }\n\n const edges: GraphEdge[] = [];\n const nodeSet = new Set<string>();\n\n for (const sourceFile of project.getSourceFiles()) {\n const fromRel = relative(absPath, sourceFile.getFilePath());\n if (fromRel.startsWith('..') || fromRel.includes('node_modules')) continue;\n nodeSet.add(fromRel);\n\n // Imports\n for (const imp of sourceFile.getImportDeclarations()) {\n const moduleSpecifier = imp.getModuleSpecifierValue();\n const resolved = resolveImport(sourceFile, moduleSpecifier, absPath);\n if (resolved) {\n nodeSet.add(resolved);\n edges.push({ from: fromRel, to: resolved, type: 'import' });\n }\n }\n\n // Re-exports\n for (const exp of sourceFile.getExportDeclarations()) {\n const moduleSpecifier = exp.getModuleSpecifierValue();\n if (moduleSpecifier) {\n const resolved = resolveImport(sourceFile, moduleSpecifier, absPath);\n if (resolved) {\n nodeSet.add(resolved);\n edges.push({ from: fromRel, to: resolved, type: 're-export' });\n }\n }\n }\n }\n\n const nodes = Array.from(nodeSet);\n\n // Calculate import counts\n const importedByCount = new Map<string, number>();\n const importCount = new Map<string, number>();\n\n for (const edge of edges) {\n importedByCount.set(edge.to, (importedByCount.get(edge.to) ?? 0) + 1);\n importCount.set(edge.from, (importCount.get(edge.from) ?? 0) + 1);\n }\n\n // Identify hubs using normalized in-degree centrality (Freeman, 1978).\n // centrality = in-degree / (N - 1), then combined with out-degree for a\n // \"betweenness-lite\" score: score = (in-degree × 2 + out-degree) / (N - 1 + 1)\n // This normalizes by graph size so hub detection is consistent across projects.\n const N = Math.max(nodes.length, 1);\n const hubs: HubNode[] = nodes\n .map((node) => {\n const inDeg = importedByCount.get(node) ?? 0;\n const outDeg = importCount.get(node) ?? 0;\n // Normalized centrality score (0-100 scale)\n const centrality = N > 1 ? (inDeg / (N - 1)) * 100 : 0;\n const score = Math.round(centrality + outDeg * (100 / (2 * N)));\n return {\n relativePath: node,\n dependents: inDeg,\n dependencies: outDeg,\n score: Math.min(100, score),\n };\n })\n .filter((h) => h.dependents >= 3 || h.score >= 15)\n .sort((a, b) => b.score - a.score);\n\n // Identify leaves (files that import but are not imported by anyone)\n const leaves = nodes.filter(\n (node) => (importedByCount.get(node) ?? 0) === 0 && (importCount.get(node) ?? 0) > 0,\n );\n\n // Identify orphans (files with no connections at all)\n const connectedNodes = new Set<string>();\n for (const edge of edges) {\n connectedNodes.add(edge.from);\n connectedNodes.add(edge.to);\n }\n const allFileNodes = new Set(files.map((f) => f.relativePath));\n const orphans = Array.from(allFileNodes).filter((n) => !connectedNodes.has(n));\n\n // Detect clusters using Union-Find for true connected components,\n // then refine with directory grouping for naming.\n const clusters = detectClusters(nodes, edges, files);\n\n // Enrich files with complexity (AST-based)\n enrichComplexity(project, absPath, files);\n\n return { nodes, edges, hubs, leaves, orphans, clusters };\n}\n\n// ===== CLUSTER DETECTION (Union-Find + directory naming) =====\n\nclass UnionFind {\n parent: Map<string, string>;\n rank: Map<string, number>;\n\n constructor(nodes: string[]) {\n this.parent = new Map();\n this.rank = new Map();\n for (const n of nodes) {\n this.parent.set(n, n);\n this.rank.set(n, 0);\n }\n }\n\n find(x: string): string {\n const p = this.parent.get(x);\n if (p === undefined) return x;\n if (p !== x) {\n this.parent.set(x, this.find(p)); // path compression\n }\n return this.parent.get(x)!;\n }\n\n union(a: string, b: string): void {\n const ra = this.find(a);\n const rb = this.find(b);\n if (ra === rb) return;\n const rankA = this.rank.get(ra) ?? 0;\n const rankB = this.rank.get(rb) ?? 0;\n if (rankA < rankB) {\n this.parent.set(ra, rb);\n } else if (rankA > rankB) {\n this.parent.set(rb, ra);\n } else {\n this.parent.set(rb, ra);\n this.rank.set(ra, rankA + 1);\n }\n }\n}\n\nfunction detectClusters(\n nodes: string[],\n edges: GraphEdge[],\n files: AnalyzedFile[],\n): FileCluster[] {\n // 1. Build connected components using Union-Find (O(E × α(V)))\n const uf = new UnionFind(nodes);\n for (const edge of edges) {\n uf.union(edge.from, edge.to);\n }\n\n // 2. Group by component root\n const components = new Map<string, string[]>();\n for (const node of nodes) {\n const root = uf.find(node);\n if (!components.has(root)) components.set(root, []);\n components.get(root)!.push(node);\n }\n\n // 3. For each component, derive a human-readable name from common directory prefix\n const tokenMap = new Map(files.map((f) => [f.relativePath, f.tokens]));\n const clusters: FileCluster[] = [];\n\n for (const [, groupFiles] of components) {\n if (groupFiles.length < 2) continue;\n\n // Find common directory prefix for naming\n const name = commonPrefix(groupFiles);\n const fileSet = new Set(groupFiles);\n let internalEdges = 0;\n let externalEdges = 0;\n\n for (const edge of edges) {\n const fromIn = fileSet.has(edge.from);\n const toIn = fileSet.has(edge.to);\n if (fromIn && toIn) internalEdges++;\n else if (fromIn || toIn) externalEdges++;\n }\n\n const totalEdges = internalEdges + externalEdges;\n const cohesion = totalEdges > 0 ? internalEdges / totalEdges : 0;\n const totalTokens = groupFiles.reduce((s, f) => s + (tokenMap.get(f) ?? 0), 0);\n\n clusters.push({\n id: name.replace(/[^a-zA-Z0-9]/g, '-') || `cluster-${clusters.length}`,\n name: name || `cluster-${clusters.length}`,\n files: groupFiles,\n totalTokens,\n internalEdges,\n externalEdges,\n cohesion: Math.round(cohesion * 100) / 100,\n });\n }\n\n return clusters.sort((a, b) => b.files.length - a.files.length);\n}\n\nfunction commonPrefix(paths: string[]): string {\n if (paths.length === 0) return '';\n const parts = paths.map((p) => p.split('/'));\n const prefix: string[] = [];\n for (let i = 0; i < parts[0].length - 1; i++) {\n const segment = parts[0][i];\n if (parts.every((p) => p[i] === segment)) {\n prefix.push(segment);\n } else break;\n }\n return prefix.join('/') || parts[0][0];\n}\n\n// ===== COMPLEXITY ANALYSIS =====\n\nfunction enrichComplexity(\n project: Project,\n absPath: string,\n files: AnalyzedFile[],\n): void {\n const fileMap = new Map(files.map((f) => [f.relativePath, f]));\n\n for (const sourceFile of project.getSourceFiles()) {\n const relPath = relative(absPath, sourceFile.getFilePath());\n if (relPath.startsWith('..') || relPath.includes('node_modules')) continue;\n\n const file = fileMap.get(relPath);\n if (!file) continue;\n\n let totalComplexity = 0;\n\n // Function declarations\n for (const func of sourceFile.getFunctions()) {\n totalComplexity += calculateCyclomaticComplexity(func);\n }\n\n // Class methods\n for (const cls of sourceFile.getClasses()) {\n for (const method of cls.getMethods()) {\n totalComplexity += calculateCyclomaticComplexity(method);\n }\n }\n\n // Arrow functions assigned to variables\n for (const varDecl of sourceFile.getVariableDeclarations()) {\n const init = varDecl.getInitializer();\n if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n totalComplexity += calculateCyclomaticComplexity(init);\n }\n }\n\n file.complexity = Math.max(1, totalComplexity);\n }\n}\n\nfunction calculateCyclomaticComplexity(node: Node): number {\n let complexity = 1;\n\n node.forEachDescendant((descendant) => {\n switch (descendant.getKind()) {\n case SyntaxKind.IfStatement:\n case SyntaxKind.ConditionalExpression:\n case SyntaxKind.ForStatement:\n case SyntaxKind.ForInStatement:\n case SyntaxKind.ForOfStatement:\n case SyntaxKind.WhileStatement:\n case SyntaxKind.DoStatement:\n case SyntaxKind.CaseClause:\n case SyntaxKind.CatchClause:\n complexity++;\n break;\n case SyntaxKind.BinaryExpression: {\n // FIX: Check the operator token kind directly instead of getText()\n // to avoid double-counting nested logical expressions.\n // getText() on `a && (b || c)` returns the full text including\n // the inner `||`, which would match both operators from the outer node.\n const opToken = (descendant as any).getOperatorToken?.();\n if (opToken) {\n const kind = opToken.getKind();\n if (\n kind === SyntaxKind.AmpersandAmpersandToken ||\n kind === SyntaxKind.BarBarToken ||\n kind === SyntaxKind.QuestionQuestionToken\n ) {\n complexity++;\n }\n }\n break;\n }\n }\n });\n\n return complexity;\n}\n\n// ===== IMPORT RESOLUTION =====\n\nfunction resolveImport(\n sourceFile: SourceFile,\n moduleSpecifier: string,\n projectRoot: string,\n): string | null {\n if (!moduleSpecifier.startsWith('.')) return null;\n\n const sourceDir = dirname(sourceFile.getFilePath());\n const basePath = resolve(sourceDir, moduleSpecifier);\n\n const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js', '/index.jsx'];\n\n for (const ext of extensions) {\n const candidate = basePath.endsWith(ext) ? basePath : basePath + ext;\n if (existsSync(candidate)) {\n const rel = relative(projectRoot, candidate);\n if (!rel.startsWith('..')) return rel;\n }\n }\n\n // .js → .ts resolution\n if (moduleSpecifier.endsWith('.js')) {\n const tsPath = basePath.replace(/\\.js$/, '.ts');\n if (existsSync(tsPath)) {\n const rel = relative(projectRoot, tsPath);\n if (!rel.startsWith('..')) return rel;\n }\n }\n\n return null;\n}\n\n// ===== HELPERS =====\n\nfunction emptyGraph(files: AnalyzedFile[]): ProjectGraph {\n return {\n nodes: files.map((f) => f.relativePath),\n edges: [],\n hubs: [],\n leaves: [],\n orphans: files.map((f) => f.relativePath),\n clusters: [],\n };\n}\n","import type {\n AnalyzedFile,\n RiskFactor,\n RiskFactorType,\n RiskWeights,\n ExclusionImpact,\n ProjectGraph,\n} from '../types/engine.js';\nimport { DEFAULT_RISK_WEIGHTS } from '../types/engine.js';\n\n// ===== RISK SCORING ENGINE =====\n//\n// Each file gets a riskScore ∈ [0, 100] representing the risk of EXCLUDING it\n// from AI context. Higher score = more dangerous to exclude.\n//\n// riskScore(file) = Σ(factor.score × factor.weight) / Σ(factor.weight)\n\nexport function scoreAllFiles(\n files: AnalyzedFile[],\n graph: ProjectGraph,\n weights: RiskWeights = DEFAULT_RISK_WEIGHTS,\n): void {\n // Pre-compute type provider map: files that export types used by others\n const typeProviderUsage = computeTypeProviderUsage(files, graph);\n\n for (const file of files) {\n const factors = computeRiskFactors(file, graph, typeProviderUsage, weights);\n file.riskFactors = factors;\n file.riskScore = computeWeightedScore(factors);\n file.exclusionImpact = scoreToImpact(file.riskScore);\n }\n}\n\nexport function scoreFile(\n file: AnalyzedFile,\n graph: ProjectGraph,\n weights: RiskWeights = DEFAULT_RISK_WEIGHTS,\n): number {\n const typeProviderUsage = computeTypeProviderUsage([file], graph);\n const factors = computeRiskFactors(file, graph, typeProviderUsage, weights);\n file.riskFactors = factors;\n file.riskScore = computeWeightedScore(factors);\n file.exclusionImpact = scoreToImpact(file.riskScore);\n return file.riskScore;\n}\n\n// ===== FACTOR COMPUTATION =====\n\nfunction computeRiskFactors(\n file: AnalyzedFile,\n graph: ProjectGraph,\n typeProviderUsage: Map<string, number>,\n weights: RiskWeights,\n): RiskFactor[] {\n const factors: RiskFactor[] = [];\n\n // 1. Hub factor — how many files depend on this file\n factors.push(computeHubFactor(file, weights.hub));\n\n // 2. Type provider factor — exports types used by other files\n factors.push(computeTypeProviderFactor(file, typeProviderUsage, weights.typeProvider));\n\n // 3. Complexity factor — cyclomatic complexity\n factors.push(computeComplexityFactor(file, weights.complexity));\n\n // 4. Recency factor — how recently modified\n factors.push(computeRecencyFactor(file, weights.recency));\n\n // 5. Config factor — is it a config or entry point\n factors.push(computeConfigFactor(file, weights.config));\n\n // 6. Churn factor — based on complexity as proxy (git integration deferred)\n factors.push(computeChurnFactor(file, weights.churn));\n\n return factors;\n}\n\nfunction computeHubFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const dependents = file.importedBy.length;\n\n // Logarithmic scaling: score = min(100, 100 × log₂(1 + dependents) / log₂(1 + K))\n // K=12 means 12 dependents → score 100. Based on information theory:\n // each doubling of dependents adds equal marginal risk.\n const K = 12;\n const score = dependents === 0\n ? 0\n : Math.min(100, Math.round(100 * Math.log2(1 + dependents) / Math.log2(1 + K)));\n\n const detail = dependents === 0\n ? 'No dependents'\n : `Hub: ${dependents} file(s) depend on this (score ${score}/100)`;\n\n return { type: 'hub', score, weight, detail };\n}\n\nfunction computeTypeProviderFactor(\n file: AnalyzedFile,\n usage: Map<string, number>,\n weight: number,\n): RiskFactor {\n const isTypeFile = file.kind === 'type';\n const consumers = usage.get(file.relativePath) ?? 0;\n\n let score: number;\n let detail: string;\n\n if (isTypeFile && consumers >= 4) {\n score = 100;\n detail = `Type provider: used by ${consumers} files (critical type source)`;\n } else if (isTypeFile && consumers >= 1) {\n score = 50;\n detail = `Type provider: used by ${consumers} files`;\n } else if (isTypeFile) {\n score = 30;\n detail = 'Type file (no detected consumers)';\n } else {\n score = 0;\n detail = 'Not a type provider';\n }\n\n return { type: 'type-provider', score, weight, detail };\n}\n\nfunction computeComplexityFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const c = file.complexity;\n\n // Logarithmic scaling: score = min(100, 100 × ln(1 + c) / ln(1 + K))\n // K=30 means complexity 30 → score 100. ln provides diminishing returns\n // for very complex files (consistent with McCabe 1976 thresholds).\n const K = 30;\n const score = Math.min(100, Math.round(100 * Math.log(1 + c) / Math.log(1 + K)));\n\n const detail = c >= 30\n ? `Very high complexity: ${c} (AI needs full context)`\n : c >= 10\n ? `High complexity: ${c}`\n : `Complexity: ${c}`;\n\n return { type: 'complexity', score, weight, detail };\n}\n\nfunction computeRecencyFactor(file: AnalyzedFile, weight: number): RiskFactor {\n const now = Date.now();\n const modified = new Date(file.lastModified).getTime();\n const daysAgo = (now - modified) / (1000 * 60 * 60 * 24);\n\n // Exponential decay with half-life of 7 days.\n // score = 100 × 2^(-daysAgo / halfLife)\n // This is the standard temporal decay model used in information retrieval\n // (Lv & Zhai, 2011 — \"Adaptive Relevance Feedback\").\n const HALF_LIFE = 7;\n const score = Math.round(100 * Math.pow(2, -daysAgo / HALF_LIFE));\n\n const detail = daysAgo <= 1\n ? 'Modified today'\n : `Modified ${Math.round(daysAgo)} days ago (decay score ${score})`;\n\n return { type: 'recency', score, weight, detail };\n}\n\nfunction computeConfigFactor(file: AnalyzedFile, weight: number): RiskFactor {\n let score: number;\n let detail: string;\n\n if (file.kind === 'entry') {\n score = 90;\n detail = 'Entry point — critical for understanding app structure';\n } else if (file.kind === 'config') {\n score = 80;\n detail = 'Configuration file — affects runtime behavior';\n } else {\n score = 0;\n detail = 'Regular source file';\n }\n\n return { type: 'config', score, weight, detail };\n}\n\nfunction computeChurnFactor(file: AnalyzedFile, weight: number): RiskFactor {\n // PROXY: Without git integration, approximate churn as geometric mean of\n // complexity signal and recency signal. This avoids double-weighting\n // (since complexity and recency have their own factors) by using the\n // *interaction* term only — high churn requires BOTH high complexity AND\n // recent modification simultaneously.\n //\n // TODO: Replace with real git churn (commit count in last 30 days) when\n // git integration is added. Proxy weight is intentionally low (5%).\n const complexitySignal = Math.min(file.complexity / 20, 1);\n const now = Date.now();\n const daysAgo = (now - new Date(file.lastModified).getTime()) / (1000 * 60 * 60 * 24);\n const recencySignal = Math.pow(2, -daysAgo / 7); // same half-life as recency factor\n\n // Geometric mean ensures both signals must be high for a high score\n const score = Math.round(Math.sqrt(complexitySignal * recencySignal) * 100);\n const detail = score >= 50\n ? 'Likely under active development (complex + recent)'\n : score >= 20\n ? 'Some recent activity'\n : 'Stable — low churn (proxy estimate)';\n\n return { type: 'churn', score, weight, detail };\n}\n\n// ===== HELPERS =====\n\nfunction computeWeightedScore(factors: RiskFactor[]): number {\n let totalWeightedScore = 0;\n let totalWeight = 0;\n\n for (const factor of factors) {\n totalWeightedScore += factor.score * factor.weight;\n totalWeight += factor.weight;\n }\n\n if (totalWeight === 0) return 0;\n return Math.round(totalWeightedScore / totalWeight);\n}\n\nfunction scoreToImpact(score: number): ExclusionImpact {\n if (score >= 80) return 'critical';\n if (score >= 60) return 'high';\n if (score >= 30) return 'medium';\n if (score > 0) return 'low';\n return 'none';\n}\n\nfunction computeTypeProviderUsage(\n files: AnalyzedFile[],\n graph: ProjectGraph,\n): Map<string, number> {\n const usage = new Map<string, number>();\n\n // Count how many files import each type file\n const typeFiles = new Set(\n files.filter((f) => f.kind === 'type').map((f) => f.relativePath),\n );\n\n for (const edge of graph.edges) {\n if (typeFiles.has(edge.to)) {\n usage.set(edge.to, (usage.get(edge.to) ?? 0) + 1);\n }\n }\n\n return usage;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { writeFile } from 'node:fs/promises';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { getCachedAnalysis } from '../../engine/cache.js';\nimport { generatePRContext } from '../../engine/pr-context.js';\nimport { planInteraction } from '../../interact/orchestrator.js';\n\nexport const interactCommand = new Command('interact')\n .description('Build optimized AI context for a task')\n .argument('<task>', 'Description of the task (e.g. \"refactor the auth middleware\")')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-m, --model <model>', 'Force model: claude-haiku-3.5 | claude-sonnet-4 | claude-opus-4')\n .option('--no-cot', 'Disable chain-of-thought in prompt')\n .option('--json', 'Output as JSON')\n .option('--prompt-only', 'Only show the generated prompt')\n .option('-o, --output <target>', 'Output target: stdout | file | clipboard', 'stdout')\n .option('--explain', 'Show detailed decision explanations')\n .option('--pr [branch]', 'PR mode: focus on changed files vs base branch (default: main)')\n .action(async (task: string, opts: {\n path?: string;\n budget?: string;\n model?: string;\n cot?: boolean;\n json?: boolean;\n promptOnly?: boolean;\n output?: string;\n explain?: boolean;\n pr?: string | boolean;\n }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n console.log(chalk.dim(`\\n Analyzing ${projectPath}...`));\n const analysis = await getCachedAnalysis(projectPath);\n\n // PR mode: show PR context summary before planning\n if (opts.pr !== undefined) {\n const baseBranch = typeof opts.pr === 'string' ? opts.pr : 'main';\n console.log(chalk.dim(` PR mode: comparing against ${baseBranch}...\\n`));\n const pr = await generatePRContext(analysis, { baseBranch });\n\n if (!pr.isGitRepo) {\n console.log(chalk.yellow(' ⚠️ Not a git repository. Falling back to normal mode.\\n'));\n } else if (pr.changedFiles.length === 0) {\n console.log(chalk.yellow(` ⚠️ No changed files vs ${baseBranch}. Falling back to normal mode.\\n`));\n } else {\n console.log(chalk.bold.magenta(' 📋 PR Context'));\n console.log(` Branch: ${pr.currentBranch} ← ${baseBranch}`);\n console.log(` Changed: ${pr.changedFiles.length} files | Dependencies: ${pr.dependencyFiles.length} files`);\n console.log(` Tokens: ~${Math.round(pr.totalContextTokens / 1000)}K`);\n if (pr.riskSummary.critical > 0 || pr.riskSummary.high > 0) {\n console.log(chalk.yellow(` ⚠️ ${pr.riskSummary.critical} critical + ${pr.riskSummary.high} high-risk files`));\n }\n console.log('');\n }\n }\n\n console.log(chalk.dim(` Planning interaction for: \"${task}\"\\n`));\n const plan = await planInteraction({\n task,\n analysis,\n budget,\n model: opts.model,\n enableCoT: opts.cot !== false,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(plan, null, 2));\n return;\n }\n\n if (opts.promptOnly) {\n console.log(plan.prompt.rendered);\n return;\n }\n\n // Decisions summary\n console.log(chalk.bold.cyan(' 🧠 Interaction Plan'));\n console.log('');\n\n for (const d of plan.decisions) {\n const icon = d.step === 'classify' ? '🏷️'\n : d.step === 'select-context' ? '📂'\n : d.step === 'choose-model' ? '🤖'\n : d.step === 'build-prompt' ? '📝'\n : d.step === 'estimate-cost' ? '💰'\n : '•';\n console.log(` ${icon} ${chalk.bold(d.step)}: ${d.decision}`);\n console.log(` ${chalk.dim(d.reason)}`);\n }\n console.log('');\n\n // Context summary\n console.log(chalk.bold(' Context:'));\n const ctx = plan.context;\n console.log(` Files: ${ctx.files.length} | Tokens: ~${Math.round(ctx.totalTokens / 1000)}K / ${Math.round(budget / 1000)}K (${ctx.usedPercent.toFixed(1)}%)`);\n console.log(` Coverage: ${ctx.coverage.score}% | Risk: ${ctx.riskScore}/100`);\n\n if (ctx.coverage.missingCritical.length > 0) {\n console.log(chalk.yellow(` ⚠️ Missing critical: ${ctx.coverage.missingCritical.join(', ')}`));\n }\n console.log('');\n\n // File list\n const fullFiles = ctx.files.filter((f) => f.pruneLevel === 'full');\n const sigFiles = ctx.files.filter((f) => f.pruneLevel === 'signatures');\n const skelFiles = ctx.files.filter((f) => f.pruneLevel === 'skeleton');\n\n if (fullFiles.length > 0) {\n console.log(chalk.bold(' Full content:'));\n for (const f of fullFiles) {\n console.log(` ${chalk.green('●')} ${f.relativePath} (~${Math.round(f.tokens / 1000)}K)`);\n }\n }\n if (sigFiles.length > 0) {\n console.log(chalk.bold(' Signatures:'));\n for (const f of sigFiles) {\n console.log(` ${chalk.yellow('○')} ${f.relativePath} (~${Math.round(f.tokens / 1000)}K)`);\n }\n }\n if (skelFiles.length > 0) {\n console.log(chalk.bold(' Skeleton:'));\n for (const f of skelFiles) {\n console.log(` ${chalk.dim('◌')} ${f.relativePath}`);\n }\n }\n console.log('');\n\n // Cost\n console.log(chalk.bold(' Cost Estimate:'));\n console.log(` Model: ${plan.model.model}`);\n console.log(` This interaction: ${plan.cost.formatted}`);\n console.log(` Without optimization: ${plan.cost.withoutOptimization.formatted}`);\n console.log(` ${chalk.green(plan.cost.savings.formatted)}`);\n console.log('');\n\n // Prompt stats\n console.log(chalk.bold(' Prompt:'));\n console.log(` Sections: ${plan.prompt.sections.map((s) => s.id).join(', ')}`);\n console.log(` Prompt tokens: ~${Math.round(plan.prompt.totalTokens / 1000)}K`);\n console.log('');\n\n // --explain: show detailed selection decisions\n if (opts.explain && plan.context.decisions.length > 0) {\n console.log(chalk.bold(' Decisions:'));\n for (const d of plan.context.decisions.slice(0, 20)) {\n const icon = d.action === 'exclude' ? chalk.red('✗') : chalk.green('✓');\n console.log(` ${icon} ${d.file} — ${d.reason}`);\n if (d.alternatives) {\n console.log(chalk.dim(` Alternative: ${d.alternatives}`));\n }\n }\n if (plan.context.decisions.length > 20) {\n console.log(chalk.dim(` ... and ${plan.context.decisions.length - 20} more decisions`));\n }\n console.log('');\n }\n\n // --output: save prompt to file or clipboard\n if (opts.output === 'file') {\n const outPath = join(resolve(opts.path ?? '.'), '.cto', `prompt-${plan.id}.md`);\n await writeFile(outPath, plan.prompt.rendered, 'utf-8');\n console.log(chalk.green(` 💾 Prompt saved to ${outPath}`));\n console.log('');\n } else if (opts.output === 'clipboard') {\n try {\n const { execSync } = await import('node:child_process');\n execSync('pbcopy', { input: plan.prompt.rendered });\n console.log(chalk.green(' 📋 Prompt copied to clipboard'));\n console.log('');\n } catch {\n console.log(chalk.yellow(' ⚠️ Could not copy to clipboard. Use --output file instead.'));\n console.log('');\n }\n }\n\n console.log(chalk.dim(` Use ${chalk.bold('--prompt-only')} to get the full prompt`));\n console.log(chalk.dim(` Use ${chalk.bold('--json')} for machine-readable output`));\n console.log(chalk.dim(` Use ${chalk.bold('--explain')} for detailed selection decisions`));\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n });\n","import { createHash } from 'node:crypto';\nimport { readdir, stat } from 'node:fs/promises';\nimport { join, extname, relative, resolve } from 'node:path';\nimport type { ProjectAnalysis } from '../types/engine.js';\nimport type { CTOConfig } from '../types/config.js';\nimport { DEFAULT_CONFIG } from '../types/config.js';\nimport { analyzeProject } from './analyzer.js';\n\n// ===== Analysis Cache =====\n//\n// Problem: analyzeProject() is expensive (file walk + AST parse + token count + graph build).\n// MCP tools and CLI commands call it on every invocation.\n//\n// Solution: Two-level cache with lightweight fingerprint invalidation.\n// 1. Compute a fast fingerprint: hash of (sorted file paths + mtimes)\n// Cost: O(n) readdir + stat, no file reads, no AST, no token counting\n// 2. If fingerprint matches cached entry → return cached analysis (instant)\n// 3. If fingerprint differs → full re-analysis, update cache\n//\n// TTL: Safety net. Even if fingerprint matches, expire after maxAgeMs.\n//\n// Reference: Content-addressable caching (Git object model principle)\n\ninterface CacheEntry {\n analysis: ProjectAnalysis;\n fingerprint: string;\n createdAt: number;\n hits: number;\n}\n\ninterface CacheOptions {\n maxAgeMs: number;\n maxEntries: number;\n enabled: boolean;\n}\n\nconst DEFAULT_CACHE_OPTIONS: CacheOptions = {\n maxAgeMs: 5 * 60 * 1000, // 5 minutes\n maxEntries: 10,\n enabled: true,\n};\n\n// In-memory LRU-ish cache\nconst cache = new Map<string, CacheEntry>();\nlet cacheOptions: CacheOptions = { ...DEFAULT_CACHE_OPTIONS };\n\n// ===== FINGERPRINT =====\n\n// Fast fingerprint: walk directory, collect paths + mtimes, hash them.\n// ~10-100x faster than full analysis (no file reads, no AST, no tokenization).\nasync function computeFingerprint(\n rootPath: string,\n config: CTOConfig = DEFAULT_CONFIG,\n): Promise<string> {\n const entries: string[] = [];\n const allExtensions = new Set([\n ...config.analysis.extensions.code,\n ...config.analysis.extensions.config,\n ...config.analysis.extensions.docs,\n ]);\n const ignoreDirSet = new Set(config.analysis.ignore.dirs);\n\n async function walk(dir: string, depth: number): Promise<void> {\n if (depth > config.analysis.maxDepth) return;\n\n let dirEntries;\n try {\n dirEntries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n\n const promises: Promise<void>[] = [];\n\n for (const entry of dirEntries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n if (!ignoreDirSet.has(entry.name) && !entry.name.startsWith('.')) {\n promises.push(walk(fullPath, depth + 1));\n }\n } else if (entry.isFile()) {\n const ext = extname(entry.name).slice(1).toLowerCase();\n if (ext && allExtensions.has(ext)) {\n promises.push(\n (async () => {\n try {\n const s = await stat(fullPath);\n const rel = relative(rootPath, fullPath);\n // Include path + mtime + size for change detection\n entries.push(`${rel}:${s.mtimeMs.toFixed(0)}:${s.size}`);\n } catch {\n // skip inaccessible files\n }\n })(),\n );\n }\n }\n }\n\n await Promise.all(promises);\n }\n\n await walk(rootPath, 0);\n\n // Sort for determinism\n entries.sort();\n return createHash('sha256').update(entries.join('|')).digest('hex').substring(0, 16);\n}\n\n// ===== PUBLIC API =====\n\n/**\n * Get a project analysis, using cache when possible.\n *\n * Cache hit: ~1-5ms (fingerprint check only)\n * Cache miss: full analyzeProject() + cache update\n */\nexport async function getCachedAnalysis(\n projectPath: string,\n config?: Partial<CTOConfig>,\n): Promise<ProjectAnalysis> {\n const absPath = resolve(projectPath);\n\n if (!cacheOptions.enabled) {\n return analyzeProject(absPath, config);\n }\n\n const existing = cache.get(absPath);\n\n // Check TTL first (cheap)\n if (existing) {\n const age = Date.now() - existing.createdAt;\n if (age > cacheOptions.maxAgeMs) {\n cache.delete(absPath);\n }\n }\n\n // Compute fingerprint\n const mergedConfig = config\n ? { ...DEFAULT_CONFIG, ...config } as CTOConfig\n : DEFAULT_CONFIG;\n const fingerprint = await computeFingerprint(absPath, mergedConfig);\n\n // Cache hit: fingerprint matches\n const cached = cache.get(absPath);\n if (cached && cached.fingerprint === fingerprint) {\n cached.hits++;\n return cached.analysis;\n }\n\n // Cache miss: full analysis\n const analysis = await analyzeProject(absPath, config);\n\n // Evict oldest entry if at capacity\n if (cache.size >= cacheOptions.maxEntries) {\n const oldest = [...cache.entries()].sort(\n (a, b) => a[1].createdAt - b[1].createdAt,\n )[0];\n if (oldest) cache.delete(oldest[0]);\n }\n\n cache.set(absPath, {\n analysis,\n fingerprint,\n createdAt: Date.now(),\n hits: 0,\n });\n\n return analysis;\n}\n\n/**\n * Invalidate cache for a specific project (e.g., after a known file change).\n */\nexport function invalidateCache(projectPath?: string): void {\n if (projectPath) {\n cache.delete(resolve(projectPath));\n } else {\n cache.clear();\n }\n}\n\n/**\n * Get cache statistics for debugging/monitoring.\n */\nexport function getCacheStats(): {\n entries: number;\n totalHits: number;\n projects: { path: string; hits: number; ageMs: number }[];\n} {\n const now = Date.now();\n const projects = [...cache.entries()].map(([path, entry]) => ({\n path,\n hits: entry.hits,\n ageMs: now - entry.createdAt,\n }));\n\n return {\n entries: cache.size,\n totalHits: projects.reduce((s, p) => s + p.hits, 0),\n projects,\n };\n}\n\n/**\n * Configure cache behavior.\n */\nexport function configureCache(options: Partial<CacheOptions>): void {\n cacheOptions = { ...cacheOptions, ...options };\n if (!cacheOptions.enabled) {\n cache.clear();\n }\n}\n","import { resolve } from 'node:path';\nimport { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport type { ProjectAnalysis, AnalyzedFile } from '../types/engine.js';\nimport { buildAdjacencyList, bfsBidirectional } from './graph-utils.js';\n\n// ===== PR Context — Git-diff Aware Context Selection =====\n//\n// When the task is \"review this PR\", sending the entire project is wasteful.\n// This module:\n// 1. Extracts changed files from git diff (branch comparison or working dir)\n// 2. Expands to transitive dependencies using BFS on the adjacency list\n// 3. Prioritizes by risk score (high-risk changed files first)\n// 4. Returns a structured PR context with change categorization\n//\n// Complexity: O(|changed| × depth) for BFS expansion\n\nconst exec = promisify(execFile);\n\nasync function git(args: string[], cwd: string): Promise<string> {\n try {\n const { stdout } = await exec('git', args, { cwd, maxBuffer: 10 * 1024 * 1024 });\n return stdout.trim();\n } catch {\n return '';\n }\n}\n\n// ===== TYPES =====\n\nexport type ChangeType = 'added' | 'modified' | 'deleted' | 'renamed';\n\nexport interface ChangedFile {\n relativePath: string;\n changeType: ChangeType;\n linesAdded: number;\n linesRemoved: number;\n}\n\nexport interface PRContextResult {\n baseBranch: string;\n currentBranch: string;\n isGitRepo: boolean;\n\n changedFiles: ChangedFile[];\n dependencyFiles: string[];\n allRelevantFiles: AnalyzedFile[];\n\n totalChangedTokens: number;\n totalContextTokens: number;\n\n riskSummary: {\n critical: number;\n high: number;\n medium: number;\n low: number;\n maxRiskFile: string;\n maxRiskScore: number;\n };\n\n renderedSummary: string;\n}\n\nexport interface PRContextOptions {\n baseBranch?: string;\n depth?: number;\n includeTests?: boolean;\n}\n\n// ===== GIT OPERATIONS =====\n\nasync function isGitRepo(projectPath: string): Promise<boolean> {\n const result = await git(['rev-parse', '--is-inside-work-tree'], projectPath);\n return result === 'true';\n}\n\nasync function getCurrentBranch(projectPath: string): Promise<string> {\n return git(['rev-parse', '--abbrev-ref', 'HEAD'], projectPath);\n}\n\nasync function getChangedFilesFromDiff(\n projectPath: string,\n baseBranch?: string,\n): Promise<ChangedFile[]> {\n const results = new Map<string, ChangedFile>();\n\n // Working directory changes (unstaged)\n const workingDiff = await git(['diff', '--numstat', 'HEAD'], projectPath);\n parseDiffNumstat(workingDiff, results, 'modified');\n\n // Staged changes\n const stagedDiff = await git(['diff', '--numstat', '--cached'], projectPath);\n parseDiffNumstat(stagedDiff, results, 'modified');\n\n // Untracked files\n const untracked = await git(['ls-files', '--others', '--exclude-standard'], projectPath);\n for (const line of untracked.split('\\n')) {\n const f = line.trim();\n if (f && !results.has(f)) {\n results.set(f, { relativePath: f, changeType: 'added', linesAdded: 0, linesRemoved: 0 });\n }\n }\n\n // Branch comparison (if baseBranch provided)\n if (baseBranch) {\n // Check if base branch exists\n const branchExists = await git(['rev-parse', '--verify', baseBranch], projectPath);\n if (branchExists) {\n const branchDiff = await git(['diff', '--numstat', `${baseBranch}...HEAD`], projectPath);\n parseDiffNumstat(branchDiff, results, 'modified');\n\n // Detect newly added files (in HEAD but not in base)\n const nameStatus = await git(['diff', '--name-status', `${baseBranch}...HEAD`], projectPath);\n for (const line of nameStatus.split('\\n')) {\n const parts = line.trim().split('\\t');\n if (parts.length >= 2) {\n const status = parts[0];\n const filePath = parts[parts.length - 1];\n if (results.has(filePath)) {\n const existing = results.get(filePath)!;\n if (status === 'A') existing.changeType = 'added';\n else if (status === 'D') existing.changeType = 'deleted';\n else if (status.startsWith('R')) existing.changeType = 'renamed';\n }\n }\n }\n }\n }\n\n return [...results.values()];\n}\n\nfunction parseDiffNumstat(\n output: string,\n results: Map<string, ChangedFile>,\n defaultType: ChangeType,\n): void {\n for (const line of output.split('\\n')) {\n const parts = line.trim().split('\\t');\n if (parts.length < 3) continue;\n\n const added = parts[0] === '-' ? 0 : parseInt(parts[0], 10) || 0;\n const removed = parts[1] === '-' ? 0 : parseInt(parts[1], 10) || 0;\n const filePath = parts[2];\n\n if (!filePath) continue;\n\n const existing = results.get(filePath);\n if (existing) {\n existing.linesAdded = Math.max(existing.linesAdded, added);\n existing.linesRemoved = Math.max(existing.linesRemoved, removed);\n } else {\n results.set(filePath, {\n relativePath: filePath,\n changeType: defaultType,\n linesAdded: added,\n linesRemoved: removed,\n });\n }\n }\n}\n\n// ===== MAIN API =====\n\n/**\n * Generate PR-focused context by analyzing git changes and expanding dependencies.\n *\n * @param analysis - Project analysis (from analyzeProject or getCachedAnalysis)\n * @param options - PR context options (baseBranch, depth, includeTests)\n * @returns Structured PR context with changed files, dependencies, risk summary\n */\nexport async function generatePRContext(\n analysis: ProjectAnalysis,\n options: PRContextOptions = {},\n): Promise<PRContextResult> {\n const projectPath = resolve(analysis.projectPath);\n const baseBranch = options.baseBranch ?? 'main';\n const depth = options.depth ?? 2;\n const includeTests = options.includeTests ?? false;\n\n // Check git repo\n const gitRepo = await isGitRepo(projectPath);\n if (!gitRepo) {\n return emptyResult(baseBranch);\n }\n\n const currentBranch = await getCurrentBranch(projectPath);\n\n // 1. Get changed files from git\n const changedFiles = await getChangedFilesFromDiff(projectPath, baseBranch);\n\n if (changedFiles.length === 0) {\n return {\n ...emptyResult(baseBranch),\n currentBranch,\n isGitRepo: true,\n renderedSummary: '# PR Context\\n\\nNo changed files detected.',\n };\n }\n\n // 2. Filter to files that exist in our analysis\n const analysisFileSet = new Set(analysis.files.map((f) => f.relativePath));\n const validChangedPaths = changedFiles\n .filter((c) => c.changeType !== 'deleted' && analysisFileSet.has(c.relativePath))\n .map((c) => c.relativePath);\n\n // 3. Expand dependencies using BFS on adjacency list\n const adj = buildAdjacencyList(analysis.graph.edges);\n const expanded = bfsBidirectional(validChangedPaths, adj, depth);\n\n // Separate changed files from dependency-only files\n const changedSet = new Set(validChangedPaths);\n const dependencyFiles = [...expanded].filter((f) => !changedSet.has(f));\n\n // 4. Filter tests if not included\n const allRelevantPaths = new Set(expanded);\n if (!includeTests) {\n for (const path of allRelevantPaths) {\n const file = analysis.files.find((f) => f.relativePath === path);\n if (file && file.kind === 'test') {\n // Keep if it was directly changed, remove if it's a dependency\n if (!changedSet.has(path)) {\n allRelevantPaths.delete(path);\n }\n }\n }\n }\n\n // 5. Collect AnalyzedFile objects, sorted by risk score (descending)\n const allRelevantFiles = analysis.files\n .filter((f) => allRelevantPaths.has(f.relativePath))\n .sort((a, b) => b.riskScore - a.riskScore);\n\n // 6. Compute token totals\n const changedAnalyzed = allRelevantFiles.filter((f) => changedSet.has(f.relativePath));\n const totalChangedTokens = changedAnalyzed.reduce((s, f) => s + f.tokens, 0);\n const totalContextTokens = allRelevantFiles.reduce((s, f) => s + f.tokens, 0);\n\n // 7. Risk summary\n const riskSummary = {\n critical: allRelevantFiles.filter((f) => f.riskScore >= 80).length,\n high: allRelevantFiles.filter((f) => f.riskScore >= 60 && f.riskScore < 80).length,\n medium: allRelevantFiles.filter((f) => f.riskScore >= 30 && f.riskScore < 60).length,\n low: allRelevantFiles.filter((f) => f.riskScore < 30).length,\n maxRiskFile: allRelevantFiles[0]?.relativePath ?? '',\n maxRiskScore: allRelevantFiles[0]?.riskScore ?? 0,\n };\n\n // 8. Render summary\n const renderedSummary = renderSummary(\n analysis,\n currentBranch,\n baseBranch,\n changedFiles,\n dependencyFiles,\n allRelevantFiles,\n changedSet,\n riskSummary,\n totalChangedTokens,\n totalContextTokens,\n );\n\n return {\n baseBranch,\n currentBranch,\n isGitRepo: true,\n changedFiles,\n dependencyFiles: dependencyFiles.filter((f) => allRelevantPaths.has(f)),\n allRelevantFiles,\n totalChangedTokens,\n totalContextTokens,\n riskSummary,\n renderedSummary,\n };\n}\n\n// ===== RENDERING =====\n\nfunction renderSummary(\n analysis: ProjectAnalysis,\n currentBranch: string,\n baseBranch: string,\n changedFiles: ChangedFile[],\n dependencyFiles: string[],\n allRelevant: AnalyzedFile[],\n changedSet: Set<string>,\n risk: PRContextResult['riskSummary'],\n changedTokens: number,\n totalTokens: number,\n): string {\n const lines: string[] = [];\n\n lines.push(`## PR Context — ${analysis.projectName}`);\n lines.push('');\n lines.push(`**Branch:** ${currentBranch} ← ${baseBranch}`);\n lines.push(`**Changed:** ${changedFiles.length} files | **Dependencies:** ${dependencyFiles.length} files`);\n lines.push(`**Tokens:** ~${Math.round(changedTokens / 1000)}K changed + ~${Math.round((totalTokens - changedTokens) / 1000)}K context = ~${Math.round(totalTokens / 1000)}K total`);\n lines.push('');\n\n // Risk banner\n if (risk.critical > 0 || risk.high > 0) {\n lines.push(`⚠️ **Risk:** ${risk.critical} critical + ${risk.high} high-risk files affected`);\n lines.push(`**Highest risk:** ${risk.maxRiskFile} (score: ${risk.maxRiskScore})`);\n lines.push('');\n }\n\n // Changed files\n lines.push('### Changed Files');\n lines.push('');\n\n const sortedChanged = changedFiles\n .filter((c) => c.changeType !== 'deleted')\n .sort((a, b) => {\n const fa = allRelevant.find((f) => f.relativePath === a.relativePath);\n const fb = allRelevant.find((f) => f.relativePath === b.relativePath);\n return (fb?.riskScore ?? 0) - (fa?.riskScore ?? 0);\n });\n\n for (const c of sortedChanged) {\n const file = allRelevant.find((f) => f.relativePath === c.relativePath);\n const risk = file ? ` risk:${file.riskScore}` : '';\n const delta = c.linesAdded || c.linesRemoved\n ? ` (+${c.linesAdded}/-${c.linesRemoved})`\n : '';\n const badge = c.changeType === 'added' ? ' 🆕' : c.changeType === 'renamed' ? ' 📝' : '';\n lines.push(`- \\`${c.relativePath}\\`${delta}${risk}${badge}`);\n }\n\n // Deleted files\n const deleted = changedFiles.filter((c) => c.changeType === 'deleted');\n if (deleted.length > 0) {\n lines.push('');\n lines.push(`**Deleted:** ${deleted.map((d) => `\\`${d.relativePath}\\``).join(', ')}`);\n }\n\n // Dependencies\n if (dependencyFiles.length > 0) {\n lines.push('');\n lines.push('### Dependencies (included for context)');\n lines.push('');\n\n const depWithInfo = dependencyFiles\n .map((d) => {\n const file = allRelevant.find((f) => f.relativePath === d);\n return { path: d, riskScore: file?.riskScore ?? 0, tokens: file?.tokens ?? 0 };\n })\n .sort((a, b) => b.riskScore - a.riskScore);\n\n for (const d of depWithInfo) {\n lines.push(`- \\`${d.path}\\` risk:${d.riskScore} ~${Math.round(d.tokens / 1000)}K tokens`);\n }\n }\n\n lines.push('');\n lines.push('### Review Focus');\n lines.push('');\n lines.push('- Review changed files for correctness, especially high-risk files');\n lines.push('- Dependencies are included for type/interface context — not for review');\n lines.push(`- ${analysis.totalFiles - allRelevant.length} files excluded (not affected by this change)`);\n\n return lines.join('\\n');\n}\n\n// ===== HELPERS =====\n\nfunction emptyResult(baseBranch: string): PRContextResult {\n return {\n baseBranch,\n currentBranch: '',\n isGitRepo: false,\n changedFiles: [],\n dependencyFiles: [],\n allRelevantFiles: [],\n totalChangedTokens: 0,\n totalContextTokens: 0,\n riskSummary: { critical: 0, high: 0, medium: 0, low: 0, maxRiskFile: '', maxRiskScore: 0 },\n renderedSummary: '# PR Context\\n\\nNot a git repository.',\n };\n}\n","import type { GraphEdge } from '../types/engine.js';\n\n// ===== SHARED GRAPH UTILITIES =====\n\nexport interface AdjacencyList {\n forward: Map<string, string[]>; // file → files it imports\n reverse: Map<string, string[]>; // file → files that import it\n}\n\nexport function buildAdjacencyList(edges: GraphEdge[]): AdjacencyList {\n const forward = new Map<string, string[]>();\n const reverse = new Map<string, string[]>();\n\n for (const edge of edges) {\n if (!forward.has(edge.from)) forward.set(edge.from, []);\n forward.get(edge.from)!.push(edge.to);\n\n if (!reverse.has(edge.to)) reverse.set(edge.to, []);\n reverse.get(edge.to)!.push(edge.from);\n }\n\n return { forward, reverse };\n}\n\nexport function bfsBidirectional(\n seeds: string[],\n adj: AdjacencyList,\n depth: number,\n): Set<string> {\n const result = new Set(seeds);\n let frontier = [...seeds];\n const visited = new Set<string>();\n\n for (let d = 0; d < depth; d++) {\n const nextFrontier: string[] = [];\n\n for (const node of frontier) {\n if (visited.has(node)) continue;\n visited.add(node);\n\n // Forward neighbors (imports)\n const fwd = adj.forward.get(node);\n if (fwd) {\n for (const neighbor of fwd) {\n if (!visited.has(neighbor)) {\n result.add(neighbor);\n nextFrontier.push(neighbor);\n }\n }\n }\n\n // Reverse neighbors (imported by)\n const rev = adj.reverse.get(node);\n if (rev) {\n for (const neighbor of rev) {\n if (!visited.has(neighbor)) {\n result.add(neighbor);\n nextFrontier.push(neighbor);\n }\n }\n }\n }\n\n frontier = nextFrontier;\n }\n\n return result;\n}\n\nexport function matchGlob(path: string, pattern: string): boolean {\n const regexStr = pattern\n .replace(/\\./g, '\\\\.')\n .replace(/\\*\\*/g, '§§')\n .replace(/\\*/g, '[^/]*')\n .replace(/§§/g, '.*')\n .replace(/\\?/g, '.');\n\n try {\n return new RegExp(`^${regexStr}$`).test(path);\n } catch {\n return false;\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { InteractionPlan, PlanDecision, TaskType } from '../types/interact.js';\nimport type { ProjectAnalysis } from '../types/engine.js';\nimport type { PolicySet } from '../types/govern.js';\nimport { selectContext } from '../engine/selector.js';\nimport { classifyTask, routeModel } from './router.js';\nimport { estimateCost } from './estimator.js';\nimport { buildPrompt } from './prompt.js';\nimport { logAudit } from '../govern/audit.js';\n\n// ===== INTERACTION ORCHESTRATOR =====\n//\n// The brain of CTO v2. Given a task description:\n// 1. Classify task type\n// 2. Select optimal context (deterministic)\n// 3. Choose best model\n// 4. Build structured prompt\n// 5. Estimate cost\n// 6. Explain all decisions\n\nexport interface OrchestratorInput {\n task: string;\n analysis: ProjectAnalysis;\n budget?: number;\n model?: string;\n policies?: PolicySet;\n depth?: number;\n enableCoT?: boolean;\n enableConstraints?: boolean;\n enableAntiHallucination?: boolean;\n}\n\nexport async function planInteraction(input: OrchestratorInput): Promise<InteractionPlan> {\n const {\n task,\n analysis,\n budget = 50_000,\n model: preferredModel,\n policies,\n depth = 2,\n enableCoT = true,\n enableConstraints = true,\n enableAntiHallucination = true,\n } = input;\n\n const decisions: PlanDecision[] = [];\n\n // 1. CLASSIFY task\n const taskType: TaskType = classifyTask(task);\n decisions.push({\n step: 'classify',\n decision: taskType,\n reason: `Task classified as \"${taskType}\" based on keyword analysis`,\n data: { task, taskType },\n });\n\n // 2. SELECT context (deterministic)\n const context = await selectContext({\n task,\n analysis,\n budget,\n policies,\n depth,\n });\n\n decisions.push({\n step: 'select-context',\n decision: `${context.files.length} files selected (${context.totalTokens} tokens)`,\n reason: `Coverage: ${context.coverage.score}%, Risk: ${context.riskScore}/100`,\n data: {\n filesIncluded: context.files.length,\n tokensUsed: context.totalTokens,\n budget,\n coverage: context.coverage.score,\n risk: context.riskScore,\n },\n });\n\n // 3. CHOOSE model\n const modelChoice = routeModel(taskType, analysis, preferredModel);\n decisions.push({\n step: 'choose-model',\n decision: modelChoice.model,\n reason: modelChoice.reason,\n data: {\n confidence: modelChoice.confidence,\n alternatives: modelChoice.alternatives.length,\n },\n });\n\n // 4. BUILD prompt\n const prompt = buildPrompt({\n task,\n taskType,\n analysis,\n selection: context,\n enableCoT,\n enableConstraints,\n enableAntiHallucination,\n });\n\n decisions.push({\n step: 'build-prompt',\n decision: `${prompt.sections.length} sections, ${prompt.totalTokens} tokens`,\n reason: `Sections: ${prompt.sections.map((s) => s.id).join(', ')}`,\n });\n\n // 5. ESTIMATE cost\n const cost = estimateCost(\n modelChoice.model,\n context.totalTokens + prompt.totalTokens,\n analysis.totalTokens,\n );\n\n decisions.push({\n step: 'estimate-cost',\n decision: cost.formatted,\n reason: cost.savings.formatted,\n data: {\n inputTokens: cost.inputTokens,\n totalCost: cost.totalCost,\n savings: cost.savings.percent,\n },\n });\n\n const plan: InteractionPlan = {\n id: randomUUID().substring(0, 8),\n task,\n taskType,\n timestamp: new Date(),\n context,\n model: modelChoice,\n prompt,\n cost,\n decisions,\n };\n\n // 6. AUDIT LOG — record this interaction for governance\n try {\n await logAudit('interact', analysis.projectPath, {\n interactionId: plan.id,\n task,\n taskType,\n contextHash: context.hash,\n filesIncluded: context.files.length,\n filesExcluded: analysis.totalFiles - context.files.length,\n tokensUsed: context.totalTokens,\n coverageScore: context.coverage.score,\n riskScore: context.riskScore,\n model: modelChoice.model,\n estimatedCost: cost.totalCost,\n });\n } catch {\n // Audit failure should never block the interaction pipeline\n }\n\n return plan;\n}\n","import { createHash } from 'node:crypto';\nimport type {\n AnalyzedFile,\n ProjectAnalysis,\n ContextSelection,\n SelectedFile,\n SelectionDecision,\n PruneLevel,\n CoverageResult,\n} from '../types/engine.js';\nimport type { PolicySet, PolicyRule } from '../types/govern.js';\nimport { scanFileForSecrets } from '../govern/secrets.js';\nimport { pruneFile } from './pruner.js';\nimport { calculateCoverage } from './coverage.js';\nimport { getPruneLevelForRisk } from './budget.js';\nimport { buildAdjacencyList, bfsBidirectional, matchGlob } from './graph-utils.js';\n\n// ===== DETERMINISTIC CONTEXT SELECTION =====\n//\n// Given a task, analysis, budget, and policies → always returns the same file set.\n// No randomness, no heuristics that change over time.\n//\n// Algorithm:\n// 1. Identify target files from task description\n// 2. Expand via dependency graph (BFS, depth=2)\n// 3. Apply policies (include-always, exclude-always)\n// 4. Score & rank by riskScore\n// 5. Greedy allocation with cascading prune levels\n// 6. Validate policies\n// 7. Calculate coverage score\n// 8. Hash for reproducibility\n\nexport interface SelectionInput {\n task: string;\n analysis: ProjectAnalysis;\n budget: number;\n policies?: PolicySet;\n depth?: number;\n}\n\nexport async function selectContext(input: SelectionInput): Promise<ContextSelection> {\n const { task, analysis, budget, policies, depth = 2 } = input;\n const decisions: SelectionDecision[] = [];\n\n // 1. Identify target files from task description\n const targetPaths = identifyTargetFiles(task, analysis.files);\n if (targetPaths.length > 0) {\n decisions.push({\n file: targetPaths.join(', '),\n action: 'include-full',\n reason: `Target file(s) identified from task description`,\n });\n }\n\n // 2. Expand via dependency graph (O(V+E) using adjacency list)\n const adj = buildAdjacencyList(analysis.graph.edges);\n const expandedPaths = targetPaths.length > 0\n ? Array.from(bfsBidirectional(targetPaths, adj, depth))\n : [];\n const expansionCount = expandedPaths.length - targetPaths.length;\n if (expansionCount > 0) {\n decisions.push({\n file: `${expansionCount} dependencies`,\n action: 'include-full',\n reason: `Expanded ${targetPaths.length} target(s) to ${expandedPaths.length} files via dependency graph (depth ${depth})`,\n });\n }\n\n // 2b. Add type providers of expanded files as candidates.\n // This aligns with coverage.ts which counts type providers as \"relevant\".\n // Without this, coverage would flag missing critical type files that the\n // selector never considered as candidates — a consistency bug.\n const allFileMap = new Map(analysis.files.map((f) => [f.relativePath, f]));\n if (targetPaths.length > 0) {\n for (const path of expandedPaths) {\n const file = allFileMap.get(path);\n if (!file) continue;\n for (const imp of file.imports) {\n const impFile = allFileMap.get(imp);\n if (impFile && impFile.kind === 'type') {\n expandedPaths.push(imp);\n }\n }\n }\n }\n\n // 3. Apply policies\n const { mustInclude, mustExclude } = applyPolicies(analysis.files, policies);\n\n // Merge: targets + expanded + must-include → candidate set\n const candidateSet = new Set([...expandedPaths, ...mustInclude]);\n\n // If no targets identified, use all files (filtered by exclude)\n if (targetPaths.length === 0) {\n for (const f of analysis.files) {\n candidateSet.add(f.relativePath);\n }\n }\n\n // Remove must-exclude\n for (const ex of mustExclude) {\n candidateSet.delete(ex);\n decisions.push({\n file: ex,\n action: 'exclude',\n reason: 'Excluded by policy',\n });\n }\n\n // 3b. secret-block: scan candidate files for secrets and exclude them\n const hasSecretBlock = policies?.rules.some(\n (r) => r.type === 'secret-block' && r.enabled,\n );\n if (hasSecretBlock) {\n for (const path of Array.from(candidateSet)) {\n const file = allFileMap.get(path);\n if (!file) continue;\n const findings = await scanFileForSecrets(\n file.path,\n analysis.projectPath,\n );\n if (findings.length > 0) {\n candidateSet.delete(path);\n decisions.push({\n file: path,\n action: 'exclude',\n reason: `Blocked: ${findings.length} secret(s) detected (${findings.map((f) => f.type).join(', ')})`,\n });\n }\n }\n }\n\n // 4. Sort candidates by riskScore descending\n const candidates = Array.from(candidateSet)\n .map((p) => allFileMap.get(p))\n .filter((f): f is AnalyzedFile => f !== undefined)\n .sort((a, b) => {\n // Targets always first\n const aIsTarget = targetPaths.includes(a.relativePath) ? 0 : 1;\n const bIsTarget = targetPaths.includes(b.relativePath) ? 0 : 1;\n if (aIsTarget !== bIsTarget) return aIsTarget - bIsTarget;\n\n // Then must-include\n const aIsMust = mustInclude.has(a.relativePath) ? 0 : 1;\n const bIsMust = mustInclude.has(b.relativePath) ? 0 : 1;\n if (aIsMust !== bIsMust) return aIsMust - bIsMust;\n\n // Then by riskScore\n return b.riskScore - a.riskScore;\n });\n\n // 5. Greedy allocation with cascading prune levels\n const selectedFiles: SelectedFile[] = [];\n let usedTokens = 0;\n\n for (const file of candidates) {\n const isTarget = targetPaths.includes(file.relativePath);\n const isMustInclude = mustInclude.has(file.relativePath);\n const defaultLevel = isTarget ? 'full' : getPruneLevelForRisk(file.riskScore);\n const levels = getCascadeLevels(defaultLevel);\n\n let included = false;\n\n for (const level of levels) {\n if (level === 'excluded') break;\n\n let tokens: number;\n if (level === 'full') {\n tokens = file.tokens;\n } else {\n const pruned = await pruneFile(file, level);\n tokens = pruned.prunedTokens;\n }\n\n if (usedTokens + tokens <= budget) {\n usedTokens += tokens;\n selectedFiles.push({\n relativePath: file.relativePath,\n tokens,\n originalTokens: file.tokens,\n pruneLevel: level,\n riskScore: file.riskScore,\n reason: buildReason(file, level, isTarget, isMustInclude),\n });\n\n if (level !== defaultLevel) {\n decisions.push({\n file: file.relativePath,\n action: `include-${level}` as SelectionDecision['action'],\n reason: `Downgraded from ${defaultLevel} to ${level} due to budget constraint`,\n alternatives: `Would need ${file.tokens - tokens} more tokens for ${defaultLevel}`,\n });\n }\n\n included = true;\n break;\n }\n }\n\n if (!included) {\n decisions.push({\n file: file.relativePath,\n action: 'exclude',\n reason: `Budget exhausted (risk: ${file.riskScore}, needs ${file.tokens} tokens)`,\n });\n }\n }\n\n // 6. Calculate coverage\n const includedPaths = selectedFiles.map((f) => f.relativePath);\n const coverage = calculateCoverage(\n targetPaths,\n includedPaths,\n analysis.files,\n analysis.graph,\n depth,\n );\n\n // 7. Calculate overall risk of the selection (lower = better)\n const includedSet = new Set(includedPaths);\n const excludedFiles = analysis.files.filter(\n (f) => !includedSet.has(f.relativePath),\n );\n const excludedRisk = excludedFiles.length > 0\n ? Math.round(excludedFiles.reduce((s, f) => s + f.riskScore, 0) / excludedFiles.length)\n : 0;\n\n // 8. Hash for determinism\n const hashInput = selectedFiles\n .map((f) => `${f.relativePath}:${f.pruneLevel}`)\n .sort()\n .join('|') + `|budget:${budget}`;\n const hash = createHash('sha256').update(hashInput).digest('hex').substring(0, 16);\n\n return {\n files: selectedFiles,\n totalTokens: usedTokens,\n budget,\n usedPercent: budget > 0 ? Math.round((usedTokens / budget) * 100 * 10) / 10 : 0,\n coverage,\n riskScore: excludedRisk,\n deterministic: true,\n hash,\n decisions,\n };\n}\n\n// ===== TARGET IDENTIFICATION =====\n\nfunction identifyTargetFiles(task: string, files: AnalyzedFile[]): string[] {\n const targets: string[] = [];\n\n // Extract file paths mentioned in the task\n // Matches patterns like: src/foo/bar.ts, ./utils.js, components/Header.tsx\n const pathPattern = /(?:^|\\s|[\"'`])([.\\w/-]+\\.[a-zA-Z]{1,4})(?:\\s|$|[\"'`]|,|:)/g;\n let match: RegExpExecArray | null;\n\n while ((match = pathPattern.exec(task)) !== null) {\n const candidate = match[1];\n // Find matching file\n const found = files.find(\n (f) => f.relativePath === candidate || f.relativePath.endsWith(candidate),\n );\n if (found && !targets.includes(found.relativePath)) {\n targets.push(found.relativePath);\n }\n }\n\n return targets;\n}\n\n// ===== POLICY APPLICATION =====\n\nfunction applyPolicies(\n files: AnalyzedFile[],\n policies?: PolicySet,\n): { mustInclude: Set<string>; mustExclude: Set<string> } {\n const mustInclude = new Set<string>();\n const mustExclude = new Set<string>();\n\n if (!policies) return { mustInclude, mustExclude };\n\n for (const rule of policies.rules) {\n if (!rule.enabled) continue;\n\n if (rule.type === 'include-always' && rule.pattern) {\n for (const file of files) {\n if (matchGlob(file.relativePath, rule.pattern)) {\n mustInclude.add(file.relativePath);\n }\n }\n }\n\n if (rule.type === 'exclude-always' && rule.pattern) {\n for (const file of files) {\n if (matchGlob(file.relativePath, rule.pattern)) {\n mustExclude.add(file.relativePath);\n }\n }\n }\n\n // secret-block is handled separately in applyPoliciesAsync\n // because it requires file I/O (scanning file contents)\n }\n\n return { mustInclude, mustExclude };\n}\n\n// ===== HELPERS =====\n\nfunction getCascadeLevels(startLevel: PruneLevel): PruneLevel[] {\n const all: PruneLevel[] = ['full', 'signatures', 'skeleton', 'excluded'];\n const startIdx = all.indexOf(startLevel);\n return all.slice(startIdx);\n}\n\nfunction buildReason(\n file: AnalyzedFile,\n level: PruneLevel,\n isTarget: boolean,\n isMustInclude: boolean,\n): string {\n if (isTarget) return 'Target file';\n if (isMustInclude) return 'Required by policy';\n\n const impact = file.exclusionImpact;\n const levelStr = level === 'full' ? 'full content' : level;\n\n if (impact === 'critical') return `Critical dependency (risk ${file.riskScore}) — ${levelStr}`;\n if (impact === 'high') return `High-risk dependency (risk ${file.riskScore}) — ${levelStr}`;\n if (impact === 'medium') return `Medium relevance (risk ${file.riskScore}) — ${levelStr}`;\n return `Low relevance (risk ${file.riskScore}) — ${levelStr}`;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve, relative } from 'node:path';\nimport type { SecretFinding, SecretType } from '../types/govern.js';\n\n// ===== SECRET DETECTION ENGINE =====\n\ninterface SecretPattern {\n type: SecretType;\n pattern: RegExp;\n severity: SecretFinding['severity'];\n description: string;\n}\n\nconst BUILTIN_PATTERNS: { type: SecretType; source: string; flags: string; severity: SecretFinding['severity']; description: string }[] = [\n // API Keys\n { type: 'api-key', source: '(?:api[_-]?key|apikey)\\\\s*[:=]\\\\s*[\\'\"]?([a-zA-Z0-9_\\\\-]{20,})[\\'\"]?', flags: 'gi', severity: 'critical', description: 'API Key' },\n { type: 'api-key', source: 'sk-[a-zA-Z0-9]{20,}', flags: 'g', severity: 'critical', description: 'OpenAI/Anthropic API Key' },\n { type: 'api-key', source: 'sk-ant-[a-zA-Z0-9\\\\-]{20,}', flags: 'g', severity: 'critical', description: 'Anthropic API Key' },\n\n // AWS\n { type: 'aws-key', source: 'AKIA[0-9A-Z]{16}', flags: 'g', severity: 'critical', description: 'AWS Access Key ID' },\n { type: 'aws-key', source: '(?:aws_secret_access_key|aws_secret)\\\\s*[:=]\\\\s*[\\'\"]?([a-zA-Z0-9/+=]{40})[\\'\"]?', flags: 'gi', severity: 'critical', description: 'AWS Secret Key' },\n\n // Private Keys\n { type: 'private-key', source: '-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----', flags: 'g', severity: 'critical', description: 'Private Key' },\n { type: 'private-key', source: '-----BEGIN OPENSSH PRIVATE KEY-----', flags: 'g', severity: 'critical', description: 'SSH Private Key' },\n\n // Passwords\n { type: 'password', source: '(?:password|passwd|pwd)\\\\s*[:=]\\\\s*[\\'\"]([^\\'\"]{8,})[\\'\"](?!\\\\s*\\\\{)', flags: 'gi', severity: 'high', description: 'Hardcoded Password' },\n { type: 'password', source: '(?:DB_PASSWORD|DATABASE_PASSWORD|MYSQL_PASSWORD|POSTGRES_PASSWORD)\\\\s*[:=]\\\\s*[\\'\"]?([^\\'\"{}\\\\s]{4,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Database Password' },\n\n // Tokens\n { type: 'token', source: '(?:bearer|token|auth_token|access_token|refresh_token)\\\\s*[:=]\\\\s*[\\'\"]([a-zA-Z0-9_\\\\-.]{20,})[\\'\"](?!\\\\s*\\\\{)', flags: 'gi', severity: 'high', description: 'Auth Token' },\n { type: 'token', source: 'ghp_[a-zA-Z0-9]{36}', flags: 'g', severity: 'critical', description: 'GitHub Personal Access Token' },\n { type: 'token', source: 'gho_[a-zA-Z0-9]{36}', flags: 'g', severity: 'critical', description: 'GitHub OAuth Token' },\n { type: 'token', source: 'glpat-[a-zA-Z0-9\\\\-]{20,}', flags: 'g', severity: 'critical', description: 'GitLab Personal Access Token' },\n { type: 'token', source: 'npm_[a-zA-Z0-9]{36}', flags: 'g', severity: 'high', description: 'npm Token' },\n\n // Connection strings\n { type: 'connection-string', source: '(?:mongodb(?:\\\\+srv)?|postgres(?:ql)?|mysql|redis|amqp):\\\\/\\\\/[^\\\\s\\'\"]+:[^\\\\s\\'\"]+@[^\\\\s\\'\"]+', flags: 'gi', severity: 'critical', description: 'Database Connection String' },\n { type: 'connection-string', source: '(?:DATABASE_URL|REDIS_URL|MONGODB_URI)\\\\s*[:=]\\\\s*[\\'\"]?([^\\\\s\\'\"]{10,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Database URL' },\n\n // Environment variables with secrets\n { type: 'env-variable', source: '(?:SECRET|PRIVATE|ENCRYPTION)[_-]?(?:KEY|TOKEN|PASS)\\\\s*[:=]\\\\s*[\\'\"]?([^\\\\s\\'\"]{8,})[\\'\"]?', flags: 'gi', severity: 'high', description: 'Secret Environment Variable' },\n\n // Stripe\n { type: 'api-key', source: 'sk_live_[a-zA-Z0-9]{24,}', flags: 'g', severity: 'critical', description: 'Stripe Live Secret Key' },\n { type: 'api-key', source: 'pk_live_[a-zA-Z0-9]{24,}', flags: 'g', severity: 'high', description: 'Stripe Live Publishable Key' },\n { type: 'api-key', source: 'rk_live_[a-zA-Z0-9]{24,}', flags: 'g', severity: 'critical', description: 'Stripe Restricted Key' },\n\n // Slack\n { type: 'token', source: 'xoxb-[0-9]{10,}-[0-9]{10,}-[a-zA-Z0-9]{24,}', flags: 'g', severity: 'critical', description: 'Slack Bot Token' },\n { type: 'token', source: 'xoxp-[0-9]{10,}-[0-9]{10,}-[a-zA-Z0-9]{24,}', flags: 'g', severity: 'critical', description: 'Slack User Token' },\n { type: 'api-key', source: 'https://hooks\\\\.slack\\\\.com/services/T[a-zA-Z0-9_]+/B[a-zA-Z0-9_]+/[a-zA-Z0-9_]+', flags: 'g', severity: 'high', description: 'Slack Webhook URL' },\n\n // Google\n { type: 'api-key', source: 'AIza[0-9A-Za-z_-]{35}', flags: 'g', severity: 'high', description: 'Google API Key' },\n { type: 'token', source: 'ya29\\\\.[0-9A-Za-z_-]+', flags: 'g', severity: 'high', description: 'Google OAuth Token' },\n\n // Azure\n { type: 'api-key', source: '(?:AccountKey|SharedAccessKey)\\\\s*=\\\\s*[a-zA-Z0-9+/=]{40,}', flags: 'g', severity: 'critical', description: 'Azure Storage Key' },\n\n // Twilio\n { type: 'api-key', source: 'AC[a-f0-9]{32}', flags: 'g', severity: 'high', description: 'Twilio Account SID' },\n\n // SendGrid\n { type: 'api-key', source: 'SG\\\\.[a-zA-Z0-9_-]{22}\\\\.[a-zA-Z0-9_-]{43}', flags: 'g', severity: 'critical', description: 'SendGrid API Key' },\n\n // JWT\n { type: 'token', source: 'eyJ[a-zA-Z0-9_-]{10,}\\\\.eyJ[a-zA-Z0-9_-]{10,}\\\\.[a-zA-Z0-9_-]{10,}', flags: 'g', severity: 'high', description: 'JSON Web Token' },\n\n // PII\n { type: 'pii', source: '\\\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\\.[A-Z|a-z]{2,}\\\\b', flags: 'g', severity: 'medium', description: 'Email Address (PII)' },\n { type: 'pii', source: '\\\\b\\\\d{3}[-.]?\\\\d{2}[-.]?\\\\d{4}\\\\b', flags: 'g', severity: 'high', description: 'Possible SSN (PII)' },\n];\n\nfunction buildPatterns(customPatterns: string[] = []): SecretPattern[] {\n const patterns: SecretPattern[] = BUILTIN_PATTERNS.map((def) => ({\n type: def.type,\n pattern: new RegExp(def.source, def.flags),\n severity: def.severity,\n description: def.description,\n }));\n\n for (const custom of customPatterns) {\n try {\n patterns.push({\n type: 'custom',\n pattern: new RegExp(custom, 'gi'),\n severity: 'medium',\n description: `Custom pattern: ${custom}`,\n });\n } catch { /* skip invalid regex */ }\n }\n\n return patterns;\n}\n\nexport function scanContentForSecrets(\n content: string,\n filePath: string,\n customPatterns: string[] = [],\n): SecretFinding[] {\n const findings: SecretFinding[] = [];\n const lines = content.split('\\n');\n const allPatterns = buildPatterns(customPatterns);\n\n for (const secretPattern of allPatterns) {\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n secretPattern.pattern.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = secretPattern.pattern.exec(line)) !== null) {\n const matchText = match[0];\n if (isTemplateOrPlaceholder(matchText)) continue;\n\n findings.push({\n type: secretPattern.type,\n file: filePath,\n line: i + 1,\n match: matchText,\n redacted: redactSecret(matchText),\n severity: secretPattern.severity,\n });\n }\n }\n }\n\n return deduplicateFindings(findings);\n}\n\nexport async function scanFileForSecrets(\n filePath: string,\n projectPath: string,\n customPatterns: string[] = [],\n): Promise<SecretFinding[]> {\n try {\n const content = await readFile(filePath, 'utf-8');\n const relPath = relative(resolve(projectPath), resolve(filePath));\n return scanContentForSecrets(content, relPath, customPatterns);\n } catch {\n return [];\n }\n}\n\nexport async function scanProjectForSecrets(\n projectPath: string,\n filePaths: string[],\n customPatterns: string[] = [],\n): Promise<SecretFinding[]> {\n const allFindings: SecretFinding[] = [];\n\n for (const fp of filePaths) {\n const findings = await scanFileForSecrets(fp, projectPath, customPatterns);\n allFindings.push(...findings);\n }\n\n return allFindings.sort((a, b) => {\n const severityOrder = { critical: 0, high: 1, medium: 2, low: 3 };\n return severityOrder[a.severity] - severityOrder[b.severity];\n });\n}\n\nexport function sanitizeContent(content: string, customPatterns: string[] = []): string {\n let sanitized = content;\n const allPatterns = buildPatterns(customPatterns);\n\n for (const secretPattern of allPatterns) {\n sanitized = sanitized.replace(secretPattern.pattern, (match) => {\n if (isTemplateOrPlaceholder(match)) return match;\n return redactSecret(match);\n });\n }\n\n return sanitized;\n}\n\nfunction redactSecret(value: string): string {\n if (value.length <= 8) return '***REDACTED***';\n const prefix = value.substring(0, 4);\n const suffix = value.substring(value.length - 2);\n return `${prefix}${'*'.repeat(Math.min(value.length - 6, 20))}${suffix}`;\n}\n\nfunction isTemplateOrPlaceholder(value: string): boolean {\n const placeholders = [\n /\\$\\{.*\\}/, /\\{\\{.*\\}\\}/, /%[sd]/, /<[A-Z_]+>/, /YOUR_.*_HERE/i,\n /\\bCHANGE_ME\\b/i, /\\bPLACEHOLDER\\b/i, /\\bexample\\b/i, /\\bTODO\\b/i, /xxx+/i,\n /\\breplace.?me\\b/i, /\\bdummy\\b/i, /\\btest_?key\\b/i, /\\bsample\\b/i,\n ];\n return placeholders.some((p) => p.test(value));\n}\n\nfunction deduplicateFindings(findings: SecretFinding[]): SecretFinding[] {\n const seen = new Set<string>();\n return findings.filter((f) => {\n const key = `${f.file}:${f.line}:${f.type}:${f.match}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\n// ===== ENTROPY ANALYSIS =====\n\nfunction shannonEntropy(str: string): number {\n const freq = new Map<string, number>();\n for (const ch of str) {\n freq.set(ch, (freq.get(ch) || 0) + 1);\n }\n let entropy = 0;\n for (const count of freq.values()) {\n const p = count / str.length;\n if (p > 0) entropy -= p * Math.log2(p);\n }\n return entropy;\n}\n\nconst HIGH_ENTROPY_RE = /['\"]([a-zA-Z0-9+/=_\\-]{30,})['\"]|=\\s*['\"]?([a-zA-Z0-9+/=_\\-]{30,})['\"]?/g;\n\nconst ENTROPY_SKIP = [\n /^[a-f0-9]{32,}$/i, // hex hashes\n /^[A-Z_]{30,}$/, // all-caps constants\n /^[a-z_]{30,}$/, // all-lowercase identifiers\n /^[a-zA-Z0-9+/]+=+$/, // base64 padding\n /^[a-z]+[A-Z][a-zA-Z]+$/, // camelCase identifiers\n /sha\\d+-/i, // integrity hashes (sha256-, sha512-)\n];\n\nexport function scanContentForHighEntropy(\n content: string,\n filePath: string,\n threshold: number = 5.0,\n): SecretFinding[] {\n const findings: SecretFinding[] = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line.trim().startsWith('//') || line.trim().startsWith('#') || line.trim().startsWith('*')) continue;\n\n HIGH_ENTROPY_RE.lastIndex = 0;\n let match: RegExpExecArray | null;\n\n while ((match = HIGH_ENTROPY_RE.exec(line)) !== null) {\n const value = match[1] || match[2];\n if (!value || value.length < 40) continue;\n if (isTemplateOrPlaceholder(value)) continue;\n if (ENTROPY_SKIP.some((p) => p.test(value))) continue;\n\n const entropy = shannonEntropy(value);\n if (entropy >= threshold) {\n findings.push({\n type: 'high-entropy',\n file: filePath,\n line: i + 1,\n match: value,\n redacted: redactSecret(value),\n severity: entropy >= 5.0 ? 'high' : 'medium',\n });\n }\n }\n }\n\n return deduplicateFindings(findings);\n}\n\n// ===== FULL PROJECT AUDIT =====\n\nexport interface AuditResult {\n findings: SecretFinding[];\n summary: {\n totalFiles: number;\n filesScanned: number;\n filesWithSecrets: number;\n totalFindings: number;\n bySeverity: { critical: number; high: number; medium: number; low: number };\n byType: Record<string, number>;\n };\n recommendations: string[];\n}\n\nexport async function auditProject(\n projectPath: string,\n filePaths: string[],\n options: { customPatterns?: string[]; entropyThreshold?: number; includePII?: boolean } = {},\n): Promise<AuditResult> {\n const { customPatterns = [], entropyThreshold = 4.5, includePII = true } = options;\n const allFindings: SecretFinding[] = [];\n const filesWithSecrets = new Set<string>();\n\n for (const fp of filePaths) {\n try {\n const content = await readFile(fp, 'utf-8');\n const relPath = relative(resolve(projectPath), resolve(fp));\n\n // Skip test files and declaration files for entropy (too many false positives)\n const isTestFile = /\\.(test|spec|mock)\\.[jt]sx?$/.test(relPath) || relPath.includes('__tests__');\n const isDtsFile = relPath.endsWith('.d.ts');\n\n // Pattern-based detection\n let findings = scanContentForSecrets(content, relPath, customPatterns);\n\n // Filter PII if not wanted\n if (!includePII) {\n findings = findings.filter((f) => f.type !== 'pii');\n }\n\n // Entropy-based detection (skip test/declaration files — too noisy)\n const entropyFindings = (isTestFile || isDtsFile)\n ? []\n : scanContentForHighEntropy(content, relPath, entropyThreshold);\n\n const combined = [...findings, ...entropyFindings];\n if (combined.length > 0) {\n filesWithSecrets.add(relPath);\n allFindings.push(...combined);\n }\n } catch {\n // skip unreadable files\n }\n }\n\n // Sort by severity\n allFindings.sort((a, b) => {\n const order = { critical: 0, high: 1, medium: 2, low: 3 };\n return order[a.severity] - order[b.severity];\n });\n\n // Build summary\n const bySeverity = { critical: 0, high: 0, medium: 0, low: 0 };\n const byType: Record<string, number> = {};\n for (const f of allFindings) {\n bySeverity[f.severity]++;\n byType[f.type] = (byType[f.type] || 0) + 1;\n }\n\n // Generate recommendations\n const recommendations: string[] = [];\n if (bySeverity.critical > 0) {\n recommendations.push('CRITICAL: Rotate all detected credentials immediately. They may already be compromised.');\n }\n if (byType['password'] > 0) {\n recommendations.push('Move passwords to environment variables or a secrets manager (AWS Secrets Manager, Vault, etc.).');\n }\n if (byType['api-key'] > 0 || byType['aws-key'] > 0) {\n recommendations.push('Use environment variables for API keys. Never commit them to source control.');\n }\n if (byType['connection-string'] > 0) {\n recommendations.push('Database connection strings should use environment variables, not hardcoded values.');\n }\n if (byType['private-key'] > 0) {\n recommendations.push('Private keys should NEVER be in source code. Use a key management service.');\n }\n if (byType['pii'] > 0) {\n recommendations.push('PII detected. Review for GDPR/CCPA compliance. Consider data anonymization.');\n }\n if (byType['high-entropy'] > 0) {\n recommendations.push('High-entropy strings detected that may be secrets. Review manually.');\n }\n if (allFindings.length > 0) {\n recommendations.push('Add a .gitignore entry for .env files if not already present.');\n recommendations.push('Run `npx cto-ai-cli --audit` regularly or add to CI pipeline.');\n }\n if (allFindings.length === 0) {\n recommendations.push('No secrets detected. Great job keeping your codebase clean!');\n }\n\n return {\n findings: allFindings,\n summary: {\n totalFiles: filePaths.length,\n filesScanned: filePaths.length,\n filesWithSecrets: filesWithSecrets.size,\n totalFindings: allFindings.length,\n bySeverity,\n byType,\n },\n recommendations,\n };\n}\n","import { Project, SyntaxKind, type SourceFile } from 'ts-morph';\nimport { readFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { AnalyzedFile, PruneLevel, PrunedContent } from '../types/engine.js';\nimport { countTokensChars4 } from './tokenizer.js';\n\nconst TS_EXTENSIONS = new Set(['ts', 'tsx', 'js', 'jsx', 'mts', 'mjs']);\n\n// ===== PUBLIC API =====\n\nexport async function pruneFile(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n if (level === 'excluded') {\n return emptyResult(file, 'excluded');\n }\n\n if (level === 'full') {\n return fullContent(file);\n }\n\n const ext = file.extension.toLowerCase();\n const isTS = TS_EXTENSIONS.has(ext);\n\n if (isTS) {\n return pruneTypeScript(file, level);\n }\n\n return pruneGeneric(file, level);\n}\n\nexport async function pruneFiles(\n files: AnalyzedFile[],\n levelFn: (file: AnalyzedFile) => PruneLevel,\n): Promise<PrunedContent[]> {\n const results: PrunedContent[] = [];\n\n for (const file of files) {\n const level = levelFn(file);\n const pruned = await pruneFile(file, level);\n results.push(pruned);\n }\n\n return results;\n}\n\n// ===== TYPESCRIPT AST-BASED PRUNING =====\n\nasync function pruneTypeScript(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n let content: string;\n try {\n content = await readFile(file.path, 'utf-8');\n } catch {\n return emptyResult(file, level);\n }\n\n let project: Project;\n try {\n const tsConfigPath = findTsConfig(file.path);\n project = new Project({\n tsConfigFilePath: tsConfigPath,\n skipAddingFilesFromTsConfig: true,\n compilerOptions: tsConfigPath\n ? undefined\n : { allowJs: true, esModuleInterop: true },\n });\n project.createSourceFile(file.path, content, { overwrite: true });\n } catch {\n // Fallback to generic pruning if AST fails\n return pruneGenericFromContent(file, content, level);\n }\n\n const sourceFile = project.getSourceFiles()[0];\n if (!sourceFile) {\n return pruneGenericFromContent(file, content, level);\n }\n\n const prunedContent = level === 'signatures'\n ? extractSignaturesAST(sourceFile)\n : extractSkeletonAST(sourceFile);\n\n const prunedTokens = countTokensChars4(Buffer.byteLength(prunedContent, 'utf-8'));\n const savingsPercent = file.tokens > 0 ? ((file.tokens - prunedTokens) / file.tokens) * 100 : 0;\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens,\n pruneLevel: level,\n content: prunedContent,\n savingsPercent: Math.max(0, savingsPercent),\n };\n}\n\n// ===== SIGNATURES: Keep imports, type defs, function signatures, class outlines =====\n\nfunction extractSignaturesAST(sf: SourceFile): string {\n const parts: string[] = [];\n\n // Imports\n for (const imp of sf.getImportDeclarations()) {\n parts.push(imp.getText());\n }\n\n if (parts.length > 0) parts.push('');\n\n // Type aliases\n for (const ta of sf.getTypeAliases()) {\n addJSDoc(ta, parts);\n parts.push(ta.getText());\n }\n\n // Interfaces\n for (const iface of sf.getInterfaces()) {\n addJSDoc(iface, parts);\n parts.push(iface.getText());\n }\n\n // Enums\n for (const en of sf.getEnums()) {\n addJSDoc(en, parts);\n parts.push(en.getText());\n }\n\n // Function declarations — signature only\n for (const fn of sf.getFunctions()) {\n addJSDoc(fn, parts);\n const isExported = fn.isExported();\n const isAsync = fn.isAsync();\n const name = fn.getName() ?? '<anonymous>';\n const params = fn.getParameters().map((p) => p.getText()).join(', ');\n const returnType = fn.getReturnTypeNode()?.getText();\n const returnStr = returnType ? `: ${returnType}` : '';\n\n const prefix = isExported ? 'export ' : '';\n const asyncStr = isAsync ? 'async ' : '';\n parts.push(`${prefix}${asyncStr}function ${name}(${params})${returnStr} { /* ... */ }`);\n }\n\n // Variable declarations (const/let with arrow functions)\n for (const stmt of sf.getVariableStatements()) {\n for (const decl of stmt.getDeclarations()) {\n const init = decl.getInitializer();\n if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n addJSDoc(stmt, parts);\n const isExported = stmt.isExported();\n const prefix = isExported ? 'export ' : '';\n const kind = stmt.getDeclarationKind();\n const name = decl.getName();\n const typeNode = decl.getTypeNode()?.getText();\n const typeStr = typeNode ? `: ${typeNode}` : '';\n parts.push(`${prefix}${kind} ${name}${typeStr} = /* ... */;`);\n } else {\n // Non-function variables: keep full declaration\n addJSDoc(stmt, parts);\n parts.push(stmt.getText());\n }\n }\n }\n\n // Classes — outline with method signatures\n for (const cls of sf.getClasses()) {\n addJSDoc(cls, parts);\n const isExported = cls.isExported();\n const prefix = isExported ? 'export ' : '';\n const name = cls.getName() ?? '<anonymous>';\n const ext = cls.getExtends()?.getText();\n const impl = cls.getImplements().map((i) => i.getText()).join(', ');\n let header = `${prefix}class ${name}`;\n if (ext) header += ` extends ${ext}`;\n if (impl) header += ` implements ${impl}`;\n header += ' {';\n parts.push(header);\n\n // Properties\n for (const prop of cls.getProperties()) {\n parts.push(` ${prop.getText()}`);\n }\n\n // Constructor\n const ctor = cls.getConstructors()[0];\n if (ctor) {\n const ctorParams = ctor.getParameters().map((p) => p.getText()).join(', ');\n parts.push(` constructor(${ctorParams}) { /* ... */ }`);\n }\n\n // Methods — signature only\n for (const method of cls.getMethods()) {\n const isStatic = method.isStatic();\n const isAsync = method.isAsync();\n const methodName = method.getName();\n const methodParams = method.getParameters().map((p) => p.getText()).join(', ');\n const returnType = method.getReturnTypeNode()?.getText();\n const returnStr = returnType ? `: ${returnType}` : '';\n const staticStr = isStatic ? 'static ' : '';\n const asyncStr = isAsync ? 'async ' : '';\n parts.push(` ${staticStr}${asyncStr}${methodName}(${methodParams})${returnStr} { /* ... */ }`);\n }\n\n parts.push('}');\n }\n\n // Re-exports\n for (const exp of sf.getExportDeclarations()) {\n parts.push(exp.getText());\n }\n\n // Export assignments\n for (const exp of sf.getExportAssignments()) {\n parts.push(exp.getText());\n }\n\n return parts.join('\\n');\n}\n\n// ===== SKELETON: Keep only declarations, no bodies at all =====\n\nfunction extractSkeletonAST(sf: SourceFile): string {\n const parts: string[] = [];\n\n // Imports\n for (const imp of sf.getImportDeclarations()) {\n parts.push(imp.getText());\n }\n\n if (parts.length > 0) parts.push('');\n\n // Type aliases — full\n for (const ta of sf.getTypeAliases()) {\n if (ta.isExported()) parts.push(ta.getText());\n }\n\n // Interfaces — name + extends only\n for (const iface of sf.getInterfaces()) {\n if (!iface.isExported()) continue;\n const ext = iface.getExtends().map((e) => e.getText());\n const extStr = ext.length > 0 ? ` extends ${ext.join(', ')}` : '';\n parts.push(`export interface ${iface.getName()}${extStr} { /* ${iface.getProperties().length} props */ }`);\n }\n\n // Enums — name only\n for (const en of sf.getEnums()) {\n if (!en.isExported()) continue;\n const members = en.getMembers().map((m) => m.getName());\n parts.push(`export enum ${en.getName()} { ${members.join(', ')} }`);\n }\n\n // Functions — name + params only\n for (const fn of sf.getFunctions()) {\n if (!fn.isExported()) continue;\n const name = fn.getName() ?? '<anonymous>';\n const params = fn.getParameters().map((p) => p.getText()).join(', ');\n parts.push(`export function ${name}(${params});`);\n }\n\n // Classes — name + method names only\n for (const cls of sf.getClasses()) {\n if (!cls.isExported()) continue;\n const methods = cls.getMethods().map((m) => m.getName());\n parts.push(`export class ${cls.getName()} { /* methods: ${methods.join(', ')} */ }`);\n }\n\n // Re-exports\n for (const exp of sf.getExportDeclarations()) {\n parts.push(exp.getText());\n }\n\n return parts.join('\\n');\n}\n\n// ===== GENERIC PRUNING (non-TS files) =====\n\nasync function pruneGeneric(\n file: AnalyzedFile,\n level: PruneLevel,\n): Promise<PrunedContent> {\n let content: string;\n try {\n content = await readFile(file.path, 'utf-8');\n } catch {\n return emptyResult(file, level);\n }\n\n return pruneGenericFromContent(file, content, level);\n}\n\nfunction pruneGenericFromContent(\n file: AnalyzedFile,\n content: string,\n level: PruneLevel,\n): PrunedContent {\n const lines = content.split('\\n');\n let result: string[];\n\n if (level === 'signatures') {\n result = lines.filter((line) => {\n const t = line.trim();\n return (\n t === '' ||\n t.startsWith('#') ||\n t.startsWith('//') ||\n t.startsWith('import ') ||\n t.startsWith('from ') ||\n t.startsWith('export ') ||\n t.startsWith('def ') ||\n t.startsWith('async def ') ||\n t.startsWith('class ') ||\n t.startsWith('function ') ||\n t.startsWith('const ') ||\n t.startsWith('let ') ||\n t.startsWith('var ') ||\n /^(pub |fn |struct |enum |impl |mod |use )/.test(t)\n );\n });\n } else {\n // skeleton: even more aggressive — only declarations\n result = lines.filter((line) => {\n const t = line.trim();\n return (\n t.startsWith('import ') ||\n t.startsWith('from ') ||\n t.startsWith('export ') ||\n t.startsWith('def ') ||\n t.startsWith('class ') ||\n t.startsWith('function ') ||\n /^(pub |fn |struct |enum |mod |use )/.test(t)\n );\n });\n }\n\n const prunedContent = result.join('\\n');\n const prunedTokens = countTokensChars4(Buffer.byteLength(prunedContent, 'utf-8'));\n const savingsPercent = file.tokens > 0 ? ((file.tokens - prunedTokens) / file.tokens) * 100 : 0;\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens,\n pruneLevel: level,\n content: prunedContent,\n savingsPercent: Math.max(0, savingsPercent),\n };\n}\n\n// ===== HELPERS =====\n\nasync function fullContent(file: AnalyzedFile): Promise<PrunedContent> {\n let content = '';\n try {\n content = await readFile(file.path, 'utf-8');\n } catch { /* empty */ }\n\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens: file.tokens,\n pruneLevel: 'full',\n content,\n savingsPercent: 0,\n };\n}\n\nfunction emptyResult(file: AnalyzedFile, level: PruneLevel): PrunedContent {\n return {\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n prunedTokens: 0,\n pruneLevel: level,\n content: '',\n savingsPercent: 100,\n };\n}\n\nfunction addJSDoc(node: { getJsDocs?: () => { getText(): string }[] }, parts: string[]): void {\n if (!node.getJsDocs) return;\n const docs = node.getJsDocs();\n if (docs.length > 0) {\n parts.push(docs[0].getText());\n }\n}\n\nfunction findTsConfig(filePath: string): string | undefined {\n let dir = filePath;\n for (let i = 0; i < 10; i++) {\n dir = join(dir, '..');\n const candidate = join(dir, 'tsconfig.json');\n if (existsSync(candidate)) return candidate;\n }\n return undefined;\n}\n","import type {\n AnalyzedFile,\n ProjectGraph,\n CoverageResult,\n} from '../types/engine.js';\nimport { buildAdjacencyList, bfsBidirectional } from './graph-utils.js';\n\n// ===== CONTEXT COVERAGE SCORING =====\n//\n// Given a set of included files and a task's target files, calculate\n// how much of the \"relevant universe\" is covered.\n//\n// coverageScore = |includedRelevant| / |relevantFiles| × 100\n//\n// \"Relevant\" = target files + their dependencies (up to `depth` levels)\n// + type providers used by included files.\n\nexport function calculateCoverage(\n targetPaths: string[],\n includedPaths: string[],\n allFiles: AnalyzedFile[],\n graph: ProjectGraph,\n depth: number = 2,\n): CoverageResult {\n // 1. Find all relevant files: targets + their dependency cone\n // Uses adjacency list for O(V+E) BFS instead of scanning all edges per node.\n const adj = buildAdjacencyList(graph.edges);\n const relevantSet = targetPaths.length > 0\n ? bfsBidirectional(targetPaths, adj, depth)\n : new Set<string>();\n const includedSet = new Set(includedPaths);\n\n // Also add type providers used by included files\n const tempFileMap = new Map(allFiles.map((f) => [f.relativePath, f]));\n for (const path of includedPaths) {\n const file = tempFileMap.get(path);\n if (!file) continue;\n\n for (const imp of file.imports) {\n const impFile = tempFileMap.get(imp);\n if (impFile && impFile.kind === 'type') {\n relevantSet.add(imp);\n }\n }\n }\n\n // 2. Calculate coverage\n const relevantFiles = Array.from(relevantSet);\n const includedRelevant = relevantFiles.filter((f) => includedSet.has(f));\n const missingRelevant = relevantFiles.filter((f) => !includedSet.has(f));\n\n // Missing critical = missing files with critical/high exclusion impact\n const missingCritical = missingRelevant.filter((f) => {\n const file = tempFileMap.get(f);\n return file && (file.exclusionImpact === 'critical' || file.exclusionImpact === 'high');\n });\n\n // Risk-weighted coverage: missing a high-risk file hurts more than missing a low-risk one.\n // score = Σ(riskScore of included relevant) / Σ(riskScore of all relevant) × 100\n // Falls back to count-based if no risk data is available.\n const fileMap = new Map(allFiles.map((f) => [f.relativePath, f]));\n let totalRelevantRisk = 0;\n let includedRelevantRisk = 0;\n\n for (const f of relevantFiles) {\n const risk = fileMap.get(f)?.riskScore ?? 1;\n totalRelevantRisk += risk;\n if (includedSet.has(f)) {\n includedRelevantRisk += risk;\n }\n }\n\n const score = totalRelevantRisk > 0\n ? Math.round((includedRelevantRisk / totalRelevantRisk) * 100)\n : relevantFiles.length > 0\n ? Math.round((includedRelevant.length / relevantFiles.length) * 100)\n : 100;\n\n // Build explanation\n let explanation: string;\n if (score >= 90) {\n explanation = `Excellent coverage (${score}%): AI has nearly all relevant context.`;\n } else if (score >= 70) {\n explanation = `Good coverage (${score}%): Most relevant files included.`;\n if (missingCritical.length > 0) {\n explanation += ` Warning: ${missingCritical.length} critical file(s) missing.`;\n }\n } else if (score >= 50) {\n explanation = `Partial coverage (${score}%): Significant context is missing.`;\n if (missingCritical.length > 0) {\n explanation += ` ${missingCritical.length} critical file(s) not included — AI quality will degrade.`;\n }\n } else {\n explanation = `Low coverage (${score}%): Most relevant files are excluded. AI response quality will be poor.`;\n }\n\n return {\n score,\n relevantFiles,\n includedRelevant,\n missingRelevant,\n missingCritical,\n explanation,\n };\n}\n","import type { AnalyzedFile, BudgetPlan, BudgetEntry, PruneLevel } from '../types/engine.js';\nimport { pruneFile } from './pruner.js';\n\n// ===== BUDGET OPTIMIZER =====\n//\n// Greedy knapsack with cascading prune levels.\n// Files are sorted by riskScore (descending) — highest risk first.\n// Each file is tried at progressively smaller prune levels until it fits.\n\nexport function getPruneLevelForRisk(riskScore: number): PruneLevel {\n if (riskScore >= 80) return 'full'; // critical — include everything, no cascading\n if (riskScore >= 60) return 'full'; // high — try full first, can cascade\n if (riskScore >= 30) return 'signatures'; // medium — signatures by default\n return 'skeleton'; // low — skeleton\n}\n\nexport function isCriticalRisk(riskScore: number): boolean {\n return riskScore >= 80;\n}\n\nexport async function optimizeBudget(\n files: AnalyzedFile[],\n budget: number,\n): Promise<BudgetPlan> {\n const entries: BudgetEntry[] = [];\n let used = 0;\n\n // Sort by riskScore descending — most important files first\n const sorted = [...files].sort((a, b) => b.riskScore - a.riskScore);\n\n for (const file of sorted) {\n const defaultLevel = getPruneLevelForRisk(file.riskScore);\n\n // Try cascading prune levels: full → signatures → skeleton → excluded\n const levelsToTry = getCascadeLevels(defaultLevel);\n\n let included = false;\n\n for (const level of levelsToTry) {\n if (level === 'excluded') break;\n\n if (level === 'full') {\n if (used + file.tokens <= budget) {\n used += file.tokens;\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: file.tokens,\n pruneLevel: 'full',\n included: true,\n reason: `Risk ${file.riskScore} — included in full`,\n });\n included = true;\n break;\n }\n } else {\n const pruned = await pruneFile(file, level);\n if (pruned.prunedTokens > 0 && used + pruned.prunedTokens <= budget) {\n used += pruned.prunedTokens;\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: pruned.prunedTokens,\n pruneLevel: level,\n included: true,\n reason: `Risk ${file.riskScore} — pruned to ${level} (budget constraint)`,\n });\n included = true;\n break;\n }\n }\n }\n\n if (!included) {\n entries.push({\n relativePath: file.relativePath,\n originalTokens: file.tokens,\n allocatedTokens: 0,\n pruneLevel: 'excluded',\n included: false,\n reason: `Risk ${file.riskScore} — excluded (budget exhausted, ${file.tokens} tokens)`,\n });\n }\n }\n\n return {\n budget,\n used,\n remaining: budget - used,\n fillPercent: budget > 0 ? Math.round((used / budget) * 100 * 10) / 10 : 0,\n files: entries,\n };\n}\n\n// ===== HELPERS =====\n\nfunction getCascadeLevels(startLevel: PruneLevel): PruneLevel[] {\n const all: PruneLevel[] = ['full', 'signatures', 'skeleton', 'excluded'];\n const startIdx = all.indexOf(startLevel);\n return all.slice(startIdx);\n}\n","import type { TaskType, ModelChoice, ModelSpec, ModelId } from '../types/interact.js';\nimport type { ProjectAnalysis } from '../types/engine.js';\n\n// ===== MODEL REGISTRY =====\n\nexport const MODEL_REGISTRY: ModelSpec[] = [\n {\n id: 'claude-haiku-3.5',\n name: 'Claude 3.5 Haiku',\n tier: 'fast',\n pricing: { inputPerMillion: 0.80, outputPerMillion: 4.00, cacheReadPerMillion: 0.08 },\n contextWindow: 200_000,\n strengths: ['speed', 'simple-tasks', 'low-cost'],\n },\n {\n id: 'claude-sonnet-4',\n name: 'Claude Sonnet 4',\n tier: 'balanced',\n pricing: { inputPerMillion: 3.00, outputPerMillion: 15.00, cacheReadPerMillion: 0.30 },\n contextWindow: 200_000,\n strengths: ['code-generation', 'refactoring', 'balanced-reasoning'],\n },\n {\n id: 'claude-opus-4',\n name: 'Claude Opus 4',\n tier: 'reasoning',\n pricing: { inputPerMillion: 15.00, outputPerMillion: 75.00, cacheReadPerMillion: 1.50 },\n contextWindow: 200_000,\n strengths: ['deep-reasoning', 'architecture', 'complex-debugging'],\n },\n];\n\n// ===== ROUTING RULES =====\n\ninterface RoutingRule {\n task: TaskType;\n defaultModel: ModelId;\n upgradeIf: (analysis: ProjectAnalysis) => boolean;\n upgradeTo: ModelId;\n reason: string;\n upgradeReason: string;\n}\n\nconst ROUTING_RULES: RoutingRule[] = [\n {\n task: 'simple-edit',\n defaultModel: 'claude-haiku-3.5',\n upgradeIf: () => false,\n upgradeTo: 'claude-haiku-3.5',\n reason: 'Simple edits are best handled by fast models',\n upgradeReason: '',\n },\n {\n task: 'docs',\n defaultModel: 'claude-haiku-3.5',\n upgradeIf: (a) => a.totalTokens > 100_000,\n upgradeTo: 'claude-sonnet-4',\n reason: 'Documentation tasks are straightforward',\n upgradeReason: 'Large codebase — Sonnet provides better understanding',\n },\n {\n task: 'test',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.overallComplexity > 15,\n upgradeTo: 'claude-opus-4',\n reason: 'Test generation requires good code understanding',\n upgradeReason: 'High complexity codebase — Opus for better test coverage',\n },\n {\n task: 'debug',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.distribution.critical > 5,\n upgradeTo: 'claude-opus-4',\n reason: 'Debugging requires solid reasoning about code flow',\n upgradeReason: 'Many critical files involved — Opus for deeper analysis',\n },\n {\n task: 'refactor',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.totalFiles > 50 && a.riskProfile.overallComplexity > 10,\n upgradeTo: 'claude-opus-4',\n reason: 'Refactoring needs good structural understanding',\n upgradeReason: 'Large + complex project — Opus for safer refactoring',\n },\n {\n task: 'review',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.riskProfile.distribution.critical > 3,\n upgradeTo: 'claude-opus-4',\n reason: 'Code review benefits from balanced reasoning',\n upgradeReason: 'Critical code under review — Opus for thorough analysis',\n },\n {\n task: 'feature',\n defaultModel: 'claude-sonnet-4',\n upgradeIf: (a) => a.totalFiles > 100,\n upgradeTo: 'claude-opus-4',\n reason: 'Feature development needs code generation + understanding',\n upgradeReason: 'Large codebase — Opus for better integration',\n },\n {\n task: 'architecture',\n defaultModel: 'claude-opus-4',\n upgradeIf: () => false,\n upgradeTo: 'claude-opus-4',\n reason: 'Architecture decisions require deep reasoning',\n upgradeReason: '',\n },\n];\n\n// ===== TASK CLASSIFICATION =====\n\nconst TASK_KEYWORDS: Record<TaskType, string[]> = {\n debug: ['debug', 'fix', 'bug', 'error', 'issue', 'broken', 'crash', 'failing', 'wrong'],\n review: ['review', 'check', 'assess', 'evaluate', 'audit', 'inspect', 'critique'],\n refactor: ['refactor', 'restructure', 'reorganize', 'clean up', 'simplify', 'extract', 'move'],\n test: ['test', 'spec', 'coverage', 'unit test', 'integration test', 'e2e'],\n docs: ['document', 'docs', 'readme', 'jsdoc', 'comment', 'explain'],\n feature: ['add', 'implement', 'create', 'build', 'new', 'feature', 'endpoint'],\n architecture: ['architecture', 'design', 'system', 'structure', 'migrate', 'pattern'],\n 'simple-edit': ['rename', 'typo', 'update', 'change', 'modify', 'tweak', 'adjust'],\n};\n\nexport function classifyTask(taskDescription: string): TaskType {\n const lower = taskDescription.toLowerCase();\n\n // Score each task type by keyword matches\n let bestType: TaskType = 'simple-edit';\n let bestScore = 0;\n\n for (const [type, keywords] of Object.entries(TASK_KEYWORDS) as [TaskType, string[]][]) {\n let score = 0;\n for (const kw of keywords) {\n if (lower.includes(kw)) score++;\n }\n if (score > bestScore) {\n bestScore = score;\n bestType = type;\n }\n }\n\n return bestType;\n}\n\n// ===== MODEL ROUTING =====\n\nexport function routeModel(\n taskType: TaskType,\n analysis: ProjectAnalysis,\n preferredModel?: ModelId,\n): ModelChoice {\n // If user explicitly chose a model, respect it\n if (preferredModel) {\n const spec = MODEL_REGISTRY.find((m) => m.id === preferredModel);\n if (spec) {\n return {\n model: preferredModel,\n reason: 'User-specified model',\n confidence: 1.0,\n alternatives: buildAlternatives(preferredModel, taskType),\n };\n }\n }\n\n // Find routing rule for this task\n const rule = ROUTING_RULES.find((r) => r.task === taskType);\n if (!rule) {\n return {\n model: 'claude-sonnet-4',\n reason: 'Default model for unrecognized task type',\n confidence: 0.5,\n alternatives: buildAlternatives('claude-sonnet-4', taskType),\n };\n }\n\n // Check if upgrade is warranted\n const shouldUpgrade = rule.upgradeIf(analysis);\n const model = shouldUpgrade ? rule.upgradeTo : rule.defaultModel;\n const reason = shouldUpgrade ? rule.upgradeReason : rule.reason;\n\n return {\n model,\n reason,\n confidence: shouldUpgrade ? 0.8 : 0.9,\n alternatives: buildAlternatives(model, taskType),\n };\n}\n\n// ===== HELPERS =====\n\nfunction buildAlternatives(chosenModel: ModelId, taskType: TaskType) {\n return MODEL_REGISTRY\n .filter((m) => m.id !== chosenModel)\n .map((m) => {\n const chosen = MODEL_REGISTRY.find((r) => r.id === chosenModel)!;\n const costDelta = m.pricing.inputPerMillion - chosen.pricing.inputPerMillion;\n const tradeoff = costDelta > 0\n ? `More capable but ${(costDelta / chosen.pricing.inputPerMillion * 100).toFixed(0)}% more expensive`\n : `${Math.abs(costDelta / chosen.pricing.inputPerMillion * 100).toFixed(0)}% cheaper but less capable`;\n\n return { model: m.id, costDelta, tradeoff };\n });\n}\n\nexport function getModelSpec(modelId: ModelId): ModelSpec | undefined {\n return MODEL_REGISTRY.find((m) => m.id === modelId);\n}\n","import type { CostEstimate, ModelId } from '../types/interact.js';\nimport { getModelSpec, MODEL_REGISTRY } from './router.js';\n\n// ===== COST ESTIMATION =====\n\nexport function estimateCost(\n modelId: ModelId,\n inputTokens: number,\n totalProjectTokens: number,\n estimatedOutputRatio: number = 0.3,\n): CostEstimate {\n const spec = getModelSpec(modelId) ?? MODEL_REGISTRY[1]; // fallback to Sonnet\n const estimatedOutputTokens = Math.round(inputTokens * estimatedOutputRatio);\n\n const inputCost = (inputTokens / 1_000_000) * spec.pricing.inputPerMillion;\n const outputCost = (estimatedOutputTokens / 1_000_000) * spec.pricing.outputPerMillion;\n const totalCost = inputCost + outputCost;\n\n // Without optimization = sending all project tokens\n const woInputCost = (totalProjectTokens / 1_000_000) * spec.pricing.inputPerMillion;\n const woOutputCost = (Math.round(totalProjectTokens * estimatedOutputRatio) / 1_000_000) * spec.pricing.outputPerMillion;\n const woTotalCost = woInputCost + woOutputCost;\n\n const tokensSaved = totalProjectTokens - inputTokens;\n const costSaved = woTotalCost - totalCost;\n const savingsPercent = woTotalCost > 0 ? (costSaved / woTotalCost) * 100 : 0;\n\n return {\n model: modelId,\n inputTokens,\n estimatedOutputTokens,\n inputCost: round(inputCost),\n outputCost: round(outputCost),\n totalCost: round(totalCost),\n formatted: formatCost(totalCost),\n\n withoutOptimization: {\n inputTokens: totalProjectTokens,\n totalCost: round(woTotalCost),\n formatted: formatCost(woTotalCost),\n },\n\n savings: {\n tokensSaved: Math.max(0, tokensSaved),\n costSaved: round(Math.max(0, costSaved)),\n percent: Math.max(0, Math.round(savingsPercent)),\n formatted: costSaved > 0\n ? `saved ${formatCost(costSaved)} (${Math.round(savingsPercent)}%)`\n : 'no savings',\n },\n };\n}\n\n// ===== HELPERS =====\n\nfunction round(n: number): number {\n return Math.round(n * 1_000_000) / 1_000_000;\n}\n\nfunction formatCost(cost: number): string {\n if (cost < 0.001) return '<$0.001';\n if (cost < 0.01) return `$${cost.toFixed(4)}`;\n if (cost < 1) return `$${cost.toFixed(3)}`;\n return `$${cost.toFixed(2)}`;\n}\n","import type { StructuredPrompt, PromptSection, TaskType } from '../types/interact.js';\nimport type { ContextSelection, ProjectAnalysis } from '../types/engine.js';\nimport { countTokensChars4 } from '../engine/tokenizer.js';\n\n// ===== STRUCTURED PROMPT BUILDER =====\n//\n// Not templates. Not libraries.\n// Task-aware prompt construction with sections that can be measured and optimized.\n\nexport interface PromptOptions {\n task: string;\n taskType: TaskType;\n analysis: ProjectAnalysis;\n selection: ContextSelection;\n enableCoT?: boolean;\n enableConstraints?: boolean;\n enableAntiHallucination?: boolean;\n}\n\nexport function buildPrompt(options: PromptOptions): StructuredPrompt {\n const {\n task,\n taskType,\n analysis,\n selection,\n enableCoT = true,\n enableConstraints = true,\n enableAntiHallucination = true,\n } = options;\n\n const sections: PromptSection[] = [];\n\n // 1. System section — role priming\n sections.push(buildSystemSection(analysis.stack, taskType));\n\n // 2. Context section — project info + selected files\n sections.push(buildContextSection(analysis, selection));\n\n // 3. Task section — what the user wants\n sections.push(buildTaskSection(task, taskType));\n\n // 4. Constraints section — safety rails\n if (enableConstraints) {\n sections.push(buildConstraintsSection(analysis.stack, taskType));\n }\n\n // 5. Chain-of-thought section\n if (enableCoT) {\n sections.push(buildCoTSection(taskType));\n }\n\n // 6. Anti-hallucination section\n if (enableAntiHallucination) {\n sections.push(buildAntiHallucinationSection());\n }\n\n // 7. Output format section\n sections.push(buildFormatSection(taskType));\n\n const rendered = sections.map((s) => s.content).join('\\n\\n---\\n\\n');\n const totalTokens = sections.reduce((s, sec) => s + sec.tokens, 0);\n\n return { sections, totalTokens, rendered };\n}\n\n// ===== SECTION BUILDERS =====\n\nfunction buildSystemSection(stack: string[], taskType: TaskType): PromptSection {\n const stackStr = stack.length > 0 ? stack.join(', ') : 'software';\n const taskRole = TASK_ROLES[taskType] ?? 'engineer';\n\n const content = [\n `You are a senior ${stackStr} ${taskRole} with deep expertise in clean architecture, testing, and production-quality code.`,\n 'You prioritize correctness, readability, and maintainability.',\n 'You never make assumptions without evidence from the code.',\n ].join(' ');\n\n return makeSection('system', 'system', content);\n}\n\nfunction buildContextSection(\n analysis: ProjectAnalysis,\n selection: ContextSelection,\n): PromptSection {\n const lines: string[] = [];\n\n lines.push(`## Project: ${analysis.projectName}`);\n lines.push(`Stack: ${analysis.stack.join(', ') || 'Unknown'}`);\n lines.push(`Files analyzed: ${analysis.totalFiles} | Tokens: ~${Math.round(analysis.totalTokens / 1000)}K`);\n lines.push(`Context coverage: ${selection.coverage.score}% | Risk score: ${selection.riskScore}/100`);\n lines.push('');\n\n // List included files with their prune levels\n lines.push('### Included Files');\n lines.push('');\n\n const fullFiles = selection.files.filter((f) => f.pruneLevel === 'full');\n const sigFiles = selection.files.filter((f) => f.pruneLevel === 'signatures');\n const skelFiles = selection.files.filter((f) => f.pruneLevel === 'skeleton');\n\n if (fullFiles.length > 0) {\n lines.push('**Full content (read these first):**');\n for (const f of fullFiles) {\n lines.push(`- \\`${f.relativePath}\\` (~${Math.round(f.tokens / 1000)}K tokens) — ${f.reason}`);\n }\n lines.push('');\n }\n\n if (sigFiles.length > 0) {\n lines.push('**Signatures only (reference as needed):**');\n for (const f of sigFiles) {\n lines.push(`- \\`${f.relativePath}\\` (~${Math.round(f.tokens / 1000)}K tokens)`);\n }\n lines.push('');\n }\n\n if (skelFiles.length > 0) {\n lines.push('**Skeleton (structure overview):**');\n for (const f of skelFiles) {\n lines.push(`- \\`${f.relativePath}\\``);\n }\n lines.push('');\n }\n\n if (selection.coverage.missingCritical.length > 0) {\n lines.push('⚠️ **Missing critical files** (not included due to budget):');\n for (const f of selection.coverage.missingCritical) {\n lines.push(`- \\`${f}\\``);\n }\n lines.push('');\n }\n\n const content = lines.join('\\n');\n return makeSection('context', 'context', content);\n}\n\nfunction buildTaskSection(task: string, taskType: TaskType): PromptSection {\n const content = [\n '## Task',\n '',\n task,\n '',\n `Task type: **${taskType}**`,\n ].join('\\n');\n\n return makeSection('task', 'task', content);\n}\n\nfunction buildConstraintsSection(stack: string[], taskType: TaskType): PromptSection {\n const lines: string[] = ['## Constraints', ''];\n\n lines.push('- **Do NOT** delete or modify existing tests unless explicitly asked');\n lines.push('- **Do NOT** change function signatures that are part of the public API');\n lines.push('- **Do NOT** introduce new dependencies without mentioning it');\n lines.push('- **Always** handle errors explicitly (no silent catches)');\n lines.push('- **Always** preserve existing code style and conventions');\n lines.push('- **Prefer** minimal changes — smallest diff that solves the problem');\n\n if (stack.includes('TypeScript')) {\n lines.push('- **Always** use strict TypeScript types (no `any` unless unavoidable)');\n lines.push('- **Always** add explicit return types to exported functions');\n }\n\n if (taskType === 'refactor') {\n lines.push('- **Do NOT** change behavior — refactoring must be behavior-preserving');\n lines.push('- **Verify** all existing tests still pass after changes');\n }\n\n if (taskType === 'test') {\n lines.push('- Use AAA pattern: Arrange, Act, Assert');\n lines.push('- Test boundaries, null/undefined, async errors, type edges');\n lines.push('- Use descriptive test names: \"should [expected] when [condition]\"');\n }\n\n return makeSection('constraints', 'constraints', lines.join('\\n'));\n}\n\nfunction buildCoTSection(taskType: TaskType): PromptSection {\n const steps = COT_STEPS[taskType] ?? COT_STEPS['simple-edit'];\n\n const lines: string[] = ['## Thinking Process', '', 'Before writing any code:'];\n steps.forEach((step, i) => {\n lines.push(`${i + 1}. ${step}`);\n });\n\n return makeSection('cot', 'constraints', lines.join('\\n'));\n}\n\nfunction buildAntiHallucinationSection(): PromptSection {\n const content = [\n '## Important',\n '',\n '- Only reference files, functions, and APIs that exist in the provided context',\n '- If you are unsure about something, say so explicitly',\n '- Do NOT invent function signatures, types, or module paths',\n '- If the context is insufficient to complete the task, explain what is missing',\n ].join('\\n');\n\n return makeSection('anti-hallucination', 'constraints', content);\n}\n\nfunction buildFormatSection(taskType: TaskType): PromptSection {\n const lines: string[] = ['## Output Format', ''];\n\n if (taskType === 'review') {\n lines.push('Provide findings in priority order: Critical > Major > Minor > Nitpick');\n lines.push('For each finding: file, line, issue, and concrete suggestion with code');\n } else if (taskType === 'architecture') {\n lines.push('Present 2-3 options with trade-offs, then recommend one with justification');\n } else if (taskType === 'debug') {\n lines.push('1. Root cause analysis');\n lines.push('2. Minimal fix');\n lines.push('3. Explanation of why the fix works');\n lines.push('4. Edge cases to consider');\n } else {\n lines.push('Provide clean, production-ready code with brief explanations of key decisions');\n }\n\n return makeSection('format', 'format', lines.join('\\n'));\n}\n\n// ===== CONSTANTS =====\n\nconst TASK_ROLES: Record<TaskType, string> = {\n debug: 'debugger',\n review: 'code reviewer',\n refactor: 'architect',\n test: 'test engineer',\n docs: 'technical writer',\n feature: 'engineer',\n architecture: 'systems architect',\n 'simple-edit': 'engineer',\n};\n\nconst COT_STEPS: Record<TaskType, string[]> = {\n debug: [\n '**Reproduce** — Understand the exact symptom and when it occurs',\n '**Hypothesize** — List the most likely root causes (max 3)',\n '**Verify** — Check each hypothesis against the code',\n '**Fix** — Apply the minimal fix that addresses the root cause',\n '**Validate** — Explain why the fix works and what edge cases it covers',\n ],\n review: [\n '**Understand** — Read the code and understand its purpose',\n '**Assess** — Evaluate correctness, readability, performance, security',\n '**Prioritize** — Rank issues by severity (critical > major > minor)',\n '**Suggest** — Provide concrete, actionable improvements with code',\n ],\n refactor: [\n '**Analyze** — Identify code smells and structural issues',\n '**Plan** — Define the target structure before changing anything',\n '**Preserve** — Ensure behavior doesn\\'t change',\n '**Refactor** — Apply changes incrementally',\n '**Verify** — Confirm all existing tests still pass',\n ],\n test: [\n '**Identify** — What needs testing? (happy path, edge cases, errors)',\n '**Structure** — Use AAA pattern: Arrange, Act, Assert',\n '**Cover** — Test boundaries, null/undefined, async errors',\n '**Isolate** — Mock external dependencies, test units independently',\n ],\n docs: [\n '**Read** — Understand the code before documenting',\n '**Structure** — Organize by audience (API users, contributors, operators)',\n '**Write** — Clear, concise, with examples',\n ],\n feature: [\n '**Clarify** — Restate the requirement in your own words',\n '**Design** — Plan the approach (types, interfaces, flow)',\n '**Implement** — Build incrementally, starting with types',\n '**Test** — Write tests alongside implementation',\n '**Integrate** — Ensure no regressions',\n ],\n architecture: [\n '**Context** — Understand current architecture and constraints',\n '**Options** — Present 2-3 viable approaches with trade-offs',\n '**Recommend** — Choose the best and explain why',\n '**Plan** — Define migration steps',\n '**Risks** — Identify risks and mitigation strategies',\n ],\n 'simple-edit': [\n '**Understand** — Read the relevant code',\n '**Plan** — Think before writing',\n '**Implement** — Write clean, well-typed code',\n '**Verify** — Check for edge cases',\n ],\n};\n\n// ===== HELPERS =====\n\nfunction makeSection(\n id: string,\n role: PromptSection['role'],\n content: string,\n): PromptSection {\n const tokens = countTokensChars4(Buffer.byteLength(content, 'utf-8'));\n return { id, role, content, tokens };\n}\n","import { randomUUID, createHash } from 'node:crypto';\nimport { readdir, chmod } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { userInfo } from 'node:os';\nimport { homedir } from 'node:os';\nimport type { AuditEntry, AuditAction } from '../types/govern.js';\n\n// ===== AUDIT TRAIL =====\n//\n// Immutable, tamper-evident audit log for all CTO interactions.\n// Each entry is SHA-256 hashed for integrity verification.\n\nconst CTO_DIR = '.cto-ai';\nconst AUDIT_DIR = 'audit';\nconst MAX_ENTRIES_PER_FILE = 500;\n\nfunction getAuditDir(): string {\n return join(homedir(), CTO_DIR, AUDIT_DIR);\n}\n\nfunction getCurrentAuditFile(): string {\n const date = new Date().toISOString().split('T')[0].replace(/-/g, '');\n return join(getAuditDir(), `audit_${date}.json`);\n}\n\nfunction computeIntegrityHash(entry: Omit<AuditEntry, 'integrityHash'>): string {\n const payload = JSON.stringify({\n id: entry.id,\n timestamp: entry.timestamp,\n action: entry.action,\n user: entry.user,\n projectPath: entry.projectPath,\n details: entry.details,\n });\n return createHash('sha256').update(payload).digest('hex');\n}\n\n// ===== HELPERS (inline to avoid cross-layer deps) =====\n\nasync function ensureDir(dirPath: string): Promise<void> {\n const { mkdir } = await import('node:fs/promises');\n await mkdir(dirPath, { recursive: true });\n}\n\nasync function readJSON<T>(filePath: string): Promise<T | null> {\n const { readFile } = await import('node:fs/promises');\n try {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nasync function writeJSON(filePath: string, data: unknown): Promise<void> {\n const { writeFile } = await import('node:fs/promises');\n await ensureDir(join(filePath, '..'));\n await writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8');\n}\n\n// ===== PUBLIC API =====\n\nexport async function logAudit(\n action: AuditAction,\n projectPath: string,\n details: Record<string, unknown> = {},\n): Promise<AuditEntry> {\n const auditDir = getAuditDir();\n await ensureDir(auditDir);\n\n let currentUser: string;\n try {\n currentUser = userInfo().username;\n } catch {\n currentUser = process.env.USER ?? process.env.USERNAME ?? 'unknown';\n }\n\n const partialEntry = {\n id: randomUUID().substring(0, 12),\n timestamp: new Date(),\n action,\n user: currentUser,\n projectPath,\n details,\n };\n\n const entry: AuditEntry = {\n ...partialEntry,\n integrityHash: computeIntegrityHash(partialEntry),\n };\n\n const auditFile = getCurrentAuditFile();\n let entries = await readJSON<AuditEntry[]>(auditFile) ?? [];\n entries.push(entry);\n\n if (entries.length > MAX_ENTRIES_PER_FILE) {\n entries = entries.slice(-MAX_ENTRIES_PER_FILE);\n }\n\n await writeJSON(auditFile, entries);\n try { await chmod(auditFile, 0o600); } catch { /* ignore on Windows */ }\n\n return entry;\n}\n\nexport async function getAuditEntries(\n options: {\n projectPath?: string;\n action?: AuditAction;\n since?: Date;\n limit?: number;\n } = {},\n): Promise<AuditEntry[]> {\n const auditDir = getAuditDir();\n let files: string[];\n try {\n files = await readdir(auditDir);\n } catch {\n return [];\n }\n\n const auditFiles = files\n .filter((f) => f.startsWith('audit_') && f.endsWith('.json'))\n .sort()\n .reverse();\n\n const allEntries: AuditEntry[] = [];\n const limit = options.limit ?? 100;\n\n for (const file of auditFiles) {\n if (allEntries.length >= limit) break;\n\n const entries = await readJSON<AuditEntry[]>(join(auditDir, file));\n if (!entries) continue;\n\n for (const entry of entries.reverse()) {\n if (allEntries.length >= limit) break;\n if (options.projectPath && entry.projectPath !== options.projectPath) continue;\n if (options.action && entry.action !== options.action) continue;\n if (options.since && new Date(entry.timestamp) < options.since) continue;\n allEntries.push(entry);\n }\n }\n\n return allEntries;\n}\n\nexport function verifyAuditEntry(entry: AuditEntry): boolean {\n const { integrityHash, ...rest } = entry;\n const expected = computeIntegrityHash(rest as Omit<AuditEntry, 'integrityHash'>);\n return expected === integrityHash;\n}\n\nexport async function verifyAuditIntegrity(): Promise<{\n totalEntries: number;\n validEntries: number;\n invalidEntries: AuditEntry[];\n}> {\n const entries = await getAuditEntries({ limit: 10000 });\n const invalidEntries: AuditEntry[] = [];\n\n for (const entry of entries) {\n if (!verifyAuditEntry(entry)) {\n invalidEntries.push(entry);\n }\n }\n\n return {\n totalEntries: entries.length,\n validEntries: entries.length - invalidEntries.length,\n invalidEntries,\n };\n}\n\nexport async function purgeOldAuditEntries(retentionDays: number): Promise<number> {\n const auditDir = getAuditDir();\n let files: string[];\n try {\n files = await readdir(auditDir);\n } catch {\n return 0;\n }\n\n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - retentionDays);\n const cutoffStr = cutoff.toISOString().split('T')[0].replace(/-/g, '');\n\n let purged = 0;\n const { unlink } = await import('node:fs/promises');\n\n for (const file of files) {\n if (!file.startsWith('audit_') || !file.endsWith('.json')) continue;\n const dateStr = file.replace('audit_', '').replace('.json', '');\n if (dateStr < cutoffStr) {\n try {\n await unlink(join(auditDir, file));\n purged++;\n } catch { /* ignore */ }\n }\n }\n\n return purged;\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { readFile, writeFile, readdir, mkdir } from 'node:fs/promises';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { selectContext } from '../../engine/selector.js';\nimport { createSnapshot, verifySnapshot, compareSnapshots } from '../../govern/snapshot.js';\nimport type { ContextSnapshot } from '../../types/govern.js';\n\nconst SNAPSHOTS_DIR = '.cto/snapshots';\n\nasync function ensureSnapshotsDir(projectPath: string): Promise<string> {\n const dir = join(projectPath, SNAPSHOTS_DIR);\n await mkdir(dir, { recursive: true });\n return dir;\n}\n\nasync function loadSnapshot(filePath: string): Promise<ContextSnapshot> {\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as ContextSnapshot;\n}\n\nexport const snapshotCommand = new Command('snapshot')\n .description('Create and manage reproducible context snapshots')\n .addCommand(\n new Command('create')\n .description('Create a snapshot of current context selection')\n .argument('<name>', 'Snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-t, --task <task>', 'Task description for context selection', 'general review')\n .action(async (name: string, opts: { path?: string; budget?: string; task?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n console.log(chalk.dim(`\\n Analyzing project...`));\n const analysis = await analyzeProject(projectPath);\n\n console.log(chalk.dim(` Selecting context...`));\n const selection = await selectContext({\n task: opts.task ?? 'general review',\n analysis,\n budget,\n });\n\n const snap = createSnapshot(name, analysis, selection, {\n task: opts.task,\n budget,\n createdBy: process.env.USER ?? 'unknown',\n });\n\n const dir = await ensureSnapshotsDir(projectPath);\n const filePath = join(dir, `${name}.json`);\n await writeFile(filePath, JSON.stringify(snap, null, 2), 'utf-8');\n\n console.log('');\n console.log(chalk.bold.cyan(` 📸 Snapshot \"${name}\" created`));\n console.log(` Files: ${snap.files.length}`);\n console.log(` Tokens: ~${Math.round(snap.totalTokens / 1000)}K`);\n console.log(` Coverage: ${snap.coverageScore}%`);\n console.log(` Risk: ${snap.riskScore}/100`);\n console.log(` Hash: ${snap.hash}`);\n console.log(` Saved: ${filePath}`);\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('verify')\n .description('Verify a snapshot against current project state')\n .argument('<name>', 'Snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .action(async (name: string, opts: { path?: string; budget?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n const snapPath = join(projectPath, SNAPSHOTS_DIR, `${name}.json`);\n const snap = await loadSnapshot(snapPath);\n\n console.log(chalk.dim(`\\n Re-analyzing project...`));\n const analysis = await analyzeProject(projectPath);\n\n const selection = await selectContext({\n task: (snap.metadata.task as string) ?? 'general review',\n analysis,\n budget,\n });\n\n const result = await verifySnapshot(snap, analysis, selection);\n\n console.log('');\n if (result.valid) {\n console.log(chalk.bold.green(` ✅ Snapshot \"${name}\" is valid`));\n } else {\n console.log(chalk.bold.red(` ❌ Snapshot \"${name}\" has drifted`));\n }\n\n console.log(` Files checked: ${result.filesChecked}`);\n console.log(` Files matched: ${result.filesMatched}`);\n\n if (result.filesMissing.length > 0) {\n console.log(chalk.yellow(` Missing: ${result.filesMissing.join(', ')}`));\n }\n if (result.filesChanged.length > 0) {\n console.log(chalk.yellow(` Changed: ${result.filesChanged.join(', ')}`));\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('compare')\n .description('Compare two snapshots')\n .argument('<older>', 'Older snapshot name')\n .argument('<newer>', 'Newer snapshot name')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (older: string, newer: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const dir = join(projectPath, SNAPSHOTS_DIR);\n\n const snap1 = await loadSnapshot(join(dir, `${older}.json`));\n const snap2 = await loadSnapshot(join(dir, `${newer}.json`));\n\n const diff = compareSnapshots(snap1, snap2);\n\n console.log('');\n console.log(chalk.bold.cyan(` 📊 Snapshot Comparison: ${older} → ${newer}`));\n console.log('');\n\n if (diff.added.length > 0) {\n console.log(chalk.green(` Added (${diff.added.length}):`));\n for (const f of diff.added) console.log(` + ${f}`);\n }\n if (diff.removed.length > 0) {\n console.log(chalk.red(` Removed (${diff.removed.length}):`));\n for (const f of diff.removed) console.log(` - ${f}`);\n }\n if (diff.changed.length > 0) {\n console.log(chalk.yellow(` Changed (${diff.changed.length}):`));\n for (const f of diff.changed) console.log(` ~ ${f}`);\n }\n\n console.log('');\n console.log(` Token delta: ${diff.tokenDelta > 0 ? '+' : ''}${diff.tokenDelta}`);\n console.log(` Coverage delta: ${diff.coverageDelta > 0 ? '+' : ''}${diff.coverageDelta}%`);\n console.log(` Risk delta: ${diff.riskDelta > 0 ? '+' : ''}${diff.riskDelta}`);\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('list')\n .description('List saved snapshots')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const dir = join(projectPath, SNAPSHOTS_DIR);\n\n let files: string[];\n try {\n files = await readdir(dir);\n } catch {\n console.log(chalk.dim('\\n No snapshots found. Run `cto snapshot create <name>` first.\\n'));\n return;\n }\n\n const snapFiles = files.filter((f) => f.endsWith('.json')).sort();\n\n if (snapFiles.length === 0) {\n console.log(chalk.dim('\\n No snapshots found.\\n'));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📸 Snapshots (${snapFiles.length})`));\n console.log('');\n\n for (const file of snapFiles) {\n try {\n const snap = await loadSnapshot(join(dir, file));\n const date = new Date(snap.createdAt).toLocaleString();\n console.log(` ${chalk.bold(snap.name)} — ${snap.files.length} files, ~${Math.round(snap.totalTokens / 1000)}K tokens, coverage ${snap.coverageScore}%`);\n console.log(` ${chalk.dim(`Created: ${date} | Hash: ${snap.hash}`)}`);\n } catch {\n console.log(` ${chalk.dim(file)} ${chalk.red('(corrupted)')}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import { randomUUID, createHash } from 'node:crypto';\nimport { readFile } from 'node:fs/promises';\nimport type {\n ContextSnapshot,\n SnapshotFile,\n SnapshotVerification,\n} from '../types/govern.js';\nimport type { ContextSelection, ProjectAnalysis } from '../types/engine.js';\n\n// ===== CONTEXT SNAPSHOTS =====\n//\n// Reproducible, verifiable snapshots of context selections.\n// Used for: deterministic mode, audit evidence, before/after comparisons.\n\nexport function createSnapshot(\n name: string,\n analysis: ProjectAnalysis,\n selection: ContextSelection,\n metadata: Record<string, unknown> = {},\n): ContextSnapshot {\n const files: SnapshotFile[] = selection.files.map((f) => ({\n relativePath: f.relativePath,\n hash: hashString(`${f.relativePath}:${f.tokens}:${f.pruneLevel}`),\n tokens: f.tokens,\n pruneLevel: f.pruneLevel,\n }));\n\n const snapshotData = files\n .map((f) => `${f.relativePath}:${f.hash}:${f.pruneLevel}`)\n .sort()\n .join('|');\n\n return {\n id: randomUUID().substring(0, 8),\n name,\n createdAt: new Date(),\n hash: hashString(snapshotData),\n projectHash: analysis.hash,\n analysisHash: analysis.hash,\n selectionHash: selection.hash,\n files,\n totalTokens: selection.totalTokens,\n coverageScore: selection.coverage.score,\n riskScore: selection.riskScore,\n metadata,\n };\n}\n\nexport async function verifySnapshot(\n snapshot: ContextSnapshot,\n currentAnalysis: ProjectAnalysis,\n currentSelection: ContextSelection,\n): Promise<SnapshotVerification> {\n const currentFiles = new Map(\n currentSelection.files.map((f) => [f.relativePath, f]),\n );\n\n let filesMatched = 0;\n const filesMissing: string[] = [];\n const filesChanged: string[] = [];\n\n for (const snapFile of snapshot.files) {\n const current = currentFiles.get(snapFile.relativePath);\n\n if (!current) {\n filesMissing.push(snapFile.relativePath);\n continue;\n }\n\n const currentHash = hashString(\n `${current.relativePath}:${current.tokens}:${current.pruneLevel}`,\n );\n\n if (currentHash === snapFile.hash) {\n filesMatched++;\n } else {\n filesChanged.push(snapFile.relativePath);\n }\n }\n\n // Verify overall hash\n const currentSnapshotData = snapshot.files\n .map((f) => {\n const current = currentFiles.get(f.relativePath);\n if (!current) return `${f.relativePath}:MISSING:MISSING`;\n return `${current.relativePath}:${hashString(`${current.relativePath}:${current.tokens}:${current.pruneLevel}`)}:${current.pruneLevel}`;\n })\n .sort()\n .join('|');\n\n const currentHash = hashString(currentSnapshotData);\n const integrityOk = currentHash === snapshot.hash && filesMissing.length === 0 && filesChanged.length === 0;\n\n return {\n valid: integrityOk,\n snapshotId: snapshot.id,\n filesChecked: snapshot.files.length,\n filesMatched,\n filesMissing,\n filesChanged,\n integrityOk,\n };\n}\n\nexport function compareSnapshots(\n older: ContextSnapshot,\n newer: ContextSnapshot,\n): {\n added: string[];\n removed: string[];\n changed: string[];\n tokenDelta: number;\n coverageDelta: number;\n riskDelta: number;\n} {\n const olderFiles = new Map(older.files.map((f) => [f.relativePath, f]));\n const newerFiles = new Map(newer.files.map((f) => [f.relativePath, f]));\n\n const added: string[] = [];\n const removed: string[] = [];\n const changed: string[] = [];\n\n for (const [path, file] of newerFiles) {\n const old = olderFiles.get(path);\n if (!old) {\n added.push(path);\n } else if (old.hash !== file.hash) {\n changed.push(path);\n }\n }\n\n for (const path of olderFiles.keys()) {\n if (!newerFiles.has(path)) {\n removed.push(path);\n }\n }\n\n return {\n added,\n removed,\n changed,\n tokenDelta: newer.totalTokens - older.totalTokens,\n coverageDelta: newer.coverageScore - older.coverageScore,\n riskDelta: newer.riskScore - older.riskScore,\n };\n}\n\n// ===== HELPERS =====\n\nfunction hashString(input: string): string {\n return createHash('sha256').update(input).digest('hex').substring(0, 16);\n}\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { getAuditEntries, verifyAuditIntegrity, purgeOldAuditEntries } from '../../govern/audit.js';\n\nexport const auditCommand = new Command('audit')\n .description('View and manage the audit trail')\n .addCommand(\n new Command('list')\n .description('List recent audit entries')\n .option('-n, --limit <limit>', 'Number of entries to show', '20')\n .option('-a, --action <action>', 'Filter by action type')\n .option('-p, --project <path>', 'Filter by project path')\n .option('--json', 'Output as JSON')\n .action(async (opts: { limit?: string; action?: string; project?: string; json?: boolean }) => {\n try {\n const entries = await getAuditEntries({\n limit: parseInt(opts.limit ?? '20', 10),\n action: opts.action as any,\n projectPath: opts.project,\n });\n\n if (opts.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n\n if (entries.length === 0) {\n console.log(chalk.dim('\\n No audit entries found.\\n'));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📋 Audit Trail (${entries.length} entries)`));\n console.log('');\n\n for (const entry of entries) {\n const date = new Date(entry.timestamp).toLocaleString();\n const actionColor = entry.action.includes('secret') ? chalk.red\n : entry.action.includes('integrity') ? chalk.yellow\n : chalk.blue;\n\n console.log(` ${chalk.dim(date)} ${actionColor(entry.action)} ${chalk.dim('by')} ${entry.user}`);\n if (entry.projectPath) {\n console.log(` ${chalk.dim(`Project: ${entry.projectPath}`)}`);\n }\n if (entry.tokensUsed) {\n console.log(` ${chalk.dim(`Tokens: ~${Math.round(entry.tokensUsed / 1000)}K | Coverage: ${entry.coverageScore ?? '?'}% | Risk: ${entry.riskScore ?? '?'}`)}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('verify')\n .description('Verify audit trail integrity')\n .action(async () => {\n try {\n console.log(chalk.dim('\\n Verifying audit integrity...\\n'));\n\n const result = await verifyAuditIntegrity();\n\n if (result.invalidEntries.length === 0) {\n console.log(chalk.bold.green(` ✅ Audit trail is intact`));\n } else {\n console.log(chalk.bold.red(` ❌ Audit trail has been tampered with`));\n }\n\n console.log(` Total entries: ${result.totalEntries}`);\n console.log(` Valid: ${result.validEntries}`);\n console.log(` Invalid: ${result.invalidEntries.length}`);\n\n if (result.invalidEntries.length > 0) {\n console.log('');\n console.log(chalk.red(' Tampered entries:'));\n for (const entry of result.invalidEntries.slice(0, 5)) {\n console.log(` ${entry.id} — ${entry.action} at ${new Date(entry.timestamp).toLocaleString()}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('purge')\n .description('Purge old audit entries')\n .option('-d, --days <days>', 'Retention days', '90')\n .action(async (opts: { days?: string }) => {\n try {\n const days = parseInt(opts.days ?? '90', 10);\n const purged = await purgeOldAuditEntries(days);\n\n console.log('');\n if (purged > 0) {\n console.log(chalk.bold(` 🗑️ Purged ${purged} audit file(s) older than ${days} days`));\n } else {\n console.log(chalk.dim(` No audit files older than ${days} days found.`));\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import { Command } from 'commander';\nimport chalk from 'chalk';\nimport { resolve, join } from 'node:path';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { DEFAULT_POLICY, addRule, removeRule, toggleRule, validateSelection } from '../../govern/policy.js';\nimport { analyzeProject } from '../../engine/analyzer.js';\nimport { selectContext } from '../../engine/selector.js';\nimport type { PolicySet } from '../../types/govern.js';\n\nconst POLICY_FILE = '.cto/policy.json';\n\nasync function loadPolicy(projectPath: string): Promise<PolicySet> {\n try {\n const content = await readFile(join(projectPath, POLICY_FILE), 'utf-8');\n return JSON.parse(content) as PolicySet;\n } catch {\n return DEFAULT_POLICY;\n }\n}\n\nasync function savePolicy(projectPath: string, policy: PolicySet): Promise<void> {\n const dir = join(projectPath, '.cto');\n await mkdir(dir, { recursive: true });\n await writeFile(join(projectPath, POLICY_FILE), JSON.stringify(policy, null, 2), 'utf-8');\n}\n\nexport const policyCommand = new Command('policy')\n .description('Manage context selection policies')\n .addCommand(\n new Command('show')\n .description('Show current policy rules')\n .option('-p, --path <path>', 'Project path', '.')\n .option('--json', 'Output as JSON')\n .action(async (opts: { path?: string; json?: boolean }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const policy = await loadPolicy(projectPath);\n\n if (opts.json) {\n console.log(JSON.stringify(policy, null, 2));\n return;\n }\n\n console.log('');\n console.log(chalk.bold.cyan(` 📜 Policy: ${policy.name} (v${policy.version})`));\n console.log('');\n\n if (policy.rules.length === 0) {\n console.log(chalk.dim(' No rules defined.'));\n }\n\n for (const rule of policy.rules) {\n const status = rule.enabled ? chalk.green('●') : chalk.dim('○');\n const typeColor = rule.type.includes('exclude') ? chalk.red\n : rule.type.includes('include') ? chalk.green\n : chalk.yellow;\n\n console.log(` ${status} ${chalk.bold(rule.id)} — ${typeColor(rule.type)}`);\n console.log(` ${chalk.dim(rule.reason)}`);\n if (rule.pattern) console.log(` ${chalk.dim(`Pattern: ${rule.pattern}`)}`);\n if (rule.threshold != null) console.log(` ${chalk.dim(`Threshold: ${rule.threshold}`)}`);\n if (rule.category) console.log(` ${chalk.dim(`Category: ${rule.category}`)}`);\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('add')\n .description('Add a new policy rule')\n .argument('<id>', 'Rule ID')\n .argument('<type>', 'Rule type: exclude-always | include-always | coverage-minimum | risk-maximum | budget-limit')\n .option('-p, --path <path>', 'Project path', '.')\n .option('--pattern <pattern>', 'Glob pattern for include/exclude rules')\n .option('--threshold <n>', 'Threshold value for metric rules')\n .option('--category <cat>', 'Category for budget-limit rules')\n .option('--reason <reason>', 'Reason for the rule', 'User-defined rule')\n .action(async (id: string, type: string, opts: {\n path?: string;\n pattern?: string;\n threshold?: string;\n category?: string;\n reason?: string;\n }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n\n policy = addRule(policy, {\n id,\n type: type as any,\n pattern: opts.pattern,\n threshold: opts.threshold ? parseInt(opts.threshold, 10) : undefined,\n category: opts.category,\n reason: opts.reason ?? 'User-defined rule',\n enabled: true,\n });\n\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" added (${type})\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('remove')\n .description('Remove a policy rule')\n .argument('<id>', 'Rule ID to remove')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (id: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n policy = removeRule(policy, id);\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" removed\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('toggle')\n .description('Enable or disable a rule')\n .argument('<id>', 'Rule ID')\n .argument('<state>', 'on | off')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (id: string, state: string, opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n let policy = await loadPolicy(projectPath);\n policy = toggleRule(policy, id, state === 'on');\n await savePolicy(projectPath, policy);\n console.log(chalk.green(`\\n ✅ Rule \"${id}\" ${state === 'on' ? 'enabled' : 'disabled'}\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('validate')\n .description('Validate current context selection against policies')\n .option('-p, --path <path>', 'Project path', '.')\n .option('-b, --budget <tokens>', 'Token budget', '50000')\n .option('-t, --task <task>', 'Task description', 'general review')\n .action(async (opts: { path?: string; budget?: string; task?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n const budget = parseInt(opts.budget ?? '50000', 10);\n\n const policy = await loadPolicy(projectPath);\n\n console.log(chalk.dim('\\n Analyzing project...'));\n const analysis = await analyzeProject(projectPath);\n\n console.log(chalk.dim(' Selecting context...'));\n const selection = await selectContext({\n task: opts.task ?? 'general review',\n analysis,\n budget,\n policies: policy,\n });\n\n const result = validateSelection(selection, policy, analysis.files);\n\n console.log('');\n if (result.passed) {\n console.log(chalk.bold.green(' ✅ Policy validation passed'));\n } else {\n console.log(chalk.bold.red(' ❌ Policy validation failed'));\n }\n\n if (result.violations.length > 0) {\n console.log('');\n console.log(chalk.bold(' Violations:'));\n for (const v of result.violations) {\n const icon = v.severity === 'error' ? chalk.red('✗') : chalk.yellow('⚠');\n console.log(` ${icon} ${v.message}`);\n }\n }\n\n if (result.warnings.length > 0) {\n console.log('');\n console.log(chalk.bold(' Warnings:'));\n for (const w of result.warnings) {\n console.log(` ${chalk.yellow('⚠')} ${w.message}`);\n }\n }\n console.log('');\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n )\n .addCommand(\n new Command('init')\n .description('Initialize default policy file')\n .option('-p, --path <path>', 'Project path', '.')\n .action(async (opts: { path?: string }) => {\n try {\n const projectPath = resolve(opts.path ?? '.');\n await savePolicy(projectPath, DEFAULT_POLICY);\n console.log(chalk.green(`\\n ✅ Default policy initialized at ${join(projectPath, POLICY_FILE)}\\n`));\n } catch (err: any) {\n console.error(chalk.red(`\\n Error: ${err.message}\\n`));\n process.exit(1);\n }\n }),\n );\n","import type {\n PolicySet,\n PolicyRule,\n PolicyRuleType,\n PolicyValidation,\n PolicyViolation,\n PolicyWarning,\n} from '../types/govern.js';\nimport type { ContextSelection, AnalyzedFile } from '../types/engine.js';\nimport { matchGlob } from '../engine/graph-utils.js';\n\n// ===== POLICY ENGINE =====\n//\n// YAML-backed rule engine for controlling what context gets included/excluded.\n// Policies are evaluated after selection to validate compliance.\n\nexport const DEFAULT_POLICY: PolicySet = {\n version: '1.0',\n name: 'default',\n rules: [\n {\n id: 'no-env',\n type: 'exclude-always',\n pattern: '**/*.env*',\n reason: 'Environment files must never be sent to AI',\n enabled: true,\n },\n {\n id: 'no-secrets',\n type: 'secret-block',\n reason: 'Files with detected secrets are blocked',\n enabled: true,\n },\n {\n id: 'min-coverage',\n type: 'coverage-minimum',\n threshold: 70,\n reason: 'Warn if context coverage drops below 70%',\n enabled: true,\n },\n ],\n};\n\n// ===== VALIDATION =====\n\nexport function validateSelection(\n selection: ContextSelection,\n policies: PolicySet,\n allFiles?: AnalyzedFile[],\n): PolicyValidation {\n const violations: PolicyViolation[] = [];\n const warnings: PolicyWarning[] = [];\n\n const includedPaths = new Set(selection.files.map((f) => f.relativePath));\n\n for (const rule of policies.rules) {\n if (!rule.enabled) continue;\n\n switch (rule.type) {\n case 'exclude-always': {\n if (!rule.pattern) break;\n const violatingFiles = selection.files.filter((f) =>\n matchGlob(f.relativePath, rule.pattern!),\n );\n for (const f of violatingFiles) {\n violations.push({\n rule,\n message: `File \"${f.relativePath}\" is included but matches exclude-always pattern \"${rule.pattern}\"`,\n severity: 'error',\n });\n }\n break;\n }\n\n case 'include-always': {\n if (!rule.pattern || !allFiles) break;\n const requiredFiles = allFiles.filter((f) =>\n matchGlob(f.relativePath, rule.pattern!),\n );\n for (const f of requiredFiles) {\n if (!includedPaths.has(f.relativePath)) {\n violations.push({\n rule,\n message: `File \"${f.relativePath}\" matches include-always pattern \"${rule.pattern}\" but is not included`,\n severity: 'warning',\n });\n }\n }\n break;\n }\n\n case 'coverage-minimum': {\n const threshold = rule.threshold ?? 70;\n if (selection.coverage.score < threshold) {\n warnings.push({\n rule,\n message: `Coverage ${selection.coverage.score}% is below minimum ${threshold}%`,\n currentValue: selection.coverage.score,\n threshold,\n });\n }\n break;\n }\n\n case 'risk-maximum': {\n const threshold = rule.threshold ?? 50;\n if (selection.riskScore > threshold) {\n warnings.push({\n rule,\n message: `Exclusion risk ${selection.riskScore}/100 exceeds maximum ${threshold}`,\n currentValue: selection.riskScore,\n threshold,\n });\n }\n break;\n }\n\n case 'budget-limit': {\n if (!rule.category || !rule.threshold) break;\n const categoryFiles = selection.files.filter((f) =>\n fileMatchesCategory(f.relativePath, rule.category!),\n );\n const categoryTokens = categoryFiles.reduce((s, f) => s + f.tokens, 0);\n const categoryPercent = selection.totalTokens > 0\n ? (categoryTokens / selection.totalTokens) * 100\n : 0;\n\n if (categoryPercent > rule.threshold) {\n warnings.push({\n rule,\n message: `Category \"${rule.category}\" uses ${Math.round(categoryPercent)}% of budget (max: ${rule.threshold}%)`,\n currentValue: Math.round(categoryPercent),\n threshold: rule.threshold,\n });\n }\n break;\n }\n }\n }\n\n return {\n passed: violations.filter((v) => v.severity === 'error').length === 0,\n violations,\n warnings,\n };\n}\n\n// ===== POLICY CRUD =====\n\nexport function addRule(policies: PolicySet, rule: PolicyRule): PolicySet {\n return {\n ...policies,\n rules: [...policies.rules, rule],\n };\n}\n\nexport function removeRule(policies: PolicySet, ruleId: string): PolicySet {\n return {\n ...policies,\n rules: policies.rules.filter((r) => r.id !== ruleId),\n };\n}\n\nexport function toggleRule(policies: PolicySet, ruleId: string, enabled: boolean): PolicySet {\n return {\n ...policies,\n rules: policies.rules.map((r) =>\n r.id === ruleId ? { ...r, enabled } : r,\n ),\n };\n}\n\n// ===== HELPERS =====\n\nfunction fileMatchesCategory(path: string, category: string): boolean {\n switch (category) {\n case 'test':\n return /\\.(test|spec)\\.[jt]sx?$/.test(path) || /\\/__tests__\\//.test(path) || /\\/tests?\\//.test(path);\n case 'config':\n return /\\.(config|rc)\\.[jt]s$/.test(path) || /\\.json$/.test(path) || /\\.ya?ml$/.test(path);\n case 'docs':\n return /\\.(md|txt|rst)$/.test(path);\n case 'types':\n return /types?\\//i.test(path) || /\\.d\\.ts$/.test(path);\n default:\n return path.includes(category);\n }\n}\n"],"mappings":"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","names":["Command","chalk","join","writeFile","join","writeFile","Command","chalk","resolve","readFile","stat","join","relative","resolve","basename","readFile","resolve","join","existsSync","join","stat","readFile","relative","basename","resolve","Command","resolve","chalk","Command","chalk","resolve","join","writeFile","createHash","readdir","stat","join","extname","relative","resolve","readdir","join","extname","stat","relative","createHash","resolve","resolve","resolve","risk","randomUUID","createHash","readFile","resolve","relative","Project","SyntaxKind","readFile","existsSync","join","TS_EXTENSIONS","emptyResult","readFile","emptyResult","Project","SyntaxKind","join","existsSync","createHash","createHash","readdir","join","mkdir","readFile","writeFile","randomUUID","Command","resolve","chalk","join","writeFile","Command","chalk","resolve","join","readFile","writeFile","readdir","mkdir","randomUUID","createHash","currentHash","join","mkdir","readFile","Command","resolve","chalk","writeFile","readdir","Command","chalk","Command","chalk","Command","chalk","resolve","join","readFile","writeFile","mkdir","POLICY_FILE","readFile","join","mkdir","writeFile","Command","resolve","chalk","Command","chalk"]}