One coding agent on a repo is a pair programmer. Three at once is a team, and a team needs more than one desk. This is how to give each agent its own checkout with git worktrees, what that still leaves you doing by hand, and how kelpie does the rest - from a branch to a pull request, with your own test in the middle. It applies the same to Codex, Cursor and OpenCode.
Two agents in one working tree share every file. Each one reads the other's
half-finished edits as the state of the code, a test run picks up changes neither of them
meant to test, and a git checkout by one moves the branch under the other. If
the project has a dev server, they fight over its port too, so the page you open is
whichever started last.
Cloning the repo again works, but every clone has its own objects and its own remote config, and a branch made in one is invisible in the others. A git worktree is the lighter answer: a second working directory for the same repository, sharing its history and branches, with a branch of its own checked out.
Cut each worktree from a freshly fetched main rather than from whatever your main checkout happens to be on, so the branch starts where its pull request will land:
git fetch origin
git worktree add ~/parallel/shop-saved-cards -b saved-cards --no-track origin/main
cd ~/parallel/shop-saved-cards
pnpm install
claude
Repeat for the next task in another directory, and start the next agent there. A few things to know:
node_modules, .env
and build output are per worktree, so each one needs its install, and its secrets copied
or linked.--no-track keeps the new branch from tracking
origin/main, so a later git push creates its own branch on the
remote rather than refusing.pnpm dev on 3000 will not both start.When the work has merged, take the worktree away and, if you like, the branch:
git worktree list
git worktree remove ~/parallel/shop-saved-cards
git branch -d saved-cards
git worktree remove refuses a worktree with uncommitted changes, which is
the safety you want. Do not reach for --force unless you have looked.
Worktrees solve the files. Everything around them is still yours to keep in your head:
Kelpie is a board of every coding agent session on your Mac, sorted by which ones need you. Its New › Feature does the worktree routine above in one step, and keeps the feature on the board as a row until it ships.
Pick the repo and the agent, give the feature a name and write the ask, the way you
would brief anyone. The name becomes the branch, so Saved cards is
saved-cards; if that branch exists already, the new one is
saved-cards-2.
It fetches the branch a pull request would target and cuts the new branch from it, in a
worktree under ~/parallel/<repo>-<name>. Your main checkout
never moves. worktreeDir in the settings picks a different
parent directory.
If the repo has a kelpie.json, each app it
declares starts in its own tmux window on a free port, after the install runs once. With
Caddy installed, the feature also gets an https
address of its own, like https://shop-saved-cards.localhost, so the link on
the row always serves that branch and nothing else.
The session starts with your ask plus a short brief: it is on its own branch in its own worktree, the dev server is already running and it should use that one, it should try what it is about to ask you to test against the running app, and it must not push or open a pull request until you say how the test went. The row sits under Running while it works, and moves to Needs you when it is done or has a question.
The Preview tab is the feature's app inside the board. Draw a box around anything wrong and add a comment, and the session gets your note with a screenshot of the box. Diff is the branch against its base, split into code, tests and docs, with line comments that go back to the session. Server holds the dev log, Restart and Stop. If you share the board with your phone, the feature's app opens there too.
When you are happy, Ship it in the Diff tab tells the session the test passed: commit what is outstanding, push the branch and open the pull request, with the description written the way your repo's template asks. The PR then shows on the row with its checks and unresolved review threads.
Tear down, in the session's menu, is the way out once the PR has merged or the
idea is dead. It stops every session parked in the worktree, the dev server included, runs
the repo's own teardown command, and removes the worktree. The branch stays,
because a pull request may still point at it. A worktree with uncommitted work is refused,
with the reason, rather than forced.
One file at the root of your repo tells kelpie how the project runs. Everything in it is optional, and a repo without one still gets the branch, the worktree and the session - just no dev server.
{
"setup": "pnpm install",
"apps": [
{ "name": "api", "command": "pnpm api --port {port}" },
{ "name": "web", "command": "API_URL=http://localhost:$KELPIE_PORT_API pnpm dev --port {port}",
"proxy": true }
],
"ready": "/health",
"teardown": "pnpm db:drop"
}
setup runs once in the new worktree before any app starts. Leave
it out and kelpie infers the install from your lockfile.apps are the processes to run, each in its own tmux window.
{port} is a free port picked for that app.proxy marks the app the feature's link opens. Exactly one app
carries it.KELPIE_PORT_<NAME> is how apps find each other: every app
sees every sibling's port in its environment.ready is the path kelpie knocks on before it shows the link, so
the link never opens a server that is still starting.teardown runs in the worktree just before it is removed, for the
state kelpie cannot see: a database your dev server created, a volume, a
registration.New › Review is the same routine pointed at a pull request: its branch checked out in a worktree of its own, its dev server up, and a session that has read the change and explains it. You click around the running branch instead of reading the diff cold, and your line comments in the Diff tab post to GitHub as one review - comment, approve or request changes.
The Mac app puts a kelpie command on your PATH that drives the board
already running, so a script, or an agent, can start and stop features too:
kelpie feature saved-cards --cwd ~/repos/shop --ask "Let a returning customer pay with a saved card"
kelpie restart-dev # the dev server of the feature checked out here
kelpie teardown # the feature checked out here: sessions, dev server, worktree
--agent picks the agent, and --ask-file reads a longer brief
from a file, or from stdin with -.
kelpie.json a feature still gets its own branch, worktree
and session. The file adds the dev server.