Run Header
experimentalHeader for one agent run: title, agent, model, branch, status, live elapsed clock, tokens, cost vs budget, step progress and Stop/Pause controls.
Running
minimal
Migrate session API to @acme/auth
Running
- Elapsed
- –:––
Live run
Steps advance, tokens and spend climb against a $5 budget, the run waits for approval, then completes and offers Open PR. Pause, Resume and Stop work (⌘. and ⌘⇧P).
full
Migrate session API to @acme/auth
Runningkura/auth-client
- Elapsed
- –:––
- Steps
- 4 of 7
- Tokens
- 268k in · 21.9k out
- Spend
- $1.14 of $5.00
Bar
One dense row per run: running, waiting for you, failed and completed.
variant
Migrate session API to @acme/auth
Runningkura/auth-client- Steps
- 4/7
- Tokens
- 290k tokens
- Cost
- $1.12 of $5.00
- Elapsed
- –:––
Patch src/middleware.ts
Waiting for youkura/auth-client- Steps
- 4/7
- Tokens
- 327k tokens
- Cost
- $1.31 of $5.00
- Elapsed
- –:––
Fix login.test.ts › refreshes an expired session
Failedkura/auth-client- Steps
- 5/7
- Tokens
- 387k tokens
- Cost
- $1.58 of $5.00
- Elapsed
- 11:09
Bump @acme/auth to 2.4.0
Completedkura/auth-client- Steps
- 7/7
- Tokens
- 450k tokens
- Cost
- $1.82 of $5.00
- Elapsed
- 11:54
With agent-fleet
A bar header above the run's subagents.
composition
Migrate session API to @acme/auth
Runningkura/auth-client- Steps
- 5/7
- Tokens
- 368k tokens
- Cost
- $1.46 of $5.00
- Elapsed
- –:––
Subagents3
- explorerFound 23 calls to fetchUser() in 9 files1:36
- , 62%test-writerRewriting mocks in src/auth/__tests__/login.test.ts–
- reviewerStarts after test-writer–
Installation
npx shadcn@latest add https://kuro.abstergo.fyi/r/run-header.jsonCopies the source into components/kura/run-header with its dependencies (kura-theme, button, icon-button, kura-format, shimmer-text, status-glyph, tooltip, use-elapsed, use-hotkey, utils). Tokens come from the kura-theme item.
When to use it
Use it for
- The top of a page or pane that shows one agent session (Claude Code, Codex, Devin-style runs): what it is doing, how long, how much it costs, and a way to stop it.
- A dense status row above a run's transcript, plan or fleet (variant='bar').
- Showing spend against a per-run budget, with the meter turning amber at 80% and red past 100%.
- Giving the human Stop / Pause / Resume with keyboard shortcuts while an agent works.
Reach for something else when
- The run's step-by-step plan — use task-list (todo-style) or agent-timeline (steps with connectors).
- Parallel subagents inside a run — use agent-fleet.
- Context-window usage of one conversation — use context-meter.
- A single tool invocation — use tool-call.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title* | React.ReactNode | — | What the run is doing, e.g. "Migrate session API to @acme/auth". Truncates. |
| agent | string | — | Agent name, e.g. "Kura". Panel meta line only. |
| model | string | — | Model id in mono, e.g. "claude-opus-5-5". Panel meta line only. |
| status* | "queued" | "running" | "waiting" | "done" | "failed" | "skipped" | "paused" | — | Run state, drawn with StatusGlyph. running = blue arc + shimmering 'Running'; waiting = amber 'Waiting for you'; done = 'Completed'; failed = red; skipped = 'Stopped'. queued/running/waiting/paused keep the clock ticking. |
| startedAt | Date | number | — | Run start. Drives the live elapsed clock (m:ss, h:mm:ss). Without it the clock shows –:––. |
| endedAt | Date | number | — | Run end. Freezes the clock at endedAt − startedAt (use for finished or persisted runs). |
| tokens | { input: number; output: number } | — | Token usage. Panel shows "412k in · 38.1k out"; bar shows the total. |
| cost | number | — | Spend so far in USD, formatted $1.82. |
| budget | number | — | Budget in USD. Shows '$1.82 of $5.00' with a 4px meter; amber from 80%, red (and red cost) past 100%. |
| branch | string | — | Git branch in mono with a branch icon. In the bar it shows from ~768px container width. |
| progress | { done: number; total: number } | — | Plan progress: '4 of 7' plus a segmented bar (continuous above 24 steps). The current segment is blue while running, amber while waiting, red when failed. |
| actions | React.ReactNode | — | Extra controls before Pause/Stop, e.g. an 'Open PR' Button once the run is done. |
| onStop | () => void | — | Shows Stop while the run is live (queued, running, waiting, paused). Bound to ⌘/Ctrl+. |
| onPause | () => void | — | Shows Pause while running. Bound to ⌘/Ctrl+Shift+P. |
| onResume | () => void | — | Shows Resume while paused. Bound to ⌘/Ctrl+Shift+P. |
| variant | "bar" | "panel" | "panel" | bar = one 44px row (glyph, title, status, branch, steps, tokens, cost, clock, controls; stats drop out as the container narrows). panel = title + meta line + a stats strip (Elapsed, Steps, Tokens, Spend). |
| shortcuts | boolean | true | Bind ⌘/Ctrl+. (Stop) and ⌘/Ctrl+Shift+P (Pause/Resume) on the document. Only one run header on screen should bind them. |
All native attributes of the root element, className and ref pass through.
Anatomy
- RunHeaderRoot <section> labelled by the title; `data-variant`, `data-status`. A size container.
data-slot="run-header" - Title<h2>, truncated.
data-slot="run-header-title" - StatusStatus word; shimmers while running, amber when waiting, red when failed.
data-slot="run-header-status" - AgentAgent name (panel).
data-slot="run-header-agent" - ModelModel id in mono (panel).
data-slot="run-header-model" - BranchBranch icon + mono name.
data-slot="run-header-branch" - Controlsactions, then run-header-pause and run-header-stop.
data-slot="run-header-controls" - Stats<dl>. In the panel each cell is run-header-stat with `data-stat` = elapsed | steps | tokens | cost, separated by hairlines.
data-slot="run-header-stats" - ElapsedMono tabular clock with reserved width so ticking never shifts layout.
data-slot="run-header-elapsed"
Accessibility
- Role:
region (section labelled by the title) - The stats are a <dl>: each value has a term (Elapsed, Steps, Tokens, Spend), visually hidden in the bar.
- A polite status region announces only status changes ('Run waiting for you'); the ticking clock and counters are not announced.
- Stop and Pause have tooltips with their shortcuts and aria-keyshortcuts. Status is never colour-only: the glyph shape and the status word carry it.
- The status glyph is decorative here (label=null) because the status word sits next to it.
- Reduced motion: The running arc, the current step's pulse and the status shimmer stop; meters change width without transition.
| Keys | Action |
|---|---|
| Mod+. | Stop the run (when onStop is set and the run is live) |
| Mod+Shift+P | Pause or resume |
| Tab | Actions, Pause, Stop |
Notes for agents
- Keep one RunHeader mounted for the life of a run and update props; pass startedAt from the server so reloads keep the right clock, and endedAt once it finishes.
- Set shortcuts={false} on every RunHeader except the one for the focused run, otherwise ⌘. stops all of them.
- Map harness states: in-progress → running; needs approval / input → waiting; interrupted by the user → skipped ('Stopped'); error → failed.
- tokens.input should include cache reads if you want the number to match the bill; cost is whatever you computed — the component only formats it.
- Use the bar inside dense layouts (above a fleet or transcript) and the panel at the top of a run page.