fix: orchestrator button + Pi SDK session error

- Move leftSidebarMode from URL state to local useState in unified-shell,
    avoiding force-dynamic router round-trip that made the button appear broken                                           - Replace fileURLToPath(new URL(..., import.meta.url)) with process.cwd()
    in bb-pi-bootstrap.ts — import.meta.url is a webpack:// URL in Next.js,
    causing cross-realm TypeError when passed to Node.js fileURLToPath()
This commit is contained in:
zenchantlive 2026-03-24 15:39:19 -07:00
parent 643fa299dd
commit d335e5bf71
98 changed files with 17851 additions and 944 deletions

View file

@ -0,0 +1,64 @@
# ADR: BeadBoard Daemon Attachment Model
- Date: 2026-03-05
- Status: Accepted
- Scope: Host-resident daemon topology for BeadBoard runtime execution
## Context
BeadBoard is evolving from a coordination surface into a coordination-plus-execution product. The product now needs a durable runtime anchor that survives browser reloads, keeps project runtime state on the user's machine, and can eventually serve both local and remote frontends.
Earlier embedded runtime scaffolding inside the Next app is useful as a transition, but it is not the target architecture.
## Decision
BeadBoard will use a **user-owned, host-resident `bb` daemon** as the execution anchor.
This means:
- each user runs their own BeadBoard daemon on their own machine
- the daemon is long-lived while the host machine is on
- runtime ownership stays with the user and the user's environment
- the frontend attaches to daemon state and control APIs instead of owning execution directly
- this is **not a centralized hosted runtime** model for the current product architecture
## Attachment model
The canonical relationship is:
1. the user starts `bb daemon start`
2. the daemon becomes the durable runtime anchor for project execution
3. a frontend attaches to daemon APIs and event streams
4. the frontend acts as a client/control surface, not the runtime owner
The phrase **frontend attaches to daemon** is intentional. It applies whether the frontend is:
- running locally on the same machine
- deployed remotely by the user
- eventually deployed in a different frontend environment that still points at the same daemon
## Local vs remote frontend
Near-term implementation may use local co-residency and in-process attachment seams for simplicity.
Long-term architecture still treats the frontend and daemon as distinct roles:
- **daemon** = execution, orchestration, durable runtime state
- **frontend** = interaction, inspection, control, visualization
Remote attachment is therefore an extension of the same architecture, not a different one.
## Non-decision: later B2B hosting
A future B2B deployment may run `bb` on a cloud VM. That is a separate later PRD and does not change the current architectural standard:
- current product direction is still user-owned daemon first
- later hosted or VM-backed deployment must build on the same daemon attachment contract rather than replacing it with a centralized runtime assumption
## Consequences
- daemon lifecycle becomes a first-class CLI/runtime concern
- Next.js runtime routes should evolve into daemon-backed adapters
- the frontend must gradually become a daemon client rather than an in-app runtime owner
- Pi integration should sit behind a BeadBoard-owned daemon/runtime boundary
- persistence, reconnect behavior, and event streaming should attach to the daemon contract rather than ephemeral browser state

View file

@ -0,0 +1,179 @@
# Phase 1: Worker Spawning - Manual E2E Test
**Date:** 2026-03-06
**Status:** Ready for manual testing
---
## Prerequisites
1. ✅ Dev server is running (user has it running)
2. ✅ Pi SDK is available (`bb daemon bootstrap-pi` should have been run)
3. ✅ All code changes are committed and applied
---
## Test Scenarios
### Scenario 1: Basic Worker Spawn
**Steps:**
1. Open BeadBoard in browser (http://localhost:3000)
2. Open left panel (orchestrator mode)
3. Send this prompt to orchestrator:
```
Spawn a worker to read the README.md file and tell me what it says.
```
4. Observe the response and check:
- [ ] Orchestrator calls `bb_spawn_worker` tool
- [ ] Worker spawns with task context
- [ ] `worker.spawned` event appears in runtime console (with "Worker" badge)
- [ ] Worker event shows task ID: "read-the-readme.md-file-and-tell-me-what-it-says"
- [ ] Worker status tool response is shown
**Expected Result:** Worker appears in console with "Worker" badge, shows "WORKING" status.
---
### Scenario 2: Worker Status Check
**Steps:**
1. From left panel, send:
```
Check the status of the worker you just spawned.
```
2. Observe:
- [ ] Orchestrator calls `bb_worker_status` tool
- [ ] Worker status is displayed with correct emoji
- [ ] Shows "WORKING", "COMPLETED", or "FAILED" as appropriate
- [ ] Task ID matches the spawned task
**Expected Result:** Current worker status shown with helpful message.
---
### Scenario 3: Worker Completion
**Steps:**
1. Wait for the worker to complete (should happen within ~30 seconds for README read)
2. Observe:
- [ ] `worker.updated` or `worker.completed` event appears
- [ ] If completed: shows "COMPLETED" with ✅ emoji
- [ ] Result summary is shown (first 200 chars)
- [ ] Worker no longer shows as "WORKING"
**Expected Result:** Worker successfully completes and result is displayed.
---
### Scenario 4: Multiple Workers
**Steps:**
1. Send prompt to orchestrator:
```
Spawn 3 workers in parallel:
- Worker 1: Read package.json
- Worker 2: List all files in src/
- Worker 3: Read .env.example file
```
2. Observe:
- [ ] Three separate `worker.spawned` events appear
- [ ] All three workers show "WORKING" status
- [ ] Each worker has a unique ID
- [ ] Task contexts are correct for each
**Expected Result:** Multiple workers run in parallel, each with unique identity and task.
---
### Scenario 5: Worker with Archetype
**Steps:**
1. Send prompt to orchestrator:
```
Spawn a worker with archetype "coder" to add a new test file.
```
2. Observe:
- [ ] Worker spawns with "Archetype: coder" in the detail
- [ ] Worker system prompt includes the archetype context
**Expected Result:** Worker behavior is guided by archetype (though actual behavior is same - this is v1).
---
### Scenario 6: Worker Error Handling
**Steps:**
1. Send prompt to orchestrator with invalid task:
```
Spawn a worker to read a file that does not exist: /nonexistent/path/to/file.txt
```
2. Observe:
- [ ] Worker attempts the task
- [ ] Worker fails and reports error
- [ ] `worker.failed` event appears with ❌ emoji
- [ ] Error message explains what went wrong
**Expected Result:** Worker failures are captured and reported clearly.
---
### Scenario 7: Runtime Console Worker Badge
**Steps:**
1. Spawn a worker
2. Look at runtime console (bottom panel)
3. Observe:
- [ ] Worker events have a purple "Worker" badge
- [ ] Orchestrator events do NOT have the badge
- [ ] Badge says "Worker Agent Event" on hover
**Expected Result:** Visual distinction between orchestrator and worker events is clear.
---
### Scenario 8: Left Panel Chat Integration
**Steps:**
1. Observe the orchestrator conversation in left panel
2. During worker spawn, check:
- [ ] Tool calls appear inline (like they do for `bb_dolt_read`)
- [ ] Worker spawn response includes worker ID
- [ ] Chat remains readable and not cluttered
**Expected Result:** Orchestrator chat surface handles worker interactions natively.
---
## Success Criteria
A scenario passes when:
- Worker events appear in runtime console
- Worker events have "Worker" badge
- Status changes (spawning → working → completed) are visible
- Tool calls are logged and returned to orchestrator
- Multiple workers can run in parallel
- Worker completion/failure is captured
---
## Bug Report Form
If any test fails, capture:
```
Test Scenario: [number]
Steps Taken: [what you did]
Expected Result: [what should happen]
Actual Result: [what actually happened]
Error Messages: [any errors in console]
Screenshot/Notes: [any additional details]
```
---
## After Testing
Once all scenarios pass:
1. Review success criteria in `docs/plans/2026-03-06-phase-1-worker-spawning.md`
2. Update roadmap to mark Phase 1 as complete
3. Move to Phase 2: Archetype-backed execution configs

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,373 @@
# BeadBoard Embedded Pi Roadmap
**Date:** 2026-03-05
**Last Updated:** 2026-03-07
**Companion PRD:** `docs/plans/2026-03-05-embedded-pi-prd.md`
**Purpose:** Track what has already shipped for Embedded Pi in BeadBoard, what is partially complete, and what remains to reach the full PRD vision.
---
## Current status
**Phase 3 COMPLETE - Testing in progress.**
We now have:
- ✅ Working embedded orchestrator with BeadBoard tools
- ✅ Worker spawning with numbered instances (Engineer 01, etc.)
- ✅ Agent types (architect, engineer, reviewer, tester, investigator, shipper)
- ✅ Template-based team spawning
- ✅ **Bead-required workflow** - every worker task has a bead
- ✅ **Async worker coordination** - non-blocking spawn, check status, read results
- ✅ **File verification pattern** - orchestrator reads actual files to verify work
**Currently testing:**
- Worker claims bead, updates, closes correctly
- Orchestrator can check worker status mid-task
- Orchestrator can get results and verify via file reads
**Biggest remaining gaps:**
- Phase 4: Launch-anywhere UX (spawn from task cards, graph nodes)
- Phase 5: Agent presence in social/graph views
- Tests and verification
---
## What is done
### Done: Runtime substrate / managed Pi foundation
- Managed Pi bootstrap exists via `src/lib/bb-pi-bootstrap.ts`
- Pi runtime detection exists via `src/lib/pi-runtime-detection.ts`
- BeadBoard-specific Pi settings + agent dir setup exist
- Embedded daemon/orchestrator substrate exists via:
- `src/lib/embedded-daemon.ts`
- `src/lib/bb-daemon.ts`
- `src/lib/pi-daemon-adapter.ts`
### Done: Orchestrator session integration
- Per-project orchestrator session can be created and reused
- Pi SDK session is initialized through the embedded adapter
- The orchestrator can receive prompts from the frontend
- The orchestrator can execute BeadBoard tools from the frontend path
### Done: BeadBoard-aware orchestrator context
- Dynamic system prompt exists in `src/tui/system-prompt.ts`
- Prompt includes:
- active tasks
- archetypes
- templates
- Deviation recording tool exists:
- `src/tui/tools/bb-deviation.ts`
### Done: Frontend prompt + telemetry plumbing
- Prompt route exists: `src/app/api/runtime/prompt/route.ts`
- Runtime event stream exists: `src/app/api/runtime/stream/route.ts`
- Runtime events endpoint exists: `src/app/api/runtime/events/route.ts`
- Left-panel orchestrator UI exists and can submit prompts
- Bottom runtime console exists and is now minimizable
### Done: Left-panel orchestrator chat UX foundation
- Left panel supports orchestrator mode
- Left panel now renders chat-style bubbles instead of raw telemetry cards
- User prompts can appear immediately in chat
- Assistant replies are projected from Pi session/runtime events
- Session/runtime errors are kept out of the main chat transcript surface
### Done: Realtime / event-ingestion hardening
- Duplicate runtime-event ingestion was debugged and deduped in the app shell
- Activity panel merging was deduped to stop repeated React key collisions
- Prompt path was changed so frontend requests return immediately instead of blocking on full agent completion
- Runtime stream now continuously surfaces new daemon events without requiring manual refresh for each turn
---
## Partially complete
### Partial: Sessions / conversation model
What works now:
- one embedded project orchestrator
- left-panel conversation surface
- runtime console telemetry
What is still missing:
- robust multi-session model
- explicit worker-session UI
- Full activity panel integration for orchestrator + worker histories
- clearer separation of orchestrator conversation vs mission/worker conversation surfaces
### Partial: Runtime observability
What works now:
- tool execution visibility
- runtime stream
- prompt submission + visible orchestrator progress
What is still missing:
- stronger stuck-session diagnostics
- clearer "thinking vs waiting vs blocked vs completed" state presentation
- better recovery/restart UX when a live session fails
### Partial: Launch plumbing
What works now:
- orchestrator prompt flow in the left panel
- UI-triggered launch route exists
What is still missing:
- launch-anywhere completion across all PRD surfaces
- more complete task/graph/swarm/mission launch affordances
- better contextual launch packaging per surface
---
## Remaining roadmap
## Phase 1 - Worker agents / sub-agents
**Status:** ✅ DONE (2026-03-06)
**Plan:** `docs/plans/2026-03-06-phase-1-worker-spawning.md`
### Shipped
- ✅ Worker spawning tool (`bb_spawn_worker`)
- ✅ Worker status tool (`bb_worker_status`)
- ✅ Worker session manager with isolated sessions
- ✅ Worker events in runtime console with "Worker" badge
- ✅ Worker lifecycle (spawning → working → completed/failed)
- ✅ Multiple parallel workers supported
- ✅ Archetype parameter support
- ✅ Worker results merge back to orchestrator chat
---
## Phase 2 - Archetypes as executable agent types
**Status:** ✅ DONE (2026-03-06)
**Plan:** `docs/plans/2026-03-06-phase-2-archetype-configs.md`
### Shipped
- ✅ Archetype CRUD tools (`bb_list_archetypes`, `bb_create_archetype`, etc.)
- ✅ Template CRUD tools (`bb_list_templates`, `bb_create_template`, etc.)
- ✅ Worker session manager loads archetype config
- ✅ Capabilities mapped to tool access (full vs read-only)
- ✅ System prompt injection per archetype
---
## Phase 3 - Agent-based orchestration
**Status:** ✅ DONE (2026-03-07) - **Testing in progress**
**Plan:** `docs/plans/2026-03-07-phase-3-agent-orchestration.md`
### Shipped
- ✅ Renamed "archetype" → "agent" everywhere user-facing
- ✅ Agent instances with numbered display names (Engineer 01, etc.)
- ✅ Agent status panel in right panel
- ✅ Agent state persistence (`.beads/agents.jsonl`)
- ✅ Template spawning tool (`bb_spawn_team`)
- ✅ Natural language task descriptions (no task_id required)
- ✅ Auto-template selection from description keywords
- ✅ Decision tree in orchestrator prompt
- ✅ Agent assignment to beads (`bb_assign_agent`)
### Additional (2026-03-07)
- ✅ **Bead-required workflow** - every worker task has a bead
- `bb_create`, `bb_update`, `bb_close`, `bb_show`, `bb_ready` tools
- Workers must claim bead → update progress → close with summary
- ✅ **Async worker coordination** - non-blocking spawn
- `bb_worker_results` tool - get results from completed workers
- Orchestrator can check status mid-task
- Continue conversation while workers run
- ✅ **File verification pattern** - orchestrator reads actual files
- Not just result strings, but actual implementation
- Makes orchestrator a true reviewer
---
## Phase 4 - Multi-surface launch-anywhere UX
**Status:** Partially done
### Remaining work
1. Complete launch affordances on:
- task cards
- graph nodes
- swarm views
- mission inspectors
- sessions contexts
- blocked triage contexts
2. Ensure each launch path packages the right local context automatically
3. Make orchestrator interactions feel consistent across surfaces
---
## Phase 5 - Agent presence in social/graph/activity views
**Status:** Not done
### Remaining work
1. Make orchestrator + worker sessions visible in social cards, graph nodes, and activity panel
2. Support switching between active workers via left-panel orchestrator
3. Preserve longer conversation history cleanly
4. Add intervention / redirection UX for active worker sessions
---
## Phase 6 - Runtime hardening and persistence
**Status:** Partially done
### Remaining work
1. Reduce drift between TUI Pi loader path and embedded Pi loader path
2. Harden reconnect/restart behavior for embedded sessions
3. Improve stuck/hung agent diagnostics
4. Clarify true host-daemon vs in-process lifecycle direction
5. Strengthen project-scoped persistence and restoration guarantees
---
## Phase 7 — Tests and verification
**Status:** Mostly not done
### Remaining work
1. Unit coverage for runtime path resolution / event projection / chat projection
2. Contract tests for adapter and runtime event schemas
3. Integration tests for orchestrator session creation + prompt flow
4. UI tests for left-panel orchestrator chat behavior
5. End-to-end tests for prompt → tool → reply flow
6. Failure-path tests for runtime import/session/tool errors
---
## Phase 8 — Unified Settings System (Future)
**Status:** Not started, documented in PRD Section 24
### Goal
Comprehensive settings for CLI and frontend: model selection, provider auth, UI preferences, runtime config.
### See
`docs/plans/2026-03-05-embedded-pi-prd.md` Section 24 for full requirements.
---
## Phase 9 — Holistic Skill Update (After All Phases Complete)
**Status:** Not started, depends on Phases 1-8
### Goal
Update `skills/beadboard-driver/` to reflect the new agent-based architecture.
### Why This Is Needed
The skill documentation was written before Phase 1-3 decisions:
- Archetypes were renamed to Agents
- Agent instances get numbered display names (Engineer 01, etc.)
- Templates are how teams are composed
- Workers spawn via `bb_spawn_worker(description)` not `bd create`
- Natural language task descriptions, not task_id requirements
### Files to Update
**Core Skill:**
- `skills/beadboard-driver/SKILL.md` - Main runbook
**References:**
- `skills/beadboard-driver/references/archetypes-templates-swarms.md` - Rename archetypes → agents
- `skills/beadboard-driver/references/command-matrix.md` - Add new agent tools
- `skills/beadboard-driver/references/agent-state-liveness.md` - Update for numbered instances
- `skills/beadboard-driver/references/session-lifecycle.md` - Update worker spawn flow
- `skills/beadboard-driver/references/coordination-system.md` - May need updates
- `skills/beadboard-driver/references/creating-beads.md` - May need updates
### Key Changes to Document
1. **Agent Types (was Archetypes)**
- 6 built-in: architect, engineer, reviewer, tester, investigator, shipper
- CRUD tools: `bb_list_agents`, `bb_create_agent`, etc.
- Each has capabilities that determine tool access
2. **Agent Instances**
- Numbered display names: "Engineer 01", "Engineer 02"
- Unique instance IDs: `{type}-{number}-{random}`
- Status panel shows active instances
3. **Templates**
- Named compositions: feature-dev, bug-fix, etc.
- Spawn via `bb_spawn_team(description)` or `bb_spawn_team(description, template)`
- Auto-select template from description keywords
4. **Worker Spawning**
- Natural language: `bb_spawn_worker(description: "Fix the login bug")`
- No task_id required - auto-generated from description
- Optional `bead_id` to assign to existing bead
5. **Orchestrator Decision Tree**
- Small task → spawn 1 agent
- Medium task → spawn 2-3 agents
- Large task → use template
### Scripts to Review
- `scripts/generate-agent-name.mjs` - May need update for new naming
- `scripts/session-preflight.mjs` - May reference old concepts
### Effort
~2-3 hours
---
## Suggested next build order
1. **Worker spawning tool + worker session model**
2. **Archetype-backed execution config**
3. **Template-first orchestration behavior**
4. **Activity panel integration for orchestrator/workers**
5. **Launch-anywhere UX completion**
6. **Runtime hardening + automated tests**
---
## Files most relevant to current Embedded Pi implementation
### Core runtime
- `src/lib/bb-daemon.ts`
- `src/lib/embedded-daemon.ts`
- `src/lib/pi-daemon-adapter.ts`
- `src/lib/pi-runtime-detection.ts`
- `src/lib/bb-pi-bootstrap.ts`
### TUI / shared Pi integration references
- `src/tui/bb-agent-tui.ts`
- `src/tui/system-prompt.ts`
- `src/tui/tools/bb-dolt-read.ts`
- `src/tui/tools/bb-deviation.ts`
- `src/tui/tools/bb-mailbox.ts`
- `src/tui/tools/bb-presence.ts`
- `src/tui/tools/bb-spawn-worker.ts`
- `src/tui/tools/bb-spawn-template.ts`
- `src/tui/tools/bb-worker-status.ts`
- `src/tui/tools/bb-worker-results.ts`
- `src/tui/tools/bb-bead-crud.ts`
- `src/tui/tools/bb-list-agents.ts`
- `src/tui/tools/bb-create-agent.ts`
- `src/tui/tools/bb-assign-agent.ts`
### Frontend surfaces
- `src/components/shared/orchestrator-panel.tsx`
- `src/components/shared/runtime-console.tsx`
- `src/components/shared/unified-shell.tsx`
- `src/components/shared/left-panel-new.tsx`
- `src/lib/orchestrator-chat.ts`
---
## Summary
**Phase 3 COMPLETE - Testing in progress.**
What is proven now:
- ✅ Embedded orchestrator runtime
- ✅ Frontend prompt path
- ✅ Realtime telemetry
- ✅ Left-panel orchestrator chat
- ✅ BeadBoard-aware tool execution
- ✅ Worker spawning with numbered instances
- ✅ Agent types with capabilities
- ✅ Template-based team spawning
- ✅ Bead-required workflow
- ✅ Async worker coordination
What remains:
- Phase 4: Launch-anywhere UX (spawn from task cards, graph nodes)
- Phase 5: Agent presence in social/graph views
- Phase 6: Runtime hardening
- Phase 7: Tests and verification
- Phase 8: Unified Settings
- Phase 9: Holistic skill update

View file

@ -0,0 +1,419 @@
# Phase 1: Worker Agent Spawning
**Date:** 2026-03-06
**Status:** Ready for implementation
**PRD Reference:** `docs/plans/2026-03-05-embedded-pi-prd.md`
**Roadmap Reference:** `docs/plans/2026-03-05-embedded-pi-roadmap.md`
---
## Goal
Enable the orchestrator Pi to spawn real worker Pi instances for parallel task execution.
This is the biggest gap between "embedded chat" and "true BeadBoard execution substrate."
---
## Current State
- One orchestrator Pi per project (working)
- Orchestrator can receive prompts and execute tools
- BeadBoard tools exist: `bb_dolt_read`, `bb_mailbox`, `bb_presence`, `bb_deviation`
- Runtime events flow to frontend via SSE
- Left panel shows orchestrator chat
---
## Target State
- Orchestrator can spawn worker Pi instances
- Each worker has isolated session/context
- Workers execute tasks independently
- Worker status/progress visible in UI
- Worker results merge back to orchestrator
---
## Architecture
### Session Model
```
Project
├── Orchestrator Session (long-lived)
│ └── Spawns workers, coordinates, reviews results
├── Worker Session 1 (task-scoped, ephemeral)
│ └── Executes specific task, reports back
├── Worker Session 2 (task-scoped, ephemeral)
│ └── Executes specific task, reports back
└── Worker Session N...
```
### Key Distinctions
| Aspect | Orchestrator | Worker |
|--------|--------------|--------|
| Lifetime | Long-lived (project-scoped) | Ephemeral (task-scoped) |
| Context | Full project context | Task-specific context |
| Tools | All tools + spawn tool | Subset (no spawn) |
| Status | Always visible | Visible while running |
| Session | Reused across prompts | Created per task, destroyed on completion |
---
## Implementation Tasks
### Task 1: Worker Session Manager
**File:** `src/lib/worker-session-manager.ts`
**Purpose:** Manage worker Pi session lifecycle separate from orchestrator.
**What to build:**
```typescript
interface WorkerSession {
id: string;
projectId: string;
taskId: string;
status: 'spawning' | 'working' | 'completed' | 'failed';
session: any; // Pi SDK session
createdAt: string;
completedAt: string | null;
result: string | null;
error: string | null;
}
class WorkerSessionManager {
private workers = new Map<string, WorkerSession>();
async spawnWorker(params: {
projectRoot: string;
taskId: string;
taskContext: string;
archetype?: string;
}): Promise<WorkerSession>;
getWorker(workerId: string): WorkerSession | undefined;
listWorkers(projectRoot: string): WorkerSession[];
terminateWorker(workerId: string): Promise<void>;
waitForWorker(workerId: string): Promise<string>;
}
```
**Test file:** `tests/lib/worker-session-manager.test.ts`
**Commands:**
```bash
cd /home/clawdbot/clawd/repos/beadboard
touch src/lib/worker-session-manager.ts
touch tests/lib/worker-session-manager.test.ts
```
---
### Task 2: Worker Spawning Tool
**File:** `src/tui/tools/bb-spawn-worker.ts`
**Purpose:** Tool that orchestrator calls to spawn a worker.
**What to build:**
```typescript
import { Type } from '@sinclair/typebox';
import type { CustomAgentTool } from '@mariozechner/pi-coding-agent';
export function createSpawnWorkerTool(projectRoot: string): CustomAgentTool {
return {
name: 'bb_spawn_worker',
label: 'Spawn Worker Agent',
description: 'Spawn a worker agent to execute a specific task in parallel. The worker will work independently and report back results.',
parameters: Type.Object({
task_id: Type.String({ description: 'The ID of the task for the worker to work on' }),
task_context: Type.String({ description: 'Context/instructions for the worker' }),
archetype: Type.Optional(Type.String({ description: 'Optional archetype for worker behavior (e.g., "coder", "reviewer", "tester")' })),
}),
async execute(_toolCallId, params: any) {
// 1. Validate task exists
// 2. Spawn worker session via WorkerSessionManager
// 3. Emit worker.spawned event
// 4. Return worker ID and status
},
};
}
```
**Test file:** `tests/tui/tools/bb-spawn-worker.test.ts`
**Commands:**
```bash
cd /home/clawdbot/clawd/repos/beadboard
touch src/tui/tools/bb-spawn-worker.ts
touch tests/tui/tools/bb-spawn-worker.test.ts
```
---
### Task 3: Worker Status Tool
**File:** `src/tui/tools/bb-worker-status.ts`
**Purpose:** Tool for orchestrator to check worker status.
**What to build:**
```typescript
export function createWorkerStatusTool(projectRoot: string): CustomAgentTool {
return {
name: 'bb_worker_status',
label: 'Check Worker Status',
description: 'Check the status of a spawned worker agent.',
parameters: Type.Object({
worker_id: Type.String({ description: 'The ID of the worker to check' }),
}),
async execute(_toolCallId, params: any) {
// Return worker status, progress, result (if completed)
},
};
}
```
**Test file:** `tests/tui/tools/bb-worker-status.test.ts`
**Commands:**
```bash
cd /home/clawdbot/clawd/repos/beadboard
touch src/tui/tools/bb-worker-status.ts
touch tests/tui/tools/bb-worker-status.test.ts
```
---
### Task 4: Update Pi Daemon Adapter for Workers
**File:** `src/lib/pi-daemon-adapter.ts`
**Changes:**
1. Import worker tools
2. Pass worker session manager reference
3. Add worker events to session subscription
**Specific edits:**
After line 64 (tools array), add:
```typescript
// Import worker tools
const { createSpawnWorkerTool } = await import('../tui/tools/bb-spawn-worker');
const { createWorkerStatusTool } = await import('../tui/tools/bb-worker-status');
```
In customTools array, add:
```typescript
{ tool: createSpawnWorkerTool(projectRoot) },
{ tool: createWorkerStatusTool(projectRoot) },
```
---
### Task 5: Runtime Event Types for Workers
**File:** `src/lib/embedded-runtime.ts`
**Already has:**
- `worker.spawned`
- `worker.updated`
- `worker.completed`
- `worker.failed`
**Verify these are used correctly in event emission.**
---
### Task 6: Worker Events in Daemon
**File:** `src/lib/embedded-daemon.ts`
**Add helper method:**
```typescript
appendWorkerEvent(projectRoot: string, workerId: string, event: {
kind: 'worker.spawned' | 'worker.updated' | 'worker.completed' | 'worker.failed';
title: string;
detail: string;
status?: RuntimeConsoleEvent['status'];
}): void {
this.appendEvent(projectRoot, {
kind: event.kind,
title: event.title,
detail: event.detail,
status: event.status,
metadata: { workerId },
});
}
```
---
### Task 7: Frontend Worker Status Display
**File:** `src/components/shared/runtime-console.tsx`
**Changes:**
1. Add worker event rendering (distinct from orchestrator events)
2. Show worker spawn/complete/fail with visual indicators
3. Display worker ID and task association
**File:** `src/components/shared/orchestrator-panel.tsx`
**Changes:**
1. Show active workers count
2. List workers with status badges
3. Click to expand worker details
---
### Task 8: Worker Isolation
**File:** `src/lib/worker-session-manager.ts`
**Ensure:**
1. Workers use separate session from orchestrator
2. Worker context is task-scoped, not project-scoped
3. Worker cannot spawn more workers (no recursion)
4. Worker results are captured, not lost
**Worker system prompt:**
```typescript
const workerPrompt = `
You are a worker agent for BeadBoard. Your job is to execute a specific task.
Task ID: ${taskId}
Task Context: ${taskContext}
Rules:
- Focus only on this task
- Report progress via bb_presence tool
- When complete, summarize what you did
- If blocked, report why
- You cannot spawn more workers
`;
```
---
### Task 9: Integration Tests
**File:** `tests/integration/worker-spawning.test.ts`
**Test scenarios:**
1. Orchestrator spawns worker successfully
2. Worker executes task and reports completion
3. Worker failure is captured and reported
4. Multiple workers can run in parallel
5. Worker status tool returns correct state
6. Events flow to frontend correctly
**Commands:**
```bash
cd /home/clawdbot/clawd/repos/beadboard
mkdir -p tests/integration
touch tests/integration/worker-spawning.test.ts
```
---
### Task 10: Manual E2E Test
**Steps:**
1. Start BeadBoard dev server
2. Open left panel orchestrator chat
3. Send prompt: "Spawn a worker to read the README.md and summarize it"
4. Verify:
- `worker.spawned` event appears in console
- Worker status shows in UI
- Worker completes with result
- `worker.completed` event appears
- Orchestrator receives result summary
---
## Files Summary
| File | Action | Purpose |
|------|--------|---------|
| `src/lib/worker-session-manager.ts` | Create | Manage worker lifecycle |
| `src/tui/tools/bb-spawn-worker.ts` | Create | Tool for spawning |
| `src/tui/tools/bb-worker-status.ts` | Create | Tool for status checks |
| `src/lib/pi-daemon-adapter.ts` | Edit | Add worker tools |
| `src/lib/embedded-daemon.ts` | Edit | Add worker event helper |
| `src/components/shared/runtime-console.tsx` | Edit | Display worker events |
| `src/components/shared/orchestrator-panel.tsx` | Edit | Show worker list |
| `tests/lib/worker-session-manager.test.ts` | Create | Unit tests |
| `tests/tui/tools/bb-spawn-worker.test.ts` | Create | Tool tests |
| `tests/tui/tools/bb-worker-status.test.ts` | Create | Tool tests |
| `tests/integration/worker-spawning.test.ts` | Create | Integration tests |
---
## Success Criteria
- [ ] Orchestrator can call `bb_spawn_worker` tool
- [ ] Worker session is created and tracked
- [ ] Worker executes task independently
- [ ] Worker events appear in runtime console
- [ ] Worker status is queryable via `bb_worker_status`
- [ ] Worker completion/failure is captured
- [ ] Multiple workers can run in parallel
- [ ] Workers cannot spawn more workers
- [ ] All tests pass
---
## Risks
| Risk | Mitigation |
|------|------------|
| Worker context bleeds into orchestrator | Separate session objects, isolated state |
| Too many workers spawn | Limit max concurrent workers per project |
| Worker hangs | Add timeout, auto-terminate stuck workers |
| Events duplicate | Use dedupe logic already in place |
---
## Estimated Effort
- Tasks 1-3 (Core): 2-3 hours
- Tasks 4-6 (Integration): 1-2 hours
- Tasks 7-8 (UI + Isolation): 2-3 hours
- Tasks 9-10 (Testing): 1-2 hours
**Total:** 6-10 hours
---
## Execution Order
Recommended sequence:
1. Task 1 → 2 → 3 (Core tools)
2. Task 4 → 5 → 6 (Integration)
3. Task 8 (Isolation - critical before testing)
4. Task 7 (UI)
5. Task 9 → 10 (Testing)
---
## Dependencies
- Pi SDK (already integrated)
- Existing daemon/adapter infrastructure
- Runtime event system (already working)
---
## Next After Phase 1
Once workers can spawn and execute:
- **Phase 2:** Archetype-backed execution configs
- **Phase 3:** Template-first orchestration with workers
- **Phase 5:** Show workers in social/graph views

View file

@ -0,0 +1,496 @@
# Phase 2: Archetype Execution Configs
**Date:** 2026-03-06
**Status:** Ready for implementation
**PRD Reference:** `docs/plans/2026-03-05-embedded-pi-prd.md`
**Depends on:** Phase 1 (Worker Spawning) ✅
---
## Goal
1. Link existing archetype system to worker behavior
2. Give orchestrator CRUD tools for archetypes and templates
---
## Current State
- **Frontend** has full archetype system:
- Schema: `AgentArchetype` with `id`, `name`, `systemPrompt`, `capabilities[]`, `color`
- Storage: `.beads/archetypes/*.json`
- UI: `archetype-inspector.tsx` for create/edit/clone
- Seed archetypes: architect, coder, reviewer, tester, researcher
- **Templates** also exist:
- Schema: `SwarmTemplate` with `team: { archetypeId, count }[]`
- Storage: `.beads/templates/*.json`
- **Backend** (`beads-fs.ts`) has all CRUD functions
- **Worker spawning** passes `archetype` but doesn't use it
- **Orchestrator** has NO tools to manage archetypes/templates
---
## Target State
- Orchestrator can CRUD archetypes and templates via tools
- Workers load archetype config and behave accordingly:
- `capabilities` → which tools worker gets
- `systemPrompt` → injected into worker prompt
---
## Capability → Tool Mapping
| Capability | Tools Granted |
|------------|---------------|
| `coding`, `implementation` | read, bash, edit, write, dolt-read |
| `planning`, `design_docs` | read, dolt-read (read-only) |
| `review`, `arch_review` | read, dolt-read (read-only) |
| `testing` | read, bash, edit, write, dolt-read |
| `research` | read, dolt-read, bash (limited) |
| All others | read, dolt-read (default read-only) |
**Rule:** If `capabilities` includes `coding` or `implementation` or `testing` → full tools. Otherwise → read-only.
---
## Implementation
### Task 1: Create Archetype CRUD Tools
**File:** `src/tui/tools/bb-list-archetypes.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { getArchetypes } from '../../lib/server/beads-fs';
export function bbListArchetypes(projectRoot: string) {
return createTool('bb_list_archetypes', {
description: 'List all available archetypes. Returns id, name, description, capabilities for each.',
parameters: {},
handler: async () => {
const archetypes = await getArchetypes();
return {
archetypes: archetypes.map(a => ({
id: a.id,
name: a.name,
description: a.description,
capabilities: a.capabilities,
color: a.color,
isBuiltIn: a.isBuiltIn,
})),
};
},
});
}
```
**File:** `src/tui/tools/bb-create-archetype.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { saveArchetype } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbCreateArchetype(projectRoot: string) {
return createTool('bb_create_archetype', {
description: 'Create a new archetype. Requires name, description, systemPrompt, capabilities, color.',
parameters: z.object({
name: z.string().describe('Display name for the archetype'),
description: z.string().describe('What this archetype does'),
systemPrompt: z.string().describe('System prompt injected into workers with this archetype'),
capabilities: z.array(z.string()).describe('List of capabilities (e.g., ["coding", "testing"])'),
color: z.string().default('#3b82f6').describe('Hex color for display'),
}),
handler: async (params) => {
const archetype = await saveArchetype({
name: params.name,
description: params.description,
systemPrompt: params.systemPrompt,
capabilities: params.capabilities,
color: params.color,
isBuiltIn: false,
});
return { ok: true, archetype };
},
});
}
```
**File:** `src/tui/tools/bb-update-archetype.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { saveArchetype } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbUpdateArchetype(projectRoot: string) {
return createTool('bb_update_archetype', {
description: 'Update an existing archetype. Cannot modify built-in archetypes.',
parameters: z.object({
id: z.string().describe('Archetype ID to update'),
name: z.string().optional().describe('New display name'),
description: z.string().optional().describe('New description'),
systemPrompt: z.string().optional().describe('New system prompt'),
capabilities: z.array(z.string()).optional().describe('New capabilities list'),
color: z.string().optional().describe('New hex color'),
}),
handler: async (params) => {
const archetype = await saveArchetype({
id: params.id,
name: params.name ?? '',
description: params.description ?? '',
systemPrompt: params.systemPrompt ?? '',
capabilities: params.capabilities ?? [],
color: params.color ?? '#3b82f6',
});
return { ok: true, archetype };
},
});
}
```
**File:** `src/tui/tools/bb-delete-archetype.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { deleteArchetype } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbDeleteArchetype(projectRoot: string) {
return createTool('bb_delete_archetype', {
description: 'Delete an archetype. Cannot delete built-in archetypes.',
parameters: z.object({
id: z.string().describe('Archetype ID to delete'),
}),
handler: async (params) => {
await deleteArchetype(params.id);
return { ok: true, deletedId: params.id };
},
});
}
```
---
### Task 2: Create Template CRUD Tools
**File:** `src/tui/tools/bb-list-templates.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { getTemplates } from '../../lib/server/beads-fs';
export function bbListTemplates(projectRoot: string) {
return createTool('bb_list_templates', {
description: 'List all swarm templates. Returns team composition for each.',
parameters: {},
handler: async () => {
const templates = await getTemplates();
return {
templates: templates.map(t => ({
id: t.id,
name: t.name,
description: t.description,
team: t.team,
isBuiltIn: t.isBuiltIn,
})),
};
},
});
}
```
**File:** `src/tui/tools/bb-create-template.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { saveTemplate } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbCreateTemplate(projectRoot: string) {
return createTool('bb_create_template', {
description: 'Create a new swarm template. Defines team composition by archetype.',
parameters: z.object({
name: z.string().describe('Display name for the template'),
description: z.string().describe('What this template is for'),
team: z.array(z.object({
archetypeId: z.string().describe('Archetype ID'),
count: z.number().describe('Number of workers with this archetype'),
})).describe('Team composition'),
color: z.string().default('#f59e0b').describe('Hex color for display'),
}),
handler: async (params) => {
const template = await saveTemplate({
name: params.name,
description: params.description,
team: params.team,
color: params.color,
isBuiltIn: false,
});
return { ok: true, template };
},
});
}
```
**File:** `src/tui/tools/bb-update-template.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { saveTemplate } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbUpdateTemplate(projectRoot: string) {
return createTool('bb_update_template', {
description: 'Update an existing swarm template.',
parameters: z.object({
id: z.string().describe('Template ID to update'),
name: z.string().optional().describe('New display name'),
description: z.string().optional().describe('New description'),
team: z.array(z.object({
archetypeId: z.string(),
count: z.number(),
})).optional().describe('New team composition'),
color: z.string().optional().describe('New hex color'),
}),
handler: async (params) => {
const template = await saveTemplate({
id: params.id,
name: params.name ?? '',
description: params.description ?? '',
team: params.team ?? [],
color: params.color ?? '#f59e0b',
});
return { ok: true, template };
},
});
}
```
**File:** `src/tui/tools/bb-delete-template.ts`
```typescript
import { createTool } from '@mariozechner/pi-coding-agent';
import { deleteTemplate } from '../../lib/server/beads-fs';
import { z } from 'zod';
export function bbDeleteTemplate(projectRoot: string) {
return createTool('bb_delete_template', {
description: 'Delete a swarm template. Cannot delete built-in templates.',
parameters: z.object({
id: z.string().describe('Template ID to delete'),
}),
handler: async (params) => {
await deleteTemplate(params.id);
return { ok: true, deletedId: params.id };
},
});
}
```
---
### Task 3: Link Archetype to Worker Behavior
**File:** `src/lib/worker-session-manager.ts`
**Changes:**
1. Import archetype loading:
```typescript
import { getArchetypes, type AgentArchetype } from './server/beads-fs';
```
2. Add capability → tool mapping:
```typescript
function getToolsForCapabilities(capabilities: string[]): {
allowEdit: boolean;
allowWrite: boolean;
allowBash: boolean;
} {
const fullAccess = ['coding', 'implementation', 'testing'];
const hasFullAccess = capabilities.some(c => fullAccess.includes(c));
if (hasFullAccess) {
return { allowEdit: true, allowWrite: true, allowBash: true };
}
// Read-only for planning, review, research
return { allowEdit: false, allowWrite: false, allowBash: false };
}
```
3. Load archetype in `createWorkerSession`:
```typescript
async createWorkerSession(
worker: WorkerInfo,
taskContext: string,
archetypeId?: string
): Promise<void> {
// Load archetype config
let archetype: AgentArchetype | undefined;
if (archetypeId) {
const archetypes = await getArchetypes();
archetype = archetypes.find(a => a.id === archetypeId);
}
const capabilities = archetype?.capabilities ?? [];
const toolAccess = getToolsForCapabilities(capabilities);
// Build tools based on capabilities
const tools = [];
tools.push(this.sdk.createReadTool(this.projectRoot));
tools.push(this.sdk.createMailboxTool(this.projectRoot));
tools.push(this.sdk.createPresenceTool(this.projectRoot));
if (toolAccess.allowBash) {
tools.push(this.sdk.createBashTool(this.projectRoot));
}
if (toolAccess.allowEdit) {
tools.push(this.sdk.createEditTool(this.projectRoot));
}
if (toolAccess.allowWrite) {
tools.push(this.sdk.createWriteTool(this.projectRoot));
}
// Always allow dolt-read for context
const { createDoltReadTool } = await import('../tui/tools/bb-dolt-read');
tools.push(createDoltReadTool(this.projectRoot));
// Build prompt with archetype system prompt
const systemPrompt = this.buildWorkerPrompt(
worker.taskId,
taskContext,
archetype?.systemPrompt
);
// ... rest of session creation
}
```
4. Update `buildWorkerPrompt` to accept optional archetype prompt:
```typescript
buildWorkerPrompt(taskId: string, taskContext: string, archetypePrompt?: string): string {
return `You are a BeadBoard worker agent.
Task ID: ${taskId}
${taskContext}
${archetypePrompt ? `## Your Specialization\n\n${archetypePrompt}` : ''}
## Instructions
Complete your assigned task. Report progress. Ask for help if blocked.
`;
}
```
---
### Task 4: Register Tools in Orchestrator
**File:** `src/lib/pi-daemon-adapter.ts`
**Changes:**
Add imports and register tools:
```typescript
import { bbListArchetypes } from '../tui/tools/bb-list-archetypes';
import { bbCreateArchetype } from '../tui/tools/bb-create-archetype';
import { bbUpdateArchetype } from '../tui/tools/bb-update-archetype';
import { bbDeleteArchetype } from '../tui/tools/bb-delete-archetype';
import { bbListTemplates } from '../tui/tools/bb-list-templates';
import { bbCreateTemplate } from '../tui/tools/bb-create-template';
import { bbUpdateTemplate } from '../tui/tools/bb-update-template';
import { bbDeleteTemplate } from '../tui/tools/bb-delete-template';
// In createTools():
tools.push(
bbListArchetypes(this.projectRoot),
bbCreateArchetype(this.projectRoot),
bbUpdateArchetype(this.projectRoot),
bbDeleteArchetype(this.projectRoot),
bbListTemplates(this.projectRoot),
bbCreateTemplate(this.projectRoot),
bbUpdateTemplate(this.projectRoot),
bbDeleteTemplate(this.projectRoot),
);
```
---
### Task 5: Tests
**File:** `tests/tui/tools/bb-archetype-crud.test.ts`
Test:
- List archetypes returns seed data
- Create archetype saves to `.beads/archetypes/`
- Update archetype modifies file
- Delete archetype removes file
- Cannot delete built-in archetypes
**File:** `tests/tui/tools/bb-template-crud.test.ts`
Test:
- List templates returns seed data
- Create template saves to `.beads/templates/`
- Update template modifies file
- Delete template removes file
- Cannot delete built-in templates
**File:** `tests/lib/worker-session-manager.test.ts`
Test:
- Coder archetype gets full tools
- Reviewer archetype gets read-only tools
- Unknown archetype defaults to read-only
- Archetype prompt injected into system prompt
---
## Files Summary
| File | Action |
|------|--------|
| `src/tui/tools/bb-list-archetypes.ts` | Create |
| `src/tui/tools/bb-create-archetype.ts` | Create |
| `src/tui/tools/bb-update-archetype.ts` | Create |
| `src/tui/tools/bb-delete-archetype.ts` | Create |
| `src/tui/tools/bb-list-templates.ts` | Create |
| `src/tui/tools/bb-create-template.ts` | Create |
| `src/tui/tools/bb-update-template.ts` | Create |
| `src/tui/tools/bb-delete-template.ts` | Create |
| `src/lib/worker-session-manager.ts` | Edit |
| `src/lib/pi-daemon-adapter.ts` | Edit |
| `tests/tui/tools/bb-archetype-crud.test.ts` | Create |
| `tests/tui/tools/bb-template-crud.test.ts` | Create |
| `tests/lib/worker-session-manager.test.ts` | Create |
---
## Estimated Effort
2-3 hours
---
## Success Criteria
- [ ] Orchestrator can list/create/update/delete archetypes
- [ ] Orchestrator can list/create/update/delete templates
- [ ] Worker with coder archetype gets edit/write/bash tools
- [ ] Worker with reviewer archetype gets read-only tools
- [ ] Archetype systemPrompt injected into worker prompt
- [ ] All tests pass
---
## Future Enhancements (Not Now)
- Fine-grained capability → tool mapping config
- Custom tool sets per archetype
- Model selection per archetype
- Archetype inheritance

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,137 @@
# Phase 4 - Multi-Surface Launch-Anywhere UX
**Status:** Planning
**Created:** 2026-03-07
**Goal:** Add spawn affordances to all UI surfaces so users can launch agents from anywhere
---
## Current Surfaces
| Surface | Location | Purpose |
|---------|----------|---------|
| Social cards | `src/components/social/` | Show beads with status, labels, assignments |
| Graph nodes | `src/components/graph/` | Show beads in dependency graph |
| Right panel | `src/components/shared/right-panel.tsx` | Contextual details when bead selected |
| Agent status panel | `src/components/agents/agent-status-panel.tsx` | Show active agents (already has spawn in orchestrator) |
---
## Discovery Tasks
### Task 1: Analyze Social Card Components
- Find all social card components
- Identify current actions/buttons
- Determine where spawn button fits
- Document available context (beadId, status, assignee, labels)
### Task 2: Analyze Graph Node Components
- Find all graph node components
- Identify current interactions
- Determine where spawn button fits
- Document available context
### Task 3: Analyze Right Panel
- Find contextual details components
- Identify where spawn makes sense
- Document available context
---
## Implementation Plan
### Step 1: Create Spawn Button Component
Create reusable spawn button that:
- Accepts beadId and context
- Shows agent type selector dropdown
- Calls orchestrator to spawn agent
- Shows loading state
- Links to Agent Status panel
**File:** `src/components/shared/spawn-agent-button.tsx`
### Step 2: Add to Social Cards
- Add spawn button to social card
- Pass beadId from card data
- Show when status is "open" or "in_progress" with no assignee
**Files:** `src/components/social/social-card.tsx`
### Step 3: Add to Graph Nodes
- Add spawn button to graph node context menu or hover
- Pass beadId from node data
- Show for unassigned beads
**Files:** `src/components/graph/graph-view.tsx`, node components
### Step 4: Add to Right Panel
- Add spawn section when viewing bead details
- Show spawn options for task/epic beads
**Files:** `src/components/shared/right-panel.tsx`
### Step 5: Wire Spawn Actions to Orchestrator
- Create API endpoint or event for spawn requests from UI
- Orchestrator receives spawn request and executes
- Update agent status panel
**Files:** `src/app/api/runtime/spawn/route.ts` or extend existing
---
## UI/UX Considerations
### Spawn Button Placement
- **Social card:** Bottom of card, next to status badge
- **Graph node:** Context menu on right-click, or hover tooltip
- **Right panel:** New section above details, when bead is unassigned
### Spawn Flow
1. User clicks "Spawn Agent" button
2. Dropdown shows agent types (Engineer, Reviewer, etc.)
3. User selects type or "Auto" (let orchestrator decide)
4. Button shows spawning state
5. Agent appears in status panel
6. Button changes to "View Agent" link
### Context Packaging
When spawning from a surface, package:
- beadId
- bead title/description
- bead status
- current assignee (if any)
- relevant labels
---
## Blocked Items
None identified yet.
---
## Success Criteria
- [ ] Spawn button appears on social cards for unassigned beads
- [ ] Spawn option available on graph nodes
- [ ] Right panel shows spawn section for task details
- [ ] Spawning from any surface creates bead and agent
- [ ] Agent status panel updates with new agent
- [ ] User can continue chatting with orchestrator while agent works
---
## Estimated Effort
4-6 hours
---
## Next Steps
1. ✅ Create plan document
2. 🔲 Run discovery on social card components
3. 🔲 Run discovery on graph node components
4. 🔲 Run discovery on right panel components
5. 🔲 Create spawn button component
6. 🔲 Integrate into surfaces

View file

@ -0,0 +1,76 @@
# Phase 5 - Agent Presence in Social/Graph Views
**Status:** Planning
**Created:** 2026-03-07
**Goal:** Show active agents in social cards, graph nodes, and make agent activity visible across the UI
---
## Current State
- Agent status panel exists in right panel (for epic/swarm context)
- Agents have display names (Engineer 01, etc.)
- Agent instances tracked in `.beads/agents.jsonl`
- No visibility in main social/graph views
---
## Implementation Plan
### Step 1: Agent Badge on Social Cards
When a bead has an active agent assigned, show:
- Agent icon/avatar
- Display name (Engineer 01)
- Status indicator (working, blocked, etc.)
**Files:**
- `src/components/social/social-card.tsx` - add agent badge
- `src/lib/types.ts` - ensure agentInstanceId on BeadIssue
### Step 2: Agent Indicator on Graph Nodes
Show agent presence on graph nodes:
- Small icon when agent assigned
- Tooltip shows agent name and status
- Color coding by status
**Files:**
- `src/components/graph/graph-view.tsx`
- Node rendering logic
### Step 3: Agent Activity in Activity Panel
If activity panel exists, show agent events:
- "Engineer 01 started working on BEAD-001"
- "Reviewer 01 completed review of BEAD-005"
**Files:**
- Check if activity panel still exists or needs rebuilding
### Step 4: Agent Filter/View
Add filter option to show only beads with active agents:
- "Show my agents" filter in social view
- Highlight beads with active work
**Files:**
- `src/components/social/social-page.tsx`
- Filter controls
---
## Blocked Items
None identified.
---
## Success Criteria
- [ ] Social cards show agent badge when agent assigned
- [ ] Graph nodes show agent indicator
- [ ] Agent status visible at a glance
- [ ] Can filter by "has active agent"
---
## Estimated Effort
2-3 hours

View file

@ -0,0 +1,75 @@
# Phase 6 - Runtime Hardening
**Status:** Planning
**Created:** 2026-03-07
**Goal:** Improve robustness of embedded Pi runtime, reconnect behavior, and error recovery
---
## Current Issues
1. Session disconnect requires manual restart
2. Stuck/hung agents have no clear diagnostics
3. Drift between TUI Pi loader and embedded Pi loader
4. No automatic recovery from failures
---
## Implementation Plan
### Step 1: Session Health Monitoring
- Add heartbeat check for orchestrator session
- Detect when session is unresponsive
- Show clear status in UI
**Files:**
- `src/lib/pi-daemon-adapter.ts` - health check
- `src/lib/embedded-daemon.ts` - monitoring
### Step 2: Automatic Reconnect
- On session disconnect, attempt reconnect
- Preserve conversation history
- Show reconnect status to user
**Files:**
- `src/lib/pi-daemon-adapter.ts`
- `src/components/shared/left-panel.tsx` - reconnect UI
### Step 3: Stuck Agent Diagnostics
- Detect agents stuck in "spawning" for too long
- Provide diagnostic information
- Allow user to cancel/retry
**Files:**
- `src/lib/worker-session-manager.ts`
- `src/components/agents/agent-status-panel.tsx`
### Step 4: Error Recovery UX
- Clear error messages when things fail
- Retry buttons for failed operations
- Logs for debugging
**Files:**
- Error handling across runtime components
- UI for error display
---
## Blocked Items
None identified.
---
## Success Criteria
- [ ] Session health monitored and shown in UI
- [ ] Automatic reconnect on disconnect
- [ ] Stuck agents detected and reported
- [ ] Clear error messages with recovery options
---
## Estimated Effort
3-4 hours

View file

@ -0,0 +1,95 @@
# Phase 7 - Tests and Verification
**Status:** Planning
**Created:** 2026-03-07
**Goal:** Add comprehensive tests for embedded Pi runtime and agent system
---
## Test Categories
### 1. Unit Tests
**Runtime Path Resolution:**
- `pi-runtime-detection.test.ts` - SDK detection, path resolution
- `bb-pi-bootstrap.test.ts` - bootstrap process
**Event Projection:**
- `embedded-daemon.test.ts` - event emission, deduplication
- `orchestrator-chat.test.ts` - message projection
**Worker Session:**
- `worker-session-manager.test.ts` - spawn, status, lifecycle
### 2. Contract Tests
**Adapter Schemas:**
- Pi SDK adapter input/output contracts
- Runtime event schema validation
### 3. Integration Tests
**Orchestrator Flow:**
- Session creation
- Prompt submission
- Tool execution
- Response handling
**Worker Flow:**
- Worker spawn
- Bead claim/update/close
- Result retrieval
### 4. UI Tests
**Left Panel:**
- Chat rendering
- Message projection
- Error display
---
## Implementation Plan
### Step 1: Unit Test Setup
- Configure test runner (Jest or Vitest)
- Create test utilities for mocking Pi SDK
**Files:**
- `tests/setup.ts`
- `tests/mocks/pi-sdk.ts`
### Step 2: Runtime Unit Tests
- Test path detection
- Test bootstrap process
- Test event deduplication
### Step 3: Worker Unit Tests
- Test spawn flow
- Test status tracking
- Test result collection
### Step 4: Integration Tests
- Test full orchestrator flow
- Test worker-to-bead workflow
---
## Blocked Items
None identified.
---
## Success Criteria
- [ ] Unit tests for runtime components pass
- [ ] Unit tests for worker session manager pass
- [ ] Integration tests for orchestrator flow pass
- [ ] Integration tests for worker flow pass
---
## Estimated Effort
4-5 hours

View file

@ -0,0 +1,159 @@
# Phase 4 Handoff Summary
**Branch:** `docs/embedded-pi-prd`
**PR:** https://github.com/zenchantlive/beadboard/pull/new/docs/embedded-pi-prd
---
## Current Status
### Phase 4: Launch-Anywhere UX - **IN PROGRESS**
**Completed by subagents (9 of 17 tasks):**
| Task | Description | Status |
|------|-------------|--------|
| 1 | useAgentStatus hook | ✅ Done |
| 2 | useSpawnAgent hook | ✅ Done |
| 3 | Hooks index | ✅ Done |
| 4 | AgentPickerPopup | ✅ Done |
| 5 | AgentAssignButton | ✅ Done |
| 6 | AgentSpawnButton | ✅ Done |
| 7 | AgentActionRow | ✅ Done |
| 8 | Agents index | ✅ Done |
| 9 | SocialCard integration | ✅ Done |
| 10 | GraphNodeCard integration | ⏳ NOT DONE |
| 11 | BlockedTriageModal integration | ⏳ NOT DONE |
| 12 | Spawn API endpoint | ✅ Done |
| 13 | Assign-agent API | ✅ Done |
| 14 | Update useAgentStatus (real data) | ⏳ NOT DONE |
| 15 | Worker status API | ✅ Done |
| 16 | BeadIssue type update | ✅ Done |
| 17 | Testing | ⏳ NOT DONE |
### Remaining Tasks
**Task 10: Add AgentActionRow to GraphNodeCard**
- File: `src/components/graph/graph-node-card.tsx`
- Add `import { AgentActionRow } from '../agents';`
- Add `projectRoot` prop
- Replace old rocket with `<AgentActionRow />`
**Task 11: Add AgentActionRow to BlockedTriageModal**
- File: `src/components/shared/blocked-triage-modal.tsx`
- Add import and component
**Task 14: Update useAgentStatus to fetch real data**
- File: `src/components/agents/hooks/use-agent-status.ts`
- Poll `/api/runtime/worker-status?beadId=X` every 5 seconds
**Task 17: Test the complete flow**
---
## Files Created (Phase 4)
```
src/components/agents/
├── agent-action-row.tsx # Combined assign + spawn
├── agent-assign-button.tsx # 👤 Icon + picker
├── agent-spawn-button.tsx # 🚀 Icon with colors
├── agent-picker-popup.tsx # Agent selection dropdown
├── index.ts # Exports
└── hooks/
├── use-agent-status.ts # Worker status tracking
├── use-spawn-agent.ts # Spawn API calls
└── index.ts
src/app/api/runtime/
├── spawn/route.ts # POST to spawn worker
└── worker-status/route.ts # GET worker status by beadId
src/app/api/beads/
└── assign-agent/route.ts # POST to assign agent type
```
## Files Modified (Phase 4)
```
src/components/social/social-card.tsx # Integrated AgentActionRow
src/components/social/social-page.tsx # Pass projectRoot
src/lib/social-cards.ts # Added agentTypeId
src/lib/types.ts # Added agentTypeId/agentInstanceId
```
---
## How the Two-Icon System Works
**Icon 1: 👤 Assign (UserPlus)**
- Opens agent picker popup
- Select agent type → assigns to bead
- Planning action (no spawn)
**Icon 2: 🚀 Spawn (Rocket)**
- **Blue** = Ready to spawn (has agentTypeId)
- **Green pulsing** = Worker active
- **Red** = Worker blocked
- **Checkmark** = Worker completed
- Click spawns the worker
---
## Rocket Colors
| Color | State | Meaning |
|-------|-------|---------|
| Hidden | No agentTypeId | No agent assigned |
| Blue | idle + agentTypeId | Ready to spawn |
| Blue pulsing | spawning | Spawning in progress |
| Green pulsing | working | Worker actively working |
| Red | blocked | Worker stuck |
| Green checkmark | completed | Worker finished |
---
## Next Session Tasks
1. **Task 10:** Add AgentActionRow to graph-node-card.tsx
2. **Task 11:** Add AgentActionRow to blocked-triage-modal.tsx
3. **Task 14:** Make useAgentStatus poll real API
4. **Task 17:** Test complete flow
---
## Key Files to Read
| File | Purpose |
|------|---------|
| `docs/plans/2026-03-08-phase-4-implementation.md` | Full implementation plan |
| `docs/plans/2026-03-05-embedded-pi-roadmap.md` | Overall roadmap |
| `src/components/agents/agent-action-row.tsx` | Main component |
| `src/components/agents/hooks/use-agent-status.ts` | Status tracking |
| `src/app/api/runtime/spawn/route.ts` | Spawn API |
---
## Pre-existing TypeScript Errors (Not Related to Phase 4)
```
src/components/shared/left-panel-new.tsx - LeftPanelFilters not exported
src/components/shared/unified-shell.tsx - Type mismatches
src/tui/tools/bb-deviation.ts - RuntimeEventKind mismatch
```
These existed before Phase 4 work and should be fixed separately.
---
## Commit History (Phase 4)
```
4a7425c feat: integrate AgentActionRow into SocialCard
547b565 feat: add agents components index
209807e feat: add AgentSpawnButton with color states
aedeb07 feat: add spawn API endpoint
20a3eb1 feat: add worker-status API endpoint
09928a8 feat: add useSpawnAgent hook
4e03654 feat: add useAgentStatus hook interface
d84770c docs: add Phase 4 implementation plan
```

File diff suppressed because it is too large Load diff