claude-brain 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,13 +25,64 @@ export async function handleWhatIfAnalysis(
25
25
  const memory = getMemoryService()
26
26
 
27
27
  if (!memory.isChromaDBEnabled()) {
28
- return ResponseFormatter.text(
29
- `## What-If: "${change}"\n\n` +
30
- 'Unable to perform what-if analysis.\n\n' +
31
- 'Note: ChromaDB is not connected. What-if analysis requires ChromaDB for semantic search across decisions. ' +
32
- 'Decisions stored via SQLite fallback are available through recall_similar. ' +
33
- 'To enable what-if analysis, start a ChromaDB server or configure persistent mode.'
34
- )
28
+ // SQLite fallback: use searchRaw for semantic search + knowledge graph if available
29
+ const results = await memory.searchRaw(change, {
30
+ project: project_name,
31
+ limit: max_results || 10,
32
+ minSimilarity: 0.2
33
+ })
34
+
35
+ const parts: string[] = []
36
+ parts.push(`## What-If: "${change}" (SQLite)`)
37
+ parts.push('')
38
+
39
+ if (results.length === 0) {
40
+ parts.push('No related decisions found to assess impact.')
41
+ return ResponseFormatter.text(parts.join('\n'))
42
+ }
43
+
44
+ // Assess impact based on similarity
45
+ const affectedDecisions = results.map(r => {
46
+ const similarity = r.similarity || 0
47
+ const impact = similarity > 0.7 ? 'high' : similarity > 0.4 ? 'medium' : 'low'
48
+ return {
49
+ decision: r.decision?.decision || r.memory?.content?.slice(0, 150) || '',
50
+ impact,
51
+ similarity,
52
+ reason: `${Math.round(similarity * 100)}% similarity — ${r.decision?.reasoning?.slice(0, 100) || 'related context found'}`
53
+ }
54
+ })
55
+
56
+ parts.push(`Analyzed ${results.length} related decisions.\n`)
57
+
58
+ parts.push('### Affected Decisions')
59
+ for (const d of affectedDecisions) {
60
+ const icon = d.impact === 'high' ? '🔴' : d.impact === 'medium' ? '🟡' : '🟢'
61
+ parts.push(`${icon} **[${d.impact}]** ${d.decision}`)
62
+ parts.push(` *${d.reason}*`)
63
+ }
64
+
65
+ // Try knowledge graph if available
66
+ try {
67
+ const kgService = getKnowledgeGraphService()
68
+ if (kgService?.graph) {
69
+ const graphResults = await kgService.graph.search(change, { limit: 5 })
70
+ if (graphResults && graphResults.length > 0) {
71
+ const technologies = graphResults
72
+ .filter((n: any) => n.type === 'technology')
73
+ .map((n: any) => n.name || n.label)
74
+ if (technologies.length > 0) {
75
+ parts.push(`\n### Connected Technologies`)
76
+ parts.push(technologies.map((t: string) => `- ${t}`).join('\n'))
77
+ }
78
+ }
79
+ }
80
+ } catch {
81
+ // Knowledge graph not available, skip
82
+ }
83
+
84
+ const content = parts.join('\n')
85
+ return ResponseFormatter.text(withMemoryIndicator(content, results.length))
35
86
  }
36
87
 
37
88
  const kgService = getKnowledgeGraphService()