# Log stream

A run's live log. Filter by severity or by plan step; follows new lines while you're at the bottom. Missing lines show as a gap that says how many and why, never as a silent jump. Warnings and errors carry an icon as well as colour.

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

## Install

```bash
npx candor-ui add log-stream
```

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

## Example

```tsx
"use client"

import type { LogItem } from "@/lib/work"
import { LogStream } from "@/components/log-stream"

const items: LogItem[] = [
  { kind: "line", id: "l1", at: "10:42:01", severity: "info", actor: "Dev agent", stepId: "s1", message: "Running migration 0142 on Staging" },
  { kind: "line", id: "l2", at: "10:42:14", severity: "info", actor: "staging", stepId: "s1", message: "Migration applied: 1 column, 1 index" },
  { kind: "line", id: "l3", at: "10:42:24", severity: "warn", actor: "staging", stepId: "s2", message: "CustomerAdmin: region sits below the fold on narrow screens" },
  { kind: "line", id: "l4", at: "10:42:33", severity: "info", actor: "Dev agent", stepId: "s3", message: "Backfill: batch 1 of 19 (1,000 customers)" },
  { kind: "gap", id: "g1", missing: 23, reason: "the log stream reconnected" },
  { kind: "line", id: "l5", at: "10:43:44", severity: "error", actor: "staging", stepId: "s3", message: "Lock timeout on customers id 48213. Retrying batch 12." },
  { kind: "line", id: "l6", at: "10:43:51", severity: "info", actor: "Dev agent", stepId: "s3", message: "Backfill: batch 12 of 19 retried, succeeded" },
]

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

## <LogStream>

Props:

- `items: LogItem[]`: Log lines and gaps, oldest first.
- `stepId?: string | undefined`: Show only lines from this plan step (gaps always show).
- `live?: boolean | undefined` (default `false`): Marks the log as live and announces new lines to screen readers. Defaults to false.
- `className?: string | undefined`

## Strings (`logStream`)

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

- `label`: Run log
- `log`: Log
- `live`: Live
- `show`: Show
- `all`: All
- `problems`: Problems
- `problemsCount`: Problems · {count}
- `emptyStep`: No log lines for this step yet.
- `empty`: No log lines yet.
- `someMissing`: Some lines are missing: {reason}
- `missing`: { one: "{count} line missing: {reason}", other: "{count} lines missing: {reason}" }
- `error`: Error
- `warning`: Warning
- `latest`: Latest

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