claude-brain 0.15.2 → 0.16.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.
- package/README.md +191 -191
- package/VERSION +1 -1
- package/assets/CLAUDE-unified.md +11 -11
- package/assets/CLAUDE.md +29 -11
- package/bunfig.toml +8 -8
- package/package.json +82 -82
- package/packs/backend/node.json +173 -173
- package/packs/core/javascript.json +176 -176
- package/packs/core/typescript.json +222 -222
- package/packs/frontend/react.json +254 -254
- package/packs/meta/testing.json +172 -172
- package/scripts/postinstall.mjs +341 -341
- package/src/automation/auto-context.ts +240 -240
- package/src/automation/decision-detector.ts +452 -452
- package/src/automation/index.ts +11 -11
- package/src/automation/phase12-manager.ts +456 -456
- package/src/automation/proactive-recall.ts +373 -373
- package/src/automation/project-detector.ts +310 -310
- package/src/automation/repo-scanner.ts +205 -205
- package/src/cli/auto-setup.ts +82 -82
- package/src/cli/bin.ts +209 -202
- package/src/cli/commands/chroma.ts +573 -573
- package/src/cli/commands/git-hook.ts +189 -189
- package/src/cli/commands/hooks.ts +213 -213
- package/src/cli/commands/init.ts +122 -122
- package/src/cli/commands/install-mcp.ts +92 -92
- package/src/cli/commands/pack.ts +197 -197
- package/src/cli/commands/refresh.ts +323 -0
- package/src/cli/commands/serve.ts +167 -173
- package/src/cli/commands/start.ts +42 -42
- package/src/cli/commands/uninstall-mcp.ts +41 -41
- package/src/cli/commands/update.ts +124 -121
- package/src/cli/diagnose.ts +4 -4
- package/src/cli/health-check.ts +4 -4
- package/src/cli/migrate-chroma.ts +106 -106
- package/src/cli/setup.ts +4 -4
- package/src/cli/ui/animations.ts +80 -80
- package/src/cli/ui/components.ts +82 -82
- package/src/cli/ui/index.ts +4 -4
- package/src/cli/ui/logo.ts +36 -36
- package/src/cli/ui/theme.ts +55 -55
- package/src/config/defaults.ts +50 -50
- package/src/config/home.ts +55 -55
- package/src/config/index.ts +7 -7
- package/src/config/loader.ts +166 -166
- package/src/config/migration.ts +76 -76
- package/src/config/schema.ts +360 -360
- package/src/config/validator.ts +184 -184
- package/src/config/watcher.ts +86 -86
- package/src/context/assembler.ts +398 -398
- package/src/context/cache-manager.ts +101 -101
- package/src/context/formatter.ts +84 -84
- package/src/context/hierarchy.ts +85 -85
- package/src/context/index.ts +83 -83
- package/src/context/progress-tracker.ts +174 -174
- package/src/context/standards-manager.ts +287 -287
- package/src/context/types.ts +252 -252
- package/src/context/validator.ts +58 -58
- package/src/diagnostics/index.ts +123 -123
- package/src/health/index.ts +229 -229
- package/src/hooks/brain-hook.ts +128 -112
- package/src/hooks/capture.ts +168 -205
- package/src/hooks/deduplicator.ts +72 -72
- package/src/hooks/git-capture.ts +109 -109
- package/src/hooks/git-hook-installer.ts +207 -207
- package/src/hooks/index.ts +20 -20
- package/src/hooks/installer.ts +194 -194
- package/src/hooks/passive-classifier.ts +404 -723
- package/src/hooks/queue.ts +129 -129
- package/src/hooks/session-tracker.ts +312 -275
- package/src/hooks/types.ts +47 -47
- package/src/index.ts +7 -7
- package/src/intelligence/cross-project/affinity.ts +162 -162
- package/src/intelligence/cross-project/generalizer.ts +283 -283
- package/src/intelligence/cross-project/index.ts +13 -13
- package/src/intelligence/cross-project/transfer.ts +201 -201
- package/src/intelligence/index.ts +24 -24
- package/src/intelligence/optimization/index.ts +10 -10
- package/src/intelligence/optimization/precompute.ts +202 -202
- package/src/intelligence/optimization/semantic-cache.ts +207 -207
- package/src/intelligence/prediction/context-anticipator.ts +198 -198
- package/src/intelligence/prediction/decision-predictor.ts +184 -184
- package/src/intelligence/prediction/index.ts +13 -13
- package/src/intelligence/prediction/recommender.ts +268 -268
- package/src/intelligence/reasoning/chain-retrieval.ts +247 -247
- package/src/intelligence/reasoning/counterfactual.ts +248 -248
- package/src/intelligence/reasoning/index.ts +13 -13
- package/src/intelligence/reasoning/synthesizer.ts +169 -169
- package/src/intelligence/temporal/evolution.ts +197 -197
- package/src/intelligence/temporal/index.ts +16 -16
- package/src/intelligence/temporal/query-processor.ts +190 -190
- package/src/intelligence/temporal/timeline.ts +259 -259
- package/src/intelligence/temporal/trends.ts +263 -263
- package/src/knowledge/entity-extractor.ts +416 -416
- package/src/knowledge/graph/builder.ts +185 -185
- package/src/knowledge/graph/linker.ts +201 -201
- package/src/knowledge/graph/memory-graph.ts +359 -359
- package/src/knowledge/graph/schema.ts +99 -99
- package/src/knowledge/graph/search.ts +168 -168
- package/src/knowledge/relationship-extractor.ts +108 -108
- package/src/memory/chroma/client.ts +174 -174
- package/src/memory/chroma/collection-manager.ts +94 -94
- package/src/memory/chroma/config.ts +57 -57
- package/src/memory/chroma/embeddings.ts +155 -155
- package/src/memory/chroma/index.ts +82 -82
- package/src/memory/chroma/migration.ts +270 -270
- package/src/memory/chroma/schemas.ts +69 -69
- package/src/memory/chroma/search.ts +315 -315
- package/src/memory/chroma/store.ts +741 -741
- package/src/memory/consolidation/archiver.ts +164 -164
- package/src/memory/consolidation/merger.ts +186 -186
- package/src/memory/consolidation/scorer.ts +138 -138
- package/src/memory/context-builder.ts +236 -236
- package/src/memory/database.ts +169 -169
- package/src/memory/embedding-utils.ts +156 -156
- package/src/memory/embeddings.ts +226 -226
- package/src/memory/episodic/detector.ts +108 -108
- package/src/memory/episodic/manager.ts +351 -351
- package/src/memory/episodic/summarizer.ts +179 -179
- package/src/memory/episodic/types.ts +52 -52
- package/src/memory/index.ts +582 -582
- package/src/memory/knowledge-extractor.ts +455 -455
- package/src/memory/learning.ts +378 -378
- package/src/memory/patterns.ts +396 -396
- package/src/memory/schema.ts +88 -88
- package/src/memory/search.ts +309 -309
- package/src/memory/store.ts +787 -787
- package/src/memory/types.ts +121 -121
- package/src/orchestrator/coordinator.ts +272 -272
- package/src/orchestrator/decision-logger.ts +228 -228
- package/src/orchestrator/event-emitter.ts +198 -198
- package/src/orchestrator/event-queue.ts +184 -184
- package/src/orchestrator/handlers/base-handler.ts +70 -70
- package/src/orchestrator/handlers/context-handler.ts +73 -73
- package/src/orchestrator/handlers/decision-handler.ts +204 -204
- package/src/orchestrator/handlers/index.ts +10 -10
- package/src/orchestrator/handlers/status-handler.ts +131 -131
- package/src/orchestrator/handlers/task-handler.ts +171 -171
- package/src/orchestrator/index.ts +275 -275
- package/src/orchestrator/task-parser.ts +284 -284
- package/src/orchestrator/types.ts +98 -98
- package/src/packs/index.ts +9 -9
- package/src/packs/loader.ts +134 -134
- package/src/packs/manager.ts +204 -204
- package/src/packs/ranker.ts +78 -78
- package/src/packs/types.ts +81 -81
- package/src/phase12/index.ts +5 -5
- package/src/retrieval/bm25/index.ts +300 -300
- package/src/retrieval/bm25/tokenizer.ts +184 -184
- package/src/retrieval/feedback/adaptive.ts +223 -223
- package/src/retrieval/feedback/index.ts +16 -16
- package/src/retrieval/feedback/metrics.ts +223 -223
- package/src/retrieval/feedback/store.ts +283 -283
- package/src/retrieval/fusion/index.ts +194 -194
- package/src/retrieval/fusion/rrf.ts +163 -163
- package/src/retrieval/index.ts +12 -12
- package/src/retrieval/pipeline.ts +375 -375
- package/src/retrieval/query/expander.ts +198 -198
- package/src/retrieval/query/index.ts +27 -27
- package/src/retrieval/query/intent-classifier.ts +236 -236
- package/src/retrieval/query/temporal-parser.ts +295 -295
- package/src/retrieval/reranker/index.ts +188 -188
- package/src/retrieval/reranker/model.ts +95 -95
- package/src/retrieval/service.ts +125 -125
- package/src/retrieval/types.ts +162 -162
- package/src/routing/entity-extractor.ts +428 -428
- package/src/routing/intent-classifier.ts +450 -436
- package/src/routing/response-filter.ts +261 -258
- package/src/routing/router.ts +1441 -1322
- package/src/routing/search-engine.ts +515 -475
- package/src/routing/types.ts +94 -94
- package/src/scripts/health-check.ts +118 -118
- package/src/scripts/setup.ts +122 -122
- package/src/server/handlers/call-tool.ts +156 -156
- package/src/server/handlers/index.ts +9 -9
- package/src/server/handlers/list-tools.ts +35 -35
- package/src/server/handlers/tools/analyze-decision-evolution.ts +151 -151
- package/src/server/handlers/tools/auto-remember.ts +200 -200
- package/src/server/handlers/tools/brain.ts +85 -85
- package/src/server/handlers/tools/create-project.ts +135 -135
- package/src/server/handlers/tools/detect-trends.ts +144 -144
- package/src/server/handlers/tools/find-cross-project-patterns.ts +168 -168
- package/src/server/handlers/tools/get-activity-log.ts +194 -194
- package/src/server/handlers/tools/get-code-standards.ts +124 -124
- package/src/server/handlers/tools/get-corrections.ts +154 -154
- package/src/server/handlers/tools/get-decision-timeline.ts +172 -172
- package/src/server/handlers/tools/get-episode.ts +103 -103
- package/src/server/handlers/tools/get-patterns.ts +158 -158
- package/src/server/handlers/tools/get-phase12-status.ts +63 -63
- package/src/server/handlers/tools/get-project-context.ts +75 -75
- package/src/server/handlers/tools/get-recommendations.ts +145 -145
- package/src/server/handlers/tools/index.ts +31 -31
- package/src/server/handlers/tools/init-project.ts +757 -757
- package/src/server/handlers/tools/list-episodes.ts +90 -90
- package/src/server/handlers/tools/list-projects.ts +125 -125
- package/src/server/handlers/tools/rate-memory.ts +101 -101
- package/src/server/handlers/tools/recall-similar.ts +87 -87
- package/src/server/handlers/tools/recognize-pattern.ts +126 -126
- package/src/server/handlers/tools/record-correction.ts +125 -125
- package/src/server/handlers/tools/remember-decision.ts +153 -153
- package/src/server/handlers/tools/schemas.ts +253 -253
- package/src/server/handlers/tools/search-knowledge-graph.ts +102 -102
- package/src/server/handlers/tools/smart-context.ts +146 -146
- package/src/server/handlers/tools/update-progress.ts +131 -131
- package/src/server/handlers/tools/what-if-analysis.ts +135 -135
- package/src/server/http-api.ts +693 -693
- package/src/server/index.ts +40 -40
- package/src/server/mcp-server.ts +283 -283
- package/src/server/providers/index.ts +7 -7
- package/src/server/providers/prompts.ts +327 -327
- package/src/server/providers/resources.ts +622 -622
- package/src/server/services.ts +468 -468
- package/src/server/types.ts +39 -39
- package/src/server/utils/error-handler.ts +155 -155
- package/src/server/utils/index.ts +13 -13
- package/src/server/utils/memory-indicator.ts +83 -83
- package/src/server/utils/request-context.ts +122 -122
- package/src/server/utils/response-formatter.ts +129 -129
- package/src/server/utils/validators.ts +210 -210
- package/src/setup/index.ts +48 -48
- package/src/setup/wizard.ts +461 -461
- package/src/tools/index.ts +24 -24
- package/src/tools/registry.ts +115 -115
- package/src/tools/schemas.test.ts +30 -30
- package/src/tools/schemas.ts +617 -617
- package/src/tools/types.ts +412 -412
- package/src/utils/circuit-breaker.ts +130 -130
- package/src/utils/cleanup.ts +34 -34
- package/src/utils/error-handler.ts +132 -132
- package/src/utils/error-messages.ts +60 -60
- package/src/utils/fallback.ts +45 -45
- package/src/utils/index.ts +54 -54
- package/src/utils/logger-utils.ts +80 -80
- package/src/utils/logger.ts +88 -88
- package/src/utils/phase12-helper.ts +56 -56
- package/src/utils/retry.ts +94 -94
- package/src/utils/timing.ts +47 -47
- package/src/utils/transaction.ts +63 -63
- package/src/vault/frontmatter.ts +264 -264
- package/src/vault/index.ts +318 -318
- package/src/vault/paths.ts +106 -106
- package/src/vault/query.ts +422 -422
- package/src/vault/reader.ts +264 -264
- package/src/vault/templates.ts +186 -186
- package/src/vault/types.ts +73 -73
- package/src/vault/watcher.ts +277 -277
- package/src/vault/writer.ts +413 -413
- package/tsconfig.json +30 -30
- package/src/cli/auto-update.ts +0 -157
|
@@ -1,194 +1,194 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get Activity Log Handler
|
|
3
|
-
* Shows recent Claude Brain activity - tool calls, memories saved/recalled
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { ToolResponse } from '@/tools/types'
|
|
8
|
-
import { getMemoryService, getPhase12Service, isServicesInitialized } from '@/server/services'
|
|
9
|
-
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
10
|
-
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
11
|
-
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
12
|
-
|
|
13
|
-
// In-memory activity log (persists during server lifetime)
|
|
14
|
-
interface ActivityEntry {
|
|
15
|
-
timestamp: Date
|
|
16
|
-
type: 'tool_call' | 'memory_saved' | 'memory_recalled' | 'project_loaded' | 'decision_detected'
|
|
17
|
-
tool?: string
|
|
18
|
-
project?: string
|
|
19
|
-
details: string
|
|
20
|
-
memoryId?: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Singleton activity log
|
|
24
|
-
const activityLog: ActivityEntry[] = []
|
|
25
|
-
const MAX_LOG_ENTRIES = 100
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Add entry to activity log (called by other handlers)
|
|
29
|
-
*/
|
|
30
|
-
export function logActivity(entry: Omit<ActivityEntry, 'timestamp'>) {
|
|
31
|
-
activityLog.unshift({
|
|
32
|
-
...entry,
|
|
33
|
-
timestamp: new Date()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
// Keep only recent entries
|
|
37
|
-
if (activityLog.length > MAX_LOG_ENTRIES) {
|
|
38
|
-
activityLog.pop()
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Get recent activity log
|
|
44
|
-
*/
|
|
45
|
-
export function getRecentActivity(limit: number = 20): ActivityEntry[] {
|
|
46
|
-
return activityLog.slice(0, limit)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
interface GetActivityLogInput {
|
|
50
|
-
limit?: number
|
|
51
|
-
type_filter?: 'tool_call' | 'memory_saved' | 'memory_recalled' | 'project_loaded' | 'decision_detected' | 'all'
|
|
52
|
-
project_filter?: string
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export async function handleGetActivityLog(
|
|
56
|
-
args: unknown,
|
|
57
|
-
logger: Logger
|
|
58
|
-
): Promise<ToolResponse> {
|
|
59
|
-
try {
|
|
60
|
-
const input = args as GetActivityLogInput
|
|
61
|
-
const {
|
|
62
|
-
limit = 20,
|
|
63
|
-
type_filter = 'all',
|
|
64
|
-
project_filter
|
|
65
|
-
} = input
|
|
66
|
-
|
|
67
|
-
logger.debug({ limit, type_filter, project_filter }, 'Getting activity log')
|
|
68
|
-
|
|
69
|
-
if (!isServicesInitialized()) {
|
|
70
|
-
throw new McpError(
|
|
71
|
-
ErrorCode.InternalError,
|
|
72
|
-
'Services not initialized'
|
|
73
|
-
)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Get memory stats
|
|
77
|
-
const memory = getMemoryService()
|
|
78
|
-
const phase12 = getPhase12Service()
|
|
79
|
-
const dbStats = memory.database.getStats()
|
|
80
|
-
|
|
81
|
-
// Filter activity
|
|
82
|
-
let filtered = activityLog
|
|
83
|
-
|
|
84
|
-
if (type_filter !== 'all') {
|
|
85
|
-
filtered = filtered.filter(e => e.type === type_filter)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (project_filter) {
|
|
89
|
-
filtered = filtered.filter(e => e.project === project_filter)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const entries = filtered.slice(0, limit)
|
|
93
|
-
|
|
94
|
-
// Build response
|
|
95
|
-
const parts: string[] = []
|
|
96
|
-
parts.push(`## 📊 Claude Brain Activity Log\n`)
|
|
97
|
-
|
|
98
|
-
// Stats section
|
|
99
|
-
parts.push(`### Database Stats`)
|
|
100
|
-
parts.push(`- **Total Memories:** ${dbStats.totalMemories}`)
|
|
101
|
-
parts.push(`- **Total Projects:** ${dbStats.totalProjects}`)
|
|
102
|
-
parts.push(`- **Database Size:** ${formatBytes(dbStats.databaseSize)}`)
|
|
103
|
-
parts.push(`- **Server Uptime:** This session\n`)
|
|
104
|
-
|
|
105
|
-
// Phase 12 status
|
|
106
|
-
const phase12Status = phase12.getStatus()
|
|
107
|
-
parts.push(`### Phase 12 Status`)
|
|
108
|
-
parts.push(`- **Current Project:** ${phase12Status.currentProject || 'None detected'}`)
|
|
109
|
-
parts.push(`- **Patterns Detected:** ${phase12Status.patternsDetected}`)
|
|
110
|
-
parts.push(`- **Decisions Auto-Saved:** ${phase12Status.decisionsAutoSaved}`)
|
|
111
|
-
parts.push(`- **Proactive Recalls:** ${phase12Status.proactiveRecalls}\n`)
|
|
112
|
-
|
|
113
|
-
// Recent activity
|
|
114
|
-
parts.push(`### Recent Activity (${entries.length} entries)`)
|
|
115
|
-
|
|
116
|
-
if (entries.length === 0) {
|
|
117
|
-
parts.push(`\n*No activity recorded yet this session.*`)
|
|
118
|
-
parts.push(`\n**Tip:** Activity is logged when you:`)
|
|
119
|
-
parts.push(`- Call tools like \`remember_decision\`, \`recall_similar\``)
|
|
120
|
-
parts.push(`- Use \`init_project\` or \`smart_context\``)
|
|
121
|
-
parts.push(`- Auto-detect decisions with \`auto_remember\``)
|
|
122
|
-
} else {
|
|
123
|
-
parts.push('')
|
|
124
|
-
for (const entry of entries) {
|
|
125
|
-
const time = entry.timestamp.toLocaleTimeString()
|
|
126
|
-
const icon = getActivityIcon(entry.type)
|
|
127
|
-
|
|
128
|
-
let line = `**${time}** ${icon} `
|
|
129
|
-
|
|
130
|
-
switch (entry.type) {
|
|
131
|
-
case 'memory_saved':
|
|
132
|
-
line += `Memory saved${entry.project ? ` [${entry.project}]` : ''}`
|
|
133
|
-
if (entry.memoryId) line += ` (ID: ${entry.memoryId.slice(0, 8)}...)`
|
|
134
|
-
break
|
|
135
|
-
case 'memory_recalled':
|
|
136
|
-
line += `Memory recalled${entry.project ? ` [${entry.project}]` : ''}`
|
|
137
|
-
break
|
|
138
|
-
case 'tool_call':
|
|
139
|
-
line += `Tool: \`${entry.tool}\`${entry.project ? ` [${entry.project}]` : ''}`
|
|
140
|
-
break
|
|
141
|
-
case 'project_loaded':
|
|
142
|
-
line += `Project loaded: ${entry.project}`
|
|
143
|
-
break
|
|
144
|
-
case 'decision_detected':
|
|
145
|
-
line += `Decision detected${entry.project ? ` [${entry.project}]` : ''}`
|
|
146
|
-
break
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
parts.push(line)
|
|
150
|
-
if (entry.details) {
|
|
151
|
-
parts.push(` └─ ${entry.details.slice(0, 80)}${entry.details.length > 80 ? '...' : ''}`)
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// How to use section
|
|
157
|
-
parts.push(`\n### How Memory Works`)
|
|
158
|
-
parts.push(`1. **Save:** \`remember_decision\` or \`auto_remember\` stores to DB + vault`)
|
|
159
|
-
parts.push(`2. **Recall:** \`recall_similar\` or \`smart_context\` searches semantically`)
|
|
160
|
-
parts.push(`3. **View:** \`get_activity_log\` shows this log`)
|
|
161
|
-
parts.push(`\n*Activity log resets when MCP server restarts.*`)
|
|
162
|
-
|
|
163
|
-
return ResponseFormatter.text(parts.join('\n'))
|
|
164
|
-
|
|
165
|
-
} catch (error) {
|
|
166
|
-
ErrorHandler.logError(logger, error, { tool: 'get_activity_log', args })
|
|
167
|
-
|
|
168
|
-
if (error instanceof McpError) {
|
|
169
|
-
throw error
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
throw new McpError(
|
|
173
|
-
ErrorCode.InternalError,
|
|
174
|
-
`Failed to get activity log: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
175
|
-
)
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function getActivityIcon(type: ActivityEntry['type']): string {
|
|
180
|
-
switch (type) {
|
|
181
|
-
case 'memory_saved': return '💾'
|
|
182
|
-
case 'memory_recalled': return '🔍'
|
|
183
|
-
case 'tool_call': return '🔧'
|
|
184
|
-
case 'project_loaded': return '📂'
|
|
185
|
-
case 'decision_detected': return '💡'
|
|
186
|
-
default: return '•'
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function formatBytes(bytes: number): string {
|
|
191
|
-
if (bytes < 1024) return `${bytes} B`
|
|
192
|
-
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
|
|
193
|
-
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
|
|
194
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Get Activity Log Handler
|
|
3
|
+
* Shows recent Claude Brain activity - tool calls, memories saved/recalled
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { ToolResponse } from '@/tools/types'
|
|
8
|
+
import { getMemoryService, getPhase12Service, isServicesInitialized } from '@/server/services'
|
|
9
|
+
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
10
|
+
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
11
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
12
|
+
|
|
13
|
+
// In-memory activity log (persists during server lifetime)
|
|
14
|
+
interface ActivityEntry {
|
|
15
|
+
timestamp: Date
|
|
16
|
+
type: 'tool_call' | 'memory_saved' | 'memory_recalled' | 'project_loaded' | 'decision_detected'
|
|
17
|
+
tool?: string
|
|
18
|
+
project?: string
|
|
19
|
+
details: string
|
|
20
|
+
memoryId?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Singleton activity log
|
|
24
|
+
const activityLog: ActivityEntry[] = []
|
|
25
|
+
const MAX_LOG_ENTRIES = 100
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Add entry to activity log (called by other handlers)
|
|
29
|
+
*/
|
|
30
|
+
export function logActivity(entry: Omit<ActivityEntry, 'timestamp'>) {
|
|
31
|
+
activityLog.unshift({
|
|
32
|
+
...entry,
|
|
33
|
+
timestamp: new Date()
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
// Keep only recent entries
|
|
37
|
+
if (activityLog.length > MAX_LOG_ENTRIES) {
|
|
38
|
+
activityLog.pop()
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get recent activity log
|
|
44
|
+
*/
|
|
45
|
+
export function getRecentActivity(limit: number = 20): ActivityEntry[] {
|
|
46
|
+
return activityLog.slice(0, limit)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface GetActivityLogInput {
|
|
50
|
+
limit?: number
|
|
51
|
+
type_filter?: 'tool_call' | 'memory_saved' | 'memory_recalled' | 'project_loaded' | 'decision_detected' | 'all'
|
|
52
|
+
project_filter?: string
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function handleGetActivityLog(
|
|
56
|
+
args: unknown,
|
|
57
|
+
logger: Logger
|
|
58
|
+
): Promise<ToolResponse> {
|
|
59
|
+
try {
|
|
60
|
+
const input = args as GetActivityLogInput
|
|
61
|
+
const {
|
|
62
|
+
limit = 20,
|
|
63
|
+
type_filter = 'all',
|
|
64
|
+
project_filter
|
|
65
|
+
} = input
|
|
66
|
+
|
|
67
|
+
logger.debug({ limit, type_filter, project_filter }, 'Getting activity log')
|
|
68
|
+
|
|
69
|
+
if (!isServicesInitialized()) {
|
|
70
|
+
throw new McpError(
|
|
71
|
+
ErrorCode.InternalError,
|
|
72
|
+
'Services not initialized'
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Get memory stats
|
|
77
|
+
const memory = getMemoryService()
|
|
78
|
+
const phase12 = getPhase12Service()
|
|
79
|
+
const dbStats = memory.database.getStats()
|
|
80
|
+
|
|
81
|
+
// Filter activity
|
|
82
|
+
let filtered = activityLog
|
|
83
|
+
|
|
84
|
+
if (type_filter !== 'all') {
|
|
85
|
+
filtered = filtered.filter(e => e.type === type_filter)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (project_filter) {
|
|
89
|
+
filtered = filtered.filter(e => e.project === project_filter)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const entries = filtered.slice(0, limit)
|
|
93
|
+
|
|
94
|
+
// Build response
|
|
95
|
+
const parts: string[] = []
|
|
96
|
+
parts.push(`## 📊 Claude Brain Activity Log\n`)
|
|
97
|
+
|
|
98
|
+
// Stats section
|
|
99
|
+
parts.push(`### Database Stats`)
|
|
100
|
+
parts.push(`- **Total Memories:** ${dbStats.totalMemories}`)
|
|
101
|
+
parts.push(`- **Total Projects:** ${dbStats.totalProjects}`)
|
|
102
|
+
parts.push(`- **Database Size:** ${formatBytes(dbStats.databaseSize)}`)
|
|
103
|
+
parts.push(`- **Server Uptime:** This session\n`)
|
|
104
|
+
|
|
105
|
+
// Phase 12 status
|
|
106
|
+
const phase12Status = phase12.getStatus()
|
|
107
|
+
parts.push(`### Phase 12 Status`)
|
|
108
|
+
parts.push(`- **Current Project:** ${phase12Status.currentProject || 'None detected'}`)
|
|
109
|
+
parts.push(`- **Patterns Detected:** ${phase12Status.patternsDetected}`)
|
|
110
|
+
parts.push(`- **Decisions Auto-Saved:** ${phase12Status.decisionsAutoSaved}`)
|
|
111
|
+
parts.push(`- **Proactive Recalls:** ${phase12Status.proactiveRecalls}\n`)
|
|
112
|
+
|
|
113
|
+
// Recent activity
|
|
114
|
+
parts.push(`### Recent Activity (${entries.length} entries)`)
|
|
115
|
+
|
|
116
|
+
if (entries.length === 0) {
|
|
117
|
+
parts.push(`\n*No activity recorded yet this session.*`)
|
|
118
|
+
parts.push(`\n**Tip:** Activity is logged when you:`)
|
|
119
|
+
parts.push(`- Call tools like \`remember_decision\`, \`recall_similar\``)
|
|
120
|
+
parts.push(`- Use \`init_project\` or \`smart_context\``)
|
|
121
|
+
parts.push(`- Auto-detect decisions with \`auto_remember\``)
|
|
122
|
+
} else {
|
|
123
|
+
parts.push('')
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
const time = entry.timestamp.toLocaleTimeString()
|
|
126
|
+
const icon = getActivityIcon(entry.type)
|
|
127
|
+
|
|
128
|
+
let line = `**${time}** ${icon} `
|
|
129
|
+
|
|
130
|
+
switch (entry.type) {
|
|
131
|
+
case 'memory_saved':
|
|
132
|
+
line += `Memory saved${entry.project ? ` [${entry.project}]` : ''}`
|
|
133
|
+
if (entry.memoryId) line += ` (ID: ${entry.memoryId.slice(0, 8)}...)`
|
|
134
|
+
break
|
|
135
|
+
case 'memory_recalled':
|
|
136
|
+
line += `Memory recalled${entry.project ? ` [${entry.project}]` : ''}`
|
|
137
|
+
break
|
|
138
|
+
case 'tool_call':
|
|
139
|
+
line += `Tool: \`${entry.tool}\`${entry.project ? ` [${entry.project}]` : ''}`
|
|
140
|
+
break
|
|
141
|
+
case 'project_loaded':
|
|
142
|
+
line += `Project loaded: ${entry.project}`
|
|
143
|
+
break
|
|
144
|
+
case 'decision_detected':
|
|
145
|
+
line += `Decision detected${entry.project ? ` [${entry.project}]` : ''}`
|
|
146
|
+
break
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
parts.push(line)
|
|
150
|
+
if (entry.details) {
|
|
151
|
+
parts.push(` └─ ${entry.details.slice(0, 80)}${entry.details.length > 80 ? '...' : ''}`)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// How to use section
|
|
157
|
+
parts.push(`\n### How Memory Works`)
|
|
158
|
+
parts.push(`1. **Save:** \`remember_decision\` or \`auto_remember\` stores to DB + vault`)
|
|
159
|
+
parts.push(`2. **Recall:** \`recall_similar\` or \`smart_context\` searches semantically`)
|
|
160
|
+
parts.push(`3. **View:** \`get_activity_log\` shows this log`)
|
|
161
|
+
parts.push(`\n*Activity log resets when MCP server restarts.*`)
|
|
162
|
+
|
|
163
|
+
return ResponseFormatter.text(parts.join('\n'))
|
|
164
|
+
|
|
165
|
+
} catch (error) {
|
|
166
|
+
ErrorHandler.logError(logger, error, { tool: 'get_activity_log', args })
|
|
167
|
+
|
|
168
|
+
if (error instanceof McpError) {
|
|
169
|
+
throw error
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
throw new McpError(
|
|
173
|
+
ErrorCode.InternalError,
|
|
174
|
+
`Failed to get activity log: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
175
|
+
)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function getActivityIcon(type: ActivityEntry['type']): string {
|
|
180
|
+
switch (type) {
|
|
181
|
+
case 'memory_saved': return '💾'
|
|
182
|
+
case 'memory_recalled': return '🔍'
|
|
183
|
+
case 'tool_call': return '🔧'
|
|
184
|
+
case 'project_loaded': return '📂'
|
|
185
|
+
case 'decision_detected': return '💡'
|
|
186
|
+
default: return '•'
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function formatBytes(bytes: number): string {
|
|
191
|
+
if (bytes < 1024) return `${bytes} B`
|
|
192
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`
|
|
193
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`
|
|
194
|
+
}
|
|
@@ -1,124 +1,124 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get Code Standards Handler
|
|
3
|
-
* Retrieves coding standards, patterns, and conventions for a project
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type { Logger } from 'pino'
|
|
7
|
-
import type { GetCodeStandardsInput, ToolResponse } from '@/tools/types'
|
|
8
|
-
import { getContextService } from '@/server/services'
|
|
9
|
-
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
-
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
-
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
12
|
-
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
13
|
-
|
|
14
|
-
export async function handleGetCodeStandards(
|
|
15
|
-
args: unknown,
|
|
16
|
-
logger: Logger
|
|
17
|
-
): Promise<ToolResponse> {
|
|
18
|
-
try {
|
|
19
|
-
const input = args as GetCodeStandardsInput
|
|
20
|
-
const { project_name, language } = input
|
|
21
|
-
|
|
22
|
-
logger.debug({ project_name, language }, 'Getting code standards')
|
|
23
|
-
|
|
24
|
-
const contextService = getContextService()
|
|
25
|
-
|
|
26
|
-
const standards = await contextService.standards.getProjectStandards(project_name)
|
|
27
|
-
|
|
28
|
-
let output = `# Code Standards for ${project_name}\n\n`
|
|
29
|
-
|
|
30
|
-
if (language) {
|
|
31
|
-
const langStandards = standards.languages.find(l => l.language.toLowerCase() === language.toLowerCase())
|
|
32
|
-
|
|
33
|
-
if (!langStandards) {
|
|
34
|
-
return ResponseFormatter.text(
|
|
35
|
-
`No standards found for ${language} in ${project_name}.\n\n` +
|
|
36
|
-
`Available languages: ${standards.languages.map(l => l.language).join(', ')}`
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
output += formatLanguageStandards(langStandards)
|
|
41
|
-
} else {
|
|
42
|
-
if (standards.languages.length > 0) {
|
|
43
|
-
output += `## Language Standards\n\n`
|
|
44
|
-
|
|
45
|
-
for (const lang of standards.languages) {
|
|
46
|
-
output += formatLanguageStandards(lang)
|
|
47
|
-
output += '\n'
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (standards.frameworks.length > 0) {
|
|
52
|
-
output += `## Framework Standards\n\n`
|
|
53
|
-
|
|
54
|
-
for (const framework of standards.frameworks) {
|
|
55
|
-
output += formatFrameworkStandards(framework)
|
|
56
|
-
output += '\n'
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
logger.info({ projectName: project_name, language }, 'Standards retrieved')
|
|
62
|
-
|
|
63
|
-
return ResponseFormatter.text(output)
|
|
64
|
-
|
|
65
|
-
} catch (error) {
|
|
66
|
-
ErrorHandler.logError(logger, error, { tool: 'get_code_standards', args })
|
|
67
|
-
|
|
68
|
-
if (error instanceof McpError) {
|
|
69
|
-
throw error
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
throw new McpError(
|
|
73
|
-
ErrorCode.InternalError,
|
|
74
|
-
`Failed to get code standards: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
75
|
-
)
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function formatLanguageStandards(lang: any): string {
|
|
80
|
-
let output = `### ${lang.language}\n\n`
|
|
81
|
-
output += `**Version:** ${lang.version}\n`
|
|
82
|
-
output += `**Style:** ${lang.style}\n\n`
|
|
83
|
-
|
|
84
|
-
if (lang.conventions && lang.conventions.length > 0) {
|
|
85
|
-
output += `**Conventions:**\n`
|
|
86
|
-
lang.conventions.forEach((conv: string) => {
|
|
87
|
-
output += `- ${conv}\n`
|
|
88
|
-
})
|
|
89
|
-
output += '\n'
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (lang.antiPatterns && lang.antiPatterns.length > 0) {
|
|
93
|
-
output += `**Anti-Patterns to Avoid:**\n`
|
|
94
|
-
lang.antiPatterns.forEach((pattern: string) => {
|
|
95
|
-
output += `- ${pattern}\n`
|
|
96
|
-
})
|
|
97
|
-
output += '\n'
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return output
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function formatFrameworkStandards(framework: any): string {
|
|
104
|
-
let output = `### ${framework.framework}\n\n`
|
|
105
|
-
output += `**Version:** ${framework.version}\n\n`
|
|
106
|
-
|
|
107
|
-
if (framework.patterns && framework.patterns.length > 0) {
|
|
108
|
-
output += `**Recommended Patterns:**\n`
|
|
109
|
-
framework.patterns.forEach((pattern: string) => {
|
|
110
|
-
output += `- ${pattern}\n`
|
|
111
|
-
})
|
|
112
|
-
output += '\n'
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (framework.bestPractices && framework.bestPractices.length > 0) {
|
|
116
|
-
output += `**Best Practices:**\n`
|
|
117
|
-
framework.bestPractices.forEach((practice: string) => {
|
|
118
|
-
output += `- ${practice}\n`
|
|
119
|
-
})
|
|
120
|
-
output += '\n'
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return output
|
|
124
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Get Code Standards Handler
|
|
3
|
+
* Retrieves coding standards, patterns, and conventions for a project
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import type { GetCodeStandardsInput, ToolResponse } from '@/tools/types'
|
|
8
|
+
import { getContextService } from '@/server/services'
|
|
9
|
+
import { ToolValidator } from '@/server/utils/validators'
|
|
10
|
+
import { ResponseFormatter } from '@/server/utils/response-formatter'
|
|
11
|
+
import { ErrorHandler } from '@/server/utils/error-handler'
|
|
12
|
+
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'
|
|
13
|
+
|
|
14
|
+
export async function handleGetCodeStandards(
|
|
15
|
+
args: unknown,
|
|
16
|
+
logger: Logger
|
|
17
|
+
): Promise<ToolResponse> {
|
|
18
|
+
try {
|
|
19
|
+
const input = args as GetCodeStandardsInput
|
|
20
|
+
const { project_name, language } = input
|
|
21
|
+
|
|
22
|
+
logger.debug({ project_name, language }, 'Getting code standards')
|
|
23
|
+
|
|
24
|
+
const contextService = getContextService()
|
|
25
|
+
|
|
26
|
+
const standards = await contextService.standards.getProjectStandards(project_name)
|
|
27
|
+
|
|
28
|
+
let output = `# Code Standards for ${project_name}\n\n`
|
|
29
|
+
|
|
30
|
+
if (language) {
|
|
31
|
+
const langStandards = standards.languages.find(l => l.language.toLowerCase() === language.toLowerCase())
|
|
32
|
+
|
|
33
|
+
if (!langStandards) {
|
|
34
|
+
return ResponseFormatter.text(
|
|
35
|
+
`No standards found for ${language} in ${project_name}.\n\n` +
|
|
36
|
+
`Available languages: ${standards.languages.map(l => l.language).join(', ')}`
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
output += formatLanguageStandards(langStandards)
|
|
41
|
+
} else {
|
|
42
|
+
if (standards.languages.length > 0) {
|
|
43
|
+
output += `## Language Standards\n\n`
|
|
44
|
+
|
|
45
|
+
for (const lang of standards.languages) {
|
|
46
|
+
output += formatLanguageStandards(lang)
|
|
47
|
+
output += '\n'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (standards.frameworks.length > 0) {
|
|
52
|
+
output += `## Framework Standards\n\n`
|
|
53
|
+
|
|
54
|
+
for (const framework of standards.frameworks) {
|
|
55
|
+
output += formatFrameworkStandards(framework)
|
|
56
|
+
output += '\n'
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
logger.info({ projectName: project_name, language }, 'Standards retrieved')
|
|
62
|
+
|
|
63
|
+
return ResponseFormatter.text(output)
|
|
64
|
+
|
|
65
|
+
} catch (error) {
|
|
66
|
+
ErrorHandler.logError(logger, error, { tool: 'get_code_standards', args })
|
|
67
|
+
|
|
68
|
+
if (error instanceof McpError) {
|
|
69
|
+
throw error
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
throw new McpError(
|
|
73
|
+
ErrorCode.InternalError,
|
|
74
|
+
`Failed to get code standards: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function formatLanguageStandards(lang: any): string {
|
|
80
|
+
let output = `### ${lang.language}\n\n`
|
|
81
|
+
output += `**Version:** ${lang.version}\n`
|
|
82
|
+
output += `**Style:** ${lang.style}\n\n`
|
|
83
|
+
|
|
84
|
+
if (lang.conventions && lang.conventions.length > 0) {
|
|
85
|
+
output += `**Conventions:**\n`
|
|
86
|
+
lang.conventions.forEach((conv: string) => {
|
|
87
|
+
output += `- ${conv}\n`
|
|
88
|
+
})
|
|
89
|
+
output += '\n'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (lang.antiPatterns && lang.antiPatterns.length > 0) {
|
|
93
|
+
output += `**Anti-Patterns to Avoid:**\n`
|
|
94
|
+
lang.antiPatterns.forEach((pattern: string) => {
|
|
95
|
+
output += `- ${pattern}\n`
|
|
96
|
+
})
|
|
97
|
+
output += '\n'
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return output
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function formatFrameworkStandards(framework: any): string {
|
|
104
|
+
let output = `### ${framework.framework}\n\n`
|
|
105
|
+
output += `**Version:** ${framework.version}\n\n`
|
|
106
|
+
|
|
107
|
+
if (framework.patterns && framework.patterns.length > 0) {
|
|
108
|
+
output += `**Recommended Patterns:**\n`
|
|
109
|
+
framework.patterns.forEach((pattern: string) => {
|
|
110
|
+
output += `- ${pattern}\n`
|
|
111
|
+
})
|
|
112
|
+
output += '\n'
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (framework.bestPractices && framework.bestPractices.length > 0) {
|
|
116
|
+
output += `**Best Practices:**\n`
|
|
117
|
+
framework.bestPractices.forEach((practice: string) => {
|
|
118
|
+
output += `- ${practice}\n`
|
|
119
|
+
})
|
|
120
|
+
output += '\n'
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return output
|
|
124
|
+
}
|