From 93d24815c15538b977eb50a88531e41bd7b948eb Mon Sep 17 00:00:00 2001 From: Mike Swanson Date: Thu, 28 May 2026 06:33:16 -0700 Subject: [PATCH] fix(hook): make check-messages.sh JSON sanitizer work without python3 on PATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sanitize_json() called `python3` unconditionally, but on ACG Windows boxes the Microsoft Store python3 alias is disabled and `py` is the launcher (feedback_python_windows). When `python3` was missing the function silently returned empty, and the surrounding `result_safe='{"messages":[]}'` default dropped every unread coord message — no error, no warning, no toast. Now prefers identity.json's `.python.command` (set during machine onboarding, matching the pattern other scripts already use), falls back to `command -v python3 || command -v py || command -v python`, and if no Python is available falls back to `tr -d '\000-\037'` so jq can still parse — lossy on real \n/\t in string fields but keeps messages visible instead of dropping them. --- .claude/scripts/check-messages.sh | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.claude/scripts/check-messages.sh b/.claude/scripts/check-messages.sh index b553afa..31a1bc3 100644 --- a/.claude/scripts/check-messages.sh +++ b/.claude/scripts/check-messages.sh @@ -22,19 +22,38 @@ if [ -f "$IDENTITY_FILE" ]; then USER_ALIAS=$(jq -r '.user // empty' "$IDENTITY_FILE" 2>/dev/null) fi +# Resolve a Python interpreter for the JSON sanitizer. Prefer the value in +# identity.json (.python.command — set during machine onboarding); fall back +# to a PATH lookup. On ACG Windows boxes the Microsoft Store `python3` alias +# is disabled and `py` is the canonical launcher, so an unconditional +# `python3` call would silently fail and cause every coord message to be +# dropped. If no Python is available at all, the sanitizer falls back to +# `tr -d` (lossy on real \n/\t in string fields but keeps messages visible). +PY="" +if [ -f "$IDENTITY_FILE" ]; then + PY=$(jq -r '.python.command // empty' "$IDENTITY_FILE" 2>/dev/null) +fi +if [ -z "$PY" ]; then + PY=$(command -v python3 || command -v py || command -v python) +fi + # Sanitize JSON: the coord API sometimes returns message bodies with unescaped # control chars (U+0000-U+001F) — invalid JSON per RFC 8259, which makes jq # abort with "Invalid string: control characters ... must be escaped". Round- # trip through python's json.loads(strict=False) (which accepts them) and # re-emit properly escaped JSON so jq downstream works on every payload. sanitize_json() { - python3 -c ' + if [ -n "$PY" ]; then + "$PY" -c ' import json, sys try: print(json.dumps(json.loads(sys.stdin.read(), strict=False))) except Exception: pass ' 2>/dev/null + else + tr -d '\000-\037' + fi } # --- Unread messages ---------------------------------------------------------