mneme-ai 2.19.64 → 2.19.66
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/bin/mneme.js +59 -0
- package/package.json +5 -5
package/bin/mneme.js
CHANGED
|
@@ -19,6 +19,65 @@ process.emit = function (name, data, ...rest) {
|
|
|
19
19
|
return originalEmit.call(this, name, data, ...rest);
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
+
// ── PHOENIX P3 — CLI BOOT DLL EXTRACTION (v2.19.65 patch) ──────────────
|
|
23
|
+
// Why it exists: nucleus_daemon.ts calls extractAndRedirect() at line 145 to
|
|
24
|
+
// move libvips DLLs to a per-PID tmpdir BEFORE sharp loads, so the daemon
|
|
25
|
+
// does not hold the canonical node_modules DLL handle and `npm install -g`
|
|
26
|
+
// can overwrite freely. But every `mneme <cmd>` CLI invocation went the
|
|
27
|
+
// other way: it static-imported `dist/index.js` which transitively pulls
|
|
28
|
+
// sharp from node_modules — locking the DLL on every CLI run, including
|
|
29
|
+
// the ones the user types repeatedly between upgrades. Empirically
|
|
30
|
+
// observed: phoenix.extract_status reports `dllExtracted: false` on any
|
|
31
|
+
// CLI process in v2.19.64; the install-trail ledger is empty; EBUSY
|
|
32
|
+
// reproduces on `npm install -g mneme-ai@latest` 100% of the time.
|
|
33
|
+
// This block closes that gap: every bin shim run extracts and redirects
|
|
34
|
+
// BEFORE the dist module load that ultimately requires sharp. Idempotent
|
|
35
|
+
// (env-var sentinel) and silent on failure (Phoenix is non-fatal at boot).
|
|
36
|
+
const __mnemePhoenixBootstrap = async () => {
|
|
37
|
+
if (process.env.MNEME_PHOENIX_CLI_EXTRACTED === "1") return;
|
|
38
|
+
process.env.MNEME_PHOENIX_CLI_EXTRACTED = "1";
|
|
39
|
+
try {
|
|
40
|
+
const fastArg = process.argv[2];
|
|
41
|
+
if (process.argv.length === 3 && (fastArg === "--version" || fastArg === "-V")) return;
|
|
42
|
+
const fs = await import("node:fs");
|
|
43
|
+
const path = await import("node:path");
|
|
44
|
+
const os = await import("node:os");
|
|
45
|
+
const url = await import("node:url");
|
|
46
|
+
const platform = process.platform;
|
|
47
|
+
const arch = process.arch;
|
|
48
|
+
const archKey = platform + "-" + arch;
|
|
49
|
+
let dir = path.dirname(url.fileURLToPath(import.meta.url));
|
|
50
|
+
let libDir = null;
|
|
51
|
+
// Empirical: on Windows the libvips DLLs live in @img/sharp-{archKey}/lib (no
|
|
52
|
+
// "libvips-" prefix). Some sharp releases also publish @img/sharp-libvips-{archKey},
|
|
53
|
+
// so probe both layouts at every walk-up step so the patch works across versions.
|
|
54
|
+
const libDirNames = ["sharp-" + archKey, "sharp-libvips-" + archKey];
|
|
55
|
+
outer: for (let i = 0; i < 12 && dir !== path.dirname(dir); i++) {
|
|
56
|
+
for (const name of libDirNames) {
|
|
57
|
+
const candidate = path.join(dir, "node_modules", "@img", name, "lib");
|
|
58
|
+
if (fs.existsSync(candidate)) { libDir = candidate; break outer; }
|
|
59
|
+
}
|
|
60
|
+
dir = path.dirname(dir);
|
|
61
|
+
}
|
|
62
|
+
if (!libDir) return;
|
|
63
|
+
const tmpDir = path.join(os.tmpdir(), "mneme-vips-" + process.pid);
|
|
64
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
65
|
+
for (const f of fs.readdirSync(libDir)) {
|
|
66
|
+
if (f.endsWith(".dll") || f.endsWith(".dylib") || f.endsWith(".so")) {
|
|
67
|
+
try { fs.copyFileSync(path.join(libDir, f), path.join(tmpDir, f)); } catch { /* per-file non-fatal */ }
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const envVar = platform === "win32" ? "PATH" : platform === "darwin" ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH";
|
|
71
|
+
const sep = platform === "win32" ? ";" : ":";
|
|
72
|
+
process.env[envVar] = tmpDir + sep + (process.env[envVar] || "");
|
|
73
|
+
process.on("exit", () => { try { fs.rmSync(tmpDir, { recursive: true, force: true }); } catch { /* non-fatal */ } });
|
|
74
|
+
} catch { /* phoenix non-fatal */ }
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Fire it synchronously via top-level await so subsequent dist/index.js
|
|
78
|
+
// load already sees the redirected env var.
|
|
79
|
+
await __mnemePhoenixBootstrap();
|
|
80
|
+
|
|
22
81
|
// ── v0.39 HPC fast path ────────────────────────────────────────────────
|
|
23
82
|
// Several common invocations don't need the 50+ command modules to load.
|
|
24
83
|
// Short-circuiting them here drops cold-start from ~8-13 s on Windows
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mneme-ai",
|
|
3
|
-
"version": "2.19.
|
|
3
|
+
"version": "2.19.66",
|
|
4
4
|
"mcpName": "io.github.patsa2561-art/mneme-ai",
|
|
5
5
|
"description": "Mneme เนโฌโ€ the memory layer for your codebase. Knows the WHY, the WHAT, the WHERE-IT-BREAKS.",
|
|
6
6
|
"type": "module",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"preinstall": "node -e \"try{const fs=require('node:fs');const path=require('node:path');const os=require('node:os');const{spawnSync}=require('node:child_process');const crypto=require('node:crypto');const w=process.platform==='win32';const home=os.homedir();const organ=path.join(home,'.mneme-global');const trailPath=path.join(organ,'preinstall-trail.jsonl');const trailSecret=process.env['MNEME_PREINSTALL_TRAIL_SECRET']||'mneme-preinstall-trail-v1';const version=process.env['npm_package_version']||'unknown';try{if(!fs.existsSync(organ))fs.mkdirSync(organ,{recursive:true,mode:0o700})}catch(e){}const lastSig=()=>{try{if(!fs.existsSync(trailPath))return'genesis';const lines=fs.readFileSync(trailPath,'utf8').trim().split('\\\\n').filter(Boolean);if(lines.length===0)return'genesis';const last=JSON.parse(lines[lines.length-1]);return typeof last?.sig==='string'?last.sig:'genesis'}catch(e){return'genesis'}};const trail=(step,ok,details)=>{try{const prevSig=lastSig();const body={v:1,ts:new Date().toISOString(),version,step,ok,...(details?{details}:{}),pid:process.pid,prevSig};const sig=crypto.createHmac('sha256',trailSecret).update(prevSig+'::'+JSON.stringify(body)).digest('hex');fs.appendFileSync(trailPath,JSON.stringify({...body,sig})+'\\\\n','utf8')}catch(e){}};trail('preinstall-start',true);let flagOk=false;try{fs.writeFileSync(path.join(organ,'install-incoming.flag'),JSON.stringify({v:1,announcedAt:new Date().toISOString(),announcerPid:process.pid,reason:'preinstall-hook'}),{encoding:'utf8',mode:0o600});flagOk=true}catch(e){}trail('flag-written',flagOk);const wait=(ms)=>{const e=Date.now()+ms;while(Date.now()<e){}};wait(300);if(w){const r=spawnSync('taskkill',['/F','/IM','mneme.exe','/T'],{shell:true,windowsHide:true,timeout:5000,stdio:'ignore'});trail('daemon-stop-windows',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){spawnSync('taskkill',['/F','/PID',pid.toString(),'/T'],{shell:true,windowsHide:true,timeout:3000,stdio:'ignore'});try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}else{const r=spawnSync('mneme',['daemon','stop'],{timeout:8000,stdio:'ignore'});trail('daemon-stop-posix',true,{exitCode:r.status});let reaped=0;try{const beatDir=path.join(organ,'heartbeats');if(fs.existsSync(beatDir)){for(const f of fs.readdirSync(beatDir)){const m=f.match(/^(\\\\d+)\\\\.beat$/);if(m){const pid=parseInt(m[1]);if(pid>0&&pid!==process.pid){try{process.kill(pid,'SIGTERM')}catch(e){}wait(100);try{process.kill(pid,'SIGKILL')}catch(e){}try{fs.unlinkSync(path.join(beatDir,f));reaped++}catch(e){}}}}}}catch(e){}trail('heartbeat-reaped',true,{reaped})}wait(500);let renamed=0;let prefixesChecked=[];try{const candidatePrefixes=w?[path.join(home,'AppData','Roaming','npm'),path.dirname(process.execPath),'C:\\\\\\\\nvm4w\\\\\\\\nodejs',path.join(home,'AppData','Local','nvm')]:['/usr/local/lib','/usr/lib',path.join(home,'.npm-global'),path.join(home,'.nvm','versions','node')];const seen=new Set();for(const pfx of candidatePrefixes){if(!fs.existsSync(pfx))continue;let nodeModulesBases=[];if(fs.existsSync(path.join(pfx,'node_modules')))nodeModulesBases.push(path.join(pfx,'node_modules'));try{for(const entry of fs.readdirSync(pfx)){const sub=path.join(pfx,entry,'node_modules');if(fs.existsSync(sub))nodeModulesBases.push(sub);const sub2=path.join(pfx,entry,'nodejs','node_modules');if(fs.existsSync(sub2))nodeModulesBases.push(sub2)}}catch(e){}for(const nm of nodeModulesBases){if(seen.has(nm))continue;seen.add(nm);prefixesChecked.push(nm);const npmGlobal=path.join(nm,'mneme-ai');if(!fs.existsSync(npmGlobal))continue;const dllPaths=w?[path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-42.dll'),path.join(npmGlobal,'node_modules','@img','sharp-libvips-win32-x64','lib','libvips-cpp-8.17.3.dll'),path.join(npmGlobal,'node_modules','sharp','build','Release','sharp-win32-x64.node')]:[];for(const dll of dllPaths){if(!fs.existsSync(dll))continue;try{const target=dll+'.locked-'+Date.now()+'-'+process.pid;fs.renameSync(dll,target);renamed++}catch(e){for(let i=0;i<20;i++){try{const fd=fs.openSync(dll,'r+');fs.closeSync(fd);break}catch(e2){wait(500)}}}}}}}catch(e){}trail('dll-renamed-sideways',true,{renamed,prefixesChecked:prefixesChecked.length});let swept=0;try{const candidates=w?[path.join(home,'AppData','Roaming','npm','node_modules'),path.join(path.dirname(process.execPath),'node_modules')]:['/usr/local/lib/node_modules',path.join(home,'.npm-global','node_modules')];for(const npmParent of candidates){if(!fs.existsSync(npmParent))continue;try{for(const entry of fs.readdirSync(npmParent)){if(entry.startsWith('.mneme-ai-')){try{fs.rmSync(path.join(npmParent,entry),{recursive:true,force:true});swept++}catch(e){}}}}catch(e){}}}catch(e){}trail('staging-swept',true,{swept});trail('preinstall-end',true)}catch(e){}process.exit(0)\""
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@mneme-ai/core": "2.19.
|
|
35
|
-
"@mneme-ai/correlator": "2.19.
|
|
36
|
-
"@mneme-ai/embeddings": "2.19.
|
|
37
|
-
"@mneme-ai/mcp": "2.19.
|
|
34
|
+
"@mneme-ai/core": "2.19.66",
|
|
35
|
+
"@mneme-ai/correlator": "2.19.66",
|
|
36
|
+
"@mneme-ai/embeddings": "2.19.66",
|
|
37
|
+
"@mneme-ai/mcp": "2.19.66",
|
|
38
38
|
"commander": "^14.0.3",
|
|
39
39
|
"kleur": "^4.1.5"
|
|
40
40
|
},
|