- Add MessageSquare icon to GraphNodeCard; prop-thread onConversationOpen
and selectedTaskId through WorkflowGraph node data (no useUrlState
inside ReactFlow nodes — avoids context/timing issues)
- Fix ContextualRightPanel: check taskId before epicId so clicking the
conversation icon always opens ThreadDrawer even when an epic filter
is active
- setEpicId now clears task from URL so selecting an epic resets any
open conversation thread
- handleGraphSelect toggles: second click on same node calls setTaskId(null)
closing the right panel
- Add onSelect to WorkflowGraph flowModel deps to prevent stale callbacks
- Fix ContextualRightPanel onClose no-ops: wired to setTaskId(null) /
setSwarmId(null) so back button works
- Right panel always visible (removed panel==='open' gate in UnifiedShell)
- SmartDag task grid: horizontal scroll, fixed-width cards, hideClosed=true
- Add <Suspense> in page.tsx for useSearchParams compatibility
- Enable dolt auto-start in .beads/config.yaml
- Add 14 static analysis tests (graph-node-conversation.test.tsx)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/lib/read-issues-dolt.ts: readIssuesViaDolt() queries issues+labels (GROUP_CONCAT)
and dependencies in 2 SQL queries; normalizes Date cols to ISO strings; returns null
on unreachable so caller can fall back gracefully
- src/lib/read-issues.ts: readIssuesFromDisk() tries Dolt first (always), falls back to
issues.jsonl with console.warn; removes dead readIssuesViaBd/normalizeBdIssue/
normalizeDependencies code now that the CLI path is superseded
- AGENTS.md: documents new Dolt read path + SSE watcher trigger; removes stale
manual issues.jsonl re-export instructions (no longer needed)
Verified: bd writes update last-touched → chokidar fires → syncActivity → Dolt query
→ snapshot diff → SSE push. 146/146 tests pass, lint clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- src/lib/dolt-client.ts: getDoltConnection(projectRoot) returns cached mysql2 Pool
- Reads host/port/database from .beads/metadata.json (no hardcoded values)
- DoltConnectionError typed error for missing metadata or unreachable server
- Tests connectivity on first connection; caches pool per resolved projectRoot
- connectionLimit: 5 for Next.js server-side concurrency
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- NEXT_SESSION_PROMPT.md: full context for Dolt mysql2 integration
including schema, current read path, normalization approach, watcher
concern, skills to use, and files to read
- mysql2 installed (beadboard-550.1 in_progress)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- AGENTS.md: add Data Backend & Platform Notes section explaining
single-platform vs mixed WSL2+Windows setup, mirrored networking
workaround, and manual issues.jsonl re-export step
- Creates beadboard-550 (Dolt mysql2 epic) to track long-term fix
- Note: mirrored networking is explicitly scoped as a mixed-env
workaround, not a requirement for single-platform contributors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phase 0:
- UnifiedShell: pass blockedOnly to SocialPage; wire TopBar with live counts
- thread-drawer: show real issue.status instead of hardcoded "In Progress"
- social-page: fix onJumpToActivity to open right panel (not dead ?view=activity)
Phase 1:
- contextual-right-panel: add taskId branch (ThreadDrawer embedded) and swarmId
branch (MissionInspector via SwarmIdBranch inner component); ActivityPanel
remains the no-selection fallback
All 207 tests pass; no new typecheck errors.
Closes beadboard-r1i (Phase 1: Contextual Right Panel)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Aurora: Real northern lights colors (teal/violet on deep blue-black)
- Midnight: Deep ocean blues with violet and cyan
- Forest: Rich forest greens with golden sunlight
- Dusk: Warm sunset oranges and corals
- Contrast: Pure black with neon accents
- Light: Clean professional light mode (NEW)
All themes have:
- Consistent status colors (green/amber/red)
- Distinct surface layers for visual hierarchy
- Theme-appropriate accent glows
- Improved contrast and accessibility
- Replace hardcoded blue radial gradient with theme variable
- Update graph-view to use new token system
- Ensure status colors (red/green/amber) remain consistent across all themes
- DAG background now changes with theme while maintaining card visibility
- Create ThemeToggle component with dropdown menu
- Shows all 5 themes with descriptions
- Persists choice to localStorage
- Updates data-theme attribute instantly
- Add palette icon to top bar
- aurora: Warm charcoal with cyan accents (fixed/improved)
- midnight: Cool blue-purple with violet accents
- forest: Earthy green-brown with lime accents
- dusk: Warm purple-brown with orange/pink accents
- contrast: Pure black with neon accents (high contrast)
All themes use the same 12-category token system for consistency.
Switch themes by changing data-theme attribute on html element.
Resolved conflicts:
- .gitignore: kept both bd.sock.startlock and .beadboard/ entries
- package.json: kept feature branch test script (explicit enumeration)
- API routes: kept dynamic export + isValidProjectRoot from main
- globals.css: kept HEAD slideInFromRight animation
- use-beads-subscription.ts: kept HEAD onopen handler
- realtime.ts: kept main console.log in emit()
- snapshot-differ.ts: kept main type-aware dependency diff
Blue colors preserved from feature branch.
Documents BeadBoard architecture, commands, verification gates,
data flow, key directories, and Windows considerations for
AI assistants working on this codebase.
- Add Epic Template section when an epic is selected
- Show template name, description, and team roster
- Template picker applies template to epic via metadata
- Add Remove Template functionality
- getTemplateId helper reads from metadata.templateId
- Task Assignment section only shows for non-epic tasks
- Collapsible sections for Needs Agent, Pre-assigned, Squad Roster
- Add metadata field to UpdateMutationPayload
- Add asOptionalMetadata validation function
- Pass --metadata flag to bd update command
- Enables storing custom data like templateId on issues
- ArchetypePicker: Full-screen modal with backdrop blur, 2-column grid,
Select/Edit/Create actions, 800px width for readability
- TemplatePicker: Same pattern with team size indicator and built-in badge
- Both pickers support backdrop click-to-close and keyboard navigation
- Add templateId: string | null to BeadIssue (links epics to templates)
- Add icon field to AgentArchetype for emoji/icon display
- Add color and icon fields to SwarmTemplate for visual customization
- Rename coder.json to engineer.json with enhanced 300+ line system prompt
- Add reviewer.json for code review specialist
- Add tester.json for test engineer
- Add investigator.json for debugging/investigation
- Add shipper.json for release/deployment
- Update architect.json with detailed workflow phases
Each archetype includes:
- Role definition and capabilities
- Workflow phases with specific actions
- Handoff protocols
- Example interactions
## Design Decision
Per bd (bead) system design, a task should have only ONE agent archetype
assigned at a time. This provides clear ownership and simpler mental model.
## What Changed
When assigning a new archetype:
1. Remove any existing agent: labels first (DELETE API)
2. Then add the new agent: label (POST API)
3. Optimistic UI updates to match
## Why This Makes Sense
- Clear ownership: 'Who's working on this?'
- Simpler coordination between tasks
- Matches how bd/agent orchestration is intended to work
- Reassigning is still possible (just click a different archetype)
## UI Behavior
- If task has 'coder' assigned, clicking 'architect' will:
1. Remove 'coder' label
2. Add 'architect' label
- Dropdown shows 'Assigned' badge on current archetype
- X button still available to unassign completely
## Test Coverage
Added graph-node-single-archetype.test.tsx with 5 tests:
- Removes existing labels before adding new
- Calls DELETE before POST
- Only allows one archetype per task
- Preserves non-agent labels
- Returns early if same archetype clicked
## The Bug
User reported: 'An archetype can only exist on one task at a time - when
I try to make the next task have the same arch, it deleted the one I
added prior.'
## Root Cause
The SSE subscription (useBeadsSubscription) refreshes data from the server
whenever ANY change happens. When user assigns an archetype:
1. User clicks assign -> optimistic update adds label locally
2. SSE fires (from previous operation or heartbeat) -> fetches fresh data
3. useEffect syncs localLabels with data.labels (which doesn't have the
new label yet)
4. Label disappears from UI
5. Eventually API completes and another SSE refresh brings it back
This race condition causes labels to flicker or disappear entirely.
## The Fix
Track pending optimistic labels in a useRef Set, and merge them with
incoming server data during sync:
1. pendingOptimisticLabels = useRef<Set<string>>(new Set())
2. When optimistically adding: add to pending set
3. useEffect merge: combine server labels + pending labels
4. After API completes: remove from pending set
This ensures optimistic labels survive SSE refreshes.
## Test Coverage
Added graph-node-labels-optimistic.test.tsx with 10 tests:
- Uses useRef for tracking
- Tracks in a Set
- Preserves labels during sync
- Adds/removes from pending set
- Handles multiple concurrent operations
- Per-node state isolation
## Verification
- typecheck: pass
- lint: pass (0 errors)
- test: all pass
Various supporting changes made during the assign archetypes feature development:
- Added contextual-right-panel.tsx and swarm-command-feed.tsx
- Updated activity-panel.tsx with new features
- UI improvements to left-panel, mobile-nav
- Test updates for url-state-integration, mobile-nav, top-bar
- Package.json updates for dependencies
- Global CSS refinements
These changes support the main assign archetypes feature but are
not directly part of its core functionality.
This document captures our collaboration journey, including bugs found,
decisions made, and honest assessment of what went well and what didn't.
Key points:
- Optimistic updates were essential for good UX
- User caught two bugs during review (DELETE method, epic filter)
- Test coverage helped ensure correctness throughout
## Context
This commit adds the supporting infrastructure that makes the assign
feature work end-to-end.
## Components Added/Modified
### SmartDag
- Main view component for graph-based task management
- Integrates TaskCardGrid and WorkflowGraph
- Has 'Assign' mode toggle button
- Passes archetypes and assignMode to WorkflowGraph
- Manages filter state (hideClosed, sortReadyFirst, etc.)
### useGraphAnalysis Hook
- Extracted graph analysis logic for reuse
- Returns: actionableNodeIds, cycleNodeIdSet, blockerTooltipMap, etc.
- Used by both SmartDag and AssignmentPanel
- Ensures consistent 'actionable' definition across components
### UnifiedShell
- Added assignMode state
- Added selectedAssignIssue state
- Renders AssignmentPanel when in graph view + assign mode
- Wires up onAssignModeChange and onSelectedIssueChange callbacks
## Design Philosophy
- Shared hook means single source of truth for 'actionable'
- Clean separation between view (SmartDag) and sidebar (AssignmentPanel)
- URL state preserved for navigation
## Test Coverage
- SmartDag tests: 12 tests covering buttons, callbacks, imports
- useGraphAnalysis tests: 6 tests covering cycle detection, blockers
- UnifiedShell tests: 9 tests covering state and rendering