claude-brain 0.3.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 +157 -0
- package/VERSION +1 -0
- package/assets/CLAUDE.md +307 -0
- package/bunfig.toml +8 -0
- package/package.json +74 -0
- package/src/automation/auto-context.ts +240 -0
- package/src/automation/decision-detector.ts +452 -0
- package/src/automation/index.ts +11 -0
- package/src/automation/proactive-recall.ts +373 -0
- package/src/automation/project-detector.ts +297 -0
- package/src/cli/auto-setup.ts +74 -0
- package/src/cli/bin.ts +110 -0
- package/src/cli/commands/install-mcp.ts +50 -0
- package/src/cli/commands/serve.ts +129 -0
- package/src/cli/diagnose.ts +4 -0
- package/src/cli/health-check.ts +4 -0
- package/src/cli/migrate-chroma.ts +106 -0
- package/src/cli/setup.ts +4 -0
- package/src/config/defaults.ts +47 -0
- package/src/config/home.ts +55 -0
- package/src/config/index.ts +7 -0
- package/src/config/loader.ts +166 -0
- package/src/config/migration.ts +76 -0
- package/src/config/schema.ts +257 -0
- package/src/config/validator.ts +184 -0
- package/src/config/watcher.ts +86 -0
- package/src/context/assembler.ts +398 -0
- package/src/context/cache-manager.ts +101 -0
- package/src/context/formatter.ts +84 -0
- package/src/context/hierarchy.ts +85 -0
- package/src/context/index.ts +83 -0
- package/src/context/progress-tracker.ts +174 -0
- package/src/context/standards-manager.ts +267 -0
- package/src/context/types.ts +252 -0
- package/src/context/validator.ts +58 -0
- package/src/cross-project/affinity.ts +162 -0
- package/src/cross-project/generalizer.ts +283 -0
- package/src/cross-project/index.ts +13 -0
- package/src/cross-project/transfer.ts +201 -0
- package/src/diagnostics/index.ts +123 -0
- package/src/health/index.ts +229 -0
- package/src/index.ts +7 -0
- package/src/knowledge/entity-extractor.ts +416 -0
- package/src/knowledge/graph/builder.ts +159 -0
- package/src/knowledge/graph/linker.ts +201 -0
- package/src/knowledge/graph/memory-graph.ts +359 -0
- package/src/knowledge/graph/schema.ts +99 -0
- package/src/knowledge/graph/search.ts +168 -0
- package/src/knowledge/relationship-extractor.ts +108 -0
- package/src/memory/chroma/client.ts +169 -0
- package/src/memory/chroma/collection-manager.ts +94 -0
- package/src/memory/chroma/config.ts +46 -0
- package/src/memory/chroma/embeddings.ts +153 -0
- package/src/memory/chroma/index.ts +82 -0
- package/src/memory/chroma/migration.ts +270 -0
- package/src/memory/chroma/schemas.ts +69 -0
- package/src/memory/chroma/search.ts +315 -0
- package/src/memory/chroma/store.ts +694 -0
- package/src/memory/consolidation/archiver.ts +164 -0
- package/src/memory/consolidation/merger.ts +186 -0
- package/src/memory/consolidation/scorer.ts +138 -0
- package/src/memory/context-builder.ts +236 -0
- package/src/memory/database.ts +169 -0
- package/src/memory/embedding-utils.ts +156 -0
- package/src/memory/embeddings.ts +226 -0
- package/src/memory/episodic/detector.ts +108 -0
- package/src/memory/episodic/manager.ts +334 -0
- package/src/memory/episodic/summarizer.ts +179 -0
- package/src/memory/episodic/types.ts +52 -0
- package/src/memory/index.ts +395 -0
- package/src/memory/knowledge-extractor.ts +455 -0
- package/src/memory/learning.ts +378 -0
- package/src/memory/patterns.ts +396 -0
- package/src/memory/schema.ts +56 -0
- package/src/memory/search.ts +309 -0
- package/src/memory/store.ts +344 -0
- package/src/memory/types.ts +121 -0
- package/src/optimization/index.ts +10 -0
- package/src/optimization/precompute.ts +202 -0
- package/src/optimization/semantic-cache.ts +207 -0
- package/src/orchestrator/coordinator.ts +272 -0
- package/src/orchestrator/decision-logger.ts +228 -0
- package/src/orchestrator/event-emitter.ts +198 -0
- package/src/orchestrator/event-queue.ts +184 -0
- package/src/orchestrator/handlers/base-handler.ts +70 -0
- package/src/orchestrator/handlers/context-handler.ts +73 -0
- package/src/orchestrator/handlers/decision-handler.ts +204 -0
- package/src/orchestrator/handlers/index.ts +10 -0
- package/src/orchestrator/handlers/status-handler.ts +131 -0
- package/src/orchestrator/handlers/task-handler.ts +171 -0
- package/src/orchestrator/index.ts +275 -0
- package/src/orchestrator/task-parser.ts +284 -0
- package/src/orchestrator/types.ts +98 -0
- package/src/phase12/index.ts +456 -0
- package/src/prediction/context-anticipator.ts +198 -0
- package/src/prediction/decision-predictor.ts +184 -0
- package/src/prediction/index.ts +13 -0
- package/src/prediction/recommender.ts +268 -0
- package/src/reasoning/chain-retrieval.ts +247 -0
- package/src/reasoning/counterfactual.ts +248 -0
- package/src/reasoning/index.ts +13 -0
- package/src/reasoning/synthesizer.ts +169 -0
- package/src/retrieval/bm25/index.ts +300 -0
- package/src/retrieval/bm25/tokenizer.ts +184 -0
- package/src/retrieval/feedback/adaptive.ts +223 -0
- package/src/retrieval/feedback/index.ts +16 -0
- package/src/retrieval/feedback/metrics.ts +223 -0
- package/src/retrieval/feedback/store.ts +283 -0
- package/src/retrieval/fusion/index.ts +194 -0
- package/src/retrieval/fusion/rrf.ts +163 -0
- package/src/retrieval/index.ts +12 -0
- package/src/retrieval/pipeline.ts +375 -0
- package/src/retrieval/query/expander.ts +198 -0
- package/src/retrieval/query/index.ts +27 -0
- package/src/retrieval/query/intent-classifier.ts +236 -0
- package/src/retrieval/query/temporal-parser.ts +295 -0
- package/src/retrieval/reranker/index.ts +188 -0
- package/src/retrieval/reranker/model.ts +95 -0
- package/src/retrieval/service.ts +125 -0
- package/src/retrieval/types.ts +162 -0
- package/src/scripts/health-check.ts +118 -0
- package/src/scripts/setup.ts +122 -0
- package/src/server/handlers/call-tool.ts +194 -0
- package/src/server/handlers/index.ts +9 -0
- package/src/server/handlers/list-tools.ts +18 -0
- package/src/server/handlers/tools/analyze-decision-evolution.ts +71 -0
- package/src/server/handlers/tools/auto-remember.ts +200 -0
- package/src/server/handlers/tools/create-project.ts +135 -0
- package/src/server/handlers/tools/detect-trends.ts +80 -0
- package/src/server/handlers/tools/find-cross-project-patterns.ts +73 -0
- package/src/server/handlers/tools/get-activity-log.ts +194 -0
- package/src/server/handlers/tools/get-code-standards.ts +124 -0
- package/src/server/handlers/tools/get-corrections.ts +154 -0
- package/src/server/handlers/tools/get-decision-timeline.ts +86 -0
- package/src/server/handlers/tools/get-episode.ts +93 -0
- package/src/server/handlers/tools/get-patterns.ts +158 -0
- package/src/server/handlers/tools/get-phase12-status.ts +63 -0
- package/src/server/handlers/tools/get-project-context.ts +75 -0
- package/src/server/handlers/tools/get-recommendations.ts +65 -0
- package/src/server/handlers/tools/index.ts +33 -0
- package/src/server/handlers/tools/init-project.ts +710 -0
- package/src/server/handlers/tools/list-episodes.ts +80 -0
- package/src/server/handlers/tools/list-projects.ts +125 -0
- package/src/server/handlers/tools/rate-memory.ts +95 -0
- package/src/server/handlers/tools/recall-similar.ts +87 -0
- package/src/server/handlers/tools/recognize-pattern.ts +126 -0
- package/src/server/handlers/tools/record-correction.ts +125 -0
- package/src/server/handlers/tools/remember-decision.ts +153 -0
- package/src/server/handlers/tools/schemas.ts +241 -0
- package/src/server/handlers/tools/search-knowledge-graph.ts +89 -0
- package/src/server/handlers/tools/smart-context.ts +124 -0
- package/src/server/handlers/tools/update-progress.ts +114 -0
- package/src/server/handlers/tools/what-if-analysis.ts +73 -0
- package/src/server/http-api.ts +474 -0
- package/src/server/index.ts +40 -0
- package/src/server/mcp-server.ts +283 -0
- package/src/server/providers/index.ts +7 -0
- package/src/server/providers/prompts.ts +327 -0
- package/src/server/providers/resources.ts +427 -0
- package/src/server/services.ts +388 -0
- package/src/server/types.ts +39 -0
- package/src/server/utils/error-handler.ts +155 -0
- package/src/server/utils/index.ts +13 -0
- package/src/server/utils/memory-indicator.ts +83 -0
- package/src/server/utils/request-context.ts +122 -0
- package/src/server/utils/response-formatter.ts +124 -0
- package/src/server/utils/validators.ts +210 -0
- package/src/setup/index.ts +22 -0
- package/src/setup/wizard.ts +321 -0
- package/src/temporal/evolution.ts +197 -0
- package/src/temporal/index.ts +16 -0
- package/src/temporal/query-processor.ts +190 -0
- package/src/temporal/timeline.ts +259 -0
- package/src/temporal/trends.ts +263 -0
- package/src/tools/index.ts +24 -0
- package/src/tools/registry.ts +106 -0
- package/src/tools/schemas.test.ts +30 -0
- package/src/tools/schemas.ts +907 -0
- package/src/tools/types.ts +412 -0
- package/src/utils/circuit-breaker.ts +130 -0
- package/src/utils/cleanup.ts +34 -0
- package/src/utils/error-handler.ts +132 -0
- package/src/utils/error-messages.ts +60 -0
- package/src/utils/fallback.ts +45 -0
- package/src/utils/index.ts +54 -0
- package/src/utils/logger-utils.ts +80 -0
- package/src/utils/logger.ts +88 -0
- package/src/utils/phase12-helper.ts +56 -0
- package/src/utils/retry.ts +94 -0
- package/src/utils/transaction.ts +63 -0
- package/src/vault/frontmatter.ts +264 -0
- package/src/vault/index.ts +318 -0
- package/src/vault/paths.ts +106 -0
- package/src/vault/query.ts +422 -0
- package/src/vault/reader.ts +264 -0
- package/src/vault/templates.ts +186 -0
- package/src/vault/types.ts +73 -0
- package/src/vault/watcher.ts +277 -0
- package/src/vault/writer.ts +393 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Brain MCP Server
|
|
3
|
+
* Main MCP server implementation using the Model Context Protocol SDK
|
|
4
|
+
* Phase 6.5: Enhanced with system prompts and resources
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
|
|
8
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
9
|
+
import {
|
|
10
|
+
CallToolRequestSchema,
|
|
11
|
+
ListToolsRequestSchema,
|
|
12
|
+
ListPromptsRequestSchema,
|
|
13
|
+
GetPromptRequestSchema,
|
|
14
|
+
ListResourcesRequestSchema,
|
|
15
|
+
ReadResourceRequestSchema
|
|
16
|
+
} from '@modelcontextprotocol/sdk/types.js'
|
|
17
|
+
import type { Logger } from 'pino'
|
|
18
|
+
import type { Config } from '@/config'
|
|
19
|
+
import type { ConnectionState, ServerStatus, ServerOptions, ServerEvents } from './types'
|
|
20
|
+
import { PromptProvider } from './providers/prompts'
|
|
21
|
+
import { ResourceProvider } from './providers/resources'
|
|
22
|
+
|
|
23
|
+
export class ClaudeBrainMCPServer {
|
|
24
|
+
private server: Server
|
|
25
|
+
private logger: Logger
|
|
26
|
+
private config: Config
|
|
27
|
+
private isRunning: boolean = false
|
|
28
|
+
private connectionState: ConnectionState = 'disconnected'
|
|
29
|
+
private startedAt?: Date
|
|
30
|
+
private requestCount: number = 0
|
|
31
|
+
private events: ServerEvents
|
|
32
|
+
|
|
33
|
+
// Phase 6.5: Prompt and Resource providers
|
|
34
|
+
private promptProvider: PromptProvider
|
|
35
|
+
private resourceProvider: ResourceProvider
|
|
36
|
+
|
|
37
|
+
constructor(config: Config, logger: Logger, options: ServerOptions = {}) {
|
|
38
|
+
this.config = config
|
|
39
|
+
this.logger = logger.child({ component: 'mcp-server' })
|
|
40
|
+
this.events = options.events || {}
|
|
41
|
+
|
|
42
|
+
// Phase 6.5: Initialize providers
|
|
43
|
+
this.promptProvider = new PromptProvider(logger)
|
|
44
|
+
this.resourceProvider = new ResourceProvider(logger)
|
|
45
|
+
|
|
46
|
+
// Initialize MCP Server with metadata and enhanced capabilities
|
|
47
|
+
this.server = new Server(
|
|
48
|
+
{
|
|
49
|
+
name: config.serverName,
|
|
50
|
+
version: config.serverVersion
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
capabilities: {
|
|
54
|
+
tools: {},
|
|
55
|
+
prompts: {}, // Phase 6.5: Enable prompts
|
|
56
|
+
resources: {} // Phase 6.5: Enable resources
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
// Setup request handlers
|
|
62
|
+
this.setupHandlers()
|
|
63
|
+
|
|
64
|
+
// Setup error handling
|
|
65
|
+
this.setupErrorHandling()
|
|
66
|
+
|
|
67
|
+
this.logger.debug('MCP server instance created with Phase 6.5 enhancements')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Setup MCP request handlers for tools, prompts, and resources
|
|
72
|
+
*/
|
|
73
|
+
private setupHandlers(): void {
|
|
74
|
+
// Handle tools/list request
|
|
75
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
76
|
+
this.logger.debug('Handling tools/list request')
|
|
77
|
+
|
|
78
|
+
// Import dynamically to avoid circular dependencies
|
|
79
|
+
const { handleListTools } = await import('./handlers/list-tools')
|
|
80
|
+
return await handleListTools()
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// Handle tools/call request
|
|
84
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
85
|
+
const toolName = request.params.name
|
|
86
|
+
const args = request.params.arguments || {}
|
|
87
|
+
|
|
88
|
+
this.requestCount++
|
|
89
|
+
const requestId = `req_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 9)}`
|
|
90
|
+
|
|
91
|
+
this.logger.debug({
|
|
92
|
+
tool: toolName,
|
|
93
|
+
args,
|
|
94
|
+
requestId
|
|
95
|
+
}, 'Handling tools/call request')
|
|
96
|
+
|
|
97
|
+
// Emit request event
|
|
98
|
+
this.events.onRequest?.(toolName, requestId)
|
|
99
|
+
|
|
100
|
+
const startTime = Date.now()
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
// Import dynamically to avoid circular dependencies
|
|
104
|
+
const { handleCallTool } = await import('./handlers/call-tool')
|
|
105
|
+
const result = await handleCallTool(toolName, args, this.logger)
|
|
106
|
+
|
|
107
|
+
const duration = Date.now() - startTime
|
|
108
|
+
this.logger.debug({
|
|
109
|
+
tool: toolName,
|
|
110
|
+
requestId,
|
|
111
|
+
durationMs: duration
|
|
112
|
+
}, 'Tool call completed')
|
|
113
|
+
|
|
114
|
+
// Emit response event
|
|
115
|
+
this.events.onResponse?.(toolName, requestId, duration)
|
|
116
|
+
|
|
117
|
+
return result
|
|
118
|
+
} catch (error) {
|
|
119
|
+
const duration = Date.now() - startTime
|
|
120
|
+
this.logger.error({
|
|
121
|
+
tool: toolName,
|
|
122
|
+
requestId,
|
|
123
|
+
durationMs: duration,
|
|
124
|
+
error: error instanceof Error ? error.message : String(error)
|
|
125
|
+
}, 'Tool call failed')
|
|
126
|
+
|
|
127
|
+
throw error
|
|
128
|
+
}
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
// Phase 6.5: Handle prompts/list request
|
|
132
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
133
|
+
this.logger.debug('Handling prompts/list request')
|
|
134
|
+
return await this.promptProvider.listPrompts()
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
// Phase 6.5: Handle prompts/get request
|
|
138
|
+
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
139
|
+
this.logger.debug({ name: request.params.name }, 'Handling prompts/get request')
|
|
140
|
+
return await this.promptProvider.getPrompt(request.params.name)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
// Phase 6.5: Handle resources/list request
|
|
144
|
+
this.server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
145
|
+
this.logger.debug('Handling resources/list request')
|
|
146
|
+
return await this.resourceProvider.listResources()
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
// Phase 6.5: Handle resources/read request
|
|
150
|
+
this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
151
|
+
this.logger.debug({ uri: request.params.uri }, 'Handling resources/read request')
|
|
152
|
+
return await this.resourceProvider.readResource(request.params.uri)
|
|
153
|
+
})
|
|
154
|
+
|
|
155
|
+
this.logger.debug('Request handlers configured (tools, prompts, resources)')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Setup error handling for the server
|
|
160
|
+
*/
|
|
161
|
+
private setupErrorHandling(): void {
|
|
162
|
+
this.server.onerror = (error) => {
|
|
163
|
+
this.logger.error({
|
|
164
|
+
error: error instanceof Error ? {
|
|
165
|
+
message: error.message,
|
|
166
|
+
stack: error.stack,
|
|
167
|
+
name: error.name
|
|
168
|
+
} : error
|
|
169
|
+
}, 'MCP server error')
|
|
170
|
+
|
|
171
|
+
this.events.onError?.(error instanceof Error ? error : new Error(String(error)))
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Update connection state and emit events
|
|
177
|
+
*/
|
|
178
|
+
private setConnectionState(state: ConnectionState): void {
|
|
179
|
+
const previousState = this.connectionState
|
|
180
|
+
this.connectionState = state
|
|
181
|
+
|
|
182
|
+
if (previousState !== state) {
|
|
183
|
+
this.logger.info({
|
|
184
|
+
previousState,
|
|
185
|
+
newState: state
|
|
186
|
+
}, 'Connection state changed')
|
|
187
|
+
|
|
188
|
+
this.events.onConnectionStateChange?.(state)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Start the MCP server and connect via stdio transport
|
|
194
|
+
*/
|
|
195
|
+
async start(): Promise<void> {
|
|
196
|
+
if (this.isRunning) {
|
|
197
|
+
this.logger.warn('Server already running')
|
|
198
|
+
return
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
try {
|
|
202
|
+
this.logger.info('Starting MCP server...')
|
|
203
|
+
this.setConnectionState('connecting')
|
|
204
|
+
|
|
205
|
+
const transport = new StdioServerTransport()
|
|
206
|
+
await this.server.connect(transport)
|
|
207
|
+
|
|
208
|
+
this.isRunning = true
|
|
209
|
+
this.startedAt = new Date()
|
|
210
|
+
this.setConnectionState('connected')
|
|
211
|
+
|
|
212
|
+
this.logger.info({
|
|
213
|
+
name: this.config.serverName,
|
|
214
|
+
version: this.config.serverVersion,
|
|
215
|
+
startedAt: this.startedAt.toISOString()
|
|
216
|
+
}, 'MCP server started successfully')
|
|
217
|
+
|
|
218
|
+
} catch (error) {
|
|
219
|
+
this.setConnectionState('disconnected')
|
|
220
|
+
this.logger.error({
|
|
221
|
+
error: error instanceof Error ? {
|
|
222
|
+
message: error.message,
|
|
223
|
+
stack: error.stack
|
|
224
|
+
} : error
|
|
225
|
+
}, 'Failed to start MCP server')
|
|
226
|
+
throw error
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Stop the MCP server gracefully
|
|
232
|
+
*/
|
|
233
|
+
async stop(): Promise<void> {
|
|
234
|
+
if (!this.isRunning) {
|
|
235
|
+
this.logger.debug('Server not running, skip stop')
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
try {
|
|
240
|
+
this.logger.info('Stopping MCP server...')
|
|
241
|
+
await this.server.close()
|
|
242
|
+
|
|
243
|
+
this.isRunning = false
|
|
244
|
+
this.setConnectionState('disconnected')
|
|
245
|
+
|
|
246
|
+
this.logger.info({
|
|
247
|
+
totalRequests: this.requestCount,
|
|
248
|
+
uptimeMs: this.startedAt ? Date.now() - this.startedAt.getTime() : 0
|
|
249
|
+
}, 'MCP server stopped')
|
|
250
|
+
|
|
251
|
+
} catch (error) {
|
|
252
|
+
this.logger.error({
|
|
253
|
+
error: error instanceof Error ? {
|
|
254
|
+
message: error.message,
|
|
255
|
+
stack: error.stack
|
|
256
|
+
} : error
|
|
257
|
+
}, 'Error stopping MCP server')
|
|
258
|
+
throw error
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get current server status
|
|
264
|
+
*/
|
|
265
|
+
getStatus(): ServerStatus {
|
|
266
|
+
return {
|
|
267
|
+
running: this.isRunning,
|
|
268
|
+
name: this.config.serverName,
|
|
269
|
+
version: this.config.serverVersion,
|
|
270
|
+
connectionState: this.connectionState,
|
|
271
|
+
startedAt: this.startedAt,
|
|
272
|
+
requestCount: this.requestCount,
|
|
273
|
+
capabilities: ['tools', 'prompts', 'resources']
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Health check method
|
|
279
|
+
*/
|
|
280
|
+
isHealthy(): boolean {
|
|
281
|
+
return this.isRunning && this.connectionState === 'connected'
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Provider
|
|
3
|
+
* Phase 6.5: System prompts for proactive Claude behavior
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Logger } from 'pino'
|
|
7
|
+
import path from 'path'
|
|
8
|
+
import { getVaultService, getContextService, isServicesInitialized } from '@/server/services'
|
|
9
|
+
import { isPhase12Available, getPhase12Instance } from '@/utils/phase12-helper'
|
|
10
|
+
|
|
11
|
+
interface DetectedProject {
|
|
12
|
+
name: string
|
|
13
|
+
path: string
|
|
14
|
+
confidence: number
|
|
15
|
+
indicators: string[]
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class PromptProvider {
|
|
19
|
+
private logger: Logger
|
|
20
|
+
|
|
21
|
+
constructor(logger: Logger) {
|
|
22
|
+
this.logger = logger.child({ component: 'prompt-provider' })
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get all available prompts
|
|
27
|
+
*/
|
|
28
|
+
async listPrompts() {
|
|
29
|
+
return {
|
|
30
|
+
prompts: [
|
|
31
|
+
{
|
|
32
|
+
name: 'claude-brain-behavior',
|
|
33
|
+
description: 'Instructions for using Claude Brain proactively',
|
|
34
|
+
arguments: []
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'current-project-context',
|
|
38
|
+
description: 'Auto-detected project context summary',
|
|
39
|
+
arguments: []
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get specific prompt content
|
|
47
|
+
*/
|
|
48
|
+
async getPrompt(name: string) {
|
|
49
|
+
switch (name) {
|
|
50
|
+
case 'claude-brain-behavior':
|
|
51
|
+
return await this.getBehaviorPrompt()
|
|
52
|
+
case 'current-project-context':
|
|
53
|
+
return await this.getProjectContextPrompt()
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unknown prompt: ${name}`)
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get behavior instructions prompt
|
|
61
|
+
*/
|
|
62
|
+
private async getBehaviorPrompt() {
|
|
63
|
+
const detectedProject = await this.detectCurrentProject()
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
messages: [
|
|
67
|
+
{
|
|
68
|
+
role: 'user',
|
|
69
|
+
content: {
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: this.buildBehaviorPromptText(detectedProject)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Build the behavior prompt text
|
|
80
|
+
*/
|
|
81
|
+
private buildBehaviorPromptText(detectedProject: DetectedProject | null): string {
|
|
82
|
+
const phase12Status = isPhase12Available()
|
|
83
|
+
? `
|
|
84
|
+
**Phase 12 Advanced Features Available:**
|
|
85
|
+
The system includes advanced automation that may auto-detect and save decisions.
|
|
86
|
+
Continue being proactive - Phase 12 features complement your behavior.
|
|
87
|
+
`
|
|
88
|
+
: ''
|
|
89
|
+
|
|
90
|
+
const projectContext = detectedProject
|
|
91
|
+
? `
|
|
92
|
+
**CURRENT PROJECT DETECTED: ${detectedProject.name}**
|
|
93
|
+
- Confidence: ${Math.round(detectedProject.confidence * 100)}%
|
|
94
|
+
- Detection method: ${detectedProject.indicators.join(', ')}
|
|
95
|
+
|
|
96
|
+
When the user asks questions, assume they're asking about this project unless they specify otherwise.
|
|
97
|
+
`
|
|
98
|
+
: 'No project currently detected in working directory.'
|
|
99
|
+
|
|
100
|
+
return `
|
|
101
|
+
# Claude Brain Integration
|
|
102
|
+
|
|
103
|
+
You are connected to Claude Brain, a persistent memory and context management system.
|
|
104
|
+
|
|
105
|
+
## CRITICAL BEHAVIORS (Always Follow)
|
|
106
|
+
|
|
107
|
+
### 1. Proactive Tool Usage
|
|
108
|
+
When users ask questions about their projects, YOU SHOULD:
|
|
109
|
+
- Use \`get_project_context\` when they mention a project name
|
|
110
|
+
- Use \`recall_similar\` before answering architecture/design questions
|
|
111
|
+
- Use \`remember_decision\` when making important recommendations
|
|
112
|
+
- Use \`update_progress\` when they complete tasks
|
|
113
|
+
|
|
114
|
+
DO NOT wait for explicit commands like "use the tool". Act proactively based on context.
|
|
115
|
+
|
|
116
|
+
### 2. Decision Detection
|
|
117
|
+
When you make recommendations that include:
|
|
118
|
+
- "I recommend..."
|
|
119
|
+
- "You should use..."
|
|
120
|
+
- "The best approach is..."
|
|
121
|
+
- Technical architecture choices
|
|
122
|
+
|
|
123
|
+
YOU SHOULD automatically use \`remember_decision\` to store this for future reference.
|
|
124
|
+
|
|
125
|
+
### 3. Context Awareness
|
|
126
|
+
${projectContext}
|
|
127
|
+
|
|
128
|
+
### 4. Memory-First Approach
|
|
129
|
+
BEFORE answering architecture, design, or technical questions:
|
|
130
|
+
1. Use \`recall_similar\` to check past decisions
|
|
131
|
+
2. If relevant past context exists, reference it in your answer
|
|
132
|
+
3. Build on past decisions rather than starting from scratch
|
|
133
|
+
|
|
134
|
+
### 5. Available Tools
|
|
135
|
+
|
|
136
|
+
**Context & Information:**
|
|
137
|
+
- \`get_project_context\`: Get full project details, tech stack, progress, standards
|
|
138
|
+
- \`list_projects\`: See all available projects
|
|
139
|
+
- \`get_code_standards\`: Get coding standards for a project
|
|
140
|
+
|
|
141
|
+
**Memory & Decisions:**
|
|
142
|
+
- \`remember_decision\`: Store important decisions (use proactively!)
|
|
143
|
+
- \`recall_similar\`: Search past decisions by semantic similarity
|
|
144
|
+
|
|
145
|
+
**Progress Tracking:**
|
|
146
|
+
- \`update_progress\`: Mark tasks complete and set next steps
|
|
147
|
+
|
|
148
|
+
**Phase 12 Smart Tools:**
|
|
149
|
+
- \`smart_context\`: Get context + proactive memory recall for current task
|
|
150
|
+
- \`auto_remember\`: Auto-detect and save decisions from text
|
|
151
|
+
- \`get_phase12_status\`: Check automation status
|
|
152
|
+
|
|
153
|
+
## Example Behaviors
|
|
154
|
+
|
|
155
|
+
**Good (Proactive):**
|
|
156
|
+
\`\`\`
|
|
157
|
+
User: "How should I handle authentication in my-app?"
|
|
158
|
+
|
|
159
|
+
You (internally):
|
|
160
|
+
1. Use recall_similar("authentication approaches")
|
|
161
|
+
2. Use get_project_context("my-app") if needed
|
|
162
|
+
|
|
163
|
+
You (response): "Based on our past Auth0 decision in your-other-app
|
|
164
|
+
(which worked well), I recommend a similar approach for my-app..."
|
|
165
|
+
\`\`\`
|
|
166
|
+
|
|
167
|
+
**Bad (Waiting for Commands):**
|
|
168
|
+
\`\`\`
|
|
169
|
+
User: "How should I handle authentication in my-app?"
|
|
170
|
+
You: "Would you like me to check past decisions first?"
|
|
171
|
+
\`\`\`
|
|
172
|
+
|
|
173
|
+
## Phase 12 Integration Notice
|
|
174
|
+
${phase12Status}
|
|
175
|
+
|
|
176
|
+
Remember: Be helpful and proactive. Users expect you to use these tools automatically based on context, not wait for explicit commands.
|
|
177
|
+
`.trim()
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Get current project context prompt
|
|
182
|
+
*/
|
|
183
|
+
private async getProjectContextPrompt() {
|
|
184
|
+
const detectedProject = await this.detectCurrentProject()
|
|
185
|
+
|
|
186
|
+
if (!detectedProject) {
|
|
187
|
+
return {
|
|
188
|
+
messages: [
|
|
189
|
+
{
|
|
190
|
+
role: 'user',
|
|
191
|
+
content: {
|
|
192
|
+
type: 'text',
|
|
193
|
+
text: 'No project detected in current working directory.'
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
]
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
if (!isServicesInitialized()) {
|
|
202
|
+
return {
|
|
203
|
+
messages: [
|
|
204
|
+
{
|
|
205
|
+
role: 'user',
|
|
206
|
+
content: {
|
|
207
|
+
type: 'text',
|
|
208
|
+
text: `Project detected: ${detectedProject.name}, but services not initialized.`
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const contextService = getContextService()
|
|
216
|
+
|
|
217
|
+
// Get brief context summary
|
|
218
|
+
const context = await contextService.getContext(detectedProject.name, {
|
|
219
|
+
includeMemories: false, // Brief summary only
|
|
220
|
+
includeProgress: true,
|
|
221
|
+
includeStandards: false,
|
|
222
|
+
maxTokens: 1000
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
const techStack = context.project.techStack?.join(', ') || 'Not specified'
|
|
226
|
+
const currentPhase = context.progress?.currentPhase || 'Not specified'
|
|
227
|
+
const completion = context.progress?.completionPercentage || 0
|
|
228
|
+
const currentTasks = context.progress?.currentTasks?.slice(0, 3).map(t => `- ${t.title}`).join('\n') || 'No current tasks'
|
|
229
|
+
|
|
230
|
+
return {
|
|
231
|
+
messages: [
|
|
232
|
+
{
|
|
233
|
+
role: 'user',
|
|
234
|
+
content: {
|
|
235
|
+
type: 'text',
|
|
236
|
+
text: `
|
|
237
|
+
# Current Project: ${detectedProject.name}
|
|
238
|
+
|
|
239
|
+
## Quick Summary
|
|
240
|
+
${context.project.description || 'No description available'}
|
|
241
|
+
|
|
242
|
+
## Tech Stack
|
|
243
|
+
${techStack}
|
|
244
|
+
|
|
245
|
+
## Current Phase
|
|
246
|
+
${currentPhase} (${completion}% complete)
|
|
247
|
+
|
|
248
|
+
## Recent Activity
|
|
249
|
+
${currentTasks}
|
|
250
|
+
|
|
251
|
+
Use \`get_project_context\` for complete details including decisions, standards, and relevant memories.
|
|
252
|
+
`.trim()
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
} catch (error) {
|
|
259
|
+
this.logger.error({ error, project: detectedProject.name }, 'Failed to load project context')
|
|
260
|
+
|
|
261
|
+
return {
|
|
262
|
+
messages: [
|
|
263
|
+
{
|
|
264
|
+
role: 'user',
|
|
265
|
+
content: {
|
|
266
|
+
type: 'text',
|
|
267
|
+
text: `Project detected: ${detectedProject.name}, but context could not be loaded. Use \`get_project_context\` to access details.`
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Detect current project from working directory
|
|
277
|
+
*/
|
|
278
|
+
private async detectCurrentProject(): Promise<DetectedProject | null> {
|
|
279
|
+
try {
|
|
280
|
+
const cwd = process.cwd()
|
|
281
|
+
|
|
282
|
+
// Check if Phase 12 is available with better detection
|
|
283
|
+
if (isPhase12Available()) {
|
|
284
|
+
const phase12 = getPhase12Instance()
|
|
285
|
+
if (phase12?.projectDetector?.detectProject) {
|
|
286
|
+
return await phase12.projectDetector.detectProject(cwd)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Fallback: Simple detection
|
|
291
|
+
if (!isServicesInitialized()) {
|
|
292
|
+
return null
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const vault = getVaultService()
|
|
296
|
+
const projects = await vault.reader.getProjectDirectories(vault.paths.projects)
|
|
297
|
+
const dirName = path.basename(cwd)
|
|
298
|
+
|
|
299
|
+
if (projects.includes(dirName)) {
|
|
300
|
+
return {
|
|
301
|
+
name: dirName,
|
|
302
|
+
path: cwd,
|
|
303
|
+
confidence: 1.0,
|
|
304
|
+
indicators: ['directory-match']
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Check if cwd contains a project folder name
|
|
309
|
+
for (const project of projects) {
|
|
310
|
+
if (cwd.toLowerCase().includes(project.toLowerCase())) {
|
|
311
|
+
return {
|
|
312
|
+
name: project,
|
|
313
|
+
path: cwd,
|
|
314
|
+
confidence: 0.7,
|
|
315
|
+
indicators: ['path-contains-project']
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return null
|
|
321
|
+
|
|
322
|
+
} catch (error) {
|
|
323
|
+
this.logger.debug({ error }, 'Project detection failed')
|
|
324
|
+
return null
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|