/** * WorktreeManager — git worktree lifecycle management for subagent isolation. * * Each subagent can optionally run in its own git worktree at * /.worktrees//, sharing the repository's * .git object store but with its own working directory and branch. * * All git operations use `child_process.execFileSync` with argv arrays * to prevent shell injection. The worktree path convention is enforced * here: all paths live under `/.worktrees/`. * * Lifecycle: * 1. create() — add a worktree (new or existing branch) * 2. remove() — remove a worktree + optional branch deletion * 3. list() — discover all worktrees in the repo * 4. findByBranch() — locate a worktree by branch name * * Branch name resolution (resolveBranchName, sanitizeForBranchName) is * pure and exported for testing — the manager itself only deals with * paths and git CLI invocation. */ /** Information about a single git worktree (parsed from `git worktree list`). */ export interface WorktreeInfo { /** Absolute path to the worktree working directory. */ path: string; /** Branch checked out in the worktree, or null if detached. */ branch: string | null; /** The commit checked out (HEAD). */ commit: string; /** True if this is the main worktree (the one containing .git/..). */ isMain: boolean; /** True if the worktree is in a "locked" state (per git worktree list). */ isLocked: boolean; /** True if the worktree is in a "prunable" state. */ isPrunable: boolean; } /** Result of attempting to create a worktree. */ export interface WorktreeCreateResult { /** Information about the newly-created or reused worktree. */ worktree: WorktreeInfo; /** True if a new branch was created; false if branch already existed. */ createdNewBranch: boolean; /** The branch name used. */ branch: string; /** Absolute path to the worktree. */ path: string; } /** Options for create(). */ export interface WorktreeCreateOptions { /** Branch name to use (required). */ branch: string; /** Base ref to fork from. Defaults to "HEAD". */ baseRef?: string; /** Whether this is an auto-generated branch (vs. user-supplied). */ ephemeral: boolean; /** Force creation even if branch is checked out elsewhere (rarely used). */ force?: boolean; } /** Default location for worktrees, relative to repo root. */ export declare const WORKTREE_DIR = ".worktrees"; /** * Sanitize a free-form string (e.g. task description) into a valid git * branch name. Lowercase, hyphens for spaces, strips invalid characters. * Does NOT guarantee uniqueness — caller must append a suffix. */ export declare function sanitizeForBranchName(input: string): string; /** * Sanitize a branch name for use as a directory name under .worktrees/. * Forward slashes in branch names (e.g. "feat/auth") become dashes so * the path remains a single segment. */ export declare function sanitizeForDirName(branch: string): string; /** * Resolve a branch name from subagent parameters. * * Precedence: * 1. Explicit `worktreeBranch` (non-empty, trimmed — used as-is) * 2. Description + 6-char FNV-1a hash suffix from agentId * 3. Fallback: "agent-" * * Empty or whitespace-only `worktreeBranch` is treated as unset, * falling through to auto-generation. This prevents creating a * worktree with an invalid empty branch name. */ export declare function resolveBranchName(params: { worktreeBranch?: string; description?: string; agentId: string; }): string; /** * Compute the worktree directory path for a given branch. */ export declare function worktreePathFor(repoRoot: string, branch: string): string; /** * Resolve the absolute path to the root of the git repository containing `cwd`. * Throws a descriptive error if `cwd` is not inside a git repo. */ export declare function resolveRepoRoot(cwd: string): string; /** * Ensure that .worktrees/ is listed in the repo's .gitignore. * Idempotent — does not duplicate entries. */ export declare function ensureWorktreeGitignore(repoRoot: string): void; /** * Validate a branch name for common git-rejected patterns. * Throws a descriptive error if the name is invalid; returns silently otherwise. */ export declare function validateBranchName(branch: string): void; /** * Reconcile worktrees after a parent crash or session restart. * * Lists all non-main worktrees and removes those whose branch is not * in the supplied `activeBranches` set. If `activeBranches` is empty * or undefined the function logs what it finds and returns 0 (safe * default — never blindly prune everything). * * F13 fix: orphaned worktrees are now detected and cleaned up on * session_start, preventing unbounded disk usage from crashed parents. */ export declare function reconcileWorktrees(manager: WorktreeManager, activeBranches?: Set, logger?: (msg: string) => void): number; export declare class WorktreeManager { private readonly repoRoot; constructor(repoRoot: string); /** The absolute repo root this manager operates on. */ get root(): string; /** * Create a worktree for the given branch, or reuse the existing one. * * Behavior: * - If the worktree directory exists for this branch → reuse it * - If the branch exists but is not checked out elsewhere → check it out * - If the branch does not exist → create it from baseRef (default HEAD) * - On any failure, throws a descriptive Error */ create(options: WorktreeCreateOptions): WorktreeCreateResult; /** * Remove a worktree. If `deleteBranch` is true, also delete the branch * (only when fully merged — uses `git branch -d`, not `-D`). * * Does NOT throw if the worktree does not exist (idempotent). */ remove(branch: string, deleteBranch: boolean, force?: boolean): { removed: boolean; branchDeleted: boolean; }; /** * List all worktrees in the repository (excluding the main worktree's * own working directory unless includeMain is true). */ list(includeMain?: boolean): WorktreeInfo[]; /** * Find a worktree by its checked-out branch name. * Returns null if no worktree has that branch checked out. */ findByBranch(branch: string): WorktreeInfo | null; /** * Check if a local branch exists in the repo. */ branchExists(branch: string): boolean; private worktreeListPorcelain; private worktreeListPorcelainRaw; /** * Parse the full porcelain output into a list of WorktreeInfo. */ private parsePorcelain; private parseBlock; /** * Lightweight parser used by create() to extract just the new worktree * info by branch name. Falls back to findByBranch behavior. */ private parseInfoLine; } //# sourceMappingURL=worktree-manager.d.ts.map