"use client" // The approval queue: what a run's tool asked a person to decide. The panel renders the EXACT // stored proposed arguments — a pretty-printed JSON of what the tool was called with — never a // model's narration of them, and it carries the AI disclosure a reviewer reads before deciding. import { AiDisclosureBadge, type ProjectSlugs, useTransport } from "@conusai-kit/ui" import { type ReactElement, useState } from "react" import type { ApprovalView } from "../contract/index.js" export interface ApprovalQueueLabels { readonly heading: string readonly empty: string readonly proposed: string readonly review: string readonly approve: string readonly reject: string readonly decided: string readonly disclosure: string readonly failed: string } export function ApprovalQueue({ slugs, approvals, labels, }: { slugs: ProjectSlugs approvals: readonly ApprovalView[] labels: ApprovalQueueLabels }): ReactElement { const { call, describe } = useTransport() const [busy, setBusy] = useState(null) const [message, setMessage] = useState(null) const decide = async (approval: ApprovalView, decision: "approve" | "reject"): Promise => { setBusy(`${approval.runId}:${approval.stepKey}`) setMessage(null) try { await call("agent.approval.review", { ...slugs, runId: approval.runId, stepKey: approval.stepKey, decision }) setMessage(labels.decided) window.location.reload() } catch (error) { setMessage(labels.failed.replace("{detail}", describe(error))) } finally { setBusy(null) } } return (

{labels.heading}

{approvals.length === 0 ?

{labels.empty}

: null} {approvals.map((approval) => (

{approval.tool}

{approval.goal}

{labels.proposed}

{JSON.stringify(approval.arguments, null, 2)}
{approval.reviewUrl !== null ? ( {labels.review} ) : null}
))} {message !== null ? (

{message}

) : null}
) }