Skip to content
Source
Sign inSign up

worktreeCleanup.ts

42 lines1.3 KB

1import { normalizeProjectPathForComparison } from "@t3tools/shared/path";
2​
3import type { ThreadShell } from "./types";
4​
5export function getOrphanedWorktreePathForThread(
6 threads: ReadonlyArray<Pick<ThreadShell, "id" | "worktreePath">>,
7 threadId: ThreadShell["id"],
8): string | null {
9 const targetThread = threads.find((thread) => thread.id === threadId);
10 if (!targetThread) {
11 return null;
12 }
13​
14 const targetWorktreePath = targetThread.worktreePath?.trim();
15 if (!targetWorktreePath) {
16 return null;
17 }
18​
19 // Threads can store one worktree as `/repo/wt` and `/repo/wt/`, and
20 // confirming deletion force-removes the checkout for every thread on it.
21 const targetKey = normalizeProjectPathForComparison(targetWorktreePath);
22 const isShared = threads.some(
23 (thread) =>
24 thread.id !== threadId &&
25 thread.worktreePath !== null &&
26 normalizeProjectPathForComparison(thread.worktreePath) === targetKey,
27 );
28​
29 return isShared ? null : targetWorktreePath;
31​
32export function formatWorktreePathForDisplay(worktreePath: string): string {
33 const trimmed = worktreePath.trim();
34 if (!trimmed) {
35 return worktreePath;
36 }
37​
38 const normalized = trimmed.replace(/\\/g, "/").replace(/\/+$/, "");
39 const parts = normalized.split("/");
40 const lastPart = parts[parts.length - 1]?.trim() ?? "";
41 return lastPart.length > 0 ? lastPart : trimmed;