@hotmeshio/long-tail 0.22.2 → 0.22.3

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 (255) hide show
  1. package/build/api/escalations/lookups.d.ts +9 -2
  2. package/build/api/escalations/lookups.js +15 -3
  3. package/build/api/escalations/metadata.d.ts +2 -0
  4. package/build/api/escalations/metadata.js +9 -0
  5. package/build/api/scan-codes/locate.js +4 -0
  6. package/build/api/scan-codes/present.d.ts +1 -1
  7. package/build/api/scan-codes/present.js +43 -0
  8. package/build/api/scan-codes/verb-accumulate.js +5 -1
  9. package/build/api/scan-codes/verb-fill.js +4 -1
  10. package/build/api/scan-codes/verb-into-subject.d.ts +12 -0
  11. package/build/api/scan-codes/verb-into-subject.js +157 -0
  12. package/build/api/scan-codes/verbs-subject.d.ts +23 -4
  13. package/build/api/scan-codes/verbs-subject.js +32 -55
  14. package/build/api/scan-codes/verbs.d.ts +10 -8
  15. package/build/api/scan-codes/verbs.js +25 -16
  16. package/build/index.d.ts +1 -1
  17. package/build/index.js +3 -2
  18. package/build/sdk/index.d.ts +1 -0
  19. package/build/services/escalation/claim-asserted.d.ts +10 -0
  20. package/build/services/escalation/claim-asserted.js +64 -0
  21. package/build/services/escalation/facets.d.ts +3 -1
  22. package/build/services/escalation/facets.js +7 -3
  23. package/build/services/escalation/index.d.ts +1 -0
  24. package/build/services/escalation/index.js +3 -1
  25. package/build/services/knowledge/lookup-cache.d.ts +16 -4
  26. package/build/services/knowledge/lookup-cache.js +53 -20
  27. package/build/services/knowledge/lookup-refs.d.ts +3 -2
  28. package/build/services/knowledge/lookup-refs.js +6 -4
  29. package/build/services/knowledge/sql.d.ts +2 -0
  30. package/build/services/knowledge/sql.js +9 -1
  31. package/build/services/mcp/server-tools.js +1 -1
  32. package/build/services/orchestrator/condition.d.ts +13 -10
  33. package/build/services/orchestrator/condition.js +8 -6
  34. package/build/services/scan-code/index.d.ts +1 -1
  35. package/build/services/scan-code/index.js +2 -1
  36. package/build/services/scan-code/validate-facts.d.ts +5 -0
  37. package/build/services/scan-code/validate-facts.js +24 -0
  38. package/build/services/scan-code/validate-query.d.ts +8 -0
  39. package/build/services/scan-code/validate-query.js +36 -0
  40. package/build/services/scan-code/validate-subject.js +29 -2
  41. package/build/services/scan-code/validate.js +17 -8
  42. package/build/shared/scan-code/gtin.d.ts +6 -0
  43. package/build/shared/scan-code/gtin.js +13 -0
  44. package/build/shared/scan-code/index.d.ts +1 -1
  45. package/build/shared/scan-code/index.js +2 -1
  46. package/build/system/mcp-servers/admin/schemas.d.ts +185 -5
  47. package/build/system/mcp-servers/admin/schemas.js +16 -3
  48. package/build/system/seed/tool-manifests-admin.d.ts +202 -1
  49. package/build/system/seed/tool-manifests-admin.js +2 -2
  50. package/build/tsconfig.tsbuildinfo +1 -1
  51. package/build/types/escalation.d.ts +14 -8
  52. package/build/types/escalation.js +16 -7
  53. package/build/types/index.d.ts +3 -3
  54. package/build/types/index.js +3 -1
  55. package/build/types/scan-code/response.d.ts +5 -0
  56. package/build/types/scan-code/rule.d.ts +32 -2
  57. package/dashboard/dist/assets/{AdminDashboard-DBW12qQt.js → AdminDashboard-hI5-kKpL.js} +2 -2
  58. package/dashboard/dist/assets/{AdminDashboard-DBW12qQt.js.map → AdminDashboard-hI5-kKpL.js.map} +1 -1
  59. package/dashboard/dist/assets/{AgentConfigPage-CmHv8U9M.js → AgentConfigPage-DetU4HZe.js} +2 -2
  60. package/dashboard/dist/assets/{AgentConfigPage-CmHv8U9M.js.map → AgentConfigPage-DetU4HZe.js.map} +1 -1
  61. package/dashboard/dist/assets/{AgentDetailPage-D1scIbz-.js → AgentDetailPage-DrGXo8KQ.js} +2 -2
  62. package/dashboard/dist/assets/{AgentDetailPage-D1scIbz-.js.map → AgentDetailPage-DrGXo8KQ.js.map} +1 -1
  63. package/dashboard/dist/assets/{AgentsPage-BA_ai9HJ.js → AgentsPage-D4md5BzM.js} +2 -2
  64. package/dashboard/dist/assets/{AgentsPage-BA_ai9HJ.js.map → AgentsPage-D4md5BzM.js.map} +1 -1
  65. package/dashboard/dist/assets/{AvailableEscalationsPage-C2_5aEFW.js → AvailableEscalationsPage-B2bS2ZJy.js} +2 -2
  66. package/dashboard/dist/assets/{AvailableEscalationsPage-C2_5aEFW.js.map → AvailableEscalationsPage-B2bS2ZJy.js.map} +1 -1
  67. package/dashboard/dist/assets/{BotPicker-BZo4Kp4a.js → BotPicker-BXtey255.js} +2 -2
  68. package/dashboard/dist/assets/{BotPicker-BZo4Kp4a.js.map → BotPicker-BXtey255.js.map} +1 -1
  69. package/dashboard/dist/assets/{BulkAssignModal-BFhyxY2T.js → BulkAssignModal-CSL_PeZv.js} +2 -2
  70. package/dashboard/dist/assets/{BulkAssignModal-BFhyxY2T.js.map → BulkAssignModal-CSL_PeZv.js.map} +1 -1
  71. package/dashboard/dist/assets/{CapabilitiesPage-CvOX6vAc.js → CapabilitiesPage-5scufTHW.js} +2 -2
  72. package/dashboard/dist/assets/{CapabilitiesPage-CvOX6vAc.js.map → CapabilitiesPage-5scufTHW.js.map} +1 -1
  73. package/dashboard/dist/assets/{CollapsibleSection-GCJsV9Oq.js → CollapsibleSection-DjjDGxP_.js} +2 -2
  74. package/dashboard/dist/assets/{CollapsibleSection-GCJsV9Oq.js.map → CollapsibleSection-DjjDGxP_.js.map} +1 -1
  75. package/dashboard/dist/assets/{ConfirmDeleteModal-CAgYLcef.js → ConfirmDeleteModal-DJSmsHQM.js} +2 -2
  76. package/dashboard/dist/assets/{ConfirmDeleteModal-CAgYLcef.js.map → ConfirmDeleteModal-DJSmsHQM.js.map} +1 -1
  77. package/dashboard/dist/assets/{CountdownTimer-Dik2z0M_.js → CountdownTimer-C5ZRYPfF.js} +2 -2
  78. package/dashboard/dist/assets/{CountdownTimer-Dik2z0M_.js.map → CountdownTimer-C5ZRYPfF.js.map} +1 -1
  79. package/dashboard/dist/assets/{CredentialsPage-twd2xCOW.js → CredentialsPage-CV6e60yC.js} +2 -2
  80. package/dashboard/dist/assets/{CredentialsPage-twd2xCOW.js.map → CredentialsPage-CV6e60yC.js.map} +1 -1
  81. package/dashboard/dist/assets/{CronLabel-DdnIuudX.js → CronLabel-CnqhqW0B.js} +2 -2
  82. package/dashboard/dist/assets/{CronLabel-DdnIuudX.js.map → CronLabel-CnqhqW0B.js.map} +1 -1
  83. package/dashboard/dist/assets/{ElapsedCell-DCctVv5R.js → ElapsedCell-C1IOn-tj.js} +2 -2
  84. package/dashboard/dist/assets/{ElapsedCell-DCctVv5R.js.map → ElapsedCell-C1IOn-tj.js.map} +1 -1
  85. package/dashboard/dist/assets/{EntityTimelinePanel-CMnskyWv.js → EntityTimelinePanel-Dz6Liig4.js} +2 -2
  86. package/dashboard/dist/assets/{EntityTimelinePanel-CMnskyWv.js.map → EntityTimelinePanel-Dz6Liig4.js.map} +1 -1
  87. package/dashboard/dist/assets/{EscalationListSchemaPage-VfCn6WDb.js → EscalationListSchemaPage-bgdmLmrh.js} +2 -2
  88. package/dashboard/dist/assets/{EscalationListSchemaPage-VfCn6WDb.js.map → EscalationListSchemaPage-bgdmLmrh.js.map} +1 -1
  89. package/dashboard/dist/assets/{EscalationListView-CGQZxcC-.js → EscalationListView-CrlD3ZGt.js} +2 -2
  90. package/dashboard/dist/assets/{EscalationListView-CGQZxcC-.js.map → EscalationListView-CrlD3ZGt.js.map} +1 -1
  91. package/dashboard/dist/assets/{EscalationSchemaPage-BX0tx-PM.js → EscalationSchemaPage-dxXO_T3t.js} +2 -2
  92. package/dashboard/dist/assets/{EscalationSchemaPage-BX0tx-PM.js.map → EscalationSchemaPage-dxXO_T3t.js.map} +1 -1
  93. package/dashboard/dist/assets/{EscalationTimeline-DKoSM56J.js → EscalationTimeline-C3WQZQuM.js} +2 -2
  94. package/dashboard/dist/assets/{EscalationTimeline-DKoSM56J.js.map → EscalationTimeline-C3WQZQuM.js.map} +1 -1
  95. package/dashboard/dist/assets/{EscalationTitleSelect-DWGLBOmS.js → EscalationTitleSelect-CTtcETUO.js} +2 -2
  96. package/dashboard/dist/assets/{EscalationTitleSelect-DWGLBOmS.js.map → EscalationTitleSelect-CTtcETUO.js.map} +1 -1
  97. package/dashboard/dist/assets/{EscalationsOverview-C2XoguaA.js → EscalationsOverview-DAjZ7JY2.js} +2 -2
  98. package/dashboard/dist/assets/{EscalationsOverview-C2XoguaA.js.map → EscalationsOverview-DAjZ7JY2.js.map} +1 -1
  99. package/dashboard/dist/assets/{EventTable-CBUWq7--.js → EventTable-B72DQP_v.js} +2 -2
  100. package/dashboard/dist/assets/{EventTable-CBUWq7--.js.map → EventTable-B72DQP_v.js.map} +1 -1
  101. package/dashboard/dist/assets/{FilterBar-8IdbleZ9.js → FilterBar-CCTaA_LH.js} +2 -2
  102. package/dashboard/dist/assets/{FilterBar-8IdbleZ9.js.map → FilterBar-CCTaA_LH.js.map} +1 -1
  103. package/dashboard/dist/assets/{GraphInvokePage-CUvoPzsW.js → GraphInvokePage-CAsCgFo3.js} +2 -2
  104. package/dashboard/dist/assets/{GraphInvokePage-CUvoPzsW.js.map → GraphInvokePage-CAsCgFo3.js.map} +1 -1
  105. package/dashboard/dist/assets/{HomePage-BP7v9GLJ.js → HomePage-DseE_iSr.js} +2 -2
  106. package/dashboard/dist/assets/{HomePage-BP7v9GLJ.js.map → HomePage-DseE_iSr.js.map} +1 -1
  107. package/dashboard/dist/assets/{ListToolbar-Cnacuwoy.js → ListToolbar-1zdqnjW6.js} +2 -2
  108. package/dashboard/dist/assets/{ListToolbar-Cnacuwoy.js.map → ListToolbar-1zdqnjW6.js.map} +1 -1
  109. package/dashboard/dist/assets/{McpOverview-C2JoNoDA.js → McpOverview-DS_JXDW5.js} +2 -2
  110. package/dashboard/dist/assets/{McpOverview-C2JoNoDA.js.map → McpOverview-DS_JXDW5.js.map} +1 -1
  111. package/dashboard/dist/assets/{McpQueryDetailPage-C_nih0w-.js → McpQueryDetailPage-BeMUGcv3.js} +2 -2
  112. package/dashboard/dist/assets/{McpQueryDetailPage-C_nih0w-.js.map → McpQueryDetailPage-BeMUGcv3.js.map} +1 -1
  113. package/dashboard/dist/assets/{McpQueryPage-U_wNXow2.js → McpQueryPage-CeiLO_LR.js} +2 -2
  114. package/dashboard/dist/assets/{McpQueryPage-U_wNXow2.js.map → McpQueryPage-CeiLO_LR.js.map} +1 -1
  115. package/dashboard/dist/assets/{McpRunDetailPage-DtKoJq6J.js → McpRunDetailPage-DYp1uZK2.js} +2 -2
  116. package/dashboard/dist/assets/{McpRunDetailPage-DtKoJq6J.js.map → McpRunDetailPage-DYp1uZK2.js.map} +1 -1
  117. package/dashboard/dist/assets/{McpRunsPage-CnYtfGhf.js → McpRunsPage-VeaDzcL4.js} +2 -2
  118. package/dashboard/dist/assets/{McpRunsPage-CnYtfGhf.js.map → McpRunsPage-VeaDzcL4.js.map} +1 -1
  119. package/dashboard/dist/assets/{OperationsPage-C7hupIer.js → OperationsPage-DK2mgaXf.js} +2 -2
  120. package/dashboard/dist/assets/{OperationsPage-C7hupIer.js.map → OperationsPage-DK2mgaXf.js.map} +1 -1
  121. package/dashboard/dist/assets/{OperatorDashboard-fVuLn2D5.js → OperatorDashboard-BNjLF0f7.js} +2 -2
  122. package/dashboard/dist/assets/{OperatorDashboard-fVuLn2D5.js.map → OperatorDashboard-BNjLF0f7.js.map} +1 -1
  123. package/dashboard/dist/assets/{PersonaDetailPage-C-4o8lPw.js → PersonaDetailPage-IQ2fZLa6.js} +2 -2
  124. package/dashboard/dist/assets/{PersonaDetailPage-C-4o8lPw.js.map → PersonaDetailPage-IQ2fZLa6.js.map} +1 -1
  125. package/dashboard/dist/assets/{PersonasPage-BL1FwLmv.js → PersonasPage-DpGFEcU-.js} +2 -2
  126. package/dashboard/dist/assets/{PersonasPage-BL1FwLmv.js.map → PersonasPage-DpGFEcU-.js.map} +1 -1
  127. package/dashboard/dist/assets/{PortalPage-tJG5sgb1.js → PortalPage-D07xyvG_.js} +2 -2
  128. package/dashboard/dist/assets/{PortalPage-tJG5sgb1.js.map → PortalPage-D07xyvG_.js.map} +1 -1
  129. package/dashboard/dist/assets/{ProcessDetailPage-Dz_jY4Yt.js → ProcessDetailPage-t8EEYSMk.js} +2 -2
  130. package/dashboard/dist/assets/{ProcessDetailPage-Dz_jY4Yt.js.map → ProcessDetailPage-t8EEYSMk.js.map} +1 -1
  131. package/dashboard/dist/assets/{ProcessesListPage-Cbn9cter.js → ProcessesListPage-BDUXLFdb.js} +2 -2
  132. package/dashboard/dist/assets/{ProcessesListPage-Cbn9cter.js.map → ProcessesListPage-BDUXLFdb.js.map} +1 -1
  133. package/dashboard/dist/assets/{ResolverForm-Bk8iXQ6-.js → ResolverForm-BwWOYv_Z.js} +6 -6
  134. package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js.map +1 -0
  135. package/dashboard/dist/assets/{RoleDetailPage-owPi6gI9.js → RoleDetailPage-zMF3x2xi.js} +2 -2
  136. package/dashboard/dist/assets/{RoleDetailPage-owPi6gI9.js.map → RoleDetailPage-zMF3x2xi.js.map} +1 -1
  137. package/dashboard/dist/assets/{RolesPage-NwmMvZFa.js → RolesPage-CEBp_PpL.js} +2 -2
  138. package/dashboard/dist/assets/{RolesPage-NwmMvZFa.js.map → RolesPage-CEBp_PpL.js.map} +1 -1
  139. package/dashboard/dist/assets/{RunAsSelector-tgEooTyU.js → RunAsSelector-CC_EHN3z.js} +2 -2
  140. package/dashboard/dist/assets/{RunAsSelector-tgEooTyU.js.map → RunAsSelector-CC_EHN3z.js.map} +1 -1
  141. package/dashboard/dist/assets/{ScanCodesPage-CUv_8ic6.js → ScanCodesPage-DD4uU-jY.js} +2 -2
  142. package/dashboard/dist/assets/{ScanCodesPage-CUv_8ic6.js.map → ScanCodesPage-DD4uU-jY.js.map} +1 -1
  143. package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js +2 -0
  144. package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js.map +1 -0
  145. package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js +2 -0
  146. package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js.map +1 -0
  147. package/dashboard/dist/assets/{StickyPagination-CsTI_gvJ.js → StickyPagination-cNqSDm5f.js} +2 -2
  148. package/dashboard/dist/assets/{StickyPagination-CsTI_gvJ.js.map → StickyPagination-cNqSDm5f.js.map} +1 -1
  149. package/dashboard/dist/assets/{StreamMessageDetail-auRlvjTh.js → StreamMessageDetail-C4oZqQdB.js} +2 -2
  150. package/dashboard/dist/assets/{StreamMessageDetail-auRlvjTh.js.map → StreamMessageDetail-C4oZqQdB.js.map} +1 -1
  151. package/dashboard/dist/assets/{SwimlaneTimeline-BLoVHYAd.js → SwimlaneTimeline-BjBiV7GT.js} +2 -2
  152. package/dashboard/dist/assets/{SwimlaneTimeline-BLoVHYAd.js.map → SwimlaneTimeline-BjBiV7GT.js.map} +1 -1
  153. package/dashboard/dist/assets/{TaskDetailPage-BPsZ1bK_.js → TaskDetailPage-pO_AnVS1.js} +2 -2
  154. package/dashboard/dist/assets/{TaskDetailPage-BPsZ1bK_.js.map → TaskDetailPage-pO_AnVS1.js.map} +1 -1
  155. package/dashboard/dist/assets/{TasksListPage-BNGM74yT.js → TasksListPage-DKDHlWP7.js} +2 -2
  156. package/dashboard/dist/assets/{TasksListPage-BNGM74yT.js.map → TasksListPage-DKDHlWP7.js.map} +1 -1
  157. package/dashboard/dist/assets/{TimeAgo-BnAHXGK7.js → TimeAgo-D2qchUuJ.js} +2 -2
  158. package/dashboard/dist/assets/{TimeAgo-BnAHXGK7.js.map → TimeAgo-D2qchUuJ.js.map} +1 -1
  159. package/dashboard/dist/assets/{TimestampCell-J4yae6mc.js → TimestampCell-DeswZGGo.js} +2 -2
  160. package/dashboard/dist/assets/{TimestampCell-J4yae6mc.js.map → TimestampCell-DeswZGGo.js.map} +1 -1
  161. package/dashboard/dist/assets/{ToolTestPanel-BdzzgXDu.js → ToolTestPanel-DJh7PIUa.js} +2 -2
  162. package/dashboard/dist/assets/{ToolTestPanel-BdzzgXDu.js.map → ToolTestPanel-DJh7PIUa.js.map} +1 -1
  163. package/dashboard/dist/assets/{TopicDetailPage-DJKg8lb7.js → TopicDetailPage-CsgDJ4Z4.js} +2 -2
  164. package/dashboard/dist/assets/{TopicDetailPage-DJKg8lb7.js.map → TopicDetailPage-CsgDJ4Z4.js.map} +1 -1
  165. package/dashboard/dist/assets/{TopicsPage-DQV0WxG6.js → TopicsPage-tBRZDVDN.js} +2 -2
  166. package/dashboard/dist/assets/{TopicsPage-DQV0WxG6.js.map → TopicsPage-tBRZDVDN.js.map} +1 -1
  167. package/dashboard/dist/assets/{UserName-Ct09nGh5.js → UserName-B-5JcDck.js} +2 -2
  168. package/dashboard/dist/assets/{UserName-Ct09nGh5.js.map → UserName-B-5JcDck.js.map} +1 -1
  169. package/dashboard/dist/assets/{WorkflowExecutionPage-B5WJOsee.js → WorkflowExecutionPage-BPHVnhp6.js} +2 -2
  170. package/dashboard/dist/assets/{WorkflowExecutionPage-B5WJOsee.js.map → WorkflowExecutionPage-BPHVnhp6.js.map} +1 -1
  171. package/dashboard/dist/assets/{WorkflowsDashboard-Hc87TRgD.js → WorkflowsDashboard-CxLlfZmY.js} +2 -2
  172. package/dashboard/dist/assets/{WorkflowsDashboard-Hc87TRgD.js.map → WorkflowsDashboard-CxLlfZmY.js.map} +1 -1
  173. package/dashboard/dist/assets/{WorkflowsOverview-CJQbyOj-.js → WorkflowsOverview-C4az5rwp.js} +2 -2
  174. package/dashboard/dist/assets/{WorkflowsOverview-CJQbyOj-.js.map → WorkflowsOverview-C4az5rwp.js.map} +1 -1
  175. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BMeED677.js → YamlWorkflowDetailPage-BmhlAUFQ.js} +2 -2
  176. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BMeED677.js.map → YamlWorkflowDetailPage-BmhlAUFQ.js.map} +1 -1
  177. package/dashboard/dist/assets/{YamlWorkflowsPage-BMMg0Id6.js → YamlWorkflowsPage-CSbG5o2V.js} +2 -2
  178. package/dashboard/dist/assets/{YamlWorkflowsPage-BMMg0Id6.js.map → YamlWorkflowsPage-CSbG5o2V.js.map} +1 -1
  179. package/dashboard/dist/assets/{agents-CdFkgFvg.js → agents-BohEn7vw.js} +2 -2
  180. package/dashboard/dist/assets/{agents-CdFkgFvg.js.map → agents-BohEn7vw.js.map} +1 -1
  181. package/dashboard/dist/assets/{bots-Mj3LHWWg.js → bots-BG2EO-Wi.js} +2 -2
  182. package/dashboard/dist/assets/{bots-Mj3LHWWg.js.map → bots-BG2EO-Wi.js.map} +1 -1
  183. package/dashboard/dist/assets/{capabilities-Dw1ObK2-.js → capabilities-CeFrBmYX.js} +2 -2
  184. package/dashboard/dist/assets/{capabilities-Dw1ObK2-.js.map → capabilities-CeFrBmYX.js.map} +1 -1
  185. package/dashboard/dist/assets/{controlplane-DcNE1APv.js → controlplane-Dhvt8l8F.js} +2 -2
  186. package/dashboard/dist/assets/{controlplane-DcNE1APv.js.map → controlplane-Dhvt8l8F.js.map} +1 -1
  187. package/dashboard/dist/assets/{escalation-columns-D364Trpy.js → escalation-columns-BWMNxImp.js} +2 -2
  188. package/dashboard/dist/assets/{escalation-columns-D364Trpy.js.map → escalation-columns-BWMNxImp.js.map} +1 -1
  189. package/dashboard/dist/assets/{index-DPStdq4T.js → index-Bd_dgyfJ.js} +2 -2
  190. package/dashboard/dist/assets/{index-DPStdq4T.js.map → index-Bd_dgyfJ.js.map} +1 -1
  191. package/dashboard/dist/assets/{index-B3veJ698.js → index-C8VlM2Oe.js} +2 -2
  192. package/dashboard/dist/assets/{index-B3veJ698.js.map → index-C8VlM2Oe.js.map} +1 -1
  193. package/dashboard/dist/assets/{index-BiVce3n0.js → index-CiqSVDga.js} +2 -2
  194. package/dashboard/dist/assets/{index-BiVce3n0.js.map → index-CiqSVDga.js.map} +1 -1
  195. package/dashboard/dist/assets/{index-DkcI4V_H.js → index-Cl_YXEdp.js} +2 -2
  196. package/dashboard/dist/assets/{index-DkcI4V_H.js.map → index-Cl_YXEdp.js.map} +1 -1
  197. package/dashboard/dist/assets/index-CtZWpy22.js +2 -0
  198. package/dashboard/dist/assets/index-CtZWpy22.js.map +1 -0
  199. package/dashboard/dist/assets/{index-Bq5XNEzD.js → index-D90D9y0J.js} +2 -2
  200. package/dashboard/dist/assets/{index-Bq5XNEzD.js.map → index-D90D9y0J.js.map} +1 -1
  201. package/dashboard/dist/assets/{index-eDm6cz0F.js → index-DABkM7s-.js} +2 -2
  202. package/dashboard/dist/assets/{index-eDm6cz0F.js.map → index-DABkM7s-.js.map} +1 -1
  203. package/dashboard/dist/assets/{index-WSm8bgE7.js → index-Dbwu51xm.js} +3 -3
  204. package/dashboard/dist/assets/{index-WSm8bgE7.js.map → index-Dbwu51xm.js.map} +1 -1
  205. package/dashboard/dist/assets/{index-Dyotfa_k.js → index-Dc3Om6G3.js} +2 -2
  206. package/dashboard/dist/assets/{index-Dyotfa_k.js.map → index-Dc3Om6G3.js.map} +1 -1
  207. package/dashboard/dist/assets/{index-BRGTmoYY.js → index-Dc_zWK23.js} +2 -2
  208. package/dashboard/dist/assets/{index-BRGTmoYY.js.map → index-Dc_zWK23.js.map} +1 -1
  209. package/dashboard/dist/assets/{index-MDD4JYtu.js → index-Y-bdW8vo.js} +2 -2
  210. package/dashboard/dist/assets/{index-MDD4JYtu.js.map → index-Y-bdW8vo.js.map} +1 -1
  211. package/dashboard/dist/assets/{index-Bd6-KmBE.js → index-dYKgd06u.js} +2 -2
  212. package/dashboard/dist/assets/{index-Bd6-KmBE.js.map → index-dYKgd06u.js.map} +1 -1
  213. package/dashboard/dist/assets/{index-BQeHJHYN.js → index-fUsx_gYx.js} +25 -25
  214. package/dashboard/dist/assets/index-fUsx_gYx.js.map +1 -0
  215. package/dashboard/dist/assets/{knowledge-Bafewjxk.js → knowledge-CCcTidNV.js} +2 -2
  216. package/dashboard/dist/assets/{knowledge-Bafewjxk.js.map → knowledge-CCcTidNV.js.map} +1 -1
  217. package/dashboard/dist/assets/{mcp-vLIutbnc.js → mcp-CLA1z7Pg.js} +2 -2
  218. package/dashboard/dist/assets/{mcp-vLIutbnc.js.map → mcp-CLA1z7Pg.js.map} +1 -1
  219. package/dashboard/dist/assets/{mcp-query-BzTtIG90.js → mcp-query-CWG0WMAs.js} +2 -2
  220. package/dashboard/dist/assets/{mcp-query-BzTtIG90.js.map → mcp-query-CWG0WMAs.js.map} +1 -1
  221. package/dashboard/dist/assets/metadata-display-B7X5hGxG.js +2 -0
  222. package/dashboard/dist/assets/metadata-display-B7X5hGxG.js.map +1 -0
  223. package/dashboard/dist/assets/{personas-WD40EDS_.js → personas-8jURIzx6.js} +2 -2
  224. package/dashboard/dist/assets/{personas-WD40EDS_.js.map → personas-8jURIzx6.js.map} +1 -1
  225. package/dashboard/dist/assets/{pipelines-DFwULWs3.js → pipelines-hVVRAXqG.js} +2 -2
  226. package/dashboard/dist/assets/{pipelines-DFwULWs3.js.map → pipelines-hVVRAXqG.js.map} +1 -1
  227. package/dashboard/dist/assets/{tasks-La_-WAUn.js → tasks-BE1O57Bf.js} +2 -2
  228. package/dashboard/dist/assets/{tasks-La_-WAUn.js.map → tasks-BE1O57Bf.js.map} +1 -1
  229. package/dashboard/dist/assets/{topics-CzYMlvqm.js → topics-Bg96Wp1r.js} +2 -2
  230. package/dashboard/dist/assets/{topics-CzYMlvqm.js.map → topics-Bg96Wp1r.js.map} +1 -1
  231. package/dashboard/dist/assets/{useDebouncedValue-C0FQyANW.js → useDebouncedValue-DmEveyEy.js} +2 -2
  232. package/dashboard/dist/assets/{useDebouncedValue-C0FQyANW.js.map → useDebouncedValue-DmEveyEy.js.map} +1 -1
  233. package/dashboard/dist/assets/{useNamespace-WW_XjAb3.js → useNamespace-DHgkzIuL.js} +2 -2
  234. package/dashboard/dist/assets/{useNamespace-WW_XjAb3.js.map → useNamespace-DHgkzIuL.js.map} +1 -1
  235. package/dashboard/dist/assets/{useYamlActivityEvents-B3YxPeFt.js → useYamlActivityEvents-RU0PvU8S.js} +2 -2
  236. package/dashboard/dist/assets/{useYamlActivityEvents-B3YxPeFt.js.map → useYamlActivityEvents-RU0PvU8S.js.map} +1 -1
  237. package/dashboard/dist/assets/{yaml-workflows-COHOjdhF.js → yaml-workflows-DQWE9ijc.js} +2 -2
  238. package/dashboard/dist/assets/{yaml-workflows-COHOjdhF.js.map → yaml-workflows-DQWE9ijc.js.map} +1 -1
  239. package/dashboard/dist/index.html +1 -1
  240. package/docs/hitl/lookups.md +27 -18
  241. package/docs/hitl/x-lt-validation.md +1 -1
  242. package/docs/hitl/x-lt-widget.md +1 -1
  243. package/docs/hitl-guide.md +1 -1
  244. package/docs/scan-codes.md +86 -16
  245. package/package.json +1 -1
  246. package/dashboard/dist/assets/ResolverForm-Bk8iXQ6-.js.map +0 -1
  247. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js +0 -2
  248. package/dashboard/dist/assets/ScanSchemeDetailPage-YHqbu7oK.js.map +0 -1
  249. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js +0 -2
  250. package/dashboard/dist/assets/ScanStationPage-B275l6r_.js.map +0 -1
  251. package/dashboard/dist/assets/index-BQeHJHYN.js.map +0 -1
  252. package/dashboard/dist/assets/index-BmNAVd4s.js +0 -2
  253. package/dashboard/dist/assets/index-BmNAVd4s.js.map +0 -1
  254. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +0 -2
  255. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +0 -1
@@ -54,7 +54,8 @@ const hold_1 = require("./hold");
54
54
  // ctx.auth is the effective actor: the badged person when a grant rode the
55
55
  // request, otherwise the authenticated principal. Attribution and write
56
56
  // scoping both derive from it, live, inside the escalation APIs.
57
- async function claimStep(step, ctx) {
57
+ /** Claims the scanned row; a presented choice passes the row it showed. */
58
+ async function claimStep(step, ctx, presentedId) {
58
59
  const metadata = await (0, context_1.templated)(step, ctx, (tpl) => (0, context_1.interpolatedMetadata)(step, ctx, tpl));
59
60
  if (metadata === null)
60
61
  return null;
@@ -67,6 +68,7 @@ async function claimStep(step, ctx) {
67
68
  durationMinutes: step.params?.durationMinutes,
68
69
  metadata: { ...metadata, ...(0, context_1.provenance)(ctx) },
69
70
  restrictRoles: step.query?.roles,
71
+ assertId: presentedId,
70
72
  }, ctx.auth);
71
73
  if (result.status === 404)
72
74
  return null;
@@ -115,19 +117,19 @@ async function resolveStep(step, ctx, presentedId) {
115
117
  ?? (result.data.escalationId ? { id: result.data.escalationId } : undefined);
116
118
  return (0, context_1.executed)(escalation, step);
117
119
  }
118
- async function escalateStep(step, ctx) {
120
+ async function escalateStep(step, ctx, presentedId) {
119
121
  // Close the located escalation first when configured — the close doubles as
120
122
  // the condition check AND the double-scan guard (second scan finds nothing
121
123
  // to close and falls through).
122
124
  if (step.params?.closeCurrent === 'resolve') {
123
- const closed = await resolveStep({ ...step, params: { ...step.params, resolverPayload: step.params?.resolverPayload ?? {} } }, ctx);
125
+ const closed = await resolveStep({ ...step, params: { ...step.params, resolverPayload: step.params?.resolverPayload ?? {} } }, ctx, presentedId);
124
126
  if (closed === null)
125
127
  return null;
126
128
  if (closed.data?.outcome !== types_1.SCAN_OUTCOMES.EXECUTED)
127
129
  return closed;
128
130
  }
129
131
  else if (step.params?.closeCurrent === 'cancel') {
130
- const cancelled = await cancelStep(step, ctx);
132
+ const cancelled = await cancelStep(step, ctx, presentedId);
131
133
  if (cancelled === null)
132
134
  return null;
133
135
  if (cancelled.data?.outcome !== types_1.SCAN_OUTCOMES.EXECUTED)
@@ -152,9 +154,11 @@ async function escalateStep(step, ctx) {
152
154
  return created;
153
155
  return (0, context_1.executed)(created.data, step);
154
156
  }
155
- async function releaseStep(step, ctx) {
157
+ async function releaseStep(step, ctx, presentedId) {
156
158
  // Locate the caller's own claim; release-by-id re-asserts the assignee
157
159
  // inside the SDK, so a lost race resolves to 409, never a foreign release.
160
+ if (presentedId)
161
+ return releaseById(presentedId, step, ctx);
158
162
  const scope = await (0, helpers_1.getEscalationReadScope)(ctx.auth.userId);
159
163
  const readable = [...scope.allRoles, ...scope.selfRoles];
160
164
  const roles = (0, metadata_1.restrictScopeRoles)(readable, scope.global, step.query?.roles);
@@ -169,23 +173,27 @@ async function releaseStep(step, ctx) {
169
173
  });
170
174
  if (escalations.length === 0)
171
175
  return null;
176
+ return releaseById(escalations[0].id, step, ctx);
177
+ }
178
+ async function releaseById(id, step, ctx) {
172
179
  const notPrimed = await (0, grant_1.spendGrant)(ctx);
173
180
  if (notPrimed)
174
181
  return notPrimed;
175
- const result = await (0, claim_1.releaseEscalation)({ id: escalations[0].id }, ctx.auth);
182
+ const result = await (0, claim_1.releaseEscalation)({ id }, ctx.auth);
176
183
  if (result.status === 403)
177
184
  return (0, context_1.forbidden)(result.error);
178
- if (result.status === 409)
185
+ if (result.status === 409 || result.status === 404)
179
186
  return (0, context_1.conflict)(result.error);
180
187
  if (result.status !== 200)
181
188
  return result;
182
189
  return (0, context_1.executed)(result.data.escalation, step);
183
190
  }
184
191
  /**
185
- * Dispatch one CHOICE verb against an already-presented row. Unlike the step
186
- * walk (where a miss falls through to the next step), the screen showed this
187
- * exact row — so a miss answers with the truth: FORBIDDEN when the actor
188
- * holds no write scope here, CONFLICT when a concurrent actor won the race.
192
+ * Dispatch one CHOICE verb against an already-presented row. Every verb that
193
+ * writes the row writes that row by id, so a code shared by several rows
194
+ * never moves the write elsewhere. Unlike the step walk (where a miss falls
195
+ * through to the next step), a miss answers with the truth: FORBIDDEN when
196
+ * the actor holds no write scope here, CONFLICT when a concurrent actor won.
189
197
  */
190
198
  async function dispatchChoiceVerb(step, ctx, row) {
191
199
  switch (step.verb) {
@@ -195,15 +203,15 @@ async function dispatchChoiceVerb(step, ctx, row) {
195
203
  return (await (0, hold_1.holdStep)(step, ctx, row));
196
204
  case types_1.SCAN_VERBS.CLAIM:
197
205
  case types_1.SCAN_VERBS.CLAIM_SHOW_DETAIL:
198
- return (await claimStep(step, ctx)) ?? (await missReason(step, ctx, 'the item is no longer claimable'));
206
+ return (await claimStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer claimable'));
199
207
  case types_1.SCAN_VERBS.RESOLVE:
200
208
  return (await resolveStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer resolvable'));
201
209
  case types_1.SCAN_VERBS.ESCALATE:
202
- return (await escalateStep(step, ctx)) ?? (await missReason(step, ctx, 'the item already moved on'));
210
+ return (await escalateStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item already moved on'));
203
211
  case types_1.SCAN_VERBS.RELEASE:
204
- return (await releaseStep(step, ctx)) ?? (0, context_1.conflict)('no claim of yours to release');
212
+ return (await releaseStep(step, ctx, row.id)) ?? (0, context_1.conflict)('no claim of yours to release');
205
213
  case types_1.SCAN_VERBS.CANCEL:
206
- return (await cancelStep(step, ctx)) ?? (await missReason(step, ctx, 'the item is no longer cancellable'));
214
+ return (await cancelStep(step, ctx, row.id)) ?? (await missReason(step, ctx, 'the item is no longer cancellable'));
207
215
  default:
208
216
  throw new Error(`unknown choice verb "${step.verb}"`);
209
217
  }
@@ -218,7 +226,7 @@ async function missReason(step, ctx, raceMessage) {
218
226
  }
219
227
  return (0, context_1.conflict)(raceMessage);
220
228
  }
221
- async function cancelStep(step, ctx) {
229
+ async function cancelStep(step, ctx, presentedId) {
222
230
  // Claim-as-lock: the atomic claim pins the row to this caller (or extends
223
231
  // their claim), serializing concurrent double-scans before the cancel.
224
232
  const notPrimed = await (0, grant_1.spendGrant)(ctx);
@@ -229,6 +237,7 @@ async function cancelStep(step, ctx) {
229
237
  value: ctx.parsed.target,
230
238
  metadata: (0, context_1.provenance)(ctx),
231
239
  restrictRoles: step.query?.roles,
240
+ assertId: presentedId,
232
241
  }, ctx.auth);
233
242
  if (claimed.status === 404)
234
243
  return null;
package/build/index.d.ts CHANGED
@@ -12,7 +12,7 @@ export * as TaskService from './services/task';
12
12
  export * as EscalationService from './services/escalation';
13
13
  export * as ConfigService from './services/config';
14
14
  export * as UserService from './services/user';
15
- export { assertValidScheme as assertValidScanScheme, assertValidSteps as assertValidScanSteps, assertValidIdentityRule as assertValidScanIdentityRule, isValidGtin, normalizeGtin, type ScanSchemeInput, type ScanRuleInput, } from './services/scan-code';
15
+ export { assertValidScheme as assertValidScanScheme, assertValidSteps as assertValidScanSteps, assertValidIdentityRule as assertValidScanIdentityRule, isValidGtin, normalizeGtin, displayGtin, type ScanSchemeInput, type ScanRuleInput, } from './services/scan-code';
16
16
  export * as TopicService from './services/topics';
17
17
  export { seedSystemTopics, seedConfigTopics } from './services/topics/system-topics';
18
18
  export { ltConfig } from './modules/ltconfig';
package/build/index.js CHANGED
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
- exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = void 0;
39
+ exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.displayGtin = exports.normalizeGtin = exports.isValidGtin = exports.assertValidScanIdentityRule = exports.assertValidScanSteps = exports.assertValidScanScheme = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
+ exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = void 0;
41
41
  const config_1 = require("./modules/config");
42
42
  const logger_1 = require("./lib/logger");
43
43
  const midnight_1 = require("./themes/midnight");
@@ -76,6 +76,7 @@ Object.defineProperty(exports, "assertValidScanSteps", { enumerable: true, get:
76
76
  Object.defineProperty(exports, "assertValidScanIdentityRule", { enumerable: true, get: function () { return scan_code_1.assertValidIdentityRule; } });
77
77
  Object.defineProperty(exports, "isValidGtin", { enumerable: true, get: function () { return scan_code_1.isValidGtin; } });
78
78
  Object.defineProperty(exports, "normalizeGtin", { enumerable: true, get: function () { return scan_code_1.normalizeGtin; } });
79
+ Object.defineProperty(exports, "displayGtin", { enumerable: true, get: function () { return scan_code_1.displayGtin; } });
79
80
  exports.TopicService = __importStar(require("./services/topics"));
80
81
  var system_topics_1 = require("./services/topics/system-topics");
81
82
  Object.defineProperty(exports, "seedSystemTopics", { enumerable: true, get: function () { return system_topics_1.seedSystemTopics; } });
@@ -213,6 +213,7 @@ export declare function createClient(options?: LTClientOptions): {
213
213
  metadata?: Record<string, any>;
214
214
  provisionIfAbsent?: import("../api/escalations/helpers").ProvisionIfAbsent;
215
215
  restrictRoles?: string[];
216
+ assertId?: string;
216
217
  }, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
217
218
  resolveByMetadata: (input: {
218
219
  key: string;
@@ -0,0 +1,10 @@
1
+ import type { ClaimResult } from './types';
2
+ /**
3
+ * Claims one named row, the same claim `claimByMetadata` makes on the row it
4
+ * picks: pending, the facet still matches, the role is allowed, and no live
5
+ * claim by someone else. One statement; a miss writes nothing.
6
+ * $1=filter $2=assignee $3=minutes $4=roles $5=metadata patch $6=id
7
+ */
8
+ export declare const CLAIM_ASSERTED = "WITH target AS MATERIALIZED (\n SELECT id, assigned_to AS prior_assigned_to FROM public.hmsh_escalations\n WHERE id = $6\n AND metadata @> $1::jsonb\n AND ($4::text[] IS NULL OR role = ANY($4::text[]))\n AND status = 'pending'\n AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW() OR assigned_to = $2)\n FOR UPDATE SKIP LOCKED\n)\nUPDATE public.hmsh_escalations e\nSET assigned_to = $2,\n claimed_at = NOW(),\n claim_expires_at = NOW() + ($3 * INTERVAL '1 minute'),\n assigned_until = NOW() + ($3 * INTERVAL '1 minute'),\n metadata = CASE WHEN $5::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $5::jsonb\n ELSE e.metadata END,\n updated_at = NOW()\nFROM target WHERE e.id = target.id\nRETURNING e.*, target.prior_assigned_to\n";
9
+ /** Claim the row `id` when it still carries `key = value`; null when it does not. */
10
+ export declare function claimAssertedByMetadata(id: string, key: string, value: string, userId: string, durationMinutes?: number, metadata?: Record<string, any>, allowedRoles?: string[] | null): Promise<ClaimResult | null>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLAIM_ASSERTED = void 0;
4
+ exports.claimAssertedByMetadata = claimAssertedByMetadata;
5
+ const db_1 = require("../../lib/db");
6
+ const escalation_wire_1 = require("../../lib/events/escalation-wire");
7
+ const uuid_1 = require("../../lib/uuid");
8
+ const client_1 = require("./client");
9
+ const crud_1 = require("./crud");
10
+ const map_1 = require("./map");
11
+ /**
12
+ * Claims one named row, the same claim `claimByMetadata` makes on the row it
13
+ * picks: pending, the facet still matches, the role is allowed, and no live
14
+ * claim by someone else. One statement; a miss writes nothing.
15
+ * $1=filter $2=assignee $3=minutes $4=roles $5=metadata patch $6=id
16
+ */
17
+ exports.CLAIM_ASSERTED = `\
18
+ WITH target AS MATERIALIZED (
19
+ SELECT id, assigned_to AS prior_assigned_to FROM public.hmsh_escalations
20
+ WHERE id = $6
21
+ AND metadata @> $1::jsonb
22
+ AND ($4::text[] IS NULL OR role = ANY($4::text[]))
23
+ AND status = 'pending'
24
+ AND (assigned_to IS NULL OR assigned_until IS NULL OR assigned_until <= NOW() OR assigned_to = $2)
25
+ FOR UPDATE SKIP LOCKED
26
+ )
27
+ UPDATE public.hmsh_escalations e
28
+ SET assigned_to = $2,
29
+ claimed_at = NOW(),
30
+ claim_expires_at = NOW() + ($3 * INTERVAL '1 minute'),
31
+ assigned_until = NOW() + ($3 * INTERVAL '1 minute'),
32
+ metadata = CASE WHEN $5::jsonb IS NOT NULL
33
+ THEN COALESCE(e.metadata, '{}'::jsonb) || $5::jsonb
34
+ ELSE e.metadata END,
35
+ updated_at = NOW()
36
+ FROM target WHERE e.id = target.id
37
+ RETURNING e.*, target.prior_assigned_to
38
+ `;
39
+ /** Claim the row `id` when it still carries `key = value`; null when it does not. */
40
+ async function claimAssertedByMetadata(id, key, value, userId, durationMinutes = 30, metadata, allowedRoles) {
41
+ if (!(0, uuid_1.isUuid)(id))
42
+ return null;
43
+ await (0, client_1.ensureEscalationCompatView)();
44
+ const { rows } = await (0, db_1.getPool)().query(exports.CLAIM_ASSERTED, [
45
+ JSON.stringify({ [key]: value }), userId, durationMinutes,
46
+ allowedRoles ?? null, metadata ? JSON.stringify(metadata) : null, id,
47
+ ]);
48
+ if (rows.length === 0)
49
+ return null;
50
+ const { prior_assigned_to: prior, ...entry } = rows[0];
51
+ const escalation = (0, map_1.toEscalationRecord)(entry);
52
+ (0, crud_1.publishEscalationChange)({
53
+ type: 'escalation.claimed',
54
+ source: 'service',
55
+ workflowId: escalation.workflow_id || '',
56
+ workflowName: escalation.workflow_type || '',
57
+ taskQueue: escalation.task_queue || '',
58
+ escalationId: escalation.id,
59
+ role: escalation.role,
60
+ status: 'claimed',
61
+ data: (0, escalation_wire_1.escalationEventData)(escalation),
62
+ });
63
+ return { escalation, isExtension: prior === userId };
64
+ }
@@ -2,7 +2,9 @@ import type { ClaimedGroup, FacetQuery, GroupSummary, LTEscalationRecord } from
2
2
  /** Ensure the compat view + the origin_id index exist before the first query. */
3
3
  export declare function ensureFacetReady(): Promise<void>;
4
4
  /** Item-level faceted search — filter/sort over top-level columns and metadata facets. */
5
- export declare function searchByFacets(query: FacetQuery): Promise<{
5
+ export declare function searchByFacets(query: FacetQuery, opts?: {
6
+ total?: boolean;
7
+ }): Promise<{
6
8
  escalations: LTEscalationRecord[];
7
9
  total: number;
8
10
  }>;
@@ -45,7 +45,7 @@ function ensureFacetReady() {
45
45
  }
46
46
  // ── Reads ────────────────────────────────────────────────────────────────────
47
47
  /** Item-level faceted search — filter/sort over top-level columns and metadata facets. */
48
- async function searchByFacets(query) {
48
+ async function searchByFacets(query, opts = {}) {
49
49
  await ensureFacetReady();
50
50
  const pool = (0, db_1.getPool)();
51
51
  const params = [];
@@ -55,9 +55,13 @@ async function searchByFacets(query) {
55
55
  const offset = query.offset ?? 0;
56
56
  const [rows, count] = await Promise.all([
57
57
  pool.query(`SELECT * FROM public.lt_escalations WHERE ${where} ORDER BY ${order} LIMIT $${params.length + 1} OFFSET $${params.length + 2}`, [...params, limit, offset]),
58
- pool.query(`SELECT count(*)::int AS total FROM public.lt_escalations WHERE ${where}`, params),
58
+ // A caller that only picks among a few rows skips the count.
59
+ opts.total === false
60
+ ? null
61
+ : pool.query(`SELECT count(*)::int AS total FROM public.lt_escalations WHERE ${where}`, params),
59
62
  ]);
60
- return { escalations: (0, map_1.toEscalationRecords)(rows.rows), total: count.rows[0]?.total ?? 0 };
63
+ const escalations = (0, map_1.toEscalationRecords)(rows.rows);
64
+ return { escalations, total: count ? count.rows[0]?.total ?? 0 : escalations.length };
61
65
  }
62
66
  /**
63
67
  * Order-level view of the pond — what a batched dispatcher reads to page by
@@ -1,5 +1,6 @@
1
1
  export * from './types';
2
2
  export * from './crud';
3
+ export { claimAssertedByMetadata } from './claim-asserted';
3
4
  export * from './batch';
4
5
  export * from './accumulate';
5
6
  export * from './bulk';
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = void 0;
17
+ exports.AnalyticsInputError = exports.resetAnalyticsCaches = exports.resolveEntitySystem = exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.countByFacets = exports.searchGroups = exports.searchByFacets = exports.ensureFacetReady = exports.ensureEscalationCompatView = exports.claimAssertedByMetadata = void 0;
18
18
  __exportStar(require("./types"), exports);
19
19
  __exportStar(require("./crud"), exports);
20
+ var claim_asserted_1 = require("./claim-asserted");
21
+ Object.defineProperty(exports, "claimAssertedByMetadata", { enumerable: true, get: function () { return claim_asserted_1.claimAssertedByMetadata; } });
20
22
  __exportStar(require("./batch"), exports);
21
23
  __exportStar(require("./accumulate"), exports);
22
24
  __exportStar(require("./bulk"), exports);
@@ -1,4 +1,4 @@
1
- import type { EscalationLookupRef } from '../../types/escalation';
1
+ import { type EscalationLookupRef } from '../../types/escalation';
2
2
  interface KnowledgeSnapshot {
3
3
  data: Record<string, unknown>;
4
4
  tags: string[];
@@ -6,24 +6,36 @@ interface KnowledgeSnapshot {
6
6
  export interface ResolvedLookup {
7
7
  domain: string;
8
8
  key: string;
9
- version: number;
9
+ /** The edition served; null when a current ref found no edition. */
10
+ version: number | null;
11
+ /** The ref follows the newest edition rather than pinning one. */
12
+ current?: true;
10
13
  as?: string;
11
14
  data: Record<string, unknown> | null;
12
15
  missing?: boolean;
13
16
  }
14
17
  /** The immutable snapshot at (domain, key, version), or null when absent. */
15
18
  export declare function getKnowledgeSnapshot(domain: string, key: string, version: number): Promise<KnowledgeSnapshot | null>;
19
+ /**
20
+ * The edition a ref names: its pin, or for a current ref the newest edition
21
+ * (the newest at `asOf` when given, so a closed row reads what was current
22
+ * when it closed). Null when there is none.
23
+ */
24
+ export declare function resolveRefEdition(ref: EscalationLookupRef, asOf?: string | null): Promise<{
25
+ version: number;
26
+ snapshot: KnowledgeSnapshot;
27
+ } | null>;
16
28
  /**
17
29
  * Resolve a metadata `lookups` array into the form-context `lookup` domain:
18
30
  * { [as ?? key]: data }. Returns null when there is nothing to resolve, so
19
31
  * escalations without refs cost zero SQL. Missing snapshots are omitted —
20
32
  * interpolated selects then fail closed rather than render the wrong list.
21
33
  */
22
- export declare function resolveLookupContext(refs: unknown): Promise<Record<string, unknown> | null>;
34
+ export declare function resolveLookupContext(refs: unknown, asOf?: string | null): Promise<Record<string, unknown> | null>;
23
35
  /**
24
36
  * Full per-ref resolution for the lookups endpoint: every ref answers, with
25
37
  * `missing: true` marking a pin that has no snapshot — fail-visible per ref
26
38
  * without failing the batch.
27
39
  */
28
- export declare function resolveLookupRefs(refs: EscalationLookupRef[]): Promise<ResolvedLookup[]>;
40
+ export declare function resolveLookupRefs(refs: EscalationLookupRef[], asOf?: string | null): Promise<ResolvedLookup[]>;
29
41
  export {};
@@ -1,21 +1,30 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getKnowledgeSnapshot = getKnowledgeSnapshot;
4
+ exports.resolveRefEdition = resolveRefEdition;
4
5
  exports.resolveLookupContext = resolveLookupContext;
5
6
  exports.resolveLookupRefs = resolveLookupRefs;
6
7
  /**
7
8
  * Lookup snapshot cache — keeps escalation lookup resolution off the SQL hot
8
- * path. A lookup ref pins {domain, key, version}; the snapshot behind it is
9
- * immutable by design, so entries cache indefinitely under an LRU bound.
10
- * Thousands of escalations sharing the same refs resolve from memory after
11
- * the first read. Missing snapshots are never cached — a later seed or
12
- * republish must become visible.
9
+ * path. An edition {domain, key, version} is immutable, so snapshots cache
10
+ * indefinitely under an LRU bound. A pinned ref resolves from memory after
11
+ * the first read; a current ref costs one indexed read to learn which
12
+ * edition is newest, then shares the same cache. Missing snapshots are never
13
+ * cached — a later seed or republish must become visible.
13
14
  */
14
15
  const db_1 = require("../../lib/db");
16
+ const escalation_1 = require("../../types/escalation");
15
17
  const sql_1 = require("./sql");
16
18
  const SNAPSHOT_CACHE_MAX_ENTRIES = 256;
17
19
  // Map preserves insertion order — delete+set on read keeps it LRU.
18
20
  const snapshotCache = new Map();
21
+ function remember(cacheKey, snapshot) {
22
+ snapshotCache.set(cacheKey, snapshot);
23
+ while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
24
+ const oldest = snapshotCache.keys().next().value;
25
+ snapshotCache.delete(oldest);
26
+ }
27
+ }
19
28
  /** The immutable snapshot at (domain, key, version), or null when absent. */
20
29
  async function getKnowledgeSnapshot(domain, key, version) {
21
30
  const cacheKey = `${domain} ${key} ${version}`;
@@ -33,13 +42,35 @@ async function getKnowledgeSnapshot(domain, key, version) {
33
42
  data: rows[0].data ?? {},
34
43
  tags: rows[0].tags ?? [],
35
44
  };
36
- snapshotCache.set(cacheKey, snapshot);
37
- while (snapshotCache.size > SNAPSHOT_CACHE_MAX_ENTRIES) {
38
- const oldest = snapshotCache.keys().next().value;
39
- snapshotCache.delete(oldest);
40
- }
45
+ remember(cacheKey, snapshot);
41
46
  return snapshot;
42
47
  }
48
+ /**
49
+ * The edition a ref names: its pin, or for a current ref the newest edition
50
+ * (the newest at `asOf` when given, so a closed row reads what was current
51
+ * when it closed). Null when there is none.
52
+ */
53
+ async function resolveRefEdition(ref, asOf) {
54
+ if (!(0, escalation_1.isCurrentLookupRef)(ref)) {
55
+ const version = ref.version;
56
+ const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, version);
57
+ return snapshot ? { version, snapshot } : null;
58
+ }
59
+ const { rows } = await (0, db_1.getPool)().query(sql_1.GET_LATEST_KNOWLEDGE_VERSION, [ref.domain, ref.key, asOf ?? null]);
60
+ if (!rows[0])
61
+ return null;
62
+ const version = Number(rows[0].version);
63
+ const cacheKey = `${ref.domain} ${ref.key} ${version}`;
64
+ const cached = snapshotCache.get(cacheKey);
65
+ if (cached)
66
+ return { version, snapshot: cached };
67
+ const snapshot = {
68
+ data: rows[0].data ?? {},
69
+ tags: rows[0].tags ?? [],
70
+ };
71
+ remember(cacheKey, snapshot);
72
+ return { version, snapshot };
73
+ }
43
74
  /** Structural check for one ref — malformed entries in stored metadata are skipped, not fatal. */
44
75
  function isLookupRef(ref) {
45
76
  if (!ref || typeof ref !== 'object')
@@ -47,7 +78,7 @@ function isLookupRef(ref) {
47
78
  const r = ref;
48
79
  return typeof r.domain === 'string' && r.domain.length > 0
49
80
  && typeof r.key === 'string' && r.key.length > 0
50
- && typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1
81
+ && ((0, escalation_1.isCurrentLookupRef)(r) || (typeof r.version === 'number' && Number.isInteger(r.version) && r.version >= 1))
51
82
  && (r.as === undefined || (typeof r.as === 'string' && r.as.length > 0));
52
83
  }
53
84
  /**
@@ -56,7 +87,7 @@ function isLookupRef(ref) {
56
87
  * escalations without refs cost zero SQL. Missing snapshots are omitted —
57
88
  * interpolated selects then fail closed rather than render the wrong list.
58
89
  */
59
- async function resolveLookupContext(refs) {
90
+ async function resolveLookupContext(refs, asOf) {
60
91
  if (!Array.isArray(refs) || refs.length === 0)
61
92
  return null;
62
93
  const valid = refs.filter(isLookupRef);
@@ -64,9 +95,9 @@ async function resolveLookupContext(refs) {
64
95
  return null;
65
96
  const ctx = {};
66
97
  for (const ref of valid) {
67
- const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, ref.version);
68
- if (snapshot)
69
- ctx[ref.as ?? ref.key] = snapshot.data;
98
+ const edition = await resolveRefEdition(ref, asOf);
99
+ if (edition)
100
+ ctx[ref.as ?? ref.key] = edition.snapshot.data;
70
101
  }
71
102
  return ctx;
72
103
  }
@@ -75,19 +106,21 @@ async function resolveLookupContext(refs) {
75
106
  * `missing: true` marking a pin that has no snapshot — fail-visible per ref
76
107
  * without failing the batch.
77
108
  */
78
- async function resolveLookupRefs(refs) {
109
+ async function resolveLookupRefs(refs, asOf) {
79
110
  const resolved = [];
80
111
  for (const ref of refs) {
81
112
  if (!isLookupRef(ref))
82
113
  continue;
83
- const snapshot = await getKnowledgeSnapshot(ref.domain, ref.key, ref.version);
114
+ const current = (0, escalation_1.isCurrentLookupRef)(ref);
115
+ const edition = await resolveRefEdition(ref, asOf);
84
116
  resolved.push({
85
117
  domain: ref.domain,
86
118
  key: ref.key,
87
- version: ref.version,
119
+ version: edition?.version ?? (current ? null : ref.version),
120
+ ...(current ? { current: true } : {}),
88
121
  ...(ref.as ? { as: ref.as } : {}),
89
- data: snapshot ? snapshot.data : null,
90
- ...(snapshot ? {} : { missing: true }),
122
+ data: edition ? edition.snapshot.data : null,
123
+ ...(edition ? {} : { missing: true }),
91
124
  });
92
125
  }
93
126
  return resolved;
@@ -1,6 +1,7 @@
1
- import type { EscalationLookupRef } from '../../types/escalation';
1
+ import { type EscalationLookupRef } from '../../types/escalation';
2
2
  /**
3
- * One message per ref whose pinned edition does not exist, naming what does.
3
+ * One message per ref with no edition behind it (a pin that does not exist,
4
+ * or a current ref to an entry with no editions), naming what does.
4
5
  * Shape is the caller's job (assertLookupRefs); this answers the second
5
6
  * question a saver has: is there an edition behind the pin.
6
7
  */
@@ -2,25 +2,27 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.describeMissingLookupRefs = describeMissingLookupRefs;
4
4
  const db_1 = require("../../lib/db");
5
+ const escalation_1 = require("../../types/escalation");
5
6
  const lookup_cache_1 = require("./lookup-cache");
6
7
  const sql_1 = require("./sql");
7
8
  /**
8
- * One message per ref whose pinned edition does not exist, naming what does.
9
+ * One message per ref with no edition behind it (a pin that does not exist,
10
+ * or a current ref to an entry with no editions), naming what does.
9
11
  * Shape is the caller's job (assertLookupRefs); this answers the second
10
12
  * question a saver has: is there an edition behind the pin.
11
13
  */
12
14
  async function describeMissingLookupRefs(refs) {
13
15
  const problems = [];
14
16
  for (const ref of refs) {
15
- const snapshot = await (0, lookup_cache_1.getKnowledgeSnapshot)(ref.domain, ref.key, ref.version);
16
- if (snapshot)
17
+ if (await (0, lookup_cache_1.resolveRefEdition)(ref))
17
18
  continue;
18
19
  const { rows } = await (0, db_1.getPool)().query(sql_1.LIST_KNOWLEDGE_VERSIONS, [ref.domain, ref.key]);
19
20
  const versions = rows.map((r) => Number(r.version)).sort((a, b) => a - b);
20
21
  const where = versions.length
21
22
  ? `editions: ${versions.map((v) => `v${v}`).join(', ')}`
22
23
  : `no knowledge entry ${ref.domain}/${ref.key}`;
23
- problems.push(`Lookup ref ${ref.domain}/${ref.key} v${ref.version} names no edition (${where})`);
24
+ const named = (0, escalation_1.isCurrentLookupRef)(ref) ? 'current' : `v${ref.version}`;
25
+ problems.push(`Lookup ref ${ref.domain}/${ref.key} ${named} names no edition (${where})`);
24
26
  }
25
27
  return problems;
26
28
  }
@@ -1,2 +1,4 @@
1
1
  export declare const GET_KNOWLEDGE_VERSION = "\n SELECT domain, key, version, data, tags, change_summary, created_at\n FROM lt_knowledge_versions\n WHERE domain = $1 AND key = $2 AND version = $3";
2
2
  export declare const LIST_KNOWLEDGE_VERSIONS = "\n SELECT v.version, v.change_summary, v.created_at,\n (v.version = k.current_version) AS is_current\n FROM lt_knowledge_versions v\n JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key\n WHERE v.domain = $1 AND v.key = $2\n ORDER BY v.version DESC";
3
+ /** The newest edition, or the newest created at or before $3 when it is set. */
4
+ export declare const GET_LATEST_KNOWLEDGE_VERSION = "\n SELECT version, data, tags\n FROM lt_knowledge_versions\n WHERE domain = $1 AND key = $2\n AND ($3::timestamptz IS NULL OR created_at <= $3)\n ORDER BY version DESC\n LIMIT 1";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.LIST_KNOWLEDGE_VERSIONS = exports.GET_KNOWLEDGE_VERSION = void 0;
3
+ exports.GET_LATEST_KNOWLEDGE_VERSION = exports.LIST_KNOWLEDGE_VERSIONS = exports.GET_KNOWLEDGE_VERSION = void 0;
4
4
  exports.GET_KNOWLEDGE_VERSION = `
5
5
  SELECT domain, key, version, data, tags, change_summary, created_at
6
6
  FROM lt_knowledge_versions
@@ -12,3 +12,11 @@ exports.LIST_KNOWLEDGE_VERSIONS = `
12
12
  JOIN lt_knowledge k ON k.domain = v.domain AND k.key = v.key
13
13
  WHERE v.domain = $1 AND v.key = $2
14
14
  ORDER BY v.version DESC`;
15
+ /** The newest edition, or the newest created at or before $3 when it is set. */
16
+ exports.GET_LATEST_KNOWLEDGE_VERSION = `
17
+ SELECT version, data, tags
18
+ FROM lt_knowledge_versions
19
+ WHERE domain = $1 AND key = $2
20
+ AND ($3::timestamptz IS NULL OR created_at <= $3)
21
+ ORDER BY version DESC
22
+ LIMIT 1`;
@@ -175,7 +175,7 @@ function registerHumanQueueTools(server) {
175
175
  };
176
176
  }
177
177
  const refs = (0, lookups_1.readLookupRefs)(escalation.envelope);
178
- const lookups = refs.length > 0 ? await (0, knowledge_1.resolveLookupRefs)(refs) : [];
178
+ const lookups = refs.length > 0 ? await (0, knowledge_1.resolveLookupRefs)(refs, (0, lookups_1.lookupAsOf)(escalation)) : [];
179
179
  return {
180
180
  content: [{
181
181
  type: 'text',
@@ -2,10 +2,11 @@ import type { Types } from '@hotmeshio/hotmesh';
2
2
  import { type AccumulateConfig, type AccumulatorResult, type EscalationLookupRef } from '../../types/escalation';
3
3
  /**
4
4
  * HotMesh's escalation config plus long-tail sugar. `schemaVersion` pins the
5
- * role form version (lt_role_schemas) the resolve UI renders; `lookups` pins
6
- * versioned knowledge editions the form may read (the `lookup.*` context
7
- * domain — see docs/hitl/lookups.md). Both are compile-time LITERALS the
8
- * workflow author sets, folded before the config reaches the engine:
5
+ * role form version (lt_role_schemas) the resolve UI renders; `lookups` names
6
+ * the knowledge entries the form may read (the `lookup.*` context domain, see
7
+ * docs/hitl/lookups.md), each pinned to an edition or following the current
8
+ * one. Both are LITERALS the workflow author sets, folded before the config
9
+ * reaches the engine:
9
10
  * schemaVersion into the GIN-indexed metadata (a queryable facet), lookups
10
11
  * into the unindexed envelope (form plumbing, never a facet). Folding is a
11
12
  * pure transform — no query, no activity — so a pinned `conditional` costs
@@ -57,17 +58,19 @@ export type ConditionEscalationConfig = Types.ConditionQueueConfig & {
57
58
  * });
58
59
  * ```
59
60
  *
60
- * **Pin versioned knowledge lookups — option lists the form reads.** Each ref
61
- * names an immutable knowledge edition; the resolve UI fetches them once and
62
- * the form addresses the content as the `lookup.*` context domain
63
- * (`x-lt-options: "lookup.materials.items"`). Evolve the list by writing the
64
- * entry (a new version mints automatically) and repinning the literal here.
61
+ * **Knowledge lookups — option lists the form reads.** Each ref names a
62
+ * knowledge entry; the resolve UI fetches it and the form addresses the
63
+ * content as the `lookup.*` context domain (`x-lt-options:
64
+ * "lookup.materials.items"`). Leave `version` out (or set `'current'`) and
65
+ * the form reads the newest edition, so a long-open row sees today's list
66
+ * and a closed row the list current when it closed. Pin a `version` when the
67
+ * form must read one exact edition.
65
68
  *
66
69
  * ```typescript
67
70
  * const decision = await conditional<PickerResolverV1>(signalId, {
68
71
  * role: 'catalog-picker',
69
72
  * description: instructions,
70
- * lookups: [{ domain: 'catalog', key: 'materials', version: 2 }],
73
+ * lookups: [{ domain: 'catalog', key: 'materials' }],
71
74
  * });
72
75
  * ```
73
76
  *