diff --git a/mcptools/wait_for_bead.sh b/mcptools/wait_for_bead.sh new file mode 100755 index 0000000..b0530f1 --- /dev/null +++ b/mcptools/wait_for_bead.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# capabilities: beads +# description: Block until a bead matching --mount and --role is ready, then print its full JSON (including comments) and exit. Uses the anvillm/events stream — no polling. +# Usage: wait_for_bead.sh --mount [--role ] +set -euo pipefail + +MOUNT="" +ROLE="${AGENT_ROLE:-developer}" + +while [[ $# -gt 0 ]]; do + case "$1" in + --mount) MOUNT="$2"; shift 2 ;; + --role) ROLE="$2"; shift 2 ;; + *) echo "unknown argument: $1" >&2; exit 1 ;; + esac +done + +if [ -z "$MOUNT" ]; then + echo "usage: wait_for_bead.sh --mount [--role ]" >&2 + exit 1 +fi + +EXPECTED_SOURCE="beads/$MOUNT" + +9p read anvillm/events | while IFS= read -r line; do + type=$(echo "$line" | jq -r '.type // empty' 2>/dev/null) + [ "$type" = "BeadReady" ] || continue + + source=$(echo "$line" | jq -r '.source // empty' 2>/dev/null) + [ "$source" = "$EXPECTED_SOURCE" ] || continue + + # Check role label matches (format: "role:") + bead_role=$(echo "$line" | jq -r ' + .data.labels // [] | + map(select(startswith("role:"))) | + first // "" | + ltrimstr("role:") + ' 2>/dev/null) + # Default to "developer" if no role label + [ -z "$bead_role" ] && bead_role="developer" + [ "$bead_role" = "$ROLE" ] || continue + + # Emit full bead data and exit + echo "$line" | jq '.data' + exit 0 +done diff --git a/skills/beads/SKILL.md b/skills/beads/SKILL.md index 78b819a..d49b942 100644 --- a/skills/beads/SKILL.md +++ b/skills/beads/SKILL.md @@ -38,6 +38,14 @@ Tool: execute_code tool: list_mounts.sh ``` +Wait for a bead matching your mount and role (blocks until one is ready, returns full bead JSON including comments, then exits): +``` +Tool: execute_code +tool: wait_for_bead.sh +args: ["--mount", ""] +``` +`--role ` is optional; defaults to `$AGENT_ROLE` or `developer`. + List ready beads (open, unblocked): ``` Tool: execute_code