@hotmeshio/long-tail 0.10.14 → 0.11.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.
Files changed (332) hide show
  1. package/build/api/escalations/analytics.d.ts +6 -0
  2. package/build/api/escalations/analytics.js +123 -0
  3. package/build/api/escalations/index.d.ts +1 -0
  4. package/build/api/escalations/index.js +4 -1
  5. package/build/api/roles.d.ts +4 -0
  6. package/build/api/roles.js +8 -0
  7. package/build/api/scan-codes/choice.d.ts +11 -0
  8. package/build/api/scan-codes/choice.js +136 -0
  9. package/build/api/scan-codes/context.d.ts +24 -0
  10. package/build/api/scan-codes/context.js +86 -0
  11. package/build/api/scan-codes/execute.d.ts +1 -0
  12. package/build/api/scan-codes/execute.js +49 -244
  13. package/build/api/scan-codes/identity.d.ts +18 -0
  14. package/build/api/scan-codes/identity.js +116 -0
  15. package/build/api/scan-codes/index.d.ts +2 -0
  16. package/build/api/scan-codes/index.js +6 -1
  17. package/build/api/scan-codes/locate.d.ts +14 -0
  18. package/build/api/scan-codes/locate.js +127 -0
  19. package/build/api/scan-codes/present.d.ts +9 -0
  20. package/build/api/scan-codes/present.js +59 -0
  21. package/build/api/scan-codes/verbs.d.ts +15 -0
  22. package/build/api/scan-codes/verbs.js +205 -0
  23. package/build/bin/ltc.js +33 -0
  24. package/build/lib/cli/commands/escalations.d.ts +31 -0
  25. package/build/lib/cli/commands/escalations.js +88 -0
  26. package/build/lib/db/schemas/028_role_entity_facet.sql +18 -0
  27. package/build/lib/db/schemas/029_scan_scheme_kind.sql +31 -0
  28. package/build/modules/config.d.ts +5 -0
  29. package/build/modules/config.js +12 -0
  30. package/build/routes/escalations/acting.d.ts +12 -0
  31. package/build/routes/escalations/acting.js +25 -0
  32. package/build/routes/escalations/analytics.d.ts +8 -0
  33. package/build/routes/escalations/analytics.js +63 -0
  34. package/build/routes/escalations/index.js +3 -0
  35. package/build/routes/escalations/resolve.js +8 -1
  36. package/build/routes/escalations/single.js +13 -4
  37. package/build/routes/roles.js +1 -1
  38. package/build/routes/scan-codes.js +28 -2
  39. package/build/scripts/ortho-populate.js +14 -0
  40. package/build/scripts/printer-cycle.d.ts +25 -0
  41. package/build/scripts/printer-cycle.js +169 -0
  42. package/build/scripts/twin-farm.js +19 -5
  43. package/build/sdk/index.d.ts +2 -0
  44. package/build/sdk/index.js +3 -0
  45. package/build/services/escalation/aggregate-sql.d.ts +36 -0
  46. package/build/services/escalation/aggregate-sql.js +253 -0
  47. package/build/services/escalation/aggregate-validate.d.ts +57 -0
  48. package/build/services/escalation/aggregate-validate.js +218 -0
  49. package/build/services/escalation/aggregates.d.ts +26 -0
  50. package/build/services/escalation/aggregates.js +204 -0
  51. package/build/services/escalation/client.js +57 -21
  52. package/build/services/escalation/facet-sql.js +17 -0
  53. package/build/services/escalation/index.d.ts +2 -0
  54. package/build/services/escalation/index.js +8 -1
  55. package/build/services/escalation/metrics-cache.d.ts +18 -0
  56. package/build/services/escalation/metrics-cache.js +47 -1
  57. package/build/services/escalation/queries.js +2 -0
  58. package/build/services/iam/acting-identity.d.ts +16 -0
  59. package/build/services/iam/acting-identity.js +60 -0
  60. package/build/services/role/index.js +2 -0
  61. package/build/services/role/sql.d.ts +10 -2
  62. package/build/services/role/sql.js +14 -1
  63. package/build/services/role/types.d.ts +16 -0
  64. package/build/services/scan-code/read.js +4 -0
  65. package/build/services/scan-code/sql.d.ts +4 -4
  66. package/build/services/scan-code/sql.js +14 -8
  67. package/build/services/scan-code/validate.d.ts +2 -0
  68. package/build/services/scan-code/validate.js +86 -0
  69. package/build/services/scan-code/write.d.ts +4 -0
  70. package/build/services/scan-code/write.js +16 -2
  71. package/build/services/user/crud.d.ts +6 -0
  72. package/build/services/user/crud.js +16 -0
  73. package/build/services/user/index.d.ts +1 -1
  74. package/build/services/user/index.js +2 -1
  75. package/build/services/user/sql.d.ts +8 -0
  76. package/build/services/user/sql.js +9 -1
  77. package/build/system/mcp-servers/admin/escalations.js +34 -0
  78. package/build/system/mcp-servers/admin/scan-codes.js +17 -1
  79. package/build/system/mcp-servers/admin/schemas.d.ts +643 -25
  80. package/build/system/mcp-servers/admin/schemas.js +127 -19
  81. package/build/system/mcp-servers/admin/users.js +3 -1
  82. package/build/system/mcp-servers/human-queue-schemas.d.ts +2 -2
  83. package/build/system/seed/tool-manifests-admin.d.ts +2283 -0
  84. package/build/system/seed/tool-manifests-admin.js +8 -5
  85. package/build/tsconfig.tsbuildinfo +1 -1
  86. package/build/types/analytics.d.ts +154 -0
  87. package/build/types/analytics.js +14 -0
  88. package/build/types/facets.d.ts +13 -0
  89. package/build/types/index.d.ts +5 -2
  90. package/build/types/index.js +5 -1
  91. package/build/types/scan-choice.d.ts +49 -0
  92. package/build/types/scan-choice.js +9 -0
  93. package/build/types/scan-code.d.ts +72 -1
  94. package/build/types/scan-code.js +30 -1
  95. package/dashboard/dist/assets/{AdminDashboard-Chg69wlx.js → AdminDashboard-DJ3LJQ09.js} +2 -2
  96. package/dashboard/dist/assets/{AdminDashboard-Chg69wlx.js.map → AdminDashboard-DJ3LJQ09.js.map} +1 -1
  97. package/dashboard/dist/assets/{AgentConfigPage-DRTFwbfC.js → AgentConfigPage-BMMvaD0z.js} +2 -2
  98. package/dashboard/dist/assets/{AgentConfigPage-DRTFwbfC.js.map → AgentConfigPage-BMMvaD0z.js.map} +1 -1
  99. package/dashboard/dist/assets/{AgentDetailPage-JKByfFIi.js → AgentDetailPage-C6wfsnRe.js} +3 -3
  100. package/dashboard/dist/assets/{AgentDetailPage-JKByfFIi.js.map → AgentDetailPage-C6wfsnRe.js.map} +1 -1
  101. package/dashboard/dist/assets/{AgentsPage-BlgEmKhA.js → AgentsPage-Cwqka7nE.js} +2 -2
  102. package/dashboard/dist/assets/{AgentsPage-BlgEmKhA.js.map → AgentsPage-Cwqka7nE.js.map} +1 -1
  103. package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js +2 -0
  104. package/dashboard/dist/assets/AvailableEscalationsPage-CVlG_AVC.js.map +1 -0
  105. package/dashboard/dist/assets/{BotPicker-CCVcz4Cq.js → BotPicker-BBkJBXZB.js} +2 -2
  106. package/dashboard/dist/assets/{BotPicker-CCVcz4Cq.js.map → BotPicker-BBkJBXZB.js.map} +1 -1
  107. package/dashboard/dist/assets/{CapabilitiesPage-Czi9jUwD.js → CapabilitiesPage-wxmE4917.js} +2 -2
  108. package/dashboard/dist/assets/{CapabilitiesPage-Czi9jUwD.js.map → CapabilitiesPage-wxmE4917.js.map} +1 -1
  109. package/dashboard/dist/assets/{CollapsibleSection-8YE965QX.js → CollapsibleSection-B3FsrHwH.js} +2 -2
  110. package/dashboard/dist/assets/{CollapsibleSection-8YE965QX.js.map → CollapsibleSection-B3FsrHwH.js.map} +1 -1
  111. package/dashboard/dist/assets/{CountdownTimer-Bxvq3D7j.js → CountdownTimer-B3nCqJdC.js} +2 -2
  112. package/dashboard/dist/assets/{CountdownTimer-Bxvq3D7j.js.map → CountdownTimer-B3nCqJdC.js.map} +1 -1
  113. package/dashboard/dist/assets/{CredentialsPage-Bn7_SX6-.js → CredentialsPage-Bv875IHe.js} +2 -2
  114. package/dashboard/dist/assets/{CredentialsPage-Bn7_SX6-.js.map → CredentialsPage-Bv875IHe.js.map} +1 -1
  115. package/dashboard/dist/assets/{CronLabel-Bn4mX_Yn.js → CronLabel-CSzjWuwj.js} +2 -2
  116. package/dashboard/dist/assets/{CronLabel-Bn4mX_Yn.js.map → CronLabel-CSzjWuwj.js.map} +1 -1
  117. package/dashboard/dist/assets/{CustomDurationPicker-pMcrFyW6.js → CustomDurationPicker-CCpqf3e4.js} +2 -2
  118. package/dashboard/dist/assets/{CustomDurationPicker-pMcrFyW6.js.map → CustomDurationPicker-CCpqf3e4.js.map} +1 -1
  119. package/dashboard/dist/assets/{DropZone-zCEGjjk-.js → DropZone-CJkk-U3o.js} +2 -2
  120. package/dashboard/dist/assets/{DropZone-zCEGjjk-.js.map → DropZone-CJkk-U3o.js.map} +1 -1
  121. package/dashboard/dist/assets/{ElapsedCell-BGO7IXEg.js → ElapsedCell-WV6pUaKo.js} +2 -2
  122. package/dashboard/dist/assets/{ElapsedCell-BGO7IXEg.js.map → ElapsedCell-WV6pUaKo.js.map} +1 -1
  123. package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js +2 -0
  124. package/dashboard/dist/assets/EntityTimelinePanel-DrL86Yrf.js.map +1 -0
  125. package/dashboard/dist/assets/{EscalationListSchemaPage-CFDxbd50.js → EscalationListSchemaPage-CTQCALw4.js} +3 -3
  126. package/dashboard/dist/assets/{EscalationListSchemaPage-CFDxbd50.js.map → EscalationListSchemaPage-CTQCALw4.js.map} +1 -1
  127. package/dashboard/dist/assets/{EscalationSchemaPage-DnXPnDkz.js → EscalationSchemaPage-D_UgP0pv.js} +3 -3
  128. package/dashboard/dist/assets/{EscalationSchemaPage-DnXPnDkz.js.map → EscalationSchemaPage-D_UgP0pv.js.map} +1 -1
  129. package/dashboard/dist/assets/{EscalationsOverview-BZMVXrkK.js → EscalationsOverview-DuIUyxr0.js} +2 -2
  130. package/dashboard/dist/assets/{EscalationsOverview-BZMVXrkK.js.map → EscalationsOverview-DuIUyxr0.js.map} +1 -1
  131. package/dashboard/dist/assets/{EventTable-Bfi-f8as.js → EventTable-BV6unphX.js} +2 -2
  132. package/dashboard/dist/assets/{EventTable-Bfi-f8as.js.map → EventTable-BV6unphX.js.map} +1 -1
  133. package/dashboard/dist/assets/FilterBar-DYFgzXNB.js +2 -0
  134. package/dashboard/dist/assets/{FilterBar-Do7yR4xM.js.map → FilterBar-DYFgzXNB.js.map} +1 -1
  135. package/dashboard/dist/assets/{GraphInvokePage-d1ie4T7f.js → GraphInvokePage-BGHVUipJ.js} +2 -2
  136. package/dashboard/dist/assets/{GraphInvokePage-d1ie4T7f.js.map → GraphInvokePage-BGHVUipJ.js.map} +1 -1
  137. package/dashboard/dist/assets/HomePage-B-S2cK3E.js +2 -0
  138. package/dashboard/dist/assets/{HomePage-BEeodImU.js.map → HomePage-B-S2cK3E.js.map} +1 -1
  139. package/dashboard/dist/assets/ListToolbar-Bl7F3A28.js +2 -0
  140. package/dashboard/dist/assets/{ListToolbar-CLtw-1QN.js.map → ListToolbar-Bl7F3A28.js.map} +1 -1
  141. package/dashboard/dist/assets/{McpOverview-DIsy9TB3.js → McpOverview-_T9IsCD_.js} +2 -2
  142. package/dashboard/dist/assets/{McpOverview-DIsy9TB3.js.map → McpOverview-_T9IsCD_.js.map} +1 -1
  143. package/dashboard/dist/assets/{McpQueryDetailPage-6PomdsyD.js → McpQueryDetailPage-DtsVqKPw.js} +2 -2
  144. package/dashboard/dist/assets/{McpQueryDetailPage-6PomdsyD.js.map → McpQueryDetailPage-DtsVqKPw.js.map} +1 -1
  145. package/dashboard/dist/assets/{McpQueryPage-YMdQCXm9.js → McpQueryPage-DX5u-1bx.js} +2 -2
  146. package/dashboard/dist/assets/{McpQueryPage-YMdQCXm9.js.map → McpQueryPage-DX5u-1bx.js.map} +1 -1
  147. package/dashboard/dist/assets/{McpRunDetailPage-DsD1Gm2o.js → McpRunDetailPage-BhcqqtYS.js} +2 -2
  148. package/dashboard/dist/assets/{McpRunDetailPage-DsD1Gm2o.js.map → McpRunDetailPage-BhcqqtYS.js.map} +1 -1
  149. package/dashboard/dist/assets/{McpRunsPage--a5Jgb33.js → McpRunsPage-L-1y8wnX.js} +2 -2
  150. package/dashboard/dist/assets/{McpRunsPage--a5Jgb33.js.map → McpRunsPage-L-1y8wnX.js.map} +1 -1
  151. package/dashboard/dist/assets/{NamespacePill-wV6L4VW1.js → NamespacePill-in1SLd0W.js} +2 -2
  152. package/dashboard/dist/assets/{NamespacePill-wV6L4VW1.js.map → NamespacePill-in1SLd0W.js.map} +1 -1
  153. package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js +3 -0
  154. package/dashboard/dist/assets/OperationsPage-i8KcDpKo.js.map +1 -0
  155. package/dashboard/dist/assets/OperatorDashboard-CIbDzOlh.js +2 -0
  156. package/dashboard/dist/assets/{OperatorDashboard-CkLfbxEh.js.map → OperatorDashboard-CIbDzOlh.js.map} +1 -1
  157. package/dashboard/dist/assets/{PageHeader-BtIr6r-8.js → PageHeader-BJgWMZtw.js} +2 -2
  158. package/dashboard/dist/assets/{PageHeader-BtIr6r-8.js.map → PageHeader-BJgWMZtw.js.map} +1 -1
  159. package/dashboard/dist/assets/{PageHeaderWithStats-C2sGqFQG.js → PageHeaderWithStats-Ccio4vyG.js} +2 -2
  160. package/dashboard/dist/assets/{PageHeaderWithStats-C2sGqFQG.js.map → PageHeaderWithStats-Ccio4vyG.js.map} +1 -1
  161. package/dashboard/dist/assets/{PersonaDetailPage-CCmOgKQb.js → PersonaDetailPage-BOaf0TW1.js} +2 -2
  162. package/dashboard/dist/assets/{PersonaDetailPage-CCmOgKQb.js.map → PersonaDetailPage-BOaf0TW1.js.map} +1 -1
  163. package/dashboard/dist/assets/{PersonasPage-BJkSuDTN.js → PersonasPage-DSdRb90f.js} +2 -2
  164. package/dashboard/dist/assets/{PersonasPage-BJkSuDTN.js.map → PersonasPage-DSdRb90f.js.map} +1 -1
  165. package/dashboard/dist/assets/{ProcessDetailPage-DT9BlJXK.js → ProcessDetailPage-DN9NqfeP.js} +2 -2
  166. package/dashboard/dist/assets/{ProcessDetailPage-DT9BlJXK.js.map → ProcessDetailPage-DN9NqfeP.js.map} +1 -1
  167. package/dashboard/dist/assets/{ProcessesListPage-DgSGzTDT.js → ProcessesListPage-CfQEWaD4.js} +2 -2
  168. package/dashboard/dist/assets/{ProcessesListPage-DgSGzTDT.js.map → ProcessesListPage-CfQEWaD4.js.map} +1 -1
  169. package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js +8 -0
  170. package/dashboard/dist/assets/RoleDetailPage-BC5HL7ls.js.map +1 -0
  171. package/dashboard/dist/assets/{RolePill-BBYjhAPj.js → RolePill-BNAP-uK6.js} +2 -2
  172. package/dashboard/dist/assets/{RolePill-BBYjhAPj.js.map → RolePill-BNAP-uK6.js.map} +1 -1
  173. package/dashboard/dist/assets/RolesPage-DCnW0VmD.js +2 -0
  174. package/dashboard/dist/assets/RolesPage-DCnW0VmD.js.map +1 -0
  175. package/dashboard/dist/assets/{RunAsSelector-CateuvcC.js → RunAsSelector-twbuX7fB.js} +2 -2
  176. package/dashboard/dist/assets/{RunAsSelector-CateuvcC.js.map → RunAsSelector-twbuX7fB.js.map} +1 -1
  177. package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js +2 -0
  178. package/dashboard/dist/assets/ScanCodesPage-CPNg6K--.js.map +1 -0
  179. package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js +2 -0
  180. package/dashboard/dist/assets/ScanSchemeDetailPage-DyLmCamO.js.map +1 -0
  181. package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js +2 -0
  182. package/dashboard/dist/assets/ScanStationPage-DoZccU5B.js.map +1 -0
  183. package/dashboard/dist/assets/{ScopeBadge-xs2Nhjy4.js → ScopeBadge-BG7KkZ8Q.js} +2 -2
  184. package/dashboard/dist/assets/{ScopeBadge-xs2Nhjy4.js.map → ScopeBadge-BG7KkZ8Q.js.map} +1 -1
  185. package/dashboard/dist/assets/{StickyPagination-Cg-QdYWL.js → StickyPagination-DIeYMPPd.js} +2 -2
  186. package/dashboard/dist/assets/{StickyPagination-Cg-QdYWL.js.map → StickyPagination-DIeYMPPd.js.map} +1 -1
  187. package/dashboard/dist/assets/{StreamMessageDetail-DEeuh4_-.js → StreamMessageDetail-gU4CUeQI.js} +2 -2
  188. package/dashboard/dist/assets/{StreamMessageDetail-DEeuh4_-.js.map → StreamMessageDetail-gU4CUeQI.js.map} +1 -1
  189. package/dashboard/dist/assets/{SwimlaneTimeline-DMY0jL2F.js → SwimlaneTimeline-Br-nBA4l.js} +2 -2
  190. package/dashboard/dist/assets/{SwimlaneTimeline-DMY0jL2F.js.map → SwimlaneTimeline-Br-nBA4l.js.map} +1 -1
  191. package/dashboard/dist/assets/{TagInput-BMmiV-MD.js → TagInput-CvM5n6ww.js} +2 -2
  192. package/dashboard/dist/assets/{TagInput-BMmiV-MD.js.map → TagInput-CvM5n6ww.js.map} +1 -1
  193. package/dashboard/dist/assets/{TaskDetailPage-CPbkIvfF.js → TaskDetailPage-_9cr_R0u.js} +2 -2
  194. package/dashboard/dist/assets/{TaskDetailPage-CPbkIvfF.js.map → TaskDetailPage-_9cr_R0u.js.map} +1 -1
  195. package/dashboard/dist/assets/{TaskQueuePill-DLgYaw1x.js → TaskQueuePill-D4JPHXOq.js} +2 -2
  196. package/dashboard/dist/assets/{TaskQueuePill-DLgYaw1x.js.map → TaskQueuePill-D4JPHXOq.js.map} +1 -1
  197. package/dashboard/dist/assets/{TasksListPage-CtHudKhQ.js → TasksListPage-DVENC9Jp.js} +2 -2
  198. package/dashboard/dist/assets/{TasksListPage-CtHudKhQ.js.map → TasksListPage-DVENC9Jp.js.map} +1 -1
  199. package/dashboard/dist/assets/{TimeAgo-BdHOizWg.js → TimeAgo-C9yYnOui.js} +2 -2
  200. package/dashboard/dist/assets/{TimeAgo-BdHOizWg.js.map → TimeAgo-C9yYnOui.js.map} +1 -1
  201. package/dashboard/dist/assets/{TimestampCell-FVukzKRe.js → TimestampCell-DoB8cYgw.js} +2 -2
  202. package/dashboard/dist/assets/{TimestampCell-FVukzKRe.js.map → TimestampCell-DoB8cYgw.js.map} +1 -1
  203. package/dashboard/dist/assets/{ToolPill-BvS53hxP.js → ToolPill-BUjbC-Tj.js} +2 -2
  204. package/dashboard/dist/assets/{ToolPill-BvS53hxP.js.map → ToolPill-BUjbC-Tj.js.map} +1 -1
  205. package/dashboard/dist/assets/{ToolTestPanel-HN0OCYTL.js → ToolTestPanel-CBtsIP8K.js} +2 -2
  206. package/dashboard/dist/assets/{ToolTestPanel-HN0OCYTL.js.map → ToolTestPanel-CBtsIP8K.js.map} +1 -1
  207. package/dashboard/dist/assets/{TopicDetailPage-DHdSpN61.js → TopicDetailPage-mR4Jaz83.js} +2 -2
  208. package/dashboard/dist/assets/{TopicDetailPage-DHdSpN61.js.map → TopicDetailPage-mR4Jaz83.js.map} +1 -1
  209. package/dashboard/dist/assets/TopicsPage-CP7HFxIC.js +2 -0
  210. package/dashboard/dist/assets/{TopicsPage-Clr6Tl5P.js.map → TopicsPage-CP7HFxIC.js.map} +1 -1
  211. package/dashboard/dist/assets/{UserName-BUVYyIAS.js → UserName-BnLF6yhz.js} +2 -2
  212. package/dashboard/dist/assets/{UserName-BUVYyIAS.js.map → UserName-BnLF6yhz.js.map} +1 -1
  213. package/dashboard/dist/assets/{WorkflowExecutionPage-kncWFfe5.js → WorkflowExecutionPage-xL956RZi.js} +2 -2
  214. package/dashboard/dist/assets/{WorkflowExecutionPage-kncWFfe5.js.map → WorkflowExecutionPage-xL956RZi.js.map} +1 -1
  215. package/dashboard/dist/assets/{WorkflowPill-BPC_Dc_I.js → WorkflowPill-tXU0-eXu.js} +2 -2
  216. package/dashboard/dist/assets/{WorkflowPill-BPC_Dc_I.js.map → WorkflowPill-tXU0-eXu.js.map} +1 -1
  217. package/dashboard/dist/assets/{WorkflowsDashboard-4ypPDGKx.js → WorkflowsDashboard-B-u7zFKM.js} +2 -2
  218. package/dashboard/dist/assets/{WorkflowsDashboard-4ypPDGKx.js.map → WorkflowsDashboard-B-u7zFKM.js.map} +1 -1
  219. package/dashboard/dist/assets/{WorkflowsOverview-CeQlZkkd.js → WorkflowsOverview-CqZVarK-.js} +2 -2
  220. package/dashboard/dist/assets/{WorkflowsOverview-CeQlZkkd.js.map → WorkflowsOverview-CqZVarK-.js.map} +1 -1
  221. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DLAlEzwT.js → YamlWorkflowDetailPage-DiFLavW0.js} +2 -2
  222. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DLAlEzwT.js.map → YamlWorkflowDetailPage-DiFLavW0.js.map} +1 -1
  223. package/dashboard/dist/assets/{YamlWorkflowsPage-DQhenKFT.js → YamlWorkflowsPage-BuQM6uZA.js} +2 -2
  224. package/dashboard/dist/assets/{YamlWorkflowsPage-DQhenKFT.js.map → YamlWorkflowsPage-BuQM6uZA.js.map} +1 -1
  225. package/dashboard/dist/assets/{agents-s3feet3W.js → agents-DU9GPovp.js} +2 -2
  226. package/dashboard/dist/assets/{agents-s3feet3W.js.map → agents-DU9GPovp.js.map} +1 -1
  227. package/dashboard/dist/assets/{bots-CkSd2rn9.js → bots-Cy-Hmg7w.js} +2 -2
  228. package/dashboard/dist/assets/{bots-CkSd2rn9.js.map → bots-Cy-Hmg7w.js.map} +1 -1
  229. package/dashboard/dist/assets/{capabilities-DA_r09tM.js → capabilities-sSJJqrp-.js} +2 -2
  230. package/dashboard/dist/assets/{capabilities-DA_r09tM.js.map → capabilities-sSJJqrp-.js.map} +1 -1
  231. package/dashboard/dist/assets/{controlplane-C9c25q21.js → controlplane-TVCjDHQ-.js} +2 -2
  232. package/dashboard/dist/assets/{controlplane-C9c25q21.js.map → controlplane-TVCjDHQ-.js.map} +1 -1
  233. package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js +2 -0
  234. package/dashboard/dist/assets/escalation-columns-BpkjKYGd.js.map +1 -0
  235. package/dashboard/dist/assets/index-5TblaCXQ.css +1 -0
  236. package/dashboard/dist/assets/{index-WxE3ONia.js → index-7BP6FaCZ.js} +2 -2
  237. package/dashboard/dist/assets/{index-WxE3ONia.js.map → index-7BP6FaCZ.js.map} +1 -1
  238. package/dashboard/dist/assets/{index-C7ABSOU2.js → index-B7IaBPBg.js} +4 -4
  239. package/dashboard/dist/assets/{index-C7ABSOU2.js.map → index-B7IaBPBg.js.map} +1 -1
  240. package/dashboard/dist/assets/{index-BU5FFAJo.js → index-BE0phFw0.js} +2 -2
  241. package/dashboard/dist/assets/{index-BU5FFAJo.js.map → index-BE0phFw0.js.map} +1 -1
  242. package/dashboard/dist/assets/{index-C-MmR-jf.js → index-BYNN9N1T.js} +2 -2
  243. package/dashboard/dist/assets/{index-C-MmR-jf.js.map → index-BYNN9N1T.js.map} +1 -1
  244. package/dashboard/dist/assets/{index-S13oPvuS.js → index-CLPVqbVY.js} +2 -2
  245. package/dashboard/dist/assets/{index-S13oPvuS.js.map → index-CLPVqbVY.js.map} +1 -1
  246. package/dashboard/dist/assets/{index-Cw9poaez.js → index-Cfv86_L9.js} +2 -2
  247. package/dashboard/dist/assets/{index-Cw9poaez.js.map → index-Cfv86_L9.js.map} +1 -1
  248. package/dashboard/dist/assets/{index-Bo5TtX9l.js → index-CtwbQ_-m.js} +2 -2
  249. package/dashboard/dist/assets/{index-Bo5TtX9l.js.map → index-CtwbQ_-m.js.map} +1 -1
  250. package/dashboard/dist/assets/index-DOai950R.js +3 -0
  251. package/dashboard/dist/assets/index-DOai950R.js.map +1 -0
  252. package/dashboard/dist/assets/{index-Cmxzk4ay.js → index-DTtHNC-D.js} +2 -2
  253. package/dashboard/dist/assets/{index-Cmxzk4ay.js.map → index-DTtHNC-D.js.map} +1 -1
  254. package/dashboard/dist/assets/{index--7Vdkzwd.js → index-DsWnVyVN.js} +2 -2
  255. package/dashboard/dist/assets/{index--7Vdkzwd.js.map → index-DsWnVyVN.js.map} +1 -1
  256. package/dashboard/dist/assets/{index-DvoMXQqO.js → index-Dy-MMYti.js} +2 -2
  257. package/dashboard/dist/assets/{index-DvoMXQqO.js.map → index-Dy-MMYti.js.map} +1 -1
  258. package/dashboard/dist/assets/index-errgQT5x.js +65 -0
  259. package/dashboard/dist/assets/index-errgQT5x.js.map +1 -0
  260. package/dashboard/dist/assets/{index-BIcYbDVf.js → index-fgBDhnI6.js} +2 -2
  261. package/dashboard/dist/assets/{index-BIcYbDVf.js.map → index-fgBDhnI6.js.map} +1 -1
  262. package/dashboard/dist/assets/{knowledge-Bpln0zy_.js → knowledge-arh4NfmL.js} +2 -2
  263. package/dashboard/dist/assets/{knowledge-Bpln0zy_.js.map → knowledge-arh4NfmL.js.map} +1 -1
  264. package/dashboard/dist/assets/{mcp-BqDq3RZH.js → mcp-QGf5jHCo.js} +2 -2
  265. package/dashboard/dist/assets/{mcp-BqDq3RZH.js.map → mcp-QGf5jHCo.js.map} +1 -1
  266. package/dashboard/dist/assets/{mcp-query-DGue75R6.js → mcp-query-BEJN1nMZ.js} +2 -2
  267. package/dashboard/dist/assets/{mcp-query-DGue75R6.js.map → mcp-query-BEJN1nMZ.js.map} +1 -1
  268. package/dashboard/dist/assets/{personas-B8z_sTiJ.js → personas-DYtw1COf.js} +2 -2
  269. package/dashboard/dist/assets/{personas-B8z_sTiJ.js.map → personas-DYtw1COf.js.map} +1 -1
  270. package/dashboard/dist/assets/{pipelines-DYgNd9nB.js → pipelines-Byi6PnbE.js} +2 -2
  271. package/dashboard/dist/assets/{pipelines-DYgNd9nB.js.map → pipelines-Byi6PnbE.js.map} +1 -1
  272. package/dashboard/dist/assets/{tasks-CJdjjhgO.js → tasks-D0SQdENz.js} +2 -2
  273. package/dashboard/dist/assets/{tasks-CJdjjhgO.js.map → tasks-D0SQdENz.js.map} +1 -1
  274. package/dashboard/dist/assets/{topics-DPrL8Dtq.js → topics-DgDv5ZXP.js} +2 -2
  275. package/dashboard/dist/assets/{topics-DPrL8Dtq.js.map → topics-DgDv5ZXP.js.map} +1 -1
  276. package/dashboard/dist/assets/useEventHooks-DZaYzE7s.js +2 -0
  277. package/dashboard/dist/assets/{useEventHooks-DXCgDgiu.js.map → useEventHooks-DZaYzE7s.js.map} +1 -1
  278. package/dashboard/dist/assets/{useNamespace-DnFZfy7N.js → useNamespace-C1OqiNXN.js} +2 -2
  279. package/dashboard/dist/assets/{useNamespace-DnFZfy7N.js.map → useNamespace-C1OqiNXN.js.map} +1 -1
  280. package/dashboard/dist/assets/{useYamlActivityEvents-kx5CLENv.js → useYamlActivityEvents-CkmXDm-Z.js} +2 -2
  281. package/dashboard/dist/assets/{useYamlActivityEvents-kx5CLENv.js.map → useYamlActivityEvents-CkmXDm-Z.js.map} +1 -1
  282. package/dashboard/dist/assets/{users-DKng7vAG.js → users-D4DCFPH1.js} +2 -2
  283. package/dashboard/dist/assets/{users-DKng7vAG.js.map → users-D4DCFPH1.js.map} +1 -1
  284. package/dashboard/dist/assets/{vendor-icons-CN-bAo9U.js → vendor-icons-BxuyFxH2.js} +152 -137
  285. package/dashboard/dist/assets/vendor-icons-BxuyFxH2.js.map +1 -0
  286. package/dashboard/dist/assets/{workflows-C4V0rMkM.js → workflows-qyc0ku_5.js} +2 -2
  287. package/dashboard/dist/assets/{workflows-C4V0rMkM.js.map → workflows-qyc0ku_5.js.map} +1 -1
  288. package/dashboard/dist/assets/{yaml-workflows-D3PAiJ9d.js → yaml-workflows-DWFww9Xn.js} +2 -2
  289. package/dashboard/dist/assets/{yaml-workflows-D3PAiJ9d.js.map → yaml-workflows-DWFww9Xn.js.map} +1 -1
  290. package/dashboard/dist/index.html +3 -3
  291. package/docs/api/http/escalations.md +133 -0
  292. package/docs/api/http/roles.md +6 -0
  293. package/docs/api/mcp/admin.md +53 -0
  294. package/docs/api/sdk/escalations.md +58 -0
  295. package/docs/cli.md +11 -0
  296. package/docs/dashboard.md +22 -20
  297. package/docs/data.md +12 -4
  298. package/docs/escalation-analytics.md +251 -0
  299. package/docs/hitl/roles.md +1 -1
  300. package/docs/hitl/x-lt-footer.md +1 -2
  301. package/docs/hitl-guide.md +3 -3
  302. package/docs/iam.md +12 -0
  303. package/docs/operations.md +17 -0
  304. package/docs/scan-codes.md +112 -0
  305. package/docs/sdk.md +1 -1
  306. package/package.json +2 -1
  307. package/dashboard/dist/assets/AvailableEscalationsPage-C_7y692Q.js +0 -2
  308. package/dashboard/dist/assets/AvailableEscalationsPage-C_7y692Q.js.map +0 -1
  309. package/dashboard/dist/assets/FilterBar-Do7yR4xM.js +0 -2
  310. package/dashboard/dist/assets/HomePage-BEeodImU.js +0 -2
  311. package/dashboard/dist/assets/ListToolbar-CLtw-1QN.js +0 -2
  312. package/dashboard/dist/assets/OperationsPage-B2v9k3DT.js +0 -2
  313. package/dashboard/dist/assets/OperationsPage-B2v9k3DT.js.map +0 -1
  314. package/dashboard/dist/assets/OperatorDashboard-CkLfbxEh.js +0 -2
  315. package/dashboard/dist/assets/RoleDetailPage-DMphTvro.js +0 -8
  316. package/dashboard/dist/assets/RoleDetailPage-DMphTvro.js.map +0 -1
  317. package/dashboard/dist/assets/RolesPage-gi_kaot1.js +0 -2
  318. package/dashboard/dist/assets/RolesPage-gi_kaot1.js.map +0 -1
  319. package/dashboard/dist/assets/ScanCodesPage-CQ8RxMug.js +0 -2
  320. package/dashboard/dist/assets/ScanCodesPage-CQ8RxMug.js.map +0 -1
  321. package/dashboard/dist/assets/ScanSchemeDetailPage-puSbuxcV.js +0 -2
  322. package/dashboard/dist/assets/ScanSchemeDetailPage-puSbuxcV.js.map +0 -1
  323. package/dashboard/dist/assets/TopicsPage-Clr6Tl5P.js +0 -2
  324. package/dashboard/dist/assets/escalation-columns-Cp3UrT48.js +0 -2
  325. package/dashboard/dist/assets/escalation-columns-Cp3UrT48.js.map +0 -1
  326. package/dashboard/dist/assets/index--DG-qQBT.js +0 -65
  327. package/dashboard/dist/assets/index--DG-qQBT.js.map +0 -1
  328. package/dashboard/dist/assets/index-DEbY57_c.js +0 -3
  329. package/dashboard/dist/assets/index-DEbY57_c.js.map +0 -1
  330. package/dashboard/dist/assets/index-DnV6LSeY.css +0 -1
  331. package/dashboard/dist/assets/useEventHooks-DXCgDgiu.js +0 -2
  332. package/dashboard/dist/assets/vendor-icons-CN-bAo9U.js.map +0 -1
@@ -84,6 +84,14 @@ exports.DELETE_ROLE = `
84
84
  * ops_home_default ($35 = provided sentinel, $36 = value) is single-holder:
85
85
  * setting it true clears the flag on every other role in the same statement
86
86
  * (the home_clear CTE touches only OTHER rows, so the two UPDATEs never meet).
87
+ *
88
+ * entity_facet ($37 = provided sentinel, $38 = value) is unversioned config:
89
+ * the metadata key naming the entity that moves through this role (powers the
90
+ * analytics surfaces — entity counts, per-entity dwell, timelines).
91
+ *
92
+ * entity_state_source ($39 = provided sentinel, $40 = value) is unversioned
93
+ * config: 'role' | 'subtype' — how this role names its contribution to the
94
+ * entity's state space (the station itself, or its subtypes).
87
95
  */
88
96
  exports.UPDATE_ROLE_METADATA = `
89
97
  WITH home_clear AS (
@@ -104,6 +112,9 @@ exports.UPDATE_ROLE_METADATA = `
104
112
  priority_threshold_minutes
105
113
  = CASE WHEN $22::boolean THEN $23::numeric ELSE priority_threshold_minutes END,
106
114
  priority_facet = CASE WHEN $24::boolean THEN $25 ELSE priority_facet END,
115
+ entity_facet = CASE WHEN $37::boolean THEN $38 ELSE entity_facet END,
116
+ entity_state_source
117
+ = CASE WHEN $39::boolean THEN COALESCE($40, 'role') ELSE entity_state_source END,
107
118
  list_schema = CASE WHEN $29::boolean THEN $30::jsonb ELSE list_schema END,
108
119
  default_pins = CASE WHEN $31::boolean THEN $32::jsonb ELSE default_pins END,
109
120
  enforce_schema = CASE WHEN $33::boolean THEN COALESCE($34::boolean, false) ELSE enforce_schema END,
@@ -121,7 +132,7 @@ exports.UPDATE_ROLE_METADATA = `
121
132
  RETURNING
122
133
  role, title, description, form_schema, metadata_schema, properties,
123
134
  ops_visible, ops_home_default, parent_role, sla_minutes, target_per_hour, worker_count,
124
- priority_threshold_minutes, priority_facet,
135
+ priority_threshold_minutes, priority_facet, entity_facet, entity_state_source,
125
136
  current_schema_version, list_schema, current_list_schema_version,
126
137
  default_pins, enforce_schema
127
138
  ), snapshot AS (
@@ -262,6 +273,8 @@ exports.LIST_ROLES_WITH_DETAILS = `
262
273
  r.worker_count,
263
274
  r.priority_threshold_minutes,
264
275
  r.priority_facet,
276
+ r.entity_facet,
277
+ r.entity_state_source,
265
278
  r.current_schema_version,
266
279
  r.list_schema,
267
280
  r.current_list_schema_version,
@@ -46,6 +46,19 @@ export interface RoleDetail {
46
46
  * an unparseable value are not counted.
47
47
  */
48
48
  priority_facet: string | null;
49
+ /**
50
+ * lt_escalations.metadata key identifying the ENTITY that moves through
51
+ * this role (e.g. serialNumber, orderId). Powers the analytics surfaces —
52
+ * distinct-entity counts, per-entity dwell, entity timelines. Null = the
53
+ * role has no entity notion.
54
+ */
55
+ entity_facet: string | null;
56
+ /**
57
+ * How this role names its contribution to the entity's state space:
58
+ * 'role' (the station itself is the state) or 'subtype' (the role's
59
+ * subtypes are its states). Only meaningful while entity_facet is set.
60
+ */
61
+ entity_state_source: 'role' | 'subtype';
49
62
  /**
50
63
  * Version of the live form_schema. Advances whenever the form (or
51
64
  * metadata_schema) changes; each version is snapshotted in lt_role_schemas so
@@ -149,6 +162,9 @@ export interface UpdateRoleInput {
149
162
  worker_count?: number | null;
150
163
  priority_threshold_minutes?: number | null;
151
164
  priority_facet?: string | null;
165
+ entity_facet?: string | null;
166
+ /** 'role' | 'subtype' — null resets to the 'role' default. */
167
+ entity_state_source?: 'role' | 'subtype' | null;
152
168
  /** Turn server-side resolver schema validation on/off for this role. */
153
169
  enforce_schema?: boolean;
154
170
  /**
@@ -15,6 +15,9 @@ function mapScheme(row) {
15
15
  encoding: row.encoding,
16
16
  delimiter: row.delimiter,
17
17
  target_length: row.target_length ?? null,
18
+ kind: row.kind ?? 'action',
19
+ grant_ttl_seconds: row.grant_ttl_seconds ?? null,
20
+ grant_max_uses: row.grant_max_uses ?? 0,
18
21
  enabled: row.enabled,
19
22
  created_at: row.created_at,
20
23
  updated_at: row.updated_at,
@@ -27,6 +30,7 @@ function mapRule(row) {
27
30
  name: row.name,
28
31
  steps: row.steps ?? [],
29
32
  fallback: row.fallback ?? {},
33
+ notPrimed: row.not_primed ?? {},
30
34
  enabled: row.enabled,
31
35
  created_at: row.created_at,
32
36
  updated_at: row.updated_at,
@@ -2,9 +2,9 @@ export declare const LIST_SCHEMES = "SELECT * FROM lt_config_scan_schemes ORDER
2
2
  export declare const GET_SCHEME = "SELECT * FROM lt_config_scan_schemes WHERE version = $1";
3
3
  export declare const LIST_ACTIONS = "SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 ORDER BY category";
4
4
  export declare const GET_ACTION = "SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2";
5
- export declare const UPSERT_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n enabled = EXCLUDED.enabled\nRETURNING *";
5
+ export declare const UPSERT_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO UPDATE SET\n name = EXCLUDED.name,\n description = EXCLUDED.description,\n target_facet = EXCLUDED.target_facet,\n encoding = EXCLUDED.encoding,\n delimiter = EXCLUDED.delimiter,\n target_length = EXCLUDED.target_length,\n kind = EXCLUDED.kind,\n grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,\n grant_max_uses = EXCLUDED.grant_max_uses,\n enabled = EXCLUDED.enabled\nRETURNING *";
6
6
  export declare const DELETE_SCHEME = "DELETE FROM lt_config_scan_schemes WHERE version = $1";
7
- export declare const UPSERT_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, enabled)\nVALUES ($1, $2, $3, $4, $5, $6)\nON CONFLICT (scheme_version, category) DO UPDATE SET\n name = EXCLUDED.name,\n steps = EXCLUDED.steps,\n fallback = EXCLUDED.fallback,\n enabled = EXCLUDED.enabled\nRETURNING *";
7
+ export declare const UPSERT_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO UPDATE SET\n name = EXCLUDED.name,\n steps = EXCLUDED.steps,\n fallback = EXCLUDED.fallback,\n not_primed = EXCLUDED.not_primed,\n enabled = EXCLUDED.enabled\nRETURNING *";
8
8
  export declare const DELETE_ACTION = "DELETE FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2";
9
- export declare const SEED_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8)\nON CONFLICT (version) DO NOTHING";
10
- export declare const SEED_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, enabled)\nVALUES ($1, $2, $3, $4, $5, $6)\nON CONFLICT (scheme_version, category) DO NOTHING";
9
+ export declare const SEED_SCHEME = "INSERT INTO lt_config_scan_schemes\n (version, name, description, target_facet, encoding, delimiter, target_length,\n kind, grant_ttl_seconds, grant_max_uses, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)\nON CONFLICT (version) DO NOTHING";
10
+ export declare const SEED_ACTION = "INSERT INTO lt_config_scan_actions\n (scheme_version, category, name, steps, fallback, not_primed, enabled)\nVALUES ($1, $2, $3, $4, $5, $6, $7)\nON CONFLICT (scheme_version, category) DO NOTHING";
@@ -17,8 +17,9 @@ SELECT * FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2
17
17
  // ------------------------------------------------------------------ //
18
18
  exports.UPSERT_SCHEME = `\
19
19
  INSERT INTO lt_config_scan_schemes
20
- (version, name, description, target_facet, encoding, delimiter, target_length, enabled)
21
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
20
+ (version, name, description, target_facet, encoding, delimiter, target_length,
21
+ kind, grant_ttl_seconds, grant_max_uses, enabled)
22
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
22
23
  ON CONFLICT (version) DO UPDATE SET
23
24
  name = EXCLUDED.name,
24
25
  description = EXCLUDED.description,
@@ -26,18 +27,22 @@ ON CONFLICT (version) DO UPDATE SET
26
27
  encoding = EXCLUDED.encoding,
27
28
  delimiter = EXCLUDED.delimiter,
28
29
  target_length = EXCLUDED.target_length,
30
+ kind = EXCLUDED.kind,
31
+ grant_ttl_seconds = EXCLUDED.grant_ttl_seconds,
32
+ grant_max_uses = EXCLUDED.grant_max_uses,
29
33
  enabled = EXCLUDED.enabled
30
34
  RETURNING *`;
31
35
  exports.DELETE_SCHEME = `\
32
36
  DELETE FROM lt_config_scan_schemes WHERE version = $1`;
33
37
  exports.UPSERT_ACTION = `\
34
38
  INSERT INTO lt_config_scan_actions
35
- (scheme_version, category, name, steps, fallback, enabled)
36
- VALUES ($1, $2, $3, $4, $5, $6)
39
+ (scheme_version, category, name, steps, fallback, not_primed, enabled)
40
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
37
41
  ON CONFLICT (scheme_version, category) DO UPDATE SET
38
42
  name = EXCLUDED.name,
39
43
  steps = EXCLUDED.steps,
40
44
  fallback = EXCLUDED.fallback,
45
+ not_primed = EXCLUDED.not_primed,
41
46
  enabled = EXCLUDED.enabled
42
47
  RETURNING *`;
43
48
  exports.DELETE_ACTION = `\
@@ -47,11 +52,12 @@ DELETE FROM lt_config_scan_actions WHERE scheme_version = $1 AND category = $2`;
47
52
  // ------------------------------------------------------------------ //
48
53
  exports.SEED_SCHEME = `\
49
54
  INSERT INTO lt_config_scan_schemes
50
- (version, name, description, target_facet, encoding, delimiter, target_length, enabled)
51
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
55
+ (version, name, description, target_facet, encoding, delimiter, target_length,
56
+ kind, grant_ttl_seconds, grant_max_uses, enabled)
57
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
52
58
  ON CONFLICT (version) DO NOTHING`;
53
59
  exports.SEED_ACTION = `\
54
60
  INSERT INTO lt_config_scan_actions
55
- (scheme_version, category, name, steps, fallback, enabled)
56
- VALUES ($1, $2, $3, $4, $5, $6)
61
+ (scheme_version, category, name, steps, fallback, not_primed, enabled)
62
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
57
63
  ON CONFLICT (scheme_version, category) DO NOTHING`;
@@ -5,6 +5,8 @@ import { type ScanScheme, type ScanStep } from '../../types';
5
5
  * than a loud upsert failure.
6
6
  */
7
7
  export declare function assertValidScheme(scheme: Partial<ScanScheme>): void;
8
+ /** Identity rules never walk steps — their fallback is the unknown-badge screen. */
9
+ export declare function assertValidIdentityRule(steps: ScanStep[]): void;
8
10
  /**
9
11
  * Reject incoherent rule steps at write time: a rule that can never
10
12
  * execute its verb must fail the upsert, not the factory-floor scan.
@@ -1,9 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertValidScheme = assertValidScheme;
4
+ exports.assertValidIdentityRule = assertValidIdentityRule;
4
5
  exports.assertValidSteps = assertValidSteps;
5
6
  const types_1 = require("../../types");
6
7
  const VALID_VERBS = new Set(Object.values(types_1.SCAN_VERBS));
8
+ /** Double-scan selection tokens — short, label-printable, never scheme-shaped. */
9
+ const CHOICE_CODE = /^[A-Za-z0-9_-]{1,32}$/;
7
10
  /**
8
11
  * Reject incoherent scheme config at write time. Throws with the exact
9
12
  * problem — a bad scheme silently misparsing every scan is far worse
@@ -32,6 +35,64 @@ function assertValidScheme(scheme) {
32
35
  throw new Error('delimiter must not be a digit');
33
36
  }
34
37
  }
38
+ const kind = scheme.kind ?? types_1.SCAN_SCHEME_KINDS.ACTION;
39
+ if (kind !== types_1.SCAN_SCHEME_KINDS.ACTION && kind !== types_1.SCAN_SCHEME_KINDS.IDENTITY) {
40
+ throw new Error(`unknown scheme kind "${kind}"`);
41
+ }
42
+ if (kind === types_1.SCAN_SCHEME_KINDS.IDENTITY) {
43
+ const ttl = scheme.grant_ttl_seconds;
44
+ if (!Number.isInteger(ttl) || ttl < 1 || ttl > 86_400) {
45
+ throw new Error('identity schemes require grant_ttl_seconds between 1 and 86400');
46
+ }
47
+ if (!Number.isInteger(scheme.grant_max_uses ?? 0) || (scheme.grant_max_uses ?? 0) < 0) {
48
+ throw new Error('grant_max_uses must be a non-negative integer');
49
+ }
50
+ }
51
+ else if (scheme.grant_ttl_seconds != null || (scheme.grant_max_uses ?? 0) !== 0) {
52
+ throw new Error('grant policy applies only to identity schemes');
53
+ }
54
+ }
55
+ /** Identity rules never walk steps — their fallback is the unknown-badge screen. */
56
+ function assertValidIdentityRule(steps) {
57
+ if (Array.isArray(steps) && steps.length > 0) {
58
+ throw new Error('identity-scheme rules must have no steps (the fallback is the unknown-badge screen)');
59
+ }
60
+ }
61
+ /** Per-choice validation — a choice is a step verb with a label, minus locate concerns. */
62
+ function assertValidChoices(choices, at) {
63
+ if (!Array.isArray(choices) || choices.length === 0) {
64
+ throw new Error(`${at}: present requires a non-empty choices array`);
65
+ }
66
+ const codes = new Set();
67
+ choices.forEach((choice, j) => {
68
+ const cat = `${at} choice ${j + 1}`;
69
+ if (!choice || typeof choice !== 'object')
70
+ throw new Error(`${cat} must be an object`);
71
+ if (!choice.label)
72
+ throw new Error(`${cat}: label is required`);
73
+ if (!VALID_VERBS.has(choice.verb))
74
+ throw new Error(`${cat}: unknown verb "${choice.verb}"`);
75
+ if (choice.verb === types_1.SCAN_VERBS.PRESENT || choice.verb === types_1.SCAN_VERBS.SHOW_LIST) {
76
+ throw new Error(`${cat}: ${choice.verb} cannot be a choice verb`);
77
+ }
78
+ if (choice.confirm && !choice.confirm.prompt) {
79
+ throw new Error(`${cat}: confirm requires a prompt`);
80
+ }
81
+ if (choice.verb === types_1.SCAN_VERBS.ESCALATE && !choice.params?.targetRole) {
82
+ throw new Error(`${cat}: escalate requires params.targetRole`);
83
+ }
84
+ if (choice.verb === types_1.SCAN_VERBS.RESOLVE && !choice.params?.resolverPayload) {
85
+ throw new Error(`${cat}: resolve requires params.resolverPayload`);
86
+ }
87
+ if (choice.code !== undefined) {
88
+ if (!CHOICE_CODE.test(choice.code)) {
89
+ throw new Error(`${cat}: code must be 1-32 letters, digits, underscore, or dash`);
90
+ }
91
+ if (codes.has(choice.code))
92
+ throw new Error(`${cat}: duplicate code "${choice.code}"`);
93
+ codes.add(choice.code);
94
+ }
95
+ });
35
96
  }
36
97
  /**
37
98
  * Reject incoherent rule steps at write time: a rule that can never
@@ -53,6 +114,31 @@ function assertValidSteps(steps) {
53
114
  if (step.confirm && !step.confirm.prompt) {
54
115
  throw new Error(`${at}: confirm requires a prompt`);
55
116
  }
117
+ // The classic confirm flow completes through per-id endpoints as the
118
+ // logged-in principal — it cannot carry an acting identity. Identity-gated
119
+ // ask-first flows are authored as PRESENT choices with confirm.
120
+ if (step.confirm && step.requireActingIdentity) {
121
+ throw new Error(`${at}: confirm and requireActingIdentity are incompatible — use a present step with a confirming choice`);
122
+ }
123
+ if (step.verb === types_1.SCAN_VERBS.PRESENT) {
124
+ if (step.confirm)
125
+ throw new Error(`${at}: present steps cannot carry confirm (choices confirm individually)`);
126
+ if (step.cardinality === 'many')
127
+ throw new Error(`${at}: present locates a single row (cardinality first)`);
128
+ assertValidChoices(step.choices, at);
129
+ if (step.autoSelectSingle && step.choices.length !== 1) {
130
+ throw new Error(`${at}: autoSelectSingle requires exactly one choice`);
131
+ }
132
+ if (step.autoSelectSingle && step.choices[0].confirm) {
133
+ throw new Error(`${at}: autoSelectSingle cannot skip a confirming choice — drop the confirm or the auto-select`);
134
+ }
135
+ }
136
+ else {
137
+ if (step.choices !== undefined)
138
+ throw new Error(`${at}: choices apply only to present steps`);
139
+ if (step.autoSelectSingle)
140
+ throw new Error(`${at}: autoSelectSingle applies only to present steps`);
141
+ }
56
142
  if (step.verb === types_1.SCAN_VERBS.ESCALATE && !step.params?.targetRole) {
57
143
  throw new Error(`${at}: escalate requires params.targetRole`);
58
144
  }
@@ -7,6 +7,9 @@ export interface ScanSchemeInput {
7
7
  encoding?: ScanScheme['encoding'];
8
8
  delimiter?: string;
9
9
  target_length?: number | null;
10
+ kind?: ScanScheme['kind'];
11
+ grant_ttl_seconds?: number | null;
12
+ grant_max_uses?: number;
10
13
  enabled?: boolean;
11
14
  }
12
15
  export interface ScanRuleInput {
@@ -15,6 +18,7 @@ export interface ScanRuleInput {
15
18
  name: string;
16
19
  steps: ScanStep[];
17
20
  fallback?: ScanRuleFallback;
21
+ notPrimed?: ScanRuleFallback;
18
22
  enabled?: boolean;
19
23
  }
20
24
  export declare function upsertScanScheme(input: ScanSchemeInput): Promise<ScanScheme>;
@@ -10,6 +10,7 @@ const db_1 = require("../../lib/db");
10
10
  const types_1 = require("../../types");
11
11
  const sql_1 = require("./sql");
12
12
  const validate_1 = require("./validate");
13
+ const read_1 = require("./read");
13
14
  function schemeParams(input) {
14
15
  return [
15
16
  input.version,
@@ -19,6 +20,9 @@ function schemeParams(input) {
19
20
  input.encoding ?? types_1.SCAN_ENCODINGS.FIXED,
20
21
  input.delimiter ?? ':',
21
22
  input.target_length ?? null,
23
+ input.kind ?? types_1.SCAN_SCHEME_KINDS.ACTION,
24
+ input.grant_ttl_seconds ?? null,
25
+ input.grant_max_uses ?? 0,
22
26
  input.enabled ?? true,
23
27
  ];
24
28
  }
@@ -29,9 +33,19 @@ function ruleParams(input) {
29
33
  input.name,
30
34
  JSON.stringify(input.steps),
31
35
  JSON.stringify(input.fallback ?? {}),
36
+ JSON.stringify(input.notPrimed ?? {}),
32
37
  input.enabled ?? true,
33
38
  ];
34
39
  }
40
+ /** Identity-scheme rules never walk steps; validated against the OWNING scheme's kind. */
41
+ async function assertStepsForScheme(input) {
42
+ const scheme = await (0, read_1.getScanScheme)(input.scheme_version);
43
+ if (scheme?.kind === types_1.SCAN_SCHEME_KINDS.IDENTITY) {
44
+ (0, validate_1.assertValidIdentityRule)(input.steps);
45
+ return;
46
+ }
47
+ (0, validate_1.assertValidSteps)(input.steps);
48
+ }
35
49
  async function upsertScanScheme(input) {
36
50
  (0, validate_1.assertValidScheme)(input);
37
51
  const { rows } = await (0, db_1.getPool)().query(sql_1.UPSERT_SCHEME, schemeParams(input));
@@ -47,7 +61,7 @@ async function upsertScanRule(input) {
47
61
  }
48
62
  if (!input.name)
49
63
  throw new Error('rule name is required');
50
- (0, validate_1.assertValidSteps)(input.steps);
64
+ await assertStepsForScheme(input);
51
65
  if (input.steps.length === 0 && !input.fallback?.markdown && !input.fallback?.route) {
52
66
  throw new Error('a rule needs at least one step or a fallback');
53
67
  }
@@ -65,7 +79,7 @@ async function seedScanScheme(input) {
65
79
  return (rowCount ?? 0) > 0;
66
80
  }
67
81
  async function seedScanRule(input) {
68
- (0, validate_1.assertValidSteps)(input.steps);
82
+ await assertStepsForScheme(input);
69
83
  const { rowCount } = await (0, db_1.getPool)().query(sql_1.SEED_ACTION, ruleParams(input));
70
84
  return (rowCount ?? 0) > 0;
71
85
  }
@@ -5,6 +5,12 @@ export declare function createUser(input: CreateUserInput): Promise<LTUserRecord
5
5
  export declare function getUser(id: string): Promise<LTUserRecord | null>;
6
6
  export declare function getUserByExternalId(externalId: string): Promise<LTUserRecord | null>;
7
7
  export declare function getUserByEmail(email: string): Promise<LTUserRecord | null>;
8
+ /**
9
+ * Resolve an ACTIVE user by a metadata binding (e.g. metadata.badge_id).
10
+ * Two users carrying the same value is a configuration fault, not a pick —
11
+ * it throws so the binding gets fixed instead of misattributing work.
12
+ */
13
+ export declare function getUserByMetadataValue(key: string, value: string): Promise<LTUserRecord | null>;
8
14
  export declare function updateUser(id: string, input: UpdateUserInput): Promise<LTUserRecord | null>;
9
15
  export declare function deleteUser(id: string): Promise<boolean>;
10
16
  export declare function listUsers(filters: {
@@ -8,6 +8,7 @@ exports.createUser = createUser;
8
8
  exports.getUser = getUser;
9
9
  exports.getUserByExternalId = getUserByExternalId;
10
10
  exports.getUserByEmail = getUserByEmail;
11
+ exports.getUserByMetadataValue = getUserByMetadataValue;
11
12
  exports.updateUser = updateUser;
12
13
  exports.deleteUser = deleteUser;
13
14
  exports.listUsers = listUsers;
@@ -93,6 +94,21 @@ async function getUserByEmail(email) {
93
94
  return null;
94
95
  return attachRoles(rows[0]);
95
96
  }
97
+ /**
98
+ * Resolve an ACTIVE user by a metadata binding (e.g. metadata.badge_id).
99
+ * Two users carrying the same value is a configuration fault, not a pick —
100
+ * it throws so the binding gets fixed instead of misattributing work.
101
+ */
102
+ async function getUserByMetadataValue(key, value) {
103
+ const pool = (0, db_1.getPool)();
104
+ const { rows } = await pool.query(sql_1.GET_USERS_BY_METADATA_VALUE, [key, value]);
105
+ if (rows.length === 0)
106
+ return null;
107
+ if (rows.length > 1) {
108
+ throw new Error(`metadata binding "${key}" is ambiguous — multiple users carry the same value`);
109
+ }
110
+ return attachRoles(rows[0]);
111
+ }
96
112
  async function updateUser(id, input) {
97
113
  const pool = (0, db_1.getPool)();
98
114
  const sets = [];
@@ -1,5 +1,5 @@
1
1
  export { CreateUserInput, UpdateUserInput, VALID_ROLE_TYPES } from './types';
2
- export { createUser, getUser, getUserByExternalId, getUserByEmail, updateUser, deleteUser, listUsers, } from './crud';
2
+ export { createUser, getUser, getUserByExternalId, getUserByEmail, getUserByMetadataValue, updateUser, deleteUser, listUsers, } from './crud';
3
3
  export { isValidRoleType, addUserRole, removeUserRole, getUserRoles, hasRole, hasRoleType, } from './roles';
4
4
  export { isSuperAdmin, isGroupAdmin, canManageRole, hasGlobalEscalationAccess, hasRolesAsAdmin, getRoleScope, getRoleWriteScope } from './rbac';
5
5
  export { READ_SCOPES, WRITE_SCOPES, DEFAULT_READ_SCOPE, DEFAULT_WRITE_SCOPE, isValidReadScope, isValidWriteScope, isValidScopePair, effectiveScope, } from './scope';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.updateUser = exports.getUserByEmail = exports.getUserByExternalId = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
3
+ exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.updateUser = exports.getUserByMetadataValue = exports.getUserByEmail = exports.getUserByExternalId = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
4
4
  var types_1 = require("./types");
5
5
  Object.defineProperty(exports, "VALID_ROLE_TYPES", { enumerable: true, get: function () { return types_1.VALID_ROLE_TYPES; } });
6
6
  var crud_1 = require("./crud");
@@ -8,6 +8,7 @@ Object.defineProperty(exports, "createUser", { enumerable: true, get: function (
8
8
  Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return crud_1.getUser; } });
9
9
  Object.defineProperty(exports, "getUserByExternalId", { enumerable: true, get: function () { return crud_1.getUserByExternalId; } });
10
10
  Object.defineProperty(exports, "getUserByEmail", { enumerable: true, get: function () { return crud_1.getUserByEmail; } });
11
+ Object.defineProperty(exports, "getUserByMetadataValue", { enumerable: true, get: function () { return crud_1.getUserByMetadataValue; } });
11
12
  Object.defineProperty(exports, "updateUser", { enumerable: true, get: function () { return crud_1.updateUser; } });
12
13
  Object.defineProperty(exports, "deleteUser", { enumerable: true, get: function () { return crud_1.deleteUser; } });
13
14
  Object.defineProperty(exports, "listUsers", { enumerable: true, get: function () { return crud_1.listUsers; } });
@@ -18,6 +18,14 @@ export declare const GET_USER_BY_EXTERNAL_ID = "SELECT * FROM lt_users WHERE ext
18
18
  export declare const CREATE_USER_WITH_ROLES = "WITH new_user AS (\n INSERT INTO lt_users (external_id, email, display_name, status, metadata, password_hash, oauth_provider, oauth_provider_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *\n ), ensured_roles AS (\n INSERT INTO lt_roles (role)\n SELECT DISTINCT unnest($9::text[])\n ON CONFLICT DO NOTHING\n ), assigned_roles AS (\n INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope)\n SELECT (SELECT id FROM new_user), x.role, x.type, x.read_scope, x.write_scope\n FROM unnest($9::text[], $10::text[], $11::text[], $12::text[]) AS x(role, type, read_scope, write_scope)\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM new_user";
19
19
  export declare const GET_USER_BY_EMAIL = "SELECT * FROM lt_users WHERE email = $1 LIMIT 1";
20
20
  export declare const GET_USER_BY_ID = "SELECT * FROM lt_users WHERE id = $1";
21
+ /**
22
+ * Lookup by a caller-named metadata key (e.g. a badge binding). LIMIT 2 so an
23
+ * ambiguous binding — two users carrying the same value — is detectable and
24
+ * can fail loudly rather than silently picking one. Seq scan by design: this
25
+ * is the people table (small); revisit with a GIN index on metadata if a
26
+ * deployment ever holds tens of thousands of users.
27
+ */
28
+ export declare const GET_USERS_BY_METADATA_VALUE = "SELECT * FROM lt_users WHERE metadata->>$1 = $2 AND status = 'active' LIMIT 2";
21
29
  /** Check if a user exists by id. Lightweight — returns only the id column. */
22
30
  export declare const VERIFY_USER_BY_ID = "SELECT id FROM lt_users WHERE id = $1 LIMIT 1";
23
31
  /** Fetch user + roles in a single query. Returns one row per role (or one row with nulls if no roles). */
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // ─── Shared queries (used by multiple modules) ──────────────────────────────
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.IS_GROUP_ADMIN = exports.GET_ROLE_SCOPE = exports.HAS_ROLE_TYPE = exports.HAS_ROLE = exports.DELETE_USER_ROLE = exports.UPSERT_USER_ROLE = exports.GET_ROLES_BY_USER_IDS = exports.DELETE_USER_BY_ID = exports.GET_USER_WITH_ROLES = exports.VERIFY_USER_BY_ID = exports.GET_USER_BY_ID = exports.GET_USER_BY_EMAIL = exports.CREATE_USER_WITH_ROLES = exports.GET_USER_BY_EXTERNAL_ID = exports.GET_ROLES_BY_USER_ID = exports.ENSURE_ROLE_EXISTS = void 0;
4
+ exports.IS_GROUP_ADMIN = exports.GET_ROLE_SCOPE = exports.HAS_ROLE_TYPE = exports.HAS_ROLE = exports.DELETE_USER_ROLE = exports.UPSERT_USER_ROLE = exports.GET_ROLES_BY_USER_IDS = exports.DELETE_USER_BY_ID = exports.GET_USER_WITH_ROLES = exports.VERIFY_USER_BY_ID = exports.GET_USERS_BY_METADATA_VALUE = exports.GET_USER_BY_ID = exports.GET_USER_BY_EMAIL = exports.CREATE_USER_WITH_ROLES = exports.GET_USER_BY_EXTERNAL_ID = exports.GET_ROLES_BY_USER_ID = exports.ENSURE_ROLE_EXISTS = void 0;
5
5
  /** Ensure a role name exists in the lt_roles lookup table (FK target). */
6
6
  exports.ENSURE_ROLE_EXISTS = 'INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING';
7
7
  /** Fetch roles for a single user, ordered by creation time. granted_by_persona
@@ -40,6 +40,14 @@ exports.CREATE_USER_WITH_ROLES = `WITH new_user AS (
40
40
  SELECT * FROM new_user`;
41
41
  exports.GET_USER_BY_EMAIL = `SELECT * FROM lt_users WHERE email = $1 LIMIT 1`;
42
42
  exports.GET_USER_BY_ID = 'SELECT * FROM lt_users WHERE id = $1';
43
+ /**
44
+ * Lookup by a caller-named metadata key (e.g. a badge binding). LIMIT 2 so an
45
+ * ambiguous binding — two users carrying the same value — is detectable and
46
+ * can fail loudly rather than silently picking one. Seq scan by design: this
47
+ * is the people table (small); revisit with a GIN index on metadata if a
48
+ * deployment ever holds tens of thousands of users.
49
+ */
50
+ exports.GET_USERS_BY_METADATA_VALUE = `SELECT * FROM lt_users WHERE metadata->>$1 = $2 AND status = 'active' LIMIT 2`;
43
51
  /** Check if a user exists by id. Lightweight — returns only the id column. */
44
52
  exports.VERIFY_USER_BY_ID = 'SELECT id FROM lt_users WHERE id = $1 LIMIT 1';
45
53
  /** Fetch user + roles in a single query. Returns one row per role (or one row with nulls if no roles). */
@@ -259,6 +259,40 @@ function registerEscalationTools(server) {
259
259
  }
260
260
  return { content: [{ type: 'text', text: JSON.stringify(result.data) }] };
261
261
  });
262
+ // mirrors POST /api/escalations/aggregate-by-facets
263
+ server.registerTool('aggregate_by_facets', {
264
+ title: 'Aggregate by Facets',
265
+ description: 'Grouped analytics over the escalation intervals. Every escalation is one open ' +
266
+ 'interval [created_at, ended_at); this tool reads it two ways: membership (rows or, ' +
267
+ 'with distinctBy, distinct entities open at an instant — a past asOf reconstructs the ' +
268
+ 'live set then) and dwell (open-seconds per group within a half-open [from,to) window). ' +
269
+ 'Group by role/subtype/status columns plus metadata facet keys; optional states[] label ' +
270
+ 'each group. One call replaces N per-filter count round-trips. The filter takes the WHAT ' +
271
+ 'fields only — status/available/jeopardy are rejected (liveness derives from the measure).',
272
+ inputSchema: schemas_1.aggregateByFacetsSchema,
273
+ }, async (args) => {
274
+ const result = await escalationApi.aggregateByFacets(args, await systemAuth());
275
+ if (result.error) {
276
+ return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
277
+ }
278
+ return { content: [{ type: 'text', text: JSON.stringify(result.data) }] };
279
+ });
280
+ // mirrors POST /api/escalations/timeline-by-facet
281
+ server.registerTool('timeline_by_facet', {
282
+ title: 'Timeline by Facet',
283
+ description: 'One entity\'s ordered interval sequence — every escalation the entity facet ' +
284
+ '(e.g. a machine id) appeared in, as [startedAt, endedAt) spans with durations, in ' +
285
+ 'created_at order. Open intervals report endedAt: null. Gaps between consecutive ' +
286
+ 'intervals are untracked time and are preserved, not filled. The entity facet value ' +
287
+ 'must be stored as a JSON string (GIN containment match).',
288
+ inputSchema: schemas_1.timelineByFacetSchema,
289
+ }, async (args) => {
290
+ const result = await escalationApi.timelineByFacet(args, await systemAuth());
291
+ if (result.error) {
292
+ return { content: [{ type: 'text', text: JSON.stringify({ error: result.error }) }], isError: true };
293
+ }
294
+ return { content: [{ type: 'text', text: JSON.stringify(result.data) }] };
295
+ });
262
296
  // mirrors POST /api/escalations/claim-groups
263
297
  server.registerTool('claim_groups', {
264
298
  title: 'Claim Groups',
@@ -56,7 +56,23 @@ function registerScanCodeTools(server) {
56
56
  'no_match_fallback, unconfigured, invalid_code, forbidden, conflict).',
57
57
  inputSchema: schemas_1.executeScanCodeSchema,
58
58
  }, async (args) => {
59
- const result = await scanCodesApi.executeScanCode({ code: args.code }, await systemAuth());
59
+ const result = await scanCodesApi.executeScanCode({
60
+ code: args.code,
61
+ actingToken: args.actingToken,
62
+ previousActingToken: args.previousActingToken,
63
+ }, await systemAuth());
64
+ return asText(result.data ?? { error: result.error });
65
+ });
66
+ // mirrors POST /api/scan-codes/execute-choice
67
+ server.registerTool('execute_scan_choice', {
68
+ title: 'Execute Scan Choice',
69
+ description: 'Execute one choice presented by a PRESENT step (the info-choice screen). ' +
70
+ 'The pointer (scheme/category/step/choice + escalationId) is re-validated ' +
71
+ 'against live config, the row\'s current state, the acting-identity gate, ' +
72
+ 'and RBAC before the verb runs.',
73
+ inputSchema: schemas_1.executeScanChoiceSchema,
74
+ }, async (args) => {
75
+ const result = await scanCodesApi.executeScanChoice(args, await systemAuth());
60
76
  return asText(result.data ?? { error: result.error });
61
77
  });
62
78
  // mirrors GET /api/scan-codes/schemes