pi-write-approval
Opt-in approval prompts for file writes, edits and shell deletions in Pi
Package details
Install pi-write-approval from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-write-approval- Package
pi-write-approval- Version
1.0.1- Published
- Nov 5, 2026
- Downloads
- 517/mo · 517/wk
- Author
- iamthes
- License
- MIT
- Types
- extension
- Size
- 14.8 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-write-approval
Opt-in approval prompts for file writes, edits and shell deletions in Pi.
Default Pi behavior is unchanged: approval is off and nothing asks for permission. Turn it on for the current session and Pi asks before every write, edit and deletion.
Install
pi install npm:pi-write-approval
Manual alternative — add the package to ~/.pi/agent/settings.json:
{
"packages": ["npm:pi-write-approval"]
}
Remove with pi remove npm:pi-write-approval. Updates arrive with
pi update --extensions.
To run a local checkout instead of the published package — the working copy is loaded
without copying, so edits take effect on /reload:
pi -e /path/to/pi-write-approval
Usage
| Action | Effect |
|---|---|
/write-approval or /write-approval toggle |
Flip the switch |
/write-approval on |
Ask before writes, edits and deletions |
/write-approval off |
Back to plain Pi behavior |
/write-approval status |
Report the current state |
ctrl+alt+w |
Flip the switch, same as the command |
pi --write-approval |
Start every session with approval on |
The keyboard shortcut works in both states and is registered by pi.registerShortcut
from the SHORTCUT constant in src/index.ts — change it there if your terminal or
window manager already grabs ctrl+alt+w. No other loaded extension or built-in Pi
binding uses that combination (the only built-in ctrl+alt shortcut is ctrl+alt+]).
The footer always carries the indicator: Write approval: ON in the default foreground
while prompts are active, Write approval: OFF dimmed like the footer's own lines
otherwise.
The state is session-scoped: a new session starts from the --write-approval flag
(default off).
What asks for approval
With approval on, Pi asks before:
writeandedittool calls outside the temp directory;bashcalls that delete files or directories (rm,rmdir,unlink,trash,trash-put,shred,find ... -delete), unless every delete operand lives in the temp directory.
Never asked: read, grep, ls, find, non-deleting bash commands, and every path
inside os.tmpdir() (on macOS also the shared /tmp, /private/tmp included). Both
/ and \ separators are recognized, so Windows paths are covered as well.
In modes without a UI (-p, --mode json) a blocked call fails with a reason instead of
waiting for an answer, so approval turned on cannot silently skip a confirmation.
Known limitations
Deletion detection is textual, so it can ask for harmless commands that merely contain a
match (for example grep 'rm' notes.txt). Erring toward an extra prompt is intentional.
Not covered by design: truncating bash redirections (> file), mv over an existing
file, sed -i, truncate, dd, the powershell tool, and deletion performed by scripts
started through bash.
Release
Publishing runs on GitHub Actions (.github/workflows/ci.yml). Every push and pull
request runs npm run check; a push to master or next additionally runs
semantic-release, which derives the version from Conventional Commits, updates
CHANGELOG.md, publishes to npm and pushes the version commit plus the tag.
Before the first release:
- create the GitHub repository and push this history to
master(semantic-release needs the tags and commits, hencefetch-depth: 0in the workflow); - add an
NPM_TOKENrepository secret — an npm automation token with publish rights forpi-write-approval(automation tokens bypass 2FA); GITHUB_TOKENis built in; the workflow requestscontents: writebecause@semantic-release/gitpushes the release commit.
Commit types drive the bump — feat: → minor, fix: → patch, BREAKING CHANGE: →
major, while chore:/docs:/style:/refactor: alone publish nothing. The initial
1.0.0 is already published; semantic-release continues from the latest tag (v1.0.0).
The package has no build step: the tarball ships src/, README.md and package.json
(see the files field), which is exactly what Pi loads.
Development
npm install # once: typescript, prettier, @types/node and host types
npm test # node:test, TypeScript runs through Node's type stripping
npm run format # prettier --write
npm run check # format:check + typecheck + tests
The suites are platform-independent: every path comes from node:os and node:path
fixtures in test/fixtures.ts, and platform-specific rules (darwin, win32) are
exercised by passing the platform explicitly.
Layout:
src/index.ts extension wiring: command, shortcut, flag, tool_call hook
src/policy.ts pure decision logic, no Pi imports, fully unit-tested
test/ node:test suites for both layers plus path fixtures