"use client"; import { useState } from "react"; import { type OpenCodePermissionRequest, type OpenCodePermissionResponse, useOpenCodeRuntimeExtras, } from "@assistant-ui/react-opencode"; import { CheckCircle2Icon, LoaderIcon, ShieldAlertIcon, XCircleIcon, } from "lucide-react"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; const formatPermissionReply = (reply: OpenCodePermissionResponse) => { switch (reply) { case "always": return "Always allow"; case "once": return "Allowed once"; case "reject": return "Rejected"; } }; export const OpenCodePermissionCard = ({ request, state, reply, }: { request: OpenCodePermissionRequest; state: "pending" | "resolved"; reply?: OpenCodePermissionResponse; }) => { const { replyToPermission } = useOpenCodeRuntimeExtras(); const [submittingReply, setSubmittingReply] = useState(null); const [error, setError] = useState(null); const submitReply = async (nextReply: OpenCodePermissionResponse) => { setSubmittingReply(nextReply); setError(null); try { await replyToPermission(request.id, nextReply); } catch (err) { setError(err instanceof Error ? err.message : "Failed to submit reply."); setSubmittingReply(null); } }; const isPending = state === "pending"; return (
{isPending ? ( ) : reply === "reject" ? ( ) : ( )}
{isPending ? "Approval required" : formatPermissionReply(reply!)} {request.title ?? `OpenCode requested approval for ${request.toolName ?? request.permission}.`}
{request.toolName ?? request.permission}
{(request.patterns.length > 0 || request.toolInput !== undefined) && ( {request.patterns.length > 0 ? (
{request.patterns.map((pattern) => ( {pattern} ))}
) : null} {request.toolInput !== undefined ? (
              {JSON.stringify(request.toolInput, null, 2)}
            
) : null}
)} {isPending ? ( {error ? (

{error}

) : null}
) : null}
); };