From 0bcf7045e1c869a2a6134bcc2926faca0d2d2ceb Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Thu, 3 Jul 2025 08:22:43 -0700 Subject: [PATCH 1/2] remind claude we use deno not node, and some default permissions --- .claude/scripts/block-node.py | 13 +++++++++++++ .claude/settings.json | 26 ++++++++++++++++++++++++++ .gitignore | 1 + 3 files changed, 40 insertions(+) create mode 100644 .claude/scripts/block-node.py create mode 100644 .claude/settings.json diff --git a/.claude/scripts/block-node.py b/.claude/scripts/block-node.py new file mode 100644 index 000000000..b25dd65f1 --- /dev/null +++ b/.claude/scripts/block-node.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 +import json, re, sys + +data = json.load(sys.stdin) +cmd = data.get("tool_input", {}).get("command", "") + +# If Claude is about to run a shell command that uses a Node package-manager… +if re.search(r'\b(npm|npx|yarn|pnpm|node)\b', cmd): + # Send feedback to Claude and *block* the tool call + print("We use **Deno** in this repo – please rewrite the command accordingly.", file=sys.stderr) + sys.exit(2) # exit-code 2 = “block & show stderr to Claude” +# Otherwise let the call proceed +sys.exit(0) diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..84b52b381 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,26 @@ +{ + "permissions": { + "allow": [ + "Bash(grep:*)", + "Bash(deno test:*)", + "Bash(deno task test:*)", + "Bash(find:*)", + "Bash(deno lint:*)", + "Bash(rg:*)" + ], + "deny": [] + }, + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash", + "hooks": [ + { + "type": "command", + "command": "python3 .claude/scripts/block-node.py" + } + ] + } + ] + } +} diff --git a/.gitignore b/.gitignore index 2462c1755..5702b4fcb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ packages/seeder/results .claude-prompt.tmp .pr-desc.tmp dist/ +.claude/settings.local.json From 2b910dfb7213ae1e7d6a627e2b6ebab72a6a5af4 Mon Sep 17 00:00:00 2001 From: Jesse Andrews Date: Thu, 3 Jul 2025 08:33:38 -0700 Subject: [PATCH 2/2] use deno to block node --- .claude/scripts/block-node.py | 13 ------------- .claude/scripts/block-node.ts | 28 ++++++++++++++++++++++++++++ .claude/settings.json | 2 +- 3 files changed, 29 insertions(+), 14 deletions(-) delete mode 100644 .claude/scripts/block-node.py create mode 100644 .claude/scripts/block-node.ts diff --git a/.claude/scripts/block-node.py b/.claude/scripts/block-node.py deleted file mode 100644 index b25dd65f1..000000000 --- a/.claude/scripts/block-node.py +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env python3 -import json, re, sys - -data = json.load(sys.stdin) -cmd = data.get("tool_input", {}).get("command", "") - -# If Claude is about to run a shell command that uses a Node package-manager… -if re.search(r'\b(npm|npx|yarn|pnpm|node)\b', cmd): - # Send feedback to Claude and *block* the tool call - print("We use **Deno** in this repo – please rewrite the command accordingly.", file=sys.stderr) - sys.exit(2) # exit-code 2 = “block & show stderr to Claude” -# Otherwise let the call proceed -sys.exit(0) diff --git a/.claude/scripts/block-node.ts b/.claude/scripts/block-node.ts new file mode 100644 index 000000000..4de815317 --- /dev/null +++ b/.claude/scripts/block-node.ts @@ -0,0 +1,28 @@ +#!/usr/bin/env -S deno run --allow-read +/** + * .claude/scripts/block-node.ts + * + * Claude Code Pre-Tool hook. + * - Blocks shell commands that invoke npm, npx, yarn, pnpm, or node. + * - Prints a Deno-friendly reminder to stderr. + * - Exits 2 so Claude blocks the tool call and shows the message. + */ + +const rawInput = await new Response(Deno.stdin.readable).text(); + +let cmd = ""; +try { + const payload = JSON.parse(rawInput); + cmd = payload?.tool_input?.command ?? ""; +} catch { + // If the JSON is malformed we allow the call rather than choke the hook. +} + +if (/\b(npm|npx|yarn|pnpm|node)\b/.test(cmd)) { + console.error( + "We use **Deno** in this repo – please rewrite the command accordingly.", + ); + Deno.exit(2); // Claude interprets exit-code 2 as “block & surface stderr” +} + +Deno.exit(0); // Let the tool call proceed diff --git a/.claude/settings.json b/.claude/settings.json index 84b52b381..7a1a63b02 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -17,7 +17,7 @@ "hooks": [ { "type": "command", - "command": "python3 .claude/scripts/block-node.py" + "command": "deno run \"$(git rev-parse --show-toplevel)/.claude/scripts/block-node.ts\"" } ] }