otty-wt
v0.1.1
Published
git worktree manager for the Otty terminal — fuzzy-pick a branch or PR, create a worktree, copy your gitignored files, open it as an Otty tab.
Maintainers
Readme
wt — git worktree manager for Otty
wt makes git worktrees effortless. Run it,
fuzzy-pick a local branch, a remote branch, or an open PR, and wt creates a worktree,
copies over the gitignored files you actually need (.env, agent config, …), and opens
it as a new tab in the Otty terminal — focusing the existing tab if
the worktree is already open.
wt pick a branch / PR → create worktree → open Otty tab
wt ls list worktrees with live state
wt rm pick a worktree to remove (deletes its branch too)
wt rm . remove the worktree you're standing in
wt doctor check dependencies, offer to install missing ones
wt help usageRequirements
- macOS with the Otty terminal installed (Otty is required —
wtopens every worktree as an Otty tab and refuses to run if theottyCLI is missing). gitandfzf.- Optional:
gh(to list/checkout open PRs) andjq(to focus an already-open tab instead of opening a duplicate).
Run wt doctor to see what's installed. If a required tool is
missing, wt offers to install it for you with Homebrew (it only ever asks — it never
installs anything without your say-so, and falls back to a brew install … hint when
Homebrew isn't available).
wt itself is a zsh script — it runs fine no matter which interactive shell you use, as
long as zsh is present (it ships with macOS).
Install
npm install -g otty-wtThis installs a single wt command. To upgrade: npm update -g otty-wt. To remove:
npm uninstall -g otty-wt.
Prefer not to use npm? Copy
bin/wtanywhere on yourPATH,chmod +xit, done.
Per-repo setup (optional)
There's nothing to configure globally. The one optional step is per repository: if you
want wt to carry your gitignored files (.env, local config, agent settings) into each
new worktree, add a .worktrees file at the repo's root — the top-level directory
that contains .git, alongside your .gitignore:
cd your-repo # the main checkout
$EDITOR .worktrees # list what to copy (see "The .worktrees copy list" below)
git add .worktrees # commit it so the whole team gets the same behaviorNo .worktrees file? wt still works — it just skips the copy step. After that, run
wt from anywhere inside the repo.
Usage
Create / open a worktree
wtOpens an fzf picker listing branches and open PRs you can branch from — locals, remotes
(without a local counterpart), and open PRs — ordered by most recent activity. The
preview pane shows the latest commit (or the PR summary). Pick one and wt:
- creates a worktree at
$WT_ROOT/<repo>/<branch>(default~/worktrees/<repo>/<branch>), - copies the files listed in
.worktrees(see below), - opens it as a new Otty tab — or focuses the existing tab if it's already open.
Branches already checked out in a worktree are hidden from the picker (use wt ls for
those). For a PR, wt checks it out with gh pr checkout.
List worktrees
wt ls BRANCH SHA STATE PATH
main a1b2c3d ◉ ~/code/app
● feature e4f5g6h ◉✱ ↑2 ~/worktrees/app/feature
hotfix i7j8k9l ↓1 ~/worktrees/app/hotfixThe main checkout is pinned first (and shown in green); the rest follow most-recently-
edited first. ● marks the worktree you're currently in. STATE: ◉ open in an Otty
tab · ✱ has uncommitted changes · ↑N/↓N commits ahead/behind upstream.
Remove a worktree
wt rm # fuzzy-pick a worktree to remove
wt rm . # remove the worktree your shell is currently insideRemoves the worktree and deletes its branch (safely — it asks before discarding
uncommitted changes or unmerged commits). Removing the worktree you're standing in works;
wt runs git from the main checkout, then reminds you to cd out of the now-deleted
directory.
Check your setup
wt doctorwt doctor — dependency check
✓ otty /Applications/Otty.app/Contents/MacOS/otty-cli
✓ git /opt/homebrew/bin/git
✓ fzf /opt/homebrew/bin/fzf
○ gh optional — list & checkout PRs in the picker
install: brew install gh
✓ jq /opt/homebrew/bin/jq
required: Otty + git + fzf · optional: gh, jqReports every dependency and, for anything missing, offers to brew install it (or prints
the command to run). ✓ present · ✗ required but missing · ○ optional and missing.
Otty itself isn't a Homebrew formula, so wt doctor points you to https://otty.sh rather
than offering to install it.
The .worktrees copy list
A fresh worktree doesn't carry your gitignored files — .env, local config, agent
settings — so the code won't run until you copy them in. Put a .worktrees file at your
repo's root — the top-level directory that holds .git, next to .gitignore — listing
what to copy. One glob per line, matched against the main checkout and copied into the
new worktree with paths preserved. # starts a comment; a trailing /** means "the whole
directory".
.env* # env files in the repo root
*/.env* # env files one level deep (app/, mobile/, …) — skips node_modules
.claude/CLAUDE.md
.claude/settings*.json
.claude/memory/**
.claude/skills/**Copies use APFS clonefile (cp -c) when possible, so they're cheap. No .worktrees
file? wt just skips the copy step.
Configuration
All optional environment variables:
| Variable | Default | Purpose |
| --------------- | -------------- | ------------------------------------------------------------- |
| WT_ROOT | ~/worktrees | Where worktrees are created ($WT_ROOT/<repo>/<branch>). |
| WT_REMOTE | origin | Remote used to list/track remote branches. |
| WT_OPEN | tab | tab or window — how new worktrees open in Otty. |
| WT_OTTY | auto-detected | Explicit path to the otty CLI, if it isn't auto-found. |
| WT_COPY_FILE | .worktrees | Name of the per-repo copy-list file. |
wt finds the otty CLI automatically (live session binary, the standard install
locations, then the app bundle). Set WT_OTTY only if yours lives somewhere unusual.
