@qredence/fleet 0.5.1 → 0.5.5

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 (78) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/bin/fleet-prime.mjs +6 -0
  3. package/dist/web/client/assets/action-swap-roll-DX5o_33Q.js +1 -0
  4. package/dist/web/client/assets/artifacts-panel-C3yewUBP.js +1 -0
  5. package/dist/web/client/assets/{chat-CsepBQwy.js → chat-W-yOMyG_.js} +1 -1
  6. package/dist/web/client/assets/chat-command-palette-D0xDK1j4.js +1 -0
  7. package/dist/web/client/assets/command-CQzrtjyj.js +2 -0
  8. package/dist/web/client/assets/{fleet-pi-tool-renderer-BD_ZAjlG.js → fleet-pi-tool-renderer-B0Y7ou0U.js} +16 -16
  9. package/dist/web/client/assets/generative-text-renderer-SS9c1kNX.js +6 -0
  10. package/dist/web/client/assets/globals-D_Hy9bT1.css +2 -0
  11. package/dist/web/client/assets/{index-DweoFRMs.js → index-C9FloFgj.js} +2 -2
  12. package/dist/web/client/assets/{ipython-tool-BfeIa0nK.js → ipython-tool-BrMePqD-.js} +1 -1
  13. package/dist/web/client/assets/{openui-renderer-DlUo6ehT.js → openui-renderer-CCfQqUfE.js} +5 -5
  14. package/dist/web/client/assets/{prime-agent-artifacts-CHGb5V_j.js → prime-agent-artifacts-C-g1VPiW.js} +1 -1
  15. package/dist/web/client/assets/range-65lubOFp.js +2 -0
  16. package/dist/web/client/assets/repl-panel-CCh4ly7J.js +1 -0
  17. package/dist/web/client/assets/routes-DSTyx_J0.js +16 -0
  18. package/dist/web/client/assets/session-insights-panel-CQdT90Op.js +1 -0
  19. package/dist/web/client/assets/subagent-chat-panel-D-qw4uWb.js +1 -0
  20. package/dist/web/client/assets/subagent-transcript-C7oRwEEP.js +1 -0
  21. package/dist/web/client/assets/subagents-panel-aSMWZP9p.js +1 -0
  22. package/dist/web/client/assets/{tool-result-CBzwwUE9.js → tool-result-C2NvnN32.js} +3 -3
  23. package/dist/web/server/{_tanstack-start-manifest_v-bDUlyKY0-KFW35JRO.js → _tanstack-start-manifest_v-DZc7dwm7-6ZQLGXB7.js} +13 -13
  24. package/dist/web/server/{artifacts-panel-D9w1DHAN-FGRDCYU2.js → artifacts-panel-Bt7YUzm4-NCBMXJ25.js} +15 -15
  25. package/dist/web/server/{chat-command-palette-BaenPkCN-BHSOPGU4.js → chat-command-palette-Co1L3rUY-RQLNME4T.js} +33 -12
  26. package/dist/web/server/{chunk-KPNGZR2R.js → chunk-2V6B62OF.js} +204 -204
  27. package/dist/web/server/{chunk-44IVTHDV.js → chunk-3HUI75QM.js} +60 -60
  28. package/dist/web/server/{chunk-5AVQZ4AZ.js → chunk-4UBOIY2S.js} +2 -1
  29. package/dist/web/server/{chunk-Y6LJ4WBI.js → chunk-56HSKUBD.js} +699 -691
  30. package/dist/web/server/{chunk-RPROZ2JC.js → chunk-5RQ6QAZX.js} +133 -133
  31. package/dist/web/server/{chunk-PWK2HJIV.js → chunk-6D524OCJ.js} +175 -175
  32. package/dist/web/server/{chunk-FBOO3G67.js → chunk-AECEK3K7.js} +6 -6
  33. package/dist/web/server/{chunk-VHCAD46L.js → chunk-AWFOBHH4.js} +4 -4
  34. package/dist/web/server/{chunk-FVWDJNXR.js → chunk-BEMDNODD.js} +1 -1
  35. package/dist/web/server/{chunk-X2TUFLTP.js → chunk-BLVCDQ7E.js} +438 -438
  36. package/dist/web/server/{chunk-EIVNRYP3.js → chunk-FZRBAPUM.js} +2 -2
  37. package/dist/web/server/chunk-KOIPYBJF.js +3773 -0
  38. package/dist/web/server/{chunk-XYYNYFFD.js → chunk-LSIHVSUT.js} +2 -2
  39. package/dist/web/server/{chunk-H64JLONZ.js → chunk-PDRD2X5G.js} +2 -2
  40. package/dist/web/server/{chunk-FE4KN6T2.js → chunk-RX62LUDV.js} +4 -4
  41. package/dist/web/server/chunk-SR65ARVS.js +192 -0
  42. package/dist/web/server/{chunk-WK7CQS2N.js → chunk-SZ65K4CO.js} +48 -48
  43. package/dist/web/server/{chunk-DO3TVNGA.js → chunk-TO3YPLNZ.js} +6 -6
  44. package/dist/web/server/{chunk-3IKSPTYI.js → chunk-UKINNXJY.js} +2 -2
  45. package/dist/web/server/{chunk-M2FGGPNA.js → chunk-VGDP4YDU.js} +70 -45
  46. package/dist/web/server/{chunk-PCJ5EKFE.js → chunk-VRLTWOVJ.js} +11 -6
  47. package/dist/web/server/{chunk-HBZ6YKRB.js → chunk-WN77JNYY.js} +2 -2
  48. package/dist/web/server/{chunk-2U7PWSJX.js → chunk-WZNZQNI4.js} +231 -3633
  49. package/dist/web/server/{chunk-B2F6MLVZ.js → chunk-XFVL5ITL.js} +2246 -2228
  50. package/dist/web/server/{chunk-3GSFXWL5.js → chunk-XLCTCC4W.js} +3 -3
  51. package/dist/web/server/{chunk-AZZHUVJR.js → chunk-Y4MHIA7B.js} +18 -26
  52. package/dist/web/server/{fleet-pi-tool-renderer-lJvZWmBJ-4M5YI6VS.js → fleet-pi-tool-renderer-CE45vM6T-2UQN6RJM.js} +11 -9
  53. package/dist/web/server/{fork-picker-dialog-BZzfxdQd-Y725VJ7G.js → fork-picker-dialog-DCzuGelH-TN2Q5OXI.js} +5 -5
  54. package/dist/web/server/{openui-renderer-Cg4RSE9k-7BTJIYZJ.js → openui-renderer-c36_GYes-HX46N4M5.js} +11 -11
  55. package/dist/web/server/{repl-panel-BEQrC2ef-V3YEZ7EO.js → repl-panel-D9E8nkQy-L45ZNG2V.js} +4 -3
  56. package/dist/web/server/{router-CEahIUpn-SRG7XKIH.js → router-_ZpegqiQ-QIE44PIB.js} +1737 -1370
  57. package/dist/web/server/{routes-BznemByz-F4DJAYIM.js → routes-Ct81-8Tq-LHRMOS7R.js} +2882 -2330
  58. package/dist/web/server/server.js +3 -3
  59. package/dist/web/server/{session-insights-panel-JfeTHE0d-3HZB3ZWI.js → session-insights-panel-BHZyKDTo-LRMAMA3O.js} +4 -2
  60. package/dist/web/server/{settings-dialog-DgeBMORv-7SRSENPM.js → settings-dialog-B4uUS6f--AZ4I4ZOT.js} +142 -142
  61. package/dist/web/server/{start-CLAD7RcD-56S4BWMM.js → start-BYVnok_H-IA6TWGA3.js} +1 -1
  62. package/dist/web/server/subagent-chat-panel-C97S3WID-DLOAD5TG.js +63 -0
  63. package/dist/web/server/subagents-panel-iHpvMIZy-LI6XK66M.js +181 -0
  64. package/dist/web/server/{workspace-panel-y54P79_B-VPIYUXF6.js → workspace-panel-CHPoiXEo-YB4WS3MK.js} +2 -2
  65. package/package.json +5 -5
  66. package/dist/web/client/assets/artifacts-panel-CX62LQ13.js +0 -1
  67. package/dist/web/client/assets/chat-command-palette-C4sSf8Kg.js +0 -1
  68. package/dist/web/client/assets/collapsible-DmyYcezk.js +0 -1
  69. package/dist/web/client/assets/command-CB6emP8m.js +0 -2
  70. package/dist/web/client/assets/conversation-turns-ByFoWPXe.js +0 -6
  71. package/dist/web/client/assets/globals-CqqQdk2S.css +0 -2
  72. package/dist/web/client/assets/range-vSJ7Ux_5.js +0 -2
  73. package/dist/web/client/assets/repl-panel-DiGS6uCw.js +0 -1
  74. package/dist/web/client/assets/routes-CxlNCi_v.js +0 -16
  75. package/dist/web/client/assets/session-insights-panel-DwmwiikS.js +0 -1
  76. package/dist/web/client/assets/subagents-panel-DGnsK6Nx.js +0 -1
  77. package/dist/web/server/chunk-ZEVZFLIY.js +0 -334
  78. package/dist/web/server/subagents-panel-CzZe3co7-2VZ5JTWF.js +0 -332
@@ -1 +0,0 @@
1
- import{t as e}from"./jsx-runtime-NZYk81nU.js";var t=[`queued`,`running`,`done`,`error`,`cancelled`];function n({activityLabel:e,artifactRuns:n,messages:r,planLabel:i,presentation:a,queue:o}){let s=Object.fromEntries(t.map(e=>[e,0]));for(let e of a.rlmChildren)s[e.status]+=1;let c=a.refinements.reduce((e,t)=>({failed:e.failed+Number(t.status===`error`),successful:e.successful+Number(t.status===`success`),total:e.total+1}),{failed:0,successful:0,total:0}),l=n.flatMap(e=>e.artifacts);return{activity:e||i||`Waiting for input`,artifactCount:l.length,assistantMessages:r.filter(e=>e.role===`assistant`).length,bashCommands:a.userBash.length,goal:a.goal,ipythonCells:l.filter(e=>e.kind===`ipython`).length,queuedFollowUps:o.followUp.length,queuedSteering:o.steering.length,refinements:c,rlmChildren:s,userMessages:r.filter(e=>e.role===`user`).length}}var r=e();function i(e){return e.replaceAll(`_`,` `)}function a(e){let t=Math.max(0,Math.round(e)),n=Math.floor(t/3600),r=Math.floor(t%3600/60),i=t%60;return n>0?`${n}h ${r}m`:r>0?`${r}m ${i}s`:`${i}s`}function o({children:e,label:t}){return(0,r.jsxs)(`section`,{"aria-label":t,className:`rounded-md border border-border/60 bg-background px-3 py-2.5 shadow-[0_1px_4px_-1px_rgba(0,0,0,0.06)]`,children:[(0,r.jsx)(`h3`,{className:`mb-2 text-[11px] font-medium uppercase tracking-wide text-foreground/45`,children:t}),(0,r.jsx)(`dl`,{className:`space-y-1.5 text-[12px]`,children:e})]})}function s({label:e,value:t}){return(0,r.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,r.jsx)(`dt`,{className:`text-foreground/50`,children:e}),(0,r.jsx)(`dd`,{className:`min-w-0 text-right font-medium text-foreground/80`,children:t})]})}function c({goal:e}){return(0,r.jsxs)(o,{label:`Goal`,children:[(0,r.jsx)(s,{label:`Status`,value:i(e.status)}),e.objective?(0,r.jsx)(s,{label:`Objective`,value:(0,r.jsx)(`span`,{className:`block max-w-56 text-pretty`,children:e.objective})}):null,(0,r.jsx)(s,{label:`Elapsed`,value:a(e.timeUsedSeconds)}),(0,r.jsx)(s,{label:`Token usage`,value:e.tokensUsed}),e.tokenBudget===void 0?null:(0,r.jsx)(s,{label:`Token budget`,value:e.tokenBudget}),(0,r.jsx)(s,{label:`Continuations`,value:e.continuationsUsed})]})}function l({activityLabel:e,artifactRuns:i,chatMode:a,messages:l,planLabel:u,presentation:d,queue:f,selectedModelKey:p,sessionId:m,status:h,thinkingLevel:g}){if(!m)return(0,r.jsx)(`section`,{"aria-label":`Session insights`,className:`flex min-h-36 items-center rounded-md border border-dashed border-border/70 px-4 text-center text-[12px] leading-5 text-foreground/45`,children:`Start or open a session to view its live insights.`});let _=n({activityLabel:e,artifactRuns:i,messages:l,planLabel:u,presentation:d,queue:f}),v=t.map(e=>`${_.rlmChildren[e]} ${e}`).join(` · `);return(0,r.jsxs)(`section`,{"aria-label":`Session insights`,className:`space-y-2.5 pb-1`,children:[(0,r.jsxs)(o,{label:`Current state`,children:[(0,r.jsx)(s,{label:`Run status`,value:h}),(0,r.jsx)(s,{label:`Activity`,value:(0,r.jsx)(`span`,{className:`block max-w-56 text-pretty`,children:_.activity})}),(0,r.jsx)(s,{label:`Queued steering`,value:_.queuedSteering}),(0,r.jsx)(s,{label:`Queued follow-ups`,value:_.queuedFollowUps})]}),_.goal?(0,r.jsx)(c,{goal:_.goal}):null,(0,r.jsxs)(o,{label:`Configuration`,children:[(0,r.jsx)(s,{label:`Model`,value:p??`Not selected`}),(0,r.jsx)(s,{label:`Mode`,value:a}),(0,r.jsx)(s,{label:`Reasoning`,value:g??d.thinkingLevel??`Not set`})]}),(0,r.jsxs)(o,{label:`Progress`,children:[(0,r.jsx)(s,{label:`User messages`,value:_.userMessages}),(0,r.jsx)(s,{label:`Assistant messages`,value:_.assistantMessages}),(0,r.jsx)(s,{label:`Artifacts`,value:_.artifactCount}),(0,r.jsx)(s,{label:`Bash commands`,value:_.bashCommands}),(0,r.jsx)(s,{label:`IPython cells`,value:_.ipythonCells}),(0,r.jsx)(s,{label:`RLM children`,value:v||`None`}),(0,r.jsx)(s,{label:`Refinements`,value:`${_.refinements.total} total · ${_.refinements.successful} successful · ${_.refinements.failed} failed`})]}),d.recap?(0,r.jsx)(o,{label:`Existing recap`,children:(0,r.jsx)(s,{label:`Summary`,value:(0,r.jsx)(`span`,{className:`block max-w-56 whitespace-pre-wrap text-left text-pretty`,children:d.recap})})}):null]})}export{l as SessionInsightsPanel};
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{i as t}from"./bundle-mjs-DKHVkVWu.js";import{t as n}from"./jsx-runtime-NZYk81nU.js";import{t as r}from"./button-0At5xSyU.js";import{t as i}from"./utils-Eg7xtNmV.js";import{i as a}from"./range-vSJ7Ux_5.js";import{t as o}from"./bot-Bs7QWJ2q.js";import{t as s}from"./chevron-right-DrJxToLs.js";import{a as c,d as l,f as u,h as d,i as f,l as p,m,n as h,o as g,p as _,r as v,s as y,t as b,u as x}from"./conversation-turns-ByFoWPXe.js";import{n as S}from"./file-text-BhQ0ZnoU.js";import{n as C}from"./notify-Duj26eeZ.js";import{t as w}from"./prime-agent-artifacts-CHGb5V_j.js";import{FleetPiToolRenderer as T}from"./fleet-pi-tool-renderer-BD_ZAjlG.js";var E=e(t(),1),D=n();function O(e){return e.status===`running`?`streaming`:e.status===`error`?`error`:`ready`}function k({turn:e,isLast:t,isStreaming:n,artifacts:r,presentation:i}){let o=(0,E.useMemo)(()=>e.assistants.flatMap((r,i)=>p(x(r.parts??[]),{messageId:r.id,isLast:t&&i===e.assistants.length-1,isStreaming:n,suppressQuestionTool:!0,ToolRendererComponent:T,TextRendererComponent:g,toolRenderers:a})),[t,n,e.assistants]);return(0,D.jsxs)(`div`,{className:`flex flex-col gap-3`,children:[e.user?(0,D.jsx)(l,{from:`user`,children:(0,D.jsx)(u,{children:(0,D.jsx)(y,{message:e.user,enableImagePreview:!1})})}):null,e.assistants.length>0?(0,D.jsx)(l,{from:`assistant`,children:(0,D.jsx)(u,{children:(0,D.jsx)(m,{variant:`ghost`,children:(0,D.jsxs)(d,{children:[t?(0,D.jsx)(h,{messages:e.assistants,artifacts:r,streaming:n}):null,(0,D.jsx)(`div`,{className:`flex flex-col gap-3`,children:o}),t&&i?(0,D.jsx)(v,{children:i.rlmChildren,tree:i.rlmTree}):null]})})})}):null]})}function A({child:e,parentSessionId:t,transcript:n,onRefresh:a}){let s=(0,E.useMemo)(()=>n?.status===`ready`?b(n.messages):[],[n]),c=O(e),l=(0,E.useMemo)(()=>n?.status===`ready`?w(n.messages,n.presentation,c):[],[c,n]),u=(0,E.useMemo)(()=>l.flatMap(e=>e.artifacts),[l]);return(0,D.jsxs)(`section`,{"aria-label":`Subagent thread: ${e.label}`,className:`space-y-2`,children:[(0,D.jsxs)(`div`,{className:`flex min-w-0 items-start gap-2 rounded-md border border-border/60 bg-background px-2.5 py-2`,children:[(0,D.jsx)(o,{className:`mt-0.5 size-3.5 shrink-0 text-foreground/45`}),(0,D.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,D.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,D.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs font-medium text-foreground/80`,children:e.sessionName||e.label}),(0,D.jsx)(`span`,{className:`shrink-0 text-[10px] capitalize text-foreground/45`,children:e.status})]}),e.model?(0,D.jsx)(`p`,{className:`truncate font-mono text-[10px] text-foreground/40`,children:e.model}):null,e.answerPreview||e.recap?(0,D.jsx)(`p`,{className:`mt-1 line-clamp-3 whitespace-pre-wrap text-[11px] leading-4 text-foreground/55`,children:e.answerPreview??e.recap}):null]}),(0,D.jsx)(r,{type:`button`,variant:`ghost`,size:`icon-sm`,className:`shrink-0 text-foreground/40 hover:text-foreground/70`,"aria-label":`Refresh ${e.label} thread`,title:`Refresh ${e.label} thread`,onClick:a,children:(0,D.jsx)(C,{className:i(`size-3.5`,n?.status===`loading`&&`animate-spin`)})})]}),t?n?.status===`loading`?(0,D.jsx)(`div`,{className:`flex min-h-32 items-center justify-center rounded-md border border-dashed border-border/70 text-[11px] text-foreground/45`,children:`Loading subagent thread…`}):n?.status===`error`?(0,D.jsxs)(`div`,{role:`alert`,className:`flex items-start gap-2 rounded-md border border-destructive/30 bg-destructive/5 px-3 py-2 text-[11px] leading-4 text-destructive`,children:[(0,D.jsx)(S,{className:`mt-0.5 size-3.5 shrink-0`}),(0,D.jsx)(`span`,{children:n?.error?.message??`Unable to load this subagent thread.`})]}):s.length===0?(0,D.jsx)(`p`,{className:`rounded-md border border-dashed border-border/70 px-3 py-3 text-[11px] leading-4 text-foreground/45`,children:`This subagent thread has no messages yet.`}):(0,D.jsx)(`div`,{className:`h-96 min-h-64 max-h-[calc(100svh-18rem)] rounded-md border border-border/60 bg-background`,children:(0,D.jsx)(_,{label:`Transcript for ${e.label}`,followOutput:!1,smooth:!1,contentClassName:`flex flex-col gap-4 px-2.5 py-3`,children:s.map((e,t)=>{let r=t===s.length-1;return(0,D.jsx)(k,{turn:e,isLast:r,isStreaming:r&&c===`streaming`,artifacts:r?u:[],presentation:r?n?.presentation:void 0},e.user?.id??`subagent-turn-${t}`)})})}):(0,D.jsx)(`p`,{className:`rounded-md border border-dashed border-border/70 px-3 py-3 text-[11px] leading-4 text-foreground/45`,children:`This subagent thread is unavailable until the parent session is active.`})]})}function j({agents:e,loadSession:t,parentSessionId:n,tree:a}){let l=(0,E.useMemo)(()=>f(e,a),[e,a]),[u,d]=(0,E.useState)(null),[p,m]=(0,E.useState)({}),h=(0,E.useRef)(new Map),g=l.find(e=>e.id===u)??l[0];(0,E.useEffect)(()=>{u&&l.some(e=>e.id===u)||d(l[0]?.id??null)},[l,u]);let _=(0,E.useCallback)(async(e,r=!1)=>{if(!n)return;let i=`${n}:${e.id}:${e.status}:${e.timestamp}`,a=p[e.id];if(!r&&a?.requestKey===i)return;let o=(h.current.get(e.id)??0)+1;h.current.set(e.id,o),m(t=>({...t,[e.id]:{requestKey:i,status:`loading`,messages:[]}}));try{let r=await t(n,e.id);if(h.current.get(e.id)!==o)return;m(t=>({...t,[e.id]:{requestKey:i,status:`ready`,messages:r.messages,presentation:r.presentation}}))}catch(t){if(h.current.get(e.id)!==o)return;m(n=>({...n,[e.id]:{requestKey:i,status:`error`,messages:[],error:t instanceof Error?t:Error(String(t))}}))}},[t,n,p]);return(0,E.useEffect)(()=>{g&&_(g)},[_,g?.id,g?.status,g?.timestamp]),l.length===0?(0,D.jsx)(`section`,{"aria-label":`Subagents`,className:`flex min-h-36 items-center rounded-md border border-dashed border-border/70 px-4 text-center text-[12px] leading-5 text-foreground/45`,children:`Subagent threads will appear here when Prime delegates work.`}):(0,D.jsxs)(`section`,{"aria-label":`Subagents`,className:`space-y-2 pb-1`,children:[(0,D.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 rounded-sm bg-foreground/5 px-2 py-1.5`,children:[(0,D.jsx)(o,{className:`size-3.5 shrink-0 text-foreground/45`}),(0,D.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-label font-medium text-foreground/70`,children:`Invoked subagents`}),(0,D.jsx)(`span`,{className:`shrink-0 text-[10px] text-foreground/40`,children:l.length})]}),(0,D.jsx)(`div`,{className:`space-y-0.5`,"data-testid":`subagent-thread-list`,children:l.map(e=>{let t=e.id===g?.id;return(0,D.jsxs)(r,{type:`button`,variant:`ghost`,size:`sm`,"aria-pressed":t,className:i(`flex w-full min-w-0 items-center gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-foreground/5 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring`,t&&`bg-foreground/8`),style:{paddingLeft:`${8+Math.max(0,e.depth??0)*12}px`},onClick:()=>d(e.id),children:[(0,D.jsx)(`span`,{className:`shrink-0`,children:c(e.status)}),(0,D.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-xs text-foreground/80`,children:e.label}),(0,D.jsx)(s,{className:`size-3 shrink-0 text-foreground/30`}),(0,D.jsx)(`span`,{className:`shrink-0 text-[10px] capitalize text-foreground/45`,children:e.status})]},e.id)})}),g?(0,D.jsx)(A,{child:g,parentSessionId:n,transcript:p[g.id],onRefresh:()=>void _(g,!0)}):null]})}export{j as SubagentsPanelContent};
@@ -1,334 +0,0 @@
1
- import {
2
- cn
3
- } from "./chunk-DJMHPJBP.js";
4
-
5
- // web/app/dist/server/assets/src-URINr_dJ.js
6
- import "react";
7
- import { jsx } from "react/jsx-runtime";
8
- function Card({ className, size = "default", ...props }) {
9
- return /* @__PURE__ */ jsx("div", {
10
- "data-slot": "card",
11
- "data-size": size,
12
- className: cn("group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl", className),
13
- ...props
14
- });
15
- }
16
- function CardHeader({ className, ...props }) {
17
- return /* @__PURE__ */ jsx("div", {
18
- "data-slot": "card-header",
19
- className: cn("group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3", className),
20
- ...props
21
- });
22
- }
23
- function CardTitle({ className, ...props }) {
24
- return /* @__PURE__ */ jsx("div", {
25
- "data-slot": "card-title",
26
- className: cn("font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm", className),
27
- ...props
28
- });
29
- }
30
- function CardDescription({ className, ...props }) {
31
- return /* @__PURE__ */ jsx("div", {
32
- "data-slot": "card-description",
33
- className: cn("text-sm text-muted-foreground", className),
34
- ...props
35
- });
36
- }
37
- function CardContent({ className, ...props }) {
38
- return /* @__PURE__ */ jsx("div", {
39
- "data-slot": "card-content",
40
- className: cn("px-4 group-data-[size=sm]/card:px-3", className),
41
- ...props
42
- });
43
- }
44
- var CSP_META = `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline'; img-src data:; font-src 'none'; connect-src 'none'; frame-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; media-src data:; navigate-to 'none';">`;
45
- var MAX_TITLE_BYTES = 240;
46
- var FORBIDDEN_ELEMENTS = /<(?:link|iframe|object|embed|base|form|portal|frameset)\b/i;
47
- var META_TAG = /<meta\b[^>]*>/gi;
48
- var REFRESH_META = /\bhttp-equiv\s*=[\s"']*refresh\b/i;
49
- var CSP_META_REFERENCE = /\bcontent-security-policy\b/i;
50
- var EVENT_HANDLER_ATTRIBUTE = /\son[a-z][\w:-]*\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/i;
51
- var SCRIPT_SOURCE_ATTRIBUTE = /<script\b[^>]*\bsrc\s*=/i;
52
- var CSS_IMPORT = /@import\b/i;
53
- var NETWORK_API = /\b(?:fetch|XMLHttpRequest|WebSocket|EventSource|sendBeacon|showModalDialog)\s*\(|\bwindow\s*\.\s*open\s*\(|\b(?:window|globalThis|document|location)\s*\.\s*(?:location|assign|replace|reload|href|pathname|host|hostname|port|protocol|search|hash)\s*=|\b(?:window|globalThis|document|location)\s*\.\s*(?:location\s*\.\s*)?(?:assign|replace|reload)\s*\(/i;
54
- var RESOURCE_ATTRIBUTE = /\b(?:src|href|action|formaction|poster|cite|background|xlink:href)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))/gi;
55
- var UNSAFE_SCHEME = /^(?:javascript|vbscript|file|blob|filesystem|about|data:text\/html|data:application\/javascript):/i;
56
- function byteLength(value) {
57
- return new TextEncoder().encode(value).byteLength;
58
- }
59
- function safeResourceUrl(value) {
60
- const normalized = value.trim();
61
- if (!normalized || UNSAFE_SCHEME.test(normalized)) return false;
62
- if (normalized.startsWith("#")) return true;
63
- return /^(?:data:image\/(?:gif|jpeg|jpg|png|webp|svg\+xml);|data:(?:audio|video)\/)/i.test(normalized);
64
- }
65
- function scanHtmlTags(document) {
66
- const tags = [];
67
- let index = 0;
68
- let rawTextElement;
69
- while (index < document.length) {
70
- if (rawTextElement) {
71
- const closingTag = new RegExp(`<\\/\\s*${rawTextElement}\\b[^>]*>`, "ig");
72
- closingTag.lastIndex = index;
73
- const closingMatch = closingTag.exec(document);
74
- if (!closingMatch) break;
75
- index = closingMatch.index;
76
- rawTextElement = void 0;
77
- }
78
- const start = document.indexOf("<", index);
79
- if (start < 0) break;
80
- if (document.startsWith("<!--", start)) {
81
- const commentEnd = document.indexOf("-->", start + 4);
82
- index = commentEnd < 0 ? document.length : commentEnd + 3;
83
- continue;
84
- }
85
- let end = start + 1;
86
- let quote;
87
- for (; end < document.length; end += 1) {
88
- const character = document[end];
89
- if (quote) {
90
- if (character === quote) quote = void 0;
91
- continue;
92
- }
93
- if (character === '"' || character === "'") {
94
- quote = character;
95
- continue;
96
- }
97
- if (character === ">") break;
98
- }
99
- if (end >= document.length) break;
100
- const raw = document.slice(start, end + 1);
101
- const tagMatch = /^<\s*(\/?)\s*([A-Za-z][\w:-]*)\b/i.exec(raw);
102
- if (!tagMatch) {
103
- index = end + 1;
104
- continue;
105
- }
106
- const closing = Boolean(tagMatch[1]);
107
- const name = tagMatch[2].toLowerCase();
108
- tags.push({
109
- raw,
110
- name,
111
- closing,
112
- start,
113
- end: end + 1
114
- });
115
- if (!closing && (name === "script" || name === "style") && !/\/\s*>$/.test(raw)) rawTextElement = name;
116
- index = end + 1;
117
- }
118
- return tags;
119
- }
120
- function hasHtmlAttribute(document, expectedAttribute) {
121
- let inTag = false;
122
- let quote;
123
- let tagStart = -1;
124
- for (let index = 0; index < document.length; index += 1) {
125
- const character = document[index];
126
- if (!inTag) {
127
- if (character === "<") {
128
- inTag = true;
129
- tagStart = index;
130
- }
131
- continue;
132
- }
133
- if (quote) {
134
- if (character === quote) quote = void 0;
135
- continue;
136
- }
137
- if (character === '"' || character === "'") {
138
- quote = character;
139
- continue;
140
- }
141
- if (character !== ">") continue;
142
- const tag = document.slice(tagStart, index + 1);
143
- inTag = false;
144
- if (/^<\s*\//.test(tag) || /^<\s*[!/?]/.test(tag)) continue;
145
- const tagName = /^<\s*[A-Za-z][\w:-]*/.exec(tag);
146
- if (!tagName) continue;
147
- const attributes = tag.slice(tagName[0].length, -1);
148
- let attributeIndex = 0;
149
- while (attributeIndex < attributes.length) {
150
- while (/\s/.test(attributes[attributeIndex] ?? "")) attributeIndex += 1;
151
- if (attributeIndex >= attributes.length || attributes[attributeIndex] === "/") break;
152
- const nameStart = attributeIndex;
153
- while (!/[\s=/>]/.test(attributes[attributeIndex] ?? "")) attributeIndex += 1;
154
- if (attributes.slice(nameStart, attributeIndex).toLowerCase() === expectedAttribute.toLowerCase()) return true;
155
- while (/\s/.test(attributes[attributeIndex] ?? "")) attributeIndex += 1;
156
- if (attributes[attributeIndex] !== "=") continue;
157
- attributeIndex += 1;
158
- while (/\s/.test(attributes[attributeIndex] ?? "")) attributeIndex += 1;
159
- const valueQuote = attributes[attributeIndex];
160
- if (valueQuote === '"' || valueQuote === "'") {
161
- attributeIndex += 1;
162
- while (attributeIndex < attributes.length && attributes[attributeIndex] !== valueQuote) attributeIndex += 1;
163
- attributeIndex += 1;
164
- continue;
165
- }
166
- while (attributeIndex < attributes.length && !/[\s>]/.test(attributes[attributeIndex] ?? "")) attributeIndex += 1;
167
- }
168
- }
169
- return false;
170
- }
171
- function hasUnsafeResourceAttribute(document) {
172
- RESOURCE_ATTRIBUTE.lastIndex = 0;
173
- for (const match of document.matchAll(RESOURCE_ATTRIBUTE)) if (!safeResourceUrl(match[1] ?? match[2] ?? match[3] ?? "")) return true;
174
- return false;
175
- }
176
- function isCssWhitespace(character) {
177
- return character !== void 0 && /\s/.test(character);
178
- }
179
- function extractCssUrlValues(document) {
180
- const values = [];
181
- const lower = document.toLowerCase();
182
- let searchFrom = 0;
183
- while (searchFrom < document.length) {
184
- const keywordStart = lower.indexOf("url", searchFrom);
185
- if (keywordStart === -1) break;
186
- let cursor = keywordStart + 3;
187
- while (isCssWhitespace(document[cursor])) cursor += 1;
188
- if (document[cursor] !== "(") {
189
- searchFrom = keywordStart + 3;
190
- continue;
191
- }
192
- cursor += 1;
193
- while (isCssWhitespace(document[cursor])) cursor += 1;
194
- const contentStart = cursor;
195
- const quote = document[contentStart];
196
- if (quote === '"' || quote === "'") {
197
- const closingQuote = document.indexOf(quote, contentStart + 1);
198
- if (closingQuote !== -1) {
199
- let afterQuote = closingQuote + 1;
200
- while (isCssWhitespace(document[afterQuote])) afterQuote += 1;
201
- if (document[afterQuote] === ")") {
202
- values.push(document.slice(contentStart, closingQuote + 1));
203
- searchFrom = afterQuote + 1;
204
- continue;
205
- }
206
- }
207
- }
208
- const closingParen = document.indexOf(")", contentStart);
209
- if (closingParen === -1) break;
210
- values.push(document.slice(contentStart, closingParen));
211
- searchFrom = closingParen + 1;
212
- }
213
- return values;
214
- }
215
- function hasUnsafeCssUrl(document) {
216
- for (const rawValue of extractCssUrlValues(document)) {
217
- let value = rawValue;
218
- if (value.length >= 2 && (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))) value = value.slice(1, -1);
219
- else value = value.trim();
220
- if (!safeResourceUrl(value)) return true;
221
- }
222
- return false;
223
- }
224
- function hasForbiddenMeta(document) {
225
- META_TAG.lastIndex = 0;
226
- for (const match of document.matchAll(META_TAG)) {
227
- const tag = match[0] ?? "";
228
- if (REFRESH_META.test(tag)) return true;
229
- if (CSP_META_REFERENCE.test(tag) && tag !== CSP_META) return true;
230
- }
231
- return false;
232
- }
233
- function hasCanonicalCspMetaInHead(document) {
234
- let headDepth = 0;
235
- for (const tag of scanHtmlTags(document)) {
236
- if (tag.name === "head") {
237
- if (tag.closing) headDepth = Math.max(0, headDepth - 1);
238
- else headDepth += 1;
239
- continue;
240
- }
241
- if (headDepth > 0 && tag.name === "meta" && !tag.closing && tag.raw === CSP_META) return true;
242
- }
243
- return false;
244
- }
245
- function normalizeDocument(document) {
246
- const trimmed = document.trim();
247
- if (hasCanonicalCspMetaInHead(trimmed)) return trimmed;
248
- const tags = scanHtmlTags(trimmed);
249
- const htmlTag = tags.find((tag) => tag.name === "html" && !tag.closing);
250
- if (!htmlTag) return `<!doctype html><html><head>${CSP_META}</head><body>${trimmed}</body></html>`;
251
- const headTag = tags.find((tag) => tag.name === "head" && !tag.closing);
252
- if (headTag) return `${trimmed.slice(0, headTag.end)}${CSP_META}${trimmed.slice(headTag.end)}`;
253
- return `${trimmed.slice(0, htmlTag.end)}<head>${CSP_META}</head>${trimmed.slice(htmlTag.end)}`;
254
- }
255
- function validateAndNormalizeOpenUIHtmlArtifact(input) {
256
- if (typeof input !== "object" || input === null) return {
257
- ok: false,
258
- reason: "OpenUI artifact must be an object."
259
- };
260
- const source = input;
261
- if (typeof source.title !== "string" || !source.title.trim()) return {
262
- ok: false,
263
- reason: "OpenUI artifact title is required."
264
- };
265
- if (typeof source.document !== "string" || !source.document.trim()) return {
266
- ok: false,
267
- reason: "OpenUI artifact document is required."
268
- };
269
- const title = source.title.trim();
270
- const document = source.document.trim();
271
- if (byteLength(title) > MAX_TITLE_BYTES) return {
272
- ok: false,
273
- reason: "OpenUI artifact title is too large."
274
- };
275
- if (byteLength(document) > 1048576) return {
276
- ok: false,
277
- reason: "OpenUI artifact exceeds the 1 MiB limit.",
278
- status: 413
279
- };
280
- if (FORBIDDEN_ELEMENTS.test(document)) return {
281
- ok: false,
282
- reason: "External HTML resources and embedded frames are not allowed."
283
- };
284
- if (hasForbiddenMeta(document)) return {
285
- ok: false,
286
- reason: "Custom refresh and CSP metadata are not allowed."
287
- };
288
- if (EVENT_HANDLER_ATTRIBUTE.test(document)) return {
289
- ok: false,
290
- reason: "Inline event-handler attributes are not allowed."
291
- };
292
- if (SCRIPT_SOURCE_ATTRIBUTE.test(document)) return {
293
- ok: false,
294
- reason: "External scripts are not allowed."
295
- };
296
- if (CSS_IMPORT.test(document) || hasUnsafeCssUrl(document)) return {
297
- ok: false,
298
- reason: "External styles and CSS resources are not allowed."
299
- };
300
- if (hasUnsafeResourceAttribute(document)) return {
301
- ok: false,
302
- reason: "External or unsafe resource URLs are not allowed."
303
- };
304
- if (NETWORK_API.test(document)) return {
305
- ok: false,
306
- reason: "Network access and pop-up APIs are not allowed."
307
- };
308
- if (hasHtmlAttribute(document, "download") || hasHtmlAttribute(document, "target")) return {
309
- ok: false,
310
- reason: "Downloads and new-window navigation are not allowed."
311
- };
312
- const normalizedDocument = normalizeDocument(document);
313
- if (byteLength(normalizedDocument) > 1048576) return {
314
- ok: false,
315
- reason: "Normalized OpenUI artifact exceeds the 1 MiB limit.",
316
- status: 413
317
- };
318
- return {
319
- ok: true,
320
- value: {
321
- title,
322
- document: normalizedDocument
323
- }
324
- };
325
- }
326
-
327
- export {
328
- Card,
329
- CardHeader,
330
- CardTitle,
331
- CardDescription,
332
- CardContent,
333
- validateAndNormalizeOpenUIHtmlArtifact
334
- };