Skip to main content
A worktree is a separate working copy of your repo on its own branch, managed by git worktree. When you create a session with Create worktree selected (the default on the new-session page), p0 spins up a fresh worktree for that session. The agent edits files without touching your main checkout. The alternative work mode is Edit in place. That mode leaves the session pointed at the workspace path with no branch isolation.

Where they live on disk

p0 puts every worktree under ~/.purple-code/worktrees/. In development builds the base directory is ~/.purple-code-dev/worktrees/ instead — the rest of the layout is identical. For a multi-repo workspace, each session gets one folder that mirrors the workspace shape.
~/.purple-code/worktrees/{workspace-name}-wt-{sessionId}/
├── repo-a/                # Worktree for workspace/repo-a
├── repo-b/                # Worktree for workspace/repo-b
├── purple/                # → symlink to workspace/purple/
├── .claude/               # → symlink to workspace/.claude/  (or .codex/ on Codex)
├── .mcp.json              # → symlink to workspace/.mcp.json
└── .workspace-root        # marker file containing the sessionId
If your workspace has its repo at the root rather than in a subfolder, the worktree dir itself is the worktree. There’s no extra repo-a/ layer. The purple/, .claude/ (or .codex/), and .mcp.json entries are linked, not copied. That means spec docs, agent config, and MCP server config in your workspace are reachable from inside the worktree without polluting the git index. On Windows without Developer Mode the .mcp.json link falls back to a watched copy. Directory links use junctions.

Branch naming

Each worktree gets its own branch off your repo’s default branch. The branch name is built from the most specific thing p0 knows about the session:
  • If the session has a feature slug (Plan & Build sessions do): {sanitized-slug}-{6-hex}.
  • Otherwise, if a workspace name is available: {sanitized-workspace}-wt-{6-hex}.
  • Otherwise, as a fallback: {adjective}-{animal}-{6-hex} from the unique-names-generator dictionaries.
The slug or name is lowercased, hyphenated, stripped of non-alphanumeric characters, and capped at 30 chars before the -{hex} suffix is appended. The base branch for the worktree is whatever you configured in Repositories as the default branch for that repo. If you haven’t configured one, p0 auto-detects it from the repo and prefixes it with origin/ when an origin remote exists. You can copy a session’s branch name from the sidebar context menu: right-click a row and choose Copy branch name.

Cleanup

There are two paths that remove a worktree:
  • Deleting the session. From the sidebar context menu, Delete cancels any active streams, kills the session’s terminals, and removes its worktree directory. The cleanup only fires when the session was a real worktree session — sessions created with Edit in place have no branch and no worktree path, so there’s nothing to remove.
  • Orphan cleanup. A worktree directory under ~/.purple-code/worktrees/ that is no longer referenced by any session in the DB is considered orphaned. You can list and delete orphans from the storage view; p0 re-checks the DB right before each removal so it can’t race with an active session.
If a worktree’s symlinks to purple/, the provider config folder, or .mcp.json go missing, the session row in the sidebar shows a yellow triangle next to its mode badge. This happens, for example, after you move or rename the workspace. Clicking the triangle runs Repair worktree, which re-creates the missing links.