keepmind 1.0.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/.agents/plugins/marketplace.json +20 -0
- package/.codex-plugin/plugin.json +46 -0
- package/LICENSE +202 -0
- package/README.md +139 -0
- package/dist/npx-cli/index.js +1398 -0
- package/dist/opencode-plugin/index.js +68 -0
- package/openclaw/Dockerfile.e2e +46 -0
- package/openclaw/SKILL.md +462 -0
- package/openclaw/TESTING.md +279 -0
- package/openclaw/dist/index.js +20 -0
- package/openclaw/e2e-verify.sh +222 -0
- package/openclaw/install.sh +1653 -0
- package/openclaw/openclaw.plugin.json +98 -0
- package/openclaw/package.json +21 -0
- package/openclaw/skills/do/SKILL.md +1 -0
- package/openclaw/skills/make-plan/SKILL.md +1 -0
- package/openclaw/src/index.test.ts +1178 -0
- package/openclaw/src/index.ts +1136 -0
- package/openclaw/test-e2e.sh +40 -0
- package/openclaw/test-install.sh +2086 -0
- package/openclaw/test-sse-consumer.js +98 -0
- package/openclaw/tsconfig.json +26 -0
- package/package.json +187 -0
- package/plugin/.claude-plugin/plugin.json +24 -0
- package/plugin/.codex-plugin/plugin.json +46 -0
- package/plugin/.mcp.json +12 -0
- package/plugin/bun.lock +325 -0
- package/plugin/hooks/bugfixes-2026-01-10.md +92 -0
- package/plugin/hooks/codex-hooks.json +63 -0
- package/plugin/hooks/hooks.json +117 -0
- package/plugin/modes/code--ar.json +24 -0
- package/plugin/modes/code--bn.json +24 -0
- package/plugin/modes/code--chill.json +8 -0
- package/plugin/modes/code--cs.json +24 -0
- package/plugin/modes/code--da.json +24 -0
- package/plugin/modes/code--de.json +24 -0
- package/plugin/modes/code--el.json +24 -0
- package/plugin/modes/code--es.json +24 -0
- package/plugin/modes/code--fi.json +24 -0
- package/plugin/modes/code--fr.json +24 -0
- package/plugin/modes/code--he.json +24 -0
- package/plugin/modes/code--hi.json +24 -0
- package/plugin/modes/code--hu.json +24 -0
- package/plugin/modes/code--id.json +24 -0
- package/plugin/modes/code--it.json +24 -0
- package/plugin/modes/code--ja.json +24 -0
- package/plugin/modes/code--ko.json +24 -0
- package/plugin/modes/code--nl.json +24 -0
- package/plugin/modes/code--no.json +24 -0
- package/plugin/modes/code--pl.json +24 -0
- package/plugin/modes/code--pt-br.json +24 -0
- package/plugin/modes/code--ro.json +24 -0
- package/plugin/modes/code--ru.json +24 -0
- package/plugin/modes/code--sv.json +24 -0
- package/plugin/modes/code--th.json +24 -0
- package/plugin/modes/code--tr.json +24 -0
- package/plugin/modes/code--uk.json +24 -0
- package/plugin/modes/code--ur.json +25 -0
- package/plugin/modes/code--vi.json +24 -0
- package/plugin/modes/code--zh.json +24 -0
- package/plugin/modes/code.json +139 -0
- package/plugin/modes/email-investigation.json +120 -0
- package/plugin/modes/law-study--chill.json +7 -0
- package/plugin/modes/law-study-CLAUDE.md +85 -0
- package/plugin/modes/law-study.json +120 -0
- package/plugin/modes/meme-tokens.json +125 -0
- package/plugin/package.json +47 -0
- package/plugin/scripts/bun-runner.js +229 -0
- package/plugin/scripts/context-generator.cjs +1005 -0
- package/plugin/scripts/mcp-server.cjs +247 -0
- package/plugin/scripts/statusline-counts.js +45 -0
- package/plugin/scripts/transcript-watcher.cjs +27 -0
- package/plugin/scripts/version-check.js +193 -0
- package/plugin/scripts/worker-cli.js +19 -0
- package/plugin/scripts/worker-service.cjs +2638 -0
- package/plugin/scripts/worker-wrapper.cjs +2 -0
- package/plugin/skills/babysit/SKILL.md +87 -0
- package/plugin/skills/design-is/SKILL.md +312 -0
- package/plugin/skills/do/SKILL.md +45 -0
- package/plugin/skills/how-it-works/SKILL.md +22 -0
- package/plugin/skills/how-it-works/onboarding-explainer.md +17 -0
- package/plugin/skills/knowledge-agent/SKILL.md +80 -0
- package/plugin/skills/learn-codebase/SKILL.md +21 -0
- package/plugin/skills/make-plan/SKILL.md +67 -0
- package/plugin/skills/mem-search/SKILL.md +131 -0
- package/plugin/skills/oh-my-issues/SKILL.md +226 -0
- package/plugin/skills/pathfinder/SKILL.md +111 -0
- package/plugin/skills/smart-explore/SKILL.md +193 -0
- package/plugin/skills/standup/SKILL.md +142 -0
- package/plugin/skills/standup/agent-brief.md +47 -0
- package/plugin/skills/standup/standup.mjs +662 -0
- package/plugin/skills/timeline-report/SKILL.md +211 -0
- package/plugin/skills/version-bump/SKILL.md +74 -0
- package/plugin/skills/version-bump/scripts/generate_changelog.js +34 -0
- package/plugin/skills/weekly-digests/SKILL.md +262 -0
- package/plugin/skills/what-the/SKILL.md +6 -0
- package/plugin/skills/wowerpoint/SKILL.md +205 -0
- package/plugin/ui/assets/fonts/monaspace-radon-var.woff +0 -0
- package/plugin/ui/assets/fonts/monaspace-radon-var.woff2 +0 -0
- package/plugin/ui/icon-thick-completed.svg +8 -0
- package/plugin/ui/icon-thick-investigated.svg +8 -0
- package/plugin/ui/icon-thick-learned.svg +12 -0
- package/plugin/ui/icon-thick-next-steps.svg +8 -0
- package/plugin/ui/viewer-bundle.js +65 -0
- package/plugin/ui/viewer.html +3302 -0
|
@@ -0,0 +1,1398 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var Ku=Object.create;var es=Object.defineProperty;var Xu=Object.getOwnPropertyDescriptor;var Vu=Object.getOwnPropertyNames;var Yu=Object.getPrototypeOf,qu=Object.prototype.hasOwnProperty;var b=(t,e,r)=>()=>{if(r)throw r[0];try{return t&&(e=t(t=0)),e}catch(n){throw r=[n],n}};var Ai=(t,e)=>()=>{try{return e||t((e={exports:{}}).exports,e),e.exports}catch(r){throw e=0,r}},de=(t,e)=>{for(var r in e)es(t,r,{get:e[r],enumerable:!0})},zu=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Vu(e))!qu.call(t,s)&&s!==r&&es(t,s,{get:()=>e[s],enumerable:!(n=Xu(e,s))||n.enumerable});return t};var He=(t,e,r)=>(r=t!=null?Ku(Yu(t)):{},zu(e||!t||!t.__esModule?es(r,"default",{value:t,enumerable:!0}):r,t));var rt=Ai((zE,ts)=>{var Hr=process||{},Mi=Hr.argv||[],Br=Hr.env||{},Zu=!(Br.NO_COLOR||Mi.includes("--no-color"))&&(!!Br.FORCE_COLOR||Mi.includes("--color")||Hr.platform==="win32"||(Hr.stdout||{}).isTTY&&Br.TERM!=="dumb"||!!Br.CI),Qu=(t,e,r=t)=>n=>{let s=""+n,o=s.indexOf(e,t.length);return~o?t+$u(s,e,r,o)+e:t+s+e},$u=(t,e,r,n)=>{let s="",o=0;do s+=t.substring(o,n)+r,o=n+e.length,n=t.indexOf(e,o);while(~n);return s+t.substring(o)},xi=(t=Zu)=>{let e=t?Qu:()=>String;return{isColorSupported:t,reset:e("\x1B[0m","\x1B[0m"),bold:e("\x1B[1m","\x1B[22m","\x1B[22m\x1B[1m"),dim:e("\x1B[2m","\x1B[22m","\x1B[22m\x1B[2m"),italic:e("\x1B[3m","\x1B[23m"),underline:e("\x1B[4m","\x1B[24m"),inverse:e("\x1B[7m","\x1B[27m"),hidden:e("\x1B[8m","\x1B[28m"),strikethrough:e("\x1B[9m","\x1B[29m"),black:e("\x1B[30m","\x1B[39m"),red:e("\x1B[31m","\x1B[39m"),green:e("\x1B[32m","\x1B[39m"),yellow:e("\x1B[33m","\x1B[39m"),blue:e("\x1B[34m","\x1B[39m"),magenta:e("\x1B[35m","\x1B[39m"),cyan:e("\x1B[36m","\x1B[39m"),white:e("\x1B[37m","\x1B[39m"),gray:e("\x1B[90m","\x1B[39m"),bgBlack:e("\x1B[40m","\x1B[49m"),bgRed:e("\x1B[41m","\x1B[49m"),bgGreen:e("\x1B[42m","\x1B[49m"),bgYellow:e("\x1B[43m","\x1B[49m"),bgBlue:e("\x1B[44m","\x1B[49m"),bgMagenta:e("\x1B[45m","\x1B[49m"),bgCyan:e("\x1B[46m","\x1B[49m"),bgWhite:e("\x1B[47m","\x1B[49m"),blackBright:e("\x1B[90m","\x1B[39m"),redBright:e("\x1B[91m","\x1B[39m"),greenBright:e("\x1B[92m","\x1B[39m"),yellowBright:e("\x1B[93m","\x1B[39m"),blueBright:e("\x1B[94m","\x1B[39m"),magentaBright:e("\x1B[95m","\x1B[39m"),cyanBright:e("\x1B[96m","\x1B[39m"),whiteBright:e("\x1B[97m","\x1B[39m"),bgBlackBright:e("\x1B[100m","\x1B[49m"),bgRedBright:e("\x1B[101m","\x1B[49m"),bgGreenBright:e("\x1B[102m","\x1B[49m"),bgYellowBright:e("\x1B[103m","\x1B[49m"),bgBlueBright:e("\x1B[104m","\x1B[49m"),bgMagentaBright:e("\x1B[105m","\x1B[49m"),bgCyanBright:e("\x1B[106m","\x1B[49m"),bgWhiteBright:e("\x1B[107m","\x1B[49m")}};ts.exports=xi();ts.exports.createColors=xi});import{existsSync as ed,readFileSync as td}from"fs";function z(t,e){if(!ed(t))return e;try{return JSON.parse(td(t,"utf-8"))}catch(r){throw new Error(`Corrupt JSON file, refusing to overwrite: ${t}: ${r instanceof Error?r.message:String(r)}`)}}var $t=b(()=>{"use strict"});import{closeSync as rs,existsSync as er,fsyncSync as Li,lstatSync as rd,mkdirSync as nd,openSync as ns,readFileSync as Di,readlinkSync as sd,realpathSync as od,renameSync as id,statSync as ad,unlinkSync as ld,writeSync as cd}from"fs";import{homedir as ud}from"os";import{basename as dd,dirname as Jr,join as Se,resolve as pd}from"path";import{fileURLToPath as md}from"url";import{randomBytes as fd}from"crypto";function ss(){return process.env.CLAUDE_CONFIG_DIR||Se(ud(),".claude")}function oe(){return Se(ss(),"plugins","marketplaces","keepmind")}function Re(){return Se(ss(),"plugins")}function De(){return Se(Re(),"known_marketplaces.json")}function Pe(){return Se(Re(),"installed_plugins.json")}function we(){return Se(ss(),"settings.json")}function nt(t){return Se(Re(),"cache","keepmind","keepmind",t)}function Kr(){let t=md(import.meta.url),e=Se(Jr(t),"..","..");if(!er(Se(e,"package.json")))throw new Error(`npmPackageRootDirectory: expected package.json at ${e}. Bundle structure may have changed \u2014 update the path walk.`);return e}function os(){return Se(Kr(),"plugin")}function Mt(){let t=Se(os(),".claude-plugin","plugin.json");if(er(t))try{let r=JSON.parse(Di(t,"utf-8"));if(r.version)return r.version}catch{}let e=Se(Kr(),"package.json");if(er(e))try{let r=JSON.parse(Di(e,"utf-8"));if(r.version)return r.version}catch{}return"0.0.0"}function xt(){let t=oe();return er(Se(t,"plugin",".claude-plugin","plugin.json"))}function tr(t){er(t)||nd(t,{recursive:!0})}function re(t,e){let r=t;try{if(rd(t).isSymbolicLink())try{r=od(t)}catch{let c=sd(t);r=pd(Jr(t),c)}}catch(c){let d=c.code;if(d!=="ENOENT"&&d!=="ENOTDIR")throw c}tr(Jr(r));let n=Jr(r),s=dd(r),o=Se(n,`.${s}.${process.pid}.${fd(6).toString("hex")}.tmp`),i=Buffer.from(JSON.stringify(e,null,2)+`
|
|
3
|
+
`,"utf-8"),a;try{a=ad(r).mode&511}catch{}let l;try{l=a!==void 0?ns(o,"w",a):ns(o,"w");let c=0;for(;c<i.length;){let d=cd(l,i,c,i.length-c);if(d===0)throw new Error(`writeSync stalled at ${c}/${i.length} bytes`);c+=d}if(Li(l),rs(l),l=void 0,id(o,r),!W){let d;try{d=ns(n,"r"),Li(d)}catch{}finally{if(d!==void 0)try{rs(d)}catch{}}}}catch(c){if(l!==void 0)try{rs(l)}catch{}try{ld(o)}catch{}throw c}}var W,Ae=b(()=>{"use strict";$t();W=process.platform==="win32"});var Pi,Ui,Fi,ji=b(()=>{Pi=(()=>{let t=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;return e=>{let r=0;for(t.lastIndex=0;t.test(e);)r+=1;return e.length-r}})(),Ui=t=>t===12288||t>=65281&&t<=65376||t>=65504&&t<=65510,Fi=t=>t===8987||t===9001||t>=12272&&t<=12287||t>=12289&&t<=12350||t>=12441&&t<=12543||t>=12549&&t<=12591||t>=12593&&t<=12686||t>=12688&&t<=12771||t>=12783&&t<=12830||t>=12832&&t<=12871||t>=12880&&t<=19903||t>=65040&&t<=65049||t>=65072&&t<=65106||t>=65108&&t<=65126||t>=65128&&t<=65131||t>=127488&&t<=127490||t>=127504&&t<=127547||t>=127552&&t<=127560||t>=131072&&t<=196605||t>=196608&&t<=262141});var gd,hd,Wi,Ed,Gi,Sd,bd,yd,Bi,Hi,Ji=b(()=>{ji();gd=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y,hd=/[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y,Wi=/(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu,Ed=/\t{1,1000}/y,Gi=new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*","yu"),Sd=/(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y,bd=new RegExp("\\p{M}+","gu"),yd={limit:1/0,ellipsis:""},Bi=(t,e={},r={})=>{let n=e.limit??1/0,s=e.ellipsis??"",o=e?.ellipsisWidth??(s?Bi(s,yd,r).width:0),i=0,a=r.controlWidth??0,l=r.tabWidth??8,c=r.emojiWidth??2,d=2,m=r.regularWidth??1,f=r.wideWidth??d,g=[[Sd,m],[gd,i],[hd,a],[Ed,l],[Gi,c],[Wi,f]],h=0,S=0,y=t.length,C=0,N=!1,D=y,R=Math.max(0,n-o),T=0,v=0,I=0,Y=0;e:for(;;){if(v>T||S>=y&&S>h){let Z=t.slice(T,v)||t.slice(h,S);C=0;for(let ve of Z.replaceAll(bd,"")){let Q=ve.codePointAt(0)||0;if(Ui(Q)?Y=d:Fi(Q)?Y=f:Y=m,I+Y>R&&(D=Math.min(D,Math.max(T,h)+C)),I+Y>n){N=!0;break e}C+=ve.length,I+=Y}T=v=0}if(S>=y)break e;for(let Z=0,ve=g.length;Z<ve;Z++){let[Q,At]=g[Z];if(Q.lastIndex=S,Q.test(t)){if(C=Q===Wi?Pi(t.slice(S,Q.lastIndex)):Q===Gi?1:Q.lastIndex-S,Y=C*At,I+Y>R&&(D=Math.min(D,S+Math.floor((R-I)/At))),I+Y>n){N=!0;break e}I+=Y,T=h,v=S,S=h=Q.lastIndex;continue e}}S+=1}return{width:N?R:I,index:N?D:y,truncated:N,ellipsed:N&&n>=o}},Hi=Bi});var Td,vd,pe,is=b(()=>{Ji();Td={limit:1/0,ellipsis:"",ellipsisWidth:0},vd=(t,e={})=>Hi(t,Td,e).width,pe=vd});function Ue(t,e,r){return String(t).normalize().split(Od).map(n=>Id(n,e,r)).join(`
|
|
4
|
+
`)}var Xr,qi,Cd,ls,zi,Rd,Zi,cs,Ki,Xi,Vi,Yi,as,wd,Id,Od,us=b(()=>{is();Xr="\x1B",qi="\x9B",Cd=39,ls="\x07",zi="[",Rd="]",Zi="m",cs=`${Rd}8;;`,Ki=new RegExp(`(?:\\${zi}(?<code>\\d+)m|\\${cs}(?<uri>.*)${ls})`,"y"),Xi=t=>{if(t>=30&&t<=37||t>=90&&t<=97)return 39;if(t>=40&&t<=47||t>=100&&t<=107)return 49;if(t===1||t===2)return 22;if(t===3)return 23;if(t===4)return 24;if(t===7)return 27;if(t===8)return 28;if(t===9)return 29;if(t===0)return 0},Vi=t=>`${Xr}${zi}${t}${Zi}`,Yi=t=>`${Xr}${cs}${t}${ls}`,as=(t,e,r)=>{let n=e[Symbol.iterator](),s=!1,o=!1,i=t.at(-1),a=i===void 0?0:pe(i),l=n.next(),c=n.next(),d=0;for(;!l.done;){let m=l.value,f=pe(m);a+f<=r?t[t.length-1]+=m:(t.push(m),a=0),(m===Xr||m===qi)&&(s=!0,o=e.startsWith(cs,d+1)),s?o?m===ls&&(s=!1,o=!1):m===Zi&&(s=!1):(a+=f,a===r&&!c.done&&(t.push(""),a=0)),l=c,c=n.next(),d+=m.length}i=t.at(-1),!a&&i!==void 0&&i.length&&t.length>1&&(t[t.length-2]+=t.pop())},wd=t=>{let e=t.split(" "),r=e.length;for(;r&&!pe(e[r-1]);)r--;return r===e.length?t:e.slice(0,r).join(" ")+e.slice(r).join("")},Id=(t,e,r={})=>{if(r.trim!==!1&&t.trim()==="")return"";let n="",s,o,i=t.split(" "),a=[""],l=0;for(let m=0;m<i.length;m++){let f=i[m];if(r.trim!==!1){let h=a.at(-1)??"",S=h.trimStart();h.length!==S.length&&(a[a.length-1]=S,l=pe(S))}m!==0&&(l>=e&&(r.wordWrap===!1||r.trim===!1)&&(a.push(""),l=0),(l||r.trim===!1)&&(a[a.length-1]+=" ",l++));let g=pe(f);if(r.hard&&g>e){let h=e-l,S=1+Math.floor((g-h-1)/e);Math.floor((g-1)/e)<S&&a.push(""),as(a,f,e),l=pe(a.at(-1)??"");continue}if(l+g>e&&l&&g){if(r.wordWrap===!1&&l<e){as(a,f,e),l=pe(a.at(-1)??"");continue}a.push(""),l=0}if(l+g>e&&r.wordWrap===!1){as(a,f,e),l=pe(a.at(-1)??"");continue}a[a.length-1]+=f,l+=g}r.trim!==!1&&(a=a.map(m=>wd(m)));let c=a.join(`
|
|
5
|
+
`),d=!1;for(let m=0;m<c.length;m++){let f=c[m];if(n+=f,d)d=!1;else if(d=f>="\uD800"&&f<="\uDBFF",d)continue;if(f===Xr||f===qi){Ki.lastIndex=m+1;let h=Ki.exec(c)?.groups;if(h?.code!==void 0){let S=Number.parseFloat(h.code);s=S===Cd?void 0:S}else h?.uri!==void 0&&(o=h.uri.length===0?void 0:h.uri)}if(c[m+1]===`
|
|
6
|
+
`){o&&(n+=Yi(""));let g=s?Xi(s):void 0;s&&g&&(n+=Vi(g))}else f===`
|
|
7
|
+
`&&(s&&Xi(s)&&(n+=Vi(s)),o&&(n+=Yi(o)))}return n},Od=/\r?\n/});var ps=Ai((mS,Qi)=>{"use strict";var ds={to(t,e){return e?`\x1B[${e+1};${t+1}H`:`\x1B[${t+1}G`},move(t,e){let r="";return t<0?r+=`\x1B[${-t}D`:t>0&&(r+=`\x1B[${t}C`),e<0?r+=`\x1B[${-e}A`:e>0&&(r+=`\x1B[${e}B`),r},up:(t=1)=>`\x1B[${t}A`,down:(t=1)=>`\x1B[${t}B`,forward:(t=1)=>`\x1B[${t}C`,backward:(t=1)=>`\x1B[${t}D`,nextLine:(t=1)=>"\x1B[E".repeat(t),prevLine:(t=1)=>"\x1B[F".repeat(t),left:"\x1B[G",hide:"\x1B[?25l",show:"\x1B[?25h",save:"\x1B7",restore:"\x1B8"},kd={up:(t=1)=>"\x1B[S".repeat(t),down:(t=1)=>"\x1B[T".repeat(t)},_d={screen:"\x1B[2J",up:(t=1)=>"\x1B[1J".repeat(t),down:(t=1)=>"\x1B[J".repeat(t),line:"\x1B[2K",lineEnd:"\x1B[K",lineStart:"\x1B[1K",lines(t){let e="";for(let r=0;r<t;r++)e+=this.line+(r<t-1?ds.up():"");return t&&(e+=ds.left),e}};Qi.exports={cursor:ds,scroll:kd,erase:_d,beep:"\x07"}});import{styleText as ms}from"node:util";import{stdout as gs,stdin as ea}from"node:process";import*as st from"node:readline";import Nd from"node:readline";import{ReadStream as $i}from"node:tty";function Tt(t,e,r){if(!r.some(i=>!i.disabled))return t;let n=t+e,s=Math.max(r.length-1,0),o=n<0?s:n>s?0:n;return r[o].disabled?Tt(o,e<0?-1:1,r):o}function hs(t,e){if(typeof t=="string")return ee.aliases.get(t)===e;for(let r of t)if(r!==void 0&&hs(r,e))return!0;return!1}function xd(t,e){if(t===e)return;let r=t.split(`
|
|
8
|
+
`),n=e.split(`
|
|
9
|
+
`),s=Math.max(r.length,n.length),o=[];for(let i=0;i<s;i++)r[i]!==n[i]&&o.push(i);return{lines:o,numLinesBefore:r.length,numLinesAfter:n.length,numLines:s}}function J(t){return t===fs}function Vr(t,e){let r=t;r.isTTY&&r.setRawMode(e)}function ta({input:t=ea,output:e=gs,overwrite:r=!0,hideCursor:n=!0}={}){let s=st.createInterface({input:t,output:e,prompt:"",tabSize:1});st.emitKeypressEvents(t,s),t instanceof $i&&t.isTTY&&t.setRawMode(!0);let o=(i,{name:a,sequence:l})=>{let c=String(i);if(hs([c,a,l],"cancel")){n&&e.write(ae.cursor.show),process.exit(0);return}if(!r)return;st.moveCursor(e,a==="return"?0:-1,a==="return"?-1:0,()=>{st.clearLine(e,1,()=>{t.once("keypress",o)})})};return n&&e.write(ae.cursor.hide),t.once("keypress",o),()=>{t.off("keypress",o),n&&e.write(ae.cursor.show),t instanceof $i&&t.isTTY&&!Ld&&t.setRawMode(!1),s.terminal=!1,s.close()}}function ot(t,e,r,n=r,s=r,o){let i=rr(t??gs);return Ue(e,i-r.length,{hard:!0,trim:!1}).split(`
|
|
10
|
+
`).map((a,l,c)=>{let d=o?o(a,l):a;return l===0?`${n}${d}`:l===c.length-1?`${s}${d}`:`${r}${d}`}).join(`
|
|
11
|
+
`)}function ra(t,e){if("~standard"in t){let r=t["~standard"].validate(e);if(r instanceof Promise)throw new TypeError("Schema validation must be synchronous. Update `validate()` and remove any asynchronous logic.");return r.issues?.at(0)?.message}return t(e)}var ae,Ad,Md,ee,Ld,fs,rr,Es,vt,Yr,na,qr,zr,Zr,Ss=b(()=>{us();ae=He(ps(),1);Ad=["up","down","left","right","space","enter","cancel"],Md=["January","February","March","April","May","June","July","August","September","October","November","December"],ee={actions:new Set(Ad),aliases:new Map([["k","up"],["j","down"],["h","left"],["l","right"],["","cancel"],["escape","cancel"]]),messages:{cancel:"Canceled",error:"Something went wrong"},withGuide:!0,date:{monthNames:[...Md],messages:{required:"Please enter a valid date",invalidMonth:"There are only 12 months in a year",invalidDay:(t,e)=>`There are only ${t} days in ${e}`,afterMin:t=>`Date must be on or after ${t.toISOString().slice(0,10)}`,beforeMax:t=>`Date must be on or before ${t.toISOString().slice(0,10)}`}}};Ld=globalThis.process.platform.startsWith("win"),fs=Symbol("clack:cancel");rr=t=>"columns"in t&&typeof t.columns=="number"?t.columns:80,Es=t=>"rows"in t&&typeof t.rows=="number"?t.rows:20;vt=class{input;output;_abortSignal;rl;opts;_render;_track=!1;_prevFrame="";_subscribers=new Map;_cursor=0;state="initial";error="";value;userInput="";constructor(e,r=!0){let{input:n=ea,output:s=gs,render:o,signal:i,...a}=e;this.opts=a,this.onKeypress=this.onKeypress.bind(this),this.close=this.close.bind(this),this.render=this.render.bind(this),this._render=o.bind(this),this._track=r,this._abortSignal=i,this.input=n,this.output=s}unsubscribe(){this._subscribers.clear()}setSubscriber(e,r){let n=this._subscribers.get(e)??[];n.push(r),this._subscribers.set(e,n)}on(e,r){this.setSubscriber(e,{cb:r})}once(e,r){this.setSubscriber(e,{cb:r,once:!0})}emit(e,...r){let n=this._subscribers.get(e)??[],s=[];for(let o of n)o.cb(...r),o.once&&s.push(()=>n.splice(n.indexOf(o),1));for(let o of s)o()}prompt(){return new Promise(e=>{if(this._abortSignal){if(this._abortSignal.aborted)return this.state="cancel",this.close(),e(fs);this._abortSignal.addEventListener("abort",()=>{this.state="cancel",this.close()},{once:!0})}this.rl=Nd.createInterface({input:this.input,tabSize:2,prompt:"",escapeCodeTimeout:50,terminal:!0}),this.rl.prompt(),this.opts.initialUserInput!==void 0&&this._setUserInput(this.opts.initialUserInput,!0),this.input.on("keypress",this.onKeypress),Vr(this.input,!0),this.output.on("resize",this.render),this.render(),this.once("submit",()=>{this.output.write(ae.cursor.show),this.output.off("resize",this.render),Vr(this.input,!1),e(this.value)}),this.once("cancel",()=>{this.output.write(ae.cursor.show),this.output.off("resize",this.render),Vr(this.input,!1),e(fs)})})}_isActionKey(e,r){return e===" "}_shouldSubmit(e,r){return!0}_setValue(e){this.value=e,this.emit("value",this.value)}_setUserInput(e,r){this.userInput=e??"",this.emit("userInput",this.userInput),r&&this._track&&this.rl&&(this.rl.write(this.userInput),this._cursor=this.rl.cursor)}_clearUserInput(){this.rl?.write(null,{ctrl:!0,name:"u"}),this._setUserInput("")}onKeypress(e,r){if(this._track&&r.name!=="return"&&(r.name&&this._isActionKey(e,r)&&this.rl?.write(null,{ctrl:!0,name:"h"}),this._cursor=this.rl?.cursor??0,this._setUserInput(this.rl?.line)),this.state==="error"&&(this.state="active"),r?.name&&(!this._track&&ee.aliases.has(r.name)&&this.emit("cursor",ee.aliases.get(r.name)),ee.actions.has(r.name)&&this.emit("cursor",r.name)),e&&(e.toLowerCase()==="y"||e.toLowerCase()==="n")&&this.emit("confirm",e.toLowerCase()==="y"),this.emit("key",e,r),r?.name==="return"&&this._shouldSubmit(e,r)){if(this.opts.validate){let n=ra(this.opts.validate,this.value);n&&(this.error=n instanceof Error?n.message:n,this.state="error",this.rl?.write(this.userInput))}this.state!=="error"&&(this.state="submit")}hs([e,r?.name,r?.sequence],"cancel")&&(this.state="cancel"),(this.state==="submit"||this.state==="cancel")&&this.emit("finalize"),this.render(),(this.state==="submit"||this.state==="cancel")&&this.close()}close(){this.input.unpipe(),this.input.removeListener("keypress",this.onKeypress),this.output.write(`
|
|
12
|
+
`),Vr(this.input,!1),this.rl?.close(),this.rl=void 0,this.emit(`${this.state}`,this.value),this.unsubscribe()}restoreCursor(){let e=Ue(this._prevFrame,process.stdout.columns,{hard:!0,trim:!1}).split(`
|
|
13
|
+
`).length-1;this.output.write(ae.cursor.move(-999,e*-1))}render(){let e=Ue(this._render(this)??"",process.stdout.columns,{hard:!0,trim:!1});if(e!==this._prevFrame){if(this.state==="initial")this.output.write(ae.cursor.hide);else{let r=xd(this._prevFrame,e),n=Es(this.output);if(this.restoreCursor(),r){let s=Math.max(0,r.numLinesAfter-n),o=Math.max(0,r.numLinesBefore-n),i=r.lines.find(a=>a>=s);if(i===void 0){this._prevFrame=e;return}if(r.lines.length===1){this.output.write(ae.cursor.move(0,i-o)),this.output.write(ae.erase.lines(1));let a=e.split(`
|
|
14
|
+
`);this.output.write(a[i]),this._prevFrame=e,this.output.write(ae.cursor.move(0,a.length-i-1));return}else if(r.lines.length>1){if(s<o)i=s;else{let l=i-o;l>0&&this.output.write(ae.cursor.move(0,l))}this.output.write(ae.erase.down());let a=e.split(`
|
|
15
|
+
`).slice(i);this.output.write(a.join(`
|
|
16
|
+
`)),this._prevFrame=e;return}}this.output.write(ae.erase.down())}this.output.write(e),this.state==="initial"&&(this.state="active"),this._prevFrame=e}}},Yr=class extends vt{get cursor(){return this.value?0:1}get _value(){return this.cursor===0}constructor(e){super(e,!1),this.value=!!e.initialValue,this.on("userInput",()=>{this.value=this._value}),this.on("confirm",r=>{this.output.write(ae.cursor.move(0,-1)),this.value=r,this.state="submit",this.close()}),this.on("cursor",()=>{this.value=!this.value})}},na=class extends vt{options;cursor=0;get _value(){return this.options[this.cursor].value}get _enabledOptions(){return this.options.filter(e=>e.disabled!==!0)}toggleAll(){let e=this._enabledOptions,r=this.value!==void 0&&this.value.length===e.length;this.value=r?[]:e.map(n=>n.value)}toggleInvert(){let e=this.value;if(!e)return;let r=this._enabledOptions.filter(n=>!e.includes(n.value));this.value=r.map(n=>n.value)}toggleValue(){this.value===void 0&&(this.value=[]);let e=this.value.includes(this._value);this.value=e?this.value.filter(r=>r!==this._value):[...this.value,this._value]}constructor(e){super(e,!1),this.options=e.options,this.value=[...e.initialValues??[]];let r=Math.max(this.options.findIndex(({value:n})=>n===e.cursorAt),0);this.cursor=this.options[r].disabled?Tt(r,1,this.options):r,this.on("key",(n,s)=>{s.name==="a"&&this.toggleAll(),s.name==="i"&&this.toggleInvert()}),this.on("cursor",n=>{switch(n){case"left":case"up":this.cursor=Tt(this.cursor,-1,this.options);break;case"down":case"right":this.cursor=Tt(this.cursor,1,this.options);break;case"space":this.toggleValue();break}})}},qr=class extends vt{_mask="\u2022";get cursor(){return this._cursor}get masked(){return this.userInput.replaceAll(/./g,this._mask)}get userInputWithCursor(){if(this.state==="submit"||this.state==="cancel")return this.masked;let e=this.userInput;if(this.cursor>=e.length)return`${this.masked}${ms(["inverse","hidden"],"_")}`;let r=this.masked,n=r.slice(0,this.cursor),s=r.slice(this.cursor);return`${n}${ms("inverse",s[0])}${s.slice(1)}`}clear(){this._clearUserInput()}constructor({mask:e,...r}){super(r),this._mask=e??"\u2022",this.on("userInput",n=>{this._setValue(n)}),this.on("finalize",()=>{this.value===void 0&&(this.value="")})}},zr=class extends vt{options;cursor=0;get _selectedValue(){return this.options[this.cursor]}changeValue(){this.value=this._selectedValue.value}constructor(e){super(e,!1),this.options=e.options;let r=this.options.findIndex(({value:s})=>s===e.initialValue),n=r===-1?0:r;this.cursor=this.options[n].disabled?Tt(n,1,this.options):n,this.changeValue(),this.on("cursor",s=>{switch(s){case"left":case"up":this.cursor=Tt(this.cursor,-1,this.options);break;case"down":case"right":this.cursor=Tt(this.cursor,1,this.options);break}this.changeValue()})}},Zr=class extends vt{get userInputWithCursor(){if(this.state==="submit")return this.userInput;let e=this.userInput;if(this.cursor>=e.length)return`${this.userInput}\u2588`;let r=e.slice(0,this.cursor),[n,...s]=e.slice(this.cursor);return`${r}${ms("inverse",n)}${s.join("")}`}get cursor(){return this._cursor}constructor(e){super({...e,initialUserInput:e.initialUserInput??e.initialValue}),this.on("userInput",r=>{this._setValue(r)}),this.on("finalize",()=>{this.value||(this.value=e.defaultValue),this.value===void 0&&(this.value="")})}}});import{styleText as p,stripVTControlCharacters as _S}from"node:util";import Ie from"node:process";function Dd(){return Ie.platform!=="win32"?Ie.env.TERM!=="linux":!!Ie.env.CI||!!Ie.env.WT_SESSION||!!Ie.env.TERMINUS_SUBLIME||Ie.env.ConEmuTask==="{cmd::Cmder}"||Ie.env.TERM_PROGRAM==="Terminus-Sublime"||Ie.env.TERM_PROGRAM==="vscode"||Ie.env.TERM==="xterm-256color"||Ie.env.TERM==="alacritty"||Ie.env.TERMINAL_EMULATOR==="JetBrains-JediTerm"}function da(t,e){let r=[`${e?`${p("cyan",O)} `:""}${t.join(" \u2022 ")}`];return e&&r.push(p("cyan",Je)),r}var sr,bs,Pd,F,Ud,la,ca,en,Fd,O,Je,xS,LS,ys,$r,jd,sa,oa,Wd,ia,Gd,Bd,Hd,Jd,DS,Kd,Xd,Vd,Yd,or,ua,aa,Ts,Ct,qd,nr,pa,K,Oe,ir,Ke,zd,Zd,Rt,tn,Qd,it,PS,$d,Qr,at,US,rn,ar,vs=b(()=>{Ss();Ss();us();is();sr=He(ps(),1);bs=Dd(),Pd=()=>process.env.CI==="true",F=(t,e)=>bs?t:e,Ud=F("\u25C6","*"),la=F("\u25A0","x"),ca=F("\u25B2","x"),en=F("\u25C7","o"),Fd=F("\u250C","T"),O=F("\u2502","|"),Je=F("\u2514","\u2014"),xS=F("\u2510","T"),LS=F("\u2518","\u2014"),ys=F("\u25CF",">"),$r=F("\u25CB"," "),jd=F("\u25FB","[\u2022]"),sa=F("\u25FC","[+]"),oa=F("\u25FB","[ ]"),Wd=F("\u25AA","\u2022"),ia=F("\u2500","-"),Gd=F("\u256E","+"),Bd=F("\u251C","+"),Hd=F("\u256F","+"),Jd=F("\u2570","+"),DS=F("\u256D","+"),Kd=F("\u25CF","\u2022"),Xd=F("\u25C6","*"),Vd=F("\u25B2","!"),Yd=F("\u25A0","x"),or=t=>{switch(t){case"initial":case"active":return p("cyan",Ud);case"cancel":return p("red",la);case"error":return p("yellow",ca);case"submit":return p("green",en)}},ua=t=>{switch(t){case"initial":case"active":return p("cyan",O);case"cancel":return p("red",O);case"error":return p("yellow",O);case"submit":return p("green",O)}};aa=(t,e,r,n,s,o=!1)=>{let i=e,a=0;if(o)for(let l=n-1;l>=r&&(i-=t[l].length,a++,!(i<=s));l--);else for(let l=r;l<n&&(i-=t[l].length,a++,!(i<=s));l++);return{lineCount:i,removals:a}},Ts=({cursor:t,options:e,style:r,output:n=process.stdout,maxItems:s=Number.POSITIVE_INFINITY,columnPadding:o=0,rowPadding:i=4})=>{let a=rr(n)-o,l=Es(n),c=p("dim","..."),d=Math.max(l-i,0),m=Math.max(Math.min(s,d),5),f=0;t>=m-3&&(f=Math.max(Math.min(t-m+3,e.length-m),0));let g=m<e.length&&f>0,h=m<e.length&&f+m<e.length,S=Math.min(f+m,e.length),y=[],C=0;g&&C++,h&&C++;let N=f+(g?1:0),D=S-(h?1:0);for(let T=N;T<D;T++){let v=Ue(r(e[T],T===t),a,{hard:!0,trim:!1}).split(`
|
|
17
|
+
`);y.push(v),C+=v.length}if(C>d){let T=0,v=0,I=C,Y=t-N,Z=d,ve=()=>aa(y,I,0,Y,Z),Q=()=>aa(y,I,Y+1,y.length,Z,!0);g?({lineCount:I,removals:T}=ve(),I>Z&&(h||(Z-=1),{lineCount:I,removals:v}=Q())):(h||(Z-=1),{lineCount:I,removals:v}=Q(),I>Z&&(Z-=1,{lineCount:I,removals:T}=ve())),T>0&&(g=!0,y.splice(0,T)),v>0&&(h=!0,y.splice(y.length-v,v))}let R=[];g&&R.push(c);for(let T of y)for(let v of T)R.push(v);return h&&R.push(c),R},Ct=t=>{let e=t.active??"Yes",r=t.inactive??"No";return new Yr({active:e,inactive:r,signal:t.signal,input:t.input,output:t.output,initialValue:t.initialValue??!0,render(){let n=t.withGuide??ee.withGuide,s=`${or(this.state)} `,o=n?`${p("gray",O)} `:"",i=ot(t.output,t.message,o,s),a=`${n?`${p("gray",O)}
|
|
18
|
+
`:""}${i}
|
|
19
|
+
`,l=this.value?e:r;switch(this.state){case"submit":{let c=n?`${p("gray",O)} `:"";return`${a}${c}${p("dim",l)}`}case"cancel":{let c=n?`${p("gray",O)} `:"";return`${a}${c}${p(["strikethrough","dim"],l)}${n?`
|
|
20
|
+
${p("gray",O)}`:""}`}default:{let c=n?`${p("cyan",O)} `:"",d=n?p("cyan",Je):"";return`${a}${c}${this.value?`${p("green",ys)} ${e}`:`${p("dim",$r)} ${p("dim",e)}`}${t.vertical?n?`
|
|
21
|
+
${p("cyan",O)} `:`
|
|
22
|
+
`:` ${p("dim","/")} `}${this.value?`${p("dim",$r)} ${p("dim",r)}`:`${p("green",ys)} ${r}`}
|
|
23
|
+
${d}
|
|
24
|
+
`}}}}).prompt()},qd=[`${p("dim","\u2191/\u2193")} to navigate`,`${p("dim","Space:")} select`,`${p("dim","Enter:")} confirm`],nr=(t,e)=>t.split(`
|
|
25
|
+
`).map(r=>e(r)).join(`
|
|
26
|
+
`),pa=t=>{let e=(n,s)=>{let o=n.label??String(n.value);return s==="disabled"?`${p("gray",oa)} ${nr(o,i=>p(["strikethrough","gray"],i))}${n.hint?` ${p("dim",`(${n.hint??"disabled"})`)}`:""}`:s==="active"?`${p("cyan",jd)} ${o}${n.hint?` ${p("dim",`(${n.hint})`)}`:""}`:s==="selected"?`${p("green",sa)} ${nr(o,i=>p("dim",i))}${n.hint?` ${p("dim",`(${n.hint})`)}`:""}`:s==="cancelled"?`${nr(o,i=>p(["strikethrough","dim"],i))}`:s==="active-selected"?`${p("green",sa)} ${o}${n.hint?` ${p("dim",`(${n.hint})`)}`:""}`:s==="submitted"?`${nr(o,i=>p("dim",i))}`:`${p("dim",oa)} ${nr(o,i=>p("dim",i))}`},r=t.required??!0;return new na({options:t.options,signal:t.signal,input:t.input,output:t.output,initialValues:t.initialValues,required:r,cursorAt:t.cursorAt,validate(n){if(r&&(n===void 0||n.length===0))return`Please select at least one option.
|
|
27
|
+
${p("reset",p("dim",`Press ${p(["gray","bgWhite","inverse"]," space ")} to select, ${p("gray",p("bgWhite",p("inverse"," enter ")))} to submit`))}`},render(){let n=t.withGuide??ee.withGuide,s=ot(t.output,t.message,n?`${ua(this.state)} `:"",`${or(this.state)} `),o=`${n?`${p("gray",O)}
|
|
28
|
+
`:""}${s}
|
|
29
|
+
`,i=this.value??[],a=(l,c)=>{if(l.disabled)return e(l,"disabled");let d=i.includes(l.value);return c&&d?e(l,"active-selected"):d?e(l,"selected"):e(l,c?"active":"inactive")};switch(this.state){case"submit":{let l=this.options.filter(({value:d})=>i.includes(d)).map(d=>e(d,"submitted")).join(p("dim",", "))||p("dim","none"),c=ot(t.output,l,n?`${p("gray",O)} `:"");return`${o}${c}`}case"cancel":{let l=this.options.filter(({value:d})=>i.includes(d)).map(d=>e(d,"cancelled")).join(p("dim",", "));if(l.trim()==="")return`${o}${p("gray",O)}`;let c=ot(t.output,l,n?`${p("gray",O)} `:"");return`${o}${c}${n?`
|
|
30
|
+
${p("gray",O)}`:""}`}case"error":{let l=n?`${p("yellow",O)} `:"",c=this.error.split(`
|
|
31
|
+
`).map((f,g)=>g===0?`${n?`${p("yellow",Je)} `:""}${p("yellow",f)}`:` ${f}`).join(`
|
|
32
|
+
`),d=o.split(`
|
|
33
|
+
`).length,m=c.split(`
|
|
34
|
+
`).length+1;return`${o}${l}${Ts({output:t.output,options:this.options,cursor:this.cursor,maxItems:t.maxItems,columnPadding:l.length,rowPadding:d+m,style:a}).join(`
|
|
35
|
+
${l}`)}
|
|
36
|
+
${c}
|
|
37
|
+
`}default:{let l=n?`${p("cyan",O)} `:"",c=o.split(`
|
|
38
|
+
`).length,d=da(qd,n),m=d.join(`
|
|
39
|
+
`),f=d.length+1;return`${o}${l}${Ts({output:t.output,options:this.options,cursor:this.cursor,maxItems:t.maxItems,columnPadding:l.length,rowPadding:c+f,style:a}).join(`
|
|
40
|
+
${l}`)}
|
|
41
|
+
${m}
|
|
42
|
+
`}}}}).prompt()},K={message:(t=[],{symbol:e=p("gray",O),secondarySymbol:r=p("gray",O),output:n=process.stdout,spacing:s=1,withGuide:o}={})=>{let i=[],a=o??ee.withGuide,l=a?r:"",c=a?`${e} `:"",d=a?`${r} `:"";for(let f=0;f<s;f++)i.push(l);let m=Array.isArray(t)?t:t.split(`
|
|
43
|
+
`);if(m.length>0){let[f,...g]=m;f.length>0?i.push(`${c}${f}`):i.push(a?e:"");for(let h of g)h.length>0?i.push(`${d}${h}`):i.push(a?r:"")}n.write(`${i.join(`
|
|
44
|
+
`)}
|
|
45
|
+
`)},info:(t,e)=>{K.message(t,{...e,symbol:p("blue",Kd)})},success:(t,e)=>{K.message(t,{...e,symbol:p("green",Xd)})},step:(t,e)=>{K.message(t,{...e,symbol:p("green",en)})},warn:(t,e)=>{K.message(t,{...e,symbol:p("yellow",Vd)})},warning:(t,e)=>{K.warn(t,e)},error:(t,e)=>{K.message(t,{...e,symbol:p("red",Yd)})}},Oe=(t="",e)=>{let r=e?.output??process.stdout,n=e?.withGuide??ee.withGuide?`${p("gray",Je)} `:"";r.write(`${n}${p("red",t)}
|
|
46
|
+
|
|
47
|
+
`)},ir=(t="",e)=>{let r=e?.output??process.stdout,n=e?.withGuide??ee.withGuide?`${p("gray",Fd)} `:"";r.write(`${n}${t}
|
|
48
|
+
`)},Ke=(t="",e)=>{let r=e?.output??process.stdout,n=e?.withGuide??ee.withGuide?`${p("gray",O)}
|
|
49
|
+
${p("gray",Je)} `:"";r.write(`${n}${t}
|
|
50
|
+
|
|
51
|
+
`)},zd=t=>t,Zd=(t,e,r)=>{let n={hard:!0,trim:!1},s=Ue(t,e,n).split(`
|
|
52
|
+
`),o=s.reduce((l,c)=>Math.max(pe(c),l),0),i=s.map(r).reduce((l,c)=>Math.max(pe(c),l),0),a=e-(i-o);return Ue(t,a,n)},Rt=(t="",e="",r)=>{let n=r?.output??Ie.stdout,s=r?.withGuide??ee.withGuide,o=r?.format??zd,i=["",...Zd(t,rr(n)-6,o).split(`
|
|
53
|
+
`).map(o),""],a=pe(e),l=Math.max(i.reduce((f,g)=>{let h=pe(g);return h>f?h:f},0),a)+2,c=i.map(f=>`${p("gray",O)} ${f}${" ".repeat(l-pe(f))}${p("gray",O)}`).join(`
|
|
54
|
+
`),d=s?`${p("gray",O)}
|
|
55
|
+
`:"",m=s?Bd:Jd;n.write(`${d}${p("green",en)} ${p("reset",e)} ${p("gray",ia.repeat(Math.max(l-a-1,1))+Gd)}
|
|
56
|
+
${c}
|
|
57
|
+
${p("gray",m+ia.repeat(l+2)+Hd)}
|
|
58
|
+
`)},tn=t=>new qr({validate:t.validate,mask:t.mask??Wd,signal:t.signal,input:t.input,output:t.output,render(){let e=t.withGuide??ee.withGuide,r=`${e?`${p("gray",O)}
|
|
59
|
+
`:""}${or(this.state)} ${t.message}
|
|
60
|
+
`,n=this.userInputWithCursor,s=this.masked;switch(this.state){case"error":{let o=e?`${p("yellow",O)} `:"",i=e?`${p("yellow",Je)} `:"",a=s??"";return t.clearOnError&&this.clear(),`${r.trim()}
|
|
61
|
+
${o}${a}
|
|
62
|
+
${i}${p("yellow",this.error)}
|
|
63
|
+
`}case"submit":{let o=e?`${p("gray",O)} `:"",i=s?p("dim",s):"";return`${r}${o}${i}`}case"cancel":{let o=e?`${p("gray",O)} `:"",i=s?p(["strikethrough","dim"],s):"";return`${r}${o}${i}${s&&e?`
|
|
64
|
+
${p("gray",O)}`:""}`}default:{let o=e?`${p("cyan",O)} `:"",i=e?p("cyan",Je):"";return`${r}${o}${n}
|
|
65
|
+
${i}
|
|
66
|
+
`}}}}).prompt(),Qd=t=>p("magenta",t),it=({indicator:t="dots",onCancel:e,output:r=process.stdout,cancelMessage:n,errorMessage:s,frames:o=bs?["\u25D2","\u25D0","\u25D3","\u25D1"]:["\u2022","o","O","0"],delay:i=bs?80:120,signal:a,...l}={})=>{let c=Pd(),d,m,f=!1,g=!1,h="",S,y=performance.now(),C=rr(r),N=l?.styleFrame??Qd,D=G=>{let w=G>1?s??ee.messages.error:n??ee.messages.cancel;g=G===1,f&&(tt(w,G),g&&typeof e=="function"&&e())},R=()=>D(2),T=()=>D(1),v=()=>{process.on("uncaughtExceptionMonitor",R),process.on("unhandledRejection",R),process.on("SIGINT",T),process.on("SIGTERM",T),process.on("exit",D),a&&a.addEventListener("abort",T)},I=()=>{process.removeListener("uncaughtExceptionMonitor",R),process.removeListener("unhandledRejection",R),process.removeListener("SIGINT",T),process.removeListener("SIGTERM",T),process.removeListener("exit",D),a&&a.removeEventListener("abort",T)},Y=()=>{if(S===void 0)return;c&&r.write(`
|
|
67
|
+
`);let G=Ue(S,C,{hard:!0,trim:!1}).split(`
|
|
68
|
+
`);G.length>1&&r.write(sr.cursor.up(G.length-1)),r.write(sr.cursor.to(0)),r.write(sr.erase.down())},Z=G=>G.replace(/\.+$/,""),ve=G=>{let w=(performance.now()-G)/1e3,A=Math.floor(w/60),L=Math.floor(w%60);return A>0?`[${A}m ${L}s]`:`[${L}s]`},Q=l.withGuide??ee.withGuide,At=(G="")=>{f=!0,d=ta({output:r}),h=Z(G),y=performance.now(),Q&&r.write(`${p("gray",O)}
|
|
69
|
+
`);let w=0,A=0;v(),m=setInterval(()=>{if(c&&h===S)return;Y(),S=h;let L=N(o[w]),$;if(c)$=`${L} ${h}...`;else if(t==="timer")$=`${L} ${h} ${ve(y)}`;else{let $n=".".repeat(Math.floor(A)).slice(0,3);$=`${L} ${h}${$n}`}let Ce=Ue($,C,{hard:!0,trim:!1});r.write(Ce),w=w+1<o.length?w+1:0,A=A<4?A+.125:0},i)},tt=(G="",w=0,A=!1)=>{if(!f)return;f=!1,clearInterval(m),Y();let L=w===0?p("green",en):w===1?p("red",la):p("red",ca);h=G??h,A||(t==="timer"?r.write(`${L} ${h} ${ve(y)}
|
|
70
|
+
`):r.write(`${L} ${h}
|
|
71
|
+
`)),I(),d()};return{start:At,stop:(G="")=>tt(G,0),message:(G="")=>{h=Z(G??h)},cancel:(G="")=>tt(G,1),error:(G="")=>tt(G,2),clear:()=>tt("",0,!0),get isCancelled(){return g}}},PS={light:F("\u2500","-"),heavy:F("\u2501","="),block:F("\u2588","#")},$d=[`${p("dim","\u2191/\u2193")} to navigate`,`${p("dim","Enter:")} confirm`],Qr=(t,e)=>t.includes(`
|
|
72
|
+
`)?t.split(`
|
|
73
|
+
`).map(r=>e(r)).join(`
|
|
74
|
+
`):e(t),at=t=>{let e=(r,n)=>{let s=r.label??String(r.value);switch(n){case"disabled":return`${p("gray",$r)} ${Qr(s,o=>p("gray",o))}${r.hint?` ${p("dim",`(${r.hint??"disabled"})`)}`:""}`;case"selected":return`${Qr(s,o=>p("dim",o))}`;case"active":return`${p("green",ys)} ${s}${r.hint?` ${p("dim",`(${r.hint})`)}`:""}`;case"cancelled":return`${Qr(s,o=>p(["strikethrough","dim"],o))}`;default:return`${p("dim",$r)} ${Qr(s,o=>p("dim",o))}`}};return new zr({options:t.options,signal:t.signal,input:t.input,output:t.output,initialValue:t.initialValue,render(){let r=t.withGuide??ee.withGuide,n=`${or(this.state)} `,s=`${ua(this.state)} `,o=ot(t.output,t.message,s,n),i=`${r?`${p("gray",O)}
|
|
75
|
+
`:""}${o}
|
|
76
|
+
`;switch(this.state){case"submit":{let a=r?`${p("gray",O)} `:"",l=ot(t.output,e(this.options[this.cursor],"selected"),a);return`${i}${l}`}case"cancel":{let a=r?`${p("gray",O)} `:"",l=ot(t.output,e(this.options[this.cursor],"cancelled"),a);return`${i}${l}${r?`
|
|
77
|
+
${p("gray",O)}`:""}`}default:{let a=r?`${p("cyan",O)} `:"",l=i.split(`
|
|
78
|
+
`).length,c=da($d,r),d=c.join(`
|
|
79
|
+
`),m=c.length+1;return`${i}${a}${Ts({output:t.output,cursor:this.cursor,options:this.options,maxItems:t.maxItems,columnPadding:a.length,rowPadding:l+m,style:(f,g)=>e(f,f.disabled?"disabled":g?"active":"inactive")}).join(`
|
|
80
|
+
${a}`)}
|
|
81
|
+
${d}
|
|
82
|
+
`}}}}).prompt()},US=`${p("gray",O)} `,rn=async(t,e)=>{for(let r of t){if(r.enabled===!1)continue;let n=it(e);n.start(r.title);let s=await r.task(n.message);n.stop(s||r.title)}},ar=t=>new Zr({validate:t.validate,placeholder:t.placeholder,defaultValue:t.defaultValue,initialValue:t.initialValue,output:t.output,signal:t.signal,input:t.input,render(){let e=t?.withGuide??ee.withGuide,r=`${`${e?`${p("gray",O)}
|
|
83
|
+
`:""}${or(this.state)} `}${t.message}
|
|
84
|
+
`,n=t.placeholder?p("inverse",t.placeholder[0])+p("dim",t.placeholder.slice(1)):p(["inverse","hidden"],"_"),s=this.userInput?this.userInputWithCursor:n,o=this.value??"";switch(this.state){case"error":{let i=this.error?` ${p("yellow",this.error)}`:"",a=e?`${p("yellow",O)} `:"",l=e?p("yellow",Je):"";return`${r.trim()}
|
|
85
|
+
${a}${s}
|
|
86
|
+
${l}${i}
|
|
87
|
+
`}case"submit":{let i=o?` ${p("dim",o)}`:"",a=e?p("gray",O):"";return`${r}${a}${i}`}case"cancel":{let i=o?` ${p(["strikethrough","dim"],o)}`:"",a=e?p("gray",O):"";return`${r}${a}${i}${o.trim()?`
|
|
88
|
+
${a}`:""}`}default:{let i=e?`${p("cyan",O)} `:"",a=e?p("cyan",Je):"";return`${r}${i}${s}
|
|
89
|
+
${a}
|
|
90
|
+
`}}}}).prompt()});import{spawn as ep}from"node:child_process";function Xe(t,e,r){return ep(t,e??[],{windowsHide:!0,...r})}var Lt=b(()=>{"use strict"});function wt(t){return process.platform==="win32"?Math.round(t*ne.WINDOWS_MULTIPLIER):t}var ne,lr=b(()=>{"use strict";ne={DEFAULT:3e5,HEALTH_CHECK:3e3,API_REQUEST:3e4,HOOK_READINESS_WAIT:1e4,POST_SPAWN_WAIT:15e3,READINESS_WAIT:3e4,PORT_IN_USE_WAIT:3e3,WORKER_STARTUP_WAIT:1e3,PRE_RESTART_SETTLE_DELAY:2e3,POWERSHELL_COMMAND:1e4,WINDOWS_MULTIPLIER:1.5}});import{readFileSync as tp,existsSync as Cs,mkdirSync as rp,renameSync as np}from"fs";import{join as fa,dirname as sp}from"path";import{homedir as ga}from"os";var le,lt=b(()=>{"use strict";lr();Ae();le=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-haiku-4-5-20251001",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:String(37700+(process.getuid?.()??77)%100),CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_API_TIMEOUT_MS:String(wt(ne.API_REQUEST)),CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"subscription",CLAUDE_MEM_GEMINI_API_KEY:"",CLAUDE_MEM_GEMINI_MODEL:"gemini-2.5-flash-lite",CLAUDE_MEM_GEMINI_RATE_LIMITING_ENABLED:"true",CLAUDE_MEM_GEMINI_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_GEMINI_MAX_TOKENS:"100000",CLAUDE_MEM_OPENROUTER_API_KEY:"",CLAUDE_MEM_OPENROUTER_MODEL:"xiaomi/mimo-v2-flash:free",CLAUDE_MEM_OPENROUTER_BASE_URL:"",CLAUDE_MEM_OPENROUTER_SITE_URL:"",CLAUDE_MEM_OPENROUTER_APP_NAME:"claude-mem",CLAUDE_MEM_OPENROUTER_MAX_CONTEXT_MESSAGES:"20",CLAUDE_MEM_OPENROUTER_MAX_TOKENS:"100000",CLAUDE_MEM_DATA_DIR:fa(ga(),".keepmind"),CLAUDE_MEM_LOG_LEVEL:"INFO",CLAUDE_MEM_PYTHON_VERSION:"3.13",CLAUDE_CODE_PATH:"",CLAUDE_MEM_MODE:"code",CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT:"false",CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_PERCENT:"true",CLAUDE_MEM_CONTEXT_FULL_COUNT:"0",CLAUDE_MEM_CONTEXT_FULL_FIELD:"narrative",CLAUDE_MEM_CONTEXT_SESSION_COUNT:"10",CLAUDE_MEM_CONTEXT_SHOW_LAST_SUMMARY:"true",CLAUDE_MEM_CONTEXT_SHOW_LAST_MESSAGE:"false",CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT:"true",CLAUDE_MEM_WELCOME_HINT_ENABLED:"true",CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:fa(ga(),".keepmind","transcript-watch.json"),CLAUDE_MEM_CODEX_TRANSCRIPT_INGESTION:"false",CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_HOOK_FAIL_LOUD_THRESHOLD:"3",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",CLAUDE_MEM_FOLDER_MD_SKELETON_DENYLIST:"[]",CLAUDE_MEM_SEMANTIC_INJECT:"false",CLAUDE_MEM_SEMANTIC_INJECT_LIMIT:"5",CLAUDE_MEM_TIER_ROUTING_ENABLED:"true",CLAUDE_MEM_TIER_SIMPLE_MODEL:"haiku",CLAUDE_MEM_TIER_SUMMARY_MODEL:"",CLAUDE_MEM_TIER_FAST_MODEL:"haiku",CLAUDE_MEM_TIER_SMART_MODEL:"sonnet",CLAUDE_MEM_CHROMA_ENABLED:"true",CLAUDE_MEM_TELEGRAM_ENABLED:"true",CLAUDE_MEM_TELEGRAM_BOT_TOKEN:"",CLAUDE_MEM_TELEGRAM_CHAT_ID:"",CLAUDE_MEM_TELEGRAM_TRIGGER_TYPES:"security_alert",CLAUDE_MEM_TELEGRAM_TRIGGER_CONCEPTS:"",CLAUDE_MEM_QUEUE_ENGINE:"sqlite",CLAUDE_MEM_REDIS_URL:"",CLAUDE_MEM_REDIS_HOST:"127.0.0.1",CLAUDE_MEM_REDIS_PORT:"6379",CLAUDE_MEM_REDIS_MODE:"external",CLAUDE_MEM_QUEUE_REDIS_PREFIX:`claude_mem_${process.env.CLAUDE_MEM_WORKER_PORT??String(37700+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_AUTH_MODE:"api-key",CLAUDE_MEM_RUNTIME:"worker",CLAUDE_MEM_SERVER_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_API_KEY:"",CLAUDE_MEM_SERVER_PROJECT_ID:"",CLAUDE_MEM_SERVER_BETA_URL:`http://127.0.0.1:${process.env.CLAUDE_MEM_SERVER_PORT??String(37877+(process.getuid?.()??77)%100)}`,CLAUDE_MEM_SERVER_BETA_API_KEY:"",CLAUDE_MEM_SERVER_BETA_PROJECT_ID:""};static getAllDefaults(){return{...this.DEFAULTS}}static envOverride(e){let r=e.replace(/^CLAUDE_MEM_/,"KEEPMIND_");return process.env[r]??process.env[e]}static get(e){return this.envOverride(e)??this.DEFAULTS[e]}static getInt(e){let r=this.get(e);return parseInt(r,10)}static getBool(e){let r=this.get(e);return r==="true"||r===!0}static applyEnvOverrides(e){let r={...e};for(let n of Object.keys(this.DEFAULTS)){let s=this.envOverride(n);s!==void 0&&(r[n]=s)}return r}static loadFromFile(e,r=!0){try{if(!Cs(e)){let a=this.getAllDefaults();try{let l=sp(e);Cs(l)||rp(l,{recursive:!0}),re(e,a),console.warn("[SETTINGS] Created settings file with defaults:",e)}catch(l){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,l instanceof Error?l.message:String(l))}return r?this.applyEnvOverrides(a):a}let n=tp(e,"utf-8"),s=JSON.parse(n.replace(/^\uFEFF/,"")),o=s;if(s.env&&typeof s.env=="object"){o=s.env;try{re(e,o),console.warn("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(a){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,a instanceof Error?a.message:String(a))}}let i={...this.DEFAULTS};for(let a of Object.keys(this.DEFAULTS))o[a]!==void 0&&(i[a]=o[a]);return r?this.applyEnvOverrides(i):i}catch(n){console.warn("[SETTINGS] Failed to load settings, using defaults:",e,n instanceof Error?n.message:String(n));let s=this.getAllDefaults();try{if(Cs(e)){let o=`${e}.corrupt-${Date.now()}`;np(e,o),console.warn("[SETTINGS] Backed up corrupt settings file to:",o)}re(e,s),console.warn("[SETTINGS] Recovered settings file with defaults:",e)}catch(o){console.warn("[SETTINGS] Failed to recover corrupt settings file:",e,o instanceof Error?o.message:String(o))}return r?this.applyEnvOverrides(s):s}}}});function ip(t){return(op??process.stderr.write.bind(process.stderr))(t)}function Rs(t){ip(t)}var op,ws=b(()=>{"use strict";op=null});import{appendFileSync as ap,existsSync as ha,mkdirSync as lp,readFileSync as cp}from"fs";import{join as up}from"path";var Os,Is,ks,u,X=b(()=>{"use strict";V();ws();Os=(o=>(o[o.DEBUG=0]="DEBUG",o[o.INFO=1]="INFO",o[o.WARN=2]="WARN",o[o.ERROR=3]="ERROR",o[o.SILENT=4]="SILENT",o))(Os||{}),Is=null,ks=class{level=null;useColor;logFilePath=null;logFileInitialized=!1;constructor(){this.useColor=process.stdout.isTTY??!1}ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInitialized=!0;try{let e=j.logsDir();ha(e)||lp(e,{recursive:!0});let r=new Date().toISOString().split("T")[0];this.logFilePath=up(e,`keepmind-${r}.log`)}catch(e){console.error("[LOGGER] Failed to initialize log file:",e instanceof Error?e.message:String(e)),this.logFilePath=null}}}getLevel(){if(this.level===null)try{let e=j.settings();if(ha(e)){let r=cp(e,"utf-8"),s=(JSON.parse(r).CLAUDE_MEM_LOG_LEVEL||"INFO").toUpperCase();this.level=Os[s]??1}else this.level=1}catch(e){console.error("[LOGGER] Failed to load log level from settings:",e instanceof Error?e.message:String(e)),this.level=1}return this.level}formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean")return e.toString();if(typeof e=="object"){if(e instanceof Error)return this.getLevel()===0?`${e.message}
|
|
91
|
+
${e.stack}`:e.message;if(Array.isArray(e))return`[${e.length} items]`;let r=Object.keys(e);return r.length===0?"{}":r.length<=3?JSON.stringify(e):`{${r.length} keys: ${r.slice(0,3).join(", ")}...}`}return String(e)}formatTool(e,r){if(!r)return e;let n=r;if(typeof r=="string")try{n=JSON.parse(r)}catch{n=r}if(e==="Bash"&&n.command)return`${e}(${n.command})`;if(n.file_path)return`${e}(${n.file_path})`;if(n.notebook_path)return`${e}(${n.notebook_path})`;if(e==="Glob"&&n.pattern)return`${e}(${n.pattern})`;if(e==="Grep"&&n.pattern)return`${e}(${n.pattern})`;if(n.url)return`${e}(${n.url})`;if(n.query)return`${e}(${n.query})`;if(e==="Task"){if(n.subagent_type)return`${e}(${n.subagent_type})`;if(n.description)return`${e}(${n.description})`}return e==="Skill"&&n.skill?`${e}(${n.skill})`:e==="LSP"&&n.operation?`${e}(${n.operation})`:e}formatTimestamp(e){let r=e.getFullYear(),n=String(e.getMonth()+1).padStart(2,"0"),s=String(e.getDate()).padStart(2,"0"),o=String(e.getHours()).padStart(2,"0"),i=String(e.getMinutes()).padStart(2,"0"),a=String(e.getSeconds()).padStart(2,"0"),l=String(e.getMilliseconds()).padStart(3,"0");return`${r}-${n}-${s} ${o}:${i}:${a}.${l}`}log(e,r,n,s,o){if(e<this.getLevel())return;this.ensureLogFileInitialized();let i=this.formatTimestamp(new Date),a=Os[e].padEnd(5),l=r.padEnd(6),c="";s?.correlationId?c=`[${s.correlationId}] `:s?.sessionId&&(c=`[session-${s.sessionId}] `);let d="";if(o!=null)if(o instanceof Error)d=this.getLevel()===0?`
|
|
92
|
+
${o.message}
|
|
93
|
+
${o.stack}`:` ${o.message}`;else if(this.getLevel()===0&&typeof o=="object")try{d=`
|
|
94
|
+
`+JSON.stringify(o,null,2)}catch{d=" "+this.formatData(o)}else d=" "+this.formatData(o);let m="";if(s){let{sessionId:g,memorySessionId:h,correlationId:S,...y}=s;Object.keys(y).length>0&&(m=` {${Object.entries(y).map(([N,D])=>`${N}=${D}`).join(", ")}}`)}let f=`[${i}] [${a}] [${l}] ${c}${n}${m}${d}`;if(this.logFilePath)try{ap(this.logFilePath,f+`
|
|
95
|
+
`,"utf8")}catch(g){Rs(`[LOGGER] Failed to write to log file: ${g instanceof Error?g.message:String(g)}
|
|
96
|
+
`)}else Rs(f+`
|
|
97
|
+
`)}debug(e,r,n,s){this.log(0,e,r,n,s)}info(e,r,n,s){this.log(1,e,r,n,s)}warn(e,r,n,s){this.log(2,e,r,n,s)}setErrorSink(e){Is=e}error(e,r,n,s){this.log(3,e,r,n,s),this.routeErrorToSink(r,n,s)}routeErrorToSink(e,r,n){try{if(!Is||!(n instanceof Error))return;Is(n)}catch{}}dataIn(e,r,n,s){this.info(e,`\u2192 ${r}`,n,s)}dataOut(e,r,n,s){this.info(e,`\u2190 ${r}`,n,s)}success(e,r,n,s){this.info(e,`\u2713 ${r}`,n,s)}failure(e,r,n,s){this.error(e,`\u2717 ${r}`,n,s)}happyPathError(e,r,n,s,o=""){let c=((new Error().stack||"").split(`
|
|
98
|
+
`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),d=c?`${c[1].split("/").pop()}:${c[2]}`:"unknown",m={...n,location:d};return this.warn(e,`[HAPPY-PATH] ${r}`,m,s),o}},u=new ks});import{join as P,dirname as dp,basename as pp}from"path";import{homedir as Ea}from"os";import{existsSync as ct,mkdirSync as mp,readFileSync as fp,renameSync as gp}from"fs";import{execSync as ob}from"child_process";import{fileURLToPath as hp}from"url";function Ep(){return typeof __dirname<"u"?__dirname:dp(hp(import.meta.url))}function ut(){let t=process.env.KEEPMIND_DATA_DIR??process.env.CLAUDE_MEM_DATA_DIR;if(t)return t;let e=P(Ea(),".keepmind"),r=P(e,"settings.json");try{if(ct(r)){let n=JSON.parse(fp(r,"utf-8")),s=n.env??n,o=s.KEEPMIND_DATA_DIR??s.CLAUDE_MEM_DATA_DIR;if(o)return o}}catch{}return e}function sn(t){mp(t,{recursive:!0})}function Rp(){try{if(ct(B)||!ct(cr))return ct(B);for(let t of["","-wal","-shm"]){let e=cr+t,r=B+t;ct(e)&&!ct(r)&&gp(e,r)}return u.info("DB","Migrated legacy claude-mem.db to keepmind.db",{from:cr,to:B}),!0}catch(t){return u.warn("DB","Could not rename legacy claude-mem.db to keepmind.db (file may be locked) \u2014 falling back to legacy path",{},t instanceof Error?t:new Error(String(t))),!1}}function Ns(){return Rp(),!ct(B)&&ct(cr)?cr:B}var lb,M,nn,ur,Sp,bp,yp,Tp,vp,Me,B,cr,Cp,Sa,_s,cb,ub,db,j,V=b(()=>{"use strict";X();lb=Ep();M=ut(),nn=process.env.CLAUDE_CONFIG_DIR||P(Ea(),".claude"),ur=P(nn,"plugins","marketplaces","keepmind"),Sp=P(M,"archives"),bp=P(M,"logs"),yp=P(M,"trash"),Tp=P(M,"backups"),vp=P(M,"modes"),Me=P(M,"settings.json"),B=P(M,"keepmind.db"),cr=P(M,"claude-mem.db"),Cp=P(M,"vector-db"),Sa=P(M,"observer-sessions"),_s=pp(Sa),cb=P(nn,"settings.json"),ub=P(nn,"commands"),db=P(nn,"CLAUDE.md");j={dataDir:()=>M,workerPid:()=>P(M,"worker.pid"),workerPort:()=>P(M,"worker.port"),serverPid:()=>P(M,".server-beta.pid"),serverPort:()=>P(M,".server-beta.port"),serverRuntime:()=>P(M,".server-beta.runtime.json"),settings:()=>P(M,"settings.json"),database:()=>Ns(),chroma:()=>P(M,"chroma"),combinedCerts:()=>P(M,"combined_certs.pem"),transcriptsConfig:()=>P(M,"transcript-watch.json"),transcriptsState:()=>P(M,"transcript-watch-state.json"),corpora:()=>P(M,"corpora"),supervisorRegistry:()=>P(M,"supervisor.json"),envFile:()=>P(M,".env"),logsDir:()=>bp,archives:()=>Sp,trash:()=>yp,backups:()=>Tp,modes:()=>vp,vectorDb:()=>Cp,observerSessions:()=>Sa}});import{execFile as wp}from"child_process";import{promisify as Ip}from"util";import{existsSync as hb,readFileSync as Eb,writeFileSync as Sb,mkdirSync as bb,unlinkSync as yb}from"fs";import{userInfo as vb}from"os";import{join as Rb}from"path";var Ob,ba=b(()=>{"use strict";V();X();Ob=Ip(wp)});import{existsSync as As,readFileSync as Ta,writeFileSync as Op,mkdirSync as kp,chmodSync as ya}from"fs";import{parseEnv as _p}from"util";function va(){return process.env.CLAUDE_MEM_ENV_FILE??j.envFile()}function Ra(t){return _p(t)}function Np(t){let e=["# claude-mem credentials","# This file stores keys and gateway settings for the claude-mem memory agent","# Edit this file or use claude-mem settings to configure",""];for(let[r,n]of Object.entries(t))if(n){let s=/[\s#=]/.test(n);e.push(`${r}=${s?`"${n}"`:n}`)}return e.join(`
|
|
99
|
+
`)+`
|
|
100
|
+
`}function dr(){let t=va();if(!As(t))return{};try{let e=Ta(t,"utf-8"),r=Ra(e),n={};for(let s of Ca)r[s]&&(n[s]=r[s]);return n}catch(e){return u.warn("ENV","Failed to load .env file",{path:t},e instanceof Error?e:new Error(String(e))),{}}}function pr(t){let e=va(),r={};try{As(j.dataDir())||kp(j.dataDir(),{recursive:!0,mode:448}),ya(j.dataDir(),448),r=As(e)?Ra(Ta(e,"utf-8")):{}}catch(s){let o=s instanceof Error?s:new Error(String(s));throw u.error("ENV","Failed to set up env directory or read existing env",{},o),o}let n={...r};for(let s of Ca){let o=t[s];o!==void 0&&(o?n[s]=o:delete n[s])}try{Op(e,Np(n),{encoding:"utf-8",mode:384}),ya(e,384)}catch(s){throw u.error("ENV","Failed to save .env file",{path:e},s instanceof Error?s:new Error(String(s))),s}}var Ca,wa=b(()=>{"use strict";X();V();ba();Ca=["ANTHROPIC_API_KEY","ANTHROPIC_BASE_URL","ANTHROPIC_AUTH_TOKEN","GEMINI_API_KEY","OPENROUTER_API_KEY"]});import{DatabaseSync as Ap}from"node:sqlite";function Ia(t){return typeof t=="bigint"?Number(t):t}function Mp(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)&&!(t instanceof Uint8Array)&&!(typeof Buffer<"u"&&Buffer.isBuffer(t))}function Oa(t){return t===void 0?null:typeof t=="boolean"?t?1:0:t}function on(t){let e=t;if(e.length===1&&Array.isArray(e[0])&&(e=e[0]),e.length===1&&Mp(e[0])){let r=e[0],n={};for(let s of Object.keys(r))n[s]=Oa(r[s]);return[n]}return e.map(Oa)}var Ms,ye,mr=b(()=>{"use strict";Ms=class{constructor(e){this.stmt=e}stmt;all(...e){return this.stmt.all(...on(e))}get(...e){return this.stmt.get(...on(e))??null}run(...e){let r=this.stmt.run(...on(e));return{changes:Ia(r.changes),lastInsertRowid:Ia(r.lastInsertRowid)}}values(...e){return this.stmt.all(...on(e)).map(n=>Object.values(n))}finalize(){}},ye=class{db;queryCache=new Map;safeIntegers;txDepth=0;filename;constructor(e,r={}){let n=r.readonly===!0;this.safeIntegers=r.safeIntegers===!0;let s=e&&e.length>0?e:":memory:";if(this.filename=s,this.db=new Ap(s,{readOnly:n,allowExtension:!0}),!n&&s!==":memory:")try{this.db.exec("PRAGMA journal_mode=WAL")}catch{}}wrap(e){return this.safeIntegers&&e.setReadBigInts(!0),new Ms(e)}prepare(e){return this.wrap(this.db.prepare(e))}query(e){let r=this.queryCache.get(e);if(r)return r;let n=this.prepare(e);return this.queryCache.set(e,n),n}run(e,...r){return r.length===0?(this.db.exec(e),{changes:0,lastInsertRowid:0}):this.prepare(e).run(...r)}exec(e){this.db.exec(e)}loadExtension(e,r){this.db.loadExtension(e)}transaction(e){return(...r)=>{let n=this.txDepth===0,s=`__cm_sp_${this.txDepth}`;n?this.db.exec("BEGIN"):this.db.exec(`SAVEPOINT ${s}`),this.txDepth++;try{let o=e(...r);return this.txDepth--,n?this.db.exec("COMMIT"):this.db.exec(`RELEASE ${s}`),o}catch(o){throw this.txDepth--,n?this.db.exec("ROLLBACK"):(this.db.exec(`ROLLBACK TO ${s}`),this.db.exec(`RELEASE ${s}`)),o}}}close(){this.db.close()}}});function ka(t){return t instanceof Error?t:new Error(String(t))}var _a=b(()=>{"use strict"});function It(t=process.env){let e={};for(let[r,n]of Object.entries(t))if(n!==void 0){if(Dp.has(r)){e[r]=n;continue}Lp.has(r)||xp.some(s=>r.startsWith(s))||(e[r]=n)}return e}var xp,Lp,Dp,an=b(()=>{"use strict";xp=["CLAUDECODE_","CLAUDE_CODE_"],Lp=new Set(["CLAUDECODE","CLAUDE_CODE_SESSION","CLAUDE_CODE_ENTRYPOINT","MCP_SESSION_ID","HTTP_PROXY","HTTPS_PROXY","ALL_PROXY","NO_PROXY","http_proxy","https_proxy","all_proxy","no_proxy","npm_config_proxy","npm_config_https_proxy"]),Dp=new Set(["CLAUDE_CODE_OAUTH_TOKEN","CLAUDE_CODE_GIT_BASH_PATH","CLAUDE_CODE_USE_BEDROCK","CLAUDE_CODE_USE_VERTEX","ANTHROPIC_BEDROCK_BASE_URL","AWS_REGION","AWS_PROFILE","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SESSION_TOKEN","ANTHROPIC_VERTEX_PROJECT_ID","CLOUD_ML_REGION","GOOGLE_APPLICATION_CREDENTIALS"])});import{spawnSync as xa}from"child_process";import{existsSync as Pp,mkdirSync as Na,readFileSync as La,writeFileSync as Up}from"fs";import Aa from"path";function Ve(t){if(!Number.isInteger(t)||t<0||t===0)return!1;try{return process.kill(t,0),!0}catch(e){if(e instanceof Error){let r=e.code;return r==="EPERM"?!0:(u.debug("SYSTEM","PID check failed",{pid:t,code:r}),!1)}return u.warn("SYSTEM","PID check threw non-Error",{pid:t,error:String(e)}),!1}}async function ln(t,e){let r=Date.now()+e;for(;Date.now()<r;){if(t.every(n=>!Ve(n.pid)))return;await new Promise(n=>setTimeout(n,100))}}function Bp(t){let e=Ma.get(t);if(e&&Date.now()-e.capturedAtMs<Gp)return e.token;let r=null;try{let n=xa("powershell.exe",["-NoProfile","-NonInteractive","-Command",`(Get-CimInstance Win32_Process -Filter "ProcessId=${t}").CreationDate.ToString('yyyyMMddHHmmss.ffffff')`],{encoding:"utf-8",timeout:5e3,windowsHide:!0,env:{...It(process.env),LC_ALL:"C",LANG:"C"}});if(n.status===0){let s=n.stdout.trim();r=s.length>0?s:null}}catch(n){u.debug("SYSTEM","captureProcessStartToken: powershell CIM lookup failed",{pid:t,error:n instanceof Error?n.message:String(n)}),r=null}return Ma.set(t,{token:r,capturedAtMs:Date.now()}),r}function Da(t){if(!Number.isInteger(t)||t<=0)return null;if(process.platform==="linux")try{let e=La(`/proc/${t}/stat`,"utf-8"),r=e.lastIndexOf(") ");if(r<0)return null;let s=e.slice(r+2).split(" ")[19];return s&&/^\d+$/.test(s)?s:null}catch(e){return u.debug("SYSTEM","captureProcessStartToken: /proc read failed",{pid:t,error:e instanceof Error?e.message:String(e)}),null}if(process.platform==="win32")return Bp(t);try{let e=xa("ps",["-p",String(t),"-o","lstart="],{encoding:"utf-8",timeout:2e3,env:{...It(process.env),LC_ALL:"C",LANG:"C"}});if(e.status!==0)return null;let r=e.stdout.trim();return r.length>0?r:null}catch(e){return u.debug("SYSTEM","captureProcessStartToken: ps exec failed",{pid:t,error:e instanceof Error?e.message:String(e)}),null}}function Ps(t){if(!t||!Ve(t.pid))return!1;if(!t.startToken)return!0;let e=Da(t.pid);if(e===null)return!0;let r=e===t.startToken;return r||u.debug("SYSTEM","verifyPidFileOwnership: start-token mismatch (PID reused)",{pid:t.pid,stored:t.startToken,current:e}),r}function cn(){return xs||(xs=new Ds),xs}function Ls(){let t=Hp.shift();t&&t()}var Fp,jp,Wp,Gp,Ma,Ds,xs,Hp,fr=b(()=>{"use strict";Lt();X();an();V();Fp=5e3,jp=1e3,Wp=j.supervisorRegistry();Gp=5e3,Ma=new Map;Ds=class{registryPath;entries=new Map;runtimeProcesses=new Map;initialized=!1;constructor(e=Wp){this.registryPath=e}initialize(){if(this.initialized)return;if(this.initialized=!0,Na(Aa.dirname(this.registryPath),{recursive:!0}),!Pp(this.registryPath)){this.persist();return}try{let n=JSON.parse(La(this.registryPath,"utf-8")).processes??{};for(let[s,o]of Object.entries(n))this.entries.set(s,o)}catch(r){r instanceof Error?u.warn("SYSTEM","Failed to parse supervisor registry, rebuilding",{path:this.registryPath},r):u.warn("SYSTEM","Failed to parse supervisor registry, rebuilding",{path:this.registryPath,error:String(r)}),this.entries.clear()}let e=this.pruneDeadEntries();e>0&&u.info("SYSTEM","Removed dead processes from supervisor registry",{removed:e}),this.persist()}register(e,r,n){this.initialize(),this.entries.set(e,r),n&&this.runtimeProcesses.set(e,n),this.persist()}unregister(e){this.initialize();let r=this.entries.get(e);this.entries.delete(e),this.runtimeProcesses.delete(e),this.persist(),r?.type==="sdk"&&Ls()}clear(){this.entries.clear(),this.runtimeProcesses.clear(),this.persist()}getAll(){return this.initialize(),Array.from(this.entries.entries()).map(([e,r])=>({id:e,...r})).sort((e,r)=>{let n=Date.parse(e.startedAt),s=Date.parse(r.startedAt);return(Number.isNaN(n)?0:n)-(Number.isNaN(s)?0:s)})}getBySession(e){let r=String(e);return this.getAll().filter(n=>n.sessionId!==void 0&&String(n.sessionId)===r)}getRuntimeProcess(e){return this.runtimeProcesses.get(e)}getByPid(e){return this.getAll().filter(r=>r.pid===e)}pruneDeadEntries(){this.initialize();let e=0,r=0;for(let[n,s]of this.entries)Ve(s.pid)||(this.entries.delete(n),this.runtimeProcesses.delete(n),e+=1,s.type==="sdk"&&(r+=1));e>0&&this.persist();for(let n=0;n<r;n+=1)Ls();return e}async reapSession(e){this.initialize();let r=this.getBySession(e);if(r.length===0)return 0;let n=typeof e=="number"?e:Number(e)||void 0;u.info("SYSTEM",`Reaping ${r.length} process(es) for session ${e}`,{sessionId:n,pids:r.map(i=>i.pid)});let s=r.filter(i=>Ve(i.pid));for(let i of s)try{typeof i.pgid=="number"&&process.platform!=="win32"?process.kill(-i.pgid,"SIGTERM"):process.kill(i.pid,"SIGTERM")}catch(a){a instanceof Error?a.code!=="ESRCH"&&u.debug("SYSTEM",`Failed to SIGTERM session process PID ${i.pid}`,{pid:i.pid,pgid:i.pgid},a):u.warn("SYSTEM",`Failed to SIGTERM session process PID ${i.pid} (non-Error)`,{pid:i.pid,pgid:i.pgid,error:String(a)})}await ln(s,Fp);let o=s.filter(i=>Ve(i.pid));for(let i of o){u.warn("SYSTEM",`Session process PID ${i.pid} did not exit after SIGTERM, sending SIGKILL`,{pid:i.pid,pgid:i.pgid,sessionId:n});try{typeof i.pgid=="number"&&process.platform!=="win32"?process.kill(-i.pgid,"SIGKILL"):process.kill(i.pid,"SIGKILL")}catch(a){a instanceof Error?a.code!=="ESRCH"&&u.debug("SYSTEM",`Failed to SIGKILL session process PID ${i.pid}`,{pid:i.pid,pgid:i.pgid},a):u.warn("SYSTEM",`Failed to SIGKILL session process PID ${i.pid} (non-Error)`,{pid:i.pid,pgid:i.pgid,error:String(a)})}}if(o.length>0){let i=Date.now()+jp;for(;Date.now()<i&&o.filter(l=>Ve(l.pid)).length!==0;)await new Promise(l=>setTimeout(l,100))}for(let i of r)this.entries.delete(i.id),this.runtimeProcesses.delete(i.id);this.persist();for(let i of r)i.type==="sdk"&&Ls();return u.info("SYSTEM",`Reaped ${r.length} process(es) for session ${e}`,{sessionId:n,reaped:r.length}),r.length}persist(){let e={processes:Object.fromEntries(this.entries.entries())};Na(Aa.dirname(this.registryPath),{recursive:!0}),Up(this.registryPath,JSON.stringify(e,null,2))}},xs=null;Hp=[]});import{execFile as Jp}from"child_process";import{existsSync as Kp,readFileSync as Xp,rmSync as Vp}from"fs";import{promisify as Yp}from"util";async function Ua(t){let e=t.currentPid??process.pid,r=t.pidFilePath??zp,n=t.registry.getAll(),s=[...n].filter(i=>i.pid!==e).sort((i,a)=>Date.parse(a.startedAt)-Date.parse(i.startedAt));for(let i of s){if(!Ve(i.pid)){t.registry.unregister(i.id);continue}try{await Pa(i,"SIGTERM")}catch(a){a instanceof Error?u.debug("SYSTEM","Failed to send SIGTERM to child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):u.warn("SYSTEM","Failed to send SIGTERM to child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}}await ln(s,5e3);let o=s.filter(i=>Ve(i.pid));for(let i of o)try{await Pa(i,"SIGKILL")}catch(a){a instanceof Error?u.debug("SYSTEM","Failed to force kill child process",{pid:i.pid,pgid:i.pgid,type:i.type},a):u.warn("SYSTEM","Failed to force kill child process (non-Error)",{pid:i.pid,pgid:i.pgid,type:i.type,error:String(a)})}await ln(o,1e3);for(let i of s)t.registry.unregister(i.id);for(let i of n.filter(a=>a.pid===e))t.registry.unregister(i.id);Zp(r,e),t.registry.pruneDeadEntries()}function Zp(t,e){if(!Kp(t))return;let r=null;try{let n=JSON.parse(Xp(t,"utf-8"));r=typeof n.pid=="number"?n.pid:null}catch(n){u.debug("SYSTEM","PID file unreadable during shutdown \u2014 leaving it (cannot prove ownership)",{pidFilePath:t,error:n instanceof Error?n.message:String(n)});return}if(r!==e){u.debug("SYSTEM","PID file not owned by this process \u2014 leaving it for its owner (restart successor?)",{pidFilePath:t,recordedPid:r,currentPid:e});return}try{Vp(t,{force:!0})}catch(n){n instanceof Error?u.debug("SYSTEM","Failed to remove PID file during shutdown",{pidFilePath:t},n):u.warn("SYSTEM","Failed to remove PID file during shutdown (non-Error)",{pidFilePath:t,error:String(n)})}}async function Pa(t,e){let{pid:r,pgid:n}=t;if(process.platform!=="win32"){if(typeof n=="number")try{process.kill(-n,e);return}catch(i){if((i instanceof Error?i.code:void 0)!=="ESRCH")throw i}try{process.kill(r,e)}catch(i){if((i instanceof Error?i.code:void 0)!=="ESRCH")throw i}return}if(e==="SIGTERM"){try{process.kill(r,e)}catch(i){if(i instanceof Error&&i.code==="ESRCH")return;throw i}return}let s=await Qp();if(s){await new Promise((i,a)=>{s(r,e,l=>{if(!l){i();return}if(l.code==="ESRCH"){i();return}a(l)})});return}let o=["/PID",String(r),"/T"];e==="SIGKILL"&&o.push("/F"),await qp("taskkill",o,{timeout:ne.POWERSHELL_COMMAND,windowsHide:!0})}async function Qp(){let t="tree-kill";try{let e=await import(t);return e.default??e}catch(e){return u.debug("SYSTEM","tree-kill module not available, using fallback",{},e instanceof Error?e:void 0),null}}var qp,zp,Fa=b(()=>{"use strict";X();lr();fr();V();qp=Yp(Jp),zp=j.workerPid()});function $p(){let e=cn().pruneDeadEntries();e>0&&u.info("SYSTEM",`Health check: pruned ${e} dead process(es) from registry`)}function Wa(){Dt===null&&(Dt=setInterval($p,ja),Dt.unref(),u.debug("SYSTEM","Health checker started",{intervalMs:ja}))}function Ga(){Dt!==null&&(clearInterval(Dt),Dt=null,u.debug("SYSTEM","Health checker stopped"))}var ja,Dt,Ba=b(()=>{"use strict";X();fr();ja=3e4,Dt=null});import{existsSync as em,readFileSync as tm,rmSync as Ha}from"fs";function Fs(){return nm}function un(t={}){let e=t.pidFilePath??rm;if(!em(e))return"missing";let r=null;try{r=JSON.parse(tm(e,"utf-8"))}catch(s){return s instanceof Error?u.warn("SYSTEM","Failed to parse worker PID file, removing it",{path:e},s):u.warn("SYSTEM","Failed to parse worker PID file, removing it",{path:e,error:String(s)}),Ha(e,{force:!0}),"invalid"}return Ps(r)&&r?((t.logAlive??!0)&&u.info("SYSTEM","Worker already running (PID alive)",{existingPid:r.pid,existingPort:r.port,startedAt:r.startedAt}),"alive"):(u.info("SYSTEM","Removing stale PID file (worker process is dead or PID has been reused)",{pid:r?.pid,port:r?.port,startedAt:r?.startedAt}),Ha(e,{force:!0}),"stale")}var rm,Us,nm,dn=b(()=>{"use strict";X();fr();Fa();Ba();V();rm=j.workerPid(),Us=class{registry;started=!1;stopPromise=null;signalHandlersRegistered=!1;shutdownInitiated=!1;shutdownHandler=null;constructor(e){this.registry=e}async start(){if(this.started)return;if(this.registry.initialize(),un({logAlive:!1})==="alive")throw new Error("Worker already running");this.started=!0,Wa()}configureSignalHandlers(e){if(this.shutdownHandler=e,this.signalHandlersRegistered)return;this.signalHandlersRegistered=!0;let r=async n=>{if(this.shutdownInitiated){u.warn("SYSTEM",`Received ${n} but shutdown already in progress`);return}this.shutdownInitiated=!0,u.info("SYSTEM",`Received ${n}, shutting down...`);try{this.shutdownHandler?await this.shutdownHandler():await this.stop()}catch(s){s instanceof Error?u.error("SYSTEM","Error during shutdown",{},s):u.error("SYSTEM","Error during shutdown (non-Error)",{error:String(s)});try{await this.stop()}catch(o){o instanceof Error?u.debug("SYSTEM","Supervisor shutdown fallback failed",{},o):u.debug("SYSTEM","Supervisor shutdown fallback failed",{error:String(o)})}}process.exit(0)};process.on("SIGTERM",()=>{r("SIGTERM")}),process.on("SIGINT",()=>{r("SIGINT")}),process.platform!=="win32"&&(process.argv.includes("--daemon")?process.on("SIGHUP",()=>{u.debug("SYSTEM","Ignoring SIGHUP in daemon mode")}):process.on("SIGHUP",()=>{r("SIGHUP")}))}async stop(){if(this.stopPromise){await this.stopPromise;return}Ga(),this.stopPromise=Ua({registry:this.registry,currentPid:process.pid}).finally(()=>{this.started=!1,this.stopPromise=null}),await this.stopPromise}assertCanSpawn(e){if(this.stopPromise!==null)throw new Error(`Supervisor is shutting down, refusing to spawn ${e}`)}registerProcess(e,r,n){this.registry.register(e,r,n)}unregisterProcess(e){this.registry.unregister(e)}getRegistry(){return this.registry}},nm=new Us(cn())});import sm from"path";import{homedir as om}from"os";import{existsSync as pn,writeFileSync as by,readFileSync as im,unlinkSync as yy,mkdirSync as Ty,rmSync as vy,statSync as Cy,utimesSync as am,copyFileSync as Ry}from"fs";import{execSync as lm,spawnSync as Iy}from"child_process";function Ja(t){return t?/(^|[\\/])node(\.exe)?$/i.test(t.trim()):!1}function cm(t,e){let r=e==="win32"?`where ${t}`:`which ${t}`,n;try{n=lm(r,{stdio:["ignore","pipe","ignore"],encoding:"utf-8",windowsHide:!0})}catch(o){return o instanceof Error?u.debug("SYSTEM",`Binary lookup failed for ${t}`,{command:r},o):u.debug("SYSTEM",`Binary lookup failed for ${t}`,{command:r},new Error(String(o))),null}return n.split(/\r?\n/).map(o=>o.trim()).find(o=>o.length>0)||null}function mn(t={}){let e=Object.keys(t).length===0;if(e&&js!==void 0)return js;let r=um(t);return e&&r!==null&&(js=r),r}function um(t){let e=t.platform??process.platform,r=t.execPath??process.execPath;if(Ja(r))return r;let n=t.env??process.env,s=t.homeDirectory??om(),o=t.pathExists??pn,i=t.lookupInPath??cm,a=e==="win32"?[n.NODE,sm.join(s,".nvm","current","bin","node.exe"),"node"]:[n.NODE,"/usr/local/bin/node","/opt/homebrew/bin/node","/usr/bin/node","node"];for(let l of a){let c=l?.trim();if(c&&(Ja(c)&&o(c)||c.toLowerCase()==="node"))return c}return i("node",e)}function Ka(){if(!pn(Pt))return null;try{return JSON.parse(im(Pt,"utf-8"))}catch(t){return t instanceof Error?u.warn("SYSTEM","Failed to parse PID file",{path:Pt},t):u.warn("SYSTEM","Failed to parse PID file",{path:Pt},new Error(String(t))),null}}function dt(t){return process.platform==="win32"?Math.round(t*2):t}function Xa(t,e,r={}){Fs().assertCanSpawn("worker daemon");let n=It({...process.env,CLAUDE_MEM_WORKER_PORT:String(e),...r}),s=mn();if(!s){u.error("SYSTEM","Node runtime not found \u2014 ensure node is on PATH or set the NODE env var. The worker daemon runs under Node (node:sqlite).");return}if(process.platform==="win32")try{let d=Xe(s,[t,"--daemon"],{detached:!0,stdio:"ignore",windowsHide:!0,env:n});if(d.pid===void 0){u.error("SYSTEM","Worker daemon spawn produced no PID on Windows",{runtimePath:s});return}return d.unref(),d.pid}catch(d){u.error("SYSTEM","Failed to spawn worker daemon on Windows",{runtimePath:s},ka(d));return}let o="/usr/bin/setsid",i=pn(o),c=Xe(i?o:s,i?[s,t,"--daemon"]:[t,"--daemon"],{detached:!0,stdio:"ignore",env:n});if(c.pid!==void 0)return c.unref(),c.pid}function Va(t){if(t===0)return!0;if(!Number.isInteger(t)||t<0)return!1;try{return process.kill(t,0),!0}catch(e){if(e instanceof Error){let r=e.code;if(r==="EPERM")return!0;u.debug("SYSTEM","Process not alive",{pid:t,code:r})}else u.debug("SYSTEM","Process not alive (non-Error thrown)",{pid:t},new Error(String(e)));return!1}}function Ya(){try{if(!pn(Pt))return;let t=new Date;am(Pt,t,t)}catch{}}function qa(){return un({logAlive:!1})}var Ly,Pt,Dy,js,gr=b(()=>{"use strict";Lt();mr();X();_a();an();dn();V();fr();Ly=j.dataDir(),Pt=j.workerPid(),Dy=j.workerPort()});import jy from"path";import dm from"net";import{readFileSync as By}from"fs";async function mm(t,e,r="GET"){let n=await fetch(`http://127.0.0.1:${t}${e}`,{method:r,signal:AbortSignal.timeout(pm)}),s="";try{s=await n.text()}catch{}return{ok:n.ok,statusCode:n.status,body:s}}async function za(t){return new Promise(e=>{let r=dm.createServer();r.once("error",n=>{n.code==="EADDRINUSE"||n.code==="EACCES"?e(!0):e(!1)}),r.once("listening",()=>{r.close(()=>e(!1))}),r.listen(t,"127.0.0.1")})}async function Za(t,e,r,n){let s=Date.now();for(;Date.now()-s<r;){try{if((await mm(t,e)).ok)return!0}catch(o){o instanceof Error?u.debug("SYSTEM",n,{},o):u.debug("SYSTEM",n,{error:String(o)})}await new Promise(o=>setTimeout(o,500))}return!1}function hr(t,e=3e4){return Za(t,"/api/health",e,"Service not ready yet, will retry")}function Er(t,e=3e4){return Za(t,"/api/readiness",e,"Worker not ready yet, will retry")}var pm,Ws=b(()=>{"use strict";X();V();pm=2500});import{dirname as fm,join as gm}from"path";import{mkdirSync as hm,readFileSync as Em,statSync as Qa,unlinkSync as $a,writeFileSync as Sm}from"fs";function el(){return gm(ut(),"spawn.lock")}function Gs(){let t=el(),e=JSON.stringify({pid:process.pid,startedAt:new Date().toISOString()});for(let r=0;r<2;r++)try{return hm(fm(t),{recursive:!0}),Sm(t,e,{flag:"wx"}),!0}catch(n){if(n?.code!=="EEXIST")return!0;if(r>0)return!1;let o;try{o=Qa(t).mtimeMs}catch{continue}if(Date.now()-o<=bm)return!1;let i;try{i=Qa(t).mtimeMs}catch{continue}if(i!==o)return!1;try{$a(t)}catch{return!1}}return!1}function Bs(){let t=el();try{if(JSON.parse(Em(t,"utf-8")).pid!==process.pid)return;$a(t)}catch{}}var bm,Hs=b(()=>{"use strict";V();bm=6e4});import{existsSync as ym}from"fs";function Tm(t){let e=Ka();return e&&typeof e.port=="number"&&Va(e.pid)?e.port:t}async function vm(t,e){let r=Date.now()+e;for(;Date.now()<r;){let n=Tm(t);if(await hr(n,800))return n;await new Promise(s=>setTimeout(s,300))}return null}async function tl(t,e){if(!e)return u.error("SYSTEM","ensureWorkerStarted called with empty workerScriptPath \u2014 caller bug"),"dead";if(!ym(e))return u.error("SYSTEM","ensureWorkerStarted: worker script not found at expected path \u2014 likely a partial install or build artifact missing",{workerScriptPath:e}),"dead";if(qa()==="alive"){if(u.info("SYSTEM","Worker PID file points to a live process, skipping duplicate spawn"),await hr(t,dt(ne.PORT_IN_USE_WAIT))){let l=await Er(t,dt(ne.READINESS_WAIT));return u.info("SYSTEM","Worker became healthy while waiting on live PID"),l?"ready":"warming"}return u.warn("SYSTEM","Live PID detected but worker did not become healthy before timeout \u2014 likely still starting"),"warming"}if(await hr(t,1e3)){let a=await Er(t,dt(ne.READINESS_WAIT));return a||u.warn("SYSTEM","Worker is alive but readiness timed out \u2014 proceeding anyway"),u.info("SYSTEM","Worker already running and healthy"),a?"ready":"warming"}if(await za(t)){if(u.info("SYSTEM","Port in use, waiting for worker to become healthy"),await hr(t,dt(ne.PORT_IN_USE_WAIT))){let l=await Er(t,dt(ne.READINESS_WAIT));return u.info("SYSTEM","Worker is now healthy"),l?"ready":"warming"}u.warn("SYSTEM","Configured port in use but no healthy worker \u2014 spawning anyway (worker will pick a free ephemeral port)")}let s=Gs(),o=t;try{if(s){if(u.info("SYSTEM","Starting worker daemon",{workerScriptPath:e}),Xa(e,t)===void 0)return u.error("SYSTEM","Failed to spawn worker daemon"),"dead"}else u.info("SYSTEM","Another launcher holds the spawn lock \u2014 skipping duplicate spawn and waiting for its worker");let a=await vm(t,dt(ne.POST_SPAWN_WAIT));if(a===null)return u.warn("SYSTEM",s?"Worker spawned but health endpoint not responding within window \u2014 likely still starting in background":"Spawn-lock holder's worker not healthy within window \u2014 likely still starting in background"),"warming";o=a}finally{s&&Bs()}let i=await Er(o,dt(ne.READINESS_WAIT));return i||u.warn("SYSTEM","Worker is alive but readiness timed out \u2014 proceeding anyway"),Ya(),u.info("SYSTEM",s?"Worker started successfully":"Worker is up (started by another launcher)"),i?"ready":"warming"}var rl=b(()=>{"use strict";X();lr();gr();Ws();Hs()});function Ot(t){return t instanceof Error?t.message:typeof t=="string"?t:t&&typeof t=="object"&&"message"in t?String(t.message):String(t??"")}function nl(t,e){for(let r of Js)if(r.match(t,e))return r;return Js[Js.length-1]}var Cm,Rm,Js,fn=b(()=>{"use strict";Cm=t=>t.platform==="win32"?'Install Bun manually then re-run `npx keepmind install`. Windows: `winget install Oven-sh.Bun` (or `powershell -c "irm bun.sh/install.ps1 | iex"`).':"Install Bun manually then re-run `npx keepmind install`. macOS/Linux: `curl -fsSL https://bun.sh/install | bash` (or `brew install oven-sh/bun/bun`).",Rm=t=>t.platform==="win32"?'Install uv manually then re-run `npx keepmind install`. Windows: `winget install astral-sh.uv` (or `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`).':"Install uv manually then re-run `npx keepmind install`. macOS/Linux: `curl -LsSf https://astral.sh/uv/install.sh | sh` (or `brew install uv`).",Js=[{id:"bun-missing-after-install",severity:"ABORT",match:t=>{let e=Ot(t);return e.includes("Bun executable not found")||e.includes("Bun installation completed but binary not found")||e.includes("Failed to install Bun")},remediation:Cm},{id:"uv-missing-after-install",severity:"ABORT",match:t=>{let e=Ot(t);return e.includes("uv executable not found")||e.includes("uv installed but version probe failed")||e.includes("uv binary not found")||e.includes("Failed to install uv")},remediation:Rm},{id:"tree-sitter-eresolve",severity:"ABORT",match:t=>/\bERESOLVE\b/.test(Ot(t)),remediation:()=>"ERESOLVE peer-dependency conflict in marketplace deps that --legacy-peer-deps could not resolve. Open an issue at https://github.com/ManuelStaggl/keepmind/issues with the conflicting peer ranges shown above."},{id:"bun-install-network-fail",severity:"SILENT_RETRY",match:t=>/error: failed to resolve/.test(Ot(t)),remediation:()=>"bun install failed to resolve packages \u2014 check network connectivity and re-run `npx keepmind install`. Cached packages in ~/.bun/install/cache will be reused."},{id:"marketplace-dir-not-writable",severity:"ABORT",match:t=>/\b(EACCES|EPERM)\b/.test(Ot(t)),remediation:t=>`Cannot write to the claude-mem data/marketplace directory under ${t.dataDir}. Check filesystem permissions or set CLAUDE_MEM_DATA_DIR to a writable path, then re-run.`},{id:"plugin-json-corrupt",severity:"ABORT",match:(t,e)=>e.component==="plugin-json"&&/Unexpected token|JSON|parse/i.test(Ot(t)),remediation:()=>"Existing plugin.json is corrupt. Run `rm -rf ~/.claude/plugins/marketplaces/keepmind` and re-run `npx keepmind install`."},{id:"all-ides-failed",severity:"ABORT",match:(t,e)=>e.component==="all-ides",remediation:()=>"Every selected IDE integration failed. See the per-IDE errors above. Re-run with `--ide=<single>` to isolate the failure."},{id:"single-ide-failed",severity:"FAIL_LOUD_PER_IDE",match:(t,e)=>e.phase==="ide-install",remediation:()=>"Re-run `npx keepmind install --ide=<name>` to retry just this IDE. The captured stderr is shown above."},{id:"path-update-failed",severity:"WARN_CONTINUE",match:(t,e)=>e.component==="path-update",remediation:()=>"Could not auto-update PATH in your shell config. Add the printed export line manually and restart your shell."},{id:"auto-memory-toggle-failed",severity:"WARN_CONTINUE",match:(t,e)=>e.component==="auto-memory",remediation:()=>'Could not disable Claude Code auto-memory. Add `"CLAUDE_CODE_DISABLE_AUTO_MEMORY": "1"` to the env block in ~/.claude/settings.json.'},{id:"version-probe-transient",severity:"WARN_CONTINUE",match:(t,e)=>e.component.endsWith("-version-probe"),remediation:()=>"Could not verify the tool version after install \u2014 the installation is likely OK. Re-run `npx keepmind install` if features misbehave."},{id:"child-process-timeout",severity:"ABORT",match:t=>/timed out|ETIMEDOUT|SIGTERM|did not finish/i.test(Ot(t)),remediation:()=>"An install command did not finish in time. Check network connectivity. On a slow host, raise the budget with CLAUDE_MEM_INSTALL_TIMEOUT_MS and re-run."},{id:"unknown-install-error",severity:"ABORT",match:()=>!0,remediation:t=>`An unexpected installer error occurred. Capture ${t.dataDir}/last-install-error.json and open an issue at https://github.com/ManuelStaggl/keepmind/issues.`}]});import{mkdirSync as wm,writeFileSync as Im}from"fs";import{join as Om}from"path";function ol(){return{warnings:[],failedIDEs:[],retryCount:{}}}function Ut(t){return t instanceof Error?t.message:typeof t=="string"?t:String(t??"")}function km(t,e,r,n){try{wm(n,{recursive:!0});let s={severity:t.severity,categoryId:t.id,component:e.component,phase:e.phase,cause:Ut(e.cause),remediation:r,details:e.details??null,timestamp:new Date().toISOString()};Im(Om(n,"last-install-error.json"),JSON.stringify(s,null,2))}catch{}}function ce(t,e,r){let n=ut(),s=nl(e.cause,{component:e.component,phase:e.phase}),o=e.remediation??s.remediation({platform:process.platform,dataDir:n});switch(t){case"ABORT":throw km(s,e,o,n),new Sr(`${e.component} failed during ${e.phase}: ${Ut(e.cause)}`,{category:s,remediation:o,cause:e.cause});case"FAIL_LOUD_PER_IDE":{let i=e.ide??e.component;r.failedIDEs.includes(i)||r.failedIDEs.push(i),r.warnings.push({component:i,message:e.details?`${Ut(e.cause)}
|
|
101
|
+
${e.details}`:Ut(e.cause),remediation:o});return}case"WARN_CONTINUE":{r.warnings.push({component:e.component,message:Ut(e.cause),remediation:o});return}case"SILENT_RETRY":{let i=(r.retryCount[e.component]??0)+1;r.retryCount[e.component]=i,i>1&&r.warnings.push({component:e.component,message:Ut(e.cause),remediation:o});return}}}function Ks(t,e){if(t.warnings.length!==0){e(""),e("Warnings & remediation:");for(let r of t.warnings)e(` \u2022 [${r.component}] ${r.message}`),r.remediation&&r.remediation!=="No action required."&&e(` \u2192 ${r.remediation}`)}}var Sr,Xs=b(()=>{"use strict";fn();V();Sr=class extends Error{category;remediation;constructor(e,r){super(e,{cause:r.cause}),this.name="InstallAbortError",this.category=r.category,this.remediation=r.remediation}}});import{existsSync as pt,readFileSync as Ys,writeFileSync as _m}from"fs";import{exec as Nm,execSync as gn,spawnSync as hn}from"child_process";import{createRequire as Am}from"module";import{join as ke}from"path";import{homedir as Ft}from"os";function il(){return W?'Install Bun manually: `winget install Oven-sh.Bun` (or `powershell -c "irm bun.sh/install.ps1 | iex"`), then re-run `npx keepmind install`.':"Install Bun manually: `curl -fsSL https://bun.sh/install | bash` (or `brew install oven-sh/bun/bun`), then re-run `npx keepmind install`."}function al(){return W?'Install uv manually: `winget install astral-sh.uv` (or `powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`), then re-run `npx keepmind install`.':"Install uv manually: `curl -LsSf https://astral.sh/uv/install.sh | sh` (or `brew install uv`), then re-run `npx keepmind install`."}function ll(){try{if(!pt(Me))return!1;let t=JSON.parse(Ys(Me,"utf-8"));if(!t||typeof t!="object")return!1;let e=t,r=e.env&&typeof e.env=="object"?e.env:{},n=e.CLAUDE_MEM_DISABLE_VECTOR_SEARCH??r.CLAUDE_MEM_DISABLE_VECTOR_SEARCH;return n===!0||n==="true"||n==="1"}catch{return!1}}function pl(t){return ke(t,".install-version")}function qs(){try{if(hn("bun",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:W}).status===0)return"bun"}catch{}return ul.find(pt)||null}function ml(){return qs()!==null}function Vs(){let t=qs();if(!t)return null;try{let e=hn(t,["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:W});return e.status===0?e.stdout.trim():null}catch{return null}}function zs(){try{if(hn("uv",["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:W}).status===0)return"uv"}catch{}return dl.find(pt)||null}function fl(){return zs()!==null}function cl(){let t=zs();if(!t)return null;try{let e=hn(t,["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:W});return e.status===0?e.stdout.trim():null}catch{return null}}function Zs(t){if(t&&typeof t=="object"){let e=t,r=[];e.message&&r.push(e.message);let n=e.stderr?e.stderr.toString().trim():"";n&&r.push(`stderr: ${n}`);let s=e.stdout?e.stdout.toString().trim():"";return!n&&s&&r.push(`stdout: ${s}`),r.join(`
|
|
102
|
+
`)}return String(t)}function xm(){try{if(W?gn('powershell -c "irm bun.sh/install.ps1 | iex"',{stdio:"pipe",timeout:br,shell:process.env.ComSpec??"cmd.exe"}):gn("curl -fsSL https://bun.sh/install | bash",{stdio:"pipe",timeout:br,shell:"/bin/bash"}),!ml())throw new Error("Bun installation completed but binary not found. Please restart your terminal and try again.")}catch(t){let e=W?` - winget install Oven-sh.Bun
|
|
103
|
+
- Or: powershell -c "irm bun.sh/install.ps1 | iex"`:` - curl -fsSL https://bun.sh/install | bash
|
|
104
|
+
- Or: brew install oven-sh/bun/bun`;throw new Error(`Failed to install Bun. Please install manually:
|
|
105
|
+
${e}
|
|
106
|
+
Then restart your terminal and try again.
|
|
107
|
+
Underlying error: ${Zs(t)}`)}}function Lm(){try{if(W?gn('powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"',{stdio:"pipe",timeout:br,shell:process.env.ComSpec??"cmd.exe"}):gn("curl -LsSf https://astral.sh/uv/install.sh | sh",{stdio:"pipe",timeout:br,shell:"/bin/bash"}),!fl())throw new Error("uv installation completed but binary not found. Please restart your terminal and try again.")}catch(t){let e=W?` - winget install astral-sh.uv
|
|
108
|
+
- Or: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"`:` - curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
109
|
+
- Or: brew install uv (macOS)`;throw new Error(`Failed to install uv. Please install manually:
|
|
110
|
+
${e}
|
|
111
|
+
Then restart your terminal and try again.
|
|
112
|
+
Underlying error: ${Zs(t)}`)}}function Pm(t){let e=JSON.parse(Ys(ke(t,"package.json"),"utf-8")),r=Object.keys(e.dependencies||{}),n=ke(t,"node_modules"),s=Am(ke(n,"noop.js")),o=[n],i=[];for(let a of r)try{s.resolve(a,{paths:o})}catch{try{s.resolve(`${a}/package.json`,{paths:o})}catch{i.push(a)}}if(r.includes("zod"))for(let a of Dm)try{s.resolve(a,{paths:o})}catch{i.push(a)}if(i.length>0)throw new Error(`Post-install check failed: unresolvable modules: ${i.join(", ")}`)}function gl(t){return t??{warnings:[],failedIDEs:[],retryCount:{}}}async function jt(t){let e=gl(t);if(!ml())try{xm()}catch(s){ce("ABORT",{component:"bun-install",phase:"setup-runtime",cause:s,remediation:il()},e)}let r=qs();if(r||(r=ul.find(pt)??null),!r)throw ce("ABORT",{component:"bun-install",phase:"setup-runtime",cause:new Error("Bun executable not found after auto-install attempt"),remediation:il()},e),new Error("unreachable");let n=Vs();return n||(await new Promise(s=>setTimeout(s,1e3)),n=Vs()),n?{bunPath:r,version:n}:(ce("WARN_CONTINUE",{component:"bun-version-probe",phase:"setup-runtime",cause:new Error(`Bun at ${r} did not respond to --version after retry`)},e),{bunPath:r,version:"unknown"})}async function Qs(t,e={}){let r=gl(t);if(!fl())try{Lm()}catch(o){if(e.allowVectorSearchOptOut&&ll())return ce("WARN_CONTINUE",{component:"uv-install",phase:"setup-runtime",cause:o},r),{uvPath:"",version:"unknown"};ce("ABORT",{component:"uv-install",phase:"setup-runtime",cause:o,remediation:al()},r)}let n=zs();if(n||(n=dl.find(pt)??null),!n){if(e.allowVectorSearchOptOut&&ll())return ce("WARN_CONTINUE",{component:"uv-install",phase:"setup-runtime",cause:new Error("uv binary not found after install; vector search disabled \u2014 continuing.")},r),{uvPath:"",version:"unknown"};throw ce("ABORT",{component:"uv-install",phase:"setup-runtime",cause:new Error("uv binary not found after auto-install attempt"),remediation:al()},r),new Error("unreachable")}let s=cl();return s||(await new Promise(o=>setTimeout(o,1e3)),s=cl()),s?{uvPath:n,version:s}:(ce("WARN_CONTINUE",{component:"uv-version-probe",phase:"setup-runtime",cause:new Error(`uv at ${n} did not respond to --version after retry`)},r),{uvPath:n,version:"unknown"})}async function En(t,e){if(!pt(ke(t,"package.json")))throw new Error(`installPluginDependencies: no package.json at ${t}`);let r=W&&e.includes(" ")?`"${e}"`:e;try{await new Promise((n,s)=>{Nm(`${r} install --frozen-lockfile --ignore-scripts`,{cwd:t,timeout:br,maxBuffer:16*1024*1024,...W?{shell:process.env.ComSpec??"cmd.exe"}:{}},(o,i,a)=>o?s(Object.assign(o,{stdout:i,stderr:a})):n())})}catch(n){throw new Error(`bun install failed in ${t}
|
|
113
|
+
${Zs(n)}`)}Pm(t)}function Um(t){let e=pl(t);if(!pt(e))return null;let r=Ys(e,"utf-8");try{let s=JSON.parse(r);if(s&&typeof s=="object"&&typeof s.version=="string")return s}catch{}let n=r.trim();return Mm.test(n)?{version:n.replace(/^v/i,"")}:null}function $s(t,e,r,n){let s={version:e,bun:r,uv:n,installedAt:new Date().toISOString()};_m(pl(t),JSON.stringify(s))}function hl(t,e){if(!pt(ke(t,"node_modules")))return!1;let r=Um(t);if(!r||r.version!==e)return!1;let n=Vs();return!(n&&!r.bun||!n&&r.bun||n&&r.bun&&n!==r.bun)}var br,ul,dl,Mm,Dm,El=b(()=>{"use strict";fn();Xs();V();Ae();br=(()=>{let t=process.env.CLAUDE_MEM_INSTALL_TIMEOUT_MS;return t&&Number.isFinite(Number(t))?Number(t):300*1e3})();ul=W?[ke(Ft(),".bun","bin","bun.exe")]:[ke(Ft(),".bun","bin","bun"),"/usr/local/bin/bun","/opt/homebrew/bin/bun"],dl=W?[ke(Ft(),".local","bin","uv.exe"),ke(Ft(),".cargo","bin","uv.exe")]:[ke(Ft(),".local","bin","uv"),ke(Ft(),".cargo","bin","uv"),"/usr/local/bin/uv","/opt/homebrew/bin/uv"],Mm=/^v?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;Dm=["zod/v3","zod/v4","zod/v4-mini"]});var mt,Sl=b(()=>{"use strict";mt={compressed:"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",frameCount:192,width:128,height:36,frameDelay:22}});import{inflateRawSync as Fm}from"zlib";function Hm(t,e=1){if(!t)return"\x1B[38;5;208m";let r=Math.min(255,Math.round(230*e)),n=Math.min(255,Math.round(115*e)),s=Math.min(255,Math.round(70*e));return`\x1B[38;2;${r};${n};${s}m`}function Jm(t,e=1){if(!t)return"\x1B[38;5;215m";let r=Math.min(255,Math.round(255*e)),n=Math.min(255,Math.round(180*e)),s=Math.min(255,Math.round(122*e));return`\x1B[38;2;${r};${n};${s}m`}function Km(){if(yr)return yr;try{yr=Fm(Buffer.from(mt.compressed,"base64")).toString("utf8").split(Bm).filter(Boolean)}catch{yr=[]}return yr}function Xm(t,e,r=1){let n=Hm(e,r),s=Jm(e,r),o=n,i=0,a=!1;for(;i<t.length;){let l=t[i];if(l==="<"){let c=t[i+1]==="/";for(;i<t.length&&t[i]!==">";)i++;i++,a=!c,o+=a?s:n;continue}o+=l,i++}return o+yl}function Vm(){return process.env.COLORTERM==="truecolor"||process.env.COLORTERM==="24bit"}function Ym(t,e){let r=eo[t],n=mt.width,s=r.slice(0,Math.min(kt,e)).padEnd(kt," "),o=Math.max(0,Math.floor((n-kt)/2));return" ".repeat(o)+`\x1B[1;97m${s}\x1B[0m`+" ".repeat(Math.max(0,n-o-kt))}function qm(t){let e=mt.width,r=Math.max(0,Math.floor((e-t.length)/2));return" ".repeat(r)+`\x1B[2;37m${t}\x1B[0m`+" ".repeat(Math.max(0,e-r-t.length))}function zm(){return!process.stdout.isTTY||process.env.CI||process.env.CLAUDE_MEM_NO_BANNER||process.env.NO_COLOR?!1:(process.stdout.columns??0)>=mt.width}async function Cl(){if(!zm())return;let t=Vm(),e=Km();if(e.length===0)return;let r=!1,n=()=>{r=!0};process.stdout.on("resize",n),process.stdout.write(Gm),process.stdout.write(jm),process.stdout.write(`
|
|
114
|
+
`.repeat(bl)),process.stdout.write(`\x1B[${bl}A`),process.stdout.write("\x1B[s");let s=" ".repeat(mt.width),o=(i,a,l,c=1)=>{process.stdout.write("\x1B[u"),process.stdout.write(Xm(i,t,c)),process.stdout.write(`
|
|
115
|
+
`);for(let d=0;d<Tl;d++)process.stdout.write(Ym(d,a)),process.stdout.write(`
|
|
116
|
+
`);for(let d=0;d<vl;d++)process.stdout.write(s),process.stdout.write(`
|
|
117
|
+
`);process.stdout.write(qm(l))};try{for(let c=0;c<e.length;c++){if(r)return;o(e[c],0,""),await Tr(mt.frameDelay)}let i=e[e.length-1],a="persistent memory across sessions",l=14;for(let c=1;c<=l;c++){if(r)return;let d=Math.ceil(kt*(c/l));o(i,d,""),await Tr(45)}for(let c=1;c<=6;c++){if(r)return;let d=Math.ceil(a.length*(c/6));o(i,kt,a.slice(0,d)),await Tr(33)}for(let c of[.85,.95,1]){if(r)return;o(i,kt,a,c),await Tr(100)}await Tr(150)}finally{process.stdout.off("resize",n),process.stdout.write(yl),process.stdout.write(Wm),process.stdout.write(`
|
|
118
|
+
`)}}var jm,Wm,Gm,yl,Bm,yr,eo,Tl,kt,vl,bl,Tr,Rl=b(()=>{"use strict";Sl();jm="\x1B[?25l",Wm="\x1B[?25h",Gm="\x1B[2J\x1B[3J\x1B[H",yl="\x1B[0m",Bm="";yr=null;eo=[" _ _ "," ___| | __ _ _ _ __| | ___ _ __ ___ ___ _ __ ___ "," / __| |/ _` | | | |/ _` |/ _ \\_____| '_ ` _ \\ / _ \\ '_ ` _ \\ ","| (__| | (_| | |_| | (_| | __/_____| | | | | | __/ | | | | |"," \\___|_|\\__,_|\\__,_|\\__,_|\\___| |_| |_| |_|\\___|_| |_| |_|"],Tl=eo.length,kt=eo[0].length,vl=1,bl=mt.height+Tl+vl+1;Tr=t=>new Promise(e=>setTimeout(e,t))});import{spawn as Zm}from"child_process";function ef(t){let e=process.env.CLAUDE_MEM_INSTALL_TIMEOUT_MS;return e&&Number.isFinite(Number(e))?Number(e):t?Qm:$m}function wl(t){return/\bERESOLVE\b/.test(t)||/code ERESOLVE/.test(t)}function Il(t){let e=t.search(/While resolving:/);return e===-1?t.trim():t.slice(e).trim()}function to(t,e,r=!0){return new Promise(n=>{let s=Zm("npm",e,{cwd:t,stdio:["ignore","pipe","pipe"],...W?{shell:process.env.ComSpec??"cmd.exe"}:{}}),o="",i="",a=!1,l=null,c=setTimeout(()=>{a=!0,s.kill("SIGTERM")},ef(r));s.stdout?.on("data",f=>{o+=f.toString()}),s.stderr?.on("data",f=>{i+=f.toString()});let d=!1,m=f=>{d||(d=!0,clearTimeout(c),n({code:typeof f=="number"?f:a?124:1,stdout:o,stderr:i||(l?String(l.message):""),timedOut:a}))};s.on("error",f=>{l=f,m(null)}),s.on("close",f=>{m(f)})})}var Qm,$m,Ol=b(()=>{"use strict";Ae();Qm=300*1e3,$m=120*1e3});async function Sn(t,e=1e4){let r=`http://127.0.0.1:${t}`,n=!1;try{await fetch(`${r}/api/admin/shutdown`,{method:"POST",signal:AbortSignal.timeout(5e3)}),n=!0}catch{return{workerWasRunning:!1}}let s=500,o=Math.ceil(e/s);for(let i=0;i<o;i++){await new Promise(a=>setTimeout(a,s));try{await fetch(`${r}/api/health`,{signal:AbortSignal.timeout(1e3)})}catch(a){if(a instanceof Error&&a.name==="AbortError")continue;return{workerWasRunning:n}}}return{workerWasRunning:n}}var ro=b(()=>{"use strict"});import{execSync as tf}from"child_process";import{existsSync as Fe,readdirSync as rf}from"fs";import{homedir as kl}from"os";import{join as je}from"path";function vr(t){try{return tf(`${W?"where":"which"} ${t}`,{stdio:"pipe"}),!0}catch(e){return process.env.DEBUG&&console.error(`[ide-detection] ${t} not in PATH:`,e instanceof Error?e.message:String(e)),!1}}function nf(t){let e=je(kl(),".vscode","extensions");if(!Fe(e))return!1;try{return rf(e).some(n=>n.toLowerCase().includes(t.toLowerCase()))}catch(r){return console.warn("[ide-detection] Failed to read VS Code extensions directory:",r instanceof Error?r.message:String(r)),!1}}function Wt(){let t=kl();return[{id:"claude-code",label:"Claude Code",detected:vr("claude"),supported:!0,hint:"recommended"},{id:"gemini-cli",label:"Gemini CLI",detected:Fe(je(t,".gemini")),supported:!0},{id:"opencode",label:"OpenCode",detected:Fe(je(t,".config","opencode"))||vr("opencode"),supported:!0,hint:"plugin-based integration"},{id:"openclaw",label:"OpenClaw",detected:Fe(je(t,".openclaw")),supported:!0,hint:"plugin-based integration"},{id:"windsurf",label:"Windsurf",detected:Fe(je(t,".codeium","windsurf")),supported:!0},{id:"codex-cli",label:"Codex CLI",detected:Fe(je(t,".codex")),supported:!0,hint:"native hooks integration"},{id:"cursor",label:"Cursor",detected:Fe(je(t,".cursor")),supported:!0,hint:"hooks + MCP integration"},{id:"copilot-cli",label:"Copilot CLI",detected:vr("copilot"),supported:!0,hint:"MCP-based integration"},{id:"antigravity",label:"Antigravity",detected:Fe(je(t,".gemini","antigravity")),supported:!0,hint:"MCP-based integration"},{id:"goose",label:"Goose",detected:Fe(je(t,".config","goose"))||vr("goose"),supported:!0,hint:"MCP-based integration"},{id:"roo-code",label:"Roo Code",detected:nf("roo-code"),supported:!0,hint:"MCP-based integration"},{id:"warp",label:"Warp",detected:Fe(je(t,".warp"))||vr("warp"),supported:!0,hint:"MCP-based integration"}]}var _l=b(()=>{"use strict";Ae()});var Nl=b(()=>{"use strict";lt();V()});var Al=b(()=>{"use strict";X();dn()});var Ml=b(()=>{"use strict";gr();Ws();Al()});import sf from"path";import{readFileSync as of,existsSync as af,writeFileSync as YT,renameSync as qT,mkdirSync as zT}from"fs";function no(t,e,r){let n=process.env[t];if(n){let s=parseInt(n,10);if(Number.isFinite(s)&&s>=r.min&&s<=r.max)return s;u.warn("SYSTEM",`Invalid ${t}, using default`,{value:n,min:r.min,max:r.max})}return e}async function cf(t,e={},r){try{return await fetch(t,{...e,signal:AbortSignal.timeout(r)})}catch(n){throw n instanceof DOMException&&n.name==="TimeoutError"?new Error(`Request timed out after ${r}ms`):n}}function uf(){return sf.join(le.get("CLAUDE_MEM_DATA_DIR"),"settings.json")}function df(t){if(!Number.isInteger(t)||t<=0)return!1;try{return process.kill(t,0),!0}catch(e){return e?.code==="EPERM"}}function pf(){try{let t=j.workerPid();if(!af(t))return null;let e=JSON.parse(of(t,"utf-8"));return typeof e.pid!="number"||typeof e.port!="number"||!df(e.pid)?null:e.port}catch{return null}}function so(){return Tn!==null||(Tn=le.loadFromFile(uf())),Tn}function xl(t,e){if(!t)return null;let r=parseInt(t,10);return Number.isFinite(r)&&r>=e.min&&r<=e.max?r:null}function mf(t,e,r){let n=process.env[t];if(n!==void 0){let i=xl(n,r);return i!==null?i:(u.warn("SYSTEM",`Invalid ${t}, using default`,{value:n,min:r.min,max:r.max}),e)}let s=so()[t],o=xl(s,r);return o!==null?o:(u.warn("SYSTEM",`Invalid ${t} in settings.json, using default`,{value:s,min:r.min,max:r.max}),e)}function ff(){if(bn!==null)return bn;let t=so();return bn=parseInt(t.CLAUDE_MEM_WORKER_PORT,10),bn}function Cr(){let t=pf();return t!==null?t:ff()}function gf(){return yn!==null||(yn=so().CLAUDE_MEM_WORKER_HOST),yn}function hf(){return vn!==null||(vn=mf("CLAUDE_MEM_API_TIMEOUT_MS",wt(ne.API_REQUEST),lf)),vn}function Ef(t){return`http://${gf()}:${Cr()}${t}`}function Cn(t,e={}){let r=e.method??"GET",n=e.timeoutMs??hf(),s=Ef(t),o={method:r};return e.headers&&(o.headers=e.headers),e.body&&(o.body=e.body),n>0?cf(s,o,n):fetch(s,o)}var lv,cv,uv,lf,bn,yn,Tn,vn,Rn=b(()=>{"use strict";Lt();X();lr();lt();V();Nl();dn();ws();Ml();gr();Hs();lv=no("CLAUDE_MEM_HEALTH_TIMEOUT_MS",wt(ne.HEALTH_CHECK),{min:500,max:3e5}),cv=no("CLAUDE_MEM_API_TIMEOUT_MS",wt(ne.API_REQUEST),{min:500,max:3e5}),uv=no("CLAUDE_MEM_HOOK_READINESS_TIMEOUT_MS",wt(ne.HOOK_READINESS_WAIT),{min:0,max:3e5}),lf={min:500,max:3e5};bn=null,yn=null,Tn=null,vn=null});function wn(t){if(!t)return t;let e="";for(let r of t){let n=r.codePointAt(0);if(!(n>=55296&&n<=57343)){if(n<=65535){e+=r;continue}e+=Sf[r]??bf}}return e}var Sf,bf,oo=b(()=>{"use strict";Sf={"\u{1F534}":"\u25CF","\u{1F7E3}":"\u25C6","\u{1F504}":"\u21BB","\u{1F535}":"\u25CB","\u{1F6A8}":"\u26A0","\u{1F510}":"\u26B7","\u{1F6E0}":"\u2692","\u{1F50D}":"\u2315","\u{1F3AF}":"\u25CE","\u{1F4AC}":"\u201D","\u{1F9E0}":"\u25C8"},bf="\u2022"});import{existsSync as yf,readFileSync as Tf,writeFileSync as Ll,mkdirSync as Dl,renameSync as vf}from"fs";import{join as io}from"path";function Pl(t){try{return yf(t)?JSON.parse(Tf(t,"utf-8")):{}}catch(e){return u.error("CONFIG","Failed to read Cursor registry, using empty registry",{file:t,error:e instanceof Error?e.message:String(e)}),{}}}function Ul(t,e){let r=io(t,"..");Dl(r,{recursive:!0}),Ll(t,JSON.stringify(e,null,2))}function ao(t,e){let r=io(t,".cursor","rules"),n=io(r,"claude-mem-context.mdc"),s=`${n}.tmp`;Dl(r,{recursive:!0});let o=`---
|
|
119
|
+
alwaysApply: true
|
|
120
|
+
description: "Claude-mem context from past sessions (auto-updated)"
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
# Memory Context from Past Sessions
|
|
124
|
+
|
|
125
|
+
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
|
126
|
+
|
|
127
|
+
${wn(e)}
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
*Updated after last session. Use claude-mem's MCP search tools for more detailed queries.*
|
|
131
|
+
`;Ll(s,o),vf(s,n)}var Fl=b(()=>{"use strict";X();oo()});import Ye from"path";import{homedir as jl}from"os";import{existsSync as Wl}from"fs";function Gl(t){for(let e of t)if(e&&Wl(e))return e;return null}function Cf(){let t=[process.env.CLAUDE_PLUGIN_ROOT,process.env.PLUGIN_ROOT,Ye.join(ur,"plugin"),Ye.join(process.cwd(),"plugin"),process.cwd()].filter(e=>!!e);for(let e of t)if(Wl(Ye.join(e,"scripts")))return e;return null}function Bl(t){let e=Cf(),r=[e?Ye.join(e,"scripts",t):"",Ye.join(ur,"plugin","scripts",t),Ye.join(process.cwd(),"plugin","scripts",t)];return Gl(r)}function Rr(){return Bl("mcp-server.cjs")}function Gt(){return Bl("worker-service.cjs")}function Bt(){let t=[Ye.join(jl(),".bun","bin","bun"),"/usr/local/bin/bun","/usr/bin/bun",...process.platform==="win32"?[Ye.join(jl(),".bun","bin","bun.exe"),Ye.join(process.env.LOCALAPPDATA||"","bun","bun.exe")]:[]];return Gl(t)??"bun"}function lo(){return process.execPath}var wr=b(()=>{"use strict";V()});var ec={};de(ec,{checkCursorHooksStatus:()=>$l,configureCursorMcp:()=>wf,findBunPath:()=>zl,findMcpServerPath:()=>Yl,findWorkerServicePath:()=>ql,getTargetDir:()=>On,handleCursorCommand:()=>Nf,installCursorHooks:()=>Zl,readCursorRegistry:()=>In,registerCursorProject:()=>Xl,uninstallCursorHooks:()=>Ql,unregisterCursorProject:()=>Vl,updateCursorContextForProject:()=>Rf,writeCursorRegistry:()=>mo});import q from"path";import{homedir as Hl}from"os";import{existsSync as ft,readFileSync as Jl,writeFileSync as uo,unlinkSync as co,mkdirSync as po}from"fs";function In(){return Pl(Kl)}function mo(t){Ul(Kl,t)}function Xl(t,e){let r=In();r[t]={workspacePath:e,installedAt:new Date().toISOString()},mo(r),u.info("CURSOR","Registered project for auto-context updates",{projectName:t,workspacePath:e})}function Vl(t){let e=In();e[t]&&(delete e[t],mo(e),u.info("CURSOR","Unregistered project",{projectName:t}))}async function Rf(t,e){let n=In()[t];if(n)try{let s=await Cn(`/api/context/inject?project=${encodeURIComponent(t)}`);if(!s.ok)return;let o=await s.text();if(!o||!o.trim())return;ao(n.workspacePath,o),u.debug("CURSOR","Updated context file",{projectName:t,workspacePath:n.workspacePath})}catch(s){s instanceof Error?u.error("WORKER","Failed to update context file",{projectName:t},s):u.error("WORKER","Failed to update context file",{projectName:t},new Error(String(s)))}}function Yl(){return Rr()}function ql(){return Gt()}function zl(){return Bt()}function On(t){switch(t){case"project":return q.join(process.cwd(),".cursor");case"user":return q.join(Hl(),".cursor");case"enterprise":return process.platform==="darwin"?"/Library/Application Support/Cursor":process.platform==="linux"?"/etc/cursor":process.platform==="win32"?q.join(process.env.ProgramData||"C:\\ProgramData","Cursor"):null;default:return null}}function wf(t){let e=Yl();if(!e)return console.error("Could not find MCP server script"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/mcp-server.cjs"),1;let r=On(t);if(!r)return console.error(`Invalid target: ${t}. Use: project or user`),1;let n=q.join(r,"mcp.json");try{po(r,{recursive:!0});let s={mcpServers:{}};if(ft(n))try{s=JSON.parse(Jl(n,"utf-8")),s.mcpServers||(s.mcpServers={})}catch(o){o instanceof Error?u.error("WORKER","Corrupt mcp.json, creating new config",{path:n},o):u.error("WORKER","Corrupt mcp.json, creating new config",{path:n},new Error(String(o))),s={mcpServers:{}}}return s.mcpServers["claude-mem"]={command:"node",args:[e]},uo(n,JSON.stringify(s,null,2)),console.log(` Configured MCP server in ${t==="user"?"~/.cursor":".cursor"}/mcp.json`),console.log(` Server path: ${e}`),0}catch(s){return console.error(`Failed to configure MCP: ${s.message}`),1}}async function Zl(t){console.log(`
|
|
132
|
+
Installing Claude-Mem Cursor hooks (${t} level)...
|
|
133
|
+
`);let e=On(t);if(!e)return console.error(`Invalid target: ${t}. Use: project, user, or enterprise`),1;let r=ql();if(!r)return console.error("Could not find worker-service.cjs"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/worker-service.cjs"),1;let n=process.cwd(),s=q.join(e,"hooks.json"),o=zl(),i=o.replace(/\\/g,"\\\\"),a=r.replace(/\\/g,"\\\\"),l=d=>`"${i}" "${a}" hook cursor ${d}`;console.log(` Using Bun runtime: ${o}`);let c={version:1,hooks:{beforeSubmitPrompt:[{command:l("session-init")},{command:l("context")}],afterMCPExecution:[{command:l("observation")}],afterShellExecution:[{command:l("observation")}],afterFileEdit:[{command:l("file-edit")}],stop:[{command:l("summarize")}]}};try{return po(e,{recursive:!0}),await If(s,c,r,t,e,n),0}catch(d){let m=d instanceof Error?d.message:String(d);return console.error(`
|
|
134
|
+
Installation failed: ${m}`),t==="enterprise"&&console.error(" Tip: Enterprise installation may require sudo/admin privileges"),1}}async function If(t,e,r,n,s,o){uo(t,JSON.stringify(e,null,2)),console.log(" Created hooks.json (unified CLI mode)"),console.log(` Worker service: ${r}`),n==="project"&&await Of(s,o),console.log(`
|
|
135
|
+
Installation complete!
|
|
136
|
+
|
|
137
|
+
Hooks installed to: ${s}/hooks.json
|
|
138
|
+
Using unified CLI: bun worker-service.cjs hook cursor <command>
|
|
139
|
+
|
|
140
|
+
Next steps:
|
|
141
|
+
1. Start keepmind worker: keepmind start
|
|
142
|
+
2. Restart Cursor to load the hooks
|
|
143
|
+
3. Check Cursor Settings \u2192 Hooks tab to verify
|
|
144
|
+
|
|
145
|
+
Context Injection:
|
|
146
|
+
Context from past sessions is stored in .cursor/rules/claude-mem-context.mdc
|
|
147
|
+
and automatically included in every chat. It updates after each session ends.
|
|
148
|
+
`)}async function Of(t,e){let r=q.join(t,"rules");po(r,{recursive:!0});let n=q.basename(e),s=!1;console.log(" Generating initial context...");try{s=await kf(n,e)}catch(o){o instanceof Error?u.debug("WORKER","Worker not running during install",{},o):u.debug("WORKER","Worker not running during install",{},new Error(String(o)))}if(!s){let o=q.join(r,"claude-mem-context.mdc");uo(o,`---
|
|
149
|
+
alwaysApply: true
|
|
150
|
+
description: "Claude-mem context from past sessions (auto-updated)"
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
# Memory Context from Past Sessions
|
|
154
|
+
|
|
155
|
+
*No context yet. Complete your first session and context will appear here.*
|
|
156
|
+
|
|
157
|
+
Use claude-mem's MCP search tools for manual memory queries.
|
|
158
|
+
`),console.log(" Created placeholder context file (will populate after first session)")}Xl(n,e),console.log(" Registered for auto-context updates")}async function kf(t,e){if(!(await Cn("/api/readiness")).ok)return!1;let n=await Cn(`/api/context/inject?project=${encodeURIComponent(t)}`);if(!n.ok)return!1;let s=await n.text();return s&&s.trim()?(ao(e,s),console.log(" Generated initial context from existing memory"),!0):!1}function Ql(t){console.log(`
|
|
159
|
+
Uninstalling Claude-Mem Cursor hooks (${t} level)...
|
|
160
|
+
`);let e=On(t);if(!e)return console.error(`Invalid target: ${t}`),1;let r=q.join(e,"hooks"),n=q.join(e,"hooks.json"),s=["common.sh","session-init.sh","context-inject.sh","save-observation.sh","save-file-edit.sh","session-summary.sh"],o=["common.ps1","session-init.ps1","context-inject.ps1","save-observation.ps1","save-file-edit.ps1","session-summary.ps1"],i=[...s,...o];try{return _f(r,i,n,t,e),0}catch(a){let l=a instanceof Error?a.message:String(a);return console.error(`
|
|
161
|
+
Uninstallation failed: ${l}`),1}}function _f(t,e,r,n,s){for(let o of e){let i=q.join(t,o);ft(i)&&(co(i),console.log(` Removed legacy script: ${o}`))}if(ft(r)&&(co(r),console.log(" Removed hooks.json")),n==="project"){let o=q.join(s,"rules","claude-mem-context.mdc");ft(o)&&(co(o),console.log(" Removed context file"));let i=q.basename(process.cwd());Vl(i),console.log(" Unregistered from auto-context updates")}console.log(`
|
|
162
|
+
Uninstallation complete!
|
|
163
|
+
`),console.log("Restart Cursor to apply changes.")}function $l(){console.log(`
|
|
164
|
+
Claude-Mem Cursor Hooks Status
|
|
165
|
+
`);let t=[{name:"Project",dir:q.join(process.cwd(),".cursor")},{name:"User",dir:q.join(Hl(),".cursor")}];process.platform==="darwin"?t.push({name:"Enterprise",dir:"/Library/Application Support/Cursor"}):process.platform==="linux"&&t.push({name:"Enterprise",dir:"/etc/cursor"});let e=!1;for(let r of t){let n=q.join(r.dir,"hooks.json"),s=q.join(r.dir,"hooks");if(ft(n)){e=!0,console.log(`${r.name}: Installed`),console.log(` Config: ${n}`);let o=null;try{o=JSON.parse(Jl(n,"utf-8"))}catch(i){i instanceof Error?u.error("WORKER","Unable to parse hooks.json",{path:n},i):u.error("WORKER","Unable to parse hooks.json",{path:n},new Error(String(i))),console.log(" Mode: Unable to parse hooks.json")}if(o){let i=o?.hooks?.beforeSubmitPrompt?.[0]?.command||"";if(i.includes("worker-service.cjs")&&i.includes("hook cursor"))console.log(" Mode: Unified CLI (bun worker-service.cjs)");else{let a=["session-init.sh","context-inject.sh","save-observation.sh"],l=["session-init.ps1","context-inject.ps1","save-observation.ps1"],c=a.some(m=>ft(q.join(s,m))),d=l.some(m=>ft(q.join(s,m)));c||d?(console.log(" Mode: Legacy shell scripts (consider reinstalling for unified CLI)"),c&&d?console.log(" Platform: Both (bash + PowerShell)"):c?console.log(" Platform: Unix (bash)"):d&&console.log(" Platform: Windows (PowerShell)")):console.log(" Mode: Unknown configuration")}}if(r.name==="Project"){let i=q.join(r.dir,"rules","claude-mem-context.mdc");ft(i)?console.log(" Context: Active"):console.log(" Context: Not yet generated (will be created on first prompt)")}}else console.log(`${r.name}: Not installed`);console.log("")}return e||console.log(`No hooks installed. Run: claude-mem cursor install
|
|
166
|
+
`),0}async function Nf(t,e){switch(t){case"install":{let r=e[0]||"project";return Zl(r)}case"uninstall":{let r=e[0]||"project";return Ql(r)}case"status":return $l();case"setup":return console.log("Use the main entry point for setup"),0;default:return console.log(`
|
|
167
|
+
Claude-Mem Cursor Integration
|
|
168
|
+
|
|
169
|
+
Usage: claude-mem cursor <command> [options]
|
|
170
|
+
|
|
171
|
+
Commands:
|
|
172
|
+
setup Interactive guided setup (recommended for first-time users)
|
|
173
|
+
|
|
174
|
+
install [target] Install Cursor hooks
|
|
175
|
+
target: project (default), user, or enterprise
|
|
176
|
+
|
|
177
|
+
uninstall [target] Remove Cursor hooks
|
|
178
|
+
target: project (default), user, or enterprise
|
|
179
|
+
|
|
180
|
+
status Check installation status
|
|
181
|
+
|
|
182
|
+
Examples:
|
|
183
|
+
npm run cursor:setup # Interactive wizard (recommended)
|
|
184
|
+
npm run cursor:install # Install for current project
|
|
185
|
+
claude-mem cursor install user # Install globally for user
|
|
186
|
+
claude-mem cursor uninstall # Remove from current project
|
|
187
|
+
claude-mem cursor status # Check if hooks are installed
|
|
188
|
+
|
|
189
|
+
For more info: https://docs.claude-mem.ai/cursor
|
|
190
|
+
`),0}}var Kl,tc=b(()=>{"use strict";X();Rn();V();Fl();wr();Kl=q.join(M,"cursor-projects.json")});var Eo={};de(Eo,{checkGeminiCliHooksStatus:()=>ic,handleGeminiCliCommand:()=>jf,installGeminiCliHooks:()=>sc,uninstallGeminiCliHooks:()=>oc});import fo from"path";import{homedir as Af}from"os";import{existsSync as Ht,readFileSync as kn,writeFileSync as go,mkdirSync as rc}from"fs";function xf(t,e,r){let n=Jt[r];if(!n)throw new Error(`Unknown Gemini CLI event: ${r}`);let s=t.replace(/\\/g,"\\\\"),o=e.replace(/\\/g,"\\\\");return`"${s}" "${o}" hook gemini-cli ${n}`}function Lf(t){return{matcher:"*",hooks:[{name:Ir,type:"command",command:t,timeout:Mf}]}}function ho(){if(!Ht(me))return{};let t=kn(me,"utf-8");try{return JSON.parse(t)}catch(e){throw e instanceof Error?u.error("WORKER","Corrupt JSON in Gemini settings",{path:me},e):u.error("WORKER","Corrupt JSON in Gemini settings",{path:me},new Error(String(e))),new Error(`Corrupt JSON in ${me}, refusing to overwrite user settings`)}}function nc(t){rc(_n,{recursive:!0}),go(me,JSON.stringify(t,null,2)+`
|
|
191
|
+
`)}function Df(t,e){let r={...t};r.hooks||(r.hooks={});for(let[n,s]of Object.entries(e)){let o=r.hooks[n]??[];for(let i of s){let a=o.findIndex(l=>l.hooks.some(c=>c.name===Ir));if(a>=0){let l=o[a],c=l.hooks.findIndex(d=>d.name===Ir);c>=0?l.hooks[c]=i.hooks[0]:l.hooks.push(i.hooks[0])}else o.push(i)}r.hooks[n]=o}return r}function Pf(){let t="<claude-mem-context>",r=`${t}
|
|
192
|
+
# Memory Context from Past Sessions
|
|
193
|
+
|
|
194
|
+
*No context yet. Complete your first session and context will appear here.*
|
|
195
|
+
</claude-mem-context>`,n="";if(Ht(xe)&&(n=kn(xe,"utf-8")),n.includes(t))return;let s=n.length>0&&!n.endsWith(`
|
|
196
|
+
`)?`
|
|
197
|
+
|
|
198
|
+
`:n.length>0?`
|
|
199
|
+
`:"",o=n+s+r+`
|
|
200
|
+
`;rc(_n,{recursive:!0}),go(xe,o)}async function sc(){console.log(`
|
|
201
|
+
Installing Claude-Mem Gemini CLI hooks...
|
|
202
|
+
`);let t=Gt();if(!t)return console.error("Could not find worker-service.cjs"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/worker-service.cjs"),1;let e=Bt();console.log(` Using Bun runtime: ${e}`),console.log(` Worker service: ${t}`);try{let r={};for(let o of Object.keys(Jt)){let i=xf(e,t,o);r[o]=[Lf(i)]}let n=ho(),s=Df(n,r);return Uf(s),0}catch(r){let n=r instanceof Error?r.message:String(r);return console.error(`
|
|
203
|
+
Installation failed: ${n}`),1}}function Uf(t){nc(t),console.log(` Merged hooks into ${me}`),Pf(),console.log(` Setup context injection in ${xe}`);let e=Object.keys(Jt);console.log(` Registered ${e.length} hook events:`);for(let r of e){let n=Jt[r];console.log(` ${r} \u2192 ${n}`)}console.log(`
|
|
204
|
+
Installation complete!
|
|
205
|
+
|
|
206
|
+
Hooks installed to: ${me}
|
|
207
|
+
Using unified CLI: bun worker-service.cjs hook gemini-cli <event>
|
|
208
|
+
|
|
209
|
+
Next steps:
|
|
210
|
+
1. Start keepmind worker: keepmind start
|
|
211
|
+
2. Restart Gemini CLI to load the hooks
|
|
212
|
+
3. Memory will be captured automatically during sessions
|
|
213
|
+
|
|
214
|
+
Context Injection:
|
|
215
|
+
Context from past sessions is injected via ~/.gemini/GEMINI.md
|
|
216
|
+
and automatically included in Gemini CLI conversations.
|
|
217
|
+
`)}function oc(){if(console.log(`
|
|
218
|
+
Uninstalling Claude-Mem Gemini CLI hooks...
|
|
219
|
+
`),!Ht(me))return console.log(" No Gemini CLI settings found \u2014 nothing to uninstall."),0;try{let t=ho();if(!t.hooks)return console.log(" No hooks found in Gemini CLI settings \u2014 nothing to uninstall."),0;let e=0;for(let[r,n]of Object.entries(t.hooks)){let s=n.map(o=>{let i=o.hooks.filter(a=>a.name!==Ir);return e+=o.hooks.length-i.length,{...o,hooks:i}}).filter(o=>o.hooks.length>0);s.length>0?t.hooks[r]=s:delete t.hooks[r]}return Object.keys(t.hooks).length===0&&delete t.hooks,Ff(t,e),0}catch(t){let e=t instanceof Error?t.message:String(t);return console.error(`
|
|
220
|
+
Uninstallation failed: ${e}`),1}}function Ff(t,e){if(nc(t),console.log(` Removed ${e} claude-mem hook(s) from ${me}`),Ht(xe)){let r=kn(xe,"utf-8"),n=/\n?<claude-mem-context>[\s\S]*?<\/claude-mem-context>\n?/;n.test(r)&&(r=r.replace(n,""),go(xe,r),console.log(` Removed context section from ${xe}`))}console.log(`
|
|
221
|
+
Uninstallation complete!
|
|
222
|
+
`),console.log("Restart Gemini CLI to apply changes.")}function ic(){if(console.log(`
|
|
223
|
+
Claude-Mem Gemini CLI Hooks Status
|
|
224
|
+
`),!Ht(me))return console.log("Gemini CLI settings: Not found"),console.log(` Expected at: ${me}
|
|
225
|
+
`),console.log(`No hooks installed. Run: claude-mem install --ide gemini-cli
|
|
226
|
+
`),0;let t;try{t=ho()}catch(r){let n=r instanceof Error?r.message:String(r);return r instanceof Error?u.error("WORKER","Failed to read Gemini CLI settings",{path:me},r):u.error("WORKER","Failed to read Gemini CLI settings",{path:me},new Error(String(r))),console.log(`Gemini CLI settings: ${n}
|
|
227
|
+
`),0}if(!t.hooks)return console.log(`Gemini CLI settings: Found, but no hooks configured
|
|
228
|
+
`),console.log(`No hooks installed. Run: claude-mem install --ide gemini-cli
|
|
229
|
+
`),0;let e=[];for(let[r,n]of Object.entries(t.hooks))n.some(o=>o.hooks.some(i=>i.name===Ir))&&e.push(r);if(e.length===0)return console.log(`Gemini CLI settings: Found, but no claude-mem hooks
|
|
230
|
+
`),console.log(`Run: claude-mem install --ide gemini-cli
|
|
231
|
+
`),0;console.log(`Settings: ${me}`),console.log("Mode: Unified CLI (bun worker-service.cjs hook gemini-cli)"),console.log(`Events: ${e.length} of ${Object.keys(Jt).length} mapped`);for(let r of e){let n=Jt[r]??"unknown";console.log(` ${r} \u2192 ${n}`)}return Ht(xe)?kn(xe,"utf-8").includes("<claude-mem-context>")?console.log(`Context: Active (${xe})`):console.log("Context: GEMINI.md exists but missing claude-mem section"):console.log("Context: No GEMINI.md found"),console.log(""),0}async function jf(t,e){switch(t){case"install":return sc();case"uninstall":return oc();case"status":return ic();default:return console.log(`
|
|
232
|
+
Claude-Mem Gemini CLI Integration
|
|
233
|
+
|
|
234
|
+
Usage: claude-mem gemini-cli <command>
|
|
235
|
+
|
|
236
|
+
Commands:
|
|
237
|
+
install Install hooks into ~/.gemini/settings.json
|
|
238
|
+
uninstall Remove claude-mem hooks (preserves other hooks)
|
|
239
|
+
status Check installation status
|
|
240
|
+
|
|
241
|
+
Examples:
|
|
242
|
+
claude-mem gemini-cli install # Install hooks
|
|
243
|
+
claude-mem gemini-cli status # Check if installed
|
|
244
|
+
claude-mem gemini-cli uninstall # Remove hooks
|
|
245
|
+
|
|
246
|
+
For more info: https://docs.claude-mem.ai/usage/gemini-provider
|
|
247
|
+
`),0}}var _n,me,xe,Ir,Mf,Jt,So=b(()=>{"use strict";X();wr();_n=fo.join(Af(),".gemini"),me=fo.join(_n,"settings.json"),xe=fo.join(_n,"GEMINI.md"),Ir="claude-mem",Mf=1e4,Jt={SessionStart:"context",BeforeAgent:"session-init",AfterAgent:"observation",BeforeTool:"observation",AfterTool:"observation",PreCompress:"summarize",Notification:"observation"}});import Wf from"path";import{existsSync as Gf,readFileSync as Bf,writeFileSync as bo,mkdirSync as Hf}from"fs";function Nn(t,e,r){let n=Wf.dirname(t);Hf(n,{recursive:!0});let s=`${Or}
|
|
248
|
+
${wn(e)}
|
|
249
|
+
${Kt}`;if(Gf(t)){let o=Bf(t,"utf-8"),i=o.indexOf(Or),a=o.indexOf(Kt);i!==-1&&a!==-1?o=o.slice(0,i)+s+o.slice(a+Kt.length):o=o.trimEnd()+`
|
|
250
|
+
|
|
251
|
+
`+s+`
|
|
252
|
+
`,bo(t,o,"utf-8")}else r?bo(t,`${r}
|
|
253
|
+
|
|
254
|
+
${s}
|
|
255
|
+
`,"utf-8"):bo(t,s+`
|
|
256
|
+
`,"utf-8")}var Or,Kt,yo=b(()=>{"use strict";oo();Or="<claude-mem-context>",Kt="</claude-mem-context>"});var wo={};de(wo,{addOpenCodePluginReference:()=>uc,checkOpenCodeStatus:()=>zf,deregisterOpenCodePluginFromConfig:()=>mc,findBuiltPluginPath:()=>fc,getInstalledPluginPath:()=>Nr,getOpenCodeAgentsMdPath:()=>_r,getOpenCodeConfigDirectory:()=>kr,getOpenCodeConfigPath:()=>Ro,getOpenCodePluginsDirectory:()=>Co,injectContextIntoAgentsMd:()=>hc,installOpenCodeIntegration:()=>Zf,installOpenCodePlugin:()=>gc,registerOpenCodePluginInConfig:()=>pc,removeOpenCodePluginReference:()=>dc,uninstallOpenCodePlugin:()=>qf});import qe from"path";import{homedir as ac}from"os";import{fileURLToPath as Jf}from"url";import{existsSync as gt,readFileSync as An,writeFileSync as vo,mkdirSync as Kf,copyFileSync as Xf,unlinkSync as lc}from"fs";function kr(){return process.env.OPENCODE_CONFIG_DIR?process.env.OPENCODE_CONFIG_DIR:qe.join(ac(),".config","opencode")}function Co(){return qe.join(kr(),"plugins")}function Ro(){return qe.join(kr(),"opencode.json")}function _r(){return qe.join(kr(),"AGENTS.md")}function Nr(){return qe.join(Co(),"claude-mem.js")}function cc(t){return Array.isArray(t.plugin)?t.plugin:t.plugin===void 0?[]:[t.plugin]}function uc(t){let e=cc(t);return e.includes(To)?t:{...t,plugin:[...e,To]}}function dc(t){return{...t,plugin:cc(t).filter(e=>e!==To)}}function pc(){let t=Ro(),e={$schema:"https://opencode.ai/config.json"};try{let r=gt(t)?JSON.parse(An(t,"utf-8")):e,n=uc(r);return vo(t,`${JSON.stringify(n,null,2)}
|
|
257
|
+
`,"utf-8"),console.log(` Plugin registered in: ${t}`),u.info("OPENCODE","Plugin registered in config",{path:t}),0}catch(r){let n=r instanceof Error?r.message:String(r);return console.error(`Failed to register OpenCode plugin in config: ${n}`),1}}function mc(){let t=Ro();if(!gt(t))return 0;try{let e=JSON.parse(An(t,"utf-8")),r=dc(e);return vo(t,`${JSON.stringify(r,null,2)}
|
|
258
|
+
`,"utf-8"),console.log(` Plugin deregistered from: ${t}`),u.info("OPENCODE","Plugin deregistered from config",{path:t}),0}catch(e){let r=e instanceof Error?e.message:String(e);return console.error(`Failed to deregister OpenCode plugin from config: ${r}`),1}}function fc(){let t=[qe.join(process.env.CLAUDE_CONFIG_DIR||qe.join(ac(),".claude"),"plugins","marketplaces","keepmind","dist","opencode-plugin","index.js"),qe.join(qe.dirname(Jf(import.meta.url)),"..","..","..","dist","opencode-plugin","index.js")];for(let e of t)if(gt(e))return e;return null}function gc(){let t=fc();if(!t)return console.error("Could not find built OpenCode plugin bundle."),console.error(" Expected at: dist/opencode-plugin/index.js"),console.error(" Run the build first: npm run build"),1;let e=Co(),r=Nr();try{Kf(e,{recursive:!0}),Xf(t,r),console.log(` Plugin installed to: ${r}`),u.info("OPENCODE","Plugin installed",{destination:r});let n=pc();return n!==0?n:0}catch(n){let s=n instanceof Error?n.message:String(n);return console.error(`Failed to install OpenCode plugin: ${s}`),1}}function hc(t){let e=_r();try{return Nn(e,t,"# Claude-Mem Memory Context"),u.info("OPENCODE","Context injected into AGENTS.md",{path:e}),0}catch(r){let n=r instanceof Error?r.message:String(r);return console.error(`Failed to inject context into AGENTS.md: ${n}`),1}}async function Vf(){let t=Cr();if(!(await fetch(`http://127.0.0.1:${t}/api/readiness`)).ok)return null;let r=await fetch(`http://127.0.0.1:${t}/api/context/inject?project=opencode`);if(!r.ok)return null;let n=await r.text();return n&&n.trim()?n:null}function Yf(t,e){e.length===0||e==="# Claude-Mem Memory Context"?(lc(t),console.log(" Removed empty AGENTS.md")):(vo(t,e+`
|
|
259
|
+
`,"utf-8"),console.log(" Cleaned context from AGENTS.md"))}function qf(){let t=!1,e=Nr();if(gt(e))try{lc(e),console.log(` Removed plugin: ${e}`)}catch(n){let s=n instanceof Error?n.message:String(n);console.error(` Failed to remove plugin: ${s}`),t=!0}mc()!==0&&(t=!0);let r=_r();if(gt(r)){let n;try{n=An(r,"utf-8")}catch(i){let a=i instanceof Error?i.message:String(i);console.error(` Failed to read AGENTS.md: ${a}`),t=!0,n=""}let s=n.indexOf(Or),o=n.indexOf(Kt);if(s!==-1&&o!==-1){n=n.slice(0,s).trimEnd()+`
|
|
260
|
+
`+n.slice(o+Kt.length).trimStart();let i=n.trim();try{Yf(r,i)}catch(a){let l=a instanceof Error?a.message:String(a);console.error(` Failed to clean AGENTS.md: ${l}`),t=!0}}}return t?1:0}function zf(){console.log(`
|
|
261
|
+
Claude-Mem OpenCode Integration Status
|
|
262
|
+
`);let t=kr(),e=Nr(),r=_r();if(console.log(`Config directory: ${t}`),console.log(` Exists: ${gt(t)?"yes":"no"}`),console.log(""),console.log(`Plugin: ${e}`),console.log(` Installed: ${gt(e)?"yes":"no"}`),console.log(""),console.log(`Context (AGENTS.md): ${r}`),gt(r)){let s=An(r,"utf-8").includes(Or);console.log(" Exists: yes"),console.log(` Has claude-mem context: ${s?"yes":"no"}`)}else console.log(" Exists: no");return console.log(""),0}async function Zf(){console.log(`
|
|
263
|
+
Installing Claude-Mem for OpenCode...
|
|
264
|
+
`);let t=gc();if(t!==0)return t;let r=`# Memory Context from Past Sessions
|
|
265
|
+
|
|
266
|
+
*No context yet. Complete your first session and context will appear here.*
|
|
267
|
+
|
|
268
|
+
Use claude-mem search tools for manual memory queries.`,n="placeholder";try{let o=await Vf();o&&(r=o,n="existing memory")}catch(o){o instanceof Error?u.debug("WORKER","Worker not available during OpenCode install",{},o):u.debug("WORKER","Worker not available during OpenCode install",{},new Error(String(o)))}return hc(r)!==0?u.warn("OPENCODE",`Failed to inject ${n} context into AGENTS.md during install`):console.log(n==="existing memory"?" Context injected from existing memory":" Placeholder context created (worker not running)"),console.log(`
|
|
269
|
+
Installation complete!
|
|
270
|
+
|
|
271
|
+
Plugin installed to: ${Nr()}
|
|
272
|
+
Context file: ${_r()}
|
|
273
|
+
|
|
274
|
+
Next steps:
|
|
275
|
+
1. Start keepmind worker: npx keepmind start
|
|
276
|
+
2. Restart OpenCode to load the plugin
|
|
277
|
+
3. Memory capture is automatic from then on
|
|
278
|
+
`),0}var To,Io=b(()=>{"use strict";X();yo();Rn();To="./plugins/claude-mem.js"});var _o={};de(_o,{checkWindsurfHooksStatus:()=>cg,installWindsurfHooks:()=>rg,readWindsurfRegistry:()=>Oo,registerWindsurfProject:()=>yc,uninstallWindsurfHooks:()=>ig,unregisterWindsurfProject:()=>Tc,writeWindsurfContextFile:()=>vc,writeWindsurfRegistry:()=>ko});import _e from"path";import{homedir as Qf}from"os";import{existsSync as Vt,readFileSync as xn,writeFileSync as Ar,unlinkSync as Sc,mkdirSync as Ln,renameSync as $f}from"fs";function Oo(){try{return Vt(Xt)?JSON.parse(xn(Xt,"utf-8")):{}}catch(t){return t instanceof Error?u.error("WORKER","Failed to read registry, using empty",{file:Xt},t):u.error("WORKER","Failed to read registry, using empty",{file:Xt},new Error(String(t))),{}}}function ko(t){let e=_e.dirname(Xt);Ln(e,{recursive:!0}),Ar(Xt,JSON.stringify(t,null,2))}function yc(t){let e=Oo();e[t]={installedAt:new Date().toISOString()},ko(e),u.info("WINDSURF","Registered project for auto-context updates",{workspacePath:t})}function Tc(t){let e=Oo();e[t]&&(delete e[t],ko(e),u.info("WINDSURF","Unregistered project",{workspacePath:t}))}function vc(t,e){let r=_e.join(t,".windsurf","rules"),n=_e.join(r,"claude-mem-context.md"),s=`${n}.tmp`;Ln(r,{recursive:!0});let o=`# Memory Context from Past Sessions
|
|
279
|
+
|
|
280
|
+
The following context is from claude-mem, a persistent memory system that tracks your coding sessions.
|
|
281
|
+
|
|
282
|
+
${e}
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
*Auto-updated by claude-mem after each session. Use MCP search tools for detailed queries.*
|
|
286
|
+
`;o.length>Ec&&(o=o.slice(0,Ec-50)+`
|
|
287
|
+
|
|
288
|
+
*[Truncated \u2014 use MCP search for full history]*
|
|
289
|
+
`),Ar(s,o),$f(s,n)}function eg(t,e,r){let s={pre_user_prompt:"session-init",post_write_code:"file-edit",post_run_command:"observation",post_mcp_tool_use:"observation",post_cascade_response:"observation"}[r]??"observation";return`"${t}" "${e}" hook windsurf ${s}`}function tg(t,e,r){Ln(bc,{recursive:!0});let n={hooks:{}};if(Vt(ie))try{n=JSON.parse(xn(ie,"utf-8")),n.hooks||(n.hooks={})}catch(s){throw s instanceof Error?u.error("WORKER","Corrupt hooks.json, refusing to overwrite",{path:ie},s):u.error("WORKER","Corrupt hooks.json, refusing to overwrite",{path:ie},new Error(String(s))),new Error(`Corrupt hooks.json at ${ie}, refusing to overwrite`)}for(let s of Mn){let i={command:eg(t,e,s),show_output:!1,working_directory:r},a=(n.hooks[s]??[]).filter(l=>!l.command.includes("worker-service")||!l.command.includes("windsurf"));n.hooks[s]=[...a,i]}Ar(ie,JSON.stringify(n,null,2))}async function rg(){console.log(`
|
|
290
|
+
Installing Claude-Mem Windsurf hooks (user level)...
|
|
291
|
+
`);let t=Gt();if(!t)return console.error("Could not find worker-service.cjs"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/worker-service.cjs"),1;let e=Bt();if(!e)return console.error("Could not find Bun runtime"),console.error(" Install Bun: curl -fsSL https://bun.sh/install | bash"),1;let r=_e.dirname(t);console.log(` Using Bun runtime: ${e}`),console.log(` Worker service: ${t}`);let n=process.cwd();try{return await ng(e,t,r,n),0}catch(s){let o=s instanceof Error?s.message:String(s);return console.error(`
|
|
292
|
+
Installation failed: ${o}`),1}}async function ng(t,e,r,n){tg(t,e,r),console.log(" Created/merged hooks.json"),await sg(n),console.log(`
|
|
293
|
+
Installation complete!
|
|
294
|
+
|
|
295
|
+
Hooks installed to: ${ie}
|
|
296
|
+
Using unified CLI: bun worker-service.cjs hook windsurf <command>
|
|
297
|
+
|
|
298
|
+
Events registered:
|
|
299
|
+
- pre_user_prompt (session init + context injection)
|
|
300
|
+
- post_write_code (code generation observation)
|
|
301
|
+
- post_run_command (command execution observation)
|
|
302
|
+
- post_mcp_tool_use (MCP tool results)
|
|
303
|
+
- post_cascade_response (full AI response)
|
|
304
|
+
|
|
305
|
+
Next steps:
|
|
306
|
+
1. Start keepmind worker: keepmind start
|
|
307
|
+
2. Restart Windsurf to load the hooks
|
|
308
|
+
3. Context is injected via .windsurf/rules/claude-mem-context.md (workspace-level)
|
|
309
|
+
`)}async function sg(t){let e=Cr(),r=_e.basename(t),n=!1;console.log(" Generating initial context...");try{n=await og(e,r,t)}catch(s){s instanceof Error?u.debug("WORKER","Worker not running during install",{},s):u.debug("WORKER","Worker not running during install",{},new Error(String(s)))}if(!n){let s=_e.join(t,".windsurf","rules");Ln(s,{recursive:!0});let o=_e.join(s,"claude-mem-context.md");Ar(o,`# Memory Context from Past Sessions
|
|
310
|
+
|
|
311
|
+
*No context yet. Complete your first session and context will appear here.*
|
|
312
|
+
|
|
313
|
+
Use claude-mem's MCP search tools for manual memory queries.
|
|
314
|
+
`),console.log(" Created placeholder context file (will populate after first session)")}yc(t),console.log(" Registered for auto-context updates")}async function og(t,e,r){if(!(await fetch(`http://127.0.0.1:${t}/api/readiness`)).ok)return!1;let s=await fetch(`http://127.0.0.1:${t}/api/context/inject?project=${encodeURIComponent(e)}`);if(!s.ok)return!1;let o=await s.text();return o&&o.trim()?(vc(r,o),console.log(" Generated initial context from existing memory"),!0):!1}function ig(){if(console.log(`
|
|
315
|
+
Uninstalling Claude-Mem Windsurf hooks...
|
|
316
|
+
`),Vt(ie))try{ag()}catch(e){e instanceof Error?u.error("WORKER","Could not parse hooks.json during uninstall",{path:ie},e):u.error("WORKER","Could not parse hooks.json during uninstall",{path:ie},new Error(String(e))),console.log(" Warning: could not parse hooks.json \u2014 leaving file intact to preserve other hooks")}else console.log(" No hooks.json found");let t=process.cwd();try{return lg(t),0}catch(e){let r=e instanceof Error?e.message:String(e);return console.error(`
|
|
317
|
+
Uninstallation failed: ${r}`),1}}function ag(){let e={hooks:JSON.parse(xn(ie,"utf-8")).hooks??{}};for(let r of Mn){let n=e.hooks[r]??[];n.length>0&&(e.hooks[r]=n.filter(s=>!s.command.includes("worker-service")||!s.command.includes("windsurf")),e.hooks[r].length===0&&delete e.hooks[r])}Object.keys(e.hooks).length===0?(Sc(ie),console.log(" Removed hooks.json (no hooks remaining)")):(Ar(ie,JSON.stringify(e,null,2)),console.log(" Removed claude-mem entries from hooks.json (other hooks preserved)"))}function lg(t){let e=_e.join(t,".windsurf","rules","claude-mem-context.md");Vt(e)&&(Sc(e),console.log(" Removed context file")),Tc(t),console.log(" Unregistered from auto-context updates"),console.log(`
|
|
318
|
+
Uninstallation complete!
|
|
319
|
+
`),console.log("Restart Windsurf to apply changes.")}function cg(){if(console.log(`
|
|
320
|
+
Claude-Mem Windsurf Hooks Status
|
|
321
|
+
`),Vt(ie)){console.log("User-level: Installed"),console.log(` Config: ${ie}`);let t=null;try{t=JSON.parse(xn(ie,"utf-8"))}catch(r){let n=r instanceof Error?r:new Error(String(r));u.error("WORKER","Unable to parse hooks.json",{path:ie},n),console.log(" Mode: Unable to parse hooks.json")}if(t){let r=Mn.filter(n=>(t?.hooks?.[n]??[]).some(s=>s.command.includes("worker-service")&&s.command.includes("windsurf")));console.log(` Events: ${r.length}/${Mn.length} registered`);for(let n of r)console.log(` - ${n}`)}let e=_e.join(process.cwd(),".windsurf","rules","claude-mem-context.md");Vt(e)?console.log(" Context: Active (current workspace)"):console.log(" Context: Not yet generated for this workspace")}else console.log("User-level: Not installed"),console.log(`
|
|
322
|
+
No hooks installed. Run: claude-mem windsurf install
|
|
323
|
+
`);return console.log(""),0}var bc,ie,Ec,Xt,Mn,No=b(()=>{"use strict";X();Rn();V();wr();bc=_e.join(Qf(),".codeium","windsurf"),ie=_e.join(bc,"hooks.json"),Ec=6e3,Xt=_e.join(M,"windsurf-projects.json"),Mn=["pre_user_prompt","post_write_code","post_run_command","post_mcp_tool_use","post_cascade_response"]});var Lo={};de(Lo,{checkOpenClawStatus:()=>hg,findPluginManifestPath:()=>kc,findPluginSkillsDirectory:()=>_c,findPreBuiltPluginDirectory:()=>Oc,getOpenClawClaudeMemExtensionDirectory:()=>xr,getOpenClawConfigDirectory:()=>Mr,getOpenClawConfigFilePath:()=>Yt,getOpenClawExtensionsDirectory:()=>Ic,installOpenClawIntegration:()=>Eg,installOpenClawPlugin:()=>Ac,uninstallOpenClawPlugin:()=>gg});import fe from"path";import{homedir as Cc}from"os";import{existsSync as We,readFileSync as ug,writeFileSync as Rc,mkdirSync as wc,cpSync as Ao,rmSync as dg}from"fs";function Mr(){return fe.join(Cc(),".openclaw")}function Ic(){return fe.join(Mr(),"extensions")}function xr(){return fe.join(Ic(),"claude-mem")}function Yt(){return fe.join(Mr(),"openclaw.json")}function Oc(){for(let t of Mo){let e=fe.join(t,"openclaw","dist"),r=fe.join(e,"index.js");if(We(r))return e}return null}function kc(){for(let t of Mo){let e=fe.join(t,"openclaw","openclaw.plugin.json");if(We(e))return e}return null}function _c(){for(let t of Mo){let e=fe.join(t,"openclaw","skills");if(We(e))return e}return null}function xo(){let t=Yt();if(!We(t))return{};try{return JSON.parse(ug(t,"utf-8"))}catch(e){let r=e instanceof Error?e:new Error(String(e));throw u.error("WORKER","Failed to parse openclaw.json",{path:t},r),r}}function Nc(t){let e=Mr();wc(e,{recursive:!0}),Rc(Yt(),JSON.stringify(t,null,2)+`
|
|
324
|
+
`,"utf-8")}function pg(t,e="openclaw",r=!0){let n=xo();if(n.plugins||(n.plugins={}),n.plugins.slots||(n.plugins.slots={}),n.plugins.entries||(n.plugins.entries={}),n.plugins.slots.memory="claude-mem",!n.plugins.entries["claude-mem"])n.plugins.entries["claude-mem"]={enabled:!0,config:{workerPort:t,project:e,syncMemoryFile:r}};else{n.plugins.entries["claude-mem"].enabled=!0,n.plugins.entries["claude-mem"].config||(n.plugins.entries["claude-mem"].config={});let s=n.plugins.entries["claude-mem"].config;s.workerPort===void 0&&(s.workerPort=t),s.project===void 0&&(s.project=e),s.syncMemoryFile===void 0&&(s.syncMemoryFile=r)}Nc(n)}function mg(){let t=Yt();if(!We(t))return;let e=xo();e.plugins?.entries?.["claude-mem"]&&delete e.plugins.entries["claude-mem"],e.plugins?.slots?.memory==="claude-mem"&&delete e.plugins.slots.memory,Nc(e)}function Ac(){let t=Oc();if(!t)return console.error("Could not find pre-built OpenClaw plugin bundle."),console.error(" Expected at: openclaw/dist/index.js"),console.error(" Ensure the npm package includes the openclaw directory."),1;let e=xr(),r=fe.join(e,"dist"),n=kc(),s=_c(),o={name:"keepmind",version:"1.0.0",type:"module",main:"dist/index.js",openclaw:{extensions:["./dist/index.js"]}};try{return wc(r,{recursive:!0}),fg(t,r,e,n,s,o),0}catch(i){let a=i instanceof Error?i.message:String(i);return console.error(`Failed to install OpenClaw plugin: ${a}`),1}}function fg(t,e,r,n,s,o){if(Ao(t,e,{recursive:!0,force:!0}),console.log(` Plugin dist copied to: ${e}`),n){let a=fe.join(r,"openclaw.plugin.json");Ao(n,a,{force:!0}),console.log(` Plugin manifest copied to: ${a}`)}if(s){let a=fe.join(r,"skills");Ao(s,a,{recursive:!0,force:!0}),console.log(` Skills copied to: ${a}`)}Rc(fe.join(r,"package.json"),JSON.stringify(o,null,2)+`
|
|
325
|
+
`,"utf-8");let i=le.getInt("CLAUDE_MEM_WORKER_PORT");pg(i),console.log(" Registered in openclaw.json"),u.info("OPENCLAW","Plugin installed",{destination:r})}function gg(){let t=!1,e=xr();if(We(e))try{dg(e,{recursive:!0,force:!0}),console.log(` Removed extension: ${e}`)}catch(r){let n=r instanceof Error?r.message:String(r);console.error(` Failed to remove extension directory: ${n}`),t=!0}try{mg(),console.log(" Unregistered from openclaw.json")}catch(r){let n=r instanceof Error?r.message:String(r);console.error(` Failed to update openclaw.json: ${n}`),t=!0}return t?1:0}function hg(){console.log(`
|
|
326
|
+
Claude-Mem OpenClaw Integration Status
|
|
327
|
+
`);let t=Mr(),e=xr(),r=Yt(),n=fe.join(e,"dist","index.js");if(console.log(`Config directory: ${t}`),console.log(` Exists: ${We(t)?"yes":"no"}`),console.log(""),console.log(`Extension directory: ${e}`),console.log(` Exists: ${We(e)?"yes":"no"}`),console.log(` Plugin entry: ${We(n)?"yes":"no"}`),console.log(""),console.log(`Config (openclaw.json): ${r}`),We(r)){let s=xo(),o=s.plugins?.entries?.["claude-mem"]!==void 0,i=s.plugins?.entries?.["claude-mem"]?.enabled===!0,a=s.plugins?.slots?.memory==="claude-mem";if(console.log(" Exists: yes"),console.log(` Registered: ${o?"yes":"no"}`),console.log(` Enabled: ${i?"yes":"no"}`),console.log(` Memory slot: ${a?"yes":"no"}`),o){let l=s.plugins.entries["claude-mem"].config;l&&(console.log(` Worker port: ${l.workerPort??"default"}`),console.log(` Project: ${l.project??"default"}`),console.log(` Sync MEMORY.md: ${l.syncMemoryFile??"default"}`))}}else console.log(" Exists: no");return console.log(""),0}async function Eg(){console.log(`
|
|
328
|
+
Installing Claude-Mem for OpenClaw...
|
|
329
|
+
`);let t=Ac();if(t!==0)return t;let e=xr();return console.log(`
|
|
330
|
+
Installation complete!
|
|
331
|
+
|
|
332
|
+
Plugin installed to: ${e}
|
|
333
|
+
Config updated: ${Yt()}
|
|
334
|
+
|
|
335
|
+
Next steps:
|
|
336
|
+
1. Start keepmind worker: npx keepmind start
|
|
337
|
+
2. Restart OpenClaw to load the plugin
|
|
338
|
+
3. Memory capture is automatic from then on
|
|
339
|
+
`),0}var Mo,Do=b(()=>{"use strict";X();lt();Mo=[fe.join(process.env.CLAUDE_CONFIG_DIR||fe.join(Cc(),".claude"),"plugins","marketplaces","keepmind"),process.cwd()]});var Ko={};de(Ko,{codexSpawn:()=>Ho,installCodexCli:()=>Kg,removeLegacyCodexMcpSearchConfig:()=>jc,resolveCodexCommand:()=>Pc,resolveCodexSpawnInvocation:()=>Uc,setTomlBooleanInTable:()=>Jo,setTomlFeatureEnabled:()=>Fc,setTomlPluginEnabled:()=>jo,uninstallCodexCli:()=>Xg});import se from"path";import{homedir as Uo}from"os";import{execFileSync as Fo,spawnSync as Sg}from"child_process";import{existsSync as zt,mkdirSync as bg,readFileSync as Wo,writeFileSync as Un}from"fs";import{fileURLToPath as yg}from"url";function xc(t){try{return process.platform==="win32"?Fo("where",[t],{stdio:"ignore"}):Fo("which",[t],{stdio:"ignore"}),!0}catch{return!1}}function wg(t){let e=se.resolve(t);for(;;){if(zt(se.join(e,".agents","plugins","marketplace.json")))return e;let r=se.dirname(e);if(r===e)return null;e=r}}function Lc(t){return vg.filter(e=>!zt(se.join(t,e)))}function Ig(t){let e=se.resolve(t),r=Lc(e);if(r.length>0)throw new Error(`Codex marketplace root ${e} is missing required files: ${r.join(", ")}`);return e}function Og(t){if(t)return Ig(t);let e=[process.env.CLAUDE_PLUGIN_ROOT,process.env.PLUGIN_ROOT,process.cwd(),se.dirname(yg(import.meta.url))].filter(r=>!!r);for(let r of e){let n=wg(r);if(n&&Lc(n).length===0)return n}throw new Error("Could not locate a Codex marketplace root with .agents/plugins/marketplace.json and plugin/.codex-plugin/plugin.json. Run npx keepmind@latest install from the package or repo root.")}function Dc(){try{let e=Fo("where",["codex"],{encoding:"utf-8",stdio:["ignore","pipe","ignore"],windowsHide:!0}).split(/\r?\n/).map(r=>r.trim()).filter(Boolean);return e.find(r=>Cg.has(se.extname(r).toLowerCase()))??e[0]??null}catch{return null}}function kg(t){return`"${t.replace(/"/g,'""')}"`}function Pc(t=process.platform,e=Dc){return t!=="win32"?"codex":e()??"codex.cmd"}function Uc(t,e=process.platform,r=Dc){let n=Pc(e,r),s={encoding:"utf-8",stdio:["ignore","pipe","pipe"],...e==="win32"?{windowsHide:!0}:{}};return e==="win32"&&Rg.has(se.extname(n).toLowerCase())?{command:"cmd.exe",args:["/d","/s","/c",[n,...t].map(kg).join(" ")],options:s}:{command:n,args:t,options:s}}function Ho(t){let e=Uc(t);return Sg(e.command,e.args,e.options)}function Lr(t){let e=Ho(t),r=console,n=e.stdout?.trimEnd(),s=e.stderr?.trimEnd();if(n&&r.log(n),s&&r.error(s),e.error)throw e.error;if(e.status!==0){let o=e.status??"unknown";throw new Error(`codex ${t.join(" ")} failed with exit code ${o}${s?`: ${s}`:""}`)}}function _g(t,e,r){try{return Lr(t),console.log(` ${e}`),!0}catch(n){let s=n instanceof Error?n.message:String(n);return console.warn(` ${r}: ${s}`),!1}}function Ng(t){let e=t instanceof Error?t.message:String(t);return e.includes(`marketplace '${Et}' is already added from a different source`)||e.includes(`marketplace \`${Et}\` is already added from a different source`)}function Ag(t){try{Lr(["plugin","marketplace","add",t]);return}catch(e){if(!Ng(e))throw e}console.warn(` Codex marketplace ${Et} is already registered from another source; replacing it with ${t}.`),Lr(["plugin","marketplace","remove",Et]),Lr(["plugin","marketplace","add",t])}function Jo(t,e,r,n){let s=`${r} = ${n?"true":"false"}`,o=t.split(`
|
|
340
|
+
`),i=o.findIndex(m=>m.trim()===e);if(i===-1){let m=t.trimEnd();return`${m}${m?`
|
|
341
|
+
|
|
342
|
+
`:""}${e}
|
|
343
|
+
${s}
|
|
344
|
+
`}let a=i+1;for(;a<o.length&&!/^\s*\[/.test(o[a]);)a+=1;let l=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),c=new RegExp(`^\\s*${l}\\s*=`),d=o.findIndex((m,f)=>f>i&&f<a&&c.test(m));return d===-1?o.splice(i+1,0,s):o[d]=s,o.join(`
|
|
345
|
+
`)}function jo(t,e,r){let n=e.replace(/\\/g,"\\\\").replace(/"/g,'\\"');return Jo(t,`[plugins."${n}"]`,"enabled",r)}function Fc(t,e,r){return Jo(t,"[features]",e,r)}function Mg(t){let e=t.trim().match(/^\[([^\]]+)\]\s*$/);return e?e[1].replace(/\s+/g,"").replace(/"/g,""):null}function Mc(t){return t==="mcp_servers.mcp-search"}function xg(t){return typeof t=="string"&&t.startsWith("mcp_servers.mcp-search.")}function Lg(t){return/claude-mem/.test(t)}function jc(t){let e=t.split(`
|
|
346
|
+
`),r=[],n=null,s=[];for(let a of e){let l=Mg(a);l!==null?(r.push({header:n,text:s.join(`
|
|
347
|
+
`)}),n=l,s=[a]):s.push(a)}return r.push({header:n,text:s.join(`
|
|
348
|
+
`)}),r.some(a=>Mc(a.header)&&Lg(a.text))?r.filter(a=>!Mc(a.header)&&!xg(a.header)).map(a=>a.text).join(`
|
|
349
|
+
`).replace(/^\n+/,"").replace(/\n{3,}/g,`
|
|
350
|
+
|
|
351
|
+
`):t}function Wc(t){if(!t&&!zt(Dn))return!1;bg(Go,{recursive:!0});let e=zt(Dn)?Wo(Dn,"utf-8"):"",r=e;t&&(r=Fc(r,"hooks",!0),r=jc(r));for(let n of Tg)r=jo(r,n,!1);return r=jo(r,Bo,t),r===e?!1:(Un(Dn,r),!0)}function Dg(){let t=Wc(!0);console.log(` Enabled Codex plugin: ${Bo}${t?"":" (already enabled)"}`)}function Pg(){let t=Wc(!1);console.log(` Disabled Codex plugin: ${Bo}${t?"":" (already disabled)"}`)}function Ug(t){return t.match(/\d+\.\d+\.\d+/)?.[0]??null}function Fg(){let t=Ho(["--version"]),e=`${t.stdout??""}
|
|
352
|
+
${t.stderr??""}`.trim();if(t.error)throw t.error;if(t.status!==0){console.warn(` Could not determine Codex CLI version. Continuing; plugin marketplace support requires ${Pn} or newer.${e?`
|
|
353
|
+
${e}`:""}`);return}let r=Ug(e);if(!r){console.warn(` Could not parse Codex CLI version from "${e||"<empty>"}". Continuing; plugin marketplace support requires ${Pn} or newer.`);return}if(r.localeCompare(Pn,void 0,{numeric:!0})<0)throw new Error(`Codex CLI ${r} is too old for plugin marketplace support. Update Codex CLI to ${Pn} or newer, then run: npx keepmind@latest install`)}function jg(){if(!zt(ht))return!0;let t="<claude-mem-context>",e="</claude-mem-context>";try{return Wg(t,e),!0}catch(r){let n=r instanceof Error?r.message:String(r);return u.warn("WORKER","Failed to clean AGENTS.md context",{error:n}),!1}}function Wg(t,e){let r=Wo(ht,"utf-8"),n=r.indexOf(t),s=r.indexOf(e);if(n===-1||s===-1)return;let o=r.substring(0,n).replace(/\n+$/,""),i=r.substring(s+e.length).replace(/^\n+/,""),a=(o+(i?`
|
|
354
|
+
|
|
355
|
+
`+i:"")).trim();a?Un(ht,a+`
|
|
356
|
+
`):Un(ht,""),console.log(` Removed legacy global context from ${ht}`)}function Po(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function Gg(t){return t.name==="codex"||t.schema==="codex"}function Bg(t){return t==="~"?Uo():t.startsWith("~/")||t.startsWith("~\\")?se.join(Uo(),t.slice(2)):t}function Hg(t){if(t.mode!=="agents")return!1;let e=t.updateOn;return Array.isArray(e)&&e.length===2&&e.includes("session_start")&&e.includes("session_end")?t.path===void 0?!0:typeof t.path=="string"&&se.resolve(Bg(t.path))===ht:!1}function Jg(){if(!zt(qt))return!0;try{let t=JSON.parse(Wo(qt,"utf-8"));if(!Po(t)||!Array.isArray(t.watches))return!0;let e=!1;for(let r of t.watches)!Po(r)||!Gg(r)||!Po(r.context)||!Hg(r.context)||(delete r.context,e=!0);return e&&(Un(qt,`${JSON.stringify(t,null,2)}
|
|
357
|
+
`),console.log(` Disabled legacy Codex transcript AGENTS.md context in ${qt}`)),!0}catch(t){let e=t instanceof Error?t.message:String(t);return u.warn("WORKER","Failed to disable Codex transcript AGENTS.md context",{error:e}),!1}}async function Kg(t){if(console.log(`
|
|
358
|
+
Installing Claude-Mem for Codex CLI (native hooks)...
|
|
359
|
+
`),!xc("codex"))return console.error("Codex CLI was not found on PATH."),console.error("Install Codex, then run: npx keepmind@latest install"),1;try{Fg();let e=Og(t);return console.log(` Registering Codex plugin marketplace: ${e}`),Ag(e),Dg(),_g(["plugin","marketplace","upgrade",Et],"Refreshed Codex marketplace and installed plugin cache.","Could not refresh Codex marketplace cache; reinstall or upgrade claude-mem from /plugins if Codex still uses old MCP config"),Gc()||console.warn(` Native Codex hooks registered, but failed to remove legacy AGENTS.md context from ${ht}.`),Bc()||console.warn(` Native Codex hooks registered, but failed to disable legacy transcript AGENTS.md context in ${qt}.`),console.log(`
|
|
360
|
+
Installation complete!
|
|
361
|
+
|
|
362
|
+
Codex marketplace: ${Et}
|
|
363
|
+
Plugin source: ${e}
|
|
364
|
+
|
|
365
|
+
Next steps:
|
|
366
|
+
1. Open Codex CLI in your project
|
|
367
|
+
2. Restart any running Codex sessions so native hooks are loaded
|
|
368
|
+
|
|
369
|
+
For a fresh setup, the supported entry point is:
|
|
370
|
+
npx keepmind@latest install
|
|
371
|
+
`),0}catch(e){let r=e instanceof Error?e.message:String(e);return console.error(`
|
|
372
|
+
Installation failed: ${r}`),1}}function Xg(){console.log(`
|
|
373
|
+
Uninstalling Claude-Mem Codex CLI integration...
|
|
374
|
+
`);let t=!1;try{Pg()}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`
|
|
375
|
+
Codex plugin config update failed: ${r}`),t=!0}try{xc("codex")?Lr(["plugin","marketplace","remove",Et]):console.log(" Codex CLI not found; skipping marketplace removal.")}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`
|
|
376
|
+
Codex marketplace removal failed: ${r}`),t=!0}try{Gc()||(console.error(`
|
|
377
|
+
Failed to remove legacy AGENTS.md context from ${ht}.`),t=!0),Bc()||(console.error(`
|
|
378
|
+
Failed to disable legacy transcript AGENTS.md context in ${qt}.`),t=!0)}catch(e){let r=e instanceof Error?e.message:String(e);console.error(`
|
|
379
|
+
Legacy context cleanup failed: ${r}`),t=!0}return t?(console.error(`
|
|
380
|
+
Uninstallation completed with errors.`),1):(console.log(`
|
|
381
|
+
Uninstallation complete!`),console.log(`Restart Codex CLI to apply changes.
|
|
382
|
+
`),0)}var Go,ht,qt,Dn,Et,Bo,Tg,Pn,vg,Cg,Rg,Gc,Bc,Xo=b(()=>{"use strict";X();V();Go=se.join(Uo(),".codex"),ht=se.join(Go,"AGENTS.md"),qt=j.transcriptsConfig(),Dn=se.join(Go,"config.toml"),Et="claude-mem-local",Bo=`claude-mem@${Et}`,Tg=["claude-mem@thedotmack"],Pn="0.128.0",vg=[se.join(".agents","plugins","marketplace.json"),se.join("plugin",".codex-plugin","plugin.json"),se.join("plugin",".mcp.json"),se.join("plugin","hooks","codex-hooks.json"),se.join("plugin","skills","mem-search","SKILL.md")],Cg=new Set([".cmd",".exe",".bat",".com"]),Rg=new Set([".cmd",".bat"]);Gc=jg;Bc=Jg});var Xc={};de(Xc,{MCP_IDE_INSTALLERS:()=>oh,installGooseMcpIntegration:()=>Kc});import Ne from"path";import{homedir as Wn}from"os";import{existsSync as Hc,readFileSync as Vg,writeFileSync as Dr,mkdirSync as Jc}from"fs";function qg(t){return{command:lo(),args:[t]}}function zg(t,e,r="mcpServers"){let n=Ne.dirname(t);Jc(n,{recursive:!0});let s=z(t,{});s[r]||(s[r]={}),s[r]["claude-mem"]=qg(e),Dr(t,JSON.stringify(s,null,2)+`
|
|
383
|
+
`)}function Fn(t){return async()=>{console.log(`
|
|
384
|
+
Installing Claude-Mem MCP integration for ${t.ideLabel}...
|
|
385
|
+
`);let e=Rr();if(!e)return console.error("Could not find MCP server script"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/mcp-server.cjs"),1;let r=t.configPath,n=t.ideId==="warp"&&!Hc(Ne.dirname(r)),s;t.contextFile&&(s=t.contextFile.path);try{return Zg(t,r,e,n,s),0}catch(o){let i=o instanceof Error?o.message:String(o);return console.error(`
|
|
386
|
+
Installation failed: ${i}`),1}}}function Zg(t,e,r,n,s){n?console.log(" Note: ~/.warp/ not found. MCP may need to be configured via Warp Drive UI."):(zg(e,r,t.configKey),console.log(` MCP config written to: ${e}`)),s&&(Nn(s,Yg),console.log(` Context placeholder written to: ${s}`));let o=[`
|
|
387
|
+
Installation complete!
|
|
388
|
+
`];o.push(`MCP config: ${e}`),s&&o.push(`Context: ${s}`),o.push(""),o.push("Note: This is an MCP-only integration providing search tools and context."),o.push(`Transcript capture is not available for ${t.ideLabel}.`),t.ideId==="warp"&&o.push("If MCP config via file is not supported, configure MCP through Warp Drive UI."),o.push(""),o.push("Next steps:"),o.push(" 1. Start keepmind worker: npx keepmind start"),o.push(` 2. Restart ${t.ideLabel} to pick up the MCP server`),o.push(""),console.log(o.join(`
|
|
389
|
+
`))}function rh(){return Ne.join(Wn(),".config","goose","config.yaml")}function nh(t){return t.includes("claude-mem:")&&t.includes("mcpServers:")}function jn(t,e=!1){return[...e?["mcpServers:"]:[]," claude-mem:",` command: ${lo()}`," args:",` - ${t}`].join(`
|
|
390
|
+
`)}async function Kc(){console.log(`
|
|
391
|
+
Installing Claude-Mem MCP integration for Goose...
|
|
392
|
+
`);let t=Rr();if(!t)return console.error("Could not find MCP server script"),console.error(" Expected at: ~/.claude/plugins/marketplaces/keepmind/plugin/scripts/mcp-server.cjs"),1;let e=rh(),r=Ne.dirname(e);try{return Jc(r,{recursive:!0}),sh(e,t),0}catch(n){let s=n instanceof Error?n.message:String(n);return console.error(`
|
|
393
|
+
Installation failed: ${s}`),1}}function sh(t,e){if(Hc(t)){let r=Vg(t,"utf-8");if(nh(r)){let n=/( {2}claude-mem:\n(?:.*\n)*?(?= {2}\S|\n\n|^\S|$))/m,s=jn(e)+`
|
|
394
|
+
`;if(!n.test(r))throw new Error("Found mcpServers/claude-mem markers but could not locate a replaceable claude-mem block");r=r.replace(n,s),Dr(t,r),console.log(` Updated existing claude-mem entry in: ${t}`)}else if(r.includes("mcpServers:")){let s=r.indexOf("mcpServers:")+11,o=`
|
|
395
|
+
`+jn(e);r=r.slice(0,s)+o+r.slice(s),Dr(t,r),console.log(` Added claude-mem to existing mcpServers in: ${t}`)}else{let n=`
|
|
396
|
+
`+jn(e,!0)+`
|
|
397
|
+
`;r=r.trimEnd()+`
|
|
398
|
+
`+n,Dr(t,r),console.log(` Appended mcpServers section to: ${t}`)}}else{let r=jn(e,!0)+`
|
|
399
|
+
`;Dr(t,r),console.log(` Created config with MCP server: ${t}`)}console.log(`
|
|
400
|
+
Installation complete!
|
|
401
|
+
|
|
402
|
+
MCP config: ${t}
|
|
403
|
+
|
|
404
|
+
Note: This is an MCP-only integration providing search tools and context.
|
|
405
|
+
Transcript capture is not available for Goose.
|
|
406
|
+
|
|
407
|
+
Next steps:
|
|
408
|
+
1. Start keepmind worker: npx keepmind start
|
|
409
|
+
2. Restart Goose to pick up the MCP server
|
|
410
|
+
`)}var Yg,Qg,$g,eh,th,oh,Vc=b(()=>{"use strict";wr();$t();yo();Yg=`# claude-mem: Cross-Session Memory
|
|
411
|
+
|
|
412
|
+
*No context yet. Complete your first session and context will appear here.*
|
|
413
|
+
|
|
414
|
+
Use claude-mem's MCP search tools for manual memory queries.`;Qg={ideId:"copilot-cli",ideLabel:"Copilot CLI",configPath:Ne.join(Wn(),".github","copilot","mcp.json"),configKey:"servers",contextFile:{path:Ne.join(process.cwd(),".github","copilot-instructions.md"),isWorkspaceRelative:!0}},$g={ideId:"antigravity",ideLabel:"Antigravity",configPath:Ne.join(Wn(),".gemini","antigravity","mcp_config.json"),configKey:"mcpServers",contextFile:{path:Ne.join(process.cwd(),".agents","rules","claude-mem-context.md"),isWorkspaceRelative:!0}},eh={ideId:"roo-code",ideLabel:"Roo Code",configPath:Ne.join(process.cwd(),".roo","mcp.json"),configKey:"mcpServers",contextFile:{path:Ne.join(process.cwd(),".roo","rules","claude-mem-context.md"),isWorkspaceRelative:!0}},th={ideId:"warp",ideLabel:"Warp",configPath:Ne.join(Wn(),".warp","mcp.json"),configKey:"mcpServers",contextFile:{path:Ne.join(process.cwd(),"WARP.md"),isWorkspaceRelative:!0}};oh={"copilot-cli":Fn(Qg),antigravity:Fn($g),goose:Kc,"roo-code":Fn(eh),warp:Fn(th)}});import{createHash as ih}from"crypto";function Vo(t,e,r){return ih("sha256").update([t||"",e||"",r||""].join("\0")).digest("hex").slice(0,16)}var Yc=b(()=>{"use strict"});function Yo(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[String(e)]}catch{return[t]}}var qc=b(()=>{"use strict"});function lh(t,e){if(e.re.lastIndex=0,e.group===void 0)return t.replace(e.re,qo(e.type));let r=e.group;return t.replace(e.re,(n,...s)=>{let o=s[r-1];return typeof o!="string"||o.length===0?n:n.replace(o,qo(e.type))})}function ch(t){if(t.length===0)return 0;let e=new Map;for(let n of t)e.set(n,(e.get(n)??0)+1);let r=0;for(let n of e.values()){let s=n/t.length;r-=s*Math.log2(s)}return r}function dh(t,e){return t.length<20||t.length>200||/[\s]/.test(t)||!/\d/.test(t)||!/[A-Za-z]/.test(t)||t.includes("/")||t.includes("\\")||t.length<=64&&uh.test(t)||t.includes("redacted:")?!1:ch(t)>=e}function mh(t,e){let r=t.split(ph);for(let n=0;n<r.length;n++){let s=r[n];s&&dh(s,e)&&(r[n]=qo("HIGH_ENTROPY"))}return r.join("")}function zo(t,e={}){if(typeof t!="string"||t.length===0)return t;try{let r=t;for(let n of ah)r=lh(r,n);return e.entropySweep!==!1&&(r=mh(r,e.entropyThreshold??4)),r}catch{return t}}function Gn(t,e={}){if(typeof t=="string")return zo(t,e);if(Array.isArray(t))return t.map(r=>Gn(r,e));if(t&&typeof t=="object"){let r={};for(let[n,s]of Object.entries(t))r[n]=Gn(s,e);return r}return t}var qo,ah,uh,ph,zc=b(()=>{"use strict";qo=t=>`\xABredacted:${t}\xBB`,ah=[{type:"PRIVATE_KEY",re:/-----BEGIN[ A-Z0-9_-]{0,100}PRIVATE KEY(?: BLOCK)?-----[\s\S]{0,4000}?-----END[ A-Z0-9_-]{0,100}PRIVATE KEY(?: BLOCK)?-----/g},{type:"CONNECTION_STRING",re:/\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis|amqp|https?):\/\/[^\s/@]+:[^\s/@]+@[^\s]{1,200}/gi},{type:"AWS_KEY",re:/\b((?:A3T[A-Z0-9]|AKIA|ASIA|ABIA|ACCA)[A-Z2-7]{16})\b/g},{type:"GITHUB_FINE_PAT",re:/\bgithub_pat_\w{82}\b/g},{type:"GITHUB_PAT",re:/\bghp_[0-9A-Za-z]{36}\b/g},{type:"GITLAB_PAT",re:/\bglpat-[\w-]{20}\b/g},{type:"SLACK_TOKEN",re:/\bxox[baprs]-[0-9A-Za-z-]{10,200}\b/g},{type:"GOOGLE_API_KEY",re:/\bAIza[\w-]{35}\b/g},{type:"STRIPE_KEY",re:/\b(?:sk|rk|pk)_(?:test|live|prod)_[A-Za-z0-9]{10,99}\b/g},{type:"JWT",re:/\bey[A-Za-z0-9_-]{17,500}\.ey[A-Za-z0-9_/\\-]{17,500}\.[A-Za-z0-9_/\\-]{10,500}={0,2}/g},{type:"BEARER",re:/\b[Bb]earer\s+[A-Za-z0-9._~+/=-]{12,500}/g},{type:"BCRYPT",re:/\$2[aby]\$\d{2}\$[./A-Za-z0-9]{53}/g},{type:"GENERIC_SECRET",re:/(?:pass(?:word)?|secret|token|api[_-]?key|client[_-]?secret|auth)\b['"\s]{0,3}[:=>]{1,2}['"\s]{0,3}([\w./+=-]{10,150})/gi,group:1}];uh=/^[0-9a-f]+$/i;ph=/([\s"'`,;(){}\[\]<>]+)/});import{readFileSync as fh,existsSync as gh}from"fs";function Bn(t){return!!t&&typeof t=="object"&&!Array.isArray(t)}function St(t,e){if(!Bn(e))return{...t};let r={...t};for(let n of Object.keys(t))e[n]!==void 0&&typeof e[n]==typeof t[n]&&(r[n]=e[n]);return r}function Zc(t=!1){if(Zo&&!t)return Zo;let e=Qo,r;try{let o=j.settings();if(gh(o)){let i=JSON.parse(fh(o,"utf-8").replace(/^/,"")),a=Bn(i)?i.memoryQuality??(Bn(i.env)?i.env.memoryQuality:void 0):void 0;Bn(a)&&(r=a)}}catch(o){u.debug("CONFIG","memoryQuality config load failed; using defaults",{},o instanceof Error?o:new Error(String(o)))}let n={redactSecrets:St(e.redactSecrets,r?.redactSecrets),scoping:St(e.scoping,r?.scoping),importance:St(e.importance,r?.importance),injection:St(e.injection,r?.injection),reconcile:St(e.reconcile,r?.reconcile),supersession:St(e.supersession,r?.supersession),expiry:St(e.expiry,r?.expiry),optimizer:St(e.optimizer,r?.optimizer)},s=process.env.CLAUDE_MEM_REDACT_SECRETS;return(s==="0"||s==="false")&&(n.redactSecrets.enabled=!1),Zo=n,n}var Qo,Zo,Qc=b(()=>{"use strict";V();X();Qo={redactSecrets:{enabled:!0,entropyThreshold:4,entropySweep:!0},scoping:{enabled:!0,includeGlobal:!0,defaultSearchScope:"project"},importance:{enabled:!0,halfLifeDays:14,llmRefine:!1},injection:{tokenBudget:4e3,candidateMultiplier:3},reconcile:{enabled:!1,noopThreshold:.92,updateBand:.75,llmAdjudicate:!1,allowHardDelete:!1},supersession:{enabled:!1},expiry:{enabled:!1,ttlDays:28,importanceFloor:7,hardDelete:!1},optimizer:{enabled:!0,tickMinutes:5,vacuumHours:24}};Zo=null});function Eh(t){if(Array.isArray(t))return t.length;if(typeof t=="string")try{let e=JSON.parse(t);return Array.isArray(e)?e.length:0}catch{return 0}return 0}function $o(t){let e=hh[t.type??"other"]??4;return Eh(t.files_modified)>0&&(e+=1),(t.narrative?.length??0)<40&&(e-=1),/\b(TODO|FIXME|WIP)\b/i.test(t.narrative??"")&&(e-=1),Math.max(1,Math.min(10,e))}var hh,$c=b(()=>{"use strict";hh={decision:9,bugfix:8,refactor:6,discovery:5,global:7,other:3,trivial:1}});function Hn(t){return t?t.toLowerCase().replace(/[^a-z0-9\s]+/g," ").split(/\s+/).filter(e=>e.length>0&&!Sh.has(e)).join(" ").trim():""}function eu(t){let e=new Set,r=t.replace(/\s+/g," ");for(let n=0;n+3<=r.length;n++)e.add(r.slice(n,n+3));return e}function bh(t,e){let r=eu(t),n=eu(e);if(r.size===0&&n.size===0)return 1;if(r.size===0||n.size===0)return 0;let s=0;for(let o of r)n.has(o)&&s++;return s/(r.size+n.size-s)}function yh(t,e){let r=new Map,n=new Map;for(let a of t.split(" "))a&&r.set(a,(r.get(a)??0)+1);for(let a of e.split(" "))a&&n.set(a,(n.get(a)??0)+1);if(r.size===0||n.size===0)return 0;let s=0;for(let[a,l]of r)s+=l*(n.get(a)??0);let o=0;for(let a of r.values())o+=a*a;let i=0;for(let a of n.values())i+=a*a;return s/(Math.sqrt(o)*Math.sqrt(i)||1)}function Th(t,e){let r=Hn(`${t??""}`),n=Hn(`${e??""}`);return Math.max(bh(r,n),yh(r,n))}function tu(t,e,r){let n=`${t.title??""} ${t.narrative??""}`,s={action:"ADD"},o=-1;for(let i of e){let a=Th(n,`${i.title??""} ${i.narrative??""}`);a<=o||(o=a,a>=r.noopThreshold?s={action:"NOOP",candidateId:i.id,score:a}:a>=r.updateBand&&r.supersessionEnabled?s={action:"UPDATE",candidateId:i.id,score:a}:s={action:"ADD",score:a})}return s}var Sh,ei=b(()=>{"use strict";Sh=new Set(["the","a","an","and","or","but","to","of","in","on","for","with","is","are","was","were","be","been","it","this","that","we","i","as","at","by","from","into","over","so","then","than","will"])});import{createHash as vh}from"crypto";function ti(t){let e=t.title??"";if(!e){if(Array.isArray(t.facts)&&t.facts.length>0)e=t.facts[0];else if(typeof t.facts=="string")try{let n=JSON.parse(t.facts);Array.isArray(n)&&n.length>0&&(e=String(n[0]))}catch{}}e||(e=(t.narrative??"").slice(0,80));let r=Hn(e);return vh("sha1").update(r).digest("hex").slice(0,16)}var ru=b(()=>{"use strict";ei()});function Ch(t){return t.trim().toLowerCase().replace(/\s+/g,"-")}function ue(t){if(!t)return _;let e=Ch(t);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:_}function nu(t){let e=["claude","codex","cursor"];return[...t].sort((r,n)=>{let s=e.indexOf(r),o=e.indexOf(n);return s!==-1||o!==-1?s===-1?1:o===-1?-1:s-o:r.localeCompare(n)})}var _,ri=b(()=>{"use strict";_="claude"});function su(t,e,r,n,s){let o=Date.now()-n,i=s!==void 0?"up.session_db_id = ?":"up.content_session_id = ?",a=s??e;return t.prepare(`
|
|
415
|
+
SELECT
|
|
416
|
+
up.*,
|
|
417
|
+
s.memory_session_id,
|
|
418
|
+
s.project,
|
|
419
|
+
COALESCE(s.platform_source, '${_}') as platform_source
|
|
420
|
+
FROM user_prompts up
|
|
421
|
+
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
422
|
+
WHERE ${i}
|
|
423
|
+
AND up.prompt_text = ?
|
|
424
|
+
AND up.created_at_epoch >= ?
|
|
425
|
+
ORDER BY up.created_at_epoch DESC
|
|
426
|
+
LIMIT 1
|
|
427
|
+
`).get(a,r,o)??void 0}var ou=b(()=>{"use strict";ri()});function Rh(t){let e=Object.fromEntries(lu.map(s=>[s,0]));iu.lastIndex=0;let r=0,n=t.replace(iu,(s,o)=>(e[o]=(e[o]??0)+1,r+=1,""));return r>au&&u.warn("SYSTEM","tag count exceeds limit",void 0,{tagCount:r,maxAllowed:au,contentLength:t.length}),{stripped:n.trim(),counts:e}}function cu(t){return Rh(t).stripped}var lu,iu,au,wh,UC,FC,uu=b(()=>{"use strict";X();lu=["private","claude-mem-context","system_instruction","system-instruction","persisted-output","system-reminder"],iu=new RegExp(`<(${lu.join("|")})\\b[^>]*>[\\s\\S]*?</\\1>`,"g"),au=100;wh=["task-notification"],UC=new RegExp(`^\\s*<(${wh.join("|")})\\b[^>]*>(?:(?!<\\1\\b|</\\1\\b)[\\s\\S])*</\\1>\\s*$`),FC=256*1024});function Jn(t){let e=t.trim(),n=cu(t).trim()||e;return n.length<=ni?n:(u.debug("DB","Truncated stored prompt text to the configured cap",{originalLength:n.length,storedLength:ni}),`${n.slice(0,ni-1)}\u2026`)}var ni,du=b(()=>{"use strict";uu();X();ni=4e3});var oi={};de(oi,{SessionStore:()=>si});function Ih(t,e){return{customTitle:t,platformSource:e?ue(e):void 0}}var si,ii=b(()=>{"use strict";mr();V();X();Yc();qc();zc();Qc();$c();ei();ru();ri();ou();du();si=class{db;redactEnabled;redactOpts;mq;rt(e){return this.redactEnabled?zo(e,this.redactOpts):e}rl(e){return this.redactEnabled?Gn(e,this.redactOpts):e}constructor(e=B){try{this.mq=Zc();let r=this.mq.redactSecrets;this.redactEnabled=r.enabled,this.redactOpts={entropySweep:r.entropySweep,entropyThreshold:r.entropyThreshold}}catch{this.mq=Qo,this.redactEnabled=process.env.CLAUDE_MEM_REDACT_SECRETS!=="0"&&process.env.CLAUDE_MEM_REDACT_SECRETS!=="false",this.redactOpts={entropySweep:!0,entropyThreshold:4}}if(e instanceof ye)this.db=e;else{e!==":memory:"&&sn(M);let r=e===B?Ns():e;this.db=new ye(r),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),this.db.run("PRAGMA journal_size_limit = 4194304")}this.initializeSchema(),this.ensureWorkerPortColumn(),this.ensurePromptTrackingColumns(),this.removeSessionSummariesUniqueConstraint(),this.addObservationHierarchicalFields(),this.makeObservationsTextNullable(),this.createUserPromptsTable(),this.ensureDiscoveryTokensColumn(),this.createPendingMessagesTable(),this.renameSessionIdColumns(),this.repairSessionIdColumnRename(),this.addFailedAtEpochColumn(),this.addOnUpdateCascadeToForeignKeys(),this.addObservationContentHashColumn(),this.addSessionCustomTitleColumn(),this.addSessionPlatformSourceColumn(),this.addObservationModelColumns(),this.ensureMergedIntoProjectColumns(),this.addObservationSubagentColumns(),this.addObservationsUniqueContentHashIndex(),this.addObservationsMetadataColumn(),this.dropDeadPendingMessagesColumns(),this.ensurePendingMessagesToolUseIdColumn(),this.dropWorkerPidColumn(),this.ensureSDKSessionsPlatformContentIdentity(),this.ensureUserPromptsSessionDbId(),this.ensurePendingMessagesSessionToolUniqueIndex(),this.addObservationImportanceColumn(),this.addObservationBitemporalColumns(),this.addObservationLastUsedColumn()}addObservationBitemporalColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(37),r=this.db.query("PRAGMA table_info(observations)").all(),n=s=>r.some(o=>o.name===s);e&&n("valid_from")&&n("valid_to")&&n("subject_key")||(n("valid_from")||this.db.run("ALTER TABLE observations ADD COLUMN valid_from INTEGER"),n("valid_to")||this.db.run("ALTER TABLE observations ADD COLUMN valid_to INTEGER"),n("subject_key")||this.db.run("ALTER TABLE observations ADD COLUMN subject_key TEXT"),this.db.run("UPDATE observations SET valid_from = created_at_epoch WHERE valid_from IS NULL"),this.db.run("CREATE INDEX IF NOT EXISTS idx_obs_subject_valid ON observations(project, subject_key, valid_to)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(37,new Date().toISOString()))}addObservationLastUsedColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(38),n=this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="last_used_at");e&&n||(n||this.db.run("ALTER TABLE observations ADD COLUMN last_used_at INTEGER"),this.db.run("CREATE INDEX IF NOT EXISTS idx_obs_last_used ON observations(last_used_at)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(38,new Date().toISOString()))}addObservationImportanceColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(36),n=this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="importance");e&&n||(n||this.db.run("ALTER TABLE observations ADD COLUMN importance INTEGER"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_importance ON observations(importance)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(36,new Date().toISOString()))}getIndexColumns(e){return this.db.query(`PRAGMA index_info(${JSON.stringify(e)})`).all().map(r=>r.name)}hasUniqueIndexOnColumns(e,r){return this.db.query(`PRAGMA index_list(${e})`).all().some(s=>{if(s.unique!==1)return!1;let o=this.getIndexColumns(s.name);return o.length===r.length&&o.every((i,a)=>i===r[a])})}resolvePromptSessionDbId(e,r,n){if(r!==void 0)return r;let s=n?ue(n):void 0;return s?this.db.prepare(`
|
|
428
|
+
SELECT id
|
|
429
|
+
FROM sdk_sessions
|
|
430
|
+
WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
|
|
431
|
+
AND content_session_id = ?
|
|
432
|
+
LIMIT 1
|
|
433
|
+
`).get(_,s,e)?.id??null:this.db.prepare(`
|
|
434
|
+
SELECT id
|
|
435
|
+
FROM sdk_sessions
|
|
436
|
+
WHERE content_session_id = ?
|
|
437
|
+
ORDER BY CASE COALESCE(NULLIF(platform_source, ''), '${_}')
|
|
438
|
+
WHEN '${_}' THEN 0
|
|
439
|
+
ELSE 1
|
|
440
|
+
END, id
|
|
441
|
+
LIMIT 1
|
|
442
|
+
`).get(e)?.id??null}dropWorkerPidColumn(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(32),n=this.db.query("PRAGMA table_info(pending_messages)").all().some(s=>s.name==="worker_pid");if(!(e&&!n)){if(n)try{this.db.run("DROP INDEX IF EXISTS idx_pending_messages_worker_pid"),this.db.run("ALTER TABLE pending_messages DROP COLUMN worker_pid"),u.debug("DB","Dropped worker_pid column and its index from pending_messages")}catch(s){u.warn("DB","Failed to drop worker_pid column from pending_messages",{},s instanceof Error?s:new Error(String(s)));return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(32,new Date().toISOString())}}ensureSDKSessionsPlatformContentIdentity(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(33),r=this.hasUniqueIndexOnColumns("sdk_sessions",["content_session_id"]),n=this.hasUniqueIndexOnColumns("sdk_sessions",["platform_source","content_session_id"]),o=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source");if(!(e&&!r&&n&&o)){if(o||this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${_}'`),this.db.run(`
|
|
443
|
+
UPDATE sdk_sessions
|
|
444
|
+
SET platform_source = '${_}'
|
|
445
|
+
WHERE platform_source IS NULL OR platform_source = ''
|
|
446
|
+
`),r){this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP TABLE IF EXISTS sdk_sessions_new"),this.db.run(`
|
|
447
|
+
CREATE TABLE sdk_sessions_new (
|
|
448
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
449
|
+
content_session_id TEXT NOT NULL,
|
|
450
|
+
memory_session_id TEXT UNIQUE,
|
|
451
|
+
project TEXT NOT NULL,
|
|
452
|
+
platform_source TEXT NOT NULL DEFAULT '${_}',
|
|
453
|
+
user_prompt TEXT,
|
|
454
|
+
started_at TEXT NOT NULL,
|
|
455
|
+
started_at_epoch INTEGER NOT NULL,
|
|
456
|
+
completed_at TEXT,
|
|
457
|
+
completed_at_epoch INTEGER,
|
|
458
|
+
status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'completed', 'failed')),
|
|
459
|
+
worker_port INTEGER,
|
|
460
|
+
prompt_counter INTEGER DEFAULT 0,
|
|
461
|
+
custom_title TEXT
|
|
462
|
+
)
|
|
463
|
+
`),this.db.run(`
|
|
464
|
+
INSERT INTO sdk_sessions_new (
|
|
465
|
+
id, content_session_id, memory_session_id, project, platform_source,
|
|
466
|
+
user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
|
|
467
|
+
status, worker_port, prompt_counter, custom_title
|
|
468
|
+
)
|
|
469
|
+
SELECT
|
|
470
|
+
id, content_session_id, memory_session_id, project,
|
|
471
|
+
COALESCE(NULLIF(platform_source, ''), '${_}'),
|
|
472
|
+
user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch,
|
|
473
|
+
status, worker_port, prompt_counter, custom_title
|
|
474
|
+
FROM sdk_sessions
|
|
475
|
+
`),this.db.run("DROP TABLE sdk_sessions"),this.db.run("ALTER TABLE sdk_sessions_new RENAME TO sdk_sessions"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString()),this.db.run("COMMIT")}catch(i){throw this.db.run("ROLLBACK"),i}finally{this.db.run("PRAGMA foreign_keys = ON")}return}this.db.run("CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(33,new Date().toISOString())}}ensureUserPromptsSessionDbId(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(34);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString());return}let s=this.db.query("PRAGMA table_info(user_prompts)").all().some(c=>c.name==="session_db_id"),i=this.db.query("PRAGMA foreign_key_list(user_prompts)").all().some(c=>c.table==="sdk_sessions"&&c.from==="content_session_id");if(e&&s&&!i)return;let a=this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='user_prompts_fts'").all().length>0,l=s?`COALESCE(up.session_db_id, (
|
|
476
|
+
SELECT s.id FROM sdk_sessions s
|
|
477
|
+
WHERE s.content_session_id = up.content_session_id
|
|
478
|
+
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${_}')
|
|
479
|
+
WHEN '${_}' THEN 0
|
|
480
|
+
ELSE 1
|
|
481
|
+
END, s.id
|
|
482
|
+
LIMIT 1
|
|
483
|
+
))`:`(
|
|
484
|
+
SELECT s.id FROM sdk_sessions s
|
|
485
|
+
WHERE s.content_session_id = up.content_session_id
|
|
486
|
+
ORDER BY CASE COALESCE(NULLIF(s.platform_source, ''), '${_}')
|
|
487
|
+
WHEN '${_}' THEN 0
|
|
488
|
+
ELSE 1
|
|
489
|
+
END, s.id
|
|
490
|
+
LIMIT 1
|
|
491
|
+
)`;this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP TRIGGER IF EXISTS user_prompts_ai"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_ad"),this.db.run("DROP TRIGGER IF EXISTS user_prompts_au"),this.db.run("DROP TABLE IF EXISTS user_prompts_new"),this.db.run(`
|
|
492
|
+
CREATE TABLE user_prompts_new (
|
|
493
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
494
|
+
session_db_id INTEGER,
|
|
495
|
+
content_session_id TEXT NOT NULL,
|
|
496
|
+
prompt_number INTEGER NOT NULL,
|
|
497
|
+
prompt_text TEXT NOT NULL,
|
|
498
|
+
created_at TEXT NOT NULL,
|
|
499
|
+
created_at_epoch INTEGER NOT NULL,
|
|
500
|
+
FOREIGN KEY(session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
|
|
501
|
+
)
|
|
502
|
+
`),this.db.run(`
|
|
503
|
+
INSERT INTO user_prompts_new (
|
|
504
|
+
id, session_db_id, content_session_id, prompt_number,
|
|
505
|
+
prompt_text, created_at, created_at_epoch
|
|
506
|
+
)
|
|
507
|
+
SELECT
|
|
508
|
+
up.id,
|
|
509
|
+
${l},
|
|
510
|
+
up.content_session_id,
|
|
511
|
+
up.prompt_number,
|
|
512
|
+
up.prompt_text,
|
|
513
|
+
up.created_at,
|
|
514
|
+
up.created_at_epoch
|
|
515
|
+
FROM user_prompts up
|
|
516
|
+
`),this.db.run("DROP TABLE user_prompts"),this.db.run("ALTER TABLE user_prompts_new RENAME TO user_prompts"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_session ON user_prompts(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_claude_session ON user_prompts(content_session_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_created ON user_prompts(created_at_epoch DESC)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_prompt_number ON user_prompts(prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number)"),a&&(this.db.run(`
|
|
517
|
+
CREATE TRIGGER user_prompts_ai AFTER INSERT ON user_prompts BEGIN
|
|
518
|
+
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
519
|
+
VALUES (new.id, new.prompt_text);
|
|
520
|
+
END;
|
|
521
|
+
|
|
522
|
+
CREATE TRIGGER user_prompts_ad AFTER DELETE ON user_prompts BEGIN
|
|
523
|
+
INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
|
|
524
|
+
VALUES('delete', old.id, old.prompt_text);
|
|
525
|
+
END;
|
|
526
|
+
|
|
527
|
+
CREATE TRIGGER user_prompts_au AFTER UPDATE ON user_prompts BEGIN
|
|
528
|
+
INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
|
|
529
|
+
VALUES('delete', old.id, old.prompt_text);
|
|
530
|
+
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
531
|
+
VALUES (new.id, new.prompt_text);
|
|
532
|
+
END;
|
|
533
|
+
`),this.db.run("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')")),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(34,new Date().toISOString()),this.db.run("COMMIT")}catch(c){throw this.db.run("ROLLBACK"),c}finally{this.db.run("PRAGMA foreign_keys = ON")}}ensurePendingMessagesSessionToolUniqueIndex(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(35);if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString());return}let n=this.hasUniqueIndexOnColumns("pending_messages",["session_db_id","tool_use_id"]);if(!(e&&n)){this.db.run("BEGIN TRANSACTION");try{this.db.run("DROP INDEX IF EXISTS ux_pending_session_tool"),this.db.run(`
|
|
534
|
+
DELETE FROM pending_messages
|
|
535
|
+
WHERE id IN (
|
|
536
|
+
SELECT id
|
|
537
|
+
FROM (
|
|
538
|
+
SELECT id,
|
|
539
|
+
ROW_NUMBER() OVER (
|
|
540
|
+
PARTITION BY session_db_id, tool_use_id
|
|
541
|
+
ORDER BY CASE status
|
|
542
|
+
WHEN 'processing' THEN 0
|
|
543
|
+
WHEN 'pending' THEN 1
|
|
544
|
+
ELSE 2
|
|
545
|
+
END, id
|
|
546
|
+
) AS duplicate_rank
|
|
547
|
+
FROM pending_messages
|
|
548
|
+
WHERE tool_use_id IS NOT NULL
|
|
549
|
+
)
|
|
550
|
+
WHERE duplicate_rank > 1
|
|
551
|
+
)
|
|
552
|
+
`),this.db.run(`
|
|
553
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
|
|
554
|
+
ON pending_messages(session_db_id, tool_use_id)
|
|
555
|
+
WHERE tool_use_id IS NOT NULL
|
|
556
|
+
`),e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(35,new Date().toISOString()),this.db.run("COMMIT")}catch(s){throw this.db.run("ROLLBACK"),s}}}dropDeadPendingMessagesColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(31),r=this.db.query("PRAGMA table_info(pending_messages)").all(),n=new Set(r.map(i=>i.name)),o=["retry_count","failed_at_epoch","completed_at_epoch"].filter(i=>n.has(i));if(!(e&&o.length===0)){if(o.length>0){this.db.run("BEGIN TRANSACTION");try{this.db.run("DELETE FROM pending_messages WHERE status NOT IN ('pending', 'processing')");for(let i of o)this.db.run(`ALTER TABLE pending_messages DROP COLUMN ${i}`),u.debug("DB",`Dropped dead column ${i} from pending_messages`);e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString()),this.db.run("COMMIT")}catch(i){this.db.run("ROLLBACK"),u.warn("DB","Failed to drop dead columns from pending_messages",{},i instanceof Error?i:new Error(String(i)));return}return}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(31,new Date().toISOString())}}initializeSchema(){this.db.run(`
|
|
557
|
+
CREATE TABLE IF NOT EXISTS schema_versions (
|
|
558
|
+
id INTEGER PRIMARY KEY,
|
|
559
|
+
version INTEGER UNIQUE NOT NULL,
|
|
560
|
+
applied_at TEXT NOT NULL
|
|
561
|
+
)
|
|
562
|
+
`),this.db.run(`
|
|
563
|
+
CREATE TABLE IF NOT EXISTS sdk_sessions (
|
|
564
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
565
|
+
content_session_id TEXT NOT NULL,
|
|
566
|
+
memory_session_id TEXT UNIQUE,
|
|
567
|
+
project TEXT NOT NULL,
|
|
568
|
+
platform_source TEXT NOT NULL DEFAULT 'claude',
|
|
569
|
+
user_prompt TEXT,
|
|
570
|
+
started_at TEXT NOT NULL,
|
|
571
|
+
started_at_epoch INTEGER NOT NULL,
|
|
572
|
+
completed_at TEXT,
|
|
573
|
+
completed_at_epoch INTEGER,
|
|
574
|
+
status TEXT CHECK(status IN ('active', 'completed', 'failed')) NOT NULL DEFAULT 'active'
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_claude_id ON sdk_sessions(content_session_id);
|
|
578
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_sdk_id ON sdk_sessions(memory_session_id);
|
|
579
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_project ON sdk_sessions(project);
|
|
580
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_status ON sdk_sessions(status);
|
|
581
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_started ON sdk_sessions(started_at_epoch DESC);
|
|
582
|
+
CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source);
|
|
583
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_sdk_sessions_platform_content ON sdk_sessions(platform_source, content_session_id);
|
|
584
|
+
|
|
585
|
+
CREATE TABLE IF NOT EXISTS observations (
|
|
586
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
587
|
+
memory_session_id TEXT NOT NULL,
|
|
588
|
+
project TEXT NOT NULL,
|
|
589
|
+
text TEXT NOT NULL,
|
|
590
|
+
type TEXT NOT NULL,
|
|
591
|
+
created_at TEXT NOT NULL,
|
|
592
|
+
created_at_epoch INTEGER NOT NULL,
|
|
593
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
CREATE INDEX IF NOT EXISTS idx_observations_sdk_session ON observations(memory_session_id);
|
|
597
|
+
CREATE INDEX IF NOT EXISTS idx_observations_project ON observations(project);
|
|
598
|
+
CREATE INDEX IF NOT EXISTS idx_observations_type ON observations(type);
|
|
599
|
+
CREATE INDEX IF NOT EXISTS idx_observations_created ON observations(created_at_epoch DESC);
|
|
600
|
+
|
|
601
|
+
CREATE TABLE IF NOT EXISTS session_summaries (
|
|
602
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
603
|
+
memory_session_id TEXT UNIQUE NOT NULL,
|
|
604
|
+
project TEXT NOT NULL,
|
|
605
|
+
request TEXT,
|
|
606
|
+
investigated TEXT,
|
|
607
|
+
learned TEXT,
|
|
608
|
+
completed TEXT,
|
|
609
|
+
next_steps TEXT,
|
|
610
|
+
files_read TEXT,
|
|
611
|
+
files_edited TEXT,
|
|
612
|
+
notes TEXT,
|
|
613
|
+
created_at TEXT NOT NULL,
|
|
614
|
+
created_at_epoch INTEGER NOT NULL,
|
|
615
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
CREATE INDEX IF NOT EXISTS idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
619
|
+
CREATE INDEX IF NOT EXISTS idx_session_summaries_project ON session_summaries(project);
|
|
620
|
+
CREATE INDEX IF NOT EXISTS idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
621
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(4,new Date().toISOString())}ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(n=>n.name==="worker_port")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN worker_port INTEGER"),u.debug("DB","Added worker_port column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(5,new Date().toISOString())}ensurePromptTrackingColumns(){this.db.query("PRAGMA table_info(sdk_sessions)").all().some(a=>a.name==="prompt_counter")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN prompt_counter INTEGER DEFAULT 0"),u.debug("DB","Added prompt_counter column to sdk_sessions table")),this.db.query("PRAGMA table_info(observations)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE observations ADD COLUMN prompt_number INTEGER"),u.debug("DB","Added prompt_number column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(a=>a.name==="prompt_number")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN prompt_number INTEGER"),u.debug("DB","Added prompt_number column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(6,new Date().toISOString())}removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index_list(session_summaries)").all().some(n=>n.unique===1&&n.origin!=="pk")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString());return}u.debug("DB","Removing UNIQUE constraint from session_summaries.memory_session_id"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS session_summaries_new"),this.db.run(`
|
|
622
|
+
CREATE TABLE session_summaries_new (
|
|
623
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
624
|
+
memory_session_id TEXT NOT NULL,
|
|
625
|
+
project TEXT NOT NULL,
|
|
626
|
+
request TEXT,
|
|
627
|
+
investigated TEXT,
|
|
628
|
+
learned TEXT,
|
|
629
|
+
completed TEXT,
|
|
630
|
+
next_steps TEXT,
|
|
631
|
+
files_read TEXT,
|
|
632
|
+
files_edited TEXT,
|
|
633
|
+
notes TEXT,
|
|
634
|
+
prompt_number INTEGER,
|
|
635
|
+
created_at TEXT NOT NULL,
|
|
636
|
+
created_at_epoch INTEGER NOT NULL,
|
|
637
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE
|
|
638
|
+
)
|
|
639
|
+
`),this.db.run(`
|
|
640
|
+
INSERT INTO session_summaries_new
|
|
641
|
+
SELECT id, memory_session_id, project, request, investigated, learned,
|
|
642
|
+
completed, next_steps, files_read, files_edited, notes,
|
|
643
|
+
prompt_number, created_at, created_at_epoch
|
|
644
|
+
FROM session_summaries
|
|
645
|
+
`),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(`
|
|
646
|
+
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
647
|
+
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
648
|
+
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
649
|
+
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(7,new Date().toISOString()),u.debug("DB","Successfully removed UNIQUE constraint from session_summaries.memory_session_id")}addObservationHierarchicalFields(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(8))return;if(this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="title")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString());return}u.debug("DB","Adding hierarchical fields to observations table"),this.db.run(`
|
|
650
|
+
ALTER TABLE observations ADD COLUMN title TEXT;
|
|
651
|
+
ALTER TABLE observations ADD COLUMN subtitle TEXT;
|
|
652
|
+
ALTER TABLE observations ADD COLUMN facts TEXT;
|
|
653
|
+
ALTER TABLE observations ADD COLUMN narrative TEXT;
|
|
654
|
+
ALTER TABLE observations ADD COLUMN concepts TEXT;
|
|
655
|
+
ALTER TABLE observations ADD COLUMN files_read TEXT;
|
|
656
|
+
ALTER TABLE observations ADD COLUMN files_modified TEXT;
|
|
657
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(8,new Date().toISOString()),u.debug("DB","Successfully added hierarchical fields to observations table")}makeObservationsTextNullable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(9))return;let n=this.db.query("PRAGMA table_info(observations)").all().find(s=>s.name==="text");if(!n||n.notnull===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString());return}u.debug("DB","Making observations.text nullable"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TABLE IF EXISTS observations_new"),this.db.run(`
|
|
658
|
+
CREATE TABLE observations_new (
|
|
659
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
660
|
+
memory_session_id TEXT NOT NULL,
|
|
661
|
+
project TEXT NOT NULL,
|
|
662
|
+
text TEXT,
|
|
663
|
+
type TEXT NOT NULL,
|
|
664
|
+
title TEXT,
|
|
665
|
+
subtitle TEXT,
|
|
666
|
+
facts TEXT,
|
|
667
|
+
narrative TEXT,
|
|
668
|
+
concepts TEXT,
|
|
669
|
+
files_read TEXT,
|
|
670
|
+
files_modified TEXT,
|
|
671
|
+
prompt_number INTEGER,
|
|
672
|
+
created_at TEXT NOT NULL,
|
|
673
|
+
created_at_epoch INTEGER NOT NULL,
|
|
674
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE
|
|
675
|
+
)
|
|
676
|
+
`),this.db.run(`
|
|
677
|
+
INSERT INTO observations_new
|
|
678
|
+
SELECT id, memory_session_id, project, text, type, title, subtitle, facts,
|
|
679
|
+
narrative, concepts, files_read, files_modified, prompt_number,
|
|
680
|
+
created_at, created_at_epoch
|
|
681
|
+
FROM observations
|
|
682
|
+
`),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(`
|
|
683
|
+
CREATE INDEX idx_observations_sdk_session ON observations(memory_session_id);
|
|
684
|
+
CREATE INDEX idx_observations_project ON observations(project);
|
|
685
|
+
CREATE INDEX idx_observations_type ON observations(type);
|
|
686
|
+
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
687
|
+
`),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(9,new Date().toISOString()),u.debug("DB","Successfully made observations.text nullable")}createUserPromptsTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(10))return;if(this.db.query("PRAGMA table_info(user_prompts)").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString());return}u.debug("DB","Creating user_prompts table with FTS5 support"),this.db.run("BEGIN TRANSACTION"),this.db.run(`
|
|
688
|
+
CREATE TABLE user_prompts (
|
|
689
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
690
|
+
session_db_id INTEGER,
|
|
691
|
+
content_session_id TEXT NOT NULL,
|
|
692
|
+
prompt_number INTEGER NOT NULL,
|
|
693
|
+
prompt_text TEXT NOT NULL,
|
|
694
|
+
created_at TEXT NOT NULL,
|
|
695
|
+
created_at_epoch INTEGER NOT NULL,
|
|
696
|
+
FOREIGN KEY(session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
CREATE INDEX idx_user_prompts_session ON user_prompts(session_db_id);
|
|
700
|
+
CREATE INDEX idx_user_prompts_claude_session ON user_prompts(content_session_id);
|
|
701
|
+
CREATE INDEX idx_user_prompts_created ON user_prompts(created_at_epoch DESC);
|
|
702
|
+
CREATE INDEX idx_user_prompts_prompt_number ON user_prompts(prompt_number);
|
|
703
|
+
CREATE INDEX idx_user_prompts_lookup ON user_prompts(session_db_id, prompt_number);
|
|
704
|
+
CREATE INDEX idx_user_prompts_content_lookup ON user_prompts(content_session_id, prompt_number);
|
|
705
|
+
`);let n=`
|
|
706
|
+
CREATE VIRTUAL TABLE user_prompts_fts USING fts5(
|
|
707
|
+
prompt_text,
|
|
708
|
+
content='user_prompts',
|
|
709
|
+
content_rowid='id'
|
|
710
|
+
);
|
|
711
|
+
`,s=`
|
|
712
|
+
CREATE TRIGGER user_prompts_ai AFTER INSERT ON user_prompts BEGIN
|
|
713
|
+
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
714
|
+
VALUES (new.id, new.prompt_text);
|
|
715
|
+
END;
|
|
716
|
+
|
|
717
|
+
CREATE TRIGGER user_prompts_ad AFTER DELETE ON user_prompts BEGIN
|
|
718
|
+
INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
|
|
719
|
+
VALUES('delete', old.id, old.prompt_text);
|
|
720
|
+
END;
|
|
721
|
+
|
|
722
|
+
CREATE TRIGGER user_prompts_au AFTER UPDATE ON user_prompts BEGIN
|
|
723
|
+
INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
|
|
724
|
+
VALUES('delete', old.id, old.prompt_text);
|
|
725
|
+
INSERT INTO user_prompts_fts(rowid, prompt_text)
|
|
726
|
+
VALUES (new.id, new.prompt_text);
|
|
727
|
+
END;
|
|
728
|
+
`;try{this.db.run(n),this.db.run(s)}catch(o){o instanceof Error?u.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},o):u.warn("DB","FTS5 not available \u2014 user_prompts_fts skipped (search uses ChromaDB)",{},new Error(String(o))),this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),u.debug("DB","Created user_prompts table (without FTS5)");return}this.db.run("COMMIT"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(10,new Date().toISOString()),u.debug("DB","Successfully created user_prompts table")}ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(11))return;this.db.query("PRAGMA table_info(observations)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE observations ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),u.debug("DB","Added discovery_tokens column to observations table")),this.db.query("PRAGMA table_info(session_summaries)").all().some(i=>i.name==="discovery_tokens")||(this.db.run("ALTER TABLE session_summaries ADD COLUMN discovery_tokens INTEGER DEFAULT 0"),u.debug("DB","Added discovery_tokens column to session_summaries table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(11,new Date().toISOString())}createPendingMessagesTable(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(16))return;if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length>0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString());return}u.debug("DB","Creating pending_messages table"),this.db.run(`
|
|
729
|
+
CREATE TABLE pending_messages (
|
|
730
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
731
|
+
session_db_id INTEGER NOT NULL,
|
|
732
|
+
content_session_id TEXT NOT NULL,
|
|
733
|
+
message_type TEXT NOT NULL CHECK(message_type IN ('observation', 'summarize')),
|
|
734
|
+
tool_name TEXT,
|
|
735
|
+
tool_input TEXT,
|
|
736
|
+
tool_response TEXT,
|
|
737
|
+
cwd TEXT,
|
|
738
|
+
last_user_message TEXT,
|
|
739
|
+
last_assistant_message TEXT,
|
|
740
|
+
prompt_number INTEGER,
|
|
741
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK(status IN ('pending', 'processing')),
|
|
742
|
+
created_at_epoch INTEGER NOT NULL,
|
|
743
|
+
FOREIGN KEY (session_db_id) REFERENCES sdk_sessions(id) ON DELETE CASCADE
|
|
744
|
+
)
|
|
745
|
+
`),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_session ON pending_messages(session_db_id)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_status ON pending_messages(status)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_pending_messages_claude_session ON pending_messages(content_session_id)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(16,new Date().toISOString()),u.debug("DB","pending_messages table created successfully")}renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(17))return;u.debug("DB","Checking session ID columns for semantic clarity rename");let r=0,n=(s,o,i)=>{let a=this.db.query(`PRAGMA table_info(${s})`).all(),l=a.some(d=>d.name===o);return a.some(d=>d.name===i)?!1:l?(this.db.run(`ALTER TABLE ${s} RENAME COLUMN ${o} TO ${i}`),u.debug("DB",`Renamed ${s}.${o} to ${i}`),!0):(u.warn("DB",`Column ${o} not found in ${s}, skipping rename`),!1)};n("sdk_sessions","claude_session_id","content_session_id")&&r++,n("sdk_sessions","sdk_session_id","memory_session_id")&&r++,n("pending_messages","claude_session_id","content_session_id")&&r++,n("observations","sdk_session_id","memory_session_id")&&r++,n("session_summaries","sdk_session_id","memory_session_id")&&r++,n("user_prompts","claude_session_id","content_session_id")&&r++,this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(17,new Date().toISOString()),r>0?u.debug("DB",`Successfully renamed ${r} session ID columns`):u.debug("DB","No session ID column renames needed (already up to date)")}repairSessionIdColumnRename(){this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(19)||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(19,new Date().toISOString())}addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(20))return;this.db.query("PRAGMA table_info(pending_messages)").all().some(s=>s.name==="failed_at_epoch")||(this.db.run("ALTER TABLE pending_messages ADD COLUMN failed_at_epoch INTEGER"),u.debug("DB","Added failed_at_epoch column to pending_messages table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(20,new Date().toISOString())}addOnUpdateCascadeToForeignKeys(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(21))return;u.debug("DB","Adding ON UPDATE CASCADE to FK constraints on observations and session_summaries"),this.db.run("PRAGMA foreign_keys = OFF"),this.db.run("BEGIN TRANSACTION"),this.db.run("DROP TRIGGER IF EXISTS observations_ai"),this.db.run("DROP TRIGGER IF EXISTS observations_ad"),this.db.run("DROP TRIGGER IF EXISTS observations_au"),this.db.run("DROP TABLE IF EXISTS observations_new");let r=this.db.query("PRAGMA table_info(observations)").all(),n=r.some(C=>C.name==="metadata"),s=r.some(C=>C.name==="content_hash"),o=n?`,
|
|
746
|
+
metadata TEXT`:"",i=n?", metadata":"",a=s?`,
|
|
747
|
+
content_hash TEXT`:"",l=s?", content_hash":"",c=`
|
|
748
|
+
CREATE TABLE observations_new (
|
|
749
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
750
|
+
memory_session_id TEXT NOT NULL,
|
|
751
|
+
project TEXT NOT NULL,
|
|
752
|
+
text TEXT,
|
|
753
|
+
type TEXT NOT NULL,
|
|
754
|
+
title TEXT,
|
|
755
|
+
subtitle TEXT,
|
|
756
|
+
facts TEXT,
|
|
757
|
+
narrative TEXT,
|
|
758
|
+
concepts TEXT,
|
|
759
|
+
files_read TEXT,
|
|
760
|
+
files_modified TEXT,
|
|
761
|
+
prompt_number INTEGER,
|
|
762
|
+
discovery_tokens INTEGER DEFAULT 0,
|
|
763
|
+
created_at TEXT NOT NULL,
|
|
764
|
+
created_at_epoch INTEGER NOT NULL${o}${a},
|
|
765
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
766
|
+
)
|
|
767
|
+
`,d=`
|
|
768
|
+
INSERT INTO observations_new
|
|
769
|
+
SELECT id, memory_session_id, project, text, type, title, subtitle, facts,
|
|
770
|
+
narrative, concepts, files_read, files_modified, prompt_number,
|
|
771
|
+
discovery_tokens, created_at, created_at_epoch${i}${l}
|
|
772
|
+
FROM observations
|
|
773
|
+
`,m=`
|
|
774
|
+
CREATE INDEX idx_observations_sdk_session ON observations(memory_session_id);
|
|
775
|
+
CREATE INDEX idx_observations_project ON observations(project);
|
|
776
|
+
CREATE INDEX idx_observations_type ON observations(type);
|
|
777
|
+
CREATE INDEX idx_observations_created ON observations(created_at_epoch DESC);
|
|
778
|
+
`,f=`
|
|
779
|
+
CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
|
|
780
|
+
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
781
|
+
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
782
|
+
END;
|
|
783
|
+
|
|
784
|
+
CREATE TRIGGER IF NOT EXISTS observations_ad AFTER DELETE ON observations BEGIN
|
|
785
|
+
INSERT INTO observations_fts(observations_fts, rowid, title, subtitle, narrative, text, facts, concepts)
|
|
786
|
+
VALUES('delete', old.id, old.title, old.subtitle, old.narrative, old.text, old.facts, old.concepts);
|
|
787
|
+
END;
|
|
788
|
+
|
|
789
|
+
CREATE TRIGGER IF NOT EXISTS observations_au AFTER UPDATE ON observations BEGIN
|
|
790
|
+
INSERT INTO observations_fts(observations_fts, rowid, title, subtitle, narrative, text, facts, concepts)
|
|
791
|
+
VALUES('delete', old.id, old.title, old.subtitle, old.narrative, old.text, old.facts, old.concepts);
|
|
792
|
+
INSERT INTO observations_fts(rowid, title, subtitle, narrative, text, facts, concepts)
|
|
793
|
+
VALUES (new.id, new.title, new.subtitle, new.narrative, new.text, new.facts, new.concepts);
|
|
794
|
+
END;
|
|
795
|
+
`;this.db.run("DROP TRIGGER IF EXISTS session_summaries_ai"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_ad"),this.db.run("DROP TRIGGER IF EXISTS session_summaries_au"),this.db.run("DROP TABLE IF EXISTS session_summaries_new");let g=`
|
|
796
|
+
CREATE TABLE session_summaries_new (
|
|
797
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
798
|
+
memory_session_id TEXT NOT NULL,
|
|
799
|
+
project TEXT NOT NULL,
|
|
800
|
+
request TEXT,
|
|
801
|
+
investigated TEXT,
|
|
802
|
+
learned TEXT,
|
|
803
|
+
completed TEXT,
|
|
804
|
+
next_steps TEXT,
|
|
805
|
+
files_read TEXT,
|
|
806
|
+
files_edited TEXT,
|
|
807
|
+
notes TEXT,
|
|
808
|
+
prompt_number INTEGER,
|
|
809
|
+
discovery_tokens INTEGER DEFAULT 0,
|
|
810
|
+
created_at TEXT NOT NULL,
|
|
811
|
+
created_at_epoch INTEGER NOT NULL,
|
|
812
|
+
FOREIGN KEY(memory_session_id) REFERENCES sdk_sessions(memory_session_id) ON DELETE CASCADE ON UPDATE CASCADE
|
|
813
|
+
)
|
|
814
|
+
`,h=`
|
|
815
|
+
INSERT INTO session_summaries_new
|
|
816
|
+
SELECT id, memory_session_id, project, request, investigated, learned,
|
|
817
|
+
completed, next_steps, files_read, files_edited, notes,
|
|
818
|
+
prompt_number, discovery_tokens, created_at, created_at_epoch
|
|
819
|
+
FROM session_summaries
|
|
820
|
+
`,S=`
|
|
821
|
+
CREATE INDEX idx_session_summaries_sdk_session ON session_summaries(memory_session_id);
|
|
822
|
+
CREATE INDEX idx_session_summaries_project ON session_summaries(project);
|
|
823
|
+
CREATE INDEX idx_session_summaries_created ON session_summaries(created_at_epoch DESC);
|
|
824
|
+
`,y=`
|
|
825
|
+
CREATE TRIGGER IF NOT EXISTS session_summaries_ai AFTER INSERT ON session_summaries BEGIN
|
|
826
|
+
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
827
|
+
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
828
|
+
END;
|
|
829
|
+
|
|
830
|
+
CREATE TRIGGER IF NOT EXISTS session_summaries_ad AFTER DELETE ON session_summaries BEGIN
|
|
831
|
+
INSERT INTO session_summaries_fts(session_summaries_fts, rowid, request, investigated, learned, completed, next_steps, notes)
|
|
832
|
+
VALUES('delete', old.id, old.request, old.investigated, old.learned, old.completed, old.next_steps, old.notes);
|
|
833
|
+
END;
|
|
834
|
+
|
|
835
|
+
CREATE TRIGGER IF NOT EXISTS session_summaries_au AFTER UPDATE ON session_summaries BEGIN
|
|
836
|
+
INSERT INTO session_summaries_fts(session_summaries_fts, rowid, request, investigated, learned, completed, next_steps, notes)
|
|
837
|
+
VALUES('delete', old.id, old.request, old.investigated, old.learned, old.completed, old.next_steps, old.notes);
|
|
838
|
+
INSERT INTO session_summaries_fts(rowid, request, investigated, learned, completed, next_steps, notes)
|
|
839
|
+
VALUES (new.id, new.request, new.investigated, new.learned, new.completed, new.next_steps, new.notes);
|
|
840
|
+
END;
|
|
841
|
+
`;try{this.recreateObservationsWithCascade(c,d,m,f),this.recreateSessionSummariesWithCascade(g,h,S,y),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(21,new Date().toISOString()),this.db.run("COMMIT"),this.db.run("PRAGMA foreign_keys = ON"),u.debug("DB","Successfully added ON UPDATE CASCADE to FK constraints")}catch(C){throw this.db.run("ROLLBACK"),this.db.run("PRAGMA foreign_keys = ON"),C instanceof Error?C:new Error(String(C))}}recreateObservationsWithCascade(e,r,n,s){this.db.run(e),this.db.run(r),this.db.run("DROP TABLE observations"),this.db.run("ALTER TABLE observations_new RENAME TO observations"),this.db.run(n),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run(s)}recreateSessionSummariesWithCascade(e,r,n,s){this.db.run(e),this.db.run(r),this.db.run("DROP TABLE session_summaries"),this.db.run("ALTER TABLE session_summaries_new RENAME TO session_summaries"),this.db.run(n),this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_summaries_fts'").all().length>0&&this.db.run(s)}addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(observations)").all().some(n=>n.name==="content_hash")){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString());return}this.db.run("ALTER TABLE observations ADD COLUMN content_hash TEXT"),this.db.run("UPDATE observations SET content_hash = substr(hex(randomblob(8)), 1, 16) WHERE content_hash IS NULL"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_content_hash ON observations(content_hash, created_at_epoch)"),u.debug("DB","Added content_hash column to observations table with backfill and index"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(22,new Date().toISOString())}addSessionCustomTitleColumn(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(23))return;this.db.query("PRAGMA table_info(sdk_sessions)").all().some(s=>s.name==="custom_title")||(this.db.run("ALTER TABLE sdk_sessions ADD COLUMN custom_title TEXT"),u.debug("DB","Added custom_title column to sdk_sessions table")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(23,new Date().toISOString())}addSessionPlatformSourceColumn(){let r=this.db.query("PRAGMA table_info(sdk_sessions)").all().some(i=>i.name==="platform_source"),s=this.db.query("PRAGMA index_list(sdk_sessions)").all().some(i=>i.name==="idx_sdk_sessions_platform_source");this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(24)&&r&&s||(r||(this.db.run(`ALTER TABLE sdk_sessions ADD COLUMN platform_source TEXT NOT NULL DEFAULT '${_}'`),u.debug("DB","Added platform_source column to sdk_sessions table")),this.db.run(`
|
|
842
|
+
UPDATE sdk_sessions
|
|
843
|
+
SET platform_source = '${_}'
|
|
844
|
+
WHERE platform_source IS NULL OR platform_source = ''
|
|
845
|
+
`),s||this.db.run("CREATE INDEX IF NOT EXISTS idx_sdk_sessions_platform_source ON sdk_sessions(platform_source)"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(24,new Date().toISOString()))}addObservationModelColumns(){let e=this.db.query("PRAGMA table_info(observations)").all(),r=e.some(s=>s.name==="generated_by_model"),n=e.some(s=>s.name==="relevance_count");r&&n||(r||this.db.run("ALTER TABLE observations ADD COLUMN generated_by_model TEXT"),n||this.db.run("ALTER TABLE observations ADD COLUMN relevance_count INTEGER DEFAULT 0"),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(26,new Date().toISOString()))}ensureMergedIntoProjectColumns(){this.db.query("PRAGMA table_info(observations)").all().some(n=>n.name==="merged_into_project")||this.db.run("ALTER TABLE observations ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)"),this.db.query("PRAGMA table_info(session_summaries)").all().some(n=>n.name==="merged_into_project")||this.db.run("ALTER TABLE session_summaries ADD COLUMN merged_into_project TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)")}addObservationSubagentColumns(){let e=this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(27),r=this.db.query("PRAGMA table_info(observations)").all(),n=r.some(i=>i.name==="agent_type"),s=r.some(i=>i.name==="agent_id");n||this.db.run("ALTER TABLE observations ADD COLUMN agent_type TEXT"),s||this.db.run("ALTER TABLE observations ADD COLUMN agent_id TEXT"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_type ON observations(agent_type)"),this.db.run("CREATE INDEX IF NOT EXISTS idx_observations_agent_id ON observations(agent_id)");let o=this.db.query("PRAGMA table_info(pending_messages)").all();if(o.length>0){let i=o.some(l=>l.name==="agent_type"),a=o.some(l=>l.name==="agent_id");i||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_type TEXT"),a||this.db.run("ALTER TABLE pending_messages ADD COLUMN agent_id TEXT")}e||this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(27,new Date().toISOString())}ensurePendingMessagesToolUseIdColumn(){if(this.db.query("SELECT name FROM sqlite_master WHERE type='table' AND name='pending_messages'").all().length===0){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString());return}this.db.query("PRAGMA table_info(pending_messages)").all().some(s=>s.name==="tool_use_id")||this.db.run("ALTER TABLE pending_messages ADD COLUMN tool_use_id TEXT"),this.db.run("BEGIN TRANSACTION");try{this.db.run(`
|
|
846
|
+
DELETE FROM pending_messages
|
|
847
|
+
WHERE id IN (
|
|
848
|
+
SELECT id
|
|
849
|
+
FROM (
|
|
850
|
+
SELECT id,
|
|
851
|
+
ROW_NUMBER() OVER (
|
|
852
|
+
PARTITION BY session_db_id, tool_use_id
|
|
853
|
+
ORDER BY CASE status
|
|
854
|
+
WHEN 'processing' THEN 0
|
|
855
|
+
WHEN 'pending' THEN 1
|
|
856
|
+
ELSE 2
|
|
857
|
+
END, id
|
|
858
|
+
) AS duplicate_rank
|
|
859
|
+
FROM pending_messages
|
|
860
|
+
WHERE tool_use_id IS NOT NULL
|
|
861
|
+
)
|
|
862
|
+
WHERE duplicate_rank > 1
|
|
863
|
+
)
|
|
864
|
+
`),this.db.run(`
|
|
865
|
+
-- tool_use_id is optional for summaries and legacy rows; enforce de-dupe
|
|
866
|
+
-- only for rows that came from a concrete tool-use event.
|
|
867
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_pending_session_tool
|
|
868
|
+
ON pending_messages(session_db_id, tool_use_id)
|
|
869
|
+
WHERE tool_use_id IS NOT NULL
|
|
870
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(28,new Date().toISOString()),this.db.run("COMMIT")}catch(s){throw this.db.run("ROLLBACK"),s}}addObservationsUniqueContentHashIndex(){if(this.db.prepare("SELECT version FROM schema_versions WHERE version = ?").get(29))return;let r=this.db.query("PRAGMA table_info(observations)").all(),n=r.some(o=>o.name==="memory_session_id"),s=r.some(o=>o.name==="content_hash");if(!n||!s){this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString());return}this.db.run("BEGIN TRANSACTION");try{this.db.run(`
|
|
871
|
+
UPDATE observations
|
|
872
|
+
SET content_hash = '__null_migration_' || id || '__'
|
|
873
|
+
WHERE content_hash IS NULL
|
|
874
|
+
`),this.db.run(`
|
|
875
|
+
DELETE FROM observations
|
|
876
|
+
WHERE id IN (
|
|
877
|
+
SELECT id
|
|
878
|
+
FROM (
|
|
879
|
+
SELECT id,
|
|
880
|
+
ROW_NUMBER() OVER (
|
|
881
|
+
PARTITION BY memory_session_id, content_hash
|
|
882
|
+
ORDER BY id
|
|
883
|
+
) AS duplicate_rank
|
|
884
|
+
FROM observations
|
|
885
|
+
)
|
|
886
|
+
WHERE duplicate_rank > 1
|
|
887
|
+
)
|
|
888
|
+
`),this.db.run(`
|
|
889
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ux_observations_session_hash
|
|
890
|
+
ON observations(memory_session_id, content_hash)
|
|
891
|
+
`),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(29,new Date().toISOString()),this.db.run("COMMIT")}catch(o){throw this.db.run("ROLLBACK"),o}}addObservationsMetadataColumn(){this.db.query("PRAGMA table_info(observations)").all().some(n=>n.name==="metadata")||(this.db.run("ALTER TABLE observations ADD COLUMN metadata TEXT"),u.debug("DB","Added metadata column to observations table (#2116)")),this.db.prepare("INSERT OR IGNORE INTO schema_versions (version, applied_at) VALUES (?, ?)").run(30,new Date().toISOString())}updateMemorySessionId(e,r){this.db.prepare(`
|
|
892
|
+
UPDATE sdk_sessions
|
|
893
|
+
SET memory_session_id = ?
|
|
894
|
+
WHERE id = ?
|
|
895
|
+
`).run(r,e)}markSessionCompleted(e){let r=Date.now(),n=new Date(r).toISOString();this.db.prepare(`
|
|
896
|
+
UPDATE sdk_sessions
|
|
897
|
+
SET status = 'completed', completed_at = ?, completed_at_epoch = ?
|
|
898
|
+
WHERE id = ?
|
|
899
|
+
`).run(n,r,e)}ensureMemorySessionIdRegistered(e,r,n){let s=this.db.prepare(`
|
|
900
|
+
SELECT id, memory_session_id, worker_port FROM sdk_sessions WHERE id = ?
|
|
901
|
+
`).get(e);if(!s)throw new Error(`Session ${e} not found in sdk_sessions`);s.memory_session_id!==r&&(this.db.prepare(`
|
|
902
|
+
UPDATE sdk_sessions SET memory_session_id = ? WHERE id = ?
|
|
903
|
+
`).run(r,e),u.info("DB","Registered memory_session_id before storage (FK fix)",{sessionDbId:e,oldId:s.memory_session_id,newId:r})),typeof n=="number"&&s.worker_port!==n&&this.db.prepare(`
|
|
904
|
+
UPDATE sdk_sessions SET worker_port = ? WHERE id = ?
|
|
905
|
+
`).run(n,e)}getRecentSummaries(e,r=10){return this.db.prepare(`
|
|
906
|
+
SELECT
|
|
907
|
+
request, investigated, learned, completed, next_steps,
|
|
908
|
+
files_read, files_edited, notes, prompt_number, created_at
|
|
909
|
+
FROM session_summaries
|
|
910
|
+
WHERE project = ?
|
|
911
|
+
ORDER BY created_at_epoch DESC
|
|
912
|
+
LIMIT ?
|
|
913
|
+
`).all(e,r)}getRecentSummariesWithSessionInfo(e,r=3){return this.db.prepare(`
|
|
914
|
+
SELECT
|
|
915
|
+
memory_session_id, request, learned, completed, next_steps,
|
|
916
|
+
prompt_number, created_at
|
|
917
|
+
FROM session_summaries
|
|
918
|
+
WHERE project = ?
|
|
919
|
+
ORDER BY created_at_epoch DESC
|
|
920
|
+
LIMIT ?
|
|
921
|
+
`).all(e,r)}getRecentObservations(e,r=20){return this.db.prepare(`
|
|
922
|
+
SELECT type, text, prompt_number, created_at
|
|
923
|
+
FROM observations
|
|
924
|
+
WHERE project = ?
|
|
925
|
+
ORDER BY created_at_epoch DESC
|
|
926
|
+
LIMIT ?
|
|
927
|
+
`).all(e,r)}getAllRecentObservations(e=100){return this.db.prepare(`
|
|
928
|
+
SELECT
|
|
929
|
+
o.id,
|
|
930
|
+
o.type,
|
|
931
|
+
o.title,
|
|
932
|
+
o.subtitle,
|
|
933
|
+
o.text,
|
|
934
|
+
o.project,
|
|
935
|
+
COALESCE(s.platform_source, '${_}') as platform_source,
|
|
936
|
+
o.prompt_number,
|
|
937
|
+
o.created_at,
|
|
938
|
+
o.created_at_epoch
|
|
939
|
+
FROM observations o
|
|
940
|
+
LEFT JOIN sdk_sessions s ON o.memory_session_id = s.memory_session_id
|
|
941
|
+
ORDER BY o.created_at_epoch DESC
|
|
942
|
+
LIMIT ?
|
|
943
|
+
`).all(e)}getAllRecentSummaries(e=50){return this.db.prepare(`
|
|
944
|
+
SELECT
|
|
945
|
+
ss.id,
|
|
946
|
+
ss.request,
|
|
947
|
+
ss.investigated,
|
|
948
|
+
ss.learned,
|
|
949
|
+
ss.completed,
|
|
950
|
+
ss.next_steps,
|
|
951
|
+
ss.files_read,
|
|
952
|
+
ss.files_edited,
|
|
953
|
+
ss.notes,
|
|
954
|
+
ss.project,
|
|
955
|
+
COALESCE(s.platform_source, '${_}') as platform_source,
|
|
956
|
+
ss.prompt_number,
|
|
957
|
+
ss.created_at,
|
|
958
|
+
ss.created_at_epoch
|
|
959
|
+
FROM session_summaries ss
|
|
960
|
+
LEFT JOIN sdk_sessions s ON ss.memory_session_id = s.memory_session_id
|
|
961
|
+
ORDER BY ss.created_at_epoch DESC
|
|
962
|
+
LIMIT ?
|
|
963
|
+
`).all(e)}getAllRecentUserPrompts(e=100){return this.db.prepare(`
|
|
964
|
+
SELECT
|
|
965
|
+
up.id,
|
|
966
|
+
up.content_session_id,
|
|
967
|
+
s.project,
|
|
968
|
+
COALESCE(s.platform_source, '${_}') as platform_source,
|
|
969
|
+
up.prompt_number,
|
|
970
|
+
up.prompt_text,
|
|
971
|
+
up.created_at,
|
|
972
|
+
up.created_at_epoch
|
|
973
|
+
FROM user_prompts up
|
|
974
|
+
LEFT JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
975
|
+
ORDER BY up.created_at_epoch DESC
|
|
976
|
+
LIMIT ?
|
|
977
|
+
`).all(e)}getAllProjects(e){let r=e?ue(e):void 0,n=`
|
|
978
|
+
SELECT DISTINCT project
|
|
979
|
+
FROM sdk_sessions
|
|
980
|
+
WHERE project IS NOT NULL AND project != ''
|
|
981
|
+
AND project != ?
|
|
982
|
+
`,s=[_s];return r&&(n+=" AND COALESCE(platform_source, ?) = ?",s.push(_,r)),n+=" ORDER BY project ASC",this.db.prepare(n).all(...s).map(i=>i.project)}getProjectCatalog(){let e=this.db.prepare(`
|
|
983
|
+
SELECT
|
|
984
|
+
COALESCE(platform_source, '${_}') as platform_source,
|
|
985
|
+
project,
|
|
986
|
+
MAX(started_at_epoch) as latest_epoch
|
|
987
|
+
FROM sdk_sessions
|
|
988
|
+
WHERE project IS NOT NULL AND project != ''
|
|
989
|
+
AND project != ?
|
|
990
|
+
GROUP BY COALESCE(platform_source, '${_}'), project
|
|
991
|
+
ORDER BY latest_epoch DESC
|
|
992
|
+
`).all(_s),r=[],n=new Set,s={};for(let i of e){let a=ue(i.platform_source);s[a]||(s[a]=[]),s[a].includes(i.project)||s[a].push(i.project),n.has(i.project)||(n.add(i.project),r.push(i.project))}let o=nu(Object.keys(s));return{projects:r,sources:o,projectsBySource:Object.fromEntries(o.map(i=>[i,s[i]||[]]))}}getLatestUserPrompt(e,r){let n=this.resolvePromptSessionDbId(e,r),s=n!==null?"up.session_db_id = ?":"up.content_session_id = ?",o=n!==null?n:e;return this.db.prepare(`
|
|
993
|
+
SELECT
|
|
994
|
+
up.*,
|
|
995
|
+
s.memory_session_id,
|
|
996
|
+
s.project,
|
|
997
|
+
COALESCE(s.platform_source, '${_}') as platform_source
|
|
998
|
+
FROM user_prompts up
|
|
999
|
+
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
1000
|
+
WHERE ${s}
|
|
1001
|
+
ORDER BY up.created_at_epoch DESC
|
|
1002
|
+
LIMIT 1
|
|
1003
|
+
`).get(o)}findRecentDuplicateUserPrompt(e,r,n,s){return su(this.db,e,Jn(r),n,this.resolvePromptSessionDbId(e,s)??void 0)}getRecentSessionsWithStatus(e,r=3,n){let s=[e],o="";return n&&(o=`AND COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?`,s.push(ue(n))),s.push(r),this.db.prepare(`
|
|
1004
|
+
SELECT * FROM (
|
|
1005
|
+
SELECT
|
|
1006
|
+
s.memory_session_id,
|
|
1007
|
+
s.status,
|
|
1008
|
+
s.started_at,
|
|
1009
|
+
s.started_at_epoch,
|
|
1010
|
+
s.user_prompt,
|
|
1011
|
+
CASE WHEN sum.memory_session_id IS NOT NULL THEN 1 ELSE 0 END as has_summary
|
|
1012
|
+
FROM sdk_sessions s
|
|
1013
|
+
LEFT JOIN session_summaries sum ON s.memory_session_id = sum.memory_session_id
|
|
1014
|
+
WHERE s.project = ? AND s.memory_session_id IS NOT NULL
|
|
1015
|
+
${o}
|
|
1016
|
+
GROUP BY s.memory_session_id
|
|
1017
|
+
ORDER BY s.started_at_epoch DESC
|
|
1018
|
+
LIMIT ?
|
|
1019
|
+
)
|
|
1020
|
+
ORDER BY started_at_epoch ASC
|
|
1021
|
+
`).all(...s)}getObservationsForSession(e,r){let n=[e],s="";return r&&(s=`
|
|
1022
|
+
AND EXISTS (
|
|
1023
|
+
SELECT 1
|
|
1024
|
+
FROM sdk_sessions s
|
|
1025
|
+
WHERE s.memory_session_id = observations.memory_session_id
|
|
1026
|
+
AND COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?
|
|
1027
|
+
)
|
|
1028
|
+
`,n.push(ue(r))),this.db.prepare(`
|
|
1029
|
+
SELECT title, subtitle, type, prompt_number
|
|
1030
|
+
FROM observations
|
|
1031
|
+
WHERE memory_session_id = ?
|
|
1032
|
+
${s}
|
|
1033
|
+
ORDER BY created_at_epoch ASC
|
|
1034
|
+
`).all(...n)}getObservationById(e,r){return r?this.db.prepare(`
|
|
1035
|
+
SELECT o.*
|
|
1036
|
+
FROM observations o
|
|
1037
|
+
LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
|
|
1038
|
+
WHERE o.id = ?
|
|
1039
|
+
AND COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?
|
|
1040
|
+
`).get(e,ue(r))||null:this.db.prepare(`
|
|
1041
|
+
SELECT *
|
|
1042
|
+
FROM observations
|
|
1043
|
+
WHERE id = ?
|
|
1044
|
+
`).get(e)||null}getObservationsByIds(e,r={}){if(e.length===0)return[];let{orderBy:n="date_desc",limit:s,project:o,platformSource:i,type:a,concepts:l,files:c}=r,d=n==="relevance",m=d?"":`ORDER BY o.created_at_epoch ${n==="date_asc"?"ASC":"DESC"}`,f=s&&!d?`LIMIT ${s}`:"",g=e.map(()=>"?").join(","),h=[...e],S=[];if(o&&(S.push("o.project = ?"),h.push(o)),i&&(S.push(`COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?`),h.push(ue(i))),a)if(Array.isArray(a)){let T=a.map(()=>"?").join(",");S.push(`o.type IN (${T})`),h.push(...a)}else S.push("o.type = ?"),h.push(a);if(l){let T=Array.isArray(l)?l:[l],v=T.map(()=>"EXISTS (SELECT 1 FROM json_each(o.concepts) WHERE value = ?)");h.push(...T),S.push(`(${v.join(" OR ")})`)}if(c){let T=Array.isArray(c)?c:[c],v=T.map(()=>"(EXISTS (SELECT 1 FROM json_each(o.files_read) WHERE value LIKE ?) OR EXISTS (SELECT 1 FROM json_each(o.files_modified) WHERE value LIKE ?))");T.forEach(I=>{h.push(`%${I}%`,`%${I}%`)}),S.push(`(${v.join(" OR ")})`)}let y=S.length>0?`WHERE o.id IN (${g}) AND ${S.join(" AND ")}`:`WHERE o.id IN (${g})`,N=this.db.prepare(`
|
|
1045
|
+
SELECT o.*
|
|
1046
|
+
FROM observations o
|
|
1047
|
+
LEFT JOIN sdk_sessions s ON s.memory_session_id = o.memory_session_id
|
|
1048
|
+
${y}
|
|
1049
|
+
${m}
|
|
1050
|
+
${f}
|
|
1051
|
+
`).all(...h);if(!d)return N;let D=new Map(N.map(T=>[T.id,T])),R=e.map(T=>D.get(T)).filter(T=>!!T);return s?R.slice(0,s):R}getSummaryForSession(e,r){let n=[e],s="";return r&&(s=`
|
|
1052
|
+
AND EXISTS (
|
|
1053
|
+
SELECT 1
|
|
1054
|
+
FROM sdk_sessions sdk
|
|
1055
|
+
WHERE sdk.memory_session_id = session_summaries.memory_session_id
|
|
1056
|
+
AND COALESCE(NULLIF(sdk.platform_source, ''), '${_}') = ?
|
|
1057
|
+
)
|
|
1058
|
+
`,n.push(ue(r))),this.db.prepare(`
|
|
1059
|
+
SELECT
|
|
1060
|
+
request, investigated, learned, completed, next_steps,
|
|
1061
|
+
files_read, files_edited, notes, prompt_number, created_at,
|
|
1062
|
+
created_at_epoch
|
|
1063
|
+
FROM session_summaries
|
|
1064
|
+
WHERE memory_session_id = ?
|
|
1065
|
+
${s}
|
|
1066
|
+
ORDER BY created_at_epoch DESC
|
|
1067
|
+
LIMIT 1
|
|
1068
|
+
`).get(...n)||null}getFilesForSession(e){let n=this.db.prepare(`
|
|
1069
|
+
SELECT files_read, files_modified
|
|
1070
|
+
FROM observations
|
|
1071
|
+
WHERE memory_session_id = ?
|
|
1072
|
+
`).all(e),s=new Set,o=new Set;for(let i of n)Yo(i.files_read).forEach(a=>s.add(a)),Yo(i.files_modified).forEach(a=>o.add(a));return{filesRead:Array.from(s),filesModified:Array.from(o)}}getSessionById(e){return this.db.prepare(`
|
|
1073
|
+
SELECT id, content_session_id, memory_session_id, project,
|
|
1074
|
+
COALESCE(platform_source, '${_}') as platform_source,
|
|
1075
|
+
user_prompt, custom_title, status
|
|
1076
|
+
FROM sdk_sessions
|
|
1077
|
+
WHERE id = ?
|
|
1078
|
+
LIMIT 1
|
|
1079
|
+
`).get(e)||null}getSdkSessionsBySessionIds(e){if(e.length===0)return[];let r=e.map(()=>"?").join(",");return this.db.prepare(`
|
|
1080
|
+
SELECT id, content_session_id, memory_session_id, project,
|
|
1081
|
+
COALESCE(platform_source, '${_}') as platform_source,
|
|
1082
|
+
user_prompt, custom_title,
|
|
1083
|
+
started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
1084
|
+
FROM sdk_sessions
|
|
1085
|
+
WHERE memory_session_id IN (${r})
|
|
1086
|
+
ORDER BY started_at_epoch DESC
|
|
1087
|
+
`).all(...e)}getPromptNumberFromUserPrompts(e,r){let n=this.resolvePromptSessionDbId(e,r);return n!==null?this.db.prepare(`
|
|
1088
|
+
SELECT COUNT(*) as count FROM user_prompts WHERE session_db_id = ?
|
|
1089
|
+
`).get(n).count:this.db.prepare(`
|
|
1090
|
+
SELECT COUNT(*) as count FROM user_prompts WHERE content_session_id = ?
|
|
1091
|
+
`).get(e).count}createSDKSession(e,r,n,s,o){let i=new Date,a=i.getTime(),l=Ih(s,o),c=l.platformSource??_,d=this.rt(Jn(n)),m=this.db.prepare(`
|
|
1092
|
+
SELECT id, platform_source
|
|
1093
|
+
FROM sdk_sessions
|
|
1094
|
+
WHERE COALESCE(NULLIF(platform_source, ''), ?) = ?
|
|
1095
|
+
AND content_session_id = ?
|
|
1096
|
+
`).get(_,c,e);if(m)return r&&this.db.prepare(`
|
|
1097
|
+
UPDATE sdk_sessions SET project = ?
|
|
1098
|
+
WHERE id = ? AND (project IS NULL OR project = '')
|
|
1099
|
+
`).run(r,m.id),l.customTitle&&this.db.prepare(`
|
|
1100
|
+
UPDATE sdk_sessions SET custom_title = ?
|
|
1101
|
+
WHERE id = ? AND custom_title IS NULL
|
|
1102
|
+
`).run(l.customTitle,m.id),m.id;let f=this.db.prepare(`
|
|
1103
|
+
INSERT INTO sdk_sessions
|
|
1104
|
+
(content_session_id, memory_session_id, project, platform_source, user_prompt, custom_title, started_at, started_at_epoch, status)
|
|
1105
|
+
VALUES (?, NULL, ?, ?, ?, ?, ?, ?, 'active')
|
|
1106
|
+
`).run(e,r,c,d,l.customTitle||null,i.toISOString(),a);return Number(f.lastInsertRowid)}saveUserPrompt(e,r,n,s){let o=new Date,i=o.getTime(),a=this.rt(Jn(n)),l=this.resolvePromptSessionDbId(e,s);return this.db.prepare(`
|
|
1107
|
+
INSERT INTO user_prompts
|
|
1108
|
+
(session_db_id, content_session_id, prompt_number, prompt_text, created_at, created_at_epoch)
|
|
1109
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
1110
|
+
`).run(l,e,r,a,o.toISOString(),i).lastInsertRowid}getUserPrompt(e,r,n){let s=this.resolvePromptSessionDbId(e,n);return s!==null?this.db.prepare(`
|
|
1111
|
+
SELECT prompt_text
|
|
1112
|
+
FROM user_prompts
|
|
1113
|
+
WHERE session_db_id = ? AND prompt_number = ?
|
|
1114
|
+
LIMIT 1
|
|
1115
|
+
`).get(s,r)?.prompt_text??null:this.db.prepare(`
|
|
1116
|
+
SELECT prompt_text
|
|
1117
|
+
FROM user_prompts
|
|
1118
|
+
WHERE content_session_id = ? AND prompt_number = ?
|
|
1119
|
+
LIMIT 1
|
|
1120
|
+
`).get(e,r)?.prompt_text??null}storeObservation(e,r,n,s,o=0,i,a){let l=i??Date.now(),c=new Date(l).toISOString(),d=this.rt(n.title),m=this.rt(n.subtitle),f=this.rt(n.narrative),g=this.rl(n.facts),h=this.rt(n.metadata??null),S=Vo(e,d??null,f??null),y=$o({type:n.type,narrative:f,files_modified:n.files_modified}),C;if(this.mq.reconcile.enabled){let T=this.reconcileBeforeInsert(r,n.type,d??null,f??null);if(T.action==="NOOP"&&T.candidateId){let v=this.db.prepare("SELECT id, created_at_epoch FROM observations WHERE id = ?").get(T.candidateId);if(v)return{id:v.id,createdAtEpoch:v.created_at_epoch}}else T.action==="UPDATE"&&(C=T.candidateId)}let D=this.db.prepare(`
|
|
1121
|
+
INSERT INTO observations
|
|
1122
|
+
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
1123
|
+
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
1124
|
+
generated_by_model, metadata, importance, valid_from, subject_key)
|
|
1125
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1126
|
+
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
1127
|
+
RETURNING id, created_at_epoch
|
|
1128
|
+
`).get(e,r,n.type,d,m,JSON.stringify(g),f,JSON.stringify(n.concepts),JSON.stringify(n.files_read),JSON.stringify(n.files_modified),s||null,o,n.agent_type??null,n.agent_id??null,S,c,l,a||null,h,y,l,ti({title:d??null,facts:g,narrative:f??null}));if(D)return C!==void 0&&this.mq.supersession.enabled&&this.supersedeObservation(C,D.id,l),{id:D.id,createdAtEpoch:D.created_at_epoch};let R=this.db.prepare("SELECT id, created_at_epoch FROM observations WHERE memory_session_id = ? AND content_hash = ?").get(e,S);if(!R)throw new Error(`storeObservation: ON CONFLICT without existing row for content_hash=${S}`);return{id:R.id,createdAtEpoch:R.created_at_epoch}}storeSummary(e,r,n,s,o=0,i){let a=i??Date.now(),l=new Date(a).toISOString(),d=this.db.prepare(`
|
|
1129
|
+
INSERT INTO session_summaries
|
|
1130
|
+
(memory_session_id, project, request, investigated, learned, completed,
|
|
1131
|
+
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
1132
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1133
|
+
`).run(e,r,this.rt(n.request),this.rt(n.investigated),this.rt(n.learned),this.rt(n.completed),this.rt(n.next_steps),this.rt(n.notes),s||null,o,l,a);return{id:Number(d.lastInsertRowid),createdAtEpoch:a}}storeObservations(e,r,n,s,o,i=0,a,l){let c=a??Date.now(),d=new Date(c).toISOString();return this.db.transaction(()=>{let f=[],g=this.db.prepare(`
|
|
1134
|
+
INSERT INTO observations
|
|
1135
|
+
(memory_session_id, project, type, title, subtitle, facts, narrative, concepts,
|
|
1136
|
+
files_read, files_modified, prompt_number, discovery_tokens, agent_type, agent_id, content_hash, created_at, created_at_epoch,
|
|
1137
|
+
generated_by_model, importance, valid_from, subject_key)
|
|
1138
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1139
|
+
ON CONFLICT(memory_session_id, content_hash) DO NOTHING
|
|
1140
|
+
RETURNING id
|
|
1141
|
+
`),h=this.db.prepare("SELECT id FROM observations WHERE memory_session_id = ? AND content_hash = ?");for(let y of n){let C=this.rt(y.title),N=this.rt(y.subtitle),D=this.rt(y.narrative),R=this.rl(y.facts),T=Vo(e,C??null,D??null),v=g.get(e,r,y.type,C,N,JSON.stringify(R),D,JSON.stringify(y.concepts),JSON.stringify(y.files_read),JSON.stringify(y.files_modified),o||null,i,y.agent_type??null,y.agent_id??null,T,d,c,l||null,$o({type:y.type,narrative:D,files_modified:y.files_modified}),c,ti({title:C??null,facts:R,narrative:D??null}));if(v){f.push(v.id);continue}let I=h.get(e,T);if(!I)throw new Error(`storeObservations: ON CONFLICT without existing row for content_hash=${T}`);f.push(I.id)}let S=null;if(s){let C=this.db.prepare(`
|
|
1142
|
+
INSERT INTO session_summaries
|
|
1143
|
+
(memory_session_id, project, request, investigated, learned, completed,
|
|
1144
|
+
next_steps, notes, prompt_number, discovery_tokens, created_at, created_at_epoch)
|
|
1145
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1146
|
+
`).run(e,r,this.rt(s.request),this.rt(s.investigated),this.rt(s.learned),this.rt(s.completed),this.rt(s.next_steps),this.rt(s.notes),o||null,i,d,c);S=Number(C.lastInsertRowid)}return{observationIds:f,summaryId:S,createdAtEpoch:c}})()}markObservationsUsed(e,r=Date.now()){if(e.length!==0)try{if(!this.db.query("PRAGMA table_info(observations)").all().some(o=>o.name==="last_used_at"))return;let s=e.map(()=>"?").join(",");this.db.prepare(`UPDATE observations SET last_used_at = ? WHERE id IN (${s})`).run(r,...e)}catch(n){u.debug("DB","markObservationsUsed failed",{count:e.length},n instanceof Error?n:new Error(String(n)))}}evaporateScratch(e){try{let r=this.db.prepare("DELETE FROM observations WHERE memory_session_id = ? AND type = 'scratch'").run(e),n=Number(r.changes??0);return n>0&&u.info("DB","Evaporated scratch observations at SessionEnd",{memorySessionId:e,count:n}),n}catch(r){return u.warn("DB","evaporateScratch failed",{memorySessionId:e},r instanceof Error?r:new Error(String(r))),0}}reconcileBeforeInsert(e,r,n,s){try{let o=Date.now()-7776e6,i=this.db.query("PRAGMA table_info(observations)").all().some(m=>m.name==="valid_to"),a=i?"AND valid_to IS NULL":"",l=this.db.prepare(`
|
|
1147
|
+
SELECT id, title, narrative, importance
|
|
1148
|
+
FROM observations
|
|
1149
|
+
WHERE project = ? AND type = ? AND created_at_epoch >= ? ${a}
|
|
1150
|
+
ORDER BY created_at_epoch DESC
|
|
1151
|
+
LIMIT 20
|
|
1152
|
+
`).all(e,r,o);if(l.length===0)return{action:"ADD"};let c=this.mq.supersession.enabled&&i;return tu({title:n,narrative:s},l,{noopThreshold:this.mq.reconcile.noopThreshold,updateBand:this.mq.reconcile.updateBand,supersessionEnabled:c})}catch(o){return u.warn("DB","reconcileBeforeInsert failed; defaulting to ADD",{project:e,type:r},o instanceof Error?o:new Error(String(o))),{action:"ADD"}}}supersedeObservation(e,r,n){try{this.db.prepare(`
|
|
1153
|
+
UPDATE observations
|
|
1154
|
+
SET valid_to = ?,
|
|
1155
|
+
metadata = json_set(COALESCE(metadata, '{}'), '$.superseded_by', ?)
|
|
1156
|
+
WHERE id = ? AND valid_to IS NULL
|
|
1157
|
+
`).run(n,r,e)}catch(s){u.warn("DB","supersedeObservation failed",{oldId:e,newId:r},s instanceof Error?s:new Error(String(s)))}}getObservationsAsOf(e,r){return this.db.query("PRAGMA table_info(observations)").all().some(s=>s.name==="valid_from")?this.db.prepare(`
|
|
1158
|
+
SELECT * FROM observations
|
|
1159
|
+
WHERE project = ?
|
|
1160
|
+
AND COALESCE(valid_from, created_at_epoch) <= ?
|
|
1161
|
+
AND (valid_to IS NULL OR valid_to > ?)
|
|
1162
|
+
`).all(e,r,r):this.db.prepare("SELECT * FROM observations WHERE project = ?").all(e)}deleteObservationsByProject(e,r={}){let n=(e??"").trim();if(n===""||n==="*")throw new Error(`deleteObservationsByProject: refusing unsafe project '${e}'`);let s=this.db.prepare("SELECT count(*) AS c FROM observations WHERE project = ?").get(n).c,o=this.db.prepare("SELECT count(*) AS c FROM session_summaries WHERE project = ?").get(n).c;if(r.dryRun)return{project:n,dryRun:!0,observationsDeleted:s,summariesDeleted:o};this.db.transaction(()=>{this.db.prepare("DELETE FROM observations WHERE project = ?").run(n),this.db.prepare("DELETE FROM session_summaries WHERE project = ?").run(n)})();try{this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}catch(a){u.warn("DB","observations_fts rebuild after project delete failed",{project:n},a instanceof Error?a:new Error(String(a)))}return u.info("DB","Deleted observations by project",{project:n,observationsDeleted:s,summariesDeleted:o}),{project:n,dryRun:!1,observationsDeleted:s,summariesDeleted:o}}getSessionSummariesByIds(e,r={}){if(e.length===0)return[];let{orderBy:n="date_desc",limit:s,project:o,platformSource:i}=r,a=n==="relevance",l=a?"":`ORDER BY ss.created_at_epoch ${n==="date_asc"?"ASC":"DESC"}`,c=s&&!a?`LIMIT ${s}`:"",d=e.map(()=>"?").join(","),m=[...e],f=[];o&&(f.push("ss.project = ?"),m.push(o)),i&&(f.push(`COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?`),m.push(ue(i)));let g=f.length>0?`AND ${f.join(" AND ")}`:"",S=this.db.prepare(`
|
|
1163
|
+
SELECT ss.*
|
|
1164
|
+
FROM session_summaries ss
|
|
1165
|
+
LEFT JOIN sdk_sessions s ON s.memory_session_id = ss.memory_session_id
|
|
1166
|
+
WHERE ss.id IN (${d}) ${g}
|
|
1167
|
+
${l}
|
|
1168
|
+
${c}
|
|
1169
|
+
`).all(...m);if(!a)return S;let y=new Map(S.map(N=>[N.id,N])),C=e.map(N=>y.get(N)).filter(N=>!!N);return s?C.slice(0,s):C}getUserPromptsByIds(e,r={}){if(e.length===0)return[];let{orderBy:n="date_desc",limit:s,project:o,platformSource:i}=r,a=n==="relevance",l=a?"":`ORDER BY up.created_at_epoch ${n==="date_asc"?"ASC":"DESC"}`,c=s?`LIMIT ${s}`:"",d=e.map(()=>"?").join(","),m=[...e],f=[];o&&(f.push("s.project = ?"),m.push(o)),i&&(f.push(`COALESCE(NULLIF(s.platform_source, ''), '${_}') = ?`),m.push(ue(i)));let g=f.length>0?`AND ${f.join(" AND ")}`:"",S=this.db.prepare(`
|
|
1170
|
+
SELECT
|
|
1171
|
+
up.*,
|
|
1172
|
+
s.project,
|
|
1173
|
+
s.memory_session_id,
|
|
1174
|
+
COALESCE(NULLIF(s.platform_source, ''), '${_}') as platform_source
|
|
1175
|
+
FROM user_prompts up
|
|
1176
|
+
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
1177
|
+
WHERE up.id IN (${d}) ${g}
|
|
1178
|
+
${l}
|
|
1179
|
+
${c}
|
|
1180
|
+
`).all(...m);if(!a)return S;let y=new Map(S.map(C=>[C.id,C]));return e.map(C=>y.get(C)).filter(C=>!!C)}getTimelineAroundTimestamp(e,r=10,n=10,s,o){return this.getTimelineAroundObservation(null,e,r,n,s,o)}getTimelineAroundObservation(e,r,n=10,s=10,o,i){let a=i?ue(i):void 0,l=(R,T)=>{let v=[],I=[];return o&&(v.push(`${R}.project = ?`),I.push(o)),a&&(v.push(`COALESCE(NULLIF(${T}.platform_source, ''), '${_}') = ?`),I.push(a)),{clause:v.length>0?`AND ${v.join(" AND ")}`:"",params:I}},c=l("o","src"),d=l("ss","src"),m=l("s","s"),f,g;if(e!==null){let R=`
|
|
1181
|
+
SELECT o.id, o.created_at_epoch
|
|
1182
|
+
FROM observations o
|
|
1183
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
1184
|
+
WHERE o.id <= ? ${c.clause}
|
|
1185
|
+
ORDER BY o.id DESC
|
|
1186
|
+
LIMIT ?
|
|
1187
|
+
`,T=`
|
|
1188
|
+
SELECT o.id, o.created_at_epoch
|
|
1189
|
+
FROM observations o
|
|
1190
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
1191
|
+
WHERE o.id >= ? ${c.clause}
|
|
1192
|
+
ORDER BY o.id ASC
|
|
1193
|
+
LIMIT ?
|
|
1194
|
+
`;try{let v=this.db.prepare(R).all(e,...c.params,n+1),I=this.db.prepare(T).all(e,...c.params,s+1);if(v.length===0&&I.length===0)return{observations:[],sessions:[],prompts:[]};f=v.length>0?v[v.length-1].created_at_epoch:r,g=I.length>0?I[I.length-1].created_at_epoch:r}catch(v){return v instanceof Error?u.error("DB","Error getting boundary observations",{project:o},v):u.error("DB","Error getting boundary observations with non-Error",{},new Error(String(v))),{observations:[],sessions:[],prompts:[]}}}else{let R=`
|
|
1195
|
+
SELECT o.created_at_epoch
|
|
1196
|
+
FROM observations o
|
|
1197
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
1198
|
+
WHERE o.created_at_epoch <= ? ${c.clause}
|
|
1199
|
+
ORDER BY o.created_at_epoch DESC
|
|
1200
|
+
LIMIT ?
|
|
1201
|
+
`,T=`
|
|
1202
|
+
SELECT o.created_at_epoch
|
|
1203
|
+
FROM observations o
|
|
1204
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
1205
|
+
WHERE o.created_at_epoch >= ? ${c.clause}
|
|
1206
|
+
ORDER BY o.created_at_epoch ASC
|
|
1207
|
+
LIMIT ?
|
|
1208
|
+
`;try{let v=this.db.prepare(R).all(r,...c.params,n),I=this.db.prepare(T).all(r,...c.params,s+1);if(v.length===0&&I.length===0)return{observations:[],sessions:[],prompts:[]};f=v.length>0?v[v.length-1].created_at_epoch:r,g=I.length>0?I[I.length-1].created_at_epoch:r}catch(v){return v instanceof Error?u.error("DB","Error getting boundary timestamps",{project:o},v):u.error("DB","Error getting boundary timestamps with non-Error",{},new Error(String(v))),{observations:[],sessions:[],prompts:[]}}}let h=`
|
|
1209
|
+
SELECT o.*
|
|
1210
|
+
FROM observations o
|
|
1211
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = o.memory_session_id
|
|
1212
|
+
WHERE o.created_at_epoch >= ? AND o.created_at_epoch <= ? ${c.clause}
|
|
1213
|
+
ORDER BY o.created_at_epoch ASC
|
|
1214
|
+
`,S=`
|
|
1215
|
+
SELECT ss.*
|
|
1216
|
+
FROM session_summaries ss
|
|
1217
|
+
LEFT JOIN sdk_sessions src ON src.memory_session_id = ss.memory_session_id
|
|
1218
|
+
WHERE ss.created_at_epoch >= ? AND ss.created_at_epoch <= ? ${d.clause}
|
|
1219
|
+
ORDER BY ss.created_at_epoch ASC
|
|
1220
|
+
`,y=`
|
|
1221
|
+
SELECT up.*, s.project, s.memory_session_id, COALESCE(NULLIF(s.platform_source, ''), '${_}') as platform_source
|
|
1222
|
+
FROM user_prompts up
|
|
1223
|
+
JOIN sdk_sessions s ON up.session_db_id = s.id
|
|
1224
|
+
WHERE up.created_at_epoch >= ? AND up.created_at_epoch <= ? ${m.clause}
|
|
1225
|
+
ORDER BY up.created_at_epoch ASC
|
|
1226
|
+
`,C=this.db.prepare(h).all(f,g,...c.params),N=this.db.prepare(S).all(f,g,...d.params),D=this.db.prepare(y).all(f,g,...m.params);return{observations:C,sessions:N.map(R=>({id:R.id,memory_session_id:R.memory_session_id,project:R.project,request:R.request,completed:R.completed,next_steps:R.next_steps,created_at:R.created_at,created_at_epoch:R.created_at_epoch})),prompts:D.map(R=>({id:R.id,content_session_id:R.content_session_id,prompt_number:R.prompt_number,prompt_text:R.prompt_text,project:R.project,platform_source:R.platform_source,created_at:R.created_at,created_at_epoch:R.created_at_epoch}))}}getPromptById(e){return this.db.prepare(`
|
|
1227
|
+
SELECT
|
|
1228
|
+
p.id,
|
|
1229
|
+
p.content_session_id,
|
|
1230
|
+
p.prompt_number,
|
|
1231
|
+
p.prompt_text,
|
|
1232
|
+
s.project,
|
|
1233
|
+
p.created_at,
|
|
1234
|
+
p.created_at_epoch
|
|
1235
|
+
FROM user_prompts p
|
|
1236
|
+
LEFT JOIN sdk_sessions s ON p.session_db_id = s.id
|
|
1237
|
+
WHERE p.id = ?
|
|
1238
|
+
LIMIT 1
|
|
1239
|
+
`).get(e)||null}getPromptsByIds(e){if(e.length===0)return[];let r=e.map(()=>"?").join(",");return this.db.prepare(`
|
|
1240
|
+
SELECT
|
|
1241
|
+
p.id,
|
|
1242
|
+
p.content_session_id,
|
|
1243
|
+
p.prompt_number,
|
|
1244
|
+
p.prompt_text,
|
|
1245
|
+
s.project,
|
|
1246
|
+
p.created_at,
|
|
1247
|
+
p.created_at_epoch
|
|
1248
|
+
FROM user_prompts p
|
|
1249
|
+
LEFT JOIN sdk_sessions s ON p.session_db_id = s.id
|
|
1250
|
+
WHERE p.id IN (${r})
|
|
1251
|
+
ORDER BY p.created_at_epoch DESC
|
|
1252
|
+
`).all(...e)}getOrCreateManualSession(e){let r=`manual-${e}`,n=`manual-content-${e}`;if(this.db.prepare("SELECT memory_session_id FROM sdk_sessions WHERE memory_session_id = ?").get(r))return r;let o=new Date;return this.db.prepare(`
|
|
1253
|
+
INSERT INTO sdk_sessions (memory_session_id, content_session_id, project, platform_source, started_at, started_at_epoch, status)
|
|
1254
|
+
VALUES (?, ?, ?, ?, ?, ?, 'active')
|
|
1255
|
+
`).run(r,n,e,_,o.toISOString(),o.getTime()),u.info("SESSION","Created manual session",{memorySessionId:r,project:e}),r}close(){this.db.close()}importSdkSession(e){let r=ue(e.platform_source),n=this.db.prepare(`SELECT id FROM sdk_sessions
|
|
1256
|
+
WHERE platform_source = ? AND content_session_id = ?`).get(r,e.content_session_id);return n?{imported:!1,id:n.id}:{imported:!0,id:this.db.prepare(`
|
|
1257
|
+
INSERT INTO sdk_sessions (
|
|
1258
|
+
content_session_id, memory_session_id, project, platform_source, user_prompt,
|
|
1259
|
+
started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
1260
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1261
|
+
`).run(e.content_session_id,e.memory_session_id,e.project,r,e.user_prompt,e.started_at,e.started_at_epoch,e.completed_at,e.completed_at_epoch,e.status).lastInsertRowid}}importSessionSummary(e){let r=this.db.prepare("SELECT id FROM session_summaries WHERE memory_session_id = ?").get(e.memory_session_id);return r?{imported:!1,id:r.id}:{imported:!0,id:this.db.prepare(`
|
|
1262
|
+
INSERT INTO session_summaries (
|
|
1263
|
+
memory_session_id, project, request, investigated, learned,
|
|
1264
|
+
completed, next_steps, files_read, files_edited, notes,
|
|
1265
|
+
prompt_number, discovery_tokens, created_at, created_at_epoch
|
|
1266
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1267
|
+
`).run(e.memory_session_id,e.project,e.request,e.investigated,e.learned,e.completed,e.next_steps,e.files_read,e.files_edited,e.notes,e.prompt_number,e.discovery_tokens||0,e.created_at,e.created_at_epoch).lastInsertRowid}}importObservation(e){let r=this.db.prepare(`
|
|
1268
|
+
SELECT id FROM observations
|
|
1269
|
+
WHERE memory_session_id = ? AND title = ? AND created_at_epoch = ?
|
|
1270
|
+
`).get(e.memory_session_id,e.title,e.created_at_epoch);return r?{imported:!1,id:r.id}:{imported:!0,id:this.db.prepare(`
|
|
1271
|
+
INSERT INTO observations (
|
|
1272
|
+
memory_session_id, project, text, type, title, subtitle,
|
|
1273
|
+
facts, narrative, concepts, files_read, files_modified,
|
|
1274
|
+
prompt_number, discovery_tokens, agent_type, agent_id,
|
|
1275
|
+
created_at, created_at_epoch
|
|
1276
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1277
|
+
`).run(e.memory_session_id,e.project,e.text,e.type,e.title,e.subtitle,e.facts,e.narrative,e.concepts,e.files_read,e.files_modified,e.prompt_number,e.discovery_tokens||0,e.agent_type??null,e.agent_id??null,e.created_at,e.created_at_epoch).lastInsertRowid}}rebuildObservationsFTSIndex(){this.db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='observations_fts'").all().length>0&&this.db.run("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')")}importUserPrompt(e){let r=null,n=e.platform_source?ue(e.platform_source):void 0;if(typeof e.session_db_id=="number"){let a=this.db.prepare(`
|
|
1278
|
+
SELECT id, content_session_id, COALESCE(NULLIF(platform_source, ''), '${_}') as platform_source
|
|
1279
|
+
FROM sdk_sessions
|
|
1280
|
+
WHERE id = ?
|
|
1281
|
+
LIMIT 1
|
|
1282
|
+
`).get(e.session_db_id);a&&a.content_session_id===e.content_session_id&&(!n||ue(a.platform_source)===n)&&(r=a.id)}r===null&&(r=this.resolvePromptSessionDbId(e.content_session_id,void 0,n));let s=this.db.prepare(`
|
|
1283
|
+
SELECT id FROM user_prompts
|
|
1284
|
+
WHERE ${r!==null?"session_db_id = ?":"content_session_id = ?"} AND prompt_number = ?
|
|
1285
|
+
`).get(r??e.content_session_id,e.prompt_number);return s?{imported:!1,id:s.id}:{imported:!0,id:this.db.prepare(`
|
|
1286
|
+
INSERT INTO user_prompts (
|
|
1287
|
+
session_db_id, content_session_id, prompt_number, prompt_text,
|
|
1288
|
+
created_at, created_at_epoch
|
|
1289
|
+
) VALUES (?, ?, ?, ?, ?, ?)
|
|
1290
|
+
`).run(r,e.content_session_id,e.prompt_number,e.prompt_text,e.created_at,e.created_at_epoch).lastInsertRowid}}}});var li={};de(li,{performMigration:()=>gu,readCounts:()=>Ze,resolveSource:()=>fu,runMigrateCommand:()=>Ah});import ze from"node:fs";import pu from"node:path";import Oh from"node:os";function mu(t){return`'${t.replace(/'/g,"''")}'`}function kh(t,e){let r=t.indexOf(e);if(r===-1)return;let n=t[r+1];return(n===void 0||n.startsWith("-"))&&(console.error(U.default.red(`Flag ${e} requires a value.`)),process.exit(1)),n}function fu(t){return t?ze.existsSync(t)&&ze.statSync(t).isDirectory()?pu.join(t,"claude-mem.db"):t:pu.join(Oh.homedir(),".claude-mem","claude-mem.db")}function Kn(t,e){try{return t.prepare(`SELECT COUNT(*) AS n FROM "${e}"`).get()?.n??0}catch{return 0}}function Ze(t){let e=new ye(t,{readonly:!0});try{return{sessions:Kn(e,"sdk_sessions"),observations:Kn(e,"observations"),summaries:Kn(e,"session_summaries"),prompts:Kn(e,"user_prompts")}}finally{e.close()}}function ai(t,e){console.log(` ${t.padEnd(8)} ${U.default.bold(String(e.sessions))} sessions \xB7 ${U.default.bold(String(e.observations))} observations \xB7 ${U.default.bold(String(e.summaries))} summaries \xB7 ${U.default.bold(String(e.prompts))} prompts`)}async function _h(t){sn(M);for(let s of["","-wal","-shm"]){let o=B+s;ze.existsSync(o)&&ze.rmSync(o)}console.log(U.default.dim(" Snapshotting source (VACUUM INTO)\u2026"));let e=new ye(t,{readonly:!0});try{e.exec(`VACUUM INTO ${mu(B)}`)}finally{e.close()}console.log(U.default.dim(" Upgrading schema via keepmind migrations\u2026"));let{SessionStore:r}=await Promise.resolve().then(()=>(ii(),oi));new r(B).close()}async function Nh(t){let{SessionStore:e}=await Promise.resolve().then(()=>(ii(),oi));new e(B).close();let r=new ye(B);try{r.exec("PRAGMA foreign_keys=OFF"),r.exec(`ATTACH DATABASE ${mu(t)} AS src`),r.exec("BEGIN");try{r.exec(`
|
|
1291
|
+
INSERT OR IGNORE INTO sdk_sessions
|
|
1292
|
+
(content_session_id, memory_session_id, project, platform_source,
|
|
1293
|
+
user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch, status)
|
|
1294
|
+
SELECT content_session_id, memory_session_id, project, COALESCE(platform_source, 'claude'),
|
|
1295
|
+
user_prompt, started_at, started_at_epoch, completed_at, completed_at_epoch, status
|
|
1296
|
+
FROM src.sdk_sessions
|
|
1297
|
+
`),r.exec(`
|
|
1298
|
+
INSERT OR IGNORE INTO observations
|
|
1299
|
+
(memory_session_id, project, text, type, title, subtitle, facts, narrative, concepts,
|
|
1300
|
+
files_read, files_modified, prompt_number, discovery_tokens, created_at, created_at_epoch,
|
|
1301
|
+
content_hash, generated_by_model, relevance_count, merged_into_project, agent_type, agent_id, metadata)
|
|
1302
|
+
SELECT memory_session_id, project, COALESCE(text, ''), type, title, subtitle, facts, narrative, concepts,
|
|
1303
|
+
files_read, files_modified, prompt_number, discovery_tokens, created_at, created_at_epoch,
|
|
1304
|
+
content_hash, generated_by_model, relevance_count, merged_into_project, agent_type, agent_id, metadata
|
|
1305
|
+
FROM src.observations
|
|
1306
|
+
`),r.exec("UPDATE observations SET valid_from = created_at_epoch WHERE valid_from IS NULL"),r.exec(`
|
|
1307
|
+
INSERT INTO session_summaries
|
|
1308
|
+
(memory_session_id, project, request, investigated, learned, completed, next_steps,
|
|
1309
|
+
files_read, files_edited, notes, prompt_number, discovery_tokens, created_at, created_at_epoch, merged_into_project)
|
|
1310
|
+
SELECT ss.memory_session_id, ss.project, ss.request, ss.investigated, ss.learned, ss.completed, ss.next_steps,
|
|
1311
|
+
ss.files_read, ss.files_edited, ss.notes, ss.prompt_number, ss.discovery_tokens, ss.created_at, ss.created_at_epoch, ss.merged_into_project
|
|
1312
|
+
FROM src.session_summaries ss
|
|
1313
|
+
WHERE NOT EXISTS (
|
|
1314
|
+
SELECT 1 FROM session_summaries d
|
|
1315
|
+
WHERE d.memory_session_id = ss.memory_session_id AND d.created_at_epoch = ss.created_at_epoch
|
|
1316
|
+
)
|
|
1317
|
+
`),r.exec(`
|
|
1318
|
+
INSERT INTO user_prompts (session_db_id, content_session_id, prompt_number, prompt_text, created_at, created_at_epoch)
|
|
1319
|
+
SELECT (SELECT t.id FROM sdk_sessions t WHERE t.content_session_id = sp.content_session_id ORDER BY t.id LIMIT 1),
|
|
1320
|
+
sp.content_session_id, sp.prompt_number, sp.prompt_text, sp.created_at, sp.created_at_epoch
|
|
1321
|
+
FROM src.user_prompts sp
|
|
1322
|
+
WHERE NOT EXISTS (
|
|
1323
|
+
SELECT 1 FROM user_prompts up
|
|
1324
|
+
WHERE up.content_session_id = sp.content_session_id AND up.prompt_number = sp.prompt_number
|
|
1325
|
+
)
|
|
1326
|
+
`),r.exec("INSERT INTO observations_fts(observations_fts) VALUES('rebuild')"),r.exec("INSERT INTO session_summaries_fts(session_summaries_fts) VALUES('rebuild')"),r.exec("INSERT INTO user_prompts_fts(user_prompts_fts) VALUES('rebuild')"),r.exec("COMMIT")}catch(n){try{r.exec("ROLLBACK")}catch{}throw n}finally{try{r.exec("DETACH DATABASE src")}catch{}r.exec("PRAGMA foreign_keys=ON")}}finally{r.close()}}async function gu(t,e={}){if(!ze.existsSync(t))throw new Error(`Source database not found: ${t}`);let r=Ze(t),n=ze.existsSync(B),s=n?Ze(B):{sessions:0,observations:0,summaries:0,prompts:0},o=!n||s.sessions===0?"adopt":"merge";return e.dryRun?{source:t,mode:o,before:s,after:s,sourceCounts:r}:(o==="adopt"?await _h(t):await Nh(t),{source:t,mode:o,before:s,after:Ze(B),sourceCounts:r})}async function Ah(t=[]){let e=t.includes("--dry-run"),r=t.includes("--purge"),n=t.includes("--yes")||t.includes("-y"),s=kh(t,"--from"),o=fu(s);console.log(`
|
|
1327
|
+
${U.default.bold("keepmind migrate")}
|
|
1328
|
+
`),ze.existsSync(o)||(console.error(U.default.red(`Source database not found: ${o}`)),console.error(U.default.dim(" Pass --from <dir-or-file> to point at an existing claude-mem.db.")),process.exit(1));let i=ze.existsSync(B),a=i?Ze(B).sessions:0,l=!i||a===0?"adopt":"merge";if(console.log(U.default.dim(` Source: ${o}`)),ai("source",Ze(o)),console.log(U.default.dim(` Target: ${B}`)),ai("target",i?Ze(B):{sessions:0,observations:0,summaries:0,prompts:0}),console.log(` Mode: ${U.default.bold(l==="adopt"?"ADOPT (fresh snapshot)":"MERGE (dedup import)")}`),l==="merge"&&ze.existsSync(j.workerPid())&&(console.log(U.default.yellow(" Note: a keepmind worker appears to be running. Stop it first for a clean merge:")),console.log(U.default.dim(" npx keepmind stop"))),e){console.log(`
|
|
1329
|
+
${U.default.cyan("Dry run")} \u2014 no changes written.
|
|
1330
|
+
`),r&&console.log(U.default.dim(` (--purge is ignored on a dry run.)
|
|
1331
|
+
`));return}console.log("");let c=await gu(o,{dryRun:!1});console.log(`
|
|
1332
|
+
${U.default.green("\u2713 Migration complete.")}`),ai("result",c.after),console.log(U.default.dim(" Vectors backfill automatically on the next worker start (semantic search).")),console.log(U.default.dim(` The original database was not modified.
|
|
1333
|
+
`)),r&&await Mh(o,n)}async function Mh(t,e){let{verifyMigrated:r,purgeClaudeMem:n}=await Promise.resolve().then(()=>(ui(),ci)),{missing:s,total:o,unhashable:i}=r(t);s>0&&(console.error(U.default.red(`
|
|
1334
|
+
\u2717 Purge aborted: ${s} of ${o} claude-mem observations are not yet in keepmind.`)),console.error(U.default.dim(` Re-run migrate (or investigate) before purging. The source was left intact.
|
|
1335
|
+
`)),process.exit(1)),i>0&&console.log(U.default.dim(` Note: ${i} legacy row(s) without a content_hash were copied but not hash-verified.`)),e||(console.error(U.default.yellow(`
|
|
1336
|
+
Refusing to purge without confirmation. Re-run with --yes to remove claude-mem.`)),console.error(U.default.dim(` Verified: all ${o} observations are safely in keepmind.
|
|
1337
|
+
`)),process.exit(1)),console.log(U.default.dim(" Purging claude-mem (verified redundant)\u2026"));let a=await n({timestamp:new Date().toISOString()});console.log(`
|
|
1338
|
+
${U.default.green("\u2713 claude-mem removed.")}`),a.archivePath&&console.log(U.default.dim(` Backup: ${a.archivePath}`)),a.processesKilled&&console.log(U.default.dim(` Stopped ${a.processesKilled} orphaned process(es).`)),console.log("")}var U,Xn=b(()=>{"use strict";U=He(rt(),1);V();mr()});import{execFile as xh}from"node:child_process";import{promisify as Lh}from"node:util";async function hu(){try{return process.platform==="win32"?await Ph():await Uh()}catch{return[]}}async function Ph(){let t=`Get-CimInstance Win32_Process | Where-Object { $_.Name -match '^(chroma-mcp|python|pythonw)(\\.exe)?$' -and $_.CommandLine -match 'chroma-mcp' -and $_.CommandLine -match '\\.claude-mem' } | ForEach-Object { "$($_.ProcessId)\`t$($_.Name)" }`,{stdout:e}=await di("powershell",["-NoProfile","-NonInteractive","-Command",t],{windowsHide:!0,timeout:15e3});return Fh(e)}async function Uh(){let{stdout:t}=await di("ps",["-eo","pid=,comm=,args="],{timeout:15e3}),e=[];for(let r of t.split(`
|
|
1339
|
+
`)){let n=r.trim();if(!n)continue;let s=n.match(/^(\d+)\s+(\S+)\s+(.*)$/);if(!s)continue;let o=Number(s[1]),i=s[2],a=s[3],l=i.split("/").pop()??i;Dh.includes(l)&&/chroma-mcp/.test(a)&&/\.claude-mem/.test(a)&&o!==process.pid&&e.push({pid:o,name:l})}return e}function Fh(t){let e=[];for(let r of t.split(`
|
|
1340
|
+
`)){let n=r.trim();if(!n)continue;let[s,o]=n.split(" "),i=Number(s);!Number.isInteger(i)||i<=0||i===process.pid||e.push({pid:i,name:o??"unknown"})}return e}async function Eu(t){let e=0;for(let r of t)if(!(!Number.isInteger(r)||r<=0))try{process.platform==="win32"?await di("taskkill",["/PID",String(r),"/T","/F"],{windowsHide:!0,timeout:1e4}):process.kill(r,"SIGKILL"),e++}catch(n){if(n?.code==="ESRCH")continue}return e}var di,Dh,Su=b(()=>{"use strict";di=Lh(xh),Dh=["chroma-mcp.exe","python.exe","pythonw.exe","chroma-mcp","python","python3"]});var ci={};de(ci,{claudeMemDbPath:()=>gi,claudeMemDir:()=>fi,detectClaudeMem:()=>vu,purgeClaudeMem:()=>Xh,verifyMigrated:()=>Kh});import{execFile as jh}from"node:child_process";import{existsSync as be,mkdirSync as Wh,readdirSync as Gh,readFileSync as Tu,rmSync as mi,writeFileSync as Bh}from"node:fs";import{homedir as Ur}from"node:os";import{join as te}from"node:path";import{promisify as Hh}from"node:util";function fi(){return te(Ur(),".claude-mem")}function gi(){return te(fi(),"claude-mem.db")}function vu(){let t=fi(),e=gi(),r=be(e),n=new Set,s=new Set,o=z(Pe(),{});for(let d of Object.keys(o?.plugins??{}))if(Pr.test(d)){n.add(d);let m=d.split("@")[1];m&&s.add(m)}let i=z(we(),{});for(let d of Object.keys(i?.enabledPlugins??{}))if(Pr.test(d)){n.add(d);let m=d.split("@")[1];m&&s.add(m)}let a=z(De(),{});for(let d of Object.keys(a)){if(s.has(d))continue;if(Pr.test(d)){s.add(d);continue}let m=z(te(Re(),"marketplaces",d,".claude-plugin","marketplace.json"),{});(Array.isArray(m?.plugins)?m.plugins:[]).some(g=>typeof g?.name=="string"&&Pr.test(g.name))&&s.add(d)}let l=[...s].map(d=>te(Re(),"marketplaces",d)).filter(d=>be(d));return{installed:r||n.size>0||s.size>0,dataDir:t,dbPath:e,hasData:r,counts:r?Jh(e):null,pluginKeys:[...n],marketplaceKeys:[...s],marketplaceDirs:l}}function Jh(t){try{return Ze(t)}catch{return null}}function Kh(t=gi()){if(!be(t)||!be(B))return{missing:0,total:0,unhashable:0};let e=new ye(B,{readonly:!0}),r=new ye(t,{readonly:!0});try{let n=new Set(e.prepare("SELECT content_hash FROM observations WHERE content_hash IS NOT NULL").all().map(a=>a.content_hash)),s=r.prepare("SELECT content_hash FROM observations").all(),o=0,i=0;for(let a of s)a.content_hash?n.has(a.content_hash)||o++:i++;return{missing:o,total:s.length,unhashable:i}}finally{try{r.close()}catch{}try{e.close()}catch{}}}async function Xh(t){let e=t.presence??vu(),r={processesKilled:0,archivePath:null,marketplacesRemoved:[],pluginsRemoved:[],strayPathsRemoved:0,dataDirRemoved:!1,errors:[]};try{let s=await hu();r.processesKilled=await Eu(s.map(o=>o.pid))}catch(s){r.errors.push(`process stop: ${Qe(s)}`)}let n=!0;if(be(e.dataDir))try{r.archivePath=await Vh(e.dataDir,t.timestamp)}catch(s){n=!1,r.errors.push(`archive: ${Qe(s)}`)}try{Yh(e,r)}catch(s){r.errors.push(`deregister: ${Qe(s)}`)}try{r.strayPathsRemoved=qh()}catch(s){r.errors.push(`stray paths: ${Qe(s)}`)}try{zh(r)}catch(s){r.errors.push(`shell alias: ${Qe(s)}`)}try{Zh(r)}catch(s){r.errors.push(`claude.json: ${Qe(s)}`)}if(be(e.dataDir))if(!n)r.errors.push("data dir kept: backup failed, refusing to delete without an archive");else try{mi(e.dataDir,{recursive:!0,force:!0}),r.dataDirRemoved=!be(e.dataDir)}catch(s){r.errors.push(`remove data dir: ${Qe(s)}`)}return r}async function Vh(t,e){let r=te(M,"backups");Wh(r,{recursive:!0});let n=e.replace(/[:.]/g,"-");if(process.platform==="win32"){let o=te(r,`claude-mem-${n}.zip`);return await bu("powershell",["-NoProfile","-NonInteractive","-Command",`Compress-Archive -Path ${yu(te(t,"*"))} -DestinationPath ${yu(o)} -Force`],{windowsHide:!0,timeout:12e4}),o}let s=te(r,`claude-mem-${n}.tar.gz`);return await bu("tar",["-czf",s,"-C",Ur(),".claude-mem"],{timeout:12e4}),s}function Yh(t,e){let r=z(Pe(),{}),n=!1;for(let l of t.pluginKeys)r?.plugins?.[l]!==void 0&&(delete r.plugins[l],e.pluginsRemoved.push(l),n=!0);n&&re(Pe(),r);let s=z(we(),{}),o=!1;for(let l of t.pluginKeys)s?.enabledPlugins?.[l]!==void 0&&(delete s.enabledPlugins[l],o=!0);o&&re(we(),s);let i=z(De(),{}),a=!1;for(let l of t.marketplaceKeys)i?.[l]!==void 0&&(delete i[l],a=!0);a&&re(De(),i);for(let l of t.marketplaceDirs)be(l)&&(mi(l,{recursive:!0,force:!0}),e.marketplacesRemoved.push(l))}function qh(){let t=Ur(),e=0,r=te(t,".npm","_npx");if(be(r))for(let o of Vn(r)){let i=te(r,o,"node_modules","claude-mem");be(i)&&pi(i)&&e++}let n=te(t,".cache","claude-cli-nodejs");if(be(n))for(let o of Vn(n)){let i=te(n,o);for(let a of Vn(i))a.startsWith("mcp-logs-plugin-claude-mem-")&&pi(te(i,a))&&e++}let s=te(t,".claude","plugins","data");if(be(s))for(let o of Vn(s))o.startsWith("claude-mem-")&&pi(te(s,o))&&e++;return e}function zh(t){let e=Ur(),r=[te(e,".bashrc"),te(e,".zshrc"),te(e,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")],n=/^\s*(alias\s+claude-mem\s*=|Set-Alias\s+(-Name\s+)?claude-mem\b)/;for(let s of r)if(be(s))try{let o=Tu(s,"utf-8").split(`
|
|
1341
|
+
`),i=o.filter(a=>!n.test(a));i.length!==o.length&&(Bh(s,i.join(`
|
|
1342
|
+
`)),t.strayPathsRemoved+=o.length-i.length)}catch(o){t.errors.push(`shell alias (${s}): ${Qe(o)}`)}}function Zh(t){let e=te(Ur(),".claude.json");if(!be(e))return;let r;try{r=JSON.parse(Tu(e,"utf-8"))}catch(s){t.errors.push(`claude.json parse (left intact): ${Qe(s)}`);return}if(!r||typeof r!="object"||Array.isArray(r))return;let n=!1;for(let s of["skillUsage","pluginUsage","usageStats"]){let o=r[s];if(o&&typeof o=="object"&&!Array.isArray(o))for(let i of Object.keys(o))Pr.test(i)&&(delete o[i],n=!0)}n&&re(e,r)}function Vn(t){try{return Gh(t)}catch{return[]}}function pi(t){try{return mi(t,{recursive:!0,force:!0}),!0}catch{return!1}}function yu(t){return`'${t.replace(/'/g,"''")}'`}function Qe(t){return t instanceof Error?t.message:String(t)}var bu,Pr,ui=b(()=>{"use strict";V();mr();Ae();Xn();Su();bu=Hh(jh),Pr=/(^|[@/])claude-mem\b/});var qn={};de(qn,{disableClaudeAutoMemory:()=>Nu,runInstallCommand:()=>yE,runRepairCommand:()=>vE});import{cpSync as Ru,existsSync as Te,mkdirSync as wu,readFileSync as Fr,rmSync as Iu,writeFileSync as Ou}from"fs";import{homedir as ku}from"os";import{dirname as _u,join as ge}from"path";function Zt(t){return le.loadFromFile(Me)[t]}async function Yn(t){if(H)await rn(t);else for(let e of t){let r=await e.task(n=>console.log(` ${n}`));console.log(` ${r}`)}}function hi(t,e){if(t(e),!H)return()=>{};let r=Date.now(),n=setInterval(()=>{let s=Math.round((Date.now()-r)/1e3);t(`${e} ${E.default.dim(`(${s}s \u2014 still working)`)}`)},1e3);return()=>clearInterval(n)}async function bt(t){if(!H)return{result:await t(),output:""};let e="",r=(...s)=>{e+=s.map(o=>typeof o=="string"?o:String(o)).join(" ")+`
|
|
1343
|
+
`},n={log:console.log,error:console.error,warn:console.warn};console.log=r,console.error=r,console.warn=r;try{return{result:await t(),output:e}}finally{console.log=n.log,console.error=n.error,console.warn=n.warn}}function Qh(){let t=z(De(),{});t.keepmind={source:{source:"github",repo:"ManuelStaggl/keepmind"},installLocation:oe(),lastUpdated:new Date().toISOString(),autoUpdate:!0},tr(Re()),re(De(),t)}function $h(t){let e=z(Pe(),{});e.version||(e.version=2),e.plugins||(e.plugins={});let r=nt(t),n=new Date().toISOString();e.plugins["keepmind@keepmind"]=[{scope:"user",installPath:r,version:t,installedAt:n,lastUpdated:n}],re(Pe(),e)}function eE(){let t=z(we(),{});t.enabledPlugins||(t.enabledPlugins={}),t.enabledPlugins["keepmind@keepmind"]=!0,re(we(),t)}function Nu(){let t=z(we(),{}),e=t.env&&typeof t.env=="object"?t.env:{};return e.CLAUDE_CODE_DISABLE_AUTO_MEMORY==="1"?!1:(t.env={...e,CLAUDE_CODE_DISABLE_AUTO_MEMORY:"1"},re(we(),t),!0)}async function tE(t,e){if(!t.includes("claude-code"))return"not-applicable";if(e.disableAutoMemory)return"disable";if(!H)return"leave-enabled";let r=await at({message:"Disable Claude Code auto-memory?",options:[{value:"leave-enabled",label:"Leave enabled",hint:"Recommended; keeps Claude Code native memory visible on startup."},{value:"disable",label:"Disable auto-memory",hint:"Only if you explicitly want keepmind to replace native startup memory."}],initialValue:"leave-enabled"});return J(r)&&(Oe("Installation cancelled."),process.exit(0)),r}function rE(t,e){let r=(n,s)=>{ce("FAIL_LOUD_PER_IDE",{component:n,ide:t,phase:"ide-install",cause:new Error(n),details:s&&s.trim().length>0?s.trim().slice(0,4e3):void 0},e)};switch(t){case"claude-code":return{title:"Claude Code: registering plugin",task:async()=>`Claude Code: plugin registered ${E.default.green("OK")}`};case"cursor":return{title:"Cursor: installing hooks + MCP",task:async n=>{n("Loading Cursor installer\u2026");let{installCursorHooks:s,configureCursorMcp:o}=await Promise.resolve().then(()=>(tc(),ec));n("Installing Cursor hooks\u2026");let{result:i,output:a}=await bt(()=>s("user"));if(i!==0)return r("Cursor: hook installation failed",a),`Cursor: hook installation failed ${E.default.red("FAIL")}`;n("Configuring Cursor MCP\u2026");let{result:l}=await bt(async()=>o("user"));return l===0?`Cursor: hooks + MCP installed ${E.default.green("OK")}`:`Cursor: hooks installed; MCP setup failed \u2014 run \`npx keepmind cursor mcp\` ${E.default.yellow("!")}`}};case"gemini-cli":return{title:"Gemini CLI: installing hooks",task:async n=>{n("Loading Gemini CLI installer\u2026");let{installGeminiCliHooks:s}=await Promise.resolve().then(()=>(So(),Eo));n("Installing Gemini CLI hooks\u2026");let{result:o,output:i}=await bt(()=>s());return o!==0?(r("Gemini CLI: hook installation failed",i),`Gemini CLI: hook installation failed ${E.default.red("FAIL")}`):`Gemini CLI: hooks installed ${E.default.green("OK")}`}};case"opencode":return{title:"OpenCode: installing plugin",task:async n=>{n("Loading OpenCode installer\u2026");let{installOpenCodeIntegration:s}=await Promise.resolve().then(()=>(Io(),wo));n("Installing OpenCode plugin\u2026");let{result:o,output:i}=await bt(()=>s());return o!==0?(r("OpenCode: plugin installation failed",i),`OpenCode: plugin installation failed ${E.default.red("FAIL")}`):`OpenCode: plugin installed ${E.default.green("OK")}`}};case"windsurf":return{title:"Windsurf: installing hooks",task:async n=>{n("Loading Windsurf installer\u2026");let{installWindsurfHooks:s}=await Promise.resolve().then(()=>(No(),_o));n("Installing Windsurf hooks\u2026");let{result:o,output:i}=await bt(()=>s());return o!==0?(r("Windsurf: hook installation failed",i),`Windsurf: hook installation failed ${E.default.red("FAIL")}`):`Windsurf: hooks installed ${E.default.green("OK")}`}};case"openclaw":return{title:"OpenClaw: installing plugin",task:async n=>{n("Loading OpenClaw installer\u2026");let{installOpenClawIntegration:s}=await Promise.resolve().then(()=>(Do(),Lo));n("Copying plugin files\u2026");let{result:o,output:i}=await bt(()=>s());return o!==0?(r("OpenClaw: plugin installation failed",i),`OpenClaw: plugin installation failed ${E.default.red("FAIL")}`):`OpenClaw: plugin installed ${E.default.green("OK")}`}};case"codex-cli":return{title:"Codex CLI: registering hooks marketplace",task:async n=>{n("Loading Codex CLI installer\u2026");let{installCodexCli:s}=await Promise.resolve().then(()=>(Xo(),Ko));n("Registering native Codex hooks\u2026");let{result:o,output:i}=await bt(()=>s(oe()));return o!==0?(r("Codex CLI: integration setup failed",i),`Codex CLI: integration setup failed ${E.default.red("FAIL")}`):`Codex CLI: hooks marketplace registered ${E.default.green("OK")}`}};case"copilot-cli":case"antigravity":case"goose":case"roo-code":case"warp":{let o=Wt().find(i=>i.id===t)?.label??t;return{title:`${o}: installing MCP integration`,task:async i=>{i("Loading MCP installer\u2026");let{MCP_IDE_INSTALLERS:a}=await Promise.resolve().then(()=>(Vc(),Xc)),l=a[t];if(!l)return`${o}: MCP installer not found ${E.default.yellow("!")}`;i(`Configuring ${o} MCP\u2026`);let{result:c,output:d}=await bt(()=>l());return c!==0?(r(`${o}: MCP integration failed`,d),`${o}: MCP integration failed ${E.default.red("FAIL")}`):`${o}: MCP integration installed ${E.default.green("OK")}`}}}default:{let s=Wt().find(o=>o.id===t);return s&&!s.supported?{title:`${s.label}: skipping`,task:async()=>`${s.label}: support coming soon ${E.default.yellow("!")}`}:null}}}async function nE(t,e){let r=[];for(let n of t){let s=rE(n,e);s&&r.push(s)}return r.length>0&&await Yn(r),t.length>0&&e.failedIDEs.length===t.length&&ce("ABORT",{component:"all-ides",phase:"ide-install",cause:new Error(`All ${t.length} selected IDE integrations failed.`)},e),e.failedIDEs}function sE(){let t=ku(),e=process.env.SHELL??"";if(e.includes("fish"))return{path:ge(t,".config","fish","config.fish"),shell:"fish"};if(e.includes("zsh"))return{path:ge(t,".zshrc"),shell:"zsh"};if(process.platform==="darwin"){let r=ge(t,".bash_profile");if(Te(r))return{path:r,shell:"bash"}}return{path:ge(t,".bashrc"),shell:"bash"}}function oE(){let t=ku(),e=ge(t,".local","bin"),r=ge(e,"claude");if(!Te(r))return;let n=process.env.PATH??"";if(n.split(":").includes(e))return;let{path:o,shell:i}=sE(),a="$HOME/.local/bin",l=i==="fish"?`set -gx PATH ${e} $PATH`:`export PATH="${a}:$PATH"`,c="";if(Te(o))try{c=Fr(o,"utf-8")}catch(d){k.warn(`Could not read ${o}: ${d instanceof Error?d.message:String(d)}`)}else try{wu(_u(o),{recursive:!0})}catch{}if(c.includes(e)||c.includes(a))k.info(`Claude Code PATH already configured in ${o}`);else try{let m=`${c.length===0||c.endsWith(`
|
|
1344
|
+
`)?"":`
|
|
1345
|
+
`}
|
|
1346
|
+
# Added by keepmind installer for Claude Code
|
|
1347
|
+
${l}
|
|
1348
|
+
`;Ou(o,c+m,"utf-8"),k.success(`Added Claude Code to PATH in ${o}`)}catch(d){k.warn(`Could not update ${o}: ${d instanceof Error?d.message:String(d)}`),k.info(`Run manually: echo '${l}' >> ${o}`);return}process.env.PATH=`${e}:${n}`}async function iE(){let t=W?'powershell -ExecutionPolicy ByPass -c "irm https://claude.ai/install.ps1 | iex"':"curl -fsSL https://claude.ai/install.sh | bash",e=H?it():null;return e?.start("Installing Claude Code (this can take a few minutes \u2014 downloading the native build)\u2026"),new Promise(r=>{let n="",s=Xe(t,[],{shell:W?process.env.ComSpec??"cmd.exe":"/bin/bash",stdio:e?["inherit","pipe","pipe"]:"inherit"});s.stdout?.on("data",o=>{n+=o.toString()}),s.stderr?.on("data",o=>{n+=o.toString()}),s.on("error",o=>{e?.error("Claude Code install failed"),n&&process.stderr.write(n),k.error(`Claude Code install failed: ${o.message}`),k.info("You can install it manually later: https://claude.ai/install.sh"),r(!1)}),s.on("exit",o=>{if(o!==0){e?.error("Claude Code install failed"),n&&process.stderr.write(n),k.error(`Claude Code install failed (exit ${o??"unknown"})`),k.info("You can install it manually later: https://claude.ai/install.sh"),r(!1);return}if(e?.stop("Claude Code installed"),!W)try{oE()}catch(i){k.warn(`Could not auto-apply PATH setup: ${i instanceof Error?i.message:String(i)}`)}r(!0)})})}async function aE(){let t=Wt(),e=t.find(o=>o.id==="claude-code");if(e&&!e.detected){k.warn("Claude Code is not installed. Claude-mem works best in Claude Code, but also works with the IDEs below.");let o=await at({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"});(J(o)||o==="cancel")&&(Oe("Installation cancelled."),process.exit(0)),o==="install"&&await iE()&&(t=Wt())}t.filter(o=>o.detected).length===0&&k.warn("No supported IDEs detected \u2014 pick the one(s) you plan to use.");let n=t.map(o=>{let i=o.detected?" [detected]":"",a=o.supported?`${o.hint}${i}`:`coming soon${i}`;return{value:o.id,label:o.label,hint:a}}),s=await pa({message:"Which IDEs do you use?",options:n,initialValues:[],required:!0});return J(s)&&(Oe("Installation cancelled."),process.exit(0)),s}function lE(){let t=oe(),e=Kr();tr(t);let r=[".agents",".codex-plugin","plugin","package.json","package-lock.json","openclaw","dist","LICENSE","README.md","CHANGELOG.md"];for(let n of r){let s=ge(e,n),o=ge(t,n);Te(s)&&(Te(o)&&Iu(o,{recursive:!0,force:!0}),Ru(s,o,{recursive:!0,force:!0}))}}function Au(t){let e=os(),r=nt(t);Iu(r,{recursive:!0,force:!0}),tr(r),Ru(e,r,{recursive:!0,force:!0})}async function cE(t){let e=oe(),r=ge(e,"package.json");if(!Te(r))return;let n=["install","--omit=dev","--ignore-scripts"],s=await to(e,n);if(s.code===0)return;s.timedOut&&ce("ABORT",{component:"marketplace-npm-install",phase:"marketplace-deps",cause:new Error("npm install timed out"),details:s.stderr.slice(0,4e3)},t),wl(s.stderr)||ce("ABORT",{component:"marketplace-npm-install",phase:"marketplace-deps",cause:new Error(`npm install failed (exit ${s.code})`),details:s.stderr.slice(0,4e3)},t),k.warn("npm reported an ERESOLVE peer-dependency conflict in marketplace deps; retrying once with --legacy-peer-deps."),k.warn(Il(s.stderr));let o=await to(e,[...n,"--legacy-peer-deps"]);if(o.code===0){t.warnings.push({component:"marketplace-npm-install",message:"tree-sitter peer-dep ERESOLVE was resolved with the --legacy-peer-deps fallback. Benign for the marketplace install; re-evaluate when tree-sitter peer ranges change.",remediation:"No action required."});return}ce("ABORT",{component:"marketplace-npm-install",phase:"marketplace-deps",cause:new Error(`npm install --legacy-peer-deps still failed (exit ${o.code}): ERESOLVE`),details:o.stderr.slice(0,4e3)},t)}function Le(t){let e=Me;try{let r={};if(Te(e))try{let n=Fr(e,"utf-8"),s=JSON.parse(n);s&&typeof s=="object"&&s.env&&typeof s.env=="object"?r={...s.env}:s&&typeof s=="object"&&(r={...s})}catch(n){console.warn("[install] Failed to parse existing settings.json, starting from empty:",n instanceof Error?n.message:String(n)),r={}}else{let n=_u(e);Te(n)||wu(n,{recursive:!0})}for(let[n,s]of Object.entries(t))r[n]=s;return Ou(e,JSON.stringify(r,null,2),"utf-8"),!0}catch(r){return k.error(`Failed to write settings to ${e}: ${r instanceof Error?r.message:String(r)}`),!1}}function uE(){try{if(!Te(Me))return;let t=JSON.parse(Fr(Me,"utf-8")),r=(t.env&&typeof t.env=="object"?t.env:t).CLAUDE_MEM_CLAUDE_AUTH_METHOD;return r==="subscription"||r==="api-key"||r==="gateway"?r:void 0}catch{return}}function Ei(){let t=uE();if(t)return t;let e=dr();return e.ANTHROPIC_BASE_URL?.trim()?"gateway":e.ANTHROPIC_API_KEY?.trim()?"api-key":"subscription"}async function dE(t){return t.runtime!==void 0&&t.runtime!=="worker"&&k.warn(`The "${t.runtime}" runtime was removed in this local-only build \u2014 using the worker runtime instead.`),Le({CLAUDE_MEM_RUNTIME:"worker"}),"worker"}async function pE(t){let e=Zt("CLAUDE_MEM_PROVIDER")||"claude",r=h=>{let S=h??Ei();Le({CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:S})&&k.info("Saved Claude Agent SDK configuration to ~/.keepmind/settings.json")},n=()=>{r("subscription"),pr({ANTHROPIC_API_KEY:"",ANTHROPIC_BASE_URL:"",ANTHROPIC_AUTH_TOKEN:""}),k.info("Configured keepmind to use your logged-in Claude SDK account.")},s=async()=>{let h=dr().ANTHROPIC_API_KEY||"";if(h.trim().length>0){let y=await at({message:"An Anthropic API key is already configured. Keep it or enter a new one?",options:[{value:"keep",label:"Keep existing key"},{value:"replace",label:"Enter a new key (rotate)"}],initialValue:"keep"});if(J(y)){k.warn("API key prompt cancelled \u2014 leaving existing configuration untouched.");return}if(y==="keep"){pr({ANTHROPIC_API_KEY:h.trim(),ANTHROPIC_BASE_URL:"",ANTHROPIC_AUTH_TOKEN:""}),r("api-key");return}}let S=await tn({message:"Paste your Anthropic API key:",mask:"*",validate:y=>!y||y.trim().length===0?"API key required":void 0});if(J(S)){k.warn("API key prompt cancelled \u2014 leaving existing configuration untouched.");return}pr({ANTHROPIC_API_KEY:String(S).trim(),ANTHROPIC_BASE_URL:"",ANTHROPIC_AUTH_TOKEN:""}),r("api-key"),k.info("Saved Anthropic API key for the Claude Agent SDK path.")},o=async()=>{let h=dr(),S=await ar({message:"Gateway URL:",placeholder:h.ANTHROPIC_BASE_URL||"http://localhost:4000",defaultValue:h.ANTHROPIC_BASE_URL||"",validate:R=>{let T=R?.trim()??"";if(!T)return"Gateway URL required";try{new URL(T);return}catch{return"Enter a valid URL, for example http://localhost:4000"}}});if(J(S)){k.warn("Gateway setup cancelled \u2014 leaving existing configuration untouched.");return}let y=await tn({message:"Gateway key/token (leave blank to keep current token, or type a new one):",mask:"*"}),C=J(y),N=C?"":String(y).trim(),D={ANTHROPIC_API_KEY:"",ANTHROPIC_BASE_URL:String(S).trim()};!C&&N.length>0&&(D.ANTHROPIC_AUTH_TOKEN=N),pr(D),r("gateway"),C||N.length===0?k.info("Gateway URL saved; existing gateway token preserved."):k.info("Configured Claude Agent SDK gateway in ~/.keepmind/.env.")};if(!H)return t.provider?t.provider==="claude"?(r(),"claude"):(Le({CLAUDE_MEM_PROVIDER:t.provider})&&k.info(`Saved provider=${t.provider} to ~/.keepmind/settings.json`),k.warn(`Provider=${t.provider} requested non-interactively. API key prompt skipped \u2014 set CLAUDE_MEM_${t.provider.toUpperCase()}_API_KEY and CLAUDE_MEM_PROVIDER in settings.json or env manually if not already set.`),t.provider):e;let i=async()=>{let h=Ei(),y=await at({message:"Do you use a subscription plan or an API key/gateway for the memory agent?",options:[{value:"subscription",label:"Subscription plan (recommended \u2014 uses your logged-in Claude SDK account)"},{value:"api-key",label:"API key or gateway (Anthropic, LiteLLM, or compatible proxy)"}],initialValue:h==="subscription"?"subscription":"api-key"});if(J(y)&&(Oe("Installation cancelled."),process.exit(0)),y==="subscription"){n();return}let C=await at({message:"How should keepmind connect?",options:[{value:"direct",label:"Anthropic API key"},{value:"gateway",label:"LiteLLM or custom gateway"}],initialValue:h==="gateway"||dr().ANTHROPIC_BASE_URL?"gateway":"direct"});J(C)&&(Oe("Installation cancelled."),process.exit(0)),C==="gateway"?await o():await s()},a;if(t.provider)a=t.provider;else{let h=await at({message:"Which memory provider do you want to use?",options:[{value:"claude",label:"Claude Agent SDK (recommended)"},{value:"gemini",label:"Gemini"},{value:"openrouter",label:"OpenRouter"}],initialValue:e});J(h)&&(Oe("Installation cancelled."),process.exit(0)),a=h}if(a==="claude")return await i(),"claude";let l=a==="gemini"?"Gemini":"OpenRouter",c=a==="gemini"?"CLAUDE_MEM_GEMINI_API_KEY":"CLAUDE_MEM_OPENROUTER_API_KEY",d=Zt(c);if(d&&d.trim().length>0)return Le({CLAUDE_MEM_PROVIDER:a})&&k.info(`Saved provider=${a} to ~/.keepmind/settings.json`),a;let m=await tn({message:`Paste your ${l} API key:`,mask:"*",validate:h=>!h||h.trim().length===0?"API key required":void 0});if(J(m))return k.warn("API key prompt cancelled \u2014 falling back to Claude provider."),r(),"claude";let f=String(m).trim();return Le({CLAUDE_MEM_PROVIDER:a,[c]:f})&&k.info(`Saved provider=${a} to ~/.keepmind/settings.json`),a}async function mE(t){let e=new Set(["claude-haiku-4-5-20251001","claude-sonnet-4-6","claude-opus-4-7"]),r=Ei()==="gateway";if(t.model&&!r){if(!e.has(t.model))throw new Error(`Unknown Claude model: ${t.model}. Allowed: ${[...e].join(", ")}`);Le({CLAUDE_MEM_MODEL:t.model})&&k.info(`Saved Claude model=${t.model} to ~/.keepmind/settings.json`);return}if(t.model&&r){Le({CLAUDE_MEM_MODEL:t.model})&&k.info(`Saved gateway model=${t.model} to ~/.keepmind/settings.json`);return}if(!H)return;let n=Zt("CLAUDE_MEM_MODEL");if(r){let l=await ar({message:"Which model should the gateway use?",placeholder:"claude-haiku-4-5-20251001",defaultValue:n||"claude-haiku-4-5-20251001",validate:m=>!m||m.trim().length===0?"Model required":void 0});J(l)&&(Oe("Installation cancelled."),process.exit(0));let c=String(l).trim();Le({CLAUDE_MEM_MODEL:c})&&k.info(`Saved gateway model=${c} to ~/.keepmind/settings.json`);return}let s=e.has(n)?n:"claude-haiku-4-5-20251001",o=await at({message:`Which Claude model should keepmind use to compress observations?
|
|
1349
|
+
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:s});J(o)&&(Oe("Installation cancelled."),process.exit(0));let i=o;Le({CLAUDE_MEM_MODEL:i})&&k.info(`Saved Claude model=${i} to ~/.keepmind/settings.json`)}function EE(){try{if(!Te(Me))return null;let t=JSON.parse(Fr(Me,"utf-8")),e=t.env&&typeof t.env=="object"?t.env:t,r=typeof e.CLAUDE_MEM_ONLINE_SIGNUP_EMAIL=="string"?e.CLAUDE_MEM_ONLINE_SIGNUP_EMAIL:"";return r?{email:r,note:typeof e.CLAUDE_MEM_ONLINE_SIGNUP_NOTE=="string"?e.CLAUDE_MEM_ONLINE_SIGNUP_NOTE:"",sent:e.CLAUDE_MEM_ONLINE_SIGNUP_SENT==="true"}:null}catch{return null}}async function Cu(t){let e=new AbortController,r=setTimeout(()=>e.abort(),5e3);try{return(await fetch(gE,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:t.email,note:t.note,version:t.version,platform:process.platform,source:"npx-installer"}),signal:e.signal})).ok}catch{return!1}finally{clearTimeout(r)}}async function SE(t){if(!H||process.env.CI||String(process.env.CLAUDE_MEM_ONLINE_OPTIN??"").trim().toLowerCase()==="false")return;let e=EE();if(e){e.sent||await Cu({email:e.email,note:e.note,version:t})&&Le({CLAUDE_MEM_ONLINE_SIGNUP_SENT:"true"});return}Rt([E.default.bold(E.default.cyan("New! CMEM Online: every mem everywhere all at once.")),"","Share your email and we'll send you a link. We're rolling this out to our","top users first, then everyone ASAP."].join(`
|
|
1350
|
+
`),"CMEM Online");let r=await ar({message:"Your work email (press Enter to skip):",placeholder:"you@company.com",defaultValue:"",validate:l=>{let c=(l??"").trim();if(c.length!==0&&!hE.test(c))return"That doesn't look like an email \u2014 fix it, or clear the field to skip."}});if(J(r))return;let n=String(r).trim();if(n.length===0)return;let s=await ar({message:"Optionally: what are you working on, or how can we help you and your team? (Enter to skip)",placeholder:"e.g. migrating a monorepo, onboarding a 5-dev team\u2026",defaultValue:""}),o=J(s)?"":String(s).trim(),i=it();i.start("Signing you up for CMEM Online\u2026");let a=await Cu({email:n,note:o,version:t});Le({CLAUDE_MEM_ONLINE_SIGNUP_EMAIL:n,CLAUDE_MEM_ONLINE_SIGNUP_NOTE:o,CLAUDE_MEM_ONLINE_SIGNUP_AT:new Date().toISOString(),CLAUDE_MEM_ONLINE_SIGNUP_SENT:a?"true":"false"}),a?i.stop(`You're on the list \u2014 we'll email ${E.default.cyan(n)} your CMEM Online link.`):i.stop(E.default.yellow(`Saved ${n} \u2014 we'll finish signing you up next time you run the installer.`))}async function bE(){let{detectClaudeMem:t,verifyMigrated:e,purgeClaudeMem:r}=await Promise.resolve().then(()=>(ui(),ci)),{performMigration:n}=await Promise.resolve().then(()=>(Xn(),li)),s=t();if(!s.hasData)return;let o=s.counts,i=o?`${o.observations} observations \xB7 ${o.sessions} sessions \xB7 ${o.summaries} summaries`:"an existing database";Rt(`Found claude-mem at ${s.dataDir}
|
|
1351
|
+
${i}`,"claude-mem detected");let a=await Ct({message:"Migrate these claude-mem memories into keepmind now?"});if(J(a)||!a)return;let l=it();l.start("Migrating claude-mem memories\u2026");try{let g=await n(s.dbPath,{});l.stop(`Migrated ${g.after.observations} observations \xB7 ${g.after.sessions} sessions (${g.mode}).`)}catch(g){l.stop("Migration failed."),K.error(`Migration failed: ${g instanceof Error?g.message:String(g)}`);return}K.info("Vectors rebuild automatically on the next worker start (semantic search).");let c=e(s.dbPath);if(c.missing>0){K.warn(`Keeping claude-mem: ${c.missing} of ${c.total} observations are not yet in keepmind.`);return}let d=c.unhashable>0?` (${c.unhashable} legacy rows without a hash were copied but can't be hash-verified)`:"",m=await Ct({message:`Remove claude-mem entirely now? Its ${c.total} observations are safely in keepmind${d} (a backup is archived first).`,initialValue:!1});if(J(m)||!m)return;let f=it();f.start("Removing claude-mem\u2026");try{let g=await r({timestamp:new Date().toISOString(),presence:s}),h=[];g.dataDirRemoved&&h.push("data removed"),(g.marketplacesRemoved.length||g.pluginsRemoved.length)&&h.push("plugin deregistered"),g.processesKilled&&h.push(`${g.processesKilled} process(es) stopped`),g.archivePath&&h.push(`backup: ${g.archivePath}`),f.stop(`claude-mem removed${h.length?` (${h.join(", ")})`:""}.`),g.errors.length&&K.warn(`Some cleanup steps had issues: ${g.errors.join("; ")}`)}catch(g){f.stop("claude-mem removal encountered an error."),K.warn(`Removal error: ${g instanceof Error?g.message:String(g)}`)}}async function yE(t={}){let e=ol();try{await TE(t,e)}catch(r){if(r instanceof Sr){Ks(e,s=>H?K.message(s):console.error(` ${s}`));let n=`Installation Aborted: ${r.category.id}`;H?(K.error(n),K.error(r.remediation),Ke(E.default.red("keepmind installation aborted."))):(console.error(`
|
|
1352
|
+
${n}`),console.error(` ${r.remediation}`),console.error(` ${r.message}`)),process.exit(1)}throw r}}async function TE(t,e){let r=Mt(),n,s;H?(await Cl(),ir(E.default.bgCyan(E.default.black(" keepmind install ")))):console.log("keepmind install");let o=oe(),i=Te(ge(o,"plugin",".claude-plugin","plugin.json")),a;if(i)try{a=JSON.parse(Fr(ge(o,"plugin",".claude-plugin","plugin.json"),"utf-8")).version??void 0}catch(w){console.warn("[install] Failed to read existing plugin version:",w instanceof Error?w.message:String(w))}let l=E.default.dim("\xB7"),c=[`${E.default.bold("keepmind")} ${E.default.cyan(`v${r}`)}`];if(a&&a!==r?c.push(`installed ${E.default.yellow(`v${a}`)}`):a&&c.push(E.default.dim("reinstall")),k.info(c.join(` ${l} `)),await SE(r),i&&process.stdin.isTTY){let w=await Ct({message:"Overwrite existing installation?",initialValue:!0});(J(w)||!w)&&(Oe("Installation cancelled."),process.exit(0))}let d;if(t.ide){d=[t.ide];let w=Wt(),A=w.find(L=>L.id===t.ide);A&&!A.supported&&(k.error(`Support for ${A.label} coming soon.`),process.exit(1)),A||(k.error(`Unknown IDE: ${t.ide}`),k.info(`Available IDEs: ${w.map(L=>L.id).join(", ")}`),process.exit(1))}else process.stdin.isTTY?d=await aE():d=["claude-code"];H&&await bE();let m=await dE(t);await pE(t)==="claude"&&await mE(t);let g="dead",h=d.length>0;{if(h){let A=Zt("CLAUDE_MEM_WORKER_PORT"),L=H?it():null;L?.start("Stopping running worker (so we can overwrite cleanly)\u2026");try{let $=await Sn(A,1e4);L?L.stop($.workerWasRunning?"Stopped running worker before overwrite.":"No worker running \u2014 proceeding."):$.workerWasRunning&&k.info("Stopped running worker before overwrite.")}catch($){let Ce=$ instanceof Error?$.message:String($);L?L.error(`Pre-overwrite worker shutdown failed: ${Ce}`):console.warn("[install] Pre-overwrite worker shutdown failed:",Ce)}}let w=[{title:"Caching plugin version",task:async A=>(A(`Caching v${r}...`),Au(r),`Plugin cached (v${r}) ${E.default.green("OK")}`)},{title:"Registering marketplace",task:async()=>(Qh(),`Marketplace registered ${E.default.green("OK")}`)},{title:"Registering plugin",task:async()=>($h(r),`Plugin registered ${E.default.green("OK")}`)},{title:"Enabling plugin in Claude settings",task:async()=>(eE(),`Plugin enabled ${E.default.green("OK")}`)},{title:"Setting up runtime (first install can take ~30s)",task:async A=>{A("Checking Bun\u2026");let{version:L}=await jt(e);A("Checking uv\u2026");let{version:$}=await Qs(e);n=L,s=$;let Ce=nt(r);if(!hl(Ce,r)){let{bunPath:$n}=await jt(),Ju=hi(A,"Installing plugin dependencies (bun install)\u2026");try{await En(Ce,$n)}finally{Ju()}$s(Ce,r,L,$)}return`Runtime ready (Bun ${L}, uv ${$}) ${E.default.green("OK")}`}}];h&&(w.unshift({title:"Copying plugin files to marketplace",task:async A=>(A("Copying to marketplace directory..."),lE(),`Plugin files copied ${E.default.green("OK")}`)}),w.push({title:"Installing marketplace dependencies",task:async A=>{let{bunPath:L}=await jt(),$=hi(A,"Installing plugin dependencies (bun install)\u2026");try{await En(ge(oe(),"plugin"),L)}finally{$()}let Ce=hi(A,"Running npm install\u2026");try{await cE(e)}finally{Ce()}return`Dependencies installed ${E.default.green("OK")}`}})),await Yn(w)}let S=await nE(d,e),y=null,C=await tE(d,t);if(C==="disable")try{let w=Nu();y=w?"disabled":"already-disabled",w?k.success("Claude Code: auto-memory disabled (CLAUDE_CODE_DISABLE_AUTO_MEMORY=1)."):k.info("Claude Code: auto-memory already disabled, leaving settings.json untouched.")}catch(w){y="failed",ce("WARN_CONTINUE",{component:"auto-memory",phase:"post-ide",cause:w},e)}else C==="leave-enabled"&&(y="left-enabled",k.info("Claude Code: leaving native auto-memory enabled unless you explicitly opt in to disabling it."));let N=!H||t.noAutoStart||m==="server";await Yn([{title:m==="server"?"Starting server daemon":"Starting worker daemon",task:async w=>{if(m==="server")return`Server runtime selected \u2014 start it with ${E.default.bold("npx keepmind server start")} ${E.default.dim("(or via Docker compose)")}`;if(N)return H?"Skipped (--no-auto-start)":"Skipped (non-TTY)";let A=Number(Zt("CLAUDE_MEM_WORKER_PORT")),L=ge(oe(),"plugin","scripts","worker-service.cjs"),$=ge(nt(r),"scripts","worker-service.cjs"),Ce=Te(L)?L:$;switch(w(`Spawning worker on port ${A}...`),g=await tl(A,Ce),g){case"ready":return`Worker ready at http://localhost:${A} ${E.default.green("OK")}`;case"warming":return`Worker starting on port ${A} \u2014 finishing in background ${E.default.yellow("\u23F3")}`;case"dead":return`Worker did not start \u2014 try \`npx keepmind start\` manually ${E.default.yellow("!")}`}}}]);let R=e.failedIDEs.length>0?"Installation Partial":"Installation Complete",T=[`Version: ${E.default.cyan(r)}`,`Plugin dir: ${E.default.cyan(o)}`,`IDEs: ${E.default.cyan(d.join(", "))}`];y==="disabled"?T.push(`Auto-memory: ${E.default.cyan("disabled")} (CLAUDE_CODE_DISABLE_AUTO_MEMORY=1)`):y==="already-disabled"?T.push(`Auto-memory: ${E.default.cyan("already disabled")} (CLAUDE_CODE_DISABLE_AUTO_MEMORY=1)`):y==="left-enabled"?T.push(`Auto-memory: ${E.default.cyan("left enabled")} (native Claude Code memory preserved)`):y==="failed"&&T.push(`Auto-memory: ${E.default.red("write failed")} (see warning above)`),S.length>0&&T.push(`Failed: ${E.default.red(S.join(", "))}`),H?Rt(T.join(`
|
|
1353
|
+
`),R):(console.log(`
|
|
1354
|
+
${R}`),T.forEach(w=>console.log(` ${w}`))),Ks(e,w=>H?K.message(w):console.log(` ${w}`));let v=Zt("CLAUDE_MEM_WORKER_PORT"),I=v,Y=!1;if(!N){let w=H?it():null;w?.start(`Verifying worker on port ${v}\u2026`);try{let A=await fetch(`http://127.0.0.1:${v}/api/health`,{signal:AbortSignal.timeout(3e3)});if(A.ok){Y=!0;try{let L=await A.json();L&&(typeof L.port=="number"||typeof L.port=="string")&&(I=L.port)}catch{}}w?.stop(Y?`Worker ready at http://localhost:${I}`:`Worker reachable but not ready on port ${v}`)}catch{w?.stop(`Worker not yet responding on port ${v} (still starting)`)}}let Z=g,ve=Z!=="dead"||Y,Q=m==="server"?"Server":"Worker",At=m==="server"?"npx keepmind server start":"npx keepmind start",tt=N?`${E.default.yellow("!")} ${Q} autostart skipped \u2014 start it manually with ${E.default.bold(At)}`:Y||Z==="ready"?`${E.default.green("\u2713")} ${Q} running at ${E.default.underline(`http://localhost:${I}`)}`:`${E.default.yellow("\u23F3")} ${Q} starting at ${E.default.underline(`http://localhost:${I}`)} \u2014 give it ~30s, then refresh`,G=N?[tt,"",`${E.default.bold("First success:")} once the worker is running, keep ${E.default.underline(`http://localhost:${v}`)} open in a browser, then open Claude Code in any project. Observations stream in as Claude reads, edits, and runs commands.`,"",`${E.default.bold("Two paths from here:")}`,` ${E.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${E.default.cyan("B.")} Front-load it: open Claude Code and run ${E.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 ${E.default.cyan("~/.keepmind")} on this machine.`,"",`${E.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${E.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.keepmind will be recreated by active hooks.")}`]:ve?[tt,"",`${E.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.`,"",`${E.default.bold("Two paths from here:")}`,` ${E.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${E.default.cyan("B.")} Front-load it: open Claude Code and run ${E.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 ${E.default.cyan("~/.keepmind")} on this machine.`,"",`${E.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${E.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.keepmind will be recreated by active hooks.")}`]:[`${E.default.yellow("!")} Worker not yet ready on port ${E.default.cyan(String(v))} -- still starting up; check ${E.default.bold("keepmind status")} later, or start manually: ${E.default.bold("npx keepmind start")}`,"",`${E.default.bold("First success:")} keep ${E.default.underline(`http://localhost:${v}`)} open in a browser, then open Claude Code in any project. Observations stream in as Claude reads, edits, and runs commands.`,"",`${E.default.bold("Two paths from here:")}`,` ${E.default.cyan("A.")} Just start working. Memory builds passively from your first prompt. (Recommended.)`,` ${E.default.cyan("B.")} Front-load it: open Claude Code and run ${E.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 ${E.default.cyan("~/.keepmind")} on this machine.`,"",`${E.default.dim("How it works: /how-it-works \xB7 Disable first-session hint: CLAUDE_MEM_WELCOME_HINT_ENABLED=false")}`,`${E.default.dim("Note: close all Claude Code sessions before uninstalling, or ~/.keepmind will be recreated by active hooks.")}`];H?(Rt(G.join(`
|
|
1355
|
+
`),"Next Steps"),S.length>0?Ke(E.default.yellow("keepmind installed with some IDE setup failures.")):Ke(E.default.green("keepmind installed successfully!"))):(console.log(`
|
|
1356
|
+
Next Steps`),G.forEach(w=>console.log(` ${w}`)),S.length>0?(console.log(`
|
|
1357
|
+
keepmind installed with some IDE setup failures.`),process.exitCode=1):console.log(`
|
|
1358
|
+
keepmind installed successfully!`))}async function vE(){let t=Mt(),e=nt(t);H?ir(E.default.bgCyan(E.default.black(" keepmind repair "))):console.log("keepmind repair"),k.info(`Version: ${E.default.cyan(t)}`),await Yn([{title:"Setting up runtime",task:async r=>{r("Checking Bun\u2026");let{version:n}=await jt();r("Checking uv\u2026");let{version:s}=await Qs();Te(ge(e,"package.json"))||(r("Cache missing \u2014 repopulating from npm package\u2026"),Au(t)),r("Reinstalling plugin dependencies\u2026");let{bunPath:o}=await jt();return await En(e,o),$s(e,t,n,s),`Runtime ready (Bun ${n}, uv ${s}) ${E.default.green("OK")}`}}]),H?Ke(E.default.green("keepmind repair complete.")):console.log("keepmind repair complete.")}var E,H,k,fE,gE,hE,zn=b(()=>{"use strict";vs();E=He(rt(),1);Lt();lt();V();wa();rl();El();Rl();fn();Xs();Ol();Ae();$t();ro();_l();H=process.stdin.isTTY===!0;k={info:t=>H?K.info(t):console.log(` ${t}`),success:t=>H?K.success(t):console.log(` ${t}`),warn:t=>H?K.warn(t):console.warn(` ${t}`),error:t=>H?K.error(t):console.error(` ${t}`)};fE="https://cmem.ai/api/waitlist",gE=process.env.CLAUDE_MEM_SIGNUP_URL?.trim()||fE,hE=/^[^\s@]+@[^\s@]+\.[^\s@]+$/});var Lu={};de(Lu,{removeFromClaudeSettings:()=>xu,runUninstallCommand:()=>AE});import{existsSync as _t,readFileSync as CE,readdirSync as Si,rmSync as jr,writeFileSync as RE}from"fs";import{homedir as Mu}from"os";import{join as Ge}from"path";function wE(){let t=oe();return _t(t)?(jr(t,{recursive:!0,force:!0}),!0):!1}function IE(){let t=Ge(Re(),"cache","keepmind","keepmind");return _t(t)?(jr(t,{recursive:!0,force:!0}),!0):!1}function OE(){let t=z(De(),{});t.keepmind&&(delete t.keepmind,re(De(),t))}function kE(){let t=z(Pe(),{});t.plugins?.["keepmind@keepmind"]&&(delete t.plugins["keepmind@keepmind"],re(Pe(),t))}function _E(){let t=Mu(),e=[Ge(t,".bashrc"),Ge(t,".zshrc"),Ge(t,"Documents","PowerShell","Microsoft.PowerShell_profile.ps1")],r=/^\s*alias\s+claude-mem\s*=/;for(let n of e){if(!_t(n))continue;let s;try{s=CE(n,"utf-8")}catch(a){console.warn(`[uninstall] Could not read ${n}:`,a instanceof Error?a.message:String(a));continue}let o=s.split(`
|
|
1359
|
+
`),i=o.filter(a=>!r.test(a));if(i.length!==o.length)try{RE(n,i.join(`
|
|
1360
|
+
`)),console.error(`Removed legacy claude-mem alias from ${n}`)}catch(a){console.warn(`[uninstall] Could not rewrite ${n}:`,a instanceof Error?a.message:String(a))}}}function xu(){let t=z(we(),{}),e=!1;t.enabledPlugins?.["keepmind@keepmind"]!==void 0&&(delete t.enabledPlugins["keepmind@keepmind"],e=!0),t.env&&typeof t.env=="object"&&!Array.isArray(t.env)&&Object.prototype.hasOwnProperty.call(t.env,"CLAUDE_CODE_DISABLE_AUTO_MEMORY")&&t.env.CLAUDE_CODE_DISABLE_AUTO_MEMORY==="1"&&(delete t.env.CLAUDE_CODE_DISABLE_AUTO_MEMORY,e=!0,Object.keys(t.env).length===0&&delete t.env),e&&re(we(),t)}function NE(){let t=Mu(),e=0,r=Ge(t,".npm","_npx");if(_t(r)){let o=[];try{o=Si(r)}catch(i){console.warn(`[uninstall] Could not read ${r}:`,i instanceof Error?i.message:String(i))}for(let i of o){let a=Ge(r,i,"node_modules","keepmind");if(_t(a))try{jr(a,{recursive:!0,force:!0}),e++}catch(l){console.warn(`[uninstall] Could not remove ${a}:`,l instanceof Error?l.message:String(l))}}}let n=Ge(t,".cache","claude-cli-nodejs");if(_t(n)){let o=[];try{o=Si(n)}catch(i){console.warn(`[uninstall] Could not read ${n}:`,i instanceof Error?i.message:String(i))}for(let i of o){let a=Ge(n,i),l=[];try{l=Si(a)}catch(c){console.warn(`[uninstall] Could not read ${a}:`,c instanceof Error?c.message:String(c));continue}for(let c of l){if(!c.startsWith("mcp-logs-plugin-claude-mem-"))continue;let d=Ge(a,c);try{jr(d,{recursive:!0,force:!0}),e++}catch(m){console.warn(`[uninstall] Could not remove ${d}:`,m instanceof Error?m.message:String(m))}}}}let s=Ge(t,".claude","plugins","data","keepmind-keepmind");if(_t(s))try{jr(s,{recursive:!0,force:!0}),e++}catch(o){console.warn(`[uninstall] Could not remove ${s}:`,o instanceof Error?o.message:String(o))}return e}async function AE(){if(ir(he.default.bgRed(he.default.white(" claude-mem uninstall "))),xt()){if(process.stdin.isTTY){let r=await Ct({message:"Are you sure you want to uninstall claude-mem?",initialValue:!1});if(J(r)||!r){Oe("Uninstall cancelled.");return}}}else if(K.warn("claude-mem does not appear to be installed."),process.stdin.isTTY){let r=await Ct({message:"Clean up any remaining registration data anyway?",initialValue:!1});if(J(r)||!r){Ke("Nothing to do.");return}}else{Ke("Nothing to do.");return}let t=le.get("CLAUDE_MEM_WORKER_PORT");try{(await Sn(t,1e4)).workerWasRunning&&K.info("Worker service stopped.")}catch(r){console.warn("[uninstall] Worker shutdown attempt failed:",r instanceof Error?r.message:String(r))}await rn([{title:"Removing marketplace directory",task:async()=>wE()?`Marketplace directory removed ${he.default.green("OK")}`:`Marketplace directory not found ${he.default.dim("skipped")}`},{title:"Removing cache directory",task:async()=>IE()?`Cache directory removed ${he.default.green("OK")}`:`Cache directory not found ${he.default.dim("skipped")}`},{title:"Removing marketplace registration",task:async()=>(OE(),`Marketplace registration removed ${he.default.green("OK")}`)},{title:"Removing plugin registration",task:async()=>(kE(),`Plugin registration removed ${he.default.green("OK")}`)},{title:"Removing from Claude settings",task:async()=>(xu(),`Claude settings updated ${he.default.green("OK")}`)},{title:"Removing legacy claude-mem shell alias",task:async()=>(_E(),`Legacy alias check complete ${he.default.green("OK")}`)},{title:"Removing stray claude-mem caches and logs",task:async()=>{let r=NE();return r>0?`Stray paths removed: ${r} ${he.default.green("OK")}`:`No stray paths found ${he.default.dim("skipped")}`}}]);let e=[{label:"Gemini CLI hooks",fn:async()=>{let{uninstallGeminiCliHooks:r}=await Promise.resolve().then(()=>(So(),Eo));return r()}},{label:"Windsurf hooks",fn:async()=>{let{uninstallWindsurfHooks:r}=await Promise.resolve().then(()=>(No(),_o));return r()}},{label:"OpenCode plugin",fn:async()=>{let{uninstallOpenCodePlugin:r}=await Promise.resolve().then(()=>(Io(),wo));return r()}},{label:"OpenClaw plugin",fn:async()=>{let{uninstallOpenClawPlugin:r}=await Promise.resolve().then(()=>(Do(),Lo));return r()}},{label:"Codex CLI",fn:async()=>{let{uninstallCodexCli:r}=await Promise.resolve().then(()=>(Xo(),Ko));return r()}}];for(let{label:r,fn:n}of e)try{await n()===0&&K.info(`${r}: removed.`)}catch(s){console.warn(`[uninstall] ${r} cleanup failed:`,s instanceof Error?s.message:String(s))}Rt([`Your data directory at ${he.default.cyan("~/.keepmind")} was preserved.`,"To remove it manually: rm -rf ~/.keepmind"].join(`
|
|
1361
|
+
`),"Note"),Ke(he.default.green("claude-mem has been uninstalled."))}var he,Du=b(()=>{"use strict";vs();he=He(rt(),1);Ae();$t();lt();ro()});var $e={};de($e,{runAdoptCommand:()=>PE,runCleanupCommand:()=>UE,runRestartCommand:()=>Ci,runSearchCommand:()=>FE,runServerApiKeyCommand:()=>wi,runStartCommand:()=>Ti,runStatusCommand:()=>Ri,runStopCommand:()=>vi,runTranscriptWatchCommand:()=>jE});import{existsSync as Qt,readdirSync as ME,readFileSync as xE}from"fs";import{dirname as LE,join as Wr}from"path";function Zn(){xt()||(console.error(Ee.default.red("keepmind is not installed.")),console.error(`Run: ${Ee.default.bold("npx keepmind install")}`),process.exit(1))}function bi(){let t=mn();return t||(console.error(Ee.default.red("Node.js runtime not found.")),console.error("keepmind requires Node.js >= 22.5 \u2014 install it from https://nodejs.org"),console.error("After installation, restart your terminal."),process.exit(1)),t}function DE(){try{let t=JSON.parse(xE(Wr(oe(),"plugin",".claude-plugin","plugin.json"),"utf-8"));return typeof t?.version=="string"?t.version:null}catch{return null}}function Pu(t){let e=DE();if(e){let n=Wr(nt(e),"scripts",t);if(Qt(n))return n}let r=Wr(Re(),"cache","keepmind","keepmind");if(Qt(r))for(let n of ME(r)){let s=Wr(r,n,"scripts",t);if(Qt(s))return s}return Wr(oe(),"plugin","scripts",t)}function Uu(){return Pu("worker-service.cjs")}function yi(t,e,r="worker"){let n=Xe(t,e,{stdio:"inherit",cwd:LE(e[0]),env:It(process.env)});n.on("error",s=>{console.error(Ee.default.red(`Failed to start ${r}: ${s.message}`)),process.exit(1)}),n.on("close",s=>{process.exit(s??0)})}function Nt(t,e=[]){Zn();let r=bi(),n=Uu();Qt(n)||(console.error(Ee.default.red(`Worker script not found at: ${n}`)),console.error("The installation may be corrupted. Try: npx keepmind install"),process.exit(1)),yi(r,[n,t,...e])}function Ti(){Nt("start")}function vi(){Nt("stop")}function Ci(){Nt("restart")}function Ri(){Nt("status")}function wi(t=[]){Nt("server",["api-key",...t])}function PE(t=[]){Zn();let e=bi(),r=Uu();Qt(r)||(console.error(Ee.default.red(`Worker script not found at: ${r}`)),console.error("The installation may be corrupted. Try: npx keepmind install"),process.exit(1));let n=process.cwd();yi(e,[r,"adopt","--cwd",n,...t])}function UE(t=[]){Nt("cleanup",t)}async function FE(t){Zn();let e=t.join(" ").trim();e||(console.error(Ee.default.red("Usage: npx keepmind search <query>")),process.exit(1));let n=`http://127.0.0.1:${le.get("CLAUDE_MEM_WORKER_PORT")}/api/search?query=${encodeURIComponent(e)}`,s;try{s=await fetch(n)}catch(i){let a=i instanceof Error?i.message:String(i);((i instanceof Error?i.cause:void 0)?.code==="ECONNREFUSED"||a.includes("ECONNREFUSED"))&&(console.error(Ee.default.red("Worker is not running.")),console.error(`Start it with: ${Ee.default.bold("npx keepmind start")}`),process.exit(1)),console.error(Ee.default.red(`Search failed: ${a}`)),process.exit(1)}s.ok||(s.status===404&&(console.error(Ee.default.red("Search endpoint not found. Is the worker running?")),console.error(`Try: ${Ee.default.bold("npx keepmind start")}`),process.exit(1)),console.error(Ee.default.red(`Search failed: HTTP ${s.status}`)),process.exit(1));let o;try{o=await s.json()}catch(i){let a=i instanceof Error?i.message:String(i);console.error(Ee.default.red(`Search failed: invalid JSON response (${a})`)),process.exit(1)}console.log(typeof o=="object"&&o!==null?JSON.stringify(o,null,2):o)}function jE(){Zn();let t=bi(),e=Pu("transcript-watcher.cjs");if(!Qt(e)){Nt("transcript",["watch"]);return}yi(t,[e,"watch"],"transcript watcher")}var Ee,Be=b(()=>{"use strict";Lt();an();Ee=He(rt(),1);gr();Ae();lt()});var Wu={};de(Wu,{runDoctorCommand:()=>GE});import{existsSync as Ii,readFileSync as Fu}from"fs";import{join as Oi}from"path";import{spawnSync as WE}from"child_process";function ju(t){try{let e=WE(t,["--version"],{encoding:"utf-8",stdio:["pipe","pipe","pipe"],shell:W});return e.status===0?e.stdout.trim():null}catch{return null}}async function GE(){let t=[],e=ut(),r=ju("bun");t.push({name:"Bun runtime",status:r?"ok":"fail",detail:r?`v${r.replace(/^v/,"")}`:"not found on PATH \u2014 install: https://bun.sh",required:!0});let n=ju("uv");t.push({name:"uv (vector search)",status:n?"ok":"warn",detail:n||"not found \u2014 vector/semantic search disabled until installed",required:!1});let s=xt();t.push({name:"Plugin installed",status:s?"ok":"fail",detail:s?oe():"run `npx keepmind install`",required:!0});let o=Oi(oe(),"node_modules"),i=Ii(o);t.push({name:"Marketplace deps",status:s?i?"ok":"fail":"warn",detail:i?"node_modules present":"missing \u2014 run `npx keepmind repair`",required:s});let a=(()=>{try{let g=Oi(ut(),"worker.pid");if(Ii(g)){let h=JSON.parse(Fu(g,"utf-8"));if(typeof h.pid=="number"&&typeof h.port=="number")try{return process.kill(h.pid,0),String(h.port)}catch(S){if(S?.code==="EPERM")return String(h.port)}}}catch{}return le.get("CLAUDE_MEM_WORKER_PORT")})(),l="fail",c=`no response on port ${a} \u2014 start with \`npx keepmind start\``;try{let g=await fetch(`http://127.0.0.1:${a}/api/health`,{signal:AbortSignal.timeout(3e3)});g.ok?(l="ok",c=`healthy at http://127.0.0.1:${a}`):(l="warn",c=`reachable but unhealthy (HTTP ${g.status}) on port ${a}`)}catch{}t.push({name:"Worker daemon",status:l,detail:c,required:!1});let d=Oi(e,"last-install-error.json");if(Ii(d)){let g=`present at ${d}`;try{let h=JSON.parse(Fu(d,"utf-8"));h&&typeof h=="object"&&(g=`${h.categoryId??"error"}: ${h.remediation??g}`)}catch{}t.push({name:"Last install error",status:"warn",detail:g,required:!1})}let m=g=>g==="ok"?yt.default.green("\u2713"):g==="warn"?yt.default.yellow("!"):yt.default.red("\u2717");console.log(yt.default.bold(`
|
|
1362
|
+
keepmind doctor
|
|
1363
|
+
`));for(let g of t)console.log(` ${m(g.status)} ${g.name.padEnd(22)} ${yt.default.dim(g.detail)}`);let f=t.filter(g=>g.required&&g.status==="fail");console.log(""),f.length===0?(console.log(yt.default.green("All required checks passed.")),process.exit(0)):(console.log(yt.default.red(`${f.length} required check(s) failed \u2014 see remediation above.`)),process.exit(1))}var yt,Gu=b(()=>{"use strict";yt=He(rt(),1);Ae();lt();V()});var ki={};de(ki,{runServerCommand:()=>HE,runWorkerAliasCommand:()=>JE});function Bu(){console.error(`Usage: ${Gr.default.bold("npx keepmind server <command>")}`),console.error("Commands: api-key create|list|revoke")}function BE(t){switch(t){case"start":return Ti(),!0;case"stop":return vi(),!0;case"restart":return Ci(),!0;case"status":return Ri(),!0;default:return!1}}async function HE(t=[]){let e=t[0]?.toLowerCase();if(e||(Bu(),process.exit(1)),e==="api-key"){let r=t[1]?.toLowerCase();if(r==="create"||r==="list"||r==="revoke"){wi(t.slice(1));return}console.error(Gr.default.red(`Unknown server api-key subcommand: ${r??"(none)"}`)),console.error("Usage: npx keepmind server api-key create|list|revoke"),process.exit(1)}console.error(Gr.default.red(`Unknown server command: ${e}`)),Bu(),process.exit(1)}function JE(t=[]){let e=t[0]?.toLowerCase();(!e||!BE(e))&&(console.error(Gr.default.red(`Unknown worker command: ${e??"(none)"}`)),console.error("Usage: npx keepmind worker start|stop|restart|status"),process.exit(1))}var Gr,_i=b(()=>{"use strict";Gr=He(rt(),1);Be()});var x=He(rt(),1);Ae();var et=process.argv.slice(2),Ni=et[0]?.toLowerCase()??"",KE=new Set(["-h","--help","-v","--version"]),Hu=Ni.startsWith("-")&&!KE.has(Ni)?"install":Ni;function XE(){let t=Mt();console.log(`
|
|
1364
|
+
${x.default.bold("keepmind")} v${t} \u2014 persistent memory for AI coding assistants
|
|
1365
|
+
|
|
1366
|
+
${x.default.bold("Install Commands")} (no Bun required):
|
|
1367
|
+
${x.default.cyan("npx keepmind")} Interactive install
|
|
1368
|
+
${x.default.cyan("npx keepmind install")} Interactive install
|
|
1369
|
+
${x.default.cyan("npx keepmind install --ide <id>")} Install for specific IDE
|
|
1370
|
+
${x.default.cyan("npx keepmind install --provider claude|gemini|openrouter")} Set LLM provider non-interactively
|
|
1371
|
+
${x.default.cyan("npx keepmind install --model <id>")} Set Claude model (when provider=claude)
|
|
1372
|
+
${x.default.cyan("npx keepmind install --no-auto-start")} Skip worker auto-start at the end
|
|
1373
|
+
${x.default.cyan("npx keepmind install --disable-auto-memory")} Explicitly disable Claude Code native auto-memory
|
|
1374
|
+
${x.default.cyan("npx keepmind repair")} Repair runtime (re-runs Bun/uv setup and bun install in plugin cache)
|
|
1375
|
+
${x.default.cyan("npx keepmind update")} Update to latest version
|
|
1376
|
+
${x.default.cyan("npx keepmind uninstall")} Remove plugin and configs
|
|
1377
|
+
${x.default.cyan("npx keepmind version")} Print version
|
|
1378
|
+
|
|
1379
|
+
${x.default.bold("Runtime Commands")} (requires Bun, delegates to installed plugin):
|
|
1380
|
+
${x.default.cyan("npx keepmind start")} Start worker service
|
|
1381
|
+
${x.default.cyan("npx keepmind stop")} Stop worker service
|
|
1382
|
+
${x.default.cyan("npx keepmind restart")} Restart worker service
|
|
1383
|
+
${x.default.cyan("npx keepmind status")} Show worker status
|
|
1384
|
+
${x.default.cyan("npx keepmind doctor")} Diagnose install/runtime health (bun, uv, worker)
|
|
1385
|
+
${x.default.cyan("npx keepmind server api-key create|list|revoke")} Manage local SQLite API keys (for the local v1 routes)
|
|
1386
|
+
${x.default.cyan("npx keepmind worker start|stop|restart|status")} Worker compatibility aliases
|
|
1387
|
+
${x.default.cyan("npx keepmind search <query>")} Search observations
|
|
1388
|
+
${x.default.cyan("npx keepmind adopt [--dry-run] [--branch <name>]")} Stamp merged worktrees into parent project
|
|
1389
|
+
${x.default.cyan("npx keepmind cleanup [--dry-run]")} Run one-time v12.4.3 pollution cleanup (or preview counts)
|
|
1390
|
+
${x.default.cyan("npx keepmind migrate [--from <dir>] [--dry-run]")} Import an existing claude-mem database (lossless, non-destructive)
|
|
1391
|
+
${x.default.cyan("npx keepmind migrate --purge --yes")} Import, then remove claude-mem entirely (archives it first; requires a verified-complete migration)
|
|
1392
|
+
${x.default.cyan("npx keepmind transcript watch")} Start transcript watcher
|
|
1393
|
+
|
|
1394
|
+
${x.default.bold("IDE Identifiers")}:
|
|
1395
|
+
claude-code, cursor, gemini-cli, opencode, openclaw,
|
|
1396
|
+
windsurf, codex-cli, copilot-cli, antigravity, goose,
|
|
1397
|
+
roo-code, warp
|
|
1398
|
+
`)}function Qn(t,e){let r=t.indexOf(e);if(r===-1)return;let n=t[r+1];return(n===void 0||n.startsWith("-"))&&(console.error(x.default.red(`Flag ${e} requires a value.`)),process.exit(1)),n}function VE(t){let e=Qn(t,"--provider");e!==void 0&&e!=="claude"&&e!=="gemini"&&e!=="openrouter"&&(console.error(`Unknown --provider: ${e}. Allowed: claude, gemini, openrouter`),process.exit(1));let r=Qn(t,"--runtime");return r!==void 0&&r!=="worker"&&console.error(`Note: the "${r}" runtime was removed; using the worker runtime.`),{ide:Qn(t,"--ide"),provider:e,model:Qn(t,"--model"),noAutoStart:t.includes("--no-auto-start"),disableAutoMemory:t.includes("--disable-auto-memory"),runtime:r}}async function YE(){switch(Hu){case"":case"install":{let{runInstallCommand:t}=await Promise.resolve().then(()=>(zn(),qn));await t(VE(et));break}case"repair":{let{runRepairCommand:t}=await Promise.resolve().then(()=>(zn(),qn));await t();break}case"update":case"upgrade":{let{runInstallCommand:t}=await Promise.resolve().then(()=>(zn(),qn));await t();break}case"uninstall":case"remove":{let{runUninstallCommand:t}=await Promise.resolve().then(()=>(Du(),Lu));await t();break}case"version":case"--version":case"-v":{console.log(Mt());break}case"help":case"--help":case"-h":{XE();break}case"start":{let{runStartCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t();break}case"stop":{let{runStopCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t();break}case"restart":{let{runRestartCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t();break}case"status":{let{runStatusCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t();break}case"doctor":{let{runDoctorCommand:t}=await Promise.resolve().then(()=>(Gu(),Wu));await t();break}case"server":{let{runServerCommand:t}=await Promise.resolve().then(()=>(_i(),ki));await t(et.slice(1));break}case"worker":{let{runWorkerAliasCommand:t}=await Promise.resolve().then(()=>(_i(),ki));t(et.slice(1));break}case"search":{let{runSearchCommand:t}=await Promise.resolve().then(()=>(Be(),$e));await t(et.slice(1));break}case"adopt":{let{runAdoptCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t(et.slice(1));break}case"cleanup":{let{runCleanupCommand:t}=await Promise.resolve().then(()=>(Be(),$e));t(et.slice(1));break}case"migrate":{let{runMigrateCommand:t}=await Promise.resolve().then(()=>(Xn(),li));await t(et.slice(1));break}case"transcript":{let t=et[1]?.toLowerCase();if(t==="watch"){let{runTranscriptWatchCommand:e}=await Promise.resolve().then(()=>(Be(),$e));e()}else console.error(x.default.red(`Unknown transcript subcommand: ${t??"(none)"}`)),console.error("Usage: npx keepmind transcript watch"),process.exit(1);break}default:console.error(x.default.red(`Unknown command: ${Hu}`)),console.error(`Run ${x.default.bold("npx keepmind --help")} for usage information.`),process.exit(1)}}YE().catch(t=>{console.error(x.default.red("Fatal error:"),t.message||t),process.exit(1)});
|