@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.
Files changed (248) hide show
  1. package/build/api/announcements.d.ts +22 -0
  2. package/build/api/announcements.js +96 -0
  3. package/build/api/escalations/claim.d.ts +4 -1
  4. package/build/api/escalations/claim.js +6 -2
  5. package/build/api/escalations/list.d.ts +8 -0
  6. package/build/api/escalations/list.js +14 -4
  7. package/build/api/index.d.ts +1 -0
  8. package/build/api/index.js +2 -1
  9. package/build/api/workflows/config.d.ts +1 -0
  10. package/build/api/workflows/config.js +1 -0
  11. package/build/api/workflows/discovery.js +1 -0
  12. package/build/index.js +4 -0
  13. package/build/lib/db/schemas/031_announcements.sql +30 -0
  14. package/build/lib/db/schemas/032_workflow_read_safe.sql +9 -0
  15. package/build/lib/events/publish.d.ts +15 -0
  16. package/build/lib/events/publish.js +22 -0
  17. package/build/routes/announcements.d.ts +2 -0
  18. package/build/routes/announcements.js +64 -0
  19. package/build/routes/escalations/list.js +2 -0
  20. package/build/routes/escalations/single.js +3 -1
  21. package/build/routes/index.js +2 -0
  22. package/build/sdk/index.d.ts +1 -0
  23. package/build/services/announcement/index.d.ts +30 -0
  24. package/build/services/announcement/index.js +29 -0
  25. package/build/services/announcement/sql.d.ts +8 -0
  26. package/build/services/announcement/sql.js +24 -0
  27. package/build/services/config/cache.js +1 -0
  28. package/build/services/config/read.js +2 -0
  29. package/build/services/config/sql.d.ts +2 -2
  30. package/build/services/config/sql.js +6 -5
  31. package/build/services/config/write.js +5 -0
  32. package/build/services/escalation/crud.d.ts +10 -2
  33. package/build/services/escalation/crud.js +20 -12
  34. package/build/services/topics/system-topics.js +20 -0
  35. package/build/shared/form-validation/index.d.ts +1 -0
  36. package/build/shared/form-validation/index.js +1 -0
  37. package/build/shared/form-validation/validate-resolver-payload.d.ts +3 -0
  38. package/build/shared/form-validation/validate-resolver-payload.js +19 -0
  39. package/build/shared/form-validation/x-lt-labels.d.ts +17 -6
  40. package/build/shared/form-validation/x-lt-labels.js +12 -4
  41. package/build/shared/form-validation/x-lt-require-any.d.ts +22 -0
  42. package/build/shared/form-validation/x-lt-require-any.js +41 -0
  43. package/build/start/workers.js +3 -5
  44. package/build/system/mcp-servers/admin/announcements.d.ts +7 -0
  45. package/build/system/mcp-servers/admin/announcements.js +69 -0
  46. package/build/system/mcp-servers/admin/index.js +5 -3
  47. package/build/system/mcp-servers/admin/workflows.js +45 -0
  48. package/build/system/seed/tool-manifests-admin.d.ts +357 -0
  49. package/build/system/seed/tool-manifests-admin.js +3 -0
  50. package/build/tsconfig.tsbuildinfo +1 -1
  51. package/build/types/config.d.ts +8 -0
  52. package/build/types/startup.d.ts +5 -0
  53. package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js → AdminDashboard-C4h1R-lz.js} +2 -2
  54. package/dashboard/dist/assets/{AdminDashboard-D2unnS2b.js.map → AdminDashboard-C4h1R-lz.js.map} +1 -1
  55. package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js → AgentConfigPage-EWC8VQ7R.js} +2 -2
  56. package/dashboard/dist/assets/{AgentConfigPage-CBkf403g.js.map → AgentConfigPage-EWC8VQ7R.js.map} +1 -1
  57. package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js → AgentDetailPage-DaLfa80d.js} +2 -2
  58. package/dashboard/dist/assets/{AgentDetailPage-CAIU3yzo.js.map → AgentDetailPage-DaLfa80d.js.map} +1 -1
  59. package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js → AgentsPage-islj_zrh.js} +2 -2
  60. package/dashboard/dist/assets/{AgentsPage-qP9fWMyT.js.map → AgentsPage-islj_zrh.js.map} +1 -1
  61. package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js +2 -0
  62. package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js.map +1 -0
  63. package/dashboard/dist/assets/{BotPicker-BN-MKITV.js → BotPicker-CnX8xfka.js} +2 -2
  64. package/dashboard/dist/assets/{BotPicker-BN-MKITV.js.map → BotPicker-CnX8xfka.js.map} +1 -1
  65. package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js → CapabilitiesPage-DK7wGMFt.js} +2 -2
  66. package/dashboard/dist/assets/{CapabilitiesPage-CJfmWokN.js.map → CapabilitiesPage-DK7wGMFt.js.map} +1 -1
  67. package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js → CollapsibleSection-WqEpMTyx.js} +2 -2
  68. package/dashboard/dist/assets/{CollapsibleSection-BvMHlHyt.js.map → CollapsibleSection-WqEpMTyx.js.map} +1 -1
  69. package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js +2 -0
  70. package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js.map +1 -0
  71. package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js → CredentialsPage-CfT60FiU.js} +2 -2
  72. package/dashboard/dist/assets/{CredentialsPage-2TvvRwGJ.js.map → CredentialsPage-CfT60FiU.js.map} +1 -1
  73. package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js → CronLabel-ds7dLz6S.js} +2 -2
  74. package/dashboard/dist/assets/{CronLabel-HxmsDSnV.js.map → CronLabel-ds7dLz6S.js.map} +1 -1
  75. package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js +2 -0
  76. package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js.map +1 -0
  77. package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js → ElapsedCell-DRQhFky_.js} +2 -2
  78. package/dashboard/dist/assets/{ElapsedCell-BkRu9Xpd.js.map → ElapsedCell-DRQhFky_.js.map} +1 -1
  79. package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js → EntityTimelinePanel-nCgWdmpK.js} +2 -2
  80. package/dashboard/dist/assets/{EntityTimelinePanel--E6hLMCM.js.map → EntityTimelinePanel-nCgWdmpK.js.map} +1 -1
  81. package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js → EscalationListSchemaPage-DBCnPMG9.js} +2 -2
  82. package/dashboard/dist/assets/{EscalationListSchemaPage-CdFtqEEX.js.map → EscalationListSchemaPage-DBCnPMG9.js.map} +1 -1
  83. package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js → EscalationSchemaPage-DfzRTqhV.js} +2 -2
  84. package/dashboard/dist/assets/{EscalationSchemaPage-BsjS2axz.js.map → EscalationSchemaPage-DfzRTqhV.js.map} +1 -1
  85. package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js → EscalationsOverview-CWd2Ivso.js} +2 -2
  86. package/dashboard/dist/assets/{EscalationsOverview-FL-xteVc.js.map → EscalationsOverview-CWd2Ivso.js.map} +1 -1
  87. package/dashboard/dist/assets/{EventTable-BOcgZ78i.js → EventTable-Dm9Fbab1.js} +2 -2
  88. package/dashboard/dist/assets/{EventTable-BOcgZ78i.js.map → EventTable-Dm9Fbab1.js.map} +1 -1
  89. package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js → FilterBar-DR4cJvTB.js} +2 -2
  90. package/dashboard/dist/assets/{FilterBar-DfCiCmm-.js.map → FilterBar-DR4cJvTB.js.map} +1 -1
  91. package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js → GraphInvokePage-DQt64Ru0.js} +2 -2
  92. package/dashboard/dist/assets/{GraphInvokePage-DfVeiN-8.js.map → GraphInvokePage-DQt64Ru0.js.map} +1 -1
  93. package/dashboard/dist/assets/{HomePage-C2IhF9WB.js → HomePage-D7qNiqtw.js} +2 -2
  94. package/dashboard/dist/assets/{HomePage-C2IhF9WB.js.map → HomePage-D7qNiqtw.js.map} +1 -1
  95. package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js → ListToolbar-BdZkpRMo.js} +2 -2
  96. package/dashboard/dist/assets/{ListToolbar-DA0PTOl5.js.map → ListToolbar-BdZkpRMo.js.map} +1 -1
  97. package/dashboard/dist/assets/{McpOverview-DstPch5M.js → McpOverview-DHAEYY1b.js} +2 -2
  98. package/dashboard/dist/assets/{McpOverview-DstPch5M.js.map → McpOverview-DHAEYY1b.js.map} +1 -1
  99. package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js → McpQueryDetailPage-BfGhRO_c.js} +2 -2
  100. package/dashboard/dist/assets/{McpQueryDetailPage-Csv0PKE0.js.map → McpQueryDetailPage-BfGhRO_c.js.map} +1 -1
  101. package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js → McpQueryPage-3EXLX1Eq.js} +2 -2
  102. package/dashboard/dist/assets/{McpQueryPage-DxmqCkly.js.map → McpQueryPage-3EXLX1Eq.js.map} +1 -1
  103. package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js → McpRunDetailPage-DHI0F65P.js} +2 -2
  104. package/dashboard/dist/assets/{McpRunDetailPage-CcJOlp_B.js.map → McpRunDetailPage-DHI0F65P.js.map} +1 -1
  105. package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js → McpRunsPage-C6-KpYCY.js} +2 -2
  106. package/dashboard/dist/assets/{McpRunsPage-BZCR043j.js.map → McpRunsPage-C6-KpYCY.js.map} +1 -1
  107. package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js → OperationsPage-BNW7uris.js} +2 -2
  108. package/dashboard/dist/assets/{OperationsPage-DMsPXITh.js.map → OperationsPage-BNW7uris.js.map} +1 -1
  109. package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js → OperatorDashboard-DLp9gCTA.js} +2 -2
  110. package/dashboard/dist/assets/{OperatorDashboard-DSloftQ5.js.map → OperatorDashboard-DLp9gCTA.js.map} +1 -1
  111. package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js → PersonaDetailPage-DFv4Zwmq.js} +2 -2
  112. package/dashboard/dist/assets/{PersonaDetailPage-jDVRCLbU.js.map → PersonaDetailPage-DFv4Zwmq.js.map} +1 -1
  113. package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js → PersonasPage-C52o87Zv.js} +2 -2
  114. package/dashboard/dist/assets/{PersonasPage-DnDDwXoy.js.map → PersonasPage-C52o87Zv.js.map} +1 -1
  115. package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js → ProcessDetailPage-CKCxXogl.js} +2 -2
  116. package/dashboard/dist/assets/{ProcessDetailPage-CfAUU6q2.js.map → ProcessDetailPage-CKCxXogl.js.map} +1 -1
  117. package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js → ProcessesListPage-D1bxIy7-.js} +2 -2
  118. package/dashboard/dist/assets/{ProcessesListPage-CnAXzaVv.js.map → ProcessesListPage-D1bxIy7-.js.map} +1 -1
  119. package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js → RoleDetailPage-_MrbOGW_.js} +2 -2
  120. package/dashboard/dist/assets/{RoleDetailPage-Dg1p6Qz_.js.map → RoleDetailPage-_MrbOGW_.js.map} +1 -1
  121. package/dashboard/dist/assets/{RolesPage-DeRVQux8.js → RolesPage-ZVCkB4iF.js} +2 -2
  122. package/dashboard/dist/assets/{RolesPage-DeRVQux8.js.map → RolesPage-ZVCkB4iF.js.map} +1 -1
  123. package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js → RunAsSelector-BAqa1Tya.js} +2 -2
  124. package/dashboard/dist/assets/{RunAsSelector-BFNqQGuG.js.map → RunAsSelector-BAqa1Tya.js.map} +1 -1
  125. package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js → ScanCodesPage-b7WkFiy-.js} +2 -2
  126. package/dashboard/dist/assets/{ScanCodesPage-D0GOdk5m.js.map → ScanCodesPage-b7WkFiy-.js.map} +1 -1
  127. package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js +2 -0
  128. package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js.map +1 -0
  129. package/dashboard/dist/assets/ScanStationPage-CPC9CdCR.js +2 -0
  130. package/dashboard/dist/assets/ScanStationPage-CPC9CdCR.js.map +1 -0
  131. package/dashboard/dist/assets/{StickyPagination-B99hVu95.js → StickyPagination-CgSzarlP.js} +2 -2
  132. package/dashboard/dist/assets/{StickyPagination-B99hVu95.js.map → StickyPagination-CgSzarlP.js.map} +1 -1
  133. package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js → StreamMessageDetail-B4E3S5RB.js} +2 -2
  134. package/dashboard/dist/assets/{StreamMessageDetail-DcDGISrv.js.map → StreamMessageDetail-B4E3S5RB.js.map} +1 -1
  135. package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js → SwimlaneTimeline-BkcjucMZ.js} +2 -2
  136. package/dashboard/dist/assets/{SwimlaneTimeline-BP3mSQAg.js.map → SwimlaneTimeline-BkcjucMZ.js.map} +1 -1
  137. package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js → TaskDetailPage-D7e8x2gX.js} +2 -2
  138. package/dashboard/dist/assets/{TaskDetailPage-_XWLJzt-.js.map → TaskDetailPage-D7e8x2gX.js.map} +1 -1
  139. package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js → TasksListPage-B4mxP9Ey.js} +2 -2
  140. package/dashboard/dist/assets/{TasksListPage-iGriKiO2.js.map → TasksListPage-B4mxP9Ey.js.map} +1 -1
  141. package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js → TimeAgo-D6sbYsUO.js} +2 -2
  142. package/dashboard/dist/assets/{TimeAgo-BO33VeFl.js.map → TimeAgo-D6sbYsUO.js.map} +1 -1
  143. package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js → TimestampCell-DFDf3NAT.js} +2 -2
  144. package/dashboard/dist/assets/{TimestampCell-KAjX7w35.js.map → TimestampCell-DFDf3NAT.js.map} +1 -1
  145. package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js → ToolTestPanel-DbWw0-Le.js} +2 -2
  146. package/dashboard/dist/assets/{ToolTestPanel-BchG2yC6.js.map → ToolTestPanel-DbWw0-Le.js.map} +1 -1
  147. package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js → TopicDetailPage-C6CPcvuO.js} +2 -2
  148. package/dashboard/dist/assets/{TopicDetailPage-BaK8H0o1.js.map → TopicDetailPage-C6CPcvuO.js.map} +1 -1
  149. package/dashboard/dist/assets/{TopicsPage-DEyvm669.js → TopicsPage-C8_XpeT2.js} +2 -2
  150. package/dashboard/dist/assets/{TopicsPage-DEyvm669.js.map → TopicsPage-C8_XpeT2.js.map} +1 -1
  151. package/dashboard/dist/assets/{UserName-BV6SKI9P.js → UserName-CIoJvf_e.js} +2 -2
  152. package/dashboard/dist/assets/{UserName-BV6SKI9P.js.map → UserName-CIoJvf_e.js.map} +1 -1
  153. package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js → WorkflowExecutionPage-Bq3kSkRr.js} +2 -2
  154. package/dashboard/dist/assets/{WorkflowExecutionPage-1sKoEFNC.js.map → WorkflowExecutionPage-Bq3kSkRr.js.map} +1 -1
  155. package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js → WorkflowsDashboard-y2L_zwnf.js} +2 -2
  156. package/dashboard/dist/assets/{WorkflowsDashboard-YTHDZZOD.js.map → WorkflowsDashboard-y2L_zwnf.js.map} +1 -1
  157. package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js → WorkflowsOverview-ChE1Mm3P.js} +2 -2
  158. package/dashboard/dist/assets/{WorkflowsOverview-ucXPLTtm.js.map → WorkflowsOverview-ChE1Mm3P.js.map} +1 -1
  159. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js → YamlWorkflowDetailPage-D0aY_inb.js} +2 -2
  160. package/dashboard/dist/assets/{YamlWorkflowDetailPage-C_RTZKqZ.js.map → YamlWorkflowDetailPage-D0aY_inb.js.map} +1 -1
  161. package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js → YamlWorkflowsPage-DJ0JitPs.js} +2 -2
  162. package/dashboard/dist/assets/{YamlWorkflowsPage-Usid3w2W.js.map → YamlWorkflowsPage-DJ0JitPs.js.map} +1 -1
  163. package/dashboard/dist/assets/{agents-BTDsRK8e.js → agents-Bu5Ly_ER.js} +2 -2
  164. package/dashboard/dist/assets/{agents-BTDsRK8e.js.map → agents-Bu5Ly_ER.js.map} +1 -1
  165. package/dashboard/dist/assets/{bots-DxLrfdfr.js → bots-Cb14wZ1Y.js} +2 -2
  166. package/dashboard/dist/assets/{bots-DxLrfdfr.js.map → bots-Cb14wZ1Y.js.map} +1 -1
  167. package/dashboard/dist/assets/{capabilities-DbTmeW-S.js → capabilities-DeHLk9JJ.js} +2 -2
  168. package/dashboard/dist/assets/{capabilities-DbTmeW-S.js.map → capabilities-DeHLk9JJ.js.map} +1 -1
  169. package/dashboard/dist/assets/{controlplane-CEBntAL4.js → controlplane-YBZ3SbA6.js} +2 -2
  170. package/dashboard/dist/assets/{controlplane-CEBntAL4.js.map → controlplane-YBZ3SbA6.js.map} +1 -1
  171. package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js → escalation-columns-CA9DQlhA.js} +2 -2
  172. package/dashboard/dist/assets/{escalation-columns-Carqdwoh.js.map → escalation-columns-CA9DQlhA.js.map} +1 -1
  173. package/dashboard/dist/assets/{index-BhapT-Vl.js → index-B0qNe7Ux.js} +2 -2
  174. package/dashboard/dist/assets/{index-BhapT-Vl.js.map → index-B0qNe7Ux.js.map} +1 -1
  175. package/dashboard/dist/assets/{index-kes8V4Xw.js → index-B4Nea96C.js} +2 -2
  176. package/dashboard/dist/assets/{index-kes8V4Xw.js.map → index-B4Nea96C.js.map} +1 -1
  177. package/dashboard/dist/assets/{index-cFHoANSG.css → index-B5jxf81r.css} +1 -1
  178. package/dashboard/dist/assets/{index-Bqm4zu46.js → index-B7fE-rND.js} +2 -2
  179. package/dashboard/dist/assets/{index-Bqm4zu46.js.map → index-B7fE-rND.js.map} +1 -1
  180. package/dashboard/dist/assets/{index-nwLh3CK2.js → index-BAKroiNw.js} +2 -2
  181. package/dashboard/dist/assets/{index-nwLh3CK2.js.map → index-BAKroiNw.js.map} +1 -1
  182. package/dashboard/dist/assets/{index-CgIBjZta.js → index-BRmgxeZM.js} +2 -2
  183. package/dashboard/dist/assets/{index-CgIBjZta.js.map → index-BRmgxeZM.js.map} +1 -1
  184. package/dashboard/dist/assets/{index-De8iV1y2.js → index-BaDimDGQ.js} +2 -2
  185. package/dashboard/dist/assets/{index-De8iV1y2.js.map → index-BaDimDGQ.js.map} +1 -1
  186. package/dashboard/dist/assets/{index-CDkg6iOE.js → index-BhurEB5s.js} +2 -2
  187. package/dashboard/dist/assets/{index-CDkg6iOE.js.map → index-BhurEB5s.js.map} +1 -1
  188. package/dashboard/dist/assets/{index-B2hz0pUh.js → index-CQriisJy.js} +2 -2
  189. package/dashboard/dist/assets/{index-B2hz0pUh.js.map → index-CQriisJy.js.map} +1 -1
  190. package/dashboard/dist/assets/{index-B9m7fA3M.js → index-D5MSJsiW.js} +2 -2
  191. package/dashboard/dist/assets/{index-B9m7fA3M.js.map → index-D5MSJsiW.js.map} +1 -1
  192. package/dashboard/dist/assets/{index-DBXm49S6.js → index-Ntul2ZC1.js} +30 -29
  193. package/dashboard/dist/assets/index-Ntul2ZC1.js.map +1 -0
  194. package/dashboard/dist/assets/{index-C0hSttF5.js → index-YUv7aNb4.js} +2 -2
  195. package/dashboard/dist/assets/{index-C0hSttF5.js.map → index-YUv7aNb4.js.map} +1 -1
  196. package/dashboard/dist/assets/{index-CVBBkW8V.js → index-chMUPSOd.js} +2 -2
  197. package/dashboard/dist/assets/{index-CVBBkW8V.js.map → index-chMUPSOd.js.map} +1 -1
  198. package/dashboard/dist/assets/index-uWUJXqGS.js +3 -0
  199. package/dashboard/dist/assets/index-uWUJXqGS.js.map +1 -0
  200. package/dashboard/dist/assets/{knowledge-oFYAanUp.js → knowledge-B1HqYuB2.js} +2 -2
  201. package/dashboard/dist/assets/{knowledge-oFYAanUp.js.map → knowledge-B1HqYuB2.js.map} +1 -1
  202. package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js → mcp-dhihqJpH.js} +2 -2
  203. package/dashboard/dist/assets/{mcp-C9Kw4Ow8.js.map → mcp-dhihqJpH.js.map} +1 -1
  204. package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js → mcp-query-B_gkB7JK.js} +2 -2
  205. package/dashboard/dist/assets/{mcp-query-BwzpZ91Z.js.map → mcp-query-B_gkB7JK.js.map} +1 -1
  206. package/dashboard/dist/assets/metadata-display-DHjqWkLG.js +2 -0
  207. package/dashboard/dist/assets/metadata-display-DHjqWkLG.js.map +1 -0
  208. package/dashboard/dist/assets/{personas-D5ehmtRb.js → personas-Bw_OlfI6.js} +2 -2
  209. package/dashboard/dist/assets/{personas-D5ehmtRb.js.map → personas-Bw_OlfI6.js.map} +1 -1
  210. package/dashboard/dist/assets/{pipelines-xgPKGEdD.js → pipelines-BYwn0LXY.js} +2 -2
  211. package/dashboard/dist/assets/{pipelines-xgPKGEdD.js.map → pipelines-BYwn0LXY.js.map} +1 -1
  212. package/dashboard/dist/assets/{tasks-CLyrl-MU.js → tasks-t6bPmJ7P.js} +2 -2
  213. package/dashboard/dist/assets/{tasks-CLyrl-MU.js.map → tasks-t6bPmJ7P.js.map} +1 -1
  214. package/dashboard/dist/assets/{topics-B_gO7CQ0.js → topics-Bgo9xw80.js} +2 -2
  215. package/dashboard/dist/assets/{topics-B_gO7CQ0.js.map → topics-Bgo9xw80.js.map} +1 -1
  216. package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js → useEventHooks-BJbMbg_h.js} +2 -2
  217. package/dashboard/dist/assets/{useEventHooks-BdWYm63U.js.map → useEventHooks-BJbMbg_h.js.map} +1 -1
  218. package/dashboard/dist/assets/{useNamespace-C238M4Qn.js → useNamespace-CaXJuSFG.js} +2 -2
  219. package/dashboard/dist/assets/{useNamespace-C238M4Qn.js.map → useNamespace-CaXJuSFG.js.map} +1 -1
  220. package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js → useYamlActivityEvents-B47LQrDk.js} +2 -2
  221. package/dashboard/dist/assets/{useYamlActivityEvents-B2ryEK4S.js.map → useYamlActivityEvents-B47LQrDk.js.map} +1 -1
  222. package/dashboard/dist/assets/{users-BFaTe6Mt.js → users-D0jvzUqW.js} +2 -2
  223. package/dashboard/dist/assets/{users-BFaTe6Mt.js.map → users-D0jvzUqW.js.map} +1 -1
  224. package/dashboard/dist/assets/{workflows-DXz7tZxp.js → workflows-DRoZRrMH.js} +2 -2
  225. package/dashboard/dist/assets/{workflows-DXz7tZxp.js.map → workflows-DRoZRrMH.js.map} +1 -1
  226. package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js → yaml-workflows-BdhYyIef.js} +2 -2
  227. package/dashboard/dist/assets/{yaml-workflows-u3xuRAnS.js.map → yaml-workflows-BdhYyIef.js.map} +1 -1
  228. package/dashboard/dist/index.html +2 -2
  229. package/docs/api/http/escalations.md +5 -1
  230. package/docs/dashboard.md +15 -0
  231. package/docs/hitl/iframe.md +56 -6
  232. package/docs/hitl/x-lt-footer.md +16 -4
  233. package/docs/hitl/x-lt-validation.md +23 -0
  234. package/docs/mcp.md +2 -0
  235. package/package.json +1 -1
  236. package/dashboard/dist/assets/AvailableEscalationsPage-DvWaiafI.js +0 -2
  237. package/dashboard/dist/assets/AvailableEscalationsPage-DvWaiafI.js.map +0 -1
  238. package/dashboard/dist/assets/CountdownTimer-By4rbMDN.js +0 -2
  239. package/dashboard/dist/assets/CountdownTimer-By4rbMDN.js.map +0 -1
  240. package/dashboard/dist/assets/CustomDurationPicker-8Ao-1pKA.js +0 -2
  241. package/dashboard/dist/assets/CustomDurationPicker-8Ao-1pKA.js.map +0 -1
  242. package/dashboard/dist/assets/ScanSchemeDetailPage-vFqoe_P4.js +0 -2
  243. package/dashboard/dist/assets/ScanSchemeDetailPage-vFqoe_P4.js.map +0 -1
  244. package/dashboard/dist/assets/ScanStationPage-DH1ynTX9.js +0 -2
  245. package/dashboard/dist/assets/ScanStationPage-DH1ynTX9.js.map +0 -1
  246. package/dashboard/dist/assets/index-DBXm49S6.js.map +0 -1
  247. package/dashboard/dist/assets/index-DsgjFRvA.js +0 -3
  248. 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 };
@@ -18,3 +18,4 @@ export * as workflowSets from './workflow-sets';
18
18
  export * as dba from './dba';
19
19
  export * as namespaces from './namespaces';
20
20
  export * as maintenance from './maintenance';
21
+ export * as announcements from './announcements';
@@ -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"));
@@ -55,6 +55,7 @@ export declare function upsertWorkflowConfig(input: {
55
55
  envelope_schema?: any;
56
56
  resolver_schema?: any;
57
57
  cron_schedule?: string | null;
58
+ read_safe?: boolean;
58
59
  }): Promise<LTApiResult>;
59
60
  /**
60
61
  * Delete a workflow configuration.
@@ -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
@@ -167,6 +167,10 @@ async function main() {
167
167
  },
168
168
  },
169
169
  examples: true,
170
+ features: {
171
+ // The examples ship the full scan demo (schemes 10/11); surface it.
172
+ scanCodes: true,
173
+ },
170
174
  mcp: {
171
175
  server: { enabled: true },
172
176
  },
@@ -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,2 @@
1
+ declare const router: import("express-serve-static-core").Router;
2
+ export default router;
@@ -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
  /**
@@ -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"));
@@ -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 *`;
@@ -19,6 +19,7 @@ async function loadAllConfigs() {
19
19
  resolverSchema: c.resolver_schema ?? null,
20
20
  cronSchedule: c.cron_schedule ?? null,
21
21
  executeAs: c.execute_as ?? null,
22
+ readSafe: c.read_safe ?? false,
22
23
  });
23
24
  }
24
25
  return map;
@@ -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
  }