# Agent Run (Moonarc)

An AI agent's run, replayed in the page: the task at the top, then four lanes that fill in order (the plan ticks off, tool calls spin and finish with their time, a diff writes in line by line, a person is asked to approve and the approve reads Approved), then the result with its numbers. The server HTML is the end state, so without JavaScript and under reduced motion every lane is filled; the animation only plays the path to it, once, in 8 to 12 s. A native checkbox drawn as a small Pause button holds the run, and so does a pointer over it. Zero JavaScript of its own; replay adds a button with a small script.

- Pro block. Install: `npx shadcn@latest add @moonarc-pro/agent-run` (license key required)
- Tier B · category section · trigger scroll, hover, click
- Readout: `<AgentRun task="…" steps={{ items, calls, diff, review }} result={…}>`
- Browser support: widely (Chrome 105 · Firefox 121 · Safari 15.4); elsewhere: without :has() the run plays once in view and cannot be held; it still ends on the filled lanes
- Measured cost: 0 B JS of its own · uses Reveal + runtime (with dependencies 3.0 kB raw; CSS 21.9 kB raw)
- Page: https://moonarc.dev/components/agent-run/

## Props

| Prop | Type | Default | Description |
|---|---|---|---|
| `task` | `string` | none | The task the run is for, in a person's words, at the top of the run. |
| `steps` | `{ items, calls, diff, review }` | none | The four lanes. items: the plan, three to five lines. calls: two to four tool calls, { name, args?, took? }, printed as name(args) in the monospace face with the time taken. diff: { path, lines: { kind: 'add' | 'del' | 'ctx', text }[] }, two to eight lines. review: { who, note?, avatar? }: who is asked (their initials are drawn unless avatar is an image URL) and what the agent says to them. |
| `result` | `{ title, stats? }` | none | The end of the run: what changed, and numbers such as tests passed, time and tokens, each { label, value }. |
| `headline` | `string` | none | The headline above the run. The headline slot wins over it. |
| `eyebrow` | `string` | none | Small label above the headline. The eyebrow slot wins over it. |
| `copy` | `string` | none | The paragraph under the headline. The copy slot wins over it. |
| `lanes` | `{ plan?, tools?, changes?, review? }` | `Plan · Tools · Changes · Review` | The four lane titles. |
| `labels` | `{ task?, running?, done?, call?, approve?, approved?, replay? }` | `Task · Running · Done · done · Approve · Approved · Replay` | The words the run prints around its content: the task's label, the status while it runs and once it is done, what a screen reader hears after each finished call, the approve before and after it is pressed, and the replay button. |
| `pauseLabel` | `string` | `'Pause'` | The pause control's label: a checkbox drawn as a small button, checked while the run is held. |
| `replay` | `boolean` | `false` | A button that plays the run again from its first beat: an internal script, measured on its own fixture. Hidden without JavaScript and under reduced motion. |
| `level` | `1 | 2` | `2` | Heading level of the headline: 2 under the page's h1, 1 when the section opens the page. The lane titles sit one level under it. |
| `tone` | `'surface' | 'muted' | 'ink' | 'brand'` | `unset (paints nothing)` | The ground: the page surface, a muted band, an always-dark ink panel, or a deep brand panel. With theme.css the run's panel takes the tone's card. On brand what is live is marked in the text colour, since the accent is the ground. |
| `density` | `'compact' | 'cozy' | 'roomy'` | `'cozy'` | Block padding and the gap above the run ×0.8 / ×1 / ×1.25 through --ma-density. |

## Usage

```astro
---
import AgentRun from '@/components/moonarc/pro/AgentRun.astro';
---
<AgentRun
  headline="Watch a run from task to merge"
  task="Fix the failing checkout test in apps/web"
  steps={{
    items: ['Read the failing job', 'Find the cause', 'Change the code', 'Run the tests again'],
    calls: [
      { name: 'read_log', args: 'job 4182', took: '0.4 s' },
      { name: 'run_tests', args: 'apps/web', took: '38 s' },
    ],
    diff: {
      path: 'apps/web/src/cart.ts',
      lines: [
        { kind: 'del', text: 'return total * 100;' },
        { kind: 'add', text: 'return Math.round(total * 100);' },
      ],
    },
    review: { who: 'Maya Kim', note: 'Ready to merge. 48 tests pass.' },
  }}
  result={{ title: 'Checkout total rounds to cents', stats: [{ label: 'Tests', value: '48 passed' }, { label: 'Time', value: '2 min 41 s' }] }}
  replay
/>
```

## Reduced motion

The end state at once: every lane filled, every call done, the diff written, the approval given, the result shown. Nothing travels and the controls are not drawn.

## With ClientRouter

CSS only (the replay button's script rebinds through the shared runtime). A new page starts a new run when it comes into view.

## Craft

- The end state is the markup: every beat is an animation from a start state back to the element's own style, with fill both, so the played run lands on exactly what the server sent, and no script has to reveal anything.
- One clock for the whole run: every beat reads --ma-agentrun-play for its play state, which is paused until Reveal marks the run in view, running then, and paused again by the Pause control (:has(:checked)) or a pointer over the run. Held, every animation reports paused.
- The schedule is computed on the server from the counts, so three plan items or five, two calls or four, the run takes 8 to 12 s; beat lengths stay the same and only the gaps scale.
- The accent is only on what is live: the top edge of the lane that runs, a spinning call, the approve being pressed, the Running status. Everything done is in the text colour and the success green.
- Machine text is set in the monospace face (tool calls, the path, the diff, times and tokens) and a person's words in the sans. The diff scrolls inside its card when a line is wider than its lane.
- Every beat is interpolated (opacity, translate, clip-path, a stroke), never a stepped change: WebKit applies a stepped keyframe that lands after the first second of the document to computed style but not to layout.

## Replaces

- Agent plan and tool call demo (Aceternity)
- AI workflow animation (Magic UI)

## Source

Pro block. The source is served by the license-gated registry: `npx shadcn@latest add @moonarc-pro/agent-run` with a key in components.json (https://moonarc.dev/account/). Everything it composes is free: reveal.
