@hotmeshio/long-tail 0.8.0 → 0.8.2

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 (256) hide show
  1. package/dashboard/dist/assets/{AdminDashboard-9JLg41f-.js → AdminDashboard-Nvja-XIJ.js} +2 -2
  2. package/dashboard/dist/assets/{AdminDashboard-9JLg41f-.js.map → AdminDashboard-Nvja-XIJ.js.map} +1 -1
  3. package/dashboard/dist/assets/AgentConfigPage-Sf2god7q.js +16 -0
  4. package/dashboard/dist/assets/AgentConfigPage-Sf2god7q.js.map +1 -0
  5. package/dashboard/dist/assets/AgentDetailPage-DtgDeZJR.js +4 -0
  6. package/dashboard/dist/assets/AgentDetailPage-DtgDeZJR.js.map +1 -0
  7. package/dashboard/dist/assets/AgentsPage-C6zqP_xC.js +2 -0
  8. package/dashboard/dist/assets/AgentsPage-C6zqP_xC.js.map +1 -0
  9. package/dashboard/dist/assets/{AvailableEscalationsPage-CoZ4Lufr.js → AvailableEscalationsPage-D61kC7Is.js} +2 -2
  10. package/dashboard/dist/assets/{AvailableEscalationsPage-CoZ4Lufr.js.map → AvailableEscalationsPage-D61kC7Is.js.map} +1 -1
  11. package/dashboard/dist/assets/{BotPicker-xGUCxJo-.js → BotPicker-ChgljKHj.js} +2 -2
  12. package/dashboard/dist/assets/{BotPicker-xGUCxJo-.js.map → BotPicker-ChgljKHj.js.map} +1 -1
  13. package/dashboard/dist/assets/CapabilitiesPage-DeybKoZM.js +2 -0
  14. package/dashboard/dist/assets/CapabilitiesPage-DeybKoZM.js.map +1 -0
  15. package/dashboard/dist/assets/{CollapsibleSection-CXMPecjj.js → CollapsibleSection-BPiTuPBk.js} +2 -2
  16. package/dashboard/dist/assets/{CollapsibleSection-CXMPecjj.js.map → CollapsibleSection-BPiTuPBk.js.map} +1 -1
  17. package/dashboard/dist/assets/CredentialsPage-DXOcPWtd.js +2 -0
  18. package/dashboard/dist/assets/CredentialsPage-DXOcPWtd.js.map +1 -0
  19. package/dashboard/dist/assets/CronLabel-D3411N8x.js +2 -0
  20. package/dashboard/dist/assets/CronLabel-D3411N8x.js.map +1 -0
  21. package/dashboard/dist/assets/{CustomDurationPicker-id6Tq64R.js → CustomDurationPicker-WG2tPSbV.js} +2 -2
  22. package/dashboard/dist/assets/{CustomDurationPicker-id6Tq64R.js.map → CustomDurationPicker-WG2tPSbV.js.map} +1 -1
  23. package/dashboard/dist/assets/{DropZone-CZDmNBn-.js → DropZone-SgiK1WOl.js} +2 -2
  24. package/dashboard/dist/assets/{DropZone-CZDmNBn-.js.map → DropZone-SgiK1WOl.js.map} +1 -1
  25. package/dashboard/dist/assets/{ElapsedCell-B8TrnyT5.js → ElapsedCell-BFWEGSD7.js} +2 -2
  26. package/dashboard/dist/assets/{ElapsedCell-B8TrnyT5.js.map → ElapsedCell-BFWEGSD7.js.map} +1 -1
  27. package/dashboard/dist/assets/EscalationSchemaPage-D2Y5Yeqn.js +9 -0
  28. package/dashboard/dist/assets/EscalationSchemaPage-D2Y5Yeqn.js.map +1 -0
  29. package/dashboard/dist/assets/{EscalationsOverview-CjLyujJ3.js → EscalationsOverview-VlLcX2YM.js} +2 -2
  30. package/dashboard/dist/assets/{EscalationsOverview-CjLyujJ3.js.map → EscalationsOverview-VlLcX2YM.js.map} +1 -1
  31. package/dashboard/dist/assets/EventTable-3MJw14jp.js +2 -0
  32. package/dashboard/dist/assets/EventTable-3MJw14jp.js.map +1 -0
  33. package/dashboard/dist/assets/FilterBar-B4Mk2PvT.js +2 -0
  34. package/dashboard/dist/assets/FilterBar-B4Mk2PvT.js.map +1 -0
  35. package/dashboard/dist/assets/GraphInvokePage-QaUUrPnh.js +2 -0
  36. package/dashboard/dist/assets/GraphInvokePage-QaUUrPnh.js.map +1 -0
  37. package/dashboard/dist/assets/HomePage-Br0A3iOp.js +2 -0
  38. package/dashboard/dist/assets/HomePage-Br0A3iOp.js.map +1 -0
  39. package/dashboard/dist/assets/{ListToolbar--FkPpYDY.js → ListToolbar-d4MGQefV.js} +2 -2
  40. package/dashboard/dist/assets/{ListToolbar--FkPpYDY.js.map → ListToolbar-d4MGQefV.js.map} +1 -1
  41. package/dashboard/dist/assets/{McpOverview-CtAFXv-T.js → McpOverview-CUzJD5Z5.js} +2 -2
  42. package/dashboard/dist/assets/{McpOverview-CtAFXv-T.js.map → McpOverview-CUzJD5Z5.js.map} +1 -1
  43. package/dashboard/dist/assets/McpQueryDetailPage-pYSZmV3M.js +5 -0
  44. package/dashboard/dist/assets/McpQueryDetailPage-pYSZmV3M.js.map +1 -0
  45. package/dashboard/dist/assets/McpQueryPage-CA5C5dss.js +2 -0
  46. package/dashboard/dist/assets/McpQueryPage-CA5C5dss.js.map +1 -0
  47. package/dashboard/dist/assets/{McpRunDetailPage-BYIxBcA7.js → McpRunDetailPage-CrRkXwAe.js} +2 -2
  48. package/dashboard/dist/assets/{McpRunDetailPage-BYIxBcA7.js.map → McpRunDetailPage-CrRkXwAe.js.map} +1 -1
  49. package/dashboard/dist/assets/McpRunsPage-BqRBDbkn.js +2 -0
  50. package/dashboard/dist/assets/McpRunsPage-BqRBDbkn.js.map +1 -0
  51. package/dashboard/dist/assets/{NamespacePill-DlqBTvFR.js → NamespacePill-SErKwgkb.js} +2 -2
  52. package/dashboard/dist/assets/{NamespacePill-DlqBTvFR.js.map → NamespacePill-SErKwgkb.js.map} +1 -1
  53. package/dashboard/dist/assets/OperationsPage--uVJxzmP.js +2 -0
  54. package/dashboard/dist/assets/OperationsPage--uVJxzmP.js.map +1 -0
  55. package/dashboard/dist/assets/{OperatorDashboard-DMQwodfo.js → OperatorDashboard-D-UMrTqI.js} +2 -2
  56. package/dashboard/dist/assets/{OperatorDashboard-DMQwodfo.js.map → OperatorDashboard-D-UMrTqI.js.map} +1 -1
  57. package/dashboard/dist/assets/{PageHeader-CFta2VaS.js → PageHeader-DJo7yMUR.js} +2 -2
  58. package/dashboard/dist/assets/{PageHeader-CFta2VaS.js.map → PageHeader-DJo7yMUR.js.map} +1 -1
  59. package/dashboard/dist/assets/{PageHeaderWithStats-CcVAji-7.js → PageHeaderWithStats-W3akV6nB.js} +2 -2
  60. package/dashboard/dist/assets/{PageHeaderWithStats-CcVAji-7.js.map → PageHeaderWithStats-W3akV6nB.js.map} +1 -1
  61. package/dashboard/dist/assets/ProcessDetailPage-BV6D_wuR.js +2 -0
  62. package/dashboard/dist/assets/ProcessDetailPage-BV6D_wuR.js.map +1 -0
  63. package/dashboard/dist/assets/{ProcessesListPage-BVtkWVLY.js → ProcessesListPage-BAalEHpx.js} +2 -2
  64. package/dashboard/dist/assets/{ProcessesListPage-BVtkWVLY.js.map → ProcessesListPage-BAalEHpx.js.map} +1 -1
  65. package/dashboard/dist/assets/RoleDetailPage-ClE7rUoo.js +11 -0
  66. package/dashboard/dist/assets/RoleDetailPage-ClE7rUoo.js.map +1 -0
  67. package/dashboard/dist/assets/RolePill-DHWixsQR.js +2 -0
  68. package/dashboard/dist/assets/RolePill-DHWixsQR.js.map +1 -0
  69. package/dashboard/dist/assets/RolesPage-DMsgZioQ.js +2 -0
  70. package/dashboard/dist/assets/RolesPage-DMsgZioQ.js.map +1 -0
  71. package/dashboard/dist/assets/{RunAsSelector-Cc1i017Z.js → RunAsSelector-VCnEYIwj.js} +2 -2
  72. package/dashboard/dist/assets/{RunAsSelector-Cc1i017Z.js.map → RunAsSelector-VCnEYIwj.js.map} +1 -1
  73. package/dashboard/dist/assets/StatCard-DrdlUeQz.js +2 -0
  74. package/dashboard/dist/assets/StatCard-DrdlUeQz.js.map +1 -0
  75. package/dashboard/dist/assets/{StatusBadge-D9MeQHrh.js → StatusBadge-DZ9137bI.js} +2 -2
  76. package/dashboard/dist/assets/{StatusBadge-D9MeQHrh.js.map → StatusBadge-DZ9137bI.js.map} +1 -1
  77. package/dashboard/dist/assets/{StickyPagination-GQKFFTjL.js → StickyPagination-3eCY2-_V.js} +2 -2
  78. package/dashboard/dist/assets/{StickyPagination-GQKFFTjL.js.map → StickyPagination-3eCY2-_V.js.map} +1 -1
  79. package/dashboard/dist/assets/{StreamMessageDetail-BYzfjWe_.js → StreamMessageDetail-70kDFH4o.js} +2 -2
  80. package/dashboard/dist/assets/StreamMessageDetail-70kDFH4o.js.map +1 -0
  81. package/dashboard/dist/assets/{SwimlaneTimeline-DLVmRrd-.js → SwimlaneTimeline-BOXRit6t.js} +2 -2
  82. package/dashboard/dist/assets/SwimlaneTimeline-BOXRit6t.js.map +1 -0
  83. package/dashboard/dist/assets/{TagInput-CQg-TrV9.js → TagInput-CGGC3DTR.js} +2 -2
  84. package/dashboard/dist/assets/{TagInput-CQg-TrV9.js.map → TagInput-CGGC3DTR.js.map} +1 -1
  85. package/dashboard/dist/assets/{TaskDetailPage-HzQpzp6D.js → TaskDetailPage-YxGQE9Qg.js} +2 -2
  86. package/dashboard/dist/assets/{TaskDetailPage-HzQpzp6D.js.map → TaskDetailPage-YxGQE9Qg.js.map} +1 -1
  87. package/dashboard/dist/assets/{TaskQueuePill-DyvtL8X4.js → TaskQueuePill-D6omQJNY.js} +2 -2
  88. package/dashboard/dist/assets/{TaskQueuePill-DyvtL8X4.js.map → TaskQueuePill-D6omQJNY.js.map} +1 -1
  89. package/dashboard/dist/assets/{TasksListPage-DpqevgTz.js → TasksListPage-DuLJQN7Q.js} +2 -2
  90. package/dashboard/dist/assets/{TasksListPage-DpqevgTz.js.map → TasksListPage-DuLJQN7Q.js.map} +1 -1
  91. package/dashboard/dist/assets/{TimeAgo-CftB8aJE.js → TimeAgo-dnc1ZjKc.js} +2 -2
  92. package/dashboard/dist/assets/{TimeAgo-CftB8aJE.js.map → TimeAgo-dnc1ZjKc.js.map} +1 -1
  93. package/dashboard/dist/assets/{TimestampCell-BSKj1jqT.js → TimestampCell-CDR6cTyq.js} +2 -2
  94. package/dashboard/dist/assets/{TimestampCell-BSKj1jqT.js.map → TimestampCell-CDR6cTyq.js.map} +1 -1
  95. package/dashboard/dist/assets/{ToolPill-miuRcj1Q.js → ToolPill-BW0iRwZu.js} +2 -2
  96. package/dashboard/dist/assets/{ToolPill-miuRcj1Q.js.map → ToolPill-BW0iRwZu.js.map} +1 -1
  97. package/dashboard/dist/assets/{ToolTestPanel-DVQICZUQ.js → ToolTestPanel-CfwGdRdz.js} +2 -2
  98. package/dashboard/dist/assets/{ToolTestPanel-DVQICZUQ.js.map → ToolTestPanel-CfwGdRdz.js.map} +1 -1
  99. package/dashboard/dist/assets/TopicDetailPage-f2qaeGFz.js +9 -0
  100. package/dashboard/dist/assets/TopicDetailPage-f2qaeGFz.js.map +1 -0
  101. package/dashboard/dist/assets/TopicsPage-CwYdVmyK.js +2 -0
  102. package/dashboard/dist/assets/TopicsPage-CwYdVmyK.js.map +1 -0
  103. package/dashboard/dist/assets/{UserName-Ce9gvlT5.js → UserName-CRE7EZPU.js} +2 -2
  104. package/dashboard/dist/assets/{UserName-Ce9gvlT5.js.map → UserName-CRE7EZPU.js.map} +1 -1
  105. package/dashboard/dist/assets/{WorkflowExecutionPage-BI9NzeaH.js → WorkflowExecutionPage-BjNBu-Zt.js} +2 -2
  106. package/dashboard/dist/assets/{WorkflowExecutionPage-BI9NzeaH.js.map → WorkflowExecutionPage-BjNBu-Zt.js.map} +1 -1
  107. package/dashboard/dist/assets/WorkflowPill-BtNBSplz.js +2 -0
  108. package/dashboard/dist/assets/WorkflowPill-BtNBSplz.js.map +1 -0
  109. package/dashboard/dist/assets/WorkflowsDashboard-DfpvbzNt.js +2 -0
  110. package/dashboard/dist/assets/WorkflowsDashboard-DfpvbzNt.js.map +1 -0
  111. package/dashboard/dist/assets/{WorkflowsOverview-CjBWlwlH.js → WorkflowsOverview-BwD2lQwj.js} +2 -2
  112. package/dashboard/dist/assets/{WorkflowsOverview-CjBWlwlH.js.map → WorkflowsOverview-BwD2lQwj.js.map} +1 -1
  113. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Ds5o1UK9.js → YamlWorkflowDetailPage-BhHb7j2s.js} +3 -3
  114. package/dashboard/dist/assets/{YamlWorkflowDetailPage-Ds5o1UK9.js.map → YamlWorkflowDetailPage-BhHb7j2s.js.map} +1 -1
  115. package/dashboard/dist/assets/YamlWorkflowsPage-SBRpY2dI.js +2 -0
  116. package/dashboard/dist/assets/YamlWorkflowsPage-SBRpY2dI.js.map +1 -0
  117. package/dashboard/dist/assets/{agents-A1U43853.js → agents-VbkdqWCr.js} +2 -2
  118. package/dashboard/dist/assets/{agents-A1U43853.js.map → agents-VbkdqWCr.js.map} +1 -1
  119. package/dashboard/dist/assets/{bots-CyzN6Uxi.js → bots-CsgYcYU_.js} +2 -2
  120. package/dashboard/dist/assets/{bots-CyzN6Uxi.js.map → bots-CsgYcYU_.js.map} +1 -1
  121. package/dashboard/dist/assets/{capabilities-BE1X5FVI.js → capabilities-CMhFyoDl.js} +2 -2
  122. package/dashboard/dist/assets/{capabilities-BE1X5FVI.js.map → capabilities-CMhFyoDl.js.map} +1 -1
  123. package/dashboard/dist/assets/{controlplane-BrwK_MT8.js → controlplane-BstXtPbV.js} +2 -2
  124. package/dashboard/dist/assets/{controlplane-BrwK_MT8.js.map → controlplane-BstXtPbV.js.map} +1 -1
  125. package/dashboard/dist/assets/{escalation-DDdt7UdU.js → escalation-C0BNAeIG.js} +2 -2
  126. package/dashboard/dist/assets/{escalation-DDdt7UdU.js.map → escalation-C0BNAeIG.js.map} +1 -1
  127. package/dashboard/dist/assets/escalation-columns-DajPgfuV.js +2 -0
  128. package/dashboard/dist/assets/escalation-columns-DajPgfuV.js.map +1 -0
  129. package/dashboard/dist/assets/index-BWLVqWLU.js +2 -0
  130. package/dashboard/dist/assets/index-BWLVqWLU.js.map +1 -0
  131. package/dashboard/dist/assets/index-BY5m8rhE.js +2 -0
  132. package/dashboard/dist/assets/index-BY5m8rhE.js.map +1 -0
  133. package/dashboard/dist/assets/{index-CGUBekEU.js → index-BYf0oNSQ.js} +2 -2
  134. package/dashboard/dist/assets/{index-CGUBekEU.js.map → index-BYf0oNSQ.js.map} +1 -1
  135. package/dashboard/dist/assets/index-BcaQ_hCz.js +9 -0
  136. package/dashboard/dist/assets/index-BcaQ_hCz.js.map +1 -0
  137. package/dashboard/dist/assets/index-BdqKh0UK.css +1 -0
  138. package/dashboard/dist/assets/{index-CKXSKsVZ.js → index-C8k3Z2su.js} +22 -22
  139. package/dashboard/dist/assets/index-C8k3Z2su.js.map +1 -0
  140. package/dashboard/dist/assets/index-CSixdp5W.js +2 -0
  141. package/dashboard/dist/assets/index-CSixdp5W.js.map +1 -0
  142. package/dashboard/dist/assets/{index-BNWKksZ6.js → index-CXnSqSFH.js} +2 -2
  143. package/dashboard/dist/assets/{index-BNWKksZ6.js.map → index-CXnSqSFH.js.map} +1 -1
  144. package/dashboard/dist/assets/{index-BtrNxebh.js → index-CaSMWhLU.js} +2 -2
  145. package/dashboard/dist/assets/{index-BtrNxebh.js.map → index-CaSMWhLU.js.map} +1 -1
  146. package/dashboard/dist/assets/index-Cl1vY8Lg.js +2 -0
  147. package/dashboard/dist/assets/index-Cl1vY8Lg.js.map +1 -0
  148. package/dashboard/dist/assets/{index-NnGsWGNS.js → index-CvFQtPWA.js} +2 -2
  149. package/dashboard/dist/assets/{index-NnGsWGNS.js.map → index-CvFQtPWA.js.map} +1 -1
  150. package/dashboard/dist/assets/index-DWlPFH3T.js +6 -0
  151. package/dashboard/dist/assets/index-DWlPFH3T.js.map +1 -0
  152. package/dashboard/dist/assets/{index-C-rJQ-vB.js → index-D_6JFBiM.js} +2 -2
  153. package/dashboard/dist/assets/{index-C-rJQ-vB.js.map → index-D_6JFBiM.js.map} +1 -1
  154. package/dashboard/dist/assets/{index-D4U--3Xo.js → index-fqU_l4dC.js} +2 -2
  155. package/dashboard/dist/assets/{index-D4U--3Xo.js.map → index-fqU_l4dC.js.map} +1 -1
  156. package/dashboard/dist/assets/{knowledge-B3ZIRTeu.js → knowledge-Bskl1MbC.js} +2 -2
  157. package/dashboard/dist/assets/{knowledge-B3ZIRTeu.js.map → knowledge-Bskl1MbC.js.map} +1 -1
  158. package/dashboard/dist/assets/{mcp-BJjWiHdc.js → mcp-C_qz25AB.js} +2 -2
  159. package/dashboard/dist/assets/{mcp-BJjWiHdc.js.map → mcp-C_qz25AB.js.map} +1 -1
  160. package/dashboard/dist/assets/{mcp-query-ksjBztwq.js → mcp-query-CJx58s1A.js} +2 -2
  161. package/dashboard/dist/assets/{mcp-query-ksjBztwq.js.map → mcp-query-CJx58s1A.js.map} +1 -1
  162. package/dashboard/dist/assets/{pipelines-DT1astmP.js → pipelines-B6GzpgtG.js} +2 -2
  163. package/dashboard/dist/assets/{pipelines-DT1astmP.js.map → pipelines-B6GzpgtG.js.map} +1 -1
  164. package/dashboard/dist/assets/roles-D8lPvFgG.js +2 -0
  165. package/dashboard/dist/assets/{roles-UboiQxXT.js.map → roles-D8lPvFgG.js.map} +1 -1
  166. package/dashboard/dist/assets/tasks-BWHakSYf.js +2 -0
  167. package/dashboard/dist/assets/{tasks-aL0K8WW3.js.map → tasks-BWHakSYf.js.map} +1 -1
  168. package/dashboard/dist/assets/{topics-CZO06VJl.js → topics-0dXzPX8t.js} +2 -2
  169. package/dashboard/dist/assets/{topics-CZO06VJl.js.map → topics-0dXzPX8t.js.map} +1 -1
  170. package/dashboard/dist/assets/{useEventHooks-DlWkui_n.js → useEventHooks-Dpixlgp-.js} +2 -2
  171. package/dashboard/dist/assets/{useEventHooks-DlWkui_n.js.map → useEventHooks-Dpixlgp-.js.map} +1 -1
  172. package/dashboard/dist/assets/{useNamespace-BBzCmCIN.js → useNamespace-DQMc77ok.js} +2 -2
  173. package/dashboard/dist/assets/{useNamespace-BBzCmCIN.js.map → useNamespace-DQMc77ok.js.map} +1 -1
  174. package/dashboard/dist/assets/{useYamlActivityEvents-ZS6wRSSc.js → useYamlActivityEvents-DO5bHOVE.js} +2 -2
  175. package/dashboard/dist/assets/{useYamlActivityEvents-ZS6wRSSc.js.map → useYamlActivityEvents-DO5bHOVE.js.map} +1 -1
  176. package/dashboard/dist/assets/{users-Dzh04pRB.js → users-B_LVbnUk.js} +2 -2
  177. package/dashboard/dist/assets/{users-Dzh04pRB.js.map → users-B_LVbnUk.js.map} +1 -1
  178. package/dashboard/dist/assets/{vendor-icons-BaQqUm-e.js → vendor-icons-DOIDKgo6.js} +115 -120
  179. package/dashboard/dist/assets/{vendor-icons-BaQqUm-e.js.map → vendor-icons-DOIDKgo6.js.map} +1 -1
  180. package/dashboard/dist/assets/{workflows-BTkHs6VT.js → workflows-WmmGDAvo.js} +2 -2
  181. package/dashboard/dist/assets/{workflows-BTkHs6VT.js.map → workflows-WmmGDAvo.js.map} +1 -1
  182. package/dashboard/dist/assets/{yaml-workflows-Df8u3lgx.js → yaml-workflows-BS7KHhU1.js} +2 -2
  183. package/dashboard/dist/assets/{yaml-workflows-Df8u3lgx.js.map → yaml-workflows-BS7KHhU1.js.map} +1 -1
  184. package/dashboard/dist/index.html +3 -3
  185. package/docs/dashboard.md +58 -42
  186. package/package.json +1 -1
  187. package/dashboard/dist/assets/AgentConfigPage-D5P1hcOc.js +0 -16
  188. package/dashboard/dist/assets/AgentConfigPage-D5P1hcOc.js.map +0 -1
  189. package/dashboard/dist/assets/AgentDetailPage-DrijeAV8.js +0 -4
  190. package/dashboard/dist/assets/AgentDetailPage-DrijeAV8.js.map +0 -1
  191. package/dashboard/dist/assets/AgentsPage-BW5d0JOt.js +0 -2
  192. package/dashboard/dist/assets/AgentsPage-BW5d0JOt.js.map +0 -1
  193. package/dashboard/dist/assets/CapabilitiesPage-ChaRJiyg.js +0 -2
  194. package/dashboard/dist/assets/CapabilitiesPage-ChaRJiyg.js.map +0 -1
  195. package/dashboard/dist/assets/CredentialsPage-BbdfZh1D.js +0 -2
  196. package/dashboard/dist/assets/CredentialsPage-BbdfZh1D.js.map +0 -1
  197. package/dashboard/dist/assets/CronLabel-CJUL50eO.js +0 -2
  198. package/dashboard/dist/assets/CronLabel-CJUL50eO.js.map +0 -1
  199. package/dashboard/dist/assets/EscalationSchemaPage-C6UuZgCD.js +0 -9
  200. package/dashboard/dist/assets/EscalationSchemaPage-C6UuZgCD.js.map +0 -1
  201. package/dashboard/dist/assets/EventTable-D_rNmyGG.js +0 -2
  202. package/dashboard/dist/assets/EventTable-D_rNmyGG.js.map +0 -1
  203. package/dashboard/dist/assets/FilterBar-BQ2JGg8U.js +0 -2
  204. package/dashboard/dist/assets/FilterBar-BQ2JGg8U.js.map +0 -1
  205. package/dashboard/dist/assets/GraphInvokePage-BMyrTnI6.js +0 -2
  206. package/dashboard/dist/assets/GraphInvokePage-BMyrTnI6.js.map +0 -1
  207. package/dashboard/dist/assets/HomePage-MBv6pwk4.js +0 -2
  208. package/dashboard/dist/assets/HomePage-MBv6pwk4.js.map +0 -1
  209. package/dashboard/dist/assets/McpQueryDetailPage-5Jzz2q2g.js +0 -5
  210. package/dashboard/dist/assets/McpQueryDetailPage-5Jzz2q2g.js.map +0 -1
  211. package/dashboard/dist/assets/McpQueryPage-DveeRF5I.js +0 -2
  212. package/dashboard/dist/assets/McpQueryPage-DveeRF5I.js.map +0 -1
  213. package/dashboard/dist/assets/McpRunsPage-Cgke6ask.js +0 -2
  214. package/dashboard/dist/assets/McpRunsPage-Cgke6ask.js.map +0 -1
  215. package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js +0 -2
  216. package/dashboard/dist/assets/OperationsPage-D2i7xrAI.js.map +0 -1
  217. package/dashboard/dist/assets/ProcessDetailPage-Dodrk5-z.js +0 -2
  218. package/dashboard/dist/assets/ProcessDetailPage-Dodrk5-z.js.map +0 -1
  219. package/dashboard/dist/assets/RoleDetailPage-8NldZI49.js +0 -11
  220. package/dashboard/dist/assets/RoleDetailPage-8NldZI49.js.map +0 -1
  221. package/dashboard/dist/assets/RolePill-CXEyPMqb.js +0 -2
  222. package/dashboard/dist/assets/RolePill-CXEyPMqb.js.map +0 -1
  223. package/dashboard/dist/assets/RolesPage-BJBjtFNY.js +0 -2
  224. package/dashboard/dist/assets/RolesPage-BJBjtFNY.js.map +0 -1
  225. package/dashboard/dist/assets/StatCard-DlgF0CJC.js +0 -2
  226. package/dashboard/dist/assets/StatCard-DlgF0CJC.js.map +0 -1
  227. package/dashboard/dist/assets/StreamMessageDetail-BYzfjWe_.js.map +0 -1
  228. package/dashboard/dist/assets/SwimlaneTimeline-DLVmRrd-.js.map +0 -1
  229. package/dashboard/dist/assets/TopicDetailPage-B2LAQDEg.js +0 -9
  230. package/dashboard/dist/assets/TopicDetailPage-B2LAQDEg.js.map +0 -1
  231. package/dashboard/dist/assets/TopicsPage-SwPAnN2C.js +0 -2
  232. package/dashboard/dist/assets/TopicsPage-SwPAnN2C.js.map +0 -1
  233. package/dashboard/dist/assets/WorkflowPill-BuNkWUVM.js +0 -2
  234. package/dashboard/dist/assets/WorkflowPill-BuNkWUVM.js.map +0 -1
  235. package/dashboard/dist/assets/WorkflowsDashboard-CvWSgQdE.js +0 -2
  236. package/dashboard/dist/assets/WorkflowsDashboard-CvWSgQdE.js.map +0 -1
  237. package/dashboard/dist/assets/YamlWorkflowsPage-ChwvZS4Z.js +0 -2
  238. package/dashboard/dist/assets/YamlWorkflowsPage-ChwvZS4Z.js.map +0 -1
  239. package/dashboard/dist/assets/escalation-columns-D_zFY1zF.js +0 -2
  240. package/dashboard/dist/assets/escalation-columns-D_zFY1zF.js.map +0 -1
  241. package/dashboard/dist/assets/index-6MALVAEY.js +0 -2
  242. package/dashboard/dist/assets/index-6MALVAEY.js.map +0 -1
  243. package/dashboard/dist/assets/index-CKXSKsVZ.js.map +0 -1
  244. package/dashboard/dist/assets/index-CZ6-l8_0.css +0 -1
  245. package/dashboard/dist/assets/index-D2dDPGNk.js +0 -2
  246. package/dashboard/dist/assets/index-D2dDPGNk.js.map +0 -1
  247. package/dashboard/dist/assets/index-D4gAsCGh.js +0 -2
  248. package/dashboard/dist/assets/index-D4gAsCGh.js.map +0 -1
  249. package/dashboard/dist/assets/index-DEXouwBQ.js +0 -2
  250. package/dashboard/dist/assets/index-DEXouwBQ.js.map +0 -1
  251. package/dashboard/dist/assets/index-U27KBbTV.js +0 -9
  252. package/dashboard/dist/assets/index-U27KBbTV.js.map +0 -1
  253. package/dashboard/dist/assets/index-fwHQSJCp.js +0 -6
  254. package/dashboard/dist/assets/index-fwHQSJCp.js.map +0 -1
  255. package/dashboard/dist/assets/roles-UboiQxXT.js +0 -2
  256. package/dashboard/dist/assets/tasks-aL0K8WW3.js +0 -2
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-D4gAsCGh.js","sources":["../../src/pages/admin/controlplane/helpers.ts","../../src/pages/admin/controlplane/useMeshSelection.ts","../../src/pages/admin/controlplane/ThrottleModal.tsx","../../src/pages/admin/controlplane/EmergencyControls.tsx","../../src/pages/admin/controlplane/StreamVolumeChart.tsx","../../src/pages/admin/controlplane/QueueCard.tsx","../../src/pages/admin/controlplane/QuorumFeed.tsx","../../src/pages/admin/controlplane/EngineCluster.tsx","../../src/pages/admin/controlplane/ControlPlaneContent.tsx","../../src/pages/admin/controlplane/ControlPlanePage.tsx"],"sourcesContent":["import type { QuorumProfile } from '../../../api/controlplane';\n\nexport const DURATIONS = [\n { label: '15m', value: '15m' },\n { label: '30m', value: '30m' },\n { label: '1h', value: '1h' },\n { label: '1d', value: '1d' },\n { label: '7d', value: '7d' },\n] as const;\n\nexport type Duration = (typeof DURATIONS)[number]['value'];\n\nexport interface QuorumEvent {\n id: number;\n type: string;\n timestamp: string;\n data: Record<string, unknown>;\n}\n\nexport const EVENT_TYPE_COLORS: Record<string, string> = {\n pong: 'text-status-success',\n ping: 'text-accent',\n throttle: 'text-status-warning',\n job: 'text-purple-400',\n work: 'text-text-secondary',\n activate: 'text-status-error',\n cron: 'text-text-tertiary',\n user: 'text-text-secondary',\n};\n\n/** Human-friendly labels for quorum event types. */\nexport const EVENT_TYPE_LABELS: Record<string, string> = {\n pong: 'roll call',\n ping: 'ping',\n throttle: 'throttle',\n job: 'job',\n work: 'work',\n activate: 'activate',\n cron: 'cron',\n user: 'user',\n};\n\nexport const MAX_EVENTS = 250;\n\nexport function isWorker(p: QuorumProfile): boolean {\n return !!p.worker_topic;\n}\n\nexport function isThrottled(p: QuorumProfile): boolean {\n return typeof p.throttle === 'number' && p.throttle !== 0;\n}\n\nexport function formatThrottleHuman(ms?: number): string {\n if (ms === undefined || ms === 0) return 'Normal';\n if (ms === -1) return 'Paused';\n if (ms >= 86_400_000) return `${(ms / 86_400_000).toFixed(0)}d`;\n if (ms >= 3_600_000) return `${(ms / 3_600_000).toFixed(1)}h`;\n if (ms >= 60_000) return `${(ms / 60_000).toFixed(1)}m`;\n if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`;\n return `${ms}ms`;\n}\n\nexport function parseTimestamp(ts?: string): Date | null {\n if (!ts) return null;\n // Handle YYYYMMDDHHMMSS.mmm format (quorum timestamps)\n const match = ts.match(/^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})\\.(\\d+)$/);\n if (match) {\n const [, y, mo, d, h, mi, s, ms] = match;\n return new Date(`${y}-${mo}-${d}T${h}:${mi}:${s}.${ms}Z`);\n }\n // Fallback to standard Date parsing\n const date = new Date(ts);\n return isNaN(date.getTime()) ? null : date;\n}\n\nexport function formatUptime(inited?: string): string {\n const date = parseTimestamp(inited);\n if (!date) return '--';\n const ms = Date.now() - date.getTime();\n if (ms < 0 || isNaN(ms)) return '--';\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h}h ${m % 60}m`;\n const d = Math.floor(h / 24);\n return `${d}d ${h % 24}h`;\n}\n\nexport function formatMemory(total?: string, free?: string): string {\n if (!total || !free) return '—';\n const t = parseFloat(total);\n const f = parseFloat(free);\n if (isNaN(t) || isNaN(f)) return '—';\n return `${(t - f).toFixed(1)} / ${t.toFixed(1)} GB`;\n}\n\nexport function stripStreamPrefix(name: string): string {\n return name.replace(/^hmsh:[^:]+:x:/, '') || '(engine)';\n}\n\n/** Engine streams have no suffix after hmsh:{app}:x: */\nexport function isEngineStream(streamName: string): boolean {\n return stripStreamPrefix(streamName) === '(engine)';\n}\n\n/** Extract a human-friendly label from engine_id like \"controlplane::durable-Hxyz...\" → \"durable\" */\nexport function engineLabel(engineId: string): string {\n // Format: {source}::{name}-{guid}\n const match = engineId.match(/^([^:]+)::(.+?)-[A-Za-z0-9_]{10,}$/);\n if (match) return match[2];\n // Fallback: just truncate\n return engineId.length > 20 ? engineId.slice(0, 20) + '...' : engineId;\n}\n\n/** Extract the source/app prefix from engine_id like \"controlplane::durable-Hxyz...\" → \"controlplane\" */\nexport function engineSource(engineId: string): string {\n const match = engineId.match(/^([^:]+)::/);\n return match?.[1] || '';\n}\n\nexport type NodeFilter = 'all' | 'workers' | 'engines';\n\n/** Known quorum message types published via the bridge. */\nexport const QUORUM_CHANNELS = [\n { key: 'pong', label: 'Roll Call', description: 'Node health check responses' },\n { key: 'ping', label: 'Ping', description: 'Health check broadcasts' },\n { key: 'throttle', label: 'Throttle', description: 'Throttle commands' },\n { key: 'job', label: 'Job', description: 'Job lifecycle events' },\n { key: 'work', label: 'Work', description: 'Worker dispatch events' },\n { key: 'activate', label: 'Activate', description: 'Worker activation' },\n { key: 'cron', label: 'Cron', description: 'Cron schedule triggers' },\n { key: 'user', label: 'User', description: 'User-defined messages' },\n] as const;\n\n/** Typed throttle target with display label and API params. */\nexport interface ThrottleTarget {\n label: string;\n /** API param: topic-based throttle (queues, all engines) */\n topic?: string;\n /** API param: guid-based throttle (single engine/worker) */\n guid?: string;\n /** API param: scope — target engines only, workers only, or both */\n scope?: 'engines' | 'workers' | 'all';\n}\n\nexport const NODE_FILTER_OPTIONS = [\n { value: 'all', label: 'All Nodes' },\n { value: 'workers', label: 'Workers' },\n { value: 'engines', label: 'Engines' },\n] as const;\n\nexport function rowKey(p: QuorumProfile): string {\n return `${p.engine_id}-${p.worker_topic || 'engine'}`;\n}\n\n// ── Queue-level helpers ────────────────────────────────────────────────\n\n/** Group worker profiles by `worker_topic` (engines excluded). */\nexport function groupByQueue(profiles: QuorumProfile[]): Map<string, QuorumProfile[]> {\n const map = new Map<string, QuorumProfile[]>();\n for (const p of profiles) {\n if (!p.worker_topic) continue;\n const q = p.worker_topic;\n if (!map.has(q)) map.set(q, []);\n map.get(q)!.push(p);\n }\n return map;\n}\n\n/** Aggregate `counts` across profiles: 200 = success, 500 = error, all = total. */\nexport function sumCounts(profiles: QuorumProfile[]): { total: number; success: number; errors: number } {\n let total = 0;\n let success = 0;\n let errors = 0;\n for (const p of profiles) {\n if (!p.counts) continue;\n for (const [code, n] of Object.entries(p.counts)) {\n total += n;\n if (code === '200') success += n;\n else if (code === '500') errors += n;\n }\n }\n return { total, success, errors };\n}\n\n/** Sum `stream_depth` across profiles. */\nexport function totalPending(profiles: QuorumProfile[]): number {\n let sum = 0;\n for (const p of profiles) {\n if (typeof p.stream_depth === 'number') sum += p.stream_depth;\n }\n return sum;\n}\n\n/** Derive queue health from member profiles. */\nexport function queueHealth(profiles: QuorumProfile[]): 'healthy' | 'degraded' | 'paused' {\n if (profiles.length === 0) return 'healthy';\n const allPaused = profiles.every((p) => p.throttle === -1);\n if (allPaused) return 'paused';\n const { errors } = sumCounts(profiles);\n if (errors > 0 || profiles.some(isThrottled)) return 'degraded';\n return 'healthy';\n}\n","import { useState, useCallback, useEffect, useMemo } from 'react';\n\nimport type { QuorumProfile } from '../../../api/controlplane';\nimport { useThrottle } from '../../../api/controlplane';\nimport { isWorker, rowKey, type ThrottleTarget } from './helpers';\n\ninterface UseMeshSelectionOptions {\n activeAppId: string;\n allProfiles: QuorumProfile[];\n profiles: QuorumProfile[];\n}\n\nexport function useMeshSelection({\n activeAppId,\n allProfiles,\n profiles,\n}: UseMeshSelectionOptions) {\n const throttleMutation = useThrottle();\n\n const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set());\n const [throttleModalOpen, setThrottleModalOpen] = useState(false);\n const [throttleTargets, setThrottleTargets] = useState<ThrottleTarget[]>([]);\n\n useEffect(() => { setSelectedIds(new Set()); }, [activeAppId]);\n\n const toggleCheckbox = useCallback((profile: QuorumProfile) => {\n setSelectedIds((prev) => {\n const next = new Set(prev);\n const key = rowKey(profile);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n }, []);\n\n const toggleAll = useCallback(() => {\n if (selectedIds.size === profiles.length) {\n setSelectedIds(new Set());\n } else {\n setSelectedIds(new Set(profiles.map(rowKey)));\n }\n }, [profiles, selectedIds.size]);\n\n /**\n * Build throttle targets from checkbox selection.\n *\n * Smart grouping:\n * - All nodes selected -> no topic/guid (entire mesh)\n * - All engines selected -> topic = engine stream (all engines)\n * - All workers on a queue selected -> topic = queue (all workers on queue)\n * - Subset of a group -> individual guid targets\n */\n const selectedThrottleTargets = useMemo((): ThrottleTarget[] => {\n const selected = profiles.filter((p) => selectedIds.has(rowKey(p)));\n if (selected.length === 0) return [];\n\n // All nodes -> entire mesh\n if (selected.length === allProfiles.length) {\n return [{ label: 'Entire Mesh' }];\n }\n\n const engines = selected.filter((p) => !isWorker(p));\n const workers = selected.filter(isWorker);\n const targets: ThrottleTarget[] = [];\n\n // Engines — always guid-per-engine, scoped to engines only\n for (const e of engines) {\n targets.push({ label: `Engine ${e.engine_id}`, guid: e.engine_id, scope: 'engines' });\n }\n\n // Workers — topic targets the queue; guid targets a single instance\n const queues = new Map<string, QuorumProfile[]>();\n for (const w of workers) {\n const q = w.worker_topic!;\n if (!queues.has(q)) queues.set(q, []);\n queues.get(q)!.push(w);\n }\n for (const [queue, members] of queues) {\n const allOnQueue = allProfiles.filter((p) => p.worker_topic === queue);\n if (members.length === allOnQueue.length) {\n targets.push({ label: queue, topic: queue });\n } else {\n for (const w of members) {\n targets.push({ label: `${queue} ${w.engine_id}`, guid: w.engine_id });\n }\n }\n }\n\n return targets;\n }, [profiles, allProfiles, selectedIds]);\n\n // ── Throttle handlers ─────────────────────────────────────────\n const handleBulkThrottle = (ms: number) => {\n const targets = throttleTargets.length > 0 ? throttleTargets : selectedThrottleTargets;\n for (const t of targets) {\n throttleMutation.mutate({\n appId: activeAppId,\n throttle: ms,\n ...(t.topic ? { topic: t.topic } : {}),\n ...(t.guid ? { guid: t.guid } : {}),\n ...(t.scope ? { scope: t.scope } : {}),\n });\n }\n setThrottleModalOpen(false);\n setThrottleTargets([]);\n };\n\n const handleRowClick = (profile: QuorumProfile, scope?: 'engines' | 'workers') => {\n const label = isWorker(profile)\n ? `${profile.worker_topic} ${profile.engine_id}`\n : `Engine ${profile.engine_id}`;\n setThrottleTargets([{\n label,\n guid: profile.engine_id,\n scope: scope || (isWorker(profile) ? 'workers' : 'engines'),\n }]);\n setThrottleModalOpen(true);\n };\n\n const handleBulkThrottleOpen = () => {\n setThrottleTargets(selectedThrottleTargets);\n setThrottleModalOpen(true);\n };\n\n const handleResumeThrottle = (profile: QuorumProfile, scope?: 'engines' | 'workers') => {\n const resolvedScope = scope || (isWorker(profile) ? 'workers' : 'engines');\n throttleMutation.mutate({ appId: activeAppId, throttle: 0, guid: profile.engine_id, scope: resolvedScope });\n };\n\n const handleResumeQueue = (queueName: string) => {\n throttleMutation.mutate({ appId: activeAppId, throttle: 0, topic: queueName });\n };\n\n const handleQueueThrottle = (queueName: string) => {\n setThrottleTargets([{ label: queueName, topic: queueName }]);\n setThrottleModalOpen(true);\n };\n\n const closeThrottleModal = () => {\n setThrottleModalOpen(false);\n setThrottleTargets([]);\n };\n\n return {\n selectedIds,\n setSelectedIds,\n toggleCheckbox,\n toggleAll,\n throttleModalOpen,\n throttleTargets,\n selectedThrottleTargets,\n throttleMutation,\n handleBulkThrottle,\n handleRowClick,\n handleBulkThrottleOpen,\n handleResumeThrottle,\n handleResumeQueue,\n handleQueueThrottle,\n closeThrottleModal,\n };\n}\n","import { useState } from 'react';\nimport { Modal } from '../../../components/common/modal/Modal';\nimport type { ThrottleTarget } from './helpers';\n\ninterface ThrottleModalProps {\n open: boolean;\n onClose: () => void;\n targets: ThrottleTarget[];\n onApply: (ms: number) => void;\n isPending: boolean;\n}\n\nconst PRESETS = [\n { label: 'Resume', ms: 0 },\n { label: '0.5s', ms: 500 },\n { label: '1s', ms: 1000 },\n { label: '5s', ms: 5000 },\n { label: '30s', ms: 30000 },\n { label: 'Pause', ms: -1 },\n];\n\nfunction TargetPill({ target }: { target: ThrottleTarget }) {\n const isMesh = target.label === 'Entire Mesh';\n const isEngine = target.label === 'All Engines' || target.label.startsWith('Engine ');\n const color = isMesh\n ? 'bg-status-error/10 text-status-error'\n : isEngine\n ? 'bg-blue-500/10 text-blue-500'\n : 'bg-accent/[0.06] text-text-secondary';\n const scopeLabel = target.scope === 'engines' ? 'engine only'\n : target.scope === 'workers' ? 'worker only'\n : target.guid ? 'guid' : target.topic ? 'topic' : 'mesh';\n\n return (\n <span className={`inline-flex items-center gap-1.5 px-2 py-0.5 text-[10px] font-medium rounded-lg ${color}`}>\n {target.label}\n <span className=\"text-[8px] opacity-50\">{scopeLabel}</span>\n </span>\n );\n}\n\nexport function ThrottleModal({ open, onClose, targets, onApply, isPending }: ThrottleModalProps) {\n const [seconds, setSeconds] = useState('');\n\n return (\n <Modal open={open} onClose={onClose} title=\"Adjust Throttle\">\n <div className=\"space-y-4\">\n <div>\n <p className=\"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2\">Targets</p>\n <div className=\"flex flex-wrap gap-1.5\">\n {targets.map((t, i) => (\n <TargetPill key={t.guid || t.topic || i} target={t} />\n ))}\n </div>\n </div>\n\n <div>\n <p className=\"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2\">Presets</p>\n <div className=\"flex flex-wrap gap-2\">\n {PRESETS.map((p) => (\n <button\n key={p.label}\n onClick={() => onApply(p.ms)}\n disabled={isPending}\n className={`px-3 py-1.5 text-xs rounded transition-colors ${\n p.ms === -1\n ? 'bg-status-error/10 text-status-error hover:bg-status-error/20'\n : p.ms === 0\n ? 'bg-status-success/10 text-status-success hover:bg-status-success/20'\n : 'bg-surface-sunken text-text-secondary hover:bg-surface-hover'\n } disabled:opacity-50`}\n >\n {p.label}\n </button>\n ))}\n </div>\n </div>\n\n <div>\n <p className=\"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2\">\n Custom delay (seconds)\n </p>\n <div className=\"flex items-center gap-3\">\n <input\n type=\"number\"\n step=\"0.1\"\n min=\"0\"\n value={seconds}\n onChange={(e) => setSeconds(e.target.value)}\n placeholder=\"e.g. 2.5\"\n className=\"input text-xs py-1.5 px-3 w-28\"\n />\n <button\n onClick={() => {\n const s = parseFloat(seconds);\n if (isNaN(s) || s < 0) return;\n onApply(Math.round(s * 1000));\n }}\n disabled={isPending}\n className=\"btn-primary text-xs py-1.5 px-4 disabled:opacity-50\"\n >\n Apply\n </button>\n </div>\n </div>\n </div>\n </Modal>\n );\n}\n","import { useState, useCallback } from 'react';\nimport { CirclePause, Play, Loader2 } from 'lucide-react';\nimport { useControlPlaneApps, useThrottle } from '../../../api/controlplane';\n\ntype Scope = 'engines' | 'workers' | 'all';\n\nexport function EmergencyControls() {\n const { data: appsData } = useControlPlaneApps();\n const throttle = useThrottle();\n const [confirming, setConfirming] = useState<{ ms: number; scope: Scope } | null>(null);\n const [inflight, setInflight] = useState(false);\n\n const apps = appsData?.apps ?? [];\n\n const applyAll = useCallback(async (ms: number, scope: Scope = 'all') => {\n if (apps.length === 0) return;\n setInflight(true);\n\n const results = await Promise.allSettled(\n apps.map((app) => throttle.mutateAsync({\n appId: app.appId,\n throttle: ms,\n ...(scope !== 'all' ? { scope } : {}),\n })),\n );\n\n const failed = results.filter((r) => r.status === 'rejected').length;\n if (failed > 0) {\n console.error(`Emergency throttle: ${failed}/${results.length} apps failed`);\n }\n\n setInflight(false);\n setConfirming(null);\n }, [apps, throttle]);\n\n const scopeLabel = (scope: Scope) =>\n scope === 'engines' ? 'engines' : scope === 'workers' ? 'workers' : 'everything';\n\n if (confirming) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-status-error\">\n Pause {scopeLabel(confirming.scope)}?\n </span>\n <button\n onClick={() => applyAll(confirming.ms, confirming.scope)}\n disabled={inflight}\n className=\"px-2.5 py-1 text-xs rounded-md bg-status-error text-white hover:bg-status-error/90 transition-colors disabled:opacity-50\"\n >\n {inflight ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : 'Confirm'}\n </button>\n <button\n onClick={() => setConfirming(null)}\n disabled={inflight}\n className=\"px-2.5 py-1 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50\"\n >\n Cancel\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"flex items-center gap-2\">\n <button\n onClick={() => setConfirming({ ms: -1, scope: 'all' })}\n disabled={inflight}\n className=\"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-error/80 hover:text-status-error hover:bg-status-error/10 transition-colors disabled:opacity-50\"\n title=\"Pause all engines and workers\"\n >\n <CirclePause className=\"w-3.5 h-3.5\" />\n Pause All\n </button>\n <button\n onClick={() => applyAll(0)}\n disabled={inflight}\n className=\"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-success/80 hover:text-status-success hover:bg-status-success/10 transition-colors disabled:opacity-50\"\n title=\"Resume all engines and workers\"\n >\n {inflight ? <Loader2 className=\"w-3.5 h-3.5 animate-spin\" /> : <Play className=\"w-3.5 h-3.5\" />}\n Resume All\n </button>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport { stripStreamPrefix, type NodeFilter } from './helpers';\n\ninterface StreamEntry {\n stream_type: 'engine' | 'worker';\n stream_name: string;\n count: number;\n}\n\ninterface StreamVolumeChartProps {\n byStream: StreamEntry[];\n onNodeFilter?: (filter: NodeFilter) => void;\n onQueueFilter?: (queue: string) => void;\n}\n\nexport function StreamVolumeChart({ byStream, onNodeFilter }: StreamVolumeChartProps) {\n const [animated, setAnimated] = useState(false);\n\n useEffect(() => {\n setAnimated(false);\n const raf = requestAnimationFrame(() => setAnimated(true));\n return () => cancelAnimationFrame(raf);\n }, [byStream]);\n\n if (byStream.length === 0) {\n return <p className=\"text-xs text-text-tertiary py-4 text-center\">No activity in this period</p>;\n }\n\n const engineStreams = byStream.filter((s) => s.stream_type === 'engine');\n const workerStreams = byStream.filter((s) => s.stream_type === 'worker');\n const maxCount = Math.max(...byStream.map((s) => s.count));\n\n const renderBar = (s: StreamEntry) => {\n const pct = maxCount > 0 ? (s.count / maxCount) * 100 : 0;\n const isEngine = s.stream_type === 'engine';\n const label = isEngine ? '(all engines)' : stripStreamPrefix(s.stream_name);\n const barColor = isEngine ? 'bg-blue-500/70' : 'bg-accent/60';\n const labelColor = isEngine ? 'text-blue-500' : 'text-text-tertiary';\n return (\n <div key={`${s.stream_type}-${s.stream_name}`} className=\"flex items-center gap-3\">\n <span\n className={`text-[9px] font-mono ${labelColor} w-36 truncate text-right shrink-0`}\n title={s.stream_name}\n >\n {label}\n </span>\n <div className=\"flex-1 h-4 bg-surface-sunken rounded overflow-hidden\">\n <div\n className={`h-full ${barColor} rounded transition-all duration-500 ease-out`}\n style={{ width: animated ? `${pct}%` : '0%' }}\n />\n </div>\n <span className=\"text-[10px] font-mono tabular-nums text-text-secondary w-12 text-right shrink-0\">\n {s.count.toLocaleString()}\n </span>\n </div>\n );\n };\n\n const labelCls = 'text-[9px] uppercase tracking-widest font-semibold mb-1 cursor-pointer hover:underline';\n\n return (\n <div className=\"space-y-1.5\">\n {engineStreams.length > 0 && (\n <>\n <p\n className={`${labelCls} text-blue-500/70 hover:text-blue-500`}\n onClick={() => onNodeFilter?.('engines')}\n >\n Engine Stream\n </p>\n {engineStreams.map(renderBar)}\n {workerStreams.length > 0 && <div className=\"h-2\" />}\n </>\n )}\n {workerStreams.length > 0 && (\n <>\n <p\n className={`${labelCls} text-accent/70 hover:text-accent`}\n onClick={() => onNodeFilter?.('workers')}\n >\n Worker Streams\n </p>\n {workerStreams.map(renderBar)}\n </>\n )}\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { ChevronRight, Gauge, CirclePlay, Activity, Clock, Inbox } from 'lucide-react';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { DataTable } from '../../../components/common/data/DataTable';\nimport { Collapsible } from '../../../components/common/layout/Collapsible';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport type { QuorumProfile } from '../../../api/controlplane';\nimport { isThrottled, formatThrottleHuman, rowKey, stripStreamPrefix, queueHealth, totalPending, sumCounts } from './helpers';\nimport type { Column } from '../../../components/common/data/DataTable';\nimport type { Duration } from './helpers';\n\ninterface StreamEntry {\n stream_type: 'engine' | 'worker';\n stream_name: string;\n count: number;\n}\n\ninterface QueueCardProps {\n queue: string;\n workers: QuorumProfile[];\n expanded: boolean;\n onToggle: (queue: string) => void;\n onWorkerClick: (p: QuorumProfile) => void;\n onResumeThrottle: (p: QuorumProfile) => void;\n onQueueThrottle: (queue: string) => void;\n onResumeQueue: (queue: string) => void;\n byStream: StreamEntry[];\n activeDuration: Duration;\n}\n\nexport function QueueCard({\n queue,\n workers,\n expanded,\n onToggle,\n onWorkerClick,\n onResumeThrottle,\n onQueueThrottle,\n onResumeQueue,\n byStream,\n activeDuration,\n}: QueueCardProps) {\n const streamCount = useMemo(() => {\n const match = byStream.find(\n (s) => s.stream_type === 'worker' && stripStreamPrefix(s.stream_name) === queue,\n );\n return match?.count ?? 0;\n }, [byStream, queue]);\n\n const health = useMemo(() => queueHealth(workers), [workers]);\n const pending = useMemo(() => totalPending(workers), [workers]);\n const { errors } = useMemo(() => sumCounts(workers), [workers]);\n\n const healthDot = health === 'paused'\n ? 'bg-status-error'\n : health === 'degraded'\n ? 'bg-status-warning'\n : 'bg-status-success';\n\n const sortedWorkers = useMemo(() =>\n [...workers].sort((a, b) => sumCounts([b]).total - sumCounts([a]).total),\n [workers],\n );\n\n const columns = useMemo((): Column<QuorumProfile>[] => [\n {\n key: 'engine_id',\n label: 'Router',\n render: (row) => {\n const label = row.engine_id.replace(/^[^:]+::/, '').replace(/-[A-Za-z0-9_]{10,}$/, '') || row.engine_id;\n const source = row.engine_id.match(/^([^:]+)::/)?.[1] || '';\n return (\n <div className=\"flex items-center gap-2\" title={row.engine_id}>\n <span className=\"text-xs text-text-secondary truncate max-w-[180px]\">{label}</span>\n {source && <span className=\"text-[9px] text-text-tertiary/50\">{source}</span>}\n </div>\n );\n },\n },\n {\n key: 'processed',\n label: 'Processed',\n render: (row) => {\n const c = sumCounts([row]);\n return <span className=\"text-xs font-mono tabular-nums text-text-tertiary\">{c.total > 0 ? c.total.toLocaleString() : '--'}</span>;\n },\n className: 'w-24',\n },\n {\n key: 'throttle',\n label: 'Throttle',\n render: (row) => {\n const t = row.throttle;\n if (t === -1) return <span className=\"text-xs text-status-error font-medium\">Paused</span>;\n if (t && t > 0) return <span className=\"text-xs text-status-warning font-medium\">{formatThrottleHuman(t)}</span>;\n return <span className=\"text-xs text-text-tertiary\">0</span>;\n },\n className: 'w-24',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {isThrottled(row) && (\n <RowAction\n icon={CirclePlay}\n title=\"Resume (remove throttle)\"\n onClick={() => onResumeThrottle(row)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )}\n <RowAction\n icon={Gauge}\n title=\"Adjust throttle\"\n onClick={() => onWorkerClick(row)}\n />\n </RowActionGroup>\n ),\n className: 'w-16',\n },\n ], [onWorkerClick, onResumeThrottle]);\n\n return (\n <div>\n <button\n onClick={() => onToggle(queue)}\n className=\"group/row relative flex items-center gap-3 w-full py-2 hover:bg-surface-hover transition-colors text-left rounded\"\n >\n <span className={`w-2 h-2 rounded-full shrink-0 ${healthDot}`} title={health} />\n <ChevronRight\n className={`w-3.5 h-3.5 text-text-tertiary/50 transition-transform duration-200 ${expanded ? 'rotate-90' : ''}`}\n strokeWidth={2}\n />\n <TaskQueuePill queue={queue} size=\"sm\" />\n\n <span className=\"flex-1\" />\n\n {errors > 0 && (\n <span className=\"text-[10px] text-status-error font-medium mr-2\">\n {errors} errors\n </span>\n )}\n\n {pending > 0 && (\n <span className=\"flex items-center gap-1 text-[10px] text-status-warning w-20\">\n <Inbox className=\"w-3 h-3 shrink-0\" strokeWidth={1.5} />\n <span className=\"font-mono tabular-nums\">{pending.toLocaleString()}</span>\n </span>\n )}\n\n <span className={`flex items-center gap-1 text-xs w-24 ${workers.some(isThrottled) ? 'text-status-warning' : 'text-text-tertiary'}`}>\n <Activity className=\"w-3 h-3 shrink-0\" strokeWidth={1.5} />\n <span className=\"font-mono tabular-nums\">{workers.length}</span>\n <span>workers</span>\n </span>\n\n <span className=\"flex items-center gap-1 text-xs font-mono text-text-tertiary w-28 justify-end mr-16\">\n {streamCount > 0 ? (\n <>\n <Clock className=\"w-3 h-3 shrink-0\" strokeWidth={1.5} />\n {streamCount.toLocaleString()} in {activeDuration}\n </>\n ) : (\n <span className=\"text-text-tertiary/40\">—</span>\n )}\n </span>\n\n <span className=\"absolute right-3 top-1/2 -translate-y-1/2 opacity-0 group-hover/row:opacity-100 transition-opacity flex items-center gap-2\">\n {workers.some(isThrottled) && (\n <CirclePlay\n className=\"w-4 h-4 text-text-tertiary hover:text-status-success\"\n strokeWidth={1.5}\n onClick={(e) => {\n e.stopPropagation();\n onResumeQueue(queue);\n }}\n />\n )}\n <Gauge\n className=\"w-4 h-4 text-text-tertiary hover:text-accent\"\n strokeWidth={1.5}\n onClick={(e) => {\n e.stopPropagation();\n onQueueThrottle(queue);\n }}\n />\n </span>\n </button>\n\n <Collapsible open={expanded}>\n <div className=\"ml-6\">\n <DataTable\n columns={columns}\n data={sortedWorkers}\n keyFn={rowKey}\n onRowClick={onWorkerClick}\n emptyMessage=\"No workers\"\n inline\n />\n </div>\n </Collapsible>\n </div>\n );\n}\n","import { useState, useCallback, useRef, useEffect } from 'react';\nimport { Radio, Settings, Eraser, Code } from 'lucide-react';\nimport { JsonViewer } from '../../../components/common/data/JsonViewer';\nimport { Collapsible } from '../../../components/common/layout/Collapsible';\nimport { useEventSubscription } from '../../../hooks/useEventContext';\nimport {\n EVENT_TYPE_COLORS,\n EVENT_TYPE_LABELS,\n QUORUM_CHANNELS,\n MAX_EVENTS,\n formatThrottleHuman,\n type QuorumEvent,\n} from './helpers';\n\nlet eventCounter = 0;\n\n// ── Human-readable event summaries ─────────────────────────────────────────\n\nfunction humanizeEvent(event: QuorumEvent): string {\n const d = event.data || {};\n const topic = d.topic ? String(d.topic) : '';\n const guid = d.guid ? String(d.guid).slice(0, 8) : '';\n\n switch (event.type) {\n case 'pong':\n return topic\n ? `Worker ${guid}... on \"${topic}\" responded`\n : `Engine ${guid}... responded`;\n case 'ping':\n return 'Roll call broadcast';\n case 'throttle': {\n const ms = d.throttle as number;\n const target = topic ? `queue \"${topic}\"` : guid ? `node ${guid}...` : 'all nodes';\n return `${formatThrottleHuman(ms)} applied to ${target}`;\n }\n case 'job':\n return `Job ${guid ? guid + '...' : ''} ${d.status || 'updated'}`;\n case 'work':\n return `Dispatched to \"${topic || 'worker'}\" ${guid ? '(' + guid + '...)' : ''}`;\n case 'activate':\n return `Worker \"${topic || 'unknown'}\" activated`;\n case 'cron':\n return `Cron triggered ${topic ? '\"' + topic + '\"' : ''}`;\n default:\n return topic || guid || event.type;\n }\n}\n\n// ── Aggregate display items ───────────────────────────────────────────────\n\ninterface DisplayItem {\n kind: 'single';\n event: QuorumEvent;\n}\n\ninterface DisplayGroup {\n kind: 'group';\n type: string;\n count: number;\n firstTimestamp: string;\n lastTimestamp: string;\n events: QuorumEvent[];\n}\n\ntype FeedItem = DisplayItem | DisplayGroup;\n\n/** Collapse consecutive pong events into a summary row. */\nfunction collapseEvents(events: QuorumEvent[]): FeedItem[] {\n const items: FeedItem[] = [];\n let i = 0;\n while (i < events.length) {\n const evt = events[i];\n // Group consecutive pong events\n if (evt.type === 'pong') {\n let j = i + 1;\n while (j < events.length && events[j].type === 'pong') j++;\n const batch = events.slice(i, j);\n if (batch.length >= 3) {\n items.push({\n kind: 'group',\n type: 'pong',\n count: batch.length,\n firstTimestamp: batch[batch.length - 1].timestamp,\n lastTimestamp: batch[0].timestamp,\n events: batch,\n });\n } else {\n for (const e of batch) items.push({ kind: 'single', event: e });\n }\n i = j;\n } else {\n items.push({ kind: 'single', event: evt });\n i++;\n }\n }\n return items;\n}\n\n// ── Event row ───────────────────────────────────────────────────────────────\n\nfunction QuorumEventRow({ event }: { event: QuorumEvent }) {\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div className=\"border-b border-surface-border/50 last:border-b-0\">\n <button\n onClick={() => setExpanded(!expanded)}\n className=\"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors\"\n >\n <span className=\"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0\">\n {new Date(event.timestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })}\n </span>\n <span className={`text-[9px] font-medium px-1 py-0.5 rounded ${EVENT_TYPE_COLORS[event.type] || 'text-text-tertiary'} bg-surface-sunken whitespace-nowrap shrink-0`}>\n {EVENT_TYPE_LABELS[event.type] || event.type}\n </span>\n <span className=\"text-[9px] text-text-secondary flex-1 min-w-0 truncate\">\n {humanizeEvent(event)}\n </span>\n <svg\n className={`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${expanded ? 'rotate-180' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n <Collapsible open={expanded}>\n <div className=\"pb-2\">\n <JsonViewer data={event.data} />\n </div>\n </Collapsible>\n </div>\n );\n}\n\n/** Collapsed group row for consecutive pong events. */\nfunction QuorumGroupRow({ group }: { group: DisplayGroup }) {\n const [expanded, setExpanded] = useState(false);\n const engines = group.events.filter((e) => !e.data?.topic).length;\n const workers = group.count - engines;\n\n return (\n <div className=\"border-b border-surface-border/50 last:border-b-0\">\n <button\n onClick={() => setExpanded(!expanded)}\n className=\"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors\"\n >\n <span className=\"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0\">\n {new Date(group.lastTimestamp).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })}\n </span>\n <span className={`text-[9px] font-medium px-1 py-0.5 rounded ${EVENT_TYPE_COLORS.pong} bg-surface-sunken whitespace-nowrap shrink-0`}>\n roll call\n </span>\n <span className=\"text-[9px] text-text-secondary flex-1 min-w-0 truncate\">\n {group.count} nodes responded\n {engines > 0 && workers > 0\n ? ` (${engines} engine${engines !== 1 ? 's' : ''}, ${workers} worker${workers !== 1 ? 's' : ''})`\n : engines > 0\n ? ` (${engines} engine${engines !== 1 ? 's' : ''})`\n : ` (${workers} worker${workers !== 1 ? 's' : ''})`}\n </span>\n <svg\n className={`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${expanded ? 'rotate-180' : ''}`}\n fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n <Collapsible open={expanded}>\n <div className=\"ml-4\">\n {group.events.map((evt) => (\n <QuorumEventRow key={evt.id} event={evt} />\n ))}\n </div>\n </Collapsible>\n </div>\n );\n}\n\n// ── Config panel ────────────────────────────────────────────────────────────\n\ninterface ConfigPanelProps {\n channels: Set<string>;\n onToggle: (key: string) => void;\n customFilter: string;\n onCustomFilterChange: (v: string) => void;\n}\n\nfunction ConfigPanel({ channels, onToggle, customFilter, onCustomFilterChange }: ConfigPanelProps) {\n return (\n <div className=\"space-y-3 pb-3 border-b border-surface-border mb-3\">\n <div className=\"flex items-center gap-2 mb-1\">\n <p className=\"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Channels\n </p>\n <p className=\"text-[9px] text-text-tertiary\">\n Unchecked channels are dropped before buffering\n </p>\n </div>\n <div className=\"grid grid-cols-2 gap-1\">\n {QUORUM_CHANNELS.map((ch) => (\n <label key={ch.key} className=\"flex items-center gap-2 cursor-pointer py-0.5\">\n <input\n type=\"checkbox\"\n checked={channels.has(ch.key)}\n onChange={() => onToggle(ch.key)}\n className=\"w-3 h-3 rounded border-border accent-accent\"\n />\n <span className=\"text-[10px] text-text-secondary\" title={ch.description}>\n {ch.label}\n </span>\n </label>\n ))}\n </div>\n <div>\n <p className=\"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">\n Text Filter\n </p>\n <input\n type=\"text\"\n value={customFilter}\n onChange={(e) => onCustomFilterChange(e.target.value)}\n placeholder=\"pong\"\n className=\"input text-[10px] font-mono py-1 px-2 w-full\"\n />\n <p className=\"text-[9px] text-text-tertiary mt-1\">\n Filter by event type, e.g. <span className=\"font-mono\">pong</span>, <span className=\"font-mono\">throttle</span>, or any text in the event data.\n </p>\n </div>\n </div>\n );\n}\n\n// ── Feed panel ──────────────────────────────────────────────────────────────\n\ninterface QuorumFeedProps {\n bridgeActive: boolean;\n}\n\nexport function QuorumFeed({ bridgeActive }: QuorumFeedProps) {\n const [showConfig, setShowConfig] = useState(false);\n const [showRaw, setShowRaw] = useState(false);\n const [events, setEvents] = useState<QuorumEvent[]>([]);\n const [channels, setChannels] = useState<Set<string>>(\n () => new Set(QUORUM_CHANNELS.map((c) => c.key)),\n );\n const [customFilter, setCustomFilter] = useState('');\n\n // Keep a ref to channels so the event callback reads the latest without re-subscribing\n const channelsRef = useRef(channels);\n useEffect(() => { channelsRef.current = channels; }, [channels]);\n const customFilterRef = useRef(customFilter);\n useEffect(() => { customFilterRef.current = customFilter; }, [customFilter]);\n\n const toggleChannel = (key: string) => {\n setChannels((prev) => {\n const next = new Set(prev);\n if (next.has(key)) next.delete(key);\n else next.add(key);\n return next;\n });\n };\n\n // Subscribe to NATS and filter on intake (before buffer)\n useEventSubscription('lt.events.mesh.>', useCallback((raw: any) => {\n const type = raw.type?.replace('mesh.', '') || 'unknown';\n\n // Channel filter: drop events for unchecked channels at intake\n if (!channelsRef.current.has(type)) return;\n\n // Text filter: if set, match against type or stringified data\n const cf = customFilterRef.current;\n if (cf) {\n const haystack = `${type} ${JSON.stringify(raw.data || raw)}`.toLowerCase();\n if (!haystack.includes(cf.toLowerCase())) return;\n }\n\n setEvents((prev) => {\n const next = [{\n id: ++eventCounter,\n type,\n timestamp: raw.timestamp || new Date().toISOString(),\n data: raw.data || raw,\n }, ...prev];\n return next.slice(0, MAX_EVENTS);\n });\n }, []));\n\n const handleClear = () => setEvents([]);\n\n return (\n <div className=\"border-l border-surface-border pl-6 pt-4 min-h-[300px] sticky top-14 self-start max-h-[calc(100vh-8rem)] flex flex-col\">\n {/* Header */}\n <div className=\"flex items-center gap-2 mb-3\">\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary\">\n Event Stream\n </p>\n <Radio className={`w-3 h-3 ${bridgeActive ? 'text-status-success animate-pulse' : 'text-text-tertiary'}`} />\n <span className=\"text-[9px] text-text-tertiary\">\n {bridgeActive ? 'Live' : '...'}\n </span>\n\n <span className=\"ml-auto flex items-center gap-1\">\n <button\n onClick={() => { setShowConfig((v) => !v); setShowRaw(false); }}\n className={`p-1 rounded transition-colors ${showConfig ? 'text-accent bg-accent/10' : 'text-text-tertiary hover:text-text-primary'}`}\n title=\"Configure channels\"\n >\n <Settings className=\"w-3.5 h-3.5\" />\n </button>\n <button\n onClick={() => { setShowRaw((v) => !v); setShowConfig(false); }}\n className={`p-1 rounded transition-colors ${showRaw ? 'text-accent bg-accent/10' : 'text-text-tertiary hover:text-text-primary'}`}\n title=\"View raw JSON\"\n >\n <Code className=\"w-3.5 h-3.5\" />\n </button>\n {events.length > 0 && (\n <button\n onClick={handleClear}\n className=\"p-1 rounded text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Clear events\"\n >\n <Eraser className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </span>\n </div>\n\n {/* Config panel (animated) */}\n <Collapsible open={showConfig}>\n <ConfigPanel\n channels={channels}\n onToggle={toggleChannel}\n customFilter={customFilter}\n onCustomFilterChange={setCustomFilter}\n />\n </Collapsible>\n\n {/* Raw JSON view */}\n <Collapsible open={showRaw}>\n <div className=\"pb-3 border-b border-surface-border mb-3\">\n <pre className=\"text-[9px] font-mono text-text-tertiary bg-surface-sunken rounded-lg p-3 max-h-[50vh] overflow-auto whitespace-pre-wrap\">\n {JSON.stringify(events.slice(0, 50), null, 2)}\n </pre>\n </div>\n </Collapsible>\n\n {/* Event count */}\n {events.length > 0 && (\n <p className=\"text-[9px] text-text-tertiary mb-2\">\n {events.length} events\n </p>\n )}\n\n {/* Event list */}\n <div className=\"flex-1 overflow-y-auto\">\n {events.length === 0 ? (\n <p className=\"text-xs text-text-tertiary py-6 text-center\">\n {bridgeActive ? 'Waiting for events...' : 'Subscribing...'}\n </p>\n ) : (\n collapseEvents(events).map((item, idx) =>\n item.kind === 'group' ? (\n <QuorumGroupRow key={`grp-${idx}`} group={item} />\n ) : (\n <QuorumEventRow key={item.event.id} event={item.event} />\n ),\n )\n )}\n </div>\n </div>\n );\n}\n","import { useMemo, useState } from 'react';\nimport { Zap, CirclePause, ChevronRight, Gauge } from 'lucide-react';\nimport { Collapsible } from '../../../components/common/layout/Collapsible';\nimport type { QuorumProfile } from '../../../api/controlplane';\nimport { sumCounts, formatUptime, engineLabel, engineSource, isThrottled, formatThrottleHuman } from './helpers';\n\ninterface EngineClusterProps {\n engines: QuorumProfile[];\n onThrottle: (profile: QuorumProfile) => void;\n isLoading: boolean;\n}\n\nfunction categorize(engines: QuorumProfile[]) {\n const active: QuorumProfile[] = [];\n const idle: QuorumProfile[] = [];\n const paused: QuorumProfile[] = [];\n\n for (const e of engines) {\n if (isThrottled(e)) {\n paused.push(e);\n } else if (e.is_scout || sumCounts([e]).total > 0) {\n active.push(e);\n } else {\n idle.push(e);\n }\n }\n\n // Sort active by processed descending; scout first if tied\n active.sort((a, b) => {\n if (a.is_scout && !b.is_scout) return -1;\n if (!a.is_scout && b.is_scout) return 1;\n return sumCounts([b]).total - sumCounts([a]).total;\n });\n\n idle.sort((a, b) => engineLabel(a.engine_id).localeCompare(engineLabel(b.engine_id)));\n paused.sort((a, b) => engineLabel(a.engine_id).localeCompare(engineLabel(b.engine_id)));\n\n return { active, idle, paused };\n}\n\nfunction EngineRow({ engine, isFirst, onThrottle }: {\n engine: QuorumProfile;\n isFirst?: boolean;\n onThrottle: (p: QuorumProfile) => void;\n}) {\n const label = engineLabel(engine.engine_id);\n const source = engineSource(engine.engine_id);\n const counts = sumCounts([engine]);\n const pending = engine.stream_depth ?? 0;\n const paused = isThrottled(engine);\n\n return (\n <div className=\"group/row flex items-center gap-3 py-2 hover:bg-surface-hover/50 transition-colors rounded px-1\">\n {paused ? (\n <CirclePause className=\"w-3.5 h-3.5 text-status-warning shrink-0\" strokeWidth={1.5} />\n ) : (\n <Zap className={`w-3.5 h-3.5 shrink-0 ${counts.total > 0 || engine.is_scout ? 'text-status-success' : 'text-text-tertiary/30'}`} strokeWidth={1.5} />\n )}\n\n <span className={`${isFirst ? 'text-base font-medium' : 'text-xs'} text-text-primary truncate max-w-[180px]`} title={engine.engine_id}>\n {label}\n </span>\n {source && <span className=\"text-[10px] text-text-tertiary/50\">{source}</span>}\n\n {engine.is_scout && (\n <span className=\"text-[9px] text-amber-500 uppercase tracking-widest\">scout</span>\n )}\n\n <span className=\"flex-1\" />\n\n {paused && (\n <span className=\"text-[10px] text-status-warning\">{engine.throttle === -1 ? 'Paused' : formatThrottleHuman(engine.throttle)}</span>\n )}\n\n {counts.total > 0 && (\n <span className=\"text-[10px] font-mono tabular-nums text-text-tertiary w-16 text-right\">{counts.total.toLocaleString()}</span>\n )}\n\n {pending > 0 && (\n <span className={`text-[10px] font-mono tabular-nums w-14 text-right ${pending > 100 ? 'text-status-warning' : 'text-text-tertiary/50'}`}>{pending.toLocaleString()} q</span>\n )}\n\n <span className=\"text-[10px] font-mono text-text-tertiary/40 w-12 text-right\">{formatUptime(engine.inited)}</span>\n\n <span className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\">\n <button\n onClick={(e) => { e.stopPropagation(); onThrottle(engine); }}\n className=\"text-text-tertiary hover:text-accent transition-colors\"\n title={paused ? 'Resume / adjust throttle' : 'Pause / throttle'}\n >\n <Gauge className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </span>\n </div>\n );\n}\n\nfunction CollapsibleGroup({ label, engines, onThrottle }: {\n label: string;\n engines: QuorumProfile[];\n onThrottle: (p: QuorumProfile) => void;\n}) {\n const [open, setOpen] = useState(false);\n if (engines.length === 0) return null;\n\n return (\n <div className=\"mt-1\">\n <button\n onClick={() => setOpen(!open)}\n className=\"flex items-center gap-1.5 text-[10px] text-text-tertiary hover:text-text-secondary transition-colors py-1\"\n >\n <ChevronRight className={`w-3 h-3 transition-transform duration-200 ${open ? 'rotate-90' : ''}`} strokeWidth={2} />\n {engines.length} {label}\n </button>\n <Collapsible open={open}>\n <div className=\"ml-1\">\n {engines.map((e) => (\n <EngineRow key={e.engine_id} engine={e} onThrottle={onThrottle} />\n ))}\n </div>\n </Collapsible>\n </div>\n );\n}\n\nexport function EngineCluster({ engines, onThrottle, isLoading }: EngineClusterProps) {\n const { active, idle, paused } = useMemo(() => categorize(engines), [engines]);\n\n if (isLoading) {\n return <p className=\"text-xs text-text-tertiary\">Discovering engines...</p>;\n }\n\n if (engines.length === 0) {\n return <p className=\"text-xs text-text-tertiary\">No engines found.</p>;\n }\n\n // All paused — no active processor\n if (active.length === 0 && idle.length === 0) {\n return (\n <div>\n <div className=\"flex items-center gap-3 py-2\">\n <CirclePause className=\"w-4 h-4 text-status-error shrink-0\" strokeWidth={1.5} />\n <span className=\"text-base text-status-error font-medium\">All {engines.length} engines paused</span>\n </div>\n <p className=\"text-[10px] text-text-tertiary ml-7\">Messages are accumulating. Resume at least one engine to restore processing.</p>\n <div className=\"ml-1 mt-2\">\n {paused.map((e) => (\n <EngineRow key={e.engine_id} engine={e} onThrottle={onThrottle} />\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n {/* Active engines — shown individually */}\n {active.map((e, i) => (\n <EngineRow key={e.engine_id} engine={e} isFirst={i === 0} onThrottle={onThrottle} />\n ))}\n\n {/* Idle — collapsed */}\n <CollapsibleGroup label=\"idle\" engines={idle} onThrottle={onThrottle} />\n\n {/* Paused — collapsed */}\n <CollapsibleGroup label=\"paused\" engines={paused} onThrottle={onThrottle} />\n </div>\n );\n}\n","import { CollapsibleSection } from '../../../components/common/layout/CollapsibleSection';\nimport { StreamVolumeChart } from './StreamVolumeChart';\nimport { QueueCard } from './QueueCard';\nimport { QuorumFeed } from './QuorumFeed';\nimport { EngineCluster } from './EngineCluster';\nimport type { Duration } from './helpers';\n\ninterface ControlPlaneContentProps {\n collapsed: Record<string, boolean>;\n toggleSection: (key: string) => void;\n activeDuration: Duration;\n streamStats: { byStream: Array<any> } | undefined;\n isLoading: boolean;\n queueMap: Map<string, Array<any>>;\n expandedQueues: Set<string>;\n toggleQueue: (queue: string) => void;\n allQueuesExpanded: boolean;\n toggleAllQueues: () => void;\n handleRowClick: (profile: any) => void;\n handleResumeThrottle: (profile: any) => void;\n handleQueueThrottle: (queue: string) => void;\n handleResumeQueue: (queue: string) => void;\n engines: Array<any>;\n bridgeActive: boolean;\n}\n\nexport function ControlPlaneContent({\n collapsed,\n toggleSection,\n activeDuration,\n streamStats,\n isLoading,\n queueMap,\n expandedQueues,\n toggleQueue,\n allQueuesExpanded,\n toggleAllQueues,\n handleRowClick,\n handleResumeThrottle,\n handleQueueThrottle,\n handleResumeQueue,\n engines,\n bridgeActive,\n}: ControlPlaneContentProps) {\n return (\n <div className=\"grid grid-cols-1 lg:grid-cols-[1fr_340px] gap-6\">\n <div className=\"flex flex-col gap-12 mt-10\">\n {/* Stream Volume */}\n <CollapsibleSection\n title={`Message Volume (${activeDuration})`}\n sectionKey=\"volume\"\n isCollapsed={!!collapsed.volume}\n onToggle={toggleSection}\n contentClassName=\"mt-4 ml-7\"\n >\n <StreamVolumeChart\n byStream={streamStats?.byStream ?? []}\n onNodeFilter={() => {}}\n onQueueFilter={() => {}}\n />\n </CollapsibleSection>\n\n {/* Engine Routers — nervous system, shown first */}\n <CollapsibleSection\n title={`Engine Routers (${engines.length})`}\n sectionKey=\"engines\"\n isCollapsed={!!collapsed.engines}\n onToggle={toggleSection}\n contentClassName=\"mt-4 ml-7\"\n >\n <EngineCluster\n engines={engines}\n onThrottle={handleRowClick}\n isLoading={isLoading}\n />\n </CollapsibleSection>\n\n {/* Worker Routers */}\n <CollapsibleSection\n title=\"Worker Routers\"\n sectionKey=\"queues\"\n isCollapsed={!!collapsed.queues}\n onToggle={toggleSection}\n contentClassName=\"mt-4 ml-7 flex flex-col gap-0\"\n >\n {isLoading ? (\n <p className=\"text-xs text-text-tertiary\">Discovering mesh nodes...</p>\n ) : queueMap.size === 0 ? (\n <p className=\"text-xs text-text-tertiary\">No worker routers found. Click \"Roll Call\" to discover.</p>\n ) : (\n <>\n <div className=\"flex justify-end mb-2\">\n <button onClick={toggleAllQueues} className=\"text-[10px] text-accent hover:underline\">\n {allQueuesExpanded ? 'Collapse all' : 'Expand all'}\n </button>\n </div>\n {[...queueMap.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([queue, qWorkers]) => (\n <QueueCard\n key={queue}\n queue={queue}\n workers={qWorkers}\n expanded={expandedQueues.has(queue)}\n onToggle={toggleQueue}\n onWorkerClick={handleRowClick}\n onResumeThrottle={handleResumeThrottle}\n onQueueThrottle={handleQueueThrottle}\n onResumeQueue={handleResumeQueue}\n byStream={streamStats?.byStream ?? []}\n activeDuration={activeDuration}\n />\n ))}\n </>\n )}\n </CollapsibleSection>\n </div>\n\n <QuorumFeed bridgeActive={bridgeActive} />\n </div>\n );\n}\n","import { useMemo, useState, useCallback, useEffect } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { RefreshCw } from 'lucide-react';\nimport { PageHeaderWithStats, type InlineStat } from '../../../components/common/layout/PageHeaderWithStats';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useNamespace } from '../../../hooks/useNamespace';\nimport {\n useRollCall,\n useStreamStats,\n useSubscribeMesh,\n} from '../../../api/controlplane';\nimport {\n DURATIONS,\n isWorker,\n isThrottled,\n groupByQueue,\n type Duration,\n} from './helpers';\nimport { useMeshSelection } from './useMeshSelection';\nimport { ThrottleModal } from './ThrottleModal';\nimport { EmergencyControls } from './EmergencyControls';\nimport { ControlPlaneContent } from './ControlPlaneContent';\n\nexport function ControlPlanePage() {\n const { namespace, available } = useNamespace();\n\n const { filters, setFilter } = useFilterParams({\n filters: { app_id: '', duration: '1h' },\n });\n\n const activeAppId = filters.app_id || namespace;\n const activeDuration = (filters.duration || '1h') as Duration;\n\n const subscribeMesh = useSubscribeMesh();\n\n const REFRESH_INTERVAL = 60_000;\n\n const { data: rollCallData, isLoading, error: rollCallError, refetch, isFetching } = useRollCall(activeAppId, REFRESH_INTERVAL);\n const { data: streamStats } = useStreamStats(activeAppId, activeDuration, undefined, REFRESH_INTERVAL);\n\n // ── All profiles (sorted) ───────────────────────────────────\n const allProfiles = useMemo(() => {\n const raw = rollCallData?.profiles ?? [];\n return [...raw].sort((a, b) => {\n const ta = a.worker_topic || a.stream || '';\n const tb = b.worker_topic || b.stream || '';\n if (!a.worker_topic && b.worker_topic) return -1;\n if (a.worker_topic && !b.worker_topic) return 1;\n return ta.localeCompare(tb);\n });\n }, [rollCallData?.profiles]);\n\n // ── Derived data ──────────────────────────────────────────────\n const engines = useMemo(() => allProfiles.filter((p) => !isWorker(p)), [allProfiles]);\n const workers = useMemo(() => allProfiles.filter(isWorker), [allProfiles]);\n const queueMap = useMemo(() => groupByQueue(allProfiles), [allProfiles]);\n const throttledCount = allProfiles.filter(isThrottled).length;\n\n const appOptions = useMemo(() => {\n const ids = new Set(available);\n if (activeAppId) ids.add(activeAppId);\n return [...ids].sort().map((id) => ({ value: id, label: id }));\n }, [available, activeAppId]);\n\n // ── Deep-link: auto-expand a queue from ?queue= param ──────────\n const [searchParams] = useSearchParams();\n const deepLinkQueue = searchParams.get('queue');\n\n // ── Queue card expand/collapse state ───────────────────────────\n const [expandedQueues, setExpandedQueues] = useState<Set<string>>(\n () => deepLinkQueue ? new Set([deepLinkQueue]) : new Set(),\n );\n const toggleQueue = useCallback((queue: string) => {\n setExpandedQueues((prev) => {\n const closing = prev.has(queue);\n const next = closing ? new Set<string>() : new Set([queue]);\n // Sync URL — add or remove ?queue= param\n const params = new URLSearchParams(window.location.search);\n if (closing) {\n params.delete('queue');\n } else {\n params.set('queue', queue);\n }\n const qs = params.toString();\n window.history.pushState(null, '', `${window.location.pathname}${qs ? `?${qs}` : ''}`);\n return next;\n });\n }, []);\n const allQueuesExpanded = queueMap.size > 0 && [...queueMap.keys()].every((q) => expandedQueues.has(q));\n const toggleAllQueues = useCallback(() => {\n if (allQueuesExpanded) setExpandedQueues(new Set());\n else setExpandedQueues(new Set(queueMap.keys()));\n }, [allQueuesExpanded, queueMap]);\n\n // ── Section collapse state (persisted) ─────────────────────────\n const STORAGE_KEY = 'lt:controlplane:collapsed';\n const [collapsed, setCollapsed] = useState<Record<string, boolean>>(() => {\n try {\n const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || '{}');\n // When deep-linking to a queue, ensure Worker Routers section is open\n if (deepLinkQueue) saved.queues = false;\n return saved;\n } catch { return {}; }\n });\n const toggleSection = useCallback((key: string) => {\n setCollapsed((prev) => {\n const next = { ...prev, [key]: !prev[key] };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n return next;\n });\n }, []);\n\n // ── Selection + throttle logic ─────────────────────────────\n const {\n throttleModalOpen,\n throttleTargets,\n selectedThrottleTargets,\n throttleMutation,\n handleBulkThrottle,\n handleRowClick,\n handleResumeThrottle,\n handleResumeQueue,\n handleQueueThrottle,\n closeThrottleModal,\n } = useMeshSelection({ activeAppId, allProfiles, profiles: allProfiles });\n\n // ── Header stats ──────────────────────────────────────────────\n const headerStats = useMemo((): InlineStat[] => {\n const stats: InlineStat[] = [\n { label: 'Engines', value: engines.length, dotClass: 'bg-blue-500' },\n { label: 'Workers', value: workers.length, dotClass: 'bg-text-secondary' },\n { label: 'Topics', value: queueMap.size },\n ];\n if (throttledCount > 0) {\n stats.push({ label: 'Throttled', value: throttledCount, dotClass: 'bg-status-warning' });\n }\n return stats;\n }, [engines.length, workers.length, queueMap.size, throttledCount]);\n\n // ── Quorum bridge ────────────────────────────────────────────\n const [bridgeActive, setBridgeActive] = useState(false);\n\n const handleStartBridge = useCallback(() => {\n subscribeMesh.mutate({ appId: activeAppId }, {\n onSuccess: () => setBridgeActive(true),\n });\n }, [activeAppId, subscribeMesh]);\n\n useEffect(() => {\n if (!bridgeActive && activeAppId) {\n handleStartBridge();\n }\n }, [activeAppId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <div>\n <PageHeaderWithStats\n title=\"Routers\"\n docsHash=\"#docs:dashboard.md:task-queues\"\n stats={headerStats}\n actions={<EmergencyControls />}\n />\n\n <FilterBar\n actions={\n <div className=\"flex items-center gap-1\">\n {DURATIONS.map((d) => (\n <button\n key={d.value}\n onClick={() => setFilter('duration', d.value)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n activeDuration === d.value\n ? 'bg-accent text-text-inverse'\n : 'text-text-tertiary hover:text-text-primary hover:bg-surface-hover'\n }`}\n >\n {d.label}\n </button>\n ))}\n </div>\n }\n >\n <FilterSelect\n label=\"Application\"\n value={filters.app_id}\n onChange={(v) => setFilter('app_id', v)}\n options={appOptions}\n />\n <button\n onClick={() => refetch()}\n disabled={isFetching}\n className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50\"\n >\n <RefreshCw className={`w-3.5 h-3.5 ${isFetching ? 'animate-spin' : ''}`} />\n Roll Call\n </button>\n </FilterBar>\n\n {/* Error banner */}\n {rollCallError && (\n <div className=\"mb-6 px-4 py-3 rounded bg-status-error/10 border border-status-error/20\">\n <p className=\"text-xs text-status-error font-medium\">\n {rollCallError.message === 'Session expired'\n ? 'Session expired — please log in again.'\n : `Failed to load mesh data: ${rollCallError.message}`}\n </p>\n </div>\n )}\n\n <ControlPlaneContent\n collapsed={collapsed}\n toggleSection={toggleSection}\n activeDuration={activeDuration}\n streamStats={streamStats}\n isLoading={isLoading}\n queueMap={queueMap}\n expandedQueues={expandedQueues}\n toggleQueue={toggleQueue}\n allQueuesExpanded={allQueuesExpanded}\n toggleAllQueues={toggleAllQueues}\n handleRowClick={handleRowClick}\n handleResumeThrottle={handleResumeThrottle}\n handleQueueThrottle={handleQueueThrottle}\n handleResumeQueue={handleResumeQueue}\n engines={engines}\n bridgeActive={bridgeActive}\n />\n\n <ThrottleModal\n open={throttleModalOpen}\n onClose={closeThrottleModal}\n targets={throttleTargets.length > 0 ? throttleTargets : selectedThrottleTargets}\n onApply={handleBulkThrottle}\n isPending={throttleMutation.isPending}\n />\n </div>\n );\n}\n"],"names":["DURATIONS","EVENT_TYPE_COLORS","EVENT_TYPE_LABELS","MAX_EVENTS","isWorker","p","isThrottled","formatThrottleHuman","ms","parseTimestamp","ts","match","y","mo","d","h","mi","s","date","formatUptime","inited","m","stripStreamPrefix","name","engineLabel","engineId","engineSource","QUORUM_CHANNELS","rowKey","groupByQueue","profiles","map","q","sumCounts","total","success","errors","code","n","totalPending","sum","queueHealth","useMeshSelection","activeAppId","allProfiles","throttleMutation","useThrottle","selectedIds","setSelectedIds","useState","throttleModalOpen","setThrottleModalOpen","throttleTargets","setThrottleTargets","useEffect","toggleCheckbox","useCallback","profile","prev","next","key","toggleAll","selectedThrottleTargets","useMemo","selected","engines","workers","targets","e","queues","w","queue","members","allOnQueue","t","scope","label","resolvedScope","queueName","PRESETS","TargetPill","target","isMesh","isEngine","color","scopeLabel","jsxs","jsx","ThrottleModal","open","onClose","onApply","isPending","seconds","setSeconds","Modal","i","EmergencyControls","appsData","useControlPlaneApps","throttle","confirming","setConfirming","inflight","setInflight","apps","applyAll","results","app","failed","r","Loader2","CirclePause","Play","StreamVolumeChart","byStream","onNodeFilter","animated","setAnimated","raf","engineStreams","workerStreams","maxCount","renderBar","pct","barColor","labelColor","labelCls","Fragment","QueueCard","expanded","onToggle","onWorkerClick","onResumeThrottle","onQueueThrottle","onResumeQueue","activeDuration","streamCount","health","pending","healthDot","sortedWorkers","a","b","columns","row","source","_a","c","RowActionGroup","RowAction","CirclePlay","Gauge","ChevronRight","TaskQueuePill","Inbox","Activity","Clock","Collapsible","DataTable","eventCounter","humanizeEvent","event","topic","guid","collapseEvents","events","items","evt","j","batch","QuorumEventRow","setExpanded","JsonViewer","QuorumGroupRow","group","ConfigPanel","channels","customFilter","onCustomFilterChange","ch","QuorumFeed","bridgeActive","showConfig","setShowConfig","showRaw","setShowRaw","setEvents","setChannels","setCustomFilter","channelsRef","useRef","customFilterRef","toggleChannel","useEventSubscription","raw","type","cf","handleClear","Radio","v","Settings","Code","Eraser","item","idx","categorize","active","idle","paused","EngineRow","engine","isFirst","onThrottle","counts","Zap","CollapsibleGroup","setOpen","EngineCluster","isLoading","ControlPlaneContent","collapsed","toggleSection","streamStats","queueMap","expandedQueues","toggleQueue","allQueuesExpanded","toggleAllQueues","handleRowClick","handleResumeThrottle","handleQueueThrottle","handleResumeQueue","CollapsibleSection","qWorkers","ControlPlanePage","namespace","available","useNamespace","filters","setFilter","useFilterParams","subscribeMesh","useSubscribeMesh","REFRESH_INTERVAL","rollCallData","rollCallError","refetch","isFetching","useRollCall","useStreamStats","ta","tb","throttledCount","appOptions","ids","id","searchParams","useSearchParams","deepLinkQueue","setExpandedQueues","closing","params","qs","STORAGE_KEY","setCollapsed","saved","handleBulkThrottle","closeThrottleModal","headerStats","stats","setBridgeActive","handleStartBridge","PageHeaderWithStats","FilterBar","FilterSelect","RefreshCw"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{a as p,j as a}from"./vendor-query-B2UbickB.js";import{a as N}from"./vendor-react-CXumBFUA.js";import{u as P,a as T,b as F,S as C,c as M,d as O,e as $}from"./StreamMessageDetail-BYzfjWe_.js";import{u as z}from"./useFilterParams-x-Dg0Vgz.js";import{u as A}from"./useNamespace-BBzCmCIN.js";import{b as D}from"./api-path-u2Jf9QXS.js";import{D as R}from"./DataTable-ZWgVQg7F.js";import{S as E}from"./StickyPagination-GQKFFTjL.js";import{F as L,b as u,a as b}from"./FilterBar-BQ2JGg8U.js";import{T as x}from"./TimestampCell-BSKj1jqT.js";import{P as U}from"./PageHeader-CFta2VaS.js";import{L as I}from"./ListToolbar--FkPpYDY.js";import{X as f}from"./vendor-icons-BaQqUm-e.js";import"./index-CKXSKsVZ.js";import"./controlplane-BrwK_MT8.js";import"./EmptyState-BcsfPq9T.js";function B(o,i){if(o.length<=i)return o;const s=Math.floor((i-1)/2);return`${o.slice(0,s)}…${o.slice(-s)}`}function oe(){const{namespace:o,available:i}=A("namespace"),{filters:s,setFilter:t,pagination:r,sort:n,setSort:_}=z({filters:{namespace:"",source:"worker",status:"",stream_name:"",msg_type:"",topic:"",workflow_name:"",jid:"",aid:""}}),[m,y]=p.useState(null),h=p.useMemo(()=>i.map(e=>({value:e,label:e})),[i]),{data:l,isLoading:j,refetch:v,isFetching:k}=P({namespace:s.namespace||o,source:s.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:n.sort_by||"created_at",order:n.order||"desc",status:s.status||void 0,stream_name:s.stream_name||void 0,msg_type:s.msg_type||void 0,topic:s.topic||void 0,workflow_name:s.workflow_name||void 0,jid:s.jid||void 0,aid:s.aid||void 0}),d=(l==null?void 0:l.messages)??[],g=(l==null?void 0:l.total)??0,c=p.useMemo(()=>m?d.find(e=>e.id===m.id&&e.source===m.source)??m:null,[d,m]),S=!!c,w=[{key:"status",label:"Status",render:e=>a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${M[e.status]}`}),a.jsx("span",{className:"text-xs",children:O[e.status]})]}),className:"w-28"},{key:"source",label:"Source",render:e=>a.jsx("span",{className:$,children:e.source}),className:"w-20"},{key:"stream_name",label:"Stream",sortable:!0,render:e=>a.jsx("span",{className:"font-mono text-xs text-text-secondary truncate block max-w-[240px]",title:e.stream_name,children:e.stream_name})},{key:"msg_type",label:"Type",render:e=>a.jsx("span",{className:"text-xs text-text-secondary",children:e.msg_type||"—"}),className:"w-24"},{key:"created_at",label:"Created",sortable:!0,render:e=>a.jsx(x,{date:e.created_at}),className:"w-44"},{key:"reserved_at",label:"Reserved",render:e=>e.reserved_at?a.jsx(x,{date:e.reserved_at}):a.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-44"},{key:"expired_at",label:"Processed",render:e=>e.expired_at?a.jsx(x,{date:e.expired_at}):a.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-44"},{key:"priority",label:"Pri",sortable:!0,render:e=>a.jsx("span",{className:"text-xs text-text-secondary",children:e.priority}),className:"w-12 text-right"},{key:"retry_attempt",label:"Retries",render:e=>a.jsxs("span",{className:"text-xs text-text-secondary",children:[e.retry_attempt,"/",e.max_retry_attempts]}),className:"w-16"}];return a.jsxs("div",{children:[a.jsx(U,{title:"Messages",docsHash:"#docs:dashboard.md:messages"}),a.jsxs(L,{actions:a.jsx(I,{onRefresh:()=>v(),isFetching:k,apiPath:D("/controlplane/stream-messages",{namespace:s.namespace||o,source:s.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:n.sort_by||"created_at",order:n.order||"desc",status:s.status||void 0,stream_name:s.stream_name||void 0,msg_type:s.msg_type||void 0,topic:s.topic||void 0,workflow_name:s.workflow_name||void 0,jid:s.jid||void 0,aid:s.aid||void 0})}),children:[a.jsx(u,{label:"Namespace",value:s.namespace,onChange:e=>t("namespace",e),options:h,required:!0}),a.jsx(u,{label:"Source",value:s.source,onChange:e=>t("source",e),options:T,required:!0}),a.jsx(u,{label:"Status",value:s.status,onChange:e=>t("status",e),options:F}),a.jsx(b,{label:"Stream",value:s.stream_name,onChange:e=>t("stream_name",e),placeholder:"Filter by stream name…"}),a.jsx(b,{label:"Job ID",value:s.jid,onChange:e=>t("jid",e),placeholder:"Filter by jid…"}),[{key:"topic",label:"Topic",value:s.topic},{key:"workflow_name",label:"Workflow",value:s.workflow_name},{key:"aid",label:"Activity",value:s.aid},{key:"msg_type",label:"Type",value:s.msg_type}].filter(e=>e.value).map(e=>a.jsxs("button",{onClick:()=>t(e.key,""),className:"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors",title:`Clear ${e.label} filter: ${e.value}`,children:[e.label,": ",B(e.value,12),a.jsx(f,{className:"w-2.5 h-2.5"})]},e.key))]}),a.jsx(R,{columns:w,data:d,keyFn:e=>`${e.source}:${e.id}`,isLoading:j,emptyMessage:"No stream messages found",onRowClick:e=>y(e),activeRowKey:c?`${c.source}:${c.id}`:null,sort:n,onSort:_}),a.jsx(E,{page:r.page,totalPages:r.totalPages(g),onPageChange:r.setPage,total:g,pageSize:r.pageSize,onPageSizeChange:r.setPageSize}),S&&N.createPortal(a.jsxs("div",{className:"fixed right-0 bottom-0 w-[400px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg",style:{top:"3.5rem"},children:[a.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50",children:[a.jsx("span",{className:"text-xs font-medium text-text-primary",children:"Message Detail"}),a.jsx("button",{onClick:()=>y(null),className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:a.jsx(f,{className:"w-4 h-4"})})]}),a.jsx("div",{className:"px-4 py-4",children:a.jsx(C,{message:c,filters:{onFilterStatus:e=>t("status",e),onFilterStreamName:e=>t("stream_name",e),onFilterMsgType:e=>t("msg_type",e),onFilterTopic:e=>t("topic",e),onFilterWorkflow:e=>t("workflow_name",e),onFilterJid:e=>t("jid",e),onFilterAid:e=>t("aid",e)}})})]}),document.body)]})}export{oe as StreamMessagesPage};
2
- //# sourceMappingURL=index-DEXouwBQ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-DEXouwBQ.js","sources":["../../src/pages/admin/streams/StreamMessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { useStreamMessages, type StreamMessage } from '../../../api/stream-messages';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useNamespace } from '../../../hooks/useNamespace';\nimport { buildApiPath } from '../../../lib/api-path';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { StickyPagination } from '../../../components/common/data/StickyPagination';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { TimestampCell } from '../../../components/common/display/TimestampCell';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { ListToolbar } from '../../../components/common/data/ListToolbar';\nimport { StreamMessageDetail } from './StreamMessageDetail';\nimport { STATUS_DOT, STATUS_LABEL, STATUS_OPTIONS, SOURCE_OPTIONS, SOURCE_BADGE } from './constants';\n\nfunction truncateMiddle(str: string, max: number): string {\n if (str.length <= max) return str;\n const half = Math.floor((max - 1) / 2);\n return `${str.slice(0, half)}…${str.slice(-half)}`;\n}\n\nexport function StreamMessagesPage() {\n const { namespace, available } = useNamespace('namespace');\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { namespace: '', source: 'worker', status: '', stream_name: '', msg_type: '', topic: '', workflow_name: '', jid: '', aid: '' },\n });\n\n const [selected, setSelected] = useState<StreamMessage | null>(null);\n\n const namespaceOptions = useMemo(\n () => available.map((id) => ({ value: id, label: id })),\n [available],\n );\n\n const { data, isLoading, refetch, isFetching } = useStreamMessages({\n namespace: filters.namespace || namespace,\n source: (filters.source as 'engine' | 'worker') || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: (filters.status as any) || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n });\n\n const messages = data?.messages ?? [];\n const total = data?.total ?? 0;\n\n const activeMessage = useMemo(() => {\n if (!selected) return null;\n return messages.find((m) => m.id === selected.id && m.source === selected.source) ?? selected;\n }, [messages, selected]);\n\n const panelOpen = !!activeMessage;\n\n const columns: Column<StreamMessage>[] = [\n {\n key: 'status',\n label: 'Status',\n render: (row) => (\n <div className=\"flex items-center gap-2\">\n <span className={`w-2 h-2 rounded-full shrink-0 ${STATUS_DOT[row.status]}`} />\n <span className=\"text-xs\">{STATUS_LABEL[row.status]}</span>\n </div>\n ),\n className: 'w-28',\n },\n {\n key: 'source',\n label: 'Source',\n render: (row) => <span className={SOURCE_BADGE}>{row.source}</span>,\n className: 'w-20',\n },\n {\n key: 'stream_name',\n label: 'Stream',\n sortable: true,\n render: (row) => (\n <span className=\"font-mono text-xs text-text-secondary truncate block max-w-[240px]\" title={row.stream_name}>\n {row.stream_name}\n </span>\n ),\n },\n {\n key: 'msg_type',\n label: 'Type',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">{row.msg_type || '—'}</span>\n ),\n className: 'w-24',\n },\n {\n key: 'created_at',\n label: 'Created',\n sortable: true,\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-44',\n },\n {\n key: 'reserved_at',\n label: 'Reserved',\n render: (row) => row.reserved_at ? <TimestampCell date={row.reserved_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'expired_at',\n label: 'Processed',\n render: (row) => row.expired_at ? <TimestampCell date={row.expired_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'priority',\n label: 'Pri',\n sortable: true,\n render: (row) => <span className=\"text-xs text-text-secondary\">{row.priority}</span>,\n className: 'w-12 text-right',\n },\n {\n key: 'retry_attempt',\n label: 'Retries',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">\n {row.retry_attempt}/{row.max_retry_attempts}\n </span>\n ),\n className: 'w-16',\n },\n ];\n\n return (\n <div>\n <PageHeader title=\"Messages\" docsHash=\"#docs:dashboard.md:messages\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/controlplane/stream-messages', {\n namespace: filters.namespace || namespace,\n source: filters.source || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: filters.status || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n })}\n />\n }>\n <FilterSelect\n label=\"Namespace\"\n value={filters.namespace}\n onChange={(v) => setFilter('namespace', v)}\n options={namespaceOptions}\n required\n />\n <FilterSelect\n label=\"Source\"\n value={filters.source}\n onChange={(v) => setFilter('source', v)}\n options={SOURCE_OPTIONS}\n required\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterInput\n label=\"Stream\"\n value={filters.stream_name}\n onChange={(v) => setFilter('stream_name', v)}\n placeholder=\"Filter by stream name…\"\n />\n <FilterInput\n label=\"Job ID\"\n value={filters.jid}\n onChange={(v) => setFilter('jid', v)}\n placeholder=\"Filter by jid…\"\n />\n {/* Active dimension filter pills — inline in the sticky bar */}\n {[\n { key: 'topic', label: 'Topic', value: filters.topic },\n { key: 'workflow_name', label: 'Workflow', value: filters.workflow_name },\n { key: 'aid', label: 'Activity', value: filters.aid },\n { key: 'msg_type', label: 'Type', value: filters.msg_type },\n ].filter((f) => f.value).map((f) => (\n <button\n key={f.key}\n onClick={() => setFilter(f.key as any, '')}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors\"\n title={`Clear ${f.label} filter: ${f.value}`}\n >\n {f.label}: {truncateMiddle(f.value, 12)}\n <X className=\"w-2.5 h-2.5\" />\n </button>\n ))}\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={messages}\n keyFn={(row) => `${row.source}:${row.id}`}\n isLoading={isLoading}\n emptyMessage=\"No stream messages found\"\n onRowClick={(row) => setSelected(row)}\n activeRowKey={activeMessage ? `${activeMessage.source}:${activeMessage.id}` : null}\n sort={sort}\n onSort={setSort}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n\n {/* Detail panel — portaled to body so fixed positioning works */}\n {panelOpen && createPortal(\n <div className=\"fixed right-0 bottom-0 w-[400px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg\" style={{ top: '3.5rem' }}>\n <div className=\"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50\">\n <span className=\"text-xs font-medium text-text-primary\">Message Detail</span>\n <button\n onClick={() => setSelected(null)}\n className=\"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n <div className=\"px-4 py-4\">\n <StreamMessageDetail\n message={activeMessage}\n filters={{\n onFilterStatus: (v) => setFilter('status', v),\n onFilterStreamName: (v) => setFilter('stream_name', v),\n onFilterMsgType: (v) => setFilter('msg_type', v),\n onFilterTopic: (v) => setFilter('topic', v),\n onFilterWorkflow: (v) => setFilter('workflow_name', v),\n onFilterJid: (v) => setFilter('jid', v),\n onFilterAid: (v) => setFilter('aid', v),\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":["truncateMiddle","str","max","half","StreamMessagesPage","namespace","available","useNamespace","filters","setFilter","pagination","sort","setSort","useFilterParams","selected","setSelected","useState","namespaceOptions","useMemo","id","data","isLoading","refetch","isFetching","useStreamMessages","messages","total","activeMessage","m","panelOpen","columns","row","jsxs","jsx","STATUS_DOT","STATUS_LABEL","SOURCE_BADGE","TimestampCell","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","SOURCE_OPTIONS","STATUS_OPTIONS","FilterInput","f","X","DataTable","StickyPagination","createPortal","StreamMessageDetail"],"mappings":"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"}
@@ -1,9 +0,0 @@
1
- import{a as m,j as e}from"./vendor-query-B2UbickB.js";import{d as te,h as Q,u as se,i as re,b as ne}from"./workflows-BTkHs6VT.js";import{C as M}from"./ConfirmDeleteModal-D9_1b4MW.js";import{R as $}from"./RolePill-CXEyPMqb.js";import{W as oe}from"./WorkflowPill-BuNkWUVM.js";import{P as ae}from"./PageHeader-CFta2VaS.js";import{ai as le,t as L,ab as ie,aj as D,ad as U,ak as ce,P as z,al as de,am as B,y as xe,U as O,X as H,i as G,V as K,W as T,C as me}from"./vendor-icons-BaQqUm-e.js";import{c as V,e as ue,f as pe}from"./vendor-react-CXumBFUA.js";import{u as he}from"./roles-UboiQxXT.js";import{B as fe}from"./BotPicker-xGUCxJo-.js";import{N as we}from"./NamespacePill-DlqBTvFR.js";import"./index-CKXSKsVZ.js";import"./Modal-CSrxpXeM.js";import"./bots-CyzN6Uxi.js";function ge({tier:t}){return t==="certified"?e.jsxs("span",{className:"inline-flex items-center gap-1 text-[10px] font-medium text-status-success",children:[e.jsx(U,{className:"w-3 h-3"}),"Certified"]}):t==="registered"?e.jsxs("span",{className:"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary",children:[e.jsx(xe,{className:"w-3 h-3"}),"Registered"]}):e.jsxs("span",{className:"inline-flex items-center gap-1 text-[10px] font-medium text-text-quaternary",children:[e.jsx(D,{className:"w-3 h-3"}),"Durable"]})}function Le(){const t=V(),{data:a,isLoading:x}=te(),h=Q(),[c,g]=m.useState(""),[o,j]=m.useState(null),[v,k]=m.useState(null),n=a??[],d=m.useMemo(()=>[...new Set(n.map(l=>l.task_queue).filter(Boolean))].sort(),[n]),i=m.useMemo(()=>{const l=c.toLowerCase().trim();return(o?[o]:d).map(f=>({queue:f,workflows:n.filter(_=>{var p;return _.task_queue===f&&(!l||_.workflow_type.toLowerCase().includes(l)||((p=_.description)==null?void 0:p.toLowerCase().includes(l)))})})).filter(f=>f.workflows.length>0)},[n,d,c,o]),u=m.useMemo(()=>{const l=c.toLowerCase().trim();return o?[]:n.filter(w=>{var f;return!w.task_queue&&(!l||w.workflow_type.toLowerCase().includes(l)||((f=w.description)==null?void 0:f.toLowerCase().includes(l)))})},[n,c,o]),r=l=>{l.registered?t(`/workflows/registry/${encodeURIComponent(l.workflow_type)}`):t(`/workflows/registry/new?workflow_type=${encodeURIComponent(l.workflow_type)}&task_queue=${encodeURIComponent(l.task_queue??"")}`)},C=()=>{v&&h.mutate(v,{onSuccess:()=>k(null)})};return e.jsxs("div",{children:[e.jsx(ae,{title:"Registered Workflows",docsHash:"#docs:dashboard.md:workflow-registry",actions:e.jsx("button",{onClick:()=>t("/workflows/registry/new"),className:"btn-primary text-xs",children:"Register Workflow"})}),!x&&d.length>0&&e.jsx("div",{className:"sticky top-0 z-20 bg-surface pt-3 pb-3",children:e.jsxs("div",{className:"bg-[#F7F7F7] rounded-lg px-5 pt-3 pb-3 flex items-center gap-5",children:[e.jsxs("button",{onClick:()=>j(null),className:`flex flex-col items-center gap-1 transition-colors ${o===null?"text-accent":"text-text-quaternary hover:text-text-secondary"}`,children:[e.jsx(le,{className:"w-3 h-3",strokeWidth:1.5}),e.jsx("span",{className:"text-[9px] font-medium",children:"All"})]}),d.map(l=>{const w=o===l,f=l.length>16?l.slice(0,14)+"…":l;return e.jsxs("button",{onClick:()=>j(w?null:l),className:`flex flex-col items-center gap-1 transition-colors ${w?"text-accent":"text-text-quaternary hover:text-text-secondary"}`,title:l,children:[e.jsx(L,{className:"w-3 h-3",strokeWidth:1.5}),e.jsx("span",{className:"text-[9px] font-medium",children:f})]},l)}),e.jsx("span",{className:"flex-1"}),e.jsxs("div",{className:"relative",children:[e.jsx(ie,{className:"absolute left-0 top-1/2 -translate-y-1/2 w-3 h-3 text-text-quaternary"}),e.jsx("input",{type:"text",value:c,onChange:l=>g(l.target.value),placeholder:`Search ${n.length} workflows…`,className:"pl-5 py-1 text-sm bg-transparent border-b border-surface-border/60 text-text-primary placeholder:text-text-quaternary focus:outline-none focus:border-accent/50 transition-colors w-52"})]})]})}),x?e.jsx(je,{}):i.length===0&&u.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:c||o?"No workflows match your filter.":"No workflows discovered yet."}):e.jsxs("div",{className:"space-y-10",children:[i.map(({queue:l,workflows:w})=>e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[78px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(L,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:l}),e.jsx("span",{className:"text-xs text-text-quaternary",children:w.length})]}),e.jsx(F,{}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:w.map(f=>e.jsx(J,{wf:f,onRowClick:r,onDelete:k,onNavigate:t},f.workflow_type))})]},l)),u.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[78px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(D,{className:"w-3 h-3 text-text-quaternary",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:"No Queue"}),e.jsx("span",{className:"text-xs text-text-quaternary",children:u.length})]}),e.jsx(F,{}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:u.map(l=>e.jsx(J,{wf:l,onRowClick:r,onDelete:k,onNavigate:t},l.workflow_type))})]})]}),e.jsx(M,{open:!!v,onClose:()=>k(null),onConfirm:C,title:"Unregister Workflow",description:e.jsxs(e.Fragment,{children:["Delete the registration for"," ",e.jsx("span",{className:"font-mono font-medium text-text-primary",children:v}),"? This removes its invocation settings, certification, and interceptor treatment; the workflow keeps running as a plain durable workflow. To demote certified → registered instead, open the workflow and uncheck Certify — that keeps every setting."]}),isPending:h.isPending,error:h.error})]})}const X="grid grid-cols-[minmax(0,1fr)_7rem_13rem_4.5rem] gap-x-6 items-start";function F(){return e.jsxs("div",{className:`${X} px-3 pb-2 pt-1`,children:[e.jsx("span",{className:"text-[10px] font-medium text-text-quaternary",children:"Workflow"}),e.jsx("span",{className:"text-[10px] font-medium text-text-quaternary",children:"Tier"}),e.jsx("span",{className:"text-[10px] font-medium text-text-quaternary",children:"Access"}),e.jsx("span",{})]})}function J({wf:t,onRowClick:a,onDelete:x,onNavigate:h}){const c=t.roles??[],g=t.invocation_roles??[];return e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>a(t),onKeyDown:o=>{(o.key==="Enter"||o.key===" ")&&a(t)},className:`group ${X} py-2.5 px-3 -mx-3 rounded-md cursor-pointer transition-colors`,children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx(oe,{type:t.workflow_type,size:"md",variant:t.tier==="certified"?"certified":t.tier==="registered"?"registered":"durable"}),t.description&&e.jsx("p",{className:"mt-0.5 text-[10px] text-text-tertiary group-hover:text-text-secondary leading-snug line-clamp-2 transition-colors",children:t.description})]}),e.jsx("div",{className:"pt-0.5",children:e.jsx(ge,{tier:t.tier??"durable"})}),e.jsxs("div",{className:"min-w-0 space-y-1 pt-0.5",children:[c.length>0&&e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[e.jsx("span",{title:"Escalation roles",children:e.jsx(U,{className:"w-3 h-3 text-text-quaternary shrink-0"})}),c.map(o=>e.jsx($,{role:o},`e-${o}`))]}),g.length>0&&e.jsxs("div",{className:"flex items-center gap-1.5 flex-wrap",children:[e.jsx("span",{title:"Invocation roles",children:e.jsx(ce,{className:"w-3 h-3 text-text-quaternary shrink-0"})}),g.map(o=>e.jsx($,{role:o},`i-${o}`))]}),c.length===0&&g.length===0&&e.jsx("span",{className:"text-xs text-text-quaternary",children:"—"})]}),e.jsxs("div",{className:"flex items-center justify-end gap-2.5 pt-0.5 opacity-0 group-hover:opacity-100 transition-opacity",children:[t.invocable&&e.jsx("button",{title:"Invoke workflow",onClick:o=>{o.stopPropagation(),h(`/workflows/start?type=${encodeURIComponent(t.workflow_type)}&mode=now`)},className:"text-text-quaternary hover:text-status-success transition-colors",children:e.jsx(z,{className:"w-3.5 h-3.5"})}),t.tier==="durable"&&e.jsx("button",{title:"Configure workflow",onClick:o=>{o.stopPropagation(),h(`/workflows/registry/new?workflow_type=${encodeURIComponent(t.workflow_type)}&task_queue=${encodeURIComponent(t.task_queue??"")}`)},className:"text-text-quaternary hover:text-status-info transition-colors",children:e.jsx(D,{className:"w-3.5 h-3.5"})}),t.tier==="registered"&&e.jsx("button",{title:"Certify workflow",onClick:o=>{o.stopPropagation(),h(`/workflows/registry/${encodeURIComponent(t.workflow_type)}`)},className:"text-text-quaternary hover:text-status-success transition-colors",children:e.jsx(de,{className:"w-3.5 h-3.5"})}),t.registered&&e.jsx("button",{title:"Unregister workflow",onClick:o=>{o.stopPropagation(),x(t.workflow_type)},className:"text-text-quaternary hover:text-status-warning transition-colors",children:e.jsx(B,{className:"w-3.5 h-3.5"})})]})]})}function je(){return e.jsx("div",{className:"animate-pulse space-y-8 mt-4",children:[1,2].map(t=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-36 mb-4"}),e.jsx("div",{className:"space-y-4",children:[1,2,3].map(a=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},a))})]},t))})}function q({selected:t,onChange:a,single:x,placeholder:h}){const{data:c}=he(),g=(c==null?void 0:c.roles)??[],[o,j]=m.useState(!1),v=m.useRef(null);m.useEffect(()=>{const i=u=>{v.current&&!v.current.contains(u.target)&&j(!1)};return document.addEventListener("mousedown",i),()=>document.removeEventListener("mousedown",i)},[]);const k=i=>{x?(a(t.includes(i)?[]:[i]),j(!1)):a(t.includes(i)?t.filter(u=>u!==i):[...t,i])},n=i=>{a(t.filter(u=>u!==i))},d=h??(x?"Select role...":"Add roles...");return e.jsxs("div",{ref:v,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>j(!o),className:"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none",children:[t.length===0&&e.jsx("span",{className:"text-xs text-text-tertiary",children:d}),t.map(i=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px]",children:[e.jsx(O,{className:"w-2.5 h-2.5 shrink-0 text-accent/75"}),i,e.jsx("span",{role:"button",onClick:u=>{u.stopPropagation(),n(i)},className:"ml-0.5 hover:text-status-error transition-colors",children:e.jsx(H,{className:"w-2.5 h-2.5"})})]},i)),e.jsx(G,{className:`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${o?"rotate-180":""}`})]}),o&&e.jsx("div",{className:"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto",children:g.length===0?e.jsx("p",{className:"px-3 py-2 text-xs text-text-tertiary",children:"No roles defined"}):g.map(i=>{const u=t.includes(i);return e.jsxs("button",{type:"button",onClick:()=>k(i),className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${u?"bg-accent/[0.06] text-accent":"text-text-primary hover:bg-surface-sunken"}`,children:[e.jsx(O,{className:"w-3 h-3 shrink-0 text-accent/60"}),e.jsx("span",{className:"flex-1",children:i}),u&&e.jsx(K,{className:"w-3 h-3 shrink-0"})]},i)})})]})}function ve({options:t,selected:a,onChange:x,placeholder:h}){const[c,g]=m.useState(!1),o=m.useRef(null);m.useEffect(()=>{const n=d=>{o.current&&!o.current.contains(d.target)&&g(!1)};return document.addEventListener("mousedown",n),()=>document.removeEventListener("mousedown",n)},[]);const j=n=>{x(a.includes(n)?a.filter(d=>d!==n):[...a,n])},v=n=>{x(a.filter(d=>d!==n))},k=h??"Add workflows...";return e.jsxs("div",{ref:o,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>g(!c),className:"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none",children:[a.length===0&&e.jsx("span",{className:"text-xs text-text-tertiary",children:k}),a.map(n=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px] font-mono",children:[e.jsx(T,{className:"w-2.5 h-2.5 shrink-0 text-accent/75"}),n,e.jsx("span",{role:"button",onClick:d=>{d.stopPropagation(),v(n)},className:"ml-0.5 hover:text-status-error transition-colors",children:e.jsx(H,{className:"w-2.5 h-2.5"})})]},n)),e.jsx(G,{className:`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${c?"rotate-180":""}`})]}),c&&e.jsx("div",{className:"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto",children:t.length===0?e.jsx("p",{className:"px-3 py-2 text-xs text-text-tertiary",children:"No registered workflows"}):t.map(n=>{const d=a.includes(n);return e.jsxs("button",{type:"button",onClick:()=>j(n),className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs font-mono transition-colors ${d?"bg-accent/[0.06] text-accent":"text-text-primary hover:bg-surface-sunken"}`,children:[e.jsx(T,{className:"w-3 h-3 shrink-0 text-accent/60"}),e.jsx("span",{className:"flex-1",children:n}),d&&e.jsx(K,{className:"w-3 h-3 shrink-0"})]},n)})})]})}function P(t){return t.split(",").map(a=>a.trim()).filter(Boolean)}const W={workflow_type:"",description:"",task_queue:"",default_role:"reviewer",invocable:!1,roles:"",invocation_roles:"",consumes:"",envelope_schema:"",resolver_schema:"",cron_schedule:"",execute_as:"",certified:!1};function ke(t){const a=(t.roles??[]).join(", "),x=(t.consumes??[]).join(", ");return{workflow_type:t.workflow_type,description:t.description??"",task_queue:t.task_queue??"",default_role:t.default_role,invocable:t.invocable,roles:a,invocation_roles:(t.invocation_roles??[]).join(", "),consumes:x,envelope_schema:t.envelope_schema?JSON.stringify(t.envelope_schema,null,2):"",resolver_schema:t.resolver_schema?JSON.stringify(t.resolver_schema,null,2):"",cron_schedule:t.cron_schedule??"",execute_as:t.execute_as??"",certified:t.certified}}function S(t){if(!t.trim())return!0;try{return JSON.parse(t),!0}catch{return!1}}function E({icon:t,color:a,children:x}){return e.jsxs("div",{className:"flex items-center gap-2 mb-4 pb-2 border-b border-surface-border",children:[e.jsx(t,{className:`w-4 h-4 ${a}`,strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:x})]})}function y({label:t,hint:a,children:x}){return e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"label",children:t}),x,a&&e.jsx("p",{className:"hint",children:a})]})}const A="input-json w-full";function R(t){return P(t)}function I(t){return t.join(", ")}const ye=new Set(["mcpQuery","mcpDeterministic","mcpQueryRouter","mcpTriage","mcpTriageRouter","mcpTriageDeterministic","insightQuery"]);function Oe(){const{workflowType:t}=ue(),a=!t,x=V(),[h]=pe(),{data:c,isLoading:g}=se(),o=re(),j=Q(),[v,k]=m.useState(!1),n=(c==null?void 0:c.find(s=>s.workflow_type===t))??null,{data:d}=ne({limit:500}),i=m.useMemo(()=>{const s=new Set((c??[]).map(b=>b.workflow_type));return[...new Set(((d==null?void 0:d.jobs)??[]).map(b=>b.entity))].filter(b=>!s.has(b)&&!ye.has(b)).sort()},[c,d]),u=m.useMemo(()=>{if(!a)return W;const s=h.get("workflow_type")??"",N=h.get("task_queue")??"";return s||N?{...W,workflow_type:s,task_queue:N}:W},[a,h]),[r,C]=m.useState(u),[l,w]=m.useState(""),[f,_]=m.useState(!1),p=m.useCallback((s,N)=>C(b=>({...b,[s]:N})),[]);m.useEffect(()=>{if(!f){if(a){C(u),_(!0);return}n&&(C(ke(n)),_(!0))}},[n,a,f,u]);const Y=()=>{if(!r.workflow_type.trim())return;w("");let s=null,N=null;try{r.envelope_schema.trim()&&(s=JSON.parse(r.envelope_schema))}catch{w("Invalid JSON in Envelope Schema");return}try{r.resolver_schema.trim()&&(N=JSON.parse(r.resolver_schema))}catch{w("Invalid JSON in Resolver Schema");return}o.mutate({workflow_type:r.workflow_type.trim(),description:r.description.trim()||null,task_queue:r.task_queue.trim()||null,default_role:r.default_role.trim()||"reviewer",invocable:r.invocable,certified:r.certified,roles:P(r.roles),invocation_roles:P(r.invocation_roles),consumes:P(r.consumes),envelope_schema:s,resolver_schema:N,cron_schedule:r.cron_schedule.trim()||null,execute_as:r.execute_as.trim()||null},{onSuccess:()=>x("/workflows/registry")})};if(g)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-40 bg-surface-sunken rounded"})]});if(!a&&!n)return e.jsx("p",{className:"text-sm text-text-secondary",children:"Config not found."});const Z=!!r.workflow_type.trim()&&S(r.envelope_schema)&&S(r.resolver_schema),ee=a&&!r.workflow_type&&i.length>0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-start justify-between mb-8",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-light font-mono text-text-primary",children:a?"New Workflow":(n==null?void 0:n.workflow_type)??""}),n&&e.jsx("div",{className:"flex items-center gap-2 mt-2",children:e.jsx(we,{namespace:"durable"})})]}),e.jsxs("div",{className:"flex items-center gap-3 mt-1",children:[e.jsx("button",{onClick:()=>x("/workflows/registry"),className:"btn-ghost text-xs",children:"Cancel"}),e.jsx("button",{onClick:Y,disabled:!Z||o.isPending,className:"btn-primary text-xs",children:o.isPending?"Saving…":a?"Register":"Save"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-3 gap-x-14 gap-y-10",children:[e.jsxs("div",{children:[e.jsx(E,{icon:me,color:"text-accent",children:"Identity"}),e.jsxs("div",{className:"space-y-5",children:[e.jsx(y,{label:"Workflow Type",hint:"Register a workflow to configure invocation and HITL escalation routing.",children:ee?e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-text-secondary",children:"Select a durable workflow to register:"}),e.jsx("div",{className:"grid gap-1",children:i.map(s=>e.jsx("button",{onClick:()=>p("workflow_type",s),className:"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors",children:s},s))}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary",children:"or"}),e.jsx("input",{type:"text",onChange:s=>p("workflow_type",s.target.value),placeholder:"Enter type manually",className:"input font-mono flex-1"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("input",{type:"text",value:r.workflow_type,onChange:s=>p("workflow_type",s.target.value),disabled:!a,placeholder:"reviewContent",className:"input font-mono w-full"}),a&&r.workflow_type&&i.length>0&&e.jsx("button",{onClick:()=>p("workflow_type",""),className:"text-[10px] text-accent hover:underline mt-1",children:"Choose from durable workflows"})]})}),e.jsx(y,{label:"Description",children:e.jsx("input",{type:"text",value:r.description,onChange:s=>p("description",s.target.value),placeholder:"Describe what this workflow does",className:"input text-xs w-full"})}),e.jsx(y,{label:"Task Queue",hint:"Durable task queue this workflow listens on.",children:e.jsx("input",{type:"text",value:r.task_queue,onChange:s=>p("task_queue",s.target.value),placeholder:"lt-review",className:"input font-mono w-full"})})]})]}),e.jsxs("div",{children:[e.jsx(E,{icon:z,color:"text-emerald-400",children:"Invocation"}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:r.invocable,onChange:s=>p("invocable",s.target.checked),className:"w-4 h-4 rounded border-border accent-accent"}),e.jsx("span",{className:"text-xs text-text-primary font-medium",children:"Invocable"})]}),e.jsx("p",{className:"hint",children:"Allow this workflow to be started from the dashboard or API."})]}),r.invocable?e.jsxs(e.Fragment,{children:[e.jsx(y,{label:"Run As",hint:"Bot identity to run under. Default runs as the invoking user.",children:e.jsx(fe,{selected:r.execute_as,onChange:s=>p("execute_as",s)})}),e.jsx(y,{label:"Invocation Roles",hint:"Only users with these roles can start this workflow. Empty = all authenticated users.",children:e.jsx(q,{selected:R(r.invocation_roles),onChange:s=>p("invocation_roles",I(s)),placeholder:"Select roles…"})}),e.jsxs(y,{label:"Envelope Schema",hint:e.jsxs(e.Fragment,{children:["Pre-fills the JSON editor when invoking. Include ",e.jsx("code",{className:"font-mono",children:"data"})," (input) and optional ",e.jsx("code",{className:"font-mono",children:"metadata"}),"."]}),children:[e.jsx("textarea",{value:r.envelope_schema,onChange:s=>p("envelope_schema",s.target.value),placeholder:`{
2
- "data": {},
3
- "metadata": {}
4
- }`,className:A,rows:8,spellCheck:!1}),r.envelope_schema.trim()&&!S(r.envelope_schema)&&e.jsx("p",{className:"text-[10px] text-status-error mt-1",children:"Invalid JSON"})]})]}):e.jsxs("p",{className:"text-[11px] text-text-tertiary py-2",children:["Enable ",e.jsx("span",{className:"font-medium text-text-secondary",children:"Invocable"})," to configure invocation roles and an input template."]})]})]}),e.jsxs("div",{children:[e.jsx(E,{icon:U,color:"text-violet-400",children:"Certification"}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs(y,{label:"Resolver Schema",hint:e.jsxs(e.Fragment,{children:["Default form for resolving escalations. Use ",e.jsx("code",{className:"font-mono",children:"properties"})," with ",e.jsx("code",{className:"font-mono",children:"type"}),", ",e.jsx("code",{className:"font-mono",children:"default"}),", ",e.jsx("code",{className:"font-mono",children:"description"}),"."]}),children:[e.jsx("textarea",{value:r.resolver_schema,onChange:s=>p("resolver_schema",s.target.value),placeholder:`{
5
- "properties": {
6
- "approved": { "type": "boolean", "default": false }
7
- }
8
- }`,className:A,rows:6,spellCheck:!1}),r.resolver_schema.trim()&&!S(r.resolver_schema)&&e.jsx("p",{className:"text-[10px] text-status-error mt-1",children:"Invalid JSON"})]}),e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:r.certified,onChange:s=>p("certified",s.target.checked),className:"w-4 h-4 rounded border-border accent-accent"}),e.jsx("span",{className:"text-xs text-text-primary font-medium",children:"Certify for HITL Escalation"})]}),e.jsx("p",{className:"hint",children:"Certified workflows use the interceptor — failures escalate to human reviewers. Unchecking demotes this workflow to registered on save; escalation roles and dependencies below are kept."})]}),r.certified?e.jsxs(e.Fragment,{children:[e.jsx(y,{label:"Default Escalation Role",hint:"The role surface interceptor-raised escalations target.",children:e.jsx(q,{selected:R(r.default_role),onChange:s=>p("default_role",s[0]??""),single:!0,placeholder:"Select role…"})}),e.jsx(y,{label:"Escalation Roles",hint:"Interceptor default for who can claim and resolve. Escalations raised in workflow code choose their own role, whose versioned schema takes precedence.",children:e.jsx(q,{selected:R(r.roles),onChange:s=>p("roles",I(s)),placeholder:"Select roles…"})}),e.jsx(y,{label:"Consumes",hint:"Upstream workflows whose output is injected into this workflow's envelope.",children:e.jsx(ve,{options:(c??[]).map(s=>s.workflow_type).filter(s=>s!==r.workflow_type),selected:R(r.consumes),onChange:s=>p("consumes",I(s)),placeholder:"Select dependencies…"})})]}):e.jsxs("p",{className:"text-[11px] text-text-tertiary py-2",children:["Enable ",e.jsx("span",{className:"font-medium text-text-secondary",children:"Certify"})," to add automatic escalation routing and role-based resolution."]}),n&&e.jsx("div",{className:"pt-4 border-t border-surface-border/50",children:e.jsxs("button",{onClick:()=>k(!0),className:"flex items-center gap-1.5 text-[11px] text-status-warning hover:underline",title:"Delete this registration — the workflow returns to plain durable",children:[e.jsx(B,{className:"w-3 h-3"})," Unregister workflow"]})})]})]})]}),(l||o.error)&&e.jsx("p",{className:"text-xs text-status-error mt-8",children:l||o.error.message}),e.jsx(M,{open:v,onClose:()=>k(!1),onConfirm:()=>j.mutate(n.workflow_type,{onSuccess:()=>x("/workflows/registry")}),title:"Unregister Workflow",description:e.jsxs(e.Fragment,{children:["Delete the registration for"," ",e.jsx("span",{className:"font-mono font-medium text-text-primary",children:n==null?void 0:n.workflow_type}),"? This removes its invocation settings, certification, and interceptor treatment; the workflow keeps running as a plain durable workflow. Escalation schemas versioned on roles are untouched."]}),isPending:j.isPending,error:j.error})]})}export{Oe as WorkflowConfigDetailPage,Le as WorkflowConfigsPage};
9
- //# sourceMappingURL=index-U27KBbTV.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-U27KBbTV.js","sources":["../../src/pages/workflows/registry/WorkflowConfigsPage.tsx","../../src/components/common/form/RolePicker.tsx","../../src/components/common/form/WorkflowPicker.tsx","../../src/lib/parse.ts","../../src/pages/workflows/registry/config-form-types.ts","../../src/pages/workflows/registry/WorkflowConfigDetailPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useDiscoveredWorkflows,\n useDeleteWorkflowConfig,\n} from '../../../api/workflows';\nimport {\n Search, Server, LayoutGrid,\n ShieldCheck, ShieldPlus, ShieldOff, Settings, Wrench, Play, UserCheck,\n} from 'lucide-react';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { RolePill } from '../../../components/common/display/RolePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport type { DiscoveredWorkflow } from '../../../api/types';\n\n// ── Tier badge ─────────────────────────────────────────────────────────────────\n\nfunction TierBadge({ tier }: { tier: string }) {\n if (tier === 'certified')\n return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-status-success\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>;\n if (tier === 'registered')\n return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><Settings className=\"w-3 h-3\" />Registered</span>;\n return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-quaternary\"><Wrench className=\"w-3 h-3\" />Durable</span>;\n}\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigsPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useDiscoveredWorkflows();\n const deleteConfig = useDeleteWorkflowConfig();\n\n const [search, setSearch] = useState('');\n const [activeQueue, setActiveQueue] = useState<string | null>(null);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n\n const allWorkflows: DiscoveredWorkflow[] = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkflows.map((w) => w.task_queue).filter(Boolean) as string[])].sort(),\n [allWorkflows],\n );\n\n const grouped = useMemo(() => {\n const q = search.toLowerCase().trim();\n const targetQueues = activeQueue ? [activeQueue] : queues;\n return targetQueues\n .map((queue) => ({\n queue,\n workflows: allWorkflows.filter(\n (w) =>\n w.task_queue === queue &&\n (!q ||\n w.workflow_type.toLowerCase().includes(q) ||\n w.description?.toLowerCase().includes(q)),\n ),\n }))\n .filter((g) => g.workflows.length > 0);\n }, [allWorkflows, queues, search, activeQueue]);\n\n // Workflows with no queue\n const ungrouped = useMemo(() => {\n const q = search.toLowerCase().trim();\n if (activeQueue) return [];\n return allWorkflows.filter(\n (w) =>\n !w.task_queue &&\n (!q || w.workflow_type.toLowerCase().includes(q) || w.description?.toLowerCase().includes(q)),\n );\n }, [allWorkflows, search, activeQueue]);\n\n const handleRowClick = (row: DiscoveredWorkflow) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`);\n }\n };\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteConfig.mutate(confirmDelete, { onSuccess: () => setConfirmDelete(null) });\n };\n\n return (\n <div>\n <PageHeader\n title=\"Registered Workflows\"\n docsHash=\"#docs:dashboard.md:workflow-registry\"\n actions={\n <button onClick={() => navigate('/workflows/registry/new')} className=\"btn-primary text-xs\">\n Register Workflow\n </button>\n }\n />\n\n {/* Sticky filter bar: queue tabs + search */}\n {!isLoading && queues.length > 0 && (\n <div className=\"sticky top-0 z-20 bg-surface pt-3 pb-3\">\n <div className=\"bg-[#F7F7F7] rounded-lg px-5 pt-3 pb-3 flex items-center gap-5\">\n <button\n onClick={() => setActiveQueue(null)}\n className={`flex flex-col items-center gap-1 transition-colors ${\n activeQueue === null ? 'text-accent' : 'text-text-quaternary hover:text-text-secondary'\n }`}\n >\n <LayoutGrid className=\"w-3 h-3\" strokeWidth={1.5} />\n <span className=\"text-[9px] font-medium\">All</span>\n </button>\n {queues.map((queue) => {\n const isActive = activeQueue === queue;\n const label = queue.length > 16 ? queue.slice(0, 14) + '…' : queue;\n return (\n <button\n key={queue}\n onClick={() => setActiveQueue(isActive ? null : queue)}\n className={`flex flex-col items-center gap-1 transition-colors ${\n isActive ? 'text-accent' : 'text-text-quaternary hover:text-text-secondary'\n }`}\n title={queue}\n >\n <Server className=\"w-3 h-3\" strokeWidth={1.5} />\n <span className=\"text-[9px] font-medium\">{label}</span>\n </button>\n );\n })}\n <span className=\"flex-1\" />\n <div className=\"relative\">\n <Search className=\"absolute left-0 top-1/2 -translate-y-1/2 w-3 h-3 text-text-quaternary\" />\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={`Search ${allWorkflows.length} workflows…`}\n className=\"pl-5 py-1 text-sm bg-transparent border-b border-surface-border/60 text-text-primary placeholder:text-text-quaternary focus:outline-none focus:border-accent/50 transition-colors w-52\"\n />\n </div>\n </div>\n </div>\n )}\n\n {/* Content */}\n {isLoading ? (\n <LoadingSkeleton />\n ) : grouped.length === 0 && ungrouped.length === 0 ? (\n <p className=\"text-sm text-text-tertiary mt-8\">\n {search || activeQueue ? 'No workflows match your filter.' : 'No workflows discovered yet.'}\n </p>\n ) : (\n <div className=\"space-y-10\">\n {grouped.map(({ queue, workflows }) => (\n <div key={queue}>\n <div className=\"sticky top-[78px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Server className=\"w-3 h-3 text-accent\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">{queue}</h2>\n <span className=\"text-xs text-text-quaternary\">{workflows.length}</span>\n </div>\n <WorkflowTableHeader />\n <div className=\"divide-y divide-surface-border/30\">\n {workflows.map((wf) => (\n <WorkflowRow\n key={wf.workflow_type}\n wf={wf}\n onRowClick={handleRowClick}\n onDelete={setConfirmDelete}\n onNavigate={navigate}\n />\n ))}\n </div>\n </div>\n ))}\n\n {ungrouped.length > 0 && (\n <div>\n <div className=\"sticky top-[78px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border\">\n <Wrench className=\"w-3 h-3 text-text-quaternary\" strokeWidth={1.5} />\n <h2 className=\"section-h2\">No Queue</h2>\n <span className=\"text-xs text-text-quaternary\">{ungrouped.length}</span>\n </div>\n <WorkflowTableHeader />\n <div className=\"divide-y divide-surface-border/30\">\n {ungrouped.map((wf) => (\n <WorkflowRow\n key={wf.workflow_type}\n wf={wf}\n onRowClick={handleRowClick}\n onDelete={setConfirmDelete}\n onNavigate={navigate}\n />\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"Unregister Workflow\"\n description={\n <>\n Delete the registration for{' '}\n <span className=\"font-mono font-medium text-text-primary\">{confirmDelete}</span>? This\n removes its invocation settings, certification, and interceptor treatment; the workflow\n keeps running as a plain durable workflow. To demote certified → registered instead,\n open the workflow and uncheck Certify — that keeps every setting.\n </>\n }\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n\n// ── Column layout ─────────────────────────────────────────────────────────────\n// [Workflow 1fr] [Tier 7rem] [Access 13rem] [Actions 4.5rem]\nconst ROW_GRID = 'grid grid-cols-[minmax(0,1fr)_7rem_13rem_4.5rem] gap-x-6 items-start';\n\nfunction WorkflowTableHeader() {\n return (\n <div className={`${ROW_GRID} px-3 pb-2 pt-1`}>\n <span className=\"text-[10px] font-medium text-text-quaternary\">Workflow</span>\n <span className=\"text-[10px] font-medium text-text-quaternary\">Tier</span>\n <span className=\"text-[10px] font-medium text-text-quaternary\">Access</span>\n <span />\n </div>\n );\n}\n\n// ── Workflow row ───────────────────────────────────────────────────────────────\n\nfunction WorkflowRow({\n wf,\n onRowClick,\n onDelete,\n onNavigate,\n}: {\n wf: DiscoveredWorkflow;\n onRowClick: (wf: DiscoveredWorkflow) => void;\n onDelete: (type: string) => void;\n onNavigate: (path: string) => void;\n}) {\n const escRoles = wf.roles ?? [];\n const invokeRoles = wf.invocation_roles ?? [];\n\n return (\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => onRowClick(wf)}\n onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') onRowClick(wf); }}\n className={`group ${ROW_GRID} py-2.5 px-3 -mx-3 rounded-md cursor-pointer transition-colors`}\n >\n {/* Col 1: Workflow name + description */}\n <div className=\"min-w-0\">\n <WorkflowPill\n type={wf.workflow_type}\n size=\"md\"\n variant={wf.tier === 'certified' ? 'certified' : wf.tier === 'registered' ? 'registered' : 'durable'}\n />\n {wf.description && (\n <p className=\"mt-0.5 text-[10px] text-text-tertiary group-hover:text-text-secondary leading-snug line-clamp-2 transition-colors\">\n {wf.description}\n </p>\n )}\n </div>\n\n {/* Col 2: Tier */}\n <div className=\"pt-0.5\">\n <TierBadge tier={wf.tier ?? 'durable'} />\n </div>\n\n {/* Col 3: Access — escalation roles then invocation roles */}\n <div className=\"min-w-0 space-y-1 pt-0.5\">\n {escRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n <span title=\"Escalation roles\"><ShieldCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n {escRoles.map((r) => <RolePill key={`e-${r}`} role={r} />)}\n </div>\n )}\n {invokeRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5 flex-wrap\">\n <span title=\"Invocation roles\"><UserCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n {invokeRoles.map((r) => <RolePill key={`i-${r}`} role={r} />)}\n </div>\n )}\n {escRoles.length === 0 && invokeRoles.length === 0 && (\n <span className=\"text-xs text-text-quaternary\">—</span>\n )}\n </div>\n\n {/* Col 4: Actions — revealed on hover */}\n <div className=\"flex items-center justify-end gap-2.5 pt-0.5 opacity-0 group-hover:opacity-100 transition-opacity\">\n {wf.invocable && (\n <button\n title=\"Invoke workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/start?type=${encodeURIComponent(wf.workflow_type)}&mode=now`); }}\n className=\"text-text-quaternary hover:text-status-success transition-colors\"\n >\n <Play className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.tier === 'durable' && (\n <button\n title=\"Configure workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(wf.workflow_type)}&task_queue=${encodeURIComponent(wf.task_queue ?? '')}`); }}\n className=\"text-text-quaternary hover:text-status-info transition-colors\"\n >\n <Wrench className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.tier === 'registered' && (\n <button\n title=\"Certify workflow\"\n onClick={(e) => { e.stopPropagation(); onNavigate(`/workflows/registry/${encodeURIComponent(wf.workflow_type)}`); }}\n className=\"text-text-quaternary hover:text-status-success transition-colors\"\n >\n <ShieldPlus className=\"w-3.5 h-3.5\" />\n </button>\n )}\n {wf.registered && (\n <button\n title=\"Unregister workflow\"\n onClick={(e) => { e.stopPropagation(); onDelete(wf.workflow_type); }}\n className=\"text-text-quaternary hover:text-status-warning transition-colors\"\n >\n <ShieldOff className=\"w-3.5 h-3.5\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ── Loading skeleton ───────────────────────────────────────────────────────────\n\nfunction LoadingSkeleton() {\n return (\n <div className=\"animate-pulse space-y-8 mt-4\">\n {[1, 2].map((i) => (\n <div key={i}>\n <div className=\"h-4 bg-surface-sunken rounded w-36 mb-4\" />\n <div className=\"space-y-4\">\n {[1, 2, 3].map((j) => (\n <div key={j} className=\"space-y-1.5\">\n <div className=\"h-3 bg-surface-sunken rounded w-48\" />\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n ))}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { User, X, ChevronDown, Check } from 'lucide-react';\nimport { useRoles } from '../../../api/roles';\n\ninterface RolePickerProps {\n selected: string[];\n onChange: (roles: string[]) => void;\n /** Only allow one selection */\n single?: boolean;\n placeholder?: string;\n}\n\nexport function RolePicker({ selected, onChange, single, placeholder }: RolePickerProps) {\n const { data } = useRoles();\n const allRoles = data?.roles ?? [];\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (role: string) => {\n if (single) {\n onChange(selected.includes(role) ? [] : [role]);\n setOpen(false);\n } else {\n onChange(\n selected.includes(role)\n ? selected.filter((r) => r !== role)\n : [...selected, role],\n );\n }\n };\n\n const remove = (role: string) => {\n onChange(selected.filter((r) => r !== role));\n };\n\n const placeholderText = placeholder ?? (single ? 'Select role...' : 'Add roles...');\n\n return (\n <div ref={ref} className=\"relative\">\n {/* Selected pills + trigger */}\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((role) => (\n <span\n key={role}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px]\"\n >\n <User className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {role}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(role); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {/* Dropdown */}\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {allRoles.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No roles defined</p>\n ) : (\n allRoles.map((role) => {\n const isSelected = selected.includes(role);\n return (\n <button\n key={role}\n type=\"button\"\n onClick={() => toggle(role)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <User className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{role}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { Workflow, X, ChevronDown, Check } from 'lucide-react';\n\ninterface WorkflowPickerProps {\n options: string[];\n selected: string[];\n onChange: (workflows: string[]) => void;\n placeholder?: string;\n}\n\nexport function WorkflowPicker({ options, selected, onChange, placeholder }: WorkflowPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (wfType: string) => {\n onChange(\n selected.includes(wfType)\n ? selected.filter((t) => t !== wfType)\n : [...selected, wfType],\n );\n };\n\n const remove = (wfType: string) => {\n onChange(selected.filter((t) => t !== wfType));\n };\n\n const placeholderText = placeholder ?? 'Add workflows...';\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((wfType) => (\n <span\n key={wfType}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px] font-mono\"\n >\n <Workflow className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {wfType}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(wfType); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {options.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No registered workflows</p>\n ) : (\n options.map((wfType) => {\n const isSelected = selected.includes(wfType);\n return (\n <button\n key={wfType}\n type=\"button\"\n onClick={() => toggle(wfType)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs font-mono transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <Workflow className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{wfType}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","export function splitCsv(s: string): string[] {\n return s\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n}\n\nexport function safeParseJson<T = unknown>(\n json: string,\n): { ok: true; data: T } | { ok: false; error: string } {\n try {\n return { ok: true, data: JSON.parse(json) as T };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n return { ok: false, error: message };\n }\n}\n","import type { LTWorkflowConfig } from '../../../api/types';\n\nexport interface ConfigFormState {\n workflow_type: string;\n description: string;\n task_queue: string;\n default_role: string;\n invocable: boolean;\n roles: string;\n invocation_roles: string;\n consumes: string;\n envelope_schema: string;\n resolver_schema: string;\n cron_schedule: string;\n execute_as: string;\n /**\n * Explicit HITL certification, persisted on the registration. Unchecking\n * demotes certified → registered on save and keeps roles/consumes intact.\n */\n certified: boolean;\n}\n\nexport const EMPTY_FORM: ConfigFormState = {\n workflow_type: '',\n description: '',\n task_queue: '',\n default_role: 'reviewer',\n invocable: false,\n roles: '',\n invocation_roles: '',\n consumes: '',\n envelope_schema: '',\n resolver_schema: '',\n cron_schedule: '',\n execute_as: '',\n certified: false,\n};\n\nexport function configToForm(c: LTWorkflowConfig): ConfigFormState {\n const roles = (c.roles ?? []).join(', ');\n const consumes = (c.consumes ?? []).join(', ');\n return {\n workflow_type: c.workflow_type,\n description: c.description ?? '',\n task_queue: c.task_queue ?? '',\n default_role: c.default_role,\n invocable: c.invocable,\n roles,\n invocation_roles: (c.invocation_roles ?? []).join(', '),\n consumes,\n envelope_schema: c.envelope_schema ? JSON.stringify(c.envelope_schema, null, 2) : '',\n resolver_schema: c.resolver_schema ? JSON.stringify(c.resolver_schema, null, 2) : '',\n cron_schedule: c.cron_schedule ?? '',\n execute_as: c.execute_as ?? '',\n certified: c.certified,\n };\n}\n\nexport const STEP_LABELS = ['Identity', 'Invocation', 'Advanced'];\n\nexport function jsonValid(v: string): boolean {\n if (!v.trim()) return true;\n try { JSON.parse(v); return true; } catch { return false; }\n}\n\nexport function isStepValid(step: number, form: ConfigFormState): boolean {\n if (step === 1) return !!form.workflow_type.trim();\n if (step === 2) return jsonValid(form.envelope_schema);\n if (step === 3) return jsonValid(form.resolver_schema);\n return true;\n}\n\nexport const labelCls = 'label';\nexport const hintCls = 'hint';\nexport const jsonCls = 'input-json w-full';\n\nexport const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport {\n Code2, Play, ShieldCheck, ShieldOff,\n} from 'lucide-react';\nimport { useWorkflowConfigs, useUpsertWorkflowConfig, useDeleteWorkflowConfig, useJobs } from '../../../api/workflows';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { WorkflowPicker } from '../../../components/common/form/WorkflowPicker';\nimport { NamespacePill } from '../../../components/common/display/NamespacePill';\nimport { splitCsv } from '../../../lib/parse';\nimport { EMPTY_FORM, configToForm, jsonValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\n\n// ── Local helpers ─────────────────────────────────────────────────────────────\n\nfunction SectionHeader({ icon: Icon, color, children }: { icon: React.ElementType; color: string; children: React.ReactNode }) {\n return (\n <div className=\"flex items-center gap-2 mb-4 pb-2 border-b border-surface-border\">\n <Icon className={`w-4 h-4 ${color}`} strokeWidth={1.5} />\n <h2 className=\"section-h2\">{children}</h2>\n </div>\n );\n}\n\nfunction Field({ label, hint, children }: { label: string; hint?: React.ReactNode; children: React.ReactNode }) {\n return (\n <div className=\"space-y-1.5\">\n <label className=\"label\">{label}</label>\n {children}\n {hint && <p className=\"hint\">{hint}</p>}\n </div>\n );\n}\n\nconst jsonCls = 'input-json w-full';\n\nfunction csvToArray(csv: string): string[] { return splitCsv(csv); }\nfunction arrayToCsv(arr: string[]): string { return arr.join(', '); }\n\nconst SYSTEM_WORKFLOWS = new Set([\n 'mcpQuery', 'mcpDeterministic', 'mcpQueryRouter', 'mcpTriage',\n 'mcpTriageRouter', 'mcpTriageDeterministic', 'insightQuery',\n]);\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigDetailPage() {\n const { workflowType } = useParams<{ workflowType: string }>();\n const isNew = !workflowType;\n const navigate = useNavigate();\n const [searchParams] = useSearchParams();\n const { data: configs, isLoading } = useWorkflowConfigs();\n const upsert = useUpsertWorkflowConfig();\n const deleteConfig = useDeleteWorkflowConfig();\n const [confirmUnregister, setConfirmUnregister] = useState(false);\n\n const editing = configs?.find((c) => c.workflow_type === workflowType) ?? null;\n\n const { data: jobsData } = useJobs({ limit: 500 });\n const unregisteredTypes = useMemo(() => {\n const registeredSet = new Set((configs ?? []).map((c) => c.workflow_type));\n const allEntities = new Set((jobsData?.jobs ?? []).map((j: any) => j.entity));\n return [...allEntities]\n .filter((e: string) => !registeredSet.has(e) && !SYSTEM_WORKFLOWS.has(e))\n .sort();\n }, [configs, jobsData]);\n\n const prefillForm = useMemo((): ConfigFormState => {\n if (!isNew) return EMPTY_FORM;\n const prefillType = searchParams.get('workflow_type') ?? '';\n const prefillQueue = searchParams.get('task_queue') ?? '';\n return prefillType || prefillQueue\n ? { ...EMPTY_FORM, workflow_type: prefillType, task_queue: prefillQueue }\n : EMPTY_FORM;\n }, [isNew, searchParams]);\n\n const [form, setForm] = useState<ConfigFormState>(prefillForm);\n const [schemaError, setSchemaError] = useState('');\n const [initialized, setInitialized] = useState(false);\n\n const set = useCallback(\n (field: keyof ConfigFormState, value: string | boolean) =>\n setForm((f) => ({ ...f, [field]: value })),\n [],\n );\n\n useEffect(() => {\n if (initialized) return;\n if (isNew) { setForm(prefillForm); setInitialized(true); return; }\n if (editing) { setForm(configToForm(editing)); setInitialized(true); }\n }, [editing, isNew, initialized, prefillForm]);\n\n const handleSave = () => {\n if (!form.workflow_type.trim()) return;\n setSchemaError('');\n\n let envelope_schema: Record<string, unknown> | null = null;\n let resolver_schema: Record<string, unknown> | null = null;\n try {\n if (form.envelope_schema.trim()) envelope_schema = JSON.parse(form.envelope_schema);\n } catch { setSchemaError('Invalid JSON in Envelope Schema'); return; }\n try {\n if (form.resolver_schema.trim()) resolver_schema = JSON.parse(form.resolver_schema);\n } catch { setSchemaError('Invalid JSON in Resolver Schema'); return; }\n\n upsert.mutate(\n {\n workflow_type: form.workflow_type.trim(),\n description: form.description.trim() || null,\n task_queue: form.task_queue.trim() || null,\n default_role: form.default_role.trim() || 'reviewer',\n invocable: form.invocable,\n certified: form.certified,\n roles: splitCsv(form.roles),\n invocation_roles: splitCsv(form.invocation_roles),\n consumes: splitCsv(form.consumes),\n envelope_schema,\n resolver_schema,\n cron_schedule: form.cron_schedule.trim() || null,\n execute_as: form.execute_as.trim() || null,\n },\n { onSuccess: () => navigate('/workflows/registry') },\n );\n };\n\n if (isLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-64\" />\n <div className=\"h-40 bg-surface-sunken rounded\" />\n </div>\n );\n }\n if (!isNew && !editing) {\n return <p className=\"text-sm text-text-secondary\">Config not found.</p>;\n }\n\n const canSave = !!form.workflow_type.trim() && jsonValid(form.envelope_schema) && jsonValid(form.resolver_schema);\n const showPickList = isNew && !form.workflow_type && unregisteredTypes.length > 0;\n\n return (\n <div>\n {/* Hero */}\n <div className=\"flex items-start justify-between mb-8\">\n <div>\n <h1 className=\"text-3xl font-light font-mono text-text-primary\">\n {isNew ? 'New Workflow' : editing?.workflow_type ?? ''}\n </h1>\n {editing && (\n <div className=\"flex items-center gap-2 mt-2\">\n <NamespacePill namespace=\"durable\" />\n </div>\n )}\n </div>\n <div className=\"flex items-center gap-3 mt-1\">\n <button onClick={() => navigate('/workflows/registry')} className=\"btn-ghost text-xs\">\n Cancel\n </button>\n <button\n onClick={handleSave}\n disabled={!canSave || upsert.isPending}\n className=\"btn-primary text-xs\"\n >\n {upsert.isPending ? 'Saving…' : isNew ? 'Register' : 'Save'}\n </button>\n </div>\n </div>\n\n {/* Three-column form */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-x-14 gap-y-10\">\n\n {/* ── Identity ─────────────────────────────────────────────────── */}\n <div>\n <SectionHeader icon={Code2} color=\"text-accent\">Identity</SectionHeader>\n <div className=\"space-y-5\">\n <Field\n label=\"Workflow Type\"\n hint=\"Register a workflow to configure invocation and HITL escalation routing.\"\n >\n {showPickList ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-text-secondary\">Select a durable workflow to register:</p>\n <div className=\"grid gap-1\">\n {(unregisteredTypes as string[]).map((type) => (\n <button\n key={type}\n onClick={() => set('workflow_type', type)}\n className=\"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors\"\n >\n {type}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-2 pt-1\">\n <span className=\"text-[10px] text-text-tertiary\">or</span>\n <input\n type=\"text\"\n onChange={(e) => set('workflow_type', e.target.value)}\n placeholder=\"Enter type manually\"\n className=\"input font-mono flex-1\"\n />\n </div>\n </div>\n ) : (\n <>\n <input\n type=\"text\"\n value={form.workflow_type}\n onChange={(e) => set('workflow_type', e.target.value)}\n disabled={!isNew}\n placeholder=\"reviewContent\"\n className=\"input font-mono w-full\"\n />\n {isNew && form.workflow_type && unregisteredTypes.length > 0 && (\n <button\n onClick={() => set('workflow_type', '')}\n className=\"text-[10px] text-accent hover:underline mt-1\"\n >\n Choose from durable workflows\n </button>\n )}\n </>\n )}\n </Field>\n\n <Field label=\"Description\">\n <input\n type=\"text\"\n value={form.description}\n onChange={(e) => set('description', e.target.value)}\n placeholder=\"Describe what this workflow does\"\n className=\"input text-xs w-full\"\n />\n </Field>\n\n <Field label=\"Task Queue\" hint=\"Durable task queue this workflow listens on.\">\n <input\n type=\"text\"\n value={form.task_queue}\n onChange={(e) => set('task_queue', e.target.value)}\n placeholder=\"lt-review\"\n className=\"input font-mono w-full\"\n />\n </Field>\n </div>\n </div>\n\n {/* ── Invocation ───────────────────────────────────────────────── */}\n <div>\n <SectionHeader icon={Play} color=\"text-emerald-400\">Invocation</SectionHeader>\n <div className=\"space-y-5\">\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.invocable}\n onChange={(e) => set('invocable', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Invocable</span>\n </label>\n <p className=\"hint\">Allow this workflow to be started from the dashboard or API.</p>\n </div>\n\n {form.invocable ? (\n <>\n <Field label=\"Run As\" hint=\"Bot identity to run under. Default runs as the invoking user.\">\n <BotPicker selected={form.execute_as} onChange={(id) => set('execute_as', id)} />\n </Field>\n\n <Field label=\"Invocation Roles\" hint=\"Only users with these roles can start this workflow. Empty = all authenticated users.\">\n <RolePicker\n selected={csvToArray(form.invocation_roles)}\n onChange={(roles) => set('invocation_roles', arrayToCsv(roles))}\n placeholder=\"Select roles…\"\n />\n </Field>\n\n <Field label=\"Envelope Schema\" hint={<>Pre-fills the JSON editor when invoking. Include <code className=\"font-mono\">data</code> (input) and optional <code className=\"font-mono\">metadata</code>.</>}>\n <textarea\n value={form.envelope_schema}\n onChange={(e) => set('envelope_schema', e.target.value)}\n placeholder={'{\\n \"data\": {},\\n \"metadata\": {}\\n}'}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n {form.envelope_schema.trim() && !jsonValid(form.envelope_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </Field>\n </>\n ) : (\n <p className=\"text-[11px] text-text-tertiary py-2\">\n Enable <span className=\"font-medium text-text-secondary\">Invocable</span> to configure invocation roles and an input template.\n </p>\n )}\n </div>\n </div>\n\n {/* ── Certification ────────────────────────────────────────────── */}\n <div>\n <SectionHeader icon={ShieldCheck} color=\"text-violet-400\">Certification</SectionHeader>\n <div className=\"space-y-5\">\n <Field\n label=\"Resolver Schema\"\n hint={<>Default form for resolving escalations. Use <code className=\"font-mono\">properties</code> with <code className=\"font-mono\">type</code>, <code className=\"font-mono\">default</code>, <code className=\"font-mono\">description</code>.</>}\n >\n <textarea\n value={form.resolver_schema}\n onChange={(e) => set('resolver_schema', e.target.value)}\n placeholder={'{\\n \"properties\": {\\n \"approved\": { \"type\": \"boolean\", \"default\": false }\\n }\\n}'}\n className={jsonCls}\n rows={6}\n spellCheck={false}\n />\n {form.resolver_schema.trim() && !jsonValid(form.resolver_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </Field>\n\n <div className=\"space-y-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.certified}\n onChange={(e) => set('certified', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Certify for HITL Escalation</span>\n </label>\n <p className=\"hint\">\n Certified workflows use the interceptor — failures escalate to human reviewers.\n Unchecking demotes this workflow to registered on save; escalation roles and\n dependencies below are kept.\n </p>\n </div>\n\n {form.certified ? (\n <>\n <Field label=\"Default Escalation Role\" hint=\"The role surface interceptor-raised escalations target.\">\n <RolePicker\n selected={csvToArray(form.default_role)}\n onChange={(roles) => set('default_role', roles[0] ?? '')}\n single\n placeholder=\"Select role…\"\n />\n </Field>\n\n <Field\n label=\"Escalation Roles\"\n hint=\"Interceptor default for who can claim and resolve. Escalations raised in workflow code choose their own role, whose versioned schema takes precedence.\"\n >\n <RolePicker\n selected={csvToArray(form.roles)}\n onChange={(roles) => set('roles', arrayToCsv(roles))}\n placeholder=\"Select roles…\"\n />\n </Field>\n\n <Field label=\"Consumes\" hint=\"Upstream workflows whose output is injected into this workflow's envelope.\">\n <WorkflowPicker\n options={(configs ?? [])\n .map((c) => c.workflow_type)\n .filter((t) => t !== form.workflow_type)}\n selected={csvToArray(form.consumes)}\n onChange={(workflows) => set('consumes', arrayToCsv(workflows))}\n placeholder=\"Select dependencies…\"\n />\n </Field>\n </>\n ) : (\n <p className=\"text-[11px] text-text-tertiary py-2\">\n Enable <span className=\"font-medium text-text-secondary\">Certify</span> to add automatic escalation routing and role-based resolution.\n </p>\n )}\n\n {editing && (\n <div className=\"pt-4 border-t border-surface-border/50\">\n <button\n onClick={() => setConfirmUnregister(true)}\n className=\"flex items-center gap-1.5 text-[11px] text-status-warning hover:underline\"\n title=\"Delete this registration — the workflow returns to plain durable\"\n >\n <ShieldOff className=\"w-3 h-3\" /> Unregister workflow\n </button>\n </div>\n )}\n </div>\n </div>\n </div>\n\n {(schemaError || upsert.error) && (\n <p className=\"text-xs text-status-error mt-8\">\n {schemaError || (upsert.error as Error).message}\n </p>\n )}\n\n <ConfirmDeleteModal\n open={confirmUnregister}\n onClose={() => setConfirmUnregister(false)}\n onConfirm={() =>\n deleteConfig.mutate(editing!.workflow_type, {\n onSuccess: () => navigate('/workflows/registry'),\n })\n }\n title=\"Unregister Workflow\"\n description={\n <>\n Delete the registration for{' '}\n <span className=\"font-mono font-medium text-text-primary\">{editing?.workflow_type}</span>?\n This removes its invocation settings, certification, and interceptor treatment; the\n workflow keeps running as a plain durable workflow. Escalation schemas versioned on\n roles are untouched.\n </>\n }\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n"],"names":["TierBadge","tier","jsxs","jsx","ShieldCheck","Settings","Wrench","WorkflowConfigsPage","navigate","useNavigate","data","isLoading","useDiscoveredWorkflows","deleteConfig","useDeleteWorkflowConfig","search","setSearch","useState","activeQueue","setActiveQueue","confirmDelete","setConfirmDelete","allWorkflows","queues","useMemo","w","grouped","q","queue","_a","g","ungrouped","handleRowClick","row","handleDelete","PageHeader","LayoutGrid","isActive","label","Server","Search","e","LoadingSkeleton","workflows","WorkflowTableHeader","wf","WorkflowRow","ConfirmDeleteModal","Fragment","ROW_GRID","onRowClick","onDelete","onNavigate","escRoles","invokeRoles","WorkflowPill","r","RolePill","UserCheck","Play","ShieldPlus","ShieldOff","i","j","RolePicker","selected","onChange","single","placeholder","useRoles","allRoles","open","setOpen","ref","useRef","useEffect","handler","toggle","role","remove","placeholderText","User","X","ChevronDown","isSelected","Check","WorkflowPicker","options","wfType","t","Workflow","splitCsv","s","v","EMPTY_FORM","configToForm","c","roles","consumes","jsonValid","SectionHeader","Icon","color","children","Field","hint","jsonCls","csvToArray","csv","arrayToCsv","arr","SYSTEM_WORKFLOWS","WorkflowConfigDetailPage","workflowType","useParams","isNew","searchParams","useSearchParams","configs","useWorkflowConfigs","upsert","useUpsertWorkflowConfig","confirmUnregister","setConfirmUnregister","editing","jobsData","useJobs","unregisteredTypes","registeredSet","prefillForm","prefillType","prefillQueue","form","setForm","schemaError","setSchemaError","initialized","setInitialized","set","useCallback","field","value","f","handleSave","envelope_schema","resolver_schema","canSave","showPickList","NamespacePill","Code2","type","BotPicker","id"],"mappings":"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"}