#!/usr/bin/env bash
# PreToolUse(Bash) — route UNBOUNDED multi-file reads into the quietcontext sandbox.
# Bounded pipelines (wc / head -N / tail -N / grep -c) already keep raw bytes out of
# context and are left alone. Bypass with a trailing "# raw-ok".
set -uo pipefail

INPUT=""; IFS= read -rd '' INPUT || true

# Fast path: the deny below can only ever fire when the command contains one of
# these literals (find / grep / git ls-files / ls with flags / a glob). Checked
# against the raw JSON (a superset of tool_input.command), so this never denies
# on its own — it only ever skips the jq spawn when none can possibly match.
case "$INPUT" in
  *find*|*grep*|*ls-files*|*'ls '*|*'**/*'*|*'*.'*) ;;
  *) exit 0 ;;
esac

CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null) || exit 0
[[ -z "$CMD" ]] && exit 0

RAW_OK_RE='#[[:space:]]*raw-ok'
[[ $CMD =~ $RAW_OK_RE ]] && exit 0

# Multi-file read: recursive/glob-wide source.
FILESCAN_RE='(\bfind\b|\bgrep\b[^|]*-[a-zA-Z]*[rR]|\bgit ls-files\b|\bls\b[^|]*-[a-zA-Z]*R|\*\*/\*|\*\.[a-z]+)'
[[ $CMD =~ $FILESCAN_RE ]] || exit 0

# Mutation or side-effecting: not our business.
MUTATE_RE='(\brm\b|\bmv\b|\bcp\b|-exec\b|-delete\b|\bsed -i\b|\bxargs\b[^|]*\b(rm|mv|sed)\b)'
[[ $CMD =~ $MUTATE_RE ]] && exit 0

# Bounded output: the raw bytes never reach context. Leave alone.
BOUNDED_RE='(\|[^|]*\bwc\b|\|[^|]*\b(head|tail)\b[^|]*(-n[[:space:]]*)?-?[0-9]{1,2}\b|\|[^|]*\b(head|tail)\b[^|0-9]*$|\|[^|]*\bsed\b[^|]*[0-9]+[[:space:]]*p|\|[^|]*\bawk\b[^|]*NR[[:space:]]*<|\bgrep\b[^|]*(-[a-zA-Z]*c\b|--count)|\bwc -l[[:space:]]*<)'
[[ $CMD =~ $BOUNDED_RE ]] && exit 0

jq -nc '{
  hookSpecificOutput: {
    hookEventName: "PreToolUse",
    permissionDecision: "deny",
    permissionDecisionReason: "quietcontext-gate: this reads many files with no bound — the raw output would land in context. Either bound it (pipe to wc / head -N), or do the work in the sandbox: ToolSearch(query:\"select:mcp__plugin_quietcontext_quietcontext__execute\") then mcp__plugin_quietcontext_quietcontext__execute with an equivalent script that prints only the derived answer. Deliberate raw run? append \" # raw-ok\"."
  }
}'
exit 0
