beadboard/tests/lib
Viktor Barzin 394a771b67 [beadboard] Add Dispatch-to-Agent button and prompt template
## Context

We want a one-click path from the right-panel task detail into the
claude-agent-service runner, without the user copy-pasting the bead id
into a CLI or another tab. The runner expects a self-contained prompt
that restates the bead id, title, description, acceptance criteria, and
the guard rails the agent must operate under (no push, no file edits,
no terraform/kubectl/helm). The prompt template lives in `src/lib/` so
it can be tested and reused from the server-side dispatch route.

The right-panel button needs to:
- Only appear when the bead is actionable (`open` or `in_progress`).
- Disable itself while the claude-agent-service is already busy (the
  service has a global `asyncio.Lock` — parallel dispatches 409).
- Disable itself when the bead lacks acceptance criteria. An agent that
  doesn't know what "done" looks like burns budget and closes nothing.
- Surface the resulting `job_id` or any 409/error back to the user.

The project has no toast library (no `sonner`, no `react-hot-toast`), so
we render status inline under the button rather than pulling in a new
dependency for this single surface.

## This change

- `src/lib/dispatch-prompt.ts` exports `buildDispatchPrompt(bead)` which
  produces the exact prompt the agent runner expects. Bead id, priority
  (`P<n>`), issue type, description, and acceptance criteria are
  interpolated; `<job_id>` stays a literal placeholder because the agent
  only learns its own id at runtime (env var).
- `src/components/shared/dispatch-button.tsx` is a focused client
  component with three responsibilities:
    1. Poll `GET /api/agent-status` every 5 s while the panel is open
       (plus an initial fetch on mount), mirror `busy` into local state.
    2. On click, `POST /api/agent-dispatch` with `{taskId}`; branch on
       200 / 409 / other.
    3. Render an inline status line under the button (`text-xs`, tone
       driven by `ok | info | error`) — no toast dep required.
  The poll interval self-clears on unmount so closing the panel stops
  network traffic.
- `src/components/shared/thread-drawer.tsx` renders `<DispatchButton>`
  alongside the existing "Edit task" button in the summary section,
  wrapped in a `flex-wrap` so the two controls reflow on narrow panes.
- Registers two new tests in `package.json`'s enumerated test script.

## What is NOT in this change

- The `/api/agent-dispatch` and `/api/agent-status` routes themselves —
  those land in the next commit. The button calls them but the server
  side is intentionally a separate step so each commit can be reviewed
  in isolation.
- No real toast system is introduced; inline status is sufficient.
- No change to how task state transitions on dispatch. The agent itself
  is expected to run `bd update --claim` / `bd close` via the prompt's
  operating rules.

## Test Plan

### Automated

```
$ node --import tsx --test tests/lib/dispatch-prompt.test.ts \
    tests/components/shared/dispatch-button.test.tsx
# tests 7 pass 7 fail 0
```

Covers:
- Bead id appears in opening paragraph and in both `bd note` / `bd close`
  commands.
- Priority rendered as `P<n>`, issue type echoed.
- Description and acceptance criteria quoted verbatim when present.
- `(no description)` / `(no acceptance criteria)` fallbacks when null.
- Guard rails block present (no terraform/kubectl/helm, workspace bd
  path, `bd update … --status blocked` fallback).
- DispatchButton module loads and exports both named and default.

`npm run typecheck` shows only the pre-existing `OrchestratorChatMessage`
type gap in `left-panel.tsx` that reproduces on untouched `main`.

### Manual Verification

1. `npm install`
2. `npm run dev`
3. Open `http://localhost:3000/?task=<some-open-bead-id>`
4. Expected: "Dispatch to Agent" button next to "Edit task" in the
   right-panel summary section.
5. Button disabled on beads with `status in {closed, blocked, deferred}`
   (they don't render the button at all).
6. Button disabled on beads missing acceptance criteria, with tooltip
   "Task is missing acceptance criteria — cannot dispatch.".
7. Click: UI flips to "Dispatching…"; once the next commit is merged,
   the agent-dispatch route will surface a `job_id` (today it returns
   404 which renders as "Dispatch failed (HTTP 404)").

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:04:34 +00:00
..
activity.test.ts feat(logic): establish derived-activity engine and agent-session protocols 2026-02-14 00:19:59 -08:00
agent-liveness.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
agent-mail.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
agent-protocol.test.ts feat(protocol): wire session aggregation and API with liveness 2026-02-14 10:43:02 -08:00
agent-registry-bd.test.ts feat(agents): complete bb-1y7 - Consolidate Agent Identity to bd Beads 2026-02-15 21:18:48 -08:00
agent-registry.test.ts test(coord): expand registry/api/reservation coverage 2026-03-03 18:48:13 -08:00
agent-reservations.test.ts test(coord): expand registry/api/reservation coverage 2026-03-03 18:48:13 -08:00
agent-sessions-liveness.test.ts feat(telemetry): complete bb-buff.1.3 - Backend Liveness Refactor 2026-02-15 21:14:05 -08:00
agent-sessions-state.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
agent-sessions.test.ts test: update all test files with templateId field 2026-02-26 10:23:07 -08:00
agent-takeover.test.ts feat(protocol): wire session aggregation and API with liveness 2026-02-14 10:43:02 -08:00
aggregate-read.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
bridge.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
coalescer.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
coord-events.test.ts feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00
coord-projections-inbox.test.ts feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00
coord-projections-reservations.test.ts feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00
coord-schema.test.ts feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip 2026-03-01 18:17:58 -08:00
dispatch-prompt.test.ts [beadboard] Add Dispatch-to-Agent button and prompt template 2026-04-18 14:04:34 +00:00
epic-graph.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
graph-view.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
graph.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
identity-isolation.test.ts fix(protocol): implement Identity Isolation to prevent task pollution 2026-02-14 13:29:28 -08:00
install-manifest.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
issue-editor.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
kanban.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
mission-pathing.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
mutations.test.ts Cleanup: Runtime artifacts, hard-coded paths, PR 14 bug fixes 2026-03-05 15:57:33 -08:00
parser.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
path-overlap.test.ts feat(protocol): implement core backend engine for Operative Protocol 2026-02-14 10:38:10 -08:00
pathing.test.ts feat: add Linux/macOS support for pathing, registry, and project scope 2026-03-22 12:48:56 +01:00
project-context.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
project-scope.test.ts feat: add Linux/macOS support for pathing, registry, and project scope 2026-03-22 12:48:56 +01:00
read-interactions.test.ts Cleanup: Runtime artifacts, hard-coded paths, PR 14 bug fixes 2026-03-05 15:57:33 -08:00
read-issues.test.ts Fix: Security, reliability, and code quality improvements from PR review 2026-03-05 16:33:10 -08:00
read-text-retry.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
realtime-activity-sse.test.ts chore: checkpoint before DAG views UX overhaul 2026-02-22 20:43:59 -08:00
realtime-history.test.ts feat(observability): chronological timeline and agent productivity APIs 2026-02-14 00:21:02 -08:00
realtime.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
registry.test.ts feat: add Linux/macOS support for pathing, registry, and project scope 2026-03-22 12:48:56 +01:00
runtime-manager.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
scanner.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
snapshot-differ-stress.test.ts test: update all test files with templateId field 2026-02-26 10:23:07 -08:00
snapshot-differ.test.ts test: update all test files with templateId field 2026-02-26 10:23:07 -08:00
social-cards.test.ts test: update all test files with templateId field 2026-02-26 10:23:07 -08:00
swarm-cards.test.ts test: update all test files with templateId field 2026-02-26 10:23:07 -08:00
swarm-molecules-simple.test.ts feat(data): complete bb-ui2.15 - Swarm Cards Data Builder 2026-02-15 21:18:13 -08:00
swarm-molecules.test.ts feat(data): complete bb-ui2.15 - Swarm Cards Data Builder 2026-02-15 21:18:13 -08:00
watcher.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
writeback.test.ts checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00