Created
July 29, 2026 07:12
-
-
Save denysvitali/3f863cda4244315b8a8ac614ffb8060d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # Patch Claude Code's out-of-band-write diff budget (GN_) from 16384 -> 0. | |
| # | |
| # Bug: for files >4kB, Claude Code keeps only a hash in readFileState. When the | |
| # file is written out-of-band (codegen, protobufs, formatters), the "file | |
| # changed" attachment is diffed against an empty cache, so the WHOLE file is | |
| # inlined as `edited_text_file.snippet` until the cumulative budget GN_ (16384 | |
| # chars) is exhausted. That silently torches the context window. | |
| # | |
| # Fix: set the budget to 0 so every such snippet is dropped and the agent is | |
| # told "the diff was omitted ... use the Read tool if you need the current | |
| # content". | |
| # | |
| # Same-length byte substitution: "GN_=16384" -> "GN_=0x000" | |
| # | |
| # Usage: | |
| # ./patch-claude-diff-budget.sh # patch all installed versions | |
| # ./patch-claude-diff-budget.sh --check # report status only | |
| # ./patch-claude-diff-budget.sh --restore # restore from .orig backups | |
| # VERSIONS_DIR=/path ./patch-claude-diff-budget.sh | |
| set -euo pipefail | |
| VERSIONS_DIR="${VERSIONS_DIR:-$HOME/.local/share/claude/versions}" | |
| # The budget symbol is minified and changes every release (GN_, $N_, Xzy, ...), | |
| # so derive it from its only use site: `if(i>=SYM)s.snippet=""`. | |
| USE_SITE_RE='if(i>=[A-Za-z0-9_$]\{1,8\})[A-Za-z0-9_$]\{1,3\}\.snippet=""' | |
| budget_symbol() { # $1 = binary | |
| # `|| true`: grep dies with SIGPIPE once head -1 closes the pipe, and | |
| # `set -o pipefail` would otherwise turn that into a fatal error. | |
| { grep -a -o -m1 "$USE_SITE_RE" "$1" 2>/dev/null || true; } \ | |
| | sed 's/^if(i>=//; s/).*$//' | |
| } | |
| mode="patch" | |
| case "${1:-}" in | |
| --check) mode="check" ;; | |
| --restore) mode="restore" ;; | |
| "") ;; | |
| *) echo "unknown arg: $1" >&2; exit 2 ;; | |
| esac | |
| [ -d "$VERSIONS_DIR" ] || { echo "no versions dir: $VERSIONS_DIR" >&2; exit 1; } | |
| shopt -s nullglob | |
| bins=("$VERSIONS_DIR"/*) | |
| [ ${#bins[@]} -gt 0 ] || { echo "no binaries in $VERSIONS_DIR" >&2; exit 1; } | |
| for bin in "${bins[@]}"; do | |
| [ -f "$bin" ] || continue | |
| case "$bin" in *.orig) continue ;; esac | |
| name=$(basename "$bin") | |
| if [ "$mode" = restore ]; then | |
| if [ -f "$bin.orig" ]; then | |
| tmp="$bin.restoring.$$" | |
| cp -p "$bin.orig" "$tmp" && mv -f "$tmp" "$bin" | |
| echo "$name: restored from backup" | |
| else | |
| echo "$name: no backup, skipped" | |
| fi | |
| continue | |
| fi | |
| sym=$(budget_symbol "$bin") | |
| if [ -z "$sym" ]; then | |
| echo "$name: budget use-site not found (different build?)" | |
| continue | |
| fi | |
| FROM="$sym=16384" | |
| TO="$sym=0x000" | |
| n_from=$(grep -c -a -F "$FROM" "$bin" || true) | |
| n_to=$(grep -c -a -F "$TO" "$bin" || true) | |
| if [ "$mode" = check ]; then | |
| if [ "$n_to" -gt 0 ]; then echo "$name: PATCHED ($TO)" | |
| elif [ "$n_from" -gt 0 ]; then echo "$name: vulnerable ($FROM present)" | |
| else echo "$name: symbol '$sym' found but no =16384 assignment" | |
| fi | |
| continue | |
| fi | |
| if [ "$n_to" -gt 0 ]; then echo "$name: already patched"; continue; fi | |
| if [ "$n_from" -eq 0 ]; then echo "$name: pattern '$FROM' not found, skipped"; continue; fi | |
| [ -f "$bin.orig" ] || cp -p "$bin" "$bin.orig" | |
| # Patch a COPY, then rename over the original. The rename swaps the inode, so | |
| # a currently-running claude process keeps its old mapping instead of having | |
| # its text segment mutated underneath it. | |
| tmp="$bin.patching.$$" | |
| cp -p "$bin" "$tmp" | |
| off=$(grep -a -b -o -F "$FROM" "$tmp" | head -1 | cut -d: -f1) | |
| printf '%s' "$TO" | dd of="$tmp" bs=1 seek="$off" conv=notrunc status=none | |
| if grep -q -a -F "$TO" "$tmp" && ! grep -q -a -F "$FROM" "$tmp"; then | |
| mv -f "$tmp" "$bin" | |
| echo "$name: patched at byte $off (backup: $name.orig)" | |
| else | |
| rm -f "$tmp" | |
| echo "$name: patch verification FAILED, original untouched" >&2 | |
| exit 1 | |
| fi | |
| done | |
| echo | |
| echo "Restart any running 'claude' sessions for the patch to take effect." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment