specmem-hardwicksoftware 3.7.40 → 3.7.41

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.40",
3
+ "version": "3.7.41",
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",
@@ -9193,14 +9193,46 @@ async function ensureModels(ui) {
9193
9193
  // Permanent models release — version-independent, all npm versions pull from here
9194
9194
  const releaseUrl = 'https://github.com/jonhardwick-spec/specmem/releases/download/models/specmem-models.tar.gz';
9195
9195
  const tmpTarball = path.join(os.tmpdir(), 'specmem-models.tar.gz');
9196
+ const expectedSizeMB = 562; // approximate tarball size
9196
9197
 
9197
9198
  initLog(`[MODELS] Downloading: ${releaseUrl}`);
9198
9199
 
9200
+ // Use spawn (async) instead of execSync so blessed TUI can render during download
9199
9201
  try {
9200
- const dlCmd = hasCurl
9201
- ? `curl -fSL --progress-bar -o "${tmpTarball}" "${releaseUrl}"`
9202
- : `wget --progress=bar:force -O "${tmpTarball}" "${releaseUrl}"`;
9203
- execSync(dlCmd, { stdio: 'pipe', timeout: 900000 }); // 15 min timeout for ~570MB
9202
+ await new Promise((resolve, reject) => {
9203
+ const args = hasCurl
9204
+ ? ['curl', ['-fSL', '-o', tmpTarball, releaseUrl]]
9205
+ : ['wget', ['-O', tmpTarball, releaseUrl]];
9206
+ const dl = spawn(args[0], args[1], { stdio: 'ignore' });
9207
+
9208
+ // Poll file size for progress updates
9209
+ const progressInterval = setInterval(() => {
9210
+ try {
9211
+ const stat = fs.statSync(tmpTarball);
9212
+ const mb = (stat.size / (1024 * 1024)).toFixed(0);
9213
+ const pct = Math.min(99, Math.round((stat.size / (expectedSizeMB * 1024 * 1024)) * 100));
9214
+ if (ui) ui.setSubStatus(`↓ Downloading ML models... ${mb}MB / ~${expectedSizeMB}MB (${pct}%)`);
9215
+ } catch {}
9216
+ }, 2000);
9217
+
9218
+ const timeout = setTimeout(() => {
9219
+ clearInterval(progressInterval);
9220
+ dl.kill('SIGTERM');
9221
+ reject(new Error('Download timed out after 15 minutes'));
9222
+ }, 900000);
9223
+
9224
+ dl.on('close', (code) => {
9225
+ clearInterval(progressInterval);
9226
+ clearTimeout(timeout);
9227
+ if (code === 0) resolve();
9228
+ else reject(new Error(`Download exited with code ${code}`));
9229
+ });
9230
+ dl.on('error', (err) => {
9231
+ clearInterval(progressInterval);
9232
+ clearTimeout(timeout);
9233
+ reject(err);
9234
+ });
9235
+ });
9204
9236
  } catch (e) {
9205
9237
  initLog(`[MODELS] Download failed: ${e.message}`);
9206
9238
  if (ui) ui.setSubStatus(`⚠ Model download failed — mini-COT/translation disabled`);