specmem-hardwicksoftware 3.7.39 → 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.39",
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",
@@ -9140,15 +9140,15 @@ function registerProjectInRegistry(projectPath, globalDir) {
9140
9140
  /**
9141
9141
  * Stage 1: MODEL DOWNLOAD
9142
9142
  * Checks for all required ML models. If any are missing, auto-downloads
9143
- * the combined models tarball from GitHub release no prompting.
9143
+ * the combined models tarball from a permanent GitHub release (tag: "models").
9144
+ * Version-independent — all npm versions pull from the same release.
9144
9145
  *
9145
- * Models bundled in npm (always present after install):
9146
- * - all-MiniLM-L6-v2 (embedding)
9147
- * - minisbd (sentence boundary)
9148
- *
9149
- * Models NOT in npm (LFS-only, downloaded via release tarball):
9150
- * - pythia-410m-onnx-quant (mini-COT)
9151
- * - argos-translate (translation en↔zh/zt)
9146
+ * All models (~662MB uncompressed):
9147
+ * - all-MiniLM-L6-v2 (23MB) — embedding model (ONNX)
9148
+ * - pythia-410m-onnx-quant (394MB) — mini-COT (ONNX int8)
9149
+ * - argos-translate (246MB) — translation (en↔zh/zt)
9150
+ * - minisbd (192KB) sentence boundary detection
9151
+ * - argos-translate-packages (4KB) — package registry
9152
9152
  */
9153
9153
  async function ensureModels(ui) {
9154
9154
  const specmemRoot = path.resolve(__dirname, '..');
@@ -9156,8 +9156,10 @@ async function ensureModels(ui) {
9156
9156
  const version = SPECMEM_VERSION;
9157
9157
 
9158
9158
  const sentinels = [
9159
+ { name: 'Embedding (MiniLM)', path: path.join(modelsDir, 'all-MiniLM-L6-v2', 'onnx', 'model_quint8_avx2.onnx') },
9159
9160
  { name: 'Mini-COT (Pythia)', path: path.join(modelsDir, 'pythia-410m-onnx-quant', 'model_quantized.onnx') },
9160
9161
  { name: 'Translation (Argos)', path: path.join(modelsDir, 'argos-translate', 'translate-en_zh-1_9', 'model', 'model.bin') },
9162
+ { name: 'SBD (minisbd)', path: path.join(modelsDir, 'minisbd', 'en.onnx') },
9161
9163
  ];
9162
9164
 
9163
9165
  const missing = sentinels.filter(s => !fs.existsSync(s.path));
@@ -9188,16 +9190,49 @@ async function ensureModels(ui) {
9188
9190
  return;
9189
9191
  }
9190
9192
 
9191
- const releaseUrl = `https://github.com/jonhardwick-spec/specmem/releases/download/v${version}/specmem-models-${version}.tar.gz`;
9192
- const tmpTarball = path.join(os.tmpdir(), `specmem-models-${version}.tar.gz`);
9193
+ // Permanent models release — version-independent, all npm versions pull from here
9194
+ const releaseUrl = 'https://github.com/jonhardwick-spec/specmem/releases/download/models/specmem-models.tar.gz';
9195
+ const tmpTarball = path.join(os.tmpdir(), 'specmem-models.tar.gz');
9196
+ const expectedSizeMB = 562; // approximate tarball size
9193
9197
 
9194
9198
  initLog(`[MODELS] Downloading: ${releaseUrl}`);
9195
9199
 
9200
+ // Use spawn (async) instead of execSync so blessed TUI can render during download
9196
9201
  try {
9197
- const dlCmd = hasCurl
9198
- ? `curl -fSL --progress-bar -o "${tmpTarball}" "${releaseUrl}"`
9199
- : `wget --progress=bar:force -O "${tmpTarball}" "${releaseUrl}"`;
9200
- 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
+ });
9201
9236
  } catch (e) {
9202
9237
  initLog(`[MODELS] Download failed: ${e.message}`);
9203
9238
  if (ui) ui.setSubStatus(`⚠ Model download failed — mini-COT/translation disabled`);
@@ -9210,14 +9245,15 @@ async function ensureModels(ui) {
9210
9245
 
9211
9246
  try {
9212
9247
  const mkdirCmd = `mkdir -p "${modelsDir}"`;
9213
- const extractCmd = `tar xzf "${tmpTarball}" -C "${modelsDir}"`;
9248
+ // Tarball has models/ prefix strip it so contents land directly in modelsDir
9249
+ const extractCmd = `tar xzf "${tmpTarball}" -C "${modelsDir}" --strip-components=1`;
9214
9250
  if (needsSudo) {
9215
9251
  execSync(`sudo ${mkdirCmd}`, { stdio: 'pipe' });
9216
- execSync(`sudo ${extractCmd}`, { stdio: 'pipe', timeout: 180000 });
9252
+ execSync(`sudo ${extractCmd}`, { stdio: 'pipe', timeout: 300000 });
9217
9253
  execSync(`sudo chmod -R a+rX "${modelsDir}"`, { stdio: 'pipe' });
9218
9254
  } else {
9219
9255
  execSync(mkdirCmd, { stdio: 'pipe' });
9220
- execSync(extractCmd, { stdio: 'pipe', timeout: 180000 });
9256
+ execSync(extractCmd, { stdio: 'pipe', timeout: 300000 });
9221
9257
  }
9222
9258
  } catch (e) {
9223
9259
  initLog(`[MODELS] Extraction failed: ${e.message}`);