macOS dev environment focused on a GitHub-issue → git-worktree → Claude Code workflow.
dotfiles_video.mov
Custom shell functions live in functions/. bootstrap.sh symlinks the directory to ~/.zsh_functions/, and .zshrc auto-sources every *.zsh file inside it.
Sandbox-oriented successor to the ghwt session layer. Ghostty stays your terminal; Herdr holds the agent session. Optional Cloudflare Sandbox provisions a remote preview/dev env. When work is done, ghsb finish runs the full review handoff.
ghsb [-c] [-f] [-b <branch>] [-i <N>] [--local|--cf] "Issue title"
ghsb finish [session-id]
ghsb review <pr-number> # same as ghsbpr
ghsb status|attach|links|list|rm [session-id]| Piece | Role |
|---|---|
| Ghostty | Terminal UI (unchanged) |
| Herdr | Persistent agent panes (cockpit) |
| Local worktree | Same ~/.claude/worktrees/{repo}-{N} as ghwt |
Cloudflare Sandbox (--cf) |
Remote clone + dev server + preview URL |
ghsb finish |
PR → Playwright video (if UI) → pr-review → ranked files → links |
Finish pipeline (run after the agent pushes, or tell the agent to run it):
- Push branch and ensure a PR exists
- Rank changed files for manual review (
~/.ghsb/artifacts/.../files-to-review.txt) - If user-facing paths changed and a preview/dev URL exists → Playwright walkthrough video
- Launch pr-review agent in Herdr (
/review-pror/pr-review-toolkit:review-pr) - Print PR, github.dev, VS Code web, dev env, and PR preview links
# Local Herdr session (default)
ghsb "Add dark mode"
# Also provision CF preview sandbox (needs deploy + env)
export GHSB_API_URL="https://ghsb-sandbox.<you>.workers.dev"
export GHSB_API_TOKEN="…"
ghsb --cf -i 42
ghsb finish # from the worktree, or: ghsb finish myrepo-42
ghsb linksCloudflare Worker lives in sandbox/ — see sandbox/README.md. Session state: ~/.ghsb/sessions/.
Agents use permission-mode auto (not always-approve).
Source: functions/ghsb.zsh, functions/_ghsb_common.zsh, scripts/ghsb-record-preview.mjs.
Architecture A sibling of ghwtpr: checkout a PR, rank files for manual review, launch pr-review in Herdr, print links.
ghsbpr <pr-number>
ghsb review <pr-number> # sameSource: functions/ghsbpr.zsh.
Classic workflow. One command turns an idea into a checked-out worktree with an agent in tmux (or the current terminal).
ghwt [-c] [-f] [-b <branch>] [-i <number>] "Issue title"| Flag | Description |
|---|---|
-c, --current |
Branch from the current branch (default: repo's default branch). |
-b <branch> |
Use an existing branch instead of creating one. |
-f, --fork |
Target the fork's own issue tracker instead of upstream (forks only). |
-i <number> |
Develop an existing issue instead of creating a new one. |
What it does:
- Detects whether you're in a fork (compares
originURL with whatghresolves) and routes issue creation to the upstream repo if so. Pass-f/--forkto instead create/reuse issues on the fork itself;-i <N>then resolves against whichever target is in effect. - Fetches all remote refs.
- Creates the issue (or reuses
-i <N>) and creates the branch — viagh issue developfor direct repos, or manually for forks. - Creates a worktree at
~/.claude/worktrees/{repo}-{issue-number}. - Runs
_worktree_setup— executes."setup-worktree"[]from.cursor/worktrees.jsonif present, otherwise copies.env.local,.dev.vars, andlocal.dbif they exist. - Calls
splt(opens Cursor at the worktree, tiles left, shows the PICK ME banner), then launchesclaude --permission-mode plan "Implement GitHub issue #N..."in a new tmux window if$TMUXis set, otherwise in the current terminal.
Source: functions/ghwt.zsh.
ghwtrm [<issue-number>]Removes the worktree at ~/.claude/worktrees/{repo}-{N} and prunes the branch metadata. With no argument it auto-detects the issue number by parsing the current working directory, so you can just run ghwtrm from inside the worktree you want to clean up.
Source: functions/ghwtrm.zsh.
ghwtb [-c] [-b <branch>] [<branch-name-or-description>]Same worktree + Cursor + Claude/Grok flow as ghwt, but skips GitHub issue creation. Creates a new branch (or reuses an existing one), checks it out at ~/.claude/worktrees/{repo}-{sanitised-branch}, and launches the AI agent. Pass a description with spaces to auto-slugify the branch name (e.g. "Add dark mode" → add-dark-mode).
| Flag | Description |
|---|---|
-c, --current |
Branch from the current branch (default: repo's default branch). |
-b <branch> |
Use an explicit branch name; any remaining text is passed to the AI as context. |
Source: functions/ghwtb.zsh.
wt <branch-name>Same worktree + Cursor + Claude flow as ghwt, but for a branch that isn't tied to a GitHub issue. Fetches the branch from origin if it isn't local, sanitises slashes and other shell-unfriendly characters, and creates a worktree at ~/.claude/worktrees/{repo}-{sanitised-branch}.
Source: functions/wt.zsh.
ght [command...]Opens a new Ghostty window in $PWD. If a command is supplied, it runs it after opening. Reuses a running Ghostty instance via osascript instead of launching a second app.
Source: functions/ght.zsh.
spltBig yellow ASCII banner used by ghwt so it's obvious which terminal to look at while Cursor opens. Opens Cursor at the current directory (or a path you pass), then tiles that window to the left half of the screen. Press Enter to dismiss.
Source: functions/splt.zsh.
functions/_worktree_setup.zsh and functions/_cursor_tile_left.zsh are sourced by the commands above and aren't meant to be called directly.
git clone https://github.com/tombeckenham/dotfiles.git ~/dotfiles
cd ~/dotfiles
./bootstrap.shOpen a new terminal afterwards so the shell config loads.
Prerequisites: macOS, your admin password (the script calls sudo pmset), and a browser for the GitHub OAuth login that runs partway through.
bootstrap.sh is idempotent — re-run it any time you pull new changes.
- Installs Xcode Command Line Tools and Homebrew if either is missing.
- Runs
brew bundleagainstBrewfile— installs starship, fnm, pnpm, pyenv, gh, jq, gnupg, lefthook, tmux, zoxide, pinentry-mac, doppler, plus the Ghostty, Cursor and OrbStack casks. - Clones Antidote (zsh plugin manager) into
~/.antidote. - Symlinks
.zshrc,.zsh_plugins.txt,starship.toml,gpg.conf,gpg-agent.confandfunctions/into$HOME(and~/.config,~/.gnupg). - Authenticates
ghwith theuserandwrite:gpg_keyscopes (refreshes the token if those scopes aren't already granted). - Configures git globally: LFS filters,
commit.gpgsign=true,tag.gpgSign=true, andgh auth setup-gitfor HTTPS token auth. - If git identity isn't set, prompts for name/email (auto-detected from existing config and the GitHub API), offers to generate an Ed25519 GPG signing key, and registers the key with GitHub via
gh gpg-key add. - Installs Node LTS via
fnm, Python 3.12 viapyenv, and Bun via the official installer. bun install -g vercel wrangler, then installs the Claude Code, OpenCode, and Grok Build CLIs.pmsetfor always-on server mode (sleep 0,displaysleep 5,autorestart 1).lefthook install— wires up the pre-commit secret scanner fromlefthook.yml.
.zshrc— loads Antidote plugins, sets up the Starship prompt, initialises zoxide (z,zi), adds Bun / pnpm / fnm toPATH, lazy-loads pyenv on firstpython/pipuse, and auto-sources every*.zshfile in~/.zsh_functions/..zsh_plugins.txt—zsh-autosuggestions,zsh-syntax-highlighting,zsh-completions,zsh-history-substring-search, plus thegit,node,npmandmacosohmyzsh plugin paths.starship.toml— fast prompt: directory (truncated to repo root), git branch and status, command duration if it took longer than 2s. Language modules are disabled to keep prompt rendering quick.gpg.conf/gpg-agent.conf—auto-key-retrieve,pinentry-mac, 10-minute default cache (2-hour max).lefthook.yml— pre-commit hook that greps staged files for private keys, OpenAI keys (sk-…), GitHub tokens (ghp_…) and PEM headers, and blocks the commit if any are found.
.
├── bootstrap.sh # Installer (run once, safe to re-run)
├── Brewfile # Homebrew packages
├── .zshrc # Shell config
├── .zsh_plugins.txt # Antidote plugin list
├── starship.toml # Prompt
├── gpg.conf # GPG settings
├── gpg-agent.conf # GPG agent
├── lefthook.yml # Pre-commit hooks
├── scripts/
│ └── ghsb-record-preview.mjs # Playwright PR preview video
├── sandbox/ # Cloudflare Sandbox Worker for ghsb --cf
└── functions/ # Custom zsh commands
├── ghsb.zsh
├── ghsbpr.zsh
├── _ghsb_common.zsh
├── ghwt.zsh
├── ghwtb.zsh
├── ghwtpr.zsh
├── ghwtrm.zsh
├── wt.zsh
├── ght.zsh
├── splt.zsh
├── _worktree_setup.zsh
└── _cursor_tile_left.zsh
- macOS only — uses
xcode-select,pmset,osascript,pinentry-macand/opt/homebrewpaths. bootstrap.shcallssudo pmsetto keep the machine awake. Remove that block if you don't want always-on power management.ghwt,ghwtb, andwtassume Claude Code is installed and onPATH(bootstrap.shinstalls it). Worktrees live under~/.claude/worktrees/.- If you fork this repo, prune
Brewfileand skip the steps inbootstrap.shyou don't want (Vercel, Wrangler, OpenCode, Grok, GPG key generation, etc.).