Files
fusion/packages/engine/src/worktree-paths.ts
Fusion (runfusion.ai) 0f372f67c3 feat(FN-4623): complete Step 3 — add backend-aware path resolution
Fusion-Task-Id: FN-4623
Fusion-Task-Lineage: 58122853-cab7-4102-9649-4ceda4c5959e
2026-05-15 19:37:48 -07:00

56 lines
1.9 KiB
TypeScript

import { homedir } from "node:os";
import { basename, isAbsolute, join, relative, resolve } from "node:path";
import type { Settings } from "@fusion/core";
import type { WorktreeBackendKind } from "./worktree-backend.js";
import { canonicalizePath } from "./worktree-pool.js";
export function resolveWorktreesDir(
rootDir: string,
settings: Pick<Settings, "worktreesDir"> | undefined,
): string {
const configured = settings?.worktreesDir;
if (!configured) {
return join(rootDir, ".worktrees");
}
const expandedHome = configured.replace(/^~(?=$|[\\/])/, homedir());
const expandedRepo = expandedHome.replaceAll("{repo}", basename(rootDir));
return resolve(rootDir, expandedRepo);
}
export function resolveTaskWorktreePath(
rootDir: string,
settings: Pick<Settings, "worktreesDir"> | undefined,
worktreeName: string,
): string {
return join(resolveWorktreesDir(rootDir, settings), worktreeName);
}
// Structural backend input avoids importing the full WorktreeBackend interface here.
export async function resolveTaskWorktreePathForBackend(
rootDir: string,
worktreeName: string,
settings: Pick<Settings, "worktreesDir"> | undefined,
backend: {
kind: WorktreeBackendKind;
resolveWorktreePath?: (input: { rootDir: string; worktreeName: string; branch: string }) => Promise<string>;
},
branch: string,
): Promise<string> {
if (backend.kind === "worktrunk" && backend.resolveWorktreePath) {
return backend.resolveWorktreePath({ rootDir, worktreeName, branch });
}
return resolveTaskWorktreePath(rootDir, settings, worktreeName);
}
export function isInsideConfiguredWorktreesDir(
rootDir: string,
settings: Pick<Settings, "worktreesDir"> | undefined,
candidate: string,
): boolean {
const worktreesDir = canonicalizePath(resolveWorktreesDir(rootDir, settings));
const target = canonicalizePath(candidate);
const rel = relative(worktreesDir, target);
return rel !== "" && !rel.startsWith("..") && !isAbsolute(rel);
}