Inbox
ProEvery agent thread that has something for you, by what it needs: approvals and questions waiting on you first, then failures, then work that finished. Filter to one environment. "Needs you" is the default view.
Preview
Install
With the Candor CLI
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/inbox
Brings in: agent-avatar, environment-band, locale, relative-time, team, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import { Inbox } from "@/components/inbox"
import type { Environment, InboxItem } from "@/lib/team"
const minutesAgo = (m: number) => new Date(Date.now() - m * 60_000).toISOString()
const environments: Environment[] = [
{ id: "prod", name: "Storefront", production: true, hue: 1, connection: "connected" },
{ id: "staging", name: "Storefront", detail: "staging", production: false, hue: 2, connection: "connected" },
]
const items: InboxItem[] = [
{
id: "i1",
kind: "approval",
title: "Run the region migration on Production",
detail: "Adds a nullable column to orders; takes a brief lock",
environmentId: "prod",
at: minutesAgo(4),
agent: { id: "a-dev", name: "Dev agent", role: "dev" },
needsYou: true,
},
{
id: "i2",
kind: "question",
title: "Which orders table did you mean?",
detail: "There’s one in the main database and one in the archive",
environmentId: "staging",
at: minutesAgo(22),
agent: { id: "a-arch", name: "Architect agent", role: "architect" },
needsYou: true,
},
{
id: "i3",
kind: "failed",
title: "Backfill of customers.region stopped",
detail: "The connection to Staging timed out after 40,000 rows",
environmentId: "staging",
at: minutesAgo(95),
agent: { id: "a-dev", name: "Dev agent", role: "dev" },
needsYou: false,
},
{
id: "i4",
kind: "finished",
title: "Turned on the new-checkout flag for 10% of users",
environmentId: "prod",
at: minutesAgo(240),
agent: { id: "a-qa", name: "QA agent", role: "qa" },
needsYou: false,
},
]
export default function Example() {
return <Inbox className="max-w-2xl" items={items} environments={environments} onOpen={() => {}} />
}<Inbox>
| Prop | Type | Default | Description |
|---|---|---|---|
| itemsrequired | InboxItem[] | — | The threads that have something for you; sorted by whether they need you, then kind, then newest. |
| environments | Environment[] | undefined | [] | The environments items belong to; with more than one, filter chips appear. |
| onOpen | ((id: string) => void) | undefined | — | Called with an item's id when it's opened. |
| className | string | undefined | — | Extra classes for the outer element. |
Strings
The fixed words, in English by default. Change any of them under inbox in <LocaleProvider strings={{ … }}>; the table is exported as inboxStrings.
| Key | English |
|---|---|
| inbox | Inbox |
| show | Show |
| needsYouCount | Needs you · {count} |
| everything | Everything |
| needsYou | Needs you |
| nothingNeedsYou | Nothing needs you right now. |
| nothingHere | Nothing here yet. |
| approval | Approval |
| question | Question |
| failed | Failed |
| finished | Finished |