@hotmeshio/long-tail 0.4.9 → 0.4.11
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/adapters/express.js +7 -2
- package/build/index.d.ts +1 -1
- package/build/index.js +3 -2
- package/build/start/config.js +26 -15
- package/dashboard/dist/assets/{AdminDashboard-BVtpNGO1.js → AdminDashboard-Z32TwYm9.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-BVtpNGO1.js.map → AdminDashboard-Z32TwYm9.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-BGDDZpxn.js → AgentConfigPage-uedbi7zT.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-BGDDZpxn.js.map → AgentConfigPage-uedbi7zT.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-9wlNBv63.js → AgentDetailPage-rRQtJQIE.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-9wlNBv63.js.map → AgentDetailPage-rRQtJQIE.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-C8Sf-OUW.js → AgentsPage-w9zOW2GX.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-C8Sf-OUW.js.map → AgentsPage-w9zOW2GX.js.map} +1 -1
- package/dashboard/dist/assets/{AvailableEscalationsPage-BzfgOP5p.js → AvailableEscalationsPage-DZ4ut6rj.js} +2 -2
- package/dashboard/dist/assets/{AvailableEscalationsPage-BzfgOP5p.js.map → AvailableEscalationsPage-DZ4ut6rj.js.map} +1 -1
- package/dashboard/dist/assets/{BotPicker-6Xk1Fq1l.js → BotPicker-BW3DEEsk.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-6Xk1Fq1l.js.map → BotPicker-BW3DEEsk.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-C30RqH3d.js → CapabilitiesPage-y7fFEpue.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-C30RqH3d.js.map → CapabilitiesPage-y7fFEpue.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-DR3D4kMt.js → CollapsibleSection-BqCrlb0a.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-DR3D4kMt.js.map → CollapsibleSection-BqCrlb0a.js.map} +1 -1
- package/dashboard/dist/assets/{ConfirmDeleteModal-dOxidrSR.js → ConfirmDeleteModal-D9_1b4MW.js} +2 -2
- package/dashboard/dist/assets/{ConfirmDeleteModal-dOxidrSR.js.map → ConfirmDeleteModal-D9_1b4MW.js.map} +1 -1
- package/dashboard/dist/assets/{CopyableId-D0SQ39nR.js → CopyableId-DaT0ZRHg.js} +2 -2
- package/dashboard/dist/assets/{CopyableId-D0SQ39nR.js.map → CopyableId-DaT0ZRHg.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-2nEwkFSm.js → CredentialsPage-jr9En3Wc.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-2nEwkFSm.js.map → CredentialsPage-jr9En3Wc.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-Cfq2Hlsq.js → CronLabel-CcPaepiQ.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-Cfq2Hlsq.js.map → CronLabel-CcPaepiQ.js.map} +1 -1
- package/dashboard/dist/assets/{CustomDurationPicker-CSvIDpXD.js → CustomDurationPicker-CPkebwlV.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-CSvIDpXD.js.map → CustomDurationPicker-CPkebwlV.js.map} +1 -1
- package/dashboard/dist/assets/{ElapsedCell-B4nhqILk.js → ElapsedCell-BjL_EpqA.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-B4nhqILk.js.map → ElapsedCell-BjL_EpqA.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-CvMHVxgm.js → EscalationsOverview-DyFZKf53.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-CvMHVxgm.js.map → EscalationsOverview-DyFZKf53.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-faF8fMen.js → EventTable-BFTY1gJh.js} +2 -2
- package/dashboard/dist/assets/{EventTable-faF8fMen.js.map → EventTable-BFTY1gJh.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-DnSHq_dm.js → HomePage-DtCV15bZ.js} +2 -2
- package/dashboard/dist/assets/{HomePage-DnSHq_dm.js.map → HomePage-DtCV15bZ.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-C1EXfNfS.js → ListToolbar-BEWIH8y8.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-C1EXfNfS.js.map → ListToolbar-BEWIH8y8.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-B9ZDlmUD.js → McpOverview-CAC72Qkp.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-B9ZDlmUD.js.map → McpOverview-CAC72Qkp.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-DdrdIa-N.js → McpQueryDetailPage-Cs5SwLE8.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-DdrdIa-N.js.map → McpQueryDetailPage-Cs5SwLE8.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-C9wb1cOa.js → McpQueryPage-CbzTE3lo.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-C9wb1cOa.js.map → McpQueryPage-CbzTE3lo.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-b5ungm-L.js → McpRunDetailPage-BJKdHgWh.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-b5ungm-L.js.map → McpRunDetailPage-BJKdHgWh.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-wa62n3tp.js → McpRunsPage-BVt_3aJW.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-wa62n3tp.js.map → McpRunsPage-BVt_3aJW.js.map} +1 -1
- package/dashboard/dist/assets/{Modal-DEODGeqx.js → Modal-CSrxpXeM.js} +2 -2
- package/dashboard/dist/assets/{Modal-DEODGeqx.js.map → Modal-CSrxpXeM.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-BDpk_HF5.js → OperatorDashboard-B8dwVFC4.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-BDpk_HF5.js.map → OperatorDashboard-B8dwVFC4.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DHLKP0kz.js → ProcessDetailPage-DBun2ogu.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DHLKP0kz.js.map → ProcessDetailPage-DBun2ogu.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CpANHQGA.js → ProcessesListPage-TDjac8Lk.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CpANHQGA.js.map → ProcessesListPage-TDjac8Lk.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-Ddta3UZX.js → RolesPage-NkVRnqrM.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-Ddta3UZX.js.map → RolesPage-NkVRnqrM.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BpeN2J3V.js → RunAsSelector-DRMoYomI.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BpeN2J3V.js.map → RunAsSelector-DRMoYomI.js.map} +1 -1
- package/dashboard/dist/assets/{ServerName-BXSm_14r.js → ServerName-A6Wlv3vZ.js} +2 -2
- package/dashboard/dist/assets/{ServerName-BXSm_14r.js.map → ServerName-A6Wlv3vZ.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-DSra_wMN.js → SwimlaneTimeline-DsPrsDBU.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-DSra_wMN.js.map → SwimlaneTimeline-DsPrsDBU.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-Dqha2tKb.js → TaskDetailPage-CZPxCOgP.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-Dqha2tKb.js.map → TaskDetailPage-CZPxCOgP.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-CM16b5S8.js → TasksListPage-BYC4Mbx8.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-CM16b5S8.js.map → TasksListPage-BYC4Mbx8.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-DCjPMPw-.js → TimeAgo-C3j486uV.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-DCjPMPw-.js.map → TimeAgo-C3j486uV.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BBdTvZ08.js → TimestampCell-DoBoqZGS.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BBdTvZ08.js.map → TimestampCell-DoBoqZGS.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Dz-76HVQ.js → ToolTestPanel-CoB5Ybz3.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Dz-76HVQ.js.map → ToolTestPanel-CoB5Ybz3.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-Ccqf9h5E.js → TopicDetailPage-Bl6daecJ.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-Ccqf9h5E.js.map → TopicDetailPage-Bl6daecJ.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage--1V67zFa.js → TopicsPage-CTU8fi_i.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage--1V67zFa.js.map → TopicsPage-CTU8fi_i.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-CfaTpV3T.js → UserName-16nVz3Sw.js} +2 -2
- package/dashboard/dist/assets/{UserName-CfaTpV3T.js.map → UserName-16nVz3Sw.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-Cp5_bsHY.js → WorkflowExecutionPage-RYeTXRHH.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-Cp5_bsHY.js.map → WorkflowExecutionPage-RYeTXRHH.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-DaZZg4xU.js → WorkflowsDashboard-B8tyWMBl.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-DaZZg4xU.js.map → WorkflowsDashboard-B8tyWMBl.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-D_ZkBVhB.js → WorkflowsOverview-Bd7eUOlY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-D_ZkBVhB.js.map → WorkflowsOverview-Bd7eUOlY.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-BKFXRwbK.js → YamlWorkflowsPage-CISGkpSa.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-BKFXRwbK.js.map → YamlWorkflowsPage-CISGkpSa.js.map} +1 -1
- package/dashboard/dist/assets/{agents-GIg2jxet.js → agents-DdrWb9IA.js} +2 -2
- package/dashboard/dist/assets/{agents-GIg2jxet.js.map → agents-DdrWb9IA.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CvrmNkL3.js → bots-DNEC8CB_.js} +2 -2
- package/dashboard/dist/assets/{bots-CvrmNkL3.js.map → bots-DNEC8CB_.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-CQ5WgulO.js → capabilities-x0lc5Qr5.js} +2 -2
- package/dashboard/dist/assets/{capabilities-CQ5WgulO.js.map → capabilities-x0lc5Qr5.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-sh5paKGB.js → controlplane-BKtGwxSj.js} +2 -2
- package/dashboard/dist/assets/{controlplane-sh5paKGB.js.map → controlplane-BKtGwxSj.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-DlTtA35J.js → escalation-Cp3QJCTq.js} +2 -2
- package/dashboard/dist/assets/{escalation-DlTtA35J.js.map → escalation-Cp3QJCTq.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-BHiDO_RZ.js → escalation-columns-_wkDseNt.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-BHiDO_RZ.js.map → escalation-columns-_wkDseNt.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-DuKOBZxw.js → helpers-Bkhi987m.js} +2 -2
- package/dashboard/dist/assets/{helpers-DuKOBZxw.js.map → helpers-Bkhi987m.js.map} +1 -1
- package/dashboard/dist/assets/{index-qpt9aUuQ.js → index-BOnE32zg.js} +2 -2
- package/dashboard/dist/assets/{index-qpt9aUuQ.js.map → index-BOnE32zg.js.map} +1 -1
- package/dashboard/dist/assets/{index-Dbxp9Nvq.js → index-BhPDvjQ6.js} +2 -2
- package/dashboard/dist/assets/{index-Dbxp9Nvq.js.map → index-BhPDvjQ6.js.map} +1 -1
- package/dashboard/dist/assets/{index-B_e2uIz9.js → index-CGy9PrdX.js} +28 -28
- package/dashboard/dist/assets/index-CGy9PrdX.js.map +1 -0
- package/dashboard/dist/assets/{index-C-JkowYp.js → index-CTl3ROOo.js} +2 -2
- package/dashboard/dist/assets/{index-C-JkowYp.js.map → index-CTl3ROOo.js.map} +1 -1
- package/dashboard/dist/assets/{index-DIpDSspp.js → index-CVv6Hs0J.js} +2 -2
- package/dashboard/dist/assets/{index-DIpDSspp.js.map → index-CVv6Hs0J.js.map} +1 -1
- package/dashboard/dist/assets/{index-PZaFsSGv.js → index-CmEmMw8h.js} +2 -2
- package/dashboard/dist/assets/{index-PZaFsSGv.js.map → index-CmEmMw8h.js.map} +1 -1
- package/dashboard/dist/assets/{index-BXGMin7U.js → index-D6EMWmS-.js} +2 -2
- package/dashboard/dist/assets/{index-BXGMin7U.js.map → index-D6EMWmS-.js.map} +1 -1
- package/dashboard/dist/assets/{index-CugmdGk-.js → index-DB_zkstT.js} +2 -2
- package/dashboard/dist/assets/{index-CugmdGk-.js.map → index-DB_zkstT.js.map} +1 -1
- package/dashboard/dist/assets/{index-BWXKb7C7.js → index-Dig8_eMS.js} +2 -2
- package/dashboard/dist/assets/{index-BWXKb7C7.js.map → index-Dig8_eMS.js.map} +1 -1
- package/dashboard/dist/assets/{index-JH__2KWY.js → index-cUV1o7mj.js} +2 -2
- package/dashboard/dist/assets/{index-JH__2KWY.js.map → index-cUV1o7mj.js.map} +1 -1
- package/dashboard/dist/assets/{index-CglOyur2.js → index-rQpU8PEa.js} +2 -2
- package/dashboard/dist/assets/{index-CglOyur2.js.map → index-rQpU8PEa.js.map} +1 -1
- package/dashboard/dist/assets/{index-7icR5Pxv.js → index-x7kIRS2q.js} +2 -2
- package/dashboard/dist/assets/{index-7icR5Pxv.js.map → index-x7kIRS2q.js.map} +1 -1
- package/dashboard/dist/assets/{index-CRDT24gK.js → index-zK7nCOfQ.js} +2 -2
- package/dashboard/dist/assets/{index-CRDT24gK.js.map → index-zK7nCOfQ.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-tDl7bioT.js → knowledge-BDr9CzZ7.js} +2 -2
- package/dashboard/dist/assets/{knowledge-tDl7bioT.js.map → knowledge-BDr9CzZ7.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-CvdtxZQK.js → mcp-CCWQrZNk.js} +2 -2
- package/dashboard/dist/assets/{mcp-CvdtxZQK.js.map → mcp-CCWQrZNk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-D5uxvom6.js → mcp-query-DYy5Xha0.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-D5uxvom6.js.map → mcp-query-DYy5Xha0.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-runs-DBUF_MeD.js → mcp-runs-DIh5XCg1.js} +2 -2
- package/dashboard/dist/assets/{mcp-runs-DBUF_MeD.js.map → mcp-runs-DIh5XCg1.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-BYTDs3EH.js → namespaces-CAaahBQS.js} +2 -2
- package/dashboard/dist/assets/{namespaces-BYTDs3EH.js.map → namespaces-CAaahBQS.js.map} +1 -1
- package/dashboard/dist/assets/{roles-BWPoKy_E.js → roles-DIjyTYc4.js} +2 -2
- package/dashboard/dist/assets/{roles-BWPoKy_E.js.map → roles-DIjyTYc4.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-BQH9o3Ge.js → tasks-DiBPwT-p.js} +2 -2
- package/dashboard/dist/assets/{tasks-BQH9o3Ge.js.map → tasks-DiBPwT-p.js.map} +1 -1
- package/dashboard/dist/assets/{topics-BjuxqPQn.js → topics-CDjGhp4t.js} +2 -2
- package/dashboard/dist/assets/{topics-BjuxqPQn.js.map → topics-CDjGhp4t.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-CZR0V3cW.js → useEventHooks-BXzvSJIr.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-CZR0V3cW.js.map → useEventHooks-BXzvSJIr.js.map} +1 -1
- package/dashboard/dist/assets/{useFilterParams-DZCAaBC7.js → useFilterParams-x-Dg0Vgz.js} +2 -2
- package/dashboard/dist/assets/{useFilterParams-DZCAaBC7.js.map → useFilterParams-x-Dg0Vgz.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-DATwT-Bk.js → useYamlActivityEvents-CAkKAAX5.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-DATwT-Bk.js.map → useYamlActivityEvents-CAkKAAX5.js.map} +1 -1
- package/dashboard/dist/assets/{users-DzO800OU.js → users-DmkMv9Hc.js} +2 -2
- package/dashboard/dist/assets/{users-DzO800OU.js.map → users-DmkMv9Hc.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-react-CX88sFS5.js → vendor-react-CXumBFUA.js} +6 -6
- package/dashboard/dist/assets/{vendor-react-CX88sFS5.js.map → vendor-react-CXumBFUA.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-C093TSq9.js → workflows-Bwikzl2q.js} +2 -2
- package/dashboard/dist/assets/{workflows-C093TSq9.js.map → workflows-Bwikzl2q.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-Du9N-ZOj.js → yaml-workflows--YR7XQ5F.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-Du9N-ZOj.js.map → yaml-workflows--YR7XQ5F.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/package.json +1 -1
- package/dashboard/dist/assets/index-B_e2uIz9.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-BWXKb7C7.js","sources":["../../src/pages/workflows/registry/WorkflowConfigsPage.tsx","../../src/lib/parse.ts","../../src/pages/workflows/registry/config-form-types.ts","../../src/components/common/form/RolePicker.tsx","../../src/components/common/form/WorkflowPicker.tsx","../../src/pages/workflows/registry/AdvancedStep.tsx","../../src/pages/workflows/registry/ConfigWizardSteps.tsx","../../src/pages/workflows/registry/WorkflowConfigDetailPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useDiscoveredWorkflows,\n useDeleteWorkflowConfig,\n} from '../../../api/workflows';\nimport { ShieldCheck, ShieldPlus, ShieldOff, Settings, Wrench, Play, UserCheck } from 'lucide-react';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { DiscoveredWorkflow } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { RolePill } from '../../../components/common/display/RolePill';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction matchesSearch(wf: DiscoveredWorkflow, search: string): boolean {\n const q = search.toLowerCase();\n return (\n wf.workflow_type.toLowerCase().includes(q) ||\n (wf.description ?? '').toLowerCase().includes(q)\n );\n}\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigsPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useDiscoveredWorkflows();\n const deleteConfig = useDeleteWorkflowConfig();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '', role: '', tier: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n\n // Debounce search input\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 allWorkflows = data ?? [];\n\n // Derive facet options from data\n const queues = useMemo(\n () => [...new Set(allWorkflows.map((w) => w.task_queue).filter(Boolean) as string[])].sort(),\n [allWorkflows],\n );\n const roles = useMemo(\n () => [...new Set(allWorkflows.flatMap((w) => w.roles ?? []))].sort(),\n [allWorkflows],\n );\n\n // Apply client-side filters\n const workflows = useMemo(() => {\n let result = allWorkflows;\n if (filters.search) result = result.filter((w) => matchesSearch(w, filters.search));\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n if (filters.role) result = result.filter((w) => (w.roles ?? []).includes(filters.role));\n if (filters.tier) result = result.filter((w) => w.tier === filters.tier);\n return result;\n }, [allWorkflows, filters]);\n\n const columns: Column<DiscoveredWorkflow>[] = [\n {\n key: 'workflow_type',\n label: 'Workflow',\n className: 'max-w-xs',\n render: (row) => (\n <div className=\"min-w-0\">\n <WorkflowPill type={row.workflow_type} size=\"md\" variant={row.tier === 'certified' ? 'certified' : row.tier === 'configured' ? 'configured' : 'durable'} />\n {row.description && (\n <p className=\"text-[10px] leading-tight text-text-quaternary mt-0.5\">{row.description}</p>\n )}\n </div>\n ),\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => row.task_queue ? <TaskQueuePill queue={row.task_queue} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'tier',\n label: 'Tier',\n render: (row) => {\n if (row.tier === 'certified') return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>;\n if (row.tier === 'configured') return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><Settings className=\"w-3 h-3\" />Configured</span>;\n return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><Wrench className=\"w-3 h-3\" />Durable</span>;\n },\n className: 'whitespace-nowrap',\n },\n {\n key: 'roles',\n label: 'Access',\n render: (row) => {\n if (!row.registered) return <span className=\"text-xs text-text-tertiary\">—</span>;\n const escRoles = row.roles ?? [];\n const invokeRoles = row.invocation_roles ?? [];\n if (!escRoles.length && !invokeRoles.length) return <span className=\"text-xs text-text-tertiary\">—</span>;\n return (\n <div className=\"space-y-1.5\">\n {escRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <span title=\"Escalation roles\"><ShieldCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n <div className=\"flex gap-1 flex-wrap\">{escRoles.map((r) => <RolePill key={`e-${r}`} role={r} />)}</div>\n </div>\n )}\n {invokeRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <span title=\"Invocation roles\"><UserCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n <div className=\"flex gap-1 flex-wrap\">{invokeRoles.map((r) => <RolePill key={`i-${r}`} role={r} />)}</div>\n </div>\n )}\n </div>\n );\n },\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.invocable && (\n <RowAction\n icon={Play}\n title=\"Invoke workflow\"\n onClick={() => navigate(`/workflows/start?type=${encodeURIComponent(row.workflow_type)}&mode=now`)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )}\n {row.tier === 'durable' && (\n <RowAction\n icon={Wrench}\n title=\"Configure workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`)}\n colorClass=\"text-text-tertiary hover:text-status-info\"\n />\n )}\n {row.tier === 'configured' && (\n <RowAction\n icon={ShieldPlus}\n title=\"Certify workflow\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )}\n {row.registered && (\n <RowAction\n icon={ShieldOff}\n title=\"Remove configuration\"\n onClick={() => setConfirmDelete(row.workflow_type)}\n colorClass=\"text-text-tertiary hover:text-status-warning\"\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteConfig.mutate(confirmDelete, {\n onSuccess: () => setConfirmDelete(null),\n });\n };\n\n const handleRowClick = (row: DiscoveredWorkflow) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`);\n }\n };\n\n return (\n <div>\n <PageHeader\n title=\"Workflow Registry\"\n docsHash=\"#docs:dashboard.md:workflow-registry\"\n actions={\n <button\n onClick={() => navigate('/workflows/registry/new')}\n className=\"btn-primary text-xs\"\n >\n Register Workflow\n </button>\n }\n />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workflow type...\"\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 <FilterSelect\n label=\"Tier\"\n value={filters.tier}\n onChange={(v) => setFilter('tier', v)}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'configured', label: 'Configured' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n <FilterSelect\n label=\"Role\"\n value={filters.role}\n onChange={(v) => setFilter('role', v)}\n options={roles.map((r) => ({ value: r, label: r }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workflows}\n keyFn={(row) => row.workflow_type}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No workflows found\"\n />\n\n {/* Delete confirmation modal */}\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"De-certify Workflow\"\n description={<>Remove certification from <span className=\"font-mono font-medium text-text-primary\">{confirmDelete}</span>? This removes interceptor guarantees, escalation chains, and invocation role constraints. The workflow will continue running as a standard durable workflow.</>}\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n","export function splitCsv(s: string): string[] {\n return s\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n}\n\nexport function safeParseJson<T = unknown>(\n json: string,\n): { ok: true; data: T } | { ok: false; error: string } {\n try {\n return { ok: true, data: JSON.parse(json) as T };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n return { ok: false, error: message };\n }\n}\n","import type { LTWorkflowConfig } from '../../../api/types';\n\nexport interface ConfigFormState {\n workflow_type: string;\n description: string;\n task_queue: string;\n default_role: string;\n invocable: boolean;\n roles: string;\n invocation_roles: string;\n consumes: string;\n envelope_schema: string;\n resolver_schema: string;\n cron_schedule: string;\n execute_as: string;\n /** UI-only — gates escalation fields in the wizard. Not sent to backend. */\n certified: boolean;\n}\n\nexport const EMPTY_FORM: ConfigFormState = {\n workflow_type: '',\n description: '',\n task_queue: '',\n default_role: 'reviewer',\n invocable: false,\n roles: '',\n invocation_roles: '',\n consumes: '',\n envelope_schema: '',\n resolver_schema: '',\n cron_schedule: '',\n execute_as: '',\n certified: false,\n};\n\nexport function configToForm(c: LTWorkflowConfig): ConfigFormState {\n const roles = (c.roles ?? []).join(', ');\n const consumes = (c.consumes ?? []).join(', ');\n return {\n workflow_type: c.workflow_type,\n description: c.description ?? '',\n task_queue: c.task_queue ?? '',\n default_role: c.default_role,\n invocable: c.invocable,\n roles,\n invocation_roles: (c.invocation_roles ?? []).join(', '),\n consumes,\n envelope_schema: c.envelope_schema ? JSON.stringify(c.envelope_schema, null, 2) : '',\n resolver_schema: c.resolver_schema ? JSON.stringify(c.resolver_schema, null, 2) : '',\n cron_schedule: c.cron_schedule ?? '',\n execute_as: c.execute_as ?? '',\n certified: !!(roles || consumes),\n };\n}\n\nexport const STEP_LABELS = ['Identity', 'Invocation', 'Advanced'];\n\nexport function jsonValid(v: string): boolean {\n if (!v.trim()) return true;\n try { JSON.parse(v); return true; } catch { return false; }\n}\n\nexport function isStepValid(step: number, form: ConfigFormState): boolean {\n if (step === 1) return !!form.workflow_type.trim();\n if (step === 2) return jsonValid(form.envelope_schema);\n if (step === 3) return jsonValid(form.resolver_schema);\n return true;\n}\n\nexport const labelCls = 'label';\nexport const hintCls = 'hint';\nexport const jsonCls = 'input-json w-full';\n\nexport const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n","import { useState, useRef, useEffect } from 'react';\nimport { User, X, ChevronDown, Check } from 'lucide-react';\nimport { useRoles } from '../../../api/roles';\n\ninterface RolePickerProps {\n selected: string[];\n onChange: (roles: string[]) => void;\n /** Only allow one selection */\n single?: boolean;\n placeholder?: string;\n}\n\nexport function RolePicker({ selected, onChange, single, placeholder }: RolePickerProps) {\n const { data } = useRoles();\n const allRoles = data?.roles ?? [];\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (role: string) => {\n if (single) {\n onChange(selected.includes(role) ? [] : [role]);\n setOpen(false);\n } else {\n onChange(\n selected.includes(role)\n ? selected.filter((r) => r !== role)\n : [...selected, role],\n );\n }\n };\n\n const remove = (role: string) => {\n onChange(selected.filter((r) => r !== role));\n };\n\n const placeholderText = placeholder ?? (single ? 'Select role...' : 'Add roles...');\n\n return (\n <div ref={ref} className=\"relative\">\n {/* Selected pills + trigger */}\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((role) => (\n <span\n key={role}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px]\"\n >\n <User className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {role}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(role); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {/* Dropdown */}\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {allRoles.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No roles defined</p>\n ) : (\n allRoles.map((role) => {\n const isSelected = selected.includes(role);\n return (\n <button\n key={role}\n type=\"button\"\n onClick={() => toggle(role)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <User className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{role}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { Workflow, X, ChevronDown, Check } from 'lucide-react';\n\ninterface WorkflowPickerProps {\n options: string[];\n selected: string[];\n onChange: (workflows: string[]) => void;\n placeholder?: string;\n}\n\nexport function WorkflowPicker({ options, selected, onChange, placeholder }: WorkflowPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (wfType: string) => {\n onChange(\n selected.includes(wfType)\n ? selected.filter((t) => t !== wfType)\n : [...selected, wfType],\n );\n };\n\n const remove = (wfType: string) => {\n onChange(selected.filter((t) => t !== wfType));\n };\n\n const placeholderText = placeholder ?? 'Add workflows...';\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((wfType) => (\n <span\n key={wfType}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px] font-mono\"\n >\n <Workflow className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {wfType}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(wfType); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {options.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No registered workflows</p>\n ) : (\n options.map((wfType) => {\n const isSelected = selected.includes(wfType);\n return (\n <button\n key={wfType}\n type=\"button\"\n onClick={() => toggle(wfType)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs font-mono transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <Workflow className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{wfType}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","import { labelCls, hintCls, jsonCls, jsonValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { WorkflowPicker } from '../../../components/common/form/WorkflowPicker';\nimport { useWorkflowConfigs } from '../../../api/workflows';\nimport { splitCsv } from '../../../lib/parse';\n\ninterface StepProps {\n form: ConfigFormState;\n set: (field: keyof ConfigFormState, value: string | boolean) => void;\n}\n\nfunction csvToArray(csv: string): string[] {\n return splitCsv(csv);\n}\n\nfunction arrayToCsv(arr: string[]): string {\n return arr.join(', ');\n}\n\nexport function AdvancedStep({ form, set }: StepProps) {\n const { data: configs } = useWorkflowConfigs();\n const consumesOptions = (configs ?? [])\n .map((c) => c.workflow_type)\n .filter((t) => t !== form.workflow_type);\n\n return (\n <div className=\"space-y-5\">\n {/* Resolver Schema — always available */}\n <div>\n <label className={labelCls}>Resolver Schema</label>\n <textarea\n value={form.resolver_schema}\n onChange={(e) => set('resolver_schema', e.target.value)}\n placeholder={`{\\n \"properties\": {\\n \"approved\": { \"type\": \"boolean\", \"default\": false, \"description\": \"Approve?\" },\\n \"notes\": { \"type\": \"string\", \"default\": \"\", \"description\": \"Reviewer notes\" }\\n }\\n}`}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n <p className={hintCls}>\n Default form template for resolving escalations from this workflow.\n Use <span className=\"font-mono\">properties</span> with <span className=\"font-mono\">type</span>, <span className=\"font-mono\">default</span>, <span className=\"font-mono\">description</span>, <span className=\"font-mono\">enum</span>, and <span className=\"font-mono\">format</span> for typed form fields.\n </p>\n {form.resolver_schema.trim() && !jsonValid(form.resolver_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </div>\n\n {/* Certify toggle */}\n <div className=\"flex gap-6 pt-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.certified}\n onChange={(e) => set('certified', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Certify for HITL Escalation</span>\n </label>\n </div>\n <p className={hintCls}>\n Certified workflows use the interceptor to wrap executions — failures\n escalate to human reviewers instead of throwing.\n </p>\n\n {form.certified ? (\n <>\n {/* Default Escalation Role */}\n <div>\n <label className={labelCls}>Default Escalation Role</label>\n <RolePicker\n selected={csvToArray(form.default_role)}\n onChange={(roles) => set('default_role', roles[0] ?? '')}\n single\n placeholder=\"Select escalation role...\"\n />\n <p className={hintCls}>\n When this workflow escalates, assign to users with this role\n </p>\n </div>\n\n {/* Escalation Roles */}\n <div>\n <label className={labelCls}>Escalation Roles</label>\n <RolePicker\n selected={csvToArray(form.roles)}\n onChange={(roles) => set('roles', arrayToCsv(roles))}\n placeholder=\"Select who can resolve escalations...\"\n />\n <p className={hintCls}>\n Users with any of these roles can claim and resolve escalations from this workflow.\n </p>\n </div>\n\n {/* Consumes */}\n <div>\n <label className={labelCls}>Consumes</label>\n <WorkflowPicker\n options={consumesOptions}\n selected={csvToArray(form.consumes)}\n onChange={(workflows) => set('consumes', arrayToCsv(workflows))}\n placeholder=\"Select workflow dependencies...\"\n />\n <p className={hintCls}>\n Output from these upstream workflows will be injected into the input envelope for this workflow.\n </p>\n </div>\n </>\n ) : (\n <div className=\"py-4 px-4 bg-surface-sunken/50 rounded-md text-center\">\n <p className=\"text-xs text-text-tertiary\">\n This workflow will run as standard durable without the interceptor.\n Enable{' '}\n <span className=\"font-medium text-text-secondary\">\n Certify for HITL Escalation\n </span>{' '}\n to add automatic escalation routing and role-based resolution.\n </p>\n </div>\n )}\n </div>\n );\n}\n","import { labelCls, hintCls, jsonCls, jsonValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { splitCsv } from '../../../lib/parse';\nexport { AdvancedStep } from './AdvancedStep';\n\ninterface StepProps {\n form: ConfigFormState;\n set: (field: keyof ConfigFormState, value: string | boolean) => void;\n}\n\ninterface BasicsStepProps extends StepProps {\n editing: boolean;\n durableTypes?: string[];\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction csvToArray(csv: string): string[] {\n return splitCsv(csv);\n}\n\nfunction arrayToCsv(arr: string[]): string {\n return arr.join(', ');\n}\n\n// ── Step 1: Identity ────────────────────────────────────────────────────────\n\nexport function BasicsStep({ form, set, editing, durableTypes = [] }: BasicsStepProps) {\n const showPickList = !editing && durableTypes.length > 0;\n\n return (\n <div className=\"space-y-5\">\n <div>\n <label className={labelCls}>Workflow Type</label>\n {showPickList && !form.workflow_type ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-text-secondary\">\n Select a durable workflow to register:\n </p>\n <div className=\"grid gap-1\">\n {durableTypes.map((type) => (\n <button\n key={type}\n onClick={() => set('workflow_type', type)}\n className=\"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors\"\n >\n {type}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-2 pt-1\">\n <span className=\"text-[10px] text-text-tertiary\">or</span>\n <input\n type=\"text\"\n onChange={(e) => set('workflow_type', e.target.value)}\n placeholder=\"Enter a workflow type manually\"\n className=\"input font-mono flex-1\"\n />\n </div>\n </div>\n ) : (\n <>\n <input\n type=\"text\"\n value={form.workflow_type}\n onChange={(e) => set('workflow_type', e.target.value)}\n disabled={editing}\n placeholder=\"reviewContent\"\n className=\"input font-mono w-full\"\n />\n {!editing && form.workflow_type && durableTypes.length > 0 && (\n <button\n onClick={() => set('workflow_type', '')}\n className=\"text-[10px] text-accent hover:underline mt-1\"\n >\n Choose from durable workflows\n </button>\n )}\n </>\n )}\n <p className={hintCls}>\n Register a workflow to configure invocation schemas and dashboard visibility. Certification for HITL escalation is optional (step 3).\n </p>\n </div>\n\n <div>\n <label className={labelCls}>Description</label>\n <input\n type=\"text\"\n value={form.description}\n onChange={(e) => set('description', e.target.value)}\n placeholder=\"AI-powered content moderation with human escalation\"\n className=\"input text-xs w-full\"\n />\n </div>\n\n <div>\n <label className={labelCls}>Task Queue</label>\n <input\n type=\"text\"\n value={form.task_queue}\n onChange={(e) => set('task_queue', e.target.value)}\n placeholder=\"lt-review\"\n className=\"input font-mono w-full\"\n />\n <p className={hintCls}>\n Durable task queue this workflow listens on\n </p>\n </div>\n </div>\n );\n}\n\n// ── Step 2: Invocation ─────────────────────────────────────────────────────\n\nexport function InvocationStep({ form, set }: StepProps) {\n return (\n <div className=\"space-y-5\">\n {/* Invocable toggle */}\n <div className=\"flex gap-6 pt-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.invocable}\n onChange={(e) => set('invocable', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Invocable</span>\n </label>\n </div>\n <p className={hintCls}>\n Allow this workflow to be started from the dashboard or API.\n </p>\n\n {form.invocable && (\n <>\n {/* Run As */}\n <div>\n <label className={labelCls}>Run As</label>\n <BotPicker\n selected={form.execute_as}\n onChange={(botId) => set('execute_as', botId)}\n />\n <p className={hintCls}>\n Choose a bot to execute this workflow under its identity and credentials.\n Default runs as the invoking user.\n </p>\n </div>\n\n {/* Invocation roles */}\n <div>\n <label className={labelCls}>Invocation Roles</label>\n <RolePicker\n selected={csvToArray(form.invocation_roles)}\n onChange={(roles) => set('invocation_roles', arrayToCsv(roles))}\n placeholder=\"Select who can start this workflow...\"\n />\n <p className={hintCls}>\n Only users with these roles can start this workflow.\n Leave empty to allow all authenticated users.\n </p>\n </div>\n\n {/* Envelope schema */}\n <div>\n <label className={labelCls}>Envelope Schema</label>\n <textarea\n value={form.envelope_schema}\n onChange={(e) => set('envelope_schema', e.target.value)}\n placeholder={`{\\n \"data\": {\\n \"contentId\": \"example-123\",\\n \"content\": \"Text to review\"\\n },\\n \"metadata\": {\\n \"source\": \"dashboard\"\\n }\\n}`}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n <p className={hintCls}>\n Pre-fills the JSON editor when invoking this workflow.\n Should include <span className=\"font-mono\">data</span> (workflow input) and optional <span className=\"font-mono\">metadata</span> (context).\n </p>\n {form.envelope_schema.trim() && !jsonValid(form.envelope_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </div>\n </>\n )}\n\n {!form.invocable && (\n <div className=\"py-4 px-4 bg-surface-sunken/50 rounded-md text-center\">\n <p className=\"text-xs text-text-tertiary\">\n Enable <span className=\"font-medium text-text-secondary\">Invocable</span> above to configure who can start this workflow and set an input template.\n </p>\n </div>\n )}\n </div>\n );\n}\n\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport { useWorkflowConfigs, useUpsertWorkflowConfig, useJobs } from '../../../api/workflows';\nimport { StepIndicator } from '../../../components/common/layout/StepIndicator';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { splitCsv } from '../../../lib/parse';\nimport { EMPTY_FORM, configToForm, STEP_LABELS, isStepValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { BasicsStep, InvocationStep, AdvancedStep } from './ConfigWizardSteps';\n\nexport function WorkflowConfigDetailPage() {\n const { workflowType } = useParams<{ workflowType: string }>();\n const isNew = !workflowType;\n const navigate = useNavigate();\n const { data: configs, isLoading } = useWorkflowConfigs();\n const upsert = useUpsertWorkflowConfig();\n\n const editing = configs?.find((c) => c.workflow_type === workflowType) ?? null;\n\n // Fetch known workflow types from jobs to build the pick-list.\n // System workflows (triage, query, routing pipelines) are excluded —\n // they serve the discovery/compilation layer, not user-authored flows.\n const SYSTEM_WORKFLOWS = new Set([\n 'mcpQuery',\n 'mcpDeterministic',\n 'mcpQueryRouter',\n 'mcpTriage',\n 'mcpTriageRouter',\n 'mcpTriageDeterministic',\n 'insightQuery',\n ]);\n const { data: jobsData } = useJobs({ limit: 500 });\n const unregisteredTypes = useMemo(() => {\n const registeredSet = new Set((configs ?? []).map((c) => c.workflow_type));\n const allEntities = new Set((jobsData?.jobs ?? []).map((j) => j.entity));\n return [...allEntities]\n .filter((e) => !registeredSet.has(e) && !SYSTEM_WORKFLOWS.has(e))\n .sort();\n }, [configs, jobsData]);\n\n // Step via URL search param for browser history\n const [searchParams, setSearchParams] = useSearchParams();\n\n // Pre-fill from URL search params when creating new\n const prefillForm = useMemo((): ConfigFormState => {\n if (!isNew) return EMPTY_FORM;\n const prefillType = searchParams.get('workflow_type') ?? '';\n const prefillQueue = searchParams.get('task_queue') ?? '';\n if (!prefillType && !prefillQueue) return EMPTY_FORM;\n return { ...EMPTY_FORM, workflow_type: prefillType, task_queue: prefillQueue };\n }, [isNew, searchParams]);\n\n const [form, setForm] = useState<ConfigFormState>(prefillForm);\n const [schemaError, setSchemaError] = useState('');\n const [initialized, setInitialized] = useState(false);\n const step = parseInt(searchParams.get('step') || '1', 10);\n const setStep = useCallback((s: number) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set('step', String(s));\n return next;\n }, { replace: false });\n }, [setSearchParams]);\n\n\n useEffect(() => {\n if (initialized) return;\n if (isNew) {\n setForm(prefillForm);\n setInitialized(true);\n return;\n }\n if (editing) {\n setForm(configToForm(editing));\n setInitialized(true);\n }\n }, [editing, isNew, initialized, prefillForm]);\n\n const set = (field: keyof ConfigFormState, value: string | boolean) =>\n setForm((f) => ({ ...f, [field]: value }));\n\n // ── Save ────────────────────────────────────────────────────────────────\n\n const handleSave = () => {\n if (!form.workflow_type.trim()) return;\n setSchemaError('');\n\n let envelope_schema: Record<string, unknown> | null = null;\n let resolver_schema: Record<string, unknown> | null = null;\n\n try {\n if (form.envelope_schema.trim()) envelope_schema = JSON.parse(form.envelope_schema);\n } catch {\n setSchemaError('Invalid JSON in Envelope Schema');\n return;\n }\n try {\n if (form.resolver_schema.trim()) resolver_schema = JSON.parse(form.resolver_schema);\n } catch {\n setSchemaError('Invalid JSON in Resolver Schema');\n return;\n }\n\n upsert.mutate(\n {\n workflow_type: form.workflow_type.trim(),\n description: form.description.trim() || null,\n task_queue: form.task_queue.trim() || null,\n default_role: form.default_role.trim() || 'reviewer',\n invocable: form.invocable,\n roles: splitCsv(form.roles),\n invocation_roles: splitCsv(form.invocation_roles),\n consumes: splitCsv(form.consumes),\n envelope_schema,\n resolver_schema,\n cron_schedule: form.cron_schedule.trim() || null,\n execute_as: form.execute_as.trim() || null,\n },\n {\n onSuccess: () => {\n navigate('/workflows/registry');\n },\n },\n );\n };\n\n // ── Loading / Not found ──────────────────────────────────────────────────\n\n if (isLoading) {\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-60 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n if (!isNew && !editing) {\n return <p className=\"text-sm text-text-secondary\">Config not found.</p>;\n }\n\n // ── Render ──────────────────────────────────────────────────────────────\n\n const isLast = step === STEP_LABELS.length;\n return (\n <div>\n <PageHeader title={isNew ? 'Register Workflow' : editing?.workflow_type ?? ''} />\n\n <div className=\"max-w-3xl\">\n <StepIndicator steps={STEP_LABELS} currentStep={step - 1} onStepClick={(i) => setStep(i + 1)} />\n\n <div className=\"min-h-[360px] py-2\">\n {step === 1 && <BasicsStep form={form} set={set} editing={!!editing} durableTypes={unregisteredTypes} />}\n {step === 2 && <InvocationStep form={form} set={set} />}\n {step === 3 && <AdvancedStep form={form} set={set} />}\n </div>\n\n {(schemaError || upsert.error) && (\n <p className=\"text-xs text-status-error mt-4\">\n {schemaError || (upsert.error as Error).message}\n </p>\n )}\n\n {/* Navigation */}\n <div className=\"flex justify-between items-center pt-4 border-t border-surface-border mt-4\">\n <div>\n {step > 1 && (\n <button\n onClick={() => setStep(step - 1)}\n className=\"btn-secondary text-xs\"\n >\n Back\n </button>\n )}\n </div>\n <div className=\"flex gap-3\">\n <button onClick={() => navigate('/workflows/registry')} className=\"btn-ghost text-xs\">\n Cancel\n </button>\n {isLast ? (\n <button\n onClick={handleSave}\n disabled={!isStepValid(step, form) || upsert.isPending}\n className=\"btn-primary text-xs\"\n >\n {upsert.isPending ? 'Saving...' : editing ? 'Save' : 'Create'}\n </button>\n ) : (\n <button\n onClick={() => setStep(step + 1)}\n disabled={!isStepValid(step, form)}\n className=\"btn-primary text-xs\"\n >\n Next\n </button>\n )}\n </div>\n </div>\n\n </div>\n </div>\n );\n}\n"],"names":["matchesSearch","wf","search","q","WorkflowConfigsPage","navigate","useNavigate","data","isLoading","useDiscoveredWorkflows","deleteConfig","useDeleteWorkflowConfig","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","confirmDelete","setConfirmDelete","useEffect","timer","allWorkflows","queues","useMemo","w","roles","workflows","result","columns","row","jsxs","jsx","WorkflowPill","TaskQueuePill","ShieldCheck","Settings","Wrench","escRoles","invokeRoles","r","RolePill","UserCheck","RowActionGroup","RowAction","Play","ShieldPlus","ShieldOff","handleDelete","handleRowClick","PageHeader","FilterBar","e","FilterSelect","v","DataTable","ConfirmDeleteModal","Fragment","splitCsv","s","EMPTY_FORM","configToForm","c","consumes","STEP_LABELS","jsonValid","isStepValid","step","form","labelCls","hintCls","jsonCls","RolePicker","selected","onChange","single","placeholder","useRoles","allRoles","open","setOpen","ref","useRef","handler","toggle","role","remove","placeholderText","User","X","ChevronDown","isSelected","Check","WorkflowPicker","options","wfType","t","Workflow","csvToArray","csv","arrayToCsv","arr","AdvancedStep","set","configs","useWorkflowConfigs","consumesOptions","BasicsStep","editing","durableTypes","showPickList","type","InvocationStep","BotPicker","botId","WorkflowConfigDetailPage","workflowType","useParams","isNew","upsert","useUpsertWorkflowConfig","SYSTEM_WORKFLOWS","jobsData","useJobs","unregisteredTypes","registeredSet","j","searchParams","setSearchParams","useSearchParams","prefillForm","prefillType","prefillQueue","setForm","schemaError","setSchemaError","initialized","setInitialized","setStep","useCallback","prev","next","field","value","f","handleSave","envelope_schema","resolver_schema","isLast","StepIndicator","i"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-Dig8_eMS.js","sources":["../../src/pages/workflows/registry/WorkflowConfigsPage.tsx","../../src/lib/parse.ts","../../src/pages/workflows/registry/config-form-types.ts","../../src/components/common/form/RolePicker.tsx","../../src/components/common/form/WorkflowPicker.tsx","../../src/pages/workflows/registry/AdvancedStep.tsx","../../src/pages/workflows/registry/ConfigWizardSteps.tsx","../../src/pages/workflows/registry/WorkflowConfigDetailPage.tsx"],"sourcesContent":["import { useState, useEffect, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n useDiscoveredWorkflows,\n useDeleteWorkflowConfig,\n} from '../../../api/workflows';\nimport { ShieldCheck, ShieldPlus, ShieldOff, Settings, Wrench, Play, UserCheck } from 'lucide-react';\nimport { DataTable, type Column } from '../../../components/common/data/DataTable';\nimport { ConfirmDeleteModal } from '../../../components/common/modal/ConfirmDeleteModal';\nimport { FilterBar, FilterSelect } from '../../../components/common/data/FilterBar';\nimport { RowAction, RowActionGroup } from '../../../components/common/layout/RowActions';\nimport { useFilterParams } from '../../../hooks/useFilterParams';\nimport type { DiscoveredWorkflow } from '../../../api/types';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { RolePill } from '../../../components/common/display/RolePill';\nimport { TaskQueuePill } from '../../../components/common/display/TaskQueuePill';\nimport { WorkflowPill } from '../../../components/common/display/WorkflowPill';\n\n// ── Helpers ───────────────────────────────────────────────────────────────────\n\nfunction matchesSearch(wf: DiscoveredWorkflow, search: string): boolean {\n const q = search.toLowerCase();\n return (\n wf.workflow_type.toLowerCase().includes(q) ||\n (wf.description ?? '').toLowerCase().includes(q)\n );\n}\n\n// ── Page ──────────────────────────────────────────────────────────────────────\n\nexport function WorkflowConfigsPage() {\n const navigate = useNavigate();\n const { data, isLoading } = useDiscoveredWorkflows();\n const deleteConfig = useDeleteWorkflowConfig();\n const { filters, setFilter } = useFilterParams({\n filters: { search: '', queue: '', role: '', tier: '' },\n });\n\n const [searchInput, setSearchInput] = useState(filters.search);\n const [confirmDelete, setConfirmDelete] = useState<string | null>(null);\n\n // Debounce search input\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 allWorkflows = data ?? [];\n\n // Derive facet options from data\n const queues = useMemo(\n () => [...new Set(allWorkflows.map((w) => w.task_queue).filter(Boolean) as string[])].sort(),\n [allWorkflows],\n );\n const roles = useMemo(\n () => [...new Set(allWorkflows.flatMap((w) => w.roles ?? []))].sort(),\n [allWorkflows],\n );\n\n // Apply client-side filters\n const workflows = useMemo(() => {\n let result = allWorkflows;\n if (filters.search) result = result.filter((w) => matchesSearch(w, filters.search));\n if (filters.queue) result = result.filter((w) => w.task_queue === filters.queue);\n if (filters.role) result = result.filter((w) => (w.roles ?? []).includes(filters.role));\n if (filters.tier) result = result.filter((w) => w.tier === filters.tier);\n return result;\n }, [allWorkflows, filters]);\n\n const columns: Column<DiscoveredWorkflow>[] = [\n {\n key: 'workflow_type',\n label: 'Workflow',\n className: 'max-w-xs',\n render: (row) => (\n <div className=\"min-w-0\">\n <WorkflowPill type={row.workflow_type} size=\"md\" variant={row.tier === 'certified' ? 'certified' : row.tier === 'configured' ? 'configured' : 'durable'} />\n {row.description && (\n <p className=\"text-[10px] leading-tight text-text-quaternary mt-0.5\">{row.description}</p>\n )}\n </div>\n ),\n },\n {\n key: 'task_queue',\n label: 'Queue',\n render: (row) => row.task_queue ? <TaskQueuePill queue={row.task_queue} /> : <span className=\"text-xs text-text-tertiary\">—</span>,\n className: 'whitespace-nowrap',\n },\n {\n key: 'tier',\n label: 'Tier',\n render: (row) => {\n if (row.tier === 'certified') return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><ShieldCheck className=\"w-3 h-3\" />Certified</span>;\n if (row.tier === 'configured') return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><Settings className=\"w-3 h-3\" />Configured</span>;\n return <span className=\"inline-flex items-center gap-1 text-[10px] font-medium text-text-secondary\"><Wrench className=\"w-3 h-3\" />Durable</span>;\n },\n className: 'whitespace-nowrap',\n },\n {\n key: 'roles',\n label: 'Access',\n render: (row) => {\n if (!row.registered) return <span className=\"text-xs text-text-tertiary\">—</span>;\n const escRoles = row.roles ?? [];\n const invokeRoles = row.invocation_roles ?? [];\n if (!escRoles.length && !invokeRoles.length) return <span className=\"text-xs text-text-tertiary\">—</span>;\n return (\n <div className=\"space-y-1.5\">\n {escRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <span title=\"Escalation roles\"><ShieldCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n <div className=\"flex gap-1 flex-wrap\">{escRoles.map((r) => <RolePill key={`e-${r}`} role={r} />)}</div>\n </div>\n )}\n {invokeRoles.length > 0 && (\n <div className=\"flex items-center gap-1.5\">\n <span title=\"Invocation roles\"><UserCheck className=\"w-3 h-3 text-text-quaternary shrink-0\" /></span>\n <div className=\"flex gap-1 flex-wrap\">{invokeRoles.map((r) => <RolePill key={`i-${r}`} role={r} />)}</div>\n </div>\n )}\n </div>\n );\n },\n },\n {\n key: 'actions',\n label: '',\n render: (row) => (\n <RowActionGroup>\n {row.invocable && (\n <RowAction\n icon={Play}\n title=\"Invoke workflow\"\n onClick={() => navigate(`/workflows/start?type=${encodeURIComponent(row.workflow_type)}&mode=now`)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )}\n {row.tier === 'durable' && (\n <RowAction\n icon={Wrench}\n title=\"Configure workflow\"\n onClick={() => navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`)}\n colorClass=\"text-text-tertiary hover:text-status-info\"\n />\n )}\n {row.tier === 'configured' && (\n <RowAction\n icon={ShieldPlus}\n title=\"Certify workflow\"\n onClick={() => navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`)}\n colorClass=\"text-text-tertiary hover:text-status-success\"\n />\n )}\n {row.registered && (\n <RowAction\n icon={ShieldOff}\n title=\"Remove configuration\"\n onClick={() => setConfirmDelete(row.workflow_type)}\n colorClass=\"text-text-tertiary hover:text-status-warning\"\n />\n )}\n </RowActionGroup>\n ),\n className: 'w-16 text-right',\n },\n ];\n\n const handleDelete = () => {\n if (!confirmDelete) return;\n deleteConfig.mutate(confirmDelete, {\n onSuccess: () => setConfirmDelete(null),\n });\n };\n\n const handleRowClick = (row: DiscoveredWorkflow) => {\n if (row.registered) {\n navigate(`/workflows/registry/${encodeURIComponent(row.workflow_type)}`);\n } else {\n navigate(`/workflows/registry/new?workflow_type=${encodeURIComponent(row.workflow_type)}&task_queue=${encodeURIComponent(row.task_queue ?? '')}`);\n }\n };\n\n return (\n <div>\n <PageHeader\n title=\"Workflow Registry\"\n docsHash=\"#docs:dashboard.md:workflow-registry\"\n actions={\n <button\n onClick={() => navigate('/workflows/registry/new')}\n className=\"btn-primary text-xs\"\n >\n Register Workflow\n </button>\n }\n />\n\n <FilterBar>\n <input\n type=\"text\"\n placeholder=\"Search workflow type...\"\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 <FilterSelect\n label=\"Tier\"\n value={filters.tier}\n onChange={(v) => setFilter('tier', v)}\n options={[\n { value: 'certified', label: 'Certified' },\n { value: 'configured', label: 'Configured' },\n { value: 'durable', label: 'Durable' },\n ]}\n />\n <FilterSelect\n label=\"Role\"\n value={filters.role}\n onChange={(v) => setFilter('role', v)}\n options={roles.map((r) => ({ value: r, label: r }))}\n />\n </FilterBar>\n\n <DataTable\n columns={columns}\n data={workflows}\n keyFn={(row) => row.workflow_type}\n onRowClick={handleRowClick}\n isLoading={isLoading}\n emptyMessage=\"No workflows found\"\n />\n\n {/* Delete confirmation modal */}\n <ConfirmDeleteModal\n open={!!confirmDelete}\n onClose={() => setConfirmDelete(null)}\n onConfirm={handleDelete}\n title=\"De-certify Workflow\"\n description={<>Remove certification from <span className=\"font-mono font-medium text-text-primary\">{confirmDelete}</span>? This removes interceptor guarantees, escalation chains, and invocation role constraints. The workflow will continue running as a standard durable workflow.</>}\n isPending={deleteConfig.isPending}\n error={deleteConfig.error as Error | null}\n />\n </div>\n );\n}\n","export function splitCsv(s: string): string[] {\n return s\n .split(',')\n .map((v) => v.trim())\n .filter(Boolean);\n}\n\nexport function safeParseJson<T = unknown>(\n json: string,\n): { ok: true; data: T } | { ok: false; error: string } {\n try {\n return { ok: true, data: JSON.parse(json) as T };\n } catch (e: unknown) {\n const message = e instanceof Error ? e.message : 'Invalid JSON';\n return { ok: false, error: message };\n }\n}\n","import type { LTWorkflowConfig } from '../../../api/types';\n\nexport interface ConfigFormState {\n workflow_type: string;\n description: string;\n task_queue: string;\n default_role: string;\n invocable: boolean;\n roles: string;\n invocation_roles: string;\n consumes: string;\n envelope_schema: string;\n resolver_schema: string;\n cron_schedule: string;\n execute_as: string;\n /** UI-only — gates escalation fields in the wizard. Not sent to backend. */\n certified: boolean;\n}\n\nexport const EMPTY_FORM: ConfigFormState = {\n workflow_type: '',\n description: '',\n task_queue: '',\n default_role: 'reviewer',\n invocable: false,\n roles: '',\n invocation_roles: '',\n consumes: '',\n envelope_schema: '',\n resolver_schema: '',\n cron_schedule: '',\n execute_as: '',\n certified: false,\n};\n\nexport function configToForm(c: LTWorkflowConfig): ConfigFormState {\n const roles = (c.roles ?? []).join(', ');\n const consumes = (c.consumes ?? []).join(', ');\n return {\n workflow_type: c.workflow_type,\n description: c.description ?? '',\n task_queue: c.task_queue ?? '',\n default_role: c.default_role,\n invocable: c.invocable,\n roles,\n invocation_roles: (c.invocation_roles ?? []).join(', '),\n consumes,\n envelope_schema: c.envelope_schema ? JSON.stringify(c.envelope_schema, null, 2) : '',\n resolver_schema: c.resolver_schema ? JSON.stringify(c.resolver_schema, null, 2) : '',\n cron_schedule: c.cron_schedule ?? '',\n execute_as: c.execute_as ?? '',\n certified: !!(roles || consumes),\n };\n}\n\nexport const STEP_LABELS = ['Identity', 'Invocation', 'Advanced'];\n\nexport function jsonValid(v: string): boolean {\n if (!v.trim()) return true;\n try { JSON.parse(v); return true; } catch { return false; }\n}\n\nexport function isStepValid(step: number, form: ConfigFormState): boolean {\n if (step === 1) return !!form.workflow_type.trim();\n if (step === 2) return jsonValid(form.envelope_schema);\n if (step === 3) return jsonValid(form.resolver_schema);\n return true;\n}\n\nexport const labelCls = 'label';\nexport const hintCls = 'hint';\nexport const jsonCls = 'input-json w-full';\n\nexport const DEFAULT_ENVELOPE = '{\\n \"data\": {},\\n \"metadata\": {}\\n}';\n","import { useState, useRef, useEffect } from 'react';\nimport { User, X, ChevronDown, Check } from 'lucide-react';\nimport { useRoles } from '../../../api/roles';\n\ninterface RolePickerProps {\n selected: string[];\n onChange: (roles: string[]) => void;\n /** Only allow one selection */\n single?: boolean;\n placeholder?: string;\n}\n\nexport function RolePicker({ selected, onChange, single, placeholder }: RolePickerProps) {\n const { data } = useRoles();\n const allRoles = data?.roles ?? [];\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (role: string) => {\n if (single) {\n onChange(selected.includes(role) ? [] : [role]);\n setOpen(false);\n } else {\n onChange(\n selected.includes(role)\n ? selected.filter((r) => r !== role)\n : [...selected, role],\n );\n }\n };\n\n const remove = (role: string) => {\n onChange(selected.filter((r) => r !== role));\n };\n\n const placeholderText = placeholder ?? (single ? 'Select role...' : 'Add roles...');\n\n return (\n <div ref={ref} className=\"relative\">\n {/* Selected pills + trigger */}\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((role) => (\n <span\n key={role}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px]\"\n >\n <User className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {role}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(role); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {/* Dropdown */}\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {allRoles.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No roles defined</p>\n ) : (\n allRoles.map((role) => {\n const isSelected = selected.includes(role);\n return (\n <button\n key={role}\n type=\"button\"\n onClick={() => toggle(role)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <User className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{role}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useRef, useEffect } from 'react';\nimport { Workflow, X, ChevronDown, Check } from 'lucide-react';\n\ninterface WorkflowPickerProps {\n options: string[];\n selected: string[];\n onChange: (workflows: string[]) => void;\n placeholder?: string;\n}\n\nexport function WorkflowPicker({ options, selected, onChange, placeholder }: WorkflowPickerProps) {\n const [open, setOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, []);\n\n const toggle = (wfType: string) => {\n onChange(\n selected.includes(wfType)\n ? selected.filter((t) => t !== wfType)\n : [...selected, wfType],\n );\n };\n\n const remove = (wfType: string) => {\n onChange(selected.filter((t) => t !== wfType));\n };\n\n const placeholderText = placeholder ?? 'Add workflows...';\n\n return (\n <div ref={ref} className=\"relative\">\n <button\n type=\"button\"\n onClick={() => setOpen(!open)}\n className=\"flex flex-wrap items-center gap-1.5 w-full min-h-[34px] px-2 py-1.5 bg-surface-sunken border border-surface-border rounded-md text-left cursor-pointer hover:border-accent/40 transition-colors focus:ring-1 focus:ring-accent focus:outline-none\"\n >\n {selected.length === 0 && (\n <span className=\"text-xs text-text-tertiary\">{placeholderText}</span>\n )}\n {selected.map((wfType) => (\n <span\n key={wfType}\n className=\"inline-flex items-center gap-1 px-2 py-0.5 rounded-lg bg-accent/[0.08] text-text-secondary text-[11px] font-mono\"\n >\n <Workflow className=\"w-2.5 h-2.5 shrink-0 text-accent/75\" />\n {wfType}\n <span\n role=\"button\"\n onClick={(e) => { e.stopPropagation(); remove(wfType); }}\n className=\"ml-0.5 hover:text-status-error transition-colors\"\n >\n <X className=\"w-2.5 h-2.5\" />\n </span>\n </span>\n ))}\n <ChevronDown className={`w-3.5 h-3.5 ml-auto shrink-0 text-text-tertiary transition-transform ${open ? 'rotate-180' : ''}`} />\n </button>\n\n {open && (\n <div className=\"absolute z-20 mt-1 w-full bg-white border border-surface-border rounded-md shadow-lg max-h-48 overflow-y-auto\">\n {options.length === 0 ? (\n <p className=\"px-3 py-2 text-xs text-text-tertiary\">No registered workflows</p>\n ) : (\n options.map((wfType) => {\n const isSelected = selected.includes(wfType);\n return (\n <button\n key={wfType}\n type=\"button\"\n onClick={() => toggle(wfType)}\n className={`flex items-center gap-2 w-full px-3 py-1.5 text-left text-xs font-mono transition-colors ${\n isSelected\n ? 'bg-accent/[0.06] text-accent'\n : 'text-text-primary hover:bg-surface-sunken'\n }`}\n >\n <Workflow className=\"w-3 h-3 shrink-0 text-accent/60\" />\n <span className=\"flex-1\">{wfType}</span>\n {isSelected && <Check className=\"w-3 h-3 shrink-0\" />}\n </button>\n );\n })\n )}\n </div>\n )}\n </div>\n );\n}\n","import { labelCls, hintCls, jsonCls, jsonValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { WorkflowPicker } from '../../../components/common/form/WorkflowPicker';\nimport { useWorkflowConfigs } from '../../../api/workflows';\nimport { splitCsv } from '../../../lib/parse';\n\ninterface StepProps {\n form: ConfigFormState;\n set: (field: keyof ConfigFormState, value: string | boolean) => void;\n}\n\nfunction csvToArray(csv: string): string[] {\n return splitCsv(csv);\n}\n\nfunction arrayToCsv(arr: string[]): string {\n return arr.join(', ');\n}\n\nexport function AdvancedStep({ form, set }: StepProps) {\n const { data: configs } = useWorkflowConfigs();\n const consumesOptions = (configs ?? [])\n .map((c) => c.workflow_type)\n .filter((t) => t !== form.workflow_type);\n\n return (\n <div className=\"space-y-5\">\n {/* Resolver Schema — always available */}\n <div>\n <label className={labelCls}>Resolver Schema</label>\n <textarea\n value={form.resolver_schema}\n onChange={(e) => set('resolver_schema', e.target.value)}\n placeholder={`{\\n \"properties\": {\\n \"approved\": { \"type\": \"boolean\", \"default\": false, \"description\": \"Approve?\" },\\n \"notes\": { \"type\": \"string\", \"default\": \"\", \"description\": \"Reviewer notes\" }\\n }\\n}`}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n <p className={hintCls}>\n Default form template for resolving escalations from this workflow.\n Use <span className=\"font-mono\">properties</span> with <span className=\"font-mono\">type</span>, <span className=\"font-mono\">default</span>, <span className=\"font-mono\">description</span>, <span className=\"font-mono\">enum</span>, and <span className=\"font-mono\">format</span> for typed form fields.\n </p>\n {form.resolver_schema.trim() && !jsonValid(form.resolver_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </div>\n\n {/* Certify toggle */}\n <div className=\"flex gap-6 pt-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.certified}\n onChange={(e) => set('certified', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Certify for HITL Escalation</span>\n </label>\n </div>\n <p className={hintCls}>\n Certified workflows use the interceptor to wrap executions — failures\n escalate to human reviewers instead of throwing.\n </p>\n\n {form.certified ? (\n <>\n {/* Default Escalation Role */}\n <div>\n <label className={labelCls}>Default Escalation Role</label>\n <RolePicker\n selected={csvToArray(form.default_role)}\n onChange={(roles) => set('default_role', roles[0] ?? '')}\n single\n placeholder=\"Select escalation role...\"\n />\n <p className={hintCls}>\n When this workflow escalates, assign to users with this role\n </p>\n </div>\n\n {/* Escalation Roles */}\n <div>\n <label className={labelCls}>Escalation Roles</label>\n <RolePicker\n selected={csvToArray(form.roles)}\n onChange={(roles) => set('roles', arrayToCsv(roles))}\n placeholder=\"Select who can resolve escalations...\"\n />\n <p className={hintCls}>\n Users with any of these roles can claim and resolve escalations from this workflow.\n </p>\n </div>\n\n {/* Consumes */}\n <div>\n <label className={labelCls}>Consumes</label>\n <WorkflowPicker\n options={consumesOptions}\n selected={csvToArray(form.consumes)}\n onChange={(workflows) => set('consumes', arrayToCsv(workflows))}\n placeholder=\"Select workflow dependencies...\"\n />\n <p className={hintCls}>\n Output from these upstream workflows will be injected into the input envelope for this workflow.\n </p>\n </div>\n </>\n ) : (\n <div className=\"py-4 px-4 bg-surface-sunken/50 rounded-md text-center\">\n <p className=\"text-xs text-text-tertiary\">\n This workflow will run as standard durable without the interceptor.\n Enable{' '}\n <span className=\"font-medium text-text-secondary\">\n Certify for HITL Escalation\n </span>{' '}\n to add automatic escalation routing and role-based resolution.\n </p>\n </div>\n )}\n </div>\n );\n}\n","import { labelCls, hintCls, jsonCls, jsonValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { RolePicker } from '../../../components/common/form/RolePicker';\nimport { BotPicker } from '../../../components/common/form/BotPicker';\nimport { splitCsv } from '../../../lib/parse';\nexport { AdvancedStep } from './AdvancedStep';\n\ninterface StepProps {\n form: ConfigFormState;\n set: (field: keyof ConfigFormState, value: string | boolean) => void;\n}\n\ninterface BasicsStepProps extends StepProps {\n editing: boolean;\n durableTypes?: string[];\n}\n\n// ── Helpers ────────────────────────────────────────────────────────────────────\n\nfunction csvToArray(csv: string): string[] {\n return splitCsv(csv);\n}\n\nfunction arrayToCsv(arr: string[]): string {\n return arr.join(', ');\n}\n\n// ── Step 1: Identity ────────────────────────────────────────────────────────\n\nexport function BasicsStep({ form, set, editing, durableTypes = [] }: BasicsStepProps) {\n const showPickList = !editing && durableTypes.length > 0;\n\n return (\n <div className=\"space-y-5\">\n <div>\n <label className={labelCls}>Workflow Type</label>\n {showPickList && !form.workflow_type ? (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-text-secondary\">\n Select a durable workflow to register:\n </p>\n <div className=\"grid gap-1\">\n {durableTypes.map((type) => (\n <button\n key={type}\n onClick={() => set('workflow_type', type)}\n className=\"flex items-center gap-2 px-3 py-2 text-left text-xs font-mono rounded-md border border-surface-border hover:border-accent/50 hover:bg-accent/[0.04] transition-colors\"\n >\n {type}\n </button>\n ))}\n </div>\n <div className=\"flex items-center gap-2 pt-1\">\n <span className=\"text-[10px] text-text-tertiary\">or</span>\n <input\n type=\"text\"\n onChange={(e) => set('workflow_type', e.target.value)}\n placeholder=\"Enter a workflow type manually\"\n className=\"input font-mono flex-1\"\n />\n </div>\n </div>\n ) : (\n <>\n <input\n type=\"text\"\n value={form.workflow_type}\n onChange={(e) => set('workflow_type', e.target.value)}\n disabled={editing}\n placeholder=\"reviewContent\"\n className=\"input font-mono w-full\"\n />\n {!editing && form.workflow_type && durableTypes.length > 0 && (\n <button\n onClick={() => set('workflow_type', '')}\n className=\"text-[10px] text-accent hover:underline mt-1\"\n >\n Choose from durable workflows\n </button>\n )}\n </>\n )}\n <p className={hintCls}>\n Register a workflow to configure invocation schemas and dashboard visibility. Certification for HITL escalation is optional (step 3).\n </p>\n </div>\n\n <div>\n <label className={labelCls}>Description</label>\n <input\n type=\"text\"\n value={form.description}\n onChange={(e) => set('description', e.target.value)}\n placeholder=\"AI-powered content moderation with human escalation\"\n className=\"input text-xs w-full\"\n />\n </div>\n\n <div>\n <label className={labelCls}>Task Queue</label>\n <input\n type=\"text\"\n value={form.task_queue}\n onChange={(e) => set('task_queue', e.target.value)}\n placeholder=\"lt-review\"\n className=\"input font-mono w-full\"\n />\n <p className={hintCls}>\n Durable task queue this workflow listens on\n </p>\n </div>\n </div>\n );\n}\n\n// ── Step 2: Invocation ─────────────────────────────────────────────────────\n\nexport function InvocationStep({ form, set }: StepProps) {\n return (\n <div className=\"space-y-5\">\n {/* Invocable toggle */}\n <div className=\"flex gap-6 pt-1\">\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input\n type=\"checkbox\"\n checked={form.invocable}\n onChange={(e) => set('invocable', e.target.checked)}\n className=\"w-4 h-4 rounded border-border accent-accent\"\n />\n <span className=\"text-xs text-text-primary font-medium\">Invocable</span>\n </label>\n </div>\n <p className={hintCls}>\n Allow this workflow to be started from the dashboard or API.\n </p>\n\n {form.invocable && (\n <>\n {/* Run As */}\n <div>\n <label className={labelCls}>Run As</label>\n <BotPicker\n selected={form.execute_as}\n onChange={(botId) => set('execute_as', botId)}\n />\n <p className={hintCls}>\n Choose a bot to execute this workflow under its identity and credentials.\n Default runs as the invoking user.\n </p>\n </div>\n\n {/* Invocation roles */}\n <div>\n <label className={labelCls}>Invocation Roles</label>\n <RolePicker\n selected={csvToArray(form.invocation_roles)}\n onChange={(roles) => set('invocation_roles', arrayToCsv(roles))}\n placeholder=\"Select who can start this workflow...\"\n />\n <p className={hintCls}>\n Only users with these roles can start this workflow.\n Leave empty to allow all authenticated users.\n </p>\n </div>\n\n {/* Envelope schema */}\n <div>\n <label className={labelCls}>Envelope Schema</label>\n <textarea\n value={form.envelope_schema}\n onChange={(e) => set('envelope_schema', e.target.value)}\n placeholder={`{\\n \"data\": {\\n \"contentId\": \"example-123\",\\n \"content\": \"Text to review\"\\n },\\n \"metadata\": {\\n \"source\": \"dashboard\"\\n }\\n}`}\n className={jsonCls}\n rows={8}\n spellCheck={false}\n />\n <p className={hintCls}>\n Pre-fills the JSON editor when invoking this workflow.\n Should include <span className=\"font-mono\">data</span> (workflow input) and optional <span className=\"font-mono\">metadata</span> (context).\n </p>\n {form.envelope_schema.trim() && !jsonValid(form.envelope_schema) && (\n <p className=\"text-[10px] text-status-error mt-1\">Invalid JSON</p>\n )}\n </div>\n </>\n )}\n\n {!form.invocable && (\n <div className=\"py-4 px-4 bg-surface-sunken/50 rounded-md text-center\">\n <p className=\"text-xs text-text-tertiary\">\n Enable <span className=\"font-medium text-text-secondary\">Invocable</span> above to configure who can start this workflow and set an input template.\n </p>\n </div>\n )}\n </div>\n );\n}\n\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useParams, useNavigate, useSearchParams } from 'react-router-dom';\nimport { useWorkflowConfigs, useUpsertWorkflowConfig, useJobs } from '../../../api/workflows';\nimport { StepIndicator } from '../../../components/common/layout/StepIndicator';\nimport { PageHeader } from '../../../components/common/layout/PageHeader';\nimport { splitCsv } from '../../../lib/parse';\nimport { EMPTY_FORM, configToForm, STEP_LABELS, isStepValid } from './config-form-types';\nimport type { ConfigFormState } from './config-form-types';\nimport { BasicsStep, InvocationStep, AdvancedStep } from './ConfigWizardSteps';\n\nexport function WorkflowConfigDetailPage() {\n const { workflowType } = useParams<{ workflowType: string }>();\n const isNew = !workflowType;\n const navigate = useNavigate();\n const { data: configs, isLoading } = useWorkflowConfigs();\n const upsert = useUpsertWorkflowConfig();\n\n const editing = configs?.find((c) => c.workflow_type === workflowType) ?? null;\n\n // Fetch known workflow types from jobs to build the pick-list.\n // System workflows (triage, query, routing pipelines) are excluded —\n // they serve the discovery/compilation layer, not user-authored flows.\n const SYSTEM_WORKFLOWS = new Set([\n 'mcpQuery',\n 'mcpDeterministic',\n 'mcpQueryRouter',\n 'mcpTriage',\n 'mcpTriageRouter',\n 'mcpTriageDeterministic',\n 'insightQuery',\n ]);\n const { data: jobsData } = useJobs({ limit: 500 });\n const unregisteredTypes = useMemo(() => {\n const registeredSet = new Set((configs ?? []).map((c) => c.workflow_type));\n const allEntities = new Set((jobsData?.jobs ?? []).map((j) => j.entity));\n return [...allEntities]\n .filter((e) => !registeredSet.has(e) && !SYSTEM_WORKFLOWS.has(e))\n .sort();\n }, [configs, jobsData]);\n\n // Step via URL search param for browser history\n const [searchParams, setSearchParams] = useSearchParams();\n\n // Pre-fill from URL search params when creating new\n const prefillForm = useMemo((): ConfigFormState => {\n if (!isNew) return EMPTY_FORM;\n const prefillType = searchParams.get('workflow_type') ?? '';\n const prefillQueue = searchParams.get('task_queue') ?? '';\n if (!prefillType && !prefillQueue) return EMPTY_FORM;\n return { ...EMPTY_FORM, workflow_type: prefillType, task_queue: prefillQueue };\n }, [isNew, searchParams]);\n\n const [form, setForm] = useState<ConfigFormState>(prefillForm);\n const [schemaError, setSchemaError] = useState('');\n const [initialized, setInitialized] = useState(false);\n const step = parseInt(searchParams.get('step') || '1', 10);\n const setStep = useCallback((s: number) => {\n setSearchParams((prev) => {\n const next = new URLSearchParams(prev);\n next.set('step', String(s));\n return next;\n }, { replace: false });\n }, [setSearchParams]);\n\n\n useEffect(() => {\n if (initialized) return;\n if (isNew) {\n setForm(prefillForm);\n setInitialized(true);\n return;\n }\n if (editing) {\n setForm(configToForm(editing));\n setInitialized(true);\n }\n }, [editing, isNew, initialized, prefillForm]);\n\n const set = (field: keyof ConfigFormState, value: string | boolean) =>\n setForm((f) => ({ ...f, [field]: value }));\n\n // ── Save ────────────────────────────────────────────────────────────────\n\n const handleSave = () => {\n if (!form.workflow_type.trim()) return;\n setSchemaError('');\n\n let envelope_schema: Record<string, unknown> | null = null;\n let resolver_schema: Record<string, unknown> | null = null;\n\n try {\n if (form.envelope_schema.trim()) envelope_schema = JSON.parse(form.envelope_schema);\n } catch {\n setSchemaError('Invalid JSON in Envelope Schema');\n return;\n }\n try {\n if (form.resolver_schema.trim()) resolver_schema = JSON.parse(form.resolver_schema);\n } catch {\n setSchemaError('Invalid JSON in Resolver Schema');\n return;\n }\n\n upsert.mutate(\n {\n workflow_type: form.workflow_type.trim(),\n description: form.description.trim() || null,\n task_queue: form.task_queue.trim() || null,\n default_role: form.default_role.trim() || 'reviewer',\n invocable: form.invocable,\n roles: splitCsv(form.roles),\n invocation_roles: splitCsv(form.invocation_roles),\n consumes: splitCsv(form.consumes),\n envelope_schema,\n resolver_schema,\n cron_schedule: form.cron_schedule.trim() || null,\n execute_as: form.execute_as.trim() || null,\n },\n {\n onSuccess: () => {\n navigate('/workflows/registry');\n },\n },\n );\n };\n\n // ── Loading / Not found ──────────────────────────────────────────────────\n\n if (isLoading) {\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-60 bg-surface-sunken rounded\" />\n </div>\n );\n }\n\n if (!isNew && !editing) {\n return <p className=\"text-sm text-text-secondary\">Config not found.</p>;\n }\n\n // ── Render ──────────────────────────────────────────────────────────────\n\n const isLast = step === STEP_LABELS.length;\n return (\n <div>\n <PageHeader title={isNew ? 'Register Workflow' : editing?.workflow_type ?? ''} />\n\n <div className=\"max-w-3xl\">\n <StepIndicator steps={STEP_LABELS} currentStep={step - 1} onStepClick={(i) => setStep(i + 1)} />\n\n <div className=\"min-h-[360px] py-2\">\n {step === 1 && <BasicsStep form={form} set={set} editing={!!editing} durableTypes={unregisteredTypes} />}\n {step === 2 && <InvocationStep form={form} set={set} />}\n {step === 3 && <AdvancedStep form={form} set={set} />}\n </div>\n\n {(schemaError || upsert.error) && (\n <p className=\"text-xs text-status-error mt-4\">\n {schemaError || (upsert.error as Error).message}\n </p>\n )}\n\n {/* Navigation */}\n <div className=\"flex justify-between items-center pt-4 border-t border-surface-border mt-4\">\n <div>\n {step > 1 && (\n <button\n onClick={() => setStep(step - 1)}\n className=\"btn-secondary text-xs\"\n >\n Back\n </button>\n )}\n </div>\n <div className=\"flex gap-3\">\n <button onClick={() => navigate('/workflows/registry')} className=\"btn-ghost text-xs\">\n Cancel\n </button>\n {isLast ? (\n <button\n onClick={handleSave}\n disabled={!isStepValid(step, form) || upsert.isPending}\n className=\"btn-primary text-xs\"\n >\n {upsert.isPending ? 'Saving...' : editing ? 'Save' : 'Create'}\n </button>\n ) : (\n <button\n onClick={() => setStep(step + 1)}\n disabled={!isStepValid(step, form)}\n className=\"btn-primary text-xs\"\n >\n Next\n </button>\n )}\n </div>\n </div>\n\n </div>\n </div>\n );\n}\n"],"names":["matchesSearch","wf","search","q","WorkflowConfigsPage","navigate","useNavigate","data","isLoading","useDiscoveredWorkflows","deleteConfig","useDeleteWorkflowConfig","filters","setFilter","useFilterParams","searchInput","setSearchInput","useState","confirmDelete","setConfirmDelete","useEffect","timer","allWorkflows","queues","useMemo","w","roles","workflows","result","columns","row","jsxs","jsx","WorkflowPill","TaskQueuePill","ShieldCheck","Settings","Wrench","escRoles","invokeRoles","r","RolePill","UserCheck","RowActionGroup","RowAction","Play","ShieldPlus","ShieldOff","handleDelete","handleRowClick","PageHeader","FilterBar","e","FilterSelect","v","DataTable","ConfirmDeleteModal","Fragment","splitCsv","s","EMPTY_FORM","configToForm","c","consumes","STEP_LABELS","jsonValid","isStepValid","step","form","labelCls","hintCls","jsonCls","RolePicker","selected","onChange","single","placeholder","useRoles","allRoles","open","setOpen","ref","useRef","handler","toggle","role","remove","placeholderText","User","X","ChevronDown","isSelected","Check","WorkflowPicker","options","wfType","t","Workflow","csvToArray","csv","arrayToCsv","arr","AdvancedStep","set","configs","useWorkflowConfigs","consumesOptions","BasicsStep","editing","durableTypes","showPickList","type","InvocationStep","BotPicker","botId","WorkflowConfigDetailPage","workflowType","useParams","isNew","upsert","useUpsertWorkflowConfig","SYSTEM_WORKFLOWS","jobsData","useJobs","unregisteredTypes","registeredSet","j","searchParams","setSearchParams","useSearchParams","prefillForm","prefillType","prefillQueue","setForm","schemaError","setSchemaError","initialized","setInitialized","setStep","useCallback","prev","next","field","value","f","handleSave","envelope_schema","resolver_schema","isLast","StepIndicator","i"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as i,j as e}from"./vendor-query-B2UbickB.js";import{P as Ne}from"./PageHeaderWithStats-DQmNXYcG.js";import{F as ve,b as Ce}from"./FilterBar-Ck4K4rzu.js";import{u as Se}from"./useFilterParams-DZCAaBC7.js";import{u as te,a as se,b as $e,c as _e,d as Te}from"./controlplane-sh5paKGB.js";import{M as Ee}from"./Modal-DEODGeqx.js";import{K as Z,ao as U,P as Re,ap as Y,aq as J,o as ne,I as Me,A as Pe,a5 as Ae,R as Le,S as We,ar as Qe,E as Fe,Z as Oe,as as Ie}from"./vendor-icons-5gSix3t2.js";import{C as z}from"./CollapsibleSection-DR3D4kMt.js";import{T as Be}from"./TaskQueuePill-BSFLiBcf.js";import{D as ze}from"./DataTable-D9yuBv0w.js";import{C as W,c as Je,J as De}from"./index-B_e2uIz9.js";import{R as Ue,a as X}from"./RowActions-Dg-Fsm5O.js";import{f as Ve}from"./vendor-react-CX88sFS5.js";import"./EmptyState-BcsfPq9T.js";const qe=[{label:"15m",value:"15m"},{label:"30m",value:"30m"},{label:"1h",value:"1h"},{label:"1d",value:"1d"},{label:"7d",value:"7d"}],re={pong:"text-status-success",ping:"text-accent",throttle:"text-status-warning",job:"text-purple-400",work:"text-text-secondary",activate:"text-status-error",cron:"text-text-tertiary",user:"text-text-secondary"},He={pong:"roll call",ping:"ping",throttle:"throttle",job:"job",work:"work",activate:"activate",cron:"cron",user:"user"},Ke=250;function A(t){return!!t.worker_topic}function L(t){return typeof t.throttle=="number"&&t.throttle!==0}function V(t){return t===void 0||t===0?"Normal":t===-1?"Paused":t>=864e5?`${(t/864e5).toFixed(0)}d`:t>=36e5?`${(t/36e5).toFixed(1)}h`:t>=6e4?`${(t/6e4).toFixed(1)}m`:t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function Ge(t){if(!t)return null;const s=t.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\.(\d+)$/);if(s){const[,r,n,a,d,l,g,c]=s;return new Date(`${r}-${n}-${a}T${d}:${l}:${g}.${c}Z`)}const o=new Date(t);return isNaN(o.getTime())?null:o}function Ze(t){const s=Ge(t);if(!s)return"--";const o=Date.now()-s.getTime();if(o<0||isNaN(o))return"--";const r=Math.floor(o/1e3);if(r<60)return`${r}s`;const n=Math.floor(r/60);if(n<60)return`${n}m`;const a=Math.floor(n/60);return a<24?`${a}h ${n%60}m`:`${Math.floor(a/24)}d ${a%24}h`}function ae(t){return t.replace(/^hmsh:[^:]+:x:/,"")||"(engine)"}function F(t){const s=t.match(/^([^:]+)::(.+?)-[A-Za-z0-9_]{10,}$/);return s?s[2]:t.length>20?t.slice(0,20)+"...":t}function Ye(t){const s=t.match(/^([^:]+)::/);return(s==null?void 0:s[1])||""}const oe=[{key:"pong",label:"Roll Call",description:"Node health check responses"},{key:"ping",label:"Ping",description:"Health check broadcasts"},{key:"throttle",label:"Throttle",description:"Throttle commands"},{key:"job",label:"Job",description:"Job lifecycle events"},{key:"work",label:"Work",description:"Worker dispatch events"},{key:"activate",label:"Activate",description:"Worker activation"},{key:"cron",label:"Cron",description:"Cron schedule triggers"},{key:"user",label:"User",description:"User-defined messages"}];function O(t){return`${t.engine_id}-${t.worker_topic||"engine"}`}function Xe(t){const s=new Map;for(const o of t){if(!o.worker_topic)continue;const r=o.worker_topic;s.has(r)||s.set(r,[]),s.get(r).push(o)}return s}function R(t){let s=0,o=0,r=0;for(const n of t)if(n.counts)for(const[a,d]of Object.entries(n.counts))s+=d,a==="200"?o+=d:a==="500"&&(r+=d);return{total:s,success:o,errors:r}}function et(t){let s=0;for(const o of t)typeof o.stream_depth=="number"&&(s+=o.stream_depth);return s}function tt(t){if(t.length===0)return"healthy";if(t.every(r=>r.throttle===-1))return"paused";const{errors:o}=R(t);return o>0||t.some(L)?"degraded":"healthy"}function st({activeAppId:t,allProfiles:s,profiles:o}){const r=te(),[n,a]=i.useState(new Set),[d,l]=i.useState(!1),[g,c]=i.useState([]);i.useEffect(()=>{a(new Set)},[t]);const w=i.useCallback(p=>{a(S=>{const b=new Set(S),$=O(p);return b.has($)?b.delete($):b.add($),b})},[]),f=i.useCallback(()=>{n.size===o.length?a(new Set):a(new Set(o.map(O)))},[o,n.size]),y=i.useMemo(()=>{const p=o.filter(N=>n.has(O(N)));if(p.length===0)return[];if(p.length===s.length)return[{label:"Entire Mesh"}];const S=p.filter(N=>!A(N)),b=p.filter(A),$=[];for(const N of S)$.push({label:`Engine ${N.engine_id}`,guid:N.engine_id,scope:"engines"});const M=new Map;for(const N of b){const T=N.worker_topic;M.has(T)||M.set(T,[]),M.get(T).push(N)}for(const[N,T]of M){const I=s.filter(P=>P.worker_topic===N);if(T.length===I.length)$.push({label:N,topic:N});else for(const P of T)$.push({label:`${N} ${P.engine_id}`,guid:P.engine_id})}return $},[o,s,n]);return{selectedIds:n,setSelectedIds:a,toggleCheckbox:w,toggleAll:f,throttleModalOpen:d,throttleTargets:g,selectedThrottleTargets:y,throttleMutation:r,handleBulkThrottle:p=>{const S=g.length>0?g:y;for(const b of S)r.mutate({appId:t,throttle:p,...b.topic?{topic:b.topic}:{},...b.guid?{guid:b.guid}:{},...b.scope?{scope:b.scope}:{}});l(!1),c([])},handleRowClick:(p,S)=>{const b=A(p)?`${p.worker_topic} ${p.engine_id}`:`Engine ${p.engine_id}`;c([{label:b,guid:p.engine_id,scope:S||(A(p)?"workers":"engines")}]),l(!0)},handleBulkThrottleOpen:()=>{c(y),l(!0)},handleResumeThrottle:(p,S)=>{const b=S||(A(p)?"workers":"engines");r.mutate({appId:t,throttle:0,guid:p.engine_id,scope:b})},handleResumeQueue:p=>{r.mutate({appId:t,throttle:0,topic:p})},handleQueueThrottle:p=>{c([{label:p,topic:p}]),l(!0)},closeThrottleModal:()=>{l(!1),c([])}}}const nt=[{label:"Resume",ms:0},{label:"0.5s",ms:500},{label:"1s",ms:1e3},{label:"5s",ms:5e3},{label:"30s",ms:3e4},{label:"Pause",ms:-1}];function rt({target:t}){const s=t.label==="Entire Mesh",o=t.label==="All Engines"||t.label.startsWith("Engine "),r=s?"bg-status-error/10 text-status-error":o?"bg-blue-500/10 text-blue-500":"bg-accent/[0.06] text-text-secondary",n=t.scope==="engines"?"engine only":t.scope==="workers"?"worker only":t.guid?"guid":t.topic?"topic":"mesh";return e.jsxs("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 text-[10px] font-medium rounded-lg ${r}`,children:[t.label,e.jsx("span",{className:"text-[8px] opacity-50",children:n})]})}function at({open:t,onClose:s,targets:o,onApply:r,isPending:n}){const[a,d]=i.useState("");return e.jsx(Ee,{open:t,onClose:s,title:"Adjust Throttle",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Targets"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:o.map((l,g)=>e.jsx(rt,{target:l},l.guid||l.topic||g))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Presets"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:nt.map(l=>e.jsx("button",{onClick:()=>r(l.ms),disabled:n,className:`px-3 py-1.5 text-xs rounded transition-colors ${l.ms===-1?"bg-status-error/10 text-status-error hover:bg-status-error/20":l.ms===0?"bg-status-success/10 text-status-success hover:bg-status-success/20":"bg-surface-sunken text-text-secondary hover:bg-surface-hover"} disabled:opacity-50`,children:l.label},l.label))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Custom delay (seconds)"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"number",step:"0.1",min:"0",value:a,onChange:l=>d(l.target.value),placeholder:"e.g. 2.5",className:"input text-xs py-1.5 px-3 w-28"}),e.jsx("button",{onClick:()=>{const l=parseFloat(a);isNaN(l)||l<0||r(Math.round(l*1e3))},disabled:n,className:"btn-primary text-xs py-1.5 px-4 disabled:opacity-50",children:"Apply"})]})]})]})})}function ot(){const{data:t}=se(),s=te(),[o,r]=i.useState(null),[n,a]=i.useState(!1),d=(t==null?void 0:t.apps)??[],l=i.useCallback(async(c,w="all")=>{if(d.length===0)return;a(!0);const f=await Promise.allSettled(d.map(k=>s.mutateAsync({appId:k.appId,throttle:c,...w!=="all"?{scope:w}:{}}))),y=f.filter(k=>k.status==="rejected").length;y>0&&console.error(`Emergency throttle: ${y}/${f.length} apps failed`),a(!1),r(null)},[d,s]),g=c=>c==="engines"?"engines":c==="workers"?"workers":"everything";return o?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs text-status-error",children:["Pause ",g(o.scope),"?"]}),e.jsx("button",{onClick:()=>l(o.ms,o.scope),disabled:n,className:"px-2.5 py-1 text-xs rounded-md bg-status-error text-white hover:bg-status-error/90 transition-colors disabled:opacity-50",children:n?e.jsx(Z,{className:"w-3.5 h-3.5 animate-spin"}):"Confirm"}),e.jsx("button",{onClick:()=>r(null),disabled:n,className:"px-2.5 py-1 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50",children:"Cancel"})]}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>r({ms:-1,scope:"all"}),disabled:n,className:"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-error/80 hover:text-status-error hover:bg-status-error/10 transition-colors disabled:opacity-50",title:"Pause all engines and workers",children:[e.jsx(U,{className:"w-3.5 h-3.5"}),"Pause All"]}),e.jsxs("button",{onClick:()=>l(0),disabled:n,className:"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-success/80 hover:text-status-success hover:bg-status-success/10 transition-colors disabled:opacity-50",title:"Resume all engines and workers",children:[n?e.jsx(Z,{className:"w-3.5 h-3.5 animate-spin"}):e.jsx(Re,{className:"w-3.5 h-3.5"}),"Resume All"]})]})}function lt({byStream:t,onNodeFilter:s}){const[o,r]=i.useState(!1);if(i.useEffect(()=>{r(!1);const c=requestAnimationFrame(()=>r(!0));return()=>cancelAnimationFrame(c)},[t]),t.length===0)return e.jsx("p",{className:"text-xs text-text-tertiary py-4 text-center",children:"No activity in this period"});const n=t.filter(c=>c.stream_type==="engine"),a=t.filter(c=>c.stream_type==="worker"),d=Math.max(...t.map(c=>c.count)),l=c=>{const w=d>0?c.count/d*100:0,f=c.stream_type==="engine",y=f?"(all engines)":ae(c.stream_name),k=f?"bg-blue-500/70":"bg-accent/60",C=f?"text-blue-500":"text-text-tertiary";return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`text-[9px] font-mono ${C} w-36 truncate text-right shrink-0`,title:c.stream_name,children:y}),e.jsx("div",{className:"flex-1 h-4 bg-surface-sunken rounded overflow-hidden",children:e.jsx("div",{className:`h-full ${k} rounded transition-all duration-500 ease-out`,style:{width:o?`${w}%`:"0%"}})}),e.jsx("span",{className:"text-[10px] font-mono tabular-nums text-text-secondary w-12 text-right shrink-0",children:c.count.toLocaleString()})]},`${c.stream_type}-${c.stream_name}`)},g="text-[9px] uppercase tracking-widest font-semibold mb-1 cursor-pointer hover:underline";return e.jsxs("div",{className:"space-y-1.5",children:[n.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`${g} text-blue-500/70 hover:text-blue-500`,onClick:()=>s==null?void 0:s("engines"),children:"Engine Stream"}),n.map(l),a.length>0&&e.jsx("div",{className:"h-2"})]}),a.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`${g} text-accent/70 hover:text-accent`,onClick:()=>s==null?void 0:s("workers"),children:"Worker Streams"}),a.map(l)]})]})}function it({queue:t,workers:s,expanded:o,onToggle:r,onWorkerClick:n,onResumeThrottle:a,onQueueThrottle:d,onResumeQueue:l,byStream:g,activeDuration:c}){const w=i.useMemo(()=>{const u=g.find(m=>m.stream_type==="worker"&&ae(m.stream_name)===t);return(u==null?void 0:u.count)??0},[g,t]),f=i.useMemo(()=>tt(s),[s]),y=i.useMemo(()=>et(s),[s]),{errors:k}=i.useMemo(()=>R(s),[s]),C=f==="paused"?"bg-status-error":f==="degraded"?"bg-status-warning":"bg-status-success",x=i.useMemo(()=>[...s].sort((u,m)=>R([m]).total-R([u]).total),[s]),j=i.useMemo(()=>[{key:"engine_id",label:"Router",render:u=>{var p;const m=u.engine_id.replace(/^[^:]+::/,"").replace(/-[A-Za-z0-9_]{10,}$/,"")||u.engine_id,_=((p=u.engine_id.match(/^([^:]+)::/))==null?void 0:p[1])||"";return e.jsxs("div",{className:"flex items-center gap-2",title:u.engine_id,children:[e.jsx("span",{className:"text-xs text-text-secondary truncate max-w-[180px]",children:m}),_&&e.jsx("span",{className:"text-[9px] text-text-tertiary/50",children:_})]})}},{key:"processed",label:"Processed",render:u=>{const m=R([u]);return e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-tertiary",children:m.total>0?m.total.toLocaleString():"--"})},className:"w-24"},{key:"throttle",label:"Throttle",render:u=>{const m=u.throttle;return m===-1?e.jsx("span",{className:"text-xs text-status-error font-medium",children:"Paused"}):m&&m>0?e.jsx("span",{className:"text-xs text-status-warning font-medium",children:V(m)}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"0"})},className:"w-24"},{key:"actions",label:"",render:u=>e.jsxs(Ue,{children:[L(u)&&e.jsx(X,{icon:Y,title:"Resume (remove throttle)",onClick:()=>a(u),colorClass:"text-text-tertiary hover:text-status-success"}),e.jsx(X,{icon:J,title:"Adjust throttle",onClick:()=>n(u)})]}),className:"w-16"}],[n,a]);return e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>r(t),className:"group/row relative flex items-center gap-3 w-full py-2 hover:bg-surface-hover transition-colors text-left rounded",children:[e.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${C}`,title:f}),e.jsx(ne,{className:`w-3.5 h-3.5 text-text-tertiary/50 transition-transform duration-200 ${o?"rotate-90":""}`,strokeWidth:2}),e.jsx(Be,{queue:t,size:"sm"}),e.jsx("span",{className:"flex-1"}),k>0&&e.jsxs("span",{className:"text-[10px] text-status-error font-medium mr-2",children:[k," errors"]}),y>0&&e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-status-warning w-20",children:[e.jsx(Me,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"font-mono tabular-nums",children:y.toLocaleString()})]}),e.jsxs("span",{className:`flex items-center gap-1 text-xs w-24 ${s.some(L)?"text-status-warning":"text-text-tertiary"}`,children:[e.jsx(Pe,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"font-mono tabular-nums",children:s.length}),e.jsx("span",{children:"workers"})]}),e.jsx("span",{className:"flex items-center gap-1 text-xs font-mono text-text-tertiary w-28 justify-end mr-16",children:w>0?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),w.toLocaleString()," in ",c]}):e.jsx("span",{className:"text-text-tertiary/40",children:"—"})}),e.jsxs("span",{className:"absolute right-3 top-1/2 -translate-y-1/2 opacity-0 group-hover/row:opacity-100 transition-opacity flex items-center gap-2",children:[s.some(L)&&e.jsx(Y,{className:"w-4 h-4 text-text-tertiary hover:text-status-success",strokeWidth:1.5,onClick:u=>{u.stopPropagation(),l(t)}}),e.jsx(J,{className:"w-4 h-4 text-text-tertiary hover:text-accent",strokeWidth:1.5,onClick:u=>{u.stopPropagation(),d(t)}})]})]}),e.jsx(W,{open:o,children:e.jsx("div",{className:"ml-6",children:e.jsx(ze,{columns:j,data:x,keyFn:O,onRowClick:n,emptyMessage:"No workers",inline:!0})})})]})}let ct=0;function dt(t){const s=t.data||{},o=s.topic?String(s.topic):"",r=s.guid?String(s.guid).slice(0,8):"";switch(t.type){case"pong":return o?`Worker ${r}... on "${o}" responded`:`Engine ${r}... responded`;case"ping":return"Roll call broadcast";case"throttle":{const n=s.throttle,a=o?`queue "${o}"`:r?`node ${r}...`:"all nodes";return`${V(n)} applied to ${a}`}case"job":return`Job ${r?r+"...":""} ${s.status||"updated"}`;case"work":return`Dispatched to "${o||"worker"}" ${r?"("+r+"...)":""}`;case"activate":return`Worker "${o||"unknown"}" activated`;case"cron":return`Cron triggered ${o?'"'+o+'"':""}`;default:return o||r||t.type}}function ut(t){const s=[];let o=0;for(;o<t.length;){const r=t[o];if(r.type==="pong"){let n=o+1;for(;n<t.length&&t[n].type==="pong";)n++;const a=t.slice(o,n);if(a.length>=3)s.push({kind:"group",type:"pong",count:a.length,firstTimestamp:a[a.length-1].timestamp,lastTimestamp:a[0].timestamp,events:a});else for(const d of a)s.push({kind:"single",event:d});o=n}else s.push({kind:"single",event:r}),o++}return s}function le({event:t}){const[s,o]=i.useState(!1);return e.jsxs("div",{className:"border-b border-surface-border/50 last:border-b-0",children:[e.jsxs("button",{onClick:()=>o(!s),className:"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors",children:[e.jsx("span",{className:"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0",children:new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}),e.jsx("span",{className:`text-[9px] font-medium px-1 py-0.5 rounded ${re[t.type]||"text-text-tertiary"} bg-surface-sunken whitespace-nowrap shrink-0`,children:He[t.type]||t.type}),e.jsx("span",{className:"text-[9px] text-text-secondary flex-1 min-w-0 truncate",children:dt(t)}),e.jsx("svg",{className:`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${s?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),e.jsx(W,{open:s,children:e.jsx("div",{className:"pb-2",children:e.jsx(De,{data:t.data})})})]})}function xt({group:t}){const[s,o]=i.useState(!1),r=t.events.filter(a=>{var d;return!((d=a.data)!=null&&d.topic)}).length,n=t.count-r;return e.jsxs("div",{className:"border-b border-surface-border/50 last:border-b-0",children:[e.jsxs("button",{onClick:()=>o(!s),className:"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors",children:[e.jsx("span",{className:"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0",children:new Date(t.lastTimestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}),e.jsx("span",{className:`text-[9px] font-medium px-1 py-0.5 rounded ${re.pong} bg-surface-sunken whitespace-nowrap shrink-0`,children:"roll call"}),e.jsxs("span",{className:"text-[9px] text-text-secondary flex-1 min-w-0 truncate",children:[t.count," nodes responded",r>0&&n>0?` (${r} engine${r!==1?"s":""}, ${n} worker${n!==1?"s":""})`:r>0?` (${r} engine${r!==1?"s":""})`:` (${n} worker${n!==1?"s":""})`]}),e.jsx("svg",{className:`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${s?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),e.jsx(W,{open:s,children:e.jsx("div",{className:"ml-4",children:t.events.map(a=>e.jsx(le,{event:a},a.id))})})]})}function pt({channels:t,onToggle:s,customFilter:o,onCustomFilterChange:r}){return e.jsxs("div",{className:"space-y-3 pb-3 border-b border-surface-border mb-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Channels"}),e.jsx("p",{className:"text-[9px] text-text-tertiary",children:"Unchecked channels are dropped before buffering"})]}),e.jsx("div",{className:"grid grid-cols-2 gap-1",children:oe.map(n=>e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer py-0.5",children:[e.jsx("input",{type:"checkbox",checked:t.has(n.key),onChange:()=>s(n.key),className:"w-3 h-3 rounded border-border accent-accent"}),e.jsx("span",{className:"text-[10px] text-text-secondary",title:n.description,children:n.label})]},n.key))}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Text Filter"}),e.jsx("input",{type:"text",value:o,onChange:n=>r(n.target.value),placeholder:"pong",className:"input text-[10px] font-mono py-1 px-2 w-full"}),e.jsxs("p",{className:"text-[9px] text-text-tertiary mt-1",children:["Filter by event type, e.g. ",e.jsx("span",{className:"font-mono",children:"pong"}),", ",e.jsx("span",{className:"font-mono",children:"throttle"}),", or any text in the event data."]})]})]})}function ht({bridgeActive:t}){const[s,o]=i.useState(!1),[r,n]=i.useState(!1),[a,d]=i.useState([]),[l,g]=i.useState(()=>new Set(oe.map(x=>x.key))),[c,w]=i.useState(""),f=i.useRef(l);i.useEffect(()=>{f.current=l},[l]);const y=i.useRef(c);i.useEffect(()=>{y.current=c},[c]);const k=x=>{g(j=>{const u=new Set(j);return u.has(x)?u.delete(x):u.add(x),u})};Je("lt.events.mesh.>",i.useCallback(x=>{var m;const j=((m=x.type)==null?void 0:m.replace("mesh.",""))||"unknown";if(!f.current.has(j))return;const u=y.current;u&&!`${j} ${JSON.stringify(x.data||x)}`.toLowerCase().includes(u.toLowerCase())||d(_=>[{id:++ct,type:j,timestamp:x.timestamp||new Date().toISOString(),data:x.data||x},..._].slice(0,Ke))},[]));const C=()=>d([]);return e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px] sticky top-14 self-start max-h-[calc(100vh-8rem)] flex flex-col",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Event Stream"}),e.jsx(Le,{className:`w-3 h-3 ${t?"text-status-success animate-pulse":"text-text-tertiary"}`}),e.jsx("span",{className:"text-[9px] text-text-tertiary",children:t?"Live":"..."}),e.jsxs("span",{className:"ml-auto flex items-center gap-1",children:[e.jsx("button",{onClick:()=>{o(x=>!x),n(!1)},className:`p-1 rounded transition-colors ${s?"text-accent bg-accent/10":"text-text-tertiary hover:text-text-primary"}`,title:"Configure channels",children:e.jsx(We,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>{n(x=>!x),o(!1)},className:`p-1 rounded transition-colors ${r?"text-accent bg-accent/10":"text-text-tertiary hover:text-text-primary"}`,title:"View raw JSON",children:e.jsx(Qe,{className:"w-3.5 h-3.5"})}),a.length>0&&e.jsx("button",{onClick:C,className:"p-1 rounded text-text-tertiary hover:text-text-primary transition-colors",title:"Clear events",children:e.jsx(Fe,{className:"w-3.5 h-3.5"})})]})]}),e.jsx(W,{open:s,children:e.jsx(pt,{channels:l,onToggle:k,customFilter:c,onCustomFilterChange:w})}),e.jsx(W,{open:r,children:e.jsx("div",{className:"pb-3 border-b border-surface-border mb-3",children:e.jsx("pre",{className:"text-[9px] font-mono text-text-tertiary bg-surface-sunken rounded-lg p-3 max-h-[50vh] overflow-auto whitespace-pre-wrap",children:JSON.stringify(a.slice(0,50),null,2)})})}),a.length>0&&e.jsxs("p",{className:"text-[9px] text-text-tertiary mb-2",children:[a.length," events"]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:a.length===0?e.jsx("p",{className:"text-xs text-text-tertiary py-6 text-center",children:t?"Waiting for events...":"Subscribing..."}):ut(a).map((x,j)=>x.kind==="group"?e.jsx(xt,{group:x},`grp-${j}`):e.jsx(le,{event:x.event},x.event.id))})]})}function mt(t){const s=[],o=[],r=[];for(const n of t)L(n)?r.push(n):n.is_scout||R([n]).total>0?s.push(n):o.push(n);return s.sort((n,a)=>n.is_scout&&!a.is_scout?-1:!n.is_scout&&a.is_scout?1:R([a]).total-R([n]).total),o.sort((n,a)=>F(n.engine_id).localeCompare(F(a.engine_id))),r.sort((n,a)=>F(n.engine_id).localeCompare(F(a.engine_id))),{active:s,idle:o,paused:r}}function D({engine:t,isFirst:s,onThrottle:o}){const r=F(t.engine_id),n=Ye(t.engine_id),a=R([t]),d=t.stream_depth??0,l=L(t);return e.jsxs("div",{className:"group/row flex items-center gap-3 py-2 hover:bg-surface-hover/50 transition-colors rounded px-1",children:[l?e.jsx(U,{className:"w-3.5 h-3.5 text-status-warning shrink-0",strokeWidth:1.5}):e.jsx(Oe,{className:`w-3.5 h-3.5 shrink-0 ${a.total>0||t.is_scout?"text-status-success":"text-text-tertiary/30"}`,strokeWidth:1.5}),e.jsx("span",{className:`${s?"text-base font-medium":"text-xs"} text-text-primary truncate max-w-[180px]`,title:t.engine_id,children:r}),n&&e.jsx("span",{className:"text-[10px] text-text-tertiary/50",children:n}),t.is_scout&&e.jsx("span",{className:"text-[9px] text-amber-500 uppercase tracking-widest",children:"scout"}),e.jsx("span",{className:"flex-1"}),l&&e.jsx("span",{className:"text-[10px] text-status-warning",children:t.throttle===-1?"Paused":V(t.throttle)}),a.total>0&&e.jsx("span",{className:"text-[10px] font-mono tabular-nums text-text-tertiary w-16 text-right",children:a.total.toLocaleString()}),d>0&&e.jsxs("span",{className:`text-[10px] font-mono tabular-nums w-14 text-right ${d>100?"text-status-warning":"text-text-tertiary/50"}`,children:[d.toLocaleString()," q"]}),e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary/40 w-12 text-right",children:Ze(t.inited)}),e.jsx("span",{className:"opacity-0 group-hover/row:opacity-100 transition-opacity",children:e.jsx("button",{onClick:g=>{g.stopPropagation(),o(t)},className:"text-text-tertiary hover:text-accent transition-colors",title:l?"Resume / adjust throttle":"Pause / throttle",children:e.jsx(J,{className:"w-3.5 h-3.5",strokeWidth:1.5})})})]})}function ee({label:t,engines:s,onThrottle:o}){const[r,n]=i.useState(!1);return s.length===0?null:e.jsxs("div",{className:"mt-1",children:[e.jsxs("button",{onClick:()=>n(!r),className:"flex items-center gap-1.5 text-[10px] text-text-tertiary hover:text-text-secondary transition-colors py-1",children:[e.jsx(ne,{className:`w-3 h-3 transition-transform duration-200 ${r?"rotate-90":""}`,strokeWidth:2}),s.length," ",t]}),e.jsx(W,{open:r,children:e.jsx("div",{className:"ml-1",children:s.map(a=>e.jsx(D,{engine:a,onThrottle:o},a.engine_id))})})]})}function gt({engines:t,onThrottle:s,isLoading:o}){const{active:r,idle:n,paused:a}=i.useMemo(()=>mt(t),[t]);return o?e.jsx("p",{className:"text-xs text-text-tertiary",children:"Discovering engines..."}):t.length===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:"No engines found."}):r.length===0&&n.length===0?e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3 py-2",children:[e.jsx(U,{className:"w-4 h-4 text-status-error shrink-0",strokeWidth:1.5}),e.jsxs("span",{className:"text-base text-status-error font-medium",children:["All ",t.length," engines paused"]})]}),e.jsx("p",{className:"text-[10px] text-text-tertiary ml-7",children:"Messages are accumulating. Resume at least one engine to restore processing."}),e.jsx("div",{className:"ml-1 mt-2",children:a.map(d=>e.jsx(D,{engine:d,onThrottle:s},d.engine_id))})]}):e.jsxs("div",{children:[r.map((d,l)=>e.jsx(D,{engine:d,isFirst:l===0,onThrottle:s},d.engine_id)),e.jsx(ee,{label:"idle",engines:n,onThrottle:s}),e.jsx(ee,{label:"paused",engines:a,onThrottle:s})]})}function ft({collapsed:t,toggleSection:s,activeDuration:o,streamStats:r,isLoading:n,queueMap:a,expandedQueues:d,toggleQueue:l,allQueuesExpanded:g,toggleAllQueues:c,handleRowClick:w,handleResumeThrottle:f,handleQueueThrottle:y,handleResumeQueue:k,engines:C,bridgeActive:x}){return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1fr_340px] gap-6",children:[e.jsxs("div",{className:"flex flex-col gap-12 mt-10",children:[e.jsx(z,{title:`Message Volume (${o})`,sectionKey:"volume",isCollapsed:!!t.volume,onToggle:s,contentClassName:"mt-4 ml-7",children:e.jsx(lt,{byStream:(r==null?void 0:r.byStream)??[],onNodeFilter:()=>{},onQueueFilter:()=>{}})}),e.jsx(z,{title:`Engine Routers (${C.length})`,sectionKey:"engines",isCollapsed:!!t.engines,onToggle:s,contentClassName:"mt-4 ml-7",children:e.jsx(gt,{engines:C,onThrottle:w,isLoading:n})}),e.jsx(z,{title:"Worker Routers",sectionKey:"queues",isCollapsed:!!t.queues,onToggle:s,contentClassName:"mt-4 ml-7 flex flex-col gap-0",children:n?e.jsx("p",{className:"text-xs text-text-tertiary",children:"Discovering mesh nodes..."}):a.size===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:'No worker routers found. Click "Roll Call" to discover.'}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex justify-end mb-2",children:e.jsx("button",{onClick:c,className:"text-[10px] text-accent hover:underline",children:g?"Collapse all":"Expand all"})}),[...a.entries()].sort(([j],[u])=>j.localeCompare(u)).map(([j,u])=>e.jsx(it,{queue:j,workers:u,expanded:d.has(j),onToggle:l,onWorkerClick:w,onResumeThrottle:f,onQueueThrottle:y,onResumeQueue:k,byStream:(r==null?void 0:r.byStream)??[],activeDuration:o},j))]})})]}),e.jsx(ht,{bridgeActive:x})]})}function Mt(){var K;const{data:t}=se(),s=(t==null?void 0:t.apps)??[],{filters:o,setFilter:r}=Se({filters:{app_id:"",duration:"1h"}}),n=((K=s[0])==null?void 0:K.appId)??"durable",a=o.app_id||n,d=o.duration||"1h",l=$e(),g=6e4,{data:c,isLoading:w,error:f,refetch:y,isFetching:k}=_e(a,g),{data:C}=Te(a,d,void 0,g),x=i.useMemo(()=>[...(c==null?void 0:c.profiles)??[]].sort((v,E)=>{const B=v.worker_topic||v.stream||"",Q=E.worker_topic||E.stream||"";return!v.worker_topic&&E.worker_topic?-1:v.worker_topic&&!E.worker_topic?1:B.localeCompare(Q)}),[c==null?void 0:c.profiles]),j=i.useMemo(()=>x.filter(h=>!A(h)),[x]),u=i.useMemo(()=>x.filter(A),[x]),m=i.useMemo(()=>Xe(x),[x]),_=x.filter(L).length,p=i.useMemo(()=>{const h=new Set(s.map(v=>v.appId));return a&&h.add(a),[...h].sort().map(v=>({value:v,label:v}))},[s,a]),[S]=Ve(),b=S.get("queue"),[$,M]=i.useState(()=>b?new Set([b]):new Set),N=i.useCallback(h=>{M(v=>{const E=v.has(h),B=E?new Set:new Set([h]),Q=new URLSearchParams(window.location.search);E?Q.delete("queue"):Q.set("queue",h);const G=Q.toString();return window.history.pushState(null,"",G?`?${G}`:window.location.pathname),B})},[]),T=m.size>0&&[...m.keys()].every(h=>$.has(h)),I=i.useCallback(()=>{M(T?new Set:new Set(m.keys()))},[T,m]),P="lt:controlplane:collapsed",[ie,ce]=i.useState(()=>{try{const h=JSON.parse(localStorage.getItem(P)||"{}");return b&&(h.queues=!1),h}catch{return{}}}),de=i.useCallback(h=>{ce(v=>{const E={...v,[h]:!v[h]};return localStorage.setItem(P,JSON.stringify(E)),E})},[]),{throttleModalOpen:ue,throttleTargets:q,selectedThrottleTargets:xe,throttleMutation:pe,handleBulkThrottle:he,handleRowClick:me,handleResumeThrottle:ge,handleResumeQueue:fe,handleQueueThrottle:be,closeThrottleModal:je}=st({activeAppId:a,allProfiles:x,profiles:x}),ye=i.useMemo(()=>{const h=[{label:"Engines",value:j.length,dotClass:"bg-blue-500"},{label:"Workers",value:u.length,dotClass:"bg-text-secondary"},{label:"Topics",value:m.size}];return _>0&&h.push({label:"Throttled",value:_,dotClass:"bg-status-warning"}),h},[j.length,u.length,m.size,_]),[H,we]=i.useState(!1),ke=i.useCallback(()=>{l.mutate({appId:a},{onSuccess:()=>we(!0)})},[a,l]);return i.useEffect(()=>{!H&&a&&ke()},[a]),e.jsxs("div",{children:[e.jsx(Ne,{title:"Routers",docsHash:"#docs:dashboard.md:task-queues",stats:ye,actions:e.jsx(ot,{})}),e.jsxs(ve,{actions:e.jsx("div",{className:"flex items-center gap-1",children:qe.map(h=>e.jsx("button",{onClick:()=>r("duration",h.value),className:`px-3 py-1 text-xs rounded-full transition-colors ${d===h.value?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:h.label},h.value))}),children:[e.jsx(Ce,{label:"Application",value:o.app_id,onChange:h=>r("app_id",h),options:p}),e.jsxs("button",{onClick:()=>y(),disabled:k,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50",children:[e.jsx(Ie,{className:`w-3.5 h-3.5 ${k?"animate-spin":""}`}),"Roll Call"]})]}),f&&e.jsx("div",{className:"mb-6 px-4 py-3 rounded bg-status-error/10 border border-status-error/20",children:e.jsx("p",{className:"text-xs text-status-error font-medium",children:f.message==="Session expired"?"Session expired — please log in again.":`Failed to load mesh data: ${f.message}`})}),e.jsx(ft,{collapsed:ie,toggleSection:de,activeDuration:d,streamStats:C,isLoading:w,queueMap:m,expandedQueues:$,toggleQueue:N,allQueuesExpanded:T,toggleAllQueues:I,handleRowClick:me,handleResumeThrottle:ge,handleQueueThrottle:be,handleResumeQueue:fe,engines:j,bridgeActive:H}),e.jsx(at,{open:ue,onClose:je,targets:q.length>0?q:xe,onApply:he,isPending:pe.isPending})]})}export{Mt as ControlPlanePage};
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{a as i,j as e}from"./vendor-query-B2UbickB.js";import{P as Ne}from"./PageHeaderWithStats-DQmNXYcG.js";import{F as ve,b as Ce}from"./FilterBar-Ck4K4rzu.js";import{u as Se}from"./useFilterParams-x-Dg0Vgz.js";import{u as te,a as se,b as $e,c as _e,d as Te}from"./controlplane-BKtGwxSj.js";import{M as Ee}from"./Modal-CSrxpXeM.js";import{K as Z,ao as U,P as Re,ap as Y,aq as J,o as ne,I as Me,A as Pe,a5 as Ae,R as Le,S as We,ar as Qe,E as Fe,Z as Oe,as as Ie}from"./vendor-icons-5gSix3t2.js";import{C as z}from"./CollapsibleSection-BqCrlb0a.js";import{T as Be}from"./TaskQueuePill-BSFLiBcf.js";import{D as ze}from"./DataTable-D9yuBv0w.js";import{C as W,c as Je,J as De}from"./index-CGy9PrdX.js";import{R as Ue,a as X}from"./RowActions-Dg-Fsm5O.js";import{f as Ve}from"./vendor-react-CXumBFUA.js";import"./EmptyState-BcsfPq9T.js";const qe=[{label:"15m",value:"15m"},{label:"30m",value:"30m"},{label:"1h",value:"1h"},{label:"1d",value:"1d"},{label:"7d",value:"7d"}],re={pong:"text-status-success",ping:"text-accent",throttle:"text-status-warning",job:"text-purple-400",work:"text-text-secondary",activate:"text-status-error",cron:"text-text-tertiary",user:"text-text-secondary"},He={pong:"roll call",ping:"ping",throttle:"throttle",job:"job",work:"work",activate:"activate",cron:"cron",user:"user"},Ke=250;function A(t){return!!t.worker_topic}function L(t){return typeof t.throttle=="number"&&t.throttle!==0}function V(t){return t===void 0||t===0?"Normal":t===-1?"Paused":t>=864e5?`${(t/864e5).toFixed(0)}d`:t>=36e5?`${(t/36e5).toFixed(1)}h`:t>=6e4?`${(t/6e4).toFixed(1)}m`:t>=1e3?`${(t/1e3).toFixed(1)}s`:`${t}ms`}function Ge(t){if(!t)return null;const s=t.match(/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})\.(\d+)$/);if(s){const[,r,n,a,d,l,g,c]=s;return new Date(`${r}-${n}-${a}T${d}:${l}:${g}.${c}Z`)}const o=new Date(t);return isNaN(o.getTime())?null:o}function Ze(t){const s=Ge(t);if(!s)return"--";const o=Date.now()-s.getTime();if(o<0||isNaN(o))return"--";const r=Math.floor(o/1e3);if(r<60)return`${r}s`;const n=Math.floor(r/60);if(n<60)return`${n}m`;const a=Math.floor(n/60);return a<24?`${a}h ${n%60}m`:`${Math.floor(a/24)}d ${a%24}h`}function ae(t){return t.replace(/^hmsh:[^:]+:x:/,"")||"(engine)"}function F(t){const s=t.match(/^([^:]+)::(.+?)-[A-Za-z0-9_]{10,}$/);return s?s[2]:t.length>20?t.slice(0,20)+"...":t}function Ye(t){const s=t.match(/^([^:]+)::/);return(s==null?void 0:s[1])||""}const oe=[{key:"pong",label:"Roll Call",description:"Node health check responses"},{key:"ping",label:"Ping",description:"Health check broadcasts"},{key:"throttle",label:"Throttle",description:"Throttle commands"},{key:"job",label:"Job",description:"Job lifecycle events"},{key:"work",label:"Work",description:"Worker dispatch events"},{key:"activate",label:"Activate",description:"Worker activation"},{key:"cron",label:"Cron",description:"Cron schedule triggers"},{key:"user",label:"User",description:"User-defined messages"}];function O(t){return`${t.engine_id}-${t.worker_topic||"engine"}`}function Xe(t){const s=new Map;for(const o of t){if(!o.worker_topic)continue;const r=o.worker_topic;s.has(r)||s.set(r,[]),s.get(r).push(o)}return s}function R(t){let s=0,o=0,r=0;for(const n of t)if(n.counts)for(const[a,d]of Object.entries(n.counts))s+=d,a==="200"?o+=d:a==="500"&&(r+=d);return{total:s,success:o,errors:r}}function et(t){let s=0;for(const o of t)typeof o.stream_depth=="number"&&(s+=o.stream_depth);return s}function tt(t){if(t.length===0)return"healthy";if(t.every(r=>r.throttle===-1))return"paused";const{errors:o}=R(t);return o>0||t.some(L)?"degraded":"healthy"}function st({activeAppId:t,allProfiles:s,profiles:o}){const r=te(),[n,a]=i.useState(new Set),[d,l]=i.useState(!1),[g,c]=i.useState([]);i.useEffect(()=>{a(new Set)},[t]);const w=i.useCallback(p=>{a(S=>{const b=new Set(S),$=O(p);return b.has($)?b.delete($):b.add($),b})},[]),f=i.useCallback(()=>{n.size===o.length?a(new Set):a(new Set(o.map(O)))},[o,n.size]),y=i.useMemo(()=>{const p=o.filter(N=>n.has(O(N)));if(p.length===0)return[];if(p.length===s.length)return[{label:"Entire Mesh"}];const S=p.filter(N=>!A(N)),b=p.filter(A),$=[];for(const N of S)$.push({label:`Engine ${N.engine_id}`,guid:N.engine_id,scope:"engines"});const M=new Map;for(const N of b){const T=N.worker_topic;M.has(T)||M.set(T,[]),M.get(T).push(N)}for(const[N,T]of M){const I=s.filter(P=>P.worker_topic===N);if(T.length===I.length)$.push({label:N,topic:N});else for(const P of T)$.push({label:`${N} ${P.engine_id}`,guid:P.engine_id})}return $},[o,s,n]);return{selectedIds:n,setSelectedIds:a,toggleCheckbox:w,toggleAll:f,throttleModalOpen:d,throttleTargets:g,selectedThrottleTargets:y,throttleMutation:r,handleBulkThrottle:p=>{const S=g.length>0?g:y;for(const b of S)r.mutate({appId:t,throttle:p,...b.topic?{topic:b.topic}:{},...b.guid?{guid:b.guid}:{},...b.scope?{scope:b.scope}:{}});l(!1),c([])},handleRowClick:(p,S)=>{const b=A(p)?`${p.worker_topic} ${p.engine_id}`:`Engine ${p.engine_id}`;c([{label:b,guid:p.engine_id,scope:S||(A(p)?"workers":"engines")}]),l(!0)},handleBulkThrottleOpen:()=>{c(y),l(!0)},handleResumeThrottle:(p,S)=>{const b=S||(A(p)?"workers":"engines");r.mutate({appId:t,throttle:0,guid:p.engine_id,scope:b})},handleResumeQueue:p=>{r.mutate({appId:t,throttle:0,topic:p})},handleQueueThrottle:p=>{c([{label:p,topic:p}]),l(!0)},closeThrottleModal:()=>{l(!1),c([])}}}const nt=[{label:"Resume",ms:0},{label:"0.5s",ms:500},{label:"1s",ms:1e3},{label:"5s",ms:5e3},{label:"30s",ms:3e4},{label:"Pause",ms:-1}];function rt({target:t}){const s=t.label==="Entire Mesh",o=t.label==="All Engines"||t.label.startsWith("Engine "),r=s?"bg-status-error/10 text-status-error":o?"bg-blue-500/10 text-blue-500":"bg-accent/[0.06] text-text-secondary",n=t.scope==="engines"?"engine only":t.scope==="workers"?"worker only":t.guid?"guid":t.topic?"topic":"mesh";return e.jsxs("span",{className:`inline-flex items-center gap-1.5 px-2 py-0.5 text-[10px] font-medium rounded-lg ${r}`,children:[t.label,e.jsx("span",{className:"text-[8px] opacity-50",children:n})]})}function at({open:t,onClose:s,targets:o,onApply:r,isPending:n}){const[a,d]=i.useState("");return e.jsx(Ee,{open:t,onClose:s,title:"Adjust Throttle",children:e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Targets"}),e.jsx("div",{className:"flex flex-wrap gap-1.5",children:o.map((l,g)=>e.jsx(rt,{target:l},l.guid||l.topic||g))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Presets"}),e.jsx("div",{className:"flex flex-wrap gap-2",children:nt.map(l=>e.jsx("button",{onClick:()=>r(l.ms),disabled:n,className:`px-3 py-1.5 text-xs rounded transition-colors ${l.ms===-1?"bg-status-error/10 text-status-error hover:bg-status-error/20":l.ms===0?"bg-status-success/10 text-status-success hover:bg-status-success/20":"bg-surface-sunken text-text-secondary hover:bg-surface-hover"} disabled:opacity-50`,children:l.label},l.label))})]}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-2",children:"Custom delay (seconds)"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("input",{type:"number",step:"0.1",min:"0",value:a,onChange:l=>d(l.target.value),placeholder:"e.g. 2.5",className:"input text-xs py-1.5 px-3 w-28"}),e.jsx("button",{onClick:()=>{const l=parseFloat(a);isNaN(l)||l<0||r(Math.round(l*1e3))},disabled:n,className:"btn-primary text-xs py-1.5 px-4 disabled:opacity-50",children:"Apply"})]})]})]})})}function ot(){const{data:t}=se(),s=te(),[o,r]=i.useState(null),[n,a]=i.useState(!1),d=(t==null?void 0:t.apps)??[],l=i.useCallback(async(c,w="all")=>{if(d.length===0)return;a(!0);const f=await Promise.allSettled(d.map(k=>s.mutateAsync({appId:k.appId,throttle:c,...w!=="all"?{scope:w}:{}}))),y=f.filter(k=>k.status==="rejected").length;y>0&&console.error(`Emergency throttle: ${y}/${f.length} apps failed`),a(!1),r(null)},[d,s]),g=c=>c==="engines"?"engines":c==="workers"?"workers":"everything";return o?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("span",{className:"text-xs text-status-error",children:["Pause ",g(o.scope),"?"]}),e.jsx("button",{onClick:()=>l(o.ms,o.scope),disabled:n,className:"px-2.5 py-1 text-xs rounded-md bg-status-error text-white hover:bg-status-error/90 transition-colors disabled:opacity-50",children:n?e.jsx(Z,{className:"w-3.5 h-3.5 animate-spin"}):"Confirm"}),e.jsx("button",{onClick:()=>r(null),disabled:n,className:"px-2.5 py-1 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50",children:"Cancel"})]}):e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("button",{onClick:()=>r({ms:-1,scope:"all"}),disabled:n,className:"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-error/80 hover:text-status-error hover:bg-status-error/10 transition-colors disabled:opacity-50",title:"Pause all engines and workers",children:[e.jsx(U,{className:"w-3.5 h-3.5"}),"Pause All"]}),e.jsxs("button",{onClick:()=>l(0),disabled:n,className:"flex items-center gap-1.5 px-2.5 py-1 text-xs rounded-md text-status-success/80 hover:text-status-success hover:bg-status-success/10 transition-colors disabled:opacity-50",title:"Resume all engines and workers",children:[n?e.jsx(Z,{className:"w-3.5 h-3.5 animate-spin"}):e.jsx(Re,{className:"w-3.5 h-3.5"}),"Resume All"]})]})}function lt({byStream:t,onNodeFilter:s}){const[o,r]=i.useState(!1);if(i.useEffect(()=>{r(!1);const c=requestAnimationFrame(()=>r(!0));return()=>cancelAnimationFrame(c)},[t]),t.length===0)return e.jsx("p",{className:"text-xs text-text-tertiary py-4 text-center",children:"No activity in this period"});const n=t.filter(c=>c.stream_type==="engine"),a=t.filter(c=>c.stream_type==="worker"),d=Math.max(...t.map(c=>c.count)),l=c=>{const w=d>0?c.count/d*100:0,f=c.stream_type==="engine",y=f?"(all engines)":ae(c.stream_name),k=f?"bg-blue-500/70":"bg-accent/60",C=f?"text-blue-500":"text-text-tertiary";return e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{className:`text-[9px] font-mono ${C} w-36 truncate text-right shrink-0`,title:c.stream_name,children:y}),e.jsx("div",{className:"flex-1 h-4 bg-surface-sunken rounded overflow-hidden",children:e.jsx("div",{className:`h-full ${k} rounded transition-all duration-500 ease-out`,style:{width:o?`${w}%`:"0%"}})}),e.jsx("span",{className:"text-[10px] font-mono tabular-nums text-text-secondary w-12 text-right shrink-0",children:c.count.toLocaleString()})]},`${c.stream_type}-${c.stream_name}`)},g="text-[9px] uppercase tracking-widest font-semibold mb-1 cursor-pointer hover:underline";return e.jsxs("div",{className:"space-y-1.5",children:[n.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`${g} text-blue-500/70 hover:text-blue-500`,onClick:()=>s==null?void 0:s("engines"),children:"Engine Stream"}),n.map(l),a.length>0&&e.jsx("div",{className:"h-2"})]}),a.length>0&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:`${g} text-accent/70 hover:text-accent`,onClick:()=>s==null?void 0:s("workers"),children:"Worker Streams"}),a.map(l)]})]})}function it({queue:t,workers:s,expanded:o,onToggle:r,onWorkerClick:n,onResumeThrottle:a,onQueueThrottle:d,onResumeQueue:l,byStream:g,activeDuration:c}){const w=i.useMemo(()=>{const u=g.find(m=>m.stream_type==="worker"&&ae(m.stream_name)===t);return(u==null?void 0:u.count)??0},[g,t]),f=i.useMemo(()=>tt(s),[s]),y=i.useMemo(()=>et(s),[s]),{errors:k}=i.useMemo(()=>R(s),[s]),C=f==="paused"?"bg-status-error":f==="degraded"?"bg-status-warning":"bg-status-success",x=i.useMemo(()=>[...s].sort((u,m)=>R([m]).total-R([u]).total),[s]),j=i.useMemo(()=>[{key:"engine_id",label:"Router",render:u=>{var p;const m=u.engine_id.replace(/^[^:]+::/,"").replace(/-[A-Za-z0-9_]{10,}$/,"")||u.engine_id,_=((p=u.engine_id.match(/^([^:]+)::/))==null?void 0:p[1])||"";return e.jsxs("div",{className:"flex items-center gap-2",title:u.engine_id,children:[e.jsx("span",{className:"text-xs text-text-secondary truncate max-w-[180px]",children:m}),_&&e.jsx("span",{className:"text-[9px] text-text-tertiary/50",children:_})]})}},{key:"processed",label:"Processed",render:u=>{const m=R([u]);return e.jsx("span",{className:"text-xs font-mono tabular-nums text-text-tertiary",children:m.total>0?m.total.toLocaleString():"--"})},className:"w-24"},{key:"throttle",label:"Throttle",render:u=>{const m=u.throttle;return m===-1?e.jsx("span",{className:"text-xs text-status-error font-medium",children:"Paused"}):m&&m>0?e.jsx("span",{className:"text-xs text-status-warning font-medium",children:V(m)}):e.jsx("span",{className:"text-xs text-text-tertiary",children:"0"})},className:"w-24"},{key:"actions",label:"",render:u=>e.jsxs(Ue,{children:[L(u)&&e.jsx(X,{icon:Y,title:"Resume (remove throttle)",onClick:()=>a(u),colorClass:"text-text-tertiary hover:text-status-success"}),e.jsx(X,{icon:J,title:"Adjust throttle",onClick:()=>n(u)})]}),className:"w-16"}],[n,a]);return e.jsxs("div",{children:[e.jsxs("button",{onClick:()=>r(t),className:"group/row relative flex items-center gap-3 w-full py-2 hover:bg-surface-hover transition-colors text-left rounded",children:[e.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${C}`,title:f}),e.jsx(ne,{className:`w-3.5 h-3.5 text-text-tertiary/50 transition-transform duration-200 ${o?"rotate-90":""}`,strokeWidth:2}),e.jsx(Be,{queue:t,size:"sm"}),e.jsx("span",{className:"flex-1"}),k>0&&e.jsxs("span",{className:"text-[10px] text-status-error font-medium mr-2",children:[k," errors"]}),y>0&&e.jsxs("span",{className:"flex items-center gap-1 text-[10px] text-status-warning w-20",children:[e.jsx(Me,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"font-mono tabular-nums",children:y.toLocaleString()})]}),e.jsxs("span",{className:`flex items-center gap-1 text-xs w-24 ${s.some(L)?"text-status-warning":"text-text-tertiary"}`,children:[e.jsx(Pe,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),e.jsx("span",{className:"font-mono tabular-nums",children:s.length}),e.jsx("span",{children:"workers"})]}),e.jsx("span",{className:"flex items-center gap-1 text-xs font-mono text-text-tertiary w-28 justify-end mr-16",children:w>0?e.jsxs(e.Fragment,{children:[e.jsx(Ae,{className:"w-3 h-3 shrink-0",strokeWidth:1.5}),w.toLocaleString()," in ",c]}):e.jsx("span",{className:"text-text-tertiary/40",children:"—"})}),e.jsxs("span",{className:"absolute right-3 top-1/2 -translate-y-1/2 opacity-0 group-hover/row:opacity-100 transition-opacity flex items-center gap-2",children:[s.some(L)&&e.jsx(Y,{className:"w-4 h-4 text-text-tertiary hover:text-status-success",strokeWidth:1.5,onClick:u=>{u.stopPropagation(),l(t)}}),e.jsx(J,{className:"w-4 h-4 text-text-tertiary hover:text-accent",strokeWidth:1.5,onClick:u=>{u.stopPropagation(),d(t)}})]})]}),e.jsx(W,{open:o,children:e.jsx("div",{className:"ml-6",children:e.jsx(ze,{columns:j,data:x,keyFn:O,onRowClick:n,emptyMessage:"No workers",inline:!0})})})]})}let ct=0;function dt(t){const s=t.data||{},o=s.topic?String(s.topic):"",r=s.guid?String(s.guid).slice(0,8):"";switch(t.type){case"pong":return o?`Worker ${r}... on "${o}" responded`:`Engine ${r}... responded`;case"ping":return"Roll call broadcast";case"throttle":{const n=s.throttle,a=o?`queue "${o}"`:r?`node ${r}...`:"all nodes";return`${V(n)} applied to ${a}`}case"job":return`Job ${r?r+"...":""} ${s.status||"updated"}`;case"work":return`Dispatched to "${o||"worker"}" ${r?"("+r+"...)":""}`;case"activate":return`Worker "${o||"unknown"}" activated`;case"cron":return`Cron triggered ${o?'"'+o+'"':""}`;default:return o||r||t.type}}function ut(t){const s=[];let o=0;for(;o<t.length;){const r=t[o];if(r.type==="pong"){let n=o+1;for(;n<t.length&&t[n].type==="pong";)n++;const a=t.slice(o,n);if(a.length>=3)s.push({kind:"group",type:"pong",count:a.length,firstTimestamp:a[a.length-1].timestamp,lastTimestamp:a[0].timestamp,events:a});else for(const d of a)s.push({kind:"single",event:d});o=n}else s.push({kind:"single",event:r}),o++}return s}function le({event:t}){const[s,o]=i.useState(!1);return e.jsxs("div",{className:"border-b border-surface-border/50 last:border-b-0",children:[e.jsxs("button",{onClick:()=>o(!s),className:"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors",children:[e.jsx("span",{className:"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0",children:new Date(t.timestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}),e.jsx("span",{className:`text-[9px] font-medium px-1 py-0.5 rounded ${re[t.type]||"text-text-tertiary"} bg-surface-sunken whitespace-nowrap shrink-0`,children:He[t.type]||t.type}),e.jsx("span",{className:"text-[9px] text-text-secondary flex-1 min-w-0 truncate",children:dt(t)}),e.jsx("svg",{className:`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${s?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),e.jsx(W,{open:s,children:e.jsx("div",{className:"pb-2",children:e.jsx(De,{data:t.data})})})]})}function xt({group:t}){const[s,o]=i.useState(!1),r=t.events.filter(a=>{var d;return!((d=a.data)!=null&&d.topic)}).length,n=t.count-r;return e.jsxs("div",{className:"border-b border-surface-border/50 last:border-b-0",children:[e.jsxs("button",{onClick:()=>o(!s),className:"flex items-center gap-2 py-1.5 w-full text-left hover:bg-surface-hover/50 transition-colors",children:[e.jsx("span",{className:"text-[9px] font-mono text-text-tertiary whitespace-nowrap tabular-nums shrink-0",children:new Date(t.lastTimestamp).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"})}),e.jsx("span",{className:`text-[9px] font-medium px-1 py-0.5 rounded ${re.pong} bg-surface-sunken whitespace-nowrap shrink-0`,children:"roll call"}),e.jsxs("span",{className:"text-[9px] text-text-secondary flex-1 min-w-0 truncate",children:[t.count," nodes responded",r>0&&n>0?` (${r} engine${r!==1?"s":""}, ${n} worker${n!==1?"s":""})`:r>0?` (${r} engine${r!==1?"s":""})`:` (${n} worker${n!==1?"s":""})`]}),e.jsx("svg",{className:`w-2.5 h-2.5 text-text-tertiary shrink-0 transition-transform duration-150 ${s?"rotate-180":""}`,fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19 9l-7 7-7-7"})})]}),e.jsx(W,{open:s,children:e.jsx("div",{className:"ml-4",children:t.events.map(a=>e.jsx(le,{event:a},a.id))})})]})}function pt({channels:t,onToggle:s,customFilter:o,onCustomFilterChange:r}){return e.jsxs("div",{className:"space-y-3 pb-3 border-b border-surface-border mb-3",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Channels"}),e.jsx("p",{className:"text-[9px] text-text-tertiary",children:"Unchecked channels are dropped before buffering"})]}),e.jsx("div",{className:"grid grid-cols-2 gap-1",children:oe.map(n=>e.jsxs("label",{className:"flex items-center gap-2 cursor-pointer py-0.5",children:[e.jsx("input",{type:"checkbox",checked:t.has(n.key),onChange:()=>s(n.key),className:"w-3 h-3 rounded border-border accent-accent"}),e.jsx("span",{className:"text-[10px] text-text-secondary",title:n.description,children:n.label})]},n.key))}),e.jsxs("div",{children:[e.jsx("p",{className:"text-[9px] font-semibold uppercase tracking-widest text-text-tertiary mb-1",children:"Text Filter"}),e.jsx("input",{type:"text",value:o,onChange:n=>r(n.target.value),placeholder:"pong",className:"input text-[10px] font-mono py-1 px-2 w-full"}),e.jsxs("p",{className:"text-[9px] text-text-tertiary mt-1",children:["Filter by event type, e.g. ",e.jsx("span",{className:"font-mono",children:"pong"}),", ",e.jsx("span",{className:"font-mono",children:"throttle"}),", or any text in the event data."]})]})]})}function ht({bridgeActive:t}){const[s,o]=i.useState(!1),[r,n]=i.useState(!1),[a,d]=i.useState([]),[l,g]=i.useState(()=>new Set(oe.map(x=>x.key))),[c,w]=i.useState(""),f=i.useRef(l);i.useEffect(()=>{f.current=l},[l]);const y=i.useRef(c);i.useEffect(()=>{y.current=c},[c]);const k=x=>{g(j=>{const u=new Set(j);return u.has(x)?u.delete(x):u.add(x),u})};Je("lt.events.mesh.>",i.useCallback(x=>{var m;const j=((m=x.type)==null?void 0:m.replace("mesh.",""))||"unknown";if(!f.current.has(j))return;const u=y.current;u&&!`${j} ${JSON.stringify(x.data||x)}`.toLowerCase().includes(u.toLowerCase())||d(_=>[{id:++ct,type:j,timestamp:x.timestamp||new Date().toISOString(),data:x.data||x},..._].slice(0,Ke))},[]));const C=()=>d([]);return e.jsxs("div",{className:"border-l border-surface-border pl-6 pt-4 min-h-[300px] sticky top-14 self-start max-h-[calc(100vh-8rem)] flex flex-col",children:[e.jsxs("div",{className:"flex items-center gap-2 mb-3",children:[e.jsx("p",{className:"text-[10px] font-semibold uppercase tracking-widest text-text-tertiary",children:"Event Stream"}),e.jsx(Le,{className:`w-3 h-3 ${t?"text-status-success animate-pulse":"text-text-tertiary"}`}),e.jsx("span",{className:"text-[9px] text-text-tertiary",children:t?"Live":"..."}),e.jsxs("span",{className:"ml-auto flex items-center gap-1",children:[e.jsx("button",{onClick:()=>{o(x=>!x),n(!1)},className:`p-1 rounded transition-colors ${s?"text-accent bg-accent/10":"text-text-tertiary hover:text-text-primary"}`,title:"Configure channels",children:e.jsx(We,{className:"w-3.5 h-3.5"})}),e.jsx("button",{onClick:()=>{n(x=>!x),o(!1)},className:`p-1 rounded transition-colors ${r?"text-accent bg-accent/10":"text-text-tertiary hover:text-text-primary"}`,title:"View raw JSON",children:e.jsx(Qe,{className:"w-3.5 h-3.5"})}),a.length>0&&e.jsx("button",{onClick:C,className:"p-1 rounded text-text-tertiary hover:text-text-primary transition-colors",title:"Clear events",children:e.jsx(Fe,{className:"w-3.5 h-3.5"})})]})]}),e.jsx(W,{open:s,children:e.jsx(pt,{channels:l,onToggle:k,customFilter:c,onCustomFilterChange:w})}),e.jsx(W,{open:r,children:e.jsx("div",{className:"pb-3 border-b border-surface-border mb-3",children:e.jsx("pre",{className:"text-[9px] font-mono text-text-tertiary bg-surface-sunken rounded-lg p-3 max-h-[50vh] overflow-auto whitespace-pre-wrap",children:JSON.stringify(a.slice(0,50),null,2)})})}),a.length>0&&e.jsxs("p",{className:"text-[9px] text-text-tertiary mb-2",children:[a.length," events"]}),e.jsx("div",{className:"flex-1 overflow-y-auto",children:a.length===0?e.jsx("p",{className:"text-xs text-text-tertiary py-6 text-center",children:t?"Waiting for events...":"Subscribing..."}):ut(a).map((x,j)=>x.kind==="group"?e.jsx(xt,{group:x},`grp-${j}`):e.jsx(le,{event:x.event},x.event.id))})]})}function mt(t){const s=[],o=[],r=[];for(const n of t)L(n)?r.push(n):n.is_scout||R([n]).total>0?s.push(n):o.push(n);return s.sort((n,a)=>n.is_scout&&!a.is_scout?-1:!n.is_scout&&a.is_scout?1:R([a]).total-R([n]).total),o.sort((n,a)=>F(n.engine_id).localeCompare(F(a.engine_id))),r.sort((n,a)=>F(n.engine_id).localeCompare(F(a.engine_id))),{active:s,idle:o,paused:r}}function D({engine:t,isFirst:s,onThrottle:o}){const r=F(t.engine_id),n=Ye(t.engine_id),a=R([t]),d=t.stream_depth??0,l=L(t);return e.jsxs("div",{className:"group/row flex items-center gap-3 py-2 hover:bg-surface-hover/50 transition-colors rounded px-1",children:[l?e.jsx(U,{className:"w-3.5 h-3.5 text-status-warning shrink-0",strokeWidth:1.5}):e.jsx(Oe,{className:`w-3.5 h-3.5 shrink-0 ${a.total>0||t.is_scout?"text-status-success":"text-text-tertiary/30"}`,strokeWidth:1.5}),e.jsx("span",{className:`${s?"text-base font-medium":"text-xs"} text-text-primary truncate max-w-[180px]`,title:t.engine_id,children:r}),n&&e.jsx("span",{className:"text-[10px] text-text-tertiary/50",children:n}),t.is_scout&&e.jsx("span",{className:"text-[9px] text-amber-500 uppercase tracking-widest",children:"scout"}),e.jsx("span",{className:"flex-1"}),l&&e.jsx("span",{className:"text-[10px] text-status-warning",children:t.throttle===-1?"Paused":V(t.throttle)}),a.total>0&&e.jsx("span",{className:"text-[10px] font-mono tabular-nums text-text-tertiary w-16 text-right",children:a.total.toLocaleString()}),d>0&&e.jsxs("span",{className:`text-[10px] font-mono tabular-nums w-14 text-right ${d>100?"text-status-warning":"text-text-tertiary/50"}`,children:[d.toLocaleString()," q"]}),e.jsx("span",{className:"text-[10px] font-mono text-text-tertiary/40 w-12 text-right",children:Ze(t.inited)}),e.jsx("span",{className:"opacity-0 group-hover/row:opacity-100 transition-opacity",children:e.jsx("button",{onClick:g=>{g.stopPropagation(),o(t)},className:"text-text-tertiary hover:text-accent transition-colors",title:l?"Resume / adjust throttle":"Pause / throttle",children:e.jsx(J,{className:"w-3.5 h-3.5",strokeWidth:1.5})})})]})}function ee({label:t,engines:s,onThrottle:o}){const[r,n]=i.useState(!1);return s.length===0?null:e.jsxs("div",{className:"mt-1",children:[e.jsxs("button",{onClick:()=>n(!r),className:"flex items-center gap-1.5 text-[10px] text-text-tertiary hover:text-text-secondary transition-colors py-1",children:[e.jsx(ne,{className:`w-3 h-3 transition-transform duration-200 ${r?"rotate-90":""}`,strokeWidth:2}),s.length," ",t]}),e.jsx(W,{open:r,children:e.jsx("div",{className:"ml-1",children:s.map(a=>e.jsx(D,{engine:a,onThrottle:o},a.engine_id))})})]})}function gt({engines:t,onThrottle:s,isLoading:o}){const{active:r,idle:n,paused:a}=i.useMemo(()=>mt(t),[t]);return o?e.jsx("p",{className:"text-xs text-text-tertiary",children:"Discovering engines..."}):t.length===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:"No engines found."}):r.length===0&&n.length===0?e.jsxs("div",{children:[e.jsxs("div",{className:"flex items-center gap-3 py-2",children:[e.jsx(U,{className:"w-4 h-4 text-status-error shrink-0",strokeWidth:1.5}),e.jsxs("span",{className:"text-base text-status-error font-medium",children:["All ",t.length," engines paused"]})]}),e.jsx("p",{className:"text-[10px] text-text-tertiary ml-7",children:"Messages are accumulating. Resume at least one engine to restore processing."}),e.jsx("div",{className:"ml-1 mt-2",children:a.map(d=>e.jsx(D,{engine:d,onThrottle:s},d.engine_id))})]}):e.jsxs("div",{children:[r.map((d,l)=>e.jsx(D,{engine:d,isFirst:l===0,onThrottle:s},d.engine_id)),e.jsx(ee,{label:"idle",engines:n,onThrottle:s}),e.jsx(ee,{label:"paused",engines:a,onThrottle:s})]})}function ft({collapsed:t,toggleSection:s,activeDuration:o,streamStats:r,isLoading:n,queueMap:a,expandedQueues:d,toggleQueue:l,allQueuesExpanded:g,toggleAllQueues:c,handleRowClick:w,handleResumeThrottle:f,handleQueueThrottle:y,handleResumeQueue:k,engines:C,bridgeActive:x}){return e.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[1fr_340px] gap-6",children:[e.jsxs("div",{className:"flex flex-col gap-12 mt-10",children:[e.jsx(z,{title:`Message Volume (${o})`,sectionKey:"volume",isCollapsed:!!t.volume,onToggle:s,contentClassName:"mt-4 ml-7",children:e.jsx(lt,{byStream:(r==null?void 0:r.byStream)??[],onNodeFilter:()=>{},onQueueFilter:()=>{}})}),e.jsx(z,{title:`Engine Routers (${C.length})`,sectionKey:"engines",isCollapsed:!!t.engines,onToggle:s,contentClassName:"mt-4 ml-7",children:e.jsx(gt,{engines:C,onThrottle:w,isLoading:n})}),e.jsx(z,{title:"Worker Routers",sectionKey:"queues",isCollapsed:!!t.queues,onToggle:s,contentClassName:"mt-4 ml-7 flex flex-col gap-0",children:n?e.jsx("p",{className:"text-xs text-text-tertiary",children:"Discovering mesh nodes..."}):a.size===0?e.jsx("p",{className:"text-xs text-text-tertiary",children:'No worker routers found. Click "Roll Call" to discover.'}):e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"flex justify-end mb-2",children:e.jsx("button",{onClick:c,className:"text-[10px] text-accent hover:underline",children:g?"Collapse all":"Expand all"})}),[...a.entries()].sort(([j],[u])=>j.localeCompare(u)).map(([j,u])=>e.jsx(it,{queue:j,workers:u,expanded:d.has(j),onToggle:l,onWorkerClick:w,onResumeThrottle:f,onQueueThrottle:y,onResumeQueue:k,byStream:(r==null?void 0:r.byStream)??[],activeDuration:o},j))]})})]}),e.jsx(ht,{bridgeActive:x})]})}function Mt(){var K;const{data:t}=se(),s=(t==null?void 0:t.apps)??[],{filters:o,setFilter:r}=Se({filters:{app_id:"",duration:"1h"}}),n=((K=s[0])==null?void 0:K.appId)??"durable",a=o.app_id||n,d=o.duration||"1h",l=$e(),g=6e4,{data:c,isLoading:w,error:f,refetch:y,isFetching:k}=_e(a,g),{data:C}=Te(a,d,void 0,g),x=i.useMemo(()=>[...(c==null?void 0:c.profiles)??[]].sort((v,E)=>{const B=v.worker_topic||v.stream||"",Q=E.worker_topic||E.stream||"";return!v.worker_topic&&E.worker_topic?-1:v.worker_topic&&!E.worker_topic?1:B.localeCompare(Q)}),[c==null?void 0:c.profiles]),j=i.useMemo(()=>x.filter(h=>!A(h)),[x]),u=i.useMemo(()=>x.filter(A),[x]),m=i.useMemo(()=>Xe(x),[x]),_=x.filter(L).length,p=i.useMemo(()=>{const h=new Set(s.map(v=>v.appId));return a&&h.add(a),[...h].sort().map(v=>({value:v,label:v}))},[s,a]),[S]=Ve(),b=S.get("queue"),[$,M]=i.useState(()=>b?new Set([b]):new Set),N=i.useCallback(h=>{M(v=>{const E=v.has(h),B=E?new Set:new Set([h]),Q=new URLSearchParams(window.location.search);E?Q.delete("queue"):Q.set("queue",h);const G=Q.toString();return window.history.pushState(null,"",G?`?${G}`:window.location.pathname),B})},[]),T=m.size>0&&[...m.keys()].every(h=>$.has(h)),I=i.useCallback(()=>{M(T?new Set:new Set(m.keys()))},[T,m]),P="lt:controlplane:collapsed",[ie,ce]=i.useState(()=>{try{const h=JSON.parse(localStorage.getItem(P)||"{}");return b&&(h.queues=!1),h}catch{return{}}}),de=i.useCallback(h=>{ce(v=>{const E={...v,[h]:!v[h]};return localStorage.setItem(P,JSON.stringify(E)),E})},[]),{throttleModalOpen:ue,throttleTargets:q,selectedThrottleTargets:xe,throttleMutation:pe,handleBulkThrottle:he,handleRowClick:me,handleResumeThrottle:ge,handleResumeQueue:fe,handleQueueThrottle:be,closeThrottleModal:je}=st({activeAppId:a,allProfiles:x,profiles:x}),ye=i.useMemo(()=>{const h=[{label:"Engines",value:j.length,dotClass:"bg-blue-500"},{label:"Workers",value:u.length,dotClass:"bg-text-secondary"},{label:"Topics",value:m.size}];return _>0&&h.push({label:"Throttled",value:_,dotClass:"bg-status-warning"}),h},[j.length,u.length,m.size,_]),[H,we]=i.useState(!1),ke=i.useCallback(()=>{l.mutate({appId:a},{onSuccess:()=>we(!0)})},[a,l]);return i.useEffect(()=>{!H&&a&&ke()},[a]),e.jsxs("div",{children:[e.jsx(Ne,{title:"Routers",docsHash:"#docs:dashboard.md:task-queues",stats:ye,actions:e.jsx(ot,{})}),e.jsxs(ve,{actions:e.jsx("div",{className:"flex items-center gap-1",children:qe.map(h=>e.jsx("button",{onClick:()=>r("duration",h.value),className:`px-3 py-1 text-xs rounded-full transition-colors ${d===h.value?"bg-accent text-text-inverse":"text-text-tertiary hover:text-text-primary hover:bg-surface-hover"}`,children:h.label},h.value))}),children:[e.jsx(Ce,{label:"Application",value:o.app_id,onChange:h=>r("app_id",h),options:p}),e.jsxs("button",{onClick:()=>y(),disabled:k,className:"flex items-center gap-1.5 px-3 py-1.5 text-xs text-text-tertiary hover:text-text-primary transition-colors disabled:opacity-50",children:[e.jsx(Ie,{className:`w-3.5 h-3.5 ${k?"animate-spin":""}`}),"Roll Call"]})]}),f&&e.jsx("div",{className:"mb-6 px-4 py-3 rounded bg-status-error/10 border border-status-error/20",children:e.jsx("p",{className:"text-xs text-status-error font-medium",children:f.message==="Session expired"?"Session expired — please log in again.":`Failed to load mesh data: ${f.message}`})}),e.jsx(ft,{collapsed:ie,toggleSection:de,activeDuration:d,streamStats:C,isLoading:w,queueMap:m,expandedQueues:$,toggleQueue:N,allQueuesExpanded:T,toggleAllQueues:I,handleRowClick:me,handleResumeThrottle:ge,handleQueueThrottle:be,handleResumeQueue:fe,engines:j,bridgeActive:H}),e.jsx(at,{open:ue,onClose:je,targets:q.length>0?q:xe,onApply:he,isPending:pe.isPending})]})}export{Mt as ControlPlanePage};
|
|
2
|
+
//# sourceMappingURL=index-cUV1o7mj.js.map
|