@triedotdev/mcp 1.0.165 → 1.0.167
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 +337 -801
- package/dist/chunk-2HF65EHQ.js +311 -0
- package/dist/chunk-2HF65EHQ.js.map +1 -0
- package/dist/{chunk-M7HMBZ3R.js → chunk-4MXH2ZPT.js} +12 -12
- package/dist/chunk-4MXH2ZPT.js.map +1 -0
- package/dist/{chunk-LR5M4RTN.js → chunk-575YT2SD.js} +1 -1
- package/dist/chunk-575YT2SD.js.map +1 -0
- package/dist/{chunk-HC5P6FZD.js → chunk-5BRRRTN6.js} +4 -4
- package/dist/{chunk-IPNPHPNN.js → chunk-7WITSO22.js} +3 -3
- package/dist/{chunk-ACU2RJUJ.js → chunk-F6WFNUAY.js} +2 -2
- package/dist/{chunk-VR4VWXXU.js → chunk-G2TGF6TR.js} +9 -2
- package/dist/chunk-G2TGF6TR.js.map +1 -0
- package/dist/{chunk-ZBXW244P.js → chunk-HVCDY3AK.js} +3 -3
- package/dist/chunk-HVCDY3AK.js.map +1 -0
- package/dist/{chunk-CDG2GVBP.js → chunk-LQIMKE3P.js} +700 -151
- package/dist/chunk-LQIMKE3P.js.map +1 -0
- package/dist/{chunk-RQ6QZBIN.js → chunk-MRHKX5M5.js} +3 -3
- package/dist/{chunk-OLNZJ3XV.js → chunk-Q63FFI6D.js} +2 -2
- package/dist/{chunk-SS2O3MTC.js → chunk-XE6KQRKZ.js} +9 -8
- package/dist/chunk-XE6KQRKZ.js.map +1 -0
- package/dist/{chunk-GDWA3CH3.js → chunk-XPZZFPBZ.js} +30 -6
- package/dist/chunk-XPZZFPBZ.js.map +1 -0
- package/dist/{chunk-WRYQHVPD.js → chunk-XTFWT2XM.js} +2 -2
- package/dist/{chunk-IS5UBN2R.js → chunk-YDHUCDHM.js} +18 -112
- package/dist/chunk-YDHUCDHM.js.map +1 -0
- package/dist/{chunk-5LRDF2WB.js → chunk-YZ6Y2H3P.js} +21 -196
- package/dist/chunk-YZ6Y2H3P.js.map +1 -0
- package/dist/{chunk-YAL3SUBG.js → chunk-ZJF5FTBX.js} +126 -355
- package/dist/chunk-ZJF5FTBX.js.map +1 -0
- package/dist/cli/create-agent.js +1 -1
- package/dist/cli/create-agent.js.map +1 -1
- package/dist/cli/main.js +194 -849
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +15 -14
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{fast-analyzer-54AHLVO5.js → fast-analyzer-XXYMOXRK.js} +3 -3
- package/dist/git-EO5SRFMN.js +28 -0
- package/dist/{github-ingester-TFBDUDIY.js → github-ingester-ZOKK6GRS.js} +3 -3
- package/dist/{goal-manager-563BNILQ.js → goal-manager-YOB7VWK7.js} +5 -4
- package/dist/{goal-validator-FJEDIYU7.js → goal-validator-ULKIBDPX.js} +5 -4
- package/dist/{hypothesis-4KC7XRBZ.js → hypothesis-7BFFT5JY.js} +5 -4
- package/dist/index.js +19 -18
- package/dist/index.js.map +1 -1
- package/dist/{issue-store-FOS4T736.js → issue-store-ZIRP23EP.js} +4 -3
- package/dist/{ledger-EDLPF6SB.js → ledger-TWZTGDFA.js} +3 -2
- package/dist/{linear-ingester-PLES2BRS.js → linear-ingester-XXPAZZRW.js} +3 -3
- package/dist/{output-manager-JNMEAXFO.js → output-manager-RVJ37XKA.js} +2 -2
- package/dist/server/mcp-server.js +19 -18
- package/dist/{tiered-storage-OP74NPJY.js → tiered-storage-Z3YCR465.js} +2 -2
- package/dist/{trie-agent-TM6ATSNR.js → trie-agent-3YDPEGHJ.js} +9 -8
- package/dist/trie-agent-3YDPEGHJ.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-5LRDF2WB.js.map +0 -1
- package/dist/chunk-CDG2GVBP.js.map +0 -1
- package/dist/chunk-GDWA3CH3.js.map +0 -1
- package/dist/chunk-IS5UBN2R.js.map +0 -1
- package/dist/chunk-LR5M4RTN.js.map +0 -1
- package/dist/chunk-M7HMBZ3R.js.map +0 -1
- package/dist/chunk-SS2O3MTC.js.map +0 -1
- package/dist/chunk-VR4VWXXU.js.map +0 -1
- package/dist/chunk-YAL3SUBG.js.map +0 -1
- package/dist/chunk-ZBXW244P.js.map +0 -1
- /package/dist/{chunk-HC5P6FZD.js.map → chunk-5BRRRTN6.js.map} +0 -0
- /package/dist/{chunk-IPNPHPNN.js.map → chunk-7WITSO22.js.map} +0 -0
- /package/dist/{chunk-ACU2RJUJ.js.map → chunk-F6WFNUAY.js.map} +0 -0
- /package/dist/{chunk-RQ6QZBIN.js.map → chunk-MRHKX5M5.js.map} +0 -0
- /package/dist/{chunk-OLNZJ3XV.js.map → chunk-Q63FFI6D.js.map} +0 -0
- /package/dist/{chunk-WRYQHVPD.js.map → chunk-XTFWT2XM.js.map} +0 -0
- /package/dist/{fast-analyzer-54AHLVO5.js.map → fast-analyzer-XXYMOXRK.js.map} +0 -0
- /package/dist/{github-ingester-TFBDUDIY.js.map → git-EO5SRFMN.js.map} +0 -0
- /package/dist/{goal-manager-563BNILQ.js.map → github-ingester-ZOKK6GRS.js.map} +0 -0
- /package/dist/{goal-validator-FJEDIYU7.js.map → goal-manager-YOB7VWK7.js.map} +0 -0
- /package/dist/{hypothesis-4KC7XRBZ.js.map → goal-validator-ULKIBDPX.js.map} +0 -0
- /package/dist/{issue-store-FOS4T736.js.map → hypothesis-7BFFT5JY.js.map} +0 -0
- /package/dist/{ledger-EDLPF6SB.js.map → issue-store-ZIRP23EP.js.map} +0 -0
- /package/dist/{linear-ingester-PLES2BRS.js.map → ledger-TWZTGDFA.js.map} +0 -0
- /package/dist/{output-manager-JNMEAXFO.js.map → linear-ingester-XXPAZZRW.js.map} +0 -0
- /package/dist/{tiered-storage-OP74NPJY.js.map → output-manager-RVJ37XKA.js.map} +0 -0
- /package/dist/{trie-agent-TM6ATSNR.js.map → tiered-storage-Z3YCR465.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage/tiered-storage.ts"],"sourcesContent":["/**\n * Tiered Storage System\n * \n * Three-tier architecture for context management:\n * - HOT: In-memory, current session data\n * - WARM: SQLite DB, queryable governance/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 { createHash } from 'node:crypto';\nimport Database, { type Database as DatabaseType } from 'better-sqlite3';\nimport type {\n Governance,\n Blocker,\n ExtractedSignal,\n ContextQuery,\n Nudge,\n Gotcha,\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: DatabaseType | 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', 'governance.db');\n this.warmDb = new Database(dbPath);\n \n // Create tables\n this.warmDb.exec(`\n CREATE TABLE IF NOT EXISTS governance (\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 hash TEXT, -- SHA-256 fingerprint (first 16 hex chars)\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 relatedGovernance 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 relatedGovernance 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 TABLE IF NOT EXISTS nudges (\n id TEXT PRIMARY KEY,\n message TEXT NOT NULL,\n severity TEXT NOT NULL, -- 'critical', 'high', 'warning', 'info'\n file TEXT,\n category TEXT, -- 'quality', 'security', 'performance', etc.\n goalId TEXT, -- Related goal ID if this is a goal violation\n timestamp TEXT NOT NULL,\n resolved BOOLEAN NOT NULL DEFAULT 0,\n resolvedAt TEXT,\n resolution TEXT, -- How it was resolved: 'dismissed', 'fixed', 'auto-fixed'\n dismissed BOOLEAN NOT NULL DEFAULT 0,\n priority INTEGER DEFAULT 5, -- 1-10 priority score\n suggestedAction TEXT,\n relatedIssues TEXT, -- JSON array\n metadata TEXT -- JSON object for additional data\n );\n\n CREATE TABLE IF NOT EXISTS gotchas (\n id TEXT PRIMARY KEY,\n message TEXT NOT NULL,\n confidence REAL NOT NULL, -- 0-1 confidence score\n riskLevel TEXT NOT NULL, -- 'low', 'medium', 'high', 'critical'\n recommendation TEXT NOT NULL,\n file TEXT,\n timestamp TEXT NOT NULL,\n precedentId TEXT, -- ID of related historical incident/governance record\n tags TEXT NOT NULL, -- JSON array\n evidence TEXT NOT NULL, -- JSON object with pastIncidents, matchingPatterns, relatedTickets\n resolved BOOLEAN NOT NULL DEFAULT 0,\n resolvedAt TEXT,\n resolution TEXT -- 'confirmed', 'false-positive', 'dismissed'\n );\n\n CREATE INDEX IF NOT EXISTS idx_governance_tags ON governance(tags);\n CREATE INDEX IF NOT EXISTS idx_governance_expanded ON governance(expandedTags);\n CREATE INDEX IF NOT EXISTS idx_governance_timestamp ON governance(timestamp);\n CREATE INDEX IF NOT EXISTS idx_governance_status ON governance(status);\n CREATE INDEX IF NOT EXISTS idx_governance_area ON governance(codebaseArea);\n CREATE INDEX IF NOT EXISTS idx_governance_domain ON governance(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 CREATE INDEX IF NOT EXISTS idx_nudges_timestamp ON nudges(timestamp);\n CREATE INDEX IF NOT EXISTS idx_nudges_resolved ON nudges(resolved);\n CREATE INDEX IF NOT EXISTS idx_nudges_severity ON nudges(severity);\n CREATE INDEX IF NOT EXISTS idx_nudges_file ON nudges(file);\n CREATE INDEX IF NOT EXISTS idx_gotchas_timestamp ON gotchas(timestamp);\n CREATE INDEX IF NOT EXISTS idx_gotchas_resolved ON gotchas(resolved);\n CREATE INDEX IF NOT EXISTS idx_gotchas_riskLevel ON gotchas(riskLevel);\n CREATE INDEX IF NOT EXISTS idx_gotchas_file ON gotchas(file);\n CREATE INDEX IF NOT EXISTS idx_gotchas_tags ON gotchas(tags);\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 // Log what we're storing for debugging\n const totalSignals = signal.governance.length + signal.facts.length + \n signal.blockers.length + signal.questions.length;\n if (totalSignals > 0) {\n console.debug(`[Storage] Storing ${totalSignals} signals: ${signal.governance.length}g, ${signal.facts.length}f, ${signal.blockers.length}b, ${signal.questions.length}q`);\n }\n\n // Store governance records\n const governanceStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO governance \n (id, decision, context, reasoning, timestamp, who, files, tags, expandedTags, relatedTo, tradeoffs, status, supersededBy, hash, dependencies, codebaseArea, domain, lastAccessed, accessCount)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)\n `);\n\n const governanceRecords = signal.governance;\n for (const gov of governanceRecords) {\n const hash = gov.hash || createHash('sha256')\n .update(`${gov.decision}|${gov.context}|${gov.when}`)\n .digest('hex')\n .slice(0, 16);\n governanceStmt.run(\n gov.id,\n gov.decision,\n gov.context,\n gov.reasoning || null,\n gov.when,\n gov.who || null,\n JSON.stringify(gov.files),\n JSON.stringify(gov.tags),\n JSON.stringify(metadata?.expandedTags || []),\n JSON.stringify(gov.relatedTo || []),\n JSON.stringify(gov.tradeoffs || []),\n gov.status,\n gov.supersededBy || null,\n hash,\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, relatedGovernance, 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.relatedGovernance || []),\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, relatedGovernance, 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.relatedGovernance || []),\n JSON.stringify(q.tags),\n JSON.stringify(metadata?.expandedTags || []),\n now\n );\n }\n\n // Store gotchas if present\n if (signal.gotchas && signal.gotchas.length > 0) {\n const gotchaStmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO gotchas\n (id, message, confidence, riskLevel, recommendation, file, timestamp, precedentId, tags, evidence, resolved, resolvedAt, resolution)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n for (const g of signal.gotchas) {\n gotchaStmt.run(\n g.id,\n g.message,\n g.confidence,\n g.riskLevel,\n g.recommendation,\n g.file || null,\n g.timestamp,\n g.precedentId || null,\n JSON.stringify(g.tags || []),\n JSON.stringify(g.evidence || { pastIncidents: [], matchingPatterns: [], relatedTickets: [] }),\n g.resolved ? 1 : 0,\n g.resolvedAt || null,\n g.resolution || null\n );\n }\n }\n \n // Log successful storage\n const storedCount = signal.governance.length + signal.facts.length + \n signal.blockers.length + signal.questions.length +\n (signal.gotchas?.length || 0);\n if (storedCount > 0) {\n console.debug(`[Storage] ✓ Successfully stored ${storedCount} signals to governance.db`);\n }\n }\n\n /**\n * Query governance records from warm storage with expanded tag matching\n */\n async queryGovernance(query: ContextQuery): Promise<Governance[]> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n let sql = 'SELECT * FROM governance 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.timestamp || 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 hash: row.hash || undefined,\n }));\n }\n\n /**\n * Query facts from warm storage (for Learned Signals display)\n */\n async queryFacts(query: { limit?: number } = {}): Promise<Array<{ id: string; fact: string; source: string; when: string; tags: string[]; confidence: number }>> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const limit = query.limit ?? 20;\n const rows = this.warmDb.prepare('SELECT * FROM facts ORDER BY timestamp DESC LIMIT ?').all(limit) as any[];\n\n return rows.map(row => ({\n id: row.id,\n fact: row.fact,\n source: row.source,\n when: row.timestamp || row.when,\n tags: JSON.parse(row.tags || '[]'),\n confidence: row.confidence ?? 0.8,\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 * Store a nudge in warm storage\n */\n async storeNudge(nudge: Nudge): Promise<void> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const stmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO nudges\n (id, message, severity, file, category, goalId, timestamp, resolved, resolvedAt, resolution, dismissed, priority, suggestedAction, relatedIssues, metadata)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n nudge.id,\n nudge.message,\n nudge.severity,\n nudge.file || null,\n nudge.category || null,\n nudge.goalId || null,\n nudge.timestamp,\n nudge.resolved ? 1 : 0,\n nudge.resolvedAt || null,\n nudge.resolution || null,\n nudge.dismissed ? 1 : 0,\n nudge.priority,\n nudge.suggestedAction || null,\n JSON.stringify(nudge.relatedIssues || []),\n JSON.stringify(nudge.metadata || {})\n );\n }\n\n /**\n * Query nudges from warm storage\n */\n async queryNudges(filters?: {\n resolved?: boolean;\n severity?: string;\n file?: string;\n category?: string;\n goalId?: string;\n limit?: number;\n }): Promise<Nudge[]> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n let sql = 'SELECT * FROM nudges WHERE 1=1';\n const params: any[] = [];\n\n if (filters?.resolved !== undefined) {\n sql += ' AND resolved = ?';\n params.push(filters.resolved ? 1 : 0);\n }\n\n if (filters?.severity) {\n sql += ' AND severity = ?';\n params.push(filters.severity);\n }\n\n if (filters?.file) {\n sql += ' AND file = ?';\n params.push(filters.file);\n }\n\n if (filters?.category) {\n sql += ' AND category = ?';\n params.push(filters.category);\n }\n\n if (filters?.goalId) {\n sql += ' AND goalId = ?';\n params.push(filters.goalId);\n }\n\n sql += ' ORDER BY timestamp DESC';\n\n if (filters?.limit) {\n sql += ' LIMIT ?';\n params.push(filters.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 message: row.message,\n severity: row.severity,\n file: row.file || undefined,\n category: row.category || undefined,\n goalId: row.goalId || undefined,\n timestamp: row.timestamp,\n resolved: Boolean(row.resolved),\n resolvedAt: row.resolvedAt || undefined,\n resolution: row.resolution || undefined,\n dismissed: Boolean(row.dismissed),\n priority: row.priority,\n suggestedAction: row.suggestedAction || undefined,\n relatedIssues: JSON.parse(row.relatedIssues || '[]'),\n metadata: JSON.parse(row.metadata || '{}'),\n }));\n }\n\n /**\n * Mark a nudge as resolved\n */\n async resolveNudge(nudgeId: string, resolution: 'dismissed' | 'fixed' | 'auto-fixed'): 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 this.warmDb.prepare(`\n UPDATE nudges \n SET resolved = 1, resolvedAt = ?, resolution = ?, dismissed = ?\n WHERE id = ?\n `).run(now, resolution, resolution === 'dismissed' ? 1 : 0, nudgeId);\n }\n\n /**\n * Mark a nudge as dismissed\n */\n async dismissNudge(nudgeId: string): Promise<void> {\n await this.resolveNudge(nudgeId, 'dismissed');\n }\n\n /**\n * Mark a nudge as fixed (automatically called when issues are resolved)\n */\n async markNudgeFixed(nudgeId: string): Promise<void> {\n await this.resolveNudge(nudgeId, 'fixed');\n }\n\n /**\n * Clear all nudges (mark all as resolved)\n */\n async clearAllNudges(): 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 this.warmDb.prepare(`\n UPDATE nudges \n SET resolved = 1, resolvedAt = ?, resolution = 'dismissed'\n WHERE resolved = 0\n `).run(now);\n }\n\n /**\n * Resolve nudges for a goal violation that was fixed in a specific file.\n * Called when a file is rescanned and no longer has violations for that goal.\n */\n async resolveNudgesForGoalViolation(file: string, goalDescription: string, _workDir?: string): Promise<number> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const goalPattern = `%Goal \"${goalDescription.replace(/\"/g, '\"\"')}\"%`;\n const fileAlt = file.replace(/\\\\/g, '/');\n const rows = this.warmDb.prepare(`\n SELECT id FROM nudges \n WHERE resolved = 0 \n AND (file = ? OR file = ?)\n AND message LIKE ?\n `).all(file, fileAlt, goalPattern) as { id: string }[];\n\n const now = new Date().toISOString();\n let resolved = 0;\n for (const row of rows) {\n this.warmDb.prepare(`\n UPDATE nudges SET resolved = 1, resolvedAt = ?, resolution = 'auto-fixed'\n WHERE id = ?\n `).run(now, row.id);\n resolved++;\n }\n return resolved;\n }\n\n /**\n * Resolve all nudges for a specific goal (used when goal is achieved or deleted)\n */\n async resolveNudgesForGoal(goalDescription: string): Promise<number> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const goalPattern = `%Goal \"${goalDescription.replace(/\"/g, '\"\"')}\"%`;\n const now = new Date().toISOString();\n \n const result = this.warmDb.prepare(`\n UPDATE nudges \n SET resolved = 1, resolvedAt = ?, resolution = 'goal-achieved'\n WHERE resolved = 0 AND message LIKE ?\n `).run(now, goalPattern);\n\n return result.changes;\n }\n\n /**\n * Resolve nudges for files that no longer exist\n */\n async resolveNudgesForMissingFiles(): Promise<number> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const { existsSync } = await import('fs');\n const rows = this.warmDb.prepare(`\n SELECT id, file FROM nudges WHERE resolved = 0 AND file IS NOT NULL\n `).all() as { id: string; file: string }[];\n\n const now = new Date().toISOString();\n let resolved = 0;\n for (const row of rows) {\n if (row.file && !existsSync(row.file)) {\n this.warmDb.prepare(`\n UPDATE nudges SET resolved = 1, resolvedAt = ?, resolution = 'file-deleted'\n WHERE id = ?\n `).run(now, row.id);\n resolved++;\n }\n }\n return resolved;\n }\n\n /**\n * Resolve nudges matching a pattern in the message (for type error clearing, etc.)\n */\n async resolveNudgesByPattern(messagePattern: string, resolution: string = 'auto-fixed'): Promise<number> {\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 const result = this.warmDb.prepare(`\n UPDATE nudges \n SET resolved = 1, resolvedAt = ?, resolution = ?\n WHERE resolved = 0 AND message LIKE ?\n `).run(now, resolution, `%${messagePattern}%`);\n\n return result.changes;\n }\n\n /**\n * Auto-resolve nudges that match fixed issues\n * Called after a scan to mark nudges as fixed if their related issues are resolved\n */\n async autoResolveFixedNudges(resolvedIssueIds: string[]): Promise<number> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n if (resolvedIssueIds.length === 0) return 0;\n\n const now = new Date().toISOString();\n let resolved = 0;\n\n // Mark nudges as fixed if their related issues are in the resolved list\n for (const issueId of resolvedIssueIds) {\n const result = this.warmDb.prepare(`\n UPDATE nudges \n SET resolved = 1, resolvedAt = ?, resolution = 'auto-fixed'\n WHERE resolved = 0 \n AND (\n relatedIssues LIKE ? \n OR id = ?\n )\n `).run(now, `%\"${issueId}\"%`, issueId);\n \n resolved += result.changes;\n }\n\n return resolved;\n }\n\n /**\n * Store a gotcha in warm storage\n */\n async storeGotcha(gotcha: Gotcha): Promise<void> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const stmt = this.warmDb.prepare(`\n INSERT OR REPLACE INTO gotchas\n (id, message, confidence, riskLevel, recommendation, file, timestamp, precedentId, tags, evidence, resolved, resolvedAt, resolution)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n gotcha.id,\n gotcha.message,\n gotcha.confidence,\n gotcha.riskLevel,\n gotcha.recommendation,\n gotcha.file || null,\n gotcha.timestamp,\n gotcha.precedentId || null,\n JSON.stringify(gotcha.tags || []),\n JSON.stringify(gotcha.evidence || { pastIncidents: [], matchingPatterns: [], relatedTickets: [] }),\n gotcha.resolved ? 1 : 0,\n gotcha.resolvedAt || null,\n gotcha.resolution || null\n );\n }\n\n /**\n * Query gotchas from warm storage\n */\n async queryGotchas(filters?: {\n resolved?: boolean;\n riskLevel?: string;\n file?: string;\n limit?: number;\n }): Promise<Gotcha[]> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n let sql = 'SELECT * FROM gotchas WHERE 1=1';\n const params: any[] = [];\n\n if (filters?.resolved !== undefined) {\n sql += ' AND resolved = ?';\n params.push(filters.resolved ? 1 : 0);\n }\n\n if (filters?.riskLevel) {\n sql += ' AND riskLevel = ?';\n params.push(filters.riskLevel);\n }\n\n if (filters?.file) {\n sql += ' AND file = ?';\n params.push(filters.file);\n }\n\n sql += ' ORDER BY timestamp DESC';\n\n if (filters?.limit) {\n sql += ' LIMIT ?';\n params.push(filters.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 message: row.message,\n confidence: row.confidence,\n riskLevel: row.riskLevel,\n recommendation: row.recommendation,\n file: row.file || undefined,\n timestamp: row.timestamp,\n precedentId: row.precedentId || undefined,\n tags: JSON.parse(row.tags || '[]'),\n evidence: JSON.parse(row.evidence || '{\"pastIncidents\":[],\"matchingPatterns\":[],\"relatedTickets\":[]}'),\n resolved: Boolean(row.resolved),\n resolvedAt: row.resolvedAt || undefined,\n resolution: row.resolution || undefined,\n }));\n }\n\n /**\n * Get unresolved nudges count\n */\n async getUnresolvedNudgesCount(): Promise<number> {\n if (!this.warmDb) await this.initialize();\n if (!this.warmDb) throw new Error('Database not initialized');\n\n const result = this.warmDb.prepare('SELECT COUNT(*) as count FROM nudges WHERE resolved = 0').get() as { count: number };\n return result.count;\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 governance = this.warmDb.prepare('SELECT * FROM governance 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 const nudges = this.warmDb.prepare('SELECT * FROM nudges WHERE timestamp < ? AND resolved = 1').all(cutoff);\n const gotchas = this.warmDb.prepare('SELECT * FROM gotchas WHERE timestamp < ? AND resolved = 1').all(cutoff);\n\n await writeFile(archivePath, JSON.stringify({ governance, facts, blockers, questions, nudges, gotchas }, null, 2));\n\n // Delete from warm storage\n this.warmDb.prepare('DELETE FROM governance 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 this.warmDb.prepare('DELETE FROM nudges WHERE timestamp < ? AND resolved = 1').run(cutoff);\n this.warmDb.prepare('DELETE FROM gotchas WHERE timestamp < ? AND resolved = 1').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"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/agent/trie-agent.ts","../src/agent/risk-predictor.ts","../src/agent/escalation.ts","../src/agent/meta-learning.ts"],"sourcesContent":["/**\n * Trie Agent - A proactive, intelligent agent that watches over your codebase\n * \n * The Trie Agent:\n * - Synthesizes insights from multiple skills\n * - Speaks conversationally, like a helpful colleague\n * - Suggests specific actions, not just problems\n * - Tracks patterns over time and learns\n * - Anticipates issues before they become critical\n * \n * Integration:\n * - Uses existing memory infrastructure (issue-store, global-memory)\n * - Persistent insight storage (survives restarts)\n * - Goal tracking and hypothesis validation\n * - Optionally enhances with LLM when ANTHROPIC_API_KEY is available\n */\n\nimport type { Issue } from '../types/index.js';\nimport { storeIssues, autoResolveIssues, getIssueHash } from '../memory/issue-store.js';\nimport { recordToGlobalMemory, findCrossProjectPatterns } from '../memory/global-memory.js';\nimport { getHistoricalInsights } from '../memory/compactor.js';\nimport { isAIAvailable, runAIAnalysis } from '../ai/client.js';\nimport { basename } from 'path';\nimport { getInsightStore, type Insight } from './insight-store.js';\nimport { getProjectState } from './project-state.js';\nimport { getGoalManager } from './goal-manager.js';\nimport { getRiskPredictor } from './risk-predictor.js';\nimport { getHypothesisEngine } from './hypothesis.js';\nimport { getEscalationManager } from './escalation.js';\nimport { getMetaLearner } from './meta-learning.js';\nimport { GotchaPredictor } from './gotcha-predictor.js';\nimport { ContextGraph } from '../context/graph.js';\nimport { getStorage } from '../storage/tiered-storage.js';\nimport type { Gotcha } from '../types/signal.js';\n\nexport type { Insight } from './insight-store.js';\n\n// Personality phrases for different situations\nconst PERSONALITY = {\n greetings: [\n \"Hey, quick heads up...\",\n \"Noticed something while scanning...\",\n \"Worth mentioning...\",\n \"Just so you know...\",\n \"Spotted this...\",\n ],\n warnings: [\n \"This needs your attention:\",\n \"I'd pause on this:\",\n \"Before you push...\",\n \"Hold up —\",\n \"Important:\",\n ],\n celebrations: [\n \"Nice work!\",\n \"Good catch!\",\n \"That's better.\",\n \"Clean.\",\n \"Progress.\",\n ],\n suggestions: [\n \"You might want to\",\n \"Consider\",\n \"Suggestion:\",\n \"Quick win:\",\n \"Idea:\",\n ],\n questions: [\n \"Did you mean to\",\n \"Should this\",\n \"Is it intentional that\",\n \"Quick question:\",\n ],\n};\n\nexport class TrieAgent {\n private projectPath: string;\n private projectName: string;\n private lastIssueHashes: Set<string> = new Set();\n private initialized: boolean = false;\n \n // Persistent stores\n private insightStore;\n private projectState;\n \n // Agency modules\n private goalManager;\n private riskPredictor;\n private hypothesisEngine;\n private escalationManager;\n private metaLearner;\n private gotchaPredictor;\n \n constructor(projectPath: string) {\n this.projectPath = projectPath;\n this.projectName = basename(projectPath);\n \n // Initialize persistent stores\n this.insightStore = getInsightStore(projectPath);\n this.projectState = getProjectState(projectPath);\n \n // Initialize agency modules\n this.goalManager = getGoalManager(projectPath);\n this.riskPredictor = getRiskPredictor(projectPath);\n this.hypothesisEngine = getHypothesisEngine(projectPath);\n this.escalationManager = getEscalationManager(projectPath);\n this.metaLearner = getMetaLearner(projectPath);\n this.gotchaPredictor = new GotchaPredictor(projectPath, new ContextGraph(projectPath));\n }\n \n /**\n * Initialize the agent - loads persistent state and historical data\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n \n try {\n // Load persistent stores\n await this.insightStore.load();\n await this.projectState.load();\n \n // Update last active timestamp\n await this.projectState.touchActive();\n \n // Get historical context from existing memory infrastructure\n const historical = await getHistoricalInsights(this.projectPath);\n \n // If we have history, we can detect trends\n if (historical && historical.totalHistoricalIssues > 0) {\n const trend = historical.improvementTrend;\n if (trend === 'improving' && this.canCreateInsight('progress-trend')) {\n await this.addInsight(this.createInsight({\n type: 'celebration',\n message: `${this.pick(PERSONALITY.celebrations)} Your code quality has been improving over time.`,\n priority: 2,\n category: 'progress',\n }));\n await this.markInsightCreated('progress-trend');\n } else if (trend === 'declining' && this.canCreateInsight('progress-trend')) {\n await this.addInsight(this.createInsight({\n type: 'observation',\n message: `${this.pick(PERSONALITY.greetings)} Issue count has been trending up. Might be worth a focused cleanup session.`,\n suggestedAction: 'Run `trie scan` and address top issues',\n priority: 5,\n category: 'quality',\n }));\n await this.markInsightCreated('progress-trend');\n }\n }\n \n this.initialized = true;\n } catch {\n // Memory might not exist yet - that's fine\n this.initialized = true;\n }\n }\n \n /**\n * Add an insight to persistent storage\n */\n async addInsight(insight: Insight): Promise<boolean> {\n return this.insightStore.addInsight(insight);\n }\n \n /**\n * Restart the agent (reload state from disk)\n */\n async restart(): Promise<void> {\n this.initialized = false;\n await this.insightStore.reload();\n await this.projectState.reload();\n await this.initialize();\n }\n \n /**\n * Load state from disk (for testing)\n */\n async loadState(): Promise<{ goals: any[]; riskBudget: any }> {\n await this.projectState.load();\n return {\n goals: this.projectState.getAllGoals(),\n riskBudget: this.projectState.getRiskBudget(),\n };\n }\n \n /**\n * Process new issues from a scan and generate insights\n * Stores issues in memory and optionally uses LLM for deeper analysis\n */\n async processIssues(issues: Issue[], context: { filesChanged?: string[]; isWatchMode: boolean }): Promise<Insight[]> {\n const newInsights: Insight[] = [];\n \n // 1. Store issues in memory infrastructure\n try {\n await storeIssues(issues, this.projectName, this.projectPath);\n await recordToGlobalMemory(issues, this.projectName, this.projectPath);\n \n // Auto-resolve issues no longer detected in changed files\n if (context.filesChanged && context.filesChanged.length > 0) {\n const currentHashes = new Set(issues.map(i => getIssueHash(i)));\n await autoResolveIssues(currentHashes, context.filesChanged, this.projectPath);\n }\n } catch {\n // Memory errors shouldn't break the agent\n }\n \n // 2. Detect changes from last scan\n const currentHashes = new Set(issues.map(i => `${i.file}:${i.line}:${i.issue.slice(0, 50)}`));\n const newIssues = issues.filter(i => !this.lastIssueHashes.has(`${i.file}:${i.line}:${i.issue.slice(0, 50)}`));\n const fixedCount = [...this.lastIssueHashes].filter(h => !currentHashes.has(h)).length;\n \n // 3. Generate heuristic insights (with cooldowns to avoid duplicates)\n \n // Accessibility issues with visual QA recommendation\n const accessibilityIssues = issues.filter(i => \n i.agent === 'accessibility' && \n (i.severity === 'critical' || i.severity === 'serious')\n );\n \n if (accessibilityIssues.length >= 2 && this.canCreateInsight('accessibility-visual-qa')) {\n const critical = accessibilityIssues.filter(i => i.severity === 'critical');\n const serious = accessibilityIssues.filter(i => i.severity === 'serious');\n \n const breakdown: Record<string, number> = {};\n if (critical.length > 0) breakdown['critical'] = critical.length;\n if (serious.length > 0) breakdown['serious'] = serious.length;\n \n const affectedFiles = [...new Set(accessibilityIssues.map(i => i.file))];\n const examples = [...critical, ...serious]\n .slice(0, 3)\n .map(i => `${basename(i.file)}:${i.line} - ${i.issue.slice(0, 60)}`);\n \n const insight = this.createInsight({\n type: 'suggestion',\n message: `Found ${accessibilityIssues.length} accessibility issue${accessibilityIssues.length > 1 ? 's' : ''} that could block users. Screenshots would help validate real impact.`,\n suggestedAction: 'Capture screenshots for visual analysis',\n actionCommand: 'trie_visual_qa_browser url:\"http://localhost:3000\"',\n priority: 7,\n category: 'quality',\n relatedIssues: accessibilityIssues.map(i => i.id),\n details: {\n affectedFiles: affectedFiles.map(f => basename(f)),\n issueBreakdown: breakdown,\n examples,\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('accessibility-visual-qa');\n }\n \n // Security concerns get immediate attention\n const securityIssues = issues.filter(i => \n i.category === 'security' || \n i.issue.toLowerCase().includes('secret') ||\n i.issue.toLowerCase().includes('vulnerability') ||\n i.issue.toLowerCase().includes('injection') ||\n i.issue.toLowerCase().includes('xss')\n );\n \n if (securityIssues.length > 0 && this.canCreateInsight('security-warning')) {\n const critical = securityIssues.filter(i => i.severity === 'critical');\n const serious = securityIssues.filter(i => i.severity === 'serious');\n if (critical.length > 0 || serious.length >= 2) {\n // Build severity breakdown\n const breakdown: Record<string, number> = {};\n if (critical.length > 0) breakdown['critical'] = critical.length;\n if (serious.length > 0) breakdown['serious'] = serious.length;\n \n // Get unique affected files\n const affectedFiles = [...new Set(securityIssues.map(i => i.file))];\n \n // Get example issues (most severe first)\n const examples = [...critical, ...serious]\n .slice(0, 3)\n .map(i => `${basename(i.file)}:${i.line} - ${i.issue.slice(0, 60)}`);\n \n const insight = this.createInsight({\n type: 'warning',\n message: `Found ${securityIssues.length} security issue${securityIssues.length > 1 ? 's' : ''} that could expose your app.`,\n suggestedAction: `Review ${affectedFiles.length} file${affectedFiles.length > 1 ? 's' : ''} immediately`,\n actionCommand: 'trie scan --skill security',\n priority: 10,\n category: 'security',\n relatedIssues: securityIssues.map(i => i.id),\n details: {\n affectedFiles: affectedFiles.map(f => basename(f)),\n issueBreakdown: breakdown,\n examples,\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('security-warning');\n }\n }\n \n // New issues from recent changes\n if (newIssues.length >= 3 && context.filesChanged && context.filesChanged.length > 0 && this.canCreateInsight('new-issues')) {\n const affectedFiles = [...new Set(newIssues.map(i => basename(i.file)))];\n const filesChanged = context.filesChanged.map(f => basename(f));\n \n // Breakdown by severity\n const breakdown: Record<string, number> = {};\n const critical = newIssues.filter(i => i.severity === 'critical');\n const serious = newIssues.filter(i => i.severity === 'serious');\n const moderate = newIssues.filter(i => i.severity === 'moderate');\n if (critical.length > 0) breakdown['critical'] = critical.length;\n if (serious.length > 0) breakdown['serious'] = serious.length;\n if (moderate.length > 0) breakdown['moderate'] = moderate.length;\n \n // Get example issues\n const examples = newIssues\n .sort((a, b) => {\n const sev: Record<string, number> = { critical: 3, serious: 2, moderate: 1, minor: 0, low: 0 };\n return (sev[b.severity] || 0) - (sev[a.severity] || 0);\n })\n .slice(0, 3)\n .map(i => `${basename(i.file)}:${i.line} - ${i.issue.slice(0, 50)}`);\n \n const insight = this.createInsight({\n type: 'observation',\n message: `Recent changes introduced ${newIssues.length} new issues in ${affectedFiles.slice(0, 3).join(', ')}.`,\n suggestedAction: `Review ${affectedFiles.length} affected file${affectedFiles.length > 1 ? 's' : ''}`,\n priority: 6,\n category: 'quality',\n details: {\n affectedFiles: affectedFiles.slice(0, 8),\n issueBreakdown: breakdown,\n examples,\n comparison: `Changed: ${filesChanged.slice(0, 3).join(', ')}${filesChanged.length > 3 ? ` +${filesChanged.length - 3} more` : ''}`,\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('new-issues');\n }\n \n // Celebrate fixes\n if (fixedCount > 0 && newIssues.length === 0 && this.canCreateInsight('celebration')) {\n const insight = this.createInsight({\n type: 'celebration',\n message: `${this.pick(PERSONALITY.celebrations)} ${fixedCount} issue${fixedCount > 1 ? 's' : ''} resolved.`,\n priority: 3,\n category: 'progress',\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('celebration');\n }\n \n // === AUTONOMOUS HYPOTHESIS GENERATION ===\n // After every scan, check if Claude should generate new hypotheses\n // This enables the agent to continuously learn and form theories about code quality\n if (issues.length >= 10 && this.canCreateInsight('hypothesis-generation')) {\n try {\n const patterns: string[] = [];\n const observations: string[] = [];\n \n // Observe patterns from this scan\n if (newIssues.length > issues.length * 0.3) {\n observations.push(`High new issue rate: ${newIssues.length} new out of ${issues.length} total`);\n }\n \n const fileFreq: Record<string, number> = {};\n for (const issue of issues) {\n fileFreq[issue.file] = (fileFreq[issue.file] || 0) + 1;\n }\n const hotFiles = Object.entries(fileFreq).filter(([, count]) => count >= 3);\n if (hotFiles.length > 0) {\n patterns.push(`Hotspot files: ${hotFiles.map(([f]) => basename(f)).join(', ')}`);\n }\n \n // Try AI-powered hypothesis generation\n const generated = await this.hypothesisEngine.generateHypothesesWithAI({\n recentIssues: issues.map(i => ({ issue: i, score: 1 })),\n patterns,\n observations,\n });\n \n // Create insights for new hypotheses\n for (const hypothesis of generated) {\n const insight = this.createInsight({\n type: 'observation',\n message: `${this.pick(PERSONALITY.questions)} New hypothesis to test: \"${hypothesis.statement}\"`,\n context: `Confidence: ${Math.round(hypothesis.confidence * 100)}%`,\n suggestedAction: `Monitor this pattern over time`,\n priority: 4,\n category: 'pattern',\n details: {\n hypothesis: hypothesis.statement,\n testCriteria: hypothesis.testCriteria || 'Collecting evidence...',\n confidence: Math.round(hypothesis.confidence * 100),\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n }\n \n if (generated.length > 0) {\n await this.markInsightCreated('hypothesis-generation');\n }\n } catch (error) {\n // Hypothesis generation is best-effort, don't break the scan\n }\n }\n \n // === AUTONOMOUS PATTERN DISCOVERY ===\n // Discover patterns from accumulated issues automatically\n // This makes patterns appear naturally from your workflow\n if (issues.length >= 5 && this.canCreateInsight('pattern-discovery')) {\n try {\n const { IncidentIndex } = await import('../context/incident-index.js');\n const { TriePatternDiscovery } = await import('../agent/pattern-discovery.js');\n const { ContextGraph } = await import('../context/graph.js');\n \n const graph = new ContextGraph(this.projectPath);\n const incidentIndex = await IncidentIndex.build(graph, this.projectPath);\n const discovery = new TriePatternDiscovery(graph, incidentIndex);\n \n // Discover hot patterns with lower threshold for faster discovery\n const hotPatterns = discovery.discoverHotPatterns(2);\n let patternsAdded = 0;\n \n for (const hot of hotPatterns.slice(0, 5)) { // Top 5 hot patterns\n const existingPatterns = await graph.listNodes();\n const alreadyExists = existingPatterns.some(\n n => n.type === 'pattern' && (n.data as any).description?.includes(hot.path)\n );\n \n if (!alreadyExists) {\n await graph.addNode('pattern', {\n description: `${hot.type === 'directory' ? 'Directory' : 'File'} hot zone: ${hot.path}`,\n appliesTo: [hot.path],\n confidence: Math.min(0.95, hot.confidence),\n occurrences: hot.incidentCount,\n firstSeen: new Date().toISOString(),\n lastSeen: new Date().toISOString(),\n isAntiPattern: hot.incidentCount >= 3,\n source: 'local'\n });\n patternsAdded++;\n }\n }\n \n // Create insight if patterns were discovered\n if (patternsAdded > 0) {\n const insight = this.createInsight({\n type: 'observation',\n message: `${this.pick(PERSONALITY.greetings)} Discovered ${patternsAdded} pattern${patternsAdded > 1 ? 's' : ''} in your codebase.`,\n suggestedAction: `Check Memory → Learned Patterns to see`,\n priority: 5,\n category: 'pattern',\n details: {\n patternsCount: patternsAdded,\n topPattern: hotPatterns[0]?.path,\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('pattern-discovery');\n }\n } catch (error) {\n // Pattern discovery is best-effort\n }\n }\n \n // Check for recurring patterns across projects (from global memory)\n if (this.canCreateInsight('pattern-suggestion')) {\n try {\n const globalPatterns = await findCrossProjectPatterns();\n const crossProjectPattern = globalPatterns.find(p => p.projects.length > 1 && p.occurrences > 3);\n if (crossProjectPattern) {\n const insight = this.createInsight({\n type: 'suggestion',\n message: `\"${crossProjectPattern.description}\" appears in ${crossProjectPattern.projects.length} projects. Consider a shared lint rule.`,\n priority: 4,\n category: 'pattern',\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('pattern-suggestion');\n }\n } catch {\n // Global memory might not be available\n }\n }\n \n // Pre-push warning (with cooldown)\n if (context.isWatchMode && this.shouldWarnBeforePush(issues) && this.canCreateInsight('pre-push-warning')) {\n const criticalIssues = issues.filter(i => i.severity === 'critical');\n const seriousIssues = issues.filter(i => i.severity === 'serious');\n const moderateIssues = issues.filter(i => i.severity === 'moderate');\n \n // Build severity breakdown\n const breakdown: Record<string, number> = {};\n if (criticalIssues.length > 0) breakdown['critical'] = criticalIssues.length;\n if (seriousIssues.length > 0) breakdown['serious'] = seriousIssues.length;\n if (moderateIssues.length > 0) breakdown['moderate'] = moderateIssues.length;\n \n // Get affected files by severity\n const criticalFiles = [...new Set(criticalIssues.map(i => basename(i.file)))];\n const seriousFiles = [...new Set(seriousIssues.map(i => basename(i.file)))];\n const affectedFiles = [...new Set([...criticalFiles, ...seriousFiles])].slice(0, 5);\n \n // Get example issues (highest severity first)\n const examples = [...criticalIssues, ...seriousIssues]\n .slice(0, 4)\n .map(i => `${basename(i.file)}:${i.line} - ${i.issue.slice(0, 50)}`);\n \n // Determine trend if we have history\n const totalBlocking = criticalIssues.length + seriousIssues.length;\n const trend = this.lastIssueHashes.size > 0 \n ? (totalBlocking > this.lastIssueHashes.size ? 'worsening' : 'improving')\n : undefined;\n \n // Build details object, only including defined values\n const insightDetails: NonNullable<Insight['details']> = {\n affectedFiles,\n issueBreakdown: breakdown,\n examples,\n };\n if (trend) insightDetails.trend = trend;\n if (moderateIssues.length > 0) insightDetails.comparison = `+${moderateIssues.length} moderate (non-blocking)`;\n \n const insight = this.createInsight({\n type: 'warning',\n message: `${totalBlocking} issue${totalBlocking > 1 ? 's' : ''} need attention before pushing.`,\n suggestedAction: 'Run pre-push check',\n actionCommand: 'trie check',\n priority: 8,\n category: 'quality',\n details: insightDetails,\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('pre-push-warning');\n }\n \n // 4. Optionally enhance with LLM for deeper insights\n if (isAIAvailable() && issues.length > 0 && newIssues.length > 0) {\n const aiInsights = await this.generateAIInsights(issues, newIssues);\n newInsights.push(...aiInsights);\n }\n \n // ==========================================================================\n // 5. AGENCY: Goals, Hypotheses, Risk Prediction\n // ==========================================================================\n \n // Phase 2: Autonomous Goals - Analyze patterns and track progress\n if (this.canCreateInsight('goal-progress')) {\n try {\n const patterns = await this.goalManager.analyzeIncidentPatterns();\n \n // Generate goals from significant patterns (high confidence, enough occurrences)\n const significantPatterns = patterns.filter(p => p.confidence >= 0.6 && p.currentValue >= 3);\n if (significantPatterns.length > 0) {\n // Auto-generate goals which creates insights internally\n await this.goalManager.autoGenerateGoals();\n }\n \n // Update goal progress and check achievements\n await this.goalManager.updateGoalProgress();\n \n // Check goal progress and create insights for major milestones\n const goals = this.projectState.getAllGoals();\n for (const goal of goals.filter(g => g.status === 'active')) {\n // Calculate percent complete\n const startVal = goal.startValue ?? goal.currentValue;\n if (startVal > 0 && goal.currentValue <= startVal) {\n const percentComplete = Math.round((1 - goal.currentValue / startVal) * 100);\n if (percentComplete >= 50 && this.canCreateInsight(`goal-${goal.id}`)) {\n const insight = this.createInsight({\n type: 'celebration',\n message: `Goal \"${goal.description}\" is ${percentComplete}% complete! ${goal.currentValue} issues remaining (started at ${startVal}).`,\n priority: 4,\n category: 'progress',\n details: {\n affectedFiles: goal.category ? [goal.category] : [],\n comparison: `${startVal} → ${goal.currentValue}`,\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated(`goal-${goal.id}`);\n }\n }\n }\n \n await this.markInsightCreated('goal-progress');\n } catch {\n // Goal analysis is optional\n }\n }\n \n // Phase 3: Risk Prediction - Warn about high-risk files\n if (context.filesChanged && context.filesChanged.length > 0 && this.canCreateInsight('risk-prediction')) {\n try {\n const riskSummary = await this.riskPredictor.predictRiskTrend(context.filesChanged);\n \n if (riskSummary.overallRisk >= 50) {\n const highRiskFactors = riskSummary.factors.filter(f => f.reasons.length > 0);\n \n if (highRiskFactors.length > 0) {\n const topFile = highRiskFactors[0];\n const insight = this.createInsight({\n type: 'warning',\n message: `Risk score ${Math.round(riskSummary.overallRisk)}/100 for changed files (${riskSummary.trend}). ${topFile ? basename(topFile.file) + ' is high-risk.' : ''}`,\n suggestedAction: 'Consider extra review before pushing',\n priority: 7,\n category: 'quality',\n details: {\n affectedFiles: highRiskFactors.slice(0, 5).map(f => basename(f.file)),\n trend: riskSummary.trend === 'increasing' ? 'worsening' : riskSummary.trend === 'decreasing' ? 'improving' : 'stable',\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated('risk-prediction');\n }\n }\n } catch {\n // Risk prediction is optional\n }\n }\n\n // Phase 3b: Gotcha Prediction - Store potential risks in ledger (runs independently of risk-prediction)\n if (context.filesChanged && context.filesChanged.length > 0) {\n try {\n const gotchas = await this.gotchaPredictor.predictGotchas(context.filesChanged);\n const storage = getStorage(this.projectPath);\n for (const gotcha of gotchas) {\n if (this.canCreateInsight(`gotcha-${gotcha.id}`)) {\n const explanation = await this.gotchaPredictor.synthesizeGotchaExplanation(gotcha);\n const insight = this.createInsight({\n type: 'warning',\n message: `[Gotcha] ${gotcha.message}`,\n context: explanation,\n suggestedAction: gotcha.recommendation,\n priority: gotcha.riskLevel === 'critical' ? 9 : 7,\n category: 'quality',\n details: {\n affectedFiles: context.filesChanged.map(f => basename(f)),\n examples: [gotcha.message, explanation],\n }\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated(`gotcha-${gotcha.id}`);\n }\n // Store gotcha in ledger for Ledger view (always store, regardless of insight cooldown)\n const primaryFile = context.filesChanged?.[0];\n const ledgerGotcha: Gotcha = {\n id: gotcha.id,\n message: gotcha.message,\n confidence: gotcha.confidence,\n riskLevel: gotcha.riskLevel,\n recommendation: gotcha.recommendation,\n ...(primaryFile && { file: primaryFile }),\n timestamp: new Date().toISOString(),\n ...(gotcha.precedentId && { precedentId: gotcha.precedentId }),\n tags: gotcha.evidence.matchingPatterns,\n evidence: gotcha.evidence,\n resolved: false,\n };\n await storage.storeGotcha(ledgerGotcha);\n }\n } catch {\n // Gotcha prediction is optional\n }\n }\n \n // Phase 3: Hypothesis Validation - Check and update hypotheses\n if (this.canCreateInsight('hypothesis-update')) {\n try {\n // Auto-generate hypotheses if we don't have many\n const hypotheses = this.projectState.getAllHypotheses();\n const testingHypotheses = hypotheses.filter(h => h.status === 'testing');\n \n if (testingHypotheses.length < 3) {\n await this.hypothesisEngine.autoGenerateHypotheses();\n }\n \n // Check for newly validated/invalidated hypotheses and create insights\n const validatedHypotheses = hypotheses.filter(h => \n h.status === 'validated' && \n h.validatedAt && \n Date.now() - new Date(h.validatedAt).getTime() < 24 * 60 * 60 * 1000 // Within last 24h\n );\n \n for (const hypothesis of validatedHypotheses.slice(0, 2)) {\n if (this.canCreateInsight(`hypothesis-${hypothesis.id}`)) {\n const insight = this.createInsight({\n type: 'celebration',\n message: `Hypothesis validated: \"${hypothesis.statement}\" (${Math.round(hypothesis.confidence * 100)}% confidence)`,\n priority: 5,\n category: 'pattern',\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n await this.markInsightCreated(`hypothesis-${hypothesis.id}`);\n }\n }\n \n await this.markInsightCreated('hypothesis-update');\n } catch {\n // Hypothesis validation is optional\n }\n }\n \n // Phase 4: Auto-Escalation - Escalate critical security issues\n const criticalSecurityIssues = issues.filter(i => \n i.severity === 'critical' && \n (i.category === 'security' || i.issue.toLowerCase().includes('secret'))\n );\n \n if (criticalSecurityIssues.length > 0) {\n try {\n const result = await this.escalationManager.escalateIssues(criticalSecurityIssues);\n if (result.action === 'auto_escalated' && result.message) {\n const insight = this.createInsight({\n type: 'observation',\n message: `Auto-escalated ${criticalSecurityIssues.length} critical security issue(s). Check your notifications.`,\n priority: 9,\n category: 'security',\n details: {\n affectedFiles: criticalSecurityIssues.slice(0, 5).map(i => basename(i.file)),\n examples: criticalSecurityIssues.slice(0, 3).map(i => i.issue.slice(0, 60)),\n },\n });\n newInsights.push(insight);\n await this.addInsight(insight);\n }\n } catch {\n // Escalation is best-effort\n }\n }\n \n // Phase 4: Meta-Learning - Note: actual feedback recording happens when user interacts\n // Here we just track that insights were shown (for latency tracking)\n // The user feedback is recorded via markInsightHelpful/dismissInsight/markInsightActedOn\n \n // Update state\n this.lastIssueHashes = currentHashes;\n \n // Record scan timestamp\n await this.projectState.recordScan();\n \n // Adapt scan frequency based on risk (Phase 2)\n try {\n const riskLevel = issues.filter(i => i.severity === 'critical').length > 0 ? 'critical' :\n issues.filter(i => i.severity === 'serious').length >= 3 ? 'high' :\n issues.length > 10 ? 'medium' : 'low';\n \n // Calculate and store adaptive scan frequency\n const { calculateAdaptiveScanFrequency } = await import('./goal-manager.js');\n const result = await calculateAdaptiveScanFrequency(riskLevel);\n await this.projectState.setScanFrequency(result.frequencyMs);\n } catch {\n // Scan frequency adaptation is optional\n }\n \n // Auto-resolve nudges for issues that were fixed\n try {\n const { getStorage } = await import('../storage/tiered-storage.js');\n const storage = getStorage(this.projectPath);\n \n // Get issue IDs that were resolved (no longer in current scan)\n const resolvedIssueIds = [...this.lastIssueHashes]\n .filter(h => !currentHashes.has(h))\n .map(h => {\n // Convert hash to potential issue ID\n // Hash format is \"file:line:issue_start\"\n // Issue IDs are typically like \"issueId\" or include file/line info\n return h.split(':').join('-');\n });\n \n if (resolvedIssueIds.length > 0) {\n const resolvedCount = await storage.autoResolveFixedNudges(resolvedIssueIds);\n if (resolvedCount > 0) {\n console.debug(`[Agent] Auto-resolved ${resolvedCount} nudge${resolvedCount !== 1 ? 's' : ''} for fixed issues`);\n }\n }\n } catch {\n // Auto-resolve is best-effort, don't break the scan\n }\n \n return newInsights;\n }\n \n /**\n * Use LLM to generate deeper insights (optional, requires ANTHROPIC_API_KEY)\n */\n private async generateAIInsights(_allIssues: Issue[], newIssues: Issue[]): Promise<Insight[]> {\n const insights: Insight[] = [];\n \n try {\n // Only analyze if we have significant new issues\n if (newIssues.length < 2) return insights;\n \n const issuesSummary = newIssues.slice(0, 10).map(i => ({\n severity: i.severity,\n issue: i.issue.slice(0, 100),\n file: basename(i.file),\n agent: i.agent\n }));\n \n const result = await runAIAnalysis({\n systemPrompt: `You are a helpful code reviewer. Analyze these issues and provide ONE brief, conversational insight.\nBe specific and actionable. Speak like a helpful colleague, not a system.\nKeep your response under 100 words. Focus on the most important pattern or concern.`,\n userPrompt: `New issues found:\\n${JSON.stringify(issuesSummary, null, 2)}\n\nWhat's the most important thing the developer should know? Provide a brief, conversational insight.`,\n maxTokens: 200,\n temperature: 0.7\n });\n \n if (result.success && result.content) {\n const insight = this.createInsight({\n type: 'observation',\n message: result.content.trim(),\n priority: 5,\n category: 'general',\n });\n insights.push(insight);\n await this.addInsight(insight);\n }\n } catch {\n // AI analysis is optional, don't fail\n }\n \n return insights;\n }\n \n /**\n * Get active insights (not dismissed, still relevant)\n */\n getActiveInsights(): Insight[] {\n return this.insightStore.getActiveInsights();\n }\n \n /**\n * Dismiss an insight\n */\n async dismissInsight(insightId: string): Promise<boolean> {\n const result = await this.insightStore.dismissInsight(insightId);\n \n // Record feedback for meta-learning (Phase 4)\n if (result) {\n await this.projectState.recordInsightFeedback('dismissed');\n }\n \n return result;\n }\n \n /**\n * Record that a user found an insight helpful\n */\n async markInsightHelpful(_insightId: string): Promise<void> {\n await this.projectState.recordInsightFeedback('helpful');\n }\n \n /**\n * Record that a user acted on an insight\n */\n async markInsightActedOn(_insightId: string): Promise<void> {\n await this.projectState.recordInsightFeedback('acted');\n }\n \n /**\n * Get insight statistics\n */\n getInsightStats() {\n return this.insightStore.getStats();\n }\n \n /**\n * Get agent metrics (for dashboard display)\n */\n getAgentMetrics() {\n return this.projectState.getMetrics();\n }\n \n /**\n * Check if in quiet hours\n */\n isQuietHours(): boolean {\n return this.projectState.isQuietHours();\n }\n \n /**\n * Check if in crunch mode\n */\n isInCrunchMode(): boolean {\n return this.projectState.isInCrunchMode();\n }\n \n /**\n * Get the insight store (for advanced operations)\n */\n getInsightStore() {\n return this.insightStore;\n }\n \n /**\n * Get the project state (for advanced operations)\n */\n getProjectState() {\n return this.projectState;\n }\n \n /**\n * Get agency modules (for watch mode integration)\n */\n getGoalManager() {\n return this.goalManager;\n }\n \n getRiskPredictor() {\n return this.riskPredictor;\n }\n \n getHypothesisEngine() {\n return this.hypothesisEngine;\n }\n \n getEscalationManager() {\n return this.escalationManager;\n }\n \n getMetaLearner() {\n return this.metaLearner;\n }\n \n /**\n * Get a rich agency status for display in watch mode\n */\n async getAgencyStatus(): Promise<{\n goals: { active: number; completed: number; topGoal?: string };\n hypotheses: { testing: number; validated: number; topHypothesis?: string };\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n scanFrequency: number;\n effectiveness: number;\n isQuietHours: boolean;\n }> {\n const goals = this.projectState.getAllGoals();\n const activeGoals = goals.filter((g: { status: string }) => g.status === 'active');\n const completedGoals = goals.filter((g: { status: string }) => g.status === 'achieved');\n \n const hypotheses = this.projectState.getAllHypotheses();\n const testingHypotheses = hypotheses.filter((h: { status: string }) => h.status === 'testing');\n const validatedHypotheses = hypotheses.filter((h: { status: string }) => h.status === 'validated');\n \n const metrics = this.projectState.getMetrics();\n const budget = this.projectState.getRiskBudget();\n \n // Calculate daily actions remaining\n const dailyActionsRemaining = budget.daily - budget.usedToday;\n \n // Calculate overall risk level\n let riskLevel: 'low' | 'medium' | 'high' | 'critical' = 'low';\n if (dailyActionsRemaining <= 1) riskLevel = 'critical';\n else if (dailyActionsRemaining <= 3) riskLevel = 'high';\n else if (dailyActionsRemaining <= 5) riskLevel = 'medium';\n \n // Calculate effectiveness using correct property names\n const totalFeedback = metrics.helpfulInsights + metrics.dismissedInsights + metrics.actedOnInsights;\n const effectiveness = totalFeedback > 0 \n ? Math.round(((metrics.helpfulInsights + metrics.actedOnInsights) / totalFeedback) * 100)\n : 100; // Default to 100% if no feedback yet\n \n // Build result with conditional optional properties\n const topGoal = activeGoals[0]?.description;\n const topHypothesis = testingHypotheses[0]?.statement?.slice(0, 50);\n \n const result: {\n goals: { active: number; completed: number; topGoal?: string };\n hypotheses: { testing: number; validated: number; topHypothesis?: string };\n riskLevel: 'low' | 'medium' | 'high' | 'critical';\n scanFrequency: number;\n effectiveness: number;\n isQuietHours: boolean;\n } = {\n goals: {\n active: activeGoals.length,\n completed: completedGoals.length,\n },\n hypotheses: {\n testing: testingHypotheses.length,\n validated: validatedHypotheses.length,\n },\n riskLevel,\n scanFrequency: this.projectState.getScanFrequencyMs(),\n effectiveness,\n isQuietHours: this.projectState.isQuietHours(),\n };\n \n if (topGoal) result.goals.topGoal = topGoal;\n if (topHypothesis) result.hypotheses.topHypothesis = topHypothesis;\n \n return result;\n }\n \n /**\n * Get a summary for the current state\n */\n getSummary(issues: Issue[]): string {\n const critical = issues.filter(i => i.severity === 'critical').length;\n const serious = issues.filter(i => i.severity === 'serious').length;\n const total = issues.length;\n \n if (total === 0) {\n return \"All clear. Your code looks good.\";\n }\n \n if (critical > 0) {\n return `${critical} critical issue${critical > 1 ? 's' : ''} need${critical === 1 ? 's' : ''} immediate attention.`;\n }\n \n if (serious > 0) {\n return `${serious} serious issue${serious > 1 ? 's' : ''} worth reviewing before shipping.`;\n }\n \n return `${total} minor thing${total > 1 ? 's' : ''} to polish when you have time.`;\n }\n \n // === Private helpers ===\n \n private shouldWarnBeforePush(issues: Issue[]): boolean {\n const critical = issues.filter(i => i.severity === 'critical').length;\n const serious = issues.filter(i => i.severity === 'serious').length;\n return critical > 0 || serious >= 3;\n }\n \n /**\n * Check if we should create an insight of this type (cooldown not expired)\n */\n private canCreateInsight(insightKey: string): boolean {\n return this.insightStore.canCreateInsight(insightKey);\n }\n \n /**\n * Mark that we created an insight of this type\n */\n private async markInsightCreated(insightKey: string): Promise<void> {\n await this.insightStore.markInsightCreated(insightKey);\n }\n \n private createInsight(params: Omit<Insight, 'id' | 'timestamp' | 'dismissed' | 'relatedIssues'> & { relatedIssues?: string[] }): Insight {\n return {\n id: `insight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n timestamp: Date.now(),\n dismissed: false,\n relatedIssues: params.relatedIssues || [],\n ...params,\n };\n }\n \n private pick<T>(arr: T[]): T {\n return arr[Math.floor(Math.random() * arr.length)] as T;\n }\n}\n\n// Singleton instance per project\nconst agentInstances: Map<string, TrieAgent> = new Map();\n\nexport function getTrieAgent(projectPath: string): TrieAgent {\n let agent = agentInstances.get(projectPath);\n if (!agent) {\n agent = new TrieAgent(projectPath);\n agentInstances.set(projectPath, agent);\n }\n return agent;\n}\n\n","/**\n * Risk Predictor - Predictive risk scoring with trend analysis\n * \n * Features:\n * - Multi-factor risk scoring\n * - Trend analysis (increasing/stable/decreasing)\n * - File-level risk predictions\n * - Historical incident correlation\n * - Proactive risk warnings\n */\n\nimport type { Insight } from './insight-store.js';\nimport { getInsightStore } from './insight-store.js';\nimport { searchIssues, type StoredIssue } from '../memory/issue-store.js';\nimport { basename, dirname } from 'path';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Risk factor contributing to overall risk\n */\nexport interface RiskFactor {\n name: string;\n weight: number; // 0-1, contribution to risk\n value: number; // Current measured value\n description: string;\n trend?: 'increasing' | 'stable' | 'decreasing';\n}\n\n/**\n * Risk prediction for a file or directory\n */\nexport interface RiskPrediction {\n target: string; // File or directory path\n currentRisk: number; // 0-100\n predictedRisk: number; // 0-100 (future prediction)\n trend: 'increasing' | 'stable' | 'decreasing';\n factors: RiskFactor[];\n confidence: number; // 0-1\n recommendations: string[];\n lastIncidentDaysAgo?: number;\n incidentCount: number;\n}\n\n/**\n * Overall project risk summary\n */\nexport interface ProjectRiskSummary {\n overallRisk: number; // 0-100\n trend: 'increasing' | 'stable' | 'decreasing';\n hotspots: RiskPrediction[];\n lowRiskAreas: string[];\n predictions: RiskPrediction[];\n confidence: number;\n}\n\n/**\n * Risk prediction configuration\n */\nexport interface RiskPredictionConfig {\n historyDays: number; // Days of history to consider\n incidentThreshold: number; // Min incidents to flag as hotspot\n riskWeights: {\n incidentCount: number;\n recency: number;\n severity: number;\n complexity: number;\n churn: number;\n };\n}\n\nconst DEFAULT_CONFIG: RiskPredictionConfig = {\n historyDays: 30,\n incidentThreshold: 3,\n riskWeights: {\n incidentCount: 0.35,\n recency: 0.25,\n severity: 0.20,\n complexity: 0.10,\n churn: 0.10,\n },\n};\n\n// ============================================================================\n// RiskPredictor Class\n// ============================================================================\n\n/**\n * Predictive risk analysis engine\n */\nexport class RiskPredictor {\n private projectPath: string;\n private config: RiskPredictionConfig;\n private insightStore;\n \n constructor(projectPath: string, config: Partial<RiskPredictionConfig> = {}) {\n this.projectPath = projectPath;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.insightStore = getInsightStore(projectPath);\n }\n \n /**\n * Calculate risk for a specific file or directory\n */\n async calculateRisk(target: string): Promise<RiskPrediction> {\n const factors: RiskFactor[] = [];\n let totalRisk = 0;\n \n try {\n // Get historical issues for this target\n const issues = await searchIssues(target, {\n workDir: this.projectPath,\n limit: 500,\n includeResolved: true,\n });\n \n const targetIssues = issues.filter(r => \n r.issue.file === target || \n r.issue.file.startsWith(target + '/') ||\n dirname(r.issue.file) === target\n );\n \n // 1. Incident count factor\n const incidentCount = targetIssues.length;\n const incidentWeight = this.config.riskWeights.incidentCount;\n const incidentScore = Math.min(100, incidentCount * 10);\n factors.push({\n name: 'Incident Count',\n weight: incidentWeight,\n value: incidentCount,\n description: `${incidentCount} historical incidents`,\n trend: this.calculateTrend(targetIssues.map(i => i.issue)),\n });\n totalRisk += incidentScore * incidentWeight;\n \n // 2. Recency factor (when was the last incident?)\n let recencyScore = 0;\n let lastIncidentDaysAgo: number | undefined;\n if (targetIssues.length > 0) {\n const latestIssue = targetIssues\n .sort((a, b) => new Date(b.issue.timestamp).getTime() - new Date(a.issue.timestamp).getTime())[0];\n \n if (latestIssue) {\n const daysSince = (Date.now() - new Date(latestIssue.issue.timestamp).getTime()) / (1000 * 60 * 60 * 24);\n lastIncidentDaysAgo = Math.floor(daysSince);\n \n // More recent = higher risk\n if (daysSince < 1) recencyScore = 100;\n else if (daysSince < 7) recencyScore = 80;\n else if (daysSince < 14) recencyScore = 60;\n else if (daysSince < 30) recencyScore = 40;\n else recencyScore = 20;\n }\n }\n \n factors.push({\n name: 'Recency',\n weight: this.config.riskWeights.recency,\n value: lastIncidentDaysAgo ?? 999,\n description: lastIncidentDaysAgo !== undefined \n ? `Last incident ${lastIncidentDaysAgo} days ago`\n : 'No recent incidents',\n });\n totalRisk += recencyScore * this.config.riskWeights.recency;\n \n // 3. Severity factor\n const criticalCount = targetIssues.filter(r => r.issue.severity === 'critical').length;\n const seriousCount = targetIssues.filter(r => r.issue.severity === 'serious').length;\n const severityScore = Math.min(100, (criticalCount * 25) + (seriousCount * 10));\n \n factors.push({\n name: 'Severity',\n weight: this.config.riskWeights.severity,\n value: severityScore,\n description: `${criticalCount} critical, ${seriousCount} serious`,\n });\n totalRisk += severityScore * this.config.riskWeights.severity;\n \n // 4. Complexity factor (approximated by issue diversity)\n const uniqueAgents = new Set(targetIssues.map(r => r.issue.agent)).size;\n const complexityScore = Math.min(100, uniqueAgents * 20);\n \n factors.push({\n name: 'Complexity',\n weight: this.config.riskWeights.complexity,\n value: uniqueAgents,\n description: `Issues from ${uniqueAgents} different analysis types`,\n });\n totalRisk += complexityScore * this.config.riskWeights.complexity;\n \n // 5. Churn factor (how often this file has issues)\n // Approximate by counting unique dates with issues\n const uniqueDates = new Set(\n targetIssues.map(r => r.issue.timestamp.split('T')[0])\n ).size;\n const churnScore = Math.min(100, uniqueDates * 10);\n \n factors.push({\n name: 'Churn',\n weight: this.config.riskWeights.churn,\n value: uniqueDates,\n description: `Issues found on ${uniqueDates} different days`,\n });\n totalRisk += churnScore * this.config.riskWeights.churn;\n \n // Calculate trend\n const trend = this.calculateTrend(targetIssues.map(i => i.issue));\n \n // Predict future risk based on trend\n let predictedRisk = totalRisk;\n if (trend === 'increasing') {\n predictedRisk = Math.min(100, totalRisk * 1.2);\n } else if (trend === 'decreasing') {\n predictedRisk = Math.max(0, totalRisk * 0.8);\n }\n \n // Generate recommendations\n const recommendations = this.generateRecommendations(factors, totalRisk);\n \n // Calculate confidence based on data quality\n const confidence = Math.min(0.95, 0.3 + (incidentCount * 0.05));\n \n const prediction: RiskPrediction = {\n target,\n currentRisk: Math.round(totalRisk),\n predictedRisk: Math.round(predictedRisk),\n trend,\n factors,\n confidence,\n recommendations,\n incidentCount,\n };\n \n if (lastIncidentDaysAgo !== undefined) {\n prediction.lastIncidentDaysAgo = lastIncidentDaysAgo;\n }\n \n return prediction;\n \n } catch (error) {\n console.error(`Failed to calculate risk for ${target}:`, error);\n return {\n target,\n currentRisk: 50,\n predictedRisk: 50,\n trend: 'stable',\n factors: [],\n confidence: 0.1,\n recommendations: ['Unable to analyze - insufficient data'],\n incidentCount: 0,\n };\n }\n }\n \n /**\n * Calculate trend from issues\n */\n private calculateTrend(issues: StoredIssue[]): 'increasing' | 'stable' | 'decreasing' {\n if (issues.length < 3) return 'stable';\n \n const now = Date.now();\n const recentCutoff = now - (7 * 24 * 60 * 60 * 1000); // 7 days\n const olderCutoff = now - (30 * 24 * 60 * 60 * 1000); // 30 days\n \n const recentIssues = issues.filter(i => new Date(i.timestamp).getTime() > recentCutoff).length;\n const olderIssues = issues.filter(i => {\n const time = new Date(i.timestamp).getTime();\n return time > olderCutoff && time <= recentCutoff;\n }).length;\n \n // Normalize by time period\n const recentRate = recentIssues / 7;\n const olderRate = olderIssues / 23;\n \n if (recentRate > olderRate * 1.5) return 'increasing';\n if (recentRate < olderRate * 0.5) return 'decreasing';\n return 'stable';\n }\n \n /**\n * Generate recommendations based on risk factors\n */\n private generateRecommendations(factors: RiskFactor[], totalRisk: number): string[] {\n const recommendations: string[] = [];\n \n if (totalRisk >= 70) {\n recommendations.push('Consider extra code review before merging changes');\n }\n \n const incidentFactor = factors.find(f => f.name === 'Incident Count');\n if (incidentFactor && incidentFactor.value >= 5) {\n recommendations.push('This area has recurring issues - consider refactoring');\n }\n \n const recencyFactor = factors.find(f => f.name === 'Recency');\n if (recencyFactor && recencyFactor.value < 7) {\n recommendations.push('Recent incident activity - monitor closely');\n }\n \n const severityFactor = factors.find(f => f.name === 'Severity');\n if (severityFactor && severityFactor.value >= 25) {\n recommendations.push('High severity issues present - prioritize fixes');\n }\n \n const complexityFactor = factors.find(f => f.name === 'Complexity');\n if (complexityFactor && complexityFactor.value >= 4) {\n recommendations.push('Multiple issue types - consider comprehensive review');\n }\n \n if (recommendations.length === 0) {\n recommendations.push('No specific concerns - maintain normal review process');\n }\n \n return recommendations;\n }\n \n /**\n * Predict risk trend for files that have recently changed\n */\n async predictRiskTrend(changedFiles: string[]): Promise<{\n trend: 'increasing' | 'stable' | 'decreasing';\n factors: Array<{ file: string; reasons: string[] }>;\n overallRisk: number;\n }> {\n const predictions = await Promise.all(\n changedFiles.map(f => this.calculateRisk(f))\n );\n \n const highRiskFiles = predictions.filter(p => p.currentRisk >= 50);\n const totalRisk = predictions.reduce((sum, p) => sum + p.currentRisk, 0) / Math.max(1, predictions.length);\n \n // Determine overall trend\n const trends = predictions.map(p => p.trend);\n const increasingCount = trends.filter(t => t === 'increasing').length;\n const decreasingCount = trends.filter(t => t === 'decreasing').length;\n \n let overallTrend: 'increasing' | 'stable' | 'decreasing' = 'stable';\n if (increasingCount > decreasingCount + 1) {\n overallTrend = 'increasing';\n } else if (decreasingCount > increasingCount + 1) {\n overallTrend = 'decreasing';\n }\n \n // Collect factors for high-risk files\n const factors = highRiskFiles.map(p => ({\n file: p.target,\n reasons: p.incidentCount > 0 \n ? ['past incidents', ...p.recommendations.slice(0, 2)]\n : ['no historical data'],\n }));\n \n return {\n trend: overallTrend,\n factors,\n overallRisk: Math.round(totalRisk),\n };\n }\n \n /**\n * Get project-wide risk summary\n */\n async getProjectRiskSummary(): Promise<ProjectRiskSummary> {\n try {\n const issues = await searchIssues('', {\n workDir: this.projectPath,\n limit: 1000,\n includeResolved: true,\n });\n \n // Group by directory\n const dirIssueCount = new Map<string, StoredIssue[]>();\n for (const { issue } of issues) {\n const dir = dirname(issue.file);\n const existing = dirIssueCount.get(dir) || [];\n existing.push(issue);\n dirIssueCount.set(dir, existing);\n }\n \n // Find hotspots (directories with many issues)\n const hotspotDirs = [...dirIssueCount.entries()]\n .filter(([_, issues]) => issues.length >= this.config.incidentThreshold)\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, 5);\n \n // Calculate risk for each hotspot\n const hotspots = await Promise.all(\n hotspotDirs.map(([dir]) => this.calculateRisk(dir))\n );\n \n // Find low-risk areas\n const allDirs = [...dirIssueCount.keys()];\n const lowRiskPredictions = await Promise.all(\n allDirs.map(dir => this.calculateRisk(dir))\n );\n const lowRiskAreas = lowRiskPredictions\n .filter(p => p.currentRisk < 20 && p.incidentCount === 0)\n .map(p => p.target)\n .slice(0, 5);\n \n // Calculate overall risk\n const overallRisk = hotspots.length > 0\n ? hotspots.reduce((sum, p) => sum + p.currentRisk, 0) / hotspots.length\n : 0;\n \n // Determine trend\n const trends = hotspots.map(p => p.trend);\n const increasingCount = trends.filter(t => t === 'increasing').length;\n const decreasingCount = trends.filter(t => t === 'decreasing').length;\n \n let trend: 'increasing' | 'stable' | 'decreasing' = 'stable';\n if (increasingCount > decreasingCount) {\n trend = 'increasing';\n } else if (decreasingCount > increasingCount) {\n trend = 'decreasing';\n }\n \n // Calculate confidence\n const confidence = Math.min(0.9, 0.4 + (issues.length * 0.001));\n \n return {\n overallRisk: Math.round(overallRisk),\n trend,\n hotspots,\n lowRiskAreas,\n predictions: hotspots,\n confidence,\n };\n \n } catch (error) {\n console.error('Failed to get project risk summary:', error);\n return {\n overallRisk: 0,\n trend: 'stable',\n hotspots: [],\n lowRiskAreas: [],\n predictions: [],\n confidence: 0.1,\n };\n }\n }\n \n /**\n * Create risk prediction insight\n */\n async generateRiskInsight(): Promise<Insight | null> {\n if (!this.insightStore.canCreateInsight('risk-prediction')) {\n return null;\n }\n \n const summary = await this.getProjectRiskSummary();\n \n // Only generate insight if there's meaningful risk\n if (summary.hotspots.length === 0 || summary.overallRisk < 30) {\n return null;\n }\n \n const topHotspot = summary.hotspots[0];\n if (!topHotspot) return null;\n \n // Convert trend format for insight display\n const trendMap: Record<'increasing' | 'stable' | 'decreasing', 'worsening' | 'stable' | 'improving'> = {\n 'increasing': 'worsening',\n 'stable': 'stable',\n 'decreasing': 'improving',\n };\n \n const insight: Insight = {\n id: `insight-risk-${Date.now()}`,\n type: 'warning',\n message: `[!] ${basename(topHotspot.target)}/ has elevated risk (${topHotspot.currentRisk}/100)`,\n context: `${topHotspot.incidentCount} past incidents. ${topHotspot.recommendations[0]}`,\n suggestedAction: 'Request extra review before merging changes to this area',\n relatedIssues: [],\n priority: Math.min(9, 5 + Math.floor(topHotspot.currentRisk / 20)),\n timestamp: Date.now(),\n dismissed: false,\n category: 'security',\n details: {\n affectedFiles: summary.hotspots.map(h => basename(h.target)),\n trend: trendMap[summary.trend],\n examples: topHotspot.recommendations,\n },\n };\n \n await this.insightStore.addInsight(insight);\n await this.insightStore.markInsightCreated('risk-prediction');\n \n return insight;\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst riskPredictors: Map<string, RiskPredictor> = new Map();\n\n/**\n * Get the RiskPredictor for a project (singleton per project)\n */\nexport function getRiskPredictor(projectPath: string): RiskPredictor {\n let predictor = riskPredictors.get(projectPath);\n if (!predictor) {\n predictor = new RiskPredictor(projectPath);\n riskPredictors.set(projectPath, predictor);\n }\n return predictor;\n}\n\n/**\n * Clear all RiskPredictor instances (for testing)\n */\nexport function clearRiskPredictors(): void {\n riskPredictors.clear();\n}\n","/**\n * Auto-Escalation System - Autonomous issue escalation\n * \n * Features:\n * - Auto-escalate critical security issues\n * - Respect quiet hours and cooldowns\n * - Multi-channel support (Slack, email, webhook)\n * - Escalation tracking and history\n * - Fallback to draft mode during quiet hours\n */\n\nimport type { Issue } from '../types/index.js';\nimport type { Insight } from './insight-store.js';\nimport { getInsightStore } from './insight-store.js';\nimport { getProjectState } from './project-state.js';\nimport { SlackIntegration } from '../integrations/slack.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Escalation target configuration\n */\nexport interface EscalationTarget {\n type: 'slack' | 'email' | 'webhook';\n config: {\n webhookUrl?: string;\n email?: string;\n channel?: string;\n username?: string;\n };\n enabled: boolean;\n forSeverities: ('critical' | 'serious' | 'moderate')[];\n forCategories: ('security' | 'quality' | 'performance' | 'all')[];\n}\n\n/**\n * Escalation message\n */\nexport interface EscalationMessage {\n id: string;\n severity: 'critical' | 'serious' | 'moderate';\n title: string;\n body: string;\n issues: Issue[];\n timestamp: number;\n sent: boolean;\n sentAt?: number;\n channel?: string;\n error?: string;\n}\n\n/**\n * Escalation result\n */\nexport interface EscalationResult {\n action: 'auto_escalated' | 'draft_only' | 'blocked' | 'failed' | 'no_action';\n reason: string;\n message?: EscalationMessage;\n draftLocation?: string;\n}\n\n/**\n * Escalation configuration\n */\nexport interface EscalationConfig {\n enabled: boolean;\n targets: EscalationTarget[];\n cooldownMinutes: number;\n maxEscalationsPerHour: number;\n respectQuietHours: boolean;\n criticalBypassQuietHours: boolean;\n draftFallbackEnabled: boolean;\n}\n\nconst DEFAULT_CONFIG: EscalationConfig = {\n enabled: true,\n targets: [],\n cooldownMinutes: 15,\n maxEscalationsPerHour: 5,\n respectQuietHours: true,\n criticalBypassQuietHours: true,\n draftFallbackEnabled: true,\n};\n\n// ============================================================================\n// EscalationManager Class\n// ============================================================================\n\n/**\n * Manages autonomous escalation of critical issues\n */\nexport class EscalationManager {\n private projectPath: string;\n private config: EscalationConfig;\n private projectState;\n private insightStore;\n private escalationHistory: EscalationMessage[] = [];\n private slackClient?: SlackIntegration;\n \n constructor(projectPath: string, config: Partial<EscalationConfig> = {}) {\n this.projectPath = projectPath;\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.projectState = getProjectState(projectPath);\n this.insightStore = getInsightStore(projectPath);\n \n // Initialize Slack client if configured\n const slackTarget = this.config.targets.find(t => t.type === 'slack' && t.enabled);\n if (slackTarget?.config.webhookUrl) {\n this.slackClient = new SlackIntegration({\n webhookUrl: slackTarget.config.webhookUrl,\n channel: slackTarget.config.channel,\n username: slackTarget.config.username,\n });\n }\n }\n \n /**\n * Check if an issue should be auto-escalated\n */\n shouldAutoEscalate(issue: Issue): boolean {\n // Must be enabled\n if (!this.config.enabled) {\n return false;\n }\n \n // Must be critical severity\n if (issue.severity !== 'critical') {\n return false;\n }\n \n // Check category (security issues get priority)\n const isSecurityIssue = \n issue.category === 'security' ||\n issue.agent === 'security' ||\n issue.issue.toLowerCase().includes('security') ||\n issue.issue.toLowerCase().includes('vulnerability') ||\n issue.issue.toLowerCase().includes('injection') ||\n issue.issue.toLowerCase().includes('xss') ||\n issue.issue.toLowerCase().includes('secret');\n \n if (!isSecurityIssue) {\n return false;\n }\n \n // Check quiet hours (unless critical bypasses)\n if (this.projectState.isQuietHours()) {\n if (!this.config.criticalBypassQuietHours) {\n return false;\n }\n }\n \n // Check cooldown\n if (!this.insightStore.canCreateInsight('auto-escalation')) {\n return false;\n }\n \n // Check hourly limit\n const recentEscalations = this.escalationHistory.filter(e => \n e.timestamp > Date.now() - (60 * 60 * 1000)\n );\n if (recentEscalations.length >= this.config.maxEscalationsPerHour) {\n return false;\n }\n \n // Check if recently escalated same file\n const recentlyEscalated = this.escalationHistory.some(e =>\n e.issues.some(i => i.file === issue.file) &&\n e.timestamp > Date.now() - (this.config.cooldownMinutes * 60 * 1000)\n );\n if (recentlyEscalated) {\n return false;\n }\n \n // Must have a valid target\n return this.hasValidEscalationTarget('critical', 'security');\n }\n \n /**\n * Check if we have a valid escalation target\n */\n private hasValidEscalationTarget(severity: string, category: string): boolean {\n return this.config.targets.some(t => \n t.enabled &&\n t.forSeverities.includes(severity as any) &&\n (t.forCategories.includes(category as any) || t.forCategories.includes('all'))\n );\n }\n \n /**\n * Auto-escalate if issue is critical\n */\n async autoEscalateIfCritical(issue: Issue): Promise<EscalationResult> {\n // Check if should escalate\n if (!this.shouldAutoEscalate(issue)) {\n // Check if we should create a draft instead\n if (issue.severity === 'critical' && this.config.draftFallbackEnabled) {\n if (this.projectState.isQuietHours()) {\n return this.createDraftEscalation([issue], 'Blocked by quiet hours');\n }\n }\n \n return {\n action: 'no_action',\n reason: 'Issue does not meet escalation criteria',\n };\n }\n \n // Create escalation message\n const message = this.createEscalationMessage([issue]);\n \n // Try to send\n try {\n await this.sendEscalation(message);\n \n // Record escalation\n this.escalationHistory.push(message);\n await this.insightStore.markInsightCreated('auto-escalation');\n \n // Create insight about escalation\n await this.createEscalationInsight(message);\n \n // Use risk budget\n await this.projectState.useRiskBudget(1);\n \n return {\n action: 'auto_escalated',\n reason: 'Critical security issue auto-escalated',\n message,\n };\n \n } catch (error) {\n console.error('Failed to send escalation:', error);\n \n // Fallback to draft\n if (this.config.draftFallbackEnabled) {\n return this.createDraftEscalation([issue], String(error));\n }\n \n return {\n action: 'failed',\n reason: `Send failed: ${error}`,\n message,\n };\n }\n }\n \n /**\n * Escalate multiple issues at once\n */\n async escalateIssues(issues: Issue[]): Promise<EscalationResult> {\n // Filter to only critical security issues\n const criticalSecurityIssues = issues.filter(i => \n i.severity === 'critical' &&\n (i.category === 'security' || i.agent === 'security')\n );\n \n if (criticalSecurityIssues.length === 0) {\n return {\n action: 'no_action',\n reason: 'No critical security issues to escalate',\n };\n }\n \n // Check quiet hours\n if (this.projectState.isQuietHours() && !this.config.criticalBypassQuietHours) {\n return this.createDraftEscalation(criticalSecurityIssues, 'Blocked by quiet hours');\n }\n \n // Create and send message\n const message = this.createEscalationMessage(criticalSecurityIssues);\n \n try {\n await this.sendEscalation(message);\n \n this.escalationHistory.push(message);\n await this.insightStore.markInsightCreated('auto-escalation');\n await this.createEscalationInsight(message);\n \n return {\n action: 'auto_escalated',\n reason: `Escalated ${criticalSecurityIssues.length} critical security issues`,\n message,\n };\n \n } catch (error) {\n if (this.config.draftFallbackEnabled) {\n return this.createDraftEscalation(criticalSecurityIssues, String(error));\n }\n \n return {\n action: 'failed',\n reason: `Send failed: ${error}`,\n message,\n };\n }\n }\n \n /**\n * Create an escalation message\n */\n private createEscalationMessage(issues: Issue[]): EscalationMessage {\n const severity = issues.some(i => i.severity === 'critical') ? 'critical' : 'serious';\n \n return {\n id: `esc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n severity,\n title: `${severity.toUpperCase()} Security Alert: ${issues.length} issue${issues.length > 1 ? 's' : ''} detected`,\n body: this.formatEscalationBody(issues),\n issues,\n timestamp: Date.now(),\n sent: false,\n };\n }\n \n /**\n * Format escalation body text\n */\n private formatEscalationBody(issues: Issue[]): string {\n const lines: string[] = [\n `**Critical Security Issues Detected**`,\n ``,\n `**Project:** ${this.projectPath.split('/').pop()}`,\n `**Issues:** ${issues.length}`,\n `**Detected:** ${new Date().toISOString()}`,\n ``,\n `**Summary:**`,\n ];\n \n for (const issue of issues.slice(0, 5)) {\n lines.push(`- \\`${issue.file}:${issue.line || '?'}\\`: ${issue.issue.slice(0, 100)}`);\n }\n \n if (issues.length > 5) {\n lines.push(`- ... and ${issues.length - 5} more`);\n }\n \n lines.push('');\n lines.push('**Action Required:** Review and address these issues immediately.');\n \n return lines.join('\\n');\n }\n \n /**\n * Send escalation through configured channels\n */\n private async sendEscalation(message: EscalationMessage): Promise<void> {\n const enabledTargets = this.config.targets.filter(t => t.enabled);\n \n if (enabledTargets.length === 0) {\n throw new Error('No enabled escalation targets configured');\n }\n \n const errors: string[] = [];\n \n for (const target of enabledTargets) {\n try {\n switch (target.type) {\n case 'slack':\n await this.sendToSlack(message, target);\n break;\n case 'email':\n await this.sendToEmail(message, target);\n break;\n case 'webhook':\n await this.sendToWebhook(message, target);\n break;\n }\n message.sent = true;\n message.sentAt = Date.now();\n message.channel = target.type;\n } catch (error) {\n errors.push(`${target.type}: ${error}`);\n }\n }\n \n if (errors.length === enabledTargets.length) {\n // All failed\n throw new Error(`All escalation channels failed: ${errors.join('; ')}`);\n }\n }\n \n /**\n * Send to Slack\n */\n private async sendToSlack(message: EscalationMessage, target: EscalationTarget): Promise<void> {\n if (!target.config.webhookUrl) {\n throw new Error('Slack webhook URL not configured');\n }\n \n // Use existing SlackIntegration if available\n if (this.slackClient) {\n await this.slackClient.sendCriticalAlert(message.issues, this.projectPath.split('/').pop() || 'Unknown');\n } else {\n // Direct webhook call\n const slack = new SlackIntegration({\n webhookUrl: target.config.webhookUrl,\n channel: target.config.channel,\n username: target.config.username || 'Trie Agent',\n });\n \n await slack.sendCriticalAlert(message.issues, this.projectPath.split('/').pop() || 'Unknown');\n }\n }\n \n /**\n * Send to email (placeholder - would need email provider integration)\n */\n private async sendToEmail(message: EscalationMessage, target: EscalationTarget): Promise<void> {\n if (!target.config.email) {\n throw new Error('Email address not configured');\n }\n \n // In a real implementation, this would use an email provider (SendGrid, SES, etc.)\n // For now, we'll log and simulate success\n console.log(`[EMAIL ESCALATION] To: ${target.config.email}`);\n console.log(`Subject: ${message.title}`);\n console.log(`Body: ${message.body}`);\n \n // Note: In production, replace with actual email sending:\n // await sendEmail({\n // to: target.config.email,\n // subject: message.title,\n // body: message.body,\n // });\n }\n \n /**\n * Send to webhook\n */\n private async sendToWebhook(message: EscalationMessage, target: EscalationTarget): Promise<void> {\n if (!target.config.webhookUrl) {\n throw new Error('Webhook URL not configured');\n }\n \n const response = await fetch(target.config.webhookUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n id: message.id,\n severity: message.severity,\n title: message.title,\n body: message.body,\n issues: message.issues.map(i => ({\n file: i.file,\n line: i.line,\n severity: i.severity,\n issue: i.issue,\n agent: i.agent,\n })),\n timestamp: message.timestamp,\n project: this.projectPath,\n }),\n });\n \n if (!response.ok) {\n throw new Error(`Webhook returned ${response.status}: ${response.statusText}`);\n }\n }\n \n /**\n * Create a draft escalation (when sending is blocked)\n */\n private createDraftEscalation(issues: Issue[], reason: string): EscalationResult {\n const message = this.createEscalationMessage(issues);\n message.error = reason;\n \n // Store as draft\n this.escalationHistory.push(message);\n \n return {\n action: 'draft_only',\n reason,\n message,\n draftLocation: `.trie/drafts/escalation-${message.id}.json`,\n };\n }\n \n /**\n * Create insight about escalation\n */\n private async createEscalationInsight(message: EscalationMessage): Promise<void> {\n const insight: Insight = {\n id: `insight-esc-${message.id}`,\n type: 'warning',\n message: `Auto-escalated: ${message.issues.length} critical security issue${message.issues.length > 1 ? 's' : ''}`,\n context: `Sent to ${message.channel}. Issues in: ${[...new Set(message.issues.map(i => i.file))].slice(0, 3).join(', ')}`,\n relatedIssues: message.issues.map(i => i.id),\n priority: 10,\n timestamp: Date.now(),\n dismissed: false,\n category: 'security',\n details: {\n affectedFiles: [...new Set(message.issues.map(i => i.file))],\n },\n };\n \n await this.insightStore.addInsight(insight);\n }\n \n /**\n * Get escalation history\n */\n getEscalationHistory(): EscalationMessage[] {\n return [...this.escalationHistory];\n }\n \n /**\n * Get pending draft escalations\n */\n getPendingDrafts(): EscalationMessage[] {\n return this.escalationHistory.filter(e => !e.sent);\n }\n \n /**\n * Retry a failed/draft escalation\n */\n async retryEscalation(messageId: string): Promise<EscalationResult> {\n const message = this.escalationHistory.find(e => e.id === messageId);\n if (!message) {\n return {\n action: 'failed',\n reason: 'Escalation message not found',\n };\n }\n \n try {\n await this.sendEscalation(message);\n \n return {\n action: 'auto_escalated',\n reason: 'Retry successful',\n message,\n };\n } catch (error) {\n return {\n action: 'failed',\n reason: `Retry failed: ${error}`,\n message,\n };\n }\n }\n \n /**\n * Configure escalation targets\n */\n addEscalationTarget(target: EscalationTarget): void {\n this.config.targets.push(target);\n \n // Re-initialize Slack client if needed\n if (target.type === 'slack' && target.enabled && target.config.webhookUrl) {\n this.slackClient = new SlackIntegration({\n webhookUrl: target.config.webhookUrl,\n channel: target.config.channel,\n username: target.config.username,\n });\n }\n }\n \n /**\n * Get current configuration\n */\n getConfig(): EscalationConfig {\n return { ...this.config };\n }\n \n /**\n * Update configuration\n */\n setConfig(config: Partial<EscalationConfig>): void {\n this.config = { ...this.config, ...config };\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst escalationManagers: Map<string, EscalationManager> = new Map();\n\n/**\n * Get the EscalationManager for a project (singleton per project)\n */\nexport function getEscalationManager(projectPath: string): EscalationManager {\n let manager = escalationManagers.get(projectPath);\n if (!manager) {\n manager = new EscalationManager(projectPath);\n escalationManagers.set(projectPath, manager);\n }\n return manager;\n}\n\n/**\n * Clear all EscalationManager instances (for testing)\n */\nexport function clearEscalationManagers(): void {\n escalationManagers.clear();\n}\n","/**\n * Meta-Learning System - Self-improving agent behavior\n * \n * Features:\n * - Track user feedback on insights\n * - Adjust insight weights based on feedback\n * - Calculate agent effectiveness metrics\n * - Learn which insights are most valuable\n * - Improve prediction accuracy over time\n */\n\nimport type { Insight } from './insight-store.js';\nimport { getInsightStore } from './insight-store.js';\nimport { getProjectState, type AgentMetrics } from './project-state.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Feedback types from users\n */\nexport type FeedbackType = 'helpful' | 'dismissed' | 'acted' | 'ignored';\n\n/**\n * Insight feedback record\n */\nexport interface InsightFeedback {\n insightId: string;\n insightType: Insight['type'];\n insightCategory: Insight['category'];\n feedback: FeedbackType;\n timestamp: number;\n latencyMs?: number; // Time from insight shown to feedback\n}\n\n/**\n * Category effectiveness stats\n */\nexport interface CategoryEffectiveness {\n category: string;\n totalInsights: number;\n helpfulCount: number;\n dismissedCount: number;\n actedCount: number;\n effectivenessScore: number; // 0-1\n}\n\n/**\n * Learning weights for insight generation\n */\nexport interface InsightWeights {\n security: number;\n quality: number;\n performance: number;\n pattern: number;\n progress: number;\n general: number;\n}\n\n/**\n * Agent effectiveness report\n */\nexport interface EffectivenessReport {\n overallScore: number;\n predictiveAccuracy: number;\n userSatisfaction: number;\n falsePositiveRate: number;\n categoryBreakdown: CategoryEffectiveness[];\n recommendations: string[];\n trends: {\n period: string;\n direction: 'improving' | 'stable' | 'declining';\n };\n}\n\n// ============================================================================\n// MetaLearner Class\n// ============================================================================\n\n/**\n * Meta-learning engine for agent self-improvement\n */\nexport class MetaLearner {\n private projectState;\n private insightStore;\n private feedbackHistory: InsightFeedback[] = [];\n private weights: InsightWeights;\n \n constructor(projectPath: string) {\n this.projectState = getProjectState(projectPath);\n this.insightStore = getInsightStore(projectPath);\n \n // Initialize with default weights\n this.weights = {\n security: 1.0,\n quality: 1.0,\n performance: 1.0,\n pattern: 1.0,\n progress: 1.0,\n general: 1.0,\n };\n }\n \n /**\n * Record user feedback on an insight\n */\n async recordFeedback(\n feedback: FeedbackType,\n context: {\n insightId: string;\n latencyMs?: number;\n }\n ): Promise<void> {\n await this.insightStore.load();\n const insight = this.insightStore.getInsight(context.insightId);\n \n if (!insight) {\n console.error(`Insight not found: ${context.insightId}`);\n return;\n }\n \n // Record feedback\n const record: InsightFeedback = {\n insightId: context.insightId,\n insightType: insight.type,\n insightCategory: insight.category,\n feedback,\n timestamp: Date.now(),\n };\n \n if (context.latencyMs !== undefined) {\n record.latencyMs = context.latencyMs;\n }\n \n this.feedbackHistory.push(record);\n \n // Update project state metrics\n await this.projectState.recordInsightFeedback(\n feedback === 'dismissed' ? 'dismissed' : \n feedback === 'acted' ? 'acted' : 'helpful'\n );\n \n // Adjust weights based on feedback\n await this.adjustWeights(record);\n }\n \n /**\n * Adjust insight weights based on feedback\n */\n private async adjustWeights(feedback: InsightFeedback): Promise<void> {\n const category = feedback.insightCategory as keyof InsightWeights;\n const currentWeight = this.weights[category];\n \n if (currentWeight === undefined) return;\n \n // Positive feedback increases weight, dismissal decreases\n let adjustment = 0;\n switch (feedback.feedback) {\n case 'acted':\n adjustment = 0.05; // Strong positive signal\n break;\n case 'helpful':\n adjustment = 0.02; // Moderate positive\n break;\n case 'dismissed':\n adjustment = -0.03; // Negative signal\n break;\n case 'ignored':\n adjustment = -0.01; // Weak negative\n break;\n }\n \n // Apply adjustment with bounds\n this.weights[category] = Math.max(0.3, Math.min(1.5, currentWeight + adjustment));\n }\n \n /**\n * Get current insight weights\n */\n getWeights(): InsightWeights {\n return { ...this.weights };\n }\n \n /**\n * Get weight for a category (used to adjust insight priority)\n */\n getCategoryWeight(category: Insight['category']): number {\n return this.weights[category] ?? 1.0;\n }\n \n /**\n * Calculate category effectiveness\n */\n calculateCategoryEffectiveness(): CategoryEffectiveness[] {\n const categories = ['security', 'quality', 'performance', 'pattern', 'progress', 'general'];\n const effectiveness: CategoryEffectiveness[] = [];\n \n for (const category of categories) {\n const categoryFeedback = this.feedbackHistory.filter(f => f.insightCategory === category);\n \n if (categoryFeedback.length === 0) {\n effectiveness.push({\n category,\n totalInsights: 0,\n helpfulCount: 0,\n dismissedCount: 0,\n actedCount: 0,\n effectivenessScore: 0.5, // Neutral when no data\n });\n continue;\n }\n \n const helpfulCount = categoryFeedback.filter(f => f.feedback === 'helpful' || f.feedback === 'acted').length;\n const dismissedCount = categoryFeedback.filter(f => f.feedback === 'dismissed').length;\n const actedCount = categoryFeedback.filter(f => f.feedback === 'acted').length;\n \n // Effectiveness = (helpful + 2*acted) / (total + dismissed)\n const score = (helpfulCount + actedCount) / Math.max(1, categoryFeedback.length);\n \n effectiveness.push({\n category,\n totalInsights: categoryFeedback.length,\n helpfulCount,\n dismissedCount,\n actedCount,\n effectivenessScore: score,\n });\n }\n \n return effectiveness;\n }\n \n /**\n * Get agent effectiveness metrics\n */\n getEffectiveness(): AgentMetrics {\n return this.projectState.getMetrics();\n }\n \n /**\n * Generate a comprehensive effectiveness report\n */\n async generateEffectivenessReport(): Promise<EffectivenessReport> {\n await this.projectState.load();\n const metrics = this.projectState.getMetrics();\n const categoryBreakdown = this.calculateCategoryEffectiveness();\n \n // Calculate overall score (weighted average of metrics)\n const overallScore = (\n metrics.userSatisfaction * 0.4 +\n metrics.predictiveAccuracy * 0.3 +\n (1 - metrics.falsePositiveRate) * 0.3\n );\n \n // Generate recommendations\n const recommendations = this.generateRecommendations(metrics, categoryBreakdown);\n \n // Determine trend\n const trend = this.calculateTrend();\n \n return {\n overallScore,\n predictiveAccuracy: metrics.predictiveAccuracy,\n userSatisfaction: metrics.userSatisfaction,\n falsePositiveRate: metrics.falsePositiveRate,\n categoryBreakdown,\n recommendations,\n trends: trend,\n };\n }\n \n /**\n * Generate improvement recommendations\n */\n private generateRecommendations(\n metrics: AgentMetrics,\n categoryBreakdown: CategoryEffectiveness[]\n ): string[] {\n const recommendations: string[] = [];\n \n // Check false positive rate\n if (metrics.falsePositiveRate > 0.3) {\n recommendations.push('High dismissal rate detected. Consider raising insight thresholds.');\n }\n \n // Check user satisfaction\n if (metrics.userSatisfaction < 0.5) {\n recommendations.push('User satisfaction is low. Review insight quality and relevance.');\n }\n \n // Check category effectiveness\n const weakCategories = categoryBreakdown\n .filter(c => c.totalInsights >= 5 && c.effectivenessScore < 0.4)\n .map(c => c.category);\n \n if (weakCategories.length > 0) {\n recommendations.push(\n `Low effectiveness in: ${weakCategories.join(', ')}. Consider adjusting insight generation for these categories.`\n );\n }\n \n // Check for high-performing categories\n const strongCategories = categoryBreakdown\n .filter(c => c.totalInsights >= 5 && c.effectivenessScore > 0.7)\n .map(c => c.category);\n \n if (strongCategories.length > 0) {\n recommendations.push(\n `Strong performance in: ${strongCategories.join(', ')}. Consider emphasizing these insights.`\n );\n }\n \n // Check prediction accuracy\n if (metrics.predictiveAccuracy < 0.6 && metrics.totalPredictions >= 10) {\n recommendations.push('Prediction accuracy below target. Review risk scoring factors.');\n }\n \n // Positive reinforcement if doing well\n if (metrics.userSatisfaction >= 0.7 && metrics.falsePositiveRate <= 0.2) {\n recommendations.push('Agent performance is excellent. Keep up the good work!');\n }\n \n return recommendations;\n }\n \n /**\n * Calculate trend direction\n */\n private calculateTrend(): { period: string; direction: 'improving' | 'stable' | 'declining' } {\n // Compare recent feedback to older feedback\n const now = Date.now();\n const recentCutoff = now - (7 * 24 * 60 * 60 * 1000); // 7 days\n const olderCutoff = now - (30 * 24 * 60 * 60 * 1000); // 30 days\n \n const recentFeedback = this.feedbackHistory.filter(f => f.timestamp > recentCutoff);\n const olderFeedback = this.feedbackHistory.filter(f => \n f.timestamp > olderCutoff && f.timestamp <= recentCutoff\n );\n \n if (recentFeedback.length < 5 || olderFeedback.length < 5) {\n return { period: 'last 30 days', direction: 'stable' };\n }\n \n // Calculate satisfaction rates\n const recentPositive = recentFeedback.filter(f => \n f.feedback === 'helpful' || f.feedback === 'acted'\n ).length / recentFeedback.length;\n \n const olderPositive = olderFeedback.filter(f => \n f.feedback === 'helpful' || f.feedback === 'acted'\n ).length / olderFeedback.length;\n \n const diff = recentPositive - olderPositive;\n \n if (diff > 0.1) {\n return { period: 'last 30 days', direction: 'improving' };\n } else if (diff < -0.1) {\n return { period: 'last 30 days', direction: 'declining' };\n }\n \n return { period: 'last 30 days', direction: 'stable' };\n }\n \n /**\n * Should an insight be shown based on learning?\n * \n * Uses weights and user patterns to filter low-value insights.\n */\n shouldShowInsight(insight: Insight): boolean {\n const weight = this.getCategoryWeight(insight.category);\n \n // If weight is very low, filter out low-priority insights\n if (weight < 0.5 && insight.priority < 5) {\n return false;\n }\n \n // Adjust priority threshold based on category weight\n const adjustedPriority = insight.priority * weight;\n \n // Show if adjusted priority is above threshold\n return adjustedPriority >= 3;\n }\n \n /**\n * Adjust insight priority based on learning\n */\n adjustInsightPriority(insight: Insight): number {\n const weight = this.getCategoryWeight(insight.category);\n return Math.round(insight.priority * weight);\n }\n \n /**\n * Get feedback history stats\n */\n getFeedbackStats(): {\n total: number;\n helpful: number;\n dismissed: number;\n acted: number;\n ignored: number;\n averageLatencyMs: number | null;\n } {\n const stats = {\n total: this.feedbackHistory.length,\n helpful: 0,\n dismissed: 0,\n acted: 0,\n ignored: 0,\n averageLatencyMs: null as number | null,\n };\n \n let totalLatency = 0;\n let latencyCount = 0;\n \n for (const feedback of this.feedbackHistory) {\n switch (feedback.feedback) {\n case 'helpful': stats.helpful++; break;\n case 'dismissed': stats.dismissed++; break;\n case 'acted': stats.acted++; break;\n case 'ignored': stats.ignored++; break;\n }\n \n if (feedback.latencyMs !== undefined) {\n totalLatency += feedback.latencyMs;\n latencyCount++;\n }\n }\n \n if (latencyCount > 0) {\n stats.averageLatencyMs = Math.round(totalLatency / latencyCount);\n }\n \n return stats;\n }\n \n /**\n * Reset learning (for testing)\n */\n reset(): void {\n this.feedbackHistory = [];\n this.weights = {\n security: 1.0,\n quality: 1.0,\n performance: 1.0,\n pattern: 1.0,\n progress: 1.0,\n general: 1.0,\n };\n }\n}\n\n// ============================================================================\n// Singleton Management\n// ============================================================================\n\nconst metaLearners: Map<string, MetaLearner> = new Map();\n\n/**\n * Get the MetaLearner for a project (singleton per project)\n */\nexport function getMetaLearner(projectPath: string): MetaLearner {\n let learner = metaLearners.get(projectPath);\n if (!learner) {\n learner = new MetaLearner(projectPath);\n metaLearners.set(projectPath, learner);\n }\n return learner;\n}\n\n/**\n * Clear all MetaLearner instances (for testing)\n */\nexport function clearMetaLearners(): void {\n metaLearners.clear();\n}\n"],"mappings":"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","names":["basename","issues","DEFAULT_CONFIG","basename","currentHashes","ContextGraph","getStorage"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/memory/issue-store.ts","../src/memory/bm25.ts","../src/memory/compactor.ts"],"sourcesContent":["/**\n * Issue Memory Store\n * \n * Working state cache complementary to the immutable ledger.\n * \n * Architecture:\n * - Ledger (.trie/memory/ledger.json) = immutable source of truth\n * - Issue Memory = mutable working state + BM25 search index\n * \n * Issue memory provides:\n * - Fast BM25 semantic search for pattern matching\n * - Mutable state tracking (resolved, open, fixed)\n * - Goal violation metrics and progress tracking\n * - Links back to ledger via ledgerBlockHash\n * \n * Phase 1 Hardening:\n * - SHA256 hashing for proper deduplication\n * - Atomic writes to prevent corruption\n * - Rotational backups for recovery\n * - Zod validation for data integrity\n */\n\nimport { mkdir, readFile, readdir } from 'fs/promises';\nimport { createHash } from 'crypto';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\nimport type { Issue } from '../types/index.js';\nimport { BM25Index } from './bm25.js';\nimport { compactOldIssues, saveCompactedSummary, getHistoricalInsights } from './compactor.js';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { withFileLock } from '../utils/file-lock.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { IssueIndexSchema, safeParseAndValidate } from './validation.js';\nimport { appendIssuesToLedger } from './ledger.js';\n\nexport interface StoredIssue {\n id: string;\n hash: string;\n severity: string;\n issue: string;\n fix: string;\n file: string;\n line: number | undefined;\n agent: string;\n category: string | undefined;\n timestamp: string;\n project: string;\n resolved: boolean | undefined;\n resolvedAt: string | undefined;\n ledgerBlockHash?: string; // Link to immutable ledger record\n}\n\nexport interface IssueSearchResult {\n issue: StoredIssue;\n score: number;\n matchType: 'bm25' | 'keyword' | 'fts5';\n}\n\nexport interface IssueMemoryStats {\n totalIssues: number;\n activeIssues: number; // Unresolved issues\n issuesByAgent: Record<string, number>;\n issuesBySeverity: Record<string, number>; // All issues (historical)\n activeIssuesBySeverity: Record<string, number>; // Only unresolved\n oldestIssue: string | undefined;\n newestIssue: string | undefined;\n resolvedCount: number;\n historicalIssues: number;\n improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown';\n capacityInfo: {\n current: number;\n max: number;\n percentFull: number;\n isAtCap: boolean;\n };\n deduplicationStats: {\n duplicatesAvoided: number;\n uniquePatterns: number;\n };\n}\n\n/**\n * Store issues and link them to the ledger\n * \n * Flow:\n * 1. Append to ledger (immutable source of truth)\n * 2. Cache in issue memory with ledger reference\n * \n * Returns number of unique issues added (after deduplication)\n */\nexport async function storeIssues(\n issues: Issue[],\n project: string,\n workDir?: string\n): Promise<{ stored: number; duplicates: number }> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const stored: StoredIssue[] = [];\n const now = new Date().toISOString();\n const seenHashes = new Set<string>();\n let duplicates = 0;\n \n for (const issue of issues) {\n const hash = hashIssue(issue);\n \n // Skip duplicates within the same scan\n if (seenHashes.has(hash)) {\n duplicates++;\n continue;\n }\n seenHashes.add(hash);\n \n const storedIssue: StoredIssue = {\n id: issue.id,\n hash,\n severity: issue.severity,\n issue: issue.issue,\n fix: issue.fix,\n file: issue.file,\n line: issue.line,\n agent: issue.agent,\n category: issue.category,\n timestamp: now,\n project,\n resolved: false,\n resolvedAt: undefined,\n ...(issue.ledgerBlockHash && { ledgerBlockHash: issue.ledgerBlockHash }),\n };\n stored.push(storedIssue);\n }\n\n // 1. Write to ledger (immutable source of truth)\n const ledgerBlock = await appendIssuesToLedger(stored, projectDir);\n \n // 2. Link issues to their ledger block\n if (ledgerBlock) {\n for (const issue of stored) {\n issue.ledgerBlockHash = ledgerBlock.blockHash;\n }\n }\n \n // 3. Cache in issue memory (working state + search index)\n const dedupedCount = await updateIssueIndex(stored, projectDir);\n \n return { stored: dedupedCount, duplicates: duplicates + (stored.length - dedupedCount) };\n}\n\n/**\n * Search issues using BM25 ranking (same algorithm as Elasticsearch)\n */\nexport async function searchIssues(\n query: string,\n options: {\n workDir?: string;\n limit?: number;\n project?: string;\n severity?: string[];\n agent?: string;\n includeResolved?: boolean;\n } = {}\n): Promise<IssueSearchResult[]> {\n const projectDir = options.workDir || getWorkingDirectory(undefined, true);\n const limit = options.limit || 10;\n const allIssues = await loadIssueIndex(projectDir);\n \n if (allIssues.length === 0) {\n return [];\n }\n\n // Filter issues first\n const filteredIssues = allIssues.filter(issue => {\n if (options.project && issue.project !== options.project) return false;\n if (options.severity && !options.severity.includes(issue.severity)) return false;\n if (options.agent && issue.agent !== options.agent) return false;\n if (!options.includeResolved && issue.resolved) return false;\n return true;\n });\n\n if (filteredIssues.length === 0) {\n return [];\n }\n\n // Build BM25 index\n const bm25 = new BM25Index();\n const issueMap = new Map<string, StoredIssue>();\n \n for (const issue of filteredIssues) {\n const searchText = `${issue.issue} ${issue.fix} ${issue.file} ${issue.agent} ${issue.category || ''} ${issue.severity}`;\n bm25.addDocument({\n id: issue.id,\n text: searchText,\n });\n issueMap.set(issue.id, issue);\n }\n\n // Search with BM25\n const bm25Results = bm25.search(query, limit);\n \n return bm25Results.map(result => ({\n issue: issueMap.get(result.id)!,\n score: result.score,\n matchType: 'bm25' as const,\n }));\n}\n\n/**\n * Find similar issues using BM25 similarity\n */\nexport async function findSimilarIssues(\n issue: Issue,\n options: {\n workDir?: string;\n limit?: number;\n excludeSameFile?: boolean;\n } = {}\n): Promise<IssueSearchResult[]> {\n // Use the issue description and fix as the query for similarity\n const query = `${issue.issue} ${issue.fix} ${issue.agent}`;\n const searchOptions: Parameters<typeof searchIssues>[1] = {\n limit: (options.limit || 5) + 5, // Get extra to account for filtering\n includeResolved: true,\n };\n if (options.workDir !== undefined) {\n searchOptions.workDir = options.workDir;\n }\n const results = await searchIssues(query, searchOptions);\n\n let filtered = results.filter(r => r.issue.id !== issue.id);\n \n if (options.excludeSameFile) {\n filtered = filtered.filter(r => r.issue.file !== issue.file);\n }\n \n return filtered.slice(0, options.limit || 5);\n}\n\n/**\n * Mark an issue as resolved\n */\nexport async function markIssueResolved(\n issueId: string,\n workDir?: string\n): Promise<boolean> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n const indexPath = join(memoryDir, 'issues.json');\n \n // Use file locking to prevent concurrent write conflicts\n return withFileLock(indexPath, async () => {\n const index = await loadIssueIndex(projectDir);\n \n const issue = index.find(i => i.id === issueId);\n if (!issue) return false;\n \n issue.resolved = true;\n issue.resolvedAt = new Date().toISOString();\n \n await saveIssueIndexInternal(index, projectDir);\n return true;\n }, { timeout: 10000 });\n}\n\n/**\n * Auto-resolve issues that were not found in the latest scan\n * \n * After a scan completes, this function compares new issues against stored issues.\n * Issues that were previously found in scanned files but are no longer detected\n * are automatically marked as resolved.\n * \n * @param newIssueHashes - Set of hashes from the current scan\n * @param scannedFiles - List of files that were scanned (to scope resolution)\n * @param workDir - Working directory\n * @returns Number of issues auto-resolved\n */\nexport async function autoResolveIssues(\n newIssueHashes: Set<string>,\n scannedFiles: string[],\n workDir?: string\n): Promise<{ resolved: number; stillActive: number }> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n const indexPath = join(memoryDir, 'issues.json');\n \n // Use file locking to prevent concurrent write conflicts\n return withFileLock(indexPath, async () => {\n const index = await loadIssueIndex(projectDir);\n \n // Normalize scanned file paths for comparison\n const scannedFileSet = new Set(scannedFiles.map(f => f.replace(/\\\\/g, '/')));\n \n const now = new Date().toISOString();\n let resolvedCount = 0;\n let stillActiveCount = 0;\n \n for (const issue of index) {\n // Skip already resolved issues\n if (issue.resolved) continue;\n \n // Normalize the issue file path\n const normalizedFile = issue.file.replace(/\\\\/g, '/');\n \n // Only auto-resolve issues in files that were scanned\n // This prevents marking issues as resolved if we just did a partial scan\n if (!scannedFileSet.has(normalizedFile)) {\n stillActiveCount++;\n continue;\n }\n \n // If the issue's hash is NOT in the new scan results, it's been fixed\n if (!newIssueHashes.has(issue.hash)) {\n issue.resolved = true;\n issue.resolvedAt = now;\n resolvedCount++;\n } else {\n stillActiveCount++;\n }\n }\n \n // Only save if we resolved something\n if (resolvedCount > 0) {\n await saveIssueIndexInternal(index, projectDir);\n }\n \n return { resolved: resolvedCount, stillActive: stillActiveCount };\n }, { timeout: 15000 });\n}\n\n/**\n * Resolve goal violation issues for a specific file and goal\n * Called when a goal violation is fixed\n */\nexport async function resolveGoalViolation(\n file: string,\n goalDescription: string,\n workDir?: string\n): Promise<number> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n const indexPath = join(memoryDir, 'issues.json');\n \n // Use file locking to prevent concurrent write conflicts\n let resolvedCount = await withFileLock(indexPath, async () => {\n const index = await loadIssueIndex(projectDir);\n \n const now = new Date().toISOString();\n let count = 0;\n \n for (const issue of index) {\n if (issue.resolved) continue;\n if (issue.agent !== 'goal-violation') continue;\n \n // Match file and goal description\n const normalizedFile = issue.file.replace(/\\\\/g, '/');\n const normalizedTarget = file.replace(/\\\\/g, '/');\n \n if (normalizedFile === normalizedTarget && \n issue.issue.includes(`Goal \"${goalDescription}\"`)) {\n issue.resolved = true;\n issue.resolvedAt = now;\n count++;\n }\n }\n \n if (count > 0) {\n await saveIssueIndexInternal(index, projectDir);\n }\n \n return count;\n }, { timeout: 10000 });\n \n // Always try to resolve nudges in SQL storage, even if issue-store had nothing\n // This handles cases where nudges exist in SQL but not in the issue index\n try {\n const { getStorage } = await import('../storage/tiered-storage.js');\n const storage = getStorage(projectDir);\n await storage.initialize();\n const nudgeResolved = await storage.resolveNudgesForGoalViolation(file, goalDescription, workDir);\n if (nudgeResolved > 0) {\n console.debug(`[IssueStore] Auto-resolved ${nudgeResolved} nudge(s) for fixed goal violation`);\n resolvedCount += nudgeResolved;\n }\n } catch (e) {\n console.debug('[IssueStore] Nudge resolution failed (non-fatal):', e);\n }\n \n return resolvedCount;\n}\n\n/**\n * Get hash for an issue (for external callers)\n */\nexport function getIssueHash(issue: Issue): string {\n return hashIssue(issue);\n}\n\n/**\n * Get memory statistics including historical insights\n */\nexport async function getMemoryStats(workDir?: string): Promise<IssueMemoryStats> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const index = await loadIssueIndex(projectDir);\n const historical = await getHistoricalInsights(projectDir);\n \n const MAX_ISSUES = 10000;\n const uniqueHashes = new Set(index.map(i => i.hash));\n \n const stats: IssueMemoryStats = {\n totalIssues: index.length,\n activeIssues: 0,\n issuesByAgent: {},\n issuesBySeverity: {},\n activeIssuesBySeverity: {},\n oldestIssue: undefined,\n newestIssue: undefined,\n resolvedCount: 0,\n historicalIssues: historical.totalHistoricalIssues,\n improvementTrend: historical.improvementTrend,\n capacityInfo: {\n current: index.length,\n max: MAX_ISSUES,\n percentFull: Math.round((index.length / MAX_ISSUES) * 100),\n isAtCap: index.length >= MAX_ISSUES,\n },\n deduplicationStats: {\n duplicatesAvoided: index.length - uniqueHashes.size,\n uniquePatterns: uniqueHashes.size,\n },\n };\n\n for (const issue of index) {\n stats.issuesByAgent[issue.agent] = (stats.issuesByAgent[issue.agent] || 0) + 1;\n stats.issuesBySeverity[issue.severity] = (stats.issuesBySeverity[issue.severity] || 0) + 1;\n \n if (issue.resolved) {\n stats.resolvedCount++;\n } else {\n stats.activeIssues++;\n stats.activeIssuesBySeverity[issue.severity] = (stats.activeIssuesBySeverity[issue.severity] || 0) + 1;\n }\n }\n\n if (index.length > 0) {\n const sorted = [...index].sort((a, b) => \n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n const oldest = sorted[0]?.timestamp;\n const newest = sorted[sorted.length - 1]?.timestamp;\n if (oldest !== undefined) {\n stats.oldestIssue = oldest;\n }\n if (newest !== undefined) {\n stats.newestIssue = newest;\n }\n }\n\n return stats;\n}\n\n/**\n * Get recent issues\n * @param options.includeResolved - If false (default), only returns unresolved issues\n */\nexport async function getRecentIssues(\n options: {\n workDir?: string;\n limit?: number;\n daysBack?: number;\n includeResolved?: boolean;\n } = {}\n): Promise<StoredIssue[]> {\n const projectDir = options.workDir || getWorkingDirectory(undefined, true);\n const index = await loadIssueIndex(projectDir);\n const limit = options.limit || 20;\n const daysBack = options.daysBack || 7;\n const includeResolved = options.includeResolved ?? false;\n \n const cutoff = new Date();\n cutoff.setDate(cutoff.getDate() - daysBack);\n \n return index\n .filter(i => {\n if (new Date(i.timestamp) < cutoff) return false;\n if (!includeResolved && i.resolved) return false;\n return true;\n })\n .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())\n .slice(0, limit);\n}\n\n/**\n * Purge issues from memory\n * Offers different strategies for managing memory capacity\n */\nexport async function purgeIssues(\n strategy: 'smart' | 'resolved' | 'old' | 'all',\n options: {\n workDir?: string;\n daysOld?: number;\n } = {}\n): Promise<{ removed: number; remaining: number; strategy: string }> {\n const projectDir = options.workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n const indexPath = join(memoryDir, 'issues.json');\n \n // Use file locking to prevent concurrent write conflicts\n return withFileLock(indexPath, async () => {\n const index = await loadIssueIndex(projectDir);\n const originalCount = index.length;\n \n let remaining: StoredIssue[] = [];\n \n switch (strategy) {\n case 'smart':\n // Keep: critical/high severity, recent (< 30 days), unresolved\n const thirtyDaysAgo = new Date();\n thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);\n \n remaining = index.filter(i => {\n const isRecent = new Date(i.timestamp) >= thirtyDaysAgo;\n const isImportant = ['critical', 'high'].includes(i.severity);\n const isUnresolved = !i.resolved;\n \n return isRecent || isImportant || isUnresolved;\n });\n break;\n \n case 'resolved':\n // Remove all resolved issues\n remaining = index.filter(i => !i.resolved);\n break;\n \n case 'old':\n // Remove issues older than specified days (default 90)\n const daysOld = options.daysOld || 90;\n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - daysOld);\n \n remaining = index.filter(i => new Date(i.timestamp) >= cutoffDate);\n break;\n \n case 'all':\n // Clear all issues (keeps compacted summaries)\n remaining = [];\n break;\n }\n \n await saveIssueIndexInternal(remaining, projectDir);\n \n return {\n removed: originalCount - remaining.length,\n remaining: remaining.length,\n strategy,\n };\n }, { timeout: 10000 });\n}\n\n/**\n * Get daily log files (legacy - deprecated)\n * \n * Note: Daily logs are redundant with the ledger.\n * The ledger provides the same information with better guarantees.\n * This function is kept for backward compatibility.\n */\nexport async function getDailyLogs(workDir?: string): Promise<string[]> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n \n try {\n if (!existsSync(memoryDir)) return [];\n const files = await readdir(memoryDir);\n return files\n .filter(f => /^\\d{4}-\\d{2}-\\d{2}\\.md$/.test(f))\n .sort()\n .reverse();\n } catch {\n return [];\n }\n}\n\n// Private helpers\n\n/**\n * Get ledger entry for an issue\n * \n * Issue memory stores working state (resolved, etc.)\n * Ledger stores immutable history (what was detected, when)\n * \n * This helper links them together for full context.\n */\nexport async function getIssueLedgerEntry(\n issue: StoredIssue,\n workDir?: string\n): Promise<{ block: any; entry: any } | null> {\n if (!issue.ledgerBlockHash) return null;\n \n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const { getLedgerBlocks } = await import('./ledger.js');\n const blocks = await getLedgerBlocks(projectDir);\n \n // Find the block this issue is linked to\n const block = blocks.find(b => b.blockHash === issue.ledgerBlockHash);\n if (!block) return null;\n \n // Find the specific entry in that block\n const entry = block.entries.find((e: any) => e.hash === issue.hash);\n if (!entry) return null;\n \n return { block, entry };\n}\n\n// Private helpers\n\n/**\n * Load issue index with validation and auto-recovery\n * \n * If the file is corrupted:\n * 1. Attempts to recover from the most recent valid backup\n * 2. Returns empty array if no valid backup exists\n */\nasync function loadIssueIndex(projectDir: string): Promise<StoredIssue[]> {\n const indexPath = join(getTrieDirectory(projectDir), 'memory', 'issues.json');\n \n try {\n if (existsSync(indexPath)) {\n const content = await readFile(indexPath, 'utf-8');\n const result = safeParseAndValidate(content, IssueIndexSchema);\n \n if (result.success) {\n return result.data as StoredIssue[];\n }\n \n // Validation failed - attempt recovery from backup\n console.error(` Issue index corrupted: ${result.error}`);\n const backupManager = new BackupManager(indexPath);\n \n if (await backupManager.recoverFromBackup()) {\n console.error(' ✅ Recovered from backup');\n const recovered = await readFile(indexPath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, IssueIndexSchema);\n if (recoveredResult.success) {\n return recoveredResult.data as StoredIssue[];\n }\n }\n \n console.error(' No valid backup found, starting fresh');\n }\n } catch {\n // Index doesn't exist or recovery failed\n }\n \n return [];\n}\n\nasync function updateIssueIndex(newIssues: StoredIssue[], projectDir: string): Promise<number> {\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const indexPath = join(memoryDir, 'issues.json');\n \n // Use file locking to prevent concurrent write conflicts\n return withFileLock(indexPath, async () => {\n let existing = await loadIssueIndex(projectDir);\n \n // Intelligent deduplication: only add truly unique issues\n // Issues are unique if they have different hash (content + file + severity + agent)\n const hashSet = new Set(existing.map(i => i.hash));\n const toAdd = newIssues.filter(i => !hashSet.has(i.hash));\n const dedupedCount = toAdd.length;\n \n existing = [...existing, ...toAdd];\n \n // Intelligent compaction: summarize old issues instead of deleting\n if (existing.length > 500) {\n const { summary, remaining } = await compactOldIssues(existing, {\n keepDays: 30,\n minIssuesToCompact: 100,\n });\n \n if (summary) {\n await saveCompactedSummary(summary, projectDir);\n existing = remaining;\n }\n }\n \n // Hard cap: prune to 10,000 if still too large\n // Prioritize: 1) Recent issues, 2) High severity, 3) Unresolved\n if (existing.length > 10000) {\n existing = intelligentPrune(existing, 10000);\n }\n \n // Use internal save since lock is already held\n await saveIssueIndexInternal(existing, projectDir);\n return dedupedCount;\n }, { timeout: 15000 });\n}\n\n/**\n * Intelligently prune issues to target count\n * Prioritizes: recent, high severity, unresolved\n */\nfunction intelligentPrune(issues: StoredIssue[], targetCount: number): StoredIssue[] {\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 = issues.map(issue => {\n const ageInDays = (Date.now() - new Date(issue.timestamp).getTime()) / (1000 * 60 * 60 * 24);\n const recencyScore = Math.max(0, 100 - ageInDays * 2); // Newer = higher score\n const severityScore = severityWeight[issue.severity] || 10;\n const resolvedPenalty = issue.resolved ? -50 : 0;\n \n return {\n issue,\n score: recencyScore + severityScore + resolvedPenalty,\n };\n });\n \n return scored\n .sort((a, b) => b.score - a.score)\n .slice(0, targetCount)\n .map(s => s.issue);\n}\n\n/**\n * Save issue index with backup and atomic write\n * \n * This is the internal version that doesn't acquire locks.\n * All public functions that call this should acquire locks first.\n * \n * 1. Creates a backup of the existing file\n * 2. Writes the new data atomically (temp file + rename)\n * 3. Maintains up to 5 rotational backups\n */\nasync function saveIssueIndexInternal(issues: StoredIssue[], projectDir: string): Promise<void> {\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const indexPath = join(memoryDir, 'issues.json');\n \n // Create backup before writing\n const backupManager = new BackupManager(indexPath);\n await backupManager.createBackup();\n \n // Atomic write\n await atomicWriteJSON(indexPath, issues);\n}\n\n/**\n * Hash an issue using SHA256 for proper deduplication\n * \n * Uses cryptographic hashing to eliminate collision risk.\n * The hash is truncated to 16 characters for storage efficiency\n * while still providing effectively zero collision probability.\n */\nfunction hashIssue(issue: Issue): string {\n const content = `${issue.issue}|${issue.file}|${issue.severity}|${issue.agent}`;\n return createHash('sha256').update(content).digest('hex').slice(0, 16);\n}\n\n","/**\n * BM25 Search Implementation\n * \n * BM25 (Best Match 25) is a ranking function used by search engines.\n * It's more sophisticated than TF-IDF and handles term frequency saturation.\n * \n * This is the same algorithm used by Elasticsearch.\n */\n\nexport interface BM25Document {\n id: string;\n text: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface BM25Result {\n id: string;\n score: number;\n metadata?: Record<string, unknown>;\n}\n\nexport class BM25Index {\n private documents: Map<string, BM25Document> = new Map();\n private termFrequencies: Map<string, Map<string, number>> = new Map();\n private documentFrequencies: Map<string, number> = new Map();\n private documentLengths: Map<string, number> = new Map();\n private avgDocLength: number = 0;\n private k1: number = 1.5;\n private b: number = 0.75;\n\n /**\n * Add a document to the index\n */\n addDocument(doc: BM25Document): void {\n const tokens = this.tokenize(doc.text);\n this.documents.set(doc.id, doc);\n this.documentLengths.set(doc.id, tokens.length);\n\n const termFreq = new Map<string, number>();\n const seenTerms = new Set<string>();\n\n for (const token of tokens) {\n termFreq.set(token, (termFreq.get(token) || 0) + 1);\n \n if (!seenTerms.has(token)) {\n seenTerms.add(token);\n this.documentFrequencies.set(token, (this.documentFrequencies.get(token) || 0) + 1);\n }\n }\n\n this.termFrequencies.set(doc.id, termFreq);\n this.updateAvgDocLength();\n }\n\n /**\n * Add multiple documents\n */\n addDocuments(docs: BM25Document[]): void {\n for (const doc of docs) {\n this.addDocument(doc);\n }\n }\n\n /**\n * Search the index\n */\n search(query: string, limit: number = 10): BM25Result[] {\n const queryTokens = this.tokenize(query);\n const scores: Map<string, number> = new Map();\n const N = this.documents.size;\n\n for (const [docId] of this.documents) {\n let score = 0;\n const docLength = this.documentLengths.get(docId) || 0;\n const termFreqs = this.termFrequencies.get(docId);\n\n if (!termFreqs) continue;\n\n for (const term of queryTokens) {\n const tf = termFreqs.get(term) || 0;\n if (tf === 0) continue;\n\n const df = this.documentFrequencies.get(term) || 0;\n const idf = Math.log((N - df + 0.5) / (df + 0.5) + 1);\n\n const numerator = tf * (this.k1 + 1);\n const denominator = tf + this.k1 * (1 - this.b + this.b * (docLength / this.avgDocLength));\n \n score += idf * (numerator / denominator);\n }\n\n if (score > 0) {\n scores.set(docId, score);\n }\n }\n\n return Array.from(scores.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit)\n .map(([id, score]) => {\n const metadata = this.documents.get(id)?.metadata;\n const result: BM25Result = { id, score };\n if (metadata !== undefined) {\n result.metadata = metadata;\n }\n return result;\n });\n }\n\n /**\n * Get document count\n */\n get size(): number {\n return this.documents.size;\n }\n\n /**\n * Clear the index\n */\n clear(): void {\n this.documents.clear();\n this.termFrequencies.clear();\n this.documentFrequencies.clear();\n this.documentLengths.clear();\n this.avgDocLength = 0;\n }\n\n /**\n * Serialize the index to JSON\n */\n serialize(): string {\n return JSON.stringify({\n documents: Array.from(this.documents.entries()),\n termFrequencies: Array.from(this.termFrequencies.entries()).map(([k, v]) => [k, Array.from(v.entries())]),\n documentFrequencies: Array.from(this.documentFrequencies.entries()),\n documentLengths: Array.from(this.documentLengths.entries()),\n avgDocLength: this.avgDocLength,\n });\n }\n\n /**\n * Load from serialized JSON\n */\n static deserialize(json: string): BM25Index {\n const data = JSON.parse(json);\n const index = new BM25Index();\n \n index.documents = new Map(data.documents);\n index.termFrequencies = new Map(data.termFrequencies.map(([k, v]: [string, [string, number][]]) => [k, new Map(v)]));\n index.documentFrequencies = new Map(data.documentFrequencies);\n index.documentLengths = new Map(data.documentLengths);\n index.avgDocLength = data.avgDocLength;\n \n return index;\n }\n\n private tokenize(text: string): string[] {\n return text\n .toLowerCase()\n .replace(/[^\\w\\s]/g, ' ')\n .split(/\\s+/)\n .filter(token => token.length > 2 && !this.isStopWord(token));\n }\n\n private isStopWord(word: string): boolean {\n const stopWords = new Set([\n 'the', 'be', 'to', 'of', 'and', 'a', 'in', 'that', 'have', 'i',\n 'it', 'for', 'not', 'on', 'with', 'he', 'as', 'you', 'do', 'at',\n 'this', 'but', 'his', 'by', 'from', 'they', 'we', 'say', 'her', 'she',\n 'or', 'an', 'will', 'my', 'one', 'all', 'would', 'there', 'their', 'what',\n 'so', 'up', 'out', 'if', 'about', 'who', 'get', 'which', 'go', 'me',\n 'when', 'make', 'can', 'like', 'time', 'no', 'just', 'him', 'know', 'take',\n 'into', 'year', 'your', 'some', 'could', 'them', 'see', 'other', 'than', 'then',\n 'now', 'look', 'only', 'come', 'its', 'over', 'also', 'back', 'after', 'use',\n 'two', 'how', 'our', 'first', 'way', 'even', 'new', 'want', 'because', 'any',\n 'these', 'give', 'day', 'most', 'us', 'should', 'been', 'has', 'was', 'are',\n ]);\n return stopWords.has(word);\n }\n\n private updateAvgDocLength(): void {\n if (this.documentLengths.size === 0) {\n this.avgDocLength = 0;\n return;\n }\n const total = Array.from(this.documentLengths.values()).reduce((a, b) => a + b, 0);\n this.avgDocLength = total / this.documentLengths.size;\n }\n}\n","/**\n * Memory Compactor\n * \n * Intelligently compacts old issues into summaries instead of deleting them.\n * Preserves patterns and insights while reducing storage.\n * \n * Phase 1 Hardening:\n * - Atomic writes to prevent corruption\n * - Backup rotation for recovery\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 type { StoredIssue } from './issue-store.js';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { BackupManager } from '../utils/backup-manager.js';\nimport { CompactedSummariesIndexSchema, safeParseAndValidate } from './validation.js';\n\nexport interface CompactedSummary {\n period: string;\n startDate: string;\n endDate: string;\n totalIssues: number;\n resolvedCount: number;\n bySeverity: Record<string, number>;\n byAgent: Record<string, number>;\n topPatterns: PatternSummary[];\n hotFiles: { file: string; count: number }[];\n compactedAt: string;\n}\n\nexport interface PatternSummary {\n pattern: string;\n count: number;\n severity: string;\n agent: string;\n exampleFix: string;\n}\n\n/**\n * Compact old issues into summaries\n * Returns the compacted summary and the remaining (recent) issues\n */\nexport async function compactOldIssues(\n issues: StoredIssue[],\n options: {\n keepDays?: number;\n minIssuesToCompact?: number;\n } = {}\n): Promise<{ summary: CompactedSummary | null; remaining: StoredIssue[] }> {\n const keepDays = options.keepDays ?? 30;\n const minIssues = options.minIssuesToCompact ?? 100;\n \n const cutoffDate = new Date();\n cutoffDate.setDate(cutoffDate.getDate() - keepDays);\n \n const oldIssues = issues.filter(i => new Date(i.timestamp) < cutoffDate);\n const recentIssues = issues.filter(i => new Date(i.timestamp) >= cutoffDate);\n \n // Only compact if we have enough old issues\n if (oldIssues.length < minIssues) {\n return { summary: null, remaining: issues };\n }\n \n // Build summary\n const summary = buildSummary(oldIssues);\n \n return { summary, remaining: recentIssues };\n}\n\n/**\n * Build a summary from a set of issues\n */\nfunction buildSummary(issues: StoredIssue[]): CompactedSummary {\n const sorted = issues.sort((a, b) => \n new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()\n );\n \n const bySeverity: Record<string, number> = {};\n const byAgent: Record<string, number> = {};\n const patternMap: Map<string, { count: number; issue: StoredIssue }> = new Map();\n const fileCount: Map<string, number> = new Map();\n \n for (const issue of issues) {\n // Count by severity\n bySeverity[issue.severity] = (bySeverity[issue.severity] || 0) + 1;\n \n // Count by agent\n byAgent[issue.agent] = (byAgent[issue.agent] || 0) + 1;\n \n // Track patterns (normalized issue text)\n const patternKey = normalizePattern(issue.issue);\n const existing = patternMap.get(patternKey);\n if (existing) {\n existing.count++;\n } else {\n patternMap.set(patternKey, { count: 1, issue });\n }\n \n // Count files\n const fileName = issue.file.split('/').pop() || issue.file;\n fileCount.set(fileName, (fileCount.get(fileName) || 0) + 1);\n }\n \n // Get top patterns\n const topPatterns = Array.from(patternMap.entries())\n .sort((a, b) => b[1].count - a[1].count)\n .slice(0, 10)\n .map(([pattern, data]) => ({\n pattern: pattern.slice(0, 100),\n count: data.count,\n severity: data.issue.severity,\n agent: data.issue.agent,\n exampleFix: data.issue.fix.slice(0, 200),\n }));\n \n // Get hot files\n const hotFiles = Array.from(fileCount.entries())\n .sort((a, b) => b[1] - a[1])\n .slice(0, 10)\n .map(([file, count]) => ({ file, count }));\n \n return {\n period: `${sorted[0]?.timestamp.split('T')[0]} to ${sorted[sorted.length - 1]?.timestamp.split('T')[0]}`,\n startDate: sorted[0]?.timestamp || '',\n endDate: sorted[sorted.length - 1]?.timestamp || '',\n totalIssues: issues.length,\n resolvedCount: issues.filter(i => i.resolved).length,\n bySeverity,\n byAgent,\n topPatterns,\n hotFiles,\n compactedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Normalize issue text for pattern matching\n */\nfunction normalizePattern(text: string): string {\n return text\n .toLowerCase()\n .replace(/`[^`]+`/g, 'CODE')\n .replace(/\\b\\d+\\b/g, 'N')\n .replace(/[\"']/g, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .slice(0, 150);\n}\n\n/**\n * Save compacted summary to disk with atomic write and backup\n */\nexport async function saveCompactedSummary(\n summary: CompactedSummary,\n projectDir: string\n): Promise<void> {\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n await mkdir(memoryDir, { recursive: true });\n \n const summaryPath = join(memoryDir, 'compacted-summaries.json');\n \n let summaries: CompactedSummary[] = [];\n try {\n if (existsSync(summaryPath)) {\n const content = await readFile(summaryPath, 'utf-8');\n const result = safeParseAndValidate(content, CompactedSummariesIndexSchema);\n if (result.success) {\n summaries = result.data as CompactedSummary[];\n }\n }\n } catch {\n summaries = [];\n }\n \n summaries.push(summary);\n \n // Keep only last 12 summaries (1 year of monthly summaries)\n if (summaries.length > 12) {\n summaries = summaries.slice(-12);\n }\n \n // Create backup before writing\n const backupManager = new BackupManager(summaryPath);\n await backupManager.createBackup();\n \n // Atomic write\n await atomicWriteJSON(summaryPath, summaries);\n}\n\n/**\n * Load compacted summaries with validation and auto-recovery\n */\nexport async function loadCompactedSummaries(projectDir: string): Promise<CompactedSummary[]> {\n const summaryPath = join(getTrieDirectory(projectDir), 'memory', 'compacted-summaries.json');\n \n try {\n if (existsSync(summaryPath)) {\n const content = await readFile(summaryPath, 'utf-8');\n const result = safeParseAndValidate(content, CompactedSummariesIndexSchema);\n \n if (result.success) {\n return result.data as CompactedSummary[];\n }\n \n // Validation failed - attempt recovery\n const backupManager = new BackupManager(summaryPath);\n if (await backupManager.recoverFromBackup()) {\n const recovered = await readFile(summaryPath, 'utf-8');\n const recoveredResult = safeParseAndValidate(recovered, CompactedSummariesIndexSchema);\n if (recoveredResult.success) {\n return recoveredResult.data as CompactedSummary[];\n }\n }\n }\n } catch {\n // File doesn't exist or recovery failed\n }\n \n return [];\n}\n\n/**\n * Generate a markdown summary of compacted history\n */\nexport function formatCompactedSummary(summary: CompactedSummary): string {\n const lines: string[] = [\n `## Compacted Summary: ${summary.period}`,\n '',\n `**Total Issues:** ${summary.totalIssues} (${summary.resolvedCount} resolved)`,\n '',\n '### By Severity',\n ...Object.entries(summary.bySeverity).map(([s, c]) => `- ${s}: ${c}`),\n '',\n '### Top Patterns',\n ...summary.topPatterns.slice(0, 5).map(p => \n `- **${p.pattern.slice(0, 50)}...** (${p.count}x, ${p.severity})`\n ),\n '',\n '### Hot Files',\n ...summary.hotFiles.slice(0, 5).map(f => `- ${f.file}: ${f.count} issues`),\n ];\n \n return lines.join('\\n');\n}\n\n/**\n * Get insights from compacted history\n */\nexport async function getHistoricalInsights(projectDir: string): Promise<{\n totalHistoricalIssues: number;\n recurringPatterns: PatternSummary[];\n improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown';\n}> {\n const summaries = await loadCompactedSummaries(projectDir);\n \n if (summaries.length === 0) {\n return {\n totalHistoricalIssues: 0,\n recurringPatterns: [],\n improvementTrend: 'unknown',\n };\n }\n \n const totalHistoricalIssues = summaries.reduce((sum, s) => sum + s.totalIssues, 0);\n \n // Find patterns that appear across multiple summaries\n const patternCounts: Map<string, PatternSummary & { appearances: number }> = new Map();\n \n for (const summary of summaries) {\n for (const pattern of summary.topPatterns) {\n const key = pattern.pattern;\n const existing = patternCounts.get(key);\n if (existing) {\n existing.count += pattern.count;\n existing.appearances++;\n } else {\n patternCounts.set(key, { ...pattern, appearances: 1 });\n }\n }\n }\n \n const recurringPatterns = Array.from(patternCounts.values())\n .filter(p => p.appearances >= 2)\n .sort((a, b) => b.count - a.count)\n .slice(0, 5);\n \n // Calculate improvement trend\n let improvementTrend: 'improving' | 'stable' | 'declining' | 'unknown' = 'unknown';\n \n if (summaries.length >= 2) {\n const recent = summaries.slice(-2);\n const olderCount = recent[0]?.totalIssues || 0;\n const newerCount = recent[1]?.totalIssues || 0;\n \n if (newerCount < olderCount * 0.8) {\n improvementTrend = 'improving';\n } else if (newerCount > olderCount * 1.2) {\n improvementTrend = 'declining';\n } else {\n improvementTrend = 'stable';\n }\n }\n \n return {\n totalHistoricalIssues,\n recurringPatterns,\n improvementTrend,\n };\n}\n"],"mappings":"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","names":["mkdir","readFile","existsSync","join","join","mkdir","existsSync","readFile"]}
|