Component Inventory
React 19 components built on Next.js 16 App Router. Server Components load data; Client Components subscribe to SSE for live state.
Pages
Each Next.js App Router page is a Server Component that loads data then hands off to Client Components for interactivity.
Renders <RepoView> kanban board for the selected repo.
- listRepoOptions
- resolveSelectedRepoId
- loadBoardData
- listOpenBatches
- 8 getConfig calls
Fully static. No data loaded. Pipeline stages table, label reference, and skills table.
Renders RepoListForm, GitHubTokenForm, ConfigForm, WipeDatabase.
- listRepos
- 19 getConfig calls
- resolveSelectedRepoId
Renders DocsPageView (client, markdown editor).
- resolveSelectedRepoId
Renders IssuesView (client, full-featured issue management).
- resolveSelectedRepoId
- listInternalIssues
- listBatchesWithIssues
- loadBoardData
Renders WorkersLive in CostSettingsProvider.
- listRepoOptions
- listWorkers
- 9 getConfig calls
- getLatestResourceSample
Renders WorkerReport in CostSettingsProvider.
- loadWorkerReport
- 5 getConfig calls
Renders AgentsLive.
- loadAgentRows
- discoverSkills
- listRepos
- resolveSelectedRepoId
Metadata card, optional report pre, AgentLog, optional RunKillButton.
- getRun
UI Primitives
Reusable atoms in src/app/_components/ui/. Build all feature UI from these to stay consistent with the design system.
| Component | File | Key Props | Description |
|---|---|---|---|
Badge |
badge.tsx |
tone: BadgeTone, color?: string |
Tinted pill. Uses color-mix for tinted background/text. |
Button |
button.tsx |
variant, size, busy?, busyLabel?, leftIcon?, rightIcon?, iconOnly? |
Shows spinner when busy. Exports buttonClasses() for anchor styling. |
Card |
card.tsx |
children |
Simple surface wrapper with padding/border. |
ConfirmationDialog |
confirmation-dialog.tsx |
title, description, onConfirm, onCancel, open |
Modal for destructive confirmations. |
EmptyState |
empty-state.tsx |
title, description?, action? |
Centered empty with optional action slot. |
ErrorState |
error-state.tsx |
message? |
Error display for failed data loads. |
InlineError |
inline-error.tsx |
error, title?, truncate? |
Inline error with tooltip on truncation. |
INPUT_CLASS |
input-class.ts |
(exported CSS string) | Apply to inputs to match design system. |
LINK_CLASS |
link-class.ts |
(exported CSS string) | For anchor styling. |
Markdown |
markdown.tsx |
children: string |
Renders markdown to HTML. |
Menu / MenuItem |
menu.tsx |
Menu: label, children; MenuItem: onClick, separated? |
Dropdown. separated adds visual divider. |
PageHeader |
page-header.tsx |
title, subtitle?, actions? |
Page-level title/subtitle/actions header. |
PageSectionHeading |
page-section-heading.tsx |
title, count? |
Section heading with numeric count badge. |
SectionHeading |
section-heading.tsx |
title |
Simpler section heading. |
Skeleton |
skeleton.tsx |
className? |
Animated loading placeholder. |
Spinner |
spinner.tsx |
size?: sm/md/lg |
Inline loading spinner. |
Tooltip |
tooltip.tsx |
content, children |
Hover tooltip wrapper. |
Workers
Components in src/app/_components/worker/ that drive the worker list page and individual row controls.
Top-level Workers page. Uses useWorkerEvents for live SSE. Shows resource/token/cost cards, search, "Clear finished" with ConfirmationDialog. Splits into "In progress" / "Done" FoldableSections.
Renders worker rows. Terminal rows: elapsed, error, Report link, Show logs. Active rows: LiveDuration, 3 ToggleModePill controls, WorkerToggleButton, RestartButton, WorkerMergeButton, CancelButton, WorkerOverridesPopover, OverrideToMergedButton. LogPanel on expand.
Gear popover with nullable override selects: Model (grouped by harness), Effort, Implement mode, Auto-merge/review/address, Accepted review level.
Wraps OverridesPopover with the setWorkerOverrides Server Action.
Forces a worker to merged, bypassing normal flow.
Ticking elapsed time via setInterval. Exports formatElapsedSeconds().
Calls cancelWorker action to cancel an in-progress worker.
Calls restartWorker action to restart a worker from a failed or stalled state.
Retries failed workers on kanban cards.
Manual merge. Disabled/warns when baseCiRed. Uses useActionState.
Pause/resume based on current worker status.
Launches a skill run in the worker's repo context.
Loading skeleton for the worker list while data is being fetched.
Repo / Kanban
Components in src/app/_components/repo/ (and a few in src/app/) that compose the issue board and PR section.
Top-level board. Uses useRepoSnapshot + useRepoSnapshotOverrides. Renders: filter bar (search, stage filter, points filter, harness filter, BatchSelector, CI badge, SyncBranchButton, PausePollingButton), AutomationChip popover, BaseCiStatus, IssuesBoard, PullRequestsSection, WorktreesSection.
Provides OverridesContext and StartedIssuesContext. Monitors SSE connection health (reconnection indicator). Renders KanbanColumnView for Backlog/Ready, InProgressColumn, MergedColumn.
Column shell with sticky header and drop target. Contains ColumnBody which renders a list or empty state.
Draggable card. Contains DecisionBadge, StateBadge labels, CloseIssueButton, IssueConfigPopover, Refine/Review buttons, WorkIssueButton, StoryPointsInput.
Valid values: 1/2/3/5/8/13/21. Suggest button opens HarnessPicker, calls suggestIssuePoints. Deduplicates in-flight with module-level pendingSuggestions Map.
Pre-claim gear popover. Wraps OverridesPopover with setIssueConfig action. Back-syncs story points on model/effort change. Exports syncedStoryPoints().
Polls /api/repo-state, subscribes to repo.updated SSE events to keep the board fresh.
Wraps useRepoSnapshot with optimistic drag-and-drop state for instant UI feedback.
5th kanban column. Uses useWorkerEvents and filters to workers in in_progress. Shows PauseResumeButton, StopButton, ticking elapsed time.
6th column, static (no SSE). Displays merged worker cards from initial server data.
Action Button Components
Small focused action buttons used throughout the board. Each calls a single Server Action.
| Component | Key Props | Action |
|---|---|---|
AddressPrButton |
workerId, repoId |
Triggers AI address-review pass on open PR. |
BaseCiFixButton |
repoId |
Kicks off a base-branch CI fix worker. |
CloseIssueButton |
issueNumber, repoId |
Closes the GitHub issue via Server Action. |
ClosePrButton |
prNumber, repoId |
Closes the open pull request. |
MergePrButton |
prNumber, repoId |
Merges the pull request (admin bypass). |
PausePollingButton |
repoId, paused |
Toggles worker poll loop for the repo. |
ReviewPrButton |
workerId, repoId |
Triggers AI review pass on open PR. |
RepoSwitcher |
repos, selectedId |
Select that pushes ?repo=<id> to the URL. |
SyncBranchButton |
repoId |
Syncs default branch from remote. |
WorkIssueButton |
issueNumber, repoId |
Claims issue and starts a worker. |
Report
Components in src/app/_components/report/ for run reports, cost/token stats, and resource usage.
| Component | Description |
|---|---|
WorkerReport |
Full run report page. Summary, cost/token stats, log, and report body. |
WorkerReportSkeleton |
Loading skeleton while the report data is fetching. |
DetailLogPanel |
Scrollable log for completed runs. Level-based color coding. |
LiveLogPanel |
Live-updating log. Subscribes to SSE for real-time output. |
CostSettings |
Per-model cost rate config. USD/BRL rate and coefficients. |
TotalCostCard |
Stat card for total USD cost. noConversion prop for BRL display. |
TotalTokensCard |
Stat card for net token count across the run. |
UsageCards (CpuCard, MemoryCard) |
Resource usage: CPU% and RSS bytes. scope prop toggles live vs. summary view. |
ReportIssueButton |
File an internal issue from a run report page. |
Agents
Components in src/app/_components/agents/ for browsing, launching, and monitoring standalone agent runs.
Agents page. Uses useWorkerEvents for SSE; refetches /api/agents on events. Shows metrics (running count, completed, total cost, avg duration), search, AgentTable in FoldableSections, "Run skill" opens RunSkillModal.
Table with: Session link, Status badge, Repo (multi-repo), Model/Effort, Cost, Started, Duration, toggle logs/report, Kill button. Expandable log/report rows.
Fetches initial log then subscribes to live SSE for the run, streaming output as it arrives.
Kills a standalone agent run (no workerId). Only shown for non-worker runs.
Filterable skill list. Calls startSkillRun on selection to dispatch the chosen skill.
SSE Integration Pattern
useWorkerEvents is the central SSE hook. It manages the EventSource lifecycle, reconnection, and state reconciliation for all live-updating surfaces.
How it works
Opens an EventSource to /api/events. On disconnect, uses exponential-backoff reconnect (1s to 30s). Fetches a fresh snapshot on reconnect to patch any events missed during downtime. All state mutations go through applyEvent() — a pure reducer — so state transitions are predictable and testable.
Event types handled
- worker.claimedprepend new worker to list
- worker.state_changedupdate status in place
- worker.failedmark worker as failed
- worker.completedmark worker as complete
- worker.github_state_changedupdate PR/issue state
- waiting_merge → mergingtrigger fresh snapshot re-fetch
- cancel from waiting_mergetrigger fresh snapshot re-fetch
- reporting → merged/failedtrigger fresh snapshot re-fetch
subscribe(fn) listener registration
subscribe(fn) registers a listener for WorkerEvent | RunEvent events. Used by WorkerTable, LogPanel, and AgentsLive to receive scoped events without managing their own EventSource connection.
initialWorkers for non-blank first paint. After mount, all mutations come exclusively from applyEvent() or fresh snapshots on reconnect. The client never re-fetches during normal operation.