@hotmeshio/long-tail 0.4.18 → 0.4.20
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/README.md +0 -2
- package/build/api/auth-sso.d.ts +12 -0
- package/build/api/auth-sso.js +54 -0
- package/build/api/escalations/bulk.js +2 -2
- package/build/api/escalations/claim.js +3 -13
- package/build/api/escalations/create.js +3 -2
- package/build/api/escalations/helpers.d.ts +1 -0
- package/build/api/escalations/helpers.js +12 -9
- package/build/api/escalations/list.d.ts +1 -0
- package/build/api/escalations/list.js +1 -0
- package/build/api/escalations/metadata.d.ts +7 -24
- package/build/api/escalations/metadata.js +31 -65
- package/build/api/escalations/single.js +3 -2
- package/build/api/settings.js +5 -0
- package/build/api/topics.d.ts +9 -0
- package/build/api/topics.js +31 -2
- package/build/lib/events/index.d.ts +1 -0
- package/build/lib/events/index.js +4 -0
- package/build/lib/events/publish.d.ts +12 -9
- package/build/lib/events/publish.js +27 -17
- package/build/modules/auth.d.ts +7 -0
- package/build/modules/auth.js +104 -2
- package/build/modules/sso.d.ts +6 -0
- package/build/modules/sso.js +20 -0
- package/build/routes/auth-sso.d.ts +2 -0
- package/build/routes/auth-sso.js +51 -0
- package/build/routes/bot-accounts.js +1 -1
- package/build/routes/controlplane.js +6 -6
- package/build/routes/escalations/list.js +1 -0
- package/build/routes/index.js +2 -0
- package/build/routes/mcp-endpoint.d.ts +17 -0
- package/build/routes/mcp-endpoint.js +70 -0
- package/build/routes/roles.js +5 -5
- package/build/routes/topics.js +2 -0
- package/build/routes/users.js +31 -5
- package/build/sdk/index.d.ts +1 -0
- package/build/services/agent/input-mapper.js +17 -1
- package/build/services/escalation/crud.d.ts +17 -1
- package/build/services/escalation/crud.js +62 -13
- package/build/services/escalation/queries.d.ts +1 -0
- package/build/services/escalation/queries.js +7 -0
- package/build/services/escalation/sql.d.ts +14 -5
- package/build/services/escalation/sql.js +53 -16
- package/build/services/mcp/exposure.d.ts +15 -0
- package/build/services/mcp/exposure.js +18 -0
- package/build/services/mcp/external-server.d.ts +15 -0
- package/build/services/mcp/external-server.js +125 -0
- package/build/services/mcp/seed-service-account.d.ts +11 -0
- package/build/services/mcp/seed-service-account.js +77 -0
- package/build/services/role/index.d.ts +1 -1
- package/build/services/role/index.js +2 -2
- package/build/services/topics/system-topics.js +29 -25
- package/build/services/user/index.d.ts +1 -1
- package/build/services/user/index.js +3 -1
- package/build/services/user/rbac.d.ts +16 -0
- package/build/services/user/rbac.js +31 -0
- package/build/services/user/sso-provision.d.ts +19 -0
- package/build/services/user/sso-provision.js +62 -0
- package/build/services/workflow-invocation.js +5 -3
- package/build/start/config.js +6 -0
- package/build/start/server.js +2 -0
- package/build/start/workers.js +15 -0
- package/build/system/index.js +53 -35
- package/build/system/mcp-servers/admin/agent-subscriptions.d.ts +5 -0
- package/build/system/mcp-servers/admin/agent-subscriptions.js +78 -0
- package/build/system/mcp-servers/admin/agents.d.ts +5 -0
- package/build/system/mcp-servers/admin/agents.js +103 -0
- package/build/system/mcp-servers/admin/bot-accounts.d.ts +5 -0
- package/build/system/mcp-servers/admin/bot-accounts.js +126 -0
- package/build/system/mcp-servers/admin/controlplane.d.ts +5 -0
- package/build/system/mcp-servers/admin/controlplane.js +107 -0
- package/build/system/mcp-servers/admin/escalations.js +88 -0
- package/build/system/mcp-servers/admin/exports.d.ts +5 -0
- package/build/system/mcp-servers/admin/exports.js +101 -0
- package/build/system/mcp-servers/admin/index.d.ts +16 -8
- package/build/system/mcp-servers/admin/index.js +36 -21
- package/build/system/mcp-servers/admin/pipelines.d.ts +5 -0
- package/build/system/mcp-servers/admin/pipelines.js +96 -0
- package/build/system/mcp-servers/admin/schemas.d.ts +614 -6
- package/build/system/mcp-servers/admin/schemas.js +239 -1
- package/build/system/mcp-servers/admin/settings.d.ts +5 -0
- package/build/system/mcp-servers/admin/settings.js +53 -0
- package/build/system/mcp-servers/admin/topics.d.ts +5 -0
- package/build/system/mcp-servers/admin/topics.js +101 -0
- package/build/system/seed/tool-manifests-admin.d.ts +5077 -188
- package/build/system/seed/tool-manifests-admin.js +79 -30
- package/build/system/seed/tool-manifests-data.d.ts +20 -0
- package/build/system/seed/tool-manifests-data.js +24 -6
- package/build/system/seed/tool-manifests-escalation.d.ts +5 -0
- package/build/system/seed/tool-manifests-escalation.js +5 -0
- package/build/system/seed/tool-manifests-events.d.ts +4 -0
- package/build/system/seed/tool-manifests-events.js +4 -0
- package/build/system/seed/tool-manifests-knowledge.d.ts +6 -0
- package/build/system/seed/tool-manifests-knowledge.js +7 -0
- package/build/system/seed/tool-manifests-workflows.d.ts +8 -0
- package/build/system/seed/tool-manifests-workflows.js +8 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/auth.d.ts +71 -0
- package/build/types/events.d.ts +17 -6
- package/build/types/index.d.ts +1 -1
- package/build/types/startup.d.ts +22 -1
- package/dashboard/dist/assets/{AdminDashboard-Cfo0mwL2.js → AdminDashboard-BwUGcCxQ.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-Cfo0mwL2.js.map → AdminDashboard-BwUGcCxQ.js.map} +1 -1
- package/dashboard/dist/assets/AgentConfigPage-DgrYzLwq.js +16 -0
- package/dashboard/dist/assets/AgentConfigPage-DgrYzLwq.js.map +1 -0
- package/dashboard/dist/assets/{AgentDetailPage-3mZA7SOb.js → AgentDetailPage-XJpl7wfJ.js} +4 -4
- package/dashboard/dist/assets/AgentDetailPage-XJpl7wfJ.js.map +1 -0
- package/dashboard/dist/assets/{AgentsPage-CTVocfBb.js → AgentsPage-CGpVG6r8.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-CTVocfBb.js.map → AgentsPage-CGpVG6r8.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DR1e0TQZ.js +2 -0
- package/dashboard/dist/assets/{AvailableEscalationsPage-CA9x9o5s.js.map → AvailableEscalationsPage-DR1e0TQZ.js.map} +1 -1
- package/dashboard/dist/assets/BotPicker-BKtjl6IL.js +2 -0
- package/dashboard/dist/assets/{BotPicker-BQp_Vs73.js.map → BotPicker-BKtjl6IL.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-wpVtkGeU.js → CapabilitiesPage-kCB8fyOj.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-wpVtkGeU.js.map → CapabilitiesPage-kCB8fyOj.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-2eZMMZiG.js → CollapsibleSection-C3tU61hB.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-2eZMMZiG.js.map → CollapsibleSection-C3tU61hB.js.map} +1 -1
- package/dashboard/dist/assets/{CredentialsPage-DJGLssm0.js → CredentialsPage-Dt4nJs_B.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-DJGLssm0.js.map → CredentialsPage-Dt4nJs_B.js.map} +1 -1
- package/dashboard/dist/assets/CronLabel-BdE6mHyA.js +2 -0
- package/dashboard/dist/assets/CronLabel-BdE6mHyA.js.map +1 -0
- package/dashboard/dist/assets/{CustomDurationPicker-DbyqfK35.js → CustomDurationPicker-B_Yxfb-u.js} +2 -2
- package/dashboard/dist/assets/{CustomDurationPicker-DbyqfK35.js.map → CustomDurationPicker-B_Yxfb-u.js.map} +1 -1
- package/dashboard/dist/assets/{DropZone-BkfRoUcm.js → DropZone-CptiQ0wc.js} +2 -2
- package/dashboard/dist/assets/{DropZone-BkfRoUcm.js.map → DropZone-CptiQ0wc.js.map} +1 -1
- package/dashboard/dist/assets/ElapsedCell-tcGx5PFI.js +2 -0
- package/dashboard/dist/assets/{ElapsedCell-BPYm8RA7.js.map → ElapsedCell-tcGx5PFI.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-kYGHfnLf.js → EscalationsOverview-1KO5dXzk.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-kYGHfnLf.js.map → EscalationsOverview-1KO5dXzk.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-DSDzJMer.js → EventTable-DnpsQ6Ew.js} +2 -2
- package/dashboard/dist/assets/{EventTable-DSDzJMer.js.map → EventTable-DnpsQ6Ew.js.map} +1 -1
- package/dashboard/dist/assets/HomePage-B2Jgo1J1.js +2 -0
- package/dashboard/dist/assets/HomePage-B2Jgo1J1.js.map +1 -0
- package/dashboard/dist/assets/ListToolbar-jrVba7QN.js +2 -0
- package/dashboard/dist/assets/{ListToolbar-DEef1_-T.js.map → ListToolbar-jrVba7QN.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-CZFW5qMb.js → McpOverview-BzyxJyc9.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-CZFW5qMb.js.map → McpOverview-BzyxJyc9.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-q9xH-QRo.js → McpQueryDetailPage-DXNseeKl.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-q9xH-QRo.js.map → McpQueryDetailPage-DXNseeKl.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-D14466yi.js → McpQueryPage-WZfTY43_.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-D14466yi.js.map → McpQueryPage-WZfTY43_.js.map} +1 -1
- package/dashboard/dist/assets/McpRunDetailPage-DKZp-p7S.js +2 -0
- package/dashboard/dist/assets/McpRunDetailPage-DKZp-p7S.js.map +1 -0
- package/dashboard/dist/assets/McpRunsPage-SXyiwc0d.js +2 -0
- package/dashboard/dist/assets/{McpRunsPage-aZg057y3.js.map → McpRunsPage-SXyiwc0d.js.map} +1 -1
- package/dashboard/dist/assets/OperatorDashboard-Cy7ySMXj.js +2 -0
- package/dashboard/dist/assets/OperatorDashboard-Cy7ySMXj.js.map +1 -0
- package/dashboard/dist/assets/{PageHeader-CR6TpJG_.js → PageHeader-BuJpMxyu.js} +2 -2
- package/dashboard/dist/assets/{PageHeader-CR6TpJG_.js.map → PageHeader-BuJpMxyu.js.map} +1 -1
- package/dashboard/dist/assets/{PageHeaderWithStats-CRcQEAO1.js → PageHeaderWithStats-yD_PTbOl.js} +2 -2
- package/dashboard/dist/assets/{PageHeaderWithStats-CRcQEAO1.js.map → PageHeaderWithStats-yD_PTbOl.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-DyzNjwu8.js → ProcessDetailPage-DYIfvWyc.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-DyzNjwu8.js.map → ProcessDetailPage-DYIfvWyc.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CT_3b5Wt.js → ProcessesListPage-DR1RGaMl.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CT_3b5Wt.js.map → ProcessesListPage-DR1RGaMl.js.map} +1 -1
- package/dashboard/dist/assets/{RolePill-BC54Vn-U.js → RolePill-SasQKc_B.js} +2 -2
- package/dashboard/dist/assets/{RolePill-BC54Vn-U.js.map → RolePill-SasQKc_B.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-CpRJq-sg.js → RolesPage-pMERxj15.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-CpRJq-sg.js.map → RolesPage-pMERxj15.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-C20rdNsC.js → RunAsSelector-B-ksMoEj.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-C20rdNsC.js.map → RunAsSelector-B-ksMoEj.js.map} +1 -1
- package/dashboard/dist/assets/ServerName-CHspudaC.js +2 -0
- package/dashboard/dist/assets/{ServerName-Q6okiv4f.js.map → ServerName-CHspudaC.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-CbFaU4bq.js → SwimlaneTimeline-Cr_K5qpu.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-CbFaU4bq.js.map → SwimlaneTimeline-Cr_K5qpu.js.map} +1 -1
- package/dashboard/dist/assets/{TagInput-D6l1SPWd.js → TagInput-DvF3j8MA.js} +2 -2
- package/dashboard/dist/assets/{TagInput-D6l1SPWd.js.map → TagInput-DvF3j8MA.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-22cJsFmM.js → TaskDetailPage-BO5p7AEe.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-22cJsFmM.js.map → TaskDetailPage-BO5p7AEe.js.map} +1 -1
- package/dashboard/dist/assets/{TaskQueuePill-iDBVCEQQ.js → TaskQueuePill-BCQrS2oK.js} +2 -2
- package/dashboard/dist/assets/{TaskQueuePill-iDBVCEQQ.js.map → TaskQueuePill-BCQrS2oK.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-BDmaUIKu.js → TasksListPage-BRg-uFtF.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-BDmaUIKu.js.map → TasksListPage-BRg-uFtF.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-7wqEp87-.js → TimeAgo-BSzN6rAH.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-7wqEp87-.js.map → TimeAgo-BSzN6rAH.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-BBCf8zsN.js → TimestampCell-DL6zMNEQ.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-BBCf8zsN.js.map → TimestampCell-DL6zMNEQ.js.map} +1 -1
- package/dashboard/dist/assets/{ToolPill-HcRTggHo.js → ToolPill-1aTqYtzp.js} +2 -2
- package/dashboard/dist/assets/{ToolPill-HcRTggHo.js.map → ToolPill-1aTqYtzp.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-Dosq1cqG.js → ToolTestPanel-fLzNp79U.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-Dosq1cqG.js.map → ToolTestPanel-fLzNp79U.js.map} +1 -1
- package/dashboard/dist/assets/TopicDetailPage-D7gCsPKB.js +9 -0
- package/dashboard/dist/assets/TopicDetailPage-D7gCsPKB.js.map +1 -0
- package/dashboard/dist/assets/{TopicsPage-tVPdz-k0.js → TopicsPage-B3Aa8Haz.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-tVPdz-k0.js.map → TopicsPage-B3Aa8Haz.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-DX7IBjFn.js → UserName-BjHIJWgh.js} +2 -2
- package/dashboard/dist/assets/{UserName-DX7IBjFn.js.map → UserName-BjHIJWgh.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-BjC0j9_L.js → WorkflowExecutionPage-BQ7AYlQA.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-BjC0j9_L.js.map → WorkflowExecutionPage-BQ7AYlQA.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowPill-54px0YiY.js → WorkflowPill-Z-zHRKOK.js} +2 -2
- package/dashboard/dist/assets/{WorkflowPill-54px0YiY.js.map → WorkflowPill-Z-zHRKOK.js.map} +1 -1
- package/dashboard/dist/assets/WorkflowsDashboard-D-G8Xudz.js +2 -0
- package/dashboard/dist/assets/WorkflowsDashboard-D-G8Xudz.js.map +1 -0
- package/dashboard/dist/assets/{WorkflowsOverview-DaJRDkNy.js → WorkflowsOverview-B4DUcVxs.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-DaJRDkNy.js.map → WorkflowsOverview-B4DUcVxs.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-CkpQaUmz.js → YamlWorkflowsPage-CnTNOku0.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-CkpQaUmz.js.map → YamlWorkflowsPage-CnTNOku0.js.map} +1 -1
- package/dashboard/dist/assets/{agents-B-P5MlEx.js → agents-CkvQDr9b.js} +2 -2
- package/dashboard/dist/assets/{agents-B-P5MlEx.js.map → agents-CkvQDr9b.js.map} +1 -1
- package/dashboard/dist/assets/{bots-CZz9iVys.js → bots-CzuMCVgU.js} +2 -2
- package/dashboard/dist/assets/{bots-CZz9iVys.js.map → bots-CzuMCVgU.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DrZ8Vw_v.js → capabilities-CbGmS0ty.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DrZ8Vw_v.js.map → capabilities-CbGmS0ty.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-cj-1c-1C.js → controlplane-DGvwkuYx.js} +2 -2
- package/dashboard/dist/assets/{controlplane-cj-1c-1C.js.map → controlplane-DGvwkuYx.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-BEVFyQnE.js → escalation-B7ysVToF.js} +2 -2
- package/dashboard/dist/assets/{escalation-BEVFyQnE.js.map → escalation-B7ysVToF.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Beox3TXH.js → escalation-columns-CHQEJU1j.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Beox3TXH.js.map → escalation-columns-CHQEJU1j.js.map} +1 -1
- package/dashboard/dist/assets/{helpers-B4gzNq9h.js → helpers-BFOjXa4r.js} +2 -2
- package/dashboard/dist/assets/{helpers-B4gzNq9h.js.map → helpers-BFOjXa4r.js.map} +1 -1
- package/dashboard/dist/assets/index-B9_1AZaG.js +2 -0
- package/dashboard/dist/assets/{index-3n5VREXN.js.map → index-B9_1AZaG.js.map} +1 -1
- package/dashboard/dist/assets/{index-BCQ65lNu.js → index-BFaDxPxA.js} +2 -2
- package/dashboard/dist/assets/{index-BCQ65lNu.js.map → index-BFaDxPxA.js.map} +1 -1
- package/dashboard/dist/assets/index-BduDiGcw.js +15 -0
- package/dashboard/dist/assets/{index-UtAfnStw.js.map → index-BduDiGcw.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bh-PnP17.js → index-BeLphL59.js} +2 -2
- package/dashboard/dist/assets/{index-Bh-PnP17.js.map → index-BeLphL59.js.map} +1 -1
- package/dashboard/dist/assets/index-C--SEsU7.css +1 -0
- package/dashboard/dist/assets/{index-_DfbFHXk.js → index-CRiBkHPb.js} +2 -2
- package/dashboard/dist/assets/{index-_DfbFHXk.js.map → index-CRiBkHPb.js.map} +1 -1
- package/dashboard/dist/assets/{index-DdKbIZNE.js → index-CbrMW-gM.js} +2 -2
- package/dashboard/dist/assets/{index-DdKbIZNE.js.map → index-CbrMW-gM.js.map} +1 -1
- package/dashboard/dist/assets/{index-aJRDh4zW.js → index-CvOGgvzP.js} +2 -2
- package/dashboard/dist/assets/{index-aJRDh4zW.js.map → index-CvOGgvzP.js.map} +1 -1
- package/dashboard/dist/assets/{index-D1MywQ2z.js → index-DDlrQeTj.js} +2 -2
- package/dashboard/dist/assets/{index-D1MywQ2z.js.map → index-DDlrQeTj.js.map} +1 -1
- package/dashboard/dist/assets/{index-BYXiz05a.js → index-DQHmfTPo.js} +2 -2
- package/dashboard/dist/assets/{index-BYXiz05a.js.map → index-DQHmfTPo.js.map} +1 -1
- package/dashboard/dist/assets/{index-BpN31nuC.js → index-_BRA9uFL.js} +25 -25
- package/dashboard/dist/assets/index-_BRA9uFL.js.map +1 -0
- package/dashboard/dist/assets/index-a98qWLB-.js +2 -0
- package/dashboard/dist/assets/index-a98qWLB-.js.map +1 -0
- package/dashboard/dist/assets/index-l_8R6U4r.js +6 -0
- package/dashboard/dist/assets/index-l_8R6U4r.js.map +1 -0
- package/dashboard/dist/assets/{index-D4KGadbW.js → index-v0OQpgXS.js} +2 -2
- package/dashboard/dist/assets/{index-D4KGadbW.js.map → index-v0OQpgXS.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-DhtKWMON.js → knowledge-BlF8UMrk.js} +2 -2
- package/dashboard/dist/assets/{knowledge-DhtKWMON.js.map → knowledge-BlF8UMrk.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-BXN7-wGF.js → mcp-MtXuky8q.js} +2 -2
- package/dashboard/dist/assets/{mcp-BXN7-wGF.js.map → mcp-MtXuky8q.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BIJP4mQJ.js → mcp-query-DQ-J1Q0K.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BIJP4mQJ.js.map → mcp-query-DQ-J1Q0K.js.map} +1 -1
- package/dashboard/dist/assets/{namespaces-ne_yDQZX.js → namespaces-DtsT_GoV.js} +2 -2
- package/dashboard/dist/assets/{namespaces-ne_yDQZX.js.map → namespaces-DtsT_GoV.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-Bcz62DoS.js → pipelines-BjlCm9VH.js} +2 -2
- package/dashboard/dist/assets/{pipelines-Bcz62DoS.js.map → pipelines-BjlCm9VH.js.map} +1 -1
- package/dashboard/dist/assets/{roles-De2CzGCy.js → roles-D-LhJ82d.js} +2 -2
- package/dashboard/dist/assets/{roles-De2CzGCy.js.map → roles-D-LhJ82d.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-4yL5EfxI.js → tasks-BrP_8uEN.js} +2 -2
- package/dashboard/dist/assets/{tasks-4yL5EfxI.js.map → tasks-BrP_8uEN.js.map} +1 -1
- package/dashboard/dist/assets/topics-DUk-zX5D.js +2 -0
- package/dashboard/dist/assets/{topics-DDKHpRwP.js.map → topics-DUk-zX5D.js.map} +1 -1
- package/dashboard/dist/assets/useEventHooks-XNNzwADV.js +2 -0
- package/dashboard/dist/assets/useEventHooks-XNNzwADV.js.map +1 -0
- package/dashboard/dist/assets/{useYamlActivityEvents-Dv6GhDkh.js → useYamlActivityEvents-DANQ5jIY.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-Dv6GhDkh.js.map → useYamlActivityEvents-DANQ5jIY.js.map} +1 -1
- package/dashboard/dist/assets/{users-pSMWP58G.js → users-vj0JgOkA.js} +2 -2
- package/dashboard/dist/assets/{users-pSMWP58G.js.map → users-vj0JgOkA.js.map} +1 -1
- package/dashboard/dist/assets/{vendor-icons-CrrAvF2g.js → vendor-icons-Doy0g69_.js} +116 -111
- package/dashboard/dist/assets/vendor-icons-Doy0g69_.js.map +1 -0
- package/dashboard/dist/assets/{workflows-COYPOe2I.js → workflows-CmqgGPzI.js} +2 -2
- package/dashboard/dist/assets/{workflows-COYPOe2I.js.map → workflows-CmqgGPzI.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-1dF3ig6u.js → yaml-workflows-DNFyjBXH.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-1dF3ig6u.js.map → yaml-workflows-DNFyjBXH.js.map} +1 -1
- package/dashboard/dist/index.html +3 -3
- package/docs/api/http/controlplane.md +1 -1
- package/docs/api/http/mcp-endpoint.md +133 -0
- package/docs/api/http/roles.md +46 -0
- package/docs/api/http/service-accounts.md +15 -0
- package/docs/api/http/settings.md +6 -0
- package/docs/api/mcp/admin.md +1187 -0
- package/docs/api/mcp/claude-code.md +47 -0
- package/docs/api/mcp/docs.md +54 -0
- package/docs/api/mcp/events.md +80 -0
- package/docs/api/mcp/file-storage.md +76 -0
- package/docs/api/mcp/http-fetch.md +64 -0
- package/docs/api/mcp/human-queue.md +101 -0
- package/docs/api/mcp/index.md +52 -0
- package/docs/api/mcp/knowledge.md +125 -0
- package/docs/api/mcp/oauth.md +62 -0
- package/docs/api/mcp/schema-exchange.md +56 -0
- package/docs/api/mcp/translation.md +28 -0
- package/docs/api/mcp/vision.md +46 -0
- package/docs/api/sdk/settings.md +3 -1
- package/docs/auth.md +109 -0
- package/docs/dashboard.md +1 -1
- package/package.json +1 -1
- package/build/system/mcp-servers/playwright/browser-lifecycle.d.ts +0 -26
- package/build/system/mcp-servers/playwright/browser-lifecycle.js +0 -125
- package/build/system/mcp-servers/playwright/index.d.ts +0 -25
- package/build/system/mcp-servers/playwright/index.js +0 -42
- package/build/system/mcp-servers/playwright/schemas.d.ts +0 -394
- package/build/system/mcp-servers/playwright/schemas.js +0 -90
- package/build/system/mcp-servers/playwright/tools-atomic.d.ts +0 -2
- package/build/system/mcp-servers/playwright/tools-atomic.js +0 -9
- package/build/system/mcp-servers/playwright/tools-navigation.d.ts +0 -2
- package/build/system/mcp-servers/playwright/tools-navigation.js +0 -153
- package/build/system/mcp-servers/playwright/tools-page-interaction.d.ts +0 -2
- package/build/system/mcp-servers/playwright/tools-page-interaction.js +0 -162
- package/build/system/mcp-servers/playwright/tools-run-script.d.ts +0 -2
- package/build/system/mcp-servers/playwright/tools-run-script.js +0 -207
- package/build/system/mcp-servers/playwright/types.d.ts +0 -8
- package/build/system/mcp-servers/playwright/types.js +0 -30
- package/build/system/mcp-servers/playwright/vision-helper.d.ts +0 -12
- package/build/system/mcp-servers/playwright/vision-helper.js +0 -81
- package/build/system/mcp-servers/playwright-cli/helpers.d.ts +0 -11
- package/build/system/mcp-servers/playwright-cli/helpers.js +0 -20
- package/build/system/mcp-servers/playwright-cli/index.d.ts +0 -4
- package/build/system/mcp-servers/playwright-cli/index.js +0 -15
- package/build/system/mcp-servers/playwright-cli/schemas.d.ts +0 -219
- package/build/system/mcp-servers/playwright-cli/schemas.js +0 -75
- package/build/system/mcp-servers/playwright-cli/tools-auth.d.ts +0 -2
- package/build/system/mcp-servers/playwright-cli/tools-auth.js +0 -183
- package/build/system/mcp-servers/playwright-cli/tools-capture.d.ts +0 -2
- package/build/system/mcp-servers/playwright-cli/tools-capture.js +0 -273
- package/build/system/seed/tool-manifests-browser.d.ts +0 -577
- package/build/system/seed/tool-manifests-browser.js +0 -158
- package/dashboard/dist/assets/AgentConfigPage-DBtvb2x5.js +0 -16
- package/dashboard/dist/assets/AgentConfigPage-DBtvb2x5.js.map +0 -1
- package/dashboard/dist/assets/AgentDetailPage-3mZA7SOb.js.map +0 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-CA9x9o5s.js +0 -2
- package/dashboard/dist/assets/BotPicker-BQp_Vs73.js +0 -2
- package/dashboard/dist/assets/CronLabel-DY8VdTS9.js +0 -2
- package/dashboard/dist/assets/CronLabel-DY8VdTS9.js.map +0 -1
- package/dashboard/dist/assets/ElapsedCell-BPYm8RA7.js +0 -2
- package/dashboard/dist/assets/EventTopicPill-CCWCs07y.js +0 -2
- package/dashboard/dist/assets/EventTopicPill-CCWCs07y.js.map +0 -1
- package/dashboard/dist/assets/HomePage-CwRebzmO.js +0 -2
- package/dashboard/dist/assets/HomePage-CwRebzmO.js.map +0 -1
- package/dashboard/dist/assets/ListToolbar-DEef1_-T.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-X0sfRFTk.js +0 -2
- package/dashboard/dist/assets/McpRunDetailPage-X0sfRFTk.js.map +0 -1
- package/dashboard/dist/assets/McpRunsPage-aZg057y3.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-iZEHnndU.js +0 -2
- package/dashboard/dist/assets/OperatorDashboard-iZEHnndU.js.map +0 -1
- package/dashboard/dist/assets/ServerName-Q6okiv4f.js +0 -2
- package/dashboard/dist/assets/TopicDetailPage-DW97-YHQ.js +0 -9
- package/dashboard/dist/assets/TopicDetailPage-DW97-YHQ.js.map +0 -1
- package/dashboard/dist/assets/WorkflowsDashboard-eCH4gpAk.js +0 -2
- package/dashboard/dist/assets/WorkflowsDashboard-eCH4gpAk.js.map +0 -1
- package/dashboard/dist/assets/index-3n5VREXN.js +0 -2
- package/dashboard/dist/assets/index-BAXzN-QB.js +0 -6
- package/dashboard/dist/assets/index-BAXzN-QB.js.map +0 -1
- package/dashboard/dist/assets/index-BpN31nuC.js.map +0 -1
- package/dashboard/dist/assets/index-C37LMzJa.css +0 -1
- package/dashboard/dist/assets/index-C5dHozmW.js +0 -2
- package/dashboard/dist/assets/index-C5dHozmW.js.map +0 -1
- package/dashboard/dist/assets/index-UtAfnStw.js +0 -15
- package/dashboard/dist/assets/topics-DDKHpRwP.js +0 -2
- package/dashboard/dist/assets/useEventHooks-NzIyvoGY.js +0 -2
- package/dashboard/dist/assets/useEventHooks-NzIyvoGY.js.map +0 -1
- package/dashboard/dist/assets/vendor-icons-CrrAvF2g.js.map +0 -1
package/README.md
CHANGED
|
@@ -62,8 +62,6 @@ Dashboard at [http://localhost:3000](http://localhost:3000). The [boilerplate](h
|
|
|
62
62
|
|
|
63
63
|
## The pattern
|
|
64
64
|
|
|
65
|
-
Most systems start with a durable workflow and stop there. Long Tail keeps going.
|
|
66
|
-
|
|
67
65
|
**Step 1 — Author a durable workflow.** Your function checkpoints to Postgres. It can sleep, branch, call child workflows, wait for signals. Standard durable execution.
|
|
68
66
|
|
|
69
67
|
**Step 2 — Certify it.** Promotion to certified adds interceptor guarantees: failures escalate instead of throwing, escalation chains route through RBAC-scoped roles, and every error is either handled or surfaced. It cannot silently fail.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Request } from 'express';
|
|
2
|
+
import type { LTApiResult } from '../types/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* Exchange host authentication for a Long Tail JWT.
|
|
5
|
+
*
|
|
6
|
+
* Calls `sso.resolve(req)` to extract the host identity, JIT provisions
|
|
7
|
+
* the user in `lt_users`, and returns a signed JWT the dashboard can
|
|
8
|
+
* store for subsequent API calls.
|
|
9
|
+
*
|
|
10
|
+
* No request body required — the host's cookies/headers carry the auth.
|
|
11
|
+
*/
|
|
12
|
+
export declare function exchangeSSO(req: Request): Promise<LTApiResult>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exchangeSSO = exchangeSSO;
|
|
4
|
+
const sso_1 = require("../modules/sso");
|
|
5
|
+
const sso_provision_1 = require("../services/user/sso-provision");
|
|
6
|
+
const auth_1 = require("../modules/auth");
|
|
7
|
+
/**
|
|
8
|
+
* Exchange host authentication for a Long Tail JWT.
|
|
9
|
+
*
|
|
10
|
+
* Calls `sso.resolve(req)` to extract the host identity, JIT provisions
|
|
11
|
+
* the user in `lt_users`, and returns a signed JWT the dashboard can
|
|
12
|
+
* store for subsequent API calls.
|
|
13
|
+
*
|
|
14
|
+
* No request body required — the host's cookies/headers carry the auth.
|
|
15
|
+
*/
|
|
16
|
+
async function exchangeSSO(req) {
|
|
17
|
+
try {
|
|
18
|
+
const ssoConfig = (0, sso_1.getSSOConfig)();
|
|
19
|
+
if (!ssoConfig) {
|
|
20
|
+
return { status: 404, error: 'SSO not configured' };
|
|
21
|
+
}
|
|
22
|
+
const identity = await ssoConfig.resolve(req);
|
|
23
|
+
if (!identity) {
|
|
24
|
+
return { status: 401, error: 'Host authentication required' };
|
|
25
|
+
}
|
|
26
|
+
const provisioned = await (0, sso_provision_1.ssoProvision)(identity, ssoConfig);
|
|
27
|
+
const highestType = provisioned.roles.some((r) => r.type === 'superadmin')
|
|
28
|
+
? 'superadmin'
|
|
29
|
+
: provisioned.roles.some((r) => r.type === 'admin')
|
|
30
|
+
? 'admin'
|
|
31
|
+
: 'member';
|
|
32
|
+
const token = (0, auth_1.signToken)({
|
|
33
|
+
userId: provisioned.userId,
|
|
34
|
+
role: highestType,
|
|
35
|
+
roles: provisioned.roles,
|
|
36
|
+
sso: true,
|
|
37
|
+
}, '24h');
|
|
38
|
+
return {
|
|
39
|
+
status: 200,
|
|
40
|
+
data: {
|
|
41
|
+
token,
|
|
42
|
+
user: {
|
|
43
|
+
id: provisioned.userId,
|
|
44
|
+
external_id: identity.externalId,
|
|
45
|
+
display_name: identity.displayName || identity.externalId,
|
|
46
|
+
roles: provisioned.roles,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
return { status: 500, error: err.message };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -141,8 +141,8 @@ async function bulkAssign(input, auth) {
|
|
|
141
141
|
if (!perm.allowed)
|
|
142
142
|
return perm;
|
|
143
143
|
// Non-superadmin: target user must hold each escalation's role
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
144
|
+
const hasGlobal = await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId);
|
|
145
|
+
if (!hasGlobal) {
|
|
146
146
|
const roles = await escalationService.getEscalationRoles(ids);
|
|
147
147
|
for (const role of roles) {
|
|
148
148
|
const targetHasRole = await userService.hasRole(targetUserId, role);
|
|
@@ -37,7 +37,7 @@ exports.claimEscalation = claimEscalation;
|
|
|
37
37
|
exports.releaseEscalation = releaseEscalation;
|
|
38
38
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
39
39
|
const userService = __importStar(require("../../services/user"));
|
|
40
|
-
const
|
|
40
|
+
const helpers_1 = require("./helpers");
|
|
41
41
|
/**
|
|
42
42
|
* Claim a pending escalation for the authenticated user.
|
|
43
43
|
*
|
|
@@ -57,8 +57,8 @@ async function claimEscalation(input, auth) {
|
|
|
57
57
|
if (!escalation) {
|
|
58
58
|
return { status: 404, error: 'Escalation not found' };
|
|
59
59
|
}
|
|
60
|
-
const
|
|
61
|
-
if (!
|
|
60
|
+
const hasGlobal = await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId);
|
|
61
|
+
if (!hasGlobal) {
|
|
62
62
|
const userHasRole = await userService.hasRole(auth.userId, escalation.role);
|
|
63
63
|
if (!userHasRole) {
|
|
64
64
|
return {
|
|
@@ -94,16 +94,6 @@ async function releaseEscalation(input, auth) {
|
|
|
94
94
|
if (!result) {
|
|
95
95
|
return { status: 409, error: 'Escalation not found or not claimed by you' };
|
|
96
96
|
}
|
|
97
|
-
(0, publish_1.publishEscalationEvent)({
|
|
98
|
-
type: 'escalation.released',
|
|
99
|
-
source: 'api',
|
|
100
|
-
workflowId: result.workflow_id || '',
|
|
101
|
-
workflowName: result.workflow_type || '',
|
|
102
|
-
taskQueue: result.task_queue || '',
|
|
103
|
-
escalationId: input.id,
|
|
104
|
-
status: 'released',
|
|
105
|
-
data: { released_by: auth.userId },
|
|
106
|
-
});
|
|
107
97
|
return { status: 200, data: { escalation: result } };
|
|
108
98
|
}
|
|
109
99
|
catch (err) {
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.createEscalation = createEscalation;
|
|
37
37
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
38
38
|
const userService = __importStar(require("../../services/user"));
|
|
39
|
+
const helpers_1 = require("./helpers");
|
|
39
40
|
// ── Create ────────────────────────────────────────────────────────────────
|
|
40
41
|
/**
|
|
41
42
|
* Create a standalone escalation (not tied to a workflow).
|
|
@@ -65,8 +66,8 @@ async function createEscalation(input, auth) {
|
|
|
65
66
|
return { status: 400, error: 'role is required' };
|
|
66
67
|
}
|
|
67
68
|
// RBAC: caller must hold the target role or be superadmin
|
|
68
|
-
const
|
|
69
|
-
if (!
|
|
69
|
+
const hasGlobal = await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId);
|
|
70
|
+
if (!hasGlobal) {
|
|
70
71
|
const userHasRole = await userService.hasRole(auth.userId, role);
|
|
71
72
|
if (!userHasRole) {
|
|
72
73
|
return { status: 403, error: `You must hold the "${role}" role or be a superadmin to create escalations for it` };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { hasGlobalEscalationAccess } from '../../services/user';
|
|
1
2
|
export declare function getVisibleRoles(userId: string): Promise<string[] | undefined>;
|
|
2
3
|
export declare function validateIds(ids: unknown): ids is string[];
|
|
3
4
|
export declare function checkBulkPermission(userId: string, ids: string[]): Promise<{
|
|
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.hasGlobalEscalationAccess = void 0;
|
|
36
37
|
exports.getVisibleRoles = getVisibleRoles;
|
|
37
38
|
exports.validateIds = validateIds;
|
|
38
39
|
exports.checkBulkPermission = checkBulkPermission;
|
|
@@ -42,9 +43,11 @@ const escalationService = __importStar(require("../../services/escalation"));
|
|
|
42
43
|
const userService = __importStar(require("../../services/user"));
|
|
43
44
|
const publish_1 = require("../../lib/events/publish");
|
|
44
45
|
// ── Private helpers ────────────────────────────────────────────────────────
|
|
46
|
+
// Re-export from service layer for use by escalation API modules
|
|
47
|
+
var user_1 = require("../../services/user");
|
|
48
|
+
Object.defineProperty(exports, "hasGlobalEscalationAccess", { enumerable: true, get: function () { return user_1.hasGlobalEscalationAccess; } });
|
|
45
49
|
async function getVisibleRoles(userId) {
|
|
46
|
-
|
|
47
|
-
if (isSuperAdminUser)
|
|
50
|
+
if (await userService.hasGlobalEscalationAccess(userId))
|
|
48
51
|
return undefined;
|
|
49
52
|
const userRoles = await userService.getUserRoles(userId);
|
|
50
53
|
return userRoles.map((r) => r.role);
|
|
@@ -53,15 +56,15 @@ function validateIds(ids) {
|
|
|
53
56
|
return Array.isArray(ids) && ids.length > 0;
|
|
54
57
|
}
|
|
55
58
|
async function checkBulkPermission(userId, ids) {
|
|
56
|
-
|
|
57
|
-
if (isSuperAdminUser)
|
|
59
|
+
if (await userService.hasGlobalEscalationAccess(userId))
|
|
58
60
|
return { allowed: true };
|
|
59
61
|
const roles = await escalationService.getEscalationRoles(ids);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
if (!roles.length)
|
|
63
|
+
return { allowed: true };
|
|
64
|
+
// Single batched query instead of N+1 loop
|
|
65
|
+
const canManageAll = await userService.hasRolesAsAdmin(userId, roles);
|
|
66
|
+
if (!canManageAll) {
|
|
67
|
+
return { allowed: false, status: 403, error: 'Insufficient permissions for one or more escalation roles' };
|
|
65
68
|
}
|
|
66
69
|
return { allowed: true };
|
|
67
70
|
}
|
|
@@ -2,13 +2,8 @@ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
|
|
|
2
2
|
/**
|
|
3
3
|
* Find escalations by a metadata key-value pair.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @param input.key — metadata field name (e.g. `"orderId"`)
|
|
9
|
-
* @param input.value — metadata field value (e.g. `"order-123"`)
|
|
10
|
-
* @param input.status — optional status filter (e.g. `"pending"`)
|
|
11
|
-
* @returns `{ status: 200, data: { escalations, total } }`
|
|
5
|
+
* Single query with window function for count. Results are
|
|
6
|
+
* RBAC-scoped to the caller's visible roles.
|
|
12
7
|
*/
|
|
13
8
|
export declare function findByMetadata(input: {
|
|
14
9
|
key: string;
|
|
@@ -20,15 +15,9 @@ export declare function findByMetadata(input: {
|
|
|
20
15
|
/**
|
|
21
16
|
* Claim an escalation by metadata key-value pair.
|
|
22
17
|
*
|
|
23
|
-
*
|
|
24
|
-
* the
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* @param input.key — metadata field name
|
|
28
|
-
* @param input.value — metadata field value
|
|
29
|
-
* @param input.durationMinutes — claim duration (default 30)
|
|
30
|
-
* @param input.assignee — optional external_id of the user to claim as
|
|
31
|
-
* @returns `{ status: 200, data: { escalation, isExtension } }`
|
|
18
|
+
* Single atomic query. RBAC is enforced in the SQL WHERE clause —
|
|
19
|
+
* if the caller doesn't have an allowed role, zero rows match and
|
|
20
|
+
* the claim never happens. No pre-flight find, no TOCTOU.
|
|
32
21
|
*/
|
|
33
22
|
export declare function claimByMetadata(input: {
|
|
34
23
|
key: string;
|
|
@@ -40,14 +29,8 @@ export declare function claimByMetadata(input: {
|
|
|
40
29
|
/**
|
|
41
30
|
* Resolve an escalation by metadata key-value pair.
|
|
42
31
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param input.key — metadata field name
|
|
47
|
-
* @param input.value — metadata field value
|
|
48
|
-
* @param input.resolverPayload — resolution data for the workflow
|
|
49
|
-
* @param input.assignee — optional external_id of the resolving user
|
|
50
|
-
* @returns result from the standard resolve endpoint
|
|
32
|
+
* Single atomic CTE: find + claim + resolve in one query.
|
|
33
|
+
* RBAC is enforced in the SQL WHERE clause.
|
|
51
34
|
*/
|
|
52
35
|
export declare function resolveByMetadata(input: {
|
|
53
36
|
key: string;
|
|
@@ -42,13 +42,8 @@ const helpers_1 = require("./helpers");
|
|
|
42
42
|
/**
|
|
43
43
|
* Find escalations by a metadata key-value pair.
|
|
44
44
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* @param input.key — metadata field name (e.g. `"orderId"`)
|
|
49
|
-
* @param input.value — metadata field value (e.g. `"order-123"`)
|
|
50
|
-
* @param input.status — optional status filter (e.g. `"pending"`)
|
|
51
|
-
* @returns `{ status: 200, data: { escalations, total } }`
|
|
45
|
+
* Single query with window function for count. Results are
|
|
46
|
+
* RBAC-scoped to the caller's visible roles.
|
|
52
47
|
*/
|
|
53
48
|
async function findByMetadata(input, auth) {
|
|
54
49
|
try {
|
|
@@ -72,15 +67,9 @@ async function findByMetadata(input, auth) {
|
|
|
72
67
|
/**
|
|
73
68
|
* Claim an escalation by metadata key-value pair.
|
|
74
69
|
*
|
|
75
|
-
*
|
|
76
|
-
* the
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* @param input.key — metadata field name
|
|
80
|
-
* @param input.value — metadata field value
|
|
81
|
-
* @param input.durationMinutes — claim duration (default 30)
|
|
82
|
-
* @param input.assignee — optional external_id of the user to claim as
|
|
83
|
-
* @returns `{ status: 200, data: { escalation, isExtension } }`
|
|
70
|
+
* Single atomic query. RBAC is enforced in the SQL WHERE clause —
|
|
71
|
+
* if the caller doesn't have an allowed role, zero rows match and
|
|
72
|
+
* the claim never happens. No pre-flight find, no TOCTOU.
|
|
84
73
|
*/
|
|
85
74
|
async function claimByMetadata(input, auth) {
|
|
86
75
|
try {
|
|
@@ -91,25 +80,17 @@ async function claimByMetadata(input, auth) {
|
|
|
91
80
|
if ('error' in resolved)
|
|
92
81
|
return resolved.error;
|
|
93
82
|
const claimUserId = resolved.userId;
|
|
94
|
-
//
|
|
95
|
-
const
|
|
96
|
-
|
|
83
|
+
// Resolve allowed roles: null = global access (no filter), string[] = scoped
|
|
84
|
+
const allowedRoles = await resolveAllowedRoles(auth.userId);
|
|
85
|
+
const result = await escalationService.claimByMetadata(input.key, input.value, claimUserId, input.durationMinutes, input.metadata, allowedRoles);
|
|
86
|
+
if (!result) {
|
|
87
|
+
// No rows matched. Check if candidates existed (role mismatch vs no match).
|
|
97
88
|
return { status: 404, error: 'No pending escalation found for this metadata' };
|
|
98
89
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (!isSuperAdmin) {
|
|
102
|
-
const userHasRole = await userService.hasRole(claimUserId, candidate.role);
|
|
103
|
-
if (!userHasRole) {
|
|
104
|
-
return { status: 403, error: `User must have the "${candidate.role}" role to claim this escalation` };
|
|
105
|
-
}
|
|
90
|
+
if (result.candidatesExist > 0 && !result.escalation) {
|
|
91
|
+
return { status: 403, error: 'Escalation exists but your roles do not permit claiming it' };
|
|
106
92
|
}
|
|
107
|
-
|
|
108
|
-
if (!result) {
|
|
109
|
-
return { status: 409, error: 'Escalation not available for claim' };
|
|
110
|
-
}
|
|
111
|
-
// Event published by service layer (services/escalation/crud.ts)
|
|
112
|
-
return { status: 200, data: result };
|
|
93
|
+
return { status: 200, data: { escalation: result.escalation, isExtension: result.isExtension } };
|
|
113
94
|
}
|
|
114
95
|
catch (err) {
|
|
115
96
|
return { status: 500, error: err.message };
|
|
@@ -118,14 +99,8 @@ async function claimByMetadata(input, auth) {
|
|
|
118
99
|
/**
|
|
119
100
|
* Resolve an escalation by metadata key-value pair.
|
|
120
101
|
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
* @param input.key — metadata field name
|
|
125
|
-
* @param input.value — metadata field value
|
|
126
|
-
* @param input.resolverPayload — resolution data for the workflow
|
|
127
|
-
* @param input.assignee — optional external_id of the resolving user
|
|
128
|
-
* @returns result from the standard resolve endpoint
|
|
102
|
+
* Single atomic CTE: find + claim + resolve in one query.
|
|
103
|
+
* RBAC is enforced in the SQL WHERE clause.
|
|
129
104
|
*/
|
|
130
105
|
async function resolveByMetadata(input, auth) {
|
|
131
106
|
try {
|
|
@@ -135,38 +110,29 @@ async function resolveByMetadata(input, auth) {
|
|
|
135
110
|
if (!input.resolverPayload) {
|
|
136
111
|
return { status: 400, error: 'resolverPayload is required' };
|
|
137
112
|
}
|
|
138
|
-
const candidates = await escalationService.findByMetadata(input.key, input.value, 'pending', 1, 0);
|
|
139
|
-
if (candidates.escalations.length === 0) {
|
|
140
|
-
return { status: 404, error: 'No pending escalation found for this metadata' };
|
|
141
|
-
}
|
|
142
|
-
const escalation = candidates.escalations[0];
|
|
143
113
|
const resolved = await (0, helpers_1.resolveAssignee)(input.assignee, auth);
|
|
144
114
|
if ('error' in resolved)
|
|
145
115
|
return resolved.error;
|
|
146
116
|
const resolveUserId = resolved.userId;
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return { status: 403, error: `User must have the "${escalation.role}" role` };
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
// Merge additional metadata if provided
|
|
155
|
-
if (input.metadata && Object.keys(input.metadata).length > 0) {
|
|
156
|
-
await escalationService.updateEscalationMetadata(escalation.id, input.metadata);
|
|
157
|
-
}
|
|
158
|
-
// Auto-claim if unclaimed or expired
|
|
159
|
-
const isClaimed = escalation.assigned_to &&
|
|
160
|
-
escalation.assigned_until &&
|
|
161
|
-
new Date(escalation.assigned_until) > new Date();
|
|
162
|
-
if (!isClaimed) {
|
|
163
|
-
await escalationService.claimEscalation(escalation.id, resolveUserId, 5);
|
|
117
|
+
const allowedRoles = await resolveAllowedRoles(auth.userId);
|
|
118
|
+
const escalation = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, allowedRoles);
|
|
119
|
+
if (!escalation) {
|
|
120
|
+
return { status: 404, error: 'No pending escalation found for this metadata, or insufficient role permissions' };
|
|
164
121
|
}
|
|
165
|
-
|
|
166
|
-
const { resolveEscalation } = await Promise.resolve().then(() => __importStar(require('./resolve')));
|
|
167
|
-
return resolveEscalation({ id: escalation.id, resolverPayload: input.resolverPayload }, auth);
|
|
122
|
+
return { status: 200, data: { escalation } };
|
|
168
123
|
}
|
|
169
124
|
catch (err) {
|
|
170
125
|
return { status: 500, error: err.message };
|
|
171
126
|
}
|
|
172
127
|
}
|
|
128
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
129
|
+
/**
|
|
130
|
+
* Resolve the set of roles the caller is allowed to act on.
|
|
131
|
+
* Returns null for global access (superadmin/admin), or string[] for scoped users.
|
|
132
|
+
*/
|
|
133
|
+
async function resolveAllowedRoles(userId) {
|
|
134
|
+
if (await userService.hasGlobalEscalationAccess(userId))
|
|
135
|
+
return null;
|
|
136
|
+
const userRoles = await userService.getUserRoles(userId);
|
|
137
|
+
return userRoles.map(r => r.role);
|
|
138
|
+
}
|
|
@@ -39,6 +39,7 @@ exports.escalateToRole = escalateToRole;
|
|
|
39
39
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
40
40
|
const userService = __importStar(require("../../services/user"));
|
|
41
41
|
const roleService = __importStar(require("../../services/role"));
|
|
42
|
+
const helpers_1 = require("./helpers");
|
|
42
43
|
// ── Single-escalation routes ───────────────────────────────────────────────
|
|
43
44
|
/**
|
|
44
45
|
* Get a single escalation by ID.
|
|
@@ -55,8 +56,8 @@ async function getEscalation(input, auth) {
|
|
|
55
56
|
if (!escalation) {
|
|
56
57
|
return { status: 404, error: 'Escalation not found' };
|
|
57
58
|
}
|
|
58
|
-
const
|
|
59
|
-
if (!
|
|
59
|
+
const hasGlobal = await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId);
|
|
60
|
+
if (!hasGlobal) {
|
|
60
61
|
const userHasRole = await userService.hasRole(auth.userId, escalation.role);
|
|
61
62
|
if (!userHasRole) {
|
|
62
63
|
return { status: 403, error: 'Not authorized to view this escalation' };
|
package/build/api/settings.js
CHANGED
|
@@ -7,6 +7,7 @@ const nats_1 = require("../lib/events/nats");
|
|
|
7
7
|
const socketio_1 = require("../lib/events/socketio");
|
|
8
8
|
const nats_ws_proxy_1 = require("../lib/events/nats-ws-proxy");
|
|
9
9
|
const config_1 = require("../modules/config");
|
|
10
|
+
const sso_1 = require("../modules/sso");
|
|
10
11
|
const defaults_1 = require("../modules/defaults");
|
|
11
12
|
const llm_1 = require("../services/llm");
|
|
12
13
|
/**
|
|
@@ -60,6 +61,10 @@ async function getSettings(req) {
|
|
|
60
61
|
transport,
|
|
61
62
|
natsWsUrl: natsAdapter ? resolveNatsWsUrl(natsAdapter, req) : null,
|
|
62
63
|
},
|
|
64
|
+
auth: {
|
|
65
|
+
sso: (0, sso_1.isSSOEnabled)(),
|
|
66
|
+
ssoLogoutUrl: (0, sso_1.getSSOConfig)()?.logoutUrl ?? null,
|
|
67
|
+
},
|
|
63
68
|
ai: {
|
|
64
69
|
enabled: (0, llm_1.hasLLMApiKey)(),
|
|
65
70
|
},
|
package/build/api/topics.d.ts
CHANGED
|
@@ -20,8 +20,17 @@ export declare function updateTopic(input: {
|
|
|
20
20
|
export declare function deleteTopic(input: {
|
|
21
21
|
topic: string;
|
|
22
22
|
}): Promise<LTApiResult>;
|
|
23
|
+
/**
|
|
24
|
+
* Validate that a subject is a valid variant of a topic pattern.
|
|
25
|
+
* Each `*` in the pattern matches exactly one literal segment in the subject.
|
|
26
|
+
* Each `>` in the pattern matches one or more trailing segments.
|
|
27
|
+
* Literal segments must match exactly.
|
|
28
|
+
*/
|
|
29
|
+
export declare function isValidVariant(pattern: string, subject: string): boolean;
|
|
23
30
|
export declare function publishTopic(input: {
|
|
24
31
|
topic: string;
|
|
32
|
+
subject?: string;
|
|
33
|
+
eventId?: string;
|
|
25
34
|
data: Record<string, any>;
|
|
26
35
|
source?: string;
|
|
27
36
|
}): Promise<LTApiResult>;
|
package/build/api/topics.js
CHANGED
|
@@ -38,6 +38,7 @@ exports.getTopic = getTopic;
|
|
|
38
38
|
exports.createTopic = createTopic;
|
|
39
39
|
exports.updateTopic = updateTopic;
|
|
40
40
|
exports.deleteTopic = deleteTopic;
|
|
41
|
+
exports.isValidVariant = isValidVariant;
|
|
41
42
|
exports.publishTopic = publishTopic;
|
|
42
43
|
const topicService = __importStar(require("../services/topics"));
|
|
43
44
|
const events_1 = require("../lib/events");
|
|
@@ -104,10 +105,38 @@ async function deleteTopic(input) {
|
|
|
104
105
|
return { status: 500, error: err.message };
|
|
105
106
|
}
|
|
106
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Validate that a subject is a valid variant of a topic pattern.
|
|
110
|
+
* Each `*` in the pattern matches exactly one literal segment in the subject.
|
|
111
|
+
* Each `>` in the pattern matches one or more trailing segments.
|
|
112
|
+
* Literal segments must match exactly.
|
|
113
|
+
*/
|
|
114
|
+
function isValidVariant(pattern, subject) {
|
|
115
|
+
const patternParts = pattern.split('.');
|
|
116
|
+
const subjectParts = subject.split('.');
|
|
117
|
+
let pi = 0;
|
|
118
|
+
let si = 0;
|
|
119
|
+
while (pi < patternParts.length && si < subjectParts.length) {
|
|
120
|
+
const pp = patternParts[pi];
|
|
121
|
+
if (pp === '>')
|
|
122
|
+
return true; // match-rest: everything from here is valid
|
|
123
|
+
if (pp !== '*' && pp !== subjectParts[si])
|
|
124
|
+
return false;
|
|
125
|
+
pi++;
|
|
126
|
+
si++;
|
|
127
|
+
}
|
|
128
|
+
return pi === patternParts.length && si === subjectParts.length;
|
|
129
|
+
}
|
|
107
130
|
async function publishTopic(input) {
|
|
108
131
|
try {
|
|
132
|
+
const publishSubject = input.subject || input.topic;
|
|
133
|
+
// Validate subject is a valid variant of the topic pattern
|
|
134
|
+
if (input.subject && !isValidVariant(input.topic, input.subject)) {
|
|
135
|
+
return { status: 400, error: `Subject "${input.subject}" does not match topic pattern "${input.topic}"` };
|
|
136
|
+
}
|
|
109
137
|
const event = {
|
|
110
|
-
|
|
138
|
+
id: input.eventId,
|
|
139
|
+
type: publishSubject,
|
|
111
140
|
source: input.source || 'dashboard',
|
|
112
141
|
workflowId: '',
|
|
113
142
|
workflowName: '',
|
|
@@ -116,7 +145,7 @@ async function publishTopic(input) {
|
|
|
116
145
|
timestamp: new Date().toISOString(),
|
|
117
146
|
};
|
|
118
147
|
await events_1.eventRegistry.publish(event);
|
|
119
|
-
return { status: 200, data: { published: true, topic:
|
|
148
|
+
return { status: 200, data: { published: true, topic: publishSubject, timestamp: event.timestamp } };
|
|
120
149
|
}
|
|
121
150
|
catch (err) {
|
|
122
151
|
return { status: 500, error: err.message };
|
|
@@ -12,6 +12,7 @@ declare class LTEventRegistry {
|
|
|
12
12
|
connect(): Promise<void>;
|
|
13
13
|
/**
|
|
14
14
|
* Publish an event to all registered adapters.
|
|
15
|
+
* Auto-assigns an idempotent event ID if not provided.
|
|
15
16
|
* Best-effort: individual adapter failures are logged, not thrown.
|
|
16
17
|
*/
|
|
17
18
|
publish(event: LTEvent): Promise<void>;
|
|
@@ -24,11 +24,15 @@ class LTEventRegistry {
|
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
26
|
* Publish an event to all registered adapters.
|
|
27
|
+
* Auto-assigns an idempotent event ID if not provided.
|
|
27
28
|
* Best-effort: individual adapter failures are logged, not thrown.
|
|
28
29
|
*/
|
|
29
30
|
async publish(event) {
|
|
30
31
|
if (!this.adapters.length)
|
|
31
32
|
return;
|
|
33
|
+
if (!event.id) {
|
|
34
|
+
event.id = `evt-${Date.now()}-${Math.random().toString(16).slice(2, 6)}`;
|
|
35
|
+
}
|
|
32
36
|
await Promise.allSettled(this.adapters.map((a) => a.publish(event).catch((err) => {
|
|
33
37
|
logger_1.loggerRegistry.error(`[lt-events] adapter publish failed: ${err?.message}`);
|
|
34
38
|
})));
|
|
@@ -15,7 +15,8 @@ export declare function publishMilestoneEvent(params: {
|
|
|
15
15
|
data?: Record<string, any>;
|
|
16
16
|
}): Promise<void>;
|
|
17
17
|
/**
|
|
18
|
-
* Publish a task lifecycle event
|
|
18
|
+
* Publish a task lifecycle event.
|
|
19
|
+
* Subject: system.task.{taskId}.{action}
|
|
19
20
|
*/
|
|
20
21
|
export declare function publishTaskEvent(params: {
|
|
21
22
|
type: 'task.created' | 'task.started' | 'task.completed' | 'task.escalated' | 'task.failed';
|
|
@@ -30,7 +31,8 @@ export declare function publishTaskEvent(params: {
|
|
|
30
31
|
data?: Record<string, any>;
|
|
31
32
|
}): Promise<void>;
|
|
32
33
|
/**
|
|
33
|
-
* Publish an escalation lifecycle event
|
|
34
|
+
* Publish an escalation lifecycle event.
|
|
35
|
+
* Subject: system.escalation.{escalationId}.{action}
|
|
34
36
|
*/
|
|
35
37
|
export declare function publishEscalationEvent(params: {
|
|
36
38
|
type: 'escalation.created' | 'escalation.resolved' | 'escalation.claimed' | 'escalation.released';
|
|
@@ -46,7 +48,7 @@ export declare function publishEscalationEvent(params: {
|
|
|
46
48
|
}): Promise<void>;
|
|
47
49
|
/**
|
|
48
50
|
* Publish an activity lifecycle event for YAML workflow steps.
|
|
49
|
-
*
|
|
51
|
+
* Subject: system.activity.{workflowId}.{activityName}.{action}
|
|
50
52
|
*/
|
|
51
53
|
export declare function publishActivityEvent(params: {
|
|
52
54
|
type: 'activity.started' | 'activity.completed' | 'activity.failed';
|
|
@@ -57,9 +59,8 @@ export declare function publishActivityEvent(params: {
|
|
|
57
59
|
data?: Record<string, any>;
|
|
58
60
|
}): Promise<void>;
|
|
59
61
|
/**
|
|
60
|
-
* Publish a knowledge lifecycle event
|
|
61
|
-
*
|
|
62
|
-
* happen both inside and outside workflows.
|
|
62
|
+
* Publish a knowledge lifecycle event.
|
|
63
|
+
* Subject: system.knowledge.{domain}.{action}
|
|
63
64
|
*/
|
|
64
65
|
export declare function publishKnowledgeEvent(params: {
|
|
65
66
|
type: 'knowledge.stored' | 'knowledge.deleted';
|
|
@@ -67,8 +68,8 @@ export declare function publishKnowledgeEvent(params: {
|
|
|
67
68
|
key: string;
|
|
68
69
|
}): Promise<void>;
|
|
69
70
|
/**
|
|
70
|
-
* Publish a file storage event
|
|
71
|
-
*
|
|
71
|
+
* Publish a file storage event.
|
|
72
|
+
* Subject: system.file.{action}
|
|
72
73
|
*/
|
|
73
74
|
export declare function publishFileEvent(params: {
|
|
74
75
|
type: 'file.stored' | 'file.deleted';
|
|
@@ -78,6 +79,7 @@ export declare function publishFileEvent(params: {
|
|
|
78
79
|
}): Promise<void>;
|
|
79
80
|
/**
|
|
80
81
|
* Publish an agent lifecycle event.
|
|
82
|
+
* Subject: system.agent.{agentName}.{action}
|
|
81
83
|
*/
|
|
82
84
|
export declare function publishAgentEvent(params: {
|
|
83
85
|
type: 'agent.started' | 'agent.completed' | 'agent.failed' | 'agent.status_changed';
|
|
@@ -87,7 +89,8 @@ export declare function publishAgentEvent(params: {
|
|
|
87
89
|
data?: Record<string, any>;
|
|
88
90
|
}): Promise<void>;
|
|
89
91
|
/**
|
|
90
|
-
* Publish a workflow lifecycle event
|
|
92
|
+
* Publish a workflow lifecycle event.
|
|
93
|
+
* Subject: system.workflow.{workflowId}.{action}
|
|
91
94
|
*/
|
|
92
95
|
export declare function publishWorkflowEvent(params: {
|
|
93
96
|
type: 'workflow.started' | 'workflow.completed' | 'workflow.failed';
|