// @generated — DO NOT EDIT. Source: packages/shared/worktree-pool.ts /** * Worktree Pool — manages a set of per-PR git worktrees for a review session. * * Runtime-agnostic. Uses ReviewGitRuntime for all git operations. * Both Bun and Pi servers import this module (Pi via vendor.sh). * * Each PR visited during a session gets its own worktree, created on first * access and cached for the session lifetime. Agents run in their PR's * worktree undisturbed by PR switches. */ import { join } from "node:path"; import type { ReviewGitRuntime } from "./review-core"; import type { PRMetadata } from "./pr-provider"; import { createWorktree, removeWorktree, fetchRef, ensureObjectAvailable } from "./worktree"; export interface PoolEntry { path: string; prUrl: string; number: number; ready: boolean; } export interface WorktreePoolConfig { sessionDir: string; repoDir: string; isSameRepo: boolean; } export interface WorktreePool { get(prUrl: string): PoolEntry | undefined; has(prUrl: string): boolean; resolve(prUrl: string): string | undefined; ensure(runtime: ReviewGitRuntime, metadata: PRMetadata): Promise; entries(): IterableIterator; cleanup(runtime: ReviewGitRuntime): Promise; } export function createWorktreePool(config: WorktreePoolConfig, initial?: PoolEntry): WorktreePool { const pool = new Map(); const pending = new Map>(); if (initial) pool.set(initial.prUrl, initial); return { get(prUrl) { return pool.get(prUrl); }, has(prUrl) { return pool.has(prUrl); }, resolve(prUrl) { const entry = pool.get(prUrl); return entry?.ready ? entry.path : undefined; }, async ensure(runtime, metadata) { const existing = pool.get(metadata.url); if (existing?.ready) return existing; const inflight = pending.get(metadata.url); if (inflight) return inflight; if (!config.isSameRepo) { throw new Error("Cross-repo pool cannot create worktrees for other PRs"); } const promise = (async (): Promise => { const number = metadata.platform === "github" ? metadata.number : metadata.iid; const worktreePath = join(config.sessionDir, "pool", `pr-${number}`); const refSpec = metadata.platform === "github" ? `refs/pull/${number}/head` : `refs/merge-requests/${number}/head`; await fetchRef(runtime, metadata.baseBranch, { cwd: config.repoDir }); await ensureObjectAvailable(runtime, metadata.baseSha, { cwd: config.repoDir }); await fetchRef(runtime, refSpec, { cwd: config.repoDir }); await createWorktree(runtime, { ref: "FETCH_HEAD", path: worktreePath, detach: true, cwd: config.repoDir, }); const entry: PoolEntry = { path: worktreePath, prUrl: metadata.url, number, ready: true }; pool.set(metadata.url, entry); return entry; })(); pending.set(metadata.url, promise); try { return await promise; } finally { pending.delete(metadata.url); } }, entries() { return pool.values(); }, async cleanup(runtime) { for (const entry of pool.values()) { await removeWorktree(runtime, entry.path, { force: true, cwd: config.repoDir }); } pool.clear(); }, }; }