claude-mem 12.6.0 → 12.6.1
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/dist/npx-cli/index.js +1 -1
- package/dist/opencode-plugin/index.js +5 -5
- package/openclaw/openclaw.plugin.json +1 -1
- package/package.json +26 -26
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/plugin/scripts/mcp-server.cjs +23 -23
- package/plugin/scripts/worker-service.cjs +173 -173
package/dist/npx-cli/index.js
CHANGED
|
@@ -403,7 +403,7 @@ ${s.trim()}`)};switch(e){case"claude-code":return{title:"Claude Code: registerin
|
|
|
403
403
|
`}
|
|
404
404
|
# Added by claude-mem installer for Claude Code
|
|
405
405
|
${c}
|
|
406
|
-
`;na(s,l+f,"utf-8"),x.success(`Added Claude Code to PATH in ${s}`)}catch(p){x.warn(`Could not update ${s}: ${p instanceof Error?p.message:String(p)}`),x.info(`Run manually: echo '${c}' >> ${s}`);return}process.env.PATH=`${t}:${r}`}async function Id(){let e=pe?'powershell -ExecutionPolicy ByPass -c "irm https://claude.ai/install.ps1 | iex"':"curl -fsSL https://claude.ai/install.sh | bash",t=F?It():null;return t?.start("Installing Claude Code (this can take a few minutes \u2014 downloading the native build)\u2026"),new Promise(n=>{let r="",o=Ee(e,[],{shell:pe?process.env.ComSpec??"cmd.exe":"/bin/bash",stdio:t?["inherit","pipe","pipe"]:"inherit"});o.stdout?.on("data",s=>{r+=s.toString()}),o.stderr?.on("data",s=>{r+=s.toString()}),o.on("error",s=>{t?.stop("Claude Code install failed",1),r&&process.stderr.write(r),x.error(`Claude Code install failed: ${s.message}`),x.info("You can install it manually later: https://claude.ai/install.sh"),n(!1)}),o.on("exit",s=>{if(s!==0){t?.stop("Claude Code install failed",1),r&&process.stderr.write(r),x.error(`Claude Code install failed (exit ${s??"unknown"})`),x.info("You can install it manually later: https://claude.ai/install.sh"),n(!1);return}if(t?.stop("Claude Code installed"),!pe)try{Rd()}catch(i){x.warn(`Could not auto-apply PATH setup: ${i instanceof Error?i.message:String(i)}`)}n(!0)})})}async function Od(){let e=rt(),t=e.find(s=>s.id==="claude-code");if(t&&!t.detected){x.warn("Claude Code is not installed. Claude-mem works best in Claude Code, but also works with the IDEs below.");let s=await Sn({message:"Install Claude Code now?",options:[{value:"install",label:"Yes \u2014 install Claude Code (recommended)"},{value:"skip",label:"No \u2014 pick another IDE below"},{value:"cancel",label:"Cancel installation"}],initialValue:"install"});(se(s)||s==="cancel")&&(De("Installation cancelled."),process.exit(0)),s==="install"&&await Id()&&(e=rt())}e.filter(s=>s.detected).length===0&&x.warn("No supported IDEs detected \u2014 pick the one(s) you plan to use.");let r=e.map(s=>{let i=s.detected?" [detected]":"",a=s.supported?`${s.hint}${i}`:`coming soon${i}`;return{value:s.id,label:s.label,hint:a}}),o=await $o({message:"Which IDEs do you use?",options:r,initialValues:[],required:!0});return se(o)&&(De("Installation cancelled."),process.exit(0)),o}function Pd(){let e=q(),t=on();Ct(e);let n=["plugin","package.json","package-lock.json","openclaw","dist","LICENSE","README.md","CHANGELOG.md"];for(let r of n){let o=ne(t,r),s=ne(e,r);ge(o)&&(ge(s)&&ta(s,{recursive:!0,force:!0}),$i(o,s,{recursive:!0,force:!0}))}}function sa(e){let t=_n(),n=qe(e);ta(n,{recursive:!0,force:!0}),Ct(n),$i(t,n,{recursive:!0,force:!0})}function Dd(){let e=q(),t=ne(e,"package.json");ge(t)&&vd("npm install --
|
|
406
|
+
`;na(s,l+f,"utf-8"),x.success(`Added Claude Code to PATH in ${s}`)}catch(p){x.warn(`Could not update ${s}: ${p instanceof Error?p.message:String(p)}`),x.info(`Run manually: echo '${c}' >> ${s}`);return}process.env.PATH=`${t}:${r}`}async function Id(){let e=pe?'powershell -ExecutionPolicy ByPass -c "irm https://claude.ai/install.ps1 | iex"':"curl -fsSL https://claude.ai/install.sh | bash",t=F?It():null;return t?.start("Installing Claude Code (this can take a few minutes \u2014 downloading the native build)\u2026"),new Promise(n=>{let r="",o=Ee(e,[],{shell:pe?process.env.ComSpec??"cmd.exe":"/bin/bash",stdio:t?["inherit","pipe","pipe"]:"inherit"});o.stdout?.on("data",s=>{r+=s.toString()}),o.stderr?.on("data",s=>{r+=s.toString()}),o.on("error",s=>{t?.stop("Claude Code install failed",1),r&&process.stderr.write(r),x.error(`Claude Code install failed: ${s.message}`),x.info("You can install it manually later: https://claude.ai/install.sh"),n(!1)}),o.on("exit",s=>{if(s!==0){t?.stop("Claude Code install failed",1),r&&process.stderr.write(r),x.error(`Claude Code install failed (exit ${s??"unknown"})`),x.info("You can install it manually later: https://claude.ai/install.sh"),n(!1);return}if(t?.stop("Claude Code installed"),!pe)try{Rd()}catch(i){x.warn(`Could not auto-apply PATH setup: ${i instanceof Error?i.message:String(i)}`)}n(!0)})})}async function Od(){let e=rt(),t=e.find(s=>s.id==="claude-code");if(t&&!t.detected){x.warn("Claude Code is not installed. Claude-mem works best in Claude Code, but also works with the IDEs below.");let s=await Sn({message:"Install Claude Code now?",options:[{value:"install",label:"Yes \u2014 install Claude Code (recommended)"},{value:"skip",label:"No \u2014 pick another IDE below"},{value:"cancel",label:"Cancel installation"}],initialValue:"install"});(se(s)||s==="cancel")&&(De("Installation cancelled."),process.exit(0)),s==="install"&&await Id()&&(e=rt())}e.filter(s=>s.detected).length===0&&x.warn("No supported IDEs detected \u2014 pick the one(s) you plan to use.");let r=e.map(s=>{let i=s.detected?" [detected]":"",a=s.supported?`${s.hint}${i}`:`coming soon${i}`;return{value:s.id,label:s.label,hint:a}}),o=await $o({message:"Which IDEs do you use?",options:r,initialValues:[],required:!0});return se(o)&&(De("Installation cancelled."),process.exit(0)),o}function Pd(){let e=q(),t=on();Ct(e);let n=["plugin","package.json","package-lock.json","openclaw","dist","LICENSE","README.md","CHANGELOG.md"];for(let r of n){let o=ne(t,r),s=ne(e,r);ge(o)&&(ge(s)&&ta(s,{recursive:!0,force:!0}),$i(o,s,{recursive:!0,force:!0}))}}function sa(e){let t=_n(),n=qe(e);ta(n,{recursive:!0,force:!0}),Ct(n),$i(t,n,{recursive:!0,force:!0})}function Dd(){let e=q(),t=ne(e,"package.json");ge(t)&&vd("npm install --omit=dev --legacy-peer-deps",{cwd:e,stdio:"pipe",encoding:"utf8",...pe?{shell:process.env.ComSpec??"cmd.exe"}:{}})}function ft(e){let t=yn;try{let n={};if(ge(t))try{let r=po(t,"utf-8"),o=JSON.parse(r);o&&typeof o=="object"&&o.env&&typeof o.env=="object"?n={...o.env}:o&&typeof o=="object"&&(n={...o})}catch(r){console.warn("[install] Failed to parse existing settings.json, starting from empty:",r instanceof Error?r.message:String(r)),n={}}else{let r=oa(t);ge(r)||ea(r,{recursive:!0})}for(let[r,o]of Object.entries(e))n[r]=o;return na(t,JSON.stringify(n,null,2),"utf-8"),!0}catch(n){return x.error(`Failed to write settings to ${t}: ${n instanceof Error?n.message:String(n)}`),!1}}async function Nd(e){let t=gt("CLAUDE_MEM_PROVIDER")||"claude",n=()=>{ft({CLAUDE_MEM_PROVIDER:"claude"})&&x.info("Saved provider=claude to ~/.claude-mem/settings.json")};if(!F)return e.provider?e.provider==="claude"?(n(),"claude"):(ft({CLAUDE_MEM_PROVIDER:e.provider})&&x.info(`Saved provider=${e.provider} to ~/.claude-mem/settings.json`),x.warn(`Provider=${e.provider} requested non-interactively. API key prompt skipped \u2014 set CLAUDE_MEM_${e.provider.toUpperCase()}_API_KEY and CLAUDE_MEM_PROVIDER in settings.json or env manually if not already set.`),e.provider):t;let r;if(e.provider)r=e.provider;else{let p=await Sn({message:"Which LLM provider should claude-mem use to compress observations?",options:[{value:"claude",label:"Claude Code auth (default \u2014 no extra setup, uses your existing Claude Code subscription)"},{value:"gemini",label:"Gemini API key (free tier available \u2014 fast and cheap)"},{value:"openrouter",label:"OpenRouter API key (BYO model \u2014 wide selection of frontier and open models)"}],initialValue:t});se(p)&&(De("Installation cancelled."),process.exit(0)),r=p}if(r==="claude")return n(),"claude";let o=r==="gemini"?"Gemini":"OpenRouter",s=r==="gemini"?"CLAUDE_MEM_GEMINI_API_KEY":"CLAUDE_MEM_OPENROUTER_API_KEY",i=gt(s);if(i&&i.trim().length>0)return ft({CLAUDE_MEM_PROVIDER:r})&&x.info(`Saved provider=${r} to ~/.claude-mem/settings.json`),r;let a=await es({message:`Paste your ${o} API key:`,mask:"*",validate:p=>!p||p.trim().length===0?"API key required":void 0});if(se(a))return x.warn("API key prompt cancelled \u2014 falling back to Claude provider."),n(),"claude";let c=String(a).trim();return ft({CLAUDE_MEM_PROVIDER:r,[s]:c})&&x.info(`Saved provider=${r} to ~/.claude-mem/settings.json`),r}async function Ad(e){let t=new Set(["claude-haiku-4-5-20251001","claude-sonnet-4-6","claude-opus-4-7"]);if(e.model){if(!t.has(e.model))throw new Error(`Unknown Claude model: ${e.model}. Allowed: ${[...t].join(", ")}`);ft({CLAUDE_MEM_MODEL:e.model})&&x.info(`Saved Claude model=${e.model} to ~/.claude-mem/settings.json`);return}if(!F)return;let n=gt("CLAUDE_MEM_MODEL"),r=t.has(n)?n:"claude-haiku-4-5-20251001",o=await Sn({message:`Which Claude model should claude-mem use to compress observations?
|
|
407
407
|
This runs whenever you and Claude touch a file \u2014 keep it cheap and fast.`,options:[{value:"claude-haiku-4-5-20251001",label:"Haiku 4.5 (recommended \u2014 fast, cheap, great for compression)"},{value:"claude-sonnet-4-6",label:"Sonnet 4.6 (balanced quality and cost)"},{value:"claude-opus-4-7",label:"Opus 4.7 (highest quality, most expensive)"}],initialValue:r});se(o)&&(De("Installation cancelled."),process.exit(0));let s=o;ft({CLAUDE_MEM_MODEL:s})&&x.info(`Saved Claude model=${s} to ~/.claude-mem/settings.json`)}async function Ld(e={}){let t=Xe();F?(await qs(),Tt(m.default.bgCyan(m.default.black(" claude-mem install ")))):console.log("claude-mem install");let n=q(),r=ge(ne(n,"plugin",".claude-plugin","plugin.json")),o;if(r)try{o=JSON.parse(po(ne(n,"plugin",".claude-plugin","plugin.json"),"utf-8")).version??void 0}catch(y){console.warn("[install] Failed to read existing plugin version:",y instanceof Error?y.message:String(y))}let s=m.default.dim("\xB7"),i=[`${m.default.bold("claude-mem")} ${m.default.cyan(`v${t}`)}`];if(o&&o!==t?i.push(`installed ${m.default.yellow(`v${o}`)}`):o&&i.push(m.default.dim("reinstall")),x.info(i.join(` ${s} `)),r&&process.stdin.isTTY){let y=await xt({message:"Overwrite existing installation?",initialValue:!0});(se(y)||!y)&&(De("Installation cancelled."),process.exit(0))}let a;if(e.ide){a=[e.ide];let y=rt(),S=y.find(E=>E.id===e.ide);S&&!S.supported&&(x.error(`Support for ${S.label} coming soon.`),process.exit(1)),S||(x.error(`Unknown IDE: ${e.ide}`),x.info(`Available IDEs: ${y.map(E=>E.id).join(", ")}`),process.exit(1))}else process.stdin.isTTY?a=await Od():a=["claude-code"];await Nd(e)==="claude"&&await Ad(e);let l="dead",p=a.length>0;{if(p){let S=gt("CLAUDE_MEM_WORKER_PORT"),E=F?It():null;E?.start("Stopping running worker (so we can overwrite cleanly)\u2026");try{let P=await kn(S,1e4);E?E.stop(P.workerWasRunning?"Stopped running worker before overwrite.":"No worker running \u2014 proceeding."):P.workerWasRunning&&x.info("Stopped running worker before overwrite.")}catch(P){let U=P instanceof Error?P.message:String(P);E?E.stop(`Pre-overwrite worker shutdown failed: ${U}`,1):console.warn("[install] Pre-overwrite worker shutdown failed:",U)}}let y=[{title:"Caching plugin version",task:async S=>(S(`Caching v${t}...`),sa(t),`Plugin cached (v${t}) ${m.default.green("OK")}`)},{title:"Registering marketplace",task:async()=>(Cd(),`Marketplace registered ${m.default.green("OK")}`)},{title:"Registering plugin",task:async()=>(bd(t),`Plugin registered ${m.default.green("OK")}`)},{title:"Enabling plugin in Claude settings",task:async()=>(kd(),`Plugin enabled ${m.default.green("OK")}`)},{title:"Setting up runtime (first install can take ~30s)",task:async S=>{S("Checking Bun\u2026");let{version:E}=await Ut();S("Checking uv\u2026");let{version:P}=await Pr(),U=qe(t);if(!Hs(U,t)){S("Installing plugin dependencies\u2026");let{bunPath:z}=await Ut();await Dr(U,z),Nr(U,t,E,P)}return`Runtime ready (Bun ${E}, uv ${P}) ${m.default.green("OK")}`}}];p&&(y.unshift({title:"Copying plugin files to marketplace",task:async S=>(S("Copying to marketplace directory..."),Pd(),`Plugin files copied ${m.default.green("OK")}`)}),y.push({title:"Installing marketplace dependencies",task:async S=>{S("Running npm install...");try{return Dd(),`Dependencies installed ${m.default.green("OK")}`}catch(E){return console.warn("[install] npm install error:",E instanceof Error?E.message:String(E)),`Dependencies may need manual install ${m.default.yellow("!")}`}}})),await Yn(y)}let f=await xd(a),g=!F||e.noAutoStart;await Yn([{title:"Starting worker daemon",task:async y=>{if(g)return F?"Skipped (--no-auto-start)":"Skipped (non-TTY)";let S=Number(gt("CLAUDE_MEM_WORKER_PORT")),E=ne(q(),"plugin","scripts","worker-service.cjs"),P=ne(qe(t),"scripts","worker-service.cjs"),U=ge(E)?E:P;switch(y(`Spawning worker on port ${S}...`),l=await Ls(S,U),l){case"ready":return`Worker ready at http://localhost:${S} ${m.default.green("OK")}`;case"warming":return`Worker starting on port ${S} \u2014 finishing in background ${m.default.yellow("\u23F3")}`;case"dead":return`Worker did not start \u2014 try \`npx claude-mem start\` manually ${m.default.yellow("!")}`}}}]);let v=f.length>0?"Installation Partial":"Installation Complete",h=[`Version: ${m.default.cyan(t)}`,`Plugin dir: ${m.default.cyan(n)}`,`IDEs: ${m.default.cyan(a.join(", "))}`];f.length>0&&h.push(`Failed: ${m.default.red(f.join(", "))}`),F?Rt(h.join(`
|
|
408
408
|
`),v):(console.log(`
|
|
409
409
|
${v}`),h.forEach(y=>console.log(` ${y}`)));let C=gt("CLAUDE_MEM_WORKER_PORT"),I=C,A=!1;if(!g){let y=F?It():null;y?.start(`Verifying worker on port ${C}\u2026`);try{let S=await fetch(`http://127.0.0.1:${C}/api/health`,{signal:AbortSignal.timeout(3e3)});if(S.ok){A=!0;try{let E=await S.json();E&&(typeof E.port=="number"||typeof E.port=="string")&&(I=E.port)}catch{}}y?.stop(A?`Worker ready at http://localhost:${I}`:`Worker reachable but not ready on port ${C}`)}catch{y?.stop(`Worker not yet responding on port ${C} (still starting)`)}}let Y=l,V=Y!=="dead"||A,G=g?`${m.default.yellow("!")} Worker autostart skipped \u2014 start it manually with ${m.default.bold("npx claude-mem start")}`:A||Y==="ready"?`${m.default.green("\u2713")} Worker running at ${m.default.underline(`http://localhost:${I}`)}`:`${m.default.yellow("\u23F3")} Worker starting at ${m.default.underline(`http://localhost:${I}`)} \u2014 give it ~30s, then refresh`,R=g?[G,"",`${m.default.bold("First success:")} once the worker is running, keep ${m.default.underline(`http://localhost:${C}`)} open in a browser, then open Claude Code in any project. Observations stream in as Claude reads, edits, and runs commands.`,"",`${m.default.bold("Two paths from here:")}`,` ${m.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${m.default.cyan("B.")} Front-load it: open Claude Code and run ${m.default.bold("/learn-codebase")} to ingest the whole repo (~5 min, optional).`,"","Memory injection starts on your second session in a project.",`Everything stays in ${m.default.cyan("~/.claude-mem")} on this machine.`,"",`${m.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${m.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.claude-mem will be recreated by active hooks.")}`]:V?[G,"",`${m.default.bold("First success:")} keep that URL open in a browser, then open Claude Code in any project. Observations stream in as Claude reads, edits, and runs commands.`,"",`${m.default.bold("Two paths from here:")}`,` ${m.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${m.default.cyan("B.")} Front-load it: open Claude Code and run ${m.default.bold("/learn-codebase")} to ingest the whole repo (~5 min, optional).`,"","Memory injection starts on your second session in a project.",`Everything stays in ${m.default.cyan("~/.claude-mem")} on this machine.`,"",`${m.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${m.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.claude-mem will be recreated by active hooks.")}`]:[`${m.default.yellow("!")} Worker not yet ready on port ${m.default.cyan(String(C))} -- still starting up; check ${m.default.bold("claude-mem status")} later, or start manually: ${m.default.bold("npx claude-mem start")}`,"",`${m.default.bold("First success:")} keep ${m.default.underline(`http://localhost:${C}`)} open in a browser, then open Claude Code in any project. Observations stream in as Claude reads, edits, and runs commands.`,"",`${m.default.bold("Two paths from here:")}`,` ${m.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${m.default.cyan("B.")} Front-load it: open Claude Code and run ${m.default.bold("/learn-codebase")} to ingest the whole repo (~5 min, optional).`,"","Memory injection starts on your second session in a project.",`Everything stays in ${m.default.cyan("~/.claude-mem")} on this machine.`,"",`${m.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${m.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.claude-mem will be recreated by active hooks.")}`];F?(Rt(R.join(`
|