/** * GitWorktreeDriver โ€” reference implementation of * {@link WorkspaceBackendDriver} backed by `git worktree`. * * See session-hierarchy.md ยง7.2 (Git-worktree reference backend). * * Safety: every subprocess invocation uses `execFile` with an argv array and * separates caller-controlled positional arguments from Git options with * `--`. Filesystem paths are canonicalized and confined to the configured * worktree root before Git receives them. Failures surface as * {@link WorkspaceBackendError} carrying the underlying cause. */ import type { WorkspaceRef } from '../../types/workspace/ref.js'; import type { Logger } from '../../utils/logger.js'; import type { BranchWorkspaceParams, CreateWorkspaceParams, WorkspaceBackendDriver, WorkspaceInspection } from './driver.js'; /** * Minimal shape of `execFile`'s promisified result โ€” allows tests to stub * via dependency injection without pulling in the full `ChildProcess` type. */ export interface ExecFileResult { stdout: string; stderr: string; } /** * Async exec callable used by {@link GitWorktreeDriver}. Matches the shape * of `promisify(execFile)` for the argv-array overload. Injected via the * constructor so tests can stub without touching `child_process`. */ export type ExecFile = (file: string, args: readonly string[]) => Promise; /** * Configuration for {@link GitWorktreeDriver}. */ export interface GitWorktreeDriverConfig { /** Absolute path to the repo root whose `.git` backs the worktrees. */ repoRoot: string; /** * Directory (absolute) where worktree checkouts live. Defaults to * `/projects//worktrees/` for the repo root's project: * namzu never writes under the working directory. */ worktreesDir?: string; logger: Logger; /** Test-seam: inject a stub `execFile` implementation. */ execFile?: ExecFile; } export declare class GitWorktreeDriver implements WorkspaceBackendDriver { readonly kind: "git-worktree"; private readonly repoRoot; private readonly worktreesDir; private readonly log; private readonly exec; constructor(config: GitWorktreeDriverConfig); create(params: CreateWorkspaceParams): Promise; branch(source: WorkspaceRef, params: BranchWorkspaceParams): Promise; dispose(ref: WorkspaceRef): Promise; /** * Did the worktree arrive despite the command reporting failure? * * Answers only for the branch this call created. A path registered * without that branch is not this call's worktree โ€” it is a leftover * from a killed attempt, or a checkout somebody else owns, and the two * are indistinguishable from here. Claiming either would mean handing * a caller a workspace whose contents nobody vouched for, so both are * left to surface as the failure they are. * * Any error while checking is itself a "no". This runs on a path that * has already gone wrong once, and guessing optimistically there is how * a recovery turns a bad situation into a wrong one. */ private createdDespite; inspect(ref: WorkspaceRef): Promise; /** * Turn persisted metadata back into an owned driver capability. * * A WorkspaceRef is recovery data, not authority to make this driver act on * any worktree registered in the same repository. Existing links are * resolved before the boundary is decided, and every Git call receives the * canonical path that was checked. This closes static symlink escapes. It * does not claim protection from a host process concurrently swapping path * components or mount points; the Git CLI exposes no descriptor-relative * removal primitive with which to make that guarantee. */ private requireOwnedRef; private registeredEntry; } /** * Parses `git worktree list --porcelain` output, returning the record for * `worktreePath` or `null` when absent. Exported for tests. */ export declare function parseWorktreeList(stdout: string, worktreePath: string): { path: string; head?: string; branch?: string; } | null; /** * `/projects//worktrees/` for a repository: the project's * slug, or its hashed form when `project.json` under the plain slug belongs * to a different directory (the rule `ensureProject` applies). */ export declare function defaultWorktreesDir(repoRoot: string): string; //# sourceMappingURL=git-worktree.d.ts.map