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.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +3 -3
- package/dist/npx-cli/index.js +359 -353
- package/dist/opencode-plugin/index.js +8 -8
- package/openclaw/dist/index.js +19 -14
- package/openclaw/openclaw.plugin.json +1 -1
- package/openclaw/src/index.test.ts +54 -0
- package/openclaw/src/index.ts +47 -3
- package/package.json +2 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/hooks/codex-hooks.json +7 -7
- package/plugin/hooks/hooks.json +7 -7
- package/plugin/package.json +1 -1
- package/plugin/scripts/context-generator.cjs +92 -79
- package/plugin/scripts/mcp-server.cjs +30 -30
- package/plugin/scripts/server-beta-service.cjs +125 -125
- package/plugin/scripts/transcript-watcher.cjs +11 -11
- package/plugin/scripts/worker-service.cjs +299 -273
- package/plugin/skills/standup/SKILL.md +1 -16
package/openclaw/dist/index.js
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
var
|
|
2
|
-
**${o}
|
|
3
|
-
|
|
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
|
-
`);
|
|
6
|
-
|
|
7
|
-
`);
|
|
8
|
-
`)
|
|
9
|
-
`));
|
|
10
|
-
`)
|
|
11
|
-
`)}}}),e.
|
|
12
|
-
`)}
|
|
13
|
-
`)}}),e.registerCommand({name:"claude-mem-
|
|
14
|
-
`)}}),e.registerCommand({name:"
|
|
15
|
-
`)}}
|
|
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.
|
|
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
|
});
|
package/openclaw/src/index.ts
CHANGED
|
@@ -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
|
-
|
|
405
|
+
const isDetailed = DETAILED_FEED_TYPES.has(observation.type);
|
|
406
|
+
const parts = [`${source}\n**${title}**`];
|
|
401
407
|
if (observation.subtitle) {
|
|
402
|
-
|
|
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.
|
|
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",
|
|
@@ -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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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
|
]
|
package/plugin/hooks/hooks.json
CHANGED
|
@@ -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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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\";
|
|
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
|
]
|