| 7737 | `).map((w)=>w.trim()).filter(Boolean)}catch($){return N(`File suggestion helper failed: ${$}`,{level:"error"}),[]}}async function rhY({hook:q,messages:K,hookName:_,toolUseID:z,hookEvent:Y,timeoutMs:$,signal:A}){let O=q.timeout??$,{signal:w,cleanup:j}=Ty(A,{timeoutMs:O});try{if(w.aborted)return j(),{outcome:"cancelled",hook:q};let H=await new Promise((J,M)=>{let X=()=>M(Error("Function hook cancelled"));w.addEventListener("abort",X),Promise.resolve(q.callback(K,w)).then((P)=>{w.removeEventListener("abort",X),J(P)}).catch((P)=>{w.removeEventListener("abort",X),M(P)})});if(j(),H)return{outcome:"success",hook:q};return{blockingError:{blockingError:q.errorMessage,command:"function"},outcome:"blocking",hook:q}}catch(H){if(j(),H instanceof Error&&(H.message==="Function hook cancelled"||H.name==="AbortError"))return{outcome:"cancelled",hook:q};return H6(H),{message:V4({type:"hook_error_during_execution",hookName:_,toolUseID:z,hookEvent:Y,content:H instanceof Error?H.message:"Function hook execution error"}),outcome:"non_blocking_error",hook:q}}}async function ohY({toolUseID:q,hook:K,hookEvent:_,hookInput:z,signal:Y,hookIndex:$,toolUseContext:A}){let O=A?{getAppState:A.getAppState,updateAttributionState:A.updateAttributionState}:void 0,w=await K.callback(z,q,Y,$,O);if(rb(w))return{outcome:"success",hook:K};return{...A_7({json:w,command:"callback",hookName:`${_}:Callback`,toolUseID:q,hookEvent:_,expectedHookEvent:_,stdout:void 0,stderr:void 0,exitCode:void 0}),outcome:"success",hook:K}}function NJ6(){let q=bQ()?.WorktreeCreate;if(q&&q.length>0)return!0;let K=sR()?.WorktreeCreate;if(!K||K.length===0)return!1;let _=fb();return K.some((z)=>!(_&&("pluginRoot"in z)))}async function dq8(q){let K={...C$(void 0),hook_event_name:"WorktreeCreate",name:q},_=await ob({hookInput:K,timeoutMs:PO}),z=_.find(($)=>$.succeeded&&$.output.trim().length>0);if(!z){let $=_.filter((A)=>!A.succeeded).map((A)=>`${A.command}: ${A.output.trim()||"no output"}`);throw Error(`WorktreeCreate hook failed: ${$.join("; ")||"no successful output"}`)}return{worktreePath:z.output.trim()}}async function SQ8(q){let K=bQ()?.WorktreeRemove,_=sR()?.WorktreeRemove,z=K&&K.length>0,Y=_&&_.length>0;if(!z&&!Y)return!1;let $={...C$(void 0),hook_event_name:"WorktreeRemove",worktree_path:q},A=await ob({hookInput:$,timeoutMs:PO});if(A.length===0)return!1;for(let O of A)if(!O.succeeded)N(`WorktreeRemove hook failed [${O.command}]: ${O.output.trim()}`,{level:"error"});return!0}function TgK(q){return q.map(({hook:K})=>{if(K.type==="command")return{type:"command",command:K.command};else if(K.type==="prompt")return{type:"prompt",prompt:K.prompt};else if(K.type==="http")return{type:"http",command:K.url};else if(K.type==="function")return{type:"function",name:"function"};else if(K.type==="callback")return{type:"callback",name:"callback"};return{type:"unknown"}})}var PO=600000,chY=1500;var y$=y(()=>{bK();ya1();ZL6();I7();fa1();tE6();bw6();vK();NB();GL6();PA8();va1();mu();aV();v8();V1();Vj6();_K();U1();k8();nu();BZ();w46();Y_7();x3();Uw6();_8();oY();Gf();E8();nS6();_B8();p2();i1();y18();lP();ww6();Bq();OgK();HgK();fgK();zo();l8();m8();y8()});var pgK={};T8(pgK,{worktreeBranchName:()=>yJ6,validateWorktreeSlug:()=>VR6,restoreWorktreeSession:()=>CQ8,removeAgentWorktree:()=>QK6,parsePRReference:()=>xQ8,killTmuxSession:()=>NR6,keepWorktree:()=>yR6,isTmuxAvailable:()=>D_7,hasWorktreeChanges:()=>v67,getTmuxInstallInstructions:()=>f_7,getCurrentWorktreeSession:()=>n2,generateTmuxSessionName:()=>bQ8,execIntoTmuxWorktree:()=>$SY,createWorktreeForSession:()=>b88,createTmuxSessionForWorktree:()=>Z_7,createAgentWorktree:()=>c88,copyWorktreeIncludeFiles:()=>mgK,cleanupWorktree:()=>ER6,cleanupStaleAgentWorktrees:()=>G_7});import{spawnSync as Dk}from"child_process";import{copyFile as SgK,mkdir as M_7,readdir as ahY,readFile as shY,stat as CgK,symlink as thY,utimes as ehY}from"fs/promises";import{basename as J_7,dirname as xgK,join as ab}from"path";function VR6(q){if(q.length>hgK)throw Error(`Invalid worktree name: must be ${hgK} characters or fewer (got ${q.length})`);for(let K of q.split("/")){if(K==="."||K==="..")throw Error(`Invalid worktree name "${q}": must not contain "." or ".." path segments`);if(!qSY.test(K))throw Error(`Invalid worktree name "${q}": each "/"-separated segment must be non-empty and contain only letters, digits, dots, underscores, and dashes`)}}async function KSY(q){await M_7(q,{recursive:!0})}async function _SY(q,K,_){for(let z of _){if(yB(z)){N(`Skipping symlink for "${z}": path traversal detected`,{level:"warn"});continue}let Y=ab(q,z),$=ab(K,z);try{await thY(Y,$,"dir"),N(`Symlinked ${z} from main repository to worktree to avoid disk bloat`)}catch(A){let O=s1(A);if(O!=="ENOENT"&&O!=="EEXIST")N(`Failed to symlink ${z} (${O??"unknown"}): ${d6(A)}`,{level:"warn"})}}}function n2(){return TR}function CQ8(q){TR=q}function bQ8(q,K){return`${J_7(q)}_${K}`.replace(/[/.]/g,"_")}function X_7(q){return ab(q,".claude","worktrees")}function IgK(q){return q.replaceAll("/","+")}function yJ6(q){return`worktree-${IgK(q)}`}function ugK(q,K){return ab(X_7(q),IgK(K))}async function P_7(q,K,_){let z=ugK(q,K),Y=yJ6(K),$=await pR7(z);if($)return{worktreePath:z,worktreeBranch:Y,headCommit:$,existed:!0};await M_7(X_7(q),{recursive:!0});let A={...process.env,...zSY},O,w=null;if(_?.prNumber){let{code:X,stderr:P}=await S7(L7(),["fetch","origin",`pull/${_.prNumber}/head`],{cwd:q,stdin:"ignore",env:A});if(X!==0)throw Error(`Failed to fetch PR #${_.prNumber}: ${P.trim()||'PR may not exist or the repository may not have a remote named "origin"'}`);O="FETCH_HEAD"}else{let[X,P]=await Promise.all([dT(),QT(q)]),W=`origin/${X}`,D=P?await Be(P,`refs/remotes/origin/${X}`):null;if(D)O=W,w=D;else{let{code:f}=await S7(L7(),["fetch","origin",X],{cwd:q,stdin:"ignore",env:A});O=f===0?W:"HEAD"}}if(!w){let{stdout:X,code:P}=await S7(L7(),["rev-parse",O],{cwd:q});if(P!==0)throw Error(`Failed to resolve base branch "${O}": git rev-parse failed`);w=X.trim()}let j=N7().worktree?.sparsePaths,H=["worktree","add"];if(j?.length)H.push("--no-checkout");H.push("-B",Y,z,O);let{code:J,stderr:M}=await S7(L7(),H,{cwd:q});if(J!==0)throw Error(`Failed to create worktree: ${M}`);if(j?.length){let X=async(G)=>{throw await S7(L7(),["worktree","remove","--force",z],{cwd:q}),Error(G)},{code:P,stderr:W}=await S7(L7(),["sparse-checkout","set","--cone","--",...j],{cwd:z});if(P!==0)await X(`Failed to configure sparse-checkout: ${W}`);let{code:D,stderr:f}=await S7(L7(),["checkout","HEAD"],{cwd:z});if(D!==0)await X(`Failed to checkout sparse worktree: ${f}`)}return{worktreePath:z,worktreeBranch:Y,headCommit:w,baseBranch:O,existed:!1}}async function mgK(q,K){let _;try{_=await shY(ab(q,".worktreeinclude"),"utf-8")}catch{return[]}let z=_.split(/\r?\n/).map((J)=>J.trim()).filter((J)=>J.length>0&&!J.startsWith("#"));if(z.length===0)return[];let Y=await S7(L7(),["ls-files","--others","--ignored","--exclude-standard","--directory"],{cwd:q});if(Y.code!==0||!Y.stdout.trim())return[];let $=Y.stdout.trim().split(` |
| 7739 | `).filter(Boolean))if(A.ignores(M))w.push(M)}}let H=[];for(let J of w){let M=ab(q,J),X=ab(K,J);try{await M_7(xgK(X),{recursive:!0}),await SgK(M,X),H.push(J)}catch(P){N(`Failed to copy ${J} to worktree: ${P.message}`,{level:"warn"})}}if(H.length>0)N(`Copied ${H.length} files from .worktreeinclude: ${H.join(", ")}`);return H}async function W_7(q,K){let _=N_6("localSettings"),z=ab(q,_);try{let j=ab(K,_);await KSY(xgK(j)),await SgK(z,j),N(`Copied settings.local.json to worktree: ${j}`)}catch(j){if(s1(j)!=="ENOENT")N(`Failed to copy settings.local.json: ${j.message}`,{level:"warn"})}let Y=ab(q,".husky"),$=ab(q,".git","hooks"),A=null;for(let j of[Y,$])try{if((await CgK(j)).isDirectory()){A=j;break}}catch{}if(A){let j=await QT(q),H=j?await ex(j)??j:null;if((H?await J_6(H,"core",null,"hooksPath"):null)!==A){let{code:M,stderr:X}=await S7(L7(),["config","core.hooksPath",A],{cwd:K});if(M===0)N(`Configured worktree to use hooks from main repository: ${A}`);else N(`Failed to configure hooks path: ${X}`,{level:"error"})}}let w=N7().worktree?.symlinkDirectories??[];if(w.length>0)await _SY(q,K,w);await mgK(q,K)}function xQ8(q){let K=q.match(/^https?:\/\/[^/]+\/[^/]+\/[^/]+\/pull\/(\d+)\/?(?:[?#].*)?$/i);if(K?.[1])return parseInt(K[1],10);let _=q.match(/^#(\d+)$/);if(_?.[1])return parseInt(_[1],10);return null}async function D_7(){let{code:q}=await a8("tmux",["-V"]);return q===0}function f_7(){switch(Z1()){case"macos":return"Install tmux with: brew install tmux";case"linux":case"wsl":return"Install tmux with: sudo apt install tmux (Debian/Ubuntu) or sudo dnf install tmux (Fedora/RHEL)";case"windows":return"tmux is not natively available on Windows. Consider using WSL or Cygwin.";default:return"Install tmux using your system package manager."}}async function Z_7(q,K){let{code:_,stderr:z}=await a8("tmux",["new-session","-d","-s",q,"-c",K]);if(_!==0)return{created:!1,error:z};return{created:!0}}async function NR6(q){let{code:K}=await a8("tmux",["kill-session","-t",q]);return K===0}async function b88(q,K,_,z){VR6(K);let Y=Z8();if(NJ6()){let $=await dq8(K);N(`Created hook-based worktree at: ${$.worktreePath}`),TR={originalCwd:Y,worktreePath:$.worktreePath,worktreeName:K,sessionId:q,tmuxSessionName:_,hookBased:!0}}else{let $=hY(Z8());if(!$)throw Error("Cannot create a worktree: not in a git repository and no WorktreeCreate hooks are configured. Configure WorktreeCreate/WorktreeRemove hooks in settings.json to use worktree isolation with other VCS systems.");let A=await oM(),O=Date.now(),{worktreePath:w,worktreeBranch:j,headCommit:H,existed:J}=await P_7($,K,z),M;if(J)N(`Resuming existing worktree at: ${w}`);else N(`Created worktree at: ${w} on branch: ${j}`),await W_7($,w),M=Date.now()-O;TR={originalCwd:Y,worktreePath:w,worktreeName:K,worktreeBranch:j,originalBranch:A,originalHeadCommit:H,sessionId:q,tmuxSessionName:_,creationDurationMs:M,usedSparsePaths:(N7().worktree?.sparsePaths?.length??0)>0}}return jw(($)=>({...$,activeWorktreeSession:TR??void 0})),TR}async function yR6(){if(!TR)return;try{let{worktreePath:q,originalCwd:K,worktreeBranch:_}=TR;process.chdir(K),TR=null,jw((z)=>({...z,activeWorktreeSession:void 0})),N(`Linked worktree preserved at: ${q}${_?` on branch: ${_}`:""}`),N(`You can continue working there by running: cd ${q}`)}catch(q){N(`Error keeping worktree: ${q}`,{level:"error"})}}async function ER6(){if(!TR)return;try{let{worktreePath:q,originalCwd:K,worktreeBranch:_,hookBased:z}=TR;if(process.chdir(K),z)if(await SQ8(q))N(`Removed hook-based worktree at: ${q}`);else N(`No WorktreeRemove hook configured, hook-based worktree left at: ${q}`,{level:"warn"});else{let{code:Y,stderr:$}=await S7(L7(),["worktree","remove","--force",q],{cwd:K});if(Y!==0)N(`Failed to remove linked worktree: ${$}`,{level:"error"});else N(`Removed linked worktree at: ${q}`)}if(TR=null,jw((Y)=>({...Y,activeWorktreeSession:void 0})),!z&&_){await R7(100);let{code:Y,stderr:$}=await S7(L7(),["branch","-D",_],{cwd:K});if(Y!==0)N(`Could not delete worktree branch: ${$}`,{level:"error"});else N(`Deleted worktree branch: ${_}`)}N("Linked worktree cleaned up completely")}catch(q){N(`Error cleaning up worktree: ${q}`,{level:"error"})}}async function c88(q){if(VR6(q),NJ6()){let A=await dq8(q);return N(`Created hook-based agent worktree at: ${A.worktreePath}`),{worktreePath:A.worktreePath,hookBased:!0}}let K=jH(Z8());if(!K)throw Error("Cannot create agent worktree: not in a git repository and no WorktreeCreate hooks are configured. Configure WorktreeCreate/WorktreeRemove hooks in settings.json to use worktree isolation with other VCS systems.");let{worktreePath:_,worktreeBranch:z,headCommit:Y,existed:$}=await P_7(K,q);if(!$)N(`Created agent worktree at: ${_} on branch: ${z}`),await W_7(K,_);else{let A=new Date;await ehY(_,A,A),N(`Resuming existing agent worktree at: ${_}`)}return{worktreePath:_,worktreeBranch:z,headCommit:Y,gitRoot:K}}async function QK6(q,K,_,z){if(z){let w=await SQ8(q);if(w)N(`Removed hook-based agent worktree at: ${q}`);else N(`No WorktreeRemove hook configured, hook-based agent worktree left at: ${q}`,{level:"warn"});return w}if(!_)return N("Cannot remove agent worktree: no git root provided",{level:"error"}),!1;let{code:Y,stderr:$}=await S7(L7(),["worktree","remove","--force",q],{cwd:_});if(Y!==0)return N(`Failed to remove agent worktree: ${$}`,{level:"error"}),!1;if(N(`Removed agent worktree at: ${q}`),!K)return!0;let{code:A,stderr:O}=await S7(L7(),["branch","-D",K],{cwd:_});if(A!==0)N(`Could not delete agent worktree branch: ${O}`,{level:"error"});return!0}async function G_7(q){let K=jH(Z8());if(!K)return 0;let _=X_7(K),z;try{z=await ahY(_)}catch{return 0}let Y=q.getTime(),$=TR?.worktreePath,A=0;for(let O of z){if(!YSY.some((M)=>M.test(O)))continue;let w=ab(_,O);if($===w)continue;let j;try{j=(await CgK(w)).mtimeMs}catch{continue}if(j>=Y)continue;let[H,J]=await Promise.all([S7(L7(),["--no-optional-locks","status","--porcelain","-uno"],{cwd:w}),S7(L7(),["rev-list","--max-count=1","HEAD","--not","--remotes"],{cwd:w})]);if(H.code!==0||H.stdout.trim().length>0)continue;if(J.code!==0||J.stdout.trim().length>0)continue;if(await QK6(w,yJ6(O),K))A++}if(A>0)await S7(L7(),["worktree","prune"],{cwd:K}),N(`cleanupStaleAgentWorktrees: removed ${A} stale worktree(s)`);return A}async function v67(q,K){let{code:_,stdout:z}=await S7(L7(),["status","--porcelain"],{cwd:q});if(_!==0)return!0;if(z.trim().length>0)return!0;let{code:Y,stdout:$}=await S7(L7(),["rev-list","--count",`${K}..HEAD`],{cwd:q});if(Y!==0)return!0;if(parseInt($.trim(),10)>0)return!0;return!1}async function $SY(q){if(process.platform==="win32")return{handled:!1,error:"Error: --tmux is not supported on Windows"};if(Dk("tmux",["-V"],{encoding:"utf-8"}).status!==0)return{handled:!1,error:`Error: tmux is not installed. ${process.platform==="darwin"?"Install tmux with: brew install tmux":"Install tmux with: sudo apt install tmux"}`};let _,z=!1;for(let V=0;V<q.length;V++){let E=q[V];if(!E)continue;if(E==="-w"||E==="--worktree"){let S=q[V+1];if(S&&!S.startsWith("-"))_=S}else if(E.startsWith("--worktree="))_=E.slice(11);else if(E==="--tmux=classic")z=!0}let Y=null;if(_){if(Y=xQ8(_),Y!==null)_=`pr-${Y}`}if(!_){let V=["swift","bright","calm","keen","bold"],E=["fox","owl","elm","oak","ray"],S=V[Math.floor(Math.random()*V.length)],R=E[Math.floor(Math.random()*E.length)],x=Math.random().toString(36).slice(2,6);_=`${S}-${R}-${x}`}try{VR6(_)}catch(V){return{handled:!1,error:`Error: ${V.message}`}}let $,A;if(NJ6()){try{$=(await dq8(_)).worktreePath}catch(V){return{handled:!1,error:`Error: ${d6(V)}`}}A=J_7(jH(Z8())??Z8()),console.log(`Using worktree via hook: ${$}`)}else{let V=jH(Z8());if(!V)return{handled:!1,error:"Error: --worktree requires a git repository"};A=J_7(V),$=ugK(V,_);try{let E=await P_7(V,_,Y!==null?{prNumber:Y}:void 0);if(!E.existed)console.log(`Created worktree: ${$} (based on ${E.baseBranch})`),await W_7(V,$)}catch(E){return{handled:!1,error:`Error: ${d6(E)}`}}}let O=`${A}_${yJ6(_)}`.replace(/[/.]/g,"_"),w=[];for(let V=0;V<q.length;V++){let E=q[V];if(!E)continue;if(E==="--tmux"||E==="--tmux=classic")continue;if(E==="-w"||E==="--worktree"){let S=q[V+1];if(S&&!S.startsWith("-"))V++;continue}if(E.startsWith("--worktree="))continue;w.push(E)}let j="C-b",H=Dk("tmux",["show-options","-g","prefix"],{encoding:"utf-8"});if(H.status===0&&H.stdout){let V=H.stdout.match(/prefix\s+(\S+)/);if(V?.[1])j=V[1]}let M=["C-b","C-c","C-d","C-t","C-o","C-r","C-s","C-g","C-e"].includes(j),X={...process.env,CLAUDE_CODE_TMUX_SESSION:O,CLAUDE_CODE_TMUX_PREFIX:j,CLAUDE_CODE_TMUX_PREFIX_CONFLICTS:M?"1":""},W=Dk("tmux",["has-session","-t",O],{encoding:"utf-8"}).status===0,D=Boolean(process.env.TMUX),f=vQ()&&!z&&!D,G=f?["-CC"]:[];if(f&&!W){let V=$8.yellow;console.log(` |