claude-recall 0.2.2 → 0.2.3

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 CHANGED
@@ -43,13 +43,26 @@ Launch Claude Code and your memories will be captured automatically. Claude Reca
43
43
 
44
44
  ## How It Works
45
45
 
46
- Claude Recall uses the Model Context Protocol to integrate directly with Claude Code. When you:
47
- - Use tools or run commands - it captures the patterns
48
- - Express preferences - it remembers them
49
- - Make decisions - it stores the context
50
- - Start new conversations - it provides relevant memories
46
+ Claude Recall uses the Model Context Protocol to integrate directly with Claude Code.
51
47
 
52
- All of this happens automatically through MCP, without any manual configuration.
48
+ ### Automatic Memory Capture (v0.2.3+)
49
+
50
+ **Any message containing "remember" will be automatically captured with highest priority.** For example:
51
+ - "Remember that I prefer tabs over spaces"
52
+ - "Remember to use PostgreSQL for the database"
53
+ - "Please remember our API uses port 8080"
54
+
55
+ Additionally, Claude Recall automatically detects and captures:
56
+ - **Preferences**: "I prefer X over Y", "Always use X", "From now on, use Y"
57
+ - **Decisions**: "We decided to...", "Let's go with...", "We'll use..."
58
+ - **Instructions**: "Make sure to...", "Ensure that...", "Files should be in..."
59
+
60
+ ### Manual Memory Storage
61
+
62
+ You can also explicitly ask Claude to store memories using the MCP tools:
63
+ - Use the `mcp__claude-recall__store_memory` tool
64
+ - Search with `mcp__claude-recall__search`
65
+ - Get stats with `mcp__claude-recall__get_stats`
53
66
 
54
67
  ## Real-World Example
55
68
 
@@ -162,6 +175,18 @@ const memories = await mcp__claude-recall__search({
162
175
  })
163
176
  ```
164
177
 
178
+ ### Customizing Memory Patterns
179
+
180
+ Claude Recall uses configurable patterns for automatic memory capture. You can customize these by setting the `CLAUDE_RECALL_PATTERNS_CONFIG` environment variable to point to your own JSON configuration file.
181
+
182
+ Default patterns include:
183
+ - **Explicit remember**: Any sentence with "remember" (confidence: 1.0)
184
+ - **Preferences**: "I prefer", "Always use", "From now on" (confidence: 0.85-0.9)
185
+ - **Locations**: "Should be in X directory" (confidence: 0.8)
186
+ - **Instructions**: "Make sure", "Ensure that" (confidence: 0.7)
187
+
188
+ See `src/config/memory-patterns.json` for the full configuration format.
189
+
165
190
  ## Troubleshooting
166
191
 
167
192
  ### MCP Server Not Found
@@ -178,6 +203,59 @@ If Claude Code can't find the MCP server:
178
203
  2. Check stats: `claude-recall stats`
179
204
  3. Ensure MCP tools are being used in Claude Code
180
205
 
206
+ ### Clearing npm Cache (Version Issues)
207
+
208
+ If you're seeing an old version after installing `@latest`, clear the npm cache:
209
+
210
+ ```bash
211
+ # Complete cache clear and reinstall
212
+ npm uninstall -g claude-recall
213
+ npm cache clean --force
214
+ npm cache verify
215
+ npm install -g claude-recall@latest
216
+
217
+ # Verify the installation
218
+ claude-recall --version
219
+ claude-recall mcp test
220
+ ```
221
+
222
+ ### Diagnostic Commands for Support
223
+
224
+ If you need help troubleshooting, run these commands and share the output:
225
+
226
+ ```bash
227
+ """# 1. Check Installation
228
+ claude-recall --version
229
+ which claude-recall
230
+ npm list -g claude-recall
231
+
232
+ # 2. Check MCP Configuration
233
+ cat ~/.claude.json | grep -A10 "claude-recall"
234
+ claude-recall mcp test
235
+
236
+ # 3. Check Database
237
+ ls -la ~/.claude-recall/
238
+ ls -lh ~/.claude-recall/claude-recall.db 2>/dev/null || echo "Database not found"
239
+
240
+ # 4. Check System Status
241
+ claude-recall status
242
+ claude-recall stats
243
+
244
+ # 5. Test Basic Functionality
245
+ claude-recall search "test"
246
+ claude-recall stats | grep "Total memories"
247
+
248
+ # 6. Check for Errors
249
+ ls -la *.log 2>/dev/null || echo "No log files"
250
+ tail -20 info.log 2>/dev/null || echo "No info log"
251
+
252
+ # 7. Environment Info
253
+ node --version
254
+ npm --version
255
+ echo "OS: $(uname -s)"
256
+ echo "Home: $HOME""""
257
+ ```
258
+
181
259
  ## Contributing
182
260
 
183
261
  We welcome contributions! Claude Recall is designed to be hackable:
@@ -251,7 +251,7 @@ async function main() {
251
251
  program
252
252
  .name('claude-recall')
253
253
  .description('Memory-enhanced Claude Code via MCP')
254
- .version('0.2.2')
254
+ .version('0.2.3')
255
255
  .option('--verbose', 'Enable verbose logging')
256
256
  .option('--config <path>', 'Path to custom config file');
257
257
  // MCP command
@@ -0,0 +1,64 @@
1
+ {
2
+ "preferencePatterns": [
3
+ {
4
+ "pattern": "(?:I prefer|I'd prefer|prefer|preferring)\\s+([\\w\\s]+)\\s+(?:over|instead of|rather than)\\s+([\\w\\s]+)",
5
+ "type": "preference",
6
+ "confidence": 0.9,
7
+ "extractionMode": "comparison"
8
+ },
9
+ {
10
+ "pattern": "(?:always use|always using|we always use)\\s+([\\w\\s\\-\\.]+)",
11
+ "type": "preference",
12
+ "confidence": 0.85,
13
+ "extractionMode": "directive"
14
+ },
15
+ {
16
+ "pattern": "(?:from now on|moving forward|going forward)(?:,)?\\s+(?:use|we'll use|let's use)\\s+([\\w\\s\\-\\.]+)",
17
+ "type": "decision",
18
+ "confidence": 0.9,
19
+ "extractionMode": "future_directive"
20
+ },
21
+ {
22
+ "pattern": "(?:should be|must be|needs to be)\\s+(?:in|at|under)\\s+(?:the)?\\s+([\\w\\/\\-\\.]+)\\s+(?:directory|folder|dir)",
23
+ "type": "location_preference",
24
+ "confidence": 0.8,
25
+ "extractionMode": "location"
26
+ },
27
+ {
28
+ "pattern": "(?:make sure|ensure)\\s+(?:to|that)\\s+([^.!?]+)",
29
+ "type": "instruction",
30
+ "confidence": 0.7,
31
+ "extractionMode": "requirement"
32
+ },
33
+ {
34
+ "pattern": "(?:remember|Remember)\\s+(?:that\\s+)?(.+?)(?:[.!?]|$)",
35
+ "type": "explicit_memory",
36
+ "confidence": 1.0,
37
+ "extractionMode": "direct_capture"
38
+ }
39
+ ],
40
+ "actionPatterns": [
41
+ {
42
+ "pattern": "(?:creating|created|adding|added)\\s+(?:a|an|the)?\\s*([\\w\\s]+)\\s+(?:in|at|to)\\s+([\\w\\/\\-\\.]+)",
43
+ "type": "file_creation",
44
+ "confidence": 0.75
45
+ },
46
+ {
47
+ "pattern": "(?:using|used|chose|chosen)\\s+([\\w\\s\\-\\.]+)\\s+(?:for|as)\\s+(?:the)?\\s*([\\w\\s]+)",
48
+ "type": "tool_choice",
49
+ "confidence": 0.8
50
+ }
51
+ ],
52
+ "contextTriggers": {
53
+ "highConfidenceWords": ["always", "never", "must", "should", "prefer", "requirement", "important"],
54
+ "decisionIndicators": ["decided", "choosing", "selected", "going with", "settled on"],
55
+ "futureTense": ["will", "going to", "from now on", "moving forward", "next time"]
56
+ },
57
+ "captureSettings": {
58
+ "minConfidence": 0.7,
59
+ "requireExplicitConfirmation": false,
60
+ "batchProcessingDelay": 1000,
61
+ "maxMemoriesPerSession": 50,
62
+ "deduplicationWindow": 3600000
63
+ }
64
+ }
@@ -0,0 +1,314 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MemoryCaptureMiddleware = void 0;
37
+ const preference_extractor_1 = require("../services/preference-extractor");
38
+ const action_pattern_detector_1 = require("../services/action-pattern-detector");
39
+ const memory_1 = require("../services/memory");
40
+ const logging_1 = require("../services/logging");
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ class MemoryCaptureMiddleware {
44
+ constructor() {
45
+ this.recentCaptures = new Map();
46
+ this.sessionMemoryCount = new Map();
47
+ this.preferenceExtractor = new preference_extractor_1.PreferenceExtractor();
48
+ this.actionDetector = new action_pattern_detector_1.ActionPatternDetector();
49
+ this.memoryService = memory_1.MemoryService.getInstance();
50
+ this.logger = logging_1.LoggingService.getInstance();
51
+ this.loadConfig();
52
+ }
53
+ loadConfig() {
54
+ try {
55
+ // First try custom config location
56
+ const customConfigPath = process.env.CLAUDE_RECALL_PATTERNS_CONFIG;
57
+ const defaultConfigPath = path.join(__dirname, '../../config/memory-patterns.json');
58
+ const configPath = customConfigPath && fs.existsSync(customConfigPath)
59
+ ? customConfigPath
60
+ : defaultConfigPath;
61
+ if (fs.existsSync(configPath)) {
62
+ const configContent = fs.readFileSync(configPath, 'utf-8');
63
+ this.config = JSON.parse(configContent);
64
+ this.logger.info('MemoryCaptureMiddleware', 'Loaded memory patterns config', { configPath });
65
+ }
66
+ else {
67
+ // Use default config if file doesn't exist
68
+ this.config = this.getDefaultConfig();
69
+ this.logger.warn('MemoryCaptureMiddleware', 'Using default config, no config file found');
70
+ }
71
+ }
72
+ catch (error) {
73
+ this.logger.error('MemoryCaptureMiddleware', 'Failed to load config, using defaults', error);
74
+ this.config = this.getDefaultConfig();
75
+ }
76
+ }
77
+ getDefaultConfig() {
78
+ return {
79
+ preferencePatterns: [
80
+ {
81
+ pattern: "(?:I prefer|prefer)\\s+([\\w\\s]+)\\s+(?:over|instead of)\\s+([\\w\\s]+)",
82
+ type: "preference",
83
+ confidence: 0.9,
84
+ extractionMode: "comparison"
85
+ }
86
+ ],
87
+ actionPatterns: [],
88
+ contextTriggers: {
89
+ highConfidenceWords: ["always", "never", "must", "prefer"],
90
+ decisionIndicators: ["decided", "choosing", "selected"],
91
+ futureTense: ["will", "going to", "from now on"]
92
+ },
93
+ captureSettings: {
94
+ minConfidence: 0.7,
95
+ requireExplicitConfirmation: false,
96
+ batchProcessingDelay: 1000,
97
+ maxMemoriesPerSession: 50,
98
+ deduplicationWindow: 3600000
99
+ }
100
+ };
101
+ }
102
+ /**
103
+ * Process a request/response pair for automatic memory capture
104
+ */
105
+ async processForMemoryCapture(request, response, sessionId) {
106
+ try {
107
+ // Don't capture from memory-related tools to avoid loops
108
+ if (request.method === 'tools/call' &&
109
+ request.params?.name?.includes('memory')) {
110
+ return;
111
+ }
112
+ // Extract content to analyze
113
+ const contentToAnalyze = this.extractContent(request, response);
114
+ if (!contentToAnalyze)
115
+ return;
116
+ // Check session memory limit
117
+ const sessionCount = this.sessionMemoryCount.get(sessionId) || 0;
118
+ if (sessionCount >= this.config.captureSettings.maxMemoriesPerSession) {
119
+ this.logger.debug('MemoryCaptureMiddleware', 'Session memory limit reached', { sessionId, count: sessionCount });
120
+ return;
121
+ }
122
+ // Analyze for patterns
123
+ const detectedMemories = await this.analyzeContent(contentToAnalyze, sessionId);
124
+ // Store unique memories
125
+ for (const memory of detectedMemories) {
126
+ if (this.shouldCapture(memory, sessionId)) {
127
+ await this.captureMemory(memory, sessionId);
128
+ }
129
+ }
130
+ }
131
+ catch (error) {
132
+ this.logger.error('MemoryCaptureMiddleware', 'Error in memory capture', error);
133
+ }
134
+ }
135
+ extractContent(request, response) {
136
+ let content = '';
137
+ // Extract from request
138
+ if (request.params?.arguments?.content) {
139
+ content += request.params.arguments.content + '\n';
140
+ }
141
+ // Extract from response
142
+ if (response.result?.content) {
143
+ if (Array.isArray(response.result.content)) {
144
+ response.result.content.forEach((item) => {
145
+ if (item.text)
146
+ content += item.text + '\n';
147
+ });
148
+ }
149
+ else if (typeof response.result.content === 'string') {
150
+ content += response.result.content + '\n';
151
+ }
152
+ }
153
+ return content.trim() || null;
154
+ }
155
+ async analyzeContent(content, sessionId) {
156
+ const memories = [];
157
+ // PRIORITY 1: Check for explicit "remember" commands
158
+ const rememberRegex = /(?:remember|Remember)\s+(?:that\s+)?(.+?)(?:[.!?]|$)/gi;
159
+ const rememberMatches = content.matchAll(rememberRegex);
160
+ for (const match of rememberMatches) {
161
+ const memoryContent = match[1].trim();
162
+ if (memoryContent) {
163
+ memories.push({
164
+ type: 'explicit_memory',
165
+ content: memoryContent,
166
+ data: {
167
+ raw: memoryContent,
168
+ source: 'explicit_remember_command',
169
+ confidence: 1.0
170
+ },
171
+ confidence: 1.0, // Always highest confidence
172
+ priority: 1 // Highest priority
173
+ });
174
+ }
175
+ }
176
+ // PRIORITY 2: Use configured preference patterns
177
+ for (const pattern of this.config.preferencePatterns) {
178
+ const regex = new RegExp(pattern.pattern, 'gi');
179
+ const matches = content.matchAll(regex);
180
+ for (const match of matches) {
181
+ // Skip if this was already captured as explicit memory
182
+ if (match[0].toLowerCase().includes('remember'))
183
+ continue;
184
+ memories.push({
185
+ type: pattern.type,
186
+ content: match[0],
187
+ data: {
188
+ pattern: pattern.type,
189
+ captured: match.slice(1),
190
+ confidence: pattern.confidence,
191
+ extractionMode: pattern.extractionMode
192
+ },
193
+ confidence: pattern.confidence,
194
+ priority: 2
195
+ });
196
+ }
197
+ }
198
+ // PRIORITY 3: Use existing PreferenceExtractor
199
+ const preferences = this.preferenceExtractor.extractPreferences(content);
200
+ for (const pref of preferences) {
201
+ if (pref.confidence >= this.config.captureSettings.minConfidence) {
202
+ // Skip if already captured as explicit memory
203
+ if (pref.raw.toLowerCase().includes('remember'))
204
+ continue;
205
+ memories.push({
206
+ type: 'preference',
207
+ content: pref.raw,
208
+ data: {
209
+ key: pref.key,
210
+ value: pref.value,
211
+ confidence: pref.confidence
212
+ },
213
+ confidence: pref.confidence,
214
+ priority: 3
215
+ });
216
+ }
217
+ }
218
+ // Check for action patterns using configured patterns
219
+ for (const pattern of this.config.actionPatterns) {
220
+ const regex = new RegExp(pattern.pattern, 'gi');
221
+ const matches = content.matchAll(regex);
222
+ for (const match of matches) {
223
+ memories.push({
224
+ type: pattern.type,
225
+ content: match[0],
226
+ data: {
227
+ pattern: pattern.type,
228
+ captured: match.slice(1),
229
+ confidence: pattern.confidence
230
+ },
231
+ confidence: pattern.confidence
232
+ });
233
+ }
234
+ }
235
+ // Check for high-confidence context triggers
236
+ const hasHighConfidenceContext = this.config.contextTriggers.highConfidenceWords.some(word => content.toLowerCase().includes(word.toLowerCase()));
237
+ if (hasHighConfidenceContext) {
238
+ // Boost confidence for all found patterns
239
+ memories.forEach(m => m.confidence = Math.min(1.0, m.confidence * 1.1));
240
+ }
241
+ return memories;
242
+ }
243
+ shouldCapture(memory, sessionId) {
244
+ // ALWAYS capture explicit "remember" commands
245
+ if (memory.type === 'explicit_memory' || memory.priority === 1) {
246
+ return true;
247
+ }
248
+ // Check confidence threshold for other types
249
+ if (memory.confidence < this.config.captureSettings.minConfidence) {
250
+ return false;
251
+ }
252
+ // Check for duplicates within deduplication window
253
+ const memoryKey = `${memory.type}:${memory.content}`;
254
+ const lastCapture = this.recentCaptures.get(memoryKey);
255
+ const now = Date.now();
256
+ if (lastCapture && (now - lastCapture) < this.config.captureSettings.deduplicationWindow) {
257
+ return false;
258
+ }
259
+ return true;
260
+ }
261
+ async captureMemory(memory, sessionId) {
262
+ try {
263
+ // Store using MemoryService
264
+ const stored = this.memoryService.store({
265
+ key: `auto_${memory.type}_${Date.now()}`,
266
+ value: memory.data,
267
+ type: memory.type,
268
+ context: {
269
+ projectId: sessionId,
270
+ type: 'auto_capture',
271
+ timestamp: Date.now()
272
+ }
273
+ });
274
+ // Update tracking
275
+ const memoryKey = `${memory.type}:${memory.content}`;
276
+ this.recentCaptures.set(memoryKey, Date.now());
277
+ const currentCount = this.sessionMemoryCount.get(sessionId) || 0;
278
+ this.sessionMemoryCount.set(sessionId, currentCount + 1);
279
+ this.logger.info('MemoryCaptureMiddleware', 'Auto-captured memory', {
280
+ type: memory.type,
281
+ confidence: memory.confidence,
282
+ sessionId
283
+ });
284
+ }
285
+ catch (error) {
286
+ this.logger.error('MemoryCaptureMiddleware', 'Failed to capture memory', error);
287
+ }
288
+ }
289
+ /**
290
+ * Clean up old session data
291
+ */
292
+ cleanupSessions() {
293
+ // Clean up old captures
294
+ const now = Date.now();
295
+ const cutoff = now - this.config.captureSettings.deduplicationWindow;
296
+ for (const [key, timestamp] of this.recentCaptures) {
297
+ if (timestamp < cutoff) {
298
+ this.recentCaptures.delete(key);
299
+ }
300
+ }
301
+ // Reset session counts periodically
302
+ if (this.sessionMemoryCount.size > 100) {
303
+ this.sessionMemoryCount.clear();
304
+ }
305
+ }
306
+ /**
307
+ * Reload configuration (useful for hot-reloading)
308
+ */
309
+ reloadConfig() {
310
+ this.loadConfig();
311
+ this.logger.info('MemoryCaptureMiddleware', 'Configuration reloaded');
312
+ }
313
+ }
314
+ exports.MemoryCaptureMiddleware = MemoryCaptureMiddleware;
@@ -7,6 +7,7 @@ const memory_1 = require("../services/memory");
7
7
  const logging_1 = require("../services/logging");
8
8
  const session_manager_1 = require("./session-manager");
9
9
  const rate_limiter_1 = require("./rate-limiter");
10
+ const memory_capture_middleware_1 = require("./memory-capture-middleware");
10
11
  class MCPServer {
11
12
  constructor() {
12
13
  this.tools = new Map();
@@ -21,31 +22,45 @@ class MCPServer {
21
22
  maxRequests: 100, // 100 requests per minute
22
23
  skipSuccessfulRequests: false
23
24
  });
25
+ this.memoryCaptureMiddleware = new memory_capture_middleware_1.MemoryCaptureMiddleware();
24
26
  this.setupRequestHandlers();
25
27
  this.registerTools();
26
28
  }
27
29
  setupRequestHandlers() {
28
30
  this.transport.onRequest(async (request) => {
31
+ let response;
29
32
  try {
30
33
  switch (request.method) {
31
34
  case 'initialize':
32
- return this.handleInitialize(request);
35
+ response = await this.handleInitialize(request);
36
+ break;
33
37
  case 'tools/list':
34
- return this.handleToolsList(request);
38
+ response = await this.handleToolsList(request);
39
+ break;
35
40
  case 'tools/call':
36
- return this.handleToolCall(request);
41
+ response = await this.handleToolCall(request);
42
+ break;
37
43
  case 'notifications/initialized':
38
- return this.handleInitialized(request);
44
+ response = await this.handleInitialized(request);
45
+ break;
39
46
  case 'health/check':
40
- return this.handleHealthCheck(request);
47
+ response = await this.handleHealthCheck(request);
48
+ break;
41
49
  default:
42
- return this.createErrorResponse(request.id, -32601, `Method not found: ${request.method}`);
50
+ response = this.createErrorResponse(request.id, -32601, `Method not found: ${request.method}`);
43
51
  }
44
52
  }
45
53
  catch (error) {
46
54
  this.logger.logServiceError('MCPServer', 'handleRequest', error, { method: request.method });
47
- return this.createErrorResponse(request.id, -32603, 'Internal error', { message: error.message });
55
+ response = this.createErrorResponse(request.id, -32603, 'Internal error', { message: error.message });
48
56
  }
57
+ // Process for automatic memory capture (non-blocking)
58
+ if (this.isInitialized && request.method === 'tools/call') {
59
+ const sessionId = request.params?.arguments?.sessionId || this.generateSessionId();
60
+ this.memoryCaptureMiddleware.processForMemoryCapture(request, response, sessionId)
61
+ .catch(err => this.logger.error('MCPServer', 'Memory capture failed', err));
62
+ }
63
+ return response;
49
64
  });
50
65
  }
51
66
  registerTools() {
@@ -257,6 +272,8 @@ class MCPServer {
257
272
  this.sessionManager.shutdown();
258
273
  // Shutdown rate limiter
259
274
  this.rateLimiter.shutdown();
275
+ // Clean up memory capture middleware
276
+ this.memoryCaptureMiddleware.cleanupSessions();
260
277
  await this.transport.stop();
261
278
  this.memoryService.close();
262
279
  this.logger.info('MCPServer', 'MCP server stopped');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-recall",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "MCP server for persistent memory in Claude Code conversations",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -21,7 +21,7 @@
21
21
  "postinstall": "node scripts/postinstall.js || true",
22
22
  "test": "jest --passWithNoTests",
23
23
  "test:watch": "jest --watch",
24
- "build": "tsc && mkdir -p dist/memory && cp src/memory/schema.sql dist/memory/ && chmod +x dist/cli/claude-recall-cli.js",
24
+ "build": "tsc && mkdir -p dist/memory dist/config && cp src/memory/schema.sql dist/memory/ && cp -r src/config/* dist/config/ 2>/dev/null || true && chmod +x dist/cli/claude-recall-cli.js",
25
25
  "build:cli": "tsc && chmod +x dist/cli/claude-recall-cli.js",
26
26
  "dev": "ts-node",
27
27
  "start": "ts-node src/server.ts",