No description
Find a file
Viktor Barzin a7b4f7ba32 [beadboard] Add agent-dispatch and agent-status API routes
## Context

The Dispatch-to-Agent button in the right-panel (previous commit) calls
two endpoints that did not yet exist server-side:

- `POST /api/agent-dispatch` — resolve the bead via the same Dolt pool
  the existing `/api/beads/read` route uses, build a prompt from it, and
  forward to `claude-agent-service`'s `/execute` endpoint with a bearer
  token. This is the server-side trust boundary: the bearer token lives
  in env (never in the browser), and the bead is re-read from Dolt
  (never trusted from the client payload) so a malicious client cannot
  inject a prompt.

- `GET /api/agent-status` — proxy `claude-agent-service`'s `/health`
  endpoint (which already returns `{status, busy}`), with a 2 s in-
  memory cache so 5 s UI polls across multiple open tabs don't hammer
  the service.

The claude-agent-service serialises jobs behind an `asyncio.Lock` — a
second `/execute` while one is running returns HTTP 409 "Agent is busy".
We surface that 409 through to the browser unchanged so the UI can show
the right toast/status line without re-mapping status codes.

```
client ──► /api/agent-dispatch ──► claude-agent-service /execute
             │                        (asyncio.Lock guards)
             └─► reads bead from Dolt pool (same path as /api/beads/read)
             └─► buildDispatchPrompt(bead)
             └─► POST {prompt, agent, budget, timeout} + Bearer token

client ──► /api/agent-status (2s cache) ──► /health  ──► {busy: bool}
```

## This change

### `src/app/api/agent-dispatch/route.ts`

- `POST {taskId: string}` handler.
- Validates JSON body and non-empty taskId (→ 400).
- Early 500 if `CLAUDE_AGENT_SERVICE_URL` or `CLAUDE_AGENT_BEARER_TOKEN`
  is missing — fail fast, fail loud.
- Resolves the bead via `readIssuesFromDisk({preferBd: true})`, which
  uses the existing Dolt client (and falls back to `issues.jsonl`).
  Filtering by id after is acceptable at BeadBoard's scale (~hundreds
  of beads) and avoids introducing a new single-bead query path.
- 400 when the bead is missing, or when `acceptance_criteria?.trim()` is
  empty — defense in depth alongside the UI disable. The button should
  already hide in these cases, but a curl'd POST must still be rejected.
- Forwards to `${CLAUDE_AGENT_SERVICE_URL}/execute` with agent
  `beads-task-runner`, max_budget_usd 5, timeout_seconds 900 (matches
  the values in the task spec).
- Passes through 409 verbatim. Other upstream errors collapse to 502.

### `src/app/api/agent-status/route.ts`

- `GET` handler, module-level snapshot cache with 2 s TTL to avoid
  hammering `/health`.
- In-flight de-dup: a single pending `fetchRemoteStatus()` is shared
  across concurrent requests so we only hit the upstream once per
  window even under bursty load.
- When `CLAUDE_AGENT_SERVICE_URL` is unset, returns `{busy: false}` and
  skips the fetch entirely — this is how the dev server boots before
  the service env is configured.
- HTTP 503 from upstream is interpreted as `busy: true` (future-proofing
  in case the service swaps 409 for 503 on overload).
- Any network error degrades gracefully to `{busy: false}` — the 409
  path on `/api/agent-dispatch` is the authoritative gate.

### Test coverage

- `tests/api/agent-dispatch-route.test.ts` (3 cases): invalid JSON body,
  missing taskId, missing env returns 500.
- `tests/api/agent-status-route.test.ts` (3 cases): unset service URL
  returns `{busy: false}` without a fetch, `/health busy:true` proxies
  through, HTTP 503 maps to busy=true. Uses a `globalThis.fetch` stub
  and cache-busting query params on dynamic import so each case starts
  from a fresh module snapshot.

## What is NOT in this change

- End-to-end happy-path coverage (bead loads, fetch returns 200, route
  yields job_id) would require mocking `readIssuesFromDisk` — that's a
  bigger refactor than this commit warrants. Live integration happens
  once the pipeline is wired.
- No retry/backoff on upstream failures. 502 passes through; the client
  decides whether to retry.
- No auth on the routes themselves — they inherit the Next.js app's
  session model (same as all other `/api/*` routes today).

## Test Plan

### Automated

```
$ node --import tsx --test tests/api/agent-dispatch-route.test.ts \
    tests/api/agent-status-route.test.ts
# tests 6 pass 6 fail 0 duration_ms 1560
```

All six route cases pass. Typecheck output shows only the pre-existing
`OrchestratorChatMessage` gap in `left-panel.tsx`. Lint output is
unchanged from `main` (1 pre-existing `no-require-imports` error in
`src/lib/bb-pi-bootstrap.ts`).

### Manual Verification

1. Export env:
   ```
   export CLAUDE_AGENT_SERVICE_URL=http://claude-agent-service.claude-agent.svc.cluster.local:8080
   export CLAUDE_AGENT_BEARER_TOKEN=$(vault kv get -field=api_bearer_token secret/claude-agent-service)
   ```
2. `npm run dev`
3. `curl -s http://localhost:3000/api/agent-status` → `{"busy":false}`
   (if the service is reachable; `{"busy":true}` if a job is running).
4. `curl -X POST http://localhost:3000/api/agent-dispatch \
       -H 'content-type: application/json' \
       -d '{"taskId":"beadboard-xyz"}'`
   - 400 if bead does not exist or lacks acceptance criteria.
   - 200 `{"job_id":"..."}` on success.
   - 409 `{"error":"Agent is busy"}` when an agent is already running.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:07:21 +00:00
.beads chore: recreate orchestrator backlog with proper bead naming and descriptions 2026-03-25 23:15:36 -05:00
.github chore: swap Discord for GitHub Discussions 2026-03-25 00:48:04 -05:00
assets fix(layout): unified right sidebar with chat mode and collapsing activity rail 2026-02-16 23:50:20 -08:00
bin feat(cli): route runtime commands and add bd diagnostics to status 2026-03-02 21:19:12 -08:00
components/ui checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
docs fix: orchestrator button + Pi SDK session error 2026-03-24 19:02:04 -05:00
help checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
install Cleanup: Runtime artifacts, hard-coded paths, PR 14 bug fixes 2026-03-05 15:57:33 -08:00
lib chore: misc updates and fixes 2026-02-26 10:25:31 -08:00
public fix(bb-ui2): integrate ThreadView into detail panels with sample data 2026-02-16 10:10:50 -08:00
reference/routes checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
scripts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
skills Cleanup: Runtime artifacts, hard-coded paths, PR 14 bug fixes 2026-03-05 15:57:33 -08:00
src [beadboard] Add agent-dispatch and agent-status API routes 2026-04-18 14:07:21 +00:00
tests [beadboard] Add agent-dispatch and agent-status API routes 2026-04-18 14:07:21 +00:00
tools checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
.eslintrc.json checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
.gitattributes chore: initialize beadboard baseline 2026-02-11 17:42:51 -08:00
.gitignore beads back 2026-03-24 19:02:04 -05:00
AGENTS.md bd init: initialize beads issue tracking 2026-03-24 19:02:04 -05:00
CLAUDE.md feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00
components.json feat(ui): complete bb-ui2.2 - shadcn/ui Setup 2026-02-15 21:16:26 -08:00
CONTRIBUTING.md Update CONTRIBUTING.md 2026-03-29 13:37:46 -07:00
eslint.config.mjs checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
LICENSE checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
next-env.d.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
next.config.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
NEXT_SESSION_PROMPT.md Cleanup: Runtime artifacts, hard-coded paths, PR 14 bug fixes 2026-03-05 15:57:33 -08:00
package-lock.json fix: orchestrator button + Pi SDK session error 2026-03-24 19:02:04 -05:00
package.json [beadboard] Add agent-dispatch and agent-status API routes 2026-04-18 14:07:21 +00:00
postcss.config.js feat: establish tokenized kanban design foundation 2026-02-11 18:38:51 -08:00
project.md refactor: extract agent bounded context + fix SSE comments + cleanup unused 2026-03-04 22:06:40 -08:00
README.md Revise installation section in README.md 2026-03-27 18:35:24 -07:00
remotion.config.ts fix(bb-ui2): integrate ThreadView into detail panels with sample data 2026-02-16 10:10:50 -08:00
tailwind.config.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
tsconfig.json feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00

🚧 The bb-pi orchestrator is under construction — help us build it! Use your own coding agent alongside BeadBoard for now. 🚧

BeadBoard

License: MIT GitHub stars Built on Beads

Multi-agent orchestration and communication system built on Beads.

Agents claim tasks, send structured mail to each other, track dependencies, and close work with evidence. BeadBoard is the coordination layer — a dashboard that shows it all happening live, a CLI (bb) that hosts the orchestrator and manages agent communication, and a built-in execution runtime (bb-pi) that can spawn and manage agent workers directly.

Built on Beads and inspired by Gastown.

BeadBoard Dashboard


📦 Installation

Prerequisites

  • Node.js 18.18+ (Node 20 LTS recommended)
  • npm 7.0+
  • Dolt (recommended — see Dolt section)

Install from Source

git clone https://github.com/zenchantlive/beadboard.git
cd beadboard
npm install
npm install -g .

This installs:

  • beadboard / bb — BeadBoard CLI: dashboard, orchestrator host, agent communication commands
  • bd — Beads CLI for task management (also available standalone: npm install -g @beads/bd)
beadboard --version
bd --version

Alternative: POSIX install script (Linux/macOS):

bash ./install/install.sh    # installs bb + beadboard shims to ~/.beadboard/bin

Or just tell your agent:

Install Beadboard, and the beadboard-driver skill from https://github.com/zenchantlive/beadboard and use it to coordinate your work. Run npx skills add zenchantlive/beadboard --skill beadboard-driver then follow the SKILL.md runbook.

Then add to your project's AGENTS.md or CLAUDE.md:

## BeadBoard

You have access to the **beadboard-driver** skill.

- Always use beadboard-driver as your entrypoint for coordination work (tasks, context, status)
  instead of inventing your own workflow.
- Use it to read and update Beads via `bd`, keep work state consistent with the BeadBoard UI,
  and obey the verification rules described in the Beadboard-Driver Skill.
- When in doubt about what to do next or how to record progress, call beadboard-driver and
  follow its guidance rather than editing markdown ad hoc.

See skills/beadboard-driver/SKILL.md for the complete agent runbook.


🚀 Add BeadBoard Skill to Your Agent

npx skills add zenchantlive/beadboard --skill beadboard-driver

This installs the beadboard-driver skill — a 9-step operating contract that gives your agent:

  • 📋 Task coordination through dependency-constrained graphs
  • 💬 Structured agent-to-agent messaging (HANDOFF, BLOCKED, DECISION, INFO)
  • 🔒 Scope-based work reservations with liveness-aware conflict resolution
  • 📡 Realtime progress tracking via heartbeats and activity streams
  • Evidence-required workflow — agents can't close work without verification gates

Quick Start

cd ~/my-project
bd init                        # initialize Beads in your project
beadboard start --dolt         # start the dashboard with Dolt (recommended)

Open http://localhost:3000.

bd create --title "My first task" --type task --priority 0

🗄️ Dolt

BeadBoard uses Dolt — a version-controlled SQL database — as its primary backend. Dolt gives you:

  • Full version history of every issue state change
  • SQL queries across all your issues and projects
  • bd dolt pull / bd dolt push for multi-agent sync across machines
  • Branch-based workflows
# macOS
brew install dolt

# Linux / Windows
curl -L https://github.com/dolthub/dolt/releases/latest/download/install.sh | bash

Without Dolt, BeadBoard falls back to reading .beads/issues.jsonl directly. This is enough to poke around, but you'll want Dolt for real work.


🔧 What BeadBoard Does

BeadBoard is three things:

The Dashboard

A live operations console with Social, Graph, and Activity views — updating in realtime via SSE as agents work.

The CLI (bb)

A full agent command center — not just a dashboard launcher:

# Agent lifecycle
bb agent register --name <id> --role <role>
bb agent list
bb agent activity-lease --agent <id>

# Agent-to-agent communication
bb agent send --from <id> --to <id> --bead <id> --category HANDOFF --subject "..."
bb agent inbox --agent <id>
bb agent ack --agent <id> --message <msg-id>

# Work reservations
bb agent reserve --agent <id> --scope <scope> --bead <id>
bb agent release --agent <id> --scope <scope>

# Orchestrator runtime
bb daemon start
bb daemon tui                    # interactive orchestrator REPL
bb daemon bootstrap              # install Pi runtime

The Orchestrator (bb-pi)

A built-in execution runtime that spawns and manages typed worker agents.


🧩 Core Features

💬 Agent Communication System

Structured message lifecycle for inter-agent coordination:

  • Message categories: HANDOFF, BLOCKED, DECISION, INFO
  • Required acknowledgment for high-signal categories (HANDOFF, BLOCKED)
  • Broadcast & role-based routing — send to all agents or by role (role:tester)
  • Per-task threads combining activity events, agent mail, and local interactions
  • Message states: unreadreadacked
bd mail inbox
bd mail send --to <agent> --bead <id> --category HANDOFF --subject "Ready for review"
bd mail ack <message-id>

🔒 Work Reservations

Agents can lock scopes (file paths, task regions) to prevent conflicting work:

  • TTL-based reservations (default 120 min)
  • Liveness-aware conflict resolution — stale agents (15min no heartbeat) can be taken over
  • File-based mutex prevents race conditions

📊 DAG Graph Visualization

DAG-oriented workspace for execution decisions:

  • Task and dependency tab modes for different planning lenses
  • Blocked chains highlighted, assignees on nodes
  • Cycle detection and blocked-chain identification

Dependency Graph View

👥 Swarm Coordination

Agent pool monitor with:

  • Archetypes — typed agent roles (architect, engineer, reviewer, tester, investigator, shipper)
  • Templates — preset team compositions (feature-dev, bug-fix, full-squad, greenfield, research-and-discovery)
  • "Needs Agent" queue for unassigned work
  • Pre-assigned queue and squad roster

Swarm Coordination Panel

📡 Realtime Operations

  • Live updates via Chokidar file watchers + Server-Sent Events
  • Activity stream with session/task context
  • Agent heartbeat and liveness tracking (active → stale → evicted)

🌐 Multi-Project Scope

  • Project registry with scanner-backed discovery
  • Single-project and aggregate modes
  • Runtime scope switching without leaving the workspace

🤖 bb-pi Orchestrator

🚧 Under active construction. The orchestrator works but has known issues being fixed. Use your own coding agent alongside BeadBoard for now, or help us improve it!

bb-pi is BeadBoard's embedded execution runtime, built on Pi (@mariozechner/pi-coding-agent). It runs a long-lived orchestrator per project that spawns typed worker agents, tracks their bead claims, and streams a live transcript.

Working today (Phases 1-3):

  • Embedded orchestrator with BeadBoard-aware tools (bb_spawn_worker, bb_worker_status, bb_create, bb_close, etc.)
  • Worker spawning with numbered display names (Engineer 01, Engineer 02...)
  • Capability-gated agent types — architects/reviewers get read-only tools, engineers/testers get full code edit/write/bash
  • Template-based team spawning via bb_spawn_team — spin up a full squad from a preset
  • Bead-required workflow — every worker claims a bead, posts progress, closes with evidence
  • Async coordination — non-blocking spawn with status polling and result reads
  • Chat-style orchestrator transcript with realtime telemetry
  • Interactive orchestrator REPL via bb daemon tui

Known issues being fixed:

  • Double-reply rendering in orchestrator chat
  • Silent failures — errors not yet surfaced to UI
  • Session race condition under rapid use

Phases 4-7 (launch-anywhere UX, agent presence in views, hardening, full test coverage) are on the roadmap. See docs/plans/2026-03-05-embedded-pi-roadmap.md.


🏗️ Architecture

┌─────────────────────────────────────────────────────────────┐
│                      BeadBoard UI                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐    │
│  │  Social  │  │  Graph   │  │ Activity │  │  Swarm   │    │
│  │  View    │  │  View    │  │  View    │  │  Panel   │    │
│  └──────────┘  └──────────┘  └──────────┘  └──────────┘    │
└─────────────────────────────────────────────────────────────┘
         │              │              │              │
    ┌────▼──────────────▼──────────────▼──────────────▼────┐
    │                  bb CLI / bb-pi runtime               │
    │  agent register · agent send · daemon tui · spawn     │
    └──────────────────────────┬───────────────────────────┘
                               │
              ┌────────────────┼────────────────┐
              │                │                │
        ┌─────▼─────┐  ┌──────▼──────┐  ┌──────▼──────┐
        │    SSE     │  │    Dolt     │  │  Chokidar   │
        │   Events   │  │  (SQL DB)   │  │  Watchers   │
        └───────────┘  └─────────────┘  └─────────────┘
              │                │                │
              └────────────────┼────────────────┘
                               │
                        ┌──────▼──────┐
                        │     bd      │
                        │ (Beads CLI) │
                        └─────────────┘

Tech Stack

Layer Technologies
Frontend Next.js 15 (App Router), React 19, TypeScript (strict)
Styling Tailwind CSS, Radix UI, Framer Motion
Graph @xyflow/react, Dagre
Database Dolt (version-controlled SQL)
Realtime Chokidar watchers, Server-Sent Events
Agent Runtime @mariozechner/pi-coding-agent (bb-pi)

Data Flow

  1. Write path: bd commands write to .beads/issues.jsonl and Dolt DB
  2. Read path: UI queries Dolt SQL (falls back to JSONL when Dolt is unavailable)
  3. Realtime: bd touches .beads/last-touched → Chokidar fires → SSE event → UI update

Key Concepts

Component Purpose
bd Beads CLI — task and dependency management
bb / beadboard BeadBoard CLI — dashboard, orchestrator host, agent commands
bb-pi Embedded Pi execution runtime (under construction)
beadboard-driver Agent skill — operating contract for coordination

🌍 Platform Support

Runs on macOS, Linux, and Windows.

  • macOS / Linux: bash ./install/install.sh installs shims to ~/.beadboard/bin
  • Windows: Path handling canonicalizes drive letter casing and backslash normalization. Mixed WSL2 + Windows setups require mirrored networking.

📁 Project Structure

beadboard/
├── src/
│   ├── app/                    # Next.js App Router pages + API routes
│   ├── components/             # UI: shared, graph, social, swarm, agents, sessions
│   ├── hooks/                  # React hooks (subscriptions, URL state, etc.)
│   ├── lib/                    # Core domain logic (parser, types, mail, registry, etc.)
│   └── tui/                    # Orchestrator TUI + agent tools
├── skills/
│   └── beadboard-driver/       # Agent skill package (runbook + scripts + tests)
├── install/                    # Platform install scripts
├── docs/                       # PRDs, roadmaps, ADRs, screenshots
└── tests/                      # Test suite (explicitly enumerated in package.json)

🛠️ Scripts

npm run dev          # Development server (localhost:3000)
npm run build        # Production build
npm run start        # Production server
npm run typecheck    # TypeScript validation (tsc --noEmit)
npm run lint         # ESLint
npm run test         # Full test suite

New test files must be added to the test script in package.json — the suite is explicitly enumerated, not auto-discovered.


🤝 Contributing

We welcome contributions from humans and AI agents. See CONTRIBUTING.md for the full guide.

Quick version:

  1. Find work: check GitHub Issues or run bd list --label contrib:open
  2. Small PRs preferred (under ~100 lines). For larger changes, open an issue first.
  3. Run the gates: npm run typecheck && npm run lint && npm run test
  4. PR against main

Join the Discussion to coordinate on contributions, get help, or discuss ideas.


📄 License

MIT


🙏 Acknowledgments

Built on Beads by Steve Yegge, inspired by Gastown. The bb-pi execution runtime uses Pi by @mariozechner.