agent-relay-server 0.75.0 → 0.76.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.
Files changed (58) hide show
  1. package/docs/openapi.json +1 -1
  2. package/package.json +2 -2
  3. package/public/assets/MessageBubble-DzhG1x8z.js +3 -0
  4. package/public/assets/{MessageBubble-opNe8Lu2.js.map → MessageBubble-DzhG1x8z.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-_mpO-kEh.js → PlanGraphPanel-brNJanGs.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-_mpO-kEh.js.map → PlanGraphPanel-brNJanGs.js.map} +1 -1
  7. package/public/assets/{activity-B079s-aD.js → activity-DIXJ-CVu.js} +2 -2
  8. package/public/assets/{activity-B079s-aD.js.map → activity-DIXJ-CVu.js.map} +1 -1
  9. package/public/assets/{agents-kkvfOptR.js → agents-BG9XZcVD.js} +2 -2
  10. package/public/assets/{agents-kkvfOptR.js.map → agents-BG9XZcVD.js.map} +1 -1
  11. package/public/assets/{automation-B4CAzi64.js → automation-jVNnsYV7.js} +2 -2
  12. package/public/assets/{automation-B4CAzi64.js.map → automation-jVNnsYV7.js.map} +1 -1
  13. package/public/assets/{chat-ZfR8BvTL.js → chat-B7EMdwIg.js} +2 -2
  14. package/public/assets/{chat-ZfR8BvTL.js.map → chat-B7EMdwIg.js.map} +1 -1
  15. package/public/assets/{formatted-body-impl-Bunmh796.js → formatted-body-impl-DBWLuF0p.js} +2 -2
  16. package/public/assets/{formatted-body-impl-Bunmh796.js.map → formatted-body-impl-DBWLuF0p.js.map} +1 -1
  17. package/public/assets/{index-DePqIpr0.js → index-DB6XGZy9.js} +5 -5
  18. package/public/assets/{index-DePqIpr0.js.map → index-DB6XGZy9.js.map} +1 -1
  19. package/public/assets/index-DepEqGST.css +2 -0
  20. package/public/assets/{insights-D9KEB80Q.js → insights-CzGE5EyU.js} +2 -2
  21. package/public/assets/{insights-D9KEB80Q.js.map → insights-CzGE5EyU.js.map} +1 -1
  22. package/public/assets/{maintenance-C0sGj_Na.js → maintenance-CGWGOhDP.js} +2 -2
  23. package/public/assets/{maintenance-C0sGj_Na.js.map → maintenance-CGWGOhDP.js.map} +1 -1
  24. package/public/assets/{managed-agents-BQq9EXOq.js → managed-agents-DyYn12ir.js} +2 -2
  25. package/public/assets/{managed-agents-BQq9EXOq.js.map → managed-agents-DyYn12ir.js.map} +1 -1
  26. package/public/assets/{markdown-preview-impl-B6xOjT1c.js → markdown-preview-impl-BA37v8OC.js} +2 -2
  27. package/public/assets/{markdown-preview-impl-B6xOjT1c.js.map → markdown-preview-impl-BA37v8OC.js.map} +1 -1
  28. package/public/assets/{memory-CB6zkEnm.js → memory-CoIM-761.js} +2 -2
  29. package/public/assets/{memory-CB6zkEnm.js.map → memory-CoIM-761.js.map} +1 -1
  30. package/public/assets/{messages-DhQjlDGk.js → messages-D-TOb6_t.js} +2 -2
  31. package/public/assets/{messages-DhQjlDGk.js.map → messages-D-TOb6_t.js.map} +1 -1
  32. package/public/assets/{orchestrators-Ze5VJVFK.js → orchestrators-XLGUAnKs.js} +2 -2
  33. package/public/assets/{orchestrators-Ze5VJVFK.js.map → orchestrators-XLGUAnKs.js.map} +1 -1
  34. package/public/assets/{overview-KxPTf_aQ.js → overview-C4Netp8S.js} +2 -2
  35. package/public/assets/{overview-KxPTf_aQ.js.map → overview-C4Netp8S.js.map} +1 -1
  36. package/public/assets/{pairs-CKAQN-Mp.js → pairs-1X219PK6.js} +2 -2
  37. package/public/assets/{pairs-CKAQN-Mp.js.map → pairs-1X219PK6.js.map} +1 -1
  38. package/public/assets/{security-BfN02cIU.js → security-CCfKm-ow.js} +2 -2
  39. package/public/assets/{security-BfN02cIU.js.map → security-CCfKm-ow.js.map} +1 -1
  40. package/public/assets/{select-2k89h2cU.js → select-BpPDknSO.js} +2 -2
  41. package/public/assets/{select-2k89h2cU.js.map → select-BpPDknSO.js.map} +1 -1
  42. package/public/assets/{settings-CxHa6IHI.js → settings-BUD05ZM3.js} +2 -2
  43. package/public/assets/{settings-CxHa6IHI.js.map → settings-BUD05ZM3.js.map} +1 -1
  44. package/public/assets/{tasks-B7S6eTJJ.js → tasks-Dvqe1bbe.js} +2 -2
  45. package/public/assets/{tasks-B7S6eTJJ.js.map → tasks-Dvqe1bbe.js.map} +1 -1
  46. package/public/assets/{teams-DPEBGRiy.js → teams-I0UCuF9H.js} +2 -2
  47. package/public/assets/{teams-DPEBGRiy.js.map → teams-I0UCuF9H.js.map} +1 -1
  48. package/public/assets/{terminal-viewer-impl-PeLYPKpp.js → terminal-viewer-impl-CKM8zVGQ.js} +2 -2
  49. package/public/assets/{terminal-viewer-impl-PeLYPKpp.js.map → terminal-viewer-impl-CKM8zVGQ.js.map} +1 -1
  50. package/public/assets/{work-queue-BI_d8G0U.js → work-queue-xWRsNNPk.js} +2 -2
  51. package/public/assets/{work-queue-BI_d8G0U.js.map → work-queue-xWRsNNPk.js.map} +1 -1
  52. package/public/index.html +2 -2
  53. package/src/lifecycle-context-pressure.ts +98 -0
  54. package/src/lifecycle-manager.ts +21 -31
  55. package/src/upgrade-local-id.ts +23 -0
  56. package/src/upgrade.ts +19 -27
  57. package/public/assets/MessageBubble-opNe8Lu2.js +0 -3
  58. package/public/assets/index-CQQTCZxg.css +0 -2
@@ -1,2 +1,2 @@
1
- import{Bn as e,an as t,ct as n,gn as r,i}from"./lucide-react-DI8kTavp.js";import{l as a,t as o}from"./store-D1K4_xId.js";import{U as s,d as c,ut as l}from"./display-DHgdn4vN.js";import{t as u}from"./badge-YQhT30dy.js";import{t as d}from"./button-CaFI76Ja.js";import{B as f,K as p,s as m}from"./index-DePqIpr0.js";import{r as h,t as g}from"./card-B_fQtKce.js";var _=e(),v={open:`bg-blue-500/10 text-blue-400 border-blue-500/20`,blocked:`bg-yellow-500/10 text-yellow-400 border-yellow-500/20`,claimed:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`,in_progress:`bg-purple-500/10 text-purple-400 border-purple-500/20`};function y(){let e=a(),t=o(e=>e.agentsById),r=o(e=>e.compose),i=o(e=>e.set),s=o(e=>e.doClaimTask),l=o(e=>e.doClaim),d=o(e=>e.openTaskEvents),h=o(e=>e.showError),g=o(e=>e.openConfirm),v=o(e=>e.doDeleteMessage),y=o(e=>e.doUpdateTaskStatus),x=f(),S=p(),C=S.filter(e=>e.claimable).length;function w(e){if(!r.from){h(`Validation`,`Select a "Claim as" agent first.`);return}e.sourceType===`task`&&e.task?s(e.task.id):e.sourceType===`message`&&e.message&&l(e.message.id)}function T(e){g(`Cancel Item`,`Cancel "${e.title||(e.sourceType===`task`?`Task #${e.id}`:`Message #${e.id}`)}"? This cannot be undone.`,()=>{e.sourceType===`task`&&e.task?y(e.task,`canceled`):e.sourceType===`message`&&e.message&&v(e.message.id)})}function E(e){e.task&&d(e.task)}return(0,_.jsxs)(`div`,{className:`space-y-4`,children:[(0,_.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-2`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(n,{className:`w-5 h-5 text-muted-foreground`}),(0,_.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Work Queue`}),C>0&&(0,_.jsxs)(u,{className:`bg-orange-500/20 text-orange-400 border-orange-500/30 border`,children:[C,` claimable`]})]}),(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(`label`,{className:`text-xs text-muted-foreground shrink-0`,children:`Claim as`}),(0,_.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-3 py-1.5 text-sm`,value:r.from,onChange:e=>i({compose:{...r,from:e.target.value}}),children:[(0,_.jsx)(`option`,{value:``,children:`Select agent...`}),x.map(e=>(0,_.jsx)(`option`,{value:e.id,children:c(e)},e.id))]})]})]}),(0,_.jsx)(m,{className:`h-[calc(100dvh-11rem)]`,children:(0,_.jsxs)(`div`,{className:`space-y-2 pr-2`,children:[S.length===0&&(0,_.jsx)(`div`,{className:`text-center text-muted-foreground py-16 text-sm`,children:`Work queue is empty`}),S.map(n=>(0,_.jsx)(b,{item:n,now:e,agentName:e=>t[e]?c(t[e]):e.slice(-10),onClaim:()=>w(n),onCancel:()=>T(n),onEvents:n.task?()=>E(n):void 0},n.id))]})})]})}function b({item:e,now:n,agentName:a,onClaim:o,onCancel:c,onEvents:f}){let p=l[e.severity]||l.info,m=v[e.status]||`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`;return(0,_.jsx)(g,{className:e.claimable?`ring-1 ring-orange-500/30`:``,children:(0,_.jsx)(h,{className:`p-3`,children:(0,_.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,_.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap mb-1`,children:[(0,_.jsx)(`span`,{className:`font-medium text-sm truncate`,children:e.title}),(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border ${p}`,children:e.severity}),(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border ${m}`,children:e.status}),e.sourceType===`message`&&(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border border-zinc-500/20 text-zinc-400`,children:`msg`})]}),e.body&&(0,_.jsx)(`p`,{className:`text-xs text-muted-foreground line-clamp-2 mb-2`,children:e.body}),(0,_.jsxs)(`div`,{className:`flex items-center gap-3 text-xs text-muted-foreground flex-wrap`,children:[e.owner&&(0,_.jsxs)(`span`,{title:`Owner`,children:[(0,_.jsx)(t,{className:`w-3 h-3 inline mr-1`}),a(e.owner)]}),e.source&&(0,_.jsx)(`span`,{className:`font-mono`,children:e.source}),(0,_.jsxs)(`span`,{title:String(e.updatedAt),children:[(0,_.jsx)(r,{className:`w-3 h-3 inline mr-1`}),s(n,e.updatedAt)]})]})]}),(0,_.jsxs)(`div`,{className:`flex flex-col gap-1 shrink-0`,children:[e.claimable&&(0,_.jsxs)(d,{size:`sm`,className:`h-7 text-xs bg-orange-600 hover:bg-orange-700 text-white`,onClick:o,children:[(0,_.jsx)(t,{className:`w-3.5 h-3.5 mr-1`}),` Claim`]}),f&&(0,_.jsx)(d,{size:`sm`,variant:`outline`,className:`h-7 text-xs`,onClick:f,children:`Events`}),(0,_.jsxs)(d,{size:`sm`,variant:`outline`,className:`h-7 text-xs text-red-400 hover:text-red-300 hover:bg-red-500/10 border-red-500/20`,onClick:c,children:[(0,_.jsx)(i,{className:`w-3.5 h-3.5 mr-1`}),` Cancel`]})]})]})})})}export{y as WorkQueueView};
2
- //# sourceMappingURL=work-queue-BI_d8G0U.js.map
1
+ import{Bn as e,an as t,ct as n,gn as r,i}from"./lucide-react-DI8kTavp.js";import{l as a,t as o}from"./store-D1K4_xId.js";import{U as s,d as c,ut as l}from"./display-DHgdn4vN.js";import{t as u}from"./badge-YQhT30dy.js";import{t as d}from"./button-CaFI76Ja.js";import{B as f,K as p,s as m}from"./index-DB6XGZy9.js";import{r as h,t as g}from"./card-B_fQtKce.js";var _=e(),v={open:`bg-blue-500/10 text-blue-400 border-blue-500/20`,blocked:`bg-yellow-500/10 text-yellow-400 border-yellow-500/20`,claimed:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`,in_progress:`bg-purple-500/10 text-purple-400 border-purple-500/20`};function y(){let e=a(),t=o(e=>e.agentsById),r=o(e=>e.compose),i=o(e=>e.set),s=o(e=>e.doClaimTask),l=o(e=>e.doClaim),d=o(e=>e.openTaskEvents),h=o(e=>e.showError),g=o(e=>e.openConfirm),v=o(e=>e.doDeleteMessage),y=o(e=>e.doUpdateTaskStatus),x=f(),S=p(),C=S.filter(e=>e.claimable).length;function w(e){if(!r.from){h(`Validation`,`Select a "Claim as" agent first.`);return}e.sourceType===`task`&&e.task?s(e.task.id):e.sourceType===`message`&&e.message&&l(e.message.id)}function T(e){g(`Cancel Item`,`Cancel "${e.title||(e.sourceType===`task`?`Task #${e.id}`:`Message #${e.id}`)}"? This cannot be undone.`,()=>{e.sourceType===`task`&&e.task?y(e.task,`canceled`):e.sourceType===`message`&&e.message&&v(e.message.id)})}function E(e){e.task&&d(e.task)}return(0,_.jsxs)(`div`,{className:`space-y-4`,children:[(0,_.jsxs)(`div`,{className:`flex items-center justify-between flex-wrap gap-2`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(n,{className:`w-5 h-5 text-muted-foreground`}),(0,_.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Work Queue`}),C>0&&(0,_.jsxs)(u,{className:`bg-orange-500/20 text-orange-400 border-orange-500/30 border`,children:[C,` claimable`]})]}),(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,_.jsx)(`label`,{className:`text-xs text-muted-foreground shrink-0`,children:`Claim as`}),(0,_.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-3 py-1.5 text-sm`,value:r.from,onChange:e=>i({compose:{...r,from:e.target.value}}),children:[(0,_.jsx)(`option`,{value:``,children:`Select agent...`}),x.map(e=>(0,_.jsx)(`option`,{value:e.id,children:c(e)},e.id))]})]})]}),(0,_.jsx)(m,{className:`h-[calc(100dvh-11rem)]`,children:(0,_.jsxs)(`div`,{className:`space-y-2 pr-2`,children:[S.length===0&&(0,_.jsx)(`div`,{className:`text-center text-muted-foreground py-16 text-sm`,children:`Work queue is empty`}),S.map(n=>(0,_.jsx)(b,{item:n,now:e,agentName:e=>t[e]?c(t[e]):e.slice(-10),onClaim:()=>w(n),onCancel:()=>T(n),onEvents:n.task?()=>E(n):void 0},n.id))]})})]})}function b({item:e,now:n,agentName:a,onClaim:o,onCancel:c,onEvents:f}){let p=l[e.severity]||l.info,m=v[e.status]||`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`;return(0,_.jsx)(g,{className:e.claimable?`ring-1 ring-orange-500/30`:``,children:(0,_.jsx)(h,{className:`p-3`,children:(0,_.jsxs)(`div`,{className:`flex items-start gap-3`,children:[(0,_.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap mb-1`,children:[(0,_.jsx)(`span`,{className:`font-medium text-sm truncate`,children:e.title}),(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border ${p}`,children:e.severity}),(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border ${m}`,children:e.status}),e.sourceType===`message`&&(0,_.jsx)(u,{variant:`outline`,className:`text-xs px-1.5 py-0 border border-zinc-500/20 text-zinc-400`,children:`msg`})]}),e.body&&(0,_.jsx)(`p`,{className:`text-xs text-muted-foreground line-clamp-2 mb-2`,children:e.body}),(0,_.jsxs)(`div`,{className:`flex items-center gap-3 text-xs text-muted-foreground flex-wrap`,children:[e.owner&&(0,_.jsxs)(`span`,{title:`Owner`,children:[(0,_.jsx)(t,{className:`w-3 h-3 inline mr-1`}),a(e.owner)]}),e.source&&(0,_.jsx)(`span`,{className:`font-mono`,children:e.source}),(0,_.jsxs)(`span`,{title:String(e.updatedAt),children:[(0,_.jsx)(r,{className:`w-3 h-3 inline mr-1`}),s(n,e.updatedAt)]})]})]}),(0,_.jsxs)(`div`,{className:`flex flex-col gap-1 shrink-0`,children:[e.claimable&&(0,_.jsxs)(d,{size:`sm`,className:`h-7 text-xs bg-orange-600 hover:bg-orange-700 text-white`,onClick:o,children:[(0,_.jsx)(t,{className:`w-3.5 h-3.5 mr-1`}),` Claim`]}),f&&(0,_.jsx)(d,{size:`sm`,variant:`outline`,className:`h-7 text-xs`,onClick:f,children:`Events`}),(0,_.jsxs)(d,{size:`sm`,variant:`outline`,className:`h-7 text-xs text-red-400 hover:text-red-300 hover:bg-red-500/10 border-red-500/20`,onClick:c,children:[(0,_.jsx)(i,{className:`w-3.5 h-3.5 mr-1`}),` Cancel`]})]})]})})})}export{y as WorkQueueView};
2
+ //# sourceMappingURL=work-queue-xWRsNNPk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"work-queue-BI_d8G0U.js","names":[],"sources":["../../dashboard/src/components/views/work-queue.tsx"],"sourcesContent":["import { useRelayStore, useNow } from '@/store'\nimport { useWorkQueueItems, useComposeAgents } from '@/hooks/use-selectors'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { ListChecks, CheckCircle2, Calendar, X } from 'lucide-react'\nimport { displayName, timeAgo } from '@/lib/display'\nimport { SEVERITY_COLORS } from '@/lib/constants'\nimport type { WorkQueueItem } from '@/types'\n\nconst STATUS_COLORS: Record<string, string> = {\n open: 'bg-blue-500/10 text-blue-400 border-blue-500/20',\n blocked: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',\n claimed: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',\n in_progress: 'bg-purple-500/10 text-purple-400 border-purple-500/20',\n}\n\nexport function WorkQueueView() {\n const now = useNow()\n const agentsById = useRelayStore((s) => s.agentsById)\n const compose = useRelayStore((s) => s.compose)\n const set = useRelayStore((s) => s.set)\n const doClaimTask = useRelayStore((s) => s.doClaimTask)\n const doClaim = useRelayStore((s) => s.doClaim)\n const openTaskEvents = useRelayStore((s) => s.openTaskEvents)\n const showError = useRelayStore((s) => s.showError)\n const openConfirm = useRelayStore((s) => s.openConfirm)\n const doDeleteMessage = useRelayStore((s) => s.doDeleteMessage)\n const doUpdateTaskStatus = useRelayStore((s) => s.doUpdateTaskStatus)\n\n const composeAgents = useComposeAgents()\n const items = useWorkQueueItems()\n\n const claimableCount = items.filter((i) => i.claimable).length\n\n function handleClaim(item: WorkQueueItem) {\n if (!compose.from) { showError('Validation', 'Select a \"Claim as\" agent first.'); return }\n if (item.sourceType === 'task' && item.task) doClaimTask(item.task.id)\n else if (item.sourceType === 'message' && item.message) doClaim(item.message.id)\n }\n\n function handleCancel(item: WorkQueueItem) {\n const label = item.title || (item.sourceType === 'task' ? `Task #${item.id}` : `Message #${item.id}`)\n openConfirm('Cancel Item', `Cancel \"${label}\"? This cannot be undone.`, () => {\n if (item.sourceType === 'task' && item.task) doUpdateTaskStatus(item.task, 'canceled')\n else if (item.sourceType === 'message' && item.message) doDeleteMessage(item.message.id)\n })\n }\n\n function handleEvents(item: WorkQueueItem) {\n if (item.task) openTaskEvents(item.task)\n }\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\">\n <ListChecks className=\"w-5 h-5 text-muted-foreground\" />\n <h2 className=\"text-lg font-semibold\">Work Queue</h2>\n {claimableCount > 0 && (\n <Badge className=\"bg-orange-500/20 text-orange-400 border-orange-500/30 border\">\n {claimableCount} claimable\n </Badge>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-muted-foreground shrink-0\">Claim as</label>\n <select\n className=\"rounded-md border border-input bg-background px-3 py-1.5 text-sm\"\n value={compose.from}\n onChange={(e) => set({ compose: { ...compose, from: e.target.value } })}\n >\n <option value=\"\">Select agent...</option>\n {composeAgents.map((a) => <option key={a.id} value={a.id}>{displayName(a)}</option>)}\n </select>\n </div>\n </div>\n\n <ScrollArea className=\"h-[calc(100dvh-11rem)]\">\n <div className=\"space-y-2 pr-2\">\n {items.length === 0 && (\n <div className=\"text-center text-muted-foreground py-16 text-sm\">Work queue is empty</div>\n )}\n {items.map((item) => (\n <WorkQueueCard\n key={item.id}\n item={item}\n now={now}\n agentName={(id) => agentsById[id] ? displayName(agentsById[id]) : id.slice(-10)}\n onClaim={() => handleClaim(item)}\n onCancel={() => handleCancel(item)}\n onEvents={item.task ? () => handleEvents(item) : undefined}\n />\n ))}\n </div>\n </ScrollArea>\n </div>\n )\n}\n\nfunction WorkQueueCard({\n item, now, agentName, onClaim, onCancel, onEvents,\n}: {\n item: WorkQueueItem\n now: number\n agentName: (id: string) => string\n onClaim: () => void\n onCancel: () => void\n onEvents?: () => void\n}) {\n const severityClass = SEVERITY_COLORS[item.severity] || SEVERITY_COLORS.info\n const statusClass = STATUS_COLORS[item.status] || 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20'\n\n return (\n <Card className={item.claimable ? 'ring-1 ring-orange-500/30' : ''}>\n <CardContent className=\"p-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap mb-1\">\n <span className=\"font-medium text-sm truncate\">{item.title}</span>\n <Badge variant=\"outline\" className={`text-xs px-1.5 py-0 border ${severityClass}`}>{item.severity}</Badge>\n <Badge variant=\"outline\" className={`text-xs px-1.5 py-0 border ${statusClass}`}>{item.status}</Badge>\n {item.sourceType === 'message' && (\n <Badge variant=\"outline\" className=\"text-xs px-1.5 py-0 border border-zinc-500/20 text-zinc-400\">msg</Badge>\n )}\n </div>\n {item.body && (\n <p className=\"text-xs text-muted-foreground line-clamp-2 mb-2\">{item.body}</p>\n )}\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground flex-wrap\">\n {item.owner && (\n <span title=\"Owner\">\n <CheckCircle2 className=\"w-3 h-3 inline mr-1\" />{agentName(item.owner)}\n </span>\n )}\n {item.source && (\n <span className=\"font-mono\">{item.source}</span>\n )}\n <span title={String(item.updatedAt)}>\n <Calendar className=\"w-3 h-3 inline mr-1\" />{timeAgo(now, item.updatedAt)}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col gap-1 shrink-0\">\n {item.claimable && (\n <Button size=\"sm\" className=\"h-7 text-xs bg-orange-600 hover:bg-orange-700 text-white\" onClick={onClaim}>\n <CheckCircle2 className=\"w-3.5 h-3.5 mr-1\" /> Claim\n </Button>\n )}\n {onEvents && (\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs\" onClick={onEvents}>\n Events\n </Button>\n )}\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs text-red-400 hover:text-red-300 hover:bg-red-500/10 border-red-500/20\" onClick={onCancel}>\n <X className=\"w-3.5 h-3.5 mr-1\" /> Cancel\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"work-queue-xWRsNNPk.js","names":[],"sources":["../../dashboard/src/components/views/work-queue.tsx"],"sourcesContent":["import { useRelayStore, useNow } from '@/store'\nimport { useWorkQueueItems, useComposeAgents } from '@/hooks/use-selectors'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { ScrollArea } from '@/components/ui/scroll-area'\nimport { ListChecks, CheckCircle2, Calendar, X } from 'lucide-react'\nimport { displayName, timeAgo } from '@/lib/display'\nimport { SEVERITY_COLORS } from '@/lib/constants'\nimport type { WorkQueueItem } from '@/types'\n\nconst STATUS_COLORS: Record<string, string> = {\n open: 'bg-blue-500/10 text-blue-400 border-blue-500/20',\n blocked: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',\n claimed: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',\n in_progress: 'bg-purple-500/10 text-purple-400 border-purple-500/20',\n}\n\nexport function WorkQueueView() {\n const now = useNow()\n const agentsById = useRelayStore((s) => s.agentsById)\n const compose = useRelayStore((s) => s.compose)\n const set = useRelayStore((s) => s.set)\n const doClaimTask = useRelayStore((s) => s.doClaimTask)\n const doClaim = useRelayStore((s) => s.doClaim)\n const openTaskEvents = useRelayStore((s) => s.openTaskEvents)\n const showError = useRelayStore((s) => s.showError)\n const openConfirm = useRelayStore((s) => s.openConfirm)\n const doDeleteMessage = useRelayStore((s) => s.doDeleteMessage)\n const doUpdateTaskStatus = useRelayStore((s) => s.doUpdateTaskStatus)\n\n const composeAgents = useComposeAgents()\n const items = useWorkQueueItems()\n\n const claimableCount = items.filter((i) => i.claimable).length\n\n function handleClaim(item: WorkQueueItem) {\n if (!compose.from) { showError('Validation', 'Select a \"Claim as\" agent first.'); return }\n if (item.sourceType === 'task' && item.task) doClaimTask(item.task.id)\n else if (item.sourceType === 'message' && item.message) doClaim(item.message.id)\n }\n\n function handleCancel(item: WorkQueueItem) {\n const label = item.title || (item.sourceType === 'task' ? `Task #${item.id}` : `Message #${item.id}`)\n openConfirm('Cancel Item', `Cancel \"${label}\"? This cannot be undone.`, () => {\n if (item.sourceType === 'task' && item.task) doUpdateTaskStatus(item.task, 'canceled')\n else if (item.sourceType === 'message' && item.message) doDeleteMessage(item.message.id)\n })\n }\n\n function handleEvents(item: WorkQueueItem) {\n if (item.task) openTaskEvents(item.task)\n }\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\">\n <ListChecks className=\"w-5 h-5 text-muted-foreground\" />\n <h2 className=\"text-lg font-semibold\">Work Queue</h2>\n {claimableCount > 0 && (\n <Badge className=\"bg-orange-500/20 text-orange-400 border-orange-500/30 border\">\n {claimableCount} claimable\n </Badge>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n <label className=\"text-xs text-muted-foreground shrink-0\">Claim as</label>\n <select\n className=\"rounded-md border border-input bg-background px-3 py-1.5 text-sm\"\n value={compose.from}\n onChange={(e) => set({ compose: { ...compose, from: e.target.value } })}\n >\n <option value=\"\">Select agent...</option>\n {composeAgents.map((a) => <option key={a.id} value={a.id}>{displayName(a)}</option>)}\n </select>\n </div>\n </div>\n\n <ScrollArea className=\"h-[calc(100dvh-11rem)]\">\n <div className=\"space-y-2 pr-2\">\n {items.length === 0 && (\n <div className=\"text-center text-muted-foreground py-16 text-sm\">Work queue is empty</div>\n )}\n {items.map((item) => (\n <WorkQueueCard\n key={item.id}\n item={item}\n now={now}\n agentName={(id) => agentsById[id] ? displayName(agentsById[id]) : id.slice(-10)}\n onClaim={() => handleClaim(item)}\n onCancel={() => handleCancel(item)}\n onEvents={item.task ? () => handleEvents(item) : undefined}\n />\n ))}\n </div>\n </ScrollArea>\n </div>\n )\n}\n\nfunction WorkQueueCard({\n item, now, agentName, onClaim, onCancel, onEvents,\n}: {\n item: WorkQueueItem\n now: number\n agentName: (id: string) => string\n onClaim: () => void\n onCancel: () => void\n onEvents?: () => void\n}) {\n const severityClass = SEVERITY_COLORS[item.severity] || SEVERITY_COLORS.info\n const statusClass = STATUS_COLORS[item.status] || 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20'\n\n return (\n <Card className={item.claimable ? 'ring-1 ring-orange-500/30' : ''}>\n <CardContent className=\"p-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 flex-wrap mb-1\">\n <span className=\"font-medium text-sm truncate\">{item.title}</span>\n <Badge variant=\"outline\" className={`text-xs px-1.5 py-0 border ${severityClass}`}>{item.severity}</Badge>\n <Badge variant=\"outline\" className={`text-xs px-1.5 py-0 border ${statusClass}`}>{item.status}</Badge>\n {item.sourceType === 'message' && (\n <Badge variant=\"outline\" className=\"text-xs px-1.5 py-0 border border-zinc-500/20 text-zinc-400\">msg</Badge>\n )}\n </div>\n {item.body && (\n <p className=\"text-xs text-muted-foreground line-clamp-2 mb-2\">{item.body}</p>\n )}\n <div className=\"flex items-center gap-3 text-xs text-muted-foreground flex-wrap\">\n {item.owner && (\n <span title=\"Owner\">\n <CheckCircle2 className=\"w-3 h-3 inline mr-1\" />{agentName(item.owner)}\n </span>\n )}\n {item.source && (\n <span className=\"font-mono\">{item.source}</span>\n )}\n <span title={String(item.updatedAt)}>\n <Calendar className=\"w-3 h-3 inline mr-1\" />{timeAgo(now, item.updatedAt)}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col gap-1 shrink-0\">\n {item.claimable && (\n <Button size=\"sm\" className=\"h-7 text-xs bg-orange-600 hover:bg-orange-700 text-white\" onClick={onClaim}>\n <CheckCircle2 className=\"w-3.5 h-3.5 mr-1\" /> Claim\n </Button>\n )}\n {onEvents && (\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs\" onClick={onEvents}>\n Events\n </Button>\n )}\n <Button size=\"sm\" variant=\"outline\" className=\"h-7 text-xs text-red-400 hover:text-red-300 hover:bg-red-500/10 border-red-500/20\" onClick={onCancel}>\n <X className=\"w-3.5 h-3.5 mr-1\" /> Cancel\n </Button>\n </div>\n </div>\n </CardContent>\n </Card>\n )\n}\n"],"mappings":"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"}
package/public/index.html CHANGED
@@ -12,7 +12,7 @@
12
12
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%2309090b'/%3E%3Ccircle cx='16' cy='16' r='4.5' fill='%2358a6ff'/%3E%3Ccircle cx='6' cy='8' r='2.5' fill='%233fb950'/%3E%3Ccircle cx='26' cy='8' r='2.5' fill='%233fb950'/%3E%3Ccircle cx='6' cy='24' r='2.5' fill='%233fb950'/%3E%3Ccircle cx='26' cy='24' r='2.5' fill='%233fb950'/%3E%3Cline x1='8' y1='9.5' x2='13' y2='14' stroke='%2330363d' stroke-width='1.5'/%3E%3Cline x1='24' y1='9.5' x2='19' y2='14' stroke='%2330363d' stroke-width='1.5'/%3E%3Cline x1='8' y1='22.5' x2='13' y2='18' stroke='%2330363d' stroke-width='1.5'/%3E%3Cline x1='24' y1='22.5' x2='19' y2='18' stroke='%2330363d' stroke-width='1.5'/%3E%3C/svg%3E">
13
13
  <link rel="manifest" href="manifest.webmanifest">
14
14
  <link rel="apple-touch-icon" href="icons/agent-relay-192.png">
15
- <script type="module" crossorigin src="./assets/index-DePqIpr0.js"></script>
15
+ <script type="module" crossorigin src="./assets/index-DB6XGZy9.js"></script>
16
16
  <link rel="modulepreload" crossorigin href="./assets/chunk-CilyBKbf.js">
17
17
  <link rel="modulepreload" crossorigin href="./assets/preload-helper-CP_edrrL.js">
18
18
  <link rel="modulepreload" crossorigin href="./assets/lucide-react-DI8kTavp.js">
@@ -37,7 +37,7 @@
37
37
  <link rel="modulepreload" crossorigin href="./assets/badge-YQhT30dy.js">
38
38
  <link rel="modulepreload" crossorigin href="./assets/input-Cqqq0OFl.js">
39
39
  <link rel="modulepreload" crossorigin href="./assets/themes-mW9zZP4O.js">
40
- <link rel="stylesheet" crossorigin href="./assets/index-CQQTCZxg.css">
40
+ <link rel="stylesheet" crossorigin href="./assets/index-DepEqGST.css">
41
41
  </head>
42
42
  <body class="bg-background text-foreground antialiased">
43
43
  <div id="root"></div>
@@ -0,0 +1,98 @@
1
+ import { createCommand } from "./commands-db";
2
+ import { getAgent, listAgents } from "./db";
3
+ import { getManagedAgentState } from "./config-store";
4
+ import { emitCommandEvent } from "./command-events";
5
+ import { handleContextPressure } from "./context-advisory";
6
+ import type { AgentCard, Command, SpawnPolicy } from "./types";
7
+
8
+ interface LifecycleContextPressureInput {
9
+ policies: SpawnPolicy[];
10
+ now: () => number;
11
+ hasActiveCommand: (target: string, type: string) => boolean;
12
+ }
13
+
14
+ interface CompactAgentInput {
15
+ agent: AgentCard;
16
+ reason: string;
17
+ policyName?: string;
18
+ alwaysReload?: string[];
19
+ now: () => number;
20
+ hasActiveCommand: (target: string, type: string) => boolean;
21
+ }
22
+
23
+ export function reconcileLifecycleContextPressure(input: LifecycleContextPressureInput): Set<string> {
24
+ const byPolicy = new Map(input.policies.map((policy) => [policy.name, policy]));
25
+ const candidates = new Map<string, { agent: AgentCard; policy?: SpawnPolicy }>();
26
+
27
+ for (const policy of input.policies) {
28
+ const state = getManagedAgentState(policy.name);
29
+ if (state?.status !== "running" || !state.agentId) continue;
30
+ const agent = getAgent(state.agentId);
31
+ if (!agent || agent.status === "offline") continue;
32
+ candidates.set(agent.id, { agent, policy });
33
+ }
34
+
35
+ for (const agent of listAgents()) {
36
+ if (!isLiveRunnerManagedAgent(agent) || candidates.has(agent.id)) continue;
37
+ const policyName = typeof agent.meta?.policyName === "string" ? agent.meta.policyName : undefined;
38
+ candidates.set(agent.id, { agent, policy: policyName ? byPolicy.get(policyName) : undefined });
39
+ }
40
+
41
+ const handled = new Set<string>();
42
+ for (const { agent, policy } of candidates.values()) {
43
+ if (handleContextPressure({
44
+ agent,
45
+ now: input.now,
46
+ hasActiveCommand: input.hasActiveCommand,
47
+ compact: (reason) => requestAgentCompact({
48
+ agent,
49
+ reason,
50
+ policyName: policy?.name,
51
+ alwaysReload: alwaysReloadTags(agent.tags),
52
+ now: input.now,
53
+ hasActiveCommand: input.hasActiveCommand,
54
+ }),
55
+ })) {
56
+ handled.add(agent.id);
57
+ }
58
+ }
59
+ return handled;
60
+ }
61
+
62
+ export function requestAgentCompact(input: CompactAgentInput): Command | null {
63
+ if (input.hasActiveCommand(input.agent.id, "agent.compact")) return null;
64
+ const spawnRequestId = typeof input.agent.meta?.spawnRequestId === "string" ? input.agent.meta.spawnRequestId : undefined;
65
+ const sessionName = typeof input.agent.meta?.sessionName === "string" ? input.agent.meta.sessionName : undefined;
66
+ const tmuxSession = typeof input.agent.meta?.tmuxSession === "string" ? input.agent.meta.tmuxSession : undefined;
67
+ const command = createCommand({
68
+ type: "agent.compact",
69
+ source: "system",
70
+ target: input.agent.id,
71
+ correlationId: spawnRequestId,
72
+ params: {
73
+ action: "compact",
74
+ agentId: input.agent.id,
75
+ ...(input.policyName ? { policyName: input.policyName } : {}),
76
+ ...(spawnRequestId ? { spawnRequestId } : {}),
77
+ ...(sessionName ? { sessionName } : {}),
78
+ ...(tmuxSession ? { tmuxSession } : {}),
79
+ reason: input.reason,
80
+ memory: input.alwaysReload?.length ? { alwaysReload: input.alwaysReload } : undefined,
81
+ requestedBy: "lifecycle-manager",
82
+ requestedAt: input.now(),
83
+ },
84
+ });
85
+ emitCommandEvent(command, "command.requested");
86
+ return command;
87
+ }
88
+
89
+ export function alwaysReloadTags(tags: string[]): string[] {
90
+ return tags
91
+ .filter((tag) => tag.startsWith("memory-reload:"))
92
+ .map((tag) => tag.slice("memory-reload:".length).trim())
93
+ .filter(Boolean);
94
+ }
95
+
96
+ function isLiveRunnerManagedAgent(agent: AgentCard): boolean {
97
+ return agent.meta?.runnerManaged === true && agent.status !== "offline" && agent.status !== "stale";
98
+ }
@@ -9,7 +9,7 @@ import {
9
9
  upsertManagedAgentState,
10
10
  } from "./config-store";
11
11
  import { emitRelayEvent } from "./events";
12
- import { handleContextPressure } from "./context-advisory";
12
+ import { alwaysReloadTags, reconcileLifecycleContextPressure, requestAgentCompact } from "./lifecycle-context-pressure";
13
13
  import { markManagedAgentRunning, emitManagedState } from "./services/managed-running";
14
14
  import { authContextFromSystem } from "./services/auth-context";
15
15
  import { emitCommandEvent } from "./command-events";
@@ -66,8 +66,10 @@ export class LifecycleManager {
66
66
  }
67
67
 
68
68
  async tick(): Promise<void> {
69
- for (const policy of this.loadPolicies()) {
70
- this.reconcilePolicy(policy);
69
+ const policies = this.loadPolicies();
70
+ const contextHandled = this.reconcileContextPressure(policies);
71
+ for (const policy of policies) {
72
+ this.reconcilePolicy(policy, contextHandled);
71
73
  }
72
74
  }
73
75
 
@@ -175,7 +177,7 @@ export class LifecycleManager {
175
177
  onConfigChanged(namespace: string, key: string): void {
176
178
  if (namespace !== "spawn-policy") return;
177
179
  const policy = this.loadPolicies().find((item) => item.name === key);
178
- if (policy) this.reconcilePolicy(policy);
180
+ if (policy) this.reconcilePolicy(policy, this.reconcileContextPressure([policy]));
179
181
  }
180
182
 
181
183
  onRelayUpdated(_newVersion: string): void {
@@ -309,7 +311,7 @@ export class LifecycleManager {
309
311
  return command;
310
312
  }
311
313
 
312
- private reconcilePolicy(policy: SpawnPolicy): void {
314
+ private reconcilePolicy(policy: SpawnPolicy, contextHandled = new Set<string>()): void {
313
315
  const state = getManagedAgentState(policy.name);
314
316
  const enabled = policy.enabled !== false;
315
317
  if (!state) {
@@ -354,9 +356,16 @@ export class LifecycleManager {
354
356
  this.stopAgent(policy, true, "idle-timeout");
355
357
  return;
356
358
  }
357
- if (handleContextPressure({ agent, now: this.now, hasActiveCommand: (target, type) => this.hasActiveCommand(target, type), compact: (reason) => this.compactAgent(policy, agent.id, reason, alwaysReloadTags(agent.tags)) })) return;
359
+ if (contextHandled.has(agent.id)) return;
358
360
  if (this.shouldCompact(agent)) {
359
- this.compactAgent(policy, agent.id, "context-threshold", alwaysReloadTags(agent.tags));
361
+ requestAgentCompact({
362
+ agent,
363
+ reason: "context-threshold",
364
+ policyName: policy.name,
365
+ alwaysReload: alwaysReloadTags(agent.tags),
366
+ now: this.now,
367
+ hasActiveCommand: (target, type) => this.hasActiveCommand(target, type),
368
+ });
360
369
  return;
361
370
  }
362
371
  if (policy.scheduledDailyRestart && this.dailyRestartDue(policy, state) && this.isIdle(policy, state, 3600)) {
@@ -384,24 +393,12 @@ export class LifecycleManager {
384
393
  }
385
394
  }
386
395
 
387
- private compactAgent(policy: SpawnPolicy, agentId: string, reason: string, alwaysReload: string[] = []): Command | null {
388
- if (this.hasActiveCommand(agentId, "agent.compact")) return null;
389
- const command = createCommand({
390
- type: "agent.compact",
391
- source: "system",
392
- target: agentId,
393
- params: {
394
- action: "compact",
395
- agentId,
396
- policyName: policy.name,
397
- reason,
398
- memory: alwaysReload.length ? { alwaysReload } : undefined,
399
- requestedBy: "lifecycle-manager",
400
- requestedAt: this.now(),
401
- },
396
+ private reconcileContextPressure(policies: SpawnPolicy[]): Set<string> {
397
+ return reconcileLifecycleContextPressure({
398
+ policies,
399
+ now: this.now,
400
+ hasActiveCommand: (target, type) => this.hasActiveCommand(target, type),
402
401
  });
403
- emitCommandEvent(command, "command.requested");
404
- return command;
405
402
  }
406
403
 
407
404
  private ensureStoppedState(policy: SpawnPolicy): void {
@@ -654,10 +651,3 @@ function agentTerminalFailureMessage(agent: ReturnType<typeof getAgent> | null):
654
651
  function isPlainRecord(value: unknown): value is Record<string, unknown> {
655
652
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
656
653
  }
657
-
658
- function alwaysReloadTags(tags: string[]): string[] {
659
- return tags
660
- .filter((tag) => tag.startsWith("memory-reload:"))
661
- .map((tag) => tag.slice("memory-reload:".length).trim())
662
- .filter(Boolean);
663
- }
@@ -0,0 +1,23 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { homedir, hostname as osHostname } from "node:os";
3
+ import { join } from "node:path";
4
+ import { localOrchestratorIdFromEnv } from "./config";
5
+
6
+ /**
7
+ * Resolve the LOCAL host's orchestrator id the same way the orchestrator runtime
8
+ * does. The upgrade command only ever touches the local runtime, so this is the
9
+ * only orchestrator whose post-restart version it can legitimately assert.
10
+ */
11
+ export function resolveLocalOrchestratorId(homeDirOverride?: string): string {
12
+ const homeDir = homeDirOverride ?? process.env.HOME ?? process.env.USERPROFILE ?? homedir();
13
+ const configPath = join(homeDir, ".agent-relay", "orchestrator.json");
14
+ if (existsSync(configPath)) {
15
+ try {
16
+ const parsed = JSON.parse(readFileSync(configPath, "utf8")) as { id?: string };
17
+ if (typeof parsed.id === "string" && parsed.id.trim()) return parsed.id.trim();
18
+ } catch {
19
+ // Unparsable config: fall through to env/hostname.
20
+ }
21
+ }
22
+ return localOrchestratorIdFromEnv() ?? osHostname().replace(/\./g, "-");
23
+ }
package/src/upgrade.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import { existsSync, readFileSync } from "node:fs";
2
- import { homedir, hostname as osHostname } from "node:os";
2
+ import { homedir } from "node:os";
3
3
  import { join, resolve } from "node:path";
4
- import { VERSION, cliRelayUrl, localOrchestratorIdFromEnv, relayAuthHeaders } from "./config";
4
+ import { VERSION, cliRelayUrl, relayAuthHeaders } from "./config";
5
5
  import type { RuntimeContracts, RuntimePackageMetadata } from "./contracts";
6
6
  import { defaultRuntimePrefix, runtimeBinPath } from "./runtime-prefix";
7
- import { errMessage } from "agent-relay-sdk";
7
+ import { resolveLocalOrchestratorId } from "./upgrade-local-id";
8
+ import { errMessage, runInstallWithRetry } from "agent-relay-sdk";
8
9
  import { shellEscape as shellQuote } from "agent-relay-sdk/shell-utils";
9
10
 
11
+ export { resolveLocalOrchestratorId } from "./upgrade-local-id";
12
+
10
13
  export type UpgradeProvider = "auto" | "all" | "codex" | "claude" | "orchestrator";
11
14
 
12
15
  type UpgradeOptions = {
@@ -68,6 +71,7 @@ type UpgradeAction = {
68
71
  command: string[];
69
72
  reason: string;
70
73
  mutates: boolean;
74
+ retryInstall?: boolean;
71
75
  };
72
76
 
73
77
  type UpgradePlan = {
@@ -178,6 +182,7 @@ export function createUpgradePlan(snapshot: UpgradeSnapshot, options: UpgradeOpt
178
182
  command,
179
183
  reason: `Update server${runnerRequested ? ", provider runner" : ""}${orchestratorRequested ? ", and orchestrator" : ""} packages to ${targetVersion}.`,
180
184
  mutates: true,
185
+ retryInstall: true,
181
186
  });
182
187
  if (snapshot.packageManager === "runtime-npm") {
183
188
  actions.push({
@@ -268,6 +273,7 @@ type ExecuteUpgradeOptions = {
268
273
  /** Poll interval while waiting for re-register (default 1s). */
269
274
  verifyIntervalMs?: number;
270
275
  sleep?: (ms: number) => Promise<void>;
276
+ installRetries?: number; installRetryBaseMs?: number;
271
277
  probeServerVersion?: () => Promise<string | undefined>;
272
278
  probeOrchestrators?: () => Promise<UpgradeSnapshot["runningOrchestrators"]>;
273
279
  /** Override the local orchestrator id (defaults to the resolved host id). */
@@ -298,7 +304,16 @@ export async function executeUpgradePlan(plan: UpgradePlan, options: ExecuteUpgr
298
304
  for (const action of plan.actions) {
299
305
  lines.push(`\n${action.label}`);
300
306
  lines.push(`$ ${action.command.map(shellQuote).join(" ")}`);
301
- const result = runner(action.command);
307
+ const result = action.retryInstall
308
+ ? await runInstallWithRetry(action.command, runner, {
309
+ sleep,
310
+ retries: options.installRetries,
311
+ baseDelayMs: options.installRetryBaseMs,
312
+ onRetry: ({ attempt, delayMs }) => {
313
+ lines.push(`npm cache race detected; retrying install attempt ${attempt} in ${delayMs}ms.`);
314
+ },
315
+ })
316
+ : runner(action.command);
302
317
  if (result.stdout.trim()) lines.push(result.stdout.trim());
303
318
  if (result.stderr.trim()) lines.push(result.stderr.trim());
304
319
  if (result.exitCode !== 0) {
@@ -568,29 +583,6 @@ function homeDir(): string {
568
583
  return process.env.HOME || process.env.USERPROFILE || homedir();
569
584
  }
570
585
 
571
- /**
572
- * Resolve the LOCAL host's orchestrator id the same way the orchestrator runtime
573
- * does (orchestrator/src/config.ts): explicit config id, then
574
- * AGENT_RELAY_ORCHESTRATOR_ID, then the hostname with dots hyphenated. The
575
- * upgrade command only ever touches the local runtime, so this is the only
576
- * orchestrator whose post-restart version it can legitimately assert (#210).
577
- */
578
- export function resolveLocalOrchestratorId(homeDirOverride?: string): string {
579
- const home = homeDirOverride ?? homeDir();
580
- const configPath = join(home, ".agent-relay", "orchestrator.json");
581
- if (existsSync(configPath)) {
582
- try {
583
- const parsed = JSON.parse(readFileSync(configPath, "utf8")) as { id?: string };
584
- if (typeof parsed.id === "string" && parsed.id.trim()) return parsed.id.trim();
585
- } catch {
586
- // Unparsable config — fall through to env/hostname.
587
- }
588
- }
589
- const envId = localOrchestratorIdFromEnv();
590
- if (envId) return envId;
591
- return osHostname().replace(/\./g, "-");
592
- }
593
-
594
586
  function uniqueStrings(values: string[]): string[] {
595
587
  return [...new Set(values.filter(Boolean))];
596
588
  }
@@ -1,3 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{An as t,Bn as n,Hn as r,L as i,Nt as a,P as o,Qn as s,R as c,Rn as l,St as u,Ut as d,Wt as f,Zt as p,a as m,c as h,cn as g,dn as _,en as v,fn as ee,h as y,i as b,it as x,jn as S,ln as C,p as w,pn as T,r as E,sn as D,st as O,tn as k,v as A,wn as te,xt as j,y as ne,yn as M}from"./lucide-react-DI8kTavp.js";import{g as N,r as re,t as P}from"./store-D1K4_xId.js";import{D as F,I as ie,M as ae,W as I,at as L,b as oe,d as se,f as ce,j as R,w as z,z as le}from"./display-DHgdn4vN.js";import{C as ue,a as de,i as fe,o as pe,t as B}from"./index-DePqIpr0.js";var V=e(s(),1),H={online:`came online`,offline:`went offline`,shutdown:`shut down`,restarted:`restarted`,"compaction-requested":`compaction requested`,compacting:`compaction started`,compacted:`context compacted`,"compaction-stalled":`compaction stalled — may need manual intervention`,"clear-requested":`clear requested`,"clearing-context":`clear started`,"context-cleared":`context cleared`,"clear-stalled":`context clear stalled — may need manual intervention`,"shutting-down":`shutting down`},me=new Set(Object.keys(H)),he=3e3;function U(e){return new Date(e.occurredAt??e.createdAt).getTime()}function ge(e){if(e.kind!==`session`)return null;let t=e.payload?.session;return!t||t.type!==`narration`&&t.type!==`reasoning`&&t.type!==`tool`?null:{id:e.id,kind:t.type,label:typeof t.label==`string`?t.label:void 0,text:e.body,ts:U(e),turnId:typeof t.turnId==`string`?t.turnId:void 0}}function _e(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`notice`)return null;let n=typeof t.label==`string`&&t.label?t.label:`compacted`;return{id:`notice-${e.id}`,status:n,timestamp:U(e)}}function ve(e){if(e.kind!==`session`)return null;let t=e.payload?.session;if(t?.type!==`relay-injection`)return null;let n=t.relayInjection&&typeof t.relayInjection==`object`&&!Array.isArray(t.relayInjection)?t.relayInjection:{},r=typeof n.category==`string`&&[`memory`,`instructions`,`tools`,`comms`,`knowledge`,`context`].includes(n.category)?n.category:`context`,i=typeof n.timestamp==`number`&&Number.isFinite(n.timestamp)?n.timestamp:U(e),a=n.detail&&typeof n.detail==`object`&&!Array.isArray(n.detail)?n.detail:{};return{id:e.id,category:r,summary:typeof n.summary==`string`&&n.summary.trim()?n.summary:e.body,detail:a,agentId:typeof n.agentId==`string`&&n.agentId?n.agentId:e.from,timestamp:i}}function W(e,t){let n=e.trim();for(let e of t){let t=e.trim();if(t){if(n===t)break;n.startsWith(`${t}\n\n`)&&(n=n.slice(t.length+2).trimStart())}}return n.trim()||e.trim()}function G(e){return e.kind===`system`&&e.from===`system`}var ye=new Set([`agent.ready`,`agent.exited`,`agent.spawn_failed`]);function K(e){let t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,`0`)}-${String(t.getDate()).padStart(2,`0`)}`}function be(e){let t=e.filter(e=>me.has(e.status)).slice().sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let e of t)n.some(t=>t.id===e.id)||n.some(t=>t.status===e.status&&Math.abs(t.timestamp-e.timestamp)<=he)||n.push(e);return n}function xe(e,t,n,r=[],i){let a=[];for(let e of r){let t=e.entries.reduce((e,t)=>Math.min(e,I(t.originalCreatedAt)),1/0),n=Number.isFinite(t)?t-1:e.importedAt;a.push({ts:n,entry:{type:`import-boundary`,history:e,timestamp:n}});for(let t of e.entries)a.push({ts:I(t.originalCreatedAt),entry:{type:`imported-message`,history:e,entry:t}})}if(n){let e=new Date(n).getTime();Number.isFinite(e)&&a.push({ts:e,entry:{type:`created`,timestamp:e}})}if(i?.spawnedBy){let e=n?new Date(n).getTime():0,t=Number.isFinite(e)?e:0;a.push({ts:t,entry:{type:`agent-action`,direction:`spawned-by`,agentId:i.spawnedBy.agentId,provider:i.spawnedBy.provider,status:`ready`,timestamp:t}})}let o=i?.spawnedBy?.agentId,s=null,c=1/0;for(let t of e){if(t.kind===`session`||G(t)||z(t)||!(t.from===`user`||o!==void 0&&t.from===o)||!F(t).trim())continue;let e=U(t);e<c&&(c=e,s=t.id)}let l=new Map,u=new Map,d=new Map;for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type===`narration`&&typeof e.turnId==`string`){let n=u.get(e.turnId)??[];n.push({id:t.id,body:t.body.trim()}),u.set(e.turnId,n)}else if(e?.type===`response`&&typeof e.turnId==`string`){let n=l.get(e.turnId)??[];n.push(t.body.trim()),l.set(e.turnId,n)}}let f=new Map;for(let[e,t]of l){let n=(u.get(e)??[]).map(e=>e.body);f.set(e,t.map(e=>W(e,n)))}for(let t of e){if(t.kind!==`session`)continue;let e=t.payload?.session;if(e?.type!==`response`||typeof e.turnId!=`string`)continue;let n=W(t.body,(u.get(e.turnId)??[]).map(e=>e.body));n&&n!==t.body&&d.set(t.id,n)}let p=new Set;for(let[e,t]of f){let n=u.get(e)??[];for(let e of t)for(let t=n.length-1;t>=0;t--){let r=n[t];if(!p.has(r.id)&&le(e,r.body)){p.add(r.id);break}}}let m=new Map,h=[];for(let t of e){if(G(t)){let e=typeof t.payload?.kind==`string`?t.payload.kind:``;if(ye.has(e)){let n=t.payload,r=typeof n.agentId==`string`?n.agentId:``,i=U(t);if(!r){a.push({ts:i,entry:{type:`notice`,msg:t}});continue}let o=e===`agent.ready`?`ready`:e===`agent.exited`?`exited`:`failed`,s=m.get(r);if(s)s.entry.status=o,typeof n.reason==`string`&&(s.entry.reason=n.reason),s.entry.timestamp=i,s.ts=i;else{let e={ts:i,entry:{type:`agent-action`,direction:`spawned-child`,agentId:r,provider:typeof n.provider==`string`?n.provider:void 0,status:o,reason:typeof n.reason==`string`?n.reason:void 0,timestamp:i}};m.set(r,e),a.push(e)}continue}a.push({ts:U(t),entry:{type:`notice`,msg:t}});continue}let e=_e(t);if(e){h.push(e);continue}let n=ge(t);if(n){if(n.kind===`narration`&&p.has(n.id))continue;a.push({ts:n.ts,entry:{type:`activity`,steps:[n],timestamp:n.ts}});continue}let r=ve(t);if(r){a.push({ts:r.timestamp,entry:{type:`relay-injection`,event:r}});continue}if(t.kind===`session`){let e=t.payload?.session;if(e?.type===`response`&&typeof e.turnId==`string`){let e=d.get(t.id);if(e&&e!==t.body){a.push({ts:U(t),entry:{type:`message`,msg:{...t,body:e}}});continue}}}let i=t.id===s?`initial-prompt`:`message`;a.push({ts:U(t),entry:{type:i,msg:t}})}for(let e of be([...t,...h]))a.push({ts:e.timestamp,entry:{type:`status`,event:e}});let g={created:0,date:1,"import-boundary":2,"imported-message":3,"initial-prompt":4,message:4,activity:4,notice:4,"agent-action":4,"relay-injection":4,status:5};a.sort((e,t)=>{let n=e.ts-t.ts;return Math.abs(n)<3e3&&g[e.entry.type]-g[t.entry.type]||n});let _=[],v=``;for(let{ts:e,entry:t}of a){if(t.type===`created`){_.push(t);continue}let n=K(e);if(n!==v&&(_.push({type:`date`,date:n,timestamp:e}),v=n),t.type===`activity`){let e=_[_.length-1];if(e&&e.type===`activity`&&we(e,t)){e.steps.push(...t.steps);continue}}_.push(t)}return _}function Se(e){return e.type===`message`?`msg-${e.msg.id}`:e.type===`initial-prompt`?`initprompt-${e.msg.id}`:e.type===`notice`?`notice-${e.msg.id}`:e.type===`relay-injection`?`relay-injection-${e.event.id}`:e.type===`agent-action`?`agent-action-${e.direction}-${e.agentId}`:e.type===`activity`?`act-${e.steps[0]?.id??e.timestamp}`:e.type===`import-boundary`?`import-${e.history.id}`:e.type===`imported-message`?`import-msg-${e.history.id}-${e.entry.originalMessageId}-${e.entry.position}`:e.type===`status`?`status-${e.event.id}`:e.type===`date`?`date-${e.date}`:`created-${e.timestamp}`}function Ce(e){return e.type===`message`||e.type===`initial-prompt`||e.type===`notice`?(e.msg.subject?`${e.msg.subject} `:``)+F(e.msg):e.type===`imported-message`?F(e.entry.message):e.type===`activity`?e.steps.map(e=>[e.label,e.text].filter(Boolean).join(` `)).join(`
2
- `):e.type===`relay-injection`?`${e.event.category} ${e.event.summary}\n${JSON.stringify(e.event.detail)}`:``}function we(e,t){let n=e.steps[e.steps.length-1]?.turnId,r=t.steps[0]?.turnId;return n&&r?n===r:!n&&!r}function Te(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Ee(e,t){if(t.startsWith(`/`))return t;let n=`${e.replace(/\/+$/,``)}/${t}`.split(`/`),r=[];for(let e of n)!e||e===`.`||(e===`..`?r.pop():r.push(e));return`/`+r.join(`/`)}function De(e){let t=e.replace(/\/+$/,``),n=t.lastIndexOf(`/`);return n>0?t.slice(0,n):`/`}function Oe(e,t){return e.filter(e=>e.status===`online`&&ie(t,e.baseDir)).sort((e,t)=>R(t.baseDir).length-R(e.baseDir).length)[0]||e.find(e=>e.status===`online`)}function ke(){return typeof window<`u`&&window.matchMedia(`(min-width: 1280px)`).matches}function Ae(){return typeof window<`u`&&!!window.getSelection()?.toString()}function je(e){let t=e.payload?.attachments;return Array.isArray(t)?t.filter(e=>!!(e&&typeof e==`object`&&typeof e.artifactId==`string`)):[]}var Me=[`👍`,`❤️`,`✅`,`👀`];function Ne(e){let t=new Map;for(let n of e.reactions||[]){let e=ae(n.emoji),r=t.get(e)??{emoji:e,count:0,mine:!1,actors:[]};r.count+=1,r.mine=r.mine||n.actorId===`user`,r.actors.push(n.actorId),t.set(e,r)}return[...t.values()].sort((e,t)=>t.count-e.count||e.emoji.localeCompare(t.emoji))}function q(e){return z(e)}function Pe(e,t){let n=e.readBy||[],r=e.resolvedToAgent||t||e.to,i=r?n.includes(r):!1,a=n.some(e=>e!==L);if(i||a){let e=i?r:n.find(e=>e!==L);return{label:`read`,title:e?`Read by ${e}`:`Read by agent`,tone:`ok`,icon:T}}if(e.deliveryStatus===`delivered`)return{label:`delivered`,title:`Delivered to agent inbox`,tone:`ok`,icon:T};if(e.deliveryStatus===`queued`)return{label:`queued`,title:`Queued until the target agent is available`,tone:`warn`,icon:p};if(e.deliveryStatus===`failed`||e.deliveryStatus===`dead`){let t=e.deliveryPoisonReason||e.deliveryLastError||e.deliveryStatus;return{label:e.deliveryStatus,title:t,tone:`danger`,icon:D}}return{label:`sent`,title:`Accepted by Relay`,tone:`muted`,icon:ee}}function Fe(e){let t=I(e.createdAt);return(e.reactions||[]).reduce((e,t)=>Math.max(e,I(t.updatedAt||t.createdAt)),t)}function Ie(e){return e?e.messages.reduce((e,t)=>Math.max(e,Fe(t)),0):0}function Le(e,t,n){return(e-t)*n}function Re(e){if(!e)return 0;let t=0;for(let n of e.messages)oe(n)&&(t=Math.max(t,I(n.createdAt)));return t}function J(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function ze(e){for(let t of e)t.previewUrl&&URL.revokeObjectURL(t.previewUrl)}function Be(e,t,n,r){if(e?.teamId)return{teamId:e.teamId};let i=[...t];n&&!i.some(e=>e.id===n.id)&&i.push(n);let a=i.filter(e=>e.threadId).reverse(),o=a.find(e=>!!r[re(e.threadId,e.channel)])??a[0];return o?.threadId?{threadId:o.threadId,...o.channel?{channel:o.channel}:{}}:null}var Y=n(),Ve={online:`text-emerald-400`,offline:`text-zinc-400`,shutdown:`text-zinc-400`,restarted:`text-blue-400`,"compaction-requested":`text-zinc-400`,compacting:`text-amber-400`,compacted:`text-amber-400`,"compaction-stalled":`text-red-400`,"clear-requested":`text-zinc-400`,"clearing-context":`text-amber-400`,"context-cleared":`text-amber-400`,"clear-stalled":`text-red-400`,"shutting-down":`text-zinc-400`};function He(e){let t=new Date,[n,r,i]=e.split(`-`).map(Number),a=new Date(n,r-1,i);if(e===K(t.getTime()))return`Today`;let o=new Date(t);return o.setDate(o.getDate()-1),e===K(o.getTime())?`Yesterday`:a.toLocaleDateString(void 0,{weekday:`short`,month:`short`,day:`numeric`,year:a.getFullYear()===t.getFullYear()?void 0:`numeric`})}function Ue({event:e}){return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs text-muted-foreground`,children:[(0,Y.jsx)(v,{className:l(`w-2 h-2 fill-current`,Ve[e.status]||`text-zinc-400`)}),(0,Y.jsx)(`span`,{children:H[e.status]||e.status}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60`,children:J(e.timestamp)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var We={"branch.landed":j,"context.warning":w,"agent.context_threshold":w,"agent.resume_budget_exhausted":w,"agent.rate_limit_resume":c},Ge={"branch.landed":`branch landed`,"context.warning":`context warning`,"agent.context_threshold":`context threshold reached`};function Ke(e){return e&&(e.includes(`.`)?e.slice(e.indexOf(`.`)+1):e).replace(/[._-]+/g,` `).trim()||`system signal`}function X({agentId:e,fallbackLabel:t,className:n}){let r=P(t=>t.agentsById[e])||null,i=P(e=>e.openInboxThread),a=P(e=>e.switchView),o=r?se(r):t||e;return(0,Y.jsxs)(`button`,{type:`button`,className:l(`inline-flex max-w-full items-center gap-1 rounded px-1 text-muted-foreground transition-colors hover:bg-muted/50 hover:text-foreground`,n),onClick:t=>{t.stopPropagation(),i(e),a(`chat`)},title:`Open chat for ${o}`,children:[(0,Y.jsx)(ue,{agent:r,className:`w-4 h-4 text-[10px]`}),(0,Y.jsx)(`span`,{className:`max-w-[160px] truncate`,children:o})]})}function qe({msg:e}){let t=e.payload??{},n=typeof t.sha==`string`?t.sha:``,r=n?n.slice(0,7):``,i=typeof t.author==`string`?t.author:``,a=typeof t.branch==`string`?t.branch:``,o=typeof t.base==`string`?t.base:``,s=t.pushed;return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:`flex max-w-full flex-wrap items-center justify-center gap-x-1.5 gap-y-0.5 rounded-full border border-emerald-500/25 bg-emerald-500/10 px-2.5 py-1 text-xs text-emerald-300/90`,children:[(0,Y.jsx)(j,{className:`h-3 w-3 shrink-0 text-emerald-400`}),(0,Y.jsx)(`span`,{className:`text-emerald-300`,children:`branch landed`}),a&&o&&(0,Y.jsxs)(`span`,{className:`font-mono text-emerald-200/70`,title:`${a} → ${o}`,children:[a,(0,Y.jsx)(`span`,{className:`opacity-50`,children:` → `}),o]}),r&&(0,Y.jsx)(`span`,{className:`rounded bg-emerald-500/15 px-1 font-mono text-emerald-200`,title:n,children:r}),i&&(0,Y.jsxs)(`span`,{className:`inline-flex items-center gap-1 text-emerald-300/80`,children:[(0,Y.jsx)(`span`,{className:`opacity-70`,children:`by`}),(0,Y.jsx)(X,{agentId:i,className:`text-emerald-300/90 hover:text-emerald-100`})]}),s===!1&&(0,Y.jsx)(`span`,{className:`text-amber-300/80`,title:`Local-only land — not pushed to origin`,children:`· local only`}),(0,Y.jsx)(`span`,{className:`text-emerald-300/50`,children:J(e.occurredAt??e.createdAt)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function Je({msg:e}){let t=typeof e.payload?.kind==`string`?e.payload.kind:``;if(t===`branch.landed`)return(0,Y.jsx)(qe,{msg:e});let n=We[t]??o,r=Ge[t]??Ke(t);return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-border bg-muted/30 px-2.5 py-1 text-xs text-muted-foreground`,children:[(0,Y.jsx)(n,{className:`h-3 w-3`}),(0,Y.jsx)(`span`,{children:r}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60`,children:J(e.occurredAt??e.createdAt)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var Ye={"spawned-child":{ready:`spawned`,exited:`spawned · exited`,failed:`spawn failed`},"spawned-by":{ready:`spawned by`,exited:`spawned by`,failed:`spawned by`}},Xe={"spawned-child-ready":i,"spawned-child-exited":x,"spawned-child-failed":D,"spawned-by-ready":S,"spawned-by-exited":S,"spawned-by-failed":S},Ze={"spawned-child-ready":`text-emerald-400`,"spawned-child-exited":`text-zinc-400`,"spawned-child-failed":`text-red-400`,"spawned-by-ready":`text-blue-400`,"spawned-by-exited":`text-blue-400`,"spawned-by-failed":`text-blue-400`};function Qe({entry:e}){let t=`${e.direction}-${e.status}`,n=Ye[e.direction]?.[e.status]??e.direction,r=Xe[t]??o,i=Ze[t]??`text-muted-foreground`,a=e.status===`failed`;return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:l(`flex items-center gap-1.5 rounded-full border bg-muted/30 px-2.5 py-1 text-xs`,a?`border-red-500/30`:`border-border`),children:[(0,Y.jsx)(r,{className:l(`h-3 w-3 shrink-0`,i)}),(0,Y.jsx)(`span`,{className:`text-muted-foreground`,children:n}),(0,Y.jsx)(X,{agentId:e.agentId}),e.reason&&a&&(0,Y.jsxs)(`span`,{className:`text-red-400/80 max-w-[120px] truncate`,title:e.reason,children:[`— `,e.reason]}),(0,Y.jsx)(`span`,{className:`text-muted-foreground/60 shrink-0`,children:J(e.timestamp)})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}var $e={memory:M,instructions:a,tools:m,comms:o,knowledge:te,context:f},Z={memory:`border-emerald-500/25 bg-emerald-500/10 text-emerald-300`,instructions:`border-sky-500/25 bg-sky-500/10 text-sky-300`,tools:`border-amber-500/25 bg-amber-500/10 text-amber-300`,comms:`border-violet-500/25 bg-violet-500/10 text-violet-300`,knowledge:`border-cyan-500/25 bg-cyan-500/10 text-cyan-300`,context:`border-zinc-500/25 bg-zinc-500/10 text-zinc-300`};function et(e){try{return JSON.stringify(e,null,2)}catch{return String(e)}}function tt({entry:e}){let[t,n]=(0,V.useState)(!1),r=e.event,i=$e[r.category]??A;return(0,Y.jsx)(`div`,{className:`flex justify-center py-2 my-1`,children:(0,Y.jsxs)(`div`,{className:l(`w-full max-w-[85%] md:max-w-[75%] rounded-lg border px-2.5 py-1.5 text-xs shadow-sm`,Z[r.category]??Z.context),children:[(0,Y.jsxs)(`button`,{type:`button`,className:`flex w-full min-w-0 items-center gap-1.5 text-left`,onClick:()=>n(e=>!e),children:[(0,Y.jsx)(i,{className:`h-3.5 w-3.5 shrink-0`}),(0,Y.jsx)(`span`,{className:`shrink-0 font-medium`,children:r.category}),(0,Y.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-foreground/80`,children:r.summary}),(0,Y.jsx)(`span`,{className:`shrink-0 text-muted-foreground/60`,children:J(r.timestamp)}),(0,Y.jsx)(C,{className:l(`h-3.5 w-3.5 shrink-0 transition-transform`,t&&`rotate-90`)})]}),t&&(0,Y.jsx)(`pre`,{className:`mt-2 max-h-72 overflow-auto rounded-md border border-border/60 bg-background/75 p-2 font-mono text-[11px] leading-relaxed text-muted-foreground whitespace-pre-wrap break-words`,children:et(r.detail)})]})})}function nt({blockedLabel:e,onInterrupt:t}){return e?(0,Y.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,Y.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-red-500/30 px-4`,children:[(0,Y.jsx)(D,{className:`w-3.5 h-3.5 text-red-400`}),(0,Y.jsxs)(`span`,{className:`text-xs text-red-300`,children:[`blocked: `,e]})]})}):(0,Y.jsx)(`div`,{className:`flex justify-start mb-3 animate-in fade-in slide-in-from-bottom-1 duration-150`,children:(0,Y.jsxs)(`div`,{className:`flex h-9 items-center gap-2 rounded-2xl rounded-bl-sm bg-card ring-1 ring-foreground/10 px-4`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,Y.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_infinite]`}),(0,Y.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.2s_infinite]`}),(0,Y.jsx)(`span`,{className:`w-1.5 h-1.5 rounded-full bg-yellow-400 animate-[pulse_1.4s_ease-in-out_0.4s_infinite]`})]}),(0,Y.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`working`}),t&&(0,Y.jsxs)(`button`,{onClick:t,title:`Interrupt`,className:`ml-1 flex items-center gap-1 rounded-full px-1.5 py-0.5 text-xs text-muted-foreground hover:text-red-300 hover:bg-red-500/10 transition-colors`,children:[(0,Y.jsx)(k,{className:`w-3.5 h-3.5`}),`Stop`]})]})})}var Q=`agent-relay:chat-hide-tools`,$=(()=>{let e=new Set,t=(()=>{try{return window.localStorage.getItem(Q)===`on`}catch{return!1}})(),n=()=>e.forEach(e=>e());return typeof window<`u`&&window.addEventListener(`storage`,e=>{e.key===Q&&(t=e.newValue===`on`,n())}),{subscribe(t){return e.add(t),()=>e.delete(t)},get:()=>t,toggle(){t=!t;try{window.localStorage.setItem(Q,t?`on`:`off`)}catch{}n()}}})();function rt(){return[(0,V.useSyncExternalStore)($.subscribe,$.get,()=>!1),$.toggle]}function it({steps:e,showReasoning:t,issueRepo:n}){let[r,i]=rt(),a=t?e:e.filter(e=>e.kind!==`reasoning`);if(!a.length)return null;let o=a.filter(e=>e.kind===`tool`).length;return(0,Y.jsx)(`div`,{className:`flex justify-start mb-2`,children:(0,Y.jsxs)(`div`,{className:`max-w-[85%] md:max-w-[75%] min-w-0 space-y-1.5`,children:[a.map(e=>e.kind===`narration`?(0,Y.jsx)(B,{text:e.text,issueRepo:n,className:`text-sm leading-relaxed break-words text-foreground/90 min-w-0`},e.id):e.kind===`reasoning`?(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground/80`,children:[(0,Y.jsx)(M,{className:`w-3.5 h-3.5 mt-0.5 shrink-0 opacity-70`}),(0,Y.jsx)(B,{text:e.text,issueRepo:n,className:`italic break-words min-w-0`})]},e.id):r?null:(0,Y.jsxs)(`div`,{className:`flex items-start gap-1.5 text-xs leading-relaxed text-muted-foreground`,children:[(0,Y.jsx)(y,{className:`w-3 h-3 mt-0.5 shrink-0 opacity-70`}),(0,Y.jsxs)(`span`,{className:`min-w-0 break-words`,children:[(0,Y.jsx)(`span`,{className:`font-medium`,children:e.label||`tool`}),e.text&&e.text.trim()&&e.text.trim()!==(e.label??``).trim()?(0,Y.jsxs)(`span`,{className:`opacity-70`,children:[` — `,e.text]}):null]})]},e.id)),o>0&&(0,Y.jsxs)(`button`,{onClick:i,className:`flex items-center gap-1 text-[11px] text-muted-foreground/50 hover:text-muted-foreground transition-colors text-left`,children:[(0,Y.jsx)(C,{className:l(`w-3 h-3 shrink-0 transition-transform`,!r&&`rotate-90`)}),(0,Y.jsx)(`span`,{children:r?`show ${o} tool step${o===1?``:`s`}`:`hide tool steps`})]})]})})}function at({date:e}){return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-3 py-3 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsx)(`span`,{className:`text-xs font-medium text-muted-foreground`,children:He(e)}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function ot({timestamp:e}){let t=new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,year:`numeric`,hour:`2-digit`,minute:`2-digit`});return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`span`,{className:`text-xs text-muted-foreground/60`,children:[`created `,t]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function st({history:e}){let t=e.sourceAgentLabel||e.sourcePeerId,n=e.entries.length;return(0,Y.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-2 my-1`,children:[(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`}),(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 rounded-full border border-dashed border-border bg-muted/30 px-2 py-1 text-[11px] text-muted-foreground`,children:[(0,Y.jsx)(u,{className:`h-3 w-3`}),(0,Y.jsxs)(`span`,{children:[`forked history from `,t]}),(0,Y.jsxs)(`span`,{className:`text-muted-foreground/60`,children:[n,` `,n===1?`entry`:`entries`]})]}),(0,Y.jsx)(`div`,{className:`h-px flex-1 bg-border`})]})}function ct({entry:e,sourceLabel:t,issueRepo:n}){let r=e.message,i=F(r),a=e.originalFrom===L;return(0,Y.jsx)(`div`,{className:l(`flex mb-3 opacity-80`,a?`justify-end`:`justify-start`),children:(0,Y.jsx)(`div`,{className:`max-w-[85%] md:max-w-[75%]`,children:(0,Y.jsxs)(`div`,{className:l(`rounded-2xl border border-dashed px-3.5 py-2 text-sm select-text`,a?`border-primary/25 bg-primary/10 text-foreground rounded-br-sm`:`border-border bg-card/70 rounded-bl-sm`),children:[(0,Y.jsxs)(`div`,{className:l(`mb-1 text-[10px] uppercase tracking-normal`,a?`text-primary/70`:`text-muted-foreground`),children:[`forked history · `,a?`you`:t||e.originalFrom]}),(0,Y.jsx)(B,{text:i,rawBody:r.body,issueRepo:n,className:`leading-relaxed`}),(0,Y.jsxs)(`p`,{className:l(`mt-1 flex items-center justify-end gap-1.5 text-xs`,a?`text-primary/60`:`text-muted-foreground`),children:[(0,Y.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.originalMessageId]}),(0,Y.jsx)(`span`,{children:J(e.originalCreatedAt)})]})]})})})}function lt({msg:e,issueRepo:t}){let n=F(e),r=J(e.occurredAt??e.createdAt);return(0,Y.jsx)(`div`,{"data-msg-id":e.id,className:`mb-3`,children:(0,Y.jsxs)(`div`,{className:`rounded-xl border border-primary/30 bg-primary/[0.06] px-3.5 py-2.5 shadow-sm`,children:[(0,Y.jsxs)(`div`,{className:`mb-1.5 flex items-center gap-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary/80`,children:[(0,Y.jsx)(A,{className:`h-3.5 w-3.5`}),(0,Y.jsx)(`span`,{children:`Initial prompt`}),(0,Y.jsx)(`span`,{className:`ml-auto text-[10px] font-normal normal-case text-muted-foreground/60`,children:r})]}),(0,Y.jsx)(B,{text:n,rawBody:e.body,issueRepo:t,className:`text-sm leading-relaxed text-foreground`})]})})}function ut({scrollEl:e,timeline:t}){let[n,r]=(0,V.useState)(!0),[i,a]=(0,V.useState)(null),[o,s]=(0,V.useState)(null),[c,u]=(0,V.useState)(!1),d=(0,V.useMemo)(()=>{for(let e=t.length-1;e>=0;e--){let n=t[e];if(!(!n||n.type!==`message`&&n.type!==`initial-prompt`)&&n.msg.from===`user`)return{id:n.msg.id,body:F(n.msg)}}return null},[t]);if((0,V.useEffect)(()=>{if(!d||!e){r(!0);return}let t=null,n=null,i=()=>{let i=e.querySelector(`[data-msg-id="${d.id}"]`);if(!i){t?.disconnect(),t=null,n=null,r(!1);return}let a=i.getBoundingClientRect(),o=e.getBoundingClientRect();u(a.top<o.top),i!==n&&(t?.disconnect(),n=i,t=new IntersectionObserver(([e])=>{e&&r(e.isIntersecting)},{root:e,threshold:0}),t.observe(i))};return i(),e.addEventListener(`scroll`,i,{passive:!0}),()=>{t?.disconnect(),e.removeEventListener(`scroll`,i)}},[d?.id,e]),n||!d||!d.body.trim())return null;let f=i?.id===d.id?i.value:!1,p=o?.id===d.id?o.value:!1;function m(){!e||!d||e.querySelector(`[data-msg-id="${d.id}"]`)?.scrollIntoView({behavior:`smooth`,block:`center`})}let h=c?`↑`:`↓`;return p?(0,Y.jsx)(`div`,{className:`flex shrink-0 bg-card/45 border-b border-border`,children:(0,Y.jsxs)(`button`,{type:`button`,className:`w-full flex items-center justify-center gap-1.5 py-1 text-[11px] text-primary/60 hover:text-primary transition-colors`,onClick:()=>s({id:d.id,value:!1}),children:[(0,Y.jsx)(`span`,{children:`Your prompt`}),(0,Y.jsx)(_,{className:`w-3 h-3`})]})}):(0,Y.jsxs)(`section`,{className:`flex shrink-0 flex-col border-b border-border bg-card/45 px-3 py-2`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] text-muted-foreground mb-0.5`,children:[(0,Y.jsx)(`span`,{className:`font-medium text-primary/70`,children:`Your prompt`}),(0,Y.jsxs)(`button`,{type:`button`,className:`ml-auto hover:text-foreground transition-colors`,onClick:m,children:[h,` scroll to original`]}),(0,Y.jsx)(`button`,{type:`button`,className:`hover:text-foreground transition-colors`,onClick:()=>s({id:d.id,value:!0}),title:`Minimize`,children:(0,Y.jsx)(g,{className:`w-3 h-3`})})]}),(0,Y.jsx)(`p`,{className:l(`text-sm text-foreground leading-snug cursor-pointer`,!f&&`line-clamp-2`),onClick:()=>a({id:d.id,value:!f}),children:d.body})]})}function dt(){return(0,V.useSyncExternalStore)(e=>N.subscribe(e),()=>N.getPlayingKey(),()=>null)}function ft({attachment:e,outbound:t}){let n=e.kind===`image`,i=e.title||e.artifactId,[o,s]=(0,V.useState)(null),[c,u]=(0,V.useState)(null),[f,p]=(0,V.useState)(!1),[m,h]=(0,V.useState)(!1);(0,V.useEffect)(()=>{let t=!1,n=null;async function i(){p(!0),u(null),s(null);try{let i=await r(`/artifacts/${encodeURIComponent(e.artifactId)}/content`);if(t)return;n=URL.createObjectURL(i),s(n)}catch(e){t||u(e.message)}finally{t||p(!1)}}return i(),()=>{t=!0,n&&URL.revokeObjectURL(n)}},[e.artifactId]);function g(){if(!o)return;let e=document.createElement(`a`);e.href=o,e.download=i,document.body.appendChild(e),e.click(),e.remove()}return n?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`button`,{type:`button`,onClick:()=>o&&h(!0),disabled:!o,className:`group/img mt-2 block overflow-hidden rounded-md border border-foreground/10 bg-black/10 text-left disabled:cursor-default relative`,children:o?(0,Y.jsxs)(Y.Fragment,{children:[(0,Y.jsx)(`img`,{src:o,alt:i,loading:`lazy`,className:`block max-h-72 max-w-full object-contain`}),(0,Y.jsx)(`span`,{className:`absolute inset-0 flex items-center justify-center bg-black/0 group-hover/img:bg-black/30 transition-colors`,children:(0,Y.jsx)(E,{className:`w-6 h-6 text-white opacity-0 group-hover/img:opacity-100 transition-opacity drop-shadow-md`})})]}):(0,Y.jsxs)(`span`,{className:l(`flex min-h-20 items-center gap-2 px-3 py-2 text-xs`,c?`text-red-400`:`text-muted-foreground`),children:[f?(0,Y.jsx)(O,{className:`h-4 w-4 animate-spin`}):(0,Y.jsx)(D,{className:`h-4 w-4`}),c||`Loading image`]})}),o&&(0,Y.jsx)(fe,{open:m,onOpenChange:h,children:(0,Y.jsxs)(de,{className:`max-w-[95vw] max-h-[95vh] w-auto p-0 bg-black/95 border-zinc-800 gap-0 overflow-hidden`,showCloseButton:!1,children:[(0,Y.jsx)(pe,{className:`sr-only`,children:i}),(0,Y.jsxs)(`div`,{className:`relative flex items-center justify-center min-h-[200px]`,children:[(0,Y.jsx)(`img`,{src:o,alt:i,className:`max-w-[93vw] max-h-[90vh] object-contain`}),(0,Y.jsxs)(`div`,{className:`absolute top-2 right-2 flex gap-1`,children:[(0,Y.jsx)(`button`,{type:`button`,onClick:g,className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Download`,children:(0,Y.jsx)(d,{className:`w-4 h-4`})}),(0,Y.jsx)(`button`,{type:`button`,onClick:()=>h(!1),className:`rounded-md bg-black/60 hover:bg-black/80 p-2 text-white transition-colors`,title:`Close`,children:(0,Y.jsx)(b,{className:`w-4 h-4`})})]})]})]})})]}):(0,Y.jsxs)(`button`,{type:`button`,onClick:g,disabled:!o,className:l(`mt-2 flex w-full items-center gap-2 rounded-md border px-2.5 py-2 text-left text-xs transition-colors disabled:cursor-default disabled:opacity-70`,t?`border-primary-foreground/20 bg-primary-foreground/10 hover:bg-primary-foreground/15`:`border-border bg-background hover:bg-muted`),children:[f?(0,Y.jsx)(O,{className:`h-4 w-4 shrink-0 animate-spin`}):c?(0,Y.jsx)(D,{className:`h-4 w-4 shrink-0 text-red-400`}):(0,Y.jsx)(a,{className:`h-4 w-4 shrink-0`}),(0,Y.jsx)(`span`,{className:l(`min-w-0 flex-1 truncate`,c&&`text-red-400`),children:c||i}),(0,Y.jsx)(d,{className:`h-3.5 w-3.5 shrink-0`})]})}function pt({open:e,onToggle:t,onReact:n}){return(0,Y.jsxs)(`div`,{className:`relative shrink-0`,children:[(0,Y.jsx)(`button`,{type:`button`,title:`Add reaction`,onClick:t,className:l(`inline-flex h-5 w-6 items-center justify-center rounded-full border border-border bg-popover text-muted-foreground shadow-sm transition hover:bg-muted hover:text-foreground`,e?`opacity-100`:`opacity-0 pointer-events-none md:group-hover/msg:opacity-100 md:group-hover/msg:pointer-events-auto`),children:(0,Y.jsx)(ne,{className:`h-3 w-3`})}),e&&(0,Y.jsx)(`div`,{className:`absolute bottom-full left-0 z-30 mb-1 flex gap-0.5 rounded-full border border-border bg-popover p-0.5 shadow-md`,children:Me.map(e=>(0,Y.jsx)(`button`,{type:`button`,title:`React ${e}`,onClick:()=>n(e),className:`inline-flex h-6 w-7 items-center justify-center rounded-full text-xs transition-colors hover:bg-muted`,children:e},e))})]})}function mt({msg:e,peer:n}){let[r,i]=(0,V.useState)(!1),a=P(e=>e.agentsById),o=e.from===n,s=(o?e.to:e.from)||``,c=a[o?n:s]?.issueRepo??a[n]?.issueRepo,u=!s||s===`broadcast`||s.includes(`:`),d=F(e),f=J(e.occurredAt??e.createdAt),p=o?t:S;return(0,Y.jsx)(`div`,{"data-msg-id":e.id,className:`flex justify-center mb-1.5`,children:(0,Y.jsxs)(`div`,{className:`w-full max-w-[94%] rounded-md border border-border/50 bg-muted/15 px-2.5 py-1`,children:[(0,Y.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs cursor-pointer select-none`,onClick:()=>i(e=>!e),children:[(0,Y.jsx)(C,{className:l(`h-3 w-3 shrink-0 text-muted-foreground/60 transition-transform`,r&&`rotate-90`)}),(0,Y.jsx)(p,{className:`h-3 w-3 shrink-0 text-muted-foreground/70`}),(0,Y.jsxs)(`span`,{className:`shrink-0 text-muted-foreground`,children:[`Message `,o?`to`:`from`]}),u?(0,Y.jsx)(`span`,{className:`shrink-0 font-medium text-muted-foreground`,children:ce(s,a)}):(0,Y.jsx)(X,{agentId:s,className:`shrink-0 px-0.5 text-foreground/80`}),!r&&(0,Y.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-muted-foreground/50`,children:d}),(0,Y.jsx)(`span`,{className:`ml-auto shrink-0 text-muted-foreground/40`,children:f})]}),r&&(0,Y.jsx)(`div`,{className:`mt-1.5 pl-5`,children:(0,Y.jsx)(B,{text:d,rawBody:e.body,issueRepo:c,className:`text-sm leading-relaxed text-foreground/90`})})]})})}var ht=(0,V.memo)(function({msg:e,peer:t,onOpenReferencedPath:n,onPreviewReferencedPath:r,onPreviewReferencedPathEnd:i}){if(e.from!==`user`&&e.to!==`user`)return(0,Y.jsx)(mt,{msg:e,peer:t});let a=e.from===L,o=P(e=>e.reactToMessage),s=P(e=>e.voiceTtsEnabled),c=dt(),u=P(e=>{let n=e.agentsById[t]?.meta?.cwd;return typeof n==`string`?n:``}),d=P(e=>e.agentsById[t]?.issueRepo),[f,p]=(0,V.useState)(!1),m=(0,V.useRef)(null),g=(0,V.useRef)(null),_=(0,V.useRef)(!1),v=F(e),ee=J(e.occurredAt??e.createdAt),y=je(e),b=Ne(e),x=a?Pe(e,t):null,S=x?.icon,C=c===String(e.id),w=s&&!a&&!q(e)&&v.trim().length>0;function T(t){t.stopPropagation(),C?N.bargeIn():N.speak(e.body,String(e.id))}(0,V.useEffect)(()=>{if(!f)return;function e(e){Ae()||m.current&&!m.current.contains(e.target)&&p(!1)}return document.addEventListener(`mousedown`,e),document.addEventListener(`touchstart`,e),()=>{document.removeEventListener(`mousedown`,e),document.removeEventListener(`touchstart`,e)}},[f]);function E(e){return Ee(u||`/`,e)}function D(e,t){let r=E(e);n?.(r,t)}function O(e,t,n){let i=E(e);r?.(i,t,n)}function A(t){o(e,t),p(!1)}function te(e){e.button===0&&(g.current={x:e.clientX,y:e.clientY},_.current=!1)}function j(e){let t=g.current;t&&(Math.abs(e.clientX-t.x)>3||Math.abs(e.clientY-t.y)>3)&&(_.current=!0)}function ne(t){if(!(q(e)||a)&&!t.target.closest(`a,button,input,textarea,select,[role="button"]`)){if(_.current||Ae()){_.current=!1;return}p(e=>!e)}}return(0,Y.jsx)(`div`,{"data-msg-id":e.id,className:l(`group/msg flex mb-3`,a?`justify-end`:`justify-start`),children:(0,Y.jsxs)(`div`,{ref:m,className:`relative max-w-[85%] md:max-w-[75%]`,children:[w&&(0,Y.jsx)(`button`,{type:`button`,title:C?`Stop playback`:`Play aloud`,onClick:T,className:l(`absolute -top-2 -right-2 z-20 inline-flex h-6 w-6 items-center justify-center rounded-full border bg-popover shadow-sm transition`,C?`border-primary/50 text-primary opacity-100`:`border-border text-muted-foreground opacity-70 hover:bg-muted hover:text-foreground hover:opacity-100 [@media(hover:hover)]:md:opacity-0 [@media(hover:hover)]:md:group-hover/msg:opacity-100`),children:C?(0,Y.jsx)(k,{className:`h-3.5 w-3.5 animate-pulse`}):(0,Y.jsx)(h,{className:`h-3.5 w-3.5`})}),(0,Y.jsxs)(`div`,{className:l(`rounded-2xl px-3.5 py-2 text-sm select-text`,!a&&!q(e)&&`cursor-pointer`,a?`bg-primary text-primary-foreground rounded-br-sm`:`bg-card ring-1 ring-foreground/10 rounded-bl-sm`),onPointerDown:te,onPointerMove:j,onClick:ne,children:[e.subject&&(0,Y.jsx)(`p`,{className:l(`text-xs font-semibold mb-1`,a?`text-primary-foreground/70`:`text-muted-foreground`),children:e.subject}),(0,Y.jsx)(B,{text:v,rawBody:e.body,issueRepo:d,className:`leading-relaxed`,onOpenPath:D,onPreviewPath:O,onPreviewPathEnd:i,resolvePathTitle:(e,t)=>`${E(e)}${t?`:${t}`:``}`}),y.map(t=>(0,Y.jsx)(ft,{attachment:t,outbound:a},`${e.id}-${t.artifactId}-${t.role||``}`)),(0,Y.jsxs)(`p`,{className:l(`text-xs mt-1 flex items-center gap-1.5`,a?`justify-end text-primary-foreground/60`:`justify-end text-muted-foreground`),children:[(0,Y.jsxs)(`span`,{className:`opacity-40`,children:[`#`,e.id]}),(0,Y.jsx)(`span`,{children:ee}),x&&S&&(0,Y.jsxs)(`span`,{className:l(`inline-flex items-center gap-1`,x.tone===`ok`&&`text-emerald-300`,x.tone===`warn`&&`text-amber-200`,x.tone===`danger`&&`text-red-200`),title:x.title,children:[(0,Y.jsx)(S,{className:`h-3 w-3`}),x.label]})]})]}),!q(e)&&b.length>0&&(0,Y.jsxs)(`div`,{className:l(`flex flex-wrap items-center gap-0.5 -mt-1 relative z-10`,a?`justify-end pr-2`:`justify-start pl-2`),children:[!a&&(0,Y.jsx)(pt,{open:f,onToggle:()=>p(e=>!e),onReact:A}),b.map(e=>(0,Y.jsxs)(`button`,{type:`button`,title:e.actors.join(`, `),onClick:()=>A(e.emoji),className:l(`inline-flex h-5 items-center gap-0.5 rounded-full border px-1.5 text-[11px] shadow-sm transition-colors`,e.mine?`border-primary/40 bg-primary/10 text-primary`:`border-border bg-background hover:bg-muted text-foreground`),children:[(0,Y.jsx)(`span`,{children:e.emoji}),e.count>1&&(0,Y.jsx)(`span`,{children:e.count})]},e.emoji))]}),!q(e)&&!a&&b.length===0&&(0,Y.jsx)(`div`,{className:`absolute -bottom-2.5 left-1 z-20`,children:(0,Y.jsx)(pt,{open:f,onToggle:()=>p(e=>!e),onReact:A})})]})})});export{xe as C,Ie as S,Ce as T,Oe as _,ot as a,ze as b,ct as c,tt as d,Ue as f,Re as g,Te as h,nt as i,lt as l,Le as m,it as n,at as o,ut as p,Qe as r,st as s,ht as t,Je as u,De as v,Se as w,ke as x,Be as y};
3
- //# sourceMappingURL=MessageBubble-opNe8Lu2.js.map