@anvia/studio 0.7.50 → 0.7.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +5 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/ui/assets/evals-page-CEs62ZfO.js +2 -0
  5. package/dist/ui/assets/evals-page-CEs62ZfO.js.map +1 -0
  6. package/dist/ui/assets/{index-BA0rdlcA.js → index-DY62pnOs.js} +4 -4
  7. package/dist/ui/assets/{index-BA0rdlcA.js.map → index-DY62pnOs.js.map} +1 -1
  8. package/dist/ui/assets/{knowledge-page-mjUIFz9M.js → knowledge-page-DMzsYo4t.js} +2 -2
  9. package/dist/ui/assets/{knowledge-page-mjUIFz9M.js.map → knowledge-page-DMzsYo4t.js.map} +1 -1
  10. package/dist/ui/assets/{mcps-page-Cc7DIAm6.js → mcps-page-ok-rle9j.js} +2 -2
  11. package/dist/ui/assets/{mcps-page-Cc7DIAm6.js.map → mcps-page-ok-rle9j.js.map} +1 -1
  12. package/dist/ui/assets/{memory-page-DQIj_bQD.js → memory-page-C7kQQjJR.js} +2 -2
  13. package/dist/ui/assets/{memory-page-DQIj_bQD.js.map → memory-page-C7kQQjJR.js.map} +1 -1
  14. package/dist/ui/assets/{pipelines-page-C-_Kz3Lk.js → pipelines-page-P3XgUxJA.js} +2 -2
  15. package/dist/ui/assets/{pipelines-page-C-_Kz3Lk.js.map → pipelines-page-P3XgUxJA.js.map} +1 -1
  16. package/dist/ui/assets/{sandboxes-page-DTIS-k4s.js → sandboxes-page-j51ihKpC.js} +2 -2
  17. package/dist/ui/assets/{sandboxes-page-DTIS-k4s.js.map → sandboxes-page-j51ihKpC.js.map} +1 -1
  18. package/dist/ui/assets/{sessions-page-BXgRMxf-.js → sessions-page-BBwN5yCL.js} +2 -2
  19. package/dist/ui/assets/{sessions-page-BXgRMxf-.js.map → sessions-page-BBwN5yCL.js.map} +1 -1
  20. package/dist/ui/assets/{status-page-C1lHztV8.js → status-page-BeUj83WX.js} +2 -2
  21. package/dist/ui/assets/{status-page-C1lHztV8.js.map → status-page-BeUj83WX.js.map} +1 -1
  22. package/dist/ui/assets/{tool-runner-FyfYw2ZF.js → tool-runner-DPD3YKe-.js} +2 -2
  23. package/dist/ui/assets/{tool-runner-FyfYw2ZF.js.map → tool-runner-DPD3YKe-.js.map} +1 -1
  24. package/dist/ui/assets/{tools-page-wjxEfdKF.js → tools-page-DXe7uWe2.js} +2 -2
  25. package/dist/ui/assets/{tools-page-wjxEfdKF.js.map → tools-page-DXe7uWe2.js.map} +1 -1
  26. package/dist/ui/assets/{trace-browser-B7e1JE0G.js → trace-browser-DLq-cgJu.js} +2 -2
  27. package/dist/ui/assets/{trace-browser-B7e1JE0G.js.map → trace-browser-DLq-cgJu.js.map} +1 -1
  28. package/dist/ui/assets/{transcript-item-BWi5umW2.js → transcript-item-CNTeNfE-.js} +2 -2
  29. package/dist/ui/assets/{transcript-item-BWi5umW2.js.map → transcript-item-CNTeNfE-.js.map} +1 -1
  30. package/dist/ui/index.html +1 -1
  31. package/package.json +5 -5
  32. package/dist/ui/assets/evals-page-BENEdYNb.js +0 -2
  33. package/dist/ui/assets/evals-page-BENEdYNb.js.map +0 -1
@@ -1,2 +1,2 @@
1
- import{i as e,r as t,s as n,t as r}from"./utils-C9GMruoG.js";import{i}from"./format-D43vTqrO.js";import{$ as a,I as o,L as s,Q as c,a as l,et as u,it as d,lt as f,o as p,q as m,r as h,s as g}from"./index-BA0rdlcA.js";var _=n(e(),1),v=t(),y=1024*1024,b=new Set(`css.csv.env.gitignore.graphql.html.ini.java.js.json.jsx.log.md.mdx.mjs.py.rb.rs.sh.sql.svg.toml.ts.tsx.txt.xml.yaml.yml`.split(`.`)),x=new Map([[`gif`,`image/gif`],[`jpeg`,`image/jpeg`],[`jpg`,`image/jpeg`],[`png`,`image/png`],[`webp`,`image/webp`]]);function S(e){let[t,n]=(0,_.useState)([]),[r,a]=(0,_.useState)(`idle`),[c,u]=(0,_.useState)(0),[p,m]=(0,_.useState)(`.`),[S,w]=(0,_.useState)([]),[E,O]=(0,_.useState)(`idle`),[k,A]=(0,_.useState)(),[M,F]=(0,_.useState)([]),[I,L]=(0,_.useState)([]),[R,z]=(0,_.useState)(`idle`),[B,V]=(0,_.useState)(``),[H,U]=(0,_.useState)(),[W,G]=(0,_.useState)(``),K=(0,_.useRef)(void 0),q=e.initialSandboxRef??t[0]?.ref??``,J=t.find(e=>e.ref===q),Y=J?.ref,X=J?.capabilities.ports??!1,Z=J?.capabilities.processes??!1,Q=(0,_.useCallback)(t=>{let n=i(t);G(n),e.onError(n)},[e.onError]);(0,_.useEffect)(()=>{if(!e.enabled){n([]);return}let t=new AbortController;return a(`loading`),G(``),j(`/sandboxes`,`Sandboxes`,t.signal,c===0?`default`:`reload`).then(e=>n(e.sandboxes)).catch(e=>{t.signal.aborted||Q(e)}).finally(()=>{t.signal.aborted||a(`idle`)}),()=>t.abort()},[e.enabled,c,Q]),(0,_.useEffect)(()=>{e.initialSandboxRef===void 0&&t[0]!==void 0&&e.onSelectSandbox(t[0].ref)},[e.initialSandboxRef,e.onSelectSandbox,t]),(0,_.useEffect)(()=>(m(`.`),w([]),A(void 0),F([]),L([]),V(``),U(void 0),()=>K.current?.abort()),[q]),(0,_.useEffect)(()=>{if(Y===void 0)return;let e=new AbortController;O(`loading`);let t=new URLSearchParams({path:p});return j(`/sandboxes/${encodeURIComponent(Y)}/files?${t}`,`Sandbox files`,e.signal,c===0?`default`:`reload`).then(e=>w(e.entries)).catch(t=>{e.signal.aborted||(w([]),Q(t))}).finally(()=>{e.signal.aborted||O(`idle`)}),()=>e.abort()},[p,c,Q,Y]),(0,_.useEffect)(()=>{if(Y===void 0)return;let e=new AbortController;z(`loading`);let t=`/sandboxes/${encodeURIComponent(Y)}`,n=[];return X?n.push(j(`${t}/ports`,`Sandbox ports`,e.signal,c===0?`default`:`reload`).then(e=>F(e.ports))):F([]),Z?n.push(j(`${t}/processes`,`Sandbox processes`,e.signal,c===0?`default`:`reload`).then(e=>{L(e.processes),V(t=>e.processes.some(e=>e.id===t)?t:``)})):(L([]),V(``)),Promise.all(n).catch(t=>{e.signal.aborted||Q(t)}).finally(()=>{e.signal.aborted||z(`idle`)}),()=>e.abort()},[c,Q,Y,X,Z]),(0,_.useEffect)(()=>{if(Y===void 0||B.length===0){U(void 0);return}let e=new AbortController;return j(`${`/sandboxes/${encodeURIComponent(Y)}/processes`}/${encodeURIComponent(B)}/logs`,`Process logs`,e.signal,c===0?`default`:`reload`).then(U).catch(t=>{e.signal.aborted||Q(t)}),()=>e.abort()},[c,Q,B,Y]),(0,_.useEffect)(()=>()=>{k?.kind===`image`&&URL.revokeObjectURL(k.url)},[k]);let $=(0,_.useCallback)(()=>{K.current?.abort(),K.current=void 0,A(void 0)},[]),ne=(0,_.useCallback)(async e=>{if(K.current?.abort(),K.current=void 0,Y===void 0)return;if((e.size??0)>y){A({kind:`large`,file:e});return}let t=P(e.path),n=x.get(t);if(!b.has(t)&&n===void 0){A({kind:`binary`,file:e});return}A({kind:`loading`,file:e}),G(``);let r=new AbortController;K.current=r;try{let t=await fetch(N(Y,e.path),{signal:r.signal});if(!t.ok)throw Error(await f(t,`Sandbox file`));let i=await t.arrayBuffer();if(i.byteLength>y){A({kind:`large`,file:e});return}if(n!==void 0){A({kind:`image`,file:e,url:URL.createObjectURL(new Blob([i],{type:n}))});return}try{A({kind:`text`,file:e,text:new TextDecoder(`utf-8`,{fatal:!0}).decode(i)})}catch{A({kind:`binary`,file:e})}}catch(t){if(r.signal.aborted)return;Q(t),A({kind:`binary`,file:e})}finally{K.current===r&&(K.current=void 0)}},[Q,Y]);return e.enabled?(0,v.jsxs)(l,{className:`grid grid-rows-[auto_minmax(0,1fr)] gap-3 p-3`,"aria-label":`Sandboxes`,children:[(0,v.jsxs)(g,{className:`flex items-center justify-between gap-4 rounded-xl px-5 py-3.5`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`h1`,{className:`m-0 text-base font-semibold text-foreground`,children:`Live sandbox workspaces`}),(0,v.jsx)(`p`,{className:`m-0 mt-0.5 text-xs leading-5 text-muted-foreground`,children:`Read-only files, published ports, and managed processes discovered from agent tools.`})]}),(0,v.jsxs)(s,{disabled:r===`loading`,size:`sm`,type:`button`,variant:`secondary`,onClick:()=>u(e=>e+1),children:[(0,v.jsx)(o,{icon:d,"aria-hidden":`true`}),`Refresh`]})]}),t.length===0&&r===`idle`?(0,v.jsx)(h,{className:`h-full`,title:`No live sandboxes detected`,text:`Studio discovers sessions automatically from tools returned by createSandboxTools(session).`}):(0,v.jsxs)(`div`,{className:`grid min-h-0 min-w-0 grid-cols-[250px_minmax(300px,0.8fr)_minmax(400px,1.2fr)] gap-3 overflow-hidden`,children:[(0,v.jsx)(C,{sandboxes:t,selectedRef:q,onSelect:e.onSelectSandbox}),(0,v.jsx)(ee,{currentPath:p,files:S,loading:E===`loading`,onOpenDirectory:e=>{$(),m(e)},onOpenFile:e=>void ne(e),onSelectPath:e=>{$(),m(e)}}),(0,v.jsx)(`div`,{className:`grid min-h-0 gap-3 overflow-y-auto pr-1`,children:J===void 0?(0,v.jsx)(h,{title:`Sandbox unavailable`,text:`The requested live sandbox is not registered by this Studio runtime.`}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(te,{sandbox:J,error:W}),(0,v.jsx)(T,{preview:k,sandboxRef:J.ref}),(0,v.jsx)(D,{loading:R===`loading`,logs:H,ports:M,processes:I,selectedProcessId:B,supportsPorts:J.capabilities.ports,supportsProcesses:J.capabilities.processes,onSelectProcess:V})]})})]})]}):(0,v.jsx)(l,{className:`p-4`,"aria-label":`Sandboxes`,children:(0,v.jsx)(h,{title:`No sandbox workspaces`,text:`Add tools created by createSandboxTools(session) to an agent to inspect its live workspace here.`})})}function C(e){return(0,v.jsxs)(g,{className:`grid min-h-0 grid-rows-[auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`border-b border-border/70 px-4 py-3`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Workspaces`}),(0,v.jsxs)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:[e.sandboxes.length,` live `,e.sandboxes.length===1?`session`:`sessions`]})]}),(0,v.jsx)(`div`,{className:`min-h-0 overflow-y-auto p-2`,children:e.sandboxes.map(t=>(0,v.jsxs)(s,{className:r(`mb-1 grid h-auto min-h-16 w-full justify-stretch gap-1 rounded-lg px-3 py-2.5 text-left`,t.ref===e.selectedRef&&`border-border bg-accent text-foreground`),type:`button`,variant:`ghost`,onClick:()=>e.onSelect(t.ref),children:[(0,v.jsxs)(`span`,{className:`flex min-w-0 items-center justify-between gap-2`,children:[(0,v.jsx)(`strong`,{className:`truncate text-sm font-semibold text-foreground`,children:t.id}),(0,v.jsx)(p,{className:`shrink-0 px-1.5 py-0.5 text-[10px]`,children:t.provider})]}),(0,v.jsx)(`span`,{className:`truncate font-mono text-[11px] font-normal text-muted-foreground`,children:t.workdir})]},t.ref))})]})}function ee(e){let t=(0,_.useMemo)(()=>M(e.currentPath),[e.currentPath]);return(0,v.jsxs)(g,{className:`grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`border-b border-border/70 px-4 py-3`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Files`}),(0,v.jsx)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:`One level at a time`})]}),(0,v.jsx)(`div`,{className:`flex min-h-10 items-center gap-1 overflow-x-auto border-b border-border/70 px-3 py-1.5`,children:t.map((t,n)=>(0,v.jsxs)(`span`,{className:`flex items-center gap-1`,children:[n>0?(0,v.jsx)(`span`,{className:`text-muted-foreground/60`,children:`/`}):null,(0,v.jsx)(s,{className:`h-7 min-h-7 px-2 font-mono text-xs`,size:`sm`,type:`button`,variant:`ghost`,onClick:()=>e.onSelectPath(t.path),children:t.label})]},t.path))}),(0,v.jsxs)(`div`,{className:`min-h-0 overflow-y-auto p-2`,children:[e.loading?(0,v.jsx)(`p`,{className:`m-0 px-3 py-4 text-xs text-muted-foreground`,children:`Loading workspace`}):null,!e.loading&&e.files.length===0?(0,v.jsx)(`p`,{className:`m-0 px-3 py-4 text-xs text-muted-foreground`,children:`This directory is empty.`}):null,e.files.map(t=>(0,v.jsxs)(s,{className:`mb-0.5 grid h-10 min-h-10 w-full grid-cols-[18px_minmax(0,1fr)_auto] justify-stretch gap-2 rounded-md px-2.5 text-left text-xs font-medium`,type:`button`,variant:`ghost`,onClick:()=>t.type===`directory`?e.onOpenDirectory(t.path):e.onOpenFile(t),children:[(0,v.jsx)(o,{className:`text-muted-foreground`,icon:t.type===`directory`?u:a,"aria-hidden":`true`}),(0,v.jsx)(`span`,{className:`truncate text-foreground`,children:F(t.path)}),(0,v.jsx)(`span`,{className:`font-mono text-[10px] font-normal text-muted-foreground`,children:t.type===`file`?I(t.size):t.type})]},t.path))]})]})}function te(e){return(0,v.jsxs)(g,{className:`rounded-xl p-4`,children:[(0,v.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Active sandbox`}),(0,v.jsx)(`h2`,{className:`m-0 mt-1 truncate text-lg font-semibold text-foreground`,children:e.sandbox.id}),(0,v.jsx)(`p`,{className:`m-0 mt-1 truncate font-mono text-xs text-muted-foreground`,children:e.sandbox.workdir})]}),(0,v.jsx)(p,{children:e.sandbox.provider})]}),(0,v.jsxs)(`div`,{className:`mt-4 grid grid-cols-2 gap-3 text-xs`,children:[(0,v.jsx)(w,{label:`Agents`,values:e.sandbox.agentIds}),(0,v.jsx)(w,{label:`Sandbox tools`,values:e.sandbox.toolNames})]}),e.error.length>0?(0,v.jsx)(`p`,{className:`m-0 mt-3 rounded-lg border border-destructive/25 bg-destructive/5 px-3 py-2 text-xs leading-5 text-destructive`,children:e.error}):null]})}function w(e){return(0,v.jsxs)(`div`,{className:`rounded-lg border border-border/70 bg-background/45 p-3`,children:[(0,v.jsx)(`span`,{className:`font-semibold uppercase tracking-[0.12em] text-muted-foreground`,children:e.label}),(0,v.jsx)(`p`,{className:`m-0 mt-1 break-words font-mono leading-5 text-foreground`,children:e.values.join(`, `)||`-`})]})}function T(e){let t=e.preview?.file;return(0,v.jsxs)(g,{className:`grid min-h-64 grid-rows-[auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`flex min-h-12 items-center justify-between gap-3 border-b border-border/70 px-4 py-2`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Preview`}),(0,v.jsx)(`p`,{className:`m-0 mt-0.5 truncate font-mono text-[11px] text-muted-foreground`,children:t?.path??`Select a file`})]}),t===void 0?null:(0,v.jsx)(s,{asChild:!0,size:`sm`,variant:`secondary`,children:(0,v.jsxs)(`a`,{href:N(e.sandboxRef,t.path,!0),children:[(0,v.jsx)(o,{icon:c,"aria-hidden":`true`}),`Download`]})})]}),(0,v.jsxs)(`div`,{className:`grid min-h-0 place-items-center overflow-auto bg-background/35 p-4`,children:[e.preview===void 0?(0,v.jsx)(`p`,{className:`m-0 text-center text-xs leading-5 text-muted-foreground`,children:`Choose a regular file to inspect its contents.`}):null,e.preview?.kind===`loading`?(0,v.jsx)(`p`,{className:`m-0 text-xs text-muted-foreground`,children:`Loading preview`}):null,e.preview?.kind===`text`?(0,v.jsx)(`pre`,{className:`m-0 h-full min-h-48 w-full overflow-auto whitespace-pre-wrap break-words rounded-lg border border-border/70 bg-card/60 p-4 font-mono text-xs leading-5 text-foreground`,children:e.preview.text}):null,e.preview?.kind===`image`?(0,v.jsx)(`img`,{className:`max-h-96 max-w-full rounded-lg border border-border/70 object-contain`,src:e.preview.url,alt:F(e.preview.file.path)}):null,e.preview?.kind===`binary`?(0,v.jsx)(E,{text:`This file type is download-only and will not be rendered in Studio.`}):null,e.preview?.kind===`large`?(0,v.jsx)(E,{text:`This file is larger than the 1 MiB inline preview limit.`}):null]})]})}function E(e){return(0,v.jsxs)(`div`,{className:`grid max-w-sm justify-items-center gap-2 text-center`,children:[(0,v.jsx)(o,{className:`h-6 w-6 text-muted-foreground`,icon:a,"aria-hidden":`true`}),(0,v.jsx)(`p`,{className:`m-0 text-xs leading-5 text-muted-foreground`,children:e.text})]})}function D(e){return(0,v.jsxs)(g,{className:`rounded-xl p-4`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Runtime`}),(0,v.jsx)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:`Published ports and managed processes`})]}),e.loading?(0,v.jsx)(p,{children:`Refreshing`}):null]}),(0,v.jsxs)(`div`,{className:`mt-4 grid gap-4`,children:[(0,v.jsx)(O,{title:`Ports`,children:e.supportsPorts?e.ports.length===0?(0,v.jsx)(k,{text:`No ports are published.`}):(0,v.jsx)(`div`,{className:`grid gap-1`,children:e.ports.map(e=>(0,v.jsxs)(`div`,{className:`grid grid-cols-[90px_minmax(0,1fr)] gap-3 rounded-md border border-border/60 px-3 py-2 font-mono text-xs`,children:[(0,v.jsxs)(`span`,{className:`text-foreground`,children:[e.containerPort,`/`,e.protocol]}),(0,v.jsxs)(`span`,{className:`truncate text-muted-foreground`,children:[e.host,`:`,e.hostPort]})]},`${e.containerPort}:${e.hostPort}`))}):(0,v.jsx)(k,{text:`Published ports are not supported by this sandbox.`})}),(0,v.jsx)(O,{title:`Processes`,children:e.supportsProcesses?e.processes.length===0?(0,v.jsx)(k,{text:`No managed processes are recorded.`}):(0,v.jsx)(`div`,{className:`grid gap-1`,children:e.processes.map(t=>(0,v.jsxs)(s,{className:r(`grid h-auto min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] justify-stretch gap-3 rounded-md px-3 py-2 text-left`,t.id===e.selectedProcessId&&`border-border bg-accent text-foreground`),type:`button`,variant:`ghost`,onClick:()=>e.onSelectProcess(t.id),children:[(0,v.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[(0,v.jsx)(o,{className:`text-muted-foreground`,icon:m,"aria-hidden":`true`}),(0,v.jsx)(`span`,{className:`truncate font-mono text-xs text-foreground`,children:[t.command,...t.args].join(` `)})]}),(0,v.jsx)(p,{className:`px-1.5 py-0.5 text-[10px]`,children:t.status})]},t.id))}):(0,v.jsx)(k,{text:`Managed processes are not supported by this sandbox.`})}),e.selectedProcessId.length>0?(0,v.jsx)(O,{title:`Process logs`,children:e.logs===void 0?(0,v.jsx)(k,{text:`Loading the latest bounded output.`}):(0,v.jsxs)(`div`,{className:`grid gap-2`,children:[(0,v.jsx)(A,{label:`stdout`,text:e.logs.stdout,truncated:e.logs.stdoutTruncated}),(0,v.jsx)(A,{label:`stderr`,text:e.logs.stderr,truncated:e.logs.stderrTruncated})]})}):null]})]})}function O(e){return(0,v.jsxs)(`section`,{className:`grid gap-2`,children:[(0,v.jsx)(`h3`,{className:`m-0 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground`,children:e.title}),e.children]})}function k(e){return(0,v.jsx)(`p`,{className:`m-0 rounded-md border border-dashed border-border/70 px-3 py-2 text-xs leading-5 text-muted-foreground`,children:e.text})}function A(e){return(0,v.jsxs)(`div`,{className:`overflow-hidden rounded-md border border-border/70 bg-background/55`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between border-b border-border/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground`,children:[(0,v.jsx)(`span`,{children:e.label}),e.truncated?(0,v.jsx)(`span`,{children:`truncated`}):null]}),(0,v.jsx)(`pre`,{className:`m-0 max-h-48 overflow-auto whitespace-pre-wrap break-words p-3 font-mono text-[11px] leading-5 text-foreground`,children:e.text||`No output`})]})}async function j(e,t,n,r=`default`){let i=await fetch(e,{cache:r,signal:n});if(!i.ok)throw Error(await f(i,t));return await i.json()}function M(e){let t=e===`.`?[]:e.split(`/`).filter(Boolean),n=[{label:`/`,path:`.`}];for(let e=0;e<t.length;e+=1)n.push({label:t[e]??``,path:t.slice(0,e+1).join(`/`)});return n}function N(e,t,n=!1){let r=new URLSearchParams({path:t});return n&&r.set(`download`,`1`),`/sandboxes/${encodeURIComponent(e)}/files/content?${r}`}function P(e){let t=F(e).toLowerCase(),n=t.lastIndexOf(`.`);return n<0?t:t.slice(n+1)}function F(e){return e.split(`/`).at(-1)??e}function I(e){return e===void 0?`-`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KiB`:`${(e/(1024*1024)).toFixed(1)} MiB`}export{S as SandboxesPage};
2
- //# sourceMappingURL=sandboxes-page-DTIS-k4s.js.map
1
+ import{i as e,r as t,s as n,t as r}from"./utils-C9GMruoG.js";import{i}from"./format-D43vTqrO.js";import{$ as a,I as o,L as s,Q as c,a as l,et as u,it as d,lt as f,o as p,q as m,r as h,s as g}from"./index-DY62pnOs.js";var _=n(e(),1),v=t(),y=1024*1024,b=new Set(`css.csv.env.gitignore.graphql.html.ini.java.js.json.jsx.log.md.mdx.mjs.py.rb.rs.sh.sql.svg.toml.ts.tsx.txt.xml.yaml.yml`.split(`.`)),x=new Map([[`gif`,`image/gif`],[`jpeg`,`image/jpeg`],[`jpg`,`image/jpeg`],[`png`,`image/png`],[`webp`,`image/webp`]]);function S(e){let[t,n]=(0,_.useState)([]),[r,a]=(0,_.useState)(`idle`),[c,u]=(0,_.useState)(0),[p,m]=(0,_.useState)(`.`),[S,w]=(0,_.useState)([]),[E,O]=(0,_.useState)(`idle`),[k,A]=(0,_.useState)(),[M,F]=(0,_.useState)([]),[I,L]=(0,_.useState)([]),[R,z]=(0,_.useState)(`idle`),[B,V]=(0,_.useState)(``),[H,U]=(0,_.useState)(),[W,G]=(0,_.useState)(``),K=(0,_.useRef)(void 0),q=e.initialSandboxRef??t[0]?.ref??``,J=t.find(e=>e.ref===q),Y=J?.ref,X=J?.capabilities.ports??!1,Z=J?.capabilities.processes??!1,Q=(0,_.useCallback)(t=>{let n=i(t);G(n),e.onError(n)},[e.onError]);(0,_.useEffect)(()=>{if(!e.enabled){n([]);return}let t=new AbortController;return a(`loading`),G(``),j(`/sandboxes`,`Sandboxes`,t.signal,c===0?`default`:`reload`).then(e=>n(e.sandboxes)).catch(e=>{t.signal.aborted||Q(e)}).finally(()=>{t.signal.aborted||a(`idle`)}),()=>t.abort()},[e.enabled,c,Q]),(0,_.useEffect)(()=>{e.initialSandboxRef===void 0&&t[0]!==void 0&&e.onSelectSandbox(t[0].ref)},[e.initialSandboxRef,e.onSelectSandbox,t]),(0,_.useEffect)(()=>(m(`.`),w([]),A(void 0),F([]),L([]),V(``),U(void 0),()=>K.current?.abort()),[q]),(0,_.useEffect)(()=>{if(Y===void 0)return;let e=new AbortController;O(`loading`);let t=new URLSearchParams({path:p});return j(`/sandboxes/${encodeURIComponent(Y)}/files?${t}`,`Sandbox files`,e.signal,c===0?`default`:`reload`).then(e=>w(e.entries)).catch(t=>{e.signal.aborted||(w([]),Q(t))}).finally(()=>{e.signal.aborted||O(`idle`)}),()=>e.abort()},[p,c,Q,Y]),(0,_.useEffect)(()=>{if(Y===void 0)return;let e=new AbortController;z(`loading`);let t=`/sandboxes/${encodeURIComponent(Y)}`,n=[];return X?n.push(j(`${t}/ports`,`Sandbox ports`,e.signal,c===0?`default`:`reload`).then(e=>F(e.ports))):F([]),Z?n.push(j(`${t}/processes`,`Sandbox processes`,e.signal,c===0?`default`:`reload`).then(e=>{L(e.processes),V(t=>e.processes.some(e=>e.id===t)?t:``)})):(L([]),V(``)),Promise.all(n).catch(t=>{e.signal.aborted||Q(t)}).finally(()=>{e.signal.aborted||z(`idle`)}),()=>e.abort()},[c,Q,Y,X,Z]),(0,_.useEffect)(()=>{if(Y===void 0||B.length===0){U(void 0);return}let e=new AbortController;return j(`${`/sandboxes/${encodeURIComponent(Y)}/processes`}/${encodeURIComponent(B)}/logs`,`Process logs`,e.signal,c===0?`default`:`reload`).then(U).catch(t=>{e.signal.aborted||Q(t)}),()=>e.abort()},[c,Q,B,Y]),(0,_.useEffect)(()=>()=>{k?.kind===`image`&&URL.revokeObjectURL(k.url)},[k]);let $=(0,_.useCallback)(()=>{K.current?.abort(),K.current=void 0,A(void 0)},[]),ne=(0,_.useCallback)(async e=>{if(K.current?.abort(),K.current=void 0,Y===void 0)return;if((e.size??0)>y){A({kind:`large`,file:e});return}let t=P(e.path),n=x.get(t);if(!b.has(t)&&n===void 0){A({kind:`binary`,file:e});return}A({kind:`loading`,file:e}),G(``);let r=new AbortController;K.current=r;try{let t=await fetch(N(Y,e.path),{signal:r.signal});if(!t.ok)throw Error(await f(t,`Sandbox file`));let i=await t.arrayBuffer();if(i.byteLength>y){A({kind:`large`,file:e});return}if(n!==void 0){A({kind:`image`,file:e,url:URL.createObjectURL(new Blob([i],{type:n}))});return}try{A({kind:`text`,file:e,text:new TextDecoder(`utf-8`,{fatal:!0}).decode(i)})}catch{A({kind:`binary`,file:e})}}catch(t){if(r.signal.aborted)return;Q(t),A({kind:`binary`,file:e})}finally{K.current===r&&(K.current=void 0)}},[Q,Y]);return e.enabled?(0,v.jsxs)(l,{className:`grid grid-rows-[auto_minmax(0,1fr)] gap-3 p-3`,"aria-label":`Sandboxes`,children:[(0,v.jsxs)(g,{className:`flex items-center justify-between gap-4 rounded-xl px-5 py-3.5`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`h1`,{className:`m-0 text-base font-semibold text-foreground`,children:`Live sandbox workspaces`}),(0,v.jsx)(`p`,{className:`m-0 mt-0.5 text-xs leading-5 text-muted-foreground`,children:`Read-only files, published ports, and managed processes discovered from agent tools.`})]}),(0,v.jsxs)(s,{disabled:r===`loading`,size:`sm`,type:`button`,variant:`secondary`,onClick:()=>u(e=>e+1),children:[(0,v.jsx)(o,{icon:d,"aria-hidden":`true`}),`Refresh`]})]}),t.length===0&&r===`idle`?(0,v.jsx)(h,{className:`h-full`,title:`No live sandboxes detected`,text:`Studio discovers sessions automatically from tools returned by createSandboxTools(session).`}):(0,v.jsxs)(`div`,{className:`grid min-h-0 min-w-0 grid-cols-[250px_minmax(300px,0.8fr)_minmax(400px,1.2fr)] gap-3 overflow-hidden`,children:[(0,v.jsx)(C,{sandboxes:t,selectedRef:q,onSelect:e.onSelectSandbox}),(0,v.jsx)(ee,{currentPath:p,files:S,loading:E===`loading`,onOpenDirectory:e=>{$(),m(e)},onOpenFile:e=>void ne(e),onSelectPath:e=>{$(),m(e)}}),(0,v.jsx)(`div`,{className:`grid min-h-0 gap-3 overflow-y-auto pr-1`,children:J===void 0?(0,v.jsx)(h,{title:`Sandbox unavailable`,text:`The requested live sandbox is not registered by this Studio runtime.`}):(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(te,{sandbox:J,error:W}),(0,v.jsx)(T,{preview:k,sandboxRef:J.ref}),(0,v.jsx)(D,{loading:R===`loading`,logs:H,ports:M,processes:I,selectedProcessId:B,supportsPorts:J.capabilities.ports,supportsProcesses:J.capabilities.processes,onSelectProcess:V})]})})]})]}):(0,v.jsx)(l,{className:`p-4`,"aria-label":`Sandboxes`,children:(0,v.jsx)(h,{title:`No sandbox workspaces`,text:`Add tools created by createSandboxTools(session) to an agent to inspect its live workspace here.`})})}function C(e){return(0,v.jsxs)(g,{className:`grid min-h-0 grid-rows-[auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`border-b border-border/70 px-4 py-3`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Workspaces`}),(0,v.jsxs)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:[e.sandboxes.length,` live `,e.sandboxes.length===1?`session`:`sessions`]})]}),(0,v.jsx)(`div`,{className:`min-h-0 overflow-y-auto p-2`,children:e.sandboxes.map(t=>(0,v.jsxs)(s,{className:r(`mb-1 grid h-auto min-h-16 w-full justify-stretch gap-1 rounded-lg px-3 py-2.5 text-left`,t.ref===e.selectedRef&&`border-border bg-accent text-foreground`),type:`button`,variant:`ghost`,onClick:()=>e.onSelect(t.ref),children:[(0,v.jsxs)(`span`,{className:`flex min-w-0 items-center justify-between gap-2`,children:[(0,v.jsx)(`strong`,{className:`truncate text-sm font-semibold text-foreground`,children:t.id}),(0,v.jsx)(p,{className:`shrink-0 px-1.5 py-0.5 text-[10px]`,children:t.provider})]}),(0,v.jsx)(`span`,{className:`truncate font-mono text-[11px] font-normal text-muted-foreground`,children:t.workdir})]},t.ref))})]})}function ee(e){let t=(0,_.useMemo)(()=>M(e.currentPath),[e.currentPath]);return(0,v.jsxs)(g,{className:`grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`border-b border-border/70 px-4 py-3`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Files`}),(0,v.jsx)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:`One level at a time`})]}),(0,v.jsx)(`div`,{className:`flex min-h-10 items-center gap-1 overflow-x-auto border-b border-border/70 px-3 py-1.5`,children:t.map((t,n)=>(0,v.jsxs)(`span`,{className:`flex items-center gap-1`,children:[n>0?(0,v.jsx)(`span`,{className:`text-muted-foreground/60`,children:`/`}):null,(0,v.jsx)(s,{className:`h-7 min-h-7 px-2 font-mono text-xs`,size:`sm`,type:`button`,variant:`ghost`,onClick:()=>e.onSelectPath(t.path),children:t.label})]},t.path))}),(0,v.jsxs)(`div`,{className:`min-h-0 overflow-y-auto p-2`,children:[e.loading?(0,v.jsx)(`p`,{className:`m-0 px-3 py-4 text-xs text-muted-foreground`,children:`Loading workspace`}):null,!e.loading&&e.files.length===0?(0,v.jsx)(`p`,{className:`m-0 px-3 py-4 text-xs text-muted-foreground`,children:`This directory is empty.`}):null,e.files.map(t=>(0,v.jsxs)(s,{className:`mb-0.5 grid h-10 min-h-10 w-full grid-cols-[18px_minmax(0,1fr)_auto] justify-stretch gap-2 rounded-md px-2.5 text-left text-xs font-medium`,type:`button`,variant:`ghost`,onClick:()=>t.type===`directory`?e.onOpenDirectory(t.path):e.onOpenFile(t),children:[(0,v.jsx)(o,{className:`text-muted-foreground`,icon:t.type===`directory`?u:a,"aria-hidden":`true`}),(0,v.jsx)(`span`,{className:`truncate text-foreground`,children:F(t.path)}),(0,v.jsx)(`span`,{className:`font-mono text-[10px] font-normal text-muted-foreground`,children:t.type===`file`?I(t.size):t.type})]},t.path))]})]})}function te(e){return(0,v.jsxs)(g,{className:`rounded-xl p-4`,children:[(0,v.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Active sandbox`}),(0,v.jsx)(`h2`,{className:`m-0 mt-1 truncate text-lg font-semibold text-foreground`,children:e.sandbox.id}),(0,v.jsx)(`p`,{className:`m-0 mt-1 truncate font-mono text-xs text-muted-foreground`,children:e.sandbox.workdir})]}),(0,v.jsx)(p,{children:e.sandbox.provider})]}),(0,v.jsxs)(`div`,{className:`mt-4 grid grid-cols-2 gap-3 text-xs`,children:[(0,v.jsx)(w,{label:`Agents`,values:e.sandbox.agentIds}),(0,v.jsx)(w,{label:`Sandbox tools`,values:e.sandbox.toolNames})]}),e.error.length>0?(0,v.jsx)(`p`,{className:`m-0 mt-3 rounded-lg border border-destructive/25 bg-destructive/5 px-3 py-2 text-xs leading-5 text-destructive`,children:e.error}):null]})}function w(e){return(0,v.jsxs)(`div`,{className:`rounded-lg border border-border/70 bg-background/45 p-3`,children:[(0,v.jsx)(`span`,{className:`font-semibold uppercase tracking-[0.12em] text-muted-foreground`,children:e.label}),(0,v.jsx)(`p`,{className:`m-0 mt-1 break-words font-mono leading-5 text-foreground`,children:e.values.join(`, `)||`-`})]})}function T(e){let t=e.preview?.file;return(0,v.jsxs)(g,{className:`grid min-h-64 grid-rows-[auto_minmax(0,1fr)] rounded-xl`,children:[(0,v.jsxs)(`div`,{className:`flex min-h-12 items-center justify-between gap-3 border-b border-border/70 px-4 py-2`,children:[(0,v.jsxs)(`div`,{className:`min-w-0`,children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Preview`}),(0,v.jsx)(`p`,{className:`m-0 mt-0.5 truncate font-mono text-[11px] text-muted-foreground`,children:t?.path??`Select a file`})]}),t===void 0?null:(0,v.jsx)(s,{asChild:!0,size:`sm`,variant:`secondary`,children:(0,v.jsxs)(`a`,{href:N(e.sandboxRef,t.path,!0),children:[(0,v.jsx)(o,{icon:c,"aria-hidden":`true`}),`Download`]})})]}),(0,v.jsxs)(`div`,{className:`grid min-h-0 place-items-center overflow-auto bg-background/35 p-4`,children:[e.preview===void 0?(0,v.jsx)(`p`,{className:`m-0 text-center text-xs leading-5 text-muted-foreground`,children:`Choose a regular file to inspect its contents.`}):null,e.preview?.kind===`loading`?(0,v.jsx)(`p`,{className:`m-0 text-xs text-muted-foreground`,children:`Loading preview`}):null,e.preview?.kind===`text`?(0,v.jsx)(`pre`,{className:`m-0 h-full min-h-48 w-full overflow-auto whitespace-pre-wrap break-words rounded-lg border border-border/70 bg-card/60 p-4 font-mono text-xs leading-5 text-foreground`,children:e.preview.text}):null,e.preview?.kind===`image`?(0,v.jsx)(`img`,{className:`max-h-96 max-w-full rounded-lg border border-border/70 object-contain`,src:e.preview.url,alt:F(e.preview.file.path)}):null,e.preview?.kind===`binary`?(0,v.jsx)(E,{text:`This file type is download-only and will not be rendered in Studio.`}):null,e.preview?.kind===`large`?(0,v.jsx)(E,{text:`This file is larger than the 1 MiB inline preview limit.`}):null]})]})}function E(e){return(0,v.jsxs)(`div`,{className:`grid max-w-sm justify-items-center gap-2 text-center`,children:[(0,v.jsx)(o,{className:`h-6 w-6 text-muted-foreground`,icon:a,"aria-hidden":`true`}),(0,v.jsx)(`p`,{className:`m-0 text-xs leading-5 text-muted-foreground`,children:e.text})]})}function D(e){return(0,v.jsxs)(g,{className:`rounded-xl p-4`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,v.jsxs)(`div`,{children:[(0,v.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:`Runtime`}),(0,v.jsx)(`p`,{className:`m-0 mt-1 text-xs text-muted-foreground`,children:`Published ports and managed processes`})]}),e.loading?(0,v.jsx)(p,{children:`Refreshing`}):null]}),(0,v.jsxs)(`div`,{className:`mt-4 grid gap-4`,children:[(0,v.jsx)(O,{title:`Ports`,children:e.supportsPorts?e.ports.length===0?(0,v.jsx)(k,{text:`No ports are published.`}):(0,v.jsx)(`div`,{className:`grid gap-1`,children:e.ports.map(e=>(0,v.jsxs)(`div`,{className:`grid grid-cols-[90px_minmax(0,1fr)] gap-3 rounded-md border border-border/60 px-3 py-2 font-mono text-xs`,children:[(0,v.jsxs)(`span`,{className:`text-foreground`,children:[e.containerPort,`/`,e.protocol]}),(0,v.jsxs)(`span`,{className:`truncate text-muted-foreground`,children:[e.host,`:`,e.hostPort]})]},`${e.containerPort}:${e.hostPort}`))}):(0,v.jsx)(k,{text:`Published ports are not supported by this sandbox.`})}),(0,v.jsx)(O,{title:`Processes`,children:e.supportsProcesses?e.processes.length===0?(0,v.jsx)(k,{text:`No managed processes are recorded.`}):(0,v.jsx)(`div`,{className:`grid gap-1`,children:e.processes.map(t=>(0,v.jsxs)(s,{className:r(`grid h-auto min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] justify-stretch gap-3 rounded-md px-3 py-2 text-left`,t.id===e.selectedProcessId&&`border-border bg-accent text-foreground`),type:`button`,variant:`ghost`,onClick:()=>e.onSelectProcess(t.id),children:[(0,v.jsxs)(`span`,{className:`flex min-w-0 items-center gap-2`,children:[(0,v.jsx)(o,{className:`text-muted-foreground`,icon:m,"aria-hidden":`true`}),(0,v.jsx)(`span`,{className:`truncate font-mono text-xs text-foreground`,children:[t.command,...t.args].join(` `)})]}),(0,v.jsx)(p,{className:`px-1.5 py-0.5 text-[10px]`,children:t.status})]},t.id))}):(0,v.jsx)(k,{text:`Managed processes are not supported by this sandbox.`})}),e.selectedProcessId.length>0?(0,v.jsx)(O,{title:`Process logs`,children:e.logs===void 0?(0,v.jsx)(k,{text:`Loading the latest bounded output.`}):(0,v.jsxs)(`div`,{className:`grid gap-2`,children:[(0,v.jsx)(A,{label:`stdout`,text:e.logs.stdout,truncated:e.logs.stdoutTruncated}),(0,v.jsx)(A,{label:`stderr`,text:e.logs.stderr,truncated:e.logs.stderrTruncated})]})}):null]})]})}function O(e){return(0,v.jsxs)(`section`,{className:`grid gap-2`,children:[(0,v.jsx)(`h3`,{className:`m-0 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground`,children:e.title}),e.children]})}function k(e){return(0,v.jsx)(`p`,{className:`m-0 rounded-md border border-dashed border-border/70 px-3 py-2 text-xs leading-5 text-muted-foreground`,children:e.text})}function A(e){return(0,v.jsxs)(`div`,{className:`overflow-hidden rounded-md border border-border/70 bg-background/55`,children:[(0,v.jsxs)(`div`,{className:`flex items-center justify-between border-b border-border/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground`,children:[(0,v.jsx)(`span`,{children:e.label}),e.truncated?(0,v.jsx)(`span`,{children:`truncated`}):null]}),(0,v.jsx)(`pre`,{className:`m-0 max-h-48 overflow-auto whitespace-pre-wrap break-words p-3 font-mono text-[11px] leading-5 text-foreground`,children:e.text||`No output`})]})}async function j(e,t,n,r=`default`){let i=await fetch(e,{cache:r,signal:n});if(!i.ok)throw Error(await f(i,t));return await i.json()}function M(e){let t=e===`.`?[]:e.split(`/`).filter(Boolean),n=[{label:`/`,path:`.`}];for(let e=0;e<t.length;e+=1)n.push({label:t[e]??``,path:t.slice(0,e+1).join(`/`)});return n}function N(e,t,n=!1){let r=new URLSearchParams({path:t});return n&&r.set(`download`,`1`),`/sandboxes/${encodeURIComponent(e)}/files/content?${r}`}function P(e){let t=F(e).toLowerCase(),n=t.lastIndexOf(`.`);return n<0?t:t.slice(n+1)}function F(e){return e.split(`/`).at(-1)??e}function I(e){return e===void 0?`-`:e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KiB`:`${(e/(1024*1024)).toFixed(1)} MiB`}export{S as SandboxesPage};
2
+ //# sourceMappingURL=sandboxes-page-j51ihKpC.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sandboxes-page-DTIS-k4s.js","names":[],"sources":["../../../src/ui/app/modules/sandboxes/sandboxes-page.tsx"],"sourcesContent":["import {\n ComputerTerminal01Icon,\n Download01Icon,\n File01Icon,\n FolderOpenIcon,\n RefreshIcon,\n} from \"@hugeicons/core-free-icons\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n StudioSandboxesSummary,\n StudioSandboxFileEntry,\n StudioSandboxFilesResponse,\n StudioSandboxPort,\n StudioSandboxPortsResponse,\n StudioSandboxProcess,\n StudioSandboxProcessesResponse,\n StudioSandboxProcessLogsResponse,\n StudioSandboxSummary,\n} from \"../../../../types\";\nimport { responseErrorMessage } from \"../../app-errors\";\nimport { Button } from \"../../components/ui/button\";\nimport { StudioIcon } from \"../../components/ui/icon\";\nimport {\n StudioEmptyState,\n StudioPageShell,\n StudioStatusBadge,\n StudioSurface,\n} from \"../../components/ui/studio\";\nimport { cn } from \"../../lib/utils\";\nimport { errorMessage } from \"../shared/format\";\n\nconst maxInlinePreviewBytes = 1024 * 1024;\nconst textExtensions = new Set([\n \"css\",\n \"csv\",\n \"env\",\n \"gitignore\",\n \"graphql\",\n \"html\",\n \"ini\",\n \"java\",\n \"js\",\n \"json\",\n \"jsx\",\n \"log\",\n \"md\",\n \"mdx\",\n \"mjs\",\n \"py\",\n \"rb\",\n \"rs\",\n \"sh\",\n \"sql\",\n \"svg\",\n \"toml\",\n \"ts\",\n \"tsx\",\n \"txt\",\n \"xml\",\n \"yaml\",\n \"yml\",\n]);\nconst imageTypes = new Map([\n [\"gif\", \"image/gif\"],\n [\"jpeg\", \"image/jpeg\"],\n [\"jpg\", \"image/jpeg\"],\n [\"png\", \"image/png\"],\n [\"webp\", \"image/webp\"],\n]);\n\ntype LoadState = \"idle\" | \"loading\";\ntype FilePreview =\n | { kind: \"binary\" | \"large\"; file: StudioSandboxFileEntry }\n | { kind: \"image\"; file: StudioSandboxFileEntry; url: string }\n | { kind: \"loading\"; file: StudioSandboxFileEntry }\n | { kind: \"text\"; file: StudioSandboxFileEntry; text: string };\n\nexport function SandboxesPage(props: {\n enabled: boolean;\n initialSandboxRef?: string;\n onError: (message: string) => void;\n onSelectSandbox: (sandboxRef: string) => void;\n}) {\n const [sandboxes, setSandboxes] = useState<StudioSandboxSummary[]>([]);\n const [summaryLoadState, setSummaryLoadState] = useState<LoadState>(\"idle\");\n const [refreshSequence, setRefreshSequence] = useState(0);\n const [currentPath, setCurrentPath] = useState(\".\");\n const [files, setFiles] = useState<StudioSandboxFileEntry[]>([]);\n const [fileLoadState, setFileLoadState] = useState<LoadState>(\"idle\");\n const [preview, setPreview] = useState<FilePreview | undefined>();\n const [ports, setPorts] = useState<StudioSandboxPort[]>([]);\n const [processes, setProcesses] = useState<StudioSandboxProcess[]>([]);\n const [runtimeLoadState, setRuntimeLoadState] = useState<LoadState>(\"idle\");\n const [selectedProcessId, setSelectedProcessId] = useState(\"\");\n const [processLogs, setProcessLogs] = useState<StudioSandboxProcessLogsResponse | undefined>();\n const [localError, setLocalError] = useState(\"\");\n const previewRequest = useRef<AbortController | undefined>(undefined);\n\n const selectedRef = props.initialSandboxRef ?? sandboxes[0]?.ref ?? \"\";\n const selectedSandbox = sandboxes.find((sandbox) => sandbox.ref === selectedRef);\n const selectedSandboxRef = selectedSandbox?.ref;\n const supportsPorts = selectedSandbox?.capabilities.ports ?? false;\n const supportsProcesses = selectedSandbox?.capabilities.processes ?? false;\n\n const reportError = useCallback(\n (error: unknown) => {\n const message = errorMessage(error);\n setLocalError(message);\n props.onError(message);\n },\n [props.onError],\n );\n\n useEffect(() => {\n if (!props.enabled) {\n setSandboxes([]);\n return;\n }\n const controller = new AbortController();\n setSummaryLoadState(\"loading\");\n setLocalError(\"\");\n void requestJson<StudioSandboxesSummary>(\n \"/sandboxes\",\n \"Sandboxes\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then((summary) => setSandboxes(summary.sandboxes))\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n })\n .finally(() => {\n if (!controller.signal.aborted) setSummaryLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [props.enabled, refreshSequence, reportError]);\n\n useEffect(() => {\n if (props.initialSandboxRef === undefined && sandboxes[0] !== undefined) {\n props.onSelectSandbox(sandboxes[0].ref);\n }\n }, [props.initialSandboxRef, props.onSelectSandbox, sandboxes]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: changing the route selection must reset sandbox-local view state.\n useEffect(() => {\n setCurrentPath(\".\");\n setFiles([]);\n setPreview(undefined);\n setPorts([]);\n setProcesses([]);\n setSelectedProcessId(\"\");\n setProcessLogs(undefined);\n return () => previewRequest.current?.abort();\n }, [selectedRef]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined) {\n return;\n }\n const controller = new AbortController();\n setFileLoadState(\"loading\");\n const params = new URLSearchParams({ path: currentPath });\n void requestJson<StudioSandboxFilesResponse>(\n `/sandboxes/${encodeURIComponent(selectedSandboxRef)}/files?${params}`,\n \"Sandbox files\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then((response) => setFiles(response.entries))\n .catch((error: unknown) => {\n if (!controller.signal.aborted) {\n setFiles([]);\n reportError(error);\n }\n })\n .finally(() => {\n if (!controller.signal.aborted) setFileLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [currentPath, refreshSequence, reportError, selectedSandboxRef]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined) {\n return;\n }\n const controller = new AbortController();\n setRuntimeLoadState(\"loading\");\n const base = `/sandboxes/${encodeURIComponent(selectedSandboxRef)}`;\n const requests: Promise<void>[] = [];\n if (supportsPorts) {\n requests.push(\n requestJson<StudioSandboxPortsResponse>(\n `${base}/ports`,\n \"Sandbox ports\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n ).then((response) => setPorts(response.ports)),\n );\n } else {\n setPorts([]);\n }\n if (supportsProcesses) {\n requests.push(\n requestJson<StudioSandboxProcessesResponse>(\n `${base}/processes`,\n \"Sandbox processes\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n ).then((response) => {\n setProcesses(response.processes);\n setSelectedProcessId((current) =>\n response.processes.some((process) => process.id === current) ? current : \"\",\n );\n }),\n );\n } else {\n setProcesses([]);\n setSelectedProcessId(\"\");\n }\n void Promise.all(requests)\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n })\n .finally(() => {\n if (!controller.signal.aborted) setRuntimeLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [refreshSequence, reportError, selectedSandboxRef, supportsPorts, supportsProcesses]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined || selectedProcessId.length === 0) {\n setProcessLogs(undefined);\n return;\n }\n const controller = new AbortController();\n const base = `/sandboxes/${encodeURIComponent(selectedSandboxRef)}/processes`;\n void requestJson<StudioSandboxProcessLogsResponse>(\n `${base}/${encodeURIComponent(selectedProcessId)}/logs`,\n \"Process logs\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then(setProcessLogs)\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n });\n return () => controller.abort();\n }, [refreshSequence, reportError, selectedProcessId, selectedSandboxRef]);\n\n useEffect(\n () => () => {\n if (preview?.kind === \"image\") URL.revokeObjectURL(preview.url);\n },\n [preview],\n );\n\n const clearPreview = useCallback(() => {\n previewRequest.current?.abort();\n previewRequest.current = undefined;\n setPreview(undefined);\n }, []);\n\n const openFile = useCallback(\n async (file: StudioSandboxFileEntry) => {\n previewRequest.current?.abort();\n previewRequest.current = undefined;\n if (selectedSandboxRef === undefined) {\n return;\n }\n if ((file.size ?? 0) > maxInlinePreviewBytes) {\n setPreview({ kind: \"large\", file });\n return;\n }\n const extension = fileExtension(file.path);\n const imageType = imageTypes.get(extension);\n if (!textExtensions.has(extension) && imageType === undefined) {\n setPreview({ kind: \"binary\", file });\n return;\n }\n\n setPreview({ kind: \"loading\", file });\n setLocalError(\"\");\n const controller = new AbortController();\n previewRequest.current = controller;\n try {\n const response = await fetch(fileContentUrl(selectedSandboxRef, file.path), {\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(await responseErrorMessage(response, \"Sandbox file\"));\n }\n const bytes = await response.arrayBuffer();\n if (bytes.byteLength > maxInlinePreviewBytes) {\n setPreview({ kind: \"large\", file });\n return;\n }\n if (imageType !== undefined) {\n const url = URL.createObjectURL(new Blob([bytes], { type: imageType }));\n setPreview({ kind: \"image\", file, url });\n return;\n }\n try {\n const text = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n setPreview({ kind: \"text\", file, text });\n } catch {\n setPreview({ kind: \"binary\", file });\n }\n } catch (error) {\n if (controller.signal.aborted) return;\n reportError(error);\n setPreview({ kind: \"binary\", file });\n } finally {\n if (previewRequest.current === controller) previewRequest.current = undefined;\n }\n },\n [reportError, selectedSandboxRef],\n );\n\n if (!props.enabled) {\n return (\n <StudioPageShell className=\"p-4\" aria-label=\"Sandboxes\">\n <StudioEmptyState\n title=\"No sandbox workspaces\"\n text=\"Add tools created by createSandboxTools(session) to an agent to inspect its live workspace here.\"\n />\n </StudioPageShell>\n );\n }\n\n return (\n <StudioPageShell\n className=\"grid grid-rows-[auto_minmax(0,1fr)] gap-3 p-3\"\n aria-label=\"Sandboxes\"\n >\n <StudioSurface className=\"flex items-center justify-between gap-4 rounded-xl px-5 py-3.5\">\n <div className=\"min-w-0\">\n <h1 className=\"m-0 text-base font-semibold text-foreground\">Live sandbox workspaces</h1>\n <p className=\"m-0 mt-0.5 text-xs leading-5 text-muted-foreground\">\n Read-only files, published ports, and managed processes discovered from agent tools.\n </p>\n </div>\n <Button\n disabled={summaryLoadState === \"loading\"}\n size=\"sm\"\n type=\"button\"\n variant=\"secondary\"\n onClick={() => setRefreshSequence((current) => current + 1)}\n >\n <StudioIcon icon={RefreshIcon} aria-hidden=\"true\" />\n Refresh\n </Button>\n </StudioSurface>\n\n {sandboxes.length === 0 && summaryLoadState === \"idle\" ? (\n <StudioEmptyState\n className=\"h-full\"\n title=\"No live sandboxes detected\"\n text=\"Studio discovers sessions automatically from tools returned by createSandboxTools(session).\"\n />\n ) : (\n <div className=\"grid min-h-0 min-w-0 grid-cols-[250px_minmax(300px,0.8fr)_minmax(400px,1.2fr)] gap-3 overflow-hidden\">\n <SandboxRail\n sandboxes={sandboxes}\n selectedRef={selectedRef}\n onSelect={props.onSelectSandbox}\n />\n <FileBrowser\n currentPath={currentPath}\n files={files}\n loading={fileLoadState === \"loading\"}\n onOpenDirectory={(filePath) => {\n clearPreview();\n setCurrentPath(filePath);\n }}\n onOpenFile={(file) => void openFile(file)}\n onSelectPath={(filePath) => {\n clearPreview();\n setCurrentPath(filePath);\n }}\n />\n <div className=\"grid min-h-0 gap-3 overflow-y-auto pr-1\">\n {selectedSandbox === undefined ? (\n <StudioEmptyState\n title=\"Sandbox unavailable\"\n text=\"The requested live sandbox is not registered by this Studio runtime.\"\n />\n ) : (\n <>\n <SandboxOverview sandbox={selectedSandbox} error={localError} />\n <FilePreviewPanel preview={preview} sandboxRef={selectedSandbox.ref} />\n <RuntimePanel\n loading={runtimeLoadState === \"loading\"}\n logs={processLogs}\n ports={ports}\n processes={processes}\n selectedProcessId={selectedProcessId}\n supportsPorts={selectedSandbox.capabilities.ports}\n supportsProcesses={selectedSandbox.capabilities.processes}\n onSelectProcess={setSelectedProcessId}\n />\n </>\n )}\n </div>\n </div>\n )}\n </StudioPageShell>\n );\n}\n\nfunction SandboxRail(props: {\n sandboxes: StudioSandboxSummary[];\n selectedRef: string;\n onSelect: (sandboxRef: string) => void;\n}) {\n return (\n <StudioSurface className=\"grid min-h-0 grid-rows-[auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"border-b border-border/70 px-4 py-3\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Workspaces\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">\n {props.sandboxes.length} live {props.sandboxes.length === 1 ? \"session\" : \"sessions\"}\n </p>\n </div>\n <div className=\"min-h-0 overflow-y-auto p-2\">\n {props.sandboxes.map((sandbox) => (\n <Button\n className={cn(\n \"mb-1 grid h-auto min-h-16 w-full justify-stretch gap-1 rounded-lg px-3 py-2.5 text-left\",\n sandbox.ref === props.selectedRef && \"border-border bg-accent text-foreground\",\n )}\n key={sandbox.ref}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelect(sandbox.ref)}\n >\n <span className=\"flex min-w-0 items-center justify-between gap-2\">\n <strong className=\"truncate text-sm font-semibold text-foreground\">\n {sandbox.id}\n </strong>\n <StudioStatusBadge className=\"shrink-0 px-1.5 py-0.5 text-[10px]\">\n {sandbox.provider}\n </StudioStatusBadge>\n </span>\n <span className=\"truncate font-mono text-[11px] font-normal text-muted-foreground\">\n {sandbox.workdir}\n </span>\n </Button>\n ))}\n </div>\n </StudioSurface>\n );\n}\n\nfunction FileBrowser(props: {\n currentPath: string;\n files: StudioSandboxFileEntry[];\n loading: boolean;\n onOpenDirectory: (path: string) => void;\n onOpenFile: (file: StudioSandboxFileEntry) => void;\n onSelectPath: (path: string) => void;\n}) {\n const breadcrumbs = useMemo(() => sandboxBreadcrumbs(props.currentPath), [props.currentPath]);\n return (\n <StudioSurface className=\"grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"border-b border-border/70 px-4 py-3\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Files\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">One level at a time</p>\n </div>\n <div className=\"flex min-h-10 items-center gap-1 overflow-x-auto border-b border-border/70 px-3 py-1.5\">\n {breadcrumbs.map((breadcrumb, index) => (\n <span className=\"flex items-center gap-1\" key={breadcrumb.path}>\n {index > 0 ? <span className=\"text-muted-foreground/60\">/</span> : null}\n <Button\n className=\"h-7 min-h-7 px-2 font-mono text-xs\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelectPath(breadcrumb.path)}\n >\n {breadcrumb.label}\n </Button>\n </span>\n ))}\n </div>\n <div className=\"min-h-0 overflow-y-auto p-2\">\n {props.loading ? (\n <p className=\"m-0 px-3 py-4 text-xs text-muted-foreground\">Loading workspace</p>\n ) : null}\n {!props.loading && props.files.length === 0 ? (\n <p className=\"m-0 px-3 py-4 text-xs text-muted-foreground\">This directory is empty.</p>\n ) : null}\n {props.files.map((file) => (\n <Button\n className=\"mb-0.5 grid h-10 min-h-10 w-full grid-cols-[18px_minmax(0,1fr)_auto] justify-stretch gap-2 rounded-md px-2.5 text-left text-xs font-medium\"\n key={file.path}\n type=\"button\"\n variant=\"ghost\"\n onClick={() =>\n file.type === \"directory\" ? props.onOpenDirectory(file.path) : props.onOpenFile(file)\n }\n >\n <StudioIcon\n className=\"text-muted-foreground\"\n icon={file.type === \"directory\" ? FolderOpenIcon : File01Icon}\n aria-hidden=\"true\"\n />\n <span className=\"truncate text-foreground\">{basename(file.path)}</span>\n <span className=\"font-mono text-[10px] font-normal text-muted-foreground\">\n {file.type === \"file\" ? formatBytes(file.size) : file.type}\n </span>\n </Button>\n ))}\n </div>\n </StudioSurface>\n );\n}\n\nfunction SandboxOverview(props: { sandbox: StudioSandboxSummary; error: string }) {\n return (\n <StudioSurface className=\"rounded-xl p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Active sandbox\n </span>\n <h2 className=\"m-0 mt-1 truncate text-lg font-semibold text-foreground\">\n {props.sandbox.id}\n </h2>\n <p className=\"m-0 mt-1 truncate font-mono text-xs text-muted-foreground\">\n {props.sandbox.workdir}\n </p>\n </div>\n <StudioStatusBadge>{props.sandbox.provider}</StudioStatusBadge>\n </div>\n <div className=\"mt-4 grid grid-cols-2 gap-3 text-xs\">\n <MetadataList label=\"Agents\" values={props.sandbox.agentIds} />\n <MetadataList label=\"Sandbox tools\" values={props.sandbox.toolNames} />\n </div>\n {props.error.length > 0 ? (\n <p className=\"m-0 mt-3 rounded-lg border border-destructive/25 bg-destructive/5 px-3 py-2 text-xs leading-5 text-destructive\">\n {props.error}\n </p>\n ) : null}\n </StudioSurface>\n );\n}\n\nfunction MetadataList(props: { label: string; values: string[] }) {\n return (\n <div className=\"rounded-lg border border-border/70 bg-background/45 p-3\">\n <span className=\"font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {props.label}\n </span>\n <p className=\"m-0 mt-1 break-words font-mono leading-5 text-foreground\">\n {props.values.join(\", \") || \"-\"}\n </p>\n </div>\n );\n}\n\nfunction FilePreviewPanel(props: { preview: FilePreview | undefined; sandboxRef: string }) {\n const file = props.preview?.file;\n return (\n <StudioSurface className=\"grid min-h-64 grid-rows-[auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"flex min-h-12 items-center justify-between gap-3 border-b border-border/70 px-4 py-2\">\n <div className=\"min-w-0\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Preview\n </span>\n <p className=\"m-0 mt-0.5 truncate font-mono text-[11px] text-muted-foreground\">\n {file?.path ?? \"Select a file\"}\n </p>\n </div>\n {file !== undefined ? (\n <Button asChild size=\"sm\" variant=\"secondary\">\n <a href={fileContentUrl(props.sandboxRef, file.path, true)}>\n <StudioIcon icon={Download01Icon} aria-hidden=\"true\" />\n Download\n </a>\n </Button>\n ) : null}\n </div>\n <div className=\"grid min-h-0 place-items-center overflow-auto bg-background/35 p-4\">\n {props.preview === undefined ? (\n <p className=\"m-0 text-center text-xs leading-5 text-muted-foreground\">\n Choose a regular file to inspect its contents.\n </p>\n ) : null}\n {props.preview?.kind === \"loading\" ? (\n <p className=\"m-0 text-xs text-muted-foreground\">Loading preview</p>\n ) : null}\n {props.preview?.kind === \"text\" ? (\n <pre className=\"m-0 h-full min-h-48 w-full overflow-auto whitespace-pre-wrap break-words rounded-lg border border-border/70 bg-card/60 p-4 font-mono text-xs leading-5 text-foreground\">\n {props.preview.text}\n </pre>\n ) : null}\n {props.preview?.kind === \"image\" ? (\n <img\n className=\"max-h-96 max-w-full rounded-lg border border-border/70 object-contain\"\n src={props.preview.url}\n alt={basename(props.preview.file.path)}\n />\n ) : null}\n {props.preview?.kind === \"binary\" ? (\n <PreviewNotice text=\"This file type is download-only and will not be rendered in Studio.\" />\n ) : null}\n {props.preview?.kind === \"large\" ? (\n <PreviewNotice text=\"This file is larger than the 1 MiB inline preview limit.\" />\n ) : null}\n </div>\n </StudioSurface>\n );\n}\n\nfunction PreviewNotice(props: { text: string }) {\n return (\n <div className=\"grid max-w-sm justify-items-center gap-2 text-center\">\n <StudioIcon className=\"h-6 w-6 text-muted-foreground\" icon={File01Icon} aria-hidden=\"true\" />\n <p className=\"m-0 text-xs leading-5 text-muted-foreground\">{props.text}</p>\n </div>\n );\n}\n\nfunction RuntimePanel(props: {\n loading: boolean;\n logs: StudioSandboxProcessLogsResponse | undefined;\n ports: StudioSandboxPort[];\n processes: StudioSandboxProcess[];\n selectedProcessId: string;\n supportsPorts: boolean;\n supportsProcesses: boolean;\n onSelectProcess: (processId: string) => void;\n}) {\n return (\n <StudioSurface className=\"rounded-xl p-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Runtime\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">\n Published ports and managed processes\n </p>\n </div>\n {props.loading ? <StudioStatusBadge>Refreshing</StudioStatusBadge> : null}\n </div>\n\n <div className=\"mt-4 grid gap-4\">\n <RuntimeSection title=\"Ports\">\n {!props.supportsPorts ? (\n <RuntimeEmpty text=\"Published ports are not supported by this sandbox.\" />\n ) : props.ports.length === 0 ? (\n <RuntimeEmpty text=\"No ports are published.\" />\n ) : (\n <div className=\"grid gap-1\">\n {props.ports.map((port) => (\n <div\n className=\"grid grid-cols-[90px_minmax(0,1fr)] gap-3 rounded-md border border-border/60 px-3 py-2 font-mono text-xs\"\n key={`${port.containerPort}:${port.hostPort}`}\n >\n <span className=\"text-foreground\">\n {port.containerPort}/{port.protocol}\n </span>\n <span className=\"truncate text-muted-foreground\">\n {port.host}:{port.hostPort}\n </span>\n </div>\n ))}\n </div>\n )}\n </RuntimeSection>\n\n <RuntimeSection title=\"Processes\">\n {!props.supportsProcesses ? (\n <RuntimeEmpty text=\"Managed processes are not supported by this sandbox.\" />\n ) : props.processes.length === 0 ? (\n <RuntimeEmpty text=\"No managed processes are recorded.\" />\n ) : (\n <div className=\"grid gap-1\">\n {props.processes.map((process) => (\n <Button\n className={cn(\n \"grid h-auto min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] justify-stretch gap-3 rounded-md px-3 py-2 text-left\",\n process.id === props.selectedProcessId &&\n \"border-border bg-accent text-foreground\",\n )}\n key={process.id}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelectProcess(process.id)}\n >\n <span className=\"flex min-w-0 items-center gap-2\">\n <StudioIcon\n className=\"text-muted-foreground\"\n icon={ComputerTerminal01Icon}\n aria-hidden=\"true\"\n />\n <span className=\"truncate font-mono text-xs text-foreground\">\n {[process.command, ...process.args].join(\" \")}\n </span>\n </span>\n <StudioStatusBadge className=\"px-1.5 py-0.5 text-[10px]\">\n {process.status}\n </StudioStatusBadge>\n </Button>\n ))}\n </div>\n )}\n </RuntimeSection>\n\n {props.selectedProcessId.length > 0 ? (\n <RuntimeSection title=\"Process logs\">\n {props.logs === undefined ? (\n <RuntimeEmpty text=\"Loading the latest bounded output.\" />\n ) : (\n <div className=\"grid gap-2\">\n <LogBlock\n label=\"stdout\"\n text={props.logs.stdout}\n truncated={props.logs.stdoutTruncated}\n />\n <LogBlock\n label=\"stderr\"\n text={props.logs.stderr}\n truncated={props.logs.stderrTruncated}\n />\n </div>\n )}\n </RuntimeSection>\n ) : null}\n </div>\n </StudioSurface>\n );\n}\n\nfunction RuntimeSection(props: { title: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-2\">\n <h3 className=\"m-0 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n {props.title}\n </h3>\n {props.children}\n </section>\n );\n}\n\nfunction RuntimeEmpty(props: { text: string }) {\n return (\n <p className=\"m-0 rounded-md border border-dashed border-border/70 px-3 py-2 text-xs leading-5 text-muted-foreground\">\n {props.text}\n </p>\n );\n}\n\nfunction LogBlock(props: { label: string; text: string; truncated: boolean }) {\n return (\n <div className=\"overflow-hidden rounded-md border border-border/70 bg-background/55\">\n <div className=\"flex items-center justify-between border-b border-border/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n <span>{props.label}</span>\n {props.truncated ? <span>truncated</span> : null}\n </div>\n <pre className=\"m-0 max-h-48 overflow-auto whitespace-pre-wrap break-words p-3 font-mono text-[11px] leading-5 text-foreground\">\n {props.text || \"No output\"}\n </pre>\n </div>\n );\n}\n\nasync function requestJson<T>(\n url: string,\n label: string,\n signal: AbortSignal,\n cache: RequestCache = \"default\",\n): Promise<T> {\n const response = await fetch(url, { cache, signal });\n if (!response.ok) {\n throw new Error(await responseErrorMessage(response, label));\n }\n return (await response.json()) as T;\n}\n\nfunction sandboxBreadcrumbs(filePath: string): Array<{ label: string; path: string }> {\n const segments = filePath === \".\" ? [] : filePath.split(\"/\").filter(Boolean);\n const breadcrumbs = [{ label: \"/\", path: \".\" }];\n for (let index = 0; index < segments.length; index += 1) {\n breadcrumbs.push({\n label: segments[index] ?? \"\",\n path: segments.slice(0, index + 1).join(\"/\"),\n });\n }\n return breadcrumbs;\n}\n\nfunction fileContentUrl(sandboxRef: string, filePath: string, download = false): string {\n const params = new URLSearchParams({ path: filePath });\n if (download) params.set(\"download\", \"1\");\n return `/sandboxes/${encodeURIComponent(sandboxRef)}/files/content?${params}`;\n}\n\nfunction fileExtension(filePath: string): string {\n const name = basename(filePath).toLowerCase();\n const dot = name.lastIndexOf(\".\");\n return dot < 0 ? name : name.slice(dot + 1);\n}\n\nfunction basename(filePath: string): string {\n return filePath.split(\"/\").at(-1) ?? filePath;\n}\n\nfunction formatBytes(size: number | undefined): string {\n if (size === undefined) return \"-\";\n if (size < 1024) return `${size} B`;\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KiB`;\n return `${(size / (1024 * 1024)).toFixed(1)} MiB`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"sandboxes-page-j51ihKpC.js","names":[],"sources":["../../../src/ui/app/modules/sandboxes/sandboxes-page.tsx"],"sourcesContent":["import {\n ComputerTerminal01Icon,\n Download01Icon,\n File01Icon,\n FolderOpenIcon,\n RefreshIcon,\n} from \"@hugeicons/core-free-icons\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport type {\n StudioSandboxesSummary,\n StudioSandboxFileEntry,\n StudioSandboxFilesResponse,\n StudioSandboxPort,\n StudioSandboxPortsResponse,\n StudioSandboxProcess,\n StudioSandboxProcessesResponse,\n StudioSandboxProcessLogsResponse,\n StudioSandboxSummary,\n} from \"../../../../types\";\nimport { responseErrorMessage } from \"../../app-errors\";\nimport { Button } from \"../../components/ui/button\";\nimport { StudioIcon } from \"../../components/ui/icon\";\nimport {\n StudioEmptyState,\n StudioPageShell,\n StudioStatusBadge,\n StudioSurface,\n} from \"../../components/ui/studio\";\nimport { cn } from \"../../lib/utils\";\nimport { errorMessage } from \"../shared/format\";\n\nconst maxInlinePreviewBytes = 1024 * 1024;\nconst textExtensions = new Set([\n \"css\",\n \"csv\",\n \"env\",\n \"gitignore\",\n \"graphql\",\n \"html\",\n \"ini\",\n \"java\",\n \"js\",\n \"json\",\n \"jsx\",\n \"log\",\n \"md\",\n \"mdx\",\n \"mjs\",\n \"py\",\n \"rb\",\n \"rs\",\n \"sh\",\n \"sql\",\n \"svg\",\n \"toml\",\n \"ts\",\n \"tsx\",\n \"txt\",\n \"xml\",\n \"yaml\",\n \"yml\",\n]);\nconst imageTypes = new Map([\n [\"gif\", \"image/gif\"],\n [\"jpeg\", \"image/jpeg\"],\n [\"jpg\", \"image/jpeg\"],\n [\"png\", \"image/png\"],\n [\"webp\", \"image/webp\"],\n]);\n\ntype LoadState = \"idle\" | \"loading\";\ntype FilePreview =\n | { kind: \"binary\" | \"large\"; file: StudioSandboxFileEntry }\n | { kind: \"image\"; file: StudioSandboxFileEntry; url: string }\n | { kind: \"loading\"; file: StudioSandboxFileEntry }\n | { kind: \"text\"; file: StudioSandboxFileEntry; text: string };\n\nexport function SandboxesPage(props: {\n enabled: boolean;\n initialSandboxRef?: string;\n onError: (message: string) => void;\n onSelectSandbox: (sandboxRef: string) => void;\n}) {\n const [sandboxes, setSandboxes] = useState<StudioSandboxSummary[]>([]);\n const [summaryLoadState, setSummaryLoadState] = useState<LoadState>(\"idle\");\n const [refreshSequence, setRefreshSequence] = useState(0);\n const [currentPath, setCurrentPath] = useState(\".\");\n const [files, setFiles] = useState<StudioSandboxFileEntry[]>([]);\n const [fileLoadState, setFileLoadState] = useState<LoadState>(\"idle\");\n const [preview, setPreview] = useState<FilePreview | undefined>();\n const [ports, setPorts] = useState<StudioSandboxPort[]>([]);\n const [processes, setProcesses] = useState<StudioSandboxProcess[]>([]);\n const [runtimeLoadState, setRuntimeLoadState] = useState<LoadState>(\"idle\");\n const [selectedProcessId, setSelectedProcessId] = useState(\"\");\n const [processLogs, setProcessLogs] = useState<StudioSandboxProcessLogsResponse | undefined>();\n const [localError, setLocalError] = useState(\"\");\n const previewRequest = useRef<AbortController | undefined>(undefined);\n\n const selectedRef = props.initialSandboxRef ?? sandboxes[0]?.ref ?? \"\";\n const selectedSandbox = sandboxes.find((sandbox) => sandbox.ref === selectedRef);\n const selectedSandboxRef = selectedSandbox?.ref;\n const supportsPorts = selectedSandbox?.capabilities.ports ?? false;\n const supportsProcesses = selectedSandbox?.capabilities.processes ?? false;\n\n const reportError = useCallback(\n (error: unknown) => {\n const message = errorMessage(error);\n setLocalError(message);\n props.onError(message);\n },\n [props.onError],\n );\n\n useEffect(() => {\n if (!props.enabled) {\n setSandboxes([]);\n return;\n }\n const controller = new AbortController();\n setSummaryLoadState(\"loading\");\n setLocalError(\"\");\n void requestJson<StudioSandboxesSummary>(\n \"/sandboxes\",\n \"Sandboxes\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then((summary) => setSandboxes(summary.sandboxes))\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n })\n .finally(() => {\n if (!controller.signal.aborted) setSummaryLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [props.enabled, refreshSequence, reportError]);\n\n useEffect(() => {\n if (props.initialSandboxRef === undefined && sandboxes[0] !== undefined) {\n props.onSelectSandbox(sandboxes[0].ref);\n }\n }, [props.initialSandboxRef, props.onSelectSandbox, sandboxes]);\n\n // biome-ignore lint/correctness/useExhaustiveDependencies: changing the route selection must reset sandbox-local view state.\n useEffect(() => {\n setCurrentPath(\".\");\n setFiles([]);\n setPreview(undefined);\n setPorts([]);\n setProcesses([]);\n setSelectedProcessId(\"\");\n setProcessLogs(undefined);\n return () => previewRequest.current?.abort();\n }, [selectedRef]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined) {\n return;\n }\n const controller = new AbortController();\n setFileLoadState(\"loading\");\n const params = new URLSearchParams({ path: currentPath });\n void requestJson<StudioSandboxFilesResponse>(\n `/sandboxes/${encodeURIComponent(selectedSandboxRef)}/files?${params}`,\n \"Sandbox files\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then((response) => setFiles(response.entries))\n .catch((error: unknown) => {\n if (!controller.signal.aborted) {\n setFiles([]);\n reportError(error);\n }\n })\n .finally(() => {\n if (!controller.signal.aborted) setFileLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [currentPath, refreshSequence, reportError, selectedSandboxRef]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined) {\n return;\n }\n const controller = new AbortController();\n setRuntimeLoadState(\"loading\");\n const base = `/sandboxes/${encodeURIComponent(selectedSandboxRef)}`;\n const requests: Promise<void>[] = [];\n if (supportsPorts) {\n requests.push(\n requestJson<StudioSandboxPortsResponse>(\n `${base}/ports`,\n \"Sandbox ports\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n ).then((response) => setPorts(response.ports)),\n );\n } else {\n setPorts([]);\n }\n if (supportsProcesses) {\n requests.push(\n requestJson<StudioSandboxProcessesResponse>(\n `${base}/processes`,\n \"Sandbox processes\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n ).then((response) => {\n setProcesses(response.processes);\n setSelectedProcessId((current) =>\n response.processes.some((process) => process.id === current) ? current : \"\",\n );\n }),\n );\n } else {\n setProcesses([]);\n setSelectedProcessId(\"\");\n }\n void Promise.all(requests)\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n })\n .finally(() => {\n if (!controller.signal.aborted) setRuntimeLoadState(\"idle\");\n });\n return () => controller.abort();\n }, [refreshSequence, reportError, selectedSandboxRef, supportsPorts, supportsProcesses]);\n\n useEffect(() => {\n if (selectedSandboxRef === undefined || selectedProcessId.length === 0) {\n setProcessLogs(undefined);\n return;\n }\n const controller = new AbortController();\n const base = `/sandboxes/${encodeURIComponent(selectedSandboxRef)}/processes`;\n void requestJson<StudioSandboxProcessLogsResponse>(\n `${base}/${encodeURIComponent(selectedProcessId)}/logs`,\n \"Process logs\",\n controller.signal,\n refreshSequence === 0 ? \"default\" : \"reload\",\n )\n .then(setProcessLogs)\n .catch((error: unknown) => {\n if (!controller.signal.aborted) reportError(error);\n });\n return () => controller.abort();\n }, [refreshSequence, reportError, selectedProcessId, selectedSandboxRef]);\n\n useEffect(\n () => () => {\n if (preview?.kind === \"image\") URL.revokeObjectURL(preview.url);\n },\n [preview],\n );\n\n const clearPreview = useCallback(() => {\n previewRequest.current?.abort();\n previewRequest.current = undefined;\n setPreview(undefined);\n }, []);\n\n const openFile = useCallback(\n async (file: StudioSandboxFileEntry) => {\n previewRequest.current?.abort();\n previewRequest.current = undefined;\n if (selectedSandboxRef === undefined) {\n return;\n }\n if ((file.size ?? 0) > maxInlinePreviewBytes) {\n setPreview({ kind: \"large\", file });\n return;\n }\n const extension = fileExtension(file.path);\n const imageType = imageTypes.get(extension);\n if (!textExtensions.has(extension) && imageType === undefined) {\n setPreview({ kind: \"binary\", file });\n return;\n }\n\n setPreview({ kind: \"loading\", file });\n setLocalError(\"\");\n const controller = new AbortController();\n previewRequest.current = controller;\n try {\n const response = await fetch(fileContentUrl(selectedSandboxRef, file.path), {\n signal: controller.signal,\n });\n if (!response.ok) {\n throw new Error(await responseErrorMessage(response, \"Sandbox file\"));\n }\n const bytes = await response.arrayBuffer();\n if (bytes.byteLength > maxInlinePreviewBytes) {\n setPreview({ kind: \"large\", file });\n return;\n }\n if (imageType !== undefined) {\n const url = URL.createObjectURL(new Blob([bytes], { type: imageType }));\n setPreview({ kind: \"image\", file, url });\n return;\n }\n try {\n const text = new TextDecoder(\"utf-8\", { fatal: true }).decode(bytes);\n setPreview({ kind: \"text\", file, text });\n } catch {\n setPreview({ kind: \"binary\", file });\n }\n } catch (error) {\n if (controller.signal.aborted) return;\n reportError(error);\n setPreview({ kind: \"binary\", file });\n } finally {\n if (previewRequest.current === controller) previewRequest.current = undefined;\n }\n },\n [reportError, selectedSandboxRef],\n );\n\n if (!props.enabled) {\n return (\n <StudioPageShell className=\"p-4\" aria-label=\"Sandboxes\">\n <StudioEmptyState\n title=\"No sandbox workspaces\"\n text=\"Add tools created by createSandboxTools(session) to an agent to inspect its live workspace here.\"\n />\n </StudioPageShell>\n );\n }\n\n return (\n <StudioPageShell\n className=\"grid grid-rows-[auto_minmax(0,1fr)] gap-3 p-3\"\n aria-label=\"Sandboxes\"\n >\n <StudioSurface className=\"flex items-center justify-between gap-4 rounded-xl px-5 py-3.5\">\n <div className=\"min-w-0\">\n <h1 className=\"m-0 text-base font-semibold text-foreground\">Live sandbox workspaces</h1>\n <p className=\"m-0 mt-0.5 text-xs leading-5 text-muted-foreground\">\n Read-only files, published ports, and managed processes discovered from agent tools.\n </p>\n </div>\n <Button\n disabled={summaryLoadState === \"loading\"}\n size=\"sm\"\n type=\"button\"\n variant=\"secondary\"\n onClick={() => setRefreshSequence((current) => current + 1)}\n >\n <StudioIcon icon={RefreshIcon} aria-hidden=\"true\" />\n Refresh\n </Button>\n </StudioSurface>\n\n {sandboxes.length === 0 && summaryLoadState === \"idle\" ? (\n <StudioEmptyState\n className=\"h-full\"\n title=\"No live sandboxes detected\"\n text=\"Studio discovers sessions automatically from tools returned by createSandboxTools(session).\"\n />\n ) : (\n <div className=\"grid min-h-0 min-w-0 grid-cols-[250px_minmax(300px,0.8fr)_minmax(400px,1.2fr)] gap-3 overflow-hidden\">\n <SandboxRail\n sandboxes={sandboxes}\n selectedRef={selectedRef}\n onSelect={props.onSelectSandbox}\n />\n <FileBrowser\n currentPath={currentPath}\n files={files}\n loading={fileLoadState === \"loading\"}\n onOpenDirectory={(filePath) => {\n clearPreview();\n setCurrentPath(filePath);\n }}\n onOpenFile={(file) => void openFile(file)}\n onSelectPath={(filePath) => {\n clearPreview();\n setCurrentPath(filePath);\n }}\n />\n <div className=\"grid min-h-0 gap-3 overflow-y-auto pr-1\">\n {selectedSandbox === undefined ? (\n <StudioEmptyState\n title=\"Sandbox unavailable\"\n text=\"The requested live sandbox is not registered by this Studio runtime.\"\n />\n ) : (\n <>\n <SandboxOverview sandbox={selectedSandbox} error={localError} />\n <FilePreviewPanel preview={preview} sandboxRef={selectedSandbox.ref} />\n <RuntimePanel\n loading={runtimeLoadState === \"loading\"}\n logs={processLogs}\n ports={ports}\n processes={processes}\n selectedProcessId={selectedProcessId}\n supportsPorts={selectedSandbox.capabilities.ports}\n supportsProcesses={selectedSandbox.capabilities.processes}\n onSelectProcess={setSelectedProcessId}\n />\n </>\n )}\n </div>\n </div>\n )}\n </StudioPageShell>\n );\n}\n\nfunction SandboxRail(props: {\n sandboxes: StudioSandboxSummary[];\n selectedRef: string;\n onSelect: (sandboxRef: string) => void;\n}) {\n return (\n <StudioSurface className=\"grid min-h-0 grid-rows-[auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"border-b border-border/70 px-4 py-3\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Workspaces\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">\n {props.sandboxes.length} live {props.sandboxes.length === 1 ? \"session\" : \"sessions\"}\n </p>\n </div>\n <div className=\"min-h-0 overflow-y-auto p-2\">\n {props.sandboxes.map((sandbox) => (\n <Button\n className={cn(\n \"mb-1 grid h-auto min-h-16 w-full justify-stretch gap-1 rounded-lg px-3 py-2.5 text-left\",\n sandbox.ref === props.selectedRef && \"border-border bg-accent text-foreground\",\n )}\n key={sandbox.ref}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelect(sandbox.ref)}\n >\n <span className=\"flex min-w-0 items-center justify-between gap-2\">\n <strong className=\"truncate text-sm font-semibold text-foreground\">\n {sandbox.id}\n </strong>\n <StudioStatusBadge className=\"shrink-0 px-1.5 py-0.5 text-[10px]\">\n {sandbox.provider}\n </StudioStatusBadge>\n </span>\n <span className=\"truncate font-mono text-[11px] font-normal text-muted-foreground\">\n {sandbox.workdir}\n </span>\n </Button>\n ))}\n </div>\n </StudioSurface>\n );\n}\n\nfunction FileBrowser(props: {\n currentPath: string;\n files: StudioSandboxFileEntry[];\n loading: boolean;\n onOpenDirectory: (path: string) => void;\n onOpenFile: (file: StudioSandboxFileEntry) => void;\n onSelectPath: (path: string) => void;\n}) {\n const breadcrumbs = useMemo(() => sandboxBreadcrumbs(props.currentPath), [props.currentPath]);\n return (\n <StudioSurface className=\"grid min-h-0 grid-rows-[auto_auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"border-b border-border/70 px-4 py-3\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Files\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">One level at a time</p>\n </div>\n <div className=\"flex min-h-10 items-center gap-1 overflow-x-auto border-b border-border/70 px-3 py-1.5\">\n {breadcrumbs.map((breadcrumb, index) => (\n <span className=\"flex items-center gap-1\" key={breadcrumb.path}>\n {index > 0 ? <span className=\"text-muted-foreground/60\">/</span> : null}\n <Button\n className=\"h-7 min-h-7 px-2 font-mono text-xs\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelectPath(breadcrumb.path)}\n >\n {breadcrumb.label}\n </Button>\n </span>\n ))}\n </div>\n <div className=\"min-h-0 overflow-y-auto p-2\">\n {props.loading ? (\n <p className=\"m-0 px-3 py-4 text-xs text-muted-foreground\">Loading workspace</p>\n ) : null}\n {!props.loading && props.files.length === 0 ? (\n <p className=\"m-0 px-3 py-4 text-xs text-muted-foreground\">This directory is empty.</p>\n ) : null}\n {props.files.map((file) => (\n <Button\n className=\"mb-0.5 grid h-10 min-h-10 w-full grid-cols-[18px_minmax(0,1fr)_auto] justify-stretch gap-2 rounded-md px-2.5 text-left text-xs font-medium\"\n key={file.path}\n type=\"button\"\n variant=\"ghost\"\n onClick={() =>\n file.type === \"directory\" ? props.onOpenDirectory(file.path) : props.onOpenFile(file)\n }\n >\n <StudioIcon\n className=\"text-muted-foreground\"\n icon={file.type === \"directory\" ? FolderOpenIcon : File01Icon}\n aria-hidden=\"true\"\n />\n <span className=\"truncate text-foreground\">{basename(file.path)}</span>\n <span className=\"font-mono text-[10px] font-normal text-muted-foreground\">\n {file.type === \"file\" ? formatBytes(file.size) : file.type}\n </span>\n </Button>\n ))}\n </div>\n </StudioSurface>\n );\n}\n\nfunction SandboxOverview(props: { sandbox: StudioSandboxSummary; error: string }) {\n return (\n <StudioSurface className=\"rounded-xl p-4\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div className=\"min-w-0\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Active sandbox\n </span>\n <h2 className=\"m-0 mt-1 truncate text-lg font-semibold text-foreground\">\n {props.sandbox.id}\n </h2>\n <p className=\"m-0 mt-1 truncate font-mono text-xs text-muted-foreground\">\n {props.sandbox.workdir}\n </p>\n </div>\n <StudioStatusBadge>{props.sandbox.provider}</StudioStatusBadge>\n </div>\n <div className=\"mt-4 grid grid-cols-2 gap-3 text-xs\">\n <MetadataList label=\"Agents\" values={props.sandbox.agentIds} />\n <MetadataList label=\"Sandbox tools\" values={props.sandbox.toolNames} />\n </div>\n {props.error.length > 0 ? (\n <p className=\"m-0 mt-3 rounded-lg border border-destructive/25 bg-destructive/5 px-3 py-2 text-xs leading-5 text-destructive\">\n {props.error}\n </p>\n ) : null}\n </StudioSurface>\n );\n}\n\nfunction MetadataList(props: { label: string; values: string[] }) {\n return (\n <div className=\"rounded-lg border border-border/70 bg-background/45 p-3\">\n <span className=\"font-semibold uppercase tracking-[0.12em] text-muted-foreground\">\n {props.label}\n </span>\n <p className=\"m-0 mt-1 break-words font-mono leading-5 text-foreground\">\n {props.values.join(\", \") || \"-\"}\n </p>\n </div>\n );\n}\n\nfunction FilePreviewPanel(props: { preview: FilePreview | undefined; sandboxRef: string }) {\n const file = props.preview?.file;\n return (\n <StudioSurface className=\"grid min-h-64 grid-rows-[auto_minmax(0,1fr)] rounded-xl\">\n <div className=\"flex min-h-12 items-center justify-between gap-3 border-b border-border/70 px-4 py-2\">\n <div className=\"min-w-0\">\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Preview\n </span>\n <p className=\"m-0 mt-0.5 truncate font-mono text-[11px] text-muted-foreground\">\n {file?.path ?? \"Select a file\"}\n </p>\n </div>\n {file !== undefined ? (\n <Button asChild size=\"sm\" variant=\"secondary\">\n <a href={fileContentUrl(props.sandboxRef, file.path, true)}>\n <StudioIcon icon={Download01Icon} aria-hidden=\"true\" />\n Download\n </a>\n </Button>\n ) : null}\n </div>\n <div className=\"grid min-h-0 place-items-center overflow-auto bg-background/35 p-4\">\n {props.preview === undefined ? (\n <p className=\"m-0 text-center text-xs leading-5 text-muted-foreground\">\n Choose a regular file to inspect its contents.\n </p>\n ) : null}\n {props.preview?.kind === \"loading\" ? (\n <p className=\"m-0 text-xs text-muted-foreground\">Loading preview</p>\n ) : null}\n {props.preview?.kind === \"text\" ? (\n <pre className=\"m-0 h-full min-h-48 w-full overflow-auto whitespace-pre-wrap break-words rounded-lg border border-border/70 bg-card/60 p-4 font-mono text-xs leading-5 text-foreground\">\n {props.preview.text}\n </pre>\n ) : null}\n {props.preview?.kind === \"image\" ? (\n <img\n className=\"max-h-96 max-w-full rounded-lg border border-border/70 object-contain\"\n src={props.preview.url}\n alt={basename(props.preview.file.path)}\n />\n ) : null}\n {props.preview?.kind === \"binary\" ? (\n <PreviewNotice text=\"This file type is download-only and will not be rendered in Studio.\" />\n ) : null}\n {props.preview?.kind === \"large\" ? (\n <PreviewNotice text=\"This file is larger than the 1 MiB inline preview limit.\" />\n ) : null}\n </div>\n </StudioSurface>\n );\n}\n\nfunction PreviewNotice(props: { text: string }) {\n return (\n <div className=\"grid max-w-sm justify-items-center gap-2 text-center\">\n <StudioIcon className=\"h-6 w-6 text-muted-foreground\" icon={File01Icon} aria-hidden=\"true\" />\n <p className=\"m-0 text-xs leading-5 text-muted-foreground\">{props.text}</p>\n </div>\n );\n}\n\nfunction RuntimePanel(props: {\n loading: boolean;\n logs: StudioSandboxProcessLogsResponse | undefined;\n ports: StudioSandboxPort[];\n processes: StudioSandboxProcess[];\n selectedProcessId: string;\n supportsPorts: boolean;\n supportsProcesses: boolean;\n onSelectProcess: (processId: string) => void;\n}) {\n return (\n <StudioSurface className=\"rounded-xl p-4\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <span className=\"text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground\">\n Runtime\n </span>\n <p className=\"m-0 mt-1 text-xs text-muted-foreground\">\n Published ports and managed processes\n </p>\n </div>\n {props.loading ? <StudioStatusBadge>Refreshing</StudioStatusBadge> : null}\n </div>\n\n <div className=\"mt-4 grid gap-4\">\n <RuntimeSection title=\"Ports\">\n {!props.supportsPorts ? (\n <RuntimeEmpty text=\"Published ports are not supported by this sandbox.\" />\n ) : props.ports.length === 0 ? (\n <RuntimeEmpty text=\"No ports are published.\" />\n ) : (\n <div className=\"grid gap-1\">\n {props.ports.map((port) => (\n <div\n className=\"grid grid-cols-[90px_minmax(0,1fr)] gap-3 rounded-md border border-border/60 px-3 py-2 font-mono text-xs\"\n key={`${port.containerPort}:${port.hostPort}`}\n >\n <span className=\"text-foreground\">\n {port.containerPort}/{port.protocol}\n </span>\n <span className=\"truncate text-muted-foreground\">\n {port.host}:{port.hostPort}\n </span>\n </div>\n ))}\n </div>\n )}\n </RuntimeSection>\n\n <RuntimeSection title=\"Processes\">\n {!props.supportsProcesses ? (\n <RuntimeEmpty text=\"Managed processes are not supported by this sandbox.\" />\n ) : props.processes.length === 0 ? (\n <RuntimeEmpty text=\"No managed processes are recorded.\" />\n ) : (\n <div className=\"grid gap-1\">\n {props.processes.map((process) => (\n <Button\n className={cn(\n \"grid h-auto min-h-11 w-full grid-cols-[minmax(0,1fr)_auto] justify-stretch gap-3 rounded-md px-3 py-2 text-left\",\n process.id === props.selectedProcessId &&\n \"border-border bg-accent text-foreground\",\n )}\n key={process.id}\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onSelectProcess(process.id)}\n >\n <span className=\"flex min-w-0 items-center gap-2\">\n <StudioIcon\n className=\"text-muted-foreground\"\n icon={ComputerTerminal01Icon}\n aria-hidden=\"true\"\n />\n <span className=\"truncate font-mono text-xs text-foreground\">\n {[process.command, ...process.args].join(\" \")}\n </span>\n </span>\n <StudioStatusBadge className=\"px-1.5 py-0.5 text-[10px]\">\n {process.status}\n </StudioStatusBadge>\n </Button>\n ))}\n </div>\n )}\n </RuntimeSection>\n\n {props.selectedProcessId.length > 0 ? (\n <RuntimeSection title=\"Process logs\">\n {props.logs === undefined ? (\n <RuntimeEmpty text=\"Loading the latest bounded output.\" />\n ) : (\n <div className=\"grid gap-2\">\n <LogBlock\n label=\"stdout\"\n text={props.logs.stdout}\n truncated={props.logs.stdoutTruncated}\n />\n <LogBlock\n label=\"stderr\"\n text={props.logs.stderr}\n truncated={props.logs.stderrTruncated}\n />\n </div>\n )}\n </RuntimeSection>\n ) : null}\n </div>\n </StudioSurface>\n );\n}\n\nfunction RuntimeSection(props: { title: string; children: ReactNode }) {\n return (\n <section className=\"grid gap-2\">\n <h3 className=\"m-0 text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n {props.title}\n </h3>\n {props.children}\n </section>\n );\n}\n\nfunction RuntimeEmpty(props: { text: string }) {\n return (\n <p className=\"m-0 rounded-md border border-dashed border-border/70 px-3 py-2 text-xs leading-5 text-muted-foreground\">\n {props.text}\n </p>\n );\n}\n\nfunction LogBlock(props: { label: string; text: string; truncated: boolean }) {\n return (\n <div className=\"overflow-hidden rounded-md border border-border/70 bg-background/55\">\n <div className=\"flex items-center justify-between border-b border-border/60 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground\">\n <span>{props.label}</span>\n {props.truncated ? <span>truncated</span> : null}\n </div>\n <pre className=\"m-0 max-h-48 overflow-auto whitespace-pre-wrap break-words p-3 font-mono text-[11px] leading-5 text-foreground\">\n {props.text || \"No output\"}\n </pre>\n </div>\n );\n}\n\nasync function requestJson<T>(\n url: string,\n label: string,\n signal: AbortSignal,\n cache: RequestCache = \"default\",\n): Promise<T> {\n const response = await fetch(url, { cache, signal });\n if (!response.ok) {\n throw new Error(await responseErrorMessage(response, label));\n }\n return (await response.json()) as T;\n}\n\nfunction sandboxBreadcrumbs(filePath: string): Array<{ label: string; path: string }> {\n const segments = filePath === \".\" ? [] : filePath.split(\"/\").filter(Boolean);\n const breadcrumbs = [{ label: \"/\", path: \".\" }];\n for (let index = 0; index < segments.length; index += 1) {\n breadcrumbs.push({\n label: segments[index] ?? \"\",\n path: segments.slice(0, index + 1).join(\"/\"),\n });\n }\n return breadcrumbs;\n}\n\nfunction fileContentUrl(sandboxRef: string, filePath: string, download = false): string {\n const params = new URLSearchParams({ path: filePath });\n if (download) params.set(\"download\", \"1\");\n return `/sandboxes/${encodeURIComponent(sandboxRef)}/files/content?${params}`;\n}\n\nfunction fileExtension(filePath: string): string {\n const name = basename(filePath).toLowerCase();\n const dot = name.lastIndexOf(\".\");\n return dot < 0 ? name : name.slice(dot + 1);\n}\n\nfunction basename(filePath: string): string {\n return filePath.split(\"/\").at(-1) ?? filePath;\n}\n\nfunction formatBytes(size: number | undefined): string {\n if (size === undefined) return \"-\";\n if (size < 1024) return `${size} B`;\n if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KiB`;\n return `${(size / (1024 * 1024)).toFixed(1)} MiB`;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as e,r as t,s as n,t as r}from"./utils-C9GMruoG.js";import{o as i,t as a}from"./format-D43vTqrO.js";import{B as o,C as s,E as c,I as l,L as u,O as d,R as f,S as p,Z as m,_ as h,a as g,b as _,g as v,h as y,k as b,m as ee,s as x,v as S,w as C,x as w,y as T,z as E}from"./index-BA0rdlcA.js";var D=n(e(),1),O=t(),k=Object.defineProperty,A=(e,t)=>k(e,`name`,{value:t,configurable:!0}),j=`Dialog`,[M,te]=d(j),[N,P]=M(j),F=A(e=>{let{__scopeDialog:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!0}=e,s=D.useRef(null),c=D.useRef(null),[l,u]=v({prop:r,defaultProp:i??!1,onChange:a,caller:j}),[d,f]=D.useState(0),[p,m]=D.useState(0);return(0,O.jsx)(N,{scope:t,triggerRef:s,contentRef:c,contentId:T(),titleId:T(),descriptionId:T(),titlePresent:d>0,descriptionPresent:p>0,setTitleCount:f,setDescriptionCount:m,open:l,onOpenChange:u,onOpenToggle:D.useCallback(()=>u(e=>!e),[u]),modal:o,children:n})},`Dialog`),I=`DialogPortal`,[L,R]=M(I,{forceMount:void 0}),z=A(e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=P(I,t);return(0,O.jsx)(L,{scope:t,forceMount:n,children:D.Children.map(r,e=>(0,O.jsx)(h,{present:n||a.open,children:(0,O.jsx)(S,{asChild:!0,container:i,children:e})}))})},`DialogPortal`),B=`DialogOverlay`,V=D.forwardRef(A(function(e,t){let n=R(B,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=P(B,e.__scopeDialog);return a.modal?(0,O.jsx)(h,{present:r||a.open,children:(0,O.jsx)(U,{...i,ref:t})}):null},`DialogOverlay`)),H=f(`DialogOverlay.RemoveScroll`),U=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(B,n),a=E(t,C());return(0,O.jsx)(ee,{as:H,allowPinchZoom:!0,shards:[i.contentRef],children:(0,O.jsx)(c.div,{"data-state":$(i.open),...r,ref:a,style:{pointerEvents:`auto`,...r.style}})})},`DialogOverlayImpl`)),W=`DialogContent`,G=D.forwardRef(A(function(e,t){let n=R(W,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=P(W,e.__scopeDialog);return(0,O.jsx)(h,{present:r||a.open,children:a.modal?(0,O.jsx)(K,{...i,ref:t}):(0,O.jsx)(q,{...i,ref:t})})},`DialogContent`)),K=D.forwardRef(A(function(e,t){let n=P(W,e.__scopeDialog),r=D.useRef(null),i=E(t,n.contentRef,r);return D.useEffect(()=>{let e=r.current;if(e)return y(e)},[]),(0,O.jsx)(J,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,onCloseAutoFocus:b(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:b(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:b(e.onFocusOutside,e=>e.preventDefault())})},`DialogContentModal`)),q=D.forwardRef(A(function(e,t){let n=P(W,e.__scopeDialog),r=D.useRef(!1),i=D.useRef(!1);return(0,O.jsx)(J,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})},`DialogContentNonModal`)),J=D.forwardRef(A(function(e,t){let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...o}=e,c=P(W,n);return p(),(0,O.jsx)(O.Fragment,{children:(0,O.jsx)(w,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,O.jsx)(s,{role:`dialog`,id:c.contentId,"aria-describedby":c.descriptionPresent?c.descriptionId:void 0,"aria-labelledby":c.titlePresent?c.titleId:void 0,"data-state":$(c.open),...o,ref:t,deferPointerDownOutside:!0,onDismiss:()=>c.onOpenChange(!1)})})})},`DialogContentImpl`)),Y=`DialogTitle`,X=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(Y,n),{setTitleCount:a}=i;return _(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,O.jsx)(c.h2,{id:i.titleId,...r,ref:t})},`DialogTitle`)),Z=`DialogDescription`,Q=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(Z,n),{setDescriptionCount:a}=i;return _(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,O.jsx)(c.p,{id:i.descriptionId,...r,ref:t})},`DialogDescription`));function $(e){return e?`open`:`closed`}A($,`getState`);var ne=F;function re({className:e,children:t,...n}){return(0,O.jsxs)(z,{children:[(0,O.jsx)(V,{className:`fixed inset-0 z-50 bg-background/80 backdrop-blur-sm`}),(0,O.jsx)(G,{className:r(`fixed left-1/2 top-1/2 z-50 grid w-[min(420px,calc(100vw-32px))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-5 text-popover-foreground shadow-2xl shadow-black/40`,e),...n,children:t})]})}function ie({className:e,...t}){return(0,O.jsx)(`div`,{className:r(`grid gap-1.5`,e),...t})}function ae({className:e,...t}){return(0,O.jsx)(`div`,{className:r(`flex justify-end gap-2`,e),...t})}function oe({className:e,...t}){return(0,O.jsx)(X,{className:r(`text-base font-bold`,e),...t})}function se({className:e,...t}){return(0,O.jsx)(Q,{className:r(`text-sm leading-6 text-muted-foreground`,e),...t})}function ce(e){return e.sessionsEnabled?(0,O.jsx)(g,{className:`overflow-auto pb-6 pr-6`,"aria-label":`Sessions`,children:(0,O.jsxs)(x,{className:`min-w-225 rounded-xl p-2`,children:[(0,O.jsxs)(`div`,{className:`sticky top-0 z-10 grid min-h-11 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-border/60 bg-card/95 px-4 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground backdrop-blur`,children:[(0,O.jsx)(`span`,{children:`Session`}),(0,O.jsx)(`span`,{children:`Agent`}),(0,O.jsx)(`span`,{children:`Messages`}),(0,O.jsx)(`span`,{children:`Updated`}),(0,O.jsx)(`span`,{className:`sr-only`,children:`Actions`})]}),e.sessionLoadState===`loading`&&e.sessions.length===0?(0,O.jsx)(`div`,{className:`px-5 py-4 text-sm font-medium text-muted-foreground`,children:`Loading sessions`}):null,e.sessionLoadState===`idle`&&e.sessions.length===0?(0,O.jsx)(`div`,{className:`px-5 py-4 text-sm font-medium text-muted-foreground`,children:`No sessions`}):null,e.sessions.map(t=>(0,O.jsxs)(`div`,{className:r(`mt-1 grid min-h-14 w-full min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-transparent px-4 text-left text-muted-foreground transition duration-200 hover:border-border/70 hover:bg-accent/80 hover:text-accent-foreground`,t.id===e.selectedSessionId&&`border-border/80 bg-muted/45 text-foreground`),children:[(0,O.jsxs)(u,{className:`col-span-4 grid h-full min-h-14 min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px] items-center justify-start gap-4 border-0 bg-transparent p-0 text-left text-inherit shadow-none hover:bg-transparent hover:text-inherit`,type:`button`,variant:`ghost`,onClick:()=>e.onOpenSession(t.id),children:[(0,O.jsxs)(`span`,{className:`grid min-w-0 gap-0.5`,children:[(0,O.jsx)(`strong`,{className:`min-w-0 truncate text-sm font-medium text-foreground`,children:t.title??`Untitled chat`}),(0,O.jsx)(`span`,{className:`min-w-0 truncate text-xs font-medium text-muted-foreground`,children:t.id})]}),(0,O.jsx)(`span`,{className:`min-w-0 truncate text-xs font-medium`,children:a(e.agents,t.agentId)}),(0,O.jsxs)(`span`,{className:`text-xs font-medium tabular-nums text-muted-foreground`,children:[t.messageCount,` messages`]}),(0,O.jsx)(`time`,{className:`text-xs font-medium text-muted-foreground`,children:i(t.updatedAt)})]}),(0,O.jsxs)(`span`,{className:`flex items-center justify-end gap-1`,children:[(0,O.jsx)(u,{"aria-label":`View tracing for ${t.title??`Untitled chat`}`,className:`h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-foreground hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5`,size:`icon`,type:`button`,variant:`ghost`,onClick:n=>{n.stopPropagation(),e.onViewSessionTracing(t.id)},children:(0,O.jsx)(l,{icon:o,"aria-hidden":`true`})}),(0,O.jsx)(u,{"aria-label":`Delete ${t.title??`Untitled chat`}`,className:`h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-destructive hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5`,size:`icon`,type:`button`,variant:`ghost`,onClick:n=>{n.stopPropagation(),e.onDeleteSession(t)},children:(0,O.jsx)(l,{icon:m,"aria-hidden":`true`})})]})]},t.id))]})}):(0,O.jsx)(`div`,{className:`w-full rounded-lg border border-dashed border-border p-8 text-sm font-medium text-muted-foreground`,children:`Sessions are disabled`})}function le(e){let t=e.session?.title??`Untitled chat`;return(0,O.jsx)(ne,{open:e.session!==void 0,onOpenChange:e.onOpenChange,children:(0,O.jsxs)(re,{children:[(0,O.jsxs)(ie,{children:[(0,O.jsx)(oe,{children:`Delete session`}),(0,O.jsxs)(se,{children:[`Delete "`,t,`" and its traces. This cannot be undone.`]})]}),(0,O.jsxs)(ae,{children:[(0,O.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>e.onOpenChange(!1),children:`Cancel`}),(0,O.jsx)(u,{type:`button`,variant:`destructive`,onClick:()=>{e.session!==void 0&&e.onConfirm(e.session)},children:`Delete`})]})]})})}export{le as DeleteSessionDialog,ce as SessionsPage};
2
- //# sourceMappingURL=sessions-page-BXgRMxf-.js.map
1
+ import{i as e,r as t,s as n,t as r}from"./utils-C9GMruoG.js";import{o as i,t as a}from"./format-D43vTqrO.js";import{B as o,C as s,E as c,I as l,L as u,O as d,R as f,S as p,Z as m,_ as h,a as g,b as _,g as v,h as y,k as b,m as ee,s as x,v as S,w as C,x as w,y as T,z as E}from"./index-DY62pnOs.js";var D=n(e(),1),O=t(),k=Object.defineProperty,A=(e,t)=>k(e,`name`,{value:t,configurable:!0}),j=`Dialog`,[M,te]=d(j),[N,P]=M(j),F=A(e=>{let{__scopeDialog:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!0}=e,s=D.useRef(null),c=D.useRef(null),[l,u]=v({prop:r,defaultProp:i??!1,onChange:a,caller:j}),[d,f]=D.useState(0),[p,m]=D.useState(0);return(0,O.jsx)(N,{scope:t,triggerRef:s,contentRef:c,contentId:T(),titleId:T(),descriptionId:T(),titlePresent:d>0,descriptionPresent:p>0,setTitleCount:f,setDescriptionCount:m,open:l,onOpenChange:u,onOpenToggle:D.useCallback(()=>u(e=>!e),[u]),modal:o,children:n})},`Dialog`),I=`DialogPortal`,[L,R]=M(I,{forceMount:void 0}),z=A(e=>{let{__scopeDialog:t,forceMount:n,children:r,container:i}=e,a=P(I,t);return(0,O.jsx)(L,{scope:t,forceMount:n,children:D.Children.map(r,e=>(0,O.jsx)(h,{present:n||a.open,children:(0,O.jsx)(S,{asChild:!0,container:i,children:e})}))})},`DialogPortal`),B=`DialogOverlay`,V=D.forwardRef(A(function(e,t){let n=R(B,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=P(B,e.__scopeDialog);return a.modal?(0,O.jsx)(h,{present:r||a.open,children:(0,O.jsx)(U,{...i,ref:t})}):null},`DialogOverlay`)),H=f(`DialogOverlay.RemoveScroll`),U=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(B,n),a=E(t,C());return(0,O.jsx)(ee,{as:H,allowPinchZoom:!0,shards:[i.contentRef],children:(0,O.jsx)(c.div,{"data-state":$(i.open),...r,ref:a,style:{pointerEvents:`auto`,...r.style}})})},`DialogOverlayImpl`)),W=`DialogContent`,G=D.forwardRef(A(function(e,t){let n=R(W,e.__scopeDialog),{forceMount:r=n.forceMount,...i}=e,a=P(W,e.__scopeDialog);return(0,O.jsx)(h,{present:r||a.open,children:a.modal?(0,O.jsx)(K,{...i,ref:t}):(0,O.jsx)(q,{...i,ref:t})})},`DialogContent`)),K=D.forwardRef(A(function(e,t){let n=P(W,e.__scopeDialog),r=D.useRef(null),i=E(t,n.contentRef,r);return D.useEffect(()=>{let e=r.current;if(e)return y(e)},[]),(0,O.jsx)(J,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:n.open,onCloseAutoFocus:b(e.onCloseAutoFocus,e=>{e.preventDefault(),n.triggerRef.current?.focus()}),onPointerDownOutside:b(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;(t.button===2||n)&&e.preventDefault()}),onFocusOutside:b(e.onFocusOutside,e=>e.preventDefault())})},`DialogContentModal`)),q=D.forwardRef(A(function(e,t){let n=P(W,e.__scopeDialog),r=D.useRef(!1),i=D.useRef(!1);return(0,O.jsx)(J,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})},`DialogContentNonModal`)),J=D.forwardRef(A(function(e,t){let{__scopeDialog:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,...o}=e,c=P(W,n);return p(),(0,O.jsx)(O.Fragment,{children:(0,O.jsx)(w,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,O.jsx)(s,{role:`dialog`,id:c.contentId,"aria-describedby":c.descriptionPresent?c.descriptionId:void 0,"aria-labelledby":c.titlePresent?c.titleId:void 0,"data-state":$(c.open),...o,ref:t,deferPointerDownOutside:!0,onDismiss:()=>c.onOpenChange(!1)})})})},`DialogContentImpl`)),Y=`DialogTitle`,X=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(Y,n),{setTitleCount:a}=i;return _(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,O.jsx)(c.h2,{id:i.titleId,...r,ref:t})},`DialogTitle`)),Z=`DialogDescription`,Q=D.forwardRef(A(function(e,t){let{__scopeDialog:n,...r}=e,i=P(Z,n),{setDescriptionCount:a}=i;return _(()=>(a(e=>e+1),()=>a(e=>e-1)),[a]),(0,O.jsx)(c.p,{id:i.descriptionId,...r,ref:t})},`DialogDescription`));function $(e){return e?`open`:`closed`}A($,`getState`);var ne=F;function re({className:e,children:t,...n}){return(0,O.jsxs)(z,{children:[(0,O.jsx)(V,{className:`fixed inset-0 z-50 bg-background/80 backdrop-blur-sm`}),(0,O.jsx)(G,{className:r(`fixed left-1/2 top-1/2 z-50 grid w-[min(420px,calc(100vw-32px))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-5 text-popover-foreground shadow-2xl shadow-black/40`,e),...n,children:t})]})}function ie({className:e,...t}){return(0,O.jsx)(`div`,{className:r(`grid gap-1.5`,e),...t})}function ae({className:e,...t}){return(0,O.jsx)(`div`,{className:r(`flex justify-end gap-2`,e),...t})}function oe({className:e,...t}){return(0,O.jsx)(X,{className:r(`text-base font-bold`,e),...t})}function se({className:e,...t}){return(0,O.jsx)(Q,{className:r(`text-sm leading-6 text-muted-foreground`,e),...t})}function ce(e){return e.sessionsEnabled?(0,O.jsx)(g,{className:`overflow-auto pb-6 pr-6`,"aria-label":`Sessions`,children:(0,O.jsxs)(x,{className:`min-w-225 rounded-xl p-2`,children:[(0,O.jsxs)(`div`,{className:`sticky top-0 z-10 grid min-h-11 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-border/60 bg-card/95 px-4 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground backdrop-blur`,children:[(0,O.jsx)(`span`,{children:`Session`}),(0,O.jsx)(`span`,{children:`Agent`}),(0,O.jsx)(`span`,{children:`Messages`}),(0,O.jsx)(`span`,{children:`Updated`}),(0,O.jsx)(`span`,{className:`sr-only`,children:`Actions`})]}),e.sessionLoadState===`loading`&&e.sessions.length===0?(0,O.jsx)(`div`,{className:`px-5 py-4 text-sm font-medium text-muted-foreground`,children:`Loading sessions`}):null,e.sessionLoadState===`idle`&&e.sessions.length===0?(0,O.jsx)(`div`,{className:`px-5 py-4 text-sm font-medium text-muted-foreground`,children:`No sessions`}):null,e.sessions.map(t=>(0,O.jsxs)(`div`,{className:r(`mt-1 grid min-h-14 w-full min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-transparent px-4 text-left text-muted-foreground transition duration-200 hover:border-border/70 hover:bg-accent/80 hover:text-accent-foreground`,t.id===e.selectedSessionId&&`border-border/80 bg-muted/45 text-foreground`),children:[(0,O.jsxs)(u,{className:`col-span-4 grid h-full min-h-14 min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px] items-center justify-start gap-4 border-0 bg-transparent p-0 text-left text-inherit shadow-none hover:bg-transparent hover:text-inherit`,type:`button`,variant:`ghost`,onClick:()=>e.onOpenSession(t.id),children:[(0,O.jsxs)(`span`,{className:`grid min-w-0 gap-0.5`,children:[(0,O.jsx)(`strong`,{className:`min-w-0 truncate text-sm font-medium text-foreground`,children:t.title??`Untitled chat`}),(0,O.jsx)(`span`,{className:`min-w-0 truncate text-xs font-medium text-muted-foreground`,children:t.id})]}),(0,O.jsx)(`span`,{className:`min-w-0 truncate text-xs font-medium`,children:a(e.agents,t.agentId)}),(0,O.jsxs)(`span`,{className:`text-xs font-medium tabular-nums text-muted-foreground`,children:[t.messageCount,` messages`]}),(0,O.jsx)(`time`,{className:`text-xs font-medium text-muted-foreground`,children:i(t.updatedAt)})]}),(0,O.jsxs)(`span`,{className:`flex items-center justify-end gap-1`,children:[(0,O.jsx)(u,{"aria-label":`View tracing for ${t.title??`Untitled chat`}`,className:`h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-foreground hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5`,size:`icon`,type:`button`,variant:`ghost`,onClick:n=>{n.stopPropagation(),e.onViewSessionTracing(t.id)},children:(0,O.jsx)(l,{icon:o,"aria-hidden":`true`})}),(0,O.jsx)(u,{"aria-label":`Delete ${t.title??`Untitled chat`}`,className:`h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-destructive hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5`,size:`icon`,type:`button`,variant:`ghost`,onClick:n=>{n.stopPropagation(),e.onDeleteSession(t)},children:(0,O.jsx)(l,{icon:m,"aria-hidden":`true`})})]})]},t.id))]})}):(0,O.jsx)(`div`,{className:`w-full rounded-lg border border-dashed border-border p-8 text-sm font-medium text-muted-foreground`,children:`Sessions are disabled`})}function le(e){let t=e.session?.title??`Untitled chat`;return(0,O.jsx)(ne,{open:e.session!==void 0,onOpenChange:e.onOpenChange,children:(0,O.jsxs)(re,{children:[(0,O.jsxs)(ie,{children:[(0,O.jsx)(oe,{children:`Delete session`}),(0,O.jsxs)(se,{children:[`Delete "`,t,`" and its traces. This cannot be undone.`]})]}),(0,O.jsxs)(ae,{children:[(0,O.jsx)(u,{type:`button`,variant:`ghost`,onClick:()=>e.onOpenChange(!1),children:`Cancel`}),(0,O.jsx)(u,{type:`button`,variant:`destructive`,onClick:()=>{e.session!==void 0&&e.onConfirm(e.session)},children:`Delete`})]})]})})}export{le as DeleteSessionDialog,ce as SessionsPage};
2
+ //# sourceMappingURL=sessions-page-BBwN5yCL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sessions-page-BXgRMxf-.js","names":["Dialog","PortalPrimitive","RemoveScroll","DialogContent","Fragment","DialogTitle","DialogDescription"],"sources":["../../../../../node_modules/.pnpm/@radix-ui+react-dialog@1.1.23_@types+react-dom@19.2.3_@types+react@19.2.14__@types+reac_206e34ced59c73f850f1f5137ff8af4b/node_modules/@radix-ui/react-dialog/dist/index.mjs","../../../src/ui/app/components/ui/dialog.tsx","../../../src/ui/app/modules/sessions/sessions-page.tsx"],"sourcesContent":["\"use client\";\nvar __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer, useDismissableLayerSurface } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = /* @__PURE__ */ __name((props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: DIALOG_NAME\n });\n const [titleCount, setTitleCount] = React.useState(0);\n const [descriptionCount, setDescriptionCount] = React.useState(0);\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n titlePresent: titleCount > 0,\n descriptionPresent: descriptionCount > 0,\n setTitleCount,\n setDescriptionCount,\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n}, \"Dialog\");\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogTrigger2(props, forwardedRef) {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.open ? context.contentId : void 0,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }, \"DialogTrigger\")\n);\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = /* @__PURE__ */ __name((props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n}, \"DialogPortal\");\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogOverlay2(props, forwardedRef) {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }, \"DialogOverlay\")\n);\nvar Slot = createSlot(\"DialogOverlay.RemoveScroll\");\nvar DialogOverlayImpl = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogOverlayImpl2(props, forwardedRef) {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n const registerDismissableSurface = useDismissableLayerSurface();\n const composedRefs = useComposedRefs(forwardedRef, registerDismissableSurface);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: composedRefs,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }, \"DialogOverlayImpl\")\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogContent2(props, forwardedRef) {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }, \"DialogContent\")\n);\nvar DialogContentModal = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentModal2(props, forwardedRef) {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: context.open,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }, \"DialogContentModal\")\n);\nvar DialogContentNonModal = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentNonModal2(props, forwardedRef) {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }, \"DialogContentNonModal\")\n);\nvar DialogContentImpl = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentImpl2(props, forwardedRef) {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n useFocusGuards();\n return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionPresent ? context.descriptionId : void 0,\n \"aria-labelledby\": context.titlePresent ? context.titleId : void 0,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: forwardedRef,\n deferPointerDownOutside: true,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ) });\n }, \"DialogContentImpl\")\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogTitle2(props, forwardedRef) {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n const { setTitleCount } = context;\n useLayoutEffect(() => {\n setTitleCount((count) => count + 1);\n return () => setTitleCount((count) => count - 1);\n }, [setTitleCount]);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }, \"DialogTitle\")\n);\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogDescription2(props, forwardedRef) {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n const { setDescriptionCount } = context;\n useLayoutEffect(() => {\n setDescriptionCount((count) => count + 1);\n return () => setDescriptionCount((count) => count - 1);\n }, [setDescriptionCount]);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }, \"DialogDescription\")\n);\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogClose2(props, forwardedRef) {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }, \"DialogClose\")\n);\nvar WarningProvider = /* @__PURE__ */ __name((props) => {\n return props.children;\n}, \"WarningProvider\");\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\n__name(getState, \"getState\");\nexport {\n DialogClose as Close,\n DialogContent as Content,\n DialogDescription as Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n DialogOverlay as Overlay,\n DialogPortal as Portal,\n Dialog as Root,\n DialogTitle as Title,\n DialogTrigger as Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogClose = DialogPrimitive.Close;\n\nexport function DialogContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return (\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm\" />\n <DialogPrimitive.Content\n className={cn(\n \"fixed left-1/2 top-1/2 z-50 grid w-[min(420px,calc(100vw-32px))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-5 text-popover-foreground shadow-2xl shadow-black/40\",\n className,\n )}\n {...props}\n >\n {children}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n );\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"grid gap-1.5\", className)} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"flex justify-end gap-2\", className)} {...props} />;\n}\n\nexport function DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return <DialogPrimitive.Title className={cn(\"text-base font-bold\", className)} {...props} />;\n}\n\nexport function DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n className={cn(\"text-sm leading-6 text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n","import { Activity01Icon, Delete02Icon } from \"@hugeicons/core-free-icons\";\nimport type { StudioConfig, StudioSessionSummary } from \"../../../../types\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../../components/ui/dialog\";\nimport { StudioIcon } from \"../../components/ui/icon\";\nimport { StudioPageShell, StudioSurface } from \"../../components/ui/studio\";\nimport { cn } from \"../../lib/utils\";\nimport { agentLabel, formatRelativeTime } from \"../shared/format\";\nimport type { SessionLoadState } from \"../shared/types\";\n\nexport function SessionsPage(props: {\n agents: StudioConfig[\"agents\"];\n sessions: StudioSessionSummary[];\n sessionsEnabled: boolean;\n sessionLoadState: SessionLoadState;\n selectedSessionId: string;\n onOpenSession: (sessionId: string) => void;\n onViewSessionTracing: (sessionId: string) => void;\n onDeleteSession: (session: StudioSessionSummary) => void;\n}) {\n if (!props.sessionsEnabled) {\n return (\n <div className=\"w-full rounded-lg border border-dashed border-border p-8 text-sm font-medium text-muted-foreground\">\n Sessions are disabled\n </div>\n );\n }\n\n return (\n <StudioPageShell className=\"overflow-auto pb-6 pr-6\" aria-label=\"Sessions\">\n <StudioSurface className=\"min-w-225 rounded-xl p-2\">\n <div className=\"sticky top-0 z-10 grid min-h-11 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-border/60 bg-card/95 px-4 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground backdrop-blur\">\n <span>Session</span>\n <span>Agent</span>\n <span>Messages</span>\n <span>Updated</span>\n <span className=\"sr-only\">Actions</span>\n </div>\n {props.sessionLoadState === \"loading\" && props.sessions.length === 0 ? (\n <div className=\"px-5 py-4 text-sm font-medium text-muted-foreground\">\n Loading sessions\n </div>\n ) : null}\n {props.sessionLoadState === \"idle\" && props.sessions.length === 0 ? (\n <div className=\"px-5 py-4 text-sm font-medium text-muted-foreground\">No sessions</div>\n ) : null}\n {props.sessions.map((session) => (\n <div\n className={cn(\n \"mt-1 grid min-h-14 w-full min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-transparent px-4 text-left text-muted-foreground transition duration-200 hover:border-border/70 hover:bg-accent/80 hover:text-accent-foreground\",\n session.id === props.selectedSessionId &&\n \"border-border/80 bg-muted/45 text-foreground\",\n )}\n key={session.id}\n >\n <Button\n className=\"col-span-4 grid h-full min-h-14 min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px] items-center justify-start gap-4 border-0 bg-transparent p-0 text-left text-inherit shadow-none hover:bg-transparent hover:text-inherit\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onOpenSession(session.id)}\n >\n <span className=\"grid min-w-0 gap-0.5\">\n <strong className=\"min-w-0 truncate text-sm font-medium text-foreground\">\n {session.title ?? \"Untitled chat\"}\n </strong>\n <span className=\"min-w-0 truncate text-xs font-medium text-muted-foreground\">\n {session.id}\n </span>\n </span>\n <span className=\"min-w-0 truncate text-xs font-medium\">\n {agentLabel(props.agents, session.agentId)}\n </span>\n <span className=\"text-xs font-medium tabular-nums text-muted-foreground\">\n {session.messageCount} messages\n </span>\n <time className=\"text-xs font-medium text-muted-foreground\">\n {formatRelativeTime(session.updatedAt)}\n </time>\n </Button>\n <span className=\"flex items-center justify-end gap-1\">\n <Button\n aria-label={`View tracing for ${session.title ?? \"Untitled chat\"}`}\n className=\"h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-foreground hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5\"\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n onClick={(event) => {\n event.stopPropagation();\n props.onViewSessionTracing(session.id);\n }}\n >\n <StudioIcon icon={Activity01Icon} aria-hidden=\"true\" />\n </Button>\n <Button\n aria-label={`Delete ${session.title ?? \"Untitled chat\"}`}\n className=\"h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-destructive hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5\"\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n onClick={(event) => {\n event.stopPropagation();\n props.onDeleteSession(session);\n }}\n >\n <StudioIcon icon={Delete02Icon} aria-hidden=\"true\" />\n </Button>\n </span>\n </div>\n ))}\n </StudioSurface>\n </StudioPageShell>\n );\n}\n\nexport function DeleteSessionDialog(props: {\n session: StudioSessionSummary | undefined;\n onOpenChange: (open: boolean) => void;\n onConfirm: (session: StudioSessionSummary) => void;\n}) {\n const title = props.session?.title ?? \"Untitled chat\";\n\n return (\n <Dialog open={props.session !== undefined} onOpenChange={props.onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete session</DialogTitle>\n <DialogDescription>\n Delete \"{title}\" and its traces. This cannot be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button type=\"button\" variant=\"ghost\" onClick={() => props.onOpenChange(false)}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={() => {\n if (props.session !== undefined) {\n props.onConfirm(props.session);\n }\n }}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"sessions-page-BBwN5yCL.js","names":["Dialog","PortalPrimitive","RemoveScroll","DialogContent","Fragment","DialogTitle","DialogDescription"],"sources":["../../../../../node_modules/.pnpm/@radix-ui+react-dialog@1.1.23_@types+react-dom@19.2.3_@types+react@19.2.14__@types+reac_206e34ced59c73f850f1f5137ff8af4b/node_modules/@radix-ui/react-dialog/dist/index.mjs","../../../src/ui/app/components/ui/dialog.tsx","../../../src/ui/app/modules/sessions/sessions-page.tsx"],"sourcesContent":["\"use client\";\nvar __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer, useDismissableLayerSurface } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { useLayoutEffect } from \"@radix-ui/react-use-layout-effect\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = /* @__PURE__ */ __name((props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: DIALOG_NAME\n });\n const [titleCount, setTitleCount] = React.useState(0);\n const [descriptionCount, setDescriptionCount] = React.useState(0);\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n titlePresent: titleCount > 0,\n descriptionPresent: descriptionCount > 0,\n setTitleCount,\n setDescriptionCount,\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n}, \"Dialog\");\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogTrigger2(props, forwardedRef) {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.open ? context.contentId : void 0,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }, \"DialogTrigger\")\n);\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = /* @__PURE__ */ __name((props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n}, \"DialogPortal\");\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogOverlay2(props, forwardedRef) {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }, \"DialogOverlay\")\n);\nvar Slot = createSlot(\"DialogOverlay.RemoveScroll\");\nvar DialogOverlayImpl = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogOverlayImpl2(props, forwardedRef) {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n const registerDismissableSurface = useDismissableLayerSurface();\n const composedRefs = useComposedRefs(forwardedRef, registerDismissableSurface);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: composedRefs,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }, \"DialogOverlayImpl\")\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogContent2(props, forwardedRef) {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }, \"DialogContent\")\n);\nvar DialogContentModal = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentModal2(props, forwardedRef) {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: context.open,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }, \"DialogContentModal\")\n);\nvar DialogContentNonModal = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentNonModal2(props, forwardedRef) {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }, \"DialogContentNonModal\")\n);\nvar DialogContentImpl = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogContentImpl2(props, forwardedRef) {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n useFocusGuards();\n return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionPresent ? context.descriptionId : void 0,\n \"aria-labelledby\": context.titlePresent ? context.titleId : void 0,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: forwardedRef,\n deferPointerDownOutside: true,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ) });\n }, \"DialogContentImpl\")\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogTitle2(props, forwardedRef) {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n const { setTitleCount } = context;\n useLayoutEffect(() => {\n setTitleCount((count) => count + 1);\n return () => setTitleCount((count) => count - 1);\n }, [setTitleCount]);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }, \"DialogTitle\")\n);\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = /* @__PURE__ */ React.forwardRef(\n // blank line to reduce diff noise\n /* @__PURE__ */ __name(function DialogDescription2(props, forwardedRef) {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n const { setDescriptionCount } = context;\n useLayoutEffect(() => {\n setDescriptionCount((count) => count + 1);\n return () => setDescriptionCount((count) => count - 1);\n }, [setDescriptionCount]);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }, \"DialogDescription\")\n);\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = /* @__PURE__ */ React.forwardRef(\n /* @__PURE__ */ __name(function DialogClose2(props, forwardedRef) {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }, \"DialogClose\")\n);\nvar WarningProvider = /* @__PURE__ */ __name((props) => {\n return props.children;\n}, \"WarningProvider\");\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\n__name(getState, \"getState\");\nexport {\n DialogClose as Close,\n DialogContent as Content,\n DialogDescription as Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n DialogOverlay as Overlay,\n DialogPortal as Portal,\n Dialog as Root,\n DialogTitle as Title,\n DialogTrigger as Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTrigger = DialogPrimitive.Trigger;\nexport const DialogClose = DialogPrimitive.Close;\n\nexport function DialogContent({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n return (\n <DialogPrimitive.Portal>\n <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-background/80 backdrop-blur-sm\" />\n <DialogPrimitive.Content\n className={cn(\n \"fixed left-1/2 top-1/2 z-50 grid w-[min(420px,calc(100vw-32px))] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border border-border bg-popover p-5 text-popover-foreground shadow-2xl shadow-black/40\",\n className,\n )}\n {...props}\n >\n {children}\n </DialogPrimitive.Content>\n </DialogPrimitive.Portal>\n );\n}\n\nexport function DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"grid gap-1.5\", className)} {...props} />;\n}\n\nexport function DialogFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div className={cn(\"flex justify-end gap-2\", className)} {...props} />;\n}\n\nexport function DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return <DialogPrimitive.Title className={cn(\"text-base font-bold\", className)} {...props} />;\n}\n\nexport function DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n className={cn(\"text-sm leading-6 text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n","import { Activity01Icon, Delete02Icon } from \"@hugeicons/core-free-icons\";\nimport type { StudioConfig, StudioSessionSummary } from \"../../../../types\";\nimport { Button } from \"../../components/ui/button\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"../../components/ui/dialog\";\nimport { StudioIcon } from \"../../components/ui/icon\";\nimport { StudioPageShell, StudioSurface } from \"../../components/ui/studio\";\nimport { cn } from \"../../lib/utils\";\nimport { agentLabel, formatRelativeTime } from \"../shared/format\";\nimport type { SessionLoadState } from \"../shared/types\";\n\nexport function SessionsPage(props: {\n agents: StudioConfig[\"agents\"];\n sessions: StudioSessionSummary[];\n sessionsEnabled: boolean;\n sessionLoadState: SessionLoadState;\n selectedSessionId: string;\n onOpenSession: (sessionId: string) => void;\n onViewSessionTracing: (sessionId: string) => void;\n onDeleteSession: (session: StudioSessionSummary) => void;\n}) {\n if (!props.sessionsEnabled) {\n return (\n <div className=\"w-full rounded-lg border border-dashed border-border p-8 text-sm font-medium text-muted-foreground\">\n Sessions are disabled\n </div>\n );\n }\n\n return (\n <StudioPageShell className=\"overflow-auto pb-6 pr-6\" aria-label=\"Sessions\">\n <StudioSurface className=\"min-w-225 rounded-xl p-2\">\n <div className=\"sticky top-0 z-10 grid min-h-11 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-border/60 bg-card/95 px-4 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground backdrop-blur\">\n <span>Session</span>\n <span>Agent</span>\n <span>Messages</span>\n <span>Updated</span>\n <span className=\"sr-only\">Actions</span>\n </div>\n {props.sessionLoadState === \"loading\" && props.sessions.length === 0 ? (\n <div className=\"px-5 py-4 text-sm font-medium text-muted-foreground\">\n Loading sessions\n </div>\n ) : null}\n {props.sessionLoadState === \"idle\" && props.sessions.length === 0 ? (\n <div className=\"px-5 py-4 text-sm font-medium text-muted-foreground\">No sessions</div>\n ) : null}\n {props.sessions.map((session) => (\n <div\n className={cn(\n \"mt-1 grid min-h-14 w-full min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px_72px] items-center gap-4 rounded-lg border border-transparent px-4 text-left text-muted-foreground transition duration-200 hover:border-border/70 hover:bg-accent/80 hover:text-accent-foreground\",\n session.id === props.selectedSessionId &&\n \"border-border/80 bg-muted/45 text-foreground\",\n )}\n key={session.id}\n >\n <Button\n className=\"col-span-4 grid h-full min-h-14 min-w-0 grid-cols-[minmax(220px,1.3fr)_180px_120px_120px] items-center justify-start gap-4 border-0 bg-transparent p-0 text-left text-inherit shadow-none hover:bg-transparent hover:text-inherit\"\n type=\"button\"\n variant=\"ghost\"\n onClick={() => props.onOpenSession(session.id)}\n >\n <span className=\"grid min-w-0 gap-0.5\">\n <strong className=\"min-w-0 truncate text-sm font-medium text-foreground\">\n {session.title ?? \"Untitled chat\"}\n </strong>\n <span className=\"min-w-0 truncate text-xs font-medium text-muted-foreground\">\n {session.id}\n </span>\n </span>\n <span className=\"min-w-0 truncate text-xs font-medium\">\n {agentLabel(props.agents, session.agentId)}\n </span>\n <span className=\"text-xs font-medium tabular-nums text-muted-foreground\">\n {session.messageCount} messages\n </span>\n <time className=\"text-xs font-medium text-muted-foreground\">\n {formatRelativeTime(session.updatedAt)}\n </time>\n </Button>\n <span className=\"flex items-center justify-end gap-1\">\n <Button\n aria-label={`View tracing for ${session.title ?? \"Untitled chat\"}`}\n className=\"h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-foreground hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5\"\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n onClick={(event) => {\n event.stopPropagation();\n props.onViewSessionTracing(session.id);\n }}\n >\n <StudioIcon icon={Activity01Icon} aria-hidden=\"true\" />\n </Button>\n <Button\n aria-label={`Delete ${session.title ?? \"Untitled chat\"}`}\n className=\"h-7 min-h-7 w-7 border-0 bg-transparent p-0 text-muted-foreground opacity-80 hover:bg-transparent hover:text-destructive hover:opacity-100 [&_svg]:h-3.5 [&_svg]:w-3.5\"\n size=\"icon\"\n type=\"button\"\n variant=\"ghost\"\n onClick={(event) => {\n event.stopPropagation();\n props.onDeleteSession(session);\n }}\n >\n <StudioIcon icon={Delete02Icon} aria-hidden=\"true\" />\n </Button>\n </span>\n </div>\n ))}\n </StudioSurface>\n </StudioPageShell>\n );\n}\n\nexport function DeleteSessionDialog(props: {\n session: StudioSessionSummary | undefined;\n onOpenChange: (open: boolean) => void;\n onConfirm: (session: StudioSessionSummary) => void;\n}) {\n const title = props.session?.title ?? \"Untitled chat\";\n\n return (\n <Dialog open={props.session !== undefined} onOpenChange={props.onOpenChange}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete session</DialogTitle>\n <DialogDescription>\n Delete \"{title}\" and its traces. This cannot be undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button type=\"button\" variant=\"ghost\" onClick={() => props.onOpenChange(false)}>\n Cancel\n </Button>\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={() => {\n if (props.session !== undefined) {\n props.onConfirm(props.session);\n }\n }}\n >\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as e,r as t,s as n}from"./utils-C9GMruoG.js";import{o as r}from"./format-D43vTqrO.js";import{L as i}from"./index-BA0rdlcA.js";import{t as a}from"./badge-D7D2A73-.js";import{t as o}from"./renderers-BYO0FrBn.js";var s=n(e(),1),c=t();function l(e){let[t,n]=(0,s.useState)(),[r,a]=(0,s.useState)(!1),[o,l]=(0,s.useState)(``),d=(0,s.useCallback)(async()=>{if(!e.enabled){n(void 0);return}a(!0),l(``);try{let e=await fetch(`/status`);if(!e.ok)throw Error(`Status failed with HTTP ${e.status}`);n(await e.json())}catch(e){l(e instanceof Error?e.message:String(e)),n(void 0)}finally{a(!1)}},[e.enabled]);return(0,s.useEffect)(()=>{d()},[d]),(0,c.jsxs)(`section`,{className:`grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-background/55`,"aria-label":`Status`,children:[(0,c.jsx)(`header`,{className:`bg-background/70 pb-3 pl-4 pr-6 pt-4 backdrop-blur`,children:(0,c.jsxs)(`div`,{className:`grid w-full grid-cols-[minmax(0,1fr)_auto] items-end gap-4 max-md:grid-cols-1`,children:[(0,c.jsxs)(`div`,{className:`grid min-w-0 gap-2`,children:[(0,c.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-[0.24em] text-muted-foreground`,children:`Operations`}),(0,c.jsx)(`h1`,{className:`m-0 text-2xl font-semibold leading-none tracking-tight text-foreground`,children:`Status`}),(0,c.jsx)(`p`,{className:`m-0 max-w-[62ch] text-sm leading-6 text-muted-foreground`,children:`Runtime health, storage adapters, feature capabilities, and current record counts.`})]}),(0,c.jsxs)(`div`,{className:`flex min-w-0 flex-wrap justify-end gap-2 max-md:justify-start`,children:[(0,c.jsx)(g,{label:`agents`,value:t?.counts.agents??0}),(0,c.jsx)(g,{label:`sessions`,value:t?.counts.sessions??`-`}),(0,c.jsx)(g,{label:`traces`,value:t?.counts.traces??`-`}),(0,c.jsx)(i,{className:`h-8 min-h-8 rounded-md px-3 text-xs`,type:`button`,variant:`secondary`,disabled:r,onClick:()=>void d(),children:`Refresh`})]})]})}),(0,c.jsx)(`div`,{className:`min-h-0 overflow-auto pb-6 pl-4 pr-6`,children:e.enabled?r&&t===void 0?(0,c.jsx)(S,{title:`Loading status`,text:`Reading runtime status.`}):o.length>0?(0,c.jsx)(S,{title:`Status error`,text:o}):t===void 0?null:(0,c.jsx)(u,{summary:t}):(0,c.jsx)(S,{title:`Status unavailable`,text:`This Studio runtime did not expose status.`})})]})}function u(e){let t=Object.entries(e.summary.capabilities).filter(([,e])=>e?.enabled===!0).length;return(0,c.jsxs)(`div`,{className:`grid h-full min-h-0 gap-5 border-t border-border/80 pt-4`,children:[(0,c.jsxs)(`section`,{className:`grid gap-5 xl:grid-cols-[minmax(280px,0.58fr)_minmax(0,1.42fr)]`,children:[(0,c.jsx)(d,{summary:e.summary,enabledCapabilityCount:t}),(0,c.jsxs)(`div`,{className:`grid gap-5 lg:grid-cols-2`,children:[(0,c.jsx)(f,{storage:e.summary.storage}),(0,c.jsx)(p,{counts:e.summary.counts})]})]}),(0,c.jsxs)(`section`,{className:`grid gap-5 xl:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]`,children:[(0,c.jsx)(m,{capabilities:e.summary.capabilities}),(0,c.jsx)(h,{summary:e.summary})]})]})}function d(e){return(0,c.jsxs)(`section`,{className:`grid content-start gap-5 border-b border-border/80 pb-5 xl:border-b-0 xl:border-r xl:pb-0 xl:pr-5`,children:[(0,c.jsxs)(`div`,{className:`grid gap-3`,children:[(0,c.jsx)(v,{children:`runtime`}),(0,c.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,c.jsx)(a,{className:`border-border/80 bg-muted/45 text-foreground`,children:`online`}),(0,c.jsxs)(a,{className:`border-border/80 bg-background/45 text-muted-foreground`,children:[e.enabledCapabilityCount,` capabilities`]})]})]}),(0,c.jsxs)(`div`,{className:`grid border-y border-border/80`,children:[(0,c.jsx)(y,{label:`id`,value:e.summary.runner.id}),(0,c.jsx)(y,{label:`name`,value:e.summary.runner.name??`-`}),(0,c.jsx)(y,{label:`version`,value:e.summary.runner.version??`-`}),(0,c.jsx)(y,{label:`generated`,value:`${r(e.summary.generatedAt)} / ${e.summary.generatedAt}`})]})]})}function f(e){let t=Object.entries(e.storage);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`storage`,value:`${t.length} adapters`}),t.length===0?(0,c.jsx)(x,{text:`No storage adapters reported.`}):(0,c.jsx)(`div`,{className:`grid border-y border-border/80`,children:t.map(([e,t])=>(0,c.jsx)(b,{label:C(e),value:t??`-`,tone:t===void 0?`muted`:`normal`},e))})]})}function p(e){let t=Object.entries(e.counts).filter(e=>typeof e[1]==`number`);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`records`,value:`${t.length} counters`}),(0,c.jsx)(`div`,{className:`grid border-y border-border/80`,children:t.map(([e,t])=>(0,c.jsx)(b,{label:C(e),value:t},e))})]})}function m(e){let t=Object.entries(e.capabilities);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`capabilities`,value:`${t.length} reported`}),t.length===0?(0,c.jsx)(x,{text:`No capabilities reported.`}):(0,c.jsx)(`div`,{className:`grid border-y border-border/80 sm:grid-cols-2 sm:divide-x sm:divide-border/80`,children:t.map(([e,n],r)=>(0,c.jsxs)(`div`,{className:[`grid min-w-0 gap-1 border-b border-border/70 px-3 py-3`,r>=t.length-(t.length%2==0?2:1)?`sm:border-b-0`:``].join(` `),children:[(0,c.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm font-semibold text-foreground`,children:C(e)}),(0,c.jsx)(`span`,{className:n?.enabled?`text-xs font-medium text-foreground`:`text-xs font-medium text-muted-foreground`,children:n?.enabled?`enabled`:`disabled`})]}),n?.reason===void 0?null:(0,c.jsx)(`p`,{className:`m-0 text-xs leading-5 text-muted-foreground`,children:n.reason})]},e))})]})}function h(e){return(0,c.jsxs)(`section`,{className:`grid min-w-0 content-start gap-3`,children:[(0,c.jsx)(_,{title:`raw summary`,value:`JSON`}),(0,c.jsxs)(`details`,{className:`group grid min-w-0 overflow-hidden border-y border-border/80`,open:!0,children:[(0,c.jsxs)(`summary`,{className:`flex min-h-11 cursor-pointer list-none items-center justify-between gap-3 bg-muted/10 px-3 text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground marker:hidden`,children:[`Payload`,(0,c.jsx)(`span`,{className:`font-medium normal-case tracking-normal group-open:hidden`,children:`Show`}),(0,c.jsx)(`span`,{className:`hidden font-medium normal-case tracking-normal group-open:inline`,children:`Hide`})]}),(0,c.jsx)(`div`,{className:`min-w-0 overflow-x-auto border-t border-border/70`,children:(0,c.jsx)(`pre`,{className:`m-0 max-h-[28rem] min-w-max p-4 text-xs leading-5 text-foreground`,children:(0,c.jsx)(`code`,{children:(0,c.jsx)(o,{text:JSON.stringify(e.summary,null,2)})})})})]})]})}function g(e){return(0,c.jsxs)(`span`,{className:`inline-flex h-8 items-center gap-2 rounded-md border border-border/70 bg-background/45 px-2.5 text-xs font-medium text-muted-foreground`,children:[(0,c.jsx)(`span`,{className:`font-semibold tabular-nums text-foreground`,children:e.value}),e.label]})}function _(e){return(0,c.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,c.jsx)(v,{children:e.title}),(0,c.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:e.value})]})}function v(e){return(0,c.jsx)(`h2`,{className:`m-0 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground`,children:e.children})}function y(e){return(0,c.jsxs)(`div`,{className:`grid min-w-0 gap-1 border-b border-border/70 px-3 py-3 first:pt-3 last:border-b-0`,children:[(0,c.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:e.label}),(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm text-foreground`,title:String(e.value),children:e.value})]})}function b(e){return(0,c.jsxs)(`div`,{className:`grid min-w-0 grid-cols-[minmax(120px,0.5fr)_minmax(0,1fr)] gap-3 border-b border-border/70 px-3 py-3 last:border-b-0`,children:[(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-muted-foreground`,children:e.label}),(0,c.jsx)(`span`,{className:[`min-w-0 truncate text-right text-sm font-semibold tabular-nums`,e.tone===`muted`?`text-muted-foreground`:`text-foreground`].join(` `),title:String(e.value),children:e.value})]})}function x(e){return(0,c.jsx)(`div`,{className:`border-y border-dashed border-border/80 px-3 py-8 text-center text-sm text-muted-foreground`,children:e.text})}function S(e){return(0,c.jsx)(`div`,{className:`grid min-h-80 place-items-center rounded-xl border border-dashed border-border/80 bg-card/35 px-6 text-center`,children:(0,c.jsxs)(`div`,{className:`grid max-w-md gap-2`,children:[(0,c.jsx)(`h2`,{className:`m-0 text-base font-semibold text-foreground`,children:e.title}),(0,c.jsx)(`p`,{className:`m-0 text-sm leading-6 text-muted-foreground`,children:e.text})]})})}function C(e){return e.replace(/([a-z])([A-Z])/g,`$1 $2`).replace(/[_-]+/g,` `).toLowerCase()}export{l as StatusPage};
2
- //# sourceMappingURL=status-page-C1lHztV8.js.map
1
+ import{i as e,r as t,s as n}from"./utils-C9GMruoG.js";import{o as r}from"./format-D43vTqrO.js";import{L as i}from"./index-DY62pnOs.js";import{t as a}from"./badge-D7D2A73-.js";import{t as o}from"./renderers-BYO0FrBn.js";var s=n(e(),1),c=t();function l(e){let[t,n]=(0,s.useState)(),[r,a]=(0,s.useState)(!1),[o,l]=(0,s.useState)(``),d=(0,s.useCallback)(async()=>{if(!e.enabled){n(void 0);return}a(!0),l(``);try{let e=await fetch(`/status`);if(!e.ok)throw Error(`Status failed with HTTP ${e.status}`);n(await e.json())}catch(e){l(e instanceof Error?e.message:String(e)),n(void 0)}finally{a(!1)}},[e.enabled]);return(0,s.useEffect)(()=>{d()},[d]),(0,c.jsxs)(`section`,{className:`grid min-h-0 grid-rows-[auto_minmax(0,1fr)] overflow-hidden bg-background/55`,"aria-label":`Status`,children:[(0,c.jsx)(`header`,{className:`bg-background/70 pb-3 pl-4 pr-6 pt-4 backdrop-blur`,children:(0,c.jsxs)(`div`,{className:`grid w-full grid-cols-[minmax(0,1fr)_auto] items-end gap-4 max-md:grid-cols-1`,children:[(0,c.jsxs)(`div`,{className:`grid min-w-0 gap-2`,children:[(0,c.jsx)(`div`,{className:`text-xs font-semibold uppercase tracking-[0.24em] text-muted-foreground`,children:`Operations`}),(0,c.jsx)(`h1`,{className:`m-0 text-2xl font-semibold leading-none tracking-tight text-foreground`,children:`Status`}),(0,c.jsx)(`p`,{className:`m-0 max-w-[62ch] text-sm leading-6 text-muted-foreground`,children:`Runtime health, storage adapters, feature capabilities, and current record counts.`})]}),(0,c.jsxs)(`div`,{className:`flex min-w-0 flex-wrap justify-end gap-2 max-md:justify-start`,children:[(0,c.jsx)(g,{label:`agents`,value:t?.counts.agents??0}),(0,c.jsx)(g,{label:`sessions`,value:t?.counts.sessions??`-`}),(0,c.jsx)(g,{label:`traces`,value:t?.counts.traces??`-`}),(0,c.jsx)(i,{className:`h-8 min-h-8 rounded-md px-3 text-xs`,type:`button`,variant:`secondary`,disabled:r,onClick:()=>void d(),children:`Refresh`})]})]})}),(0,c.jsx)(`div`,{className:`min-h-0 overflow-auto pb-6 pl-4 pr-6`,children:e.enabled?r&&t===void 0?(0,c.jsx)(S,{title:`Loading status`,text:`Reading runtime status.`}):o.length>0?(0,c.jsx)(S,{title:`Status error`,text:o}):t===void 0?null:(0,c.jsx)(u,{summary:t}):(0,c.jsx)(S,{title:`Status unavailable`,text:`This Studio runtime did not expose status.`})})]})}function u(e){let t=Object.entries(e.summary.capabilities).filter(([,e])=>e?.enabled===!0).length;return(0,c.jsxs)(`div`,{className:`grid h-full min-h-0 gap-5 border-t border-border/80 pt-4`,children:[(0,c.jsxs)(`section`,{className:`grid gap-5 xl:grid-cols-[minmax(280px,0.58fr)_minmax(0,1.42fr)]`,children:[(0,c.jsx)(d,{summary:e.summary,enabledCapabilityCount:t}),(0,c.jsxs)(`div`,{className:`grid gap-5 lg:grid-cols-2`,children:[(0,c.jsx)(f,{storage:e.summary.storage}),(0,c.jsx)(p,{counts:e.summary.counts})]})]}),(0,c.jsxs)(`section`,{className:`grid gap-5 xl:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]`,children:[(0,c.jsx)(m,{capabilities:e.summary.capabilities}),(0,c.jsx)(h,{summary:e.summary})]})]})}function d(e){return(0,c.jsxs)(`section`,{className:`grid content-start gap-5 border-b border-border/80 pb-5 xl:border-b-0 xl:border-r xl:pb-0 xl:pr-5`,children:[(0,c.jsxs)(`div`,{className:`grid gap-3`,children:[(0,c.jsx)(v,{children:`runtime`}),(0,c.jsxs)(`div`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,c.jsx)(a,{className:`border-border/80 bg-muted/45 text-foreground`,children:`online`}),(0,c.jsxs)(a,{className:`border-border/80 bg-background/45 text-muted-foreground`,children:[e.enabledCapabilityCount,` capabilities`]})]})]}),(0,c.jsxs)(`div`,{className:`grid border-y border-border/80`,children:[(0,c.jsx)(y,{label:`id`,value:e.summary.runner.id}),(0,c.jsx)(y,{label:`name`,value:e.summary.runner.name??`-`}),(0,c.jsx)(y,{label:`version`,value:e.summary.runner.version??`-`}),(0,c.jsx)(y,{label:`generated`,value:`${r(e.summary.generatedAt)} / ${e.summary.generatedAt}`})]})]})}function f(e){let t=Object.entries(e.storage);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`storage`,value:`${t.length} adapters`}),t.length===0?(0,c.jsx)(x,{text:`No storage adapters reported.`}):(0,c.jsx)(`div`,{className:`grid border-y border-border/80`,children:t.map(([e,t])=>(0,c.jsx)(b,{label:C(e),value:t??`-`,tone:t===void 0?`muted`:`normal`},e))})]})}function p(e){let t=Object.entries(e.counts).filter(e=>typeof e[1]==`number`);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`records`,value:`${t.length} counters`}),(0,c.jsx)(`div`,{className:`grid border-y border-border/80`,children:t.map(([e,t])=>(0,c.jsx)(b,{label:C(e),value:t},e))})]})}function m(e){let t=Object.entries(e.capabilities);return(0,c.jsxs)(`section`,{className:`grid content-start gap-3`,children:[(0,c.jsx)(_,{title:`capabilities`,value:`${t.length} reported`}),t.length===0?(0,c.jsx)(x,{text:`No capabilities reported.`}):(0,c.jsx)(`div`,{className:`grid border-y border-border/80 sm:grid-cols-2 sm:divide-x sm:divide-border/80`,children:t.map(([e,n],r)=>(0,c.jsxs)(`div`,{className:[`grid min-w-0 gap-1 border-b border-border/70 px-3 py-3`,r>=t.length-(t.length%2==0?2:1)?`sm:border-b-0`:``].join(` `),children:[(0,c.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm font-semibold text-foreground`,children:C(e)}),(0,c.jsx)(`span`,{className:n?.enabled?`text-xs font-medium text-foreground`:`text-xs font-medium text-muted-foreground`,children:n?.enabled?`enabled`:`disabled`})]}),n?.reason===void 0?null:(0,c.jsx)(`p`,{className:`m-0 text-xs leading-5 text-muted-foreground`,children:n.reason})]},e))})]})}function h(e){return(0,c.jsxs)(`section`,{className:`grid min-w-0 content-start gap-3`,children:[(0,c.jsx)(_,{title:`raw summary`,value:`JSON`}),(0,c.jsxs)(`details`,{className:`group grid min-w-0 overflow-hidden border-y border-border/80`,open:!0,children:[(0,c.jsxs)(`summary`,{className:`flex min-h-11 cursor-pointer list-none items-center justify-between gap-3 bg-muted/10 px-3 text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground marker:hidden`,children:[`Payload`,(0,c.jsx)(`span`,{className:`font-medium normal-case tracking-normal group-open:hidden`,children:`Show`}),(0,c.jsx)(`span`,{className:`hidden font-medium normal-case tracking-normal group-open:inline`,children:`Hide`})]}),(0,c.jsx)(`div`,{className:`min-w-0 overflow-x-auto border-t border-border/70`,children:(0,c.jsx)(`pre`,{className:`m-0 max-h-[28rem] min-w-max p-4 text-xs leading-5 text-foreground`,children:(0,c.jsx)(`code`,{children:(0,c.jsx)(o,{text:JSON.stringify(e.summary,null,2)})})})})]})]})}function g(e){return(0,c.jsxs)(`span`,{className:`inline-flex h-8 items-center gap-2 rounded-md border border-border/70 bg-background/45 px-2.5 text-xs font-medium text-muted-foreground`,children:[(0,c.jsx)(`span`,{className:`font-semibold tabular-nums text-foreground`,children:e.value}),e.label]})}function _(e){return(0,c.jsxs)(`div`,{className:`flex min-w-0 items-center justify-between gap-3`,children:[(0,c.jsx)(v,{children:e.title}),(0,c.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:e.value})]})}function v(e){return(0,c.jsx)(`h2`,{className:`m-0 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground`,children:e.children})}function y(e){return(0,c.jsxs)(`div`,{className:`grid min-w-0 gap-1 border-b border-border/70 px-3 py-3 first:pt-3 last:border-b-0`,children:[(0,c.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground`,children:e.label}),(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm text-foreground`,title:String(e.value),children:e.value})]})}function b(e){return(0,c.jsxs)(`div`,{className:`grid min-w-0 grid-cols-[minmax(120px,0.5fr)_minmax(0,1fr)] gap-3 border-b border-border/70 px-3 py-3 last:border-b-0`,children:[(0,c.jsx)(`span`,{className:`min-w-0 truncate text-sm font-medium text-muted-foreground`,children:e.label}),(0,c.jsx)(`span`,{className:[`min-w-0 truncate text-right text-sm font-semibold tabular-nums`,e.tone===`muted`?`text-muted-foreground`:`text-foreground`].join(` `),title:String(e.value),children:e.value})]})}function x(e){return(0,c.jsx)(`div`,{className:`border-y border-dashed border-border/80 px-3 py-8 text-center text-sm text-muted-foreground`,children:e.text})}function S(e){return(0,c.jsx)(`div`,{className:`grid min-h-80 place-items-center rounded-xl border border-dashed border-border/80 bg-card/35 px-6 text-center`,children:(0,c.jsxs)(`div`,{className:`grid max-w-md gap-2`,children:[(0,c.jsx)(`h2`,{className:`m-0 text-base font-semibold text-foreground`,children:e.title}),(0,c.jsx)(`p`,{className:`m-0 text-sm leading-6 text-muted-foreground`,children:e.text})]})})}function C(e){return e.replace(/([a-z])([A-Z])/g,`$1 $2`).replace(/[_-]+/g,` `).toLowerCase()}export{l as StatusPage};
2
+ //# sourceMappingURL=status-page-BeUj83WX.js.map