@autosk/worktree
v0.1.3
Published
Shipped autoskd v2 isolation provider: per-task git worktree isolation (worktreeIsolation()) attachable to any workflow.
Readme
@autosk/worktree
The shipped isolation provider for autoskd v2: per-task git worktree
isolation, attachable to any workflow. It ports v1's worktree behaviour onto
the v2 IsolationProvider contract (design
docs/plans/20260612-Bun-Daemon-Extensions.md §3.5).
Usage
import { statusStep } from "@autosk/sdk";
import { piAgent } from "@autosk/pi-agent";
import { worktreeIsolation } from "@autosk/worktree";
autosk.registerWorkflow({
name: "feature-dev",
firstStep: "dev",
// Agents are inline step values (the step key is the agent name).
steps: { dev: piAgent({ firstMessageFile: ".../dev.md" }), accept: statusStep("human") },
isolation: worktreeIsolation(),
});Each isolated task runs in its own checkout so concurrent tasks never collide on
the working tree. The engine calls acquire before scheduling each session (its
returned cwd becomes ctx.cwd) and reap only on a terminal transition
(done/cancel). This provider has no live env to stop, so it omits
release entirely — keeping the checkout on disk across sibling/human-park steps
is exactly the absence of teardown.
Behaviour
Deterministic mapping — byte-identical to v1, so a worktree allocated by either stack resolves to the same place:
~/.autosk/worktrees/<basename(canonRoot)>-<8hex(sha256(canonRoot))>/<task-id>
branch = autosk/<task-id>- acquire (ensure-ready) — allocates the per-task worktree on branch
autosk/<task-id>(offHEAD), or re-uses it when a prior step kept it. A missing dir is re-allocated on the existing branch (v1 "missing worktree auto-recovery"). Idempotent and re-entered per step. Returns{ cwd, meta: { branch, projectRoot } }. - (no
release) — sibling step and human-park keep the dir on disk untouched, so the nextacquirere-uses the same checkout. There is nothing to quiesce, so the method is omitted. - reap (destroy-on-terminal, done / cancel) — keyed by
(projectRoot, taskId), so it works with no live handle (engine terminal, a manualdone/cancelafter a park, or crash recovery). Removes the worktree dir but preserves theautosk/<task-id>branch (so the work survives for review / merge). Withforce:falseit refuses to discard uncommitted changes and reports{ removed:false, dirty:true };force:trueremoves regardless.
Failure handling
The provider only throws descriptive messages — the engine wraps them
(isolation_acquire_failed: … on acquire, isolation_reap_failed: … on a
terminal reap) and parks the task to human. It never parks or formats those
prefixes itself. Throw cases:
- non-git root —
not a git repository: <root>(the project root isn't a git repo). - stranded dir —
worktree_stranded: …(a directory sits at the worktree path whose gitdir doesn't resolve to the project's — e.g. a foreign repo). - git missing —
git binary not found on PATH.
Configuration
worktreeIsolation(options?):
| Option | Default | Description |
| -------- | ------------------ | --------------------------------------------------------------------------- |
| home | process.env.HOME | Home dir the worktree tree lives under (<home>/.autosk/worktrees/…). Tests inject a temp home. |
| gitBin | "git" | git binary to shell out to. |
Exports
worktreeIsolation(options?)→IsolationProviderbranchFor(taskId),pathFor(projectRoot, taskId, home?),slugFor(canon)— the deterministic derivation helpers (exported for tooling / tests).WORKTREE_TAG— the provider tag ("worktree") rendered byworkflow.get.
