diff --git a/plugin/scripts/context-generator.cjs b/plugin/scripts/context-generator.cjs index b4dce51a..0b5f6bde 100644 --- a/plugin/scripts/context-generator.cjs +++ b/plugin/scripts/context-generator.cjs @@ -758,4 +758,4 @@ ${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(...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),u=d!==o?d:"";if(o=d,t.has(a.id)){let E=ft(a,s);n.push(...Ke(a,u,E,s))}else n.push(Ve(a,u,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 m=d.data,u=pe(m.displayTime);o.push(...mt(m,u))}else{let m=d.data,u=Tt(m.files_modified,n,m.files_read),l=le(m.created_at),E=l!==a;a=l;let T=t.has(m.id);if(u!==i&&(o.push(...at(u)),i=u),T){let O=ft(m,s);o.push(...ct(m,l,E,O,s))}else o.push(dt(m,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?ut(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 m=t.slice(0,s.sessionCount),u=we(m,t),l=ue(e,u),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=me(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 m=i.length>1?$e(d,i,t,o):de(d,a,t,o),u=i.length>1?Fe(d,i,t,o):ce(d,a,t,o);return m.length===0&&u.length===0?Qt(a,e):Zt(a,m,u,t,s,r?.session_id,e)}finally{d.close()}}0&&(module.exports={generateContext}); +`).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?.length?r.projects:n.allProjects,a=i[i.length-1]??n.primary;r?.full&&(t.totalObservationCount=999999,t.sessionCount=999999);let d=zt();if(!d)return"";try{let m=i.length>1?$e(d,i,t,o):de(d,a,t,o),u=i.length>1?Fe(d,i,t,o):ce(d,a,t,o);return m.length===0&&u.length===0?Qt(a,e):Zt(a,m,u,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 20cfd913..31f5b667 100755 --- a/plugin/scripts/worker-service.cjs +++ b/plugin/scripts/worker-service.cjs @@ -950,7 +950,7 @@ ${Y.gray}${"\u2500".repeat(60)}${Y.reset} ${Y.dim}No previous sessions found for this project yet.${Y.reset} `}var cl=he(()=>{"use strict";Um();rn();Ha()});function o5(t,e,r,n){let i=[];return n?i.push(...GH(t)):i.push(...AH(t)),n?i.push(...VH()):i.push(...NH()),n?i.push(...KH()):i.push(...MH()),n?i.push(...JH()):i.push(...DH()),a_(r)&&(n?i.push(...XH(e,r)):i.push(...jH(e,r))),i}var a5=he(()=>{"use strict";Ha();al();cl()});function yxe(t){let e=new Map;for(let n of t){let i=n.type==="observation"?n.data.created_at:n.data.displayTime,s=Ds(i);e.has(s)||e.set(s,[]),e.get(s).push(n)}let r=Array.from(e.entries()).sort((n,i)=>{let s=new Date(n[0]).getTime(),o=new Date(i[0]).getTime();return s-o});return new Map(r)}function c5(t,e){return e.fullObservationField==="narrative"?t.narrative:t.facts?Oa(t.facts).join(` `):null}function _xe(t,e,r,n){let i=[];i.push(...zH(t));let s="";for(let o of e)if(o.type==="summary"){let a=o.data,c=Dn(a.displayTime);i.push(...qH(a,c))}else{let a=o.data,c=yr(a.created_at),l=c!==s?c:"";if(s=c,r.has(a.id)){let p=c5(a,n);i.push(...FH(a,l,p,n))}else i.push(UH(a,l,n))}return i}function bxe(t,e,r,n,i){let s=[];s.push(...YH(t));let o=null,a="";for(let c of e)if(c.type==="summary"){o=null,a="";let u=c.data,l=Dn(u.displayTime);s.push(...r5(u,l))}else{let u=c.data,l=$i(u.files_modified,i,u.files_read),d=yr(u.created_at),p=d!==a;a=d;let m=r.has(u.id);if(l!==o&&(s.push(...QH(l)),o=l),m){let f=c5(u,n);s.push(...t5(u,d,p,f,n))}else s.push(e5(u,d,p,n))}return s.push(""),s}function Sxe(t,e,r,n,i,s){return s?bxe(t,e,r,n,i):_xe(t,e,r,n)}function u5(t,e,r,n,i){let s=[],o=yxe(t);for(let[a,c]of o)s.push(...Sxe(a,c,e,r,n,i));return s}var l5=he(()=>{"use strict";Ls();al();cl()});function d5(t,e,r){return!(!t.showLastSummary||!e||!!!(e.investigated||e.learned||e.completed||e.next_steps)||r&&e.created_at_epoch<=r.created_at_epoch)}function p5(t,e){let r=[];return e?(r.push(...Hm("Investigated",t.investigated,Y.blue)),r.push(...Hm("Learned",t.learned,Y.yellow)),r.push(...Hm("Completed",t.completed,Y.green)),r.push(...Hm("Next Steps",t.next_steps,Y.magenta))):(r.push(...qm("Investigated",t.investigated)),r.push(...qm("Learned",t.learned)),r.push(...qm("Completed",t.completed)),r.push(...qm("Next Steps",t.next_steps))),r}var m5=he(()=>{"use strict";Um();al();cl()});function f5(t,e){return e?n5(t):HH(t)}function h5(t,e,r){return!a_(e)||t.totalDiscoveryTokens<=0||t.savings<=0?[]:r?i5(t.totalDiscoveryTokens,t.totalReadTokens):ZH(t.totalDiscoveryTokens,t.totalReadTokens)}var g5=he(()=>{"use strict";Ha();al();cl()});function wxe(){try{return new Ps}catch(t){if(t.code==="ERR_DLOPEN_FAILED"){try{(0,_5.unlinkSync)(xxe)}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 t}}function Exe(t,e){return e?s5(t):BH(t)}function kxe(t,e,r,n,i,s,o){let a=[],c=KI(e);a.push(...o5(t,c,n,o));let u=r.slice(0,n.sessionCount),l=OH(u,r),d=QI(e,l),p=CH(e,n.fullObservationCount);a.push(...u5(d,p,n,i,o));let m=r[0],f=e[0];d5(n,m,f)&&a.push(...p5(m,o));let h=YI(e,n,s,i);return a.push(...f5(h,o)),a.push(...h5(c,n,o)),a.join(` -`).trimEnd()}async function tR(t,e=!1){let r=BI(),n=t?.cwd??process.cwd(),i=ar(n),s=t?.platform_source,o=t?.projects??i.allProjects,a=o[o.length-1];t?.full&&(r.totalObservationCount=999999,r.sessionCount=999999);let c=wxe();if(!c)return"";try{let u=o.length>1?IH(c,o,r,s):JI(c,a,r,s),l=o.length>1?RH(c,o,r,s):XI(c,a,r,s);return u.length===0&&l.length===0?Exe(a,e):kxe(a,u,l,r,n,t?.session_id,e)}finally{c.close()}}var v5,y5,_5,xxe,b5=he(()=>{"use strict";v5=Ie(require("path"),1),y5=require("os"),_5=require("fs");fg();Q();Ki();WI();Ha();eR();a5();l5();m5();g5();al();cl();xxe=v5.default.join((0,y5.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version")});var S5=he(()=>{"use strict";b5();WI();Ha();eR()});var rR={};ln(rR,{generateContext:()=>tR});var nR=he(()=>{"use strict";S5()});function Oxe(){try{let t=process.stdin;return t.isTTY?!1:(t.readable,!0)}catch{return!1}}function Cxe(t){let e=t.trim();if(!e)return{success:!1};try{return{success:!0,value:JSON.parse(e)}}catch{return{success:!1}}}async function I5(){if(Oxe())return new Promise((t,e)=>{let r="",n=!1,i=null,s=()=>{try{process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),process.stdin.removeAllListeners("error")}catch{}},o=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),t(l))},a=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),e(l))},c=()=>{let l=Cxe(r);return l.success?(o(l.value),!0):!1},u=setTimeout(()=>{n||c()||(r.trim()?a(new Error(`Incomplete JSON after ${$5}ms: ${r.slice(0,100)}...`)):o(void 0))},$5);try{process.stdin.on("data",l=>{r+=l,i&&(clearTimeout(i),i=null),!c()&&(i=setTimeout(()=>{c()},Pxe))}),process.stdin.on("end",()=>{n||c()||o((r.trim(),void 0))}),process.stdin.on("error",()=>{n||o(void 0)})}catch{n=!0,clearTimeout(u),s(),t(void 0)}})}var $5,Pxe,R5=he(()=>{"use strict";$5=3e4,Pxe=50});var O5,C5=he(()=>{"use strict";O5={normalizeInput(t){let e=t??{};return{sessionId:e.session_id??e.id??e.sessionId,cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.tool_name,toolInput:e.tool_input,toolResponse:e.tool_response,transcriptPath:e.transcript_path}},formatOutput(t){let e=t??{};if(e.hookSpecificOutput){let n={hookSpecificOutput:t.hookSpecificOutput};return e.systemMessage&&(n.systemMessage=e.systemMessage),n}let r={};return e.systemMessage&&(r.systemMessage=e.systemMessage),r}}});var P5,A5=he(()=>{"use strict";P5={normalizeInput(t){let e=t??{},r=!!e.command&&!e.tool_name;return{sessionId:e.conversation_id||e.generation_id||e.id,cwd:e.workspace_roots?.[0]??e.cwd??process.cwd(),prompt:e.prompt??e.query??e.input??e.message,toolName:r?"Bash":e.tool_name,toolInput:r?{command:e.command}:e.tool_input,toolResponse:r?{output:e.output}:e.result_json,transcriptPath:void 0,filePath:e.file_path,edits:e.edits}},formatOutput(t){return{continue:t.continue??!0}}}});var N5,M5=he(()=>{"use strict";N5={normalizeInput(t){let e=t??{},r=e.cwd??process.env.GEMINI_CWD??process.env.GEMINI_PROJECT_DIR??process.env.CLAUDE_PROJECT_DIR??process.cwd(),n=e.session_id??process.env.GEMINI_SESSION_ID??void 0,i=e.hook_event_name,s=e.tool_name,o=e.tool_input,a=e.tool_response;i==="AfterAgent"&&e.prompt_response&&(s=s??"GeminiAgent",o=o??{prompt:e.prompt},a=a??{response:e.prompt_response}),i==="BeforeTool"&&s&&!a&&(a={_preExecution:!0}),i==="Notification"&&(s=s??"GeminiNotification",o=o??{notification_type:e.notification_type,message:e.message},a=a??{details:e.details});let c={};return e.source&&(c.source=e.source),e.reason&&(c.reason=e.reason),e.trigger&&(c.trigger=e.trigger),e.mcp_context&&(c.mcp_context=e.mcp_context),e.notification_type&&(c.notification_type=e.notification_type),e.stop_hook_active!==void 0&&(c.stop_hook_active=e.stop_hook_active),e.original_request_name&&(c.original_request_name=e.original_request_name),i&&(c.hook_event_name=i),{sessionId:n,cwd:r,prompt:e.prompt,toolName:s,toolInput:o,toolResponse:a,transcriptPath:e.transcript_path,metadata:Object.keys(c).length>0?c:void 0}},formatOutput(t){let e={};if(e.continue=t.continue??!0,t.suppressOutput!==void 0&&(e.suppressOutput=t.suppressOutput),t.systemMessage){let r=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;e.systemMessage=t.systemMessage.replace(r,"")}return t.hookSpecificOutput&&(e.hookSpecificOutput={additionalContext:t.hookSpecificOutput.additionalContext}),e}}});var uR,D5=he(()=>{"use strict";uR={normalizeInput(t){let e=t;return{sessionId:e.sessionId??e.session_id??"unknown",cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.toolName??e.tool_name,toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResponse??e.tool_response,transcriptPath:e.transcriptPath??e.transcript_path,filePath:e.filePath??e.file_path,edits:e.edits}},formatOutput(t){return t}}});var j5,z5=he(()=>{"use strict";j5={normalizeInput(t){let e=t??{},r=e.tool_info??{},n=e.agent_action_name??"",i={sessionId:e.trajectory_id??e.execution_id,cwd:r.cwd??process.cwd(),platform:"windsurf"};switch(n){case"pre_user_prompt":return{...i,prompt:r.user_prompt};case"post_write_code":return{...i,toolName:"Write",filePath:r.file_path,edits:r.edits,toolInput:{file_path:r.file_path,edits:r.edits}};case"post_run_command":return{...i,cwd:r.cwd??i.cwd,toolName:"Bash",toolInput:{command:r.command_line}};case"post_mcp_tool_use":return{...i,toolName:r.mcp_tool_name??"mcp_tool",toolInput:r.mcp_tool_arguments,toolResponse:r.mcp_result};case"post_cascade_response":return{...i,toolName:"cascade_response",toolResponse:r.response};default:return i}},formatOutput(t){return{continue:t.continue??!0}}}});function L5(t){switch(t){case"claude-code":return O5;case"cursor":return P5;case"gemini":case"gemini-cli":return N5;case"windsurf":return j5;case"raw":return uR;default:return uR}}var U5=he(()=>{"use strict";C5();A5();M5();D5();z5()});var lR,dR=he(()=>{"use strict";Or();Ki();gn();Q();Yt();Ct();bi();lR={async execute(t){if(!await or())return{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""},exitCode:nt.SUCCESS};let r=t.cwd??process.cwd(),n=ar(r),i=Qr(),s=St(t.platform),a=ge.loadFromFile(dt).CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT==="true",c=n.allProjects.join(","),u=`/api/context/inject?projects=${encodeURIComponent(c)}&platformSource=${encodeURIComponent(s)}`,l=t.platform==="claude-code"?`${u}&colors=true`:u;try{let[d,p]=await Promise.all([ut(u),a?ut(l).catch(()=>null):Promise.resolve(null)]);if(!d.ok)return _.warn("HOOK","Context generation failed, returning empty",{status:d.status}),{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""},exitCode:nt.SUCCESS};let[m,f]=await Promise.all([d.text(),p?.ok?p.text():Promise.resolve("")]),h=m.trim(),g=f.trim(),v=t.platform,y=g||(v==="gemini-cli"||v==="gemini"?h:""),b=a&&y?`${y} +`).trimEnd()}async function tR(t,e=!1){let r=BI(),n=t?.cwd??process.cwd(),i=ar(n),s=t?.platform_source,o=t?.projects?.length?t.projects:i.allProjects,a=o[o.length-1]??i.primary;t?.full&&(r.totalObservationCount=999999,r.sessionCount=999999);let c=wxe();if(!c)return"";try{let u=o.length>1?IH(c,o,r,s):JI(c,a,r,s),l=o.length>1?RH(c,o,r,s):XI(c,a,r,s);return u.length===0&&l.length===0?Exe(a,e):kxe(a,u,l,r,n,t?.session_id,e)}finally{c.close()}}var v5,y5,_5,xxe,b5=he(()=>{"use strict";v5=Ie(require("path"),1),y5=require("os"),_5=require("fs");fg();Q();Ki();WI();Ha();eR();a5();l5();m5();g5();al();cl();xxe=v5.default.join((0,y5.homedir)(),".claude","plugins","marketplaces","thedotmack","plugin",".install-version")});var S5=he(()=>{"use strict";b5();WI();Ha();eR()});var rR={};ln(rR,{generateContext:()=>tR});var nR=he(()=>{"use strict";S5()});function Oxe(){try{let t=process.stdin;return t.isTTY?!1:(t.readable,!0)}catch{return!1}}function Cxe(t){let e=t.trim();if(!e)return{success:!1};try{return{success:!0,value:JSON.parse(e)}}catch{return{success:!1}}}async function I5(){if(Oxe())return new Promise((t,e)=>{let r="",n=!1,i=null,s=()=>{try{process.stdin.removeAllListeners("data"),process.stdin.removeAllListeners("end"),process.stdin.removeAllListeners("error")}catch{}},o=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),t(l))},a=l=>{n||(n=!0,i&&clearTimeout(i),clearTimeout(u),s(),e(l))},c=()=>{let l=Cxe(r);return l.success?(o(l.value),!0):!1},u=setTimeout(()=>{n||c()||(r.trim()?a(new Error(`Incomplete JSON after ${$5}ms: ${r.slice(0,100)}...`)):o(void 0))},$5);try{process.stdin.on("data",l=>{r+=l,i&&(clearTimeout(i),i=null),!c()&&(i=setTimeout(()=>{c()},Pxe))}),process.stdin.on("end",()=>{n||c()||o((r.trim(),void 0))}),process.stdin.on("error",()=>{n||o(void 0)})}catch{n=!0,clearTimeout(u),s(),t(void 0)}})}var $5,Pxe,R5=he(()=>{"use strict";$5=3e4,Pxe=50});var O5,C5=he(()=>{"use strict";O5={normalizeInput(t){let e=t??{};return{sessionId:e.session_id??e.id??e.sessionId,cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.tool_name,toolInput:e.tool_input,toolResponse:e.tool_response,transcriptPath:e.transcript_path}},formatOutput(t){let e=t??{};if(e.hookSpecificOutput){let n={hookSpecificOutput:t.hookSpecificOutput};return e.systemMessage&&(n.systemMessage=e.systemMessage),n}let r={};return e.systemMessage&&(r.systemMessage=e.systemMessage),r}}});var P5,A5=he(()=>{"use strict";P5={normalizeInput(t){let e=t??{},r=!!e.command&&!e.tool_name;return{sessionId:e.conversation_id||e.generation_id||e.id,cwd:e.workspace_roots?.[0]??e.cwd??process.cwd(),prompt:e.prompt??e.query??e.input??e.message,toolName:r?"Bash":e.tool_name,toolInput:r?{command:e.command}:e.tool_input,toolResponse:r?{output:e.output}:e.result_json,transcriptPath:void 0,filePath:e.file_path,edits:e.edits}},formatOutput(t){return{continue:t.continue??!0}}}});var N5,M5=he(()=>{"use strict";N5={normalizeInput(t){let e=t??{},r=e.cwd??process.env.GEMINI_CWD??process.env.GEMINI_PROJECT_DIR??process.env.CLAUDE_PROJECT_DIR??process.cwd(),n=e.session_id??process.env.GEMINI_SESSION_ID??void 0,i=e.hook_event_name,s=e.tool_name,o=e.tool_input,a=e.tool_response;i==="AfterAgent"&&e.prompt_response&&(s=s??"GeminiAgent",o=o??{prompt:e.prompt},a=a??{response:e.prompt_response}),i==="BeforeTool"&&s&&!a&&(a={_preExecution:!0}),i==="Notification"&&(s=s??"GeminiNotification",o=o??{notification_type:e.notification_type,message:e.message},a=a??{details:e.details});let c={};return e.source&&(c.source=e.source),e.reason&&(c.reason=e.reason),e.trigger&&(c.trigger=e.trigger),e.mcp_context&&(c.mcp_context=e.mcp_context),e.notification_type&&(c.notification_type=e.notification_type),e.stop_hook_active!==void 0&&(c.stop_hook_active=e.stop_hook_active),e.original_request_name&&(c.original_request_name=e.original_request_name),i&&(c.hook_event_name=i),{sessionId:n,cwd:r,prompt:e.prompt,toolName:s,toolInput:o,toolResponse:a,transcriptPath:e.transcript_path,metadata:Object.keys(c).length>0?c:void 0}},formatOutput(t){let e={};if(e.continue=t.continue??!0,t.suppressOutput!==void 0&&(e.suppressOutput=t.suppressOutput),t.systemMessage){let r=/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;e.systemMessage=t.systemMessage.replace(r,"")}return t.hookSpecificOutput&&(e.hookSpecificOutput={additionalContext:t.hookSpecificOutput.additionalContext}),e}}});var uR,D5=he(()=>{"use strict";uR={normalizeInput(t){let e=t;return{sessionId:e.sessionId??e.session_id??"unknown",cwd:e.cwd??process.cwd(),prompt:e.prompt,toolName:e.toolName??e.tool_name,toolInput:e.toolInput??e.tool_input,toolResponse:e.toolResponse??e.tool_response,transcriptPath:e.transcriptPath??e.transcript_path,filePath:e.filePath??e.file_path,edits:e.edits}},formatOutput(t){return t}}});var j5,z5=he(()=>{"use strict";j5={normalizeInput(t){let e=t??{},r=e.tool_info??{},n=e.agent_action_name??"",i={sessionId:e.trajectory_id??e.execution_id,cwd:r.cwd??process.cwd(),platform:"windsurf"};switch(n){case"pre_user_prompt":return{...i,prompt:r.user_prompt};case"post_write_code":return{...i,toolName:"Write",filePath:r.file_path,edits:r.edits,toolInput:{file_path:r.file_path,edits:r.edits}};case"post_run_command":return{...i,cwd:r.cwd??i.cwd,toolName:"Bash",toolInput:{command:r.command_line}};case"post_mcp_tool_use":return{...i,toolName:r.mcp_tool_name??"mcp_tool",toolInput:r.mcp_tool_arguments,toolResponse:r.mcp_result};case"post_cascade_response":return{...i,toolName:"cascade_response",toolResponse:r.response};default:return i}},formatOutput(t){return{continue:t.continue??!0}}}});function L5(t){switch(t){case"claude-code":return O5;case"cursor":return P5;case"gemini":case"gemini-cli":return N5;case"windsurf":return j5;case"raw":return uR;default:return uR}}var U5=he(()=>{"use strict";C5();A5();M5();D5();z5()});var lR,dR=he(()=>{"use strict";Or();Ki();gn();Q();Yt();Ct();bi();lR={async execute(t){if(!await or())return{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""},exitCode:nt.SUCCESS};let r=t.cwd??process.cwd(),n=ar(r),i=Qr(),s=St(t.platform),a=ge.loadFromFile(dt).CLAUDE_MEM_CONTEXT_SHOW_TERMINAL_OUTPUT==="true",c=n.allProjects.join(","),u=`/api/context/inject?projects=${encodeURIComponent(c)}&platformSource=${encodeURIComponent(s)}`,l=t.platform==="claude-code"?`${u}&colors=true`:u;try{let[d,p]=await Promise.all([ut(u),a?ut(l).catch(()=>null):Promise.resolve(null)]);if(!d.ok)return _.warn("HOOK","Context generation failed, returning empty",{status:d.status}),{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""},exitCode:nt.SUCCESS};let[m,f]=await Promise.all([d.text(),p?.ok?p.text():Promise.resolve("")]),h=m.trim(),g=f.trim(),v=t.platform,y=g||(v==="gemini-cli"||v==="gemini"?h:""),b=a&&y?`${y} View Observations Live @ http://localhost:${i}`:void 0;return{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:h},systemMessage:b}}catch(d){return _.warn("HOOK","Context fetch error, returning empty",{error:d instanceof Error?d.message:String(d)}),{hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:""},exitCode:nt.SUCCESS}}}}});function Axe(t){try{let e=JSON.parse(t);if(e&&Array.isArray(e.messages))return{isGemini:!0,messages:e.messages}}catch{}return{isGemini:!1}}function F5(t,e,r=!1){if(!t||!(0,w_.existsSync)(t))return _.warn("PARSER",`Transcript path missing or file does not exist: ${t}`),"";let n=(0,w_.readFileSync)(t,"utf-8").trim();if(!n)return _.warn("PARSER",`Transcript file exists but is empty: ${t}`),"";let i=Axe(n);return i.isGemini?Nxe(i.messages,e,r):Mxe(n,e,r)}function Nxe(t,e,r){let n=e==="assistant"?"gemini":"user";for(let i=t.length-1;i>=0;i--){let s=t[i];if(s?.type===n&&typeof s.content=="string"){let o=s.content;return r&&(o=o.replace(sl,""),o=o.replace(/\n{3,}/g,` @@ -1683,8 +1683,8 @@ ${e}`,o=T$(i,s),a=`${t}.tmp`;try{(0,Di.writeFileSync)(a,o),(0,Di.renameSync)(a,t SET status = 'failed', failed_at_epoch = ? WHERE status = 'pending' AND session_db_id IN (${d}) - `).run(Date.now(),...l);p.changes>0&&_.info("SYSTEM",`Marked ${p.changes} pending messages from stale sessions as failed`)}}catch(u){_.error("SYSTEM","Failed to clean up stale sessions",{},u)}let a=n.getSessionsWithPendingMessages(),c={totalPendingSessions:a.length,sessionsStarted:0,sessionsSkipped:0,startedSessionIds:[]};if(a.length===0)return c;_.info("SYSTEM",`Processing up to ${e} of ${a.length} pending session queues`);for(let u of a){if(c.sessionsStarted>=e)break;try{if(this.sessionManager.getSession(u)?.generatorPromise){c.sessionsSkipped++;continue}let d=this.sessionManager.initializeSession(u);_.info("SYSTEM",`Starting processor for session ${u}`,{project:d.project,pendingCount:n.getPendingCount(u)}),this.startSessionProcessor(d,"startup-recovery"),c.sessionsStarted++,c.startedSessionIds.push(u),await new Promise(p=>setTimeout(p,100))}catch(l){_.error("SYSTEM",`Failed to process session ${u}`,{},l),c.sessionsSkipped++}}return c}async shutdown(){this.transcriptWatcher&&(this.transcriptWatcher.stop(),this.transcriptWatcher=null,_.info("TRANSCRIPT","Transcript watcher stopped")),this.stopOrphanReaper&&(this.stopOrphanReaper(),this.stopOrphanReaper=null),this.staleSessionReaperInterval&&(clearInterval(this.staleSessionReaperInterval),this.staleSessionReaperInterval=null),await ID({server:this.server.getHttpServer(),sessionManager:this.sessionManager,mcpClient:this.mcpClient,dbManager:this.dbManager,chromaMcpManager:this.chromaMcpManager||void 0})}broadcastProcessingStatus(){let e=this.sessionManager.getTotalActiveWork(),r=e>0,n=this.sessionManager.getActiveSessionCount();_.info("WORKER","Broadcasting processing status",{isProcessing:r,queueDepth:e,activeSessions:n}),this.sseBroadcaster.broadcast({type:"processing_status",isProcessing:r,queueDepth:e})}};async function xR(t){return TD(t,__filename)}async function lwe(){let t=process.argv[2];(["start","hook","restart","--daemon"].includes(t)||t===void 0)&&_g()&&process.exit(0);let r=Qr();function n(i,s){let o=t3(i,s);console.log(JSON.stringify(o)),process.exit(0)}switch(t){case"start":{await xR(r)?n("ready"):n("error","Failed to start worker");break}case"stop":{await sk(r),await ik(r,Ji(15e3))||_.warn("SYSTEM","Port did not free up after shutdown",{port:r}),da(),_.info("SYSTEM","Worker stopped successfully"),process.exit(0);break}case"restart":{_.info("SYSTEM","Restarting worker"),await sk(r),await ik(r,Ji(15e3))||(_.error("SYSTEM","Port did not free up after shutdown, aborting restart",{port:r}),process.exit(0)),da(),gg(__filename,r)===void 0&&(_.error("SYSTEM","Failed to spawn worker daemon during restart"),process.exit(0)),await bo(r,Ji(fr.POST_SPAWN_WAIT))||(da(),_.error("SYSTEM","Worker failed to restart"),process.exit(0)),_.info("SYSTEM","Worker restarted successfully"),process.exit(0);break}case"status":{let i=await Bc(r),s=rk();i&&s?(console.log("Worker is running"),console.log(` PID: ${s.pid}`),console.log(` Port: ${s.port}`),console.log(` Started: ${s.startedAt}`)):console.log("Worker is not running"),process.exit(0);break}case"cursor":{let i=process.argv[3],s=await K6(i,process.argv.slice(4));process.exit(s);break}case"gemini-cli":{let i=process.argv[3],s=await Y6(i,process.argv.slice(4));process.exit(s);break}case"hook":{let i=process.argv[3],s=process.argv[4];(!i||!s)&&(console.error("Usage: claude-mem hook "),console.error("Platforms: claude-code, cursor, gemini-cli, raw"),console.error("Events: context, session-init, observation, summarize, session-complete, user-message"),process.exit(1)),await xR(r)||_.warn("SYSTEM","Worker failed to start before hook, handler will proceed gracefully");let{hookCommand:a}=await Promise.resolve().then(()=>(K5(),V5));await a(i,s);break}case"generate":{let i=process.argv.includes("--dry-run"),{generateClaudeMd:s}=await Promise.resolve().then(()=>(bR(),_R)),o=await s(i);process.exit(o);break}case"clean":{let i=process.argv.includes("--dry-run"),{cleanClaudeMd:s}=await Promise.resolve().then(()=>(bR(),_R)),o=await s(i);process.exit(o);break}case"adopt":{let i=process.argv.includes("--dry-run"),s=process.argv.indexOf("--branch"),o=s!==-1?process.argv[s+1]:void 0,a=process.argv.indexOf("--cwd"),c=a!==-1?process.argv[a+1]:process.cwd(),u=await dk({repoPath:c,dryRun:i,onlyBranch:o}),l=u.dryRun?"(dry-run)":"(applied)";console.log(` -Worktree adoption ${l}`),console.log(` Parent project: ${u.parentProject||"(unknown)"}`),console.log(` Repo: ${u.repoPath}`),console.log(` Worktrees scanned: ${u.scannedWorktrees}`),console.log(` Merged branches: ${u.mergedBranches.join(", ")||"(none)"}`),console.log(` Observations adopted: ${u.adoptedObservations}`),console.log(` Summaries adopted: ${u.adoptedSummaries}`),console.log(` Chroma docs updated: ${u.chromaUpdates}`),u.chromaFailed>0&&console.log(` Chroma sync failures: ${u.chromaFailed} (will retry on next run)`);for(let d of u.errors)console.log(` ! ${d.worktree}: ${d.error}`);process.exit(0)}default:{let i=rk();i&&bD(i.pid)&&(_.info("SYSTEM","Worker already running (PID alive), refusing to start duplicate",{existingPid:i.pid,existingPort:i.port,startedAt:i.startedAt}),process.exit(0)),await Bc(r)&&(_.info("SYSTEM","Port already in use, refusing to start duplicate",{port:r}),process.exit(0)),process.on("unhandledRejection",o=>{_.error("SYSTEM","Unhandled rejection in daemon",{reason:o instanceof Error?o.message:String(o)})}),process.on("uncaughtException",o=>{_.error("SYSTEM","Uncaught exception in daemon",{},o)}),new E_().start().catch(async o=>{o instanceof Error&&(o.code==="EADDRINUSE"||/port.*in use|address.*in use/i.test(o.message))&&await bo(r,3e3)&&(_.info("SYSTEM","Duplicate daemon exiting \u2014 another worker already claimed port",{port:r}),process.exit(0)),_.failure("SYSTEM","Worker failed to start",{},o),da(),process.exit(0)})}}}var dwe=typeof require<"u"&&typeof module<"u"?require.main===module||!module.parent||process.env.CLAUDE_MEM_MANAGED==="true":mwe.url===`file://${process.argv[1]}`||process.argv[1]?.endsWith("worker-service")||process.argv[1]?.endsWith("worker-service.cjs")||process.argv[1]?.replaceAll("\\","/")===__filename?.replaceAll("\\","/");dwe&&lwe().catch(t=>{_.error("SYSTEM","Fatal error in main",{},t instanceof Error?t:void 0),process.exit(0)});0&&(module.exports={WorkerService,buildStatusOutput,ensureWorkerStarted,isPluginDisabledInClaudeSettings}); + `).run(Date.now(),...l);p.changes>0&&_.info("SYSTEM",`Marked ${p.changes} pending messages from stale sessions as failed`)}}catch(u){_.error("SYSTEM","Failed to clean up stale sessions",{},u)}let a=n.getSessionsWithPendingMessages(),c={totalPendingSessions:a.length,sessionsStarted:0,sessionsSkipped:0,startedSessionIds:[]};if(a.length===0)return c;_.info("SYSTEM",`Processing up to ${e} of ${a.length} pending session queues`);for(let u of a){if(c.sessionsStarted>=e)break;try{if(this.sessionManager.getSession(u)?.generatorPromise){c.sessionsSkipped++;continue}let d=this.sessionManager.initializeSession(u);_.info("SYSTEM",`Starting processor for session ${u}`,{project:d.project,pendingCount:n.getPendingCount(u)}),this.startSessionProcessor(d,"startup-recovery"),c.sessionsStarted++,c.startedSessionIds.push(u),await new Promise(p=>setTimeout(p,100))}catch(l){_.error("SYSTEM",`Failed to process session ${u}`,{},l),c.sessionsSkipped++}}return c}async shutdown(){this.transcriptWatcher&&(this.transcriptWatcher.stop(),this.transcriptWatcher=null,_.info("TRANSCRIPT","Transcript watcher stopped")),this.stopOrphanReaper&&(this.stopOrphanReaper(),this.stopOrphanReaper=null),this.staleSessionReaperInterval&&(clearInterval(this.staleSessionReaperInterval),this.staleSessionReaperInterval=null),await ID({server:this.server.getHttpServer(),sessionManager:this.sessionManager,mcpClient:this.mcpClient,dbManager:this.dbManager,chromaMcpManager:this.chromaMcpManager||void 0})}broadcastProcessingStatus(){let e=this.sessionManager.getTotalActiveWork(),r=e>0,n=this.sessionManager.getActiveSessionCount();_.info("WORKER","Broadcasting processing status",{isProcessing:r,queueDepth:e,activeSessions:n}),this.sseBroadcaster.broadcast({type:"processing_status",isProcessing:r,queueDepth:e})}};async function xR(t){return TD(t,__filename)}async function lwe(){let t=process.argv[2];(["start","hook","restart","--daemon"].includes(t)||t===void 0)&&_g()&&process.exit(0);let r=Qr();function n(i,s){let o=t3(i,s);console.log(JSON.stringify(o)),process.exit(0)}switch(t){case"start":{await xR(r)?n("ready"):n("error","Failed to start worker");break}case"stop":{await sk(r),await ik(r,Ji(15e3))||_.warn("SYSTEM","Port did not free up after shutdown",{port:r}),da(),_.info("SYSTEM","Worker stopped successfully"),process.exit(0);break}case"restart":{_.info("SYSTEM","Restarting worker"),await sk(r),await ik(r,Ji(15e3))||(_.error("SYSTEM","Port did not free up after shutdown, aborting restart",{port:r}),process.exit(0)),da(),gg(__filename,r)===void 0&&(_.error("SYSTEM","Failed to spawn worker daemon during restart"),process.exit(0)),await bo(r,Ji(fr.POST_SPAWN_WAIT))||(da(),_.error("SYSTEM","Worker failed to restart"),process.exit(0)),_.info("SYSTEM","Worker restarted successfully"),process.exit(0);break}case"status":{let i=await Bc(r),s=rk();i&&s?(console.log("Worker is running"),console.log(` PID: ${s.pid}`),console.log(` Port: ${s.port}`),console.log(` Started: ${s.startedAt}`)):console.log("Worker is not running"),process.exit(0);break}case"cursor":{let i=process.argv[3],s=await K6(i,process.argv.slice(4));process.exit(s);break}case"gemini-cli":{let i=process.argv[3],s=await Y6(i,process.argv.slice(4));process.exit(s);break}case"hook":{let i=process.argv[3],s=process.argv[4];(!i||!s)&&(console.error("Usage: claude-mem hook "),console.error("Platforms: claude-code, cursor, gemini-cli, raw"),console.error("Events: context, session-init, observation, summarize, session-complete, user-message"),process.exit(1)),await xR(r)||_.warn("SYSTEM","Worker failed to start before hook, handler will proceed gracefully");let{hookCommand:a}=await Promise.resolve().then(()=>(K5(),V5));await a(i,s);break}case"generate":{let i=process.argv.includes("--dry-run"),{generateClaudeMd:s}=await Promise.resolve().then(()=>(bR(),_R)),o=await s(i);process.exit(o);break}case"clean":{let i=process.argv.includes("--dry-run"),{cleanClaudeMd:s}=await Promise.resolve().then(()=>(bR(),_R)),o=await s(i);process.exit(o);break}case"adopt":{let i=process.argv.includes("--dry-run"),s=process.argv.indexOf("--branch"),o=s!==-1?process.argv[s+1]:void 0;s!==-1&&(!o||o.startsWith("--"))&&(console.error("Usage: adopt [--dry-run] [--branch ] [--cwd ]"),process.exit(1));let a=o,c=process.argv.indexOf("--cwd"),u=c!==-1?process.argv[c+1]:void 0;c!==-1&&(!u||u.startsWith("--"))&&(console.error("Usage: adopt [--dry-run] [--branch ] [--cwd ]"),process.exit(1));let l=u??process.cwd(),d=await dk({repoPath:l,dryRun:i,onlyBranch:a}),p=d.dryRun?"(dry-run)":"(applied)";console.log(` +Worktree adoption ${p}`),console.log(` Parent project: ${d.parentProject||"(unknown)"}`),console.log(` Repo: ${d.repoPath}`),console.log(` Worktrees scanned: ${d.scannedWorktrees}`),console.log(` Merged branches: ${d.mergedBranches.join(", ")||"(none)"}`),console.log(` Observations adopted: ${d.adoptedObservations}`),console.log(` Summaries adopted: ${d.adoptedSummaries}`),console.log(` Chroma docs updated: ${d.chromaUpdates}`),d.chromaFailed>0&&console.log(` Chroma sync failures: ${d.chromaFailed} (will retry on next run)`);for(let m of d.errors)console.log(` ! ${m.worktree}: ${m.error}`);process.exit(0)}default:{let i=rk();i&&bD(i.pid)&&(_.info("SYSTEM","Worker already running (PID alive), refusing to start duplicate",{existingPid:i.pid,existingPort:i.port,startedAt:i.startedAt}),process.exit(0)),await Bc(r)&&(_.info("SYSTEM","Port already in use, refusing to start duplicate",{port:r}),process.exit(0)),process.on("unhandledRejection",o=>{_.error("SYSTEM","Unhandled rejection in daemon",{reason:o instanceof Error?o.message:String(o)})}),process.on("uncaughtException",o=>{_.error("SYSTEM","Uncaught exception in daemon",{},o)}),new E_().start().catch(async o=>{o instanceof Error&&(o.code==="EADDRINUSE"||/port.*in use|address.*in use/i.test(o.message))&&await bo(r,3e3)&&(_.info("SYSTEM","Duplicate daemon exiting \u2014 another worker already claimed port",{port:r}),process.exit(0)),_.failure("SYSTEM","Worker failed to start",{},o),da(),process.exit(0)})}}}var dwe=typeof require<"u"&&typeof module<"u"?require.main===module||!module.parent||process.env.CLAUDE_MEM_MANAGED==="true":mwe.url===`file://${process.argv[1]}`||process.argv[1]?.endsWith("worker-service")||process.argv[1]?.endsWith("worker-service.cjs")||process.argv[1]?.replaceAll("\\","/")===__filename?.replaceAll("\\","/");dwe&&lwe().catch(t=>{_.error("SYSTEM","Fatal error in main",{},t instanceof Error?t:void 0),process.exit(0)});0&&(module.exports={WorkerService,buildStatusOutput,ensureWorkerStarted,isPluginDisabledInClaudeSettings}); /*! Bundled license information: depd/index.js: diff --git a/plugin/ui/viewer.html b/plugin/ui/viewer.html index 04f79156..aa0e0cfb 100644 --- a/plugin/ui/viewer.html +++ b/plugin/ui/viewer.html @@ -1139,7 +1139,7 @@ letter-spacing: 0.02em; color: var(--color-text-muted); background: var(--color-type-badge-bg); - border: 1px solid var(--color-border); + border: 1px solid var(--color-border-primary); opacity: 0.85; } diff --git a/src/npx-cli/index.ts b/src/npx-cli/index.ts index a706eb7b..cd0d999e 100644 --- a/src/npx-cli/index.ts +++ b/src/npx-cli/index.ts @@ -52,7 +52,7 @@ ${pc.bold('Runtime Commands')} (requires Bun, delegates to installed plugin): ${pc.cyan('npx claude-mem restart')} Restart worker service ${pc.cyan('npx claude-mem status')} Show worker status ${pc.cyan('npx claude-mem search ')} Search observations - ${pc.cyan('npx claude-mem adopt [--dry-run]')} Stamp merged worktrees into parent project + ${pc.cyan('npx claude-mem adopt [--dry-run] [--branch ]')} Stamp merged worktrees into parent project ${pc.cyan('npx claude-mem transcript watch')} Start transcript watcher ${pc.bold('IDE Identifiers')}: diff --git a/src/services/context/ContextBuilder.ts b/src/services/context/ContextBuilder.ts index 8190dc9a..b7f0aa79 100644 --- a/src/services/context/ContextBuilder.ts +++ b/src/services/context/ContextBuilder.ts @@ -136,8 +136,8 @@ export async function generateContext( // `project` (used for header + single-project query) is always the last entry // of `projects` so the empty-state header and the query target stay in sync // when a caller passes `projects` without a matching cwd (e.g. worker route). - const projects = input?.projects ?? context.allProjects; - const project = projects[projects.length - 1]; + const projects = input?.projects?.length ? input.projects : context.allProjects; + const project = projects[projects.length - 1] ?? context.primary; // Full mode: fetch all observations but keep normal rendering (level 1 summaries) if (input?.full) { diff --git a/src/services/sqlite/migrations/runner.ts b/src/services/sqlite/migrations/runner.ts index 3c601126..0f736715 100644 --- a/src/services/sqlite/migrations/runner.ts +++ b/src/services/sqlite/migrations/runner.ts @@ -937,19 +937,19 @@ export class MigrationRunner { .all() as TableColumnInfo[]; if (!obsCols.some(c => c.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.run( + 'CREATE INDEX IF NOT EXISTS idx_observations_merged_into ON observations(merged_into_project)' + ); const sumCols = this.db .query('PRAGMA table_info(session_summaries)') .all() as TableColumnInfo[]; if (!sumCols.some(c => c.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)' - ); } + this.db.run( + 'CREATE INDEX IF NOT EXISTS idx_summaries_merged_into ON session_summaries(merged_into_project)' + ); } } diff --git a/src/services/worker-service.ts b/src/services/worker-service.ts index b16d6979..aaa7151c 100644 --- a/src/services/worker-service.ts +++ b/src/services/worker-service.ts @@ -1211,11 +1211,21 @@ async function main() { case 'adopt': { const dryRun = process.argv.includes('--dry-run'); const branchIndex = process.argv.indexOf('--branch'); - const onlyBranch = branchIndex !== -1 ? process.argv[branchIndex + 1] : undefined; + const branchValue = branchIndex !== -1 ? process.argv[branchIndex + 1] : undefined; + if (branchIndex !== -1 && (!branchValue || branchValue.startsWith('--'))) { + console.error('Usage: adopt [--dry-run] [--branch ] [--cwd ]'); + process.exit(1); + } + const onlyBranch = branchValue; // Honor an explicit --cwd override so the NPX CLI can pass through the // user's working directory (the spawn sets cwd to the marketplace dir). const cwdIndex = process.argv.indexOf('--cwd'); - const repoPath = cwdIndex !== -1 ? process.argv[cwdIndex + 1] : process.cwd(); + const cwdValue = cwdIndex !== -1 ? process.argv[cwdIndex + 1] : undefined; + if (cwdIndex !== -1 && (!cwdValue || cwdValue.startsWith('--'))) { + console.error('Usage: adopt [--dry-run] [--branch ] [--cwd ]'); + process.exit(1); + } + const repoPath = cwdValue ?? process.cwd(); const result = await adoptMergedWorktrees({ repoPath, dryRun, onlyBranch }); diff --git a/src/ui/viewer-template.html b/src/ui/viewer-template.html index 04f79156..aa0e0cfb 100644 --- a/src/ui/viewer-template.html +++ b/src/ui/viewer-template.html @@ -1139,7 +1139,7 @@ letter-spacing: 0.02em; color: var(--color-text-muted); background: var(--color-type-badge-bg); - border: 1px solid var(--color-border); + border: 1px solid var(--color-border-primary); opacity: 0.85; }