agent-relay-server 0.104.5 → 0.105.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/docs/openapi.json +141 -1
  2. package/package.json +3 -2
  3. package/public/assets/MessageBubble-CHor4Sxp.js +4 -0
  4. package/public/assets/{MessageBubble-BpiTbbnp.js.map → MessageBubble-CHor4Sxp.js.map} +1 -1
  5. package/public/assets/{PlanGraphPanel-k8Aa98g5.js → PlanGraphPanel-jHfkQBX6.js} +2 -2
  6. package/public/assets/{PlanGraphPanel-k8Aa98g5.js.map → PlanGraphPanel-jHfkQBX6.js.map} +1 -1
  7. package/public/assets/{activity-CxKi5Erb.js → activity-DDXS6LsX.js} +2 -2
  8. package/public/assets/{activity-CxKi5Erb.js.map → activity-DDXS6LsX.js.map} +1 -1
  9. package/public/assets/{agent-profiles-DMZXdN6K.js → agent-profiles-Cn8lCTkg.js} +2 -2
  10. package/public/assets/{agent-profiles-DMZXdN6K.js.map → agent-profiles-Cn8lCTkg.js.map} +1 -1
  11. package/public/assets/agents-DBTdcFFz.js +2 -0
  12. package/public/assets/{agents-BrvpH3gn.js.map → agents-DBTdcFFz.js.map} +1 -1
  13. package/public/assets/{analytics-1fvh-9ok.js → analytics-VximqXQ9.js} +3 -3
  14. package/public/assets/{analytics-1fvh-9ok.js.map → analytics-VximqXQ9.js.map} +1 -1
  15. package/public/assets/{automation-BCgX5WOH.js → automation-L9wq4y5F.js} +2 -2
  16. package/public/assets/{automation-BCgX5WOH.js.map → automation-L9wq4y5F.js.map} +1 -1
  17. package/public/assets/{badge-BLar6FjP.js → badge-D8fABzMs.js} +2 -2
  18. package/public/assets/{badge-BLar6FjP.js.map → badge-D8fABzMs.js.map} +1 -1
  19. package/public/assets/{branch-state-badge-DYA7bU0i.js → branch-state-badge-CcLZ_u86.js} +2 -2
  20. package/public/assets/{branch-state-badge-DYA7bU0i.js.map → branch-state-badge-CcLZ_u86.js.map} +1 -1
  21. package/public/assets/{button-BrIB69qd.js → button-KASZcscA.js} +2 -2
  22. package/public/assets/{button-BrIB69qd.js.map → button-KASZcscA.js.map} +1 -1
  23. package/public/assets/card-Cds0MWME.js +2 -0
  24. package/public/assets/{card-lhnFnBoz.js.map → card-Cds0MWME.js.map} +1 -1
  25. package/public/assets/{channels-CK80oJYG.js → channels-CcSnLzCG.js} +2 -2
  26. package/public/assets/{channels-CK80oJYG.js.map → channels-CcSnLzCG.js.map} +1 -1
  27. package/public/assets/{chat-D_2PEz06.js → chat-BzMj_PO6.js} +2 -2
  28. package/public/assets/{chat-D_2PEz06.js.map → chat-BzMj_PO6.js.map} +1 -1
  29. package/public/assets/{connectors-ChGyht5m.js → connectors-DbPOlQhL.js} +2 -2
  30. package/public/assets/{connectors-ChGyht5m.js.map → connectors-DbPOlQhL.js.map} +1 -1
  31. package/public/assets/copy-button-d9DFNX9v.js +2 -0
  32. package/public/assets/{copy-button-Cd-LbSbg.js.map → copy-button-d9DFNX9v.js.map} +1 -1
  33. package/public/assets/{display-D1xB8NJZ.js → display-BWi8DQCp.js} +2 -2
  34. package/public/assets/display-BWi8DQCp.js.map +1 -0
  35. package/public/assets/{dist-BnbGIUmi.js → dist-BbUJ1Vht.js} +2 -2
  36. package/public/assets/{dist-BnbGIUmi.js.map → dist-BbUJ1Vht.js.map} +1 -1
  37. package/public/assets/{dist-Bp10H3oR.js → dist-BlZvUZZB.js} +2 -2
  38. package/public/assets/{dist-Bp10H3oR.js.map → dist-BlZvUZZB.js.map} +1 -1
  39. package/public/assets/{dist-DDUGmmoi.js → dist-BwwlmyBq.js} +2 -2
  40. package/public/assets/{dist-DDUGmmoi.js.map → dist-BwwlmyBq.js.map} +1 -1
  41. package/public/assets/dist-CBVZk9U8.js +2 -0
  42. package/public/assets/{dist-BEzpMqLy.js.map → dist-CBVZk9U8.js.map} +1 -1
  43. package/public/assets/{dist-B5VvlkhI.js → dist-CgqfdHSt.js} +2 -2
  44. package/public/assets/{dist-B5VvlkhI.js.map → dist-CgqfdHSt.js.map} +1 -1
  45. package/public/assets/dist-DC-TqTz2.js +2 -0
  46. package/public/assets/{dist-30weaXto.js.map → dist-DC-TqTz2.js.map} +1 -1
  47. package/public/assets/{dist-DZ97OosY.js → dist-DOAjFOS4.js} +2 -2
  48. package/public/assets/{dist-DZ97OosY.js.map → dist-DOAjFOS4.js.map} +1 -1
  49. package/public/assets/{dist-BjOBkHHY.js → dist-DTXKbk2K.js} +2 -2
  50. package/public/assets/{dist-BjOBkHHY.js.map → dist-DTXKbk2K.js.map} +1 -1
  51. package/public/assets/dist-DreO5AcZ.js +2 -0
  52. package/public/assets/{dist-Cgy0FmP-.js.map → dist-DreO5AcZ.js.map} +1 -1
  53. package/public/assets/{dist-CQF3Jiqg.js → dist-DybScJmm.js} +2 -2
  54. package/public/assets/{dist-CQF3Jiqg.js.map → dist-DybScJmm.js.map} +1 -1
  55. package/public/assets/{dist-DAl28ejX.js → dist-UhEAFdvZ.js} +2 -2
  56. package/public/assets/{dist-DAl28ejX.js.map → dist-UhEAFdvZ.js.map} +1 -1
  57. package/public/assets/{es2015-B8Z9p8oQ.js → es2015-DUjFyjDp.js} +2 -2
  58. package/public/assets/{es2015-B8Z9p8oQ.js.map → es2015-DUjFyjDp.js.map} +1 -1
  59. package/public/assets/{formatted-body-impl-BJ4WCF5J.js → formatted-body-impl-CFWHLkCY.js} +2 -2
  60. package/public/assets/{formatted-body-impl-BJ4WCF5J.js.map → formatted-body-impl-CFWHLkCY.js.map} +1 -1
  61. package/public/assets/index-BjjzI2LT.css +2 -0
  62. package/public/assets/{index-CN7QZlMb.js → index-aCfZQ7LY.js} +13 -13
  63. package/public/assets/index-aCfZQ7LY.js.map +1 -0
  64. package/public/assets/{input-B_fUHtLD.js → input-CtHfLn1i.js} +2 -2
  65. package/public/assets/{input-B_fUHtLD.js.map → input-CtHfLn1i.js.map} +1 -1
  66. package/public/assets/{insights-BCZRV0hX.js → insights-BuPFE0tf.js} +2 -2
  67. package/public/assets/{insights-BCZRV0hX.js.map → insights-BuPFE0tf.js.map} +1 -1
  68. package/public/assets/{integrations-C7UGs00U.js → integrations-hkSW8CzM.js} +2 -2
  69. package/public/assets/{integrations-C7UGs00U.js.map → integrations-hkSW8CzM.js.map} +1 -1
  70. package/public/assets/{lib-ng6WZYjE.js → lib-l-JkMVR9.js} +2 -2
  71. package/public/assets/{lib-ng6WZYjE.js.map → lib-l-JkMVR9.js.map} +1 -1
  72. package/public/assets/{lucide-react-BYZuAhQs.js → lucide-react-C4eXYCwx.js} +2 -2
  73. package/public/assets/{lucide-react-BYZuAhQs.js.map → lucide-react-C4eXYCwx.js.map} +1 -1
  74. package/public/assets/{maintenance-ChYno3Fm.js → maintenance-wYwJ7w6h.js} +2 -2
  75. package/public/assets/{maintenance-ChYno3Fm.js.map → maintenance-wYwJ7w6h.js.map} +1 -1
  76. package/public/assets/{managed-agents-DjxZQNIR.js → managed-agents-CKaYD93I.js} +4 -4
  77. package/public/assets/{managed-agents-DjxZQNIR.js.map → managed-agents-CKaYD93I.js.map} +1 -1
  78. package/public/assets/{markdown-preview-impl-DFa5HF1H.js → markdown-preview-impl-bf4eDQUM.js} +2 -2
  79. package/public/assets/{markdown-preview-impl-DFa5HF1H.js.map → markdown-preview-impl-bf4eDQUM.js.map} +1 -1
  80. package/public/assets/memory-DIneEza9.js +2 -0
  81. package/public/assets/{memory-CTw6kadT.js.map → memory-DIneEza9.js.map} +1 -1
  82. package/public/assets/{messages-Cjr816D_.js → messages-DP9Vv_wh.js} +2 -2
  83. package/public/assets/{messages-Cjr816D_.js.map → messages-DP9Vv_wh.js.map} +1 -1
  84. package/public/assets/{orchestrators-CdmFKA7K.js → orchestrators-CAnKjxdO.js} +2 -2
  85. package/public/assets/{orchestrators-CdmFKA7K.js.map → orchestrators-CAnKjxdO.js.map} +1 -1
  86. package/public/assets/{overview-DBOnjfpP.js → overview-B98U3C-y.js} +2 -2
  87. package/public/assets/{overview-DBOnjfpP.js.map → overview-B98U3C-y.js.map} +1 -1
  88. package/public/assets/{pairs-BkcdKdF7.js → pairs-DVeeuxhY.js} +2 -2
  89. package/public/assets/{pairs-BkcdKdF7.js.map → pairs-DVeeuxhY.js.map} +1 -1
  90. package/public/assets/{projects-ClKbDQB1.js → projects-vt63bwHN.js} +2 -2
  91. package/public/assets/{projects-ClKbDQB1.js.map → projects-vt63bwHN.js.map} +1 -1
  92. package/public/assets/prompt-settings-Df-0ZMJ5.js +2 -0
  93. package/public/assets/prompt-settings-Df-0ZMJ5.js.map +1 -0
  94. package/public/assets/{react-dom-Dbhs84ug.js → react-dom-BMF4hNzG.js} +2 -2
  95. package/public/assets/{react-dom-Dbhs84ug.js.map → react-dom-BMF4hNzG.js.map} +1 -1
  96. package/public/assets/{registry-Bsf3RtOO.js → registry-DlLZyW7_.js} +2 -2
  97. package/public/assets/{registry-Bsf3RtOO.js.map → registry-DlLZyW7_.js.map} +1 -1
  98. package/public/assets/{security-Iyu5bhJw.js → security-Bo4Ty3lz.js} +2 -2
  99. package/public/assets/{security-Iyu5bhJw.js.map → security-Bo4Ty3lz.js.map} +1 -1
  100. package/public/assets/{select-Bi6tNJDx.js → select-BguZ80M8.js} +2 -2
  101. package/public/assets/{select-Bi6tNJDx.js.map → select-BguZ80M8.js.map} +1 -1
  102. package/public/assets/settings-CpX9Xw2j.js +6 -0
  103. package/public/assets/{settings-CbHp2F9r.js.map → settings-CpX9Xw2j.js.map} +1 -1
  104. package/public/assets/{store-zeyDiSKE.js → store-DUfrGvOE.js} +3 -3
  105. package/public/assets/{store-zeyDiSKE.js.map → store-DUfrGvOE.js.map} +1 -1
  106. package/public/assets/{tasks-CPlf-5Tr.js → tasks-Cg1HXY9l.js} +2 -2
  107. package/public/assets/{tasks-CPlf-5Tr.js.map → tasks-Cg1HXY9l.js.map} +1 -1
  108. package/public/assets/{teams-D2uUNhlY.js → teams-BFcYunxB.js} +2 -2
  109. package/public/assets/{teams-D2uUNhlY.js.map → teams-BFcYunxB.js.map} +1 -1
  110. package/public/assets/{terminal-viewer-impl-uRzbrlXy.js → terminal-viewer-impl-CF2EBa2K.js} +3 -3
  111. package/public/assets/{terminal-viewer-impl-uRzbrlXy.js.map → terminal-viewer-impl-CF2EBa2K.js.map} +1 -1
  112. package/public/assets/types-DorDDvEb.js.map +1 -1
  113. package/public/assets/{use-keyboard-viewport-D8_NYDkh.js → use-keyboard-viewport-RYMALvu1.js} +2 -2
  114. package/public/assets/{use-keyboard-viewport-D8_NYDkh.js.map → use-keyboard-viewport-RYMALvu1.js.map} +1 -1
  115. package/public/assets/user-avatar-D1ffSClz.js +2 -0
  116. package/public/assets/{user-avatar-GFWMuAGK.js.map → user-avatar-D1ffSClz.js.map} +1 -1
  117. package/public/assets/{work-queue-B30SNmuq.js → work-queue-DV36cxjp.js} +2 -2
  118. package/public/assets/{work-queue-B30SNmuq.js.map → work-queue-DV36cxjp.js.map} +1 -1
  119. package/public/assets/workspaces-CIsQqQby.js +3 -0
  120. package/public/assets/workspaces-CIsQqQby.js.map +1 -0
  121. package/public/index.html +22 -22
  122. package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
  123. package/runner/plugins/claude/monitors/relay-monitor.provisioned.mjs +114 -23
  124. package/runner/plugins/claude/monitors/relay-monitor.ts +2 -2
  125. package/runner/src/adapter.ts +4 -1
  126. package/src/agent-lifecycle-events.ts +21 -5
  127. package/src/automations/reconcile.ts +4 -1
  128. package/src/branch-landed.ts +22 -4
  129. package/src/config-store.ts +17 -21
  130. package/src/context-advisory.ts +10 -3
  131. package/src/db/index.ts +1 -0
  132. package/src/db/projects.ts +29 -0
  133. package/src/db/prompt-templates-schema.ts +20 -0
  134. package/src/db/prompt-templates.ts +86 -0
  135. package/src/db/schema.ts +5 -4
  136. package/src/db/tasks.ts +2 -1
  137. package/src/db/workspaces.ts +41 -1
  138. package/src/index.ts +3 -0
  139. package/src/project-instructions.ts +7 -14
  140. package/src/prompt-resolver.ts +530 -0
  141. package/src/routes/index.ts +5 -0
  142. package/src/routes/prompt-templates.ts +60 -0
  143. package/src/routes/workspaces.ts +4 -3
  144. package/src/routing-policy-push.ts +4 -1
  145. package/src/security.ts +3 -0
  146. package/src/self-resume.ts +8 -15
  147. package/src/services/prompt-templates.ts +19 -0
  148. package/src/services/register-agent.ts +2 -0
  149. package/src/services/spawn-issue-activity.ts +107 -0
  150. package/src/spawn-targets.ts +3 -11
  151. package/src/steward.ts +5 -23
  152. package/src/workspace-auto-merge.ts +19 -2
  153. package/src/workspace-phase.ts +15 -28
  154. package/public/assets/MessageBubble-BpiTbbnp.js +0 -4
  155. package/public/assets/agents-BrvpH3gn.js +0 -2
  156. package/public/assets/card-lhnFnBoz.js +0 -2
  157. package/public/assets/copy-button-Cd-LbSbg.js +0 -2
  158. package/public/assets/display-D1xB8NJZ.js.map +0 -1
  159. package/public/assets/dist-30weaXto.js +0 -2
  160. package/public/assets/dist-BEzpMqLy.js +0 -2
  161. package/public/assets/dist-Cgy0FmP-.js +0 -2
  162. package/public/assets/index-BMO_Sblt.css +0 -2
  163. package/public/assets/index-CN7QZlMb.js.map +0 -1
  164. package/public/assets/memory-CTw6kadT.js +0 -2
  165. package/public/assets/settings-CbHp2F9r.js +0 -6
  166. package/public/assets/user-avatar-GFWMuAGK.js +0 -2
  167. package/public/assets/workspaces-CSpmgbPT.js +0 -3
  168. package/public/assets/workspaces-CSpmgbPT.js.map +0 -1
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{$t as t,B as n,G as r,I as ee,O as te,Qn as i,dr as a,h as ne,jn as o,k as s}from"./lucide-react-BYZuAhQs.js";import{f as c,t as l}from"./store-zeyDiSKE.js";import{K as u,d as re,h as d}from"./display-D1xB8NJZ.js";import{t as f}from"./badge-BLar6FjP.js";import{t as p}from"./button-BrIB69qd.js";import{t as m}from"./input-B_fUHtLD.js";import{R as ie,r as ae,u as oe}from"./index-CN7QZlMb.js";import{a as h,o as g,r as _,t as v}from"./card-lhnFnBoz.js";var y=e(a(),1),b=i(),x=[`organization`,`role`,`project`,`task`,`interaction`,`agent`],se=[`private`,`project`,`org`,`public`],ce=[`public`,`normal`,`sensitive`,`secret`],le=[`reported`,`inferred`,`verified`];function S(){return{type:`project`,scope:`default`,title:``,content:``,tags:``,visibility:`project`,sensitivity:`normal`,confidence:`reported`,relevanceScore:`0.7`}}function C(e){return{type:e.type,scope:e.scope,title:e.title,content:e.content,tags:e.tags.join(`, `),visibility:e.visibility,sensitivity:e.sensitivity,confidence:e.confidence,relevanceScore:String(e.relevanceScore)}}function w(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function ue(e){let t={limit:100};e.type&&(t.type=e.type),e.scope.trim()&&(t.scope=e.scope.trim()),e.visibility&&(t.visibility=e.visibility);let n=w(e.tags);if(n.length&&(t.tags=n),e.minRelevance.trim()){let n=Number(e.minRelevance);Number.isFinite(n)&&(t.minRelevance=Math.max(0,Math.min(1,n)))}return t}function T(e){return e===`secret`?`bg-red-500/10 text-red-400 border-red-500/30`:e===`sensitive`?`bg-yellow-500/10 text-yellow-400 border-yellow-500/30`:e===`public`?`bg-blue-500/10 text-blue-400 border-blue-500/30`:`bg-zinc-500/10 text-zinc-400 border-zinc-500/30`}function E(e){return e>=.8?`text-emerald-400`:e>=.5?`text-yellow-400`:`text-zinc-400`}function de(e){return e?Object.entries(e).map(([e,t])=>`${e}=${Array.isArray(t)?t.join(` `):String(t)}`).join(` `):`default`}function fe(e){return e.filter(e=>![`system`,`user`,`channel`].includes(e.kind||``))}function D(){let e=c(),i=l(e=>e.agents),a=l(e=>e.memories),D=l(e=>e.memoryTotal),k=l(e=>e.memoryStats),A=l(e=>e.memoryBrokerInfo),j=l(e=>e.memoryFilters),M=l(e=>e.selectedMemoryId),me=l(e=>e.memoryLoading),N=l(e=>e.set),he=l(e=>e.fetchMemories),ge=l(e=>e.refreshMemory),P=l(e=>e.saveMemory),F=l(e=>e.deleteMemory),I=l(e=>e.injectMemory),L=a.find(e=>e.id===M),[R,z]=(0,y.useState)(`create`),[B,V]=(0,y.useState)(S),[H,U]=(0,y.useState)(``),[W,_e]=(0,y.useState)(`manual`),[G,ve]=(0,y.useState)(`1600`),[K,q]=(0,y.useState)(`8`),[J,ye]=(0,y.useState)(``),Y=(0,y.useMemo)(()=>fe(i),[i]);(0,y.useEffect)(()=>{!H&&Y[0]&&U(Y[0].id)},[Y,H]),(0,y.useEffect)(()=>{L&&R===`edit`&&V(C(L))},[L?.id,R]);let X=(0,y.useMemo)(()=>{let e=j.search.trim().toLowerCase();return e?a.filter(t=>[t.id,t.type,t.scope,t.title,t.content,...t.tags].some(t=>String(t).toLowerCase().includes(e))):a},[a,j.search]);function Z(e){N({memoryFilters:{...j,...e}})}async function be(){let e=Number(B.relevanceScore),t={title:B.title.trim(),content:B.content.trim(),tags:w(B.tags),visibility:B.visibility,sensitivity:B.sensitivity,confidence:B.confidence,relevanceScore:Number.isFinite(e)?Math.max(0,Math.min(1,e)):.7};if(R===`edit`&&L){await P(t,L.id);return}await P({...t,type:B.type,scope:B.scope.trim()}),z(`create`),V(S())}async function Q(e){if(!H)return;let t=await I({agentId:H,memoryIds:e,query:e?.length?void 0:ue(j),reason:W.trim()||`manual`,budget:{maxTokens:Math.max(200,Number(G)||1600),maxMemories:Math.max(1,Number(K)||8),priorityCutoff:3}});t?.command?.id&&ye(t.command.id)}function xe(){z(`create`),V(S())}function Se(){L&&(z(`edit`),V(C(L)))}let Ce=B.title.trim()&&B.content.trim()&&(R===`edit`||B.scope.trim()),$=de(A?.config);return(0,b.jsxs)(`div`,{className:`space-y-4`,children:[(0,b.jsxs)(`div`,{className:`flex items-center justify-between gap-3 flex-wrap`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsx)(o,{className:`w-5 h-5 text-muted-foreground`}),(0,b.jsx)(`h2`,{className:`text-lg font-semibold`,children:`Memory`}),(0,b.jsx)(f,{variant:`secondary`,children:k?.total??D}),A&&(0,b.jsx)(f,{className:A.external?`bg-blue-500/15 text-blue-400 border-blue-500/30`:`bg-emerald-500/15 text-emerald-400 border-emerald-500/30`,children:A.type})]}),(0,b.jsxs)(p,{size:`sm`,variant:`outline`,className:`gap-1.5`,onClick:()=>ge(),children:[(0,b.jsx)(ee,{className:`w-3.5 h-3.5 ${me?`animate-spin`:``}`}),`Refresh`]})]}),(0,b.jsxs)(`div`,{className:`grid gap-3 xl:grid-cols-[1.2fr_0.8fr]`,children:[(0,b.jsxs)(v,{children:[(0,b.jsx)(h,{className:`py-3 px-4`,children:(0,b.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,b.jsxs)(g,{className:`text-sm font-medium flex items-center gap-2`,children:[(0,b.jsx)(t,{className:`w-4 h-4 text-muted-foreground`}),`Broker`]}),A?.capabilities&&(0,b.jsx)(`div`,{className:`flex flex-wrap gap-1 justify-end`,children:Object.entries(A.capabilities).filter(([,e])=>!!e).map(([e])=>(0,b.jsx)(f,{variant:`outline`,className:`text-[10px] px-1.5 py-0`,children:e},e))})]})}),(0,b.jsxs)(_,{className:`px-4 pb-4 space-y-3`,children:[(0,b.jsxs)(`div`,{className:`grid grid-cols-2 md:grid-cols-5 gap-2`,children:[(0,b.jsx)(O,{label:`total`,value:k?.total??D}),(0,b.jsx)(O,{label:`project`,value:k?.byType?.project??0}),(0,b.jsx)(O,{label:`task`,value:k?.byType?.task??0}),(0,b.jsx)(O,{label:`agent`,value:k?.byType?.agent??0}),(0,b.jsx)(O,{label:`sensitive`,value:(k?.bySensitivity?.sensitive??0)+(k?.bySensitivity?.secret??0)})]}),(0,b.jsx)(`div`,{className:`font-mono text-xs text-muted-foreground truncate`,title:$,children:$})]})]}),(0,b.jsxs)(v,{children:[(0,b.jsx)(h,{className:`py-3 px-4`,children:(0,b.jsx)(g,{className:`text-sm font-medium`,children:`Inject`})}),(0,b.jsxs)(_,{className:`px-4 pb-4 space-y-2`,children:[(0,b.jsxs)(`div`,{className:`grid grid-cols-1 sm:grid-cols-2 gap-2`,children:[(0,b.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:H,onChange:e=>U(e.target.value),children:[(0,b.jsx)(`option`,{value:``,children:`Agent`}),Y.map(e=>(0,b.jsx)(`option`,{value:e.id,children:re(e)},e.id))]}),(0,b.jsx)(m,{value:W,onChange:e=>_e(e.target.value),placeholder:`reason`}),(0,b.jsx)(m,{value:G,onChange:e=>ve(e.target.value),inputMode:`numeric`,placeholder:`tokens`}),(0,b.jsx)(m,{value:K,onChange:e=>q(e.target.value),inputMode:`numeric`,placeholder:`memories`})]}),(0,b.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,b.jsxs)(p,{size:`sm`,className:`gap-1.5`,disabled:!H||!L,onClick:()=>L&&Q([L.id]),children:[(0,b.jsx)(te,{className:`w-3.5 h-3.5`}),`Selected`]}),(0,b.jsxs)(p,{size:`sm`,variant:`outline`,className:`gap-1.5`,disabled:!H,onClick:()=>Q(),children:[(0,b.jsx)(s,{className:`w-3.5 h-3.5`}),`Filtered`]}),J&&(0,b.jsx)(f,{variant:`outline`,className:`font-mono text-[10px]`,children:J})]})]})]})]}),(0,b.jsxs)(`div`,{className:`grid gap-4 xl:grid-cols-[minmax(0,1fr)_420px]`,children:[(0,b.jsxs)(`div`,{className:`space-y-3`,children:[(0,b.jsx)(v,{children:(0,b.jsx)(_,{className:`p-3`,children:(0,b.jsxs)(`div`,{className:`grid grid-cols-2 lg:grid-cols-6 gap-2`,children:[(0,b.jsx)(m,{className:`lg:col-span-2`,value:j.search,onChange:e=>Z({search:e.target.value}),placeholder:`Search visible memories`}),(0,b.jsxs)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:j.type,onChange:e=>Z({type:e.target.value}),children:[(0,b.jsx)(`option`,{value:``,children:`All types`}),x.map(e=>(0,b.jsx)(`option`,{value:e,children:e},e))]}),(0,b.jsx)(m,{value:j.scope,onChange:e=>Z({scope:e.target.value}),placeholder:`scope`}),(0,b.jsx)(m,{value:j.tags,onChange:e=>Z({tags:e.target.value}),placeholder:`tags`}),(0,b.jsxs)(`div`,{className:`flex gap-2`,children:[(0,b.jsx)(m,{value:j.minRelevance,onChange:e=>Z({minRelevance:e.target.value}),placeholder:`score`}),(0,b.jsx)(p,{size:`sm`,variant:`outline`,className:`h-8 px-2`,onClick:()=>he(),children:(0,b.jsx)(s,{className:`w-4 h-4`})})]})]})})}),(0,b.jsx)(oe,{className:`h-[calc(100dvh-24rem)] min-h-[360px]`,children:(0,b.jsxs)(`div`,{className:`space-y-2 pr-2`,children:[X.length===0&&(0,b.jsx)(`div`,{className:`text-center text-sm text-muted-foreground py-16`,children:`No memories`}),X.map(t=>(0,b.jsx)(pe,{memory:t,selected:t.id===M,now:e,onSelect:()=>N({selectedMemoryId:t.id})},t.id))]})})]}),(0,b.jsxs)(v,{children:[(0,b.jsx)(h,{className:`py-3 px-4`,children:(0,b.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,b.jsx)(g,{className:`text-sm font-medium`,children:R===`edit`?`Edit Memory`:`New Memory`}),(0,b.jsxs)(`div`,{className:`flex gap-1`,children:[(0,b.jsx)(p,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,onClick:xe,title:`New memory`,children:(0,b.jsx)(n,{className:`w-3.5 h-3.5`})}),(0,b.jsx)(p,{size:`sm`,variant:`ghost`,className:`h-7 px-2`,onClick:Se,disabled:!L,title:`Edit selected`,children:(0,b.jsx)(r,{className:`w-3.5 h-3.5`})}),(0,b.jsx)(p,{size:`sm`,variant:`ghost`,className:`h-7 px-2 text-red-400 hover:text-red-300`,disabled:!L,onClick:()=>L&&F(L.id),title:`Delete selected`,children:(0,b.jsx)(ne,{className:`w-3.5 h-3.5`})})]})]})}),(0,b.jsxs)(_,{className:`px-4 pb-4 space-y-3`,children:[L&&(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)(`div`,{className:`space-y-2`,children:[(0,b.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[(0,b.jsx)(f,{variant:`secondary`,children:L.type}),(0,b.jsx)(f,{variant:`outline`,children:L.scope}),(0,b.jsx)(f,{className:T(L.sensitivity),children:L.sensitivity}),(0,b.jsx)(f,{variant:`outline`,className:E(L.relevanceScore),children:L.relevanceScore.toFixed(2)})]}),(0,b.jsxs)(`div`,{className:`text-xs text-muted-foreground`,title:d(L.updatedAt),children:[`updated `,u(e,L.updatedAt)]}),(0,b.jsx)(`p`,{className:`text-sm font-medium`,children:L.title}),(0,b.jsx)(`p`,{className:`text-xs text-muted-foreground whitespace-pre-wrap max-h-24 overflow-auto`,children:L.content})]}),(0,b.jsx)(ie,{})]}),(0,b.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,b.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,disabled:R===`edit`,value:B.type,onChange:e=>V({...B,type:e.target.value}),children:x.map(e=>(0,b.jsx)(`option`,{value:e,children:e},e))}),(0,b.jsx)(m,{disabled:R===`edit`,value:B.scope,onChange:e=>V({...B,scope:e.target.value}),placeholder:`scope`}),(0,b.jsx)(m,{className:`col-span-2`,value:B.title,onChange:e=>V({...B,title:e.target.value}),placeholder:`title`}),(0,b.jsx)(ae,{className:`col-span-2 min-h-32`,value:B.content,onChange:e=>V({...B,content:e.target.value}),placeholder:`content`}),(0,b.jsx)(m,{className:`col-span-2`,value:B.tags,onChange:e=>V({...B,tags:e.target.value}),placeholder:`tags`}),(0,b.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:B.visibility,onChange:e=>V({...B,visibility:e.target.value}),children:se.map(e=>(0,b.jsx)(`option`,{value:e,children:e},e))}),(0,b.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:B.sensitivity,onChange:e=>V({...B,sensitivity:e.target.value}),children:ce.map(e=>(0,b.jsx)(`option`,{value:e,children:e},e))}),(0,b.jsx)(`select`,{className:`rounded-md border border-input bg-background px-2 py-1.5 text-sm`,value:B.confidence,onChange:e=>V({...B,confidence:e.target.value}),children:le.map(e=>(0,b.jsx)(`option`,{value:e,children:e},e))}),(0,b.jsx)(m,{value:B.relevanceScore,onChange:e=>V({...B,relevanceScore:e.target.value}),inputMode:`decimal`,placeholder:`score`})]}),(0,b.jsx)(p,{size:`sm`,className:`w-full`,disabled:!Ce,onClick:be,children:R===`edit`?`Save memory`:`Create memory`})]})]})]})]})}function O({label:e,value:t}){return(0,b.jsxs)(`div`,{className:`rounded-md border border-border bg-muted/20 px-3 py-2`,children:[(0,b.jsx)(`div`,{className:`text-lg font-semibold tabular-nums`,children:t}),(0,b.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:e})]})}function pe({memory:e,selected:t,now:n,onSelect:r}){return(0,b.jsx)(`button`,{onClick:r,className:`w-full text-left rounded-md border p-3 transition-colors ${t?`border-primary bg-primary/5`:`border-border bg-card hover:border-zinc-600`}`,children:(0,b.jsxs)(`div`,{className:`flex items-start justify-between gap-3`,children:[(0,b.jsxs)(`div`,{className:`min-w-0`,children:[(0,b.jsxs)(`div`,{className:`flex items-center gap-1.5 flex-wrap`,children:[(0,b.jsx)(f,{variant:`secondary`,className:`text-[10px]`,children:e.type}),(0,b.jsx)(f,{variant:`outline`,className:`text-[10px] font-mono`,children:e.scope}),(0,b.jsx)(f,{className:`text-[10px] ${T(e.sensitivity)}`,children:e.sensitivity})]}),(0,b.jsx)(`div`,{className:`font-medium text-sm mt-2 truncate`,children:e.title}),(0,b.jsx)(`div`,{className:`text-xs text-muted-foreground line-clamp-2 mt-1`,children:e.content}),e.tags.length>0&&(0,b.jsx)(`div`,{className:`flex gap-1 flex-wrap mt-2`,children:e.tags.slice(0,8).map(e=>(0,b.jsxs)(f,{variant:`outline`,className:`text-[10px] text-zinc-400`,children:[`#`,e]},e))})]}),(0,b.jsxs)(`div`,{className:`text-right shrink-0 space-y-1`,children:[(0,b.jsx)(`div`,{className:`text-sm font-semibold tabular-nums ${E(e.relevanceScore)}`,children:e.relevanceScore.toFixed(2)}),(0,b.jsx)(`div`,{className:`text-[10px] text-muted-foreground`,title:d(e.updatedAt),children:u(n,e.updatedAt)}),e.accessCount>0&&(0,b.jsxs)(`div`,{className:`text-[10px] text-muted-foreground`,children:[e.accessCount,` hits`]})]})]})})}export{D as MemoryView};
2
- //# sourceMappingURL=memory-CTw6kadT.js.map
@@ -1,6 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{$n as t,A as n,An as r,B as i,Bn as a,D as o,En as s,Gn as c,I as l,Kt as u,Qn as d,S as f,W as p,Xn as m,Z as h,Zt as g,_n as _,c as v,dr as y,ft as b,h as x,hn as S,j as C,jt as w,p as T,qt as E,rr as D,xn as ee,yn as te}from"./lucide-react-BYZuAhQs.js";import{g as O,m as k,t as A,u as ne}from"./store-zeyDiSKE.js";import{c as re,o as ie,r as ae,u as j}from"./types-DorDDvEb.js";import{t as oe}from"./themes-DjSwmAZN.js";import{a as M,i as N,n as P,r as F,t as I}from"./select-Bi6tNJDx.js";import{t as L}from"./badge-BLar6FjP.js";import{t as R}from"./button-BrIB69qd.js";import{t as z}from"./input-B_fUHtLD.js";import{r as se,z as B}from"./index-CN7QZlMb.js";import{a as V,i as H,n as ce,o as U,r as W,t as G}from"./card-lhnFnBoz.js";import{t as le}from"./user-avatar-GFWMuAGK.js";var K=e(y(),1);function q(e){return`${e.namespace}/${e.key}`}function ue(e){return`/settings/${encodeURIComponent(e.namespace)}/${encodeURIComponent(e.key)}`}function de(e){return e.trim().toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``)||`settings`}function fe(e){let t=new Map;for(let n of e.filter(e=>e.readable)){let e=n.display?.group?.trim()||n.namespace;t.set(e,[...t.get(e)??[],n])}return[...t.entries()].map(([e,t])=>({group:e,slug:de(e),settings:t.sort(pe)})).sort((e,t)=>me(e.settings)-me(t.settings)||e.group.localeCompare(t.group))}function pe(e,t){return(e.display?.order??2**53-1)-(t.display?.order??2**53-1)||e.display?.label?.localeCompare(t.display?.label??``)||q(e).localeCompare(q(t))}function me(e){return Math.min(...e.map(e=>e.display?.order??2**53-1))}function he(e){return Array.isArray(e.type)?e.type.find(e=>e!==`null`):e.type}function ge(e,t,n){if(!t.length)return n;let[r,...i]=t;if(r===void 0)return n;if(typeof r==`number`){let t=Array.isArray(e)?[...e]:[];return t[r]=ge(t[r],i,n),t}let a=ie(e)?{...e}:{},o=ge(a[r],i,n);return o===void 0?delete a[r]:a[r]=o,a}function _e(e){if(e.default!==void 0)return e.default;if(e.const!==void 0)return e.const;if(e.enum?.length)return e.enum[0];switch(he(e)){case`boolean`:return!1;case`integer`:case`number`:return 0;case`array`:return[];case`object`:return{};case`string`:return``;default:return}}function ve(e){return e.split(/\r?\n|,/).map(e=>e.trim()).filter(Boolean)}function ye(e){return Array.isArray(e)?e.map(e=>String(e)).join(`
2
- `):``}function be(e){return ie(e)?Object.entries(e).map(([e,t])=>`${e}=${String(t??``)}`).join(`
3
- `):``}function xe(e){return Object.fromEntries(e.split(/\r?\n/).map(e=>e.trim()).filter(Boolean).map(e=>{let t=e.indexOf(`=`);return t>=0?[e.slice(0,t).trim(),e.slice(t+1)]:[e,``]}))}var J=d(),Se=`__unset__`;function Ce(e){return e===`server-runtime`?`Server runtime`:e===`bootstrap`?`Bootstrap`:`Browser`}function we(e){return e===`server-runtime`?`Stored by Relay and mutable while the server is running.`:e===`bootstrap`?`Read from startup configuration; restart or host config changes are required.`:`Stored only in this browser profile.`}function Te(e){return e===`browser`?(0,J.jsx)(h,{className:`size-3.5`}):(0,J.jsx)(o,{className:`size-3.5`})}function Ee(e){return e.details??[]}function De({group:e,settings:t,onSaved:n}){let r=[...new Set(t.map(e=>e.tier))];return(0,J.jsxs)(`section`,{className:`space-y-3`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,J.jsx)(`h2`,{className:`text-base font-semibold`,children:e}),(0,J.jsx)(`div`,{className:`flex flex-wrap gap-1`,children:r.map(e=>(0,J.jsxs)(L,{variant:`outline`,className:`gap-1`,title:we(e),children:[Te(e),Ce(e)]},e))})]}),t.length===0?(0,J.jsx)(G,{size:`sm`,children:(0,J.jsx)(W,{className:`text-sm text-muted-foreground`,children:`No settings in this group.`})}):(0,J.jsx)(`div`,{className:`space-y-3`,children:t.map(e=>(0,J.jsx)(Oe,{setting:e,onSaved:n},q(e)))})]})}function Oe({setting:e,onSaved:r}){let[i,a]=(0,K.useState)(()=>e.value??e.defaults??_e(e.schema)),[o,s]=(0,K.useState)(!1),[c,l]=(0,K.useState)(``),[u,d]=(0,K.useState)([]),f=e.writable&&e.tier===`server-runtime`;function p(e,t){a(n=>ge(n,e,t)),d([]),l(``)}async function m(){if(f){s(!0),d([]),l(``);try{let n=await t(`PUT`,ue(e),{value:i,updatedBy:`dashboard`});a(n.value),r(n),l(`Saved`)}catch(e){let t=Ee(e);d(t.length?t:[e.message])}finally{s(!1)}}}return(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsxs)(U,{className:`flex flex-wrap items-center gap-2 text-sm`,children:[e.display.label,(0,J.jsxs)(L,{variant:`outline`,className:`gap-1`,title:we(e.tier),children:[Te(e.tier),Ce(e.tier)]}),!e.writable&&(0,J.jsx)(L,{variant:`secondary`,children:`Read only`})]}),e.display.description&&(0,J.jsx)(H,{children:e.display.description}),(0,J.jsx)(ce,{children:(0,J.jsxs)(R,{size:`sm`,onClick:m,disabled:!f||o,children:[(0,J.jsx)(n,{className:`size-4`}),o?`Saving`:`Save`]})})]}),(0,J.jsxs)(W,{className:`space-y-3`,children:[(0,J.jsx)(ke,{schema:e.schema,value:i,path:[],label:e.display.label,required:!0,disabled:!f||o,onChange:p}),(0,J.jsxs)(`p`,{className:`flex flex-wrap items-center gap-x-2 text-[11px] text-muted-foreground`,children:[(0,J.jsxs)(`code`,{className:`rounded bg-muted px-1.5 py-0.5 font-mono`,children:[e.namespace,`/`,e.key]}),(0,J.jsxs)(`span`,{children:[`read `,(0,J.jsx)(`span`,{className:`text-foreground/70`,children:e.scope.read})]}),(0,J.jsx)(`span`,{"aria-hidden":!0,children:`·`}),(0,J.jsxs)(`span`,{children:[`write `,(0,J.jsx)(`span`,{className:`text-foreground/70`,children:e.scope.write})]})]}),u.length>0&&(0,J.jsxs)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsxs)(`div`,{className:`mb-1 flex items-center gap-2 font-medium`,children:[(0,J.jsx)(_,{className:`size-4`}),`Save failed`]}),(0,J.jsx)(`ul`,{className:`list-disc space-y-1 pl-5`,children:u.map(e=>(0,J.jsx)(`li`,{children:e},e))})]}),c&&(0,J.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-emerald-500`,children:[(0,J.jsx)(S,{className:`size-4`}),c]})]})]})}function ke(e){let{schema:t,value:n,path:r,label:i,required:a,disabled:o,onChange:s}=e,c=he(t);if(t.enum?.length){let e=n==null||n===``?Se:String(n);return(0,J.jsx)(Y,{label:i,description:t.description,children:(0,J.jsxs)(I,{value:e,onValueChange:e=>s(r,e===`__unset__`?void 0:e),disabled:o,children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsxs)(P,{children:[!a&&(0,J.jsx)(F,{value:`__unset__`,children:`Not set`}),t.enum.map(e=>(0,J.jsx)(F,{value:String(e),children:String(e)},String(e)))]})]})})}if(c===`boolean`)return(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:i}),t.description&&(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:t.description})]}),(0,J.jsx)(B,{checked:!!n,onCheckedChange:e=>s(r,e),disabled:o})]});if(c===`integer`||c===`number`)return(0,J.jsx)(Y,{label:i,description:t.description,children:(0,J.jsx)(z,{type:`number`,min:typeof t.minimum==`number`?t.minimum:void 0,max:typeof t.maximum==`number`?t.maximum:void 0,step:c===`integer`?1:`any`,value:typeof n==`number`?n:``,disabled:o,onChange:e=>s(r,e.target.value===``&&!a?void 0:Number(e.target.value))})});if(c===`array`)return(0,J.jsx)(Y,{label:i,description:t.description??`One item per line.`,children:(0,J.jsx)(se,{rows:Math.min(8,Math.max(3,Array.isArray(n)?n.length+1:3)),value:ye(n),disabled:o,onChange:e=>s(r,ve(e.target.value))})});if(c===`object`){let e=t.properties??{},a=new Set(t.required??[]);return Object.keys(e).length===0&&t.additionalProperties?(0,J.jsx)(Y,{label:i,description:t.description??`KEY=value, one entry per line.`,children:(0,J.jsx)(se,{rows:5,value:be(n),disabled:o,onChange:e=>s(r,xe(e.target.value))})}):(0,J.jsxs)(`div`,{className:`space-y-3`,children:[r.length>0&&(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:i}),t.description&&(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:t.description})]}),(0,J.jsx)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:Object.entries(e).map(([e,t])=>{let i=ie(n)?n[e]:void 0;return(0,J.jsx)(ke,{schema:t,value:i===void 0&&a.has(e)?_e(t):i,path:[...r,e],label:t.title||Ae(e),required:a.has(e),disabled:o,onChange:s},e)})})]})}return(0,J.jsx)(Y,{label:i,description:t.description,children:(0,J.jsx)(z,{value:typeof n==`string`?n:n==null?``:String(n),disabled:o,onChange:e=>s(r,e.target.value===``&&!a?void 0:e.target.value)})})}function Y({label:e,description:t,children:n}){return(0,J.jsxs)(`label`,{className:`block space-y-1.5 text-sm`,children:[(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:e}),n,t&&(0,J.jsx)(`span`,{className:`block text-xs text-muted-foreground`,children:t})]})}function Ae(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1 $2`).replace(/[-_]+/g,` `).replace(/^\w/,e=>e.toUpperCase())}function je(){let e=A(e=>e.theme),t=A(e=>e.showReasoning),n=A(e=>e.set);return(0,J.jsxs)(`section`,{className:`space-y-4`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h2`,{className:`text-base font-semibold`,children:`Browser preferences`}),(0,J.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`These are stored in local dashboard state, not in Relay server config.`})]}),(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsx)(U,{className:`text-sm`,children:`Dashboard display`}),(0,J.jsx)(H,{className:`text-xs`,children:`Browser tier · persisted in this browser profile.`}),(0,J.jsx)(ce,{children:(0,J.jsxs)(L,{variant:`outline`,className:`gap-1`,children:[(0,J.jsx)(h,{className:`size-3.5`}),`Browser`]})})]}),(0,J.jsxs)(W,{className:`grid gap-3 md:grid-cols-2`,children:[(0,J.jsx)(Y,{label:`Theme`,children:(0,J.jsxs)(I,{value:e,onValueChange:e=>n({theme:e}),children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsx)(P,{children:oe.map(e=>(0,J.jsx)(F,{value:e.id,children:e.label},e.id))})]})}),(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,J.jsx)(r,{className:`size-4`}),(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:`Show reasoning details`}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Display captured reasoning/tool steps in chat. Server capture is controlled separately by provider reasoningCapture.`})]})]}),(0,J.jsx)(B,{checked:t,onCheckedChange:e=>n({showReasoning:e})})]})]})]}),(0,J.jsx)(Me,{})]})}function Me(){let e=A(e=>e.voiceTtsEnabled),t=A(e=>e.setVoiceTtsEnabled),n=A(e=>e.voiceTtsMode),r=A(e=>e.setVoiceTtsMode),i=A(e=>e.voiceTtsKokoroVoice),a=A(e=>e.setVoiceTtsKokoroVoice),o=A(e=>e.voiceTtsBrowserVoice),s=A(e=>e.setVoiceTtsBrowserVoice),c=A(e=>e.voiceInputMode),l=A(e=>e.setVoiceInputMode),[u,d]=(0,K.useState)(()=>O());(0,K.useEffect)(()=>{if(typeof window>`u`||!(`speechSynthesis`in window))return;let e=()=>d(O());return e(),window.speechSynthesis.addEventListener?.(`voiceschanged`,e),()=>window.speechSynthesis.removeEventListener?.(`voiceschanged`,e)},[]);let f=k.some(e=>e.id===i)?k:[...k,{id:i,label:i}];return(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsxs)(U,{className:`flex items-center gap-2 text-sm`,children:[(0,J.jsx)(v,{className:`size-4`}),`Voice`]}),(0,J.jsx)(H,{className:`text-xs`,children:`Browser tier TTS and push-to-talk behavior.`}),(0,J.jsx)(ce,{children:(0,J.jsx)(B,{checked:e,onCheckedChange:t})})]}),(0,J.jsxs)(W,{className:`grid gap-3 md:grid-cols-2`,children:[(0,J.jsx)(Y,{label:`Speech engine`,children:(0,J.jsxs)(I,{value:n,onValueChange:e=>r(e),children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsxs)(P,{children:[(0,J.jsx)(F,{value:`kokoro`,children:`Kokoro (server, fallback to browser)`}),(0,J.jsx)(F,{value:`browser`,children:`Browser Web Speech API`})]})]})}),(0,J.jsx)(Y,{label:`Kokoro voice`,children:(0,J.jsxs)(I,{value:i,onValueChange:a,children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsx)(P,{children:f.map(e=>(0,J.jsx)(F,{value:e.id,children:e.label},e.id))})]})}),(0,J.jsx)(Y,{label:`Browser voice`,children:(0,J.jsxs)(I,{value:o||`__unset__`,onValueChange:e=>s(e===`__unset__`?``:e),children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsxs)(P,{children:[(0,J.jsx)(F,{value:Se,children:`System default`}),u.map(e=>(0,J.jsx)(F,{value:e.uri,children:e.label},e.uri))]})]})}),(0,J.jsx)(Y,{label:`Push-to-talk input`,children:(0,J.jsxs)(I,{value:c,onValueChange:e=>l(e),children:[(0,J.jsx)(N,{children:(0,J.jsx)(M,{})}),(0,J.jsxs)(P,{children:[(0,J.jsx)(F,{value:`compose`,children:`Fill message box`}),(0,J.jsx)(F,{value:`autosend`,children:`Send immediately`})]})]})})]})]})}function Ne({catalog:e,error:n,canWrite:r,onCatalog:a}){let s=e[0]?.provider??``,[c,l]=(0,K.useState)(s),[d,m]=(0,K.useState)(()=>Pe(s)),[h,g]=(0,K.useState)(``),[_,v]=(0,K.useState)([]),y=e.some(e=>e.provider===c)?c:s,b=e.find(e=>e.provider===y)??e[0],C=e.map(e=>e.provider);function w(e){m(t=>({...t,...e})),v([]),g(``)}function T(e){l(e),m(Pe(e)),v([]),g(``)}async function D(){a((await t(`GET`,`/providers`)).catalog)}async function ee(){if(r){v([]),g(``);try{await t(`PUT`,`/providers/${encodeURIComponent(d.provider)}/models/${encodeURIComponent(d.alias)}`,{label:d.label,providerModel:d.providerModel,efforts:ve(d.efforts),defaultEffort:d.defaultEffort.trim()||void 0,limits:d.limits,capabilities:d.capabilities,contextThreshold:Fe(d),disabled:d.disabled,updatedBy:`dashboard`}),await D(),g(`${d.alias} saved`),m(Pe(d.provider))}catch(e){let t=Ee(e);v(t.length?t:[e.message])}}}async function te(e,n){if(r){v([]),g(``);try{await t(`PATCH`,`/providers/${encodeURIComponent(y)}/models/${encodeURIComponent(e.alias)}`,{disabled:n,updatedBy:`dashboard`}),await D(),g(`${e.alias} ${n?`disabled`:`enabled`}`)}catch(e){let t=Ee(e);v(t.length?t:[e.message])}}}async function O(e){if(r){v([]),g(``);try{await t(`DELETE`,`/providers/${encodeURIComponent(y)}/models/${encodeURIComponent(e.alias)}`),await D(),g(`${e.alias} removed`)}catch(e){let t=Ee(e);v(t.length?t:[e.message])}}}function k(e){m({provider:y,alias:e.alias,label:e.label,providerModel:e.providerModel,efforts:e.efforts.join(`, `),defaultEffort:e.defaultEffort??``,selfCompactUtilization:e.contextThreshold?.selfCompactUtilization?.toString()??``,warnUtilization:e.contextThreshold?.warnUtilization?.toString()??``,hardBackstopUtilization:e.contextThreshold?.hardBackstopUtilization?.toString()??``,disabled:!!e.disabled,limits:e.limits,capabilities:e.capabilities}),v([]),g(``)}return n?(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`text-sm text-muted-foreground`,children:[(0,J.jsxs)(`div`,{className:`mb-1 flex items-center gap-2 font-medium text-foreground`,children:[(0,J.jsx)(f,{className:`size-4`}),`Model catalog`]}),n]})}):(0,J.jsxs)(`section`,{className:`space-y-4`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h2`,{className:`text-base font-semibold`,children:`Model catalog`}),(0,J.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Add override models, disable unavailable models, or remove custom entries from the provider catalog.`})]}),!r&&(0,J.jsx)(L,{variant:`secondary`,children:`Read only: needs settings:write:provider`})]}),(0,J.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:C.map(e=>(0,J.jsx)(R,{variant:e===y?`default`:`outline`,size:`sm`,onClick:()=>T(e),children:e},e))}),(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsx)(U,{className:`text-sm`,children:`Add or edit model`}),(0,J.jsx)(ce,{children:(0,J.jsxs)(L,{variant:`outline`,className:`gap-1`,children:[(0,J.jsx)(o,{className:`size-3.5`}),`Server runtime`]})})]}),(0,J.jsxs)(W,{className:`space-y-3`,children:[(0,J.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-2`,children:[(0,J.jsx)(Y,{label:`Alias`,children:(0,J.jsx)(z,{value:d.alias,disabled:!r,placeholder:`nightly`,onChange:e=>w({alias:e.target.value.trim()})})}),(0,J.jsx)(Y,{label:`Label`,children:(0,J.jsx)(z,{value:d.label,disabled:!r,placeholder:`Nightly Codex`,onChange:e=>w({label:e.target.value})})}),(0,J.jsx)(Y,{label:`Provider model`,children:(0,J.jsx)(z,{value:d.providerModel,disabled:!r,placeholder:`codex-nightly`,onChange:e=>w({providerModel:e.target.value})})}),(0,J.jsx)(Y,{label:`Efforts`,children:(0,J.jsx)(z,{value:d.efforts,disabled:!r,placeholder:`low, medium, high`,onChange:e=>w({efforts:e.target.value})})}),(0,J.jsx)(Y,{label:`Default effort`,children:(0,J.jsx)(z,{value:d.defaultEffort,disabled:!r,placeholder:`medium`,onChange:e=>w({defaultEffort:e.target.value})})}),(0,J.jsx)(Y,{label:`Self compact utilization`,children:(0,J.jsx)(z,{value:d.selfCompactUtilization,disabled:!r,placeholder:`0.80`,inputMode:`decimal`,onChange:e=>w({selfCompactUtilization:e.target.value})})}),(0,J.jsx)(Y,{label:`Warn utilization`,children:(0,J.jsx)(z,{value:d.warnUtilization,disabled:!r,placeholder:`default: self - 0.10`,inputMode:`decimal`,onChange:e=>w({warnUtilization:e.target.value})})}),(0,J.jsx)(Y,{label:`Hard backstop utilization`,children:(0,J.jsx)(z,{value:d.hardBackstopUtilization,disabled:!r,placeholder:`0.90`,inputMode:`decimal`,onChange:e=>w({hardBackstopUtilization:e.target.value})})}),(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:`Disabled`}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Keep visible but unavailable for new launches.`})]}),(0,J.jsx)(B,{checked:d.disabled,disabled:!r,onCheckedChange:e=>w({disabled:e})})]})]}),(0,J.jsxs)(R,{onClick:ee,disabled:!r||!d.alias||!d.label||!d.providerModel,children:[(0,J.jsx)(i,{className:`size-4`}),`Save model`]})]})]}),(0,J.jsxs)(`div`,{className:`space-y-2`,children:[b&&b.models.length===0&&(0,J.jsx)(G,{size:`sm`,children:(0,J.jsx)(W,{className:`text-sm text-muted-foreground`,children:`No models in this provider catalog yet.`})}),b?.models.map(e=>(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,J.jsxs)(`div`,{className:`min-w-0`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,J.jsx)(`span`,{className:`font-medium`,children:e.label}),(0,J.jsx)(`code`,{className:`rounded bg-muted px-1.5 py-0.5 font-mono text-xs`,children:e.alias}),e.disabled&&(0,J.jsx)(L,{variant:`secondary`,children:`Disabled`})]}),(0,J.jsxs)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:[e.providerModel,e.efforts.length>0?` · efforts ${e.efforts.join(`, `)}`:` · no effort levels`,e.defaultEffort?` · default ${e.defaultEffort}`:``,` · context ${Le(e)}`]})]}),(0,J.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,J.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>k(e),children:[(0,J.jsx)(p,{className:`size-4`}),`Edit`]}),(0,J.jsxs)(R,{variant:`outline`,size:`sm`,disabled:!r,onClick:()=>void te(e,!e.disabled),children:[e.disabled?(0,J.jsx)(u,{className:`size-4`}):(0,J.jsx)(E,{className:`size-4`}),e.disabled?`Enable`:`Disable`]}),(0,J.jsxs)(R,{variant:`outline`,size:`sm`,disabled:!r,onClick:()=>void O(e),children:[(0,J.jsx)(x,{className:`size-4`}),`Remove`]})]})]})},e.alias))]}),_.length>0&&(0,J.jsx)(`div`,{className:`rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:(0,J.jsx)(`ul`,{className:`list-disc space-y-1 pl-5`,children:_.map(e=>(0,J.jsx)(`li`,{children:e},e))})}),h&&(0,J.jsxs)(`p`,{className:`flex items-center gap-1 text-sm text-emerald-500`,children:[(0,J.jsx)(S,{className:`size-4`}),h]})]})}function Pe(e){return{provider:e,alias:``,label:``,providerModel:``,efforts:``,defaultEffort:``,selfCompactUtilization:``,warnUtilization:``,hardBackstopUtilization:``,disabled:!1}}function Fe(e){let t=Ie(e.selfCompactUtilization,`Self compact utilization`),n=Ie(e.warnUtilization,`Warn utilization`),r=Ie(e.hardBackstopUtilization,`Hard backstop utilization`);if(!(t===void 0&&n===void 0&&r===void 0)){if(t===void 0)throw Error(`Self compact utilization is required when setting context thresholds`);return{selfCompactUtilization:t,...n===void 0?{}:{warnUtilization:n},...r===void 0?{}:{hardBackstopUtilization:r}}}}function Ie(e,t){let n=e.trim();if(!n)return;let r=Number(n);if(!Number.isFinite(r))throw Error(`${t} must be a number`);return r}function Le(e){if(e.contextThreshold)return`self ${Re(e.contextThreshold.selfCompactUtilization)}, warn ${Re(e.contextThreshold.warnUtilization??Math.max(0,e.contextThreshold.selfCompactUtilization-.1))}`;let t=ne(e.limits?.contextWindowTokens?.value);return`derived self ${Re(t.selfCompactUtilization)}, warn ${Re(t.warnUtilization)}`}function Re(e){return`${Math.round(e*100)}%`}var ze=5,Be=15,Ve={claude:`Claude`,codex:`Codex`};function He(e){return Math.round(e/6e4)}function Ue(e){return`${He(e)} min`}function We({canWrite:e}){let[n,r]=(0,K.useState)(null),[i,a]=(0,K.useState)(``),[o,s]=(0,K.useState)(``),[c,l]=(0,K.useState)(null);(0,K.useEffect)(()=>{let e=!1;return(async()=>{try{let n=await t(`GET`,`/providers/quota-config`);e||r(n)}catch(t){e||a(t.message)}})(),()=>{e=!0}},[]);async function u(e,n){r(t=>({...t??{},[e]:n})),s(``),l(e);try{let i=await t(`PUT`,`/providers/${e}/quota-config`,n);r(t=>({...t??{},[e]:i}))}catch(t){s(`${Ve[e]??e}: ${t.message}`)}finally{l(null)}}let d=n?Object.keys(n).sort():[];return(0,J.jsxs)(`section`,{className:`space-y-4`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h2`,{className:`text-base font-semibold`,children:`Quota`}),(0,J.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Per-provider quota collection and display. `,(0,J.jsx)(`strong`,{children:`Enabled`}),` governs collection (disabled stops polling — no API calls);`,(0,J.jsx)(`strong`,{children:` Show in widget`}),` governs display only.`]})]}),i&&(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4`}),(0,J.jsx)(`span`,{children:i})]}),o&&(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4`}),(0,J.jsx)(`span`,{children:o})]}),!n&&!i&&(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,J.jsx)(b,{className:`size-4 animate-spin`}),`Loading quota config…`]})}),d.map(t=>{let i=n[t],a=!e||c===t;return(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsxs)(U,{className:`flex items-center gap-2 text-sm`,children:[(0,J.jsx)(w,{className:`size-4`}),Ve[t]??t,c===t&&(0,J.jsx)(b,{className:`size-3 animate-spin text-muted-foreground`})]}),(0,J.jsxs)(H,{className:`text-xs`,children:[i.enabled?`Polled every ${Ue(i.pollIntervalMs)}`:`Collection disabled`,i.enabled&&!i.showInWidget?` · hidden from widget`:``]})]}),(0,J.jsxs)(W,{className:`space-y-4`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:`Enabled`}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Collect quota for this provider. Off stops all polling (no API calls, no token spend).`})]}),(0,J.jsx)(B,{checked:i.enabled,disabled:a,onCheckedChange:e=>void u(t,{...i,enabled:e})})]}),(0,J.jsxs)(`div`,{className:`rounded-md border bg-muted/20 p-3 space-y-2`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:`Polling interval`}),(0,J.jsx)(L,{variant:`outline`,className:`tabular-nums`,children:Ue(i.pollIntervalMs)})]}),(0,J.jsx)(`input`,{type:`range`,min:ze,max:Be,step:1,value:He(i.pollIntervalMs),disabled:a||!i.enabled,onChange:e=>{let n=Number(e.target.value)*6e4;r(e=>({...e??{},[t]:{...i,pollIntervalMs:n}}))},onPointerUp:e=>void u(t,{...i,pollIntervalMs:Number(e.target.value)*6e4}),onKeyUp:e=>void u(t,{...i,pollIntervalMs:Number(e.target.value)*6e4}),className:`w-full accent-primary disabled:opacity-50`}),(0,J.jsxs)(`div`,{className:`flex justify-between text-[10px] text-muted-foreground`,children:[(0,J.jsxs)(`span`,{children:[ze,` min`]}),(0,J.jsxs)(`span`,{children:[Be,` min`]})]})]}),(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3 rounded-md border bg-muted/20 p-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`text-sm font-medium`,children:`Show in quota widget`}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Display only. Off hides this provider from the dashboard widget; collection continues if enabled.`})]}),(0,J.jsx)(B,{checked:i.showInWidget,disabled:a,onCheckedChange:e=>void u(t,{...i,showInWidget:e})})]})]})]},t)})]})}function Ge({message:e}){return(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4 shrink-0`}),(0,J.jsx)(`span`,{children:e})]})}var Ke=re(),X={cautionAt:.15,avoidLargeAt:.5,hardAvoidAt:1},qe=.99,Je=.5;function Z(e,t){return((e??t)*100).toFixed(0)}function Q(e){let t=Number(e);return!Number.isFinite(t)||t<0||t>100?null:t/100}function Ye({policy:e,canWrite:r,onPolicy:i}){let a=e.quotaBands,o=e.providerQuota??{},[s,c]=(0,K.useState)(Z(a?.cautionAt,X.cautionAt)),[l,u]=(0,K.useState)(Z(a?.avoidLargeAt,X.avoidLargeAt)),[d,f]=(0,K.useState)(Z(a?.hardAvoidAt,X.hardAvoidAt)),[p,m]=(0,K.useState)(()=>{let e={};for(let t of Ke){let n=o[t]??{};e[t]={backstop:Z(n.hardBackstopUtilization,qe),floor:Z(n.burnPenaltyUtilizationFloor,Je)}}return e}),[h,g]=(0,K.useState)(!1),[_,v]=(0,K.useState)(``),[y,x]=(0,K.useState)(!1),[S,C]=(0,K.useState)(``);async function w(){let n=Q(s),r=Q(l),a=Q(d);if(n===null){C(`Caution threshold must be 0–100%.`);return}if(r===null){C(`Avoid-large threshold must be 0–100%.`);return}if(a===null){C(`Hard-avoid threshold must be 0–100%.`);return}if(n>=r){C(`Caution must be less than avoid-large.`);return}if(r>=a){C(`Avoid-large must be less than hard-avoid.`);return}let o={};for(let e of Ke){let t=p[e],n=Q(t.backstop),r=Q(t.floor);if(n===null){C(`${j(e)}: hard-backstop must be 0–100%.`);return}if(r===null){C(`${j(e)}: burn-penalty floor must be 0–100%.`);return}o[e]={hardBackstopUtilization:n,burnPenaltyUtilizationFloor:r}}C(``),g(!0),v(``),x(!1);try{i(await t(`PUT`,`/routing-policy`,{...e,quotaBands:{cautionAt:n,avoidLargeAt:r,hardAvoidAt:a},providerQuota:o})),x(!0),setTimeout(()=>x(!1),2e3)}catch(e){v(e.message)}finally{g(!1)}}function T(e,t){m(n=>({...n,[e]:{...n[e],...t}})),C(``),x(!1)}function E(){C(``),x(!1)}return(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsx)(U,{className:`text-sm`,children:`Quota thresholds`}),(0,J.jsx)(H,{className:`text-xs`,children:`Band cutoffs govern when the orchestrator starts penalising or blocking high-quota providers. Values are utilization percentages (0–100).`})]}),(0,J.jsxs)(W,{className:`space-y-4`,children:[(_||S)&&(0,J.jsx)(Ge,{message:_||S}),(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:`Band cutoffs`}),(0,J.jsx)(Xe,{caution:Number(s),avoidLarge:Number(l),hardAvoid:Number(d)}),(0,J.jsxs)(`div`,{className:`mt-3 grid gap-3 sm:grid-cols-3`,children:[(0,J.jsx)($,{label:`Caution at`,hint:`Default: ${(X.cautionAt*100).toFixed(0)}%`,value:s,disabled:!r||h,onChange:e=>{c(e),E()}}),(0,J.jsx)($,{label:`Avoid-large at`,hint:`Default: ${(X.avoidLargeAt*100).toFixed(0)}%`,value:l,disabled:!r||h,onChange:e=>{u(e),E()}}),(0,J.jsx)($,{label:`Hard-avoid at`,hint:`Default: ${(X.hardAvoidAt*100).toFixed(0)}%`,value:d,disabled:!r||h,onChange:e=>{f(e),E()}})]})]}),Ke.map(e=>{let t=p[e];return(0,J.jsxs)(`div`,{children:[(0,J.jsxs)(`div`,{className:`mb-2 text-xs font-medium text-muted-foreground uppercase tracking-wide`,children:[j(e),` overrides`]}),(0,J.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,J.jsx)($,{label:`Hard-backstop utilization`,hint:`Provider blocked above this. Default: ${(qe*100).toFixed(0)}%`,value:t.backstop,disabled:!r||h,onChange:t=>T(e,{backstop:t})}),(0,J.jsx)($,{label:`Burn-penalty floor`,hint:`Penalties suppressed below this. Default: ${(Je*100).toFixed(0)}%`,value:t.floor,disabled:!r||h,onChange:t=>T(e,{floor:t})})]})]},e)}),r&&(0,J.jsxs)(R,{size:`sm`,onClick:()=>void w(),disabled:h,children:[h?(0,J.jsx)(b,{className:`size-4 animate-spin`}):(0,J.jsx)(n,{className:`size-4`}),y?`Saved`:`Save thresholds`]})]})]})}function Xe({caution:e,avoidLarge:t,hardAvoid:n}){let r=e=>Math.max(0,Math.min(100,Number.isFinite(e)?e:0)),i=r(e),a=Math.max(i,r(t)),o=Math.max(a,r(n)),s=e=>`${e.toFixed(0)}%`,c=[{key:`normal`,label:`normal`,color:`bg-emerald-500`,from:0,to:i,range:`0–${s(i)}`},{key:`caution`,label:`caution`,color:`bg-amber-500`,from:i,to:a,range:`${s(i)}–${s(a)}`},{key:`avoid-large`,label:`avoid large`,color:`bg-orange-500`,from:a,to:o,range:`${s(a)}–${s(o)}`},{key:`hard-avoid`,label:`hard avoid`,color:`bg-red-500`,from:o,to:100,range:`≥ ${s(o)}`}];return(0,J.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,J.jsx)(`div`,{className:`flex h-2.5 overflow-hidden rounded-full bg-muted`,role:`img`,"aria-label":`Quota penalty bands from 0 to 100 percent`,children:c.map(e=>(0,J.jsx)(`div`,{className:m(e.color,`transition-[width] duration-300`),style:{width:`${e.to-e.from}%`},title:`${e.label} · ${e.range}`},e.key))}),(0,J.jsx)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-1 text-[10px] text-muted-foreground`,children:c.map(e=>(0,J.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,J.jsx)(`span`,{className:m(`size-2 shrink-0 rounded-full`,e.color)}),e.label,` `,(0,J.jsx)(`span`,{className:`tabular-nums text-foreground/70`,children:e.range})]},e.key))})]})}function $({label:e,hint:t,value:n,disabled:r,onChange:i}){return(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:e}),(0,J.jsxs)(`div`,{className:`relative`,children:[(0,J.jsx)(z,{value:n,onChange:e=>i(e.target.value),disabled:r,className:`h-8 pr-6 text-xs tabular-nums`}),(0,J.jsx)(`span`,{className:`pointer-events-none absolute inset-y-0 right-2.5 flex items-center text-xs text-muted-foreground`,children:`%`})]}),(0,J.jsx)(`span`,{className:`text-[10px] text-muted-foreground`,children:t})]})}function Ze(){let[e,n]=(0,K.useState)(null),[r,i]=(0,K.useState)(!1),[a,o]=(0,K.useState)(``),[s,c]=(0,K.useState)(!1),[d,f]=(0,K.useState)(!1);async function p(){if(!d){i(!0),o(``);try{let[e,r]=await Promise.all([t(`GET`,`/routing-policy`),t(`GET`,`/agent-profiles/coordinator`).catch(()=>null)]);n({policy:e,profile:r}),f(!0)}catch(e){o(e.message)}finally{i(!1)}}}async function h(){f(!1),i(!0),o(``);try{let[e,r]=await Promise.all([t(`GET`,`/routing-policy`),t(`GET`,`/agent-profiles/coordinator`).catch(()=>null)]);n({policy:e,profile:r}),f(!0)}catch(e){o(e.message)}finally{i(!1)}}function g(){let e=!s;c(e),e&&!d&&p()}return(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`space-y-3`,children:[(0,J.jsxs)(`button`,{type:`button`,className:`flex w-full items-center gap-2 text-left`,onClick:g,children:[(0,J.jsx)(u,{className:`size-4 text-muted-foreground`}),(0,J.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,J.jsx)(`div`,{className:`text-sm font-semibold`,children:`What your coordinator knows`}),(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground`,children:`Active routing policy + coordinator profile instructions (read-only)`})]}),s?(0,J.jsx)(ee,{className:`size-4 shrink-0 text-muted-foreground`}):(0,J.jsx)(te,{className:`size-4 shrink-0 text-muted-foreground`})]}),s&&(0,J.jsxs)(`div`,{className:`space-y-4 pt-1`,children:[(0,J.jsx)(`div`,{className:`flex justify-end`,children:(0,J.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void h(),disabled:r,children:[(0,J.jsx)(l,{className:m(`size-3.5`,r&&`animate-spin`)}),`Refresh`]})}),a&&(0,J.jsx)(Ge,{message:a}),r&&!e&&(0,J.jsxs)(`div`,{className:`flex items-center gap-2 text-xs text-muted-foreground py-2`,children:[(0,J.jsx)(b,{className:`size-3.5 animate-spin`}),`Loading…`]}),e&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(Qe,{policy:e.policy}),e.profile?(0,J.jsx)(et,{profile:e.profile}):(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`Coordinator profile not found.`})]})]})]})})}function Qe({policy:e}){let t=e.quotaBands,n=e.providerQuota??{};return(0,J.jsxs)(`div`,{className:`space-y-2`,children:[(0,J.jsx)(`div`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wide`,children:`Active routing policy`}),e.rules.length===0?(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`No rules — coordinators use their own heuristics.`}):(0,J.jsxs)(`div`,{className:`overflow-hidden rounded-md border border-border text-xs`,children:[(0,J.jsxs)(`div`,{className:`grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:[(0,J.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`#`}),(0,J.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Match`}),(0,J.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Target`}),(0,J.jsx)(`div`,{className:`bg-muted/40 px-2 py-1.5`,children:`Status`})]}),e.rules.map((e,t)=>(0,J.jsxs)(`div`,{className:m(`grid grid-cols-[1.5rem_minmax(0,1fr)_minmax(0,1fr)_minmax(0,1fr)] gap-px bg-border`,e.enabled===!1&&`opacity-50`),children:[(0,J.jsx)(`div`,{className:`bg-card px-2 py-1.5 text-muted-foreground tabular-nums`,children:t+1}),(0,J.jsxs)(`div`,{className:`bg-card px-2 py-1.5`,children:[e.label&&(0,J.jsx)(`div`,{className:`font-medium`,children:e.label}),e.match.taskType&&(0,J.jsxs)(`div`,{className:`font-mono`,children:[`task: `,e.match.taskType]}),e.match.capability&&(0,J.jsxs)(`div`,{className:`font-mono`,children:[`cap: `,e.match.capability]})]}),(0,J.jsxs)(`div`,{className:`bg-card px-2 py-1.5`,children:[(0,J.jsx)(`span`,{className:`font-medium`,children:e.target.provider}),e.target.model&&(0,J.jsxs)(`span`,{className:`text-muted-foreground`,children:[` / `,e.target.model]}),e.target.effort&&(0,J.jsxs)(`span`,{className:`text-muted-foreground`,children:[` (`,e.target.effort,`)`]})]}),(0,J.jsx)(`div`,{className:`bg-card px-2 py-1.5`,children:e.enabled===!1?(0,J.jsx)(`span`,{className:`text-muted-foreground`,children:`disabled`}):(0,J.jsx)(`span`,{className:`text-emerald-500`,children:`active`})})]},t))]}),(t||Object.keys(n).length>0)&&(0,J.jsxs)(`div`,{className:`rounded-md border border-border bg-muted/10 px-3 py-2 text-xs space-y-1`,children:[t&&(0,J.jsxs)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-0.5`,children:[t.cautionAt!==void 0&&(0,J.jsxs)(`span`,{children:[`caution ≥ `,(t.cautionAt*100).toFixed(0),`%`]}),t.avoidLargeAt!==void 0&&(0,J.jsxs)(`span`,{children:[`avoid-large ≥ `,(t.avoidLargeAt*100).toFixed(0),`%`]}),t.hardAvoidAt!==void 0&&(0,J.jsxs)(`span`,{children:[`hard-avoid ≥ `,(t.hardAvoidAt*100).toFixed(0),`%`]})]}),Object.entries(n).map(([e,t])=>(0,J.jsxs)(`div`,{className:`flex flex-wrap gap-x-4 gap-y-0.5 text-muted-foreground`,children:[(0,J.jsx)(`span`,{className:`font-medium text-foreground`,children:j(e)}),t?.hardBackstopUtilization!==void 0&&(0,J.jsxs)(`span`,{children:[`backstop: `,(t.hardBackstopUtilization*100).toFixed(0),`%`]}),t?.burnPenaltyUtilizationFloor!==void 0&&(0,J.jsxs)(`span`,{children:[`floor: `,(t.burnPenaltyUtilizationFloor*100).toFixed(0),`%`]})]},e))]})]})}function $e({text:e,index:t}){return(0,J.jsxs)(`div`,{className:`relative max-h-72 overflow-y-auto rounded-md border border-border bg-muted/20`,children:[t!==void 0&&(0,J.jsxs)(`span`,{className:`sticky top-0 float-right m-1.5 rounded bg-muted px-1.5 py-0.5 text-[9px] font-medium tabular-nums text-muted-foreground`,children:[`#`,t]}),(0,J.jsx)(`pre`,{className:`whitespace-pre-wrap break-words px-3 py-2.5 font-sans text-[11px] leading-relaxed text-foreground/90`,children:e})]})}function et({profile:e}){return(0,J.jsxs)(`div`,{className:`space-y-2`,children:[(0,J.jsxs)(`div`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wide`,children:[`Coordinator profile instructions`,(0,J.jsx)(L,{variant:`secondary`,className:`ml-2 text-[10px]`,children:e.name}),e.builtIn&&(0,J.jsx)(L,{variant:`outline`,className:`ml-1 text-[10px]`,children:`built-in`})]}),e.description&&(0,J.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:e.description}),(0,J.jsxs)(`div`,{className:`flex flex-wrap gap-2 text-[10px]`,children:[(0,J.jsxs)(L,{variant:`outline`,children:[`base: `,e.base]}),(0,J.jsxs)(L,{variant:`outline`,children:[`repo: `,e.instructions.repoInstructions]}),(0,J.jsxs)(L,{variant:`outline`,children:[`global: `,e.instructions.globalInstructions]}),e.provider&&(0,J.jsxs)(L,{variant:`outline`,children:[`provider: `,e.provider]})]}),e.instructions.system&&(0,J.jsxs)(`div`,{className:`space-y-1`,children:[(0,J.jsx)(`div`,{className:`text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:`System prompt`}),(0,J.jsx)($e,{text:e.instructions.system})]}),e.instructions.append.length>0&&(0,J.jsxs)(`div`,{className:`space-y-2`,children:[(0,J.jsxs)(`div`,{className:`text-[10px] font-medium text-muted-foreground uppercase tracking-wide`,children:[`Appended instructions (`,e.instructions.append.length,`)`]}),e.instructions.append.map((e,t)=>(0,J.jsx)($e,{text:e,index:t+1},t))]}),e.instructions.append.length===0&&!e.instructions.system&&(0,J.jsx)(`div`,{className:`text-xs text-muted-foreground italic`,children:`No instruction blocks defined.`})]})}var tt=re();function nt(){return{label:``,matchTaskType:``,matchCapability:``,targetProvider:tt[0]??``,targetModel:``,targetEffort:``,enabled:!0}}function rt(e){return{label:e.label??``,matchTaskType:e.match.taskType??``,matchCapability:e.match.capability??``,targetProvider:e.target.provider,targetModel:e.target.model??``,targetEffort:e.target.effort??``,enabled:e.enabled!==!1}}function it(e){return{...e.label.trim()?{label:e.label.trim()}:{},match:{...e.matchTaskType.trim()?{taskType:e.matchTaskType.trim()}:{},...e.matchCapability.trim()?{capability:e.matchCapability.trim()}:{}},target:{provider:e.targetProvider,...e.targetModel.trim()?{model:e.targetModel.trim()}:{},...e.targetEffort.trim()?{effort:e.targetEffort.trim()}:{}},enabled:e.enabled}}function at(e){return!e.matchTaskType.trim()&&!e.matchCapability.trim()?`At least one match criterion (task type or capability) is required.`:null}function ot({message:e}){return(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4 shrink-0`}),(0,J.jsx)(`span`,{children:e})]})}function st({canWrite:e}){let[n,r]=(0,K.useState)(null),[i,a]=(0,K.useState)(!1),[o,s]=(0,K.useState)(``),[c,u]=(0,K.useState)(!1);!c&&!i&&!o&&(a(!0),(async()=>{try{r(await t(`GET`,`/routing-policy`)),u(!0)}catch(e){s(e.message)}finally{a(!1)}})());async function d(){a(!0),s(``);try{r(await t(`GET`,`/routing-policy`)),u(!0)}catch(e){s(e.message)}finally{a(!1)}}return(0,J.jsxs)(`div`,{className:`space-y-6`,children:[(0,J.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h2`,{className:`text-base font-semibold`,children:`Routing`}),(0,J.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Declarative rules mapping task types and capabilities to providers. Rules are advisory — coordinators apply them; explicit per-spawn arguments always take precedence.`})]}),(0,J.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void d(),disabled:i,children:[(0,J.jsx)(l,{className:m(`size-4`,i&&`animate-spin`)}),`Refresh`]})]}),o&&(0,J.jsx)(ot,{message:o}),i&&!n&&(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:[(0,J.jsx)(b,{className:`size-4 animate-spin`}),`Loading routing policy…`]})}),n&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(ct,{policy:n,canWrite:e,onPolicy:r}),(0,J.jsx)(Ye,{policy:n,canWrite:e,onPolicy:r})]}),(0,J.jsx)(Ze,{})]})}function ct({policy:e,canWrite:n,onPolicy:r}){let[a,o]=(0,K.useState)(!1),[s,c]=(0,K.useState)(``),[l,u]=(0,K.useState)(!1),[d,f]=(0,K.useState)(nt),[p,m]=(0,K.useState)(``),[h,g]=(0,K.useState)(null),[_,v]=(0,K.useState)(nt),[y,x]=(0,K.useState)(``);async function S(e){o(!0),c(``);try{r(await t(`PUT`,`/routing-policy`,e))}catch(e){c(e.message)}finally{o(!1)}}function w(t,n){let r=[...e.rules],i=t+n;i<0||i>=r.length||([r[t],r[i]]=[r[i],r[t]],S({...e,rules:r}))}function T(t){let n=e.rules.map((e,n)=>n===t?{...e,enabled:e.enabled===!1}:e);S({...e,rules:n})}function E(t){S({...e,rules:e.rules.filter((e,n)=>n!==t)})}function D(){f(nt()),m(``),u(!0)}function ee(){u(!1),m(``)}function te(){let t=at(d);if(t){m(t);return}u(!1),S({...e,rules:[...e.rules,it(d)]})}function O(t){g(t),v(rt(e.rules[t])),x(``)}function k(){g(null),x(``)}function A(){if(h===null)return;let t=at(_);if(t){x(t);return}let n=e.rules.map((e,t)=>t===h?it(_):e);g(null),S({...e,rules:n})}return(0,J.jsxs)(G,{size:`sm`,children:[(0,J.jsxs)(V,{children:[(0,J.jsxs)(U,{className:`flex items-center gap-2 text-sm`,children:[(0,J.jsx)(C,{className:`size-4`}),`Rules`,(0,J.jsxs)(L,{variant:`outline`,className:`ml-auto text-[10px]`,children:[e.rules.length,` rule`,e.rules.length===1?``:`s`]}),a&&(0,J.jsx)(b,{className:`size-3 animate-spin text-muted-foreground`})]}),(0,J.jsx)(H,{className:`text-xs`,children:`Evaluated in order — first matching enabled rule wins. Rules are advisory; explicit spawn arguments override them.`})]}),(0,J.jsxs)(W,{className:`space-y-2`,children:[s&&(0,J.jsx)(ot,{message:s}),e.rules.length===0&&!l&&(0,J.jsx)(`div`,{className:`rounded-md border border-dashed border-border py-6 text-center text-xs text-muted-foreground`,children:`No rules — coordinators fall back to their own heuristics.`}),e.rules.map((t,r)=>h===r?(0,J.jsx)(ut,{form:_,error:y,onChange:v,onSave:A,onCancel:k},r):(0,J.jsx)(lt,{rule:t,idx:r,total:e.rules.length,canWrite:n,saving:a,onMoveUp:()=>w(r,-1),onMoveDown:()=>w(r,1),onToggle:()=>T(r),onEdit:()=>O(r),onRemove:()=>E(r)},r)),l&&(0,J.jsx)(ut,{form:d,error:p,onChange:f,onSave:te,onCancel:ee,isNew:!0}),n&&!l&&h===null&&(0,J.jsxs)(R,{variant:`outline`,size:`sm`,className:`w-full gap-1`,onClick:D,disabled:a,children:[(0,J.jsx)(i,{className:`size-4`}),`Add rule`]})]})]})}function lt({rule:e,idx:t,total:n,canWrite:r,saving:i,onMoveUp:o,onMoveDown:s,onToggle:l,onEdit:u,onRemove:d}){return(0,J.jsxs)(`div`,{className:m(`group flex items-start gap-3 rounded-md border bg-muted/20 p-3`,e.enabled===!1&&`opacity-60`),children:[(0,J.jsxs)(`div`,{className:`flex flex-col items-center gap-0.5 pt-0.5`,children:[(0,J.jsx)(`button`,{type:`button`,title:`Move up`,onClick:o,disabled:!r||i||t===0,className:`rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30`,children:(0,J.jsx)(a,{className:`size-3.5`})}),(0,J.jsx)(`button`,{type:`button`,title:`Move down`,onClick:s,disabled:!r||i||t===n-1,className:`rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none disabled:opacity-30`,children:(0,J.jsx)(c,{className:`size-3.5`})})]}),(0,J.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-1`,children:[(0,J.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,J.jsxs)(`span`,{className:`text-[10px] tabular-nums text-muted-foreground`,children:[`#`,t+1]}),e.label&&(0,J.jsx)(`span`,{className:`text-xs font-medium`,children:e.label}),(0,J.jsx)(L,{variant:`outline`,className:`text-[10px]`,children:e.target.provider}),e.target.model&&(0,J.jsx)(L,{variant:`outline`,className:`text-[10px] font-mono`,children:e.target.model}),e.target.effort&&(0,J.jsx)(L,{variant:`outline`,className:`text-[10px]`,children:e.target.effort})]}),(0,J.jsxs)(`div`,{className:`flex flex-wrap gap-x-3 gap-y-0.5 text-[10px] text-muted-foreground`,children:[e.match.taskType&&(0,J.jsxs)(`span`,{children:[`task-type: `,(0,J.jsx)(`span`,{className:`font-mono text-foreground`,children:e.match.taskType})]}),e.match.capability&&(0,J.jsxs)(`span`,{children:[`capability: `,(0,J.jsx)(`span`,{className:`font-mono text-foreground`,children:e.match.capability})]})]})]}),(0,J.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 opacity-70 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100`,children:[(0,J.jsx)(B,{checked:e.enabled!==!1,disabled:!r||i,onCheckedChange:l,title:e.enabled===!1?`Enable rule`:`Disable rule`}),r&&(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(`button`,{type:`button`,title:`Edit`,onClick:u,disabled:i,className:`rounded p-1 text-muted-foreground hover:bg-accent hover:text-foreground disabled:pointer-events-none`,children:(0,J.jsxs)(`svg`,{className:`size-3.5`,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,children:[(0,J.jsx)(`path`,{d:`M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7`}),(0,J.jsx)(`path`,{d:`M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z`})]})}),(0,J.jsx)(`button`,{type:`button`,title:`Remove`,onClick:d,disabled:i,className:`rounded p-1 text-destructive hover:bg-destructive/10 disabled:pointer-events-none`,children:(0,J.jsx)(x,{className:`size-3.5`})})]})]})]})}function ut({form:e,error:t,onChange:r,onSave:i,onCancel:a,isNew:o}){function s(t){r({...e,...t})}return(0,J.jsxs)(`div`,{className:`rounded-md border border-primary/30 bg-primary/5 p-3 space-y-3`,children:[(0,J.jsx)(`div`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wide`,children:o?`New rule`:`Edit rule`}),(0,J.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Label (optional)`}),(0,J.jsx)(z,{value:e.label,onChange:e=>s({label:e.target.value}),placeholder:`e.g. Route GUI tasks to Claude`,className:`h-8 text-xs`})]}),(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Target provider`}),(0,J.jsxs)(I,{value:e.targetProvider,onValueChange:e=>s({targetProvider:e}),children:[(0,J.jsx)(N,{className:`h-8 text-xs`,children:(0,J.jsx)(M,{})}),(0,J.jsx)(P,{children:tt.map(e=>(0,J.jsx)(F,{value:e,className:`text-xs`,children:j(e)},e))})]})]})]}),(0,J.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Match task-type (prefix)`}),(0,J.jsx)(z,{value:e.matchTaskType,onChange:e=>s({matchTaskType:e.target.value}),placeholder:`e.g. gui, backend, mechanical`,className:`h-8 font-mono text-xs`}),(0,J.jsxs)(`span`,{className:`block text-[10px] leading-snug text-muted-foreground`,children:[`Prefix match — `,(0,J.jsx)(`span`,{className:`font-mono text-foreground`,children:`gui`}),` matches `,(0,J.jsx)(`span`,{className:`font-mono text-foreground`,children:`gui/ux`}),`, `,(0,J.jsx)(`span`,{className:`font-mono text-foreground`,children:`gui/layout`}),`.`]})]}),(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Match capability (exact)`}),(0,J.jsx)(z,{value:e.matchCapability,onChange:e=>s({matchCapability:e.target.value}),placeholder:`e.g. code, research, bounded`,className:`h-8 font-mono text-xs`}),(0,J.jsx)(`span`,{className:`block text-[10px] leading-snug text-muted-foreground`,children:`Exact match against the agent's capability tag. Both fields are AND-ed.`})]})]}),(0,J.jsxs)(`div`,{className:`grid gap-3 sm:grid-cols-2`,children:[(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Model alias (optional)`}),(0,J.jsx)(z,{value:e.targetModel,onChange:e=>s({targetModel:e.target.value}),placeholder:`e.g. opus, gpt-5.4`,className:`h-8 font-mono text-xs`})]}),(0,J.jsxs)(`label`,{className:`space-y-1`,children:[(0,J.jsx)(`span`,{className:`text-[10px] font-medium text-muted-foreground`,children:`Effort (optional)`}),(0,J.jsx)(z,{value:e.targetEffort,onChange:e=>s({targetEffort:e.target.value}),placeholder:`e.g. high, low`,className:`h-8 text-xs`})]})]}),(0,J.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,J.jsx)(B,{checked:e.enabled,onCheckedChange:e=>s({enabled:e})}),(0,J.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Enabled`})]}),t&&(0,J.jsx)(ot,{message:t}),(0,J.jsxs)(`div`,{className:`flex gap-2`,children:[(0,J.jsxs)(R,{size:`sm`,onClick:i,children:[(0,J.jsx)(n,{className:`size-4`}),o?`Add`:`Save`]}),(0,J.jsx)(R,{size:`sm`,variant:`outline`,onClick:a,children:`Cancel`})]})]})}var dt=`browser`,ft=`models`,pt=`profile`,mt=`routing`,ht=[`branch.landed`,`landed-failure`,`agent.ready`,`agent.exited`,`agent.spawn_failed`,`agent.context_threshold`,`agent.quota_threshold`,`workspace.steward_task`,`workspace.conflict`,`workspace.review_request`];function gt(){if(typeof window>`u`)return``;let e=window.location.hash.replace(/^#/,``);return e.startsWith(`settings/`)?decodeURIComponent(e.slice(9)):``}function _t(e){if(typeof window>`u`)return;let t=new URL(window.location.href);t.hash=`settings/${encodeURIComponent(e)}`,window.history.pushState({},``,t)}function vt(){let[e,n]=(0,K.useState)([]),[r,i]=(0,K.useState)(null),[a,o]=(0,K.useState)([]),[s,c]=(0,K.useState)(()=>gt()),[u,d]=(0,K.useState)(!0),[f,p]=(0,K.useState)(``),[h,v]=(0,K.useState)(``);async function y(){d(!0),p(``),v(``);try{let[e,r,a]=await Promise.all([t(`GET`,`/settings`),t(`GET`,`/tokens/me`),t(`GET`,`/providers`).catch(e=>(v(e.message),{catalog:[]}))]);n(e.settings),i(r),o(a.catalog)}catch(e){p(e.message)}finally{d(!1)}}(0,K.useEffect)(()=>{y()},[]),(0,K.useEffect)(()=>{let e=()=>c(gt());return window.addEventListener(`hashchange`,e),window.addEventListener(`popstate`,e),()=>{window.removeEventListener(`hashchange`,e),window.removeEventListener(`popstate`,e)}},[]);let b=(0,K.useMemo)(()=>fe(e),[e]),x=(0,K.useMemo)(()=>[...b.map(e=>({slug:e.slug,label:e.group,description:`${e.settings.length} schema setting${e.settings.length===1?``:`s`}`,kind:`descriptors`,settings:e.settings})),{slug:mt,label:`Routing`,description:`Rules, quota thresholds, coordinator view`,kind:`routing`,settings:[]},{slug:pt,label:`Profile`,description:`Display name and avatar`,kind:`profile`,settings:[]},{slug:dt,label:`Browser`,description:`Local dashboard preferences`,kind:`browser`,settings:[]},{slug:ft,label:`Models`,description:`Provider model catalog`,kind:`models`,settings:[]}],[b]),S=x.find(e=>e.slug===s)??x[0];function C(e){c(e),_t(e)}function w(e){n(t=>t.map(t=>q(t)===q(e)?e:t))}return(0,J.jsxs)(`div`,{className:`space-y-4`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-start justify-between gap-3`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h1`,{className:`text-lg font-semibold`,children:`Settings`}),(0,J.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Schema-driven Relay settings, browser preferences, and model catalog controls.`})]}),(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[r&&(0,J.jsxs)(L,{variant:`outline`,className:`gap-1`,children:[(0,J.jsx)(g,{className:`size-3`}),r.kind,`:`,r.actor]}),(0,J.jsxs)(R,{variant:`outline`,size:`sm`,onClick:()=>void y(),disabled:u,children:[(0,J.jsx)(l,{className:m(`size-4`,u&&`animate-spin`)}),`Refresh`]})]})]}),f&&(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-lg border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4`}),(0,J.jsx)(`span`,{children:f})]}),(0,J.jsxs)(`div`,{className:`grid gap-4 lg:grid-cols-[230px_minmax(0,1fr)]`,children:[(0,J.jsx)(`nav`,{className:`space-y-1 lg:sticky lg:top-4 lg:self-start`,children:x.map(e=>(0,J.jsxs)(`button`,{type:`button`,className:m(`w-full rounded-md border px-3 py-2 text-left text-sm transition-colors`,S?.slug===e.slug?`border-primary/50 bg-primary/10 text-foreground`:`border-transparent hover:border-border hover:bg-accent`),onClick:()=>C(e.slug),children:[(0,J.jsx)(`span`,{className:`block font-medium`,children:e.label}),(0,J.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:e.description})]},e.slug))}),(0,J.jsx)(`div`,{className:`min-w-0 space-y-4`,children:u&&!e.length?(0,J.jsx)(G,{size:`sm`,children:(0,J.jsx)(W,{className:`text-sm text-muted-foreground`,children:`Loading settings…`})}):S?.kind===`routing`?(0,J.jsx)(st,{canWrite:ae(r?.scopes,`settings:write:routing`)}):S?.kind===`descriptors`?(0,J.jsxs)(J.Fragment,{children:[(0,J.jsx)(De,{group:S.label,settings:S.settings,onSaved:w}),S.label===`Providers`&&(0,J.jsx)(We,{canWrite:ae(r?.scopes,`settings:write:provider`)}),S.label===`Notifications`&&(0,J.jsx)(yt,{})]}):S?.kind===`profile`?(0,J.jsx)(bt,{}):S?.kind===`browser`?(0,J.jsx)(je,{}):(0,J.jsx)(Ne,{catalog:a,error:h,canWrite:ae(r?.scopes,`settings:write:provider`),onCatalog:o})})]})]})}function yt(){let[e,n]=(0,K.useState)(`branch.landed`),[r,i]=(0,K.useState)(`{
4
- "repoRoot": "/repo"
5
- }`),[a,o]=(0,K.useState)(null),[s,c]=(0,K.useState)(!1),[l,u]=(0,K.useState)(``);async function d(){c(!0),u(``);try{let n=JSON.parse(r);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Scope must be a JSON object`);o((await t(`POST`,`/notifications/preview`,{type:e,scope:n})).preview)}catch(e){o(null),u(e.message)}finally{c(!1)}}return(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`space-y-3`,children:[(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,J.jsxs)(`div`,{children:[(0,J.jsx)(`h2`,{className:`text-sm font-semibold`,children:`Who gets what`}),(0,J.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Dry-run notification routing without sending.`})]}),(0,J.jsxs)(R,{size:`sm`,onClick:()=>void d(),disabled:s,children:[(0,J.jsx)(C,{className:`size-4`}),`Preview`]})]}),(0,J.jsxs)(`div`,{className:`grid gap-3 md:grid-cols-[240px_minmax(0,1fr)]`,children:[(0,J.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,J.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`Type`}),(0,J.jsxs)(I,{value:e,onValueChange:n,children:[(0,J.jsx)(N,{className:`w-full`,children:(0,J.jsx)(M,{})}),(0,J.jsx)(P,{children:ht.map(e=>(0,J.jsx)(F,{value:e,children:e},e))})]})]}),(0,J.jsxs)(`div`,{className:`space-y-1.5`,children:[(0,J.jsx)(`label`,{className:`text-xs font-medium text-muted-foreground`,children:`Scope`}),(0,J.jsx)(se,{value:r,onChange:e=>i(e.target.value),rows:4,className:`font-mono text-xs`})]})]}),l&&(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-2 text-xs text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-3.5`}),(0,J.jsx)(`span`,{children:l})]}),a&&(0,J.jsx)(`div`,{className:`overflow-hidden rounded-md border border-border`,children:a.recipients.length===0?(0,J.jsx)(`div`,{className:`px-3 py-4 text-center text-xs text-muted-foreground`,children:`No recipients`}):a.recipients.map(e=>(0,J.jsxs)(`div`,{className:`grid gap-1 border-b border-border px-3 py-2 text-xs last:border-b-0 md:grid-cols-[minmax(0,180px)_minmax(0,160px)_minmax(0,1fr)]`,children:[(0,J.jsx)(`span`,{className:`truncate font-medium`,children:e.recipient}),(0,J.jsx)(`span`,{className:`truncate font-mono text-muted-foreground`,children:e.matchedRule}),(0,J.jsx)(`span`,{className:`truncate text-muted-foreground`,children:e.reason})]},`${e.recipient}-${e.matchedRule}`))})]})})}function bt(){let e=A(e=>e.fetchUsers),r=(0,K.useRef)(null),[i,a]=(0,K.useState)(null),[o,c]=(0,K.useState)(``),[l,u]=(0,K.useState)(!0),[d,f]=(0,K.useState)(!1),[p,m]=(0,K.useState)(``);async function h(){u(!0),m(``);try{let e=await t(`GET`,`/users/me`);a(e),c(e.displayName||e.handle)}catch(e){m(e.message)}finally{u(!1)}}(0,K.useEffect)(()=>{h()},[]);async function g(){f(!0),m(``);try{let n=await t(`PATCH`,`/users/me`,{displayName:o});a(n),c(n.displayName||n.handle),await e()}catch(e){m(e.message)}finally{f(!1)}}async function v(t){if(t){f(!0),m(``);try{let n=await D(`/users/me/avatar`,t);a(n.user),c(n.user.displayName||n.user.handle),await e()}catch(e){m(e.message)}finally{f(!1),r.current&&(r.current.value=``)}}}async function y(){f(!0),m(``);try{a(await t(`DELETE`,`/users/me/avatar`)),await e()}catch(e){m(e.message)}finally{f(!1)}}return(0,J.jsx)(G,{size:`sm`,children:(0,J.jsxs)(W,{className:`space-y-4`,children:[p&&(0,J.jsxs)(`div`,{className:`flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 p-3 text-sm text-destructive`,children:[(0,J.jsx)(_,{className:`mt-0.5 size-4`}),(0,J.jsx)(`span`,{children:p})]}),(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center gap-4`,children:[(0,J.jsx)(le,{user:i??void 0,distinct:!0,className:`size-16 text-lg`}),(0,J.jsxs)(`div`,{className:`min-w-0 flex-1 space-y-2`,children:[(0,J.jsx)(`label`,{className:`block text-xs font-medium text-muted-foreground`,htmlFor:`profile-display-name`,children:`Display name`}),(0,J.jsx)(`input`,{id:`profile-display-name`,className:`h-9 w-full rounded-md border border-input bg-background px-3 text-sm`,value:o,onChange:e=>c(e.target.value),disabled:l||d,maxLength:120})]})]}),(0,J.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,J.jsxs)(R,{size:`sm`,onClick:()=>void g(),disabled:l||d||!o.trim(),children:[(0,J.jsx)(n,{className:`size-4`}),`Save`]}),(0,J.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>r.current?.click(),disabled:l||d,children:[(0,J.jsx)(T,{className:`size-4`}),`Upload`]}),(0,J.jsxs)(R,{size:`sm`,variant:`outline`,onClick:()=>void y(),disabled:l||d||!i?.avatarArtifactId,children:[(0,J.jsx)(x,{className:`size-4`}),`Remove`]}),d&&(0,J.jsx)(s,{className:`size-4 animate-pulse text-muted-foreground`}),(0,J.jsx)(`input`,{ref:r,type:`file`,accept:`image/png,image/jpeg,image/gif,image/webp`,className:`hidden`,onChange:e=>void v(e.target.files?.[0])})]})]})})}export{vt as SettingsView};
6
- //# sourceMappingURL=settings-CbHp2F9r.js.map
@@ -1,2 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{Qn as t,Xn as n,dr as r,er as i}from"./lucide-react-BYZuAhQs.js";import{_ as a,rt as o}from"./display-D1xB8NJZ.js";import{D as s}from"./index-CN7QZlMb.js";var c=e(r(),1),l=t(),u={id:o};function d({user:e,address:t,distinct:r=!1,className:o}){let d=e?.avatarUrl??(e?.avatarArtifactId?`/artifacts/${encodeURIComponent(e.avatarArtifactId)}/content`:null),[f,p]=(0,c.useState)(null);(0,c.useEffect)(()=>{if(!d){p(null);return}let e=!1,t=null;return(async()=>{try{let n=await i(d);if(e)return;t=URL.createObjectURL(n),p(t)}catch{e||p(null)}})(),()=>{e=!0,t&&URL.revokeObjectURL(t)}},[d]);let m=e?.displayName||e?.handle||`User`;if(f)return(0,l.jsx)(`img`,{src:f,alt:m,title:m,className:n(`w-7 h-7 rounded-md object-cover`,o)});if(r){let e=(m.trim()[0]||`U`).toUpperCase();return(0,l.jsx)(`span`,{title:m,className:n(`inline-flex w-7 h-7 items-center justify-center rounded-md bg-muted text-xs font-semibold ring-1 ring-foreground/10`,a(t),o),children:e})}return(0,l.jsx)(s,{agent:u,className:o})}export{d as t};
2
- //# sourceMappingURL=user-avatar-GFWMuAGK.js.map
@@ -1,3 +0,0 @@
1
- import{r as e}from"./chunk-CilyBKbf.js";import{At as t,Bn as n,Dt as r,Gn as i,Ht as a,I as o,It as s,Jn as c,Kt as l,Qn as u,Sn as d,Wt as f,X as p,dr as m,h,i as g,kt as _,m as v,on as y,xn as b,yn as ee,zt as x}from"./lucide-react-BYZuAhQs.js";import{f as S,t as C}from"./store-zeyDiSKE.js";import{i as w}from"./types-DorDDvEb.js";import{K as T,d as E}from"./display-D1xB8NJZ.js";import{t as D}from"./badge-BLar6FjP.js";import{t as O}from"./button-BrIB69qd.js";import{t as k}from"./copy-button-Cd-LbSbg.js";import{a as A,o as j,r as M,t as N}from"./card-lhnFnBoz.js";var P=e(m(),1),F=u(),I=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`,`cleanup_requested`]),L=new Set([`active`,`ready`,`conflict`,`review_requested`,`merge_planned`]),R=new Set([`active`,`ready`,`review_requested`,`merge_planned`,`conflict`]),z={active:`bg-blue-500/10 text-blue-400 border-blue-500/20`,ready:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`,conflict:`bg-red-500/10 text-red-400 border-red-500/20`,review_requested:`bg-yellow-500/10 text-yellow-400 border-yellow-500/20`,merge_planned:`bg-indigo-500/10 text-indigo-400 border-indigo-500/20`,merged:`bg-violet-500/10 text-violet-400 border-violet-500/20`,abandoned:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`,cleanup_requested:`bg-orange-500/10 text-orange-400 border-orange-500/20`,cleaned:`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`},B={active:`active`,ready:`ready`,conflict:`conflict`,review_requested:`review`,merge_planned:`merge planned`,merged:`merged`,abandoned:`abandoned`,cleanup_requested:`cleanup`,cleaned:`cleaned`},V={conflict:0,ready:1,review_requested:2,merge_planned:3,active:4,cleanup_requested:5,merged:6,abandoned:7,cleaned:8},H=new Set(w);function U(e){let t=e.split(`/`).filter(Boolean);return t.length<=3?e||`-`:`/${t.slice(-3).join(`/`)}`}function W(e,t){return e?E(e):t||`-`}function G(e){return z[e]||`bg-zinc-500/10 text-zinc-400 border-zinc-500/20`}function K(e,t){let n=(V[e.status]??99)-(V[t.status]??99);return n===0?Number(t.updatedAt||0)-Number(e.updatedAt||0):n}function q(e){let t=new Map;for(let n of e){let e=n.repoRoot||n.sourceCwd||`unknown repo`;t.set(e,[...t.get(e)||[],n])}return[...t.entries()].map(([e,t])=>({repoRoot:e,workspaces:t.sort(K)})).sort((e,t)=>{let n=e.workspaces.some(e=>I.has(e.status));return n===t.workspaces.some(e=>I.has(e.status))?e.repoRoot.localeCompare(t.repoRoot):n?-1:1})}function J(e,t){return t===`all`?e:t===`cleaned`?e.filter(e=>H.has(e.status)):e.filter(e=>!H.has(e.status))}function Y({workspace:e,expanded:t,onToggleDetails:n}){let i=C(e=>e.workspaceAction),a=C(e=>e.purgeWorkspace),o=C(e=>e.fetchWorkspaceMergePreview),c=C(e=>e.openFilesAt),u=e.status===`cleaned`||e.status===`merged`||e.status===`abandoned`,f=u||e.status===`cleanup_requested`,p=e.worktreePath||e.sourceCwd||e.repoRoot,m=C(t=>t.workspaceGitState[e.id]),_=!!m&&m.available!==!1&&m.landed===!0,v=e.mode===`isolated`&&!!e.worktreePath&&R.has(e.status)&&!_;async function y(){await o(e.id),await i(e.id,`merge`)}return(0,F.jsxs)(`div`,{className:`flex flex-wrap justify-end gap-1.5`,children:[(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,title:t?`Hide details`:`Show diff & timeline`,onClick:n,children:t?(0,F.jsx)(b,{className:`h-3.5 w-3.5`}):(0,F.jsx)(ee,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,title:`Open workspace`,disabled:!p||e.status===`cleaned`,onClick:()=>void c({path:p}),children:(0,F.jsx)(s,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(k,{value:p,label:`Copy path`,copiedLabel:`Copied path`,size:`icon-sm`,variant:`ghost`,disabled:!p}),(0,F.jsx)(O,{size:`icon-sm`,variant:`outline`,title:`Mark ready`,disabled:f||e.status===`ready`,onClick:()=>void i(e.id,`ready`),children:(0,F.jsx)(d,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(O,{size:`icon-sm`,variant:`outline`,title:`Request review`,disabled:f||e.status===`review_requested`,onClick:()=>void i(e.id,`request-review`),children:(0,F.jsx)(l,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(O,{size:`icon-sm`,variant:`outline`,title:`Mark merge planned`,disabled:f||e.status===`merge_planned`,onClick:()=>void i(e.id,`merge-plan`),children:(0,F.jsx)(x,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(O,{size:`icon-sm`,variant:`default`,title:_?`Already merged into base — nothing to land`:`Merge & land work`,disabled:!v,onClick:()=>void y(),children:(0,F.jsx)(r,{className:`h-3.5 w-3.5`})}),(0,F.jsx)(O,{size:`icon-sm`,variant:`outline`,title:`Request cleanup (removes the worktree on the host)`,disabled:e.status===`cleaned`||e.status===`cleanup_requested`,onClick:()=>void i(e.id,`cleanup`),children:(0,F.jsx)(h,{className:`h-3.5 w-3.5`})}),u&&(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,title:`Purge record (clears the row, does not touch disk)`,onClick:()=>void a(e.id),children:(0,F.jsx)(g,{className:`h-3.5 w-3.5`})})]})}function X({workspace:e,unmerged:t}){let n=C(t=>t.workspaceMergePreview[e.id]),r=C(e=>e.fetchWorkspaceMergePreview),i=t>0&&R.has(e.status);return(0,P.useEffect)(()=>{i&&n===void 0&&r(e.id)},[i,n,e.id,r]),!i||n===void 0||n.available===!1?null:n.conflict?(0,F.jsxs)(`span`,{className:`flex items-center gap-0.5 text-amber-400`,title:`Merging into ${n.baseRef||`base`} would conflict — resolve before merging`,children:[(0,F.jsx)(v,{className:`h-3 w-3`}),`conflict`]}):n.conflict===!1?(0,F.jsxs)(`span`,{className:`flex items-center gap-0.5 text-emerald-400`,title:`Clean to merge via ${n.strategy===`pr`?`PR`:`rebase + fast-forward`} into ${n.baseRef||`base`}`,children:[(0,F.jsx)(d,{className:`h-3 w-3`}),n.strategy===`pr`?`PR ready`:`clean`]}):null}function Z({workspace:e}){let t=S(),r=C(t=>t.workspaceGitState[e.id]),s=C(e=>e.fetchWorkspaceGitState),c=e.mode===`isolated`&&!!e.worktreePath&&L.has(e.status);if((0,P.useEffect)(()=>{c&&r===void 0&&s(e.id)},[c,r,e.id,s]),!c)return null;let l=(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh git state`,onClick:()=>void s(e.id),children:(0,F.jsx)(o,{className:`h-3 w-3`})});if(r===void 0)return(0,F.jsx)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:`Loading git state…`});if(r.available===!1)return(0,F.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,title:r.reason,children:[(0,F.jsx)(`span`,{children:`git state unavailable`}),l]});if(r.missing)return(0,F.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-muted-foreground`,children:[`worktree gone `,l]});if(r.error)return(0,F.jsxs)(`div`,{className:`flex items-center gap-1 text-[11px] text-red-400`,title:r.error,children:[(0,F.jsx)(`span`,{children:`git error`}),l]});let u=r.ahead??0,f=r.landed===!0,p=f?0:r.unmergedAhead??u,m=r.behind??0,h=r.dirtyCount??0,g=p===0&&h===0&&!f,v=r.lastCommit;return(0,F.jsxs)(`div`,{className:`space-y-0.5`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px]`,children:[g?(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`no unmerged work`}):(0,F.jsxs)(F.Fragment,{children:[f?(0,F.jsxs)(`span`,{className:`flex items-center gap-0.5 text-emerald-400`,title:`Work already landed in ${r.baseRef||`base`} via squash/cherry-pick — safe to clean up`,children:[(0,F.jsx)(d,{className:`h-3 w-3`}),`landed`]}):(0,F.jsxs)(`span`,{className:p>0?`flex items-center text-emerald-400`:`flex items-center text-muted-foreground`,title:u===p?`${p} commit(s) ahead of base`:`${p} unmerged commit(s) (${u} ahead of base)`,children:[(0,F.jsx)(n,{className:`h-3 w-3`}),p]}),(0,F.jsxs)(`span`,{className:m>0?`flex items-center text-amber-400`:`flex items-center text-muted-foreground`,title:`${m} commit(s) behind base`,children:[(0,F.jsx)(i,{className:`h-3 w-3`}),m]}),h>0&&(0,F.jsxs)(`span`,{className:`flex items-center text-orange-400`,title:`${h} uncommitted change(s)`,children:[(0,F.jsx)(a,{className:`h-3 w-3`}),h]}),!f&&(0,F.jsx)(X,{workspace:e,unmerged:p})]}),l]}),v&&(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground`,title:`${v.sha.slice(0,8)} — ${v.message}`,children:[(0,F.jsx)(_,{className:`h-3 w-3 shrink-0`}),(0,F.jsx)(`span`,{className:`truncate`,children:v.message||v.sha.slice(0,8)}),v.at?(0,F.jsxs)(`span`,{className:`shrink-0 opacity-70`,children:[`· `,T(t,v.at)]}):null]})]})}function Q({workspace:e}){let t=S(),n=typeof e.metadata?.mergedAt==`number`?e.metadata.mergedAt:void 0,r=[{label:`created`,at:e.createdAt},{label:`ready`,at:e.readyAt},{label:`merged`,at:n},{label:`cleaned`,at:e.cleanedAt}].filter(e=>typeof e.at==`number`&&e.at>0);return(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground`,children:[(0,F.jsxs)(`span`,{className:`flex items-center gap-1 font-medium text-foreground`,children:[(0,F.jsx)(y,{className:`h-3 w-3`}),`Timeline`]}),r.map((e,n)=>(0,F.jsxs)(`span`,{className:`flex items-center gap-1`,children:[n>0&&(0,F.jsx)(`span`,{className:`opacity-40`,children:`→`}),(0,F.jsx)(`span`,{className:`text-foreground`,children:e.label}),(0,F.jsx)(`span`,{title:new Date(e.at).toLocaleString(),children:T(t,e.at)})]},e.label))]})}function te(e){return e.startsWith(`+`)&&!e.startsWith(`+++`)?`text-emerald-400`:e.startsWith(`-`)&&!e.startsWith(`---`)?`text-red-400`:e.startsWith(`@@`)?`text-cyan-400`:e.startsWith(`diff `)||e.startsWith(`index `)||e.startsWith(`+++`)||e.startsWith(`---`)?`text-muted-foreground`:``}function ne({workspace:e}){let t=C(t=>t.workspaceDiff[e.id]),n=C(e=>e.fetchWorkspaceDiff),r=e.mode===`isolated`&&!!e.worktreePath;if((0,P.useEffect)(()=>{r&&t===void 0&&n(e.id)},[r,t,e.id,n]),!r)return null;if(t===void 0)return(0,F.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Loading diff…`});if(t.available===!1)return(0,F.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`Diff unavailable`,t.reason?`: ${t.reason}`:``]});if(t.missing)return(0,F.jsx)(`div`,{className:`text-[11px] text-muted-foreground`,children:`Worktree no longer on disk`});if(t.error)return(0,F.jsxs)(`div`,{className:`text-[11px] text-red-400`,children:[`Diff error: `,t.error]});if(!t.files.length)return(0,F.jsxs)(`div`,{className:`text-[11px] text-muted-foreground`,children:[`No committed changes against `,t.baseRef||`base`]});let i=(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,className:`h-5 w-5`,title:`Refresh diff`,onClick:()=>void n(e.id),children:(0,F.jsx)(o,{className:`h-3 w-3`})});return(0,F.jsxs)(`div`,{className:`space-y-1`,children:[(0,F.jsxs)(`div`,{className:`flex items-center gap-2 text-[11px] font-medium`,children:[(0,F.jsx)(f,{className:`h-3 w-3`}),(0,F.jsxs)(`span`,{children:[t.files.length,` file`,t.files.length===1?``:`s`,` vs `,t.baseRef||`base`]}),i]}),(0,F.jsx)(`ul`,{className:`space-y-0.5 text-[11px]`,children:t.files.map(e=>(0,F.jsxs)(`li`,{className:`flex items-center gap-2 font-mono`,children:[(0,F.jsx)(`span`,{className:`truncate`,title:e.path,children:e.path}),e.binary?(0,F.jsx)(`span`,{className:`shrink-0 text-muted-foreground`,children:`binary`}):(0,F.jsxs)(`span`,{className:`shrink-0`,children:[(0,F.jsxs)(`span`,{className:`text-emerald-400`,children:[`+`,e.additions??0]}),` `,(0,F.jsxs)(`span`,{className:`text-red-400`,children:[`−`,e.deletions??0]})]})]},e.path))}),t.patch&&(0,F.jsxs)(`pre`,{className:`max-h-80 overflow-auto rounded border border-border bg-muted/30 p-2 text-[10.5px] leading-relaxed`,children:[t.patch.split(`
2
- `).map((e,t)=>(0,F.jsx)(`div`,{className:te(e),children:e||` `},t)),t.truncated&&(0,F.jsx)(`div`,{className:`mt-1 text-muted-foreground`,children:`… patch truncated`})]})]})}function $({workspace:e}){return(0,F.jsxs)(`div`,{className:`space-y-3 border-t border-dashed border-border bg-muted/20 px-3 py-3`,children:[(0,F.jsx)(Q,{workspace:e}),(0,F.jsx)(ne,{workspace:e})]})}function re(){let e=C(e=>e.workspaceOrphans),n=C(e=>e.fetchWorkspaceOrphans),r=C(e=>e.reclaimWorkspaceOrphan);return(0,P.useEffect)(()=>{n()},[n]),e.length?(0,F.jsxs)(N,{className:`border-amber-500/30`,children:[(0,F.jsxs)(A,{className:`px-4 py-3`,children:[(0,F.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,F.jsx)(p,{className:`h-4 w-4 text-amber-400`}),(0,F.jsx)(j,{className:`text-sm font-medium`,children:`Orphaned worktrees`}),(0,F.jsx)(D,{variant:`outline`,className:`border-amber-500/30 text-amber-400 text-[10px]`,children:e.length}),(0,F.jsx)(O,{size:`icon-sm`,variant:`ghost`,className:`ml-auto h-6 w-6`,title:`Rescan`,onClick:()=>void n(),children:(0,F.jsx)(o,{className:`h-3.5 w-3.5`})})]}),(0,F.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`Agent worktrees on disk with no live workspace. Reclaim removes them from the host.`})]}),(0,F.jsx)(M,{className:`p-0`,children:e.map(e=>(0,F.jsxs)(`div`,{className:`flex items-center gap-3 border-t border-border px-4 py-2 text-xs`,children:[(0,F.jsx)(t,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,F.jsx)(`span`,{className:`truncate font-medium`,title:e.branch,children:e.branch||`(detached)`}),(0,F.jsx)(`span`,{className:`truncate font-mono text-muted-foreground`,title:e.worktreePath,children:U(e.worktreePath)}),e.hadTerminalRow&&(0,F.jsx)(D,{variant:`outline`,className:`text-[10px]`,children:`cleanup failed`}),(0,F.jsxs)(O,{size:`sm`,variant:`outline`,className:`ml-auto h-7 text-xs`,onClick:()=>void r(e),children:[(0,F.jsx)(c,{className:`mr-1 h-3.5 w-3.5`}),`Reclaim`]})]},e.worktreePath))})]}):null}function ie(e){let t=e.match(/\/pull\/(\d+)/);return t?`PR #${t[1]}`:`View PR`}function ae({workspace:e}){let t=e.metadata?.mergeResult,n=t?.prUrl,i=t?.error||e.metadata?.mergeError;return!n&&!i?null:(0,F.jsxs)(F.Fragment,{children:[n&&(0,F.jsxs)(`a`,{href:n,target:`_blank`,rel:`noreferrer`,title:n,className:`inline-flex items-center gap-0.5 rounded border border-violet-500/30 px-1.5 py-0 text-[10px] text-violet-400 hover:text-violet-300`,children:[(0,F.jsx)(r,{className:`h-2.5 w-2.5`}),ie(n)]}),i&&(0,F.jsxs)(D,{variant:`outline`,className:`max-w-[16rem] border-amber-500/30 text-amber-400 text-[10px]`,title:i,children:[(0,F.jsx)(v,{className:`mr-0.5 h-2.5 w-2.5 shrink-0`}),(0,F.jsxs)(`span`,{className:`truncate`,children:[`merge: `,i]})]})]})}function oe({workspace:e}){let n=S(),[r,i]=(0,P.useState)(!1),a=C(e=>e.agentsById),o=C(t=>t.workspaceFocusId===e.id),s=e.ownerAgentId?a[e.ownerAgentId]:void 0,c=e.stewardAgentId?a[e.stewardAgentId]:void 0,l=e.worktreePath||e.sourceCwd||e.repoRoot,u=(0,P.useRef)(null);return(0,P.useEffect)(()=>{o&&u.current?.scrollIntoView({behavior:`smooth`,block:`center`})},[o]),(0,F.jsxs)(`div`,{ref:u,className:`border-t border-border ${o?`bg-primary/5 ring-1 ring-inset ring-primary/40`:``}`,children:[(0,F.jsxs)(`div`,{className:`grid gap-3 px-3 py-3 text-sm lg:grid-cols-[minmax(180px,1.2fr)_minmax(220px,1.5fr)_minmax(160px,1fr)_minmax(170px,auto)]`,children:[(0,F.jsxs)(`div`,{className:`min-w-0 space-y-1`,children:[(0,F.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[(0,F.jsx)(t,{className:`h-3.5 w-3.5 shrink-0 text-muted-foreground`}),(0,F.jsx)(`span`,{className:`truncate font-medium`,title:e.branch||e.id,children:e.branch||e.id})]}),(0,F.jsxs)(`div`,{className:`flex flex-wrap gap-1`,children:[(0,F.jsx)(D,{variant:`outline`,className:`text-[10px] ${e.mode===`isolated`?`border-sky-500/30 text-sky-400`:`border-zinc-500/30 text-zinc-400`}`,children:e.mode}),e.requestedMode&&e.requestedMode!==e.mode&&(0,F.jsxs)(D,{variant:`outline`,className:`text-[10px]`,children:[`requested `,e.requestedMode]}),(0,F.jsx)(D,{variant:`outline`,className:`text-[10px] ${G(e.status)}`,children:B[e.status]||e.status}),(0,F.jsx)(ae,{workspace:e})]})]}),(0,F.jsxs)(`div`,{className:`min-w-0 space-y-1`,children:[(0,F.jsx)(`div`,{className:`truncate font-mono text-xs`,title:l,children:U(l)}),(0,F.jsx)(`div`,{className:`truncate text-xs text-muted-foreground`,title:e.sourceCwd,children:e.sourceCwd}),(0,F.jsx)(Z,{workspace:e})]}),(0,F.jsxs)(`div`,{className:`grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-2 gap-y-1 text-xs`,children:[(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`Owner`}),(0,F.jsx)(`span`,{className:`truncate`,title:e.ownerAgentId,children:W(s,e.ownerPolicyName||e.ownerAgentId)}),(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`Steward`}),(0,F.jsx)(`span`,{className:`truncate`,title:e.stewardAgentId,children:W(c,e.stewardAgentId)}),(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`Updated`}),(0,F.jsx)(`span`,{children:T(n,e.updatedAt)}),e.baseRef&&(0,F.jsxs)(F.Fragment,{children:[(0,F.jsx)(`span`,{className:`text-muted-foreground`,children:`Base`}),(0,F.jsx)(`span`,{className:`truncate`,title:e.baseSha,children:e.baseRef})]})]}),(0,F.jsx)(Y,{workspace:e,expanded:r,onToggleDetails:()=>i(e=>!e)})]}),r&&(0,F.jsx)($,{workspace:e})]})}function se({repoRoot:e,workspaces:t}){let n=t.filter(e=>I.has(e.status)).length,r=t.filter(e=>e.status===`ready`||e.status===`review_requested`||e.status===`merge_planned`).length,i=t.filter(e=>e.status===`conflict`).length;return(0,F.jsxs)(N,{children:[(0,F.jsx)(A,{className:`px-4 py-3`,children:(0,F.jsx)(`div`,{className:`flex min-w-0 items-start gap-3`,children:(0,F.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,F.jsx)(j,{className:`truncate text-sm font-medium`,title:e,children:e}),(0,F.jsxs)(`div`,{className:`mt-1 flex flex-wrap gap-1.5`,children:[(0,F.jsxs)(D,{variant:`outline`,className:`text-[10px]`,children:[t.length,` total`]}),(0,F.jsxs)(D,{variant:`outline`,className:`text-[10px]`,children:[n,` live`]}),r>0&&(0,F.jsxs)(D,{variant:`outline`,className:`border-emerald-500/20 text-emerald-400 text-[10px]`,children:[r,` merge signal`]}),i>0&&(0,F.jsxs)(D,{variant:`outline`,className:`border-red-500/20 text-red-400 text-[10px]`,children:[i,` conflict`]})]})]})})}),(0,F.jsx)(M,{className:`p-0`,children:t.map(e=>(0,F.jsx)(oe,{workspace:e},e.id))})]})}function ce(){let[e,t]=(0,P.useState)(`active`),n=C(e=>e.workspaces),r=C(e=>e.set),i=C(e=>e.workspaceFocusId);(0,P.useEffect)(()=>{i&&t(`all`)},[i]),(0,P.useEffect)(()=>()=>{r({workspaceFocusId:null})},[r]);let a=(0,P.useMemo)(()=>J(n,e),[n,e]),o=(0,P.useMemo)(()=>q(a),[a]),s=n.filter(e=>I.has(e.status)).length,c=n.filter(e=>e.mode===`isolated`).length,l=n.filter(e=>e.status===`ready`||e.status===`review_requested`||e.status===`merge_planned`).length,u=n.filter(e=>e.status===`conflict`).length,d=n.filter(e=>H.has(e.status)).length,f=[{key:`active`,label:`Active`,count:n.length-d},{key:`cleaned`,label:`Done`,count:d},{key:`all`,label:`All`,count:n.length}];return(0,F.jsxs)(`div`,{className:`space-y-4`,children:[(0,F.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,F.jsxs)(`div`,{children:[(0,F.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Workspaces`}),(0,F.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Agent worktrees, ownership, and merge readiness.`})]}),(0,F.jsxs)(`div`,{className:`ml-auto flex flex-wrap gap-1.5`,children:[(0,F.jsxs)(D,{variant:`outline`,children:[c,` isolated`]}),(0,F.jsxs)(D,{variant:`outline`,children:[s,` live`]}),(0,F.jsxs)(D,{variant:`outline`,children:[l,` ready`]}),u>0&&(0,F.jsxs)(D,{variant:`outline`,className:`border-red-500/20 text-red-400`,children:[u,` conflict`]})]})]}),(0,F.jsx)(re,{}),(0,F.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:(0,F.jsx)(`div`,{className:`flex rounded-md border border-border bg-card p-1`,children:f.map(n=>(0,F.jsxs)(O,{size:`sm`,variant:e===n.key?`secondary`:`ghost`,className:`h-7 text-xs`,onClick:()=>t(n.key),children:[n.label,(0,F.jsx)(`span`,{className:`ml-1 text-muted-foreground`,children:n.count})]},n.key))})}),o.length===0?(0,F.jsxs)(`div`,{className:`rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground`,children:[`No `,e===`all`?``:e,` workspaces`]}):(0,F.jsx)(`div`,{className:`space-y-3`,children:o.map(e=>(0,F.jsx)(se,{repoRoot:e.repoRoot,workspaces:e.workspaces},e.repoRoot))})]})}export{ce as WorkspacesView};
3
- //# sourceMappingURL=workspaces-CSpmgbPT.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"workspaces-CSpmgbPT.js","names":[],"sources":["../../dashboard/src/components/views/workspaces.tsx"],"sourcesContent":["import { useEffect, useMemo, useRef, useState } from 'react'\nimport { ArchiveRestore, ArrowDown, ArrowUp, Check, ChevronDown, ChevronRight, Clock, Eye, FileDiff, FilePen, Flag, FolderOpen, GitBranch, GitCommitHorizontal, GitMerge, PackageOpen, RefreshCw, TriangleAlert, Trash2, X } from 'lucide-react'\nimport { TERMINAL_WORKSPACE_STATUS_VALUES } from 'agent-relay-sdk/types'\nimport { useRelayStore, useNow } from '@/store'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { CopyButton } from '@/components/shared/copy-button'\nimport { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'\nimport { displayName, timeAgo } from '@/lib/display'\nimport type { Agent, WorkspaceOrphan, WorkspaceRecord, WorkspaceStatus } from '@/types'\n\nconst LIVE_STATUSES = new Set<WorkspaceStatus>(['active', 'ready', 'conflict', 'review_requested', 'merge_planned', 'cleanup_requested'])\nconst GIT_STATE_STATUSES = new Set<WorkspaceStatus>(['active', 'ready', 'conflict', 'review_requested', 'merge_planned'])\nconst MERGEABLE_STATUSES = new Set<WorkspaceStatus>(['active', 'ready', 'review_requested', 'merge_planned', 'conflict'])\n\ntype WorkspaceFilter = 'active' | 'cleaned' | 'all'\n\nconst STATUS_CLASS: Record<WorkspaceStatus, string> = {\n active: 'bg-blue-500/10 text-blue-400 border-blue-500/20',\n ready: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20',\n conflict: 'bg-red-500/10 text-red-400 border-red-500/20',\n review_requested: 'bg-yellow-500/10 text-yellow-400 border-yellow-500/20',\n merge_planned: 'bg-indigo-500/10 text-indigo-400 border-indigo-500/20',\n merged: 'bg-violet-500/10 text-violet-400 border-violet-500/20',\n abandoned: 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20',\n cleanup_requested: 'bg-orange-500/10 text-orange-400 border-orange-500/20',\n cleaned: 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20',\n}\n\nconst STATUS_LABEL: Record<WorkspaceStatus, string> = {\n active: 'active',\n ready: 'ready',\n conflict: 'conflict',\n review_requested: 'review',\n merge_planned: 'merge planned',\n merged: 'merged',\n abandoned: 'abandoned',\n cleanup_requested: 'cleanup',\n cleaned: 'cleaned',\n}\n\nconst STATUS_ORDER: Record<WorkspaceStatus, number> = {\n conflict: 0,\n ready: 1,\n review_requested: 2,\n merge_planned: 3,\n active: 4,\n cleanup_requested: 5,\n merged: 6,\n abandoned: 7,\n cleaned: 8,\n}\n\nconst TERMINAL_STATUSES = new Set<WorkspaceStatus>(TERMINAL_WORKSPACE_STATUS_VALUES)\n\nfunction shortPath(path: string): string {\n const parts = path.split('/').filter(Boolean)\n if (parts.length <= 3) return path || '-'\n return `/${parts.slice(-3).join('/')}`\n}\n\nfunction agentLabel(agent: Agent | undefined, fallback: string | undefined): string {\n if (agent) return displayName(agent)\n return fallback || '-'\n}\n\nfunction statusTone(status: WorkspaceStatus): string {\n return STATUS_CLASS[status] || 'bg-zinc-500/10 text-zinc-400 border-zinc-500/20'\n}\n\nfunction workspaceSort(a: WorkspaceRecord, b: WorkspaceRecord): number {\n const status = (STATUS_ORDER[a.status] ?? 99) - (STATUS_ORDER[b.status] ?? 99)\n if (status !== 0) return status\n return Number(b.updatedAt || 0) - Number(a.updatedAt || 0)\n}\n\nfunction groupWorkspaces(workspaces: WorkspaceRecord[]): Array<{ repoRoot: string; workspaces: WorkspaceRecord[] }> {\n const grouped = new Map<string, WorkspaceRecord[]>()\n for (const workspace of workspaces) {\n const key = workspace.repoRoot || workspace.sourceCwd || 'unknown repo'\n grouped.set(key, [...(grouped.get(key) || []), workspace])\n }\n return [...grouped.entries()]\n .map(([repoRoot, items]) => ({ repoRoot, workspaces: items.sort(workspaceSort) }))\n .sort((a, b) => {\n const liveA = a.workspaces.some((item) => LIVE_STATUSES.has(item.status))\n const liveB = b.workspaces.some((item) => LIVE_STATUSES.has(item.status))\n if (liveA !== liveB) return liveA ? -1 : 1\n return a.repoRoot.localeCompare(b.repoRoot)\n })\n}\n\nfunction filterWorkspaces(workspaces: WorkspaceRecord[], filter: WorkspaceFilter): WorkspaceRecord[] {\n if (filter === 'all') return workspaces\n if (filter === 'cleaned') return workspaces.filter((workspace) => TERMINAL_STATUSES.has(workspace.status))\n return workspaces.filter((workspace) => !TERMINAL_STATUSES.has(workspace.status))\n}\n\nfunction WorkspaceActions({ workspace, expanded, onToggleDetails }: { workspace: WorkspaceRecord; expanded: boolean; onToggleDetails: () => void }) {\n const workspaceAction = useRelayStore((s) => s.workspaceAction)\n const purgeWorkspace = useRelayStore((s) => s.purgeWorkspace)\n const fetchWorkspaceMergePreview = useRelayStore((s) => s.fetchWorkspaceMergePreview)\n const openFilesAt = useRelayStore((s) => s.openFilesAt)\n const terminal = workspace.status === 'cleaned' || workspace.status === 'merged' || workspace.status === 'abandoned'\n const disabled = terminal || workspace.status === 'cleanup_requested'\n const openPath = workspace.worktreePath || workspace.sourceCwd || workspace.repoRoot\n // Already-landed work (squash/cherry-pick) has nothing left to merge — a merge\n // would open a duplicate/no-op PR, so disable the button.\n const gitState = useRelayStore((s) => s.workspaceGitState[workspace.id])\n const landed = !!gitState && gitState.available !== false && gitState.landed === true\n const mergeable = workspace.mode === 'isolated' && Boolean(workspace.worktreePath) && MERGEABLE_STATUSES.has(workspace.status) && !landed\n\n // Refresh the preview so the confirm dialog states the strategy/outcome, then\n // dispatch the real merge command.\n async function merge() {\n await fetchWorkspaceMergePreview(workspace.id)\n await workspaceAction(workspace.id, 'merge')\n }\n\n return (\n <div className=\"flex flex-wrap justify-end gap-1.5\">\n <Button size=\"icon-sm\" variant=\"ghost\" title={expanded ? 'Hide details' : 'Show diff & timeline'} onClick={onToggleDetails}>\n {expanded ? <ChevronDown className=\"h-3.5 w-3.5\" /> : <ChevronRight className=\"h-3.5 w-3.5\" />}\n </Button>\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n title=\"Open workspace\"\n disabled={!openPath || workspace.status === 'cleaned'}\n onClick={() => void openFilesAt({ path: openPath })}\n >\n <FolderOpen className=\"h-3.5 w-3.5\" />\n </Button>\n <CopyButton value={openPath} label=\"Copy path\" copiedLabel=\"Copied path\" size=\"icon-sm\" variant=\"ghost\" disabled={!openPath} />\n <Button size=\"icon-sm\" variant=\"outline\" title=\"Mark ready\" disabled={disabled || workspace.status === 'ready'} onClick={() => void workspaceAction(workspace.id, 'ready')}>\n <Check className=\"h-3.5 w-3.5\" />\n </Button>\n <Button size=\"icon-sm\" variant=\"outline\" title=\"Request review\" disabled={disabled || workspace.status === 'review_requested'} onClick={() => void workspaceAction(workspace.id, 'request-review')}>\n <Eye className=\"h-3.5 w-3.5\" />\n </Button>\n <Button size=\"icon-sm\" variant=\"outline\" title=\"Mark merge planned\" disabled={disabled || workspace.status === 'merge_planned'} onClick={() => void workspaceAction(workspace.id, 'merge-plan')}>\n <Flag className=\"h-3.5 w-3.5\" />\n </Button>\n <Button size=\"icon-sm\" variant=\"default\" title={landed ? 'Already merged into base — nothing to land' : 'Merge & land work'} disabled={!mergeable} onClick={() => void merge()}>\n <GitMerge className=\"h-3.5 w-3.5\" />\n </Button>\n <Button size=\"icon-sm\" variant=\"outline\" title=\"Request cleanup (removes the worktree on the host)\" disabled={workspace.status === 'cleaned' || workspace.status === 'cleanup_requested'} onClick={() => void workspaceAction(workspace.id, 'cleanup')}>\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n {terminal && (\n <Button size=\"icon-sm\" variant=\"ghost\" title=\"Purge record (clears the row, does not touch disk)\" onClick={() => void purgeWorkspace(workspace.id)}>\n <X className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n )\n}\n\n// Pre-merge conflict hint, shown next to git state when the worktree has work to\n// land. Lazily fetched from the owning host (an external sync), so an effect is\n// the right tool. Reports clean-ff vs would-conflict before the user merges.\nfunction MergePreviewHint({ workspace, unmerged }: { workspace: WorkspaceRecord; unmerged: number }) {\n const preview = useRelayStore((s) => s.workspaceMergePreview[workspace.id])\n const fetchWorkspaceMergePreview = useRelayStore((s) => s.fetchWorkspaceMergePreview)\n const eligible = unmerged > 0 && MERGEABLE_STATUSES.has(workspace.status)\n\n useEffect(() => {\n if (eligible && preview === undefined) void fetchWorkspaceMergePreview(workspace.id)\n }, [eligible, preview, workspace.id, fetchWorkspaceMergePreview])\n\n if (!eligible || preview === undefined || preview.available === false) return null\n if (preview.conflict) {\n return (\n <span className=\"flex items-center gap-0.5 text-amber-400\" title={`Merging into ${preview.baseRef || 'base'} would conflict — resolve before merging`}>\n <TriangleAlert className=\"h-3 w-3\" />conflict\n </span>\n )\n }\n if (preview.conflict === false) {\n return (\n <span className=\"flex items-center gap-0.5 text-emerald-400\" title={`Clean to merge via ${preview.strategy === 'pr' ? 'PR' : 'rebase + fast-forward'} into ${preview.baseRef || 'base'}`}>\n <Check className=\"h-3 w-3\" />{preview.strategy === 'pr' ? 'PR ready' : 'clean'}\n </span>\n )\n }\n return null\n}\n\n// Live git state of the worktree, fetched lazily from the owning host. This is\n// an external-system sync (host git over the orchestrator proxy), so an effect\n// is the right tool — it does not derive state from props.\nfunction GitState({ workspace }: { workspace: WorkspaceRecord }) {\n const now = useNow()\n const gitState = useRelayStore((s) => s.workspaceGitState[workspace.id])\n const fetchWorkspaceGitState = useRelayStore((s) => s.fetchWorkspaceGitState)\n const eligible = workspace.mode === 'isolated' && Boolean(workspace.worktreePath) && GIT_STATE_STATUSES.has(workspace.status)\n\n useEffect(() => {\n if (eligible && gitState === undefined) void fetchWorkspaceGitState(workspace.id)\n }, [eligible, gitState, workspace.id, fetchWorkspaceGitState])\n\n if (!eligible) return null\n\n const refresh = (\n <Button\n size=\"icon-sm\"\n variant=\"ghost\"\n className=\"h-5 w-5\"\n title=\"Refresh git state\"\n onClick={() => void fetchWorkspaceGitState(workspace.id)}\n >\n <RefreshCw className=\"h-3 w-3\" />\n </Button>\n )\n\n if (gitState === undefined) {\n return <div className=\"flex items-center gap-1 text-[11px] text-muted-foreground\">Loading git state…</div>\n }\n if (gitState.available === false) {\n return (\n <div className=\"flex items-center gap-1 text-[11px] text-muted-foreground\" title={gitState.reason}>\n <span>git state unavailable</span>\n {refresh}\n </div>\n )\n }\n if (gitState.missing) {\n return <div className=\"flex items-center gap-1 text-[11px] text-muted-foreground\">worktree gone {refresh}</div>\n }\n if (gitState.error) {\n return (\n <div className=\"flex items-center gap-1 text-[11px] text-red-400\" title={gitState.error}>\n <span>git error</span>\n {refresh}\n </div>\n )\n }\n\n const ahead = gitState.ahead ?? 0\n // Work squash/cherry-pick-merged into base leaves `ahead` positive but is\n // effectively landed — surface the unmerged count, not the raw ahead.\n const landed = gitState.landed === true\n const unmerged = landed ? 0 : (gitState.unmergedAhead ?? ahead)\n const behind = gitState.behind ?? 0\n const dirty = gitState.dirtyCount ?? 0\n const clean = unmerged === 0 && dirty === 0 && !landed\n const commit = gitState.lastCommit\n\n return (\n <div className=\"space-y-0.5\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5 text-[11px]\">\n {clean ? (\n <span className=\"text-muted-foreground\">no unmerged work</span>\n ) : (\n <>\n {landed ? (\n <span className=\"flex items-center gap-0.5 text-emerald-400\" title={`Work already landed in ${gitState.baseRef || 'base'} via squash/cherry-pick — safe to clean up`}>\n <Check className=\"h-3 w-3\" />landed\n </span>\n ) : (\n <span className={unmerged > 0 ? 'flex items-center text-emerald-400' : 'flex items-center text-muted-foreground'} title={ahead !== unmerged ? `${unmerged} unmerged commit(s) (${ahead} ahead of base)` : `${unmerged} commit(s) ahead of base`}>\n <ArrowUp className=\"h-3 w-3\" />{unmerged}\n </span>\n )}\n <span className={behind > 0 ? 'flex items-center text-amber-400' : 'flex items-center text-muted-foreground'} title={`${behind} commit(s) behind base`}>\n <ArrowDown className=\"h-3 w-3\" />{behind}\n </span>\n {dirty > 0 && (\n <span className=\"flex items-center text-orange-400\" title={`${dirty} uncommitted change(s)`}>\n <FilePen className=\"h-3 w-3\" />{dirty}\n </span>\n )}\n {!landed && <MergePreviewHint workspace={workspace} unmerged={unmerged} />}\n </>\n )}\n {refresh}\n </div>\n {commit && (\n <div className=\"flex min-w-0 items-center gap-1 text-[11px] text-muted-foreground\" title={`${commit.sha.slice(0, 8)} — ${commit.message}`}>\n <GitCommitHorizontal className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{commit.message || commit.sha.slice(0, 8)}</span>\n {commit.at ? <span className=\"shrink-0 opacity-70\">· {timeAgo(now, commit.at)}</span> : null}\n </div>\n )}\n </div>\n )\n}\n\n// Lifecycle timeline from the timestamps the relay already records:\n// created → ready → merged → cleaned. Surfaces history without a drawer.\nfunction WorkspaceTimeline({ workspace }: { workspace: WorkspaceRecord }) {\n const now = useNow()\n const mergedAt = typeof workspace.metadata?.mergedAt === 'number' ? (workspace.metadata.mergedAt as number) : undefined\n const steps = [\n { label: 'created', at: workspace.createdAt },\n { label: 'ready', at: workspace.readyAt },\n { label: 'merged', at: mergedAt },\n { label: 'cleaned', at: workspace.cleanedAt },\n ].filter((step): step is { label: string; at: number } => typeof step.at === 'number' && step.at > 0)\n\n return (\n <div className=\"flex flex-wrap items-center gap-x-3 gap-y-1 text-[11px] text-muted-foreground\">\n <span className=\"flex items-center gap-1 font-medium text-foreground\"><Clock className=\"h-3 w-3\" />Timeline</span>\n {steps.map((step, i) => (\n <span key={step.label} className=\"flex items-center gap-1\">\n {i > 0 && <span className=\"opacity-40\">→</span>}\n <span className=\"text-foreground\">{step.label}</span>\n <span title={new Date(step.at).toLocaleString()}>{timeAgo(now, step.at)}</span>\n </span>\n ))}\n </div>\n )\n}\n\nfunction diffLineClass(line: string): string {\n if (line.startsWith('+') && !line.startsWith('+++')) return 'text-emerald-400'\n if (line.startsWith('-') && !line.startsWith('---')) return 'text-red-400'\n if (line.startsWith('@@')) return 'text-cyan-400'\n if (line.startsWith('diff ') || line.startsWith('index ') || line.startsWith('+++') || line.startsWith('---')) return 'text-muted-foreground'\n return ''\n}\n\n// Diff of committed work against base, lazily fetched from the owning host.\nfunction WorkspaceDiffView({ workspace }: { workspace: WorkspaceRecord }) {\n const diff = useRelayStore((s) => s.workspaceDiff[workspace.id])\n const fetchWorkspaceDiff = useRelayStore((s) => s.fetchWorkspaceDiff)\n const eligible = workspace.mode === 'isolated' && Boolean(workspace.worktreePath)\n\n useEffect(() => {\n if (eligible && diff === undefined) void fetchWorkspaceDiff(workspace.id)\n }, [eligible, diff, workspace.id, fetchWorkspaceDiff])\n\n if (!eligible) return null\n if (diff === undefined) return <div className=\"text-[11px] text-muted-foreground\">Loading diff…</div>\n if (diff.available === false) return <div className=\"text-[11px] text-muted-foreground\">Diff unavailable{diff.reason ? `: ${diff.reason}` : ''}</div>\n if (diff.missing) return <div className=\"text-[11px] text-muted-foreground\">Worktree no longer on disk</div>\n if (diff.error) return <div className=\"text-[11px] text-red-400\">Diff error: {diff.error}</div>\n if (!diff.files.length) return <div className=\"text-[11px] text-muted-foreground\">No committed changes against {diff.baseRef || 'base'}</div>\n\n const refresh = (\n <Button size=\"icon-sm\" variant=\"ghost\" className=\"h-5 w-5\" title=\"Refresh diff\" onClick={() => void fetchWorkspaceDiff(workspace.id)}>\n <RefreshCw className=\"h-3 w-3\" />\n </Button>\n )\n\n return (\n <div className=\"space-y-1\">\n <div className=\"flex items-center gap-2 text-[11px] font-medium\">\n <FileDiff className=\"h-3 w-3\" />\n <span>{diff.files.length} file{diff.files.length === 1 ? '' : 's'} vs {diff.baseRef || 'base'}</span>\n {refresh}\n </div>\n <ul className=\"space-y-0.5 text-[11px]\">\n {diff.files.map((file) => (\n <li key={file.path} className=\"flex items-center gap-2 font-mono\">\n <span className=\"truncate\" title={file.path}>{file.path}</span>\n {file.binary ? (\n <span className=\"shrink-0 text-muted-foreground\">binary</span>\n ) : (\n <span className=\"shrink-0\">\n <span className=\"text-emerald-400\">+{file.additions ?? 0}</span>{' '}\n <span className=\"text-red-400\">−{file.deletions ?? 0}</span>\n </span>\n )}\n </li>\n ))}\n </ul>\n {diff.patch && (\n <pre className=\"max-h-80 overflow-auto rounded border border-border bg-muted/30 p-2 text-[10.5px] leading-relaxed\">\n {diff.patch.split('\\n').map((line, i) => (\n <div key={i} className={diffLineClass(line)}>{line || ' '}</div>\n ))}\n {diff.truncated && <div className=\"mt-1 text-muted-foreground\">… patch truncated</div>}\n </pre>\n )}\n </div>\n )\n}\n\nfunction WorkspaceDetails({ workspace }: { workspace: WorkspaceRecord }) {\n return (\n <div className=\"space-y-3 border-t border-dashed border-border bg-muted/20 px-3 py-3\">\n <WorkspaceTimeline workspace={workspace} />\n <WorkspaceDiffView workspace={workspace} />\n </div>\n )\n}\n\n// Worktrees on disk with no live workspace row — reclaimable in one click.\nfunction OrphanPanel() {\n const orphans = useRelayStore((s) => s.workspaceOrphans)\n const fetchWorkspaceOrphans = useRelayStore((s) => s.fetchWorkspaceOrphans)\n const reclaimWorkspaceOrphan = useRelayStore((s) => s.reclaimWorkspaceOrphan)\n\n useEffect(() => {\n void fetchWorkspaceOrphans()\n }, [fetchWorkspaceOrphans])\n\n if (!orphans.length) return null\n\n return (\n <Card className=\"border-amber-500/30\">\n <CardHeader className=\"px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <PackageOpen className=\"h-4 w-4 text-amber-400\" />\n <CardTitle className=\"text-sm font-medium\">Orphaned worktrees</CardTitle>\n <Badge variant=\"outline\" className=\"border-amber-500/30 text-amber-400 text-[10px]\">{orphans.length}</Badge>\n <Button size=\"icon-sm\" variant=\"ghost\" className=\"ml-auto h-6 w-6\" title=\"Rescan\" onClick={() => void fetchWorkspaceOrphans()}>\n <RefreshCw className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n <p className=\"mt-1 text-xs text-muted-foreground\">Agent worktrees on disk with no live workspace. Reclaim removes them from the host.</p>\n </CardHeader>\n <CardContent className=\"p-0\">\n {orphans.map((orphan) => (\n <div key={orphan.worktreePath} className=\"flex items-center gap-3 border-t border-border px-4 py-2 text-xs\">\n <GitBranch className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"truncate font-medium\" title={orphan.branch}>{orphan.branch || '(detached)'}</span>\n <span className=\"truncate font-mono text-muted-foreground\" title={orphan.worktreePath}>{shortPath(orphan.worktreePath)}</span>\n {orphan.hadTerminalRow && <Badge variant=\"outline\" className=\"text-[10px]\">cleanup failed</Badge>}\n <Button size=\"sm\" variant=\"outline\" className=\"ml-auto h-7 text-xs\" onClick={() => void reclaimWorkspaceOrphan(orphan)}>\n <ArchiveRestore className=\"mr-1 h-3.5 w-3.5\" />Reclaim\n </Button>\n </div>\n ))}\n </CardContent>\n </Card>\n )\n}\n\n// A `pr`-strategy merge lands as an opened PR, not a local fast-forward, so the\n// outcome only shows up here — surface the PR link and any error the orchestrator\n// returned (which the command layer keeps in result even when status=succeeded).\nfunction prLabel(url: string): string {\n const match = url.match(/\\/pull\\/(\\d+)/)\n return match ? `PR #${match[1]}` : 'View PR'\n}\n\nfunction MergeOutcome({ workspace }: { workspace: WorkspaceRecord }) {\n const result = workspace.metadata?.mergeResult as { prUrl?: string; error?: string } | undefined\n const prUrl = result?.prUrl\n const error = result?.error || (workspace.metadata?.mergeError as string | undefined)\n if (!prUrl && !error) return null\n return (\n <>\n {prUrl && (\n <a\n href={prUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n title={prUrl}\n className=\"inline-flex items-center gap-0.5 rounded border border-violet-500/30 px-1.5 py-0 text-[10px] text-violet-400 hover:text-violet-300\"\n >\n <GitMerge className=\"h-2.5 w-2.5\" />{prLabel(prUrl)}\n </a>\n )}\n {error && (\n <Badge variant=\"outline\" className=\"max-w-[16rem] border-amber-500/30 text-amber-400 text-[10px]\" title={error}>\n <TriangleAlert className=\"mr-0.5 h-2.5 w-2.5 shrink-0\" /><span className=\"truncate\">merge: {error}</span>\n </Badge>\n )}\n </>\n )\n}\n\nfunction WorkspaceRow({ workspace }: { workspace: WorkspaceRecord }) {\n const now = useNow()\n const [expanded, setExpanded] = useState(false)\n const agentsById = useRelayStore((s) => s.agentsById)\n const focused = useRelayStore((s) => s.workspaceFocusId === workspace.id)\n const owner = workspace.ownerAgentId ? agentsById[workspace.ownerAgentId] : undefined\n const steward = workspace.stewardAgentId ? agentsById[workspace.stewardAgentId] : undefined\n const path = workspace.worktreePath || workspace.sourceCwd || workspace.repoRoot\n const rowRef = useRef<HTMLDivElement>(null)\n\n // Click-through landing (#236): scroll the targeted row into view once it mounts.\n useEffect(() => {\n if (focused) rowRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' })\n }, [focused])\n\n return (\n <div ref={rowRef} className={`border-t border-border ${focused ? 'bg-primary/5 ring-1 ring-inset ring-primary/40' : ''}`}>\n <div className=\"grid gap-3 px-3 py-3 text-sm lg:grid-cols-[minmax(180px,1.2fr)_minmax(220px,1.5fr)_minmax(160px,1fr)_minmax(170px,auto)]\">\n <div className=\"min-w-0 space-y-1\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <GitBranch className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"truncate font-medium\" title={workspace.branch || workspace.id}>{workspace.branch || workspace.id}</span>\n </div>\n <div className=\"flex flex-wrap gap-1\">\n <Badge variant=\"outline\" className={`text-[10px] ${workspace.mode === 'isolated' ? 'border-sky-500/30 text-sky-400' : 'border-zinc-500/30 text-zinc-400'}`}>\n {workspace.mode}\n </Badge>\n {workspace.requestedMode && workspace.requestedMode !== workspace.mode && (\n <Badge variant=\"outline\" className=\"text-[10px]\">requested {workspace.requestedMode}</Badge>\n )}\n <Badge variant=\"outline\" className={`text-[10px] ${statusTone(workspace.status)}`}>{STATUS_LABEL[workspace.status] || workspace.status}</Badge>\n <MergeOutcome workspace={workspace} />\n </div>\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <div className=\"truncate font-mono text-xs\" title={path}>{shortPath(path)}</div>\n <div className=\"truncate text-xs text-muted-foreground\" title={workspace.sourceCwd}>{workspace.sourceCwd}</div>\n <GitState workspace={workspace} />\n </div>\n\n <div className=\"grid grid-cols-[4.5rem_minmax(0,1fr)] gap-x-2 gap-y-1 text-xs\">\n <span className=\"text-muted-foreground\">Owner</span>\n <span className=\"truncate\" title={workspace.ownerAgentId}>{agentLabel(owner, workspace.ownerPolicyName || workspace.ownerAgentId)}</span>\n <span className=\"text-muted-foreground\">Steward</span>\n <span className=\"truncate\" title={workspace.stewardAgentId}>{agentLabel(steward, workspace.stewardAgentId)}</span>\n <span className=\"text-muted-foreground\">Updated</span>\n <span>{timeAgo(now, workspace.updatedAt)}</span>\n {workspace.baseRef && (\n <>\n <span className=\"text-muted-foreground\">Base</span>\n <span className=\"truncate\" title={workspace.baseSha}>{workspace.baseRef}</span>\n </>\n )}\n </div>\n\n <WorkspaceActions workspace={workspace} expanded={expanded} onToggleDetails={() => setExpanded((value) => !value)} />\n </div>\n {expanded && <WorkspaceDetails workspace={workspace} />}\n </div>\n )\n}\n\nfunction RepoGroup({ repoRoot, workspaces }: { repoRoot: string; workspaces: WorkspaceRecord[] }) {\n const liveCount = workspaces.filter((item) => LIVE_STATUSES.has(item.status)).length\n const readyCount = workspaces.filter((item) => item.status === 'ready' || item.status === 'review_requested' || item.status === 'merge_planned').length\n const conflictCount = workspaces.filter((item) => item.status === 'conflict').length\n\n return (\n <Card>\n <CardHeader className=\"px-4 py-3\">\n <div className=\"flex min-w-0 items-start gap-3\">\n <div className=\"min-w-0 flex-1\">\n <CardTitle className=\"truncate text-sm font-medium\" title={repoRoot}>{repoRoot}</CardTitle>\n <div className=\"mt-1 flex flex-wrap gap-1.5\">\n <Badge variant=\"outline\" className=\"text-[10px]\">{workspaces.length} total</Badge>\n <Badge variant=\"outline\" className=\"text-[10px]\">{liveCount} live</Badge>\n {readyCount > 0 && <Badge variant=\"outline\" className=\"border-emerald-500/20 text-emerald-400 text-[10px]\">{readyCount} merge signal</Badge>}\n {conflictCount > 0 && <Badge variant=\"outline\" className=\"border-red-500/20 text-red-400 text-[10px]\">{conflictCount} conflict</Badge>}\n </div>\n </div>\n </div>\n </CardHeader>\n <CardContent className=\"p-0\">\n {workspaces.map((workspace) => (\n <WorkspaceRow key={workspace.id} workspace={workspace} />\n ))}\n </CardContent>\n </Card>\n )\n}\n\nexport function WorkspacesView() {\n const [filter, setFilter] = useState<WorkspaceFilter>('active')\n const workspaces = useRelayStore((s) => s.workspaces)\n const set = useRelayStore((s) => s.set)\n const workspaceFocusId = useRelayStore((s) => s.workspaceFocusId)\n\n // Badge click-through (#236): a focused workspace may be in any state, so widen\n // the filter to 'all' to guarantee its row renders. Clear the focus when leaving\n // the panel so the highlight doesn't linger on the next visit.\n useEffect(() => {\n if (workspaceFocusId) setFilter('all')\n }, [workspaceFocusId])\n useEffect(() => () => { set({ workspaceFocusId: null }) }, [set])\n\n const visibleWorkspaces = useMemo(() => filterWorkspaces(workspaces, filter), [workspaces, filter])\n const grouped = useMemo(() => groupWorkspaces(visibleWorkspaces), [visibleWorkspaces])\n const liveCount = workspaces.filter((item) => LIVE_STATUSES.has(item.status)).length\n const isolatedCount = workspaces.filter((item) => item.mode === 'isolated').length\n const readyCount = workspaces.filter((item) => item.status === 'ready' || item.status === 'review_requested' || item.status === 'merge_planned').length\n const conflictCount = workspaces.filter((item) => item.status === 'conflict').length\n const doneCount = workspaces.filter((item) => TERMINAL_STATUSES.has(item.status)).length\n const activeCount = workspaces.length - doneCount\n const filters: Array<{ key: WorkspaceFilter; label: string; count: number }> = [\n { key: 'active', label: 'Active', count: activeCount },\n { key: 'cleaned', label: 'Done', count: doneCount },\n { key: 'all', label: 'All', count: workspaces.length },\n ]\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Workspaces</h1>\n <p className=\"text-sm text-muted-foreground\">Agent worktrees, ownership, and merge readiness.</p>\n </div>\n <div className=\"ml-auto flex flex-wrap gap-1.5\">\n <Badge variant=\"outline\">{isolatedCount} isolated</Badge>\n <Badge variant=\"outline\">{liveCount} live</Badge>\n <Badge variant=\"outline\">{readyCount} ready</Badge>\n {conflictCount > 0 && <Badge variant=\"outline\" className=\"border-red-500/20 text-red-400\">{conflictCount} conflict</Badge>}\n </div>\n </div>\n\n <OrphanPanel />\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <div className=\"flex rounded-md border border-border bg-card p-1\">\n {filters.map((item) => (\n <Button\n key={item.key}\n size=\"sm\"\n variant={filter === item.key ? 'secondary' : 'ghost'}\n className=\"h-7 text-xs\"\n onClick={() => setFilter(item.key)}\n >\n {item.label}\n <span className=\"ml-1 text-muted-foreground\">{item.count}</span>\n </Button>\n ))}\n </div>\n </div>\n\n {grouped.length === 0 ? (\n <div className=\"rounded-md border border-border px-3 py-12 text-center text-sm text-muted-foreground\">\n No {filter === 'all' ? '' : filter} workspaces\n </div>\n ) : (\n <div className=\"space-y-3\">\n {grouped.map((group) => (\n <RepoGroup key={group.repoRoot} repoRoot={group.repoRoot} workspaces={group.workspaces} />\n ))}\n </div>\n )}\n </div>\n )\n}\n"],"mappings":"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"}