Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "wt",
"owner": {
"name": "timvw"
},
"plugins": [
{
"name": "wt",
"source": "./plugins/wt",
"description": "Teaches Claude Code how to work with wt-managed git worktrees",
"version": "0.1.0"
}
]
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ go.work.sum
# OS
.DS_Store
Thumbs.db
wt
/wt
go.work.sum
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Inspired by [haacked/dotfiles/tree-me](https://github.com/haacked/dotfiles/blob/
- **Color-coded status output** — green (clean), red (dirty), yellow (ahead/behind), bold cyan (current); respects `NO_COLOR=1` and auto-strips colors when piped
- **CI/CD status integration** — `wt status --ci` shows pipeline status (✓/✗/●) per branch via `gh` or `glab` CLI
- **Per-repo `.wt.toml` config** — override global settings (strategy, hooks, etc.) on a per-repository basis
- **Claude Code plugin** — install with `claude plugin add timvw/wt` to teach Claude how to use wt commands and worktree workflows
- Shell integration with auto-cd functionality
- Tab completion for Bash and Zsh

Expand Down Expand Up @@ -140,6 +141,7 @@ In `json` mode, shell integration does **not** auto-navigate. For commands that
| [Examples](docs/examples.md) | Claude Code + tmux, multi-repo workflows, environment variables |
| [Installation](docs/installation.md) | All platforms, shell integration, building from source |
| [Development](docs/development.md) | Building, testing, running from source |
| [Claude Code Plugin](plugins/wt/) | Plugin that teaches Claude Code how to work with wt |

## How It Works

Expand Down
7 changes: 7 additions & 0 deletions plugins/wt/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "wt",
"description": "Teaches Claude Code how to work with wt-managed git worktrees",
"author": {
"name": "timvw"
}
}
174 changes: 174 additions & 0 deletions plugins/wt/skills/wt/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
---
name: wt
description: "This skill should be used when the user asks about 'wt', 'worktree', 'worktrees', 'wt create', 'wt checkout', 'wt list', 'wt remove', 'wt pr', 'wt mr', or mentions managing git worktrees with wt. Also use when the user asks how wt works, how to use wt commands, or how to organize branches with worktrees."
user-invocable: true
---

# Working with wt - Git Worktree Manager

wt is a fast Git worktree helper written in Go. It wraps `git worktree` with a convenient interface, organized directory structure, and smart defaults. Each branch gets its own directory — no stashing, no branch switching.

## Core Philosophy

**Never switch branches in the main checkout.** Always create a worktree for each task. This keeps the user's workspace clean and allows parallel work on multiple branches.

## Commands

| Command | Purpose |
|---------|---------|
| `wt create <branch> [base]` | Create a new branch in a worktree (defaults to main/master as base) |
| `wt co <branch>` | Checkout an existing branch in a new worktree |
| `wt co` | Interactive: fuzzy-search from available branches |
| `wt ls` | List all worktrees |
| `wt rm <branch>` | Remove a worktree |
| `wt rm` | Interactive: fuzzy-search worktree to remove |
| `wt pr [number\|url]` | Checkout a GitHub PR (requires `gh` CLI) |
| `wt pr` | Interactive: fuzzy-search from open PRs |
| `wt mr [number\|url]` | Checkout a GitLab MR (requires `glab` CLI) |
| `wt mr` | Interactive: fuzzy-search from open MRs |
| `wt status` | Color-coded overview of all worktrees |
| `wt status --ci` | Include CI/CD pipeline status per branch |
| `wt info` | Show active strategy, pattern, variables |
| `wt config show` | Show effective config with sources |
| `wt cleanup --stale` | Detect stale worktrees (deleted remotes, inactive commits) |
| `wt prune` | Clean up stale worktree admin files |
| `wt migrate` | Migrate worktrees to match configured paths |
| `wt init` | Configure shell integration |
| `wt examples` | Show practical examples |

## Worktree Layout Strategies

wt supports multiple strategies for organizing worktrees. Configure via `~/.config/wt/config.toml` or per-repo `.wt.toml`.

| Strategy | Layout |
|----------|--------|
| `global` | `<root>/<repo>/<branch>` — all repos share one root |
| `sibling-repo` | `../<repo>-worktrees/<branch>` — worktrees next to repo |
| `parent-branches` | `../<branch>` — branches as siblings of main checkout |

The `pattern` setting controls the path template. Variables: `{root}`, `{repo}`, `{branch}`, `{host}`, `{owner}`.

## Configuration

- Config file: `~/.config/wt/config.toml` (or `WT_CONFIG` / `--config`)
- Per-repo override: `.wt.toml` in the repo root
- Key settings: `root`, `strategy`, `pattern`, `separator`
- Env overrides: `WORKTREE_ROOT`, `WORKTREE_STRATEGY`, `WORKTREE_PATTERN`, `WORKTREE_SEPARATOR`

## Hooks

wt supports pre/post hooks for `create`, `checkout`, `remove`, `pr`, and `mr` commands.

Configure in `config.toml` or `.wt.toml`:

```toml
[hooks]
post_create = ["cp .env $WT_PATH/.env"]
post_checkout = ["echo 'Switched to $WT_BRANCH'"]
```

Hook environment variables: `WT_PATH`, `WT_BRANCH`, `WT_MAIN`, `WT_REPO_NAME`, `WT_REPO_HOST`, `WT_REPO_OWNER`. Disable all hooks: `WT_HOOKS_DISABLED=1`.

### Common Hook Recipes

**Copy `.env` files from main worktree:**

```toml
[hooks]
post_create = [
"test -f $WT_MAIN/.env && cp $WT_MAIN/.env $WT_PATH/.env || true"
]
post_checkout = [
"test -f $WT_MAIN/.env && cp $WT_MAIN/.env $WT_PATH/.env || true"
]
```

**Auto-install dependencies (Node.js):**

```toml
[hooks]
post_create = ["cd $WT_PATH && npm install"]
post_checkout = ["cd $WT_PATH && npm install"]
```

**Auto-install dependencies (Python/uv):**

```toml
[hooks]
post_create = ["cd $WT_PATH && uv sync"]
post_checkout = ["cd $WT_PATH && uv sync"]
```

**Launch Claude Code in tmux per worktree:**

```toml
[hooks]
post_create = [
"tmux new-session -d -s \"$WT_REPO_NAME/$WT_BRANCH\" -c \"$WT_PATH\" \"claude -n '$WT_REPO_NAME/$WT_BRANCH'\" 2>/dev/null; echo \"tmux session: $WT_REPO_NAME/$WT_BRANCH\""
]
pre_remove = [
"tmux kill-session -t \"$WT_REPO_NAME/$WT_BRANCH\" 2>/dev/null || true"
]
```

**Shared build cache (symlink `node_modules` across worktrees):**

```toml
[hooks]
post_create = [
"mkdir -p $HOME/.cache/wt/$WT_REPO_NAME/node_modules && ln -sf $HOME/.cache/wt/$WT_REPO_NAME/node_modules $WT_PATH/node_modules && cd $WT_PATH && npm install"
]
```

**Deterministic dev server port per branch:**

```toml
[hooks]
post_create = [
"printf 'PORT=%d\\n' $(( 3000 + $(printf '%s' \"$WT_BRANCH\" | cksum | cut -d' ' -f1) % 997 )) > $WT_PATH/.env.port"
]
```

## JSON Output

Most commands support `--format json` for machine-readable output:

```bash
wt --format json list
wt --format json info
wt --format json config show
wt --format json version
```

## Shell Integration

After `wt init`, the shell function auto-navigates to worktrees on create/checkout. As an agent, you won't get auto-cd — use the printed worktree path explicitly in subsequent operations.

## Agent Workflow

```bash
# 1. Create worktree for a task
wt create feat/my-feature

# 2. Work in the worktree directory (path printed by wt create)
# All file operations should use the worktree path

# 3. Run tests, commit, push from the worktree
go test ./...
git add . && git commit -m "feat: my feature"
git push -u origin feat/my-feature

# 4. Create PR
gh pr create --title "feat: my feature" --body "Description"

# 5. Clean up after merge
wt rm feat/my-feature
```

## When Helping Users

- If the user wants to work on a branch, suggest `wt create` or `wt co` instead of `git checkout`
- Use `wt ls` to understand the current worktree layout
- For PRs/MRs, use `wt pr` / `wt mr` — they resolve the branch name automatically
- Use `wt status` to get an overview of all worktrees and their state
- For non-interactive/agent contexts, always pass explicit arguments (e.g., `wt co <branch>`, not `wt co`)
39 changes: 39 additions & 0 deletions plugins/wt/skills/wt/skill-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
skill: wt:wt
model: haiku

tests:
- id: wt-explain
prompt: "explain what wt is and how to use it"
should_trigger: true

- id: wt-create-worktree
prompt: "how do I create a worktree for a new feature branch?"
should_trigger: true

- id: wt-checkout-pr
prompt: "how do I checkout a GitHub PR with wt?"
should_trigger: true

- id: wt-hooks-env
prompt: "how do I set up hooks in wt to copy .env files?"
should_trigger: true

- id: wt-hooks-npm
prompt: "how do I auto-run npm install when creating a worktree?"
should_trigger: true

- id: wt-hooks-uv
prompt: "can wt automatically run uv sync for new worktrees?"
should_trigger: true

- id: wt-strategies
prompt: "what worktree strategies does wt support?"
should_trigger: true

- id: unrelated-git-rebase
prompt: "how do I rebase my branch?"
should_trigger: false

- id: unrelated-docker
prompt: "how do I build a Docker image?"
should_trigger: false