pwt — Power Worktrees
One branch per worktree, one port per server, one stable workflow. For humans and AI agents working in parallel.
brew install jonasporto/pwt/pwt
Why pwt
- Work in parallelMultiple projects, or parallel changes within the same project. No stashing, no branch juggling.
- One stable workflowKeep one editor open, swap branches underneath it.
- No local conflictsAutomatic per-worktree ports and predictable dev servers.
- Project-aware automationSetup, servers, and custom commands defined per project in a Pwtfile.
- Background jobsReal detached daemons with logs, exit codes, and wait primitives.
- Agent-readyPorcelain output, stable exit codes, and
pwt skillfor AI-driven workflows.
One setup, every agent
Claude Code, Codex, Cursor and the rest each create worktrees their own way, and each has its own answer for the setup problem: a copy file here, a hook there, nothing at all in most. Define it once in a Pwtfile and every tool lands on the same ready checkout, with its own port, its own database and its own generated config.
- You own the definitionWhat "a ready worktree" means lives in your repository, versioned, not in four tool-specific config formats that drift apart.
- Ports across projectsAllocation is machine-wide, so two agents in two different repositories never get handed the same port.
- One inventory
pwt list,pwt portsandpwt jobsshow everything in flight, whoever created it. - Nothing to interceptWhen a tool creates a worktree on its own,
pwt adoptregisters it after the fact: port, metadata and setup, no rework.
Quick start
cd ~/projects/myapp
pwt init # Initialize project
pwt add feat/user-auth # Create worktree from branch
pwt feat/user-auth # Jump to a worktree
pwt server --bg # Start its dev server, detached
pwt list # List worktrees with git status
Install
# Homebrew
brew install jonasporto/pwt/pwt
# npm
npm i -g @jonasporto/pwt
# curl
curl -fsSL https://raw.githubusercontent.com/jonasporto/pwt/main/install.sh | bash
Pwtfile: project hooks
Think Makefile, but for the worktree lifecycle. pwt stays project-agnostic; your Pwtfile defines what setup, servers, and health mean for your stack.
PORT_BASE=5001
setup() {
pwtfile_copy ".env.local"
pwtfile_symlink ".cache"
./scripts/setup
}
server() {
case "${1:-start}" in
start) exec env PORT="$PWT_PORT" ./scripts/dev ;;
stop) ./scripts/dev-stop ;;
esac
}
Stable gateway
Each worktree gets its own port, and one stable project URL routes to whichever worktree you're testing:
pwt gateway up --port 5999
pwt gateway use feat/user-auth
open "$(pwt gateway url)"
Built for agents too
Driving pwt from an AI agent or a script? pwt skill prints the agent guide:
machine-readable output (list --porcelain, state --json), a stable
exit-code table, and wait primitives (pwt server wait, pwt jobs wait)
that replace poll loops. See also llms.txt.
From the blog
-
I timed every command in my CLI on a 95-worktree project
Four commands took over ten seconds. The fix was not making the work faster, it was taking the work off the read path. Includes the two instruments that lied to me and the command that is still slow today.
-
Your agent created the worktree. Now it does not run.
Coding agents create worktrees themselves, and a fresh checkout has no .env, no dependencies and no port of its own. The hook that fixes it makes you take over worktree creation, which is the part worth reading before you wire anything.
-
What is using port 5000 on your Mac (and why your tools call it a running server)
AirPlay Receiver holds 5000 and 7000, answers HTTP 403 as AirTunes, and satisfies every readiness probe pointed at it. Whether it collides with your server depends on one socket option. Four false positives I found in my own tool, and the classifier that fixes all of them.
-
Using pwt ports as a central registry for every app on your machine
Scanning finds a port that is free right now, which is why two projects end up with the same number: a sleeping app still owns one. Allocation is bookkeeping, naming is a proxy, and they are different problems.
Documentation
README · Install guide · FAQ · Changelog · State contract · llms.txt