Collab Scripts
Shell scripts for launching and managing teams, designed for integration with Claude Code and other AI-assisted workflows.
All scripts live in scripts/ and use collab-paths.sh for consistent path resolution.
collab-launch.sh
All-in-one team launcher. Creates team, starts bridge, opens monitor.
./scripts/collab-launch.sh <working-directory> <task-description> [agents] [template]
Examples:
# Default: codex (lead) + claude (worker)
./scripts/collab-launch.sh ~/myproject "Review all API endpoints for security issues"
# Custom agents: comma-separated list (first = lead)
./scripts/collab-launch.sh ~/myproject "Security audit" codex,claude,grok
# With a role template from collab-templates.json
./scripts/collab-launch.sh ~/myproject "Security audit" codex,claude review
Both optional arguments have an env-var equivalent, so a line-up or template you always want does not have to be retyped:
| Argument | Env var | Precedence |
|---|---|---|
3rd (agents) | COLLAB_AGENTS | argument > env var > default pair |
4th (template) | COLLAB_TEMPLATE | argument > env var > generic lead/worker roles |
Naming agents, by argument or by COLLAB_AGENTS, also disables the auto-fallback that preflight uses to swap out a dead agent. A named agent that is broken becomes a hard preflight failure instead of a silent substitution.
What it does:
- Starts the ensemble server (if not running)
- Runs
collab-preflight.shfor exactly the agents this run needs - Creates a team via API
- Starts the ensemble bridge
- Opens the TUI monitor, picking the best viewer automatically (see table below)
- Starts a background message poller
- Waits for agents to begin communicating
Monitor selection (override with COLLAB_MONITOR=herdr|tmux|iterm|none):
| Situation | Monitor opened |
|---|---|
Inside a herdr workspace (HERDR_ENV=1) | herdr pane, labelled after the project directory |
| Inside tmux already | tmux split pane (right 40%) |
| macOS + iTerm2, not in tmux | native iTerm2 split pane |
| Linux, or no iTerm2 | detached tmux session (tmux attach -t ensemble-<id>) |
herdr is checked before iTerm2: it passes TERM_PROGRAM=iTerm.app through unchanged, so trusting that variable opens a real iTerm split outside the layout you are watching.
Layout overrides: COLLAB_ITERM_MODE=split|tab|window and COLLAB_HERDR_MODE=split|tab (both default to split).
Output (herdr example, three agents):
◈ ensemble collab
Review all API endpoints for security issues
✓ Server running
✓ Team created (collab-1774001029143-7384)
✓ Bridge started
✓ Monitor opened (herdr split)
✓ Agents communicating (2 messages)
Team is live! codex-1 + claude-2 + grok-3 are collaborating.
The last line of stdout is a machine-readable TEAM_ID=<id> trailer. Grep for that instead of reading /tmp/collab-team-id.txt, which is global and gets overwritten when two collabs run at the same time.
collab-preflight.sh
Verifies the agents can actually work before a team is spawned. Run automatically by collab-launch.sh; skip with COLLAB_SKIP_PREFLIGHT=1.
./scripts/collab-preflight.sh [agents-csv]
Only the CLIs you name are checked, so a codex quota wall does not block a grok,claude run. The codex check is a real codex exec that must return a sentinel string: an auth mode that rejects the configured model answers with an ordinary error containing no quota wording, and used to be reported as healthy right before the agent spawned and sat silent all session.
| Exit | Meaning |
|---|---|
| 0 | Safe to launch |
| 1 | Ensemble service not running |
| 2 | Service is stale (started without auth, restart it) |
| 3 | Claude CLI broken, or a named agent is unavailable |
| 4 | Codex CLI broken |
| 5 | DNS/network issue |
| 6 | Grok CLI broken |
collab-poll.sh
Single-shot message poller. Fetches new messages since last call, tracks state automatically.
./scripts/collab-poll.sh <team-id> [--sleep N]
| Flag | Description |
|---|---|
--sleep N | Wait N seconds before polling |
Output format: tab-separated sender\tcontent lines, ending with a status line:
| Status | Meaning |
|---|---|
---STATUS:ACTIVE | New messages found |
---STATUS:QUIET | No new messages |
---STATUS:DONE | Team finished (summary follows) |
---STATUS:WAITING | Messages file not yet created |
Example:
./scripts/collab-poll.sh abc-123 --sleep 15
# codex-1 I found a SQL injection vulnerability in auth.ts line 42
# claude-2 Confirmed. The input is not sanitized before the query
# ---STATUS:ACTIVE
State is tracked in /tmp/ensemble/<team-id>/.poll-seen — no need to manage offsets manually.
collab-livefeed.sh
Continuous live feed. Streams messages to stdout in real time. Blocks until team finishes.
./scripts/collab-livefeed.sh <team-id>
Best used in a separate terminal or tmux pane:
# In a separate pane
./scripts/collab-livefeed.sh abc-123
collab-status.sh
Dashboard for all active and recent teams.
./scripts/collab-status.sh [--once] [--interval SECONDS]
| Flag | Description |
|---|---|
--once | Print snapshot and exit |
--interval N | Refresh every N seconds (default: 5) |
Shows: team name, status (active/finished/stale), message count, last message, duration, agents.
collab-replay.sh
Replay a past collaboration session with timing and colors.
./scripts/collab-replay.sh <team-id> [--speed N] [--verbose]
| Flag | Description |
|---|---|
--speed N | Playback speed multiplier (default: 1, 0 = instant) |
--verbose | Include ensemble system messages |
collab-cleanup.sh
Remove finished team runtime directories from /tmp/ensemble/. Dry-run by default.
./scripts/collab-cleanup.sh # list what would be deleted
./scripts/collab-cleanup.sh --force # actually delete
This does not disband a running team. To end one, press d in the monitor or POST /api/ensemble/teams/<id>/disband.
team-say.sh / team-read.sh
Low-level agent communication. Used internally by agents during collaboration.
# Agent sends a message (from agent, to recipient)
./scripts/team-say.sh <team-id> <from> <to> "message"
# Agent reads messages
./scripts/team-read.sh <team-id>
These use fcntl.flock for atomic JSONL writes to prevent message corruption.
ensemble-bridge.sh
Message bridge between file-based and HTTP communication. Started automatically by collab-launch.sh.
- Polls
messages.jsonlfor new messages - POSTs them to the ensemble API
- Handles retries with exponential backoff
- Differentiates client errors (skip) from server errors (retry)
- Single-instance guard (won’t double-start)
- Auto-stops when
.finishedmarker appears
parse-messages.py
Shared JSONL message parser. Used by poll, livefeed, and status scripts.
python3 scripts/parse-messages.py <file> [options]
| Option | Description |
|---|---|
--skip N | Skip first N lines |
--max-content N | Truncate content to N chars (default: 500) |
--include-ensemble | Include ensemble system messages |
--meta-only | Output metadata (count, timestamps) instead of messages |