import { useEffect, useRef, useState } from "react"; import type { Extension } from "../workspace/types"; function controls(container: HTMLElement | null) { return [ ...(container?.querySelectorAll( 'button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [href], [tabindex]:not([tabindex="-1"])', ) ?? []), ]; } export function ExtensionDialog({ extension, onRespond, }: { extension?: Extension; onRespond: (response: Record) => void; }) { const ref = useRef(null); const opener = useRef(null); const respond = useRef(onRespond); const [value, setValue] = useState(""); respond.current = onRespond; useEffect(() => { if (!extension) return; opener.current = document.activeElement as HTMLElement | null; setValue( extension.prefill ?? extension.initialValue ?? extension.text ?? "", ); const frame = requestAnimationFrame(() => controls(ref.current)[0]?.focus(), ); const keydown = (event: KeyboardEvent) => { if (event.key === "Escape") { event.preventDefault(); respond.current({ cancelled: true }); return; } if (event.key !== "Tab") return; const focusable = controls(ref.current); const first = focusable[0]; const last = focusable[focusable.length - 1]; if (!first || !last) return; if (event.shiftKey && document.activeElement === first) { event.preventDefault(); last.focus(); } else if (!event.shiftKey && document.activeElement === last) { event.preventDefault(); first.focus(); } }; window.addEventListener("keydown", keydown); return () => { cancelAnimationFrame(frame); window.removeEventListener("keydown", keydown); opener.current?.focus(); }; }, [extension]); if (!extension) return null; return (

Pi agent request

Review request

Requested action

{extension.title ?? "Pi needs input"}

{extension.message && ( <>

Request details

{extension.message}

)}
{extension.method === "select" && (
{extension.options?.map((option) => ( ))}
)} {extension.method === "confirm" && (
)} {extension.method === "input" && ( <> setValue(event.currentTarget.value)} /> )} {extension.method === "editor" && ( <>