@pify/worktree 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -17
- package/package.json +1 -1
- package/skills/worktree/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -1,41 +1,84 @@
|
|
|
1
1
|
# @pify/worktree
|
|
2
2
|
|
|
3
|
-
Safe git-worktree management for [pi](https://github.com/earendil-works/pi) — isolated workspaces for parallel or risky changes, with safety rails
|
|
3
|
+
Safe git-worktree management for [pi](https://github.com/earendil-works/pi) — isolated workspaces for parallel or risky changes, with safety rails on every destructive path and a clean merge-back flow. Windows-first: no tmux, no daemons, no shell interpolation.
|
|
4
4
|
|
|
5
5
|
Part of the [Pify suite](https://github.com/pifydev). Install with [`pify install worktree`](https://github.com/pifydev/cli) or `pi install npm:@pify/worktree`.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Why
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
- **`worktree_list`** — every worktree with branch, `primary`/`dirty`/`locked`/`prunable` flags.
|
|
11
|
-
- **`worktree_merge`** — with your confirmation: merges the worktree's branch into the primary branch, then removes the worktree. **Conflicting merges abort cleanly** — the primary is restored, nothing half-merged.
|
|
12
|
-
- **`worktree_remove`** — refuses the primary worktree, the one the session runs in, and locked ones outright; uncommitted changes need your explicit confirmation (fail-closed without a UI). The branch is always kept.
|
|
13
|
-
- **`/worktree enter <target>` / `/worktree exit`** (v0.3) — take the conversation into a worktree and back out again. See below.
|
|
14
|
-
- **`/worktree`** — `list` / `create <branch> [base] [--enter]` / `enter <target>` / `exit` / `remove <target>` / `merge <branch>` / `prune` for humans. Everything after the route is taken whole, so paths with spaces work (v0.2).
|
|
15
|
-
- **Targets resolve the way you'd name them** (v0.2): a branch, a path, a directory name, or — for worktrees created by `isolation: "worktree"` in `@pify/subagent`/`swarm`/`workflow` — the agent slug alone (`worker-1` finds branch `agent/worker-1`).
|
|
9
|
+
Two changes that touch the same files cannot share one checkout. The usual workarounds — stashing, branching back and forth, or just being careful — all fail the same way: work gets lost, or the main checkout ends up in a state nobody can build. A worktree gives each line of work its own directory and its own branch, and git already knows how to do it. What was missing was a way to drive it that refuses to destroy anything by accident, and a way to actually *go there* without abandoning the conversation.
|
|
16
10
|
|
|
17
|
-
##
|
|
11
|
+
## Tools
|
|
12
|
+
|
|
13
|
+
### `worktree_create`
|
|
14
|
+
|
|
15
|
+
| Parameter | Type | Notes |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| `branch` | string | A new branch, or an existing one not checked out anywhere |
|
|
18
|
+
| `base` | string, optional | Base ref for a new branch; defaults to HEAD |
|
|
19
|
+
|
|
20
|
+
Creates the worktree under `~/.worktrees/<repo>/<branch>` and reports the path and base commit. The main checkout is untouched. The result also says plainly that the agent's own tools still point at the main checkout — only you can move the session (see below).
|
|
21
|
+
|
|
22
|
+
### `worktree_list`
|
|
23
|
+
|
|
24
|
+
No parameters. Every worktree with its branch and `primary` / `dirty` / `locked` / `prunable` flags.
|
|
25
|
+
|
|
26
|
+
### `worktree_merge`
|
|
27
|
+
|
|
28
|
+
| Parameter | Type | Notes |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `branch` | string | Branch of the worktree to merge back |
|
|
31
|
+
|
|
32
|
+
With your confirmation: merges into the primary worktree's branch, then removes the worktree (keeping the branch). Both sides must be clean first. **A conflicting merge aborts cleanly** — the primary is restored and nothing is left half-merged.
|
|
33
|
+
|
|
34
|
+
### `worktree_remove`
|
|
35
|
+
|
|
36
|
+
| Parameter | Type | Notes |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `target` | string | Branch name or worktree path |
|
|
39
|
+
|
|
40
|
+
Refuses the primary worktree, the one this session runs in, and locked ones outright. Uncommitted changes require your explicit confirmation, and are refused outright when there is no UI to ask through. The branch itself is always kept.
|
|
41
|
+
|
|
42
|
+
## Entering a worktree
|
|
18
43
|
|
|
19
44
|
Creating a worktree used to be half the job. pi binds `read`, `edit`, `bash` and `@` completion to the session's working directory, and a session cannot change its own — so the worktree existed, and everything you had just discussed stayed in the terminal you were in.
|
|
20
45
|
|
|
21
|
-
`/worktree enter <branch|path>` forks the current session into the worktree and switches to it. The conversation comes along, the tools rebind, and the branch you were reading about is the branch you are now in. `/worktree exit`
|
|
46
|
+
`/worktree enter <branch|path>` forks the current session into the worktree and switches to it. The conversation comes along, the tools rebind, and the branch you were reading about is the branch you are now in. `/worktree exit` returns to the session you came from. `/worktree create <branch> --enter` does both in one step.
|
|
22
47
|
|
|
23
|
-
Two
|
|
48
|
+
Two refusals, each with a different fix:
|
|
24
49
|
|
|
25
50
|
- **`--no-session`** — entering forks a session file, so there has to be one.
|
|
26
|
-
- **A session pi
|
|
51
|
+
- **A session pi has not written yet** — pi keeps a session in memory until the agent has replied, so a brand-new session has nothing on disk to fork. Ask something first, or open the worktree in its own pi.
|
|
52
|
+
|
|
53
|
+
Session switching is a user command, so **the agent cannot move itself**. That is why `worktree_create` says so in its result instead of implying the tools followed it there.
|
|
54
|
+
|
|
55
|
+
## Command
|
|
27
56
|
|
|
28
|
-
|
|
57
|
+
`/worktree` — the same list as `worktree_list`.
|
|
58
|
+
`/worktree create <branch> [base] [--enter]` — create, optionally entering it.
|
|
59
|
+
`/worktree enter <branch|path>` — take the conversation into a worktree.
|
|
60
|
+
`/worktree exit` — return to the session you came from.
|
|
61
|
+
`/worktree remove <branch|path>` — remove, with the same rails as the tool.
|
|
62
|
+
`/worktree merge <branch>` — merge back and clean up.
|
|
63
|
+
`/worktree prune` — drop administrative records for worktrees whose directories are gone.
|
|
29
64
|
|
|
30
|
-
|
|
65
|
+
Everything after the route is taken whole, so paths with spaces work.
|
|
66
|
+
|
|
67
|
+
## Targets resolve the way you would name them
|
|
68
|
+
|
|
69
|
+
A branch, a full path, a directory name — or, for worktrees created by `isolation: "worktree"` in [`@pify/subagent`](https://github.com/pifydev/subagent), [`@pify/swarm`](https://github.com/pifydev/swarm) or [`@pify/workflow`](https://github.com/pifydev/workflow), the agent slug alone: `worker-1` finds branch `agent/worker-1`.
|
|
31
70
|
|
|
32
71
|
## Safety model
|
|
33
72
|
|
|
34
|
-
Every git call is an `execFile` argv — no shell, no string interpolation, ever. Branch names are validated against a restricted grammar (no leading `-`, no `..`, no ref tricks) before
|
|
73
|
+
Every git call is an `execFile` argv — no shell, no string interpolation, ever. Branch names are validated against a restricted grammar (no leading `-`, no `..`, no ref tricks) before they reach git.
|
|
74
|
+
|
|
75
|
+
Removal risk is assessed before anything happens: primary, current-session, locked, and dirty are four distinct verdicts, and only dirty is confirmable. Containment is checked on directory boundaries, so sitting in `feature-2` does not block removing `feature`.
|
|
76
|
+
|
|
77
|
+
Integration tests run the whole create → merge → remove flow, and the conflict-abort path, against real repositories rather than mocks.
|
|
35
78
|
|
|
36
79
|
## Where this sits in the suite
|
|
37
80
|
|
|
38
|
-
`@pify/subagent` and `@pify/swarm` run agents in
|
|
81
|
+
`@pify/subagent` and `@pify/swarm` run agents in place — shared files, which is fine for read-mostly work. Worktrees are the isolation layer for parallel **mutating** work, and all three of the agent packages can create one per child with `isolation: "worktree"`. A worktree whose child changed nothing is removed automatically; anything uncommitted is kept and reported.
|
|
39
82
|
|
|
40
83
|
## License
|
|
41
84
|
|
package/package.json
CHANGED
package/skills/worktree/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: worktree
|
|
3
|
-
description: Use when work should happen in isolation from the main checkout - risky refactors, parallel efforts, or long-running changes
|
|
3
|
+
description: Use when work should happen in isolation from the main checkout - risky refactors, parallel efforts, or long-running changes
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Git worktrees
|