agent-relay-server 0.123.0 → 0.123.1
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.
- package/docs/openapi.json +1 -1
- package/package.json +2 -2
- package/public/assets/MessageBubble-NCggGKTA.js +2 -0
- package/public/assets/{MessageBubble-BTeFExjj.js.map → MessageBubble-NCggGKTA.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-jU1DXg7w.js → PlanGraphPanel-CSdszmGk.js} +2 -2
- package/public/assets/{PlanGraphPanel-jU1DXg7w.js.map → PlanGraphPanel-CSdszmGk.js.map} +1 -1
- package/public/assets/{activity-DUig2iYW.js → activity-Cyp2nolX.js} +2 -2
- package/public/assets/{activity-DUig2iYW.js.map → activity-Cyp2nolX.js.map} +1 -1
- package/public/assets/{agent-profiles-D-oFmb6S.js → agent-profiles-D5Izg0Vn.js} +2 -2
- package/public/assets/{agent-profiles-D-oFmb6S.js.map → agent-profiles-D5Izg0Vn.js.map} +1 -1
- package/public/assets/{agent-type-icon-Dan2l3Tm.js → agent-type-icon-BxUopALO.js} +2 -2
- package/public/assets/{agent-type-icon-Dan2l3Tm.js.map → agent-type-icon-BxUopALO.js.map} +1 -1
- package/public/assets/agents-DIOxuJ6M.js +2 -0
- package/public/assets/{agents-BkC6mcTh.js.map → agents-DIOxuJ6M.js.map} +1 -1
- package/public/assets/{analytics-C3Dlmqe9.js → analytics-DqAuUAwX.js} +3 -3
- package/public/assets/{analytics-C3Dlmqe9.js.map → analytics-DqAuUAwX.js.map} +1 -1
- package/public/assets/{automation-AeMZ70WQ.js → automation-Bn6mOLAR.js} +2 -2
- package/public/assets/{automation-AeMZ70WQ.js.map → automation-Bn6mOLAR.js.map} +1 -1
- package/public/assets/{badge-DCIT3Irj.js → badge-XEru6wto.js} +2 -2
- package/public/assets/{badge-DCIT3Irj.js.map → badge-XEru6wto.js.map} +1 -1
- package/public/assets/branch-state-badge-Mf0Ow77K.js +2 -0
- package/public/assets/{branch-state-badge-CNW10MTC.js.map → branch-state-badge-Mf0Ow77K.js.map} +1 -1
- package/public/assets/{button-CzdTkRIf.js → button-C3CQSr4p.js} +2 -2
- package/public/assets/{button-CzdTkRIf.js.map → button-C3CQSr4p.js.map} +1 -1
- package/public/assets/card-C5XTIPvq.js +2 -0
- package/public/assets/{card-C3BGuVC6.js.map → card-C5XTIPvq.js.map} +1 -1
- package/public/assets/{channels-Bc_mEd56.js → channels-DVRkVeky.js} +2 -2
- package/public/assets/{channels-Bc_mEd56.js.map → channels-DVRkVeky.js.map} +1 -1
- package/public/assets/chat-eUaPz399.js +2 -0
- package/public/assets/{chat-BCNCuTgw.js.map → chat-eUaPz399.js.map} +1 -1
- package/public/assets/{connectors-h0d5Mc6e.js → connectors-Cqubkw9C.js} +2 -2
- package/public/assets/{connectors-h0d5Mc6e.js.map → connectors-Cqubkw9C.js.map} +1 -1
- package/public/assets/copy-button-Bil2CjzT.js +2 -0
- package/public/assets/{copy-button-B3o1jpLu.js.map → copy-button-Bil2CjzT.js.map} +1 -1
- package/public/assets/{dist-OUPTEP6q.js → dist-4VwhnLtj.js} +2 -2
- package/public/assets/{dist-OUPTEP6q.js.map → dist-4VwhnLtj.js.map} +1 -1
- package/public/assets/{dist-BIjlN-xB.js → dist-B8tD9ZcR.js} +2 -2
- package/public/assets/{dist-BIjlN-xB.js.map → dist-B8tD9ZcR.js.map} +1 -1
- package/public/assets/{dist-BInckSJC.js → dist-BJaV2BD4.js} +2 -2
- package/public/assets/{dist-BInckSJC.js.map → dist-BJaV2BD4.js.map} +1 -1
- package/public/assets/{dist-B-T7lg0a.js → dist-C5z05Vkz.js} +2 -2
- package/public/assets/{dist-B-T7lg0a.js.map → dist-C5z05Vkz.js.map} +1 -1
- package/public/assets/dist-CFtFIhu3.js +2 -0
- package/public/assets/{dist-DT-OV6sQ.js.map → dist-CFtFIhu3.js.map} +1 -1
- package/public/assets/{dist-C7aTlosb.js → dist-CGaHpxnN.js} +2 -2
- package/public/assets/{dist-C7aTlosb.js.map → dist-CGaHpxnN.js.map} +1 -1
- package/public/assets/dist-CjyfQThq.js +2 -0
- package/public/assets/{dist-DGfp5dLz.js.map → dist-CjyfQThq.js.map} +1 -1
- package/public/assets/dist-CrUl2aQp.js +2 -0
- package/public/assets/{dist-B6woQ9Tb.js.map → dist-CrUl2aQp.js.map} +1 -1
- package/public/assets/{dist-B3e4B9pg.js → dist-DKmTXfpP.js} +2 -2
- package/public/assets/{dist-B3e4B9pg.js.map → dist-DKmTXfpP.js.map} +1 -1
- package/public/assets/{dist-B9G83DXv.js → dist-V3wu3BHw.js} +2 -2
- package/public/assets/{dist-B9G83DXv.js.map → dist-V3wu3BHw.js.map} +1 -1
- package/public/assets/{dist-BlzVGRhh.js → dist-r8wyUTkK.js} +2 -2
- package/public/assets/{dist-BlzVGRhh.js.map → dist-r8wyUTkK.js.map} +1 -1
- package/public/assets/{es2015-CnKXYKpf.js → es2015-5DTJe35n.js} +2 -2
- package/public/assets/{es2015-CnKXYKpf.js.map → es2015-5DTJe35n.js.map} +1 -1
- package/public/assets/formatted-body-CvrQ2D1J.js +3 -0
- package/public/assets/{formatted-body-CVr3Iev9.js.map → formatted-body-CvrQ2D1J.js.map} +1 -1
- package/public/assets/{formatted-body-impl-Cq5SRGpm.js → formatted-body-impl-BJ7jdbpR.js} +2 -2
- package/public/assets/{formatted-body-impl-Cq5SRGpm.js.map → formatted-body-impl-BJ7jdbpR.js.map} +1 -1
- package/public/assets/index-DnUo0Zqg.js +25 -0
- package/public/assets/index-DnUo0Zqg.js.map +1 -0
- package/public/assets/{input-B6Q0NWCS.js → input-CXMbJ848.js} +2 -2
- package/public/assets/{input-B6Q0NWCS.js.map → input-CXMbJ848.js.map} +1 -1
- package/public/assets/{insights-C8lIBXg3.js → insights-CQGH5LhD.js} +2 -2
- package/public/assets/{insights-C8lIBXg3.js.map → insights-CQGH5LhD.js.map} +1 -1
- package/public/assets/{integrations-7OFsJtY7.js → integrations-9G5TJnnU.js} +2 -2
- package/public/assets/{integrations-7OFsJtY7.js.map → integrations-9G5TJnnU.js.map} +1 -1
- package/public/assets/{lib-BHsWPMKB.js → lib-BcUW1l-W.js} +2 -2
- package/public/assets/{lib-BHsWPMKB.js.map → lib-BcUW1l-W.js.map} +1 -1
- package/public/assets/lucide-react-CoU_Xts2.js +10 -0
- package/public/assets/{lucide-react-DuhlF2Sj.js.map → lucide-react-CoU_Xts2.js.map} +1 -1
- package/public/assets/maintenance-7c7UvpAt.js +2 -0
- package/public/assets/{maintenance-HDpg20OY.js.map → maintenance-7c7UvpAt.js.map} +1 -1
- package/public/assets/{managed-agents-muCIMxng.js → managed-agents-yh4HPO5a.js} +4 -4
- package/public/assets/{managed-agents-muCIMxng.js.map → managed-agents-yh4HPO5a.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-Cx7pCfA6.js → markdown-preview-impl-BuOn5-Uc.js} +2 -2
- package/public/assets/{markdown-preview-impl-Cx7pCfA6.js.map → markdown-preview-impl-BuOn5-Uc.js.map} +1 -1
- package/public/assets/memory-Qv0JN8CE.js +2 -0
- package/public/assets/{memory-CTO1FfJ-.js.map → memory-Qv0JN8CE.js.map} +1 -1
- package/public/assets/messages-CgjHJmc2.js +2 -0
- package/public/assets/{messages-RWSXG2UM.js.map → messages-CgjHJmc2.js.map} +1 -1
- package/public/assets/{orchestrators-5aiYw3yx.js → orchestrators-CgL4CFzb.js} +2 -2
- package/public/assets/{orchestrators-5aiYw3yx.js.map → orchestrators-CgL4CFzb.js.map} +1 -1
- package/public/assets/{overview-Du6XLt5l.js → overview-Bri04eYE.js} +2 -2
- package/public/assets/{overview-Du6XLt5l.js.map → overview-Bri04eYE.js.map} +1 -1
- package/public/assets/{pairs-BDRnlEta.js → pairs-C78LwUH2.js} +2 -2
- package/public/assets/{pairs-BDRnlEta.js.map → pairs-C78LwUH2.js.map} +1 -1
- package/public/assets/{projects-DwsWE9es.js → projects-CquHTMo1.js} +2 -2
- package/public/assets/{projects-DwsWE9es.js.map → projects-CquHTMo1.js.map} +1 -1
- package/public/assets/prompt-settings-DDEkMqPZ.js +2 -0
- package/public/assets/{prompt-settings-CaJX_LbA.js.map → prompt-settings-DDEkMqPZ.js.map} +1 -1
- package/public/assets/{react-dom-DWBmcawP.js → react-dom-BQICbUuF.js} +2 -2
- package/public/assets/{react-dom-DWBmcawP.js.map → react-dom-BQICbUuF.js.map} +1 -1
- package/public/assets/registry-5KhP5FE5.js +2 -0
- package/public/assets/registry-5KhP5FE5.js.map +1 -0
- package/public/assets/{security-BpVrdYhJ.js → security-wvnRKFvm.js} +2 -2
- package/public/assets/{security-BpVrdYhJ.js.map → security-wvnRKFvm.js.map} +1 -1
- package/public/assets/{select-DallbU93.js → select-BIfbVmLf.js} +2 -2
- package/public/assets/{select-DallbU93.js.map → select-BIfbVmLf.js.map} +1 -1
- package/public/assets/settings-B6Ntahx7.js +6 -0
- package/public/assets/{settings-BUQirdyI.js.map → settings-B6Ntahx7.js.map} +1 -1
- package/public/assets/{store-DMZSTozC.js → store-zFLzd0Jd.js} +5 -5
- package/public/assets/{store-DMZSTozC.js.map → store-zFLzd0Jd.js.map} +1 -1
- package/public/assets/{task-chip-DXfvXBDx.js → task-chip-BHM-e3I8.js} +2 -2
- package/public/assets/{task-chip-DXfvXBDx.js.map → task-chip-BHM-e3I8.js.map} +1 -1
- package/public/assets/{tasks-k8mQDfKy.js → tasks-CUglafo5.js} +2 -2
- package/public/assets/{tasks-k8mQDfKy.js.map → tasks-CUglafo5.js.map} +1 -1
- package/public/assets/{teams-DI-Lhhbl.js → teams-EE8RHhHM.js} +2 -2
- package/public/assets/{teams-DI-Lhhbl.js.map → teams-EE8RHhHM.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-BL853Fpi.js → terminal-viewer-impl-DBRkdyag.js} +3 -3
- package/public/assets/{terminal-viewer-impl-BL853Fpi.js.map → terminal-viewer-impl-DBRkdyag.js.map} +1 -1
- package/public/assets/{use-keyboard-viewport-CP109w9y.js → use-keyboard-viewport-CAa7IQTm.js} +2 -2
- package/public/assets/{use-keyboard-viewport-CP109w9y.js.map → use-keyboard-viewport-CAa7IQTm.js.map} +1 -1
- package/public/assets/user-avatar-kYPfLgXp.js +2 -0
- package/public/assets/{user-avatar-D9xyGi3u.js.map → user-avatar-kYPfLgXp.js.map} +1 -1
- package/public/assets/{work-queue-DrLIdvxB.js → work-queue-BFQVVL4T.js} +2 -2
- package/public/assets/{work-queue-DrLIdvxB.js.map → work-queue-BFQVVL4T.js.map} +1 -1
- package/public/assets/workspaces-CR6f7G0R.js +3 -0
- package/public/assets/{workspaces-CnNL6T8Q.js.map → workspaces-CR6f7G0R.js.map} +1 -1
- package/public/index.html +23 -23
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/src/launch-assembly.ts +34 -1
- package/runner/src/provisioning.ts +15 -0
- package/public/assets/MessageBubble-BTeFExjj.js +0 -2
- package/public/assets/agents-BkC6mcTh.js +0 -2
- package/public/assets/branch-state-badge-CNW10MTC.js +0 -2
- package/public/assets/card-C3BGuVC6.js +0 -2
- package/public/assets/chat-BCNCuTgw.js +0 -2
- package/public/assets/copy-button-B3o1jpLu.js +0 -2
- package/public/assets/dist-B6woQ9Tb.js +0 -2
- package/public/assets/dist-DGfp5dLz.js +0 -2
- package/public/assets/dist-DT-OV6sQ.js +0 -2
- package/public/assets/formatted-body-CVr3Iev9.js +0 -3
- package/public/assets/index--9UMzCFf.js +0 -25
- package/public/assets/index--9UMzCFf.js.map +0 -1
- package/public/assets/lucide-react-DuhlF2Sj.js +0 -10
- package/public/assets/maintenance-HDpg20OY.js +0 -2
- package/public/assets/memory-CTO1FfJ-.js +0 -2
- package/public/assets/messages-RWSXG2UM.js +0 -2
- package/public/assets/prompt-settings-CaJX_LbA.js +0 -2
- package/public/assets/registry-C-uIL0Nl.js +0 -2
- package/public/assets/registry-C-uIL0Nl.js.map +0 -1
- package/public/assets/settings-BUQirdyI.js +0 -6
- package/public/assets/user-avatar-D9xyGi3u.js +0 -2
- package/public/assets/workspaces-CnNL6T8Q.js +0 -3
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{R as t,W as n,er as r,gr as i,h as a,o,rr as s,tr as c,un as l,yn as u}from"./lucide-react-CoU_Xts2.js";import{p as d,t as f}from"./store-zFLzd0Jd.js";import{K as p,h as m}from"./display-GFbGUG0O.js";import{t as h}from"./badge-XEru6wto.js";import{t as g}from"./button-C3CQSr4p.js";import{G as _}from"./index-DnUo0Zqg.js";var v=e(i(),1),y=s(),b={succeeded:`bg-emerald-500/10 text-emerald-400 border-emerald-500/30`,running:`bg-blue-500/10 text-blue-400 border-blue-500/30`,failed:`bg-red-500/10 text-red-400 border-red-500/30`,idle:`bg-zinc-500/10 text-zinc-400 border-zinc-500/30`,disabled:`bg-zinc-500/10 text-zinc-500 border-zinc-500/20`};function x(){let e=d(),n=f(e=>e.maintenanceJobs),r=f(e=>e.fetchMaintenanceJobs),i=f(e=>e.runMaintenanceJob),a=(0,v.useMemo)(()=>({failed:n.filter(e=>e.lastStatus===`failed`).length,running:n.filter(e=>e.running||e.lastStatus===`running`).length,dueSoon:n.filter(t=>t.nextRunAt&&t.nextRunAt<=e+300*1e3).length}),[n,e]);return(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-2`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-2 min-w-0`,children:[(0,y.jsx)(o,{className:`h-5 w-5 text-muted-foreground`}),(0,y.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Maintenance`}),(0,y.jsx)(h,{variant:`secondary`,children:n.length}),a.running>0&&(0,y.jsxs)(h,{className:`border border-blue-500/30 bg-blue-500/10 text-blue-400`,children:[a.running,` running`]}),a.failed>0&&(0,y.jsxs)(h,{variant:`destructive`,children:[a.failed,` failing`]}),a.dueSoon>0&&(0,y.jsxs)(h,{className:`border border-yellow-500/30 bg-yellow-500/10 text-yellow-400`,children:[a.dueSoon,` due soon`]})]}),(0,y.jsxs)(g,{size:`sm`,variant:`outline`,onClick:()=>void r(),children:[(0,y.jsx)(t,{className:`h-3.5 w-3.5`}),` Refresh`]})]}),(0,y.jsx)(_,{className:`h-[calc(100dvh-10rem)]`,children:n.length===0?(0,y.jsx)(`div`,{className:`rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground`,children:`No maintenance jobs registered`}):(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`div`,{className:`hidden overflow-x-auto rounded-md border border-border md:block`,children:(0,y.jsxs)(`table`,{className:`w-full min-w-[980px] text-sm`,children:[(0,y.jsx)(`thead`,{className:`bg-muted/40 text-xs text-muted-foreground`,children:(0,y.jsxs)(`tr`,{children:[(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Job`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Status`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Last run`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Next run`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Duration`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-left font-medium`,children:`Result`}),(0,y.jsx)(`th`,{className:`px-3 py-2 text-right font-medium`,children:`Action`})]})}),(0,y.jsx)(`tbody`,{children:n.map(t=>(0,y.jsx)(T,{job:t,now:e,onRun:()=>void i(t.id)},t.id))})]})}),(0,y.jsx)(`div`,{className:`space-y-3 md:hidden`,children:n.map(t=>(0,y.jsx)(w,{job:t,now:e,onRun:()=>void i(t.id)},t.id))})]})})]})}function S(e){return e.running?`running`:e.enabled?e.lastStatus:`disabled`}function C({status:e}){return(0,y.jsxs)(h,{variant:`outline`,className:c(`border`,b[e]||b.idle),children:[E(e),e]})}function w({job:e,now:t,onRun:r}){let i=S(e);return(0,y.jsxs)(`div`,{className:`rounded-md border border-border p-3`,children:[(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsx)(`div`,{className:`font-medium`,children:e.title}),(0,y.jsx)(`div`,{className:`mt-0.5 text-xs text-muted-foreground`,children:e.description}),(0,y.jsx)(`div`,{className:`mt-1 font-mono text-[11px] text-muted-foreground/80`,children:e.id})]}),(0,y.jsx)(C,{status:i})]}),e.consecutiveFailures>0&&(0,y.jsxs)(`div`,{className:`mt-2 text-xs text-red-400`,children:[e.consecutiveFailures,` failure`,e.consecutiveFailures===1?``:`s`]}),(0,y.jsxs)(`dl`,{className:`mt-3 grid grid-cols-3 gap-2 text-xs`,children:[(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`dt`,{className:`text-muted-foreground`,children:`Last run`}),(0,y.jsx)(`dd`,{children:e.lastRunAt?(0,y.jsx)(`span`,{title:m(e.lastRunAt),children:p(t,e.lastRunAt)}):`never`})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`dt`,{className:`text-muted-foreground`,children:`Next run`}),(0,y.jsx)(`dd`,{children:e.nextRunAt?(0,y.jsx)(`span`,{title:m(e.nextRunAt),children:O(t,e.nextRunAt)}):`-`})]}),(0,y.jsxs)(`div`,{children:[(0,y.jsx)(`dt`,{className:`text-muted-foreground`,children:`Duration`}),(0,y.jsx)(`dd`,{children:e.lastDurationMs===void 0?`-`:`${e.lastDurationMs}ms`})]})]}),(0,y.jsxs)(`div`,{className:`mt-3`,children:[(0,y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Result`}),e.lastError?(0,y.jsx)(`div`,{className:`mt-0.5 text-xs text-red-400 line-clamp-3`,children:e.lastError}):(0,y.jsx)(`div`,{className:`mt-0.5 font-mono text-[11px] text-muted-foreground line-clamp-3`,children:D(e)})]}),(0,y.jsx)(`div`,{className:`mt-3 flex justify-end`,children:(0,y.jsxs)(g,{size:`sm`,variant:`outline`,disabled:!e.enabled||e.running,onClick:r,children:[(0,y.jsx)(n,{className:`h-3.5 w-3.5`}),` Run`]})})]})}function T({job:e,now:t,onRun:r}){let i=S(e);return(0,y.jsxs)(`tr`,{className:`border-t border-border align-top`,children:[(0,y.jsxs)(`td`,{className:`px-3 py-3`,children:[(0,y.jsx)(`div`,{className:`font-medium`,children:e.title}),(0,y.jsx)(`div`,{className:`mt-0.5 max-w-md text-xs text-muted-foreground`,children:e.description}),(0,y.jsx)(`div`,{className:`mt-1 font-mono text-[11px] text-muted-foreground/80`,children:e.id})]}),(0,y.jsxs)(`td`,{className:`px-3 py-3`,children:[(0,y.jsx)(C,{status:i}),e.consecutiveFailures>0&&(0,y.jsxs)(`div`,{className:`mt-1 text-xs text-red-400`,children:[e.consecutiveFailures,` failure`,e.consecutiveFailures===1?``:`s`]})]}),(0,y.jsx)(`td`,{className:`px-3 py-3 text-xs text-muted-foreground`,children:e.lastRunAt?(0,y.jsx)(`span`,{title:m(e.lastRunAt),children:p(t,e.lastRunAt)}):`never`}),(0,y.jsx)(`td`,{className:`px-3 py-3 text-xs text-muted-foreground`,children:e.nextRunAt?(0,y.jsx)(`span`,{title:m(e.nextRunAt),children:O(t,e.nextRunAt)}):`-`}),(0,y.jsx)(`td`,{className:`px-3 py-3 text-xs text-muted-foreground`,children:e.lastDurationMs===void 0?`-`:`${e.lastDurationMs}ms`}),(0,y.jsx)(`td`,{className:`px-3 py-3`,children:e.lastError?(0,y.jsx)(`div`,{className:`max-w-sm text-xs text-red-400 line-clamp-3`,children:e.lastError}):(0,y.jsx)(`div`,{className:`max-w-sm font-mono text-[11px] text-muted-foreground line-clamp-3`,children:D(e)})}),(0,y.jsx)(`td`,{className:`px-3 py-3 text-right`,children:(0,y.jsxs)(g,{size:`sm`,variant:`outline`,disabled:!e.enabled||e.running,onClick:r,children:[(0,y.jsx)(n,{className:`h-3.5 w-3.5`}),` Run`]})})]})}function E(e){return e===`succeeded`?(0,y.jsx)(u,{className:`mr-1 h-3 w-3`}):e===`running`?(0,y.jsx)(r,{className:`mr-1 h-3 w-3`}):e===`failed`?(0,y.jsx)(a,{className:`mr-1 h-3 w-3`}):(0,y.jsx)(l,{className:`mr-1 h-3 w-3`})}function D(e){if(!e.lastResult)return`-`;let t=Object.entries(e.lastResult).filter(([,e])=>Array.isArray(e)?e.length>0:e!=null&&e!==0).map(([e,t])=>`${e}: ${Array.isArray(t)?t.length:String(t)}`);return t.length?t.join(`, `):`no changes`}function O(e,t){if(t<=e)return`due now`;let n=Math.max(0,(t-e)/1e3);return n<60?`in ${Math.ceil(n)}s`:n<3600?`in ${Math.ceil(n/60)}m`:n<86400?`in ${Math.ceil(n/3600)}h`:`in ${Math.ceil(n/86400)}d`}export{x as MaintenanceView};
|
|
2
|
+
//# sourceMappingURL=maintenance-7c7UvpAt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance-HDpg20OY.js","names":[],"sources":["../../dashboard/src/components/views/maintenance.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { Activity, AlertTriangle, CheckCircle2, Clock3, Play, RefreshCw, Wrench } from 'lucide-react'\nimport { useRelayStore, useNow } from '@/store'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { cn } from '@/lib/utils'\nimport { fmtTime, timeAgo } from '@/lib/display'\nimport type { MaintenanceJob } from '@/types'\n\nconst STATUS_CLASS: Record<string, string> = {\n succeeded: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30',\n running: 'bg-blue-500/10 text-blue-400 border-blue-500/30',\n failed: 'bg-red-500/10 text-red-400 border-red-500/30',\n idle: 'bg-zinc-500/10 text-zinc-400 border-zinc-500/30',\n disabled: 'bg-zinc-500/10 text-zinc-500 border-zinc-500/20',\n}\n\nexport function MaintenanceView() {\n const now = useNow()\n const jobs = useRelayStore((s) => s.maintenanceJobs)\n const fetchMaintenanceJobs = useRelayStore((s) => s.fetchMaintenanceJobs)\n const runMaintenanceJob = useRelayStore((s) => s.runMaintenanceJob)\n\n const summary = useMemo(() => {\n const failed = jobs.filter((job) => job.lastStatus === 'failed').length\n const running = jobs.filter((job) => job.running || job.lastStatus === 'running').length\n const dueSoon = jobs.filter((job) => job.nextRunAt && job.nextRunAt <= now + 5 * 60 * 1000).length\n return { failed, running, dueSoon }\n }, [jobs, now])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between flex-wrap gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <Wrench className=\"h-5 w-5 text-muted-foreground\" />\n <h2 className=\"text-lg font-semibold\">Maintenance</h2>\n <Badge variant=\"secondary\">{jobs.length}</Badge>\n {summary.running > 0 && <Badge className=\"border border-blue-500/30 bg-blue-500/10 text-blue-400\">{summary.running} running</Badge>}\n {summary.failed > 0 && <Badge variant=\"destructive\">{summary.failed} failing</Badge>}\n {summary.dueSoon > 0 && <Badge className=\"border border-yellow-500/30 bg-yellow-500/10 text-yellow-400\">{summary.dueSoon} due soon</Badge>}\n </div>\n <Button size=\"sm\" variant=\"outline\" onClick={() => void fetchMaintenanceJobs()}>\n <RefreshCw className=\"h-3.5 w-3.5\" /> Refresh\n </Button>\n </div>\n\n <ScrollArea className=\"h-[calc(100dvh-10rem)]\">\n {jobs.length === 0 ? (\n <div className=\"rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground\">No maintenance jobs registered</div>\n ) : (\n <>\n {/* Desktop / wide: full table */}\n <div className=\"hidden overflow-x-auto rounded-md border border-border md:block\">\n <table className=\"w-full min-w-[980px] text-sm\">\n <thead className=\"bg-muted/40 text-xs text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">Job</th>\n <th className=\"px-3 py-2 text-left font-medium\">Status</th>\n <th className=\"px-3 py-2 text-left font-medium\">Last run</th>\n <th className=\"px-3 py-2 text-left font-medium\">Next run</th>\n <th className=\"px-3 py-2 text-left font-medium\">Duration</th>\n <th className=\"px-3 py-2 text-left font-medium\">Result</th>\n <th className=\"px-3 py-2 text-right font-medium\">Action</th>\n </tr>\n </thead>\n <tbody>\n {jobs.map((job) => (\n <MaintenanceRow\n key={job.id}\n job={job}\n now={now}\n onRun={() => void runMaintenanceJob(job.id)}\n />\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Mobile / narrow: stacked cards so every field is visible without horizontal scroll */}\n <div className=\"space-y-3 md:hidden\">\n {jobs.map((job) => (\n <MaintenanceCard\n key={job.id}\n job={job}\n now={now}\n onRun={() => void runMaintenanceJob(job.id)}\n />\n ))}\n </div>\n </>\n )}\n </ScrollArea>\n </div>\n )\n}\n\nfunction jobStatus(job: MaintenanceJob): string {\n return job.running ? 'running' : job.enabled ? job.lastStatus : 'disabled'\n}\n\nfunction StatusBadge({ status }: { status: string }) {\n return (\n <Badge variant=\"outline\" className={cn('border', STATUS_CLASS[status] || STATUS_CLASS.idle)}>\n {statusIcon(status)}\n {status}\n </Badge>\n )\n}\n\nfunction MaintenanceCard({ job, now, onRun }: { job: MaintenanceJob; now: number; onRun: () => void }) {\n const status = jobStatus(job)\n return (\n <div className=\"rounded-md border border-border p-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"font-medium\">{job.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{job.description}</div>\n <div className=\"mt-1 font-mono text-[11px] text-muted-foreground/80\">{job.id}</div>\n </div>\n <StatusBadge status={status} />\n </div>\n\n {job.consecutiveFailures > 0 && (\n <div className=\"mt-2 text-xs text-red-400\">{job.consecutiveFailures} failure{job.consecutiveFailures === 1 ? '' : 's'}</div>\n )}\n\n <dl className=\"mt-3 grid grid-cols-3 gap-2 text-xs\">\n <div>\n <dt className=\"text-muted-foreground\">Last run</dt>\n <dd>{job.lastRunAt ? <span title={fmtTime(job.lastRunAt)}>{timeAgo(now, job.lastRunAt)}</span> : 'never'}</dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">Next run</dt>\n <dd>{job.nextRunAt ? <span title={fmtTime(job.nextRunAt)}>{nextRunText(now, job.nextRunAt)}</span> : '-'}</dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">Duration</dt>\n <dd>{job.lastDurationMs !== undefined ? `${job.lastDurationMs}ms` : '-'}</dd>\n </div>\n </dl>\n\n <div className=\"mt-3\">\n <div className=\"text-xs text-muted-foreground\">Result</div>\n {job.lastError ? (\n <div className=\"mt-0.5 text-xs text-red-400 line-clamp-3\">{job.lastError}</div>\n ) : (\n <div className=\"mt-0.5 font-mono text-[11px] text-muted-foreground line-clamp-3\">{resultSummary(job)}</div>\n )}\n </div>\n\n <div className=\"mt-3 flex justify-end\">\n <Button size=\"sm\" variant=\"outline\" disabled={!job.enabled || job.running} onClick={onRun}>\n <Play className=\"h-3.5 w-3.5\" /> Run\n </Button>\n </div>\n </div>\n )\n}\n\nfunction MaintenanceRow({ job, now, onRun }: { job: MaintenanceJob; now: number; onRun: () => void }) {\n const status = jobStatus(job)\n return (\n <tr className=\"border-t border-border align-top\">\n <td className=\"px-3 py-3\">\n <div className=\"font-medium\">{job.title}</div>\n <div className=\"mt-0.5 max-w-md text-xs text-muted-foreground\">{job.description}</div>\n <div className=\"mt-1 font-mono text-[11px] text-muted-foreground/80\">{job.id}</div>\n </td>\n <td className=\"px-3 py-3\">\n <StatusBadge status={status} />\n {job.consecutiveFailures > 0 && (\n <div className=\"mt-1 text-xs text-red-400\">{job.consecutiveFailures} failure{job.consecutiveFailures === 1 ? '' : 's'}</div>\n )}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.lastRunAt ? (\n <span title={fmtTime(job.lastRunAt)}>{timeAgo(now, job.lastRunAt)}</span>\n ) : 'never'}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.nextRunAt ? (\n <span title={fmtTime(job.nextRunAt)}>{nextRunText(now, job.nextRunAt)}</span>\n ) : '-'}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.lastDurationMs !== undefined ? `${job.lastDurationMs}ms` : '-'}\n </td>\n <td className=\"px-3 py-3\">\n {job.lastError ? (\n <div className=\"max-w-sm text-xs text-red-400 line-clamp-3\">{job.lastError}</div>\n ) : (\n <div className=\"max-w-sm font-mono text-[11px] text-muted-foreground line-clamp-3\">{resultSummary(job)}</div>\n )}\n </td>\n <td className=\"px-3 py-3 text-right\">\n <Button size=\"sm\" variant=\"outline\" disabled={!job.enabled || job.running} onClick={onRun}>\n <Play className=\"h-3.5 w-3.5\" /> Run\n </Button>\n </td>\n </tr>\n )\n}\n\nfunction statusIcon(status: string) {\n if (status === 'succeeded') return <CheckCircle2 className=\"mr-1 h-3 w-3\" />\n if (status === 'running') return <Activity className=\"mr-1 h-3 w-3\" />\n if (status === 'failed') return <AlertTriangle className=\"mr-1 h-3 w-3\" />\n return <Clock3 className=\"mr-1 h-3 w-3\" />\n}\n\nfunction resultSummary(job: MaintenanceJob): string {\n if (!job.lastResult) return '-'\n const entries = Object.entries(job.lastResult)\n .filter(([, value]) => Array.isArray(value) ? value.length > 0 : value !== undefined && value !== null && value !== 0)\n .map(([key, value]) => `${key}: ${Array.isArray(value) ? value.length : String(value)}`)\n return entries.length ? entries.join(', ') : 'no changes'\n}\n\nfunction nextRunText(now: number, nextRunAt: number): string {\n if (nextRunAt <= now) return 'due now'\n const diff = Math.max(0, (nextRunAt - now) / 1000)\n if (diff < 60) return `in ${Math.ceil(diff)}s`\n if (diff < 3600) return `in ${Math.ceil(diff / 60)}m`\n if (diff < 86400) return `in ${Math.ceil(diff / 3600)}h`\n return `in ${Math.ceil(diff / 86400)}d`\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"maintenance-7c7UvpAt.js","names":[],"sources":["../../dashboard/src/components/views/maintenance.tsx"],"sourcesContent":["import { useMemo } from 'react'\nimport { Activity, AlertTriangle, CheckCircle2, Clock3, Play, RefreshCw, Wrench } from 'lucide-react'\nimport { useRelayStore, useNow } from '@/store'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { cn } from '@/lib/utils'\nimport { fmtTime, timeAgo } from '@/lib/display'\nimport type { MaintenanceJob } from '@/types'\n\nconst STATUS_CLASS: Record<string, string> = {\n succeeded: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/30',\n running: 'bg-blue-500/10 text-blue-400 border-blue-500/30',\n failed: 'bg-red-500/10 text-red-400 border-red-500/30',\n idle: 'bg-zinc-500/10 text-zinc-400 border-zinc-500/30',\n disabled: 'bg-zinc-500/10 text-zinc-500 border-zinc-500/20',\n}\n\nexport function MaintenanceView() {\n const now = useNow()\n const jobs = useRelayStore((s) => s.maintenanceJobs)\n const fetchMaintenanceJobs = useRelayStore((s) => s.fetchMaintenanceJobs)\n const runMaintenanceJob = useRelayStore((s) => s.runMaintenanceJob)\n\n const summary = useMemo(() => {\n const failed = jobs.filter((job) => job.lastStatus === 'failed').length\n const running = jobs.filter((job) => job.running || job.lastStatus === 'running').length\n const dueSoon = jobs.filter((job) => job.nextRunAt && job.nextRunAt <= now + 5 * 60 * 1000).length\n return { failed, running, dueSoon }\n }, [jobs, now])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between flex-wrap gap-2\">\n <div className=\"flex items-center gap-2 min-w-0\">\n <Wrench className=\"h-5 w-5 text-muted-foreground\" />\n <h2 className=\"text-lg font-semibold\">Maintenance</h2>\n <Badge variant=\"secondary\">{jobs.length}</Badge>\n {summary.running > 0 && <Badge className=\"border border-blue-500/30 bg-blue-500/10 text-blue-400\">{summary.running} running</Badge>}\n {summary.failed > 0 && <Badge variant=\"destructive\">{summary.failed} failing</Badge>}\n {summary.dueSoon > 0 && <Badge className=\"border border-yellow-500/30 bg-yellow-500/10 text-yellow-400\">{summary.dueSoon} due soon</Badge>}\n </div>\n <Button size=\"sm\" variant=\"outline\" onClick={() => void fetchMaintenanceJobs()}>\n <RefreshCw className=\"h-3.5 w-3.5\" /> Refresh\n </Button>\n </div>\n\n <ScrollArea className=\"h-[calc(100dvh-10rem)]\">\n {jobs.length === 0 ? (\n <div className=\"rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground\">No maintenance jobs registered</div>\n ) : (\n <>\n {/* Desktop / wide: full table */}\n <div className=\"hidden overflow-x-auto rounded-md border border-border md:block\">\n <table className=\"w-full min-w-[980px] text-sm\">\n <thead className=\"bg-muted/40 text-xs text-muted-foreground\">\n <tr>\n <th className=\"px-3 py-2 text-left font-medium\">Job</th>\n <th className=\"px-3 py-2 text-left font-medium\">Status</th>\n <th className=\"px-3 py-2 text-left font-medium\">Last run</th>\n <th className=\"px-3 py-2 text-left font-medium\">Next run</th>\n <th className=\"px-3 py-2 text-left font-medium\">Duration</th>\n <th className=\"px-3 py-2 text-left font-medium\">Result</th>\n <th className=\"px-3 py-2 text-right font-medium\">Action</th>\n </tr>\n </thead>\n <tbody>\n {jobs.map((job) => (\n <MaintenanceRow\n key={job.id}\n job={job}\n now={now}\n onRun={() => void runMaintenanceJob(job.id)}\n />\n ))}\n </tbody>\n </table>\n </div>\n\n {/* Mobile / narrow: stacked cards so every field is visible without horizontal scroll */}\n <div className=\"space-y-3 md:hidden\">\n {jobs.map((job) => (\n <MaintenanceCard\n key={job.id}\n job={job}\n now={now}\n onRun={() => void runMaintenanceJob(job.id)}\n />\n ))}\n </div>\n </>\n )}\n </ScrollArea>\n </div>\n )\n}\n\nfunction jobStatus(job: MaintenanceJob): string {\n return job.running ? 'running' : job.enabled ? job.lastStatus : 'disabled'\n}\n\nfunction StatusBadge({ status }: { status: string }) {\n return (\n <Badge variant=\"outline\" className={cn('border', STATUS_CLASS[status] || STATUS_CLASS.idle)}>\n {statusIcon(status)}\n {status}\n </Badge>\n )\n}\n\nfunction MaintenanceCard({ job, now, onRun }: { job: MaintenanceJob; now: number; onRun: () => void }) {\n const status = jobStatus(job)\n return (\n <div className=\"rounded-md border border-border p-3\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"font-medium\">{job.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{job.description}</div>\n <div className=\"mt-1 font-mono text-[11px] text-muted-foreground/80\">{job.id}</div>\n </div>\n <StatusBadge status={status} />\n </div>\n\n {job.consecutiveFailures > 0 && (\n <div className=\"mt-2 text-xs text-red-400\">{job.consecutiveFailures} failure{job.consecutiveFailures === 1 ? '' : 's'}</div>\n )}\n\n <dl className=\"mt-3 grid grid-cols-3 gap-2 text-xs\">\n <div>\n <dt className=\"text-muted-foreground\">Last run</dt>\n <dd>{job.lastRunAt ? <span title={fmtTime(job.lastRunAt)}>{timeAgo(now, job.lastRunAt)}</span> : 'never'}</dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">Next run</dt>\n <dd>{job.nextRunAt ? <span title={fmtTime(job.nextRunAt)}>{nextRunText(now, job.nextRunAt)}</span> : '-'}</dd>\n </div>\n <div>\n <dt className=\"text-muted-foreground\">Duration</dt>\n <dd>{job.lastDurationMs !== undefined ? `${job.lastDurationMs}ms` : '-'}</dd>\n </div>\n </dl>\n\n <div className=\"mt-3\">\n <div className=\"text-xs text-muted-foreground\">Result</div>\n {job.lastError ? (\n <div className=\"mt-0.5 text-xs text-red-400 line-clamp-3\">{job.lastError}</div>\n ) : (\n <div className=\"mt-0.5 font-mono text-[11px] text-muted-foreground line-clamp-3\">{resultSummary(job)}</div>\n )}\n </div>\n\n <div className=\"mt-3 flex justify-end\">\n <Button size=\"sm\" variant=\"outline\" disabled={!job.enabled || job.running} onClick={onRun}>\n <Play className=\"h-3.5 w-3.5\" /> Run\n </Button>\n </div>\n </div>\n )\n}\n\nfunction MaintenanceRow({ job, now, onRun }: { job: MaintenanceJob; now: number; onRun: () => void }) {\n const status = jobStatus(job)\n return (\n <tr className=\"border-t border-border align-top\">\n <td className=\"px-3 py-3\">\n <div className=\"font-medium\">{job.title}</div>\n <div className=\"mt-0.5 max-w-md text-xs text-muted-foreground\">{job.description}</div>\n <div className=\"mt-1 font-mono text-[11px] text-muted-foreground/80\">{job.id}</div>\n </td>\n <td className=\"px-3 py-3\">\n <StatusBadge status={status} />\n {job.consecutiveFailures > 0 && (\n <div className=\"mt-1 text-xs text-red-400\">{job.consecutiveFailures} failure{job.consecutiveFailures === 1 ? '' : 's'}</div>\n )}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.lastRunAt ? (\n <span title={fmtTime(job.lastRunAt)}>{timeAgo(now, job.lastRunAt)}</span>\n ) : 'never'}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.nextRunAt ? (\n <span title={fmtTime(job.nextRunAt)}>{nextRunText(now, job.nextRunAt)}</span>\n ) : '-'}\n </td>\n <td className=\"px-3 py-3 text-xs text-muted-foreground\">\n {job.lastDurationMs !== undefined ? `${job.lastDurationMs}ms` : '-'}\n </td>\n <td className=\"px-3 py-3\">\n {job.lastError ? (\n <div className=\"max-w-sm text-xs text-red-400 line-clamp-3\">{job.lastError}</div>\n ) : (\n <div className=\"max-w-sm font-mono text-[11px] text-muted-foreground line-clamp-3\">{resultSummary(job)}</div>\n )}\n </td>\n <td className=\"px-3 py-3 text-right\">\n <Button size=\"sm\" variant=\"outline\" disabled={!job.enabled || job.running} onClick={onRun}>\n <Play className=\"h-3.5 w-3.5\" /> Run\n </Button>\n </td>\n </tr>\n )\n}\n\nfunction statusIcon(status: string) {\n if (status === 'succeeded') return <CheckCircle2 className=\"mr-1 h-3 w-3\" />\n if (status === 'running') return <Activity className=\"mr-1 h-3 w-3\" />\n if (status === 'failed') return <AlertTriangle className=\"mr-1 h-3 w-3\" />\n return <Clock3 className=\"mr-1 h-3 w-3\" />\n}\n\nfunction resultSummary(job: MaintenanceJob): string {\n if (!job.lastResult) return '-'\n const entries = Object.entries(job.lastResult)\n .filter(([, value]) => Array.isArray(value) ? value.length > 0 : value !== undefined && value !== null && value !== 0)\n .map(([key, value]) => `${key}: ${Array.isArray(value) ? value.length : String(value)}`)\n return entries.length ? entries.join(', ') : 'no changes'\n}\n\nfunction nextRunText(now: number, nextRunAt: number): string {\n if (nextRunAt <= now) return 'due now'\n const diff = Math.max(0, (nextRunAt - now) / 1000)\n if (diff < 60) return `in ${Math.ceil(diff)}s`\n if (diff < 3600) return `in ${Math.ceil(diff / 60)}m`\n if (diff < 86400) return `in ${Math.ceil(diff / 3600)}h`\n return `in ${Math.ceil(diff / 86400)}d`\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{
|
|
2
|
-
`)}):null]})}),(0,A.jsx)(B,{title:`Recent Events (${S.length})`,icon:(0,A.jsx)(
|
|
3
|
-
`)}function B({title:e,icon:t,children:n}){return(0,A.jsxs)(`div`,{className:`rounded-md border border-border p-2.5`,children:[(0,A.jsxs)(`h3`,{className:`mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground`,children:[t,e]}),n]})}function V({label:e,value:t,className:n=``,mono:r=!1}){return(0,A.jsxs)(`div`,{className:`min-w-0 ${n}`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`truncate ${r?`font-mono`:``}`,title:t,children:t})]})}function H({label:e,values:t}){return(0,A.jsxs)(`div`,{className:`col-span-2`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`mt-0.5 flex flex-wrap gap-1`,children:t.map(e=>(0,A.jsx)(C,{variant:`outline`,className:`text-[10px]`,children:e},e))})]})}function U({title:e,body:t}){return(0,A.jsxs)(`div`,{className:`rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`mt-0.5 break-words text-red-300/80`,children:t})]})}function W(e,t){let n=t?.meta?.tmuxSession;return typeof n==`string`&&n.trim()?n:e.state.tmuxSession}function G(e,t){return W(e,t)?!!t?.providerCapabilities?.terminal?.live?.read:!1}function K(e,t){return G(e,t)?!!t?.providerCapabilities?.terminal?.live?.write:!1}function q(){let e=v(e=>e.managedPolicies),
|
|
4
|
-
//# sourceMappingURL=managed-agents-
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{H as t,K as n,O as r,P as i,W as a,Wt as o,_ as s,b as c,er as l,g as u,gr as d,h as f,ir as p,rr as m,tr as h,y as g}from"./lucide-react-CoU_Xts2.js";import{p as _,t as v}from"./store-zFLzd0Jd.js";import{f as y}from"./types-CRptbSYh.js";import{K as b,h as x,q as S}from"./display-GFbGUG0O.js";import{t as C}from"./badge-XEru6wto.js";import{t as w}from"./button-C3CQSr4p.js";import{t as T}from"./copy-button-Bil2CjzT.js";import{$ as E,Q as D,et as O}from"./index-DnUo0Zqg.js";var k=e(d(),1),A=m(),j={running:`bg-emerald-500/15 text-emerald-400 border-emerald-500/30`,starting:`bg-blue-500/15 text-blue-400 border-blue-500/30`,stopping:`bg-yellow-500/15 text-yellow-400 border-yellow-500/30`,backoff:`bg-red-500/15 text-red-400 border-red-500/30`,failed:`bg-red-500/15 text-red-400 border-red-500/30`,stopped:`bg-muted text-muted-foreground border-border`};function M({status:e}){return(0,A.jsx)(`span`,{className:h(`inline-flex items-center rounded border px-2 py-0.5 text-xs font-medium`,j[e]),children:e})}var N={running:`bg-emerald-500/20 text-emerald-400`,starting:`bg-blue-500/20 text-blue-400`,stopping:`bg-yellow-500/20 text-yellow-400`,stopped:`bg-zinc-500/20 text-zinc-400`,backoff:`bg-red-500/20 text-red-400`,failed:`bg-red-500/20 text-red-400`};function P({item:e,agent:t,orchestrators:n,now:i,onClose:a,initialDiagnostics:s}){let[c,u]=(0,k.useState)(s??null),[d,m]=(0,k.useState)(!1),[h,_]=(0,k.useState)(null);(0,k.useEffect)(()=>{if(s){u(s);return}let t=!1;return m(!0),_(null),p(`GET`,`/spawn-policy/`+encodeURIComponent(e.policy.name)+`/diagnostics?limit=80`).then(e=>{t||u(e)}).catch(e=>{t||(u(null),_(e.message))}).finally(()=>{t||m(!1)}),()=>{t=!0}},[e.policy.name,e.state.updatedAt,s]);let v=n.find(t=>t.id===e.policy.orchestratorId),y=(0,k.useMemo)(()=>F(e,v),[e,v]),S=c?.timeline??[],O=L(S,t),j=c?.crashReport??null,P=I(e,y),R=t?D(i,t):null;return(0,A.jsxs)(`section`,{className:`rounded-md border border-border bg-card p-3 space-y-3`,children:[(0,A.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-2`,children:[(0,A.jsxs)(`div`,{className:`min-w-0`,children:[(0,A.jsxs)(`h2`,{className:`flex items-center gap-1.5 text-sm font-semibold`,children:[(0,A.jsx)(g,{className:`h-4 w-4 text-muted-foreground`}),e.policy.label||e.policy.name,` Diagnostics`]}),(0,A.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Spawn config, live attachments, recent lifecycle, and logs.`})]}),(0,A.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,A.jsx)(T,{value:()=>z(e,t,v,y,S,j,O),label:`Copy Bundle`,showText:!0,size:`sm`,variant:`outline`,className:`h-8 text-xs`}),(0,A.jsx)(w,{variant:`outline`,size:`sm`,onClick:a,children:`Close`})]})]}),h&&(0,A.jsx)(`div`,{className:`rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5 text-xs text-red-300`,children:h}),d&&!c&&(0,A.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Loading diagnostics...`}),(0,A.jsxs)(`div`,{className:`grid gap-3 lg:grid-cols-2`,children:[(0,A.jsx)(B,{title:`Spawn Command`,icon:(0,A.jsx)(o,{className:`h-3.5 w-3.5`}),children:(0,A.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-1 text-xs`,children:[(0,A.jsx)(V,{label:`Provider`,value:e.policy.provider}),e.policy.model&&(0,A.jsx)(V,{label:`Model`,value:e.policy.model}),e.policy.effort&&(0,A.jsx)(V,{label:`Effort`,value:e.policy.effort}),(0,A.jsx)(V,{label:`Approval`,value:e.policy.permissionMode}),(0,A.jsx)(V,{label:`Mode`,value:e.policy.mode}),e.policy.profile&&(0,A.jsx)(V,{label:`Profile`,value:e.policy.profile}),e.policy.rig&&(0,A.jsx)(V,{label:`Rig`,value:e.policy.rig}),(0,A.jsx)(V,{label:`CWD`,value:e.policy.cwd,className:`col-span-2`,mono:!0}),e.policy.providerArgs.length>0&&(0,A.jsx)(V,{label:`Provider Args`,value:e.policy.providerArgs.join(` `),className:`col-span-2`,mono:!0}),e.policy.tags.length>0&&(0,A.jsx)(H,{label:`Tags`,values:e.policy.tags}),e.policy.capabilities.length>0&&(0,A.jsx)(H,{label:`Caps`,values:e.policy.capabilities})]})}),(0,A.jsx)(B,{title:`Runtime`,icon:(0,A.jsx)(r,{className:`h-3.5 w-3.5`}),children:(0,A.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[(0,A.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:`Lifecycle`}),(0,A.jsx)(M,{status:e.state.status}),(0,A.jsx)(C,{className:N[e.state.status]||`bg-zinc-500/20 text-zinc-400`,children:e.state.status})]}),(0,A.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-1`,children:[(0,A.jsx)(V,{label:`Orchestrator`,value:v?`${v.hostname} (${v.id})`:e.policy.orchestratorId}),v?.version&&(0,A.jsx)(V,{label:`Orch Version`,value:v.version}),y?.pid&&(0,A.jsx)(V,{label:`PID`,value:String(y.pid),mono:!0}),y?.supervisor&&(0,A.jsx)(V,{label:`Supervisor`,value:y.supervisor}),y?.systemdUnit&&(0,A.jsx)(V,{label:`Systemd`,value:y.systemdUnit,mono:!0,className:`col-span-2`}),y?.sessionName&&(0,A.jsx)(V,{label:`Session`,value:y.sessionName,mono:!0}),y?.terminalSession&&(0,A.jsx)(V,{label:`Terminal`,value:y.terminalAvailable?`${y.terminalSession} (available)`:`${y.terminalSession} (not attachable)`,mono:!0}),y?.spawnRequestId&&(0,A.jsx)(V,{label:`Spawn ID`,value:y.spawnRequestId,mono:!0,className:`col-span-2`}),y?.startedAt&&(0,A.jsx)(V,{label:`Started`,value:x(y.startedAt)}),e.state.restartCount!==void 0&&(0,A.jsx)(V,{label:`Restarts`,value:String(e.state.restartCount)}),e.state.consecutiveFailures!==void 0&&(0,A.jsx)(V,{label:`Failures`,value:String(e.state.consecutiveFailures)}),e.state.backoffUntil&&(0,A.jsx)(V,{label:`Backoff`,value:e.state.backoffUntil>i?b(i,e.state.backoffUntil):`expired`})]}),R&&(0,A.jsxs)(`div`,{className:`rounded border border-yellow-500/20 bg-yellow-500/5 px-2 py-1.5 text-yellow-100/80`,children:[`Stuck busy: `,R.kind,` stale for `,b(i,i-R.staleForMs)]}),e.state.lastError&&(0,A.jsx)(U,{title:`Last Error`,body:e.state.lastError})]})})]}),(O||j)&&(0,A.jsx)(B,{title:`Post-Mortem`,icon:(0,A.jsx)(f,{className:`h-3.5 w-3.5`}),children:(0,A.jsxs)(`div`,{className:`space-y-2 text-xs`,children:[j&&(0,A.jsxs)(`div`,{className:`rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5`,children:[(0,A.jsx)(`div`,{className:`font-medium text-red-200`,children:j.diagnosis.summary}),(0,A.jsxs)(`div`,{className:`mt-0.5 text-red-200/70`,children:[`Cause `,j.diagnosis.cause,` · `,j.diagnosis.confidence]})]}),O&&(0,A.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-3 gap-y-1`,children:[(0,A.jsx)(V,{label:`Exit`,value:O.lastError,className:`col-span-2`}),O.detectedAt&&(0,A.jsx)(V,{label:`Detected`,value:b(i,O.detectedAt)}),typeof O.runtimeMs==`number`&&(0,A.jsx)(V,{label:`Runtime`,value:`${Math.max(0,Math.round(O.runtimeMs/1e3))}s`}),O.systemd?.unit&&(0,A.jsx)(V,{label:`Unit`,value:O.systemd.unit,mono:!0,className:`col-span-2`}),O.systemd?.result&&(0,A.jsx)(V,{label:`Systemd Result`,value:O.systemd.result}),O.logFile&&(0,A.jsx)(V,{label:`Log`,value:O.logFile,mono:!0,className:`col-span-2`})]}),O?.logTail?.length?(0,A.jsx)(`pre`,{className:`max-h-32 overflow-auto whitespace-pre-wrap break-words rounded border border-border bg-zinc-950 p-2 text-[11px] leading-4 text-zinc-100`,children:O.logTail.slice(-8).join(`
|
|
2
|
+
`)}):null]})}),(0,A.jsx)(B,{title:`Recent Events (${S.length})`,icon:(0,A.jsx)(l,{className:`h-3.5 w-3.5`}),children:S.length===0?(0,A.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`No recent lifecycle events or command outcomes.`}):(0,A.jsx)(`div`,{className:`space-y-1`,children:S.slice(0,12).map((e,t)=>(0,A.jsxs)(`div`,{className:`grid grid-cols-[5.5rem_5rem_1fr] gap-2 text-xs`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground tabular-nums`,children:b(i,e.ts)}),(0,A.jsx)(C,{variant:`outline`,className:`h-5 justify-center text-[10px]`,children:e.source}),(0,A.jsxs)(`div`,{className:`min-w-0`,children:[(0,A.jsx)(`div`,{className:`truncate font-medium`,title:e.title,children:e.title}),e.detail&&(0,A.jsx)(`div`,{className:`break-words text-muted-foreground`,children:e.detail.length>160?e.detail.slice(0,160)+`...`:e.detail}),typeof e.metadata?.id==`string`&&(0,A.jsxs)(`div`,{className:`font-mono text-[10px] text-muted-foreground`,children:[`command `,e.metadata.id]})]})]},`${e.source}-${e.ts}-${e.kind}-${t}`))})}),v&&P&&(0,A.jsx)(B,{title:`Log Tail`,icon:(0,A.jsx)(o,{className:`h-3.5 w-3.5`}),children:(0,A.jsx)(E,{orchestratorId:v.id,session:P,lines:120})})]})}function F(e,t){return t?.managedAgents.find(t=>t.policyName===e.policy.name||e.state.agentId&&t.agentId===e.state.agentId||e.state.spawnRequestId&&t.spawnRequestId===e.state.spawnRequestId||e.state.tmuxSession&&(t.sessionName===e.state.tmuxSession||t.tmuxSession===e.state.tmuxSession))}function I(e,t){return t?.terminalSession||t?.sessionName||t?.tmuxSession||e.state.tmuxSession}function L(e,t){let n=R(t?.meta?.lastExit);if(n)return n;for(let t of e){let e=R(t.metadata?.lastExit);if(e)return e}return null}function R(e){if(!y(e)||typeof e.lastError!=`string`)return null;let t=y(e.systemd)?e.systemd:void 0;return{lastError:e.lastError,detectedAt:typeof e.detectedAt==`number`?e.detectedAt:void 0,runtimeMs:typeof e.runtimeMs==`number`?e.runtimeMs:void 0,logFile:typeof e.logFile==`string`?e.logFile:void 0,logBytes:typeof e.logBytes==`number`?e.logBytes:void 0,logEmpty:typeof e.logEmpty==`boolean`?e.logEmpty:void 0,logTail:Array.isArray(e.logTail)?e.logTail.filter(e=>typeof e==`string`):void 0,systemd:t?{unit:typeof t.unit==`string`?t.unit:void 0,activeState:typeof t.activeState==`string`?t.activeState:void 0,subState:typeof t.subState==`string`?t.subState:void 0,result:typeof t.result==`string`?t.result:void 0}:void 0,unavailable:Array.isArray(e.unavailable)?e.unavailable.filter(e=>typeof e==`string`):void 0}}function z(e,t,n,r,i,a,o){let s=[`# Managed Agent Diagnostics`,`Policy: ${e.policy.name}`,`Lifecycle: ${e.state.status}`,`Provider: ${e.policy.provider}`,`CWD: ${e.policy.cwd}`,`Approval: ${e.policy.permissionMode}`];if(e.policy.model&&s.push(`Model: ${e.policy.model}`),e.policy.effort&&s.push(`Effort: ${e.policy.effort}`),e.policy.profile&&s.push(`Profile: ${e.policy.profile}`),e.policy.tags.length&&s.push(`Tags: ${e.policy.tags.join(`, `)}`),e.policy.capabilities.length&&s.push(`Caps: ${e.policy.capabilities.join(`, `)}`),t&&s.push(`Agent: ${t.id} (${t.status})`),n&&s.push(`Orchestrator: ${n.hostname} (${n.id})`,`Orchestrator status: ${n.status}`),r&&(s.push(``,`## Runtime`),r.pid&&s.push(`PID: ${r.pid}`),r.supervisor&&s.push(`Supervisor: ${r.supervisor}`),r.systemdUnit&&s.push(`Systemd: ${r.systemdUnit}`),r.sessionName&&s.push(`Session: ${r.sessionName}`),r.terminalSession&&s.push(`Terminal: ${r.terminalSession} (${r.terminalAvailable?`available`:`not attachable`})`),r.spawnRequestId&&s.push(`Spawn request: ${r.spawnRequestId}`)),(e.state.lastError||a||o)&&(s.push(``,`## Post-Mortem`),e.state.lastError&&s.push(`Last error: ${e.state.lastError}`),a&&s.push(`Crash: ${a.diagnosis.cause}/${a.diagnosis.confidence} - ${a.diagnosis.summary}`),o?.lastError&&s.push(`Exit: ${o.lastError}`),o?.logTail?.length&&s.push(``,`Log tail:`,...o.logTail.slice(-8))),i.length){s.push(``,`## Recent Events`);for(let e of i.slice(0,12)){let t=typeof e.metadata?.id==`string`?` (${e.metadata.id})`:``;s.push(`- ${new Date(S(e.ts)).toISOString()} [${e.source}] ${e.title}${t}${e.detail?`: ${e.detail}`:``}`)}}return s.join(`
|
|
3
|
+
`)}function B({title:e,icon:t,children:n}){return(0,A.jsxs)(`div`,{className:`rounded-md border border-border p-2.5`,children:[(0,A.jsxs)(`h3`,{className:`mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground`,children:[t,e]}),n]})}function V({label:e,value:t,className:n=``,mono:r=!1}){return(0,A.jsxs)(`div`,{className:`min-w-0 ${n}`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`truncate ${r?`font-mono`:``}`,title:t,children:t})]})}function H({label:e,values:t}){return(0,A.jsxs)(`div`,{className:`col-span-2`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`mt-0.5 flex flex-wrap gap-1`,children:t.map(e=>(0,A.jsx)(C,{variant:`outline`,className:`text-[10px]`,children:e},e))})]})}function U({title:e,body:t}){return(0,A.jsxs)(`div`,{className:`rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5`,children:[(0,A.jsx)(`span`,{className:`text-muted-foreground`,children:e}),(0,A.jsx)(`div`,{className:`mt-0.5 break-words text-red-300/80`,children:t})]})}function W(e,t){let n=t?.meta?.tmuxSession;return typeof n==`string`&&n.trim()?n:e.state.tmuxSession}function G(e,t){return W(e,t)?!!t?.providerCapabilities?.terminal?.live?.read:!1}function K(e,t){return G(e,t)?!!t?.providerCapabilities?.terminal?.live?.write:!1}function q(){let e=v(e=>e.managedPolicies),r=v(e=>e.agentsById),l=v(e=>e.orchestrators),d=v(e=>e.fetchManagedPolicies),f=v(e=>e.fetchOrchestrators),p=v(e=>e.apiCall),m=v(e=>e.openPolicyCreate),h=v(e=>e.openPolicyEdit),y=v(e=>e.deletePolicy),b=_(),[S,C]=(0,k.useState)(null),[T,D]=(0,k.useState)(null),[j,N]=(0,k.useState)(null);(0,k.useEffect)(()=>{Promise.all([d(),f()])},[]);async function F(e,t){await p(`POST`,`/spawn-policy/${encodeURIComponent(e)}/${t}`,{surface:{component:`managed-agents`}}),await d()}let I=j?e.find(e=>e.policy.name===j)??null:null;return(0,A.jsxs)(`div`,{className:`space-y-4`,children:[(0,A.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Managed Agents`}),(0,A.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Spawn policies, lifecycle state, and headless session logs.`})]}),(0,A.jsxs)(w,{onClick:m,size:`sm`,children:[(0,A.jsx)(t,{className:`h-4 w-4 mr-1`}),`Create Policy`]})]}),e.length===0&&(0,A.jsx)(`div`,{className:`rounded-md border border-border px-3 py-8 text-center text-sm text-muted-foreground`,children:`No managed agents configured`}),(0,A.jsx)(`div`,{className:`grid gap-3 sm:grid-cols-2 lg:grid-cols-3`,children:e.map(e=>{let t=e.state.agentId?r[e.state.agentId]:void 0,l=W(e,t);return(0,A.jsxs)(`div`,{className:`rounded-md border border-border bg-card p-3 space-y-2`,children:[(0,A.jsxs)(`div`,{className:`flex items-start justify-between gap-2`,children:[(0,A.jsxs)(`div`,{className:`min-w-0`,children:[(0,A.jsx)(`div`,{className:`font-medium text-sm truncate`,children:e.policy.label||e.policy.name}),(0,A.jsxs)(`div`,{className:`text-xs text-muted-foreground truncate`,children:[e.policy.mode,` · `,e.policy.cwd]})]}),(0,A.jsx)(M,{status:e.state.status})]}),(0,A.jsxs)(`div`,{className:`grid grid-cols-2 gap-x-4 gap-y-1 text-xs`,children:[(0,A.jsx)(`div`,{className:`text-muted-foreground`,children:`Provider`}),(0,A.jsx)(`div`,{children:e.policy.provider}),(0,A.jsx)(`div`,{className:`text-muted-foreground`,children:`Agent`}),(0,A.jsx)(`div`,{className:`font-mono truncate`,children:e.state.agentId||`-`}),(0,A.jsx)(`div`,{className:`text-muted-foreground`,children:`Restarts`}),(0,A.jsx)(`div`,{children:e.state.restartCount}),(e.state.backoffUntil||e.state.lastError)&&(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(`div`,{className:`text-muted-foreground`,children:e.state.backoffUntil?`Backoff`:`Error`}),(0,A.jsx)(`div`,{className:`truncate`,children:e.state.backoffUntil?x(e.state.backoffUntil):e.state.lastError})]})]}),(0,A.jsxs)(`div`,{className:`flex flex-wrap gap-1 pt-1 border-t border-border`,children:[(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>F(e.policy.name,`start`),title:`Start`,children:(0,A.jsx)(a,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>F(e.policy.name,`stop`),title:`Stop`,children:(0,A.jsx)(c,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>F(e.policy.name,`restart`),title:`Restart`,children:(0,A.jsx)(i,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>C(e),disabled:!e.state.tmuxSession,title:`Logs`,children:(0,A.jsx)(o,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>l&&D({item:e,session:l}),disabled:!G(e,t),title:`Terminal`,children:(0,A.jsx)(s,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:j===e.policy.name?`secondary`:`outline`,className:`h-7 w-7`,onClick:()=>N(t=>t===e.policy.name?null:e.policy.name),title:`Diagnostics`,children:(0,A.jsx)(g,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>h(e.policy),title:`Edit`,children:(0,A.jsx)(n,{className:`h-3.5 w-3.5`})}),(0,A.jsx)(w,{size:`icon`,variant:`outline`,className:`h-7 w-7`,onClick:()=>y(e.policy.name),title:`Delete`,children:(0,A.jsx)(u,{className:`h-3.5 w-3.5`})})]})]},e.policy.name)})}),I&&(0,A.jsx)(P,{item:I,agent:I.state.agentId?r[I.state.agentId]:void 0,orchestrators:l,now:b,onClose:()=>N(null)}),S?.state.tmuxSession&&(0,A.jsxs)(`div`,{className:`space-y-2`,children:[(0,A.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,A.jsxs)(`h2`,{className:`text-lg font-semibold`,children:[S.policy.name,` Logs`]}),(0,A.jsx)(w,{variant:`outline`,size:`sm`,onClick:()=>C(null),children:`Close`})]}),(0,A.jsx)(E,{orchestratorId:S.policy.orchestratorId,session:S.state.tmuxSession})]}),(0,A.jsx)(O,{open:!!T,onOpenChange:e=>{e||D(null)},orchestratorId:T?.item.policy.orchestratorId??``,session:T?.session??``,interactive:T?K(T.item,T.item.state.agentId?r[T.item.state.agentId]:void 0):!1,canWrite:T?K(T.item,T.item.state.agentId?r[T.item.state.agentId]:void 0):!1})]})}export{q as ManagedAgentsView};
|
|
4
|
+
//# sourceMappingURL=managed-agents-yh4HPO5a.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-agents-muCIMxng.js","names":[],"sources":["../../dashboard/src/components/shared/health-badge.tsx","../../dashboard/src/components/shared/managed-policy-diagnostics.tsx","../../dashboard/src/components/views/managed-agents.tsx"],"sourcesContent":["import { cn } from '@/lib/utils'\nimport type { ManagedAgentLifecycleStatus } from '@/types'\n\nconst styles: Record<ManagedAgentLifecycleStatus, string> = {\n running: 'bg-emerald-500/15 text-emerald-400 border-emerald-500/30',\n starting: 'bg-blue-500/15 text-blue-400 border-blue-500/30',\n stopping: 'bg-yellow-500/15 text-yellow-400 border-yellow-500/30',\n backoff: 'bg-red-500/15 text-red-400 border-red-500/30',\n failed: 'bg-red-500/15 text-red-400 border-red-500/30',\n stopped: 'bg-muted text-muted-foreground border-border',\n}\n\nexport function HealthBadge({ status }: { status: ManagedAgentLifecycleStatus }) {\n return (\n <span className={cn('inline-flex items-center rounded border px-2 py-0.5 text-xs font-medium', styles[status])}>\n {status}\n </span>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { CrashReport } from 'agent-relay-sdk/types'\nimport { isRecord } from 'agent-relay-sdk/types'\nimport { Activity, AlertTriangle, FileText, Server, Stethoscope } from 'lucide-react'\nimport { api } from '@/lib/api'\nimport { fmtTime, timeAgo, toTimestamp } from '@/lib/display'\nimport { agentStuckBusyHealth } from '@/lib/busy-health'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { CopyButton } from '@/components/shared/copy-button'\nimport { HealthBadge } from '@/components/shared/health-badge'\nimport { LogViewer } from '@/components/shared/log-viewer'\nimport type { Agent, AgentTimelineEntry, ManagedAgent, ManagedPolicyHealth, Orchestrator } from '@/types'\n\ninterface ManagedPolicyDiagnosticsProps {\n item: ManagedPolicyHealth\n agent?: Agent\n orchestrators: Orchestrator[]\n now: number\n onClose: () => void\n initialDiagnostics?: ManagedPolicyDiagnosticsPayload\n}\n\nexport interface ManagedPolicyDiagnosticsPayload extends ManagedPolicyHealth {\n timeline: AgentTimelineEntry[]\n crashReport: CrashReport | null\n}\n\nconst LIFECYCLE_STATUS_COLORS: Record<string, string> = {\n running: 'bg-emerald-500/20 text-emerald-400',\n starting: 'bg-blue-500/20 text-blue-400',\n stopping: 'bg-yellow-500/20 text-yellow-400',\n stopped: 'bg-zinc-500/20 text-zinc-400',\n backoff: 'bg-red-500/20 text-red-400',\n failed: 'bg-red-500/20 text-red-400',\n}\n\nexport function ManagedPolicyDiagnostics({ item, agent, orchestrators, now, onClose, initialDiagnostics }: ManagedPolicyDiagnosticsProps) {\n const [diagnostics, setDiagnostics] = useState<ManagedPolicyDiagnosticsPayload | null>(initialDiagnostics ?? null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (initialDiagnostics) {\n setDiagnostics(initialDiagnostics)\n return\n }\n let cancelled = false\n setLoading(true)\n setError(null)\n api<ManagedPolicyDiagnosticsPayload>('GET', '/spawn-policy/' + encodeURIComponent(item.policy.name) + '/diagnostics?limit=80')\n .then((payload) => {\n if (!cancelled) setDiagnostics(payload)\n })\n .catch((e) => {\n if (!cancelled) {\n setDiagnostics(null)\n setError((e as Error).message)\n }\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => { cancelled = true }\n }, [item.policy.name, item.state.updatedAt, initialDiagnostics])\n\n const orchestrator = orchestrators.find((o) => o.id === item.policy.orchestratorId)\n const managedAgent = useMemo(() => managedAgentFor(item, orchestrator), [item, orchestrator])\n const timeline = diagnostics?.timeline ?? []\n const lastExit = latestExitDiagnostics(timeline, agent)\n const crashReport = diagnostics?.crashReport ?? null\n const logSession = logSessionFor(item, managedAgent)\n const stuckBusy = agent ? agentStuckBusyHealth(now, agent) : null\n\n return (\n <section className=\"rounded-md border border-border bg-card p-3 space-y-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h2 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Stethoscope className=\"h-4 w-4 text-muted-foreground\" />\n {item.policy.label || item.policy.name} Diagnostics\n </h2>\n <p className=\"text-xs text-muted-foreground\">Spawn config, live attachments, recent lifecycle, and logs.</p>\n </div>\n <div className=\"flex items-center gap-1\">\n <CopyButton value={() => buildDiagnosticBundle(item, agent, orchestrator, managedAgent, timeline, crashReport, lastExit)} label=\"Copy Bundle\" showText size=\"sm\" variant=\"outline\" className=\"h-8 text-xs\" />\n <Button variant=\"outline\" size=\"sm\" onClick={onClose}>Close</Button>\n </div>\n </div>\n\n {error && <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5 text-xs text-red-300\">{error}</div>}\n {loading && !diagnostics && <div className=\"text-xs text-muted-foreground\">Loading diagnostics...</div>}\n\n <div className=\"grid gap-3 lg:grid-cols-2\">\n <Panel title=\"Spawn Command\" icon={<FileText className=\"h-3.5 w-3.5\" />}>\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1 text-xs\">\n <KV label=\"Provider\" value={item.policy.provider} />\n {item.policy.model && <KV label=\"Model\" value={item.policy.model} />}\n {item.policy.effort && <KV label=\"Effort\" value={item.policy.effort} />}\n <KV label=\"Approval\" value={item.policy.permissionMode} />\n <KV label=\"Mode\" value={item.policy.mode} />\n {item.policy.profile && <KV label=\"Profile\" value={item.policy.profile} />}\n {item.policy.rig && <KV label=\"Rig\" value={item.policy.rig} />}\n <KV label=\"CWD\" value={item.policy.cwd} className=\"col-span-2\" mono />\n {item.policy.providerArgs.length > 0 && <KV label=\"Provider Args\" value={item.policy.providerArgs.join(' ')} className=\"col-span-2\" mono />}\n {item.policy.tags.length > 0 && <Pills label=\"Tags\" values={item.policy.tags} />}\n {item.policy.capabilities.length > 0 && <Pills label=\"Caps\" values={item.policy.capabilities} />}\n </div>\n </Panel>\n\n <Panel title=\"Runtime\" icon={<Server className=\"h-3.5 w-3.5\" />}>\n <div className=\"space-y-2 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground\">Lifecycle</span>\n <HealthBadge status={item.state.status} />\n <Badge className={LIFECYCLE_STATUS_COLORS[item.state.status] || 'bg-zinc-500/20 text-zinc-400'}>{item.state.status}</Badge>\n </div>\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1\">\n <KV label=\"Orchestrator\" value={orchestrator ? `${orchestrator.hostname} (${orchestrator.id})` : item.policy.orchestratorId} />\n {orchestrator?.version && <KV label=\"Orch Version\" value={orchestrator.version} />}\n {managedAgent?.pid && <KV label=\"PID\" value={String(managedAgent.pid)} mono />}\n {managedAgent?.supervisor && <KV label=\"Supervisor\" value={managedAgent.supervisor} />}\n {managedAgent?.systemdUnit && <KV label=\"Systemd\" value={managedAgent.systemdUnit} mono className=\"col-span-2\" />}\n {managedAgent?.sessionName && <KV label=\"Session\" value={managedAgent.sessionName} mono />}\n {managedAgent?.terminalSession && <KV label=\"Terminal\" value={managedAgent.terminalAvailable ? `${managedAgent.terminalSession} (available)` : `${managedAgent.terminalSession} (not attachable)`} mono />}\n {managedAgent?.spawnRequestId && <KV label=\"Spawn ID\" value={managedAgent.spawnRequestId} mono className=\"col-span-2\" />}\n {managedAgent?.startedAt && <KV label=\"Started\" value={fmtTime(managedAgent.startedAt)} />}\n {item.state.restartCount !== undefined && <KV label=\"Restarts\" value={String(item.state.restartCount)} />}\n {item.state.consecutiveFailures !== undefined && <KV label=\"Failures\" value={String(item.state.consecutiveFailures)} />}\n {item.state.backoffUntil && <KV label=\"Backoff\" value={item.state.backoffUntil > now ? timeAgo(now, item.state.backoffUntil) : 'expired'} />}\n </div>\n {stuckBusy && (\n <div className=\"rounded border border-yellow-500/20 bg-yellow-500/5 px-2 py-1.5 text-yellow-100/80\">\n Stuck busy: {stuckBusy.kind} stale for {timeAgo(now, now - stuckBusy.staleForMs)}\n </div>\n )}\n {item.state.lastError && <ErrorBlock title=\"Last Error\" body={item.state.lastError} />}\n </div>\n </Panel>\n </div>\n\n {(lastExit || crashReport) && (\n <Panel title=\"Post-Mortem\" icon={<AlertTriangle className=\"h-3.5 w-3.5\" />}>\n <div className=\"space-y-2 text-xs\">\n {crashReport && (\n <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5\">\n <div className=\"font-medium text-red-200\">{crashReport.diagnosis.summary}</div>\n <div className=\"mt-0.5 text-red-200/70\">Cause {crashReport.diagnosis.cause} · {crashReport.diagnosis.confidence}</div>\n </div>\n )}\n {lastExit && (\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1\">\n <KV label=\"Exit\" value={lastExit.lastError} className=\"col-span-2\" />\n {lastExit.detectedAt && <KV label=\"Detected\" value={timeAgo(now, lastExit.detectedAt)} />}\n {typeof lastExit.runtimeMs === 'number' && <KV label=\"Runtime\" value={`${Math.max(0, Math.round(lastExit.runtimeMs / 1000))}s`} />}\n {lastExit.systemd?.unit && <KV label=\"Unit\" value={lastExit.systemd.unit} mono className=\"col-span-2\" />}\n {lastExit.systemd?.result && <KV label=\"Systemd Result\" value={lastExit.systemd.result} />}\n {lastExit.logFile && <KV label=\"Log\" value={lastExit.logFile} mono className=\"col-span-2\" />}\n </div>\n )}\n {lastExit?.logTail?.length ? (\n <pre className=\"max-h-32 overflow-auto whitespace-pre-wrap break-words rounded border border-border bg-zinc-950 p-2 text-[11px] leading-4 text-zinc-100\">{lastExit.logTail.slice(-8).join('\\n')}</pre>\n ) : null}\n </div>\n </Panel>\n )}\n\n <Panel title={`Recent Events (${timeline.length})`} icon={<Activity className=\"h-3.5 w-3.5\" />}>\n {timeline.length === 0 ? (\n <div className=\"text-xs text-muted-foreground\">No recent lifecycle events or command outcomes.</div>\n ) : (\n <div className=\"space-y-1\">\n {timeline.slice(0, 12).map((entry, index) => (\n <div key={`${entry.source}-${entry.ts}-${entry.kind}-${index}`} className=\"grid grid-cols-[5.5rem_5rem_1fr] gap-2 text-xs\">\n <span className=\"text-muted-foreground tabular-nums\">{timeAgo(now, entry.ts)}</span>\n <Badge variant=\"outline\" className=\"h-5 justify-center text-[10px]\">{entry.source}</Badge>\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\" title={entry.title}>{entry.title}</div>\n {entry.detail && <div className=\"break-words text-muted-foreground\">{entry.detail.length > 160 ? entry.detail.slice(0, 160) + '...' : entry.detail}</div>}\n {typeof entry.metadata?.id === 'string' && <div className=\"font-mono text-[10px] text-muted-foreground\">command {entry.metadata.id}</div>}\n </div>\n </div>\n ))}\n </div>\n )}\n </Panel>\n\n {orchestrator && logSession && (\n <Panel title=\"Log Tail\" icon={<FileText className=\"h-3.5 w-3.5\" />}>\n <LogViewer orchestratorId={orchestrator.id} session={logSession} lines={120} />\n </Panel>\n )}\n </section>\n )\n}\n\nfunction managedAgentFor(item: ManagedPolicyHealth, orchestrator?: Orchestrator): ManagedAgent | undefined {\n return orchestrator?.managedAgents.find((m) =>\n m.policyName === item.policy.name ||\n (item.state.agentId && m.agentId === item.state.agentId) ||\n (item.state.spawnRequestId && m.spawnRequestId === item.state.spawnRequestId) ||\n (item.state.tmuxSession && (m.sessionName === item.state.tmuxSession || m.tmuxSession === item.state.tmuxSession))\n )\n}\n\nfunction logSessionFor(item: ManagedPolicyHealth, managedAgent?: ManagedAgent): string | undefined {\n return managedAgent?.terminalSession || managedAgent?.sessionName || managedAgent?.tmuxSession || item.state.tmuxSession\n}\n\nfunction latestExitDiagnostics(timeline: AgentTimelineEntry[], agent?: Agent): ManagedSessionExitDiagnostics | null {\n const fromAgent = exitDiagnostics(agent?.meta?.lastExit)\n if (fromAgent) return fromAgent\n for (const entry of timeline) {\n const exit = exitDiagnostics(entry.metadata?.lastExit)\n if (exit) return exit\n }\n return null\n}\n\nfunction exitDiagnostics(value: unknown): ManagedSessionExitDiagnostics | null {\n if (!isRecord(value) || typeof value.lastError !== 'string') return null\n const systemd = isRecord(value.systemd) ? value.systemd : undefined\n return {\n lastError: value.lastError,\n detectedAt: typeof value.detectedAt === 'number' ? value.detectedAt : undefined,\n runtimeMs: typeof value.runtimeMs === 'number' ? value.runtimeMs : undefined,\n logFile: typeof value.logFile === 'string' ? value.logFile : undefined,\n logBytes: typeof value.logBytes === 'number' ? value.logBytes : undefined,\n logEmpty: typeof value.logEmpty === 'boolean' ? value.logEmpty : undefined,\n logTail: Array.isArray(value.logTail) ? value.logTail.filter((line): line is string => typeof line === 'string') : undefined,\n systemd: systemd ? {\n unit: typeof systemd.unit === 'string' ? systemd.unit : undefined,\n activeState: typeof systemd.activeState === 'string' ? systemd.activeState : undefined,\n subState: typeof systemd.subState === 'string' ? systemd.subState : undefined,\n result: typeof systemd.result === 'string' ? systemd.result : undefined,\n } : undefined,\n unavailable: Array.isArray(value.unavailable) ? value.unavailable.filter((line): line is string => typeof line === 'string') : undefined,\n }\n}\n\ninterface ManagedSessionExitDiagnostics {\n lastError: string\n detectedAt?: number\n runtimeMs?: number\n logFile?: string\n logBytes?: number\n logEmpty?: boolean\n logTail?: string[]\n systemd?: {\n unit?: string\n activeState?: string\n subState?: string\n result?: string\n }\n unavailable?: string[]\n}\n\nfunction buildDiagnosticBundle(\n item: ManagedPolicyHealth,\n agent: Agent | undefined,\n orchestrator: Orchestrator | undefined,\n managedAgent: ManagedAgent | undefined,\n timeline: AgentTimelineEntry[],\n crashReport: CrashReport | null,\n lastExit: ManagedSessionExitDiagnostics | null,\n): string {\n const lines = [\n '# Managed Agent Diagnostics',\n `Policy: ${item.policy.name}`,\n `Lifecycle: ${item.state.status}`,\n `Provider: ${item.policy.provider}`,\n `CWD: ${item.policy.cwd}`,\n `Approval: ${item.policy.permissionMode}`,\n ]\n if (item.policy.model) lines.push(`Model: ${item.policy.model}`)\n if (item.policy.effort) lines.push(`Effort: ${item.policy.effort}`)\n if (item.policy.profile) lines.push(`Profile: ${item.policy.profile}`)\n if (item.policy.tags.length) lines.push(`Tags: ${item.policy.tags.join(', ')}`)\n if (item.policy.capabilities.length) lines.push(`Caps: ${item.policy.capabilities.join(', ')}`)\n if (agent) lines.push(`Agent: ${agent.id} (${agent.status})`)\n if (orchestrator) lines.push(`Orchestrator: ${orchestrator.hostname} (${orchestrator.id})`, `Orchestrator status: ${orchestrator.status}`)\n if (managedAgent) {\n lines.push('', '## Runtime')\n if (managedAgent.pid) lines.push(`PID: ${managedAgent.pid}`)\n if (managedAgent.supervisor) lines.push(`Supervisor: ${managedAgent.supervisor}`)\n if (managedAgent.systemdUnit) lines.push(`Systemd: ${managedAgent.systemdUnit}`)\n if (managedAgent.sessionName) lines.push(`Session: ${managedAgent.sessionName}`)\n if (managedAgent.terminalSession) lines.push(`Terminal: ${managedAgent.terminalSession} (${managedAgent.terminalAvailable ? 'available' : 'not attachable'})`)\n if (managedAgent.spawnRequestId) lines.push(`Spawn request: ${managedAgent.spawnRequestId}`)\n }\n if (item.state.lastError || crashReport || lastExit) {\n lines.push('', '## Post-Mortem')\n if (item.state.lastError) lines.push(`Last error: ${item.state.lastError}`)\n if (crashReport) lines.push(`Crash: ${crashReport.diagnosis.cause}/${crashReport.diagnosis.confidence} - ${crashReport.diagnosis.summary}`)\n if (lastExit?.lastError) lines.push(`Exit: ${lastExit.lastError}`)\n if (lastExit?.logTail?.length) lines.push('', 'Log tail:', ...lastExit.logTail.slice(-8))\n }\n if (timeline.length) {\n lines.push('', '## Recent Events')\n for (const entry of timeline.slice(0, 12)) {\n const commandId = typeof entry.metadata?.id === 'string' ? ` (${entry.metadata.id})` : ''\n lines.push(`- ${new Date(toTimestamp(entry.ts)).toISOString()} [${entry.source}] ${entry.title}${commandId}${entry.detail ? `: ${entry.detail}` : ''}`)\n }\n }\n return lines.join('\\n')\n}\n\nfunction Panel({ title, icon, children }: { title: string; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div className=\"rounded-md border border-border p-2.5\">\n <h3 className=\"mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n {icon}\n {title}\n </h3>\n {children}\n </div>\n )\n}\n\nfunction KV({ label, value, className = '', mono = false }: { label: string; value: string; className?: string; mono?: boolean }) {\n return (\n <div className={`min-w-0 ${className}`}>\n <span className=\"text-muted-foreground\">{label}</span>\n <div className={`truncate ${mono ? 'font-mono' : ''}`} title={value}>{value}</div>\n </div>\n )\n}\n\nfunction Pills({ label, values }: { label: string; values: string[] }) {\n return (\n <div className=\"col-span-2\">\n <span className=\"text-muted-foreground\">{label}</span>\n <div className=\"mt-0.5 flex flex-wrap gap-1\">\n {values.map((value) => <Badge key={value} variant=\"outline\" className=\"text-[10px]\">{value}</Badge>)}\n </div>\n </div>\n )\n}\n\nfunction ErrorBlock({ title, body }: { title: string; body: string }) {\n return (\n <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5\">\n <span className=\"text-muted-foreground\">{title}</span>\n <div className=\"mt-0.5 break-words text-red-300/80\">{body}</div>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { FileText, Pencil, Play, Plus, RotateCw, Square, Stethoscope, Terminal, Trash2 } from 'lucide-react'\nimport { useNow, useRelayStore } from '@/store'\nimport { Button } from '@/components/ui/button'\nimport { HealthBadge } from '@/components/shared/health-badge'\nimport { LogViewer } from '@/components/shared/log-viewer'\nimport { ManagedPolicyDiagnostics } from '@/components/shared/managed-policy-diagnostics'\nimport { TerminalDialog } from '@/components/shared/terminal-viewer'\nimport { fmtTime } from '@/lib/display'\nimport type { Agent, ManagedPolicyHealth } from '@/types'\n\nfunction terminalSessionFor(item: ManagedPolicyHealth, agent?: Agent): string | undefined {\n const agentSession = agent?.meta?.tmuxSession\n if (typeof agentSession === 'string' && agentSession.trim()) return agentSession\n return item.state.tmuxSession\n}\n\nfunction canReadTerminal(item: ManagedPolicyHealth, agent?: Agent): boolean {\n if (!terminalSessionFor(item, agent)) return false\n return Boolean(agent?.providerCapabilities?.terminal?.live?.read)\n}\n\nfunction canWriteTerminal(item: ManagedPolicyHealth, agent?: Agent): boolean {\n if (!canReadTerminal(item, agent)) return false\n return Boolean(agent?.providerCapabilities?.terminal?.live?.write)\n}\n\nexport function ManagedAgentsView() {\n const policies = useRelayStore((s) => s.managedPolicies)\n const agentsById = useRelayStore((s) => s.agentsById)\n const orchestrators = useRelayStore((s) => s.orchestrators)\n const fetchManagedPolicies = useRelayStore((s) => s.fetchManagedPolicies)\n const fetchOrchestrators = useRelayStore((s) => s.fetchOrchestrators)\n const apiCall = useRelayStore((s) => s.apiCall)\n const openPolicyCreate = useRelayStore((s) => s.openPolicyCreate)\n const openPolicyEdit = useRelayStore((s) => s.openPolicyEdit)\n const deletePolicy = useRelayStore((s) => s.deletePolicy)\n const now = useNow()\n const [logsFor, setLogsFor] = useState<ManagedPolicyHealth | null>(null)\n const [terminalFor, setTerminalFor] = useState<{ item: ManagedPolicyHealth; session: string } | null>(null)\n const [diagnosticsFor, setDiagnosticsFor] = useState<string | null>(null)\n\n useEffect(() => {\n void Promise.all([fetchManagedPolicies(), fetchOrchestrators()])\n }, [])\n\n async function lifecycle(name: string, action: 'start' | 'stop' | 'restart') {\n await apiCall('POST', `/spawn-policy/${encodeURIComponent(name)}/${action}`, { surface: { component: 'managed-agents' } })\n await fetchManagedPolicies()\n }\n\n const diagnosticsItem = diagnosticsFor ? policies.find((item) => item.policy.name === diagnosticsFor) ?? null : null\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Managed Agents</h1>\n <p className=\"text-sm text-muted-foreground\">Spawn policies, lifecycle state, and headless session logs.</p>\n </div>\n <Button onClick={openPolicyCreate} size=\"sm\">\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Policy\n </Button>\n </div>\n\n {policies.length === 0 && (\n <div className=\"rounded-md border border-border px-3 py-8 text-center text-sm text-muted-foreground\">\n No managed agents configured\n </div>\n )}\n\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {policies.map((item) => {\n const agent = item.state.agentId ? agentsById[item.state.agentId] : undefined\n const terminalSession = terminalSessionFor(item, agent)\n return (\n <div key={item.policy.name} className=\"rounded-md border border-border bg-card p-3 space-y-2\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"font-medium text-sm truncate\">{item.policy.label || item.policy.name}</div>\n <div className=\"text-xs text-muted-foreground truncate\">{item.policy.mode} · {item.policy.cwd}</div>\n </div>\n <HealthBadge status={item.state.status} />\n </div>\n\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-1 text-xs\">\n <div className=\"text-muted-foreground\">Provider</div>\n <div>{item.policy.provider}</div>\n <div className=\"text-muted-foreground\">Agent</div>\n <div className=\"font-mono truncate\">{item.state.agentId || '-'}</div>\n <div className=\"text-muted-foreground\">Restarts</div>\n <div>{item.state.restartCount}</div>\n {(item.state.backoffUntil || item.state.lastError) && (\n <>\n <div className=\"text-muted-foreground\">{item.state.backoffUntil ? 'Backoff' : 'Error'}</div>\n <div className=\"truncate\">{item.state.backoffUntil ? fmtTime(item.state.backoffUntil) : item.state.lastError}</div>\n </>\n )}\n </div>\n\n <div className=\"flex flex-wrap gap-1 pt-1 border-t border-border\">\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'start')} title=\"Start\"><Play className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'stop')} title=\"Stop\"><Square className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'restart')} title=\"Restart\"><RotateCw className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => setLogsFor(item)} disabled={!item.state.tmuxSession} title=\"Logs\"><FileText className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => terminalSession && setTerminalFor({ item, session: terminalSession })} disabled={!canReadTerminal(item, agent)} title=\"Terminal\"><Terminal className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant={diagnosticsFor === item.policy.name ? 'secondary' : 'outline'} className=\"h-7 w-7\" onClick={() => setDiagnosticsFor((current) => current === item.policy.name ? null : item.policy.name)} title=\"Diagnostics\"><Stethoscope className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => openPolicyEdit(item.policy)} title=\"Edit\"><Pencil className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => deletePolicy(item.policy.name)} title=\"Delete\"><Trash2 className=\"h-3.5 w-3.5\" /></Button>\n </div>\n </div>\n )\n })}\n </div>\n\n {diagnosticsItem && (\n <ManagedPolicyDiagnostics\n item={diagnosticsItem}\n agent={diagnosticsItem.state.agentId ? agentsById[diagnosticsItem.state.agentId] : undefined}\n orchestrators={orchestrators}\n now={now}\n onClose={() => setDiagnosticsFor(null)}\n />\n )}\n\n {logsFor?.state.tmuxSession && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">{logsFor.policy.name} Logs</h2>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setLogsFor(null)}>Close</Button>\n </div>\n <LogViewer orchestratorId={logsFor.policy.orchestratorId} session={logsFor.state.tmuxSession} />\n </div>\n )}\n\n <TerminalDialog\n open={!!terminalFor}\n onOpenChange={(open) => { if (!open) setTerminalFor(null) }}\n orchestratorId={terminalFor?.item.policy.orchestratorId ?? ''}\n session={terminalFor?.session ?? ''}\n interactive={terminalFor ? canWriteTerminal(terminalFor.item, terminalFor.item.state.agentId ? agentsById[terminalFor.item.state.agentId] : undefined) : false}\n canWrite={terminalFor ? canWriteTerminal(terminalFor.item, terminalFor.item.state.agentId ? agentsById[terminalFor.item.state.agentId] : undefined) : false}\n />\n </div>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"managed-agents-yh4HPO5a.js","names":[],"sources":["../../dashboard/src/components/shared/health-badge.tsx","../../dashboard/src/components/shared/managed-policy-diagnostics.tsx","../../dashboard/src/components/views/managed-agents.tsx"],"sourcesContent":["import { cn } from '@/lib/utils'\nimport type { ManagedAgentLifecycleStatus } from '@/types'\n\nconst styles: Record<ManagedAgentLifecycleStatus, string> = {\n running: 'bg-emerald-500/15 text-emerald-400 border-emerald-500/30',\n starting: 'bg-blue-500/15 text-blue-400 border-blue-500/30',\n stopping: 'bg-yellow-500/15 text-yellow-400 border-yellow-500/30',\n backoff: 'bg-red-500/15 text-red-400 border-red-500/30',\n failed: 'bg-red-500/15 text-red-400 border-red-500/30',\n stopped: 'bg-muted text-muted-foreground border-border',\n}\n\nexport function HealthBadge({ status }: { status: ManagedAgentLifecycleStatus }) {\n return (\n <span className={cn('inline-flex items-center rounded border px-2 py-0.5 text-xs font-medium', styles[status])}>\n {status}\n </span>\n )\n}\n","import { useEffect, useMemo, useState } from 'react'\nimport type { CrashReport } from 'agent-relay-sdk/types'\nimport { isRecord } from 'agent-relay-sdk/types'\nimport { Activity, AlertTriangle, FileText, Server, Stethoscope } from 'lucide-react'\nimport { api } from '@/lib/api'\nimport { fmtTime, timeAgo, toTimestamp } from '@/lib/display'\nimport { agentStuckBusyHealth } from '@/lib/busy-health'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { CopyButton } from '@/components/shared/copy-button'\nimport { HealthBadge } from '@/components/shared/health-badge'\nimport { LogViewer } from '@/components/shared/log-viewer'\nimport type { Agent, AgentTimelineEntry, ManagedAgent, ManagedPolicyHealth, Orchestrator } from '@/types'\n\ninterface ManagedPolicyDiagnosticsProps {\n item: ManagedPolicyHealth\n agent?: Agent\n orchestrators: Orchestrator[]\n now: number\n onClose: () => void\n initialDiagnostics?: ManagedPolicyDiagnosticsPayload\n}\n\nexport interface ManagedPolicyDiagnosticsPayload extends ManagedPolicyHealth {\n timeline: AgentTimelineEntry[]\n crashReport: CrashReport | null\n}\n\nconst LIFECYCLE_STATUS_COLORS: Record<string, string> = {\n running: 'bg-emerald-500/20 text-emerald-400',\n starting: 'bg-blue-500/20 text-blue-400',\n stopping: 'bg-yellow-500/20 text-yellow-400',\n stopped: 'bg-zinc-500/20 text-zinc-400',\n backoff: 'bg-red-500/20 text-red-400',\n failed: 'bg-red-500/20 text-red-400',\n}\n\nexport function ManagedPolicyDiagnostics({ item, agent, orchestrators, now, onClose, initialDiagnostics }: ManagedPolicyDiagnosticsProps) {\n const [diagnostics, setDiagnostics] = useState<ManagedPolicyDiagnosticsPayload | null>(initialDiagnostics ?? null)\n const [loading, setLoading] = useState(false)\n const [error, setError] = useState<string | null>(null)\n\n useEffect(() => {\n if (initialDiagnostics) {\n setDiagnostics(initialDiagnostics)\n return\n }\n let cancelled = false\n setLoading(true)\n setError(null)\n api<ManagedPolicyDiagnosticsPayload>('GET', '/spawn-policy/' + encodeURIComponent(item.policy.name) + '/diagnostics?limit=80')\n .then((payload) => {\n if (!cancelled) setDiagnostics(payload)\n })\n .catch((e) => {\n if (!cancelled) {\n setDiagnostics(null)\n setError((e as Error).message)\n }\n })\n .finally(() => {\n if (!cancelled) setLoading(false)\n })\n return () => { cancelled = true }\n }, [item.policy.name, item.state.updatedAt, initialDiagnostics])\n\n const orchestrator = orchestrators.find((o) => o.id === item.policy.orchestratorId)\n const managedAgent = useMemo(() => managedAgentFor(item, orchestrator), [item, orchestrator])\n const timeline = diagnostics?.timeline ?? []\n const lastExit = latestExitDiagnostics(timeline, agent)\n const crashReport = diagnostics?.crashReport ?? null\n const logSession = logSessionFor(item, managedAgent)\n const stuckBusy = agent ? agentStuckBusyHealth(now, agent) : null\n\n return (\n <section className=\"rounded-md border border-border bg-card p-3 space-y-3\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <h2 className=\"flex items-center gap-1.5 text-sm font-semibold\">\n <Stethoscope className=\"h-4 w-4 text-muted-foreground\" />\n {item.policy.label || item.policy.name} Diagnostics\n </h2>\n <p className=\"text-xs text-muted-foreground\">Spawn config, live attachments, recent lifecycle, and logs.</p>\n </div>\n <div className=\"flex items-center gap-1\">\n <CopyButton value={() => buildDiagnosticBundle(item, agent, orchestrator, managedAgent, timeline, crashReport, lastExit)} label=\"Copy Bundle\" showText size=\"sm\" variant=\"outline\" className=\"h-8 text-xs\" />\n <Button variant=\"outline\" size=\"sm\" onClick={onClose}>Close</Button>\n </div>\n </div>\n\n {error && <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5 text-xs text-red-300\">{error}</div>}\n {loading && !diagnostics && <div className=\"text-xs text-muted-foreground\">Loading diagnostics...</div>}\n\n <div className=\"grid gap-3 lg:grid-cols-2\">\n <Panel title=\"Spawn Command\" icon={<FileText className=\"h-3.5 w-3.5\" />}>\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1 text-xs\">\n <KV label=\"Provider\" value={item.policy.provider} />\n {item.policy.model && <KV label=\"Model\" value={item.policy.model} />}\n {item.policy.effort && <KV label=\"Effort\" value={item.policy.effort} />}\n <KV label=\"Approval\" value={item.policy.permissionMode} />\n <KV label=\"Mode\" value={item.policy.mode} />\n {item.policy.profile && <KV label=\"Profile\" value={item.policy.profile} />}\n {item.policy.rig && <KV label=\"Rig\" value={item.policy.rig} />}\n <KV label=\"CWD\" value={item.policy.cwd} className=\"col-span-2\" mono />\n {item.policy.providerArgs.length > 0 && <KV label=\"Provider Args\" value={item.policy.providerArgs.join(' ')} className=\"col-span-2\" mono />}\n {item.policy.tags.length > 0 && <Pills label=\"Tags\" values={item.policy.tags} />}\n {item.policy.capabilities.length > 0 && <Pills label=\"Caps\" values={item.policy.capabilities} />}\n </div>\n </Panel>\n\n <Panel title=\"Runtime\" icon={<Server className=\"h-3.5 w-3.5\" />}>\n <div className=\"space-y-2 text-xs\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground\">Lifecycle</span>\n <HealthBadge status={item.state.status} />\n <Badge className={LIFECYCLE_STATUS_COLORS[item.state.status] || 'bg-zinc-500/20 text-zinc-400'}>{item.state.status}</Badge>\n </div>\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1\">\n <KV label=\"Orchestrator\" value={orchestrator ? `${orchestrator.hostname} (${orchestrator.id})` : item.policy.orchestratorId} />\n {orchestrator?.version && <KV label=\"Orch Version\" value={orchestrator.version} />}\n {managedAgent?.pid && <KV label=\"PID\" value={String(managedAgent.pid)} mono />}\n {managedAgent?.supervisor && <KV label=\"Supervisor\" value={managedAgent.supervisor} />}\n {managedAgent?.systemdUnit && <KV label=\"Systemd\" value={managedAgent.systemdUnit} mono className=\"col-span-2\" />}\n {managedAgent?.sessionName && <KV label=\"Session\" value={managedAgent.sessionName} mono />}\n {managedAgent?.terminalSession && <KV label=\"Terminal\" value={managedAgent.terminalAvailable ? `${managedAgent.terminalSession} (available)` : `${managedAgent.terminalSession} (not attachable)`} mono />}\n {managedAgent?.spawnRequestId && <KV label=\"Spawn ID\" value={managedAgent.spawnRequestId} mono className=\"col-span-2\" />}\n {managedAgent?.startedAt && <KV label=\"Started\" value={fmtTime(managedAgent.startedAt)} />}\n {item.state.restartCount !== undefined && <KV label=\"Restarts\" value={String(item.state.restartCount)} />}\n {item.state.consecutiveFailures !== undefined && <KV label=\"Failures\" value={String(item.state.consecutiveFailures)} />}\n {item.state.backoffUntil && <KV label=\"Backoff\" value={item.state.backoffUntil > now ? timeAgo(now, item.state.backoffUntil) : 'expired'} />}\n </div>\n {stuckBusy && (\n <div className=\"rounded border border-yellow-500/20 bg-yellow-500/5 px-2 py-1.5 text-yellow-100/80\">\n Stuck busy: {stuckBusy.kind} stale for {timeAgo(now, now - stuckBusy.staleForMs)}\n </div>\n )}\n {item.state.lastError && <ErrorBlock title=\"Last Error\" body={item.state.lastError} />}\n </div>\n </Panel>\n </div>\n\n {(lastExit || crashReport) && (\n <Panel title=\"Post-Mortem\" icon={<AlertTriangle className=\"h-3.5 w-3.5\" />}>\n <div className=\"space-y-2 text-xs\">\n {crashReport && (\n <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5\">\n <div className=\"font-medium text-red-200\">{crashReport.diagnosis.summary}</div>\n <div className=\"mt-0.5 text-red-200/70\">Cause {crashReport.diagnosis.cause} · {crashReport.diagnosis.confidence}</div>\n </div>\n )}\n {lastExit && (\n <div className=\"grid grid-cols-2 gap-x-3 gap-y-1\">\n <KV label=\"Exit\" value={lastExit.lastError} className=\"col-span-2\" />\n {lastExit.detectedAt && <KV label=\"Detected\" value={timeAgo(now, lastExit.detectedAt)} />}\n {typeof lastExit.runtimeMs === 'number' && <KV label=\"Runtime\" value={`${Math.max(0, Math.round(lastExit.runtimeMs / 1000))}s`} />}\n {lastExit.systemd?.unit && <KV label=\"Unit\" value={lastExit.systemd.unit} mono className=\"col-span-2\" />}\n {lastExit.systemd?.result && <KV label=\"Systemd Result\" value={lastExit.systemd.result} />}\n {lastExit.logFile && <KV label=\"Log\" value={lastExit.logFile} mono className=\"col-span-2\" />}\n </div>\n )}\n {lastExit?.logTail?.length ? (\n <pre className=\"max-h-32 overflow-auto whitespace-pre-wrap break-words rounded border border-border bg-zinc-950 p-2 text-[11px] leading-4 text-zinc-100\">{lastExit.logTail.slice(-8).join('\\n')}</pre>\n ) : null}\n </div>\n </Panel>\n )}\n\n <Panel title={`Recent Events (${timeline.length})`} icon={<Activity className=\"h-3.5 w-3.5\" />}>\n {timeline.length === 0 ? (\n <div className=\"text-xs text-muted-foreground\">No recent lifecycle events or command outcomes.</div>\n ) : (\n <div className=\"space-y-1\">\n {timeline.slice(0, 12).map((entry, index) => (\n <div key={`${entry.source}-${entry.ts}-${entry.kind}-${index}`} className=\"grid grid-cols-[5.5rem_5rem_1fr] gap-2 text-xs\">\n <span className=\"text-muted-foreground tabular-nums\">{timeAgo(now, entry.ts)}</span>\n <Badge variant=\"outline\" className=\"h-5 justify-center text-[10px]\">{entry.source}</Badge>\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium\" title={entry.title}>{entry.title}</div>\n {entry.detail && <div className=\"break-words text-muted-foreground\">{entry.detail.length > 160 ? entry.detail.slice(0, 160) + '...' : entry.detail}</div>}\n {typeof entry.metadata?.id === 'string' && <div className=\"font-mono text-[10px] text-muted-foreground\">command {entry.metadata.id}</div>}\n </div>\n </div>\n ))}\n </div>\n )}\n </Panel>\n\n {orchestrator && logSession && (\n <Panel title=\"Log Tail\" icon={<FileText className=\"h-3.5 w-3.5\" />}>\n <LogViewer orchestratorId={orchestrator.id} session={logSession} lines={120} />\n </Panel>\n )}\n </section>\n )\n}\n\nfunction managedAgentFor(item: ManagedPolicyHealth, orchestrator?: Orchestrator): ManagedAgent | undefined {\n return orchestrator?.managedAgents.find((m) =>\n m.policyName === item.policy.name ||\n (item.state.agentId && m.agentId === item.state.agentId) ||\n (item.state.spawnRequestId && m.spawnRequestId === item.state.spawnRequestId) ||\n (item.state.tmuxSession && (m.sessionName === item.state.tmuxSession || m.tmuxSession === item.state.tmuxSession))\n )\n}\n\nfunction logSessionFor(item: ManagedPolicyHealth, managedAgent?: ManagedAgent): string | undefined {\n return managedAgent?.terminalSession || managedAgent?.sessionName || managedAgent?.tmuxSession || item.state.tmuxSession\n}\n\nfunction latestExitDiagnostics(timeline: AgentTimelineEntry[], agent?: Agent): ManagedSessionExitDiagnostics | null {\n const fromAgent = exitDiagnostics(agent?.meta?.lastExit)\n if (fromAgent) return fromAgent\n for (const entry of timeline) {\n const exit = exitDiagnostics(entry.metadata?.lastExit)\n if (exit) return exit\n }\n return null\n}\n\nfunction exitDiagnostics(value: unknown): ManagedSessionExitDiagnostics | null {\n if (!isRecord(value) || typeof value.lastError !== 'string') return null\n const systemd = isRecord(value.systemd) ? value.systemd : undefined\n return {\n lastError: value.lastError,\n detectedAt: typeof value.detectedAt === 'number' ? value.detectedAt : undefined,\n runtimeMs: typeof value.runtimeMs === 'number' ? value.runtimeMs : undefined,\n logFile: typeof value.logFile === 'string' ? value.logFile : undefined,\n logBytes: typeof value.logBytes === 'number' ? value.logBytes : undefined,\n logEmpty: typeof value.logEmpty === 'boolean' ? value.logEmpty : undefined,\n logTail: Array.isArray(value.logTail) ? value.logTail.filter((line): line is string => typeof line === 'string') : undefined,\n systemd: systemd ? {\n unit: typeof systemd.unit === 'string' ? systemd.unit : undefined,\n activeState: typeof systemd.activeState === 'string' ? systemd.activeState : undefined,\n subState: typeof systemd.subState === 'string' ? systemd.subState : undefined,\n result: typeof systemd.result === 'string' ? systemd.result : undefined,\n } : undefined,\n unavailable: Array.isArray(value.unavailable) ? value.unavailable.filter((line): line is string => typeof line === 'string') : undefined,\n }\n}\n\ninterface ManagedSessionExitDiagnostics {\n lastError: string\n detectedAt?: number\n runtimeMs?: number\n logFile?: string\n logBytes?: number\n logEmpty?: boolean\n logTail?: string[]\n systemd?: {\n unit?: string\n activeState?: string\n subState?: string\n result?: string\n }\n unavailable?: string[]\n}\n\nfunction buildDiagnosticBundle(\n item: ManagedPolicyHealth,\n agent: Agent | undefined,\n orchestrator: Orchestrator | undefined,\n managedAgent: ManagedAgent | undefined,\n timeline: AgentTimelineEntry[],\n crashReport: CrashReport | null,\n lastExit: ManagedSessionExitDiagnostics | null,\n): string {\n const lines = [\n '# Managed Agent Diagnostics',\n `Policy: ${item.policy.name}`,\n `Lifecycle: ${item.state.status}`,\n `Provider: ${item.policy.provider}`,\n `CWD: ${item.policy.cwd}`,\n `Approval: ${item.policy.permissionMode}`,\n ]\n if (item.policy.model) lines.push(`Model: ${item.policy.model}`)\n if (item.policy.effort) lines.push(`Effort: ${item.policy.effort}`)\n if (item.policy.profile) lines.push(`Profile: ${item.policy.profile}`)\n if (item.policy.tags.length) lines.push(`Tags: ${item.policy.tags.join(', ')}`)\n if (item.policy.capabilities.length) lines.push(`Caps: ${item.policy.capabilities.join(', ')}`)\n if (agent) lines.push(`Agent: ${agent.id} (${agent.status})`)\n if (orchestrator) lines.push(`Orchestrator: ${orchestrator.hostname} (${orchestrator.id})`, `Orchestrator status: ${orchestrator.status}`)\n if (managedAgent) {\n lines.push('', '## Runtime')\n if (managedAgent.pid) lines.push(`PID: ${managedAgent.pid}`)\n if (managedAgent.supervisor) lines.push(`Supervisor: ${managedAgent.supervisor}`)\n if (managedAgent.systemdUnit) lines.push(`Systemd: ${managedAgent.systemdUnit}`)\n if (managedAgent.sessionName) lines.push(`Session: ${managedAgent.sessionName}`)\n if (managedAgent.terminalSession) lines.push(`Terminal: ${managedAgent.terminalSession} (${managedAgent.terminalAvailable ? 'available' : 'not attachable'})`)\n if (managedAgent.spawnRequestId) lines.push(`Spawn request: ${managedAgent.spawnRequestId}`)\n }\n if (item.state.lastError || crashReport || lastExit) {\n lines.push('', '## Post-Mortem')\n if (item.state.lastError) lines.push(`Last error: ${item.state.lastError}`)\n if (crashReport) lines.push(`Crash: ${crashReport.diagnosis.cause}/${crashReport.diagnosis.confidence} - ${crashReport.diagnosis.summary}`)\n if (lastExit?.lastError) lines.push(`Exit: ${lastExit.lastError}`)\n if (lastExit?.logTail?.length) lines.push('', 'Log tail:', ...lastExit.logTail.slice(-8))\n }\n if (timeline.length) {\n lines.push('', '## Recent Events')\n for (const entry of timeline.slice(0, 12)) {\n const commandId = typeof entry.metadata?.id === 'string' ? ` (${entry.metadata.id})` : ''\n lines.push(`- ${new Date(toTimestamp(entry.ts)).toISOString()} [${entry.source}] ${entry.title}${commandId}${entry.detail ? `: ${entry.detail}` : ''}`)\n }\n }\n return lines.join('\\n')\n}\n\nfunction Panel({ title, icon, children }: { title: string; icon: React.ReactNode; children: React.ReactNode }) {\n return (\n <div className=\"rounded-md border border-border p-2.5\">\n <h3 className=\"mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n {icon}\n {title}\n </h3>\n {children}\n </div>\n )\n}\n\nfunction KV({ label, value, className = '', mono = false }: { label: string; value: string; className?: string; mono?: boolean }) {\n return (\n <div className={`min-w-0 ${className}`}>\n <span className=\"text-muted-foreground\">{label}</span>\n <div className={`truncate ${mono ? 'font-mono' : ''}`} title={value}>{value}</div>\n </div>\n )\n}\n\nfunction Pills({ label, values }: { label: string; values: string[] }) {\n return (\n <div className=\"col-span-2\">\n <span className=\"text-muted-foreground\">{label}</span>\n <div className=\"mt-0.5 flex flex-wrap gap-1\">\n {values.map((value) => <Badge key={value} variant=\"outline\" className=\"text-[10px]\">{value}</Badge>)}\n </div>\n </div>\n )\n}\n\nfunction ErrorBlock({ title, body }: { title: string; body: string }) {\n return (\n <div className=\"rounded border border-red-500/20 bg-red-500/5 px-2 py-1.5\">\n <span className=\"text-muted-foreground\">{title}</span>\n <div className=\"mt-0.5 break-words text-red-300/80\">{body}</div>\n </div>\n )\n}\n","import { useEffect, useState } from 'react'\nimport { FileText, Pencil, Play, Plus, RotateCw, Square, Stethoscope, Terminal, Trash2 } from 'lucide-react'\nimport { useNow, useRelayStore } from '@/store'\nimport { Button } from '@/components/ui/button'\nimport { HealthBadge } from '@/components/shared/health-badge'\nimport { LogViewer } from '@/components/shared/log-viewer'\nimport { ManagedPolicyDiagnostics } from '@/components/shared/managed-policy-diagnostics'\nimport { TerminalDialog } from '@/components/shared/terminal-viewer'\nimport { fmtTime } from '@/lib/display'\nimport type { Agent, ManagedPolicyHealth } from '@/types'\n\nfunction terminalSessionFor(item: ManagedPolicyHealth, agent?: Agent): string | undefined {\n const agentSession = agent?.meta?.tmuxSession\n if (typeof agentSession === 'string' && agentSession.trim()) return agentSession\n return item.state.tmuxSession\n}\n\nfunction canReadTerminal(item: ManagedPolicyHealth, agent?: Agent): boolean {\n if (!terminalSessionFor(item, agent)) return false\n return Boolean(agent?.providerCapabilities?.terminal?.live?.read)\n}\n\nfunction canWriteTerminal(item: ManagedPolicyHealth, agent?: Agent): boolean {\n if (!canReadTerminal(item, agent)) return false\n return Boolean(agent?.providerCapabilities?.terminal?.live?.write)\n}\n\nexport function ManagedAgentsView() {\n const policies = useRelayStore((s) => s.managedPolicies)\n const agentsById = useRelayStore((s) => s.agentsById)\n const orchestrators = useRelayStore((s) => s.orchestrators)\n const fetchManagedPolicies = useRelayStore((s) => s.fetchManagedPolicies)\n const fetchOrchestrators = useRelayStore((s) => s.fetchOrchestrators)\n const apiCall = useRelayStore((s) => s.apiCall)\n const openPolicyCreate = useRelayStore((s) => s.openPolicyCreate)\n const openPolicyEdit = useRelayStore((s) => s.openPolicyEdit)\n const deletePolicy = useRelayStore((s) => s.deletePolicy)\n const now = useNow()\n const [logsFor, setLogsFor] = useState<ManagedPolicyHealth | null>(null)\n const [terminalFor, setTerminalFor] = useState<{ item: ManagedPolicyHealth; session: string } | null>(null)\n const [diagnosticsFor, setDiagnosticsFor] = useState<string | null>(null)\n\n useEffect(() => {\n void Promise.all([fetchManagedPolicies(), fetchOrchestrators()])\n }, [])\n\n async function lifecycle(name: string, action: 'start' | 'stop' | 'restart') {\n await apiCall('POST', `/spawn-policy/${encodeURIComponent(name)}/${action}`, { surface: { component: 'managed-agents' } })\n await fetchManagedPolicies()\n }\n\n const diagnosticsItem = diagnosticsFor ? policies.find((item) => item.policy.name === diagnosticsFor) ?? null : null\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Managed Agents</h1>\n <p className=\"text-sm text-muted-foreground\">Spawn policies, lifecycle state, and headless session logs.</p>\n </div>\n <Button onClick={openPolicyCreate} size=\"sm\">\n <Plus className=\"h-4 w-4 mr-1\" />\n Create Policy\n </Button>\n </div>\n\n {policies.length === 0 && (\n <div className=\"rounded-md border border-border px-3 py-8 text-center text-sm text-muted-foreground\">\n No managed agents configured\n </div>\n )}\n\n <div className=\"grid gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {policies.map((item) => {\n const agent = item.state.agentId ? agentsById[item.state.agentId] : undefined\n const terminalSession = terminalSessionFor(item, agent)\n return (\n <div key={item.policy.name} className=\"rounded-md border border-border bg-card p-3 space-y-2\">\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"font-medium text-sm truncate\">{item.policy.label || item.policy.name}</div>\n <div className=\"text-xs text-muted-foreground truncate\">{item.policy.mode} · {item.policy.cwd}</div>\n </div>\n <HealthBadge status={item.state.status} />\n </div>\n\n <div className=\"grid grid-cols-2 gap-x-4 gap-y-1 text-xs\">\n <div className=\"text-muted-foreground\">Provider</div>\n <div>{item.policy.provider}</div>\n <div className=\"text-muted-foreground\">Agent</div>\n <div className=\"font-mono truncate\">{item.state.agentId || '-'}</div>\n <div className=\"text-muted-foreground\">Restarts</div>\n <div>{item.state.restartCount}</div>\n {(item.state.backoffUntil || item.state.lastError) && (\n <>\n <div className=\"text-muted-foreground\">{item.state.backoffUntil ? 'Backoff' : 'Error'}</div>\n <div className=\"truncate\">{item.state.backoffUntil ? fmtTime(item.state.backoffUntil) : item.state.lastError}</div>\n </>\n )}\n </div>\n\n <div className=\"flex flex-wrap gap-1 pt-1 border-t border-border\">\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'start')} title=\"Start\"><Play className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'stop')} title=\"Stop\"><Square className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => lifecycle(item.policy.name, 'restart')} title=\"Restart\"><RotateCw className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => setLogsFor(item)} disabled={!item.state.tmuxSession} title=\"Logs\"><FileText className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => terminalSession && setTerminalFor({ item, session: terminalSession })} disabled={!canReadTerminal(item, agent)} title=\"Terminal\"><Terminal className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant={diagnosticsFor === item.policy.name ? 'secondary' : 'outline'} className=\"h-7 w-7\" onClick={() => setDiagnosticsFor((current) => current === item.policy.name ? null : item.policy.name)} title=\"Diagnostics\"><Stethoscope className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => openPolicyEdit(item.policy)} title=\"Edit\"><Pencil className=\"h-3.5 w-3.5\" /></Button>\n <Button size=\"icon\" variant=\"outline\" className=\"h-7 w-7\" onClick={() => deletePolicy(item.policy.name)} title=\"Delete\"><Trash2 className=\"h-3.5 w-3.5\" /></Button>\n </div>\n </div>\n )\n })}\n </div>\n\n {diagnosticsItem && (\n <ManagedPolicyDiagnostics\n item={diagnosticsItem}\n agent={diagnosticsItem.state.agentId ? agentsById[diagnosticsItem.state.agentId] : undefined}\n orchestrators={orchestrators}\n now={now}\n onClose={() => setDiagnosticsFor(null)}\n />\n )}\n\n {logsFor?.state.tmuxSession && (\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold\">{logsFor.policy.name} Logs</h2>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setLogsFor(null)}>Close</Button>\n </div>\n <LogViewer orchestratorId={logsFor.policy.orchestratorId} session={logsFor.state.tmuxSession} />\n </div>\n )}\n\n <TerminalDialog\n open={!!terminalFor}\n onOpenChange={(open) => { if (!open) setTerminalFor(null) }}\n orchestratorId={terminalFor?.item.policy.orchestratorId ?? ''}\n session={terminalFor?.session ?? ''}\n interactive={terminalFor ? canWriteTerminal(terminalFor.item, terminalFor.item.state.agentId ? agentsById[terminalFor.item.state.agentId] : undefined) : false}\n canWrite={terminalFor ? canWriteTerminal(terminalFor.item, terminalFor.item.state.agentId ? agentsById[terminalFor.item.state.agentId] : undefined) : false}\n />\n </div>\n )\n}\n"],"mappings":"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"}
|
package/public/assets/{markdown-preview-impl-Cx7pCfA6.js → markdown-preview-impl-BuOn5-Uc.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
2
|
-
//# sourceMappingURL=markdown-preview-impl-
|
|
1
|
+
import{rr as e}from"./lucide-react-CoU_Xts2.js";import{dt as t,ft as n}from"./index-DnUo0Zqg.js";import{i as r,n as i,r as a,t as o}from"./lib-BcUW1l-W.js";var s=e(),c={...a,attributes:{...a.attributes,code:[...a.attributes?.code||[],[`className`,/^language-[\w-]+$/]]}};function l(e){return!e||!/^https?:\/\//i.test(e)?{}:{target:`_blank`,rel:`noreferrer`}}function u({content:e,path:a}){return(0,s.jsx)(`div`,{className:`markdown-preview max-w-none overflow-hidden p-4 text-sm leading-6`,children:(0,s.jsx)(r,{remarkPlugins:[o],rehypePlugins:[[i,c]],components:{a({href:e,children:t}){return(0,s.jsx)(`a`,{href:e,...l(e),children:t})},img({src:e,alt:n}){return e?(0,s.jsx)(t,{src:e,alt:n,className:`max-w-full`}):null},code({className:e,children:t,...r}){let i=/language-([\w-]+)/.exec(e||``),o=String(t).replace(/\n$/,``);return i?(0,s.jsx)(n,{content:o,path:`${a}.${i[1]}`,languageHint:i[1],compact:!0}):(0,s.jsx)(`code`,{className:e,...r,children:t})}},children:e})})}export{u as MarkdownPreview};
|
|
2
|
+
//# sourceMappingURL=markdown-preview-impl-BuOn5-Uc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-preview-impl-
|
|
1
|
+
{"version":3,"file":"markdown-preview-impl-BuOn5-Uc.js","names":[],"sources":["../../dashboard/src/components/shared/markdown-preview-impl.tsx"],"sourcesContent":["import ReactMarkdown from 'react-markdown'\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize'\nimport remarkGfm from 'remark-gfm'\nimport { CodePreview } from './code-preview'\nimport { ZoomableImage } from './zoomable-image'\n\nconst markdownSchema = {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n code: [\n ...(defaultSchema.attributes?.code || []),\n ['className', /^language-[\\w-]+$/],\n ],\n },\n}\n\nfunction externalLinkProps(href?: string) {\n if (!href || !/^https?:\\/\\//i.test(href)) return {}\n return { target: '_blank', rel: 'noreferrer' }\n}\n\nexport interface MarkdownPreviewProps { content: string; path: string }\n\nexport function MarkdownPreview({ content, path }: MarkdownPreviewProps) {\n return (\n <div className=\"markdown-preview max-w-none overflow-hidden p-4 text-sm leading-6\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n rehypePlugins={[[rehypeSanitize, markdownSchema]]}\n components={{\n a({ href, children }) {\n return (\n <a href={href} {...externalLinkProps(href)}>\n {children}\n </a>\n )\n },\n img({ src, alt }) {\n if (!src) return null\n return <ZoomableImage src={src} alt={alt} className=\"max-w-full\" />\n },\n code({ className, children, ...props }) {\n const match = /language-([\\w-]+)/.exec(className || '')\n const code = String(children).replace(/\\n$/, '')\n if (match) {\n return (\n <CodePreview\n content={code}\n path={`${path}.${match[1]}`}\n languageHint={match[1]}\n compact\n />\n )\n }\n return (\n <code className={className} {...props}>\n {children}\n </code>\n )\n },\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n )\n}\n"],"mappings":"sKAMM,EAAiB,CACrB,GAAG,EACH,WAAY,CACV,GAAG,EAAc,WACjB,KAAM,CACJ,GAAI,EAAc,YAAY,MAAQ,EAAE,CACxC,CAAC,YAAa,oBAAoB,CACnC,CACF,CACF,CAED,SAAS,EAAkB,EAAe,CAExC,MADI,CAAC,GAAQ,CAAC,gBAAgB,KAAK,EAAK,CAAS,EAAE,CAC5C,CAAE,OAAQ,SAAU,IAAK,aAAc,CAKhD,SAAgB,EAAgB,CAAE,UAAS,QAA8B,CACvE,OACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,8EACb,EAAA,EAAA,KAAC,EAAD,CACE,cAAe,CAAC,EAAU,CAC1B,cAAe,CAAC,CAAC,EAAgB,EAAe,CAAC,CACjD,WAAY,CACV,EAAE,CAAE,OAAM,YAAY,CACpB,OACE,EAAA,EAAA,KAAC,IAAD,CAAS,OAAM,GAAI,EAAkB,EAAK,CACvC,WACC,CAAA,EAGR,IAAI,CAAE,MAAK,OAAO,CAEhB,OADK,GACE,EAAA,EAAA,KAAC,EAAD,CAAoB,MAAU,MAAK,UAAU,aAAe,CAAA,CADlD,MAGnB,KAAK,CAAE,YAAW,WAAU,GAAG,GAAS,CACtC,IAAM,EAAQ,oBAAoB,KAAK,GAAa,GAAG,CACjD,EAAO,OAAO,EAAS,CAAC,QAAQ,MAAO,GAAG,CAWhD,OAVI,GAEA,EAAA,EAAA,KAAC,EAAD,CACE,QAAS,EACT,KAAM,GAAG,EAAK,GAAG,EAAM,KACvB,aAAc,EAAM,GACpB,QAAA,GACA,CAAA,EAIJ,EAAA,EAAA,KAAC,OAAD,CAAiB,YAAW,GAAI,EAC7B,WACI,CAAA,EAGZ,UAEA,EACa,CAAA,CACZ,CAAA"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./chunk-CilyBKbf.js";import{A as t,Fn as n,H as r,R as ee,g as te,gr as i,j as a,nn as ne,q as re,rr as o}from"./lucide-react-CoU_Xts2.js";import{p as ie,t as s}from"./store-zFLzd0Jd.js";import{K as c,d as ae,h as l}from"./display-GFbGUG0O.js";import{t as u}from"./badge-XEru6wto.js";import{t as d}from"./button-C3CQSr4p.js";import{t as f}from"./input-CXMbJ848.js";import{G as oe,W as se,vt as p}from"./index-DnUo0Zqg.js";import{o as m,r as h,s as g,t as _}from"./card-C5XTIPvq.js";var v=e(i(),1),y=o(),b=[`organization`,`role`,`project`,`task`,`interaction`,`agent`],ce=[`private`,`project`,`org`,`public`],le=[`public`,`normal`,`sensitive`,`secret`],x=[`reported`,`inferred`,`verified`];function S(){return{type:`project`,scope:`default`,title:``,content:``,tags:``,visibility:`project`,sensitivity:`normal`,confidence:`reported`,relevanceScore:`0.7`}}function C(e){return{type:e.type,scope:e.scope,title:e.title,content:e.content,tags:e.tags.join(`, `),visibility:e.visibility,sensitivity:e.sensitivity,confidence:e.confidence,relevanceScore:String(e.relevanceScore)}}function w(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function ue(e){let t={limit:100};e.type&&(t.type=e.type),e.scope.trim()&&(t.scope=e.scope.trim()),e.visibility&&(t.visibility=e.visibility);let n=w(e.tags);if(n.length&&(t.tags=n),e.minRelevance.trim()){let n=Number(e.minRelevance);Number.isFinite(n)&&(t.minRelevance=Math.max(0,Math.min(1,n)))}return t}function T(e){return e===`secret`?`bg-red-500/10 text-red-400 border-red-500/30`:e===`sensitive`?`bg-yellow-500/10 text-yellow-400 border-yellow-500/30`:e===`public`?`bg-blue-500/10 text-blue-400 border-blue-500/30`:`bg-zinc-500/10 text-zinc-400 border-zinc-500/30`}function E(e){return e>=.8?`text-emerald-400`:e>=.5?`text-yellow-400`:`text-zinc-400`}function D(e){return e?Object.entries(e).map(([e,t])=>`${e}=${Array.isArray(t)?t.join(` `):String(t)}`).join(` `):`default`}function de(e){return e.filter(e=>![`system`,`user`,`channel`].includes(e.kind||``))}function O(){let e=ie(),i=s(e=>e.agents),o=s(e=>e.memories),O=s(e=>e.memoryTotal),A=s(e=>e.memoryStats),j=s(e=>e.memoryBrokerInfo),M=s(e=>e.memoryFilters),N=s(e=>e.selectedMemoryId),pe=s(e=>e.memoryLoading),P=s(e=>e.set),me=s(e=>e.fetchMemories),he=s(e=>e.refreshMemory),F=s(e=>e.saveMemory),I=s(e=>e.deleteMemory),L=s(e=>e.injectMemory),R=o.find(e=>e.id===N),[z,B]=(0,v.useState)(`create`),[V,H]=(0,v.useState)(S),[U,W]=(0,v.useState)(``),[G,ge]=(0,v.useState)(`manual`),[K,_e]=(0,v.useState)(`1600`),[q,ve]=(0,v.useState)(`8`),[J,ye]=(0,v.useState)(``),Y=(0,v.useMemo)(()=>de(i),[i]);(0,v.useEffect)(()=>{!U&&Y[0]&&W(Y[0].id)},[Y,U]),(0,v.useEffect)(()=>{R&&z===`edit`&&H(C(R))},[R?.id,z]);let X=(0,v.useMemo)(()=>{let e=M.search.trim().toLowerCase();return e?o.filter(t=>[t.id,t.type,t.scope,t.title,t.content,...t.tags].some(t=>String(t).toLowerCase().includes(e))):o},[o,M.search]);function Z(e){P({memoryFilters:{...M,...e}})}async function be(){let e=Number(V.relevanceScore),t={title:V.title.trim(),content:V.content.trim(),tags:w(V.tags),visibility:V.visibility,sensitivity:V.sensitivity,confidence:V.confidence,relevanceScore:Number.isFinite(e)?Math.max(0,Math.min(1,e)):.7};if(z===`edit`&&R){await F(t,R.id);return}await F({...t,type:V.type,scope:V.scope.trim()}),B(`create`),H(S())}async function Q(e){if(!U)return;let t=await L({agentId:U,memoryIds:e,query:e?.length?void 0:ue(M),reason:G.trim()||`manual`,budget:{maxTokens:Math.max(200,Number(K)||1600),maxMemories:Math.max(1,Number(q)||8),priorityCutoff:3}});t?.command?.id&&ye(t.command.id)}function xe(){B(`create`),H(S())}function Se(){R&&(B(`edit`),H(C(R)))}let Ce=V.title.trim()&&V.content.trim()&&(z===`edit`||V.scope.trim()),$=D(j?.config);return(0,y.jsxs)(`div`,{className:`space-y-4`,children:[(0,y.jsxs)(`div`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,y.jsx)(n,{className:`w-5 h-5 text-muted-foreground`}),(0,y.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Memory`}),(0,y.jsx)(u,{variant:`secondary`,children:A?.total??O}),j&&(0,y.jsx)(u,{className:j.external?`bg-blue-500/15 text-blue-400 border-blue-500/30`:`bg-emerald-500/15 text-emerald-400 border-emerald-500/30`,children:j.type})]}),(0,y.jsxs)(d,{size:`sm`,variant:`outline`,className:`gap-1.5`,onClick:()=>he(),children:[(0,y.jsx)(ee,{className:`w-3.5 h-3.5 ${pe?`animate-spin`:``}`}),`Refresh`]})]}),(0,y.jsxs)(`div`,{className:`grid gap-3 xl:grid-cols-[1.2fr_0.8fr]`,children:[(0,y.jsxs)(_,{children:[(0,y.jsx)(m,{className:`py-3 px-4`,children:(0,y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,y.jsxs)(g,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,y.jsx)(ne,{className:`w-4 h-4 text-muted-foreground`}),`Broker`]}),j?.capabilities&&(0,y.jsx)(`div`,{className:`flex flex-wrap gap-1 justify-end`,children:Object.entries(j.capabilities).filter(([,e])=>!!e).map(([e])=>(0,y.jsx)(u,{variant:`outline`,className:`text-[10px] px-1.5 py-0`,children:e},e))})]})}),(0,y.jsxs)(h,{className:`px-4 pb-4 space-y-3`,children:[(0,y.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-5 gap-2`,children:[(0,y.jsx)(k,{label:`total`,value:A?.total??O}),(0,y.jsx)(k,{label:`project`,value:A?.byType?.project??0}),(0,y.jsx)(k,{label:`task`,value:A?.byType?.task??0}),(0,y.jsx)(k,{label:`agent`,value:A?.byType?.agent??0}),(0,y.jsx)(k,{label:`sensitive`,value:(A?.bySensitivity?.sensitive??0)+(A?.bySensitivity?.secret??0)})]}),(0,y.jsx)(`div`,{className:`font-mono text-xs text-muted-foreground truncate`,title:$,children:$})]})]}),(0,y.jsxs)(_,{children:[(0,y.jsx)(m,{className:`py-3 px-4`,children:(0,y.jsx)(g,{className:`text-sm font-medium`,children:`Inject`})}),(0,y.jsxs)(h,{className:`px-4 pb-4 space-y-2`,children:[(0,y.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-2`,children:[(0,y.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:U,onChange:e=>W(e.target.value),children:[(0,y.jsx)(`option`,{value:``,children:`Agent`}),Y.map(e=>(0,y.jsx)(`option`,{value:e.id,children:ae(e)},e.id))]}),(0,y.jsx)(f,{value:G,onChange:e=>ge(e.target.value),placeholder:`reason`}),(0,y.jsx)(f,{value:K,onChange:e=>_e(e.target.value),inputMode:`numeric`,placeholder:`tokens`}),(0,y.jsx)(f,{value:q,onChange:e=>ve(e.target.value),inputMode:`numeric`,placeholder:`memories`})]}),(0,y.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,y.jsxs)(d,{size:`sm`,className:`gap-1.5`,disabled:!U||!R,onClick:()=>R&&Q([R.id]),children:[(0,y.jsx)(t,{className:`w-3.5 h-3.5`}),`Selected`]}),(0,y.jsxs)(d,{size:`sm`,variant:`outline`,className:`gap-1.5`,disabled:!U,onClick:()=>Q(),children:[(0,y.jsx)(a,{className:`w-3.5 h-3.5`}),`Filtered`]}),J&&(0,y.jsx)(u,{variant:`outline`,className:`font-mono text-[10px]`,children:J})]})]})]})]}),(0,y.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-[minmax(0,1fr)_420px]`,children:[(0,y.jsxs)(`div`,{className:`space-y-3`,children:[(0,y.jsx)(_,{children:(0,y.jsx)(h,{className:`p-3`,children:(0,y.jsxs)(`div`,{className:`grid grid-cols-2 lg:grid-cols-6 gap-2`,children:[(0,y.jsx)(f,{className:`lg:col-span-2`,value:M.search,onChange:e=>Z({search:e.target.value}),placeholder:`Search visible memories`}),(0,y.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:M.type,onChange:e=>Z({type:e.target.value}),children:[(0,y.jsx)(`option`,{value:``,children:`All types`}),b.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))]}),(0,y.jsx)(f,{value:M.scope,onChange:e=>Z({scope:e.target.value}),placeholder:`scope`}),(0,y.jsx)(f,{value:M.tags,onChange:e=>Z({tags:e.target.value}),placeholder:`tags`}),(0,y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,y.jsx)(f,{value:M.minRelevance,onChange:e=>Z({minRelevance:e.target.value}),placeholder:`score`}),(0,y.jsx)(d,{size:`sm`,variant:`outline`,className:`h-8 px-2`,onClick:()=>me(),children:(0,y.jsx)(a,{className:`w-4 h-4`})})]})]})})}),(0,y.jsx)(oe,{className:`h-[calc(100dvh-24rem)] min-h-[360px]`,children:(0,y.jsxs)(`div`,{className:`space-y-2 pr-2`,children:[X.length===0&&(0,y.jsx)(`div`,{className:`text-center text-sm text-muted-foreground py-16`,children:`No memories`}),X.map(t=>(0,y.jsx)(fe,{memory:t,selected:t.id===N,now:e,onSelect:()=>P({selectedMemoryId:t.id})},t.id))]})})]}),(0,y.jsxs)(_,{children:[(0,y.jsx)(m,{className:`py-3 px-4`,children:(0,y.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,y.jsx)(g,{className:`text-sm font-medium`,children:z===`edit`?`Edit Memory`:`New Memory`}),(0,y.jsxs)(`div`,{className:`flex gap-1`,children:[(0,y.jsx)(d,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,onClick:xe,title:`New memory`,children:(0,y.jsx)(r,{className:`w-3.5 h-3.5`})}),(0,y.jsx)(d,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,onClick:Se,disabled:!R,title:`Edit selected`,children:(0,y.jsx)(re,{className:`w-3.5 h-3.5`})}),(0,y.jsx)(d,{size:`sm`,variant:`ghost`,className:`h-7 px-2 text-red-400 hover:text-red-300`,disabled:!R,onClick:()=>R&&I(R.id),title:`Delete selected`,children:(0,y.jsx)(te,{className:`w-3.5 h-3.5`})})]})]})}),(0,y.jsxs)(h,{className:`px-4 pb-4 space-y-3`,children:[R&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(`div`,{className:`space-y-2`,children:[(0,y.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[(0,y.jsx)(u,{variant:`secondary`,children:R.type}),(0,y.jsx)(u,{variant:`outline`,children:R.scope}),(0,y.jsx)(u,{className:T(R.sensitivity),children:R.sensitivity}),(0,y.jsx)(u,{variant:`outline`,className:E(R.relevanceScore),children:R.relevanceScore.toFixed(2)})]}),(0,y.jsxs)(`div`,{className:`text-xs text-muted-foreground`,title:l(R.updatedAt),children:[`updated `,c(e,R.updatedAt)]}),(0,y.jsx)(`p`,{className:`text-sm font-medium`,children:R.title}),(0,y.jsx)(`p`,{className:`text-xs text-muted-foreground whitespace-pre-wrap max-h-24 overflow-auto`,children:R.content})]}),(0,y.jsx)(p,{})]}),(0,y.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,y.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,disabled:z===`edit`,value:V.type,onChange:e=>H({...V,type:e.target.value}),children:b.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))}),(0,y.jsx)(f,{disabled:z===`edit`,value:V.scope,onChange:e=>H({...V,scope:e.target.value}),placeholder:`scope`}),(0,y.jsx)(f,{className:`col-span-2`,value:V.title,onChange:e=>H({...V,title:e.target.value}),placeholder:`title`}),(0,y.jsx)(se,{className:`col-span-2 min-h-32`,value:V.content,onChange:e=>H({...V,content:e.target.value}),placeholder:`content`}),(0,y.jsx)(f,{className:`col-span-2`,value:V.tags,onChange:e=>H({...V,tags:e.target.value}),placeholder:`tags`}),(0,y.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:V.visibility,onChange:e=>H({...V,visibility:e.target.value}),children:ce.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))}),(0,y.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:V.sensitivity,onChange:e=>H({...V,sensitivity:e.target.value}),children:le.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))}),(0,y.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:V.confidence,onChange:e=>H({...V,confidence:e.target.value}),children:x.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))}),(0,y.jsx)(f,{value:V.relevanceScore,onChange:e=>H({...V,relevanceScore:e.target.value}),inputMode:`decimal`,placeholder:`score`})]}),(0,y.jsx)(d,{size:`sm`,className:`w-full`,disabled:!Ce,onClick:be,children:z===`edit`?`Save memory`:`Create memory`})]})]})]})]})}function k({label:e,value:t}){return(0,y.jsxs)(`div`,{className:`rounded-md border border-border bg-muted/20 px-3 py-2`,children:[(0,y.jsx)(`div`,{className:`text-lg font-semibold tabular-nums`,children:t}),(0,y.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e})]})}function fe({memory:e,selected:t,now:n,onSelect:r}){return(0,y.jsx)(`button`,{onClick:r,className:`w-full text-left rounded-md border p-3 transition-colors ${t?`border-primary bg-primary/5`:`border-border bg-card hover:border-zinc-600`}`,children:(0,y.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,y.jsxs)(`div`,{className:`min-w-0`,children:[(0,y.jsxs)(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[(0,y.jsx)(u,{variant:`secondary`,className:`text-[10px]`,children:e.type}),(0,y.jsx)(u,{variant:`outline`,className:`text-[10px] font-mono`,children:e.scope}),(0,y.jsx)(u,{className:`text-[10px] ${T(e.sensitivity)}`,children:e.sensitivity})]}),(0,y.jsx)(`div`,{className:`font-medium text-sm mt-2 truncate`,children:e.title}),(0,y.jsx)(`div`,{className:`text-xs text-muted-foreground line-clamp-2 mt-1`,children:e.content}),e.tags.length>0&&(0,y.jsx)(`div`,{className:`flex gap-1 flex-wrap mt-2`,children:e.tags.slice(0,8).map(e=>(0,y.jsxs)(u,{variant:`outline`,className:`text-[10px] text-zinc-400`,children:[`#`,e]},e))})]}),(0,y.jsxs)(`div`,{className:`text-right shrink-0 space-y-1`,children:[(0,y.jsx)(`div`,{className:`text-sm font-semibold tabular-nums ${E(e.relevanceScore)}`,children:e.relevanceScore.toFixed(2)}),(0,y.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,title:l(e.updatedAt),children:c(n,e.updatedAt)}),e.accessCount>0&&(0,y.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.accessCount,` hits`]})]})]})})}export{O as MemoryView};
|
|
2
|
+
//# sourceMappingURL=memory-Qv0JN8CE.js.map
|