checkpoint: pre-split branch cleanup

This commit is contained in:
ZenchantLive 2026-03-03 16:43:42 -08:00
parent 4c2ae2e5b7
commit b5db7a7753
276 changed files with 35912 additions and 60119 deletions

View file

@ -1,165 +1,165 @@
# Agent Session Flow & Operator Guide
This document defines the canonical workflow for human operators using `bb agent` to coordinate work in the Beadboard repo.
## Core Principle: Two Sources of Truth
1. **Work Lifecycle**: `bd` (Beads) is the ONLY source of truth for what work is happening (`in_progress`, `done`, dependencies).
2. **Coordination**: `bb agent` is the source of truth for *who* is doing it and *how* they are coordinating (reservations, handoffs).
**Rule**: Never write to `.beads/issues.jsonl` directly. Always use `bd` commands.
## Session Lifecycle
### 1. Identity Check (Start of Session)
Before claiming work, ensure your agent identity is registered and active.
```bash
# Check if you are registered
bb agent show --agent agent-ui-1
# If not, register (idempotent, use --force-update to change role/display)
bb agent register --name agent-ui-1 --role ui --display "UI Agent 1"
```
### 2. Picking and Claiming Work
Use `bd` to find and claim work. This is the "clock in" event.
```bash
# 1. Find ready work (unblocked)
bd ready
# 2. Inspect the bead
bd show bb-dcv.5
# 3. CLAIM the bead (Atomic Claim)
# This sets status=in_progress AND assigns it to you in one atomic op.
bd update bb-dcv.5 --status in_progress --notes "Starting docs work" --claim
```
### 3. Coordination (During Work)
While working, use `bb agent` to coordinate with other agents or reserve contested resources.
#### Reservations (Traffic Control)
Prevent collisions on shared files or subsystems.
```bash
# Reserve a scope (default TTL 120m)
bb agent reserve --agent agent-ui-1 --bead bb-dcv.5 --scope "src/components/graph/*"
# Check status of your reservation
bb agent status --bead bb-dcv.5
```
#### Communication (Handoffs & Blockers)
Send structured signals to other agents.
```bash
# BLOCKER: Request help
bb agent send \
--from agent-ui-1 \
--to agent-backend-1 \
--bead bb-dcv.5 \
--category BLOCKED \
--subject "API 404 on /b/users" \
--body "Endpoint missing. Blocking UI integration."
# HANDOFF: Pass context
bb agent send \
--from agent-ui-1 \
--to agent-qa-1 \
--bead bb-dcv.5 \
--category HANDOFF \
--subject "Ready for verification" \
--body "UI complete. Verify at /graph and /kanban."
```
#### Checking Mail
```bash
# Check inbox
bb agent inbox --agent agent-ui-1 --state unread
# Read a message (marks as read)
bb agent read --agent agent-ui-1 --message msg_id_123
# Acknowledge a message (required for HANDOFF/BLOCKED)
bb agent ack --agent agent-ui-1 --message msg_id_123
```
### 4. Completion (End of Session)
Wrap up the session cleanly.
1. **Release Reservations**:
```bash
# Release specific scope
bb agent release --agent agent-ui-1 --scope "src/components/graph/*"
```
2. **Update Bead Status**:
```bash
# Post evidence/results
bd update bb-dcv.5 --notes "Docs created. Validation passed."
# Close the bead
bd close bb-dcv.5 --reason "Completed all acceptance criteria"
```
## UX & Output Formats
All `bb agent` commands support human-friendly output (default) and machine-readable JSON.
### Human Format (Default)
Optimized for operator readability.
```text
$ bb agent register --name agent-ui-1 --role ui
✓ Agent registered: agent-ui-1 (role: ui)
```
### JSON Format (`--json`)
Optimized for tool parsing. Always returns a standard envelope.
```bash
$ bb agent register --name agent-ui-1 --role ui --json
```
```json
{
"ok": true,
"command": "agent register",
"data": {
"agent_id": "agent-ui-1",
"role": "ui",
"status": "idle",
...
},
"error": null
}
```
### Error Handling
Errors always return `ok: false` with a stable error code.
```json
{
"ok": false,
"command": "agent send",
"data": null,
"error": {
"code": "UNKNOWN_RECIPIENT",
"message": "Agent 'ghost-1' not found"
}
}
```
## Anti-Patterns (Don't Do This)
1. **Ghosting**: Claiming a bead but not registering an agent identity.
2. **Squatting**: Holding a reservation (`--ttl 1440`) while not actively working.
3. **Bypassing**: Writing to `issues.jsonl` directly instead of using `bd`.
4. **Zombie Claims**: Forgetting to `bd close` or `bd update --status todo` when stopping work.
# Agent Session Flow & Operator Guide
This document defines the canonical workflow for human operators using `bb agent` to coordinate work in the Beadboard repo.
## Core Principle: Two Sources of Truth
1. **Work Lifecycle**: `bd` (Beads) is the ONLY source of truth for what work is happening (`in_progress`, `done`, dependencies).
2. **Coordination**: `bb agent` is the source of truth for *who* is doing it and *how* they are coordinating (reservations, handoffs).
**Rule**: Never write to `.beads/issues.jsonl` directly. Always use `bd` commands.
## Session Lifecycle
### 1. Identity Check (Start of Session)
Before claiming work, ensure your agent identity is registered and active.
```bash
# Check if you are registered
bb agent show --agent agent-ui-1
# If not, register (idempotent, use --force-update to change role/display)
bb agent register --name agent-ui-1 --role ui --display "UI Agent 1"
```
### 2. Picking and Claiming Work
Use `bd` to find and claim work. This is the "clock in" event.
```bash
# 1. Find ready work (unblocked)
bd ready
# 2. Inspect the bead
bd show bb-dcv.5
# 3. CLAIM the bead (Atomic Claim)
# This sets status=in_progress AND assigns it to you in one atomic op.
bd update bb-dcv.5 --status in_progress --notes "Starting docs work" --claim
```
### 3. Coordination (During Work)
While working, use `bb agent` to coordinate with other agents or reserve contested resources.
#### Reservations (Traffic Control)
Prevent collisions on shared files or subsystems.
```bash
# Reserve a scope (default TTL 120m)
bb agent reserve --agent agent-ui-1 --bead bb-dcv.5 --scope "src/components/graph/*"
# Check status of your reservation
bb agent status --bead bb-dcv.5
```
#### Communication (Handoffs & Blockers)
Send structured signals to other agents.
```bash
# BLOCKER: Request help
bb agent send \
--from agent-ui-1 \
--to agent-backend-1 \
--bead bb-dcv.5 \
--category BLOCKED \
--subject "API 404 on /b/users" \
--body "Endpoint missing. Blocking UI integration."
# HANDOFF: Pass context
bb agent send \
--from agent-ui-1 \
--to agent-qa-1 \
--bead bb-dcv.5 \
--category HANDOFF \
--subject "Ready for verification" \
--body "UI complete. Verify at /graph and /kanban."
```
#### Checking Mail
```bash
# Check inbox
bb agent inbox --agent agent-ui-1 --state unread
# Read a message (marks as read)
bb agent read --agent agent-ui-1 --message msg_id_123
# Acknowledge a message (required for HANDOFF/BLOCKED)
bb agent ack --agent agent-ui-1 --message msg_id_123
```
### 4. Completion (End of Session)
Wrap up the session cleanly.
1. **Release Reservations**:
```bash
# Release specific scope
bb agent release --agent agent-ui-1 --scope "src/components/graph/*"
```
2. **Update Bead Status**:
```bash
# Post evidence/results
bd update bb-dcv.5 --notes "Docs created. Validation passed."
# Close the bead
bd close bb-dcv.5 --reason "Completed all acceptance criteria"
```
## UX & Output Formats
All `bb agent` commands support human-friendly output (default) and machine-readable JSON.
### Human Format (Default)
Optimized for operator readability.
```text
$ bb agent register --name agent-ui-1 --role ui
✓ Agent registered: agent-ui-1 (role: ui)
```
### JSON Format (`--json`)
Optimized for tool parsing. Always returns a standard envelope.
```bash
$ bb agent register --name agent-ui-1 --role ui --json
```
```json
{
"ok": true,
"command": "agent register",
"data": {
"agent_id": "agent-ui-1",
"role": "ui",
"status": "idle",
...
},
"error": null
}
```
### Error Handling
Errors always return `ok: false` with a stable error code.
```json
{
"ok": false,
"command": "agent send",
"data": null,
"error": {
"code": "UNKNOWN_RECIPIENT",
"message": "Agent 'ghost-1' not found"
}
}
```
## Anti-Patterns (Don't Do This)
1. **Ghosting**: Claiming a bead but not registering an agent identity.
2. **Squatting**: Holding a reservation (`--ttl 1440`) while not actively working.
3. **Bypassing**: Writing to `issues.jsonl` directly instead of using `bd`.
4. **Zombie Claims**: Forgetting to `bd close` or `bd update --status todo` when stopping work.

View file

@ -1,283 +1,283 @@
# BeadBoard API Reference
## Overview
BeadBoard exposes REST endpoints for reading bead data, managing agent coordination, and streaming real-time activity. All endpoints return JSON (unless noted otherwise).
## Bead Management
### `GET /api/beads/read`
Read beads from the current or specified project.
**Query Parameters:**
- `project` (optional): Project key for scope resolution
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"issues": [...],
"projectRoot": "/path/to/project"
}
```
### `POST /api/beads/create`
Create a new bead.
**Body:**
```json
{
"title": "Task title",
"description": "Optional description",
"status": "open",
"priority": "p2",
"issue_type": "task"
}
```
### `POST /api/beads/update`
Update an existing bead.
**Body:**
```json
{
"id": "bb-abc",
"updates": {
"status": "in_progress",
"assignee": "agent-1"
}
}
```
### `POST /api/beads/close`
Close a bead.
**Body:**
```json
{
"id": "bb-abc",
"reason": "Completion reason"
}
```
### `POST /api/beads/reopen`
Reopen a closed bead.
**Body:**
```json
{
"id": "bb-abc"
}
```
### `POST /api/beads/comment`
Add a comment to a bead.
**Body:**
```json
{
"id": "bb-abc",
"comment": "Comment text",
"author": "agent-1"
}
```
## Agent Coordination
### `GET /api/agents/[agentId]/stats`
Fetch productivity metrics for a specific agent.
**Path Parameters:**
- `agentId`: Agent identifier
**Response:**
```json
{
"activeTasks": 3,
"completedTasks": 12,
"handoffsSent": 8,
"recentWins": [
{ "id": "bb-xyz", "title": "Task title" }
]
}
```
### `GET /api/sessions`
Fetch the agent sessions task feed.
**Query Parameters:**
- `project` (optional): Project scope
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"buckets": [
{
"epic": {
"id": "bb-epic",
"title": "Epic Title",
"status": "open"
},
"tasks": [
{
"id": "bb-task",
"title": "Task Title",
"epicId": "bb-epic",
"status": "in_progress",
"sessionState": "active",
"owner": "agent-1",
"lastActor": "agent-1",
"lastActivityAt": "2026-02-16T05:00:00Z",
"communication": {
"unreadCount": 2,
"pendingRequired": true,
"latestSnippet": "Blocked on API"
}
}
]
}
]
}
```
### `GET /api/sessions/[beadId]/conversation`
Get the full conversation thread for a bead, including comments and agent messages.
**Path Parameters:**
- `beadId`: Bead identifier
**Response:**
```json
{
"comments": [...],
"messages": [...]
}
```
### `POST /api/sessions/[beadId]/comment`
Add a comment to a bead session.
**Path Parameters:**
- `beadId`: Bead identifier
**Body:**
```json
{
"comment": "Comment text",
"author": "agent-1"
}
```
### `POST /api/sessions/[beadId]/messages/[messageId]/read`
Mark an agent message as read.
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
### `POST /api/sessions/[beadId]/messages/[messageId]/ack`
Acknowledge an agent message (required for HANDOFF/BLOCKED categories).
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
## Activity & Events
### `GET /api/activity`
Fetch recent activity events (history buffer).
**Response:**
```json
{
"events": [
{
"id": "evt-123",
"beadId": "bb-abc",
"kind": "status_changed",
"actor": "agent-1",
"timestamp": "2026-02-16T05:00:00Z",
"changes": {
"from": "todo",
"to": "in_progress"
}
}
]
}
```
### `GET /api/events`
Server-Sent Events stream for real-time activity.
**Response:** SSE stream with `event` and `data` fields.
**Event Types:**
- `activity`: New activity event
- `bead_updated`: Bead state changed
- `agent_registered`: New agent registered
## Project Management
### `GET /api/projects`
List all registered projects.
**Response:**
```json
{
"projects": [
{
"key": "proj-1",
"root": "/path/to/project",
"name": "Project Name"
}
]
}
```
### `POST /api/scan`
Scan filesystem for bead-enabled projects.
**Body:**
```json
{
"paths": ["/path/to/scan"]
}
```
**Response:**
```json
{
"discovered": [
{
"root": "/path/to/project",
"beadCount": 42
}
]
}
```
## Error Handling
All endpoints follow a consistent error format:
```json
{
"error": "Error message",
"code": "ERROR_CODE",
"details": {}
}
```
**Common Error Codes:**
- `INVALID_REQUEST`: Malformed request body or parameters
- `NOT_FOUND`: Resource does not exist
- `PERMISSION_DENIED`: Operation not allowed
- `INTERNAL_ERROR`: Server-side error
## Rate Limiting
No rate limiting is currently enforced for local BeadBoard instances. If deploying publicly, implement rate limiting externally.
## Authentication
BeadBoard runs as a local dashboard with no authentication. If exposing over a network, secure access using reverse proxy authentication or network isolation.
# BeadBoard API Reference
## Overview
BeadBoard exposes REST endpoints for reading bead data, managing agent coordination, and streaming real-time activity. All endpoints return JSON (unless noted otherwise).
## Bead Management
### `GET /api/beads/read`
Read beads from the current or specified project.
**Query Parameters:**
- `project` (optional): Project key for scope resolution
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"issues": [...],
"projectRoot": "/path/to/project"
}
```
### `POST /api/beads/create`
Create a new bead.
**Body:**
```json
{
"title": "Task title",
"description": "Optional description",
"status": "open",
"priority": "p2",
"issue_type": "task"
}
```
### `POST /api/beads/update`
Update an existing bead.
**Body:**
```json
{
"id": "bb-abc",
"updates": {
"status": "in_progress",
"assignee": "agent-1"
}
}
```
### `POST /api/beads/close`
Close a bead.
**Body:**
```json
{
"id": "bb-abc",
"reason": "Completion reason"
}
```
### `POST /api/beads/reopen`
Reopen a closed bead.
**Body:**
```json
{
"id": "bb-abc"
}
```
### `POST /api/beads/comment`
Add a comment to a bead.
**Body:**
```json
{
"id": "bb-abc",
"comment": "Comment text",
"author": "agent-1"
}
```
## Agent Coordination
### `GET /api/agents/[agentId]/stats`
Fetch productivity metrics for a specific agent.
**Path Parameters:**
- `agentId`: Agent identifier
**Response:**
```json
{
"activeTasks": 3,
"completedTasks": 12,
"handoffsSent": 8,
"recentWins": [
{ "id": "bb-xyz", "title": "Task title" }
]
}
```
### `GET /api/sessions`
Fetch the agent sessions task feed.
**Query Parameters:**
- `project` (optional): Project scope
- `mode` (optional): `single` or `aggregate`
**Response:**
```json
{
"buckets": [
{
"epic": {
"id": "bb-epic",
"title": "Epic Title",
"status": "open"
},
"tasks": [
{
"id": "bb-task",
"title": "Task Title",
"epicId": "bb-epic",
"status": "in_progress",
"sessionState": "active",
"owner": "agent-1",
"lastActor": "agent-1",
"lastActivityAt": "2026-02-16T05:00:00Z",
"communication": {
"unreadCount": 2,
"pendingRequired": true,
"latestSnippet": "Blocked on API"
}
}
]
}
]
}
```
### `GET /api/sessions/[beadId]/conversation`
Get the full conversation thread for a bead, including comments and agent messages.
**Path Parameters:**
- `beadId`: Bead identifier
**Response:**
```json
{
"comments": [...],
"messages": [...]
}
```
### `POST /api/sessions/[beadId]/comment`
Add a comment to a bead session.
**Path Parameters:**
- `beadId`: Bead identifier
**Body:**
```json
{
"comment": "Comment text",
"author": "agent-1"
}
```
### `POST /api/sessions/[beadId]/messages/[messageId]/read`
Mark an agent message as read.
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
### `POST /api/sessions/[beadId]/messages/[messageId]/ack`
Acknowledge an agent message (required for HANDOFF/BLOCKED categories).
**Path Parameters:**
- `beadId`: Bead identifier
- `messageId`: Message identifier
## Activity & Events
### `GET /api/activity`
Fetch recent activity events (history buffer).
**Response:**
```json
{
"events": [
{
"id": "evt-123",
"beadId": "bb-abc",
"kind": "status_changed",
"actor": "agent-1",
"timestamp": "2026-02-16T05:00:00Z",
"changes": {
"from": "todo",
"to": "in_progress"
}
}
]
}
```
### `GET /api/events`
Server-Sent Events stream for real-time activity.
**Response:** SSE stream with `event` and `data` fields.
**Event Types:**
- `activity`: New activity event
- `bead_updated`: Bead state changed
- `agent_registered`: New agent registered
## Project Management
### `GET /api/projects`
List all registered projects.
**Response:**
```json
{
"projects": [
{
"key": "proj-1",
"root": "/path/to/project",
"name": "Project Name"
}
]
}
```
### `POST /api/scan`
Scan filesystem for bead-enabled projects.
**Body:**
```json
{
"paths": ["/path/to/scan"]
}
```
**Response:**
```json
{
"discovered": [
{
"root": "/path/to/project",
"beadCount": 42
}
]
}
```
## Error Handling
All endpoints follow a consistent error format:
```json
{
"error": "Error message",
"code": "ERROR_CODE",
"details": {}
}
```
**Common Error Codes:**
- `INVALID_REQUEST`: Malformed request body or parameters
- `NOT_FOUND`: Resource does not exist
- `PERMISSION_DENIED`: Operation not allowed
- `INTERNAL_ERROR`: Server-side error
## Rate Limiting
No rate limiting is currently enforced for local BeadBoard instances. If deploying publicly, implement rate limiting externally.
## Authentication
BeadBoard runs as a local dashboard with no authentication. If exposing over a network, secure access using reverse proxy authentication or network isolation.

View file

@ -1,5 +1,5 @@
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};
export default {
plugins: {
'@tailwindcss/postcss': {},
},
};

View file

@ -1,166 +1,166 @@
diff --git a/.gitignore b/.gitignore
index eb35607..596f42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ node_modules/
*.tsbuildinfo
.worktrees/
worktrees/
+
+# bv (beads viewer) local config and caches
+.bv/
diff --git a/src/app/globals.css b/src/app/globals.css
index d17e938..a474080 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,15 +3,15 @@
@tailwind utilities;
:root {
- --color-bg: #090c14;
- --color-surface: #101827;
- --color-surface-muted: #192336;
- --color-surface-raised: #22314a;
- --color-text-strong: #f6f8ff;
- --color-text-body: #d8e0f1;
- --color-text-muted: #9caccc;
- --color-border-soft: rgba(145, 166, 204, 0.3);
- --color-border-strong: rgba(187, 209, 246, 0.62);
+ --color-bg: #090909;
+ --color-surface: #161616;
+ --color-surface-muted: #212121;
+ --color-surface-raised: #2a2a2a;
+ --color-text-strong: #f5f5f5;
+ --color-text-body: #d0d0d0;
+ --color-text-muted: #9a9a9a;
+ --color-border-soft: rgba(255, 255, 255, 0.15);
+ --color-border-strong: rgba(255, 255, 255, 0.3);
--status-open: #60a5fa;
--status-progress: #fbbf24;
@@ -38,10 +38,9 @@ body {
body {
background:
- radial-gradient(circle at 10% 12%, rgba(12, 138, 215, 0.34), transparent 36%),
- radial-gradient(circle at 84% 20%, rgba(250, 122, 91, 0.18), transparent 30%),
- radial-gradient(circle at 68% 88%, rgba(57, 189, 154, 0.14), transparent 36%),
- linear-gradient(155deg, #05070d 0%, #0b1322 42%, #121e34 100%);
+ radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.05), transparent 36%),
+ radial-gradient(circle at 84% 18%, rgba(255, 180, 80, 0.06), transparent 32%),
+ linear-gradient(160deg, #070707 0%, #101010 48%, #161616 100%);
color: var(--color-text-body);
- font-family: 'Segoe UI', 'Aptos', Inter, system-ui, sans-serif;
+ font-family: 'DM Sans', 'Segoe UI', Inter, system-ui, sans-serif;
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ff1ad90..1417e77 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,18 @@
import type { Metadata } from 'next';
+import { DM_Sans, JetBrains_Mono } from 'next/font/google';
import type { ReactNode } from 'react';
import './globals.css';
+const dmSans = DM_Sans({
+ subsets: ['latin'],
+ variable: '--font-ui',
+});
+
+const jetbrainsMono = JetBrains_Mono({
+ subsets: ['latin'],
+ variable: '--font-mono',
+});
+
export const metadata: Metadata = {
title: 'BeadBoard',
description: 'Windows-native Beads dashboard',
@@ -10,7 +21,7 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
- <body>{children}</body>
+ <body className={`${dmSans.variable} ${jetbrainsMono.variable}`}>{children}</body>
</html>
);
}
diff --git a/src/components/kanban/kanban-controls.tsx b/src/components/kanban/kanban-controls.tsx
index 78b09f4..e1e04f9 100644
--- a/src/components/kanban/kanban-controls.tsx
+++ b/src/components/kanban/kanban-controls.tsx
@@ -14,7 +14,7 @@ interface KanbanControlsProps {
export function KanbanControls({ filters, stats, onFiltersChange }: KanbanControlsProps) {
const inputClass =
- 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-cyan-300/70 focus:ring-2 focus:ring-cyan-300/20';
+ 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-border-strong focus:ring-2 focus:ring-white/10';
return (
<section className="grid gap-3">
@@ -57,7 +57,7 @@ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanContro
type="checkbox"
checked={filters.showClosed ?? false}
onChange={(event) => onFiltersChange({ ...filters, showClosed: event.target.checked })}
- className="h-4 w-4 accent-cyan-400"
+ className="h-4 w-4 accent-amber-400"
/>
Show closed
</label>
diff --git a/src/components/shared/chip.tsx b/src/components/shared/chip.tsx
index c1637e6..e29d49d 100644
--- a/src/components/shared/chip.tsx
+++ b/src/components/shared/chip.tsx
@@ -7,7 +7,7 @@ interface ChipProps {
const CHIP_TONE_CLASS: Record<NonNullable<ChipProps['tone']>, string> = {
default: 'border-border-soft bg-surface-muted/75 text-text-body',
- status: 'border-cyan-300/30 bg-cyan-500/20 text-cyan-50',
+ status: 'border-zinc-300/30 bg-zinc-500/20 text-zinc-100',
priority: 'border-amber-300/30 bg-amber-500/20 text-amber-50',
};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 5ad9067..953965c 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -5,8 +5,8 @@ const config: Config = {
theme: {
extend: {
fontFamily: {
- ui: ['Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
- mono: ['JetBrains Mono', 'Consolas', 'monospace'],
+ ui: ['var(--font-ui)', 'Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
+ mono: ['var(--font-mono)', 'Consolas', 'monospace'],
},
colors: {
bg: 'var(--color-bg)',
diff --git a/tests/guards/kanban-responsive-contract.test.mjs b/tests/guards/kanban-responsive-contract.test.mjs
index 4e02f28..3efabf4 100644
--- a/tests/guards/kanban-responsive-contract.test.mjs
+++ b/tests/guards/kanban-responsive-contract.test.mjs
@@ -9,11 +9,12 @@ async function read(relativePath) {
return fs.readFile(path.join(ROOT, relativePath), 'utf8');
}
-test('kanban board uses intentional horizontal scroll affordances', async () => {
+test('kanban board uses expandable vertical swimlanes', async () => {
const board = await read('src/components/kanban/kanban-board.tsx');
- assert.match(board, /snap-x/);
- assert.match(board, /overflow-x-auto/);
+ assert.match(board, /aria-expanded/);
+ assert.match(board, /onActivateStatus/);
+ assert.match(board, /max-h-\[50vh\]/);
});
test('kanban page defines mobile detail drawer behavior', async () => {
@@ -21,6 +22,8 @@ test('kanban page defines mobile detail drawer behavior', async () => {
assert.match(page, /fixed inset-0/);
assert.match(page, /lg:hidden/);
+ assert.match(page, /lg:grid-cols-\[minmax\(0,1fr\)_minmax\(22rem,26rem\)\]/);
+ assert.match(page, /lg:border-l/);
});
test('kanban controls use fluid full-width sizing on small viewports', async () => {
diff --git a/.gitignore b/.gitignore
index eb35607..596f42a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@ node_modules/
*.tsbuildinfo
.worktrees/
worktrees/
+
+# bv (beads viewer) local config and caches
+.bv/
diff --git a/src/app/globals.css b/src/app/globals.css
index d17e938..a474080 100644
--- a/src/app/globals.css
+++ b/src/app/globals.css
@@ -3,15 +3,15 @@
@tailwind utilities;
:root {
- --color-bg: #090c14;
- --color-surface: #101827;
- --color-surface-muted: #192336;
- --color-surface-raised: #22314a;
- --color-text-strong: #f6f8ff;
- --color-text-body: #d8e0f1;
- --color-text-muted: #9caccc;
- --color-border-soft: rgba(145, 166, 204, 0.3);
- --color-border-strong: rgba(187, 209, 246, 0.62);
+ --color-bg: #090909;
+ --color-surface: #161616;
+ --color-surface-muted: #212121;
+ --color-surface-raised: #2a2a2a;
+ --color-text-strong: #f5f5f5;
+ --color-text-body: #d0d0d0;
+ --color-text-muted: #9a9a9a;
+ --color-border-soft: rgba(255, 255, 255, 0.15);
+ --color-border-strong: rgba(255, 255, 255, 0.3);
--status-open: #60a5fa;
--status-progress: #fbbf24;
@@ -38,10 +38,9 @@ body {
body {
background:
- radial-gradient(circle at 10% 12%, rgba(12, 138, 215, 0.34), transparent 36%),
- radial-gradient(circle at 84% 20%, rgba(250, 122, 91, 0.18), transparent 30%),
- radial-gradient(circle at 68% 88%, rgba(57, 189, 154, 0.14), transparent 36%),
- linear-gradient(155deg, #05070d 0%, #0b1322 42%, #121e34 100%);
+ radial-gradient(circle at 14% 12%, rgba(255, 255, 255, 0.05), transparent 36%),
+ radial-gradient(circle at 84% 18%, rgba(255, 180, 80, 0.06), transparent 32%),
+ linear-gradient(160deg, #070707 0%, #101010 48%, #161616 100%);
color: var(--color-text-body);
- font-family: 'Segoe UI', 'Aptos', Inter, system-ui, sans-serif;
+ font-family: 'DM Sans', 'Segoe UI', Inter, system-ui, sans-serif;
}
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index ff1ad90..1417e77 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,18 @@
import type { Metadata } from 'next';
+import { DM_Sans, JetBrains_Mono } from 'next/font/google';
import type { ReactNode } from 'react';
import './globals.css';
+const dmSans = DM_Sans({
+ subsets: ['latin'],
+ variable: '--font-ui',
+});
+
+const jetbrainsMono = JetBrains_Mono({
+ subsets: ['latin'],
+ variable: '--font-mono',
+});
+
export const metadata: Metadata = {
title: 'BeadBoard',
description: 'Windows-native Beads dashboard',
@@ -10,7 +21,7 @@ export const metadata: Metadata = {
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
- <body>{children}</body>
+ <body className={`${dmSans.variable} ${jetbrainsMono.variable}`}>{children}</body>
</html>
);
}
diff --git a/src/components/kanban/kanban-controls.tsx b/src/components/kanban/kanban-controls.tsx
index 78b09f4..e1e04f9 100644
--- a/src/components/kanban/kanban-controls.tsx
+++ b/src/components/kanban/kanban-controls.tsx
@@ -14,7 +14,7 @@ interface KanbanControlsProps {
export function KanbanControls({ filters, stats, onFiltersChange }: KanbanControlsProps) {
const inputClass =
- 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-cyan-300/70 focus:ring-2 focus:ring-cyan-300/20';
+ 'rounded-xl border border-border-soft bg-surface-muted/78 px-3 py-2.5 text-sm text-text-strong outline-none transition placeholder:text-text-muted focus:border-border-strong focus:ring-2 focus:ring-white/10';
return (
<section className="grid gap-3">
@@ -57,7 +57,7 @@ export function KanbanControls({ filters, stats, onFiltersChange }: KanbanContro
type="checkbox"
checked={filters.showClosed ?? false}
onChange={(event) => onFiltersChange({ ...filters, showClosed: event.target.checked })}
- className="h-4 w-4 accent-cyan-400"
+ className="h-4 w-4 accent-amber-400"
/>
Show closed
</label>
diff --git a/src/components/shared/chip.tsx b/src/components/shared/chip.tsx
index c1637e6..e29d49d 100644
--- a/src/components/shared/chip.tsx
+++ b/src/components/shared/chip.tsx
@@ -7,7 +7,7 @@ interface ChipProps {
const CHIP_TONE_CLASS: Record<NonNullable<ChipProps['tone']>, string> = {
default: 'border-border-soft bg-surface-muted/75 text-text-body',
- status: 'border-cyan-300/30 bg-cyan-500/20 text-cyan-50',
+ status: 'border-zinc-300/30 bg-zinc-500/20 text-zinc-100',
priority: 'border-amber-300/30 bg-amber-500/20 text-amber-50',
};
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 5ad9067..953965c 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -5,8 +5,8 @@ const config: Config = {
theme: {
extend: {
fontFamily: {
- ui: ['Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
- mono: ['JetBrains Mono', 'Consolas', 'monospace'],
+ ui: ['var(--font-ui)', 'Segoe UI', 'Inter', 'system-ui', 'sans-serif'],
+ mono: ['var(--font-mono)', 'Consolas', 'monospace'],
},
colors: {
bg: 'var(--color-bg)',
diff --git a/tests/guards/kanban-responsive-contract.test.mjs b/tests/guards/kanban-responsive-contract.test.mjs
index 4e02f28..3efabf4 100644
--- a/tests/guards/kanban-responsive-contract.test.mjs
+++ b/tests/guards/kanban-responsive-contract.test.mjs
@@ -9,11 +9,12 @@ async function read(relativePath) {
return fs.readFile(path.join(ROOT, relativePath), 'utf8');
}
-test('kanban board uses intentional horizontal scroll affordances', async () => {
+test('kanban board uses expandable vertical swimlanes', async () => {
const board = await read('src/components/kanban/kanban-board.tsx');
- assert.match(board, /snap-x/);
- assert.match(board, /overflow-x-auto/);
+ assert.match(board, /aria-expanded/);
+ assert.match(board, /onActivateStatus/);
+ assert.match(board, /max-h-\[50vh\]/);
});
test('kanban page defines mobile detail drawer behavior', async () => {
@@ -21,6 +22,8 @@ test('kanban page defines mobile detail drawer behavior', async () => {
assert.match(page, /fixed inset-0/);
assert.match(page, /lg:hidden/);
+ assert.match(page, /lg:grid-cols-\[minmax\(0,1fr\)_minmax\(22rem,26rem\)\]/);
+ assert.match(page, /lg:border-l/);
});
test('kanban controls use fluid full-width sizing on small viewports', async () => {

File diff suppressed because it is too large Load diff

View file

@ -1,130 +1,130 @@
# Agent Sessions Hub
## Overview
The Agent Sessions Hub (`/sessions`) provides a unified command workspace for tracking multi-agent coordination across your BeadBoard projects. It combines task status, agent communication, and derived activity into a social-dense interface optimized for understanding "who's doing what" at a glance.
## Features
### 1. Epic-Grouped Task Feed
Tasks are automatically organized by their parent Epic, providing logical context for understanding work scope.
- **Session State Indicators**: Each task displays its real-time state (active, reviewing, needs_input, completed, stale)
- **Owner & Actor Tracking**: See who owns the task and who last acted on it
- **Communication Badges**: Unread message counts and pending acknowledgment flags
### 2. Agent Communication Integration
Built-in cross-agent messaging system for coordination without leaving the dashboard.
**Message Types:**
- `HANDOFF` - Pass context to another agent
- `BLOCKED` - Request help or flag blockers
- `INFO` - Share updates or documentation
**Communication Features:**
- Inbox view with unread/read/acked states
- Required acknowledgments for critical handoffs
- Per-bead conversation threads
### 3. Agent Statistics & Productivity Metrics
Real-time performance tracking for each registered agent.
**Metrics Tracked:**
- Active tasks (currently in progress)
- Completed tasks (closed beads)
- Handoffs sent (coordination events)
- Recent wins (last 3 completed tasks)
### 4. Derived Activity Engine
Instead of storing history separately, BeadBoard computes activity on-demand by diffing snapshots of `issues.jsonl`.
**Event Types Generated:**
- Bead lifecycle: created, closed, reopened
- Status changes: todo → in_progress → done
- Assignee changes
- Priority, title, description updates
- Label and dependency changes
**Persistence:**
- File-backed ring buffer survives server restarts
- O(N) snapshot diffing algorithm
- No separate event database required
## Architecture
### Backend Components
- **Agent Registry** (`src/lib/agent-registry.ts`): Maintains agent identity and roles
- **Agent Mail** (`src/lib/agent-mail.ts`): Cross-agent messaging with inbox/ack protocol
- **Agent Reservations** (`src/lib/agent-reservations.ts`): File/scope locking to prevent collisions
- **Agent Sessions** (`src/lib/agent-sessions.ts`): Session state derivation and task feed builder
- **Snapshot Differ** (`src/lib/snapshot-differ.ts`): O(N) diffing engine for activity events
- **Activity Persistence** (`src/lib/activity-persistence.ts`): File-backed event buffer
### API Endpoints
- `GET /api/sessions` - Fetch session task feed
- `GET /api/sessions/[beadId]/conversation` - Get full conversation thread for a bead
- `POST /api/sessions/[beadId]/comment` - Add a comment to a bead session
- `POST /api/sessions/[beadId]/messages/[messageId]/read` - Mark message as read
- `POST /api/sessions/[beadId]/messages/[messageId]/ack` - Acknowledge message
- `GET /api/agents/[agentId]/stats` - Fetch agent productivity metrics
### Frontend Components
- **SessionsPage** (`src/components/sessions/sessions-page.tsx`): Main layout and orchestration
- **TaskCard** components: Visual representation of session state
- **AgentStatsPanel**: Metrics dashboard per agent
## Session States
Tasks automatically transition between states based on activity and communication:
| State | Description | Visual Indicator |
|-------|-------------|------------------|
| `active` | Status is `in_progress`, recent activity | Green pulse |
| `reviewing` | Under review or verification | Blue |
| `deciding` | Status is `todo` or `ready`, waiting for claim | Gray |
| `needs_input` | Status is `blocked` or has pending required acknowledgments | Yellow/Orange |
| `completed` | Status is `closed` | Green checkmark |
| `stale` | No activity in 24+ hours | Faded/Red |
## Integration with `bb agent` CLI
The Sessions Hub visualizes data managed by the `bb agent` command-line interface. See `docs/agent-session-flow.md` for the operator workflow.
**Key Commands:**
- `bb agent register --name <name> --role <role>` - Register agent identity
- `bb agent send --from <sender> --to <recipient> --bead <id> --category <type>` - Send message
- `bb agent inbox --agent <name>` - Check messages
- `bb agent reserve --agent <name> --scope <glob> --bead <id>` - Reserve files
- `bb agent status --bead <id>` - Check reservation status
## Data Flow
1. **Source of Truth**: `.beads/issues.jsonl` via `bd` CLI
2. **Activity Generation**: Watcher detects changes → snapshot differ → event bus
3. **Agent Coordination**: `bb` CLI writes to `.beads/agents/` directory
4. **UI Refresh**: SSE stream (`/api/events`) pushes updates to frontend in real-time
## Configuration
No configuration required. The Sessions Hub automatically:
- Discovers registered agents from `.beads/agents/`
- Builds communication graph from mailboxes
- Derives session states from current bead status + activity
## Performance
- **O(N) Diffing**: Snapshot differ scales linearly with number of beads
- **Ring Buffer**: Activity persistence uses fixed-size memory buffer (configurable)
- **Real-time Updates**: SSE keeps UI synchronized without polling
## Limitations
- Comment interactions are not yet streamed to the timeline
- Cross-project agent coordination requires agents to be registered in each project
- Stale threshold is fixed at 24 hours (not user-configurable)
## Related Documentation
- `docs/agent-session-flow.md` - CLI workflow guide for operators
- `docs/features/timeline.md` - Chronological activity feed
- `docs/RFC-001-Agent-Coordination.md` - Agent coordination design
- `docs/adr/2026-02-14-beadboard-driver-skill-and-bb-resolution.md` - beadboard-driver skill
# Agent Sessions Hub
## Overview
The Agent Sessions Hub (`/sessions`) provides a unified command workspace for tracking multi-agent coordination across your BeadBoard projects. It combines task status, agent communication, and derived activity into a social-dense interface optimized for understanding "who's doing what" at a glance.
## Features
### 1. Epic-Grouped Task Feed
Tasks are automatically organized by their parent Epic, providing logical context for understanding work scope.
- **Session State Indicators**: Each task displays its real-time state (active, reviewing, needs_input, completed, stale)
- **Owner & Actor Tracking**: See who owns the task and who last acted on it
- **Communication Badges**: Unread message counts and pending acknowledgment flags
### 2. Agent Communication Integration
Built-in cross-agent messaging system for coordination without leaving the dashboard.
**Message Types:**
- `HANDOFF` - Pass context to another agent
- `BLOCKED` - Request help or flag blockers
- `INFO` - Share updates or documentation
**Communication Features:**
- Inbox view with unread/read/acked states
- Required acknowledgments for critical handoffs
- Per-bead conversation threads
### 3. Agent Statistics & Productivity Metrics
Real-time performance tracking for each registered agent.
**Metrics Tracked:**
- Active tasks (currently in progress)
- Completed tasks (closed beads)
- Handoffs sent (coordination events)
- Recent wins (last 3 completed tasks)
### 4. Derived Activity Engine
Instead of storing history separately, BeadBoard computes activity on-demand by diffing snapshots of `issues.jsonl`.
**Event Types Generated:**
- Bead lifecycle: created, closed, reopened
- Status changes: todo → in_progress → done
- Assignee changes
- Priority, title, description updates
- Label and dependency changes
**Persistence:**
- File-backed ring buffer survives server restarts
- O(N) snapshot diffing algorithm
- No separate event database required
## Architecture
### Backend Components
- **Agent Registry** (`src/lib/agent-registry.ts`): Maintains agent identity and roles
- **Agent Mail** (`src/lib/agent-mail.ts`): Cross-agent messaging with inbox/ack protocol
- **Agent Reservations** (`src/lib/agent-reservations.ts`): File/scope locking to prevent collisions
- **Agent Sessions** (`src/lib/agent-sessions.ts`): Session state derivation and task feed builder
- **Snapshot Differ** (`src/lib/snapshot-differ.ts`): O(N) diffing engine for activity events
- **Activity Persistence** (`src/lib/activity-persistence.ts`): File-backed event buffer
### API Endpoints
- `GET /api/sessions` - Fetch session task feed
- `GET /api/sessions/[beadId]/conversation` - Get full conversation thread for a bead
- `POST /api/sessions/[beadId]/comment` - Add a comment to a bead session
- `POST /api/sessions/[beadId]/messages/[messageId]/read` - Mark message as read
- `POST /api/sessions/[beadId]/messages/[messageId]/ack` - Acknowledge message
- `GET /api/agents/[agentId]/stats` - Fetch agent productivity metrics
### Frontend Components
- **SessionsPage** (`src/components/sessions/sessions-page.tsx`): Main layout and orchestration
- **TaskCard** components: Visual representation of session state
- **AgentStatsPanel**: Metrics dashboard per agent
## Session States
Tasks automatically transition between states based on activity and communication:
| State | Description | Visual Indicator |
|-------|-------------|------------------|
| `active` | Status is `in_progress`, recent activity | Green pulse |
| `reviewing` | Under review or verification | Blue |
| `deciding` | Status is `todo` or `ready`, waiting for claim | Gray |
| `needs_input` | Status is `blocked` or has pending required acknowledgments | Yellow/Orange |
| `completed` | Status is `closed` | Green checkmark |
| `stale` | No activity in 24+ hours | Faded/Red |
## Integration with `bb agent` CLI
The Sessions Hub visualizes data managed by the `bb agent` command-line interface. See `docs/agent-session-flow.md` for the operator workflow.
**Key Commands:**
- `bb agent register --name <name> --role <role>` - Register agent identity
- `bb agent send --from <sender> --to <recipient> --bead <id> --category <type>` - Send message
- `bb agent inbox --agent <name>` - Check messages
- `bb agent reserve --agent <name> --scope <glob> --bead <id>` - Reserve files
- `bb agent status --bead <id>` - Check reservation status
## Data Flow
1. **Source of Truth**: `.beads/issues.jsonl` via `bd` CLI
2. **Activity Generation**: Watcher detects changes → snapshot differ → event bus
3. **Agent Coordination**: `bb` CLI writes to `.beads/agents/` directory
4. **UI Refresh**: SSE stream (`/api/events`) pushes updates to frontend in real-time
## Configuration
No configuration required. The Sessions Hub automatically:
- Discovers registered agents from `.beads/agents/`
- Builds communication graph from mailboxes
- Derives session states from current bead status + activity
## Performance
- **O(N) Diffing**: Snapshot differ scales linearly with number of beads
- **Ring Buffer**: Activity persistence uses fixed-size memory buffer (configurable)
- **Real-time Updates**: SSE keeps UI synchronized without polling
## Limitations
- Comment interactions are not yet streamed to the timeline
- Cross-project agent coordination requires agents to be registered in each project
- Stale threshold is fixed at 24 hours (not user-configurable)
## Related Documentation
- `docs/agent-session-flow.md` - CLI workflow guide for operators
- `docs/features/timeline.md` - Chronological activity feed
- `docs/RFC-001-Agent-Coordination.md` - Agent coordination design
- `docs/adr/2026-02-14-beadboard-driver-skill-and-bb-resolution.md` - beadboard-driver skill

View file

@ -1,318 +1,318 @@
# Comprehensive Theme System Design
## The Problem
We have colors scattered across 67+ files:
- Hardcoded hex: `bg-[#0a111a]`, `bg-[#111f2b]`, `bg-[#14202e]`
- Inline styles: `style={{ backgroundColor: '#1a2d3d' }}`
- Arbitrary Tailwind: `bg-white/5`, `border-white/10`
- Mixed variable systems: `--ui-bg-*`, `--color-bg-*`, etc.
## The Solution: Unified Theme System
### File Structure
```
src/styles/
themes/
index.css ← Theme definitions + data-attribute switching
tokens.css ← Base CSS variable names (no values)
components/
surfaces.css ← Surface layer utilities
interactions.css ← Hover, focus, active states
```
### Token Architecture (12 Semantic Categories)
#### 1. SURFACE LAYERS (Backgrounds)
```css
--surface-backdrop: /* Page background */
--surface-elevated: /* Header - sits on top */
--surface-primary: /* Left sidebar */
--surface-secondary: /* Main content area */
--surface-tertiary: /* Panels/cards within sidebars */
--surface-quaternary: /* Cards */
--surface-overlay: /* Modals, dropdowns, drawers */
--surface-input: /* Form fields, inputs */
--surface-hover: /* Hover states */
--surface-active: /* Active/selected states */
--surface-tooltip: /* Tooltips, popovers */
```
#### 2. BORDERS
```css
--border-subtle: /* Dividers between sections */
--border-default: /* Card borders */
--border-strong: /* Focus rings, selected states */
--border-accent: /* Colored status borders */
```
#### 3. TEXT
```css
--text-primary: /* Headlines, important text */
--text-secondary: /* Body text */
--text-tertiary: /* Muted, hints */
--text-disabled: /* Disabled elements */
--text-inverse: /* Text on colored backgrounds */
```
#### 4. ACCENTS (Functional)
```css
--accent-info: /* Cyan - links, actions */
--accent-success: /* Green - ready, done */
--accent-warning: /* Amber - in progress */
--accent-danger: /* Red - blocked, errors */
```
#### 5. ACCENTS (Aurora Glow)
```css
--glow-info: /* Box-shadow glow for info */
--glow-success: /* Box-shadow glow for success */
--glow-warning: /* Box-shadow glow for warning */
--glow-danger: /* Box-shadow glow for danger */
```
#### 6. GRAPH COLORS
```css
--graph-node-default: /* Default node background */
--graph-node-epic: /* Epic node accent */
--graph-edge-default: /* Default edge color */
--graph-edge-selected: /* Selected edge color */
--graph-edge-cycle: /* Cycle warning color */
```
#### 7. SEMANTIC ALPHAS
Instead of `bg-white/5` and `bg-black/40`, use themeable alphas:
```css
--alpha-white-low: /* 5% white */
--alpha-white-medium: /* 10% white */
--alpha-white-high: /* 20% white */
--alpha-black-low: /* 10% black */
--alpha-black-medium: /* 40% black */
--alpha-black-high: /* 80% black */
```
#### 8. STATUS COLORS
```css
--status-ready: /* Ready/open status */
--status-in-progress: /* In progress status */
--status-blocked: /* Blocked status */
--status-closed: /* Closed/done status */
--status-deferred: /* Deferred status */
```
#### 9. SHADOWS
```css
--shadow-sm: /* Subtle elevation */
--shadow-md: /* Cards */
--shadow-lg: /* Modals, drawers */
--shadow-glow-info: /* Aurora glow */
--shadow-glow-success: /* Aurora glow */
--shadow-glow-warning: /* Aurora glow */
--shadow-glow-danger: /* Aurora glow */
```
#### 10. AGENT/ROLE COLORS
```css
--agent-role-ui: /* UI role color */
--agent-role-graph: /* Graph role color */
--agent-role-orchestrator: /* Orchestrator role */
--agent-role-researcher: /* Researcher role */
```
#### 11. SCROLLBARS
```css
--scrollbar-track: /* Scrollbar track */
--scrollbar-thumb: /* Scrollbar thumb */
--scrollbar-thumb-hover: /* Scrollbar thumb hover */
```
#### 12. CODE/SYNTAX
```css
--code-background: /* Code block background */
--code-text: /* Code text color */
```
---
## Theme Definitions (Example)
### Aurora Theme (Current)
```css
[data-theme="aurora"] {
/* Surfaces - Warm Charcoal */
--surface-backdrop: #181716;
--surface-elevated: #131211;
--surface-primary: #1f1e1d;
--surface-secondary: #242322;
--surface-tertiary: #282725;
--surface-quaternary: #302e2c;
--surface-overlay: #0d0c0b;
/* Borders */
--border-subtle: rgba(180, 175, 165, 0.15);
--border-default: rgba(180, 175, 165, 0.25);
--border-strong: rgba(180, 175, 165, 0.4);
/* Text */
--text-primary: #f0eeea;
--text-secondary: #c9c5bc;
--text-tertiary: #a8a49a;
/* Accents */
--accent-info: #35c9ff;
--accent-success: #35d98f;
--accent-warning: #ffb24a;
--accent-danger: #ff4c72;
/* Glows */
--glow-info: 0 0 20px rgba(53, 201, 255, 0.3);
--glow-success: 0 0 20px rgba(53, 217, 143, 0.3);
/* Graph */
--graph-node-default: rgba(48, 46, 44, 0.8);
--graph-node-epic: rgba(53, 201, 255, 0.15);
--graph-edge-default: rgba(180, 175, 165, 0.3);
--graph-edge-selected: #35c9ff;
/* Alphas */
--alpha-white-low: rgba(240, 238, 234, 0.05);
--alpha-white-medium: rgba(240, 238, 234, 0.1);
--alpha-black-medium: rgba(0, 0, 0, 0.4);
}
```
### Midnight Theme (Future)
```css
[data-theme="midnight"] {
--surface-backdrop: #0a0a0f;
--surface-elevated: #050508;
--surface-primary: #111118;
--surface-secondary: #151520;
--surface-quaternary: #1e1e2e;
--accent-info: #8b5cf6;
--accent-success: #10b981;
/* Same structure, different values */
}
```
---
## Migration Strategy
### Phase 1: Create Token System
1. Create `src/styles/themes/index.css` with token definitions
2. Create `src/styles/themes/tokens.css` with token names
3. Add data-theme attribute to layout
### Phase 2: Component Audit & Migration
For each component:
1. Replace hardcoded colors with semantic tokens
2. Replace `bg-white/5` with `bg-[var(--alpha-white-low)]`
3. Replace `bg-[#0a111a]` with appropriate surface token
### Phase 3: Graph/Flow Colors
1. Extract all graph colors to `--graph-*` tokens
2. Update ReactFlow styles to use CSS variables
### Phase 4: Validation
1. Create theme preview page showing all tokens
2. Verify no hardcoded colors remain
---
## Usage Examples
### Before (Chaos):
```tsx
<div className="bg-[#0a111a] border border-white/10">
<span className="text-[#a8a49a]">Text</span>
</div>
```
### After (Clean):
```tsx
<div className="bg-[var(--surface-tertiary)] border border-[var(--border-default)]">
<span className="text-[var(--text-tertiary)]">Text</span>
</div>
```
### With Tailwind utilities (even cleaner):
```tsx
<div className="surface-tertiary border-default">
<span className="text-tertiary">Text</span>
</div>
```
---
## Component Mapping Guide
| Component | Current | New Token |
|-----------|---------|-----------|
| TopBar | `bg-[var(--ui-bg-header)]` | `bg-[var(--surface-elevated)]` |
| LeftPanel | `bg-[var(--ui-bg-shell)]` | `bg-[var(--surface-primary)]` |
| Main content | `bg-[var(--ui-bg-main)]` | `bg-[var(--surface-secondary)]` |
| SocialCard | `bg-[var(--ui-bg-card)]` | `bg-[var(--surface-quaternary)]` |
| AssignmentPanel | `bg-[#0a111a]` | `bg-[var(--surface-tertiary)]` |
| Modal/Drawer | `bg-[#0d0c0b]` | `bg-[var(--surface-overlay)]` |
| Input fields | `bg-[#0f1824]` | `bg-[var(--surface-input)]` |
---
## Files That Need Migration (Priority Order)
### HIGH (Core UI):
1. `src/app/globals.css` - Define tokens
2. `src/components/shared/unified-shell.tsx` - Main layout
3. `src/components/shared/top-bar.tsx` - Header
4. `src/components/shared/left-panel.tsx` - Sidebar
5. `src/components/shared/right-panel.tsx` - Right panel
6. `src/components/social/social-card.tsx` - Cards
### MEDIUM (Active Views):
7. `src/components/graph/assignment-panel.tsx` - Heavy hardcoded colors
8. `src/components/graph/graph-node-card.tsx` - Graph nodes
9. `src/components/activity/swarm-command-feed.tsx` - Activity feed
10. `src/components/graph/smart-dag.tsx` - Graph background
### LOWER (Secondary):
11. All modal/dialog components
12. All form/input components
13. Kanban components (if still used)
14. Swarm components
---
## Success Criteria
- [ ] Zero hardcoded hex colors in components (except for data viz)
- [ ] Zero `bg-white/X` or `bg-black/X` - all use `--alpha-*` tokens
- [ ] Theme switcher works instantly without reload
- [ ] All 12 token categories have values for each theme
- [ ] Visual regression test passes (no unintended changes)
---
## For You (The Human)
Once this is implemented, you can just say:
> "Change the sidebar to be slightly lighter in the aurora theme"
And I'll know exactly where to go:
```css
[data-theme="aurora"] {
--surface-primary: #252422; /* Changed from #1f1e1d */
}
```
Or:
> "Make the aurora glow more subtle"
```css
[data-theme="aurora"] {
--glow-info: 0 0 12px rgba(53, 201, 255, 0.15); /* Reduced from 20px/0.3 */
}
```
Everything in one place. No hunting through 67 files.
# Comprehensive Theme System Design
## The Problem
We have colors scattered across 67+ files:
- Hardcoded hex: `bg-[#0a111a]`, `bg-[#111f2b]`, `bg-[#14202e]`
- Inline styles: `style={{ backgroundColor: '#1a2d3d' }}`
- Arbitrary Tailwind: `bg-white/5`, `border-white/10`
- Mixed variable systems: `--ui-bg-*`, `--color-bg-*`, etc.
## The Solution: Unified Theme System
### File Structure
```
src/styles/
themes/
index.css ← Theme definitions + data-attribute switching
tokens.css ← Base CSS variable names (no values)
components/
surfaces.css ← Surface layer utilities
interactions.css ← Hover, focus, active states
```
### Token Architecture (12 Semantic Categories)
#### 1. SURFACE LAYERS (Backgrounds)
```css
--surface-backdrop: /* Page background */
--surface-elevated: /* Header - sits on top */
--surface-primary: /* Left sidebar */
--surface-secondary: /* Main content area */
--surface-tertiary: /* Panels/cards within sidebars */
--surface-quaternary: /* Cards */
--surface-overlay: /* Modals, dropdowns, drawers */
--surface-input: /* Form fields, inputs */
--surface-hover: /* Hover states */
--surface-active: /* Active/selected states */
--surface-tooltip: /* Tooltips, popovers */
```
#### 2. BORDERS
```css
--border-subtle: /* Dividers between sections */
--border-default: /* Card borders */
--border-strong: /* Focus rings, selected states */
--border-accent: /* Colored status borders */
```
#### 3. TEXT
```css
--text-primary: /* Headlines, important text */
--text-secondary: /* Body text */
--text-tertiary: /* Muted, hints */
--text-disabled: /* Disabled elements */
--text-inverse: /* Text on colored backgrounds */
```
#### 4. ACCENTS (Functional)
```css
--accent-info: /* Cyan - links, actions */
--accent-success: /* Green - ready, done */
--accent-warning: /* Amber - in progress */
--accent-danger: /* Red - blocked, errors */
```
#### 5. ACCENTS (Aurora Glow)
```css
--glow-info: /* Box-shadow glow for info */
--glow-success: /* Box-shadow glow for success */
--glow-warning: /* Box-shadow glow for warning */
--glow-danger: /* Box-shadow glow for danger */
```
#### 6. GRAPH COLORS
```css
--graph-node-default: /* Default node background */
--graph-node-epic: /* Epic node accent */
--graph-edge-default: /* Default edge color */
--graph-edge-selected: /* Selected edge color */
--graph-edge-cycle: /* Cycle warning color */
```
#### 7. SEMANTIC ALPHAS
Instead of `bg-white/5` and `bg-black/40`, use themeable alphas:
```css
--alpha-white-low: /* 5% white */
--alpha-white-medium: /* 10% white */
--alpha-white-high: /* 20% white */
--alpha-black-low: /* 10% black */
--alpha-black-medium: /* 40% black */
--alpha-black-high: /* 80% black */
```
#### 8. STATUS COLORS
```css
--status-ready: /* Ready/open status */
--status-in-progress: /* In progress status */
--status-blocked: /* Blocked status */
--status-closed: /* Closed/done status */
--status-deferred: /* Deferred status */
```
#### 9. SHADOWS
```css
--shadow-sm: /* Subtle elevation */
--shadow-md: /* Cards */
--shadow-lg: /* Modals, drawers */
--shadow-glow-info: /* Aurora glow */
--shadow-glow-success: /* Aurora glow */
--shadow-glow-warning: /* Aurora glow */
--shadow-glow-danger: /* Aurora glow */
```
#### 10. AGENT/ROLE COLORS
```css
--agent-role-ui: /* UI role color */
--agent-role-graph: /* Graph role color */
--agent-role-orchestrator: /* Orchestrator role */
--agent-role-researcher: /* Researcher role */
```
#### 11. SCROLLBARS
```css
--scrollbar-track: /* Scrollbar track */
--scrollbar-thumb: /* Scrollbar thumb */
--scrollbar-thumb-hover: /* Scrollbar thumb hover */
```
#### 12. CODE/SYNTAX
```css
--code-background: /* Code block background */
--code-text: /* Code text color */
```
---
## Theme Definitions (Example)
### Aurora Theme (Current)
```css
[data-theme="aurora"] {
/* Surfaces - Warm Charcoal */
--surface-backdrop: #181716;
--surface-elevated: #131211;
--surface-primary: #1f1e1d;
--surface-secondary: #242322;
--surface-tertiary: #282725;
--surface-quaternary: #302e2c;
--surface-overlay: #0d0c0b;
/* Borders */
--border-subtle: rgba(180, 175, 165, 0.15);
--border-default: rgba(180, 175, 165, 0.25);
--border-strong: rgba(180, 175, 165, 0.4);
/* Text */
--text-primary: #f0eeea;
--text-secondary: #c9c5bc;
--text-tertiary: #a8a49a;
/* Accents */
--accent-info: #35c9ff;
--accent-success: #35d98f;
--accent-warning: #ffb24a;
--accent-danger: #ff4c72;
/* Glows */
--glow-info: 0 0 20px rgba(53, 201, 255, 0.3);
--glow-success: 0 0 20px rgba(53, 217, 143, 0.3);
/* Graph */
--graph-node-default: rgba(48, 46, 44, 0.8);
--graph-node-epic: rgba(53, 201, 255, 0.15);
--graph-edge-default: rgba(180, 175, 165, 0.3);
--graph-edge-selected: #35c9ff;
/* Alphas */
--alpha-white-low: rgba(240, 238, 234, 0.05);
--alpha-white-medium: rgba(240, 238, 234, 0.1);
--alpha-black-medium: rgba(0, 0, 0, 0.4);
}
```
### Midnight Theme (Future)
```css
[data-theme="midnight"] {
--surface-backdrop: #0a0a0f;
--surface-elevated: #050508;
--surface-primary: #111118;
--surface-secondary: #151520;
--surface-quaternary: #1e1e2e;
--accent-info: #8b5cf6;
--accent-success: #10b981;
/* Same structure, different values */
}
```
---
## Migration Strategy
### Phase 1: Create Token System
1. Create `src/styles/themes/index.css` with token definitions
2. Create `src/styles/themes/tokens.css` with token names
3. Add data-theme attribute to layout
### Phase 2: Component Audit & Migration
For each component:
1. Replace hardcoded colors with semantic tokens
2. Replace `bg-white/5` with `bg-[var(--alpha-white-low)]`
3. Replace `bg-[#0a111a]` with appropriate surface token
### Phase 3: Graph/Flow Colors
1. Extract all graph colors to `--graph-*` tokens
2. Update ReactFlow styles to use CSS variables
### Phase 4: Validation
1. Create theme preview page showing all tokens
2. Verify no hardcoded colors remain
---
## Usage Examples
### Before (Chaos):
```tsx
<div className="bg-[#0a111a] border border-white/10">
<span className="text-[#a8a49a]">Text</span>
</div>
```
### After (Clean):
```tsx
<div className="bg-[var(--surface-tertiary)] border border-[var(--border-default)]">
<span className="text-[var(--text-tertiary)]">Text</span>
</div>
```
### With Tailwind utilities (even cleaner):
```tsx
<div className="surface-tertiary border-default">
<span className="text-tertiary">Text</span>
</div>
```
---
## Component Mapping Guide
| Component | Current | New Token |
|-----------|---------|-----------|
| TopBar | `bg-[var(--ui-bg-header)]` | `bg-[var(--surface-elevated)]` |
| LeftPanel | `bg-[var(--ui-bg-shell)]` | `bg-[var(--surface-primary)]` |
| Main content | `bg-[var(--ui-bg-main)]` | `bg-[var(--surface-secondary)]` |
| SocialCard | `bg-[var(--ui-bg-card)]` | `bg-[var(--surface-quaternary)]` |
| AssignmentPanel | `bg-[#0a111a]` | `bg-[var(--surface-tertiary)]` |
| Modal/Drawer | `bg-[#0d0c0b]` | `bg-[var(--surface-overlay)]` |
| Input fields | `bg-[#0f1824]` | `bg-[var(--surface-input)]` |
---
## Files That Need Migration (Priority Order)
### HIGH (Core UI):
1. `src/app/globals.css` - Define tokens
2. `src/components/shared/unified-shell.tsx` - Main layout
3. `src/components/shared/top-bar.tsx` - Header
4. `src/components/shared/left-panel.tsx` - Sidebar
5. `src/components/shared/right-panel.tsx` - Right panel
6. `src/components/social/social-card.tsx` - Cards
### MEDIUM (Active Views):
7. `src/components/graph/assignment-panel.tsx` - Heavy hardcoded colors
8. `src/components/graph/graph-node-card.tsx` - Graph nodes
9. `src/components/activity/swarm-command-feed.tsx` - Activity feed
10. `src/components/graph/smart-dag.tsx` - Graph background
### LOWER (Secondary):
11. All modal/dialog components
12. All form/input components
13. Kanban components (if still used)
14. Swarm components
---
## Success Criteria
- [ ] Zero hardcoded hex colors in components (except for data viz)
- [ ] Zero `bg-white/X` or `bg-black/X` - all use `--alpha-*` tokens
- [ ] Theme switcher works instantly without reload
- [ ] All 12 token categories have values for each theme
- [ ] Visual regression test passes (no unintended changes)
---
## For You (The Human)
Once this is implemented, you can just say:
> "Change the sidebar to be slightly lighter in the aurora theme"
And I'll know exactly where to go:
```css
[data-theme="aurora"] {
--surface-primary: #252422; /* Changed from #1f1e1d */
}
```
Or:
> "Make the aurora glow more subtle"
```css
[data-theme="aurora"] {
--glow-info: 0 0 12px rgba(53, 201, 255, 0.15); /* Reduced from 20px/0.3 */
}
```
Everything in one place. No hunting through 67 files.

View file

@ -257,4 +257,4 @@
- Mutations executed only via `bd.exe`
- Real-time updates delivered via SSE
- Kanban, Graph, Timeline, Agent Session views functional
- Boundary guard test prevents direct JSONL writes
- Boundary guard test prevents direct JSONL writes

View file

@ -159,4 +159,4 @@ Current Beads ecosystem tools are often Unix/macOS oriented, creating friction f
- Reads from `.beads/issues.jsonl` successfully for registered projects
- All writes performed via `bd.exe` and reflected back via watcher/SSE
- Kanban, Timeline, Graph, and Agent Session views function against real bead data
- No direct `issues.jsonl` write implementation exists in app code
- No direct `issues.jsonl` write implementation exists in app code

View file

@ -1,134 +1,134 @@
# BeadBoard Kanban Design System Plan
**Goal**
Ship a production-ready baseline visual system for Tracer Bullet 1 (Kanban) before further feature expansion.
**Primary decision**
Use **Tailwind CSS v4 + CSS tokens (`@theme`) + Framer Motion**.
## 1. Why This Stack
### Tailwind v4 is the right baseline
- Fastest path to a coherent, reusable system in Next.js 15.
- CSS-first token model (`@theme`) fits our need for semantic design tokens.
- Lets us avoid scattered inline styles and ad-hoc CSS files.
### Framer Motion should be scoped
- Use for state transitions (card changes, panel enter/exit, filtered results).
- Avoid decorative over-animation that hurts readability in a dense dashboard.
### Risks and mitigations
- Risk: “generic Tailwind look”
- Mitigation: strict token palette + component contracts + typography rules.
- Risk: visual inconsistency
- Mitigation: no direct color literals in component markup except token definitions.
## 2. Baseline-First Sequencing
This should happen **now**, not later.
1. Foundation (tokens, layout, core components)
2. Motion and interaction polish
3. Accessibility and responsive hardening
4. Continue other tracer bullets
## 3. Visual Language (v1)
### Product feel
- High-signal operations UI.
- Calm neutral surfaces with sharp status accents.
- Dense information without visual clutter.
### Typography
- Primary UI: `DM Sans` (or `Inter` fallback decision at implementation time)
- Metadata/IDs: `JetBrains Mono`
### Color model
- Semantic tokens only:
- `background`, `foreground`, `surface`, `muted`
- `status-open`, `status-in-progress`, `status-blocked`, `status-deferred`, `status-closed`
- `priority-p0` ... `priority-p4`
- Contrast target: at least WCAG AA for normal text.
## 4. Component Contract
Required first-class components:
- `KanbanPageShell`
- `KanbanControls`
- `KanbanBoard`
- `KanbanColumn`
- `KanbanCard`
- `KanbanDetailPanel`
- shared: `Badge`, `Chip`, `StatPill`
Rules:
- Component variants defined via class composition (CVA optional but preferred).
- No inline style objects for production components.
- All spacing/radius/shadow/color come from tokens/utilities.
## 5. Layout Contract
### Desktop
- Sticky top header with filters + stats.
- Main grid: board + detail panel.
- Columns scroll horizontally as needed.
### Mobile
- Stacked controls.
- Board in horizontal swipe/scroll mode.
- Detail panel becomes full-screen drawer.
## 6. Motion Contract (Framer Motion)
Use motion for:
- Card appear/disappear on filtering.
- Detail panel slide-in/out.
- Subtle status count transitions.
Do not animate:
- Global page container on every render.
- Constant hover effects that reduce legibility/performance.
## 7. Tailwind v4 Implementation Plan
### Phase A: Design System Foundation (P0)
- Add Tailwind v4 pipeline with `@import "tailwindcss"` in global stylesheet.
- Define `@theme` token set (colors, radius, spacing aliases, shadows, motion tokens).
- Add base layer typography/background defaults.
- Replace inline styles in tracer-1 components with tokenized Tailwind classes.
Acceptance criteria:
- No inline style usage in `src/components/kanban/*` and shared primitives (except truly dynamic edge cases).
- UI at `localhost:3000` has coherent baseline styling.
### Phase B: Motion + Interaction Polish (P1)
- Integrate Framer Motion transitions for board and panel.
- Improve visual hierarchy of card metadata.
- Add polished empty/loading/error states.
Acceptance criteria:
- Motion communicates state changes without jitter.
- Filtering and detail interactions feel intentional.
### Phase C: Accessibility + Responsive Hardening (P1)
- Keyboard focus and traversal for cards/panel.
- Verify color contrast and focus visibility.
- Tune mobile breakpoints and touch targets.
Acceptance criteria:
- Keyboard-only flow works for core Kanban actions.
- Mobile experience is usable and visually consistent.
## 8. Technical Boundaries
- Read path remains `.beads/issues.jsonl` / `.beads/issues.jsonl.new`.
- No direct write path to JSONL.
- Styling changes must not alter read/write boundary behavior.
## 9. Definition of Done (Tracer-1 Design Baseline)
- Tailwind v4 configured and used as primary styling framework.
- Tokenized design system applied across tracer-1 Kanban components.
- Framer Motion integrated for key transitions.
- Tests/typecheck pass, app runs on `localhost:3000`.
- Visual result is clearly beyond prototype/demo quality.
# BeadBoard Kanban Design System Plan
**Goal**
Ship a production-ready baseline visual system for Tracer Bullet 1 (Kanban) before further feature expansion.
**Primary decision**
Use **Tailwind CSS v4 + CSS tokens (`@theme`) + Framer Motion**.
## 1. Why This Stack
### Tailwind v4 is the right baseline
- Fastest path to a coherent, reusable system in Next.js 15.
- CSS-first token model (`@theme`) fits our need for semantic design tokens.
- Lets us avoid scattered inline styles and ad-hoc CSS files.
### Framer Motion should be scoped
- Use for state transitions (card changes, panel enter/exit, filtered results).
- Avoid decorative over-animation that hurts readability in a dense dashboard.
### Risks and mitigations
- Risk: “generic Tailwind look”
- Mitigation: strict token palette + component contracts + typography rules.
- Risk: visual inconsistency
- Mitigation: no direct color literals in component markup except token definitions.
## 2. Baseline-First Sequencing
This should happen **now**, not later.
1. Foundation (tokens, layout, core components)
2. Motion and interaction polish
3. Accessibility and responsive hardening
4. Continue other tracer bullets
## 3. Visual Language (v1)
### Product feel
- High-signal operations UI.
- Calm neutral surfaces with sharp status accents.
- Dense information without visual clutter.
### Typography
- Primary UI: `DM Sans` (or `Inter` fallback decision at implementation time)
- Metadata/IDs: `JetBrains Mono`
### Color model
- Semantic tokens only:
- `background`, `foreground`, `surface`, `muted`
- `status-open`, `status-in-progress`, `status-blocked`, `status-deferred`, `status-closed`
- `priority-p0` ... `priority-p4`
- Contrast target: at least WCAG AA for normal text.
## 4. Component Contract
Required first-class components:
- `KanbanPageShell`
- `KanbanControls`
- `KanbanBoard`
- `KanbanColumn`
- `KanbanCard`
- `KanbanDetailPanel`
- shared: `Badge`, `Chip`, `StatPill`
Rules:
- Component variants defined via class composition (CVA optional but preferred).
- No inline style objects for production components.
- All spacing/radius/shadow/color come from tokens/utilities.
## 5. Layout Contract
### Desktop
- Sticky top header with filters + stats.
- Main grid: board + detail panel.
- Columns scroll horizontally as needed.
### Mobile
- Stacked controls.
- Board in horizontal swipe/scroll mode.
- Detail panel becomes full-screen drawer.
## 6. Motion Contract (Framer Motion)
Use motion for:
- Card appear/disappear on filtering.
- Detail panel slide-in/out.
- Subtle status count transitions.
Do not animate:
- Global page container on every render.
- Constant hover effects that reduce legibility/performance.
## 7. Tailwind v4 Implementation Plan
### Phase A: Design System Foundation (P0)
- Add Tailwind v4 pipeline with `@import "tailwindcss"` in global stylesheet.
- Define `@theme` token set (colors, radius, spacing aliases, shadows, motion tokens).
- Add base layer typography/background defaults.
- Replace inline styles in tracer-1 components with tokenized Tailwind classes.
Acceptance criteria:
- No inline style usage in `src/components/kanban/*` and shared primitives (except truly dynamic edge cases).
- UI at `localhost:3000` has coherent baseline styling.
### Phase B: Motion + Interaction Polish (P1)
- Integrate Framer Motion transitions for board and panel.
- Improve visual hierarchy of card metadata.
- Add polished empty/loading/error states.
Acceptance criteria:
- Motion communicates state changes without jitter.
- Filtering and detail interactions feel intentional.
### Phase C: Accessibility + Responsive Hardening (P1)
- Keyboard focus and traversal for cards/panel.
- Verify color contrast and focus visibility.
- Tune mobile breakpoints and touch targets.
Acceptance criteria:
- Keyboard-only flow works for core Kanban actions.
- Mobile experience is usable and visually consistent.
## 8. Technical Boundaries
- Read path remains `.beads/issues.jsonl` / `.beads/issues.jsonl.new`.
- No direct write path to JSONL.
- Styling changes must not alter read/write boundary behavior.
## 9. Definition of Done (Tracer-1 Design Baseline)
- Tailwind v4 configured and used as primary styling framework.
- Tokenized design system applied across tracer-1 Kanban components.
- Framer Motion integrated for key transitions.
- Tests/typecheck pass, app runs on `localhost:3000`.
- Visual result is clearly beyond prototype/demo quality.

View file

@ -1,52 +1,52 @@
# Project Context Model Design
## Summary
Aggregate views need stable project identity attached to each issue so cross-project Kanban, timeline, and session views can filter and display project metadata consistently. This design adds a normalized `ProjectContext` payload to every issue returned from read flows while keeping the raw JSONL format untouched.
## Requirements
- Use existing Windows-safe path normalization for stable identity.
- Attach project identity on every issue returned from read services.
- Include fields: `key`, `root`, `displayPath`, `name`, `source`, `addedAt`.
- Default single-project reads to `source="local"` and `addedAt=null`.
## Data Model
```ts
export type ProjectSource = 'local' | 'registry' | 'scanner';
export interface ProjectContext {
key: string; // windowsPathKey(root)
root: string; // canonicalizeWindowsPath(root)
displayPath: string; // toDisplayPath(root)
name: string; // path.basename(root)
source: ProjectSource;
addedAt: string | null;
}
export type BeadIssueWithProject = BeadIssue & { project: ProjectContext };
```
## Construction
- Add a helper (e.g., `buildProjectContext`) that accepts `projectRoot`, `source`, and `addedAt`.
- Normalize the root with `canonicalizeWindowsPath`, compute the key with `windowsPathKey`, display path with `toDisplayPath`, and name from `path.basename`.
- No filesystem checks are required; this is identity metadata only.
## Read Flow Integration
- Update `readIssuesFromDisk` to attach `project` to each parsed issue.
- Default `projectRoot` to `process.cwd()` when not provided.
- Keep the existing `BeadIssue` shape for raw parsing; project context is added in read services only.
## Error Handling
- If `projectRoot` is empty, throw a clear error early in `buildProjectContext`.
- Otherwise, treat normalization as pure string ops and do not swallow exceptions.
## Tests
- Add unit tests for `buildProjectContext` field derivation (key/root/displayPath/name/source/addedAt).
- Update `readIssuesFromDisk` tests to assert `project` is attached with expected fields.
## Alternatives Considered
1. **Wrapper object `{ project, issue }`**
Pro: explicit separation; Con: more refactors across UI filtering and query shapes.
2. **`metadata.project` on issues**
Pro: zero type changes; Con: weak typing and harder discoverability.
3. **Chosen: `issue.project` field**
Clear typing, predictable access, and minimal friction for UI + aggregate queries.
# Project Context Model Design
## Summary
Aggregate views need stable project identity attached to each issue so cross-project Kanban, timeline, and session views can filter and display project metadata consistently. This design adds a normalized `ProjectContext` payload to every issue returned from read flows while keeping the raw JSONL format untouched.
## Requirements
- Use existing Windows-safe path normalization for stable identity.
- Attach project identity on every issue returned from read services.
- Include fields: `key`, `root`, `displayPath`, `name`, `source`, `addedAt`.
- Default single-project reads to `source="local"` and `addedAt=null`.
## Data Model
```ts
export type ProjectSource = 'local' | 'registry' | 'scanner';
export interface ProjectContext {
key: string; // windowsPathKey(root)
root: string; // canonicalizeWindowsPath(root)
displayPath: string; // toDisplayPath(root)
name: string; // path.basename(root)
source: ProjectSource;
addedAt: string | null;
}
export type BeadIssueWithProject = BeadIssue & { project: ProjectContext };
```
## Construction
- Add a helper (e.g., `buildProjectContext`) that accepts `projectRoot`, `source`, and `addedAt`.
- Normalize the root with `canonicalizeWindowsPath`, compute the key with `windowsPathKey`, display path with `toDisplayPath`, and name from `path.basename`.
- No filesystem checks are required; this is identity metadata only.
## Read Flow Integration
- Update `readIssuesFromDisk` to attach `project` to each parsed issue.
- Default `projectRoot` to `process.cwd()` when not provided.
- Keep the existing `BeadIssue` shape for raw parsing; project context is added in read services only.
## Error Handling
- If `projectRoot` is empty, throw a clear error early in `buildProjectContext`.
- Otherwise, treat normalization as pure string ops and do not swallow exceptions.
## Tests
- Add unit tests for `buildProjectContext` field derivation (key/root/displayPath/name/source/addedAt).
- Update `readIssuesFromDisk` tests to assert `project` is attached with expected fields.
## Alternatives Considered
1. **Wrapper object `{ project, issue }`**
Pro: explicit separation; Con: more refactors across UI filtering and query shapes.
2. **`metadata.project` on issues**
Pro: zero type changes; Con: weak typing and harder discoverability.
3. **Chosen: `issue.project` field**
Clear typing, predictable access, and minimal friction for UI + aggregate queries.

View file

@ -1,139 +1,139 @@
# Multi-Project UI Contract (bb-6aj.6)
Date: 2026-02-13
Owner: `bb-6aj.6`
Scope: Convert existing registry/scanner backend into stable, user-facing project scope workflows for Kanban and Graph.
## 1) Product Workflow Contract
Primary user flow:
1. Select project scope (`local` or one registry project).
2. View project-scoped issues in Kanban and Graph using the same selected scope.
3. Manage registry roots (add/remove) from a single shared manager panel.
4. Discover import candidates from safe scan roots and add selected projects to registry.
5. (Later phase) Optionally switch to aggregate mode for cross-project read-only views.
Rules:
- Project scope is always explicit in URL query (`?project=`).
- Scope change affects reads only; mutations continue to target current scope root.
- Project scope must persist when navigating between `/` and `/graph`.
- No direct JSONL writes at any point.
## 2) Screen Ownership
Kanban (`/`):
- Primary triage and mutation workspace.
- Owns project scope picker entry point and registry manager entry.
- Displays selected project context in header.
Graph (`/graph`):
- Readability-first dependency exploration for selected scope.
- Shares same project scope query + model as Kanban.
- Must preserve current scope when linking back to Kanban.
Shared controls:
- Project scope resolver utility (server-safe).
- URL serialization/parsing for project selection.
- Scope badge/pill visual token (consistent across pages).
Out of scope for this contract:
- Timeline/session epics behavior changes.
- Full graph redesign beyond scope persistence/read correctness.
## 3) URL and State Contract
Query key:
- `project`: scope key string.
Key encoding:
- `local`: current workspace (`process.cwd()`).
- registry project: `windowsPathKey(project.path)` derived from registry entry.
Resolution behavior:
1. Build scope options: `local` + registry projects (dedup by key).
2. If `project` query matches an option key, use that root.
3. If missing or invalid, fallback to `local`.
4. Reads use resolved root; returned issues include resolved `project` context.
Navigation behavior:
- `Kanban -> Graph` carries `?project=<key>`.
- `Graph -> Kanban` carries `?project=<key>`.
- Any scope picker action rewrites URL query without losing active route.
## 4) Aggregate Mode Contract (Deferred to bb-6aj.11)
- Aggregate mode is read-only across multiple project roots.
- Aggregate mode does not become default.
- Aggregate mode must visually mark per-project source on each card/row.
- Mutations from aggregate mode are disabled until explicit target scope is chosen.
## 5) Empty and Error States
No projects in registry:
- Show local project as selected.
- Show non-blocking empty hint in manager panel.
Invalid query key:
- Fallback to local scope.
- Keep page functional; do not hard fail.
Read failure for selected root:
- Preserve selected scope in UI.
- Show actionable error card with path and retry affordance.
Scanner failures:
- Show root-level failure summary with skipped/error counts.
- Do not alter current selection automatically.
## 6) Phased Execution Plan
Phase A (`bb-6aj.7`): Shared scope model + URL persistence
- Add server utility to resolve active scope from query + registry.
- Wire `/` and `/graph` to resolved scope.
- Ensure cross-links preserve `?project=`.
Phase B (`bb-6aj.8`): Registry manager panel
- List registry projects with add/remove actions.
- Validate Windows absolute paths with clear error text.
Phase C (`bb-6aj.9`): Scanner UX
- Scan safe roots with mode/depth controls.
- Allow selective import to registry.
Phase D (`bb-6aj.10`): Project-scoped reads in core views
- Ensure all read endpoints/components use selected scope root.
- Validate no regressions in local-only flow.
Phase E (`bb-6aj.11`): Aggregate mode
- Add cross-project read view with project badges.
- Keep mutations disabled without explicit project selection.
Phase F (`bb-6aj.12`): Verification and guardrails
- Typecheck + tests + Playwright evidence at required breakpoints.
## 7) Acceptance Criteria Matrix
Functional:
- Same `project` key yields same root and same issue set on both pages.
- Invalid `project` key falls back to local root cleanly.
- Route transitions preserve selected scope.
Boundary safety:
- No direct `.beads/issues.jsonl` writes.
- Existing mutation API boundaries unchanged.
Verification:
- Unit tests for scope resolution and URL behavior.
- Existing tests remain green.
- Playwright captures prove scope persistence on `/` and `/graph`.
## 8) Risks and Mitigations
Risk: Query value leaks absolute paths.
- Mitigation: use opaque normalized key, not raw path.
Risk: Registry drift vs URL key stale.
- Mitigation: deterministic fallback to local + visible selected-scope indicator.
Risk: UX churn from adding controls too early.
- Mitigation: enforce phase order and keep Phase A minimal.
# Multi-Project UI Contract (bb-6aj.6)
Date: 2026-02-13
Owner: `bb-6aj.6`
Scope: Convert existing registry/scanner backend into stable, user-facing project scope workflows for Kanban and Graph.
## 1) Product Workflow Contract
Primary user flow:
1. Select project scope (`local` or one registry project).
2. View project-scoped issues in Kanban and Graph using the same selected scope.
3. Manage registry roots (add/remove) from a single shared manager panel.
4. Discover import candidates from safe scan roots and add selected projects to registry.
5. (Later phase) Optionally switch to aggregate mode for cross-project read-only views.
Rules:
- Project scope is always explicit in URL query (`?project=`).
- Scope change affects reads only; mutations continue to target current scope root.
- Project scope must persist when navigating between `/` and `/graph`.
- No direct JSONL writes at any point.
## 2) Screen Ownership
Kanban (`/`):
- Primary triage and mutation workspace.
- Owns project scope picker entry point and registry manager entry.
- Displays selected project context in header.
Graph (`/graph`):
- Readability-first dependency exploration for selected scope.
- Shares same project scope query + model as Kanban.
- Must preserve current scope when linking back to Kanban.
Shared controls:
- Project scope resolver utility (server-safe).
- URL serialization/parsing for project selection.
- Scope badge/pill visual token (consistent across pages).
Out of scope for this contract:
- Timeline/session epics behavior changes.
- Full graph redesign beyond scope persistence/read correctness.
## 3) URL and State Contract
Query key:
- `project`: scope key string.
Key encoding:
- `local`: current workspace (`process.cwd()`).
- registry project: `windowsPathKey(project.path)` derived from registry entry.
Resolution behavior:
1. Build scope options: `local` + registry projects (dedup by key).
2. If `project` query matches an option key, use that root.
3. If missing or invalid, fallback to `local`.
4. Reads use resolved root; returned issues include resolved `project` context.
Navigation behavior:
- `Kanban -> Graph` carries `?project=<key>`.
- `Graph -> Kanban` carries `?project=<key>`.
- Any scope picker action rewrites URL query without losing active route.
## 4) Aggregate Mode Contract (Deferred to bb-6aj.11)
- Aggregate mode is read-only across multiple project roots.
- Aggregate mode does not become default.
- Aggregate mode must visually mark per-project source on each card/row.
- Mutations from aggregate mode are disabled until explicit target scope is chosen.
## 5) Empty and Error States
No projects in registry:
- Show local project as selected.
- Show non-blocking empty hint in manager panel.
Invalid query key:
- Fallback to local scope.
- Keep page functional; do not hard fail.
Read failure for selected root:
- Preserve selected scope in UI.
- Show actionable error card with path and retry affordance.
Scanner failures:
- Show root-level failure summary with skipped/error counts.
- Do not alter current selection automatically.
## 6) Phased Execution Plan
Phase A (`bb-6aj.7`): Shared scope model + URL persistence
- Add server utility to resolve active scope from query + registry.
- Wire `/` and `/graph` to resolved scope.
- Ensure cross-links preserve `?project=`.
Phase B (`bb-6aj.8`): Registry manager panel
- List registry projects with add/remove actions.
- Validate Windows absolute paths with clear error text.
Phase C (`bb-6aj.9`): Scanner UX
- Scan safe roots with mode/depth controls.
- Allow selective import to registry.
Phase D (`bb-6aj.10`): Project-scoped reads in core views
- Ensure all read endpoints/components use selected scope root.
- Validate no regressions in local-only flow.
Phase E (`bb-6aj.11`): Aggregate mode
- Add cross-project read view with project badges.
- Keep mutations disabled without explicit project selection.
Phase F (`bb-6aj.12`): Verification and guardrails
- Typecheck + tests + Playwright evidence at required breakpoints.
## 7) Acceptance Criteria Matrix
Functional:
- Same `project` key yields same root and same issue set on both pages.
- Invalid `project` key falls back to local root cleanly.
- Route transitions preserve selected scope.
Boundary safety:
- No direct `.beads/issues.jsonl` writes.
- Existing mutation API boundaries unchanged.
Verification:
- Unit tests for scope resolution and URL behavior.
- Existing tests remain green.
- Playwright captures prove scope persistence on `/` and `/graph`.
## 8) Risks and Mitigations
Risk: Query value leaks absolute paths.
- Mitigation: use opaque normalized key, not raw path.
Risk: Registry drift vs URL key stale.
- Mitigation: deterministic fallback to local + visible selected-scope indicator.
Risk: UX churn from adding controls too early.
- Mitigation: enforce phase order and keep Phase A minimal.

View file

@ -1,5 +1,5 @@
# Unified UX PRD - Swimlane Social Hub
# Unified UX PRD - Swimlane Social Hub
> **Version**: 2.0
> **Date**: 2026-02-16
> **Status**: UPDATED - Complete Design Specification
@ -19,356 +19,356 @@
### Phase 1-3: Not Started
- Planning complete, implementation pending Phase 0 completion
---
## Executive Summary
### Problem
BeadBoard has 4 fragmented pages with no shared navigation, no shared state, and inconsistent design language. The current Aero Chrome glass-morphism visual style has been rejected by users. Users want ONE cohesive experience for supervising multi-agent teams and managing tasks.
### Solution
Single unified shell at `/` with 4 switchable views (Social Feed, Swimlanes, Graph, Timeline), new earthy-dark design system, agent-prominent UX, and thoughtful interaction patterns throughout.
---
## Key Decisions (Immutable)
| # | Decision | Choice | Rationale |
|---|----------|--------|-----------|
| 1 | Routing | Single page + client tabs at / | Preserves selection state, panels never unmount |
| 2 | State Source | URL is Single Source of Truth | Prevents race conditions |
| 3 | Activity Feed | Context-aware (filters to selection) | Most useful for supervision workflow |
| 4 | Mobile | Hamburger left + slide-over right + bottom tabs | Standard pattern |
| 5 | Build Order | Tokens → Shell → Views (tracer bullet) | Real dependency chain |
| 6 | Card Interaction | Selection + detail strip below grid (desktop) | Grid stays uniform, split-view for conversation |
| 7 | Mobile Detail | Full-screen overlay (not split) | Keyboard takes 40% of screen |
| 8 | Visual Style | Earthy-dark design system (NOT Aero Chrome) | User provided full token spec |
| 9 | Agent Presence | Prominent - agents are the star | Avatars on every card, role-colored borders |
| 10 | Left Panel | Minimal with counts, nested epic tree | Status dots, hover tooltips |
| 11 | Card View-Jump | Small icons at card bottom | Jump to views with task pre-selected |
| 12 | Units | rem-based | Accessibility |
---
## Design Token Specification
### Color Palette
**Backgrounds:**
```css
--color-bg-base: #2D2D2D /* primary background */
--color-bg-card: #363636 /* cards, elevated surfaces */
--color-bg-input: #404040 /* inputs, hover states */
```
**Accents:**
```css
--color-accent-green: #7CB97A /* primary CTA, success, in-progress */
--color-accent-amber: #D4A574 /* warning, blocked */
--color-accent-teal: #5BA8A0 /* secondary, open/ready */
```
**Text:**
```css
--color-text-primary: #FFFFFF
--color-text-secondary: #B8B8B8
--color-text-muted: #888888
--color-text-on-primary: #1A1A1A
```
**Borders:**
```css
--color-border-default: #4A4A4A
--color-border-subtle: #3A3A3A
```
**Status Mapping:**
- open/ready → teal `#5BA8A0`
- in_progress → green `#7CB97A`
- blocked → amber `#D4A574`
- closed → muted `#888888`
**Agent Role Colors:**
- ui → `#6B9BD2` (steel blue)
- graph → `#7CB97A` (green)
- orchestrator → `#B08ED6` (soft purple)
- agent → `#B8B8B8` (neutral)
- researcher → `#D4A574` (amber)
**Liveness Colors:**
- active → `#7CB97A` (green, pulsing)
- stale → `#D4A574` (amber)
- evicted → `#C97A7A` (muted rose)
- idle → `#888888` (muted)
### Radii
```css
--radius-sm: 0.375rem /* 6px */
--radius-card: 0.625rem /* 10px */
--radius-modal: 1rem /* 16px */
--radius-pill: 9999px
```
### Shadows
```css
--shadow-sm: 0 1px 2px rgba(0,0,0,0.1)
--shadow-md: 0 4px 12px rgba(0,0,0,0.15)
```
### Typography
- Font: system sans-serif (Inter if available)
- H1: 2rem/700, H2: 1.5rem/600, H3: 1.125rem/600
- Body: 0.875rem/400, Small: 0.75rem/400, Tiny: 0.6875rem/500
- Line-height: headings 1.2, body 1.5
### Spacing
- Base: 0.25rem (4px)
- Card padding: 1rem-1.25rem
- Gaps: 1rem
- Section gaps: 2rem-2.5rem
### Icons & Transitions
- Icons: Lucide React, 1.5-2px stroke, 1rem-1.5rem size
- Transitions: 150-200ms ease-out for all hover/focus
---
## Component Anatomy
### Social Feed Card
```
┌─────────────────────────────────────┐
│ [⊕] (top-R)│ expand icon
│ │
│ bb-buff.1.1 │ task ID (tiny, teal)
│ Fix login bug on mobile │ title (bold, white)
│ │
│ UNLOCKS: │ blocked-by (ROSE tint)
│ ● #123 Blocker task │
│ │
│ BLOCKS: │ downstream (AMBER tint)
│ ● #234 Dependent task │
│ │
│ "Found the issue in the auth..." │ latest message (muted)
│ │
│ [●a-1] [●a-2] │ agent avatars (PROMINENT)
│ [≡] [◊] [≋]│ view-jump icons
└─────────────────────────────────────┘
```
**Card Specs:**
- Background: `#363636`
- Border: 1px status-colored (teal/green/amber/muted)
- Border-radius: 10px
- Status dot on card matches status mapping
- Agent avatars have **role-colored left border**
- Blocks/unlocks have tinted backgrounds (rose #E57373/10%, amber #D4A574/10%)
**Blocks/Unlocks Pattern (reuse from task-card-grid.tsx):**
```tsx
// Container
rounded-lg p-2 border border-white/5
// "Unlocks" header (rose tint)
text-[9px] font-bold uppercase tracking-widest text-rose-400/80
bg-rose-500/10 // background tint
// "Blocks" header (amber tint)
text-[9px] font-bold uppercase tracking-widest text-amber-400/80
bg-amber-500/10 // background tint
// Individual item
rounded border border-white/5 bg-white/5 px-2.5 py-2
hover:border-sky-400/30 hover:bg-white/10 transition-colors
```
### ZFC Agent State Visuals
| State | Visual |
|-------|--------|
| idle | `#888888` static dot |
| spawning | `#5BA8A0` pulsing dot |
| running | `#7CB97A` animated dot |
| working | `#7CB97A` pulsing glow |
| stuck | `#D4A574` attention dot (needs help!) |
| done | `#7CB97A` check |
| stopped | `#888888` no animation |
| dead | `#C97A7A` warning |
### Agent Card (Right Panel)
```
┌──────────────────────┐
│ [●avatar] agent-1 │ role-colored left border
│ role: ui │ role label
│ ● working · 2m ago │ ZFC state dot + age
│ Task: buff.1.1 │ current task
│ [≡] [◊] [≋] [💬] │ view-jump + message
└──────────────────────┘
```
### Swimlane Header
- Swarm name + computed counts: "3/8 done · 2 active · 1 ready · 1 blocked"
- Agent roster with ZFC state labels
- Collapsible
---
## Layout Architecture
### Shell Structure (CSS Grid)
```
┌──────────────────────────────────────────────────────────────────┐
│ TOP BAR (fixed, 3rem) │
│ ≡ [Swimlanes|Graph|Timeline|Social] ◢ │
├──────────┬──────────────────────────────────┬────────────────────┤
│ LEFT │ MIDDLE │ RIGHT │
│ 13.75rem │ flex-1 │ 17.5rem │
│ │ │ │
│ Channel │ View content (swaps on tab) │ Agents (~40%) │
│ tree │ │ ────────────────── │
│ │ │ Activity (~60%) │
└──────────┴──────────────────────────────────┴────────────────────┘
```
**Grid:** `grid-template-columns: 13.75rem 1fr 17.5rem`
### Detail Strip Behavior
**Desktop (≥1024px):**
- Grid splits: cards (~45%) | detail strip (~55%)
- Strip slides in below grid when card selected
- Cards remain visible above
**Mobile (<768px):**
- Full-screen overlay (z-index above bottom tabs)
- Required: virtual keyboard takes 40% of screen
- Split view would leave 0px for conversation
### Responsive Behavior
| Size | Left | Middle | Right | Detail Strip |
|------|------|--------|-------|--------------|
| Desktop (≥1024px) | 13.75rem fixed | flex-1 | 17.5rem fixed | Below grid |
| Tablet (768-1024px) | Overlay | flex-1 | Overlay | Slide-over |
| Mobile (<768px) | Overlay | flex-1 | Hidden | Full-screen |
---
## Anti-Patterns (Forbidden)
- NO glass-morphism / backdrop-blur effects
- NO arbitrary Tailwind color values (use tokens)
- NO agent-unaware cards (every card shows agents)
- NO page-per-view routing (use client tabs)
- NO localStorage for view state (use URL)
- NO direct JSONL writes (use bd CLI)
---
## Recommended Bead Structure
### Phase 0: Design Foundation
**Goal:** Tokens + Primitives only. No views.
**bb-ui2.1a** - Token System Update
- Update tokens.css with complete spec above
- Ensure all status/liveness/role colors defined
- Migrate away from Aero Chrome gradients
**bb-ui2.2a** - Card Primitive with Blocks/Unlocks
- Build reusable Card component
- Implement blocks/unlocks section pattern (reuse task-card-grid.tsx logic)
- Status-colored borders
- Soft gradient backgrounds (amber/teal tints, not harsh Aero Chrome)
**bb-ui2.3a** - Agent Avatar Primitive
- Avatar with role-colored ring
- ZFC state indicator (dot/pulse/glow)
- Size variants (sm, md, lg)
**bb-ui2.4a** - Status Utilities Update
- Rewrite status-utils.tsx for new tokens
- Status badge component with pill + dot
- Liveness indicator component
### Phase 1: Layout Polish
**Goal:** Fix current layout issues, preserve structure
**bb-ui2.22** - Detail Strip Positioning Fix
- Move from side drawer to below-grid (desktop)
- Full-screen overlay (mobile)
- Preserve URL state behavior
- Thread content actually shows selected bead data
**bb-ui2.23** - Activity Panel Polish
- Split right panel: Agents (40%) + Activity (60%)
- Agent cards with ZFC states
- Context-aware activity filtering
**bb-ui2.24** - Mobile Responsive Polish
- Bottom tab bar
- Panel overlays
- Touch-friendly targets
### Phase 2: Card Design Implementation
**Goal:** Implement complete card anatomy
**bb-ui2.25** - Social Feed Card Redesign
- Full card anatomy from spec
- Blocks/unlocks with rose/amber tints
- Prominent agent avatars
- View-jump icons
- Expand icon → full-page popup
**bb-ui2.26** - Swimlane Card Redesign
- Agent-first layout
- ZFC state prominent
- Status-colored border
- Drag-drop preserved
**bb-ui2.27** - Graph Node Redesign
- New design tokens
- Agent avatars on nodes
- Selection syncs with store
### Phase 3: Cross-Cutting Polish
**Goal:** Deep links, mobile, final gates
**bb-ui2.28** - Deep Link Verification
- All URL patterns work
- Browser back/forward
- Shareable URLs
**bb-ui2.29** - Screenshot Evidence
- All breakpoints
- All views
- Mobile + desktop
**bb-ui2.30** - Final Gates
- typecheck, lint, test
- Close epic
---
## Verification Strategy
After each bead:
```bash
npm run typecheck
npm run lint
npm run test
```
Visual verification:
- Screenshots at 390px, 768px, 1440px
- Compare against design spec
- Agent avatars visible on all cards
- Blocks/unlocks sections tinted correctly
---
*End of PRD v2.0 - Ready for Implementation*
---
## Executive Summary
### Problem
BeadBoard has 4 fragmented pages with no shared navigation, no shared state, and inconsistent design language. The current Aero Chrome glass-morphism visual style has been rejected by users. Users want ONE cohesive experience for supervising multi-agent teams and managing tasks.
### Solution
Single unified shell at `/` with 4 switchable views (Social Feed, Swimlanes, Graph, Timeline), new earthy-dark design system, agent-prominent UX, and thoughtful interaction patterns throughout.
---
## Key Decisions (Immutable)
| # | Decision | Choice | Rationale |
|---|----------|--------|-----------|
| 1 | Routing | Single page + client tabs at / | Preserves selection state, panels never unmount |
| 2 | State Source | URL is Single Source of Truth | Prevents race conditions |
| 3 | Activity Feed | Context-aware (filters to selection) | Most useful for supervision workflow |
| 4 | Mobile | Hamburger left + slide-over right + bottom tabs | Standard pattern |
| 5 | Build Order | Tokens → Shell → Views (tracer bullet) | Real dependency chain |
| 6 | Card Interaction | Selection + detail strip below grid (desktop) | Grid stays uniform, split-view for conversation |
| 7 | Mobile Detail | Full-screen overlay (not split) | Keyboard takes 40% of screen |
| 8 | Visual Style | Earthy-dark design system (NOT Aero Chrome) | User provided full token spec |
| 9 | Agent Presence | Prominent - agents are the star | Avatars on every card, role-colored borders |
| 10 | Left Panel | Minimal with counts, nested epic tree | Status dots, hover tooltips |
| 11 | Card View-Jump | Small icons at card bottom | Jump to views with task pre-selected |
| 12 | Units | rem-based | Accessibility |
---
## Design Token Specification
### Color Palette
**Backgrounds:**
```css
--color-bg-base: #2D2D2D /* primary background */
--color-bg-card: #363636 /* cards, elevated surfaces */
--color-bg-input: #404040 /* inputs, hover states */
```
**Accents:**
```css
--color-accent-green: #7CB97A /* primary CTA, success, in-progress */
--color-accent-amber: #D4A574 /* warning, blocked */
--color-accent-teal: #5BA8A0 /* secondary, open/ready */
```
**Text:**
```css
--color-text-primary: #FFFFFF
--color-text-secondary: #B8B8B8
--color-text-muted: #888888
--color-text-on-primary: #1A1A1A
```
**Borders:**
```css
--color-border-default: #4A4A4A
--color-border-subtle: #3A3A3A
```
**Status Mapping:**
- open/ready → teal `#5BA8A0`
- in_progress → green `#7CB97A`
- blocked → amber `#D4A574`
- closed → muted `#888888`
**Agent Role Colors:**
- ui → `#6B9BD2` (steel blue)
- graph → `#7CB97A` (green)
- orchestrator → `#B08ED6` (soft purple)
- agent → `#B8B8B8` (neutral)
- researcher → `#D4A574` (amber)
**Liveness Colors:**
- active → `#7CB97A` (green, pulsing)
- stale → `#D4A574` (amber)
- evicted → `#C97A7A` (muted rose)
- idle → `#888888` (muted)
### Radii
```css
--radius-sm: 0.375rem /* 6px */
--radius-card: 0.625rem /* 10px */
--radius-modal: 1rem /* 16px */
--radius-pill: 9999px
```
### Shadows
```css
--shadow-sm: 0 1px 2px rgba(0,0,0,0.1)
--shadow-md: 0 4px 12px rgba(0,0,0,0.15)
```
### Typography
- Font: system sans-serif (Inter if available)
- H1: 2rem/700, H2: 1.5rem/600, H3: 1.125rem/600
- Body: 0.875rem/400, Small: 0.75rem/400, Tiny: 0.6875rem/500
- Line-height: headings 1.2, body 1.5
### Spacing
- Base: 0.25rem (4px)
- Card padding: 1rem-1.25rem
- Gaps: 1rem
- Section gaps: 2rem-2.5rem
### Icons & Transitions
- Icons: Lucide React, 1.5-2px stroke, 1rem-1.5rem size
- Transitions: 150-200ms ease-out for all hover/focus
---
## Component Anatomy
### Social Feed Card
```
┌─────────────────────────────────────┐
│ [⊕] (top-R)│ expand icon
│ │
│ bb-buff.1.1 │ task ID (tiny, teal)
│ Fix login bug on mobile │ title (bold, white)
│ │
│ UNLOCKS: │ blocked-by (ROSE tint)
│ ● #123 Blocker task │
│ │
│ BLOCKS: │ downstream (AMBER tint)
│ ● #234 Dependent task │
│ │
│ "Found the issue in the auth..." │ latest message (muted)
│ │
│ [●a-1] [●a-2] │ agent avatars (PROMINENT)
│ [≡] [◊] [≋]│ view-jump icons
└─────────────────────────────────────┘
```
**Card Specs:**
- Background: `#363636`
- Border: 1px status-colored (teal/green/amber/muted)
- Border-radius: 10px
- Status dot on card matches status mapping
- Agent avatars have **role-colored left border**
- Blocks/unlocks have tinted backgrounds (rose #E57373/10%, amber #D4A574/10%)
**Blocks/Unlocks Pattern (reuse from task-card-grid.tsx):**
```tsx
// Container
rounded-lg p-2 border border-white/5
// "Unlocks" header (rose tint)
text-[9px] font-bold uppercase tracking-widest text-rose-400/80
bg-rose-500/10 // background tint
// "Blocks" header (amber tint)
text-[9px] font-bold uppercase tracking-widest text-amber-400/80
bg-amber-500/10 // background tint
// Individual item
rounded border border-white/5 bg-white/5 px-2.5 py-2
hover:border-sky-400/30 hover:bg-white/10 transition-colors
```
### ZFC Agent State Visuals
| State | Visual |
|-------|--------|
| idle | `#888888` static dot |
| spawning | `#5BA8A0` pulsing dot |
| running | `#7CB97A` animated dot |
| working | `#7CB97A` pulsing glow |
| stuck | `#D4A574` attention dot (needs help!) |
| done | `#7CB97A` check |
| stopped | `#888888` no animation |
| dead | `#C97A7A` warning |
### Agent Card (Right Panel)
```
┌──────────────────────┐
│ [●avatar] agent-1 │ role-colored left border
│ role: ui │ role label
│ ● working · 2m ago │ ZFC state dot + age
│ Task: buff.1.1 │ current task
│ [≡] [◊] [≋] [💬] │ view-jump + message
└──────────────────────┘
```
### Swimlane Header
- Swarm name + computed counts: "3/8 done · 2 active · 1 ready · 1 blocked"
- Agent roster with ZFC state labels
- Collapsible
---
## Layout Architecture
### Shell Structure (CSS Grid)
```
┌──────────────────────────────────────────────────────────────────┐
│ TOP BAR (fixed, 3rem) │
│ ≡ [Swimlanes|Graph|Timeline|Social] ◢ │
├──────────┬──────────────────────────────────┬────────────────────┤
│ LEFT │ MIDDLE │ RIGHT │
│ 13.75rem │ flex-1 │ 17.5rem │
│ │ │ │
│ Channel │ View content (swaps on tab) │ Agents (~40%) │
│ tree │ │ ────────────────── │
│ │ │ Activity (~60%) │
└──────────┴──────────────────────────────────┴────────────────────┘
```
**Grid:** `grid-template-columns: 13.75rem 1fr 17.5rem`
### Detail Strip Behavior
**Desktop (≥1024px):**
- Grid splits: cards (~45%) | detail strip (~55%)
- Strip slides in below grid when card selected
- Cards remain visible above
**Mobile (<768px):**
- Full-screen overlay (z-index above bottom tabs)
- Required: virtual keyboard takes 40% of screen
- Split view would leave 0px for conversation
### Responsive Behavior
| Size | Left | Middle | Right | Detail Strip |
|------|------|--------|-------|--------------|
| Desktop (≥1024px) | 13.75rem fixed | flex-1 | 17.5rem fixed | Below grid |
| Tablet (768-1024px) | Overlay | flex-1 | Overlay | Slide-over |
| Mobile (<768px) | Overlay | flex-1 | Hidden | Full-screen |
---
## Anti-Patterns (Forbidden)
- NO glass-morphism / backdrop-blur effects
- NO arbitrary Tailwind color values (use tokens)
- NO agent-unaware cards (every card shows agents)
- NO page-per-view routing (use client tabs)
- NO localStorage for view state (use URL)
- NO direct JSONL writes (use bd CLI)
---
## Recommended Bead Structure
### Phase 0: Design Foundation
**Goal:** Tokens + Primitives only. No views.
**bb-ui2.1a** - Token System Update
- Update tokens.css with complete spec above
- Ensure all status/liveness/role colors defined
- Migrate away from Aero Chrome gradients
**bb-ui2.2a** - Card Primitive with Blocks/Unlocks
- Build reusable Card component
- Implement blocks/unlocks section pattern (reuse task-card-grid.tsx logic)
- Status-colored borders
- Soft gradient backgrounds (amber/teal tints, not harsh Aero Chrome)
**bb-ui2.3a** - Agent Avatar Primitive
- Avatar with role-colored ring
- ZFC state indicator (dot/pulse/glow)
- Size variants (sm, md, lg)
**bb-ui2.4a** - Status Utilities Update
- Rewrite status-utils.tsx for new tokens
- Status badge component with pill + dot
- Liveness indicator component
### Phase 1: Layout Polish
**Goal:** Fix current layout issues, preserve structure
**bb-ui2.22** - Detail Strip Positioning Fix
- Move from side drawer to below-grid (desktop)
- Full-screen overlay (mobile)
- Preserve URL state behavior
- Thread content actually shows selected bead data
**bb-ui2.23** - Activity Panel Polish
- Split right panel: Agents (40%) + Activity (60%)
- Agent cards with ZFC states
- Context-aware activity filtering
**bb-ui2.24** - Mobile Responsive Polish
- Bottom tab bar
- Panel overlays
- Touch-friendly targets
### Phase 2: Card Design Implementation
**Goal:** Implement complete card anatomy
**bb-ui2.25** - Social Feed Card Redesign
- Full card anatomy from spec
- Blocks/unlocks with rose/amber tints
- Prominent agent avatars
- View-jump icons
- Expand icon → full-page popup
**bb-ui2.26** - Swimlane Card Redesign
- Agent-first layout
- ZFC state prominent
- Status-colored border
- Drag-drop preserved
**bb-ui2.27** - Graph Node Redesign
- New design tokens
- Agent avatars on nodes
- Selection syncs with store
### Phase 3: Cross-Cutting Polish
**Goal:** Deep links, mobile, final gates
**bb-ui2.28** - Deep Link Verification
- All URL patterns work
- Browser back/forward
- Shareable URLs
**bb-ui2.29** - Screenshot Evidence
- All breakpoints
- All views
- Mobile + desktop
**bb-ui2.30** - Final Gates
- typecheck, lint, test
- Close epic
---
## Verification Strategy
After each bead:
```bash
npm run typecheck
npm run lint
npm run test
```
Visual verification:
- Screenshots at 390px, 768px, 1440px
- Compare against design spec
- Agent avatars visible on all cards
- Blocks/unlocks sections tinted correctly
---
*End of PRD v2.0 - Ready for Implementation*

View file

@ -1,171 +1,171 @@
# Swarm View Remake - Product Requirements Document (PRD)
## Overview
The goal is to completely remake the Beadboard "Swarm" view (`/view=swarm`) into a powerful, command-center style workspace. The current flat grid of mission cards will be replaced with a deep, context-aware interface that integrates with the Gastown/Beads orchestration model, introducing the concepts of Agent Archetypes and Swarm Templates.
This document serves as the comprehensive technical specification for implementation.
---
## 1. Core Concepts & Data Models
### 1.1 Agent Archetypes
Archetypes define specialized roles that worker agents (Polecats) can adopt.
* **Storage Path:** `.beads/archetypes/*.json` (Git-tracked alongside the project).
* **Seeding:** The application must check for the existence of this directory on startup (or via a specific API route). If empty, it must create the directory and write default archetypes (e.g., `architect.json`, `reviewer.json`, `implementer.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface AgentArchetype {
id: string; // The filename without .json (e.g., 'architect')
name: string; // Display name (e.g., 'Software Architect')
description: string;
systemPrompt: string; // The core behavioral instructions
capabilities: string[]; // e.g., ['planning', 'code_review']
color: string; // e.g., 'primary', 'destructive', 'warn', etc.
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
isBuiltIn: boolean; // True if seeded by default, false if user-created
}
```
### 1.2 Swarm Templates
Templates define mission blueprints—a preset team composition and standard workflow.
* **Storage Path:** `.beads/templates/*.json`.
* **Seeding:** Similar to archetypes, provide robust defaults (e.g., `feature-sprint.json`, `bug-blitz.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface SwarmTemplate {
id: string; // The filename without .json
name: string; // Display name
description: string;
team: {
archetypeId: string; // Must match an AgentArchetype.id
count: number;
}[];
protoFormula?: string; // Optional: Maps to a `bd` formula name (e.g., 'release')
createdAt: string;
updatedAt: string;
isBuiltIn: boolean;
}
```
---
## 2. API Contracts & Backend Architecture
The UI needs a robust Next.js API layer to manage these new files and interface with the CLI. All routes should be under `src/app/api/swarm/`.
### 2.1 Archetypes API (`/api/swarm/archetypes`)
* **GET:** Returns `AgentArchetype[]`. Reads all `.json` files from `.beads/archetypes/`.
* **POST:** Creates a new archetype. Validates payload, writes to `.beads/archetypes/{id}.json`.
* **PUT /:id:** Updates an existing archetype.
* **DELETE /:id:** Deletes an archetype (prevent deletion if `isBuiltIn` is true).
### 2.2 Templates API (`/api/swarm/templates`)
* **GET:** Returns `SwarmTemplate[]`. Reads from `.beads/templates/`.
* **POST, PUT, DELETE:** Standard CRUD mirroring Archetypes.
### 2.3 Orchestration API (`/api/swarm/orchestration`)
* **POST `/launch`:**
* **Payload:** `{ templateId: string, missionName: string, projectRoot: string }`
* **Action:** Reads the template. If `protoFormula` exists, executes `bd mol pour <protoFormula> --title <missionName>`. If no formula, executes `bd create epic <missionName>`. Then executes `gt sling` or equivalent to assign the specific roster to the new Epic.
* **Response:** The new Epic ID to immediately select in the UI.
---
## 3. Frontend Architecture & Component Structure
The current `src/components/swarm/swarm-page.tsx` will be completely replaced. The new architecture pushes state down into specialized components.
### 3.1 Shell Integration (`src/components/shared/unified-shell.tsx`)
The `UnifiedShell` must dynamically alter its layout based on the active view.
* **When `view === 'swarm'`:**
* **Left Panel:** Do NOT render the standard Epic Tree. Render `<SwarmMissionPicker />`.
* **Middle Column:** Render `<SwarmWorkspace />`.
* **Right Panel:** Remain as the `<ActivityPanel />` (Agent pool monitor).
### 3.2 The Swarm Workspace (`src/components/swarm/swarm-workspace.tsx`)
The main container for the middle column. Manages the active sub-tab state.
```tsx
// State: activeTab: 'operations' | 'archetypes' | 'templates'
<div className="swarm-workspace">
<SwarmWorkspaceNav activeTab={activeTab} onTabChange={setTab} />
{activeTab === 'operations' && <SwarmOperationsmissionId={selectedMissionId} />}
{activeTab === 'archetypes' && <ArchetypesArmory />}
{activeTab === 'templates' && <TemplatesManager />}
</div>
```
---
## 4. UI/UX Details by Sub-Tab
### 4.1 Left Panel: `<SwarmMissionPicker />`
A dense, scannable list replacing the left panel.
* Fetches epics (like the current `useMissionList` hook).
* **Row Design:**
* `[Health Dot] [Mission Title] (ID)`
* A micro-progress bar underneath the title.
* **Interaction:** Clicking sets the `swarmId` URL param and automatically switches the `SwarmWorkspace` to the 'operations' tab.
### 4.2 Tab 1: `<SwarmOperations />` (The Operations Command Center)
This view only renders if a mission (Epic) is selected. It completely replaces the redundant Graph view with a focused, control-oriented dashboard for agent orchestration.
* **Header Section:**
* Mission Title, Epic ID, and overall health status.
* **Action Strip:** Buttons for "Summon Polecats" (assign agents based on a template), "Halt Swarm", and "Run Debrief".
* **Convoy Stepper:** The visual orchestration pipeline (Planning -> Deployment -> Execution -> Debrief).
* **The Telemetry Grid (Hybrid Layout):**
* **Top/Left Pane (Specialized Agent DAG):** Unlike the generic global graph, this graph specifically visualizes *who* is doing *what*. Nodes should emphasize Agent Avatars and archetype colors. Edges should represent the flow of work between agents (e.g., Coder -> Reviewer) rather than just raw task dependencies.
* **Bottom/Right Pane (Metrics & Attention):**
* **Priority Attention (What is blocked?):** A highly focused feed of *only* the `blocked` beads or beads that require Human-In-The-Loop (HITL) intervention for this specific mission.
* **Mission Roster:** A quick summary of active agents.
### 4.3 Tab 2: `<ArchetypesArmory />`
* **Layout:** CSS Grid of archetype cards.
* **Card Design:** Shows Name, Color badge, Capabilities tags, and truncated description.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central popup (reusing the app's existing Dialog/Popup pattern) to edit the metadata.
* Includes a focused text area to edit the raw `systemPrompt`.
* A primary "Create New Archetype" button exists at the top.
### 4.4 Tab 3: `<TemplatesManager />`
* **Layout:** List or Grid view of templates.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central `<TemplateEditor />` popup.
* **Key UI Feature:** An intuitive interface to build the `team` array (e.g., click "Add Role", select "Architect" from the Archetypes list, set count to "1").
* A primary "Create New Template" button exists at the top.
---
## 5. Engine Integration & Visual Hooks
Raw terminal panes are rejected. Orchestration must feel native to the React application.
### 5.1 The Convoy Stepper (`<ConvoyOrchestrationStepper />`)
When `<LaunchSwarmDialog />` is submitted, a prominent overlay or banner appears in the Operations view:
* **Phase 1: Planning.** (Spinning) -> API calls `bd mol pour` -> (Check)
* **Phase 2: Graph Generation.** (Spinning) -> UI polls API for new beads -> (Check)
* **Phase 3: Deployment.** (Spinning) -> API calls `gt sling` -> (Check)
* The stepper fades out after 3 seconds of full completion, revealing the live DAG.
### 5.2 Responsive Graph Expansion
The Graph view in the Operations tab must smoothly handle rapid influxes of nodes (which happens when a template is poured). The physics simulation (if applicable) or layout engine should be robust enough to handle ~20-50 nodes appearing simultaneously without throwing errors or causing heavy layout thrashing.
---
## 6. Implementation Phasing Strategy
To avoid massive, monolithic PRs, implementation should follow this order:
1. **Phase 1: Data Layer & API.** Implement `src/lib/types-swarm.ts`, the seed logic, and the CRUD API routes for Archetypes and Templates.
2. **Phase 2: Shell Routing & Sub-tabs.** Update `UnifiedShell` to intercept the Swarm view, implement the `SwarmMissionPicker` for the left panel, and scaffold the empty 3 sub-tabs.
3. **Phase 3: Armory & Templates UI.** Build out the CRUD interfaces for Archetypes and Templates.
4. **Phase 4: The Operations Dashboard.** Build the complex detail view, integrating the existing graph components and agent roster.
5. **Phase 5: Orchestration (The glue).** Hook up the "Launch" button to the new templates, implement the `ConvoyStepper`, and wire the API to `bd` and `gt`.
# Swarm View Remake - Product Requirements Document (PRD)
## Overview
The goal is to completely remake the Beadboard "Swarm" view (`/view=swarm`) into a powerful, command-center style workspace. The current flat grid of mission cards will be replaced with a deep, context-aware interface that integrates with the Gastown/Beads orchestration model, introducing the concepts of Agent Archetypes and Swarm Templates.
This document serves as the comprehensive technical specification for implementation.
---
## 1. Core Concepts & Data Models
### 1.1 Agent Archetypes
Archetypes define specialized roles that worker agents (Polecats) can adopt.
* **Storage Path:** `.beads/archetypes/*.json` (Git-tracked alongside the project).
* **Seeding:** The application must check for the existence of this directory on startup (or via a specific API route). If empty, it must create the directory and write default archetypes (e.g., `architect.json`, `reviewer.json`, `implementer.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface AgentArchetype {
id: string; // The filename without .json (e.g., 'architect')
name: string; // Display name (e.g., 'Software Architect')
description: string;
systemPrompt: string; // The core behavioral instructions
capabilities: string[]; // e.g., ['planning', 'code_review']
color: string; // e.g., 'primary', 'destructive', 'warn', etc.
createdAt: string; // ISO timestamp
updatedAt: string; // ISO timestamp
isBuiltIn: boolean; // True if seeded by default, false if user-created
}
```
### 1.2 Swarm Templates
Templates define mission blueprints—a preset team composition and standard workflow.
* **Storage Path:** `.beads/templates/*.json`.
* **Seeding:** Similar to archetypes, provide robust defaults (e.g., `feature-sprint.json`, `bug-blitz.json`).
* **Data Interface (`src/lib/types-swarm.ts`):**
```typescript
export interface SwarmTemplate {
id: string; // The filename without .json
name: string; // Display name
description: string;
team: {
archetypeId: string; // Must match an AgentArchetype.id
count: number;
}[];
protoFormula?: string; // Optional: Maps to a `bd` formula name (e.g., 'release')
createdAt: string;
updatedAt: string;
isBuiltIn: boolean;
}
```
---
## 2. API Contracts & Backend Architecture
The UI needs a robust Next.js API layer to manage these new files and interface with the CLI. All routes should be under `src/app/api/swarm/`.
### 2.1 Archetypes API (`/api/swarm/archetypes`)
* **GET:** Returns `AgentArchetype[]`. Reads all `.json` files from `.beads/archetypes/`.
* **POST:** Creates a new archetype. Validates payload, writes to `.beads/archetypes/{id}.json`.
* **PUT /:id:** Updates an existing archetype.
* **DELETE /:id:** Deletes an archetype (prevent deletion if `isBuiltIn` is true).
### 2.2 Templates API (`/api/swarm/templates`)
* **GET:** Returns `SwarmTemplate[]`. Reads from `.beads/templates/`.
* **POST, PUT, DELETE:** Standard CRUD mirroring Archetypes.
### 2.3 Orchestration API (`/api/swarm/orchestration`)
* **POST `/launch`:**
* **Payload:** `{ templateId: string, missionName: string, projectRoot: string }`
* **Action:** Reads the template. If `protoFormula` exists, executes `bd mol pour <protoFormula> --title <missionName>`. If no formula, executes `bd create epic <missionName>`. Then executes `gt sling` or equivalent to assign the specific roster to the new Epic.
* **Response:** The new Epic ID to immediately select in the UI.
---
## 3. Frontend Architecture & Component Structure
The current `src/components/swarm/swarm-page.tsx` will be completely replaced. The new architecture pushes state down into specialized components.
### 3.1 Shell Integration (`src/components/shared/unified-shell.tsx`)
The `UnifiedShell` must dynamically alter its layout based on the active view.
* **When `view === 'swarm'`:**
* **Left Panel:** Do NOT render the standard Epic Tree. Render `<SwarmMissionPicker />`.
* **Middle Column:** Render `<SwarmWorkspace />`.
* **Right Panel:** Remain as the `<ActivityPanel />` (Agent pool monitor).
### 3.2 The Swarm Workspace (`src/components/swarm/swarm-workspace.tsx`)
The main container for the middle column. Manages the active sub-tab state.
```tsx
// State: activeTab: 'operations' | 'archetypes' | 'templates'
<div className="swarm-workspace">
<SwarmWorkspaceNav activeTab={activeTab} onTabChange={setTab} />
{activeTab === 'operations' && <SwarmOperationsmissionId={selectedMissionId} />}
{activeTab === 'archetypes' && <ArchetypesArmory />}
{activeTab === 'templates' && <TemplatesManager />}
</div>
```
---
## 4. UI/UX Details by Sub-Tab
### 4.1 Left Panel: `<SwarmMissionPicker />`
A dense, scannable list replacing the left panel.
* Fetches epics (like the current `useMissionList` hook).
* **Row Design:**
* `[Health Dot] [Mission Title] (ID)`
* A micro-progress bar underneath the title.
* **Interaction:** Clicking sets the `swarmId` URL param and automatically switches the `SwarmWorkspace` to the 'operations' tab.
### 4.2 Tab 1: `<SwarmOperations />` (The Operations Command Center)
This view only renders if a mission (Epic) is selected. It completely replaces the redundant Graph view with a focused, control-oriented dashboard for agent orchestration.
* **Header Section:**
* Mission Title, Epic ID, and overall health status.
* **Action Strip:** Buttons for "Summon Polecats" (assign agents based on a template), "Halt Swarm", and "Run Debrief".
* **Convoy Stepper:** The visual orchestration pipeline (Planning -> Deployment -> Execution -> Debrief).
* **The Telemetry Grid (Hybrid Layout):**
* **Top/Left Pane (Specialized Agent DAG):** Unlike the generic global graph, this graph specifically visualizes *who* is doing *what*. Nodes should emphasize Agent Avatars and archetype colors. Edges should represent the flow of work between agents (e.g., Coder -> Reviewer) rather than just raw task dependencies.
* **Bottom/Right Pane (Metrics & Attention):**
* **Priority Attention (What is blocked?):** A highly focused feed of *only* the `blocked` beads or beads that require Human-In-The-Loop (HITL) intervention for this specific mission.
* **Mission Roster:** A quick summary of active agents.
### 4.3 Tab 2: `<ArchetypesArmory />`
* **Layout:** CSS Grid of archetype cards.
* **Card Design:** Shows Name, Color badge, Capabilities tags, and truncated description.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central popup (reusing the app's existing Dialog/Popup pattern) to edit the metadata.
* Includes a focused text area to edit the raw `systemPrompt`.
* A primary "Create New Archetype" button exists at the top.
### 4.4 Tab 3: `<TemplatesManager />`
* **Layout:** List or Grid view of templates.
* **Interaction:**
* Cards are highly interactive. Clicking a card opens a central `<TemplateEditor />` popup.
* **Key UI Feature:** An intuitive interface to build the `team` array (e.g., click "Add Role", select "Architect" from the Archetypes list, set count to "1").
* A primary "Create New Template" button exists at the top.
---
## 5. Engine Integration & Visual Hooks
Raw terminal panes are rejected. Orchestration must feel native to the React application.
### 5.1 The Convoy Stepper (`<ConvoyOrchestrationStepper />`)
When `<LaunchSwarmDialog />` is submitted, a prominent overlay or banner appears in the Operations view:
* **Phase 1: Planning.** (Spinning) -> API calls `bd mol pour` -> (Check)
* **Phase 2: Graph Generation.** (Spinning) -> UI polls API for new beads -> (Check)
* **Phase 3: Deployment.** (Spinning) -> API calls `gt sling` -> (Check)
* The stepper fades out after 3 seconds of full completion, revealing the live DAG.
### 5.2 Responsive Graph Expansion
The Graph view in the Operations tab must smoothly handle rapid influxes of nodes (which happens when a template is poured). The physics simulation (if applicable) or layout engine should be robust enough to handle ~20-50 nodes appearing simultaneously without throwing errors or causing heavy layout thrashing.
---
## 6. Implementation Phasing Strategy
To avoid massive, monolithic PRs, implementation should follow this order:
1. **Phase 1: Data Layer & API.** Implement `src/lib/types-swarm.ts`, the seed logic, and the CRUD API routes for Archetypes and Templates.
2. **Phase 2: Shell Routing & Sub-tabs.** Update `UnifiedShell` to intercept the Swarm view, implement the `SwarmMissionPicker` for the left panel, and scaffold the empty 3 sub-tabs.
3. **Phase 3: Armory & Templates UI.** Build out the CRUD interfaces for Archetypes and Templates.
4. **Phase 4: The Operations Dashboard.** Build the complex detail view, integrating the existing graph components and agent roster.
5. **Phase 5: Orchestration (The glue).** Hook up the "Launch" button to the new templates, implement the `ConvoyStepper`, and wire the API to `bd` and `gt`.

View file

@ -1,49 +1,49 @@
# DAG Views & Command Center UX Overhaul
## The Problem
The current `/grid` and `/swarm` views are fragmented. The left sidebar changes shape and color depending on the mode, causing jarring context switches. The Swarm DAG needs animation enhancements, the Grid view needs clarity, and the Right Panel gets cut off and is filled with noisy, irrelevant data (e.g., dead agents from days ago).
## The Goal
Create a unified "Mission Control" experience designed specifically for a single Commander observing and managing AI agents. Eliminate context switching while separating the noise of real-time execution from the quiet of architectural planning.
## The Solution: Macro vs. Micro Architecture
Instead of arbitrary "Grid" and "Swarm" routing modes, we move to a **Depth-Based Context** model.
### 1. The Macro View (Planning / The Grid)
**Trigger:** Looking at the entire workspace or multiple epics.
- **The DAG:** Structural and quiet. Shows task dependencies and static statuses (Ready, Blocked, Done). No noisy agent animations or live data flows.
- **Left Panel:** The unified Task/Epic tree. Clean, consistent UI.
- **Right Panel (Global Events):** A high-level timeline of events (e.g., "Agent X completed Task Y", "Task Z is blocked"), essentially a git-log of the workspace.
### 2. The Micro View (Execution / The Swarm)
**Trigger:** Selecting a specific Epic or an active Task. The view zooms in to focus only on localized context.
- **The DAG:** Comes alive. You only see the tasks actively being worked on and their immediate neighbors. Nodes pulse to indicate agent activity, and edges show animated data-flow passing between tasks/agents.
- **Left Panel:** Remains the unified Task/Epic tree, but highlights the active epic and places "Active Agent" indicator badges next to tasks currently in progress.
- **Right Panel (The Command Feed):** Splits into a stacked or tabbed view optimized for live operations:
- **Active Squad Roster:** Only lists agents assigned to *this specific Epic context*. Dead agents from previous sessions are completely hidden. Shows current token usage and active task assignments.
- **Live Telemetry (The Swarm Activity Feed):** A highly readable streaming feed of what the agents are thinking and doing *right now* ("Agent X evaluating `lib/utils.ts`", "Agent Y blocked on API key"). This replaces the current messy telemetry grid into a focused, scrolling terminal-like feed on the right.
## Technical Execution Plan
### 1. Left Panel Unification
- Remove the `SwarmMissionPicker` override.
- Update `unified-shell.tsx` to always render `<LeftPanel />`.
- Enhance `<LeftPanel />` to display active agent indicators based on live telemetry data.
### 2. Right Panel Fixes & Contextual Rendering
- Fix the CSS grid width causing the Right Panel to be cut off (`rightPanelWidth` adjustments in `unified-shell.tsx`).
- Introduce `<ContextualRightPanel />` that reads the URL state (`epicId` / `taskId` vs `null`).
- Component swap:
- No Epic Selected -> `<GlobalActivityFeed />`
- Epic/Task Selected -> `<SwarmCommandFeed />` (Roster + Telemetry)
### 3. DAG Component Merging
- Merge `GraphView` and `SwarmWorkspace` core logic into a single `<SmartDag />` component.
- The `<SmartDag />` will read the `epicId` context to determine its zoom level and animation states.
- Introduce framer-motion (or existing animation libraries) for data flow and node pulsing.
### 4. Overhauling the Swarm Activity Feed & Roster
- **Contextual Agent Roster:** Instead of pulling all agents globally (like `ActivityPanel` currently does), we extract the active roster logic from `TelemetryGrid` to only show agents actively assigned to `in_progress` tasks within the currently selected `epicId`.
- **Streaming Telemetry Feed:** We reuse the `/api/events` SSE connection from `ActivityPanel`, but we filter the incoming events `beadId` to match the children of the current `epicId`. We format this feed as a terminal-like streaming log with concise, color-coded badges indicating what the agents are currently doing.
- **Cleanup the Graveyard:** Dead agents and old task logs will be entirely stripped from this contextual right panel, ensuring it remains a focused "Command Feed" of live operations.
# DAG Views & Command Center UX Overhaul
## The Problem
The current `/grid` and `/swarm` views are fragmented. The left sidebar changes shape and color depending on the mode, causing jarring context switches. The Swarm DAG needs animation enhancements, the Grid view needs clarity, and the Right Panel gets cut off and is filled with noisy, irrelevant data (e.g., dead agents from days ago).
## The Goal
Create a unified "Mission Control" experience designed specifically for a single Commander observing and managing AI agents. Eliminate context switching while separating the noise of real-time execution from the quiet of architectural planning.
## The Solution: Macro vs. Micro Architecture
Instead of arbitrary "Grid" and "Swarm" routing modes, we move to a **Depth-Based Context** model.
### 1. The Macro View (Planning / The Grid)
**Trigger:** Looking at the entire workspace or multiple epics.
- **The DAG:** Structural and quiet. Shows task dependencies and static statuses (Ready, Blocked, Done). No noisy agent animations or live data flows.
- **Left Panel:** The unified Task/Epic tree. Clean, consistent UI.
- **Right Panel (Global Events):** A high-level timeline of events (e.g., "Agent X completed Task Y", "Task Z is blocked"), essentially a git-log of the workspace.
### 2. The Micro View (Execution / The Swarm)
**Trigger:** Selecting a specific Epic or an active Task. The view zooms in to focus only on localized context.
- **The DAG:** Comes alive. You only see the tasks actively being worked on and their immediate neighbors. Nodes pulse to indicate agent activity, and edges show animated data-flow passing between tasks/agents.
- **Left Panel:** Remains the unified Task/Epic tree, but highlights the active epic and places "Active Agent" indicator badges next to tasks currently in progress.
- **Right Panel (The Command Feed):** Splits into a stacked or tabbed view optimized for live operations:
- **Active Squad Roster:** Only lists agents assigned to *this specific Epic context*. Dead agents from previous sessions are completely hidden. Shows current token usage and active task assignments.
- **Live Telemetry (The Swarm Activity Feed):** A highly readable streaming feed of what the agents are thinking and doing *right now* ("Agent X evaluating `lib/utils.ts`", "Agent Y blocked on API key"). This replaces the current messy telemetry grid into a focused, scrolling terminal-like feed on the right.
## Technical Execution Plan
### 1. Left Panel Unification
- Remove the `SwarmMissionPicker` override.
- Update `unified-shell.tsx` to always render `<LeftPanel />`.
- Enhance `<LeftPanel />` to display active agent indicators based on live telemetry data.
### 2. Right Panel Fixes & Contextual Rendering
- Fix the CSS grid width causing the Right Panel to be cut off (`rightPanelWidth` adjustments in `unified-shell.tsx`).
- Introduce `<ContextualRightPanel />` that reads the URL state (`epicId` / `taskId` vs `null`).
- Component swap:
- No Epic Selected -> `<GlobalActivityFeed />`
- Epic/Task Selected -> `<SwarmCommandFeed />` (Roster + Telemetry)
### 3. DAG Component Merging
- Merge `GraphView` and `SwarmWorkspace` core logic into a single `<SmartDag />` component.
- The `<SmartDag />` will read the `epicId` context to determine its zoom level and animation states.
- Introduce framer-motion (or existing animation libraries) for data flow and node pulsing.
### 4. Overhauling the Swarm Activity Feed & Roster
- **Contextual Agent Roster:** Instead of pulling all agents globally (like `ActivityPanel` currently does), we extract the active roster logic from `TelemetryGrid` to only show agents actively assigned to `in_progress` tasks within the currently selected `epicId`.
- **Streaming Telemetry Feed:** We reuse the `/api/events` SSE connection from `ActivityPanel`, but we filter the incoming events `beadId` to match the children of the current `epicId`. We format this feed as a terminal-like streaming log with concise, color-coded badges indicating what the agents are currently doing.
- **Cleanup the Graveyard:** Dead agents and old task logs will be entirely stripped from this contextual right panel, ensuring it remains a focused "Command Feed" of live operations.

View file

@ -0,0 +1,533 @@
# BeadBoard Global Install Runtime Manager Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Replace repo-path shim install behavior with a robust global install model where `beadboard` runs from managed runtime home and works from any directory.
**Architecture:** Keep a hybrid install strategy with npm-global as primary and script bootstrap as fallback, but unify both paths behind one runtime manager contract (`~/.beadboard/runtime/<version>` + stable shims). Preserve backward compatibility by detecting legacy repo-bound shims and offering migration. Implement with strict TDD and explicit installer smoke tests.
**Tech Stack:** Node.js (ESM), TypeScript/tsx for CLI code, PowerShell + POSIX shell wrappers, GitHub Actions, Node test runner.
---
## Pre-Implementation Checklist
### Task 0: Baseline and Safety Snapshot
**Files:**
- Modify: `beadboard/.beads/issues.jsonl` via `bd` commands only
- Read: `/mnt/c/Users/Zenchant/codex/beadboard/AGENTS.md`
- Read: `/mnt/c/Users/Zenchant/codex/beadboard/NEXT_SESSION_PROMPT.md`
**Step 1: Claim/track implementation bead(s)**
Run:
```bash
cd /mnt/c/Users/Zenchant/codex/beadboard
bd create --title="Global installer runtime manager implementation" --description="Implement npm-global-first runtime manager with migration from repo-path shims" --type=task --priority=1 --label="installation,cli,runtime"
bd update <new-bead-id> --status in_progress --assignee <agent-bead-id>
```
**Step 2: Capture baseline gate status**
Run:
```bash
npm run typecheck
npm run lint
npm run test
```
Expected: existing known unrelated failures may appear; record exact failing files/tests in bead notes.
**Step 3: Commit checkpoint**
No code changes yet. Do not commit.
---
## Phase 1: Define Runtime Manager Contract
### Task 1: Add runtime manager ADR and package contract
**Files:**
- Create: `docs/adr/2026-03-03-runtime-manager-global-install.md`
- Modify: `docs/adr/2026-03-03-global-installer-contract-and-manifest.md`
**Step 1: Write failing docs contract test**
Create:
- `tests/docs/runtime-manager-adr-contract.test.ts`
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import path from 'node:path';
test('runtime manager ADR exists and declares runtime home strategy', async () => {
const raw = await fs.readFile(path.resolve('docs/adr/2026-03-03-runtime-manager-global-install.md'), 'utf8');
assert.match(raw, /~\/\.beadboard\/runtime/i);
assert.match(raw, /npm i -g beadboard/i);
assert.match(raw, /legacy repo-bound shim migration/i);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts
```
Expected: FAIL (`ENOENT` for missing ADR file).
**Step 3: Write minimal implementation**
Add ADR with:
- runtime directory layout
- shim strategy
- update/uninstall model
- compatibility migration model
- failure modes and rollback
**Step 4: Run test to verify it passes**
Run:
```bash
node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add tests/docs/runtime-manager-adr-contract.test.ts docs/adr/2026-03-03-runtime-manager-global-install.md docs/adr/2026-03-03-global-installer-contract-and-manifest.md
git commit -m "docs: define runtime manager global install contract"
```
---
## Phase 2: Implement Runtime Manager Library
### Task 2: Add runtime manager core module with strict validation
**Files:**
- Create: `src/lib/runtime-manager.ts`
- Create: `tests/lib/runtime-manager.test.ts`
**Step 1: Write failing test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { getRuntimePaths, normalizeVersion } from '../../src/lib/runtime-manager';
test('normalizeVersion supports semver and rejects empty', () => {
assert.equal(normalizeVersion('1.2.3'), '1.2.3');
assert.throws(() => normalizeVersion(''));
});
test('getRuntimePaths builds ~/.beadboard/runtime/<version> layout', () => {
const p = getRuntimePaths('/tmp/home', '1.2.3');
assert.match(p.runtimeRoot, /runtime\/1\.2\.3$/);
assert.match(p.shimDir, /\.beadboard\/bin$/);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
```
Expected: FAIL (`Cannot find module '../../src/lib/runtime-manager'`).
**Step 3: Write minimal implementation**
Implement exports:
- `normalizeVersion(version: string): string`
- `getRuntimePaths(home: string, version: string)`
- `resolveInstallHome(env)`
Keep pure and side-effect free.
**Step 4: Run test to verify it passes**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add src/lib/runtime-manager.ts tests/lib/runtime-manager.test.ts
git commit -m "feat(installer): add runtime manager core library"
```
---
## Phase 3: Move Launcher to Runtime-Aware Execution
### Task 3: Update launcher to run from managed runtime root
**Files:**
- Modify: `install/beadboard.mjs`
- Modify: `tests/scripts/beadboard-launcher.test.ts`
- Create: `tests/scripts/beadboard-launcher-runtime.test.ts`
**Step 1: Write failing test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import path from 'node:path';
const execFileAsync = promisify(execFile);
const launcherPath = path.resolve('install/beadboard.mjs');
test('status --json reports runtime root and install mode', async () => {
const { stdout } = await execFileAsync(process.execPath, [launcherPath, 'status', '--json']);
const payload = JSON.parse(stdout);
assert.ok(payload.runtimeRoot);
assert.ok(payload.installMode);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
```
Expected: FAIL (missing fields).
**Step 3: Write minimal implementation**
In launcher:
- derive runtime home/version
- include `runtimeRoot`, `installMode`, `shimTarget` in JSON status
- preserve existing `start/open/status` behavior
**Step 4: Run tests to verify pass**
Run:
```bash
node --import tsx --test tests/scripts/beadboard-launcher.test.ts
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add install/beadboard.mjs tests/scripts/beadboard-launcher.test.ts tests/scripts/beadboard-launcher-runtime.test.ts
git commit -m "feat(launcher): add runtime-aware status metadata"
```
---
## Phase 4: Replace Repo-Bound Shim Targets
### Task 4: Make install wrappers point at runtime-managed target
**Files:**
- Modify: `install/install.sh`
- Modify: `install/install.ps1`
- Modify: `tests/scripts/install-wrappers-contract.test.ts`
- Modify: `tests/scripts/install-sh-smoke.test.ts`
- Create: `tests/scripts/install-legacy-migration.test.ts`
**Step 1: Write failing migration test**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
// simulate legacy shim text and verify installer rewrites to runtime target
test('installer migrates legacy repo-bound shim to runtime-managed shim', async () => {
assert.fail('implement');
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
```
Expected: FAIL.
**Step 3: Write minimal implementation**
In both wrappers:
- install runtime metadata file (`~/.beadboard/runtime/current.json`)
- rewrite `bb`/`beadboard` shims to resolve runtime target first
- detect old shim signatures and replace atomically
**Step 4: Run wrapper tests**
Run:
```bash
node --import tsx --test tests/scripts/install-wrappers-contract.test.ts
node --import tsx --test tests/scripts/install-sh-smoke.test.ts
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add install/install.sh install/install.ps1 tests/scripts/install-wrappers-contract.test.ts tests/scripts/install-sh-smoke.test.ts tests/scripts/install-legacy-migration.test.ts
git commit -m "feat(installer): migrate shims to runtime-managed targets"
```
---
## Phase 5: Add npm-Global Entry and Self-Management Commands
### Task 5: Add CLI entrypoint commands (`self-update`, `uninstall`, `doctor`)
**Files:**
- Modify: `package.json`
- Create: `bin/beadboard.js`
- Create: `src/cli/beadboard-cli.ts`
- Create: `tests/cli/beadboard-cli.test.ts`
**Step 1: Write failing CLI tests**
```ts
import test from 'node:test';
import assert from 'node:assert/strict';
import { runCli } from '../../src/cli/beadboard-cli';
test('doctor returns structured install diagnostics', async () => {
const out = await runCli(['doctor', '--json']);
assert.equal(out.ok, true);
assert.ok(out.installMode);
});
```
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/cli/beadboard-cli.test.ts
```
Expected: FAIL (missing module/command).
**Step 3: Write minimal implementation**
Add commands:
- `beadboard doctor --json`
- `beadboard self-update` (placeholder behavior with explicit output if publish not configured)
- `beadboard uninstall` (remove shims/runtime with `--yes` guard)
Add `bin` mapping in `package.json`.
**Step 4: Run test to verify pass**
Run:
```bash
node --import tsx --test tests/cli/beadboard-cli.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add package.json bin/beadboard.js src/cli/beadboard-cli.ts tests/cli/beadboard-cli.test.ts
git commit -m "feat(cli): add global entrypoint with doctor/update/uninstall commands"
```
---
## Phase 6: Driver Alignment + Remediation UX Finalization
### Task 6: Update driver preflight/remediation copy for npm-global-first flow
**Files:**
- Modify: `skills/beadboard-driver/scripts/lib/driver-lib.mjs`
- Modify: `skills/beadboard-driver/scripts/session-preflight.mjs`
- Modify: `tests/skills/beadboard-driver/resolve-bb.test.ts`
- Modify: `tests/skills/beadboard-driver/session-preflight.test.ts`
**Step 1: Write failing test assertion**
Add expectation:
- remediation mentions `npm i -g beadboard` as primary
- install script remains fallback
**Step 2: Run test to verify it fails**
Run:
```bash
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts
```
Expected: FAIL (copy mismatch).
**Step 3: Write minimal implementation**
Update remediation strings to:
1. npm-global install
2. fallback installer wrapper
3. BB_REPO override guidance
**Step 4: Re-run tests**
Run:
```bash
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add skills/beadboard-driver/scripts/lib/driver-lib.mjs skills/beadboard-driver/scripts/session-preflight.mjs tests/skills/beadboard-driver/resolve-bb.test.ts tests/skills/beadboard-driver/session-preflight.test.ts
git commit -m "feat(driver): prefer npm-global remediation with installer fallback"
```
---
## Phase 7: CI, Docs, and Release Readiness
### Task 7: Expand CI smoke and operator docs for global model
**Files:**
- Modify: `.github/workflows/installer-smoke.yml`
- Modify: `README.md`
- Modify: `docs/adr/2026-03-03-runtime-manager-global-install.md`
- Create: `docs/ops/global-install-rollout.md`
- Modify: `tests/scripts/installer-ci-contract.test.ts`
- Modify: `tests/docs/installer-quickstart-contract.test.ts`
**Step 1: Write failing test updates**
Add assertions for:
- npm-global command in docs
- runtime home path mentions
- CI step validating `beadboard doctor --json`
**Step 2: Run tests to verify fail**
Run:
```bash
node --import tsx --test tests/scripts/installer-ci-contract.test.ts
node --import tsx --test tests/docs/installer-quickstart-contract.test.ts
```
Expected: FAIL.
**Step 3: Write minimal implementation**
Update docs and workflow:
- install paths
- migration notes
- recovery playbook
- supported platforms matrix
**Step 4: Re-run tests**
Run:
```bash
node --import tsx --test tests/scripts/installer-ci-contract.test.ts
node --import tsx --test tests/docs/installer-quickstart-contract.test.ts
```
Expected: PASS.
**Step 5: Commit**
```bash
git add .github/workflows/installer-smoke.yml README.md docs/adr/2026-03-03-runtime-manager-global-install.md docs/ops/global-install-rollout.md tests/scripts/installer-ci-contract.test.ts tests/docs/installer-quickstart-contract.test.ts
git commit -m "docs(ci): finalize global install runtime docs and smoke coverage"
```
---
## Phase 8: Final Verification + Bead Closeout
### Task 8: Full-gate verification and close
**Files:**
- Modify: `beadboard` issue notes via `bd update`
- Modify: `NEXT_SESSION_PROMPT.md`
**Step 1: Run full gates**
Run:
```bash
npm run typecheck
npm run lint
npm run test
```
Expected: PASS; if unrelated failures exist, capture exact files/tests.
**Step 2: Run targeted installer acceptance checks**
Run:
```bash
node --import tsx --test tests/lib/runtime-manager.test.ts
node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts
node --import tsx --test tests/scripts/install-legacy-migration.test.ts
node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts
```
Expected: PASS.
**Step 3: Update beads with evidence**
Run:
```bash
bd update <bead-id> --notes "<commands run + pass/fail details>"
bd close <bead-id> --reason "<completed outcome>"
```
**Step 4: Update handoff**
Modify:
- `NEXT_SESSION_PROMPT.md` with shipped state + residual risks + next bead.
**Step 5: Commit**
```bash
git add NEXT_SESSION_PROMPT.md
git commit -m "chore: close runtime-manager rollout with verification evidence"
```
---
## References and Required Skills During Execution
1. `@test-driven-development`
2. `@verification-before-completion`
3. `@linus-beads-discipline`
4. `@beadboard-driver`
5. `@executing-plans` (required for implementation phase)
---
Plan complete and saved to `docs/plans/2026-03-03-global-install-runtime-manager.md`. Two execution options:
**1. Subagent-Driven (this session)** - I dispatch fresh subagent per task, review between tasks, fast iteration
**2. Parallel Session (separate)** - Open new session with executing-plans, batch execution with checkpoints
Which approach?

File diff suppressed because it is too large Load diff