diff --git a/cc-ci-plan/launch.sh b/cc-ci-plan/launch.sh index 2df50f0..abc5cf0 100755 --- a/cc-ci-plan/launch.sh +++ b/cc-ci-plan/launch.sh @@ -142,11 +142,21 @@ stop_loops() { done } -# Wake a loop by typing a one-line message into its tmux session (queues if mid-turn). +# Wake a loop by typing a message into its tmux session and SUBMITTING it. A single Enter after a +# long `send-keys -l` is often swallowed while the TUI ingests the paste (text left unsent in the +# input box), so retry Enter/C-m until the message's leading text is no longer in the input box. ping_session() { - local s="$1" msg="$2" + local s="$1" msg="$2" prefix i session_alive "$s" || return 0 - tmux send-keys -t "$s" -l -- "$msg" 2>/dev/null && { sleep 0.3; tmux send-keys -t "$s" Enter 2>/dev/null; } + prefix="${msg:0:28}" + tmux send-keys -t "$s" -l -- "$msg" 2>/dev/null || return 0 + sleep 0.5 + for i in 1 2 3 4 5; do + tmux send-keys -t "$s" Enter 2>/dev/null + sleep 1 + tmux capture-pane -pt "$s" 2>/dev/null | tail -4 | grep -qF -- "$prefix" || return 0 # submitted + tmux send-keys -t "$s" C-m 2>/dev/null; sleep 0.5 + done } # A loop can stall ALIVE on a usage/spend-limit notice: the claude process stays up (so the diff --git a/cc-ci-plan/msg-loop.sh b/cc-ci-plan/msg-loop.sh new file mode 100755 index 0000000..df24140 --- /dev/null +++ b/cc-ci-plan/msg-loop.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +# msg-loop.sh — reliably send a message to a loop's tmux session AND submit it. +# ------------------------------------------------------------------------- +# `tmux send-keys -l ` frequently leaves the text sitting UNSENT in +# the input box (the immediate Enter is swallowed while the TUI is still ingesting +# the paste). This types the message, then retries Enter/C-m until the text is no +# longer in the input box (= it was submitted), or gives up after a bounded loop. +# +# msg-loop.sh +# exit 0 = delivered; 2 = could not confirm submit; 1 = bad args / no session. +set -uo pipefail + +S="${1:?usage: msg-loop.sh }"; shift +MSG="$*" +[ -n "$MSG" ] || { echo "msg-loop: empty message"; exit 1; } +tmux has-session -t "$S" 2>/dev/null || { echo "msg-loop: no tmux session '$S'"; exit 1; } + +PREFIX="$(printf '%s' "$MSG" | head -c 28)" +# Submitted ⇔ the message's leading text is no longer in the input box (bottom of the pane). +in_input_box() { tmux capture-pane -pt "$S" 2>/dev/null | tail -4 | grep -qF -- "$PREFIX"; } + +tmux send-keys -t "$S" -l -- "$MSG" 2>/dev/null || { echo "msg-loop: send-keys failed"; exit 1; } +sleep 0.8 +for _ in 1 2 3 4 5 6 7 8 9 10; do + tmux send-keys -t "$S" Enter 2>/dev/null || true + sleep 1.2 + in_input_box || { echo "$S: delivered ✔"; exit 0; } + tmux send-keys -t "$S" C-m 2>/dev/null || true # some TUI states take C-m not Enter + sleep 0.8 + in_input_box || { echo "$S: delivered ✔"; exit 0; } +done +echo "$S: WARNING — could not confirm submit; message may remain in the input box" +exit 2