@hotmeshio/long-tail 0.13.1 → 0.14.1
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/escalations/claim.d.ts +4 -1
- package/build/api/escalations/claim.js +6 -2
- 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/index.js +4 -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/routes/announcements.d.ts +2 -0
- package/build/routes/announcements.js +64 -0
- package/build/routes/escalations/list.js +2 -0
- package/build/routes/escalations/single.js +3 -1
- package/build/routes/index.js +2 -0
- package/build/sdk/index.d.ts +1 -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/escalation/crud.d.ts +10 -2
- package/build/services/escalation/crud.js +20 -12
- 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 +3 -5
- 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/config.d.ts +8 -0
- package/build/types/startup.d.ts +5 -0
- package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js → AdminDashboard-C4h1R-lz.js} +2 -2
- package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js.map → AdminDashboard-C4h1R-lz.js.map} +1 -1
- package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js → AgentConfigPage-EWC8VQ7R.js} +2 -2
- package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js.map → AgentConfigPage-EWC8VQ7R.js.map} +1 -1
- package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js → AgentDetailPage-DaLfa80d.js} +2 -2
- package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js.map → AgentDetailPage-DaLfa80d.js.map} +1 -1
- package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js → AgentsPage-islj_zrh.js} +2 -2
- package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js.map → AgentsPage-islj_zrh.js.map} +1 -1
- package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js +2 -0
- package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js.map +1 -0
- package/dashboard/dist/assets/{BotPicker-BN-MKITV.js → BotPicker-CnX8xfka.js} +2 -2
- package/dashboard/dist/assets/{BotPicker-BN-MKITV.js.map → BotPicker-CnX8xfka.js.map} +1 -1
- package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js → CapabilitiesPage-DK7wGMFt.js} +2 -2
- package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js.map → CapabilitiesPage-DK7wGMFt.js.map} +1 -1
- package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js → CollapsibleSection-WqEpMTyx.js} +2 -2
- package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js.map → CollapsibleSection-WqEpMTyx.js.map} +1 -1
- package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js +2 -0
- package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js.map +1 -0
- package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js → CredentialsPage-CfT60FiU.js} +2 -2
- package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js.map → CredentialsPage-CfT60FiU.js.map} +1 -1
- package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js → CronLabel-ds7dLz6S.js} +2 -2
- package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js.map → CronLabel-ds7dLz6S.js.map} +1 -1
- package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js +2 -0
- package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js.map +1 -0
- package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js → ElapsedCell-DRQhFky_.js} +2 -2
- package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js.map → ElapsedCell-DRQhFky_.js.map} +1 -1
- package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js → EntityTimelinePanel-nCgWdmpK.js} +2 -2
- package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js.map → EntityTimelinePanel-nCgWdmpK.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js → EscalationListSchemaPage-DBCnPMG9.js} +2 -2
- package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js.map → EscalationListSchemaPage-DBCnPMG9.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js → EscalationSchemaPage-DfzRTqhV.js} +2 -2
- package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js.map → EscalationSchemaPage-DfzRTqhV.js.map} +1 -1
- package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js → EscalationsOverview-CWd2Ivso.js} +2 -2
- package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js.map → EscalationsOverview-CWd2Ivso.js.map} +1 -1
- package/dashboard/dist/assets/{EventTable-BOcgZ78i.js → EventTable-Dm9Fbab1.js} +2 -2
- package/dashboard/dist/assets/{EventTable-BOcgZ78i.js.map → EventTable-Dm9Fbab1.js.map} +1 -1
- package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js → FilterBar-DR4cJvTB.js} +2 -2
- package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js.map → FilterBar-DR4cJvTB.js.map} +1 -1
- package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js → GraphInvokePage-DQt64Ru0.js} +2 -2
- package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js.map → GraphInvokePage-DQt64Ru0.js.map} +1 -1
- package/dashboard/dist/assets/{HomePage-C2IhF9WB.js → HomePage-D7qNiqtw.js} +2 -2
- package/dashboard/dist/assets/{HomePage-C2IhF9WB.js.map → HomePage-D7qNiqtw.js.map} +1 -1
- package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js → ListToolbar-BdZkpRMo.js} +2 -2
- package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js.map → ListToolbar-BdZkpRMo.js.map} +1 -1
- package/dashboard/dist/assets/{McpOverview-DstPch5M.js → McpOverview-DHAEYY1b.js} +2 -2
- package/dashboard/dist/assets/{McpOverview-DstPch5M.js.map → McpOverview-DHAEYY1b.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js → McpQueryDetailPage-BfGhRO_c.js} +2 -2
- package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js.map → McpQueryDetailPage-BfGhRO_c.js.map} +1 -1
- package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js → McpQueryPage-3EXLX1Eq.js} +2 -2
- package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js.map → McpQueryPage-3EXLX1Eq.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js → McpRunDetailPage-DHI0F65P.js} +2 -2
- package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js.map → McpRunDetailPage-DHI0F65P.js.map} +1 -1
- package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js → McpRunsPage-C6-KpYCY.js} +2 -2
- package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js.map → McpRunsPage-C6-KpYCY.js.map} +1 -1
- package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js → OperationsPage-BNW7uris.js} +2 -2
- package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js.map → OperationsPage-BNW7uris.js.map} +1 -1
- package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js → OperatorDashboard-DLp9gCTA.js} +2 -2
- package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js.map → OperatorDashboard-DLp9gCTA.js.map} +1 -1
- package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js → PersonaDetailPage-DFv4Zwmq.js} +2 -2
- package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js.map → PersonaDetailPage-DFv4Zwmq.js.map} +1 -1
- package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js → PersonasPage-C52o87Zv.js} +2 -2
- package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js.map → PersonasPage-C52o87Zv.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js → ProcessDetailPage-CKCxXogl.js} +2 -2
- package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js.map → ProcessDetailPage-CKCxXogl.js.map} +1 -1
- package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js → ProcessesListPage-D1bxIy7-.js} +2 -2
- package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js.map → ProcessesListPage-D1bxIy7-.js.map} +1 -1
- package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js → RoleDetailPage-_MrbOGW_.js} +2 -2
- package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js.map → RoleDetailPage-_MrbOGW_.js.map} +1 -1
- package/dashboard/dist/assets/{RolesPage-DeRVQux8.js → RolesPage-ZVCkB4iF.js} +2 -2
- package/dashboard/dist/assets/{RolesPage-DeRVQux8.js.map → RolesPage-ZVCkB4iF.js.map} +1 -1
- package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js → RunAsSelector-BAqa1Tya.js} +2 -2
- package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js.map → RunAsSelector-BAqa1Tya.js.map} +1 -1
- package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js → ScanCodesPage-b7WkFiy-.js} +2 -2
- package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js.map → ScanCodesPage-b7WkFiy-.js.map} +1 -1
- package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js +2 -0
- package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js.map +1 -0
- package/dashboard/dist/assets/ScanStationPage-CPC9CdCR.js +2 -0
- package/dashboard/dist/assets/ScanStationPage-CPC9CdCR.js.map +1 -0
- package/dashboard/dist/assets/{StickyPagination-B99hVu95.js → StickyPagination-CgSzarlP.js} +2 -2
- package/dashboard/dist/assets/{StickyPagination-B99hVu95.js.map → StickyPagination-CgSzarlP.js.map} +1 -1
- package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js → StreamMessageDetail-B4E3S5RB.js} +2 -2
- package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js.map → StreamMessageDetail-B4E3S5RB.js.map} +1 -1
- package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js → SwimlaneTimeline-BkcjucMZ.js} +2 -2
- package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js.map → SwimlaneTimeline-BkcjucMZ.js.map} +1 -1
- package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js → TaskDetailPage-D7e8x2gX.js} +2 -2
- package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js.map → TaskDetailPage-D7e8x2gX.js.map} +1 -1
- package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js → TasksListPage-B4mxP9Ey.js} +2 -2
- package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js.map → TasksListPage-B4mxP9Ey.js.map} +1 -1
- package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js → TimeAgo-D6sbYsUO.js} +2 -2
- package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js.map → TimeAgo-D6sbYsUO.js.map} +1 -1
- package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js → TimestampCell-DFDf3NAT.js} +2 -2
- package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js.map → TimestampCell-DFDf3NAT.js.map} +1 -1
- package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js → ToolTestPanel-DbWw0-Le.js} +2 -2
- package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js.map → ToolTestPanel-DbWw0-Le.js.map} +1 -1
- package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js → TopicDetailPage-C6CPcvuO.js} +2 -2
- package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js.map → TopicDetailPage-C6CPcvuO.js.map} +1 -1
- package/dashboard/dist/assets/{TopicsPage-DEyvm669.js → TopicsPage-C8_XpeT2.js} +2 -2
- package/dashboard/dist/assets/{TopicsPage-DEyvm669.js.map → TopicsPage-C8_XpeT2.js.map} +1 -1
- package/dashboard/dist/assets/{UserName-BV6SKI9P.js → UserName-CIoJvf_e.js} +2 -2
- package/dashboard/dist/assets/{UserName-BV6SKI9P.js.map → UserName-CIoJvf_e.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js → WorkflowExecutionPage-Bq3kSkRr.js} +2 -2
- package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js.map → WorkflowExecutionPage-Bq3kSkRr.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js → WorkflowsDashboard-y2L_zwnf.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js.map → WorkflowsDashboard-y2L_zwnf.js.map} +1 -1
- package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js → WorkflowsOverview-ChE1Mm3P.js} +2 -2
- package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js.map → WorkflowsOverview-ChE1Mm3P.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js → YamlWorkflowDetailPage-D0aY_inb.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js.map → YamlWorkflowDetailPage-D0aY_inb.js.map} +1 -1
- package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js → YamlWorkflowsPage-DJ0JitPs.js} +2 -2
- package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js.map → YamlWorkflowsPage-DJ0JitPs.js.map} +1 -1
- package/dashboard/dist/assets/{agents-BTDsRK8e.js → agents-Bu5Ly_ER.js} +2 -2
- package/dashboard/dist/assets/{agents-BTDsRK8e.js.map → agents-Bu5Ly_ER.js.map} +1 -1
- package/dashboard/dist/assets/{bots-DxLrfdfr.js → bots-Cb14wZ1Y.js} +2 -2
- package/dashboard/dist/assets/{bots-DxLrfdfr.js.map → bots-Cb14wZ1Y.js.map} +1 -1
- package/dashboard/dist/assets/{capabilities-DbTmeW-S.js → capabilities-DeHLk9JJ.js} +2 -2
- package/dashboard/dist/assets/{capabilities-DbTmeW-S.js.map → capabilities-DeHLk9JJ.js.map} +1 -1
- package/dashboard/dist/assets/{controlplane-CEBntAL4.js → controlplane-YBZ3SbA6.js} +2 -2
- package/dashboard/dist/assets/{controlplane-CEBntAL4.js.map → controlplane-YBZ3SbA6.js.map} +1 -1
- package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js → escalation-columns-CA9DQlhA.js} +2 -2
- package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js.map → escalation-columns-CA9DQlhA.js.map} +1 -1
- package/dashboard/dist/assets/{index-BhapT-Vl.js → index-B0qNe7Ux.js} +2 -2
- package/dashboard/dist/assets/{index-BhapT-Vl.js.map → index-B0qNe7Ux.js.map} +1 -1
- package/dashboard/dist/assets/{index-kes8V4Xw.js → index-B4Nea96C.js} +2 -2
- package/dashboard/dist/assets/{index-kes8V4Xw.js.map → index-B4Nea96C.js.map} +1 -1
- package/dashboard/dist/assets/{index-cFHoANSG.css → index-B5jxf81r.css} +1 -1
- package/dashboard/dist/assets/{index-Bqm4zu46.js → index-B7fE-rND.js} +2 -2
- package/dashboard/dist/assets/{index-Bqm4zu46.js.map → index-B7fE-rND.js.map} +1 -1
- package/dashboard/dist/assets/{index-nwLh3CK2.js → index-BAKroiNw.js} +2 -2
- package/dashboard/dist/assets/{index-nwLh3CK2.js.map → index-BAKroiNw.js.map} +1 -1
- package/dashboard/dist/assets/{index-CgIBjZta.js → index-BRmgxeZM.js} +2 -2
- package/dashboard/dist/assets/{index-CgIBjZta.js.map → index-BRmgxeZM.js.map} +1 -1
- package/dashboard/dist/assets/{index-De8iV1y2.js → index-BaDimDGQ.js} +2 -2
- package/dashboard/dist/assets/{index-De8iV1y2.js.map → index-BaDimDGQ.js.map} +1 -1
- package/dashboard/dist/assets/{index-CDkg6iOE.js → index-BhurEB5s.js} +2 -2
- package/dashboard/dist/assets/{index-CDkg6iOE.js.map → index-BhurEB5s.js.map} +1 -1
- package/dashboard/dist/assets/{index-B2hz0pUh.js → index-CQriisJy.js} +2 -2
- package/dashboard/dist/assets/{index-B2hz0pUh.js.map → index-CQriisJy.js.map} +1 -1
- package/dashboard/dist/assets/{index-B9m7fA3M.js → index-D5MSJsiW.js} +2 -2
- package/dashboard/dist/assets/{index-B9m7fA3M.js.map → index-D5MSJsiW.js.map} +1 -1
- package/dashboard/dist/assets/{index-DBXm49S6.js → index-Ntul2ZC1.js} +30 -29
- package/dashboard/dist/assets/index-Ntul2ZC1.js.map +1 -0
- package/dashboard/dist/assets/{index-C0hSttF5.js → index-YUv7aNb4.js} +2 -2
- package/dashboard/dist/assets/{index-C0hSttF5.js.map → index-YUv7aNb4.js.map} +1 -1
- package/dashboard/dist/assets/{index-CVBBkW8V.js → index-chMUPSOd.js} +2 -2
- package/dashboard/dist/assets/{index-CVBBkW8V.js.map → index-chMUPSOd.js.map} +1 -1
- package/dashboard/dist/assets/index-uWUJXqGS.js +3 -0
- package/dashboard/dist/assets/index-uWUJXqGS.js.map +1 -0
- package/dashboard/dist/assets/{knowledge-oFYAanUp.js → knowledge-B1HqYuB2.js} +2 -2
- package/dashboard/dist/assets/{knowledge-oFYAanUp.js.map → knowledge-B1HqYuB2.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js → mcp-dhihqJpH.js} +2 -2
- package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js.map → mcp-dhihqJpH.js.map} +1 -1
- package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js → mcp-query-B_gkB7JK.js} +2 -2
- package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js.map → mcp-query-B_gkB7JK.js.map} +1 -1
- package/dashboard/dist/assets/metadata-display-DHjqWkLG.js +2 -0
- package/dashboard/dist/assets/metadata-display-DHjqWkLG.js.map +1 -0
- package/dashboard/dist/assets/{personas-D5ehmtRb.js → personas-Bw_OlfI6.js} +2 -2
- package/dashboard/dist/assets/{personas-D5ehmtRb.js.map → personas-Bw_OlfI6.js.map} +1 -1
- package/dashboard/dist/assets/{pipelines-xgPKGEdD.js → pipelines-BYwn0LXY.js} +2 -2
- package/dashboard/dist/assets/{pipelines-xgPKGEdD.js.map → pipelines-BYwn0LXY.js.map} +1 -1
- package/dashboard/dist/assets/{tasks-CLyrl-MU.js → tasks-t6bPmJ7P.js} +2 -2
- package/dashboard/dist/assets/{tasks-CLyrl-MU.js.map → tasks-t6bPmJ7P.js.map} +1 -1
- package/dashboard/dist/assets/{topics-B_gO7CQ0.js → topics-Bgo9xw80.js} +2 -2
- package/dashboard/dist/assets/{topics-B_gO7CQ0.js.map → topics-Bgo9xw80.js.map} +1 -1
- package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js → useEventHooks-BJbMbg_h.js} +2 -2
- package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js.map → useEventHooks-BJbMbg_h.js.map} +1 -1
- package/dashboard/dist/assets/{useNamespace-C238M4Qn.js → useNamespace-CaXJuSFG.js} +2 -2
- package/dashboard/dist/assets/{useNamespace-C238M4Qn.js.map → useNamespace-CaXJuSFG.js.map} +1 -1
- package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js → useYamlActivityEvents-B47LQrDk.js} +2 -2
- package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js.map → useYamlActivityEvents-B47LQrDk.js.map} +1 -1
- package/dashboard/dist/assets/{users-BFaTe6Mt.js → users-D0jvzUqW.js} +2 -2
- package/dashboard/dist/assets/{users-BFaTe6Mt.js.map → users-D0jvzUqW.js.map} +1 -1
- package/dashboard/dist/assets/{workflows-DXz7tZxp.js → workflows-DRoZRrMH.js} +2 -2
- package/dashboard/dist/assets/{workflows-DXz7tZxp.js.map → workflows-DRoZRrMH.js.map} +1 -1
- package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js → yaml-workflows-BdhYyIef.js} +2 -2
- package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js.map → yaml-workflows-BdhYyIef.js.map} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/docs/api/http/escalations.md +5 -1
- package/docs/dashboard.md +15 -0
- package/docs/hitl/iframe.md +56 -6
- 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/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/ScanStationPage-DH1ynTX9.js +0 -2
- package/dashboard/dist/assets/ScanStationPage-DH1ynTX9.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
|
+
}
|
|
@@ -21,12 +21,15 @@ export declare function claimEscalation(input: {
|
|
|
21
21
|
* Release a claimed escalation back to the pool.
|
|
22
22
|
*
|
|
23
23
|
* Only the user who holds the claim can release it. Publishes a
|
|
24
|
-
* `escalation.released` event
|
|
24
|
+
* `escalation.released` event unless `quiet` — the identical release with no
|
|
25
|
+
* event, for bookkeeping releases that are not lifecycle transitions.
|
|
25
26
|
*
|
|
26
27
|
* @param input.id — escalation UUID
|
|
28
|
+
* @param input.quiet — suppress the `released` event (default: loud)
|
|
27
29
|
* @param auth — authenticated user context
|
|
28
30
|
* @returns `{ status: 200, data: { escalation } }` or 409
|
|
29
31
|
*/
|
|
30
32
|
export declare function releaseEscalation(input: {
|
|
31
33
|
id: string;
|
|
34
|
+
quiet?: boolean;
|
|
32
35
|
}, auth: LTApiAuth): Promise<LTApiResult>;
|
|
@@ -81,9 +81,11 @@ async function claimEscalation(input, auth) {
|
|
|
81
81
|
* Release a claimed escalation back to the pool.
|
|
82
82
|
*
|
|
83
83
|
* Only the user who holds the claim can release it. Publishes a
|
|
84
|
-
* `escalation.released` event
|
|
84
|
+
* `escalation.released` event unless `quiet` — the identical release with no
|
|
85
|
+
* event, for bookkeeping releases that are not lifecycle transitions.
|
|
85
86
|
*
|
|
86
87
|
* @param input.id — escalation UUID
|
|
88
|
+
* @param input.quiet — suppress the `released` event (default: loud)
|
|
87
89
|
* @param auth — authenticated user context
|
|
88
90
|
* @returns `{ status: 200, data: { escalation } }` or 409
|
|
89
91
|
*/
|
|
@@ -97,7 +99,9 @@ async function releaseEscalation(input, auth) {
|
|
|
97
99
|
const manageDenied = await (0, helpers_1.assertQueueManageAccess)(auth.userId, escalation.role);
|
|
98
100
|
if (manageDenied)
|
|
99
101
|
return manageDenied;
|
|
100
|
-
const result = await escalationService.releaseEscalation(input.id, auth.userId
|
|
102
|
+
const result = await escalationService.releaseEscalation(input.id, auth.userId, {
|
|
103
|
+
quiet: input.quiet === true,
|
|
104
|
+
});
|
|
101
105
|
if (!result) {
|
|
102
106
|
return { status: 409, error: 'Escalation not found or not claimed by you' };
|
|
103
107
|
}
|
|
@@ -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 ?? [],
|
package/build/index.js
CHANGED
|
@@ -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}
|
|
@@ -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;
|
|
@@ -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
|
});
|
|
@@ -84,12 +84,14 @@ function registerSingleRoutes(router) {
|
|
|
84
84
|
* Release a claimed escalation back to the available pool.
|
|
85
85
|
* Only the assigned actor (token user, or the badged person when an
|
|
86
86
|
* X-LT-Acting-Token grant rides the request) may release their own claim.
|
|
87
|
+
* `quiet: true` in the body performs the identical release without the
|
|
88
|
+
* `released` event — bookkeeping releases only; default stays loud.
|
|
87
89
|
*/
|
|
88
90
|
router.post('/:id/release', async (req, res) => {
|
|
89
91
|
const auth = await (0, acting_1.effectiveWorkAuth)(req, res);
|
|
90
92
|
if (!auth)
|
|
91
93
|
return;
|
|
92
|
-
const result = await api.releaseEscalation({ id: req.params.id }, auth);
|
|
94
|
+
const result = await api.releaseEscalation({ id: req.params.id, quiet: req.body?.quiet === true }, auth);
|
|
93
95
|
res.status(result.status).json(result.data ?? { error: result.error });
|
|
94
96
|
});
|
|
95
97
|
/**
|
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"));
|
package/build/sdk/index.d.ts
CHANGED
|
@@ -139,6 +139,7 @@ export declare function createClient(options?: LTClientOptions): {
|
|
|
139
139
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
140
140
|
release: (input: {
|
|
141
141
|
id: string;
|
|
142
|
+
quiet?: boolean;
|
|
142
143
|
}, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
|
|
143
144
|
resolve: (input: {
|
|
144
145
|
id: string;
|
|
@@ -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 *`;
|
|
@@ -29,6 +29,7 @@ async function getWorkflowConfig(workflowType) {
|
|
|
29
29
|
resolver_schema: wf.resolver_schema ?? null,
|
|
30
30
|
cron_schedule: wf.cron_schedule ?? null,
|
|
31
31
|
execute_as: wf.execute_as ?? null,
|
|
32
|
+
read_safe: wf.read_safe ?? false,
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
async function listWorkflowConfigs() {
|
|
@@ -66,5 +67,6 @@ async function listWorkflowConfigs() {
|
|
|
66
67
|
resolver_schema: wf.resolver_schema ?? null,
|
|
67
68
|
cron_schedule: wf.cron_schedule ?? null,
|
|
68
69
|
execute_as: wf.execute_as ?? null,
|
|
70
|
+
read_safe: wf.read_safe ?? false,
|
|
69
71
|
}));
|
|
70
72
|
}
|