specmem-hardwicksoftware 3.7.41 → 3.7.42

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specmem-hardwicksoftware",
3
- "version": "3.7.41",
3
+ "version": "3.7.42",
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",
@@ -10157,6 +10157,42 @@ ${lastOutput}
10157
10157
  try { execSync('which podman 2>/dev/null', { stdio: 'pipe' }); return 'podman'; } catch { return 'docker'; }
10158
10158
  })();
10159
10159
 
10160
+ // Helper: run a long command async so blessed TUI stays responsive
10161
+ const spawnAsync = (cmd, args, label, timeoutMs = 600000) => {
10162
+ return new Promise((resolve, reject) => {
10163
+ const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'] });
10164
+ let lastLine = '';
10165
+ const onData = (chunk) => {
10166
+ const lines = chunk.toString().split('\n').filter(Boolean);
10167
+ if (lines.length) lastLine = lines[lines.length - 1].slice(0, 80);
10168
+ };
10169
+ if (child.stdout) child.stdout.on('data', onData);
10170
+ if (child.stderr) child.stderr.on('data', onData);
10171
+
10172
+ const statusInterval = setInterval(() => {
10173
+ if (ui && lastLine) ui.setSubStatus(lastLine);
10174
+ }, 2000);
10175
+
10176
+ const timer = setTimeout(() => {
10177
+ clearInterval(statusInterval);
10178
+ child.kill('SIGTERM');
10179
+ reject(new Error(`${label} timed out`));
10180
+ }, timeoutMs);
10181
+
10182
+ child.on('close', (code) => {
10183
+ clearInterval(statusInterval);
10184
+ clearTimeout(timer);
10185
+ if (code === 0) resolve();
10186
+ else reject(new Error(`${label} exited with code ${code}`));
10187
+ });
10188
+ child.on('error', (err) => {
10189
+ clearInterval(statusInterval);
10190
+ clearTimeout(timer);
10191
+ reject(err);
10192
+ });
10193
+ });
10194
+ };
10195
+
10160
10196
  let imageExists = false;
10161
10197
  try {
10162
10198
  execSync(`${rtCmd} image inspect ${containerImage} 2>/dev/null`, { stdio: 'pipe' });
@@ -10165,7 +10201,7 @@ ${lastOutput}
10165
10201
  } catch {
10166
10202
  ui.setStatus(`Pulling ${containerImage}...`);
10167
10203
  try {
10168
- execSync(`${rtCmd} pull ${containerImage}`, { stdio: 'ignore', timeout: 600000 });
10204
+ await spawnAsync(rtCmd, ['pull', containerImage], 'Image pull', 600000);
10169
10205
  imageExists = true;
10170
10206
  ui.setStatus('Image pulled');
10171
10207
  } catch (pullErr) {
@@ -10174,13 +10210,9 @@ ${lastOutput}
10174
10210
  ui.setStatus('Pull failed, building locally...');
10175
10211
  const dockerfilePath = path.join(path.dirname(__dirname), 'container', 'Dockerfile');
10176
10212
  if (fs.existsSync(dockerfilePath)) {
10177
- // stdio:'ignore' build output can be gigabytes (no .dockerignore at context root)
10178
- // Without this, Node's default 1MB maxBuffer causes ERR_CHILD_PROCESS_STDIO_MAXBUFFER
10179
- // which crashes init before the catch can fire cleanly
10213
+ ui.setStatus('Building container image locally (this may take 10-20 min)...');
10180
10214
  try {
10181
- execSync(`${rtCmd} build -t ${containerImage} -f ${dockerfilePath} ${path.dirname(__dirname)}`, {
10182
- stdio: 'ignore', timeout: 1200000 // 20 min for local build
10183
- });
10215
+ await spawnAsync(rtCmd, ['build', '-t', containerImage, '-f', dockerfilePath, path.dirname(__dirname)], 'Image build', 1200000);
10184
10216
  imageExists = true;
10185
10217
  ui.setStatus('Image built locally');
10186
10218
  } catch (buildErr) {
@@ -10189,7 +10221,6 @@ ${lastOutput}
10189
10221
  }
10190
10222
  }
10191
10223
  } catch (fallbackErr) {
10192
- // Catch-all: even if ui.setStatus or fs.existsSync throws, don't crash init
10193
10224
  initLog(`[CONTAINER] Pull fallback error: ${fallbackErr.message}`);
10194
10225
  ui.setStatus('Image unavailable');
10195
10226
  }