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}
**${o}**`];if(e.subtitle&&g.push(T(e.subtitle,a?500:260)),!a)return T(g.join(`
`),te);e.narrative&&g.push(`Narrative
${T(e.narrative,900)}`);let p=Q(e.facts).slice(0,se);p.length>0&&g.push(`Facts
${p.map(w=>`- ${T(w,320)}`).join(`
`)}`);let m=Q(e.concepts).slice(0,8);return m.length>0&&g.push(`Concepts: ${m.join(", ")}`),T(g.join(`

`),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(`

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