Run List
Agent run history with activity indicators, unread state, and host-owned actions.
Next run
Usage
import { RunList } from '@commenda/pathfinder/run-list';
<RunList
items={runs}
selectedId={activeRunId}
onOpen={openConversation}
onMarkRead={markRunRead}
nextRun={{ label: 'Tomorrow at 9:00 AM', dateTime: '2026-10-14T09:00:00Z' }}
actionConfig={{
onRunNow: runNow,
onMarkAllRead: markAllRead,
onSettings: openSettings,
}}
paginationConfig={{ hasMore, isLoading, onLoadMore: loadOlder, error }}
/>;The host provides newest-first runs and a localized timestamp label plus a machine-readable dateTime. Opening a row calls onOpen and requests onMarkRead only if it was unread. Update the controlled data after your app accepts that operation. Fetching, scheduling, routing, and unread persistence stay outside the component.
Status and unread indicators
Each row has a stable 16px leading slot. Awaiting input is amber, failures red, running uses a blue arc, and an unread completed run has a blue dot. Canceled and skipped runs remain neutral even when unread; their trailing label explains the outcome. Queued and read completed runs use a neutral ring. Status is included in the button's accessible name, so it is not communicated by color alone.
The header menu exposes only supplied actions: Run now, Mark all as read, and Agent settings. Its button is separate from the disclosure trigger. Output counts hide at zero and use compact formatting for large values. Unread counts describe the loaded items, not an assumed server total.
Empty, loading, and collapsed
Next run
Your scheduled agent runs will appear here.
Next run
A collapsed section shows the loaded unread count. Initial loading uses skeleton rows; refreshing retains the existing history. Supply nextRun only when there is a schedule. Pagination preserves existing items, disables repeated requests while loading, and displays error next to the retry control.
Responsive behavior
Long dates, large counts, empty lists, row removal, and new-run insertion use the same controls as Output List. A mobile menu stays available without hover. The host should guard overlapping requests and retain IDs across page loads.
API reference
| Prop | Type | Behavior |
|---|---|---|
itemsRequired | readonly RunItem[] | Newest-first run history |
onOpenRequired | (id: string) => void | Navigate to the run conversation |
onMarkRead | (id: string) => void | Request unread persistence |
selectedId | string|null | Controlled active run |
onSelectionChange | (id: string) => void | Notify selection intent |
nextRun | ObjectView fields | Optional scheduled run |
actionConfig | ObjectView fields | Optional header actions |
paginationConfig | ObjectView fields | Older history and errors |
disclosureConfig | OutputDisclosureConfigView fields · 2 shapes | App-persisted or local disclosure |
loadingConfig | ObjectView fields | Initial skeletons / busy state |
title | string | Copy and host placement |
emptyLabel | string | Copy and host placement |
className | string | Copy and host placement |
nextRunObject fields
| Field | Type | Requirement |
|---|---|---|
label | string | Required |
dateTime | string | Optional |
actionConfigObject fields
| Field | Type | Requirement |
|---|---|---|
onRunNow | (() => void) | Optional |
onMarkAllRead | (() => void) | Optional |
onSettings | (() => void) | Optional |
paginationConfigObject fields
| Field | Type | Requirement |
|---|---|---|
hasMore | boolean | Required |
isLoading | boolean | Required |
onLoadMore | () => void | Required |
error | string | Optional |
disclosureConfigObject fields
Choose one of these 2 shapes. Do not combine fields excluded by the selected shape.
Option 1
| Field | Type | Requirement |
|---|---|---|
open | boolean | Required |
onOpenChange | (open: boolean) => void | Required |
Do not supply: defaultOpen.
Option 2
| Field | Type | Requirement |
|---|---|---|
defaultOpen | boolean | Optional |
onOpenChange | ((open: boolean) => void) | Optional |
Do not supply: open.
loadingConfigObject fields
| Field | Type | Requirement |
|---|---|---|
isLoading | boolean | Required |
label | string | Optional |
A RunItem has id, timestamp: { dateTime, label }, status, optional outputCount, unread, and disabled. Status accepts queued, running, awaiting, completed, failed, canceled, or skipped. Disabled rows cannot open. Pagination is explicit; this small rail does not virtualize an unbounded run history.
Design rules and compatibility
- RUN-01: Match Output List's compact card and 32px row geometry. The status indicator leads; the date is the primary label.
- RUN-02: Canceled and skipped runs are neutral, never failures. Awaiting, failed, and running take precedence over unread; reduced motion stops the running animation.
- RUN-03: Opening an unread run requests marking it read. Keep all mutations and routing in host callbacks; selected and unread state remain controlled.
- RUN-04: Keep header actions independent from disclosure, retain existing rows during pagination, and preserve keyboard focus during removal.
The existing enterprise AgentRunsRail can map its IDs, formatted timestamps, selected conversation, paging, and mutation callbacks into this API. Its current canceled-as-failed mapping must change intentionally to the neutral Figma behavior. No consumer migration is included here. Compose Output List beside it for the responsive panel and complete simulated workflow.