/**
 * 审计深挖 G4 — the `EnterWorktree` / `ExitWorktree` tool pair: SESSION-level git-worktree
 * isolation (CC 2.1.198 parity). EnterWorktree creates a managed worktree under `.sema-worktrees/`
 * (the same {@link WORKTREE_PARENT} the subagent `isolation:"worktree"` lane uses) and REALLY switches
 * the task's working directory into it; ExitWorktree returns to the original directory and cleans up.
 *
 * CC-parity semantics (198 bundle, verbatim-checked):
 *  ① worktrees live in a managed parent dir inside the repo (CC: `.claude/worktrees/`; sema:
 *    `.sema-worktrees/`) — never scattered;
 *  ② baseRef is two-state: `"head"` = the current local HEAD (unpushed commits present), `"fresh"` =
 *    the default branch tip (CC: `origin/<default-branch>` for a clean tree);
 *  ③ a second CREATING EnterWorktree (`name`) while one is active is REFUSED ("Already in a worktree
 *    session" — CC errorCode 2); switching into an EXISTING worktree via `path` is allowed (深对比残差
 *    M22 RESOLVED, live-CC anchor 2026-07-09: the previous worktree is left on disk untouched, only the
 *    new one is tracked for exit-time cleanup, and a path-entered tree is NEVER removed by ExitWorktree);
 *  ④ ExitWorktree outside a session is an honest NO-OP (CC errorCode 1), and a worktree with
 *    uncommitted files or commits is NOT deleted by default (CC refuses `remove` without
 *    `discard_changes`; sema keeps it and reports the path — inspect/merge in userland);
 *  ⑤ outside a git repository CC delegates to WorktreeCreate/WorktreeRemove hooks — sema has no such
 *    shell extension point, so the tool says so honestly and refuses (no silent degrade).
 *
 * cwd architecture (the load-bearing conclusion): the task's working directory IS mutable state — the
 * hands band shares one {@link CwdRef} (`handsCwdRef` in prepare-task): Bash runs every command in
 * `cwdRef.current` (and `cd` moves it), Read/Edit/Write resolve relative paths against it, Monitor
 * spawns there. EnterWorktree therefore performs a REAL switch by assigning `cwdRef.current`; the
 * Runner's per-tool cwd read reports it as `workspace_changed`, same as an observed `cd`. Path
 * containment is untouched: the worktree lives UNDER the task root, so resolveKey's canonical-within
 * check still holds for every subsequent fs op.
 *
 * ⚠️ Containment ruling (deliberate): entering a worktree is a **cwd switch, NOT a
 * sandbox**. resolveKey's containment anchor stays the ORIGINAL task root — it is deliberately NOT
 * re-anchored/tightened to the worktree dir, so `../../` from inside the worktree can still reach the
 * rest of the repository (which is WITHIN the task root and was reachable before Enter too), while
 * anything outside the task root stays fenced exactly as before. This matches CC 2.1.198 semantics
 * (CC worktrees live beside the repo with no containment tightening either); tightening here would buy
 * no security (Bash/`cd` already roam the root) and would break legitimate repo-relative access. The
 * tool description + Enter reply state this honestly so the model never assumes isolation.
 *
 * Security posture: both tools only ever run `git` against the task root / managed worktree (no
 * arbitrary command surface), but they create/delete on-disk state ⇒ effect:"write" (plan mode gates
 * them like every other write tool; read-only hands never mount them — see prepare-task).
 *
 * Durability: the active session lives in a SHARED, ALL-SERIALIZABLE
 * {@link WorktreeSessionRef} owned by prepare-task (never a closure-only var, and no captured destroy
 * closure — Exit re-derives removal as a plain `git worktree remove`). A durable suspend stamps it into
 * `CheckpointState.activeWorktree` (+ the cwd into `handsCwd`); resume re-seeds both, so
 * Enter→suspend→resume→Exit behaves exactly like an unsuspended session.
 */
import type { ActiveWorktreeSession, AgentTool, ExecutionEnv } from "../internal/harness-types.js";
import type { CwdRef } from "./fs/index.js";
/** the ACTIVE worktree session, ALL-SERIALIZABLE (plain strings, no closures):
 *  prepare-task owns the ref, stamps `current` into `CheckpointState.activeWorktree` at a durable
 *  suspend, and re-seeds it on resume, so ExitWorktree works across the suspend/resume boundary (the
 *  tree survives on disk; removal is re-derived as a plain `git worktree remove`).
 *
 *  REF-D3/D4: canonical definition moved to `engine/harness/types.ts` (the harness layer must never
 *  import FROM `tools/`, so it cannot point back at a definition declared here); this re-export keeps
 *  the existing `ActiveWorktreeSession` import path (including the public one via `src/index.ts`)
 *  unchanged for every consumer. */
export type { ActiveWorktreeSession };
/** The shared mutable holder for {@link ActiveWorktreeSession} — the worktree twin of {@link CwdRef}. */
export interface WorktreeSessionRef {
    current?: ActiveWorktreeSession;
    /** HRD-PTL-8 — an ExitWorktree call is in flight on `current`. RUNTIME-ONLY (deliberately not part of
     *  the durable `CheckpointState.activeWorktree` projection: a suspend cannot happen inside the exit's
     *  own await chain, and a resumed process has no in-flight exit by definition). A concurrent or
     *  re-entrant Exit reads this and is refused honestly instead of being told no session is active. */
    exiting?: boolean;
    /** HRD-PTL-13 — an EnterWorktree call is in flight on this ref (either form). RUNTIME-ONLY, same
     *  rationale as {@link exiting}. The single-session rule cannot be enforced by reading `current` alone:
     *  the create path assigns it only after several awaits, so two overlapping calls would both pass that
     *  check and both create a worktree, leaving the earlier one untracked (see the guard in EnterWorktree
     *  for the CAS-reject-vs-serialize trade-off). */
    entering?: boolean;
}
export interface WorktreeToolsOptions {
    /** The task root (the repo root the managed worktrees nest under; `git` runs `-C` here). */
    repoRoot: string;
    /** The task's shared mutable working directory (the hands band's `handsCwdRef`) — EnterWorktree
     *  assigns it to the worktree path (a REAL cwd switch: Bash/Read/Edit/Write/Monitor all follow),
     *  ExitWorktree restores it. */
    cwdRef: CwdRef;
    /** the shared session-state ref (checkpointable — prepare-task serializes it into
     *  the durable checkpoint and re-seeds it on resume). Omitted ⇒ a private per-mount ref (same live
     *  behavior, minus durable-suspend survival — prepare-task always passes one). */
    session?: WorktreeSessionRef;
}
/**
 * Build the EnterWorktree/ExitWorktree pair. One session-state closure per mount (= per task): the
 * active worktree handle lives here, never in a model argument. Mounted by prepare-task only when the
 * task has real write hands over a tracked cwd (`handsCwdRef` exists — same premise family as the
 * Monitor mount); git-ness is probed honestly at Enter time (same posture as the subagent
 * worktree-isolation helper — no per-task prepare-time git exec).
 */
export declare function createWorktreeTools(env: ExecutionEnv, opts: WorktreeToolsOptions): AgentTool[];
