Commit graph

28 commits

Author SHA1 Message Date
Viktor Barzin
394a771b67 [beadboard] Add Dispatch-to-Agent button and prompt template
## Context

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

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

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

## This change

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

## What is NOT in this change

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

## Test Plan

### Automated

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

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

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

### Manual Verification

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:04:34 +00:00
Viktor Barzin
845e90d7c0 [beadboard] Add quality filters for acceptance criteria and description length
## Context

The left-panel task list surfaces every bead regardless of whether the task
has been specified thoroughly enough for an agent to pick it up. Tasks with
empty `acceptance_criteria` or very short descriptions are low-signal noise
that muddles the navigation spine — especially now that we plan to dispatch
tasks to Claude agents (which need concrete instructions to succeed).

Epics are deliberately exempt: their role is grouping, not execution, so
requiring acceptance criteria / long descriptions on epics would hide the
entire backbone of the navigation.

## This change

- Plumbs `acceptance_criteria` end-to-end: adds the optional field on
  `BeadIssue`, and reads it both from `.beads/issues.jsonl` (parser) and
  Dolt SQL (`read-issues-dolt.ts` row shape + normalizer).
- Extends `LeftPanelFilters` with `hideNoAcceptance` and
  `hideShortDescription` (both default `true`) in the source-of-truth
  `hooks/use-url-state.ts` and in the re-exported shadow type on
  `components/shared/left-panel.tsx`.
- Updates `isTaskMatch` in both `left-panel.tsx` and `left-panel-new.tsx`
  to skip non-epic tasks lacking acceptance criteria or with a description
  shorter than `SHORT_DESCRIPTION_MIN_LENGTH` (200 chars). Epics bypass
  both filters via the `issue_type === 'epic'` guard.
- Exposes `isTaskMatch` from `left-panel.tsx` so the filter tests can
  assert behavior directly (previously only `shouldHideEpicEntry` was
  exported).
- Adds two checkboxes under the existing "Hide Closed" button in both
  left-panel variants (legacy `left-panel.tsx` and the one unified-shell
  currently wires up — `left-panel-new.tsx`).
- Seeds both new filter flags as `true` in the `UnifiedShell` default
  state so fresh sessions see the high-signal view without toggling.

## What is NOT in this change

- No mutation of `bd` / CLI behavior. Filters are purely UI-level.
- No localStorage persistence for the two new flags — existing
  `hideClosed` is also React-only, so parity is preserved. If/when we
  persist any of these, all three move together.
- No change to the `metadata.acceptance` path used by `kanban.ts`'s
  `hasQualitySignal` — that's a separate signal with its own callers.

## Test Plan

### Automated

Tests run from `/home/wizard/code/beadboard`:

```
$ node --import tsx --test tests/components/shared/left-panel-filtering.test.ts
# tests 15
# pass 15
# fail 0
# duration_ms 604
```

All 15 filter cases pass: 6 pre-existing `shouldHideEpicEntry` cases plus
9 new `isTaskMatch` cases covering acceptance-criteria-empty hides,
acceptance-criteria-disabled shows, epic exemption, 199/200-char
description boundary, null description, and short-description flag
disabled.

Related suites still green:

```
$ node --import tsx --test tests/components/shared/left-panel.test.tsx \
    tests/components/shared/unified-shell-hide-closed-contract.test.ts
# tests 7 pass 7 fail 0
```

Pre-existing failures in `tests/hooks/url-state-integration.test.ts`
(`view=activity` cases) and one pre-existing typecheck error in
`left-panel.tsx` thread prop are unrelated — both reproduce on `main`
before this change.

### Manual Verification

1. `npm install`
2. `npm run dev`
3. Open `http://localhost:3000` with bd project loaded.
4. Expected: two new checkboxes appear under "Hide Closed" in the left
   sidebar — "Hide tasks without acceptance criteria" and
   "Hide tasks with short description (<200 chars)". Both checked by
   default.
5. Toggle each off. Expected: additional beads appear in epic expansions
   (tasks that were previously hidden because they lack quality signal).
6. Confirm epics remain visible regardless of the checkbox state.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 14:00:51 +00:00
ZenchantLive
b5db7a7753 checkpoint: pre-split branch cleanup 2026-03-03 16:43:42 -08:00
zenchantlive
c8c91736b8 fix: remove buildProjectContext usage causing build error 2026-03-01 21:22:46 -08:00
zenchantlive
29eefaf7ec feat: add BlockedTriageModal component with tests
- Create BlockedTriageModal component at src/components/shared/blocked-triage-modal.tsx
- Implements modal with blocked task triage functionality
- Uses deriveBlockedIds and buildBlockedByTree from kanban lib
- Each row shows blocker chain and has inline archetype picker
- Modal is scrollable and closes via Escape/close button
- Add corresponding tests at tests/components/blocked-triage-modal.test.tsx
- Register test in package.json test script
2026-03-01 21:12:46 -08:00
zenchantlive
c246ceaf21 feat(ux): consolidate Launch Swarm + telemetry UX with minimized strip
- Removed broken LaunchSwarmDialog (formula-based) from TopBar/LeftPanel
- All Rocket buttons (TopBar, LeftPanel, DAG nodes, social cards) now open
  AssignmentPanel (archetype-based) which actually works
- Every Rocket clears taskId first so assignMode && !taskId condition passes
- Conversation button priority: taskId always shows conversation, not assign panel
- Added TelemetryStrip: minimized right sidebar with status dots when non-telemetry
  panel (conversation/assignment) is active
- Live feed has minimize button → restores last taskId or assignMode
- DAG nodes: Signal icon → restores telemetry feed
- Social button on DAG nodes: single router.push to avoid race (setView + setTaskId)
- Fixed social card message button: opens right panel with drawer:closed (no popup)

Co-Authored-By: Oz <oz-agent@warp.dev>
2026-03-01 18:17:58 -08:00
ZenchantLive
861ae89491 fix: wire conversation panel to DAG nodes with toggle support
- 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>
2026-03-01 13:51:46 -08:00
zenchantlive
211e503409 feat(graph): enforce single archetype per task
## 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
2026-02-24 17:04:44 -08:00
zenchantlive
bd3b3da30a fix(graph): prevent SSE overwrites of optimistic label updates
## 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
2026-02-24 16:48:16 -08:00
zenchantlive
fbfe393f6d chore: checkpoint related UI improvements and supporting components
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.
2026-02-24 16:25:45 -08:00
zenchantlive
93b3c33976 feat(core): add SmartDag and supporting infrastructure for assign mode
## 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
2026-02-24 16:16:10 -08:00
zenchantlive
308a7d9b31 feat(ui): add AssignmentPanel with Needs Agent, Pre-assigned, Squad Roster
## The Feature Request
User wanted an enhanced sidebar panel showing:
- Tasks needing agents (ready but unassigned)
- Pre-assigned tasks waiting to start
- Active workers on current epic

## Design Collaboration
We discussed what each section should show:
1. **Needs Agent**: Actionable tasks (no blockers) without agent: label
2. **Pre-assigned**: Tasks with agent: label, not yet in_progress
3. **Squad Roster**: in_progress tasks with assignee

## Technical Implementation
- Uses useGraphAnalysis hook for actionableNodeIds
- Helper functions: hasAgentLabel(), getAgentLabels(), extractArchetypeIdFromLabel()
- Quick assign dropdown on each 'Needs Agent' item
- Archetype badges shown on 'Pre-assigned' items

## UI/UX Decisions
- Each section has count badge in header
- Max-height with scroll for each section
- Consistent styling with existing panel patterns
- Uses CSS variables for theming

## Test Coverage
- Added assignment-panel-sections.test.tsx with 5 TDD tests
- Tests verify: useGraphAnalysis import, section headers, filtering logic

## Beads: beadboard-b7t (closed)
2026-02-24 16:15:35 -08:00
zenchantlive
512a836db4 feat(graph): add Assign button and archetype dropdown to GraphNodeCard
## The Collaboration Story
User requested ability to assign agent archetypes to tasks directly from
graph nodes. This was the core UI feature request.

## Design Decisions Made Together
1. **Placement**: We decided to put the assign UI at the bottom of the card
   to not interfere with existing status/badges display
2. **Pattern**: Used Radix dropdown-menu (already in project) for consistency
3. **Visual feedback**: Added loading spinner during API calls, success/error
   messages that auto-dismiss
4. **Closed tasks**: Excluded closed tasks from assignment (logical constraint)

## Issues We Encountered
- Initially only added POST handler for assignment
- User pointed out we needed DELETE for unassign - added that
- The unassign button (X) needed to call DELETE not POST

## API Changes
- Added DELETE handler to /api/swarm/prep for removing agent assignments
- Uses 'bd label remove' under the hood

## What the UI Shows
- Dropdown with available archetypes
- Badge showing assigned archetype name with color
- X button to unassign (on each badge)
- 'Assigned' label on already-assigned archetypes in dropdown

## Test Coverage
- Added graph-node-assign.test.tsx with 6 TDD tests

## Beads: beadboard-brq (closed)
2026-02-24 16:14:56 -08:00
zenchantlive
164b26e570 feat(graph): pass labels through WorkflowGraph to enable agent assignment display
## Context
This is the foundation commit for the 'Assign Archetypes to Tasks' feature.
We needed a way to display which agents are assigned to tasks directly on
the graph nodes.

## Decision Process
- User wanted to see agent assignments on DAG nodes
- We discovered that labels (including 'agent:archetype-id' format) weren't
  being passed through the WorkflowGraph component
- Added 'labels' and 'archetypes' to GraphNodeData interface

## What Changed
- WorkflowGraph now passes issue.labels to each node's data
- GraphNodeData interface updated to include labels: string[]
- Added archetypes prop for dropdown population

## Test Coverage
- Added graph-node-labels.test.tsx with 4 passing tests

## Beads: beadboard-yo5 (closed)
2026-02-24 16:14:39 -08:00
zenchantlive
a03def1ca1 chore: checkpoint before DAG views UX overhaul 2026-02-22 20:43:59 -08:00
zenchantlive
654f73f83d feat(swarm): modify unified-shell to render swarm layout 2026-02-20 17:25:05 -08:00
zenchantlive
b721073585 feat(swarm): modify unified-shell to render swarm layout 2026-02-20 17:15:05 -08:00
zenchantlive
f03cd13d87 feat(swarm): implement swarm workspace container component 2026-02-20 17:13:12 -08:00
zenchantlive
f35ae8df33 feat(swarm): implement mission picker for left panel 2026-02-20 17:12:01 -08:00
zenchantlive
395f90ed2a feat(ui3): elegant earthy task feed redesign 2026-02-16 23:20:47 -08:00
zenchantlive
9c703072d1 fix: truncate SocialCard dependencies, refine SocialPage layout 2026-02-16 22:48:36 -08:00
zenchantlive
c74a4098e7 refactor: BaseCard hard style shadow, SocialCard blocking lists, AgentAvatar ZFC states 2026-02-16 22:41:56 -08:00
zenchantlive
4efc461c1e feat(ui): add view components for Social, Swarm, and Graph (bb-ui2.11, .16, .20)
STORY:
With the shell layout complete, we needed the actual content for each view.
Three agents worked in parallel on the card components that would populate
the Social and Swarm views, plus integrating the existing graph into the shell.

COLLABORATION:
Agent bb-98c (social-card-builder) created SocialCard:
- Task ID with teal styling
- UNLOCKS section (green) showing what this task unblocks
- BLOCKS section (amber) showing what's blocking this task
- Agent avatars with liveness glow
- View-jump icons for quick navigation

Agent bb-nuy (swarm-card-builder) created SwarmCard:
- Agent roster with liveness indicators
- Progress bar (ASCII block format: ████████░░░░)
- Attention items with warning styling
- View-jump icons

Agent bb-54x (graph-integrator) integrated WorkflowGraph:
- Created GraphView wrapper with Flow/Overview tabs
- Wired into UnifiedShell when view=graph
- Connected taskId to selectedId for URL sync
- Connected graphTab to URL state

DELIVERABLES:
- src/components/social/social-card.tsx: Task card for activity feed
- src/components/swarm/swarm-card.tsx: Swarm health card
- src/components/graph/graph-view.tsx: Graph wrapper with tabs
- src/components/shared/mobile-nav.tsx: Bottom tab bar
- Tests for all components

VERIFICATION:
- npm run typecheck: PASS
- npm run lint: PASS
- npm run test: PASS

CLOSES: bb-ui2.11, bb-ui2.16, bb-ui2.20
2026-02-15 23:21:20 -08:00
zenchantlive
ce8fdd0d4c feat(ui): complete shell layout components (bb-ui2.6, .7, .8, .9, .27)
STORY:
Phase 1 of the Unified UX epic required a complete 3-panel shell layout
with responsive behavior across mobile, tablet, and desktop breakpoints.
The existing page structure was fragmented - we needed a cohesive shell.

COLLABORATION:
Three agents (bb-5am, bb-dwz, bb-3dv) worked in parallel on:
- TopBar: View tabs (Social/Graph/Swarm) with active states, filter input
- LeftPanel: Channel tree navigation with epic filtering, responsive collapse
- RightPanel: Detail strip with sidebar (desktop) / drawer (tablet/mobile) modes

We encountered a hydration mismatch error on mobile/tablet because
useResponsive was returning different values on server vs client.
Fixed by defaulting to desktop on server and only updating after mount.

Mobile navigation (bb-ui2.27) added:
- Hamburger menu for left panel access on mobile/tablet
- Bottom tab bar for thumb-friendly view switching

DELIVERABLES:
- src/components/shared/top-bar.tsx: TopBar with view tabs + hamburger
- src/components/shared/left-panel.tsx: Epic tree with expand/collapse
- src/components/shared/right-panel.tsx: Responsive sidebar/drawer
- src/components/shared/unified-shell.tsx: Main 3-panel grid layout
- src/components/shared/mobile-nav.tsx: Bottom tab bar for mobile
- src/hooks/use-responsive.ts: Breakpoint detection (mobile/tablet/desktop)
- Tests for all components

VERIFICATION:
- npm run typecheck: PASS
- npm run lint: PASS
- npm run test: PASS

CLOSES: bb-ui2.6, bb-ui2.7, bb-ui2.8, bb-ui2.9, bb-ui2.27
2026-02-15 23:19:52 -08:00
zenchantlive
173937c1f3 chore: add utility scripts and additional test coverage
STORY:
Development requires supporting scripts and comprehensive test coverage.
This commit adds utility scripts and extends test suites.

COLLABORATION:
- scripts/capture-sessions.mjs: Screenshot capture for sessions hub
- scripts/capture-timeline.mjs: Timeline view capture utility
- sessions-header-logic.ts: Session header business logic
- Additional test files for sessions, hooks, and snapshot diffing
2026-02-15 21:19:31 -08:00
zenchantlive
544a46427b feat(sessions): complete bb-buff.3.4 - Role-Based Color Coding
STORY:
In a multi-agent control center, operators need to quickly identify
what TYPE of agent they're looking at - UI agents, graph agents,
orchestrators, or general workers.

COLLABORATION:
We implemented role-based border colors on agent avatars:
- ui agents: blue border
- graph agents: green border
- orchestrators: purple border
- default/other: gray border

The agent-station component now displays these colors, making it
instantly visible what role each agent plays in the swarm.

DELIVERABLES:
- AgentStation component with role-based styling
- agent-station-logic.ts with role color derivation
- Tests: agent-station-logic.test.ts updated and passing

VERIFICATION:
- typecheck: PASS
- lint: PASS
- test: PASS

CLOSES: bb-buff.3.4
2026-02-15 21:16:08 -08:00
zenchantlive
0d73d2afaf feat(sessions): complete bb-buff.3.2 - Critical Visual Signals
STORY:
The Sessions Hub needed clear visual distinction between healthy
agents and those in trouble. Users couldn't quickly identify stuck
or dead agents in the control center view.

COLLABORATION:
We added 'stuck' and 'dead' states to the AgentSessionState type,
created deriveSessionState() with Zero-Failure-Check priority,
and implemented restrained visual treatments:
- stuck: pulsing red border (ring-2 ring-red-500 animate-pulse)
- dead: strong ghosting (opacity-40 grayscale)
- evicted: milder ghosting (opacity-60 grayscale-[0.5])

Session cards now display STUCK/OFFLINE badges with aria-labels
for accessibility.

DELIVERABLES:
- AgentSessionState extended with stuck/dead states
- deriveSessionState() derives from ZFC state priority
- Visual treatments for stuck/dead/evicted
- Accessible badges with aria-label

TESTS:
- tests/lib/agent-sessions-state.test.ts: 6/6 PASS
- tests/components/shared/status-utils-visual.test.ts: 4/4 PASS
- tests/components/sessions/session-feed-card-state.test.tsx: 4/4 PASS

CLOSES: bb-buff.3.2
BLOCKS: bb-buff.3.3
2026-02-15 21:15:28 -08:00
zenchantlive
c7c3a25457 docs(beads): etch project history into memory bank and finalize skill-bb
We completed the 'Deep Metadata Etch' today, transforming our Beads issues from simple trackers into a permanent narrative of our collaboration.

Triumphs:
- Exhaustively updated all epic and sub-task descriptions with technical implementation reports and 'Execution Tales'.
- Finalized the 'bb' agent CLI skill (bb.ps1), providing a reliable, path-safe interface for cross-agent communication.
- Published ADR-001 and RFC-001 to document our coordination protocols.
- Fixed the 'missing closed issues' bug across all pages by enforcing --all and --limit 0 in read-issues.ts.

Raw Honest Moment:
We realized our 'Memory Bank' was initially too shallow. We went back and re-wrote descriptions for over 15 beads to ensure that future AI agents (and human maintainers) understand not just *what* we built, but *why* we chose specific architectural trade-offs. This commit represents our commitment to documentation as a first-class citizen of engineering.
2026-02-14 00:21:25 -08:00