pf 0.0.4 β†’ 0.0.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Pullfrog, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,57 +1,259 @@
1
- # pf
1
+ <p align="center">
2
+ <h1 align="center">🌲<br/><code>pf</code></h1>
3
+ <p align="center">Human- and agent-friendly Git multitasking. Powered by worktrees.
4
+ <br/>
5
+ by <a href="https://x.com/colinhacks">@colinhacks</a>
6
+ </p>
7
+ </p>
8
+ <br/>
2
9
 
3
- A humane utility for git worktrees.
10
+ <p align="center">
11
+ <a href="https://opensource.org/licenses/MIT" rel="nofollow"><img src="https://img.shields.io/github/license/pullfrog/pf" alt="License"></a>
12
+ <a href="https://www.npmjs.com/package/pf" rel="nofollow"><img src="https://img.shields.io/npm/dw/pf.svg" alt="npm"></a>
13
+ <a href="https://github.com/pullfrog/pf" rel="nofollow"><img src="https://img.shields.io/github/stars/pullfrog/pf" alt="stars"></a>
14
+ </p>
15
+
16
+ <br/>
17
+ <br/>
18
+ <br/>
4
19
 
5
20
  ## Install
6
21
 
22
+ ```bash
23
+ $ npm i -g pf
7
24
  ```
8
- npm i -g pf
25
+
26
+ <br/>
27
+
28
+ ## How `pf` works
29
+
30
+ There have been many attempts to nail a DX for parallel work in the agentic coding era. Most are thin wrappers over `git worktree`. Instead `pf` introduces a new paradigm: the *workshell*.
31
+
32
+ **A _workshell_ is an ephemeral worktree whose lifecycle is bound to a subshell.**
33
+
34
+ Here's how it works (key points in **bold**).
35
+
36
+ - You open a Git branch with `pf open <branch>` or create a new one with `pf new <branch>`.
37
+ - An ephemeral worktree is created for this branch (in `.git/pf/worktrees`) and **opened in a fresh subshell**.
38
+ - You are now in an fresh checkout of your repo that is isolated on disk. Make changes with your agent/editor of choice and commit them.
39
+ - You close the subshell with `pf close`. **The associated worktree is auto-pruned**.
40
+ - Your changes still exist on the associated branch, as Git commits/branches are shared among all worktrees. The worktree is destroyedβ€”but your commits aren't.
41
+
42
+ <!-- That's it. **Ephemeral worktrees whose lifecycle is bound to a subshell.** When the subshell exits, the worktree is destroyedβ€”but your commits aren't. -->
43
+
44
+ <!--
45
+ ## How does it work
46
+
47
+ There have been many attempts to nail a DX for parallel work in the agentic coding era. Most are thin wrappers over `git worktree`. That's not what `pf` is (though worktrees are used internally).
48
+
49
+ Here's how it works (key points in **bold**).
50
+
51
+ - **A fresh worktree is created** β€” The `pf` utility a) creates a new worktree in `.git/pf/worktrees` and b) opens it in a *subshell*.
52
+ - **Make edits and commit** β€” From the worksh your preferred IDE/agent.
53
+ - **Commit your changes** β€” Though your file system is isolated, Git commit history (including branches) is still shared among all worktrees.
54
+ - **Exit the subshell** β€” Run `pf close` to exit the subshell. As with `git switch`, `pf close` won't let you close the subshell if you have unstaged/uncommitted changes.
55
+ - **The worktree is auto-pruned** β€” This is key. The lifecycle of the worktree is tied to the subshell. When the subshell is closed, the worktree is destroyed. But *the commits you made inside the subshell* still exist.
56
+ - **Merge in your changes** β€” Merge/rebase your branch as you normally would, or push to GitHub to open a PR. -->
57
+
58
+ <br/>
59
+
60
+ ## Features
61
+
62
+ This approach has some nice properties.
63
+
64
+ - πŸ–₯️ **Tab-local workspaces** β€” Normally a `git checkout`/`git switch` changes your active branch for all terminals. With workshells, you can functionality open branches *in the current tab only*.
65
+ - 🌳 **Full isolation** β€” Each workshell is isolated on disk, so the changes you make don't interfere anything else you're doing.
66
+ - πŸ™…β€β™‚οΈ **Never stash again** β€” You can `pf open` a branch even with uncommitted changes. When you exit the subshell, things will be exactly the same as they were. β˜•οΈ
67
+ - πŸͺΎ **Consistent with branch semantics** β€” As with regular `git switch`, `pf close` won't let you close the subshell if you have unstaged/uncommitted changes. This is a feature, not a bug! Regular worktrees make it easy to lose your work in a forgotten corner of your file system.
68
+ - πŸ€– **Agent-ready** β€” Spin up parallel workshells so multiple agents can work simultaneously without conflicts.
69
+
70
+ <br/>
71
+
72
+ ## Quickstart
73
+
74
+ This section is entirely linear and self-contained. Try running all these commands in order to get a feel for how `pf` works. First, install `pf`.
75
+
76
+ ```bash
77
+ $ npm i -g pf
9
78
  ```
10
79
 
11
- ## Usage
80
+ <br/>
81
+
82
+ Then clone a repo (any repo works):
12
83
 
84
+ ```bash
85
+ $ git clone git@github.com:colinhacks/zod.git
86
+ $ cd zod
13
87
  ```
14
- pf <command> [options]
15
88
 
16
- Commands:
17
- new [name] Create a branch and worktree with the specified name (default: "pf-[hash]")
18
- open <name> Open a worktree in a subshell
19
- ls List all tracked worktrees
20
- rm <name> Remove a worktree
89
+ <br/>
21
90
 
22
- Options:
23
- --help, -h Show help
24
- --version, -v Show version
91
+ After cloning, the `main` branch is checked out. Let's say we want to start work on a new feature:
92
+
93
+ ```bash
94
+ $ pf new feat-1
95
+
96
+ βœ“ feat-1 (from main)
97
+ Opened branch in ephemeral subshell at .git/pf/worktrees/zod@feat-1
98
+ Type 'pf close' to return.
25
99
  ```
26
100
 
27
- ## Why `pf`?
101
+ <br/>
102
+
103
+ You're now in a workshell. Check where you are:
104
+
105
+ ```bash
106
+ $ pwd
107
+ /Users/colinmcd94/Documents/repos/zod/.git/pf/worktrees/zod@feat-1
108
+
109
+ $ git branch --show-current
110
+ feat-1
111
+ ```
112
+
113
+ <br/>
114
+
115
+ Now let's make some changes. (You can also open the repo in an IDE, start an agent run, etc.)
116
+
117
+ ```bash
118
+ $ touch a.txt
119
+ ```
120
+
121
+ <br/>
122
+
123
+ Now let's try to close the workshell.
28
124
 
29
- In agentic development, you often want to spin up isolated workspaces for specific tasksβ€”without stashing or committing your current changes. pf makes this effortless.
125
+ ```bash
126
+ $ pf close
127
+ ⚠ Uncommitted changes found. Commit, stash, or reset your changes first.
128
+ Or use --force/-f to discard changes
129
+ pf close -f
130
+ ```
131
+
132
+ <br/>
30
133
 
31
- Create a new worktree for a task:
134
+ We aren't able to close because we have uncommitted changes. Let's commit them.
32
135
 
136
+ ```bash
137
+ $ git add -A && git commit -am "Add a.txt"
33
138
  ```
34
- $ pf new add-login-button
139
+
140
+ <br/>
141
+
142
+ Now we can try closing again. Since our changes can be fast-forwarded from the base branch, `pf` offers to auto-merge the changes.
143
+
144
+ ```bash
145
+ $ pf close
146
+ βœ“ Back in main
147
+ Pruned worktree. Your changes are still in the 'feat-1' branch.
148
+ To merge your changes:
149
+ git merge feat-1
150
+
151
+ Auto-merge? (y/n/never) y
152
+
153
+ βœ“ Merged 'feat-1' into 'main'
35
154
  ```
36
155
 
37
- This creates a branch and worktree, then drops you into a subshell. Open it in your editor or point an AI coding agent at it. Your changes are completely independent of any other work on your machine.
156
+ <br/>
157
+
158
+ ## CLI
159
+
160
+ ```sh
161
+ pf v0.x.y - Human- and agent-friendly Git multitasking
38
162
 
39
- When you're done, push to GitHub and create a PR:
163
+ Usage: pf <command> [options]
40
164
 
165
+ Commands:
166
+ new [branch] Create a branch and open it [--from <branch>]
167
+ open <branch> Open a branch in a workshell
168
+ close Exit current workshell
169
+ ls List orphaned worktrees
170
+ status Show current branch
171
+ rm <branch> Remove a branch's worktree
172
+
173
+ Options:
174
+ --help, -h Show help
175
+ --version, -v Show version
41
176
  ```
42
- $ git push -u origin add-login-button
177
+
178
+ <br />
179
+
180
+ ### List orphaned worktrees
181
+
182
+ Normally the worktree will be auto-pruned when you close its associated workshell. If a worktree is left behind for some reason, you can list them with `pf ls`.
183
+
184
+ ```sh
185
+ $ pf ls
186
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
187
+ β”‚ branch β”‚ status β”‚ created β”‚
188
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
189
+ β”‚ main * β”‚ clean β”‚ - β”‚
190
+ β”‚ feat-1 β”‚ 1 changed β”‚ 5 minutes ago β”‚
191
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
43
192
  ```
44
193
 
45
- Or merge directly back into main:
194
+ <br />
195
+
196
+
197
+ ### Open a branch in a workshell
46
198
 
199
+ You can open any existing Git branch in a workshell.
200
+
201
+ ```sh
202
+ $ pf open feat-1
203
+
204
+ βœ“ feat-1 (existing worktree)
205
+ Type 'pf close' to return.
47
206
  ```
48
- $ git checkout main && git merge add-login-button
207
+
208
+ <br />
209
+
210
+ ### Show current branch status
211
+
212
+ ```sh
213
+ $ pf status
214
+ branch: main (root)
215
+ worktree: /path/to/zod
216
+ status: clean
49
217
  ```
50
218
 
51
- Then just `exit` to pop out of the worktree and back to your main repo. Clean up when you're done:
219
+ <br />
52
220
 
221
+ ### Remove a worktree
222
+
223
+ Remove the worktree for a branch (the branch itself is kept):
224
+
225
+ ```sh
226
+ $ pf rm feat-1
227
+
228
+ βœ“ Pruned worktree for feat-1
53
229
  ```
54
- $ pf rm add-login-button
230
+
231
+ <br />
232
+
233
+ ### Closing a workshell
234
+
235
+ This closes the current workshell and auto-prunes the associated worktree. Your changes survive in your branch commits.
236
+
237
+ ```sh
238
+ $ pf close
239
+ βœ“ Back in main
240
+ Pruned worktree. Your changes are still in the 'feat-1' branch.
241
+ To merge your changes:
242
+ git merge feat-1
243
+
244
+ Auto-merge? (y/n/never) y
245
+
246
+ βœ“ Merged 'feat-1' into 'main'
55
247
  ```
56
248
 
57
- Use `pf ls` to see your active worktrees, and `pf open <name>` to return to one later.
249
+ If the branch hasn't been pushed to a remote, you'll be prompted to auto-merge:
250
+
251
+ - `y` β€” merge into base branch
252
+ - `n` β€” skip (branch is kept, merge manually later)
253
+ - `never` β€” permanently disable auto-merge prompt
254
+
255
+ That command will fail if you have unstaged/uncommited changes. Use the `--force`/`-f` flag to force close the workshell; **this will discard uncommitted changes**.
256
+
257
+ ```sh
258
+ $ pf close --force
259
+ ```