pi-git-bash-only
Enforce Git Bash as the only shell for pi on Windows: hard-block powershell/pwsh/cmd calls, inject shell policy into the system prompt, verify shell configuration, and install wmicu + gbk (GBK to UTF-8 wrappers for native exe output).
Package details
Install pi-git-bash-only from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-git-bash-only- Package
pi-git-bash-only- Version
1.1.1- Published
- Aug 25, 2026
- Downloads
- 447/mo · 9/wk
- Author
- naoki326
- License
- MIT
- Types
- extension
- Size
- 23.7 KB
- Dependencies
- 0 dependencies · 1 peer
Pi manifest JSON
{
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-git-bash-only
Your Windows pi agent gets exactly one shell: Git Bash.
You standardized on Git Bash — and then the model "helpfully" emits:
powershell -Command "Get-Process | Select Name" # sneaks in PowerShell
cmd /c "dir /s" # …or cmd
That escapes your shell policy, breaks your quoting/encoding assumptions, and reintroduces everything you moved to Git Bash to avoid. Telling the model not to do it helps — until context gets long and it forgets.
pi-git-bash-only enforces it instead of asking nicely:
| Layer | What it does |
|---|---|
| 🔒 Hard block | A tool_call hook blocks powershell / pwsh / cmd calls — including .exe, full-path, backtick, and cmd //c forms. The block reason tells the model exactly which bash-friendly exe to use instead. |
| 🧠 Soft policy | Injects a concise shell policy into the system prompt every turn (block-list + standalone-exe alternatives), so the model rarely tries in the first place. |
| 🔍 Shell audit | On startup, statically verifies which bash pi will actually use (shellPath setting → default Git Bash location → PATH scan). If it's not Git Bash, you get a warning with the exact settings fix. |
📦 wmicu + gbk included |
Idempotently installs two GBK→UTF-8 wrappers to ~/bin: wmicu (wmic pass-through) and gbk — a general wrapper for any native exe that also disables MSYS path mangling, so gbk taskkill /PID 123 /F just works. |
🩺 /gitbash |
One command shows shell audit + wmicu + PATH status at a glance. |
No-op on non-Windows platforms. No configuration required.
Install
# from GitHub
pi install git:github.com/Naoki326/pi-git-bash-only
# from npm
pi install npm:pi-git-bash-only
Try it without installing:
pi -e git:github.com/Naoki326/pi-git-bash-only
See it work
Ask the agent to use PowerShell. Watch it bounce off the block and land on bash:
> run this: powershell -Command "echo e2e-test"
✗ tool bash: powershell -Command "echo e2e-test"
BLOCKED — 已拦截 Windows 原生 shell 调用(powershell)。
本环境已禁用 Windows 原生 shell(Git Bash only,pi-git-bash-only 包)。
请改用 bash 语法重新实现;需要 Windows 特定功能时直接调用独立 exe:
注册表用 reg.exe、进程用 tasklist/taskkill、进程 CommandLine 核验用
wmicu、服务用 sc.exe、文件 ACL 用 icacls.exe。
✓ tool bash: echo e2e-test
e2e-test
The powershell call was hard-blocked by pi-git-bash-only; re-implemented
with native bash — same output.
One retry, then it stays in bash for the rest of the session — the soft policy means most sessions never hit the block at all.
The one (maybe) manual step
Packages can carry extensions but not your settings.json. pi resolves its shell as shellPath setting → C:\Program Files\Git\bin\bash.exe → PATH scan, so if Git Bash is in the default location you're done — no action needed.
Otherwise, pin it in ~/.pi/agent/settings.json:
{ "shellPath": "C:/Program Files/Git/bin/bash.exe" }
The startup audit warns you (with this exact fix) if pi would pick anything else.
wmicu and gbk
Git Bash calling native exes has two built-in traps:
- MSYS path mangling —
/PID,/FI-style flags get rewritten toC:/Program Files/Git/PIDand the exe errors out (taskkill /PID 123 /F→无效参数). - GBK mojibake — on Chinese Windows, native exes emit GBK; a UTF-8 terminal shows garbage, which silently defeats "verify the output before you act on it".
gbk fixes both at once:
$ gbk taskkill /PID 99999999 /F # single-slash flags pass through untouched
错误: 没有找到进程 "99999999"。 # …and the message is readable UTF-8
$ gbk tasklist /FI "IMAGENAME eq node.exe" /FO CSV
"映像名称","PID",...
$ tasklist ... | gbk # pipe mode: stdin GBK → stdout UTF-8
wmicu is the dedicated wmic wrapper (same usage as wmic):
$ wmicu process where processid=999999 get commandline
没有可用实例。 # was mojibake
- Both require
nodeon PATH;wmicualso needswmic. - PIDs are Windows PIDs (
tasklist/wmicones), not Git Bash's internal$$. - Installs are idempotent: files are marked
# pi-git-bash-only: managedand only managed copies are ever replaced — your own~/bin/wmicu/~/bin/gbkare never touched. - PATH note: Git Bash injects
$HOME/bininto PATH itself (/etc/profile.d/env.sh), so if you start pi from a Git Bash terminal — the common case — both tools are on PATH with zero setup. Only when pi is launched from PowerShell / Start Menu / other terminals do you need to add~/binto your Windows user PATH once./gitbashshows the actual state for the current session. - The soft-policy layer teaches the model these two traps every turn, so it reaches for
gbkbefore it ever sees a mangled flag.
Complements pi-ast-guard
pi-ast-guard blocks destructive commands via AST parsing. pi-git-bash-only locks which shell your agent may reach. Different axes, zero overlap — use both for defense in depth.
Design notes
- The block regex is battle-tested against 33 cases: all 18 invocation forms blocked (
powershell -Command,pwsh -c,cmd //c, full paths,$(cmd /c …), backticks, mixed case…); 15 benign patterns pass untouched ($cmd,--cmd,foo.cmd,cmdlet,cmdkey,npm run cmd:x,git commit -m "…cmd…"-shaped text, …). - Fail-closed by intent: a plain-text mention (
echo "powershell") may cost one blocked retry — the reason always explains the fix. Silence-by-default would leak the very thing you installed this to prevent. - Covers pi's
bashtool, including sub-agent calls. User-typed!/!!commands and processes spawned by other extensions are outside its jurisdiction — pi's own tool surface and common execution layers already run Git Bash. session_startaudit is fully static (no command execution).
Uninstall
pi remove npm:pi-git-bash-only # or your git source
rm ~/bin/wmicu ~/bin/gbk # the only files written outside pi
License
MIT