Workspace Isolation

Give each agent its own git worktree so concurrent edits never clobber each other

Workspace isolation gives every agent its own working directory on its own branch, so agents editing the same repository never overwrite each other’s changes.

Using it from the CLI

You don’t need to touch the adapter API โ€” the praisonai run command has a built-in --worktree flag that wires the adapter into your normal run.

bash
praisonai run "Rework the retry loop" --worktree

The agent runs on a fresh branch; your working tree stays clean. Any output is auto-committed to the branch for review, or the branch is pruned if nothing changed.

Isolated Runs (CLI)

praisonai run --worktree / --keep โ€” per-run isolation from the terminal.


Diagram

Workspace Isolation

๐Ÿ“ Repository

๐Ÿค– Alice Worktree

๐Ÿค– Bob Worktree

โœ… Merge Back

From the CLI

Run any agent on a fresh, disposable branch โ€” no code required.

bash
# Run any agent on a fresh, disposable branch
praisonai run "refactor auth" --worktree

# Keep the branch checkout in place for review
praisonai run "refactor auth" --worktree --keep

The agent edits inside an isolated praisonai/<task>-<hash> worktree; on teardown its changes are auto-committed to that branch for review, or the worktree is kept in place with --keep. See praisonai run --worktree for the full behaviour.

Quick Start

  1. Isolate a run from the CLI

    Add --worktree to any run invocation โ€” the agent works on a fresh branch instead of your working tree.

    bash
    praisonai run "refactor auth to use bcrypt" --worktree
    # > Isolated run on branch 'praisonai/refactor-auth-<uid>' (./.praisonai/worktrees/refactor-auth-<uid>)
    # ... agent runs ...
    # > Committed changes to branch 'praisonai/refactor-auth-<uid>'.
    # > Review/merge with: git merge praisonai/refactor-auth-<uid>

    Keep the worktree in place for in-place review with --keep:

    bash
    praisonai run agents.yaml --worktree --keep

    No-op outside a git repo, so it’s always safe to pass. See praisonai run --worktree.

  2. Concurrent Agents With Isolation (Python)

    Give each agent its own git worktree โ€” edits stay independent.

    python
    from praisonaiagents import Agent
    from praisonaiagents.workspace import GitWorktreeAdapter
    
    workspace = GitWorktreeAdapter()
    
    alice = Agent(name="Alice", instructions="Edit README.md")
    bob = Agent(name="Bob", instructions="Also edit README.md")
    
    alice_dir = workspace.create("alice")  # -> ./.praisonai/worktrees/alice-<hash>
    bob_dir = workspace.create("bob")      # -> ./.praisonai/worktrees/bob-<hash>
  3. Default, Reset, or Remove

    Opt out of isolation with NoIsolationAdapter, or reset and tear down worktrees when a run ends.

    python
    from praisonaiagents.workspace import NoIsolationAdapter
    
    workspace = NoIsolationAdapter()
    workspace.create("alice")  # -> current working directory
  4. Reset or Remove

    Restore a worktree to a clean state, or tear it down when the run ends.

    python
    workspace.reset("alice")   # git clean + checkout inside alice's worktree
    workspace.remove("alice")  # remove the worktree and its branch

How It Works

GitWorktreeAdapter runs real git worktree commands to provision a fresh branch and directory per run.

Diagram
Isolated WorktreegitGitWorktreeAdapterAgentUserIsolated WorktreegitGitWorktreeAdapterAgentUserRun task on repocreate(“alice”)git worktree add -B praisonai/aliceNew branch + directoryIsolated pathEdits stay contained
MethodWhat it does
create(name)Provision the isolated directory and return its path (idempotent โ€” reused if it exists).
path(name)Return the directory path for name without creating it.
reset(name)Restore tracked files and drop untracked files inside the worktree.
remove(name)Tear down the worktree and delete its branch.

When the directory is not a git repository, every method degrades gracefully โ€” create and path return the original directory, and reset and remove do nothing.


CLI Usage

praisonai run --worktree wraps the adapter so a single command runs the agent on a fresh branch โ€” no Python glue required.

bash
praisonai run "refactor auth to use bcrypt" --worktree
Diagram

Isolated praisonai run

Yes

No

๐Ÿ“ praisonai run –worktree

๐ŸŒฟ New branch + worktree

๐Ÿค– Agent edits here

Changes?

โœ… Auto-commit branch, prune checkout

๐Ÿงน Remove worktree + branch

The run detects changes with git status --porcelain, so brand-new (untracked) files are never lost.

SituationWorktree checkoutBranchReported
No changesRemovedRemovedNo changes on '<branch>'.
Any change (tracked or untracked)PrunedRetained with auto-commitCommitted changes to branch '<branch>'. Review/merge with: git merge <branch>
--keepRetainedRetainedWorktree kept at <path> (branch '<branch>'). Review/merge then remove with: git worktree remove.
Cwd is not a git repon/a (no-op)n/aWarning: Not a git repository; running without worktree isolation.

Choosing an Adapter

Both adapters share the same interface, so you can swap them without changing your code.

Diagram

From the CLI

In Python

Yes

No

Yes

No

How are you
reaching isolation?

–worktree flag
no code

Agents editing
the same repo
in parallel?

GitWorktreeAdapter

Is cwd
a git repo?

NoIsolationAdapter

GitWorktreeAdapter is always safe โ€” if the directory is not a git repo it falls back to NoIsolationAdapter behaviour automatically.


Configuration Options

GitWorktreeAdapter accepts three options.

OptionTypeDefaultDescription
root`str \Path \None`Path.cwd()Repository root to isolate.
branch_prefixstr"praisonai"Prefix for worktree branches โ€” branches are named {branch_prefix}/{slug(name)}.
worktrees_dir`str \Path \None`{root}/.praisonai/worktreesDirectory where per-run worktrees are created.
python
from praisonaiagents.workspace import GitWorktreeAdapter

workspace = GitWorktreeAdapter(
    root=".",
    branch_prefix="team",
    worktrees_dir=".worktrees",
)

if workspace.available:
    workspace.create("alice")

The available attribute is True only when root is inside a git repository and git is on the PATH.

NoIsolationAdapter accepts a single root option (str | Path | None, default Path.cwd()) that it returns from create and path.


Common Patterns

Give parallel sub-agents their own worktrees.

python
from praisonaiagents.workspace import GitWorktreeAdapter

workspace = GitWorktreeAdapter()

for name in ("researcher", "writer", "reviewer"):
    workspace.create(name)  # each gets an independent branch + directory

Reuse the same worktree for a named agent โ€” create is idempotent.

python
first = workspace.create("alice")
second = workspace.create("alice")
assert first == second  # same worktree reused, no duplicate created

Clean up when the run finishes.

python
workspace.create("alice")
# ... agent does its work ...
workspace.remove("alice")  # removes worktree and branch

CLI usage

The same isolation primitive is available directly on the CLI โ€” pass --worktree to praisonai run and every invocation gets its own branch. Pass --keep to retain the worktree checkout after the run for review. See Per-run worktree isolation for the full flag reference and behaviour matrix.

bash
praisonai run "refactor auth.py" --worktree
praisonai run agents.yaml --worktree --keep

Best Practices

Reach for –worktree before the Python API

For a one-off isolated agent run there is nothing to install and no Python glue โ€” just append --worktree. The programmatic GitWorktreeAdapter is only needed when you’re orchestrating multiple agents from your own code.

Use –keep when you want to inspect in place

Without --keep, the worktree checkout is pruned after each run (the branch is preserved). With --keep, both the checkout and the branch stay so you can cd into the isolated directory and inspect changes in place.

Merge or squash the auto-commit

The isolated run auto-commits everything (tracked + untracked) with the message praisonai run: <target>, so merge or cherry-pick with a plain git merge praisonai/<name>-<uid>. To collapse into a single commit, use git merge --squash.

Use GitWorktreeAdapter unconditionally

It degrades gracefully outside git repos, so you can always reach for it. No need to detect git yourself โ€” available reports the state and non-git directories simply fall back to shared behaviour.

Name worktrees by agent or run, not by task

Names are hashed into collision-resistant slugs, so "agent one" and "agent-one" never share a worktree. Stable names keep create idempotent across retries.

Clean up with remove() when the run ends

Each worktree lives under .praisonai/worktrees/. Call remove() on completion to stop that directory from growing over long-running sessions.

Requires git โ‰ฅ 2.5

git worktree was introduced in git 2.5. On older git or non-git directories, isolation is unavailable and the adapter falls back to the shared directory.


Also available on the CLI

Run a single praisonai run invocation on a fresh worktree/branch with the --worktree flag โ€” no Python needed. It commits the run’s output to the branch on exit (or keep it in place with --keep).

bash
praisonai run --worktree "Refactor the auth module and add tests"

See Isolated Runs (Git Worktree) for the full flag reference and teardown behaviour.


Related