claude-brain 0.9.3 → 0.13.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.
Files changed (66) hide show
  1. package/VERSION +1 -1
  2. package/assets/CLAUDE.md +9 -1
  3. package/package.json +1 -1
  4. package/src/automation/phase12-manager.ts +456 -0
  5. package/src/automation/project-detector.ts +13 -0
  6. package/src/automation/repo-scanner.ts +205 -0
  7. package/src/cli/bin.ts +30 -0
  8. package/src/cli/commands/git-hook.ts +189 -0
  9. package/src/cli/commands/hooks.ts +8 -9
  10. package/src/cli/commands/init.ts +98 -0
  11. package/src/cli/commands/serve.ts +7 -20
  12. package/src/cli/commands/update.ts +3 -3
  13. package/src/config/defaults.ts +4 -1
  14. package/src/config/schema.ts +27 -7
  15. package/src/hooks/brain-hook.ts +8 -6
  16. package/src/hooks/capture.ts +9 -2
  17. package/src/hooks/git-capture.ts +94 -0
  18. package/src/hooks/git-hook-installer.ts +197 -0
  19. package/src/hooks/index.ts +1 -0
  20. package/src/hooks/session-tracker.ts +79 -3
  21. package/src/hooks/types.ts +1 -1
  22. package/src/intelligence/index.ts +24 -0
  23. package/src/knowledge/graph/builder.ts +26 -0
  24. package/src/memory/chroma/store.ts +18 -2
  25. package/src/memory/episodic/manager.ts +17 -0
  26. package/src/memory/index.ts +48 -18
  27. package/src/phase12/index.ts +3 -454
  28. package/src/routing/intent-classifier.ts +107 -9
  29. package/src/routing/response-filter.ts +50 -17
  30. package/src/routing/router.ts +472 -224
  31. package/src/routing/search-engine.ts +464 -0
  32. package/src/routing/types.ts +84 -0
  33. package/src/server/handlers/call-tool.ts +4 -49
  34. package/src/server/handlers/tools/analyze-decision-evolution.ts +1 -1
  35. package/src/server/handlers/tools/detect-trends.ts +1 -1
  36. package/src/server/handlers/tools/find-cross-project-patterns.ts +1 -1
  37. package/src/server/handlers/tools/get-decision-timeline.ts +2 -2
  38. package/src/server/handlers/tools/get-recommendations.ts +1 -1
  39. package/src/server/handlers/tools/index.ts +5 -7
  40. package/src/server/handlers/tools/what-if-analysis.ts +1 -1
  41. package/src/server/providers/resources.ts +195 -0
  42. package/src/server/services.ts +81 -6
  43. package/src/tools/schemas.ts +7 -329
  44. package/src/utils/phase12-helper.ts +2 -2
  45. package/src/utils/timing.ts +47 -0
  46. package/src/vault/writer.ts +22 -2
  47. /package/src/{cross-project → intelligence/cross-project}/affinity.ts +0 -0
  48. /package/src/{cross-project → intelligence/cross-project}/generalizer.ts +0 -0
  49. /package/src/{cross-project → intelligence/cross-project}/index.ts +0 -0
  50. /package/src/{cross-project → intelligence/cross-project}/transfer.ts +0 -0
  51. /package/src/{optimization → intelligence/optimization}/index.ts +0 -0
  52. /package/src/{optimization → intelligence/optimization}/precompute.ts +0 -0
  53. /package/src/{optimization → intelligence/optimization}/semantic-cache.ts +0 -0
  54. /package/src/{prediction → intelligence/prediction}/context-anticipator.ts +0 -0
  55. /package/src/{prediction → intelligence/prediction}/decision-predictor.ts +0 -0
  56. /package/src/{prediction → intelligence/prediction}/index.ts +0 -0
  57. /package/src/{prediction → intelligence/prediction}/recommender.ts +0 -0
  58. /package/src/{reasoning → intelligence/reasoning}/chain-retrieval.ts +0 -0
  59. /package/src/{reasoning → intelligence/reasoning}/counterfactual.ts +0 -0
  60. /package/src/{reasoning → intelligence/reasoning}/index.ts +0 -0
  61. /package/src/{reasoning → intelligence/reasoning}/synthesizer.ts +0 -0
  62. /package/src/{temporal → intelligence/temporal}/evolution.ts +0 -0
  63. /package/src/{temporal → intelligence/temporal}/index.ts +0 -0
  64. /package/src/{temporal → intelligence/temporal}/query-processor.ts +0 -0
  65. /package/src/{temporal → intelligence/temporal}/timeline.ts +0 -0
  66. /package/src/{temporal → intelligence/temporal}/trends.ts +0 -0
@@ -0,0 +1,464 @@
1
+ /**
2
+ * Search Engine
3
+ * Phase 19: Wires all advanced intelligence features into a unified search path.
4
+ *
5
+ * This is the core intelligence layer between the router and raw memory.
6
+ * Provides: hybrid search, semantic caching, temporal filtering, timeouts.
7
+ */
8
+
9
+ import type { Logger } from 'pino'
10
+ import type { NormalizedResult } from './types'
11
+ import { normalizeSearchResults, normalizePatternResults, normalizeCorrectionResults } from './types'
12
+ import {
13
+ getMemoryService,
14
+ getSemanticCacheService,
15
+ getRetrievalPipeline,
16
+ getKnowledgeGraphService,
17
+ getEpisodeService,
18
+ isServicesInitialized
19
+ } from '@/server/services'
20
+ import { timed } from '@/utils/timing'
21
+
22
+ /**
23
+ * Wrap a promise with a timeout. Returns fallback if the promise doesn't resolve in time.
24
+ */
25
+ function withTimeout<T>(promise: Promise<T>, ms: number, fallback: T): Promise<T> {
26
+ return Promise.race([
27
+ promise,
28
+ new Promise<T>(resolve => setTimeout(() => resolve(fallback), ms))
29
+ ])
30
+ }
31
+
32
+ const SEARCH_TIMEOUT = 5000 // 5s timeout for normal searches
33
+ const INTELLIGENCE_TIMEOUT = 12000 // 12s timeout for bulk analytical features
34
+
35
+ export class SearchEngine {
36
+ private logger: Logger
37
+
38
+ constructor(logger: Logger) {
39
+ this.logger = logger.child({ component: 'search-engine' })
40
+ }
41
+
42
+ /**
43
+ * Enhanced search — uses hybrid retrieval pipeline when available,
44
+ * falls back to plain searchRaw().
45
+ * Wraps with semantic cache for repeated queries.
46
+ */
47
+ async enhancedSearch(
48
+ query: string,
49
+ options?: { project?: string; limit?: number; minSimilarity?: number }
50
+ ): Promise<NormalizedResult[]> {
51
+ return timed('brain:search', () => this._enhancedSearchInner(query, options))
52
+ }
53
+
54
+ private async _enhancedSearchInner(
55
+ query: string,
56
+ options?: { project?: string; limit?: number; minSimilarity?: number }
57
+ ): Promise<NormalizedResult[]> {
58
+ if (!isServicesInitialized()) return []
59
+
60
+ const cacheKey = `search:${query}:${options?.project || ''}:${options?.limit || 5}`
61
+
62
+ // Check semantic cache first
63
+ const cache = getSemanticCacheService()
64
+ if (cache) {
65
+ try {
66
+ const cached = await cache.get(cacheKey)
67
+ if (cached) {
68
+ this.logger.debug({ query }, 'Search cache hit')
69
+ return cached as NormalizedResult[]
70
+ }
71
+ } catch {
72
+ // Cache miss or error, continue
73
+ }
74
+ }
75
+
76
+ // Try hybrid search via RetrievalPipeline
77
+ const pipeline = getRetrievalPipeline()
78
+ if (pipeline) {
79
+ try {
80
+ const hybridResults = await withTimeout(
81
+ pipeline.search(query, {
82
+ project: options?.project,
83
+ limit: options?.limit || 5,
84
+ minSimilarity: options?.minSimilarity || 0.3
85
+ }),
86
+ SEARCH_TIMEOUT,
87
+ []
88
+ )
89
+
90
+ if (hybridResults.length > 0) {
91
+ const normalized = hybridResults.map((r: any) => ({
92
+ id: r.id || '',
93
+ content: r.content || r.document || '',
94
+ score: r.score || r.similarity || 0,
95
+ source: 'decision' as const,
96
+ project: r.metadata?.project || options?.project || '',
97
+ date: r.metadata?.created_at || '',
98
+ metadata: r.metadata || {}
99
+ }))
100
+
101
+ // Cache results
102
+ if (cache) {
103
+ try { await cache.set(cacheKey, normalized) } catch {}
104
+ }
105
+ return normalized
106
+ }
107
+ } catch (error) {
108
+ this.logger.debug({ error }, 'Hybrid search failed, falling back to plain search')
109
+ }
110
+ }
111
+
112
+ // Fallback: plain searchRaw
113
+ return this.plainSearch(query, options, cache, cacheKey)
114
+ }
115
+
116
+ /**
117
+ * Plain search using memory.searchRaw() — always available.
118
+ */
119
+ async plainSearch(
120
+ query: string,
121
+ options?: { project?: string; limit?: number; minSimilarity?: number },
122
+ cache?: any,
123
+ cacheKey?: string
124
+ ): Promise<NormalizedResult[]> {
125
+ if (!isServicesInitialized()) return []
126
+
127
+ const memory = getMemoryService()
128
+ try {
129
+ const rawResults = await withTimeout(
130
+ memory.searchRaw(query, {
131
+ project: options?.project,
132
+ limit: options?.limit || 5,
133
+ minSimilarity: options?.minSimilarity || 0.3
134
+ }),
135
+ SEARCH_TIMEOUT,
136
+ []
137
+ )
138
+ const normalized = normalizeSearchResults(rawResults)
139
+
140
+ // Cache results
141
+ if (cache && cacheKey) {
142
+ try { await cache.set(cacheKey, normalized) } catch {}
143
+ }
144
+
145
+ return normalized
146
+ } catch {
147
+ return []
148
+ }
149
+ }
150
+
151
+ /**
152
+ * Search patterns with normalization and timeout
153
+ */
154
+ async searchPatterns(
155
+ query: string,
156
+ options?: { project?: string; limit?: number; minSimilarity?: number }
157
+ ): Promise<NormalizedResult[]> {
158
+ if (!isServicesInitialized()) return []
159
+ const memory = getMemoryService()
160
+ try {
161
+ const results = await withTimeout(
162
+ memory.searchPatterns(query, {
163
+ project: options?.project,
164
+ limit: options?.limit || 3,
165
+ minSimilarity: options?.minSimilarity || 0.3
166
+ }),
167
+ SEARCH_TIMEOUT,
168
+ []
169
+ )
170
+ return normalizePatternResults(results)
171
+ } catch {
172
+ return []
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Search corrections with normalization and timeout
178
+ */
179
+ async searchCorrections(
180
+ query: string,
181
+ options?: { project?: string; limit?: number; minSimilarity?: number }
182
+ ): Promise<NormalizedResult[]> {
183
+ if (!isServicesInitialized()) return []
184
+ const memory = getMemoryService()
185
+ try {
186
+ const results = await withTimeout(
187
+ memory.searchCorrections(query, {
188
+ project: options?.project,
189
+ limit: options?.limit || 3,
190
+ minSimilarity: options?.minSimilarity || 0.3
191
+ }),
192
+ SEARCH_TIMEOUT,
193
+ []
194
+ )
195
+ return normalizeCorrectionResults(results)
196
+ } catch {
197
+ return []
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Search knowledge graph for related concepts
203
+ */
204
+ async searchGraph(query: string, limit: number = 5): Promise<NormalizedResult[]> {
205
+ try {
206
+ const kgService = getKnowledgeGraphService()
207
+ if (!kgService?.search) return []
208
+
209
+ const graphResults = kgService.search.search({ query, limit })
210
+ if (!graphResults?.nodes?.length) return []
211
+
212
+ return graphResults.nodes.map((n: any) => ({
213
+ id: n.id || '',
214
+ content: `**${n.label || n.name}** (${n.type})${n.properties?.description ? `\n${n.properties.description}` : ''}`,
215
+ score: graphResults.scores.get(n.id) || 0.5,
216
+ source: 'graph' as const,
217
+ project: n.properties?.project || '',
218
+ date: '',
219
+ metadata: n.properties || {}
220
+ }))
221
+ } catch {
222
+ return []
223
+ }
224
+ }
225
+
226
+ /**
227
+ * Temporal search — parse temporal phrases from query, filter results by date range.
228
+ * Uses TemporalQueryProcessor when available.
229
+ */
230
+ async temporalSearch(
231
+ query: string,
232
+ options?: { project?: string; limit?: number }
233
+ ): Promise<{ results: NormalizedResult[]; cleanedQuery: string }> {
234
+ if (!isServicesInitialized()) return { results: [], cleanedQuery: query }
235
+
236
+ try {
237
+ // Dynamic import to avoid hard dependency
238
+ const { TemporalQueryProcessor } = await import('@/intelligence/temporal/query-processor')
239
+ const processor = new TemporalQueryProcessor(this.logger)
240
+ const parsed = processor.parse(query)
241
+
242
+ if (parsed.intent === 'none') {
243
+ // No temporal expressions found, use normal search
244
+ const results = await this.enhancedSearch(query, options)
245
+ return { results, cleanedQuery: query }
246
+ }
247
+
248
+ // Search with cleaned query (temporal phrases removed)
249
+ const results = await this.enhancedSearch(parsed.cleaned || query, {
250
+ ...options,
251
+ limit: (options?.limit || 5) * 2 // Fetch more since we'll filter by date
252
+ })
253
+
254
+ // Filter results by date range
255
+ const filtered = results.filter(r => {
256
+ if (!r.date) return true // Keep results without dates
257
+ const date = new Date(r.date)
258
+ if (isNaN(date.getTime())) return true
259
+ if (parsed.startDate && date < parsed.startDate) return false
260
+ if (parsed.endDate && date > parsed.endDate) return false
261
+ return true
262
+ })
263
+
264
+ return {
265
+ results: filtered.slice(0, options?.limit || 5),
266
+ cleanedQuery: parsed.cleaned || query
267
+ }
268
+ } catch {
269
+ // TemporalQueryProcessor not available, fall back
270
+ const results = await this.enhancedSearch(query, options)
271
+ return { results, cleanedQuery: query }
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Build a timeline for a topic/project
277
+ */
278
+ async buildTimeline(
279
+ options?: { project?: string; topic?: string; limit?: number }
280
+ ): Promise<any | null> {
281
+ if (!isServicesInitialized()) return null
282
+
283
+ try {
284
+ const memory = getMemoryService()
285
+ if (!memory.isChromaDBEnabled()) return null
286
+
287
+ const { TimelineBuilder } = await import('@/intelligence/temporal/timeline')
288
+ const builder = new TimelineBuilder(
289
+ this.logger,
290
+ memory.chroma.collections,
291
+ memory.chroma.embeddings
292
+ )
293
+ return await withTimeout(
294
+ builder.buildTimeline(options),
295
+ SEARCH_TIMEOUT,
296
+ null
297
+ )
298
+ } catch {
299
+ return null
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Analyze decision evolution for a topic
305
+ */
306
+ async analyzeEvolution(
307
+ topic: string,
308
+ options?: { project?: string; limit?: number }
309
+ ): Promise<any | null> {
310
+ if (!isServicesInitialized()) return null
311
+
312
+ try {
313
+ const memory = getMemoryService()
314
+ if (!memory.isChromaDBEnabled()) return null
315
+
316
+ const { DecisionEvolutionTracker } = await import('@/intelligence/temporal/evolution')
317
+ const tracker = new DecisionEvolutionTracker(
318
+ this.logger,
319
+ memory.chroma.collections,
320
+ memory.chroma.embeddings
321
+ )
322
+ return await withTimeout(
323
+ tracker.analyzeEvolution(topic, options),
324
+ INTELLIGENCE_TIMEOUT,
325
+ null
326
+ )
327
+ } catch {
328
+ return null
329
+ }
330
+ }
331
+
332
+ /**
333
+ * Detect trends
334
+ */
335
+ async detectTrends(
336
+ options?: { project?: string; periodDays?: number; limit?: number }
337
+ ): Promise<any | null> {
338
+ if (!isServicesInitialized()) return null
339
+
340
+ try {
341
+ const memory = getMemoryService()
342
+ if (!memory.isChromaDBEnabled()) return null
343
+
344
+ const { TrendDetector } = await import('@/intelligence/temporal/trends')
345
+ const detector = new TrendDetector(this.logger, memory.chroma.collections)
346
+ return await withTimeout(
347
+ detector.detectTrends(options),
348
+ INTELLIGENCE_TIMEOUT,
349
+ null
350
+ )
351
+ } catch {
352
+ return null
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Multi-hop chain retrieval for complex questions
358
+ */
359
+ async chainSearch(
360
+ query: string,
361
+ options?: { project?: string; maxHops?: number }
362
+ ): Promise<any | null> {
363
+ if (!isServicesInitialized()) return null
364
+
365
+ try {
366
+ const memory = getMemoryService()
367
+ if (!memory.isChromaDBEnabled()) return null
368
+
369
+ const { ChainRetrieval } = await import('@/intelligence/reasoning/chain-retrieval')
370
+ const chain = new ChainRetrieval(
371
+ this.logger,
372
+ memory.chroma.collections,
373
+ memory.chroma.embeddings
374
+ )
375
+ return await withTimeout(
376
+ chain.retrieve(query, {
377
+ maxHops: options?.maxHops || 3,
378
+ project: options?.project
379
+ }),
380
+ INTELLIGENCE_TIMEOUT,
381
+ null
382
+ )
383
+ } catch {
384
+ return null
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Get recommendations based on context
390
+ */
391
+ async getRecommendations(
392
+ query: string,
393
+ options?: { project?: string; limit?: number }
394
+ ): Promise<any | null> {
395
+ if (!isServicesInitialized()) return null
396
+
397
+ try {
398
+ const memory = getMemoryService()
399
+ if (!memory.isChromaDBEnabled()) return null
400
+
401
+ const { Recommender } = await import('@/intelligence/prediction/recommender')
402
+ const recommender = new Recommender(
403
+ this.logger,
404
+ memory.chroma.collections,
405
+ memory.chroma.embeddings
406
+ )
407
+ return await withTimeout(
408
+ recommender.getRecommendations(query, {
409
+ project: options?.project,
410
+ limit: options?.limit || 5
411
+ }),
412
+ INTELLIGENCE_TIMEOUT,
413
+ null
414
+ )
415
+ } catch {
416
+ return null
417
+ }
418
+ }
419
+
420
+ /**
421
+ * Find cross-project patterns
422
+ */
423
+ async findCrossProjectPatterns(
424
+ options?: { query?: string; minProjects?: number; limit?: number }
425
+ ): Promise<any | null> {
426
+ if (!isServicesInitialized()) return null
427
+
428
+ try {
429
+ const memory = getMemoryService()
430
+ if (!memory.isChromaDBEnabled()) return null
431
+
432
+ const { PatternGeneralizer } = await import('@/intelligence/cross-project/generalizer')
433
+ const generalizer = new PatternGeneralizer(
434
+ this.logger,
435
+ memory.chroma.collections,
436
+ memory.chroma.embeddings
437
+ )
438
+ return await withTimeout(
439
+ generalizer.findCrossProjectPatterns(options),
440
+ INTELLIGENCE_TIMEOUT,
441
+ null
442
+ )
443
+ } catch {
444
+ return null
445
+ }
446
+ }
447
+
448
+ /**
449
+ * Invalidate cache entries for a project after store/update/delete
450
+ */
451
+ invalidateCache(project?: string): void {
452
+ try {
453
+ const cache = getSemanticCacheService()
454
+ if (!cache) return
455
+ if (project) {
456
+ cache.invalidateProject(project)
457
+ } else {
458
+ cache.clear()
459
+ }
460
+ } catch {
461
+ // Cache not available
462
+ }
463
+ }
464
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Routing Types
3
+ * Phase 19: Normalized result types for the brain() router
4
+ *
5
+ * Eliminates scattered `r.decision?.decision || r.content?.slice(0, 300)`
6
+ * by normalizing all search results to a flat structure.
7
+ */
8
+
9
+ export interface NormalizedResult {
10
+ id: string
11
+ content: string
12
+ score: number
13
+ source: 'decision' | 'pattern' | 'correction' | 'memory' | 'graph' | 'episode' | 'cross-project'
14
+ project?: string
15
+ date?: string
16
+ metadata?: Record<string, unknown>
17
+ }
18
+
19
+ /**
20
+ * Normalize raw searchRaw() results into flat NormalizedResult[]
21
+ * Handles the nested { memory: { id }, decision: { id } } structure
22
+ */
23
+ export function normalizeSearchResults(rawResults: any[]): NormalizedResult[] {
24
+ return rawResults.map(r => {
25
+ const id = r.memory?.id || r.decision?.id || r.id || ''
26
+ const project = r.memory?.project || r.decision?.project || r.metadata?.project || ''
27
+ const date = r.memory?.createdAt || r.decision?.createdAt || r.metadata?.created_at || ''
28
+
29
+ // Prefer decision content, fall back to memory content
30
+ let content: string
31
+ if (r.decision?.decision) {
32
+ content = r.decision.decision
33
+ if (r.decision.reasoning) {
34
+ content = `**${content}**\n${r.decision.reasoning}`
35
+ }
36
+ } else if (r.memory?.content) {
37
+ content = r.memory.content
38
+ } else if (r.content) {
39
+ content = typeof r.content === 'string' ? r.content : JSON.stringify(r.content)
40
+ } else {
41
+ content = ''
42
+ }
43
+
44
+ return {
45
+ id,
46
+ content,
47
+ score: r.similarity || r.score || 0,
48
+ source: r.decision ? 'decision' as const : 'memory' as const,
49
+ project: typeof project === 'string' ? project : String(project),
50
+ date: date instanceof Date ? date.toISOString() : typeof date === 'string' ? date : '',
51
+ metadata: r.metadata || r.decision || r.memory?.metadata || {}
52
+ }
53
+ })
54
+ }
55
+
56
+ /**
57
+ * Normalize pattern search results
58
+ */
59
+ export function normalizePatternResults(results: any[]): NormalizedResult[] {
60
+ return results.map(p => ({
61
+ id: p.id || '',
62
+ content: p.metadata?.description || p.description || p.content || '',
63
+ score: p.similarity || p.score || 0,
64
+ source: 'pattern' as const,
65
+ project: p.metadata?.project || p.project || '',
66
+ date: p.metadata?.created_at || '',
67
+ metadata: p.metadata || {}
68
+ }))
69
+ }
70
+
71
+ /**
72
+ * Normalize correction search results
73
+ */
74
+ export function normalizeCorrectionResults(results: any[]): NormalizedResult[] {
75
+ return results.map(c => ({
76
+ id: c.id || '',
77
+ content: `Original: ${c.metadata?.original || c.original || ''}\nFix: ${c.metadata?.correction || c.correction || c.content || ''}`,
78
+ score: c.similarity || c.score || 0,
79
+ source: 'correction' as const,
80
+ project: c.metadata?.project || c.project || '',
81
+ date: c.metadata?.created_at || '',
82
+ metadata: c.metadata || {}
83
+ }))
84
+ }
@@ -31,23 +31,11 @@ import { handleGetCorrections } from './tools/get-corrections'
31
31
  import { handleCreateProject } from './tools/create-project'
32
32
  import { handleInitProject } from './tools/init-project'
33
33
 
34
- // Phase 13 Retrieval handlers
35
- import { handleRateMemory } from './tools/rate-memory'
36
-
37
- // Phase 14 Knowledge Graph & Episodic Memory handlers
38
- import { handleSearchKnowledgeGraph } from './tools/search-knowledge-graph'
39
- import { handleGetEpisode } from './tools/get-episode'
40
- import { handleListEpisodes } from './tools/list-episodes'
41
-
42
- // Phase 15 Advanced Intelligence & Temporal Reasoning handlers
43
- import { handleGetDecisionTimeline } from './tools/get-decision-timeline'
44
- import { handleAnalyzeDecisionEvolution } from './tools/analyze-decision-evolution'
45
- import { handleDetectTrends } from './tools/detect-trends'
46
- import { handleWhatIfAnalysis } from './tools/what-if-analysis'
47
- import { handleGetRecommendations } from './tools/get-recommendations'
48
- import { handleFindCrossProjectPatterns } from './tools/find-cross-project-patterns'
49
-
50
34
  // Phase 16 Unified Brain Tool
35
+ // Phase 19: Removed 9 redundant tool handlers (rate_memory, search_knowledge_graph,
36
+ // get_episode, list_episodes, get_decision_timeline, analyze_decision_evolution,
37
+ // detect_trends, what_if_analysis, get_recommendations, find_cross_project_patterns).
38
+ // Their functionality is now absorbed into brain().
51
39
  import { handleBrain } from './tools/brain'
52
40
 
53
41
  /**
@@ -134,39 +122,6 @@ export async function handleCallTool(
134
122
  case 'get_corrections':
135
123
  return await handleGetCorrections(args, logger)
136
124
 
137
- // Phase 13 Retrieval Tools
138
- case 'rate_memory':
139
- return await handleRateMemory(args, logger)
140
-
141
- // Phase 14 Knowledge Graph & Episodic Memory Tools
142
- case 'search_knowledge_graph':
143
- return await handleSearchKnowledgeGraph(args, logger)
144
-
145
- case 'get_episode':
146
- return await handleGetEpisode(args, logger)
147
-
148
- case 'list_episodes':
149
- return await handleListEpisodes(args, logger)
150
-
151
- // Phase 15 Advanced Intelligence & Temporal Reasoning Tools
152
- case 'get_decision_timeline':
153
- return await handleGetDecisionTimeline(args, logger)
154
-
155
- case 'analyze_decision_evolution':
156
- return await handleAnalyzeDecisionEvolution(args, logger)
157
-
158
- case 'detect_trends':
159
- return await handleDetectTrends(args, logger)
160
-
161
- case 'what_if_analysis':
162
- return await handleWhatIfAnalysis(args, logger)
163
-
164
- case 'get_recommendations':
165
- return await handleGetRecommendations(args, logger)
166
-
167
- case 'find_cross_project_patterns':
168
- return await handleFindCrossProjectPatterns(args, logger)
169
-
170
125
  // Phase 16 Unified Brain Tool
171
126
  case 'brain':
172
127
  return await handleBrain(args, logger)
@@ -12,7 +12,7 @@ import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-in
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { AnalyzeDecisionEvolutionSchema } from './schemas'
15
- import { DecisionEvolutionTracker } from '@/temporal/evolution'
15
+ import { DecisionEvolutionTracker } from '@/intelligence/temporal/evolution'
16
16
 
17
17
  export async function handleAnalyzeDecisionEvolution(
18
18
  args: unknown,
@@ -12,7 +12,7 @@ import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-in
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { DetectTrendsSchema } from './schemas'
15
- import { TrendDetector } from '@/temporal/trends'
15
+ import { TrendDetector } from '@/intelligence/temporal/trends'
16
16
 
17
17
  export async function handleDetectTrends(
18
18
  args: unknown,
@@ -12,7 +12,7 @@ import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-in
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { FindCrossProjectPatternsSchema } from './schemas'
15
- import { PatternGeneralizer } from '@/cross-project/generalizer'
15
+ import { PatternGeneralizer } from '@/intelligence/cross-project/generalizer'
16
16
 
17
17
  export async function handleFindCrossProjectPatterns(
18
18
  args: unknown,
@@ -12,8 +12,8 @@ import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-in
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { GetDecisionTimelineSchema } from './schemas'
15
- import { TimelineBuilder } from '@/temporal/timeline'
16
- import { TemporalQueryProcessor } from '@/temporal/query-processor'
15
+ import { TimelineBuilder } from '@/intelligence/temporal/timeline'
16
+ import { TemporalQueryProcessor } from '@/intelligence/temporal/query-processor'
17
17
 
18
18
  export async function handleGetDecisionTimeline(
19
19
  args: unknown,
@@ -12,7 +12,7 @@ import { withMemoryIndicator, formatMemoryStats } from '@/server/utils/memory-in
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { GetRecommendationsSchema } from './schemas'
15
- import { Recommender } from '@/prediction/recommender'
15
+ import { Recommender } from '@/intelligence/prediction/recommender'
16
16
 
17
17
  export async function handleGetRecommendations(
18
18
  args: unknown,
@@ -24,10 +24,8 @@ export { handleGetCorrections } from './get-corrections'
24
24
  export { handleCreateProject } from './create-project'
25
25
  export { handleInitProject } from './init-project'
26
26
 
27
- // Phase 15 - Advanced Intelligence & Temporal Reasoning
28
- export { handleGetDecisionTimeline } from './get-decision-timeline'
29
- export { handleAnalyzeDecisionEvolution } from './analyze-decision-evolution'
30
- export { handleDetectTrends } from './detect-trends'
31
- export { handleWhatIfAnalysis } from './what-if-analysis'
32
- export { handleGetRecommendations } from './get-recommendations'
33
- export { handleFindCrossProjectPatterns } from './find-cross-project-patterns'
27
+ // Phase 19: Removed 9 redundant tool exports.
28
+ // rate_memory, search_knowledge_graph, get_episode, list_episodes,
29
+ // get_decision_timeline, analyze_decision_evolution, detect_trends,
30
+ // what_if_analysis, get_recommendations, find_cross_project_patterns
31
+ // are now absorbed into brain(). Handler files kept for reference.
@@ -12,7 +12,7 @@ import { withMemoryIndicator } from '@/server/utils/memory-indicator'
12
12
  import { ErrorHandler } from '@/server/utils/error-handler'
13
13
  import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
14
14
  import { WhatIfAnalysisSchema } from './schemas'
15
- import { CounterfactualAnalyzer } from '@/reasoning/counterfactual'
15
+ import { CounterfactualAnalyzer } from '@/intelligence/reasoning/counterfactual'
16
16
 
17
17
  export async function handleWhatIfAnalysis(
18
18
  args: unknown,