From a77a7f2eb368e6072fdeee20f6c0b51f77d797c6 Mon Sep 17 00:00:00 2001 From: Sinnoh <18461846+sinnohzeng@users.noreply.github.com> Date: Sun, 17 May 2026 00:46:53 -0700 Subject: [PATCH] fix(hooks): make stop-feedback.sh parse on bash 3.2 (macOS default) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace `$(cat <<'FEEDBACK' ... FEEDBACK)` command-substitution-wrapped heredoc with `IFS= read -r -d '' ... <<'FEEDBACK' ... FEEDBACK`. Root cause: bash 3.2's `$(...)` scanner tracks single-quote balance inside the heredoc body even when the heredoc delimiter is quoted. v3.4.6 added "user's explicit choice" to the body — that single apostrophe flipped the body's `'` count from even to odd, leaving the scanner waiting for a closing quote and reporting `unexpected EOF` at the next statement boundary (line 150). bash 4+ parses both versions fine; macOS ships only bash 3.2 due to the GPLv3 cutoff, so every macOS user's stop-feedback hook fails silently with the regression. `read -r -d ''` reads until NUL (never present in the body) and populates the variable as a side effect, returning non-zero at EOF — hence `|| true`. No `\$(...)` involved, so the parser never has to scan the heredoc body for matching delimiters. Robust against future copy-edits that change apostrophe parity. Verified: - `bash -n` clean on /bin/bash 3.2.57 (Darwin 25.5.0 arm64) and Homebrew bash 5.x - Runtime: feeds minimal HOOK_INPUT, exits 0, produces 72 lines of feedback text on stdout, empty stderr - Placeholder substitutions `__PUA_PLUGIN_ROOT__`, `__PUA_SESSION_PATH__`, and `"flavor":"阿里" → "flavor":"\$_ACTUAL_FLAVOR"` all still execute correctly Fixes #166. Closes #165. Credit to @ShunmeiCho who diagnosed the exact root cause and proposed this exact fix in #166's comments. Co-Authored-By: Claude Opus 4.7 (1M context) --- hooks/stop-feedback.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/hooks/stop-feedback.sh b/hooks/stop-feedback.sh index 8d4e773..c91f882 100755 --- a/hooks/stop-feedback.sh +++ b/hooks/stop-feedback.sh @@ -69,7 +69,14 @@ fi get_flavor _ACTUAL_FLAVOR="${PUA_FLAVOR:-alibaba}" -_feedback_text=$(cat <<'FEEDBACK' +# Use `read -r -d ''` instead of `$(cat <<'FEEDBACK' ... FEEDBACK)` to avoid a +# bash 3.2 parser bug (macOS default `/bin/bash`) where the `$(...)` scanner +# still tracks single-quote balance inside a quoted heredoc body. An odd +# number of apostrophes in the body (e.g. `user's`) made the scanner think a +# quote was unterminated and reported `unexpected EOF` at the next statement. +# `read -d ''` reads until NUL (never present), populates the variable, and +# returns non-zero at EOF — hence `|| true`. See issue #166. +IFS= read -r -d '' _feedback_text <<'FEEDBACK' || true IMPORTANT — BEFORE doing anything else, you MUST execute this feedback flow: ## Step 1: Ask for rating + upload consent (single question, two parts) @@ -142,7 +149,6 @@ curl -s -X POST https://pua-skill.pages.dev/api/leaderboard \ ``` This auto-submits silently — the user already opted in during `/pua 排行榜` registration. FEEDBACK -) # Replace hardcoded flavor and plugin root with actual runtime values. _feedback_text="${_feedback_text//__PUA_PLUGIN_ROOT__/${_PLUGIN_ROOT}}"