diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c2cd938f..488825bc 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "plugins": [ { "name": "claude-mem", - "version": "7.2.2", + "version": "7.2.3", "source": "./plugin", "description": "Persistent memory system for Claude Code - context compression across sessions" } diff --git a/package.json b/package.json index 6b94bc43..7462bd3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "claude-mem", - "version": "7.2.2", + "version": "7.2.3", "description": "Memory compression system for Claude Code - persist context across sessions", "keywords": [ "claude", diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index 628aa01c..43076789 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "claude-mem", - "version": "7.2.2", + "version": "7.2.3", "description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions", "author": { "name": "Alex Newman" diff --git a/plugin/package.json b/plugin/package.json index 6a2c3135..d8c1e6aa 100644 --- a/plugin/package.json +++ b/plugin/package.json @@ -1,6 +1,6 @@ { "name": "claude-mem-plugin", - "version": "7.2.2", + "version": "7.2.3", "private": true, "description": "Runtime dependencies for claude-mem bundled hooks", "type": "module", diff --git a/plugin/scripts/cleanup-hook.js b/plugin/scripts/cleanup-hook.js index 460d46cb..002077b1 100755 --- a/plugin/scripts/cleanup-hook.js +++ b/plugin/scripts/cleanup-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import{stdin as y}from"process";import C from"path";import{homedir as Ot}from"os";import{spawnSync as ht}from"child_process";import{existsSync as Ct,writeFileSync as K,readFileSync as At,mkdirSync as Mt}from"fs";import{readFileSync as z,writeFileSync as Z,existsSync as tt}from"fs";import{join as et}from"path";import{homedir as rt}from"os";var q=["bugfix","feature","refactor","discovery","decision","change"],Q=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var k=q.join(","),v=Q.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:et(rt(),".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:k,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:v,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 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(!tt(t))return this.getAllDefaults();let e=z(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{Z(t,JSON.stringify(n,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(s[i]=n[i]);return s}};var A=(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))(A||{}),M=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=A[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),f=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${s}:${i}:${c}.${f}`}log(t,e,r,n,s){if(t0&&(h=` {${Object.entries(w).map(([X,J])=>`${X}=${J}`).join(", ")}}`)}let P=`[${i}] [${c}] [${f}] ${g}${r}${h}${a}`;t===3?console.error(P):console.log(P)}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`})}happyPathError(t,e,r,n,s=""){let g=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=g?`${g[1].split("/").pop()}:${g[2]}`:"unknown",h={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,h,n),s}},u=new M;var d={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function U(o){return process.platform==="win32"?Math.round(o*d.WINDOWS_MULTIPLIER):o}import{existsSync as I,readFileSync as ut,writeFileSync as lt,unlinkSync as pt,mkdirSync as W}from"fs";import{createWriteStream as Et}from"fs";import{join as T}from"path";import{spawn as ft}from"child_process";import{homedir as gt}from"os";import{join as p,dirname as nt,basename as Bt}from"path";import{homedir as ot}from"os";import{fileURLToPath as st}from"url";function it(){return typeof __dirname<"u"?__dirname:nt(st(import.meta.url))}var Xt=it(),E=l.get("CLAUDE_MEM_DATA_DIR"),D=process.env.CLAUDE_CONFIG_DIR||p(ot(),".claude"),Jt=p(E,"archives"),qt=p(E,"logs"),Qt=p(E,"trash"),zt=p(E,"backups"),Zt=p(E,"settings.json"),te=p(E,"claude-mem.db"),ee=p(E,"vector-db"),re=p(D,"settings.json"),ne=p(D,"commands"),oe=p(D,"CLAUDE.md");import{spawnSync as at}from"child_process";import{existsSync as ct}from"fs";import{join as N}from"path";import{homedir as x}from"os";function L(){let o=process.platform==="win32";try{if(at("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:o}).status===0)return"bun"}catch{}let t=o?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(ct(e))return e;return null}function $(){return L()!==null}var S=T(E,"worker.pid"),H=T(E,"logs"),F=T(gt(),".claude","plugins","marketplaces","thedotmack"),mt=5e3,_t=1e4,dt=200,St=1e3,Tt=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=T(F,"plugin","scripts","worker-service.cjs");if(!I(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let n=L();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=ft(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),c=Et(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=mt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!I(S))return null;let t=ut(S,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(E,{recursive:!0}),lt(S,JSON.stringify(t,null,2))}static removePidFile(){try{I(S)&&pt(S)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=_t){let n=Date.now();for(;Date.now()-nsetTimeout(s,dt))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,Tt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return T(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math.floor(n/1e3),i=Math.floor(s/60),c=Math.floor(i/60),f=Math.floor(c/24);return f>0?`${f}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function R(o={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:n}=o,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",f=r||"Worker service connection failed.",g=t?` (port ${t})`:"",a=`${f}${g} +import{stdin as w}from"process";import A from"path";import{homedir as Ot}from"os";import{spawnSync as ht}from"child_process";import{existsSync as At,writeFileSync as K,readFileSync as Ct,mkdirSync as Mt}from"fs";import{readFileSync as z,writeFileSync as Z,existsSync as tt}from"fs";import{join as et}from"path";import{homedir as rt}from"os";var q=["bugfix","feature","refactor","discovery","decision","change"],Q=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var v=q.join(","),U=Q.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:et(rt(),".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:v,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 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(!tt(t))return this.getAllDefaults();let e=z(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{Z(t,JSON.stringify(n,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(s[i]=n[i]);return s}};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||{}),M=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=C[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),f=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${s}:${i}:${c}.${f}`}log(t,e,r,n,s){if(t0&&(h=` {${Object.entries(k).map(([X,J])=>`${X}=${J}`).join(", ")}}`)}let y=`[${i}] [${c}] [${f}] ${g}${r}${h}${a}`;t===3?console.error(y):console.log(y)}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`})}happyPathError(t,e,r,n,s=""){let g=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=g?`${g[1].split("/").pop()}:${g[2]}`:"unknown",h={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,h,n),s}},u=new M;var _={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function D(o){return process.platform==="win32"?Math.round(o*_.WINDOWS_MULTIPLIER):o}import{existsSync as I,readFileSync as ut,writeFileSync as lt,unlinkSync as pt,mkdirSync as W}from"fs";import{createWriteStream as Et}from"fs";import{join as T}from"path";import{spawn as ft}from"child_process";import{homedir as gt}from"os";import{join as p,dirname as nt,basename as Bt}from"path";import{homedir as ot}from"os";import{fileURLToPath as st}from"url";function it(){return typeof __dirname<"u"?__dirname:nt(st(import.meta.url))}var Xt=it(),E=l.get("CLAUDE_MEM_DATA_DIR"),L=process.env.CLAUDE_CONFIG_DIR||p(ot(),".claude"),Jt=p(E,"archives"),qt=p(E,"logs"),Qt=p(E,"trash"),zt=p(E,"backups"),Zt=p(E,"settings.json"),te=p(E,"claude-mem.db"),ee=p(E,"vector-db"),re=p(L,"settings.json"),ne=p(L,"commands"),oe=p(L,"CLAUDE.md");import{spawnSync as at}from"child_process";import{existsSync as ct}from"fs";import{join as N}from"path";import{homedir as x}from"os";function R(){let o=process.platform==="win32";try{if(at("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:o}).status===0)return"bun"}catch{}let t=o?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(ct(e))return e;return null}function $(){return R()!==null}var d=T(E,"worker.pid"),H=T(E,"logs"),F=T(gt(),".claude","plugins","marketplaces","thedotmack"),mt=5e3,_t=1e4,St=200,dt=1e3,Tt=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=T(F,"plugin","scripts","worker-service.cjs");if(!I(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let n=R();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=ft(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),c=Et(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=mt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!I(d))return null;let t=ut(d,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(E,{recursive:!0}),lt(d,JSON.stringify(t,null,2))}static removePidFile(){try{I(d)&&pt(d)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=_t){let n=Date.now();for(;Date.now()-nsetTimeout(s,St))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,Tt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return T(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math.floor(n/1e3),i=Math.floor(s/60),c=Math.floor(i/60),f=Math.floor(c/24);return f>0?`${f}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function P(o={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:n}=o,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",f=r||"Worker service connection failed.",g=t?` (port ${t})`:"",a=`${f}${g} `;return a+=`To restart the worker: `,a+=`1. Exit Claude Code completely @@ -13,4 +13,4 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje If that doesn't work, try: /troubleshoot`),n&&(a=`Worker Error: ${n} -${a}`),a}var V=C.join(Ot(),".claude","plugins","marketplaces","thedotmack"),j=U(d.HEALTH_CHECK),_=null;function m(){if(_!==null)return _;try{let o=C.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(o);return _=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),_}catch(o){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:o}),_=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),_}}async function b(){try{let o=m();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(j)})).ok}catch(o){return u.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}function Dt(){try{let o=C.join(V,"package.json");return JSON.parse(At(o,"utf-8")).version}catch(o){return u.debug("SYSTEM","Failed to read plugin version",{error:o instanceof Error?o.message:String(o)}),null}}async function Lt(){try{let o=m(),t=await fetch(`http://127.0.0.1:${o}/api/version`,{signal:AbortSignal.timeout(j)});return t.ok?(await t.json()).version:null}catch(o){return u.debug("SYSTEM","Failed to get worker version",{error:o instanceof Error?o.message:String(o)}),null}}async function B(){let o=Dt(),t=await Lt();!o||!t||o!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:o,workerVersion:t}),await O.restart(m()),await new Promise(e=>setTimeout(e,1e3)),await b()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:o,runningVersion:t,port}))}async function It(){let o=l.get("CLAUDE_MEM_DATA_DIR"),t=C.join(o,".pm2-migrated");if(Mt(o,{recursive:!0}),!Ct(t))try{ht("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=m(),r=await O.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:V}),r.success}async function G(){if(await b()){await B();return}if(!await It()){let e=m();throw new Error(R({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await b()){await B();return}let t=m();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(R({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}async function Y(o){if(await G(),!o)throw new Error("cleanup-hook requires input from Claude Code");let{session_id:t,reason:e}=o,r=m();try{(await fetch(`http://127.0.0.1:${r}/api/sessions/complete`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,reason:e}),signal:AbortSignal.timeout(d.DEFAULT)})).ok||console.error("[cleanup-hook] Session not found or already cleaned up")}catch{}console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}if(y.isTTY)Y(void 0);else{let o="";y.on("data",t=>o+=t),y.on("end",async()=>{let t=o?JSON.parse(o):void 0;await Y(t)})} +${a}`),a}var V=A.join(Ot(),".claude","plugins","marketplaces","thedotmack"),j=D(_.HEALTH_CHECK),S=null;function m(){if(S!==null)return S;try{let o=A.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(o);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}catch(o){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:o}),S=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),S}}async function b(){try{let o=m();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(j)})).ok}catch(o){return u.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}function Dt(){try{let o=A.join(V,"package.json");return JSON.parse(Ct(o,"utf-8")).version}catch(o){return u.debug("SYSTEM","Failed to read plugin version",{error:o instanceof Error?o.message:String(o)}),null}}async function Lt(){try{let o=m(),t=await fetch(`http://127.0.0.1:${o}/api/version`,{signal:AbortSignal.timeout(j)});return t.ok?(await t.json()).version:null}catch(o){return u.debug("SYSTEM","Failed to get worker version",{error:o instanceof Error?o.message:String(o)}),null}}async function B(){let o=Dt(),t=await Lt();!o||!t||o!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:o,workerVersion:t}),await new Promise(e=>setTimeout(e,D(_.PRE_RESTART_SETTLE_DELAY))),await O.restart(m()),await new Promise(e=>setTimeout(e,1e3)),await b()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:o,runningVersion:t,port:m()}))}async function Rt(){let o=l.get("CLAUDE_MEM_DATA_DIR"),t=A.join(o,".pm2-migrated");if(Mt(o,{recursive:!0}),!At(t))try{ht("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=m(),r=await O.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:V}),r.success}async function Y(){if(await b()){await B();return}if(!await Rt()){let e=m();throw new Error(P({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await b()){await B();return}let t=m();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(P({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}async function G(o){if(await Y(),!o)throw new Error("cleanup-hook requires input from Claude Code");let{session_id:t,reason:e}=o,r=m();try{(await fetch(`http://127.0.0.1:${r}/api/sessions/complete`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,reason:e}),signal:AbortSignal.timeout(_.DEFAULT)})).ok||console.error("[cleanup-hook] Session not found or already cleaned up")}catch{}console.log('{"continue": true, "suppressOutput": true}'),process.exit(0)}if(w.isTTY)G(void 0);else{let o="";w.on("data",t=>o+=t),w.on("end",async()=>{let t=o?JSON.parse(o):void 0;await G(t)})} diff --git a/plugin/scripts/context-hook.js b/plugin/scripts/context-hook.js index 8b9a4a25..17a09aaf 100755 --- a/plugin/scripts/context-hook.js +++ b/plugin/scripts/context-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import bt from"path";import{stdin as b}from"process";import A from"path";import{homedir as Ct}from"os";import{spawnSync as At}from"child_process";import{existsSync as Mt,writeFileSync as K,readFileSync as Dt,mkdirSync as Lt}from"fs";import{readFileSync as tt,writeFileSync as et,existsSync as rt}from"fs";import{join as nt}from"path";import{homedir as ot}from"os";var z=["bugfix","feature","refactor","discovery","decision","change"],Z=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var k=z.join(","),v=Z.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:nt(ot(),".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:k,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:v,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 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(!rt(t))return this.getAllDefaults();let e=tt(t,"utf-8"),r=JSON.parse(e),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{et(t,JSON.stringify(o,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),a=String(t.getSeconds()).padStart(2,"0"),g=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${o} ${s}:${i}:${a}.${g}`}log(t,e,r,o,s){if(t0&&(C=` {${Object.entries(P).map(([q,Q])=>`${q}=${Q}`).join(", ")}}`)}let y=`[${i}] [${a}] [${g}] ${m}${r}${C}${c}`;t===3?console.error(y):console.log(y)}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`})}happyPathError(t,e,r,o,s=""){let m=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),c=m?`${m[1].split("/").pop()}:${m[2]}`:"unknown",C={...r,location:c};return this.warn(t,`[HAPPY-PATH] ${e}`,C,o),s}},u=new D;var S={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*S.WINDOWS_MULTIPLIER):n}import{existsSync as I,readFileSync as pt,writeFileSync as ft,unlinkSync as gt,mkdirSync as W}from"fs";import{createWriteStream as mt}from"fs";import{join as h}from"path";import{spawn as Et}from"child_process";import{homedir as _t}from"os";import{join as p,dirname as st,basename as Yt}from"path";import{homedir as it}from"os";import{fileURLToPath as at}from"url";function ct(){return typeof __dirname<"u"?__dirname:st(at(import.meta.url))}var zt=ct(),f=l.get("CLAUDE_MEM_DATA_DIR"),L=process.env.CLAUDE_CONFIG_DIR||p(it(),".claude"),Zt=p(f,"archives"),te=p(f,"logs"),ee=p(f,"trash"),re=p(f,"backups"),ne=p(f,"settings.json"),oe=p(f,"claude-mem.db"),se=p(f,"vector-db"),ie=p(L,"settings.json"),ae=p(L,"commands"),ce=p(L,"CLAUDE.md");import{spawnSync as ut}from"child_process";import{existsSync as lt}from"fs";import{join as N}from"path";import{homedir as x}from"os";function R(){let n=process.platform==="win32";try{if(ut("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:n}).status===0)return"bun"}catch{}let t=n?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(lt(e))return e;return null}function $(){return R()!==null}var T=h(f,"worker.pid"),H=h(f,"logs"),F=h(_t(),".claude","plugins","marketplaces","thedotmack"),dt=5e3,St=1e4,Tt=200,ht=1e3,Ot=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=h(F,"plugin","scripts","worker-service.cjs");if(!I(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let o=R();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=Et(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),a=mt(e,{flags:"a"});return i.stdout?.pipe(a),i.stderr?.pipe(a),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=dt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!I(T))return null;let t=pt(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(f,{recursive:!0}),ft(T,JSON.stringify(t,null,2))}static removePidFile(){try{I(T)&>(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=St){let o=Date.now();for(;Date.now()-osetTimeout(s,Tt))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(o,Ot))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),a=Math.floor(i/60),g=Math.floor(a/24);return g>0?`${g}d ${a%24}h`:a>0?`${a}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function E(n={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:o}=n,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",a=s?"Command Prompt or PowerShell":"Terminal",g=r||"Worker service connection failed.",m=t?` (port ${t})`:"",c=`${g}${m} +import bt from"path";import{stdin as P}from"process";import A from"path";import{homedir as Ct}from"os";import{spawnSync as At}from"child_process";import{existsSync as Mt,writeFileSync as K,readFileSync as Dt,mkdirSync as Lt}from"fs";import{readFileSync as tt,writeFileSync as et,existsSync as rt}from"fs";import{join as nt}from"path";import{homedir as ot}from"os";var z=["bugfix","feature","refactor","discovery","decision","change"],Z=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var v=z.join(","),U=Z.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:nt(ot(),".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:v,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 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(!rt(t))return this.getAllDefaults();let e=tt(t,"utf-8"),r=JSON.parse(e),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{et(t,JSON.stringify(o,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),a=String(t.getSeconds()).padStart(2,"0"),f=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${o} ${s}:${i}:${a}.${f}`}log(t,e,r,o,s){if(t0&&(C=` {${Object.entries(k).map(([q,Q])=>`${q}=${Q}`).join(", ")}}`)}let y=`[${i}] [${a}] [${f}] ${m}${r}${C}${c}`;t===3?console.error(y):console.log(y)}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`})}happyPathError(t,e,r,o,s=""){let m=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),c=m?`${m[1].split("/").pop()}:${m[2]}`:"unknown",C={...r,location:c};return this.warn(t,`[HAPPY-PATH] ${e}`,C,o),s}},u=new D;var d={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function L(n){return process.platform==="win32"?Math.round(n*d.WINDOWS_MULTIPLIER):n}import{existsSync as I,readFileSync as pt,writeFileSync as Et,unlinkSync as ft,mkdirSync as W}from"fs";import{createWriteStream as mt}from"fs";import{join as h}from"path";import{spawn as gt}from"child_process";import{homedir as _t}from"os";import{join as p,dirname as st,basename as Gt}from"path";import{homedir as it}from"os";import{fileURLToPath as at}from"url";function ct(){return typeof __dirname<"u"?__dirname:st(at(import.meta.url))}var zt=ct(),E=l.get("CLAUDE_MEM_DATA_DIR"),R=process.env.CLAUDE_CONFIG_DIR||p(it(),".claude"),Zt=p(E,"archives"),te=p(E,"logs"),ee=p(E,"trash"),re=p(E,"backups"),ne=p(E,"settings.json"),oe=p(E,"claude-mem.db"),se=p(E,"vector-db"),ie=p(R,"settings.json"),ae=p(R,"commands"),ce=p(R,"CLAUDE.md");import{spawnSync as ut}from"child_process";import{existsSync as lt}from"fs";import{join as N}from"path";import{homedir as x}from"os";function w(){let n=process.platform==="win32";try{if(ut("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:n}).status===0)return"bun"}catch{}let t=n?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(lt(e))return e;return null}function $(){return w()!==null}var T=h(E,"worker.pid"),H=h(E,"logs"),F=h(_t(),".claude","plugins","marketplaces","thedotmack"),dt=5e3,St=1e4,Tt=200,ht=1e3,Ot=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=h(F,"plugin","scripts","worker-service.cjs");if(!I(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let o=w();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=gt(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),a=mt(e,{flags:"a"});return i.stdout?.pipe(a),i.stderr?.pipe(a),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=dt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!I(T))return null;let t=pt(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(E,{recursive:!0}),Et(T,JSON.stringify(t,null,2))}static removePidFile(){try{I(T)&&ft(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=St){let o=Date.now();for(;Date.now()-osetTimeout(s,Tt))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(o,Ot))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),a=Math.floor(i/60),f=Math.floor(a/24);return f>0?`${f}d ${a%24}h`:a>0?`${a}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function _(n={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:o}=n,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",a=s?"Command Prompt or PowerShell":"Terminal",f=r||"Worker service connection failed.",m=t?` (port ${t})`:"",c=`${f}${m} `;return c+=`To restart the worker: `,c+=`1. Exit Claude Code completely @@ -13,4 +13,4 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje If that doesn't work, try: /troubleshoot`),o&&(c=`Worker Error: ${o} -${c}`),c}var j=A.join(Ct(),".claude","plugins","marketplaces","thedotmack"),V=U(S.HEALTH_CHECK),d=null;function _(){if(d!==null)return d;try{let n=A.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(n);return d=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),d}catch(n){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:n}),d=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),d}}async function w(){try{let n=_();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(V)})).ok}catch(n){return u.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}function Rt(){try{let n=A.join(j,"package.json");return JSON.parse(Dt(n,"utf-8")).version}catch(n){return u.debug("SYSTEM","Failed to read plugin version",{error:n instanceof Error?n.message:String(n)}),null}}async function It(){try{let n=_(),t=await fetch(`http://127.0.0.1:${n}/api/version`,{signal:AbortSignal.timeout(V)});return t.ok?(await t.json()).version:null}catch(n){return u.debug("SYSTEM","Failed to get worker version",{error:n instanceof Error?n.message:String(n)}),null}}async function B(){let n=Rt(),t=await It();!n||!t||n!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:n,workerVersion:t}),await O.restart(_()),await new Promise(e=>setTimeout(e,1e3)),await w()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:n,runningVersion:t,port}))}async function wt(){let n=l.get("CLAUDE_MEM_DATA_DIR"),t=A.join(n,".pm2-migrated");if(Lt(n,{recursive:!0}),!Mt(t))try{At("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=_(),r=await O.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:j}),r.success}async function G(){if(await w()){await B();return}if(!await wt()){let e=_();throw new Error(E({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await w()){await B();return}let t=_();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(E({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function Y(n){throw n.cause?.code==="ECONNREFUSED"||n.code==="ConnectionRefused"||n.name==="TimeoutError"||n.message?.includes("fetch failed")||n.message?.includes("Unable to connect")?new Error(E()):n}function X(n,t,e){u.error("HOOK",`${e.operation} failed`,{status:n.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${E()}`:`${e.operation} failed: ${E()}`;throw new Error(r)}async function J(n){await G();let t=n?.cwd??process.cwd(),e=t?bt.basename(t):"unknown-project",r=_(),o=`http://127.0.0.1:${r}/api/context/inject?project=${encodeURIComponent(e)}`;try{let s=await fetch(o,{signal:AbortSignal.timeout(S.DEFAULT)});if(!s.ok){let a=await s.text();X(s,a,{hookName:"context",operation:"Context generation",project:e,port:r})}return(await s.text()).trim()}catch(s){Y(s)}}var yt=process.argv.includes("--colors");if(b.isTTY||yt)J(void 0).then(n=>{console.log(n),process.exit(0)});else{let n="";b.on("data",t=>n+=t),b.on("end",async()=>{let t=n.trim()?JSON.parse(n):void 0,e=await J(t);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e}})),process.exit(0)})} +${c}`),c}var j=A.join(Ct(),".claude","plugins","marketplaces","thedotmack"),V=L(d.HEALTH_CHECK),S=null;function g(){if(S!==null)return S;try{let n=A.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(n);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}catch(n){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:n}),S=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),S}}async function b(){try{let n=g();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(V)})).ok}catch(n){return u.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}function Rt(){try{let n=A.join(j,"package.json");return JSON.parse(Dt(n,"utf-8")).version}catch(n){return u.debug("SYSTEM","Failed to read plugin version",{error:n instanceof Error?n.message:String(n)}),null}}async function wt(){try{let n=g(),t=await fetch(`http://127.0.0.1:${n}/api/version`,{signal:AbortSignal.timeout(V)});return t.ok?(await t.json()).version:null}catch(n){return u.debug("SYSTEM","Failed to get worker version",{error:n instanceof Error?n.message:String(n)}),null}}async function B(){let n=Rt(),t=await wt();!n||!t||n!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:n,workerVersion:t}),await new Promise(e=>setTimeout(e,L(d.PRE_RESTART_SETTLE_DELAY))),await O.restart(g()),await new Promise(e=>setTimeout(e,1e3)),await b()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:n,runningVersion:t,port:g()}))}async function It(){let n=l.get("CLAUDE_MEM_DATA_DIR"),t=A.join(n,".pm2-migrated");if(Lt(n,{recursive:!0}),!Mt(t))try{At("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=g(),r=await O.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:j}),r.success}async function Y(){if(await b()){await B();return}if(!await It()){let e=g();throw new Error(_({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await b()){await B();return}let t=g();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(_({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function G(n){throw n.cause?.code==="ECONNREFUSED"||n.code==="ConnectionRefused"||n.name==="TimeoutError"||n.message?.includes("fetch failed")||n.message?.includes("Unable to connect")?new Error(_()):n}function X(n,t,e){u.error("HOOK",`${e.operation} failed`,{status:n.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${_()}`:`${e.operation} failed: ${_()}`;throw new Error(r)}async function J(n){await Y();let t=n?.cwd??process.cwd(),e=t?bt.basename(t):"unknown-project",r=g(),o=`http://127.0.0.1:${r}/api/context/inject?project=${encodeURIComponent(e)}`;try{let s=await fetch(o,{signal:AbortSignal.timeout(d.DEFAULT)});if(!s.ok){let a=await s.text();X(s,a,{hookName:"context",operation:"Context generation",project:e,port:r})}return(await s.text()).trim()}catch(s){G(s)}}var Pt=process.argv.includes("--colors");if(P.isTTY||Pt)J(void 0).then(n=>{console.log(n),process.exit(0)});else{let n="";P.on("data",t=>n+=t),P.on("end",async()=>{let t=n.trim()?JSON.parse(n):void 0,e=await J(t);console.log(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e}})),process.exit(0)})} diff --git a/plugin/scripts/mcp-server.cjs b/plugin/scripts/mcp-server.cjs index 4738c46c..e0ccd0b1 100755 --- a/plugin/scripts/mcp-server.cjs +++ b/plugin/scripts/mcp-server.cjs @@ -8,7 +8,7 @@ ]`;continue}r+=s[d],s[d]==="\\"?n=!0:l&&s[d]==="]"?l=!1:!l&&s[d]==="["&&(l=!0)}try{new RegExp(r)}catch{return console.warn(`Could not convert regex pattern at ${e.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`),a.source}return r}function Sa(a,e){if(e.target==="openAi"&&console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead."),e.target==="openApi3"&&a.keyType?._def.typeName===R.ZodEnum)return{type:"object",required:a.keyType._def.values,properties:a.keyType._def.values.reduce((s,r)=>({...s,[r]:B(a.valueType._def,{...e,currentPath:[...e.currentPath,"properties",r]})??fe(e)}),{}),additionalProperties:e.rejectedAdditionalProperties};let t={type:"object",additionalProperties:B(a.valueType._def,{...e,currentPath:[...e.currentPath,"additionalProperties"]})??e.allowedAdditionalProperties};if(e.target==="openApi3")return t;if(a.keyType?._def.typeName===R.ZodString&&a.keyType._def.checks?.length){let{type:s,...r}=ba(a.keyType._def,e);return{...t,propertyNames:r}}else{if(a.keyType?._def.typeName===R.ZodEnum)return{...t,propertyNames:{enum:a.keyType._def.values}};if(a.keyType?._def.typeName===R.ZodBranded&&a.keyType._def.type._def.typeName===R.ZodString&&a.keyType._def.type._def.checks?.length){let{type:s,...r}=Ea(a.keyType._def,e);return{...t,propertyNames:r}}}return t}function Mi(a,e){if(e.mapStrategy==="record")return Sa(a,e);let t=B(a.keyType._def,{...e,currentPath:[...e.currentPath,"items","items","0"]})||fe(e),s=B(a.valueType._def,{...e,currentPath:[...e.currentPath,"items","items","1"]})||fe(e);return{type:"array",maxItems:125,items:{type:"array",items:[t,s],minItems:2,maxItems:2}}}function Fi(a){let e=a.values,s=Object.keys(a.values).filter(n=>typeof e[e[n]]!="number").map(n=>e[n]),r=Array.from(new Set(s.map(n=>typeof n)));return{type:r.length===1?r[0]==="string"?"string":"number":["string","number"],enum:s}}function Ui(a){return a.target==="openAi"?void 0:{not:fe({...a,currentPath:[...a.currentPath,"not"]})}}function qi(a){return a.target==="openApi3"?{enum:["null"],nullable:!0}:{type:"null"}}var It={ZodString:"string",ZodNumber:"number",ZodBigInt:"integer",ZodBoolean:"boolean",ZodNull:"null"};function zi(a,e){if(e.target==="openApi3")return Vi(a,e);let t=a.options instanceof Map?Array.from(a.options.values()):a.options;if(t.every(s=>s._def.typeName in It&&(!s._def.checks||!s._def.checks.length))){let s=t.reduce((r,n)=>{let l=It[n._def.typeName];return l&&!r.includes(l)?[...r,l]:r},[]);return{type:s.length>1?s:s[0]}}else if(t.every(s=>s._def.typeName==="ZodLiteral"&&!s.description)){let s=t.reduce((r,n)=>{let l=typeof n._def.value;switch(l){case"string":case"number":case"boolean":return[...r,l];case"bigint":return[...r,"integer"];case"object":if(n._def.value===null)return[...r,"null"];case"symbol":case"undefined":case"function":default:return r}},[]);if(s.length===t.length){let r=s.filter((n,l,i)=>i.indexOf(n)===l);return{type:r.length>1?r:r[0],enum:t.reduce((n,l)=>n.includes(l._def.value)?n:[...n,l._def.value],[])}}}else if(t.every(s=>s._def.typeName==="ZodEnum"))return{type:"string",enum:t.reduce((s,r)=>[...s,...r._def.values.filter(n=>!s.includes(n))],[])};return Vi(a,e)}var Vi=(a,e)=>{let t=(a.options instanceof Map?Array.from(a.options.values()):a.options).map((s,r)=>B(s._def,{...e,currentPath:[...e.currentPath,"anyOf",`${r}`]})).filter(s=>!!s&&(!e.strictUnions||typeof s=="object"&&Object.keys(s).length>0));return t.length?{anyOf:t}:void 0};function Hi(a,e){if(["ZodString","ZodNumber","ZodBigInt","ZodBoolean","ZodNull"].includes(a.innerType._def.typeName)&&(!a.innerType._def.checks||!a.innerType._def.checks.length))return e.target==="openApi3"?{type:It[a.innerType._def.typeName],nullable:!0}:{type:[It[a.innerType._def.typeName],"null"]};if(e.target==="openApi3"){let s=B(a.innerType._def,{...e,currentPath:[...e.currentPath]});return s&&"$ref"in s?{allOf:[s],nullable:!0}:s&&{...s,nullable:!0}}let t=B(a.innerType._def,{...e,currentPath:[...e.currentPath,"anyOf","0"]});return t&&{anyOf:[t,{type:"null"}]}}function Zi(a,e){let t={type:"number"};if(!a.checks)return t;for(let s of a.checks)switch(s.kind){case"int":t.type="integer",_s(t,"type",s.message,e);break;case"min":e.target==="jsonSchema7"?s.inclusive?ee(t,"minimum",s.value,s.message,e):ee(t,"exclusiveMinimum",s.value,s.message,e):(s.inclusive||(t.exclusiveMinimum=!0),ee(t,"minimum",s.value,s.message,e));break;case"max":e.target==="jsonSchema7"?s.inclusive?ee(t,"maximum",s.value,s.message,e):ee(t,"exclusiveMaximum",s.value,s.message,e):(s.inclusive||(t.exclusiveMaximum=!0),ee(t,"maximum",s.value,s.message,e));break;case"multipleOf":ee(t,"multipleOf",s.value,s.message,e);break}return t}function Bi(a,e){let t=e.target==="openAi",s={type:"object",properties:{}},r=[],n=a.shape();for(let i in n){let d=n[i];if(d===void 0||d._def===void 0)continue;let f=If(d);f&&t&&(d._def.typeName==="ZodOptional"&&(d=d._def.innerType),d.isNullable()||(d=d.nullable()),f=!1);let h=B(d._def,{...e,currentPath:[...e.currentPath,"properties",i],propertyPath:[...e.currentPath,"properties",i]});h!==void 0&&(s.properties[i]=h,f||r.push(i))}r.length&&(s.required=r);let l=Df(a,e);return l!==void 0&&(s.additionalProperties=l),s}function Df(a,e){if(a.catchall._def.typeName!=="ZodNever")return B(a.catchall._def,{...e,currentPath:[...e.currentPath,"additionalProperties"]});switch(a.unknownKeys){case"passthrough":return e.allowedAdditionalProperties;case"strict":return e.rejectedAdditionalProperties;case"strip":return e.removeAdditionalStrategy==="strict"?e.allowedAdditionalProperties:e.rejectedAdditionalProperties}}function If(a){try{return a.isOptional()}catch{return!0}}var Wi=(a,e)=>{if(e.currentPath.toString()===e.propertyPath?.toString())return B(a.innerType._def,e);let t=B(a.innerType._def,{...e,currentPath:[...e.currentPath,"anyOf","1"]});return t?{anyOf:[{not:fe(e)},t]}:fe(e)};var Ki=(a,e)=>{if(e.pipeStrategy==="input")return B(a.in._def,e);if(e.pipeStrategy==="output")return B(a.out._def,e);let t=B(a.in._def,{...e,currentPath:[...e.currentPath,"allOf","0"]}),s=B(a.out._def,{...e,currentPath:[...e.currentPath,"allOf",t?"1":"0"]});return{allOf:[t,s].filter(r=>r!==void 0)}};function Qi(a,e){return B(a.type._def,e)}function Ji(a,e){let s={type:"array",uniqueItems:!0,items:B(a.valueType._def,{...e,currentPath:[...e.currentPath,"items"]})};return a.minSize&&ee(s,"minItems",a.minSize.value,a.minSize.message,e),a.maxSize&&ee(s,"maxItems",a.maxSize.value,a.maxSize.message,e),s}function Gi(a,e){return a.rest?{type:"array",minItems:a.items.length,items:a.items.map((t,s)=>B(t._def,{...e,currentPath:[...e.currentPath,"items",`${s}`]})).reduce((t,s)=>s===void 0?t:[...t,s],[]),additionalItems:B(a.rest._def,{...e,currentPath:[...e.currentPath,"additionalItems"]})}:{type:"array",minItems:a.items.length,maxItems:a.items.length,items:a.items.map((t,s)=>B(t._def,{...e,currentPath:[...e.currentPath,"items",`${s}`]})).reduce((t,s)=>s===void 0?t:[...t,s],[])}}function Yi(a){return{not:fe(a)}}function Xi(a){return fe(a)}var el=(a,e)=>B(a.innerType._def,e);var rl=(a,e,t)=>{switch(e){case R.ZodString:return ba(a,t);case R.ZodNumber:return Zi(a,t);case R.ZodObject:return Bi(a,t);case R.ZodBigInt:return Ai(a,t);case R.ZodBoolean:return Di();case R.ZodDate:return Es(a,t);case R.ZodUndefined:return Yi(t);case R.ZodNull:return qi(t);case R.ZodArray:return Oi(a,t);case R.ZodUnion:case R.ZodDiscriminatedUnion:return zi(a,t);case R.ZodIntersection:return Ni(a,t);case R.ZodTuple:return Gi(a,t);case R.ZodRecord:return Sa(a,t);case R.ZodLiteral:return ji(a,t);case R.ZodEnum:return Ci(a);case R.ZodNativeEnum:return Fi(a);case R.ZodNullable:return Hi(a,t);case R.ZodOptional:return Wi(a,t);case R.ZodMap:return Mi(a,t);case R.ZodSet:return Ji(a,t);case R.ZodLazy:return()=>a.getter()._def;case R.ZodPromise:return Qi(a,t);case R.ZodNaN:case R.ZodNever:return Ui(t);case R.ZodEffects:return $i(a,t);case R.ZodAny:return fe(t);case R.ZodUnknown:return Xi(t);case R.ZodDefault:return ki(a,t);case R.ZodBranded:return Ea(a,t);case R.ZodReadonly:return el(a,t);case R.ZodCatch:return Ii(a,t);case R.ZodPipeline:return Ki(a,t);case R.ZodFunction:case R.ZodVoid:case R.ZodSymbol:return;default:return(s=>{})(e)}};function B(a,e,t=!1){let s=e.seen.get(a);if(e.override){let i=e.override?.(a,e,s,t);if(i!==wi)return i}if(s&&!t){let i=kf(s,e);if(i!==void 0)return i}let r={def:a,path:e.currentPath,jsonSchema:void 0};e.seen.set(a,r);let n=rl(a,a.typeName,e),l=typeof n=="function"?B(n(),e):n;if(l&&$f(a,e,l),e.postProcess){let i=e.postProcess(l,a,e);return r.jsonSchema=l,i}return r.jsonSchema=l,l}var kf=(a,e)=>{switch(e.$refStrategy){case"root":return{$ref:a.path.join("/")};case"relative":return{$ref:_a(e.currentPath,a.path)};case"none":case"seen":return a.path.lengthe.currentPath[s]===t)?(console.warn(`Recursive reference detected at ${e.currentPath.join("/")}! Defaulting to any`),fe(e)):e.$refStrategy==="seen"?fe(e):void 0}},$f=(a,e,t)=>(a.description&&(t.description=a.description,e.markdownDescription&&(t.markdownDescription=a.description)),t);var Ps=(a,e)=>{let t=Ri(e),s=typeof e=="object"&&e.definitions?Object.entries(e.definitions).reduce((d,[f,h])=>({...d,[f]:B(h._def,{...t,currentPath:[...t.basePath,t.definitionPath,f]},!0)??fe(t)}),{}):void 0,r=typeof e=="string"?e:e?.nameStrategy==="title"?void 0:e?.name,n=B(a._def,r===void 0?t:{...t,currentPath:[...t.basePath,t.definitionPath,r]},!1)??fe(t),l=typeof e=="object"&&e.name!==void 0&&e.nameStrategy==="title"?e.name:void 0;l!==void 0&&(n.title=l),t.flags.hasReferencedOpenAiAnyType&&(s||(s={}),s[t.openAiAnyTypeName]||(s[t.openAiAnyTypeName]={type:["string","number","integer","boolean","array","null"],items:{$ref:t.$refStrategy==="relative"?"1":[...t.basePath,t.definitionPath,t.openAiAnyTypeName].join("/")}}));let i=r===void 0?s?{...n,[t.definitionPath]:s}:n:{$ref:[...t.$refStrategy==="relative"?[]:t.basePath,t.definitionPath,r].join("/"),[t.definitionPath]:{...s,[r]:n}};return t.target==="jsonSchema7"?i.$schema="http://json-schema.org/draft-07/schema#":(t.target==="jsonSchema2019-09"||t.target==="openAi")&&(i.$schema="https://json-schema.org/draft/2019-09/schema#"),t.target==="openAi"&&("anyOf"in i||"oneOf"in i||"allOf"in i||"type"in i&&Array.isArray(i.type))&&console.warn("Warning: OpenAI may not support schemas with unions as roots! Try wrapping it in an object property."),i};var ht=require("fs"),sl=require("path"),nl=require("os");var Cf=["bugfix","feature","refactor","discovery","decision","change"],Nf=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var tl=Cf.join(","),al=Nf.join(",");var rr=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:(0,sl.join)((0,nl.homedir)(),".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:tl,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:al,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(e){return this.DEFAULTS[e]}static getInt(e){let t=this.get(e);return parseInt(t,10)}static getBool(e){return this.get(e)==="true"}static loadFromFile(e){if(!(0,ht.existsSync)(e))return this.getAllDefaults();let t=(0,ht.readFileSync)(e,"utf-8"),s=JSON.parse(t),r=s;if(s.env&&typeof s.env=="object"){r=s.env;try{(0,ht.writeFileSync)(e,JSON.stringify(r,null,2),"utf-8"),ye.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:e})}catch(l){ye.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:e},l)}}let n={...this.DEFAULTS};for(let l of Object.keys(this.DEFAULTS))r[l]!==void 0&&(n[l]=r[l]);return n}};var xs=(n=>(n[n.DEBUG=0]="DEBUG",n[n.INFO=1]="INFO",n[n.WARN=2]="WARN",n[n.ERROR=3]="ERROR",n[n.SILENT=4]="SILENT",n))(xs||{}),ws=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let e=rr.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=xs[e]??1}return this.level}correlationId(e,t){return`obs-${e}-${t}`}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.getLevel()===0?`${e.message} ${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let t=Object.keys(e);return t.length===0?"{}":t.length<=3?JSON.stringify(e):`{${t.length} keys: ${t.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,t){if(!t)return e;try{let s=typeof t=="string"?JSON.parse(t):t;if(e==="Bash"&&s.command){let r=s.command.length>50?s.command.substring(0,50)+"...":s.command;return`${e}(${r})`}if(e==="Read"&&s.file_path){let r=s.file_path.split("/").pop()||s.file_path;return`${e}(${r})`}if(e==="Edit"&&s.file_path){let r=s.file_path.split("/").pop()||s.file_path;return`${e}(${r})`}if(e==="Write"&&s.file_path){let r=s.file_path.split("/").pop()||s.file_path;return`${e}(${r})`}return e}catch{return e}}formatTimestamp(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0"),n=String(e.getHours()).padStart(2,"0"),l=String(e.getMinutes()).padStart(2,"0"),i=String(e.getSeconds()).padStart(2,"0"),d=String(e.getMilliseconds()).padStart(3,"0");return`${t}-${s}-${r} ${n}:${l}:${i}.${d}`}log(e,t,s,r,n){if(e0&&(m=` {${Object.entries(v).map(([O,x])=>`${O}=${x}`).join(", ")}}`)}let E=`[${l}] [${i}] [${d}] ${f}${s}${m}${h}`;e===3?console.error(E):console.log(E)}debug(e,t,s,r){this.log(0,e,t,s,r)}info(e,t,s,r){this.log(1,e,t,s,r)}warn(e,t,s,r){this.log(2,e,t,s,r)}error(e,t,s,r){this.log(3,e,t,s,r)}dataIn(e,t,s,r){this.info(e,`\u2192 ${t}`,s,r)}dataOut(e,t,s,r){this.info(e,`\u2190 ${t}`,s,r)}success(e,t,s,r){this.info(e,`\u2713 ${t}`,s,r)}failure(e,t,s,r){this.error(e,`\u2717 ${t}`,s,r)}timing(e,t,s,r){this.info(e,`\u23F1 ${t}`,r,{duration:`${s}ms`})}happyPathError(e,t,s,r,n=""){let f=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),h=f?`${f[1].split("/").pop()}:${f[2]}`:"unknown",m={...s,location:h};return this.warn(e,`[HAPPY-PATH] ${t}`,m,r),n}},ye=new ws;var xa=Da(require("path"),1),Os=require("os");var Ts={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function ol(a){return process.platform==="win32"?Math.round(a*Ts.WINDOWS_MULTIPLIER):a}var Pa=require("path");var cl=require("os");var $e=require("path"),il=require("os");var ll=require("url");var Lf={};function jf(){return typeof __dirname<"u"?__dirname:(0,$e.dirname)((0,ll.fileURLToPath)(Lf.url))}var $g=jf(),cr=rr.get("CLAUDE_MEM_DATA_DIR"),Rs=process.env.CLAUDE_CONFIG_DIR||(0,$e.join)((0,il.homedir)(),".claude"),Cg=(0,$e.join)(cr,"archives"),Ng=(0,$e.join)(cr,"logs"),jg=(0,$e.join)(cr,"trash"),Lg=(0,$e.join)(cr,"backups"),Mg=(0,$e.join)(cr,"settings.json"),Fg=(0,$e.join)(cr,"claude-mem.db"),Ug=(0,$e.join)(cr,"vector-db"),qg=(0,$e.join)(Rs,"settings.json"),Vg=(0,$e.join)(Rs,"commands"),zg=(0,$e.join)(Rs,"CLAUDE.md");var Jg=(0,Pa.join)(cr,"worker.pid"),Gg=(0,Pa.join)(cr,"logs"),Yg=(0,Pa.join)((0,cl.homedir)(),".claude","plugins","marketplaces","thedotmack");var ly=xa.default.join((0,Os.homedir)(),".claude","plugins","marketplaces","thedotmack"),cy=ol(Ts.HEALTH_CHECK),pt=null;function ul(){if(pt!==null)return pt;try{let a=xa.default.join(rr.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=rr.loadFromFile(a);return pt=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),pt}catch(a){return ye.debug("SYSTEM","Failed to load port from settings, using default",{error:a}),pt=parseInt(rr.get("CLAUDE_MEM_WORKER_PORT"),10),pt}}function dl(){let a=xa.default.join((0,Os.homedir)(),".claude-mem","settings.json");return rr.loadFromFile(a).CLAUDE_MEM_WORKER_HOST}var Mf=ul(),Ff=dl(),mt=`http://${Ff}:${Mf}`,kt={search:"/api/search",timeline:"/api/timeline",get_recent_context:"/api/context/recent",get_context_timeline:"/api/context/timeline",progressive_description:"/api/instructions"};async function $t(a,e){ye.debug("SYSTEM","\u2192 Worker API",void 0,{endpoint:a,params:e});try{let t=new URLSearchParams;for(let[l,i]of Object.entries(e))i!=null&&t.append(l,String(i));let s=`${mt}${a}?${t}`,r=await fetch(s);if(!r.ok){let l=await r.text();throw new Error(`Worker API error (${r.status}): ${l}`)}let n=await r.json();return ye.debug("SYSTEM","\u2190 Worker API success",void 0,{endpoint:a}),n}catch(t){return ye.error("SYSTEM","\u2190 Worker API error",void 0,{endpoint:a,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function As(a,e){ye.debug("HTTP","Worker API request (path)",void 0,{endpoint:a,id:e});try{let t=`${mt}${a}/${e}`,s=await fetch(t);if(!s.ok){let n=await s.text();throw new Error(`Worker API error (${s.status}): ${n}`)}let r=await s.json();return ye.debug("HTTP","Worker API success (path)",void 0,{endpoint:a,id:e}),{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}catch(t){return ye.error("HTTP","Worker API error (path)",void 0,{endpoint:a,id:e,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function Uf(a,e){ye.debug("HTTP","Worker API request (POST)",void 0,{endpoint:a});try{let t=`${mt}${a}`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let n=await s.text();throw new Error(`Worker API error (${s.status}): ${n}`)}let r=await s.json();return ye.debug("HTTP","Worker API success (POST)",void 0,{endpoint:a}),{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}catch(t){return ye.error("HTTP","Worker API error (POST)",void 0,{endpoint:a,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function qf(){try{return(await fetch(`${mt}/api/health`)).ok}catch{return!1}}var fl=[{name:"search",description:"Search memory",inputSchema:o.object({query:o.string().optional(),type:o.enum(["observations","sessions","prompts"]).optional(),obs_type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional(),dateStart:o.union([o.string(),o.number()]).optional(),dateEnd:o.union([o.string(),o.number()]).optional(),limit:o.number().min(1).max(100).default(20),offset:o.number().min(0).default(0),orderBy:o.enum(["relevance","date_desc","date_asc"]).default("date_desc")}),handler:async a=>{let e=kt.search;return await $t(e,a)}},{name:"timeline",description:"Timeline context",inputSchema:o.object({query:o.string().optional(),anchor:o.number().optional(),depth_before:o.number().min(0).max(100).default(10),depth_after:o.number().min(0).max(100).default(10),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional()}),handler:async a=>{let e=kt.timeline;return await $t(e,a)}},{name:"get_recent_context",description:"Recent context",inputSchema:o.object({limit:o.number().min(1).max(100).default(30),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional(),dateStart:o.union([o.string(),o.number()]).optional(),dateEnd:o.union([o.string(),o.number()]).optional()}),handler:async a=>{let e=kt.get_recent_context;return await $t(e,a)}},{name:"get_context_timeline",description:"Timeline around ID",inputSchema:o.object({anchor:o.number(),depth_before:o.number().min(0).max(100).default(10),depth_after:o.number().min(0).max(100).default(10),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional()}),handler:async a=>{let e=kt.get_context_timeline;return await $t(e,a)}},{name:"progressive_description",description:"Usage help",inputSchema:o.object({topic:o.enum(["workflow","search_params","examples","all"]).default("all")}),handler:async a=>{let e=kt.progressive_description;return await $t(e,a)}},{name:"get_observation",description:"Fetch by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/observation",a.id)},{name:"get_batch_observations",description:"Batch fetch",inputSchema:o.object({ids:o.array(o.number()),orderBy:o.enum(["date_desc","date_asc"]).optional(),limit:o.number().optional(),project:o.string().optional()}),handler:async a=>await Uf("/api/observations/batch",a)},{name:"get_session",description:"Session by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/session",a.id)},{name:"get_prompt",description:"Prompt by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/prompt",a.id)}],Ds=new va({name:"claude-mem-search-server",version:"1.0.0"},{capabilities:{tools:{}}});Ds.setRequestHandler(Va,async()=>({tools:fl.map(a=>({name:a.name,description:a.description,inputSchema:Ps(a.inputSchema)}))}));Ds.setRequestHandler(za,async a=>{let e=fl.find(t=>t.name===a.params.name);if(!e)throw new Error(`Unknown tool: ${a.params.name}`);try{return await e.handler(a.params.arguments||{})}catch(t){return{content:[{type:"text",text:`Tool execution failed: ${t.message}`}],isError:!0}}});async function hl(){ye.info("SYSTEM","MCP server shutting down"),process.exit(0)}process.on("SIGTERM",hl);process.on("SIGINT",hl);async function Vf(){let a=new ya;await Ds.connect(a),ye.info("SYSTEM","Claude-mem search server started"),setTimeout(async()=>{await qf()?ye.info("SYSTEM","Worker available",void 0,{workerUrl:mt}):(ye.warn("SYSTEM","Worker not available",void 0,{workerUrl:mt}),ye.warn("SYSTEM","Tools will fail until Worker is started"),ye.warn("SYSTEM","Start Worker with: npm run worker:restart"))},0)}Vf().catch(a=>{ye.error("SYSTEM","Fatal error",void 0,a),process.exit(1)}); +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),h=f?`${f[1].split("/").pop()}:${f[2]}`:"unknown",m={...s,location:h};return this.warn(e,`[HAPPY-PATH] ${t}`,m,r),n}},ye=new ws;var xa=Da(require("path"),1),Os=require("os");var Ts={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function ol(a){return process.platform==="win32"?Math.round(a*Ts.WINDOWS_MULTIPLIER):a}var Pa=require("path");var cl=require("os");var $e=require("path"),il=require("os");var ll=require("url");var Lf={};function jf(){return typeof __dirname<"u"?__dirname:(0,$e.dirname)((0,ll.fileURLToPath)(Lf.url))}var $g=jf(),cr=rr.get("CLAUDE_MEM_DATA_DIR"),Rs=process.env.CLAUDE_CONFIG_DIR||(0,$e.join)((0,il.homedir)(),".claude"),Cg=(0,$e.join)(cr,"archives"),Ng=(0,$e.join)(cr,"logs"),jg=(0,$e.join)(cr,"trash"),Lg=(0,$e.join)(cr,"backups"),Mg=(0,$e.join)(cr,"settings.json"),Fg=(0,$e.join)(cr,"claude-mem.db"),Ug=(0,$e.join)(cr,"vector-db"),qg=(0,$e.join)(Rs,"settings.json"),Vg=(0,$e.join)(Rs,"commands"),zg=(0,$e.join)(Rs,"CLAUDE.md");var Jg=(0,Pa.join)(cr,"worker.pid"),Gg=(0,Pa.join)(cr,"logs"),Yg=(0,Pa.join)((0,cl.homedir)(),".claude","plugins","marketplaces","thedotmack");var ly=xa.default.join((0,Os.homedir)(),".claude","plugins","marketplaces","thedotmack"),cy=ol(Ts.HEALTH_CHECK),pt=null;function ul(){if(pt!==null)return pt;try{let a=xa.default.join(rr.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=rr.loadFromFile(a);return pt=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),pt}catch(a){return ye.debug("SYSTEM","Failed to load port from settings, using default",{error:a}),pt=parseInt(rr.get("CLAUDE_MEM_WORKER_PORT"),10),pt}}function dl(){let a=xa.default.join((0,Os.homedir)(),".claude-mem","settings.json");return rr.loadFromFile(a).CLAUDE_MEM_WORKER_HOST}var Mf=ul(),Ff=dl(),mt=`http://${Ff}:${Mf}`,kt={search:"/api/search",timeline:"/api/timeline",get_recent_context:"/api/context/recent",get_context_timeline:"/api/context/timeline",progressive_description:"/api/instructions"};async function $t(a,e){ye.debug("SYSTEM","\u2192 Worker API",void 0,{endpoint:a,params:e});try{let t=new URLSearchParams;for(let[l,i]of Object.entries(e))i!=null&&t.append(l,String(i));let s=`${mt}${a}?${t}`,r=await fetch(s);if(!r.ok){let l=await r.text();throw new Error(`Worker API error (${r.status}): ${l}`)}let n=await r.json();return ye.debug("SYSTEM","\u2190 Worker API success",void 0,{endpoint:a}),n}catch(t){return ye.error("SYSTEM","\u2190 Worker API error",void 0,{endpoint:a,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function As(a,e){ye.debug("HTTP","Worker API request (path)",void 0,{endpoint:a,id:e});try{let t=`${mt}${a}/${e}`,s=await fetch(t);if(!s.ok){let n=await s.text();throw new Error(`Worker API error (${s.status}): ${n}`)}let r=await s.json();return ye.debug("HTTP","Worker API success (path)",void 0,{endpoint:a,id:e}),{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}catch(t){return ye.error("HTTP","Worker API error (path)",void 0,{endpoint:a,id:e,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function Uf(a,e){ye.debug("HTTP","Worker API request (POST)",void 0,{endpoint:a});try{let t=`${mt}${a}`,s=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!s.ok){let n=await s.text();throw new Error(`Worker API error (${s.status}): ${n}`)}let r=await s.json();return ye.debug("HTTP","Worker API success (POST)",void 0,{endpoint:a}),{content:[{type:"text",text:JSON.stringify(r,null,2)}]}}catch(t){return ye.error("HTTP","Worker API error (POST)",void 0,{endpoint:a,error:t.message}),{content:[{type:"text",text:`Error calling Worker API: ${t.message}`}],isError:!0}}}async function qf(){try{return(await fetch(`${mt}/api/health`)).ok}catch{return!1}}var fl=[{name:"search",description:"Search memory",inputSchema:o.object({query:o.string().optional(),type:o.enum(["observations","sessions","prompts"]).optional(),obs_type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional(),dateStart:o.union([o.string(),o.number()]).optional(),dateEnd:o.union([o.string(),o.number()]).optional(),limit:o.number().min(1).max(100).default(20),offset:o.number().min(0).default(0),orderBy:o.enum(["relevance","date_desc","date_asc"]).default("date_desc")}),handler:async a=>{let e=kt.search;return await $t(e,a)}},{name:"timeline",description:"Timeline context",inputSchema:o.object({query:o.string().optional(),anchor:o.number().optional(),depth_before:o.number().min(0).max(100).default(10),depth_after:o.number().min(0).max(100).default(10),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional()}),handler:async a=>{let e=kt.timeline;return await $t(e,a)}},{name:"get_recent_context",description:"Recent context",inputSchema:o.object({limit:o.number().min(1).max(100).default(30),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional(),dateStart:o.union([o.string(),o.number()]).optional(),dateEnd:o.union([o.string(),o.number()]).optional()}),handler:async a=>{let e=kt.get_recent_context;return await $t(e,a)}},{name:"get_context_timeline",description:"Timeline around ID",inputSchema:o.object({anchor:o.number(),depth_before:o.number().min(0).max(100).default(10),depth_after:o.number().min(0).max(100).default(10),type:o.string().optional(),concepts:o.string().optional(),files:o.string().optional(),project:o.string().optional()}),handler:async a=>{let e=kt.get_context_timeline;return await $t(e,a)}},{name:"progressive_description",description:"Usage help",inputSchema:o.object({topic:o.enum(["workflow","search_params","examples","all"]).default("all")}),handler:async a=>{let e=kt.progressive_description;return await $t(e,a)}},{name:"get_observation",description:"Fetch by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/observation",a.id)},{name:"get_batch_observations",description:"Batch fetch",inputSchema:o.object({ids:o.array(o.number()),orderBy:o.enum(["date_desc","date_asc"]).optional(),limit:o.number().optional(),project:o.string().optional()}),handler:async a=>await Uf("/api/observations/batch",a)},{name:"get_session",description:"Session by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/session",a.id)},{name:"get_prompt",description:"Prompt by ID",inputSchema:o.object({id:o.number()}),handler:async a=>await As("/api/prompt",a.id)}],Ds=new va({name:"claude-mem-search-server",version:"1.0.0"},{capabilities:{tools:{}}});Ds.setRequestHandler(Va,async()=>({tools:fl.map(a=>({name:a.name,description:a.description,inputSchema:Ps(a.inputSchema)}))}));Ds.setRequestHandler(za,async a=>{let e=fl.find(t=>t.name===a.params.name);if(!e)throw new Error(`Unknown tool: ${a.params.name}`);try{return await e.handler(a.params.arguments||{})}catch(t){return{content:[{type:"text",text:`Tool execution failed: ${t.message}`}],isError:!0}}});async function hl(){ye.info("SYSTEM","MCP server shutting down"),process.exit(0)}process.on("SIGTERM",hl);process.on("SIGINT",hl);async function Vf(){let a=new ya;await Ds.connect(a),ye.info("SYSTEM","Claude-mem search server started"),setTimeout(async()=>{await qf()?ye.info("SYSTEM","Worker available",void 0,{workerUrl:mt}):(ye.warn("SYSTEM","Worker not available",void 0,{workerUrl:mt}),ye.warn("SYSTEM","Tools will fail until Worker is started"),ye.warn("SYSTEM","Start Worker with: npm run worker:restart"))},0)}Vf().catch(a=>{ye.error("SYSTEM","Fatal error",void 0,a),process.exit(1)}); /*! Bundled license information: uri-js/dist/es5/uri.all.js: diff --git a/plugin/scripts/new-hook.js b/plugin/scripts/new-hook.js index c81e9dbd..5f8c0ab9 100755 --- a/plugin/scripts/new-hook.js +++ b/plugin/scripts/new-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import Pt from"path";import{stdin as q}from"process";function Z(n,t,e){return 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 A(n,t,e={}){let r=Z(n,t,e);return JSON.stringify(r)}import C from"path";import{homedir as Mt}from"os";import{spawnSync as Dt}from"child_process";import{existsSync as Lt,writeFileSync as V,readFileSync as bt,mkdirSync as Rt}from"fs";import{readFileSync as rt,writeFileSync as nt,existsSync as ot}from"fs";import{join as st}from"path";import{homedir as it}from"os";var tt=["bugfix","feature","refactor","discovery","decision","change"],et=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var N=tt.join(","),x=et.join(",");var m=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:st(it(),".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:N,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:x,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 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(!ot(t))return this.getAllDefaults();let e=rt(t,"utf-8"),r=JSON.parse(e),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{nt(t,JSON.stringify(o,null,2),"utf-8"),p.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){p.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=m.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),u=String(t.getSeconds()).padStart(2,"0"),l=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${o} ${s}:${i}:${u}.${l}`}log(t,e,r,o,s){if(t0&&(S=` {${Object.entries(U).map(([z,Q])=>`${z}=${Q}`).join(", ")}}`)}let v=`[${i}] [${u}] [${l}] ${c}${r}${S}${a}`;t===3?console.error(v):console.log(v)}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`})}happyPathError(t,e,r,o,s=""){let c=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=c?`${c[1].split("/").pop()}:${c[2]}`:"unknown",S={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,S,o),s}},p=new D;var L={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function $(n){return process.platform==="win32"?Math.round(n*L.WINDOWS_MULTIPLIER):n}import{existsSync as w,readFileSync as ft,writeFileSync as gt,unlinkSync as Et,mkdirSync as K}from"fs";import{createWriteStream as dt}from"fs";import{join as h}from"path";import{spawn as St}from"child_process";import{homedir as _t}from"os";import{join as f,dirname as at,basename as qt}from"path";import{homedir as ct}from"os";import{fileURLToPath as ut}from"url";function pt(){return typeof __dirname<"u"?__dirname:at(ut(import.meta.url))}var ee=pt(),g=m.get("CLAUDE_MEM_DATA_DIR"),b=process.env.CLAUDE_CONFIG_DIR||f(ct(),".claude"),re=f(g,"archives"),ne=f(g,"logs"),oe=f(g,"trash"),se=f(g,"backups"),ie=f(g,"settings.json"),ae=f(g,"claude-mem.db"),ce=f(g,"vector-db"),ue=f(b,"settings.json"),pe=f(b,"commands"),le=f(b,"CLAUDE.md");import{spawnSync as lt}from"child_process";import{existsSync as mt}from"fs";import{join as H}from"path";import{homedir as W}from"os";function R(){let n=process.platform==="win32";try{if(lt("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:n}).status===0)return"bun"}catch{}let t=n?[H(W(),".bun","bin","bun.exe")]:[H(W(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(mt(e))return e;return null}function F(){return R()!==null}var T=h(g,"worker.pid"),B=h(g,"logs"),j=h(_t(),".claude","plugins","marketplaces","thedotmack"),Tt=5e3,ht=1e4,Ot=200,Ct=1e3,At=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};K(B,{recursive:!0});let e=h(j,"plugin","scripts","worker-service.cjs");if(!w(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return F()}static async startWithBun(t,e,r){let o=R();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=St(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:j,...s&&{windowsHide:!0}}),u=dt(e,{flags:"a"});return i.stdout?.pipe(u),i.stderr?.pipe(u),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=Tt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!w(T))return null;let t=ft(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){K(g,{recursive:!0}),gt(T,JSON.stringify(t,null,2))}static removePidFile(){try{w(T)&&Et(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ht){let o=Date.now();for(;Date.now()-osetTimeout(s,Ot))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(o,At))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(B,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),u=Math.floor(i/60),l=Math.floor(u/24);return l>0?`${l}d ${u%24}h`:u>0?`${u}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function E(n={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:o}=n,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",u=s?"Command Prompt or PowerShell":"Terminal",l=r||"Worker service connection failed.",c=t?` (port ${t})`:"",a=`${l}${c} +import It from"path";import{stdin as q}from"process";function Z(n,t,e){return 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=Z(n,t,e);return JSON.stringify(r)}import A from"path";import{homedir as Mt}from"os";import{spawnSync as Dt}from"child_process";import{existsSync as Rt,writeFileSync as V,readFileSync as Lt,mkdirSync as bt}from"fs";import{readFileSync as rt,writeFileSync as nt,existsSync as ot}from"fs";import{join as st}from"path";import{homedir as it}from"os";var tt=["bugfix","feature","refactor","discovery","decision","change"],et=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var x=tt.join(","),$=et.join(",");var m=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:st(it(),".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:x,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:$,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 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(!ot(t))return this.getAllDefaults();let e=rt(t,"utf-8"),r=JSON.parse(e),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{nt(t,JSON.stringify(o,null,2),"utf-8"),p.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){p.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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||{}),R=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=m.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=D[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),u=String(t.getSeconds()).padStart(2,"0"),l=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${o} ${s}:${i}:${u}.${l}`}log(t,e,r,o,s){if(t0&&(_=` {${Object.entries(N).map(([z,Q])=>`${z}=${Q}`).join(", ")}}`)}let U=`[${i}] [${u}] [${l}] ${c}${r}${_}${a}`;t===3?console.error(U):console.log(U)}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`})}happyPathError(t,e,r,o,s=""){let c=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=c?`${c[1].split("/").pop()}:${c[2]}`:"unknown",_={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,_,o),s}},p=new R;var C={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function L(n){return process.platform==="win32"?Math.round(n*C.WINDOWS_MULTIPLIER):n}import{existsSync as P,readFileSync as ft,writeFileSync as gt,unlinkSync as Et,mkdirSync as K}from"fs";import{createWriteStream as St}from"fs";import{join as h}from"path";import{spawn as _t}from"child_process";import{homedir as dt}from"os";import{join as f,dirname as at,basename as qt}from"path";import{homedir as ct}from"os";import{fileURLToPath as ut}from"url";function pt(){return typeof __dirname<"u"?__dirname:at(ut(import.meta.url))}var ee=pt(),g=m.get("CLAUDE_MEM_DATA_DIR"),b=process.env.CLAUDE_CONFIG_DIR||f(ct(),".claude"),re=f(g,"archives"),ne=f(g,"logs"),oe=f(g,"trash"),se=f(g,"backups"),ie=f(g,"settings.json"),ae=f(g,"claude-mem.db"),ce=f(g,"vector-db"),ue=f(b,"settings.json"),pe=f(b,"commands"),le=f(b,"CLAUDE.md");import{spawnSync as lt}from"child_process";import{existsSync as mt}from"fs";import{join as H}from"path";import{homedir as W}from"os";function w(){let n=process.platform==="win32";try{if(lt("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:n}).status===0)return"bun"}catch{}let t=n?[H(W(),".bun","bin","bun.exe")]:[H(W(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(mt(e))return e;return null}function F(){return w()!==null}var T=h(g,"worker.pid"),B=h(g,"logs"),j=h(dt(),".claude","plugins","marketplaces","thedotmack"),Tt=5e3,ht=1e4,Ot=200,Ct=1e3,At=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};K(B,{recursive:!0});let e=h(j,"plugin","scripts","worker-service.cjs");if(!P(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return F()}static async startWithBun(t,e,r){let o=w();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=_t(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:j,...s&&{windowsHide:!0}}),u=St(e,{flags:"a"});return i.stdout?.pipe(u),i.stderr?.pipe(u),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=Tt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!P(T))return null;let t=ft(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){K(g,{recursive:!0}),gt(T,JSON.stringify(t,null,2))}static removePidFile(){try{P(T)&&Et(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ht){let o=Date.now();for(;Date.now()-osetTimeout(s,Ot))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(o,At))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(B,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),u=Math.floor(i/60),l=Math.floor(u/24);return l>0?`${l}d ${u%24}h`:u>0?`${u}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function S(n={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:o}=n,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",u=s?"Command Prompt or PowerShell":"Terminal",l=r||"Worker service connection failed.",c=t?` (port ${t})`:"",a=`${l}${c} `;return a+=`To restart the worker: `,a+=`1. Exit Claude Code completely @@ -13,4 +13,4 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje If that doesn't work, try: /troubleshoot`),o&&(a=`Worker Error: ${o} -${a}`),a}var X=C.join(Mt(),".claude","plugins","marketplaces","thedotmack"),Y=$(L.HEALTH_CHECK),_=null;function d(){if(_!==null)return _;try{let n=C.join(m.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=m.loadFromFile(n);return _=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),_}catch(n){return p.debug("SYSTEM","Failed to load port from settings, using default",{error:n}),_=parseInt(m.get("CLAUDE_MEM_WORKER_PORT"),10),_}}async function k(){try{let n=d();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(Y)})).ok}catch(n){return p.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}function wt(){try{let n=C.join(X,"package.json");return JSON.parse(bt(n,"utf-8")).version}catch(n){return p.debug("SYSTEM","Failed to read plugin version",{error:n instanceof Error?n.message:String(n)}),null}}async function kt(){try{let n=d(),t=await fetch(`http://127.0.0.1:${n}/api/version`,{signal:AbortSignal.timeout(Y)});return t.ok?(await t.json()).version:null}catch(n){return p.debug("SYSTEM","Failed to get worker version",{error:n instanceof Error?n.message:String(n)}),null}}async function G(){let n=wt(),t=await kt();!n||!t||n!==t&&(p.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:n,workerVersion:t}),await O.restart(d()),await new Promise(e=>setTimeout(e,1e3)),await k()||p.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:n,runningVersion:t,port}))}async function It(){let n=m.get("CLAUDE_MEM_DATA_DIR"),t=C.join(n,".pm2-migrated");if(Rt(n,{recursive:!0}),!Lt(t))try{Dt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),V(t,new Date().toISOString(),"utf-8"),p.debug("SYSTEM","PM2 cleanup completed and marked")}catch{V(t,new Date().toISOString(),"utf-8")}let e=d(),r=await O.start(e);return r.success||p.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:X}),r.success}async function J(){if(await k()){await G();return}if(!await It()){let e=d();throw new Error(E({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await k()){await G();return}let t=d();throw p.error("SYSTEM","Worker started but not responding to health checks"),new Error(E({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function I(n){throw n.cause?.code==="ECONNREFUSED"||n.code==="ConnectionRefused"||n.name==="TimeoutError"||n.message?.includes("fetch failed")||n.message?.includes("Unable to connect")?new Error(E()):n}function P(n,t,e){p.error("HOOK",`${e.operation} failed`,{status:n.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${E()}`:`${e.operation} failed: ${E()}`;throw new Error(r)}async function yt(n){if(await J(),!n)throw new Error("newHook requires input");let{session_id:t,cwd:e,prompt:r}=n,o=Pt.basename(e),s=d(),i,u;try{let c=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(!c.ok){let S=await c.text();P(c,S,{hookName:"new",operation:"Session initialization",project:o,port:s})}let a=await c.json();if(i=a.sessionDbId,u=a.promptNumber,a.skipped&&a.reason==="private"){console.error(`[new-hook] Session ${i}, prompt #${u} (fully private - skipped)`),console.log(A("UserPromptSubmit",!0));return}console.error(`[new-hook] Session ${i}, prompt #${u}`)}catch(c){I(c)}let l=r.startsWith("/")?r.substring(1):r;try{let c=await fetch(`http://127.0.0.1:${s}/sessions/${i}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:l,promptNumber:u}),signal:AbortSignal.timeout(5e3)});if(!c.ok){let a=await c.text();P(c,a,{hookName:"new",operation:"SDK agent start",project:o,port:s,sessionId:String(i)})}}catch(c){I(c)}console.log(A("UserPromptSubmit",!0))}var y="";q.on("data",n=>y+=n);q.on("end",async()=>{let n=y?JSON.parse(y):void 0;await yt(n)}); +${a}`),a}var Y=A.join(Mt(),".claude","plugins","marketplaces","thedotmack"),X=L(C.HEALTH_CHECK),d=null;function E(){if(d!==null)return d;try{let n=A.join(m.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=m.loadFromFile(n);return d=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),d}catch(n){return p.debug("SYSTEM","Failed to load port from settings, using default",{error:n}),d=parseInt(m.get("CLAUDE_MEM_WORKER_PORT"),10),d}}async function k(){try{let n=E();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(X)})).ok}catch(n){return p.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}function wt(){try{let n=A.join(Y,"package.json");return JSON.parse(Lt(n,"utf-8")).version}catch(n){return p.debug("SYSTEM","Failed to read plugin version",{error:n instanceof Error?n.message:String(n)}),null}}async function Pt(){try{let n=E(),t=await fetch(`http://127.0.0.1:${n}/api/version`,{signal:AbortSignal.timeout(X)});return t.ok?(await t.json()).version:null}catch(n){return p.debug("SYSTEM","Failed to get worker version",{error:n instanceof Error?n.message:String(n)}),null}}async function G(){let n=wt(),t=await Pt();!n||!t||n!==t&&(p.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:n,workerVersion:t}),await new Promise(e=>setTimeout(e,L(C.PRE_RESTART_SETTLE_DELAY))),await O.restart(E()),await new Promise(e=>setTimeout(e,1e3)),await k()||p.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:n,runningVersion:t,port:E()}))}async function kt(){let n=m.get("CLAUDE_MEM_DATA_DIR"),t=A.join(n,".pm2-migrated");if(bt(n,{recursive:!0}),!Rt(t))try{Dt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),V(t,new Date().toISOString(),"utf-8"),p.debug("SYSTEM","PM2 cleanup completed and marked")}catch{V(t,new Date().toISOString(),"utf-8")}let e=E(),r=await O.start(e);return r.success||p.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:Y}),r.success}async function J(){if(await k()){await G();return}if(!await kt()){let e=E();throw new Error(S({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await k()){await G();return}let t=E();throw p.error("SYSTEM","Worker started but not responding to health checks"),new Error(S({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function I(n){throw n.cause?.code==="ECONNREFUSED"||n.code==="ConnectionRefused"||n.name==="TimeoutError"||n.message?.includes("fetch failed")||n.message?.includes("Unable to connect")?new Error(S()):n}function y(n,t,e){p.error("HOOK",`${e.operation} failed`,{status:n.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${S()}`:`${e.operation} failed: ${S()}`;throw new Error(r)}async function yt(n){if(await J(),!n)throw new Error("newHook requires input");let{session_id:t,cwd:e,prompt:r}=n,o=It.basename(e),s=E(),i,u;try{let c=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(!c.ok){let _=await c.text();y(c,_,{hookName:"new",operation:"Session initialization",project:o,port:s})}let a=await c.json();if(i=a.sessionDbId,u=a.promptNumber,a.skipped&&a.reason==="private"){console.error(`[new-hook] Session ${i}, prompt #${u} (fully private - skipped)`),console.log(M("UserPromptSubmit",!0));return}console.error(`[new-hook] Session ${i}, prompt #${u}`)}catch(c){I(c)}let l=r.startsWith("/")?r.substring(1):r;try{let c=await fetch(`http://127.0.0.1:${s}/sessions/${i}/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({userPrompt:l,promptNumber:u}),signal:AbortSignal.timeout(5e3)});if(!c.ok){let a=await c.text();y(c,a,{hookName:"new",operation:"SDK agent start",project:o,port:s,sessionId:String(i)})}}catch(c){I(c)}console.log(M("UserPromptSubmit",!0))}var v="";q.on("data",n=>v+=n);q.on("end",async()=>{let n=v?JSON.parse(v):void 0;await yt(n)}); diff --git a/plugin/scripts/save-hook.js b/plugin/scripts/save-hook.js index 4366cd07..92604995 100755 --- a/plugin/scripts/save-hook.js +++ b/plugin/scripts/save-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import{stdin as q}from"process";function Z(n,t,e){return 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 y(n,t,e={}){let r=Z(n,t,e);return JSON.stringify(r)}import{readFileSync as rt,writeFileSync as nt,existsSync as ot}from"fs";import{join as st}from"path";import{homedir as it}from"os";var tt=["bugfix","feature","refactor","discovery","decision","change"],et=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var v=tt.join(","),U=et.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:st(it(),".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:v,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 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(!ot(t))return this.getAllDefaults();let e=rt(t,"utf-8"),r=JSON.parse(e),o=r;if(r.env&&typeof r.env=="object"){o=r.env;try{nt(t,JSON.stringify(o,null,2),"utf-8"),a.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){a.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=f.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),p=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${o} ${s}:${i}:${c}.${p}`}log(t,e,r,o,s){if(t0&&(C=` {${Object.entries(k).map(([Q,z])=>`${Q}=${z}`).join(", ")}}`)}let w=`[${i}] [${c}] [${p}] ${l}${r}${C}${u}`;t===3?console.error(w):console.log(w)}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`})}happyPathError(t,e,r,o,s=""){let l=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",C={...r,location:u};return this.warn(t,`[HAPPY-PATH] ${e}`,C,o),s}},a=new D;import A from"path";import{homedir as Mt}from"os";import{spawnSync as Dt}from"child_process";import{existsSync as Lt,writeFileSync as B,readFileSync as Rt,mkdirSync as bt}from"fs";var S={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(n){return process.platform==="win32"?Math.round(n*S.WINDOWS_MULTIPLIER):n}import{existsSync as b,readFileSync as mt,writeFileSync as gt,unlinkSync as Et,mkdirSync as W}from"fs";import{createWriteStream as _t}from"fs";import{join as O}from"path";import{spawn as dt}from"child_process";import{homedir as St}from"os";import{join as m,dirname as at,basename as Jt}from"path";import{homedir as ct}from"os";import{fileURLToPath as ut}from"url";function pt(){return typeof __dirname<"u"?__dirname:at(ut(import.meta.url))}var te=pt(),g=f.get("CLAUDE_MEM_DATA_DIR"),L=process.env.CLAUDE_CONFIG_DIR||m(ct(),".claude"),ee=m(g,"archives"),re=m(g,"logs"),ne=m(g,"trash"),oe=m(g,"backups"),se=m(g,"settings.json"),ie=m(g,"claude-mem.db"),ae=m(g,"vector-db"),ce=m(L,"settings.json"),ue=m(L,"commands"),pe=m(L,"CLAUDE.md");import{spawnSync as lt}from"child_process";import{existsSync as ft}from"fs";import{join as x}from"path";import{homedir as H}from"os";function R(){let n=process.platform==="win32";try{if(lt("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:n}).status===0)return"bun"}catch{}let t=n?[x(H(),".bun","bin","bun.exe")]:[x(H(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(ft(e))return e;return null}function $(){return R()!==null}var T=O(g,"worker.pid"),F=O(g,"logs"),K=O(St(),".claude","plugins","marketplaces","thedotmack"),Tt=5e3,Ot=1e4,ht=200,Ct=1e3,At=100,h=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(F,{recursive:!0});let e=O(K,"plugin","scripts","worker-service.cjs");if(!b(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let o=R();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=dt(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:K,...s&&{windowsHide:!0}}),c=_t(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=Tt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!b(T))return null;let t=mt(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(g,{recursive:!0}),gt(T,JSON.stringify(t,null,2))}static removePidFile(){try{b(T)&&Et(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=Ot){let o=Date.now();for(;Date.now()-osetTimeout(s,ht))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(o,At))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return O(F,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),c=Math.floor(i/60),p=Math.floor(c/24);return p>0?`${p}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function E(n={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:o}=n,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",p=r||"Worker service connection failed.",l=t?` (port ${t})`:"",u=`${p}${l} +import{stdin as q}from"process";function Z(o,t,e){return 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 v(o,t,e={}){let r=Z(o,t,e);return JSON.stringify(r)}import{readFileSync as rt,writeFileSync as ot,existsSync as nt}from"fs";import{join as st}from"path";import{homedir as it}from"os";var tt=["bugfix","feature","refactor","discovery","decision","change"],et=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var U=tt.join(","),N=et.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:st(it(),".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:U,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 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(!nt(t))return this.getAllDefaults();let e=rt(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{ot(t,JSON.stringify(n,null,2),"utf-8"),a.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){a.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(s[i]=n[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=f.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),p=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${s}:${i}:${c}.${p}`}log(t,e,r,n,s){if(t0&&(C=` {${Object.entries(y).map(([Q,z])=>`${Q}=${z}`).join(", ")}}`)}let k=`[${i}] [${c}] [${p}] ${l}${r}${C}${u}`;t===3?console.error(k):console.log(k)}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`})}happyPathError(t,e,r,n,s=""){let l=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",C={...r,location:u};return this.warn(t,`[HAPPY-PATH] ${e}`,C,n),s}},a=new D;import A from"path";import{homedir as Mt}from"os";import{spawnSync as Dt}from"child_process";import{existsSync as Lt,writeFileSync as B,readFileSync as Rt,mkdirSync as bt}from"fs";var d={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function L(o){return process.platform==="win32"?Math.round(o*d.WINDOWS_MULTIPLIER):o}import{existsSync as P,readFileSync as Et,writeFileSync as mt,unlinkSync as gt,mkdirSync as W}from"fs";import{createWriteStream as _t}from"fs";import{join as O}from"path";import{spawn as dt}from"child_process";import{homedir as St}from"os";import{join as E,dirname as at,basename as Jt}from"path";import{homedir as ct}from"os";import{fileURLToPath as ut}from"url";function pt(){return typeof __dirname<"u"?__dirname:at(ut(import.meta.url))}var te=pt(),m=f.get("CLAUDE_MEM_DATA_DIR"),R=process.env.CLAUDE_CONFIG_DIR||E(ct(),".claude"),ee=E(m,"archives"),re=E(m,"logs"),oe=E(m,"trash"),ne=E(m,"backups"),se=E(m,"settings.json"),ie=E(m,"claude-mem.db"),ae=E(m,"vector-db"),ce=E(R,"settings.json"),ue=E(R,"commands"),pe=E(R,"CLAUDE.md");import{spawnSync as lt}from"child_process";import{existsSync as ft}from"fs";import{join as x}from"path";import{homedir as H}from"os";function b(){let o=process.platform==="win32";try{if(lt("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:o}).status===0)return"bun"}catch{}let t=o?[x(H(),".bun","bin","bun.exe")]:[x(H(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(ft(e))return e;return null}function $(){return b()!==null}var T=O(m,"worker.pid"),F=O(m,"logs"),K=O(St(),".claude","plugins","marketplaces","thedotmack"),Tt=5e3,Ot=1e4,ht=200,Ct=1e3,At=100,h=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(F,{recursive:!0});let e=O(K,"plugin","scripts","worker-service.cjs");if(!P(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let n=b();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=dt(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:K,...s&&{windowsHide:!0}}),c=_t(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=Tt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!P(T))return null;let t=Et(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(m,{recursive:!0}),mt(T,JSON.stringify(t,null,2))}static removePidFile(){try{P(T)&>(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=Ot){let n=Date.now();for(;Date.now()-nsetTimeout(s,ht))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,At))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return O(F,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math.floor(n/1e3),i=Math.floor(s/60),c=Math.floor(i/60),p=Math.floor(c/24);return p>0?`${p}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function _(o={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:n}=o,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",p=r||"Worker service connection failed.",l=t?` (port ${t})`:"",u=`${p}${l} `;return u+=`To restart the worker: `,u+=`1. Exit Claude Code completely @@ -11,6 +11,6 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje `,u+=`4. Run: npm run worker:restart `,u+="5. Restart Claude Code",e&&(u+=` -If that doesn't work, try: /troubleshoot`),o&&(u=`Worker Error: ${o} +If that doesn't work, try: /troubleshoot`),n&&(u=`Worker Error: ${n} -${u}`),u}var j=A.join(Mt(),".claude","plugins","marketplaces","thedotmack"),G=N(S.HEALTH_CHECK),d=null;function _(){if(d!==null)return d;try{let n=A.join(f.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=f.loadFromFile(n);return d=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),d}catch(n){return a.debug("SYSTEM","Failed to load port from settings, using default",{error:n}),d=parseInt(f.get("CLAUDE_MEM_WORKER_PORT"),10),d}}async function I(){try{let n=_();return(await fetch(`http://127.0.0.1:${n}/health`,{signal:AbortSignal.timeout(G)})).ok}catch(n){return a.debug("SYSTEM","Worker health check failed",{error:n instanceof Error?n.message:String(n),errorType:n?.constructor?.name}),!1}}function It(){try{let n=A.join(j,"package.json");return JSON.parse(Rt(n,"utf-8")).version}catch(n){return a.debug("SYSTEM","Failed to read plugin version",{error:n instanceof Error?n.message:String(n)}),null}}async function Pt(){try{let n=_(),t=await fetch(`http://127.0.0.1:${n}/api/version`,{signal:AbortSignal.timeout(G)});return t.ok?(await t.json()).version:null}catch(n){return a.debug("SYSTEM","Failed to get worker version",{error:n instanceof Error?n.message:String(n)}),null}}async function V(){let n=It(),t=await Pt();!n||!t||n!==t&&(a.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:n,workerVersion:t}),await h.restart(_()),await new Promise(e=>setTimeout(e,1e3)),await I()||a.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:n,runningVersion:t,port}))}async function wt(){let n=f.get("CLAUDE_MEM_DATA_DIR"),t=A.join(n,".pm2-migrated");if(bt(n,{recursive:!0}),!Lt(t))try{Dt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),B(t,new Date().toISOString(),"utf-8"),a.debug("SYSTEM","PM2 cleanup completed and marked")}catch{B(t,new Date().toISOString(),"utf-8")}let e=_(),r=await h.start(e);return r.success||a.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:j}),r.success}async function X(){if(await I()){await V();return}if(!await wt()){let e=_();throw new Error(E({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await I()){await V();return}let t=_();throw a.error("SYSTEM","Worker started but not responding to health checks"),new Error(E({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function Y(n){throw n.cause?.code==="ECONNREFUSED"||n.code==="ConnectionRefused"||n.name==="TimeoutError"||n.message?.includes("fetch failed")||n.message?.includes("Unable to connect")?new Error(E()):n}function J(n,t,e){a.error("HOOK",`${e.operation} failed`,{status:n.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${E()}`:`${e.operation} failed: ${E()}`;throw new Error(r)}async function kt(n){if(await X(),!n)throw new Error("saveHook requires input");let{session_id:t,cwd:e,tool_name:r,tool_input:o,tool_response:s}=n,i=_(),c=a.formatTool(r,o);a.dataIn("HOOK",`PostToolUse: ${c}`,{workerPort:i});try{let p=await fetch(`http://127.0.0.1:${i}/api/sessions/observations`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({claudeSessionId:t,tool_name:r,tool_input:o,tool_response:s,cwd:e||a.happyPathError("HOOK","Missing cwd in PostToolUse hook input",void 0,{session_id:t,tool_name:r},"")}),signal:AbortSignal.timeout(S.DEFAULT)});if(!p.ok){let l=await p.text();J(p,l,{hookName:"save",operation:"Observation storage",toolName:r,sessionId:t,port:i})}a.debug("HOOK","Observation sent successfully",{toolName:r})}catch(p){Y(p)}console.log(y("PostToolUse",!0))}var P="";q.on("data",n=>P+=n);q.on("end",async()=>{let n=P?JSON.parse(P):void 0;await kt(n)}); +${u}`),u}var j=A.join(Mt(),".claude","plugins","marketplaces","thedotmack"),G=L(d.HEALTH_CHECK),S=null;function g(){if(S!==null)return S;try{let o=A.join(f.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=f.loadFromFile(o);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}catch(o){return a.debug("SYSTEM","Failed to load port from settings, using default",{error:o}),S=parseInt(f.get("CLAUDE_MEM_WORKER_PORT"),10),S}}async function w(){try{let o=g();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(G)})).ok}catch(o){return a.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}function Pt(){try{let o=A.join(j,"package.json");return JSON.parse(Rt(o,"utf-8")).version}catch(o){return a.debug("SYSTEM","Failed to read plugin version",{error:o instanceof Error?o.message:String(o)}),null}}async function wt(){try{let o=g(),t=await fetch(`http://127.0.0.1:${o}/api/version`,{signal:AbortSignal.timeout(G)});return t.ok?(await t.json()).version:null}catch(o){return a.debug("SYSTEM","Failed to get worker version",{error:o instanceof Error?o.message:String(o)}),null}}async function V(){let o=Pt(),t=await wt();!o||!t||o!==t&&(a.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:o,workerVersion:t}),await new Promise(e=>setTimeout(e,L(d.PRE_RESTART_SETTLE_DELAY))),await h.restart(g()),await new Promise(e=>setTimeout(e,1e3)),await w()||a.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:o,runningVersion:t,port:g()}))}async function It(){let o=f.get("CLAUDE_MEM_DATA_DIR"),t=A.join(o,".pm2-migrated");if(bt(o,{recursive:!0}),!Lt(t))try{Dt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),B(t,new Date().toISOString(),"utf-8"),a.debug("SYSTEM","PM2 cleanup completed and marked")}catch{B(t,new Date().toISOString(),"utf-8")}let e=g(),r=await h.start(e);return r.success||a.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:j}),r.success}async function Y(){if(await w()){await V();return}if(!await It()){let e=g();throw new Error(_({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await w()){await V();return}let t=g();throw a.error("SYSTEM","Worker started but not responding to health checks"),new Error(_({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function X(o){throw o.cause?.code==="ECONNREFUSED"||o.code==="ConnectionRefused"||o.name==="TimeoutError"||o.message?.includes("fetch failed")||o.message?.includes("Unable to connect")?new Error(_()):o}function J(o,t,e){a.error("HOOK",`${e.operation} failed`,{status:o.status,...e},t);let r=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${_()}`:`${e.operation} failed: ${_()}`;throw new Error(r)}async function kt(o){if(await Y(),!o)throw new Error("saveHook requires input");let{session_id:t,cwd:e,tool_name:r,tool_input:n,tool_response:s}=o,i=g(),c=a.formatTool(r,n);a.dataIn("HOOK",`PostToolUse: ${c}`,{workerPort:i});try{let p=await fetch(`http://127.0.0.1:${i}/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||a.happyPathError("HOOK","Missing cwd in PostToolUse hook input",void 0,{session_id:t,tool_name:r},"")}),signal:AbortSignal.timeout(d.DEFAULT)});if(!p.ok){let l=await p.text();J(p,l,{hookName:"save",operation:"Observation storage",toolName:r,sessionId:t,port:i})}a.debug("HOOK","Observation sent successfully",{toolName:r})}catch(p){X(p)}console.log(v("PostToolUse",!0))}var I="";q.on("data",o=>I+=o);q.on("end",async()=>{let o=I?JSON.parse(I):void 0;await kt(o)}); diff --git a/plugin/scripts/summary-hook.js b/plugin/scripts/summary-hook.js index d547d8c2..5bdc4566 100755 --- a/plugin/scripts/summary-hook.js +++ b/plugin/scripts/summary-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import{stdin as z}from"process";function tt(r,t,e){return 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 U(r,t,e={}){let n=tt(r,t,e);return JSON.stringify(n)}import{readFileSync as nt,writeFileSync as ot,existsSync as st}from"fs";import{join as it}from"path";import{homedir as at}from"os";var et=["bugfix","feature","refactor","discovery","decision","change"],rt=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var v=et.join(","),N=rt.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:it(at(),".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:v,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 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(!st(t))return this.getAllDefaults();let e=nt(t,"utf-8"),n=JSON.parse(e),o=n;if(n.env&&typeof n.env=="object"){o=n.env;try{ot(t,JSON.stringify(o,null,2),"utf-8"),a.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){a.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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||{}),y=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=f.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===0?`${t.message} +import{stdin as z}from"process";function tt(r,t,e){return 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 v(r,t,e={}){let n=tt(r,t,e);return JSON.stringify(n)}import{readFileSync as nt,writeFileSync as ot,existsSync as st}from"fs";import{join as it}from"path";import{homedir as at}from"os";var et=["bugfix","feature","refactor","discovery","decision","change"],rt=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var N=et.join(","),x=rt.join(",");var f=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:it(at(),".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:N,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:x,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 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(!st(t))return this.getAllDefaults();let e=nt(t,"utf-8"),n=JSON.parse(e),o=n;if(n.env&&typeof n.env=="object"){o=n.env;try{ot(t,JSON.stringify(o,null,2),"utf-8"),a.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){a.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))o[i]!==void 0&&(s[i]=o[i]);return s}};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||{}),R=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=f.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),n=String(t.getMonth()+1).padStart(2,"0"),o=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),p=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${n}-${o} ${s}:${i}:${c}.${p}`}log(t,e,n,o,s){if(t0&&(C=` {${Object.entries(k).map(([Q,Z])=>`${Q}=${Z}`).join(", ")}}`)}let P=`[${i}] [${c}] [${p}] ${l}${n}${C}${u}`;t===3?console.error(P):console.log(P)}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`})}happyPathError(t,e,n,o,s=""){let l=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",C={...n,location:u};return this.warn(t,`[HAPPY-PATH] ${e}`,C,o),s}},a=new y;import A from"path";import{homedir as yt}from"os";import{spawnSync as Dt}from"child_process";import{existsSync as Rt,writeFileSync as V,readFileSync as Lt,mkdirSync as bt}from"fs";var _={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function x(r){return process.platform==="win32"?Math.round(r*_.WINDOWS_MULTIPLIER):r}import{existsSync as L,readFileSync as gt,writeFileSync as Et,unlinkSync as dt,mkdirSync as F}from"fs";import{createWriteStream as St}from"fs";import{join as h}from"path";import{spawn as _t}from"child_process";import{homedir as Tt}from"os";import{join as m,dirname as ct,basename as Qt}from"path";import{homedir as ut}from"os";import{fileURLToPath as pt}from"url";function lt(){return typeof __dirname<"u"?__dirname:ct(pt(import.meta.url))}var ne=lt(),g=f.get("CLAUDE_MEM_DATA_DIR"),D=process.env.CLAUDE_CONFIG_DIR||m(ut(),".claude"),oe=m(g,"archives"),se=m(g,"logs"),ie=m(g,"trash"),ae=m(g,"backups"),ce=m(g,"settings.json"),ue=m(g,"claude-mem.db"),pe=m(g,"vector-db"),le=m(D,"settings.json"),fe=m(D,"commands"),me=m(D,"CLAUDE.md");import{spawnSync as ft}from"child_process";import{existsSync as mt}from"fs";import{join as H}from"path";import{homedir as $}from"os";function R(){let r=process.platform==="win32";try{if(ft("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:r}).status===0)return"bun"}catch{}let t=r?[H($(),".bun","bin","bun.exe")]:[H($(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(mt(e))return e;return null}function W(){return R()!==null}var T=h(g,"worker.pid"),K=h(g,"logs"),B=h(Tt(),".claude","plugins","marketplaces","thedotmack"),ht=5e3,Ot=1e4,Ct=200,At=1e3,Mt=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};F(K,{recursive:!0});let e=h(B,"plugin","scripts","worker-service.cjs");if(!L(e))return{success:!1,error:`Worker script not found at ${e}`};let n=this.getLogFilePath();return this.startWithBun(e,n,t)}static isBunAvailable(){return W()}static async startWithBun(t,e,n){let o=R();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=_t(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(n)},cwd:B,...s&&{windowsHide:!0}}),c=St(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:n,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,n)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=ht){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!L(T))return null;let t=gt(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){F(g,{recursive:!0}),Et(T,JSON.stringify(t,null,2))}static removePidFile(){try{L(T)&&dt(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,n=Ot){let o=Date.now();for(;Date.now()-osetTimeout(s,Ct))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let n=Date.now();for(;Date.now()-nsetTimeout(o,Mt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(K,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),c=Math.floor(i/60),p=Math.floor(c/24);return p>0?`${p}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function E(r={}){let{port:t,includeSkillFallback:e=!1,customPrefix:n,actualError:o}=r,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",p=n||"Worker service connection failed.",l=t?` (port ${t})`:"",u=`${p}${l} +`+JSON.stringify(s,null,2):u=" "+this.formatData(s));let A="";if(o){let{sessionId:Nt,sdkSessionId:xt,correlationId:Ht,...U}=o;Object.keys(U).length>0&&(A=` {${Object.entries(U).map(([Q,Z])=>`${Q}=${Z}`).join(", ")}}`)}let k=`[${i}] [${c}] [${p}] ${l}${n}${A}${u}`;t===3?console.error(k):console.log(k)}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`})}happyPathError(t,e,n,o,s=""){let l=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),u=l?`${l[1].split("/").pop()}:${l[2]}`:"unknown",A={...n,location:u};return this.warn(t,`[HAPPY-PATH] ${e}`,A,o),s}},a=new R;import C from"path";import{homedir as Rt}from"os";import{spawnSync as yt}from"child_process";import{existsSync as Lt,writeFileSync as V,readFileSync as Dt,mkdirSync as bt}from"fs";var _={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function y(r){return process.platform==="win32"?Math.round(r*_.WINDOWS_MULTIPLIER):r}import{existsSync as b,readFileSync as gt,writeFileSync as Et,unlinkSync as dt,mkdirSync as F}from"fs";import{createWriteStream as _t}from"fs";import{join as h}from"path";import{spawn as St}from"child_process";import{homedir as Tt}from"os";import{join as m,dirname as ct,basename as Qt}from"path";import{homedir as ut}from"os";import{fileURLToPath as pt}from"url";function lt(){return typeof __dirname<"u"?__dirname:ct(pt(import.meta.url))}var ne=lt(),g=f.get("CLAUDE_MEM_DATA_DIR"),L=process.env.CLAUDE_CONFIG_DIR||m(ut(),".claude"),oe=m(g,"archives"),se=m(g,"logs"),ie=m(g,"trash"),ae=m(g,"backups"),ce=m(g,"settings.json"),ue=m(g,"claude-mem.db"),pe=m(g,"vector-db"),le=m(L,"settings.json"),fe=m(L,"commands"),me=m(L,"CLAUDE.md");import{spawnSync as ft}from"child_process";import{existsSync as mt}from"fs";import{join as H}from"path";import{homedir as $}from"os";function D(){let r=process.platform==="win32";try{if(ft("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:r}).status===0)return"bun"}catch{}let t=r?[H($(),".bun","bin","bun.exe")]:[H($(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(mt(e))return e;return null}function W(){return D()!==null}var T=h(g,"worker.pid"),K=h(g,"logs"),B=h(Tt(),".claude","plugins","marketplaces","thedotmack"),ht=5e3,Ot=1e4,At=200,Ct=1e3,Mt=100,O=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};F(K,{recursive:!0});let e=h(B,"plugin","scripts","worker-service.cjs");if(!b(e))return{success:!1,error:`Worker script not found at ${e}`};let n=this.getLogFilePath();return this.startWithBun(e,n,t)}static isBunAvailable(){return W()}static async startWithBun(t,e,n){let o=D();if(!o)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=St(o,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(n)},cwd:B,...s&&{windowsHide:!0}}),c=_t(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:n,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,n)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=ht){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!b(T))return null;let t=gt(T,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){F(g,{recursive:!0}),Et(T,JSON.stringify(t,null,2))}static removePidFile(){try{b(T)&&dt(T)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,n=Ot){let o=Date.now();for(;Date.now()-osetTimeout(s,At))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let n=Date.now();for(;Date.now()-nsetTimeout(o,Mt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return h(K,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),o=Date.now()-e,s=Math.floor(o/1e3),i=Math.floor(s/60),c=Math.floor(i/60),p=Math.floor(c/24);return p>0?`${p}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function d(r={}){let{port:t,includeSkillFallback:e=!1,customPrefix:n,actualError:o}=r,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",p=n||"Worker service connection failed.",l=t?` (port ${t})`:"",u=`${p}${l} `;return u+=`To restart the worker: `,u+=`1. Exit Claude Code completely @@ -13,8 +13,8 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje If that doesn't work, try: /troubleshoot`),o&&(u=`Worker Error: ${o} -${u}`),u}var G=A.join(yt(),".claude","plugins","marketplaces","thedotmack"),X=x(_.HEALTH_CHECK),S=null;function d(){if(S!==null)return S;try{let r=A.join(f.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=f.loadFromFile(r);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}catch(r){return a.debug("SYSTEM","Failed to load port from settings, using default",{error:r}),S=parseInt(f.get("CLAUDE_MEM_WORKER_PORT"),10),S}}async function b(){try{let r=d();return(await fetch(`http://127.0.0.1:${r}/health`,{signal:AbortSignal.timeout(X)})).ok}catch(r){return a.debug("SYSTEM","Worker health check failed",{error:r instanceof Error?r.message:String(r),errorType:r?.constructor?.name}),!1}}function It(){try{let r=A.join(G,"package.json");return JSON.parse(Lt(r,"utf-8")).version}catch(r){return a.debug("SYSTEM","Failed to read plugin version",{error:r instanceof Error?r.message:String(r)}),null}}async function wt(){try{let r=d(),t=await fetch(`http://127.0.0.1:${r}/api/version`,{signal:AbortSignal.timeout(X)});return t.ok?(await t.json()).version:null}catch(r){return a.debug("SYSTEM","Failed to get worker version",{error:r instanceof Error?r.message:String(r)}),null}}async function j(){let r=It(),t=await wt();!r||!t||r!==t&&(a.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:r,workerVersion:t}),await O.restart(d()),await new Promise(e=>setTimeout(e,1e3)),await b()||a.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:r,runningVersion:t,port}))}async function Pt(){let r=f.get("CLAUDE_MEM_DATA_DIR"),t=A.join(r,".pm2-migrated");if(bt(r,{recursive:!0}),!Rt(t))try{Dt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),V(t,new Date().toISOString(),"utf-8"),a.debug("SYSTEM","PM2 cleanup completed and marked")}catch{V(t,new Date().toISOString(),"utf-8")}let e=d(),n=await O.start(e);return n.success||a.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:n.error,marketplaceRoot:G}),n.success}async function Y(){if(await b()){await j();return}if(!await Pt()){let e=d();throw new Error(E({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(n=>setTimeout(n,500)),await b()){await j();return}let t=d();throw a.error("SYSTEM","Worker started but not responding to health checks"),new Error(E({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function J(r){throw r.cause?.code==="ECONNREFUSED"||r.code==="ConnectionRefused"||r.name==="TimeoutError"||r.message?.includes("fetch failed")||r.message?.includes("Unable to connect")?new Error(E()):r}function q(r,t,e){a.error("HOOK",`${e.operation} failed`,{status:r.status,...e},t);let n=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${E()}`:`${e.operation} failed: ${E()}`;throw new Error(n)}import{readFileSync as kt,existsSync as Ut}from"fs";function I(r,t,e=!1){if(!r||!Ut(r))return a.happyPathError("PARSER","Transcript path missing or file does not exist",void 0,{transcriptPath:r,role:t},""),"";try{let n=kt(r,"utf-8").trim();if(!n)return a.happyPathError("PARSER","Transcript file exists but is empty",void 0,{transcriptPath:r,role:t},""),"";let o=n.split(` +${u}`),u}var G=C.join(Rt(),".claude","plugins","marketplaces","thedotmack"),Y=y(_.HEALTH_CHECK),S=null;function E(){if(S!==null)return S;try{let r=C.join(f.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=f.loadFromFile(r);return S=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),S}catch(r){return a.debug("SYSTEM","Failed to load port from settings, using default",{error:r}),S=parseInt(f.get("CLAUDE_MEM_WORKER_PORT"),10),S}}async function P(){try{let r=E();return(await fetch(`http://127.0.0.1:${r}/health`,{signal:AbortSignal.timeout(Y)})).ok}catch(r){return a.debug("SYSTEM","Worker health check failed",{error:r instanceof Error?r.message:String(r),errorType:r?.constructor?.name}),!1}}function Pt(){try{let r=C.join(G,"package.json");return JSON.parse(Dt(r,"utf-8")).version}catch(r){return a.debug("SYSTEM","Failed to read plugin version",{error:r instanceof Error?r.message:String(r)}),null}}async function wt(){try{let r=E(),t=await fetch(`http://127.0.0.1:${r}/api/version`,{signal:AbortSignal.timeout(Y)});return t.ok?(await t.json()).version:null}catch(r){return a.debug("SYSTEM","Failed to get worker version",{error:r instanceof Error?r.message:String(r)}),null}}async function j(){let r=Pt(),t=await wt();!r||!t||r!==t&&(a.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:r,workerVersion:t}),await new Promise(e=>setTimeout(e,y(_.PRE_RESTART_SETTLE_DELAY))),await O.restart(E()),await new Promise(e=>setTimeout(e,1e3)),await P()||a.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:r,runningVersion:t,port:E()}))}async function It(){let r=f.get("CLAUDE_MEM_DATA_DIR"),t=C.join(r,".pm2-migrated");if(bt(r,{recursive:!0}),!Lt(t))try{yt("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),V(t,new Date().toISOString(),"utf-8"),a.debug("SYSTEM","PM2 cleanup completed and marked")}catch{V(t,new Date().toISOString(),"utf-8")}let e=E(),n=await O.start(e);return n.success||a.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:n.error,marketplaceRoot:G}),n.success}async function X(){if(await P()){await j();return}if(!await It()){let e=E();throw new Error(d({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(n=>setTimeout(n,500)),await P()){await j();return}let t=E();throw a.error("SYSTEM","Worker started but not responding to health checks"),new Error(d({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}function J(r){throw r.cause?.code==="ECONNREFUSED"||r.code==="ConnectionRefused"||r.name==="TimeoutError"||r.message?.includes("fetch failed")||r.message?.includes("Unable to connect")?new Error(d()):r}function q(r,t,e){a.error("HOOK",`${e.operation} failed`,{status:r.status,...e},t);let n=e.toolName?`Failed ${e.operation} for ${e.toolName}: ${d()}`:`${e.operation} failed: ${d()}`;throw new Error(n)}import{readFileSync as kt,existsSync as Ut}from"fs";function w(r,t,e=!1){if(!r||!Ut(r))return a.happyPathError("PARSER","Transcript path missing or file does not exist",void 0,{transcriptPath:r,role:t},""),"";try{let n=kt(r,"utf-8").trim();if(!n)return a.happyPathError("PARSER","Transcript file exists but is empty",void 0,{transcriptPath:r,role:t},""),"";let o=n.split(` `),s=!1;for(let i=o.length-1;i>=0;i--)try{let c=JSON.parse(o[i]);if(c.type===t&&(s=!0,c.message?.content)){let p="",l=c.message.content;return typeof l=="string"?p=l:Array.isArray(l)&&(p=l.filter(u=>u.type==="text").map(u=>u.text).join(` `)),e&&(p=p.replace(/[\s\S]*?<\/system-reminder>/g,""),p=p.replace(/\n{3,}/g,` -`).trim()),(!p||p.trim()==="")&&a.happyPathError("PARSER","Found message but content is empty after processing",void 0,{role:t,transcriptPath:r,msgContentType:typeof l,stripSystemReminders:e},""),p}}catch{continue}s||a.happyPathError("PARSER","No message found for role in transcript",void 0,{role:t,transcriptPath:r,totalLines:o.length},"")}catch(n){a.error("HOOK","Failed to read transcript",{transcriptPath:r},n)}return""}async function vt(r){if(await Y(),!r)throw new Error("summaryHook requires input");let{session_id:t}=r,e=d(),n=r.transcript_path||a.happyPathError("HOOK","Missing transcript_path in Stop hook input",void 0,{session_id:t},""),o=I(n,"user"),s=I(n,"assistant",!0);a.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(_.DEFAULT)});if(!i.ok){let c=await i.text();q(i,c,{hookName:"summary",operation:"Summary generation",sessionId:t,port:e})}a.debug("HOOK","Summary request sent successfully")}catch(i){J(i)}finally{try{let i=await fetch(`http://127.0.0.1:${e}/api/processing`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({isProcessing:!1}),signal:AbortSignal.timeout(2e3)});i.ok||a.warn("HOOK","Failed to stop spinner",{status:i.status})}catch(i){a.warn("HOOK","Could not stop spinner",{error:i.message})}}console.log(U("Stop",!0))}var w="";z.on("data",r=>w+=r);z.on("end",async()=>{let r=w?JSON.parse(w):void 0;await vt(r)}); +`).trim()),(!p||p.trim()==="")&&a.happyPathError("PARSER","Found message but content is empty after processing",void 0,{role:t,transcriptPath:r,msgContentType:typeof l,stripSystemReminders:e},""),p}}catch{continue}s||a.happyPathError("PARSER","No message found for role in transcript",void 0,{role:t,transcriptPath:r,totalLines:o.length},"")}catch(n){a.error("HOOK","Failed to read transcript",{transcriptPath:r},n)}return""}async function vt(r){if(await X(),!r)throw new Error("summaryHook requires input");let{session_id:t}=r,e=E(),n=r.transcript_path||a.happyPathError("HOOK","Missing transcript_path in Stop hook input",void 0,{session_id:t},""),o=w(n,"user"),s=w(n,"assistant",!0);a.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(_.DEFAULT)});if(!i.ok){let c=await i.text();q(i,c,{hookName:"summary",operation:"Summary generation",sessionId:t,port:e})}a.debug("HOOK","Summary request sent successfully")}catch(i){J(i)}finally{try{let i=await fetch(`http://127.0.0.1:${e}/api/processing`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({isProcessing:!1}),signal:AbortSignal.timeout(2e3)});i.ok||a.warn("HOOK","Failed to stop spinner",{status:i.status})}catch(i){a.warn("HOOK","Could not stop spinner",{error:i.message})}}console.log(v("Stop",!0))}var I="";z.on("data",r=>I+=r);z.on("end",async()=>{let r=I?JSON.parse(I):void 0;await vt(r)}); diff --git a/plugin/scripts/user-message-hook.js b/plugin/scripts/user-message-hook.js index c4476b59..b131d7a0 100755 --- a/plugin/scripts/user-message-hook.js +++ b/plugin/scripts/user-message-hook.js @@ -1,8 +1,8 @@ #!/usr/bin/env bun -import{basename as wt}from"path";import C from"path";import{homedir as Tt}from"os";import{spawnSync as ht}from"child_process";import{existsSync as Ot,writeFileSync as K,readFileSync as Ct,mkdirSync as At}from"fs";import{readFileSync as Q,writeFileSync as z,existsSync as Z}from"fs";import{join as tt}from"path";import{homedir as et}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 P=J.join(","),k=q.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:tt(et(),".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:P,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:k,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 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(!Z(t))return this.getAllDefaults();let e=Q(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{z(t,JSON.stringify(n,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(s[i]=n[i]);return s}};var A=(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))(A||{}),M=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=A[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),g=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${s}:${i}:${c}.${g}`}log(t,e,r,n,s){if(t0&&(O=` {${Object.entries(y).map(([X,Y])=>`${X}=${Y}`).join(", ")}}`)}let I=`[${i}] [${c}] [${g}] ${m}${r}${O}${a}`;t===3?console.error(I):console.log(I)}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`})}happyPathError(t,e,r,n,s=""){let m=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=m?`${m[1].split("/").pop()}:${m[2]}`:"unknown",O={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,O,n),s}},u=new M;var D={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5},v={SUCCESS:0,FAILURE:1,USER_MESSAGE_ONLY:3};function U(o){return process.platform==="win32"?Math.round(o*D.WINDOWS_MULTIPLIER):o}import{existsSync as R,readFileSync as ct,writeFileSync as ut,unlinkSync as lt,mkdirSync as W}from"fs";import{createWriteStream as pt}from"fs";import{join as S}from"path";import{spawn as Et}from"child_process";import{homedir as gt}from"os";import{join as p,dirname as rt,basename as Bt}from"path";import{homedir as nt}from"os";import{fileURLToPath as ot}from"url";function st(){return typeof __dirname<"u"?__dirname:rt(ot(import.meta.url))}var Yt=st(),E=l.get("CLAUDE_MEM_DATA_DIR"),L=process.env.CLAUDE_CONFIG_DIR||p(nt(),".claude"),Jt=p(E,"archives"),qt=p(E,"logs"),Qt=p(E,"trash"),zt=p(E,"backups"),Zt=p(E,"settings.json"),te=p(E,"claude-mem.db"),ee=p(E,"vector-db"),re=p(L,"settings.json"),ne=p(L,"commands"),oe=p(L,"CLAUDE.md");import{spawnSync as it}from"child_process";import{existsSync as at}from"fs";import{join as N}from"path";import{homedir as x}from"os";function w(){let o=process.platform==="win32";try{if(it("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:o}).status===0)return"bun"}catch{}let t=o?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(at(e))return e;return null}function $(){return w()!==null}var d=S(E,"worker.pid"),H=S(E,"logs"),F=S(gt(),".claude","plugins","marketplaces","thedotmack"),mt=5e3,ft=1e4,_t=200,dt=1e3,St=100,T=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=S(F,"plugin","scripts","worker-service.cjs");if(!R(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let n=w();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=Et(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),c=pt(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=mt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!R(d))return null;let t=ct(d,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(E,{recursive:!0}),ut(d,JSON.stringify(t,null,2))}static removePidFile(){try{R(d)&<(d)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ft){let n=Date.now();for(;Date.now()-nsetTimeout(s,_t))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,St))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return S(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math.floor(n/1e3),i=Math.floor(s/60),c=Math.floor(i/60),g=Math.floor(c/24);return g>0?`${g}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function h(o={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:n}=o,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",g=r||"Worker service connection failed.",m=t?` (port ${t})`:"",a=`${g}${m} +import{basename as Rt}from"path";import A from"path";import{homedir as Tt}from"os";import{spawnSync as ht}from"child_process";import{existsSync as Ot,writeFileSync as K,readFileSync as Ct,mkdirSync as At}from"fs";import{readFileSync as Q,writeFileSync as z,existsSync as Z}from"fs";import{join as tt}from"path";import{homedir as et}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 k=J.join(","),v=q.join(",");var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:tt(et(),".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:k,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:v,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 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(!Z(t))return this.getAllDefaults();let e=Q(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{z(t,JSON.stringify(n,null,2),"utf-8"),u.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){u.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let s={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(s[i]=n[i]);return s}};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=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=M[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),s=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),c=String(t.getSeconds()).padStart(2,"0"),m=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${s}:${i}:${c}.${m}`}log(t,e,r,n,s){if(t0&&(O=` {${Object.entries(P).map(([Y,X])=>`${Y}=${X}`).join(", ")}}`)}let y=`[${i}] [${c}] [${m}] ${g}${r}${O}${a}`;t===3?console.error(y):console.log(y)}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`})}happyPathError(t,e,r,n,s=""){let g=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),a=g?`${g[1].split("/").pop()}:${g[2]}`:"unknown",O={...r,location:a};return this.warn(t,`[HAPPY-PATH] ${e}`,O,n),s}},u=new D;var C={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5},U={SUCCESS:0,FAILURE:1,USER_MESSAGE_ONLY:3};function L(o){return process.platform==="win32"?Math.round(o*C.WINDOWS_MULTIPLIER):o}import{existsSync as b,readFileSync as ct,writeFileSync as ut,unlinkSync as lt,mkdirSync as W}from"fs";import{createWriteStream as pt}from"fs";import{join as S}from"path";import{spawn as Et}from"child_process";import{homedir as mt}from"os";import{join as p,dirname as rt,basename as Bt}from"path";import{homedir as nt}from"os";import{fileURLToPath as ot}from"url";function st(){return typeof __dirname<"u"?__dirname:rt(ot(import.meta.url))}var Xt=st(),E=l.get("CLAUDE_MEM_DATA_DIR"),R=process.env.CLAUDE_CONFIG_DIR||p(nt(),".claude"),Jt=p(E,"archives"),qt=p(E,"logs"),Qt=p(E,"trash"),zt=p(E,"backups"),Zt=p(E,"settings.json"),te=p(E,"claude-mem.db"),ee=p(E,"vector-db"),re=p(R,"settings.json"),ne=p(R,"commands"),oe=p(R,"CLAUDE.md");import{spawnSync as it}from"child_process";import{existsSync as at}from"fs";import{join as N}from"path";import{homedir as x}from"os";function w(){let o=process.platform==="win32";try{if(it("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:o}).status===0)return"bun"}catch{}let t=o?[N(x(),".bun","bin","bun.exe")]:[N(x(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(at(e))return e;return null}function $(){return w()!==null}var d=S(E,"worker.pid"),H=S(E,"logs"),F=S(mt(),".claude","plugins","marketplaces","thedotmack"),gt=5e3,ft=1e4,_t=200,dt=1e3,St=100,T=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};W(H,{recursive:!0});let e=S(F,"plugin","scripts","worker-service.cjs");if(!b(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return $()}static async startWithBun(t,e,r){let n=w();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let s=process.platform==="win32",i=Et(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:F,...s&&{windowsHide:!0}}),c=pt(e,{flags:"a"});return i.stdout?.pipe(c),i.stderr?.pipe(c),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(s){return{success:!1,error:s instanceof Error?s.message:String(s)}}}static async stop(t=gt){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!b(d))return null;let t=ct(d,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){W(E,{recursive:!0}),ut(d,JSON.stringify(t,null,2))}static removePidFile(){try{b(d)&<(d)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ft){let n=Date.now();for(;Date.now()-nsetTimeout(s,_t))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,St))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return S(H,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math.floor(n/1e3),i=Math.floor(s/60),c=Math.floor(i/60),m=Math.floor(c/24);return m>0?`${m}d ${c%24}h`:c>0?`${c}h ${i%60}m`:i>0?`${i}m ${s%60}s`:`${s}s`}};function h(o={}){let{port:t,includeSkillFallback:e=!1,customPrefix:r,actualError:n}=o,s=process.platform==="win32",i=s?"%USERPROFILE%\\.claude\\plugins\\marketplaces\\thedotmack":"~/.claude/plugins/marketplaces/thedotmack",c=s?"Command Prompt or PowerShell":"Terminal",m=r||"Worker service connection failed.",g=t?` (port ${t})`:"",a=`${m}${g} `;return a+=`To restart the worker: `,a+=`1. Exit Claude Code completely @@ -13,7 +13,7 @@ ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Obje If that doesn't work, try: /troubleshoot`),n&&(a=`Worker Error: ${n} -${a}`),a}var V=C.join(Tt(),".claude","plugins","marketplaces","thedotmack"),j=U(D.HEALTH_CHECK),_=null;function f(){if(_!==null)return _;try{let o=C.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(o);return _=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),_}catch(o){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:o}),_=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),_}}async function b(){try{let o=f();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(j)})).ok}catch(o){return u.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}function Mt(){try{let o=C.join(V,"package.json");return JSON.parse(Ct(o,"utf-8")).version}catch(o){return u.debug("SYSTEM","Failed to read plugin version",{error:o instanceof Error?o.message:String(o)}),null}}async function Dt(){try{let o=f(),t=await fetch(`http://127.0.0.1:${o}/api/version`,{signal:AbortSignal.timeout(j)});return t.ok?(await t.json()).version:null}catch(o){return u.debug("SYSTEM","Failed to get worker version",{error:o instanceof Error?o.message:String(o)}),null}}async function B(){let o=Mt(),t=await Dt();!o||!t||o!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:o,workerVersion:t}),await T.restart(f()),await new Promise(e=>setTimeout(e,1e3)),await b()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:o,runningVersion:t,port}))}async function Lt(){let o=l.get("CLAUDE_MEM_DATA_DIR"),t=C.join(o,".pm2-migrated");if(At(o,{recursive:!0}),!Ot(t))try{ht("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=f(),r=await T.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:V}),r.success}async function G(){if(await b()){await B();return}if(!await Lt()){let e=f();throw new Error(h({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await b()){await B();return}let t=f();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(h({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}try{await G();let o=f(),t=wt(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(h({includeSkillFallback:!0}));let r=await e.text();console.error(` +${a}`),a}var V=A.join(Tt(),".claude","plugins","marketplaces","thedotmack"),j=L(C.HEALTH_CHECK),_=null;function f(){if(_!==null)return _;try{let o=A.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(o);return _=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),_}catch(o){return u.debug("SYSTEM","Failed to load port from settings, using default",{error:o}),_=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),_}}async function I(){try{let o=f();return(await fetch(`http://127.0.0.1:${o}/health`,{signal:AbortSignal.timeout(j)})).ok}catch(o){return u.debug("SYSTEM","Worker health check failed",{error:o instanceof Error?o.message:String(o),errorType:o?.constructor?.name}),!1}}function Mt(){try{let o=A.join(V,"package.json");return JSON.parse(Ct(o,"utf-8")).version}catch(o){return u.debug("SYSTEM","Failed to read plugin version",{error:o instanceof Error?o.message:String(o)}),null}}async function Dt(){try{let o=f(),t=await fetch(`http://127.0.0.1:${o}/api/version`,{signal:AbortSignal.timeout(j)});return t.ok?(await t.json()).version:null}catch(o){return u.debug("SYSTEM","Failed to get worker version",{error:o instanceof Error?o.message:String(o)}),null}}async function B(){let o=Mt(),t=await Dt();!o||!t||o!==t&&(u.info("SYSTEM","Worker version mismatch detected - restarting worker",{pluginVersion:o,workerVersion:t}),await new Promise(e=>setTimeout(e,L(C.PRE_RESTART_SETTLE_DELAY))),await T.restart(f()),await new Promise(e=>setTimeout(e,1e3)),await I()||u.error("SYSTEM","Worker failed to restart after version mismatch",{expectedVersion:o,runningVersion:t,port:f()}))}async function Lt(){let o=l.get("CLAUDE_MEM_DATA_DIR"),t=A.join(o,".pm2-migrated");if(At(o,{recursive:!0}),!Ot(t))try{ht("pm2",["delete","claude-mem-worker"],{stdio:"ignore"}),K(t,new Date().toISOString(),"utf-8"),u.debug("SYSTEM","PM2 cleanup completed and marked")}catch{K(t,new Date().toISOString(),"utf-8")}let e=f(),r=await T.start(e);return r.success||u.error("SYSTEM","Failed to start worker",{platform:process.platform,port:e,error:r.error,marketplaceRoot:V}),r.success}async function G(){if(await I()){await B();return}if(!await Lt()){let e=f();throw new Error(h({port:e,customPrefix:`Worker service failed to start on port ${e}.`}))}for(let e=0;e<5;e++)if(await new Promise(r=>setTimeout(r,500)),await I()){await B();return}let t=f();throw u.error("SYSTEM","Worker started but not responding to health checks"),new Error(h({port:t,customPrefix:`Worker service started but is not responding on port ${t}.`}))}try{await G();let o=f(),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(h({includeSkillFallback:!0}));let r=await e.text();console.error(` \u{1F4DD} Claude-Mem Context Loaded \u2139\uFE0F Note: This appears as stderr but is informational only @@ -42,4 +42,4 @@ Dependencies are installing in the background. This only happens once. Thank you for installing Claude-Mem! This message was not added to your startup context, so you can continue working as normal. -`)}process.exit(v.USER_MESSAGE_ONLY); +`)}process.exit(U.USER_MESSAGE_ONLY); diff --git a/plugin/scripts/worker-cli.js b/plugin/scripts/worker-cli.js index 68d97104..26619ada 100755 --- a/plugin/scripts/worker-cli.js +++ b/plugin/scripts/worker-cli.js @@ -1,5 +1,5 @@ #!/usr/bin/env bun -import{existsSync as M,readFileSync as et,writeFileSync as rt,unlinkSync as nt,mkdirSync as k}from"fs";import{createWriteStream as ot}from"fs";import{join as d}from"path";import{spawn as st}from"child_process";import{homedir as it}from"os";import{join as c,dirname as J,basename as Pt}from"path";import{homedir as q}from"os";import{fileURLToPath as Q}from"url";import{readFileSync as V,writeFileSync as j,existsSync as G}from"fs";import{join as X}from"path";import{homedir as Y}from"os";var K=["bugfix","feature","refactor","discovery","decision","change"],B=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var R=K.join(","),P=B.join(",");var O=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(O||{}),h=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=O[t]??1}return this.level}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.getLevel()===0?`${t.message} +import{existsSync as M,readFileSync as et,writeFileSync as rt,unlinkSync as nt,mkdirSync as k}from"fs";import{createWriteStream as ot}from"fs";import{join as d}from"path";import{spawn as st}from"child_process";import{homedir as it}from"os";import{join as c,dirname as J,basename as Pt}from"path";import{homedir as q}from"os";import{fileURLToPath as Q}from"url";import{readFileSync as V,writeFileSync as j,existsSync as G}from"fs";import{join as Y}from"path";import{homedir as X}from"os";var K=["bugfix","feature","refactor","discovery","decision","change"],B=["how-it-works","why-it-exists","what-changed","problem-solution","gotcha","pattern","trade-off"];var I=K.join(","),P=B.join(",");var O=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(O||{}),h=class{level=null;useColor;constructor(){this.useColor=process.stdout.isTTY??!1}getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toUpperCase();this.level=O[t]??1}return this.level}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.getLevel()===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}}formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0"),o=String(t.getHours()).padStart(2,"0"),i=String(t.getMinutes()).padStart(2,"0"),a=String(t.getSeconds()).padStart(2,"0"),g=String(t.getMilliseconds()).padStart(3,"0");return`${e}-${r}-${n} ${o}:${i}:${a}.${g}`}log(t,e,r,n,o){if(t0&&(T=` {${Object.entries(I).map(([F,H])=>`${F}=${H}`).join(", ")}}`)}let L=`[${i}] [${a}] [${g}] ${E}${r}${T}${m}`;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`})}happyPathError(t,e,r,n,o=""){let E=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),m=E?`${E[1].split("/").pop()}:${E[2]}`:"unknown",T={...r,location:m};return this.warn(t,`[HAPPY-PATH] ${e}`,T,n),o}},_=new h;var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:X(Y(),".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:R,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:P,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 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(!G(t))return this.getAllDefaults();let e=V(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{j(t,JSON.stringify(n,null,2),"utf-8"),_.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){_.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let o={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(o[i]=n[i]);return o}};function z(){return typeof __dirname<"u"?__dirname:J(Q(import.meta.url))}var vt=z(),u=l.get("CLAUDE_MEM_DATA_DIR"),C=process.env.CLAUDE_CONFIG_DIR||c(q(),".claude"),Ut=c(u,"archives"),Nt=c(u,"logs"),xt=c(u,"trash"),$t=c(u,"backups"),Wt=c(u,"settings.json"),Ft=c(u,"claude-mem.db"),Ht=c(u,"vector-db"),Kt=c(C,"settings.json"),Bt=c(C,"commands"),Vt=c(C,"CLAUDE.md");import{spawnSync as Z}from"child_process";import{existsSync as tt}from"fs";import{join as w}from"path";import{homedir as b}from"os";function A(){let s=process.platform==="win32";try{if(Z("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:s}).status===0)return"bun"}catch{}let t=s?[w(b(),".bun","bin","bun.exe")]:[w(b(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(tt(e))return e;return null}function y(){return A()!==null}var S=d(u,"worker.pid"),v=d(u,"logs"),U=d(it(),".claude","plugins","marketplaces","thedotmack"),at=5e3,ct=1e4,ut=200,lt=1e3,pt=100,p=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};k(v,{recursive:!0});let e=d(U,"plugin","scripts","worker-service.cjs");if(!M(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return y()}static async startWithBun(t,e,r){let n=A();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let o=process.platform==="win32",i=st(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:U,...o&&{windowsHide:!0}}),a=ot(e,{flags:"a"});return i.stdout?.pipe(a),i.stderr?.pipe(a),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(o){return{success:!1,error:o instanceof Error?o.message:String(o)}}}static async stop(t=at){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!M(S))return null;let t=et(S,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){k(u,{recursive:!0}),rt(S,JSON.stringify(t,null,2))}static removePidFile(){try{M(S)&&nt(S)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ct){let n=Date.now();for(;Date.now()-nsetTimeout(o,ut))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,pt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return d(v,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,o=Math.floor(n/1e3),i=Math.floor(o/60),a=Math.floor(i/60),g=Math.floor(a/24);return g>0?`${g}d ${a%24}h`:a>0?`${a}h ${i%60}m`:i>0?`${i}m ${o%60}s`:`${o}s`}};import x from"path";import{homedir as gt}from"os";var D={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function N(s){return process.platform==="win32"?Math.round(s*D.WINDOWS_MULTIPLIER):s}var me=x.join(gt(),".claude","plugins","marketplaces","thedotmack"),_e=N(D.HEALTH_CHECK),f=null;function $(){if(f!==null)return f;try{let s=x.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(s);return f=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),f}catch(s){return _.debug("SYSTEM","Failed to load port from settings, using default",{error:s}),f=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),f}}var Et=process.argv[2],W=$();async function ft(){switch(Et){case"start":{let s=await p.start(W);if(s.success){console.log(`Worker started (PID: ${s.pid})`);let t=new Date().toISOString().slice(0,10);console.log(`Logs: ~/.claude-mem/logs/worker-${t}.log`),process.exit(0)}else console.error(`Failed to start: ${s.error}`),process.exit(1);break}case"stop":await p.stop(),console.log("Worker stopped"),process.exit(0);case"restart":{let s=await p.restart(W);s.success?(console.log(`Worker restarted (PID: ${s.pid})`),process.exit(0)):(console.error(`Failed to restart: ${s.error}`),process.exit(1));break}case"status":{let s=await p.status();s.running?(console.log("Worker is running"),console.log(` PID: ${s.pid}`),console.log(` Port: ${s.port}`),console.log(` Uptime: ${s.uptime}`)):console.log("Worker is not running"),process.exit(0)}default:console.log("Usage: worker-cli.js "),process.exit(1)}}ft().catch(s=>{console.error(s),process.exit(1)}); +`+JSON.stringify(o,null,2):m=" "+this.formatData(o));let T="";if(n){let{sessionId:mt,sdkSessionId:_t,correlationId:St,...R}=n;Object.keys(R).length>0&&(T=` {${Object.entries(R).map(([F,H])=>`${F}=${H}`).join(", ")}}`)}let L=`[${i}] [${a}] [${g}] ${E}${r}${T}${m}`;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`})}happyPathError(t,e,r,n,o=""){let E=((new Error().stack||"").split(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),m=E?`${E[1].split("/").pop()}:${E[2]}`:"unknown",T={...r,location:m};return this.warn(t,`[HAPPY-PATH] ${e}`,T,n),o}},_=new h;var l=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-5",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_DATA_DIR:Y(X(),".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:I,CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS:P,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 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(!G(t))return this.getAllDefaults();let e=V(t,"utf-8"),r=JSON.parse(e),n=r;if(r.env&&typeof r.env=="object"){n=r.env;try{j(t,JSON.stringify(n,null,2),"utf-8"),_.info("SETTINGS","Migrated settings file from nested to flat schema",{settingsPath:t})}catch(i){_.warn("SETTINGS","Failed to auto-migrate settings file",{settingsPath:t},i)}}let o={...this.DEFAULTS};for(let i of Object.keys(this.DEFAULTS))n[i]!==void 0&&(o[i]=n[i]);return o}};function z(){return typeof __dirname<"u"?__dirname:J(Q(import.meta.url))}var vt=z(),u=l.get("CLAUDE_MEM_DATA_DIR"),A=process.env.CLAUDE_CONFIG_DIR||c(q(),".claude"),Ut=c(u,"archives"),Nt=c(u,"logs"),xt=c(u,"trash"),$t=c(u,"backups"),Wt=c(u,"settings.json"),Ft=c(u,"claude-mem.db"),Ht=c(u,"vector-db"),Kt=c(A,"settings.json"),Bt=c(A,"commands"),Vt=c(A,"CLAUDE.md");import{spawnSync as Z}from"child_process";import{existsSync as tt}from"fs";import{join as w}from"path";import{homedir as b}from"os";function C(){let s=process.platform==="win32";try{if(Z("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:s}).status===0)return"bun"}catch{}let t=s?[w(b(),".bun","bin","bun.exe")]:[w(b(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun","/home/linuxbrew/.linuxbrew/bin/bun"];for(let e of t)if(tt(e))return e;return null}function y(){return C()!==null}var S=d(u,"worker.pid"),v=d(u,"logs"),U=d(it(),".claude","plugins","marketplaces","thedotmack"),at=5e3,ct=1e4,ut=200,lt=1e3,pt=100,p=class{static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,error:`Invalid port ${t}. Must be between 1024 and 65535`};if(await this.isRunning())return{success:!0,pid:this.getPidInfo()?.pid};k(v,{recursive:!0});let e=d(U,"plugin","scripts","worker-service.cjs");if(!M(e))return{success:!1,error:`Worker script not found at ${e}`};let r=this.getLogFilePath();return this.startWithBun(e,r,t)}static isBunAvailable(){return y()}static async startWithBun(t,e,r){let n=C();if(!n)return{success:!1,error:"Bun is required but not found in PATH or common installation paths. Install from https://bun.sh"};try{let o=process.platform==="win32",i=st(n,[t],{detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,CLAUDE_MEM_WORKER_PORT:String(r)},cwd:U,...o&&{windowsHide:!0}}),a=ot(e,{flags:"a"});return i.stdout?.pipe(a),i.stderr?.pipe(a),i.unref(),i.pid?(this.writePidFile({pid:i.pid,port:r,startedAt:new Date().toISOString(),version:process.env.npm_package_version||"unknown"}),this.waitForHealth(i.pid,r)):{success:!1,error:"Failed to get PID from spawned process"}}catch(o){return{success:!1,error:o instanceof Error?o.message:String(o)}}}static async stop(t=at){let e=this.getPidInfo();if(!e)return!0;try{process.kill(e.pid,"SIGTERM"),await this.waitForExit(e.pid,t)}catch{try{process.kill(e.pid,"SIGKILL")}catch{}}return this.removePidFile(),!0}static async restart(t){return await this.stop(),this.start(t)}static async status(){let t=this.getPidInfo();if(!t)return{running:!1};let e=this.isProcessAlive(t.pid);return{running:e,pid:e?t.pid:void 0,port:e?t.port:void 0,uptime:e?this.formatUptime(t.startedAt):void 0}}static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=this.isProcessAlive(t.pid);return e||this.removePidFile(),e}static getPidInfo(){try{if(!M(S))return null;let t=et(S,"utf-8"),e=JSON.parse(t);return typeof e.pid!="number"||typeof e.port!="number"?null:e}catch{return null}}static writePidFile(t){k(u,{recursive:!0}),rt(S,JSON.stringify(t,null,2))}static removePidFile(){try{M(S)&&nt(S)}catch{}}static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}static async waitForHealth(t,e,r=ct){let n=Date.now();for(;Date.now()-nsetTimeout(o,ut))}return{success:!1,error:"Health check timed out"}}static async waitForExit(t,e){let r=Date.now();for(;Date.now()-rsetTimeout(n,pt))}throw new Error("Process did not exit within timeout")}static getLogFilePath(){let t=new Date().toISOString().slice(0,10);return d(v,`worker-${t}.log`)}static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,o=Math.floor(n/1e3),i=Math.floor(o/60),a=Math.floor(i/60),g=Math.floor(a/24);return g>0?`${g}d ${a%24}h`:a>0?`${a}h ${i%60}m`:i>0?`${i}m ${o%60}s`:`${o}s`}};import x from"path";import{homedir as gt}from"os";var D={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function N(s){return process.platform==="win32"?Math.round(s*D.WINDOWS_MULTIPLIER):s}var me=x.join(gt(),".claude","plugins","marketplaces","thedotmack"),_e=N(D.HEALTH_CHECK),f=null;function $(){if(f!==null)return f;try{let s=x.join(l.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),t=l.loadFromFile(s);return f=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),f}catch(s){return _.debug("SYSTEM","Failed to load port from settings, using default",{error:s}),f=parseInt(l.get("CLAUDE_MEM_WORKER_PORT"),10),f}}var Et=process.argv[2],W=$();async function ft(){switch(Et){case"start":{let s=await p.start(W);if(s.success){console.log(`Worker started (PID: ${s.pid})`);let t=new Date().toISOString().slice(0,10);console.log(`Logs: ~/.claude-mem/logs/worker-${t}.log`),process.exit(0)}else console.error(`Failed to start: ${s.error}`),process.exit(1);break}case"stop":await p.stop(),console.log("Worker stopped"),process.exit(0);case"restart":{let s=await p.restart(W);s.success?(console.log(`Worker restarted (PID: ${s.pid})`),process.exit(0)):(console.error(`Failed to restart: ${s.error}`),process.exit(1));break}case"status":{let s=await p.status();s.running?(console.log("Worker is running"),console.log(` PID: ${s.pid}`),console.log(` Port: ${s.port}`),console.log(` Uptime: ${s.uptime}`)):console.log("Worker is not running"),process.exit(0)}default:console.log("Usage: worker-cli.js "),process.exit(1)}}ft().catch(s=>{console.error(s),process.exit(1)}); diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index 71296ccc..d6b0e337 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -541,7 +541,7 @@ No previous sessions found for this project yet.`;let v=p.slice(0,r.sessionCount `):null;if(e){let oe=G?`${se.dim}${fe}${se.reset}`:" ".repeat(fe.length),Be=r.showReadTokens&&H>0?`${se.dim}(~${H}t)${se.reset}`:"",Ge=r.showWorkTokens&&W>0?`${se.dim}(${re} ${W.toLocaleString()}t)${se.reset}`:"";m.push(` ${se.dim}#${J.id}${se.reset} ${oe} ${Ee} ${se.bright}${De}${se.reset}`),ge&&m.push(` ${se.dim}${ge}${se.reset}`),(Be||Ge)&&m.push(` ${Be} ${Ge}`),m.push("")}else{K&&(m.push(""),K=!1),m.push(`**#${J.id}** ${Q||"\u2033"} ${Ee} **${De}**`),ge&&(m.push(""),m.push(ge),m.push(""));let oe=[];r.showReadTokens&&oe.push(`Read: ~${H}`),r.showWorkTokens&&oe.push(`Work: ${ue}`),oe.length>0&&m.push(oe.join(", ")),m.push(""),X=null}}else if(e){let ge=G?`${se.dim}${fe}${se.reset}`:" ".repeat(fe.length),oe=r.showReadTokens&&H>0?`${se.dim}(~${H}t)${se.reset}`:"",Be=r.showWorkTokens&&W>0?`${se.dim}(${re} ${W.toLocaleString()}t)${se.reset}`:"";m.push(` ${se.dim}#${J.id}${se.reset} ${ge} ${Ee} ${De} ${oe} ${Be}`)}else{let ge=r.showReadTokens?`~${H}`:"",oe=r.showWorkTokens?ue:"";m.push(`| #${J.id} | ${Q||"\u2033"} | ${Ee} | ${De} | ${ge} | ${oe} |`)}}K&&m.push("")}let O=p[0],j=u[0];if(r.showLastSummary&&O&&(O.investigated||O.learned||O.completed||O.next_steps)&&(!j||O.created_at_epoch>j.created_at_epoch)&&(m.push(...Bl("Investigated",O.investigated,se.blue,e)),m.push(...Bl("Learned",O.learned,se.yellow,e)),m.push(...Bl("Completed",O.completed,se.green,e)),m.push(...Bl("Next Steps",O.next_steps,se.magenta,e))),d&&(m.push(""),m.push("---"),m.push(""),e?(m.push(`${se.bright}${se.magenta}\u{1F4CB} Previously${se.reset}`),m.push(""),m.push(`${se.dim}A: ${d}${se.reset}`)):(m.push("**\u{1F4CB} Previously**"),m.push(""),m.push(`A: ${d}`)),m.push("")),T&&b>0&&R>0){let z=Math.round(b/1e3);m.push(""),e?m.push(`${se.dim}\u{1F4B0} Access ${z}k tokens of past research & decisions for just ${g.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.${se.reset}`):m.push(`\u{1F4B0} Access ${z}k tokens of past research & decisions for just ${g.toLocaleString()}t. Use the mem-search skill to access memories by ID instead of re-reading files.`)}}return i?.close(),m.join(` `).trimEnd()}var io,zl,ei,m5,f1,v5,se,Wl=Ha(()=>{"use strict";io=bt(require("path"),1),zl=require("os"),ei=require("fs");ll();Xi();ft();ia();$f();m5=io.default.join((0,zl.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");f1=4,v5=1,se={reset:"\x1B[0m",bright:"\x1B[1m",dim:"\x1B[2m",cyan:"\x1B[36m",green:"\x1B[32m",yellow:"\x1B[33m",blue:"\x1B[34m",magenta:"\x1B[35m",gray:"\x1B[90m",red:"\x1B[31m"}});var S5={};iu(S5,{WorkerService:()=>Xl});module.exports=N1(S5);var x1=bt(od(),1),lo=bt(require("path"),1),_1=bt(require("fs"),1);var S={};iu(S,{BRAND:()=>aN,DIRTY:()=>ss,EMPTY_PATH:()=>jD,INVALID:()=>Te,NEVER:()=>UN,OK:()=>Ct,ParseStatus:()=>Tt,Schema:()=>He,ZodAny:()=>ka,ZodArray:()=>na,ZodBigInt:()=>is,ZodBoolean:()=>os,ZodBranded:()=>Hi,ZodCatch:()=>ys,ZodDate:()=>cs,ZodDefault:()=>gs,ZodDiscriminatedUnion:()=>Rc,ZodEffects:()=>pr,ZodEnum:()=>hs,ZodError:()=>Ht,ZodFirstPartyTypeKind:()=>Oe,ZodFunction:()=>Oc,ZodIntersection:()=>ds,ZodIssueCode:()=>ee,ZodLazy:()=>fs,ZodLiteral:()=>ms,ZodMap:()=>Pn,ZodNaN:()=>Cn,ZodNativeEnum:()=>vs,ZodNever:()=>Cr,ZodNull:()=>us,ZodNullable:()=>zr,ZodNumber:()=>ns,ZodObject:()=>Bt,ZodOptional:()=>lr,ZodParsedType:()=>pe,ZodPipeline:()=>Bi,ZodPromise:()=>Aa,ZodReadonly:()=>bs,ZodRecord:()=>Pc,ZodSchema:()=>He,ZodSet:()=>On,ZodString:()=>Ca,ZodSymbol:()=>Tn,ZodTransformer:()=>pr,ZodTuple:()=>Br,ZodType:()=>He,ZodUndefined:()=>ls,ZodUnion:()=>ps,ZodUnknown:()=>sa,ZodVoid:()=>Rn,addIssueToContext:()=>ie,any:()=>dN,array:()=>vN,bigint:()=>oN,boolean:()=>t0,coerce:()=>qN,custom:()=>Yx,date:()=>cN,datetimeRegex:()=>Xx,defaultErrorMap:()=>ra,discriminatedUnion:()=>xN,effect:()=>IN,enum:()=>CN,function:()=>RN,getErrorMap:()=>Sn,getParsedType:()=>Hr,instanceof:()=>nN,intersection:()=>_N,isAborted:()=>wc,isAsync:()=>En,isDirty:()=>Tc,isValid:()=>Oa,late:()=>sN,lazy:()=>PN,literal:()=>ON,makeIssue:()=>Ui,map:()=>wN,nan:()=>iN,nativeEnum:()=>kN,never:()=>mN,null:()=>pN,nullable:()=>NN,number:()=>e0,object:()=>gN,objectUtil:()=>cd,oboolean:()=>FN,onumber:()=>LN,optional:()=>DN,ostring:()=>MN,pipeline:()=>$N,preprocess:()=>jN,promise:()=>AN,quotelessJson:()=>ID,record:()=>EN,set:()=>TN,setErrorMap:()=>ND,strictObject:()=>yN,string:()=>Jx,symbol:()=>lN,transformer:()=>IN,tuple:()=>SN,undefined:()=>uN,union:()=>bN,unknown:()=>fN,util:()=>We,void:()=>hN});var We;(function(a){a.assertEqual=s=>{};function e(s){}a.assertIs=e;function r(s){throw new Error}a.assertNever=r,a.arrayToEnum=s=>{let i={};for(let n of s)i[n]=n;return i},a.getValidEnumValues=s=>{let i=a.objectKeys(s).filter(o=>typeof s[s[o]]!="number"),n={};for(let o of i)n[o]=s[o];return a.objectValues(n)},a.objectValues=s=>a.objectKeys(s).map(function(i){return s[i]}),a.objectKeys=typeof Object.keys=="function"?s=>Object.keys(s):s=>{let i=[];for(let n in s)Object.prototype.hasOwnProperty.call(s,n)&&i.push(n);return i},a.find=(s,i)=>{for(let n of s)if(i(n))return n},a.isInteger=typeof Number.isInteger=="function"?s=>Number.isInteger(s):s=>typeof s=="number"&&Number.isFinite(s)&&Math.floor(s)===s;function t(s,i=" | "){return s.map(n=>typeof n=="string"?`'${n}'`:n).join(i)}a.joinValues=t,a.jsonStringifyReplacer=(s,i)=>typeof i=="bigint"?i.toString():i})(We||(We={}));var cd;(function(a){a.mergeShapes=(e,r)=>({...e,...r})})(cd||(cd={}));var pe=We.arrayToEnum(["string","nan","number","integer","float","boolean","date","bigint","symbol","function","undefined","null","array","object","unknown","promise","void","never","map","set"]),Hr=a=>{switch(typeof a){case"undefined":return pe.undefined;case"string":return pe.string;case"number":return Number.isNaN(a)?pe.nan:pe.number;case"boolean":return pe.boolean;case"function":return pe.function;case"bigint":return pe.bigint;case"symbol":return pe.symbol;case"object":return Array.isArray(a)?pe.array:a===null?pe.null:a.then&&typeof a.then=="function"&&a.catch&&typeof a.catch=="function"?pe.promise:typeof Map<"u"&&a instanceof Map?pe.map:typeof Set<"u"&&a instanceof Set?pe.set:typeof Date<"u"&&a instanceof Date?pe.date:pe.object;default:return pe.unknown}};var ee=We.arrayToEnum(["invalid_type","invalid_literal","custom","invalid_union","invalid_union_discriminator","invalid_enum_value","unrecognized_keys","invalid_arguments","invalid_return_type","invalid_date","invalid_string","too_small","too_big","invalid_intersection_types","not_multiple_of","not_finite"]),ID=a=>JSON.stringify(a,null,2).replace(/"([^"]+)":/g,"$1:"),Ht=class a extends Error{get errors(){return this.issues}constructor(e){super(),this.issues=[],this.addIssue=t=>{this.issues=[...this.issues,t]},this.addIssues=(t=[])=>{this.issues=[...this.issues,...t]};let r=new.target.prototype;Object.setPrototypeOf?Object.setPrototypeOf(this,r):this.__proto__=r,this.name="ZodError",this.issues=e}format(e){let r=e||function(i){return i.message},t={_errors:[]},s=i=>{for(let n of i.issues)if(n.code==="invalid_union")n.unionErrors.map(s);else if(n.code==="invalid_return_type")s(n.returnTypeError);else if(n.code==="invalid_arguments")s(n.argumentsError);else if(n.path.length===0)t._errors.push(r(n));else{let o=t,l=0;for(;lr.message){let r={},t=[];for(let s of this.issues)if(s.path.length>0){let i=s.path[0];r[i]=r[i]||[],r[i].push(e(s))}else t.push(e(s));return{formErrors:t,fieldErrors:r}}get formErrors(){return this.flatten()}};Ht.create=a=>new Ht(a);var DD=(a,e)=>{let r;switch(a.code){case ee.invalid_type:a.received===pe.undefined?r="Required":r=`Expected ${a.expected}, received ${a.received}`;break;case ee.invalid_literal:r=`Invalid literal value, expected ${JSON.stringify(a.expected,We.jsonStringifyReplacer)}`;break;case ee.unrecognized_keys:r=`Unrecognized key(s) in object: ${We.joinValues(a.keys,", ")}`;break;case ee.invalid_union:r="Invalid input";break;case ee.invalid_union_discriminator:r=`Invalid discriminator value. Expected ${We.joinValues(a.options)}`;break;case ee.invalid_enum_value:r=`Invalid enum value. Expected ${We.joinValues(a.options)}, received '${a.received}'`;break;case ee.invalid_arguments:r="Invalid function arguments";break;case ee.invalid_return_type:r="Invalid function return type";break;case ee.invalid_date:r="Invalid date";break;case ee.invalid_string:typeof a.validation=="object"?"includes"in a.validation?(r=`Invalid input: must include "${a.validation.includes}"`,typeof a.validation.position=="number"&&(r=`${r} at one or more positions greater than or equal to ${a.validation.position}`)):"startsWith"in a.validation?r=`Invalid input: must start with "${a.validation.startsWith}"`:"endsWith"in a.validation?r=`Invalid input: must end with "${a.validation.endsWith}"`:We.assertNever(a.validation):a.validation!=="regex"?r=`Invalid ${a.validation}`:r="Invalid";break;case ee.too_small:a.type==="array"?r=`Array must contain ${a.exact?"exactly":a.inclusive?"at least":"more than"} ${a.minimum} element(s)`:a.type==="string"?r=`String must contain ${a.exact?"exactly":a.inclusive?"at least":"over"} ${a.minimum} character(s)`:a.type==="number"?r=`Number must be ${a.exact?"exactly equal to ":a.inclusive?"greater than or equal to ":"greater than "}${a.minimum}`:a.type==="bigint"?r=`Number must be ${a.exact?"exactly equal to ":a.inclusive?"greater than or equal to ":"greater than "}${a.minimum}`:a.type==="date"?r=`Date must be ${a.exact?"exactly equal to ":a.inclusive?"greater than or equal to ":"greater than "}${new Date(Number(a.minimum))}`:r="Invalid input";break;case ee.too_big:a.type==="array"?r=`Array must contain ${a.exact?"exactly":a.inclusive?"at most":"less than"} ${a.maximum} element(s)`:a.type==="string"?r=`String must contain ${a.exact?"exactly":a.inclusive?"at most":"under"} ${a.maximum} character(s)`:a.type==="number"?r=`Number must be ${a.exact?"exactly":a.inclusive?"less than or equal to":"less than"} ${a.maximum}`:a.type==="bigint"?r=`BigInt must be ${a.exact?"exactly":a.inclusive?"less than or equal to":"less than"} ${a.maximum}`:a.type==="date"?r=`Date must be ${a.exact?"exactly":a.inclusive?"smaller than or equal to":"smaller than"} ${new Date(Number(a.maximum))}`:r="Invalid input";break;case ee.custom:r="Invalid input";break;case ee.invalid_intersection_types:r="Intersection results could not be merged";break;case ee.not_multiple_of:r=`Number must be a multiple of ${a.multipleOf}`;break;case ee.not_finite:r="Number must be finite";break;default:r=e.defaultError,We.assertNever(a)}return{message:r}},ra=DD;var Vx=ra;function ND(a){Vx=a}function Sn(){return Vx}var Ui=a=>{let{data:e,path:r,errorMaps:t,issueData:s}=a,i=[...r,...s.path||[]],n={...s,path:i};if(s.message!==void 0)return{...s,path:i,message:s.message};let o="",l=t.filter(c=>!!c).slice().reverse();for(let c of l)o=c(n,{data:e,defaultError:o}).message;return{...s,path:i,message:o}},jD=[];function ie(a,e){let r=Sn(),t=Ui({issueData:e,data:a.data,path:a.path,errorMaps:[a.common.contextualErrorMap,a.schemaErrorMap,r,r===ra?void 0:ra].filter(s=>!!s)});a.common.issues.push(t)}var Tt=class a{constructor(){this.value="valid"}dirty(){this.value==="valid"&&(this.value="dirty")}abort(){this.value!=="aborted"&&(this.value="aborted")}static mergeArray(e,r){let t=[];for(let s of r){if(s.status==="aborted")return Te;s.status==="dirty"&&e.dirty(),t.push(s.value)}return{status:e.value,value:t}}static async mergeObjectAsync(e,r){let t=[];for(let s of r){let i=await s.key,n=await s.value;t.push({key:i,value:n})}return a.mergeObjectSync(e,t)}static mergeObjectSync(e,r){let t={};for(let s of r){let{key:i,value:n}=s;if(i.status==="aborted"||n.status==="aborted")return Te;i.status==="dirty"&&e.dirty(),n.status==="dirty"&&e.dirty(),i.value!=="__proto__"&&(typeof n.value<"u"||s.alwaysSet)&&(t[i.value]=n.value)}return{status:e.value,value:t}}},Te=Object.freeze({status:"aborted"}),ss=a=>({status:"dirty",value:a}),Ct=a=>({status:"valid",value:a}),wc=a=>a.status==="aborted",Tc=a=>a.status==="dirty",Oa=a=>a.status==="valid",En=a=>typeof Promise<"u"&&a instanceof Promise;var ve;(function(a){a.errToObj=e=>typeof e=="string"?{message:e}:e||{},a.toString=e=>typeof e=="string"?e:e?.message})(ve||(ve={}));var ur=class{constructor(e,r,t,s){this._cachedPath=[],this.parent=e,this.data=r,this._path=t,this._key=s}get path(){return this._cachedPath.length||(Array.isArray(this._key)?this._cachedPath.push(...this._path,...this._key):this._cachedPath.push(...this._path,this._key)),this._cachedPath}},Wx=(a,e)=>{if(Oa(e))return{success:!0,data:e.value};if(!a.common.issues.length)throw new Error("Validation failed but no issues detected.");return{success:!1,get error(){if(this._error)return this._error;let r=new Ht(a.common.issues);return this._error=r,this._error}}};function Le(a){if(!a)return{};let{errorMap:e,invalid_type_error:r,required_error:t,description:s}=a;if(e&&(r||t))throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);return e?{errorMap:e,description:s}:{errorMap:(n,o)=>{let{message:l}=a;return n.code==="invalid_enum_value"?{message:l??o.defaultError}:typeof o.data>"u"?{message:l??t??o.defaultError}:n.code!=="invalid_type"?{message:o.defaultError}:{message:l??r??o.defaultError}},description:s}}var He=class{get description(){return this._def.description}_getType(e){return Hr(e.data)}_getOrReturnCtx(e,r){return r||{common:e.parent.common,data:e.data,parsedType:Hr(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}_processInputParams(e){return{status:new Tt,ctx:{common:e.parent.common,data:e.data,parsedType:Hr(e.data),schemaErrorMap:this._def.errorMap,path:e.path,parent:e.parent}}}_parseSync(e){let r=this._parse(e);if(En(r))throw new Error("Synchronous parse encountered promise.");return r}_parseAsync(e){let r=this._parse(e);return Promise.resolve(r)}parse(e,r){let t=this.safeParse(e,r);if(t.success)return t.data;throw t.error}safeParse(e,r){let t={common:{issues:[],async:r?.async??!1,contextualErrorMap:r?.errorMap},path:r?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Hr(e)},s=this._parseSync({data:e,path:t.path,parent:t});return Wx(t,s)}"~validate"(e){let r={common:{issues:[],async:!!this["~standard"].async},path:[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Hr(e)};if(!this["~standard"].async)try{let t=this._parseSync({data:e,path:[],parent:r});return Oa(t)?{value:t.value}:{issues:r.common.issues}}catch(t){t?.message?.toLowerCase()?.includes("encountered")&&(this["~standard"].async=!0),r.common={issues:[],async:!0}}return this._parseAsync({data:e,path:[],parent:r}).then(t=>Oa(t)?{value:t.value}:{issues:r.common.issues})}async parseAsync(e,r){let t=await this.safeParseAsync(e,r);if(t.success)return t.data;throw t.error}async safeParseAsync(e,r){let t={common:{issues:[],contextualErrorMap:r?.errorMap,async:!0},path:r?.path||[],schemaErrorMap:this._def.errorMap,parent:null,data:e,parsedType:Hr(e)},s=this._parse({data:e,path:t.path,parent:t}),i=await(En(s)?s:Promise.resolve(s));return Wx(t,i)}refine(e,r){let t=s=>typeof r=="string"||typeof r>"u"?{message:r}:typeof r=="function"?r(s):r;return this._refinement((s,i)=>{let n=e(s),o=()=>i.addIssue({code:ee.custom,...t(s)});return typeof Promise<"u"&&n instanceof Promise?n.then(l=>l?!0:(o(),!1)):n?!0:(o(),!1)})}refinement(e,r){return this._refinement((t,s)=>e(t)?!0:(s.addIssue(typeof r=="function"?r(t,s):r),!1))}_refinement(e){return new pr({schema:this,typeName:Oe.ZodEffects,effect:{type:"refinement",refinement:e}})}superRefine(e){return this._refinement(e)}constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this.parse.bind(this),this.safeParse=this.safeParse.bind(this),this.parseAsync=this.parseAsync.bind(this),this.safeParseAsync=this.safeParseAsync.bind(this),this.spa=this.spa.bind(this),this.refine=this.refine.bind(this),this.refinement=this.refinement.bind(this),this.superRefine=this.superRefine.bind(this),this.optional=this.optional.bind(this),this.nullable=this.nullable.bind(this),this.nullish=this.nullish.bind(this),this.array=this.array.bind(this),this.promise=this.promise.bind(this),this.or=this.or.bind(this),this.and=this.and.bind(this),this.transform=this.transform.bind(this),this.brand=this.brand.bind(this),this.default=this.default.bind(this),this.catch=this.catch.bind(this),this.describe=this.describe.bind(this),this.pipe=this.pipe.bind(this),this.readonly=this.readonly.bind(this),this.isNullable=this.isNullable.bind(this),this.isOptional=this.isOptional.bind(this),this["~standard"]={version:1,vendor:"zod",validate:r=>this["~validate"](r)}}optional(){return lr.create(this,this._def)}nullable(){return zr.create(this,this._def)}nullish(){return this.nullable().optional()}array(){return na.create(this)}promise(){return Aa.create(this,this._def)}or(e){return ps.create([this,e],this._def)}and(e){return ds.create(this,e,this._def)}transform(e){return new pr({...Le(this._def),schema:this,typeName:Oe.ZodEffects,effect:{type:"transform",transform:e}})}default(e){let r=typeof e=="function"?e:()=>e;return new gs({...Le(this._def),innerType:this,defaultValue:r,typeName:Oe.ZodDefault})}brand(){return new Hi({typeName:Oe.ZodBranded,type:this,...Le(this._def)})}catch(e){let r=typeof e=="function"?e:()=>e;return new ys({...Le(this._def),innerType:this,catchValue:r,typeName:Oe.ZodCatch})}describe(e){let r=this.constructor;return new r({...this._def,description:e})}pipe(e){return Bi.create(this,e)}readonly(){return bs.create(this)}isOptional(){return this.safeParse(void 0).success}isNullable(){return this.safeParse(null).success}},$D=/^c[^\s-]{8,}$/i,MD=/^[0-9a-z]+$/,LD=/^[0-9A-HJKMNP-TV-Z]{26}$/i,FD=/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i,qD=/^[a-z0-9_-]{21}$/i,UD=/^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/,HD=/^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/,BD=/^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i,zD="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$",ld,VD=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,WD=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/,GD=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,ZD=/^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,KD=/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/,XD=/^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/,Zx="((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))",QD=new RegExp(`^${Zx}$`);function Kx(a){let e="[0-5]\\d";a.precision?e=`${e}\\.\\d{${a.precision}}`:a.precision==null&&(e=`${e}(\\.\\d+)?`);let r=a.precision?"+":"?";return`([01]\\d|2[0-3]):[0-5]\\d(:${e})${r}`}function YD(a){return new RegExp(`^${Kx(a)}$`)}function Xx(a){let e=`${Zx}T${Kx(a)}`,r=[];return r.push(a.local?"Z?":"Z"),a.offset&&r.push("([+-]\\d{2}:?\\d{2})"),e=`${e}(${r.join("|")})`,new RegExp(`^${e}$`)}function JD(a,e){return!!((e==="v4"||!e)&&VD.test(a)||(e==="v6"||!e)&&GD.test(a))}function eN(a,e){if(!UD.test(a))return!1;try{let[r]=a.split(".");if(!r)return!1;let t=r.replace(/-/g,"+").replace(/_/g,"/").padEnd(r.length+(4-r.length%4)%4,"="),s=JSON.parse(atob(t));return!(typeof s!="object"||s===null||"typ"in s&&s?.typ!=="JWT"||!s.alg||e&&s.alg!==e)}catch{return!1}}function tN(a,e){return!!((e==="v4"||!e)&&WD.test(a)||(e==="v6"||!e)&&ZD.test(a))}var Ca=class a extends He{_parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!==pe.string){let i=this._getOrReturnCtx(e);return ie(i,{code:ee.invalid_type,expected:pe.string,received:i.parsedType}),Te}let t=new Tt,s;for(let i of this._def.checks)if(i.kind==="min")e.data.lengthi.value&&(s=this._getOrReturnCtx(e,s),ie(s,{code:ee.too_big,maximum:i.value,type:"string",inclusive:!0,exact:!1,message:i.message}),t.dirty());else if(i.kind==="length"){let n=e.data.length>i.value,o=e.data.lengthe.test(s),{validation:r,code:ee.invalid_string,...ve.errToObj(t)})}_addCheck(e){return new a({...this._def,checks:[...this._def.checks,e]})}email(e){return this._addCheck({kind:"email",...ve.errToObj(e)})}url(e){return this._addCheck({kind:"url",...ve.errToObj(e)})}emoji(e){return this._addCheck({kind:"emoji",...ve.errToObj(e)})}uuid(e){return this._addCheck({kind:"uuid",...ve.errToObj(e)})}nanoid(e){return this._addCheck({kind:"nanoid",...ve.errToObj(e)})}cuid(e){return this._addCheck({kind:"cuid",...ve.errToObj(e)})}cuid2(e){return this._addCheck({kind:"cuid2",...ve.errToObj(e)})}ulid(e){return this._addCheck({kind:"ulid",...ve.errToObj(e)})}base64(e){return this._addCheck({kind:"base64",...ve.errToObj(e)})}base64url(e){return this._addCheck({kind:"base64url",...ve.errToObj(e)})}jwt(e){return this._addCheck({kind:"jwt",...ve.errToObj(e)})}ip(e){return this._addCheck({kind:"ip",...ve.errToObj(e)})}cidr(e){return this._addCheck({kind:"cidr",...ve.errToObj(e)})}datetime(e){return typeof e=="string"?this._addCheck({kind:"datetime",precision:null,offset:!1,local:!1,message:e}):this._addCheck({kind:"datetime",precision:typeof e?.precision>"u"?null:e?.precision,offset:e?.offset??!1,local:e?.local??!1,...ve.errToObj(e?.message)})}date(e){return this._addCheck({kind:"date",message:e})}time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:null,message:e}):this._addCheck({kind:"time",precision:typeof e?.precision>"u"?null:e?.precision,...ve.errToObj(e?.message)})}duration(e){return this._addCheck({kind:"duration",...ve.errToObj(e)})}regex(e,r){return this._addCheck({kind:"regex",regex:e,...ve.errToObj(r)})}includes(e,r){return this._addCheck({kind:"includes",value:e,position:r?.position,...ve.errToObj(r?.message)})}startsWith(e,r){return this._addCheck({kind:"startsWith",value:e,...ve.errToObj(r)})}endsWith(e,r){return this._addCheck({kind:"endsWith",value:e,...ve.errToObj(r)})}min(e,r){return this._addCheck({kind:"min",value:e,...ve.errToObj(r)})}max(e,r){return this._addCheck({kind:"max",value:e,...ve.errToObj(r)})}length(e,r){return this._addCheck({kind:"length",value:e,...ve.errToObj(r)})}nonempty(e){return this.min(1,ve.errToObj(e))}trim(){return new a({...this._def,checks:[...this._def.checks,{kind:"trim"}]})}toLowerCase(){return new a({...this._def,checks:[...this._def.checks,{kind:"toLowerCase"}]})}toUpperCase(){return new a({...this._def,checks:[...this._def.checks,{kind:"toUpperCase"}]})}get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}get minLength(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxLength(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuenew Ca({checks:[],typeName:Oe.ZodString,coerce:a?.coerce??!1,...Le(a)});function rN(a,e){let r=(a.toString().split(".")[1]||"").length,t=(e.toString().split(".")[1]||"").length,s=r>t?r:t,i=Number.parseInt(a.toFixed(s).replace(".","")),n=Number.parseInt(e.toFixed(s).replace(".",""));return i%n/10**s}var ns=class a extends He{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,this.step=this.multipleOf}_parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!==pe.number){let i=this._getOrReturnCtx(e);return ie(i,{code:ee.invalid_type,expected:pe.number,received:i.parsedType}),Te}let t,s=new Tt;for(let i of this._def.checks)i.kind==="int"?We.isInteger(e.data)||(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.invalid_type,expected:"integer",received:"float",message:i.message}),s.dirty()):i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.too_big,maximum:i.value,type:"number",inclusive:i.inclusive,exact:!1,message:i.message}),s.dirty()):i.kind==="multipleOf"?rN(e.data,i.value)!==0&&(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.not_multiple_of,multipleOf:i.value,message:i.message}),s.dirty()):i.kind==="finite"?Number.isFinite(e.data)||(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.not_finite,message:i.message}),s.dirty()):We.assertNever(i);return{status:s.value,value:e.data}}gte(e,r){return this.setLimit("min",e,!0,ve.toString(r))}gt(e,r){return this.setLimit("min",e,!1,ve.toString(r))}lte(e,r){return this.setLimit("max",e,!0,ve.toString(r))}lt(e,r){return this.setLimit("max",e,!1,ve.toString(r))}setLimit(e,r,t,s){return new a({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:t,message:ve.toString(s)}]})}_addCheck(e){return new a({...this._def,checks:[...this._def.checks,e]})}int(e){return this._addCheck({kind:"int",message:ve.toString(e)})}positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,message:ve.toString(e)})}negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,message:ve.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,message:ve.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,message:ve.toString(e)})}multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message:ve.toString(r)})}finite(e){return this._addCheck({kind:"finite",message:ve.toString(e)})}safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_SAFE_INTEGER,message:ve.toString(e)})._addCheck({kind:"max",inclusive:!0,value:Number.MAX_SAFE_INTEGER,message:ve.toString(e)})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuee.kind==="int"||e.kind==="multipleOf"&&We.isInteger(e.value))}get isFinite(){let e=null,r=null;for(let t of this._def.checks){if(t.kind==="finite"||t.kind==="int"||t.kind==="multipleOf")return!0;t.kind==="min"?(r===null||t.value>r)&&(r=t.value):t.kind==="max"&&(e===null||t.valuenew ns({checks:[],typeName:Oe.ZodNumber,coerce:a?.coerce||!1,...Le(a)});var is=class a extends He{constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}_parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return this._getInvalidInput(e)}if(this._getType(e)!==pe.bigint)return this._getInvalidInput(e);let t,s=new Tt;for(let i of this._def.checks)i.kind==="min"?(i.inclusive?e.datai.value:e.data>=i.value)&&(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.too_big,type:"bigint",maximum:i.value,inclusive:i.inclusive,message:i.message}),s.dirty()):i.kind==="multipleOf"?e.data%i.value!==BigInt(0)&&(t=this._getOrReturnCtx(e,t),ie(t,{code:ee.not_multiple_of,multipleOf:i.value,message:i.message}),s.dirty()):We.assertNever(i);return{status:s.value,value:e.data}}_getInvalidInput(e){let r=this._getOrReturnCtx(e);return ie(r,{code:ee.invalid_type,expected:pe.bigint,received:r.parsedType}),Te}gte(e,r){return this.setLimit("min",e,!0,ve.toString(r))}gt(e,r){return this.setLimit("min",e,!1,ve.toString(r))}lte(e,r){return this.setLimit("max",e,!0,ve.toString(r))}lt(e,r){return this.setLimit("max",e,!1,ve.toString(r))}setLimit(e,r,t,s){return new a({...this._def,checks:[...this._def.checks,{kind:e,value:r,inclusive:t,message:ve.toString(s)}]})}_addCheck(e){return new a({...this._def,checks:[...this._def.checks,e]})}positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!1,message:ve.toString(e)})}negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!1,message:ve.toString(e)})}nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:!0,message:ve.toString(e)})}nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:!0,message:ve.toString(e)})}multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message:ve.toString(r)})}get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e}get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuenew is({checks:[],typeName:Oe.ZodBigInt,coerce:a?.coerce??!1,...Le(a)});var os=class extends He{_parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==pe.boolean){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.boolean,received:t.parsedType}),Te}return Ct(e.data)}};os.create=a=>new os({typeName:Oe.ZodBoolean,coerce:a?.coerce||!1,...Le(a)});var cs=class a extends He{_parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e)!==pe.date){let i=this._getOrReturnCtx(e);return ie(i,{code:ee.invalid_type,expected:pe.date,received:i.parsedType}),Te}if(Number.isNaN(e.data.getTime())){let i=this._getOrReturnCtx(e);return ie(i,{code:ee.invalid_date}),Te}let t=new Tt,s;for(let i of this._def.checks)i.kind==="min"?e.data.getTime()i.value&&(s=this._getOrReturnCtx(e,s),ie(s,{code:ee.too_big,message:i.message,inclusive:!0,exact:!1,maximum:i.value,type:"date"}),t.dirty()):We.assertNever(i);return{status:t.value,value:new Date(e.data.getTime())}}_addCheck(e){return new a({...this._def,checks:[...this._def.checks,e]})}min(e,r){return this._addCheck({kind:"min",value:e.getTime(),message:ve.toString(r)})}max(e,r){return this._addCheck({kind:"max",value:e.getTime(),message:ve.toString(r)})}get minDate(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(e===null||r.value>e)&&(e=r.value);return e!=null?new Date(e):null}get maxDate(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(e===null||r.valuenew cs({checks:[],coerce:a?.coerce||!1,typeName:Oe.ZodDate,...Le(a)});var Tn=class extends He{_parse(e){if(this._getType(e)!==pe.symbol){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.symbol,received:t.parsedType}),Te}return Ct(e.data)}};Tn.create=a=>new Tn({typeName:Oe.ZodSymbol,...Le(a)});var ls=class extends He{_parse(e){if(this._getType(e)!==pe.undefined){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.undefined,received:t.parsedType}),Te}return Ct(e.data)}};ls.create=a=>new ls({typeName:Oe.ZodUndefined,...Le(a)});var us=class extends He{_parse(e){if(this._getType(e)!==pe.null){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.null,received:t.parsedType}),Te}return Ct(e.data)}};us.create=a=>new us({typeName:Oe.ZodNull,...Le(a)});var ka=class extends He{constructor(){super(...arguments),this._any=!0}_parse(e){return Ct(e.data)}};ka.create=a=>new ka({typeName:Oe.ZodAny,...Le(a)});var sa=class extends He{constructor(){super(...arguments),this._unknown=!0}_parse(e){return Ct(e.data)}};sa.create=a=>new sa({typeName:Oe.ZodUnknown,...Le(a)});var Cr=class extends He{_parse(e){let r=this._getOrReturnCtx(e);return ie(r,{code:ee.invalid_type,expected:pe.never,received:r.parsedType}),Te}};Cr.create=a=>new Cr({typeName:Oe.ZodNever,...Le(a)});var Rn=class extends He{_parse(e){if(this._getType(e)!==pe.undefined){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.void,received:t.parsedType}),Te}return Ct(e.data)}};Rn.create=a=>new Rn({typeName:Oe.ZodVoid,...Le(a)});var na=class a extends He{_parse(e){let{ctx:r,status:t}=this._processInputParams(e),s=this._def;if(r.parsedType!==pe.array)return ie(r,{code:ee.invalid_type,expected:pe.array,received:r.parsedType}),Te;if(s.exactLength!==null){let n=r.data.length>s.exactLength.value,o=r.data.lengths.maxLength.value&&(ie(r,{code:ee.too_big,maximum:s.maxLength.value,type:"array",inclusive:!0,exact:!1,message:s.maxLength.message}),t.dirty()),r.common.async)return Promise.all([...r.data].map((n,o)=>s.type._parseAsync(new ur(r,n,r.path,o)))).then(n=>Tt.mergeArray(t,n));let i=[...r.data].map((n,o)=>s.type._parseSync(new ur(r,n,r.path,o)));return Tt.mergeArray(t,i)}get element(){return this._def.type}min(e,r){return new a({...this._def,minLength:{value:e,message:ve.toString(r)}})}max(e,r){return new a({...this._def,maxLength:{value:e,message:ve.toString(r)}})}length(e,r){return new a({...this._def,exactLength:{value:e,message:ve.toString(r)}})}nonempty(e){return this.min(1,e)}};na.create=(a,e)=>new na({type:a,minLength:null,maxLength:null,exactLength:null,typeName:Oe.ZodArray,...Le(e)});function wn(a){if(a instanceof Bt){let e={};for(let r in a.shape){let t=a.shape[r];e[r]=lr.create(wn(t))}return new Bt({...a._def,shape:()=>e})}else return a instanceof na?new na({...a._def,type:wn(a.element)}):a instanceof lr?lr.create(wn(a.unwrap())):a instanceof zr?zr.create(wn(a.unwrap())):a instanceof Br?Br.create(a.items.map(e=>wn(e))):a}var Bt=class a extends He{constructor(){super(...arguments),this._cached=null,this.nonstrict=this.passthrough,this.augment=this.extend}_getCached(){if(this._cached!==null)return this._cached;let e=this._def.shape(),r=We.objectKeys(e);return this._cached={shape:e,keys:r},this._cached}_parse(e){if(this._getType(e)!==pe.object){let c=this._getOrReturnCtx(e);return ie(c,{code:ee.invalid_type,expected:pe.object,received:c.parsedType}),Te}let{status:t,ctx:s}=this._processInputParams(e),{shape:i,keys:n}=this._getCached(),o=[];if(!(this._def.catchall instanceof Cr&&this._def.unknownKeys==="strip"))for(let c in s.data)n.includes(c)||o.push(c);let l=[];for(let c of n){let u=i[c],p=s.data[c];l.push({key:{status:"valid",value:c},value:u._parse(new ur(s,p,s.path,c)),alwaysSet:c in s.data})}if(this._def.catchall instanceof Cr){let c=this._def.unknownKeys;if(c==="passthrough")for(let u of o)l.push({key:{status:"valid",value:u},value:{status:"valid",value:s.data[u]}});else if(c==="strict")o.length>0&&(ie(s,{code:ee.unrecognized_keys,keys:o}),t.dirty());else if(c!=="strip")throw new Error("Internal ZodObject error: invalid unknownKeys value.")}else{let c=this._def.catchall;for(let u of o){let p=s.data[u];l.push({key:{status:"valid",value:u},value:c._parse(new ur(s,p,s.path,u)),alwaysSet:u in s.data})}}return s.common.async?Promise.resolve().then(async()=>{let c=[];for(let u of l){let p=await u.key,f=await u.value;c.push({key:p,value:f,alwaysSet:u.alwaysSet})}return c}).then(c=>Tt.mergeObjectSync(t,c)):Tt.mergeObjectSync(t,l)}get shape(){return this._def.shape()}strict(e){return ve.errToObj,new a({...this._def,unknownKeys:"strict",...e!==void 0?{errorMap:(r,t)=>{let s=this._def.errorMap?.(r,t).message??t.defaultError;return r.code==="unrecognized_keys"?{message:ve.errToObj(e).message??s}:{message:s}}}:{}})}strip(){return new a({...this._def,unknownKeys:"strip"})}passthrough(){return new a({...this._def,unknownKeys:"passthrough"})}extend(e){return new a({...this._def,shape:()=>({...this._def.shape(),...e})})}merge(e){return new a({unknownKeys:e._def.unknownKeys,catchall:e._def.catchall,shape:()=>({...this._def.shape(),...e._def.shape()}),typeName:Oe.ZodObject})}setKey(e,r){return this.augment({[e]:r})}catchall(e){return new a({...this._def,catchall:e})}pick(e){let r={};for(let t of We.objectKeys(e))e[t]&&this.shape[t]&&(r[t]=this.shape[t]);return new a({...this._def,shape:()=>r})}omit(e){let r={};for(let t of We.objectKeys(this.shape))e[t]||(r[t]=this.shape[t]);return new a({...this._def,shape:()=>r})}deepPartial(){return wn(this)}partial(e){let r={};for(let t of We.objectKeys(this.shape)){let s=this.shape[t];e&&!e[t]?r[t]=s:r[t]=s.optional()}return new a({...this._def,shape:()=>r})}required(e){let r={};for(let t of We.objectKeys(this.shape))if(e&&!e[t])r[t]=this.shape[t];else{let i=this.shape[t];for(;i instanceof lr;)i=i._def.innerType;r[t]=i}return new a({...this._def,shape:()=>r})}keyof(){return Qx(We.objectKeys(this.shape))}};Bt.create=(a,e)=>new Bt({shape:()=>a,unknownKeys:"strip",catchall:Cr.create(),typeName:Oe.ZodObject,...Le(e)});Bt.strictCreate=(a,e)=>new Bt({shape:()=>a,unknownKeys:"strict",catchall:Cr.create(),typeName:Oe.ZodObject,...Le(e)});Bt.lazycreate=(a,e)=>new Bt({shape:a,unknownKeys:"strip",catchall:Cr.create(),typeName:Oe.ZodObject,...Le(e)});var ps=class extends He{_parse(e){let{ctx:r}=this._processInputParams(e),t=this._def.options;function s(i){for(let o of i)if(o.result.status==="valid")return o.result;for(let o of i)if(o.result.status==="dirty")return r.common.issues.push(...o.ctx.common.issues),o.result;let n=i.map(o=>new Ht(o.ctx.common.issues));return ie(r,{code:ee.invalid_union,unionErrors:n}),Te}if(r.common.async)return Promise.all(t.map(async i=>{let n={...r,common:{...r.common,issues:[]},parent:null};return{result:await i._parseAsync({data:r.data,path:r.path,parent:n}),ctx:n}})).then(s);{let i,n=[];for(let l of t){let c={...r,common:{...r.common,issues:[]},parent:null},u=l._parseSync({data:r.data,path:r.path,parent:c});if(u.status==="valid")return u;u.status==="dirty"&&!i&&(i={result:u,ctx:c}),c.common.issues.length&&n.push(c.common.issues)}if(i)return r.common.issues.push(...i.ctx.common.issues),i.result;let o=n.map(l=>new Ht(l));return ie(r,{code:ee.invalid_union,unionErrors:o}),Te}}get options(){return this._def.options}};ps.create=(a,e)=>new ps({options:a,typeName:Oe.ZodUnion,...Le(e)});var aa=a=>a instanceof fs?aa(a.schema):a instanceof pr?aa(a.innerType()):a instanceof ms?[a.value]:a instanceof hs?a.options:a instanceof vs?We.objectValues(a.enum):a instanceof gs?aa(a._def.innerType):a instanceof ls?[void 0]:a instanceof us?[null]:a instanceof lr?[void 0,...aa(a.unwrap())]:a instanceof zr?[null,...aa(a.unwrap())]:a instanceof Hi||a instanceof bs?aa(a.unwrap()):a instanceof ys?aa(a._def.innerType):[],Rc=class a extends He{_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==pe.object)return ie(r,{code:ee.invalid_type,expected:pe.object,received:r.parsedType}),Te;let t=this.discriminator,s=r.data[t],i=this.optionsMap.get(s);return i?r.common.async?i._parseAsync({data:r.data,path:r.path,parent:r}):i._parseSync({data:r.data,path:r.path,parent:r}):(ie(r,{code:ee.invalid_union_discriminator,options:Array.from(this.optionsMap.keys()),path:[t]}),Te)}get discriminator(){return this._def.discriminator}get options(){return this._def.options}get optionsMap(){return this._def.optionsMap}static create(e,r,t){let s=new Map;for(let i of r){let n=aa(i.shape[e]);if(!n.length)throw new Error(`A discriminator value for key \`${e}\` could not be extracted from all schema options`);for(let o of n){if(s.has(o))throw new Error(`Discriminator property ${String(e)} has duplicate value ${String(o)}`);s.set(o,i)}}return new a({typeName:Oe.ZodDiscriminatedUnion,discriminator:e,options:r,optionsMap:s,...Le(t)})}};function ud(a,e){let r=Hr(a),t=Hr(e);if(a===e)return{valid:!0,data:a};if(r===pe.object&&t===pe.object){let s=We.objectKeys(e),i=We.objectKeys(a).filter(o=>s.indexOf(o)!==-1),n={...a,...e};for(let o of i){let l=ud(a[o],e[o]);if(!l.valid)return{valid:!1};n[o]=l.data}return{valid:!0,data:n}}else if(r===pe.array&&t===pe.array){if(a.length!==e.length)return{valid:!1};let s=[];for(let i=0;i{if(wc(i)||wc(n))return Te;let o=ud(i.value,n.value);return o.valid?((Tc(i)||Tc(n))&&r.dirty(),{status:r.value,value:o.data}):(ie(t,{code:ee.invalid_intersection_types}),Te)};return t.common.async?Promise.all([this._def.left._parseAsync({data:t.data,path:t.path,parent:t}),this._def.right._parseAsync({data:t.data,path:t.path,parent:t})]).then(([i,n])=>s(i,n)):s(this._def.left._parseSync({data:t.data,path:t.path,parent:t}),this._def.right._parseSync({data:t.data,path:t.path,parent:t}))}};ds.create=(a,e,r)=>new ds({left:a,right:e,typeName:Oe.ZodIntersection,...Le(r)});var Br=class a extends He{_parse(e){let{status:r,ctx:t}=this._processInputParams(e);if(t.parsedType!==pe.array)return ie(t,{code:ee.invalid_type,expected:pe.array,received:t.parsedType}),Te;if(t.data.lengththis._def.items.length&&(ie(t,{code:ee.too_big,maximum:this._def.items.length,inclusive:!0,exact:!1,type:"array"}),r.dirty());let i=[...t.data].map((n,o)=>{let l=this._def.items[o]||this._def.rest;return l?l._parse(new ur(t,n,t.path,o)):null}).filter(n=>!!n);return t.common.async?Promise.all(i).then(n=>Tt.mergeArray(r,n)):Tt.mergeArray(r,i)}get items(){return this._def.items}rest(e){return new a({...this._def,rest:e})}};Br.create=(a,e)=>{if(!Array.isArray(a))throw new Error("You must pass an array of schemas to z.tuple([ ... ])");return new Br({items:a,typeName:Oe.ZodTuple,rest:null,...Le(e)})};var Pc=class a extends He{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:r,ctx:t}=this._processInputParams(e);if(t.parsedType!==pe.object)return ie(t,{code:ee.invalid_type,expected:pe.object,received:t.parsedType}),Te;let s=[],i=this._def.keyType,n=this._def.valueType;for(let o in t.data)s.push({key:i._parse(new ur(t,o,t.path,o)),value:n._parse(new ur(t,t.data[o],t.path,o)),alwaysSet:o in t.data});return t.common.async?Tt.mergeObjectAsync(r,s):Tt.mergeObjectSync(r,s)}get element(){return this._def.valueType}static create(e,r,t){return r instanceof He?new a({keyType:e,valueType:r,typeName:Oe.ZodRecord,...Le(t)}):new a({keyType:Ca.create(),valueType:e,typeName:Oe.ZodRecord,...Le(r)})}},Pn=class extends He{get keySchema(){return this._def.keyType}get valueSchema(){return this._def.valueType}_parse(e){let{status:r,ctx:t}=this._processInputParams(e);if(t.parsedType!==pe.map)return ie(t,{code:ee.invalid_type,expected:pe.map,received:t.parsedType}),Te;let s=this._def.keyType,i=this._def.valueType,n=[...t.data.entries()].map(([o,l],c)=>({key:s._parse(new ur(t,o,t.path,[c,"key"])),value:i._parse(new ur(t,l,t.path,[c,"value"]))}));if(t.common.async){let o=new Map;return Promise.resolve().then(async()=>{for(let l of n){let c=await l.key,u=await l.value;if(c.status==="aborted"||u.status==="aborted")return Te;(c.status==="dirty"||u.status==="dirty")&&r.dirty(),o.set(c.value,u.value)}return{status:r.value,value:o}})}else{let o=new Map;for(let l of n){let c=l.key,u=l.value;if(c.status==="aborted"||u.status==="aborted")return Te;(c.status==="dirty"||u.status==="dirty")&&r.dirty(),o.set(c.value,u.value)}return{status:r.value,value:o}}}};Pn.create=(a,e,r)=>new Pn({valueType:e,keyType:a,typeName:Oe.ZodMap,...Le(r)});var On=class a extends He{_parse(e){let{status:r,ctx:t}=this._processInputParams(e);if(t.parsedType!==pe.set)return ie(t,{code:ee.invalid_type,expected:pe.set,received:t.parsedType}),Te;let s=this._def;s.minSize!==null&&t.data.sizes.maxSize.value&&(ie(t,{code:ee.too_big,maximum:s.maxSize.value,type:"set",inclusive:!0,exact:!1,message:s.maxSize.message}),r.dirty());let i=this._def.valueType;function n(l){let c=new Set;for(let u of l){if(u.status==="aborted")return Te;u.status==="dirty"&&r.dirty(),c.add(u.value)}return{status:r.value,value:c}}let o=[...t.data.values()].map((l,c)=>i._parse(new ur(t,l,t.path,c)));return t.common.async?Promise.all(o).then(l=>n(l)):n(o)}min(e,r){return new a({...this._def,minSize:{value:e,message:ve.toString(r)}})}max(e,r){return new a({...this._def,maxSize:{value:e,message:ve.toString(r)}})}size(e,r){return this.min(e,r).max(e,r)}nonempty(e){return this.min(1,e)}};On.create=(a,e)=>new On({valueType:a,minSize:null,maxSize:null,typeName:Oe.ZodSet,...Le(e)});var Oc=class a extends He{constructor(){super(...arguments),this.validate=this.implement}_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==pe.function)return ie(r,{code:ee.invalid_type,expected:pe.function,received:r.parsedType}),Te;function t(o,l){return Ui({data:o,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,Sn(),ra].filter(c=>!!c),issueData:{code:ee.invalid_arguments,argumentsError:l}})}function s(o,l){return Ui({data:o,path:r.path,errorMaps:[r.common.contextualErrorMap,r.schemaErrorMap,Sn(),ra].filter(c=>!!c),issueData:{code:ee.invalid_return_type,returnTypeError:l}})}let i={errorMap:r.common.contextualErrorMap},n=r.data;if(this._def.returns instanceof Aa){let o=this;return Ct(async function(...l){let c=new Ht([]),u=await o._def.args.parseAsync(l,i).catch(d=>{throw c.addIssue(t(l,d)),c}),p=await Reflect.apply(n,this,u);return await o._def.returns._def.type.parseAsync(p,i).catch(d=>{throw c.addIssue(s(p,d)),c})})}else{let o=this;return Ct(function(...l){let c=o._def.args.safeParse(l,i);if(!c.success)throw new Ht([t(l,c.error)]);let u=Reflect.apply(n,this,c.data),p=o._def.returns.safeParse(u,i);if(!p.success)throw new Ht([s(u,p.error)]);return p.data})}}parameters(){return this._def.args}returnType(){return this._def.returns}args(...e){return new a({...this._def,args:Br.create(e).rest(sa.create())})}returns(e){return new a({...this._def,returns:e})}implement(e){return this.parse(e)}strictImplement(e){return this.parse(e)}static create(e,r,t){return new a({args:e||Br.create([]).rest(sa.create()),returns:r||sa.create(),typeName:Oe.ZodFunction,...Le(t)})}},fs=class extends He{get schema(){return this._def.getter()}_parse(e){let{ctx:r}=this._processInputParams(e);return this._def.getter()._parse({data:r.data,path:r.path,parent:r})}};fs.create=(a,e)=>new fs({getter:a,typeName:Oe.ZodLazy,...Le(e)});var ms=class extends He{_parse(e){if(e.data!==this._def.value){let r=this._getOrReturnCtx(e);return ie(r,{received:r.data,code:ee.invalid_literal,expected:this._def.value}),Te}return{status:"valid",value:e.data}}get value(){return this._def.value}};ms.create=(a,e)=>new ms({value:a,typeName:Oe.ZodLiteral,...Le(e)});function Qx(a,e){return new hs({values:a,typeName:Oe.ZodEnum,...Le(e)})}var hs=class a extends He{_parse(e){if(typeof e.data!="string"){let r=this._getOrReturnCtx(e),t=this._def.values;return ie(r,{expected:We.joinValues(t),received:r.parsedType,code:ee.invalid_type}),Te}if(this._cache||(this._cache=new Set(this._def.values)),!this._cache.has(e.data)){let r=this._getOrReturnCtx(e),t=this._def.values;return ie(r,{received:r.data,code:ee.invalid_enum_value,options:t}),Te}return Ct(e.data)}get options(){return this._def.values}get enum(){let e={};for(let r of this._def.values)e[r]=r;return e}get Values(){let e={};for(let r of this._def.values)e[r]=r;return e}get Enum(){let e={};for(let r of this._def.values)e[r]=r;return e}extract(e,r=this._def){return a.create(e,{...this._def,...r})}exclude(e,r=this._def){return a.create(this.options.filter(t=>!e.includes(t)),{...this._def,...r})}};hs.create=Qx;var vs=class extends He{_parse(e){let r=We.getValidEnumValues(this._def.values),t=this._getOrReturnCtx(e);if(t.parsedType!==pe.string&&t.parsedType!==pe.number){let s=We.objectValues(r);return ie(t,{expected:We.joinValues(s),received:t.parsedType,code:ee.invalid_type}),Te}if(this._cache||(this._cache=new Set(We.getValidEnumValues(this._def.values))),!this._cache.has(e.data)){let s=We.objectValues(r);return ie(t,{received:t.data,code:ee.invalid_enum_value,options:s}),Te}return Ct(e.data)}get enum(){return this._def.values}};vs.create=(a,e)=>new vs({values:a,typeName:Oe.ZodNativeEnum,...Le(e)});var Aa=class extends He{unwrap(){return this._def.type}_parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==pe.promise&&r.common.async===!1)return ie(r,{code:ee.invalid_type,expected:pe.promise,received:r.parsedType}),Te;let t=r.parsedType===pe.promise?r.data:Promise.resolve(r.data);return Ct(t.then(s=>this._def.type.parseAsync(s,{path:r.path,errorMap:r.common.contextualErrorMap})))}};Aa.create=(a,e)=>new Aa({type:a,typeName:Oe.ZodPromise,...Le(e)});var pr=class extends He{innerType(){return this._def.schema}sourceType(){return this._def.schema._def.typeName===Oe.ZodEffects?this._def.schema.sourceType():this._def.schema}_parse(e){let{status:r,ctx:t}=this._processInputParams(e),s=this._def.effect||null,i={addIssue:n=>{ie(t,n),n.fatal?r.abort():r.dirty()},get path(){return t.path}};if(i.addIssue=i.addIssue.bind(i),s.type==="preprocess"){let n=s.transform(t.data,i);if(t.common.async)return Promise.resolve(n).then(async o=>{if(r.value==="aborted")return Te;let l=await this._def.schema._parseAsync({data:o,path:t.path,parent:t});return l.status==="aborted"?Te:l.status==="dirty"?ss(l.value):r.value==="dirty"?ss(l.value):l});{if(r.value==="aborted")return Te;let o=this._def.schema._parseSync({data:n,path:t.path,parent:t});return o.status==="aborted"?Te:o.status==="dirty"?ss(o.value):r.value==="dirty"?ss(o.value):o}}if(s.type==="refinement"){let n=o=>{let l=s.refinement(o,i);if(t.common.async)return Promise.resolve(l);if(l instanceof Promise)throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");return o};if(t.common.async===!1){let o=this._def.schema._parseSync({data:t.data,path:t.path,parent:t});return o.status==="aborted"?Te:(o.status==="dirty"&&r.dirty(),n(o.value),{status:r.value,value:o.value})}else return this._def.schema._parseAsync({data:t.data,path:t.path,parent:t}).then(o=>o.status==="aborted"?Te:(o.status==="dirty"&&r.dirty(),n(o.value).then(()=>({status:r.value,value:o.value}))))}if(s.type==="transform")if(t.common.async===!1){let n=this._def.schema._parseSync({data:t.data,path:t.path,parent:t});if(!Oa(n))return Te;let o=s.transform(n.value,i);if(o instanceof Promise)throw new Error("Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.");return{status:r.value,value:o}}else return this._def.schema._parseAsync({data:t.data,path:t.path,parent:t}).then(n=>Oa(n)?Promise.resolve(s.transform(n.value,i)).then(o=>({status:r.value,value:o})):Te);We.assertNever(s)}};pr.create=(a,e,r)=>new pr({schema:a,typeName:Oe.ZodEffects,effect:e,...Le(r)});pr.createWithPreprocess=(a,e,r)=>new pr({schema:e,effect:{type:"preprocess",transform:a},typeName:Oe.ZodEffects,...Le(r)});var lr=class extends He{_parse(e){return this._getType(e)===pe.undefined?Ct(void 0):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};lr.create=(a,e)=>new lr({innerType:a,typeName:Oe.ZodOptional,...Le(e)});var zr=class extends He{_parse(e){return this._getType(e)===pe.null?Ct(null):this._def.innerType._parse(e)}unwrap(){return this._def.innerType}};zr.create=(a,e)=>new zr({innerType:a,typeName:Oe.ZodNullable,...Le(e)});var gs=class extends He{_parse(e){let{ctx:r}=this._processInputParams(e),t=r.data;return r.parsedType===pe.undefined&&(t=this._def.defaultValue()),this._def.innerType._parse({data:t,path:r.path,parent:r})}removeDefault(){return this._def.innerType}};gs.create=(a,e)=>new gs({innerType:a,typeName:Oe.ZodDefault,defaultValue:typeof e.default=="function"?e.default:()=>e.default,...Le(e)});var ys=class extends He{_parse(e){let{ctx:r}=this._processInputParams(e),t={...r,common:{...r.common,issues:[]}},s=this._def.innerType._parse({data:t.data,path:t.path,parent:{...t}});return En(s)?s.then(i=>({status:"valid",value:i.status==="valid"?i.value:this._def.catchValue({get error(){return new Ht(t.common.issues)},input:t.data})})):{status:"valid",value:s.status==="valid"?s.value:this._def.catchValue({get error(){return new Ht(t.common.issues)},input:t.data})}}removeCatch(){return this._def.innerType}};ys.create=(a,e)=>new ys({innerType:a,typeName:Oe.ZodCatch,catchValue:typeof e.catch=="function"?e.catch:()=>e.catch,...Le(e)});var Cn=class extends He{_parse(e){if(this._getType(e)!==pe.nan){let t=this._getOrReturnCtx(e);return ie(t,{code:ee.invalid_type,expected:pe.nan,received:t.parsedType}),Te}return{status:"valid",value:e.data}}};Cn.create=a=>new Cn({typeName:Oe.ZodNaN,...Le(a)});var aN=Symbol("zod_brand"),Hi=class extends He{_parse(e){let{ctx:r}=this._processInputParams(e),t=r.data;return this._def.type._parse({data:t,path:r.path,parent:r})}unwrap(){return this._def.type}},Bi=class a extends He{_parse(e){let{status:r,ctx:t}=this._processInputParams(e);if(t.common.async)return(async()=>{let i=await this._def.in._parseAsync({data:t.data,path:t.path,parent:t});return i.status==="aborted"?Te:i.status==="dirty"?(r.dirty(),ss(i.value)):this._def.out._parseAsync({data:i.value,path:t.path,parent:t})})();{let s=this._def.in._parseSync({data:t.data,path:t.path,parent:t});return s.status==="aborted"?Te:s.status==="dirty"?(r.dirty(),{status:"dirty",value:s.value}):this._def.out._parseSync({data:s.value,path:t.path,parent:t})}}static create(e,r){return new a({in:e,out:r,typeName:Oe.ZodPipeline})}},bs=class extends He{_parse(e){let r=this._def.innerType._parse(e),t=s=>(Oa(s)&&(s.value=Object.freeze(s.value)),s);return En(r)?r.then(s=>t(s)):t(r)}unwrap(){return this._def.innerType}};bs.create=(a,e)=>new bs({innerType:a,typeName:Oe.ZodReadonly,...Le(e)});function Gx(a,e){let r=typeof a=="function"?a(e):typeof a=="string"?{message:a}:a;return typeof r=="string"?{message:r}:r}function Yx(a,e={},r){return a?ka.create().superRefine((t,s)=>{let i=a(t);if(i instanceof Promise)return i.then(n=>{if(!n){let o=Gx(e,t),l=o.fatal??r??!0;s.addIssue({code:"custom",...o,fatal:l})}});if(!i){let n=Gx(e,t),o=n.fatal??r??!0;s.addIssue({code:"custom",...n,fatal:o})}}):ka.create()}var sN={object:Bt.lazycreate},Oe;(function(a){a.ZodString="ZodString",a.ZodNumber="ZodNumber",a.ZodNaN="ZodNaN",a.ZodBigInt="ZodBigInt",a.ZodBoolean="ZodBoolean",a.ZodDate="ZodDate",a.ZodSymbol="ZodSymbol",a.ZodUndefined="ZodUndefined",a.ZodNull="ZodNull",a.ZodAny="ZodAny",a.ZodUnknown="ZodUnknown",a.ZodNever="ZodNever",a.ZodVoid="ZodVoid",a.ZodArray="ZodArray",a.ZodObject="ZodObject",a.ZodUnion="ZodUnion",a.ZodDiscriminatedUnion="ZodDiscriminatedUnion",a.ZodIntersection="ZodIntersection",a.ZodTuple="ZodTuple",a.ZodRecord="ZodRecord",a.ZodMap="ZodMap",a.ZodSet="ZodSet",a.ZodFunction="ZodFunction",a.ZodLazy="ZodLazy",a.ZodLiteral="ZodLiteral",a.ZodEnum="ZodEnum",a.ZodEffects="ZodEffects",a.ZodNativeEnum="ZodNativeEnum",a.ZodOptional="ZodOptional",a.ZodNullable="ZodNullable",a.ZodDefault="ZodDefault",a.ZodCatch="ZodCatch",a.ZodPromise="ZodPromise",a.ZodBranded="ZodBranded",a.ZodPipeline="ZodPipeline",a.ZodReadonly="ZodReadonly"})(Oe||(Oe={}));var nN=(a,e={message:`Input not instance of ${a.name}`})=>Yx(r=>r instanceof a,e),Jx=Ca.create,e0=ns.create,iN=Cn.create,oN=is.create,t0=os.create,cN=cs.create,lN=Tn.create,uN=ls.create,pN=us.create,dN=ka.create,fN=sa.create,mN=Cr.create,hN=Rn.create,vN=na.create,gN=Bt.create,yN=Bt.strictCreate,bN=ps.create,xN=Rc.create,_N=ds.create,SN=Br.create,EN=Pc.create,wN=Pn.create,TN=On.create,RN=Oc.create,PN=fs.create,ON=ms.create,CN=hs.create,kN=vs.create,AN=Aa.create,IN=pr.create,DN=lr.create,NN=zr.create,jN=pr.createWithPreprocess,$N=Bi.create,MN=()=>Jx().optional(),LN=()=>e0().optional(),FN=()=>t0().optional(),qN={string:(a=>Ca.create({...a,coerce:!0})),number:(a=>ns.create({...a,coerce:!0})),boolean:(a=>os.create({...a,coerce:!0})),bigint:(a=>is.create({...a,coerce:!0})),date:(a=>cs.create({...a,coerce:!0}))};var UN=Te;var pd="2025-06-18";var r0=[pd,"2025-03-26","2024-11-05","2024-10-07"],Cc="2.0",a0=S.union([S.string(),S.number().int()]),s0=S.string(),HN=S.object({progressToken:S.optional(a0)}).passthrough(),mr=S.object({_meta:S.optional(HN)}).passthrough(),zt=S.object({method:S.string(),params:S.optional(mr)}),zi=S.object({_meta:S.optional(S.object({}).passthrough())}).passthrough(),Vr=S.object({method:S.string(),params:S.optional(zi)}),hr=S.object({_meta:S.optional(S.object({}).passthrough())}).passthrough(),kc=S.union([S.string(),S.number().int()]),n0=S.object({jsonrpc:S.literal(Cc),id:kc}).merge(zt).strict(),i0=a=>n0.safeParse(a).success,o0=S.object({jsonrpc:S.literal(Cc)}).merge(Vr).strict(),c0=a=>o0.safeParse(a).success,l0=S.object({jsonrpc:S.literal(Cc),id:kc,result:hr}).strict(),dd=a=>l0.safeParse(a).success,dr;(function(a){a[a.ConnectionClosed=-32e3]="ConnectionClosed",a[a.RequestTimeout=-32001]="RequestTimeout",a[a.ParseError=-32700]="ParseError",a[a.InvalidRequest=-32600]="InvalidRequest",a[a.MethodNotFound=-32601]="MethodNotFound",a[a.InvalidParams=-32602]="InvalidParams",a[a.InternalError=-32603]="InternalError"})(dr||(dr={}));var u0=S.object({jsonrpc:S.literal(Cc),id:kc,error:S.object({code:S.number().int(),message:S.string(),data:S.optional(S.unknown())})}).strict(),p0=a=>u0.safeParse(a).success,d0=S.union([n0,o0,l0,u0]),xs=hr.strict(),Ac=Vr.extend({method:S.literal("notifications/cancelled"),params:zi.extend({requestId:kc,reason:S.string().optional()})}),BN=S.object({src:S.string(),mimeType:S.optional(S.string()),sizes:S.optional(S.array(S.string()))}).passthrough(),Vi=S.object({icons:S.array(BN).optional()}).passthrough(),Wi=S.object({name:S.string(),title:S.optional(S.string())}).passthrough(),f0=Wi.extend({version:S.string(),websiteUrl:S.optional(S.string())}).merge(Vi),zN=S.object({experimental:S.optional(S.object({}).passthrough()),sampling:S.optional(S.object({}).passthrough()),elicitation:S.optional(S.object({}).passthrough()),roots:S.optional(S.object({listChanged:S.optional(S.boolean())}).passthrough())}).passthrough(),VN=zt.extend({method:S.literal("initialize"),params:mr.extend({protocolVersion:S.string(),capabilities:zN,clientInfo:f0})});var WN=S.object({experimental:S.optional(S.object({}).passthrough()),logging:S.optional(S.object({}).passthrough()),completions:S.optional(S.object({}).passthrough()),prompts:S.optional(S.object({listChanged:S.optional(S.boolean())}).passthrough()),resources:S.optional(S.object({subscribe:S.optional(S.boolean()),listChanged:S.optional(S.boolean())}).passthrough()),tools:S.optional(S.object({listChanged:S.optional(S.boolean())}).passthrough())}).passthrough(),fd=hr.extend({protocolVersion:S.string(),capabilities:WN,serverInfo:f0,instructions:S.optional(S.string())}),GN=Vr.extend({method:S.literal("notifications/initialized")});var Ic=zt.extend({method:S.literal("ping")}),ZN=S.object({progress:S.number(),total:S.optional(S.number()),message:S.optional(S.string())}).passthrough(),Dc=Vr.extend({method:S.literal("notifications/progress"),params:zi.merge(ZN).extend({progressToken:a0})}),Nc=zt.extend({params:mr.extend({cursor:S.optional(s0)}).optional()}),jc=hr.extend({nextCursor:S.optional(s0)}),m0=S.object({uri:S.string(),mimeType:S.optional(S.string()),_meta:S.optional(S.object({}).passthrough())}).passthrough(),h0=m0.extend({text:S.string()}),md=S.string().refine(a=>{try{return atob(a),!0}catch{return!1}},{message:"Invalid Base64 string"}),v0=m0.extend({blob:md}),g0=Wi.extend({uri:S.string(),description:S.optional(S.string()),mimeType:S.optional(S.string()),_meta:S.optional(S.object({}).passthrough())}).merge(Vi),KN=Wi.extend({uriTemplate:S.string(),description:S.optional(S.string()),mimeType:S.optional(S.string()),_meta:S.optional(S.object({}).passthrough())}).merge(Vi),XN=Nc.extend({method:S.literal("resources/list")}),hd=jc.extend({resources:S.array(g0)}),QN=Nc.extend({method:S.literal("resources/templates/list")}),vd=jc.extend({resourceTemplates:S.array(KN)}),YN=zt.extend({method:S.literal("resources/read"),params:mr.extend({uri:S.string()})}),gd=hr.extend({contents:S.array(S.union([h0,v0]))}),JN=Vr.extend({method:S.literal("notifications/resources/list_changed")}),e2=zt.extend({method:S.literal("resources/subscribe"),params:mr.extend({uri:S.string()})}),t2=zt.extend({method:S.literal("resources/unsubscribe"),params:mr.extend({uri:S.string()})}),r2=Vr.extend({method:S.literal("notifications/resources/updated"),params:zi.extend({uri:S.string()})}),a2=S.object({name:S.string(),description:S.optional(S.string()),required:S.optional(S.boolean())}).passthrough(),s2=Wi.extend({description:S.optional(S.string()),arguments:S.optional(S.array(a2)),_meta:S.optional(S.object({}).passthrough())}).merge(Vi),n2=Nc.extend({method:S.literal("prompts/list")}),yd=jc.extend({prompts:S.array(s2)}),i2=zt.extend({method:S.literal("prompts/get"),params:mr.extend({name:S.string(),arguments:S.optional(S.record(S.string()))})}),bd=S.object({type:S.literal("text"),text:S.string(),_meta:S.optional(S.object({}).passthrough())}).passthrough(),xd=S.object({type:S.literal("image"),data:md,mimeType:S.string(),_meta:S.optional(S.object({}).passthrough())}).passthrough(),_d=S.object({type:S.literal("audio"),data:md,mimeType:S.string(),_meta:S.optional(S.object({}).passthrough())}).passthrough(),o2=S.object({type:S.literal("resource"),resource:S.union([h0,v0]),_meta:S.optional(S.object({}).passthrough())}).passthrough(),c2=g0.extend({type:S.literal("resource_link")}),y0=S.union([bd,xd,_d,c2,o2]),l2=S.object({role:S.enum(["user","assistant"]),content:y0}).passthrough(),Sd=hr.extend({description:S.optional(S.string()),messages:S.array(l2)}),u2=Vr.extend({method:S.literal("notifications/prompts/list_changed")}),p2=S.object({title:S.optional(S.string()),readOnlyHint:S.optional(S.boolean()),destructiveHint:S.optional(S.boolean()),idempotentHint:S.optional(S.boolean()),openWorldHint:S.optional(S.boolean())}).passthrough(),d2=Wi.extend({description:S.optional(S.string()),inputSchema:S.object({type:S.literal("object"),properties:S.optional(S.object({}).passthrough()),required:S.optional(S.array(S.string()))}).passthrough(),outputSchema:S.optional(S.object({type:S.literal("object"),properties:S.optional(S.object({}).passthrough()),required:S.optional(S.array(S.string()))}).passthrough()),annotations:S.optional(p2),_meta:S.optional(S.object({}).passthrough())}).merge(Vi),f2=Nc.extend({method:S.literal("tools/list")}),Ed=jc.extend({tools:S.array(d2)}),$c=hr.extend({content:S.array(y0).default([]),structuredContent:S.object({}).passthrough().optional(),isError:S.optional(S.boolean())}),T3=$c.or(hr.extend({toolResult:S.unknown()})),m2=zt.extend({method:S.literal("tools/call"),params:mr.extend({name:S.string(),arguments:S.optional(S.record(S.unknown()))})}),h2=Vr.extend({method:S.literal("notifications/tools/list_changed")}),b0=S.enum(["debug","info","notice","warning","error","critical","alert","emergency"]),v2=zt.extend({method:S.literal("logging/setLevel"),params:mr.extend({level:b0})}),g2=Vr.extend({method:S.literal("notifications/message"),params:zi.extend({level:b0,logger:S.optional(S.string()),data:S.unknown()})}),y2=S.object({name:S.string().optional()}).passthrough(),b2=S.object({hints:S.optional(S.array(y2)),costPriority:S.optional(S.number().min(0).max(1)),speedPriority:S.optional(S.number().min(0).max(1)),intelligencePriority:S.optional(S.number().min(0).max(1))}).passthrough(),x2=S.object({role:S.enum(["user","assistant"]),content:S.union([bd,xd,_d])}).passthrough(),_2=zt.extend({method:S.literal("sampling/createMessage"),params:mr.extend({messages:S.array(x2),systemPrompt:S.optional(S.string()),includeContext:S.optional(S.enum(["none","thisServer","allServers"])),temperature:S.optional(S.number()),maxTokens:S.number().int(),stopSequences:S.optional(S.array(S.string())),metadata:S.optional(S.object({}).passthrough()),modelPreferences:S.optional(b2)})}),S2=hr.extend({model:S.string(),stopReason:S.optional(S.enum(["endTurn","stopSequence","maxTokens"]).or(S.string())),role:S.enum(["user","assistant"]),content:S.discriminatedUnion("type",[bd,xd,_d])}),E2=S.object({type:S.literal("boolean"),title:S.optional(S.string()),description:S.optional(S.string()),default:S.optional(S.boolean())}).passthrough(),w2=S.object({type:S.literal("string"),title:S.optional(S.string()),description:S.optional(S.string()),minLength:S.optional(S.number()),maxLength:S.optional(S.number()),format:S.optional(S.enum(["email","uri","date","date-time"]))}).passthrough(),T2=S.object({type:S.enum(["number","integer"]),title:S.optional(S.string()),description:S.optional(S.string()),minimum:S.optional(S.number()),maximum:S.optional(S.number())}).passthrough(),R2=S.object({type:S.literal("string"),title:S.optional(S.string()),description:S.optional(S.string()),enum:S.array(S.string()),enumNames:S.optional(S.array(S.string()))}).passthrough(),P2=S.union([E2,w2,T2,R2]),O2=zt.extend({method:S.literal("elicitation/create"),params:mr.extend({message:S.string(),requestedSchema:S.object({type:S.literal("object"),properties:S.record(S.string(),P2),required:S.optional(S.array(S.string()))}).passthrough()})}),C2=hr.extend({action:S.enum(["accept","decline","cancel"]),content:S.optional(S.record(S.string(),S.unknown()))}),k2=S.object({type:S.literal("ref/resource"),uri:S.string()}).passthrough();var A2=S.object({type:S.literal("ref/prompt"),name:S.string()}).passthrough(),I2=zt.extend({method:S.literal("completion/complete"),params:mr.extend({ref:S.union([A2,k2]),argument:S.object({name:S.string(),value:S.string()}).passthrough(),context:S.optional(S.object({arguments:S.optional(S.record(S.string(),S.string()))}))})}),wd=hr.extend({completion:S.object({values:S.array(S.string()).max(100),total:S.optional(S.number().int()),hasMore:S.optional(S.boolean())}).passthrough()}),D2=S.object({uri:S.string().startsWith("file://"),name:S.optional(S.string()),_meta:S.optional(S.object({}).passthrough())}).passthrough(),N2=zt.extend({method:S.literal("roots/list")}),j2=hr.extend({roots:S.array(D2)}),$2=Vr.extend({method:S.literal("notifications/roots/list_changed")}),R3=S.union([Ic,VN,I2,v2,i2,n2,XN,QN,YN,e2,t2,m2,f2]),P3=S.union([Ac,Dc,GN,$2]),O3=S.union([xs,S2,C2,j2]),C3=S.union([Ic,_2,O2,N2]),k3=S.union([Ac,Dc,g2,r2,JN,h2,u2]),A3=S.union([xs,fd,wd,Sd,yd,hd,vd,gd,$c,Ed]),fr=class extends Error{constructor(e,r,t){super(`MCP error ${e}: ${r}`),this.code=e,this.data=t,this.name="McpError"}};var M2=6e4,Mc=class{constructor(e){this._options=e,this._requestMessageId=0,this._requestHandlers=new Map,this._requestHandlerAbortControllers=new Map,this._notificationHandlers=new Map,this._responseHandlers=new Map,this._progressHandlers=new Map,this._timeoutInfo=new Map,this._pendingDebouncedNotifications=new Set,this.setNotificationHandler(Ac,r=>{let t=this._requestHandlerAbortControllers.get(r.params.requestId);t?.abort(r.params.reason)}),this.setNotificationHandler(Dc,r=>{this._onprogress(r)}),this.setRequestHandler(Ic,r=>({}))}_setupTimeout(e,r,t,s,i=!1){this._timeoutInfo.set(e,{timeoutId:setTimeout(s,r),startTime:Date.now(),timeout:r,maxTotalTimeout:t,resetTimeoutOnProgress:i,onTimeout:s})}_resetTimeout(e){let r=this._timeoutInfo.get(e);if(!r)return!1;let t=Date.now()-r.startTime;if(r.maxTotalTimeout&&t>=r.maxTotalTimeout)throw this._timeoutInfo.delete(e),new fr(dr.RequestTimeout,"Maximum total timeout exceeded",{maxTotalTimeout:r.maxTotalTimeout,totalElapsed:t});return clearTimeout(r.timeoutId),r.timeoutId=setTimeout(r.onTimeout,r.timeout),!0}_cleanupTimeout(e){let r=this._timeoutInfo.get(e);r&&(clearTimeout(r.timeoutId),this._timeoutInfo.delete(e))}async connect(e){var r,t,s;this._transport=e;let i=(r=this.transport)===null||r===void 0?void 0:r.onclose;this._transport.onclose=()=>{i?.(),this._onclose()};let n=(t=this.transport)===null||t===void 0?void 0:t.onerror;this._transport.onerror=l=>{n?.(l),this._onerror(l)};let o=(s=this._transport)===null||s===void 0?void 0:s.onmessage;this._transport.onmessage=(l,c)=>{o?.(l,c),dd(l)||p0(l)?this._onresponse(l):i0(l)?this._onrequest(l,c):c0(l)?this._onnotification(l):this._onerror(new Error(`Unknown message type: ${JSON.stringify(l)}`))},await this._transport.start()}_onclose(){var e;let r=this._responseHandlers;this._responseHandlers=new Map,this._progressHandlers.clear(),this._pendingDebouncedNotifications.clear(),this._transport=void 0,(e=this.onclose)===null||e===void 0||e.call(this);let t=new fr(dr.ConnectionClosed,"Connection closed");for(let s of r.values())s(t)}_onerror(e){var r;(r=this.onerror)===null||r===void 0||r.call(this,e)}_onnotification(e){var r;let t=(r=this._notificationHandlers.get(e.method))!==null&&r!==void 0?r:this.fallbackNotificationHandler;t!==void 0&&Promise.resolve().then(()=>t(e)).catch(s=>this._onerror(new Error(`Uncaught error in notification handler: ${s}`)))}_onrequest(e,r){var t,s;let i=(t=this._requestHandlers.get(e.method))!==null&&t!==void 0?t:this.fallbackRequestHandler,n=this._transport;if(i===void 0){n?.send({jsonrpc:"2.0",id:e.id,error:{code:dr.MethodNotFound,message:"Method not found"}}).catch(c=>this._onerror(new Error(`Failed to send an error response: ${c}`)));return}let o=new AbortController;this._requestHandlerAbortControllers.set(e.id,o);let l={signal:o.signal,sessionId:n?.sessionId,_meta:(s=e.params)===null||s===void 0?void 0:s._meta,sendNotification:c=>this.notification(c,{relatedRequestId:e.id}),sendRequest:(c,u,p)=>this.request(c,u,{...p,relatedRequestId:e.id}),authInfo:r?.authInfo,requestId:e.id,requestInfo:r?.requestInfo};Promise.resolve().then(()=>i(e,l)).then(c=>{if(!o.signal.aborted)return n?.send({result:c,jsonrpc:"2.0",id:e.id})},c=>{var u;if(!o.signal.aborted)return n?.send({jsonrpc:"2.0",id:e.id,error:{code:Number.isSafeInteger(c.code)?c.code:dr.InternalError,message:(u=c.message)!==null&&u!==void 0?u:"Internal error"}})}).catch(c=>this._onerror(new Error(`Failed to send response: ${c}`))).finally(()=>{this._requestHandlerAbortControllers.delete(e.id)})}_onprogress(e){let{progressToken:r,...t}=e.params,s=Number(r),i=this._progressHandlers.get(s);if(!i){this._onerror(new Error(`Received a progress notification for an unknown token: ${JSON.stringify(e)}`));return}let n=this._responseHandlers.get(s),o=this._timeoutInfo.get(s);if(o&&n&&o.resetTimeoutOnProgress)try{this._resetTimeout(s)}catch(l){n(l);return}i(t)}_onresponse(e){let r=Number(e.id),t=this._responseHandlers.get(r);if(t===void 0){this._onerror(new Error(`Received a response for an unknown message ID: ${JSON.stringify(e)}`));return}if(this._responseHandlers.delete(r),this._progressHandlers.delete(r),this._cleanupTimeout(r),dd(e))t(e);else{let s=new fr(e.error.code,e.error.message,e.error.data);t(s)}}get transport(){return this._transport}async close(){var e;await((e=this._transport)===null||e===void 0?void 0:e.close())}request(e,r,t){let{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}=t??{};return new Promise((o,l)=>{var c,u,p,f,d,v;if(!this._transport){l(new Error("Not connected"));return}((c=this._options)===null||c===void 0?void 0:c.enforceStrictCapabilities)===!0&&this.assertCapabilityForMethod(e.method),(u=t?.signal)===null||u===void 0||u.throwIfAborted();let h=this._requestMessageId++,m={...e,jsonrpc:"2.0",id:h};t?.onprogress&&(this._progressHandlers.set(h,t.onprogress),m.params={...e.params,_meta:{...((p=e.params)===null||p===void 0?void 0:p._meta)||{},progressToken:h}});let y=R=>{var w;this._responseHandlers.delete(h),this._progressHandlers.delete(h),this._cleanupTimeout(h),(w=this._transport)===null||w===void 0||w.send({jsonrpc:"2.0",method:"notifications/cancelled",params:{requestId:h,reason:String(R)}},{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}).catch(T=>this._onerror(new Error(`Failed to send cancellation: ${T}`))),l(R)};this._responseHandlers.set(h,R=>{var w;if(!(!((w=t?.signal)===null||w===void 0)&&w.aborted)){if(R instanceof Error)return l(R);try{let T=r.parse(R.result);o(T)}catch(T){l(T)}}}),(f=t?.signal)===null||f===void 0||f.addEventListener("abort",()=>{var R;y((R=t?.signal)===null||R===void 0?void 0:R.reason)});let g=(d=t?.timeout)!==null&&d!==void 0?d:M2,b=()=>y(new fr(dr.RequestTimeout,"Request timed out",{timeout:g}));this._setupTimeout(h,g,t?.maxTotalTimeout,b,(v=t?.resetTimeoutOnProgress)!==null&&v!==void 0?v:!1),this._transport.send(m,{relatedRequestId:s,resumptionToken:i,onresumptiontoken:n}).catch(R=>{this._cleanupTimeout(h),l(R)})})}async notification(e,r){var t,s;if(!this._transport)throw new Error("Not connected");if(this.assertNotificationCapability(e.method),((s=(t=this._options)===null||t===void 0?void 0:t.debouncedNotificationMethods)!==null&&s!==void 0?s:[]).includes(e.method)&&!e.params&&!r?.relatedRequestId){if(this._pendingDebouncedNotifications.has(e.method))return;this._pendingDebouncedNotifications.add(e.method),Promise.resolve().then(()=>{var l;if(this._pendingDebouncedNotifications.delete(e.method),!this._transport)return;let c={...e,jsonrpc:"2.0"};(l=this._transport)===null||l===void 0||l.send(c,r).catch(u=>this._onerror(u))});return}let o={...e,jsonrpc:"2.0"};await this._transport.send(o,r)}setRequestHandler(e,r){let t=e.shape.method.value;this.assertRequestHandlerCapability(t),this._requestHandlers.set(t,(s,i)=>Promise.resolve(r(e.parse(s),i)))}removeRequestHandler(e){this._requestHandlers.delete(e)}assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw new Error(`A request handler for ${e} already exists, which would be overridden`)}setNotificationHandler(e,r){this._notificationHandlers.set(e.shape.method.value,t=>Promise.resolve(r(e.parse(t))))}removeNotificationHandler(e){this._notificationHandlers.delete(e)}};function x0(a,e){return Object.entries(e).reduce((r,[t,s])=>(s&&typeof s=="object"?r[t]=r[t]?{...r[t],...s}:s:r[t]=s,r),{...a})}var SS=bt(_S(),1),kn=class extends Mc{constructor(e,r){var t;super(r),this._clientInfo=e,this._cachedToolOutputValidators=new Map,this._capabilities=(t=r?.capabilities)!==null&&t!==void 0?t:{},this._ajv=new SS.default}registerCapabilities(e){if(this.transport)throw new Error("Cannot register capabilities after connecting to transport");this._capabilities=x0(this._capabilities,e)}assertCapability(e,r){var t;if(!(!((t=this._serverCapabilities)===null||t===void 0)&&t[e]))throw new Error(`Server does not support ${e} (required for ${r})`)}async connect(e,r){if(await super.connect(e),e.sessionId===void 0)try{let t=await this.request({method:"initialize",params:{protocolVersion:pd,capabilities:this._capabilities,clientInfo:this._clientInfo}},fd,r);if(t===void 0)throw new Error(`Server sent invalid initialize result: ${t}`);if(!r0.includes(t.protocolVersion))throw new Error(`Server's protocol version is not supported: ${t.protocolVersion}`);this._serverCapabilities=t.capabilities,this._serverVersion=t.serverInfo,e.setProtocolVersion&&e.setProtocolVersion(t.protocolVersion),this._instructions=t.instructions,await this.notification({method:"notifications/initialized"})}catch(t){throw this.close(),t}}getServerCapabilities(){return this._serverCapabilities}getServerVersion(){return this._serverVersion}getInstructions(){return this._instructions}assertCapabilityForMethod(e){var r,t,s,i,n;switch(e){case"logging/setLevel":if(!(!((r=this._serverCapabilities)===null||r===void 0)&&r.logging))throw new Error(`Server does not support logging (required for ${e})`);break;case"prompts/get":case"prompts/list":if(!(!((t=this._serverCapabilities)===null||t===void 0)&&t.prompts))throw new Error(`Server does not support prompts (required for ${e})`);break;case"resources/list":case"resources/templates/list":case"resources/read":case"resources/subscribe":case"resources/unsubscribe":if(!(!((s=this._serverCapabilities)===null||s===void 0)&&s.resources))throw new Error(`Server does not support resources (required for ${e})`);if(e==="resources/subscribe"&&!this._serverCapabilities.resources.subscribe)throw new Error(`Server does not support resource subscriptions (required for ${e})`);break;case"tools/call":case"tools/list":if(!(!((i=this._serverCapabilities)===null||i===void 0)&&i.tools))throw new Error(`Server does not support tools (required for ${e})`);break;case"completion/complete":if(!(!((n=this._serverCapabilities)===null||n===void 0)&&n.completions))throw new Error(`Server does not support completions (required for ${e})`);break;case"initialize":break;case"ping":break}}assertNotificationCapability(e){var r;switch(e){case"notifications/roots/list_changed":if(!(!((r=this._capabilities.roots)===null||r===void 0)&&r.listChanged))throw new Error(`Client does not support roots list changed notifications (required for ${e})`);break;case"notifications/initialized":break;case"notifications/cancelled":break;case"notifications/progress":break}}assertRequestHandlerCapability(e){switch(e){case"sampling/createMessage":if(!this._capabilities.sampling)throw new Error(`Client does not support sampling capability (required for ${e})`);break;case"elicitation/create":if(!this._capabilities.elicitation)throw new Error(`Client does not support elicitation capability (required for ${e})`);break;case"roots/list":if(!this._capabilities.roots)throw new Error(`Client does not support roots capability (required for ${e})`);break;case"ping":break}}async ping(e){return this.request({method:"ping"},xs,e)}async complete(e,r){return this.request({method:"completion/complete",params:e},wd,r)}async setLoggingLevel(e,r){return this.request({method:"logging/setLevel",params:{level:e}},xs,r)}async getPrompt(e,r){return this.request({method:"prompts/get",params:e},Sd,r)}async listPrompts(e,r){return this.request({method:"prompts/list",params:e},yd,r)}async listResources(e,r){return this.request({method:"resources/list",params:e},hd,r)}async listResourceTemplates(e,r){return this.request({method:"resources/templates/list",params:e},vd,r)}async readResource(e,r){return this.request({method:"resources/read",params:e},gd,r)}async subscribeResource(e,r){return this.request({method:"resources/subscribe",params:e},xs,r)}async unsubscribeResource(e,r){return this.request({method:"resources/unsubscribe",params:e},xs,r)}async callTool(e,r=$c,t){let s=await this.request({method:"tools/call",params:e},r,t),i=this.getToolOutputValidator(e.name);if(i){if(!s.structuredContent&&!s.isError)throw new fr(dr.InvalidRequest,`Tool ${e.name} has an output schema but did not return structured content`);if(s.structuredContent)try{if(!i(s.structuredContent))throw new fr(dr.InvalidParams,`Structured content does not match the tool's output schema: ${this._ajv.errorsText(i.errors)}`)}catch(n){throw n instanceof fr?n:new fr(dr.InvalidParams,`Failed to validate structured content: ${n instanceof Error?n.message:String(n)}`)}}return s}cacheToolOutputSchemas(e){this._cachedToolOutputValidators.clear();for(let r of e)if(r.outputSchema)try{let t=this._ajv.compile(r.outputSchema);this._cachedToolOutputValidators.set(r.name,t)}catch{}}getToolOutputValidator(e){return this._cachedToolOutputValidators.get(e)}async listTools(e,r){let t=await this.request({method:"tools/list",params:e},Ed,r);return this.cacheToolOutputSchemas(t.tools),t}async sendRootsListChanged(){return this.notification({method:"notifications/roots/list_changed"})}};var dE=bt(uE(),1),Zi=bt(require("node:process"),1),fE=require("node:stream");var al=class{append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(` `);if(e===-1)return null;let r=this._buffer.toString("utf8",0,e).replace(/\r$/,"");return this._buffer=this._buffer.subarray(e+1),H$(r)}clear(){this._buffer=void 0}};function H$(a){return d0.parse(JSON.parse(a))}function pE(a){return JSON.stringify(a)+` -`}var B$=Zi.default.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"];function z$(){let a={};for(let e of B$){let r=Zi.default.env[e];r!==void 0&&(r.startsWith("()")||(a[e]=r))}return a}var Dn=class{constructor(e){this._abortController=new AbortController,this._readBuffer=new al,this._stderrStream=null,this._serverParams=e,(e.stderr==="pipe"||e.stderr==="overlapped")&&(this._stderrStream=new fE.PassThrough)}async start(){if(this._process)throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");return new Promise((e,r)=>{var t,s,i,n,o;this._process=(0,dE.default)(this._serverParams.command,(t=this._serverParams.args)!==null&&t!==void 0?t:[],{env:{...z$(),...this._serverParams.env},stdio:["pipe","pipe",(s=this._serverParams.stderr)!==null&&s!==void 0?s:"inherit"],shell:!1,signal:this._abortController.signal,windowsHide:Zi.default.platform==="win32"&&V$(),cwd:this._serverParams.cwd}),this._process.on("error",l=>{var c,u;if(l.name==="AbortError"){(c=this.onclose)===null||c===void 0||c.call(this);return}r(l),(u=this.onerror)===null||u===void 0||u.call(this,l)}),this._process.on("spawn",()=>{e()}),this._process.on("close",l=>{var c;this._process=void 0,(c=this.onclose)===null||c===void 0||c.call(this)}),(i=this._process.stdin)===null||i===void 0||i.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),(n=this._process.stdout)===null||n===void 0||n.on("data",l=>{this._readBuffer.append(l),this.processReadBuffer()}),(o=this._process.stdout)===null||o===void 0||o.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}get stderr(){var e,r;return this._stderrStream?this._stderrStream:(r=(e=this._process)===null||e===void 0?void 0:e.stderr)!==null&&r!==void 0?r:null}get pid(){var e,r;return(r=(e=this._process)===null||e===void 0?void 0:e.pid)!==null&&r!==void 0?r:null}processReadBuffer(){for(var e,r;;)try{let t=this._readBuffer.readMessage();if(t===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,t)}catch(t){(r=this.onerror)===null||r===void 0||r.call(this,t)}}async close(){this._abortController.abort(),this._process=void 0,this._readBuffer.clear()}send(e){return new Promise(r=>{var t;if(!(!((t=this._process)===null||t===void 0)&&t.stdin))throw new Error("Not connected");let s=pE(e);this._process.stdin.write(s)?r():this._process.stdin.once("drain",r)})}};function V$(){return"type"in Zi.default}var cl=bt(require("path"),1),lf=require("os");ft();var of={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,WINDOWS_MULTIPLIER:1.5};function yE(a){return process.platform==="win32"?Math.round(a*of.WINDOWS_MULTIPLIER):a}var ol=require("path");var SE=require("os");kr();var gH=(0,ol.join)(Vt,"worker.pid"),yH=(0,ol.join)(Vt,"logs"),bH=(0,ol.join)((0,SE.homedir)(),".claude","plugins","marketplaces","thedotmack");ia();var CH=cl.default.join((0,lf.homedir)(),".claude","plugins","marketplaces","thedotmack"),kH=yE(of.HEALTH_CHECK),Es=null;function Ln(){if(Es!==null)return Es;try{let a=cl.default.join(lt.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=lt.loadFromFile(a);return Es=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),Es}catch(a){return M.debug("SYSTEM","Failed to load port from settings, using default",{error:a}),Es=parseInt(lt.get("CLAUDE_MEM_WORKER_PORT"),10),Es}}function EE(){Es=null}function wE(){let a=cl.default.join((0,lf.homedir)(),".claude-mem","settings.json");return lt.loadFromFile(a).CLAUDE_MEM_WORKER_HOST}ft();var S1=require("child_process"),E1=require("util");ll();var RE=require("bun:sqlite");kr();var ul=class{db;constructor(e){e||(il(Vt),e=nl),this.db=new RE.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.ensureFTSTables()}ensureFTSTables(){try{if(this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all().some(t=>t.name==="observations_fts"||t.name==="session_summaries_fts"))return;console.log("[SessionSearch] Creating FTS5 tables..."),this.db.run(` +`}var B$=Zi.default.platform==="win32"?["APPDATA","HOMEDRIVE","HOMEPATH","LOCALAPPDATA","PATH","PROCESSOR_ARCHITECTURE","SYSTEMDRIVE","SYSTEMROOT","TEMP","USERNAME","USERPROFILE","PROGRAMFILES"]:["HOME","LOGNAME","PATH","SHELL","TERM","USER"];function z$(){let a={};for(let e of B$){let r=Zi.default.env[e];r!==void 0&&(r.startsWith("()")||(a[e]=r))}return a}var Dn=class{constructor(e){this._abortController=new AbortController,this._readBuffer=new al,this._stderrStream=null,this._serverParams=e,(e.stderr==="pipe"||e.stderr==="overlapped")&&(this._stderrStream=new fE.PassThrough)}async start(){if(this._process)throw new Error("StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.");return new Promise((e,r)=>{var t,s,i,n,o;this._process=(0,dE.default)(this._serverParams.command,(t=this._serverParams.args)!==null&&t!==void 0?t:[],{env:{...z$(),...this._serverParams.env},stdio:["pipe","pipe",(s=this._serverParams.stderr)!==null&&s!==void 0?s:"inherit"],shell:!1,signal:this._abortController.signal,windowsHide:Zi.default.platform==="win32"&&V$(),cwd:this._serverParams.cwd}),this._process.on("error",l=>{var c,u;if(l.name==="AbortError"){(c=this.onclose)===null||c===void 0||c.call(this);return}r(l),(u=this.onerror)===null||u===void 0||u.call(this,l)}),this._process.on("spawn",()=>{e()}),this._process.on("close",l=>{var c;this._process=void 0,(c=this.onclose)===null||c===void 0||c.call(this)}),(i=this._process.stdin)===null||i===void 0||i.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),(n=this._process.stdout)===null||n===void 0||n.on("data",l=>{this._readBuffer.append(l),this.processReadBuffer()}),(o=this._process.stdout)===null||o===void 0||o.on("error",l=>{var c;(c=this.onerror)===null||c===void 0||c.call(this,l)}),this._stderrStream&&this._process.stderr&&this._process.stderr.pipe(this._stderrStream)})}get stderr(){var e,r;return this._stderrStream?this._stderrStream:(r=(e=this._process)===null||e===void 0?void 0:e.stderr)!==null&&r!==void 0?r:null}get pid(){var e,r;return(r=(e=this._process)===null||e===void 0?void 0:e.pid)!==null&&r!==void 0?r:null}processReadBuffer(){for(var e,r;;)try{let t=this._readBuffer.readMessage();if(t===null)break;(e=this.onmessage)===null||e===void 0||e.call(this,t)}catch(t){(r=this.onerror)===null||r===void 0||r.call(this,t)}}async close(){this._abortController.abort(),this._process=void 0,this._readBuffer.clear()}send(e){return new Promise(r=>{var t;if(!(!((t=this._process)===null||t===void 0)&&t.stdin))throw new Error("Not connected");let s=pE(e);this._process.stdin.write(s)?r():this._process.stdin.once("drain",r)})}};function V$(){return"type"in Zi.default}var cl=bt(require("path"),1),lf=require("os");ft();var of={DEFAULT:5e3,HEALTH_CHECK:1e3,WORKER_STARTUP_WAIT:1e3,WORKER_STARTUP_RETRIES:15,PRE_RESTART_SETTLE_DELAY:2e3,WINDOWS_MULTIPLIER:1.5};function yE(a){return process.platform==="win32"?Math.round(a*of.WINDOWS_MULTIPLIER):a}var ol=require("path");var SE=require("os");kr();var gH=(0,ol.join)(Vt,"worker.pid"),yH=(0,ol.join)(Vt,"logs"),bH=(0,ol.join)((0,SE.homedir)(),".claude","plugins","marketplaces","thedotmack");ia();var CH=cl.default.join((0,lf.homedir)(),".claude","plugins","marketplaces","thedotmack"),kH=yE(of.HEALTH_CHECK),Es=null;function Ln(){if(Es!==null)return Es;try{let a=cl.default.join(lt.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=lt.loadFromFile(a);return Es=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),Es}catch(a){return M.debug("SYSTEM","Failed to load port from settings, using default",{error:a}),Es=parseInt(lt.get("CLAUDE_MEM_WORKER_PORT"),10),Es}}function EE(){Es=null}function wE(){let a=cl.default.join((0,lf.homedir)(),".claude-mem","settings.json");return lt.loadFromFile(a).CLAUDE_MEM_WORKER_HOST}ft();var S1=require("child_process"),E1=require("util");ll();var RE=require("bun:sqlite");kr();var ul=class{db;constructor(e){e||(il(Vt),e=nl),this.db=new RE.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.ensureFTSTables()}ensureFTSTables(){try{if(this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'").all().some(t=>t.name==="observations_fts"||t.name==="session_summaries_fts"))return;console.log("[SessionSearch] Creating FTS5 tables..."),this.db.run(` CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5( title, subtitle, diff --git a/src/shared/hook-constants.ts b/src/shared/hook-constants.ts index 11d75423..a5af1e98 100644 --- a/src/shared/hook-constants.ts +++ b/src/shared/hook-constants.ts @@ -3,6 +3,7 @@ export const HOOK_TIMEOUTS = { HEALTH_CHECK: 1000, // Worker health check (up from 500ms) WORKER_STARTUP_WAIT: 1000, WORKER_STARTUP_RETRIES: 15, + PRE_RESTART_SETTLE_DELAY: 2000, // Give files time to sync before restart WINDOWS_MULTIPLIER: 1.5 // Platform-specific adjustment } as const; diff --git a/src/shared/worker-utils.ts b/src/shared/worker-utils.ts index add1b364..410fc0e5 100644 --- a/src/shared/worker-utils.ts +++ b/src/shared/worker-utils.ts @@ -131,6 +131,9 @@ async function ensureWorkerVersionMatches(): Promise { workerVersion }); + // Give files time to sync before restart + await new Promise(resolve => setTimeout(resolve, getTimeout(HOOK_TIMEOUTS.PRE_RESTART_SETTLE_DELAY))); + // Restart the worker await ProcessManager.restart(getWorkerPort()); @@ -142,7 +145,7 @@ async function ensureWorkerVersionMatches(): Promise { logger.error('SYSTEM', 'Worker failed to restart after version mismatch', { expectedVersion: pluginVersion, runningVersion: workerVersion, - port + port: getWorkerPort() }); } }