@triedotdev/mcp 1.0.94 → 1.0.99
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +145 -137
- package/dist/{chunk-JAAIHNOE.js → chunk-APMV77PU.js} +21 -6
- package/dist/chunk-APMV77PU.js.map +1 -0
- package/dist/{chunk-HLSBTOVE.js → chunk-B3MNN3XB.js} +13 -18
- package/dist/{chunk-HLSBTOVE.js.map → chunk-B3MNN3XB.js.map} +1 -1
- package/dist/{chunk-IIF5XDCJ.js → chunk-DIZFGLXE.js} +787 -4696
- package/dist/chunk-DIZFGLXE.js.map +1 -0
- package/dist/{chunk-JO6RVXS6.js → chunk-F4NJ4CBP.js} +2 -2
- package/dist/{chunk-AZRCKBGF.js → chunk-FNCCZ3XB.js} +1222 -75
- package/dist/chunk-FNCCZ3XB.js.map +1 -0
- package/dist/chunk-G76DYVGX.js +136 -0
- package/dist/chunk-G76DYVGX.js.map +1 -0
- package/dist/chunk-HSNE46VE.js +956 -0
- package/dist/chunk-HSNE46VE.js.map +1 -0
- package/dist/{chunk-STEFLYPR.js → chunk-IXO4G4D3.js} +2 -2
- package/dist/{chunk-OEYIOOYB.js → chunk-JDHR5BDR.js} +2 -3
- package/dist/chunk-NIASHOAB.js +1304 -0
- package/dist/chunk-NIASHOAB.js.map +1 -0
- package/dist/{chunk-CKM6A3G6.js → chunk-OVRG5RP3.js} +6 -7
- package/dist/chunk-OVRG5RP3.js.map +1 -0
- package/dist/{chunk-RYRVEO2B.js → chunk-R3I2GCZC.js} +3 -3
- package/dist/{chunk-WT3XQCG2.js → chunk-R4AAPFXC.js} +2 -2
- package/dist/cli/create-agent.js +931 -7
- package/dist/cli/create-agent.js.map +1 -1
- package/dist/cli/main.js +151 -383
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +13 -20
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{goal-manager-HOZ7R2QV.js → goal-manager-LAOT4QQX.js} +6 -6
- package/dist/guardian-agent-M352CBE5.js +19 -0
- package/dist/index.js +1025 -1550
- package/dist/index.js.map +1 -1
- package/dist/{issue-store-DXIOP6AK.js → issue-store-W2X33X2X.js} +4 -4
- package/dist/{progress-LHI66U7B.js → progress-PQVEM7BR.js} +2 -2
- package/dist/{vibe-code-signatures-C5A4BHXD.js → vibe-code-signatures-ELEWJFGZ.js} +3 -3
- package/dist/{vulnerability-signatures-SVIHJQO5.js → vulnerability-signatures-EIJQX2TS.js} +3 -3
- package/dist/workers/agent-worker.js +2 -11
- package/dist/workers/agent-worker.js.map +1 -1
- package/package.json +2 -2
- package/dist/agent-smith-MYQ35URL.js +0 -14
- package/dist/agent-smith-runner-4TBONXCP.js +0 -573
- package/dist/agent-smith-runner-4TBONXCP.js.map +0 -1
- package/dist/cache-manager-RMPRPD5T.js +0 -10
- package/dist/chunk-AZRCKBGF.js.map +0 -1
- package/dist/chunk-CKM6A3G6.js.map +0 -1
- package/dist/chunk-E2ZATINO.js +0 -10879
- package/dist/chunk-E2ZATINO.js.map +0 -1
- package/dist/chunk-FFWNZUG2.js +0 -266
- package/dist/chunk-FFWNZUG2.js.map +0 -1
- package/dist/chunk-FK6DQKDY.js +0 -175
- package/dist/chunk-FK6DQKDY.js.map +0 -1
- package/dist/chunk-IFGF33R5.js +0 -279
- package/dist/chunk-IFGF33R5.js.map +0 -1
- package/dist/chunk-IIF5XDCJ.js.map +0 -1
- package/dist/chunk-JAAIHNOE.js.map +0 -1
- package/dist/chunk-ODWDESYP.js +0 -141
- package/dist/chunk-ODWDESYP.js.map +0 -1
- package/dist/chunk-OWBWNXSC.js +0 -955
- package/dist/chunk-OWBWNXSC.js.map +0 -1
- package/dist/chunk-Q764X2WD.js +0 -2124
- package/dist/chunk-Q764X2WD.js.map +0 -1
- package/dist/chunk-RE6ZWXJC.js +0 -279
- package/dist/chunk-RE6ZWXJC.js.map +0 -1
- package/dist/chunk-RNJ6JKMA.js +0 -2270
- package/dist/chunk-RNJ6JKMA.js.map +0 -1
- package/dist/chunk-Y62VM3ER.js +0 -536
- package/dist/chunk-Y62VM3ER.js.map +0 -1
- package/dist/git-45LZUUYA.js +0 -29
- package/dist/guardian-agent-RB2UQP5V.js +0 -21
- package/dist/progress-LHI66U7B.js.map +0 -1
- package/dist/vibe-code-signatures-C5A4BHXD.js.map +0 -1
- package/dist/vulnerability-signatures-SVIHJQO5.js.map +0 -1
- /package/dist/{chunk-JO6RVXS6.js.map → chunk-F4NJ4CBP.js.map} +0 -0
- /package/dist/{chunk-STEFLYPR.js.map → chunk-IXO4G4D3.js.map} +0 -0
- /package/dist/{chunk-OEYIOOYB.js.map → chunk-JDHR5BDR.js.map} +0 -0
- /package/dist/{chunk-RYRVEO2B.js.map → chunk-R3I2GCZC.js.map} +0 -0
- /package/dist/{chunk-WT3XQCG2.js.map → chunk-R4AAPFXC.js.map} +0 -0
- /package/dist/{agent-smith-MYQ35URL.js.map → goal-manager-LAOT4QQX.js.map} +0 -0
- /package/dist/{cache-manager-RMPRPD5T.js.map → guardian-agent-M352CBE5.js.map} +0 -0
- /package/dist/{git-45LZUUYA.js.map → issue-store-W2X33X2X.js.map} +0 -0
- /package/dist/{goal-manager-HOZ7R2QV.js.map → progress-PQVEM7BR.js.map} +0 -0
- /package/dist/{guardian-agent-RB2UQP5V.js.map → vibe-code-signatures-ELEWJFGZ.js.map} +0 -0
- /package/dist/{issue-store-DXIOP6AK.js.map → vulnerability-signatures-EIJQX2TS.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/global-memory.ts","../src/ai/client.ts","../src/storage/tiered-storage.ts","../src/guardian/gotcha-predictor.ts","../src/context/graph.ts","../src/context/store.ts"],"sourcesContent":["/**\n * Cross-Project Memory\n * \n * Stores and retrieves patterns across all projects.\n * Location: ~/.trie/memory/\n * \n * Phase 1 Hardening:\n * - SHA256 hashing for pattern IDs\n * - Atomic writes to prevent corruption\n * - Rotational backups for recovery\n * - Zod validation for data integrity\n */\n\nimport { mkdir, writeFile, readFile, readdir } from 'fs/promises';\nimport { createHash } from 'crypto';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport type { Issue } from '../types/index.js';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { GlobalPatternsIndexSchema, safeParseAndValidate } from './validation.js';\n\nconst GLOBAL_TRIE_DIR = join(homedir(), '.trie');\nconst GLOBAL_MEMORY_DIR = join(GLOBAL_TRIE_DIR, 'memory');\n\nexport interface GlobalPattern {\n id: string;\n pattern: string;\n description: string;\n severity: string;\n agent: string;\n occurrences: number;\n projects: string[];\n firstSeen: string;\n lastSeen: string;\n fixApplied?: {\n project: string;\n timestamp: string;\n fix: string;\n };\n}\n\nexport interface ProjectSummary {\n name: string;\n path: string;\n lastScan: string;\n healthScore: number;\n totalIssues: number;\n patterns: string[];\n}\n\n/**\n * Record issues to global memory\n */\nexport async function recordToGlobalMemory(\n issues: Issue[],\n projectName: string,\n projectPath: string,\n healthScore: number = 0\n): Promise<void> {\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n await mkdir(join(GLOBAL_MEMORY_DIR, 'projects'), { recursive: true });\n\n const patterns = await loadGlobalPatterns();\n const now = new Date().toISOString();\n\n for (const issue of issues) {\n const patternId = extractPatternId(issue);\n const existing = patterns.find(p => p.id === patternId);\n\n if (existing) {\n existing.occurrences++;\n existing.lastSeen = now;\n if (!existing.projects.includes(projectName)) {\n existing.projects.push(projectName);\n }\n } else {\n patterns.push({\n id: patternId,\n pattern: issue.issue.slice(0, 200),\n description: issue.fix.slice(0, 200),\n severity: issue.severity,\n agent: issue.agent,\n occurrences: 1,\n projects: [projectName],\n firstSeen: now,\n lastSeen: now,\n });\n }\n }\n\n await saveGlobalPatterns(patterns);\n\n const summaryPath = join(GLOBAL_MEMORY_DIR, 'projects', `${sanitizeName(projectName)}.json`);\n const summary: ProjectSummary = {\n name: projectName,\n path: projectPath,\n lastScan: now,\n healthScore,\n totalIssues: issues.length,\n patterns: [...new Set(issues.map(i => extractPatternId(i)))],\n };\n \n // Use atomic write for project summary\n await atomicWriteJSON(summaryPath, summary);\n}\n\n/**\n * Find patterns that appear across multiple projects\n */\nexport async function findCrossProjectPatterns(\n minOccurrences: number = 2\n): Promise<GlobalPattern[]> {\n const patterns = await loadGlobalPatterns();\n return patterns\n .filter(p => p.projects.length >= minOccurrences)\n .sort((a, b) => b.occurrences - a.occurrences);\n}\n\n/**\n * Check if an issue has been fixed in another project\n */\nexport async function findFixFromOtherProjects(\n issue: Issue\n): Promise<GlobalPattern | null> {\n const patterns = await loadGlobalPatterns();\n const patternId = extractPatternId(issue);\n const pattern = patterns.find(p => p.id === patternId);\n\n if (pattern?.fixApplied) {\n return pattern;\n }\n\n return null;\n}\n\n/**\n * Record that a pattern was fixed\n */\nexport async function recordPatternFix(\n issue: Issue,\n projectName: string,\n fix: string\n): Promise<void> {\n const patterns = await loadGlobalPatterns();\n const patternId = extractPatternId(issue);\n const pattern = patterns.find(p => p.id === patternId);\n\n if (pattern && !pattern.fixApplied) {\n pattern.fixApplied = {\n project: projectName,\n timestamp: new Date().toISOString(),\n fix: fix.slice(0, 500),\n };\n await saveGlobalPatterns(patterns);\n }\n}\n\n/**\n * Get all tracked projects\n */\nexport async function listTrackedProjects(): Promise<ProjectSummary[]> {\n const projectsDir = join(GLOBAL_MEMORY_DIR, 'projects');\n \n try {\n if (!existsSync(projectsDir)) return [];\n \n const files = await readdir(projectsDir);\n const summaries: ProjectSummary[] = [];\n \n for (const file of files) {\n if (!file.endsWith('.json')) continue;\n try {\n const content = await readFile(join(projectsDir, file), 'utf-8');\n summaries.push(JSON.parse(content));\n } catch {\n // Skip invalid files\n }\n }\n \n return summaries.sort((a, b) => \n new Date(b.lastScan).getTime() - new Date(a.lastScan).getTime()\n );\n } catch {\n return [];\n }\n}\n\n/**\n * Get global memory statistics\n */\nexport async function getGlobalMemoryStats(): Promise<{\n totalPatterns: number;\n crossProjectPatterns: number;\n trackedProjects: number;\n totalOccurrences: number;\n fixedPatterns: number;\n patternsByAgent: Record<string, number>;\n capacityInfo: {\n current: number;\n max: number;\n percentFull: number;\n isAtCap: boolean;\n };\n deduplicationStats: {\n uniquePatterns: number;\n averageOccurrences: number;\n };\n}> {\n const patterns = await loadGlobalPatterns();\n const projects = await listTrackedProjects();\n \n const MAX_PATTERNS = 500;\n \n // Count patterns by agent type\n const patternsByAgent: Record<string, number> = {};\n for (const pattern of patterns) {\n patternsByAgent[pattern.agent] = (patternsByAgent[pattern.agent] || 0) + 1;\n }\n \n const totalOccurrences = patterns.reduce((sum, p) => sum + p.occurrences, 0);\n const avgOccurrences = patterns.length > 0 ? totalOccurrences / patterns.length : 0;\n \n return {\n totalPatterns: patterns.length,\n crossProjectPatterns: patterns.filter(p => p.projects.length >= 2).length,\n trackedProjects: projects.length,\n totalOccurrences,\n fixedPatterns: patterns.filter(p => p.fixApplied).length,\n patternsByAgent,\n capacityInfo: {\n current: patterns.length,\n max: MAX_PATTERNS,\n percentFull: Math.round((patterns.length / MAX_PATTERNS) * 100),\n isAtCap: patterns.length >= MAX_PATTERNS,\n },\n deduplicationStats: {\n uniquePatterns: patterns.length,\n averageOccurrences: Math.round(avgOccurrences * 10) / 10,\n },\n };\n}\n\n/**\n * Update GLOBAL_MEMORY.md with current patterns\n */\nexport async function updateGlobalMemoryMd(): Promise<void> {\n const patterns = await loadGlobalPatterns();\n const crossProject = patterns.filter(p => p.projects.length >= 2);\n const projects = await listTrackedProjects();\n\n const lines: string[] = [\n '# Global Trie Memory',\n '',\n '> Auto-generated file tracking patterns across all your projects.',\n `> Last updated: ${new Date().toISOString()}`,\n '',\n '## Summary',\n '',\n `- **Projects tracked:** ${projects.length}`,\n `- **Total patterns:** ${patterns.length}`,\n `- **Cross-project patterns:** ${crossProject.length}`,\n '',\n '## Cross-Project Patterns',\n '',\n 'These issues appear in multiple projects:',\n '',\n ];\n \n for (const p of crossProject.slice(0, 20)) {\n lines.push(\n `### ${p.pattern.slice(0, 60)}${p.pattern.length > 60 ? '...' : ''}`,\n '',\n `- **Severity:** ${p.severity}`,\n `- **Agent:** ${p.agent}`,\n `- **Occurrences:** ${p.occurrences} across ${p.projects.length} projects`,\n `- **Projects:** ${p.projects.slice(0, 5).join(', ')}${p.projects.length > 5 ? '...' : ''}`,\n );\n if (p.fixApplied) {\n lines.push(`- **Fixed in:** ${p.fixApplied.project} on ${p.fixApplied.timestamp.split('T')[0]}`);\n } else {\n lines.push('- **Status:** Not fixed');\n }\n lines.push('');\n }\n\n lines.push(\n '## Tracked Projects',\n '',\n '| Project | Last Scan | Health | Issues |',\n '|---------|-----------|--------|--------|',\n );\n \n for (const p of projects.slice(0, 20)) {\n lines.push(`| ${p.name} | ${p.lastScan.split('T')[0]} | ${p.healthScore}% | ${p.totalIssues} |`);\n }\n\n lines.push('', '---', '', '*This file is auto-generated by Trie. Do not edit manually.*');\n\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n await writeFile(join(GLOBAL_MEMORY_DIR, 'GLOBAL_MEMORY.md'), lines.join('\\n'));\n}\n\n/**\n * Search global patterns\n */\nexport async function searchGlobalPatterns(\n query: string,\n options: {\n limit?: number;\n severity?: string[];\n agent?: string;\n } = {}\n): Promise<GlobalPattern[]> {\n const patterns = await loadGlobalPatterns();\n const limit = options.limit || 10;\n const queryTerms = query.toLowerCase().split(/\\s+/).filter(t => t.length > 2);\n \n const scored = patterns\n .filter(p => {\n if (options.severity && !options.severity.includes(p.severity)) return false;\n if (options.agent && p.agent !== options.agent) return false;\n return true;\n })\n .map(p => {\n const text = `${p.pattern} ${p.description} ${p.agent}`.toLowerCase();\n let score = 0;\n for (const term of queryTerms) {\n if (text.includes(term)) score++;\n }\n return { pattern: p, score };\n })\n .filter(s => s.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, limit);\n \n return scored.map(s => s.pattern);\n}\n\n// Private helpers\n\n/**\n * Load global patterns with validation and auto-recovery\n */\nasync function loadGlobalPatterns(): Promise<GlobalPattern[]> {\n const patternsPath = join(GLOBAL_MEMORY_DIR, 'global-patterns.json');\n \n try {\n if (existsSync(patternsPath)) {\n const content = await readFile(patternsPath, 'utf-8');\n const result = safeParseAndValidate(content, GlobalPatternsIndexSchema);\n \n if (result.success) {\n return result.data as GlobalPattern[];\n }\n \n // Validation failed - attempt recovery\n const backupManager = new BackupManager(patternsPath);\n if (await backupManager.recoverFromBackup()) {\n const recovered = await readFile(patternsPath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, GlobalPatternsIndexSchema);\n if (recoveredResult.success) {\n return recoveredResult.data as GlobalPattern[];\n }\n }\n }\n } catch {\n // File doesn't exist or recovery failed\n }\n \n return [];\n}\n\n/**\n * Save global patterns with backup and atomic write\n */\nasync function saveGlobalPatterns(patterns: GlobalPattern[]): Promise<void> {\n await mkdir(GLOBAL_MEMORY_DIR, { recursive: true });\n const patternsPath = join(GLOBAL_MEMORY_DIR, 'global-patterns.json');\n \n // Intelligent deduplication: merge patterns with same ID\n const patternMap = new Map<string, GlobalPattern>();\n for (const pattern of patterns) {\n const existing = patternMap.get(pattern.id);\n if (existing) {\n // Merge: update occurrences, projects, and timestamps\n existing.occurrences += pattern.occurrences;\n for (const proj of pattern.projects) {\n if (!existing.projects.includes(proj)) {\n existing.projects.push(proj);\n }\n }\n existing.lastSeen = pattern.lastSeen > existing.lastSeen ? pattern.lastSeen : existing.lastSeen;\n } else {\n patternMap.set(pattern.id, pattern);\n }\n }\n \n const deduplicated = Array.from(patternMap.values());\n \n // Intelligent pruning: prioritize recent, high-severity, cross-project patterns\n const pruned = intelligentPruneGlobalPatterns(deduplicated, 500);\n \n // Create backup before writing\n const backupManager = new BackupManager(patternsPath);\n await backupManager.createBackup();\n \n // Atomic write\n await atomicWriteJSON(patternsPath, pruned);\n}\n\n/**\n * Intelligently prune global patterns to target count\n * Prioritizes: cross-project, high severity, recent, fixed patterns\n */\nfunction intelligentPruneGlobalPatterns(patterns: GlobalPattern[], targetCount: number): GlobalPattern[] {\n if (patterns.length <= targetCount) {\n return patterns;\n }\n \n const severityWeight: Record<string, number> = {\n critical: 100,\n high: 50,\n moderate: 20,\n low: 10,\n info: 5,\n };\n \n const scored = patterns.map(pattern => {\n const ageInDays = (Date.now() - new Date(pattern.lastSeen).getTime()) / (1000 * 60 * 60 * 24);\n const recencyScore = Math.max(0, 100 - ageInDays * 2);\n const severityScore = severityWeight[pattern.severity] || 10;\n const crossProjectBonus = (pattern.projects.length - 1) * 30; // More projects = higher score\n const fixedBonus = pattern.fixApplied ? 20 : 0;\n const occurrenceScore = Math.min(pattern.occurrences * 2, 100);\n \n return {\n pattern,\n score: recencyScore + severityScore + crossProjectBonus + fixedBonus + occurrenceScore,\n };\n });\n \n return scored\n .sort((a, b) => b.score - a.score)\n .slice(0, targetCount)\n .map(s => s.pattern);\n}\n\n/**\n * Extract a pattern ID using SHA256 for proper deduplication\n * \n * Normalizes the issue text to group similar patterns:\n * - Lowercases\n * - Replaces code snippets with 'CODE'\n * - Replaces numbers with 'N'\n * - Removes quotes\n * \n * Uses SHA256 truncated to 12 chars for collision-free IDs.\n */\nfunction extractPatternId(issue: Issue): string {\n const normalized = issue.issue\n .toLowerCase()\n .replace(/`[^`]+`/g, 'CODE')\n .replace(/\\b\\d+\\b/g, 'N')\n .replace(/['\"]/g, '')\n .slice(0, 100);\n \n const hash = createHash('sha256')\n .update(normalized)\n .digest('hex')\n .slice(0, 12);\n \n return `${issue.agent}-${issue.severity}-${hash}`;\n}\n\nfunction sanitizeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_]/g, '-').toLowerCase();\n}\n","/**\n * Centralized AI Client\n * \n * Handles API key detection, graceful fallbacks, and AI-powered analysis.\n * All agents use this for AI-enhanced analysis.\n * \n * API Key Setup:\n * 1. Set ANTHROPIC_API_KEY in your environment\n * 2. Or add it to your MCP server config (mcp.json)\n * 3. Or create .env file in your project root\n * \n * If no API key is found, agents fall back to pattern-only mode.\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\n\n// Cached client instance\nlet clientInstance: Anthropic | null = null;\nlet apiKeyChecked = false;\nlet apiKeyAvailable = false;\n\n/**\n * Check if AI is available (API key is set)\n */\nexport function isAIAvailable(): boolean {\n if (!apiKeyChecked) {\n checkAPIKey();\n }\n return apiKeyAvailable;\n}\n\n/**\n * Check for API key in environment and config file\n */\nfunction checkAPIKey(): void {\n apiKeyChecked = true;\n \n // Check standard env var first\n const envApiKey = process.env.ANTHROPIC_API_KEY;\n \n if (envApiKey && envApiKey.length > 10) {\n apiKeyAvailable = true;\n return;\n }\n \n // Check config file for API key (synchronous read)\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const configPath = join(getTrieDirectory(workDir), 'config.json');\n \n if (existsSync(configPath)) {\n const configContent = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(configContent);\n \n if (config.apiKeys?.anthropic && config.apiKeys.anthropic.length > 10) {\n // Set it in process.env so Anthropic SDK can use it\n process.env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;\n apiKeyAvailable = true;\n return;\n }\n }\n } catch {\n // Config file doesn't exist or couldn't be read, continue without it\n }\n \n // Check .env files (common patterns)\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const envFiles = ['.env', '.env.local', '.env.production'];\n \n for (const envFile of envFiles) {\n const envPath = join(workDir, envFile);\n if (existsSync(envPath)) {\n const envContent = readFileSync(envPath, 'utf-8');\n const lines = envContent.split('\\n');\n \n for (const line of lines) {\n const match = line.match(/^\\s*ANTHROPIC_API_KEY\\s*=\\s*(.+)$/);\n if (match && match[1]) {\n const key = match[1].trim().replace(/^[\"']|[\"']$/g, ''); // Remove quotes\n if (key.length > 10) {\n process.env.ANTHROPIC_API_KEY = key;\n apiKeyAvailable = true;\n return;\n }\n }\n }\n }\n }\n } catch {\n // .env file doesn't exist or couldn't be read, continue without it\n }\n \n apiKeyAvailable = false;\n}\n\n/**\n * Get the Anthropic client (lazy initialized)\n * Throws if API key is not available\n */\nexport function getClient(): Anthropic {\n if (!isAIAvailable()) {\n throw new Error(\n 'ANTHROPIC_API_KEY not found. Set it in your environment to enable AI-powered analysis.\\n' +\n 'Example: export ANTHROPIC_API_KEY=sk-ant-...'\n );\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\n/**\n * Try to get client, return null if not available\n */\nexport function tryGetClient(): Anthropic | null {\n if (!isAIAvailable()) {\n return null;\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\nexport interface AIAnalysisRequest {\n systemPrompt: string;\n userPrompt: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface AIAnalysisResult {\n success: boolean;\n content: string;\n error?: string;\n tokensUsed?: {\n input: number;\n output: number;\n };\n}\n\n/**\n * Run AI analysis with the given prompts\n */\nexport async function runAIAnalysis(request: AIAnalysisRequest): Promise<AIAnalysisResult> {\n const client = tryGetClient();\n \n if (!client) {\n return {\n success: false,\n content: '',\n error: 'AI not available - ANTHROPIC_API_KEY not set'\n };\n }\n \n try {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: request.temperature ?? 0.3,\n system: request.systemPrompt,\n messages: [\n {\n role: 'user',\n content: request.userPrompt\n }\n ]\n });\n \n // Extract text content\n const textContent = response.content\n .filter((block): block is Anthropic.TextBlock => block.type === 'text')\n .map(block => block.text)\n .join('\\n');\n \n return {\n success: true,\n content: textContent,\n tokensUsed: {\n input: response.usage.input_tokens,\n output: response.usage.output_tokens\n }\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n \n // Check for specific error types\n if (errorMessage.includes('authentication') || errorMessage.includes('API key')) {\n return {\n success: false,\n content: '',\n error: 'Invalid API key. Check your ANTHROPIC_API_KEY.'\n };\n }\n \n if (errorMessage.includes('rate limit')) {\n return {\n success: false,\n content: '',\n error: 'Rate limited. Try again in a moment.'\n };\n }\n \n return {\n success: false,\n content: '',\n error: `AI analysis failed: ${errorMessage}`\n };\n }\n}\n\n/**\n * AI analysis for code issues\n */\nexport interface CodeIssueAnalysisRequest {\n issues: Array<{\n file: string;\n line?: number;\n issue: string;\n code?: string;\n }>;\n analysisType: 'validate' | 'expand' | 'fix' | 'explain';\n context?: string;\n}\n\n/**\n * Run AI analysis on code issues\n * Used by agents to validate, expand, or fix detected issues\n */\nexport async function analyzeCodeIssues(request: CodeIssueAnalysisRequest): Promise<AIAnalysisResult> {\n const systemPrompts: Record<CodeIssueAnalysisRequest['analysisType'], string> = {\n validate: `You are a senior code reviewer. Analyze the following issues detected by static analysis.\nFor each issue:\n1. Determine if it's a TRUE POSITIVE (real problem) or FALSE POSITIVE (not actually an issue)\n2. Provide a confidence score (0-100)\n3. Explain your reasoning briefly\n\nOutput format:\n### Issue 1: [file:line]\n**Verdict:** TRUE_POSITIVE / FALSE_POSITIVE\n**Confidence:** [0-100]\n**Reason:** [one line explanation]\n**Fix:** [specific fix if true positive]`,\n\n expand: `You are a security expert and senior architect. Given these detected code issues, look deeper:\n1. Are there related problems in the same code that were missed?\n2. What's the root cause of these patterns?\n3. What's the blast radius if these issues cause problems?\n4. What architectural changes would prevent these patterns?\n\nBe specific. Reference line numbers. Provide code examples.`,\n\n fix: `You are an expert programmer. For each issue, provide a specific fix:\n1. Show the exact code change needed\n2. Explain why this fix works\n3. Note any edge cases to consider\n\nUse markdown code blocks with the language specified.`,\n\n explain: `You are a patient teacher explaining code issues to a junior developer.\nFor each issue:\n1. Explain what the problem is in simple terms\n2. Explain why it's a problem (what could go wrong)\n3. Explain the fix and why it works\n4. Provide a learning resource if relevant`\n };\n\n const issuesText = request.issues.map((issue, i) => {\n let text = `### Issue ${i + 1}: ${issue.file}${issue.line ? ':' + issue.line : ''}\\n`;\n text += `**Problem:** ${issue.issue}\\n`;\n if (issue.code) {\n text += `**Code:**\\n\\`\\`\\`\\n${issue.code}\\n\\`\\`\\`\\n`;\n }\n return text;\n }).join('\\n');\n\n const userPrompt = `${request.context ? `Context: ${request.context}\\n\\n` : ''}${issuesText}`;\n\n return runAIAnalysis({\n systemPrompt: systemPrompts[request.analysisType],\n userPrompt,\n maxTokens: 4096,\n temperature: 0.2\n });\n}\n\n/**\n * Get status message about AI availability\n */\nexport function getAIStatusMessage(): string {\n if (isAIAvailable()) {\n return '[AI] AI-powered analysis enabled';\n }\n return '[!] AI not available (ANTHROPIC_API_KEY not set) - using pattern-only mode';\n}\n","/**\n * Tiered Storage System\n * \n * Three-tier architecture for context management:\n * - HOT: In-memory, current session data\n * - WARM: SQLite DB, queryable decisions/facts/blockers\n * - COLD: Full history, indexed but not actively queried\n * \n * This prevents context pollution by keeping agents focused on\n * relevant signal rather than dumping everything into context.\n */\n\nimport { writeFile, mkdir } from 'fs/promises';\nimport { join } from 'path';\nimport Database from 'better-sqlite3';\nimport type {\n Decision,\n Blocker,\n ExtractedSignal,\n ContextQuery,\n} from '../types/signal.js';\nimport { getTrieDirectory } from '../utils/workspace.js';\n\nexport class TieredStorage {\n private workDir: string;\n private hotCache: Map<string, any> = new Map();\n private warmDb: Database.Database | null = null;\n\n constructor(workDir: string) {\n this.workDir = workDir;\n }\n\n /**\n * Initialize storage directories and database\n */\n async initialize(): Promise<void> {\n const trieDir = getTrieDirectory(this.workDir);\n \n // Create directories\n await mkdir(join(trieDir, 'hot'), { recursive: true });\n await mkdir(join(trieDir, 'warm'), { recursive: true });\n await mkdir(join(trieDir, 'cold'), { recursive: true });\n\n // Initialize warm database\n const dbPath = join(trieDir, 'warm', 'decisions.db');\n this.warmDb = new Database(dbPath);\n \n // Create tables\n this.warmDb.exec(`\n CREATE TABLE IF NOT EXISTS decisions (\n id TEXT PRIMARY KEY,\n decision TEXT NOT NULL,\n context TEXT NOT NULL,\n reasoning TEXT,\n timestamp TEXT NOT NULL,\n who TEXT,\n files TEXT NOT NULL, -- JSON array\n tags TEXT NOT NULL, -- JSON array\n expandedTags TEXT, -- JSON array (with synonyms)\n relatedTo TEXT, -- JSON array\n tradeoffs TEXT, -- JSON array\n status TEXT NOT NULL,\n supersededBy TEXT,\n dependencies TEXT, -- JSON array (npm packages, services)\n codebaseArea TEXT, -- JSON array (frontend, backend, auth, etc.)\n domain TEXT, -- JSON array (payments, compliance, etc.)\n lastAccessed TEXT NOT NULL,\n accessCount INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS facts (\n id TEXT PRIMARY KEY,\n fact TEXT NOT NULL,\n source TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n tags TEXT NOT NULL, -- JSON array\n expandedTags TEXT, -- JSON array (with synonyms)\n relatedDecisions TEXT, -- JSON array\n confidence REAL NOT NULL,\n lastAccessed TEXT NOT NULL,\n accessCount INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS blockers (\n id TEXT PRIMARY KEY,\n blocker TEXT NOT NULL,\n impact TEXT NOT NULL,\n affectedAreas TEXT NOT NULL, -- JSON array\n timestamp TEXT NOT NULL,\n resolvedAt TEXT,\n resolution TEXT,\n tags TEXT NOT NULL, -- JSON array\n expandedTags TEXT, -- JSON array (with synonyms)\n lastAccessed TEXT NOT NULL,\n accessCount INTEGER DEFAULT 0\n );\n\n CREATE TABLE IF NOT EXISTS questions (\n id TEXT PRIMARY KEY,\n question TEXT NOT NULL,\n context TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n answeredAt TEXT,\n answer TEXT,\n relatedDecisions TEXT, -- JSON array\n tags TEXT NOT NULL, -- JSON array\n expandedTags TEXT, -- JSON array (with synonyms)\n lastAccessed TEXT NOT NULL,\n accessCount INTEGER DEFAULT 0\n );\n\n CREATE INDEX IF NOT EXISTS idx_decisions_tags ON decisions(tags);\n CREATE INDEX IF NOT EXISTS idx_decisions_expanded ON decisions(expandedTags);\n CREATE INDEX IF NOT EXISTS idx_decisions_timestamp ON decisions(timestamp);\n CREATE INDEX IF NOT EXISTS idx_decisions_status ON decisions(status);\n CREATE INDEX IF NOT EXISTS idx_decisions_area ON decisions(codebaseArea);\n CREATE INDEX IF NOT EXISTS idx_decisions_domain ON decisions(domain);\n CREATE INDEX IF NOT EXISTS idx_facts_tags ON facts(tags);\n CREATE INDEX IF NOT EXISTS idx_facts_expanded ON facts(expandedTags);\n CREATE INDEX IF NOT EXISTS idx_blockers_impact ON blockers(impact);\n CREATE INDEX IF NOT EXISTS idx_blockers_resolved ON blockers(resolvedAt);\n `);\n }\n\n /**\n * Store extracted signal with enriched metadata in warm storage\n */\n async storeSignal(signal: ExtractedSignal, metadata?: {\n expandedTags?: string[];\n dependencies?: string[];\n codebaseArea?: string[];\n domain?: string[];\n }): Promise<void> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const now = new Date().toISOString();\n\n // Store decisions\n const decisionStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO decisions \n (id, decision, context, reasoning, timestamp, who, files, tags, expandedTags, relatedTo, tradeoffs, status, supersededBy, dependencies, codebaseArea, domain, lastAccessed, accessCount)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)\n `);\n\n for (const dec of signal.decisions) {\n decisionStmt.run(\n dec.id,\n dec.decision,\n dec.context,\n dec.reasoning || null,\n dec.when,\n dec.who || null,\n JSON.stringify(dec.files),\n JSON.stringify(dec.tags),\n JSON.stringify(metadata?.expandedTags || []),\n JSON.stringify(dec.relatedTo || []),\n JSON.stringify(dec.tradeoffs || []),\n dec.status,\n dec.supersededBy || null,\n JSON.stringify(metadata?.dependencies || []),\n JSON.stringify(metadata?.codebaseArea || []),\n JSON.stringify(metadata?.domain || []),\n now\n );\n }\n\n // Store facts\n const factStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO facts\n (id, fact, source, timestamp, tags, expandedTags, relatedDecisions, confidence, lastAccessed, accessCount)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 0)\n `);\n\n for (const fact of signal.facts) {\n factStmt.run(\n fact.id,\n fact.fact,\n fact.source,\n fact.when,\n JSON.stringify(fact.tags),\n JSON.stringify(metadata?.expandedTags || []),\n JSON.stringify(fact.relatedDecisions || []),\n fact.confidence,\n now\n );\n }\n\n // Store blockers\n const blockerStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO blockers\n (id, blocker, impact, affectedAreas, timestamp, resolvedAt, resolution, tags, expandedTags, lastAccessed, accessCount)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)\n `);\n\n for (const blocker of signal.blockers) {\n blockerStmt.run(\n blocker.id,\n blocker.blocker,\n blocker.impact,\n JSON.stringify(blocker.affectedAreas),\n blocker.when,\n blocker.resolvedAt || null,\n blocker.resolution || null,\n JSON.stringify(blocker.tags),\n JSON.stringify(metadata?.expandedTags || []),\n now\n );\n }\n\n // Store questions\n const questionStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO questions\n (id, question, context, timestamp, answeredAt, answer, relatedDecisions, tags, expandedTags, lastAccessed, accessCount)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)\n `);\n\n for (const q of signal.questions) {\n questionStmt.run(\n q.id,\n q.question,\n q.context,\n q.when,\n q.answeredAt || null,\n q.answer || null,\n JSON.stringify(q.relatedDecisions || []),\n JSON.stringify(q.tags),\n JSON.stringify(metadata?.expandedTags || []),\n now\n );\n }\n }\n\n /**\n * Query decisions from warm storage with expanded tag matching\n */\n async queryDecisions(query: ContextQuery): Promise<Decision[]> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n let sql = 'SELECT * FROM decisions WHERE status = ?';\n const params: any[] = ['active'];\n\n // Add filters - search both tags and expandedTags for broader matching\n if (query.tags && query.tags.length > 0) {\n sql += ' AND (' + query.tags.map(() => '(tags LIKE ? OR expandedTags LIKE ?)').join(' OR ') + ')';\n for (const tag of query.tags) {\n params.push(`%\"${tag}\"%`, `%\"${tag}\"%`);\n }\n }\n\n // Filter by codebase area if specified\n if (query.filters?.codebaseArea) {\n sql += ' AND codebaseArea LIKE ?';\n params.push(`%\"${query.filters.codebaseArea}\"%`);\n }\n\n // Filter by domain if specified\n if (query.filters?.domain) {\n sql += ' AND domain LIKE ?';\n params.push(`%\"${query.filters.domain}\"%`);\n }\n\n if (query.timeWindow) {\n if (query.timeWindow.start) {\n sql += ' AND timestamp >= ?';\n params.push(query.timeWindow.start);\n }\n if (query.timeWindow.end) {\n sql += ' AND timestamp <= ?';\n params.push(query.timeWindow.end);\n }\n }\n\n sql += ' ORDER BY timestamp DESC';\n\n if (query.limit) {\n sql += ' LIMIT ?';\n params.push(query.limit);\n }\n\n const rows = this.warmDb.prepare(sql).all(...params) as any[];\n\n return rows.map(row => ({\n id: row.id,\n decision: row.decision,\n context: row.context,\n reasoning: row.reasoning,\n when: row.when,\n who: row.who,\n files: JSON.parse(row.files),\n tags: JSON.parse(row.tags),\n relatedTo: JSON.parse(row.relatedTo || '[]'),\n tradeoffs: JSON.parse(row.tradeoffs || '[]'),\n status: row.status,\n supersededBy: row.supersededBy\n }));\n }\n\n /**\n * Query blockers from warm storage with expanded tag matching\n */\n async queryBlockers(query: ContextQuery): Promise<Blocker[]> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n let sql = 'SELECT * FROM blockers WHERE resolvedAt IS NULL';\n const params: any[] = [];\n\n if (query.tags && query.tags.length > 0) {\n sql += ' AND (' + query.tags.map(() => '(tags LIKE ? OR expandedTags LIKE ?)').join(' OR ') + ')';\n for (const tag of query.tags) {\n params.push(`%\"${tag}\"%`, `%\"${tag}\"%`);\n }\n }\n\n sql += ' ORDER BY CASE impact WHEN \"critical\" THEN 1 WHEN \"high\" THEN 2 WHEN \"medium\" THEN 3 ELSE 4 END, timestamp DESC';\n\n if (query.limit) {\n sql += ' LIMIT ?';\n params.push(query.limit);\n }\n\n const rows = this.warmDb.prepare(sql).all(...params) as any[];\n\n return rows.map(row => ({\n id: row.id,\n blocker: row.blocker,\n impact: row.impact,\n affectedAreas: JSON.parse(row.affectedAreas),\n when: row.when,\n resolvedAt: row.resolvedAt,\n resolution: row.resolution,\n tags: JSON.parse(row.tags)\n }));\n }\n\n /**\n * Get hot cache item\n */\n getHot<T>(key: string): T | undefined {\n return this.hotCache.get(key);\n }\n\n /**\n * Set hot cache item\n */\n setHot<T>(key: string, value: T): void {\n this.hotCache.set(key, value);\n }\n\n /**\n * Clear hot cache\n */\n clearHot(): void {\n this.hotCache.clear();\n }\n\n /**\n * Archive old data to cold storage\n */\n async archiveToCold(olderThanDays: number = 90): Promise<void> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - olderThanDays);\n const cutoff = cutoffDate.toISOString();\n\n // Export to cold storage\n const coldDir = join(getTrieDirectory(this.workDir), 'cold');\n const archivePath = join(coldDir, `archive-${Date.now()}.json`);\n\n const decisions = this.warmDb.prepare('SELECT * FROM decisions WHERE timestamp < ? AND accessCount < 3').all(cutoff);\n const facts = this.warmDb.prepare('SELECT * FROM facts WHERE timestamp < ? AND accessCount < 3').all(cutoff);\n const blockers = this.warmDb.prepare('SELECT * FROM blockers WHERE timestamp < ? AND resolvedAt IS NOT NULL').all(cutoff);\n const questions = this.warmDb.prepare('SELECT * FROM questions WHERE timestamp < ? AND answeredAt IS NOT NULL').all(cutoff);\n\n await writeFile(archivePath, JSON.stringify({ decisions, facts, blockers, questions }, null, 2));\n\n // Delete from warm storage\n this.warmDb.prepare('DELETE FROM decisions WHERE timestamp < ? AND accessCount < 3').run(cutoff);\n this.warmDb.prepare('DELETE FROM facts WHERE timestamp < ? AND accessCount < 3').run(cutoff);\n this.warmDb.prepare('DELETE FROM blockers WHERE timestamp < ? AND resolvedAt IS NOT NULL').run(cutoff);\n this.warmDb.prepare('DELETE FROM questions WHERE timestamp < ? AND answeredAt IS NOT NULL').run(cutoff);\n }\n\n /**\n * Close database connection\n */\n close(): void {\n if (this.warmDb) {\n this.warmDb.close();\n this.warmDb = null;\n }\n }\n}\n\n/**\n * Get storage instance for working directory\n */\nconst storageInstances = new Map<string, TieredStorage>();\n\nexport function getStorage(workDir: string): TieredStorage {\n if (!storageInstances.has(workDir)) {\n storageInstances.set(workDir, new TieredStorage(workDir));\n }\n return storageInstances.get(workDir)!;\n}\n","import { ContextGraph } from '../context/graph.js';\nimport { searchIssues } from '../memory/issue-store.js';\nimport { scanForVulnerabilities } from '../trie/vulnerability-signatures.js';\nimport { scanForVibeCodeIssues } from '../trie/vibe-code-signatures.js';\nimport type { LinearTicketNode, LinearTicketNodeData } from '../context/nodes.js';\nimport { tryGetClient } from '../ai/client.js';\nimport { getStorage } from '../storage/tiered-storage.js';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nexport interface GotchaPrediction {\n id: string;\n message: string;\n confidence: number;\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n precedentId?: string;\n recommendation: string;\n evidence: {\n pastIncidents: string[];\n matchingPatterns: string[];\n relatedTickets: string[];\n };\n}\n\nexport class GotchaPredictor {\n private readonly projectPath: string;\n private readonly graph: ContextGraph;\n\n constructor(projectPath: string, graph: ContextGraph) {\n this.projectPath = projectPath;\n this.graph = graph;\n }\n\n async predictGotchas(changedFiles: string[]): Promise<GotchaPrediction[]> {\n const gotchas: GotchaPrediction[] = [];\n\n // 1. Get active Linear tickets\n const tickets = (await this.graph.listNodes()).filter(n => n.type === 'linear-ticket') as LinearTicketNode[];\n \n for (const file of changedFiles) {\n const fileGotchas = await this.predictForFile(file, tickets);\n gotchas.push(...fileGotchas);\n }\n\n return gotchas;\n }\n\n private async predictForFile(filePath: string, tickets: LinearTicketNode[]): Promise<GotchaPrediction[]> {\n const gotchas: GotchaPrediction[] = [];\n const fullPath = path.resolve(this.projectPath, filePath);\n\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n\n // 1. Run deterministic scanners for signatures\n const vulnerabilities = await scanForVulnerabilities(content, filePath);\n const vibeIssues = await scanForVibeCodeIssues(content, filePath);\n\n const signatures = [\n ...vulnerabilities.map(v => v.category),\n ...vibeIssues.map(v => v.category)\n ];\n\n // === NEW: Query warm storage for relevant decisions and blockers ===\n const storage = getStorage(this.projectPath);\n await storage.initialize();\n\n // Infer tags from file path and signatures\n const tags = this.extractTagsFromFile(filePath, signatures);\n \n // Query relevant decisions for this file/area\n const relevantDecisions = await storage.queryDecisions({\n tags,\n limit: 10,\n });\n\n // Query active blockers for this area\n const activeBlockers = await storage.queryBlockers({\n tags,\n limit: 5,\n });\n\n // === NEW: Add gotchas from decision ledger ===\n for (const decision of relevantDecisions) {\n // Check if this file is in the decision's file list\n if (decision.files.some(f => f.includes(filePath) || filePath.includes(f))) {\n gotchas.push({\n id: `gotcha-decision-${decision.id}`,\n message: `Decision: ${decision.decision}`,\n confidence: 0.85,\n riskLevel: 'medium',\n precedentId: decision.id,\n recommendation: decision.reasoning || 'Review this decision before making changes',\n evidence: {\n pastIncidents: [],\n matchingPatterns: decision.tags,\n relatedTickets: []\n }\n });\n }\n }\n\n // === NEW: Add gotchas from active blockers ===\n for (const blocker of activeBlockers) {\n gotchas.push({\n id: `gotcha-blocker-${blocker.id}`,\n message: `⚠️ Active Blocker: ${blocker.blocker}`,\n confidence: 0.95,\n riskLevel: blocker.impact === 'critical' ? 'critical' : \n blocker.impact === 'high' ? 'high' : 'medium',\n recommendation: `This area is currently blocked. Consider resolving this before making changes.`,\n evidence: {\n pastIncidents: [],\n matchingPatterns: blocker.tags,\n relatedTickets: []\n }\n });\n }\n\n for (const ticket of tickets) {\n const ticketData = ticket.data as LinearTicketNodeData;\n \n // Correlation 1: Ticket Intent vs Deterministic Signatures\n const intentMatch = this.correlateIntentWithSignatures(ticketData, signatures);\n if (intentMatch) {\n gotchas.push(intentMatch);\n }\n\n // Correlation 2: Historical Precedents\n const historicalPrecedents = await this.findHistoricalPrecedents(filePath, ticketData);\n if (historicalPrecedents) {\n gotchas.push(historicalPrecedents);\n }\n }\n\n return gotchas;\n }\n\n /**\n * Extract tags from file path and signatures for storage queries\n */\n private extractTagsFromFile(filePath: string, signatures: string[]): string[] {\n const tags = new Set<string>();\n\n // Add tags from file path\n const normalized = filePath.toLowerCase();\n if (normalized.includes('/auth/')) tags.add('auth');\n if (normalized.includes('/payment/')) tags.add('payments');\n if (normalized.includes('/api/')) tags.add('api');\n if (normalized.includes('/frontend/') || normalized.includes('/ui/')) tags.add('ui');\n if (normalized.includes('/backend/')) tags.add('backend');\n if (normalized.includes('/database/') || normalized.includes('/models/')) tags.add('database');\n\n // Add tags from signatures\n signatures.forEach(sig => tags.add(sig.toLowerCase()));\n\n return Array.from(tags);\n }\n\n private correlateIntentWithSignatures(ticket: LinearTicketNodeData, signatures: string[]): GotchaPrediction | null {\n const relevantSignatures = signatures.filter(sig => \n ticket.intentVibe.some(vibe => this.vibeToSignatureMap(vibe).includes(sig))\n );\n\n if (relevantSignatures.length > 0) {\n return {\n id: `gotcha-intent-${ticket.ticketId}-${Date.now()}`,\n message: `[${ticket.ticketId}] Working on \"${ticket.title}\" (${ticket.intentVibe.join(', ')}) in a file with ${relevantSignatures.join(', ')} signatures.`,\n confidence: 0.8,\n riskLevel: 'high',\n recommendation: `Be careful with ${relevantSignatures[0]} patterns as they correlate with the intent of your ticket.`,\n evidence: {\n pastIncidents: [],\n matchingPatterns: relevantSignatures,\n relatedTickets: [ticket.ticketId]\n }\n };\n }\n\n return null;\n }\n\n private async findHistoricalPrecedents(filePath: string, ticket: LinearTicketNodeData): Promise<GotchaPrediction | null> {\n // Search for historical issues similar to this ticket's description\n const similarIssues = await searchIssues(ticket.description, {\n workDir: this.projectPath,\n limit: 3\n });\n\n const relevantIssues = similarIssues.filter(r => r.issue.file === filePath || r.issue.file.includes(path.basename(filePath)));\n\n const [firstMatch] = relevantIssues;\n if (firstMatch) {\n const issue = firstMatch.issue;\n return {\n id: `gotcha-precedent-${ticket.ticketId}-${Date.now()}`,\n message: `A similar task in the past caused an issue: \"${issue.issue}\"`,\n confidence: 0.9,\n riskLevel: 'critical',\n precedentId: issue.id,\n recommendation: `Last time we worked on something similar here, we had to fix: \"${issue.fix}\". Check this first.`,\n evidence: {\n pastIncidents: [issue.id],\n matchingPatterns: [],\n relatedTickets: [ticket.ticketId]\n }\n };\n }\n\n return null;\n }\n\n private vibeToSignatureMap(vibe: string): string[] {\n const map: Record<string, string[]> = {\n 'performance': ['giant-file', 'performance', 'react-antipattern'],\n 'security': ['injection', 'secrets', 'auth', 'xss', 'crypto'],\n 'auth': ['auth', 'secrets', 'config'],\n 'bug': ['no-error-handling', 'async', 'error-handling'],\n 'feature': ['mixing-concerns', 'hardcoded'],\n 'refactor': ['code-smell', 'giant-file', 'mixing-concerns']\n };\n return map[vibe] || [];\n }\n\n async synthesizeGotchaExplanation(gotcha: GotchaPrediction): Promise<string> {\n const client = tryGetClient();\n if (!client) return gotcha.message;\n\n const prompt = `\n You are a JIT Defect Predictor. You found a potential \"gotcha\" for a developer.\n \n Ticket context: ${gotcha.evidence.relatedTickets.join(', ')}\n Signatures detected: ${gotcha.evidence.matchingPatterns.join(', ')}\n Past incidents: ${gotcha.evidence.pastIncidents.join(', ')}\n \n Raw message: ${gotcha.message}\n Recommendation: ${gotcha.recommendation}\n \n Explain this gotcha in a concise, human-friendly way (max 2 sentences). \n Make it sound like a senior dev giving a helpful nudge.\n `;\n\n try {\n const response = await client.messages.create({\n model: 'claude-3-5-sonnet-20240620',\n max_tokens: 100,\n messages: [{ role: 'user', content: prompt }]\n });\n\n const text = response.content\n .filter((block): block is { type: 'text'; text: string } => block.type === 'text')\n .map(block => block.text)\n .join('');\n \n return text.trim() || gotcha.message;\n } catch {\n return gotcha.message;\n }\n }\n}\n","import crypto from 'node:crypto';\nimport path from 'node:path';\n\nimport type { RiskLevel } from '../types/index.js';\nimport { ContextStore } from './store.js';\nimport type {\n ChangeNode,\n ChangeNodeData,\n ContextSnapshot,\n DecisionNode,\n DecisionNodeData,\n Edge,\n EdgeDirection,\n EdgeType,\n FileNode,\n FileNodeData,\n FixNode,\n FixNodeData,\n IncidentNode,\n IncidentNodeData,\n IssueNode,\n IssueNodeData,\n LinearTicketNode,\n LinearTicketNodeData,\n Node,\n NodeData,\n NodeType,\n PatternNode,\n PatternNodeData\n} from './types.js';\n\nexport class ContextGraph {\n private readonly store: ContextStore;\n private readonly projectPath: string;\n\n constructor(projectPath: string, dbPath?: string, store?: ContextStore) {\n this.projectPath = projectPath;\n this.store = store ?? new ContextStore(projectPath, dbPath);\n }\n\n get projectRoot(): string {\n return this.projectPath;\n }\n\n async addNode(type: 'file', data: FileNodeData): Promise<FileNode>;\n async addNode(type: 'change', data: ChangeNodeData): Promise<ChangeNode>;\n async addNode(type: 'incident', data: IncidentNodeData): Promise<IncidentNode>;\n async addNode(type: 'issue', data: IssueNodeData): Promise<IssueNode>;\n async addNode(type: 'pattern', data: PatternNodeData): Promise<PatternNode>;\n async addNode(type: 'fix', data: FixNodeData): Promise<FixNode>;\n async addNode(type: 'decision', data: DecisionNodeData): Promise<DecisionNode>;\n async addNode(type: 'linear-ticket', data: LinearTicketNodeData): Promise<LinearTicketNode>;\n async addNode(type: NodeType, data: NodeData): Promise<Node> {\n const now = new Date().toISOString();\n const id = this.generateNodeId(type, data);\n const node = {\n id,\n type,\n data,\n created_at: now,\n updated_at: now\n } as Node;\n\n this.store.addNode(node);\n return node;\n }\n\n async getNode(type: NodeType, id: string): Promise<Node | null> {\n return this.store.getNodeByType(type, id);\n }\n\n async updateNode(type: NodeType, id: string, updates: Partial<NodeData>): Promise<void> {\n const updated = this.store.updateNode(id, updates, new Date().toISOString());\n if (updated && updated.type !== type) {\n throw new Error(`Type mismatch for node ${id}: expected ${type} but found ${updated.type}`);\n }\n }\n\n async deleteNode(_type: NodeType, id: string): Promise<void> {\n this.store.deleteNode(id);\n }\n\n async addEdge(\n fromId: string,\n toId: string,\n type: EdgeType,\n metadata: Record<string, unknown> = {},\n weight = 1\n ): Promise<Edge> {\n const edge: Edge = {\n id: crypto.randomUUID(),\n from_id: fromId,\n to_id: toId,\n type,\n weight,\n metadata,\n created_at: new Date().toISOString()\n };\n\n this.store.addEdge(edge);\n return edge;\n }\n\n async getEdges(nodeId: string, direction: EdgeDirection = 'both'): Promise<Edge[]> {\n return this.store.getEdges(nodeId, direction);\n }\n\n async getIncidentsForFile(filePath: string): Promise<IncidentNode[]> {\n const fileNode = this.findFileNode(filePath);\n if (!fileNode) return [];\n\n const incidents = new Map<string, IncidentNode>();\n\n const affectEdges = this.store.getEdges(fileNode.id, 'in').filter((edge) => edge.type === 'affects');\n for (const edge of affectEdges) {\n const changeId = edge.from_id;\n const leadEdges = this.store.getEdges(changeId, 'out').filter((e) => e.type === 'leadTo');\n const causedByEdges = this.store.getEdges(changeId, 'in').filter((e) => e.type === 'causedBy');\n\n for (const le of leadEdges) {\n const incident = this.store.getNodeByType('incident', le.to_id);\n if (incident) incidents.set(incident.id, incident as IncidentNode);\n }\n\n for (const ce of causedByEdges) {\n const incident = this.store.getNodeByType('incident', ce.from_id);\n if (incident) incidents.set(incident.id, incident as IncidentNode);\n }\n }\n\n return Array.from(incidents.values());\n }\n\n async getPatternsForFile(filePath: string): Promise<PatternNode[]> {\n const normalized = this.normalizePath(filePath);\n const nodes = this.store.findNodesByType('pattern') as PatternNode[];\n\n return nodes.filter((node) =>\n node.data.appliesTo.some((pattern) => normalized.includes(pattern) || filePath.includes(pattern))\n );\n }\n\n async getRecentChanges(limit: number): Promise<ChangeNode[]> {\n const nodes = this.store.findNodesByType('change') as ChangeNode[];\n return nodes\n .sort((a, b) => new Date(b.data.timestamp).getTime() - new Date(a.data.timestamp).getTime())\n .slice(0, limit);\n }\n\n async calculateFileRisk(filePath: string): Promise<RiskLevel> {\n const fileNode = this.findFileNode(filePath);\n if (!fileNode) return 'low';\n\n // Simple heuristic based on incidents and changes\n const incidentScore = Math.min(fileNode.data.incidentCount * 2, 6);\n const changeScore = Math.min(fileNode.data.changeCount, 4);\n const baseScore = this.riskLevelToScore(fileNode.data.riskLevel);\n const total = baseScore + incidentScore + changeScore;\n\n if (total >= 10) return 'critical';\n if (total >= 7) return 'high';\n if (total >= 4) return 'medium';\n return 'low';\n }\n\n async listNodes(): Promise<Node[]> {\n return this.store.listNodes();\n }\n\n async listEdges(): Promise<Edge[]> {\n return this.store.listEdges();\n }\n\n async deleteEdge(id: string): Promise<void> {\n this.store.deleteEdge(id);\n }\n\n async getSnapshot(): Promise<ContextSnapshot> {\n return {\n nodes: this.store.listNodes(),\n edges: this.store.listEdges(),\n exported_at: new Date().toISOString()\n };\n }\n\n async applySnapshot(snapshot: ContextSnapshot): Promise<void> {\n for (const node of snapshot.nodes) {\n const existing = this.store.getNode(node.id);\n if (!existing || this.isNewer(node.updated_at, existing.updated_at)) {\n this.store.upsertNode(node);\n }\n }\n\n for (const edge of snapshot.edges) {\n const existing = this.store.getEdge(edge.id);\n if (!existing) {\n this.store.upsertEdge(edge);\n }\n }\n }\n\n private generateNodeId(type: NodeType, data: NodeData): string {\n if (type === 'file') {\n const fileData = data as FileNodeData;\n return this.normalizePath(fileData.path);\n }\n\n if (type === 'change') {\n const changeData = data as ChangeNodeData;\n if (changeData.commitHash) {\n return changeData.commitHash;\n }\n }\n\n if (type === 'linear-ticket') {\n const ticketData = data as LinearTicketNodeData;\n return `linear:${ticketData.ticketId}`;\n }\n\n return crypto.randomUUID();\n }\n\n private findFileNode(filePath: string): FileNode | null {\n const normalized = this.normalizePath(filePath);\n const nodes = this.store.findNodesByType('file') as FileNode[];\n return (\n nodes.find(\n (node) =>\n node.id === normalized ||\n this.normalizePath(node.data.path) === normalized ||\n node.data.path === filePath\n ) ?? null\n );\n }\n\n private normalizePath(filePath: string): string {\n return path.resolve(this.projectPath, filePath);\n }\n\n private riskLevelToScore(level: RiskLevel): number {\n switch (level) {\n case 'critical':\n return 6;\n case 'high':\n return 4;\n case 'medium':\n return 2;\n default:\n return 0;\n }\n }\n\n private isNewer(incoming: string, existing: string): boolean {\n return new Date(incoming).getTime() >= new Date(existing).getTime();\n }\n}\n","import Database, { type Database as DatabaseType } from 'better-sqlite3';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { getTrieDirectory } from '../utils/workspace.js';\n\nimport type { Edge, EdgeDirection, EdgeType, Node, NodeData, NodeType } from './types.js';\n\ntype NodeRow = {\n id: string;\n type: NodeType;\n data: string;\n created_at: string;\n updated_at: string;\n};\n\ntype EdgeRow = {\n id: string;\n from_id: string;\n to_id: string;\n type: EdgeType;\n weight: number;\n metadata: string | null;\n created_at: string;\n};\n\nexport class ContextStore {\n private db: DatabaseType;\n private readonly dbFilePath: string;\n\n constructor(projectPath: string, dbFilePath?: string) {\n this.dbFilePath = dbFilePath ?? path.join(getTrieDirectory(projectPath), 'context.db');\n this.ensureDirectory();\n\n this.db = new Database(this.dbFilePath);\n this.configure();\n this.prepareSchema();\n }\n\n get databasePath(): string {\n return this.dbFilePath;\n }\n\n addNode(node: Node): Node {\n const stmt = this.db.prepare(\n `INSERT INTO nodes (id, type, data, created_at, updated_at)\n VALUES (@id, @type, @data, @created_at, @updated_at)`\n );\n\n stmt.run({\n id: node.id,\n type: node.type,\n data: JSON.stringify(node.data),\n created_at: node.created_at,\n updated_at: node.updated_at\n });\n\n return node;\n }\n\n upsertNode(node: Node): Node {\n const stmt = this.db.prepare(\n `INSERT INTO nodes (id, type, data, created_at, updated_at)\n VALUES (@id, @type, @data, @created_at, @updated_at)\n ON CONFLICT(id) DO UPDATE SET\n type=excluded.type,\n data=excluded.data,\n updated_at=excluded.updated_at`\n );\n\n stmt.run({\n id: node.id,\n type: node.type,\n data: JSON.stringify(node.data),\n created_at: node.created_at,\n updated_at: node.updated_at\n });\n\n return node;\n }\n\n getNode(id: string): Node | null {\n const row = this.db.prepare('SELECT * FROM nodes WHERE id = ?').get(id) as NodeRow | undefined;\n return row ? this.mapNodeRow(row) : null;\n }\n\n getNodeByType(type: NodeType, id: string): Node | null {\n const row = this.db\n .prepare('SELECT * FROM nodes WHERE id = ? AND type = ?')\n .get(id, type) as NodeRow | undefined;\n return row ? this.mapNodeRow(row) : null;\n }\n\n updateNode(id: string, updates: Partial<NodeData>, updatedAt: string): Node | null {\n const existing = this.getNode(id);\n if (!existing) {\n return null;\n }\n\n const merged = {\n ...existing,\n data: { ...existing.data, ...updates },\n updated_at: updatedAt\n } as Node;\n\n this.db\n .prepare(\n `UPDATE nodes SET data = @data, updated_at = @updated_at\n WHERE id = @id`\n )\n .run({\n id,\n data: JSON.stringify(merged.data),\n updated_at: merged.updated_at\n });\n\n return merged;\n }\n\n deleteNode(id: string): void {\n const deleteEdges = this.db.prepare('DELETE FROM edges WHERE from_id = ? OR to_id = ?');\n const deleteNodeStmt = this.db.prepare('DELETE FROM nodes WHERE id = ?');\n\n const transaction = this.db.transaction((nodeId: string) => {\n deleteEdges.run(nodeId, nodeId);\n deleteNodeStmt.run(nodeId);\n });\n\n transaction(id);\n }\n\n listNodes(): Node[] {\n const rows = this.db.prepare('SELECT * FROM nodes').all() as NodeRow[];\n return rows.map((row) => this.mapNodeRow(row));\n }\n\n findNodesByType(type: NodeType): Node[] {\n const rows = this.db.prepare('SELECT * FROM nodes WHERE type = ?').all(type) as NodeRow[];\n return rows.map((row) => this.mapNodeRow(row));\n }\n\n addEdge(edge: Edge): Edge {\n const stmt = this.db.prepare(\n `INSERT INTO edges (id, from_id, to_id, type, weight, metadata, created_at)\n VALUES (@id, @from_id, @to_id, @type, @weight, @metadata, @created_at)`\n );\n\n stmt.run({\n id: edge.id,\n from_id: edge.from_id,\n to_id: edge.to_id,\n type: edge.type,\n weight: edge.weight,\n metadata: JSON.stringify(edge.metadata ?? {}),\n created_at: edge.created_at\n });\n\n return edge;\n }\n\n upsertEdge(edge: Edge): Edge {\n const stmt = this.db.prepare(\n `INSERT INTO edges (id, from_id, to_id, type, weight, metadata, created_at)\n VALUES (@id, @from_id, @to_id, @type, @weight, @metadata, @created_at)\n ON CONFLICT(id) DO UPDATE SET\n from_id=excluded.from_id,\n to_id=excluded.to_id,\n type=excluded.type,\n weight=excluded.weight,\n metadata=excluded.metadata`\n );\n\n stmt.run({\n id: edge.id,\n from_id: edge.from_id,\n to_id: edge.to_id,\n type: edge.type,\n weight: edge.weight,\n metadata: JSON.stringify(edge.metadata ?? {}),\n created_at: edge.created_at\n });\n\n return edge;\n }\n\n getEdge(id: string): Edge | null {\n const row = this.db.prepare('SELECT * FROM edges WHERE id = ?').get(id) as EdgeRow | undefined;\n return row ? this.mapEdgeRow(row) : null;\n }\n\n getEdges(nodeId: string, direction: EdgeDirection = 'both'): Edge[] {\n let rows: EdgeRow[];\n\n if (direction === 'in') {\n rows = this.db.prepare('SELECT * FROM edges WHERE to_id = ?').all(nodeId) as EdgeRow[];\n } else if (direction === 'out') {\n rows = this.db.prepare('SELECT * FROM edges WHERE from_id = ?').all(nodeId) as EdgeRow[];\n } else {\n rows = this.db\n .prepare('SELECT * FROM edges WHERE from_id = ? OR to_id = ?')\n .all(nodeId, nodeId) as EdgeRow[];\n }\n\n return rows.map((row) => this.mapEdgeRow(row));\n }\n\n listEdges(): Edge[] {\n const rows = this.db.prepare('SELECT * FROM edges').all() as EdgeRow[];\n return rows.map((row) => this.mapEdgeRow(row));\n }\n\n deleteEdge(id: string): void {\n this.db.prepare('DELETE FROM edges WHERE id = ?').run(id);\n }\n\n close(): void {\n this.db.close();\n }\n\n private ensureDirectory(): void {\n fs.mkdirSync(path.dirname(this.dbFilePath), { recursive: true });\n }\n\n private configure(): void {\n this.db.pragma('journal_mode = WAL');\n this.db.pragma('busy_timeout = 5000');\n this.db.pragma('synchronous = NORMAL');\n }\n\n private prepareSchema(): void {\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS nodes (\n id TEXT PRIMARY KEY,\n type TEXT NOT NULL,\n data TEXT NOT NULL,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE TABLE IF NOT EXISTS edges (\n id TEXT PRIMARY KEY,\n from_id TEXT NOT NULL,\n to_id TEXT NOT NULL,\n type TEXT NOT NULL,\n weight REAL NOT NULL DEFAULT 1,\n metadata TEXT DEFAULT '{}',\n created_at TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_nodes_type ON nodes(type);\n CREATE INDEX IF NOT EXISTS idx_edges_from ON edges(from_id);\n CREATE INDEX IF NOT EXISTS idx_edges_to ON edges(to_id);\n CREATE INDEX IF NOT EXISTS idx_edges_type ON edges(type);\n `);\n }\n\n private mapNodeRow(row: NodeRow): Node {\n return {\n id: row.id,\n type: row.type,\n data: JSON.parse(row.data),\n created_at: row.created_at,\n updated_at: row.updated_at\n } as Node;\n }\n\n private mapEdgeRow(row: EdgeRow): Edge {\n return {\n id: row.id,\n from_id: row.from_id,\n to_id: row.to_id,\n type: row.type,\n weight: row.weight,\n created_at: row.created_at,\n metadata: row.metadata ? (JSON.parse(row.metadata) as Record<string, unknown>) : {}\n };\n }\n}\n"],"mappings":"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","names":["existsSync","join","join","existsSync","writeFile","mkdir","join","mkdir","join","writeFile","path","Database","fs","path","path","Database","fs","path"]}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getGuardianState
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-R3I2GCZC.js";
|
|
4
4
|
import {
|
|
5
5
|
BackupManager,
|
|
6
6
|
atomicWriteJSON,
|
|
7
7
|
getMemoryStats,
|
|
8
8
|
safeParseAndValidate,
|
|
9
9
|
searchIssues
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JDHR5BDR.js";
|
|
11
11
|
import {
|
|
12
12
|
getTrieDirectory
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-R4AAPFXC.js";
|
|
14
14
|
|
|
15
15
|
// src/guardian/insight-store.ts
|
|
16
16
|
import { mkdir, readFile } from "fs/promises";
|
|
@@ -563,7 +563,6 @@ var GoalManager = class {
|
|
|
563
563
|
agentToCategory(agent) {
|
|
564
564
|
const categoryMap = {
|
|
565
565
|
"security": "security",
|
|
566
|
-
"privacy": "security",
|
|
567
566
|
"soc2": "security",
|
|
568
567
|
"performance": "performance",
|
|
569
568
|
"accessibility": "quality",
|
|
@@ -745,7 +744,7 @@ var GoalManager = class {
|
|
|
745
744
|
}
|
|
746
745
|
if (desc.includes("security") || desc.includes("vulnerab") || desc.includes("fix security")) {
|
|
747
746
|
const securityIssues = issues.filter(
|
|
748
|
-
(r) => r.issue.agent === "security" || r.issue.
|
|
747
|
+
(r) => r.issue.agent === "security" || r.issue.severity === "critical"
|
|
749
748
|
);
|
|
750
749
|
return securityIssues.length;
|
|
751
750
|
}
|
|
@@ -898,7 +897,7 @@ var GoalManager = class {
|
|
|
898
897
|
});
|
|
899
898
|
} else if (desc.includes("security") || desc.includes("vulnerab") || desc.includes("fix security")) {
|
|
900
899
|
matchingResolved = resolved.filter(
|
|
901
|
-
(i) => i.agent === "security" || i.
|
|
900
|
+
(i) => i.agent === "security" || i.severity === "critical"
|
|
902
901
|
);
|
|
903
902
|
} else if (desc.includes("type") || desc.includes("typescript") || desc.includes("any type")) {
|
|
904
903
|
matchingResolved = resolved.filter(
|
|
@@ -1042,4 +1041,4 @@ export {
|
|
|
1042
1041
|
getGoalManager,
|
|
1043
1042
|
clearGoalManagers
|
|
1044
1043
|
};
|
|
1045
|
-
//# sourceMappingURL=chunk-
|
|
1044
|
+
//# sourceMappingURL=chunk-OVRG5RP3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/guardian/insight-store.ts","../src/guardian/goal-manager.ts"],"sourcesContent":["/**\n * Insight Store - Persistent storage for Guardian insights\n * \n * Phase 1 of Guardian Agency Plan: Fix critical persistence gaps\n * \n * Persists to: .trie/memory/guardian-insights.json\n * \n * Features:\n * - Insight persistence across restarts\n * - Cooldown state persistence (prevents duplicate insights)\n * - Dismissed insight tracking\n * - Atomic writes with backup rotation\n * - Zod validation for data integrity\n */\n\nimport { mkdir, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { getTrieDirectory } from '../utils/workspace.js';\nimport { z } from 'zod';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { safeParseAndValidate } from '../memory/validation.js';\n\n// ============================================================================\n// Schemas\n// ============================================================================\n\n/**\n * Schema for insight details\n */\nexport const InsightDetailsSchema = z.object({\n affectedFiles: z.array(z.string()).optional(),\n issueBreakdown: z.record(z.string(), z.number()).optional(),\n examples: z.array(z.string()).optional(),\n trend: z.enum(['improving', 'stable', 'worsening']).optional(),\n comparison: z.string().optional(),\n resolvedCount: z.number().optional(),\n resolvedIssues: z.array(z.object({\n file: z.string(),\n line: z.number().optional(),\n issue: z.string(),\n agent: z.string(),\n resolvedAt: z.string().optional(),\n })).optional(),\n summary: z.string().optional(),\n});\n\n/**\n * Schema for a Guardian insight\n */\nexport const GuardianInsightSchema = z.object({\n id: z.string(),\n type: z.enum(['observation', 'warning', 'suggestion', 'celebration', 'question']),\n message: z.string(),\n context: z.string().optional(),\n suggestedAction: z.string().optional(),\n actionCommand: z.string().optional(),\n relatedIssues: z.array(z.string()),\n priority: z.number().min(1).max(10),\n timestamp: z.number(),\n dismissed: z.boolean(),\n category: z.enum(['security', 'quality', 'performance', 'pattern', 'progress', 'general']),\n details: InsightDetailsSchema.optional(),\n});\n\nexport type GuardianInsight = z.infer<typeof GuardianInsightSchema>;\n\n/**\n * Schema for the entire insight store file\n */\nexport const InsightStoreDataSchema = z.object({\n version: z.literal(1),\n insights: z.array(GuardianInsightSchema),\n cooldowns: z.record(z.string(), z.number()), // insightKey -> timestamp\n dismissedIds: z.array(z.string()), // Track dismissed insight IDs permanently\n lastUpdated: z.string(),\n});\n\nexport type InsightStoreData = z.infer<typeof InsightStoreDataSchema>;\n\n// ============================================================================\n// InsightStore Class\n// ============================================================================\n\n/**\n * Persistent store for Guardian insights\n * \n * Usage:\n * ```typescript\n * const store = new InsightStore(projectPath);\n * await store.load();\n * \n * await store.addInsight(insight);\n * const active = store.getActiveInsights();\n * await store.dismissInsight(insightId);\n * ```\n */\nexport class InsightStore {\n private projectPath: string;\n private data: InsightStoreData;\n private loaded: boolean = false;\n private dirty: boolean = false;\n \n // Default cooldown periods (in ms)\n static readonly COOLDOWNS: Record<string, number> = {\n 'pre-push-warning': 60000, // 1 min between pre-push warnings\n 'security-warning': 30000, // 30s between security warnings\n 'new-issues': 30000, // 30s between new issue observations\n 'celebration': 60000, // 1 min between celebrations\n 'pattern-suggestion': 120000, // 2 min between pattern suggestions\n 'accessibility-visual-qa': 300000, // 5 min between visual QA suggestions\n 'goal-suggestion': 300000, // 5 min between goal suggestions\n 'risk-prediction': 180000, // 3 min between risk predictions\n 'hypothesis-update': 600000, // 10 min between hypothesis updates\n 'auto-escalation': 300000, // 5 min between auto-escalations\n };\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n this.data = this.createEmptyData();\n }\n \n /**\n * Get the storage file path\n */\n private getStorePath(): string {\n return join(getTrieDirectory(this.projectPath), 'memory', 'guardian-insights.json');\n }\n \n /**\n * Create empty data structure\n */\n private createEmptyData(): InsightStoreData {\n return {\n version: 1,\n insights: [],\n cooldowns: {},\n dismissedIds: [],\n lastUpdated: new Date().toISOString(),\n };\n }\n \n /**\n * Load insights from disk\n * \n * If the file is corrupted, attempts recovery from backup.\n * Returns empty data if no valid file/backup exists.\n */\n async load(): Promise<InsightStoreData> {\n if (this.loaded) {\n return this.data;\n }\n \n const storePath = this.getStorePath();\n \n try {\n if (existsSync(storePath)) {\n const content = await readFile(storePath, 'utf-8');\n const result = safeParseAndValidate(content, InsightStoreDataSchema);\n \n if (result.success) {\n this.data = result.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n \n // Validation failed - attempt recovery from backup\n console.error(` Insight store corrupted: ${result.error}`);\n const backupManager = new BackupManager(storePath);\n \n if (await backupManager.recoverFromBackup()) {\n console.error(' Recovered from backup');\n const recovered = await readFile(storePath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, InsightStoreDataSchema);\n if (recoveredResult.success) {\n this.data = recoveredResult.data;\n this.loaded = true;\n // Deduplicate any existing duplicate insights\n this.deduplicateInsights();\n return this.data;\n }\n }\n \n console.error(' No valid backup found, starting fresh');\n }\n } catch (error) {\n // File doesn't exist or recovery failed - start fresh\n console.error(` Could not load insight store: ${error}`);\n }\n \n this.data = this.createEmptyData();\n this.loaded = true;\n return this.data;\n }\n \n /**\n * Deduplicate existing insights on load\n * Keeps the most recent instance of each unique insight\n */\n private deduplicateInsights(): void {\n const seen = new Map<string, number>(); // contentKey -> index of first occurrence\n const toRemove: number[] = [];\n \n // Process from newest to oldest (insights are sorted by recency)\n for (let i = 0; i < this.data.insights.length; i++) {\n const insight = this.data.insights[i];\n if (!insight) continue;\n \n const contentKey = this.getContentKey(insight);\n \n if (seen.has(contentKey)) {\n // This is a duplicate - mark for removal\n toRemove.push(i);\n } else {\n seen.set(contentKey, i);\n }\n }\n \n // Remove duplicates (reverse order to preserve indices)\n if (toRemove.length > 0) {\n for (let i = toRemove.length - 1; i >= 0; i--) {\n const idx = toRemove[i];\n if (idx !== undefined) {\n this.data.insights.splice(idx, 1);\n }\n }\n this.dirty = true;\n }\n }\n \n /**\n * Save insights to disk\n * \n * Creates backup before writing, uses atomic write.\n */\n async save(): Promise<void> {\n if (!this.dirty && this.loaded) {\n return; // No changes to save\n }\n \n const storePath = this.getStorePath();\n const memoryDir = join(getTrieDirectory(this.projectPath), 'memory');\n \n // Ensure directory exists\n await mkdir(memoryDir, { recursive: true });\n \n // Create backup before writing\n const backupManager = new BackupManager(storePath);\n await backupManager.createBackup();\n \n // Update timestamp\n this.data.lastUpdated = new Date().toISOString();\n \n // Atomic write\n await atomicWriteJSON(storePath, this.data);\n \n this.dirty = false;\n }\n \n /**\n * Generate a content-based key for deduplication\n * Insights with the same content key are considered duplicates\n */\n private getContentKey(insight: GuardianInsight): string {\n // Normalize the message by removing specific numbers/counts that might vary slightly\n // e.g., \"Found 30 security issues\" and \"Found 31 security issues\" are the same insight\n const normalizedMessage = insight.message\n .replace(/\\d+/g, 'N') // Replace all numbers with N\n .toLowerCase()\n .trim();\n \n return `${insight.type}:${insight.category}:${normalizedMessage}`;\n }\n \n /**\n * Add an insight to the store\n * \n * Checks for duplicates using both insight ID and content similarity.\n * If a similar insight already exists (same type, category, and normalized message),\n * updates its timestamp instead of creating a duplicate.\n * Respects cooldowns to prevent insight spam.\n */\n async addInsight(insight: GuardianInsight): Promise<boolean> {\n await this.load();\n \n // Check if already exists by ID\n if (this.data.insights.some(i => i.id === insight.id)) {\n return false;\n }\n \n // Check if ID was previously dismissed (don't re-add)\n if (this.data.dismissedIds.includes(insight.id)) {\n return false;\n }\n \n // Check for content-based duplicates (same type, category, similar message)\n const contentKey = this.getContentKey(insight);\n const existingIndex = this.data.insights.findIndex(i => \n !i.dismissed && this.getContentKey(i) === contentKey\n );\n \n if (existingIndex >= 0) {\n // Update existing insight instead of adding duplicate\n const existing = this.data.insights[existingIndex];\n if (existing) {\n // Update with new data but keep the original ID\n existing.timestamp = insight.timestamp;\n existing.message = insight.message; // Update with current counts\n existing.details = insight.details; // Update details\n existing.relatedIssues = insight.relatedIssues;\n existing.suggestedAction = insight.suggestedAction;\n \n // Move to front of list\n this.data.insights.splice(existingIndex, 1);\n this.data.insights.unshift(existing);\n \n this.dirty = true;\n await this.save();\n }\n return false; // Return false to indicate no new insight was created\n }\n \n // Add to front of list\n this.data.insights.unshift(insight);\n \n // Keep only last 100 insights\n if (this.data.insights.length > 100) {\n this.data.insights = this.data.insights.slice(0, 100);\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Check if a cooldown has expired for an insight type\n */\n canCreateInsight(insightKey: string): boolean {\n const lastTime = this.data.cooldowns[insightKey];\n const cooldown = InsightStore.COOLDOWNS[insightKey] || 30000;\n \n if (!lastTime) return true;\n return Date.now() - lastTime > cooldown;\n }\n \n /**\n * Mark that an insight type was created (set cooldown)\n */\n async markInsightCreated(insightKey: string): Promise<void> {\n await this.load();\n this.data.cooldowns[insightKey] = Date.now();\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get active (non-dismissed) insights\n * \n * Returns insights sorted by priority (highest first),\n * limited to the specified count.\n */\n getActiveInsights(limit: number = 5): GuardianInsight[] {\n return this.data.insights\n .filter(i => !i.dismissed)\n .sort((a, b) => b.priority - a.priority)\n .slice(0, limit);\n }\n \n /**\n * Get all insights (including dismissed)\n */\n getAllInsights(): GuardianInsight[] {\n return [...this.data.insights];\n }\n \n /**\n * Dismiss an insight by ID\n */\n async dismissInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n insight.dismissed = true;\n \n // Track permanently dismissed IDs\n if (!this.data.dismissedIds.includes(insightId)) {\n this.data.dismissedIds.push(insightId);\n \n // Keep only last 500 dismissed IDs\n if (this.data.dismissedIds.length > 500) {\n this.data.dismissedIds = this.data.dismissedIds.slice(-500);\n }\n }\n \n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Remove an insight entirely\n */\n async removeInsight(insightId: string): Promise<boolean> {\n await this.load();\n \n const index = this.data.insights.findIndex(i => i.id === insightId);\n if (index === -1) {\n return false;\n }\n \n this.data.insights.splice(index, 1);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Clear all cooldowns\n */\n async clearCooldowns(): Promise<void> {\n await this.load();\n this.data.cooldowns = {};\n this.dirty = true;\n await this.save();\n }\n \n /**\n * Get insight by ID\n */\n getInsight(insightId: string): GuardianInsight | undefined {\n return this.data.insights.find(i => i.id === insightId);\n }\n \n /**\n * Update an existing insight\n */\n async updateInsight(insightId: string, updates: Partial<GuardianInsight>): Promise<boolean> {\n await this.load();\n \n const insight = this.data.insights.find(i => i.id === insightId);\n if (!insight) {\n return false;\n }\n \n Object.assign(insight, updates);\n this.dirty = true;\n await this.save();\n \n return true;\n }\n \n /**\n * Get insights by category\n */\n getInsightsByCategory(category: GuardianInsight['category']): GuardianInsight[] {\n return this.data.insights.filter(i => i.category === category && !i.dismissed);\n }\n \n /**\n * Get insights by type\n */\n getInsightsByType(type: GuardianInsight['type']): GuardianInsight[] {\n return this.data.insights.filter(i => i.type === type && !i.dismissed);\n }\n \n /**\n * Get insights from the last N hours\n */\n getRecentInsights(hours: number = 24): GuardianInsight[] {\n const cutoff = Date.now() - (hours * 60 * 60 * 1000);\n return this.data.insights.filter(i => i.timestamp >= cutoff);\n }\n \n /**\n * Get statistics about insights\n */\n getStats(): {\n total: number;\n active: number;\n dismissed: number;\n byCategory: Record<string, number>;\n byType: Record<string, number>;\n } {\n const stats = {\n total: this.data.insights.length,\n active: 0,\n dismissed: 0,\n byCategory: {} as Record<string, number>,\n byType: {} as Record<string, number>,\n };\n \n for (const insight of this.data.insights) {\n if (insight.dismissed) {\n stats.dismissed++;\n } else {\n stats.active++;\n }\n \n stats.byCategory[insight.category] = (stats.byCategory[insight.category] || 0) + 1;\n stats.byType[insight.type] = (stats.byType[insight.type] || 0) + 1;\n }\n \n return stats;\n }\n \n /**\n * Prune old insights (older than N days)\n */\n async pruneOldInsights(daysToKeep: number = 30): Promise<number> {\n await this.load();\n \n const cutoff = Date.now() - (daysToKeep * 24 * 60 * 60 * 1000);\n const originalCount = this.data.insights.length;\n \n this.data.insights = this.data.insights.filter(i => i.timestamp >= cutoff);\n \n const pruned = originalCount - this.data.insights.length;\n if (pruned > 0) {\n this.dirty = true;\n await this.save();\n }\n \n return pruned;\n }\n \n /**\n * Check if the store has been loaded\n */\n isLoaded(): boolean {\n return this.loaded;\n }\n \n /**\n * Force reload from disk\n */\n async reload(): Promise<InsightStoreData> {\n this.loaded = false;\n this.dirty = false;\n return this.load();\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst insightStores: Map<string, InsightStore> = new Map();\n\n/**\n * Get the InsightStore for a project (singleton per project)\n */\nexport function getInsightStore(projectPath: string): InsightStore {\n let store = insightStores.get(projectPath);\n if (!store) {\n store = new InsightStore(projectPath);\n insightStores.set(projectPath, store);\n }\n return store;\n}\n\n/**\n * Clear all InsightStore instances (for testing)\n */\nexport function clearInsightStores(): void {\n insightStores.clear();\n}\n","/**\n * Goal Manager - Autonomous goal generation and tracking\n * \n * Phase 2 of Guardian Agency Plan: Autonomous Goals\n * \n * Features:\n * - Auto-generates goals from incident patterns\n * - Tracks goal progress over time\n * - Presents goals to users for acceptance/rejection\n * - Adaptive goal difficulty based on team velocity\n * - Goal achievement celebrations\n */\n\nimport type { Goal } from './guardian-state.js';\nimport { getGuardianState } from './guardian-state.js';\nimport { getInsightStore, type GuardianInsight } from './insight-store.js';\nimport { searchIssues, getMemoryStats } from '../memory/issue-store.js';\nimport { basename } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A pattern detected from incident history\n */\nexport interface IncidentPattern {\n type: 'file-cluster' | 'severity-trend' | 'agent-concentration' | 'time-pattern';\n description: string;\n metric: string;\n currentValue: number;\n suggestedTarget: number;\n confidence: number; // 0-1\n evidence: string[];\n category?: 'security' | 'quality' | 'performance' | 'coverage' | 'general';\n}\n\n/**\n * Goal opportunity - a potential goal before user acceptance\n */\nexport interface GoalOpportunity {\n pattern: IncidentPattern;\n goal: Omit<Goal, 'id' | 'createdAt' | 'updatedAt'>;\n reasoning: string;\n}\n\n/**\n * Configuration for goal generation\n */\nexport interface GoalGenerationConfig {\n minConfidence: number; // Minimum confidence to suggest goal (0-1)\n maxActiveGoals: number; // Maximum concurrent active goals\n goalDurationDays: number; // Default goal duration in days\n reductionTargetPercent: number; // Target reduction percentage\n}\n\nconst DEFAULT_CONFIG: GoalGenerationConfig = {\n minConfidence: 0.6,\n maxActiveGoals: 3,\n goalDurationDays: 14,\n reductionTargetPercent: 50,\n};\n\n// ============================================================================\n// GoalManager Class\n// ============================================================================\n\n/**\n * Manages autonomous goal generation and tracking\n */\nexport class GoalManager {\n private projectPath: string;\n private config: GoalGenerationConfig;\n private guardianState;\n private insightStore;\n \n constructor(projectPath: string, config: Partial<GoalGenerationConfig> = {}) {\n this.projectPath = projectPath;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.guardianState = getGuardianState(projectPath);\n this.insightStore = getInsightStore(projectPath);\n }\n \n /**\n * Analyze incident patterns from memory\n */\n async analyzeIncidentPatterns(): Promise<IncidentPattern[]> {\n const patterns: IncidentPattern[] = [];\n \n try {\n // Get recent issues for analysis\n const stats = await getMemoryStats(this.projectPath);\n const recentIssues = await searchIssues('', {\n workDir: this.projectPath,\n limit: 500,\n includeResolved: true,\n });\n \n if (recentIssues.length < 5) {\n return patterns; // Not enough data for pattern detection\n }\n \n // 1. Analyze file clusters (files with most issues)\n const fileIssueCount = new Map<string, number>();\n for (const { issue } of recentIssues) {\n const file = issue.file;\n fileIssueCount.set(file, (fileIssueCount.get(file) || 0) + 1);\n }\n \n const sortedFiles = [...fileIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n // Detect hot directories\n const dirIssueCount = new Map<string, number>();\n for (const [file, count] of sortedFiles) {\n const parts = file.split('/');\n if (parts.length > 1) {\n const dir = parts.slice(0, -1).join('/');\n dirIssueCount.set(dir, (dirIssueCount.get(dir) || 0) + count);\n }\n }\n \n const sortedDirs = [...dirIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n if (sortedDirs.length > 0) {\n const [topDir, topDirCount] = sortedDirs[0]!;\n const totalIssues = recentIssues.length;\n const percentage = (topDirCount / totalIssues) * 100;\n \n if (percentage >= 30) {\n patterns.push({\n type: 'file-cluster',\n description: `${basename(topDir)}/ has ${percentage.toFixed(0)}% of issues`,\n metric: `${topDir}_issues`,\n currentValue: topDirCount,\n suggestedTarget: Math.floor(topDirCount * (1 - this.config.reductionTargetPercent / 100)),\n confidence: Math.min(0.9, percentage / 100 + 0.3),\n evidence: [\n `${topDirCount} issues in ${topDir}/`,\n `${percentage.toFixed(0)}% of total issues`,\n `Top files: ${sortedFiles.filter(([f]) => f.startsWith(topDir)).slice(0, 3).map(([f]) => basename(f)).join(', ')}`,\n ],\n category: 'quality',\n });\n }\n }\n \n // 2. Analyze severity trends\n const criticalCount = recentIssues.filter(r => r.issue.severity === 'critical').length;\n const seriousCount = recentIssues.filter(r => r.issue.severity === 'serious').length;\n \n if (criticalCount >= 3) {\n patterns.push({\n type: 'severity-trend',\n description: `${criticalCount} critical issues need attention`,\n metric: 'critical_issues',\n currentValue: criticalCount,\n suggestedTarget: 0,\n confidence: Math.min(0.95, 0.5 + criticalCount * 0.1),\n evidence: [\n `${criticalCount} critical severity issues`,\n `${seriousCount} serious severity issues`,\n 'Critical issues should be zero for production safety',\n ],\n category: 'security',\n });\n }\n \n // 3. Analyze agent concentration (skill-specific issues)\n const agentIssueCount = new Map<string, number>();\n for (const { issue } of recentIssues) {\n agentIssueCount.set(issue.agent, (agentIssueCount.get(issue.agent) || 0) + 1);\n }\n \n const sortedAgents = [...agentIssueCount.entries()]\n .sort((a, b) => b[1] - a[1]);\n \n if (sortedAgents.length > 0) {\n const [topAgent, topAgentCount] = sortedAgents[0]!;\n const percentage = (topAgentCount / recentIssues.length) * 100;\n \n if (percentage >= 40 && topAgentCount >= 5) {\n const category = this.agentToCategory(topAgent);\n patterns.push({\n type: 'agent-concentration',\n description: `${topAgent} skill finds ${percentage.toFixed(0)}% of issues`,\n metric: `${topAgent}_issues`,\n currentValue: topAgentCount,\n suggestedTarget: Math.floor(topAgentCount * 0.5),\n confidence: Math.min(0.85, percentage / 100 + 0.2),\n evidence: [\n `${topAgentCount} issues from ${topAgent}`,\n `${percentage.toFixed(0)}% of all issues`,\n `Suggests focused improvement in ${category} area`,\n ],\n category,\n });\n }\n }\n \n // 4. Detect improvement trends (for streak goals)\n if (stats.improvementTrend === 'improving') {\n patterns.push({\n type: 'time-pattern',\n description: 'Quality is improving - maintain the streak',\n metric: 'clean_scans',\n currentValue: 0,\n suggestedTarget: 5,\n confidence: 0.7,\n evidence: [\n 'Historical trend shows improvement',\n 'Momentum is positive',\n 'Streak goal can maintain motivation',\n ],\n category: 'quality',\n });\n }\n \n } catch (error) {\n console.error('Failed to analyze incident patterns:', error);\n }\n \n return patterns;\n }\n \n /**\n * Convert agent name to category\n */\n private agentToCategory(agent: string): 'security' | 'quality' | 'performance' | 'coverage' | 'general' {\n const categoryMap: Record<string, 'security' | 'quality' | 'performance' | 'coverage' | 'general'> = {\n 'security': 'security',\n 'soc2': 'security',\n 'performance': 'performance',\n 'accessibility': 'quality',\n 'test': 'coverage',\n 'typecheck': 'quality',\n 'bug-finding': 'quality',\n };\n return categoryMap[agent] || 'general';\n }\n \n /**\n * Generate goal opportunities from patterns\n */\n async generateGoalOpportunities(): Promise<GoalOpportunity[]> {\n const patterns = await this.analyzeIncidentPatterns();\n const opportunities: GoalOpportunity[] = [];\n \n // Filter by confidence threshold\n const validPatterns = patterns.filter(p => p.confidence >= this.config.minConfidence);\n \n // Check current active goals\n await this.guardianState.load();\n const activeGoals = this.guardianState.getActiveGoals();\n \n // Don't suggest too many goals\n const slotsAvailable = this.config.maxActiveGoals - activeGoals.length;\n if (slotsAvailable <= 0) {\n return opportunities;\n }\n \n // Convert patterns to goal opportunities\n for (const pattern of validPatterns.slice(0, slotsAvailable)) {\n const goalType = pattern.type === 'time-pattern' ? 'streak' : 'reduction';\n const deadline = new Date();\n deadline.setDate(deadline.getDate() + this.config.goalDurationDays);\n \n opportunities.push({\n pattern,\n goal: {\n description: this.generateGoalDescription(pattern),\n type: goalType,\n metric: pattern.metric,\n target: pattern.suggestedTarget,\n currentValue: pattern.currentValue,\n startValue: pattern.currentValue,\n status: 'active',\n autoGenerated: true,\n confidence: pattern.confidence,\n deadline: deadline.toISOString(),\n category: pattern.category,\n evidence: pattern.evidence,\n },\n reasoning: this.generateGoalReasoning(pattern),\n });\n }\n \n return opportunities;\n }\n \n /**\n * Generate a human-readable goal description\n */\n private generateGoalDescription(pattern: IncidentPattern): string {\n switch (pattern.type) {\n case 'file-cluster':\n return `Reduce issues in ${pattern.description.split(' ')[0]} by ${this.config.reductionTargetPercent}%`;\n case 'severity-trend':\n return 'Eliminate all critical issues';\n case 'agent-concentration':\n return `Reduce ${pattern.description.split(' ')[0]} issues by 50%`;\n case 'time-pattern':\n return 'Achieve 5 consecutive clean scans';\n default:\n return pattern.description;\n }\n }\n \n /**\n * Generate reasoning for why this goal was suggested\n */\n private generateGoalReasoning(pattern: IncidentPattern): string {\n const evidence = pattern.evidence.join('. ');\n return `Based on analysis: ${evidence}. Confidence: ${(pattern.confidence * 100).toFixed(0)}%`;\n }\n \n /**\n * Auto-generate goals and create them (with auto-generated status)\n * \n * Returns goals that need user acceptance.\n */\n async autoGenerateGoals(): Promise<Goal[]> {\n const opportunities = await this.generateGoalOpportunities();\n const createdGoals: Goal[] = [];\n \n for (const opportunity of opportunities) {\n const goal: Goal = {\n id: `goal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n ...opportunity.goal,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n \n await this.guardianState.addGoal(goal);\n createdGoals.push(goal);\n \n // Create insight about the new goal\n if (this.insightStore.canCreateInsight('goal-suggestion')) {\n const insight: GuardianInsight = {\n id: `insight-goal-${goal.id}`,\n type: 'suggestion',\n message: `New goal suggested: ${goal.description}`,\n context: opportunity.reasoning,\n suggestedAction: 'Review and accept/reject this goal',\n relatedIssues: [],\n priority: 6,\n timestamp: Date.now(),\n dismissed: false,\n category: 'progress',\n details: {\n examples: opportunity.pattern.evidence,\n },\n };\n await this.insightStore.addInsight(insight);\n await this.insightStore.markInsightCreated('goal-suggestion');\n }\n }\n \n return createdGoals;\n }\n \n /**\n * Update goal progress based on current state\n */\n async updateGoalProgress(): Promise<void> {\n await this.guardianState.load();\n const activeGoals = this.guardianState.getActiveGoals();\n \n for (const goal of activeGoals) {\n const currentValue = await this.measureGoalMetric(goal);\n \n // Update current value\n await this.guardianState.updateGoal(goal.id, { currentValue });\n \n // Check if goal achieved\n if (this.isGoalAchieved(goal, currentValue)) {\n await this.guardianState.updateGoal(goal.id, {\n status: 'achieved',\n achievedAt: new Date().toISOString(),\n currentValue,\n });\n \n // Celebrate!\n await this.celebrateGoalAchievement(goal);\n }\n \n // Check if goal failed (past deadline and not achieved)\n if (goal.deadline) {\n const deadline = new Date(goal.deadline);\n if (Date.now() > deadline.getTime() && !this.isGoalAchieved(goal, currentValue)) {\n await this.guardianState.updateGoal(goal.id, {\n status: 'failed',\n currentValue,\n });\n }\n }\n }\n }\n \n /**\n * Measure the current value of a goal's metric\n * \n * Supports both structured metrics and semantic/natural language goals\n */\n private async measureGoalMetric(goal: Goal): Promise<number> {\n try {\n const issues = await searchIssues('', {\n workDir: this.projectPath,\n limit: 1000,\n includeResolved: false,\n });\n \n // Structured metrics (auto-generated goals)\n if (goal.metric.endsWith('_issues')) {\n const prefix = goal.metric.replace('_issues', '');\n \n // Check if it's a directory metric\n if (prefix.includes('/')) {\n return issues.filter(r => r.issue.file.startsWith(prefix)).length;\n }\n \n // Check if it's an agent metric\n return issues.filter(r => r.issue.agent === prefix).length;\n }\n \n if (goal.metric === 'critical_issues') {\n return issues.filter(r => r.issue.severity === 'critical').length;\n }\n \n // Semantic goal tracking - match description to issue types\n const desc = goal.description.toLowerCase();\n \n // Path-aware matching for directory/module-specific goals\n // Matches patterns like \"in the auth module\", \"in src/\", \"in components folder\"\n const dirMatch = goal.description.match(/in\\s+(?:the\\s+)?(\\S+?)(?:\\s+(?:module|folder|directory|dir))?(?:\\s|$)/i);\n if (dirMatch && dirMatch[1]) {\n const dirName = dirMatch[1].toLowerCase().replace(/[/\\\\]$/, ''); // Normalize trailing slashes\n const matchingIssues = issues.filter(r => {\n const filePath = r.issue.file.toLowerCase();\n // Match directory name anywhere in path (e.g., \"auth\" matches \"src/auth/login.ts\")\n return filePath.includes(`/${dirName}/`) || \n filePath.includes(`\\\\${dirName}\\\\`) ||\n filePath.startsWith(`${dirName}/`) ||\n filePath.startsWith(`${dirName}\\\\`);\n });\n if (matchingIssues.length > 0 || desc.includes(dirName)) {\n return matchingIssues.length;\n }\n }\n \n // Dead code / unused code goals\n if (desc.includes('dead code') || desc.includes('unused') || desc.includes('remove unused')) {\n const deadCodeIssues = issues.filter(r => {\n const msg = r.issue.issue.toLowerCase();\n return msg.includes('unused') || msg.includes('dead code') || \n msg.includes('never used') || msg.includes('unreachable') ||\n msg.includes('no-unused') || msg.includes('defined but never');\n });\n return deadCodeIssues.length;\n }\n \n // Security goals\n if (desc.includes('security') || desc.includes('vulnerab') || desc.includes('fix security')) {\n const securityIssues = issues.filter(r => \n r.issue.agent === 'security' ||\n r.issue.severity === 'critical'\n );\n return securityIssues.length;\n }\n \n // Type safety goals\n if (desc.includes('type') || desc.includes('typescript') || desc.includes('any type')) {\n const typeIssues = issues.filter(r => \n r.issue.agent === 'typecheck' ||\n r.issue.issue.toLowerCase().includes('type') ||\n r.issue.issue.toLowerCase().includes('any')\n );\n return typeIssues.length;\n }\n \n // Test coverage goals\n if (desc.includes('test') || desc.includes('coverage')) {\n const testIssues = issues.filter(r => \n r.issue.agent === 'test' ||\n r.issue.issue.toLowerCase().includes('test') ||\n r.issue.issue.toLowerCase().includes('coverage')\n );\n return testIssues.length;\n }\n \n // Performance goals\n if (desc.includes('performance') || desc.includes('slow') || desc.includes('optimize')) {\n const perfIssues = issues.filter(r => \n r.issue.agent === 'performance' ||\n r.issue.issue.toLowerCase().includes('performance') ||\n r.issue.issue.toLowerCase().includes('slow')\n );\n return perfIssues.length;\n }\n \n // Accessibility goals\n if (desc.includes('accessibility') || desc.includes('a11y') || desc.includes('accessible')) {\n const a11yIssues = issues.filter(r => \n r.issue.agent === 'accessibility' ||\n r.issue.issue.toLowerCase().includes('accessibility')\n );\n return a11yIssues.length;\n }\n \n // Bug-related goals\n if (desc.includes('bug') || desc.includes('fix') || desc.includes('error')) {\n const bugIssues = issues.filter(r => \n r.issue.agent === 'bug-finding' ||\n r.issue.severity === 'critical' ||\n r.issue.severity === 'serious'\n );\n return bugIssues.length;\n }\n \n // Quality goals (general)\n if (desc.includes('quality') || desc.includes('clean') || desc.includes('improve')) {\n // Count all issues as baseline for quality\n return issues.length;\n }\n \n // Default: total issues\n return issues.length;\n } catch {\n return goal.currentValue; // Return existing value on error\n }\n }\n \n /**\n * Check if a goal has been achieved\n */\n private isGoalAchieved(goal: Goal, currentValue: number): boolean {\n switch (goal.type) {\n case 'reduction':\n return currentValue <= goal.target;\n case 'score':\n return currentValue >= goal.target;\n case 'streak':\n return currentValue >= goal.target;\n default:\n return currentValue <= goal.target;\n }\n }\n \n /**\n * Create a celebration insight for goal achievement\n */\n private async celebrateGoalAchievement(goal: Goal): Promise<void> {\n // Find resolved issues that match this goal's metric\n const resolvedDetails = await this.getResolvedIssuesForGoal(goal);\n \n // Validate required fields\n if (goal.startValue === undefined || goal.startValue === null) {\n throw new Error(`Goal ${goal.id} missing startValue`);\n }\n if (goal.currentValue === undefined || goal.currentValue === null) {\n throw new Error(`Goal ${goal.id} missing currentValue`);\n }\n if (goal.target === undefined || goal.target === null) {\n throw new Error(`Goal ${goal.id} missing target`);\n }\n \n // Validate resolvedDetails structure\n for (let i = 0; i < resolvedDetails.length; i++) {\n const issue = resolvedDetails[i];\n if (!issue) {\n throw new Error(`Resolved issue at index ${i} is null/undefined`);\n }\n if (!issue.file) {\n throw new Error(`Resolved issue at index ${i} missing file field`);\n }\n if (!issue.issue) {\n throw new Error(`Resolved issue at index ${i} missing issue description`);\n }\n if (!issue.agent) {\n throw new Error(`Resolved issue at index ${i} missing agent field`);\n }\n }\n \n const insight: GuardianInsight = {\n id: `insight-achieved-${goal.id}`,\n type: 'celebration',\n message: `Goal achieved: ${goal.description}!`,\n context: `Started at ${goal.startValue}, now at ${goal.currentValue}. Target was ${goal.target}.`,\n relatedIssues: [],\n priority: 8,\n timestamp: Date.now(),\n dismissed: false,\n category: 'progress',\n details: {\n resolvedCount: resolvedDetails.length,\n resolvedIssues: resolvedDetails.slice(0, 20).map(issue => ({\n file: issue.file,\n line: issue.line,\n issue: issue.issue,\n agent: issue.agent,\n resolvedAt: issue.resolvedAt,\n })),\n summary: resolvedDetails.length > 0 \n ? `Resolved ${resolvedDetails.length} issue${resolvedDetails.length > 1 ? 's' : ''} matching this goal`\n : 'Progress tracked via metric reduction',\n },\n };\n \n // Validate insight structure before saving\n if (!insight.details) {\n throw new Error('Failed to create details object for goal achievement insight');\n }\n if (insight.details.resolvedCount === undefined) {\n throw new Error('resolvedCount is undefined in goal achievement insight');\n }\n if (insight.details.resolvedCount > 0 && (!insight.details.resolvedIssues || insight.details.resolvedIssues.length === 0)) {\n throw new Error(`resolvedCount is ${insight.details.resolvedCount} but resolvedIssues array is empty`);\n }\n if (insight.details.resolvedCount !== insight.details.resolvedIssues?.length) {\n throw new Error(`resolvedCount (${insight.details.resolvedCount}) doesn't match resolvedIssues length (${insight.details.resolvedIssues?.length})`);\n }\n \n await this.insightStore.addInsight(insight);\n }\n\n /**\n * Get resolved issues that match a goal's metric pattern\n */\n private async getResolvedIssuesForGoal(goal: Goal): Promise<Array<{ file: string; line: number | undefined; issue: string; agent: string; resolvedAt: string | undefined }>> {\n try {\n // Get all resolved issues\n const allResolved = await searchIssues('', {\n workDir: this.projectPath,\n limit: 1000,\n includeResolved: true,\n });\n \n // Filter to only resolved issues\n const resolved = allResolved\n .map(r => r.issue)\n .filter(issue => issue.resolved === true);\n \n // Filter by goal's metric pattern (same logic as measureGoalMetric)\n const desc = goal.description.toLowerCase();\n const metric = goal.metric.toLowerCase();\n \n let matchingResolved = resolved;\n \n // Match by metric pattern\n if (metric.endsWith('_issues')) {\n const prefix = metric.replace('_issues', '');\n if (prefix.includes('/')) {\n matchingResolved = resolved.filter(i => i.file.startsWith(prefix));\n } else {\n matchingResolved = resolved.filter(i => i.agent === prefix);\n }\n } else if (metric === 'critical_issues') {\n matchingResolved = resolved.filter(i => i.severity === 'critical');\n } else {\n // Semantic matching (same as measureGoalMetric)\n if (desc.includes('dead code') || desc.includes('unused') || desc.includes('remove unused')) {\n matchingResolved = resolved.filter(i => {\n const msg = i.issue.toLowerCase();\n return msg.includes('unused') || msg.includes('dead code') || \n msg.includes('never used') || msg.includes('unreachable') ||\n msg.includes('no-unused') || msg.includes('defined but never');\n });\n } else if (desc.includes('security') || desc.includes('vulnerab') || desc.includes('fix security')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'security' || i.severity === 'critical'\n );\n } else if (desc.includes('type') || desc.includes('typescript') || desc.includes('any type')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'typecheck' ||\n i.issue.toLowerCase().includes('type') ||\n i.issue.toLowerCase().includes('any')\n );\n } else if (desc.includes('test') || desc.includes('coverage')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'test' ||\n i.issue.toLowerCase().includes('test') ||\n i.issue.toLowerCase().includes('coverage')\n );\n } else if (desc.includes('performance') || desc.includes('slow') || desc.includes('optimize')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'performance' ||\n i.issue.toLowerCase().includes('performance') ||\n i.issue.toLowerCase().includes('slow')\n );\n } else if (desc.includes('accessibility') || desc.includes('a11y') || desc.includes('accessible')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'accessibility' ||\n i.issue.toLowerCase().includes('accessibility')\n );\n } else if (desc.includes('bug') || desc.includes('fix') || desc.includes('error')) {\n matchingResolved = resolved.filter(i => \n i.agent === 'bug-finding' ||\n i.severity === 'critical' ||\n i.severity === 'serious'\n );\n }\n }\n \n // Filter by resolvedAt timestamp (only include issues resolved during goal's lifetime)\n const goalCreatedAt = new Date(goal.createdAt).getTime();\n const goalAchievedAt = goal.achievedAt ? new Date(goal.achievedAt).getTime() : Date.now();\n \n return matchingResolved\n .filter(issue => {\n if (!issue.resolvedAt) return false;\n const resolvedAt = new Date(issue.resolvedAt).getTime();\n return resolvedAt >= goalCreatedAt && resolvedAt <= goalAchievedAt;\n })\n .sort((a, b) => {\n // Sort by resolvedAt, most recent first\n const aTime = a.resolvedAt ? new Date(a.resolvedAt).getTime() : 0;\n const bTime = b.resolvedAt ? new Date(b.resolvedAt).getTime() : 0;\n return bTime - aTime;\n });\n } catch {\n return [];\n }\n }\n \n /**\n * Accept an auto-generated goal\n */\n async acceptGoal(goalId: string): Promise<boolean> {\n return this.guardianState.respondToGoal(goalId, true);\n }\n \n /**\n * Reject an auto-generated goal\n */\n async rejectGoal(goalId: string): Promise<boolean> {\n return this.guardianState.respondToGoal(goalId, false);\n }\n \n /**\n * Get pending auto-generated goals (awaiting acceptance)\n */\n getPendingGoals(): Goal[] {\n return this.guardianState.getAutoGeneratedGoals()\n .filter(g => g.status === 'active');\n }\n \n /**\n * Get goal progress summary\n */\n getGoalProgressSummary(): {\n active: number;\n achieved: number;\n failed: number;\n pending: number;\n } {\n const goals = this.guardianState.getAllGoals();\n return {\n active: goals.filter(g => g.status === 'active').length,\n achieved: goals.filter(g => g.status === 'achieved').length,\n failed: goals.filter(g => g.status === 'failed').length,\n pending: goals.filter(g => g.autoGenerated && g.status === 'active').length,\n };\n }\n}\n\n// ============================================================================\n// Adaptive Scan Frequency\n// ============================================================================\n\n/**\n * Calculate optimal scan frequency based on current risk level\n */\nexport async function calculateAdaptiveScanFrequency(projectPath: string): Promise<{\n frequencyMs: number;\n reason: string;\n}> {\n const guardianState = getGuardianState(projectPath);\n await guardianState.load();\n \n try {\n const stats = await getMemoryStats(projectPath);\n const issues = await searchIssues('', {\n workDir: projectPath,\n limit: 100,\n includeResolved: false,\n });\n \n const criticalCount = issues.filter(r => r.issue.severity === 'critical').length;\n const seriousCount = issues.filter(r => r.issue.severity === 'serious').length;\n \n // High risk: scan every minute\n if (criticalCount >= 3) {\n return {\n frequencyMs: 60000,\n reason: `${criticalCount} critical issues detected - scanning frequently`,\n };\n }\n \n // Medium-high risk: scan every 2 minutes\n if (criticalCount > 0 || seriousCount >= 5) {\n return {\n frequencyMs: 120000,\n reason: `Critical or many serious issues - elevated scan frequency`,\n };\n }\n \n // Medium risk: scan every 3 minutes\n if (seriousCount > 0) {\n return {\n frequencyMs: 180000,\n reason: `${seriousCount} serious issues - moderate scan frequency`,\n };\n }\n \n // Low risk: scan every 5 minutes (default)\n if (stats.totalIssues > 10) {\n return {\n frequencyMs: 300000,\n reason: 'Some issues present - standard scan frequency',\n };\n }\n \n // Very low risk: scan every 10 minutes\n return {\n frequencyMs: 600000,\n reason: 'Code looks good - relaxed scan frequency',\n };\n \n } catch {\n // Default on error\n return {\n frequencyMs: 300000,\n reason: 'Default scan frequency (5 min)',\n };\n }\n}\n\n/**\n * Apply adaptive scan frequency\n */\nexport async function adaptScanFrequency(projectPath: string): Promise<number> {\n const guardianState = getGuardianState(projectPath);\n const { frequencyMs } = await calculateAdaptiveScanFrequency(projectPath);\n \n await guardianState.setScanFrequency(frequencyMs);\n \n return frequencyMs;\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst goalManagers: Map<string, GoalManager> = new Map();\n\n/**\n * Get the GoalManager for a project (singleton per project)\n */\nexport function getGoalManager(projectPath: string): GoalManager {\n let manager = goalManagers.get(projectPath);\n if (!manager) {\n manager = new GoalManager(projectPath);\n goalManagers.set(projectPath, manager);\n }\n return manager;\n}\n\n/**\n * Clear all GoalManager instances (for testing)\n */\nexport function clearGoalManagers(): void {\n goalManagers.clear();\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
BackupManager,
|
|
3
3
|
atomicWriteJSON,
|
|
4
4
|
safeParseAndValidate
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-JDHR5BDR.js";
|
|
6
6
|
import {
|
|
7
7
|
getTrieDirectory
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-R4AAPFXC.js";
|
|
9
9
|
|
|
10
10
|
// src/guardian/guardian-state.ts
|
|
11
11
|
import { mkdir, readFile } from "fs/promises";
|
|
@@ -679,4 +679,4 @@ function getGuardianState(projectPath) {
|
|
|
679
679
|
export {
|
|
680
680
|
getGuardianState
|
|
681
681
|
};
|
|
682
|
-
//# sourceMappingURL=chunk-
|
|
682
|
+
//# sourceMappingURL=chunk-R3I2GCZC.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
isInteractiveMode
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-APMV77PU.js";
|
|
4
4
|
import {
|
|
5
5
|
__require
|
|
6
6
|
} from "./chunk-DGUM43GV.js";
|
|
@@ -189,4 +189,4 @@ export {
|
|
|
189
189
|
getTrieDirectory,
|
|
190
190
|
getWorkingDirectory
|
|
191
191
|
};
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-R4AAPFXC.js.map
|