Command reference
Run any of these with --help in your terminal for the same text.
Each command has a stable anchor, so /docs/commands/#create
links straight to it.
create
add
track
adopt
setup
list
ls
tree
skill
cd
use
current
info
show
remove
rm
server
s
gateway
servers
run
for-each
diff
repair
fix
auto-remove
cleanup
restore
fix-port
doctor
state
meta
m
project
config
port
ports
plugin
step
alias
jobs
logs
self
versions
pwt create
Also available as add.
Usage: pwt create|add <branch> [base] ["description"]
Arguments:
branch Branch name or ticket (e.g., TICKET-1234)
base Base branch (default: master)
"description" Quoted text with spaces is treated as description
Options:
--from <ref> Create from specific ref (tag, commit, branch)
--from-current Create from current branch
--branch <name> Use exact Git branch name (directory still uses <branch>)
--track <remote/ref>
--track-existing <remote/ref>
Create local branch tracking an existing remote branch
--clone Use git clone instead of worktree
-e, --editor Open in editor after creation
-n, --dry-run Show what would be done
-h, --help Show this help
Examples:
pwt create TICKET-1234 # no description
pwt create TICKET-1234 "auth login bug" # with description
pwt create TICKET-1234 develop "auth login" # custom base + description
pwt create --track origin/team/TICKET-1234
pwt track origin/team/TICKET-1234
pwt create TICKET-1234 --branch team/TICKET-1234 --from origin/team/TICKET-1234
pwt add
Alias for pwt create.
pwt track
Usage: pwt track <remote-branch> [--name <worktree>] [options]
Create a pwt-managed worktree that tracks an existing remote branch.
The local branch matches the remote branch name without applying branch_prefix.
Arguments:
remote-branch Remote branch, e.g. origin/team/TICKET-1234
Options:
--name <name> Override worktree directory/metadata name
-e, --editor Open editor after creation
-n, --dry-run Show what would be done
--clone Use git clone instead of worktree
-h, --help Show this help
Examples:
pwt track origin/team/PROJ-1234
pwt track origin/team/fix-login-flow --name login-flow
pwt adopt
Also available as setup.
Usage: pwt adopt [path]
pwt adopt --all [dir]
pwt setup [path]
Register an existing git worktree with pwt and run standard setup.
Arguments:
path Existing worktree path (default: current directory)
--all [dir] Adopt every unregistered worktree in dir (default: worktrees_dir)
This allocates/records metadata, exports PWT_* context, runs Pwtfile setup,
runs the post-create hook, and sets the worktree as current.
pwt setup
Alias for pwt adopt.
pwt list
Also available as ls.
Usage: pwt list|ls [options]
List all worktrees for the current project.
Options:
-d, --dirty Only show dirty worktrees
-v, --verbose Show detailed info (original format)
-q, --quick Skip network operations (faster)
-r, --refresh Force refresh cache
--porcelain Output JSON (for scripts)
--names Output only worktree names (for completions)
statusline Compact single-line for prompts
Examples:
pwt list # Default tabular view
pwt list -d # Only dirty worktrees
pwt list --porcelain # JSON output
pwt list --names # Just names (for shell completion)
pwt ls
Alias for pwt list.
pwt tree
Usage: pwt tree [--all] [--dirty] [--ports] [--short] [--refresh]
Visual tree view of worktrees - mental map of active work.
Options:
--all, -a Show all projects (global view)
--dirty, -d Show only dirty worktrees
--ports, -p Show port mappings
--short, -s One line per worktree
--refresh, -r Recompute synchronously (skip cache)
Examples:
pwt tree # current project
pwt tree --all # all projects
pwt tree --dirty # only dirty worktrees
pwt tree --ports # show ports
pwt skill
Usage: pwt skill [--path] [--install [dir]]
Print the agent-facing guide to driving pwt: machine-readable
flags, exit codes, wait primitives and the worktree lifecycle.
Options:
(none) Print the guide to stdout
--path Print the file path instead
--install [dir] Copy the skill into dir
(default: ~/.claude/skills/pwt-cli)
For humans, see 'pwt help' and 'pwt help pwtfile'.
pwt cd
Usage: pwt cd [worktree|@|-]
pwt cd <term> # search by name or description
pwt cd --select # interactive picker (fzf)
Navigate to a worktree (outputs path for shell integration).
Arguments:
worktree Name of the worktree
<term> Search term (matches name AND description)
@ Main app directory
- Previous worktree (like cd -)
(none) Last used worktree, or main
Options:
--select, -s Interactive worktree selector (fzf)
Search behavior:
- Partial name match: pwt cd auth
- Description search: pwt cd "auth login"
- If no match found, falls back to fzf for fuzzy selection
Tip: Run 'pwt shell-init' for real cd integration.
pwt use
Usage: pwt use <worktree> [options]
Switch the current worktree symlink.
Arguments:
worktree Target worktree name (supports partial match)
@ Switch to main app
Options:
-s, --select Interactive picker (fzf)
Examples:
pwt use TICKET-123 # switch by name
pwt use 123 # partial match
pwt use @ # switch to main app
pwt use --select # interactive picker
pwt current
Usage: pwt current [options]
Show the currently active worktree.
Options:
--name Output only the worktree name
--port Output only the port number
--branch Output only the branch name
--path Output only the worktree path
--json Output full context as JSON
--resolved Show resolved symlink path
Detection order:
1. Current directory (if inside a worktree)
2. 'current' symlink (set via 'pwt use')
Examples:
pwt current # show current worktree
pwt current --port # get port for scripts
pwt current --json # full context as JSON
pwt info
Also available as show.
Usage: pwt info [worktree] [--porcelain]
Show detailed information about a worktree.
Arguments:
worktree Name of the worktree (optional if inside one)
@ Main app
--porcelain Machine-readable JSON output (alias: --json)
Information shown:
- Branch and tracking information
- Assigned port number
- Server status
- Directory, mode, description, and created timestamp from metadata
- Creation metadata
- Git status (dirty files)
Examples:
pwt info # info for current worktree
pwt info TICKET-123 # info for specific worktree
pwt info @ # info for main app
pwt show
Alias for pwt info.
pwt remove
Also available as rm.
Usage: pwt remove|rm [worktree] [options]
Arguments:
worktree Worktree name (default: current)
@ Not allowed (cannot remove main app)
Options:
--with-branch Also delete the branch (if merged)
--force-branch Force delete the branch (even if not merged)
--kill-port Kill processes using the port
--kill-<command> Run Pwtfile <command> --kill before removal
--kill-all Run Pwtfile server --kill and kill port processes
-y, --yes Skip confirmation prompts
-h, --help Show this help
Safety: Dirty worktrees are backed up to ~/.pwt/trash/
pwt rm
Alias for pwt remove.
pwt server
Also available as s.
Usage: pwt server|s [worktree] [--bg] [--no-input] [pwtfile-flags...]
pwt server wait [worktree] [--log-contains <str>] [--timeout <s>]
Start development server for a worktree.
'pwt server wait' blocks until the server is ready (see: pwt server wait --help).
Arguments:
worktree Worktree name (default: current worktree or symlink)
Options:
--bg Run server in background (daemonize)
--count N With --bg: spawn N instances
--no-input Close stdin and set PWT_AGENT=1
-h, --help Show this help
Detection order:
1. Argument provided: pwt server ACME-1234-50XX
2. Inside worktree directory
3. Current symlink set via 'pwt use'
Server runs on port from worktree metadata (usually 50XX).
pwt s
Alias for pwt server.
pwt gateway
Usage: pwt gateway <command> [args]
Manage a stable per-project gateway URL that forwards to a worktree server.
Commands:
init --port <port> [--host <host>]
Configure gateway port and public host
up [--port <port>] [--host <host>]
Start gateway proxy daemon
down Stop gateway proxy
start Alias for up
stop Alias for down
restart Restart gateway proxy
status [--json] Show gateway status
use <worktree|@> [-- ...] Point gateway at a worktree; auto-starts server if needed
url Print gateway URL
logs [-f] Show gateway logs
pwt servers
Usage: pwt servers [--all] [--json]
Show development server status for the current project.
Options:
--all, -a Include stopped worktrees
--json Output machine-readable JSON
-h, --help Show this help
pwt run
Usage: pwt run [worktree] <command...>
Run a command in a worktree without changing directory.
Arguments:
worktree Target worktree (@ for main, optional)
command Command to run in the worktree
If worktree is omitted, runs in current worktree or main.
Examples:
pwt run TICKET-123 ./scripts/test # in specific worktree
pwt run @ git status # in main app
pwt run ./scripts/test # in current/main
pwt for-each
Usage: pwt for-each <command...>
Run a command in all worktrees.
Arguments:
command Command to run in each worktree
Notes:
- If command is a Pwtfile function, runs it via Pwtfile
- Runs in the main checkout (@) first, then in every worktree
- Exits non-zero and lists the worktrees where the command failed
Examples:
pwt for-each git status
pwt for-each ./scripts/test
pwt for-each migrate # Runs Pwtfile migrate()
pwt diff
Usage: pwt diff <worktree1> [worktree2]
Show file differences between worktrees.
Arguments:
worktree1 First worktree to compare
worktree2 Second worktree (default: @ for main app)
Examples:
pwt diff TICKET-123 # Compare TICKET-123 vs main
pwt diff TICKET-123 @ # Same as above
pwt diff TICKET-123 TICKET-456 # Compare two worktrees
pwt repair
Also available as fix.
Usage: pwt repair|fix [worktree]
Run repair hooks on worktrees.
Arguments:
worktree Specific worktree to repair (optional)
If omitted, repairs all worktrees
Runs the 'repair' function from Pwtfile and any repair hooks.
Useful after config changes or dependency updates.
Examples:
pwt repair # repair all worktrees
pwt repair TICKET-123 # repair specific worktree
pwt fix
Alias for pwt repair.
pwt auto-remove
Also available as cleanup.
Usage: pwt auto-remove|cleanup [target] [options]
Safely remove worktrees that have been merged into target branch.
Arguments:
target Target branch to check merges against (default: current)
Options:
--execute, -y Actually remove (default is dry-run)
--dry-run, -n Preview what would be removed (default)
-h, --help Show this help
Safety:
- Dry-run by default (shows what would be removed)
- Dirty worktrees backed up to ~/.pwt/trash/
- Requires --execute for non-interactive use
pwt cleanup
Alias for pwt auto-remove.
pwt restore
Usage: pwt [project] restore [backup] [worktree]
pwt restore List available backups
pwt restore list List available backups
pwt restore <backup> Recreate worktree and apply backup
pwt restore <backup> <wt> Apply backup to existing worktree
Backups are created automatically when removing dirty worktrees.
Location: ~/.pwt/trash/
pwt fix-port
Usage: pwt fix-port [worktree]
Resolve port conflicts for a worktree.
Arguments:
worktree Target worktree (optional if inside one)
When a port conflict is detected, offers:
- Kill the process using the port
- Reallocate to a new port
Examples:
pwt fix-port # fix port for current worktree
pwt fix-port TICKET-123 # fix port for specific worktree
pwt doctor
Usage: pwt doctor
Check system health and pwt configuration.
Checks performed:
- Required tools (git)
- Optional tools (jq, lsof, fzf)
- PWT directory structure
- Leftover legacy state backups (*.v1.bak)
- Project configurations
- Worktree integrity
pwt state
Usage: pwt state [--json]
pwt state migrate [--status|--check|--verify]
Emit a versioned JSON snapshot of all pwt state: projects,
worktrees (with metadata) and background jobs.
Subcommands:
migrate Inspect/apply state schema migrations
(see docs/migrations/)
Consumers that prefer reading files directly can watch
$PWT_DIR (state-version, events.log, projects/, state/, jobs/)
as described in docs/state-v2-contract.md.
pwt meta
Also available as m.
Usage: pwt meta [command] [args]
pwt meta "text with spaces" (set description on current worktree)
pwt meta <key> [value] (get/set field on current worktree)
Manage worktree metadata - descriptions, ports, and custom fields.
Metadata helps you find and identify worktrees across pwt commands.
COMMANDS:
list List all metadata (default)
show <worktree> Show metadata for one worktree
set <worktree> <field> <value> Set a field on any worktree
unset [worktree] <field> Remove a custom field (phase, reviewer, ...)
Structural fields (port, path, ...) refused
import Import existing worktrees
SHORTCUT (from inside a worktree - targets the worktree you are IN):
pwt meta "text with spaces" Set description (spaces = description)
pwt meta <key> Get a field
pwt meta <key> <value> Set a field
pwt meta unset <key> Remove a field
FIELDS:
description Free text describing the worktree purpose
port Port number for dev servers (auto-allocated)
marker Visual marker for lists (emoji or text)
<custom> Any custom field you want (e.g., env, reviewer)
═══════════════════════════════════════════════════════════════════════
WHERE METADATA APPEARS
═══════════════════════════════════════════════════════════════════════
┌─────────────────────────────────────────────────────────────────┐
│ pwt list │
│ Shows description and port in the Meta column │
├─────────────────────────────────────────────────────────────────┤
│ Worktree Branch Status Meta │
│ ─────────────────────────────────────────────────────────────── │
│ TICKET-123 fix/TICKET-123 ✓ clean port=3001 │
│ description=auth bug│
│ TICKET-456 feat/TICKET-456 ● dirty port=3002 │
│ description=new API │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ pwt select │
│ Shows port and description in the fzf picker │
├─────────────────────────────────────────────────────────────────┤
│ TICKET-123 fix/TICKET-123 :3001 · auth bug │
│ TICKET-456 feat/TICKET-456 :3002 · new API │
│ @ main · · main app │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ pwt info TICKET-123 │
│ Shows all metadata fields │
├─────────────────────────────────────────────────────────────────┤
│ Worktree: TICKET-123 │
│ Branch: fix/TICKET-123 │
│ Port: 3001 │
│ Desc: auth bug │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ pwt cd <search> │
│ Searches BOTH name AND description (case-insensitive) │
├─────────────────────────────────────────────────────────────────┤
│ $ pwt cd auth # partial match │
│ $ pwt cd "login bug" # multi-word search │
│ $ pwt cd "au bug" # no match? fzf does fuzzy search │
│ │
│ No match or multiple? Opens fzf for fuzzy selection │
└─────────────────────────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════════════════
EXAMPLES
═══════════════════════════════════════════════════════════════════════
Setting description (quickest - text with spaces = description):
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta "fixing login auth bug" │
│ ✓ TICKET-123.description = fixing login auth bug │
└─────────────────────────────────────────────────────────────────┘
Setting description (explicit key):
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta description "fixing login auth bug" │
│ ✓ TICKET-123.description = fixing login auth bug │
└─────────────────────────────────────────────────────────────────┘
Setting description (on any worktree, from anywhere):
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta set TICKET-123 description "fixing login auth bug" │
│ ✓ Updated TICKET-123.description = fixing login auth bug │
└─────────────────────────────────────────────────────────────────┘
Getting a field value:
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta port │
│ 3001 │
└─────────────────────────────────────────────────────────────────┘
Viewing all metadata:
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta show TICKET-123 │
│ { │
│ "port": 3001, │
│ "description": "fixing login auth bug", │
│ "branch": "fix/TICKET-123", │
│ "created_at": "2024-01-15T10:30:00" │
│ } │
└─────────────────────────────────────────────────────────────────┘
Adding custom fields:
┌─────────────────────────────────────────────────────────────────┐
│ $ pwt meta set TICKET-123 reviewer "@john" │
│ $ pwt meta set TICKET-123 env staging │
│ # Custom fields show in pwt list and pwt info │
└─────────────────────────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════════════════
WORKFLOW TIPS
═══════════════════════════════════════════════════════════════════════
Description flows naturally through the entire workflow:
# 1. Create with description
$ pwt create TICKET-123 "auth: fix session timeout"
# 2. Or set later (from inside worktree)
$ pwt meta "auth: fix session timeout"
# 3. Find by description
$ pwt cd timeout # partial match
$ pwt cd "session timeout" # multi-word
$ pwt cd "ses time" # no match? fzf fuzzy search
# 4. See in lists
$ pwt list # Meta column shows description
$ pwt select # fzf picker shows description
pwt m
Alias for pwt meta.
pwt project
Usage: pwt project [command] [args]
Manage project configurations.
Commands:
list List all configured projects (default)
init <name> Initialize a new project config
show <name> Show project config and hooks
set <name> <key> <value> Update project config value
path <name> Print project config directory path
alias <name> [alias|--clear] Get/set/clear project alias
validate Validate current project setup
Options:
-h, --help, help Show this help
Config location: ~/.pwt/projects/<project>/config
Hooks location: ~/.pwt/projects/<project>/hooks/
pwt config
Usage: pwt config [key] [value]
View or set project configuration.
Commands:
show Show all settings (default)
<key> Show value for key
<key> <value> Set value for key
Keys:
main_app - Path to main project
worktrees_dir - Path to worktrees directory
branch_prefix - Prefix for branches (e.g., user/)
base_port - Base port for allocation (default: 5000)
gateway_port - Stable gateway proxy port
gateway_host - Public gateway URL host
workspace_link - Stable symlink kept pointing at the current worktree (for editors)
Options:
-h, --help, help Show this help
Config location: ~/.pwt/projects/<project>/config
pwt port
Usage: pwt port [worktree]
Get the port number for a worktree.
Arguments:
worktree Target worktree (optional if inside one)
Outputs just the port number, useful in scripts:
curl http://localhost:$(pwt port)
Examples:
pwt port # port for current worktree
pwt port TICKET-123 # port for specific worktree
pwt ports
Usage: pwt ports [--json]
Show every port pwt has allocated, across all projects.
Options:
--json Machine-readable output
-h, --help Show this help
Columns: port, project, worktree, status.
Status is 'listening' when a server is bound to the port,
'system' when a macOS daemon holds it (AirPlay Receiver
takes 5000 and 7000), and 'conflict' when two records
claim the same port.
pwt plugin
Usage: pwt plugin <action>
Manage pwt plugins - extend pwt with custom commands.
Actions:
list List installed plugins
install <source> Install plugin from file or URL
remove <name> Remove user plugin
create <name> Create new plugin from template
path Show plugin directories
Plugin Locations:
User plugins: ~/.pwt/plugins/ (writable, highest priority)
Homebrew: $(brew --prefix)/share/pwt/plugins/
npm: <prefix>/share/pwt/plugins/
User plugins override system plugins with the same name.
Plugin Structure:
Plugins are executable scripts named pwt-<command>
Invoked as 'pwt <command>'
Environment Variables (available to plugins):
PWT_PROJECT Current project name
PWT_MAIN_APP Main app directory
PWT_WORKTREES_DIR Worktrees directory
PWT_WORKTREE Current worktree name
PWT_PORT Current worktree port
PWT_BRANCH Current worktree branch
Examples:
pwt plugin list
pwt plugin create github
pwt plugin install ./my-plugin.sh
pwt plugin remove github
pwt step
Usage: pwt step <name> [args...]
Run a single step from the project Pwtfile.
Arguments:
name Step name (without step_ prefix)
args Passed to the function as "$1", "$2", ... and
as raw "$PWT_ARGS"
A step that setup() calls with arguments needs the same
arguments here. Under "set -u" a missing one fails with
"$1: unbound variable" - the step is asking for input,
it is not a pwt error.
Examples:
pwt step install # run step_install()
pwt step seed --fresh # run step_seed() with args
pwt step setup_dbs _wt42 # step that requires a positional
pwt steps # list available steps
pwt alias
Usage: pwt alias [<name>|--clear]
Set a short alias for the current project.
Arguments:
name New alias (must not conflict with commands)
--clear Remove current alias
(none) Show current alias
Examples:
pwt alias # show current alias
pwt alias api # set alias to 'api'
pwt alias --clear # remove alias
Once aliased, use it anywhere:
pwt api list # same as pwt my-long-project list
pwt api cd TICKET # same as pwt my-long-project cd TICKET
pwt jobs
Usage: pwt jobs [subcommand]
Manage background jobs started with --bg.
Subcommands:
list [--porcelain] List all jobs (default; --porcelain for JSON)
logs <job-id> [-f] View job output (-f to follow)
wait <id|worktree> [--timeout <s>] Block until a job finishes
stop <job-id> Stop a running job
stop --all Stop all running jobs
clean Remove stale job entries
help Show this help
wait exits 0 when the job's process is gone and prints '<id> <status>'.
Default --timeout is 600s; on timeout it exits 5.
A worktree name resolves to its running server job (then most recent job).
Examples:
pwt server --bg # start server in background
pwt jobs # list running jobs
pwt jobs logs abc123 # view job output
pwt jobs logs abc123 -f # follow job output
pwt jobs wait abc123 --timeout 300 # block until job exits
pwt jobs stop abc123 # stop a job
pwt jobs stop --all # stop all jobs
pwt logs
Usage: pwt logs [worktree] [-f]
Show background-job logs for a worktree: the running server job if
any, otherwise the most recent job. Defaults to the worktree you
are in (or the current symlink).
For a specific job: pwt jobs logs <job-id> [-f]
pwt self
Also available as versions, which.
Usage: pwt self [use <target>]
pwt versions (alias for 'pwt self')
Manage which pwt installation runs when you type 'pwt'.
Commands:
(none) List all installations; → marks the active one
use local Point ~/.local/bin/pwt at this script's own checkout
use <path> Point at a specific checkout (repo root or bin/pwt)
use npm Point at the npm-installed binary
use brew Point at the Homebrew binary
After switching, regenerate the shell wrapper (it hardcodes the path):
exec $SHELL # or: eval "$(pwt shell-init)"
pwt versions
Alias for pwt self.