@@ -11,59 +11,49 @@ mkdir -p "${CLAUDE_PROJECT_DIR}/.claude"
1111FLAG=" ${CLAUDE_PROJECT_DIR} /.claude/.claudesay-active"
1212trap ' rm -f "$TTY_FILE"; rm -rf "$CLAUDE_PROJECT_DIR"' EXIT
1313
14- # Helper: write a transcript in the Claude Code JSONL format.
15- # Each entry wraps the message under a "message" key, matching what
16- # ~/.claude/projects/<proj>/<session>.jsonl actually contains.
17- make_transcript () {
18- local text=" $1 "
19- local tmp; tmp=$( mktemp)
20- jq -n ' {"type":"user","message":{"role":"user","content":"hello"}}' >> " $tmp "
21- jq -n --arg t " $text " \
22- ' {"message":{"role":"assistant","content":[{"type":"text","text":$t}]}}' >> " $tmp "
23- echo " $tmp "
24- }
25-
14+ # run_stop passes a response_preview string directly, matching the real Stop
15+ # hook input. Using response_preview avoids the one-turn delay caused by the
16+ # transcript being written AFTER the hook returns.
2617run_stop () {
27- local transcript =" $1 "
28- printf ' {"transcript_path":"%s"}\n ' " $transcript " \
18+ local preview =" $1 "
19+ jq -n --arg p " $preview " ' {"response_preview":$p} ' \
2920 | bash " $PLUGIN_ROOT /hooks/scripts/stop.sh"
3021}
3122
3223echo " === stop.sh: flag absent → silent approve ==="
3324rm -f " $FLAG "
34- out=$( run_stop /dev/null )
25+ out=$( run_stop " hello <claudesay mood= \" happy \" >hi</claudesay> " )
3526assert_eq " returns approve when flag absent" " $out " ' {"decision":"approve"}'
3627assert_eq " no tty output when flag absent" " $( cat " $TTY_FILE " ) " " "
3728
3829echo " "
3930echo " === stop.sh: flag present, tag found → emits systemMessage bubble ==="
4031mkdir -p " $( dirname " $FLAG " ) " ; touch " $FLAG "
41- TRANSCRIPT=$( make_transcript ' Great job! <claudesay mood="excited">All 3 tests pass!</claudesay>' )
42- out=$( run_stop " $TRANSCRIPT " )
32+ out=$( run_stop ' Great job! <claudesay mood="excited">All 3 tests pass!</claudesay>' )
4333assert_contains " returns approve decision" " $out " ' "decision": "approve"'
4434assert_contains " emits systemMessage key" " $out " ' "systemMessage"'
4535parsed=$( printf ' %s' " $out " | jq -r ' .systemMessage' 2> /dev/null || true)
4636assert_contains " bubble content in systemMessage" " $parsed " " All 3 tests pass!"
4737assert_eq " no direct tty write" " $( cat " $TTY_FILE " ) " " "
4838> " $TTY_FILE "
49- rm -f " $TRANSCRIPT "
5039
5140echo " "
5241echo " === stop.sh: flag present, no tag → silent approve ==="
53- TRANSCRIPT=$( make_transcript ' Here is some code without a tag' )
54- out=$( run_stop " $TRANSCRIPT " )
42+ out=$( run_stop ' Here is some code without a tag' )
5543assert_eq " returns approve when no tag" " $out " ' {"decision":"approve"}'
5644assert_eq " no tty output when no tag" " $( cat " $TTY_FILE " ) " " "
57- rm -f " $TRANSCRIPT "
5845
5946echo " "
6047echo " === stop.sh: multiple tags → uses last one ==="
61- TRANSCRIPT=$( make_transcript ' First <claudesay mood="happy">first msg</claudesay> then <claudesay mood="excited">second msg</claudesay>' )
62- out=$( run_stop " $TRANSCRIPT " )
48+ out=$( run_stop ' First <claudesay mood="happy">first msg</claudesay> then <claudesay mood="excited">second msg</claudesay>' )
6349parsed=$( printf ' %s' " $out " | jq -r ' .systemMessage' 2> /dev/null || true)
6450assert_contains " last tag wins" " $parsed " " second msg"
6551> " $TTY_FILE "
66- rm -f " $TRANSCRIPT "
52+
53+ echo " "
54+ echo " === stop.sh: empty response_preview → silent approve ==="
55+ out=$( run_stop ' ' )
56+ assert_eq " returns approve on empty preview" " $out " ' {"decision":"approve"}'
6757
6858echo " "
6959echo " === pre-tool-use.sh: flag absent → silent allow ==="
0 commit comments