Daemonless ticket-queue poller for the sonu plugin — cron wrapper that wakes a headless agent session only when a trigger label or in-flight ticket branch exists PrabhdeepSingh's sonu plugin introduces a daemonless ticket-queue poller, a cron wrapper that wakes a headless agent session only when a trigger label or in-flight ticket branch exists. The script, factory-poll.sh, uses flock for serialization and checks for specific labels and ticket branches to minimize API calls and token usage. | /usr/bin/env bash | | | factory-poll.sh — the entire "daemon" for the sonu plugin's ticket queue. | | | | | | Polls a repo's ticket queue and, only when there is something to do, spawns | | | one headless agent session that runs /sonu:factory scan, claim, route, | | | build in a worktree, sweep . All the intelligence lives in the plugin; | | | this script only decides whether it's worth waking the agent. | | | | | | Requires: the sonu plugin installed github.com/PrabhdeepSingh/claude-plugins , | | | an authenticated gh CLI, and a tracker configured via /sonu:factory init. | | | | | | Install cron, every 15 minutes : | | | /15 $HOME/.sonu/factory-poll.sh | | | Or on macOS, a launchd plist with StartInterval 900. | | | | | | Notes: | | | - flock keeps runs serialized one at a time , matching one-ticket-per-pass. | | | - The trigger labels are queried separately: gh issue list with two | | | --label flags is AND semantics, and a ticket only ever carries one trigger. | | | - In-flight ticket/ branches also wake the agent, or the close-the-loop | | | sweep would starve once triggers are consumed. | | | - Empty queue costs two API calls and zero tokens. | | | set -u | | | REPO DIR="/path/to/repo" <-- set me | | | cd "$REPO DIR" || exit 1 | | | mkdir -p "$HOME/.sonu" | | | exec 9 "$HOME/.sonu/factory.lock" | | | flock -n 9 || exit 0 a previous run is still going | | | queued=0 | | | for label in factory-ready-for-spec factory-ready-to-implement; do | | | n=$ gh issue list --state open --label "$label" --json number --jq 'length' 2 /dev/null || echo 0 | | | queued=$ queued + n | | | done | | | Tickets mid-flight carry no trigger by definition; their ticket/ branches | | | are what the sweep needs to see status flips, worktree cleanup . | | | inflight=$ git branch --list 'ticket/ ' | wc -l | tr -d ' ' | | | "$ queued + inflight " -gt 0 || exit 0 nothing queued, nothing to sweep | | | timeout 2h claude -p "/sonu:factory" "$HOME/.sonu/factory.log" 2 &1 |