set -euo pipefail
MODE="${BASEMIND_GUARD:-nudge}"
[ "${MODE}" = "off" ] && exit 0
command -v jq >/dev/null 2>&1 || exit 0
input="$(cat 2>/dev/null || true)"
[ -n "${input}" ] || exit 0
tool="$(printf '%s' "${input}" | jq -r '.tool_name // empty' 2>/dev/null || true)"
session="$(printf '%s' "${input}" | jq -r '.session_id // "nosession"' 2>/dev/null || echo nosession)"
case "${tool}" in
Grep)
alt="basemind: search_symbols (definitions), find_references / find_callers (call sites), or workspace_grep (indexed regex over content)"
;;
Glob)
alt="basemind: list_files (indexed paths, with language / path filters)"
;;
*)
exit 0
;;
esac
emit_allow() {
jq -cn --arg m "$1" \
'{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",additionalContext:$m}}'
}
emit_deny() {
jq -cn --arg m "$1" \
'{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:$m}}'
}
if [ "${MODE}" = "redirect" ]; then
emit_deny "Use ${alt} instead of ${tool} for codebase navigation — it answers from the index \
(paths + line numbers, a fraction of the tokens). Set BASEMIND_GUARD=nudge to make this advisory, \
or BASEMIND_GUARD=off to disable."
exit 0
fi
safe_session="$(printf '%s' "${session}" | tr -c 'A-Za-z0-9._-' '_')"
[ -n "${safe_session}" ] || safe_session="nosession"
marker_dir="${TMPDIR:-/tmp}/basemind-guard"
marker="${marker_dir}/${safe_session}.${tool}"
mkdir -p "${marker_dir}" 2>/dev/null || true
if [ -e "${marker}" ]; then
exit 0
fi
: >"${marker}" 2>/dev/null || true
emit_allow "basemind is indexed for this repo. For codebase structure, prefer ${alt} — it returns \
paths + line numbers without reading file bodies, at a fraction of the tokens. Proceeding with \
${tool} for now. (BASEMIND_GUARD=off silences this; =redirect enforces it.)"
exit 0