# Trace viewer

One run as a timeline: each span (agent step, model call, tool, external call, a wait for a person) as a bar on a shared clock, nested under its parent. Opens on the first failure. Select a span for its detail; an open span (still running) runs to "now" with a striped end. The span that broke is solid red; ancestors that failed because of it are pale red.

- Registry name: `trace-viewer` (`@candor/trace-viewer`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/trace-viewer

## Install

```bash
npx candor-ui add trace-viewer
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/trace-viewer`.
It brings in: locale, ops, status, step-list, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import { TraceViewer } from "@/components/trace-viewer"
import type { AgentIdentity } from "@/lib/chat"
import type { TraceSpan } from "@/lib/ops"

const keel: AgentIdentity = { id: "a-keel", name: "Keel", role: "orchestrator" }
const dev: AgentIdentity = { id: "a-dev", name: "Dev agent", role: "dev" }
const qa: AgentIdentity = { id: "a-qa", name: "QA agent", role: "qa" }

const spans: TraceSpan[] = [
  { id: "s0", name: "Add region to projects", kind: "agent", start: 0, duration: 431_000, status: "failed", agent: keel },
  { id: "s1", parentId: "s0", name: "Plan the change", kind: "model", start: 800, duration: 14_200, status: "succeeded", detail: "Claude Opus 5.5 · 18k in / 1.2k out" },
  { id: "s2", parentId: "s0", name: "Dev agent: build on Staging", kind: "agent", start: 16_000, duration: 300_000, status: "failed", agent: dev },
  { id: "s3", parentId: "s2", name: "migration.apply 0142", kind: "tool", start: 18_000, duration: 14_000, status: "succeeded" },
  { id: "s4", parentId: "s2", name: "Backfill: 19 batches", kind: "external", start: 34_000, duration: 264_000, status: "failed", error: "Batch 12 hit a lock timeout four times; the run was stopped.", detail: "18,240 projects; 11,000 updated before the stop." },
  { id: "s5", parentId: "s0", name: "Wait: ask Dana whether a job writes projects", kind: "wait", start: 318_000, duration: 108_000, status: "succeeded" },
  { id: "s6", parentId: "s0", name: "QA agent: tests", kind: "agent", start: 428_000, duration: 3_000, status: "skipped", agent: qa },
]

export default function Example() {
  return <TraceViewer spans={spans} total={431_000} />
}
```

## <TraceViewer>

Props:

- `spans: TraceSpan[]`: The run's spans, each with its parent, start and duration in ms from the run's start; no duration means still running.
- `total: number`: ms; the run's length so far.
- `className?: string | undefined`

## Strings (`traceViewer`)

The fixed words, English by default. Override any of them under `traceViewer` in `<LocaleProvider strings={{ traceViewer: { … } }}>`; the table is exported as `traceViewerStrings`.

- `trace`: Trace
- `span`: Span
- `spans`: Spans
- `spanDetail`: Span detail
- `kindAgent`: Agent
- `kindModel`: Model call
- `kindTool`: Tool
- `kindExternal`: External call
- `kindWait`: Waiting
- `kindOther`: Other
- `spanRunning`: starts {start}, still running, {status}
- `spanTakes`: starts {start}, takes {duration}, {status}
- `starts`: Starts
- `takes`: Takes
- `stillRunning`: Still running
- `agent`: Agent

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
