# Schedule list

Recurring agent jobs (a morning health check, a weekly hygiene report): when they run in plain words, when they run next, a strip of recent outcomes, and pause/resume. A paused job says so instead of showing a next run.

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

## Install

```bash
npx candor-ui add schedule-list
```

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

## Example

```tsx
"use client"

import * as React from "react"
import { ScheduleList } from "@/components/schedule-list"
import type { Schedule } from "@/lib/ops"

const ahead = (m: number) => new Date(Date.now() + m * 60_000).toISOString()

export default function Example() {
  const [schedules, setSchedules] = React.useState<Schedule[]>([
    { id: "j1", title: "Morning health check", when: "Every weekday at 07:00", nextRunAt: ahead(13 * 60), paused: false, history: ["succeeded", "succeeded", "succeeded", "failed", "succeeded", "succeeded"], agent: { id: "qa", name: "QA agent", role: "tester" } },
    { id: "j2", title: "Weekly unused-flags report", when: "Mondays at 08:00", nextRunAt: ahead(5 * 24 * 60), paused: false, history: ["succeeded", "succeeded", "succeeded", "succeeded"], agent: { id: "an", name: "Analyst agent", role: "analyst" } },
    { id: "j3", title: "Re-read the main repository", when: "Every day at 02:00", nextRunAt: null, paused: true, history: ["succeeded", "failed", "failed"], agent: { id: "ar", name: "Architect agent", role: "planner" } },
  ])
  return (
    <ScheduleList
      className="max-w-xl"
      schedules={schedules}
      onToggle={(id, paused) => setSchedules((s) => s.map((x) => (x.id === id ? { ...x, paused, nextRunAt: paused ? null : ahead(60) } : x)))}
    />
  )
}
```

## <ScheduleList>

Props:

- `schedules: Schedule[]`: The recurring jobs, with their schedule, next run and recent outcomes.
- `onToggle?: ((id: string, paused: boolean) => void) | undefined`: Shows pause/resume; called with the job id and whether it should now be paused.
- `className?: string | undefined`

## Strings (`scheduleList`)

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

- `label`: Scheduled jobs
- `heading`: Scheduled
- `paused`: Paused
- `next`: next {when}
- `notScheduled`: not scheduled
- `lastRuns`: Last {count} runs: {failed} failed
- `resume`: Resume
- `pause`: Pause
- `resumeJob`: Resume {title}
- `pauseJob`: Pause {title}

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