npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jordyvanvorselen/pi-bare-worktrees

v0.1.2

Published

Git worktrees for --bare checkouts in pi: one worktree per task, shared env links, protected branches, and a worktree tool the agent uses itself.

Readme

pi-bare-worktrees

Git worktrees for --bare checkouts in pi. One worktree per task, shared env files linked in, protected branches kept read-only, and a worktree tool the agent calls itself.

What it does

  • Every change gets its own worktree. main and other protected branches are read-only. The first edit on them is blocked with a message that tells the model to call worktree create. It then continues in the new worktree without a cd.
  • Shared env, zero config. Every file under <root>/.shared-env/ is symlinked into each worktree at the same relative path. Real files are never overwritten.
  • Fast. No git process on session start or on tool calls. Root detection, worktree listing and link checks read the filesystem. Git runs only when you create, remove, clean, or in the background for the footer.
  • Native. The tool shows up in the system prompt, the footer shows the active worktree, state survives /resume, and subagents inherit the worktree.

Layout it expects

project/
├── .bare/            bare repo (core.bare = true)
├── .shared-env/      gitignored files to mirror, e.g. connect-backend/.env.keys
├── main/             worktree for main
└── feat/login/       worktree for feat/login

Path equals branch name. Create one with:

mkdir project && cd project
git clone --bare [email protected]:org/repo.git .bare
git --git-dir=.bare config remote.origin.fetch '+refs/heads/*:refs/remotes/origin/*'
git --git-dir=.bare fetch
git --git-dir=.bare worktree add main main

Outside this layout the extension turns itself off and says so once at startup.

Install

pi install npm:@jordyvanvorselen/pi-bare-worktrees

Then, inside a worktree:

/wt setup

Setup opens one screen with every setting prefilled: shared env directory, base branch, protected patterns, branch template, fetch before create, auto-link, post-create commands and copy list. Press Enter through the fields to keep the defaults, or type to edit a value in place. ↑↓ moves between fields, space toggles a yes/no field, ctrl+s saves from anywhere and esc cancels. It saves to .bare/config under [bare-worktrees] and runs doctor right away.

Commands

| Command | What it does | | ------------------------------------------ | ------------------------------------------------------------------------ | | /wt | Pick a worktree and switch the session into it | | /wt new <branch> [--from <ref>] [--move] | Create at <root>/<branch>, link env, run post-create, switch | | /wt use <branch> [--move] | Switch into an existing worktree | | /wt list | Worktrees with active and read-only marks | | /wt link | Re-sync shared env links into the active worktree | | /wt rm <branch> [--force] [--branch] | Remove a worktree, optionally its branch | | /wt clean | Fetch with prune, then pick which gone or missing worktrees to remove | | /wt doctor [--fix] | Missing links, conflicts, detached HEADs, prunable entries | | /wt sync | Move the session cwd into the active worktree after the model created it | | /wt on / /wt off | Enforcement for this session. Off needs a confirm | | /wt setup | Run the wizard again |

--move stashes uncommitted changes and pops them in the target.

The worktree tool

worktree({ action: "create" | "use" | "list" | "status" | "link" | "remove" | "doctor",
           branch?, from?, move?, force? })

After create or use, every built-in tool call is routed into that worktree: relative paths are resolved there and bash runs there. The model never needs cd. Run /wt sync when you want the session itself to move too.

Enforcement

| Call | Protected worktree | Feature worktree | | ------------------------------------------------------------- | ---------------------------- | ---------------- | | read, grep, find, ls | allow | allow | | bash: build, test, git status/log/diff | allow | allow | | bash: git commit/push/rebase/reset/..., rm, sed -i, > | block | allow | | bash: git worktree, git switch, git checkout <branch> | block | block | | edit, write | block | allow | | subagent | cwd set to active worktree | same |

Blocked calls return a reason that names the exact worktree create call to make. Bash detection is a regex over the command; it catches the common cases and is cheap. git checkout -- <file> is allowed.

Configuration

Per repo, in .bare/config:

[bare-worktrees]
	sharedEnv = .shared-env
	baseBranch = main
	protected = release/*
	branchTemplate = feat/{slug}
	fetchBeforeCreate = false
	postCreate = yarn install --immutable
	copy = .idea
	autoLink = true

Global, in ~/.pi/agent/pi-bare-worktrees.json:

{
  "warnWhenNotBare": true,
  "systemPrompt": true,
  "systemPromptFile": "/path/to/custom-section.md",
  "defaults": { "branchTemplate": "task/{slug}" }
}

systemPromptFile replaces the built-in <worktrees> section. Placeholders: {root} {active} {activePath} {state} {branchTemplate} {example} {baseBranch} {protected}.

Footer and other extensions

The extension publishes its state through ctx.ui.setStatus("wt", ...), which the built-in footer shows. In pi-powerline-footer add a custom item with "statusKey": "wt".

Text looks like ⎇ feat/login ↑2 ● or ⌂ main · ro. ↪ means tools are routed into a worktree the session cwd is not in.

For richer bars, subscribe on the shared bus:

pi.events.on("bare-worktrees:changed", (s) => {
  // { root, active: { branch, path, name, protected } | null, enforcement, routed,
  //   live: { dirty, ahead, behind, gone, missingLinks } | null }
});

Performance notes

  • Session start: one directory walk of .bare/worktrees/* and one lstat per shared file. About 5 ms for 40 worktrees and 12 shared files.
  • Tool calls: string operations only. Under 0.1 ms.
  • Dirty and ahead/behind run in the background after the agent settles, debounced, and stale results are dropped.
  • /wt clean is the only command that touches the network.

Development

npm install
npm run lint
npm run typecheck
npm test
pi -e ./src/index.ts

Run npm run lint:fix to fix lint and formatting problems.

Versioning and releases

This package follows semantic versioning. Every pull request must raise the version in package.json. CI fails the pull request when the version is not higher than on main.

Pick the bump that matches the change:

| Change | Command | Example | | ----------------------------------------------------- | ---------------------------------------- | --------------- | | Bug fix, docs, internal change | npm version patch --no-git-tag-version | 0.1.0 → 0.1.1 | | New feature or setting that keeps old behaviour | npm version minor --no-git-tag-version | 0.1.1 → 0.2.0 | | Breaking change, such as a removed or renamed setting | npm version major --no-git-tag-version | 0.2.0 → 1.0.0 |

The command updates both package.json and package-lock.json. Commit both files.

When a pull request merges, GitHub Actions runs the checks again and publishes the new version to npm. It then creates a GitHub release tagged with the version number, such as 0.1.2. GitHub generates the release notes from the merged pull requests.