Controller

Worktrees

Run sessions on isolated git worktrees so branches and dev servers don't collide.

A worktree is a git worktree Controller manages for a project: an isolated checkout on its own branch. Each session belongs to one worktree for its entire lifetime. Multiple sessions can share a worktree, while separate worktrees keep parallel changes and dev servers isolated.

Create a worktree

Ask a main-worktree agent to create a worktree for a task, or run controller worktrees create [<project>] --name <name> from the terminal. The agent can use the controller-worktrees skill to choose a branch and start a linked conversation in the new worktree.

Controller checks out the new worktree and, if the project has a setup.sh, runs it to install dependencies.

Existing Git worktrees

When you add a Git project, Controller automatically tracks its existing linked worktrees. It also refreshes the list when the sidebar loads the project's worktrees. There is no import step. Tracking preserves each checkout's path, branch or detached HEAD, and uncommitted files. Controller assigns an ID and PORT_OFFSET without running setup or changing the checkout.

Worktrees that Git reports as prunable or whose directories are missing are not registered. If a tracked worktree disappears, Controller keeps its record and conversation history, but disables new work there. A path with prior Controller history is not automatically reused for a different checkout, because session storage is keyed by path.

Pick a worktree when starting a session

Expand a worktree in the sidebar and use New conversation. The session's agent, terminals, and run.sh operate inside that worktree's checkout, and the agent is told to edit files only there. A main-worktree conversation can inspect, test, and run the project. When you ask it for a change, its agent hands the work off to a new linked conversation in a feature worktree and replies with a link to it, instead of making the change itself.

Each worktree row shows its linked PR number on the right (green icon when open, violet when merged); click it to open the PR tab for that worktree. The session header shows the same PR next to its change summary. Hover a worktree to start its run.sh server (play) or stop it (pause, shown in green while running). Stopping interrupts the server but keeps its Run terminal and output. Removed worktrees appear dimmed with an archive icon.

Remove a worktree

Controller checks for uncommitted changes and running processes before removing a worktree. Its conversations and transcripts remain in the sidebar as history. They cannot run new turns. Open one and select Continue on main to create a distinct linked conversation in the main worktree. A removed worktree's name stays reserved so its history is never mixed with a new worktree's conversations.

For a worktree discovered outside Controller, the sidebar offers Stop tracking instead. This removes it from active Controller work without running git worktree remove or deleting its directory. Its conversation history remains visible. To remove the checkout itself, use Git directly.

Parallel worktrees and PORT_OFFSET

Each worktree gets a numeric PORT_OFFSET — 0 for the main worktree, then 3, 6, and so on. By deriving your dev server's ports from your base ports plus PORT_OFFSET in run.sh, two worktrees can run side by side without colliding on the same port (e.g. both trying to bind 3000). See Controller scripts for the port pattern.

Target a worktree with schedules

Scheduled sessions run on a specific worktree. Ask the agent to schedule a session (for example, "run the morning health check on the main worktree at 8am") and it sets up the schedule on that worktree through the controller-schedules skill. Each schedule starts a new session on the given worktree when it fires, and it shows up in the sidebar like any other session.

Ask the agent to create one

You can have the agent set up a fresh worktree for you. When you ask it to "create a worktree on a new branch" or "work on this issue in a fresh worktree", it reaches for the controller-worktrees skill. Combined with run.sh, this gives you an isolated branch with its own dev server in one step.

On this page