feat: run agents in isolated git worktrees#2938
Merged
Merged
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
aheritier
reviewed
May 30, 2026
Add a --worktree/-w flag to `docker agent run` that, when the working directory is inside a git repository, creates a fresh git worktree on a dedicated branch and points the session at it. This isolates the agent's changes from the user's checkout. - Generated names use Docker's namesgenerator (e.g. "focused_turing"); an explicit name can be given with --worktree=<name>. - The branch is named worktree-<name> and the worktree is stored under <data-dir>/worktrees/<name>. - Explicit names are validated to prevent path traversal, and duplicate names are rejected with a clear error. - --worktree is mutually exclusive with --remote and --sandbox. - Documents the flag in the CLI reference.
Introduce the worktree_create lifecycle event, fired once just after `docker agent run --worktree` creates a git worktree and before the session starts. Each hook runs inside the new worktree so setup commands (copy .env, install dependencies, warm caches) operate on the fresh checkout. A blocking verdict aborts the run. The input carries worktree_path, worktree_branch, and worktree_source_dir (the repo root branched from) so hooks can copy untracked files git won't carry over. Unlike most events it is dispatched from the CLI rather than the run loop, because the working directory must be settled before the runtime and session exist. The dispatch nil-guards loadResult to match the surrounding cleanup convention. Also fix hookWorkingDir to default to the executor's working directory when a hook has no working_dir override, instead of inheriting the process cwd. This was masked for runtime hooks (the process has already chdir'd) but surfaced via the CLI-dispatched worktree_create event. Includes schema, example, docs, and tests.
When `docker agent run --worktree` created the worktree, clean it up once the interactive session ends: - Clean (no uncommitted changes, untracked files, or new commits): the worktree and its branch are removed automatically. - Has work: prompt to keep or remove, defaulting to keep on any non-yes answer or read error so work is never discarded silently. - Non-interactive (--exec): never cleaned up; left in place for inspection. - Pre-existing worktrees are never touched (Create only makes new ones). - A TUI error leaves the worktree in place rather than risk discarding work after an abnormal exit. Adds Worktree.Status (uncommitted/untracked/new-commit detection via a recorded BaseCommit) and Worktree.Remove, plus tests for the auto-remove, keep-on-decline, and confirm-remove paths. The session is shut down before removal so tools release file handles, and cleanup runs on a non-cancelable context so a Ctrl-C TUI exit doesn't abort the prompt.
Add `docker agent run --worktree-pr <number|url>`, which creates a git worktree checked out on an existing GitHub pull request so the agent can continue it. The PR's head branch is checked out tracking its remote, so commits made during the run push back to the pull request. PR resolution is delegated to the GitHub CLI (gh pr checkout), which handles head-branch lookup, fork remotes, and upstream tracking. The flag accepts a PR number, docker#123, or a pull request URL. - Mutually exclusive with --worktree, --remote, and --sandbox. - Returns clear errors when gh is missing or the ref is malformed. - Reuses the existing worktree_create hook and end-of-session cleanup. The worktree is stored under <data-dir>/worktrees/pr-<number>.
ad775f0 to
67db959
Compare
This comment was marked as low quality.
This comment was marked as low quality.
gtardif
approved these changes
Jun 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds first-class support for running an agent inside a git worktree, so its changes stay isolated from your checkout on a dedicated branch. Built up over four focused commits:
--worktree[=name]/-w— Run in a fresh worktree of the current repo. An explicit name is optional; otherwise a friendly name is generated (Docker-style, e.g.focused_turing). Stored at<data-dir>/worktrees/<name>on aworktree-<name>branch. Validated against path traversal; mutually exclusive with--remoteand--sandbox.worktree_createhook — A new lifecycle event fired just after the worktree is created and before the session starts. Hooks run inside the new worktree, receivingworktree_path,worktree_branch, andworktree_source_dir, so they can prepare the checkout (copy.env, install deps, warm caches). A blocking verdict aborts the run.Cleanup on exit — When the interactive session ends:
--exec→ never cleaned up; left for inspection.--worktree-pr <number|url>— Check out an existing GitHub pull request to continue it. The PR's head branch is checked out tracking its remote (viagh pr checkout), so commits push back to the PR. Handles fork remotes and upstream tracking. Requires the GitHub CLI.Notes
namesgenerator(Apache-2.0) verbatim to avoid pulling in the full engine module.--worktree-prrequiresghto be installed and authenticated; missing/malformed inputs produce clear errors.Testing
worktree_createhook covered end-to-end; fixedhookWorkingDirto default to the executor's working dir (surfaced by the CLI-dispatched event).task build/ tests /golangci-lint/ custom lint cops all pass.