claude-mem 3.0.2 → 3.0.4

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 (56) hide show
  1. package/.mcp.json +11 -0
  2. package/claude-mem +0 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +64 -0
  5. package/dist/commands/compress.d.ts +2 -0
  6. package/dist/commands/compress.js +59 -0
  7. package/dist/commands/install.d.ts +2 -0
  8. package/dist/commands/install.js +372 -0
  9. package/dist/commands/load-context.d.ts +2 -0
  10. package/dist/commands/load-context.js +330 -0
  11. package/dist/commands/logs.d.ts +2 -0
  12. package/dist/commands/logs.js +41 -0
  13. package/dist/commands/migrate.d.ts +9 -0
  14. package/dist/commands/migrate.js +174 -0
  15. package/dist/commands/status.d.ts +1 -0
  16. package/dist/commands/status.js +159 -0
  17. package/dist/commands/uninstall.d.ts +2 -0
  18. package/dist/commands/uninstall.js +105 -0
  19. package/dist/config.d.ts +6 -0
  20. package/dist/config.js +33 -0
  21. package/dist/constants.d.ts +516 -0
  22. package/dist/constants.js +522 -0
  23. package/dist/error-handler.d.ts +17 -0
  24. package/dist/error-handler.js +103 -0
  25. package/dist/mcp-server-cli.d.ts +34 -0
  26. package/dist/mcp-server-cli.js +158 -0
  27. package/dist/mcp-server.d.ts +103 -0
  28. package/dist/mcp-server.js +269 -0
  29. package/dist/types.d.ts +148 -0
  30. package/dist/types.js +78 -0
  31. package/dist/utils/HookDetector.d.ts +64 -0
  32. package/dist/utils/HookDetector.js +213 -0
  33. package/dist/utils/PathResolver.d.ts +16 -0
  34. package/dist/utils/PathResolver.js +55 -0
  35. package/dist/utils/SettingsManager.d.ts +63 -0
  36. package/dist/utils/SettingsManager.js +133 -0
  37. package/dist/utils/TranscriptCompressor.d.ts +111 -0
  38. package/dist/utils/TranscriptCompressor.js +486 -0
  39. package/dist/utils/common.d.ts +29 -0
  40. package/dist/utils/common.js +14 -0
  41. package/dist/utils/error-utils.d.ts +93 -0
  42. package/dist/utils/error-utils.js +238 -0
  43. package/dist/utils/index.d.ts +19 -0
  44. package/dist/utils/index.js +26 -0
  45. package/dist/utils/logger.d.ts +19 -0
  46. package/dist/utils/logger.js +42 -0
  47. package/dist/utils/mcp-client-factory.d.ts +51 -0
  48. package/dist/utils/mcp-client-factory.js +115 -0
  49. package/dist/utils/mcp-client.d.ts +75 -0
  50. package/dist/utils/mcp-client.js +120 -0
  51. package/dist/utils/memory-mcp-client.d.ts +135 -0
  52. package/dist/utils/memory-mcp-client.js +490 -0
  53. package/dist/utils/weaviate-mcp-adapter.d.ts +102 -0
  54. package/dist/utils/weaviate-mcp-adapter.js +587 -0
  55. package/package.json +3 -2
  56. package/src/claude-mem.js +0 -859
@@ -0,0 +1,522 @@
1
+ /**
2
+ * Claude Memory System - Constants and Templates
3
+ *
4
+ * This file consolidates all prompts, instructions, and output templates
5
+ * used throughout the claude-mem system for better maintainability,
6
+ * DRYness, and easier auditing of LLM logic.
7
+ */
8
+ // =============================================================================
9
+ // ANALYSIS PROMPTS AND TEMPLATES
10
+ // =============================================================================
11
+ /**
12
+ * Entity naming patterns for the knowledge graph
13
+ */
14
+ export const ENTITY_NAMING_PATTERNS = {
15
+ component: "Component_Name",
16
+ decision: "Decision_Name",
17
+ pattern: "Pattern_Name",
18
+ tool: "Tool_Name",
19
+ fix: "Fix_Name",
20
+ workflow: "Workflow_Name"
21
+ };
22
+ /**
23
+ * Available entity types for classification
24
+ */
25
+ export const ENTITY_TYPES = {
26
+ component: "component", // UI components, modules, services
27
+ pattern: "pattern", // Architectural or design patterns
28
+ workflow: "workflow", // Processes, pipelines, sequences
29
+ integration: "integration", // APIs, external services, data sources
30
+ concept: "concept", // Abstract ideas, methodologies, principles
31
+ decision: "decision", // Design choices, trade-offs, solutions
32
+ tool: "tool", // Utilities, libraries, development tools
33
+ fix: "fix" // Bug fixes, patches, workarounds
34
+ };
35
+ /**
36
+ * Standard observation fields for entities
37
+ */
38
+ export const OBSERVATION_FIELDS = [
39
+ "Core purpose: [what it fundamentally does]",
40
+ "Brief description: [one-line summary for session-start display]",
41
+ "Implementation: [key technical details, code patterns]",
42
+ "Dependencies: [what it requires or builds upon]",
43
+ "Usage context: [when/why it's used]",
44
+ "Performance characteristics: [speed, reliability, constraints]",
45
+ "Integration points: [how it connects to other systems]",
46
+ "Keywords: [searchable terms for this concept]",
47
+ "Decision rationale: [why this approach was chosen]",
48
+ "Next steps: [what needs to be done next with this component]",
49
+ "Files modified: [list of files changed]",
50
+ "Tools used: [development tools/commands used]"
51
+ ];
52
+ /**
53
+ * Relationship types for creating meaningful entity connections
54
+ */
55
+ export const RELATIONSHIP_TYPES = [
56
+ "executes_via", "orchestrates_through", "validates_using",
57
+ "provides_auth_to", "manages_state_for", "processes_events_from",
58
+ "caches_data_from", "routes_requests_to", "transforms_data_for",
59
+ "extends", "enhances_performance_of", "builds_upon",
60
+ "fixes_issue_in", "replaces", "optimizes",
61
+ "uses_tool_chain", "triggers_tool", "receives_result_from"
62
+ ];
63
+ /**
64
+ * Creates the main analysis prompt for transcript compression
65
+ */
66
+ export function createAnalysisPrompt(projectName, sessionId, hasCompressedContent, existingMemoriesText, toolUseChains) {
67
+ const incrementalSection = hasCompressedContent ? `
68
+ INCREMENTAL COMPRESSION:
69
+ Lines marked [ALREADY COMPRESSED] contain existing memory references.
70
+ DO NOT re-compress these. Build upon existing patterns and connect new entities to them.
71
+
72
+ EXISTING COMPRESSED MEMORIES:
73
+ ${existingMemoriesText}
74
+ ` : '';
75
+ const toolChainsSection = toolUseChains.length > 0 ? `
76
+ TOOL USE CHAINS DETECTED:
77
+ ${toolUseChains.map(chain => `- Tool chain ${chain.id}: ${chain.tools.join(' → ')}`).join('\n')}
78
+ Create relationships for these tool use sequences in the knowledge graph.
79
+ ` : '';
80
+ return `You are analyzing a Claude Code conversation transcript to create a sophisticated memory index system using the Model Context Protocol knowledge graph.
81
+
82
+ Your task:
83
+ 1. Extract ALL key technical entities following MCP memory best practices
84
+ 2. Create rich, searchable entities with detailed observations using MCP tools
85
+ 3. Create specific, active-voice relationships between entities
86
+ 4. Return compressed summaries in STRICT JSONL format with memory/keyword references
87
+
88
+ ${incrementalSection}${toolChainsSection}
89
+
90
+ ENTITY EXTRACTION GUIDELINES:
91
+ Focus on these categories for creating a searchable index:
92
+ - **Technical Components**: Functions, classes, services, APIs, databases, modules
93
+ - **Architectural Patterns**: State management, authentication flows, data pipelines, design patterns
94
+ - **Development Decisions**: Design choices, trade-offs, problem solutions, optimizations
95
+ - **Workflows & Processes**: Build processes, deployment strategies, testing approaches
96
+ - **Integration Points**: External APIs, third-party services, data sources
97
+ - **Performance & Reliability**: Caching strategies, error handling, optimization techniques
98
+ - **Bugs & Fixes**: Issues encountered, debugging approaches, solutions applied
99
+
100
+ ENTITY FORMAT:
101
+ - name: "${projectName}_EntityName"
102
+ (Use clear, searchable names that describe WHAT it is, not session-specific IDs)
103
+ IMPORTANT: Include entity type in name for better categorization:
104
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.component}" for UI/modules/services
105
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.decision}" for architectural choices
106
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.pattern}" for design patterns
107
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.tool}" for libraries/tools
108
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.fix}" for bug fixes
109
+ * "${projectName}_${ENTITY_NAMING_PATTERNS.workflow}" for processes
110
+ - entityType: Choose from:
111
+ ${Object.entries(ENTITY_TYPES).map(([key, value]) => ` * "${value}" - ${getEntityTypeDescription(key)}`).join('\n')}
112
+ - observations: Rich, structured details for future recall:
113
+ ${OBSERVATION_FIELDS.map(field => ` * "${field}"`).join('\n')}
114
+ * "UUID: ${sessionId}"
115
+ * "Session: ${sessionId}"
116
+
117
+ RELATIONSHIP FORMAT (Use specific, active voice):
118
+ Be precise with relationships to create a meaningful graph:
119
+ ${RELATIONSHIP_TYPES.slice(0, 6).join(', ')}
120
+ ${RELATIONSHIP_TYPES.slice(6, 12).join(', ')}
121
+ ${RELATIONSHIP_TYPES.slice(12).join(', ')}
122
+
123
+ OUTPUT FORMAT REQUIREMENTS:
124
+ Return ONLY valid JSONL format (one JSON object per line, NOT an array) with this EXACT structure:
125
+
126
+ EXAMPLE OUTPUT:
127
+ ${createExampleOutput(projectName, sessionId)}
128
+
129
+ SUMMARY REQUIREMENTS:
130
+ Each index entry must:
131
+ - Be a valid JSON object with ALL required fields: timestamp, session_id, project, summary, nodes, keywords, message_count, uuid, archive_path
132
+ - timestamp: Current ISO timestamp
133
+ - session_id: Use EXACT session ID "${sessionId}" (no "session-" prefix)
134
+ - project: "${projectName}"
135
+ - summary: Describe WHAT was accomplished and WHY it matters (active voice, specific, actionable)
136
+ * Start with action verb: "Implemented", "Fixed", "Refactored", "Designed", "Optimized"
137
+ * Include the main component/feature affected
138
+ * Mention the key outcome or improvement
139
+ - nodes: Array of 2-4 entity names created in knowledge graph (use type-prefixed names)
140
+ - keywords: Array of 3-5 searchable terms (include tool names, patterns, technologies)
141
+ - message_count: Total messages in conversation (use actual count)
142
+ - uuid: "${sessionId}"
143
+ - archive_path: "~/.claude-mem/archives/${sessionId}.jsonl.archive"
144
+
145
+ MCP TOOL USAGE:
146
+ 1. FIRST: Call create_entities for each distinct concept/component/decision
147
+ - Create session entity: ${projectName}_Session_${sessionId}
148
+ - Create entities for major components/patterns/decisions
149
+ - Include rich observations with keywords and metadata
150
+ 2. THEN: Call create_relations to link related entities
151
+ - Link entities to session entity
152
+ - Create tool chain relationships via parent_tool_use_id
153
+ - Connect new entities to existing ones (if incremental)
154
+ 3. FINALLY: Return JSONL summaries referencing created entities
155
+
156
+ INDEXING PRIORITIES:
157
+ - Prioritize entities that will be valuable for future code recall
158
+ - Focus on reusable patterns and solutions
159
+ - Capture decision rationale and trade-offs
160
+ - Include error patterns and their fixes
161
+ - Document integration points and API usage
162
+ - Note performance optimizations and their impact
163
+ - Create entities for tool chains and workflows
164
+
165
+ Project: ${projectName}
166
+ Session ID: ${sessionId}
167
+
168
+ CRITICAL REQUIREMENTS:
169
+ - Create 3-15 entities depending on conversation complexity
170
+ - Create 5-20 relationships showing entity connections
171
+ - Return 3-10 JSONL index entries (one JSON object per line, NOT an array)
172
+ - Each line must be valid JSON parseable with JSON.parse()
173
+ - Each line must have ALL required fields (timestamp, session_id, project, summary, nodes, keywords, message_count, uuid, archive_path)
174
+ - Use EXACT session ID without prefixes
175
+ - Focus on creating a searchable index for future development
176
+ - Original transcript will be archived as ${sessionId}.jsonl.archive
177
+ ${hasCompressedContent ? '- Build upon existing entities, do not duplicate them' : ''}
178
+
179
+ Conversation to compress:`;
180
+ }
181
+ /**
182
+ * Helper function to get entity type descriptions
183
+ */
184
+ function getEntityTypeDescription(type) {
185
+ const descriptions = {
186
+ component: "UI components, modules, services",
187
+ pattern: "Architectural or design patterns",
188
+ workflow: "Processes, pipelines, sequences",
189
+ integration: "APIs, external services, data sources",
190
+ concept: "Abstract ideas, methodologies, principles",
191
+ decision: "Design choices, trade-offs, solutions",
192
+ tool: "Utilities, libraries, development tools",
193
+ fix: "Bug fixes, patches, workarounds"
194
+ };
195
+ return descriptions[type];
196
+ }
197
+ /**
198
+ * Creates example output for the analysis prompt
199
+ */
200
+ function createExampleOutput(projectName, sessionId) {
201
+ return `{"timestamp":"${new Date().toISOString()}","session_id":"${sessionId}","project":"${projectName}","summary":"Implemented Redis caching system with TTL support and connection pooling","nodes":["${projectName}_Component_RedisCache","${projectName}_Pattern_ConnectionPool"],"keywords":["redis","caching","ttl","connection_pooling"],"message_count":42,"uuid":"${sessionId}","archive_path":"~/.claude-mem/archives/${sessionId}.jsonl.archive"}
202
+ {"timestamp":"${new Date().toISOString()}","session_id":"${sessionId}","project":"${projectName}","summary":"Built JWT authentication with refresh tokens and role-based access control","nodes":["${projectName}_Component_JWTAuth","${projectName}_Decision_RoleManager","${projectName}_Pattern_RefreshToken"],"keywords":["jwt","authentication","rbac","security","refresh_token"],"message_count":35,"uuid":"${sessionId}","archive_path":"~/.claude-mem/archives/${sessionId}.jsonl.archive"}
203
+ {"timestamp":"${new Date().toISOString()}","session_id":"${sessionId}","project":"${projectName}","summary":"Fixed WebSocket memory leak by implementing proper connection cleanup handlers","nodes":["${projectName}_Fix_WebSocketLeak","${projectName}_Component_ConnectionCleanup"],"keywords":["websocket","memory_leak","cleanup","debugging"],"message_count":28,"uuid":"${sessionId}","archive_path":"~/.claude-mem/archives/${sessionId}.jsonl.archive"}`;
204
+ }
205
+ // =============================================================================
206
+ // CONTEXT PRIMING TEMPLATES
207
+ // =============================================================================
208
+ /**
209
+ * System message templates for context priming
210
+ */
211
+ export const CONTEXT_TEMPLATES = {
212
+ PRIMARY_CONTEXT: (projectName) => `Context primed for project: ${projectName}. Access memories with search_nodes("${projectName}*") or open_nodes(["entity_name"]).`,
213
+ RECENT_SESSIONS: (sessionList) => `Recent sessions available: ${sessionList}`,
214
+ AVAILABLE_ENTITIES: (type, entities, hasMore, moreCount) => `Available ${type} entities: ${entities.join(', ')}${hasMore ? ` (+${moreCount} more)` : ''}`,
215
+ SESSION_START_HEADER: '🧠 Active Working Context from Previous Sessions:',
216
+ SESSION_START_SEPARATOR: '═'.repeat(70),
217
+ RESUME_INSTRUCTIONS: `💡 TO RESUME: Load active components with open_nodes(["<exact_names>"])
218
+ 📊 TO EXPLORE: Search related work with search_nodes("<keywords>")`
219
+ };
220
+ // =============================================================================
221
+ // SESSION START OUTPUT TEMPLATES
222
+ // =============================================================================
223
+ /**
224
+ * Session start formatting templates
225
+ */
226
+ export const SESSION_START_TEMPLATES = {
227
+ FOCUS_LINE: (focus) => `📌 CURRENT FOCUS: ${focus}`,
228
+ LAST_WORKED: (timeAgo, projectName) => `Last worked: ${timeAgo} | Project: ${projectName}`,
229
+ SECTIONS: {
230
+ COMPONENTS: '🎯 ACTIVE COMPONENTS (load these for context):',
231
+ DECISIONS: '🔄 RECENT DECISIONS & PATTERNS:',
232
+ TOOLS: '🛠️ TOOLS & INFRASTRUCTURE:',
233
+ FIXES: '🐛 RECENT FIXES:',
234
+ ACTIONS: '⚡ NEXT ACTIONS:'
235
+ },
236
+ ACTION_PREFIX: '□ ',
237
+ ENTITY_BULLET: '• '
238
+ };
239
+ /**
240
+ * Time formatting for "time ago" displays
241
+ */
242
+ export const TIME_FORMATS = {
243
+ JUST_NOW: 'just now',
244
+ HOURS_AGO: (hours) => `${hours} hour${hours > 1 ? 's' : ''} ago`,
245
+ DAYS_AGO: (days) => `${days} day${days > 1 ? 's' : ''} ago`,
246
+ RECENTLY: 'recently'
247
+ };
248
+ // =============================================================================
249
+ // HOOK RESPONSE TEMPLATES
250
+ // =============================================================================
251
+ /**
252
+ * Standard hook response structures for Claude Code integration
253
+ */
254
+ export const HOOK_RESPONSES = {
255
+ SUCCESS: (hookEventName, message) => ({
256
+ hookSpecificOutput: {
257
+ hookEventName,
258
+ status: "success",
259
+ message
260
+ },
261
+ suppressOutput: true
262
+ }),
263
+ SKIPPED: (hookEventName, message) => ({
264
+ hookSpecificOutput: {
265
+ hookEventName,
266
+ status: "skipped",
267
+ message
268
+ },
269
+ suppressOutput: true
270
+ }),
271
+ BLOCKED: (reason) => ({
272
+ decision: "block",
273
+ reason
274
+ }),
275
+ CONTINUE: (hookEventName, additionalContext) => ({
276
+ continue: true,
277
+ ...(additionalContext && {
278
+ hookSpecificOutput: {
279
+ hookEventName,
280
+ additionalContext
281
+ }
282
+ })
283
+ }),
284
+ ERROR: (reason) => ({
285
+ decision: "block",
286
+ reason
287
+ })
288
+ };
289
+ /**
290
+ * Pre-defined hook messages
291
+ */
292
+ export const HOOK_MESSAGES = {
293
+ COMPRESSION_SUCCESS: "Memory compression completed successfully",
294
+ COMPRESSION_SKIPPED: "Compression skipped - Claude SDK not available in this context",
295
+ COMPRESSION_FAILED: (stderr) => `Compression failed: ${stderr}`,
296
+ CONTEXT_LOADED: "Project context loaded successfully",
297
+ CONTEXT_SKIPPED: "Continuing session - context loading skipped",
298
+ NO_TRANSCRIPT: "No transcript path provided",
299
+ HOOK_ERROR: (error) => `Hook error: ${error}`
300
+ };
301
+ // =============================================================================
302
+ // CONFIGURATION TEMPLATES
303
+ // =============================================================================
304
+ /**
305
+ * MCP server configuration template
306
+ */
307
+ export const MCP_CONFIG_TEMPLATE = {
308
+ "claude-mem": {
309
+ command: "npx",
310
+ args: ["-y", "@modelcontextprotocol/server-memory"]
311
+ }
312
+ };
313
+ /**
314
+ * Hook configuration templates for Claude settings
315
+ */
316
+ export const HOOK_CONFIG_TEMPLATES = {
317
+ PRE_COMPACT: (scriptPath) => ({
318
+ pattern: "*",
319
+ hooks: [{
320
+ type: "command",
321
+ command: scriptPath,
322
+ timeout: 180000
323
+ }]
324
+ }),
325
+ SESSION_START: (scriptPath) => ({
326
+ pattern: "*",
327
+ hooks: [{
328
+ type: "command",
329
+ command: scriptPath,
330
+ timeout: 30000
331
+ }]
332
+ }),
333
+ SESSION_END: (scriptPath) => ({
334
+ pattern: "*",
335
+ hooks: [{
336
+ type: "command",
337
+ command: scriptPath,
338
+ timeout: 180000
339
+ }]
340
+ })
341
+ };
342
+ // =============================================================================
343
+ // CLI MESSAGES AND STATUS TEMPLATES
344
+ // =============================================================================
345
+ /**
346
+ * Command-line interface messages
347
+ */
348
+ export const CLI_MESSAGES = {
349
+ INSTALLATION: {
350
+ STARTING: '🚀 Installing Claude Memory System with embedded Weaviate...',
351
+ SUCCESS: '🎉 Installation complete! Embedded vector database ready.',
352
+ HOOKS_INSTALLED: '✅ Installed hooks to ~/.claude-mem/hooks/',
353
+ MCP_CONFIGURED: (path) => `✅ Configured MCP memory server in ${path}`,
354
+ EMBEDDED_READY: '🧠 Embedded Weaviate initialized for persistent semantic memory',
355
+ ALREADY_INSTALLED: '⚠️ Claude Memory hooks are already installed.',
356
+ USE_FORCE: ' Use --force to overwrite existing installation.',
357
+ SETTINGS_WRITTEN: (type, path) => `✅ Installed hooks in ${type} settings\n Settings file: ${path}`
358
+ },
359
+ NEXT_STEPS: [
360
+ '1. Restart Claude Code to load the new hooks',
361
+ '2. Use `/clear` and `/compact` in Claude Code to save and compress session memories',
362
+ '3. New sessions will automatically load relevant context'
363
+ ],
364
+ ERRORS: {
365
+ HOOKS_NOT_FOUND: '❌ Hook source files not found',
366
+ SETTINGS_WRITE_FAILED: (path, error) => `❌ Failed to write settings file: ${error}\n Path: ${path}`,
367
+ MCP_CONFIG_PARSE_FAILED: (error) => `⚠️ Warning: Could not parse existing MCP config: ${error}`,
368
+ MCP_CONFIG_WRITE_FAILED: (error) => `⚠️ Warning: Could not write MCP config: ${error}`,
369
+ COMPRESSION_FAILED: (error) => `❌ Compression failed: ${error}`,
370
+ CONTEXT_LOAD_FAILED: (error) => `❌ Failed to load context: ${error}`
371
+ },
372
+ STATUS: {
373
+ NO_INDEX: '📚 No memory index found. Starting fresh session.',
374
+ NO_MATCHES: '📚 No matching memories found in index.',
375
+ RECENT_MEMORIES: '🧠 Recent memories from previous sessions:',
376
+ MEMORY_COUNT: (count) => `📚 Showing ${count} most recent memories`,
377
+ FULL_CONTEXT_AVAILABLE: '💡 Full context available via MCP memory tools'
378
+ }
379
+ };
380
+ // =============================================================================
381
+ // DEBUG AND LOGGING TEMPLATES
382
+ // =============================================================================
383
+ /**
384
+ * Debug logging message templates
385
+ */
386
+ export const DEBUG_MESSAGES = {
387
+ COMPRESSION_STARTED: '🚀 COMPRESSION STARTED',
388
+ TRANSCRIPT_PATH: (path) => `📁 Transcript Path: ${path}`,
389
+ SESSION_ID: (id) => `🔍 Session ID: ${id}`,
390
+ PROJECT_NAME: (name) => `📝 PROJECT NAME: ${name}`,
391
+ CLAUDE_SDK_CALL: '🤖 Calling Claude SDK to analyze and populate knowledge graph...',
392
+ TRANSCRIPT_STATS: (size, count) => `📊 Transcript size: ${size} characters, ${count} messages`,
393
+ COMPRESSION_COMPLETE: (count) => `✅ COMPRESSION COMPLETE\n Total summaries extracted: ${count}`,
394
+ CLAUDE_PATH_FOUND: (path) => `🎯 Found Claude Code at: ${path}`,
395
+ MCP_CONFIG_USED: (path) => `📋 Using MCP config: ${path}`
396
+ };
397
+ // =============================================================================
398
+ // SEARCH AND QUERY TEMPLATES
399
+ // =============================================================================
400
+ /**
401
+ * Knowledge graph search templates
402
+ */
403
+ export const SEARCH_TEMPLATES = {
404
+ SEARCH_SCRIPT: (query) => `
405
+ import { query } from "@anthropic-ai/claude-code";
406
+
407
+ const searchQuery = process.env.SEARCH_QUERY || '';
408
+
409
+ const result = await query({
410
+ prompt: "Search for: " + searchQuery,
411
+ options: {
412
+ mcpConfig: "~/.claude/.mcp.json",
413
+ allowedTools: ["mcp__memory__search_nodes"],
414
+ outputFormat: "json"
415
+ }
416
+ });
417
+
418
+ console.log(JSON.stringify(result));
419
+ `,
420
+ SEARCH_PREFIX: "Search for: "
421
+ };
422
+ // =============================================================================
423
+ // WEAVIATE INTEGRATION CONSTANTS
424
+ // =============================================================================
425
+ /**
426
+ * Weaviate MCP server configuration template
427
+ */
428
+ export const WEAVIATE_MCP_CONFIG = {
429
+ "claude-mem": {
430
+ command: process.platform === 'win32'
431
+ ? "C:\\path\\to\\mcp-server.exe"
432
+ : "/usr/local/bin/mcp-server-weaviate"
433
+ }
434
+ };
435
+ /**
436
+ * Weaviate collection names for entities and relations
437
+ */
438
+ export const WEAVIATE_COLLECTIONS = {
439
+ ENTITIES: 'claude_mem_entities',
440
+ RELATIONS: 'claude_mem_relations'
441
+ };
442
+ /**
443
+ * Default Weaviate configuration values
444
+ */
445
+ export const WEAVIATE_DEFAULTS = {
446
+ HOST: 'localhost:8080',
447
+ SCHEME: 'http',
448
+ MCP_PATH: '/usr/local/bin/mcp-server-weaviate'
449
+ };
450
+ /**
451
+ * Weaviate-specific CLI messages
452
+ */
453
+ export const WEAVIATE_MESSAGES = {
454
+ CONNECTION: {
455
+ CONNECTING: '🔗 Connecting to Weaviate server...',
456
+ CONNECTED: '✅ Connected to Weaviate successfully',
457
+ FAILED: (error) => `❌ Failed to connect to Weaviate: ${error}`,
458
+ DISCONNECTED: '👋 Disconnected from Weaviate'
459
+ },
460
+ MIGRATION: {
461
+ STARTING: '🚀 Starting migration to Weaviate backend...',
462
+ READING_INDEX: '📖 Reading existing memory index files...',
463
+ MIGRATING_ENTITIES: (count) => `🔄 Migrating ${count} entities to Weaviate...`,
464
+ MIGRATING_RELATIONS: (count) => `🔗 Migrating ${count} relations to Weaviate...`,
465
+ UPDATING_SETTINGS: '⚙️ Updating settings to use Weaviate backend...',
466
+ COMPLETED: '✅ Migration to Weaviate completed successfully',
467
+ FAILED: (error) => `❌ Migration failed: ${error}`,
468
+ NO_DATA: '💡 No existing data found to migrate'
469
+ },
470
+ SEARCH: {
471
+ SEMANTIC_SEARCH: '🧠 Using semantic search with Weaviate...',
472
+ KEYWORD_SEARCH: '🔍 Using keyword search with Weaviate...',
473
+ HYBRID_SEARCH: '🔬 Using hybrid search with Weaviate...',
474
+ NO_RESULTS: '📚 No results found in Weaviate database',
475
+ RESULTS_FOUND: (count) => `📊 Found ${count} results in Weaviate`
476
+ },
477
+ SETUP: {
478
+ STARTING_EMBEDDED: '🚀 Starting embedded Weaviate instance...',
479
+ EMBEDDED_READY: '✅ Embedded Weaviate is ready and accepting connections',
480
+ DOWNLOADING_BINARIES: '⬇️ Downloading Weaviate binaries (first time only)...',
481
+ INITIALIZING_SCHEMA: '📋 Initializing knowledge graph schema...'
482
+ }
483
+ };
484
+ /**
485
+ * Weaviate error messages
486
+ */
487
+ export const WEAVIATE_ERRORS = {
488
+ CONNECTION_FAILED: 'Could not establish connection to Weaviate server',
489
+ MCP_SERVER_NOT_FOUND: 'Weaviate MCP server binary not found at specified path',
490
+ INVALID_COLLECTION: (collection) => `Invalid Weaviate collection: ${collection}`,
491
+ QUERY_FAILED: (query, error) => `Query failed for '${query}': ${error}`,
492
+ ENTITY_CREATION_FAILED: (name) => `Failed to create entity '${name}' in Weaviate`,
493
+ RELATION_CREATION_FAILED: (from, to) => `Failed to create relation '${from}' -> '${to}' in Weaviate`,
494
+ MIGRATION_INCOMPLETE: 'Migration was incomplete - some data may not have been transferred',
495
+ EMBEDDED_START_FAILED: 'Failed to start embedded Weaviate instance - check disk space and permissions',
496
+ SCHEMA_MISMATCH: 'Weaviate schema does not match expected structure'
497
+ };
498
+ /**
499
+ * Export all constants for easy importing
500
+ */
501
+ export const CONSTANTS = {
502
+ ENTITY_NAMING_PATTERNS,
503
+ ENTITY_TYPES,
504
+ OBSERVATION_FIELDS,
505
+ RELATIONSHIP_TYPES,
506
+ CONTEXT_TEMPLATES,
507
+ SESSION_START_TEMPLATES,
508
+ TIME_FORMATS,
509
+ HOOK_RESPONSES,
510
+ HOOK_MESSAGES,
511
+ MCP_CONFIG_TEMPLATE,
512
+ HOOK_CONFIG_TEMPLATES,
513
+ CLI_MESSAGES,
514
+ DEBUG_MESSAGES,
515
+ SEARCH_TEMPLATES,
516
+ // Weaviate constants
517
+ WEAVIATE_MCP_CONFIG,
518
+ WEAVIATE_COLLECTIONS,
519
+ WEAVIATE_DEFAULTS,
520
+ WEAVIATE_MESSAGES,
521
+ WEAVIATE_ERRORS
522
+ };
@@ -0,0 +1,17 @@
1
+ export declare class ErrorHandler {
2
+ private logger;
3
+ private logDir;
4
+ constructor(enableDebug?: boolean);
5
+ private ensureLogDirectory;
6
+ handleHookError(error: Error, hookType: string, payload?: unknown): never;
7
+ handleCompressionError(error: Error, transcriptPath: string, stage: string): never;
8
+ handleValidationError(message: string, context?: Record<string, unknown>): never;
9
+ logSuccess(operation: string, details?: Record<string, unknown>): void;
10
+ logWarning(message: string, details?: Record<string, unknown>): void;
11
+ logDebug(message: string, details?: Record<string, unknown>): void;
12
+ }
13
+ export declare function parseStdinJson<T = unknown>(input: string): T;
14
+ export declare function safeExecute<T>(operation: () => Promise<T>, errorHandler: ErrorHandler, context: string): Promise<T>;
15
+ export declare function validateFileExists(filePath: string, errorHandler: ErrorHandler): void;
16
+ export declare function createHookResponse(success: boolean, data?: Record<string, unknown>): string;
17
+ export declare const globalErrorHandler: ErrorHandler;
@@ -0,0 +1,103 @@
1
+ import { existsSync, mkdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { HookError, CompressionError, FileLogger } from './types.js';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ export class ErrorHandler {
8
+ logger;
9
+ logDir;
10
+ constructor(enableDebug = false) {
11
+ this.logDir = join(__dirname, '..', 'logs');
12
+ this.ensureLogDirectory();
13
+ const logFile = join(this.logDir, `claude-mem-${new Date().toISOString().slice(0, 10)}.log`);
14
+ this.logger = new FileLogger(logFile, enableDebug);
15
+ }
16
+ ensureLogDirectory() {
17
+ if (!existsSync(this.logDir)) {
18
+ mkdirSync(this.logDir, { recursive: true });
19
+ }
20
+ }
21
+ handleHookError(error, hookType, payload) {
22
+ const hookError = error instanceof HookError
23
+ ? error
24
+ : new HookError(error.message, hookType, payload, 'HOOK_EXECUTION_ERROR');
25
+ this.logger.error(`Hook execution failed in ${hookType}`, hookError, {
26
+ hookType,
27
+ payload: payload ? JSON.stringify(payload) : undefined,
28
+ });
29
+ console.log(JSON.stringify({
30
+ continue: false,
31
+ stopReason: `Hook error: ${hookError.message}`,
32
+ error: {
33
+ type: hookError.name,
34
+ message: hookError.message,
35
+ code: hookError.code,
36
+ },
37
+ }));
38
+ process.exit(1);
39
+ }
40
+ handleCompressionError(error, transcriptPath, stage) {
41
+ const compressionError = error instanceof CompressionError
42
+ ? error
43
+ : new CompressionError(error.message, transcriptPath, stage);
44
+ this.logger.error(`Compression failed during ${stage}`, compressionError, {
45
+ transcriptPath,
46
+ stage,
47
+ });
48
+ console.error(`Compression error: ${compressionError.message}`);
49
+ console.error(`Stage: ${stage}`);
50
+ console.error(`Transcript: ${transcriptPath}`);
51
+ process.exit(1);
52
+ }
53
+ handleValidationError(message, context) {
54
+ this.logger.error('Validation error', undefined, { message, context });
55
+ console.error(`Validation error: ${message}`);
56
+ if (context) {
57
+ console.error('Context:', JSON.stringify(context, null, 2));
58
+ }
59
+ process.exit(1);
60
+ }
61
+ logSuccess(operation, details) {
62
+ this.logger.info(`Operation successful: ${operation}`, details);
63
+ }
64
+ logWarning(message, details) {
65
+ this.logger.warn(message, details);
66
+ }
67
+ logDebug(message, details) {
68
+ this.logger.debug(message, details);
69
+ }
70
+ }
71
+ export function parseStdinJson(input) {
72
+ try {
73
+ return JSON.parse(input);
74
+ }
75
+ catch (error) {
76
+ throw new Error(`Failed to parse JSON input: ${error instanceof Error ? error.message : 'Unknown error'}`);
77
+ }
78
+ }
79
+ export async function safeExecute(operation, errorHandler, context) {
80
+ try {
81
+ return await operation();
82
+ }
83
+ catch (error) {
84
+ const message = `Safe execution failed in ${context}: ${error instanceof Error ? error.message : String(error)}`;
85
+ errorHandler.handleValidationError(message, { context, error });
86
+ throw error;
87
+ }
88
+ }
89
+ export function validateFileExists(filePath, errorHandler) {
90
+ if (!existsSync(filePath)) {
91
+ errorHandler.handleValidationError(`File not found: ${filePath}`, {
92
+ filePath,
93
+ });
94
+ }
95
+ }
96
+ export function createHookResponse(success, data) {
97
+ const response = {
98
+ continue: success,
99
+ ...data,
100
+ };
101
+ return JSON.stringify(response);
102
+ }
103
+ export const globalErrorHandler = new ErrorHandler(process.env.DEBUG === 'true');
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * 🔒 LOCKED by @docs-agent | Change to 🔑 to allow @docs-agent edits
4
+ *
5
+ * OFFICIAL DOCS: @modelcontextprotocol/sdk v1.0.0
6
+ * Last Verified: 2025-09-01
7
+ *
8
+ * Claude-mem MCP Server CLI Entry Point
9
+ *
10
+ * This module provides the standalone entry point for running the claude-mem MCP server
11
+ * that communicates with Claude Code via stdio transport.
12
+ *
13
+ * Usage:
14
+ * node dist/mcp-server-cli.js
15
+ * claude-mem-server
16
+ *
17
+ * Communication:
18
+ * - Stdin/Stdout: MCP protocol messages with Claude Code
19
+ * - Stderr: Logging and diagnostic output
20
+ *
21
+ * Architecture:
22
+ * This CLI connects the MCP server to Claude Code via stdio transport,
23
+ * enabling Claude Code to access the embedded Weaviate knowledge graph
24
+ * through standard MCP memory tools.
25
+ *
26
+ * Implementation follows official MCP SDK patterns:
27
+ * - StdioServerTransport for stdin/stdout communication (SDK README.md#_snippet_16)
28
+ * - Server initialization before transport connection
29
+ * - Graceful shutdown handlers for SIGINT/SIGTERM
30
+ * - Error handling for uncaught exceptions
31
+ *
32
+ * @see docs/mcp-sdk/stdio-transport.md for transport patterns
33
+ */
34
+ export {};