@hotmeshio/long-tail 0.13.1 → 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/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/routes/announcements.d.ts +2 -0
- package/build/routes/announcements.js +64 -0
- 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/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-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/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/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
|
@@ -261,6 +261,26 @@ const SYSTEM_TOPICS = [
|
|
|
261
261
|
example_payload: { workflowId: 'wf-abc', workflowName: 'processOrder', milestones: [{ name: 'items_processed', value: 42 }] },
|
|
262
262
|
tags: ['progress', 'core'],
|
|
263
263
|
},
|
|
264
|
+
// Surfaces
|
|
265
|
+
{
|
|
266
|
+
topic: 'system.surfaces.dashboard',
|
|
267
|
+
description: 'A dashboard announcement was published or removed. Delivery reaches ' +
|
|
268
|
+
'every authenticated subscriber — role targeting is display scoping, ' +
|
|
269
|
+
'so bodies must never carry secrets.',
|
|
270
|
+
category: 'surfaces',
|
|
271
|
+
payload_schema: objectSchema({
|
|
272
|
+
action: { type: 'string', description: 'created | deleted' },
|
|
273
|
+
announcement: {
|
|
274
|
+
type: 'object',
|
|
275
|
+
description: 'The announcement row (id, title, body, layout, roles, expires_at)',
|
|
276
|
+
},
|
|
277
|
+
}),
|
|
278
|
+
example_payload: {
|
|
279
|
+
action: 'created',
|
|
280
|
+
announcement: { id: 'ann-001', title: 'Maintenance tonight', layout: 'banner', roles: [] },
|
|
281
|
+
},
|
|
282
|
+
tags: ['surface', 'dashboard'],
|
|
283
|
+
},
|
|
264
284
|
];
|
|
265
285
|
// ── Seeding ─────────────────────────────────────────────────────────────────────
|
|
266
286
|
/**
|
|
@@ -29,5 +29,6 @@ __exportStar(require("./x-lt-labels"), exports);
|
|
|
29
29
|
__exportStar(require("./x-lt-query"), exports);
|
|
30
30
|
__exportStar(require("./x-lt-submit-guard"), exports);
|
|
31
31
|
__exportStar(require("./x-lt-show-if"), exports);
|
|
32
|
+
__exportStar(require("./x-lt-require-any"), exports);
|
|
32
33
|
__exportStar(require("./field-validator"), exports);
|
|
33
34
|
__exportStar(require("./validate-resolver-payload"), exports);
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
* - x-lt-require-all against the checklist items resolved from context
|
|
16
16
|
* - static + dynamic bounds (minimum/x-lt-minimum, lengths, patterns)
|
|
17
17
|
*
|
|
18
|
+
* Root-level x-lt-require-any groups run after the per-field pass: each group
|
|
19
|
+
* needs a value in at least one visible member (all-hidden groups are waived).
|
|
20
|
+
*
|
|
18
21
|
* The showIf/`resolver.*` domain is always the FLAT form representation, so a
|
|
19
22
|
* condition like `resolver.approved` reads the same on both sides.
|
|
20
23
|
*/
|
|
@@ -19,12 +19,16 @@ exports.validateResolverPayload = validateResolverPayload;
|
|
|
19
19
|
* - x-lt-require-all against the checklist items resolved from context
|
|
20
20
|
* - static + dynamic bounds (minimum/x-lt-minimum, lengths, patterns)
|
|
21
21
|
*
|
|
22
|
+
* Root-level x-lt-require-any groups run after the per-field pass: each group
|
|
23
|
+
* needs a value in at least one visible member (all-hidden groups are waived).
|
|
24
|
+
*
|
|
22
25
|
* The showIf/`resolver.*` domain is always the FLAT form representation, so a
|
|
23
26
|
* condition like `resolver.approved` reads the same on both sides.
|
|
24
27
|
*/
|
|
25
28
|
const field_validator_1 = require("./field-validator");
|
|
26
29
|
const x_lt_show_if_1 = require("./x-lt-show-if");
|
|
27
30
|
const x_lt_bind_1 = require("./x-lt-bind");
|
|
31
|
+
const x_lt_require_any_1 = require("./x-lt-require-any");
|
|
28
32
|
/**
|
|
29
33
|
* Validate FLAT form values against the form schema. This is the dashboard's
|
|
30
34
|
* entry point (the values the user edits, keyed by field name).
|
|
@@ -46,6 +50,21 @@ function validateResolverForm(schema, formValues, ctx) {
|
|
|
46
50
|
if (err)
|
|
47
51
|
errors.push({ field, message: err });
|
|
48
52
|
}
|
|
53
|
+
// Require-any groups: at least one VISIBLE member per group carries a value.
|
|
54
|
+
// A member hidden by showIf (or naming no property) can neither satisfy nor
|
|
55
|
+
// be demanded; an all-hidden group is waived.
|
|
56
|
+
for (const group of (0, x_lt_require_any_1.readRequireAnyGroups)(schema)) {
|
|
57
|
+
const visible = group.filter((k) => properties[k] && (0, x_lt_show_if_1.evaluateShowIf)(properties[k]['x-lt-showIf'], liveCtx));
|
|
58
|
+
if (visible.length === 0)
|
|
59
|
+
continue;
|
|
60
|
+
if (visible.some((k) => (0, x_lt_require_any_1.hasRequireAnyValue)(formValues[k])))
|
|
61
|
+
continue;
|
|
62
|
+
const titles = visible.map((k) => properties[k].title ?? k);
|
|
63
|
+
errors.push({
|
|
64
|
+
field: visible[0],
|
|
65
|
+
message: `Enter a value for at least one of: ${titles.join(', ')}`,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
49
68
|
return errors;
|
|
50
69
|
}
|
|
51
70
|
/**
|
|
@@ -10,19 +10,30 @@
|
|
|
10
10
|
* { "x-lt-labels": { "claim": "Claim and Submit", "submit": "Approve" } }
|
|
11
11
|
* ```
|
|
12
12
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* `cancel` additionally accepts `false` to remove the control entirely —
|
|
14
|
+
* for roles where cancelling is not part of the process ("Send to Service"
|
|
15
|
+
* flows escalate instead). The other targets are rename-only: hiding
|
|
16
|
+
* claim/submit/release would strand the footer.
|
|
17
|
+
*
|
|
18
|
+
* Only the five known targets are read; unknown keys and non-string values
|
|
19
|
+
* (except `cancel: false`) are ignored. Any target the schema omits keeps its
|
|
20
|
+
* default label, so a schema overrides just the controls it cares about.
|
|
16
21
|
*/
|
|
17
22
|
export declare const X_LT_LABELS = "x-lt-labels";
|
|
18
23
|
/** The footer controls a schema may rename. */
|
|
19
24
|
export declare const FOOTER_LABEL_TARGETS: readonly ["claim", "cancel", "submit", "escalate", "release"];
|
|
20
25
|
export type FooterLabelTarget = (typeof FOOTER_LABEL_TARGETS)[number];
|
|
21
|
-
/**
|
|
22
|
-
|
|
26
|
+
/**
|
|
27
|
+
* A partial map of target → override label. Absent targets keep their
|
|
28
|
+
* default. `cancel: false` removes the cancel control from the footer.
|
|
29
|
+
*/
|
|
30
|
+
export type FooterLabels = Partial<Record<Exclude<FooterLabelTarget, 'cancel'>, string>> & {
|
|
31
|
+
cancel?: string | false;
|
|
32
|
+
};
|
|
23
33
|
/**
|
|
24
34
|
* The schema's footer label overrides, or an empty map when none are declared.
|
|
25
35
|
* Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and
|
|
26
|
-
* blank or non-string values are dropped
|
|
36
|
+
* blank or non-string values are dropped — except `cancel: false`, which is
|
|
37
|
+
* preserved as the hide instruction.
|
|
27
38
|
*/
|
|
28
39
|
export declare function readFooterLabels(schema: Record<string, unknown> | null | undefined): FooterLabels;
|
|
@@ -11,9 +11,14 @@
|
|
|
11
11
|
* { "x-lt-labels": { "claim": "Claim and Submit", "submit": "Approve" } }
|
|
12
12
|
* ```
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* `cancel` additionally accepts `false` to remove the control entirely —
|
|
15
|
+
* for roles where cancelling is not part of the process ("Send to Service"
|
|
16
|
+
* flows escalate instead). The other targets are rename-only: hiding
|
|
17
|
+
* claim/submit/release would strand the footer.
|
|
18
|
+
*
|
|
19
|
+
* Only the five known targets are read; unknown keys and non-string values
|
|
20
|
+
* (except `cancel: false`) are ignored. Any target the schema omits keeps its
|
|
21
|
+
* default label, so a schema overrides just the controls it cares about.
|
|
17
22
|
*/
|
|
18
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
24
|
exports.FOOTER_LABEL_TARGETS = exports.X_LT_LABELS = void 0;
|
|
@@ -24,7 +29,8 @@ exports.FOOTER_LABEL_TARGETS = ['claim', 'cancel', 'submit', 'escalate', 'releas
|
|
|
24
29
|
/**
|
|
25
30
|
* The schema's footer label overrides, or an empty map when none are declared.
|
|
26
31
|
* Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and
|
|
27
|
-
* blank or non-string values are dropped
|
|
32
|
+
* blank or non-string values are dropped — except `cancel: false`, which is
|
|
33
|
+
* preserved as the hide instruction.
|
|
28
34
|
*/
|
|
29
35
|
function readFooterLabels(schema) {
|
|
30
36
|
const raw = schema?.[exports.X_LT_LABELS];
|
|
@@ -32,6 +38,8 @@ function readFooterLabels(schema) {
|
|
|
32
38
|
return {};
|
|
33
39
|
const source = raw;
|
|
34
40
|
const labels = {};
|
|
41
|
+
if (source.cancel === false)
|
|
42
|
+
labels.cancel = false;
|
|
35
43
|
for (const target of exports.FOOTER_LABEL_TARGETS) {
|
|
36
44
|
const value = source[target];
|
|
37
45
|
if (typeof value === 'string' && value.trim().length > 0) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x-lt-require-any — "at least one of this set" as a root-schema token. A
|
|
3
|
+
* form_schema declares groups of field names; a submission passes when every
|
|
4
|
+
* group has a value in at least one member. The canonical case: a Left
|
|
5
|
+
* quantity and a Right quantity where either satisfies, but blank-both fails.
|
|
6
|
+
*
|
|
7
|
+
* x-lt-require-any string[][] — e.g. [["left_quantity", "right_quantity"]]
|
|
8
|
+
*
|
|
9
|
+
* Visibility rules compose: a member hidden by its `x-lt-showIf` (or naming
|
|
10
|
+
* no schema property) can neither satisfy the group nor be demanded of the
|
|
11
|
+
* submitter, and a group whose members are ALL hidden is waived. `false` and
|
|
12
|
+
* `0` are answers; `''`, null, and undefined are not.
|
|
13
|
+
*/
|
|
14
|
+
export declare const X_LT_REQUIRE_ANY = "x-lt-require-any";
|
|
15
|
+
/**
|
|
16
|
+
* The schema's require-any groups. Malformed declarations (non-array token,
|
|
17
|
+
* non-array groups, non-string members) read as no groups — a bad token never
|
|
18
|
+
* bricks submission.
|
|
19
|
+
*/
|
|
20
|
+
export declare function readRequireAnyGroups(schema: Record<string, unknown> | null | undefined): string[][];
|
|
21
|
+
/** Present = an actual answer: `false` and `0` count; `''`/null/undefined do not. */
|
|
22
|
+
export declare function hasRequireAnyValue(value: unknown): boolean;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* x-lt-require-any — "at least one of this set" as a root-schema token. A
|
|
4
|
+
* form_schema declares groups of field names; a submission passes when every
|
|
5
|
+
* group has a value in at least one member. The canonical case: a Left
|
|
6
|
+
* quantity and a Right quantity where either satisfies, but blank-both fails.
|
|
7
|
+
*
|
|
8
|
+
* x-lt-require-any string[][] — e.g. [["left_quantity", "right_quantity"]]
|
|
9
|
+
*
|
|
10
|
+
* Visibility rules compose: a member hidden by its `x-lt-showIf` (or naming
|
|
11
|
+
* no schema property) can neither satisfy the group nor be demanded of the
|
|
12
|
+
* submitter, and a group whose members are ALL hidden is waived. `false` and
|
|
13
|
+
* `0` are answers; `''`, null, and undefined are not.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.X_LT_REQUIRE_ANY = void 0;
|
|
17
|
+
exports.readRequireAnyGroups = readRequireAnyGroups;
|
|
18
|
+
exports.hasRequireAnyValue = hasRequireAnyValue;
|
|
19
|
+
exports.X_LT_REQUIRE_ANY = 'x-lt-require-any';
|
|
20
|
+
/**
|
|
21
|
+
* The schema's require-any groups. Malformed declarations (non-array token,
|
|
22
|
+
* non-array groups, non-string members) read as no groups — a bad token never
|
|
23
|
+
* bricks submission.
|
|
24
|
+
*/
|
|
25
|
+
function readRequireAnyGroups(schema) {
|
|
26
|
+
const raw = schema?.[exports.X_LT_REQUIRE_ANY];
|
|
27
|
+
if (!Array.isArray(raw))
|
|
28
|
+
return [];
|
|
29
|
+
return raw
|
|
30
|
+
.filter((group) => Array.isArray(group))
|
|
31
|
+
.map((group) => group.filter((m) => typeof m === 'string' && m.length > 0))
|
|
32
|
+
.filter((group) => group.length > 0);
|
|
33
|
+
}
|
|
34
|
+
/** Present = an actual answer: `false` and `0` count; `''`/null/undefined do not. */
|
|
35
|
+
function hasRequireAnyValue(value) {
|
|
36
|
+
if (value === undefined || value === null)
|
|
37
|
+
return false;
|
|
38
|
+
if (typeof value === 'string')
|
|
39
|
+
return value.trim().length > 0;
|
|
40
|
+
return true;
|
|
41
|
+
}
|
package/build/start/workers.js
CHANGED
|
@@ -236,6 +236,7 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
236
236
|
resolver_schema: c.resolverSchema ?? null,
|
|
237
237
|
cron_schedule: c.cronSchedule ?? null,
|
|
238
238
|
execute_as: c.executeAs ?? null,
|
|
239
|
+
read_safe: c.readSafe ?? false,
|
|
239
240
|
};
|
|
240
241
|
try {
|
|
241
242
|
if ((0, apply_report_1.ownedByCode)(c.reset, configSource)) {
|
|
@@ -472,9 +473,8 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
472
473
|
(0, apply_report_1.logSurfaceReport)('agents', agentReport);
|
|
473
474
|
}
|
|
474
475
|
}
|
|
475
|
-
//
|
|
476
|
-
//
|
|
477
|
-
// unit; the scheme applies first so rule validation sees its kind.
|
|
476
|
+
// Declared scan schemes + rules (one ownership unit, one reset). The scheme
|
|
477
|
+
// applies first — rule validation reads its kind.
|
|
478
478
|
if (startConfig.scanSchemes?.length) {
|
|
479
479
|
const { seedScanScheme, seedScanRule, applyScanScheme, applyScanRule, listScanSchemes, listScanRules, } = await Promise.resolve().then(() => __importStar(require('../services/scan-code')));
|
|
480
480
|
const scanReport = (0, apply_report_1.newSurfaceReport)();
|
|
@@ -492,7 +492,6 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
492
492
|
(0, apply_report_1.recordOutcome)(scanReport, `scheme ${scheme.version}`, outcome);
|
|
493
493
|
if (outcome === 'applied')
|
|
494
494
|
logger_1.loggerRegistry.info(`[long-tail] scan scheme applied: ${scheme.version}`);
|
|
495
|
-
// Undeclared rules on a code-owned scheme are reported, never deleted.
|
|
496
495
|
const declaredCategories = new Set((rules ?? []).map((r) => r.category));
|
|
497
496
|
const existingRules = await listScanRules(scheme.version);
|
|
498
497
|
scanReport.orphans.push(...existingRules
|
|
@@ -514,7 +513,6 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
|
|
|
514
513
|
}
|
|
515
514
|
}
|
|
516
515
|
if (codeOwnedBoot && !startConfig.examples) {
|
|
517
|
-
// Schemes in the DB not declared here (demo seeds own theirs under examples).
|
|
518
516
|
const declaredVersions = new Set(startConfig.scanSchemes.map((s) => s.version));
|
|
519
517
|
scanReport.orphans.push(...(await listScanSchemes())
|
|
520
518
|
.map((s) => s.version)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard announcement tool — mirrors routes/announcements.ts. Publishing
|
|
3
|
+
* is a privileged surface (the HTTP route guards with requireRoleManager);
|
|
4
|
+
* targeting is display scoping only, so bodies must never carry secrets.
|
|
5
|
+
*/
|
|
6
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
7
|
+
export declare function registerAnnouncementTools(server: McpServer): void;
|
|
@@ -0,0 +1,69 @@
|
|
|
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.registerAnnouncementTools = registerAnnouncementTools;
|
|
37
|
+
const zod_1 = require("zod");
|
|
38
|
+
const api = __importStar(require("../../../api/announcements"));
|
|
39
|
+
const publishAnnouncementSchema = zod_1.z.object({
|
|
40
|
+
body: zod_1.z.string().describe('Markdown body — the only required field.'),
|
|
41
|
+
title: zod_1.z.string().optional().describe('Headline shown on the collapsed banner.'),
|
|
42
|
+
layout: zod_1.z.string().optional().describe("Presentation form. Default: 'banner'."),
|
|
43
|
+
roles: zod_1.z.array(zod_1.z.string()).optional().describe('Target roles; omitted = everyone.'),
|
|
44
|
+
expires_at: zod_1.z.string().optional().describe('ISO timestamp; omitted = 24 hours from now.'),
|
|
45
|
+
});
|
|
46
|
+
function registerAnnouncementTools(server) {
|
|
47
|
+
// mirrors POST /api/announcements
|
|
48
|
+
server.registerTool('publish_announcement', {
|
|
49
|
+
title: 'Publish Announcement',
|
|
50
|
+
description: 'Publish a dashboard announcement — a banner every targeted user sees ' +
|
|
51
|
+
'live and on their next load until it expires or is dismissed. Only ' +
|
|
52
|
+
'the body is required; title, layout, role targeting, and expiry ' +
|
|
53
|
+
'(default 24h) are optional. Bodies broadcast to all authenticated ' +
|
|
54
|
+
'subscribers — never include secrets.',
|
|
55
|
+
inputSchema: publishAnnouncementSchema,
|
|
56
|
+
}, async (args) => {
|
|
57
|
+
const result = await api.createAnnouncement({
|
|
58
|
+
body: args.body,
|
|
59
|
+
title: args.title,
|
|
60
|
+
layout: args.layout,
|
|
61
|
+
roles: args.roles,
|
|
62
|
+
expiresAt: args.expires_at,
|
|
63
|
+
}, { userId: 'lt-system', role: 'superadmin' });
|
|
64
|
+
if (result.error) {
|
|
65
|
+
return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
|
|
66
|
+
}
|
|
67
|
+
return { content: [{ type: 'text', text: JSON.stringify(result.data) }] };
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -60,7 +60,8 @@ const overview_1 = require("./overview");
|
|
|
60
60
|
const diagnostics_1 = require("./diagnostics");
|
|
61
61
|
const scan_codes_1 = require("./scan-codes");
|
|
62
62
|
const domain_context_1 = require("./domain-context");
|
|
63
|
-
const
|
|
63
|
+
const announcements_1 = require("./announcements");
|
|
64
|
+
const TOOL_COUNT = 105;
|
|
64
65
|
let server = null;
|
|
65
66
|
async function createAdminServer(options) {
|
|
66
67
|
if (server && !options?.fresh)
|
|
@@ -73,7 +74,7 @@ async function createAdminServer(options) {
|
|
|
73
74
|
(0, tasks_1.registerTaskTools)(instance); // 2 tools
|
|
74
75
|
(0, escalations_1.registerEscalationTools)(instance); // 20 tools (RO + RW single + metadata + bulk)
|
|
75
76
|
(0, workflow_config_1.registerWorkflowConfigTools)(instance); // 3 tools
|
|
76
|
-
(0, workflows_1.registerWorkflowTools)(instance); //
|
|
77
|
+
(0, workflows_1.registerWorkflowTools)(instance); // 5 tools (+ terminate_workflow, invoke_workflow_read_safe)
|
|
77
78
|
(0, mcp_servers_1.registerMcpServerTools)(instance); // 4 tools
|
|
78
79
|
(0, yaml_workflows_1.registerYamlWorkflowTools)(instance); // 5 tools
|
|
79
80
|
(0, users_1.registerUserTools)(instance); // 10 tools (users + roles + role schemas)
|
|
@@ -91,7 +92,8 @@ async function createAdminServer(options) {
|
|
|
91
92
|
(0, diagnostics_1.registerDiagnosticsTools)(instance); // 3 tools
|
|
92
93
|
(0, scan_codes_1.registerScanCodeTools)(instance); // 5 tools (scan schemes + rules + execute)
|
|
93
94
|
(0, domain_context_1.registerDomainContextTools)(instance); // 1 tool (get_domain_context)
|
|
94
|
-
//
|
|
95
|
+
(0, announcements_1.registerAnnouncementTools)(instance); // 1 tool (publish_announcement)
|
|
96
|
+
// Total: 105
|
|
95
97
|
logger_1.loggerRegistry.info(`[lt-mcp:admin] ${name} ready (${TOOL_COUNT} tools registered)`);
|
|
96
98
|
return instance;
|
|
97
99
|
}
|
|
@@ -109,6 +109,51 @@ function registerWorkflowTools(server) {
|
|
|
109
109
|
}],
|
|
110
110
|
};
|
|
111
111
|
});
|
|
112
|
+
// invoke_workflow gated to configs registered read-safe — the invocation
|
|
113
|
+
// surface exposed to read-scoped MCP callers. Any workflow may be attempted;
|
|
114
|
+
// one lacking the flag fails with a clear error.
|
|
115
|
+
server.registerTool('invoke_workflow_read_safe', {
|
|
116
|
+
title: 'Invoke Read-Safe Workflow',
|
|
117
|
+
description: 'Start a workflow registered read-safe (side-effect-free). Same contract ' +
|
|
118
|
+
'as invoke_workflow, gated to configs carrying read_safe=true — the ' +
|
|
119
|
+
'variant exposed to read-scoped MCP callers. A workflow without the ' +
|
|
120
|
+
'flag fails with a clear error.',
|
|
121
|
+
inputSchema: schemas_1.invokeWorkflowSchema,
|
|
122
|
+
}, async (args) => {
|
|
123
|
+
const config = await configService.getWorkflowConfig(args.workflow_type);
|
|
124
|
+
if (!config?.invocable) {
|
|
125
|
+
return {
|
|
126
|
+
content: [{
|
|
127
|
+
type: 'text',
|
|
128
|
+
text: JSON.stringify({ error: `workflow ${args.workflow_type} is not invocable` }),
|
|
129
|
+
}],
|
|
130
|
+
isError: true,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (!config.read_safe) {
|
|
134
|
+
return {
|
|
135
|
+
content: [{
|
|
136
|
+
type: 'text',
|
|
137
|
+
text: JSON.stringify({ error: `workflow ${args.workflow_type} is not registered read-safe` }),
|
|
138
|
+
}],
|
|
139
|
+
isError: true,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const result = await (0, workflow_invocation_1.invokeWorkflow)({
|
|
143
|
+
workflowType: args.workflow_type,
|
|
144
|
+
data: args.data,
|
|
145
|
+
metadata: args.metadata,
|
|
146
|
+
executeAs: args.execute_as,
|
|
147
|
+
options: args.options,
|
|
148
|
+
auth: { userId: 'lt-system', role: 'superadmin' },
|
|
149
|
+
});
|
|
150
|
+
return {
|
|
151
|
+
content: [{
|
|
152
|
+
type: 'text',
|
|
153
|
+
text: JSON.stringify({ workflow_id: result.workflowId, message: 'Workflow started' }),
|
|
154
|
+
}],
|
|
155
|
+
};
|
|
156
|
+
});
|
|
112
157
|
// mirrors GET /api/workflows/:workflowId/status + /result
|
|
113
158
|
server.registerTool('get_workflow_status', {
|
|
114
159
|
title: 'Get Workflow Status',
|