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

pi-permission-modes

v2.7.2

Published

Switchable, user-definable permission modes for the pi coding agent. Each mode pairs an OS-level sandbox (bubblewrap, sandbox-exec, native Windows) with an allow / ask / deny policy for every tool. Default, Plan Mode, Build and YOLO ship; retune them or a

Readme

pi-permission-modes

CI License: MIT

Switchable, user-definable permission modes for the pi coding agent. A mode bundles an OS-level sandbox profile with an allow / ask / deny policy for every tool the agent has. Four modes ship by default - Default -> Plan Mode -> Build -> YOLO - and you can retune them or add your own.

It is the most complete integration of Anthropic's sandbox-runtime for pi, with the usability work on top: one keystroke switches the mode, network prompts pause the command instead of failing it, the model is told its boundaries so it works within them, and every blocked step points at the documentation that explains it. Linux (including WSL2), macOS and Windows are supported.

pi in Build mode asking before a read outside the project: Allow once, Allow for session, Deny, Deny and block; the footer shows the sandboxed mode, the filtered network and two background shells

The complete reference lives in docs/ and ships with the extension, so the agent can read it too. SECURITY.md has the threat model, CHANGELOG.md the releases, and CONTRIBUTING.md how to hack on it.

Quick start

pi install npm:pi-permission-modes

On Linux (including WSL2) the sandbox also needs three system packages on PATH:

# Debian / Ubuntu / WSL2
sudo apt install -y bubblewrap socat ripgrep

Verify

  1. Start pi in any project - the footer shows a mode indicator, e.g. Default.
  2. Switch to Build (alt+m until Build, or /perm build):
    • sandbox active -> Build (sandboxed in project dir);
    • otherwise -> Build (!) sandbox-runtime missing ... plus a fix-it notification.
  3. /sandbox prints the active sandbox configuration (or why it's unavailable).

Install

pi install fetches the package and runs npm install for you, so @anthropic-ai/sandbox-runtime comes along automatically; the pi SDK is provided by the host. Node 22.12 or newer is required (pi itself needs 22.19).

Other install methods

  • pi install git:github.com/wynainfo/pi-permission-modes - straight from GitHub (the latest release)
  • pi install npm:[email protected] - pin a version (pi update --extensions won't advance it)
  • pi install git:github.com/wynainfo/pi-permission-modes@dev - the development branch; may break between releases
  • pi install -l npm:pi-permission-modes - project-local install (.pi/npm/, shareable with your team)
  • pi update --extensions - pull the latest release, whichever way you installed

Platform notes

Linux. Ubuntu 24.04 and newer (desktop and server; WSL2 images usually do not) restrict unprivileged user namespaces through AppArmor, and every sandboxed command fails with bwrap: ... Operation not permitted. Nothing runs unsandboxed. The fix is a small AppArmor profile or one sysctl: docs/troubleshooting.md. WSL1 has no user namespaces at all; the sandbox reports it as unsupported.

macOS. The sandbox uses the built-in sandbox-exec - no extra packages. Go tools (gh, kubectl, terraform) need an opt-in switch per mode (docs/sandbox.md); loopback services and local ports are open unless a mode turns sandbox.allowLocalBinding off (docs/sandbox.md).

Windows (alpha). The sandbox is the runtime's native Windows backend: commands run as a separate local account behind a firewall rule keyed on it, with the profile as NTFS permissions. It needs Git for Windows and one /sandbox install in pi (one UAC prompt, then one question: whether your user profile is readable to sandboxed commands, minus the credential stores). Until then the sandboxed modes degrade to prompting only. Details and limits: docs/sandbox.md.

Modes

The table describes the shipped defaults; every mode is data and can be retuned, and you can add your own (docs/modes.md).

| Mode | Behavior | |------|----------| | Default | Confirm every bash/edit/write; reads are free. Approved in-project bash runs sandboxed (writes confined to the project). | | Plan Mode | Reads are free; in-project bash runs sandboxed read-only, so only read commands work. The one mutation allowed without confirmation is creating or editing Markdown inside the project. A system-prompt addition steers the model to write a plan to plan/<date>_<description>.md, render it with the show_plan tool, and hand over: an Accept / Decline prompt follows the plan (approving a plan). | | Build | Reads, writes, and bash inside the project run with no confirmation; in-project bash runs sandboxed. | | YOLO | Never prompts, never sandboxes, no protected-path backstop. Can do anything the current user can. |

In every mode except YOLO: out-of-project access prompts; bash that reaches outside the project or escalates privileges (sudo and friends, detected even through wrappers and bash -c scripts) prompts, and runs unsandboxed once you approve it; edit/write to protected paths (.git/, .env, dotfiles, ...) are hard-blocked. When the sandbox is unavailable, the sandboxed modes show (!) <reason> in the footer and in-project bash prompts instead - you are never silently unprotected.

At a glance

The current mode is persisted per session and shown in the footer, next to the network state: Build (sandboxed in project dir, alt+m) Network: filtered (alt+n).

| Command | What it does | |---|---| | alt+m, /perm <mode> | Cycle or switch the mode | | alt+n, /net ... | Toggle network filtering; allowlist, grants, denies | | /perm init | Write a full copy of the stock defaults to the global config | | /perm clear-approvals, /perm blocks, /perm unblock <path> | Session grants and "Deny and block" paths | | /plan approve, /plan status | Plan approval | | /shells | List and stop background shells | | /sandbox | The active sandbox configuration | | pi --perm <mode>, pi --no-sandbox | Start mode; keep the modes, drop OS sandboxing |

Network requests to hosts outside the allowlist pause while you're asked (allow for the session or forever, or deny); the model can also ask for hosts up front with request_network_access (docs/network.md). Prompts for an out-of-project path offer Deny and block, which masks the path for the rest of the session (docs/permissions.md). Git over SSH cannot authenticate inside the sandbox (~/.ssh is masked); use HTTPS with a fine-grained token (docs/network.md).

How protection works

Two independent layers compose:

  1. Policy engine (allow / ask / deny): every tool call resolves against the active mode's policy for its surface (bash, file tools, the project boundary, web search, extension tools, skills). For bash, the command line is parsed with tree-sitter and every command it contains, nested ones included, is judged separately; out-of-project paths and privilege escalation are detected structurally (docs/permissions.md).
  2. OS sandbox (@anthropic-ai/sandbox-runtime): the real enforcement for bash. In-project bash runs wrapped by bubblewrap (Linux), sandbox-exec (macOS) or a separate local account (Windows), with writes confined to the profile's allowWrite, the profile's denyRead secrets unreadable, and network traffic filtered by a domain allowlist, regardless of what the command does (docs/sandbox.md).

So a bash command that policy says allow still runs sandboxed; ask prompts, then runs sandboxed, or unsandboxed for an escape you approve; deny never runs. Only the model's bash tool is OS-sandboxed; the file tools are governed by the policy engine and the protected-path backstop. While a sandboxed mode is active, the model is told its boundaries in the system prompt, so it picks paths and hosts that work. SECURITY.md has the full threat model and the known limitations.

Background shells. A dev server, a watcher or a long build runs as a background shell (bash with run_in_background: true) under the same sandbox and the same prompts; the model reads it with bash_output, stops it with kill_shell, and is told when it ends. /shells lists and stops them. On Linux expose relays ports into the shell so you can open its server in a browser (docs/shells.md).

Configuration

Modes are data, layered in this order:

  1. Stock defaults - permission-mode.defaults.json, shipped with the extension. Run /perm init to drop a full copy at the global path.
  2. ~/.pi/agent/permission-mode/permission-mode.json (global, full authority): redefine built-in modes, add your own, set defaultMode and cycleOrder.
  3. <project>/.pi/permission-mode.json (project, tighten-only): may only make an existing mode stricter. Opening an untrusted repo can never weaken your protection.

A mode has a sandbox block (what bash may read, write and reach) and a permission block (an allow / ask / deny per tool, as a single action or a glob map). A redefined mode keeps every stock field you leave out, and a block you set replaces the stock block whole. A global config that gives Build its own network allowlist and asks before every rm:

{
  "$schema": "https://raw.githubusercontent.com/wynainfo/pi-permission-modes/main/schemas/permission-mode.schema.json",
  "modes": {
    "build": {
      "sandbox": { "network": { "allowedDomains": ["github.com", "*.github.com", "registry.npmjs.org"] } },
      "permission": { "bash": { "*": "allow", "rm*": "ask" } }
    }
  }
}

In a glob map the last matching pattern wins and, across layers, the most restrictive wins. Every key, the pattern syntax, the project rules, and the outdated-default warnings: docs/configuration.md, docs/sandbox.md, docs/permissions.md.

Documentation

| File | Covers | |---|---| | docs/index.md | Topic map, commands and shortcuts | | docs/configuration.md | Files, layers, what a project config may change, keeping the global config current | | docs/modes.md | The stock modes, mode fields, start mode, plan approval, your own modes, strict home | | docs/permissions.md | Rules, pattern syntax, resolution, bash gating, protected paths, session grants, Deny and block | | docs/sandbox.md | Every sandbox key, scratch directory, violations, placeholders, platforms | | docs/network.md | Allowlist, requesting access, grants, git authentication | | docs/shells.md | Background shells: run_in_background, bash_output, kill_shell, /shells, notices, port exposure | | docs/troubleshooting.md | One section per error message | | docs/architecture.md | For forks and contributors |

Disabling

  • Temporarily: launch pi with --no-extensions (disables all), or --no-sandbox to keep the modes but drop OS sandboxing.
  • Permanently: pi remove npm:pi-permission-modes (or git:github.com/wynainfo/pi-permission-modes, matching how you installed it) - or remove the entry from your pi settings.