@hotmeshio/long-tail 0.4.3 → 0.4.4

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 (244) hide show
  1. package/build/api/settings.js +4 -0
  2. package/build/lib/db/index.d.ts +1 -7
  3. package/build/lib/db/schemas/008_capability_reaction.sql +12 -0
  4. package/build/lib/db/schemas/009_file_topic_category.sql +10 -0
  5. package/build/lib/events/index.d.ts +9 -0
  6. package/build/lib/events/index.js +15 -0
  7. package/build/lib/events/nats.d.ts +15 -1
  8. package/build/lib/events/nats.js +44 -2
  9. package/build/lib/events/publish.d.ts +10 -0
  10. package/build/lib/events/publish.js +28 -0
  11. package/build/modules/config.d.ts +1 -7
  12. package/build/services/agent/subscription-sql.d.ts +3 -3
  13. package/build/services/agent/subscription-sql.js +7 -5
  14. package/build/services/agent/subscriptions.d.ts +3 -1
  15. package/build/services/agent/subscriptions.js +6 -0
  16. package/build/services/agent/trigger-registry.js +18 -0
  17. package/build/services/topics/system-topics.js +29 -0
  18. package/build/services/yaml-workflow/deployer.d.ts +1 -1
  19. package/build/services/yaml-workflow/deployer.js +2 -2
  20. package/build/services/yaml-workflow/invoke.d.ts +2 -0
  21. package/build/services/yaml-workflow/invoke.js +5 -1
  22. package/build/start/adapters.js +11 -9
  23. package/build/start/config.js +4 -0
  24. package/build/start/workers.js +12 -3
  25. package/build/system/index.js +16 -0
  26. package/build/system/mcp-servers/file-storage.js +18 -0
  27. package/build/system/workflows/capability-invoke/activities.d.ts +12 -0
  28. package/build/system/workflows/capability-invoke/activities.js +14 -0
  29. package/build/system/workflows/capability-invoke/index.d.ts +14 -0
  30. package/build/system/workflows/capability-invoke/index.js +74 -0
  31. package/build/tsconfig.tsbuildinfo +1 -1
  32. package/build/types/events.d.ts +13 -1
  33. package/build/types/startup.d.ts +7 -0
  34. package/dashboard/dist/assets/{AdminDashboard-Dr5wTIZT.js → AdminDashboard-DISq0Tz8.js} +2 -2
  35. package/dashboard/dist/assets/{AdminDashboard-Dr5wTIZT.js.map → AdminDashboard-DISq0Tz8.js.map} +1 -1
  36. package/dashboard/dist/assets/AgentConfigPage-DqaJpB3K.js +16 -0
  37. package/dashboard/dist/assets/AgentConfigPage-DqaJpB3K.js.map +1 -0
  38. package/dashboard/dist/assets/AgentDetailPage-BPzPk2GC.js +4 -0
  39. package/dashboard/dist/assets/AgentDetailPage-BPzPk2GC.js.map +1 -0
  40. package/dashboard/dist/assets/AgentsPage-CLcxJWjC.js +2 -0
  41. package/dashboard/dist/assets/AgentsPage-CLcxJWjC.js.map +1 -0
  42. package/dashboard/dist/assets/AvailableEscalationsPage-hOcjAAIj.js +2 -0
  43. package/dashboard/dist/assets/{AvailableEscalationsPage-UzjXcO3W.js.map → AvailableEscalationsPage-hOcjAAIj.js.map} +1 -1
  44. package/dashboard/dist/assets/{BotPicker-CM-_u73k.js → BotPicker-DuAZgHbJ.js} +2 -2
  45. package/dashboard/dist/assets/{BotPicker-CM-_u73k.js.map → BotPicker-DuAZgHbJ.js.map} +1 -1
  46. package/dashboard/dist/assets/CapabilitiesPage-PRel6TXd.js +2 -0
  47. package/dashboard/dist/assets/CapabilitiesPage-PRel6TXd.js.map +1 -0
  48. package/dashboard/dist/assets/{CollapsibleSection-CnPKa7df.js → CollapsibleSection-DnoUFQVf.js} +2 -2
  49. package/dashboard/dist/assets/{CollapsibleSection-CnPKa7df.js.map → CollapsibleSection-DnoUFQVf.js.map} +1 -1
  50. package/dashboard/dist/assets/CopyableId-D0SQ39nR.js +2 -0
  51. package/dashboard/dist/assets/CopyableId-D0SQ39nR.js.map +1 -0
  52. package/dashboard/dist/assets/{CredentialsPage-CImIzra4.js → CredentialsPage-CqedUU7b.js} +2 -2
  53. package/dashboard/dist/assets/{CredentialsPage-CImIzra4.js.map → CredentialsPage-CqedUU7b.js.map} +1 -1
  54. package/dashboard/dist/assets/{CronLabel-5HPAmciI.js → CronLabel-CPEjE-mH.js} +2 -2
  55. package/dashboard/dist/assets/CronLabel-CPEjE-mH.js.map +1 -0
  56. package/dashboard/dist/assets/CustomDurationPicker-BIQWzbv0.js +2 -0
  57. package/dashboard/dist/assets/{CustomDurationPicker-5JzEgS7I.js.map → CustomDurationPicker-BIQWzbv0.js.map} +1 -1
  58. package/dashboard/dist/assets/{DropZone-BEW3jBzf.js → DropZone-e5EOL5gC.js} +2 -2
  59. package/dashboard/dist/assets/{DropZone-BEW3jBzf.js.map → DropZone-e5EOL5gC.js.map} +1 -1
  60. package/dashboard/dist/assets/ElapsedCell-CzVjr74Y.js +2 -0
  61. package/dashboard/dist/assets/{ElapsedCell-B79BF5Mj.js.map → ElapsedCell-CzVjr74Y.js.map} +1 -1
  62. package/dashboard/dist/assets/{EscalationsOverview-QvWvbpx3.js → EscalationsOverview-Bcrb44xJ.js} +2 -2
  63. package/dashboard/dist/assets/{EscalationsOverview-QvWvbpx3.js.map → EscalationsOverview-Bcrb44xJ.js.map} +1 -1
  64. package/dashboard/dist/assets/{EventTable-DAclQwfr.js → EventTable-CGfJU7e1.js} +2 -2
  65. package/dashboard/dist/assets/{EventTable-DAclQwfr.js.map → EventTable-CGfJU7e1.js.map} +1 -1
  66. package/dashboard/dist/assets/{EventTopicPill-By-6sXDp.js → EventTopicPill-xJJnxvlP.js} +2 -2
  67. package/dashboard/dist/assets/{EventTopicPill-By-6sXDp.js.map → EventTopicPill-xJJnxvlP.js.map} +1 -1
  68. package/dashboard/dist/assets/{HomePage-DVOi7rR1.js → HomePage-BIzUcGW9.js} +2 -2
  69. package/dashboard/dist/assets/{HomePage-DVOi7rR1.js.map → HomePage-BIzUcGW9.js.map} +1 -1
  70. package/dashboard/dist/assets/{ListToolbar-Bntl2hex.js → ListToolbar-DNAGFe14.js} +2 -2
  71. package/dashboard/dist/assets/{ListToolbar-Bntl2hex.js.map → ListToolbar-DNAGFe14.js.map} +1 -1
  72. package/dashboard/dist/assets/{McpOverview-B-xSYPJj.js → McpOverview-BpYk21es.js} +2 -2
  73. package/dashboard/dist/assets/{McpOverview-B-xSYPJj.js.map → McpOverview-BpYk21es.js.map} +1 -1
  74. package/dashboard/dist/assets/{McpQueryDetailPage-Cq71BzjB.js → McpQueryDetailPage-DlrZiSuL.js} +2 -2
  75. package/dashboard/dist/assets/{McpQueryDetailPage-Cq71BzjB.js.map → McpQueryDetailPage-DlrZiSuL.js.map} +1 -1
  76. package/dashboard/dist/assets/{McpQueryPage-Dfz87aZF.js → McpQueryPage-COfPssO7.js} +2 -2
  77. package/dashboard/dist/assets/{McpQueryPage-Dfz87aZF.js.map → McpQueryPage-COfPssO7.js.map} +1 -1
  78. package/dashboard/dist/assets/McpRunDetailPage-Cra0nQSw.js +2 -0
  79. package/dashboard/dist/assets/McpRunDetailPage-Cra0nQSw.js.map +1 -0
  80. package/dashboard/dist/assets/{McpRunsPage-MUYvUYqz.js → McpRunsPage-BlgcGN3k.js} +2 -2
  81. package/dashboard/dist/assets/{McpRunsPage-MUYvUYqz.js.map → McpRunsPage-BlgcGN3k.js.map} +1 -1
  82. package/dashboard/dist/assets/{OperatorDashboard-Rih1SZrn.js → OperatorDashboard-BbO6cWzb.js} +2 -2
  83. package/dashboard/dist/assets/{OperatorDashboard-Rih1SZrn.js.map → OperatorDashboard-BbO6cWzb.js.map} +1 -1
  84. package/dashboard/dist/assets/{PageHeader-Bo0SpcCK.js → PageHeader-B_gV_jKk.js} +2 -2
  85. package/dashboard/dist/assets/{PageHeader-Bo0SpcCK.js.map → PageHeader-B_gV_jKk.js.map} +1 -1
  86. package/dashboard/dist/assets/{PageHeaderWithStats-7K5BdhOj.js → PageHeaderWithStats-D0I0nrnx.js} +2 -2
  87. package/dashboard/dist/assets/{PageHeaderWithStats-7K5BdhOj.js.map → PageHeaderWithStats-D0I0nrnx.js.map} +1 -1
  88. package/dashboard/dist/assets/ProcessDetailPage-s_iV8ICg.js +2 -0
  89. package/dashboard/dist/assets/{ProcessDetailPage-BMkWCjqD.js.map → ProcessDetailPage-s_iV8ICg.js.map} +1 -1
  90. package/dashboard/dist/assets/{ProcessesListPage-vZjUSc7S.js → ProcessesListPage-MnLMnxAa.js} +2 -2
  91. package/dashboard/dist/assets/{ProcessesListPage-vZjUSc7S.js.map → ProcessesListPage-MnLMnxAa.js.map} +1 -1
  92. package/dashboard/dist/assets/{RolePill-BDzPFQUv.js → RolePill-BOBytzrP.js} +2 -2
  93. package/dashboard/dist/assets/{RolePill-BDzPFQUv.js.map → RolePill-BOBytzrP.js.map} +1 -1
  94. package/dashboard/dist/assets/{RolesPage-kjeAsj3_.js → RolesPage-BH7KASM7.js} +2 -2
  95. package/dashboard/dist/assets/{RolesPage-kjeAsj3_.js.map → RolesPage-BH7KASM7.js.map} +1 -1
  96. package/dashboard/dist/assets/{RunAsSelector-DC4SLtTq.js → RunAsSelector-_QbJKhlo.js} +2 -2
  97. package/dashboard/dist/assets/{RunAsSelector-DC4SLtTq.js.map → RunAsSelector-_QbJKhlo.js.map} +1 -1
  98. package/dashboard/dist/assets/{ServerName-CEOFF7UG.js → ServerName-uqa4eBqm.js} +2 -2
  99. package/dashboard/dist/assets/{ServerName-CEOFF7UG.js.map → ServerName-uqa4eBqm.js.map} +1 -1
  100. package/dashboard/dist/assets/SwimlaneTimeline-og79Llvs.js +2 -0
  101. package/dashboard/dist/assets/SwimlaneTimeline-og79Llvs.js.map +1 -0
  102. package/dashboard/dist/assets/{TagInput-VBY0xIwb.js → TagInput-D3f11sbM.js} +2 -2
  103. package/dashboard/dist/assets/{TagInput-VBY0xIwb.js.map → TagInput-D3f11sbM.js.map} +1 -1
  104. package/dashboard/dist/assets/{TaskDetailPage-C0AlG_2t.js → TaskDetailPage-DPV4ySd9.js} +2 -2
  105. package/dashboard/dist/assets/{TaskDetailPage-C0AlG_2t.js.map → TaskDetailPage-DPV4ySd9.js.map} +1 -1
  106. package/dashboard/dist/assets/{TaskQueuePill-DZykFijh.js → TaskQueuePill-Bc45J7X1.js} +2 -2
  107. package/dashboard/dist/assets/{TaskQueuePill-DZykFijh.js.map → TaskQueuePill-Bc45J7X1.js.map} +1 -1
  108. package/dashboard/dist/assets/{TasksListPage-69ZWCaCP.js → TasksListPage-BYj3OqUi.js} +2 -2
  109. package/dashboard/dist/assets/{TasksListPage-69ZWCaCP.js.map → TasksListPage-BYj3OqUi.js.map} +1 -1
  110. package/dashboard/dist/assets/TimeAgo-W7TdJpV-.js +2 -0
  111. package/dashboard/dist/assets/{TimeAgo-CttiZG0k.js.map → TimeAgo-W7TdJpV-.js.map} +1 -1
  112. package/dashboard/dist/assets/{TimestampCell-CYFbEhqc.js → TimestampCell-Bi2nc9Q_.js} +2 -2
  113. package/dashboard/dist/assets/{TimestampCell-CYFbEhqc.js.map → TimestampCell-Bi2nc9Q_.js.map} +1 -1
  114. package/dashboard/dist/assets/{ToolPill-RP2Tvlrx.js → ToolPill-CuoXcmhv.js} +2 -2
  115. package/dashboard/dist/assets/{ToolPill-RP2Tvlrx.js.map → ToolPill-CuoXcmhv.js.map} +1 -1
  116. package/dashboard/dist/assets/ToolTestPanel-Dl3C53zb.js +2 -0
  117. package/dashboard/dist/assets/ToolTestPanel-Dl3C53zb.js.map +1 -0
  118. package/dashboard/dist/assets/{TopicDetailPage-Aq4-6GLl.js → TopicDetailPage-CjaZn4WP.js} +2 -2
  119. package/dashboard/dist/assets/{TopicDetailPage-Aq4-6GLl.js.map → TopicDetailPage-CjaZn4WP.js.map} +1 -1
  120. package/dashboard/dist/assets/{TopicsPage-BYFKjRY_.js → TopicsPage-BfsJEC1p.js} +2 -2
  121. package/dashboard/dist/assets/{TopicsPage-BYFKjRY_.js.map → TopicsPage-BfsJEC1p.js.map} +1 -1
  122. package/dashboard/dist/assets/{UserName-C4_T5-rI.js → UserName-b4baWHM_.js} +2 -2
  123. package/dashboard/dist/assets/{UserName-C4_T5-rI.js.map → UserName-b4baWHM_.js.map} +1 -1
  124. package/dashboard/dist/assets/WorkflowExecutionPage-BGmJnXnk.js +2 -0
  125. package/dashboard/dist/assets/WorkflowExecutionPage-BGmJnXnk.js.map +1 -0
  126. package/dashboard/dist/assets/WorkflowPill-Bg2-0Hkg.js +2 -0
  127. package/dashboard/dist/assets/WorkflowPill-Bg2-0Hkg.js.map +1 -0
  128. package/dashboard/dist/assets/{WorkflowsDashboard-_LMWc-OC.js → WorkflowsDashboard-BzH7jMRu.js} +2 -2
  129. package/dashboard/dist/assets/{WorkflowsDashboard-_LMWc-OC.js.map → WorkflowsDashboard-BzH7jMRu.js.map} +1 -1
  130. package/dashboard/dist/assets/{WorkflowsOverview-DFrfw554.js → WorkflowsOverview-BcUgBvjD.js} +2 -2
  131. package/dashboard/dist/assets/{WorkflowsOverview-DFrfw554.js.map → WorkflowsOverview-BcUgBvjD.js.map} +1 -1
  132. package/dashboard/dist/assets/{YamlWorkflowsPage-CZzGwfol.js → YamlWorkflowsPage-OhpCQJ0l.js} +2 -2
  133. package/dashboard/dist/assets/{YamlWorkflowsPage-CZzGwfol.js.map → YamlWorkflowsPage-OhpCQJ0l.js.map} +1 -1
  134. package/dashboard/dist/assets/{agents-CsKILVSU.js → agents-Ce3HmPz4.js} +2 -2
  135. package/dashboard/dist/assets/{agents-CsKILVSU.js.map → agents-Ce3HmPz4.js.map} +1 -1
  136. package/dashboard/dist/assets/{bots-BzEs6Q9L.js → bots-B0BomNnf.js} +2 -2
  137. package/dashboard/dist/assets/{bots-BzEs6Q9L.js.map → bots-B0BomNnf.js.map} +1 -1
  138. package/dashboard/dist/assets/capabilities-t-w5N9K9.js +2 -0
  139. package/dashboard/dist/assets/capabilities-t-w5N9K9.js.map +1 -0
  140. package/dashboard/dist/assets/{controlplane-COYEIIAz.js → controlplane-BrtAZnJM.js} +2 -2
  141. package/dashboard/dist/assets/{controlplane-COYEIIAz.js.map → controlplane-BrtAZnJM.js.map} +1 -1
  142. package/dashboard/dist/assets/{escalation-BZjS2202.js → escalation-DilnDxw2.js} +2 -2
  143. package/dashboard/dist/assets/{escalation-BZjS2202.js.map → escalation-DilnDxw2.js.map} +1 -1
  144. package/dashboard/dist/assets/{escalation-columns-DtRVmPSB.js → escalation-columns-C0slywOY.js} +2 -2
  145. package/dashboard/dist/assets/{escalation-columns-DtRVmPSB.js.map → escalation-columns-C0slywOY.js.map} +1 -1
  146. package/dashboard/dist/assets/{helpers-BngVEys5.js → helpers-BMvPqQr8.js} +2 -2
  147. package/dashboard/dist/assets/{helpers-BngVEys5.js.map → helpers-BMvPqQr8.js.map} +1 -1
  148. package/dashboard/dist/assets/{index-DxMNiFPS.js → index-30-pN97P.js} +2 -2
  149. package/dashboard/dist/assets/{index-DxMNiFPS.js.map → index-30-pN97P.js.map} +1 -1
  150. package/dashboard/dist/assets/index-BPxglOYm.css +1 -0
  151. package/dashboard/dist/assets/{index-R61-yG56.js → index-Bl9wzQ8Q.js} +2 -2
  152. package/dashboard/dist/assets/{index-R61-yG56.js.map → index-Bl9wzQ8Q.js.map} +1 -1
  153. package/dashboard/dist/assets/{index-ABsZZf_U.js → index-BxOuF0hm.js} +2 -2
  154. package/dashboard/dist/assets/{index-ABsZZf_U.js.map → index-BxOuF0hm.js.map} +1 -1
  155. package/dashboard/dist/assets/{index-BCsShN2l.js → index-Ck2QdJXT.js} +2 -2
  156. package/dashboard/dist/assets/{index-BCsShN2l.js.map → index-Ck2QdJXT.js.map} +1 -1
  157. package/dashboard/dist/assets/{index-xgl431mG.js → index-DNmlrCAp.js} +2 -2
  158. package/dashboard/dist/assets/{index-xgl431mG.js.map → index-DNmlrCAp.js.map} +1 -1
  159. package/dashboard/dist/assets/index-DPW_i3fH.js +6 -0
  160. package/dashboard/dist/assets/index-DPW_i3fH.js.map +1 -0
  161. package/dashboard/dist/assets/{index-DcpCR9c_.js → index-DZX-E_3q.js} +24 -24
  162. package/dashboard/dist/assets/index-DZX-E_3q.js.map +1 -0
  163. package/dashboard/dist/assets/{index-DykjJxzr.js → index-D_wqdvG_.js} +2 -2
  164. package/dashboard/dist/assets/{index-DykjJxzr.js.map → index-D_wqdvG_.js.map} +1 -1
  165. package/dashboard/dist/assets/{index-Bq5MSkCL.js → index-DnsVYMMg.js} +2 -2
  166. package/dashboard/dist/assets/{index-Bq5MSkCL.js.map → index-DnsVYMMg.js.map} +1 -1
  167. package/dashboard/dist/assets/{index-BwivT39P.js → index-H5TlloTk.js} +2 -2
  168. package/dashboard/dist/assets/{index-BwivT39P.js.map → index-H5TlloTk.js.map} +1 -1
  169. package/dashboard/dist/assets/{index-ByxH4qQ-.js → index-f-0Duls3.js} +2 -2
  170. package/dashboard/dist/assets/{index-ByxH4qQ-.js.map → index-f-0Duls3.js.map} +1 -1
  171. package/dashboard/dist/assets/{index-COgyD_H2.js → index-pIMl0mYp.js} +2 -2
  172. package/dashboard/dist/assets/{index-COgyD_H2.js.map → index-pIMl0mYp.js.map} +1 -1
  173. package/dashboard/dist/assets/{index-Byp8BDPs.js → index-qNuxC8kX.js} +2 -2
  174. package/dashboard/dist/assets/{index-Byp8BDPs.js.map → index-qNuxC8kX.js.map} +1 -1
  175. package/dashboard/dist/assets/{knowledge-DhCbDgy4.js → knowledge-D01NdF5h.js} +2 -2
  176. package/dashboard/dist/assets/{knowledge-DhCbDgy4.js.map → knowledge-D01NdF5h.js.map} +1 -1
  177. package/dashboard/dist/assets/{mcp-xh7T0I-f.js → mcp-CjXjDZI0.js} +2 -2
  178. package/dashboard/dist/assets/{mcp-xh7T0I-f.js.map → mcp-CjXjDZI0.js.map} +1 -1
  179. package/dashboard/dist/assets/{mcp-query-il3CfU3U.js → mcp-query-LlKQcWLJ.js} +2 -2
  180. package/dashboard/dist/assets/{mcp-query-il3CfU3U.js.map → mcp-query-LlKQcWLJ.js.map} +1 -1
  181. package/dashboard/dist/assets/{mcp-runs-4fyRpegc.js → mcp-runs-C0C54hU6.js} +2 -2
  182. package/dashboard/dist/assets/{mcp-runs-4fyRpegc.js.map → mcp-runs-C0C54hU6.js.map} +1 -1
  183. package/dashboard/dist/assets/{namespaces-BBTvHnRF.js → namespaces-6qWDXXJV.js} +2 -2
  184. package/dashboard/dist/assets/{namespaces-BBTvHnRF.js.map → namespaces-6qWDXXJV.js.map} +1 -1
  185. package/dashboard/dist/assets/{roles-D7bx5FAM.js → roles-Dtj0uabn.js} +2 -2
  186. package/dashboard/dist/assets/{roles-D7bx5FAM.js.map → roles-Dtj0uabn.js.map} +1 -1
  187. package/dashboard/dist/assets/{tasks-BgxRbhVM.js → tasks-BevFBjZq.js} +2 -2
  188. package/dashboard/dist/assets/{tasks-BgxRbhVM.js.map → tasks-BevFBjZq.js.map} +1 -1
  189. package/dashboard/dist/assets/{topics-CTtCboHe.js → topics-BMG5tx2g.js} +2 -2
  190. package/dashboard/dist/assets/{topics-CTtCboHe.js.map → topics-BMG5tx2g.js.map} +1 -1
  191. package/dashboard/dist/assets/useEventHooks-CPyvFlVR.js +2 -0
  192. package/dashboard/dist/assets/useEventHooks-CPyvFlVR.js.map +1 -0
  193. package/dashboard/dist/assets/{useYamlActivityEvents-CSMX9He5.js → useYamlActivityEvents-Bll8NPNQ.js} +2 -2
  194. package/dashboard/dist/assets/{useYamlActivityEvents-CSMX9He5.js.map → useYamlActivityEvents-Bll8NPNQ.js.map} +1 -1
  195. package/dashboard/dist/assets/{users-CyF-5WLI.js → users-XZ349b0r.js} +2 -2
  196. package/dashboard/dist/assets/{users-CyF-5WLI.js.map → users-XZ349b0r.js.map} +1 -1
  197. package/dashboard/dist/assets/{vendor-icons-BNtvBbnj.js → vendor-icons-B_Yla7iD.js} +2 -2
  198. package/dashboard/dist/assets/{vendor-icons-BNtvBbnj.js.map → vendor-icons-B_Yla7iD.js.map} +1 -1
  199. package/dashboard/dist/assets/{workflows-Bf4_w24H.js → workflows-Do-Eiv8f.js} +2 -2
  200. package/dashboard/dist/assets/{workflows-Bf4_w24H.js.map → workflows-Do-Eiv8f.js.map} +1 -1
  201. package/dashboard/dist/assets/{yaml-workflows-Cp1N0NMK.js → yaml-workflows-DolGRQ5f.js} +2 -2
  202. package/dashboard/dist/assets/{yaml-workflows-Cp1N0NMK.js.map → yaml-workflows-DolGRQ5f.js.map} +1 -1
  203. package/dashboard/dist/index.html +3 -3
  204. package/docs/agents.md +9 -9
  205. package/docs/api/http/agents.md +12 -10
  206. package/docs/api/http/settings.md +4 -0
  207. package/docs/api/sdk/agents.md +4 -2
  208. package/docs/api/sdk/settings.md +2 -1
  209. package/docs/dashboard.md +1 -1
  210. package/package.json +2 -2
  211. package/dashboard/dist/assets/AgentConfigPage-D52KyJY-.js +0 -13
  212. package/dashboard/dist/assets/AgentConfigPage-D52KyJY-.js.map +0 -1
  213. package/dashboard/dist/assets/AgentDetailPage-Cbo_qrYF.js +0 -4
  214. package/dashboard/dist/assets/AgentDetailPage-Cbo_qrYF.js.map +0 -1
  215. package/dashboard/dist/assets/AgentsPage-CvuF8--H.js +0 -2
  216. package/dashboard/dist/assets/AgentsPage-CvuF8--H.js.map +0 -1
  217. package/dashboard/dist/assets/AvailableEscalationsPage-UzjXcO3W.js +0 -2
  218. package/dashboard/dist/assets/CapabilitiesPage-D1QEHMKw.js +0 -2
  219. package/dashboard/dist/assets/CapabilitiesPage-D1QEHMKw.js.map +0 -1
  220. package/dashboard/dist/assets/CopyableId-DmLF-RqZ.js +0 -2
  221. package/dashboard/dist/assets/CopyableId-DmLF-RqZ.js.map +0 -1
  222. package/dashboard/dist/assets/CronLabel-5HPAmciI.js.map +0 -1
  223. package/dashboard/dist/assets/CustomDurationPicker-5JzEgS7I.js +0 -2
  224. package/dashboard/dist/assets/ElapsedCell-B79BF5Mj.js +0 -2
  225. package/dashboard/dist/assets/McpRunDetailPage-CXXRgMmJ.js +0 -2
  226. package/dashboard/dist/assets/McpRunDetailPage-CXXRgMmJ.js.map +0 -1
  227. package/dashboard/dist/assets/ProcessDetailPage-BMkWCjqD.js +0 -2
  228. package/dashboard/dist/assets/SwimlaneTimeline-MUUXgT3o.js +0 -2
  229. package/dashboard/dist/assets/SwimlaneTimeline-MUUXgT3o.js.map +0 -1
  230. package/dashboard/dist/assets/TimeAgo-CttiZG0k.js +0 -2
  231. package/dashboard/dist/assets/ToolTestPanel-CY_PLZSe.js +0 -2
  232. package/dashboard/dist/assets/ToolTestPanel-CY_PLZSe.js.map +0 -1
  233. package/dashboard/dist/assets/WorkflowExecutionPage-DUSTBasv.js +0 -2
  234. package/dashboard/dist/assets/WorkflowExecutionPage-DUSTBasv.js.map +0 -1
  235. package/dashboard/dist/assets/WorkflowPill-pPuGH8v9.js +0 -2
  236. package/dashboard/dist/assets/WorkflowPill-pPuGH8v9.js.map +0 -1
  237. package/dashboard/dist/assets/index-DXEYynKO.css +0 -1
  238. package/dashboard/dist/assets/index-DcpCR9c_.js.map +0 -1
  239. package/dashboard/dist/assets/index-DuPY59Yu.js +0 -5
  240. package/dashboard/dist/assets/index-DuPY59Yu.js.map +0 -1
  241. package/dashboard/dist/assets/settings-nt6qyR1S.js +0 -2
  242. package/dashboard/dist/assets/settings-nt6qyR1S.js.map +0 -1
  243. package/dashboard/dist/assets/useEventHooks-CkJOmbF-.js +0 -2
  244. package/dashboard/dist/assets/useEventHooks-CkJOmbF-.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TopicDetailPage-Aq4-6GLl.js","sources":["../../src/pages/topics/TopicDetailPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { Radio, Bot, Tag, Pencil, Trash2, Save, X, BookOpen } from 'lucide-react';\nimport { useTopic, useUpdateTopic, useDeleteTopic } from '../../api/topics';\nimport { JsonViewer } from '../../components/common/data/JsonViewer';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\n\nconst CATEGORY_COLORS: Record<string, string> = {\n task: 'bg-blue-400/15 text-blue-400',\n workflow: 'bg-accent/15 text-accent',\n escalation: 'bg-amber-400/15 text-amber-400',\n activity: 'bg-cyan-400/15 text-cyan-400',\n knowledge: 'bg-violet-400/15 text-violet-400',\n agent: 'bg-emerald-400/15 text-emerald-400',\n app: 'bg-rose-400/15 text-rose-400',\n milestone: 'bg-violet-400/15 text-violet-400',\n};\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-3 pb-2 border-b border-surface-border\">\n <Icon className={`w-4 h-4 ${color}`} strokeWidth={1.5} />\n <h2 className=\"text-xs font-semibold uppercase tracking-widest text-accent/80\">{children}</h2>\n </div>\n );\n}\n\nexport function TopicDetailPage() {\n const { topic: encodedTopic } = useParams<{ topic: string }>();\n const topicKey = encodedTopic ? decodeURIComponent(encodedTopic) : null;\n const navigate = useNavigate();\n const { data: topic, isLoading, refetch, isFetching } = useTopic(topicKey);\n const updateMutation = useUpdateTopic();\n const deleteMutation = useDeleteTopic();\n\n const [editing, setEditing] = useState(false);\n const [editDescription, setEditDescription] = useState('');\n const [editTags, setEditTags] = useState('');\n const [editSchema, setEditSchema] = useState('');\n const [schemaError, setSchemaError] = useState('');\n\n if (isLoading) {\n return <div className=\"animate-pulse space-y-4\"><div className=\"h-8 bg-surface-sunken rounded w-48\" /><div className=\"h-40 bg-surface-sunken rounded\" /></div>;\n }\n\n if (!topic) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20 text-center\">\n <Radio className=\"w-12 h-12 text-text-quaternary mb-4\" strokeWidth={1} />\n <h2 className=\"text-lg font-medium text-text-primary mb-2\">Topic not found</h2>\n </div>\n );\n }\n\n const isSystem = topic.source === 'system';\n const isManaged = topic.managed;\n const editable = !isManaged;\n const categoryPillCls = CATEGORY_COLORS[topic.category] ?? 'bg-zinc-400/15 text-zinc-400';\n\n const startEdit = () => {\n setEditDescription(topic.description ?? '');\n setEditTags((topic.tags ?? []).join(', '));\n setEditSchema(topic.payload_schema ? JSON.stringify(topic.payload_schema, null, 2) : '');\n setSchemaError('');\n setEditing(true);\n };\n\n const cancelEdit = () => setEditing(false);\n\n const saveEdit = () => {\n const tags = editTags.split(',').map((t) => t.trim()).filter(Boolean);\n let payload_schema: Record<string, any> | undefined;\n if (editSchema.trim()) {\n try {\n payload_schema = JSON.parse(editSchema);\n setSchemaError('');\n } catch {\n setSchemaError('Invalid JSON');\n return;\n }\n }\n updateMutation.mutate(\n { topic: topic.topic, description: editDescription, tags, ...(payload_schema !== undefined ? { payload_schema } : {}) },\n { onSuccess: () => { setEditing(false); refetch(); } },\n );\n };\n\n const handleDelete = () => {\n if (confirm(`Delete topic \"${topic.topic}\"?\\n\\nThis removes it from the catalog. Active subscriptions are not affected.`)) {\n deleteMutation.mutate(topic.topic, { onSuccess: () => navigate('/topics') });\n }\n };\n\n return (\n <div className=\"max-w-3xl\">\n {/* Header */}\n <div className=\"flex items-start justify-between mb-6\">\n <div>\n <div className=\"flex items-center gap-3 mb-2\">\n <Radio className=\"w-5 h-5 text-accent\" strokeWidth={1.5} />\n <h1 className=\"text-lg font-mono font-medium text-text-primary\">{topic.topic}</h1>\n <button onClick={() => { window.location.hash = '#docs:topics.md'; }} className=\"text-text-quaternary hover:text-accent transition-colors\" title=\"Topic docs\">\n <BookOpen className=\"w-4 h-4\" strokeWidth={1.5} />\n </button>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${categoryPillCls}`}>{topic.category}</span>\n <span className=\"text-[10px] font-mono text-text-quaternary\">source: {topic.source}</span>\n {topic.last_seen_at && (\n <span className=\"text-[10px] text-text-quaternary\">last seen <DateValue date={topic.last_seen_at} /></span>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/topics/by-name/${encodeURIComponent(topic.topic)}`}\n />\n {!editing && editable && (\n <>\n <button onClick={startEdit} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors\">\n <Pencil className=\"w-3 h-3\" /> Edit\n </button>\n {!isSystem && (\n <button onClick={handleDelete} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md text-red-400/60 hover:text-red-400 hover:bg-red-600/10 transition-colors\">\n <Trash2 className=\"w-3 h-3\" /> Delete\n </button>\n )}\n </>\n )}\n {editing && (\n <>\n <button onClick={saveEdit} disabled={updateMutation.isPending} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors\">\n <Save className=\"w-3 h-3\" /> Save\n </button>\n <button onClick={cancelEdit} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md text-text-tertiary hover:text-text-primary hover:bg-surface-hover transition-colors\">\n <X className=\"w-3 h-3\" /> Cancel\n </button>\n </>\n )}\n </div>\n </div>\n\n {/* Description */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Description</label>\n <textarea\n value={editDescription}\n onChange={(e) => setEditDescription(e.target.value)}\n rows={3}\n className=\"input resize-none\"\n placeholder=\"What this topic represents\"\n />\n </div>\n ) : (\n topic.description\n ? <p className=\"text-sm text-text-secondary leading-relaxed\">{topic.description}</p>\n : <p className=\"text-sm text-text-quaternary italic\">No description</p>\n )}\n </div>\n\n {/* Tags */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Tags</label>\n <input\n type=\"text\"\n value={editTags}\n onChange={(e) => setEditTags(e.target.value)}\n placeholder=\"lifecycle, core, error\"\n className=\"input font-mono\"\n />\n <p className=\"hint\">Comma-separated. Used for filtering in the catalog.</p>\n </div>\n ) : topic.tags?.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n <Tag className=\"w-3 h-3 text-text-quaternary\" strokeWidth={1.5} />\n {topic.tags.map((tag) => (\n <span key={tag} className=\"inline-flex items-center px-2 py-0.5 rounded text-[10px] font-mono text-text-tertiary bg-surface-sunken\">\n {tag}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n\n {/* Payload Schema */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Payload Schema</label>\n <textarea\n value={editSchema}\n onChange={(e) => { setEditSchema(e.target.value); setSchemaError(''); }}\n rows={12}\n className=\"input-json w-full\"\n placeholder={'{\\n \"type\": \"object\",\\n \"properties\": {\\n \"orderId\": { \"type\": \"string\" }\\n }\\n}'}\n />\n {schemaError && <p className=\"text-[10px] text-red-400 mt-1\">{schemaError}</p>}\n <p className=\"hint\">JSON Schema describing the event.data shape. Shown in subscription editor as field reference.</p>\n </div>\n ) : topic.payload_schema ? (\n <>\n <SectionHeader icon={Radio} color=\"text-accent\">Payload Schema</SectionHeader>\n <JsonViewer data={topic.payload_schema} />\n </>\n ) : (\n <>\n <SectionHeader icon={Radio} color=\"text-accent\">Payload Schema</SectionHeader>\n <p className=\"text-[11px] text-text-quaternary\">No schema defined. Click Edit to add one.</p>\n </>\n )}\n </div>\n\n {/* Example Payload */}\n {topic.example_payload && (\n <div className=\"mb-8\">\n <SectionHeader icon={Radio} color=\"text-cyan-400\">Example Payload</SectionHeader>\n <JsonViewer data={topic.example_payload} />\n </div>\n )}\n\n {/* Subscribers */}\n <div className=\"mb-8\">\n <SectionHeader icon={Bot} color=\"text-emerald-400\">\n Subscribers ({topic.subscribers?.length ?? 0})\n </SectionHeader>\n {topic.subscribers?.length ? (\n <div className=\"space-y-1\">\n {topic.subscribers.map((sub) => (\n <div key={sub.id} className=\"flex items-center justify-between py-2 px-3 rounded-md hover:bg-surface-hover transition-colors\">\n <button\n onClick={() => navigate(`/agents/${sub.agent_id}`)}\n className=\"flex items-center gap-2 text-left min-w-0\"\n >\n <Bot className=\"w-3 h-3 text-emerald-400 shrink-0\" strokeWidth={1.5} />\n <span className=\"text-xs text-text-primary hover:text-accent transition-colors\">{sub.agent_name}</span>\n </button>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-[10px] font-mono text-text-quaternary\">{sub.topic}</span>\n <span className=\"text-[10px] text-text-tertiary\">{sub.reaction_type}</span>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-[11px] text-text-quaternary py-2\">No agents are subscribed to this topic.</p>\n )}\n </div>\n\n {/* Metadata */}\n <div className=\"text-[10px] text-text-quaternary space-y-1 pt-4 border-t border-surface-border\">\n <p>Created <DateValue date={topic.created_at} /></p>\n <p>Updated <DateValue date={topic.updated_at} /></p>\n </div>\n </div>\n );\n}\n"],"names":["CATEGORY_COLORS","SectionHeader","Icon","color","children","jsxs","jsx","TopicDetailPage","encodedTopic","useParams","topicKey","navigate","useNavigate","topic","isLoading","refetch","isFetching","useTopic","updateMutation","useUpdateTopic","deleteMutation","useDeleteTopic","editing","setEditing","useState","editDescription","setEditDescription","editTags","setEditTags","editSchema","setEditSchema","schemaError","setSchemaError","Radio","isSystem","editable","categoryPillCls","startEdit","cancelEdit","saveEdit","tags","t","payload_schema","handleDelete","BookOpen","DateValue","ListToolbar","Fragment","Pencil","Trash2","Save","X","e","_a","Tag","tag","JsonViewer","Bot","_b","_c","sub"],"mappings":"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"}
1
+ {"version":3,"file":"TopicDetailPage-CjaZn4WP.js","sources":["../../src/pages/topics/TopicDetailPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useParams, useNavigate } from 'react-router-dom';\nimport { Radio, Bot, Tag, Pencil, Trash2, Save, X, BookOpen } from 'lucide-react';\nimport { useTopic, useUpdateTopic, useDeleteTopic } from '../../api/topics';\nimport { JsonViewer } from '../../components/common/data/JsonViewer';\nimport { DateValue } from '../../components/common/display/DateValue';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\n\nconst CATEGORY_COLORS: Record<string, string> = {\n task: 'bg-blue-400/15 text-blue-400',\n workflow: 'bg-accent/15 text-accent',\n escalation: 'bg-amber-400/15 text-amber-400',\n activity: 'bg-cyan-400/15 text-cyan-400',\n knowledge: 'bg-violet-400/15 text-violet-400',\n agent: 'bg-emerald-400/15 text-emerald-400',\n app: 'bg-rose-400/15 text-rose-400',\n milestone: 'bg-violet-400/15 text-violet-400',\n};\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-3 pb-2 border-b border-surface-border\">\n <Icon className={`w-4 h-4 ${color}`} strokeWidth={1.5} />\n <h2 className=\"text-xs font-semibold uppercase tracking-widest text-accent/80\">{children}</h2>\n </div>\n );\n}\n\nexport function TopicDetailPage() {\n const { topic: encodedTopic } = useParams<{ topic: string }>();\n const topicKey = encodedTopic ? decodeURIComponent(encodedTopic) : null;\n const navigate = useNavigate();\n const { data: topic, isLoading, refetch, isFetching } = useTopic(topicKey);\n const updateMutation = useUpdateTopic();\n const deleteMutation = useDeleteTopic();\n\n const [editing, setEditing] = useState(false);\n const [editDescription, setEditDescription] = useState('');\n const [editTags, setEditTags] = useState('');\n const [editSchema, setEditSchema] = useState('');\n const [schemaError, setSchemaError] = useState('');\n\n if (isLoading) {\n return <div className=\"animate-pulse space-y-4\"><div className=\"h-8 bg-surface-sunken rounded w-48\" /><div className=\"h-40 bg-surface-sunken rounded\" /></div>;\n }\n\n if (!topic) {\n return (\n <div className=\"flex flex-col items-center justify-center py-20 text-center\">\n <Radio className=\"w-12 h-12 text-text-quaternary mb-4\" strokeWidth={1} />\n <h2 className=\"text-lg font-medium text-text-primary mb-2\">Topic not found</h2>\n </div>\n );\n }\n\n const isSystem = topic.source === 'system';\n const isManaged = topic.managed;\n const editable = !isManaged;\n const categoryPillCls = CATEGORY_COLORS[topic.category] ?? 'bg-zinc-400/15 text-zinc-400';\n\n const startEdit = () => {\n setEditDescription(topic.description ?? '');\n setEditTags((topic.tags ?? []).join(', '));\n setEditSchema(topic.payload_schema ? JSON.stringify(topic.payload_schema, null, 2) : '');\n setSchemaError('');\n setEditing(true);\n };\n\n const cancelEdit = () => setEditing(false);\n\n const saveEdit = () => {\n const tags = editTags.split(',').map((t) => t.trim()).filter(Boolean);\n let payload_schema: Record<string, any> | undefined;\n if (editSchema.trim()) {\n try {\n payload_schema = JSON.parse(editSchema);\n setSchemaError('');\n } catch {\n setSchemaError('Invalid JSON');\n return;\n }\n }\n updateMutation.mutate(\n { topic: topic.topic, description: editDescription, tags, ...(payload_schema !== undefined ? { payload_schema } : {}) },\n { onSuccess: () => { setEditing(false); refetch(); } },\n );\n };\n\n const handleDelete = () => {\n if (confirm(`Delete topic \"${topic.topic}\"?\\n\\nThis removes it from the catalog. Active subscriptions are not affected.`)) {\n deleteMutation.mutate(topic.topic, { onSuccess: () => navigate('/topics') });\n }\n };\n\n return (\n <div className=\"max-w-3xl\">\n {/* Header */}\n <div className=\"flex items-start justify-between mb-6\">\n <div>\n <div className=\"flex items-center gap-3 mb-2\">\n <Radio className=\"w-5 h-5 text-accent\" strokeWidth={1.5} />\n <h1 className=\"text-lg font-mono font-medium text-text-primary\">{topic.topic}</h1>\n <button onClick={() => { window.location.hash = '#docs:topics.md'; }} className=\"text-text-quaternary hover:text-accent transition-colors\" title=\"Topic docs\">\n <BookOpen className=\"w-4 h-4\" strokeWidth={1.5} />\n </button>\n </div>\n <div className=\"flex items-center gap-3\">\n <span className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${categoryPillCls}`}>{topic.category}</span>\n <span className=\"text-[10px] font-mono text-text-quaternary\">source: {topic.source}</span>\n {topic.last_seen_at && (\n <span className=\"text-[10px] text-text-quaternary\">last seen <DateValue date={topic.last_seen_at} /></span>\n )}\n </div>\n </div>\n\n <div className=\"flex items-center gap-2\">\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/topics/by-name/${encodeURIComponent(topic.topic)}`}\n />\n {!editing && editable && (\n <>\n <button onClick={startEdit} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors\">\n <Pencil className=\"w-3 h-3\" /> Edit\n </button>\n {!isSystem && (\n <button onClick={handleDelete} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md text-red-400/60 hover:text-red-400 hover:bg-red-600/10 transition-colors\">\n <Trash2 className=\"w-3 h-3\" /> Delete\n </button>\n )}\n </>\n )}\n {editing && (\n <>\n <button onClick={saveEdit} disabled={updateMutation.isPending} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md bg-accent text-text-inverse hover:bg-accent-hover transition-colors\">\n <Save className=\"w-3 h-3\" /> Save\n </button>\n <button onClick={cancelEdit} className=\"flex items-center gap-1.5 px-3 py-1.5 text-xs rounded-md text-text-tertiary hover:text-text-primary hover:bg-surface-hover transition-colors\">\n <X className=\"w-3 h-3\" /> Cancel\n </button>\n </>\n )}\n </div>\n </div>\n\n {/* Description */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Description</label>\n <textarea\n value={editDescription}\n onChange={(e) => setEditDescription(e.target.value)}\n rows={3}\n className=\"input resize-none\"\n placeholder=\"What this topic represents\"\n />\n </div>\n ) : (\n topic.description\n ? <p className=\"text-sm text-text-secondary leading-relaxed\">{topic.description}</p>\n : <p className=\"text-sm text-text-quaternary italic\">No description</p>\n )}\n </div>\n\n {/* Tags */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Tags</label>\n <input\n type=\"text\"\n value={editTags}\n onChange={(e) => setEditTags(e.target.value)}\n placeholder=\"lifecycle, core, error\"\n className=\"input font-mono\"\n />\n <p className=\"hint\">Comma-separated. Used for filtering in the catalog.</p>\n </div>\n ) : topic.tags?.length > 0 ? (\n <div className=\"flex items-center gap-2\">\n <Tag className=\"w-3 h-3 text-text-quaternary\" strokeWidth={1.5} />\n {topic.tags.map((tag) => (\n <span key={tag} className=\"inline-flex items-center px-2 py-0.5 rounded text-[10px] font-mono text-text-tertiary bg-surface-sunken\">\n {tag}\n </span>\n ))}\n </div>\n ) : null}\n </div>\n\n {/* Payload Schema */}\n <div className=\"mb-8\">\n {editing ? (\n <div>\n <label className=\"section-header\">Payload Schema</label>\n <textarea\n value={editSchema}\n onChange={(e) => { setEditSchema(e.target.value); setSchemaError(''); }}\n rows={12}\n className=\"input-json w-full\"\n placeholder={'{\\n \"type\": \"object\",\\n \"properties\": {\\n \"orderId\": { \"type\": \"string\" }\\n }\\n}'}\n />\n {schemaError && <p className=\"text-[10px] text-red-400 mt-1\">{schemaError}</p>}\n <p className=\"hint\">JSON Schema describing the event.data shape. Shown in subscription editor as field reference.</p>\n </div>\n ) : topic.payload_schema ? (\n <>\n <SectionHeader icon={Radio} color=\"text-accent\">Payload Schema</SectionHeader>\n <JsonViewer data={topic.payload_schema} />\n </>\n ) : (\n <>\n <SectionHeader icon={Radio} color=\"text-accent\">Payload Schema</SectionHeader>\n <p className=\"text-[11px] text-text-quaternary\">No schema defined. Click Edit to add one.</p>\n </>\n )}\n </div>\n\n {/* Example Payload */}\n {topic.example_payload && (\n <div className=\"mb-8\">\n <SectionHeader icon={Radio} color=\"text-cyan-400\">Example Payload</SectionHeader>\n <JsonViewer data={topic.example_payload} />\n </div>\n )}\n\n {/* Subscribers */}\n <div className=\"mb-8\">\n <SectionHeader icon={Bot} color=\"text-emerald-400\">\n Subscribers ({topic.subscribers?.length ?? 0})\n </SectionHeader>\n {topic.subscribers?.length ? (\n <div className=\"space-y-1\">\n {topic.subscribers.map((sub) => (\n <div key={sub.id} className=\"flex items-center justify-between py-2 px-3 rounded-md hover:bg-surface-hover transition-colors\">\n <button\n onClick={() => navigate(`/agents/${sub.agent_id}`)}\n className=\"flex items-center gap-2 text-left min-w-0\"\n >\n <Bot className=\"w-3 h-3 text-emerald-400 shrink-0\" strokeWidth={1.5} />\n <span className=\"text-xs text-text-primary hover:text-accent transition-colors\">{sub.agent_name}</span>\n </button>\n <div className=\"flex items-center gap-3\">\n <span className=\"text-[10px] font-mono text-text-quaternary\">{sub.topic}</span>\n <span className=\"text-[10px] text-text-tertiary\">{sub.reaction_type}</span>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-[11px] text-text-quaternary py-2\">No agents are subscribed to this topic.</p>\n )}\n </div>\n\n {/* Metadata */}\n <div className=\"text-[10px] text-text-quaternary space-y-1 pt-4 border-t border-surface-border\">\n <p>Created <DateValue date={topic.created_at} /></p>\n <p>Updated <DateValue date={topic.updated_at} /></p>\n </div>\n </div>\n );\n}\n"],"names":["CATEGORY_COLORS","SectionHeader","Icon","color","children","jsxs","jsx","TopicDetailPage","encodedTopic","useParams","topicKey","navigate","useNavigate","topic","isLoading","refetch","isFetching","useTopic","updateMutation","useUpdateTopic","deleteMutation","useDeleteTopic","editing","setEditing","useState","editDescription","setEditDescription","editTags","setEditTags","editSchema","setEditSchema","schemaError","setSchemaError","Radio","isSystem","editable","categoryPillCls","startEdit","cancelEdit","saveEdit","tags","t","payload_schema","handleDelete","BookOpen","DateValue","ListToolbar","Fragment","Pencil","Trash2","Save","X","e","_a","Tag","tag","JsonViewer","Bot","_b","_c","sub"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as e}from"./vendor-query-B2UbickB.js";import{u as x}from"./topics-CTtCboHe.js";import{u as m}from"./useFilterParams-DZCAaBC7.js";import{D as g}from"./DataTable-D9yuBv0w.js";import{S as u}from"./StickyPagination-F9FZsRy9.js";import{F as d,b}from"./FilterBar-Ck4K4rzu.js";import{P as f}from"./PageHeader-Bo0SpcCK.js";import{L as y}from"./ListToolbar-Bntl2hex.js";import{c as h}from"./index-DcpCR9c_.js";import{R as j}from"./vendor-icons-BNtvBbnj.js";import{c as v}from"./vendor-react-CX88sFS5.js";import"./EmptyState-BcsfPq9T.js";const k={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"},N=[{value:"task",label:"Task"},{value:"workflow",label:"Workflow"},{value:"escalation",label:"Escalation"},{value:"activity",label:"Activity"},{value:"knowledge",label:"Knowledge"},{value:"agent",label:"Agent"},{value:"app",label:"App"},{value:"milestone",label:"Milestone"}];function w({category:t}){const a=k[t]??"bg-zinc-400/15 text-zinc-400";return e.jsx("span",{className:`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${a}`,children:t})}const P=[{key:"topic",label:"Topic",render:t=>e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(j,{className:"w-3 h-3 shrink-0 text-text-quaternary",strokeWidth:1.5}),e.jsx("span",{className:"text-xs font-mono text-text-primary truncate",children:t.topic})]})},{key:"category",label:"Category",render:t=>e.jsx(w,{category:t.category}),className:"w-28"},{key:"description",label:"Description",render:t=>t.description?e.jsx("span",{className:"text-[11px] text-text-secondary truncate block max-w-xs",children:t.description}):e.jsx("span",{className:"text-text-quaternary",children:"—"})},{key:"source",label:"Source",render:t=>e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary",children:t.source}),className:"w-24"},{key:"subscriber_count",label:"Subscribers",render:t=>{const a=t.subscriber_count??0;return a?e.jsx("span",{className:"inline-flex items-center justify-center min-w-[20px] px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-accent/15 text-accent",children:a}):e.jsx("span",{className:"text-text-quaternary",children:"—"})},className:"w-24 text-center"},{key:"last_seen_at",label:"Last Seen",render:t=>t.last_seen_at?e.jsx("span",{className:"whitespace-nowrap",children:e.jsx(h,{date:t.last_seen_at})}):e.jsx("span",{className:"text-text-quaternary",children:"—"}),className:"w-28"}];function D(){const t=v(),{filters:a,setFilter:n,pagination:s}=m({filters:{category:""}}),{data:o,isLoading:l,refetch:c,isFetching:p}=x({category:a.category||void 0,limit:s.pageSize,offset:s.offset}),i=(o==null?void 0:o.total)??0;return e.jsxs("div",{children:[e.jsx(f,{title:"Topic Catalog",docsHash:"#docs:topics.md"}),e.jsx(d,{actions:e.jsx(y,{onRefresh:()=>c(),isFetching:p,apiPath:`/topics?limit=${s.pageSize}&offset=${s.offset}${a.category?`&category=${a.category}`:""}`}),children:e.jsx(b,{label:"Category",value:a.category,onChange:r=>n("category",r),options:N})}),e.jsx(g,{columns:P,data:(o==null?void 0:o.topics)??[],keyFn:r=>r.topic,onRowClick:r=>t(`/topics/${encodeURIComponent(r.topic)}`),isLoading:l,emptyMessage:"No topics registered yet"}),e.jsx(u,{page:s.page,totalPages:s.totalPages(i),onPageChange:s.setPage,total:i,pageSize:s.pageSize,onPageSizeChange:s.setPageSize})]})}export{D as TopicsPage};
2
- //# sourceMappingURL=TopicsPage-BYFKjRY_.js.map
1
+ import{j as e}from"./vendor-query-B2UbickB.js";import{u as x}from"./topics-BMG5tx2g.js";import{u as m}from"./useFilterParams-DZCAaBC7.js";import{D as g}from"./DataTable-D9yuBv0w.js";import{S as u}from"./StickyPagination-F9FZsRy9.js";import{F as d,b}from"./FilterBar-Ck4K4rzu.js";import{P as f}from"./PageHeader-B_gV_jKk.js";import{L as y}from"./ListToolbar-DNAGFe14.js";import{d as h}from"./index-DZX-E_3q.js";import{R as j}from"./vendor-icons-B_Yla7iD.js";import{c as v}from"./vendor-react-CX88sFS5.js";import"./EmptyState-BcsfPq9T.js";const k={task:"bg-blue-400/15 text-blue-400",workflow:"bg-accent/15 text-accent",escalation:"bg-amber-400/15 text-amber-400",activity:"bg-cyan-400/15 text-cyan-400",knowledge:"bg-violet-400/15 text-violet-400",agent:"bg-emerald-400/15 text-emerald-400",app:"bg-rose-400/15 text-rose-400",milestone:"bg-violet-400/15 text-violet-400"},N=[{value:"task",label:"Task"},{value:"workflow",label:"Workflow"},{value:"escalation",label:"Escalation"},{value:"activity",label:"Activity"},{value:"knowledge",label:"Knowledge"},{value:"agent",label:"Agent"},{value:"app",label:"App"},{value:"milestone",label:"Milestone"}];function w({category:t}){const a=k[t]??"bg-zinc-400/15 text-zinc-400";return e.jsx("span",{className:`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${a}`,children:t})}const P=[{key:"topic",label:"Topic",render:t=>e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(j,{className:"w-3 h-3 shrink-0 text-text-quaternary",strokeWidth:1.5}),e.jsx("span",{className:"text-xs font-mono text-text-primary truncate",children:t.topic})]})},{key:"category",label:"Category",render:t=>e.jsx(w,{category:t.category}),className:"w-28"},{key:"description",label:"Description",render:t=>t.description?e.jsx("span",{className:"text-[11px] text-text-secondary truncate block max-w-xs",children:t.description}):e.jsx("span",{className:"text-text-quaternary",children:"—"})},{key:"source",label:"Source",render:t=>e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary",children:t.source}),className:"w-24"},{key:"subscriber_count",label:"Subscribers",render:t=>{const a=t.subscriber_count??0;return a?e.jsx("span",{className:"inline-flex items-center justify-center min-w-[20px] px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-accent/15 text-accent",children:a}):e.jsx("span",{className:"text-text-quaternary",children:"—"})},className:"w-24 text-center"},{key:"last_seen_at",label:"Last Seen",render:t=>t.last_seen_at?e.jsx("span",{className:"whitespace-nowrap",children:e.jsx(h,{date:t.last_seen_at})}):e.jsx("span",{className:"text-text-quaternary",children:"—"}),className:"w-28"}];function D(){const t=v(),{filters:a,setFilter:n,pagination:s}=m({filters:{category:""}}),{data:o,isLoading:l,refetch:c,isFetching:p}=x({category:a.category||void 0,limit:s.pageSize,offset:s.offset}),i=(o==null?void 0:o.total)??0;return e.jsxs("div",{children:[e.jsx(f,{title:"Topic Catalog",docsHash:"#docs:topics.md"}),e.jsx(d,{actions:e.jsx(y,{onRefresh:()=>c(),isFetching:p,apiPath:`/topics?limit=${s.pageSize}&offset=${s.offset}${a.category?`&category=${a.category}`:""}`}),children:e.jsx(b,{label:"Category",value:a.category,onChange:r=>n("category",r),options:N})}),e.jsx(g,{columns:P,data:(o==null?void 0:o.topics)??[],keyFn:r=>r.topic,onRowClick:r=>t(`/topics/${encodeURIComponent(r.topic)}`),isLoading:l,emptyMessage:"No topics registered yet"}),e.jsx(u,{page:s.page,totalPages:s.totalPages(i),onPageChange:s.setPage,total:i,pageSize:s.pageSize,onPageSizeChange:s.setPageSize})]})}export{D as TopicsPage};
2
+ //# sourceMappingURL=TopicsPage-BfsJEC1p.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TopicsPage-BYFKjRY_.js","sources":["../../src/pages/topics/TopicsPage.tsx"],"sourcesContent":["import { useNavigate } from 'react-router-dom';\nimport { Radio } from 'lucide-react';\nimport { useTopics, type TopicCatalogEntry } from '../../api/topics';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { DateValue } from '../../components/common/display/DateValue';\n\nconst CATEGORY_COLORS: Record<string, string> = {\n task: 'bg-blue-400/15 text-blue-400',\n workflow: 'bg-accent/15 text-accent',\n escalation: 'bg-amber-400/15 text-amber-400',\n activity: 'bg-cyan-400/15 text-cyan-400',\n knowledge: 'bg-violet-400/15 text-violet-400',\n agent: 'bg-emerald-400/15 text-emerald-400',\n app: 'bg-rose-400/15 text-rose-400',\n milestone: 'bg-violet-400/15 text-violet-400',\n};\n\nconst CATEGORY_OPTIONS = [\n { value: 'task', label: 'Task' },\n { value: 'workflow', label: 'Workflow' },\n { value: 'escalation', label: 'Escalation' },\n { value: 'activity', label: 'Activity' },\n { value: 'knowledge', label: 'Knowledge' },\n { value: 'agent', label: 'Agent' },\n { value: 'app', label: 'App' },\n { value: 'milestone', label: 'Milestone' },\n];\n\nfunction CategoryPill({ category }: { category: string }) {\n const cls = CATEGORY_COLORS[category] ?? 'bg-zinc-400/15 text-zinc-400';\n return (\n <span className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${cls}`}>\n {category}\n </span>\n );\n}\n\nconst columns: Column<TopicCatalogEntry>[] = [\n {\n key: 'topic',\n label: 'Topic',\n render: (row) => (\n <div className=\"flex items-center gap-2 min-w-0\">\n <Radio className=\"w-3 h-3 shrink-0 text-text-quaternary\" strokeWidth={1.5} />\n <span className=\"text-xs font-mono text-text-primary truncate\">{row.topic}</span>\n </div>\n ),\n },\n {\n key: 'category',\n label: 'Category',\n render: (row) => <CategoryPill category={row.category} />,\n className: 'w-28',\n },\n {\n key: 'description',\n label: 'Description',\n render: (row) => row.description\n ? <span className=\"text-[11px] text-text-secondary truncate block max-w-xs\">{row.description}</span>\n : <span className=\"text-text-quaternary\">—</span>,\n },\n {\n key: 'source',\n label: 'Source',\n render: (row) => (\n <span className=\"text-[10px] font-mono text-text-tertiary\">{row.source}</span>\n ),\n className: 'w-24',\n },\n {\n key: 'subscriber_count',\n label: 'Subscribers',\n render: (row) => {\n const count = row.subscriber_count ?? 0;\n if (!count) return <span className=\"text-text-quaternary\">—</span>;\n return (\n <span className=\"inline-flex items-center justify-center min-w-[20px] px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-accent/15 text-accent\">\n {count}\n </span>\n );\n },\n className: 'w-24 text-center',\n },\n {\n key: 'last_seen_at',\n label: 'Last Seen',\n render: (row) => row.last_seen_at\n ? <span className=\"whitespace-nowrap\"><DateValue date={row.last_seen_at} /></span>\n : <span className=\"text-text-quaternary\">—</span>,\n className: 'w-28',\n },\n];\n\nexport function TopicsPage() {\n const navigate = useNavigate();\n\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { category: '' },\n });\n\n const { data, isLoading, refetch, isFetching } = useTopics({\n category: filters.category || undefined,\n limit: pagination.pageSize,\n offset: pagination.offset,\n });\n\n const total = data?.total ?? 0;\n\n return (\n <div>\n <PageHeader title=\"Topic Catalog\" docsHash=\"#docs:topics.md\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/topics?limit=${pagination.pageSize}&offset=${pagination.offset}${filters.category ? `&category=${filters.category}` : ''}`}\n />\n }>\n <FilterSelect\n label=\"Category\"\n value={filters.category}\n onChange={(v) => setFilter('category', v)}\n options={CATEGORY_OPTIONS}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={data?.topics ?? []}\n keyFn={(row) => row.topic}\n onRowClick={(row) => navigate(`/topics/${encodeURIComponent(row.topic)}`)}\n isLoading={isLoading}\n emptyMessage=\"No topics registered yet\"\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 </div>\n );\n}\n"],"names":["CATEGORY_COLORS","CATEGORY_OPTIONS","CategoryPill","category","cls","columns","row","jsxs","jsx","Radio","count","DateValue","TopicsPage","navigate","useNavigate","filters","setFilter","pagination","useFilterParams","data","isLoading","refetch","isFetching","useTopics","total","PageHeader","FilterBar","ListToolbar","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
1
+ {"version":3,"file":"TopicsPage-BfsJEC1p.js","sources":["../../src/pages/topics/TopicsPage.tsx"],"sourcesContent":["import { useNavigate } from 'react-router-dom';\nimport { Radio } from 'lucide-react';\nimport { useTopics, type TopicCatalogEntry } from '../../api/topics';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { DateValue } from '../../components/common/display/DateValue';\n\nconst CATEGORY_COLORS: Record<string, string> = {\n task: 'bg-blue-400/15 text-blue-400',\n workflow: 'bg-accent/15 text-accent',\n escalation: 'bg-amber-400/15 text-amber-400',\n activity: 'bg-cyan-400/15 text-cyan-400',\n knowledge: 'bg-violet-400/15 text-violet-400',\n agent: 'bg-emerald-400/15 text-emerald-400',\n app: 'bg-rose-400/15 text-rose-400',\n milestone: 'bg-violet-400/15 text-violet-400',\n};\n\nconst CATEGORY_OPTIONS = [\n { value: 'task', label: 'Task' },\n { value: 'workflow', label: 'Workflow' },\n { value: 'escalation', label: 'Escalation' },\n { value: 'activity', label: 'Activity' },\n { value: 'knowledge', label: 'Knowledge' },\n { value: 'agent', label: 'Agent' },\n { value: 'app', label: 'App' },\n { value: 'milestone', label: 'Milestone' },\n];\n\nfunction CategoryPill({ category }: { category: string }) {\n const cls = CATEGORY_COLORS[category] ?? 'bg-zinc-400/15 text-zinc-400';\n return (\n <span className={`inline-flex items-center px-2 py-0.5 rounded text-[10px] font-medium ${cls}`}>\n {category}\n </span>\n );\n}\n\nconst columns: Column<TopicCatalogEntry>[] = [\n {\n key: 'topic',\n label: 'Topic',\n render: (row) => (\n <div className=\"flex items-center gap-2 min-w-0\">\n <Radio className=\"w-3 h-3 shrink-0 text-text-quaternary\" strokeWidth={1.5} />\n <span className=\"text-xs font-mono text-text-primary truncate\">{row.topic}</span>\n </div>\n ),\n },\n {\n key: 'category',\n label: 'Category',\n render: (row) => <CategoryPill category={row.category} />,\n className: 'w-28',\n },\n {\n key: 'description',\n label: 'Description',\n render: (row) => row.description\n ? <span className=\"text-[11px] text-text-secondary truncate block max-w-xs\">{row.description}</span>\n : <span className=\"text-text-quaternary\">—</span>,\n },\n {\n key: 'source',\n label: 'Source',\n render: (row) => (\n <span className=\"text-[10px] font-mono text-text-tertiary\">{row.source}</span>\n ),\n className: 'w-24',\n },\n {\n key: 'subscriber_count',\n label: 'Subscribers',\n render: (row) => {\n const count = row.subscriber_count ?? 0;\n if (!count) return <span className=\"text-text-quaternary\">—</span>;\n return (\n <span className=\"inline-flex items-center justify-center min-w-[20px] px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-accent/15 text-accent\">\n {count}\n </span>\n );\n },\n className: 'w-24 text-center',\n },\n {\n key: 'last_seen_at',\n label: 'Last Seen',\n render: (row) => row.last_seen_at\n ? <span className=\"whitespace-nowrap\"><DateValue date={row.last_seen_at} /></span>\n : <span className=\"text-text-quaternary\">—</span>,\n className: 'w-28',\n },\n];\n\nexport function TopicsPage() {\n const navigate = useNavigate();\n\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { category: '' },\n });\n\n const { data, isLoading, refetch, isFetching } = useTopics({\n category: filters.category || undefined,\n limit: pagination.pageSize,\n offset: pagination.offset,\n });\n\n const total = data?.total ?? 0;\n\n return (\n <div>\n <PageHeader title=\"Topic Catalog\" docsHash=\"#docs:topics.md\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/topics?limit=${pagination.pageSize}&offset=${pagination.offset}${filters.category ? `&category=${filters.category}` : ''}`}\n />\n }>\n <FilterSelect\n label=\"Category\"\n value={filters.category}\n onChange={(v) => setFilter('category', v)}\n options={CATEGORY_OPTIONS}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={data?.topics ?? []}\n keyFn={(row) => row.topic}\n onRowClick={(row) => navigate(`/topics/${encodeURIComponent(row.topic)}`)}\n isLoading={isLoading}\n emptyMessage=\"No topics registered yet\"\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 </div>\n );\n}\n"],"names":["CATEGORY_COLORS","CATEGORY_OPTIONS","CategoryPill","category","cls","columns","row","jsxs","jsx","Radio","count","DateValue","TopicsPage","navigate","useNavigate","filters","setFilter","pagination","useFilterParams","data","isLoading","refetch","isFetching","useTopics","total","PageHeader","FilterBar","ListToolbar","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{j as r}from"./vendor-query-B2UbickB.js";import{a as t}from"./users-CyF-5WLI.js";function m({userId:a,fallback:s}){const{data:e}=t(a);return e?r.jsx(r.Fragment,{children:e.display_name||e.email||e.external_id}):r.jsx(r.Fragment,{children:s??`${a.slice(0,8)}…`})}export{m as U};
2
- //# sourceMappingURL=UserName-C4_T5-rI.js.map
1
+ import{j as r}from"./vendor-query-B2UbickB.js";import{a as t}from"./users-XZ349b0r.js";function m({userId:a,fallback:s}){const{data:e}=t(a);return e?r.jsx(r.Fragment,{children:e.display_name||e.email||e.external_id}):r.jsx(r.Fragment,{children:s??`${a.slice(0,8)}…`})}export{m as U};
2
+ //# sourceMappingURL=UserName-b4baWHM_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"UserName-C4_T5-rI.js","sources":["../../src/components/common/display/UserName.tsx"],"sourcesContent":["import { useUser } from '../../../api/users';\n\n/**\n * Resolves a user ID to their display name (or email, or truncated ID as fallback).\n * Renders inline — suitable for use inside <span>, <p>, etc.\n */\nexport function UserName({ userId, fallback }: { userId: string; fallback?: string }) {\n const { data: resolved } = useUser(userId);\n\n if (resolved) {\n return <>{resolved.display_name || resolved.email || resolved.external_id}</>;\n }\n\n // Still loading or no record — show fallback or truncated ID\n return <>{fallback ?? `${userId.slice(0, 8)}…`}</>;\n}\n"],"names":["UserName","userId","fallback","resolved","useUser","jsx","Fragment"],"mappings":"uFAMO,SAASA,EAAS,CAAE,OAAAC,EAAQ,SAAAC,GAAmD,CACpF,KAAM,CAAE,KAAMC,GAAaC,EAAQH,CAAM,EAEzC,OAAIE,oBACQ,SAAAA,EAAS,cAAgBA,EAAS,OAASA,EAAS,YAAY,EAIrEE,EAAAA,IAAAC,EAAAA,SAAA,CAAG,YAAY,GAAGL,EAAO,MAAM,EAAG,CAAC,CAAC,GAAA,CAAI,CACjD"}
1
+ {"version":3,"file":"UserName-b4baWHM_.js","sources":["../../src/components/common/display/UserName.tsx"],"sourcesContent":["import { useUser } from '../../../api/users';\n\n/**\n * Resolves a user ID to their display name (or email, or truncated ID as fallback).\n * Renders inline — suitable for use inside <span>, <p>, etc.\n */\nexport function UserName({ userId, fallback }: { userId: string; fallback?: string }) {\n const { data: resolved } = useUser(userId);\n\n if (resolved) {\n return <>{resolved.display_name || resolved.email || resolved.external_id}</>;\n }\n\n // Still loading or no record — show fallback or truncated ID\n return <>{fallback ?? `${userId.slice(0, 8)}…`}</>;\n}\n"],"names":["UserName","userId","fallback","resolved","useUser","jsx","Fragment"],"mappings":"uFAMO,SAASA,EAAS,CAAE,OAAAC,EAAQ,SAAAC,GAAmD,CACpF,KAAM,CAAE,KAAMC,GAAaC,EAAQH,CAAM,EAEzC,OAAIE,oBACQ,SAAAA,EAAS,cAAgBA,EAAS,OAASA,EAAS,YAAY,EAIrEE,EAAAA,IAAAC,EAAAA,SAAA,CAAG,YAAY,GAAGL,EAAO,MAAM,EAAG,CAAC,CAAC,GAAA,CAAI,CACjD"}
@@ -0,0 +1,2 @@
1
+ import{j as e,a as b}from"./vendor-query-B2UbickB.js";import{a as S,g as L}from"./workflows-Do-Eiv8f.js";import{h as P}from"./useEventHooks-CPyvFlVR.js";import{u as R}from"./useCollapsedSections-BU5HULGs.js";import{b as A,e as D}from"./tasks-BevFBjZq.js";import{d as y,D as V,J as N,e as K}from"./index-DZX-E_3q.js";import{P as Q}from"./PageHeader-B_gV_jKk.js";import{C as k}from"./CollapsibleSection-DnoUFQVf.js";import{L as U}from"./ListToolbar-DNAGFe14.js";import{S as _}from"./StatusBadge-XQlNFwmH.js";import{C as z}from"./CopyableId-D0SQ39nR.js";import{L as f,e as B,u as H,c as J}from"./vendor-react-CX88sFS5.js";import{S as M}from"./SwimlaneTimeline-og79Llvs.js";import{E as O}from"./EventTable-CGfJU7e1.js";import"./vendor-icons-B_Yla7iD.js";import"./FilterBar-Ck4K4rzu.js";function u({label:t,value:a,mono:r,truncate:s,children:i}){return e.jsxs("div",{children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:t}),i||e.jsx("p",{className:`text-xs text-text-primary ${r?"font-mono":""} ${s?"truncate":""}`,title:s?a:void 0,children:a})]})}function F(t){const a=t.lastIndexOf("-");return a<=0?{taskQueue:t,workflowType:t}:{taskQueue:t.substring(0,a),workflowType:t.substring(a+1)}}function q({execution:t,task:a,escalations:r}){const s=t.parent_workflow_id,n=a&&a.workflow_id===t.workflow_id?a.parent_workflow_id:null,d=s||n||null,c=d&&d!==t.workflow_id?d:null,{taskQueue:p,workflowType:o}=F(t.workflow_type);return e.jsxs("div",{className:"bg-surface-sunken/50 rounded-md px-6 py-5 mb-6",children:[e.jsxs("div",{className:"grid grid-cols-2 sm:grid-cols-4 gap-y-4 gap-x-8",children:[e.jsx(z,{label:"Workflow Type",value:o,href:`/workflows/executions?entity=${encodeURIComponent(o)}`}),e.jsx(u,{label:"Task Queue",value:p,mono:!0}),e.jsx(u,{label:"Start Time",children:t.start_time?e.jsx(y,{date:t.start_time,format:"datetime",className:"text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})}),e.jsx(u,{label:"End Time",children:t.close_time?e.jsx(y,{date:t.close_time,format:"datetime",className:"text-text-primary"}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"--"})}),e.jsx(u,{label:"Duration",children:e.jsx(V,{ms:t.duration_ms,className:"font-mono text-text-primary"})}),e.jsx(u,{label:"History Size",value:`${t.summary.total_events} events`}),e.jsx(u,{label:"Activities",value:`${t.summary.activities.completed} / ${t.summary.activities.total}`}),e.jsx(u,{label:"Workflow ID",value:t.workflow_id,mono:!0,truncate:!0})]}),(c||r&&r.length>0)&&e.jsxs("div",{className:"mt-5 pt-4 border-t border-surface-border/50 space-y-3",children:[c&&e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0",children:"Parent"}),e.jsx(f,{to:`/workflows/executions/${c}`,className:"text-xs font-mono text-accent hover:underline truncate",title:c,children:c})]}),!1,r&&r.length>0&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0 mt-0.5",children:r.length===1?"Escalation":"Escalations"}),e.jsx("div",{className:"flex flex-wrap gap-x-4 gap-y-1",children:r.map(m=>e.jsxs(f,{to:`/escalations/detail/${m.id}`,className:"inline-flex items-center gap-1.5 text-xs font-mono text-accent hover:underline",children:[e.jsx("span",{children:m.type}),e.jsx(_,{status:m.status})]},m.id))})]})]})]})}function Z(t){var s;const a=t.events.find(i=>i.event_type==="workflow_execution_started"),r=(s=a==null?void 0:a.attributes)==null?void 0:s.input;return r&&typeof r=="object"?r:null}function G({execution:t}){const a=Z(t),r=t.result,s=(r==null?void 0:r.data)??r??null;return!a&&!s?null:e.jsxs("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6",children:[a!==null&&e.jsx("div",{children:e.jsx(N,{data:a,label:"Input Envelope"})}),s!==null&&e.jsx("div",{children:e.jsx(N,{data:s,label:"Result"})})]})}function X({isRunning:t,hasToolCalls:a,workflowId:r,onAction:s}){const[i,n]=b.useState(!1),d=b.useRef(null);return b.useEffect(()=>{if(!i)return;const c=p=>{d.current&&!d.current.contains(p.target)&&n(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[i]),e.jsxs("div",{className:"relative",ref:d,children:[e.jsx("button",{onClick:()=>n(!i),className:"btn-primary text-xs",children:"Actions"}),i&&e.jsxs("div",{className:"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10",children:[e.jsx("button",{onClick:()=>{s("restart"),n(!1)},className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",children:"Restart Workflow"}),t&&e.jsx("button",{onClick:()=>{s("terminate"),n(!1)},className:"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover",children:"Terminate"}),a&&e.jsx(f,{to:`/mcp/queries/${r}?step=3`,className:"block w-full text-left px-4 py-2 text-xs text-accent hover:bg-surface-hover",onClick:()=>n(!1),children:"Compile into Pipeline"}),e.jsx(f,{to:`/mcp/executions/${encodeURIComponent(r)}?namespace=durable`,className:"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover",onClick:()=>n(!1),children:"View Raw Execution"})]})]})}function fe(){const{workflowId:t}=B(),{pathname:a}=H();P(t);const r=(a.startsWith("/workflows/durable/"),"Durable Execution"),{data:s,isLoading:i,error:n,refetch:d,isFetching:c}=S(t),{data:p}=A(t),{data:o}=D(t),{data:m}=K(t),E=J(),h=L(),{isCollapsed:w,toggle:v}=R("workflow-execution"),T=x=>{var l;if(x==="terminate")confirm("Are you sure you want to terminate this workflow?")&&h.mutate(t);else if(x==="restart"&&s){const W=s.workflow_id.replace(/-[A-Za-z0-9_-]{20,}$/,""),j=s.events.find($=>$.event_type==="workflow_execution_started"),g=(l=j==null?void 0:j.attributes)==null?void 0:l.input;g&&sessionStorage.setItem("lt:invoke:prefill",JSON.stringify(g)),E(`/workflows/start?type=${encodeURIComponent(W)}&mode=now`)}};if(i)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-60 bg-surface-sunken rounded"})]});if(n||!s){const x=(n==null?void 0:n.message)??"",l=x.includes("expired")||x.includes("no longer available");return e.jsxs("div",{children:[e.jsx(f,{to:"/workflows/executions",className:"text-xs text-text-tertiary hover:text-text-primary",children:"← Workflows"}),e.jsxs("div",{className:"mt-4 text-center py-8",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:l?"Execution data is no longer available":n?"Unable to load execution":"Execution not found"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:l?"This workflow's underlying job has expired. The task record is preserved, but the execution timeline has been cleaned up.":x||"The workflow could not be resolved."})]})]})}const C=s.status!=="completed"&&s.status!=="failed",I=s.status==="completed"&&s.events.some(x=>{if(x.event_type!=="activity_task_completed")return!1;const l=x.attributes.activity_type;return l==="callDbTool"||l==="callVisionTool"||l==="callMcpTool"||(l==null?void 0:l.startsWith("mcp_"))});return e.jsxs("div",{children:[e.jsx(Q,{title:r,actions:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx(U,{onRefresh:()=>d(),isFetching:c,apiPath:`/workflow-states/${t}/execution`}),e.jsx(_,{status:s.status}),e.jsx(X,{isRunning:C,hasToolCalls:I,workflowId:t,onAction:T})]})}),e.jsx(q,{execution:s,task:p,childTasks:o==null?void 0:o.tasks,escalations:m==null?void 0:m.escalations}),h.error&&e.jsx("div",{className:"py-3 mb-6",children:e.jsxs("p",{className:"text-xs text-status-error",children:["Terminate failed: ",h.error.message]})}),e.jsxs("div",{className:"space-y-6",children:[e.jsx(k,{title:"Details",sectionKey:"details",isCollapsed:w("details"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(G,{execution:s})}),e.jsx(k,{title:"Execution Timeline",sectionKey:"timeline",isCollapsed:w("timeline"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(M,{events:s.events,childTasks:o==null?void 0:o.tasks})}),e.jsx(k,{title:"Events",sectionKey:"events",isCollapsed:w("events"),onToggle:v,contentClassName:"mt-4 ml-9",children:e.jsx(O,{events:s.events,childTasks:o==null?void 0:o.tasks})})]})]})}export{fe as WorkflowExecutionPage};
2
+ //# sourceMappingURL=WorkflowExecutionPage-BGmJnXnk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowExecutionPage-BGmJnXnk.js","sources":["../../src/pages/workflows/workflow-execution/ExecutionHeader.tsx","../../src/pages/workflows/workflow-execution/ExecutionInputResult.tsx","../../src/pages/workflows/WorkflowExecutionPage.tsx"],"sourcesContent":["import { Link } from 'react-router-dom';\nimport { StatusBadge } from '../../../components/common/display/StatusBadge';\nimport { CopyableId } from '../../../components/common/display/CopyableId';\nimport type { WorkflowExecution, LTTaskRecord, LTEscalationRecord } from '../../../api/types';\nimport { DateValue } from '../../../components/common/display/DateValue';\nimport { DurationValue } from '../../../components/common/display/DurationValue';\n\nfunction MetadataField({\n label,\n value,\n mono,\n truncate,\n children,\n}: {\n label: string;\n value?: string;\n mono?: boolean;\n truncate?: boolean;\n children?: React.ReactNode;\n}) {\n return (\n <div>\n <p className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">\n {label}\n </p>\n {children || (\n <p\n className={`text-xs text-text-primary ${mono ? 'font-mono' : ''} ${truncate ? 'truncate' : ''}`}\n title={truncate ? value : undefined}\n >\n {value}\n </p>\n )}\n </div>\n );\n}\n\n/**\n * Split a HotMesh compound entity key (taskQueue-workflowName) on the last '-'.\n * Workflow names are camelCase, so the last segment is always the workflow type.\n */\nfunction splitEntityKey(compound: string): { taskQueue: string; workflowType: string } {\n const lastDash = compound.lastIndexOf('-');\n if (lastDash <= 0) return { taskQueue: compound, workflowType: compound };\n return {\n taskQueue: compound.substring(0, lastDash),\n workflowType: compound.substring(lastDash + 1),\n };\n}\n\ninterface ExecutionHeaderProps {\n execution: WorkflowExecution;\n task?: LTTaskRecord | null;\n childTasks?: LTTaskRecord[];\n escalations?: LTEscalationRecord[];\n}\n\nexport function ExecutionHeader({ execution, task, escalations }: ExecutionHeaderProps) {\n // Determine parent relationship — prefer execution-level pj (from HotMesh\n // raw state), fall back to lt_tasks record. When the SDK adds\n // parent_workflow_id natively, it flows through automatically.\n const executionParent = (execution as any).parent_workflow_id as string | undefined;\n const isLeaf = task && task.workflow_id === execution.workflow_id;\n const taskParent = isLeaf ? task.parent_workflow_id : null;\n const rawParent = executionParent || taskParent || null;\n // Filter self-references — cron-invoked workflows store themselves as parent\n const parentWorkflowId = rawParent && rawParent !== execution.workflow_id ? rawParent : null;\n\n // Split compound HotMesh keys into separate task queue / workflow type\n const { taskQueue, workflowType } = splitEntityKey(execution.workflow_type);\n\n return (\n <div className=\"bg-surface-sunken/50 rounded-md px-6 py-5 mb-6\">\n\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-y-4 gap-x-8\">\n <CopyableId label=\"Workflow Type\" value={workflowType} href={`/workflows/executions?entity=${encodeURIComponent(workflowType)}`} />\n <MetadataField label=\"Task Queue\" value={taskQueue} mono />\n <MetadataField label=\"Start Time\">\n {execution.start_time\n ? <DateValue date={execution.start_time} format=\"datetime\" className=\"text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </MetadataField>\n <MetadataField label=\"End Time\">\n {execution.close_time\n ? <DateValue date={execution.close_time} format=\"datetime\" className=\"text-text-primary\" />\n : <span className=\"text-xs text-text-tertiary\">--</span>}\n </MetadataField>\n <MetadataField label=\"Duration\">\n <DurationValue ms={execution.duration_ms} className=\"font-mono text-text-primary\" />\n </MetadataField>\n <MetadataField\n label=\"History Size\"\n value={`${execution.summary.total_events} events`}\n />\n <MetadataField\n label=\"Activities\"\n value={`${execution.summary.activities.completed} / ${execution.summary.activities.total}`}\n />\n <MetadataField\n label=\"Workflow ID\"\n value={execution.workflow_id}\n mono\n truncate\n />\n </div>\n\n {/* Related links */}\n {(parentWorkflowId || (escalations && escalations.length > 0)) && (\n <div className=\"mt-5 pt-4 border-t border-surface-border/50 space-y-3\">\n {/* Parent navigation */}\n {parentWorkflowId && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0\">\n Parent\n </span>\n <Link\n to={`/workflows/executions/${parentWorkflowId}`}\n className=\"text-xs font-mono text-accent hover:underline truncate\"\n title={parentWorkflowId}\n >\n {parentWorkflowId}\n </Link>\n </div>\n )}\n\n {/* Process link — deep-links to process list filtered by this workflow */}\n {false && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0\">\n Process\n </span>\n <Link\n to={`/processes/all?search=${encodeURIComponent(execution.workflow_id)}`}\n className=\"text-xs font-mono text-accent hover:underline truncate\"\n >\n Find in Processes\n </Link>\n </div>\n )}\n\n {/* Escalation links */}\n {escalations && escalations.length > 0 && (\n <div className=\"flex items-start gap-2\">\n <span className=\"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary shrink-0 mt-0.5\">\n {escalations.length === 1 ? 'Escalation' : 'Escalations'}\n </span>\n <div className=\"flex flex-wrap gap-x-4 gap-y-1\">\n {escalations.map((esc) => (\n <Link\n key={esc.id}\n to={`/escalations/detail/${esc.id}`}\n className=\"inline-flex items-center gap-1.5 text-xs font-mono text-accent hover:underline\"\n >\n <span>{esc.type}</span>\n <StatusBadge status={esc.status} />\n </Link>\n ))}\n </div>\n </div>\n )}\n </div>\n )}\n </div>\n );\n}\n","import { JsonViewer } from '../../../components/common/data/JsonViewer';\nimport type { WorkflowExecution } from '../../../api/types';\n\ninterface ExecutionInputResultProps {\n execution: WorkflowExecution;\n}\n\n/**\n * Extract the workflow input envelope from the workflow_execution_started event.\n * HotMesh 0.13.0+ includes the actual trigger arguments (the envelope passed\n * to startWorkflow) in the start event's `input` attribute.\n */\nfunction extractInput(execution: WorkflowExecution): Record<string, unknown> | null {\n const startEvent = execution.events.find(\n (e) => e.event_type === 'workflow_execution_started',\n );\n const input = (startEvent?.attributes as any)?.input;\n return input && typeof input === 'object' ? input : null;\n}\n\nexport function ExecutionInputResult({ execution }: ExecutionInputResultProps) {\n const input = extractInput(execution);\n\n // Result: unwrap the workflow return — the `data` field is what LT users care about\n const rawResult = execution.result as Record<string, unknown> | null | undefined;\n const result = rawResult?.data ?? rawResult ?? null;\n\n if (!input && !result) return null;\n\n return (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-6\">\n {input !== null && (\n <div>\n <JsonViewer data={input} label=\"Input Envelope\" />\n </div>\n )}\n {result !== null && (\n <div>\n <JsonViewer data={result} label=\"Result\" />\n </div>\n )}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { useParams, useLocation, useNavigate, Link } from 'react-router-dom';\nimport { useWorkflowExecution, useTerminateWorkflow } from '../../api/workflows';\nimport { useWorkflowDetailEvents } from '../../hooks/useEventHooks';\nimport { useCollapsedSections } from '../../hooks/useCollapsedSections';\nimport { useTaskByWorkflowId, useChildTasks } from '../../api/tasks';\nimport { useEscalationsByWorkflowId } from '../../api/escalations';\n\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { CollapsibleSection } from '../../components/common/layout/CollapsibleSection';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { StatusBadge } from '../../components/common/display/StatusBadge';\n\nimport { ExecutionHeader } from './workflow-execution/ExecutionHeader';\nimport { ExecutionInputResult } from './workflow-execution/ExecutionInputResult';\nimport { SwimlaneTimeline } from './workflow-execution/SwimlaneTimeline';\nimport { EventTable } from './workflow-execution/EventTable';\n\nfunction ActionsDropdown({ isRunning, hasToolCalls, workflowId, onAction }: {\n isRunning: boolean;\n hasToolCalls: boolean;\n workflowId: string;\n onAction: (action: 'restart' | 'terminate') => void;\n}) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!open) return;\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 }, [open]);\n\n return (\n <div className=\"relative\" ref={ref}>\n <button onClick={() => setOpen(!open)} className=\"btn-primary text-xs\">\n Actions\n </button>\n {open && (\n <div className=\"absolute right-0 mt-1 w-44 bg-surface-raised border border-surface-border rounded-md shadow-lg z-10\">\n <button\n onClick={() => { onAction('restart'); setOpen(false); }}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n >\n Restart Workflow\n </button>\n {isRunning && (\n <button\n onClick={() => { onAction('terminate'); setOpen(false); }}\n className=\"block w-full text-left px-4 py-2 text-xs text-status-error hover:bg-surface-hover\"\n >\n Terminate\n </button>\n )}\n {hasToolCalls && (\n <Link\n to={`/mcp/queries/${workflowId}?step=3`}\n className=\"block w-full text-left px-4 py-2 text-xs text-accent hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n Compile into Pipeline\n </Link>\n )}\n <Link\n to={`/mcp/executions/${encodeURIComponent(workflowId)}?namespace=durable`}\n className=\"block w-full text-left px-4 py-2 text-xs text-text-secondary hover:bg-surface-hover\"\n onClick={() => setOpen(false)}\n >\n View Raw Execution\n </Link>\n </div>\n )}\n </div>\n );\n}\n\nexport function WorkflowExecutionPage() {\n const { workflowId } = useParams<{ workflowId: string }>();\n const { pathname } = useLocation();\n useWorkflowDetailEvents(workflowId);\n\n const executionTitle = pathname.startsWith('/workflows/durable/')\n ? 'Durable Execution'\n : 'Durable Execution';\n const { data: execution, isLoading, error, refetch, isFetching } = useWorkflowExecution(workflowId!);\n const { data: task } = useTaskByWorkflowId(workflowId!);\n const { data: childTasksData } = useChildTasks(workflowId!);\n const { data: escalationsData } = useEscalationsByWorkflowId(workflowId);\n const navigate = useNavigate();\n const terminateMutation = useTerminateWorkflow();\n const { isCollapsed, toggle } = useCollapsedSections('workflow-execution');\n\n const handleAction = (action: 'restart' | 'terminate') => {\n if (action === 'terminate') {\n if (confirm('Are you sure you want to terminate this workflow?')) {\n terminateMutation.mutate(workflowId!);\n }\n } else if (action === 'restart' && execution) {\n // Extract entity from workflow_id (format: {entity}-{guid})\n const entity = execution.workflow_id.replace(/-[A-Za-z0-9_-]{20,}$/, '');\n // Extract original input from the started event\n const startEvent = execution.events.find((e) => e.event_type === 'workflow_execution_started');\n const input = (startEvent?.attributes as any)?.input;\n if (input) {\n sessionStorage.setItem('lt:invoke:prefill', JSON.stringify(input));\n }\n navigate(`/workflows/start?type=${encodeURIComponent(entity)}&mode=now`);\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-60 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n if (error || !execution) {\n const msg = (error as Error)?.message ?? '';\n const isExpired = msg.includes('expired') || msg.includes('no longer available');\n\n return (\n <div>\n <Link to=\"/workflows/executions\" className=\"text-xs text-text-tertiary hover:text-text-primary\">\n &larr; Workflows\n </Link>\n <div className=\"mt-4 text-center py-8\">\n <p className=\"text-sm text-text-primary mb-1\">\n {isExpired\n ? 'Execution data is no longer available'\n : error\n ? 'Unable to load execution'\n : 'Execution not found'}\n </p>\n <p className=\"text-xs text-text-tertiary\">\n {isExpired\n ? \"This workflow's underlying job has expired. The task record is preserved, but the execution timeline has been cleaned up.\"\n : msg || 'The workflow could not be resolved.'}\n </p>\n </div>\n </div>\n );\n }\n\n const isRunning = execution.status !== 'completed' && execution.status !== 'failed';\n const hasToolCalls = execution.status === 'completed' && execution.events.some(\n (e) => {\n if (e.event_type !== 'activity_task_completed') return false;\n const actType = (e.attributes as any).activity_type;\n return actType === 'callDbTool' || actType === 'callVisionTool' || actType === 'callMcpTool' || actType?.startsWith('mcp_');\n },\n );\n\n return (\n <div>\n <PageHeader\n title={executionTitle}\n actions={\n <div className=\"flex items-center gap-3\">\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/workflow-states/${workflowId}/execution`}\n />\n <StatusBadge status={execution.status} />\n <ActionsDropdown\n isRunning={isRunning}\n hasToolCalls={hasToolCalls}\n workflowId={workflowId!}\n onAction={handleAction}\n />\n </div>\n }\n />\n\n <ExecutionHeader\n execution={execution}\n task={task}\n childTasks={childTasksData?.tasks}\n escalations={escalationsData?.escalations}\n />\n\n {terminateMutation.error && (\n <div className=\"py-3 mb-6\">\n <p className=\"text-xs text-status-error\">\n Terminate failed: {terminateMutation.error.message}\n </p>\n </div>\n )}\n\n\n <div className=\"space-y-6\">\n <CollapsibleSection title=\"Details\" sectionKey=\"details\" isCollapsed={isCollapsed('details')} onToggle={toggle} contentClassName=\"mt-4 ml-9\">\n <ExecutionInputResult execution={execution} />\n </CollapsibleSection>\n\n <CollapsibleSection title=\"Execution Timeline\" sectionKey=\"timeline\" isCollapsed={isCollapsed('timeline')} onToggle={toggle} contentClassName=\"mt-4 ml-9\">\n <SwimlaneTimeline\n events={execution.events}\n childTasks={childTasksData?.tasks}\n />\n </CollapsibleSection>\n\n <CollapsibleSection title=\"Events\" sectionKey=\"events\" isCollapsed={isCollapsed('events')} onToggle={toggle} contentClassName=\"mt-4 ml-9\">\n <EventTable\n events={execution.events}\n childTasks={childTasksData?.tasks}\n />\n </CollapsibleSection>\n </div>\n </div>\n );\n}\n"],"names":["MetadataField","label","value","mono","truncate","children","jsx","splitEntityKey","compound","lastDash","ExecutionHeader","execution","task","escalations","executionParent","taskParent","rawParent","parentWorkflowId","taskQueue","workflowType","jsxs","CopyableId","DateValue","DurationValue","Link","esc","StatusBadge","extractInput","startEvent","e","input","_a","ExecutionInputResult","rawResult","result","JsonViewer","ActionsDropdown","isRunning","hasToolCalls","workflowId","onAction","open","setOpen","useState","ref","useRef","useEffect","handler","WorkflowExecutionPage","useParams","pathname","useLocation","useWorkflowDetailEvents","executionTitle","isLoading","error","refetch","isFetching","useWorkflowExecution","useTaskByWorkflowId","childTasksData","useChildTasks","escalationsData","useEscalationsByWorkflowId","navigate","useNavigate","terminateMutation","useTerminateWorkflow","isCollapsed","toggle","useCollapsedSections","handleAction","action","entity","msg","isExpired","actType","PageHeader","ListToolbar","CollapsibleSection","SwimlaneTimeline","EventTable"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{j as n}from"./vendor-query-B2UbickB.js";import{c as d,Z as u,W as f,S as m,aa as h}from"./vendor-icons-B_Yla7iD.js";const s=[{text:"text-rose-400",bg:"bg-rose-400/[0.08]"},{text:"text-pink-400",bg:"bg-pink-400/[0.08]"},{text:"text-fuchsia-400",bg:"bg-fuchsia-400/[0.08]"},{text:"text-purple-400",bg:"bg-purple-400/[0.08]"},{text:"text-violet-400",bg:"bg-violet-400/[0.08]"},{text:"text-indigo-400",bg:"bg-indigo-400/[0.08]"},{text:"text-blue-400",bg:"bg-blue-400/[0.08]"},{text:"text-sky-400",bg:"bg-sky-400/[0.08]"},{text:"text-cyan-400",bg:"bg-cyan-400/[0.08]"},{text:"text-teal-400",bg:"bg-teal-400/[0.08]"},{text:"text-emerald-400",bg:"bg-emerald-400/[0.08]"},{text:"text-green-400",bg:"bg-green-400/[0.08]"},{text:"text-lime-400",bg:"bg-lime-400/[0.08]"},{text:"text-yellow-400",bg:"bg-yellow-400/[0.08]"},{text:"text-amber-400",bg:"bg-amber-400/[0.08]"},{text:"text-orange-400",bg:"bg-orange-400/[0.08]"},{text:"text-red-400",bg:"bg-red-400/[0.08]"},{text:"text-stone-400",bg:"bg-stone-400/[0.08]"},{text:"text-rose-300",bg:"bg-rose-300/[0.08]"},{text:"text-violet-300",bg:"bg-violet-300/[0.08]"},{text:"text-sky-300",bg:"bg-sky-300/[0.08]"},{text:"text-teal-300",bg:"bg-teal-300/[0.08]"},{text:"text-amber-300",bg:"bg-amber-300/[0.08]"},{text:"text-pink-300",bg:"bg-pink-300/[0.08]"}];function y(e){let t=0;for(let x=0;x<e.length;x++)t=(t<<5)-t+e.charCodeAt(x)|0;return Math.abs(t)}function k(e){return s[y(e)%s.length]}const C={certified:h,configured:m,pipeline:f,capability:u,durable:d},w={certified:"text-status-success",configured:"text-status-info"};function N({type:e,size:t="sm",certified:x,variant:r}){const a=t==="md"?"px-2.5 py-0.5 gap-1.5":t==="xs"?"px-1 py-px gap-0.5":"px-1.5 py-px gap-1",l=t==="md"?"13px":t==="xs"?"9px":"11px",i=t==="md"?"w-3.5 h-3.5":t==="xs"?"w-2 h-2":"w-2.5 h-2.5",o=r??(x?"certified":"durable"),c=C[o],b=w[o],g=b?null:k(e),p=b||((g==null?void 0:g.text)??"text-accent/75");return n.jsxs("span",{className:`inline-flex items-center ${a} font-mono text-text-secondary border border-surface-border rounded-lg`,style:{fontSize:l,lineHeight:1.1},children:[n.jsx(c,{className:`${i} shrink-0 ${p}`}),e]})}export{N as W};
2
+ //# sourceMappingURL=WorkflowPill-Bg2-0Hkg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WorkflowPill-Bg2-0Hkg.js","sources":["../../src/lib/type-color.ts","../../src/components/common/display/WorkflowPill.tsx"],"sourcesContent":["/**\n * Deterministic color assignment for workflow type names.\n *\n * Maps any string to a consistent color from a curated 24-color palette.\n * The same type name always produces the same color across the entire UI.\n * Uses a simple hash to distribute names evenly across the palette.\n *\n * Each entry provides:\n * text — icon and text color (Tailwind class)\n * bg — subtle background tint (Tailwind class)\n */\n\nconst PALETTE: Array<{ text: string; bg: string }> = [\n { text: 'text-rose-400', bg: 'bg-rose-400/[0.08]' },\n { text: 'text-pink-400', bg: 'bg-pink-400/[0.08]' },\n { text: 'text-fuchsia-400', bg: 'bg-fuchsia-400/[0.08]' },\n { text: 'text-purple-400', bg: 'bg-purple-400/[0.08]' },\n { text: 'text-violet-400', bg: 'bg-violet-400/[0.08]' },\n { text: 'text-indigo-400', bg: 'bg-indigo-400/[0.08]' },\n { text: 'text-blue-400', bg: 'bg-blue-400/[0.08]' },\n { text: 'text-sky-400', bg: 'bg-sky-400/[0.08]' },\n { text: 'text-cyan-400', bg: 'bg-cyan-400/[0.08]' },\n { text: 'text-teal-400', bg: 'bg-teal-400/[0.08]' },\n { text: 'text-emerald-400', bg: 'bg-emerald-400/[0.08]' },\n { text: 'text-green-400', bg: 'bg-green-400/[0.08]' },\n { text: 'text-lime-400', bg: 'bg-lime-400/[0.08]' },\n { text: 'text-yellow-400', bg: 'bg-yellow-400/[0.08]' },\n { text: 'text-amber-400', bg: 'bg-amber-400/[0.08]' },\n { text: 'text-orange-400', bg: 'bg-orange-400/[0.08]' },\n { text: 'text-red-400', bg: 'bg-red-400/[0.08]' },\n { text: 'text-stone-400', bg: 'bg-stone-400/[0.08]' },\n { text: 'text-rose-300', bg: 'bg-rose-300/[0.08]' },\n { text: 'text-violet-300', bg: 'bg-violet-300/[0.08]' },\n { text: 'text-sky-300', bg: 'bg-sky-300/[0.08]' },\n { text: 'text-teal-300', bg: 'bg-teal-300/[0.08]' },\n { text: 'text-amber-300', bg: 'bg-amber-300/[0.08]' },\n { text: 'text-pink-300', bg: 'bg-pink-300/[0.08]' },\n];\n\nfunction hash(str: string): number {\n let h = 0;\n for (let i = 0; i < str.length; i++) {\n h = ((h << 5) - h + str.charCodeAt(i)) | 0;\n }\n return Math.abs(h);\n}\n\nexport function typeColor(typeName: string): { text: string; bg: string } {\n return PALETTE[hash(typeName) % PALETTE.length];\n}\n","import { Workflow, ShieldCheck, Settings, Wand2, Zap } from 'lucide-react';\nimport { typeColor } from '../../../lib/type-color';\n\ntype WorkflowVariant = 'durable' | 'configured' | 'certified' | 'pipeline' | 'capability';\n\ninterface WorkflowPillProps {\n type: string;\n size?: 'xs' | 'sm' | 'md';\n /** @deprecated Use `variant` instead */\n certified?: boolean;\n variant?: WorkflowVariant;\n}\n\nconst VARIANT_ICON: Record<WorkflowVariant, typeof Workflow> = {\n certified: ShieldCheck,\n configured: Settings,\n pipeline: Wand2,\n capability: Zap,\n durable: Workflow,\n};\n\nconst VARIANT_FIXED_COLOR: Record<string, string> = {\n certified: 'text-status-success',\n configured: 'text-status-info',\n};\n\nexport function WorkflowPill({ type, size = 'sm', certified, variant }: WorkflowPillProps) {\n const sizeClass = size === 'md'\n ? 'px-2.5 py-0.5 gap-1.5'\n : size === 'xs'\n ? 'px-1 py-px gap-0.5'\n : 'px-1.5 py-px gap-1';\n const fontSize = size === 'md' ? '13px' : size === 'xs' ? '9px' : '11px';\n const iconClass = size === 'md' ? 'w-3.5 h-3.5' : size === 'xs' ? 'w-2 h-2' : 'w-2.5 h-2.5';\n\n const resolved = variant ?? (certified ? 'certified' : 'durable');\n const Icon = VARIANT_ICON[resolved];\n\n // Pipeline and durable variants get a type-name-derived color.\n // Certified and configured keep their fixed semantic colors.\n const fixedColor = VARIANT_FIXED_COLOR[resolved];\n const derived = fixedColor ? null : typeColor(type);\n const iconColor = fixedColor || (derived?.text ?? 'text-accent/75');\n\n return (\n <span className={`inline-flex items-center ${sizeClass} font-mono text-text-secondary border border-surface-border rounded-lg`} style={{ fontSize, lineHeight: 1.1 }}>\n <Icon className={`${iconClass} shrink-0 ${iconColor}`} />\n {type}\n </span>\n );\n}\n"],"names":["PALETTE","hash","str","h","i","typeColor","typeName","VARIANT_ICON","ShieldCheck","Settings","Wand2","Zap","Workflow","VARIANT_FIXED_COLOR","WorkflowPill","type","size","certified","variant","sizeClass","fontSize","iconClass","resolved","Icon","fixedColor","derived","iconColor","jsxs","jsx"],"mappings":"2HAYA,MAAMA,EAA+C,CACnD,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,mBAAqB,GAAI,uBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,mBAAqB,GAAI,uBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,kBAAqB,GAAI,sBAAA,EACjC,CAAE,KAAM,eAAqB,GAAI,mBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,EACjC,CAAE,KAAM,iBAAqB,GAAI,qBAAA,EACjC,CAAE,KAAM,gBAAqB,GAAI,oBAAA,CACnC,EAEA,SAASC,EAAKC,EAAqB,CACjC,IAAIC,EAAI,EACR,QAASC,EAAI,EAAGA,EAAIF,EAAI,OAAQE,IAC9BD,GAAMA,GAAK,GAAKA,EAAID,EAAI,WAAWE,CAAC,EAAK,EAE3C,OAAO,KAAK,IAAID,CAAC,CACnB,CAEO,SAASE,EAAUC,EAAgD,CACxE,OAAON,EAAQC,EAAKK,CAAQ,EAAIN,EAAQ,MAAM,CAChD,CCpCA,MAAMO,EAAyD,CAC7D,UAAYC,EACZ,WAAYC,EACZ,SAAYC,EACZ,WAAYC,EACZ,QAAYC,CACd,EAEMC,EAA8C,CAClD,UAAY,sBACZ,WAAY,kBACd,EAEO,SAASC,EAAa,CAAE,KAAAC,EAAM,KAAAC,EAAO,KAAM,UAAAC,EAAW,QAAAC,GAA8B,CACzF,MAAMC,EAAYH,IAAS,KACvB,wBACAA,IAAS,KACP,qBACA,qBACAI,EAAWJ,IAAS,KAAO,OAASA,IAAS,KAAO,MAAQ,OAC5DK,EAAYL,IAAS,KAAO,cAAgBA,IAAS,KAAO,UAAY,cAExEM,EAAWJ,IAAYD,EAAY,YAAc,WACjDM,EAAOhB,EAAae,CAAQ,EAI5BE,EAAaX,EAAoBS,CAAQ,EACzCG,EAAUD,EAAa,KAAOnB,EAAUU,CAAI,EAC5CW,EAAYF,KAAeC,GAAA,YAAAA,EAAS,OAAQ,kBAElD,OACEE,EAAAA,KAAC,OAAA,CAAK,UAAW,4BAA4BR,CAAS,yEAA0E,MAAO,CAAE,SAAAC,EAAU,WAAY,GAAA,EAC7J,SAAA,CAAAQ,MAACL,GAAK,UAAW,GAAGF,CAAS,aAAaK,CAAS,GAAI,EACtDX,CAAA,EACH,CAEJ"}
@@ -1,2 +1,2 @@
1
- import{a as u,j as s}from"./vendor-query-B2UbickB.js";import{T as h}from"./TimestampCell-CYFbEhqc.js";import{E as D}from"./ElapsedCell-B79BF5Mj.js";import{u as R,e as z,b as E}from"./workflows-Bf4_w24H.js";import{i as W}from"./index-DcpCR9c_.js";import{b as A}from"./useEventHooks-CkJOmbF-.js";import{u as L}from"./useFilterParams-DZCAaBC7.js";import{D as M}from"./DataTable-D9yuBv0w.js";import{W as I}from"./WorkflowPill-pPuGH8v9.js";import{P as U}from"./PageHeader-Bo0SpcCK.js";import{F as O,b as f}from"./FilterBar-Ck4K4rzu.js";import{S as B}from"./StickyPagination-F9FZsRy9.js";import{L as H}from"./ListToolbar-Bntl2hex.js";import{R as G,a as w}from"./RowActions-Dg-Fsm5O.js";import{r as J,S as V}from"./vendor-icons-BNtvBbnj.js";import{c as q}from"./vendor-react-CX88sFS5.js";import"./EmptyState-BcsfPq9T.js";const K={running:"in_progress",completed:"completed",failed:"failed"},Q={in_progress:"bg-status-active",completed:"bg-status-success",failed:"bg-status-error"},X={running:"text-status-active",completed:"text-status-success",failed:"text-status-error"};function Y(d,n,p,a,r){return[{key:"workflow_id",label:"Workflow ID / Type",render:e=>{const o=Q[K[e.status]??e.status]??"bg-status-pending",m=e.status==="running"?" animate-pulse":"";return s.jsxs("div",{className:"flex items-start gap-2 min-w-0",children:[s.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full mt-1.5 ${o}${m}`,title:e.status}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"font-mono text-xs text-text-primary truncate block",children:e.workflow_id}),s.jsx("div",{className:"mt-0.5",children:s.jsx(I,{type:e.entity,variant:r.get(e.entity)??"durable",size:"xs"})})]})]})}},{key:"created_at",label:"Created",render:e=>s.jsx(h,{date:e.created_at}),className:"w-40",sortable:!0},{key:"updated_at",label:"Updated",render:e=>s.jsx(h,{date:e.updated_at}),className:"w-40",sortable:!0},{key:"duration",label:"Duration",render:e=>s.jsx(D,{startDate:e.created_at,endDate:e.status==="running"?null:e.updated_at,isLive:e.status==="running"}),className:"w-28"},{key:"actions",label:"",render:e=>s.jsxs(G,{children:[s.jsx(w,{icon:J,title:`Filter by ${e.entity}`,onClick:()=>d(e.entity)}),s.jsx("button",{onClick:o=>{o.stopPropagation(),n(e.status)},className:"opacity-0 group-hover/row:opacity-100 transition-opacity",title:`Filter by ${e.status}`,children:s.jsx("svg",{className:`w-[18px] h-[18px] ${X[e.status]??"text-text-tertiary"} hover:opacity-70`,viewBox:"0 0 24 24",fill:"currentColor",children:s.jsx("circle",{cx:"12",cy:"12",r:"6"})})}),p&&s.jsx(w,{icon:V,title:"View config",onClick:()=>a(`/workflows/registry/${encodeURIComponent(e.entity)}`)})]}),className:"w-24 text-right"}]}function xe({tier:d="all"}){A();const n=q(),{isSuperAdmin:p}=W(),{filters:a,setFilter:r,pagination:e,sort:o,setSort:m}=L({filters:{search:"",entity:"",status:"",tier:d}}),l=a.tier||"all",v=l==="certified"?"true":l==="durable"?"false":void 0,{data:g}=R(),{data:x}=z(),k=u.useMemo(()=>{const t=new Map;for(const y of x??[])t.set(y.workflow_type,y.tier??"durable");return t},[x]),j=Y(t=>r("entity",t),t=>r("status",t),p,n,k),[c,S]=u.useState(a.search);u.useEffect(()=>{if(c===a.search)return;const t=setTimeout(()=>r("search",c),300);return()=>clearTimeout(t)},[c,r,a.search]);const{data:i,isLoading:C,refetch:_,isFetching:$}=E({limit:e.pageSize,offset:e.offset,entity:a.entity||void 0,search:a.search||void 0,status:a.status||void 0,sort_by:o.sort_by||void 0,order:o.sort_by?o.order:void 0,registered:v}),b=(i==null?void 0:i.total)??0,N=(i==null?void 0:i.jobs)??[],T=u.useMemo(()=>[...new Set((g??[]).map(t=>t.workflow_type))].sort(),[g]),P="Durable Executions",F=l==="certified"?"No certified workflow executions found":l==="durable"?"No durable workflow executions found":"No workflow executions found";return s.jsxs("div",{children:[s.jsx(U,{title:P,docsHash:"#docs:dashboard.md:durable-executions"}),s.jsxs(O,{actions:s.jsx(H,{onRefresh:()=>_(),isFetching:$,apiPath:`/workflow-states/jobs?limit=${e.pageSize}&offset=${e.offset}${a.entity?`&entity=${a.entity}`:""}${a.search?`&search=${a.search}`:""}${a.status?`&status=${a.status}`:""}${o.sort_by?`&sort_by=${o.sort_by}&order=${o.order}`:""}`}),children:[s.jsx("input",{type:"text",placeholder:"Search workflow ID...",value:c,onChange:t=>S(t.target.value),className:"input text-[11px] py-1 px-2 w-56"}),s.jsx(f,{label:"Type",value:a.entity,onChange:t=>r("entity",t),options:T.map(t=>({value:t,label:t}))}),s.jsx(f,{label:"Status",value:a.status,onChange:t=>r("status",t),options:[{value:"running",label:"Running"},{value:"completed",label:"Completed"},{value:"failed",label:"Failed"}]}),s.jsx(f,{label:"Tier",value:a.tier==="all"?"":a.tier,onChange:t=>r("tier",t||"all"),options:[{value:"certified",label:"Certified"},{value:"durable",label:"Durable"}]})]}),s.jsx(M,{columns:j,data:N,keyFn:t=>t.workflow_id,onRowClick:t=>n(`/workflows/executions/${t.workflow_id}`),isLoading:C,emptyMessage:F,sort:o,onSort:m}),s.jsx(B,{page:e.page,totalPages:e.totalPages(b),onPageChange:e.setPage,total:b,pageSize:e.pageSize,onPageSizeChange:e.setPageSize})]})}export{xe as WorkflowsDashboard};
2
- //# sourceMappingURL=WorkflowsDashboard-_LMWc-OC.js.map
1
+ import{a as u,j as s}from"./vendor-query-B2UbickB.js";import{T as h}from"./TimestampCell-Bi2nc9Q_.js";import{E as D}from"./ElapsedCell-CzVjr74Y.js";import{u as R,e as z,b as E}from"./workflows-Do-Eiv8f.js";import{j as W}from"./index-DZX-E_3q.js";import{b as A}from"./useEventHooks-CPyvFlVR.js";import{u as L}from"./useFilterParams-DZCAaBC7.js";import{D as M}from"./DataTable-D9yuBv0w.js";import{W as I}from"./WorkflowPill-Bg2-0Hkg.js";import{P as U}from"./PageHeader-B_gV_jKk.js";import{F as O,b as f}from"./FilterBar-Ck4K4rzu.js";import{S as B}from"./StickyPagination-F9FZsRy9.js";import{L as H}from"./ListToolbar-DNAGFe14.js";import{R as G,a as w}from"./RowActions-Dg-Fsm5O.js";import{r as J,S as V}from"./vendor-icons-B_Yla7iD.js";import{c as q}from"./vendor-react-CX88sFS5.js";import"./EmptyState-BcsfPq9T.js";const K={running:"in_progress",completed:"completed",failed:"failed"},Q={in_progress:"bg-status-active",completed:"bg-status-success",failed:"bg-status-error"},X={running:"text-status-active",completed:"text-status-success",failed:"text-status-error"};function Y(d,n,p,a,r){return[{key:"workflow_id",label:"Workflow ID / Type",render:e=>{const o=Q[K[e.status]??e.status]??"bg-status-pending",m=e.status==="running"?" animate-pulse":"";return s.jsxs("div",{className:"flex items-start gap-2 min-w-0",children:[s.jsx("span",{className:`w-1.5 h-1.5 shrink-0 rounded-full mt-1.5 ${o}${m}`,title:e.status}),s.jsxs("div",{className:"min-w-0",children:[s.jsx("span",{className:"font-mono text-xs text-text-primary truncate block",children:e.workflow_id}),s.jsx("div",{className:"mt-0.5",children:s.jsx(I,{type:e.entity,variant:r.get(e.entity)??"durable",size:"xs"})})]})]})}},{key:"created_at",label:"Created",render:e=>s.jsx(h,{date:e.created_at}),className:"w-40",sortable:!0},{key:"updated_at",label:"Updated",render:e=>s.jsx(h,{date:e.updated_at}),className:"w-40",sortable:!0},{key:"duration",label:"Duration",render:e=>s.jsx(D,{startDate:e.created_at,endDate:e.status==="running"?null:e.updated_at,isLive:e.status==="running"}),className:"w-28"},{key:"actions",label:"",render:e=>s.jsxs(G,{children:[s.jsx(w,{icon:J,title:`Filter by ${e.entity}`,onClick:()=>d(e.entity)}),s.jsx("button",{onClick:o=>{o.stopPropagation(),n(e.status)},className:"opacity-0 group-hover/row:opacity-100 transition-opacity",title:`Filter by ${e.status}`,children:s.jsx("svg",{className:`w-[18px] h-[18px] ${X[e.status]??"text-text-tertiary"} hover:opacity-70`,viewBox:"0 0 24 24",fill:"currentColor",children:s.jsx("circle",{cx:"12",cy:"12",r:"6"})})}),p&&s.jsx(w,{icon:V,title:"View config",onClick:()=>a(`/workflows/registry/${encodeURIComponent(e.entity)}`)})]}),className:"w-24 text-right"}]}function xe({tier:d="all"}){A();const n=q(),{isSuperAdmin:p}=W(),{filters:a,setFilter:r,pagination:e,sort:o,setSort:m}=L({filters:{search:"",entity:"",status:"",tier:d}}),l=a.tier||"all",v=l==="certified"?"true":l==="durable"?"false":void 0,{data:g}=R(),{data:x}=z(),k=u.useMemo(()=>{const t=new Map;for(const y of x??[])t.set(y.workflow_type,y.tier??"durable");return t},[x]),j=Y(t=>r("entity",t),t=>r("status",t),p,n,k),[c,S]=u.useState(a.search);u.useEffect(()=>{if(c===a.search)return;const t=setTimeout(()=>r("search",c),300);return()=>clearTimeout(t)},[c,r,a.search]);const{data:i,isLoading:C,refetch:_,isFetching:$}=E({limit:e.pageSize,offset:e.offset,entity:a.entity||void 0,search:a.search||void 0,status:a.status||void 0,sort_by:o.sort_by||void 0,order:o.sort_by?o.order:void 0,registered:v}),b=(i==null?void 0:i.total)??0,N=(i==null?void 0:i.jobs)??[],T=u.useMemo(()=>[...new Set((g??[]).map(t=>t.workflow_type))].sort(),[g]),P="Durable Executions",F=l==="certified"?"No certified workflow executions found":l==="durable"?"No durable workflow executions found":"No workflow executions found";return s.jsxs("div",{children:[s.jsx(U,{title:P,docsHash:"#docs:dashboard.md:durable-executions"}),s.jsxs(O,{actions:s.jsx(H,{onRefresh:()=>_(),isFetching:$,apiPath:`/workflow-states/jobs?limit=${e.pageSize}&offset=${e.offset}${a.entity?`&entity=${a.entity}`:""}${a.search?`&search=${a.search}`:""}${a.status?`&status=${a.status}`:""}${o.sort_by?`&sort_by=${o.sort_by}&order=${o.order}`:""}`}),children:[s.jsx("input",{type:"text",placeholder:"Search workflow ID...",value:c,onChange:t=>S(t.target.value),className:"input text-[11px] py-1 px-2 w-56"}),s.jsx(f,{label:"Type",value:a.entity,onChange:t=>r("entity",t),options:T.map(t=>({value:t,label:t}))}),s.jsx(f,{label:"Status",value:a.status,onChange:t=>r("status",t),options:[{value:"running",label:"Running"},{value:"completed",label:"Completed"},{value:"failed",label:"Failed"}]}),s.jsx(f,{label:"Tier",value:a.tier==="all"?"":a.tier,onChange:t=>r("tier",t||"all"),options:[{value:"certified",label:"Certified"},{value:"durable",label:"Durable"}]})]}),s.jsx(M,{columns:j,data:N,keyFn:t=>t.workflow_id,onRowClick:t=>n(`/workflows/executions/${t.workflow_id}`),isLoading:C,emptyMessage:F,sort:o,onSort:m}),s.jsx(B,{page:e.page,totalPages:e.totalPages(b),onPageChange:e.setPage,total:b,pageSize:e.pageSize,onPageSizeChange:e.setPageSize})]})}export{xe as WorkflowsDashboard};
2
+ //# sourceMappingURL=WorkflowsDashboard-BzH7jMRu.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowsDashboard-_LMWc-OC.js","sources":["../../src/pages/workflows/WorkflowsDashboard.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter, Settings } from 'lucide-react';\nimport { TimestampCell } from '../../components/common/display/TimestampCell';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { useJobs, useWorkflowConfigs, useDiscoveredWorkflows } from '../../api/workflows';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob, WorkflowTier } from '../../api/types';\n\nexport type ExecutionsTier = 'all' | 'certified' | 'durable';\n\nconst jobStatusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n isSuperAdmin: boolean,\n navigate: (path: string) => void,\n tierMap: Map<string, WorkflowTier>,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID / Type',\n render: (row) => {\n const dotClass = STATUS_DOT[jobStatusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-start gap-2 min-w-0\">\n <span className={`w-1.5 h-1.5 shrink-0 rounded-full mt-1.5 ${dotClass}${pulseClass}`} title={row.status} />\n <div className=\"min-w-0\">\n <span className=\"font-mono text-xs text-text-primary truncate block\">\n {row.workflow_id}\n </span>\n <div className=\"mt-0.5\">\n <WorkflowPill type={row.entity} variant={tierMap.get(row.entity) ?? 'durable'} size=\"xs\" />\n </div>\n </div>\n </div>\n );\n },\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <TimestampCell date={row.updated_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n {isSuperAdmin && (\n <RowAction\n icon={Settings}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.entity)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function WorkflowsDashboard({ tier: initialTier = 'all' }: { tier?: ExecutionsTier }) {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const { isSuperAdmin } = useAuth();\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', tier: initialTier },\n });\n\n const activeTier = (filters.tier || 'all') as ExecutionsTier;\n\n // Map tier to server-side registered filter\n const registeredFilter = activeTier === 'certified' ? 'true'\n : activeTier === 'durable' ? 'false'\n : undefined;\n\n const { data: configs } = useWorkflowConfigs();\n const { data: discoveredData } = useDiscoveredWorkflows();\n\n const tierMap = useMemo(() => {\n const map = new Map<string, WorkflowTier>();\n for (const dw of discoveredData ?? []) {\n map.set(dw.workflow_type, dw.tier ?? 'durable');\n }\n return map;\n }, [discoveredData]);\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n isSuperAdmin,\n navigate,\n tierMap,\n );\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: jobsData, isLoading, refetch, isFetching } = useJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || undefined,\n order: sort.sort_by ? sort.order : undefined,\n registered: registeredFilter,\n });\n\n const total = jobsData?.total ?? 0;\n const jobs = jobsData?.jobs ?? [];\n\n const entities = useMemo(() => {\n return [...new Set((configs ?? []).map((c) => c.workflow_type))].sort();\n }, [configs]);\n\n const pageTitle = 'Durable Executions';\n\n const emptyMessage = activeTier === 'certified'\n ? 'No certified workflow executions found'\n : activeTier === 'durable'\n ? 'No durable workflow executions found'\n : 'No workflow executions found';\n\n return (\n <div>\n <PageHeader title={pageTitle} docsHash=\"#docs:dashboard.md:durable-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/workflow-states/jobs?limit=${pagination.pageSize}&offset=${pagination.offset}${filters.entity ? `&entity=${filters.entity}` : ''}${filters.search ? `&search=${filters.search}` : ''}${filters.status ? `&status=${filters.status}` : ''}${sort.sort_by ? `&sort_by=${sort.sort_by}&order=${sort.order}` : ''}`}\n />\n }>\n <input\n type=\"text\"\n placeholder=\"Search workflow ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Type\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities.map((e) => ({ value: e, label: e }))}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n <FilterSelect\n label=\"Tier\"\n value={filters.tier === 'all' ? '' : filters.tier}\n onChange={(v) => setFilter('tier', v || 'all')}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/workflows/executions/${row.workflow_id}`)}\n isLoading={isLoading}\n emptyMessage={emptyMessage}\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 </div>\n );\n}\n"],"names":["jobStatusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","isSuperAdmin","navigate","tierMap","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","TimestampCell","ElapsedCell","RowActionGroup","RowAction","Filter","e","Settings","WorkflowsDashboard","initialTier","useWorkflowListEvents","useNavigate","useAuth","filters","setFilter","pagination","sort","setSort","useFilterParams","activeTier","registeredFilter","configs","useWorkflowConfigs","discoveredData","useDiscoveredWorkflows","useMemo","map","dw","columns","entity","status","searchInput","setSearchInput","useState","useEffect","timer","jobsData","isLoading","refetch","isFetching","useJobs","total","jobs","entities","c","pageTitle","emptyMessage","PageHeader","FilterBar","ListToolbar","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
1
+ {"version":3,"file":"WorkflowsDashboard-BzH7jMRu.js","sources":["../../src/pages/workflows/WorkflowsDashboard.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Filter, Settings } from 'lucide-react';\nimport { TimestampCell } from '../../components/common/display/TimestampCell';\nimport { ElapsedCell } from '../../components/common/display/ElapsedCell';\nimport { useJobs, useWorkflowConfigs, useDiscoveredWorkflows } from '../../api/workflows';\nimport { useAuth } from '../../hooks/useAuth';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { useFilterParams } from '../../hooks/useFilterParams';\nimport { DataTable, type Column } from '../../components/common/data/DataTable';\nimport { WorkflowPill } from '../../components/common/display/WorkflowPill';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect } from '../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../components/common/data/StickyPagination';\nimport { ListToolbar } from '../../components/common/data/ListToolbar';\nimport { RowAction, RowActionGroup } from '../../components/common/layout/RowActions';\nimport type { LTJob, WorkflowTier } from '../../api/types';\n\nexport type ExecutionsTier = 'all' | 'certified' | 'durable';\n\nconst jobStatusMap: Record<string, string> = {\n running: 'in_progress',\n completed: 'completed',\n failed: 'failed',\n};\n\nconst STATUS_DOT: Record<string, string> = {\n in_progress: 'bg-status-active',\n completed: 'bg-status-success',\n failed: 'bg-status-error',\n};\n\nconst STATUS_COLORS: Record<string, string> = {\n running: 'text-status-active',\n completed: 'text-status-success',\n failed: 'text-status-error',\n};\n\nfunction buildColumns(\n onFilterEntity: (entity: string) => void,\n onFilterStatus: (status: string) => void,\n isSuperAdmin: boolean,\n navigate: (path: string) => void,\n tierMap: Map<string, WorkflowTier>,\n): Column<LTJob>[] {\n return [\n {\n key: 'workflow_id',\n label: 'Workflow ID / Type',\n render: (row) => {\n const dotClass = STATUS_DOT[jobStatusMap[row.status] ?? row.status] ?? 'bg-status-pending';\n const pulseClass = row.status === 'running' ? ' animate-pulse' : '';\n return (\n <div className=\"flex items-start gap-2 min-w-0\">\n <span className={`w-1.5 h-1.5 shrink-0 rounded-full mt-1.5 ${dotClass}${pulseClass}`} title={row.status} />\n <div className=\"min-w-0\">\n <span className=\"font-mono text-xs text-text-primary truncate block\">\n {row.workflow_id}\n </span>\n <div className=\"mt-0.5\">\n <WorkflowPill type={row.entity} variant={tierMap.get(row.entity) ?? 'durable'} size=\"xs\" />\n </div>\n </div>\n </div>\n );\n },\n },\n {\n key: 'created_at',\n label: 'Created',\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'updated_at',\n label: 'Updated',\n render: (row) => <TimestampCell date={row.updated_at} />,\n className: 'w-40',\n sortable: true,\n },\n {\n key: 'duration',\n label: 'Duration',\n render: (row) => (\n <ElapsedCell\n startDate={row.created_at}\n endDate={row.status === 'running' ? null : row.updated_at}\n isLive={row.status === 'running'}\n />\n ),\n className: 'w-28',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n <RowAction\n icon={Filter}\n title={`Filter by ${row.entity}`}\n onClick={() => onFilterEntity(row.entity)}\n />\n <button\n onClick={(e) => { e.stopPropagation(); onFilterStatus(row.status); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity\"\n title={`Filter by ${row.status}`}\n >\n <svg className={`w-[18px] h-[18px] ${STATUS_COLORS[row.status] ?? 'text-text-tertiary'} hover:opacity-70`} viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n </svg>\n </button>\n {isSuperAdmin && (\n <RowAction\n icon={Settings}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.entity)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-24 text-right',\n },\n ];\n}\n\nexport function WorkflowsDashboard({ tier: initialTier = 'all' }: { tier?: ExecutionsTier }) {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const { isSuperAdmin } = useAuth();\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { search: '', entity: '', status: '', tier: initialTier },\n });\n\n const activeTier = (filters.tier || 'all') as ExecutionsTier;\n\n // Map tier to server-side registered filter\n const registeredFilter = activeTier === 'certified' ? 'true'\n : activeTier === 'durable' ? 'false'\n : undefined;\n\n const { data: configs } = useWorkflowConfigs();\n const { data: discoveredData } = useDiscoveredWorkflows();\n\n const tierMap = useMemo(() => {\n const map = new Map<string, WorkflowTier>();\n for (const dw of discoveredData ?? []) {\n map.set(dw.workflow_type, dw.tier ?? 'durable');\n }\n return map;\n }, [discoveredData]);\n\n const columns = buildColumns(\n (entity) => setFilter('entity', entity),\n (status) => setFilter('status', status),\n isSuperAdmin,\n navigate,\n tierMap,\n );\n const [searchInput, setSearchInput] = useState(filters.search);\n\n useEffect(() => {\n if (searchInput === filters.search) return;\n const timer = setTimeout(() => setFilter('search', searchInput), 300);\n return () => clearTimeout(timer);\n }, [searchInput, setFilter, filters.search]);\n\n const { data: jobsData, isLoading, refetch, isFetching } = useJobs({\n limit: pagination.pageSize,\n offset: pagination.offset,\n entity: filters.entity || undefined,\n search: filters.search || undefined,\n status: filters.status || undefined,\n sort_by: sort.sort_by || undefined,\n order: sort.sort_by ? sort.order : undefined,\n registered: registeredFilter,\n });\n\n const total = jobsData?.total ?? 0;\n const jobs = jobsData?.jobs ?? [];\n\n const entities = useMemo(() => {\n return [...new Set((configs ?? []).map((c) => c.workflow_type))].sort();\n }, [configs]);\n\n const pageTitle = 'Durable Executions';\n\n const emptyMessage = activeTier === 'certified'\n ? 'No certified workflow executions found'\n : activeTier === 'durable'\n ? 'No durable workflow executions found'\n : 'No workflow executions found';\n\n return (\n <div>\n <PageHeader title={pageTitle} docsHash=\"#docs:dashboard.md:durable-executions\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={`/workflow-states/jobs?limit=${pagination.pageSize}&offset=${pagination.offset}${filters.entity ? `&entity=${filters.entity}` : ''}${filters.search ? `&search=${filters.search}` : ''}${filters.status ? `&status=${filters.status}` : ''}${sort.sort_by ? `&sort_by=${sort.sort_by}&order=${sort.order}` : ''}`}\n />\n }>\n <input\n type=\"text\"\n placeholder=\"Search workflow ID...\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n className=\"input text-[11px] py-1 px-2 w-56\"\n />\n <FilterSelect\n label=\"Type\"\n value={filters.entity}\n onChange={(v) => setFilter('entity', v)}\n options={entities.map((e) => ({ value: e, label: e }))}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'running', label: 'Running' },\n { value: 'completed', label: 'Completed' },\n { value: 'failed', label: 'Failed' },\n ]}\n />\n <FilterSelect\n label=\"Tier\"\n value={filters.tier === 'all' ? '' : filters.tier}\n onChange={(v) => setFilter('tier', v || 'all')}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={jobs}\n keyFn={(row) => row.workflow_id}\n onRowClick={(row) => navigate(`/workflows/executions/${row.workflow_id}`)}\n isLoading={isLoading}\n emptyMessage={emptyMessage}\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 </div>\n );\n}\n"],"names":["jobStatusMap","STATUS_DOT","STATUS_COLORS","buildColumns","onFilterEntity","onFilterStatus","isSuperAdmin","navigate","tierMap","row","dotClass","pulseClass","jsxs","jsx","WorkflowPill","TimestampCell","ElapsedCell","RowActionGroup","RowAction","Filter","e","Settings","WorkflowsDashboard","initialTier","useWorkflowListEvents","useNavigate","useAuth","filters","setFilter","pagination","sort","setSort","useFilterParams","activeTier","registeredFilter","configs","useWorkflowConfigs","discoveredData","useDiscoveredWorkflows","useMemo","map","dw","columns","entity","status","searchInput","setSearchInput","useState","useEffect","timer","jobsData","isLoading","refetch","isFetching","useJobs","total","jobs","entities","c","pageTitle","emptyMessage","PageHeader","FilterBar","ListToolbar","FilterSelect","v","DataTable","StickyPagination"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as x,j as t}from"./vendor-query-B2UbickB.js";import{b as C,u as k}from"./workflows-Bf4_w24H.js";import{b as $}from"./useEventHooks-CkJOmbF-.js";import{P as D}from"./PageHeader-Bo0SpcCK.js";import{S as h}from"./StatCard-DlgF0CJC.js";import{c as w}from"./vendor-react-CX88sFS5.js";import"./index-DcpCR9c_.js";import"./vendor-icons-BNtvBbnj.js";const v=[{label:"1h",ms:36e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"30d",ms:2592e6}];function T(r){return r<1e3?`${Math.round(r)}ms`:r<6e4?`${(r/1e3).toFixed(1)}s`:r<36e5?`${(r/6e4).toFixed(1)}m`:`${(r/36e5).toFixed(1)}h`}function p({value:r,colorClass:o,onClick:f}){return r===0?t.jsx("span",{className:"text-text-tertiary",children:"0"}):t.jsx("button",{onClick:f,className:`${o} hover:underline tabular-nums font-medium`,children:r})}function _(){$();const r=w(),[o,f]=x.useState("24h"),{data:c}=C({limit:500}),{data:g}=k(),b=x.useMemo(()=>{const e=v.find(i=>i.label===o);return Date.now()-e.ms},[o]),n=x.useMemo(()=>((c==null?void 0:c.jobs)??[]).filter(e=>new Date(e.created_at).getTime()>=b),[c==null?void 0:c.jobs,b]),j=x.useMemo(()=>{const e=new Map;for(const a of n){const s=e.get(a.entity)??{total:0,running:0,completed:0,failed:0,durations:[]};if(s.total++,a.status==="running"&&s.running++,a.status==="completed"){s.completed++;const m=new Date(a.updated_at).getTime()-new Date(a.created_at).getTime();m>0&&s.durations.push(m)}a.status==="failed"&&s.failed++,e.set(a.entity,s)}const i=[];for(const[a,s]of e)i.push({type:a,...s,avgDuration:s.durations.length>0?s.durations.reduce((m,N)=>m+N,0)/s.durations.length:null});return i.sort((a,s)=>s.total-a.total)},[n]),u=x.useMemo(()=>({total:n.length,running:n.filter(e=>e.status==="running").length,completed:n.filter(e=>e.status==="completed").length,failed:n.filter(e=>e.status==="failed").length}),[n]),y=(g==null?void 0:g.length)??0,l=(e,i)=>{const a=new URLSearchParams;e&&a.set("entity",e),i&&a.set("status",i);const s=a.toString();r(`/workflows/executions${s?`?${s}`:""}`)},d="pb-2 text-[10px] font-semibold uppercase tracking-widest text-text-tertiary";return t.jsxs("div",{children:[t.jsx(D,{title:"Workflows",actions:t.jsxs("span",{className:"text-xs text-text-tertiary",children:[y," certified type",y!==1?"s":""]})}),t.jsx("div",{className:"flex items-center gap-1 mb-6",children:v.map(e=>t.jsx("button",{onClick:()=>f(e.label),className:`px-3 py-1 text-xs rounded-full transition-colors ${o===e.label?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:e.label},e.label))}),t.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-8",children:[t.jsx(h,{label:"Total",value:u.total,onClick:()=>l()}),t.jsx(h,{label:"Running",value:u.running,colorClass:"text-status-active",onClick:()=>l(void 0,"running")}),t.jsx(h,{label:"Completed",value:u.completed,colorClass:"text-status-success",onClick:()=>l(void 0,"completed")}),t.jsx(h,{label:"Failed",value:u.failed,colorClass:"text-status-error",onClick:()=>l(void 0,"failed")})]}),j.length>0&&t.jsxs("table",{className:"w-full text-left",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-surface-border",children:[t.jsx("th",{className:d,children:"Type"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Total"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Running"}),t.jsx("th",{className:`${d} text-right w-24`,children:"Completed"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Failed"}),t.jsx("th",{className:`${d} text-right w-28`,children:"Avg Duration"})]})}),t.jsx("tbody",{children:j.map(e=>t.jsxs("tr",{className:"border-b border-surface-border last:border-b-0",children:[t.jsx("td",{className:"py-3 text-sm font-mono text-text-primary",children:t.jsx("button",{onClick:()=>l(e.type),className:"hover:text-accent hover:underline",children:e.type})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.total,colorClass:"text-text-secondary",onClick:()=>l(e.type)})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.running,colorClass:"text-status-active",onClick:()=>l(e.type,"running")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.completed,colorClass:"text-status-success",onClick:()=>l(e.type,"completed")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.failed,colorClass:"text-status-error",onClick:()=>l(e.type,"failed")})}),t.jsx("td",{className:"py-3 text-sm font-mono text-text-secondary text-right",children:e.avgDuration!==null?T(e.avgDuration):"—"})]},e.type))})]}),j.length===0&&t.jsx("div",{className:"py-16 text-center",children:t.jsxs("p",{className:"text-sm text-text-tertiary",children:["No workflow activity in the last ",o]})})]})}export{_ as WorkflowsOverview};
2
- //# sourceMappingURL=WorkflowsOverview-DFrfw554.js.map
1
+ import{a as x,j as t}from"./vendor-query-B2UbickB.js";import{b as C,u as k}from"./workflows-Do-Eiv8f.js";import{b as $}from"./useEventHooks-CPyvFlVR.js";import{P as D}from"./PageHeader-B_gV_jKk.js";import{S as h}from"./StatCard-DlgF0CJC.js";import{c as w}from"./vendor-react-CX88sFS5.js";import"./index-DZX-E_3q.js";import"./vendor-icons-B_Yla7iD.js";const v=[{label:"1h",ms:36e5},{label:"24h",ms:864e5},{label:"7d",ms:6048e5},{label:"30d",ms:2592e6}];function T(r){return r<1e3?`${Math.round(r)}ms`:r<6e4?`${(r/1e3).toFixed(1)}s`:r<36e5?`${(r/6e4).toFixed(1)}m`:`${(r/36e5).toFixed(1)}h`}function p({value:r,colorClass:o,onClick:f}){return r===0?t.jsx("span",{className:"text-text-tertiary",children:"0"}):t.jsx("button",{onClick:f,className:`${o} hover:underline tabular-nums font-medium`,children:r})}function _(){$();const r=w(),[o,f]=x.useState("24h"),{data:c}=C({limit:500}),{data:g}=k(),b=x.useMemo(()=>{const e=v.find(i=>i.label===o);return Date.now()-e.ms},[o]),n=x.useMemo(()=>((c==null?void 0:c.jobs)??[]).filter(e=>new Date(e.created_at).getTime()>=b),[c==null?void 0:c.jobs,b]),j=x.useMemo(()=>{const e=new Map;for(const a of n){const s=e.get(a.entity)??{total:0,running:0,completed:0,failed:0,durations:[]};if(s.total++,a.status==="running"&&s.running++,a.status==="completed"){s.completed++;const m=new Date(a.updated_at).getTime()-new Date(a.created_at).getTime();m>0&&s.durations.push(m)}a.status==="failed"&&s.failed++,e.set(a.entity,s)}const i=[];for(const[a,s]of e)i.push({type:a,...s,avgDuration:s.durations.length>0?s.durations.reduce((m,N)=>m+N,0)/s.durations.length:null});return i.sort((a,s)=>s.total-a.total)},[n]),u=x.useMemo(()=>({total:n.length,running:n.filter(e=>e.status==="running").length,completed:n.filter(e=>e.status==="completed").length,failed:n.filter(e=>e.status==="failed").length}),[n]),y=(g==null?void 0:g.length)??0,l=(e,i)=>{const a=new URLSearchParams;e&&a.set("entity",e),i&&a.set("status",i);const s=a.toString();r(`/workflows/executions${s?`?${s}`:""}`)},d="pb-2 text-[10px] font-semibold uppercase tracking-widest text-text-tertiary";return t.jsxs("div",{children:[t.jsx(D,{title:"Workflows",actions:t.jsxs("span",{className:"text-xs text-text-tertiary",children:[y," certified type",y!==1?"s":""]})}),t.jsx("div",{className:"flex items-center gap-1 mb-6",children:v.map(e=>t.jsx("button",{onClick:()=>f(e.label),className:`px-3 py-1 text-xs rounded-full transition-colors ${o===e.label?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:e.label},e.label))}),t.jsxs("div",{className:"grid grid-cols-4 gap-4 mb-8",children:[t.jsx(h,{label:"Total",value:u.total,onClick:()=>l()}),t.jsx(h,{label:"Running",value:u.running,colorClass:"text-status-active",onClick:()=>l(void 0,"running")}),t.jsx(h,{label:"Completed",value:u.completed,colorClass:"text-status-success",onClick:()=>l(void 0,"completed")}),t.jsx(h,{label:"Failed",value:u.failed,colorClass:"text-status-error",onClick:()=>l(void 0,"failed")})]}),j.length>0&&t.jsxs("table",{className:"w-full text-left",children:[t.jsx("thead",{children:t.jsxs("tr",{className:"border-b border-surface-border",children:[t.jsx("th",{className:d,children:"Type"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Total"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Running"}),t.jsx("th",{className:`${d} text-right w-24`,children:"Completed"}),t.jsx("th",{className:`${d} text-right w-20`,children:"Failed"}),t.jsx("th",{className:`${d} text-right w-28`,children:"Avg Duration"})]})}),t.jsx("tbody",{children:j.map(e=>t.jsxs("tr",{className:"border-b border-surface-border last:border-b-0",children:[t.jsx("td",{className:"py-3 text-sm font-mono text-text-primary",children:t.jsx("button",{onClick:()=>l(e.type),className:"hover:text-accent hover:underline",children:e.type})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.total,colorClass:"text-text-secondary",onClick:()=>l(e.type)})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.running,colorClass:"text-status-active",onClick:()=>l(e.type,"running")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.completed,colorClass:"text-status-success",onClick:()=>l(e.type,"completed")})}),t.jsx("td",{className:"py-3 text-sm text-right",children:t.jsx(p,{value:e.failed,colorClass:"text-status-error",onClick:()=>l(e.type,"failed")})}),t.jsx("td",{className:"py-3 text-sm font-mono text-text-secondary text-right",children:e.avgDuration!==null?T(e.avgDuration):"—"})]},e.type))})]}),j.length===0&&t.jsx("div",{className:"py-16 text-center",children:t.jsxs("p",{className:"text-sm text-text-tertiary",children:["No workflow activity in the last ",o]})})]})}export{_ as WorkflowsOverview};
2
+ //# sourceMappingURL=WorkflowsOverview-BcUgBvjD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"WorkflowsOverview-DFrfw554.js","sources":["../../src/pages/workflows/WorkflowsOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useJobs, useWorkflowConfigs } from '../../api/workflows';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface TypeStats {\n type: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Clickable stat cell ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowsOverview() {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n\n const { data: allJobs } = useJobs({ limit: 500 });\n const { data: configs } = useWorkflowConfigs();\n\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const jobs = useMemo(\n () => (allJobs?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allJobs?.jobs, cutoff],\n );\n\n const byType = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of jobs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: TypeStats[] = [];\n for (const [type, stats] of map) {\n result.push({\n type,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [jobs]);\n\n // Totals\n const totals = useMemo(() => ({\n total: jobs.length,\n running: jobs.filter((j) => j.status === 'running').length,\n completed: jobs.filter((j) => j.status === 'completed').length,\n failed: jobs.filter((j) => j.status === 'failed').length,\n }), [jobs]);\n\n const registered = configs?.length ?? 0;\n\n const goToList = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/workflows/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-[10px] font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader\n title=\"Workflows\"\n actions={\n <span className=\"text-xs text-text-tertiary\">\n {registered} certified type{registered !== 1 ? 's' : ''}\n </span>\n }\n />\n\n {/* Duration tabs */}\n <div className=\"flex items-center gap-1 mb-6\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\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 {/* Summary cards */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total\" value={totals.total} onClick={() => goToList()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToList(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToList(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToList(undefined, 'failed')} />\n </div>\n\n {/* By-type table */}\n {byType.length > 0 && (\n <table className=\"w-full text-left\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Type</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byType.map((row) => (\n <tr key={row.type} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToList(row.type)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.type}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToList(row.type)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToList(row.type, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToList(row.type, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToList(row.type, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byType.length === 0 && (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-tertiary\">\n No workflow activity in the last {duration}\n </p>\n </div>\n )}\n </div>\n );\n}"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","WorkflowsOverview","useWorkflowListEvents","navigate","useNavigate","duration","setDuration","useState","allJobs","useJobs","configs","useWorkflowConfigs","cutoff","useMemo","d","jobs","j","byType","map","entry","dur","result","type","stats","a","b","totals","registered","goToList","entity","status","params","qs","thCls","PageHeader","jsxs","StatCard","row"],"mappings":"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"}
1
+ {"version":3,"file":"WorkflowsOverview-BcUgBvjD.js","sources":["../../src/pages/workflows/WorkflowsOverview.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useJobs, useWorkflowConfigs } from '../../api/workflows';\nimport { useWorkflowListEvents } from '../../hooks/useEventHooks';\nimport { PageHeader } from '../../components/common/layout/PageHeader';\nimport { StatCard } from '../../components/common/data/StatCard';\n\n// ── Duration filter ──────────────────────────────────────────────────────────\n\nconst DURATIONS = [\n { label: '1h', ms: 3_600_000 },\n { label: '24h', ms: 86_400_000 },\n { label: '7d', ms: 604_800_000 },\n { label: '30d', ms: 2_592_000_000 },\n] as const;\n\ntype DurationLabel = (typeof DURATIONS)[number]['label'];\n\n// ── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatDuration(ms: number): string {\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n if (ms < 3_600_000) return `${(ms / 60_000).toFixed(1)}m`;\n return `${(ms / 3_600_000).toFixed(1)}h`;\n}\n\ninterface TypeStats {\n type: string;\n total: number;\n running: number;\n completed: number;\n failed: number;\n avgDuration: number | null;\n}\n\n// ── Clickable stat cell ──────────────────────────────────────────────────────\n\nfunction StatCell({\n value,\n colorClass,\n onClick,\n}: {\n value: number;\n colorClass: string;\n onClick: () => void;\n}) {\n if (value === 0) {\n return <span className=\"text-text-tertiary\">0</span>;\n }\n return (\n <button\n onClick={onClick}\n className={`${colorClass} hover:underline tabular-nums font-medium`}\n >\n {value}\n </button>\n );\n}\n\n// ── Page ─────────────────────────────────────────────────────────────────────\n\nexport function WorkflowsOverview() {\n useWorkflowListEvents();\n const navigate = useNavigate();\n const [duration, setDuration] = useState<DurationLabel>('24h');\n\n const { data: allJobs } = useJobs({ limit: 500 });\n const { data: configs } = useWorkflowConfigs();\n\n const cutoff = useMemo(() => {\n const d = DURATIONS.find((d) => d.label === duration)!;\n return Date.now() - d.ms;\n }, [duration]);\n\n const jobs = useMemo(\n () => (allJobs?.jobs ?? []).filter((j) => new Date(j.created_at).getTime() >= cutoff),\n [allJobs?.jobs, cutoff],\n );\n\n const byType = useMemo(() => {\n const map = new Map<string, { total: number; running: number; completed: number; failed: number; durations: number[] }>();\n for (const j of jobs) {\n const entry = map.get(j.entity) ?? { total: 0, running: 0, completed: 0, failed: 0, durations: [] };\n entry.total++;\n if (j.status === 'running') entry.running++;\n if (j.status === 'completed') {\n entry.completed++;\n const dur = new Date(j.updated_at).getTime() - new Date(j.created_at).getTime();\n if (dur > 0) entry.durations.push(dur);\n }\n if (j.status === 'failed') entry.failed++;\n map.set(j.entity, entry);\n }\n\n const result: TypeStats[] = [];\n for (const [type, stats] of map) {\n result.push({\n type,\n ...stats,\n avgDuration: stats.durations.length > 0\n ? stats.durations.reduce((a, b) => a + b, 0) / stats.durations.length\n : null,\n });\n }\n return result.sort((a, b) => b.total - a.total);\n }, [jobs]);\n\n // Totals\n const totals = useMemo(() => ({\n total: jobs.length,\n running: jobs.filter((j) => j.status === 'running').length,\n completed: jobs.filter((j) => j.status === 'completed').length,\n failed: jobs.filter((j) => j.status === 'failed').length,\n }), [jobs]);\n\n const registered = configs?.length ?? 0;\n\n const goToList = (entity?: string, status?: string) => {\n const params = new URLSearchParams();\n if (entity) params.set('entity', entity);\n if (status) params.set('status', status);\n const qs = params.toString();\n navigate(`/workflows/executions${qs ? `?${qs}` : ''}`);\n };\n\n const thCls = 'pb-2 text-[10px] font-semibold uppercase tracking-widest text-text-tertiary';\n\n return (\n <div>\n <PageHeader\n title=\"Workflows\"\n actions={\n <span className=\"text-xs text-text-tertiary\">\n {registered} certified type{registered !== 1 ? 's' : ''}\n </span>\n }\n />\n\n {/* Duration tabs */}\n <div className=\"flex items-center gap-1 mb-6\">\n {DURATIONS.map((d) => (\n <button\n key={d.label}\n onClick={() => setDuration(d.label)}\n className={`px-3 py-1 text-xs rounded-full transition-colors ${\n duration === d.label\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 {/* Summary cards */}\n <div className=\"grid grid-cols-4 gap-4 mb-8\">\n <StatCard label=\"Total\" value={totals.total} onClick={() => goToList()} />\n <StatCard label=\"Running\" value={totals.running} colorClass=\"text-status-active\" onClick={() => goToList(undefined, 'running')} />\n <StatCard label=\"Completed\" value={totals.completed} colorClass=\"text-status-success\" onClick={() => goToList(undefined, 'completed')} />\n <StatCard label=\"Failed\" value={totals.failed} colorClass=\"text-status-error\" onClick={() => goToList(undefined, 'failed')} />\n </div>\n\n {/* By-type table */}\n {byType.length > 0 && (\n <table className=\"w-full text-left\">\n <thead>\n <tr className=\"border-b border-surface-border\">\n <th className={thCls}>Type</th>\n <th className={`${thCls} text-right w-20`}>Total</th>\n <th className={`${thCls} text-right w-20`}>Running</th>\n <th className={`${thCls} text-right w-24`}>Completed</th>\n <th className={`${thCls} text-right w-20`}>Failed</th>\n <th className={`${thCls} text-right w-28`}>Avg Duration</th>\n </tr>\n </thead>\n <tbody>\n {byType.map((row) => (\n <tr key={row.type} className=\"border-b border-surface-border last:border-b-0\">\n <td className=\"py-3 text-sm font-mono text-text-primary\">\n <button\n onClick={() => goToList(row.type)}\n className=\"hover:text-accent hover:underline\"\n >\n {row.type}\n </button>\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.total} colorClass=\"text-text-secondary\" onClick={() => goToList(row.type)} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.running} colorClass=\"text-status-active\" onClick={() => goToList(row.type, 'running')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.completed} colorClass=\"text-status-success\" onClick={() => goToList(row.type, 'completed')} />\n </td>\n <td className=\"py-3 text-sm text-right\">\n <StatCell value={row.failed} colorClass=\"text-status-error\" onClick={() => goToList(row.type, 'failed')} />\n </td>\n <td className=\"py-3 text-sm font-mono text-text-secondary text-right\">\n {row.avgDuration !== null ? formatDuration(row.avgDuration) : '—'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n )}\n\n {byType.length === 0 && (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-tertiary\">\n No workflow activity in the last {duration}\n </p>\n </div>\n )}\n </div>\n );\n}"],"names":["DURATIONS","formatDuration","ms","StatCell","value","colorClass","onClick","jsx","WorkflowsOverview","useWorkflowListEvents","navigate","useNavigate","duration","setDuration","useState","allJobs","useJobs","configs","useWorkflowConfigs","cutoff","useMemo","d","jobs","j","byType","map","entry","dur","result","type","stats","a","b","totals","registered","goToList","entity","status","params","qs","thCls","PageHeader","jsxs","StatCard","row"],"mappings":"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"}