Git-worktree isolation for subagents.
When a subagent's isolation: :worktree is set, the parent's cwd
is checked: must be inside a git repo, must have git on PATH,
and (by default) must have a clean working tree. If any safety
check fails, the caller falls back to :in_process cleanly.
Worktrees are created under ~/.cache/ex_athena/worktrees/<sess>/<name>-<n>,
branched off HEAD. After the subagent finishes:
- If it left changes in the worktree, the path + branch are surfaced in the spawn result so the caller can review/merge.
- If the worktree is clean, it's removed via
git worktree remove --force.
The WorktreeSweeper GenServer (see
ExAthena.Agents.WorktreeSweeper) GCs orphaned worktrees on
application start.
This module deliberately uses System.cmd/3 directly (not
Tools.Bash) so worktree creation/teardown bypasses the parent's
permission gate — otherwise a parent in :plan mode could never
spawn a worktree-isolated subagent.
Summary
Functions
Decide what to do with a worktree after the subagent finishes.
Decide isolation strategy for def against the parent's cwd.
Functions
Decide what to do with a worktree after the subagent finishes.
Returns {:kept, info} if the worktree had changes (caller is
expected to surface the path + branch), or {:removed, info}
when cleanup succeeded. Failure to remove is logged but
non-fatal; the sweeper will catch it later.
@spec resolve(ExAthena.Agents.Definition.t(), String.t(), String.t()) :: {:worktree, map()} | {:in_process, atom()}
Decide isolation strategy for def against the parent's cwd.
Returns one of:
{:worktree, %{path: ..., branch: ...}}— created and ready.{:in_process, reason}— fell back; reason is a short atom explaining why (:no_git,:not_a_repo,:dirty_tree,:create_failed).{:in_process, :requested}— the def explicitly asks for in-process; no checks were attempted.