# Stop all

A workspace-wide stop: "Pause every agent". It says how many runs are in flight (from the app, or that the app hasn't said), asks what happens to them (finish the current step, stop now, or hand back to a person) with nothing chosen for the person, and says for the choice what can and can't be undone. The stop itself is confirmed the way the kit's other serious steps are: held down (`HoldToConfirm`) or, with `confirm={{ by: "type", phrase }}`, typed (`TypeToConfirm`). It stays locked, and says why, until a choice is made.

The app does the stopping in `onStop` and reports back through `status`: "stopping" while runs finish their step, "paused" once nothing runs, with Resume when `onResume` is given. A failure comes back as `error` and is said as an alert. Nothing here says a run stopped unless the app says so.

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

## Install

```bash
npx candor-ui add stop-all
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/stop-all`.
It brings in: button, hold-to-confirm, locale, locked, motion, radio-group, tokens, type-to-confirm, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import * as React from "react"
import { StopAll, type StopAllStatus, type StopMode } from "@/components/candor/stop-all"
import { Button } from "@/components/candor/ui/button"

export default function Example() {
  // The app owns the stop: it pauses the agents and says where that is.
  const [status, setStatus] = React.useState<StopAllStatus>("running")
  const [mode, setMode] = React.useState<StopMode | null>(null)
  return (
    <div className="flex max-w-xl flex-col gap-3">
      <StopAll
        inFlight={7}
        status={status}
        stillFinishing={status === "stopping" ? 3 : undefined}
        consequences={{ "stop-now": { cannotUndo: ["Emails already sent stay sent.", "A step stopped part-way isn't rolled back; its run shows what it changed."] } }}
        onStop={(m) => {
          setMode(m)
          setStatus(m === "finish-step" ? "stopping" : "paused")
        }}
        onResume={() => setStatus("running")}
      />
      {status === "stopping" && (
        <div data-demo="" className="flex items-center gap-2 text-xs text-muted-foreground">
          The demo's runs are finishing ({mode}).
          <Button size="xs" variant="outline" onClick={() => setStatus("paused")}>
            Finish them
          </Button>
        </div>
      )}
    </div>
  )
}
```

## <StopAll>

Props:

- `inFlight?: number | undefined`: How many runs are going now, as the app counts them. Left out, the control says the app hasn't said.
- `onStop: (mode: StopMode) => void`: Called with the person's choice once the stop is confirmed. Pause the agents here and report through `status`.
- `status?: StopAllStatus | undefined` (default `"running"`): Where the stop is: "running" (the default; nothing paused), "stopping" or "paused", as the app reports it.
- `stillFinishing?: number | undefined`: While "stopping": how many runs are still finishing their step, when the app knows.
- `onResume?: (() => void) | undefined`: Shows Resume once every agent is paused; called when it's pressed.
- `modes?: StopMode[] | undefined` (default `allModes`): The choices the app supports, in order. All three by default; leave out one the app can't do.
- `consequences?: Partial<Record<StopMode, StopConsequences>> | undefined`: What can and can't be undone for each choice, in the app's words, in place of the kit's general lines.
- `confirm?: { by: "hold"; holdMs?: number | undefined } | { by: "type"; phrase?: string | undefined } | undefined` (default `{ by: "hold" }`): How the stop is confirmed: held for a moment (the default), or by typing a phrase such as the workspace's name.
- `locked?: string | undefined`: Why the viewer can't pause every agent (not an admin, say). The control stays visible and says so.
- `error?: string | undefined`: Why the last stop or resume failed, from the app. Shown as an alert.
- `className?: string | undefined`

## Strings (`stopAll`)

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

- `title`: Pause every agent
- `intro`: Stops new runs from starting anywhere in the workspace. Choose what happens to the runs already going.
- `inFlight`: { one: "{count} run is in flight now.", other: "{count} runs are in flight now." }
- `noneInFlight`: No runs are in flight now.
- `inFlightUnknown`: The app hasn't said how many runs are in flight.
- `choose`: What happens to runs in flight
- `finish-step`: Finish the current step, then pause
- `finish-stepHint`: Each run completes the step it's on and stops before the next one. Nothing is cut off part-way.
- `stop-now`: Stop now
- `stop-nowHint`: Each run stops where it is. A step that was part-way through may have made some of its changes and not others.
- `hand-back`: Hand back to a person
- `hand-backHint`: Each run stops and goes to its owner with its progress, for them to finish or cancel.
- `canUndo`: Can be undone
- `cannotUndo`: Can't be undone
- `undoResume`: Resuming lets agents start new runs again.
- `keepDone`: What runs have already done stays done. Pausing doesn't reverse it.
- `keepPartial`: A step stopped part-way isn't rolled back.
- `keepHanded`: Handed-back runs stay with their owners after you resume.
- `chooseFirst`: Choose what happens to runs in flight first.
- `holdReason`: {choice}. {inFlight}
- `phrase`: pause every agent
- `stopping`: Pausing. Runs are finishing their current step.
- `stoppingCount`: { one: "Pausing. {count} run is still finishing its step.", other: "Pausing. {count} runs are still finishing their step." }
- `paused`: Every agent is paused. No new runs start until you resume.
- `resume`: Resume agents

## Types

### StopMode

What happens to a run that's going when every agent is paused.

```ts
"finish-step" | "stop-now" | "hand-back"
```

### StopAllStatus

Where the workspace-wide stop is, from the app.

```ts
"running" | "stopping" | "paused"
```

### StopConsequences

What can and can't be undone after a stop, in the app's words; replaces the kit's lines for that choice.

```ts
{
  /** What the person can take back, e.g. "Resuming restarts the 4 runs that finished their step." */
  canUndo?: string[] | undefined;
  /** What stays, e.g. "Emails already sent stay sent." */
  cannotUndo?: string[] | undefined;
}
```

## Motion

- **status** (arrive, fade): The line that says where the stop is (pausing, paused, or that it failed) fades and rises in when the app's answer changes while the control is on screen. A state already showing when it first draws is still.

Set with `--cd-motion-stop-all-<moment>-*` in your brand file; the families are in the design reference.

## 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`: its fixed strings in `strings`, its nouns in `nouns`; entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
