toolkit/packages/skills/swarm-inbox/SKILL.md
Read and send inter-agent messages within a swarm team
npx skillsauth add stevengonsalvez/agents-in-a-box swarm-inboxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Read your inbox or send messages to other team members.
# Read your messages
/swarm-inbox
# Read with options
/swarm-inbox --last 10
# Send a message
/swarm-inbox --to <agent> --msg "message"
# Broadcast to all
/swarm-inbox --broadcast --msg "message"
| Argument | Description |
|----------|-------------|
| (none) | Read all messages in your inbox |
| --last N | Read only the last N messages |
| --to <agent> | Send message to specific agent (leader, agent-1, etc.) |
| --msg "text" | Message content |
| --type <type> | Message type (default: status) |
| --broadcast | Send to all team members |
| Type | Usage |
|------|-------|
| task | Assign work to an agent |
| status | Progress update |
| handoff | Pass work to another agent |
| help | Request assistance |
| complete | Task completion notification |
| broadcast | Message to all members |
| shutdown | Graceful termination request |
When you receive /swarm-inbox (no send args):
Detect Current Context
# Find which team and agent you are
# This should be set in your session context
TEAM_ID="$CURRENT_SWARM_TEAM"
AGENT_NAME="$CURRENT_SWARM_AGENT"
# Or detect from environment/session name
SESSION_NAME=$(tmux display-message -p '#S' 2>/dev/null || echo "")
if [[ "$SESSION_NAME" =~ ^swarm-([0-9]+)-(.+)$ ]]; then
TEAM_ID="swarm-${BASH_REMATCH[1]}"
AGENT_NAME="${BASH_REMATCH[2]}"
fi
Read Messages
source {{HOME_TOOL_DIR}}/utils/swarm-lib.sh
MESSAGES=$(swarm_read_inbox "$TEAM_ID" "$AGENT_NAME" --last 20)
if [ "$(echo "$MESSAGES" | jq 'length')" -eq 0 ]; then
echo "No messages in inbox"
else
echo "=== Inbox: $AGENT_NAME ==="
echo "$MESSAGES" | jq -r '.[] | "[\(.ts | split("T")[1] | split("+")[0])] \(.from) -> \(.type): \(.payload | tostring)"'
fi
When you receive /swarm-inbox --to <agent> --msg "text":
Parse Arguments
TO_AGENT="agent-1" # from --to
MESSAGE="Task complete, ready for review" # from --msg
MSG_TYPE="${TYPE:-status}" # from --type or default
Construct Payload
# For simple text messages
PAYLOAD=$(jq -n --arg msg "$MESSAGE" '{message: $msg}')
# For task assignments (if type is task)
# PAYLOAD='{"task_id": "bd-123", "action": "start", "context": "..."}'
Send Message
swarm_send_message "$TEAM_ID" "$AGENT_NAME" "$TO_AGENT" "$MSG_TYPE" "$PAYLOAD"
echo "Message sent to $TO_AGENT"
When you receive /swarm-inbox --broadcast --msg "text":
PAYLOAD=$(jq -n --arg msg "$MESSAGE" '{message: $msg}')
swarm_broadcast "$TEAM_ID" "$AGENT_NAME" "broadcast" "$PAYLOAD"
echo "Broadcast sent to all team members"
=== Inbox: agent-1 ===
[11:30:15] leader -> task: {"task_id":"bd-007","action":"start"}
[11:45:22] agent-2 -> handoff: {"task_id":"bd-007","context":"Backend complete"}
[11:50:00] leader -> status: {"message":"Keep up the good work!"}
# Simple progress update
/swarm-inbox --to leader --msg "Task bd-007 at 50% progress"
# Request help
/swarm-inbox --to leader --type help --msg "Blocked on API auth issue"
# Task handoff
/swarm-inbox --to agent-2 --type handoff --msg '{"task_id":"bd-007","context":"Frontend ready for integration"}'
# Broadcast announcement
/swarm-inbox --broadcast --msg "Taking 5 min break, will resume shortly"
Messages are stored as JSONL (one JSON object per line):
{
"ts": "2026-02-03T11:30:15+00:00",
"from": "leader",
"to": "agent-1",
"type": "task",
"payload": {
"task_id": "bd-007",
"action": "start",
"context": "Implement user authentication endpoint"
}
}
Agents should poll their inbox regularly:
# Poll loop (conceptual - implement in agent behavior)
while true; do
NEW_MESSAGES=$(swarm_read_inbox "$TEAM_ID" "$AGENT_NAME" --last 5)
for msg in $(echo "$NEW_MESSAGES" | jq -c '.[]'); do
TYPE=$(echo "$msg" | jq -r '.type')
case $TYPE in
task)
# Handle task assignment
;;
shutdown)
# Graceful shutdown
;;
*)
# Log other messages
;;
esac
done
sleep 5
done
| File | Description |
|------|-------------|
| {{HOME_TOOL_DIR}}/swarm/{team-id}/inbox/leader.jsonl | Leader's inbox |
| {{HOME_TOOL_DIR}}/swarm/{team-id}/inbox/agent-1.jsonl | Agent 1's inbox |
| {{HOME_TOOL_DIR}}/swarm/{team-id}/inbox/agent-N.jsonl | Agent N's inbox |
documentation
Report reflect drain spend over a time window — tokens split by cached (cache_read), uncached writes (cache_creation), and io (input+output), with a $ estimate, grouped by day / outcome / model / transcript. Reads the drainer's cost log and surfaces outlier runs and cache-reuse health (the 41.5M-token failure mode = low cache reuse + high cache writes). Use to answer "what is reflection costing me" for the last day / week.
development
Show fleet status — every claude session running on the host, merged across ainb + claude-peers broker + background jobs. Use when you need to enumerate sessions before composing an action, see which sessions have a peer registered (broker-routable) vs tmux-only, check the `summary` of each session, or pipe the list into jq for filtering. Default output: text table. Pass --format json for LLM consumption.
testing
Ordered multi-step prompts to fleet targets, ack-gated between steps via JSONL assistant-turn-end detection. Use for cycles like disconnect→reconnect→verify, or any flow where step N+1 requires step N to have completed first. The skill BLOCKS until each target's transcript shows the next assistant turn finishing OR per-step timeout fires (default 300s).
development
Center control panel — enumerate every claude session that is blocked waiting on something: a user answer (AskUserQuestion fired), an API error retry, an idle assistant turn-end with no follow-up, or an explicit WAITING: marker. Returns rich JSON with signal kind + context per session. Use this when you've stepped away from the fleet and want one place to see everything that wants your attention and answer it.