Refactor silent debugging to happy path error handling
- Replaced instances of silentDebug with happy_path_error__with_fallback across multiple files to improve error logging and handling. - Updated the utility function to provide clearer semantics for error handling when expected values are missing. - Introduced a script to find potential silent failures in the codebase that may need to be addressed with the new error handling approach.
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import{stdin as A}from"process";import p from"path";import{existsSync as C}from"fs";import{homedir as I}from"os";import{spawnSync as U}from"child_process";import{readFileSync as x,existsSync as H}from"fs";import{join as F}from"path";import{homedir as j}from"os";var W=["bugfix","feature","refactor","discovery","decision","change"],b=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=W.join(","),R=b.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:F(j(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:R,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!H(t))return this.getAllDefaults();let e=x(t,"utf-8"),r=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let l of Object.keys(this.DEFAULTS))r[l]!==void 0&&(s[l]=r[l]);return s}};import{join as G}from"path";import{homedir as Y}from"os";import{existsSync as J,readFileSync as q}from"fs";import{appendFileSync as K}from"fs";import{homedir as V}from"os";import{join as X}from"path";var B=X(V(),".claude-mem","silent.log");function E(o,t,e=""){let n=new Date().toISOString(),g=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=g?`${g[1].split("/").pop()}:${g[2]}`:"unknown",a=`[${n}] [${u}] ${o}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(c){a+=` [stringify error: ${c}]`}a+=`
|
||||
`;try{K(B,a)}catch(c){console.error("[silent-debug] Failed to write to log:",c)}return e}var S=G(Y(),".claude-mem","settings.json");function y(o,t){try{if(J(S)){let n=JSON.parse(q(S,"utf-8")).env?.[o];if(n!==void 0)return n}}catch(e){E("Failed to load settings file",{error:e,settingsPath:S,key:o})}return process.env[o]||t}var O=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(O||{}),m=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=O[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let n=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&n.command){let r=n.command.length>50?n.command.substring(0,50)+"...":n.command;return`${t}(${r})`}if(t==="Read"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Edit"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Write"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}return t}catch{return t}}log(t,e,n,r,s){if(t<this.level)return;let l=new Date().toISOString().replace("T"," ").substring(0,23),g=O[t].padEnd(5),u=e.padEnd(6),a="";r?.correlationId?a=`[${r.correlationId}] `:r?.sessionId&&(a=`[session-${r.sessionId}] `);let c="";s!=null&&(this.level===0&&typeof s=="object"?c=`
|
||||
`+JSON.stringify(s,null,2):c=" "+this.formatData(s));let L="";if(r){let{sessionId:et,sdkSessionId:rt,correlationId:nt,...h}=r;Object.keys(h).length>0&&(L=` {${Object.entries(h).map(([$,v])=>`${$}=${v}`).join(", ")}}`)}let M=`[${l}] [${g}] [${u}] ${a}${n}${L}${c}`;t===3?console.error(M):console.log(M)}debug(t,e,n,r){this.log(0,t,e,n,r)}info(t,e,n,r){this.log(1,t,e,n,r)}warn(t,e,n,r){this.log(2,t,e,n,r)}error(t,e,n,r){this.log(3,t,e,n,r)}dataIn(t,e,n,r){this.info(t,`\u2192 ${e}`,n,r)}dataOut(t,e,n,r){this.info(t,`\u2190 ${e}`,n,r)}success(t,e,n,r){this.info(t,`\u2713 ${e}`,n,r)}failure(t,e,n,r){this.error(t,`\u2717 ${e}`,n,r)}timing(t,e,n,r){this.info(t,`\u23F1 ${e}`,r,{duration:`${n}ms`})}},d=new m;var _={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*_.WINDOWS_MULTIPLIER):o}var i=p.join(I(),".claude","plugins","marketplaces","thedotmack"),z=N(_.HEALTH_CHECK),Q=_.WORKER_STARTUP_WAIT,Z=_.WORKER_STARTUP_RETRIES;function T(){let o=p.join(I(),".claude-mem","settings.json"),t=f.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let o=T();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return d.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function tt(){try{let o=p.join(i,"plugin","scripts","worker-service.cjs");if(!C(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=U("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${i}' -WindowStyle Hidden`],{cwd:i,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=p.join(i,"ecosystem.config.cjs");if(!C(t))throw new Error(`Ecosystem config not found at ${t}`);let e=p.join(i,"node_modules",".bin","pm2"),n=C(e)?e:"pm2",r=U(n,["start",t],{cwd:i,stdio:"pipe",encoding:"utf-8"});if(r.status!==0)throw new Error(r.stderr||"PM2 start failed")}for(let t=0;t<Z;t++)if(await new Promise(e=>setTimeout(e,Q)),await P())return!0;return!1}catch(o){return d.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:p.join(i,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:i}),!1}}async function k(){if(await P())return;if(!await tt()){let t=T();throw new Error(`Worker service failed to start on port ${t}.
|
||||
import{stdin as A}from"process";import p from"path";import{existsSync as C}from"fs";import{homedir as I}from"os";import{spawnSync as U}from"child_process";import{readFileSync as x,existsSync as H}from"fs";import{join as F}from"path";import{homedir as j}from"os";var W=["bugfix","feature","refactor","discovery","decision","change"],b=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=W.join(","),R=b.join(",");var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:F(j(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:R,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!H(t))return this.getAllDefaults();let e=x(t,"utf-8"),r=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let l of Object.keys(this.DEFAULTS))r[l]!==void 0&&(s[l]=r[l]);return s}};import{join as G}from"path";import{homedir as Y}from"os";import{existsSync as J,readFileSync as q}from"fs";import{appendFileSync as K}from"fs";import{homedir as V}from"os";import{join as X}from"path";var B=X(V(),".claude-mem","silent.log");function E(o,t,e=""){let n=new Date().toISOString(),f=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),S=f?`${f[1].split("/").pop()}:${f[2]}`:"unknown",a=`[${n}] [HAPPY-PATH-ERROR] [${S}] ${o}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(c){a+=` [stringify error: ${c}]`}a+=`
|
||||
`;try{K(B,a)}catch(c){console.error("[silent-debug] Failed to write to log:",c)}return e}var u=G(Y(),".claude-mem","settings.json");function y(o,t){try{if(J(u)){let n=JSON.parse(q(u,"utf-8")).env?.[o];if(n!==void 0)return n}}catch(e){E("Failed to load settings file",{error:e,settingsPath:u,key:o})}return process.env[o]||t}var O=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(O||{}),m=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=O[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let n=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&n.command){let r=n.command.length>50?n.command.substring(0,50)+"...":n.command;return`${t}(${r})`}if(t==="Read"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Edit"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Write"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}return t}catch{return t}}log(t,e,n,r,s){if(t<this.level)return;let l=new Date().toISOString().replace("T"," ").substring(0,23),f=O[t].padEnd(5),S=e.padEnd(6),a="";r?.correlationId?a=`[${r.correlationId}] `:r?.sessionId&&(a=`[session-${r.sessionId}] `);let c="";s!=null&&(this.level===0&&typeof s=="object"?c=`
|
||||
`+JSON.stringify(s,null,2):c=" "+this.formatData(s));let L="";if(r){let{sessionId:et,sdkSessionId:rt,correlationId:nt,...M}=r;Object.keys(M).length>0&&(L=` {${Object.entries(M).map(([$,v])=>`${$}=${v}`).join(", ")}}`)}let h=`[${l}] [${f}] [${S}] ${a}${n}${L}${c}`;t===3?console.error(h):console.log(h)}debug(t,e,n,r){this.log(0,t,e,n,r)}info(t,e,n,r){this.log(1,t,e,n,r)}warn(t,e,n,r){this.log(2,t,e,n,r)}error(t,e,n,r){this.log(3,t,e,n,r)}dataIn(t,e,n,r){this.info(t,`\u2192 ${e}`,n,r)}dataOut(t,e,n,r){this.info(t,`\u2190 ${e}`,n,r)}success(t,e,n,r){this.info(t,`\u2713 ${e}`,n,r)}failure(t,e,n,r){this.error(t,`\u2717 ${e}`,n,r)}timing(t,e,n,r){this.info(t,`\u23F1 ${e}`,r,{duration:`${n}ms`})}},d=new m;var _={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*_.WINDOWS_MULTIPLIER):o}var i=p.join(I(),".claude","plugins","marketplaces","thedotmack"),z=N(_.HEALTH_CHECK),Q=_.WORKER_STARTUP_WAIT,Z=_.WORKER_STARTUP_RETRIES;function T(){let o=p.join(I(),".claude-mem","settings.json"),t=g.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let o=T();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return d.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function tt(){try{let o=p.join(i,"plugin","scripts","worker-service.cjs");if(!C(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=U("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${i}' -WindowStyle Hidden`],{cwd:i,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=p.join(i,"ecosystem.config.cjs");if(!C(t))throw new Error(`Ecosystem config not found at ${t}`);let e=p.join(i,"node_modules",".bin","pm2"),n=C(e)?e:"pm2",r=U(n,["start",t],{cwd:i,stdio:"pipe",encoding:"utf-8"});if(r.status!==0)throw new Error(r.stderr||"PM2 start failed")}for(let t=0;t<Z;t++)if(await new Promise(e=>setTimeout(e,Q)),await P())return!0;return!1}catch(o){return d.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:p.join(i,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:i}),!1}}async function k(){if(await P())return;if(!await tt()){let t=T();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${i}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
"use strict";var Be=Object.create;var V=Object.defineProperty;var He=Object.getOwnPropertyDescriptor;var je=Object.getOwnPropertyNames;var Ge=Object.getPrototypeOf,Ye=Object.prototype.hasOwnProperty;var Ve=(a,e)=>{for(var s in e)V(a,s,{get:e[s],enumerable:!0})},Te=(a,e,s,t)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of je(e))!Ye.call(a,n)&&n!==s&&V(a,n,{get:()=>e[n],enumerable:!(t=He(e,n))||t.enumerable});return a};var ge=(a,e,s)=>(s=a!=null?Be(Ge(a)):{},Te(e||!a||!a.__esModule?V(s,"default",{value:a,enumerable:!0}):s,a)),Ke=a=>Te(V({},"__esModule",{value:!0}),a);var cs={};Ve(cs,{generateContext:()=>as});module.exports=Ke(cs);var U=ge(require("path"),1),ee=require("os"),P=require("fs");var Ce=ge(require("better-sqlite3"),1);var S=require("path"),oe=require("os"),Ne=require("fs");var Ae=require("url");var Oe=require("path"),Re=require("os"),K=require("fs");var Se=require("fs"),he=require("os"),be=require("path"),qe=(0,be.join)((0,he.homedir)(),".claude-mem","silent.log");function fe(a,e,s=""){let t=new Date().toISOString(),d=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=d?`${d[1].split("/").pop()}:${d[2]}`:"unknown",m=`[${t}] [${_}] ${a}`;if(e!==void 0)try{m+=` ${JSON.stringify(e)}`}catch(l){m+=` [stringify error: ${l}]`}m+=`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),_=d?`${d[1].split("/").pop()}:${d[2]}`:"unknown",m=`[${t}] [HAPPY-PATH-ERROR] [${_}] ${a}`;if(e!==void 0)try{m+=` ${JSON.stringify(e)}`}catch(l){m+=` [stringify error: ${l}]`}m+=`
|
||||
`;try{(0,Se.appendFileSync)(qe,m)}catch(l){console.error("[silent-debug] Failed to write to log:",l)}return s}var ne=(0,Oe.join)((0,Re.homedir)(),".claude-mem","settings.json");function q(a,e){try{if((0,K.existsSync)(ne)){let t=JSON.parse((0,K.readFileSync)(ne,"utf-8")).env?.[a];if(t!==void 0)return t}}catch(s){fe("Failed to load settings file",{error:s,settingsPath:ne,key:a})}return process.env[a]||e}var Qe={};function Je(){return typeof __dirname<"u"?__dirname:(0,S.dirname)((0,Ae.fileURLToPath)(Qe.url))}var Ss=Je(),C=q("CLAUDE_MEM_DATA_DIR",(0,S.join)((0,oe.homedir)(),".claude-mem")),ie=process.env.CLAUDE_CONFIG_DIR||(0,S.join)((0,oe.homedir)(),".claude"),hs=(0,S.join)(C,"archives"),bs=(0,S.join)(C,"logs"),fs=(0,S.join)(C,"trash"),Os=(0,S.join)(C,"backups"),Rs=(0,S.join)(C,"settings.json"),Ie=(0,S.join)(C,"claude-mem.db"),Ns=(0,S.join)(C,"vector-db"),As=(0,S.join)(ie,"settings.json"),Is=(0,S.join)(ie,"commands"),Ls=(0,S.join)(ie,"CLAUDE.md");function Le(a){(0,Ne.mkdirSync)(a,{recursive:!0})}var ae=(i=>(i[i.DEBUG=0]="DEBUG",i[i.INFO=1]="INFO",i[i.WARN=2]="WARN",i[i.ERROR=3]="ERROR",i[i.SILENT=4]="SILENT",i))(ae||{}),ce=class{level;useColor;constructor(){let e=q("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=ae[e]??1,this.useColor=process.stdout.isTTY??!1}correlationId(e,s){return`obs-${e}-${s}`}sessionId(e){return`session-${e}`}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.level===0?`${e.message}
|
||||
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let s=Object.keys(e);return s.length===0?"{}":s.length<=3?JSON.stringify(e):`{${s.length} keys: ${s.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,s){if(!s)return e;try{let t=typeof s=="string"?JSON.parse(s):s;if(e==="Bash"&&t.command){let n=t.command.length>50?t.command.substring(0,50)+"...":t.command;return`${e}(${n})`}if(e==="Read"&&t.file_path){let n=t.file_path.split("/").pop()||t.file_path;return`${e}(${n})`}if(e==="Edit"&&t.file_path){let n=t.file_path.split("/").pop()||t.file_path;return`${e}(${n})`}if(e==="Write"&&t.file_path){let n=t.file_path.split("/").pop()||t.file_path;return`${e}(${n})`}return e}catch{return e}}log(e,s,t,n,i){if(e<this.level)return;let c=new Date().toISOString().replace("T"," ").substring(0,23),d=ae[e].padEnd(5),_=s.padEnd(6),m="";n?.correlationId?m=`[${n.correlationId}] `:n?.sessionId&&(m=`[session-${n.sessionId}] `);let l="";i!=null&&(this.level===0&&typeof i=="object"?l=`
|
||||
`+JSON.stringify(i,null,2):l=" "+this.formatData(i));let b="";if(n){let{sessionId:f,sdkSessionId:y,correlationId:E,...r}=n;Object.keys(r).length>0&&(b=` {${Object.entries(r).map(([O,h])=>`${O}=${h}`).join(", ")}}`)}let v=`[${c}] [${d}] [${_}] ${m}${t}${b}${l}`;e===3?console.error(v):console.log(v)}debug(e,s,t,n){this.log(0,e,s,t,n)}info(e,s,t,n){this.log(1,e,s,t,n)}warn(e,s,t,n){this.log(2,e,s,t,n)}error(e,s,t,n){this.log(3,e,s,t,n)}dataIn(e,s,t,n){this.info(e,`\u2192 ${s}`,t,n)}dataOut(e,s,t,n){this.info(e,`\u2190 ${s}`,t,n)}success(e,s,t,n){this.info(e,`\u2713 ${s}`,t,n)}failure(e,s,t,n){this.error(e,`\u2717 ${s}`,t,n)}timing(e,s,t,n){this.info(e,`\u23F1 ${s}`,n,{duration:`${t}ms`})}},B=new ce;var J=class{db;constructor(){Le(C),this.db=new Ce.default(Ie),this.db.pragma("journal_mode = WAL"),this.db.pragma("synchronous = NORMAL"),this.db.pragma("foreign_keys = ON"),this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn()}initializeSchema(){try{this.db.exec(`
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import et from"path";import{stdin as d}from"process";import l from"path";import{existsSync as C}from"fs";import{homedir as I}from"os";import{spawnSync as U}from"child_process";import{readFileSync as b,existsSync as H}from"fs";import{join as F}from"path";import{homedir as j}from"os";var v=["bugfix","feature","refactor","discovery","decision","change"],W=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var h=v.join(","),D=W.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:F(j(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:h,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:D,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!H(t))return this.getAllDefaults();let e=b(t,"utf-8"),n=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))n[a]!==void 0&&(s[a]=n[a]);return s}};import{join as G}from"path";import{homedir as Y}from"os";import{existsSync as J,readFileSync as q}from"fs";import{appendFileSync as K}from"fs";import{homedir as V}from"os";import{join as X}from"path";var B=X(V(),".claude-mem","silent.log");function R(o,t,e=""){let r=new Date().toISOString(),E=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=E?`${E[1].split("/").pop()}:${E[2]}`:"unknown",c=`[${r}] [${u}] ${o}`;if(t!==void 0)try{c+=` ${JSON.stringify(t)}`}catch(_){c+=` [stringify error: ${_}]`}c+=`
|
||||
`;try{K(B,c)}catch(_){console.error("[silent-debug] Failed to write to log:",_)}return e}var g=G(Y(),".claude-mem","settings.json");function y(o,t){try{if(J(g)){let r=JSON.parse(q(g,"utf-8")).env?.[o];if(r!==void 0)return r}}catch(e){R("Failed to load settings file",{error:e,settingsPath:g,key:o})}return process.env[o]||t}var S=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(S||{}),O=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=S[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let n=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${n})`}if(t==="Read"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Edit"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Write"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}return t}catch{return t}}log(t,e,r,n,s){if(t<this.level)return;let a=new Date().toISOString().replace("T"," ").substring(0,23),E=S[t].padEnd(5),u=e.padEnd(6),c="";n?.correlationId?c=`[${n.correlationId}] `:n?.sessionId&&(c=`[session-${n.sessionId}] `);let _="";s!=null&&(this.level===0&&typeof s=="object"?_=`
|
||||
`+JSON.stringify(s,null,2):_=" "+this.formatData(s));let A="";if(n){let{sessionId:nt,sdkSessionId:ot,correlationId:st,...M}=n;Object.keys(M).length>0&&(A=` {${Object.entries(M).map(([k,x])=>`${k}=${x}`).join(", ")}}`)}let L=`[${a}] [${E}] [${u}] ${c}${r}${A}${_}`;t===3?console.error(L):console.log(L)}debug(t,e,r,n){this.log(0,t,e,r,n)}info(t,e,r,n){this.log(1,t,e,r,n)}warn(t,e,r,n){this.log(2,t,e,r,n)}error(t,e,r,n){this.log(3,t,e,r,n)}dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}},m=new O;var p={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*p.WINDOWS_MULTIPLIER):o}var i=l.join(I(),".claude","plugins","marketplaces","thedotmack"),z=N(p.HEALTH_CHECK),Q=p.WORKER_STARTUP_WAIT,Z=p.WORKER_STARTUP_RETRIES;function T(){let o=l.join(I(),".claude-mem","settings.json"),t=f.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function w(){try{let o=T();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return m.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function tt(){try{let o=l.join(i,"plugin","scripts","worker-service.cjs");if(!C(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=U("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${i}' -WindowStyle Hidden`],{cwd:i,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=l.join(i,"ecosystem.config.cjs");if(!C(t))throw new Error(`Ecosystem config not found at ${t}`);let e=l.join(i,"node_modules",".bin","pm2"),r=C(e)?e:"pm2",n=U(r,["start",t],{cwd:i,stdio:"pipe",encoding:"utf-8"});if(n.status!==0)throw new Error(n.stderr||"PM2 start failed")}for(let t=0;t<Z;t++)if(await new Promise(e=>setTimeout(e,Q)),await w())return!0;return!1}catch(o){return m.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:l.join(i,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:i}),!1}}async function P(){if(await w())return;if(!await tt()){let t=T();throw new Error(`Worker service failed to start on port ${t}.
|
||||
import et from"path";import{stdin as d}from"process";import l from"path";import{existsSync as C}from"fs";import{homedir as I}from"os";import{spawnSync as U}from"child_process";import{readFileSync as b,existsSync as H}from"fs";import{join as F}from"path";import{homedir as j}from"os";var v=["bugfix","feature","refactor","discovery","decision","change"],W=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var M=v.join(","),R=W.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:F(j(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:M,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:R,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!H(t))return this.getAllDefaults();let e=b(t,"utf-8"),n=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let c of Object.keys(this.DEFAULTS))n[c]!==void 0&&(s[c]=n[c]);return s}};import{join as G}from"path";import{homedir as Y}from"os";import{existsSync as J,readFileSync as q}from"fs";import{appendFileSync as K}from"fs";import{homedir as V}from"os";import{join as X}from"path";var B=X(V(),".claude-mem","silent.log");function D(o,t,e=""){let r=new Date().toISOString(),E=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=E?`${E[1].split("/").pop()}:${E[2]}`:"unknown",a=`[${r}] [HAPPY-PATH-ERROR] [${u}] ${o}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(_){a+=` [stringify error: ${_}]`}a+=`
|
||||
`;try{K(B,a)}catch(_){console.error("[silent-debug] Failed to write to log:",_)}return e}var g=G(Y(),".claude-mem","settings.json");function y(o,t){try{if(J(g)){let r=JSON.parse(q(g,"utf-8")).env?.[o];if(r!==void 0)return r}}catch(e){D("Failed to load settings file",{error:e,settingsPath:g,key:o})}return process.env[o]||t}var S=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(S||{}),O=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=S[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let n=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${n})`}if(t==="Read"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Edit"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Write"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}return t}catch{return t}}log(t,e,r,n,s){if(t<this.level)return;let c=new Date().toISOString().replace("T"," ").substring(0,23),E=S[t].padEnd(5),u=e.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let _="";s!=null&&(this.level===0&&typeof s=="object"?_=`
|
||||
`+JSON.stringify(s,null,2):_=" "+this.formatData(s));let A="";if(n){let{sessionId:nt,sdkSessionId:ot,correlationId:st,...h}=n;Object.keys(h).length>0&&(A=` {${Object.entries(h).map(([k,x])=>`${k}=${x}`).join(", ")}}`)}let L=`[${c}] [${E}] [${u}] ${a}${r}${A}${_}`;t===3?console.error(L):console.log(L)}debug(t,e,r,n){this.log(0,t,e,r,n)}info(t,e,r,n){this.log(1,t,e,r,n)}warn(t,e,r,n){this.log(2,t,e,r,n)}error(t,e,r,n){this.log(3,t,e,r,n)}dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}},m=new O;var p={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*p.WINDOWS_MULTIPLIER):o}var i=l.join(I(),".claude","plugins","marketplaces","thedotmack"),z=N(p.HEALTH_CHECK),Q=p.WORKER_STARTUP_WAIT,Z=p.WORKER_STARTUP_RETRIES;function T(){let o=l.join(I(),".claude-mem","settings.json"),t=f.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function w(){try{let o=T();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return m.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function tt(){try{let o=l.join(i,"plugin","scripts","worker-service.cjs");if(!C(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=U("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${i}' -WindowStyle Hidden`],{cwd:i,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=l.join(i,"ecosystem.config.cjs");if(!C(t))throw new Error(`Ecosystem config not found at ${t}`);let e=l.join(i,"node_modules",".bin","pm2"),r=C(e)?e:"pm2",n=U(r,["start",t],{cwd:i,stdio:"pipe",encoding:"utf-8"});if(n.status!==0)throw new Error(n.stderr||"PM2 start failed")}for(let t=0;t<Z;t++)if(await new Promise(e=>setTimeout(e,Q)),await w())return!0;return!1}catch(o){return m.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:l.join(i,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:i}),!1}}async function P(){if(await w())return;if(!await tt()){let t=T();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${i}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env node
|
||||
import ot from"path";import{stdin as b}from"process";function x(n,t,e){return n==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:n==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:n==="UserPromptSubmit"||n==="PostToolUse"?{continue:!0,suppressOutput:!0}:n==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function m(n,t,e={}){let r=x(n,t,e);return JSON.stringify(r)}import _ from"path";import{existsSync as A}from"fs";import{homedir as w}from"os";import{spawnSync as I}from"child_process";import{readFileSync as F,existsSync as j}from"fs";import{join as V}from"path";import{homedir as K}from"os";var H=["bugfix","feature","refactor","discovery","decision","change"],W=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var y=H.join(","),D=W.join(",");var S=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:V(K(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:y,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:D,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!j(t))return this.getAllDefaults();let e=F(t,"utf-8"),o=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let c of Object.keys(this.DEFAULTS))o[c]!==void 0&&(s[c]=o[c]);return s}};import{join as J}from"path";import{homedir as q}from"os";import{existsSync as z,readFileSync as Q}from"fs";import{appendFileSync as X}from"fs";import{homedir as B}from"os";import{join as G}from"path";var Y=G(B(),".claude-mem","silent.log");function l(n,t,e=""){let r=new Date().toISOString(),p=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),i=p?`${p[1].split("/").pop()}:${p[2]}`:"unknown",a=`[${r}] [${i}] ${n}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(E){a+=` [stringify error: ${E}]`}a+=`
|
||||
import ot from"path";import{stdin as b}from"process";function H(n,t,e){return n==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:n==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:n==="UserPromptSubmit"||n==="PostToolUse"?{continue:!0,suppressOutput:!0}:n==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function m(n,t,e={}){let r=H(n,t,e);return JSON.stringify(r)}import _ from"path";import{existsSync as A}from"fs";import{homedir as w}from"os";import{spawnSync as I}from"child_process";import{readFileSync as F,existsSync as j}from"fs";import{join as V}from"path";import{homedir as K}from"os";var v=["bugfix","feature","refactor","discovery","decision","change"],W=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var y=v.join(","),D=W.join(",");var S=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:V(K(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:y,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:D,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!j(t))return this.getAllDefaults();let e=F(t,"utf-8"),o=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let p of Object.keys(this.DEFAULTS))o[p]!==void 0&&(s[p]=o[p]);return s}};import{join as J}from"path";import{homedir as q}from"os";import{existsSync as z,readFileSync as Q}from"fs";import{appendFileSync as X}from"fs";import{homedir as B}from"os";import{join as G}from"path";var Y=G(B(),".claude-mem","silent.log");function l(n,t,e=""){let r=new Date().toISOString(),c=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),i=c?`${c[1].split("/").pop()}:${c[2]}`:"unknown",a=`[${r}] [HAPPY-PATH-ERROR] [${i}] ${n}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(E){a+=` [stringify error: ${E}]`}a+=`
|
||||
`;try{X(Y,a)}catch(E){console.error("[silent-debug] Failed to write to log:",E)}return e}var O=J(q(),".claude-mem","settings.json");function N(n,t){try{if(z(O)){let r=JSON.parse(Q(O,"utf-8")).env?.[n];if(r!==void 0)return r}}catch(e){l("Failed to load settings file",{error:e,settingsPath:O,key:n})}return process.env[n]||t}var T=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(T||{}),d=class{level;useColor;constructor(){let t=N("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=T[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let o=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${o})`}if(t==="Read"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}if(t==="Edit"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}if(t==="Write"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}return t}catch{return t}}log(t,e,r,o,s){if(t<this.level)return;let c=new Date().toISOString().replace("T"," ").substring(0,23),p=T[t].padEnd(5),i=e.padEnd(6),a="";o?.correlationId?a=`[${o.correlationId}] `:o?.sessionId&&(a=`[session-${o.sessionId}] `);let E="";s!=null&&(this.level===0&&typeof s=="object"?E=`
|
||||
`+JSON.stringify(s,null,2):E=" "+this.formatData(s));let h="";if(o){let{sessionId:st,sdkSessionId:it,correlationId:at,...R}=o;Object.keys(R).length>0&&(h=` {${Object.entries(R).map(([$,v])=>`${$}=${v}`).join(", ")}}`)}let M=`[${c}] [${p}] [${i}] ${a}${r}${h}${E}`;t===3?console.error(M):console.log(M)}debug(t,e,r,o){this.log(0,t,e,r,o)}info(t,e,r,o){this.log(1,t,e,r,o)}warn(t,e,r,o){this.log(2,t,e,r,o)}error(t,e,r,o){this.log(3,t,e,r,o)}dataIn(t,e,r,o){this.info(t,`\u2192 ${e}`,r,o)}dataOut(t,e,r,o){this.info(t,`\u2190 ${e}`,r,o)}success(t,e,r,o){this.info(t,`\u2713 ${e}`,r,o)}failure(t,e,r,o){this.error(t,`\u2717 ${e}`,r,o)}timing(t,e,r,o){this.info(t,`\u23F1 ${e}`,o,{duration:`${r}ms`})}},C=new d;var f={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function U(n){return process.platform==="win32"?Math.round(n*f.WINDOWS_MULTIPLIER):n}var u=_.join(w(),".claude","plugins","marketplaces","thedotmack"),Z=U(f.HEALTH_CHECK),tt=f.WORKER_STARTUP_WAIT,et=f.WORKER_STARTUP_RETRIES;function g(){let n=_.join(w(),".claude-mem","settings.json"),t=S.loadFromFile(n);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let n=g();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(Z)})).ok}catch(n){return C.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}async function rt(){try{let n=_.join(u,"plugin","scripts","worker-service.cjs");if(!A(n))throw new Error(`Worker script not found at ${n}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${n}' -WorkingDirectory '${u}' -WindowStyle Hidden`],{cwd:u,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=_.join(u,"ecosystem.config.cjs");if(!A(t))throw new Error(`Ecosystem config not found at ${t}`);let e=_.join(u,"node_modules",".bin","pm2"),r=A(e)?e:"pm2",o=I(r,["start",t],{cwd:u,stdio:"pipe",encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr||"PM2 start failed")}for(let t=0;t<et;t++)if(await new Promise(e=>setTimeout(e,tt)),await P())return!0;return!1}catch(n){return C.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:_.join(u,"plugin","scripts","worker-service.cjs"),error:n instanceof Error?n.message:String(n),marketplaceRoot:u}),!1}}async function k(){if(await P())return;if(!await rt()){let t=g();throw new Error(`Worker service failed to start on port ${t}.
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let o=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${o})`}if(t==="Read"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}if(t==="Edit"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}if(t==="Write"&&r.file_path){let o=r.file_path.split("/").pop()||r.file_path;return`${t}(${o})`}return t}catch{return t}}log(t,e,r,o,s){if(t<this.level)return;let p=new Date().toISOString().replace("T"," ").substring(0,23),c=T[t].padEnd(5),i=e.padEnd(6),a="";o?.correlationId?a=`[${o.correlationId}] `:o?.sessionId&&(a=`[session-${o.sessionId}] `);let E="";s!=null&&(this.level===0&&typeof s=="object"?E=`
|
||||
`+JSON.stringify(s,null,2):E=" "+this.formatData(s));let L="";if(o){let{sessionId:st,sdkSessionId:it,correlationId:at,...M}=o;Object.keys(M).length>0&&(L=` {${Object.entries(M).map(([$,x])=>`${$}=${x}`).join(", ")}}`)}let R=`[${p}] [${c}] [${i}] ${a}${r}${L}${E}`;t===3?console.error(R):console.log(R)}debug(t,e,r,o){this.log(0,t,e,r,o)}info(t,e,r,o){this.log(1,t,e,r,o)}warn(t,e,r,o){this.log(2,t,e,r,o)}error(t,e,r,o){this.log(3,t,e,r,o)}dataIn(t,e,r,o){this.info(t,`\u2192 ${e}`,r,o)}dataOut(t,e,r,o){this.info(t,`\u2190 ${e}`,r,o)}success(t,e,r,o){this.info(t,`\u2713 ${e}`,r,o)}failure(t,e,r,o){this.error(t,`\u2717 ${e}`,r,o)}timing(t,e,r,o){this.info(t,`\u23F1 ${e}`,o,{duration:`${r}ms`})}},C=new d;var f={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function U(n){return process.platform==="win32"?Math.round(n*f.WINDOWS_MULTIPLIER):n}var u=_.join(w(),".claude","plugins","marketplaces","thedotmack"),Z=U(f.HEALTH_CHECK),tt=f.WORKER_STARTUP_WAIT,et=f.WORKER_STARTUP_RETRIES;function g(){let n=_.join(w(),".claude-mem","settings.json"),t=S.loadFromFile(n);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let n=g();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(Z)})).ok}catch(n){return C.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}async function rt(){try{let n=_.join(u,"plugin","scripts","worker-service.cjs");if(!A(n))throw new Error(`Worker script not found at ${n}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${n}' -WorkingDirectory '${u}' -WindowStyle Hidden`],{cwd:u,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=_.join(u,"ecosystem.config.cjs");if(!A(t))throw new Error(`Ecosystem config not found at ${t}`);let e=_.join(u,"node_modules",".bin","pm2"),r=A(e)?e:"pm2",o=I(r,["start",t],{cwd:u,stdio:"pipe",encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr||"PM2 start failed")}for(let t=0;t<et;t++)if(await new Promise(e=>setTimeout(e,tt)),await P())return!0;return!1}catch(n){return C.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:_.join(u,"plugin","scripts","worker-service.cjs"),error:n instanceof Error?n.message:String(n),marketplaceRoot:u}),!1}}async function k(){if(await P())return;if(!await rt()){let t=g();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${u}
|
||||
npx pm2 start ecosystem.config.cjs
|
||||
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}async function nt(n){if(await k(),!n)throw new Error("newHook requires input");let{session_id:t,cwd:e,prompt:r}=n;l("[new-hook] Input received",{session_id:t,cwd:e,cwd_type:typeof e,cwd_length:e?.length,has_cwd:!!e,prompt_length:r?.length});let o=ot.basename(e);l("[new-hook] Project extracted",{project:o,project_type:typeof o,project_length:o?.length,is_empty:o==="",cwd_was:e});let s=g(),c,p;try{let i=await fetch(`http://127.0.0.1:${s}/api/sessions/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,project:o,prompt:r}),signal:AbortSignal.timeout(5e3)});if(!i.ok){let E=await i.text();throw new Error(`Failed to initialize session: ${i.status} ${E}`)}let a=await i.json();if(c=a.sessionDbId,p=a.promptNumber,a.skipped&&a.reason==="private"){console.error(`[new-hook] Session ${c}, prompt #${p} (fully private - skipped)`),console.log(m("UserPromptSubmit",!0));return}console.error(`[new-hook] Session ${c}, prompt #${p}`)}catch(i){throw i.cause?.code==="ECONNREFUSED"||i.name==="TimeoutError"||i.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):i}console.log(m("UserPromptSubmit",!0))}var L="";b.on("data",n=>L+=n);b.on("end",async()=>{let n=L?JSON.parse(L):void 0;await nt(n)});
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}async function nt(n){if(await k(),!n)throw new Error("newHook requires input");let{session_id:t,cwd:e,prompt:r}=n;l("[new-hook] Input received",{session_id:t,cwd:e,cwd_type:typeof e,cwd_length:e?.length,has_cwd:!!e,prompt_length:r?.length});let o=ot.basename(e);l("[new-hook] Project extracted",{project:o,project_type:typeof o,project_length:o?.length,is_empty:o==="",cwd_was:e});let s=g(),p,c;try{let i=await fetch(`http://127.0.0.1:${s}/api/sessions/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,project:o,prompt:r}),signal:AbortSignal.timeout(5e3)});if(!i.ok){let E=await i.text();throw new Error(`Failed to initialize session: ${i.status} ${E}`)}let a=await i.json();if(p=a.sessionDbId,c=a.promptNumber,a.skipped&&a.reason==="private"){console.error(`[new-hook] Session ${p}, prompt #${c} (fully private - skipped)`),console.log(m("UserPromptSubmit",!0));return}console.error(`[new-hook] Session ${p}, prompt #${c}`)}catch(i){throw i.cause?.code==="ECONNREFUSED"||i.name==="TimeoutError"||i.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):i}console.log(m("UserPromptSubmit",!0))}var h="";b.on("data",n=>h+=n);b.on("end",async()=>{let n=h?JSON.parse(h):void 0;await nt(n)});
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env node
|
||||
import{stdin as b}from"process";function H(o,t,e){return o==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:o==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:o==="UserPromptSubmit"||o==="PostToolUse"?{continue:!0,suppressOutput:!0}:o==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function T(o,t,e={}){let r=H(o,t,e);return JSON.stringify(r)}import{join as j}from"path";import{homedir as V}from"os";import{existsSync as X,readFileSync as B}from"fs";import{appendFileSync as x}from"fs";import{homedir as W}from"os";import{join as F}from"path";var K=F(W(),".claude-mem","silent.log");function h(o,t,e=""){let r=new Date().toISOString(),p=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),i=p?`${p[1].split("/").pop()}:${p[2]}`:"unknown",a=`[${r}] [${i}] ${o}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(_){a+=` [stringify error: ${_}]`}a+=`
|
||||
`;try{x(K,a)}catch(_){console.error("[silent-debug] Failed to write to log:",_)}return e}var g=j(V(),".claude-mem","settings.json");function y(o,t){try{if(X(g)){let r=JSON.parse(B(g,"utf-8")).env?.[o];if(r!==void 0)return r}}catch(e){h("Failed to load settings file",{error:e,settingsPath:g,key:o})}return process.env[o]||t}var m=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(m||{}),d=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=m[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let n=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${n})`}if(t==="Read"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Edit"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Write"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}return t}catch{return t}}log(t,e,r,n,s){if(t<this.level)return;let c=new Date().toISOString().replace("T"," ").substring(0,23),p=m[t].padEnd(5),i=e.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let _="";s!=null&&(this.level===0&&typeof s=="object"?_=`
|
||||
`+JSON.stringify(s,null,2):_=" "+this.formatData(s));let L="";if(n){let{sessionId:st,sdkSessionId:it,correlationId:at,...R}=n;Object.keys(R).length>0&&(L=` {${Object.entries(R).map(([$,v])=>`${$}=${v}`).join(", ")}}`)}let M=`[${c}] [${p}] [${i}] ${a}${r}${L}${_}`;t===3?console.error(M):console.log(M)}debug(t,e,r,n){this.log(0,t,e,r,n)}info(t,e,r,n){this.log(1,t,e,r,n)}warn(t,e,r,n){this.log(2,t,e,r,n)}error(t,e,r,n){this.log(3,t,e,r,n)}dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}},u=new d;import f from"path";import{existsSync as C}from"fs";import{homedir as P}from"os";import{spawnSync as I}from"child_process";import{readFileSync as J,existsSync as q}from"fs";import{join as Q}from"path";import{homedir as z}from"os";var G=["bugfix","feature","refactor","discovery","decision","change"],Y=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=G.join(","),U=Y.join(",");var S=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:Q(z(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:U,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!q(t))return this.getAllDefaults();let e=J(t,"utf-8"),n=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let c of Object.keys(this.DEFAULTS))n[c]!==void 0&&(s[c]=n[c]);return s}};var l={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*l.WINDOWS_MULTIPLIER):o}var E=f.join(P(),".claude","plugins","marketplaces","thedotmack"),Z=N(l.HEALTH_CHECK),tt=l.WORKER_STARTUP_WAIT,et=l.WORKER_STARTUP_RETRIES;function O(){let o=f.join(P(),".claude-mem","settings.json"),t=S.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function w(){try{let o=O();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(Z)})).ok}catch(o){return u.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function rt(){try{let o=f.join(E,"plugin","scripts","worker-service.cjs");if(!C(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${E}' -WindowStyle Hidden`],{cwd:E,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=f.join(E,"ecosystem.config.cjs");if(!C(t))throw new Error(`Ecosystem config not found at ${t}`);let e=f.join(E,"node_modules",".bin","pm2"),r=C(e)?e:"pm2",n=I(r,["start",t],{cwd:E,stdio:"pipe",encoding:"utf-8"});if(n.status!==0)throw new Error(n.stderr||"PM2 start failed")}for(let t=0;t<et;t++)if(await new Promise(e=>setTimeout(e,tt)),await w())return!0;return!1}catch(o){return u.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:f.join(E,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:E}),!1}}async function k(){if(await w())return;if(!await rt()){let t=O();throw new Error(`Worker service failed to start on port ${t}.
|
||||
import{stdin as b}from"process";function v(o,t,e){return o==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:o==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:o==="UserPromptSubmit"||o==="PostToolUse"?{continue:!0,suppressOutput:!0}:o==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function g(o,t,e={}){let r=v(o,t,e);return JSON.stringify(r)}import{join as j}from"path";import{homedir as V}from"os";import{existsSync as X,readFileSync as B}from"fs";import{appendFileSync as x}from"fs";import{homedir as W}from"os";import{join as F}from"path";var K=F(W(),".claude-mem","silent.log");function S(o,t,e=""){let r=new Date().toISOString(),u=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),i=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",a=`[${r}] [HAPPY-PATH-ERROR] [${i}] ${o}`;if(t!==void 0)try{a+=` ${JSON.stringify(t)}`}catch(_){a+=` [stringify error: ${_}]`}a+=`
|
||||
`;try{x(K,a)}catch(_){console.error("[silent-debug] Failed to write to log:",_)}return e}var m=j(V(),".claude-mem","settings.json");function y(o,t){try{if(X(m)){let r=JSON.parse(B(m,"utf-8")).env?.[o];if(r!==void 0)return r}}catch(e){S("Failed to load settings file",{error:e,settingsPath:m,key:o})}return process.env[o]||t}var d=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(d||{}),C=class{level;useColor;constructor(){let t=y("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=d[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let n=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${n})`}if(t==="Read"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Edit"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Write"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}return t}catch{return t}}log(t,e,r,n,s){if(t<this.level)return;let c=new Date().toISOString().replace("T"," ").substring(0,23),u=d[t].padEnd(5),i=e.padEnd(6),a="";n?.correlationId?a=`[${n.correlationId}] `:n?.sessionId&&(a=`[session-${n.sessionId}] `);let _="";s!=null&&(this.level===0&&typeof s=="object"?_=`
|
||||
`+JSON.stringify(s,null,2):_=" "+this.formatData(s));let h="";if(n){let{sessionId:st,sdkSessionId:it,correlationId:at,...R}=n;Object.keys(R).length>0&&(h=` {${Object.entries(R).map(([H,$])=>`${H}=${$}`).join(", ")}}`)}let M=`[${c}] [${u}] [${i}] ${a}${r}${h}${_}`;t===3?console.error(M):console.log(M)}debug(t,e,r,n){this.log(0,t,e,r,n)}info(t,e,r,n){this.log(1,t,e,r,n)}warn(t,e,r,n){this.log(2,t,e,r,n)}error(t,e,r,n){this.log(3,t,e,r,n)}dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}},p=new C;import f from"path";import{existsSync as A}from"fs";import{homedir as P}from"os";import{spawnSync as I}from"child_process";import{readFileSync as J,existsSync as q}from"fs";import{join as Q}from"path";import{homedir as z}from"os";var G=["bugfix","feature","refactor","discovery","decision","change"],Y=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=G.join(","),U=Y.join(",");var T=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:Q(z(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:U,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!q(t))return this.getAllDefaults();let e=J(t,"utf-8"),n=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let c of Object.keys(this.DEFAULTS))n[c]!==void 0&&(s[c]=n[c]);return s}};var l={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*l.WINDOWS_MULTIPLIER):o}var E=f.join(P(),".claude","plugins","marketplaces","thedotmack"),Z=N(l.HEALTH_CHECK),tt=l.WORKER_STARTUP_WAIT,et=l.WORKER_STARTUP_RETRIES;function O(){let o=f.join(P(),".claude-mem","settings.json"),t=T.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function w(){try{let o=O();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(Z)})).ok}catch(o){return p.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function rt(){try{let o=f.join(E,"plugin","scripts","worker-service.cjs");if(!A(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${E}' -WindowStyle Hidden`],{cwd:E,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=f.join(E,"ecosystem.config.cjs");if(!A(t))throw new Error(`Ecosystem config not found at ${t}`);let e=f.join(E,"node_modules",".bin","pm2"),r=A(e)?e:"pm2",n=I(r,["start",t],{cwd:E,stdio:"pipe",encoding:"utf-8"});if(n.status!==0)throw new Error(n.stderr||"PM2 start failed")}for(let t=0;t<et;t++)if(await new Promise(e=>setTimeout(e,tt)),await w())return!0;return!1}catch(o){return p.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:f.join(E,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:E}),!1}}async function k(){if(await w())return;if(!await rt()){let t=O();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${E}
|
||||
npx pm2 start ecosystem.config.cjs
|
||||
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}var ot=new Set(["ListMcpResourcesTool","SlashCommand","Skill","TodoWrite","AskUserQuestion"]);async function nt(o){if(await k(),!o)throw new Error("saveHook requires input");let{session_id:t,cwd:e,tool_name:r,tool_input:n,tool_response:s}=o;if(ot.has(r)){console.log(T("PostToolUse",!0));return}let c=O(),p=u.formatTool(r,n);u.dataIn("HOOK",`PostToolUse: ${p}`,{workerPort:c});try{let i=await fetch(`http://127.0.0.1:${c}/api/sessions/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,tool_name:r,tool_input:n,tool_response:s,cwd:e||""}),signal:AbortSignal.timeout(l.DEFAULT)});if(!i.ok){let a=await i.text();throw u.failure("HOOK","Failed to send observation",{status:i.status},a),new Error(`Failed to send observation to worker: ${i.status} ${a}`)}u.debug("HOOK","Observation sent successfully",{toolName:r})}catch(i){throw i.cause?.code==="ECONNREFUSED"||i.name==="TimeoutError"||i.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):i}console.log(T("PostToolUse",!0))}var A="";b.on("data",o=>A+=o);b.on("end",async()=>{let o=A?JSON.parse(A):void 0;await nt(o)});
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}var ot=new Set(["ListMcpResourcesTool","SlashCommand","Skill","TodoWrite","AskUserQuestion"]);async function nt(o){if(await k(),!o)throw new Error("saveHook requires input");let{session_id:t,cwd:e,tool_name:r,tool_input:n,tool_response:s}=o;if(ot.has(r)){console.log(g("PostToolUse",!0));return}let c=O(),u=p.formatTool(r,n);p.dataIn("HOOK",`PostToolUse: ${u}`,{workerPort:c});try{let i=await fetch(`http://127.0.0.1:${c}/api/sessions/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,tool_name:r,tool_input:n,tool_response:s,cwd:S("Missing cwd in PostToolUse hook input",{session_id:t,tool_name:r},e||"")}),signal:AbortSignal.timeout(l.DEFAULT)});if(!i.ok){let a=await i.text();throw p.failure("HOOK","Failed to send observation",{status:i.status},a),new Error(`Failed to send observation to worker: ${i.status} ${a}`)}p.debug("HOOK","Observation sent successfully",{toolName:r})}catch(i){throw i.cause?.code==="ECONNREFUSED"||i.name==="TimeoutError"||i.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):i}console.log(g("PostToolUse",!0))}var L="";b.on("data",o=>L+=o);b.on("end",async()=>{let o=L?JSON.parse(L):void 0;await nt(o)});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
import{stdin as x}from"process";import{readFileSync as H,existsSync as $}from"fs";function W(r,t,e){return r==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:r==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:r==="UserPromptSubmit"||r==="PostToolUse"?{continue:!0,suppressOutput:!0}:r==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function M(r,t,e={}){let n=W(r,t,e);return JSON.stringify(n)}import{join as X}from"path";import{homedir as B}from"os";import{existsSync as G,readFileSync as Y}from"fs";import{appendFileSync as F}from"fs";import{homedir as K}from"os";import{join as j}from"path";var V=j(K(),".claude-mem","silent.log");function h(r,t,e=""){let n=new Date().toISOString(),a=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),E=a?`${a[1].split("/").pop()}:${a[2]}`:"unknown",u=`[${n}] [${E}] ${r}`;if(t!==void 0)try{u+=` ${JSON.stringify(t)}`}catch(l){u+=` [stringify error: ${l}]`}u+=`
|
||||
`;try{F(V,u)}catch(l){console.error("[silent-debug] Failed to write to log:",l)}return e}var O=X(B(),".claude-mem","settings.json");function R(r,t){try{if(G(O)){let n=JSON.parse(Y(O,"utf-8")).env?.[r];if(n!==void 0)return n}}catch(e){h("Failed to load settings file",{error:e,settingsPath:O,key:r})}return process.env[r]||t}var m=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(m||{}),T=class{level;useColor;constructor(){let t=R("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=m[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let n=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&n.command){let o=n.command.length>50?n.command.substring(0,50)+"...":n.command;return`${t}(${o})`}if(t==="Read"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}if(t==="Edit"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}if(t==="Write"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}return t}catch{return t}}log(t,e,n,o,s){if(t<this.level)return;let i=new Date().toISOString().replace("T"," ").substring(0,23),a=m[t].padEnd(5),E=e.padEnd(6),u="";o?.correlationId?u=`[${o.correlationId}] `:o?.sessionId&&(u=`[session-${o.sessionId}] `);let l="";s!=null&&(this.level===0&&typeof s=="object"?l=`
|
||||
`+JSON.stringify(s,null,2):l=" "+this.formatData(s));let y="";if(o){let{sessionId:ct,sdkSessionId:pt,correlationId:ut,...L}=o;Object.keys(L).length>0&&(y=` {${Object.entries(L).map(([b,v])=>`${b}=${v}`).join(", ")}}`)}let A=`[${i}] [${a}] [${E}] ${u}${n}${y}${l}`;t===3?console.error(A):console.log(A)}debug(t,e,n,o){this.log(0,t,e,n,o)}info(t,e,n,o){this.log(1,t,e,n,o)}warn(t,e,n,o){this.log(2,t,e,n,o)}error(t,e,n,o){this.log(3,t,e,n,o)}dataIn(t,e,n,o){this.info(t,`\u2192 ${e}`,n,o)}dataOut(t,e,n,o){this.info(t,`\u2190 ${e}`,n,o)}success(t,e,n,o){this.info(t,`\u2713 ${e}`,n,o)}failure(t,e,n,o){this.error(t,`\u2717 ${e}`,n,o)}timing(t,e,n,o){this.info(t,`\u23F1 ${e}`,o,{duration:`${n}ms`})}},c=new T;import _ from"path";import{existsSync as d}from"fs";import{homedir as P}from"os";import{spawnSync as I}from"child_process";import{readFileSync as z,existsSync as Q}from"fs";import{join as Z}from"path";import{homedir as tt}from"os";var J=["bugfix","feature","refactor","discovery","decision","change"],q=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=J.join(","),N=q.join(",");var g=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:Z(tt(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:N,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!Q(t))return this.getAllDefaults();let e=z(t,"utf-8"),o=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};var f={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function U(r){return process.platform==="win32"?Math.round(r*f.WINDOWS_MULTIPLIER):r}var p=_.join(P(),".claude","plugins","marketplaces","thedotmack"),et=U(f.HEALTH_CHECK),rt=f.WORKER_STARTUP_WAIT,nt=f.WORKER_STARTUP_RETRIES;function S(){let r=_.join(P(),".claude-mem","settings.json"),t=g.loadFromFile(r);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function k(){try{let r=S();return(await fetch(`http://127.0.0.1:${r}/health`,{signal:AbortSignal.timeout(et)})).ok}catch(r){return c.debug("SYSTEM","Worker health check failed",{error:r instanceof Error?r.message:String(r),errorType:r?.constructor?.name}),!1}}async function ot(){try{let r=_.join(p,"plugin","scripts","worker-service.cjs");if(!d(r))throw new Error(`Worker script not found at ${r}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${r}' -WorkingDirectory '${p}' -WindowStyle Hidden`],{cwd:p,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=_.join(p,"ecosystem.config.cjs");if(!d(t))throw new Error(`Ecosystem config not found at ${t}`);let e=_.join(p,"node_modules",".bin","pm2"),n=d(e)?e:"pm2",o=I(n,["start",t],{cwd:p,stdio:"pipe",encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr||"PM2 start failed")}for(let t=0;t<nt;t++)if(await new Promise(e=>setTimeout(e,rt)),await k())return!0;return!1}catch(r){return c.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:_.join(p,"plugin","scripts","worker-service.cjs"),error:r instanceof Error?r.message:String(r),marketplaceRoot:p}),!1}}async function w(){if(await k())return;if(!await ot()){let t=S();throw new Error(`Worker service failed to start on port ${t}.
|
||||
import{stdin as x}from"process";import{readFileSync as H,existsSync as $}from"fs";function W(r,t,e){return r==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:r==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:r==="UserPromptSubmit"||r==="PostToolUse"?{continue:!0,suppressOutput:!0}:r==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function M(r,t,e={}){let n=W(r,t,e);return JSON.stringify(n)}import{join as X}from"path";import{homedir as B}from"os";import{existsSync as G,readFileSync as Y}from"fs";import{appendFileSync as F}from"fs";import{homedir as K}from"os";import{join as j}from"path";var V=j(K(),".claude-mem","silent.log");function g(r,t,e=""){let n=new Date().toISOString(),a=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),E=a?`${a[1].split("/").pop()}:${a[2]}`:"unknown",u=`[${n}] [HAPPY-PATH-ERROR] [${E}] ${r}`;if(t!==void 0)try{u+=` ${JSON.stringify(t)}`}catch(_){u+=` [stringify error: ${_}]`}u+=`
|
||||
`;try{F(V,u)}catch(_){console.error("[silent-debug] Failed to write to log:",_)}return e}var m=X(B(),".claude-mem","settings.json");function R(r,t){try{if(G(m)){let n=JSON.parse(Y(m,"utf-8")).env?.[r];if(n!==void 0)return n}}catch(e){g("Failed to load settings file",{error:e,settingsPath:m,key:r})}return process.env[r]||t}var T=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(T||{}),d=class{level;useColor;constructor(){let t=R("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=T[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let n=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&n.command){let o=n.command.length>50?n.command.substring(0,50)+"...":n.command;return`${t}(${o})`}if(t==="Read"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}if(t==="Edit"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}if(t==="Write"&&n.file_path){let o=n.file_path.split("/").pop()||n.file_path;return`${t}(${o})`}return t}catch{return t}}log(t,e,n,o,s){if(t<this.level)return;let i=new Date().toISOString().replace("T"," ").substring(0,23),a=T[t].padEnd(5),E=e.padEnd(6),u="";o?.correlationId?u=`[${o.correlationId}] `:o?.sessionId&&(u=`[session-${o.sessionId}] `);let _="";s!=null&&(this.level===0&&typeof s=="object"?_=`
|
||||
`+JSON.stringify(s,null,2):_=" "+this.formatData(s));let A="";if(o){let{sessionId:ct,sdkSessionId:pt,correlationId:ut,...L}=o;Object.keys(L).length>0&&(A=` {${Object.entries(L).map(([b,v])=>`${b}=${v}`).join(", ")}}`)}let h=`[${i}] [${a}] [${E}] ${u}${n}${A}${_}`;t===3?console.error(h):console.log(h)}debug(t,e,n,o){this.log(0,t,e,n,o)}info(t,e,n,o){this.log(1,t,e,n,o)}warn(t,e,n,o){this.log(2,t,e,n,o)}error(t,e,n,o){this.log(3,t,e,n,o)}dataIn(t,e,n,o){this.info(t,`\u2192 ${e}`,n,o)}dataOut(t,e,n,o){this.info(t,`\u2190 ${e}`,n,o)}success(t,e,n,o){this.info(t,`\u2713 ${e}`,n,o)}failure(t,e,n,o){this.error(t,`\u2717 ${e}`,n,o)}timing(t,e,n,o){this.info(t,`\u23F1 ${e}`,o,{duration:`${n}ms`})}},c=new d;import f from"path";import{existsSync as y}from"fs";import{homedir as P}from"os";import{spawnSync as I}from"child_process";import{readFileSync as z,existsSync as Q}from"fs";import{join as Z}from"path";import{homedir as tt}from"os";var J=["bugfix","feature","refactor","discovery","decision","change"],q=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=J.join(","),N=q.join(",");var S=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:Z(tt(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:N,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!Q(t))return this.getAllDefaults();let e=z(t,"utf-8"),o=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};var l={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function U(r){return process.platform==="win32"?Math.round(r*l.WINDOWS_MULTIPLIER):r}var p=f.join(P(),".claude","plugins","marketplaces","thedotmack"),et=U(l.HEALTH_CHECK),rt=l.WORKER_STARTUP_WAIT,nt=l.WORKER_STARTUP_RETRIES;function O(){let r=f.join(P(),".claude-mem","settings.json"),t=S.loadFromFile(r);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function k(){try{let r=O();return(await fetch(`http://127.0.0.1:${r}/health`,{signal:AbortSignal.timeout(et)})).ok}catch(r){return c.debug("SYSTEM","Worker health check failed",{error:r instanceof Error?r.message:String(r),errorType:r?.constructor?.name}),!1}}async function ot(){try{let r=f.join(p,"plugin","scripts","worker-service.cjs");if(!y(r))throw new Error(`Worker script not found at ${r}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${r}' -WorkingDirectory '${p}' -WindowStyle Hidden`],{cwd:p,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=f.join(p,"ecosystem.config.cjs");if(!y(t))throw new Error(`Ecosystem config not found at ${t}`);let e=f.join(p,"node_modules",".bin","pm2"),n=y(e)?e:"pm2",o=I(n,["start",t],{cwd:p,stdio:"pipe",encoding:"utf-8"});if(o.status!==0)throw new Error(o.stderr||"PM2 start failed")}for(let t=0;t<nt;t++)if(await new Promise(e=>setTimeout(e,rt)),await k())return!0;return!1}catch(r){return c.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:f.join(p,"plugin","scripts","worker-service.cjs"),error:r instanceof Error?r.message:String(r),marketplaceRoot:p}),!1}}async function w(){if(await k())return;if(!await ot()){let t=O();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${p}
|
||||
@@ -15,4 +15,4 @@ If already running, try: npx pm2 restart claude-mem-worker`)}}function st(r){if(
|
||||
`);for(let n=e.length-1;n>=0;n--)try{let o=JSON.parse(e[n]);if(o.type==="assistant"&&o.message?.content){let s="",i=o.message.content;return typeof i=="string"?s=i:Array.isArray(i)&&(s=i.filter(E=>E.type==="text").map(E=>E.text).join(`
|
||||
`)),s=s.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g,""),s=s.replace(/\n{3,}/g,`
|
||||
|
||||
`).trim(),s}}catch{continue}}catch(t){c.error("HOOK","Failed to read transcript",{transcriptPath:r},t)}return""}async function at(r){if(await w(),!r)throw new Error("summaryHook requires input");let{session_id:t}=r,e=S(),n=st(r.transcript_path||""),o=it(r.transcript_path||"");c.dataIn("HOOK","Stop: Requesting summary",{workerPort:e,hasLastUserMessage:!!n,hasLastAssistantMessage:!!o});try{let s=await fetch(`http://127.0.0.1:${e}/api/sessions/summarize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,last_user_message:n,last_assistant_message:o}),signal:AbortSignal.timeout(f.DEFAULT)});if(!s.ok){let i=await s.text();throw c.failure("HOOK","Failed to generate summary",{status:s.status},i),new Error(`Failed to request summary from worker: ${s.status} ${i}`)}c.debug("HOOK","Summary request sent successfully")}catch(s){throw s.cause?.code==="ECONNREFUSED"||s.name==="TimeoutError"||s.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):s}finally{fetch(`http://127.0.0.1:${e}/api/processing`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({isProcessing:!1})}).catch(()=>{})}console.log(M("Stop",!0))}var C="";x.on("data",r=>C+=r);x.on("end",async()=>{let r=C?JSON.parse(C):void 0;await at(r)});
|
||||
`).trim(),s}}catch{continue}}catch(t){c.error("HOOK","Failed to read transcript",{transcriptPath:r},t)}return""}async function at(r){if(await w(),!r)throw new Error("summaryHook requires input");let{session_id:t}=r,e=O(),n=g("Missing transcript_path in Stop hook input",{session_id:t},r.transcript_path||""),o=st(n),s=it(n);c.dataIn("HOOK","Stop: Requesting summary",{workerPort:e,hasLastUserMessage:!!o,hasLastAssistantMessage:!!s});try{let i=await fetch(`http://127.0.0.1:${e}/api/sessions/summarize`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,last_user_message:o,last_assistant_message:s}),signal:AbortSignal.timeout(l.DEFAULT)});if(!i.ok){let a=await i.text();throw c.failure("HOOK","Failed to generate summary",{status:i.status},a),new Error(`Failed to request summary from worker: ${i.status} ${a}`)}c.debug("HOOK","Summary request sent successfully")}catch(i){throw i.cause?.code==="ECONNREFUSED"||i.name==="TimeoutError"||i.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):i}finally{fetch(`http://127.0.0.1:${e}/api/processing`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({isProcessing:!1})}).catch(()=>{})}console.log(M("Stop",!0))}var C="";x.on("data",r=>C+=r);x.on("end",async()=>{let r=C?JSON.parse(C):void 0;await at(r)});
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env node
|
||||
import{basename as rt}from"path";import p from"path";import{existsSync as h}from"fs";import{homedir as w}from"os";import{spawnSync as I}from"child_process";import{readFileSync as H,existsSync as F}from"fs";import{join as j}from"path";import{homedir as V}from"os";var b=["bugfix","feature","refactor","discovery","decision","change"],x=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var D=b.join(","),y=x.join(",");var S=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_DATA_DIR:j(V(),".claude-mem"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"true",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES:D,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:y,CLAUDE_MEM_CONTEXT_FULL_COUNT:"5",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false"};static getAllDefaults(){return{...this.DEFAULTS}}static get(t){return process.env[t]||this.DEFAULTS[t]}static getInt(t){let e=this.get(t);return parseInt(e,10)}static getBool(t){return this.get(t)==="true"}static loadFromFile(t){if(!F(t))return this.getAllDefaults();let e=H(t,"utf-8"),r=JSON.parse(e).env||{},s={...this.DEFAULTS};for(let E of Object.keys(this.DEFAULTS))r[E]!==void 0&&(s[E]=r[E]);return s}};import{join as Y}from"path";import{homedir as J}from"os";import{existsSync as q,readFileSync as Z}from"fs";import{appendFileSync as K}from"fs";import{homedir as X}from"os";import{join as B}from"path";var G=B(X(),".claude-mem","silent.log");function R(o,t,e=""){let n=new Date().toISOString(),_=((new Error().stack||"").split(`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),l=_?`${_[1].split("/").pop()}:${_[2]}`:"unknown",i=`[${n}] [${l}] ${o}`;if(t!==void 0)try{i+=` ${JSON.stringify(t)}`}catch(a){i+=` [stringify error: ${a}]`}i+=`
|
||||
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),l=_?`${_[1].split("/").pop()}:${_[2]}`:"unknown",i=`[${n}] [HAPPY-PATH-ERROR] [${l}] ${o}`;if(t!==void 0)try{i+=` ${JSON.stringify(t)}`}catch(a){i+=` [stringify error: ${a}]`}i+=`
|
||||
`;try{K(G,i)}catch(a){console.error("[silent-debug] Failed to write to log:",a)}return e}var O=Y(J(),".claude-mem","settings.json");function U(o,t){try{if(q(O)){let n=JSON.parse(Z(O,"utf-8")).env?.[o];if(n!==void 0)return n}}catch(e){R("Failed to load settings file",{error:e,settingsPath:O,key:o})}return process.env[o]||t}var C=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s[s.SILENT=4]="SILENT",s))(C||{}),d=class{level;useColor;constructor(){let t=U("CLAUDE_MEM_LOG_LEVEL","INFO").toUpperCase();this.level=C[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message}
|
||||
${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let n=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&n.command){let r=n.command.length>50?n.command.substring(0,50)+"...":n.command;return`${t}(${r})`}if(t==="Read"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Edit"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}if(t==="Write"&&n.file_path){let r=n.file_path.split("/").pop()||n.file_path;return`${t}(${r})`}return t}catch{return t}}log(t,e,n,r,s){if(t<this.level)return;let E=new Date().toISOString().replace("T"," ").substring(0,23),_=C[t].padEnd(5),l=e.padEnd(6),i="";r?.correlationId?i=`[${r.correlationId}] `:r?.sessionId&&(i=`[session-${r.sessionId}] `);let a="";s!=null&&(this.level===0&&typeof s=="object"?a=`
|
||||
`+JSON.stringify(s,null,2):a=" "+this.formatData(s));let u="";if(r){let{sessionId:L,sdkSessionId:$,correlationId:M,...f}=r;Object.keys(f).length>0&&(u=` {${Object.entries(f).map(([k,W])=>`${k}=${W}`).join(", ")}}`)}let T=`[${E}] [${_}] [${l}] ${i}${n}${u}${a}`;t===3?console.error(T):console.log(T)}debug(t,e,n,r){this.log(0,t,e,n,r)}info(t,e,n,r){this.log(1,t,e,n,r)}warn(t,e,n,r){this.log(2,t,e,n,r)}error(t,e,n,r){this.log(3,t,e,n,r)}dataIn(t,e,n,r){this.info(t,`\u2192 ${e}`,n,r)}dataOut(t,e,n,r){this.info(t,`\u2190 ${e}`,n,r)}success(t,e,n,r){this.info(t,`\u2713 ${e}`,n,r)}failure(t,e,n,r){this.error(t,`\u2717 ${e}`,n,r)}timing(t,e,n,r){this.info(t,`\u23F1 ${e}`,r,{duration:`${n}ms`})}},A=new d;var g={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*g.WINDOWS_MULTIPLIER):o}var c=p.join(w(),".claude","plugins","marketplaces","thedotmack"),z=N(g.HEALTH_CHECK),Q=g.WORKER_STARTUP_WAIT,tt=g.WORKER_STARTUP_RETRIES;function m(){let o=p.join(w(),".claude-mem","settings.json"),t=S.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let o=m();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return A.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function et(){try{let o=p.join(c,"plugin","scripts","worker-service.cjs");if(!h(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${c}' -WindowStyle Hidden`],{cwd:c,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=p.join(c,"ecosystem.config.cjs");if(!h(t))throw new Error(`Ecosystem config not found at ${t}`);let e=p.join(c,"node_modules",".bin","pm2"),n=h(e)?e:"pm2",r=I(n,["start",t],{cwd:c,stdio:"pipe",encoding:"utf-8"});if(r.status!==0)throw new Error(r.stderr||"PM2 start failed")}for(let t=0;t<tt;t++)if(await new Promise(e=>setTimeout(e,Q)),await P())return!0;return!1}catch(o){return A.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:p.join(c,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:c}),!1}}async function v(){if(await P())return;if(!await et()){let t=m();throw new Error(`Worker service failed to start on port ${t}.
|
||||
`+JSON.stringify(s,null,2):a=" "+this.formatData(s));let u="";if(r){let{sessionId:L,sdkSessionId:v,correlationId:M,...g}=r;Object.keys(g).length>0&&(u=` {${Object.entries(g).map(([$,W])=>`${$}=${W}`).join(", ")}}`)}let T=`[${E}] [${_}] [${l}] ${i}${n}${u}${a}`;t===3?console.error(T):console.log(T)}debug(t,e,n,r){this.log(0,t,e,n,r)}info(t,e,n,r){this.log(1,t,e,n,r)}warn(t,e,n,r){this.log(2,t,e,n,r)}error(t,e,n,r){this.log(3,t,e,n,r)}dataIn(t,e,n,r){this.info(t,`\u2192 ${e}`,n,r)}dataOut(t,e,n,r){this.info(t,`\u2190 ${e}`,n,r)}success(t,e,n,r){this.info(t,`\u2713 ${e}`,n,r)}failure(t,e,n,r){this.error(t,`\u2717 ${e}`,n,r)}timing(t,e,n,r){this.info(t,`\u23F1 ${e}`,r,{duration:`${n}ms`})}},A=new d;var f={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(o){return process.platform==="win32"?Math.round(o*f.WINDOWS_MULTIPLIER):o}var c=p.join(w(),".claude","plugins","marketplaces","thedotmack"),z=N(f.HEALTH_CHECK),Q=f.WORKER_STARTUP_WAIT,tt=f.WORKER_STARTUP_RETRIES;function m(){let o=p.join(w(),".claude-mem","settings.json"),t=S.loadFromFile(o);return parseInt(t.CLAUDE_MEM_WORKER_PORT,10)}async function P(){try{let o=m();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(z)})).ok}catch(o){return A.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}async function et(){try{let o=p.join(c,"plugin","scripts","worker-service.cjs");if(!h(o))throw new Error(`Worker script not found at ${o}`);if(process.platform==="win32"){let t=I("powershell.exe",["-NoProfile","-NonInteractive","-Command",`Start-Process -FilePath 'node' -ArgumentList '${o}' -WorkingDirectory '${c}' -WindowStyle Hidden`],{cwd:c,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(t.status!==0)throw new Error(t.stderr||"PowerShell Start-Process failed")}else{let t=p.join(c,"ecosystem.config.cjs");if(!h(t))throw new Error(`Ecosystem config not found at ${t}`);let e=p.join(c,"node_modules",".bin","pm2"),n=h(e)?e:"pm2",r=I(n,["start",t],{cwd:c,stdio:"pipe",encoding:"utf-8"});if(r.status!==0)throw new Error(r.stderr||"PM2 start failed")}for(let t=0;t<tt;t++)if(await new Promise(e=>setTimeout(e,Q)),await P())return!0;return!1}catch(o){return A.error("SYSTEM","Failed to start worker",{platform:process.platform,workerScript:p.join(c,"plugin","scripts","worker-service.cjs"),error:o instanceof Error?o.message:String(o),marketplaceRoot:c}),!1}}async function k(){if(await P())return;if(!await et()){let t=m();throw new Error(`Worker service failed to start on port ${t}.
|
||||
|
||||
To start manually, run:
|
||||
cd ${c}
|
||||
npx pm2 start ecosystem.config.cjs
|
||||
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}try{await v();let o=m(),t=rt(process.cwd()),e=await fetch(`http://127.0.0.1:${o}/api/context/inject?project=${encodeURIComponent(t)}&colors=true`,{method:"GET",signal:AbortSignal.timeout(5e3)});if(!e.ok)throw new Error(`Worker error ${e.status}`);let n=await e.text(),r=new Date,s=new Date("2025-12-06T00:00:00Z"),E=new Date("2025-12-05T05:00:00Z"),_="";r<E&&(_=`
|
||||
If already running, try: npx pm2 restart claude-mem-worker`)}}try{await k();let o=m(),t=rt(process.cwd()),e=await fetch(`http://127.0.0.1:${o}/api/context/inject?project=${encodeURIComponent(t)}&colors=true`,{method:"GET",signal:AbortSignal.timeout(5e3)});if(!e.ok)throw new Error(`Worker error ${e.status}`);let n=await e.text(),r=new Date,s=new Date("2025-12-06T00:00:00Z"),E=new Date("2025-12-05T05:00:00Z"),_="";r<E&&(_=`
|
||||
|
||||
\u{1F680} \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501 \u{1F680}
|
||||
|
||||
@@ -19,7 +19,7 @@ If already running, try: npx pm2 restart claude-mem-worker`)}}try{await v();let
|
||||
\u2B50 Your upvote means the world - thank you!
|
||||
|
||||
\u{1F680} \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501 \u{1F680}
|
||||
`);let l="";if(r<s){let a=r.getUTCHours()*60+r.getUTCMinutes(),u=Math.floor((a-300+1440)%1440/60),T=r.getUTCDate(),L=r.getUTCMonth(),M=r.getUTCFullYear()===2025&&L===11&&T>=1&&T<=5,f=u>=17&&u<19;M&&f?l=`
|
||||
`);let l="";if(r<s){let a=r.getUTCHours()*60+r.getUTCMinutes(),u=Math.floor((a-300+1440)%1440/60),T=r.getUTCDate(),L=r.getUTCMonth(),M=r.getUTCFullYear()===2025&&L===11&&T>=1&&T<=5,g=u>=17&&u<19;M&&g?l=`
|
||||
\u{1F534} LIVE NOW: AMA w/ Dev (@thedotmack) until 7pm EST
|
||||
`:l=`
|
||||
\u2013 LIVE AMA w/ Dev (@thedotmack) Dec 1st\u20135th, 5pm to 7pm EST
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user