@triedotdev/mcp 1.0.136 → 1.0.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-DFHMB44X.js → chunk-4JQ6W7LW.js} +3 -4
- package/dist/chunk-4JQ6W7LW.js.map +1 -0
- package/dist/{chunk-WS6OA7H6.js → chunk-4MJ52WBH.js} +2 -3
- package/dist/chunk-4MJ52WBH.js.map +1 -0
- package/dist/{chunk-UHMMANC2.js → chunk-6EP2VTHC.js} +15 -15
- package/dist/chunk-6EP2VTHC.js.map +1 -0
- package/dist/{chunk-T4THB2OR.js → chunk-A6PWS6ZV.js} +38 -27
- package/dist/chunk-A6PWS6ZV.js.map +1 -0
- package/dist/{chunk-POHBQUG7.js → chunk-AXYNWBME.js} +272 -187
- package/dist/chunk-AXYNWBME.js.map +1 -0
- package/dist/{chunk-AJ34GCMD.js → chunk-DPZLABUC.js} +32 -32
- package/dist/chunk-DPZLABUC.js.map +1 -0
- package/dist/{chunk-UHX4462X.js → chunk-G74XEI7K.js} +13 -14
- package/dist/chunk-G74XEI7K.js.map +1 -0
- package/dist/{goal-validator-PDKYZSNP.js → chunk-HUR67JXG.js} +71 -33
- package/dist/chunk-HUR67JXG.js.map +1 -0
- package/dist/{chunk-6OUWNVLX.js → chunk-K6NTRSDF.js} +4 -4
- package/dist/{chunk-G5PRBQIQ.js → chunk-QM5VIDFN.js} +75 -71
- package/dist/chunk-QM5VIDFN.js.map +1 -0
- package/dist/{chunk-4YJ6KLGI.js → chunk-QNKBXOIQ.js} +7 -5
- package/dist/chunk-QNKBXOIQ.js.map +1 -0
- package/dist/{chunk-JAKMZI5S.js → chunk-R3WZI6QZ.js} +290 -179
- package/dist/chunk-R3WZI6QZ.js.map +1 -0
- package/dist/{chunk-VRLMTOB6.js → chunk-TIMIKBY2.js} +1 -1
- package/dist/chunk-TIMIKBY2.js.map +1 -0
- package/dist/cli/main.js +104 -100
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/yolo-daemon.js +13 -13
- package/dist/cli/yolo-daemon.js.map +1 -1
- package/dist/{goal-manager-FAK7H4RR.js → goal-manager-62IL6WGY.js} +6 -7
- package/dist/goal-validator-HPPBSDXD.js +22 -0
- package/dist/guardian-agent-YKG5XURG.js +30 -0
- package/dist/{hypothesis-L5446W36.js → hypothesis-W37VG6DA.js} +6 -7
- package/dist/index.js +265 -259
- package/dist/index.js.map +1 -1
- package/dist/{insight-store-F5KDBY5Y.js → insight-store-U3NYTOJE.js} +5 -3
- package/dist/issue-store-EZMBHOVN.js +32 -0
- package/dist/{output-manager-BOTMXSND.js → output-manager-DZO5LGSG.js} +2 -2
- package/dist/output-manager-DZO5LGSG.js.map +1 -0
- package/dist/ui/chat.html +1 -1
- package/package.json +1 -1
- package/dist/chunk-4YJ6KLGI.js.map +0 -1
- package/dist/chunk-AJ34GCMD.js.map +0 -1
- package/dist/chunk-DFHMB44X.js.map +0 -1
- package/dist/chunk-G5PRBQIQ.js.map +0 -1
- package/dist/chunk-JAKMZI5S.js.map +0 -1
- package/dist/chunk-PEJEYWVR.js +0 -135
- package/dist/chunk-PEJEYWVR.js.map +0 -1
- package/dist/chunk-POHBQUG7.js.map +0 -1
- package/dist/chunk-T4THB2OR.js.map +0 -1
- package/dist/chunk-UHMMANC2.js.map +0 -1
- package/dist/chunk-UHX4462X.js.map +0 -1
- package/dist/chunk-VRLMTOB6.js.map +0 -1
- package/dist/chunk-WS6OA7H6.js.map +0 -1
- package/dist/goal-validator-PDKYZSNP.js.map +0 -1
- package/dist/guardian-agent-4RHGIXUD.js +0 -27
- package/dist/ledger-WKVJWHBX.js +0 -17
- /package/dist/{chunk-6OUWNVLX.js.map → chunk-K6NTRSDF.js.map} +0 -0
- /package/dist/{goal-manager-FAK7H4RR.js.map → goal-manager-62IL6WGY.js.map} +0 -0
- /package/dist/{guardian-agent-4RHGIXUD.js.map → goal-validator-HPPBSDXD.js.map} +0 -0
- /package/dist/{hypothesis-L5446W36.js.map → guardian-agent-YKG5XURG.js.map} +0 -0
- /package/dist/{insight-store-F5KDBY5Y.js.map → hypothesis-W37VG6DA.js.map} +0 -0
- /package/dist/{ledger-WKVJWHBX.js.map → insight-store-U3NYTOJE.js.map} +0 -0
- /package/dist/{output-manager-BOTMXSND.js.map → issue-store-EZMBHOVN.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/memory/issue-store.ts","../src/memory/bm25.ts","../src/memory/compactor.ts","../src/memory/ledger.ts"],"sourcesContent":["/**\n * Issue Memory Store\n * \n * Stores issues for semantic search and pattern detection.\n * Uses BM25 ranking for search (same algorithm as Elasticsearch).\n * Local JSON storage with daily logs.\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, writeFile, 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 { 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}\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 from a scan\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 };\n stored.push(storedIssue);\n }\n\n await appendToDailyLog(stored, projectDir);\n await appendIssuesToLedger(stored, projectDir);\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 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 saveIssueIndex(index, projectDir);\n return true;\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 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 saveIssueIndex(index, projectDir);\n }\n \n return { resolved: resolvedCount, stillActive: stillActiveCount };\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 index = await loadIssueIndex(projectDir);\n \n const now = new Date().toISOString();\n let resolvedCount = 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 resolvedCount++;\n }\n }\n \n if (resolvedCount > 0) {\n await saveIssueIndex(index, projectDir);\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 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 saveIssueIndex(remaining, projectDir);\n \n return {\n removed: originalCount - remaining.length,\n remaining: remaining.length,\n strategy,\n };\n}\n\n/**\n * Get daily log files\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\nasync function appendToDailyLog(issues: StoredIssue[], projectDir: string): Promise<void> {\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n const today = new Date().toISOString().split('T')[0];\n const logPath = join(memoryDir, `${today}.md`);\n\n let content = '';\n \n try {\n if (existsSync(logPath)) {\n content = await readFile(logPath, 'utf-8');\n } else {\n content = `# Issue Log: ${today}\\n\\n`;\n }\n } catch {\n content = `# Issue Log: ${today}\\n\\n`;\n }\n\n const time = new Date().toTimeString().split(' ')[0];\n \n const newEntries = issues.map(i => \n `## [${time}] ${i.severity.toUpperCase()}: ${i.issue.slice(0, 80)}${i.issue.length > 80 ? '...' : ''}\\n` +\n `- **File:** \\`${i.file}\\`${i.line ? `:${i.line}` : ''}\\n` +\n `- **Agent:** ${i.agent}\\n` +\n `- **Fix:** ${i.fix.slice(0, 200)}${i.fix.length > 200 ? '...' : ''}\\n`\n ).join('\\n');\n\n content += newEntries + '\\n';\n \n await writeFile(logPath, content);\n}\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 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 await saveIssueIndex(existing, projectDir);\n return dedupedCount;\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 * 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 saveIssueIndex(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","import { createHash } from 'crypto';\nimport { mkdir, readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\nimport { atomicWriteJSON } from '../utils/atomic-write.js';\nimport { getWorkingDirectory, getTrieDirectory } from '../utils/workspace.js';\nimport type { StoredIssue } from './issue-store.js';\n\nconst LEDGER_FILENAME = 'ledger.json';\nconst GENESIS_HASH = '0'.repeat(64);\nconst LEDGER_VERSION = 1;\n\nexport interface LedgerEntry {\n id: string;\n hash: string;\n severity: string;\n file: string;\n agent: string;\n timestamp: string;\n}\n\nexport interface LedgerBlock {\n version: number;\n date: string;\n entries: LedgerEntry[];\n previousHash: string;\n merkleRoot: string;\n blockHash: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LedgerVerificationResult {\n valid: boolean;\n error?: string;\n}\n\nexport async function appendIssuesToLedger(\n issues: StoredIssue[],\n workDir?: string\n): Promise<LedgerBlock | null> {\n if (issues.length === 0) return null;\n\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const memoryDir = join(getTrieDirectory(projectDir), 'memory');\n await mkdir(memoryDir, { recursive: true });\n\n const blocks = await loadLedger(projectDir);\n const today = new Date().toISOString().slice(0, 10);\n const now = new Date().toISOString();\n\n const entries: LedgerEntry[] = issues.map(issue => ({\n id: issue.id,\n hash: issue.hash,\n severity: issue.severity,\n file: issue.file,\n agent: issue.agent,\n timestamp: issue.timestamp,\n }));\n\n const previousBlock = blocks[blocks.length - 1];\n const block = previousBlock && previousBlock.date === today\n ? previousBlock\n : createBlock(today, now, previousBlock?.blockHash ?? GENESIS_HASH);\n\n if (block !== previousBlock) {\n blocks.push(block);\n }\n\n block.entries = [...block.entries, ...entries];\n block.merkleRoot = computeMerkleRoot(block.entries.map(entry => entry.hash));\n block.blockHash = computeBlockHash(block.previousHash, block.merkleRoot, block.date, block.version);\n block.updatedAt = now;\n\n await saveLedger(blocks, projectDir);\n return block;\n}\n\nexport async function verifyLedger(workDir?: string): Promise<LedgerVerificationResult> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n const blocks = await loadLedger(projectDir);\n\n if (blocks.length === 0) {\n return { valid: true };\n }\n\n for (let i = 0; i < blocks.length; i += 1) {\n const block = blocks[i];\n if (!block) {\n return { valid: false, error: `Block ${i} missing` };\n }\n const expectedPreviousHash = i === 0\n ? GENESIS_HASH\n : blocks[i - 1]?.blockHash;\n\n if (!expectedPreviousHash) {\n return { valid: false, error: `Block ${i} missing previous block` };\n }\n\n if (block.previousHash !== expectedPreviousHash) {\n return { valid: false, error: `Block ${i} previous hash mismatch` };\n }\n\n const computedMerkleRoot = computeMerkleRoot(block.entries.map(entry => entry.hash));\n if (block.merkleRoot !== computedMerkleRoot) {\n return { valid: false, error: `Block ${i} merkle root mismatch` };\n }\n\n const computedBlockHash = computeBlockHash(block.previousHash, block.merkleRoot, block.date, block.version);\n if (block.blockHash !== computedBlockHash) {\n return { valid: false, error: `Block ${i} hash mismatch` };\n }\n }\n\n return { valid: true };\n}\n\nexport function computeMerkleRoot(hashes: string[]): string {\n if (hashes.length === 0) {\n return sha256('');\n }\n\n let level = hashes.slice();\n while (level.length > 1) {\n const nextLevel: string[] = [];\n for (let i = 0; i < level.length; i += 2) {\n const left = level[i];\n const right = level[i + 1] ?? left;\n nextLevel.push(sha256(`${left}:${right}`));\n }\n level = nextLevel;\n }\n\n return level[0]!;\n}\n\nfunction computeBlockHash(previousHash: string, merkleRoot: string, date: string, version: number): string {\n return sha256(`${version}:${date}:${previousHash}:${merkleRoot}`);\n}\n\nfunction createBlock(date: string, now: string, previousHash: string): LedgerBlock {\n return {\n version: LEDGER_VERSION,\n date,\n entries: [],\n previousHash,\n merkleRoot: '',\n blockHash: '',\n createdAt: now,\n updatedAt: now,\n };\n}\n\nasync function loadLedger(projectDir: string): Promise<LedgerBlock[]> {\n const ledgerPath = join(getTrieDirectory(projectDir), 'memory', LEDGER_FILENAME);\n try {\n if (!existsSync(ledgerPath)) return [];\n const content = await readFile(ledgerPath, 'utf-8');\n const parsed = JSON.parse(content);\n if (!Array.isArray(parsed)) return [];\n return parsed as LedgerBlock[];\n } catch {\n return [];\n }\n}\n\n/** Load ledger blocks for UI display (block hashes, merkle roots, chain) */\nexport async function getLedgerBlocks(workDir?: string): Promise<LedgerBlock[]> {\n const projectDir = workDir || getWorkingDirectory(undefined, true);\n return loadLedger(projectDir);\n}\n\nasync function saveLedger(blocks: LedgerBlock[], projectDir: string): Promise<void> {\n const ledgerPath = join(getTrieDirectory(projectDir), 'memory', LEDGER_FILENAME);\n await atomicWriteJSON(ledgerPath, blocks);\n}\n\nfunction sha256(input: string): string {\n return createHash('sha256').update(input).digest('hex');\n}\n"],"mappings":"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","names":["mkdir","readFile","createHash","existsSync","join","mkdir","readFile","existsSync","join","join","mkdir","join","existsSync","readFile","join","mkdir","existsSync","readFile","createHash"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/output-manager.ts"],"sourcesContent":["/**\n * OutputManager - Unified output abstraction for all UI modes\n * \n * Routes content to the appropriate renderer based on current mode:\n * - TUI: Routes to InteractiveDashboard\n * - Console: Routes to console.error with ANSI colors\n * - MCP: Accumulates for markdown response\n * - JSON: Accumulates for JSON response\n * - Silent: Discards output\n * \n * This solves the problem of skills suppressing content in interactive mode\n * by redirecting it to the dashboard instead.\n */\n\nimport type { Issue } from '../types/index.js';\nimport type { StreamingManager } from './streaming.js';\nimport { isInteractiveMode } from './progress.js';\nimport pc from 'picocolors';\n\n// Output content types\nexport type OutputContentType = \n | 'banner' // ASCII art banner from skills\n | 'progress' // Progress update\n | 'issue' // Issue found\n | 'snippet' // Code snippet with context\n | 'cost' // Cost estimate from Moneybags\n | 'readiness' // Production readiness score\n | 'semantic' // Semantic analysis (data flow, race conditions)\n | 'attack' // Attack surface analysis\n | 'activity' // Activity log message\n | 'report' // Full markdown report section\n | 'log' // Raw log message\n | 'nudge'; // Proactive notification\n\n// Nudge content for proactive notifications\nexport interface NudgeContent {\n message: string;\n severity: 'critical' | 'warning' | 'info';\n file?: string;\n autoHideMs?: number; // Auto-dismiss after this many milliseconds\n}\n\nexport interface BannerContent {\n skill: string;\n art: string;\n quote?: string;\n version?: string;\n}\n\nexport interface SnippetContent {\n file: string;\n lines: string[];\n highlightLine?: number;\n startLine: number;\n}\n\nexport interface CostContent {\n fixNowCost: number;\n productionCost: number;\n savings: number;\n perIssue?: Array<{ issue: string; cost: number }>;\n}\n\nexport interface ReadinessContent {\n score: number;\n requirementsMet: number;\n total: number;\n status: 'ready' | 'caution' | 'not-ready';\n requirements?: Array<{ name: string; met: boolean }>;\n}\n\nexport interface SemanticContent {\n dataFlowIssues: number;\n raceConditions: number;\n authIssues: number;\n details?: Array<{ type: string; description: string; file: string; line?: number }>;\n}\n\nexport interface AttackSurfaceContent {\n totalEndpoints: number;\n unprotected: number;\n riskScore: number;\n endpoints?: Array<{ path: string; method: string; auth: boolean; sensitive: boolean }>;\n}\n\nexport interface OutputContent {\n type: OutputContentType;\n content: any;\n timestamp?: number;\n metadata?: {\n severity?: 'critical' | 'serious' | 'moderate' | 'low';\n agent?: string;\n file?: string;\n };\n}\n\nexport type OutputMode = 'tui' | 'console' | 'mcp' | 'json' | 'silent';\n\n/**\n * Central output manager - singleton\n */\nclass OutputManagerImpl {\n private mode: OutputMode = 'console';\n private streamingManager?: StreamingManager;\n private markdownBuffer: string[] = [];\n private jsonBuffer: OutputContent[] = [];\n private rawLogBuffer: Array<{ time: string; level: string; message: string }> = [];\n \n // Callbacks for TUI integration (explicitly allow undefined for exactOptionalPropertyTypes)\n private onBanner: ((content: BannerContent) => void) | undefined = undefined;\n private onSnippet: ((content: SnippetContent) => void) | undefined = undefined;\n private onCost: ((content: CostContent) => void) | undefined = undefined;\n private onReadiness: ((content: ReadinessContent) => void) | undefined = undefined;\n private onSemantic: ((content: SemanticContent) => void) | undefined = undefined;\n private onAttack: ((content: AttackSurfaceContent) => void) | undefined = undefined;\n private onActivity: ((message: string) => void) | undefined = undefined;\n private onLog: ((level: string, message: string) => void) | undefined = undefined;\n private onNudge: ((content: NudgeContent) => void) | undefined = undefined;\n\n /**\n * Set the output mode\n */\n setMode(mode: OutputMode): void {\n this.mode = mode;\n }\n\n /**\n * Get current output mode\n */\n getMode(): OutputMode {\n return this.mode;\n }\n\n /**\n * Set streaming manager for TUI updates\n */\n setStreamingManager(manager: StreamingManager): void {\n this.streamingManager = manager;\n }\n\n /**\n * Register TUI callbacks for rich content\n */\n registerTUICallbacks(callbacks: {\n onBanner?: (content: BannerContent) => void;\n onSnippet?: (content: SnippetContent) => void;\n onCost?: (content: CostContent) => void;\n onReadiness?: (content: ReadinessContent) => void;\n onSemantic?: (content: SemanticContent) => void;\n onAttack?: (content: AttackSurfaceContent) => void;\n onActivity?: (message: string) => void;\n onLog?: (level: string, message: string) => void;\n onNudge?: (content: NudgeContent) => void;\n }): void {\n this.onBanner = callbacks.onBanner;\n this.onSnippet = callbacks.onSnippet;\n this.onCost = callbacks.onCost;\n this.onReadiness = callbacks.onReadiness;\n this.onSemantic = callbacks.onSemantic;\n this.onAttack = callbacks.onAttack;\n this.onActivity = callbacks.onActivity;\n this.onLog = callbacks.onLog;\n this.onNudge = callbacks.onNudge;\n }\n\n /**\n * Clear TUI callbacks (when dashboard stops)\n */\n clearTUICallbacks(): void {\n this.onBanner = undefined;\n this.onSnippet = undefined;\n this.onCost = undefined;\n this.onReadiness = undefined;\n this.onSemantic = undefined;\n this.onAttack = undefined;\n this.onActivity = undefined;\n this.onLog = undefined;\n this.onNudge = undefined;\n }\n\n /**\n * Emit content - routes to appropriate handler based on mode\n */\n emit(content: OutputContent): void {\n content.timestamp = content.timestamp ?? Date.now();\n \n switch (this.mode) {\n case 'tui':\n this.routeToTUI(content);\n break;\n case 'console':\n this.routeToConsole(content);\n break;\n case 'mcp':\n this.routeToMarkdown(content);\n break;\n case 'json':\n this.routeToJson(content);\n break;\n case 'silent':\n // Discard\n break;\n }\n \n // Always capture in raw log buffer\n this.captureRawLog(content);\n }\n\n /**\n * Route content to TUI (dashboard callbacks)\n */\n private routeToTUI(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n this.onBanner?.(content.content as BannerContent);\n break;\n case 'snippet':\n this.onSnippet?.(content.content as SnippetContent);\n break;\n case 'cost':\n this.onCost?.(content.content as CostContent);\n break;\n case 'readiness':\n this.onReadiness?.(content.content as ReadinessContent);\n break;\n case 'semantic':\n this.onSemantic?.(content.content as SemanticContent);\n break;\n case 'attack':\n this.onAttack?.(content.content as AttackSurfaceContent);\n break;\n case 'activity':\n this.onActivity?.(content.content as string);\n break;\n case 'log':\n const level = content.metadata?.severity ?? 'info';\n this.onLog?.(level, content.content as string);\n break;\n case 'issue':\n // Issues go through streaming manager\n this.streamingManager?.reportIssue(content.content as Issue);\n break;\n case 'progress':\n // Progress goes through streaming manager\n break;\n case 'report':\n // Reports are captured but not directly displayed\n break;\n case 'nudge':\n // Proactive notifications go to dashboard\n this.onNudge?.(content.content as NudgeContent);\n break;\n }\n }\n\n /**\n * Route content to console (ANSI formatted)\n */\n private routeToConsole(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n const banner = content.content as BannerContent;\n console.error('\\n' + '='.repeat(60));\n console.error(banner.art);\n if (banner.version) {\n console.error(` ${banner.skill} v${banner.version}`);\n }\n console.error('');\n if (banner.quote) {\n console.error(` \"${banner.quote}\"`);\n }\n console.error('='.repeat(60) + '\\n');\n break;\n \n case 'snippet':\n const snippet = content.content as SnippetContent;\n console.error(`\\n${pc.dim('File:')} ${snippet.file}`);\n for (let i = 0; i < snippet.lines.length; i++) {\n const lineNum = snippet.startLine + i;\n const isHighlight = lineNum === snippet.highlightLine;\n const prefix = isHighlight ? pc.red('→') : ' ';\n const lineNumStr = pc.dim(lineNum.toString().padStart(4));\n const line = isHighlight ? pc.yellow(snippet.lines[i]) : snippet.lines[i];\n console.error(`${prefix} ${lineNumStr} | ${line}`);\n }\n console.error('');\n break;\n \n case 'cost':\n const cost = content.content as CostContent;\n console.error('\\n' + pc.cyan('[$] Cost Estimate:'));\n console.error(` Fix now: ${pc.green(this.formatCurrency(cost.fixNowCost))}`);\n console.error(` If production: ${pc.red(this.formatCurrency(cost.productionCost))}`);\n console.error(` Savings: ${pc.yellow(this.formatCurrency(cost.savings))}`);\n console.error('');\n break;\n \n case 'readiness':\n const readiness = content.content as ReadinessContent;\n const statusColor = readiness.status === 'ready' ? pc.green : \n readiness.status === 'caution' ? pc.yellow : pc.red;\n console.error('\\n' + pc.cyan('[%] Production Readiness:'));\n console.error(` Score: ${statusColor(readiness.score + '/100')}`);\n console.error(` Requirements: ${readiness.requirementsMet}/${readiness.total}`);\n console.error(` Status: ${statusColor(readiness.status.toUpperCase())}`);\n console.error('');\n break;\n \n case 'semantic':\n const semantic = content.content as SemanticContent;\n console.error('\\n' + pc.cyan('[?] Semantic Analysis:'));\n if (semantic.dataFlowIssues > 0) {\n console.error(` ${pc.red('[!]')} ${semantic.dataFlowIssues} data flow vulnerabilities`);\n }\n if (semantic.raceConditions > 0) {\n console.error(` ${pc.yellow('[~]')} ${semantic.raceConditions} race conditions`);\n }\n if (semantic.authIssues > 0) {\n console.error(` ${pc.red('[!]')} ${semantic.authIssues} authentication issues`);\n }\n console.error('');\n break;\n \n case 'attack':\n const attack = content.content as AttackSurfaceContent;\n console.error('\\n' + pc.cyan('[>] Attack Surface:'));\n console.error(` Endpoints: ${attack.totalEndpoints}`);\n if (attack.unprotected > 0) {\n console.error(` ${pc.red('Unprotected:')} ${attack.unprotected}`);\n }\n console.error(` Risk Score: ${attack.riskScore}/100`);\n console.error('');\n break;\n \n case 'activity':\n console.error(pc.dim(`[${this.formatTime()}]`) + ` ${content.content}`);\n break;\n \n case 'log':\n // For log content, severity can be any string (info, warn, error, debug)\n const logLevel = String(content.metadata?.severity ?? 'info');\n const levelColor = logLevel === 'error' || logLevel === 'critical' ? pc.red :\n logLevel === 'warn' || logLevel === 'serious' ? pc.yellow :\n logLevel === 'info' || logLevel === 'moderate' ? pc.blue : pc.dim;\n console.error(levelColor(`[${logLevel.toUpperCase()}]`) + ` ${content.content}`);\n break;\n \n case 'issue':\n const issue = content.content as Issue;\n const sevColor = issue.severity === 'critical' ? pc.red :\n issue.severity === 'serious' ? pc.yellow :\n issue.severity === 'moderate' ? pc.blue : pc.dim;\n console.error(`${sevColor(`[${issue.severity.toUpperCase()}]`)} ${issue.issue}`);\n console.error(` ${pc.dim('File:')} ${issue.file}:${issue.line ?? '?'}`);\n break;\n \n case 'report':\n // Reports are printed as-is (already formatted)\n console.error(content.content);\n break;\n \n case 'nudge':\n // Proactive notifications in console mode\n const nudge = content.content as NudgeContent;\n const nudgeColor = nudge.severity === 'critical' ? pc.red :\n nudge.severity === 'warning' ? pc.yellow : pc.cyan;\n const nudgeIcon = nudge.severity === 'critical' ? '[!!!]' :\n nudge.severity === 'warning' ? '[!]' : '[>]';\n console.error('');\n console.error(nudgeColor('━'.repeat(60)));\n console.error(nudgeColor(`${nudgeIcon} TRIE AGENT SAYS:`));\n console.error(nudgeColor('━'.repeat(60)));\n console.error('');\n console.error(` ${pc.bold(nudge.message)}`);\n if (nudge.file) {\n console.error(` ${pc.dim('File:')} ${nudge.file}`);\n }\n console.error('');\n console.error(nudgeColor('━'.repeat(60)));\n console.error('');\n break;\n }\n }\n\n /**\n * Route content to markdown buffer\n */\n private routeToMarkdown(content: OutputContent): void {\n switch (content.type) {\n case 'banner':\n const banner = content.content as BannerContent;\n this.markdownBuffer.push(`## ${banner.skill}\\n`);\n if (banner.quote) {\n this.markdownBuffer.push(`> ${banner.quote}\\n`);\n }\n break;\n \n case 'snippet':\n const snippet = content.content as SnippetContent;\n this.markdownBuffer.push(`\\n**File:** \\`${snippet.file}\\`\\n`);\n this.markdownBuffer.push('```\\n');\n for (let i = 0; i < snippet.lines.length; i++) {\n const lineNum = snippet.startLine + i;\n const prefix = lineNum === snippet.highlightLine ? '→' : ' ';\n this.markdownBuffer.push(`${prefix} ${lineNum.toString().padStart(4)} | ${snippet.lines[i]}\\n`);\n }\n this.markdownBuffer.push('```\\n');\n break;\n \n case 'cost':\n const cost = content.content as CostContent;\n this.markdownBuffer.push(`\\n### Cost Estimate\\n`);\n this.markdownBuffer.push(`- Fix now: ${this.formatCurrency(cost.fixNowCost)}\\n`);\n this.markdownBuffer.push(`- If production: ${this.formatCurrency(cost.productionCost)}\\n`);\n this.markdownBuffer.push(`- Savings: ${this.formatCurrency(cost.savings)}\\n`);\n break;\n \n case 'readiness':\n const readiness = content.content as ReadinessContent;\n this.markdownBuffer.push(`\\n### Production Readiness\\n`);\n this.markdownBuffer.push(`- Score: ${readiness.score}/100\\n`);\n this.markdownBuffer.push(`- Requirements: ${readiness.requirementsMet}/${readiness.total}\\n`);\n this.markdownBuffer.push(`- Status: **${readiness.status.toUpperCase()}**\\n`);\n break;\n \n case 'semantic':\n const semantic = content.content as SemanticContent;\n this.markdownBuffer.push(`\\n### Semantic Analysis\\n`);\n if (semantic.dataFlowIssues > 0) {\n this.markdownBuffer.push(`- [CRITICAL] ${semantic.dataFlowIssues} data flow vulnerabilities\\n`);\n }\n if (semantic.raceConditions > 0) {\n this.markdownBuffer.push(`- [WARN] ${semantic.raceConditions} race conditions\\n`);\n }\n if (semantic.authIssues > 0) {\n this.markdownBuffer.push(`- [CRITICAL] ${semantic.authIssues} authentication issues\\n`);\n }\n break;\n \n case 'attack':\n const attack = content.content as AttackSurfaceContent;\n this.markdownBuffer.push(`\\n### Attack Surface\\n`);\n this.markdownBuffer.push(`- Endpoints: ${attack.totalEndpoints}\\n`);\n this.markdownBuffer.push(`- Unprotected: ${attack.unprotected}\\n`);\n this.markdownBuffer.push(`- Risk Score: ${attack.riskScore}/100\\n`);\n break;\n \n case 'report':\n this.markdownBuffer.push(content.content);\n break;\n \n default:\n // Other types are captured in JSON buffer\n this.jsonBuffer.push(content);\n }\n }\n\n /**\n * Route content to JSON buffer\n */\n private routeToJson(content: OutputContent): void {\n this.jsonBuffer.push(content);\n }\n\n /**\n * Capture content in raw log buffer\n */\n private captureRawLog(content: OutputContent): void {\n const time = this.formatTime(content.timestamp);\n const level = content.metadata?.severity ?? content.type;\n let message = '';\n \n switch (content.type) {\n case 'banner':\n message = `[BANNER] ${(content.content as BannerContent).skill}`;\n break;\n case 'activity':\n case 'log':\n message = content.content as string;\n break;\n case 'issue':\n const issue = content.content as Issue;\n message = `[${issue.severity.toUpperCase()}] ${issue.issue}`;\n break;\n default:\n message = `[${content.type.toUpperCase()}] Content received`;\n }\n \n this.rawLogBuffer.push({ time, level, message });\n \n // Keep buffer size reasonable\n if (this.rawLogBuffer.length > 500) {\n this.rawLogBuffer = this.rawLogBuffer.slice(-500);\n }\n }\n\n /**\n * Get raw log buffer for display\n */\n getRawLog(): Array<{ time: string; level: string; message: string }> {\n return [...this.rawLogBuffer];\n }\n\n /**\n * Get accumulated markdown output\n */\n getMarkdown(): string {\n return this.markdownBuffer.join('\\n');\n }\n\n /**\n * Get accumulated JSON output\n */\n getJson(): OutputContent[] {\n return [...this.jsonBuffer];\n }\n\n /**\n * Clear buffers\n */\n clearBuffers(): void {\n this.markdownBuffer = [];\n this.jsonBuffer = [];\n }\n\n // ============================================\n // Convenience methods for common output types\n // ============================================\n\n /**\n * Display a skill banner\n */\n banner(skill: string, art: string, options?: { quote?: string; version?: string }): void {\n this.emit({\n type: 'banner',\n content: { skill, art, quote: options?.quote, version: options?.version } as BannerContent,\n metadata: { agent: skill }\n });\n }\n\n /**\n * Display a code snippet\n */\n snippet(file: string, lines: string[], startLine: number, highlightLine?: number): void {\n this.emit({\n type: 'snippet',\n content: { file, lines, startLine, highlightLine } as SnippetContent,\n metadata: { file }\n });\n }\n\n /**\n * Display cost estimate\n */\n cost(fixNowCost: number, productionCost: number, savings: number, perIssue?: Array<{ issue: string; cost: number }>): void {\n this.emit({\n type: 'cost',\n content: { fixNowCost, productionCost, savings, perIssue } as CostContent\n });\n }\n\n /**\n * Display production readiness\n */\n readiness(\n score: number, \n requirementsMet: number, \n total: number, \n status: 'ready' | 'caution' | 'not-ready',\n requirements?: Array<{ name: string; met: boolean }>\n ): void {\n const content: ReadinessContent = { score, requirementsMet, total, status };\n if (requirements) {\n content.requirements = requirements;\n }\n this.emit({\n type: 'readiness',\n content\n });\n }\n\n /**\n * Display semantic analysis results\n */\n semantic(dataFlowIssues: number, raceConditions: number, authIssues: number): void {\n this.emit({\n type: 'semantic',\n content: { dataFlowIssues, raceConditions, authIssues } as SemanticContent\n });\n }\n\n /**\n * Display attack surface analysis\n */\n attack(totalEndpoints: number, unprotected: number, riskScore: number): void {\n this.emit({\n type: 'attack',\n content: { totalEndpoints, unprotected, riskScore } as AttackSurfaceContent\n });\n }\n\n /**\n * Log an activity message\n */\n activity(message: string): void {\n this.emit({\n type: 'activity',\n content: message\n });\n }\n\n /**\n * Log a message at specified level\n */\n log(level: 'info' | 'warn' | 'error' | 'debug', message: string): void {\n this.emit({\n type: 'log',\n content: message,\n metadata: { severity: level as any }\n });\n }\n\n /**\n * Log info message\n */\n info(message: string): void {\n this.log('info', message);\n }\n\n /**\n * Log warning message\n */\n warn(message: string): void {\n this.log('warn', message);\n }\n\n /**\n * Log error message\n */\n error(message: string): void {\n this.log('error', message);\n }\n\n /**\n * Log debug message\n */\n debug(message: string): void {\n this.log('debug', message);\n }\n\n /**\n * Report an issue\n */\n issue(issue: Issue): void {\n this.emit({\n type: 'issue',\n content: issue,\n metadata: { severity: issue.severity, agent: issue.agent, file: issue.file }\n });\n }\n\n /**\n * Add a report section\n */\n report(content: string): void {\n this.emit({\n type: 'report',\n content\n });\n }\n\n /**\n * Send a proactive notification/nudge to the user\n * This creates a prominent popup in TUI mode or a boxed message in console mode\n */\n nudge(message: string, severity: 'critical' | 'warning' | 'info' = 'warning', file?: string, autoHideMs?: number): void {\n const metadata: { severity?: 'critical' | 'serious' | 'moderate' | 'low'; agent?: string; file?: string } = {};\n // Map nudge severity to issue severity\n if (severity === 'critical') metadata.severity = 'critical';\n else if (severity === 'warning') metadata.severity = 'moderate';\n else metadata.severity = 'low';\n if (file !== undefined) metadata.file = file;\n this.emit({\n type: 'nudge',\n content: { message, severity, file, autoHideMs } as NudgeContent,\n metadata,\n });\n }\n\n // ============================================\n // Helpers\n // ============================================\n\n private formatCurrency(amount: number): string {\n if (amount >= 1000000) return `$${(amount / 1000000).toFixed(2)}M`;\n if (amount >= 1000) return `$${(amount / 1000).toFixed(1)}k`;\n return `$${amount}`;\n }\n\n private formatTime(timestamp?: number): string {\n const date = timestamp ? new Date(timestamp) : new Date();\n return date.toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit', second: '2-digit' });\n }\n}\n\n// Singleton instance\nlet instance: OutputManagerImpl | null = null;\n\n/**\n * Get the OutputManager instance\n */\nexport function getOutputManager(): OutputManagerImpl {\n if (!instance) {\n instance = new OutputManagerImpl();\n \n // Auto-detect mode based on interactive mode flag\n if (isInteractiveMode()) {\n instance.setMode('tui');\n }\n }\n return instance;\n}\n\n/**\n * Convenience function - shorthand for getOutputManager()\n */\nexport function output(): OutputManagerImpl {\n return getOutputManager();\n}\n\n/**\n * Reset the OutputManager (for testing)\n */\nexport function resetOutputManager(): void {\n instance = null;\n}\n"],"mappings":"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","names":[]}
|