forked from bchanot/claude
fix(rtk): rtk resolution + absolute-path rewrite — compression was silently dead
rtk lives at ~/.cargo/bin but the hand-managed .bashrc lost the cargo line: command -v failed in hook AND tool shell, so the hook no-op'd with a stderr warn on every Bash call — input compression silently OFF. - Resolve RTK_BIN by probing known install dirs (LRN-036 class). - Substitute the ABSOLUTE path at the rewrite head: a bare 'rtk …' exits 127 in the tool shell, whose PATH the hook cannot fix (proven). - Compound rewrites carrying further bare rtk segments pass through unrewritten: quoted text (commit messages) makes a global substitution unsafe — lose compression, never emit a command that 127s (proven: a commit chain 127'd mid-flow). - detect_rtk probes the same dirs so the banner reports capability. - Re-pinned .rtk-hook.sha256: the rtk BINARY verifies the hook against it at execution time and refuses a modified hook — the pin is live machinery, not a vestige; coupling documented in the header. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016zA3Qh2Q1QpcGXzXxKeDHR
This commit is contained in:
co-authored by
Claude Fable 5
parent
fe9fa86bb2
commit
f0b7e89468
@@ -1 +1 @@
|
||||
ef0d630994fd7ef5f2b84fb66cd6249c493bb8736bcacd4734d7c798125018fb rtk-rewrite.sh
|
||||
0f43229d17d03342d27c0b836b9b70f25f98dfb80a35ffc8dc2488034cb8719c rtk-rewrite.sh
|
||||
|
||||
+36
-3
@@ -7,6 +7,10 @@
|
||||
# which is the single source of truth (src/discover/registry.rs).
|
||||
# To add or change rewrite rules, edit the Rust registry — not this file.
|
||||
#
|
||||
# INTEGRITY PIN: the rtk binary verifies this file against
|
||||
# hooks/.rtk-hook.sha256 at execution time and refuses to run on mismatch.
|
||||
# ANY edit here must re-pin: (cd hooks && sha256sum rtk-rewrite.sh > .rtk-hook.sha256)
|
||||
#
|
||||
# Exit code protocol for `rtk rewrite`:
|
||||
# 0 + stdout Rewrite found, no deny/ask rule matched → auto-allow
|
||||
# 1 No RTK equivalent → pass through unchanged
|
||||
@@ -18,14 +22,27 @@ if ! command -v jq &>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v rtk &>/dev/null; then
|
||||
# PATH heal: hook/tool-shell PATH may lack the cargo bin dir (hand-managed
|
||||
# ~/.bashrc can lose the cargo line — LRN-036 class). Resolve the ABSOLUTE
|
||||
# binary path: the rewritten command executes in the tool shell, whose PATH
|
||||
# the hook cannot fix — a bare `rtk …` rewrite would exit 127 there.
|
||||
RTK_BIN="$(command -v rtk 2>/dev/null || true)"
|
||||
RTK_ON_PATH=1
|
||||
if [ -z "$RTK_BIN" ]; then
|
||||
RTK_ON_PATH=0
|
||||
for _d in "$HOME/.cargo/bin" "$HOME/.local/bin"; do
|
||||
if [ -x "$_d/rtk" ]; then RTK_BIN="$_d/rtk"; break; fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$RTK_BIN" ]; then
|
||||
echo "[rtk] WARNING: rtk is not installed or not in PATH. Hook cannot rewrite commands. Install: https://github.com/rtk-ai/rtk#installation" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Version guard: rtk rewrite was added in 0.23.0.
|
||||
# Older binaries: warn once and exit cleanly (no silent failure).
|
||||
RTK_VERSION=$(rtk --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||
RTK_VERSION=$("$RTK_BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||
if [ -n "$RTK_VERSION" ]; then
|
||||
MAJOR=$(echo "$RTK_VERSION" | cut -d. -f1)
|
||||
MINOR=$(echo "$RTK_VERSION" | cut -d. -f2)
|
||||
@@ -44,7 +61,7 @@ if [ -z "$CMD" ]; then
|
||||
fi
|
||||
|
||||
# Delegate all rewrite + permission logic to the Rust binary.
|
||||
REWRITTEN=$(rtk rewrite "$CMD" 2>/dev/null)
|
||||
REWRITTEN=$("$RTK_BIN" rewrite "$CMD" 2>/dev/null)
|
||||
EXIT_CODE=$?
|
||||
|
||||
case $EXIT_CODE in
|
||||
@@ -70,6 +87,22 @@ case $EXIT_CODE in
|
||||
;;
|
||||
esac
|
||||
|
||||
# When rtk is NOT on PATH, a bare `rtk …` rewrite exits 127 in the tool
|
||||
# shell (whose PATH the hook cannot fix). Substitute the absolute path at
|
||||
# the string head — the only position safe to rewrite. Compound commands
|
||||
# (`a && b`) can carry further bare rtk segments we canNOT substitute
|
||||
# safely (quoted text, e.g. commit messages, may contain the same
|
||||
# pattern): if any remain at a command position, pass through unrewritten
|
||||
# — lose the compression, never emit a command that 127s.
|
||||
if [ "$RTK_ON_PATH" -eq 0 ]; then
|
||||
case "$REWRITTEN" in
|
||||
rtk\ *) REWRITTEN="$RTK_BIN ${REWRITTEN#rtk }" ;;
|
||||
esac
|
||||
if printf '%s' "$REWRITTEN" | grep -Eq '(^|[;&|][[:space:]]*)rtk[[:space:]]'; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
ORIGINAL_INPUT=$(echo "$INPUT" | jq -c '.tool_input')
|
||||
UPDATED_INPUT=$(echo "$ORIGINAL_INPUT" | jq --arg cmd "$REWRITTEN" '.command = $cmd')
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
# --- Always-on plugins ---
|
||||
|
||||
detect_rtk() {
|
||||
command -v rtk &>/dev/null
|
||||
command -v rtk &>/dev/null && return 0
|
||||
# PATH heal: hook/session PATH may lack the cargo bin dir (LRN-036 class)
|
||||
[ -x "$HOME/.cargo/bin/rtk" ] || [ -x "$HOME/.local/bin/rtk" ]
|
||||
}
|
||||
|
||||
detect_superpowers() {
|
||||
|
||||
Reference in New Issue
Block a user