pi: prompt before dangerous commands
β’ 251 words β’ 2 min
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.
π€ Drafted with /bloggify.