specmem-hardwicksoftware 3.7.46 → 3.7.48

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.
@@ -0,0 +1,448 @@
1
+ # SpecMem Search Tools - HOW TO USE
2
+
3
+ This document provides a comprehensive guide to using SpecMem's semantic search tools: `find_code_pointers` and `find_memory`. These tools use embeddings to search by meaning rather than keywords.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Introduction](#introduction)
10
+ 2. [Query Formulation (CRITICAL)](#query-formulation-critical)
11
+ 3. [find_code_pointers - Semantic Code Search](#find_code_pointers---semantic-code-search)
12
+ 4. [find_memory - Semantic Memory Search](#find_memory---semantic-memory-search)
13
+ 5. [Timeout Behavior](#timeout-behavior)
14
+ 6. [Common Mistakes](#common-mistakes)
15
+ 7. [Best Practices](#best-practices)
16
+ 8. [Troubleshooting](#troubleshooting)
17
+
18
+ ---
19
+
20
+ ## Introduction
21
+
22
+ SpecMem provides two powerful semantic search tools:
23
+
24
+ ### find_code_pointers
25
+ - **Purpose**: Search your codebase by meaning, not keywords
26
+ - **What it finds**: Functions, classes, methods, interfaces, and other code definitions
27
+ - **Unique feature**: Shows tracebacks (who imports/calls the code you find)
28
+ - **Best for**: Understanding code architecture, finding implementations, tracing dependencies
29
+
30
+ ### find_memory
31
+ - **Purpose**: Search stored memories (past conversations, decisions, context)
32
+ - **What it finds**: Episodic events, semantic facts, procedural knowledge, working memories
33
+ - **Unique feature**: Supports time queries like "yesterday", "last week", specific dates
34
+ - **Best for**: Recall past discussions, find decisions, locate context from previous sessions
35
+
36
+ ---
37
+
38
+ ## Query Formulation (CRITICAL)
39
+
40
+ The most important factor for getting good results is how you write your query. The two tools have different requirements:
41
+
42
+ ### find_code_pointers: Use CODE TERMS
43
+
44
+ **DO write queries using code-related terms:**
45
+ - `admin login auth`
46
+ - `database connection pool`
47
+ - `api handler middleware`
48
+ - `user authentication flow`
49
+ - `json response serializer`
50
+
51
+ **DO NOT write natural language questions:**
52
+ - `"how does admin login work"` - BAD
53
+ - `"where is the database connection defined"` - BAD
54
+ - `"what middleware handles authentication"` - BAD
55
+
56
+ **Why?** find_code_pointers searches for code definitions using embeddings trained on code. Natural language questions don't match the embedding space well.
57
+
58
+ **Query examples by use case:**
59
+
60
+ | Use Case | Good Query | Bad Query |
61
+ |----------|-----------|-----------|
62
+ | Find auth logic | `authentication token validation` | `how does token auth work` |
63
+ | Find DB code | `postgres connection pool` | `where do we connect to database` |
64
+ | Find API code | `rest endpoint handler` | `how are API routes defined` |
65
+ | Find utilities | `string formatting helper` | `what utility functions exist` |
66
+
67
+ ### find_memory: Natural Language Works
68
+
69
+ find_memory is more flexible - natural language queries work well:
70
+ - `"discussion about API design"`
71
+ - `"database migration decisions"`
72
+ - `"user feedback on login flow"`
73
+
74
+ Be specific about what you're looking for. Vague queries return vague results.
75
+
76
+ ---
77
+
78
+ ## find_code_pointers - Semantic Code Search
79
+
80
+ ### Basic Usage
81
+
82
+ ```javascript
83
+ find_code_pointers({ query: "admin login authentication" })
84
+ find_code_pointers({ query: "database connection pool" })
85
+ ```
86
+
87
+ ### Parameter Reference
88
+
89
+ | Parameter | Type | Default | Description |
90
+ |-----------|------|---------|-------------|
91
+ | `query` | string | required | What to search for - use CODE TERMS |
92
+ | `limit` | number | 10 | Maximum results to return |
93
+ | `threshold` | number | 0.25 | Minimum similarity score (0-1). Higher = more strict |
94
+ | `language` | string | - | Filter by language: typescript, javascript, python, go, rust, etc. |
95
+ | `filePattern` | string | - | Filter by file path pattern: `routes/*.ts`, `src/api/**` |
96
+ | `definitionTypes` | array | - | Filter by type: function, method, class, interface, type, enum, variable, constant, constructor |
97
+ | `includeTracebacks` | boolean | true | Show who imports/calls the found code |
98
+ | `galleryMode` | boolean | false | Enable Mini COT analysis for deeper understanding |
99
+ | `zoom` | number | 50 | Detail level: 0=signature only, 50=balanced, 100=full context |
100
+ | `cameraRollMode` | boolean | true | Returns drilldownIDs for drill_down exploration |
101
+ | `zoomLevel` | string | - | Preset zoom: ultra-wide, wide, normal, close, macro |
102
+ | `includeMemoryLinks` | boolean | true | Link code to related memories |
103
+ | `includeRecent` | number | 0 | Force-include N most recently modified files |
104
+ | `keywordFallback` | boolean | true | Fall back to keyword search if semantic returns nothing |
105
+ | `allProjects` | boolean | false | Search ALL projects instead of current |
106
+
107
+ ### Zoom Level Presets
108
+
109
+ | Preset | Results | Threshold | Best For |
110
+ |--------|---------|-----------|----------|
111
+ | `ultra-wide` | 50 | 15% | Exploration, unknown codebase |
112
+ | `wide` | 25 | 25% | Broad overview |
113
+ | `normal` | 15 | 40% | Balanced (default feel) |
114
+ | `close` | 10 | 60% | Specific known functionality |
115
+ | `macro` | 5 | 80% | Exact matches only |
116
+
117
+ ### Example Queries
118
+
119
+ ```javascript
120
+ // Find authentication-related code
121
+ find_code_pointers({ query: "jwt token validation", limit: 10 })
122
+
123
+ // Find database code, TypeScript only
124
+ find_code_pointers({ query: "postgres query builder", language: "typescript" })
125
+
126
+ // Find with tracebacks (who calls this)
127
+ find_code_pointers({ query: "api middleware handler", includeTracebacks: true })
128
+
129
+ // Gallery mode for deeper analysis
130
+ find_code_pointers({ query: "auth flow", galleryMode: true })
131
+
132
+ // Use zoom level preset
133
+ find_code_pointers({ query: "connection pool", zoomLevel: "close" })
134
+ ```
135
+
136
+ ---
137
+
138
+ ## find_memory - Semantic Memory Search
139
+
140
+ ### Basic Usage
141
+
142
+ ```javascript
143
+ find_memory({ query: "API design decisions" })
144
+ find_memory({ query: "database migration" })
145
+ ```
146
+
147
+ ### Parameter Reference
148
+
149
+ | Parameter | Type | Default | Description |
150
+ |-----------|------|---------|-------------|
151
+ | `query` | string | required | What to search for - natural language works |
152
+ | `limit` | number | 10 | Maximum results to return |
153
+ | `threshold` | number | 0.25 | Minimum similarity score (0-1). Higher = more strict |
154
+ | `memoryTypes` | array | - | Filter: episodic, semantic, procedural, working, consolidated |
155
+ | `tags` | array | - | Filter by tags (OR logic) |
156
+ | `importance` | array | - | Filter: critical, high, medium, low, trivial |
157
+ | `dateRange` | object | - | Filter by date: `{ start: "2024-01-01", end: "2024-12-31" }` |
158
+ | `includeRecent` | number | 0 | Force-include N most recent memories regardless of relevance |
159
+ | `recencyBoost` | boolean | true | Boost recent memories (last hour +20%, last day +10%) |
160
+ | `keywordFallback` | boolean | true | Fall back to keyword search if semantic returns nothing |
161
+ | `role` | string | - | Filter by message role: "user" or "assistant" |
162
+ | `summarize` | boolean | true | Return summarized content (first 500 chars) |
163
+ | `maxContentLength` | number | 500 | Truncate content to this many characters |
164
+ | `galleryMode` | boolean | false | Enable Mini COT analysis |
165
+ | `cameraRollMode` | boolean | true | Returns drilldownIDs for drill_down exploration |
166
+ | `zoomLevel` | string | - | Preset zoom: ultra-wide, wide, normal, close, macro |
167
+ | `projectPath` | string | - | Search specific project path |
168
+ | `allProjects` | boolean | false | Search ALL projects |
169
+
170
+ ### Time Queries
171
+
172
+ find_memory supports natural language time expressions:
173
+ - `"yesterday"`
174
+ - `"last week"`
175
+ - `"last month"`
176
+ - `"2024-01-15"`
177
+ - `"past hour"`
178
+
179
+ Use with `dateRange` parameter for precise filtering.
180
+
181
+ ### Memory Types
182
+
183
+ | Type | Description |
184
+ |------|-------------|
185
+ | `episodic` | Events, things that happened |
186
+ | `semantic` | Facts, knowledge, learned information |
187
+ | `procedural` | How-to, step-by-step processes |
188
+ | `working` | Temporary/active memory |
189
+ | `consolidated` | Merged/condensed memories |
190
+
191
+ ### Example Queries
192
+
193
+ ```javascript
194
+ // Basic search
195
+ find_memory({ query: "API design decisions" })
196
+
197
+ // Filter by memory type
198
+ find_memory({ query: "database", memoryTypes: ["episodic", "semantic"] })
199
+
200
+ // Time-based search
201
+ find_memory({ query: "auth", dateRange: { start: "2024-01-01", end: "2024-12-31" } })
202
+
203
+ // Get recent memories regardless of relevance
204
+ find_memory({ query: "anything", includeRecent: 5 })
205
+
206
+ // Full content, no summarization
207
+ find_memory({ query: "important decision", summarize: false })
208
+
209
+ // Cross-project search
210
+ find_memory({ query: "shared utility", allProjects: true })
211
+ ```
212
+
213
+ ---
214
+
215
+ ## Timeout Behavior
216
+
217
+ ### Understanding "processing" vs "working"
218
+
219
+ **IMPORTANT**: The embedding server may send `{"status":"processing"}` responses. This status indicates the server is **alive**, NOT that it is actively processing your query.
220
+
221
+ - **"processing" status**: Server is alive and idle - does NOT mean your query is being worked on
222
+ - **Actual working**: The server is generating embeddings or searching
223
+
224
+ ### Timeout Configuration
225
+
226
+ Timeouts are controlled by environment variable:
227
+ ```bash
228
+ export SPECMEM_EMBEDDING_TIMEOUT=60 # seconds, default
229
+ ```
230
+
231
+ For code search specifically:
232
+ ```bash
233
+ export SPECMEM_CODE_SEARCH_TIMEOUT=60 # seconds, default
234
+ ```
235
+
236
+ ### Timeout Values by Operation
237
+
238
+ | Operation | Default Timeout | Config Variable |
239
+ |-----------|-----------------|-----------------|
240
+ | Embedding generation | 60s | SPECMEM_EMBEDDING_TIMEOUT |
241
+ | DB search | 6x embedding timeout | SPECMEM_EMBEDDING_TIMEOUT |
242
+ | Keyword fallback | 10s | - |
243
+ | Recent files lookup | 5s | - |
244
+ | Tracebacks | 30s | - |
245
+ | Gallery mode | 2x normal | - |
246
+
247
+ ### Retry Logic
248
+
249
+ Both tools have built-in retry logic for transient failures:
250
+ - **find_memory**: 2 retries by default (configurable via SPECMEM_FIND_MEMORY_RETRIES)
251
+ - **find_code_pointers**: 2 retries by default
252
+
253
+ Retries handle:
254
+ - Connection timeouts
255
+ - Socket reset errors
256
+ - Resource busy errors
257
+ - Temporary service unavailability
258
+
259
+ ### Invalid Query Behavior
260
+
261
+ Queries with wrong input format should timeout quickly with a hint about correct format. If you see timeout errors:
262
+
263
+ 1. Check that all required parameters are provided
264
+ 2. Verify parameter types are correct
265
+ 3. Ensure query string is not empty
266
+
267
+ ---
268
+
269
+ ## Common Mistakes
270
+
271
+ ### Mistake 1: Writing Natural Language Questions for Code Search
272
+
273
+ ```javascript
274
+ // WRONG - natural language
275
+ find_code_pointers({ query: "how does the admin login work" })
276
+
277
+ // RIGHT - code terms
278
+ find_code_pointers({ query: "admin login authentication flow" })
279
+ ```
280
+
281
+ ### Mistake 2: Using Too High Threshold
282
+
283
+ ```javascript
284
+ // WRONG - too strict, returns nothing
285
+ find_code_pointers({ query: "auth", threshold: 0.8 })
286
+
287
+ // RIGHT - balanced threshold
288
+ find_code_pointers({ query: "auth", threshold: 0.25 })
289
+ ```
290
+
291
+ ### Mistake 3: Forgetting cameraRollMode Returns IDs
292
+
293
+ When `cameraRollMode: true` (default), results include `drilldownID` values. Use these with `drill_down()` to explore:
294
+ ```javascript
295
+ // First search
296
+ const results = find_code_pointers({ query: "auth", cameraRollMode: true })
297
+
298
+ // Then drill down into a specific result
299
+ drill_down({ drilldownID: results[0].drilldownID })
300
+ ```
301
+
302
+ ### Mistake 4: Not Using zoomLevel Presets
303
+
304
+ Instead of guessing zoom values, use presets:
305
+ ```javascript
306
+ // WRONG - guessing values
307
+ find_code_pointers({ query: "auth", zoom: 75 })
308
+
309
+ // RIGHT - use preset
310
+ find_code_pointers({ query: "auth", zoomLevel: "close" })
311
+ ```
312
+
313
+ ### Mistake 5: Not Checking includeRecent
314
+
315
+ When searching unfamiliar codebases, include recent files:
316
+ ```javascript
317
+ find_code_pointers({ query: "auth", includeRecent: 10 })
318
+ ```
319
+
320
+ ### Mistake 6: Not Using keywordFallback
321
+
322
+ Keyword fallback finds code that semantic search might miss:
323
+ ```javascript
324
+ // Should usually keep true (default)
325
+ find_code_pointers({ query: "auth", keywordFallback: true })
326
+ ```
327
+
328
+ ---
329
+
330
+ ## Best Practices
331
+
332
+ ### When to Use find_code_pointers
333
+
334
+ 1. **Understanding code architecture** - Find how components connect
335
+ 2. **Finding implementations** - Locate specific function/class definitions
336
+ 3. **Tracing dependencies** - See who imports/calls code (tracebacks)
337
+ 4. **Exploring unfamiliar code** - Use with `includeRecent`
338
+
339
+ ### When to Use find_memory
340
+
341
+ 1. **Recalling past discussions** - Find previous conversations
342
+ 2. **Locating decisions** - Search for decisions made earlier
343
+ 3. **Cross-session context** - Carry context across sessions
344
+ 4. **Time-based queries** - Use "yesterday", "last week"
345
+
346
+ ### Parameter Selection Guide
347
+
348
+ | Goal | Recommended Parameters |
349
+ |------|----------------------|
350
+ | Quick exploration | `zoomLevel: "ultra-wide"`, `limit: 50` |
351
+ | Normal search | defaults (threshold: 0.25, limit: 10) |
352
+ | Exact match | `zoomLevel: "macro"`, `threshold: 0.8` |
353
+ | Understand code | `includeTracebacks: true`, `galleryMode: true` |
354
+ | Cross-project | `allProjects: true` |
355
+ | Recent context | `includeRecent: 10`, `recencyBoost: true` |
356
+
357
+ ### Combining with Drill-Down
358
+
359
+ Always use `drill_down()` to explore results:
360
+ ```javascript
361
+ // 1. Search
362
+ const results = find_code_pointers({ query: "auth" })
363
+
364
+ // 2. Drill into best match
365
+ drill_down({ drilldownID: results[0].drilldownID })
366
+
367
+ // Or for memory
368
+ const memResults = find_memory({ query: "API decisions" })
369
+ drill_down({ drilldownID: memResults[0].drilldownID })
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Troubleshooting
375
+
376
+ ### No Results Returned
377
+
378
+ 1. **Lower the threshold**:
379
+ ```javascript
380
+ find_code_pointers({ query: "auth", threshold: 0.15 })
381
+ ```
382
+
383
+ 2. **Enable keyword fallback**:
384
+ ```javascript
385
+ find_code_pointers({ query: "auth", keywordFallback: true })
386
+ ```
387
+
388
+ 3. **Check query formulation** - use code terms, not questions
389
+
390
+ ### Timeout Errors
391
+
392
+ 1. **Increase timeout**:
393
+ ```bash
394
+ export SPECMEM_EMBEDDING_TIMEOUT=120
395
+ ```
396
+
397
+ 2. **Check embedding server status**:
398
+ ```javascript
399
+ embedding_status({})
400
+ ```
401
+
402
+ 3. **Restart embedding server if needed**:
403
+ ```javascript
404
+ embedding_stop({})
405
+ embedding_start({})
406
+ ```
407
+
408
+ ### Low-Quality Results
409
+
410
+ 1. **Use gallery mode for analysis**:
411
+ ```javascript
412
+ find_code_pointers({ query: "auth", galleryMode: true })
413
+ ```
414
+
415
+ 2. **Add tracebacks to understand context**:
416
+ ```javascript
417
+ find_code_pointers({ query: "auth", includeTracebacks: true })
418
+ ```
419
+
420
+ 3. **Include recent files for fresh context**:
421
+ ```javascript
422
+ find_code_pointers({ query: "auth", includeRecent: 10 })
423
+ ```
424
+
425
+ ### Memory Search Tips
426
+
427
+ 1. **Use specific queries** - more context = better results
428
+ 2. **Filter by memory type** - narrow down what you're looking for
429
+ 3. **Use importance filter** for critical information
430
+ 4. **Combine with dateRange** for historical context
431
+
432
+ ---
433
+
434
+ ## Summary
435
+
436
+ | Tool | Query Style | Best For |
437
+ |------|-------------|----------|
438
+ | find_code_pointers | CODE TERMS | Code search, architecture understanding |
439
+ | find_memory | Natural language | Past discussions, decisions, context |
440
+
441
+ **Key Takeaways**:
442
+ 1. Use CODE TERMS for code search, natural language for memory search
443
+ 2. Keep threshold at 0.25 unless you need exact matches
444
+ 3. Use zoomLevel presets instead of guessing values
445
+ 4. Always use drill_down() to explore results
446
+ 5. Enable galleryMode for deeper analysis
447
+ 6. Understand that "processing" status doesn't mean your query is being worked on
448
+ 7. Use includeRecent when exploring unfamiliar codebases
@@ -6,6 +6,9 @@
6
6
  *
7
7
  * Now integrated with LWJEB event bus for tool:execution events
8
8
  */
9
+ import { readFileSync, existsSync } from 'fs';
10
+ import { join, dirname } from 'path';
11
+ import { fileURLToPath } from 'url';
9
12
  import { logger } from '../utils/logger.js';
10
13
  import { getCoordinator } from '../coordination/integration.js';
11
14
  // import zod schemas for validation
@@ -411,8 +414,33 @@ export class MCPProtocolHandler {
411
414
  };
412
415
  }
413
416
  }
414
- // execute the tool
415
- const result = await this.toolRegistry.executeTool(toolName, validatedArgs);
417
+ // execute the tool with timeout - return helpful message instead of hanging
418
+ const TOOL_TIMEOUT_MS = 30000; // 30 second timeout
419
+
420
+ // Load HOW_TO_USE file for timeout responses
421
+ let howToUseContent = null;
422
+ try {
423
+ const __dirname = dirname(fileURLToPath(import.meta.url));
424
+ const helpPath = join(__dirname, '..', '..', 'HOW_TO_USE_SPECMEM_MCP.md');
425
+ if (existsSync(helpPath)) {
426
+ howToUseContent = readFileSync(helpPath, 'utf-8');
427
+ }
428
+ } catch (e) {
429
+ logger.warn({ error: e.message }, 'Could not load HOW_TO_USE file');
430
+ }
431
+
432
+ const result = await Promise.race([
433
+ this.toolRegistry.executeTool(toolName, validatedArgs),
434
+ new Promise((resolve) =>
435
+ setTimeout(() => {
436
+ if (howToUseContent) {
437
+ logger.warn({ toolName }, 'Tool timed out, returning HOW_TO_USE guide');
438
+ resolve(`[TIMEOUT] ${toolName} timed out after ${TOOL_TIMEOUT_MS}ms.\n\nThe embedding service may be slow or your query may need refinement.\n\n---\n\n## SpecMem Search Guide\n\n${howToUseContent}`);
439
+ } else {
440
+ resolve(`[TIMEOUT] ${toolName} timed out after ${TOOL_TIMEOUT_MS}ms. The embedding service may be slow or unavailable. Try: 1) Check if embedding server is running 2) Use simpler search terms 3) Try find_memory or find_code_pointers with a more specific query`);
441
+ }
442
+ }, TOOL_TIMEOUT_MS))
443
+ ]);
416
444
  const duration = Date.now() - startTime;
417
445
  logger.debug({ toolName, duration, callCount: this.callCount }, 'tool call handled');
418
446
  // Emit tool execution complete event via LWJEB
@@ -148,6 +148,10 @@ export class ExtractSessions {
148
148
  logger.warn({ error: serializeError(batchError) }, 'batch embedding failed, falling back to individual');
149
149
  embeddings = await Promise.all(texts.map(t => this.embeddingProvider.generateEmbedding(t)));
150
150
  }
151
+
152
+ // Yield to event loop between batches to prevent UI freeze
153
+ await new Promise(resolve => setTimeout(resolve, 10));
154
+ }
151
155
  try {
152
156
  // PROJECT ISOLATION: Get fresh project path at call time
153
157
  const projectPath = getProjectPathForInsert();
package/mcp-proxy.cjs CHANGED
@@ -20,6 +20,19 @@ const MAX_RESTART_DELAY = 10000; // 10s max backoff
20
20
  const INITIAL_RESTART_DELAY = 500; // 500ms first retry
21
21
  const MAX_QUEUE_SIZE = 200;
22
22
  const HEARTBEAT_INTERVAL = 30000; // 30s keepalive pings
23
+ const TOOL_CALL_TIMEOUT = 25000; // 25s timeout for tool calls
24
+
25
+ // Load HOW_TO_USE guide for timeout responses
26
+ let HOW_TO_USE_CONTENT = null;
27
+ try {
28
+ const helpPath = path.join(__dirname, 'HOW_TO_USE_SPECMEM_MCP.md');
29
+ if (fs.existsSync(helpPath)) {
30
+ HOW_TO_USE_CONTENT = fs.readFileSync(helpPath, 'utf-8');
31
+ log(`Loaded HOW_TO_USE guide (${HOW_TO_USE_CONTENT.length} chars)`);
32
+ }
33
+ } catch (e) {
34
+ log(`Could not load HOW_TO_USE guide: ${e.message}`);
35
+ }
23
36
 
24
37
  // State
25
38
  let child = null;
@@ -34,6 +47,7 @@ let shuttingDown = false;
34
47
  let heartbeatTimer = null;
35
48
  let childStdoutBuffer = '';
36
49
  let stdinBuffer = '';
50
+ let pendingToolCalls = new Map(); // Track tool calls with timeouts
37
51
 
38
52
  function log(msg) {
39
53
  try {
@@ -165,6 +179,46 @@ function sendToServer(msg) {
165
179
 
166
180
  try {
167
181
  child.stdin.write(serializeMessage(msg));
182
+
183
+ // Track tool calls for timeout
184
+ if (msg.method === 'tools/call' && msg.id) {
185
+ const toolName = msg.params?.name || 'unknown';
186
+ log(`Tool call ${msg.id}: ${toolName} - setting ${TOOL_CALL_TIMEOUT}ms timeout`);
187
+
188
+ const timeout = setTimeout(() => {
189
+ if (pendingToolCalls.has(msg.id)) {
190
+ log(`Tool call ${msg.id} (${toolName}) timed out after ${TOOL_CALL_TIMEOUT}ms`);
191
+
192
+ // Return HOW_TO_USE guide instead of error
193
+ let helpText = `Tool '${toolName}' timed out after ${TOOL_CALL_TIMEOUT}ms. The embedding service may be slow or your query may need refinement.`;
194
+ if (HOW_TO_USE_CONTENT) {
195
+ helpText = `[TIMEOUT] ${toolName} timed out.\n\nThe embedding service may be slow or your query may need refinement.\n\n---\n\n## SpecMem Search Guide\n\n${HOW_TO_USE_CONTENT}`;
196
+ }
197
+
198
+ // Send response with help text (as result, not error, so Claude can read it)
199
+ const response = {
200
+ jsonrpc: '2.0',
201
+ id: msg.id,
202
+ result: {
203
+ content: [
204
+ {
205
+ type: 'text',
206
+ text: helpText
207
+ }
208
+ ]
209
+ }
210
+ };
211
+ sendToClient(response);
212
+ pendingToolCalls.delete(msg.id);
213
+
214
+ // Restart the server to clear any stuck state
215
+ log(`Restarting server after tool timeout`);
216
+ scheduleRestart();
217
+ }
218
+ }, TOOL_CALL_TIMEOUT);
219
+
220
+ pendingToolCalls.set(msg.id, { toolName, timeout });
221
+ }
168
222
  } catch (e) {
169
223
  log(`child stdin write error: ${e.message}`);
170
224
  pendingQueue.push(msg);
@@ -247,6 +301,14 @@ function spawnServer() {
247
301
 
248
302
  // Forward everything else to Claude
249
303
  sendToClient(msg);
304
+
305
+ // Check if this is a tool response - clear the timeout
306
+ if (msg.id && pendingToolCalls.has(msg.id)) {
307
+ const callInfo = pendingToolCalls.get(msg.id);
308
+ if (callInfo.timeout) clearTimeout(callInfo.timeout);
309
+ pendingToolCalls.delete(msg.id);
310
+ log(`Tool call ${msg.id} completed, cleared timeout`);
311
+ }
250
312
  }
251
313
  });
252
314
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specmem-hardwicksoftware",
3
- "version": "3.7.46",
3
+ "version": "3.7.48",
4
4
  "type": "module",
5
5
  "description": "Your Claude Code sessions don't have to start from scratch anymore — SpecMem gives your AI real memory. It won't forget your conversations, your code, or your architecture decisions between sessions. That's the whole point. Semantic code indexing that actually works: TypeScript, JavaScript, Python, Go, Rust, Java, Kotlin, C, C++, HTML and more. It doesn't just track functions — it gets classes, methods, fields, constants, enums, macros, imports, structs, the whole codebase graph. There's chat memory too, powered by pgvector embeddings. You've also got token compression, team coordination, multi-agent comms, and file watching built in. 74+ MCP tools. Runs on PostgreSQL + Docker. It's kind of a big deal. justcalljon.pro",
6
6
  "main": "dist/index.js",
@@ -171,6 +171,7 @@
171
171
  "embedding-sandbox/models/minisbd/",
172
172
  "embedding-sandbox/*.txt",
173
173
  "legal/",
174
+ "HOW_TO_USE_SPECMEM_MCP.md",
174
175
  "svg-sections/",
175
176
  "specmem/config.json",
176
177
  "specmem/model-config.json",
@@ -36,11 +36,11 @@
36
36
  "resources": {
37
37
  "cpuMin": 10,
38
38
  "cpuMax": 50,
39
- "cpuCoreMin": 1,
39
+ "cpuCoreMin": 3,
40
40
  "cpuCoreMax": 5,
41
41
  "ramMinMb": 6000,
42
42
  "ramMaxMb": 19500,
43
- "updatedAt": "2026-03-01T19:38:15.430Z"
43
+ "updatedAt": "2026-03-10T03:31:53.267Z"
44
44
  },
45
45
  "resourcePool": {
46
46
  "embedding": {
@@ -1,6 +1,6 @@
1
1
  ; ============================================
2
2
  ; SPECMEM BRAIN CONTAINER - DYNAMIC SUPERVISORD CONFIG
3
- ; Generated by specmem-init at 2026-03-10T03:09:08.421Z
3
+ ; Generated by specmem-init at 2026-03-10T03:30:28.641Z
4
4
  ; Thread counts from model-config.json resourcePool
5
5
  ; ============================================
6
6