1
0

redirect-read-hook.sh 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738
  1. #!/usr/bin/env bash
  2. # PreToolUse(Read) REDIRECT hook — prototype for A/B (P1: get agents off Read and
  3. # onto codegraph_node during implementation, not just for Q&A).
  4. #
  5. # When the agent Reads a SOURCE file, deny it and steer to codegraph_node's
  6. # file-view, which (as of the Lever-1 change) returns the WHOLE file verbatim
  7. # WITH line numbers — imports, top-level code, comments and all — PLUS the file's
  8. # blast radius, in one call. That output is a strict superset of Read, so the
  9. # redirect is lossless: the agent loses nothing by taking it, and gains who-
  10. # depends-on-this for the edit it's about to make.
  11. #
  12. # Differs from block-read-hook.sh (which steers to explore/node-by-symbol): this
  13. # names the FILE-VIEW path explicitly (file:"<base>" + includeCode:true), the
  14. # 1:1 Read replacement we're trying to get picked during implementation.
  15. #
  16. # Non-source files (configs, docs, lockfiles, .env) pass through to a real Read.
  17. # A redirect to a file codegraph hasn't indexed SELF-CORRECTS: the file-view
  18. # replies "No indexed file matches … Read it directly", so a just-created file
  19. # never dead-ends — the agent Reads it on the next turn.
  20. #
  21. # Wire via: claude ... --settings <settings-with-this-as-PreToolUse(Read)>
  22. # Eval artifact only. The production version is an indexed-aware `codegraph`
  23. # subcommand (cross-platform — no bash/jq — and queries the index so it never
  24. # bounces a new/un-indexed file), wired opt-in by the installer.
  25. set -uo pipefail
  26. input="$(cat)"
  27. fp="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty' 2>/dev/null)"
  28. [ -n "$fp" ] || exit 0
  29. base="$(basename "$fp")"
  30. case "$fp" in
  31. *.ts|*.tsx|*.js|*.jsx|*.mjs|*.cjs|*.py|*.go|*.rs|*.java|*.rb|*.php|*.swift|*.kt|*.kts|*.scala|*.c|*.cc|*.cpp|*.h|*.hpp|*.cs|*.lua|*.vue|*.svelte|*.m|*.mm)
  32. msg="codegraph has this file indexed (kept in sync on every edit). Call codegraph_node with file:\"$base\" and includeCode:true instead of Read — it returns the WHOLE file verbatim WITH line numbers (imports, top-level code and all — safe to base an Edit on) PLUS which files depend on it, in one call. Treat its output as already-Read; do not Read this file. (If it answers that the file isn't indexed — e.g. you just created it — then Read it directly.)"
  33. jq -n --arg m "$msg" '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:$m}}'
  34. exit 0
  35. ;;
  36. esac
  37. exit 0