git-worktree-manager 0.0.39

CLI tool integrating git worktree with AI coding assistants
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
//! Body of the `manage` skill — worktree management + health rulebook +
//! hook recommendation catalog.

pub fn content() -> &'static str {
    r#"---
name: manage
description: "Manage git worktrees safely across multiple parallel sessions. Auto-applies when the user invokes gw list/delete/clean/sync/merge/pr/resume."
allowed-tools: Bash, Read, Edit
---

# gw: manage

This skill helps you (Claude) operate the `gw` (git-worktree-manager) management
commands safely when the user is working across multiple parallel worktrees.
Use it whenever the user asks about listing, deleting, syncing, merging,
opening PRs, resuming sessions, or otherwise inspecting worktree state. It also
defines a health rulebook (problems to watch for) and a catalog of Claude Code
hooks you may suggest installing on the user's consent.

## 1. Command Guidance

These are the management-side commands. For full flag detail, see
`references/gw-commands.md` (auto-loaded next to this SKILL.md).

| Command | Purpose |
|---------|---------|
| `gw list` (alias `gw ls`) | List all worktrees with status indicators (active, clean, modified, stale). |
| `gw status` | Show detailed info about the current worktree. |
| `gw delete [target]` | Delete a worktree (and optionally its branch / remote branch). |
| `gw clean` | Batch cleanup of merged or stale worktrees, with `--dry-run` and `-i` selection. |
| `gw sync [branch]` | Rebase a worktree (or `--all`) against its base branch. |
| `gw merge [branch]` | Merge a feature branch into its base branch. |
| `gw pr [branch]` | Create a GitHub Pull Request from a worktree. |
| `gw resume [branch]` | Resume an AI session in a worktree (auto-uses `--continue` when possible). |
| `gw shell [worktree] [cmd...]` | Open an interactive shell in a worktree, or run a one-off command there. |
| `gw diff <a> <b>` | Compare two branches (full / `--summary` / `--files`). |
| `gw change-base <new> [branch]` | Move a worktree onto a different base branch. |
| `gw backup create/list/restore` | Create or restore a `git bundle` backup of a worktree. |
| `gw stash save/list/apply` | Worktree-aware stash that survives across worktrees. |
| `gw tree` | Visual tree of the worktree hierarchy. |
| `gw stats` | Worktree count, age, on-disk size. |

`gw new` (creating a worktree to delegate work into) is owned by the sibling
`delegate` skill — defer to that skill for new-task workflows.

For the full flag matrix, terminal launch methods, config keys, and helper
commands, read `references/gw-commands.md`.

## 2. Worktree-Health Rulebook

These rules apply when you (Claude) help the user with worktree commands.
Each rule names a symptom, why it hurts, what healthy looks like, how to
detect it, and what to suggest. Apply them proactively but quietly — surface
a concern once per session per rule, then drop it unless the user asks.

### Rule: Stale cwd / externally-deleted worktree

**Symptom:** The current working directory disappears mid-session because
another `gw` session ran `gw delete` on this worktree (or the user removed
it manually from another terminal).

**Why it hurts:** Every subsequent shell, git, or tool call fails with
"No such file or directory". `git push`, `npm publish`, `cargo publish`,
test runs, even a plain `ls` all break. The user wastes time diagnosing
what looks like permission/path bugs but is really a missing cwd.

**Healthy state:** `pwd` resolves to a real directory, and
`git rev-parse --show-toplevel` succeeds and matches a registered worktree
(visible in `gw status` / `gw list`).

**How to detect:** At session start, or as soon as a command fails with an
ENOENT-shaped error, run:

```bash
pwd && git rev-parse --show-toplevel
```

If either errors with "No such file or directory" (or `pwd` prints a path
that no longer exists), the cwd is gone.

**Suggested action:** Tell the user clearly that the worktree directory has
been removed underneath this session. Then either `cd` to the main repo
checkout, or run `gw new <branch>` to recreate the worktree from the same
branch and resume there. Do not attempt further work from the dead cwd.

### Rule: Wrong-base branching

**Symptom:** The user spawns a new worktree with `gw new fix-X` from `main`
when an in-flight feature branch should have been the base.

**Why it hurts:** When the parent feature branch later merges, the new
branch's diff includes those merged changes a second time. The user has
to rebase or cherry-pick to salvage clean history, and PR review surfaces
unrelated changes that confuse reviewers.

**Healthy state:** Every `gw new` call passes `--base <correct-branch>`
when the intended parent is *not* `main` (or the configured default base).

**How to detect:** Before running `gw new`, ask: is this work building on
top of another in-flight feature, or directly on the default base? Check
`gw list` for active feature branches that might be the intended parent.
If the new task's description references work happening on another branch,
that other branch is probably the right base.

**Suggested action:** Confirm the intended base with the user, then pass
`--base <branch>` explicitly to `gw new`. When in doubt, ask once rather
than guessing.

### Rule: Sibling worktree drift (pull-style awareness)

**Symptom:** The user starts work in worktree A, but a sibling worktree B
on the same base merged yesterday and A doesn't know.

**Why it hurts:** A is now N commits behind base. The eventual merge or PR
will require a rebase, or worse, ship code that silently relies on stale
assumptions about sibling work.

**Healthy state:** When starting work, the sibling base is up-to-date or
there is a clear "I will rebase later" plan that the user has acknowledged.

**How to detect:** At session start, run `gw list`. For each worktree on
the same base, check the lag both directions:

```bash
git log --oneline base..HEAD | wc -l   # commits ahead of base
git log --oneline HEAD..base | wc -l   # commits behind base
```

A non-trivial "behind" count (say, > 5) means drift worth surfacing.

**Suggested action:** Surface the drift in the session greeting, e.g.
"worktree A is 12 commits behind main; want me to `gw sync` it before we
start?" If multiple worktrees lag, suggest `gw sync --all`.

### Rule: Test/lint convention gap

**Symptom:** The project's `CLAUDE.md` is missing or doesn't list how to
run tests, lint, build, or format-check for this stack.

**Why it hurts:** Every fresh session re-derives commands, sometimes
guessing wrong (running `npm test` in a Cargo project, calling `pytest`
when the project uses `uv run pytest`, etc.). The result is "Command
Failed" errors that look like real bugs but are environmental, and
wasted iteration time.

**Healthy state:** `CLAUDE.md` has a one-line entry for each of: test,
lint, build, fmt-check (skipping any genuinely not used).

**How to detect:** At session start, read `CLAUDE.md` (or
`cat CLAUDE.md 2>/dev/null` if uncertain it exists). If it doesn't
mention a test runner, lint command, or build command appropriate to
detected stack files (`Cargo.toml` → cargo, `package.json` → npm/bun/pnpm,
`pyproject.toml` → pytest/uv, `go.mod` → go, etc.), the gap is real.

**Suggested action:** Ask the user once, "What's the canonical
test/lint/build invocation for this project? I'll write it into CLAUDE.md
so future sessions don't re-derive." On consent, edit `CLAUDE.md` (do
not silently rewrite it).

## 3. Recommended-Hooks Catalog

When a rule's suggested action is to add a Claude Code hook, pick from
this catalog. Each entry includes the JSON to write, the dependency (the
`gw` helper command it invokes), and the rationale. Edit the **project's**
`.claude/settings.json` (NOT `~/.claude/settings.json`) on user consent.

### Hook 1 — SessionStart sanity (primary)

The default recommendation. At session start, runs a fast sanity check
on the current cwd: validates that the directory exists, that it's a
registered gw worktree, that the configured base branch is reachable.
Cost is roughly ~5ms. Output is a single summary line. Directly addresses
the dominant friction (publish/test commands blocked because cwd was
removed by a sibling session).

```jsonc
{
  "hooks": {
    "SessionStart": [
      { "matcher": "*", "hooks": [
        { "type": "command", "command": "gw doctor --session-start --quiet" }
      ]}
    ]
  }
}
```

### Hook 2 — PreToolUse guard (advanced)

Parses the inbound bash command from the hook payload via stdin. If the
command matches a risky pattern (`git push`, `gh release`, `npm publish`,
`cargo publish`, `bun publish`, `pnpm publish`) AND the cwd looks
unhealthy (missing, unregistered, or significantly behind base), the hook
blocks the tool call with a clear explanation. Suggest only after the
user has expressed interest in stronger pre-publish safety — this hook
runs on every Bash invocation, so the latency budget matters.

```jsonc
{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash", "hooks": [
        { "type": "command", "command": "gw guard --tool-input -" }
      ]}
    ]
  }
}
```

### Hook 3 — Stop summary (optional)

Prints a single line of worktree state when a turn ends: "uncommitted N
files, base differs by X commits". Informational only — does not block
or modify anything. Mention only on direct request from the user; do not
volunteer it.

```jsonc
{
  "hooks": {
    "Stop": [
      { "matcher": "*", "hooks": [
        { "type": "command", "command": "gw status --on-stop --quiet" }
      ]}
    ]
  }
}
```

## 4. When to suggest, when to stop

Read this section before recommending any hook. It is addressed to you,
the in-session Claude.

- **Default behavior:** when running a worktree command and the
  SessionStart hook (Hook 1) is NOT present in the project's
  `.claude/settings.json`, suggest Hook 1 *once* in this session. If the
  user accepts, edit `.claude/settings.json` (project-local). If the user
  refuses, or the hook is already present in equivalent form, do NOT
  bring it up again in subsequent sessions — the file's contents are the
  implicit state record. Do not maintain a separate memory of "I asked
  already".
- **Hook 2** (PreToolUse guard): mention only after the user has
  expressed interest in stronger pre-publish safety after seeing Hook 1's
  value. Do not volunteer it unprompted on a fresh project.
- **Hook 3** (Stop summary): mention only on direct request.
- **NEVER** edit `~/.claude/settings.json` or
  `~/.claude/settings.local.json`. Always edit the project-local file at
  `.claude/settings.json` (creating it if absent).
- **NEVER** install a hook silently — always state what the hook does,
  show the JSON, and ask for explicit consent before writing.
- When applying changes to `.claude/settings.json`, **preserve any
  existing hooks the user has** — read the file, parse it, and add to
  the relevant `hooks.<Event>` array. Do not replace the file wholesale,
  do not overwrite unrelated keys, and do not deduplicate by removing
  hooks the user installed for other reasons.
- If `.claude/settings.json` exists but is malformed JSON, do not try to
  repair it silently — surface the parse error to the user and ask how
  they want to proceed.
"#
}

pub fn reference_content() -> &'static str {
    r#"# gw Command Reference

Complete reference for all gw (git-worktree-manager) commands.

## Core Worktree Management

### `gw new <branch> [OPTIONS]`
Create new worktree for feature branch.
- `-p, --path <PATH>` — Custom worktree path (default: `../<repo>-<branch>`)
- `-b, --base <BASE>` — Base branch to create from (default: from config or auto-detect)
- `--no-term` — Skip AI tool launch
- `-T, --term <METHOD>` — Terminal launch method. Accepts canonical name (e.g., `tmux`, `wezterm-tab`) or alias (e.g., `t`, `w-t`). Supports `method:session-name` for tmux/zellij (e.g., `tmux:mywork`). See Terminal Launch Methods section below.
- `--bg` — Launch AI tool in background
- `--prompt <PROMPT>` — Initial prompt as a CLI string (single-line, best for short prompts)
- `--prompt-file <PATH>` — Read initial prompt from a file (recommended for multi-line / quoted content)
- `--prompt-stdin` — Read initial prompt from standard input (for piping). Avoid combining with `-T <terminal>` — the spawned terminal may inherit a closed stdin.

Only one of `--prompt`, `--prompt-file`, `--prompt-stdin` may be used per invocation.

### `gw delete [target] [OPTIONS]`
Delete a worktree.
- `-k, --keep-branch` — Keep the branch (only remove worktree directory)
- `-r, --delete-remote` — Also delete the remote branch
- `--no-force` — Don't use --force flag
- `-w, --worktree` — Resolve target as worktree directory name
- `-b, --branch` — Resolve target as branch name

### `gw list`
List all worktrees with status indicators (active, clean, modified, stale). Alias: `gw ls`.

### `gw status`
Show detailed info about the current worktree.

### `gw resume [branch] [OPTIONS]`
Resume AI work in a worktree. Auto-detects existing Claude sessions and uses `--continue`.
- `-T, --term <METHOD>` — Terminal launch method (same format as `gw new`)
- `--bg` — Launch AI tool in background
- `-w, --worktree` — Resolve as worktree name
- `-b, --by-branch` — Resolve as branch name

### `gw shell [worktree] [COMMAND...]`
Open interactive shell in a worktree, or execute a command.
```bash
gw shell feature-x           # interactive shell
gw shell feature-x npm test  # run command
```

## Git Workflow

### `gw pr [branch] [OPTIONS]`
Create GitHub Pull Request from worktree.
- `-t, --title <TITLE>` — PR title
- `-B, --body <BODY>` — PR body
- `-d, --draft` — Create as draft PR
- `--no-push` — Skip pushing to remote
- `-w, --worktree` / `-b, --by-branch` — Target resolution

### `gw merge [branch] [OPTIONS]`
Merge feature branch into base branch.
- `-i, --interactive` — Interactive rebase
- `--dry-run` — Show what would happen
- `--push` — Push to remote after merge
- `--ai-merge` — Use AI to resolve merge conflicts
- `-w, --worktree` — Resolve as worktree name

### `gw sync [branch] [OPTIONS]`
Sync worktree with base branch (rebase).
- `--all` — Sync all worktrees
- `--fetch-only` — Only fetch without rebasing
- `--ai-merge` — Use AI to resolve conflicts
- `-w, --worktree` / `-b, --by-branch` — Target resolution

### `gw change-base <new-base> [branch] [OPTIONS]`
Change base branch for a worktree.
- `--dry-run` — Show what would happen
- `-i, --interactive` — Interactive rebase
- `-w, --worktree` / `-b, --by-branch` — Target resolution

### `gw diff <branch1> <branch2> [OPTIONS]`
Compare two branches.
- `-s, --summary` — Show statistics only
- `-f, --files` — Show changed files only

## Maintenance

### `gw clean [OPTIONS]`
Batch cleanup of worktrees.
- `--merged` — Delete worktrees for branches already merged to base
- `--older-than <DURATION>` — Delete worktrees older than duration (e.g., `7d`, `2w`, `1m`)
- `-i, --interactive` — Interactive selection
- `--dry-run` — Preview without deleting

### `gw doctor`
Run health check: git version, worktree accessibility, uncommitted changes, behind-base detection, merge conflicts, Claude Code integration.

### `gw upgrade`
Check for updates and install latest version from GitHub Releases.

### `gw tree`
Display worktree hierarchy as a visual tree.

### `gw stats`
Show worktree statistics (count, age, size).

## Backup & Stash

### `gw backup create [branch] [--all]`
Create git bundle backup of worktree(s).

### `gw backup list [branch] [--all]`
List available backups.

### `gw backup restore <branch> [--path <PATH>] [--id <ID>]`
Restore worktree from backup.

### `gw stash save [message]`
Save changes to worktree-aware stash.

### `gw stash list`
List stashes organized by worktree/branch.

### `gw stash apply <target-branch> [-s <stash-ref>]`
Apply stash to a different worktree.

## Configuration

### `gw config show`
Show current configuration.

### `gw config list`
List all configuration keys with descriptions.

### `gw config get <KEY>`
Get a config value. Keys use dot notation (see Key Config Keys section below).

### `gw config set <KEY> <VALUE>`
Set a config value. Key-specific valid values:
- `ai_tool.command` — Preset name (`claude`, `claude-yolo`, `claude-remote`, `claude-yolo-remote`, `codex`, `codex-yolo`, `no-op`) or any command name
- `launch.method` — Any terminal launch method name or alias (see Terminal Launch Methods)
- `update.auto_check` — `true` or `false`

### `gw config use-preset <NAME>`
Use a predefined AI tool preset: `claude`, `claude-yolo`, `claude-remote`, `claude-yolo-remote`, `codex`, `codex-yolo`, `no-op`.

### `gw config list-presets`
List available presets.

### `gw config reset`
Reset configuration to defaults.

## Hooks

### `gw hook add <EVENT> <COMMAND> [--id <ID>] [-d <DESC>]`
Add a lifecycle hook.

### `gw hook remove <EVENT> <HOOK_ID>`
Remove a hook.

### `gw hook list [EVENT]`
List hooks.

### `gw hook enable/disable <EVENT> <HOOK_ID>`
Toggle hook on/off.

### `gw hook run <EVENT> [--dry-run]`
Manually run hooks for an event.

**Available events:** `worktree.pre_create`, `worktree.post_create`, `worktree.pre_delete`, `worktree.post_delete`, `merge.pre`, `merge.post`, `pr.pre`, `pr.post`, `resume.pre`, `resume.post`, `sync.pre`, `sync.post`

## Export / Import

### `gw export [-o <FILE>]`
Export worktree configuration to JSON.

### `gw import <FILE> [--apply]`
Import configuration (preview by default, `--apply` to apply).

## Global Mode

Add `-g` or `--global` to any command to operate across all registered repositories.

### `gw -g list`
List worktrees across all registered repos.

### `gw scan [--dir <DIR>]`
Scan for and register git repositories.

### `gw prune`
Clean up stale registry entries.

## Shell Integration

### `gw shell-setup`
Interactive setup for shell integration (gw-cd function).

### `gw-cd [branch]`
Shell function to navigate to worktree by branch name. Supports:
- `gw-cd` — interactive selector
- `gw-cd feature-x` — direct navigation
- `gw-cd -g feature-x` — global (across repos)
- `gw-cd repo:branch` — repo-scoped navigation

## Terminal Launch Methods

Used with `-T` flag on `gw new` and `gw resume`. Supports `method:session-name` for tmux/zellij (e.g., `tmux:mywork`, `z:task1`).

| Method | Alias | Description |
|--------|-------|-------------|
| `foreground` | `fg` | Block in current terminal |
| `detach` | `d` | Fully detached process |
| `iterm-window` | `i-w` | iTerm2 new window |
| `iterm-tab` | `i-t` | iTerm2 new tab |
| `iterm-pane-h` | `i-p-h` | iTerm2 horizontal pane |
| `iterm-pane-v` | `i-p-v` | iTerm2 vertical pane |
| `tmux` | `t` | tmux new session |
| `tmux-window` | `t-w` | tmux new window |
| `tmux-pane-h` | `t-p-h` | tmux horizontal pane |
| `tmux-pane-v` | `t-p-v` | tmux vertical pane |
| `zellij` | `z` | Zellij new session |
| `zellij-tab` | `z-t` | Zellij new tab |
| `zellij-pane-h` | `z-p-h` | Zellij horizontal pane |
| `zellij-pane-v` | `z-p-v` | Zellij vertical pane |
| `wezterm-window` | `w-w` | WezTerm new window |
| `wezterm-tab` | `w-t` | WezTerm new tab |
| `wezterm-tab-bg` | `w-t-b` | WezTerm new tab (background, no focus steal) |
| `wezterm-pane-h` | `w-p-h` | WezTerm horizontal pane |
| `wezterm-pane-v` | `w-p-v` | WezTerm vertical pane |

## Key Config Keys

| Key | Description | Default |
|-----|-------------|---------|
| `ai_tool.command` | AI tool name or preset | `claude` |
| `ai_tool.args` | Additional arguments | `[]` |
| `launch.method` | Default terminal method | `foreground` |
| `launch.tmux_session_prefix` | tmux session prefix | `gw` |
| `launch.wezterm_ready_timeout` | WezTerm ready timeout (secs) | `5.0` |
| `update.auto_check` | Auto-check for updates | `true` |

## Helper Commands (for scripting and completion)

These hidden commands output newline-separated values, useful for scripting:
- `gw _config-keys` — List all config key names
- `gw _term-values` — List all valid `--term` values (canonical + aliases)
- `gw _preset-names` — List all AI tool preset names
- `gw _hook-events` — List all valid hook event names
- `gw _path --list-branches [-g]` — List worktree branch names
"#
}