Worktrees and ports
Every conversation, and so every card a teammate works on, runs in its own git worktree on its own branch, with its own ports. Agents work side by side without touching your checkout or each other.
What happens when work starts
- Tutti creates a git worktree of the project on a new branch (by default
tutti/<short-title>), from the project's base branch. - It copies or links files you listed, such as
.env, from your main checkout. - It allocates ports for this conversation, unique on your machine.
- The
[setup]script prepares the worktree (dependencies, migrations, seed data). For a one-agent conversation it runs before the agent starts; teammates run it themselves the first time they need to run the app or tests, so reading and planning start right away. You can also choose Set up. - Dev servers from
[run]start on demand, or as soon as the worktree is ready if you turn on Start dev servers automatically in Settings.
Your main checkout is never touched: no files change there, and git commands for the work run only in the worktree.
Ports
Each conversation gets $TUTTI_PORT, plus $TUTTI_PORT_1, $TUTTI_PORT_2… if
ports.extra asks for them (up to 9). Use them in your dev server commands instead of fixed ports, and
ten copies of your app can run at once:
[run]
api = { cmd = "uv run python manage.py runserver 127.0.0.1:$TUTTI_PORT", url = "http://localhost:$TUTTI_PORT" }
web = { cmd = "pnpm dev --port $TUTTI_PORT_1", url = "http://localhost:$TUTTI_PORT_1" }
[ports]
extra = 1
The Preview tab shows the dev server, and the conversation's header shows its status with Start and Stop.
Environment variables
Setup, dev servers, teardown and agents get these:
| Variable | Value |
|---|---|
TUTTI_PORT | This conversation's main port. |
TUTTI_PORT_1 … TUTTI_PORT_9 | Extra ports, if ports.extra is set. |
TUTTI_WORKTREE | The worktree's folder. |
TUTTI_ROOT | Your main checkout's folder. |
TUTTI_BRANCH | The conversation's branch. |
TUTTI_SESSION | A short, unique name for the conversation, handy for database and Compose project names (e.g. shop_$TUTTI_SESSION). |
TUTTI_SESSION_ID | The conversation's id. |
TUTTI_PROJECT | The project's name. |
Add your own in [env]; $TUTTI_* variables are expanded there.
Where worktrees live
In Tutti's data folder, not in your repository: ~/Library/Application Support/build.tutti.Tutti on
macOS, ~/.local/share/tutti on Linux and %LOCALAPPDATA%\tutti\Tutti\data on Windows (or
TUTTI_DATA_DIR if you set it). Use Open in editor (⌘⇧E)
or Show in folder to get there.
When work ends
Archiving a conversation runs the [teardown] script (drop the database, stop containers) and removes
the worktree. The branch stays, with everything committed on it, unless you choose to delete it.
Something missing or unclear? Ask us, and we'll answer and improve this page.