Skip to content

Approval

Asks before the agent acts. It names the action as a question, shows the risk with a word and an icon, previews what will be sent, and lets the person edit it first. The outcome stays in the thread.

Medium riskslack.post_message

Send this summary to #design-system?

The assistant will post one message as you. 46 people are in the channel.

Weekly update: 3 accessibility issues fixed on checkout, radius tokens shipped in Figma, Agent kit in review.

risk="medium" · editableText · alwaysAllowLabel — try Edit, then approveLive · light and dark follow the theme switch

Add the source to a shadcn project

npx shadcn@latest add https://docs.atomus.io/r/ai-approval.jsonOpen in v0

Installs the component source, its CSS and the Atomus tokens into components/atomus/. How the registry works

Low riskfs.read

Read 3 files in /design-tokens?

Read-only. Nothing is changed.

High riskfigma.delete_variables

Delete 214 unused variables from the Figma file?

Removes the variables from every page and mode of Atomus 4.0.

Collections: Color (128), Spacing (52), Radius (34). This can’t be undone from the assistant.

risk="low" · risk="high" with a named actionLive · light and dark follow the theme switch

From guidelines/components/ai-approval.md

Properties, variants and anatomy of the Figma components. React props use the same names.

Human-in-the-loop confirmation before an agent acts: the action as a question, a short summary, the risk level, a preview of what will be sent or changed, and Approve / Deny. People can edit the content before approving and can allow the action for the rest of the chat. After they decide, the card stays in the thread with the outcome. Part of the Agent kit.

Figma: component set Approval on the 🤖 Agent kit page of Atomus 4.0 (node 25550:1196), connected to React with Code Connect. React props use the same names as the Figma properties below.

Property Type / options
Title text
Summary text
Risk Low · Medium · High
Tool name text
Details slot (preview)
Editable boolean (off)
Always allow boolean (off) + label
State Pending · Approved · Denied
Approve label · Deny label text

Risk

  • Low — read-only or easy to undo; shield icon, success accent.
  • Medium (default) — sends, posts or changes something people can fix; warning accent.
  • High — deletes, pays, publishes or can’t be undone; error accent and border. Name the action on the button (“Delete variables”).

Anatomy

  1. Accent bar on the left in the risk colour, and a risk icon tile.
  2. Eyebrow: risk word (“High risk”) and tool name.
  3. Title (the question) and summary.
  4. Details or editable preview.
  5. Footer: “Always allow” checkbox; Deny, Edit, Approve.
  6. Outcome after the decision: “Approved”, “Approved with your edits” or “Denied”.

Use for

  • Any agent action that writes, sends, spends, deletes or shares.
  • Steps the person may want to adjust before they happen (an email, a message, a list of issues).

Not for

  • Read-only actions the person already asked for: just run them and show a Tool call.
  • Confirming a person’s own action in a form: use Modal.

Accessibility

  • The card is a labelled region (aria-labelledby the title, described by the summary).
  • Risk is a word and an icon, never colour alone.
  • Focus is not moved to the card when it appears (Primer: keep focus stable); it is reachable in reading order and the buttons are standard buttons.
  • The outcome is announced in a status region.
import { Approval } from '@stanvision/atomus-react';
<Approval
title="Send this summary to #design-system?"
risk="medium"
toolName="slack.post_message"
editableText={draft}
alwaysAllowLabel="Always allow posting to #design-system"
status={decision} // 'pending' | 'approved' | 'denied'
onApprove={({ alwaysAllow, editedText }) => run(editedText ?? draft, alwaysAllow)}
onDeny={cancel}
>
The assistant will post one message as you.
</Approval>

Full types and defaults are in React API at the end of the page.

  • title (the question), children (summary), risk (low · medium · high), toolName.
  • details for a read-only preview, or editableText for edit-then-approve; onApprove receives { alwaysAllow, editedText }.
  • alwaysAllowLabel shows the checkbox — never for high risk.
  • status keeps the outcome visible after the decision; approveLabel names the action (“Delete variables”).

From the Figma guidelines.

Do

  • Phrase the title as a yes/no question with the scope: “File 3 issues in Linear?”.
  • Show exactly what will be sent or changed, and let people edit it when it is text.
  • Keep the card in the thread after the decision so the record stays visible.
  • Offer “Always allow” only for low- and medium-risk actions, scoped to this chat.

Forbidden

  • Never run the action before the person approves.
  • Never pre-tick “Always allow”.
  • Never offer “Always allow” for high-risk actions.
  • Never use a vague label such as “OK” or “Continue” — say what Approve does.

Generated from react/src/components by scripts/gen-react-api.mjs — the same tables agents read in guidelines/components/ai-approval.md.

Use only these props; anything else is not part of the API.

Figma: Approval — human-in-the-loop confirmation before an agent acts. Approve, deny, or edit then approve. The person stays the decision-maker; the outcome stays visible after they decide.

import { Approval } from '@stanvision/atomus-react'; — source: react/src/components/ai/Approval.tsx

Prop Type Default Description
title ReactNode required Figma: Title — the action as a question: “Send this email to 12 people?”
children ReactNode — Figma: Summary — what will happen and what it affects, in one or two sentences.
risk 'low' | 'medium' | 'high' 'medium' Figma: Risk — low · medium · high; shown with an icon and a word, never colour alone.
toolName string — Figma: Tool name — the function that will run (send_email).
details ReactNode — Figma: Details — a preview of what will be sent or changed (read-only).
editableText string — Figma: Editable — plain text the person may edit before approving (“edit then approve”).
editLabel string 'Edit before approving' Label of the editable field
alwaysAllowLabel string — Figma: Always allow — shows the checkbox with this label (“Always allow send_email in this chat”).
status 'pending' | 'approved' | 'denied' 'pending' Figma: State — pending asks; approved and denied show the outcome in place of the buttons.
approveLabel string 'Approve' Figma: Approve label — name the action for high risk (“Delete variables”)
denyLabel string 'Deny' Figma: Deny label
onApprove (decision: ApprovalDecision) => void — Called with the decision when the person approves (after any edits)
onDeny () => void — Called when the person denies; keep the card and set status="denied"
className string — Extra class on the root element (layout only — never restyle colours or sizes).

Accepts only the props above.

ApprovalDecision:

Field Type Description
alwaysAllow boolean The “always allow” checkbox was ticked
editedText? string The edited text, when the person used Edit before approving