
Security News
CVE Volume Surges Past 48,000 in 2025 as WordPress Plugin Ecosystem Drives Growth
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.
pfHuman- and agent-friendly Git multitasking. Powered by worktrees.
by @colinhacks
$ npm i -g pf
pf worksThere 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.
A workshell is an ephemeral worktree whose lifecycle is bound to a subshell.
Here's how it works (key points in bold).
pf open <branch> or create a new one with pf new <branch>..git/pf/worktrees) and opened in a fresh subshell.pf close. The associated worktree is auto-pruned.This approach has some nice properties.
git checkout/git switch changes your active branch for all terminals. With workshells, you can functionality open branches in the current tab only.pf open a branch even with uncommitted changes. When you exit the subshell, things will be exactly the same as they were. ☕️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.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.
$ npm i -g pf
Then clone a repo (any repo works):
$ git clone git@github.com:colinhacks/zod.git
$ cd zod
After cloning, the main branch is checked out. Let's say we want to start work on a new feature:
$ pf new feat-1
✓ feat-1 (from main)
Opened branch in ephemeral subshell at .git/pf/worktrees/zod@feat-1
Type 'pf close' to return.
You're now in a workshell. Check where you are:
$ pwd
/Users/colinmcd94/Documents/repos/zod/.git/pf/worktrees/zod@feat-1
$ git branch --show-current
feat-1
Now let's make some changes. (You can also open the repo in an IDE, start an agent run, etc.)
$ touch a.txt
Now let's try to close the workshell.
$ pf close
⚠ Uncommitted changes found. Commit, stash, or reset your changes first.
Or use --force/-f to discard changes
pf close -f
We aren't able to close because we have uncommitted changes. Let's commit them.
$ git add -A && git commit -am "Add a.txt"
Now we can try closing again. Since our changes can be fast-forwarded from the base branch, pf offers to auto-merge the changes.
$ pf close
✓ Back in main
Pruned worktree. Your changes are still in the 'feat-1' branch.
To merge your changes:
git merge feat-1
Auto-merge? (y/n/never) y
✓ Merged 'feat-1' into 'main'
pf v0.x.y - Human- and agent-friendly Git multitasking
Usage: pf <command> [options]
Commands:
new [branch] Create a branch and open it [--from <branch>]
open <branch> Open a branch in a workshell
close Exit current workshell
ls List orphaned worktrees
status Show current branch
rm <branch> Remove a branch's worktree
config Show or create config file
Options:
--help, -h Show help
--version, -v Show version
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.
$ pf ls
┌────────┬───────────┬───────────────┐
│ branch │ status │ created │
├────────┼───────────┼───────────────┤
│ main * │ clean │ - │
│ feat-1 │ 1 changed │ 5 minutes ago │
└────────┴───────────┴───────────────┘
You can open any existing Git branch in a workshell.
$ pf open feat-1
✓ feat-1 (existing worktree)
Type 'pf close' to return.
$ pf status
branch: main (root)
worktree: /path/to/zod
status: clean
Remove the worktree for a branch (the branch itself is kept):
$ pf rm feat-1
✓ Pruned worktree for feat-1
This closes the current workshell and auto-prunes the associated worktree. Your changes survive in your branch commits.
$ pf close
✓ Back in main
Pruned worktree. Your changes are still in the 'feat-1' branch.
To merge your changes:
git merge feat-1
Auto-merge? (y/n/never) y
✓ Merged 'feat-1' into 'main'
If the branch hasn't been pushed to a remote, you'll be prompted to auto-merge:
y — merge into base branchn — skip (branch is kept, merge manually later)never — permanently disable auto-merge promptThat command will fail if you have unstaged/uncommited changes. Use the --force/-f flag to force close the workshell; this will discard uncommitted changes.
$ pf close --force
pf.tomlTo print or create a config file:
$ pf config
✓ Config file: /path/to/repo/.git/pf.toml
────────────────────────────────────────────────────────────
setup = "npm install"
────────────────────────────────────────────────────────────
If no config exists, you'll be prompted to create one.
$ pf config
No config file found.
Where would you like to create one?
1. .git/pf.toml (local only, not committed)
2. pf.toml (project root, can be committed)
Choice (1/2): 1
✓ Created /path/to/repo/.git/pf.toml
pf.tomlYou can configure pf with a pf.toml file. This is useful for running setup scripts when opening a workshell (e.g., npm install).
pf looks for config files in the following order:
| Path | Description |
|---|---|
.git/pf.toml | Local only, not committed (highest precedence) |
pf.toml | Project root, can be committed |
# setup script executed in subshell after initialization
setup = "npm install && cp {{ repo_path }}/.env {{ worktree_path }}/.env"
The following variable substitutions are supported in setup.
| Variable | Description | Example |
|---|---|---|
{{ branch }} | Branch name | feature/auth |
{{ worktree_path }} | Absolute path to worktree | /path/to/repo/.git/pf/worktrees/repo@feat |
{{ repo_path }} | Absolute path to main repo | /path/to/repo |
FAQs
Agent- and human-friendly Git multitasking, powered by worktrees
We found that pf demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.

Security News
Socket CEO Feross Aboukhadijeh joins Insecure Agents to discuss CVE remediation and why supply chain attacks require a different security approach.

Security News
Tailwind Labs laid off 75% of its engineering team after revenue dropped 80%, as LLMs redirect traffic away from documentation where developers discover paid products.