agent-relay-server 0.58.0 → 0.59.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 (135) hide show
  1. package/docs/openapi.json +1 -1
  2. package/package.json +2 -2
  3. package/public/assets/{MessageBubble-CHKzD4RY.js → MessageBubble-BrEKymoV.js} +2 -2
  4. package/public/assets/{MessageBubble-CHKzD4RY.js.map → MessageBubble-BrEKymoV.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-BFVTJa0q.js → PlanGraphPanel-CXix1C-H.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-BFVTJa0q.js.map → PlanGraphPanel-CXix1C-H.js.map} +1 -1
  7. package/public/assets/{activity-M-dFLU_O.js → activity-CRafQ1Je.js} +2 -2
  8. package/public/assets/{activity-M-dFLU_O.js.map → activity-CRafQ1Je.js.map} +1 -1
  9. package/public/assets/{agent-profiles-CvHSoyCX.js → agent-profiles-DW4o5-ND.js} +2 -2
  10. package/public/assets/{agent-profiles-CvHSoyCX.js.map → agent-profiles-DW4o5-ND.js.map} +1 -1
  11. package/public/assets/agents-Cbegv0Hm.js +2 -0
  12. package/public/assets/{agents-DZBM5dp_.js.map → agents-Cbegv0Hm.js.map} +1 -1
  13. package/public/assets/analytics-DX6T7JX3.js +910 -0
  14. package/public/assets/{analytics-bvjb3Urs.js.map → analytics-DX6T7JX3.js.map} +1 -1
  15. package/public/assets/{automation-CDSn9Uq-.js → automation-CzSBv4gg.js} +2 -2
  16. package/public/assets/{automation-CDSn9Uq-.js.map → automation-CzSBv4gg.js.map} +1 -1
  17. package/public/assets/{badge-Dj6PREuI.js → badge-Cy6qO_Jz.js} +2 -2
  18. package/public/assets/{badge-Dj6PREuI.js.map → badge-Cy6qO_Jz.js.map} +1 -1
  19. package/public/assets/{branch-state-badge-CdYg2HYc.js → branch-state-badge-CRA50r81.js} +2 -2
  20. package/public/assets/{branch-state-badge-CdYg2HYc.js.map → branch-state-badge-CRA50r81.js.map} +1 -1
  21. package/public/assets/{button-Cqpufqam.js → button-73wpRw65.js} +2 -2
  22. package/public/assets/{button-Cqpufqam.js.map → button-73wpRw65.js.map} +1 -1
  23. package/public/assets/{card-OmDF73CE.js → card-BU6PvVHv.js} +2 -2
  24. package/public/assets/{card-OmDF73CE.js.map → card-BU6PvVHv.js.map} +1 -1
  25. package/public/assets/{channels-BkxrdOFZ.js → channels-B1MQCPCT.js} +2 -2
  26. package/public/assets/{channels-BkxrdOFZ.js.map → channels-B1MQCPCT.js.map} +1 -1
  27. package/public/assets/chat-BqIaFYGJ.js +2 -0
  28. package/public/assets/{chat-YzX1z76l.js.map → chat-BqIaFYGJ.js.map} +1 -1
  29. package/public/assets/{connectors-Bg3rHgl_.js → connectors-C9aFJIrh.js} +2 -2
  30. package/public/assets/{connectors-Bg3rHgl_.js.map → connectors-C9aFJIrh.js.map} +1 -1
  31. package/public/assets/{copy-button-DI7b8A7_.js → copy-button-HRopUwui.js} +2 -2
  32. package/public/assets/{copy-button-DI7b8A7_.js.map → copy-button-HRopUwui.js.map} +1 -1
  33. package/public/assets/display-CketawEF.js.map +1 -1
  34. package/public/assets/{dist-CNjnTZEI.js → dist-CC5f7oYw.js} +2 -2
  35. package/public/assets/{dist-CNjnTZEI.js.map → dist-CC5f7oYw.js.map} +1 -1
  36. package/public/assets/{dist-DkeTrbTA.js → dist-CLHMeXYi.js} +2 -2
  37. package/public/assets/{dist-DkeTrbTA.js.map → dist-CLHMeXYi.js.map} +1 -1
  38. package/public/assets/{dist-C5t_OxI0.js → dist-Ci1MM51P.js} +2 -2
  39. package/public/assets/{dist-C5t_OxI0.js.map → dist-Ci1MM51P.js.map} +1 -1
  40. package/public/assets/{dist-CV3sgFiv.js → dist-Cko2KPW8.js} +2 -2
  41. package/public/assets/{dist-CV3sgFiv.js.map → dist-Cko2KPW8.js.map} +1 -1
  42. package/public/assets/dist-D41tzJYg.js +2 -0
  43. package/public/assets/{dist-yYauqYKR.js.map → dist-D41tzJYg.js.map} +1 -1
  44. package/public/assets/{dist-CoUvwLTy.js → dist-DFLciw0h.js} +2 -2
  45. package/public/assets/{dist-CoUvwLTy.js.map → dist-DFLciw0h.js.map} +1 -1
  46. package/public/assets/dist-DUoZnlB2.js +2 -0
  47. package/public/assets/{dist-DmhyU0Na.js.map → dist-DUoZnlB2.js.map} +1 -1
  48. package/public/assets/dist-De2oguBm.js +2 -0
  49. package/public/assets/{dist-DxkMwkrr.js.map → dist-De2oguBm.js.map} +1 -1
  50. package/public/assets/{dist-1x-LE9Uk.js → dist-DmN94rc8.js} +2 -2
  51. package/public/assets/{dist-1x-LE9Uk.js.map → dist-DmN94rc8.js.map} +1 -1
  52. package/public/assets/{dist-DV2tZ2fq.js → dist-Kkpnjx_M.js} +2 -2
  53. package/public/assets/{dist-DV2tZ2fq.js.map → dist-Kkpnjx_M.js.map} +1 -1
  54. package/public/assets/{dist-Ca3ujqG_.js → dist-T7u7IZGJ.js} +2 -2
  55. package/public/assets/{dist-Ca3ujqG_.js.map → dist-T7u7IZGJ.js.map} +1 -1
  56. package/public/assets/{es2015-DcavLcQ0.js → es2015-Df08Opjx.js} +2 -2
  57. package/public/assets/{es2015-DcavLcQ0.js.map → es2015-Df08Opjx.js.map} +1 -1
  58. package/public/assets/{formatted-body-impl-D8i9qqL1.js → formatted-body-impl-DOXH7oDF.js} +2 -2
  59. package/public/assets/{formatted-body-impl-D8i9qqL1.js.map → formatted-body-impl-DOXH7oDF.js.map} +1 -1
  60. package/public/assets/index-DaNOQJci.css +2 -0
  61. package/public/assets/index-br_Y6Cvt.js +21 -0
  62. package/public/assets/{index-Ba2RDJaA.js.map → index-br_Y6Cvt.js.map} +1 -1
  63. package/public/assets/{input-C_dl_9fG.js → input-B2EDz-BE.js} +2 -2
  64. package/public/assets/{input-C_dl_9fG.js.map → input-B2EDz-BE.js.map} +1 -1
  65. package/public/assets/{insights-D1aANwZ2.js → insights-B1edq5lk.js} +2 -2
  66. package/public/assets/{insights-D1aANwZ2.js.map → insights-B1edq5lk.js.map} +1 -1
  67. package/public/assets/{integrations-BrAr9bap.js → integrations-Cm4fjp7_.js} +2 -2
  68. package/public/assets/{integrations-BrAr9bap.js.map → integrations-Cm4fjp7_.js.map} +1 -1
  69. package/public/assets/{lib-B3iMVsf-.js → lib-BZrjIp-o.js} +3 -3
  70. package/public/assets/{lib-B3iMVsf-.js.map → lib-BZrjIp-o.js.map} +1 -1
  71. package/public/assets/lucide-react-H_-8G79A.js +9 -0
  72. package/public/assets/{lucide-react-CMhBract.js.map → lucide-react-H_-8G79A.js.map} +1 -1
  73. package/public/assets/{maintenance-C-xspsMG.js → maintenance-D6zvw0fU.js} +2 -2
  74. package/public/assets/{maintenance-C-xspsMG.js.map → maintenance-D6zvw0fU.js.map} +1 -1
  75. package/public/assets/{managed-agents-Bf3ni0vo.js → managed-agents-CzfEznM1.js} +2 -2
  76. package/public/assets/{managed-agents-Bf3ni0vo.js.map → managed-agents-CzfEznM1.js.map} +1 -1
  77. package/public/assets/{markdown-preview-impl-DKbUBTf_.js → markdown-preview-impl-DZlCaTHQ.js} +2 -2
  78. package/public/assets/{markdown-preview-impl-DKbUBTf_.js.map → markdown-preview-impl-DZlCaTHQ.js.map} +1 -1
  79. package/public/assets/memory-CUUAzJDc.js +2 -0
  80. package/public/assets/{memory-DeLwJFwH.js.map → memory-CUUAzJDc.js.map} +1 -1
  81. package/public/assets/messages-6QZH46LG.js +2 -0
  82. package/public/assets/{messages-Cww6dZnM.js.map → messages-6QZH46LG.js.map} +1 -1
  83. package/public/assets/{orchestrators-DRjwROXw.js → orchestrators-CrcqkPuc.js} +2 -2
  84. package/public/assets/{orchestrators-DRjwROXw.js.map → orchestrators-CrcqkPuc.js.map} +1 -1
  85. package/public/assets/overview-418xXZO_.js +2 -0
  86. package/public/assets/{overview-DjcRomU_.js.map → overview-418xXZO_.js.map} +1 -1
  87. package/public/assets/pairs-CnedATgT.js +2 -0
  88. package/public/assets/{pairs-DT0u2fnW.js.map → pairs-CnedATgT.js.map} +1 -1
  89. package/public/assets/{react-dom-Dtl9-x_1.js → react-dom-WI6TjVe7.js} +2 -2
  90. package/public/assets/{react-dom-Dtl9-x_1.js.map → react-dom-WI6TjVe7.js.map} +1 -1
  91. package/public/assets/{security-Bwg3oFI8.js → security-DS13pbag.js} +2 -2
  92. package/public/assets/{security-Bwg3oFI8.js.map → security-DS13pbag.js.map} +1 -1
  93. package/public/assets/{select-Cariwv69.js → select-BOprGZDS.js} +2 -2
  94. package/public/assets/{select-Cariwv69.js.map → select-BOprGZDS.js.map} +1 -1
  95. package/public/assets/{settings-Bd6Ug3DO.js → settings-BgInn_f3.js} +4 -4
  96. package/public/assets/{settings-Bd6Ug3DO.js.map → settings-BgInn_f3.js.map} +1 -1
  97. package/public/assets/{store-BgJq_lN9.js → store-DHO_a8BD.js} +5 -5
  98. package/public/assets/{store-BgJq_lN9.js.map → store-DHO_a8BD.js.map} +1 -1
  99. package/public/assets/{tasks-DVz1zhOU.js → tasks-B-4oCPuv.js} +2 -2
  100. package/public/assets/{tasks-DVz1zhOU.js.map → tasks-B-4oCPuv.js.map} +1 -1
  101. package/public/assets/teams-sCQAs_QA.js +2 -0
  102. package/public/assets/{teams-TqFntFB_.js.map → teams-sCQAs_QA.js.map} +1 -1
  103. package/public/assets/{terminal-viewer-impl-OsJ5crlx.js → terminal-viewer-impl-BhqS2XpS.js} +3 -3
  104. package/public/assets/{terminal-viewer-impl-OsJ5crlx.js.map → terminal-viewer-impl-BhqS2XpS.js.map} +1 -1
  105. package/public/assets/{use-keyboard-viewport-BYHcL7sP.js → use-keyboard-viewport-fOL_3RHB.js} +2 -2
  106. package/public/assets/{use-keyboard-viewport-BYHcL7sP.js.map → use-keyboard-viewport-fOL_3RHB.js.map} +1 -1
  107. package/public/assets/{work-queue-B4b2jPLR.js → work-queue-BDhjlwUH.js} +2 -2
  108. package/public/assets/{work-queue-B4b2jPLR.js.map → work-queue-BDhjlwUH.js.map} +1 -1
  109. package/public/assets/workspaces-6I-C69nf.js +3 -0
  110. package/public/assets/{workspaces-m97LP4Eu.js.map → workspaces-6I-C69nf.js.map} +1 -1
  111. package/public/index.html +21 -21
  112. package/src/db/stats.ts +209 -38
  113. package/src/maintenance.ts +9 -2
  114. package/src/mcp.ts +3 -0
  115. package/src/project-instructions.ts +176 -0
  116. package/src/routes/agents-spawn.ts +2 -0
  117. package/src/routes/commands.ts +11 -5
  118. package/src/services/spawn-agent.ts +26 -1
  119. package/src/workspace-merge.ts +11 -0
  120. package/src/workspace-pr-completion.ts +57 -1
  121. package/public/assets/agents-DZBM5dp_.js +0 -2
  122. package/public/assets/analytics-bvjb3Urs.js +0 -910
  123. package/public/assets/chat-YzX1z76l.js +0 -2
  124. package/public/assets/dist-DmhyU0Na.js +0 -2
  125. package/public/assets/dist-DxkMwkrr.js +0 -2
  126. package/public/assets/dist-yYauqYKR.js +0 -2
  127. package/public/assets/index-Ba2RDJaA.js +0 -21
  128. package/public/assets/index-CtFXWxBJ.css +0 -2
  129. package/public/assets/lucide-react-CMhBract.js +0 -9
  130. package/public/assets/memory-DeLwJFwH.js +0 -2
  131. package/public/assets/messages-Cww6dZnM.js +0 -2
  132. package/public/assets/overview-DjcRomU_.js +0 -2
  133. package/public/assets/pairs-DT0u2fnW.js +0 -2
  134. package/public/assets/teams-TqFntFB_.js +0 -2
  135. package/public/assets/workspaces-m97LP4Eu.js +0 -3
@@ -113,6 +113,16 @@ interface RequestWorkspaceMergeOptions {
113
113
  reviewer?: string;
114
114
  /** Extra metadata merged onto the workspace row when moving to merge_planned. */
115
115
  metadata?: Record<string, unknown>;
116
+ /**
117
+ * Set when this "merge" is really a land-and-continue RECYCLE of a workspace whose PR
118
+ * already merged on the remote out-of-band (#423). The host preview is then a no-op
119
+ * (work is already in base) so `mergeWorkspace` recycles the live owner onto a fresh
120
+ * branch without merging anything — `result.merged` is false. The relay still owns the
121
+ * ground truth that a land happened (it observed `prMerged`), so it carries the merge
122
+ * SHA/subject here; the merge-result handler fires the `branch.landed` notice from it,
123
+ * giving full parity with a rebase-ff land-and-continue.
124
+ */
125
+ prLanded?: { sha?: string; subject?: string };
116
126
  }
117
127
 
118
128
  type RequestWorkspaceMergeResult =
@@ -253,6 +263,7 @@ export function requestWorkspaceMerge(workspace: WorkspaceRecord, opts: RequestW
253
263
  prBody,
254
264
  ...(autoMerge !== undefined ? { autoMerge } : {}),
255
265
  ...(opts.reviewer !== undefined ? { reviewer: opts.reviewer } : {}),
266
+ ...(opts.prLanded !== undefined ? { prLanded: opts.prLanded } : {}),
256
267
  requestedBy: opts.requestedBy,
257
268
  requestedAt: Date.now(),
258
269
  },
@@ -1,9 +1,65 @@
1
1
  import { isRecord } from "agent-relay-sdk";
2
2
  import { createCommand, getCommand } from "./commands-db";
3
- import { patchWorkspaceMetadata } from "./db";
3
+ import { createActivityEvent, patchWorkspaceMetadata } from "./db";
4
4
  import { handleReviewerPipelineScan, isAwaitingReviewerApproval } from "./reviewer-pipeline";
5
+ import { isOwnerAlive, requestWorkspaceMerge } from "./workspace-merge";
5
6
  import type { Command, WorkspaceAutoMergePolicy, WorkspaceMergePreview, WorkspaceRecord } from "./types";
6
7
 
8
+ /**
9
+ * Decide what to do when a workspace's PR has merged on the remote (`prMerged`/`landed`),
10
+ * out-of-band of the relay's land path. Splits on owner liveness:
11
+ *
12
+ * - LIVE owner → land-and-continue RECYCLE (#423). The rebase-ff land path recycles a live
13
+ * owner onto a fresh `agent/...-N` branch off the advanced base; a PR land never ran through
14
+ * it, stranding the owner on its merged branch at terminal `merged` (`relay_workspace_status`
15
+ * then reports "you don't own an isolated workspace"). Dispatch a `rebase-ff` merge carrying
16
+ * `prLanded` (the merge SHA/subject — our ground truth). The host honors prLanded and recycles
17
+ * the live owner onto a fresh branch cut off the UPDATED upstream base, returning it to
18
+ * `active` in the same CWD. (A bare no-op assumption would NOT hold for a squash merge onto an
19
+ * advanced base — local cherry/tree detection can't see the squash commit, so the host's own
20
+ * no-op derivation reports ahead>0 and would soft-loop via review_requested; prLanded is what
21
+ * short-circuits that, see `mergeWorkspace`.) Explicit `rebase-ff` so a (prMerged-gated,
22
+ * near-impossible) non-recycle never opens a duplicate PR; the merge-result handler fires the
23
+ * `branch.landed` notice from `prLanded` (SHA + subject) since the recycle reports no land.
24
+ * - GONE owner (offline/absent) → finalize terminal `merged` + store-ahead `branch.landed` for
25
+ * its next poll (#304). Signalled by `kind: "finalize"`; the caller invokes the finalizer.
26
+ *
27
+ * `kind: "wait"` means the per-repo merge lease is held this tick (a concurrent merge) — retry
28
+ * next sweep; the caller must NOT finalize, or it re-strands the live owner.
29
+ */
30
+ export function reconcileLandedPr(workspace: WorkspaceRecord, preview: WorkspaceMergePreview):
31
+ | { kind: "recycle"; command: Command }
32
+ | { kind: "wait"; reason: string }
33
+ | { kind: "finalize" } {
34
+ if (!isOwnerAlive(workspace.ownerAgentId)) return { kind: "finalize" };
35
+ const recycle = requestWorkspaceMerge(workspace, {
36
+ strategy: "rebase-ff",
37
+ requestedBy: "pr-land-recycle",
38
+ prLanded: {
39
+ sha: typeof preview.prMergeSha === "string" ? preview.prMergeSha : undefined,
40
+ subject: typeof preview.prMergeSubject === "string" ? preview.prMergeSubject : undefined,
41
+ },
42
+ });
43
+ if (recycle.ok) {
44
+ createActivityEvent({
45
+ clientId: `workspace-pr-recycle-${workspace.id}-${Date.now()}`,
46
+ kind: "state",
47
+ title: "Workspace recycling after PR land",
48
+ body: `${workspace.branch ?? workspace.id}'s PR merged into ${preview.baseRef ?? "base"} — recycling the live owner onto a fresh branch (land-and-continue)`,
49
+ meta: workspace.branch ?? workspace.id,
50
+ icon: "ti-git-merge",
51
+ view: "orchestrators",
52
+ metadata: { source: "server", maintenanceJobId: "workspace-conflict-scan", workspaceId: workspace.id, commandId: recycle.command.id, landedVia: "pr" },
53
+ });
54
+ return { kind: "recycle", command: recycle.command };
55
+ }
56
+ // 409 = lease held by an in-flight merge — retry next sweep, don't finalize (re-strands a
57
+ // live owner). Any other failure (e.g. lost worktree) falls through to finalize so the row
58
+ // doesn't loop forever in a reconcilable status.
59
+ if (recycle.status === 409) return { kind: "wait", reason: "recycle-lease-held" };
60
+ return { kind: "finalize" };
61
+ }
62
+
7
63
  const ACTIVE_COMMAND_STATUSES = new Set(["pending", "accepted", "running"]);
8
64
  const PASSING_CONCLUSIONS = new Set(["SUCCESS", "NEUTRAL", "SKIPPED"]);
9
65
  const PASSING_STATES = new Set(["SUCCESS"]);
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{At as t,B as n,Cn as r,G as i,I as a,J as o,Kn as s,Mn as c,On as l,P as u,Pn as d,Rt as f,g as p,i as m,l as h,m as g,st as _}from"./lucide-react-CMhBract.js";import{o as ee,t as v}from"./store-BgJq_lN9.js";import{G as y,K as b,U as x,V as S,a as C,d as w,i as te,n as ne}from"./display-CketawEF.js";import{o as T,r as E}from"./dist-DV2tZ2fq.js";import{t as D}from"./dist-CoUvwLTy.js";import{i as O,n as k}from"./dist-CV3sgFiv.js";import{t as A}from"./dist-C5t_OxI0.js";import{t as j}from"./dist-1x-LE9Uk.js";import{a as M,i as N,n as re,o as ie,r as ae,s as oe,t as P}from"./es2015-DcavLcQ0.js";import{a as F,i as se,n as I,r as L,t as R}from"./dist-Ca3ujqG_.js";import{t as z}from"./badge-Dj6PREuI.js";import{t as B}from"./button-Cqpufqam.js";import{t as ce}from"./copy-button-DI7b8A7_.js";import{B as le,H as V,P as ue,S as H,U,V as W,d as de,g as fe,h as pe,l as me,m as he,p as ge,u as _e,x as G}from"./index-Ba2RDJaA.js";import{n as ve,t as ye}from"./card-OmDF73CE.js";import{n as be,t as xe}from"./branch-state-badge-CdYg2HYc.js";var K=e(s(),1),q=d(),J=`Popover`,[Se,Ce]=O(J,[F]),Y=F(),[we,X]=Se(J),Te=e=>{let{__scopePopover:t,children:n,open:r,defaultOpen:i,onOpenChange:a,modal:o=!1}=e,s=Y(t),c=K.useRef(null),[l,u]=K.useState(!1),[d,f]=A({prop:r,defaultProp:i??!1,onChange:a,caller:J});return(0,q.jsx)(se,{...s,children:(0,q.jsx)(we,{scope:t,contentId:oe(),triggerRef:c,open:d,onOpenChange:f,onOpenToggle:K.useCallback(()=>f(e=>!e),[f]),hasCustomAnchor:l,onCustomAnchorAdd:K.useCallback(()=>u(!0),[]),onCustomAnchorRemove:K.useCallback(()=>u(!1),[]),modal:o,children:n})})};Te.displayName=J;var Ee=`PopoverAnchor`,De=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(Ee,n),a=Y(n),{onCustomAnchorAdd:o,onCustomAnchorRemove:s}=i;return K.useEffect(()=>(o(),()=>s()),[o,s]),(0,q.jsx)(R,{...a,...r,ref:t})});De.displayName=Ee;var Oe=`PopoverTrigger`,ke=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X(Oe,n),a=Y(n),o=T(t,i.triggerRef),s=(0,q.jsx)(D.button,{type:`button`,"aria-haspopup":`dialog`,"aria-expanded":i.open,"aria-controls":i.contentId,"data-state":Ve(i.open),...r,ref:o,onClick:k(e.onClick,i.onOpenToggle)});return i.hasCustomAnchor?s:(0,q.jsx)(R,{asChild:!0,...a,children:s})});ke.displayName=Oe;var Z=`PopoverPortal`,[Ae,je]=Se(Z,{forceMount:void 0}),Me=e=>{let{__scopePopover:t,forceMount:n,children:r,container:i}=e,a=X(Z,t);return(0,q.jsx)(Ae,{scope:t,forceMount:n,children:(0,q.jsx)(j,{present:n||a.open,children:(0,q.jsx)(N,{asChild:!0,container:i,children:r})})})};Me.displayName=Z;var Q=`PopoverContent`,Ne=K.forwardRef((e,t)=>{let n=je(Q,e.__scopePopover),{forceMount:r=n.forceMount,...i}=e,a=X(Q,e.__scopePopover);return(0,q.jsx)(j,{present:r||a.open,children:a.modal?(0,q.jsx)(Fe,{...i,ref:t}):(0,q.jsx)(Ie,{...i,ref:t})})});Ne.displayName=Q;var Pe=E(`PopoverContent.RemoveScroll`),Fe=K.forwardRef((e,t)=>{let n=X(Q,e.__scopePopover),r=K.useRef(null),i=T(t,r),a=K.useRef(!1);return K.useEffect(()=>{let e=r.current;if(e)return P(e)},[]),(0,q.jsx)(re,{as:Pe,allowPinchZoom:!0,children:(0,q.jsx)(Le,{...e,ref:i,trapFocus:n.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(e.onCloseAutoFocus,e=>{e.preventDefault(),a.current||n.triggerRef.current?.focus()}),onPointerDownOutside:k(e.onPointerDownOutside,e=>{let t=e.detail.originalEvent,n=t.button===0&&t.ctrlKey===!0;a.current=t.button===2||n},{checkForDefaultPrevented:!1}),onFocusOutside:k(e.onFocusOutside,e=>e.preventDefault(),{checkForDefaultPrevented:!1})})})}),Ie=K.forwardRef((e,t)=>{let n=X(Q,e.__scopePopover),r=K.useRef(!1),i=K.useRef(!1);return(0,q.jsx)(Le,{...e,ref:t,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:t=>{e.onCloseAutoFocus?.(t),t.defaultPrevented||(r.current||n.triggerRef.current?.focus(),t.preventDefault()),r.current=!1,i.current=!1},onInteractOutside:t=>{e.onInteractOutside?.(t),t.defaultPrevented||(r.current=!0,t.detail.originalEvent.type===`pointerdown`&&(i.current=!0));let a=t.target;n.triggerRef.current?.contains(a)&&t.preventDefault(),t.detail.originalEvent.type===`focusin`&&i.current&&t.preventDefault()}})}),Le=K.forwardRef((e,t)=>{let{__scopePopover:n,trapFocus:r,onOpenAutoFocus:i,onCloseAutoFocus:a,disableOutsidePointerEvents:o,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onInteractOutside:u,...d}=e,f=X(Q,n),p=Y(n);return ae(),(0,q.jsx)(M,{asChild:!0,loop:!0,trapped:r,onMountAutoFocus:i,onUnmountAutoFocus:a,children:(0,q.jsx)(ie,{asChild:!0,disableOutsidePointerEvents:o,onInteractOutside:u,onEscapeKeyDown:s,onPointerDownOutside:c,onFocusOutside:l,onDismiss:()=>f.onOpenChange(!1),children:(0,q.jsx)(L,{"data-state":Ve(f.open),role:`dialog`,id:f.contentId,...p,...d,ref:t,style:{...d.style,"--radix-popover-content-transform-origin":`var(--radix-popper-transform-origin)`,"--radix-popover-content-available-width":`var(--radix-popper-available-width)`,"--radix-popover-content-available-height":`var(--radix-popper-available-height)`,"--radix-popover-trigger-width":`var(--radix-popper-anchor-width)`,"--radix-popover-trigger-height":`var(--radix-popper-anchor-height)`}})})})}),$=`PopoverClose`,Re=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=X($,n);return(0,q.jsx)(D.button,{type:`button`,...r,ref:t,onClick:k(e.onClick,()=>i.onOpenChange(!1))})});Re.displayName=$;var ze=`PopoverArrow`,Be=K.forwardRef((e,t)=>{let{__scopePopover:n,...r}=e,i=Y(n);return(0,q.jsx)(I,{...i,...r,ref:t})});Be.displayName=ze;function Ve(e){return e?`open`:`closed`}var He=Te,Ue=ke,We=Me,Ge=Ne;function Ke({...e}){return(0,q.jsx)(He,{"data-slot":`popover`,...e})}function qe({...e}){return(0,q.jsx)(Ue,{"data-slot":`popover-trigger`,...e})}function Je({className:e,align:t=`center`,sideOffset:n=4,...r}){return(0,q.jsx)(We,{children:(0,q.jsx)(Ge,{"data-slot":`popover-content`,align:t,sideOffset:n,className:c(`z-50 flex w-72 origin-(--radix-popover-content-transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95`,e),...r})})}function Ye({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-header`,className:c(`flex flex-col gap-0.5 text-sm`,e),...t})}function Xe({className:e,...t}){return(0,q.jsx)(`div`,{"data-slot":`popover-title`,className:c(`font-medium`,e),...t})}function Ze({agent:e,childAgents:r=[],parentAgent:a}){let s=ee();v(e=>e.set);let c=v(e=>e.switchView),l=v(e=>e.openInboxThread),d=v(e=>e.openAgentDetail),m=v(e=>e.openPairInvite),T=v(e=>e.openRename),E=v(e=>e.openConfirm),D=v(e=>e.doAgentAction),O=v(e=>e.doDeleteAgent),k=v(e=>e.openFilesForAgent),A=v(e=>e.workspaceAction),j=v(e=>e.openWorkspaceFocus),{terminalOpen:M,terminalTarget:N,terminalOpening:re,openTerminal:ie,closeTerminal:ae}=be(e.id),oe=le(),P=te(s,e,ue(e),oe[e.id]||null),F=C(e,`shutdown`),se=C(e,`compact`),I=C(e,`clearContext`),L=!!(e.providerCapabilities?.terminal?.live?.read||e.providerCapabilities?.terminal?.attach?.create),R=!!(e.providerCapabilities?.terminal?.live?.write||e.providerCapabilities?.model?.provider===`claude`),V=ne(e),U=a?w(a):e.spawnedBy,W=r.length>0;return(0,q.jsxs)(q.Fragment,{children:[(0,q.jsx)(ye,{className:`group hover:border-zinc-600 transition-colors cursor-pointer`,onClick:()=>d(e),children:(0,q.jsxs)(ve,{className:`p-4`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2.5 mb-2.5`,children:[(0,q.jsx)(H,{agent:e,now:s,className:`mt-0.5`}),(0,q.jsx)(G,{agent:e}),(0,q.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,q.jsx)(`div`,{className:`text-sm font-medium truncate`,children:w(e)}),(0,q.jsx)(`div`,{className:`text-xs mt-0.5 ${y(P.tone)}`,children:P.label}),typeof e.meta?.cwd==`string`&&e.meta.cwd&&(0,q.jsx)(`button`,{type:`button`,className:`mt-0.5 block max-w-full truncate font-mono text-[10px] text-muted-foreground hover:text-foreground`,title:`Open ${e.meta.cwd} in Files`,onClick:t=>{t.stopPropagation(),k(e)},children:S(e.meta.cwd)})]}),e.branchState&&e.branchWorkspaceId&&(0,q.jsx)(xe,{state:e.branchState,className:`mt-0.5 shrink-0`,onClick:t=>{t.stopPropagation(),j(e.branchWorkspaceId)}})]}),P.badges.length>0&&(0,q.jsx)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:P.badges.map(e=>(0,q.jsx)(`span`,{className:`text-[10px] px-1.5 py-0.5 rounded-full font-medium ${e.className}`,children:e.label},e.label))}),(W||e.spawnedBy&&U)&&(0,q.jsxs)(`div`,{className:`mb-2 flex flex-wrap gap-1.5`,onClick:e=>e.stopPropagation(),children:[W&&(0,q.jsxs)(Ke,{children:[(0,q.jsx)(qe,{asChild:!0,children:(0,q.jsxs)(`button`,{type:`button`,className:`inline-flex h-6 max-w-full items-center gap-1.5 rounded-full border border-sky-500/30 bg-sky-500/10 px-2 text-[10px] font-medium text-sky-300 transition-colors hover:bg-sky-500/15`,title:`${r.length} live child ${r.length===1?`agent`:`agents`}`,children:[(0,q.jsx)(h,{className:`h-3 w-3`}),(0,q.jsx)(`span`,{children:r.length}),(0,q.jsx)(`span`,{className:`flex -space-x-1`,children:r.slice(0,4).map(e=>(0,q.jsx)(H,{agent:e,now:s,className:`h-2 w-2 ring-1 ring-background`},e.id))})]})}),(0,q.jsxs)(Je,{align:`start`,className:`w-80`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(Ye,{children:(0,q.jsx)(Xe,{children:`Team`})}),(0,q.jsx)(`div`,{className:`space-y-1.5`,children:r.map(e=>(0,q.jsxs)(`div`,{className:`rounded-md border border-border bg-card/60 p-2`,children:[(0,q.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,q.jsx)(H,{agent:e,now:s,className:`mt-1`}),(0,q.jsx)(G,{agent:e}),(0,q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,q.jsx)(`div`,{className:`truncate text-xs font-medium`,children:w(e)}),(0,q.jsx)(`div`,{className:`truncate text-[10px] text-muted-foreground`,children:e.providerCapabilities?.model?.alias||e.providerCapabilities?.model?.id||e.providerCapabilities?.model?.provider||e.status})]}),(0,q.jsx)(z,{variant:`outline`,className:`h-4 px-1.5 text-[9px]`,children:e.status})]}),(0,q.jsxs)(`div`,{className:`mt-2 flex gap-1`,children:[(0,q.jsx)(B,{size:`xs`,variant:`outline`,onClick:()=>d(e),children:`Open`}),(0,q.jsxs)(B,{size:`xs`,variant:`ghost`,onClick:()=>{l(e.id),c(`chat`)},children:[(0,q.jsx)(o,{className:`h-3 w-3`}),`Chat`]})]})]},e.id))})]})]}),e.spawnedBy&&U&&(0,q.jsx)(z,{variant:`outline`,className:`max-w-full text-[10px] text-muted-foreground`,children:(0,q.jsxs)(`span`,{className:`truncate`,children:[`spawned by `,U]})})]}),(e.tags.length>0||b(e.capabilities).length>0)&&(0,q.jsxs)(`div`,{className:`flex flex-wrap gap-1 mb-2`,children:[e.tags.slice(0,3).map(e=>(0,q.jsx)(z,{variant:`outline`,className:`text-[9px] px-1 py-0 h-4`,children:e},e)),b(e.capabilities).slice(0,2).map(e=>(0,q.jsx)(z,{variant:`secondary`,className:`text-[9px] px-1 py-0 h-4`,children:e},e))]}),(0,q.jsxs)(`div`,{className:`space-y-2 mb-2`,children:[(0,q.jsx)(pe,{agent:e}),(0,q.jsx)(he,{agent:e,compact:!0}),(0,q.jsx)(fe,{agent:e})]}),(0,q.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e.id!==`user`&&e.id!==`system`&&x(s,e.lastSeen)}),(0,q.jsxs)(`div`,{className:`flex gap-1 mt-2.5 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity`,onClick:e=>e.stopPropagation(),children:[(0,q.jsx)(ce,{value:e.id,label:`Copy agent ID`,size:`icon`,className:`h-7 w-7`,iconClassName:`w-3 h-3`}),(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Chat`,onClick:()=>{l(e.id),c(`chat`)},children:(0,q.jsx)(o,{className:`w-3 h-3`})}),(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Pair`,onClick:()=>m(e.id),children:(0,q.jsx)(_,{className:`w-3 h-3`})}),(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Rename`,onClick:()=>T(e),children:(0,q.jsx)(n,{className:`w-3 h-3`})}),L&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Terminal`,disabled:re,onClick:()=>void ie(),children:(0,q.jsx)(p,{className:`w-3 h-3`})}),(e.branchState===`changes`||e.branchState===`idle`)&&e.branchWorkspaceId&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-amber-400 hover:text-amber-300`,title:`Mark workspace ready — hand off to the auto-merge`,onClick:()=>E(`Mark Workspace Ready`,`Mark ${w(e)}'s branch ready to land? The relay auto-merge will rebase and land it.`,()=>A(e.branchWorkspaceId,`ready`)),children:(0,q.jsx)(t,{className:`w-3 h-3`})}),se&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Compact`,onClick:()=>E(`Compact Agent`,`Compact context for ${w(e)}?`,()=>D(e,`compact`,`agents-grid`)),children:(0,q.jsx)(i,{className:`w-3 h-3`})}),I&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7`,title:`Clear Context`,onClick:()=>E(`Clear Context`,`Clear context for ${w(e)}?`,()=>D(e,`clearContext`,`agents-grid`)),children:(0,q.jsx)(f,{className:`w-3 h-3`})}),F&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Shutdown`,onClick:()=>E(`Shutdown Agent`,`Shutdown ${w(e)}?`,()=>D(e,`shutdown`,`agents-grid`)),children:(0,q.jsx)(u,{className:`w-3 h-3`})}),V&&(0,q.jsx)(B,{size:`icon`,variant:`ghost`,className:`h-7 w-7 text-red-400 hover:text-red-300`,title:`Forget stale agent`,onClick:()=>E(`Forget Agent`,`Forget ${w(e)}?`,()=>O(e.id)),children:(0,q.jsx)(g,{className:`w-3 h-3`})})]})]})}),N&&(0,q.jsx)(ge,{open:M,onOpenChange:ae,orchestratorId:N.orchestratorId,session:N.session,interactive:N.interactive||R})]})}function Qe(){let e=v(e=>e.agentPresetFilter),t=v(e=>e.agentStatusFilter),n=v(e=>e.agentTagFilter),i=v(e=>e.agentHostFilter),o=v(e=>e.agentSort),s=v(e=>e.agentSortDir),c=v(e=>e.showOffline),u=v(e=>e.set),d=v(e=>e.openAgentSpawn),f=v(e=>e.agentsById),p=ee(),h=W(),g=U(),_=V(),y=me(h,p),b=de(h,p),x=e||t||n||i;function S(){u({agentPresetFilter:``,agentStatusFilter:``,agentTagFilter:``,agentHostFilter:``})}function C(){u({agentSortDir:s===`asc`?`desc`:`asc`})}return(0,q.jsxs)(`div`,{className:`space-y-4`,children:[(0,q.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,q.jsxs)(`select`,{value:e,onChange:e=>u({agentPresetFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`All agents`}),(0,q.jsx)(`option`,{value:`active`,children:`Active`}),(0,q.jsx)(`option`,{value:`claude`,children:`Claude`}),(0,q.jsx)(`option`,{value:`codex`,children:`Codex`}),(0,q.jsx)(`option`,{value:`paired`,children:`Paired`}),(0,q.jsx)(`option`,{value:`unpaired`,children:`Unpaired`}),(0,q.jsx)(`option`,{value:`offline_stale`,children:`Offline / Stale`})]}),(0,q.jsxs)(`select`,{value:t,onChange:e=>u({agentStatusFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any status`}),(0,q.jsx)(`option`,{value:`online`,children:`Online`}),(0,q.jsx)(`option`,{value:`idle`,children:`Idle`}),(0,q.jsx)(`option`,{value:`busy`,children:`Busy`}),(0,q.jsx)(`option`,{value:`offline`,children:`Offline`}),(0,q.jsx)(`option`,{value:`starting`,children:`Starting`})]}),g.length>0&&(0,q.jsxs)(`select`,{value:n,onChange:e=>u({agentTagFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any tag`}),g.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),_.length>1&&(0,q.jsxs)(`select`,{value:i,onChange:e=>u({agentHostFilter:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:``,children:`Any host`}),_.map(e=>(0,q.jsx)(`option`,{value:e,children:e},e))]}),(0,q.jsxs)(`select`,{value:o,onChange:e=>u({agentSort:e.target.value}),className:`h-8 rounded-md border border-border bg-card text-sm px-2 text-foreground`,children:[(0,q.jsx)(`option`,{value:`status`,children:`Sort: Status`}),(0,q.jsx)(`option`,{value:`name`,children:`Sort: Name`}),(0,q.jsx)(`option`,{value:`lastSeen`,children:`Sort: Last seen`}),(0,q.jsx)(`option`,{value:`created`,children:`Sort: Created`})]}),(0,q.jsx)(B,{size:`icon`,variant:`outline`,className:`h-8 w-8`,title:`Toggle sort direction`,onClick:C,children:s===`asc`?(0,q.jsx)(r,{className:`w-3.5 h-3.5`}):(0,q.jsx)(l,{className:`w-3.5 h-3.5`})}),(0,q.jsxs)(`label`,{className:`flex items-center gap-1.5 text-sm text-muted-foreground cursor-pointer select-none`,children:[(0,q.jsx)(`input`,{type:`checkbox`,checked:c,onChange:e=>u({showOffline:e.target.checked}),className:`rounded`}),`Show offline`]}),x&&(0,q.jsxs)(B,{size:`sm`,variant:`ghost`,className:`h-8 text-muted-foreground hover:text-foreground gap-1`,onClick:S,children:[(0,q.jsx)(m,{className:`w-3 h-3`}),`Clear filters`]}),(0,q.jsx)(`div`,{className:`ml-auto`,children:(0,q.jsxs)(B,{size:`sm`,onClick:d,className:`gap-1`,children:[(0,q.jsx)(a,{className:`w-3.5 h-3.5`}),`Spawn`]})})]}),b.length===0?(0,q.jsx)(`div`,{className:`text-center py-16 text-muted-foreground text-sm`,children:`No agents match the current filters.`}):(0,q.jsx)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 xl:grid-cols-4 gap-3`,children:b.map(e=>(0,q.jsx)(Ze,{agent:e,parentAgent:e.spawnedBy?f[e.spawnedBy]??null:null,childAgents:_e(y.get(e.id)??[])},e.id))})]})}export{Qe as AgentsView};
2
- //# sourceMappingURL=agents-DZBM5dp_.js.map