running output pending
{"path":"CHANGELOG.md"}Waiting for the host response.
Recipe / tool approval
A tool call becomes trustworthy when its name, arguments, output, and proposed write are visible before the human decides.
Preview the live recipe, then copy HTML or Install. CSS is composition-only: copy the listed component stylesheets.
Preview
{"actionId":"write-release-notes-01","path":"release-notes.md","content":"# Release notes\n\n- Added agent-ui recipes"}The file proposal is ready. No file changed.
approval required
write-file · release-notes.md · actionId=write-release-notes-01 · exact action shown
Why this is safe
Draft only touches a new markdown file. No secrets or production paths.
Code
<section class="au-tool-call" data-au-state="waiting" aria-label="Release notes tool call">
<header class="au-tool-call__header"><span class="au-tool-call__name">write-file</span><span class="au-tool-call__status">waiting</span></header>
<pre class="au-tool-call__args">{"actionId":"write-release-notes-01","path":"release-notes.md"}</pre>
<p class="au-tool-call__output">The file proposal is ready. No file changed.</p>
</section>
<section class="au-approval-gate" data-au-state="waiting" data-action-id="write-release-notes-01" aria-labelledby="approval-title">
<header class="au-approval-gate__header">
<div>
<p class="au-approval-gate__eyebrow">approval required</p>
<h2 class="au-approval-gate__title" id="approval-title">Write release-notes.md?</h2>
</div>
</header>
<p class="au-approval-gate__action">write-file · release-notes.md · exact action shown</p>
<form class="au-approval-gate__footer" method="post">
<button class="au-btn au-btn--ghost" type="submit" name="decision" value="reject">Keep editing</button>
<button class="au-btn au-btn--primary" type="submit" name="decision" value="approve">Approve write</button>
</form>
</section>recipes.css as product CSS.Install
<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="components/button/button.css">
<link rel="stylesheet" href="components/tool-call/tool-call.css">
<link rel="stylesheet" href="components/approval-gate/approval-gate.css">
<link rel="stylesheet" href="host-chrome.css">Arguments and output are rendered as text. The component does not parse markup, execute commands, or imply that a waiting call succeeded.
running output pending
{"path":"CHANGELOG.md"}Waiting for the host response.
success output received
{"path":"CHANGELOG.md","offset":0,"limit":30}3 headings found. No file changed.
error host rejected output
{"path":"release-notes.md"}Permission denied. No file changed.
cancelled host stopped call
{"actionId":"write-release-notes-01"}The host cancelled this call before execution.
tokens.css, tool-call.css, approval-gate.css, and button.css for actions.running, waiting, success, error, and cancelled. Gates support waiting, success, error, and cancelled.When the agent needs a policy choice before acting, do not invent a supervision component. Stack an approval-gate (why paused + exact action) with an ask-user-question (bounded options). The host still owns authorization and whether work resumes.
approval-gate header and action line state the pause. ask-user-question options carry the judgement. Pair with question resume for the answered → resumed handoff. Message copy / regenerate footers stay host button actions inside chat-message — not a new component.
Compose the tool call and approval gate when the next action has a meaningful consequence. Keep the trust boundary in the host.