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)}
**${o}**`;return e.subtitle&&(l+=`
${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(`

`);_=L.pop()||"";for(let B of L){let F=B.split(`
`).filter(S=>S.startsWith("data:")).map(S=>S.slice(5).trim());if(F.length===0)continue;let A=F.join(`
`);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(`
`));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(`
`));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(`
`)}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(`
`)}}}),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(`
`)}}),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(`
`)}}),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(`
`)}}),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(`
`)}}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};
