affectUI › Components › Agents

Permission Request

An agent asks for one specific right – who, why and exactly what will happen – and you allow it once, for an hour or always; then it folds into one line with the time left and Revoke.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/permission-request.json · Import from @/components/ui/permission-request

When to use

  • An agent hits an action it isn't allowed to do yet and asks for that one right – push to main, send emails, spend money
  • Granting access for a while instead of forever: just once, for an hour, or always
  • Anywhere people should see exactly what will happen – the files, recipients or amounts – before they say yes

When not to use

  • Setting up front how much an agent may do in general – use Autonomy Dial
  • Reviewing a finished result before it goes out – use Approval Card or Agent Inbox
  • Connecting a tool for the first time (OAuth) – that's the provider's consent screen

Usage

import { PermissionRequest } from "@/components/ui/permission-request";

export function PushRequest({ onAnswer }: { onAnswer: (allowed: boolean, until?: number) => void }) {
  return (
    <PermissionRequest
      agent={{ name: "Coder", model: "GPT-6 Sol" }}
      action="push to main"
      target="acme/web"
      risk="risky"
      reason="The fix for the flaky checkout test passed review and all checks."
      preview={[
        { id: "a", label: "src/checkout/cart.ts", meta: "+12 −4" },
        { id: "b", label: "Deploys to production after the merge" },
      ]}
      onDecisionChange={(d) => d && onAnswer(d.allow, d.until)}
    />
  );
}

Props

NameTypeDefaultDescription
agent{ name, model?, avatar? }Who asks – the avatar is a small mark, e.g. the model maker's logo; defaults to initials
actionstringWhat it wants to do, read after "wants to", e.g. "push to main"
targetstringWhere, e.g. "acme/web" or "Stripe · live mode" – shown under the title with toolIcon
toolIconReactNodeThe tool's mark next to the target
risk"safe" | "risky" | "destructive""risky"Risky and destructive carry a tag; destructive also turns Allow red and leaves out Always
reasonstringThe agent's own words on why it needs this
preview{ id, label, meta?, icon? }[]Exactly what will happen – files, recipients, amounts; meta is right-aligned, e.g. "+12 −4"
previewTitlestring"What will happen"Heading of the preview
previewLimitnumber3Rows shown before "N more"
scopes("once" | "timed" | "always")[]all threeThe choices of how long; one choice hides the switch
scope / defaultScope / onScopeChangePermissionScope"once"Controlled or uncontrolled choice of how long
durationnumber60Minutes a timed grant holds
decision / defaultDecisionPermissionDecision | null{ allow, scope, at, until? } – null while it waits
onDecisionChange(decision | null) => voidAllow, Deny – and null for Revoke, Change or Ask again
nownumberDate.now()The clock for the time left – without it the card ticks every second while a timed grant runs
classNamestringExtra class on the root

Keyboard

  • Enter: Allows, with the chosen scope – while the focus is in the card
  • Esc: Denies
  • ← / →: Picks how long

Accessibility

  • While it waits the card is a dialog labelled by its title ("Coder wants to push to main") and described by the reason
  • How long is a radio group; the Allow button names the choice, e.g. "Allow for 1 hour"
  • The decided line is a status, so screen readers announce "Allowed for 1 hour" or "Denied"

Responsive

  • Fills its container up to 400px
  • Below 340px the reason loses its indent, the buttons share the width and the keyboard hints go
  • Touch screens get taller choices and buttons and no keyboard hints
  • Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"

Requirements

  • React 19

Related

  • Autonomy Dial – How much an agent may do on its own – a three-stop dial, and its real actions gliding between “Runs on its own” and “Asks you first”, with a lock for what always asks
  • Approval Card – An agent asks before it acts – risk badge, preview, Approve and Deny with shortcuts, a pausing countdown, and a smooth morph into a resolved row
  • Agent Inbox – All your background agent tasks in one calm list – live clocks and status tags, filter tabs with rolling counts, rows that unfold to the last steps with Approve, Reject, Retry or Open, and glide to their new place
  • Tool Call Card – An agent's tool call in one line – live timer, status and summary, folds open to highlighted arguments and result with copy, retry on errors and a group that sums them up

Guides