specmem-hardwicksoftware 3.7.38 → 3.7.40
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 +1 -1
- package/scripts/specmem-init.cjs +43 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "specmem-hardwicksoftware",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.40",
|
|
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",
|
package/scripts/specmem-init.cjs
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
9146
|
-
* - all-MiniLM-L6-v2 (embedding)
|
|
9147
|
-
* -
|
|
9148
|
-
*
|
|
9149
|
-
*
|
|
9150
|
-
* -
|
|
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,8 +9190,9 @@ async function ensureModels(ui) {
|
|
|
9188
9190
|
return;
|
|
9189
9191
|
}
|
|
9190
9192
|
|
|
9191
|
-
|
|
9192
|
-
const
|
|
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');
|
|
9193
9196
|
|
|
9194
9197
|
initLog(`[MODELS] Downloading: ${releaseUrl}`);
|
|
9195
9198
|
|
|
@@ -9210,14 +9213,15 @@ async function ensureModels(ui) {
|
|
|
9210
9213
|
|
|
9211
9214
|
try {
|
|
9212
9215
|
const mkdirCmd = `mkdir -p "${modelsDir}"`;
|
|
9213
|
-
|
|
9216
|
+
// Tarball has models/ prefix — strip it so contents land directly in modelsDir
|
|
9217
|
+
const extractCmd = `tar xzf "${tmpTarball}" -C "${modelsDir}" --strip-components=1`;
|
|
9214
9218
|
if (needsSudo) {
|
|
9215
9219
|
execSync(`sudo ${mkdirCmd}`, { stdio: 'pipe' });
|
|
9216
|
-
execSync(`sudo ${extractCmd}`, { stdio: 'pipe', timeout:
|
|
9220
|
+
execSync(`sudo ${extractCmd}`, { stdio: 'pipe', timeout: 300000 });
|
|
9217
9221
|
execSync(`sudo chmod -R a+rX "${modelsDir}"`, { stdio: 'pipe' });
|
|
9218
9222
|
} else {
|
|
9219
9223
|
execSync(mkdirCmd, { stdio: 'pipe' });
|
|
9220
|
-
execSync(extractCmd, { stdio: 'pipe', timeout:
|
|
9224
|
+
execSync(extractCmd, { stdio: 'pipe', timeout: 300000 });
|
|
9221
9225
|
}
|
|
9222
9226
|
} catch (e) {
|
|
9223
9227
|
initLog(`[MODELS] Extraction failed: ${e.message}`);
|
|
@@ -10129,23 +10133,33 @@ ${lastOutput}
|
|
|
10129
10133
|
} catch {
|
|
10130
10134
|
ui.setStatus(`Pulling ${containerImage}...`);
|
|
10131
10135
|
try {
|
|
10132
|
-
execSync(`${rtCmd} pull ${containerImage}`, { stdio: '
|
|
10136
|
+
execSync(`${rtCmd} pull ${containerImage}`, { stdio: 'ignore', timeout: 600000 });
|
|
10133
10137
|
imageExists = true;
|
|
10134
10138
|
ui.setStatus('Image pulled');
|
|
10135
10139
|
} catch (pullErr) {
|
|
10136
10140
|
// Try building locally if pull fails
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10141
|
+
try {
|
|
10142
|
+
ui.setStatus('Pull failed, building locally...');
|
|
10143
|
+
const dockerfilePath = path.join(path.dirname(__dirname), 'container', 'Dockerfile');
|
|
10144
|
+
if (fs.existsSync(dockerfilePath)) {
|
|
10145
|
+
// stdio:'ignore' — build output can be gigabytes (no .dockerignore at context root)
|
|
10146
|
+
// Without this, Node's default 1MB maxBuffer causes ERR_CHILD_PROCESS_STDIO_MAXBUFFER
|
|
10147
|
+
// which crashes init before the catch can fire cleanly
|
|
10148
|
+
try {
|
|
10149
|
+
execSync(`${rtCmd} build -t ${containerImage} -f ${dockerfilePath} ${path.dirname(__dirname)}`, {
|
|
10150
|
+
stdio: 'ignore', timeout: 1200000 // 20 min for local build
|
|
10151
|
+
});
|
|
10152
|
+
imageExists = true;
|
|
10153
|
+
ui.setStatus('Image built locally');
|
|
10154
|
+
} catch (buildErr) {
|
|
10155
|
+
initLog(`[CONTAINER] Local build failed: ${buildErr.message}`);
|
|
10156
|
+
ui.setStatus('Image unavailable — will use legacy mode');
|
|
10157
|
+
}
|
|
10148
10158
|
}
|
|
10159
|
+
} catch (fallbackErr) {
|
|
10160
|
+
// Catch-all: even if ui.setStatus or fs.existsSync throws, don't crash init
|
|
10161
|
+
initLog(`[CONTAINER] Pull fallback error: ${fallbackErr.message}`);
|
|
10162
|
+
ui.setStatus('Image unavailable');
|
|
10149
10163
|
}
|
|
10150
10164
|
}
|
|
10151
10165
|
}
|
|
@@ -11698,5 +11712,9 @@ priority=999
|
|
|
11698
11712
|
|
|
11699
11713
|
main().catch((err) => {
|
|
11700
11714
|
cleanupSpeedMode();
|
|
11715
|
+
// Stop ProgressUI if active — otherwise error prints to alternate screen buffer and is invisible
|
|
11716
|
+
if (_currentUI && typeof _currentUI.stop === 'function') {
|
|
11717
|
+
try { _currentUI.stop(); } catch {}
|
|
11718
|
+
}
|
|
11701
11719
|
console.error(err);
|
|
11702
11720
|
});
|