# Run tree

Who is doing what: the orchestrator and the specialists it handed work to, as a tree. Parallel work shows as siblings. Each node carries its status, time, and the agent's own check of its result when it ran one. A collapsed branch still says how many are running or failed inside it.

- Registry name: `run-tree` (`@candor/run-tree`)
- 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/run-tree

## Install

```bash
npx candor-ui add run-tree
```

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

## Example

```tsx
"use client"

import type { AgentIdentity } from "@/lib/chat"
import type { RunNode } from "@/lib/work"
import { RunTree } from "@/components/run-tree"

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

const root: RunNode = {
  id: "r0",
  agent: keel,
  task: "Add region to customers",
  status: "running",
  duration: "3m 12s",
  children: [
    { id: "r1", agent: architect, task: "Design the column and access", status: "succeeded", duration: "41s", verdict: { outcome: "unsure", note: "Mobile app screens not in scope; confirm with the team" } },
    {
      id: "r2",
      agent: dev,
      task: "Build on Staging",
      status: "running",
      duration: "1m 50s",
      children: [
        { id: "r2a", agent: dev, task: "Migration and pages", status: "succeeded", duration: "23s", verdict: { outcome: "pass", note: "Applied; the schema shows 4 values" } },
        { id: "r2b", agent: dev, task: "Backfill customers", status: "running" },
      ],
    },
    { id: "r3", agent: qa, task: "Run tests and check the pages", status: "blocked" },
  ],
}

export default function Example() {
  return <RunTree className="max-w-2xl" root={root} />
}
```

## <RunTree>

Props:

- `root: RunNode`: The orchestrator, with the agents it handed work to as children.
- `onSelect?: ((id: string) => void) | undefined`: Makes nodes selectable; called with the node's id.
- `activeId?: string | undefined`: The id of the selected node.
- `className?: string | undefined`

## Strings (`runTree`)

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

- `label`: Agents on this run
- `pass`: Checked
- `fail`: Check failed
- `unsure`: Unsure
- `collapse`: Collapse
- `expand`: Expand
- `underIt`: {count} under it
- `running`: {count} running
- `failed`: {count} failed

## 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`.
