pi: prompt before dangerous commands
• 247 words • 2 min • updated
Problem statement: my Pi extension blocked dangerous shell commands outright, even when I had already preserved the state they could destroy.
The guard parses every bash tool call with tree-sitter, catching commands such
as rm -rf, terraform destroy, and destructive Git operations. Today it did
exactly what I had asked:
% git -C "$(brew --repo thiagowfx/pancake)" reset --hard origin/master
git reset --hard is blocked - discards changes irreversiblyBlocking remains the right default, but an interactive session can ask me. Pi
extensions can intercept the
tool_call event
and open a confirmation dialog through ctx.ui.
The change in
dangerous-command-guard/guard.ts:
- pi.on("tool_call", async (event) => {
+ pi.on("tool_call", async (event, ctx) => {
if (event.toolName !== "bash") return;
const command = event.input.command;
if (typeof command !== "string") return;
const blocked = await findBlockedCommand(command);
- if (blocked) return { block: true, reason: blocked.reason };
+ if (!blocked) return;
+ if (!ctx.hasUI) return { block: true, reason: blocked.reason };
+
+ const allowed = await ctx.ui.confirm(
+ "Allow dangerous command?",
+ `${blocked.command}\n\n${blocked.reason}`,
+ );
+ if (!allowed) return { block: true, reason: "Blocked by user" };
});
Interactive Pi now pauses for approval. Print and JSON modes have no UI, so they still fail closed. Safe commands never prompt.
The tests exercise all three decisions:
✔ extension prompts before dangerous bash tool calls (0.66225ms)
ℹ tests 48
ℹ pass 48
ℹ fail 0Same guardrails, with an escape hatch operated by a human rather than a model. ∎
/bloggify,
then reviewed and edited by me.
More agent-assisted posts.