pi-interactive-only
Pi extension that refuses to run Pi in non-interactive modes (print/JSON/RPC), forcing interactive-only usage.
Package details
Install pi-interactive-only from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-interactive-only- Package
pi-interactive-only- Version
1.0.0- Published
- Oct 7, 2026
- Downloads
- 285/mo · 7/wk
- Author
- koaqiu
- License
- MIT
- Types
- extension
- Size
- 7.8 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions/interactive-only.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-interactive-only
A Pi extension that refuses to run Pi in any non-interactive mode.
After installing it, the only accepted run mode is the terminal UI (tui).
It exists for machines where Pi must never be driven by a script, a pipe, or an automation job — only from a real terminal session.
Blocked / allowed
| Invocation | Pi mode | Result |
|---|---|---|
pi |
tui |
allowed |
pi -p "…", pi --print "…" |
print |
refused |
git diff | pi "review this" |
print (automatic downgrade) |
refused |
pi --mode json "…" |
json |
refused |
pi --mode rpc |
rpc |
refused |
pi --help, pi update, pi list, pi install |
— | unaffected |
A refused run exits with code 2 after writing one message to stderr, before the
first model request. No tokens are spent, and nothing is written to stdout, so a
pipeline consuming stdout sees a clean failure.
Install
# from npm
pi install npm:pi-interactive-only
# from git
pi install git:github.com/koaqiu/pi-interactive-only
# try it for a single invocation, without saving anything
pi -e npm:pi-interactive-only
pi -e ./pi-interactive-only
Add --local (-l) to write the declaration to .pi/settings.json instead of the
personal settings, for example to protect one specific project only:
pi install -l git:github.com/koaqiu/pi-interactive-only
Remove it again with pi remove npm:pi-interactive-only (or pi remove -l …).
Configuration
| Environment variable | Default | Effect |
|---|---|---|
PI_ALLOW_NONINTERACTIVE |
unset | 1/true/yes/on disables the guard for that run |
PI_ALLOWED_MODES |
tui |
comma-separated allow-list, e.g. tui,rpc to keep RPC integrations working |
# allowed once, e.g. inside a CI job that knows what it is doing
PI_ALLOW_NONINTERACTIVE=1 pi -p "regenerate the changelog"
# keep RPC but still block print/JSON
PI_ALLOWED_MODES=tui,rpc pi --mode rpc
There is no on-disk configuration and no persisted state: the extension only reads
the environment at session_start.
Notes
- The guard runs in-process at
session_start, i.e. after Pi has already parsed its argv and created the session. It stops the run before any prompt is sent, but it is not an argv-level rejection of the flag. --help,--list-models,--export, and thepi install/update/list/config/mcpsubcommands never start a session, so they keep working.- The extension is harmless in interactive mode: it returns immediately when
ctx.mode === "tui".
Development
npm install
npm run typecheck # tsc --noEmit
pi -e . -p # should print the refusal to stderr and exit 2
License
MIT