#!/usr/bin/env node import{stdin as A}from"process";import{readFileSync as I,existsSync as T}from"fs";function P(s,t,e){return s==="PreCompact"?t?{continue:!0,suppressOutput:!0}:{continue:!1,stopReason:e.reason||"Pre-compact operation failed",suppressOutput:!0}:s==="SessionStart"?t&&e.context?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:e.context}}:{continue:!0,suppressOutput:!0}:s==="UserPromptSubmit"||s==="PostToolUse"?{continue:!0,suppressOutput:!0}:s==="Stop"?{continue:!0,suppressOutput:!0}:{continue:t,suppressOutput:!0,...e.reason&&!t?{stopReason:e.reason}:{}}}function k(s,t,e={}){let r=P(s,t,e);return JSON.stringify(r)}var d=(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))(d||{}),y=class{level;useColor;constructor(){let t=process.env.CLAUDE_MEM_LOG_LEVEL?.toUpperCase()||"INFO";this.level=d[t]??1,this.useColor=process.stdout.isTTY??!1}correlationId(t,e){return`obs-${t}-${e}`}sessionId(t){return`session-${t}`}formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return t.toString();if(typeof t=="object"){if(t instanceof Error)return this.level===0?`${t.message} ${t.stack}`:t.message;if(Array.isArray(t))return`[${t.length} items]`;let e=Object.keys(t);return e.length===0?"{}":e.length<=3?JSON.stringify(t):`{${e.length} keys: ${e.slice(0,3).join(", ")}...}`}return String(t)}formatTool(t,e){if(!e)return t;try{let r=typeof e=="string"?JSON.parse(e):e;if(t==="Bash"&&r.command){let n=r.command.length>50?r.command.substring(0,50)+"...":r.command;return`${t}(${n})`}if(t==="Read"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Edit"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}if(t==="Write"&&r.file_path){let n=r.file_path.split("/").pop()||r.file_path;return`${t}(${n})`}return t}catch{return t}}log(t,e,r,n,o){if(t0&&(E=` {${Object.entries(C).map(([v,b])=>`${v}=${b}`).join(", ")}}`)}let x=`[${i}] [${c}] [${m}] ${l}${r}${E}${g}`;t===3?console.error(x):console.log(x)}debug(t,e,r,n){this.log(0,t,e,r,n)}info(t,e,r,n){this.log(1,t,e,r,n)}warn(t,e,r,n){this.log(2,t,e,r,n)}error(t,e,r,n){this.log(3,t,e,r,n)}dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}},u=new y;import O from"path";import{homedir as M}from"os";import{existsSync as R,readFileSync as N}from"fs";import{spawnSync as W}from"child_process";import{join as a,dirname as L,basename as rt}from"path";import{homedir as w}from"os";import{fileURLToPath as H}from"url";function U(){return typeof __dirname<"u"?__dirname:L(H(import.meta.url))}var j=U(),p=process.env.CLAUDE_MEM_DATA_DIR||a(w(),".claude-mem"),h=process.env.CLAUDE_CONFIG_DIR||a(w(),".claude"),it=a(p,"archives"),at=a(p,"logs"),ct=a(p,"trash"),pt=a(p,"backups"),ut=a(p,"settings.json"),mt=a(p,"claude-mem.db"),ft=a(p,"vector-db"),lt=a(h,"settings.json"),gt=a(h,"commands"),dt=a(h,"CLAUDE.md");function S(){return a(j,"..","..")}var F=100,K=500,B=10;function f(){try{let s=O.join(M(),".claude-mem","settings.json");if(R(s)){let t=JSON.parse(N(s,"utf-8")),e=parseInt(t.env?.CLAUDE_MEM_WORKER_PORT,10);if(!isNaN(e))return e}}catch{}return parseInt(process.env.CLAUDE_MEM_WORKER_PORT||"37777",10)}async function D(){try{let s=f();return(await fetch(`http://127.0.0.1:${s}/health`,{signal:AbortSignal.timeout(F)})).ok}catch{return!1}}async function G(){try{let s=S(),t=O.join(s,"ecosystem.config.cjs");if(!R(t))throw new Error(`Ecosystem config not found at ${t}`);let e=O.join(s,"node_modules",".bin","pm2"),r=process.platform==="win32"?e+".cmd":e,n=R(r)?r:"pm2",o=W(n,["start",t],{cwd:s,stdio:"pipe",encoding:"utf-8",windowsHide:!0});if(o.status!==0)throw new Error(o.stderr||"PM2 start failed");for(let i=0;isetTimeout(c,K)),await D())return!0;return!1}catch{return!1}}async function $(){if(await D())return;if(!await G()){let t=f(),e=S();throw new Error(`Worker service failed to start on port ${t}. To start manually, run: cd ${e} npx pm2 start ecosystem.config.cjs If already running, try: npx pm2 restart claude-mem-worker`)}}function J(s){if(!s||!T(s))return"";try{let t=I(s,"utf-8").trim();if(!t)return"";let e=t.split(` `);for(let r=e.length-1;r>=0;r--)try{let n=JSON.parse(e[r]);if(n.type==="user"&&n.message?.content){let o=n.message.content;if(typeof o=="string")return o;if(Array.isArray(o))return o.filter(c=>c.type==="text").map(c=>c.text).join(` `)}}catch{continue}}catch(t){u.error("HOOK","Failed to read transcript",{transcriptPath:s},t)}return""}function q(s){if(!s||!T(s))return"";try{let t=I(s,"utf-8").trim();if(!t)return"";let e=t.split(` `);for(let r=e.length-1;r>=0;r--)try{let n=JSON.parse(e[r]);if(n.type==="assistant"&&n.message?.content){let o="",i=n.message.content;return typeof i=="string"?o=i:Array.isArray(i)&&(o=i.filter(m=>m.type==="text").map(m=>m.text).join(` `)),o=o.replace(/[\s\S]*?<\/system-reminder>/g,""),o=o.replace(/\n{3,}/g,` `).trim(),o}}catch{continue}}catch(t){u.error("HOOK","Failed to read transcript",{transcriptPath:s},t)}return""}async function V(s){if(!s)throw new Error("summaryHook requires input");let{session_id:t}=s;await $();let e=f(),r=J(s.transcript_path||""),n=q(s.transcript_path||"");u.dataIn("HOOK","Stop: Requesting summary",{workerPort:e,hasLastUserMessage:!!r,hasLastAssistantMessage:!!n});try{let o=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:r,last_assistant_message:n}),signal:AbortSignal.timeout(2e3)});if(!o.ok){let i=await o.text();throw u.failure("HOOK","Failed to generate summary",{status:o.status},i),new Error(`Failed to request summary from worker: ${o.status} ${i}`)}u.debug("HOOK","Summary request sent successfully")}catch(o){throw o.cause?.code==="ECONNREFUSED"||o.name==="TimeoutError"||o.message.includes("fetch failed")?new Error("There's a problem with the worker. If you just updated, type `pm2 restart claude-mem-worker` in your terminal to continue"):o}finally{fetch(`http://127.0.0.1:${e}/api/processing`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({isProcessing:!1})}).catch(()=>{})}console.log(k("Stop",!0))}var _="";A.on("data",s=>_+=s);A.on("end",async()=>{let s=_?JSON.parse(_):void 0;await V(s)});