diff --git a/plugin/scripts/context-generator.cjs b/plugin/scripts/context-generator.cjs index 336140a1..70fdecb2 100644 --- a/plugin/scripts/context-generator.cjs +++ b/plugin/scripts/context-generator.cjs @@ -6,7 +6,7 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?m=` `,"utf8")}catch(T){process.stderr.write(`[LOGGER] Failed to write to log file: ${T} `)}else process.stderr.write(E+` `)}debug(e,t,s,n){this.log(0,e,t,s,n)}info(e,t,s,n){this.log(1,e,t,s,n)}warn(e,t,s,n){this.log(2,e,t,s,n)}error(e,t,s,n){this.log(3,e,t,s,n)}dataIn(e,t,s,n){this.info(e,`\u2192 ${t}`,s,n)}dataOut(e,t,s,n){this.info(e,`\u2190 ${t}`,s,n)}success(e,t,s,n){this.info(e,`\u2713 ${t}`,s,n)}failure(e,t,s,n){this.error(e,`\u2717 ${t}`,s,n)}timing(e,t,s,n){this.info(e,`\u23F1 ${t}`,n,{duration:`${s}ms`})}happyPathError(e,t,s,n,o=""){let u=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),m=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",l={...s,location:m};return this.warn(e,`[HAPPY-PATH] ${t}`,l,n),o}},_=new Z;var wt={};function kt(){return typeof __dirname<"u"?__dirname:(0,f.dirname)((0,be.fileURLToPath)(wt.url))}var $t=kt();function Ft(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let r=(0,f.join)((0,ee.homedir)(),".claude-mem"),e=(0,f.join)(r,"settings.json");try{if((0,P.existsSync)(e)){let{readFileSync:t}=require("fs"),s=JSON.parse(t(e,"utf-8")),n=s.env??s;if(n.CLAUDE_MEM_DATA_DIR)return n.CLAUDE_MEM_DATA_DIR}}catch{}return r}var N=Ft(),y=process.env.CLAUDE_CONFIG_DIR||(0,f.join)((0,ee.homedir)(),".claude"),os=(0,f.join)(y,"plugins","marketplaces","thedotmack"),is=(0,f.join)(N,"archives"),as=(0,f.join)(N,"logs"),ds=(0,f.join)(N,"trash"),cs=(0,f.join)(N,"backups"),us=(0,f.join)(N,"modes"),ms=(0,f.join)(N,"settings.json"),he=(0,f.join)(N,"claude-mem.db"),_s=(0,f.join)(N,"vector-db"),ps=(0,f.join)(N,"observer-sessions"),ls=(0,f.join)(y,"settings.json"),Es=(0,f.join)(y,"commands"),gs=(0,f.join)(y,"CLAUDE.md");function Oe(r){(0,P.mkdirSync)(r,{recursive:!0})}function Ae(){return(0,f.join)($t,"..")}var Le=require("crypto");var Ne=require("os"),Ce=L(require("path"),1);var j=require("fs"),H=L(require("path"),1),v={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function Re(r){let e=H.default.join(r,".git"),t;try{t=(0,j.statSync)(e)}catch{return v}if(!t.isFile())return v;let s;try{s=(0,j.readFileSync)(e,"utf-8").trim()}catch{return v}let n=s.match(/^gitdir:\s*(.+)$/);if(!n)return v;let i=n[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return v;let a=i[1],d=H.default.basename(r),u=H.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:u}}function Ie(r){return r==="~"||r.startsWith("~/")?r.replace(/^~/,(0,Ne.homedir)()):r}function Pt(r){if(!r||r.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:r}),"unknown-project";let e=Ie(r),t=Ce.default.basename(e);if(t===""){if(process.platform==="win32"){let n=r.match(/^([A-Z]):\\/i);if(n){let i=`drive-${n[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:r,projectName:i}),i}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:r}),"unknown-project"}return t}function te(r){let e=Pt(r);if(!r)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let t=Ie(r),s=Re(t);if(s.isWorktree&&s.parentProjectName){let n=`${s.parentProjectName}/${e}`;return{primary:n,parent:s.parentProjectName,isWorktree:!0,allProjects:[n]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var Ht=3e4;function X(r,e,t){return(0,Le.createHash)("sha256").update([r||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function G(r,e,t){let s=t-Ht;return r.prepare("SELECT id, created_at_epoch FROM observations WHERE content_hash = ? AND created_at_epoch > ?").get(e,s)}function se(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[String(e)]}catch{return[r]}}var h="claude";function jt(r){return r.trim().toLowerCase().replace(/\s+/g,"-")}function D(r){if(!r)return h;let e=jt(r);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:h}function ye(r){let e=["claude","codex","cursor"];return[...r].sort((t,s)=>{let n=e.indexOf(t),o=e.indexOf(s);return n!==-1||o!==-1?n===-1?1:o===-1?-1:n-o:t.localeCompare(s)})}function Xt(r,e){return{customTitle:r,platformSource:e?D(e):void 0}}var B=class{db;constructor(e=he){e!==":memory:"&&Oe(N),this.db=new De.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),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()}initializeSchema(){this.db.run(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),m=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",l={...s,location:m};return this.warn(e,`[HAPPY-PATH] ${t}`,l,n),o}},_=new Z;var wt={};function kt(){return typeof __dirname<"u"?__dirname:(0,f.dirname)((0,be.fileURLToPath)(wt.url))}var $t=kt();function Ft(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let r=(0,f.join)((0,ee.homedir)(),".claude-mem"),e=(0,f.join)(r,"settings.json");try{if((0,P.existsSync)(e)){let{readFileSync:t}=require("fs"),s=JSON.parse(t(e,"utf-8")),n=s.env??s;if(n.CLAUDE_MEM_DATA_DIR)return n.CLAUDE_MEM_DATA_DIR}}catch{}return r}var N=Ft(),y=process.env.CLAUDE_CONFIG_DIR||(0,f.join)((0,ee.homedir)(),".claude"),os=(0,f.join)(y,"plugins","marketplaces","thedotmack"),is=(0,f.join)(N,"archives"),as=(0,f.join)(N,"logs"),ds=(0,f.join)(N,"trash"),cs=(0,f.join)(N,"backups"),us=(0,f.join)(N,"modes"),ms=(0,f.join)(N,"settings.json"),he=(0,f.join)(N,"claude-mem.db"),_s=(0,f.join)(N,"vector-db"),ps=(0,f.join)(N,"observer-sessions"),ls=(0,f.join)(y,"settings.json"),Es=(0,f.join)(y,"commands"),gs=(0,f.join)(y,"CLAUDE.md");function Oe(r){(0,P.mkdirSync)(r,{recursive:!0})}function Ae(){return(0,f.join)($t,"..")}var Le=require("crypto");var Ne=require("os"),Ce=L(require("path"),1);var H=require("fs"),j=L(require("path"),1),v={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null};function Re(r){let e=j.default.join(r,".git"),t;try{t=(0,H.statSync)(e)}catch{return v}if(!t.isFile())return v;let s;try{s=(0,H.readFileSync)(e,"utf-8").trim()}catch{return v}let n=s.match(/^gitdir:\s*(.+)$/);if(!n)return v;let i=n[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!i)return v;let a=i[1],d=j.default.basename(r),u=j.default.basename(a);return{isWorktree:!0,worktreeName:d,parentRepoPath:a,parentProjectName:u}}function Ie(r){return r==="~"||r.startsWith("~/")?r.replace(/^~/,(0,Ne.homedir)()):r}function Pt(r){if(!r||r.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:r}),"unknown-project";let e=Ie(r),t=Ce.default.basename(e);if(t===""){if(process.platform==="win32"){let n=r.match(/^([A-Z]):\\/i);if(n){let i=`drive-${n[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:r,projectName:i}),i}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:r}),"unknown-project"}return t}function te(r){let e=Pt(r);if(!r)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let t=Ie(r),s=Re(t);if(s.isWorktree&&s.parentProjectName){let n=`${s.parentProjectName}/${e}`;return{primary:n,parent:s.parentProjectName,isWorktree:!0,allProjects:[s.parentProjectName,n]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var jt=3e4;function X(r,e,t){return(0,Le.createHash)("sha256").update([r||"",e||"",t||""].join("\0")).digest("hex").slice(0,16)}function G(r,e,t){let s=t-jt;return r.prepare("SELECT id, created_at_epoch FROM observations WHERE content_hash = ? AND created_at_epoch > ?").get(e,s)}function se(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[String(e)]}catch{return[r]}}var h="claude";function Ht(r){return r.trim().toLowerCase().replace(/\s+/g,"-")}function D(r){if(!r)return h;let e=Ht(r);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:h}function ye(r){let e=["claude","codex","cursor"];return[...r].sort((t,s)=>{let n=e.indexOf(t),o=e.indexOf(s);return n!==-1||o!==-1?n===-1?1:o===-1?-1:n-o:t.localeCompare(s)})}function Xt(r,e){return{customTitle:r,platformSource:e?D(e):void 0}}var B=class{db;constructor(e=he){e!==":memory:"&&Oe(N),this.db=new De.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),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()}initializeSchema(){this.db.run(` CREATE TABLE IF NOT EXISTS schema_versions ( id INTEGER PRIMARY KEY, version INTEGER UNIQUE NOT NULL, @@ -747,13 +747,13 @@ ${o.stack}`:` ${o.message}`:this.getLevel()===0&&typeof o=="object"?m=` ORDER BY ss.created_at_epoch DESC LIMIT ? `).all(...e,...s?[s]:[],t.sessionCount+oe)}function Bt(r){return r.replace(/\//g,"-")}function Wt(r){try{if(!(0,V.existsSync)(r))return{userMessage:"",assistantMessage:""};let e=(0,V.readFileSync)(r,"utf-8").trim();if(!e)return{userMessage:"",assistantMessage:""};let t=e.split(` -`).filter(n=>n.trim()),s="";for(let n=t.length-1;n>=0;n--)try{let o=t[n];if(!o.includes('"type":"assistant"'))continue;let i=JSON.parse(o);if(i.type==="assistant"&&i.message?.content&&Array.isArray(i.message.content)){let a="";for(let d of i.message.content)d.type==="text"&&(a+=d.text);if(a=a.replace(xe,"").trim(),a){s=a;break}}}catch(o){_.debug("PARSER","Skipping malformed transcript line",{lineIndex:n},o);continue}return{userMessage:"",assistantMessage:s}}catch(e){return _.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r},e),{userMessage:"",assistantMessage:""}}}function ue(r,e,t,s){if(!e.showLastMessage||r.length===0)return{userMessage:"",assistantMessage:""};let n=r.find(d=>d.memory_session_id!==t);if(!n)return{userMessage:"",assistantMessage:""};let o=n.memory_session_id,i=Bt(s),a=ke.default.join(y,"projects",i,`${o}.jsonl`);return Wt(a)}function we(r,e){let t=e[0]?.id;return r.map((s,n)=>{let o=n===0?null:e[n+1];return{...s,displayEpoch:o?o.created_at_epoch:s.created_at_epoch,displayTime:o?o.created_at:s.created_at,shouldShowLink:s.id!==t}})}function me(r,e){let t=[...r.map(s=>({type:"observation",data:s})),...e.map(s=>({type:"summary",data:s}))];return t.sort((s,n)=>{let o=s.type==="observation"?s.data.created_at_epoch:s.data.displayEpoch,i=n.type==="observation"?n.data.created_at_epoch:n.data.displayEpoch;return o-i}),t}function Pe(r,e){return new Set(r.slice(0,e).map(t=>t.id))}function He(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function je(r){return[`# [${r}] recent context, ${He()}`,""]}function Xe(){return[`Legend: \u{1F3AF}session ${A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji}${t.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function Ge(){return[]}function Be(){return[]}function We(r,e){let t=[],s=[`${r.totalObservations} obs (${r.totalReadTokens.toLocaleString()}t read)`,`${r.totalDiscoveryTokens.toLocaleString()}t work`];return r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?s.push(`${r.savingsPercent}% savings`):e.showSavingsAmount&&s.push(`${r.savings.toLocaleString()}t saved`)),t.push(`Stats: ${s.join(" | ")}`),t.push(""),t}function Ye(r){return[`### ${r}`]}function qe(r){return r.toLowerCase().replace(" am","a").replace(" pm","p")}function Ve(r,e,t){let s=r.title||"Untitled",n=A.getInstance().getTypeIcon(r.type),o=e?qe(e):'"';return`${r.id} ${o} ${n} ${s}`}function Ke(r,e,t,s){let n=[],o=r.title||"Untitled",i=A.getInstance().getTypeIcon(r.type),a=e?qe(e):'"',{readTokens:d,discoveryDisplay:u}=k(r,s);n.push(`**${r.id}** ${a} ${i} **${o}**`),t&&n.push(t);let m=[];return s.showReadTokens&&m.push(`~${d}t`),s.showWorkTokens&&m.push(u),m.length>0&&n.push(m.join(" ")),n.push(""),n}function Je(r,e){return[`S${r.id} ${r.request||"Session started"} (${e})`]}function $(r,e){return e?[`**${r}**: ${e}`,""]:[]}function ze(r){return r.assistantMessage?["","---","","**Previously**","",`A: ${r.assistantMessage}`,""]:[]}function Qe(r,e){return["",`Access ${Math.round(r/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function Ze(r){return`# [${r}] recent context, ${He()} +`).filter(n=>n.trim()),s="";for(let n=t.length-1;n>=0;n--)try{let o=t[n];if(!o.includes('"type":"assistant"'))continue;let i=JSON.parse(o);if(i.type==="assistant"&&i.message?.content&&Array.isArray(i.message.content)){let a="";for(let d of i.message.content)d.type==="text"&&(a+=d.text);if(a=a.replace(xe,"").trim(),a){s=a;break}}}catch(o){_.debug("PARSER","Skipping malformed transcript line",{lineIndex:n},o);continue}return{userMessage:"",assistantMessage:s}}catch(e){return _.failure("WORKER","Failed to extract prior messages from transcript",{transcriptPath:r},e),{userMessage:"",assistantMessage:""}}}function ue(r,e,t,s){if(!e.showLastMessage||r.length===0)return{userMessage:"",assistantMessage:""};let n=r.find(d=>d.memory_session_id!==t);if(!n)return{userMessage:"",assistantMessage:""};let o=n.memory_session_id,i=Bt(s),a=ke.default.join(y,"projects",i,`${o}.jsonl`);return Wt(a)}function we(r,e){let t=e[0]?.id;return r.map((s,n)=>{let o=n===0?null:e[n+1];return{...s,displayEpoch:o?o.created_at_epoch:s.created_at_epoch,displayTime:o?o.created_at:s.created_at,shouldShowLink:s.id!==t}})}function me(r,e){let t=[...r.map(s=>({type:"observation",data:s})),...e.map(s=>({type:"summary",data:s}))];return t.sort((s,n)=>{let o=s.type==="observation"?s.data.created_at_epoch:s.data.displayEpoch,i=n.type==="observation"?n.data.created_at_epoch:n.data.displayEpoch;return o-i}),t}function Pe(r,e){return new Set(r.slice(0,e).map(t=>t.id))}function je(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function He(r){return[`# [${r}] recent context, ${je()}`,""]}function Xe(){return[`Legend: \u{1F3AF}session ${A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji}${t.id}`).join(" ")}`,"Format: ID TIME TYPE TITLE","Fetch details: get_observations([IDs]) | Search: mem-search skill",""]}function Ge(){return[]}function Be(){return[]}function We(r,e){let t=[],s=[`${r.totalObservations} obs (${r.totalReadTokens.toLocaleString()}t read)`,`${r.totalDiscoveryTokens.toLocaleString()}t work`];return r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)&&(e.showSavingsPercent?s.push(`${r.savingsPercent}% savings`):e.showSavingsAmount&&s.push(`${r.savings.toLocaleString()}t saved`)),t.push(`Stats: ${s.join(" | ")}`),t.push(""),t}function Ye(r){return[`### ${r}`]}function qe(r){return r.toLowerCase().replace(" am","a").replace(" pm","p")}function Ve(r,e,t){let s=r.title||"Untitled",n=A.getInstance().getTypeIcon(r.type),o=e?qe(e):'"';return`${r.id} ${o} ${n} ${s}`}function Ke(r,e,t,s){let n=[],o=r.title||"Untitled",i=A.getInstance().getTypeIcon(r.type),a=e?qe(e):'"',{readTokens:d,discoveryDisplay:u}=k(r,s);n.push(`**${r.id}** ${a} ${i} **${o}**`),t&&n.push(t);let m=[];return s.showReadTokens&&m.push(`~${d}t`),s.showWorkTokens&&m.push(u),m.length>0&&n.push(m.join(" ")),n.push(""),n}function Je(r,e){return[`S${r.id} ${r.request||"Session started"} (${e})`]}function $(r,e){return e?[`**${r}**: ${e}`,""]:[]}function ze(r){return r.assistantMessage?["","---","","**Previously**","",`A: ${r.assistantMessage}`,""]:[]}function Qe(r,e){return["",`Access ${Math.round(r/1e3)}k tokens of past work via get_observations([IDs]) or mem-search skill.`]}function Ze(r){return`# [${r}] recent context, ${je()} No previous sessions found.`}function et(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0}).toLowerCase().replace(" ",""),s=r.toLocaleTimeString("en-US",{timeZoneName:"short"}).split(" ").pop();return`${e} ${t} ${s}`}function tt(r){return["",`${c.bright}${c.cyan}[${r}] recent context, ${et()}${c.reset}`,`${c.gray}${"\u2500".repeat(60)}${c.reset}`,""]}function st(){let e=A.getInstance().getActiveMode().observation_types.map(t=>`${t.emoji} ${t.id}`).join(" | ");return[`${c.dim}Legend: session-request | ${e}${c.reset}`,""]}function rt(){return[`${c.bright}Column Key${c.reset}`,`${c.dim} Read: Tokens to read this observation (cost to learn it now)${c.reset}`,`${c.dim} Work: Tokens spent on work that produced this record ( research, building, deciding)${c.reset}`,""]}function nt(){return[`${c.dim}Context Index: This semantic index (titles, types, files, tokens) is usually sufficient to understand past work.${c.reset}`,"",`${c.dim}When you need implementation details, rationale, or debugging context:${c.reset}`,`${c.dim} - Fetch by ID: get_observations([IDs]) for observations visible in this index${c.reset}`,`${c.dim} - Search history: Use the mem-search skill for past decisions, bugs, and deeper research${c.reset}`,`${c.dim} - Trust this index over re-reading code for past decisions and learnings${c.reset}`,""]}function ot(r,e){let t=[];if(t.push(`${c.bright}${c.cyan}Context Economics${c.reset}`),t.push(`${c.dim} Loading: ${r.totalObservations} observations (${r.totalReadTokens.toLocaleString()} tokens to read)${c.reset}`),t.push(`${c.dim} Work investment: ${r.totalDiscoveryTokens.toLocaleString()} tokens spent on research, building, and decisions${c.reset}`),r.totalDiscoveryTokens>0&&(e.showSavingsAmount||e.showSavingsPercent)){let s=" Your savings: ";e.showSavingsAmount&&e.showSavingsPercent?s+=`${r.savings.toLocaleString()} tokens (${r.savingsPercent}% reduction from reuse)`:e.showSavingsAmount?s+=`${r.savings.toLocaleString()} tokens`:s+=`${r.savingsPercent}% reduction from reuse`,t.push(`${c.green}${s}${c.reset}`)}return t.push(""),t}function it(r){return[`${c.bright}${c.cyan}${r}${c.reset}`,""]}function at(r){return[`${c.dim}${r}${c.reset}`]}function dt(r,e,t,s){let n=r.title||"Untitled",o=A.getInstance().getTypeIcon(r.type),{readTokens:i,discoveryTokens:a,workEmoji:d}=k(r,s),u=t?`${c.dim}${e}${c.reset}`:" ".repeat(e.length),m=s.showReadTokens&&i>0?`${c.dim}(~${i}t)${c.reset}`:"",l=s.showWorkTokens&&a>0?`${c.dim}(${d} ${a.toLocaleString()}t)${c.reset}`:"";return` ${c.dim}#${r.id}${c.reset} ${u} ${o} ${n} ${m} ${l}`}function ct(r,e,t,s,n){let o=[],i=r.title||"Untitled",a=A.getInstance().getTypeIcon(r.type),{readTokens:d,discoveryTokens:u,workEmoji:m}=k(r,n),l=t?`${c.dim}${e}${c.reset}`:" ".repeat(e.length),E=n.showReadTokens&&d>0?`${c.dim}(~${d}t)${c.reset}`:"",T=n.showWorkTokens&&u>0?`${c.dim}(${m} ${u.toLocaleString()}t)${c.reset}`:"";return o.push(` ${c.dim}#${r.id}${c.reset} ${l} ${a} ${c.bright}${i}${c.reset}`),s&&o.push(` ${c.dim}${s}${c.reset}`),(E||T)&&o.push(` ${E} ${T}`),o.push(""),o}function ut(r,e){let t=`${r.request||"Session started"} (${e})`;return[`${c.yellow}#S${r.id}${c.reset} ${t}`,""]}function F(r,e,t){return e?[`${t}${r}:${c.reset} ${e}`,""]:[]}function mt(r){return r.assistantMessage?["","---","",`${c.bright}${c.magenta}Previously${c.reset}`,"",`${c.dim}A: ${r.assistantMessage}${c.reset}`,""]:[]}function _t(r,e){let t=Math.round(r/1e3);return["",`${c.dim}Access ${t}k tokens of past research & decisions for just ${e.toLocaleString()}t. Use the claude-mem skill to access memories by ID.${c.reset}`]}function pt(r){return` ${c.bright}${c.cyan}[${r}] recent context, ${et()}${c.reset} ${c.gray}${"\u2500".repeat(60)}${c.reset} ${c.dim}No previous sessions found for this project yet.${c.reset} -`}function lt(r,e,t,s){let n=[];return s?n.push(...tt(r)):n.push(...je(r)),s?n.push(...st()):n.push(...Xe()),s?n.push(...rt()):n.push(...Ge()),s?n.push(...nt()):n.push(...Be()),q(t)&&(s?n.push(...ot(e,t)):n.push(...We(e,t))),n}var _e=L(require("path"),1);function z(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch(e){return _.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:r?.substring(0,50)},e),[]}}function pe(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function le(r){return new Date(r).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function gt(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function Et(r,e){return _e.default.isAbsolute(r)?_e.default.relative(e,r):r}function Tt(r,e,t){let s=z(r);if(s.length>0)return Et(s[0],e);if(t){let n=z(t);if(n.length>0)return Et(n[0],e)}return"General"}function Yt(r){let e=new Map;for(let s of r){let n=s.type==="observation"?s.data.created_at:s.data.displayTime,o=gt(n);e.has(o)||e.set(o,[]),e.get(o).push(s)}let t=Array.from(e.entries()).sort((s,n)=>{let o=new Date(s[0]).getTime(),i=new Date(n[0]).getTime();return o-i});return new Map(t)}function ft(r,e){return e.fullObservationField==="narrative"?r.narrative:r.facts?z(r.facts).join(` +`}function lt(r,e,t,s){let n=[];return s?n.push(...tt(r)):n.push(...He(r)),s?n.push(...st()):n.push(...Xe()),s?n.push(...rt()):n.push(...Ge()),s?n.push(...nt()):n.push(...Be()),q(t)&&(s?n.push(...ot(e,t)):n.push(...We(e,t))),n}var _e=L(require("path"),1);function z(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArray(e)?e:[]}catch(e){return _.debug("PARSER","Failed to parse JSON array, using empty fallback",{preview:r?.substring(0,50)},e),[]}}function pe(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}function le(r){return new Date(r).toLocaleString("en-US",{hour:"numeric",minute:"2-digit",hour12:!0})}function gt(r){return new Date(r).toLocaleString("en-US",{month:"short",day:"numeric",year:"numeric"})}function Et(r,e){return _e.default.isAbsolute(r)?_e.default.relative(e,r):r}function Tt(r,e,t){let s=z(r);if(s.length>0)return Et(s[0],e);if(t){let n=z(t);if(n.length>0)return Et(n[0],e)}return"General"}function Yt(r){let e=new Map;for(let s of r){let n=s.type==="observation"?s.data.created_at:s.data.displayTime,o=gt(n);e.has(o)||e.set(o,[]),e.get(o).push(s)}let t=Array.from(e.entries()).sort((s,n)=>{let o=new Date(s[0]).getTime(),i=new Date(n[0]).getTime();return o-i});return new Map(t)}function ft(r,e){return e.fullObservationField==="narrative"?r.narrative:r.facts?z(r.facts).join(` `):null}function qt(r,e,t,s){let n=[];n.push(...Ye(r));let o="";for(let i of e)if(i.type==="summary"){let a=i.data,d=pe(a.displayTime);n.push(...Je(a,d))}else{let a=i.data,d=le(a.created_at),m=d!==o?d:"";if(o=d,t.has(a.id)){let E=ft(a,s);n.push(...Ke(a,m,E,s))}else n.push(Ve(a,m,s))}return n}function Vt(r,e,t,s,n){let o=[];o.push(...it(r));let i=null,a="";for(let d of e)if(d.type==="summary"){i=null,a="";let u=d.data,m=pe(u.displayTime);o.push(...ut(u,m))}else{let u=d.data,m=Tt(u.files_modified,n,u.files_read),l=le(u.created_at),E=l!==a;a=l;let T=t.has(u.id);if(m!==i&&(o.push(...at(m)),i=m),T){let O=ft(u,s);o.push(...ct(u,l,E,O,s))}else o.push(dt(u,l,E,s))}return o.push(""),o}function Kt(r,e,t,s,n,o){return o?Vt(r,e,t,s,n):qt(r,e,t,s)}function St(r,e,t,s,n){let o=[],i=Yt(r);for(let[a,d]of i)o.push(...Kt(a,d,e,t,s,n));return o}function bt(r,e,t){return!(!r.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||t&&e.created_at_epoch<=t.created_at_epoch)}function ht(r,e){let t=[];return e?(t.push(...F("Investigated",r.investigated,c.blue)),t.push(...F("Learned",r.learned,c.yellow)),t.push(...F("Completed",r.completed,c.green)),t.push(...F("Next Steps",r.next_steps,c.magenta))):(t.push(...$("Investigated",r.investigated)),t.push(...$("Learned",r.learned)),t.push(...$("Completed",r.completed)),t.push(...$("Next Steps",r.next_steps))),t}function Ot(r,e){return e?mt(r):ze(r)}function At(r,e,t){return!q(e)||r.totalDiscoveryTokens<=0||r.savings<=0?[]:t?_t(r.totalDiscoveryTokens,r.totalReadTokens):Qe(r.totalDiscoveryTokens,r.totalReadTokens)}var Jt=Rt.default.join((0,Nt.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version");function zt(){try{return new B}catch(r){if(r.code==="ERR_DLOPEN_FAILED"){try{(0,Ct.unlinkSync)(Jt)}catch(e){_.debug("SYSTEM","Marker file cleanup failed (may not exist)",{},e)}return _.error("SYSTEM","Native module rebuild needed - restart Claude Code to auto-fix"),null}throw r}}function Qt(r,e){return e?pt(r):Ze(r)}function Zt(r,e,t,s,n,o,i){let a=[],d=ae(e);a.push(...lt(r,d,s,i));let u=t.slice(0,s.sessionCount),m=we(u,t),l=me(e,m),E=Pe(e,s.fullObservationCount);a.push(...St(l,E,s,n,i));let T=t[0],O=e[0];bt(s,T,O)&&a.push(...ht(T,i));let S=ue(e,s,o,n);return a.push(...Ot(S,i)),a.push(...At(d,s,i)),a.join(` `).trimEnd()}async function Ee(r,e=!1){let t=ne(),s=r?.cwd??process.cwd(),n=te(s),o=r?.platform_source,i=r?.projects??n.allProjects,a=i[i.length-1];r?.full&&(t.totalObservationCount=999999,t.sessionCount=999999);let d=zt();if(!d)return"";try{let u=i.length>1?$e(d,i,t,o):de(d,a,t,o),m=i.length>1?Fe(d,i,t,o):ce(d,a,t,o);return u.length===0&&m.length===0?Qt(a,e):Zt(a,u,m,t,s,r?.session_id,e)}finally{d.close()}}0&&(module.exports={generateContext}); diff --git a/plugin/scripts/worker-service.cjs b/plugin/scripts/worker-service.cjs index e19b8f15..23f16308 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -16,7 +16,7 @@ ${s.stack}`:` ${s.message}`:this.getLevel()===0&&typeof s=="object"?l=` `,"utf8")}catch(m){process.stderr.write(`[LOGGER] Failed to write to log file: ${m} `)}else process.stderr.write(p+` `)}debug(e,r,n,i){this.log(0,e,r,n,i)}info(e,r,n,i){this.log(1,e,r,n,i)}warn(e,r,n,i){this.log(2,e,r,n,i)}error(e,r,n,i){this.log(3,e,r,n,i)}dataIn(e,r,n,i){this.info(e,`\u2192 ${r}`,n,i)}dataOut(e,r,n,i){this.info(e,`\u2190 ${r}`,n,i)}success(e,r,n,i){this.info(e,`\u2713 ${r}`,n,i)}failure(e,r,n,i){this.error(e,`\u2717 ${r}`,n,i)}timing(e,r,n,i){this.info(e,`\u23F1 ${r}`,i,{duration:`${n}ms`})}happyPathError(e,r,n,i,s=""){let u=((new Error().stack||"").split(` -`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),l=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",d={...n,location:l};return this.warn(e,`[HAPPY-PATH] ${r}`,d,i),s}},_=new RE});function rg(t){return process.platform==="win32"?Math.round(t*mr.WINDOWS_MULTIPLIER):t}var mr,nt,gn=he(()=>{"use strict";mr={DEFAULT:3e5,HEALTH_CHECK:3e3,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},nt={SUCCESS:0,FAILURE:1,BLOCKING_ERROR:2,USER_MESSAGE_ONLY:3}});var EM={};ln(EM,{SettingsDefaultsManager:()=>ge});var Wi,Gd,OE,ge,Yt=he(()=>{"use strict";Wi=require("fs"),Gd=require("path"),OE=require("os"),ge=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-6",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"cli",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_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:(0,Gd.join)((0,OE.homedir)(),".claude-mem"),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_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,Gd.join)((0,OE.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",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_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database"};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[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))process.env[n]!==void 0&&(r[n]=process.env[n]);return r}static loadFromFile(e){try{if(!(0,Wi.existsSync)(e)){let o=this.getAllDefaults();try{let a=(0,Gd.dirname)(e);(0,Wi.existsSync)(a)||(0,Wi.mkdirSync)(a,{recursive:!0}),(0,Wi.writeFileSync)(e,JSON.stringify(o,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",e)}catch(a){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,a)}return this.applyEnvOverrides(o)}let r=(0,Wi.readFileSync)(e,"utf-8"),n=JSON.parse(r),i=n;if(n.env&&typeof n.env=="object"){i=n.env;try{(0,Wi.writeFileSync)(e,JSON.stringify(i,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(o){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,o)}}let s={...this.DEFAULTS};for(let o of Object.keys(this.DEFAULTS))i[o]!==void 0&&(s[o]=i[o]);return this.applyEnvOverrides(s)}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",e,r),this.applyEnvOverrides(this.getAllDefaults())}}}});var CM={};ln(CM,{ARCHIVES_DIR:()=>PE,BACKUPS_DIR:()=>RM,CLAUDE_COMMANDS_DIR:()=>OM,CLAUDE_CONFIG_DIR:()=>$s,CLAUDE_MD_PATH:()=>oQ,CLAUDE_SETTINGS_PATH:()=>sQ,DATA_DIR:()=>fr,DB_PATH:()=>Wd,LOGS_DIR:()=>$M,MARKETPLACE_ROOT:()=>yo,MODES_DIR:()=>AE,OBSERVER_SESSIONS_DIR:()=>Is,TRASH_DIR:()=>IM,USER_SETTINGS_PATH:()=>dt,VECTOR_DB_DIR:()=>iQ,createBackupFilename:()=>fQ,ensureAllClaudeDirs:()=>dQ,ensureAllDataDirs:()=>uQ,ensureDir:()=>sr,ensureModesDir:()=>lQ,getCurrentProjectName:()=>pQ,getPackageCommandsDir:()=>mQ,getPackageRoot:()=>vn,getProjectArchiveDir:()=>aQ,getWorkerSocketPath:()=>cQ});function tQ(){return typeof __dirname<"u"?__dirname:(0,mt.dirname)((0,TM.fileURLToPath)(hQ.url))}function nQ(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let t=(0,mt.join)((0,CE.homedir)(),".claude-mem"),e=(0,mt.join)(t,"settings.json");try{if((0,ng.existsSync)(e)){let{readFileSync:r}=require("fs"),n=JSON.parse(r(e,"utf-8")),i=n.env??n;if(i.CLAUDE_MEM_DATA_DIR)return i.CLAUDE_MEM_DATA_DIR}}catch{}return t}function aQ(t){return(0,mt.join)(PE,t)}function cQ(t){return(0,mt.join)(fr,`worker-${t}.sock`)}function sr(t){(0,ng.mkdirSync)(t,{recursive:!0})}function uQ(){sr(fr),sr(PE),sr($M),sr(IM),sr(RM),sr(AE)}function lQ(){sr(AE)}function dQ(){sr($s),sr(OM)}function pQ(){try{let t=(0,kM.execSync)("git rev-parse --show-toplevel",{cwd:process.cwd(),encoding:"utf8",stdio:["pipe","pipe","ignore"],windowsHide:!0}).trim();return(0,mt.basename)((0,mt.dirname)(t))+"/"+(0,mt.basename)(t)}catch(t){_.debug("SYSTEM","Git root detection failed, using cwd basename",{cwd:process.cwd()},t);let e=process.cwd();return(0,mt.basename)((0,mt.dirname)(e))+"/"+(0,mt.basename)(e)}}function vn(){return(0,mt.join)(rQ,"..")}function mQ(){let t=vn();return(0,mt.join)(t,"commands")}function fQ(t){let e=new Date().toISOString().replace(/[:.]/g,"-").replace("T","_").slice(0,19);return`${t}.backup.${e}`}var mt,CE,ng,kM,TM,hQ,rQ,fr,$s,yo,PE,$M,IM,RM,AE,dt,Wd,iQ,Is,sQ,OM,oQ,Ct=he(()=>{"use strict";mt=require("path"),CE=require("os"),ng=require("fs"),kM=require("child_process"),TM=require("url");Q();hQ={};rQ=tQ();fr=nQ(),$s=process.env.CLAUDE_CONFIG_DIR||(0,mt.join)((0,CE.homedir)(),".claude"),yo=(0,mt.join)($s,"plugins","marketplaces","thedotmack"),PE=(0,mt.join)(fr,"archives"),$M=(0,mt.join)(fr,"logs"),IM=(0,mt.join)(fr,"trash"),RM=(0,mt.join)(fr,"backups"),AE=(0,mt.join)(fr,"modes"),dt=(0,mt.join)(fr,"settings.json"),Wd=(0,mt.join)(fr,"claude-mem.db"),iQ=(0,mt.join)(fr,"vector-db"),Is=(0,mt.join)(fr,"observer-sessions"),sQ=(0,mt.join)($s,"settings.json"),OM=(0,mt.join)($s,"commands"),oQ=(0,mt.join)($s,"CLAUDE.md")});function gQ(t,e={},r){return new Promise((n,i)=>{let s=setTimeout(()=>i(new Error(`Request timed out after ${r}ms`)),r);fetch(t,e).then(o=>{clearTimeout(s),n(o)},o=>{clearTimeout(s),i(o)})})}function Qr(){if(Vd!==null)return Vd;let t=ig.default.join(ge.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=ge.loadFromFile(t);return Vd=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),Vd}function ME(){if(Kd!==null)return Kd;let t=ig.default.join(ge.get("CLAUDE_MEM_DATA_DIR"),"settings.json");return Kd=ge.loadFromFile(t).CLAUDE_MEM_WORKER_HOST,Kd}function AM(){Vd=null,Kd=null}function vQ(t){return`http://${ME()}:${Qr()}${t}`}function ut(t,e={}){let r=e.method??"GET",n=e.timeoutMs??NE,i=vQ(t),s={method:r};return e.headers&&(s.headers=e.headers),e.body&&(s.body=e.body),n>0?gQ(i,s,n):fetch(i,s)}async function yQ(){return(await ut("/api/health",{timeoutMs:NE})).ok}function _Q(){try{let t=ig.default.join(yo,"package.json");return JSON.parse((0,PM.readFileSync)(t,"utf-8")).version}catch(t){let e=t.code;if(e==="ENOENT"||e==="EBUSY")return _.debug("SYSTEM","Could not read plugin version (shutdown race)",{code:e}),"unknown";throw t}}async function bQ(){let t=await ut("/api/version",{timeoutMs:NE});if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function SQ(){try{let t=_Q();if(t==="unknown")return;let e=await bQ();if(e==="unknown")return;t!==e&&_.debug("SYSTEM","Version check",{pluginVersion:t,workerVersion:e,note:"Mismatch will be auto-restarted by worker-service start command"})}catch(t){_.debug("SYSTEM","Version check failed",{error:t instanceof Error?t.message:String(t)})}}async function or(){try{if(await yQ())return await SQ(),!0}catch(t){_.debug("SYSTEM","Worker health check failed",{error:t instanceof Error?t.message:String(t)})}return _.warn("SYSTEM","Worker not healthy, hook will proceed gracefully"),!1}var ig,PM,NE,Vd,Kd,Rr=he(()=>{"use strict";ig=Oe(require("path"),1),PM=require("fs");Q();gn();Yt();Ct();NE=(()=>{let t=process.env.CLAUDE_MEM_HEALTH_TIMEOUT_MS;if(t){let e=parseInt(t,10);if(Number.isFinite(e)&&e>=500&&e<=3e5)return e;_.warn("SYSTEM","Invalid CLAUDE_MEM_HEALTH_TIMEOUT_MS, using default",{value:t,min:500,max:3e5})}return rg(mr.HEALTH_CHECK)})();Vd=null,Kd=null});function YM(t){let e=lg.default.join(t,".git"),r;try{r=(0,dg.statSync)(e)}catch{return Yd}if(!r.isFile())return Yd;let n;try{n=(0,dg.readFileSync)(e,"utf-8").trim()}catch{return Yd}let i=n.match(/^gitdir:\s*(.+)$/);if(!i)return Yd;let o=i[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!o)return Yd;let a=o[1],c=lg.default.basename(t),u=lg.default.basename(a);return{isWorktree:!0,worktreeName:c,parentRepoPath:a,parentProjectName:u}}var dg,lg,Yd,QM=he(()=>{"use strict";dg=require("fs"),lg=Oe(require("path"),1),Yd={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null}});function rD(t){return t==="~"||t.startsWith("~/")?t.replace(/^~/,(0,eD.homedir)()):t}function FQ(t){if(!t||t.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:t}),"unknown-project";let e=rD(t),r=tD.default.basename(e);if(r===""){if(process.platform==="win32"){let i=t.match(/^([A-Z]):\\/i);if(i){let o=`drive-${i[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:t,projectName:o}),o}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:t}),"unknown-project"}return r}function zr(t){let e=FQ(t);if(!t)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let r=rD(t),n=YM(r);if(n.isWorktree&&n.parentProjectName){let i=`${n.parentProjectName}/${e}`;return{primary:i,parent:n.parentProjectName,isWorktree:!0,allProjects:[i]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var eD,tD,Cs=he(()=>{"use strict";eD=require("os"),tD=Oe(require("path"),1);Q();QM()});function pg(t,e,r){return(0,nD.createHash)("sha256").update([t||"",e||"",r||""].join("\0")).digest("hex").slice(0,16)}function mg(t,e,r){let n=r-qQ;return t.prepare("SELECT id, created_at_epoch FROM observations WHERE content_hash = ? AND created_at_epoch > ?").get(e,n)}var nD,qQ,iD=he(()=>{"use strict";nD=require("crypto");Q();Cs();qQ=3e4});function Hc(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[String(e)]}catch{return[t]}}var KE=he(()=>{"use strict"});function HQ(t){return t.trim().toLowerCase().replace(/\s+/g,"-")}function St(t){if(!t)return Lr;let e=HQ(t);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:Lr}function sD(t){let e=["claude","codex","cursor"];return[...t].sort((r,n)=>{let i=e.indexOf(r),s=e.indexOf(n);return i!==-1||s!==-1?i===-1?1:s===-1?-1:i-s:r.localeCompare(n)})}var Lr,bi=he(()=>{"use strict";Lr="claude"});function ZQ(t,e){return{customTitle:t,platformSource:e?St(e):void 0}}var oD,Ps,fg=he(()=>{"use strict";oD=require("bun:sqlite");Ct();Q();iD();KE();bi();Ps=class{db;constructor(e=Wd){e!==":memory:"&&sr(fr),this.db=new oD.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),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()}initializeSchema(){this.db.run(` +`)[2]||"").match(/at\s+(?:.*\s+)?\(?([^:]+):(\d+):(\d+)\)?/),l=u?`${u[1].split("/").pop()}:${u[2]}`:"unknown",d={...n,location:l};return this.warn(e,`[HAPPY-PATH] ${r}`,d,i),s}},_=new RE});function rg(t){return process.platform==="win32"?Math.round(t*mr.WINDOWS_MULTIPLIER):t}var mr,nt,gn=he(()=>{"use strict";mr={DEFAULT:3e5,HEALTH_CHECK:3e3,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},nt={SUCCESS:0,FAILURE:1,BLOCKING_ERROR:2,USER_MESSAGE_ONLY:3}});var EM={};ln(EM,{SettingsDefaultsManager:()=>ge});var Wi,Gd,OE,ge,Yt=he(()=>{"use strict";Wi=require("fs"),Gd=require("path"),OE=require("os"),ge=class{static DEFAULTS={CLAUDE_MEM_MODEL:"claude-sonnet-4-6",CLAUDE_MEM_CONTEXT_OBSERVATIONS:"50",CLAUDE_MEM_WORKER_PORT:"37777",CLAUDE_MEM_WORKER_HOST:"127.0.0.1",CLAUDE_MEM_SKIP_TOOLS:"ListMcpResourcesTool,SlashCommand,Skill,TodoWrite,AskUserQuestion",CLAUDE_MEM_PROVIDER:"claude",CLAUDE_MEM_CLAUDE_AUTH_METHOD:"cli",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_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:(0,Gd.join)((0,OE.homedir)(),".claude-mem"),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_FOLDER_CLAUDEMD_ENABLED:"false",CLAUDE_MEM_FOLDER_USE_LOCAL_MD:"false",CLAUDE_MEM_TRANSCRIPTS_ENABLED:"true",CLAUDE_MEM_TRANSCRIPTS_CONFIG_PATH:(0,Gd.join)((0,OE.homedir)(),".claude-mem","transcript-watch.json"),CLAUDE_MEM_MAX_CONCURRENT_AGENTS:"2",CLAUDE_MEM_EXCLUDED_PROJECTS:"",CLAUDE_MEM_FOLDER_MD_EXCLUDE:"[]",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_CHROMA_ENABLED:"true",CLAUDE_MEM_CHROMA_MODE:"local",CLAUDE_MEM_CHROMA_HOST:"127.0.0.1",CLAUDE_MEM_CHROMA_PORT:"8000",CLAUDE_MEM_CHROMA_SSL:"false",CLAUDE_MEM_CHROMA_API_KEY:"",CLAUDE_MEM_CHROMA_TENANT:"default_tenant",CLAUDE_MEM_CHROMA_DATABASE:"default_database"};static getAllDefaults(){return{...this.DEFAULTS}}static get(e){return process.env[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))process.env[n]!==void 0&&(r[n]=process.env[n]);return r}static loadFromFile(e){try{if(!(0,Wi.existsSync)(e)){let o=this.getAllDefaults();try{let a=(0,Gd.dirname)(e);(0,Wi.existsSync)(a)||(0,Wi.mkdirSync)(a,{recursive:!0}),(0,Wi.writeFileSync)(e,JSON.stringify(o,null,2),"utf-8"),console.log("[SETTINGS] Created settings file with defaults:",e)}catch(a){console.warn("[SETTINGS] Failed to create settings file, using in-memory defaults:",e,a)}return this.applyEnvOverrides(o)}let r=(0,Wi.readFileSync)(e,"utf-8"),n=JSON.parse(r),i=n;if(n.env&&typeof n.env=="object"){i=n.env;try{(0,Wi.writeFileSync)(e,JSON.stringify(i,null,2),"utf-8"),console.log("[SETTINGS] Migrated settings file from nested to flat schema:",e)}catch(o){console.warn("[SETTINGS] Failed to auto-migrate settings file:",e,o)}}let s={...this.DEFAULTS};for(let o of Object.keys(this.DEFAULTS))i[o]!==void 0&&(s[o]=i[o]);return this.applyEnvOverrides(s)}catch(r){return console.warn("[SETTINGS] Failed to load settings, using defaults:",e,r),this.applyEnvOverrides(this.getAllDefaults())}}}});var CM={};ln(CM,{ARCHIVES_DIR:()=>PE,BACKUPS_DIR:()=>RM,CLAUDE_COMMANDS_DIR:()=>OM,CLAUDE_CONFIG_DIR:()=>$s,CLAUDE_MD_PATH:()=>oQ,CLAUDE_SETTINGS_PATH:()=>sQ,DATA_DIR:()=>fr,DB_PATH:()=>Wd,LOGS_DIR:()=>$M,MARKETPLACE_ROOT:()=>yo,MODES_DIR:()=>AE,OBSERVER_SESSIONS_DIR:()=>Is,TRASH_DIR:()=>IM,USER_SETTINGS_PATH:()=>dt,VECTOR_DB_DIR:()=>iQ,createBackupFilename:()=>fQ,ensureAllClaudeDirs:()=>dQ,ensureAllDataDirs:()=>uQ,ensureDir:()=>sr,ensureModesDir:()=>lQ,getCurrentProjectName:()=>pQ,getPackageCommandsDir:()=>mQ,getPackageRoot:()=>vn,getProjectArchiveDir:()=>aQ,getWorkerSocketPath:()=>cQ});function tQ(){return typeof __dirname<"u"?__dirname:(0,mt.dirname)((0,TM.fileURLToPath)(hQ.url))}function nQ(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAUDE_MEM_DATA_DIR;let t=(0,mt.join)((0,CE.homedir)(),".claude-mem"),e=(0,mt.join)(t,"settings.json");try{if((0,ng.existsSync)(e)){let{readFileSync:r}=require("fs"),n=JSON.parse(r(e,"utf-8")),i=n.env??n;if(i.CLAUDE_MEM_DATA_DIR)return i.CLAUDE_MEM_DATA_DIR}}catch{}return t}function aQ(t){return(0,mt.join)(PE,t)}function cQ(t){return(0,mt.join)(fr,`worker-${t}.sock`)}function sr(t){(0,ng.mkdirSync)(t,{recursive:!0})}function uQ(){sr(fr),sr(PE),sr($M),sr(IM),sr(RM),sr(AE)}function lQ(){sr(AE)}function dQ(){sr($s),sr(OM)}function pQ(){try{let t=(0,kM.execSync)("git rev-parse --show-toplevel",{cwd:process.cwd(),encoding:"utf8",stdio:["pipe","pipe","ignore"],windowsHide:!0}).trim();return(0,mt.basename)((0,mt.dirname)(t))+"/"+(0,mt.basename)(t)}catch(t){_.debug("SYSTEM","Git root detection failed, using cwd basename",{cwd:process.cwd()},t);let e=process.cwd();return(0,mt.basename)((0,mt.dirname)(e))+"/"+(0,mt.basename)(e)}}function vn(){return(0,mt.join)(rQ,"..")}function mQ(){let t=vn();return(0,mt.join)(t,"commands")}function fQ(t){let e=new Date().toISOString().replace(/[:.]/g,"-").replace("T","_").slice(0,19);return`${t}.backup.${e}`}var mt,CE,ng,kM,TM,hQ,rQ,fr,$s,yo,PE,$M,IM,RM,AE,dt,Wd,iQ,Is,sQ,OM,oQ,Ct=he(()=>{"use strict";mt=require("path"),CE=require("os"),ng=require("fs"),kM=require("child_process"),TM=require("url");Q();hQ={};rQ=tQ();fr=nQ(),$s=process.env.CLAUDE_CONFIG_DIR||(0,mt.join)((0,CE.homedir)(),".claude"),yo=(0,mt.join)($s,"plugins","marketplaces","thedotmack"),PE=(0,mt.join)(fr,"archives"),$M=(0,mt.join)(fr,"logs"),IM=(0,mt.join)(fr,"trash"),RM=(0,mt.join)(fr,"backups"),AE=(0,mt.join)(fr,"modes"),dt=(0,mt.join)(fr,"settings.json"),Wd=(0,mt.join)(fr,"claude-mem.db"),iQ=(0,mt.join)(fr,"vector-db"),Is=(0,mt.join)(fr,"observer-sessions"),sQ=(0,mt.join)($s,"settings.json"),OM=(0,mt.join)($s,"commands"),oQ=(0,mt.join)($s,"CLAUDE.md")});function gQ(t,e={},r){return new Promise((n,i)=>{let s=setTimeout(()=>i(new Error(`Request timed out after ${r}ms`)),r);fetch(t,e).then(o=>{clearTimeout(s),n(o)},o=>{clearTimeout(s),i(o)})})}function Qr(){if(Vd!==null)return Vd;let t=ig.default.join(ge.get("CLAUDE_MEM_DATA_DIR"),"settings.json"),e=ge.loadFromFile(t);return Vd=parseInt(e.CLAUDE_MEM_WORKER_PORT,10),Vd}function ME(){if(Kd!==null)return Kd;let t=ig.default.join(ge.get("CLAUDE_MEM_DATA_DIR"),"settings.json");return Kd=ge.loadFromFile(t).CLAUDE_MEM_WORKER_HOST,Kd}function AM(){Vd=null,Kd=null}function vQ(t){return`http://${ME()}:${Qr()}${t}`}function ut(t,e={}){let r=e.method??"GET",n=e.timeoutMs??NE,i=vQ(t),s={method:r};return e.headers&&(s.headers=e.headers),e.body&&(s.body=e.body),n>0?gQ(i,s,n):fetch(i,s)}async function yQ(){return(await ut("/api/health",{timeoutMs:NE})).ok}function _Q(){try{let t=ig.default.join(yo,"package.json");return JSON.parse((0,PM.readFileSync)(t,"utf-8")).version}catch(t){let e=t.code;if(e==="ENOENT"||e==="EBUSY")return _.debug("SYSTEM","Could not read plugin version (shutdown race)",{code:e}),"unknown";throw t}}async function bQ(){let t=await ut("/api/version",{timeoutMs:NE});if(!t.ok)throw new Error(`Failed to get worker version: ${t.status}`);return(await t.json()).version}async function SQ(){try{let t=_Q();if(t==="unknown")return;let e=await bQ();if(e==="unknown")return;t!==e&&_.debug("SYSTEM","Version check",{pluginVersion:t,workerVersion:e,note:"Mismatch will be auto-restarted by worker-service start command"})}catch(t){_.debug("SYSTEM","Version check failed",{error:t instanceof Error?t.message:String(t)})}}async function or(){try{if(await yQ())return await SQ(),!0}catch(t){_.debug("SYSTEM","Worker health check failed",{error:t instanceof Error?t.message:String(t)})}return _.warn("SYSTEM","Worker not healthy, hook will proceed gracefully"),!1}var ig,PM,NE,Vd,Kd,Rr=he(()=>{"use strict";ig=Oe(require("path"),1),PM=require("fs");Q();gn();Yt();Ct();NE=(()=>{let t=process.env.CLAUDE_MEM_HEALTH_TIMEOUT_MS;if(t){let e=parseInt(t,10);if(Number.isFinite(e)&&e>=500&&e<=3e5)return e;_.warn("SYSTEM","Invalid CLAUDE_MEM_HEALTH_TIMEOUT_MS, using default",{value:t,min:500,max:3e5})}return rg(mr.HEALTH_CHECK)})();Vd=null,Kd=null});function YM(t){let e=lg.default.join(t,".git"),r;try{r=(0,dg.statSync)(e)}catch{return Yd}if(!r.isFile())return Yd;let n;try{n=(0,dg.readFileSync)(e,"utf-8").trim()}catch{return Yd}let i=n.match(/^gitdir:\s*(.+)$/);if(!i)return Yd;let o=i[1].match(/^(.+)[/\\]\.git[/\\]worktrees[/\\]([^/\\]+)$/);if(!o)return Yd;let a=o[1],c=lg.default.basename(t),u=lg.default.basename(a);return{isWorktree:!0,worktreeName:c,parentRepoPath:a,parentProjectName:u}}var dg,lg,Yd,QM=he(()=>{"use strict";dg=require("fs"),lg=Oe(require("path"),1),Yd={isWorktree:!1,worktreeName:null,parentRepoPath:null,parentProjectName:null}});function rD(t){return t==="~"||t.startsWith("~/")?t.replace(/^~/,(0,eD.homedir)()):t}function FQ(t){if(!t||t.trim()==="")return _.warn("PROJECT_NAME","Empty cwd provided, using fallback",{cwd:t}),"unknown-project";let e=rD(t),r=tD.default.basename(e);if(r===""){if(process.platform==="win32"){let i=t.match(/^([A-Z]):\\/i);if(i){let o=`drive-${i[1].toUpperCase()}`;return _.info("PROJECT_NAME","Drive root detected",{cwd:t,projectName:o}),o}}return _.warn("PROJECT_NAME","Root directory detected, using fallback",{cwd:t}),"unknown-project"}return r}function zr(t){let e=FQ(t);if(!t)return{primary:e,parent:null,isWorktree:!1,allProjects:[e]};let r=rD(t),n=YM(r);if(n.isWorktree&&n.parentProjectName){let i=`${n.parentProjectName}/${e}`;return{primary:i,parent:n.parentProjectName,isWorktree:!0,allProjects:[n.parentProjectName,i]}}return{primary:e,parent:null,isWorktree:!1,allProjects:[e]}}var eD,tD,Cs=he(()=>{"use strict";eD=require("os"),tD=Oe(require("path"),1);Q();QM()});function pg(t,e,r){return(0,nD.createHash)("sha256").update([t||"",e||"",r||""].join("\0")).digest("hex").slice(0,16)}function mg(t,e,r){let n=r-qQ;return t.prepare("SELECT id, created_at_epoch FROM observations WHERE content_hash = ? AND created_at_epoch > ?").get(e,n)}var nD,qQ,iD=he(()=>{"use strict";nD=require("crypto");Q();Cs();qQ=3e4});function Hc(t){if(!t)return[];try{let e=JSON.parse(t);return Array.isArray(e)?e:[String(e)]}catch{return[t]}}var KE=he(()=>{"use strict"});function HQ(t){return t.trim().toLowerCase().replace(/\s+/g,"-")}function St(t){if(!t)return Lr;let e=HQ(t);return e?e==="transcript"||e.includes("codex")?"codex":e.includes("cursor")?"cursor":e.includes("claude")?"claude":e:Lr}function sD(t){let e=["claude","codex","cursor"];return[...t].sort((r,n)=>{let i=e.indexOf(r),s=e.indexOf(n);return i!==-1||s!==-1?i===-1?1:s===-1?-1:i-s:r.localeCompare(n)})}var Lr,bi=he(()=>{"use strict";Lr="claude"});function ZQ(t,e){return{customTitle:t,platformSource:e?St(e):void 0}}var oD,Ps,fg=he(()=>{"use strict";oD=require("bun:sqlite");Ct();Q();iD();KE();bi();Ps=class{db;constructor(e=Wd){e!==":memory:"&&sr(fr),this.db=new oD.Database(e),this.db.run("PRAGMA journal_mode = WAL"),this.db.run("PRAGMA synchronous = NORMAL"),this.db.run("PRAGMA foreign_keys = ON"),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()}initializeSchema(){this.db.run(` CREATE TABLE IF NOT EXISTS schema_versions ( id INTEGER PRIMARY KEY, version INTEGER UNIQUE NOT NULL, diff --git a/src/utils/project-name.ts b/src/utils/project-name.ts index 7c05e9b8..0642735e 100644 --- a/src/utils/project-name.ts +++ b/src/utils/project-name.ts @@ -64,7 +64,9 @@ export interface ProjectContext { parent: string | null; /** True if currently in a worktree */ isWorktree: boolean; - /** Projects to query — always `[primary]` so observations don't cross worktrees */ + /** Projects to query for reads. In a worktree: `[parent, composite]` so + * main-repo context flows into every worktree while sibling worktrees stay + * isolated. In the main repo: `[primary]`. Writes always use `.primary`. */ allProjects: string[]; } @@ -96,7 +98,7 @@ export function getProjectContext(cwd: string | null | undefined): ProjectContex primary: composite, parent: worktreeInfo.parentProjectName, isWorktree: true, - allProjects: [composite] + allProjects: [worktreeInfo.parentProjectName, composite] }; }