UNPKG

@sema-agent/core

Version:

Stateless, task-oriented AI agent core

52 lines (51 loc) • 3.26 kB
import type { ExecutionEnv } from "../internal/harness-types.js"; /** Private parent dir (under the repo root) that holds all managed worktrees, so {@link pruneWorktrees} and a * userland reaper can find orphans by a single known location. */ export declare const WORKTREE_PARENT = ".sema-worktrees"; export interface AddWorktreeOptions { /** The base repository root — where `git worktree add` runs (the base env's cwd is typically this). */ repoRoot: string; /** Stable per-task identity, sanitized into the worktree dir name (for human-readable orphan diagnosis). */ sessionId: string; /** * How to build a worktree-ROOTED {@link ExecutionEnv} for THIS env type — the only env-specific bit. Local: * `(dir) => new NodeExecutionEnv({ cwd: dir })`. A single-E2B deployment: an E2B env whose cwd is `dir`. The * returned env's fs/shell must operate relative to `dir`, so the agent's hands AND exec are confined there. */ rootEnvAt: (worktreeDir: string) => ExecutionEnv | Promise<ExecutionEnv>; /** Base commit/ref for the worktree (default `HEAD` at creation time). */ commit?: string; } /** * design/97 CORE-6 — the env-agnostic git-WORKTREE isolation primitive. Creates a detached worktree under * {@link WORKTREE_PARENT} in `repoRoot` (via the BASE env's shell) and returns a worktree-ROOTED ExecutionEnv * (built by `rootEnvAt`) whose `destroy()` removes the worktree. A control-plane `executionEnvFactory` calls this * when its `ctx.isolation === "worktree"` and returns the result (with `destroy`); for a non-isolated task it * returns the SHARED base env (no `destroy`) so the Runner never tears the base down. * * ISOLATE-ONLY: the runtime never merges — the orchestrator script reads each worktree's result and * decides verify/merge in userland. Caveats: `git worktree` isolates the git WORKING COPY, not * arbitrary shell access (bash can still reach the host — sandbox separately); UNCOMMITTED changes in the base * repo are absent in the child (detached HEAD); a worktree orphaned by a process crash is reaped by * {@link pruneWorktrees} (userland — there is no Runner hook for post-kill cleanup). */ export declare function addWorktree(baseEnv: ExecutionEnv, opts: AddWorktreeOptions): Promise<{ env: ExecutionEnv & { destroy(): Promise<void>; }; worktreeDir: string; }>; /** Reap orphaned worktrees (after a crash removed their dirs) — `git worktree prune` deregisters them. A userland * reaper calls this periodically against the base repo; core ships no post-kill Runner hook. * * HRD-PTL-11: the exec Result used to be discarded, so every caller had to ASSUME the prune landed — and * ExitWorktree's "already gone externally" leg told the model "stale git worktree metadata was pruned" * on a claim it could not have checked. Same fail-loud treatment {@link removeWorktree} already got * Report the outcome, let the caller decide what to say. Never throws (a throwing env * lands on the same `{ok:false}`), so a caller that ignores the value behaves exactly as before. */ export declare function pruneWorktrees(baseEnv: ExecutionEnv, repoRoot: string): Promise<{ ok: true; } | { ok: false; detail: string; }>;