@hotmeshio/long-tail 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/api/announcements.d.ts +22 -0
- package/build/api/announcements.js +96 -0
- package/build/api/auth-sso.d.ts +6 -3
- package/build/api/auth-sso.js +6 -3
- package/build/api/escalations/list.d.ts +8 -0
- package/build/api/escalations/list.js +14 -4
- package/build/api/index.d.ts +1 -0
- package/build/api/index.js +2 -1
- package/build/api/workflows/config.d.ts +1 -0
- package/build/api/workflows/config.js +1 -0
- package/build/api/workflows/discovery.js +1 -0
- package/build/lib/db/schemas/031_announcements.sql +30 -0
- package/build/lib/db/schemas/032_workflow_read_safe.sql +9 -0
- package/build/lib/events/publish.d.ts +15 -0
- package/build/lib/events/publish.js +22 -0
- package/build/modules/auth.js +9 -3
- package/build/routes/announcements.d.ts +2 -0
- package/build/routes/announcements.js +64 -0
- package/build/routes/auth-sso.js +6 -1
- package/build/routes/escalations/list.js +2 -0
- package/build/routes/index.js +2 -0
- package/build/services/announcement/index.d.ts +30 -0
- package/build/services/announcement/index.js +29 -0
- package/build/services/announcement/sql.d.ts +8 -0
- package/build/services/announcement/sql.js +24 -0
- package/build/services/config/cache.js +1 -0
- package/build/services/config/read.js +2 -0
- package/build/services/config/sql.d.ts +2 -2
- package/build/services/config/sql.js +6 -5
- package/build/services/config/write.js +5 -0
- package/build/services/scan-code/index.d.ts +1 -1
- package/build/services/scan-code/index.js +3 -1
- package/build/services/scan-code/sql.d.ts +7 -0
- package/build/services/scan-code/sql.js +55 -1
- package/build/services/scan-code/write.d.ts +8 -0
- package/build/services/scan-code/write.js +23 -1
- package/build/services/topics/system-topics.js +20 -0
- package/build/shared/form-validation/index.d.ts +1 -0
- package/build/shared/form-validation/index.js +1 -0
- package/build/shared/form-validation/validate-resolver-payload.d.ts +3 -0
- package/build/shared/form-validation/validate-resolver-payload.js +19 -0
- package/build/shared/form-validation/x-lt-labels.d.ts +17 -6
- package/build/shared/form-validation/x-lt-labels.js +12 -4
- package/build/shared/form-validation/x-lt-require-any.d.ts +22 -0
- package/build/shared/form-validation/x-lt-require-any.js +41 -0
- package/build/start/workers.js +50 -0
- package/build/system/mcp-servers/admin/announcements.d.ts +7 -0
- package/build/system/mcp-servers/admin/announcements.js +69 -0
- package/build/system/mcp-servers/admin/index.js +5 -3
- package/build/system/mcp-servers/admin/workflows.js +45 -0
- package/build/system/seed/tool-manifests-admin.d.ts +357 -0
- package/build/system/seed/tool-manifests-admin.js +3 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/auth.d.ts +21 -7
- package/build/types/config.d.ts +8 -0
- package/build/types/index.d.ts +1 -1
- package/build/types/startup.d.ts +57 -0
- package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js → AdminDashboard-DeZsR4pA.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js.map → AdminDashboard-DeZsR4pA.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js → AgentConfigPage-Bi5ZAsjf.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js.map → AgentConfigPage-Bi5ZAsjf.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js → AgentDetailPage-CIbKor5E.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js.map → AgentDetailPage-CIbKor5E.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js → AgentsPage-CRFZ6KDu.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js.map → AgentsPage-CRFZ6KDu.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DDsmXjpi.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-DDsmXjpi.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-BN-MKITV.js → BotPicker-dUpw1wW6.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-BN-MKITV.js.map → BotPicker-dUpw1wW6.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js → CapabilitiesPage-Ca2jEln-.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js.map → CapabilitiesPage-Ca2jEln-.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js → CollapsibleSection-BXlR5QmW.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js.map → CollapsibleSection-BXlR5QmW.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-rnoWmFqx.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-rnoWmFqx.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js → CredentialsPage-CGyCCzGh.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js.map → CredentialsPage-CGyCCzGh.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js → CronLabel-CAu2hmQf.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js.map → CronLabel-CAu2hmQf.js.map} +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-hlnadaFt.js +2 -0
- package/dashboard/dist/assets/CustomDurationPicker-hlnadaFt.js.map +1 -0
- package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js → ElapsedCell-B1eoCzEw.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js.map → ElapsedCell-B1eoCzEw.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js → EntityTimelinePanel-CIOyjwjM.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js.map → EntityTimelinePanel-CIOyjwjM.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js → EscalationListSchemaPage-DQNQ7o_4.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js.map → EscalationListSchemaPage-DQNQ7o_4.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js → EscalationSchemaPage-DFgDn4R3.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js.map → EscalationSchemaPage-DFgDn4R3.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js → EscalationsOverview-DfbKtXVZ.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js.map → EscalationsOverview-DfbKtXVZ.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-BOcgZ78i.js → EventTable-CZPkvhao.js} +2 -2
- package/dashboard/dist/assets/{EventTable-BOcgZ78i.js.map → EventTable-CZPkvhao.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js → FilterBar-CYjKK9Cp.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js.map → FilterBar-CYjKK9Cp.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js → GraphInvokePage-DY9u42vt.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js.map → GraphInvokePage-DY9u42vt.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-C2IhF9WB.js → HomePage-p_CYlGnh.js} +2 -2
- package/dashboard/dist/assets/{HomePage-C2IhF9WB.js.map → HomePage-p_CYlGnh.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js → ListToolbar-Dz-1RXSH.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js.map → ListToolbar-Dz-1RXSH.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DstPch5M.js → McpOverview-BUI9sVTk.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DstPch5M.js.map → McpOverview-BUI9sVTk.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js → McpQueryDetailPage-CVN_UAB3.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js.map → McpQueryDetailPage-CVN_UAB3.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js → McpQueryPage-DRTKSPDR.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js.map → McpQueryPage-DRTKSPDR.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js → McpRunDetailPage-CTb1AxR3.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js.map → McpRunDetailPage-CTb1AxR3.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js → McpRunsPage-BWLwjVd0.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js.map → McpRunsPage-BWLwjVd0.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js → OperationsPage-BSl_oUAJ.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js.map → OperationsPage-BSl_oUAJ.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js → OperatorDashboard-DGs9kPOZ.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js.map → OperatorDashboard-DGs9kPOZ.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js → PersonaDetailPage-C33MgXUY.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js.map → PersonaDetailPage-C33MgXUY.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js → PersonasPage-BbLOHq5X.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js.map → PersonasPage-BbLOHq5X.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js → ProcessDetailPage-zwd0HCJl.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js.map → ProcessDetailPage-zwd0HCJl.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js → ProcessesListPage-DnfmK6jf.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js.map → ProcessesListPage-DnfmK6jf.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js → RoleDetailPage-axZtFPC_.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js.map → RoleDetailPage-axZtFPC_.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DeRVQux8.js → RolesPage-DN6yqH7-.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DeRVQux8.js.map → RolesPage-DN6yqH7-.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js → RunAsSelector-DrGsUhL8.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js.map → RunAsSelector-DrGsUhL8.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js → ScanCodesPage-BmQjEyWZ.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js.map → ScanCodesPage-BmQjEyWZ.js.map} +1 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-VODehqGs.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-VODehqGs.js.map +1 -0
- package/dashboard/dist/assets/{ScanStationPage-DH1ynTX9.js → ScanStationPage-Y-9Gs7t5.js} +2 -2
- package/dashboard/dist/assets/{ScanStationPage-DH1ynTX9.js.map → ScanStationPage-Y-9Gs7t5.js.map} +1 -1
- package/dashboard/dist/assets/{StickyPagination-B99hVu95.js → StickyPagination-9VkHiOsT.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-B99hVu95.js.map → StickyPagination-9VkHiOsT.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js → StreamMessageDetail-C37J6Qyz.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js.map → StreamMessageDetail-C37J6Qyz.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js → SwimlaneTimeline-NVGsBIX-.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js.map → SwimlaneTimeline-NVGsBIX-.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js → TaskDetailPage-5sbMHi5U.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js.map → TaskDetailPage-5sbMHi5U.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js → TasksListPage-C9AN7IBb.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js.map → TasksListPage-C9AN7IBb.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js → TimeAgo-CsbQGlSd.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js.map → TimeAgo-CsbQGlSd.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js → TimestampCell-DlbIkV-G.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js.map → TimestampCell-DlbIkV-G.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js → ToolTestPanel-BKbLocvr.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js.map → ToolTestPanel-BKbLocvr.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js → TopicDetailPage-fOnTfDso.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js.map → TopicDetailPage-fOnTfDso.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DEyvm669.js → TopicsPage-BoVkp7DM.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DEyvm669.js.map → TopicsPage-BoVkp7DM.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BV6SKI9P.js → UserName-0gjVPU_U.js} +2 -2
- package/dashboard/dist/assets/{UserName-BV6SKI9P.js.map → UserName-0gjVPU_U.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js → WorkflowExecutionPage-B28OxTS_.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js.map → WorkflowExecutionPage-B28OxTS_.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js → WorkflowsDashboard-Bzvz6tTY.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js.map → WorkflowsDashboard-Bzvz6tTY.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js → WorkflowsOverview-BkcRU4Ej.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js.map → WorkflowsOverview-BkcRU4Ej.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js → YamlWorkflowDetailPage-CmM78sYi.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js.map → YamlWorkflowDetailPage-CmM78sYi.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js → YamlWorkflowsPage-Dp6vG1au.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js.map → YamlWorkflowsPage-Dp6vG1au.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BTDsRK8e.js → agents-MeqzOPD6.js} +2 -2
- package/dashboard/dist/assets/{agents-BTDsRK8e.js.map → agents-MeqzOPD6.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DxLrfdfr.js → bots-DTGXnvX_.js} +2 -2
- package/dashboard/dist/assets/{bots-DxLrfdfr.js.map → bots-DTGXnvX_.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DbTmeW-S.js → capabilities-BjlARR7F.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DbTmeW-S.js.map → capabilities-BjlARR7F.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CEBntAL4.js → controlplane-DMYI0OaL.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CEBntAL4.js.map → controlplane-DMYI0OaL.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js → escalation-columns-BMO_H3cb.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js.map → escalation-columns-BMO_H3cb.js.map} +1 -1
- package/dashboard/dist/assets/{index-De8iV1y2.js → index-3QEnMBNG.js} +2 -2
- package/dashboard/dist/assets/{index-De8iV1y2.js.map → index-3QEnMBNG.js.map} +1 -1
- package/dashboard/dist/assets/{index-Bqm4zu46.js → index-B3FzpDEG.js} +2 -2
- package/dashboard/dist/assets/{index-Bqm4zu46.js.map → index-B3FzpDEG.js.map} +1 -1
- package/dashboard/dist/assets/{index-cFHoANSG.css → index-B5jxf81r.css} +1 -1
- package/dashboard/dist/assets/{index-DBXm49S6.js → index-BU4oujVO.js} +30 -29
- package/dashboard/dist/assets/index-BU4oujVO.js.map +1 -0
- package/dashboard/dist/assets/{index-kes8V4Xw.js → index-CGCD5hTX.js} +2 -2
- package/dashboard/dist/assets/{index-kes8V4Xw.js.map → index-CGCD5hTX.js.map} +1 -1
- package/dashboard/dist/assets/{index-BhapT-Vl.js → index-Ch-OS1pk.js} +2 -2
- package/dashboard/dist/assets/{index-BhapT-Vl.js.map → index-Ch-OS1pk.js.map} +1 -1
- package/dashboard/dist/assets/{index-B9m7fA3M.js → index-CkkOh8y9.js} +2 -2
- package/dashboard/dist/assets/{index-B9m7fA3M.js.map → index-CkkOh8y9.js.map} +1 -1
- package/dashboard/dist/assets/{index-B2hz0pUh.js → index-D3iDAWK2.js} +2 -2
- package/dashboard/dist/assets/{index-B2hz0pUh.js.map → index-D3iDAWK2.js.map} +1 -1
- package/dashboard/dist/assets/{index-C0hSttF5.js → index-D6kXz3H8.js} +2 -2
- package/dashboard/dist/assets/{index-C0hSttF5.js.map → index-D6kXz3H8.js.map} +1 -1
- package/dashboard/dist/assets/{index-CVBBkW8V.js → index-Dsgqxdyh.js} +2 -2
- package/dashboard/dist/assets/{index-CVBBkW8V.js.map → index-Dsgqxdyh.js.map} +1 -1
- package/dashboard/dist/assets/{index-nwLh3CK2.js → index-DuhqzYwC.js} +2 -2
- package/dashboard/dist/assets/{index-nwLh3CK2.js.map → index-DuhqzYwC.js.map} +1 -1
- package/dashboard/dist/assets/{index-CDkg6iOE.js → index-DuyzcDuV.js} +2 -2
- package/dashboard/dist/assets/{index-CDkg6iOE.js.map → index-DuyzcDuV.js.map} +1 -1
- package/dashboard/dist/assets/index-LF1gEc6w.js +3 -0
- package/dashboard/dist/assets/index-LF1gEc6w.js.map +1 -0
- package/dashboard/dist/assets/{index-CgIBjZta.js → index-k5vcLICm.js} +2 -2
- package/dashboard/dist/assets/{index-CgIBjZta.js.map → index-k5vcLICm.js.map} +1 -1
- package/dashboard/dist/assets/{knowledge-oFYAanUp.js → knowledge-DAV1Jy7b.js} +2 -2
- package/dashboard/dist/assets/{knowledge-oFYAanUp.js.map → knowledge-DAV1Jy7b.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js → mcp-CivbxL1P.js} +2 -2
- package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js.map → mcp-CivbxL1P.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js → mcp-query-CGvWNrgo.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js.map → mcp-query-CGvWNrgo.js.map} +1 -1
- package/dashboard/dist/assets/{personas-D5ehmtRb.js → personas-lI3aUr6t.js} +2 -2
- package/dashboard/dist/assets/{personas-D5ehmtRb.js.map → personas-lI3aUr6t.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-xgPKGEdD.js → pipelines-DjPfnTmx.js} +2 -2
- package/dashboard/dist/assets/{pipelines-xgPKGEdD.js.map → pipelines-DjPfnTmx.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CLyrl-MU.js → tasks-Co_S55BO.js} +2 -2
- package/dashboard/dist/assets/{tasks-CLyrl-MU.js.map → tasks-Co_S55BO.js.map} +1 -1
- package/dashboard/dist/assets/{topics-B_gO7CQ0.js → topics-2IGhZXBi.js} +2 -2
- package/dashboard/dist/assets/{topics-B_gO7CQ0.js.map → topics-2IGhZXBi.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js → useEventHooks-D0C5yke4.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js.map → useEventHooks-D0C5yke4.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-C238M4Qn.js → useNamespace-LG52DTT-.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-C238M4Qn.js.map → useNamespace-LG52DTT-.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js → useYamlActivityEvents-1IZGVpWC.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js.map → useYamlActivityEvents-1IZGVpWC.js.map} +1 -1
- package/dashboard/dist/assets/{users-BFaTe6Mt.js → users-C-eHT1i6.js} +2 -2
- package/dashboard/dist/assets/{users-BFaTe6Mt.js.map → users-C-eHT1i6.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DXz7tZxp.js → workflows-C16CeY4e.js} +2 -2
- package/dashboard/dist/assets/{workflows-DXz7tZxp.js.map → workflows-C16CeY4e.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js → yaml-workflows-BBenayT9.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js.map → yaml-workflows-BBenayT9.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/auth.md +26 -1
- package/docs/code-owned-configuration.md +27 -0
- package/docs/dashboard.md +15 -0
- package/docs/hitl/x-lt-footer.md +16 -4
- package/docs/hitl/x-lt-validation.md +23 -0
- package/docs/mcp.md +2 -0
- package/docs/scan-codes.md +24 -0
- package/package.json +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-DvWaiafI.js +0 -2
- package/dashboard/dist/assets/AvailableEscalationsPage-DvWaiafI.js.map +0 -1
- package/dashboard/dist/assets/CountdownTimer-By4rbMDN.js +0 -2
- package/dashboard/dist/assets/CountdownTimer-By4rbMDN.js.map +0 -1
- package/dashboard/dist/assets/CustomDurationPicker-8Ao-1pKA.js +0 -2
- package/dashboard/dist/assets/CustomDurationPicker-8Ao-1pKA.js.map +0 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-vFqoe_P4.js +0 -2
- package/dashboard/dist/assets/ScanSchemeDetailPage-vFqoe_P4.js.map +0 -1
- package/dashboard/dist/assets/index-DBXm49S6.js.map +0 -1
- package/dashboard/dist/assets/index-DsgjFRvA.js +0 -3
- package/dashboard/dist/assets/index-DsgjFRvA.js.map +0 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LTApiResult, LTApiAuth } from '../types/sdk';
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard announcements — broadcast notices on the dashboard surface.
|
|
4
|
+
* Publishing is a role-manager act (superadmin/admin/engineer via the route
|
|
5
|
+
* guard); reading is any authenticated user, server-filtered to their roles.
|
|
6
|
+
* Role targeting is display scoping only: the live event reaches every
|
|
7
|
+
* authenticated subscriber, so bodies must never carry secrets.
|
|
8
|
+
*/
|
|
9
|
+
/** Create an announcement. Only `body` is required — everything else defaults. */
|
|
10
|
+
export declare function createAnnouncement(input: {
|
|
11
|
+
body?: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
layout?: string;
|
|
14
|
+
roles?: string[];
|
|
15
|
+
expiresAt?: string;
|
|
16
|
+
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
17
|
+
/** Active announcements for the caller — admins see all, others their roles' slice. */
|
|
18
|
+
export declare function listAnnouncements(auth: LTApiAuth): Promise<LTApiResult>;
|
|
19
|
+
/** Remove an announcement; subscribers see it drop live. */
|
|
20
|
+
export declare function deleteAnnouncement(input: {
|
|
21
|
+
id: string;
|
|
22
|
+
}, _auth: LTApiAuth): Promise<LTApiResult>;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createAnnouncement = createAnnouncement;
|
|
37
|
+
exports.listAnnouncements = listAnnouncements;
|
|
38
|
+
exports.deleteAnnouncement = deleteAnnouncement;
|
|
39
|
+
const announcementService = __importStar(require("../services/announcement"));
|
|
40
|
+
const publish_1 = require("../lib/events/publish");
|
|
41
|
+
const user_1 = require("../services/user");
|
|
42
|
+
/**
|
|
43
|
+
* Dashboard announcements — broadcast notices on the dashboard surface.
|
|
44
|
+
* Publishing is a role-manager act (superadmin/admin/engineer via the route
|
|
45
|
+
* guard); reading is any authenticated user, server-filtered to their roles.
|
|
46
|
+
* Role targeting is display scoping only: the live event reaches every
|
|
47
|
+
* authenticated subscriber, so bodies must never carry secrets.
|
|
48
|
+
*/
|
|
49
|
+
/** Create an announcement. Only `body` is required — everything else defaults. */
|
|
50
|
+
async function createAnnouncement(input, auth) {
|
|
51
|
+
try {
|
|
52
|
+
if (!input.body?.trim()) {
|
|
53
|
+
return { status: 400, error: 'body is required' };
|
|
54
|
+
}
|
|
55
|
+
const announcement = await announcementService.createAnnouncement({
|
|
56
|
+
body: input.body,
|
|
57
|
+
title: input.title,
|
|
58
|
+
layout: input.layout,
|
|
59
|
+
roles: input.roles,
|
|
60
|
+
expiresAt: input.expiresAt,
|
|
61
|
+
createdBy: auth.userId,
|
|
62
|
+
});
|
|
63
|
+
await (0, publish_1.publishAnnouncementEvent)({ type: 'announcement.created', announcement });
|
|
64
|
+
return { status: 200, data: announcement };
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
return { status: 500, error: err.message };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/** Active announcements for the caller — admins see all, others their roles' slice. */
|
|
71
|
+
async function listAnnouncements(auth) {
|
|
72
|
+
try {
|
|
73
|
+
const unscoped = auth.role === 'superadmin' || auth.role === 'admin';
|
|
74
|
+
const roles = unscoped
|
|
75
|
+
? null
|
|
76
|
+
: (await (0, user_1.getUserRoles)(auth.userId)).map((r) => r.role);
|
|
77
|
+
const announcements = await announcementService.listActiveAnnouncements(roles);
|
|
78
|
+
return { status: 200, data: { announcements } };
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
return { status: 500, error: err.message };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/** Remove an announcement; subscribers see it drop live. */
|
|
85
|
+
async function deleteAnnouncement(input, _auth) {
|
|
86
|
+
try {
|
|
87
|
+
const deleted = await announcementService.deleteAnnouncement(input.id);
|
|
88
|
+
if (!deleted)
|
|
89
|
+
return { status: 404, error: 'announcement not found' };
|
|
90
|
+
await (0, publish_1.publishAnnouncementEvent)({ type: 'announcement.deleted', announcement: deleted });
|
|
91
|
+
return { status: 200, data: { deleted: true, id: input.id } };
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
return { status: 500, error: err.message };
|
|
95
|
+
}
|
|
96
|
+
}
|
package/build/api/auth-sso.d.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import type { Request } from 'express';
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
2
|
import type { LTApiResult } from '../types/sdk';
|
|
3
3
|
/**
|
|
4
4
|
* Exchange host authentication for a Long Tail JWT.
|
|
5
5
|
*
|
|
6
|
-
* Calls `sso.resolve(req)` to extract the host identity, JIT provisions
|
|
6
|
+
* Calls `sso.resolve(req, res)` to extract the host identity, JIT provisions
|
|
7
7
|
* the user in `lt_users`, and returns a signed JWT the dashboard can
|
|
8
8
|
* store for subsequent API calls.
|
|
9
9
|
*
|
|
10
10
|
* No request body required — the host's cookies/headers carry the auth.
|
|
11
|
+
* `res` gives cookie-owning hosts the response handle at the exchange
|
|
12
|
+
* boundary (login and every keepalive beat) to set/refresh their session
|
|
13
|
+
* cookie — headers only; the route writes the response body.
|
|
11
14
|
*/
|
|
12
|
-
export declare function exchangeSSO(req: Request): Promise<LTApiResult>;
|
|
15
|
+
export declare function exchangeSSO(req: Request, res?: Response): Promise<LTApiResult>;
|
package/build/api/auth-sso.js
CHANGED
|
@@ -7,19 +7,22 @@ const auth_1 = require("../modules/auth");
|
|
|
7
7
|
/**
|
|
8
8
|
* Exchange host authentication for a Long Tail JWT.
|
|
9
9
|
*
|
|
10
|
-
* Calls `sso.resolve(req)` to extract the host identity, JIT provisions
|
|
10
|
+
* Calls `sso.resolve(req, res)` to extract the host identity, JIT provisions
|
|
11
11
|
* the user in `lt_users`, and returns a signed JWT the dashboard can
|
|
12
12
|
* store for subsequent API calls.
|
|
13
13
|
*
|
|
14
14
|
* No request body required — the host's cookies/headers carry the auth.
|
|
15
|
+
* `res` gives cookie-owning hosts the response handle at the exchange
|
|
16
|
+
* boundary (login and every keepalive beat) to set/refresh their session
|
|
17
|
+
* cookie — headers only; the route writes the response body.
|
|
15
18
|
*/
|
|
16
|
-
async function exchangeSSO(req) {
|
|
19
|
+
async function exchangeSSO(req, res) {
|
|
17
20
|
try {
|
|
18
21
|
const ssoConfig = (0, sso_1.getSSOConfig)();
|
|
19
22
|
if (!ssoConfig) {
|
|
20
23
|
return { status: 404, error: 'SSO not configured' };
|
|
21
24
|
}
|
|
22
|
-
const identity = await ssoConfig.resolve(req);
|
|
25
|
+
const identity = await ssoConfig.resolve(req, res);
|
|
23
26
|
if (!identity) {
|
|
24
27
|
return { status: 401, error: 'Host authentication required' };
|
|
25
28
|
}
|
|
@@ -11,6 +11,14 @@ export interface FacetInput {
|
|
|
11
11
|
/** Only rows past their role's priority threshold — see FacetQuery.jeopardy. */
|
|
12
12
|
jeopardy?: boolean;
|
|
13
13
|
orderBy?: FacetOrder[];
|
|
14
|
+
/**
|
|
15
|
+
* List rows omit the two heavyweight JSON columns (`envelope`,
|
|
16
|
+
* `escalation_payload`) by default — at scale they dominate the payload.
|
|
17
|
+
* Pass `'envelope'` to restore both (list schemas interpolating
|
|
18
|
+
* `{{envelope.*}}`/`{{payload.*}}` need them). The single-item GET always
|
|
19
|
+
* carries the full record.
|
|
20
|
+
*/
|
|
21
|
+
include?: string;
|
|
14
22
|
}
|
|
15
23
|
/**
|
|
16
24
|
* List escalations with optional filters.
|
|
@@ -42,6 +42,16 @@ exports.getStationMetrics = getStationMetrics;
|
|
|
42
42
|
const escalationService = __importStar(require("../../services/escalation"));
|
|
43
43
|
const features_1 = require("../../modules/features");
|
|
44
44
|
const helpers_1 = require("./helpers");
|
|
45
|
+
/** Strip the heavyweight JSON columns from list rows unless asked back. */
|
|
46
|
+
function projectListRows(rows, include) {
|
|
47
|
+
if (include === 'envelope')
|
|
48
|
+
return rows;
|
|
49
|
+
return rows.map(({ envelope: _e, escalation_payload: _p, ...rest }) => rest);
|
|
50
|
+
}
|
|
51
|
+
/** Apply the list projection to a { escalations, ... } service result. */
|
|
52
|
+
function projectListResult(result, include) {
|
|
53
|
+
return { ...result, escalations: projectListRows(result.escalations, include) };
|
|
54
|
+
}
|
|
45
55
|
/** True when the caller asked for anything the plain list path can't express. */
|
|
46
56
|
function hasFacetQuery(i) {
|
|
47
57
|
return !!(i.facets ||
|
|
@@ -107,7 +117,7 @@ async function listEscalations(input, auth) {
|
|
|
107
117
|
limit: input.limit ?? 50,
|
|
108
118
|
offset: input.offset ?? 0,
|
|
109
119
|
});
|
|
110
|
-
return { status: 200, data: result };
|
|
120
|
+
return { status: 200, data: projectListResult(result, input.include) };
|
|
111
121
|
}
|
|
112
122
|
const result = await escalationService.listEscalations({
|
|
113
123
|
status: input.status,
|
|
@@ -127,7 +137,7 @@ async function listEscalations(input, auth) {
|
|
|
127
137
|
selfRoles: scope.global ? undefined : scope.selfRoles,
|
|
128
138
|
meUserId: auth.userId,
|
|
129
139
|
});
|
|
130
|
-
return { status: 200, data: result };
|
|
140
|
+
return { status: 200, data: projectListResult(result, input.include) };
|
|
131
141
|
}
|
|
132
142
|
catch (err) {
|
|
133
143
|
return { status: 500, error: err.message };
|
|
@@ -182,7 +192,7 @@ async function listAvailableEscalations(input, auth) {
|
|
|
182
192
|
limit: input.limit ?? 50,
|
|
183
193
|
offset: input.offset ?? 0,
|
|
184
194
|
});
|
|
185
|
-
return { status: 200, data: result };
|
|
195
|
+
return { status: 200, data: projectListResult(result, input.include) };
|
|
186
196
|
}
|
|
187
197
|
const result = await escalationService.listAvailableEscalations({
|
|
188
198
|
role: input.role,
|
|
@@ -198,7 +208,7 @@ async function listAvailableEscalations(input, auth) {
|
|
|
198
208
|
selfRoles: scope.global ? undefined : scope.selfRoles,
|
|
199
209
|
meUserId: auth.userId,
|
|
200
210
|
});
|
|
201
|
-
return { status: 200, data: result };
|
|
211
|
+
return { status: 200, data: projectListResult(result, input.include) };
|
|
202
212
|
}
|
|
203
213
|
catch (err) {
|
|
204
214
|
return { status: 500, error: err.message };
|
package/build/api/index.d.ts
CHANGED
package/build/api/index.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.maintenance = exports.namespaces = exports.dba = exports.workflowSets = exports.botAccounts = exports.controlplane = exports.exports = exports.settings = exports.insight = exports.mcpRuns = exports.pipelines = exports.mcp = exports.auth = exports.personas = exports.roles = exports.users = exports.yamlWorkflows = exports.workflows = exports.escalations = exports.tasks = void 0;
|
|
36
|
+
exports.announcements = exports.maintenance = exports.namespaces = exports.dba = exports.workflowSets = exports.botAccounts = exports.controlplane = exports.exports = exports.settings = exports.insight = exports.mcpRuns = exports.pipelines = exports.mcp = exports.auth = exports.personas = exports.roles = exports.users = exports.yamlWorkflows = exports.workflows = exports.escalations = exports.tasks = void 0;
|
|
37
37
|
exports.tasks = __importStar(require("./tasks"));
|
|
38
38
|
exports.escalations = __importStar(require("./escalations"));
|
|
39
39
|
exports.workflows = __importStar(require("./workflows"));
|
|
@@ -54,3 +54,4 @@ exports.workflowSets = __importStar(require("./workflow-sets"));
|
|
|
54
54
|
exports.dba = __importStar(require("./dba"));
|
|
55
55
|
exports.namespaces = __importStar(require("./namespaces"));
|
|
56
56
|
exports.maintenance = __importStar(require("./maintenance"));
|
|
57
|
+
exports.announcements = __importStar(require("./announcements"));
|
|
@@ -120,6 +120,7 @@ async function upsertWorkflowConfig(input) {
|
|
|
120
120
|
envelope_schema: input.envelope_schema ?? null,
|
|
121
121
|
resolver_schema: input.resolver_schema ?? null,
|
|
122
122
|
cron_schedule: input.cron_schedule ?? null,
|
|
123
|
+
read_safe: input.read_safe ?? false,
|
|
123
124
|
});
|
|
124
125
|
ltconfig_1.ltConfig.invalidate();
|
|
125
126
|
await cron_1.cronRegistry.restartCron(config);
|
|
@@ -113,6 +113,7 @@ async function listDiscoveredWorkflows(input) {
|
|
|
113
113
|
registered: !!config,
|
|
114
114
|
active: !!worker,
|
|
115
115
|
invocable: config?.invocable ?? !!worker,
|
|
116
|
+
read_safe: config?.read_safe ?? false,
|
|
116
117
|
system: registry_1.SYSTEM_WORKFLOWS.has(workflowType),
|
|
117
118
|
description: config?.description ?? null,
|
|
118
119
|
roles: config?.roles ?? [],
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
-- Migration 031: Dashboard announcements
|
|
2
|
+
--
|
|
3
|
+
-- Broadcast notices for the dashboard surface (system.surfaces.dashboard).
|
|
4
|
+
-- Role targeting is display scoping only — live events reach every
|
|
5
|
+
-- authenticated socket, so a body must never carry secrets. Rows expire by
|
|
6
|
+
-- timestamp; dismissal is per-browser on the client.
|
|
7
|
+
|
|
8
|
+
CREATE TABLE IF NOT EXISTS lt_announcements (
|
|
9
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
10
|
+
title TEXT,
|
|
11
|
+
body TEXT NOT NULL,
|
|
12
|
+
layout TEXT NOT NULL DEFAULT 'banner',
|
|
13
|
+
roles TEXT[] NOT NULL DEFAULT '{}',
|
|
14
|
+
created_by TEXT,
|
|
15
|
+
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
16
|
+
expires_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + INTERVAL '24 hours'
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
CREATE INDEX IF NOT EXISTS idx_lt_announcements_expires ON lt_announcements (expires_at);
|
|
20
|
+
|
|
21
|
+
-- The announcement topic (system.surfaces.dashboard) introduces the
|
|
22
|
+
-- 'surfaces' category to the topic catalog.
|
|
23
|
+
ALTER TABLE lt_topic_catalog
|
|
24
|
+
DROP CONSTRAINT IF EXISTS lt_topic_catalog_category_check;
|
|
25
|
+
|
|
26
|
+
ALTER TABLE lt_topic_catalog
|
|
27
|
+
ADD CONSTRAINT lt_topic_catalog_category_check
|
|
28
|
+
CHECK (category IN (
|
|
29
|
+
'task','workflow','escalation','activity','knowledge','file','agent','app','milestone','surfaces'
|
|
30
|
+
));
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Migration 032: read-safe workflow flag
|
|
2
|
+
--
|
|
3
|
+
-- Marks a workflow as side-effect-free for external MCP callers: the
|
|
4
|
+
-- invoke_workflow_read_safe tool (manifest read_safe: true) starts only
|
|
5
|
+
-- workflows carrying this flag, extending the tool-manifest read-scope
|
|
6
|
+
-- contract to workflow invocation. Fail-closed: unset means not read-safe.
|
|
7
|
+
|
|
8
|
+
ALTER TABLE lt_config_workflows
|
|
9
|
+
ADD COLUMN IF NOT EXISTS read_safe BOOLEAN NOT NULL DEFAULT false;
|
|
@@ -64,6 +64,21 @@ export declare function publishActivityEvent(params: {
|
|
|
64
64
|
activityName: string;
|
|
65
65
|
data?: Record<string, any>;
|
|
66
66
|
}): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* The dashboard-surface broadcast subject. Announcements publish here and the
|
|
69
|
+
* dashboard subscribes; the payload is the announcement row (small by
|
|
70
|
+
* nature). Delivery reaches every authenticated socket — role targeting is
|
|
71
|
+
* display scoping, never confidentiality.
|
|
72
|
+
*/
|
|
73
|
+
export declare const ANNOUNCEMENT_TOPIC = "system.surfaces.dashboard";
|
|
74
|
+
/**
|
|
75
|
+
* Publish a dashboard announcement event.
|
|
76
|
+
* Subject: system.surfaces.dashboard (fixed — one surface, one channel)
|
|
77
|
+
*/
|
|
78
|
+
export declare function publishAnnouncementEvent(params: {
|
|
79
|
+
type: 'announcement.created' | 'announcement.deleted';
|
|
80
|
+
announcement: Record<string, any>;
|
|
81
|
+
}): Promise<void>;
|
|
67
82
|
/**
|
|
68
83
|
* Publish a knowledge lifecycle event.
|
|
69
84
|
* Subject: system.knowledge.{domain}.{action}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ANNOUNCEMENT_TOPIC = void 0;
|
|
3
4
|
exports.publishMilestoneEvent = publishMilestoneEvent;
|
|
4
5
|
exports.publishTaskEvent = publishTaskEvent;
|
|
5
6
|
exports.publishEscalationEvent = publishEscalationEvent;
|
|
6
7
|
exports.publishActivityEvent = publishActivityEvent;
|
|
8
|
+
exports.publishAnnouncementEvent = publishAnnouncementEvent;
|
|
7
9
|
exports.publishKnowledgeEvent = publishKnowledgeEvent;
|
|
8
10
|
exports.publishFileEvent = publishFileEvent;
|
|
9
11
|
exports.publishAgentEvent = publishAgentEvent;
|
|
@@ -104,6 +106,26 @@ function publishActivityEvent(params) {
|
|
|
104
106
|
timestamp: new Date().toISOString(),
|
|
105
107
|
});
|
|
106
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* The dashboard-surface broadcast subject. Announcements publish here and the
|
|
111
|
+
* dashboard subscribes; the payload is the announcement row (small by
|
|
112
|
+
* nature). Delivery reaches every authenticated socket — role targeting is
|
|
113
|
+
* display scoping, never confidentiality.
|
|
114
|
+
*/
|
|
115
|
+
exports.ANNOUNCEMENT_TOPIC = 'system.surfaces.dashboard';
|
|
116
|
+
/**
|
|
117
|
+
* Publish a dashboard announcement event.
|
|
118
|
+
* Subject: system.surfaces.dashboard (fixed — one surface, one channel)
|
|
119
|
+
*/
|
|
120
|
+
function publishAnnouncementEvent(params) {
|
|
121
|
+
const action = params.type.split('.')[1];
|
|
122
|
+
return fireAndForget({
|
|
123
|
+
type: exports.ANNOUNCEMENT_TOPIC,
|
|
124
|
+
source: 'announcement',
|
|
125
|
+
data: { action, announcement: params.announcement },
|
|
126
|
+
timestamp: new Date().toISOString(),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
107
129
|
/**
|
|
108
130
|
* Publish a knowledge lifecycle event.
|
|
109
131
|
* Subject: system.knowledge.{domain}.{action}
|
package/build/modules/auth.js
CHANGED
|
@@ -43,6 +43,7 @@ exports.signToken = signToken;
|
|
|
43
43
|
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
44
44
|
const config_1 = require("./config");
|
|
45
45
|
const sso_1 = require("./sso");
|
|
46
|
+
const logger_1 = require("../lib/logger");
|
|
46
47
|
const user_1 = require("../services/user");
|
|
47
48
|
const sso_provision_1 = require("../services/user/sso-provision");
|
|
48
49
|
const bot_api_key_1 = require("../services/auth/bot-api-key");
|
|
@@ -156,7 +157,10 @@ const requireAuth = async (req, res, next) => {
|
|
|
156
157
|
const mw = _authMiddleware || createAuthMiddleware(new JwtAuthAdapter());
|
|
157
158
|
return mw(req, res, next);
|
|
158
159
|
}
|
|
159
|
-
// SSO fallback: no Bearer, but host may have authenticated via cookies/headers
|
|
160
|
+
// SSO fallback: no Bearer, but host may have authenticated via cookies/headers.
|
|
161
|
+
// `res` is deliberately NOT passed to resolve here: this path runs on every
|
|
162
|
+
// cookie-bearing request, and ambient API traffic must never slide the host
|
|
163
|
+
// session — only the explicit exchange (login + gated keepalive beat) does.
|
|
160
164
|
const ssoConfig = (0, sso_1.getSSOConfig)();
|
|
161
165
|
if (ssoConfig) {
|
|
162
166
|
try {
|
|
@@ -177,8 +181,10 @@ const requireAuth = async (req, res, next) => {
|
|
|
177
181
|
return next();
|
|
178
182
|
}
|
|
179
183
|
}
|
|
180
|
-
catch {
|
|
181
|
-
// SSO resolve failed — fall through to 401
|
|
184
|
+
catch (err) {
|
|
185
|
+
// SSO resolve failed — fall through to 401, but leave a trace so host
|
|
186
|
+
// resolve errors are diagnosable.
|
|
187
|
+
logger_1.loggerRegistry.debug(`[long-tail] sso resolve failed on auth fallback: ${err?.message}`);
|
|
182
188
|
}
|
|
183
189
|
}
|
|
184
190
|
// No Bearer, no SSO — delegate to standard middleware (returns 401)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const express_1 = require("express");
|
|
37
|
+
const api = __importStar(require("../api/announcements"));
|
|
38
|
+
const auth_1 = require("../modules/auth");
|
|
39
|
+
const router = (0, express_1.Router)();
|
|
40
|
+
/**
|
|
41
|
+
* Dashboard announcements. Publishing and removal are role-manager acts
|
|
42
|
+
* (superadmin, admin type, or engineer); any authenticated user reads their
|
|
43
|
+
* role-filtered slice. Targeting is display scoping — the live event
|
|
44
|
+
* broadcasts to every authenticated subscriber.
|
|
45
|
+
*/
|
|
46
|
+
router.get('/', async (req, res) => {
|
|
47
|
+
const result = await api.listAnnouncements(req.auth);
|
|
48
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
49
|
+
});
|
|
50
|
+
router.post('/', auth_1.requireRoleManager, async (req, res) => {
|
|
51
|
+
const result = await api.createAnnouncement({
|
|
52
|
+
body: req.body?.body,
|
|
53
|
+
title: req.body?.title,
|
|
54
|
+
layout: req.body?.layout,
|
|
55
|
+
roles: req.body?.roles,
|
|
56
|
+
expiresAt: req.body?.expiresAt,
|
|
57
|
+
}, req.auth);
|
|
58
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
59
|
+
});
|
|
60
|
+
router.delete('/:id', auth_1.requireRoleManager, async (req, res) => {
|
|
61
|
+
const result = await api.deleteAnnouncement({ id: String(req.params.id) }, req.auth);
|
|
62
|
+
res.status(result.status).json(result.data ?? { error: result.error });
|
|
63
|
+
});
|
|
64
|
+
exports.default = router;
|
package/build/routes/auth-sso.js
CHANGED
|
@@ -45,7 +45,12 @@ const router = (0, express_1.Router)();
|
|
|
45
45
|
* login form with a transparent token exchange.
|
|
46
46
|
*/
|
|
47
47
|
router.post('/sso', async (req, res) => {
|
|
48
|
-
const result = await api.exchangeSSO(req);
|
|
48
|
+
const result = await api.exchangeSSO(req, res);
|
|
49
|
+
// A host's resolve may only set headers on `res`; if one violates the
|
|
50
|
+
// contract and writes the response, degrade to a skipped beat instead of
|
|
51
|
+
// a headers-after-send crash.
|
|
52
|
+
if (res.headersSent)
|
|
53
|
+
return;
|
|
49
54
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
50
55
|
});
|
|
51
56
|
exports.default = router;
|
|
@@ -109,6 +109,7 @@ function registerListRoutes(router) {
|
|
|
109
109
|
orderBy: jsonParam(req.query.orderBy),
|
|
110
110
|
available: req.query.available != null ? req.query.available === 'true' : undefined,
|
|
111
111
|
jeopardy: req.query.jeopardy === '1' || req.query.jeopardy === 'true' || undefined,
|
|
112
|
+
include: req.query.include,
|
|
112
113
|
}, req.auth);
|
|
113
114
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
114
115
|
});
|
|
@@ -136,6 +137,7 @@ function registerListRoutes(router) {
|
|
|
136
137
|
exists: jsonParam(req.query.exists),
|
|
137
138
|
orderBy: jsonParam(req.query.orderBy),
|
|
138
139
|
jeopardy: req.query.jeopardy === '1' || req.query.jeopardy === 'true' || undefined,
|
|
140
|
+
include: req.query.include,
|
|
139
141
|
}, req.auth);
|
|
140
142
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
141
143
|
});
|
package/build/routes/index.js
CHANGED
|
@@ -38,6 +38,7 @@ const topics_1 = __importDefault(require("./topics"));
|
|
|
38
38
|
const nats_credentials_1 = __importDefault(require("./nats-credentials"));
|
|
39
39
|
const scan_codes_1 = __importDefault(require("./scan-codes"));
|
|
40
40
|
const domain_1 = __importDefault(require("./domain"));
|
|
41
|
+
const announcements_1 = __importDefault(require("./announcements"));
|
|
41
42
|
const router = (0, express_1.Router)();
|
|
42
43
|
// Public routes (no auth required — they handle their own auth)
|
|
43
44
|
router.use('/auth', auth_2.default);
|
|
@@ -76,6 +77,7 @@ router.use('/capabilities', capabilities_1.default);
|
|
|
76
77
|
router.use('/topics', topics_1.default);
|
|
77
78
|
router.use('/scan-codes', scan_codes_1.default);
|
|
78
79
|
router.use('/domain', domain_1.default);
|
|
80
|
+
router.use('/announcements', announcements_1.default);
|
|
79
81
|
const overview_1 = __importDefault(require("./overview"));
|
|
80
82
|
router.use('/overview', overview_1.default);
|
|
81
83
|
const diagnostics_1 = __importDefault(require("./diagnostics"));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A dashboard announcement — a broadcast notice on the dashboard surface.
|
|
3
|
+
* Role targeting is display scoping only (live events reach every
|
|
4
|
+
* authenticated socket); bodies must never carry secrets.
|
|
5
|
+
*/
|
|
6
|
+
export interface LTAnnouncement {
|
|
7
|
+
id: string;
|
|
8
|
+
title: string | null;
|
|
9
|
+
/** Markdown. */
|
|
10
|
+
body: string;
|
|
11
|
+
layout: string;
|
|
12
|
+
/** Empty = everyone; otherwise shown to holders of any named role. */
|
|
13
|
+
roles: string[];
|
|
14
|
+
created_by: string | null;
|
|
15
|
+
created_at: string;
|
|
16
|
+
expires_at: string;
|
|
17
|
+
}
|
|
18
|
+
/** Only the body is required; everything else has a liberal default (24h expiry). */
|
|
19
|
+
export declare function createAnnouncement(input: {
|
|
20
|
+
body: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
layout?: string;
|
|
23
|
+
roles?: string[];
|
|
24
|
+
createdBy?: string;
|
|
25
|
+
expiresAt?: string;
|
|
26
|
+
}): Promise<LTAnnouncement>;
|
|
27
|
+
/** Active announcements visible to a viewer; null roles = the unscoped admin view. */
|
|
28
|
+
export declare function listActiveAnnouncements(userRoles: string[] | null): Promise<LTAnnouncement[]>;
|
|
29
|
+
/** Returns the deleted row so the caller can publish its removal, or null. */
|
|
30
|
+
export declare function deleteAnnouncement(id: string): Promise<LTAnnouncement | null>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAnnouncement = createAnnouncement;
|
|
4
|
+
exports.listActiveAnnouncements = listActiveAnnouncements;
|
|
5
|
+
exports.deleteAnnouncement = deleteAnnouncement;
|
|
6
|
+
const db_1 = require("../../lib/db");
|
|
7
|
+
const sql_1 = require("./sql");
|
|
8
|
+
/** Only the body is required; everything else has a liberal default (24h expiry). */
|
|
9
|
+
async function createAnnouncement(input) {
|
|
10
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.INSERT_ANNOUNCEMENT, [
|
|
11
|
+
input.title ?? null,
|
|
12
|
+
input.body,
|
|
13
|
+
input.layout ?? null,
|
|
14
|
+
input.roles ?? null,
|
|
15
|
+
input.createdBy ?? null,
|
|
16
|
+
input.expiresAt ?? null,
|
|
17
|
+
]);
|
|
18
|
+
return rows[0];
|
|
19
|
+
}
|
|
20
|
+
/** Active announcements visible to a viewer; null roles = the unscoped admin view. */
|
|
21
|
+
async function listActiveAnnouncements(userRoles) {
|
|
22
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.LIST_ACTIVE_ANNOUNCEMENTS, [userRoles]);
|
|
23
|
+
return rows;
|
|
24
|
+
}
|
|
25
|
+
/** Returns the deleted row so the caller can publish its removal, or null. */
|
|
26
|
+
async function deleteAnnouncement(id) {
|
|
27
|
+
const { rows } = await (0, db_1.getPool)().query(sql_1.DELETE_ANNOUNCEMENT, [id]);
|
|
28
|
+
return rows[0] ?? null;
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const INSERT_ANNOUNCEMENT = "\n INSERT INTO lt_announcements (title, body, layout, roles, created_by, expires_at)\n VALUES ($1, $2, COALESCE($3, 'banner'), COALESCE($4::text[], '{}'), $5,\n COALESCE($6::timestamptz, NOW() + INTERVAL '24 hours'))\n RETURNING *";
|
|
2
|
+
/**
|
|
3
|
+
* Active announcements for a viewer. $1 = the viewer's role names, or NULL
|
|
4
|
+
* for the unscoped admin view. Untargeted rows (roles = '{}') reach everyone;
|
|
5
|
+
* targeted rows reach holders of any named role.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LIST_ACTIVE_ANNOUNCEMENTS = "\n SELECT * FROM lt_announcements\n WHERE expires_at > NOW()\n AND ($1::text[] IS NULL OR roles = '{}' OR roles && $1::text[])\n ORDER BY created_at DESC";
|
|
8
|
+
export declare const DELETE_ANNOUNCEMENT = "\n DELETE FROM lt_announcements WHERE id = $1\n RETURNING *";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─── Announcement queries ────────────────────────────────────────────────────
|
|
3
|
+
// Liberal defaults live in the SQL so the service contract is self-describing:
|
|
4
|
+
// only the body is required; layout, targeting, and the 24-hour expiry fill in.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DELETE_ANNOUNCEMENT = exports.LIST_ACTIVE_ANNOUNCEMENTS = exports.INSERT_ANNOUNCEMENT = void 0;
|
|
7
|
+
exports.INSERT_ANNOUNCEMENT = `
|
|
8
|
+
INSERT INTO lt_announcements (title, body, layout, roles, created_by, expires_at)
|
|
9
|
+
VALUES ($1, $2, COALESCE($3, 'banner'), COALESCE($4::text[], '{}'), $5,
|
|
10
|
+
COALESCE($6::timestamptz, NOW() + INTERVAL '24 hours'))
|
|
11
|
+
RETURNING *`;
|
|
12
|
+
/**
|
|
13
|
+
* Active announcements for a viewer. $1 = the viewer's role names, or NULL
|
|
14
|
+
* for the unscoped admin view. Untargeted rows (roles = '{}') reach everyone;
|
|
15
|
+
* targeted rows reach holders of any named role.
|
|
16
|
+
*/
|
|
17
|
+
exports.LIST_ACTIVE_ANNOUNCEMENTS = `
|
|
18
|
+
SELECT * FROM lt_announcements
|
|
19
|
+
WHERE expires_at > NOW()
|
|
20
|
+
AND ($1::text[] IS NULL OR roles = '{}' OR roles && $1::text[])
|
|
21
|
+
ORDER BY created_at DESC`;
|
|
22
|
+
exports.DELETE_ANNOUNCEMENT = `
|
|
23
|
+
DELETE FROM lt_announcements WHERE id = $1
|
|
24
|
+
RETURNING *`;
|