experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore(hooks): switch push/main-bookmark guard from hard-block to ask-prompt

Changes the block-push.mjs PreToolUse:Bash hook from a hard rejection (stderr + exit 20) to a permission-prompt request via the documented permissionDecision: 'ask' shape. The user gets the standard tool-permission prompt and can approve or deny inline, instead of having to retry the command via the ! prefix. Same trigger patterns (jj git push, git push, jj bookmark set main, etc.) — only the response shape changed.

+14 -8
+14 -8
.claude/hooks/block-push.mjs
··· 1 1 #!/usr/bin/env node 2 - // PreToolUse:Bash hook — blocks pushing/main-moving from agent sessions. 3 - // User-typed `!` commands run client-side and bypass PreToolUse hooks. 2 + // PreToolUse:Bash hook — surfaces push/main-move commands to the user 3 + // for explicit approval instead of letting agents run them silently. 4 + // Emits the documented `permissionDecision: "ask"` shape so Claude Code 5 + // shows the standard tool-permission prompt; the user approves or denies. 4 6 5 7 import { readFileSync } from "node:fs"; 6 8 ··· 22 24 23 25 for (const { re, why } of PATTERNS) { 24 26 if (re.test(command)) { 25 - const head = command.split("\n")[0].slice(0, 100); 26 - process.stderr.write( 27 - `BLOCKED: \`${head}\` ${why}.\n` + 28 - `mpeek policy: jj bookmark set main / jj git push / git push are user-only.\n` + 29 - `If the user wants this, they run it themselves via the \`!\` prefix.\n`, 27 + process.stdout.write( 28 + JSON.stringify({ 29 + hookSpecificOutput: { 30 + hookEventName: "PreToolUse", 31 + permissionDecision: "ask", 32 + permissionDecisionReason: 33 + `mpeek policy: this command ${why}. Please confirm before allowing.`, 34 + }, 35 + }), 30 36 ); 31 - process.exit(2); 37 + process.exit(0); 32 38 } 33 39 } 34 40