claude-mem 13.4.2 → 13.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,20 @@
1
- var Y="127.0.0.1",X=["\u{1F527}","\u{1F4D0}","\u{1F50D}","\u{1F4BB}","\u{1F9EA}","\u{1F41B}","\u{1F6E1}\uFE0F","\u2601\uFE0F","\u{1F4E6}","\u{1F3AF}","\u{1F52E}","\u26A1","\u{1F30A}","\u{1F3A8}","\u{1F4CA}","\u{1F680}","\u{1F52C}","\u{1F3D7}\uFE0F","\u{1F4DD}","\u{1F3AD}"];function V(e){let s=0;for(let o=0;o<e.length;o++)s=(s<<5)-s+e.charCodeAt(o)|0;return X[Math.abs(s)%X.length]}var ee="\u{1F99E}",ne="\u2328\uFE0F",te="Claude Code Session",re="\u{1F980}";function se(e){let s=e?.primary??ee,o=e?.claudeCode??ne,a=e?.claudeCodeLabel??te,l=e?.default??re,g=e?.agents??{};return function(m){if(!m)return l;if(m.startsWith("openclaw-")){let p=m.slice(9);return p?`${g[p]||V(p)} ${p}`:`${s} openclaw`}if(m==="openclaw")return`${s} openclaw`;let b=a.trim();return b?`${o} ${b} (${m})`:`${o} ${m}`}}var q=Y;function T(e){return`http://${q}:${e}`}var oe=3,Q=3e4,y="CLOSED",j=0,J=0,$=!1;function G(e){return y==="CLOSED"?!0:y==="OPEN"?Date.now()-J>=Q?(y="HALF_OPEN",e.info("[claude-mem] Circuit breaker: probing worker connection"),$?!1:($=!0,!0)):!1:$?!1:($=!0,!0)}function z(e){y!=="CLOSED"&&e.info("[claude-mem] Worker connection restored \u2014 circuit closed"),y="CLOSED",j=0,$=!1}function M(e){$=!1,j++,(y==="HALF_OPEN"||y==="CLOSED"&&j>=oe)&&(y="OPEN",J=Date.now(),e.warn(`[claude-mem] Worker unreachable \u2014 disabling requests for ${Q/1e3}s`))}function ie(){y="CLOSED",j=0,J=0,$=!1}async function Z(e,s,o,a){if(!G(a))return null;try{let l=await fetch(`${T(e)}${s}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});return l.ok?(z(a),await l.json()):(M(a),a.warn(`[claude-mem] Worker POST ${s} returned ${l.status}`),null)}catch(l){let g=l instanceof Error?l.message:String(l);return M(a),y!=="OPEN"&&a.warn(`[claude-mem] Worker POST ${s} failed: ${g}`),null}}function ae(e,s,o,a){G(a)&&fetch(`${T(e)}${s}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}).then(l=>{if(!l.ok){M(a),a.warn(`[claude-mem] Worker POST ${s} returned ${l.status}`);return}z(a)}).catch(l=>{let g=l instanceof Error?l.message:String(l);M(a),y!=="OPEN"&&a.warn(`[claude-mem] Worker POST ${s} failed: ${g}`)})}async function H(e,s,o){if(!G(o))return null;try{let a=await fetch(`${T(e)}${s}`);return a.ok?(z(o),await a.text()):(M(o),o.warn(`[claude-mem] Worker GET ${s} returned ${a.status}`),null)}catch(a){let l=a instanceof Error?a.message:String(a);return M(o),y!=="OPEN"&&o.warn(`[claude-mem] Worker GET ${s} failed: ${l}`),null}}async function W(e,s,o){let a=await H(e,s,o);if(!a)return null;try{return JSON.parse(a)}catch{return o.warn(`[claude-mem] Worker GET ${s} returned non-JSON response`),null}}function ce(e,s){let o=e.title||"Untitled",l=`${s(e.project)}
2
- **${o}**`;return e.subtitle&&(l+=`
3
- ${e.subtitle}`),l}var le={telegram:{namespace:"telegram",functionName:"sendMessageTelegram"},whatsapp:{namespace:"whatsapp",functionName:"sendMessageWhatsApp"},discord:{namespace:"discord",functionName:"sendMessageDiscord"},slack:{namespace:"slack",functionName:"sendMessageSlack"},signal:{namespace:"signal",functionName:"sendMessageSignal"},imessage:{namespace:"imessage",functionName:"sendMessageIMessage"},line:{namespace:"line",functionName:"sendMessageLine"}};async function ue(e,s,o,a){try{let l=await fetch(`https://api.telegram.org/bot${e}/sendMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({chat_id:s,text:o,parse_mode:"Markdown"})});if(!l.ok){let g=await l.text();a.warn(`[claude-mem] Direct Telegram send failed (${l.status}): ${g}`)}}catch(l){let g=l instanceof Error?l.message:String(l);a.warn(`[claude-mem] Direct Telegram send error: ${g}`)}}function ge(e,s,o,a,l){if(l&&s==="telegram")return ue(l,o,a,e.logger);let g=le[s];if(!g)return e.logger.warn(`[claude-mem] Unsupported channel type: ${s}`),Promise.resolve();let v=e.runtime.channel[g.namespace];if(!v)return e.logger.warn(`[claude-mem] Channel "${s}" not available in runtime`),Promise.resolve();let m=v[g.functionName];return m?m(...s==="whatsapp"?[o,a,{verbose:!1}]:[o,a]).catch(p=>{let w=p instanceof Error?p.message:String(p);e.logger.error(`[claude-mem] Failed to send to ${s}: ${w}`)}):(e.logger.warn(`[claude-mem] Channel "${s}" has no ${g.functionName} function`),Promise.resolve())}async function de(e,s,o,a,l,g,v,m){let b=1e3,p=3e4;for(;!l.signal.aborted;){try{g("reconnecting"),e.logger.info(`[claude-mem] Connecting to SSE stream at ${T(s)}/stream`);let w=await fetch(`${T(s)}/stream`,{signal:l.signal,headers:{Accept:"text/event-stream"}});if(!w.ok)throw new Error(`SSE stream returned HTTP ${w.status}`);if(!w.body)throw new Error("SSE stream response has no body");g("connected"),b=1e3,e.logger.info("[claude-mem] Connected to SSE stream");let x=w.body.getReader(),D=new TextDecoder,_="";for(;;){let{done:R,value:P}=await x.read();if(R)break;_+=D.decode(P,{stream:!0}),_.length>1048576&&(e.logger.warn("[claude-mem] SSE buffer overflow, clearing buffer"),_="");let L=_.split(`
1
+ var ne=new Set(["security_alert","security_note","bugfix","decision"]),te=900,re=2200,se=5,oe=1024*1024,ie=37777,V="127.0.0.1",Y=["\u{1F527}","\u{1F4D0}","\u{1F50D}","\u{1F4BB}","\u{1F9EA}","\u{1F41B}","\u{1F6E1}\uFE0F","\u2601\uFE0F","\u{1F4E6}","\u{1F3AF}","\u{1F52E}","\u26A1","\u{1F30A}","\u{1F3A8}","\u{1F4CA}","\u{1F680}","\u{1F52C}","\u{1F3D7}\uFE0F","\u{1F4DD}","\u{1F3AD}"];function ae(e){let s=0;for(let o=0;o<e.length;o++)s=(s<<5)-s+e.charCodeAt(o)|0;return Y[Math.abs(s)%Y.length]}var ce="\u{1F99E}",le="\u2328\uFE0F",ue="Claude Code Session",ge="\u{1F980}";function de(e){let s=e?.primary??ce,o=e?.claudeCode??le,i=e?.claudeCodeLabel??ue,a=e?.default??ge,g=e?.agents??{};return function(m){if(!m)return a;if(m.startsWith("openclaw-")){let b=m.slice(9);return b?`${g[b]||ae(b)} ${b}`:`${s} openclaw`}if(m==="openclaw")return`${s} openclaw`;let w=i.trim();return w?`${o} ${w} (${m})`:`${o} ${m}`}}var q=V;function L(e){return`http://${q}:${e}`}var me=3,ee=3e4,v="CLOSED",N=0,G=0,$=!1;function z(e){return v==="CLOSED"?!0:v==="OPEN"?Date.now()-G>=ee?(v="HALF_OPEN",e.info("[claude-mem] Circuit breaker: probing worker connection"),$?!1:($=!0,!0)):!1:$?!1:($=!0,!0)}function X(e){v!=="CLOSED"&&e.info("[claude-mem] Worker connection restored \u2014 circuit closed"),v="CLOSED",N=0,$=!1}function M(e){$=!1,N++,(v==="HALF_OPEN"||v==="CLOSED"&&N>=me)&&(v="OPEN",G=Date.now(),e.warn(`[claude-mem] Worker unreachable \u2014 disabling requests for ${ee/1e3}s`))}function fe(){v="CLOSED",N=0,G=0,$=!1}async function Z(e,s,o,i){if(!z(i))return null;try{let a=await fetch(`${L(e)}${s}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});return a.ok?(X(i),await a.json()):(M(i),i.warn(`[claude-mem] Worker POST ${s} returned ${a.status}`),null)}catch(a){let g=a instanceof Error?a.message:String(a);return M(i),v!=="OPEN"&&i.warn(`[claude-mem] Worker POST ${s} failed: ${g}`),null}}function pe(e,s,o,i){z(i)&&fetch(`${L(e)}${s}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)}).then(a=>{if(!a.ok){M(i),i.warn(`[claude-mem] Worker POST ${s} returned ${a.status}`);return}X(i)}).catch(a=>{let g=a instanceof Error?a.message:String(a);M(i),v!=="OPEN"&&i.warn(`[claude-mem] Worker POST ${s} failed: ${g}`)})}async function J(e,s,o){if(!z(o))return null;try{let i=await fetch(`${L(e)}${s}`);return i.ok?(X(o),await i.text()):(M(o),o.warn(`[claude-mem] Worker GET ${s} returned ${i.status}`),null)}catch(i){let a=i instanceof Error?i.message:String(i);return M(o),v!=="OPEN"&&o.warn(`[claude-mem] Worker GET ${s} failed: ${a}`),null}}async function H(e,s,o){let i=await J(e,s,o);if(!i)return null;try{return JSON.parse(i)}catch{return o.warn(`[claude-mem] Worker GET ${s} returned non-JSON response`),null}}function we(e,s){let o=e.title||"Untitled",i=s(e.project),a=ne.has(e.type),g=[`${i}
2
+ **${o}**`];if(e.subtitle&&g.push(T(e.subtitle,a?500:260)),!a)return T(g.join(`
3
+ `),te);e.narrative&&g.push(`Narrative
4
+ ${T(e.narrative,900)}`);let p=Q(e.facts).slice(0,se);p.length>0&&g.push(`Facts
5
+ ${p.map(w=>`- ${T(w,320)}`).join(`
6
+ `)}`);let m=Q(e.concepts).slice(0,8);return m.length>0&&g.push(`Concepts: ${m.join(", ")}`),T(g.join(`
4
7
 
5
- `);_=L.pop()||"";for(let B of L){let F=B.split(`
6
- `).filter(S=>S.startsWith("data:")).map(S=>S.slice(5).trim());if(F.length===0)continue;let A=F.join(`
7
- `);if(A)try{let S=JSON.parse(A);if(S.type==="new_observation"&&S.observation){let C=ce(S.observation,v);await ge(e,o,a,C,m)}}catch(S){let O=S instanceof Error?S.message:String(S);e.logger.warn(`[claude-mem] Failed to parse SSE frame: ${O}`)}}}}catch(w){if(l.signal.aborted)break;g("reconnecting");let x=w instanceof Error?w.message:String(w);e.logger.warn(`[claude-mem] SSE stream error: ${x}. Reconnecting in ${b/1e3}s`)}if(l.signal.aborted)break;await new Promise(w=>setTimeout(w,b)),b=Math.min(b*2,p)}g("disconnected")}function me(e){let s=e.pluginConfig||{},o=s.workerPort||37777;q=s.workerHost||Y;let a=s.project||"openclaw",l=se(s.observationFeed?.emojis);function g(r){return r.agentId?`openclaw-${r.agentId}`:a}let v=new Map,m=new Map,b=new Map,p=new Map,w=s.syncMemoryFile!==!1,x=new Set(s.syncMemoryFileExclude||[]);function D(r){let n=r||"default";return v.has(n)||v.set(n,`openclaw-${n}-${Date.now()}`),v.get(n)}function _(r){if(!w)return!1;let n=r?.agentId;return!(n&&x.has(n))}function R(r){let n=new Set;for(let t of[r.sessionKey,r.conversationId,r.channelId]){let i=typeof t=="string"?t.trim():"";i&&n.add(i)}return n.size===0&&n.add("default"),Array.from(n)}function P(r){let n=R(r),t=n.find(u=>m.has(u));t=t?m.get(t):n[0];let i=b.get(t);i||(i=new Set([t]),b.set(t,i));for(let u of n)i.add(u),m.set(u,t);let c=D(t);for(let u of i)v.set(u,c);return{canonicalKey:t,contentSessionId:c}}function L(r,n,t){let i=Date.now();for(let[d,f]of p)i-f>2e3&&p.delete(d);let c=`${r}::${n}::${t}`,u=p.get(c);return p.set(c,i),typeof u=="number"&&i-u<=2e3}function B(r){let n=R(r),t=n.map(c=>m.get(c)).find(Boolean)||n[0],i=b.get(t)||new Set([t,...n]);for(let c of i)m.delete(c),v.delete(c);b.delete(t),v.delete(t)}let F=6e4,A=new Map;async function S(r){let n=[a],t=r?g(r):null;t&&t!==a&&n.push(t);let i=n.join(","),c=A.get(i);if(c&&Date.now()-c.fetchedAt<F)return c.text;let u=await H(o,`/api/context/inject?projects=${encodeURIComponent(i)}`,e.logger);if(u&&u.trim().length>0){let d=u.trim();return A.set(i,{text:d,fetchedAt:Date.now()}),d}return null}async function O(r,n,t){let{contentSessionId:i}=P(r),c=g(r);if(L(i,c,n)){e.logger.info(`[claude-mem] Skipping duplicate prompt init: contentSessionId=${i} project=${c} via=${t}`);return}await Z(o,"/api/sessions/init",{contentSessionId:i,project:c,prompt:n},e.logger),e.logger.info(`[claude-mem] Session initialized via ${t}: contentSessionId=${i} project=${c}`)}e.on("session_start",async(r,n)=>{await O(n,"session start","session_start")}),e.on("message_received",async(r,n)=>{let{canonicalKey:t,contentSessionId:i}=P(n);e.logger.info(`[claude-mem] Message received \u2014 prompt capture deferred to before_agent_start: session=${t} contentSessionId=${i} hasContent=${!!r.content}`)}),e.on("after_compaction",async(r,n)=>{await O(n,"after compaction","after_compaction")}),e.on("before_agent_start",async(r,n)=>{await O(n,r.prompt||"agent run","before_agent_start")}),e.on("before_prompt_build",async(r,n)=>{if(!_(n))return;let t=await S(n);if(t)return e.logger.info(`[claude-mem] Context injected via system prompt for agent=${n.agentId??"unknown"}`),{appendSystemContext:t}}),e.on("tool_result_persist",(r,n)=>{e.logger.info(`[claude-mem] tool_result_persist fired: tool=${r.toolName??"unknown"} agent=${n.agentId??"none"} session=${n.sessionKey??"none"}`);let t=r.toolName;if(!t||t.startsWith("memory_"))return;let{canonicalKey:i,contentSessionId:c}=P(n),u="",d=r.message?.content;Array.isArray(d)&&(u=d.filter(E=>(E.type==="tool_result"||E.type==="text")&&"text"in E).map(E=>String(E.text)).join(`
8
- `));let f=1e3;u.length>f&&(u=u.slice(0,f));let h=n.workspaceDir||process.cwd();n.workspaceDir||e.logger.info(`[claude-mem] tool_result_persist missing workspaceDir; using process.cwd(): session=${i} tool=${t}`),ae(o,"/api/sessions/observations",{contentSessionId:c,tool_name:t,tool_input:r.params||{},tool_response:u,cwd:h},e.logger)}),e.on("agent_end",async(r,n)=>{let{contentSessionId:t}=P(n),i="";if(Array.isArray(r.messages))for(let c=r.messages.length-1;c>=0;c--){let u=r.messages[c];if(u?.role==="assistant"){typeof u.content=="string"?i=u.content:Array.isArray(u.content)&&(i=u.content.filter(d=>d.type==="text").map(d=>d.text||"").join(`
9
- `));break}}await Z(o,"/api/sessions/summarize",{contentSessionId:t,last_assistant_message:i},e.logger)}),e.on("session_end",async(r,n)=>{B(n),e.logger.info("[claude-mem] Session tracking cleaned up")}),e.on("gateway_start",async()=>{ie(),v.clear(),A.clear(),p.clear(),m.clear(),b.clear(),e.logger.info("[claude-mem] Gateway started \u2014 session tracking reset")});let C=null,I="disconnected",k=null;e.registerService({id:"claude-mem-observation-feed",start:async r=>{C&&(C.abort(),k&&(await k,k=null));let n=s.observationFeed;if(!n?.enabled){e.logger.info("[claude-mem] Observation feed disabled");return}if(!n.channel||!n.to){e.logger.warn("[claude-mem] Observation feed misconfigured \u2014 channel or target missing");return}e.logger.info(`[claude-mem] Observation feed starting \u2014 channel: ${n.channel}, target: ${n.to}`),C=new AbortController,k=de(e,o,n.channel,n.to,C,t=>{I=t},l,n.botToken)},stop:async r=>{C&&(C.abort(),C=null),k&&(await k,k=null),I="disconnected",e.logger.info("[claude-mem] Observation feed stopped \u2014 SSE connection closed")}});function U(r,n=5){return!Array.isArray(r)||r.length===0?"No results found.":r.slice(0,n).map((t,i)=>{let c=t,u=String(c.title||c.subtitle||c.text||"Untitled"),d=c.project?` [${String(c.project)}]`:"";return`${i+1}. ${u}${d}`}).join(`
10
- `)}function N(r,n=10){let t=Number(r);return Number.isFinite(t)?Math.max(1,Math.min(50,Math.trunc(t))):n}e.registerCommand({name:"claude_mem_feed",description:"Show or toggle Claude-Mem observation feed status",acceptsArgs:!0,handler:async r=>{let n=s.observationFeed;if(!n)return{text:"Observation feed not configured. Add observationFeed to your plugin config."};let t=r.args?.trim();return t==="on"?(e.logger.info("[claude-mem] Feed enable requested via command"),{text:"Feed enable requested. Update observationFeed.enabled in your plugin config to persist."}):t==="off"?(e.logger.info("[claude-mem] Feed disable requested via command"),{text:"Feed disable requested. Update observationFeed.enabled in your plugin config to persist."}):{text:["Claude-Mem Observation Feed",`Enabled: ${n.enabled?"yes":"no"}`,`Channel: ${n.channel||"not set"}`,`Target: ${n.to||"not set"}`,`Connection: ${I}`].join(`
11
- `)}}}),e.registerCommand({name:"claude-mem-search",description:"Search Claude-Mem observations by query",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"";if(!n)return"Usage: /claude-mem-search <query> [limit]";let t=n.split(/\s+/),i=t[t.length-1],c=/^\d+$/.test(i),u=c?N(i,10):10,d=c?t.slice(0,-1).join(" "):n,f=await W(o,`/api/search/observations?query=${encodeURIComponent(d)}&limit=${u}`,e.logger);if(!f)return"Claude-Mem search failed (worker unavailable or invalid response).";let h=Array.isArray(f.items)?f.items:[];return[`Claude-Mem Search: "${d}"`,U(h,u)].join(`
12
- `)}}),e.registerCommand({name:"claude-mem-recent",description:"Show recent Claude-Mem context for a project",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"",t=n?n.split(/\s+/):[],i=t.length>0?t[t.length-1]:"",c=/^\d+$/.test(i),u=c?N(i,3):3,d=c?t.slice(0,-1).join(" "):n,f=new URLSearchParams;f.set("limit",String(u)),d&&f.set("project",d);let h=await W(o,`/api/context/recent?${f.toString()}`,e.logger);if(!h)return"Claude-Mem recent context failed (worker unavailable or invalid response).";let E=Array.isArray(h.session_summaries)?h.session_summaries:[],K=Array.isArray(h.recent_observations)?h.recent_observations:[];return["Claude-Mem Recent Context",`Project: ${d||"(auto)"}`,`Session summaries: ${E.length}`,`Recent observations: ${K.length}`,U(K,Math.min(5,K.length||5))].join(`
13
- `)}}),e.registerCommand({name:"claude-mem-timeline",description:"Find best memory match and show nearby timeline events",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"";if(!n)return"Usage: /claude-mem-timeline <query> [depthBefore] [depthAfter]";let t=n.split(/\s+/),i=5,c=5;t.length>=2&&/^\d+$/.test(t[t.length-1])&&(i=N(t.pop(),5)),t.length>=2&&/^\d+$/.test(t[t.length-1])&&(c=N(t.pop(),5));let u=t.join(" "),d=new URLSearchParams({query:u,mode:"auto",depth_before:String(c),depth_after:String(i)}),f=await W(o,`/api/timeline/by-query?${d.toString()}`,e.logger);if(!f)return"Claude-Mem timeline lookup failed (worker unavailable or invalid response).";let h=Array.isArray(f.timeline)?f.timeline:[],E=f.anchor?String(f.anchor):"(none)";return[`Claude-Mem Timeline: "${u}"`,`Anchor: ${E}`,U(h,8)].join(`
14
- `)}}),e.registerCommand({name:"claude_mem_status",description:"Check Claude-Mem worker health and session status",handler:async()=>{let r=await H(o,"/api/health",e.logger);if(!r)return{text:`Claude-Mem worker unreachable at port ${o}`};try{return{text:["Claude-Mem Worker Status",`Status: ${JSON.parse(r).status||"unknown"}`,`Port: ${o}`,`Active sessions: ${v.size}`,`Observation feed: ${I}`].join(`
15
- `)}}catch{return{text:"Claude-Mem worker responded but returned unexpected data"}}}}),e.logger.info(`[claude-mem] OpenClaw plugin loaded \u2014 v1.0.0 (worker: ${q}:${o})`)}export{me as default};
8
+ `),re)}function T(e,s){if(e.length<=s)return e;let o=Math.max(0,s-3),i=e.slice(0,o),a=i.search(/\s+\S*$/),g=a>Math.floor(o*.65)?a:o;return`${i.slice(0,g).trimEnd()}...`}function Q(e){if(!e)return[];try{let s=JSON.parse(e);return Array.isArray(s)?s.filter(o=>typeof o=="string"):[]}catch{return[]}}var be={telegram:{namespace:"telegram",functionName:"sendMessageTelegram"},whatsapp:{namespace:"whatsapp",functionName:"sendMessageWhatsApp"},discord:{namespace:"discord",functionName:"sendMessageDiscord"},slack:{namespace:"slack",functionName:"sendMessageSlack"},signal:{namespace:"signal",functionName:"sendMessageSignal"},imessage:{namespace:"imessage",functionName:"sendMessageIMessage"},line:{namespace:"line",functionName:"sendMessageLine"}};async function ye(e,s,o,i){try{let a=await fetch(`https://api.telegram.org/bot${e}/sendMessage`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({chat_id:s,text:o,parse_mode:"Markdown"})});if(!a.ok){let g=await a.text();i.warn(`[claude-mem] Direct Telegram send failed (${a.status}): ${g}`)}}catch(a){let g=a instanceof Error?a.message:String(a);i.warn(`[claude-mem] Direct Telegram send error: ${g}`)}}function Se(e,s,o,i,a){if(a&&s==="telegram")return ye(a,o,i,e.logger);let g=be[s];if(!g)return e.logger.warn(`[claude-mem] Unsupported channel type: ${s}`),Promise.resolve();let p=e.runtime.channel[g.namespace];if(!p)return e.logger.warn(`[claude-mem] Channel "${s}" not available in runtime`),Promise.resolve();let m=p[g.functionName];return m?m(...s==="whatsapp"?[o,i,{verbose:!1}]:[o,i]).catch(b=>{let y=b instanceof Error?b.message:String(b);e.logger.error(`[claude-mem] Failed to send to ${s}: ${y}`)}):(e.logger.warn(`[claude-mem] Channel "${s}" has no ${g.functionName} function`),Promise.resolve())}async function ve(e,s,o,i,a,g,p,m){let w=1e3,b=3e4;for(;!a.signal.aborted;){try{g("reconnecting"),e.logger.info(`[claude-mem] Connecting to SSE stream at ${L(s)}/stream`);let y=await fetch(`${L(s)}/stream`,{signal:a.signal,headers:{Accept:"text/event-stream"}});if(!y.ok)throw new Error(`SSE stream returned HTTP ${y.status}`);if(!y.body)throw new Error("SSE stream response has no body");g("connected"),w=1e3,e.logger.info("[claude-mem] Connected to SSE stream");let x=y.body.getReader(),B=new TextDecoder,_="";for(;;){let{done:R,value:P}=await x.read();if(R)break;_+=B.decode(P,{stream:!0}),_.length>oe&&(e.logger.warn("[claude-mem] SSE buffer overflow, clearing buffer"),_="");let F=_.split(`
9
+
10
+ `);_=F.pop()||"";for(let U of F){let D=U.split(`
11
+ `).filter(S=>S.startsWith("data:")).map(S=>S.slice(5).trim());if(D.length===0)continue;let A=D.join(`
12
+ `);if(A)try{let S=JSON.parse(A);if(S.type==="new_observation"&&S.observation){let C=we(S.observation,p);await Se(e,o,i,C,m)}}catch(S){let O=S instanceof Error?S.message:String(S);e.logger.warn(`[claude-mem] Failed to parse SSE frame: ${O}`)}}}}catch(y){if(a.signal.aborted)break;g("reconnecting");let x=y instanceof Error?y.message:String(y);e.logger.warn(`[claude-mem] SSE stream error: ${x}. Reconnecting in ${w/1e3}s`)}if(a.signal.aborted)break;await new Promise(y=>setTimeout(y,w)),w=Math.min(w*2,b)}g("disconnected")}function he(e){let s=e.pluginConfig||{},o=s.workerPort||ie;q=s.workerHost||V;let i=s.project||"openclaw",a=de(s.observationFeed?.emojis);function g(r){return r.agentId?`openclaw-${r.agentId}`:i}let p=new Map,m=new Map,w=new Map,b=new Map,y=s.syncMemoryFile!==!1,x=new Set(s.syncMemoryFileExclude||[]);function B(r){let n=r||"default";return p.has(n)||p.set(n,`openclaw-${n}-${Date.now()}`),p.get(n)}function _(r){if(!y)return!1;let n=r?.agentId;return!(n&&x.has(n))}function R(r){let n=new Set;for(let t of[r.sessionKey,r.conversationId,r.channelId]){let c=typeof t=="string"?t.trim():"";c&&n.add(c)}return n.size===0&&n.add("default"),Array.from(n)}function P(r){let n=R(r),t=n.find(u=>m.has(u));t=t?m.get(t):n[0];let c=w.get(t);c||(c=new Set([t]),w.set(t,c));for(let u of n)c.add(u),m.set(u,t);let l=B(t);for(let u of c)p.set(u,l);return{canonicalKey:t,contentSessionId:l}}function F(r,n,t){let c=Date.now();for(let[d,f]of b)c-f>2e3&&b.delete(d);let l=`${r}::${n}::${t}`,u=b.get(l);return b.set(l,c),typeof u=="number"&&c-u<=2e3}function U(r){let n=R(r),t=n.map(l=>m.get(l)).find(Boolean)||n[0],c=w.get(t)||new Set([t,...n]);for(let l of c)m.delete(l),p.delete(l);w.delete(t),p.delete(t)}let D=6e4,A=new Map;async function S(r){let n=[i],t=r?g(r):null;t&&t!==i&&n.push(t);let c=n.join(","),l=A.get(c);if(l&&Date.now()-l.fetchedAt<D)return l.text;let u=await J(o,`/api/context/inject?projects=${encodeURIComponent(c)}`,e.logger);if(u&&u.trim().length>0){let d=u.trim();return A.set(c,{text:d,fetchedAt:Date.now()}),d}return null}async function O(r,n,t){let{contentSessionId:c}=P(r),l=g(r);if(F(c,l,n)){e.logger.info(`[claude-mem] Skipping duplicate prompt init: contentSessionId=${c} project=${l} via=${t}`);return}await Z(o,"/api/sessions/init",{contentSessionId:c,project:l,prompt:n},e.logger),e.logger.info(`[claude-mem] Session initialized via ${t}: contentSessionId=${c} project=${l}`)}e.on("session_start",async(r,n)=>{await O(n,"session start","session_start")}),e.on("message_received",async(r,n)=>{let{canonicalKey:t,contentSessionId:c}=P(n);e.logger.info(`[claude-mem] Message received \u2014 prompt capture deferred to before_agent_start: session=${t} contentSessionId=${c} hasContent=${!!r.content}`)}),e.on("after_compaction",async(r,n)=>{await O(n,"after compaction","after_compaction")}),e.on("before_agent_start",async(r,n)=>{await O(n,r.prompt||"agent run","before_agent_start")}),e.on("before_prompt_build",async(r,n)=>{if(!_(n))return;let t=await S(n);if(t)return e.logger.info(`[claude-mem] Context injected via system prompt for agent=${n.agentId??"unknown"}`),{appendSystemContext:t}}),e.on("tool_result_persist",(r,n)=>{e.logger.info(`[claude-mem] tool_result_persist fired: tool=${r.toolName??"unknown"} agent=${n.agentId??"none"} session=${n.sessionKey??"none"}`);let t=r.toolName;if(!t||t.startsWith("memory_"))return;let{canonicalKey:c,contentSessionId:l}=P(n),u="",d=r.message?.content;Array.isArray(d)&&(u=d.filter(E=>(E.type==="tool_result"||E.type==="text")&&"text"in E).map(E=>String(E.text)).join(`
13
+ `));let f=1e3;u.length>f&&(u=u.slice(0,f));let h=n.workspaceDir||process.cwd();n.workspaceDir||e.logger.info(`[claude-mem] tool_result_persist missing workspaceDir; using process.cwd(): session=${c} tool=${t}`),pe(o,"/api/sessions/observations",{contentSessionId:l,tool_name:t,tool_input:r.params||{},tool_response:u,cwd:h},e.logger)}),e.on("agent_end",async(r,n)=>{let{contentSessionId:t}=P(n),c="";if(Array.isArray(r.messages))for(let l=r.messages.length-1;l>=0;l--){let u=r.messages[l];if(u?.role==="assistant"){typeof u.content=="string"?c=u.content:Array.isArray(u.content)&&(c=u.content.filter(d=>d.type==="text").map(d=>d.text||"").join(`
14
+ `));break}}await Z(o,"/api/sessions/summarize",{contentSessionId:t,last_assistant_message:c},e.logger)}),e.on("session_end",async(r,n)=>{U(n),e.logger.info("[claude-mem] Session tracking cleaned up")}),e.on("gateway_start",async()=>{fe(),p.clear(),A.clear(),b.clear(),m.clear(),w.clear(),e.logger.info("[claude-mem] Gateway started \u2014 session tracking reset")});let C=null,I="disconnected",k=null;e.registerService({id:"claude-mem-observation-feed",start:async r=>{C&&(C.abort(),k&&(await k,k=null));let n=s.observationFeed;if(!n?.enabled){e.logger.info("[claude-mem] Observation feed disabled");return}if(!n.channel||!n.to){e.logger.warn("[claude-mem] Observation feed misconfigured \u2014 channel or target missing");return}e.logger.info(`[claude-mem] Observation feed starting \u2014 channel: ${n.channel}, target: ${n.to}`),C=new AbortController,k=ve(e,o,n.channel,n.to,C,t=>{I=t},a,n.botToken)},stop:async r=>{C&&(C.abort(),C=null),k&&(await k,k=null),I="disconnected",e.logger.info("[claude-mem] Observation feed stopped \u2014 SSE connection closed")}});function K(r,n=5){return!Array.isArray(r)||r.length===0?"No results found.":r.slice(0,n).map((t,c)=>{let l=t,u=String(l.title||l.subtitle||l.text||"Untitled"),d=l.project?` [${String(l.project)}]`:"";return`${c+1}. ${u}${d}`}).join(`
15
+ `)}function j(r,n=10){let t=Number(r);return Number.isFinite(t)?Math.max(1,Math.min(50,Math.trunc(t))):n}e.registerCommand({name:"claude_mem_feed",description:"Show or toggle Claude-Mem observation feed status",acceptsArgs:!0,handler:async r=>{let n=s.observationFeed;if(!n)return{text:"Observation feed not configured. Add observationFeed to your plugin config."};let t=r.args?.trim();return t==="on"?(e.logger.info("[claude-mem] Feed enable requested via command"),{text:"Feed enable requested. Update observationFeed.enabled in your plugin config to persist."}):t==="off"?(e.logger.info("[claude-mem] Feed disable requested via command"),{text:"Feed disable requested. Update observationFeed.enabled in your plugin config to persist."}):{text:["Claude-Mem Observation Feed",`Enabled: ${n.enabled?"yes":"no"}`,`Channel: ${n.channel||"not set"}`,`Target: ${n.to||"not set"}`,`Connection: ${I}`].join(`
16
+ `)}}}),e.registerCommand({name:"claude-mem-search",description:"Search Claude-Mem observations by query",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"";if(!n)return"Usage: /claude-mem-search <query> [limit]";let t=n.split(/\s+/),c=t[t.length-1],l=/^\d+$/.test(c),u=l?j(c,10):10,d=l?t.slice(0,-1).join(" "):n,f=await H(o,`/api/search/observations?query=${encodeURIComponent(d)}&limit=${u}`,e.logger);if(!f)return"Claude-Mem search failed (worker unavailable or invalid response).";let h=Array.isArray(f.items)?f.items:[];return[`Claude-Mem Search: "${d}"`,K(h,u)].join(`
17
+ `)}}),e.registerCommand({name:"claude-mem-recent",description:"Show recent Claude-Mem context for a project",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"",t=n?n.split(/\s+/):[],c=t.length>0?t[t.length-1]:"",l=/^\d+$/.test(c),u=l?j(c,3):3,d=l?t.slice(0,-1).join(" "):n,f=new URLSearchParams;f.set("limit",String(u)),d&&f.set("project",d);let h=await H(o,`/api/context/recent?${f.toString()}`,e.logger);if(!h)return"Claude-Mem recent context failed (worker unavailable or invalid response).";let E=Array.isArray(h.session_summaries)?h.session_summaries:[],W=Array.isArray(h.recent_observations)?h.recent_observations:[];return["Claude-Mem Recent Context",`Project: ${d||"(auto)"}`,`Session summaries: ${E.length}`,`Recent observations: ${W.length}`,K(W,Math.min(5,W.length||5))].join(`
18
+ `)}}),e.registerCommand({name:"claude-mem-timeline",description:"Find best memory match and show nearby timeline events",acceptsArgs:!0,handler:async r=>{let n=r.args?.trim()||"";if(!n)return"Usage: /claude-mem-timeline <query> [depthBefore] [depthAfter]";let t=n.split(/\s+/),c=5,l=5;t.length>=2&&/^\d+$/.test(t[t.length-1])&&(c=j(t.pop(),5)),t.length>=2&&/^\d+$/.test(t[t.length-1])&&(l=j(t.pop(),5));let u=t.join(" "),d=new URLSearchParams({query:u,mode:"auto",depth_before:String(l),depth_after:String(c)}),f=await H(o,`/api/timeline/by-query?${d.toString()}`,e.logger);if(!f)return"Claude-Mem timeline lookup failed (worker unavailable or invalid response).";let h=Array.isArray(f.timeline)?f.timeline:[],E=f.anchor?String(f.anchor):"(none)";return[`Claude-Mem Timeline: "${u}"`,`Anchor: ${E}`,K(h,8)].join(`
19
+ `)}}),e.registerCommand({name:"claude_mem_status",description:"Check Claude-Mem worker health and session status",handler:async()=>{let r=await J(o,"/api/health",e.logger);if(!r)return{text:`Claude-Mem worker unreachable at port ${o}`};try{return{text:["Claude-Mem Worker Status",`Status: ${JSON.parse(r).status||"unknown"}`,`Port: ${o}`,`Active sessions: ${p.size}`,`Observation feed: ${I}`].join(`
20
+ `)}}catch{return{text:"Claude-Mem worker responded but returned unexpected data"}}}}),e.logger.info(`[claude-mem] OpenClaw plugin loaded \u2014 v1.0.0 (worker: ${q}:${o})`)}export{he as default};
@@ -3,7 +3,7 @@
3
3
  "name": "Claude-Mem (Persistent Memory)",
4
4
  "description": "OpenClaw plugin for Claude-Mem. Records observations from embedded runner sessions and streams them to messaging channels.",
5
5
  "kind": "memory",
6
- "version": "13.4.2",
6
+ "version": "13.5.0",
7
7
  "license": "Apache-2.0",
8
8
  "author": "thedotmack",
9
9
  "homepage": "https://claude-mem.ai",
@@ -824,6 +824,9 @@ describe("SSE stream integration", () => {
824
824
  type: "discovery",
825
825
  project: "test",
826
826
  prompt_number: 1,
827
+ narrative: "Discovery observations should keep routine feed messages compact.",
828
+ facts: JSON.stringify(["Routine detail should not be shown"]),
829
+ concepts: JSON.stringify(["compact-feed"]),
827
830
  created_at_epoch: Date.now(),
828
831
  },
829
832
  timestamp: Date.now(),
@@ -840,6 +843,57 @@ describe("SSE stream integration", () => {
840
843
  assert.equal(sentMessages[0].to, "12345");
841
844
  assert.ok(sentMessages[0].text.includes("Test Observation"));
842
845
  assert.ok(sentMessages[0].text.includes("Found something interesting"));
846
+ assert.ok(!sentMessages[0].text.includes("Narrative"));
847
+ assert.ok(!sentMessages[0].text.includes("Routine detail should not be shown"));
848
+ assert.ok(!sentMessages[0].text.includes("compact-feed"));
849
+ assert.ok(sentMessages[0].text.length <= 900);
850
+
851
+ await getService().stop({});
852
+ });
853
+
854
+ it("keeps important feed messages more complete", async () => {
855
+ const { api, sentMessages, getService } = createMockApi({
856
+ workerPort: serverPort,
857
+ observationFeed: { enabled: true, channel: "telegram", to: "12345" },
858
+ });
859
+ claudeMemPlugin(api);
860
+
861
+ await getService().start({});
862
+ await new Promise((resolve) => setTimeout(resolve, 200));
863
+
864
+ for (const res of serverResponses) {
865
+ res.write(
866
+ `data: ${JSON.stringify({
867
+ type: "new_observation",
868
+ observation: {
869
+ id: 2,
870
+ title: "Important Bugfix",
871
+ subtitle: "Fixed a regression",
872
+ type: "bugfix",
873
+ project: "test",
874
+ prompt_number: 1,
875
+ narrative: "This fuller context should stay visible for important feed messages.",
876
+ facts: JSON.stringify([
877
+ "Important fact one is preserved",
878
+ "Important fact two is preserved",
879
+ "Important fact three is preserved",
880
+ ]),
881
+ concepts: JSON.stringify(["important-feed"]),
882
+ created_at_epoch: Date.now(),
883
+ },
884
+ timestamp: Date.now(),
885
+ })}\n\n`
886
+ );
887
+ }
888
+
889
+ await new Promise((resolve) => setTimeout(resolve, 200));
890
+
891
+ assert.equal(sentMessages.length, 1);
892
+ assert.ok(sentMessages[0].text.includes("Narrative"));
893
+ assert.ok(sentMessages[0].text.includes("This fuller context should stay visible"));
894
+ assert.ok(sentMessages[0].text.includes("Important fact three is preserved"));
895
+ assert.ok(sentMessages[0].text.includes("Concepts: important-feed"));
896
+ assert.ok(sentMessages[0].text.length <= 2200);
843
897
 
844
898
  await getService().stop({});
845
899
  });
@@ -156,6 +156,11 @@ interface SSENewObservationEvent {
156
156
 
157
157
  type ConnectionState = "disconnected" | "connected" | "reconnecting";
158
158
 
159
+ const DETAILED_FEED_TYPES = new Set(["security_alert", "security_note", "bugfix", "decision"]);
160
+ const COMPACT_FEED_MAX_CHARS = 900;
161
+ const DETAILED_FEED_MAX_CHARS = 2200;
162
+ const DETAILED_FACT_LIMIT = 5;
163
+
159
164
  interface FeedEmojiConfig {
160
165
  primary?: string;
161
166
  claudeCode?: string;
@@ -397,11 +402,50 @@ function formatObservationMessage(
397
402
  ): string {
398
403
  const title = observation.title || "Untitled";
399
404
  const source = getSourceLabel(observation.project);
400
- let message = `${source}\n**${title}**`;
405
+ const isDetailed = DETAILED_FEED_TYPES.has(observation.type);
406
+ const parts = [`${source}\n**${title}**`];
401
407
  if (observation.subtitle) {
402
- message += `\n${observation.subtitle}`;
408
+ parts.push(truncateText(observation.subtitle, isDetailed ? 500 : 260));
409
+ }
410
+
411
+ if (!isDetailed) {
412
+ return truncateText(parts.join("\n"), COMPACT_FEED_MAX_CHARS);
413
+ }
414
+
415
+ if (observation.narrative) {
416
+ parts.push(`Narrative\n${truncateText(observation.narrative, 900)}`);
417
+ }
418
+
419
+ const facts = parseStringArray(observation.facts).slice(0, DETAILED_FACT_LIMIT);
420
+ if (facts.length > 0) {
421
+ parts.push(`Facts\n${facts.map((fact) => `- ${truncateText(fact, 320)}`).join("\n")}`);
422
+ }
423
+
424
+ const concepts = parseStringArray(observation.concepts).slice(0, 8);
425
+ if (concepts.length > 0) {
426
+ parts.push(`Concepts: ${concepts.join(", ")}`);
427
+ }
428
+
429
+ return truncateText(parts.join("\n\n"), DETAILED_FEED_MAX_CHARS);
430
+ }
431
+
432
+ function truncateText(value: string, maxChars: number): string {
433
+ if (value.length <= maxChars) return value;
434
+ const hardLimit = Math.max(0, maxChars - 3);
435
+ const truncated = value.slice(0, hardLimit);
436
+ const lastWhitespace = truncated.search(/\s+\S*$/);
437
+ const boundary = lastWhitespace > Math.floor(hardLimit * 0.65) ? lastWhitespace : hardLimit;
438
+ return `${truncated.slice(0, boundary).trimEnd()}...`;
439
+ }
440
+
441
+ function parseStringArray(value: string | null | undefined): string[] {
442
+ if (!value) return [];
443
+ try {
444
+ const parsed = JSON.parse(value);
445
+ return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === "string") : [];
446
+ } catch {
447
+ return [];
403
448
  }
404
- return message;
405
449
  }
406
450
 
407
451
  const CHANNEL_SEND_MAP: Record<string, { namespace: string; functionName: string }> = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem",
3
- "version": "13.4.2",
3
+ "version": "13.5.0",
4
4
  "description": "Memory compression system for Claude Code - persist context across sessions",
5
5
  "keywords": [
6
6
  "claude",
@@ -140,6 +140,7 @@
140
140
  "ioredis": "^5.10.1",
141
141
  "pg": "^8.20.0",
142
142
  "picocolors": "^1.1.1",
143
+ "posthog-node": "^5.36.8",
143
144
  "react": "^19.2.6",
144
145
  "react-dom": "^19.2.6",
145
146
  "shell-quote": "^1.8.3",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem",
3
- "version": "13.4.2",
3
+ "version": "13.5.0",
4
4
  "description": "Memory compression system for Claude Code - persist context across sessions",
5
5
  "author": {
6
6
  "name": "Alex Newman"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem",
3
- "version": "13.4.2",
3
+ "version": "13.5.0",
4
4
  "description": "Memory compression system for Claude Code - persist context across sessions",
5
5
  "author": {
6
6
  "name": "Alex Newman",
@@ -7,17 +7,17 @@
7
7
  "hooks": [
8
8
  {
9
9
  "type": "command",
10
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/version-check.js\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: version-check.js not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; CLAUDE_MEM_CODEX_HOOK=1 node \"$_P/scripts/version-check.js\"",
10
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/version-check.js\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: version-check.js not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; CLAUDE_MEM_CODEX_HOOK=1 node \"$_P/scripts/version-check.js\"",
11
11
  "timeout": 5
12
12
  },
13
13
  {
14
14
  "type": "command",
15
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" start",
15
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" start",
16
16
  "timeout": 60
17
17
  },
18
18
  {
19
19
  "type": "command",
20
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex context",
20
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex context",
21
21
  "timeout": 60,
22
22
  "statusMessage": "Loading claude-mem context"
23
23
  }
@@ -29,7 +29,7 @@
29
29
  "hooks": [
30
30
  {
31
31
  "type": "command",
32
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex session-init",
32
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex session-init",
33
33
  "timeout": 60
34
34
  }
35
35
  ]
@@ -41,7 +41,7 @@
41
41
  "hooks": [
42
42
  {
43
43
  "type": "command",
44
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex file-context",
44
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex file-context",
45
45
  "timeout": 30
46
46
  }
47
47
  ]
@@ -53,7 +53,7 @@
53
53
  "hooks": [
54
54
  {
55
55
  "type": "command",
56
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex observation",
56
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex observation",
57
57
  "timeout": 120
58
58
  }
59
59
  ]
@@ -64,7 +64,7 @@
64
64
  "hooks": [
65
65
  {
66
66
  "type": "command",
67
- "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex summarize",
67
+ "command": "_HP=$(printenv PATH 2>/dev/null || true); if [ -z \"$_HP\" ] && [ -n \"${SHELL:-}\" ]; then _HP=$(\"$SHELL\" -lc 'printf %s \"$PATH\"' 2>/dev/null || true); fi; _HP=$(printf '%s' \"$_HP\" | tr ' ' ':'); export PATH=\"${_HP:+$_HP:}$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook codex summarize",
68
68
  "timeout": 60
69
69
  }
70
70
  ]
@@ -8,7 +8,7 @@
8
8
  {
9
9
  "type": "command",
10
10
  "shell": "bash",
11
- "command": "export PATH=\"$HOME/.nvm/versions/node/v$(ls \\\"$HOME/.nvm/versions/node\\\" 2>/dev/null | sed 's/^v//' | sort -t. -k1,1n -k2,2n -k3,3n | tail -1)/bin:$HOME/.local/bin:/usr/local/bin:/opt/homebrew/bin:$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/version-check.js\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: version-check.js not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/version-check.js\"",
11
+ "command": "export PATH=\"$HOME/.nvm/versions/node/v$(ls \\\"$HOME/.nvm/versions/node\\\" 2>/dev/null | sed 's/^v//' | sort -t. -k1,1n -k2,2n -k3,3n | tail -1)/bin:$HOME/.local/bin:/usr/local/bin:/opt/homebrew/bin:$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/version-check.js\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: version-check.js not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/version-check.js\"",
12
12
  "timeout": 300
13
13
  }
14
14
  ]
@@ -21,13 +21,13 @@
21
21
  {
22
22
  "type": "command",
23
23
  "shell": "bash",
24
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" start; echo '{\"continue\":true,\"suppressOutput\":true}'",
24
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" start; echo '{\"continue\":true,\"suppressOutput\":true}'",
25
25
  "timeout": 60
26
26
  },
27
27
  {
28
28
  "type": "command",
29
29
  "shell": "bash",
30
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code context",
30
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code context",
31
31
  "timeout": 60
32
32
  }
33
33
  ]
@@ -39,7 +39,7 @@
39
39
  {
40
40
  "type": "command",
41
41
  "shell": "bash",
42
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code session-init",
42
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code session-init",
43
43
  "timeout": 60
44
44
  }
45
45
  ]
@@ -52,7 +52,7 @@
52
52
  {
53
53
  "type": "command",
54
54
  "shell": "bash",
55
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code observation",
55
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code observation",
56
56
  "timeout": 120
57
57
  }
58
58
  ]
@@ -65,7 +65,7 @@
65
65
  {
66
66
  "type": "command",
67
67
  "shell": "bash",
68
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code file-context",
68
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code file-context",
69
69
  "timeout": 60
70
70
  }
71
71
  ]
@@ -77,7 +77,7 @@
77
77
  {
78
78
  "type": "command",
79
79
  "shell": "bash",
80
- "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && { printf '%s\\n' \"$_Q\"; break; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code summarize",
80
+ "command": "export PATH=\"$($SHELL -lc 'echo $PATH' 2>/dev/null):$PATH\"; _C=\"${CLAUDE_CONFIG_DIR:-$HOME/.claude}\"; _E=\"${CLAUDE_PLUGIN_ROOT:-${PLUGIN_ROOT:-}}\"; _F=; _P=$({ [ -n \"$_E\" ] && printf '%s\\n' \"$_E\"; ls -dt \"$_C/plugins/cache/thedotmack/claude-mem\"/[0-9]*/ 2>/dev/null; printf '%s\\n' \"$_C/plugins/marketplaces/thedotmack/plugin\"; } | while IFS= read -r _R; do _R=\"${_R%/}\"; [ -d \"$_R/plugin/scripts\" ] && _Q=\"$_R/plugin\" || _Q=\"$_R\"; [ -f \"$_Q/scripts/bun-runner.js\" ] && [ -f \"$_Q/scripts/worker-service.cjs\" ] && [ -z \"$_F\" ] && { _F=1; printf '%s\\n' \"$_Q\"; }; done); [ -n \"$_P\" ] || { echo \"claude-mem: plugin scripts not found\" >&2; exit 1; }; command -v cygpath >/dev/null 2>&1 && { _W=$(cygpath -w \"$_P\" 2>/dev/null); [ -n \"$_W\" ] && _P=\"$_W\"; }; node \"$_P/scripts/bun-runner.js\" \"$_P/scripts/worker-service.cjs\" hook claude-code summarize",
81
81
  "timeout": 120
82
82
  }
83
83
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-plugin",
3
- "version": "13.4.2",
3
+ "version": "13.5.0",
4
4
  "private": true,
5
5
  "description": "Runtime dependencies for claude-mem bundled hooks",
6
6
  "type": "module",