@hotmeshio/long-tail 0.22.1 → 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 (331) hide show
  1. package/build/api/escalations/accumulate.js +38 -19
  2. package/build/api/escalations/lookups.d.ts +9 -2
  3. package/build/api/escalations/lookups.js +15 -3
  4. package/build/api/escalations/metadata.d.ts +2 -0
  5. package/build/api/escalations/metadata.js +9 -0
  6. package/build/api/escalations/resolve-batch.js +18 -11
  7. package/build/api/roles.js +4 -0
  8. package/build/api/scan-codes/badge-policy.d.ts +10 -0
  9. package/build/api/scan-codes/badge-policy.js +72 -0
  10. package/build/api/scan-codes/choice.js +16 -10
  11. package/build/api/scan-codes/context.d.ts +45 -1
  12. package/build/api/scan-codes/context.js +51 -3
  13. package/build/api/scan-codes/execute.js +73 -35
  14. package/build/api/scan-codes/grant.d.ts +27 -0
  15. package/build/api/scan-codes/grant.js +67 -0
  16. package/build/api/scan-codes/hold.d.ts +10 -0
  17. package/build/api/scan-codes/hold.js +98 -0
  18. package/build/api/scan-codes/identity.d.ts +5 -2
  19. package/build/api/scan-codes/identity.js +26 -8
  20. package/build/api/scan-codes/locate.js +4 -0
  21. package/build/api/scan-codes/present.d.ts +1 -1
  22. package/build/api/scan-codes/present.js +43 -0
  23. package/build/api/scan-codes/subject.d.ts +15 -0
  24. package/build/api/scan-codes/subject.js +68 -0
  25. package/build/api/scan-codes/verb-accumulate.d.ts +24 -0
  26. package/build/api/scan-codes/verb-accumulate.js +151 -0
  27. package/build/api/scan-codes/verb-fill.d.ts +6 -0
  28. package/build/api/scan-codes/verb-fill.js +155 -0
  29. package/build/api/scan-codes/verb-into-subject.d.ts +12 -0
  30. package/build/api/scan-codes/verb-into-subject.js +157 -0
  31. package/build/api/scan-codes/verbs-subject.d.ts +33 -0
  32. package/build/api/scan-codes/verbs-subject.js +247 -0
  33. package/build/api/scan-codes/verbs.d.ts +11 -29
  34. package/build/api/scan-codes/verbs.js +51 -131
  35. package/build/index.d.ts +1 -0
  36. package/build/index.js +9 -2
  37. package/build/lib/db/schemas/037_scan_gtin_and_subject_grants.sql +27 -0
  38. package/build/routes/escalations/acting.d.ts +5 -0
  39. package/build/routes/escalations/acting.js +8 -1
  40. package/build/routes/scan-codes.js +3 -0
  41. package/build/sdk/index.d.ts +1 -0
  42. package/build/services/escalation/claim-asserted.d.ts +10 -0
  43. package/build/services/escalation/claim-asserted.js +64 -0
  44. package/build/services/escalation/facets.d.ts +3 -1
  45. package/build/services/escalation/facets.js +7 -3
  46. package/build/services/escalation/index.d.ts +1 -0
  47. package/build/services/escalation/index.js +3 -1
  48. package/build/services/iam/acting-identity.d.ts +29 -4
  49. package/build/services/iam/acting-identity.js +60 -17
  50. package/build/services/iam/ephemeral.d.ts +21 -0
  51. package/build/services/iam/ephemeral.js +32 -1
  52. package/build/services/iam/sql.d.ts +10 -0
  53. package/build/services/iam/sql.js +32 -3
  54. package/build/services/knowledge/lookup-cache.d.ts +16 -4
  55. package/build/services/knowledge/lookup-cache.js +53 -20
  56. package/build/services/knowledge/lookup-refs.d.ts +3 -2
  57. package/build/services/knowledge/lookup-refs.js +6 -4
  58. package/build/services/knowledge/sql.d.ts +2 -0
  59. package/build/services/knowledge/sql.js +9 -1
  60. package/build/services/mcp/server-tools.js +1 -1
  61. package/build/services/orchestrator/condition.d.ts +13 -10
  62. package/build/services/orchestrator/condition.js +8 -6
  63. package/build/services/role/badge-grant.d.ts +5 -0
  64. package/build/services/role/badge-grant.js +36 -0
  65. package/build/services/role/seed.js +5 -0
  66. package/build/services/role/types.d.ts +14 -0
  67. package/build/services/role/types.js +5 -0
  68. package/build/services/scan-code/index.d.ts +3 -2
  69. package/build/services/scan-code/index.js +8 -1
  70. package/build/services/scan-code/parse.d.ts +23 -20
  71. package/build/services/scan-code/parse.js +45 -90
  72. package/build/services/scan-code/read.js +1 -0
  73. package/build/services/scan-code/sql.d.ts +3 -3
  74. package/build/services/scan-code/sql.js +11 -8
  75. package/build/services/scan-code/validate-facts.d.ts +5 -0
  76. package/build/services/scan-code/validate-facts.js +24 -0
  77. package/build/services/scan-code/validate-query.d.ts +8 -0
  78. package/build/services/scan-code/validate-query.js +36 -0
  79. package/build/services/scan-code/validate-subject.d.ts +7 -0
  80. package/build/services/scan-code/validate-subject.js +185 -0
  81. package/build/services/scan-code/validate.d.ts +7 -0
  82. package/build/services/scan-code/validate.js +103 -18
  83. package/build/services/scan-code/write.d.ts +1 -0
  84. package/build/services/scan-code/write.js +9 -3
  85. package/build/shared/form-validation/field-validator.js +4 -0
  86. package/build/shared/form-validation/index.d.ts +1 -0
  87. package/build/shared/form-validation/index.js +1 -0
  88. package/build/shared/form-validation/x-lt-scan.d.ts +52 -0
  89. package/build/shared/form-validation/x-lt-scan.js +166 -0
  90. package/build/shared/scan-code/gtin.d.ts +11 -0
  91. package/build/shared/scan-code/gtin.js +38 -0
  92. package/build/shared/scan-code/index.d.ts +2 -0
  93. package/build/shared/scan-code/index.js +11 -0
  94. package/build/shared/scan-code/parse.d.ts +46 -0
  95. package/build/shared/scan-code/parse.js +133 -0
  96. package/build/system/mcp-servers/admin/scan-codes.js +10 -4
  97. package/build/system/mcp-servers/admin/schemas.d.ts +939 -28
  98. package/build/system/mcp-servers/admin/schemas.js +72 -6
  99. package/build/system/mcp-servers/human-queue-schemas.d.ts +6 -6
  100. package/build/system/seed/tool-manifests-admin.d.ts +202 -1
  101. package/build/system/seed/tool-manifests-admin.js +2 -2
  102. package/build/tsconfig.tsbuildinfo +1 -1
  103. package/build/types/escalation.d.ts +16 -8
  104. package/build/types/escalation.js +18 -7
  105. package/build/types/index.d.ts +4 -4
  106. package/build/types/index.js +10 -1
  107. package/build/types/scan-code/constants.d.ts +182 -0
  108. package/build/types/{scan-code.js → scan-code/constants.js} +72 -11
  109. package/build/types/scan-code/index.d.ts +3 -0
  110. package/build/types/scan-code/index.js +17 -0
  111. package/build/types/scan-code/response.d.ts +145 -0
  112. package/build/types/scan-code/response.js +2 -0
  113. package/build/types/scan-code/rule.d.ts +229 -0
  114. package/build/types/scan-code/rule.js +2 -0
  115. package/build/types/startup.d.ts +3 -1
  116. package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js → AdminDashboard-hI5-kKpL.js} +2 -2
  117. package/dashboard/dist/assets/{AdminDashboard-BbWve-Ax.js.map → AdminDashboard-hI5-kKpL.js.map} +1 -1
  118. package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js → AgentConfigPage-DetU4HZe.js} +2 -2
  119. package/dashboard/dist/assets/{AgentConfigPage-M-9eTKhP.js.map → AgentConfigPage-DetU4HZe.js.map} +1 -1
  120. package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js → AgentDetailPage-DrGXo8KQ.js} +3 -3
  121. package/dashboard/dist/assets/{AgentDetailPage-CsakSlx5.js.map → AgentDetailPage-DrGXo8KQ.js.map} +1 -1
  122. package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js → AgentsPage-D4md5BzM.js} +2 -2
  123. package/dashboard/dist/assets/{AgentsPage-Cj_cRTT1.js.map → AgentsPage-D4md5BzM.js.map} +1 -1
  124. package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js → AvailableEscalationsPage-B2bS2ZJy.js} +2 -2
  125. package/dashboard/dist/assets/{AvailableEscalationsPage-BXJmMBM1.js.map → AvailableEscalationsPage-B2bS2ZJy.js.map} +1 -1
  126. package/dashboard/dist/assets/{BotPicker-CGB16rYU.js → BotPicker-BXtey255.js} +2 -2
  127. package/dashboard/dist/assets/{BotPicker-CGB16rYU.js.map → BotPicker-BXtey255.js.map} +1 -1
  128. package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js → BulkAssignModal-CSL_PeZv.js} +2 -2
  129. package/dashboard/dist/assets/{BulkAssignModal-MjxcU7N1.js.map → BulkAssignModal-CSL_PeZv.js.map} +1 -1
  130. package/dashboard/dist/assets/CapabilitiesPage-5scufTHW.js +2 -0
  131. package/dashboard/dist/assets/{CapabilitiesPage-BxadotXn.js.map → CapabilitiesPage-5scufTHW.js.map} +1 -1
  132. package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js → CollapsibleSection-DjjDGxP_.js} +2 -2
  133. package/dashboard/dist/assets/{CollapsibleSection-BBNpP-6h.js.map → CollapsibleSection-DjjDGxP_.js.map} +1 -1
  134. package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js → ConfirmDeleteModal-DJSmsHQM.js} +2 -2
  135. package/dashboard/dist/assets/{ConfirmDeleteModal-D_kAbT_D.js.map → ConfirmDeleteModal-DJSmsHQM.js.map} +1 -1
  136. package/dashboard/dist/assets/CountdownTimer-C5ZRYPfF.js +2 -0
  137. package/dashboard/dist/assets/{CountdownTimer-CI_JOAvk.js.map → CountdownTimer-C5ZRYPfF.js.map} +1 -1
  138. package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js → CredentialsPage-CV6e60yC.js} +2 -2
  139. package/dashboard/dist/assets/{CredentialsPage-C9OA1Q2J.js.map → CredentialsPage-CV6e60yC.js.map} +1 -1
  140. package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js → CronLabel-CnqhqW0B.js} +2 -2
  141. package/dashboard/dist/assets/{CronLabel-sxLLBf2I.js.map → CronLabel-CnqhqW0B.js.map} +1 -1
  142. package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js → ElapsedCell-C1IOn-tj.js} +2 -2
  143. package/dashboard/dist/assets/{ElapsedCell-jH9m8Dgl.js.map → ElapsedCell-C1IOn-tj.js.map} +1 -1
  144. package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js → EntityTimelinePanel-Dz6Liig4.js} +2 -2
  145. package/dashboard/dist/assets/{EntityTimelinePanel-Dl3Nr2kk.js.map → EntityTimelinePanel-Dz6Liig4.js.map} +1 -1
  146. package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js → EscalationListSchemaPage-bgdmLmrh.js} +3 -3
  147. package/dashboard/dist/assets/{EscalationListSchemaPage-DAK6It5J.js.map → EscalationListSchemaPage-bgdmLmrh.js.map} +1 -1
  148. package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js → EscalationListView-CrlD3ZGt.js} +2 -2
  149. package/dashboard/dist/assets/{EscalationListView-CAHbdxKR.js.map → EscalationListView-CrlD3ZGt.js.map} +1 -1
  150. package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js → EscalationSchemaPage-dxXO_T3t.js} +3 -3
  151. package/dashboard/dist/assets/{EscalationSchemaPage-DotfAMCL.js.map → EscalationSchemaPage-dxXO_T3t.js.map} +1 -1
  152. package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js → EscalationTimeline-C3WQZQuM.js} +2 -2
  153. package/dashboard/dist/assets/{EscalationTimeline-DqmFydnU.js.map → EscalationTimeline-C3WQZQuM.js.map} +1 -1
  154. package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js → EscalationTitleSelect-CTtcETUO.js} +2 -2
  155. package/dashboard/dist/assets/{EscalationTitleSelect-BpRquguO.js.map → EscalationTitleSelect-CTtcETUO.js.map} +1 -1
  156. package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js → EscalationsOverview-DAjZ7JY2.js} +2 -2
  157. package/dashboard/dist/assets/{EscalationsOverview-DtGOqnP4.js.map → EscalationsOverview-DAjZ7JY2.js.map} +1 -1
  158. package/dashboard/dist/assets/{EventTable-DSHqKyX2.js → EventTable-B72DQP_v.js} +2 -2
  159. package/dashboard/dist/assets/{EventTable-DSHqKyX2.js.map → EventTable-B72DQP_v.js.map} +1 -1
  160. package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js → FilterBar-CCTaA_LH.js} +2 -2
  161. package/dashboard/dist/assets/{FilterBar-Dxd0wNSW.js.map → FilterBar-CCTaA_LH.js.map} +1 -1
  162. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js +2 -0
  163. package/dashboard/dist/assets/GrantScopeField-BzWGzBfA.js.map +1 -0
  164. package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js → GraphInvokePage-CAsCgFo3.js} +2 -2
  165. package/dashboard/dist/assets/{GraphInvokePage-ChqqGkro.js.map → GraphInvokePage-CAsCgFo3.js.map} +1 -1
  166. package/dashboard/dist/assets/{HomePage-ByKesG8w.js → HomePage-DseE_iSr.js} +2 -2
  167. package/dashboard/dist/assets/{HomePage-ByKesG8w.js.map → HomePage-DseE_iSr.js.map} +1 -1
  168. package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js → ListToolbar-1zdqnjW6.js} +2 -2
  169. package/dashboard/dist/assets/{ListToolbar-Ddz_S2av.js.map → ListToolbar-1zdqnjW6.js.map} +1 -1
  170. package/dashboard/dist/assets/{McpOverview-CVe13tEv.js → McpOverview-DS_JXDW5.js} +2 -2
  171. package/dashboard/dist/assets/{McpOverview-CVe13tEv.js.map → McpOverview-DS_JXDW5.js.map} +1 -1
  172. package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js → McpQueryDetailPage-BeMUGcv3.js} +2 -2
  173. package/dashboard/dist/assets/{McpQueryDetailPage-BQYF2Mjq.js.map → McpQueryDetailPage-BeMUGcv3.js.map} +1 -1
  174. package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js → McpQueryPage-CeiLO_LR.js} +2 -2
  175. package/dashboard/dist/assets/{McpQueryPage-DZi5lm7s.js.map → McpQueryPage-CeiLO_LR.js.map} +1 -1
  176. package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js → McpRunDetailPage-DYp1uZK2.js} +2 -2
  177. package/dashboard/dist/assets/{McpRunDetailPage-DreARTE1.js.map → McpRunDetailPage-DYp1uZK2.js.map} +1 -1
  178. package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js → McpRunsPage-VeaDzcL4.js} +2 -2
  179. package/dashboard/dist/assets/{McpRunsPage-DmO0YVhT.js.map → McpRunsPage-VeaDzcL4.js.map} +1 -1
  180. package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js → OperationsPage-DK2mgaXf.js} +2 -2
  181. package/dashboard/dist/assets/{OperationsPage-DpjCO85T.js.map → OperationsPage-DK2mgaXf.js.map} +1 -1
  182. package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js → OperatorDashboard-BNjLF0f7.js} +2 -2
  183. package/dashboard/dist/assets/{OperatorDashboard-Vv_MEBkv.js.map → OperatorDashboard-BNjLF0f7.js.map} +1 -1
  184. package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js → PersonaDetailPage-IQ2fZLa6.js} +2 -2
  185. package/dashboard/dist/assets/{PersonaDetailPage-CW-2uBHY.js.map → PersonaDetailPage-IQ2fZLa6.js.map} +1 -1
  186. package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js → PersonasPage-DpGFEcU-.js} +2 -2
  187. package/dashboard/dist/assets/{PersonasPage-CO6yYQdm.js.map → PersonasPage-DpGFEcU-.js.map} +1 -1
  188. package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js → PortalPage-D07xyvG_.js} +2 -2
  189. package/dashboard/dist/assets/{PortalPage-DcNqhBlg.js.map → PortalPage-D07xyvG_.js.map} +1 -1
  190. package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js → ProcessDetailPage-t8EEYSMk.js} +2 -2
  191. package/dashboard/dist/assets/{ProcessDetailPage-BuipGZcC.js.map → ProcessDetailPage-t8EEYSMk.js.map} +1 -1
  192. package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js → ProcessesListPage-BDUXLFdb.js} +2 -2
  193. package/dashboard/dist/assets/{ProcessesListPage-D9DYntvl.js.map → ProcessesListPage-BDUXLFdb.js.map} +1 -1
  194. package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js +8 -0
  195. package/dashboard/dist/assets/ResolverForm-BwWOYv_Z.js.map +1 -0
  196. package/dashboard/dist/assets/RoleDetailPage-zMF3x2xi.js +8 -0
  197. package/dashboard/dist/assets/RoleDetailPage-zMF3x2xi.js.map +1 -0
  198. package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js → RolesPage-CEBp_PpL.js} +2 -2
  199. package/dashboard/dist/assets/{RolesPage-0QJOBSzF.js.map → RolesPage-CEBp_PpL.js.map} +1 -1
  200. package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js → RunAsSelector-CC_EHN3z.js} +2 -2
  201. package/dashboard/dist/assets/{RunAsSelector-Dh4lyyRo.js.map → RunAsSelector-CC_EHN3z.js.map} +1 -1
  202. package/dashboard/dist/assets/ScanCodesPage-DD4uU-jY.js +2 -0
  203. package/dashboard/dist/assets/ScanCodesPage-DD4uU-jY.js.map +1 -0
  204. package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js +2 -0
  205. package/dashboard/dist/assets/ScanSchemeDetailPage-CUW8gYFh.js.map +1 -0
  206. package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js +2 -0
  207. package/dashboard/dist/assets/ScanStationPage-DpO_ESuf.js.map +1 -0
  208. package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js → StickyPagination-cNqSDm5f.js} +2 -2
  209. package/dashboard/dist/assets/{StickyPagination-BSUyf5ja.js.map → StickyPagination-cNqSDm5f.js.map} +1 -1
  210. package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js → StreamMessageDetail-C4oZqQdB.js} +2 -2
  211. package/dashboard/dist/assets/{StreamMessageDetail--tp7l2Sd.js.map → StreamMessageDetail-C4oZqQdB.js.map} +1 -1
  212. package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js → SwimlaneTimeline-BjBiV7GT.js} +2 -2
  213. package/dashboard/dist/assets/{SwimlaneTimeline-CxBZ2THh.js.map → SwimlaneTimeline-BjBiV7GT.js.map} +1 -1
  214. package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js → TaskDetailPage-pO_AnVS1.js} +2 -2
  215. package/dashboard/dist/assets/{TaskDetailPage-BJ1QrmPH.js.map → TaskDetailPage-pO_AnVS1.js.map} +1 -1
  216. package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js → TasksListPage-DKDHlWP7.js} +2 -2
  217. package/dashboard/dist/assets/{TasksListPage-5BydGWmt.js.map → TasksListPage-DKDHlWP7.js.map} +1 -1
  218. package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js → TimeAgo-D2qchUuJ.js} +2 -2
  219. package/dashboard/dist/assets/{TimeAgo-CCnz84Y4.js.map → TimeAgo-D2qchUuJ.js.map} +1 -1
  220. package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js → TimestampCell-DeswZGGo.js} +2 -2
  221. package/dashboard/dist/assets/{TimestampCell-D0ru7Lya.js.map → TimestampCell-DeswZGGo.js.map} +1 -1
  222. package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js → ToolTestPanel-DJh7PIUa.js} +2 -2
  223. package/dashboard/dist/assets/{ToolTestPanel-3Kpofmen.js.map → ToolTestPanel-DJh7PIUa.js.map} +1 -1
  224. package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js → TopicDetailPage-CsgDJ4Z4.js} +2 -2
  225. package/dashboard/dist/assets/{TopicDetailPage-BaBXD_AK.js.map → TopicDetailPage-CsgDJ4Z4.js.map} +1 -1
  226. package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js → TopicsPage-tBRZDVDN.js} +2 -2
  227. package/dashboard/dist/assets/{TopicsPage-Cnm1AAjh.js.map → TopicsPage-tBRZDVDN.js.map} +1 -1
  228. package/dashboard/dist/assets/{UserName-CXsdPiMZ.js → UserName-B-5JcDck.js} +2 -2
  229. package/dashboard/dist/assets/{UserName-CXsdPiMZ.js.map → UserName-B-5JcDck.js.map} +1 -1
  230. package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js → WorkflowExecutionPage-BPHVnhp6.js} +2 -2
  231. package/dashboard/dist/assets/{WorkflowExecutionPage-zx3AUJFd.js.map → WorkflowExecutionPage-BPHVnhp6.js.map} +1 -1
  232. package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js → WorkflowsDashboard-CxLlfZmY.js} +2 -2
  233. package/dashboard/dist/assets/{WorkflowsDashboard-DfAGK1l7.js.map → WorkflowsDashboard-CxLlfZmY.js.map} +1 -1
  234. package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js → WorkflowsOverview-C4az5rwp.js} +2 -2
  235. package/dashboard/dist/assets/{WorkflowsOverview-QIYvoa13.js.map → WorkflowsOverview-C4az5rwp.js.map} +1 -1
  236. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js → YamlWorkflowDetailPage-BmhlAUFQ.js} +8 -8
  237. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DGgO3hyB.js.map → YamlWorkflowDetailPage-BmhlAUFQ.js.map} +1 -1
  238. package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js → YamlWorkflowsPage-CSbG5o2V.js} +2 -2
  239. package/dashboard/dist/assets/{YamlWorkflowsPage-CEsHm0B9.js.map → YamlWorkflowsPage-CSbG5o2V.js.map} +1 -1
  240. package/dashboard/dist/assets/{agents-v_HH3Rji.js → agents-BohEn7vw.js} +2 -2
  241. package/dashboard/dist/assets/{agents-v_HH3Rji.js.map → agents-BohEn7vw.js.map} +1 -1
  242. package/dashboard/dist/assets/{bots-bwvWYrXz.js → bots-BG2EO-Wi.js} +2 -2
  243. package/dashboard/dist/assets/{bots-bwvWYrXz.js.map → bots-BG2EO-Wi.js.map} +1 -1
  244. package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js → capabilities-CeFrBmYX.js} +2 -2
  245. package/dashboard/dist/assets/{capabilities-D4vaw_nQ.js.map → capabilities-CeFrBmYX.js.map} +1 -1
  246. package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js → controlplane-Dhvt8l8F.js} +2 -2
  247. package/dashboard/dist/assets/{controlplane-CiiZ6LJF.js.map → controlplane-Dhvt8l8F.js.map} +1 -1
  248. package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js → escalation-columns-BWMNxImp.js} +2 -2
  249. package/dashboard/dist/assets/{escalation-columns-Dv-MB3eC.js.map → escalation-columns-BWMNxImp.js.map} +1 -1
  250. package/dashboard/dist/assets/{index-CzjUgFt_.js → index-Bd_dgyfJ.js} +2 -2
  251. package/dashboard/dist/assets/{index-CzjUgFt_.js.map → index-Bd_dgyfJ.js.map} +1 -1
  252. package/dashboard/dist/assets/{index-IJmtbuLh.js → index-C8VlM2Oe.js} +2 -2
  253. package/dashboard/dist/assets/{index-IJmtbuLh.js.map → index-C8VlM2Oe.js.map} +1 -1
  254. package/dashboard/dist/assets/{index-CcuvGdvf.js → index-CiqSVDga.js} +2 -2
  255. package/dashboard/dist/assets/{index-CcuvGdvf.js.map → index-CiqSVDga.js.map} +1 -1
  256. package/dashboard/dist/assets/{index-C3WutFpT.js → index-Cl_YXEdp.js} +2 -2
  257. package/dashboard/dist/assets/{index-C3WutFpT.js.map → index-Cl_YXEdp.js.map} +1 -1
  258. package/dashboard/dist/assets/index-CtZWpy22.js +2 -0
  259. package/dashboard/dist/assets/index-CtZWpy22.js.map +1 -0
  260. package/dashboard/dist/assets/{index-CjenRVX_.js → index-D90D9y0J.js} +2 -2
  261. package/dashboard/dist/assets/{index-CjenRVX_.js.map → index-D90D9y0J.js.map} +1 -1
  262. package/dashboard/dist/assets/{index-BLB77tc8.js → index-DABkM7s-.js} +2 -2
  263. package/dashboard/dist/assets/{index-BLB77tc8.js.map → index-DABkM7s-.js.map} +1 -1
  264. package/dashboard/dist/assets/index-Dbwu51xm.js +3 -0
  265. package/dashboard/dist/assets/index-Dbwu51xm.js.map +1 -0
  266. package/dashboard/dist/assets/{index-2tzsxFat.js → index-Dc3Om6G3.js} +2 -2
  267. package/dashboard/dist/assets/{index-2tzsxFat.js.map → index-Dc3Om6G3.js.map} +1 -1
  268. package/dashboard/dist/assets/{index-D2VKBMng.js → index-Dc_zWK23.js} +2 -2
  269. package/dashboard/dist/assets/{index-D2VKBMng.js.map → index-Dc_zWK23.js.map} +1 -1
  270. package/dashboard/dist/assets/index-DcppjzP5.css +1 -0
  271. package/dashboard/dist/assets/{index-C_ISDOWJ.js → index-Y-bdW8vo.js} +2 -2
  272. package/dashboard/dist/assets/{index-C_ISDOWJ.js.map → index-Y-bdW8vo.js.map} +1 -1
  273. package/dashboard/dist/assets/{index-C4Lce2ET.js → index-dYKgd06u.js} +3 -3
  274. package/dashboard/dist/assets/{index-C4Lce2ET.js.map → index-dYKgd06u.js.map} +1 -1
  275. package/dashboard/dist/assets/index-fUsx_gYx.js +67 -0
  276. package/dashboard/dist/assets/index-fUsx_gYx.js.map +1 -0
  277. package/dashboard/dist/assets/{knowledge-D1YP2NzS.js → knowledge-CCcTidNV.js} +2 -2
  278. package/dashboard/dist/assets/{knowledge-D1YP2NzS.js.map → knowledge-CCcTidNV.js.map} +1 -1
  279. package/dashboard/dist/assets/{mcp-Bb5psC61.js → mcp-CLA1z7Pg.js} +2 -2
  280. package/dashboard/dist/assets/{mcp-Bb5psC61.js.map → mcp-CLA1z7Pg.js.map} +1 -1
  281. package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js → mcp-query-CWG0WMAs.js} +2 -2
  282. package/dashboard/dist/assets/{mcp-query-D5jUdZwN.js.map → mcp-query-CWG0WMAs.js.map} +1 -1
  283. package/dashboard/dist/assets/metadata-display-B7X5hGxG.js +2 -0
  284. package/dashboard/dist/assets/metadata-display-B7X5hGxG.js.map +1 -0
  285. package/dashboard/dist/assets/{personas-CDndbkp4.js → personas-8jURIzx6.js} +2 -2
  286. package/dashboard/dist/assets/{personas-CDndbkp4.js.map → personas-8jURIzx6.js.map} +1 -1
  287. package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js → pipelines-hVVRAXqG.js} +2 -2
  288. package/dashboard/dist/assets/{pipelines-Dq3kNhKu.js.map → pipelines-hVVRAXqG.js.map} +1 -1
  289. package/dashboard/dist/assets/{tasks-BlpDsWCy.js → tasks-BE1O57Bf.js} +2 -2
  290. package/dashboard/dist/assets/{tasks-BlpDsWCy.js.map → tasks-BE1O57Bf.js.map} +1 -1
  291. package/dashboard/dist/assets/{topics-C0YaR9fu.js → topics-Bg96Wp1r.js} +2 -2
  292. package/dashboard/dist/assets/{topics-C0YaR9fu.js.map → topics-Bg96Wp1r.js.map} +1 -1
  293. package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js → useDebouncedValue-DmEveyEy.js} +2 -2
  294. package/dashboard/dist/assets/{useDebouncedValue-B-KC5ba3.js.map → useDebouncedValue-DmEveyEy.js.map} +1 -1
  295. package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js → useNamespace-DHgkzIuL.js} +2 -2
  296. package/dashboard/dist/assets/{useNamespace-Dkr5g2Ac.js.map → useNamespace-DHgkzIuL.js.map} +1 -1
  297. package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js → useYamlActivityEvents-RU0PvU8S.js} +2 -2
  298. package/dashboard/dist/assets/{useYamlActivityEvents-BANBOshA.js.map → useYamlActivityEvents-RU0PvU8S.js.map} +1 -1
  299. package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js → yaml-workflows-DQWE9ijc.js} +2 -2
  300. package/dashboard/dist/assets/{yaml-workflows-BLYoJfmB.js.map → yaml-workflows-DQWE9ijc.js.map} +1 -1
  301. package/dashboard/dist/index.html +2 -2
  302. package/docs/dashboard.md +1 -1
  303. package/docs/hitl/lookups.md +27 -18
  304. package/docs/hitl/x-lt-scan.md +51 -0
  305. package/docs/hitl/x-lt-validation.md +1 -1
  306. package/docs/hitl/x-lt-widget.md +1 -1
  307. package/docs/hitl-guide.md +3 -1
  308. package/docs/scan-codes.md +303 -33
  309. package/package.json +1 -1
  310. package/build/types/scan-code.d.ts +0 -317
  311. package/dashboard/dist/assets/CapabilitiesPage-BxadotXn.js +0 -2
  312. package/dashboard/dist/assets/CountdownTimer-CI_JOAvk.js +0 -2
  313. package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js +0 -8
  314. package/dashboard/dist/assets/ResolverForm-BVG8X0sS.js.map +0 -1
  315. package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js +0 -8
  316. package/dashboard/dist/assets/RoleDetailPage-KCXDqoJz.js.map +0 -1
  317. package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js +0 -2
  318. package/dashboard/dist/assets/ScanCodesPage-CUhCz-Yr.js.map +0 -1
  319. package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js +0 -2
  320. package/dashboard/dist/assets/ScanSchemeDetailPage-qzXKNqJK.js.map +0 -1
  321. package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js +0 -2
  322. package/dashboard/dist/assets/ScanStationPage-D8e8cG3t.js.map +0 -1
  323. package/dashboard/dist/assets/index-CT-FN6CW.js +0 -3
  324. package/dashboard/dist/assets/index-CT-FN6CW.js.map +0 -1
  325. package/dashboard/dist/assets/index-D6pBLZFu.js +0 -2
  326. package/dashboard/dist/assets/index-D6pBLZFu.js.map +0 -1
  327. package/dashboard/dist/assets/index-Dh8MJl3L.css +0 -1
  328. package/dashboard/dist/assets/index-N71QQ3J5.js +0 -67
  329. package/dashboard/dist/assets/index-N71QQ3J5.js.map +0 -1
  330. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +0 -2
  331. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +0 -1
@@ -37,10 +37,15 @@ exports.executeScanCode = executeScanCode;
37
37
  const scanCodeService = __importStar(require("../../services/scan-code"));
38
38
  const identity_1 = require("./identity");
39
39
  const context_1 = require("./context");
40
+ const grant_1 = require("./grant");
41
+ const hold_1 = require("./hold");
40
42
  const locate_1 = require("./locate");
41
43
  const present_1 = require("./present");
44
+ const subject_1 = require("./subject");
45
+ const verb_fill_1 = require("./verb-fill");
42
46
  const verbs_1 = require("./verbs");
43
47
  const types_1 = require("../../types");
48
+ const SUBJECT_STALE_MESSAGE = 'That one moved on. Scan it again.';
44
49
  /**
45
50
  * Execute a raw scan code: parse → load the rule → walk its steps in order.
46
51
  * The first step whose condition matches performs its verb and answers; a
@@ -77,45 +82,57 @@ async function executeScanCode(input, auth) {
77
82
  }
78
83
  // 2a. Identity schemes are the badge layer — they mint, never walk steps.
79
84
  if (scheme.kind === types_1.SCAN_SCHEME_KINDS.IDENTITY) {
80
- return (0, identity_1.executeIdentityScan)(parsed, scheme, rule, input.previousActingToken);
85
+ return (0, identity_1.executeIdentityScan)(parsed, scheme, rule, input.previousActingToken, {
86
+ userId: auth.userId,
87
+ stationRole: typeof input.stationRole === 'string' ? input.stationRole : undefined,
88
+ });
81
89
  }
82
- // 2b. A supplied acting grant is exchanged once, up front — the acting
83
- // user's read scope must govern the locate as much as the mutation. A
84
- // dead grant terminates loudly; silently degrading to the station
85
- // identity would misattribute whatever follows.
86
- let effectiveAuth = auth;
87
- let acting = false;
90
+ // 2b. A supplied acting grant is read up front (not spent): the acting
91
+ // user's read scope governs the locate as much as the mutation. A dead
92
+ // grant terminates loudly; silently degrading to the station identity
93
+ // would misattribute whatever follows.
94
+ const ctx = {
95
+ scheme, rule, parsed, rawCode: input.code.trim(), scannedAt: new Date().toISOString(),
96
+ auth, stationAuth: auth, acting: false,
97
+ };
88
98
  if (input.actingToken) {
89
- const resolved = await (0, identity_1.resolveActingAuth)(input.actingToken);
90
- if (!resolved.ok) {
91
- return {
92
- status: 200,
93
- data: {
94
- outcome: types_1.SCAN_OUTCOMES.NOT_PRIMED,
95
- parsed,
96
- notPrimed: rule.notPrimed,
97
- error: resolved.error,
98
- },
99
- };
99
+ const peeked = await (0, grant_1.peekGrant)(input.actingToken);
100
+ if (!peeked.ok) {
101
+ return { status: 200, data: { ...(0, context_1.notPrimed)(ctx, peeked.error).data, parsed } };
100
102
  }
101
- effectiveAuth = resolved.auth;
102
- acting = true;
103
+ ctx.auth = peeked.auth;
104
+ ctx.acting = true;
105
+ ctx.grant = peeked.grant;
103
106
  }
107
+ // 2c. The held subject, re-derived from the station's pointer
108
+ const held = await (0, subject_1.resolveSubject)(input.subject, schemes, auth);
109
+ if (held?.ok)
110
+ ctx.subject = held.subject;
111
+ else if (held)
112
+ ctx.subjectStale = true;
104
113
  // 3. Walk the steps — first condition match wins
105
- const ctx = {
106
- scheme, rule, parsed, scannedAt: new Date().toISOString(),
107
- auth: effectiveAuth, stationAuth: auth, acting,
108
- };
109
- for (let i = 0; i < rule.steps.length; i++) {
110
- const result = await executeStep(rule.steps[i], i, ctx);
111
- if (result)
112
- return decorate(result, ctx, i);
114
+ let result = null;
115
+ for (let i = 0; i < rule.steps.length && !result; i++) {
116
+ const stepResult = await executeStep(rule.steps[i], ctx);
117
+ if (stepResult)
118
+ result = decorate((0, context_1.withDone)(stepResult, rule.steps[i], (0, context_1.templateContext)(ctx)), ctx, i);
113
119
  }
114
- // 4. Nothing matched — the fallback screen is the answer
115
- return {
116
- status: 200,
117
- data: decorateData({ outcome: types_1.SCAN_OUTCOMES.NO_MATCH_FALLBACK, fallback: rule.fallback }, ctx),
118
- };
120
+ // 4. Nothing matched: a stale subject, or the fallback screen
121
+ if (!result) {
122
+ result = ctx.subjectStale
123
+ ? { status: 200, data: decorateData({ outcome: types_1.SCAN_OUTCOMES.SUBJECT_STALE, clearSubject: true, error: SUBJECT_STALE_MESSAGE }, ctx) }
124
+ : { status: 200, data: decorateData({ outcome: types_1.SCAN_OUTCOMES.NO_MATCH_FALLBACK, fallback: rule.fallback }, ctx) };
125
+ }
126
+ // 5. Settle the badge: refund a spend whose act did not land
127
+ const acting = await (0, grant_1.settleGrant)(ctx, result);
128
+ if (result.data && typeof result.data === 'object' && 'outcome' in result.data) {
129
+ result.data = {
130
+ ...result.data,
131
+ ...(acting ? { acting } : {}),
132
+ ...(ctx.subjectStale ? { clearSubject: true } : {}),
133
+ };
134
+ }
135
+ return result;
119
136
  }
120
137
  catch (err) {
121
138
  return { status: 500, error: err.message };
@@ -139,17 +156,34 @@ function decorateData(data, ctx) {
139
156
  },
140
157
  };
141
158
  }
159
+ /**
160
+ * A subject step runs only while a subject from one of its schemes is held,
161
+ * and, when it declares facets, only while the held row carries them.
162
+ */
163
+ function subjectGateOpen(step, ctx) {
164
+ if (!step.subject)
165
+ return true;
166
+ if (!ctx.subject || !step.subject.schemes.includes(ctx.subject.scheme.version))
167
+ return false;
168
+ const meta = (ctx.subject.row.metadata ?? {});
169
+ return Object.entries(step.subject.facets ?? {}).every(([key, value]) => meta[key] === value);
170
+ }
142
171
  /**
143
172
  * Execute one step. Returns null when the step's condition matched nothing
144
173
  * (fall through) and an LTApiResult for every terminal outcome.
145
174
  */
146
- async function executeStep(step, index, ctx) {
175
+ async function executeStep(step, ctx) {
176
+ if (!subjectGateOpen(step, ctx))
177
+ return null;
147
178
  // The identity pre-condition: the effective actor must be a real acting
148
179
  // identity — a badge grant, or an authenticated user whose own write scope
149
180
  // covers the step. A write-incapable shared account can never self-satisfy,
150
181
  // so the outcome is the rule's "scan your badge" screen, never a silent or
151
182
  // misattributed action.
152
- if (step.requireActingIdentity && !(await (0, identity_1.actingIdentitySatisfied)(step, ctx))) {
183
+ // A subject step checks the pairing first and asks for the badge only when
184
+ // the pairing is right (see identityGate), so a wrong container is named
185
+ // at once.
186
+ if (step.requireActingIdentity && !step.subject && !(await (0, identity_1.actingIdentitySatisfied)(step, ctx))) {
153
187
  return (0, context_1.notPrimed)(ctx);
154
188
  }
155
189
  // Confirm steps and read verbs only locate — mutation happens after the
@@ -160,6 +194,8 @@ async function executeStep(step, index, ctx) {
160
194
  switch (step.verb) {
161
195
  case types_1.SCAN_VERBS.PRESENT:
162
196
  return (0, present_1.presentStep)(step, ctx);
197
+ case types_1.SCAN_VERBS.HOLD:
198
+ return (0, hold_1.holdStep)(step, ctx);
163
199
  case types_1.SCAN_VERBS.CLAIM:
164
200
  case types_1.SCAN_VERBS.CLAIM_SHOW_DETAIL:
165
201
  return (0, verbs_1.claimStep)(step, ctx);
@@ -173,6 +209,8 @@ async function executeStep(step, index, ctx) {
173
209
  return (0, verbs_1.cancelStep)(step, ctx);
174
210
  case types_1.SCAN_VERBS.ACCUMULATE:
175
211
  return (0, verbs_1.accumulateStep)(step, ctx);
212
+ case types_1.SCAN_VERBS.FILL:
213
+ return (0, verb_fill_1.fillStep)(step, ctx);
176
214
  default:
177
215
  throw new Error(`unknown scan verb "${step.verb}"`);
178
216
  }
@@ -0,0 +1,27 @@
1
+ import { type ScanExecuteResponse, type ScanStep } from '../../types';
2
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
3
+ import { type GrantLedger, type StepContext } from './context';
4
+ export type PeekResult = {
5
+ ok: true;
6
+ auth: LTApiAuth;
7
+ grant: GrantLedger;
8
+ } | {
9
+ ok: false;
10
+ error: string;
11
+ };
12
+ /** Read the grant without spending it. */
13
+ export declare function peekGrant(token: string): Promise<PeekResult>;
14
+ /**
15
+ * Spend the request's grant before a write. Returns null when the act may
16
+ * proceed (spent now, spent earlier in this request, or no grant rides it),
17
+ * and the not-primed result when the grant cannot cover this act. `ref` is
18
+ * the held subject the act lands on.
19
+ */
20
+ export declare function spendGrant(ctx: StepContext, ref?: string | null): Promise<LTApiResult<ScanExecuteResponse> | null>;
21
+ /** The step's identity requirement, checked at the moment it is about to act. */
22
+ export declare function identityGate(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
23
+ /**
24
+ * Close the request's books on the grant: refund a spend whose act did not
25
+ * land, and report the grant's state for the client to keep or retire.
26
+ */
27
+ export declare function settleGrant(ctx: StepContext, result: LTApiResult<ScanExecuteResponse> | null): Promise<ScanExecuteResponse['acting'] | undefined>;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.peekGrant = peekGrant;
4
+ exports.spendGrant = spendGrant;
5
+ exports.identityGate = identityGate;
6
+ exports.settleGrant = settleGrant;
7
+ const acting_identity_1 = require("../../services/iam/acting-identity");
8
+ const types_1 = require("../../types");
9
+ const context_1 = require("./context");
10
+ const identity_1 = require("./identity");
11
+ /** Read the grant without spending it. */
12
+ async function peekGrant(token) {
13
+ const peeked = await (0, acting_identity_1.peekActingAuth)(token);
14
+ if (!peeked.ok)
15
+ return peeked;
16
+ return {
17
+ ok: true,
18
+ auth: peeked.auth,
19
+ grant: { token, peeked: { remaining: peeked.grant.remaining, bound: peeked.grant.bound }, spent: null },
20
+ };
21
+ }
22
+ /**
23
+ * Spend the request's grant before a write. Returns null when the act may
24
+ * proceed (spent now, spent earlier in this request, or no grant rides it),
25
+ * and the not-primed result when the grant cannot cover this act. `ref` is
26
+ * the held subject the act lands on.
27
+ */
28
+ async function spendGrant(ctx, ref = ctx.subject?.row.id ?? null) {
29
+ const grant = ctx.grant;
30
+ if (!grant || grant.spent)
31
+ return null;
32
+ const consumed = await (0, acting_identity_1.consumeActingGrant)(grant.token, ref);
33
+ if (!consumed.ok)
34
+ return (0, context_1.notPrimed)(ctx, consumed.error);
35
+ grant.spent = { remaining: consumed.grant.remaining, bound: consumed.grant.bound };
36
+ return null;
37
+ }
38
+ /** The step's identity requirement, checked at the moment it is about to act. */
39
+ async function identityGate(step, ctx) {
40
+ if (!step.requireActingIdentity || (await (0, identity_1.actingIdentitySatisfied)(step, ctx)))
41
+ return null;
42
+ return (0, context_1.notPrimed)(ctx);
43
+ }
44
+ /** True when the result is a write that landed. */
45
+ function landed(result) {
46
+ const data = result?.data;
47
+ return !!data && data.outcome === types_1.SCAN_OUTCOMES.EXECUTED
48
+ && !!data.verb && types_1.SCAN_MUTATING_VERBS.includes(data.verb) && !data.already;
49
+ }
50
+ /**
51
+ * Close the request's books on the grant: refund a spend whose act did not
52
+ * land, and report the grant's state for the client to keep or retire.
53
+ */
54
+ async function settleGrant(ctx, result) {
55
+ const grant = ctx.grant;
56
+ if (!grant)
57
+ return undefined;
58
+ if (grant.spent && !landed(result)) {
59
+ // Spending a bound grant cost nothing; spending an unbound one counted
60
+ // a use and may have bound it, so both come back.
61
+ if (!grant.peeked.bound)
62
+ await (0, acting_identity_1.refundActingGrant)(grant.token, grant.spent.bound);
63
+ grant.spent = null;
64
+ }
65
+ const state = grant.spent ?? grant.peeked;
66
+ return { consumed: !!grant.spent, remaining: state.remaining, bound: state.bound };
67
+ }
@@ -0,0 +1,10 @@
1
+ import { type LTEscalationRecord, type ScanExecuteResponse, type ScanStep } from '../../types';
2
+ import type { LTApiResult } from '../../types/sdk';
3
+ import { type StepContext } from './context';
4
+ /**
5
+ * HOLD: locate the row and hand the station a subject to hold. The next
6
+ * scans (the badge, then the container) act on it. Writes nothing and spends
7
+ * no badge use. A live claim by someone else is reported, not refused: the
8
+ * bench says whose it is, and the act decides.
9
+ */
10
+ export declare function holdStep(step: ScanStep, ctx: StepContext, located?: LTEscalationRecord): Promise<LTApiResult<ScanExecuteResponse> | null>;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.holdStep = holdStep;
37
+ const scanCodeService = __importStar(require("../../services/scan-code"));
38
+ const types_1 = require("../../types");
39
+ const context_1 = require("./context");
40
+ const locate_1 = require("./locate");
41
+ const subject_1 = require("./subject");
42
+ /**
43
+ * HOLD: locate the row and hand the station a subject to hold. The next
44
+ * scans (the badge, then the container) act on it. Writes nothing and spends
45
+ * no badge use. A live claim by someone else is reported, not refused: the
46
+ * bench says whose it is, and the act decides.
47
+ */
48
+ async function holdStep(step, ctx, located) {
49
+ const row = located ?? (await (0, locate_1.locateForStep)(step, ctx, 1))?.escalations[0];
50
+ if (!row)
51
+ return null;
52
+ return {
53
+ status: 200,
54
+ data: {
55
+ outcome: types_1.SCAN_OUTCOMES.HELD,
56
+ verb: step.verb,
57
+ escalation: row,
58
+ subject: await heldSubject(step, ctx, row),
59
+ },
60
+ };
61
+ }
62
+ async function heldSubject(step, ctx, row) {
63
+ const hold = step.params?.hold ?? {};
64
+ const tpl = { ...(0, context_1.templateContext)(ctx), item: row.metadata ?? {} };
65
+ const ttl = hold.ttlSeconds ?? types_1.SCAN_HOLD_TTL_DEFAULT_SECONDS;
66
+ const claimant = await (0, subject_1.claimedByOther)(row, ctx.acting ? ctx.auth.userId : null);
67
+ return {
68
+ code: ctx.rawCode ?? holdCode(ctx),
69
+ escalationId: row.id,
70
+ label: scanCodeService.renderScanCopy(hold.label ?? types_1.SCAN_TEMPLATE_TOKENS.TARGET, tpl),
71
+ ...optionalCopy('headline', hold.headline, tpl),
72
+ ...optionalCopy('subline', hold.subline, tpl),
73
+ expiresAt: new Date(Date.now() + ttl * 1000).toISOString(),
74
+ ...(hold.expect ? {
75
+ expect: {
76
+ schemes: hold.expect.schemes,
77
+ ...(hold.expect.prompt ? { prompt: scanCodeService.renderScanCopy(hold.expect.prompt, tpl) } : {}),
78
+ },
79
+ } : {}),
80
+ ...(claimant ? { claimedBy: claimant } : {}),
81
+ };
82
+ }
83
+ /** The canonical code for the held row, as the station would scan it. */
84
+ function holdCode(ctx) {
85
+ const { scheme, parsed } = ctx;
86
+ if (scheme.encoding === 'delimited') {
87
+ const d = scheme.delimiter;
88
+ return `${parsed.version}${d}${parsed.category}${d}${parsed.target}`;
89
+ }
90
+ return `${parsed.version}${parsed.category}${parsed.target}`;
91
+ }
92
+ /** A rendered line, or nothing when the template is absent or renders empty. */
93
+ function optionalCopy(key, template, tpl) {
94
+ if (!template)
95
+ return {};
96
+ const text = scanCodeService.renderScanCopy(template, tpl).trim();
97
+ return text ? { [key]: text } : {};
98
+ }
@@ -1,13 +1,16 @@
1
1
  import { type ParsedScanCode, type ScanExecuteResponse, type ScanRule, type ScanScheme, type ScanStep } from '../../types';
2
2
  import type { LTApiResult } from '../../types/sdk';
3
3
  import type { StepContext } from './context';
4
- export { resolveActingAuth, type ActingAuthResult } from '../../services/iam/acting-identity';
4
+ export { resolveActingAuth, peekActingAuth, type ActingAuthResult } from '../../services/iam/acting-identity';
5
5
  /**
6
6
  * Resolve an identity scan: badge → user → minted acting grant.
7
7
  * Identity schemes never walk steps; the rule's fallback is the
8
8
  * unknown-badge screen.
9
9
  */
10
- export declare function executeIdentityScan(parsed: ParsedScanCode, scheme: ScanScheme, rule: ScanRule, previousActingToken?: string): Promise<LTApiResult<ScanExecuteResponse>>;
10
+ export declare function executeIdentityScan(parsed: ParsedScanCode, scheme: ScanScheme, rule: ScanRule, previousActingToken?: string, station?: {
11
+ userId: string;
12
+ stationRole?: string;
13
+ }): Promise<LTApiResult<ScanExecuteResponse>>;
11
14
  /**
12
15
  * The identity pre-condition's satisfaction test. A primed grant always
13
16
  * satisfies; without one, the authenticated user satisfies only when their
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.resolveActingAuth = void 0;
36
+ exports.peekActingAuth = exports.resolveActingAuth = void 0;
37
37
  exports.executeIdentityScan = executeIdentityScan;
38
38
  exports.actingIdentitySatisfied = actingIdentitySatisfied;
39
39
  const userService = __importStar(require("../../services/user"));
@@ -41,8 +41,10 @@ const ephemeral_1 = require("../../services/iam/ephemeral");
41
41
  const metadata_1 = require("../escalations/metadata");
42
42
  const helpers_1 = require("../escalations/helpers");
43
43
  const types_1 = require("../../types");
44
+ const badge_policy_1 = require("./badge-policy");
44
45
  var acting_identity_1 = require("../../services/iam/acting-identity");
45
46
  Object.defineProperty(exports, "resolveActingAuth", { enumerable: true, get: function () { return acting_identity_1.resolveActingAuth; } });
47
+ Object.defineProperty(exports, "peekActingAuth", { enumerable: true, get: function () { return acting_identity_1.peekActingAuth; } });
46
48
  // ── Acting identity — the badge layer over the scan surface ────────────────
47
49
  //
48
50
  // A shared station device signs in as an ordinary read-capable account; the
@@ -58,8 +60,18 @@ Object.defineProperty(exports, "resolveActingAuth", { enumerable: true, get: fun
58
60
  * Identity schemes never walk steps; the rule's fallback is the
59
61
  * unknown-badge screen.
60
62
  */
61
- async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
62
- const user = await userService.getUserByMetadataValue(scheme.target_facet, parsed.target);
63
+ async function executeIdentityScan(parsed, scheme, rule, previousActingToken, station) {
64
+ // Two users bound to one badge is a configuration fault: refuse the badge
65
+ // and name the fault, never pick one of them.
66
+ let user;
67
+ let unknownReason = 'badge not recognized';
68
+ try {
69
+ user = await userService.getUserByMetadataValue(scheme.target_facet, parsed.target);
70
+ }
71
+ catch (err) {
72
+ user = null;
73
+ unknownReason = `badge is bound to more than one person: ${err.message}`;
74
+ }
63
75
  if (!user) {
64
76
  return {
65
77
  status: 200,
@@ -68,7 +80,7 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
68
80
  parsed,
69
81
  rule: { schemeVersion: rule.scheme_version, category: rule.category, name: rule.name },
70
82
  fallback: rule.fallback,
71
- error: 'badge not recognized',
83
+ error: unknownReason,
72
84
  },
73
85
  };
74
86
  }
@@ -79,12 +91,17 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
79
91
  await (0, ephemeral_1.revokeEphemeral)(prev.uuid).catch(() => { });
80
92
  }
81
93
  }
94
+ // The station decides the policy: its role's badge_grant, else the scheme's.
95
+ const policy = station
96
+ ? await (0, badge_policy_1.stationGrantPolicy)(scheme, station.userId, station.stationRole)
97
+ : { ttlSeconds: scheme.grant_ttl_seconds ?? 0, maxUses: scheme.grant_max_uses ?? 0, scope: scheme.grant_scope ?? types_1.SCAN_GRANT_SCOPES.ACTION };
82
98
  const uuid = await (0, ephemeral_1.storeEphemeral)(user.id, {
83
- ttlSeconds: scheme.grant_ttl_seconds ?? undefined,
84
- maxUses: scheme.grant_max_uses,
99
+ ttlSeconds: policy.ttlSeconds || undefined,
100
+ maxUses: policy.maxUses,
85
101
  label: types_1.ACTING_IDENTITY_LABEL,
102
+ bindOnUse: policy.scope === types_1.SCAN_GRANT_SCOPES.SUBJECT,
86
103
  });
87
- const expiresAt = new Date(Date.now() + (scheme.grant_ttl_seconds ?? 0) * 1000).toISOString();
104
+ const expiresAt = new Date(Date.now() + policy.ttlSeconds * 1000).toISOString();
88
105
  return {
89
106
  status: 200,
90
107
  data: {
@@ -94,7 +111,8 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
94
111
  actor: { id: user.id, displayName: user.display_name || user.external_id },
95
112
  actingToken: (0, ephemeral_1.formatEphemeralToken)(uuid, types_1.ACTING_IDENTITY_LABEL),
96
113
  expiresAt,
97
- maxUses: scheme.grant_max_uses ?? 0,
114
+ maxUses: policy.maxUses,
115
+ grantScope: policy.scope,
98
116
  },
99
117
  };
100
118
  }
@@ -61,6 +61,8 @@ async function locateForStep(step, ctx, limit) {
61
61
  return escalationService.listEscalations({
62
62
  metadata: facets,
63
63
  status,
64
+ type: step.query?.types?.[0],
65
+ subtype: step.query?.subtypes?.[0],
64
66
  assigned_to: ctx.auth.userId,
65
67
  visibleRoles: roles ?? undefined,
66
68
  limit,
@@ -71,6 +73,8 @@ async function locateForStep(step, ctx, limit) {
71
73
  return null;
72
74
  return escalationService.searchByFacets({
73
75
  roles: roles ?? undefined,
76
+ types: step.query?.types,
77
+ subtypes: step.query?.subtypes,
74
78
  facets,
75
79
  status,
76
80
  available: availability === types_1.SCAN_AVAILABILITY.AVAILABLE
@@ -1,6 +1,6 @@
1
1
  import { type ScanExecuteResponse, type ScanStep } from '../../types';
2
2
  import type { LTApiResult } from '../../types/sdk';
3
- import type { StepContext } from './context';
3
+ import { type StepContext } from './context';
4
4
  /**
5
5
  * Locate the target and present the step's choices. Choices whose identity
6
6
  * requirement is unsatisfied come back withheld — the screen renders the
@@ -1,10 +1,52 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.presentStep = presentStep;
37
+ const scanCodeService = __importStar(require("../../services/scan-code"));
4
38
  const types_1 = require("../../types");
5
39
  const identity_1 = require("./identity");
6
40
  const locate_1 = require("./locate");
7
41
  const verbs_1 = require("./verbs");
42
+ const context_1 = require("./context");
43
+ /** The step's facts rendered against the presented row; unreadable tokens render empty. */
44
+ function renderFacts(step, ctx, row) {
45
+ if (!step.facts)
46
+ return undefined;
47
+ const tpl = { ...(0, context_1.templateContext)(ctx), item: row.metadata ?? {} };
48
+ return step.facts.map((fact) => ({ label: fact.label, value: scanCodeService.renderScanCopy(fact.value, tpl) }));
49
+ }
8
50
  // ── The info-choice outcome — locate → present reality + labeled choices ───
9
51
  //
10
52
  // Some objects carry one code for their whole life: the next action cannot be
@@ -52,6 +94,7 @@ async function presentStep(step, ctx) {
52
94
  verb: step.verb,
53
95
  escalation,
54
96
  choices,
97
+ ...(step.facts ? { facts: renderFacts(step, ctx, escalation) } : {}),
55
98
  notPrimed: ctx.rule.notPrimed,
56
99
  ...(autoSelect ? { autoSelect: true } : {}),
57
100
  },
@@ -0,0 +1,15 @@
1
+ import { type LTEscalationRecord, type ScanScheme, type ScanSubjectRef } from '../../types';
2
+ import type { LTApiAuth } from '../../types/sdk';
3
+ import type { HeldSubject } from './context';
4
+ export type SubjectResult = {
5
+ ok: true;
6
+ subject: HeldSubject;
7
+ } | {
8
+ ok: false;
9
+ };
10
+ export declare function resolveSubject(ref: ScanSubjectRef | undefined, schemes: ScanScheme[], stationAuth: LTApiAuth): Promise<SubjectResult | null>;
11
+ /** Who holds a live claim on the row, when that is someone other than `actorId`. */
12
+ export declare function claimedByOther(row: LTEscalationRecord, actorId: string | null): Promise<{
13
+ id: string;
14
+ displayName: string;
15
+ } | null>;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveSubject = resolveSubject;
37
+ exports.claimedByOther = claimedByOther;
38
+ const scanCodeService = __importStar(require("../../services/scan-code"));
39
+ const escalationService = __importStar(require("../../services/escalation"));
40
+ const userService = __importStar(require("../../services/user"));
41
+ const uuid_1 = require("../../lib/uuid");
42
+ const helpers_1 = require("../escalations/helpers");
43
+ const types_1 = require("../../types");
44
+ async function resolveSubject(ref, schemes, stationAuth) {
45
+ if (!ref)
46
+ return null;
47
+ if (typeof ref.code !== 'string' || !(0, uuid_1.isUuid)(ref.escalationId))
48
+ return { ok: false };
49
+ const parsed = scanCodeService.parseScanCode(ref.code, schemes);
50
+ if (!parsed.ok || parsed.scheme.kind !== types_1.SCAN_SCHEME_KINDS.ACTION)
51
+ return { ok: false };
52
+ const row = await escalationService.getEscalation(ref.escalationId);
53
+ if (!row || row.status !== 'pending')
54
+ return { ok: false };
55
+ if (await (0, helpers_1.assertReadAccess)(stationAuth.userId, row))
56
+ return { ok: false };
57
+ if (row.metadata?.[parsed.scheme.target_facet] !== parsed.parsed.target) {
58
+ return { ok: false };
59
+ }
60
+ return { ok: true, subject: { row, parsed: parsed.parsed, scheme: parsed.scheme, code: ref.code } };
61
+ }
62
+ /** Who holds a live claim on the row, when that is someone other than `actorId`. */
63
+ async function claimedByOther(row, actorId) {
64
+ if (!row.assigned_to || !(0, types_1.isEffectivelyClaimed)(row) || row.assigned_to === actorId)
65
+ return null;
66
+ const user = await userService.getUser(row.assigned_to);
67
+ return { id: row.assigned_to, displayName: user?.display_name || user?.external_id || 'another associate' };
68
+ }