Files
hermes-config/bin/hermes-dispatch

73 lines
1.8 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/bash
# hermes-dispatch — watch the queue, feed tasks into the hermes tmux pane
# Fire-and-forget: dispatches next task as soon as the prompt is visible.
# Does NOT wait for completion — just ensures hermes is idle before sending.
set -euo pipefail
QUEUE_DIR="$HOME/.hermes/queue"
TARGET_PANE="${HERMES_PANE:-Hermes:0.0}"
POLL_INTERVAL="${POLL_INTERVAL:-2}"
log() { echo "[$(date +%H:%M:%S)] $*"; }
is_hermes_idle() {
# Strip blank lines, check bottom of pane for the input prompt
local content
content=$(tmux capture-pane -t "$TARGET_PANE" -p 2>/dev/null | grep -v '^$' | tail -4)
echo "$content" | grep -qE '⚕ |type a message'
}
pick_next_task() {
for pri in high normal low; do
local task
task=$(ls "$QUEUE_DIR/pending/${pri}_"*.task 2>/dev/null | head -1)
if [[ -n "$task" ]]; then
echo "$task"
return
fi
done
}
dispatch_task() {
local task_file="$1"
local basename=$(basename "$task_file")
local prompt
prompt=$(grep '^PROMPT=' "$task_file" | sed 's/^PROMPT=//')
if [[ -z "$prompt" ]]; then
log "ERROR: empty prompt in $basename"
mv "$task_file" "$QUEUE_DIR/failed/$basename"
return
fi
log "DISPATCH: $basename"
log " → ${prompt:0:100}"
# Move to done immediately (fire-and-forget)
mv "$task_file" "$QUEUE_DIR/done/$basename"
# Send to pane
tmux send-keys -t "$TARGET_PANE" "$prompt" Enter
}
# --- Main loop ---
log "hermes-dispatch started (fire-and-forget mode)"
log "Pane: $TARGET_PANE | Poll: ${POLL_INTERVAL}s"
log "Watching: $QUEUE_DIR/pending/"
while true; do
task=$(pick_next_task)
if [[ -n "$task" ]]; then
if is_hermes_idle; then
dispatch_task "$task"
# Give hermes a moment to start processing before next poll
sleep 8
fi
fi
sleep "$POLL_INTERVAL"
done