// Claude Code PreToolUse command hook for a managed session. The bundle's // settings.json runs it as // timeout -k 2 10 claude-gate.mjs || exit 2 // with hook timeout 20 (S0 lines 1-4): exit 0 lets the tool run, exit 2 // blocks it with the reason on stderr, and the wrapper turns a crash, a // missing file or a timeout into exit 2. import { readFileSync } from "node:fs"; import { decide } from "./gate.mjs"; function block(reason) { process.stderr.write(`${reason}\n`); process.exit(2); } try { const policy = JSON.parse(readFileSync(process.argv[2], "utf8")); if (policy.harness !== "claude-code") block("mosaic gate: policy file is not a claude-code policy"); const event = JSON.parse(readFileSync(0, "utf8")); const verdict = decide(policy, event.tool_name, event.tool_input); if (!verdict.allow) block(verdict.reason); process.exit(0); } catch (error) { block(`mosaic gate: ${error.message}`); }