@triedotdev/mcp 1.0.161 → 1.0.162
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-ZGVPZZFM.js → chunk-ERMLZJTK.js} +4 -4
- package/dist/{chunk-OWYOC5DX.js → chunk-HFVPHQL3.js} +2 -2
- package/dist/{chunk-XMW2WTZB.js → chunk-LLDZDU2Y.js} +19 -2
- package/dist/chunk-LLDZDU2Y.js.map +1 -0
- package/dist/{chunk-MPHYM7M6.js → chunk-Q4K7CFCK.js} +164 -33
- package/dist/chunk-Q4K7CFCK.js.map +1 -0
- package/dist/{chunk-XBXII4FC.js → chunk-UDQBOLIR.js} +18 -4
- package/dist/chunk-UDQBOLIR.js.map +1 -0
- package/dist/cli/main.js +2 -2
- package/dist/cli/yolo-daemon.js +4 -4
- package/dist/index.js +5 -5
- package/dist/server/mcp-server.js +5 -5
- package/dist/{tiered-storage-THHKROJF.js → tiered-storage-FHHAJR4P.js} +2 -2
- package/dist/{trie-agent-VRV6GKJP.js → trie-agent-NYSPGZYS.js} +4 -4
- package/package.json +1 -1
- package/dist/chunk-MPHYM7M6.js.map +0 -1
- package/dist/chunk-XBXII4FC.js.map +0 -1
- package/dist/chunk-XMW2WTZB.js.map +0 -1
- /package/dist/{chunk-ZGVPZZFM.js.map → chunk-ERMLZJTK.js.map} +0 -0
- /package/dist/{chunk-OWYOC5DX.js.map → chunk-HFVPHQL3.js.map} +0 -0
- /package/dist/{tiered-storage-THHKROJF.js.map → tiered-storage-FHHAJR4P.js.map} +0 -0
- /package/dist/{trie-agent-VRV6GKJP.js.map → trie-agent-NYSPGZYS.js.map} +0 -0
|
@@ -12,10 +12,10 @@ import {
|
|
|
12
12
|
SlackIntegration,
|
|
13
13
|
findCrossProjectPatterns,
|
|
14
14
|
recordToGlobalMemory
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-HFVPHQL3.js";
|
|
16
16
|
import {
|
|
17
17
|
getStorage
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-LLDZDU2Y.js";
|
|
19
19
|
import {
|
|
20
20
|
ContextGraph
|
|
21
21
|
} from "./chunk-VUL52BQL.js";
|
|
@@ -1587,7 +1587,7 @@ var TrieAgent = class {
|
|
|
1587
1587
|
} catch {
|
|
1588
1588
|
}
|
|
1589
1589
|
try {
|
|
1590
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
1590
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
|
|
1591
1591
|
const storage = getStorage2(this.projectPath);
|
|
1592
1592
|
const resolvedIssueIds = [...this.lastIssueHashes].filter((h) => !currentHashes.has(h)).map((h) => {
|
|
1593
1593
|
return h.split(":").join("-");
|
|
@@ -1824,4 +1824,4 @@ export {
|
|
|
1824
1824
|
TrieAgent,
|
|
1825
1825
|
getTrieAgent
|
|
1826
1826
|
};
|
|
1827
|
-
//# sourceMappingURL=chunk-
|
|
1827
|
+
//# sourceMappingURL=chunk-ERMLZJTK.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getStorage
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-LLDZDU2Y.js";
|
|
4
4
|
import {
|
|
5
5
|
tryGetClient
|
|
6
6
|
} from "./chunk-FQ45QP5A.js";
|
|
@@ -821,4 +821,4 @@ export {
|
|
|
821
821
|
SlackIntegration,
|
|
822
822
|
GotchaPredictor
|
|
823
823
|
};
|
|
824
|
-
//# sourceMappingURL=chunk-
|
|
824
|
+
//# sourceMappingURL=chunk-HFVPHQL3.js.map
|
|
@@ -311,7 +311,7 @@ var TieredStorage = class {
|
|
|
311
311
|
decision: row.decision,
|
|
312
312
|
context: row.context,
|
|
313
313
|
reasoning: row.reasoning,
|
|
314
|
-
when: row.when,
|
|
314
|
+
when: row.timestamp || row.when,
|
|
315
315
|
who: row.who,
|
|
316
316
|
files: JSON.parse(row.files),
|
|
317
317
|
tags: JSON.parse(row.tags),
|
|
@@ -322,6 +322,23 @@ var TieredStorage = class {
|
|
|
322
322
|
hash: row.hash || void 0
|
|
323
323
|
}));
|
|
324
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Query facts from warm storage (for Learned Signals display)
|
|
327
|
+
*/
|
|
328
|
+
async queryFacts(query = {}) {
|
|
329
|
+
if (!this.warmDb) await this.initialize();
|
|
330
|
+
if (!this.warmDb) throw new Error("Database not initialized");
|
|
331
|
+
const limit = query.limit ?? 20;
|
|
332
|
+
const rows = this.warmDb.prepare("SELECT * FROM facts ORDER BY timestamp DESC LIMIT ?").all(limit);
|
|
333
|
+
return rows.map((row) => ({
|
|
334
|
+
id: row.id,
|
|
335
|
+
fact: row.fact,
|
|
336
|
+
source: row.source,
|
|
337
|
+
when: row.timestamp || row.when,
|
|
338
|
+
tags: JSON.parse(row.tags || "[]"),
|
|
339
|
+
confidence: row.confidence ?? 0.8
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
325
342
|
/**
|
|
326
343
|
* Query blockers from warm storage with expanded tag matching
|
|
327
344
|
*/
|
|
@@ -639,4 +656,4 @@ export {
|
|
|
639
656
|
TieredStorage,
|
|
640
657
|
getStorage
|
|
641
658
|
};
|
|
642
|
-
//# sourceMappingURL=chunk-
|
|
659
|
+
//# sourceMappingURL=chunk-LLDZDU2Y.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 * 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":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-JVMBCWKS.js";
|
|
4
4
|
import {
|
|
5
5
|
getTrieAgent
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-ERMLZJTK.js";
|
|
7
7
|
import {
|
|
8
8
|
CodebaseIndex
|
|
9
9
|
} from "./chunk-Q5EKA5YA.js";
|
|
@@ -30,11 +30,11 @@ import {
|
|
|
30
30
|
} from "./chunk-TN5WEKWI.js";
|
|
31
31
|
import {
|
|
32
32
|
findCrossProjectPatterns
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-HFVPHQL3.js";
|
|
34
34
|
import {
|
|
35
35
|
TieredStorage,
|
|
36
36
|
getStorage
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-LLDZDU2Y.js";
|
|
38
38
|
import {
|
|
39
39
|
ContextGraph
|
|
40
40
|
} from "./chunk-VUL52BQL.js";
|
|
@@ -457,6 +457,7 @@ function handleStreamUpdate(state, update) {
|
|
|
457
457
|
const total = (update.data.governance || 0) + (update.data.facts || 0) + (update.data.blockers || 0) + (update.data.questions || 0);
|
|
458
458
|
if (total > 0) {
|
|
459
459
|
s = addActivity(s, `[+] Extracted ${total} signals (${update.data.governance}g, ${update.data.facts}f, ${update.data.blockers}b)`);
|
|
460
|
+
s.memoryTree = { ...s.memoryTree, loaded: false };
|
|
460
461
|
}
|
|
461
462
|
break;
|
|
462
463
|
}
|
|
@@ -691,6 +692,7 @@ function dashboardReducer(state, action) {
|
|
|
691
692
|
case "SET_MEMORY_TREE": {
|
|
692
693
|
const blocks = action.ledgerBlocks ?? state.memoryTree.ledgerBlocks;
|
|
693
694
|
const gotchas = action.storageGotchas ?? state.memoryTree.storageGotchas;
|
|
695
|
+
const facts = action.storageFacts ?? state.memoryTree.storageFacts;
|
|
694
696
|
const expanded = new Set(state.memoryTree.expandedNodes);
|
|
695
697
|
if (blocks.length > 0) expanded.add("ledger-chain");
|
|
696
698
|
if (gotchas.length > 0) expanded.add("gotchas");
|
|
@@ -702,6 +704,7 @@ function dashboardReducer(state, action) {
|
|
|
702
704
|
snapshot: action.snapshot,
|
|
703
705
|
globalPatterns: action.patterns,
|
|
704
706
|
storageGovernance: action.storageGovernance ?? state.memoryTree.storageGovernance,
|
|
707
|
+
storageFacts: facts,
|
|
705
708
|
storageGotchas: gotchas,
|
|
706
709
|
ledgerBlocks: blocks,
|
|
707
710
|
expandedNodes: expanded
|
|
@@ -967,7 +970,7 @@ function createInitialState() {
|
|
|
967
970
|
},
|
|
968
971
|
goalsPanel: { goals: [], selectedIndex: 0, selectedAchievedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningGoalId: null, scanningProgress: "" },
|
|
969
972
|
hypothesesPanel: { hypotheses: [], selectedIndex: 0, selectedCompletedIndex: 0, inputMode: "browse", inputBuffer: "", lastRefresh: 0, scanningHypothesisId: null, scanningProgress: "" },
|
|
970
|
-
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageGotchas: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
973
|
+
memoryTree: { loaded: false, snapshot: null, globalPatterns: [], storageGovernance: [], storageFacts: [], storageGotchas: [], ledgerBlocks: [], expandedNodes: /* @__PURE__ */ new Set(["decisions"]), expandedItemId: null, selectedNode: "decisions", scrollPosition: 0, lastRefresh: 0 },
|
|
971
974
|
agentBrain: { loaded: false, governance: [], patterns: [], ledgerHash: null, selectedIndex: 0, expandedIndex: null },
|
|
972
975
|
chatState: { messages: [], inputBuffer: "", loading: false, progress: null, messageQueue: [], currentSessionId: null, currentSessionTitle: null },
|
|
973
976
|
chatArchivePanel: { sessions: [], selectedIndex: 0, showArchived: false, loading: false, inputMode: "browse", inputBuffer: "" },
|
|
@@ -1171,10 +1174,27 @@ function Notification() {
|
|
|
1171
1174
|
if (!notification || !notification.active) return null;
|
|
1172
1175
|
if (notification.autoHideAt && Date.now() > notification.autoHideAt) return null;
|
|
1173
1176
|
const color = notification.severity === "critical" ? "red" : notification.severity === "warning" ? "yellow" : "blue";
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1177
|
+
const borderColor = notification.severity === "critical" ? "red" : notification.severity === "warning" ? "yellow" : "blue";
|
|
1178
|
+
return /* @__PURE__ */ jsx4(Box3, { marginY: 1, marginX: 1, children: /* @__PURE__ */ jsxs3(
|
|
1179
|
+
Box3,
|
|
1180
|
+
{
|
|
1181
|
+
borderStyle: "single",
|
|
1182
|
+
borderColor,
|
|
1183
|
+
paddingX: 2,
|
|
1184
|
+
paddingY: 1,
|
|
1185
|
+
flexDirection: "column",
|
|
1186
|
+
children: [
|
|
1187
|
+
/* @__PURE__ */ jsxs3(Text3, { wrap: "wrap", children: [
|
|
1188
|
+
/* @__PURE__ */ jsx4(Text3, { color, bold: true, children: "\u25CF " }),
|
|
1189
|
+
notification.message
|
|
1190
|
+
] }),
|
|
1191
|
+
notification.file && /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
|
|
1192
|
+
" \u2192 ",
|
|
1193
|
+
notification.file
|
|
1194
|
+
] })
|
|
1195
|
+
]
|
|
1196
|
+
}
|
|
1197
|
+
) });
|
|
1178
1198
|
}
|
|
1179
1199
|
|
|
1180
1200
|
// src/cli/dashboard/components/ConfigDialog.tsx
|
|
@@ -1966,7 +1986,7 @@ function AgentView() {
|
|
|
1966
1986
|
const { getInsightStore } = await import("./insight-store-EC4PLSAW.js");
|
|
1967
1987
|
const store = getInsightStore(workDir);
|
|
1968
1988
|
await store.dismissInsight(insight.id);
|
|
1969
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
1989
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
|
|
1970
1990
|
const storage = getStorage2(workDir);
|
|
1971
1991
|
await storage.dismissNudge(insight.id).catch(() => {
|
|
1972
1992
|
});
|
|
@@ -1978,7 +1998,7 @@ function AgentView() {
|
|
|
1978
1998
|
const clearAllNudges = useCallback(async () => {
|
|
1979
1999
|
try {
|
|
1980
2000
|
const workDir = getWorkingDirectory(void 0, true);
|
|
1981
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
2001
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
|
|
1982
2002
|
const storage = getStorage2(workDir);
|
|
1983
2003
|
await storage.clearAllNudges();
|
|
1984
2004
|
dispatch({ type: "CLEAR_ALL_INSIGHTS" });
|
|
@@ -2799,7 +2819,7 @@ function timeAgo2(iso) {
|
|
|
2799
2819
|
function MemoryTreeView() {
|
|
2800
2820
|
const { state, dispatch } = useDashboard();
|
|
2801
2821
|
const { memoryTree } = state;
|
|
2802
|
-
const { snapshot, globalPatterns, storageGovernance, storageGotchas, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
|
|
2822
|
+
const { snapshot, globalPatterns, storageGovernance, storageFacts, storageGotchas, ledgerBlocks, expandedNodes, expandedItemId, selectedNode, loaded } = memoryTree;
|
|
2803
2823
|
const { stdout } = useStdout8();
|
|
2804
2824
|
const cols = stdout?.columns || 80;
|
|
2805
2825
|
const narrow = cols < 60;
|
|
@@ -2809,14 +2829,15 @@ function MemoryTreeView() {
|
|
|
2809
2829
|
const workDir = getWorkingDirectory(void 0, true);
|
|
2810
2830
|
const graph = new ContextGraph(workDir);
|
|
2811
2831
|
const storage = new TieredStorage(workDir);
|
|
2812
|
-
const [snap, patterns, governance2, gotchas, blocks] = await Promise.all([
|
|
2832
|
+
const [snap, patterns, governance2, facts, gotchas, blocks] = await Promise.all([
|
|
2813
2833
|
graph.getSnapshot(),
|
|
2814
2834
|
findCrossProjectPatterns(2),
|
|
2815
2835
|
storage.queryGovernance({ limit: 20 }).catch(() => []),
|
|
2836
|
+
storage.queryFacts({ limit: 20 }).catch(() => []),
|
|
2816
2837
|
storage.queryGotchas({ limit: 20, resolved: false }).catch(() => []),
|
|
2817
2838
|
getLedgerBlocks(workDir).catch(() => [])
|
|
2818
2839
|
]);
|
|
2819
|
-
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageGotchas: gotchas, ledgerBlocks: blocks });
|
|
2840
|
+
dispatch({ type: "SET_MEMORY_TREE", snapshot: snap, patterns, storageGovernance: governance2, storageFacts: facts, storageGotchas: gotchas, ledgerBlocks: blocks });
|
|
2820
2841
|
} catch (err) {
|
|
2821
2842
|
dispatch({ type: "ADD_ACTIVITY", message: "Context graph load error" });
|
|
2822
2843
|
}
|
|
@@ -2887,18 +2908,13 @@ function MemoryTreeView() {
|
|
|
2887
2908
|
...n.data.reasoning != null ? { reasoning: n.data.reasoning } : {},
|
|
2888
2909
|
...n.data.outcome != null ? { outcome: n.data.outcome } : {}
|
|
2889
2910
|
}));
|
|
2890
|
-
const productGovernance = governance.filter(
|
|
2891
|
-
|
|
2892
|
-
// Longer decisions are likely product decisions
|
|
2893
|
-
);
|
|
2894
|
-
const learnedSignals = governance.filter(
|
|
2895
|
-
(g) => !productGovernance.includes(g)
|
|
2896
|
-
);
|
|
2911
|
+
const productGovernance = governance.filter((g) => g.who === "user");
|
|
2912
|
+
const learnedSignals = governance.filter((g) => g.who !== "user");
|
|
2897
2913
|
const hotspots = fileNodes.filter((n) => n.data.riskLevel === "critical" || n.data.riskLevel === "high").sort((a, b) => {
|
|
2898
2914
|
const order = { critical: 0, high: 1 };
|
|
2899
2915
|
return (order[a.data.riskLevel] ?? 2) - (order[b.data.riskLevel] ?? 2);
|
|
2900
2916
|
});
|
|
2901
|
-
const totalEntries = productGovernance.length + learnedSignals.length + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
|
|
2917
|
+
const totalEntries = productGovernance.length + learnedSignals.length + (storageFacts?.length ?? 0) + incidentNodes.length + patternNodes.length + globalPatterns.length + hotspots.length + ledgerBlocks.length;
|
|
2902
2918
|
const expandedGovernance = expandedItemId?.startsWith("decision-") ? governance.find((g) => `decision-${g.id}` === expandedItemId) : null;
|
|
2903
2919
|
const expandedIncident = expandedItemId?.startsWith("incident-") ? incidentNodes.find((n) => `incident-${n.id}` === expandedItemId) : null;
|
|
2904
2920
|
const expandedGotcha = expandedItemId?.startsWith("gotcha-") ? storageGotchas.find((g) => `gotcha-${g.id}` === expandedItemId) ?? null : null;
|
|
@@ -3164,13 +3180,13 @@ function MemoryTreeView() {
|
|
|
3164
3180
|
] })
|
|
3165
3181
|
] }, g.id);
|
|
3166
3182
|
}),
|
|
3167
|
-
renderHeader("patterns", "Learned Signals", learnedSignals.length + patternNodes.length, learnedSignals.length === 0 && patternNodes.length === 0 ? "-- Trie learns as you work" : void 0),
|
|
3183
|
+
renderHeader("patterns", "Learned Signals", learnedSignals.length + (storageFacts?.length ?? 0) + patternNodes.length, learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && patternNodes.length === 0 ? "-- Trie learns as you work" : void 0),
|
|
3168
3184
|
expandedNodes.has("patterns") && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3169
3185
|
learnedSignals.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
3170
3186
|
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3171
3187
|
" ",
|
|
3172
3188
|
" ",
|
|
3173
|
-
"Governance
|
|
3189
|
+
"Governance"
|
|
3174
3190
|
] }),
|
|
3175
3191
|
learnedSignals.slice(0, 5).map((g) => {
|
|
3176
3192
|
const descWidth = Math.max(30, contentWidth - 15);
|
|
@@ -3182,13 +3198,34 @@ function MemoryTreeView() {
|
|
|
3182
3198
|
/* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
3183
3199
|
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3184
3200
|
" ",
|
|
3185
|
-
timeAgo2(g.when)
|
|
3201
|
+
timeAgo2(g.when ?? "")
|
|
3186
3202
|
] })
|
|
3187
3203
|
] }, g.id);
|
|
3188
3204
|
})
|
|
3189
3205
|
] }),
|
|
3190
|
-
|
|
3191
|
-
|
|
3206
|
+
(storageFacts?.length ?? 0) > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: learnedSignals.length > 0 ? 1 : 0, children: [
|
|
3207
|
+
/* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3208
|
+
" ",
|
|
3209
|
+
" ",
|
|
3210
|
+
"Facts"
|
|
3211
|
+
] }),
|
|
3212
|
+
storageFacts.slice(0, 5).map((f) => {
|
|
3213
|
+
const descWidth = Math.max(30, contentWidth - 15);
|
|
3214
|
+
const desc = f.fact.length > descWidth ? f.fact.slice(0, descWidth - 3) + "..." : f.fact;
|
|
3215
|
+
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
3216
|
+
" ",
|
|
3217
|
+
/* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u25CB" }),
|
|
3218
|
+
" ",
|
|
3219
|
+
/* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
3220
|
+
narrow ? null : /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3221
|
+
" ",
|
|
3222
|
+
timeAgo2(f.when)
|
|
3223
|
+
] })
|
|
3224
|
+
] }, f.id);
|
|
3225
|
+
})
|
|
3226
|
+
] }),
|
|
3227
|
+
patternNodes.length > 0 && /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0 ? 1 : 0, children: [
|
|
3228
|
+
(learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0) && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3192
3229
|
" ",
|
|
3193
3230
|
" ",
|
|
3194
3231
|
"Patterns"
|
|
@@ -3199,9 +3236,10 @@ function MemoryTreeView() {
|
|
|
3199
3236
|
const confColor = conf > 70 ? "green" : conf > 40 ? "yellow" : void 0;
|
|
3200
3237
|
const descWidth = Math.max(30, contentWidth - 15);
|
|
3201
3238
|
const desc = n.data.description.length > descWidth ? n.data.description.slice(0, descWidth - 3) + "..." : n.data.description;
|
|
3239
|
+
const hasPreceding = learnedSignals.length > 0 || (storageFacts?.length ?? 0) > 0;
|
|
3202
3240
|
return /* @__PURE__ */ jsxs10(Text10, { wrap: "truncate", children: [
|
|
3203
|
-
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) :
|
|
3204
|
-
|
|
3241
|
+
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: "> " }) : hasPreceding ? " " : " ",
|
|
3242
|
+
!hasPreceding && " ",
|
|
3205
3243
|
n.data.isAntiPattern ? /* @__PURE__ */ jsx11(Text10, { color: "red", children: "!" }) : /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "\u25CB" }),
|
|
3206
3244
|
" ",
|
|
3207
3245
|
sel(nodeId) ? /* @__PURE__ */ jsx11(Text10, { bold: true, color: "green", children: desc }) : /* @__PURE__ */ jsx11(Text10, { children: desc }),
|
|
@@ -3218,7 +3256,7 @@ function MemoryTreeView() {
|
|
|
3218
3256
|
] }, n.id);
|
|
3219
3257
|
})
|
|
3220
3258
|
] }),
|
|
3221
|
-
patternNodes.length === 0 && learnedSignals.length === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3259
|
+
patternNodes.length === 0 && learnedSignals.length === 0 && (storageFacts?.length ?? 0) === 0 && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
|
|
3222
3260
|
" ",
|
|
3223
3261
|
" ",
|
|
3224
3262
|
"No signals learned yet. Trie will extract insights as you work."
|
|
@@ -7130,6 +7168,77 @@ var TrieQueryContextTool = class {
|
|
|
7130
7168
|
};
|
|
7131
7169
|
}
|
|
7132
7170
|
};
|
|
7171
|
+
var TrieQueryLedgerBlocksTool = class {
|
|
7172
|
+
async execute(input) {
|
|
7173
|
+
const workDir = input.directory || getWorkingDirectory(void 0, true);
|
|
7174
|
+
const analysis = input.analysis || "issues";
|
|
7175
|
+
const limit = input.limit ?? 50;
|
|
7176
|
+
const blocks = await getLedgerBlocks(workDir);
|
|
7177
|
+
const limited = blocks.slice(-limit);
|
|
7178
|
+
if (blocks.length === 0) {
|
|
7179
|
+
return {
|
|
7180
|
+
content: [{
|
|
7181
|
+
type: "text",
|
|
7182
|
+
text: "No ledger blocks found. Ledger blocks are created when issues are recorded during watch mode or scans."
|
|
7183
|
+
}]
|
|
7184
|
+
};
|
|
7185
|
+
}
|
|
7186
|
+
let output = `Ledger Chain: ${blocks.length} block(s)
|
|
7187
|
+
|
|
7188
|
+
`;
|
|
7189
|
+
if (analysis === "summary" || analysis === "all") {
|
|
7190
|
+
output += "**Block summary:**\n";
|
|
7191
|
+
for (let i = 0; i < limited.length; i++) {
|
|
7192
|
+
const b = limited[i];
|
|
7193
|
+
const critical = b.entries.filter((e) => e.severity === "critical").length;
|
|
7194
|
+
output += ` Block ${blocks.length - limited.length + i + 1}: ${b.date} \u2014 ${b.entries.length} entries (${critical} critical)
|
|
7195
|
+
`;
|
|
7196
|
+
}
|
|
7197
|
+
output += "\n";
|
|
7198
|
+
}
|
|
7199
|
+
if (analysis === "issues" || analysis === "all") {
|
|
7200
|
+
const allEntries = limited.flatMap((b) => b.entries).filter((e) => e.status !== "false-positive");
|
|
7201
|
+
const total = allEntries.length;
|
|
7202
|
+
if (total === 0) {
|
|
7203
|
+
output += "No active entries in these blocks.\n";
|
|
7204
|
+
} else {
|
|
7205
|
+
const byFile = /* @__PURE__ */ new Map();
|
|
7206
|
+
const bySeverity = /* @__PURE__ */ new Map();
|
|
7207
|
+
const byAgent = /* @__PURE__ */ new Map();
|
|
7208
|
+
for (const e of allEntries) {
|
|
7209
|
+
byFile.set(e.file, (byFile.get(e.file) || 0) + 1);
|
|
7210
|
+
bySeverity.set(e.severity, (bySeverity.get(e.severity) || 0) + 1);
|
|
7211
|
+
byAgent.set(e.agent, (byAgent.get(e.agent) || 0) + 1);
|
|
7212
|
+
}
|
|
7213
|
+
const topFiles = [...byFile.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10);
|
|
7214
|
+
const topSeverities = [...bySeverity.entries()].sort((a, b) => b[1] - a[1]);
|
|
7215
|
+
const topAgents = [...byAgent.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5);
|
|
7216
|
+
output += `**Most frequent issues across ${total} entries:**
|
|
7217
|
+
|
|
7218
|
+
`;
|
|
7219
|
+
output += "**By file:**\n";
|
|
7220
|
+
for (const [file, count] of topFiles) {
|
|
7221
|
+
const short = file.split("/").pop() || file;
|
|
7222
|
+
output += ` ${short}: ${count}
|
|
7223
|
+
`;
|
|
7224
|
+
}
|
|
7225
|
+
output += "\n**By severity:**\n";
|
|
7226
|
+
for (const [sev, count] of topSeverities) {
|
|
7227
|
+
output += ` ${sev}: ${count}
|
|
7228
|
+
`;
|
|
7229
|
+
}
|
|
7230
|
+
output += "\n**By agent:**\n";
|
|
7231
|
+
for (const [agent, count] of topAgents) {
|
|
7232
|
+
output += ` ${agent}: ${count}
|
|
7233
|
+
`;
|
|
7234
|
+
}
|
|
7235
|
+
}
|
|
7236
|
+
}
|
|
7237
|
+
return {
|
|
7238
|
+
content: [{ type: "text", text: output.trim() }]
|
|
7239
|
+
};
|
|
7240
|
+
}
|
|
7241
|
+
};
|
|
7133
7242
|
|
|
7134
7243
|
// src/tools/checkpoint.ts
|
|
7135
7244
|
async function handleCheckpointTool(input) {
|
|
@@ -7815,7 +7924,7 @@ var CHAT_TOOLS = [
|
|
|
7815
7924
|
},
|
|
7816
7925
|
{
|
|
7817
7926
|
name: "trie_get_blockers",
|
|
7818
|
-
description:
|
|
7927
|
+
description: 'Query active blockers \u2014 known problems preventing progress. NOT the same as "blocks" (ledger chain).',
|
|
7819
7928
|
input_schema: {
|
|
7820
7929
|
type: "object",
|
|
7821
7930
|
properties: {
|
|
@@ -7823,6 +7932,17 @@ var CHAT_TOOLS = [
|
|
|
7823
7932
|
}
|
|
7824
7933
|
}
|
|
7825
7934
|
},
|
|
7935
|
+
{
|
|
7936
|
+
name: "trie_query_ledger_blocks",
|
|
7937
|
+
description: 'Query the ledger chain blocks \u2014 the tamper-evident chain of recorded issues. Use when user asks about "blocks", "ledger chain", "what issues in my blocks", "most frequent issues in blocks", etc. Returns block summary and aggregation of issues by file, severity, and agent.',
|
|
7938
|
+
input_schema: {
|
|
7939
|
+
type: "object",
|
|
7940
|
+
properties: {
|
|
7941
|
+
analysis: { type: "string", enum: ["summary", "issues", "all"], description: "What to analyze: summary (block counts), issues (most frequent files/severities/agents), or all (default: issues)" },
|
|
7942
|
+
limit: { type: "number", description: "Max blocks to include (default: 50)" }
|
|
7943
|
+
}
|
|
7944
|
+
}
|
|
7945
|
+
},
|
|
7826
7946
|
{
|
|
7827
7947
|
name: "trie_query_context",
|
|
7828
7948
|
description: 'Natural-language search across ALL Trie context: goals, hypotheses, nudges (goal violations), incidents, governance, blockers, facts, and questions. Use for "what are my goals", "show hypotheses", "any nudges", "show incidents", "recent governance", etc.',
|
|
@@ -8092,6 +8212,11 @@ async function executeTool(name, input, onProgress) {
|
|
|
8092
8212
|
const result = await tool.execute(withDir);
|
|
8093
8213
|
return textFromResult(result);
|
|
8094
8214
|
}
|
|
8215
|
+
case "trie_query_ledger_blocks": {
|
|
8216
|
+
const tool = new TrieQueryLedgerBlocksTool();
|
|
8217
|
+
const result = await tool.execute(withDir);
|
|
8218
|
+
return textFromResult(result);
|
|
8219
|
+
}
|
|
8095
8220
|
case "trie_query_context": {
|
|
8096
8221
|
const tool = new TrieQueryContextTool();
|
|
8097
8222
|
const result = await tool.execute(withDir);
|
|
@@ -8624,6 +8749,7 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
|
8624
8749
|
- Check recent goal violations (nudges) in the provided project context
|
|
8625
8750
|
- Record incidents, decisions, and feedback about the codebase
|
|
8626
8751
|
- Query ALL stored context: goals, hypotheses, nudges, decisions, blockers via trie_query_context
|
|
8752
|
+
- Query ledger chain blocks (issues recorded in blocks) via trie_query_ledger_blocks \u2014 use for "blocks", "ledger chain", "most frequent issues"
|
|
8627
8753
|
- Create and manage goals and hypotheses
|
|
8628
8754
|
- Propose fixes for goal violations (requires user confirmation before spawning Claude Code)
|
|
8629
8755
|
- Run AI-powered scans to detect goal violations across the entire codebase
|
|
@@ -8635,6 +8761,10 @@ var SYSTEM_PROMPT = `You are Trie, a code assistant embedded in a terminal TUI.
|
|
|
8635
8761
|
- It uses AI analysis and is much more reliable than regex pattern matching
|
|
8636
8762
|
- You also have trie_search_files but it requires ripgrep (often not installed)
|
|
8637
8763
|
|
|
8764
|
+
**CRITICAL - "blocks" vs "blockers" (different concepts):**
|
|
8765
|
+
- **Blocks** = Ledger chain blocks (Memory \u2192 Ledger Chain). Each block has entries (recorded issues). Use trie_query_ledger_blocks when user asks about "blocks", "ledger chain", "what issues in my blocks", "most frequent issues in blocks", etc.
|
|
8766
|
+
- **Blockers** = Things preventing progress (from governance). Use trie_get_blockers when user asks about "blockers" or "what's blocking me".
|
|
8767
|
+
|
|
8638
8768
|
**When user asks "what are my goals", "show hypotheses", "any nudges", "latest decisions", etc.:**
|
|
8639
8769
|
- The project context block already includes goals, hypotheses, nudges, decisions, blockers
|
|
8640
8770
|
- If the user wants more detail or the context seems stale: Call trie_query_context with the relevant query (e.g. query: "goals", type: "goals")
|
|
@@ -9505,7 +9635,7 @@ function DashboardApp({ onReady }) {
|
|
|
9505
9635
|
const loadPersistedNudges = useCallback7(async () => {
|
|
9506
9636
|
try {
|
|
9507
9637
|
const workDir = getWorkingDirectory(void 0, true);
|
|
9508
|
-
const { getStorage: getStorage2 } = await import("./tiered-storage-
|
|
9638
|
+
const { getStorage: getStorage2 } = await import("./tiered-storage-FHHAJR4P.js");
|
|
9509
9639
|
const storage = getStorage2(workDir);
|
|
9510
9640
|
await storage.initialize();
|
|
9511
9641
|
const nudges = await storage.queryNudges({ resolved: false, limit: 50 });
|
|
@@ -11096,7 +11226,7 @@ Use \`trie_watch start\` to begin autonomous scanning.`
|
|
|
11096
11226
|
).join("\n");
|
|
11097
11227
|
let agencyStatus = "";
|
|
11098
11228
|
try {
|
|
11099
|
-
const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-
|
|
11229
|
+
const { getTrieAgent: getTrieAgent2 } = await import("./trie-agent-NYSPGZYS.js");
|
|
11100
11230
|
const trieAgent = getTrieAgent2(this.watchedDirectory || getWorkingDirectory(void 0, true));
|
|
11101
11231
|
await trieAgent.initialize();
|
|
11102
11232
|
const status = await trieAgent.getAgencyStatus();
|
|
@@ -11227,10 +11357,11 @@ export {
|
|
|
11227
11357
|
TrieGetRelatedGovernanceTool,
|
|
11228
11358
|
TrieGetRelatedDecisionsTool,
|
|
11229
11359
|
TrieQueryContextTool,
|
|
11360
|
+
TrieQueryLedgerBlocksTool,
|
|
11230
11361
|
handleCheckpointTool,
|
|
11231
11362
|
TriePipelineTool,
|
|
11232
11363
|
GitHubBranchesTool,
|
|
11233
11364
|
InteractiveDashboard,
|
|
11234
11365
|
TrieWatchTool
|
|
11235
11366
|
};
|
|
11236
|
-
//# sourceMappingURL=chunk-
|
|
11367
|
+
//# sourceMappingURL=chunk-Q4K7CFCK.js.map
|