From 1933c6cb1d388528526967d90965e0e28d9d0d65 Mon Sep 17 00:00:00 2001 From: "jason.woltje" Date: Sat, 25 Jul 2026 22:56:46 +0000 Subject: [PATCH] feat(framework): accept digest message class in agent-send.sh (W1) (#894) Co-authored-by: jason.woltje Co-committed-by: jason.woltje --- .../mosaic/framework/tools/tmux/agent-send.sh | 7 ++++--- .../framework/tools/tmux/agent-send.test.sh | 21 +++++++++++++++++-- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/packages/mosaic/framework/tools/tmux/agent-send.sh b/packages/mosaic/framework/tools/tmux/agent-send.sh index 9809bf70..9da54052 100755 --- a/packages/mosaic/framework/tools/tmux/agent-send.sh +++ b/packages/mosaic/framework/tools/tmux/agent-send.sh @@ -46,6 +46,7 @@ # actionable carries a decision/blocker/gate — deliver # human from a human operator — deliver # reaction an emoji/ack reaction +# digest machine-wake, coalescible; batched wake/heartbeat signal # Long form: --class CLASS (or --class=CLASS). When SET, the # preamble carries a ` class=` token INSIDE the bracket: # [ -> class=terminal-log] @@ -58,7 +59,7 @@ # -h help # # PREAMBLE GRAMMAR (for consumers / daemons mirroring this producer) -# ^\[(\S+) -> (\S+?)(?: class=(terminal-log|actionable|human|reaction))?\] (.*)$ +# ^\[(\S+) -> (\S+?)(?: class=(terminal-log|actionable|human|reaction|digest))?\] (.*)$ # group 1 = src label group 2 = dst host:session # group 3 = class (absent => actionable) group 4 = message body # @@ -109,8 +110,8 @@ done CLASS_TOKEN="" if [ -n "$CLASS" ]; then case "$CLASS" in - terminal-log|actionable|human|reaction) CLASS_TOKEN=" class=${CLASS}" ;; - *) echo "ERROR: invalid --class '$CLASS' (allowed: terminal-log, actionable, human, reaction)" >&2; exit 3 ;; + terminal-log|actionable|human|reaction|digest) CLASS_TOKEN=" class=${CLASS}" ;; + *) echo "ERROR: invalid --class '$CLASS' (allowed: terminal-log, actionable, human, reaction, digest)" >&2; exit 3 ;; esac fi diff --git a/packages/mosaic/framework/tools/tmux/agent-send.test.sh b/packages/mosaic/framework/tools/tmux/agent-send.test.sh index bc94e5f4..87a1ed90 100755 --- a/packages/mosaic/framework/tools/tmux/agent-send.test.sh +++ b/packages/mosaic/framework/tools/tmux/agent-send.test.sh @@ -17,6 +17,9 @@ # 8. MOSAIC_AGENT_NAME is authoritative for sender identity. # 9. sender fallback queries local tmux, never the destination -L socket. # 10. an undeterminable sender is stamped as "?". +# 11. --class digest is accepted (machine-wake, coalescible canon class). +# 12. -C digest short form parses identically. +# 13. the documented consumer regex parses producer output for class=digest. set -uo pipefail HERE=$(cd -- "$(dirname -- "$0")" && pwd) @@ -65,7 +68,7 @@ run_auto() { } # Documented consumer grammar — the daemon will mirror exactly this. -GRAMMAR='^\[(\S+) -> (\S+) class=(terminal-log|actionable|human|reaction)\] (.*)$' +GRAMMAR='^\[(\S+) -> (\S+) class=(terminal-log|actionable|human|reaction|digest)\] (.*)$' GRAMMAR_NOCLASS='^\[(\S+) -> (\S+)\] (.*)$' # 1. REGRESSION BAR: classic preamble, byte-for-byte. @@ -108,8 +111,22 @@ else [ "$?" = 3 ] && ok "--class with no value => exit 3" || no "--class with no value => exit 3" "wrong rc" fi +# 11. --class digest (space form) is accepted. +got=$(run -s mos --class digest -m "wake payload") +want='[a:src -> dsthost:mos class=digest] wake payload' +if [ "$got" = "$want" ]; then ok "--class digest emits token" +else no "--class digest emits token" "got=[$got] want=[$want]" +fi + +# 12. -C digest short form. +got=$(run -s mos -C digest -m "coalesced wake") +want='[a:src -> dsthost:mos class=digest] coalesced wake' +if [ "$got" = "$want" ]; then ok "-C digest (short form)" +else no "-C digest (short form)" "got=[$got] want=[$want]" +fi + # 7. consumer grammar parses every class + classic line. -for c in terminal-log actionable human reaction; do +for c in terminal-log actionable human reaction digest; do line=$(run -s mos --class "$c" -m "body $c") [[ "$line" =~ $GRAMMAR ]] && [ "${BASH_REMATCH[3]}" = "$c" ] && [ "${BASH_REMATCH[4]}" = "body $c" ] \ && ok "grammar parses class=$c" || no "grammar parses class=$c" "line=[$line]"