agent-relay-server 0.124.0 → 0.126.0
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 +9 -5
- package/public/assets/{MessageBubble-SQK8-Mzp.js → MessageBubble-B6YgulnX.js} +2 -2
- package/public/assets/{MessageBubble-SQK8-Mzp.js.map → MessageBubble-B6YgulnX.js.map} +1 -1
- package/public/assets/{PlanGraphPanel-CS-aow4S.js → PlanGraphPanel--DNxHn1T.js} +2 -2
- package/public/assets/{PlanGraphPanel-CS-aow4S.js.map → PlanGraphPanel--DNxHn1T.js.map} +1 -1
- package/public/assets/{activity-W31XvhC2.js → activity-Fo5aLYD6.js} +2 -2
- package/public/assets/{activity-W31XvhC2.js.map → activity-Fo5aLYD6.js.map} +1 -1
- package/public/assets/agent-profiles-C3p0xclG.js +2 -0
- package/public/assets/{agent-profiles-DXysA9To.js.map → agent-profiles-C3p0xclG.js.map} +1 -1
- package/public/assets/{agent-type-icon-BxUopALO.js → agent-type-icon-BmBR-9CH.js} +2 -2
- package/public/assets/{agent-type-icon-BxUopALO.js.map → agent-type-icon-BmBR-9CH.js.map} +1 -1
- package/public/assets/{agents-B5GRNRnN.js → agents-_GBQyF5b.js} +2 -2
- package/public/assets/{agents-B5GRNRnN.js.map → agents-_GBQyF5b.js.map} +1 -1
- package/public/assets/{analytics-DqAuUAwX.js → analytics-BZtRycyL.js} +2 -2
- package/public/assets/{analytics-DqAuUAwX.js.map → analytics-BZtRycyL.js.map} +1 -1
- package/public/assets/{automation-DYlgHYcb.js → automation-Cf_Ewi9f.js} +2 -2
- package/public/assets/{automation-DYlgHYcb.js.map → automation-Cf_Ewi9f.js.map} +1 -1
- package/public/assets/{badge-XEru6wto.js → badge-BCvp7LK3.js} +2 -2
- package/public/assets/{badge-XEru6wto.js.map → badge-BCvp7LK3.js.map} +1 -1
- package/public/assets/{branch-state-badge-Mf0Ow77K.js → branch-state-badge-Cscjqf-E.js} +2 -2
- package/public/assets/{branch-state-badge-Mf0Ow77K.js.map → branch-state-badge-Cscjqf-E.js.map} +1 -1
- package/public/assets/{button-C3CQSr4p.js → button-DyHjsHY3.js} +2 -2
- package/public/assets/{button-C3CQSr4p.js.map → button-DyHjsHY3.js.map} +1 -1
- package/public/assets/{card-C5XTIPvq.js → card-BoqYxpVW.js} +2 -2
- package/public/assets/{card-C5XTIPvq.js.map → card-BoqYxpVW.js.map} +1 -1
- package/public/assets/{channels-DVRkVeky.js → channels-DAtOnA6o.js} +2 -2
- package/public/assets/{channels-DVRkVeky.js.map → channels-DAtOnA6o.js.map} +1 -1
- package/public/assets/chat-BdbIWZpQ.js +2 -0
- package/public/assets/chat-BdbIWZpQ.js.map +1 -0
- package/public/assets/{connectors-Cqubkw9C.js → connectors-B2grC-hl.js} +2 -2
- package/public/assets/{connectors-Cqubkw9C.js.map → connectors-B2grC-hl.js.map} +1 -1
- package/public/assets/{copy-button-Bil2CjzT.js → copy-button-C67FUG3E.js} +2 -2
- package/public/assets/{copy-button-Bil2CjzT.js.map → copy-button-C67FUG3E.js.map} +1 -1
- package/public/assets/{display-GFbGUG0O.js → display-aTnwsqQh.js} +3 -3
- package/public/assets/{display-GFbGUG0O.js.map → display-aTnwsqQh.js.map} +1 -1
- package/public/assets/{dist-V3wu3BHw.js → dist-BD4Xc13v.js} +2 -2
- package/public/assets/{dist-V3wu3BHw.js.map → dist-BD4Xc13v.js.map} +1 -1
- package/public/assets/{dist-C5z05Vkz.js → dist-BFDfbfNC.js} +2 -2
- package/public/assets/{dist-C5z05Vkz.js.map → dist-BFDfbfNC.js.map} +1 -1
- package/public/assets/{dist-CjyfQThq.js → dist-BJKxqIQd.js} +2 -2
- package/public/assets/{dist-CjyfQThq.js.map → dist-BJKxqIQd.js.map} +1 -1
- package/public/assets/{dist-B8tD9ZcR.js → dist-BNB3fTO-.js} +2 -2
- package/public/assets/{dist-B8tD9ZcR.js.map → dist-BNB3fTO-.js.map} +1 -1
- package/public/assets/{dist-CFtFIhu3.js → dist-CHKra2JV.js} +2 -2
- package/public/assets/{dist-CFtFIhu3.js.map → dist-CHKra2JV.js.map} +1 -1
- package/public/assets/{dist-r8wyUTkK.js → dist-CQMQ5iku.js} +2 -2
- package/public/assets/{dist-r8wyUTkK.js.map → dist-CQMQ5iku.js.map} +1 -1
- package/public/assets/{dist-DKmTXfpP.js → dist-C_VOBSaK.js} +2 -2
- package/public/assets/{dist-DKmTXfpP.js.map → dist-C_VOBSaK.js.map} +1 -1
- package/public/assets/{dist-CGaHpxnN.js → dist-D5w04z0l.js} +2 -2
- package/public/assets/{dist-CGaHpxnN.js.map → dist-D5w04z0l.js.map} +1 -1
- package/public/assets/{dist-4VwhnLtj.js → dist-DG75bvPp.js} +2 -2
- package/public/assets/{dist-4VwhnLtj.js.map → dist-DG75bvPp.js.map} +1 -1
- package/public/assets/{dist-CrUl2aQp.js → dist-G8YBD-wp.js} +2 -2
- package/public/assets/{dist-CrUl2aQp.js.map → dist-G8YBD-wp.js.map} +1 -1
- package/public/assets/{dist-BJaV2BD4.js → dist-f6MW74eX.js} +2 -2
- package/public/assets/{dist-BJaV2BD4.js.map → dist-f6MW74eX.js.map} +1 -1
- package/public/assets/{es2015-5DTJe35n.js → es2015-a6fysEVz.js} +2 -2
- package/public/assets/{es2015-5DTJe35n.js.map → es2015-a6fysEVz.js.map} +1 -1
- package/public/assets/{formatted-body-impl-L1EMnNW6.js → formatted-body-impl-gOLBKeyW.js} +2 -2
- package/public/assets/{formatted-body-impl-L1EMnNW6.js.map → formatted-body-impl-gOLBKeyW.js.map} +1 -1
- package/public/assets/formatted-body-jjhFXTap.js +3 -0
- package/public/assets/{formatted-body-BYQ-SPtj.js.map → formatted-body-jjhFXTap.js.map} +1 -1
- package/public/assets/index-CgH1BZwq.js +26 -0
- package/public/assets/index-CgH1BZwq.js.map +1 -0
- package/public/assets/index-DHzXsQot.css +2 -0
- package/public/assets/{input-CXMbJ848.js → input-Rc4oWv4q.js} +2 -2
- package/public/assets/{input-CXMbJ848.js.map → input-Rc4oWv4q.js.map} +1 -1
- package/public/assets/{insights-DwZxq1Dn.js → insights-CTW85An9.js} +2 -2
- package/public/assets/{insights-DwZxq1Dn.js.map → insights-CTW85An9.js.map} +1 -1
- package/public/assets/{integrations-9G5TJnnU.js → integrations-9c6IdRU4.js} +2 -2
- package/public/assets/{integrations-9G5TJnnU.js.map → integrations-9c6IdRU4.js.map} +1 -1
- package/public/assets/{lib-BcUW1l-W.js → lib-BZ6WPg2t.js} +2 -2
- package/public/assets/{lib-BcUW1l-W.js.map → lib-BZ6WPg2t.js.map} +1 -1
- package/public/assets/lucide-react-NXHPIMsX.js +10 -0
- package/public/assets/lucide-react-NXHPIMsX.js.map +1 -0
- package/public/assets/{maintenance-COcmUDnf.js → maintenance-D5PEygZz.js} +2 -2
- package/public/assets/{maintenance-COcmUDnf.js.map → maintenance-D5PEygZz.js.map} +1 -1
- package/public/assets/{managed-agents-D9-dgMeX.js → managed-agents-pkpAzZy8.js} +2 -2
- package/public/assets/{managed-agents-D9-dgMeX.js.map → managed-agents-pkpAzZy8.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-DH372bL-.js → markdown-preview-impl-DMzFE-Lo.js} +2 -2
- package/public/assets/{markdown-preview-impl-DH372bL-.js.map → markdown-preview-impl-DMzFE-Lo.js.map} +1 -1
- package/public/assets/{memory-B9hRK8sk.js → memory-BnquVYQz.js} +2 -2
- package/public/assets/{memory-B9hRK8sk.js.map → memory-BnquVYQz.js.map} +1 -1
- package/public/assets/{messages-BHkHlXzF.js → messages-DgxLlndC.js} +2 -2
- package/public/assets/{messages-BHkHlXzF.js.map → messages-DgxLlndC.js.map} +1 -1
- package/public/assets/{orchestrators-CXy3SDSn.js → orchestrators-BaWxeAlK.js} +2 -2
- package/public/assets/{orchestrators-CXy3SDSn.js.map → orchestrators-BaWxeAlK.js.map} +1 -1
- package/public/assets/{overview-D2yRyCQq.js → overview-Kvs-j2gg.js} +2 -2
- package/public/assets/{overview-D2yRyCQq.js.map → overview-Kvs-j2gg.js.map} +1 -1
- package/public/assets/{pairs-5tXdHylI.js → pairs-eDzbqcER.js} +2 -2
- package/public/assets/{pairs-5tXdHylI.js.map → pairs-eDzbqcER.js.map} +1 -1
- package/public/assets/{projects-CquHTMo1.js → projects-iDkxAGBW.js} +2 -2
- package/public/assets/{projects-CquHTMo1.js.map → projects-iDkxAGBW.js.map} +1 -1
- package/public/assets/{prompt-settings-Bn5mmi9w.js → prompt-settings-CjcqBG_r.js} +2 -2
- package/public/assets/{prompt-settings-Bn5mmi9w.js.map → prompt-settings-CjcqBG_r.js.map} +1 -1
- package/public/assets/{react-dom-BQICbUuF.js → react-dom-8yaD9iJG.js} +2 -2
- package/public/assets/{react-dom-BQICbUuF.js.map → react-dom-8yaD9iJG.js.map} +1 -1
- package/public/assets/{registry-C3sB7qv5.js → registry-C1DSnjjg.js} +2 -2
- package/public/assets/{registry-C3sB7qv5.js.map → registry-C1DSnjjg.js.map} +1 -1
- package/public/assets/{security-CmD-YE-_.js → security-VbEe_jwm.js} +2 -2
- package/public/assets/{security-CmD-YE-_.js.map → security-VbEe_jwm.js.map} +1 -1
- package/public/assets/{select-C0UlhK2k.js → select-CVfwgfKl.js} +2 -2
- package/public/assets/{select-C0UlhK2k.js.map → select-CVfwgfKl.js.map} +1 -1
- package/public/assets/{settings-DrqMG5nG.js → settings-ujA9hZW1.js} +4 -4
- package/public/assets/{settings-DrqMG5nG.js.map → settings-ujA9hZW1.js.map} +1 -1
- package/public/assets/store-D-Frk_EC.js +9 -0
- package/public/assets/store-D-Frk_EC.js.map +1 -0
- package/public/assets/{task-chip-BHM-e3I8.js → task-chip-CeujtXYT.js} +2 -2
- package/public/assets/{task-chip-BHM-e3I8.js.map → task-chip-CeujtXYT.js.map} +1 -1
- package/public/assets/{tasks-ChQjtXHu.js → tasks-BtbKaa-b.js} +2 -2
- package/public/assets/{tasks-ChQjtXHu.js.map → tasks-BtbKaa-b.js.map} +1 -1
- package/public/assets/{teams-itjNlDLp.js → teams-CrVDQ99v.js} +2 -2
- package/public/assets/{teams-itjNlDLp.js.map → teams-CrVDQ99v.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-B9M6s2vB.js → terminal-viewer-impl-Aays_e7-.js} +2 -2
- package/public/assets/{terminal-viewer-impl-B9M6s2vB.js.map → terminal-viewer-impl-Aays_e7-.js.map} +1 -1
- package/public/assets/{types-CRptbSYh.js → types-BqeSkWrv.js} +2 -2
- package/public/assets/types-BqeSkWrv.js.map +1 -0
- package/public/assets/{use-keyboard-viewport-CAa7IQTm.js → use-keyboard-viewport-cGEmrGE7.js} +2 -2
- package/public/assets/{use-keyboard-viewport-CAa7IQTm.js.map → use-keyboard-viewport-cGEmrGE7.js.map} +1 -1
- package/public/assets/{user-avatar-kYPfLgXp.js → user-avatar-qbo-B3dQ.js} +2 -2
- package/public/assets/{user-avatar-kYPfLgXp.js.map → user-avatar-qbo-B3dQ.js.map} +1 -1
- package/public/assets/{work-queue-Kw0uMkEF.js → work-queue-DDSGZO4Z.js} +2 -2
- package/public/assets/{work-queue-Kw0uMkEF.js.map → work-queue-DDSGZO4Z.js.map} +1 -1
- package/public/assets/{workspaces-CR6f7G0R.js → workspaces-CoDz-iZd.js} +2 -2
- package/public/assets/{workspaces-CR6f7G0R.js.map → workspaces-CoDz-iZd.js.map} +1 -1
- package/public/index.html +26 -26
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/relay-status.sh +11 -1
- package/runner/plugins/claude/hooks/stop.sh +6 -1
- package/runner/plugins/claude/hooks/user-prompt-submit.sh +6 -1
- package/runner/src/adapter.ts +5 -1
- package/runner/src/adapters/claude-transcript.ts +52 -58
- package/runner/src/adapters/codex-agent-message-capture.ts +33 -31
- package/runner/src/adapters/codex.ts +30 -12
- package/runner/src/control-server.ts +9 -4
- package/runner/src/response-capture-report.ts +4 -1
- package/runner/src/runner-core.ts +108 -46
- package/runner/src/runner-helpers.ts +31 -0
- package/src/agent-lifecycle-events.ts +8 -0
- package/src/bus.ts +0 -24
- package/src/db/agents.ts +15 -1
- package/src/db/messages.ts +150 -43
- package/src/maintenance/jobs.ts +8 -2
- package/src/mcp/tools-workspace.ts +4 -0
- package/src/routes/agent-sessions.ts +10 -7
- package/src/routes/agents.ts +0 -4
- package/src/routes/orchestrator.ts +5 -2
- package/src/routes/settings.ts +31 -2
- package/src/services/restart-instructions.ts +36 -0
- package/src/services/send-message.ts +7 -18
- package/src/services/shutdown-agent.ts +6 -0
- package/src/services/task-entity.ts +4 -0
- package/src/services/transient-agent-reaper.ts +40 -1
- package/src/services/work-finality.ts +25 -0
- package/src/settings/registry.ts +14 -3
- package/public/assets/agent-profiles-DXysA9To.js +0 -2
- package/public/assets/chat-Clz6qOtn.js +0 -2
- package/public/assets/chat-Clz6qOtn.js.map +0 -1
- package/public/assets/formatted-body-BYQ-SPtj.js +0 -3
- package/public/assets/index-0uIGXT14.js +0 -25
- package/public/assets/index-0uIGXT14.js.map +0 -1
- package/public/assets/index-DOJ7KidA.css +0 -2
- package/public/assets/lucide-react-CoU_Xts2.js +0 -10
- package/public/assets/lucide-react-CoU_Xts2.js.map +0 -1
- package/public/assets/store-zFLzd0Jd.js +0 -9
- package/public/assets/store-zFLzd0Jd.js.map +0 -1
- package/public/assets/types-CRptbSYh.js.map +0 -1
|
@@ -1,2 +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-
|
|
2
|
-
//# sourceMappingURL=maintenance-
|
|
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-NXHPIMsX.js";import{p as d,t as f}from"./store-D-Frk_EC.js";import{K as p,h as m}from"./display-aTnwsqQh.js";import{t as h}from"./badge-BCvp7LK3.js";import{t as g}from"./button-DyHjsHY3.js";import{G as _}from"./index-CgH1BZwq.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-D5PEygZz.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maintenance-COcmUDnf.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":"qYAUM,EAAuC,CAC3C,UAAW,2DACX,QAAS,kDACT,OAAQ,+CACR,KAAM,kDACN,SAAU,kDACX,CAED,SAAgB,GAAkB,CAChC,IAAM,EAAM,GAAQ,CACd,EAAO,EAAe,GAAM,EAAE,gBAAgB,CAC9C,EAAuB,EAAe,GAAM,EAAE,qBAAqB,CACnE,EAAoB,EAAe,GAAM,EAAE,kBAAkB,CAE7D,GAAA,EAAA,EAAA,cAIG,CAAE,OAHM,EAAK,OAAQ,GAAQ,EAAI,aAAe,SAAS,CAAC,OAGhD,QAFD,EAAK,OAAQ,GAAQ,EAAI,SAAW,EAAI,aAAe,UAAU,CAAC,OAExD,QADV,EAAK,OAAQ,GAAQ,EAAI,WAAa,EAAI,WAAa,EAAM,IAAS,IAAK,CAAC,OACzD,EAClC,CAAC,EAAM,EAAI,CAAC,CAEf,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qBAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,6DAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,2CAAf,EACE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,gCAAkC,CAAA,EACpD,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,cAAgB,CAAA,EACtD,EAAA,EAAA,KAAC,EAAD,CAAO,QAAQ,qBAAa,EAAK,OAAe,CAAA,CAC/C,EAAQ,QAAU,IAAK,EAAA,EAAA,MAAC,EAAD,CAAO,UAAU,kEAAjB,CAA2E,EAAQ,QAAQ,WAAgB,GAClI,EAAQ,OAAS,IAAK,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,uBAAf,CAA8B,EAAQ,OAAO,WAAgB,GACnF,EAAQ,QAAU,IAAK,EAAA,EAAA,MAAC,EAAD,CAAO,UAAU,wEAAjB,CAAiF,EAAQ,QAAQ,YAAiB,GACtI,IACN,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,YAAe,KAAK,GAAsB,UAA9E,EACE,EAAA,EAAA,KAAC,EAAD,CAAW,UAAU,cAAgB,CAAA,CAAA,WAC9B,GACL,IAEN,EAAA,EAAA,KAAC,EAAD,CAAY,UAAU,kCACnB,EAAK,SAAW,GACf,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gGAAuF,iCAAoC,CAAA,EAE1I,EAAA,EAAA,MAAA,EAAA,SAAA,CAAA,SAAA,EAEE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,4EACb,EAAA,EAAA,MAAC,QAAD,CAAO,UAAU,wCAAjB,EACE,EAAA,EAAA,KAAC,QAAD,CAAO,UAAU,sDACf,EAAA,EAAA,MAAC,KAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,MAAQ,CAAA,EACxD,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,SAAW,CAAA,EAC3D,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,WAAa,CAAA,EAC7D,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,WAAa,CAAA,EAC7D,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,WAAa,CAAA,EAC7D,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,2CAAkC,SAAW,CAAA,EAC3D,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,4CAAmC,SAAW,CAAA,CACzD,CAAA,CAAA,CACC,CAAA,EACR,EAAA,EAAA,KAAC,QAAD,CAAA,SACG,EAAK,IAAK,IACT,EAAA,EAAA,KAAC,EAAD,CAEO,MACA,MACL,UAAa,KAAK,EAAkB,EAAI,GAAG,CAC3C,CAJK,EAAI,GAIT,CACF,CACI,CAAA,CACF,GACJ,CAAA,EAGN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+BACZ,EAAK,IAAK,IACT,EAAA,EAAA,KAAC,EAAD,CAEO,MACA,MACL,UAAa,KAAK,EAAkB,EAAI,GAAG,CAC3C,CAJK,EAAI,GAIT,CACF,CACE,CAAA,CACL,CAAA,CAAA,CAEM,CAAA,CACT,GAIV,SAAS,EAAU,EAA6B,CAC9C,OAAO,EAAI,QAAU,UAAY,EAAI,QAAU,EAAI,WAAa,WAGlE,SAAS,EAAY,CAAE,UAA8B,CACnD,OACE,EAAA,EAAA,MAAC,EAAD,CAAO,QAAQ,UAAU,UAAW,EAAG,SAAU,EAAa,IAAW,EAAa,KAAK,UAA3F,CACG,EAAW,EAAO,CAClB,EACK,GAIZ,SAAS,EAAgB,CAAE,MAAK,MAAK,SAAkE,CACrG,IAAM,EAAS,EAAU,EAAI,CAC7B,OACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,+CAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,kDAAf,EACE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,mBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uBAAe,EAAI,MAAY,CAAA,EAC9C,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,gDAAwC,EAAI,YAAkB,CAAA,EAC7E,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+DAAuD,EAAI,GAAS,CAAA,CAC/E,IACN,EAAA,EAAA,KAAC,EAAD,CAAqB,SAAU,CAAA,CAC3B,GAEL,EAAI,oBAAsB,IACzB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,CAA4C,EAAI,oBAAoB,WAAS,EAAI,sBAAwB,EAAI,GAAK,IAAU,IAG9H,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,+CAAd,EACE,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,WAAa,CAAA,EACnD,EAAA,EAAA,KAAC,KAAD,CAAA,SAAK,EAAI,WAAY,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,EAAQ,EAAI,UAAU,UAAG,EAAQ,EAAK,EAAI,UAAU,CAAQ,CAAA,CAAG,QAAa,CAAA,CAC1G,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,WAAa,CAAA,EACnD,EAAA,EAAA,KAAC,KAAD,CAAA,SAAK,EAAI,WAAY,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,EAAQ,EAAI,UAAU,UAAG,EAAY,EAAK,EAAI,UAAU,CAAQ,CAAA,CAAG,IAAS,CAAA,CAC1G,CAAA,CAAA,EACN,EAAA,EAAA,MAAC,MAAD,CAAA,SAAA,EACE,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCAAwB,WAAa,CAAA,EACnD,EAAA,EAAA,KAAC,KAAD,CAAA,SAAK,EAAI,iBAAmB,IAAA,GAAwC,IAA5B,GAAG,EAAI,eAAe,IAAe,CAAA,CACzE,CAAA,CAAA,CACH,IAEL,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,gBAAf,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yCAAgC,SAAY,CAAA,CAC1D,EAAI,WACH,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,oDAA4C,EAAI,UAAgB,CAAA,EAE/E,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,2EAAmE,EAAc,EAAI,CAAO,CAAA,CAEzG,IAEN,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,kCACb,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,SAAU,CAAC,EAAI,SAAW,EAAI,QAAS,QAAS,WAApF,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,cAAgB,CAAA,CAAA,OACzB,GACL,CAAA,CACF,GAIV,SAAS,EAAe,CAAE,MAAK,MAAK,SAAkE,CACpG,IAAM,EAAS,EAAU,EAAI,CAC7B,OACE,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,4CAAd,EACE,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,qBAAd,EACE,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,uBAAe,EAAI,MAAY,CAAA,EAC9C,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,yDAAiD,EAAI,YAAkB,CAAA,EACtF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,+DAAuD,EAAI,GAAS,CAAA,CAChF,IACL,EAAA,EAAA,MAAC,KAAD,CAAI,UAAU,qBAAd,EACE,EAAA,EAAA,KAAC,EAAD,CAAqB,SAAU,CAAA,CAC9B,EAAI,oBAAsB,IACzB,EAAA,EAAA,MAAC,MAAD,CAAK,UAAU,qCAAf,CAA4C,EAAI,oBAAoB,WAAS,EAAI,sBAAwB,EAAI,GAAK,IAAU,GAE3H,IACL,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mDACX,EAAI,WACH,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,EAAQ,EAAI,UAAU,UAAG,EAAQ,EAAK,EAAI,UAAU,CAAQ,CAAA,CACvE,QACD,CAAA,EACL,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mDACX,EAAI,WACH,EAAA,EAAA,KAAC,OAAD,CAAM,MAAO,EAAQ,EAAI,UAAU,UAAG,EAAY,EAAK,EAAI,UAAU,CAAQ,CAAA,CAC3E,IACD,CAAA,EACL,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,mDACX,EAAI,iBAAmB,IAAA,GAAwC,IAA5B,GAAG,EAAI,eAAe,IACvD,CAAA,EACL,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,qBACX,EAAI,WACH,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,sDAA8C,EAAI,UAAgB,CAAA,EAEjF,EAAA,EAAA,KAAC,MAAD,CAAK,UAAU,6EAAqE,EAAc,EAAI,CAAO,CAAA,CAE5G,CAAA,EACL,EAAA,EAAA,KAAC,KAAD,CAAI,UAAU,iCACZ,EAAA,EAAA,MAAC,EAAD,CAAQ,KAAK,KAAK,QAAQ,UAAU,SAAU,CAAC,EAAI,SAAW,EAAI,QAAS,QAAS,WAApF,EACE,EAAA,EAAA,KAAC,EAAD,CAAM,UAAU,cAAgB,CAAA,CAAA,OACzB,GACN,CAAA,CACF,GAIT,SAAS,EAAW,EAAgB,CAIlC,OAHI,IAAW,aAAoB,EAAA,EAAA,KAAC,EAAD,CAAc,UAAU,eAAiB,CAAA,CACxE,IAAW,WAAkB,EAAA,EAAA,KAAC,EAAD,CAAU,UAAU,eAAiB,CAAA,CAClE,IAAW,UAAiB,EAAA,EAAA,KAAC,EAAD,CAAe,UAAU,eAAiB,CAAA,EACnE,EAAA,EAAA,KAAC,EAAD,CAAQ,UAAU,eAAiB,CAAA,CAG5C,SAAS,EAAc,EAA6B,CAClD,GAAI,CAAC,EAAI,WAAY,MAAO,IAC5B,IAAM,EAAU,OAAO,QAAQ,EAAI,WAAW,CAC3C,QAAQ,EAAG,KAAW,MAAM,QAAQ,EAAM,CAAG,EAAM,OAAS,EAAI,GAAiC,MAAQ,IAAU,EAAE,CACrH,KAAK,CAAC,EAAK,KAAW,GAAG,EAAI,IAAI,MAAM,QAAQ,EAAM,CAAG,EAAM,OAAS,OAAO,EAAM,GAAG,CAC1F,OAAO,EAAQ,OAAS,EAAQ,KAAK,KAAK,CAAG,aAG/C,SAAS,EAAY,EAAa,EAA2B,CAC3D,GAAI,GAAa,EAAK,MAAO,UAC7B,IAAM,EAAO,KAAK,IAAI,GAAI,EAAY,GAAO,IAAK,CAIlD,OAHI,EAAO,GAAW,MAAM,KAAK,KAAK,EAAK,CAAC,GACxC,EAAO,KAAa,MAAM,KAAK,KAAK,EAAO,GAAG,CAAC,GAC/C,EAAO,MAAc,MAAM,KAAK,KAAK,EAAO,KAAK,CAAC,GAC/C,MAAM,KAAK,KAAK,EAAO,MAAM,CAAC"}
|
|
1
|
+
{"version":3,"file":"maintenance-D5PEygZz.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{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-
|
|
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-NXHPIMsX.js";import{p as _,t as v}from"./store-D-Frk_EC.js";import{p as y}from"./types-BqeSkWrv.js";import{K as b,h as x,q as S}from"./display-aTnwsqQh.js";import{t as C}from"./badge-BCvp7LK3.js";import{t as w}from"./button-DyHjsHY3.js";import{t as T}from"./copy-button-C67FUG3E.js";import{$ as E,Q as D,et as O}from"./index-CgH1BZwq.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
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
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-
|
|
4
|
+
//# sourceMappingURL=managed-agents-pkpAzZy8.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-agents-D9-dgMeX.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-pkpAzZy8.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-DH372bL-.js → markdown-preview-impl-DMzFE-Lo.js}
RENAMED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{rr as e}from"./lucide-react-
|
|
2
|
-
//# sourceMappingURL=markdown-preview-impl-
|
|
1
|
+
import{rr as e}from"./lucide-react-NXHPIMsX.js";import{dt as t,ft as n}from"./index-CgH1BZwq.js";import{i as r,n as i,r as a,t as o}from"./lib-BZ6WPg2t.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-DMzFE-Lo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-preview-impl-
|
|
1
|
+
{"version":3,"file":"markdown-preview-impl-DMzFE-Lo.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"}
|
|
@@ -1,2 +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-0uIGXT14.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-
|
|
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-NXHPIMsX.js";import{p as ie,t as s}from"./store-D-Frk_EC.js";import{K as c,d as ae,h as l}from"./display-aTnwsqQh.js";import{t as u}from"./badge-BCvp7LK3.js";import{t as d}from"./button-DyHjsHY3.js";import{t as f}from"./input-Rc4oWv4q.js";import{G as oe,W as se,vt as p}from"./index-CgH1BZwq.js";import{o as m,r as h,s as g,t as _}from"./card-BoqYxpVW.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-BnquVYQz.js.map
|