Overview
Presentational human-in-the-loop approval surface for reviewing a tool operation before the host application executes it.
Usage
ApprovalCard is fully controlled. It does not execute commands, apply patches,
persist policy decisions, or read environment values. The component only renders
the supplied context and invokes callback props for host-owned actions.
Resolution callback
onResolve is the single decision contract. It fires for every action —
Approve, Approve with edits, Deny, and Dismiss — with the complete
ApprovalResolution payload: the selected decision, parsed editedArgs for
edited approvals, optional reason text, and the remember checkbox state.
Action buttons render only while the request is actionable and onResolve is
wired; a card without the callback is purely presentational.
decision: 'deny' means the approver actively refused the operation.
decision: 'cancel' (the Dismiss button) means the prompt was dismissed
without a decision.
Operation rendering
tool.namerenders in monospace inside the title, distinguishing the identifier from the surrounding sentence.tool.riskrenders as a stacked-bar signal icon (bar count scales with risk, so it doesn't rely on color alone) with a tooltip carrying the risk label; the icon itself is the accessible name viaaria-label.operation.kind: 'command'renders the command as a syntax-highlighted shellCodeBlock.operation.kind: 'patch'renders the supplied unified patch as a syntax-highlighted diff.operation.filesTouchedrenders one row per unique path, each with a copy button. Duplicate paths are collapsed.operation.argsPreviewrenders throughPayloadInspector; oversized previews are replaced with a bounded truncation notice before rendering.envrenders variable names only, as plain text. Values are not accepted and are stripped if a caller accidentally passesNAME=value.- Sandbox context, environment names, and the policy version / idempotency key / snapshot id all live in a single collapsed "Details" disclosure so supporting context stays out of the approver's way until they ask for it. The action buttons are the last element of a pending card.
Approval states
Pending requests render action buttons. Non-pending requests render a
read-only, state-tinted summary. When expiresAt passes while state is
still pending, the effective state becomes expired, actions disappear, and
no callback fires automatically.
Heading levels
The card title defaults to an h3 with section headings one level deeper.
Pass headingLevel to fit the card into the host page's document outline,
matching the Card convention.
When to use
- A tool call, command, file write, or patch needs explicit human approval before execution.
- Showing policy, sandbox, idempotency, environment-name, and argument context for an approval request.
- The action has already completed and only needs historical display — use event-stream-viewer or run-step-timeline instead.
- Collecting arbitrary form input for a workflow — compose form controls directly instead.
Examples
Command approval
A pending command approval with sandbox context, arguments, environment names, and editable arguments.
Expired approval
A read-only approval request whose pending decision window has expired.
Patch approval
A high-risk patch approval that previews the proposed diff, touched files, and arguments.
Props
| Name | Type | Default | Required | Bindable | Description |
|---|---|---|---|---|---|
tool | { /** Human-readable tool name requesting approval. */ name: string; /** Risk level assigned by the policy evaluator. */ risk: ApprovalToolRisk; } | req | Tool requesting approval. | ||
sandbox | { /** Sandbox provider, such as Codex or a remote execution backend. */ provider: string; /** Sandbox profile or policy name. */ name: string; /** Working directory for the pending operation. */ workingDir: string; } | Optional sandbox context in which the operation will run. | |||
operation | | ApprovalCommandOperationApprovalFileWriteOperationApprovalPatchOperationApprovalOtherOperation | req | Operation details shown to the approver. | ||
env | string[] | [] | Environment variable names only. Values are ignored if accidentally supplied as NAME=value. | ||
snapshotId | text | Snapshot identifier for the pending approval context. | |||
policyVersion | text | req | Policy version that produced the approval request. | ||
idempotencyKey | text | req | Idempotency key that makes repeated decisions durable. | ||
expiresAt | text | Optional ISO timestamp after which a pending approval is treated as expired. | |||
state | 'pending''approved''approved_with_edits''denied''expired''cancelled' | req | Persisted approval state. | ||
editableArgs | boolean | false | Whether approving with edited JSON arguments is available. Default false. | ||
headingLevel | 23456 | 3 | Heading level for the card title; section headings render one level deeper. Default 3. | ||
onResolve | (resolution: ApprovalResolution) => void | Called for approve, approve-with-edits, deny, and dismiss with the complete resolution payload. | |||
id | unknown | req |