()
| 823 | } |
| 824 | |
| 825 | export async function cleanupWorktree(): Promise<void> { |
| 826 | if (!currentWorktreeSession) { |
| 827 | return |
| 828 | } |
| 829 | |
| 830 | try { |
| 831 | const { worktreePath, originalCwd, worktreeBranch, hookBased } = |
| 832 | currentWorktreeSession |
| 833 | |
| 834 | // Change back to original directory first |
| 835 | process.chdir(originalCwd) |
| 836 | |
| 837 | if (hookBased) { |
| 838 | // Hook-based worktree: delegate cleanup to WorktreeRemove hook |
| 839 | const hookRan = await executeWorktreeRemoveHook(worktreePath) |
| 840 | if (hookRan) { |
| 841 | logForDebugging(`Removed hook-based worktree at: ${worktreePath}`) |
| 842 | } else { |
| 843 | logForDebugging( |
| 844 | `No WorktreeRemove hook configured, hook-based worktree left at: ${worktreePath}`, |
| 845 | { level: 'warn' }, |
| 846 | ) |
| 847 | } |
| 848 | } else { |
| 849 | // Git-based worktree: use git worktree remove. |
| 850 | // Explicit cwd: process.chdir above does NOT update getCwd() (the state |
| 851 | // CWD that execFileNoThrow defaults to). If the model cd'd to a non-repo |
| 852 | // dir, the bare execFileNoThrow variant would fail silently here. |
| 853 | const { code: removeCode, stderr: removeError } = |
| 854 | await execFileNoThrowWithCwd( |
| 855 | gitExe(), |
| 856 | ['worktree', 'remove', '--force', worktreePath], |
| 857 | { cwd: originalCwd }, |
| 858 | ) |
| 859 | |
| 860 | if (removeCode !== 0) { |
| 861 | logForDebugging(`Failed to remove linked worktree: ${removeError}`, { |
| 862 | level: 'error', |
| 863 | }) |
| 864 | } else { |
| 865 | logForDebugging(`Removed linked worktree at: ${worktreePath}`) |
| 866 | } |
| 867 | } |
| 868 | |
| 869 | // Clear the session |
| 870 | currentWorktreeSession = null |
| 871 | |
| 872 | // Update config |
| 873 | saveCurrentProjectConfig(current => ({ |
| 874 | ...current, |
| 875 | activeWorktreeSession: undefined, |
| 876 | })) |
| 877 | |
| 878 | // Delete the temporary worktree branch (git-based only) |
| 879 | if (!hookBased && worktreeBranch) { |
| 880 | // Wait a bit to ensure git has released all locks |
| 881 | await sleep(100) |
| 882 |
no test coverage detected