@hotmeshio/long-tail 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/escalations/create.js +30 -9
- package/build/api/roles.d.ts +32 -0
- package/build/api/roles.js +73 -0
- package/build/bin/ltc.js +23 -0
- package/build/lib/cli/commands/roles.d.ts +17 -0
- package/build/lib/cli/commands/roles.js +102 -0
- package/build/lib/db/schemas/017_role_schema_versions.sql +40 -0
- package/build/lib/db/schemas/018_role_upstreams.sql +21 -0
- package/build/routes/roles.js +20 -0
- package/build/scripts/ortho-populate.d.ts +80 -8
- package/build/scripts/ortho-populate.js +204 -52
- package/build/sdk/index.d.ts +2 -0
- package/build/sdk/index.js +2 -0
- package/build/services/orchestrator/condition.d.ts +25 -1
- package/build/services/orchestrator/condition.js +29 -1
- package/build/services/role/index.d.ts +15 -1
- package/build/services/role/index.js +45 -1
- package/build/services/role/sql.d.ts +23 -2
- package/build/services/role/sql.js +93 -16
- package/build/services/role/types.d.ts +41 -0
- package/build/system/mcp-servers/admin/index.js +3 -3
- package/build/system/mcp-servers/admin/schemas.d.ts +25 -2
- package/build/system/mcp-servers/admin/schemas.js +11 -2
- package/build/system/mcp-servers/admin/users.js +42 -0
- package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -0
- package/build/system/mcp-servers/human-queue-schemas.js +4 -0
- package/build/system/mcp-servers/human-queue.js +10 -2
- package/build/system/seed/tool-manifests-admin.d.ts +371 -0
- package/build/system/seed/tool-manifests-admin.js +3 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +16 -0
- package/build/types/escalation.js +17 -0
- package/dashboard/dist/assets/{AdminDashboard-Bg1HgukI.js → AdminDashboard-rZDVS2G_.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Bg1HgukI.js.map → AdminDashboard-rZDVS2G_.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-HBe_YDU_.js → AgentConfigPage-CbyyCjCT.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-HBe_YDU_.js.map → AgentConfigPage-CbyyCjCT.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-BsaiYbwL.js → AgentDetailPage-DMeHvidT.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-BsaiYbwL.js.map → AgentDetailPage-DMeHvidT.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-DhN2lIBh.js → AgentsPage-C8fKLxh-.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-DhN2lIBh.js.map → AgentsPage-C8fKLxh-.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-_xcWvlIz.js → AvailableEscalationsPage-CUHcybKU.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-_xcWvlIz.js.map → AvailableEscalationsPage-CUHcybKU.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-DY6iUVC9.js → BotPicker-DGhniNcy.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-DY6iUVC9.js.map → BotPicker-DGhniNcy.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-w1owqsmN.js → CapabilitiesPage-ClfuW4ya.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-w1owqsmN.js.map → CapabilitiesPage-ClfuW4ya.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DIMGjlJ-.js → CollapsibleSection-DnECdKEY.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DIMGjlJ-.js.map → CollapsibleSection-DnECdKEY.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-D1OmMHux.js → CredentialsPage-DdZ-jyyc.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-D1OmMHux.js.map → CredentialsPage-DdZ-jyyc.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-CQy3DrUQ.js → CronLabel-CymxLvY0.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-CQy3DrUQ.js.map → CronLabel-CymxLvY0.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-BoBkl9tw.js → CustomDurationPicker-8JHvVWD2.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-BoBkl9tw.js.map → CustomDurationPicker-8JHvVWD2.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-QXbiuU0b.js → DropZone-DEX0BBqt.js} +2 -2
- package/dashboard/dist/assets/{DropZone-QXbiuU0b.js.map → DropZone-DEX0BBqt.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Donjm9gT.js → ElapsedCell-BRZfw_Af.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Donjm9gT.js.map → ElapsedCell-BRZfw_Af.js.map} +1 -1
- package/dashboard/dist/assets/EscalationSchemaPage-Do2iPKUl.js +9 -0
- package/dashboard/dist/assets/EscalationSchemaPage-Do2iPKUl.js.map +1 -0
- package/dashboard/dist/assets/{EscalationsOverview-CvHIJ_GG.js → EscalationsOverview-CiQO3ntf.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CvHIJ_GG.js.map → EscalationsOverview-CiQO3ntf.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DpAXMmT3.js → EventTable-CLuAbba_.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DpAXMmT3.js.map → EventTable-CLuAbba_.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-De1XVx5d.js → GraphInvokePage-BFRi6Nny.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-De1XVx5d.js.map → GraphInvokePage-BFRi6Nny.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-BYR5VXXw.js → HomePage-m1pnxilb.js} +2 -2
- package/dashboard/dist/assets/{HomePage-BYR5VXXw.js.map → HomePage-m1pnxilb.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-Bx7jGzPA.js → ListToolbar-D4Y-M7wN.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-Bx7jGzPA.js.map → ListToolbar-D4Y-M7wN.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DXRKcJN0.js → McpOverview-mfJpETsW.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DXRKcJN0.js.map → McpOverview-mfJpETsW.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-CmW15w5e.js → McpQueryDetailPage-Cb99vI7v.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-CmW15w5e.js.map → McpQueryDetailPage-Cb99vI7v.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-BE6I011z.js → McpQueryPage-CKKOxks0.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-BE6I011z.js.map → McpQueryPage-CKKOxks0.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-Dsa3G3XQ.js → McpRunDetailPage-CyTbHs0J.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-Dsa3G3XQ.js.map → McpRunDetailPage-CyTbHs0J.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-uTbym66Y.js → McpRunsPage-MIwmK-Ky.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-uTbym66Y.js.map → McpRunsPage-MIwmK-Ky.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-BGf0jHwE.js → NamespacePill-CwKdoyRM.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-BGf0jHwE.js.map → NamespacePill-CwKdoyRM.js.map} +1 -1
- package/dashboard/dist/assets/OperationsPage-DPesph0U.js +2 -0
- package/dashboard/dist/assets/OperationsPage-DPesph0U.js.map +1 -0
- package/dashboard/dist/assets/{OperatorDashboard-i8cxaDlk.js → OperatorDashboard-K1gzULr7.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-i8cxaDlk.js.map → OperatorDashboard-K1gzULr7.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-BZJsEVOC.js → PageHeader-BhaWTWcM.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-BZJsEVOC.js.map → PageHeader-BhaWTWcM.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-BWuD7s9c.js → PageHeaderWithStats-yex5WmHB.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-BWuD7s9c.js.map → PageHeaderWithStats-yex5WmHB.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CP7GZhgs.js → ProcessDetailPage-DBIrY6Vd.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CP7GZhgs.js.map → ProcessDetailPage-DBIrY6Vd.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-btsU6hBR.js → ProcessesListPage-CrLGDCAD.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-btsU6hBR.js.map → ProcessesListPage-CrLGDCAD.js.map} +1 -1
- package/dashboard/dist/assets/RoleDetailPage-7j6Mk780.js +11 -0
- package/dashboard/dist/assets/RoleDetailPage-7j6Mk780.js.map +1 -0
- package/dashboard/dist/assets/{RolePill-Pb9TKSQN.js → RolePill-Cl71eDUA.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Pb9TKSQN.js.map → RolePill-Cl71eDUA.js.map} +1 -1
- package/dashboard/dist/assets/RolesPage-B0ZgjB2V.js +2 -0
- package/dashboard/dist/assets/{RolesPage-1DBoEMsb.js.map → RolesPage-B0ZgjB2V.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-Cp6j3FEY.js → RunAsSelector-DA0h41ml.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-Cp6j3FEY.js.map → RunAsSelector-DA0h41ml.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-Pr8kawv8.js → StickyPagination-t5B71hwd.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-Pr8kawv8.js.map → StickyPagination-t5B71hwd.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-BqmQ-N3y.js → StreamMessageDetail-CYFnZsYA.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-BqmQ-N3y.js.map → StreamMessageDetail-CYFnZsYA.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-y1YmXrsj.js → SwimlaneTimeline-CY18gBek.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-y1YmXrsj.js.map → SwimlaneTimeline-CY18gBek.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-Df4myuYF.js → TagInput-B_WQiuer.js} +2 -2
- package/dashboard/dist/assets/{TagInput-Df4myuYF.js.map → TagInput-B_WQiuer.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CT5rXHK5.js → TaskDetailPage-B9owzuhV.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CT5rXHK5.js.map → TaskDetailPage-B9owzuhV.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-YalYdCNo.js → TaskQueuePill-Lgn2obNU.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-YalYdCNo.js.map → TaskQueuePill-Lgn2obNU.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-DOy6JlKS.js → TasksListPage-Dlsu7cWG.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-DOy6JlKS.js.map → TasksListPage-Dlsu7cWG.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BAQwZSpq.js → TimeAgo-CSzifQXB.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BAQwZSpq.js.map → TimeAgo-CSzifQXB.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BK_jufns.js → TimestampCell-CIxgN57O.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BK_jufns.js.map → TimestampCell-CIxgN57O.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-VGpT6Quy.js → ToolPill-uVqcbHPE.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-VGpT6Quy.js.map → ToolPill-uVqcbHPE.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-5PMQyUCe.js → ToolTestPanel-Bw844EW3.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-5PMQyUCe.js.map → ToolTestPanel-Bw844EW3.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-Cn1ShfR8.js → TopicDetailPage-HuDx2oAW.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-Cn1ShfR8.js.map → TopicDetailPage-HuDx2oAW.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-D67tjS8L.js → TopicsPage-CAG0RhAK.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-D67tjS8L.js.map → TopicsPage-CAG0RhAK.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-Dsu1Jk4N.js → UserName-CoGYeig8.js} +2 -2
- package/dashboard/dist/assets/{UserName-Dsu1Jk4N.js.map → UserName-CoGYeig8.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BwQoOmUE.js → WorkflowExecutionPage-Dhb9EWgI.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BwQoOmUE.js.map → WorkflowExecutionPage-Dhb9EWgI.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-pPUqmx6Q.js → WorkflowPill-IDjTRfQ8.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-pPUqmx6Q.js.map → WorkflowPill-IDjTRfQ8.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-D3z7COgH.js → WorkflowsDashboard-bJ6Zebfv.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-D3z7COgH.js.map → WorkflowsDashboard-bJ6Zebfv.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-C15JcxyY.js → WorkflowsOverview-B8262fVx.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-C15JcxyY.js.map → WorkflowsOverview-B8262fVx.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BYq3t7E-.js → YamlWorkflowDetailPage-DhW3q2cO.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-BYq3t7E-.js.map → YamlWorkflowDetailPage-DhW3q2cO.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-B44WgwE_.js → YamlWorkflowsPage-C8hBjSn_.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-B44WgwE_.js.map → YamlWorkflowsPage-C8hBjSn_.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BRmmK6Y9.js → agents-j2YErVp4.js} +2 -2
- package/dashboard/dist/assets/{agents-BRmmK6Y9.js.map → agents-j2YErVp4.js.map} +1 -1
- package/dashboard/dist/assets/{bots-BD75mzGG.js → bots-CD8Bl5pL.js} +2 -2
- package/dashboard/dist/assets/{bots-BD75mzGG.js.map → bots-CD8Bl5pL.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DDgC_Kds.js → capabilities-Dz190EAa.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DDgC_Kds.js.map → capabilities-Dz190EAa.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-BJh12lMv.js → controlplane-CkUHGPA3.js} +2 -2
- package/dashboard/dist/assets/{controlplane-BJh12lMv.js.map → controlplane-CkUHGPA3.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-DIJt2sgn.js → escalation-BXTwi4J1.js} +2 -2
- package/dashboard/dist/assets/{escalation-DIJt2sgn.js.map → escalation-BXTwi4J1.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-zl6E94Up.js → escalation-columns-GxxwSbDk.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-zl6E94Up.js.map → escalation-columns-GxxwSbDk.js.map} +1 -1
- package/dashboard/dist/assets/{index-DU7YumVJ.js → index-BK3PVYcd.js} +2 -2
- package/dashboard/dist/assets/{index-DU7YumVJ.js.map → index-BK3PVYcd.js.map} +1 -1
- package/dashboard/dist/assets/{index-CknKy4RA.js → index-BkwsJ-0v.js} +2 -2
- package/dashboard/dist/assets/{index-CknKy4RA.js.map → index-BkwsJ-0v.js.map} +1 -1
- package/dashboard/dist/assets/{index-B0kmiSmt.js → index-CaMVn0kW.js} +2 -2
- package/dashboard/dist/assets/{index-B0kmiSmt.js.map → index-CaMVn0kW.js.map} +1 -1
- package/dashboard/dist/assets/{index-BUbzfEA9.js → index-CkL8bpdH.js} +2 -2
- package/dashboard/dist/assets/{index-BUbzfEA9.js.map → index-CkL8bpdH.js.map} +1 -1
- package/dashboard/dist/assets/index-CoGkgm9-.js +6 -0
- package/dashboard/dist/assets/{index-DccCwyZl.js.map → index-CoGkgm9-.js.map} +1 -1
- package/dashboard/dist/assets/{index-CtDf8vvQ.js → index-D-7W2AHB.js} +9 -9
- package/dashboard/dist/assets/index-D-7W2AHB.js.map +1 -0
- package/dashboard/dist/assets/{index-CV4lEd4I.js → index-DGKgXObc.js} +2 -2
- package/dashboard/dist/assets/{index-CV4lEd4I.js.map → index-DGKgXObc.js.map} +1 -1
- package/dashboard/dist/assets/{index-DVVIeBBk.js → index-DTrcYOM2.js} +2 -2
- package/dashboard/dist/assets/{index-DVVIeBBk.js.map → index-DTrcYOM2.js.map} +1 -1
- package/dashboard/dist/assets/{index-BhznDv-4.js → index-NfVWOFbF.js} +2 -2
- package/dashboard/dist/assets/{index-BhznDv-4.js.map → index-NfVWOFbF.js.map} +1 -1
- package/dashboard/dist/assets/index-Wny0bRgq.css +1 -0
- package/dashboard/dist/assets/{index-DrUkTcn-.js → index-YliQ4kW_.js} +2 -2
- package/dashboard/dist/assets/{index-DrUkTcn-.js.map → index-YliQ4kW_.js.map} +1 -1
- package/dashboard/dist/assets/{index-CpgV4Kkp.js → index-eLRh-2NW.js} +2 -2
- package/dashboard/dist/assets/{index-CpgV4Kkp.js.map → index-eLRh-2NW.js.map} +1 -1
- package/dashboard/dist/assets/{index-CDPBXB4e.js → index-n-lZY5S6.js} +2 -2
- package/dashboard/dist/assets/{index-CDPBXB4e.js.map → index-n-lZY5S6.js.map} +1 -1
- package/dashboard/dist/assets/{index-j-C7g_Ej.js → index-qT7eB_Hk.js} +2 -2
- package/dashboard/dist/assets/{index-j-C7g_Ej.js.map → index-qT7eB_Hk.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-pNDWACXB.js → knowledge-CSAbLtk7.js} +2 -2
- package/dashboard/dist/assets/{knowledge-pNDWACXB.js.map → knowledge-CSAbLtk7.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-xddLBwUW.js → mcp-D0Ha3aEo.js} +2 -2
- package/dashboard/dist/assets/{mcp-xddLBwUW.js.map → mcp-D0Ha3aEo.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CmNjvxTG.js → mcp-query-BySmvmuS.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CmNjvxTG.js.map → mcp-query-BySmvmuS.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-B05sd2nB.js → pipelines-DiqWgxJd.js} +2 -2
- package/dashboard/dist/assets/{pipelines-B05sd2nB.js.map → pipelines-DiqWgxJd.js.map} +1 -1
- package/dashboard/dist/assets/roles-BdtnzLsL.js +2 -0
- package/dashboard/dist/assets/roles-BdtnzLsL.js.map +1 -0
- package/dashboard/dist/assets/{tasks-Bm1OKrJA.js → tasks-DYCUi5nZ.js} +2 -2
- package/dashboard/dist/assets/{tasks-Bm1OKrJA.js.map → tasks-DYCUi5nZ.js.map} +1 -1
- package/dashboard/dist/assets/{topics-BVIqtmd4.js → topics-CA7i8ymr.js} +2 -2
- package/dashboard/dist/assets/{topics-BVIqtmd4.js.map → topics-CA7i8ymr.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-_qCzU74s.js → useEventHooks-SfWdyc5L.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-_qCzU74s.js.map → useEventHooks-SfWdyc5L.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-CDnCSFpG.js → useNamespace-CZUsk5Vv.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-CDnCSFpG.js.map → useNamespace-CZUsk5Vv.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-zrHMhaFM.js → useYamlActivityEvents-DKQ5dREx.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-zrHMhaFM.js.map → useYamlActivityEvents-DKQ5dREx.js.map} +1 -1
- package/dashboard/dist/assets/{users-BPBMZg27.js → users-BxKf5dAX.js} +2 -2
- package/dashboard/dist/assets/{users-BPBMZg27.js.map → users-BxKf5dAX.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-C1zVP_dv.js → vendor-icons-CEWCGPeJ.js} +76 -76
- package/dashboard/dist/assets/vendor-icons-CEWCGPeJ.js.map +1 -0
- package/dashboard/dist/assets/{workflows-CT6nTL1I.js → workflows-DNPQ-j-7.js} +2 -2
- package/dashboard/dist/assets/{workflows-CT6nTL1I.js.map → workflows-DNPQ-j-7.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-CdfjkOKU.js → yaml-workflows-CA8BrFxc.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-CdfjkOKU.js.map → yaml-workflows-CA8BrFxc.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/roles.md +62 -0
- package/docs/api/mcp/admin.md +32 -1
- package/docs/api/mcp/human-queue.md +2 -0
- package/docs/api/sdk/roles.md +39 -0
- package/docs/cli.md +13 -0
- package/docs/dashboard.md +13 -6
- package/docs/data.md +34 -0
- package/docs/hitl-guide.md +25 -3
- package/package.json +1 -1
- package/dashboard/dist/assets/OperationsPage-CAmiFHI6.js +0 -2
- package/dashboard/dist/assets/OperationsPage-CAmiFHI6.js.map +0 -1
- package/dashboard/dist/assets/RoleDetailPage-BB_e330f.js +0 -16
- package/dashboard/dist/assets/RoleDetailPage-BB_e330f.js.map +0 -1
- package/dashboard/dist/assets/RolesPage-1DBoEMsb.js +0 -2
- package/dashboard/dist/assets/index-BRtKQtQZ.css +0 -1
- package/dashboard/dist/assets/index-CtDf8vvQ.js.map +0 -1
- package/dashboard/dist/assets/index-DccCwyZl.js +0 -6
- package/dashboard/dist/assets/roles-bRgaMcdy.js +0 -2
- package/dashboard/dist/assets/roles-bRgaMcdy.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-C1zVP_dv.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as n,j as t}from"./vendor-query-B2UbickB.js";import{g as h}from"./workflows-
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{a as n,j as t}from"./vendor-query-B2UbickB.js";import{g as h}from"./workflows-DNPQ-j-7.js";import{D as g}from"./DataTable-ZWgVQg7F.js";import{F as y,b as j}from"./FilterBar-BQ2JGg8U.js";import{R as q,a as u}from"./RowActions-BA9L9djf.js";import{u as C}from"./useFilterParams-x-Dg0Vgz.js";import{P as R}from"./PageHeader-BhaWTWcM.js";import{T as b}from"./TaskQueuePill-Lgn2obNU.js";import{W as _}from"./WorkflowPill-IDjTRfQ8.js";import{ad as v,ah as N,l as I}from"./vendor-icons-CEWCGPeJ.js";import{c as P}from"./vendor-react-CXumBFUA.js";import"./index-D-7W2AHB.js";import"./EmptyState-BcsfPq9T.js";function H(){const r=P(),{data:c,isLoading:m}=h(),{filters:s,setFilter:i}=C({filters:{search:"",queue:""}}),[a,p]=n.useState(s.search);n.useEffect(()=>{if(a===s.search)return;const e=setTimeout(()=>i("search",a),300);return()=>clearTimeout(e)},[a,i,s.search]);const o=c??[],d=n.useMemo(()=>[...new Set(o.map(e=>e.task_queue).filter(Boolean))].sort(),[o]),f=n.useMemo(()=>{let e=o;if(s.search){const l=s.search.toLowerCase();e=e.filter(w=>w.name.toLowerCase().includes(l))}return s.queue&&(e=e.filter(l=>l.task_queue===s.queue)),e},[o,s]),k=[{key:"name",label:"Workflow",render:e=>t.jsx(_,{type:e.name})},{key:"task_queue",label:"Queue",render:e=>t.jsx(b,{queue:e.task_queue}),className:"whitespace-nowrap"},{key:"registered",label:"Status",render:e=>e.registered?t.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-accent/10 text-accent",children:[t.jsx(v,{className:"w-3 h-3"}),"Certified"]}):t.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-surface-sunken text-text-tertiary",children:"Durable"}),className:"whitespace-nowrap"},{key:"actions",label:"",render:e=>t.jsx(q,{children:e.registered?t.jsx(u,{icon:N,title:"View config",onClick:()=>r(`/workflows/registry/${encodeURIComponent(e.name)}`)}):t.jsx(u,{icon:I,title:"Register workflow",onClick:()=>r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)})}),className:"w-16 text-right"}],x=e=>{e.registered?r(`/workflows/registry/${encodeURIComponent(e.name)}`):r(`/workflows/registry/new?workflow_type=${encodeURIComponent(e.name)}&task_queue=${encodeURIComponent(e.task_queue)}`)};return t.jsxs("div",{children:[t.jsx(R,{title:"Workers",docsHash:"#docs:dashboard.md:task-queues"}),t.jsxs(y,{children:[t.jsx("input",{type:"text",placeholder:"Search workers...",value:a,onChange:e=>p(e.target.value),className:"input text-[11px] py-1 px-2 w-56"}),t.jsx(j,{label:"Queue",value:s.queue,onChange:e=>i("queue",e),options:d.map(e=>({value:e,label:e}))})]}),t.jsx(g,{columns:k,data:f,keyFn:e=>e.name,onRowClick:x,isLoading:m,emptyMessage:"No active workers"})]})}export{H as WorkersPage};
|
|
2
|
+
//# sourceMappingURL=index-BkwsJ-0v.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-BkwsJ-0v.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Plus, Eye, ShieldCheck } from 'lucide-react';\nimport { useActiveWorkers } from '../../../api/workflows';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { ActiveWorker } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkersPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useActiveWorkers();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '' },\n });\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 allWorkers = data ?? [];\n\n const queues = useMemo(\n () => [...new Set(allWorkers.map((w) => w.task_queue).filter(Boolean))].sort(),\n [allWorkers],\n );\n\n const workers = useMemo(() => {\n let result = allWorkers;\n if (filters.search) {\n const q = filters.search.toLowerCase();\n result = result.filter((w) => w.name.toLowerCase().includes(q));\n }\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n return result;\n }, [allWorkers, filters]);\n\n const columns: Column<ActiveWorker>[] = [\n {\n key: 'name',\n label: 'Workflow',\n render: (row) => <WorkflowPill type={row.name} />,\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => <TaskQueuePill queue={row.task_queue} />,\n className: 'whitespace-nowrap',\n },\n {\n key: 'registered',\n label: 'Status',\n render: (row) => row.registered\n ? <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] font-medium bg-accent/10 text-accent\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>\n : <span className=\"inline-flex items-center px-1.5 py-0.5 rounded text-[10px] font-medium bg-surface-sunken text-text-tertiary\">Durable</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.registered ? (\n <RowAction\n icon={Eye}\n title=\"View config\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.name)}`)}\n />\n ) : (\n <RowAction\n icon={Plus}\n title=\"Register workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`)}\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleRowClick = (row: ActiveWorker) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.name)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.name)}&task_queue=${encodeURIComponent(row.task_queue)}`);\n }\n };\n\n return (\n <div>\n <PageHeader title=\"Workers\" docsHash=\"#docs:dashboard.md:task-queues\" />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workers...\"\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=\"Queue\"\n value={filters.queue}\n onChange={(v) => setFilter('queue', v)}\n options={queues.map((q) => ({ value: q, label: q }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workers}\n keyFn={(row) => row.name}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No active workers\"\n />\n </div>\n );\n}\n"],"names":["WorkersPage","navigate","useNavigate","data","isLoading","useActiveWorkers","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","useEffect","timer","allWorkers","queues","useMemo","w","workers","result","q","columns","row","WorkflowPill","TaskQueuePill","jsxs","jsx","ShieldCheck","RowActionGroup","RowAction","Eye","Plus","handleRowClick","PageHeader","FilterBar","FilterSelect","v","DataTable"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as p,j as a}from"./vendor-query-B2UbickB.js";import{a as N}from"./vendor-react-CXumBFUA.js";import{u as P,a as T,b as F,S as C,c as M,d as O,e as $}from"./StreamMessageDetail-
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{a as p,j as a}from"./vendor-query-B2UbickB.js";import{a as N}from"./vendor-react-CXumBFUA.js";import{u as P,a as T,b as F,S as C,c as M,d as O,e as $}from"./StreamMessageDetail-CYFnZsYA.js";import{u as z}from"./useFilterParams-x-Dg0Vgz.js";import{u as A}from"./useNamespace-CZUsk5Vv.js";import{b as D}from"./api-path-u2Jf9QXS.js";import{D as R}from"./DataTable-ZWgVQg7F.js";import{S as E}from"./StickyPagination-t5B71hwd.js";import{F as L,b as u,a as b}from"./FilterBar-BQ2JGg8U.js";import{T as x}from"./TimestampCell-CIxgN57O.js";import{P as U}from"./PageHeader-BhaWTWcM.js";import{L as I}from"./ListToolbar-D4Y-M7wN.js";import{X as f}from"./vendor-icons-CEWCGPeJ.js";import"./index-D-7W2AHB.js";import"./controlplane-CkUHGPA3.js";import"./EmptyState-BcsfPq9T.js";function B(o,i){if(o.length<=i)return o;const s=Math.floor((i-1)/2);return`${o.slice(0,s)}…${o.slice(-s)}`}function oe(){const{namespace:o,available:i}=A("namespace"),{filters:s,setFilter:t,pagination:r,sort:n,setSort:_}=z({filters:{namespace:"",source:"worker",status:"",stream_name:"",msg_type:"",topic:"",workflow_name:"",jid:"",aid:""}}),[m,y]=p.useState(null),h=p.useMemo(()=>i.map(e=>({value:e,label:e})),[i]),{data:l,isLoading:j,refetch:v,isFetching:k}=P({namespace:s.namespace||o,source:s.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:n.sort_by||"created_at",order:n.order||"desc",status:s.status||void 0,stream_name:s.stream_name||void 0,msg_type:s.msg_type||void 0,topic:s.topic||void 0,workflow_name:s.workflow_name||void 0,jid:s.jid||void 0,aid:s.aid||void 0}),d=(l==null?void 0:l.messages)??[],g=(l==null?void 0:l.total)??0,c=p.useMemo(()=>m?d.find(e=>e.id===m.id&&e.source===m.source)??m:null,[d,m]),S=!!c,w=[{key:"status",label:"Status",render:e=>a.jsxs("div",{className:"flex items-center gap-2",children:[a.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${M[e.status]}`}),a.jsx("span",{className:"text-xs",children:O[e.status]})]}),className:"w-28"},{key:"source",label:"Source",render:e=>a.jsx("span",{className:$,children:e.source}),className:"w-20"},{key:"stream_name",label:"Stream",sortable:!0,render:e=>a.jsx("span",{className:"font-mono text-xs text-text-secondary truncate block max-w-[240px]",title:e.stream_name,children:e.stream_name})},{key:"msg_type",label:"Type",render:e=>a.jsx("span",{className:"text-xs text-text-secondary",children:e.msg_type||"—"}),className:"w-24"},{key:"created_at",label:"Created",sortable:!0,render:e=>a.jsx(x,{date:e.created_at}),className:"w-44"},{key:"reserved_at",label:"Reserved",render:e=>e.reserved_at?a.jsx(x,{date:e.reserved_at}):a.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-44"},{key:"expired_at",label:"Processed",render:e=>e.expired_at?a.jsx(x,{date:e.expired_at}):a.jsx("span",{className:"text-xs text-text-tertiary",children:"—"}),className:"w-44"},{key:"priority",label:"Pri",sortable:!0,render:e=>a.jsx("span",{className:"text-xs text-text-secondary",children:e.priority}),className:"w-12 text-right"},{key:"retry_attempt",label:"Retries",render:e=>a.jsxs("span",{className:"text-xs text-text-secondary",children:[e.retry_attempt,"/",e.max_retry_attempts]}),className:"w-16"}];return a.jsxs("div",{children:[a.jsx(U,{title:"Messages",docsHash:"#docs:dashboard.md:messages"}),a.jsxs(L,{actions:a.jsx(I,{onRefresh:()=>v(),isFetching:k,apiPath:D("/controlplane/stream-messages",{namespace:s.namespace||o,source:s.source||"worker",limit:r.pageSize,offset:r.offset,sort_by:n.sort_by||"created_at",order:n.order||"desc",status:s.status||void 0,stream_name:s.stream_name||void 0,msg_type:s.msg_type||void 0,topic:s.topic||void 0,workflow_name:s.workflow_name||void 0,jid:s.jid||void 0,aid:s.aid||void 0})}),children:[a.jsx(u,{label:"Namespace",value:s.namespace,onChange:e=>t("namespace",e),options:h,required:!0}),a.jsx(u,{label:"Source",value:s.source,onChange:e=>t("source",e),options:T,required:!0}),a.jsx(u,{label:"Status",value:s.status,onChange:e=>t("status",e),options:F}),a.jsx(b,{label:"Stream",value:s.stream_name,onChange:e=>t("stream_name",e),placeholder:"Filter by stream name…"}),a.jsx(b,{label:"Job ID",value:s.jid,onChange:e=>t("jid",e),placeholder:"Filter by jid…"}),[{key:"topic",label:"Topic",value:s.topic},{key:"workflow_name",label:"Workflow",value:s.workflow_name},{key:"aid",label:"Activity",value:s.aid},{key:"msg_type",label:"Type",value:s.msg_type}].filter(e=>e.value).map(e=>a.jsxs("button",{onClick:()=>t(e.key,""),className:"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors",title:`Clear ${e.label} filter: ${e.value}`,children:[e.label,": ",B(e.value,12),a.jsx(f,{className:"w-2.5 h-2.5"})]},e.key))]}),a.jsx(R,{columns:w,data:d,keyFn:e=>`${e.source}:${e.id}`,isLoading:j,emptyMessage:"No stream messages found",onRowClick:e=>y(e),activeRowKey:c?`${c.source}:${c.id}`:null,sort:n,onSort:_}),a.jsx(E,{page:r.page,totalPages:r.totalPages(g),onPageChange:r.setPage,total:g,pageSize:r.pageSize,onPageSizeChange:r.setPageSize}),S&&N.createPortal(a.jsxs("div",{className:"fixed right-0 bottom-0 w-[400px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg",style:{top:"3.5rem"},children:[a.jsxs("div",{className:"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50",children:[a.jsx("span",{className:"text-xs font-medium text-text-primary",children:"Message Detail"}),a.jsx("button",{onClick:()=>y(null),className:"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors",title:"Close",children:a.jsx(f,{className:"w-4 h-4"})})]}),a.jsx("div",{className:"px-4 py-4",children:a.jsx(C,{message:c,filters:{onFilterStatus:e=>t("status",e),onFilterStreamName:e=>t("stream_name",e),onFilterMsgType:e=>t("msg_type",e),onFilterTopic:e=>t("topic",e),onFilterWorkflow:e=>t("workflow_name",e),onFilterJid:e=>t("jid",e),onFilterAid:e=>t("aid",e)}})})]}),document.body)]})}export{oe as StreamMessagesPage};
|
|
2
|
+
//# sourceMappingURL=index-CaMVn0kW.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-B0kmiSmt.js","sources":["../../src/pages/admin/streams/StreamMessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { useStreamMessages, type StreamMessage } from '../../../api/stream-messages';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useNamespace } from '../../../hooks/useNamespace';\nimport { buildApiPath } from '../../../lib/api-path';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { StickyPagination } from '../../../components/common/data/StickyPagination';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { TimestampCell } from '../../../components/common/display/TimestampCell';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { ListToolbar } from '../../../components/common/data/ListToolbar';\nimport { StreamMessageDetail } from './StreamMessageDetail';\nimport { STATUS_DOT, STATUS_LABEL, STATUS_OPTIONS, SOURCE_OPTIONS, SOURCE_BADGE } from './constants';\n\nfunction truncateMiddle(str: string, max: number): string {\n if (str.length <= max) return str;\n const half = Math.floor((max - 1) / 2);\n return `${str.slice(0, half)}…${str.slice(-half)}`;\n}\n\nexport function StreamMessagesPage() {\n const { namespace, available } = useNamespace('namespace');\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { namespace: '', source: 'worker', status: '', stream_name: '', msg_type: '', topic: '', workflow_name: '', jid: '', aid: '' },\n });\n\n const [selected, setSelected] = useState<StreamMessage | null>(null);\n\n const namespaceOptions = useMemo(\n () => available.map((id) => ({ value: id, label: id })),\n [available],\n );\n\n const { data, isLoading, refetch, isFetching } = useStreamMessages({\n namespace: filters.namespace || namespace,\n source: (filters.source as 'engine' | 'worker') || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: (filters.status as any) || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n });\n\n const messages = data?.messages ?? [];\n const total = data?.total ?? 0;\n\n const activeMessage = useMemo(() => {\n if (!selected) return null;\n return messages.find((m) => m.id === selected.id && m.source === selected.source) ?? selected;\n }, [messages, selected]);\n\n const panelOpen = !!activeMessage;\n\n const columns: Column<StreamMessage>[] = [\n {\n key: 'status',\n label: 'Status',\n render: (row) => (\n <div className=\"flex items-center gap-2\">\n <span className={`w-2 h-2 rounded-full shrink-0 ${STATUS_DOT[row.status]}`} />\n <span className=\"text-xs\">{STATUS_LABEL[row.status]}</span>\n </div>\n ),\n className: 'w-28',\n },\n {\n key: 'source',\n label: 'Source',\n render: (row) => <span className={SOURCE_BADGE}>{row.source}</span>,\n className: 'w-20',\n },\n {\n key: 'stream_name',\n label: 'Stream',\n sortable: true,\n render: (row) => (\n <span className=\"font-mono text-xs text-text-secondary truncate block max-w-[240px]\" title={row.stream_name}>\n {row.stream_name}\n </span>\n ),\n },\n {\n key: 'msg_type',\n label: 'Type',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">{row.msg_type || '—'}</span>\n ),\n className: 'w-24',\n },\n {\n key: 'created_at',\n label: 'Created',\n sortable: true,\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-44',\n },\n {\n key: 'reserved_at',\n label: 'Reserved',\n render: (row) => row.reserved_at ? <TimestampCell date={row.reserved_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'expired_at',\n label: 'Processed',\n render: (row) => row.expired_at ? <TimestampCell date={row.expired_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'priority',\n label: 'Pri',\n sortable: true,\n render: (row) => <span className=\"text-xs text-text-secondary\">{row.priority}</span>,\n className: 'w-12 text-right',\n },\n {\n key: 'retry_attempt',\n label: 'Retries',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">\n {row.retry_attempt}/{row.max_retry_attempts}\n </span>\n ),\n className: 'w-16',\n },\n ];\n\n return (\n <div>\n <PageHeader title=\"Messages\" docsHash=\"#docs:dashboard.md:messages\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/controlplane/stream-messages', {\n namespace: filters.namespace || namespace,\n source: filters.source || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: filters.status || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n })}\n />\n }>\n <FilterSelect\n label=\"Namespace\"\n value={filters.namespace}\n onChange={(v) => setFilter('namespace', v)}\n options={namespaceOptions}\n required\n />\n <FilterSelect\n label=\"Source\"\n value={filters.source}\n onChange={(v) => setFilter('source', v)}\n options={SOURCE_OPTIONS}\n required\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterInput\n label=\"Stream\"\n value={filters.stream_name}\n onChange={(v) => setFilter('stream_name', v)}\n placeholder=\"Filter by stream name…\"\n />\n <FilterInput\n label=\"Job ID\"\n value={filters.jid}\n onChange={(v) => setFilter('jid', v)}\n placeholder=\"Filter by jid…\"\n />\n {/* Active dimension filter pills — inline in the sticky bar */}\n {[\n { key: 'topic', label: 'Topic', value: filters.topic },\n { key: 'workflow_name', label: 'Workflow', value: filters.workflow_name },\n { key: 'aid', label: 'Activity', value: filters.aid },\n { key: 'msg_type', label: 'Type', value: filters.msg_type },\n ].filter((f) => f.value).map((f) => (\n <button\n key={f.key}\n onClick={() => setFilter(f.key as any, '')}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors\"\n title={`Clear ${f.label} filter: ${f.value}`}\n >\n {f.label}: {truncateMiddle(f.value, 12)}\n <X className=\"w-2.5 h-2.5\" />\n </button>\n ))}\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={messages}\n keyFn={(row) => `${row.source}:${row.id}`}\n isLoading={isLoading}\n emptyMessage=\"No stream messages found\"\n onRowClick={(row) => setSelected(row)}\n activeRowKey={activeMessage ? `${activeMessage.source}:${activeMessage.id}` : null}\n sort={sort}\n onSort={setSort}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n\n {/* Detail panel — portaled to body so fixed positioning works */}\n {panelOpen && createPortal(\n <div className=\"fixed right-0 bottom-0 w-[400px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg\" style={{ top: '3.5rem' }}>\n <div className=\"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50\">\n <span className=\"text-xs font-medium text-text-primary\">Message Detail</span>\n <button\n onClick={() => setSelected(null)}\n className=\"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n <div className=\"px-4 py-4\">\n <StreamMessageDetail\n message={activeMessage}\n filters={{\n onFilterStatus: (v) => setFilter('status', v),\n onFilterStreamName: (v) => setFilter('stream_name', v),\n onFilterMsgType: (v) => setFilter('msg_type', v),\n onFilterTopic: (v) => setFilter('topic', v),\n onFilterWorkflow: (v) => setFilter('workflow_name', v),\n onFilterJid: (v) => setFilter('jid', v),\n onFilterAid: (v) => setFilter('aid', v),\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":["truncateMiddle","str","max","half","StreamMessagesPage","namespace","available","useNamespace","filters","setFilter","pagination","sort","setSort","useFilterParams","selected","setSelected","useState","namespaceOptions","useMemo","id","data","isLoading","refetch","isFetching","useStreamMessages","messages","total","activeMessage","m","panelOpen","columns","row","jsxs","jsx","STATUS_DOT","STATUS_LABEL","SOURCE_BADGE","TimestampCell","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","SOURCE_OPTIONS","STATUS_OPTIONS","FilterInput","f","X","DataTable","StickyPagination","createPortal","StreamMessageDetail"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CaMVn0kW.js","sources":["../../src/pages/admin/streams/StreamMessagesPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\nimport { X } from 'lucide-react';\nimport { useStreamMessages, type StreamMessage } from '../../../api/stream-messages';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useNamespace } from '../../../hooks/useNamespace';\nimport { buildApiPath } from '../../../lib/api-path';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { StickyPagination } from '../../../components/common/data/StickyPagination';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { TimestampCell } from '../../../components/common/display/TimestampCell';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { ListToolbar } from '../../../components/common/data/ListToolbar';\nimport { StreamMessageDetail } from './StreamMessageDetail';\nimport { STATUS_DOT, STATUS_LABEL, STATUS_OPTIONS, SOURCE_OPTIONS, SOURCE_BADGE } from './constants';\n\nfunction truncateMiddle(str: string, max: number): string {\n if (str.length <= max) return str;\n const half = Math.floor((max - 1) / 2);\n return `${str.slice(0, half)}…${str.slice(-half)}`;\n}\n\nexport function StreamMessagesPage() {\n const { namespace, available } = useNamespace('namespace');\n\n const { filters, setFilter, pagination, sort, setSort } = useFilterParams({\n filters: { namespace: '', source: 'worker', status: '', stream_name: '', msg_type: '', topic: '', workflow_name: '', jid: '', aid: '' },\n });\n\n const [selected, setSelected] = useState<StreamMessage | null>(null);\n\n const namespaceOptions = useMemo(\n () => available.map((id) => ({ value: id, label: id })),\n [available],\n );\n\n const { data, isLoading, refetch, isFetching } = useStreamMessages({\n namespace: filters.namespace || namespace,\n source: (filters.source as 'engine' | 'worker') || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: (filters.status as any) || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n });\n\n const messages = data?.messages ?? [];\n const total = data?.total ?? 0;\n\n const activeMessage = useMemo(() => {\n if (!selected) return null;\n return messages.find((m) => m.id === selected.id && m.source === selected.source) ?? selected;\n }, [messages, selected]);\n\n const panelOpen = !!activeMessage;\n\n const columns: Column<StreamMessage>[] = [\n {\n key: 'status',\n label: 'Status',\n render: (row) => (\n <div className=\"flex items-center gap-2\">\n <span className={`w-2 h-2 rounded-full shrink-0 ${STATUS_DOT[row.status]}`} />\n <span className=\"text-xs\">{STATUS_LABEL[row.status]}</span>\n </div>\n ),\n className: 'w-28',\n },\n {\n key: 'source',\n label: 'Source',\n render: (row) => <span className={SOURCE_BADGE}>{row.source}</span>,\n className: 'w-20',\n },\n {\n key: 'stream_name',\n label: 'Stream',\n sortable: true,\n render: (row) => (\n <span className=\"font-mono text-xs text-text-secondary truncate block max-w-[240px]\" title={row.stream_name}>\n {row.stream_name}\n </span>\n ),\n },\n {\n key: 'msg_type',\n label: 'Type',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">{row.msg_type || '—'}</span>\n ),\n className: 'w-24',\n },\n {\n key: 'created_at',\n label: 'Created',\n sortable: true,\n render: (row) => <TimestampCell date={row.created_at} />,\n className: 'w-44',\n },\n {\n key: 'reserved_at',\n label: 'Reserved',\n render: (row) => row.reserved_at ? <TimestampCell date={row.reserved_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'expired_at',\n label: 'Processed',\n render: (row) => row.expired_at ? <TimestampCell date={row.expired_at} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'w-44',\n },\n {\n key: 'priority',\n label: 'Pri',\n sortable: true,\n render: (row) => <span className=\"text-xs text-text-secondary\">{row.priority}</span>,\n className: 'w-12 text-right',\n },\n {\n key: 'retry_attempt',\n label: 'Retries',\n render: (row) => (\n <span className=\"text-xs text-text-secondary\">\n {row.retry_attempt}/{row.max_retry_attempts}\n </span>\n ),\n className: 'w-16',\n },\n ];\n\n return (\n <div>\n <PageHeader title=\"Messages\" docsHash=\"#docs:dashboard.md:messages\" />\n\n <FilterBar actions={\n <ListToolbar\n onRefresh={() => refetch()}\n isFetching={isFetching}\n apiPath={buildApiPath('/controlplane/stream-messages', {\n namespace: filters.namespace || namespace,\n source: filters.source || 'worker',\n limit: pagination.pageSize,\n offset: pagination.offset,\n sort_by: sort.sort_by || 'created_at',\n order: sort.order || 'desc',\n status: filters.status || undefined,\n stream_name: filters.stream_name || undefined,\n msg_type: filters.msg_type || undefined,\n topic: filters.topic || undefined,\n workflow_name: filters.workflow_name || undefined,\n jid: filters.jid || undefined,\n aid: filters.aid || undefined,\n })}\n />\n }>\n <FilterSelect\n label=\"Namespace\"\n value={filters.namespace}\n onChange={(v) => setFilter('namespace', v)}\n options={namespaceOptions}\n required\n />\n <FilterSelect\n label=\"Source\"\n value={filters.source}\n onChange={(v) => setFilter('source', v)}\n options={SOURCE_OPTIONS}\n required\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={STATUS_OPTIONS}\n />\n <FilterInput\n label=\"Stream\"\n value={filters.stream_name}\n onChange={(v) => setFilter('stream_name', v)}\n placeholder=\"Filter by stream name…\"\n />\n <FilterInput\n label=\"Job ID\"\n value={filters.jid}\n onChange={(v) => setFilter('jid', v)}\n placeholder=\"Filter by jid…\"\n />\n {/* Active dimension filter pills — inline in the sticky bar */}\n {[\n { key: 'topic', label: 'Topic', value: filters.topic },\n { key: 'workflow_name', label: 'Workflow', value: filters.workflow_name },\n { key: 'aid', label: 'Activity', value: filters.aid },\n { key: 'msg_type', label: 'Type', value: filters.msg_type },\n ].filter((f) => f.value).map((f) => (\n <button\n key={f.key}\n onClick={() => setFilter(f.key as any, '')}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 text-[10px] font-mono rounded-full bg-accent/15 text-accent hover:bg-accent/25 transition-colors\"\n title={`Clear ${f.label} filter: ${f.value}`}\n >\n {f.label}: {truncateMiddle(f.value, 12)}\n <X className=\"w-2.5 h-2.5\" />\n </button>\n ))}\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={messages}\n keyFn={(row) => `${row.source}:${row.id}`}\n isLoading={isLoading}\n emptyMessage=\"No stream messages found\"\n onRowClick={(row) => setSelected(row)}\n activeRowKey={activeMessage ? `${activeMessage.source}:${activeMessage.id}` : null}\n sort={sort}\n onSort={setSort}\n />\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n\n {/* Detail panel — portaled to body so fixed positioning works */}\n {panelOpen && createPortal(\n <div className=\"fixed right-0 bottom-0 w-[400px] z-40 border-l border-surface-border bg-surface overflow-y-auto shadow-lg\" style={{ top: '3.5rem' }}>\n <div className=\"sticky top-0 z-10 flex items-center justify-between px-4 py-3 bg-surface border-b border-surface-border/50\">\n <span className=\"text-xs font-medium text-text-primary\">Message Detail</span>\n <button\n onClick={() => setSelected(null)}\n className=\"p-1 rounded hover:bg-surface-hover text-text-tertiary hover:text-text-primary transition-colors\"\n title=\"Close\"\n >\n <X className=\"w-4 h-4\" />\n </button>\n </div>\n <div className=\"px-4 py-4\">\n <StreamMessageDetail\n message={activeMessage}\n filters={{\n onFilterStatus: (v) => setFilter('status', v),\n onFilterStreamName: (v) => setFilter('stream_name', v),\n onFilterMsgType: (v) => setFilter('msg_type', v),\n onFilterTopic: (v) => setFilter('topic', v),\n onFilterWorkflow: (v) => setFilter('workflow_name', v),\n onFilterJid: (v) => setFilter('jid', v),\n onFilterAid: (v) => setFilter('aid', v),\n }}\n />\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n}\n"],"names":["truncateMiddle","str","max","half","StreamMessagesPage","namespace","available","useNamespace","filters","setFilter","pagination","sort","setSort","useFilterParams","selected","setSelected","useState","namespaceOptions","useMemo","id","data","isLoading","refetch","isFetching","useStreamMessages","messages","total","activeMessage","m","panelOpen","columns","row","jsxs","jsx","STATUS_DOT","STATUS_LABEL","SOURCE_BADGE","TimestampCell","PageHeader","FilterBar","ListToolbar","buildApiPath","FilterSelect","v","SOURCE_OPTIONS","STATUS_OPTIONS","FilterInput","f","X","DataTable","StickyPagination","createPortal","StreamMessageDetail"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{a as c,j as e}from"./vendor-query-B2UbickB.js";import{c as D,u as B,d as $,e as z}from"./workflows-
|
|
1
|
+
import{a as c,j as e}from"./vendor-query-B2UbickB.js";import{c as D,u as B,d as $,e as z}from"./workflows-DNPQ-j-7.js";import{P as H}from"./PageHeader-BhaWTWcM.js";import{W as V}from"./WorkflowPill-IDjTRfQ8.js";import{N as K}from"./NamespacePill-CwKdoyRM.js";import{ab as U,b as L,a6 as G,ac as Q,ad as X,P as Y}from"./vendor-icons-CEWCGPeJ.js";import{j as R}from"./index-D-7W2AHB.js";import{B as Z}from"./BotPicker-DGhniNcy.js";import{L as ee,c as te,f as se}from"./vendor-react-CXumBFUA.js";import"./bots-CD8Bl5pL.js";function ae({configs:t,selectedType:r,onSelect:m,tierMap:h,activeTypes:n}){const[x,p]=c.useState(""),i=c.useMemo(()=>{if(!x.trim())return t;const s=x.toLowerCase();return t.filter(j=>{var a;return j.workflow_type.toLowerCase().includes(s)||((a=j.description)==null?void 0:a.toLowerCase().includes(s))})},[t,x]);return e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-0 z-20 bg-surface pt-4",children:[e.jsx("div",{className:"bg-[#F7F7F7] rounded-lg px-4 py-2 mb-3",children:e.jsxs("div",{className:"relative w-1/2",children:[e.jsx(U,{className:"absolute left-0 top-1/2 -translate-y-1/2 w-3 h-3 text-text-quaternary"}),e.jsx("input",{type:"text",value:x,onChange:s=>p(s.target.value),placeholder:`Search ${t.length} workflows…`,className:"w-full pl-5 py-1 text-sm bg-transparent border-b border-surface-border/60 text-text-primary placeholder:text-text-quaternary focus:outline-none focus:border-accent/50 transition-colors"})]})}),e.jsxs("div",{className:"flex items-center gap-2 py-2 border-b border-surface-border",children:[e.jsx("h2",{className:"section-h2",children:"Workflows"}),e.jsx("span",{className:"text-xs text-text-quaternary",children:i.length})]})]}),i.length===0?e.jsx("p",{className:"text-sm text-text-tertiary py-8 text-center",children:"No workflows match your search."}):e.jsx("div",{className:"divide-y divide-surface-border/30",children:i.map(s=>{const j=r===s.workflow_type,a=h.get(s.workflow_type)??"durable",l=a==="certified"?"certified":a==="configured"?"configured":"durable";return e.jsxs("button",{onClick:()=>m(s),className:"group relative w-full text-left py-3 px-3 -mx-3 rounded-md transition-colors duration-150",children:[j&&e.jsx("span",{className:"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full"}),e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(V,{type:s.workflow_type,size:"md",variant:l}),e.jsxs("span",{className:"ml-auto flex items-center gap-2 shrink-0",children:[s.execute_as&&e.jsxs("span",{className:"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[9px] bg-accent/10 text-accent rounded",children:[e.jsx(L,{className:"w-2.5 h-2.5"}),s.execute_as]}),(n==null?void 0:n.has(s.workflow_type))&&e.jsx("span",{title:"Cron schedule active",children:e.jsx(G,{className:"w-3 h-3 text-status-success/70 shrink-0"})}),e.jsx(K,{namespace:"durable"})]})]}),s.description&&e.jsx("p",{className:"text-[10px] text-text-tertiary group-hover:text-text-secondary leading-relaxed line-clamp-2 pl-0.5 transition-colors",children:s.description})]},s.workflow_type)})})]})}const I=`{
|
|
2
2
|
"data": {},
|
|
3
3
|
"metadata": {}
|
|
4
4
|
}`;function re(t){return typeof t=="boolean"?"boolean":typeof t=="number"?"number":Array.isArray(t)?"array":t!==null&&typeof t=="object"?"object":"string"}function T(t){if(!t)return[];const r=t.data;return!r||typeof r!="object"?[]:Object.entries(r).map(([m,h])=>({key:m,type:re(h),defaultValue:h}))}function M(t){return{...t}}function W(t,r){return JSON.stringify({data:t,metadata:r},null,2)}function ne({config:t,overrideBot:r,onOverrideChange:m,showOverride:h}){const{user:n}=R(),x=r||t.execute_as;return e.jsxs("div",{className:"bg-surface-sunken rounded-lg px-4 py-3 space-y-2",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("span",{className:"text-[10px] text-text-tertiary uppercase tracking-wider font-medium",children:"Running as"}),x&&!r&&e.jsx("span",{className:"text-[9px] text-text-tertiary",children:"configured default"}),r&&e.jsx("span",{className:"text-[9px] text-accent",children:"admin override"})]}),e.jsx("div",{className:"flex items-center gap-1.5",children:x?e.jsxs(e.Fragment,{children:[e.jsx(L,{className:"w-3.5 h-3.5 text-accent/70"}),e.jsx("span",{className:"text-xs text-text-primary font-mono",children:x})]}):e.jsxs(e.Fragment,{children:[e.jsx(Q,{className:"w-3.5 h-3.5 text-text-tertiary"}),e.jsx("span",{className:"text-xs text-text-primary",children:(n==null?void 0:n.displayName)||(n==null?void 0:n.username)||"you"})]})}),h&&m&&e.jsxs("div",{className:"pt-1 border-t border-surface-border",children:[e.jsx("label",{className:"text-[10px] text-text-tertiary mb-1 block",children:"Override identity"}),e.jsx(Z,{selected:r??"",onChange:m,placeholder:t.execute_as?`Default: ${t.execute_as}`:"Invoking user (default)"})]})]})}function oe({selectedConfig:t,isJsonMode:r,hasFormView:m,jsonInput:h,formFields:n,dataFields:x,onJsonChange:p,onToggleMode:i,onUpdateFormField:s,onSetFormFields:j}){return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-baseline justify-between mb-2",children:[e.jsx("label",{className:"block text-xs text-text-secondary",children:"Envelope"}),e.jsxs("div",{className:"flex items-center gap-3",children:[m&&e.jsx("button",{type:"button",onClick:i,className:"text-[10px] text-accent hover:underline",children:r?"Form view":"JSON view"}),t.envelope_schema?e.jsx("span",{className:"text-[10px] text-accent",children:"Pre-filled from workflow config"}):e.jsx("span",{className:"text-[10px] text-status-warning",children:"No template"})]})]}),!t.envelope_schema&&e.jsx("div",{className:"bg-surface-sunken border border-surface-border rounded px-4 py-3 mb-3",children:e.jsxs("p",{className:"text-xs text-text-secondary leading-relaxed",children:["This workflow has no input template. Edit the JSON directly below, or register it as a ",e.jsx(ee,{to:"/workflows/registry/new",className:"text-status-success hover:underline",children:"certified workflow"})," in the Workflow Registry for pre-filled fields and form-based input."]})}),r||!m?e.jsx("textarea",{value:h,onChange:a=>p(a.target.value),className:"input-json",rows:12,spellCheck:!1}):e.jsx("div",{className:"space-y-3",children:x.map(({key:a,type:l})=>{var N,v;const u=n[a],w=typeof u=="string"?u:JSON.stringify(u??(l==="array"?[]:{}),null,2),k=Math.min(20,Math.max(4,((v=(N=w==null?void 0:w.split)==null?void 0:N.call(w,`
|
|
5
5
|
`))==null?void 0:v.length)??4));return e.jsxs("div",{children:[e.jsxs("label",{className:"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:[a,e.jsx("span",{className:"ml-2 font-normal normal-case",children:l})]}),l==="boolean"?e.jsxs("select",{value:String(u??!1),onChange:f=>s(a,f.target.value,l),className:"select text-xs w-full",children:[e.jsx("option",{value:"true",children:"true"}),e.jsx("option",{value:"false",children:"false"})]}):l==="object"||l==="array"?e.jsx("textarea",{value:w,onChange:f=>{try{s(a,JSON.parse(f.target.value),l)}catch{j({...n,[a]:f.target.value})}},className:"input-json w-full",rows:k,spellCheck:!1}):e.jsx("input",{type:l==="number"?"number":"text",value:String(u??""),onChange:f=>s(a,f.target.value,l),className:"input text-xs w-full"})]},a)})}),e.jsxs("p",{className:"text-[10px] text-text-tertiary mt-1.5",children:["The envelope wraps your workflow input. ",e.jsx("code",{className:"text-accent/80",children:"data"})," holds workflow-specific fields; ",e.jsx("code",{className:"text-accent/80",children:"metadata"})," is optional context."]})]})}function le({selected:t,executionsPath:r}){var O,J;const m=te(),{isSuperAdmin:h,hasRoleType:n}=R(),x=h||n("admin"),p=D(),[i,s]=c.useState(I),[j,a]=c.useState(""),[l,u]=c.useState({}),[w,k]=c.useState(!1),[N,v]=c.useState(""),f=(((O=t.roles)==null?void 0:O.length)??0)>0||(((J=t.consumes)==null?void 0:J.length)??0)>0,[P,d]=c.useState(f),_=c.useMemo(()=>T(t.envelope_schema??null),[t.envelope_schema]),F=_.length>0,E=c.useMemo(()=>{if(!t.envelope_schema)return{};const o=t.envelope_schema.metadata;return o&&typeof o=="object"?o:{}},[t.envelope_schema]);c.useEffect(()=>{var S;a(""),p.reset();const o=sessionStorage.getItem("lt:invoke:prefill");if(o){sessionStorage.removeItem("lt:invoke:prefill"),s(o);try{const g=JSON.parse(o),C=(g==null?void 0:g.data)??g;C&&typeof C=="object"&&u(M(C))}catch{}k(!0),v("");return}const b=t.envelope_schema?JSON.stringify(t.envelope_schema,null,2):I;s(b),(S=t.envelope_schema)!=null&&S.data&&typeof t.envelope_schema.data=="object"?u(M(t.envelope_schema.data)):u({}),k(!T(t.envelope_schema??null).length),v(""),d(f)},[t.workflow_type]);const y=()=>{if(w)try{const o=JSON.parse(i);o.data&&typeof o.data=="object"&&u(M(o.data))}catch{}else s(W(l,E));k(!w)},q=(o,b,S)=>{let g=b;S==="number"?g=b===""?0:Number(b):S==="boolean"&&(g=b==="true"||b===!0);const C={...l,[o]:g};u(C),s(W(C,E))},A=async()=>{a("");let o;try{o=JSON.parse(i)}catch{a("Invalid JSON");return}const{data:b,metadata:S}=o;if(!b||typeof b!="object"){a('Envelope must include a "data" object');return}try{const g={...S??{}};P&&(g.certified=!0),await p.mutateAsync({workflowType:t.workflow_type,data:b,metadata:g,...N?{execute_as:N}:{}}),m(r)}catch{}};return e.jsxs("div",{className:"space-y-6",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-mono font-medium text-text-primary",children:t.workflow_type}),t.description&&e.jsx("p",{className:"text-xs text-text-quaternary mt-1 leading-relaxed",children:t.description})]}),e.jsx(ne,{config:t,overrideBot:N,onOverrideChange:v,showOverride:x}),f&&e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:P,onChange:o=>d(o.target.checked),className:"rounded border-surface-border text-accent focus:ring-accent/30"}),e.jsx(X,{className:"w-3.5 h-3.5 text-text-tertiary"}),e.jsx("span",{className:"text-xs text-text-secondary",children:"Enable task tracking and escalation routing"})]}),e.jsx(oe,{selectedConfig:t,isJsonMode:w,hasFormView:F,jsonInput:i,formFields:l,dataFields:_,onJsonChange:o=>{s(o),a("")},onToggleMode:y,onUpdateFormField:q,onSetFormFields:u}),j&&e.jsx("p",{className:"text-xs text-status-error",children:j}),p.error&&e.jsx("p",{className:"text-xs text-status-error",children:p.error.message}),p.isSuccess&&e.jsx("p",{className:"text-xs text-status-success",children:"Workflow started"}),e.jsx("button",{onClick:A,disabled:p.isPending,className:"btn-primary",children:p.isPending?"Starting...":"Start Workflow"})]})}function ce(){const[t,r]=se(),{data:m,isLoading:h}=B(),{data:n,isLoading:x}=$(),{data:p}=z(),i=t.get("type")??"",s=m??[],j=c.useMemo(()=>{const d=new Map;for(const _ of n??[])d.set(_.workflow_type,_.tier??"durable");return d},[n]),a=c.useMemo(()=>{const d=s.filter(y=>y.invocable),_=new Set(s.map(y=>y.workflow_type)),E=(n??[]).filter(y=>y.active&&!_.has(y.workflow_type)).map(y=>({workflow_type:y.workflow_type,task_queue:y.task_queue??"",invocable:!0,description:null,default_role:"reviewer",roles:[],invocation_roles:[],consumes:[],envelope_schema:null,resolver_schema:null,cron_schedule:null,execute_as:null}));return[...d,...E]},[s,n]),l=a.find(d=>d.workflow_type===i),u=new Set((p??[]).filter(d=>d.active).map(d=>d.workflow_type)),w="/workflows/executions",k=c.useRef(null),[N,v]=c.useState(!0),f=c.useRef(i);c.useEffect(()=>{if(f.current!==i){v(!1);const d=setTimeout(()=>{f.current=i,v(!0)},120);return()=>clearTimeout(d)}},[i]),c.useEffect(()=>{a.length===1&&!t.get("type")&&r({type:a[0].workflow_type},{replace:!0})},[a.length]);const P=d=>{r({type:d.workflow_type},{replace:!0})};return h||x?e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-40 bg-surface-sunken rounded"})]}):e.jsxs("div",{children:[e.jsx(H,{title:"Invoke",docsHash:"#docs:dashboard.md:invoke-workflow"}),a.length===0?e.jsxs("div",{className:"py-16 text-center",children:[e.jsx("p",{className:"text-sm text-text-primary mb-1",children:"No invocable workflows"}),e.jsx("p",{className:"text-xs text-text-tertiary",children:"Mark workflows as invocable in the registry, or start the server with examples enabled."})]}):e.jsxs("div",{className:"grid grid-cols-3 gap-8 items-start",children:[e.jsx("div",{className:"col-span-2",children:e.jsx(ae,{configs:a,selectedType:i,onSelect:P,tierMap:j,activeTypes:u})}),e.jsx("div",{ref:k,className:`sticky top-4 transition-all duration-200 ease-out ${N?"opacity-100 translate-y-0":"opacity-0 translate-y-1"}`,children:i&&l?e.jsx(le,{selected:l,executionsPath:w}):e.jsxs("div",{className:"flex flex-col items-center justify-center py-24 text-center",children:[e.jsx("div",{className:"w-12 h-12 rounded-full bg-accent/[0.06] flex items-center justify-center mb-4",children:e.jsx(Y,{className:"w-5 h-5 text-accent/50"})}),e.jsx("p",{className:"text-sm text-text-secondary mb-1",children:"Select a workflow"}),e.jsx("p",{className:"text-xs text-text-quaternary",children:"Choose one from the list to configure and invoke it."})]})})]})]})}function ye(){return e.jsx(ce,{})}export{ye as DurableInvokePage,ce as StartWorkflowPage};
|
|
6
|
-
//# sourceMappingURL=index-
|
|
6
|
+
//# sourceMappingURL=index-CkL8bpdH.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-BUbzfEA9.js","sources":["../../src/pages/workflows/start/WorkflowSelector.tsx","../../src/pages/workflows/start/helpers.ts","../../src/pages/workflows/start/IdentitySummary.tsx","../../src/pages/workflows/start/EnvelopeEditor.tsx","../../src/pages/workflows/start/StartNowPanel.tsx","../../src/pages/workflows/start/StartWorkflowPage.tsx","../../src/pages/workflows/start/DurableInvokePage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { Search, Bot, Clock } from 'lucide-react';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\nimport { NamespacePill } from '../../../components/common/display/NamespacePill';\nimport type { LTWorkflowConfig, WorkflowTier } from '../../../api/types';\n\nexport function WorkflowSelector({\n configs,\n selectedType,\n onSelect,\n tierMap,\n activeTypes,\n}: {\n configs: LTWorkflowConfig[];\n selectedType: string;\n onSelect: (config: LTWorkflowConfig) => void;\n tierMap: Map<string, WorkflowTier>;\n activeTypes?: Set<string>;\n}) {\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n if (!search.trim()) return configs;\n const q = search.toLowerCase();\n return configs.filter(\n (c) =>\n c.workflow_type.toLowerCase().includes(q) ||\n c.description?.toLowerCase().includes(q),\n );\n }, [configs, search]);\n\n return (\n <div>\n {/* Sticky header: search pill + section label — single block, no gap */}\n <div className=\"sticky top-0 z-20 bg-surface pt-4\">\n <div className=\"bg-[#F7F7F7] rounded-lg px-4 py-2 mb-3\">\n <div className=\"relative w-1/2\">\n <Search className=\"absolute left-0 top-1/2 -translate-y-1/2 w-3 h-3 text-text-quaternary\" />\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={`Search ${configs.length} workflows…`}\n className=\"w-full pl-5 py-1 text-sm bg-transparent border-b border-surface-border/60 text-text-primary placeholder:text-text-quaternary focus:outline-none focus:border-accent/50 transition-colors\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2 py-2 border-b border-surface-border\">\n <h2 className=\"section-h2\">Workflows</h2>\n <span className=\"text-xs text-text-quaternary\">{filtered.length}</span>\n </div>\n </div>\n\n {/* List */}\n {filtered.length === 0 ? (\n <p className=\"text-sm text-text-tertiary py-8 text-center\">No workflows match your search.</p>\n ) : (\n <div className=\"divide-y divide-surface-border/30\">\n {filtered.map((config) => {\n const isSelected = selectedType === config.workflow_type;\n const tier = tierMap.get(config.workflow_type) ?? 'durable';\n const variant =\n tier === 'certified' ? 'certified' : tier === 'configured' ? 'configured' : 'durable';\n return (\n <button\n key={config.workflow_type}\n onClick={() => onSelect(config)}\n className=\"group relative w-full text-left py-3 px-3 -mx-3 rounded-md transition-colors duration-150\"\n >\n {isSelected && (\n <span className=\"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full\" />\n )}\n <div className=\"flex items-center gap-2 mb-1\">\n <WorkflowPill type={config.workflow_type} size=\"md\" variant={variant} />\n <span className=\"ml-auto flex items-center gap-2 shrink-0\">\n {config.execute_as && (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[9px] bg-accent/10 text-accent rounded\">\n <Bot className=\"w-2.5 h-2.5\" />\n {config.execute_as}\n </span>\n )}\n {activeTypes?.has(config.workflow_type) && (\n <span title=\"Cron schedule active\">\n <Clock className=\"w-3 h-3 text-status-success/70 shrink-0\" />\n </span>\n )}\n <NamespacePill namespace=\"durable\" />\n </span>\n </div>\n {config.description && (\n <p className=\"text-[10px] text-text-tertiary group-hover:text-text-secondary leading-relaxed line-clamp-2 pl-0.5 transition-colors\">\n {config.description}\n </p>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","export const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n\n/** Infer a simple field type from a value. */\nexport function inferTypeFromValue(value: unknown): string {\n if (typeof value === 'boolean') return 'boolean';\n if (typeof value === 'number') return 'number';\n if (Array.isArray(value)) return 'array';\n if (value !== null && typeof value === 'object') return 'object';\n return 'string';\n}\n\n/** Extract the data keys from an envelope_schema and their inferred types. */\nexport function extractDataFields(\n schema: Record<string, unknown> | null,\n): { key: string; type: string; defaultValue: unknown }[] {\n if (!schema) return [];\n const data = schema.data;\n if (!data || typeof data !== 'object') return [];\n return Object.entries(data as Record<string, unknown>).map(([key, value]) => ({\n key,\n type: inferTypeFromValue(value),\n defaultValue: value,\n }));\n}\n\n/** Build form field values from data object. */\nexport function dataToFields(data: Record<string, unknown>): Record<string, unknown> {\n return { ...data };\n}\n\n/** Build full envelope JSON string from form fields + metadata. */\nexport function fieldsToJson(\n fields: Record<string, unknown>,\n metadata: Record<string, unknown>,\n): string {\n return JSON.stringify({ data: fields, metadata }, null, 2);\n}\n","import { Bot, UserCircle } from 'lucide-react';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { useAuth } from '../../../hooks/useAuth';\nimport type { LTWorkflowConfig } from '../../../api/types';\n\nexport function IdentitySummary({\n config,\n overrideBot,\n onOverrideChange,\n showOverride,\n}: {\n config: LTWorkflowConfig;\n overrideBot?: string;\n onOverrideChange?: (botExternalId: string) => void;\n showOverride?: boolean;\n}) {\n const { user } = useAuth();\n const effectiveBot = overrideBot || config.execute_as;\n\n return (\n <div className=\"bg-surface-sunken rounded-lg px-4 py-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider font-medium\">Running as</span>\n {effectiveBot && !overrideBot && (\n <span className=\"text-[9px] text-text-tertiary\">configured default</span>\n )}\n {overrideBot && (\n <span className=\"text-[9px] text-accent\">admin override</span>\n )}\n </div>\n <div className=\"flex items-center gap-1.5\">\n {effectiveBot ? (\n <>\n <Bot className=\"w-3.5 h-3.5 text-accent/70\" />\n <span className=\"text-xs text-text-primary font-mono\">{effectiveBot}</span>\n </>\n ) : (\n <>\n <UserCircle className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <span className=\"text-xs text-text-primary\">\n {user?.displayName || user?.username || 'you'}\n </span>\n </>\n )}\n </div>\n {showOverride && onOverrideChange && (\n <div className=\"pt-1 border-t border-surface-border\">\n <label className=\"text-[10px] text-text-tertiary mb-1 block\">Override identity</label>\n <BotPicker\n selected={overrideBot ?? ''}\n onChange={onOverrideChange}\n placeholder={config.execute_as ? `Default: ${config.execute_as}` : 'Invoking user (default)'}\n />\n </div>\n )}\n </div>\n );\n}\n","import { Link } from 'react-router-dom';\nimport type { LTWorkflowConfig } from '../../../api/types';\n\ninterface DataField {\n key: string;\n type: string;\n defaultValue: unknown;\n}\n\nexport function EnvelopeEditor({\n selectedConfig,\n isJsonMode,\n hasFormView,\n jsonInput,\n formFields,\n dataFields,\n onJsonChange,\n onToggleMode,\n onUpdateFormField,\n onSetFormFields,\n}: {\n selectedConfig: LTWorkflowConfig;\n isJsonMode: boolean;\n hasFormView: boolean;\n jsonInput: string;\n formFields: Record<string, unknown>;\n dataFields: DataField[];\n onJsonChange: (value: string) => void;\n onToggleMode: () => void;\n onUpdateFormField: (key: string, value: unknown, type: string) => void;\n onSetFormFields: (fields: Record<string, unknown>) => void;\n}) {\n return (\n <div>\n <div className=\"flex items-baseline justify-between mb-2\">\n <label className=\"block text-xs text-text-secondary\">\n Envelope\n </label>\n <div className=\"flex items-center gap-3\">\n {hasFormView && (\n <button\n type=\"button\"\n onClick={onToggleMode}\n className=\"text-[10px] text-accent hover:underline\"\n >\n {isJsonMode ? 'Form view' : 'JSON view'}\n </button>\n )}\n {selectedConfig.envelope_schema ? (\n <span className=\"text-[10px] text-accent\">\n Pre-filled from workflow config\n </span>\n ) : (\n <span className=\"text-[10px] text-status-warning\">\n No template\n </span>\n )}\n </div>\n </div>\n\n {!selectedConfig.envelope_schema && (\n <div className=\"bg-surface-sunken border border-surface-border rounded px-4 py-3 mb-3\">\n <p className=\"text-xs text-text-secondary leading-relaxed\">\n This workflow has no input template. Edit the JSON directly below, or register it as a <Link to=\"/workflows/registry/new\" className=\"text-status-success hover:underline\">certified workflow</Link> in the Workflow Registry for pre-filled fields and form-based input.\n </p>\n </div>\n )}\n\n {isJsonMode || !hasFormView ? (\n /* JSON view */\n <textarea\n value={jsonInput}\n onChange={(e) => onJsonChange(e.target.value)}\n className=\"input-json\"\n rows={12}\n spellCheck={false}\n />\n ) : (\n /* Form view */\n <div className=\"space-y-3\">\n {dataFields.map(({ key, type }) => {\n const value = formFields[key];\n const jsonValue =\n typeof value === 'string'\n ? value\n : JSON.stringify(\n value ?? (type === 'array' ? [] : {}),\n null,\n 2,\n );\n const textareaRows = Math.min(\n 20,\n Math.max(4, (jsonValue?.split?.('\\n')?.length ?? 4)),\n );\n return (\n <div key={key}>\n <label className=\"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">\n {key}\n <span className=\"ml-2 font-normal normal-case\">\n {type}\n </span>\n </label>\n {type === 'boolean' ? (\n <select\n value={String(value ?? false)}\n onChange={(e) =>\n onUpdateFormField(key, e.target.value, type)\n }\n className=\"select text-xs w-full\"\n >\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : type === 'object' || type === 'array' ? (\n <textarea\n value={jsonValue}\n onChange={(e) => {\n try {\n onUpdateFormField(\n key,\n JSON.parse(e.target.value),\n type,\n );\n } catch {\n // Keep raw text without syncing to JSON\n onSetFormFields({\n ...formFields,\n [key]: e.target.value,\n });\n }\n }}\n className=\"input-json w-full\"\n rows={textareaRows}\n spellCheck={false}\n />\n ) : (\n <input\n type={type === 'number' ? 'number' : 'text'}\n value={String(value ?? '')}\n onChange={(e) =>\n onUpdateFormField(key, e.target.value, type)\n }\n className=\"input text-xs w-full\"\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n <p className=\"text-[10px] text-text-tertiary mt-1.5\">\n The envelope wraps your workflow input. <code className=\"text-accent/80\">data</code> holds workflow-specific fields; <code className=\"text-accent/80\">metadata</code> is optional context.\n </p>\n </div>\n );\n}\n","import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ShieldCheck } from 'lucide-react';\nimport { useInvokeWorkflow } from '../../../api/workflows';\nimport { useAuth } from '../../../hooks/useAuth';\nimport type { LTWorkflowConfig } from '../../../api/types';\nimport {\n DEFAULT_ENVELOPE,\n extractDataFields,\n dataToFields,\n fieldsToJson,\n} from './helpers';\nimport { IdentitySummary } from './IdentitySummary';\nimport { EnvelopeEditor } from './EnvelopeEditor';\n\nexport function StartNowPanel({ selected, executionsPath }: { selected: LTWorkflowConfig; executionsPath: string }) {\n const navigate = useNavigate();\n const { isSuperAdmin, hasRoleType } = useAuth();\n const isAdmin = isSuperAdmin || hasRoleType('admin');\n const invokeMutation = useInvokeWorkflow();\n const [jsonInput, setJsonInput] = useState(DEFAULT_ENVELOPE);\n const [parseError, setParseError] = useState('');\n const [formFields, setFormFields] = useState<Record<string, unknown>>({});\n const [isJsonMode, setIsJsonMode] = useState(false);\n const [overrideBot, setOverrideBot] = useState('');\n const isCertifiable = (selected.roles?.length ?? 0) > 0 || (selected.consumes?.length ?? 0) > 0;\n const [certified, setCertified] = useState(isCertifiable);\n\n const dataFields = useMemo(\n () => extractDataFields(selected.envelope_schema ?? null),\n [selected.envelope_schema],\n );\n const hasFormView = dataFields.length > 0;\n\n const schemaMetadata = useMemo(() => {\n if (!selected.envelope_schema) return {};\n const md = selected.envelope_schema.metadata;\n return md && typeof md === 'object' ? (md as Record<string, unknown>) : {};\n }, [selected.envelope_schema]);\n\n useEffect(() => {\n setParseError('');\n invokeMutation.reset();\n\n const prefill = sessionStorage.getItem('lt:invoke:prefill');\n if (prefill) {\n sessionStorage.removeItem('lt:invoke:prefill');\n setJsonInput(prefill);\n try {\n const parsed = JSON.parse(prefill);\n const data = parsed?.data ?? parsed;\n if (data && typeof data === 'object') setFormFields(dataToFields(data));\n } catch { /* use as-is */ }\n setIsJsonMode(true);\n setOverrideBot('');\n return;\n }\n\n const json = selected.envelope_schema\n ? JSON.stringify(selected.envelope_schema, null, 2)\n : DEFAULT_ENVELOPE;\n setJsonInput(json);\n if (selected.envelope_schema?.data && typeof selected.envelope_schema.data === 'object') {\n setFormFields(dataToFields(selected.envelope_schema.data as Record<string, unknown>));\n } else {\n setFormFields({});\n }\n setIsJsonMode(!extractDataFields(selected.envelope_schema ?? null).length);\n setOverrideBot('');\n setCertified(isCertifiable);\n }, [selected.workflow_type]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleToggleMode = () => {\n if (isJsonMode) {\n try {\n const parsed = JSON.parse(jsonInput);\n if (parsed.data && typeof parsed.data === 'object') setFormFields(dataToFields(parsed.data));\n } catch { /* keep existing */ }\n } else {\n setJsonInput(fieldsToJson(formFields, schemaMetadata));\n }\n setIsJsonMode(!isJsonMode);\n };\n\n const updateFormField = (key: string, value: unknown, type: string) => {\n let parsed = value;\n if (type === 'number') parsed = value === '' ? 0 : Number(value);\n else if (type === 'boolean') parsed = value === 'true' || value === true;\n const updated = { ...formFields, [key]: parsed };\n setFormFields(updated);\n setJsonInput(fieldsToJson(updated, schemaMetadata));\n };\n\n const handleInvoke = async () => {\n setParseError('');\n let envelope: Record<string, unknown>;\n try {\n envelope = JSON.parse(jsonInput);\n } catch {\n setParseError('Invalid JSON');\n return;\n }\n const { data, metadata } = envelope;\n if (!data || typeof data !== 'object') {\n setParseError('Envelope must include a \"data\" object');\n return;\n }\n try {\n const resolvedMetadata = { ...((metadata as Record<string, unknown>) ?? {}) };\n if (certified) resolvedMetadata.certified = true;\n await invokeMutation.mutateAsync({\n workflowType: selected.workflow_type,\n data: data as Record<string, unknown>,\n metadata: resolvedMetadata,\n ...(overrideBot ? { execute_as: overrideBot } : {}),\n });\n navigate(executionsPath);\n } catch { /* error via mutation */ }\n };\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h2 className=\"text-lg font-mono font-medium text-text-primary\">{selected.workflow_type}</h2>\n {selected.description && (\n <p className=\"text-xs text-text-quaternary mt-1 leading-relaxed\">\n {selected.description}\n </p>\n )}\n </div>\n\n <IdentitySummary\n config={selected}\n overrideBot={overrideBot}\n onOverrideChange={setOverrideBot}\n showOverride={isAdmin}\n />\n\n {isCertifiable && (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={certified}\n onChange={(e) => setCertified(e.target.checked)}\n className=\"rounded border-surface-border text-accent focus:ring-accent/30\"\n />\n <ShieldCheck className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <span className=\"text-xs text-text-secondary\">Enable task tracking and escalation routing</span>\n </label>\n )}\n\n <EnvelopeEditor\n selectedConfig={selected}\n isJsonMode={isJsonMode}\n hasFormView={hasFormView}\n jsonInput={jsonInput}\n formFields={formFields}\n dataFields={dataFields}\n onJsonChange={(v) => { setJsonInput(v); setParseError(''); }}\n onToggleMode={handleToggleMode}\n onUpdateFormField={updateFormField}\n onSetFormFields={setFormFields}\n />\n\n {parseError && <p className=\"text-xs text-status-error\">{parseError}</p>}\n {invokeMutation.error && <p className=\"text-xs text-status-error\">{invokeMutation.error.message}</p>}\n {invokeMutation.isSuccess && <p className=\"text-xs text-status-success\">Workflow started</p>}\n\n <button onClick={handleInvoke} disabled={invokeMutation.isPending} className=\"btn-primary\">\n {invokeMutation.isPending ? 'Starting...' : 'Start Workflow'}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Play } from 'lucide-react';\nimport { useWorkflowConfigs, useDiscoveredWorkflows, useCronStatus } from '../../../api/workflows';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport type { LTWorkflowConfig, WorkflowTier } from '../../../api/types';\nimport { WorkflowSelector } from './WorkflowSelector';\nimport { StartNowPanel } from './StartNowPanel';\n\nexport function StartWorkflowPage() {\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: configsData, isLoading } = useWorkflowConfigs();\n const { data: discoveredData, isLoading: discoveredLoading } = useDiscoveredWorkflows();\n const { data: cronEntries } = useCronStatus();\n\n const selectedType = searchParams.get('type') ?? '';\n\n const configs: LTWorkflowConfig[] = configsData ?? [];\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 invocableConfigs = useMemo(() => {\n const certified = configs.filter((c) => c.invocable);\n const registeredTypes = new Set(configs.map((c) => c.workflow_type));\n const discovered = discoveredData ?? [];\n const durable = discovered\n .filter((dw) => dw.active && !registeredTypes.has(dw.workflow_type))\n .map((dw) => ({\n workflow_type: dw.workflow_type,\n task_queue: dw.task_queue ?? '',\n invocable: true,\n description: null,\n default_role: 'reviewer',\n roles: [],\n invocation_roles: [],\n consumes: [],\n envelope_schema: null,\n resolver_schema: null,\n cron_schedule: null,\n execute_as: null,\n } satisfies LTWorkflowConfig));\n return [...certified, ...durable];\n }, [configs, discoveredData]);\n\n const selectedConfig = invocableConfigs.find((c) => c.workflow_type === selectedType);\n\n const activeTypes = new Set(\n (cronEntries ?? []).filter((e) => e.active).map((e) => e.workflow_type),\n );\n\n const executionsPath = '/workflows/executions';\n\n // Fade transition when selection changes\n const panelRef = useRef<HTMLDivElement>(null);\n const [panelVisible, setPanelVisible] = useState(true);\n const prevKeyRef = useRef(selectedType);\n useEffect(() => {\n if (prevKeyRef.current !== selectedType) {\n setPanelVisible(false);\n const timer = setTimeout(() => {\n prevKeyRef.current = selectedType;\n setPanelVisible(true);\n }, 120);\n return () => clearTimeout(timer);\n }\n }, [selectedType]);\n\n useEffect(() => {\n if (invocableConfigs.length === 1 && !searchParams.get('type')) {\n setSearchParams({ type: invocableConfigs[0].workflow_type }, { replace: true });\n }\n }, [invocableConfigs.length]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleSelect = (config: LTWorkflowConfig) => {\n setSearchParams({ type: config.workflow_type }, { replace: true });\n };\n\n if (isLoading || discoveredLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-48\" />\n <div className=\"h-40 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n return (\n <div>\n <PageHeader title=\"Invoke\" docsHash=\"#docs:dashboard.md:invoke-workflow\" />\n\n {invocableConfigs.length === 0 ? (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-primary mb-1\">No invocable workflows</p>\n <p className=\"text-xs text-text-tertiary\">Mark workflows as invocable in the registry, or start the server with examples enabled.</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-3 gap-8 items-start\">\n\n {/* ── Left: workflow list (2 cols) ── */}\n <div className=\"col-span-2\">\n <WorkflowSelector\n configs={invocableConfigs}\n selectedType={selectedType}\n onSelect={handleSelect}\n tierMap={tierMap}\n activeTypes={activeTypes}\n />\n </div>\n\n {/* ── Right: invoke form (1 col, sticky) ── */}\n <div\n ref={panelRef}\n className={`sticky top-4 transition-all duration-200 ease-out ${\n panelVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-1'\n }`}\n >\n {selectedType && selectedConfig ? (\n <StartNowPanel selected={selectedConfig} executionsPath={executionsPath} />\n ) : (\n <div className=\"flex flex-col items-center justify-center py-24 text-center\">\n <div className=\"w-12 h-12 rounded-full bg-accent/[0.06] flex items-center justify-center mb-4\">\n <Play className=\"w-5 h-5 text-accent/50\" />\n </div>\n <p className=\"text-sm text-text-secondary mb-1\">Select a workflow</p>\n <p className=\"text-xs text-text-quaternary\">Choose one from the list to configure and invoke it.</p>\n </div>\n )}\n </div>\n\n </div>\n )}\n </div>\n );\n}\n","import { StartWorkflowPage } from './StartWorkflowPage';\n\nexport function DurableInvokePage() {\n return <StartWorkflowPage />;\n}\n"],"names":["WorkflowSelector","configs","selectedType","onSelect","tierMap","activeTypes","search","setSearch","useState","filtered","useMemo","q","c","_a","jsxs","jsx","Search","e","config","isSelected","tier","variant","WorkflowPill","Bot","Clock","NamespacePill","DEFAULT_ENVELOPE","inferTypeFromValue","value","extractDataFields","schema","data","key","dataToFields","fieldsToJson","fields","metadata","IdentitySummary","overrideBot","onOverrideChange","showOverride","user","useAuth","effectiveBot","Fragment","UserCircle","BotPicker","EnvelopeEditor","selectedConfig","isJsonMode","hasFormView","jsonInput","formFields","dataFields","onJsonChange","onToggleMode","onUpdateFormField","onSetFormFields","Link","type","jsonValue","textareaRows","_b","StartNowPanel","selected","executionsPath","navigate","useNavigate","isSuperAdmin","hasRoleType","isAdmin","invokeMutation","useInvokeWorkflow","setJsonInput","parseError","setParseError","setFormFields","setIsJsonMode","setOverrideBot","isCertifiable","certified","setCertified","schemaMetadata","md","useEffect","prefill","parsed","json","handleToggleMode","updateFormField","updated","handleInvoke","envelope","resolvedMetadata","ShieldCheck","v","StartWorkflowPage","searchParams","setSearchParams","useSearchParams","configsData","isLoading","useWorkflowConfigs","discoveredData","discoveredLoading","useDiscoveredWorkflows","cronEntries","useCronStatus","map","dw","invocableConfigs","registeredTypes","durable","panelRef","useRef","panelVisible","setPanelVisible","prevKeyRef","timer","handleSelect","PageHeader","Play","DurableInvokePage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CkL8bpdH.js","sources":["../../src/pages/workflows/start/WorkflowSelector.tsx","../../src/pages/workflows/start/helpers.ts","../../src/pages/workflows/start/IdentitySummary.tsx","../../src/pages/workflows/start/EnvelopeEditor.tsx","../../src/pages/workflows/start/StartNowPanel.tsx","../../src/pages/workflows/start/StartWorkflowPage.tsx","../../src/pages/workflows/start/DurableInvokePage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { Search, Bot, Clock } from 'lucide-react';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\nimport { NamespacePill } from '../../../components/common/display/NamespacePill';\nimport type { LTWorkflowConfig, WorkflowTier } from '../../../api/types';\n\nexport function WorkflowSelector({\n configs,\n selectedType,\n onSelect,\n tierMap,\n activeTypes,\n}: {\n configs: LTWorkflowConfig[];\n selectedType: string;\n onSelect: (config: LTWorkflowConfig) => void;\n tierMap: Map<string, WorkflowTier>;\n activeTypes?: Set<string>;\n}) {\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n if (!search.trim()) return configs;\n const q = search.toLowerCase();\n return configs.filter(\n (c) =>\n c.workflow_type.toLowerCase().includes(q) ||\n c.description?.toLowerCase().includes(q),\n );\n }, [configs, search]);\n\n return (\n <div>\n {/* Sticky header: search pill + section label — single block, no gap */}\n <div className=\"sticky top-0 z-20 bg-surface pt-4\">\n <div className=\"bg-[#F7F7F7] rounded-lg px-4 py-2 mb-3\">\n <div className=\"relative w-1/2\">\n <Search className=\"absolute left-0 top-1/2 -translate-y-1/2 w-3 h-3 text-text-quaternary\" />\n <input\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder={`Search ${configs.length} workflows…`}\n className=\"w-full pl-5 py-1 text-sm bg-transparent border-b border-surface-border/60 text-text-primary placeholder:text-text-quaternary focus:outline-none focus:border-accent/50 transition-colors\"\n />\n </div>\n </div>\n <div className=\"flex items-center gap-2 py-2 border-b border-surface-border\">\n <h2 className=\"section-h2\">Workflows</h2>\n <span className=\"text-xs text-text-quaternary\">{filtered.length}</span>\n </div>\n </div>\n\n {/* List */}\n {filtered.length === 0 ? (\n <p className=\"text-sm text-text-tertiary py-8 text-center\">No workflows match your search.</p>\n ) : (\n <div className=\"divide-y divide-surface-border/30\">\n {filtered.map((config) => {\n const isSelected = selectedType === config.workflow_type;\n const tier = tierMap.get(config.workflow_type) ?? 'durable';\n const variant =\n tier === 'certified' ? 'certified' : tier === 'configured' ? 'configured' : 'durable';\n return (\n <button\n key={config.workflow_type}\n onClick={() => onSelect(config)}\n className=\"group relative w-full text-left py-3 px-3 -mx-3 rounded-md transition-colors duration-150\"\n >\n {isSelected && (\n <span className=\"absolute left-0 top-1 bottom-1 w-0.5 bg-accent rounded-full\" />\n )}\n <div className=\"flex items-center gap-2 mb-1\">\n <WorkflowPill type={config.workflow_type} size=\"md\" variant={variant} />\n <span className=\"ml-auto flex items-center gap-2 shrink-0\">\n {config.execute_as && (\n <span className=\"inline-flex items-center gap-0.5 px-1.5 py-0.5 text-[9px] bg-accent/10 text-accent rounded\">\n <Bot className=\"w-2.5 h-2.5\" />\n {config.execute_as}\n </span>\n )}\n {activeTypes?.has(config.workflow_type) && (\n <span title=\"Cron schedule active\">\n <Clock className=\"w-3 h-3 text-status-success/70 shrink-0\" />\n </span>\n )}\n <NamespacePill namespace=\"durable\" />\n </span>\n </div>\n {config.description && (\n <p className=\"text-[10px] text-text-tertiary group-hover:text-text-secondary leading-relaxed line-clamp-2 pl-0.5 transition-colors\">\n {config.description}\n </p>\n )}\n </button>\n );\n })}\n </div>\n )}\n </div>\n );\n}\n","export const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n\n/** Infer a simple field type from a value. */\nexport function inferTypeFromValue(value: unknown): string {\n if (typeof value === 'boolean') return 'boolean';\n if (typeof value === 'number') return 'number';\n if (Array.isArray(value)) return 'array';\n if (value !== null && typeof value === 'object') return 'object';\n return 'string';\n}\n\n/** Extract the data keys from an envelope_schema and their inferred types. */\nexport function extractDataFields(\n schema: Record<string, unknown> | null,\n): { key: string; type: string; defaultValue: unknown }[] {\n if (!schema) return [];\n const data = schema.data;\n if (!data || typeof data !== 'object') return [];\n return Object.entries(data as Record<string, unknown>).map(([key, value]) => ({\n key,\n type: inferTypeFromValue(value),\n defaultValue: value,\n }));\n}\n\n/** Build form field values from data object. */\nexport function dataToFields(data: Record<string, unknown>): Record<string, unknown> {\n return { ...data };\n}\n\n/** Build full envelope JSON string from form fields + metadata. */\nexport function fieldsToJson(\n fields: Record<string, unknown>,\n metadata: Record<string, unknown>,\n): string {\n return JSON.stringify({ data: fields, metadata }, null, 2);\n}\n","import { Bot, UserCircle } from 'lucide-react';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { useAuth } from '../../../hooks/useAuth';\nimport type { LTWorkflowConfig } from '../../../api/types';\n\nexport function IdentitySummary({\n config,\n overrideBot,\n onOverrideChange,\n showOverride,\n}: {\n config: LTWorkflowConfig;\n overrideBot?: string;\n onOverrideChange?: (botExternalId: string) => void;\n showOverride?: boolean;\n}) {\n const { user } = useAuth();\n const effectiveBot = overrideBot || config.execute_as;\n\n return (\n <div className=\"bg-surface-sunken rounded-lg px-4 py-3 space-y-2\">\n <div className=\"flex items-center justify-between\">\n <span className=\"text-[10px] text-text-tertiary uppercase tracking-wider font-medium\">Running as</span>\n {effectiveBot && !overrideBot && (\n <span className=\"text-[9px] text-text-tertiary\">configured default</span>\n )}\n {overrideBot && (\n <span className=\"text-[9px] text-accent\">admin override</span>\n )}\n </div>\n <div className=\"flex items-center gap-1.5\">\n {effectiveBot ? (\n <>\n <Bot className=\"w-3.5 h-3.5 text-accent/70\" />\n <span className=\"text-xs text-text-primary font-mono\">{effectiveBot}</span>\n </>\n ) : (\n <>\n <UserCircle className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <span className=\"text-xs text-text-primary\">\n {user?.displayName || user?.username || 'you'}\n </span>\n </>\n )}\n </div>\n {showOverride && onOverrideChange && (\n <div className=\"pt-1 border-t border-surface-border\">\n <label className=\"text-[10px] text-text-tertiary mb-1 block\">Override identity</label>\n <BotPicker\n selected={overrideBot ?? ''}\n onChange={onOverrideChange}\n placeholder={config.execute_as ? `Default: ${config.execute_as}` : 'Invoking user (default)'}\n />\n </div>\n )}\n </div>\n );\n}\n","import { Link } from 'react-router-dom';\nimport type { LTWorkflowConfig } from '../../../api/types';\n\ninterface DataField {\n key: string;\n type: string;\n defaultValue: unknown;\n}\n\nexport function EnvelopeEditor({\n selectedConfig,\n isJsonMode,\n hasFormView,\n jsonInput,\n formFields,\n dataFields,\n onJsonChange,\n onToggleMode,\n onUpdateFormField,\n onSetFormFields,\n}: {\n selectedConfig: LTWorkflowConfig;\n isJsonMode: boolean;\n hasFormView: boolean;\n jsonInput: string;\n formFields: Record<string, unknown>;\n dataFields: DataField[];\n onJsonChange: (value: string) => void;\n onToggleMode: () => void;\n onUpdateFormField: (key: string, value: unknown, type: string) => void;\n onSetFormFields: (fields: Record<string, unknown>) => void;\n}) {\n return (\n <div>\n <div className=\"flex items-baseline justify-between mb-2\">\n <label className=\"block text-xs text-text-secondary\">\n Envelope\n </label>\n <div className=\"flex items-center gap-3\">\n {hasFormView && (\n <button\n type=\"button\"\n onClick={onToggleMode}\n className=\"text-[10px] text-accent hover:underline\"\n >\n {isJsonMode ? 'Form view' : 'JSON view'}\n </button>\n )}\n {selectedConfig.envelope_schema ? (\n <span className=\"text-[10px] text-accent\">\n Pre-filled from workflow config\n </span>\n ) : (\n <span className=\"text-[10px] text-status-warning\">\n No template\n </span>\n )}\n </div>\n </div>\n\n {!selectedConfig.envelope_schema && (\n <div className=\"bg-surface-sunken border border-surface-border rounded px-4 py-3 mb-3\">\n <p className=\"text-xs text-text-secondary leading-relaxed\">\n This workflow has no input template. Edit the JSON directly below, or register it as a <Link to=\"/workflows/registry/new\" className=\"text-status-success hover:underline\">certified workflow</Link> in the Workflow Registry for pre-filled fields and form-based input.\n </p>\n </div>\n )}\n\n {isJsonMode || !hasFormView ? (\n /* JSON view */\n <textarea\n value={jsonInput}\n onChange={(e) => onJsonChange(e.target.value)}\n className=\"input-json\"\n rows={12}\n spellCheck={false}\n />\n ) : (\n /* Form view */\n <div className=\"space-y-3\">\n {dataFields.map(({ key, type }) => {\n const value = formFields[key];\n const jsonValue =\n typeof value === 'string'\n ? value\n : JSON.stringify(\n value ?? (type === 'array' ? [] : {}),\n null,\n 2,\n );\n const textareaRows = Math.min(\n 20,\n Math.max(4, (jsonValue?.split?.('\\n')?.length ?? 4)),\n );\n return (\n <div key={key}>\n <label className=\"block text-[10px] font-semibold uppercase tracking-widest text-text-tertiary mb-1\">\n {key}\n <span className=\"ml-2 font-normal normal-case\">\n {type}\n </span>\n </label>\n {type === 'boolean' ? (\n <select\n value={String(value ?? false)}\n onChange={(e) =>\n onUpdateFormField(key, e.target.value, type)\n }\n className=\"select text-xs w-full\"\n >\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : type === 'object' || type === 'array' ? (\n <textarea\n value={jsonValue}\n onChange={(e) => {\n try {\n onUpdateFormField(\n key,\n JSON.parse(e.target.value),\n type,\n );\n } catch {\n // Keep raw text without syncing to JSON\n onSetFormFields({\n ...formFields,\n [key]: e.target.value,\n });\n }\n }}\n className=\"input-json w-full\"\n rows={textareaRows}\n spellCheck={false}\n />\n ) : (\n <input\n type={type === 'number' ? 'number' : 'text'}\n value={String(value ?? '')}\n onChange={(e) =>\n onUpdateFormField(key, e.target.value, type)\n }\n className=\"input text-xs w-full\"\n />\n )}\n </div>\n );\n })}\n </div>\n )}\n <p className=\"text-[10px] text-text-tertiary mt-1.5\">\n The envelope wraps your workflow input. <code className=\"text-accent/80\">data</code> holds workflow-specific fields; <code className=\"text-accent/80\">metadata</code> is optional context.\n </p>\n </div>\n );\n}\n","import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { ShieldCheck } from 'lucide-react';\nimport { useInvokeWorkflow } from '../../../api/workflows';\nimport { useAuth } from '../../../hooks/useAuth';\nimport type { LTWorkflowConfig } from '../../../api/types';\nimport {\n DEFAULT_ENVELOPE,\n extractDataFields,\n dataToFields,\n fieldsToJson,\n} from './helpers';\nimport { IdentitySummary } from './IdentitySummary';\nimport { EnvelopeEditor } from './EnvelopeEditor';\n\nexport function StartNowPanel({ selected, executionsPath }: { selected: LTWorkflowConfig; executionsPath: string }) {\n const navigate = useNavigate();\n const { isSuperAdmin, hasRoleType } = useAuth();\n const isAdmin = isSuperAdmin || hasRoleType('admin');\n const invokeMutation = useInvokeWorkflow();\n const [jsonInput, setJsonInput] = useState(DEFAULT_ENVELOPE);\n const [parseError, setParseError] = useState('');\n const [formFields, setFormFields] = useState<Record<string, unknown>>({});\n const [isJsonMode, setIsJsonMode] = useState(false);\n const [overrideBot, setOverrideBot] = useState('');\n const isCertifiable = (selected.roles?.length ?? 0) > 0 || (selected.consumes?.length ?? 0) > 0;\n const [certified, setCertified] = useState(isCertifiable);\n\n const dataFields = useMemo(\n () => extractDataFields(selected.envelope_schema ?? null),\n [selected.envelope_schema],\n );\n const hasFormView = dataFields.length > 0;\n\n const schemaMetadata = useMemo(() => {\n if (!selected.envelope_schema) return {};\n const md = selected.envelope_schema.metadata;\n return md && typeof md === 'object' ? (md as Record<string, unknown>) : {};\n }, [selected.envelope_schema]);\n\n useEffect(() => {\n setParseError('');\n invokeMutation.reset();\n\n const prefill = sessionStorage.getItem('lt:invoke:prefill');\n if (prefill) {\n sessionStorage.removeItem('lt:invoke:prefill');\n setJsonInput(prefill);\n try {\n const parsed = JSON.parse(prefill);\n const data = parsed?.data ?? parsed;\n if (data && typeof data === 'object') setFormFields(dataToFields(data));\n } catch { /* use as-is */ }\n setIsJsonMode(true);\n setOverrideBot('');\n return;\n }\n\n const json = selected.envelope_schema\n ? JSON.stringify(selected.envelope_schema, null, 2)\n : DEFAULT_ENVELOPE;\n setJsonInput(json);\n if (selected.envelope_schema?.data && typeof selected.envelope_schema.data === 'object') {\n setFormFields(dataToFields(selected.envelope_schema.data as Record<string, unknown>));\n } else {\n setFormFields({});\n }\n setIsJsonMode(!extractDataFields(selected.envelope_schema ?? null).length);\n setOverrideBot('');\n setCertified(isCertifiable);\n }, [selected.workflow_type]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleToggleMode = () => {\n if (isJsonMode) {\n try {\n const parsed = JSON.parse(jsonInput);\n if (parsed.data && typeof parsed.data === 'object') setFormFields(dataToFields(parsed.data));\n } catch { /* keep existing */ }\n } else {\n setJsonInput(fieldsToJson(formFields, schemaMetadata));\n }\n setIsJsonMode(!isJsonMode);\n };\n\n const updateFormField = (key: string, value: unknown, type: string) => {\n let parsed = value;\n if (type === 'number') parsed = value === '' ? 0 : Number(value);\n else if (type === 'boolean') parsed = value === 'true' || value === true;\n const updated = { ...formFields, [key]: parsed };\n setFormFields(updated);\n setJsonInput(fieldsToJson(updated, schemaMetadata));\n };\n\n const handleInvoke = async () => {\n setParseError('');\n let envelope: Record<string, unknown>;\n try {\n envelope = JSON.parse(jsonInput);\n } catch {\n setParseError('Invalid JSON');\n return;\n }\n const { data, metadata } = envelope;\n if (!data || typeof data !== 'object') {\n setParseError('Envelope must include a \"data\" object');\n return;\n }\n try {\n const resolvedMetadata = { ...((metadata as Record<string, unknown>) ?? {}) };\n if (certified) resolvedMetadata.certified = true;\n await invokeMutation.mutateAsync({\n workflowType: selected.workflow_type,\n data: data as Record<string, unknown>,\n metadata: resolvedMetadata,\n ...(overrideBot ? { execute_as: overrideBot } : {}),\n });\n navigate(executionsPath);\n } catch { /* error via mutation */ }\n };\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h2 className=\"text-lg font-mono font-medium text-text-primary\">{selected.workflow_type}</h2>\n {selected.description && (\n <p className=\"text-xs text-text-quaternary mt-1 leading-relaxed\">\n {selected.description}\n </p>\n )}\n </div>\n\n <IdentitySummary\n config={selected}\n overrideBot={overrideBot}\n onOverrideChange={setOverrideBot}\n showOverride={isAdmin}\n />\n\n {isCertifiable && (\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={certified}\n onChange={(e) => setCertified(e.target.checked)}\n className=\"rounded border-surface-border text-accent focus:ring-accent/30\"\n />\n <ShieldCheck className=\"w-3.5 h-3.5 text-text-tertiary\" />\n <span className=\"text-xs text-text-secondary\">Enable task tracking and escalation routing</span>\n </label>\n )}\n\n <EnvelopeEditor\n selectedConfig={selected}\n isJsonMode={isJsonMode}\n hasFormView={hasFormView}\n jsonInput={jsonInput}\n formFields={formFields}\n dataFields={dataFields}\n onJsonChange={(v) => { setJsonInput(v); setParseError(''); }}\n onToggleMode={handleToggleMode}\n onUpdateFormField={updateFormField}\n onSetFormFields={setFormFields}\n />\n\n {parseError && <p className=\"text-xs text-status-error\">{parseError}</p>}\n {invokeMutation.error && <p className=\"text-xs text-status-error\">{invokeMutation.error.message}</p>}\n {invokeMutation.isSuccess && <p className=\"text-xs text-status-success\">Workflow started</p>}\n\n <button onClick={handleInvoke} disabled={invokeMutation.isPending} className=\"btn-primary\">\n {invokeMutation.isPending ? 'Starting...' : 'Start Workflow'}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { Play } from 'lucide-react';\nimport { useWorkflowConfigs, useDiscoveredWorkflows, useCronStatus } from '../../../api/workflows';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport type { LTWorkflowConfig, WorkflowTier } from '../../../api/types';\nimport { WorkflowSelector } from './WorkflowSelector';\nimport { StartNowPanel } from './StartNowPanel';\n\nexport function StartWorkflowPage() {\n const [searchParams, setSearchParams] = useSearchParams();\n const { data: configsData, isLoading } = useWorkflowConfigs();\n const { data: discoveredData, isLoading: discoveredLoading } = useDiscoveredWorkflows();\n const { data: cronEntries } = useCronStatus();\n\n const selectedType = searchParams.get('type') ?? '';\n\n const configs: LTWorkflowConfig[] = configsData ?? [];\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 invocableConfigs = useMemo(() => {\n const certified = configs.filter((c) => c.invocable);\n const registeredTypes = new Set(configs.map((c) => c.workflow_type));\n const discovered = discoveredData ?? [];\n const durable = discovered\n .filter((dw) => dw.active && !registeredTypes.has(dw.workflow_type))\n .map((dw) => ({\n workflow_type: dw.workflow_type,\n task_queue: dw.task_queue ?? '',\n invocable: true,\n description: null,\n default_role: 'reviewer',\n roles: [],\n invocation_roles: [],\n consumes: [],\n envelope_schema: null,\n resolver_schema: null,\n cron_schedule: null,\n execute_as: null,\n } satisfies LTWorkflowConfig));\n return [...certified, ...durable];\n }, [configs, discoveredData]);\n\n const selectedConfig = invocableConfigs.find((c) => c.workflow_type === selectedType);\n\n const activeTypes = new Set(\n (cronEntries ?? []).filter((e) => e.active).map((e) => e.workflow_type),\n );\n\n const executionsPath = '/workflows/executions';\n\n // Fade transition when selection changes\n const panelRef = useRef<HTMLDivElement>(null);\n const [panelVisible, setPanelVisible] = useState(true);\n const prevKeyRef = useRef(selectedType);\n useEffect(() => {\n if (prevKeyRef.current !== selectedType) {\n setPanelVisible(false);\n const timer = setTimeout(() => {\n prevKeyRef.current = selectedType;\n setPanelVisible(true);\n }, 120);\n return () => clearTimeout(timer);\n }\n }, [selectedType]);\n\n useEffect(() => {\n if (invocableConfigs.length === 1 && !searchParams.get('type')) {\n setSearchParams({ type: invocableConfigs[0].workflow_type }, { replace: true });\n }\n }, [invocableConfigs.length]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleSelect = (config: LTWorkflowConfig) => {\n setSearchParams({ type: config.workflow_type }, { replace: true });\n };\n\n if (isLoading || discoveredLoading) {\n return (\n <div className=\"animate-pulse space-y-4\">\n <div className=\"h-8 bg-surface-sunken rounded w-48\" />\n <div className=\"h-40 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n return (\n <div>\n <PageHeader title=\"Invoke\" docsHash=\"#docs:dashboard.md:invoke-workflow\" />\n\n {invocableConfigs.length === 0 ? (\n <div className=\"py-16 text-center\">\n <p className=\"text-sm text-text-primary mb-1\">No invocable workflows</p>\n <p className=\"text-xs text-text-tertiary\">Mark workflows as invocable in the registry, or start the server with examples enabled.</p>\n </div>\n ) : (\n <div className=\"grid grid-cols-3 gap-8 items-start\">\n\n {/* ── Left: workflow list (2 cols) ── */}\n <div className=\"col-span-2\">\n <WorkflowSelector\n configs={invocableConfigs}\n selectedType={selectedType}\n onSelect={handleSelect}\n tierMap={tierMap}\n activeTypes={activeTypes}\n />\n </div>\n\n {/* ── Right: invoke form (1 col, sticky) ── */}\n <div\n ref={panelRef}\n className={`sticky top-4 transition-all duration-200 ease-out ${\n panelVisible ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-1'\n }`}\n >\n {selectedType && selectedConfig ? (\n <StartNowPanel selected={selectedConfig} executionsPath={executionsPath} />\n ) : (\n <div className=\"flex flex-col items-center justify-center py-24 text-center\">\n <div className=\"w-12 h-12 rounded-full bg-accent/[0.06] flex items-center justify-center mb-4\">\n <Play className=\"w-5 h-5 text-accent/50\" />\n </div>\n <p className=\"text-sm text-text-secondary mb-1\">Select a workflow</p>\n <p className=\"text-xs text-text-quaternary\">Choose one from the list to configure and invoke it.</p>\n </div>\n )}\n </div>\n\n </div>\n )}\n </div>\n );\n}\n","import { StartWorkflowPage } from './StartWorkflowPage';\n\nexport function DurableInvokePage() {\n return <StartWorkflowPage />;\n}\n"],"names":["WorkflowSelector","configs","selectedType","onSelect","tierMap","activeTypes","search","setSearch","useState","filtered","useMemo","q","c","_a","jsxs","jsx","Search","e","config","isSelected","tier","variant","WorkflowPill","Bot","Clock","NamespacePill","DEFAULT_ENVELOPE","inferTypeFromValue","value","extractDataFields","schema","data","key","dataToFields","fieldsToJson","fields","metadata","IdentitySummary","overrideBot","onOverrideChange","showOverride","user","useAuth","effectiveBot","Fragment","UserCircle","BotPicker","EnvelopeEditor","selectedConfig","isJsonMode","hasFormView","jsonInput","formFields","dataFields","onJsonChange","onToggleMode","onUpdateFormField","onSetFormFields","Link","type","jsonValue","textareaRows","_b","StartNowPanel","selected","executionsPath","navigate","useNavigate","isSuperAdmin","hasRoleType","isAdmin","invokeMutation","useInvokeWorkflow","setJsonInput","parseError","setParseError","setFormFields","setIsJsonMode","setOverrideBot","isCertifiable","certified","setCertified","schemaMetadata","md","useEffect","prefill","parsed","json","handleToggleMode","updateFormField","updated","handleInvoke","envelope","resolvedMetadata","ShieldCheck","v","StartWorkflowPage","searchParams","setSearchParams","useSearchParams","configsData","isLoading","useWorkflowConfigs","discoveredData","discoveredLoading","useDiscoveredWorkflows","cronEntries","useCronStatus","map","dw","invocableConfigs","registeredTypes","durable","panelRef","useRef","panelVisible","setPanelVisible","prevKeyRef","timer","handleSelect","PageHeader","Play","DurableInvokePage"],"mappings":"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"}
|