@hotmeshio/long-tail 0.25.0 → 0.25.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/batch-flag.d.ts +19 -0
- package/build/api/escalations/batch-flag.js +138 -0
- package/build/api/escalations/index.d.ts +2 -0
- package/build/api/escalations/index.js +8 -1
- package/build/api/escalations/roster-action.d.ts +37 -0
- package/build/api/escalations/roster-action.js +179 -0
- package/build/api/scan-codes/choice-roles.d.ts +3 -0
- package/build/api/scan-codes/choice-roles.js +48 -0
- package/build/api/scan-codes/choice.js +8 -0
- package/build/api/scan-codes/fill-labels.d.ts +15 -0
- package/build/api/scan-codes/fill-labels.js +99 -0
- package/build/api/scan-codes/hold.js +1 -0
- package/build/api/scan-codes/present.js +7 -2
- package/build/api/scan-codes/verb-fill.js +22 -5
- package/build/routes/escalations/resolve.js +45 -0
- package/build/sdk/index.d.ts +11 -0
- package/build/sdk/index.js +3 -0
- package/build/services/domain/seed.d.ts +12 -10
- package/build/services/domain/seed.js +31 -25
- package/build/services/escalation/batch-flag.d.ts +25 -0
- package/build/services/escalation/batch-flag.js +51 -0
- package/build/services/escalation/index.d.ts +1 -0
- package/build/services/escalation/index.js +1 -0
- package/build/services/escalation/roster.d.ts +3 -1
- package/build/services/escalation/roster.js +6 -1
- package/build/services/scan-code/validate-subject.js +16 -0
- package/build/services/scan-code/validate.js +7 -0
- package/build/shared/form-validation/index.d.ts +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/x-lt-actions.d.ts +80 -0
- package/build/shared/form-validation/x-lt-actions.js +133 -0
- package/build/shared/form-validation/x-lt-roster.d.ts +2 -0
- package/build/shared/form-validation/x-lt-roster.js +50 -6
- package/build/start/workers.d.ts +3 -0
- package/build/start/workers.js +15 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/escalation.d.ts +19 -0
- package/build/types/escalation.js +4 -0
- package/build/types/index.d.ts +1 -1
- package/build/types/scan-choice.d.ts +9 -0
- package/build/types/scan-code/response.d.ts +2 -0
- package/build/types/scan-code/rule.d.ts +17 -0
- package/build/types/startup.d.ts +8 -1
- package/dashboard/dist/assets/{AdminDashboard-DWVRAu63.js → AdminDashboard-B8MqNLiB.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-DWVRAu63.js.map → AdminDashboard-B8MqNLiB.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-Exjtjbvp.js → AgentConfigPage-Yg81Eiuo.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-Exjtjbvp.js.map → AgentConfigPage-Yg81Eiuo.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-nDbZo6RB.js → AgentDetailPage-ZUGYEONO.js} +3 -3
- package/dashboard/dist/assets/{AgentDetailPage-nDbZo6RB.js.map → AgentDetailPage-ZUGYEONO.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-Dsk9iHps.js → AgentsPage-CZIWMwak.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-Dsk9iHps.js.map → AgentsPage-CZIWMwak.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-BVtpc4xO.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-D1mCqj8Z.js.map → AvailableEscalationsPage-BVtpc4xO.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-u5760MWZ.js → BotPicker-8bf0yOCT.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-u5760MWZ.js.map → BotPicker-8bf0yOCT.js.map} +1 -1
- package/dashboard/dist/assets/{BulkAssignModal-CtISXXmW.js → BulkAssignModal-B2lr1J6P.js} +2 -2
- package/dashboard/dist/assets/{BulkAssignModal-CtISXXmW.js.map → BulkAssignModal-B2lr1J6P.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-BKIlrQfU.js → CapabilitiesPage-BQQBR2sj.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-BKIlrQfU.js.map → CapabilitiesPage-BQQBR2sj.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DlBVTFqc.js → CollapsibleSection-DFW8TYyU.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DlBVTFqc.js.map → CollapsibleSection-DFW8TYyU.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-Pabkchg_.js → ConfirmDeleteModal-DGlOlQAo.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-Pabkchg_.js.map → ConfirmDeleteModal-DGlOlQAo.js.map} +1 -1
- package/dashboard/dist/assets/{ConnectedAppsPage-DG2YZGN3.js → ConnectedAppsPage-CIM9gzHj.js} +2 -2
- package/dashboard/dist/assets/{ConnectedAppsPage-DG2YZGN3.js.map → ConnectedAppsPage-CIM9gzHj.js.map} +1 -1
- package/dashboard/dist/assets/{CountdownTimer-5t8S2qMi.js → CountdownTimer-BD_iWm6S.js} +2 -2
- package/dashboard/dist/assets/{CountdownTimer-5t8S2qMi.js.map → CountdownTimer-BD_iWm6S.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-CPVbYQow.js → CredentialsPage-CTtUkvoD.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-CPVbYQow.js.map → CredentialsPage-CTtUkvoD.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-C7UbTrO-.js → CronLabel-rZMptkYQ.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-C7UbTrO-.js.map → CronLabel-rZMptkYQ.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-DCZpORx-.js → DropZone-u1JGfR9G.js} +2 -2
- package/dashboard/dist/assets/{DropZone-DCZpORx-.js.map → DropZone-u1JGfR9G.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-Yz7-LbtE.js → ElapsedCell-CmK9gHC5.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-Yz7-LbtE.js.map → ElapsedCell-CmK9gHC5.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel-xgPRdKEq.js → EntityTimelinePanel-Cfg0EMZs.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel-xgPRdKEq.js.map → EntityTimelinePanel-Cfg0EMZs.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CqCd-y6B.js → EscalationListSchemaPage-CPcbC1-9.js} +3 -3
- package/dashboard/dist/assets/{EscalationListSchemaPage-CqCd-y6B.js.map → EscalationListSchemaPage-CPcbC1-9.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-D8YVQNph.js → EscalationSchemaPage-BsYdNVN7.js} +3 -3
- package/dashboard/dist/assets/{EscalationSchemaPage-D8YVQNph.js.map → EscalationSchemaPage-BsYdNVN7.js.map} +1 -1
- package/dashboard/dist/assets/EscalationTimeline-D1enxZDs.js +2 -0
- package/dashboard/dist/assets/{EscalationTimeline-D6jrDcBb.js.map → EscalationTimeline-D1enxZDs.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationTitleSelect-CGGT-QTu.js → EscalationTitleSelect-DwqhnPKX.js} +2 -2
- package/dashboard/dist/assets/{EscalationTitleSelect-CGGT-QTu.js.map → EscalationTitleSelect-DwqhnPKX.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-B7O4ttP4.js → EscalationsOverview-ChuKh02E.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-B7O4ttP4.js.map → EscalationsOverview-ChuKh02E.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DJniXnhe.js → EventTable-GqZIKPce.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DJniXnhe.js.map → EventTable-GqZIKPce.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-f-LEKcHI.js → FilterBar-CqPFZkVU.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-f-LEKcHI.js.map → FilterBar-CqPFZkVU.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-CR0MtYv8.js → GraphInvokePage-_fB7mtBU.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-CR0MtYv8.js.map → GraphInvokePage-_fB7mtBU.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-HVw7T5ER.js → HomePage-BXA0Cz0F.js} +2 -2
- package/dashboard/dist/assets/{HomePage-HVw7T5ER.js.map → HomePage-BXA0Cz0F.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-CTGK5BXW.js → ListToolbar-Bf4DFITI.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-CTGK5BXW.js.map → ListToolbar-Bf4DFITI.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-B2bbKKu2.js → McpOverview-H61XQRji.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-B2bbKKu2.js.map → McpOverview-H61XQRji.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DgLxwwJy.js → McpQueryDetailPage-wbwK8WWq.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DgLxwwJy.js.map → McpQueryDetailPage-wbwK8WWq.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-CSkczeJP.js → McpQueryPage-CYvVEk3G.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-CSkczeJP.js.map → McpQueryPage-CYvVEk3G.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CrUsDPRD.js → McpRunDetailPage-TZBX68i4.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CrUsDPRD.js.map → McpRunDetailPage-TZBX68i4.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-twxFdTtJ.js → McpRunsPage-Cu91Mh52.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-twxFdTtJ.js.map → McpRunsPage-Cu91Mh52.js.map} +1 -1
- package/dashboard/dist/assets/{NamespacePill-CSZT2fA4.js → NamespacePill-C5epAgq6.js} +2 -2
- package/dashboard/dist/assets/{NamespacePill-CSZT2fA4.js.map → NamespacePill-C5epAgq6.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-gOVMrL_a.js → OperationsPage-D-6sKw6y.js} +3 -3
- package/dashboard/dist/assets/{OperationsPage-gOVMrL_a.js.map → OperationsPage-D-6sKw6y.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-DD8JUU3L.js +2 -0
- package/dashboard/dist/assets/{OperatorDashboard-BoeZIyup.js.map → OperatorDashboard-DD8JUU3L.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeader-C4z1ExF7.js → PageHeader-BSWIspNB.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-C4z1ExF7.js.map → PageHeader-BSWIspNB.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-B_f_Sz_Q.js → PageHeaderWithStats-DDjopQ-k.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-B_f_Sz_Q.js.map → PageHeaderWithStats-DDjopQ-k.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-CDktk1mi.js → PersonaDetailPage-CGri6okV.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-CDktk1mi.js.map → PersonaDetailPage-CGri6okV.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-Bs097x07.js → PersonasPage-DtHW6-Qx.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-Bs097x07.js.map → PersonasPage-DtHW6-Qx.js.map} +1 -1
- package/dashboard/dist/assets/PortalPage-Dgbk_mzr.js +2 -0
- package/dashboard/dist/assets/{PortalPage-DjfjerpF.js.map → PortalPage-Dgbk_mzr.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-B30RatjD.js → ProcessDetailPage-BdkacBrD.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-B30RatjD.js.map → ProcessDetailPage-BdkacBrD.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-DrvjzgWT.js → ProcessesListPage-DO5A-OfZ.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-DrvjzgWT.js.map → ProcessesListPage-DO5A-OfZ.js.map} +1 -1
- package/dashboard/dist/assets/ResolverForm-CqGE5lf-.js +8 -0
- package/dashboard/dist/assets/ResolverForm-CqGE5lf-.js.map +1 -0
- package/dashboard/dist/assets/{RoleDetailPage-ClYgn-3d.js → RoleDetailPage-DgVp0Hih.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-ClYgn-3d.js.map → RoleDetailPage-DgVp0Hih.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-Bw_n7EpR.js → RolePill-CoETDpjF.js} +2 -2
- package/dashboard/dist/assets/{RolePill-Bw_n7EpR.js.map → RolePill-CoETDpjF.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-B_3qWsvQ.js → RolesPage-BmsWq83e.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-B_3qWsvQ.js.map → RolesPage-BmsWq83e.js.map} +1 -1
- package/dashboard/dist/assets/RosterWidget-DR-T4Izu.js +2 -0
- package/dashboard/dist/assets/RosterWidget-DR-T4Izu.js.map +1 -0
- package/dashboard/dist/assets/{RunAsSelector-CbJT50Hp.js → RunAsSelector-CyUWGp5P.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-CbJT50Hp.js.map → RunAsSelector-CyUWGp5P.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-CIIDuh8w.js → ScanCodesPage-Cy05JOt4.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-CIIDuh8w.js.map → ScanCodesPage-Cy05JOt4.js.map} +1 -1
- package/dashboard/dist/assets/{ScanSchemeDetailPage-Bd3P3eyh.js → ScanSchemeDetailPage-BX1afzOg.js} +2 -2
- package/dashboard/dist/assets/{ScanSchemeDetailPage-Bd3P3eyh.js.map → ScanSchemeDetailPage-BX1afzOg.js.map} +1 -1
- package/dashboard/dist/assets/ScanStationPage-DLAB41tb.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-DLAB41tb.js.map +1 -0
- package/dashboard/dist/assets/{ScopeBadge-CKgfwTy3.js → ScopeBadge-CGsTtqFr.js} +2 -2
- package/dashboard/dist/assets/{ScopeBadge-CKgfwTy3.js.map → ScopeBadge-CGsTtqFr.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-BNOuYZ1m.js → StickyPagination-BzUTnYYE.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-BNOuYZ1m.js.map → StickyPagination-BzUTnYYE.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-ALVUnfF1.js → StreamMessageDetail-D0W1ekgG.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-ALVUnfF1.js.map → StreamMessageDetail-D0W1ekgG.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-B5b8-xqI.js → SwimlaneTimeline-BPBwmwuO.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-B5b8-xqI.js.map → SwimlaneTimeline-BPBwmwuO.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-B6fMAqxd.js → TagInput-S7UuVT_M.js} +2 -2
- package/dashboard/dist/assets/{TagInput-B6fMAqxd.js.map → TagInput-S7UuVT_M.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-CoV3WcTA.js → TaskDetailPage-VuaIXISy.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-CoV3WcTA.js.map → TaskDetailPage-VuaIXISy.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-BnDp_DE6.js → TaskQueuePill-BlHNpYiZ.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-BnDp_DE6.js.map → TaskQueuePill-BlHNpYiZ.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CkMmOYOE.js → TasksListPage-KaUSoqos.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CkMmOYOE.js.map → TasksListPage-KaUSoqos.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-DVkFgECX.js → TimeAgo-C_E6u0fr.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-DVkFgECX.js.map → TimeAgo-C_E6u0fr.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-CfTc6Txy.js → TimestampCell-CUJiAmax.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-CfTc6Txy.js.map → TimestampCell-CUJiAmax.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-BRZWo4l8.js → ToolPill-D40uLM_v.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-BRZWo4l8.js.map → ToolPill-D40uLM_v.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-kvqZqM0A.js → ToolTestPanel-Ch5nQANh.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-kvqZqM0A.js.map → ToolTestPanel-Ch5nQANh.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-CjkAAyy8.js → TopicDetailPage-BprToO7w.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-CjkAAyy8.js.map → TopicDetailPage-BprToO7w.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-CJZnv50y.js → TopicsPage-8SmCnQ-E.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-CJZnv50y.js.map → TopicsPage-8SmCnQ-E.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CPJPZnN1.js → UserName-BkJryunF.js} +2 -2
- package/dashboard/dist/assets/{UserName-CPJPZnN1.js.map → UserName-BkJryunF.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-46UV5pJd.js → WorkflowExecutionPage-B2S5ODie.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-46UV5pJd.js.map → WorkflowExecutionPage-B2S5ODie.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-Cly9Ln_3.js → WorkflowPill-DJLcK_CM.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-Cly9Ln_3.js.map → WorkflowPill-DJLcK_CM.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DtxYdQbQ.js → WorkflowsDashboard-CABuRCXp.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DtxYdQbQ.js.map → WorkflowsDashboard-CABuRCXp.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-Cg4LSfck.js → WorkflowsOverview-BPUHAj8T.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-Cg4LSfck.js.map → WorkflowsOverview-BPUHAj8T.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Del-RCgi.js → YamlWorkflowDetailPage-DZGjT-Tl.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-Del-RCgi.js.map → YamlWorkflowDetailPage-DZGjT-Tl.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BF6Jtx24.js → YamlWorkflowsPage-DIxHURlM.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BF6Jtx24.js.map → YamlWorkflowsPage-DIxHURlM.js.map} +1 -1
- package/dashboard/dist/assets/{agents-wL-3dMOX.js → agents-BnDp2rcb.js} +2 -2
- package/dashboard/dist/assets/{agents-wL-3dMOX.js.map → agents-BnDp2rcb.js.map} +1 -1
- package/dashboard/dist/assets/{bots-D72EsztP.js → bots-maURYoyr.js} +2 -2
- package/dashboard/dist/assets/{bots-D72EsztP.js.map → bots-maURYoyr.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DXFo6bRb.js → capabilities-5-TakMUh.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DXFo6bRb.js.map → capabilities-5-TakMUh.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-gQdOgVtH.js → controlplane-BXVVTWoh.js} +2 -2
- package/dashboard/dist/assets/{controlplane-gQdOgVtH.js.map → controlplane-BXVVTWoh.js.map} +1 -1
- package/dashboard/dist/assets/escalation-columns-v8gx8wFb.js +2 -0
- package/dashboard/dist/assets/{escalation-columns-CSE5wfWQ.js.map → escalation-columns-v8gx8wFb.js.map} +1 -1
- package/dashboard/dist/assets/escalation-items-OWntjDaH.js +2 -0
- package/dashboard/dist/assets/escalation-items-OWntjDaH.js.map +1 -0
- package/dashboard/dist/assets/{index-Btm8FtTQ.js → index-BIfY4mR2.js} +2 -2
- package/dashboard/dist/assets/{index-Btm8FtTQ.js.map → index-BIfY4mR2.js.map} +1 -1
- package/dashboard/dist/assets/{index-h1Useskt.js → index-BTm3-qwq.js} +2 -2
- package/dashboard/dist/assets/{index-h1Useskt.js.map → index-BTm3-qwq.js.map} +1 -1
- package/dashboard/dist/assets/{index-Cu0xdX2t.js → index-CR9rhAvN.js} +2 -2
- package/dashboard/dist/assets/{index-Cu0xdX2t.js.map → index-CR9rhAvN.js.map} +1 -1
- package/dashboard/dist/assets/index-CWKs10VQ.js +13 -0
- package/dashboard/dist/assets/{index-D1lfq5iZ.js.map → index-CWKs10VQ.js.map} +1 -1
- package/dashboard/dist/assets/index-CvKegIVe.js +3 -0
- package/dashboard/dist/assets/index-CvKegIVe.js.map +1 -0
- package/dashboard/dist/assets/{index-BaCDL5fh.js → index-D7peGNN0.js} +27 -27
- package/dashboard/dist/assets/index-D7peGNN0.js.map +1 -0
- package/dashboard/dist/assets/{index-CptTEhWp.js → index-D_ojXTgO.js} +2 -2
- package/dashboard/dist/assets/{index-CptTEhWp.js.map → index-D_ojXTgO.js.map} +1 -1
- package/dashboard/dist/assets/index-Dafrbwk_.js +2 -0
- package/dashboard/dist/assets/{index-BvH8T-jb.js.map → index-Dafrbwk_.js.map} +1 -1
- package/dashboard/dist/assets/{index-czgLyfSo.js → index-Dk7nwVpm.js} +2 -2
- package/dashboard/dist/assets/{index-czgLyfSo.js.map → index-Dk7nwVpm.js.map} +1 -1
- package/dashboard/dist/assets/{index-CDxOQ84B.js → index-DvkcyTE2.js} +2 -2
- package/dashboard/dist/assets/{index-CDxOQ84B.js.map → index-DvkcyTE2.js.map} +1 -1
- package/dashboard/dist/assets/{index-C1iuZ4Q5.js → index-WPVpyoD3.js} +2 -2
- package/dashboard/dist/assets/{index-C1iuZ4Q5.js.map → index-WPVpyoD3.js.map} +1 -1
- package/dashboard/dist/assets/{index-C-QQ5rKF.js → index-YGTGxcTF.js} +2 -2
- package/dashboard/dist/assets/{index-C-QQ5rKF.js.map → index-YGTGxcTF.js.map} +1 -1
- package/dashboard/dist/assets/{index-ujGmmwl6.js → index-vgHzaGmW.js} +2 -2
- package/dashboard/dist/assets/{index-ujGmmwl6.js.map → index-vgHzaGmW.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-150lsM68.js → knowledge-L_zY1zmy.js} +2 -2
- package/dashboard/dist/assets/{knowledge-150lsM68.js.map → knowledge-L_zY1zmy.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-CDsSMaYq.js → mcp-query-CFbGudkb.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-CDsSMaYq.js.map → mcp-query-CFbGudkb.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CRtY4v5W.js → mcp-wCWFRA0T.js} +2 -2
- package/dashboard/dist/assets/{mcp-CRtY4v5W.js.map → mcp-wCWFRA0T.js.map} +1 -1
- package/dashboard/dist/assets/{personas-C2Wm4ng1.js → personas-B_VIacZJ.js} +2 -2
- package/dashboard/dist/assets/{personas-C2Wm4ng1.js.map → personas-B_VIacZJ.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-BH0F9-jf.js → pipelines-Bv0Z8xQA.js} +2 -2
- package/dashboard/dist/assets/{pipelines-BH0F9-jf.js.map → pipelines-Bv0Z8xQA.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BkUVpaOa.js → tasks-DP6yaNZs.js} +2 -2
- package/dashboard/dist/assets/{tasks-BkUVpaOa.js.map → tasks-DP6yaNZs.js.map} +1 -1
- package/dashboard/dist/assets/{topics-Crl8HKHq.js → topics-UBSIcpSR.js} +2 -2
- package/dashboard/dist/assets/{topics-Crl8HKHq.js.map → topics-UBSIcpSR.js.map} +1 -1
- package/dashboard/dist/assets/{useDebouncedValue-Dk3r5xo-.js → useDebouncedValue-R62q3Xpx.js} +2 -2
- package/dashboard/dist/assets/{useDebouncedValue-Dk3r5xo-.js.map → useDebouncedValue-R62q3Xpx.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-BXuyHKAs.js → useNamespace-CAaszJDE.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-BXuyHKAs.js.map → useNamespace-CAaszJDE.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DSlkjQfb.js → useYamlActivityEvents-emCp9U69.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DSlkjQfb.js.map → useYamlActivityEvents-emCp9U69.js.map} +1 -1
- package/dashboard/dist/assets/validate-C7yskdEn.js +2 -0
- package/dashboard/dist/assets/validate-C7yskdEn.js.map +1 -0
- package/dashboard/dist/assets/{vendor-icons-C_DQEeBy.js → vendor-icons-DUYcKTjP.js} +2 -2
- package/dashboard/dist/assets/{vendor-icons-C_DQEeBy.js.map → vendor-icons-DUYcKTjP.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-B230v5Za.js → yaml-workflows-C2sOwz1p.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-B230v5Za.js.map → yaml-workflows-C2sOwz1p.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/accumulator.md +1 -1
- package/docs/api/http/escalations.md +33 -0
- package/docs/api/sdk/escalations.md +26 -1
- package/docs/code-owned-configuration.md +2 -2
- package/docs/domain-dictionary.md +19 -3
- package/docs/faceted-routing.md +4 -3
- package/docs/hitl/escalation.md +9 -0
- package/docs/hitl/x-lt-display.md +1 -1
- package/docs/hitl/x-lt-embed.md +2 -0
- package/docs/hitl/x-lt-roster.md +32 -8
- package/docs/scan-codes.md +45 -3
- package/package.json +2 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-D1mCqj8Z.js +0 -2
- package/dashboard/dist/assets/EscalationTimeline-D6jrDcBb.js +0 -2
- package/dashboard/dist/assets/FormattedValue-CUtv1g3k.js +0 -2
- package/dashboard/dist/assets/FormattedValue-CUtv1g3k.js.map +0 -1
- package/dashboard/dist/assets/OperatorDashboard-BoeZIyup.js +0 -2
- package/dashboard/dist/assets/PortalPage-DjfjerpF.js +0 -2
- package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js +0 -8
- package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js.map +0 -1
- package/dashboard/dist/assets/ScanStationPage-BiO34nov.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-BiO34nov.js.map +0 -1
- package/dashboard/dist/assets/escalation-columns-CSE5wfWQ.js +0 -2
- package/dashboard/dist/assets/escalation-items-BIgBWbaw.js +0 -2
- package/dashboard/dist/assets/escalation-items-BIgBWbaw.js.map +0 -1
- package/dashboard/dist/assets/index-BaCDL5fh.js.map +0 -1
- package/dashboard/dist/assets/index-BvH8T-jb.js +0 -2
- package/dashboard/dist/assets/index-CED9cLE2.js +0 -3
- package/dashboard/dist/assets/index-CED9cLE2.js.map +0 -1
- package/dashboard/dist/assets/index-D1lfq5iZ.js +0 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-h1Useskt.js","sources":["../../src/hooks/useExpandedRows.ts","../../src/pages/mcp/servers/helpers.ts","../../src/pages/mcp/servers/ServerRow.tsx","../../src/pages/mcp/servers/McpServersPage.tsx"],"sourcesContent":["import { useState, useCallback } from 'react';\n\n/**\n * Track expanded row IDs with localStorage persistence.\n *\n * Resilient: if a stored ID no longer exists in the data, it's silently ignored.\n * Never blocks rendering — reads from localStorage synchronously on mount,\n * writes asynchronously on change.\n */\nexport function useExpandedRows(storageKey: string): {\n expandedIds: Set<string>;\n toggle: (id: string) => void;\n isExpanded: (id: string) => boolean;\n} {\n const [expandedIds, setExpandedIds] = useState<Set<string>>(() => {\n try {\n const raw = localStorage.getItem(storageKey);\n if (raw) {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return new Set(parsed);\n }\n } catch { /* corrupted or unavailable — start empty */ }\n return new Set();\n });\n\n const persist = useCallback((next: Set<string>) => {\n try {\n localStorage.setItem(storageKey, JSON.stringify([...next]));\n } catch { /* quota exceeded or unavailable — ignore */ }\n }, [storageKey]);\n\n const toggle = useCallback((id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n persist(next);\n return next;\n });\n }, [persist]);\n\n const isExpanded = useCallback((id: string) => expandedIds.has(id), [expandedIds]);\n\n return { expandedIds, toggle, isExpanded };\n}\n","import type { McpServerRecord, McpToolManifest } from '../../../api/types';\n\nexport function isBuiltIn(row: McpServerRecord): boolean {\n return !!(row.metadata as Record<string, unknown> | null)?.builtin\n || !!(row.transport_config as Record<string, unknown> | null)?.builtin;\n}\n\n/** Check if a server or any of its tools match the search term */\nexport function matchesSearch(server: McpServerRecord, search: string): boolean {\n if (!search) return true;\n const q = search.toLowerCase();\n if (server.name.toLowerCase().includes(q)) return true;\n if (server.description?.toLowerCase().includes(q)) return true;\n if ((server.tags ?? []).some((t) => t.toLowerCase().includes(q))) return true;\n const tools = (server.tool_manifest ?? []) as McpToolManifest[];\n return tools.some(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n}\n\n/** Filter tools within a server that match the search term */\nexport function filterTools(tools: McpToolManifest[], search: string): McpToolManifest[] {\n if (!search) return tools;\n const q = search.toLowerCase();\n return tools.filter(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n}\n","import { ChevronRight, Pencil, Trash2, Plug, Unplug, Play } from 'lucide-react';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport {\n useConnectMcpServer,\n useDisconnectMcpServer,\n} from '../../../api/mcp';\nimport { StatusBadge } from '../../../components/common/display/StatusBadge';\nimport { ToolPill } from '../../../components/common/display/ToolPill';\nimport { ServerName } from '../../../components/common/display/ServerName';\n\nimport type { McpServerRecord, McpToolManifest } from '../../../api/types';\nimport { isBuiltIn } from './helpers';\n\nexport function ServerRow({\n server,\n expanded,\n onToggle,\n onEdit,\n onDelete,\n onTryTool,\n connect,\n disconnect,\n visibleTools,\n}: {\n server: McpServerRecord;\n expanded: boolean;\n onToggle: () => void;\n onEdit: () => void;\n onDelete: () => void;\n onTryTool: (tool: McpToolManifest) => void;\n connect: ReturnType<typeof useConnectMcpServer>;\n disconnect: ReturnType<typeof useDisconnectMcpServer>;\n visibleTools: McpToolManifest[];\n}) {\n const allTools = (server.tool_manifest ?? []) as McpToolManifest[];\n const builtin = isBuiltIn(server);\n const tags = server.tags ?? [];\n\n return (\n <>\n {/* Server header row */}\n <tr\n onClick={allTools.length > 0 ? onToggle : undefined}\n className={`group/row border-b border-surface-border/50 transition-colors duration-100 ${\n allTools.length > 0 ? 'cursor-pointer row-hover' : ''\n }`}\n >\n {/* Name + tags */}\n <td className=\"px-6 py-2.5\">\n <div className=\"flex items-center gap-3\">\n <span className={`transition-transform duration-150 ${expanded ? 'rotate-90' : ''} ${allTools.length === 0 ? 'opacity-0' : 'text-text-tertiary'}`}>\n <ChevronRight size={14} />\n </span>\n <span className=\"flex items-center gap-1.5\">\n <ServerName name={server.name} serverId={server.id} short={false} />\n {allTools.length > 0 && (\n <sup className=\"text-2xs font-normal text-accent/70\">{allTools.length}</sup>\n )}\n </span>\n {tags.length > 0 && (\n <div className=\"flex gap-1 ml-auto shrink-0\">\n {tags.slice(0, 3).map((tag) => (\n <span key={tag} className=\"inline-block px-1.5 py-0 text-2xs text-text-tertiary bg-surface-sunken rounded\">\n {tag}\n </span>\n ))}\n {tags.length > 3 && (\n <span className=\"text-2xs text-text-quaternary\" title={tags.slice(3).join(', ')}>…</span>\n )}\n </div>\n )}\n </div>\n </td>\n\n {/* Status */}\n <td className=\"px-4 py-2.5 w-28 whitespace-nowrap\">\n <StatusBadge status={server.status} />\n </td>\n\n {/* Actions */}\n <td className=\"px-4 py-2.5 w-16\">\n <RowActionGroup>\n {!builtin && (\n server.status === 'connected' ? (\n <RowAction\n icon={Unplug}\n title=\"Disconnect server\"\n onClick={() => disconnect.mutate(server.id)}\n />\n ) : (\n <RowAction\n icon={Plug}\n title=\"Connect server\"\n onClick={() => connect.mutate(server.id)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )\n )}\n <RowAction\n icon={Pencil}\n title=\"Edit server\"\n onClick={onEdit}\n />\n {!builtin && (\n <RowAction\n icon={Trash2}\n title=\"Delete server\"\n onClick={onDelete}\n colorClass=\"text-text-tertiary hover:text-status-error\"\n />\n )}\n </RowActionGroup>\n </td>\n </tr>\n\n {/* Expanded tool rows — real table rows for column alignment */}\n {expanded && visibleTools.map((tool) => (\n <tr\n key={tool.name}\n onClick={() => onTryTool(tool)}\n className=\"group/row cursor-pointer hover:bg-surface-hover/50 transition-colors border-b border-surface-border/15\"\n >\n {/* Tool name + description */}\n <td className=\"pl-14 pr-6 py-2.5\">\n <ToolPill name={tool.name} size=\"md\" />\n {tool.description && (\n <p className=\"text-2xs leading-snug text-text-quaternary mt-0.5\">{tool.description}</p>\n )}\n </td>\n\n {/* Status — empty for tools */}\n <td className=\"px-4 py-2.5 w-28\" />\n\n {/* Actions — play on hover */}\n <td className=\"px-4 py-2.5 w-16\">\n <div className=\"flex items-center justify-end\">\n <button\n onClick={(e) => { e.stopPropagation(); onTryTool(tool); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity text-text-tertiary hover:text-accent\"\n title=\"Try tool\"\n >\n <Play className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </div>\n </td>\n </tr>\n ))}\n </>\n );\n}\n","import { useState, useMemo, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useMcpServers,\n useConnectMcpServer,\n useDisconnectMcpServer,\n useDeleteMcpServer,\n} from '../../../api/mcp';\nimport { EmptyState } from '../../../components/common/display/EmptyState';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport type { McpServerRecord, McpToolManifest } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../../components/common/data/StickyPagination';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useExpandedRows } from '../../../hooks/useExpandedRows';\nimport { ToolTestPanel } from '../../../components/common/test/ToolTestPanel';\nimport { matchesSearch, filterTools } from './helpers';\nimport { ServerRow } from './ServerRow';\n\nexport function McpServersPage() {\n const navigate = useNavigate();\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { status: '', search: '', tag: '' },\n });\n\n const { data, isLoading } = useMcpServers({\n status: filters.status || undefined,\n search: filters.search || undefined,\n tags: filters.tag || undefined,\n });\n const connect = useConnectMcpServer();\n const disconnect = useDisconnectMcpServer();\n const deleteServer = useDeleteMcpServer();\n\n const [confirmDelete, setConfirmDelete] = useState<McpServerRecord | null>(null);\n const { expandedIds, toggle: toggleExpand } = useExpandedRows('lt:expanded:mcp-servers');\n const [tryTool, setTryTool] = useState<{\n serverId: string;\n serverName: string;\n tool: McpToolManifest;\n } | null>(null);\n\n const servers = data?.servers ?? [];\n const total = data?.total ?? 0;\n\n // Derive unique tags from current result set for the filter dropdown\n const tagOptions = useMemo(() => {\n const allTags = new Set<string>();\n for (const s of servers) {\n for (const t of s.tags ?? []) allTags.add(t);\n }\n return [...allTags].sort().map((t) => ({ value: t, label: t }));\n }, [servers]);\n\n // Client-side search filtering for tool-level matches within expanded rows\n const filteredServers = useMemo(() => {\n if (!filters.search) return servers;\n return servers.filter((s) => matchesSearch(s, filters.search));\n }, [servers, filters.search]);\n\n // Auto-expand servers whose tools match the search (so results are visible)\n useEffect(() => {\n if (!filters.search) return;\n const q = filters.search.toLowerCase();\n for (const s of filteredServers) {\n const tools = (s.tool_manifest ?? []) as McpToolManifest[];\n const hasToolMatch = tools.some(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n if (hasToolMatch && !expandedIds.has(s.id)) {\n toggleExpand(s.id);\n }\n }\n }, [filters.search, filteredServers]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteServer.mutate(confirmDelete.id, {\n onSuccess: () => setConfirmDelete(null),\n });\n };\n\n if (isLoading) {\n return (\n <div>\n <PageHeader title=\"Servers & Tools\" />\n <div className=\"animate-pulse space-y-0\">\n {Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"h-14 border-b last:border-b-0 px-6 flex items-center\">\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <PageHeader\n title=\"Servers & Tools\"\n docsHash=\"#docs:dashboard.md:mcp-server-tools\"\n actions={\n <button\n onClick={() => navigate('/mcp/servers/new')}\n className=\"btn-primary text-xs\"\n >\n Register Server\n </button>\n }\n />\n\n <p className=\"text-sm text-text-secondary mb-6 max-w-2xl leading-relaxed\">\n Registered MCP servers and their available tools. Each server exposes tools that can be used by the MCP Tool Designer.\n </p>\n\n <FilterBar>\n <FilterInput\n label=\"Search\"\n value={filters.search}\n onChange={(v) => setFilter('search', v)}\n placeholder=\"Server or tool name...\"\n />\n <FilterSelect\n label=\"Tag\"\n value={filters.tag}\n onChange={(v) => setFilter('tag', v)}\n options={tagOptions}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'registered', label: 'Registered' },\n { value: 'connected', label: 'Connected' },\n { value: 'error', label: 'Error' },\n { value: 'disconnected', label: 'Disconnected' },\n ]}\n />\n </FilterBar>\n\n <div className={`flex gap-0 ${tryTool ? '' : ''}`}>\n {/* Server list */}\n <div className={`${tryTool ? 'flex-1 min-w-0' : 'w-full'} transition-all`}>\n {filteredServers.length === 0 ? (\n <EmptyState title=\"No servers found\" />\n ) : (\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b\">\n <th className=\"sticky top-[2.75rem] z-10 bg-surface px-6 py-3 text-left text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">\n Server / Tool\n </th>\n <th className=\"sticky top-[2.75rem] z-10 bg-surface px-4 py-3 text-left text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28\">\n Status\n </th>\n <th className=\"sticky top-[2.75rem] z-10 bg-surface w-16\" />\n </tr>\n </thead>\n <tbody>\n {filteredServers.map((server) => (\n <ServerRow\n key={server.id}\n server={server}\n expanded={expandedIds.has(server.id)}\n onToggle={() => toggleExpand(server.id)}\n onEdit={() => navigate(`/mcp/servers/${server.id}`)}\n onDelete={() => setConfirmDelete(server)}\n onTryTool={(tool) =>\n setTryTool({\n serverId: server.id,\n serverName: server.name,\n tool,\n })\n }\n connect={connect}\n disconnect={disconnect}\n visibleTools={filterTools(\n (server.tool_manifest ?? []) as McpToolManifest[],\n filters.search,\n )}\n />\n ))}\n </tbody>\n </table>\n )}\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n\n {/* Test panel — slides in from right */}\n {tryTool && (\n <div className=\"w-[380px] shrink-0 sticky top-0 max-h-screen overflow-y-auto\">\n <ToolTestPanel\n serverId={tryTool.serverId}\n serverName={tryTool.serverName}\n tool={tryTool.tool}\n onClose={() => setTryTool(null)}\n />\n </div>\n )}\n </div>\n\n {/* Delete confirmation modal */}\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"Delete MCP Server\"\n description={\n <>\n Delete{' '}\n <span className=\"font-medium text-text-primary\">{confirmDelete?.name}</span>?\n This will remove the server registration.\n </>\n }\n isPending={deleteServer.isPending}\n error={deleteServer.error as Error | null}\n />\n </div>\n );\n}\n"],"names":["useExpandedRows","storageKey","expandedIds","setExpandedIds","useState","raw","parsed","persist","useCallback","next","toggle","id","prev","isExpanded","isBuiltIn","row","_a","_b","matchesSearch","server","search","q","t","filterTools","tools","ServerRow","expanded","onToggle","onEdit","onDelete","onTryTool","connect","disconnect","visibleTools","allTools","builtin","tags","jsxs","Fragment","jsx","ChevronRight","ServerName","tag","StatusBadge","RowActionGroup","RowAction","Unplug","Plug","Pencil","Trash2","tool","ToolPill","e","Play","McpServersPage","navigate","useNavigate","filters","setFilter","pagination","useFilterParams","data","isLoading","useMcpServers","useConnectMcpServer","useDisconnectMcpServer","deleteServer","useDeleteMcpServer","confirmDelete","setConfirmDelete","toggleExpand","tryTool","setTryTool","servers","total","tagOptions","useMemo","allTags","s","filteredServers","useEffect","handleDelete","PageHeader","_","i","FilterBar","FilterInput","v","FilterSelect","EmptyState","StickyPagination","ToolTestPanel","ConfirmDeleteModal"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-BTm3-qwq.js","sources":["../../src/hooks/useExpandedRows.ts","../../src/pages/mcp/servers/helpers.ts","../../src/pages/mcp/servers/ServerRow.tsx","../../src/pages/mcp/servers/McpServersPage.tsx"],"sourcesContent":["import { useState, useCallback } from 'react';\n\n/**\n * Track expanded row IDs with localStorage persistence.\n *\n * Resilient: if a stored ID no longer exists in the data, it's silently ignored.\n * Never blocks rendering — reads from localStorage synchronously on mount,\n * writes asynchronously on change.\n */\nexport function useExpandedRows(storageKey: string): {\n expandedIds: Set<string>;\n toggle: (id: string) => void;\n isExpanded: (id: string) => boolean;\n} {\n const [expandedIds, setExpandedIds] = useState<Set<string>>(() => {\n try {\n const raw = localStorage.getItem(storageKey);\n if (raw) {\n const parsed = JSON.parse(raw);\n if (Array.isArray(parsed)) return new Set(parsed);\n }\n } catch { /* corrupted or unavailable — start empty */ }\n return new Set();\n });\n\n const persist = useCallback((next: Set<string>) => {\n try {\n localStorage.setItem(storageKey, JSON.stringify([...next]));\n } catch { /* quota exceeded or unavailable — ignore */ }\n }, [storageKey]);\n\n const toggle = useCallback((id: string) => {\n setExpandedIds((prev) => {\n const next = new Set(prev);\n if (next.has(id)) {\n next.delete(id);\n } else {\n next.add(id);\n }\n persist(next);\n return next;\n });\n }, [persist]);\n\n const isExpanded = useCallback((id: string) => expandedIds.has(id), [expandedIds]);\n\n return { expandedIds, toggle, isExpanded };\n}\n","import type { McpServerRecord, McpToolManifest } from '../../../api/types';\n\nexport function isBuiltIn(row: McpServerRecord): boolean {\n return !!(row.metadata as Record<string, unknown> | null)?.builtin\n || !!(row.transport_config as Record<string, unknown> | null)?.builtin;\n}\n\n/** Check if a server or any of its tools match the search term */\nexport function matchesSearch(server: McpServerRecord, search: string): boolean {\n if (!search) return true;\n const q = search.toLowerCase();\n if (server.name.toLowerCase().includes(q)) return true;\n if (server.description?.toLowerCase().includes(q)) return true;\n if ((server.tags ?? []).some((t) => t.toLowerCase().includes(q))) return true;\n const tools = (server.tool_manifest ?? []) as McpToolManifest[];\n return tools.some(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n}\n\n/** Filter tools within a server that match the search term */\nexport function filterTools(tools: McpToolManifest[], search: string): McpToolManifest[] {\n if (!search) return tools;\n const q = search.toLowerCase();\n return tools.filter(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n}\n","import { ChevronRight, Pencil, Trash2, Plug, Unplug, Play } from 'lucide-react';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport {\n useConnectMcpServer,\n useDisconnectMcpServer,\n} from '../../../api/mcp';\nimport { StatusBadge } from '../../../components/common/display/StatusBadge';\nimport { ToolPill } from '../../../components/common/display/ToolPill';\nimport { ServerName } from '../../../components/common/display/ServerName';\n\nimport type { McpServerRecord, McpToolManifest } from '../../../api/types';\nimport { isBuiltIn } from './helpers';\n\nexport function ServerRow({\n server,\n expanded,\n onToggle,\n onEdit,\n onDelete,\n onTryTool,\n connect,\n disconnect,\n visibleTools,\n}: {\n server: McpServerRecord;\n expanded: boolean;\n onToggle: () => void;\n onEdit: () => void;\n onDelete: () => void;\n onTryTool: (tool: McpToolManifest) => void;\n connect: ReturnType<typeof useConnectMcpServer>;\n disconnect: ReturnType<typeof useDisconnectMcpServer>;\n visibleTools: McpToolManifest[];\n}) {\n const allTools = (server.tool_manifest ?? []) as McpToolManifest[];\n const builtin = isBuiltIn(server);\n const tags = server.tags ?? [];\n\n return (\n <>\n {/* Server header row */}\n <tr\n onClick={allTools.length > 0 ? onToggle : undefined}\n className={`group/row border-b border-surface-border/50 transition-colors duration-100 ${\n allTools.length > 0 ? 'cursor-pointer row-hover' : ''\n }`}\n >\n {/* Name + tags */}\n <td className=\"px-6 py-2.5\">\n <div className=\"flex items-center gap-3\">\n <span className={`transition-transform duration-150 ${expanded ? 'rotate-90' : ''} ${allTools.length === 0 ? 'opacity-0' : 'text-text-tertiary'}`}>\n <ChevronRight size={14} />\n </span>\n <span className=\"flex items-center gap-1.5\">\n <ServerName name={server.name} serverId={server.id} short={false} />\n {allTools.length > 0 && (\n <sup className=\"text-2xs font-normal text-accent/70\">{allTools.length}</sup>\n )}\n </span>\n {tags.length > 0 && (\n <div className=\"flex gap-1 ml-auto shrink-0\">\n {tags.slice(0, 3).map((tag) => (\n <span key={tag} className=\"inline-block px-1.5 py-0 text-2xs text-text-tertiary bg-surface-sunken rounded\">\n {tag}\n </span>\n ))}\n {tags.length > 3 && (\n <span className=\"text-2xs text-text-quaternary\" title={tags.slice(3).join(', ')}>…</span>\n )}\n </div>\n )}\n </div>\n </td>\n\n {/* Status */}\n <td className=\"px-4 py-2.5 w-28 whitespace-nowrap\">\n <StatusBadge status={server.status} />\n </td>\n\n {/* Actions */}\n <td className=\"px-4 py-2.5 w-16\">\n <RowActionGroup>\n {!builtin && (\n server.status === 'connected' ? (\n <RowAction\n icon={Unplug}\n title=\"Disconnect server\"\n onClick={() => disconnect.mutate(server.id)}\n />\n ) : (\n <RowAction\n icon={Plug}\n title=\"Connect server\"\n onClick={() => connect.mutate(server.id)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )\n )}\n <RowAction\n icon={Pencil}\n title=\"Edit server\"\n onClick={onEdit}\n />\n {!builtin && (\n <RowAction\n icon={Trash2}\n title=\"Delete server\"\n onClick={onDelete}\n colorClass=\"text-text-tertiary hover:text-status-error\"\n />\n )}\n </RowActionGroup>\n </td>\n </tr>\n\n {/* Expanded tool rows — real table rows for column alignment */}\n {expanded && visibleTools.map((tool) => (\n <tr\n key={tool.name}\n onClick={() => onTryTool(tool)}\n className=\"group/row cursor-pointer hover:bg-surface-hover/50 transition-colors border-b border-surface-border/15\"\n >\n {/* Tool name + description */}\n <td className=\"pl-14 pr-6 py-2.5\">\n <ToolPill name={tool.name} size=\"md\" />\n {tool.description && (\n <p className=\"text-2xs leading-snug text-text-quaternary mt-0.5\">{tool.description}</p>\n )}\n </td>\n\n {/* Status — empty for tools */}\n <td className=\"px-4 py-2.5 w-28\" />\n\n {/* Actions — play on hover */}\n <td className=\"px-4 py-2.5 w-16\">\n <div className=\"flex items-center justify-end\">\n <button\n onClick={(e) => { e.stopPropagation(); onTryTool(tool); }}\n className=\"opacity-0 group-hover/row:opacity-100 transition-opacity text-text-tertiary hover:text-accent\"\n title=\"Try tool\"\n >\n <Play className=\"w-3.5 h-3.5\" strokeWidth={1.5} />\n </button>\n </div>\n </td>\n </tr>\n ))}\n </>\n );\n}\n","import { useState, useMemo, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useMcpServers,\n useConnectMcpServer,\n useDisconnectMcpServer,\n useDeleteMcpServer,\n} from '../../../api/mcp';\nimport { EmptyState } from '../../../components/common/display/EmptyState';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport type { McpServerRecord, McpToolManifest } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { FilterBar, FilterSelect, FilterInput } from '../../../components/common/data/FilterBar';\nimport { StickyPagination } from '../../../components/common/data/StickyPagination';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport { useExpandedRows } from '../../../hooks/useExpandedRows';\nimport { ToolTestPanel } from '../../../components/common/test/ToolTestPanel';\nimport { matchesSearch, filterTools } from './helpers';\nimport { ServerRow } from './ServerRow';\n\nexport function McpServersPage() {\n const navigate = useNavigate();\n const { filters, setFilter, pagination } = useFilterParams({\n filters: { status: '', search: '', tag: '' },\n });\n\n const { data, isLoading } = useMcpServers({\n status: filters.status || undefined,\n search: filters.search || undefined,\n tags: filters.tag || undefined,\n });\n const connect = useConnectMcpServer();\n const disconnect = useDisconnectMcpServer();\n const deleteServer = useDeleteMcpServer();\n\n const [confirmDelete, setConfirmDelete] = useState<McpServerRecord | null>(null);\n const { expandedIds, toggle: toggleExpand } = useExpandedRows('lt:expanded:mcp-servers');\n const [tryTool, setTryTool] = useState<{\n serverId: string;\n serverName: string;\n tool: McpToolManifest;\n } | null>(null);\n\n const servers = data?.servers ?? [];\n const total = data?.total ?? 0;\n\n // Derive unique tags from current result set for the filter dropdown\n const tagOptions = useMemo(() => {\n const allTags = new Set<string>();\n for (const s of servers) {\n for (const t of s.tags ?? []) allTags.add(t);\n }\n return [...allTags].sort().map((t) => ({ value: t, label: t }));\n }, [servers]);\n\n // Client-side search filtering for tool-level matches within expanded rows\n const filteredServers = useMemo(() => {\n if (!filters.search) return servers;\n return servers.filter((s) => matchesSearch(s, filters.search));\n }, [servers, filters.search]);\n\n // Auto-expand servers whose tools match the search (so results are visible)\n useEffect(() => {\n if (!filters.search) return;\n const q = filters.search.toLowerCase();\n for (const s of filteredServers) {\n const tools = (s.tool_manifest ?? []) as McpToolManifest[];\n const hasToolMatch = tools.some(\n (t) => t.name.toLowerCase().includes(q) || t.description?.toLowerCase().includes(q),\n );\n if (hasToolMatch && !expandedIds.has(s.id)) {\n toggleExpand(s.id);\n }\n }\n }, [filters.search, filteredServers]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteServer.mutate(confirmDelete.id, {\n onSuccess: () => setConfirmDelete(null),\n });\n };\n\n if (isLoading) {\n return (\n <div>\n <PageHeader title=\"Servers & Tools\" />\n <div className=\"animate-pulse space-y-0\">\n {Array.from({ length: 5 }).map((_, i) => (\n <div key={i} className=\"h-14 border-b last:border-b-0 px-6 flex items-center\">\n <div className=\"h-3 bg-surface-sunken rounded w-full\" />\n </div>\n ))}\n </div>\n </div>\n );\n }\n\n return (\n <div>\n <PageHeader\n title=\"Servers & Tools\"\n docsHash=\"#docs:dashboard.md:mcp-server-tools\"\n actions={\n <button\n onClick={() => navigate('/mcp/servers/new')}\n className=\"btn-primary text-xs\"\n >\n Register Server\n </button>\n }\n />\n\n <p className=\"text-sm text-text-secondary mb-6 max-w-2xl leading-relaxed\">\n Registered MCP servers and their available tools. Each server exposes tools that can be used by the MCP Tool Designer.\n </p>\n\n <FilterBar>\n <FilterInput\n label=\"Search\"\n value={filters.search}\n onChange={(v) => setFilter('search', v)}\n placeholder=\"Server or tool name...\"\n />\n <FilterSelect\n label=\"Tag\"\n value={filters.tag}\n onChange={(v) => setFilter('tag', v)}\n options={tagOptions}\n />\n <FilterSelect\n label=\"Status\"\n value={filters.status}\n onChange={(v) => setFilter('status', v)}\n options={[\n { value: 'registered', label: 'Registered' },\n { value: 'connected', label: 'Connected' },\n { value: 'error', label: 'Error' },\n { value: 'disconnected', label: 'Disconnected' },\n ]}\n />\n </FilterBar>\n\n <div className={`flex gap-0 ${tryTool ? '' : ''}`}>\n {/* Server list */}\n <div className={`${tryTool ? 'flex-1 min-w-0' : 'w-full'} transition-all`}>\n {filteredServers.length === 0 ? (\n <EmptyState title=\"No servers found\" />\n ) : (\n <table className=\"w-full\">\n <thead>\n <tr className=\"border-b\">\n <th className=\"sticky top-[2.75rem] z-10 bg-surface px-6 py-3 text-left text-2xs font-semibold uppercase tracking-widest text-text-tertiary\">\n Server / Tool\n </th>\n <th className=\"sticky top-[2.75rem] z-10 bg-surface px-4 py-3 text-left text-2xs font-semibold uppercase tracking-widest text-text-tertiary w-28\">\n Status\n </th>\n <th className=\"sticky top-[2.75rem] z-10 bg-surface w-16\" />\n </tr>\n </thead>\n <tbody>\n {filteredServers.map((server) => (\n <ServerRow\n key={server.id}\n server={server}\n expanded={expandedIds.has(server.id)}\n onToggle={() => toggleExpand(server.id)}\n onEdit={() => navigate(`/mcp/servers/${server.id}`)}\n onDelete={() => setConfirmDelete(server)}\n onTryTool={(tool) =>\n setTryTool({\n serverId: server.id,\n serverName: server.name,\n tool,\n })\n }\n connect={connect}\n disconnect={disconnect}\n visibleTools={filterTools(\n (server.tool_manifest ?? []) as McpToolManifest[],\n filters.search,\n )}\n />\n ))}\n </tbody>\n </table>\n )}\n\n <StickyPagination\n page={pagination.page}\n totalPages={pagination.totalPages(total)}\n onPageChange={pagination.setPage}\n total={total}\n pageSize={pagination.pageSize}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n\n {/* Test panel — slides in from right */}\n {tryTool && (\n <div className=\"w-[380px] shrink-0 sticky top-0 max-h-screen overflow-y-auto\">\n <ToolTestPanel\n serverId={tryTool.serverId}\n serverName={tryTool.serverName}\n tool={tryTool.tool}\n onClose={() => setTryTool(null)}\n />\n </div>\n )}\n </div>\n\n {/* Delete confirmation modal */}\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"Delete MCP Server\"\n description={\n <>\n Delete{' '}\n <span className=\"font-medium text-text-primary\">{confirmDelete?.name}</span>?\n This will remove the server registration.\n </>\n }\n isPending={deleteServer.isPending}\n error={deleteServer.error as Error | null}\n />\n </div>\n );\n}\n"],"names":["useExpandedRows","storageKey","expandedIds","setExpandedIds","useState","raw","parsed","persist","useCallback","next","toggle","id","prev","isExpanded","isBuiltIn","row","_a","_b","matchesSearch","server","search","q","t","filterTools","tools","ServerRow","expanded","onToggle","onEdit","onDelete","onTryTool","connect","disconnect","visibleTools","allTools","builtin","tags","jsxs","Fragment","jsx","ChevronRight","ServerName","tag","StatusBadge","RowActionGroup","RowAction","Unplug","Plug","Pencil","Trash2","tool","ToolPill","e","Play","McpServersPage","navigate","useNavigate","filters","setFilter","pagination","useFilterParams","data","isLoading","useMcpServers","useConnectMcpServer","useDisconnectMcpServer","deleteServer","useDeleteMcpServer","confirmDelete","setConfirmDelete","toggleExpand","tryTool","setTryTool","servers","total","tagOptions","useMemo","allTags","s","filteredServers","useEffect","handleDelete","PageHeader","_","i","FilterBar","FilterInput","v","FilterSelect","EmptyState","StickyPagination","ToolTestPanel","ConfirmDeleteModal"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as n,j as s}from"./vendor-query-DvWWuNIB.js";import{
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{a as n,j as s}from"./vendor-query-DvWWuNIB.js";import{aI as h,e as g}from"./index-D7peGNN0.js";import{D as y}from"./DataTable-FjFhx0SE.js";import{F as C,b as j}from"./FilterBar-CqPFZkVU.js";import{R as q,a as u}from"./RowActions-Bdd7z4eB.js";import{u as R}from"./useFilterParams-DBRw1Hcv.js";import{P as b}from"./PageHeader-BSWIspNB.js";import{T as _}from"./TaskQueuePill-BlHNpYiZ.js";import{W as N}from"./WorkflowPill-DJLcK_CM.js";import{aA as v,E as I,h as S}from"./vendor-icons-DUYcKTjP.js";import{u as E}from"./vendor-react-_9U4mKFr.js";import"./EmptyState-DgC_6njU.js";import"./useContainerWidth-DSLp1gEm.js";function G(){const r=E(),{data:c,isLoading:m}=h(),{filters:t,setFilter:i}=R({filters:{search:"",queue:""}}),[a,p]=n.useState(t.search);n.useEffect(()=>{if(a===t.search)return;const e=setTimeout(()=>i("search",a),g);return()=>clearTimeout(e)},[a,i,t.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(t.search){const l=t.search.toLowerCase();e=e.filter(w=>w.name.toLowerCase().includes(l))}return t.queue&&(e=e.filter(l=>l.task_queue===t.queue)),e},[o,t]),k=[{key:"name",label:"Workflow",render:e=>s.jsx(N,{type:e.name})},{key:"task_queue",label:"Queue",render:e=>s.jsx(_,{queue:e.task_queue}),className:"whitespace-nowrap"},{key:"registered",label:"Status",render:e=>e.registered?s.jsxs("span",{className:"inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-2xs font-medium bg-accent/10 text-accent",children:[s.jsx(v,{className:"w-3 h-3"}),"Certified"]}):s.jsx("span",{className:"inline-flex items-center px-1.5 py-0.5 rounded text-2xs font-medium bg-surface-sunken text-text-tertiary",children:"Durable"}),className:"whitespace-nowrap"},{key:"actions",label:"",render:e=>s.jsx(q,{children:e.registered?s.jsx(u,{icon:I,title:"View config",onClick:()=>r(`/workflows/registry/${encodeURIComponent(e.name)}`)}):s.jsx(u,{icon:S,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 s.jsxs("div",{children:[s.jsx(b,{title:"Workers",docsHash:"#docs:dashboard.md:task-queues"}),s.jsxs(C,{children:[s.jsx("input",{type:"text",placeholder:"Search workers...",value:a,onChange:e=>p(e.target.value),className:"input text-2xs py-1 px-2 w-56"}),s.jsx(j,{label:"Queue",value:t.queue,onChange:e=>i("queue",e),options:d.map(e=>({value:e,label:e}))})]}),s.jsx(y,{columns:k,data:f,keyFn:e=>e.name,onRowClick:x,isLoading:m,emptyMessage:"No active workers"})]})}export{G as WorkersPage};
|
|
2
|
+
//# sourceMappingURL=index-CR9rhAvN.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-CR9rhAvN.js","sources":["../../src/pages/workflows/workers/WorkersPage.tsx"],"sourcesContent":["import { SEARCH_DEBOUNCE_MS } from '../../../lib/realtime-refresh';\nimport { 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), SEARCH_DEBOUNCE_MS);\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-2xs 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-2xs 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-2xs 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","SEARCH_DEBOUNCE_MS","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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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{a as d,j as e}from"./vendor-query-DvWWuNIB.js";import{aE as Z,aJ as M,Y as ee,a as te,aK as se,aA as re,aB as oe,az as ne}from"./index-D7peGNN0.js";import{F as ae,b as le,a as ie}from"./FilterBar-CqPFZkVU.js";import{C as Q}from"./ConfirmDeleteModal-DGlOlQAo.js";import{R as L}from"./RolePill-CoETDpjF.js";import{W as ce}from"./WorkflowPill-DJLcK_CM.js";import{P as ue}from"./PageHeader-BSWIspNB.js";import{O as de,ax as F,aA as B,aE as me,k as z,aF as xe,aG as H,a4 as pe,U as J,X as he,C as fe,ac as we,aH as T,m as ke,E as ve}from"./vendor-icons-DUYcKTjP.js";import{u as G,e as ge,f as je}from"./vendor-react-_9U4mKFr.js";import{B as ye}from"./BotPicker-8bf0yOCT.js";import{N as Ne}from"./NamespacePill-C5epAgq6.js";import{c as be,f as _e,R as Ce,g as Se,h as U}from"./ResolverForm-CqGE5lf-.js";import"./escalation-items-OWntjDaH.js";import"./validate-C7yskdEn.js";import"./RosterWidget-DR-T4Izu.js";import"./bots-maURYoyr.js";import"./StatusBadge-DHVwxre2.js";import"./constants-CeBBTzf5.js";import"./UserName-BkJryunF.js";function Ie({tier:t}){return t==="certified"?e.jsxs("span",{className:"inline-flex items-center gap-1 text-2xs font-medium text-status-success",children:[e.jsx(B,{className:"w-3 h-3"}),"Certified"]}):t==="registered"?e.jsxs("span",{className:"inline-flex items-center gap-1 text-2xs font-medium text-text-secondary",children:[e.jsx(pe,{className:"w-3 h-3"}),"Registered"]}):e.jsxs("span",{className:"inline-flex items-center gap-1 text-2xs font-medium text-text-quaternary",children:[e.jsx(F,{className:"w-3 h-3"}),"Durable"]})}function rt(){const t=G(),{data:o,isLoading:i}=Z(),m=M(),[u,p]=d.useState(""),[r,k]=d.useState(null),[f,g]=d.useState(null),a=o??[],y=d.useMemo(()=>[...new Set(a.map(l=>l.task_queue).filter(Boolean))].sort(),[a]),c=d.useMemo(()=>{const l=u.toLowerCase().trim();return(r?[r]:y).map(h=>({queue:h,workflows:a.filter(S=>{var N;return S.task_queue===h&&(!l||S.workflow_type.toLowerCase().includes(l)||((N=S.description)==null?void 0:N.toLowerCase().includes(l)))})})).filter(h=>h.workflows.length>0)},[a,y,u,r]),x=d.useMemo(()=>{const l=u.toLowerCase().trim();return r?[]:a.filter(s=>{var h;return!s.task_queue&&(!l||s.workflow_type.toLowerCase().includes(l)||((h=s.description)==null?void 0:h.toLowerCase().includes(l)))})},[a,u,r]),C=l=>{l.registered?t(`/workflows/registry/${encodeURIComponent(l.workflow_type)}`):t(`/workflows/registry/new?workflow_type=${encodeURIComponent(l.workflow_type)}&task_queue=${encodeURIComponent(l.task_queue??"")}`)},I=()=>{f&&m.mutate(f,{onSuccess:()=>g(null)})};return e.jsxs("div",{children:[e.jsx(ue,{title:"Registered Workflows",docsHash:"#docs:dashboard.md:workflow-registry",actions:e.jsx("button",{onClick:()=>t("/workflows/registry/new"),className:"btn-primary text-xs",children:"Register Workflow"})}),!i&&y.length>0&&e.jsxs(ae,{children:[e.jsx(le,{label:"Queue",value:r??"",onChange:l=>k(l||null),options:y.map(l=>({value:l,label:l}))}),e.jsx(ie,{label:"Search",value:u,onChange:p,placeholder:`${a.length} workflows…`})]}),i?e.jsx(We,{}):c.length===0&&x.length===0?e.jsx("p",{className:"text-sm text-text-tertiary mt-8",children:u||r?"No workflows match your filter.":"No workflows discovered yet."}):e.jsxs("div",{className:"space-y-10",children:[c.map(({queue:l,workflows:s})=>e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(de,{className:"w-3 h-3 text-accent",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:l}),e.jsx("span",{className:"text-xs text-text-quaternary",children:s.length})]}),e.jsx($,{}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:s.map(h=>e.jsx(A,{wf:h,onRowClick:C,onDelete:g,onNavigate:t},h.workflow_type))})]},l)),x.length>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"sticky top-[60px] z-10 bg-surface flex items-center gap-2 py-2 mb-2 border-b border-surface-border",children:[e.jsx(F,{className:"w-3 h-3 text-text-quaternary",strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:"No Queue"}),e.jsx("span",{className:"text-xs text-text-quaternary",children:x.length})]}),e.jsx($,{}),e.jsx("div",{className:"divide-y divide-surface-border/30",children:x.map(l=>e.jsx(A,{wf:l,onRowClick:C,onDelete:g,onNavigate:t},l.workflow_type))})]})]}),e.jsx(Q,{open:!!f,onClose:()=>g(null),onConfirm:I,title:"Unregister Workflow",description:e.jsxs(e.Fragment,{children:["Delete the registration for"," ",e.jsx("span",{className:"font-mono font-medium text-text-primary",children:f}),"? This removes its invocation settings, certification, and interceptor treatment; the workflow keeps running as a plain durable workflow. To demote certified → registered instead, open the workflow and uncheck Certify — that keeps every setting."]}),isPending:m.isPending,error:m.error})]})}const K="grid grid-cols-[minmax(0,1fr)_7rem_13rem_4.5rem] gap-x-6";function $(){return e.jsxs("div",{className:`${K} px-3 pb-2 pt-1`,children:[e.jsx("span",{className:"text-2xs font-medium text-text-quaternary",children:"Workflow"}),e.jsx("span",{className:"text-2xs font-medium text-text-quaternary",children:"Tier"}),e.jsx("span",{className:"text-2xs font-medium text-text-quaternary",children:"Access"}),e.jsx("span",{})]})}function A({wf:t,onRowClick:o,onDelete:i,onNavigate:m}){const u=t.roles??[],p=t.invocation_roles??[];return e.jsxs("div",{role:"button",tabIndex:0,onClick:()=>o(t),onKeyDown:r=>{(r.key==="Enter"||r.key===" ")&&o(t)},className:`group ${K} py-2 px-3 -mx-3 rounded-md cursor-pointer transition-colors items-center`,children:[e.jsxs("div",{className:"flex items-center gap-3 min-w-0",children:[e.jsx(ce,{type:t.workflow_type,size:"md",variant:t.tier==="certified"?"certified":t.tier==="registered"?"registered":"durable"}),t.description&&e.jsx("p",{className:"flex-1 min-w-0 truncate text-2xs text-text-tertiary group-hover:text-text-secondary transition-colors",children:t.description})]}),e.jsx("div",{children:e.jsx(Ie,{tier:t.tier??"durable"})}),e.jsxs("div",{className:"flex items-center gap-1.5 min-w-0 overflow-hidden whitespace-nowrap",children:[u.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"Escalation roles",children:e.jsx(B,{className:"w-3 h-3 text-text-quaternary shrink-0"})}),u.map(r=>e.jsx(L,{role:r},`e-${r}`))]}),p.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("span",{title:"Invocation roles",children:e.jsx(me,{className:"w-3 h-3 text-text-quaternary shrink-0"})}),p.map(r=>e.jsx(L,{role:r},`i-${r}`))]}),u.length===0&&p.length===0&&e.jsx("span",{className:"text-xs text-text-quaternary",children:"—"})]}),e.jsxs("div",{className:"flex items-center justify-end gap-2.5 opacity-0 group-hover:opacity-100 transition-opacity",children:[t.invocable&&e.jsx("button",{title:"Invoke workflow",onClick:r=>{r.stopPropagation(),m(`/workflows/start?type=${encodeURIComponent(t.workflow_type)}&mode=now`)},className:"text-text-quaternary hover:text-status-success transition-colors",children:e.jsx(z,{className:"w-3.5 h-3.5"})}),t.tier==="durable"&&e.jsx("button",{title:"Configure workflow",onClick:r=>{r.stopPropagation(),m(`/workflows/registry/new?workflow_type=${encodeURIComponent(t.workflow_type)}&task_queue=${encodeURIComponent(t.task_queue??"")}`)},className:"text-text-quaternary hover:text-status-info transition-colors",children:e.jsx(F,{className:"w-3.5 h-3.5"})}),t.tier==="registered"&&e.jsx("button",{title:"Certify workflow",onClick:r=>{r.stopPropagation(),m(`/workflows/registry/${encodeURIComponent(t.workflow_type)}`)},className:"text-text-quaternary hover:text-status-success transition-colors",children:e.jsx(xe,{className:"w-3.5 h-3.5"})}),t.registered&&e.jsx("button",{title:"Unregister workflow",onClick:r=>{r.stopPropagation(),i(t.workflow_type)},className:"text-text-quaternary hover:text-status-warning transition-colors",children:e.jsx(H,{className:"w-3.5 h-3.5"})})]})]})}function We(){return e.jsx("div",{className:"animate-pulse space-y-8 mt-4",children:[1,2].map(t=>e.jsxs("div",{children:[e.jsx("div",{className:"h-4 bg-surface-sunken rounded w-36 mb-4"}),e.jsx("div",{className:"space-y-4",children:[1,2,3].map(o=>e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-48"}),e.jsx("div",{className:"h-3 bg-surface-sunken rounded w-full"})]},o))})]},t))})}function Re({selected:t,onChange:o,single:i,placeholder:m}){const{data:u}=ee(),p=(u==null?void 0:u.roles)??[],[r,k]=d.useState(!1),f=d.useRef(null);d.useEffect(()=>{const c=x=>{f.current&&!f.current.contains(x.target)&&k(!1)};return document.addEventListener("mousedown",c),()=>document.removeEventListener("mousedown",c)},[]);const g=c=>{i?(o(t.includes(c)?[]:[c]),k(!1)):o(t.includes(c)?t.filter(x=>x!==c):[...t,c])},a=c=>{o(t.filter(x=>x!==c))},y=m??(i?"Select role...":"Add roles...");return e.jsxs("div",{ref:f,className:"relative",children:[e.jsxs("button",{type:"button",onClick:()=>k(!r),className:"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none",children:[t.length===0&&e.jsx("span",{className:"text-xs text-text-tertiary",children:y}),t.map(c=>e.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-2xs",children:[e.jsx(J,{className:"w-2.5 h-2.5 shrink-0 text-accent/75"}),c,e.jsx("span",{role:"button",onClick:x=>{x.stopPropagation(),a(c)},className:"ml-0.5 hover:text-status-error transition-colors",children:e.jsx(he,{className:"w-2.5 h-2.5"})})]},c)),e.jsx(fe,{className:`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${r?"rotate-180":""}`})]}),r&&e.jsx("div",{className:"absolute z-[100] mt-1 w-full bg-surface-raised border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto",children:p.length===0?e.jsx("p",{className:"px-3 py-2 text-xs text-text-tertiary",children:"No roles defined"}):p.map(c=>{const x=t.includes(c);return e.jsxs("button",{type:"button",onClick:()=>g(c),className:`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${x?"bg-accent/[0.06] text-accent":"text-text-primary hover:bg-surface-sunken"}`,children:[e.jsx(J,{className:"w-3 h-3 shrink-0 text-accent/60"}),e.jsx("span",{className:"flex-1",children:c}),x&&e.jsx(we,{className:"w-3 h-3 shrink-0"})]},c)})})]})}function W(t){return t.split(",").map(o=>o.trim()).filter(Boolean)}const R={workflow_type:"",description:"",task_queue:"",default_role:"reviewer",invocable:!1,roles:"",invocation_roles:"",consumes:"",envelope_schema:"",input_schema:"",input_lookups:"",icon:"",resolver_schema:"",cron_schedule:"",execute_as:"",certified:!1};function qe(t){var m;const o=(t.roles??[]).join(", "),i=(t.consumes??[]).join(", ");return{workflow_type:t.workflow_type,description:t.description??"",task_queue:t.task_queue??"",default_role:t.default_role,invocable:t.invocable,roles:o,invocation_roles:(t.invocation_roles??[]).join(", "),consumes:i,envelope_schema:t.envelope_schema?JSON.stringify(t.envelope_schema,null,2):"",input_schema:t.input_schema?JSON.stringify(t.input_schema,null,2):"",input_lookups:(m=t.input_lookups)!=null&&m.length?JSON.stringify(t.input_lookups,null,2):"",icon:t.icon??"",resolver_schema:t.resolver_schema?JSON.stringify(t.resolver_schema,null,2):"",cron_schedule:t.cron_schedule??"",execute_as:t.execute_as??"",certified:t.certified}}function _(t){if(!t.trim())return!0;try{return JSON.parse(t),!0}catch{return!1}}function Pe(t){if(!t.trim())return null;try{const o=JSON.parse(t);return o&&typeof o=="object"&&!Array.isArray(o)&&o.properties?o:null}catch{return null}}function Fe({schemaText:t,lookup:o}){const i=d.useMemo(()=>Pe(t),[t]),m=d.useMemo(()=>i?be(i):"",[i]),[u,p]=d.useState(m);d.useEffect(()=>{p(m)},[m]);const r=d.useMemo(()=>({..._e({},o),resolver:null}),[o]);return i?e.jsx("div",{className:"@container","data-testid":"input-form-preview",children:e.jsx(Ce,{value:u,onChange:p,escalationContext:r})}):e.jsxs("p",{className:"text-2xs text-text-tertiary",children:["A schema with ",e.jsx("code",{className:"font-mono",children:"properties"})," previews here as the operator's form."]})}function Oe({value:t,onChange:o}){const[i,m]=d.useState(""),u=d.useMemo(()=>Se(i),[i]),p=U(t);return e.jsxs("div",{className:"space-y-2","data-testid":"workflow-icon-picker",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("input",{type:"text",value:i,onChange:r=>m(r.target.value),placeholder:"Filter icons…","aria-label":"Filter icons",className:"input text-2xs py-1 w-40"}),e.jsxs("span",{className:"flex items-center gap-1.5 text-2xs text-text-tertiary min-w-0",children:[p?e.jsx(p,{className:"w-3.5 h-3.5 text-accent shrink-0",strokeWidth:1.5}):e.jsx(T,{className:"w-3.5 h-3.5 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"font-mono truncate",children:t||"tier glyph"})]})]}),e.jsxs("div",{className:"flex flex-wrap gap-1",role:"listbox","aria-label":"Workflow icon",children:[e.jsx("button",{type:"button",role:"option","aria-selected":!t,title:"No icon (tier glyph)",onClick:()=>o(""),className:`p-1.5 rounded-md border transition-colors ${t?"border-transparent text-text-quaternary hover:bg-surface-hover hover:text-text-secondary":"border-accent bg-accent/10 text-accent"}`,children:e.jsx(T,{className:"w-4 h-4",strokeWidth:1.5})}),u.map(r=>{const k=U(r),f=t===r;return e.jsx("button",{type:"button",role:"option","aria-selected":f,title:r,onClick:()=>o(r),className:`p-1.5 rounded-md border transition-colors ${f?"border-accent bg-accent/10 text-accent":"border-transparent text-text-tertiary hover:bg-surface-hover hover:text-text-primary"}`,children:e.jsx(k,{className:"w-4 h-4",strokeWidth:1.5})},r)}),u.length===0&&e.jsx("p",{className:"text-2xs text-text-tertiary px-1 py-1.5",children:"No icon matches."})]})]})}function q({icon:t,color:o,children:i}){return e.jsxs("div",{className:"flex items-center gap-2 mb-4 pb-2 border-b border-surface-border",children:[e.jsx(t,{className:`w-4 h-4 ${o}`,strokeWidth:1.5}),e.jsx("h2",{className:"section-h2",children:i})]})}function j({label:t,hint:o,children:i}){return e.jsxs("div",{className:"space-y-1.5",children:[e.jsx("label",{className:"label",children:t}),i,o&&e.jsx("p",{className:"hint",children:o})]})}const P="input-json w-full";function Ee(t){return W(t)}function De(t){return t.join(", ")}const Le=new Set(["mcpQuery","mcpDeterministic","mcpQueryRouter","mcpTriage","mcpTriageRouter","mcpTriageDeterministic","insightQuery"]);function ot(){const{workflowType:t}=ge(),o=!t,i=G(),[m]=je(),{data:u,isLoading:p}=te(),r=se(),k=M(),[f,g]=d.useState(!1),a=(u==null?void 0:u.find(n=>n.workflow_type===t))??null,y=Array.isArray(a==null?void 0:a.input_lookups)&&a.input_lookups.length>0,{data:c}=re((a==null?void 0:a.workflow_type)??"",y),x=d.useMemo(()=>c?oe(c.lookups):void 0,[c]),{data:C}=ne({limit:500}),I=d.useMemo(()=>{const n=new Set((u??[]).map(v=>v.workflow_type));return[...new Set(((C==null?void 0:C.jobs)??[]).map(v=>v.entity))].filter(v=>!n.has(v)&&!Le.has(v)).sort()},[u,C]),l=d.useMemo(()=>{if(!o)return R;const n=m.get("workflow_type")??"",b=m.get("task_queue")??"";return n||b?{...R,workflow_type:n,task_queue:b}:R},[o,m]),[s,h]=d.useState(l),[S,N]=d.useState(""),[O,E]=d.useState(!1),w=d.useCallback((n,b)=>h(v=>({...v,[n]:b})),[]);d.useEffect(()=>{if(!O){if(o){h(l),E(!0);return}a&&(h(qe(a)),E(!0))}},[a,o,O,l]);const Y=()=>{if(!s.workflow_type.trim())return;N("");let n=null,b=null,v=null,D=null;try{s.envelope_schema.trim()&&(n=JSON.parse(s.envelope_schema))}catch{N("Invalid JSON in Envelope Schema");return}try{s.input_schema.trim()&&(b=JSON.parse(s.input_schema))}catch{N("Invalid JSON in Input Form");return}try{s.input_lookups.trim()&&(v=JSON.parse(s.input_lookups))}catch{N("Invalid JSON in Lookups");return}try{s.resolver_schema.trim()&&(D=JSON.parse(s.resolver_schema))}catch{N("Invalid JSON in Resolver Schema");return}r.mutate({workflow_type:s.workflow_type.trim(),description:s.description.trim()||null,task_queue:s.task_queue.trim()||null,default_role:s.default_role.trim()||"reviewer",invocable:s.invocable,certified:s.certified,roles:W(s.roles),invocation_roles:W(s.invocation_roles),consumes:W(s.consumes),envelope_schema:n,input_schema:b,input_lookups:v,icon:s.icon||null,resolver_schema:D,cron_schedule:s.cron_schedule.trim()||null,execute_as:s.execute_as.trim()||null},{onSuccess:()=>i("/workflows/registry")})};if(p)return e.jsxs("div",{className:"animate-pulse space-y-4",children:[e.jsx("div",{className:"h-8 bg-surface-sunken rounded w-64"}),e.jsx("div",{className:"h-40 bg-surface-sunken rounded"})]});if(!o&&!a)return e.jsx("p",{className:"text-sm text-text-secondary",children:"Config not found."});const V=!!s.workflow_type.trim()&&_(s.envelope_schema)&&_(s.input_schema)&&_(s.input_lookups)&&_(s.resolver_schema),X=o&&!s.workflow_type&&I.length>0;return e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-start justify-between mb-8",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-3xl font-light font-mono text-text-primary",children:o?"New Workflow":(a==null?void 0:a.workflow_type)??""}),a&&e.jsx("div",{className:"flex items-center gap-2 mt-2",children:e.jsx(Ne,{namespace:"durable"})})]}),e.jsxs("div",{className:"flex items-center gap-3 mt-1",children:[a&&e.jsxs("button",{onClick:()=>g(!0),className:"flex items-center gap-1.5 text-2xs text-status-warning hover:underline mr-3",title:"Delete this registration — the workflow returns to plain durable",children:[e.jsx(H,{className:"w-3 h-3",strokeWidth:1.5})," Unregister"]}),e.jsx("button",{onClick:()=>i("/workflows/registry"),className:"btn-ghost text-xs",children:"Cancel"}),e.jsx("button",{onClick:Y,disabled:!V||r.isPending,className:"btn-primary text-xs",children:r.isPending?"Saving…":o?"Register":"Save"})]})]}),e.jsxs("div",{className:"grid grid-cols-1 @wall:grid-cols-3 gap-x-14 gap-y-10",children:[e.jsxs("div",{children:[e.jsx(q,{icon:ke,color:"text-accent",children:"Identity"}),e.jsxs("div",{className:"space-y-5",children:[e.jsx(j,{label:"Workflow Type",hint:"Register a workflow to configure invocation and HITL escalation routing.",children:X?e.jsxs("div",{className:"space-y-2",children:[e.jsx("p",{className:"text-xs text-text-secondary",children:"Select a durable workflow to register:"}),e.jsx("div",{className:"grid gap-1",children:I.map(n=>e.jsx("button",{onClick:()=>w("workflow_type",n),className:"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors",children:n},n))}),e.jsxs("div",{className:"flex items-center gap-2 pt-1",children:[e.jsx("span",{className:"text-2xs text-text-tertiary",children:"or"}),e.jsx("input",{type:"text",onChange:n=>w("workflow_type",n.target.value),placeholder:"Enter type manually",className:"input font-mono flex-1"})]})]}):e.jsxs(e.Fragment,{children:[e.jsx("input",{type:"text",value:s.workflow_type,onChange:n=>w("workflow_type",n.target.value),disabled:!o,placeholder:"reviewContent",className:"input font-mono w-full"}),o&&s.workflow_type&&I.length>0&&e.jsx("button",{onClick:()=>w("workflow_type",""),className:"text-2xs text-accent hover:underline mt-1",children:"Choose from durable workflows"})]})}),e.jsx(j,{label:"Icon",hint:"Leads the workflow's row and heading on the Invoke Tool page so operators tell tools apart at a glance. Declared in code as WORKFLOW_ICONS.*",children:e.jsx(Oe,{value:s.icon,onChange:n=>w("icon",n)})}),e.jsx(j,{label:"Description",children:e.jsx("input",{type:"text",value:s.description,onChange:n=>w("description",n.target.value),placeholder:"Describe what this workflow does",className:"input text-xs w-full"})}),e.jsx(j,{label:"Task Queue",hint:"Durable task queue this workflow listens on.",children:e.jsx("input",{type:"text",value:s.task_queue,onChange:n=>w("task_queue",n.target.value),placeholder:"lt-review",className:"input font-mono w-full"})})]})]}),e.jsxs("div",{children:[e.jsx(q,{icon:z,color:"text-accent",children:"Invocation"}),e.jsxs("div",{className:"space-y-5",children:[e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",checked:s.invocable,onChange:n=>w("invocable",n.target.checked),className:"w-4 h-4 rounded border-border accent-accent"}),e.jsx("span",{className:"text-xs text-text-primary font-medium",children:"Invocable"})]}),e.jsx("p",{className:"hint",children:"Allow this workflow to be started from the dashboard or API."})]}),s.invocable?e.jsxs(e.Fragment,{children:[e.jsx(j,{label:"Run As",hint:"Bot identity to run under. Default runs as the invoking user.",children:e.jsx(ye,{selected:s.execute_as,onChange:n=>w("execute_as",n)})}),e.jsx(j,{label:"Invocation Roles",hint:"Only users with these roles can start this workflow. Empty = all authenticated users.",children:e.jsx(Re,{selected:Ee(s.invocation_roles),onChange:n=>w("invocation_roles",De(n)),placeholder:"Select roles…"})}),e.jsxs(j,{label:"Input Form",hint:e.jsx("button",{type:"button",onClick:()=>{window.location.hash="#docs:hitl/invoke-form.md"},className:"text-accent hover:underline",children:"Authoring reference →"}),children:[e.jsx("textarea",{value:s.input_schema,onChange:n=>w("input_schema",n.target.value),placeholder:`{
|
|
2
|
+
"x-lt-layout": "two-column",
|
|
3
|
+
"required": ["serialNumber"],
|
|
4
|
+
"properties": {
|
|
5
|
+
"serialNumber": { "type": "string", "title": "Serial number", "description": "Read it off the label" }
|
|
6
|
+
}
|
|
7
|
+
}`,className:P,rows:14,spellCheck:!1,"data-testid":"input-form-editor"}),s.input_schema.trim()&&!_(s.input_schema)&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:"Invalid JSON"})]}),e.jsxs(j,{label:"Lookups",hint:e.jsxs(e.Fragment,{children:["Versioned knowledge refs read as ",e.jsx("code",{className:"font-mono",children:"lookup.<as>"}),". ",e.jsx("button",{type:"button",onClick:()=>{window.location.hash="#docs:hitl/lookups.md"},className:"text-accent hover:underline",children:"Lookups reference →"})]}),children:[e.jsx("textarea",{value:s.input_lookups,onChange:n=>w("input_lookups",n.target.value),placeholder:`[
|
|
8
|
+
{ "domain": "fleet", "key": "serial-numbers", "version": 1, "as": "serials" }
|
|
9
|
+
]`,className:P,rows:5,spellCheck:!1,"data-testid":"input-lookups-editor"}),s.input_lookups.trim()&&!_(s.input_lookups)&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:"Invalid JSON"})]}),e.jsxs(j,{label:s.input_schema.trim()?"Envelope Metadata":"Envelope Schema",hint:s.input_schema.trim()?e.jsxs(e.Fragment,{children:["With an input form, only ",e.jsx("code",{className:"font-mono",children:"metadata"})," is read from here and stamped on every run; ",e.jsx("code",{className:"font-mono",children:"data"})," comes from the form."]}):e.jsxs(e.Fragment,{children:["Pre-fills the JSON editor when invoking. Include ",e.jsx("code",{className:"font-mono",children:"data"})," (input) and optional ",e.jsx("code",{className:"font-mono",children:"metadata"}),". Declare an input form above for a rich, validated form instead."]}),children:[e.jsx("textarea",{value:s.envelope_schema,onChange:n=>w("envelope_schema",n.target.value),placeholder:`{
|
|
10
|
+
"data": {},
|
|
11
|
+
"metadata": {}
|
|
12
|
+
}`,className:P,rows:8,spellCheck:!1}),s.envelope_schema.trim()&&!_(s.envelope_schema)&&e.jsx("p",{className:"text-2xs text-status-error mt-1",children:"Invalid JSON"})]})]}):e.jsxs("p",{className:"text-2xs text-text-tertiary py-2",children:["Enable ",e.jsx("span",{className:"font-medium text-text-secondary",children:"Invocable"})," to configure invocation roles and an input template."]})]})]}),e.jsxs("div",{className:"@wall:sticky @wall:top-0 self-start max-h-[calc(100vh-6rem)] overflow-y-auto",children:[e.jsx(q,{icon:ve,color:"text-accent",children:"Preview"}),s.invocable&&s.input_schema.trim()&&_(s.input_schema)?e.jsx(Fe,{schemaText:s.input_schema,lookup:x}):e.jsx("p",{className:"text-2xs text-text-tertiary leading-relaxed",children:s.invocable?"Declare an Input Form and it previews here as the operator's form, live as you type.":"Enable Invocable and declare an Input Form to preview the operator's form here."})]})]}),(S||r.error)&&e.jsx("p",{className:"text-xs text-status-error mt-8",children:S||r.error.message}),e.jsx(Q,{open:f,onClose:()=>g(!1),onConfirm:()=>k.mutate(a.workflow_type,{onSuccess:()=>i("/workflows/registry")}),title:"Unregister Workflow",description:e.jsxs(e.Fragment,{children:["Delete the registration for"," ",e.jsx("span",{className:"font-mono font-medium text-text-primary",children:a==null?void 0:a.workflow_type}),"? This removes its invocation settings, certification, and interceptor treatment; the workflow keeps running as a plain durable workflow. Escalation schemas versioned on roles are untouched."]}),isPending:k.isPending,error:k.error})]})}export{ot as WorkflowConfigDetailPage,rt as WorkflowConfigsPage};
|
|
13
|
+
//# sourceMappingURL=index-CWKs10VQ.js.map
|