@hotmeshio/long-tail 0.14.1 → 0.14.4

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 (266) hide show
  1. package/build/api/escalations/bulk.d.ts +18 -0
  2. package/build/api/escalations/bulk.js +49 -1
  3. package/build/api/escalations/helpers.d.ts +11 -1
  4. package/build/api/escalations/helpers.js +30 -3
  5. package/build/api/escalations/index.d.ts +1 -1
  6. package/build/api/escalations/index.js +2 -1
  7. package/build/routes/escalations/bulk.js +6 -0
  8. package/build/sdk/index.d.ts +4 -0
  9. package/build/sdk/index.js +1 -0
  10. package/build/services/escalation/bulk.d.ts +27 -0
  11. package/build/services/escalation/bulk.js +39 -0
  12. package/build/services/escalation/sql.d.ts +17 -0
  13. package/build/services/escalation/sql.js +44 -1
  14. package/build/shared/form-validation/field-validator.js +6 -4
  15. package/build/shared/form-validation/index.d.ts +2 -0
  16. package/build/shared/form-validation/index.js +2 -0
  17. package/build/shared/form-validation/validate-resolver-payload.d.ts +2 -0
  18. package/build/shared/form-validation/validate-resolver-payload.js +19 -0
  19. package/build/shared/form-validation/x-lt-options.d.ts +22 -0
  20. package/build/shared/form-validation/x-lt-options.js +51 -0
  21. package/build/shared/form-validation/x-lt-require-sum.d.ts +30 -0
  22. package/build/shared/form-validation/x-lt-require-sum.js +59 -0
  23. package/build/system/mcp-servers/admin/escalations.js +13 -1
  24. package/build/system/mcp-servers/admin/schemas.d.ts +10 -0
  25. package/build/system/mcp-servers/admin/schemas.js +6 -2
  26. package/build/system/seed/tool-manifests-admin.d.ts +88 -0
  27. package/build/system/seed/tool-manifests-admin.js +2 -1
  28. package/build/tsconfig.tsbuildinfo +1 -1
  29. package/dashboard/dist/assets/{AdminDashboard-C4h1R-lz.js → AdminDashboard-CUqnrc7h.js} +2 -2
  30. package/dashboard/dist/assets/{AdminDashboard-C4h1R-lz.js.map → AdminDashboard-CUqnrc7h.js.map} +1 -1
  31. package/dashboard/dist/assets/{AgentConfigPage-EWC8VQ7R.js → AgentConfigPage-lmUOwyHO.js} +6 -6
  32. package/dashboard/dist/assets/{AgentConfigPage-EWC8VQ7R.js.map → AgentConfigPage-lmUOwyHO.js.map} +1 -1
  33. package/dashboard/dist/assets/{AgentDetailPage-DaLfa80d.js → AgentDetailPage-C_xAw6aF.js} +3 -3
  34. package/dashboard/dist/assets/{AgentDetailPage-DaLfa80d.js.map → AgentDetailPage-C_xAw6aF.js.map} +1 -1
  35. package/dashboard/dist/assets/{AgentsPage-islj_zrh.js → AgentsPage-CHCGAkpN.js} +2 -2
  36. package/dashboard/dist/assets/{AgentsPage-islj_zrh.js.map → AgentsPage-CHCGAkpN.js.map} +1 -1
  37. package/dashboard/dist/assets/AvailableEscalationsPage-BvQdHMl2.js +2 -0
  38. package/dashboard/dist/assets/AvailableEscalationsPage-BvQdHMl2.js.map +1 -0
  39. package/dashboard/dist/assets/BotPicker-Dsr8Yyj_.js +2 -0
  40. package/dashboard/dist/assets/{BotPicker-CnX8xfka.js.map → BotPicker-Dsr8Yyj_.js.map} +1 -1
  41. package/dashboard/dist/assets/BulkAssignModal-CbUftMR2.js +2 -0
  42. package/dashboard/dist/assets/BulkAssignModal-CbUftMR2.js.map +1 -0
  43. package/dashboard/dist/assets/CapabilitiesPage-CPNUJPHs.js +2 -0
  44. package/dashboard/dist/assets/{CapabilitiesPage-DK7wGMFt.js.map → CapabilitiesPage-CPNUJPHs.js.map} +1 -1
  45. package/dashboard/dist/assets/{CollapsibleSection-WqEpMTyx.js → CollapsibleSection-DffGX2tR.js} +2 -2
  46. package/dashboard/dist/assets/{CollapsibleSection-WqEpMTyx.js.map → CollapsibleSection-DffGX2tR.js.map} +1 -1
  47. package/dashboard/dist/assets/CountdownTimer-Bb_VuJc8.js +2 -0
  48. package/dashboard/dist/assets/CountdownTimer-Bb_VuJc8.js.map +1 -0
  49. package/dashboard/dist/assets/{CredentialsPage-CfT60FiU.js → CredentialsPage-UXnD_Rau.js} +2 -2
  50. package/dashboard/dist/assets/{CredentialsPage-CfT60FiU.js.map → CredentialsPage-UXnD_Rau.js.map} +1 -1
  51. package/dashboard/dist/assets/{CronLabel-ds7dLz6S.js → CronLabel-CctUYUlI.js} +2 -2
  52. package/dashboard/dist/assets/{CronLabel-ds7dLz6S.js.map → CronLabel-CctUYUlI.js.map} +1 -1
  53. package/dashboard/dist/assets/{DataTable-Bir0Xs1p.js → DataTable-DFPMeqyQ.js} +2 -2
  54. package/dashboard/dist/assets/DataTable-DFPMeqyQ.js.map +1 -0
  55. package/dashboard/dist/assets/{DropZone-DovkhN2p.js → DropZone-7UoXQ4qL.js} +2 -2
  56. package/dashboard/dist/assets/{DropZone-DovkhN2p.js.map → DropZone-7UoXQ4qL.js.map} +1 -1
  57. package/dashboard/dist/assets/{ElapsedCell-DRQhFky_.js → ElapsedCell-C7_Y8xXn.js} +2 -2
  58. package/dashboard/dist/assets/{ElapsedCell-DRQhFky_.js.map → ElapsedCell-C7_Y8xXn.js.map} +1 -1
  59. package/dashboard/dist/assets/{EntityTimelinePanel-nCgWdmpK.js → EntityTimelinePanel-pRu91gZK.js} +2 -2
  60. package/dashboard/dist/assets/{EntityTimelinePanel-nCgWdmpK.js.map → EntityTimelinePanel-pRu91gZK.js.map} +1 -1
  61. package/dashboard/dist/assets/{EscalationListSchemaPage-DBCnPMG9.js → EscalationListSchemaPage-B3f2mjqg.js} +3 -3
  62. package/dashboard/dist/assets/{EscalationListSchemaPage-DBCnPMG9.js.map → EscalationListSchemaPage-B3f2mjqg.js.map} +1 -1
  63. package/dashboard/dist/assets/{EscalationSchemaPage-DfzRTqhV.js → EscalationSchemaPage-AJ85FRZy.js} +3 -3
  64. package/dashboard/dist/assets/{EscalationSchemaPage-DfzRTqhV.js.map → EscalationSchemaPage-AJ85FRZy.js.map} +1 -1
  65. package/dashboard/dist/assets/{EscalationsOverview-CWd2Ivso.js → EscalationsOverview-DMLLWzjS.js} +2 -2
  66. package/dashboard/dist/assets/{EscalationsOverview-CWd2Ivso.js.map → EscalationsOverview-DMLLWzjS.js.map} +1 -1
  67. package/dashboard/dist/assets/{EventTable-Dm9Fbab1.js → EventTable-BlNuCTN6.js} +2 -2
  68. package/dashboard/dist/assets/{EventTable-Dm9Fbab1.js.map → EventTable-BlNuCTN6.js.map} +1 -1
  69. package/dashboard/dist/assets/{FilterBar-DR4cJvTB.js → FilterBar-B-rkcWkV.js} +2 -2
  70. package/dashboard/dist/assets/{FilterBar-DR4cJvTB.js.map → FilterBar-B-rkcWkV.js.map} +1 -1
  71. package/dashboard/dist/assets/{GraphInvokePage-DQt64Ru0.js → GraphInvokePage-Bkt5tAFo.js} +2 -2
  72. package/dashboard/dist/assets/{GraphInvokePage-DQt64Ru0.js.map → GraphInvokePage-Bkt5tAFo.js.map} +1 -1
  73. package/dashboard/dist/assets/{HomePage-D7qNiqtw.js → HomePage-CIE9bCFQ.js} +2 -2
  74. package/dashboard/dist/assets/{HomePage-D7qNiqtw.js.map → HomePage-CIE9bCFQ.js.map} +1 -1
  75. package/dashboard/dist/assets/{ListToolbar-BdZkpRMo.js → ListToolbar-C_-Utxqm.js} +2 -2
  76. package/dashboard/dist/assets/{ListToolbar-BdZkpRMo.js.map → ListToolbar-C_-Utxqm.js.map} +1 -1
  77. package/dashboard/dist/assets/{McpOverview-DHAEYY1b.js → McpOverview-c0p171OK.js} +2 -2
  78. package/dashboard/dist/assets/{McpOverview-DHAEYY1b.js.map → McpOverview-c0p171OK.js.map} +1 -1
  79. package/dashboard/dist/assets/{McpQueryDetailPage-BfGhRO_c.js → McpQueryDetailPage-B61I9-dM.js} +3 -3
  80. package/dashboard/dist/assets/{McpQueryDetailPage-BfGhRO_c.js.map → McpQueryDetailPage-B61I9-dM.js.map} +1 -1
  81. package/dashboard/dist/assets/McpQueryPage-Viqi13Fa.js +2 -0
  82. package/dashboard/dist/assets/{McpQueryPage-3EXLX1Eq.js.map → McpQueryPage-Viqi13Fa.js.map} +1 -1
  83. package/dashboard/dist/assets/{McpRunDetailPage-DHI0F65P.js → McpRunDetailPage-CiAx_xyV.js} +2 -2
  84. package/dashboard/dist/assets/{McpRunDetailPage-DHI0F65P.js.map → McpRunDetailPage-CiAx_xyV.js.map} +1 -1
  85. package/dashboard/dist/assets/{McpRunsPage-C6-KpYCY.js → McpRunsPage-BpfvNRbE.js} +2 -2
  86. package/dashboard/dist/assets/{McpRunsPage-C6-KpYCY.js.map → McpRunsPage-BpfvNRbE.js.map} +1 -1
  87. package/dashboard/dist/assets/{NamespacePill-BeifzjUm.js → NamespacePill-CKp_9EaI.js} +2 -2
  88. package/dashboard/dist/assets/{NamespacePill-BeifzjUm.js.map → NamespacePill-CKp_9EaI.js.map} +1 -1
  89. package/dashboard/dist/assets/OperationsPage-DGKwUE6h.js +3 -0
  90. package/dashboard/dist/assets/OperationsPage-DGKwUE6h.js.map +1 -0
  91. package/dashboard/dist/assets/{OperatorDashboard-DLp9gCTA.js → OperatorDashboard-ha-05tgB.js} +2 -2
  92. package/dashboard/dist/assets/{OperatorDashboard-DLp9gCTA.js.map → OperatorDashboard-ha-05tgB.js.map} +1 -1
  93. package/dashboard/dist/assets/{PageHeader-BpeBHqyc.js → PageHeader-CDDpHpdv.js} +2 -2
  94. package/dashboard/dist/assets/{PageHeader-BpeBHqyc.js.map → PageHeader-CDDpHpdv.js.map} +1 -1
  95. package/dashboard/dist/assets/{PageHeaderWithStats-JXeUFa_g.js → PageHeaderWithStats-DIWH6fRv.js} +2 -2
  96. package/dashboard/dist/assets/{PageHeaderWithStats-JXeUFa_g.js.map → PageHeaderWithStats-DIWH6fRv.js.map} +1 -1
  97. package/dashboard/dist/assets/{PersonaDetailPage-DFv4Zwmq.js → PersonaDetailPage-DMH-D1ns.js} +2 -2
  98. package/dashboard/dist/assets/{PersonaDetailPage-DFv4Zwmq.js.map → PersonaDetailPage-DMH-D1ns.js.map} +1 -1
  99. package/dashboard/dist/assets/{PersonasPage-C52o87Zv.js → PersonasPage-YLjCcQcU.js} +2 -2
  100. package/dashboard/dist/assets/{PersonasPage-C52o87Zv.js.map → PersonasPage-YLjCcQcU.js.map} +1 -1
  101. package/dashboard/dist/assets/{ProcessDetailPage-CKCxXogl.js → ProcessDetailPage-W5_2FJHn.js} +2 -2
  102. package/dashboard/dist/assets/{ProcessDetailPage-CKCxXogl.js.map → ProcessDetailPage-W5_2FJHn.js.map} +1 -1
  103. package/dashboard/dist/assets/{ProcessesListPage-D1bxIy7-.js → ProcessesListPage-5f_2S9ER.js} +2 -2
  104. package/dashboard/dist/assets/{ProcessesListPage-D1bxIy7-.js.map → ProcessesListPage-5f_2S9ER.js.map} +1 -1
  105. package/dashboard/dist/assets/{RoleDetailPage-_MrbOGW_.js → RoleDetailPage-CuDTO13n.js} +3 -3
  106. package/dashboard/dist/assets/{RoleDetailPage-_MrbOGW_.js.map → RoleDetailPage-CuDTO13n.js.map} +1 -1
  107. package/dashboard/dist/assets/{RolePill-EocCXZh0.js → RolePill-C0hExOmI.js} +2 -2
  108. package/dashboard/dist/assets/{RolePill-EocCXZh0.js.map → RolePill-C0hExOmI.js.map} +1 -1
  109. package/dashboard/dist/assets/{RolesPage-ZVCkB4iF.js → RolesPage-McMYumsZ.js} +2 -2
  110. package/dashboard/dist/assets/{RolesPage-ZVCkB4iF.js.map → RolesPage-McMYumsZ.js.map} +1 -1
  111. package/dashboard/dist/assets/RunAsSelector-CC87e67k.js +2 -0
  112. package/dashboard/dist/assets/{RunAsSelector-BAqa1Tya.js.map → RunAsSelector-CC87e67k.js.map} +1 -1
  113. package/dashboard/dist/assets/{ScanCodesPage-b7WkFiy-.js → ScanCodesPage-Zk6Jorv_.js} +2 -2
  114. package/dashboard/dist/assets/{ScanCodesPage-b7WkFiy-.js.map → ScanCodesPage-Zk6Jorv_.js.map} +1 -1
  115. package/dashboard/dist/assets/ScanSchemeDetailPage-B79pya8o.js +2 -0
  116. package/dashboard/dist/assets/ScanSchemeDetailPage-B79pya8o.js.map +1 -0
  117. package/dashboard/dist/assets/ScanStationPage-BLlHMmd_.js +2 -0
  118. package/dashboard/dist/assets/{ScanStationPage-CPC9CdCR.js.map → ScanStationPage-BLlHMmd_.js.map} +1 -1
  119. package/dashboard/dist/assets/{ScopeBadge-H5dEqeHi.js → ScopeBadge-BBQvz4pj.js} +2 -2
  120. package/dashboard/dist/assets/{ScopeBadge-H5dEqeHi.js.map → ScopeBadge-BBQvz4pj.js.map} +1 -1
  121. package/dashboard/dist/assets/StatusBadge-BDeUwPtb.js +2 -0
  122. package/dashboard/dist/assets/StatusBadge-BDeUwPtb.js.map +1 -0
  123. package/dashboard/dist/assets/{StickyPagination-CgSzarlP.js → StickyPagination-CnJgQPU1.js} +2 -2
  124. package/dashboard/dist/assets/{StickyPagination-CgSzarlP.js.map → StickyPagination-CnJgQPU1.js.map} +1 -1
  125. package/dashboard/dist/assets/{StreamMessageDetail-B4E3S5RB.js → StreamMessageDetail-CU5wrqO_.js} +2 -2
  126. package/dashboard/dist/assets/{StreamMessageDetail-B4E3S5RB.js.map → StreamMessageDetail-CU5wrqO_.js.map} +1 -1
  127. package/dashboard/dist/assets/{SwimlaneTimeline-BkcjucMZ.js → SwimlaneTimeline-D5m-_zgy.js} +2 -2
  128. package/dashboard/dist/assets/{SwimlaneTimeline-BkcjucMZ.js.map → SwimlaneTimeline-D5m-_zgy.js.map} +1 -1
  129. package/dashboard/dist/assets/{TagInput-Ch5u6iPH.js → TagInput-BXxXs1JD.js} +2 -2
  130. package/dashboard/dist/assets/{TagInput-Ch5u6iPH.js.map → TagInput-BXxXs1JD.js.map} +1 -1
  131. package/dashboard/dist/assets/{TaskDetailPage-D7e8x2gX.js → TaskDetailPage-SvVSH39Q.js} +2 -2
  132. package/dashboard/dist/assets/{TaskDetailPage-D7e8x2gX.js.map → TaskDetailPage-SvVSH39Q.js.map} +1 -1
  133. package/dashboard/dist/assets/{TaskQueuePill-Bz146p-P.js → TaskQueuePill-BKGJBVZG.js} +2 -2
  134. package/dashboard/dist/assets/{TaskQueuePill-Bz146p-P.js.map → TaskQueuePill-BKGJBVZG.js.map} +1 -1
  135. package/dashboard/dist/assets/{TasksListPage-B4mxP9Ey.js → TasksListPage-BtpwvxkS.js} +2 -2
  136. package/dashboard/dist/assets/{TasksListPage-B4mxP9Ey.js.map → TasksListPage-BtpwvxkS.js.map} +1 -1
  137. package/dashboard/dist/assets/{TimeAgo-D6sbYsUO.js → TimeAgo-BPODA7Dm.js} +2 -2
  138. package/dashboard/dist/assets/{TimeAgo-D6sbYsUO.js.map → TimeAgo-BPODA7Dm.js.map} +1 -1
  139. package/dashboard/dist/assets/{TimestampCell-DFDf3NAT.js → TimestampCell-DEQXlxbH.js} +2 -2
  140. package/dashboard/dist/assets/{TimestampCell-DFDf3NAT.js.map → TimestampCell-DEQXlxbH.js.map} +1 -1
  141. package/dashboard/dist/assets/{ToolPill-sj8OkBB0.js → ToolPill-BY6zLSfA.js} +2 -2
  142. package/dashboard/dist/assets/{ToolPill-sj8OkBB0.js.map → ToolPill-BY6zLSfA.js.map} +1 -1
  143. package/dashboard/dist/assets/{ToolTestPanel-DbWw0-Le.js → ToolTestPanel-Ztc0pRSh.js} +2 -2
  144. package/dashboard/dist/assets/{ToolTestPanel-DbWw0-Le.js.map → ToolTestPanel-Ztc0pRSh.js.map} +1 -1
  145. package/dashboard/dist/assets/{TopicDetailPage-C6CPcvuO.js → TopicDetailPage-BmpEqg-Q.js} +4 -4
  146. package/dashboard/dist/assets/{TopicDetailPage-C6CPcvuO.js.map → TopicDetailPage-BmpEqg-Q.js.map} +1 -1
  147. package/dashboard/dist/assets/{TopicsPage-C8_XpeT2.js → TopicsPage-BVW5y6vE.js} +2 -2
  148. package/dashboard/dist/assets/{TopicsPage-C8_XpeT2.js.map → TopicsPage-BVW5y6vE.js.map} +1 -1
  149. package/dashboard/dist/assets/UserName-D915g7ba.js +2 -0
  150. package/dashboard/dist/assets/{UserName-CIoJvf_e.js.map → UserName-D915g7ba.js.map} +1 -1
  151. package/dashboard/dist/assets/WorkflowExecutionPage-CIl9ESgk.js +2 -0
  152. package/dashboard/dist/assets/WorkflowExecutionPage-CIl9ESgk.js.map +1 -0
  153. package/dashboard/dist/assets/{WorkflowPill-BcA7S3gI.js → WorkflowPill-qp5UF3-y.js} +2 -2
  154. package/dashboard/dist/assets/{WorkflowPill-BcA7S3gI.js.map → WorkflowPill-qp5UF3-y.js.map} +1 -1
  155. package/dashboard/dist/assets/{WorkflowsDashboard-y2L_zwnf.js → WorkflowsDashboard-DtkaGgdZ.js} +2 -2
  156. package/dashboard/dist/assets/{WorkflowsDashboard-y2L_zwnf.js.map → WorkflowsDashboard-DtkaGgdZ.js.map} +1 -1
  157. package/dashboard/dist/assets/{WorkflowsOverview-ChE1Mm3P.js → WorkflowsOverview-DANXhmXb.js} +2 -2
  158. package/dashboard/dist/assets/{WorkflowsOverview-ChE1Mm3P.js.map → WorkflowsOverview-DANXhmXb.js.map} +1 -1
  159. package/dashboard/dist/assets/{YamlWorkflowDetailPage-D0aY_inb.js → YamlWorkflowDetailPage-m6Ub7qtE.js} +2 -2
  160. package/dashboard/dist/assets/{YamlWorkflowDetailPage-D0aY_inb.js.map → YamlWorkflowDetailPage-m6Ub7qtE.js.map} +1 -1
  161. package/dashboard/dist/assets/{YamlWorkflowsPage-DJ0JitPs.js → YamlWorkflowsPage-5MOsxbLW.js} +2 -2
  162. package/dashboard/dist/assets/{YamlWorkflowsPage-DJ0JitPs.js.map → YamlWorkflowsPage-5MOsxbLW.js.map} +1 -1
  163. package/dashboard/dist/assets/{agents-Bu5Ly_ER.js → agents-DacpnIqz.js} +2 -2
  164. package/dashboard/dist/assets/{agents-Bu5Ly_ER.js.map → agents-DacpnIqz.js.map} +1 -1
  165. package/dashboard/dist/assets/{bots-Cb14wZ1Y.js → bots-El47Xy5a.js} +2 -2
  166. package/dashboard/dist/assets/{bots-Cb14wZ1Y.js.map → bots-El47Xy5a.js.map} +1 -1
  167. package/dashboard/dist/assets/{capabilities-DeHLk9JJ.js → capabilities-DGC__Aob.js} +2 -2
  168. package/dashboard/dist/assets/{capabilities-DeHLk9JJ.js.map → capabilities-DGC__Aob.js.map} +1 -1
  169. package/dashboard/dist/assets/{controlplane-YBZ3SbA6.js → controlplane-Bzx-qd8m.js} +2 -2
  170. package/dashboard/dist/assets/{controlplane-YBZ3SbA6.js.map → controlplane-Bzx-qd8m.js.map} +1 -1
  171. package/dashboard/dist/assets/{escalation-columns-CA9DQlhA.js → escalation-columns-BmY7BriY.js} +2 -2
  172. package/dashboard/dist/assets/{escalation-columns-CA9DQlhA.js.map → escalation-columns-BmY7BriY.js.map} +1 -1
  173. package/dashboard/dist/assets/{index-D5MSJsiW.js → index-B4ZNPgcz.js} +2 -2
  174. package/dashboard/dist/assets/{index-D5MSJsiW.js.map → index-B4ZNPgcz.js.map} +1 -1
  175. package/dashboard/dist/assets/index-BPK2cB4Q.js +6 -0
  176. package/dashboard/dist/assets/index-BPK2cB4Q.js.map +1 -0
  177. package/dashboard/dist/assets/{index-B0qNe7Ux.js → index-Bwlnpbpd.js} +2 -2
  178. package/dashboard/dist/assets/{index-B0qNe7Ux.js.map → index-Bwlnpbpd.js.map} +1 -1
  179. package/dashboard/dist/assets/{index-CQriisJy.js → index-CHwg51qz.js} +2 -2
  180. package/dashboard/dist/assets/{index-CQriisJy.js.map → index-CHwg51qz.js.map} +1 -1
  181. package/dashboard/dist/assets/index-CJV2pWNH.css +1 -0
  182. package/dashboard/dist/assets/{index-BaDimDGQ.js → index-Ce6ghhpn.js} +2 -2
  183. package/dashboard/dist/assets/{index-BaDimDGQ.js.map → index-Ce6ghhpn.js.map} +1 -1
  184. package/dashboard/dist/assets/{index-B4Nea96C.js → index-Cfw6FARc.js} +2 -2
  185. package/dashboard/dist/assets/{index-B4Nea96C.js.map → index-Cfw6FARc.js.map} +1 -1
  186. package/dashboard/dist/assets/{index-BAKroiNw.js → index-CoIh4ipz.js} +2 -2
  187. package/dashboard/dist/assets/{index-BAKroiNw.js.map → index-CoIh4ipz.js.map} +1 -1
  188. package/dashboard/dist/assets/index-Cqc7Wu5Y.js +3 -0
  189. package/dashboard/dist/assets/index-Cqc7Wu5Y.js.map +1 -0
  190. package/dashboard/dist/assets/index-DH_xm9UQ.js +2 -0
  191. package/dashboard/dist/assets/{index-chMUPSOd.js.map → index-DH_xm9UQ.js.map} +1 -1
  192. package/dashboard/dist/assets/{index-B7fE-rND.js → index-DYz57kr_.js} +2 -2
  193. package/dashboard/dist/assets/{index-B7fE-rND.js.map → index-DYz57kr_.js.map} +1 -1
  194. package/dashboard/dist/assets/{index-YUv7aNb4.js → index-DpsVlk5z.js} +2 -2
  195. package/dashboard/dist/assets/{index-YUv7aNb4.js.map → index-DpsVlk5z.js.map} +1 -1
  196. package/dashboard/dist/assets/{index-Ntul2ZC1.js → index-SU2xrnBD.js} +29 -28
  197. package/dashboard/dist/assets/index-SU2xrnBD.js.map +1 -0
  198. package/dashboard/dist/assets/{index-BRmgxeZM.js → index-ZtpEajtq.js} +3 -3
  199. package/dashboard/dist/assets/{index-BRmgxeZM.js.map → index-ZtpEajtq.js.map} +1 -1
  200. package/dashboard/dist/assets/{knowledge-B1HqYuB2.js → knowledge-k-5jr2BN.js} +2 -2
  201. package/dashboard/dist/assets/{knowledge-B1HqYuB2.js.map → knowledge-k-5jr2BN.js.map} +1 -1
  202. package/dashboard/dist/assets/{mcp-dhihqJpH.js → mcp-BEqxxlW9.js} +2 -2
  203. package/dashboard/dist/assets/{mcp-dhihqJpH.js.map → mcp-BEqxxlW9.js.map} +1 -1
  204. package/dashboard/dist/assets/{mcp-query-B_gkB7JK.js → mcp-query-qXTlQfc_.js} +2 -2
  205. package/dashboard/dist/assets/{mcp-query-B_gkB7JK.js.map → mcp-query-qXTlQfc_.js.map} +1 -1
  206. package/dashboard/dist/assets/{personas-Bw_OlfI6.js → personas-jJEDmBtg.js} +2 -2
  207. package/dashboard/dist/assets/{personas-Bw_OlfI6.js.map → personas-jJEDmBtg.js.map} +1 -1
  208. package/dashboard/dist/assets/{pipelines-BYwn0LXY.js → pipelines-BNPJh69x.js} +2 -2
  209. package/dashboard/dist/assets/{pipelines-BYwn0LXY.js.map → pipelines-BNPJh69x.js.map} +1 -1
  210. package/dashboard/dist/assets/{tasks-t6bPmJ7P.js → tasks-DhD71qXJ.js} +2 -2
  211. package/dashboard/dist/assets/{tasks-t6bPmJ7P.js.map → tasks-DhD71qXJ.js.map} +1 -1
  212. package/dashboard/dist/assets/{topics-Bgo9xw80.js → topics-CrXwwuW-.js} +2 -2
  213. package/dashboard/dist/assets/{topics-Bgo9xw80.js.map → topics-CrXwwuW-.js.map} +1 -1
  214. package/dashboard/dist/assets/{useEventHooks-BJbMbg_h.js → useEventHooks-DL7R0ASv.js} +2 -2
  215. package/dashboard/dist/assets/{useEventHooks-BJbMbg_h.js.map → useEventHooks-DL7R0ASv.js.map} +1 -1
  216. package/dashboard/dist/assets/{useNamespace-CaXJuSFG.js → useNamespace-ETqzJakA.js} +2 -2
  217. package/dashboard/dist/assets/{useNamespace-CaXJuSFG.js.map → useNamespace-ETqzJakA.js.map} +1 -1
  218. package/dashboard/dist/assets/{useYamlActivityEvents-B47LQrDk.js → useYamlActivityEvents-SqY67S-F.js} +2 -2
  219. package/dashboard/dist/assets/{useYamlActivityEvents-B47LQrDk.js.map → useYamlActivityEvents-SqY67S-F.js.map} +1 -1
  220. package/dashboard/dist/assets/{users-D0jvzUqW.js → users-DF8dTbOo.js} +2 -2
  221. package/dashboard/dist/assets/{users-D0jvzUqW.js.map → users-DF8dTbOo.js.map} +1 -1
  222. package/dashboard/dist/assets/{vendor-icons-BPsNpK3Y.js → vendor-icons-BgsXTN4h.js} +145 -140
  223. package/dashboard/dist/assets/vendor-icons-BgsXTN4h.js.map +1 -0
  224. package/dashboard/dist/assets/{workflows-DRoZRrMH.js → workflows-Bdke7fzx.js} +2 -2
  225. package/dashboard/dist/assets/{workflows-DRoZRrMH.js.map → workflows-Bdke7fzx.js.map} +1 -1
  226. package/dashboard/dist/assets/{yaml-workflows-BdhYyIef.js → yaml-workflows-UMxHYunb.js} +2 -2
  227. package/dashboard/dist/assets/{yaml-workflows-BdhYyIef.js.map → yaml-workflows-UMxHYunb.js.map} +1 -1
  228. package/dashboard/dist/index.html +3 -3
  229. package/docs/api/http/escalations.md +29 -0
  230. package/docs/dashboard.md +2 -0
  231. package/docs/events.md +1 -1
  232. package/docs/hitl/form.md +1 -0
  233. package/docs/hitl/x-lt-footer.md +6 -0
  234. package/docs/hitl/x-lt-list-schema.md +4 -2
  235. package/docs/hitl/x-lt-validation.md +62 -1
  236. package/docs/hitl-guide.md +3 -0
  237. package/package.json +1 -1
  238. package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js +0 -2
  239. package/dashboard/dist/assets/AvailableEscalationsPage-B8NjwwKQ.js.map +0 -1
  240. package/dashboard/dist/assets/BotPicker-CnX8xfka.js +0 -2
  241. package/dashboard/dist/assets/CapabilitiesPage-DK7wGMFt.js +0 -2
  242. package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js +0 -2
  243. package/dashboard/dist/assets/CountdownTimer-BvQw_3WJ.js.map +0 -1
  244. package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js +0 -2
  245. package/dashboard/dist/assets/CustomDurationPicker-D-iY1f4n.js.map +0 -1
  246. package/dashboard/dist/assets/DataTable-Bir0Xs1p.js.map +0 -1
  247. package/dashboard/dist/assets/McpQueryPage-3EXLX1Eq.js +0 -2
  248. package/dashboard/dist/assets/OperationsPage-BNW7uris.js +0 -3
  249. package/dashboard/dist/assets/OperationsPage-BNW7uris.js.map +0 -1
  250. package/dashboard/dist/assets/RunAsSelector-BAqa1Tya.js +0 -2
  251. package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js +0 -2
  252. package/dashboard/dist/assets/ScanSchemeDetailPage-BCsEgS-s.js.map +0 -1
  253. package/dashboard/dist/assets/ScanStationPage-CPC9CdCR.js +0 -2
  254. package/dashboard/dist/assets/StatusBadge-DkgllZHv.js +0 -2
  255. package/dashboard/dist/assets/StatusBadge-DkgllZHv.js.map +0 -1
  256. package/dashboard/dist/assets/UserName-CIoJvf_e.js +0 -2
  257. package/dashboard/dist/assets/WorkflowExecutionPage-Bq3kSkRr.js +0 -2
  258. package/dashboard/dist/assets/WorkflowExecutionPage-Bq3kSkRr.js.map +0 -1
  259. package/dashboard/dist/assets/index-B5jxf81r.css +0 -1
  260. package/dashboard/dist/assets/index-BhurEB5s.js +0 -6
  261. package/dashboard/dist/assets/index-BhurEB5s.js.map +0 -1
  262. package/dashboard/dist/assets/index-Ntul2ZC1.js.map +0 -1
  263. package/dashboard/dist/assets/index-chMUPSOd.js +0 -2
  264. package/dashboard/dist/assets/index-uWUJXqGS.js +0 -3
  265. package/dashboard/dist/assets/index-uWUJXqGS.js.map +0 -1
  266. package/dashboard/dist/assets/vendor-icons-BPsNpK3Y.js.map +0 -1
@@ -49,6 +49,9 @@ export declare function bulkClaim(input: {
49
49
  * @param input.query — `{ role, facets? }` selector (query form)
50
50
  * @param input.targetUserId — user to assign to
51
51
  * @param input.durationMinutes — assignment duration (default: 30)
52
+ * @param input.reassign — also take over rows under a LIVE claim (ids form
53
+ * only; requires admin/superadmin). Default false: live claims are skipped
54
+ * and counted in `skipped`.
52
55
  * @param auth — authenticated user context
53
56
  * @returns `{ status: 200, data: { assigned, skipped } }`
54
57
  */
@@ -60,6 +63,21 @@ export declare function bulkAssign(input: {
60
63
  };
61
64
  targetUserId: string;
62
65
  durationMinutes?: number;
66
+ reassign?: boolean;
67
+ }, auth: LTApiAuth): Promise<LTApiResult>;
68
+ /**
69
+ * Return claimed escalations to the available pool — the admin override of
70
+ * someone else's live claim (self-return stays the release verb). One
71
+ * guarded statement; unclaimed and terminal rows are skipped. Publishes a
72
+ * `released` event per returned row with the acting admin in the delta.
73
+ *
74
+ * RBAC: admin/superadmin (global escalation access) only.
75
+ *
76
+ * @param input.ids — array of escalation UUIDs
77
+ * @returns `{ status: 200, data: { unassigned, skipped } }`
78
+ */
79
+ export declare function bulkUnassign(input: {
80
+ ids?: string[];
63
81
  }, auth: LTApiAuth): Promise<LTApiResult>;
64
82
  /**
65
83
  * Route multiple escalations to a different role.
@@ -37,6 +37,7 @@ exports.releaseExpiredClaims = releaseExpiredClaims;
37
37
  exports.updatePriority = updatePriority;
38
38
  exports.bulkClaim = bulkClaim;
39
39
  exports.bulkAssign = bulkAssign;
40
+ exports.bulkUnassign = bulkUnassign;
40
41
  exports.bulkEscalate = bulkEscalate;
41
42
  exports.bulkTriage = bulkTriage;
42
43
  const escalationService = __importStar(require("../../services/escalation"));
@@ -133,12 +134,15 @@ async function bulkClaim(input, auth) {
133
134
  * @param input.query — `{ role, facets? }` selector (query form)
134
135
  * @param input.targetUserId — user to assign to
135
136
  * @param input.durationMinutes — assignment duration (default: 30)
137
+ * @param input.reassign — also take over rows under a LIVE claim (ids form
138
+ * only; requires admin/superadmin). Default false: live claims are skipped
139
+ * and counted in `skipped`.
136
140
  * @param auth — authenticated user context
137
141
  * @returns `{ status: 200, data: { assigned, skipped } }`
138
142
  */
139
143
  async function bulkAssign(input, auth) {
140
144
  try {
141
- const { ids, query, targetUserId, durationMinutes } = input;
145
+ const { ids, query, targetUserId, durationMinutes, reassign } = input;
142
146
  if (!targetUserId || typeof targetUserId !== 'string') {
143
147
  return { status: 400, error: 'targetUserId is required' };
144
148
  }
@@ -147,6 +151,14 @@ async function bulkAssign(input, auth) {
147
151
  if (hasIds === hasQuery) {
148
152
  return { status: 400, error: 'provide exactly one of ids or query' };
149
153
  }
154
+ if (reassign === true && hasQuery) {
155
+ return { status: 400, error: 'reassign requires the ids form' };
156
+ }
157
+ // Taking over a LIVE claim is a management override — stricter than
158
+ // pre-assigning pool rows, which role-scoped admins may do.
159
+ if (reassign === true && !(await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId))) {
160
+ return { status: 403, error: 'Forbidden: reassign requires admin access' };
161
+ }
150
162
  if (hasQuery) {
151
163
  if (!query.role || typeof query.role !== 'string') {
152
164
  return { status: 400, error: 'query.role is required' };
@@ -186,6 +198,14 @@ async function bulkAssign(input, auth) {
186
198
  }
187
199
  }
188
200
  }
201
+ if (reassign === true) {
202
+ const result = await escalationService.bulkReassignEscalations(ids, targetUserId, durationMinutes ?? 30);
203
+ if (result.assigned > 0) {
204
+ const priorById = new Map(result.changes.map((c) => [c.id, c.prior_assignee]));
205
+ (0, helpers_1.publishBulkClaimEvents)(result.changes.map((c) => c.id), targetUserId, undefined, priorById);
206
+ }
207
+ return { status: 200, data: { assigned: result.assigned, skipped: result.skipped } };
208
+ }
189
209
  const result = await escalationService.bulkAssignEscalations(ids, targetUserId, durationMinutes ?? 30);
190
210
  if (result.assigned > 0)
191
211
  (0, helpers_1.publishBulkClaimEvents)(ids, targetUserId);
@@ -195,6 +215,34 @@ async function bulkAssign(input, auth) {
195
215
  return { status: 500, error: err.message };
196
216
  }
197
217
  }
218
+ /**
219
+ * Return claimed escalations to the available pool — the admin override of
220
+ * someone else's live claim (self-return stays the release verb). One
221
+ * guarded statement; unclaimed and terminal rows are skipped. Publishes a
222
+ * `released` event per returned row with the acting admin in the delta.
223
+ *
224
+ * RBAC: admin/superadmin (global escalation access) only.
225
+ *
226
+ * @param input.ids — array of escalation UUIDs
227
+ * @returns `{ status: 200, data: { unassigned, skipped } }`
228
+ */
229
+ async function bulkUnassign(input, auth) {
230
+ try {
231
+ if (!(0, helpers_1.validateIds)(input.ids ?? [])) {
232
+ return { status: 400, error: 'ids must be a non-empty array' };
233
+ }
234
+ if (!(await (0, helpers_1.hasGlobalEscalationAccess)(auth.userId))) {
235
+ return { status: 403, error: 'Forbidden: unassign requires admin access' };
236
+ }
237
+ const result = await escalationService.bulkUnassignEscalations(input.ids);
238
+ if (result.unassigned > 0)
239
+ (0, helpers_1.publishBulkReleaseEvents)(result.changes, auth.userId);
240
+ return { status: 200, data: { unassigned: result.unassigned, skipped: result.skipped } };
241
+ }
242
+ catch (err) {
243
+ return { status: 500, error: err.message };
244
+ }
245
+ }
198
246
  /**
199
247
  * Route multiple escalations to a different role.
200
248
  *
@@ -150,4 +150,14 @@ export declare function publishBulkReassignEvents(beforeRows: Array<{
150
150
  id: string;
151
151
  role: string;
152
152
  }>, targetRole: string): void;
153
- export declare function publishBulkClaimEvents(ids: string[], assignedTo: string, knownRole?: string): void;
153
+ export declare function publishBulkClaimEvents(ids: string[], assignedTo: string, knownRole?: string, priorById?: Map<string, string | null>): void;
154
+ /**
155
+ * Per-row released events for an admin unassign — the row returns to the
156
+ * pool under the same verb a self-release produces, with the acting admin in
157
+ * the delta.
158
+ */
159
+ export declare function publishBulkReleaseEvents(changes: Array<{
160
+ id: string;
161
+ role: string;
162
+ prior_assignee: string | null;
163
+ }>, releasedBy: string): void;
@@ -46,6 +46,7 @@ exports.resolveAssignee = resolveAssignee;
46
46
  exports.ensureRoleMembership = ensureRoleMembership;
47
47
  exports.publishBulkReassignEvents = publishBulkReassignEvents;
48
48
  exports.publishBulkClaimEvents = publishBulkClaimEvents;
49
+ exports.publishBulkReleaseEvents = publishBulkReleaseEvents;
49
50
  const escalationService = __importStar(require("../../services/escalation"));
50
51
  const userService = __importStar(require("../../services/user"));
51
52
  const publish_1 = require("../../lib/events/publish");
@@ -283,10 +284,11 @@ function publishBulkReassignEvents(beforeRows, targetRole) {
283
284
  }
284
285
  }
285
286
  }
286
- function publishBulkClaimEvents(ids, assignedTo, knownRole) {
287
+ function publishBulkClaimEvents(ids, assignedTo, knownRole, priorById) {
287
288
  // The claimed subject carries each row's role token. Query-form callers
288
289
  // already know the single role; id-form callers resolve roles with one
289
- // indexed read. Fire-and-forget, like every event publish.
290
+ // indexed read. Fire-and-forget, like every event publish. `priorById`
291
+ // (reassign) adds the displaced assignee to each row's delta.
290
292
  void (async () => {
291
293
  const roleById = new Map();
292
294
  if (knownRole) {
@@ -299,6 +301,7 @@ function publishBulkClaimEvents(ids, assignedTo, knownRole) {
299
301
  roleById.set(row.id, row.role);
300
302
  }
301
303
  for (const id of ids) {
304
+ const prior = priorById?.get(id);
302
305
  (0, publish_1.publishEscalationEvent)({
303
306
  type: 'escalation.claimed',
304
307
  source: 'api',
@@ -310,8 +313,32 @@ function publishBulkClaimEvents(ids, assignedTo, knownRole) {
310
313
  status: 'claimed',
311
314
  // Bulk exception to the one-shape convention (see lib/events/escalation-wire.ts):
312
315
  // delta + `bulk: true`, no per-row fetch. Subscribers fetch by id for detail.
313
- data: { assigned_to: assignedTo, bulk: true },
316
+ data: { assigned_to: assignedTo, bulk: true, ...(prior ? { reassigned_from: prior } : {}) },
314
317
  });
315
318
  }
316
319
  })().catch(() => { });
317
320
  }
321
+ /**
322
+ * Per-row released events for an admin unassign — the row returns to the
323
+ * pool under the same verb a self-release produces, with the acting admin in
324
+ * the delta.
325
+ */
326
+ function publishBulkReleaseEvents(changes, releasedBy) {
327
+ for (const change of changes) {
328
+ void (0, publish_1.publishEscalationEvent)({
329
+ type: 'escalation.released',
330
+ source: 'api',
331
+ workflowId: '',
332
+ workflowName: '',
333
+ taskQueue: '',
334
+ escalationId: change.id,
335
+ role: change.role,
336
+ status: 'released',
337
+ data: {
338
+ released_by: releasedBy,
339
+ bulk: true,
340
+ ...(change.prior_assignee ? { unassigned_from: change.prior_assignee } : {}),
341
+ },
342
+ });
343
+ }
344
+ }
@@ -2,7 +2,7 @@ export { createEscalation } from './create';
2
2
  export { listEscalations, listAvailableEscalations, listDistinctTypes, listFacetKeys, getEscalationStats, getStationMetrics } from './list';
3
3
  export { getEscalation, getEscalationsByWorkflowId, escalateToRole } from './single';
4
4
  export { claimEscalation, releaseEscalation } from './claim';
5
- export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkEscalate, bulkTriage } from './bulk';
5
+ export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkUnassign, bulkEscalate, bulkTriage } from './bulk';
6
6
  export { resolveEscalation, resolveBySignalKey, resolveByIds, resolveAllOrNone } from './resolve';
7
7
  export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
8
8
  export { cancelSingleEscalation, bulkCancel } from './cancel';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
3
+ exports.timelineByFacet = exports.aggregateByFacets = exports.claimByFacets = exports.claimGroups = exports.searchByFacets = exports.bulkCancel = exports.cancelSingleEscalation = exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveAllOrNone = exports.resolveByIds = exports.resolveBySignalKey = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkUnassign = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetKeys = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
4
4
  var create_1 = require("./create");
5
5
  Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
6
6
  var list_1 = require("./list");
@@ -22,6 +22,7 @@ Object.defineProperty(exports, "releaseExpiredClaims", { enumerable: true, get:
22
22
  Object.defineProperty(exports, "updatePriority", { enumerable: true, get: function () { return bulk_1.updatePriority; } });
23
23
  Object.defineProperty(exports, "bulkClaim", { enumerable: true, get: function () { return bulk_1.bulkClaim; } });
24
24
  Object.defineProperty(exports, "bulkAssign", { enumerable: true, get: function () { return bulk_1.bulkAssign; } });
25
+ Object.defineProperty(exports, "bulkUnassign", { enumerable: true, get: function () { return bulk_1.bulkUnassign; } });
25
26
  Object.defineProperty(exports, "bulkEscalate", { enumerable: true, get: function () { return bulk_1.bulkEscalate; } });
26
27
  Object.defineProperty(exports, "bulkTriage", { enumerable: true, get: function () { return bulk_1.bulkTriage; } });
27
28
  var resolve_1 = require("./resolve");
@@ -54,9 +54,15 @@ function registerBulkRoutes(router) {
54
54
  query: req.body?.query,
55
55
  targetUserId: req.body?.targetUserId,
56
56
  durationMinutes: req.body?.durationMinutes,
57
+ // Take over live claims too (ids form; admin/superadmin only).
58
+ reassign: req.body?.reassign === true,
57
59
  }, req.auth);
58
60
  res.status(result.status).json(result.data ?? { error: result.error });
59
61
  });
62
+ router.post('/bulk-unassign', async (req, res) => {
63
+ const result = await api.bulkUnassign({ ids: req.body?.ids }, req.auth);
64
+ res.status(result.status).json(result.data ?? { error: result.error });
65
+ });
60
66
  router.patch('/bulk-escalate', async (req, res) => {
61
67
  const result = await api.bulkEscalate({ ids: req.body?.ids, targetRole: req.body?.targetRole }, req.auth);
62
68
  res.status(result.status).json(result.data ?? { error: result.error });
@@ -181,6 +181,10 @@ export declare function createClient(options?: LTClientOptions): {
181
181
  };
182
182
  targetUserId: string;
183
183
  durationMinutes?: number;
184
+ reassign?: boolean;
185
+ }, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
186
+ bulkUnassign: (input: {
187
+ ids?: string[];
184
188
  }, auth?: LTApiAuth) => Promise<LTApiResult<any>>;
185
189
  bulkEscalate: (input: {
186
190
  ids: string[];
@@ -136,6 +136,7 @@ function createClient(options = {}) {
136
136
  updatePriority: bindAuth(escalationsApi.updatePriority, auth),
137
137
  bulkClaim: bindAuth(escalationsApi.bulkClaim, auth),
138
138
  bulkAssign: bindAuth(escalationsApi.bulkAssign, auth),
139
+ bulkUnassign: bindAuth(escalationsApi.bulkUnassign, auth),
139
140
  bulkEscalate: bindAuth(escalationsApi.bulkEscalate, auth),
140
141
  bulkTriage: bindAuth(escalationsApi.bulkTriage, auth),
141
142
  findByMetadata: bindAuth(escalationsApi.findByMetadata, auth),
@@ -1,4 +1,10 @@
1
1
  import type { LTEscalationRecord } from '../../types';
2
+ /** One row touched by a reassign/unassign, with its pre-update assignee. */
3
+ export interface AssignmentChange {
4
+ id: string;
5
+ role: string;
6
+ prior_assignee: string | null;
7
+ }
2
8
  /**
3
9
  * Bulk claim escalations for a user.
4
10
  * Items already claimed by another active user are skipped.
@@ -29,6 +35,27 @@ export declare function bulkAssignEscalationsByQuery(query: {
29
35
  assigned: number;
30
36
  ids: string[];
31
37
  }>;
38
+ /**
39
+ * Reassign pending rows to a user, INCLUDING rows under a live claim — the
40
+ * management override plain assign is not (claimMany skips live claims). One
41
+ * guarded statement; rows not returned were terminal or missing. Each
42
+ * returned row carries its pre-update assignee for the event.
43
+ */
44
+ export declare function bulkReassignEscalations(ids: string[], targetUserId: string, durationMinutes?: number): Promise<{
45
+ assigned: number;
46
+ skipped: number;
47
+ changes: AssignmentChange[];
48
+ }>;
49
+ /**
50
+ * Return pending claimed rows to the available pool (admin override of
51
+ * someone else's claim — self-return stays the release verb). One guarded
52
+ * statement; unclaimed and terminal rows are skipped.
53
+ */
54
+ export declare function bulkUnassignEscalations(ids: string[]): Promise<{
55
+ unassigned: number;
56
+ skipped: number;
57
+ changes: AssignmentChange[];
58
+ }>;
32
59
  /**
33
60
  * Bulk reassign escalations to a different role.
34
61
  * Clears assignment on all affected rows.
@@ -3,11 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.bulkClaimEscalations = bulkClaimEscalations;
4
4
  exports.bulkAssignEscalations = bulkAssignEscalations;
5
5
  exports.bulkAssignEscalationsByQuery = bulkAssignEscalationsByQuery;
6
+ exports.bulkReassignEscalations = bulkReassignEscalations;
7
+ exports.bulkUnassignEscalations = bulkUnassignEscalations;
6
8
  exports.bulkEscalateToRole = bulkEscalateToRole;
7
9
  exports.bulkCancelEscalations = bulkCancelEscalations;
8
10
  exports.bulkResolveForTriage = bulkResolveForTriage;
11
+ const db_1 = require("../../lib/db");
9
12
  const client_1 = require("./client");
10
13
  const map_1 = require("./map");
14
+ const sql_1 = require("./sql");
11
15
  /**
12
16
  * Bulk claim escalations for a user.
13
17
  * Items already claimed by another active user are skipped.
@@ -49,6 +53,41 @@ async function bulkAssignEscalationsByQuery(query, targetUserId, durationMinutes
49
53
  });
50
54
  return { assigned: claimed, ids: entries.map((e) => e.id) };
51
55
  }
56
+ /**
57
+ * Reassign pending rows to a user, INCLUDING rows under a live claim — the
58
+ * management override plain assign is not (claimMany skips live claims). One
59
+ * guarded statement; rows not returned were terminal or missing. Each
60
+ * returned row carries its pre-update assignee for the event.
61
+ */
62
+ async function bulkReassignEscalations(ids, targetUserId, durationMinutes = 30) {
63
+ if (ids.length === 0)
64
+ return { assigned: 0, skipped: 0, changes: [] };
65
+ await (0, client_1.ensureEscalationCompatView)();
66
+ const { rows } = await (0, db_1.getPool)().query(sql_1.BULK_REASSIGN, [ids, targetUserId, durationMinutes]);
67
+ const changes = rows.map((r) => ({
68
+ id: r.id,
69
+ role: r.role,
70
+ prior_assignee: r.prior_assignee ?? null,
71
+ }));
72
+ return { assigned: rows.length, skipped: ids.length - rows.length, changes };
73
+ }
74
+ /**
75
+ * Return pending claimed rows to the available pool (admin override of
76
+ * someone else's claim — self-return stays the release verb). One guarded
77
+ * statement; unclaimed and terminal rows are skipped.
78
+ */
79
+ async function bulkUnassignEscalations(ids) {
80
+ if (ids.length === 0)
81
+ return { unassigned: 0, skipped: 0, changes: [] };
82
+ await (0, client_1.ensureEscalationCompatView)();
83
+ const { rows } = await (0, db_1.getPool)().query(sql_1.BULK_UNASSIGN, [ids]);
84
+ const changes = rows.map((r) => ({
85
+ id: r.id,
86
+ role: r.role,
87
+ prior_assignee: r.prior_assignee ?? null,
88
+ }));
89
+ return { unassigned: rows.length, skipped: ids.length - rows.length, changes };
90
+ }
52
91
  /**
53
92
  * Bulk reassign escalations to a different role.
54
93
  * Clears assignment on all affected rows.
@@ -8,6 +8,23 @@
8
8
  * table. Clears both `assigned_until` and `claim_expires_at`.
9
9
  */
10
10
  export declare const RELEASE_EXPIRED_CLAIMS = "UPDATE public.hmsh_escalations\nSET assigned_to = NULL,\n assigned_until = NULL,\n claimed_at = NULL,\n claim_expires_at = NULL,\n updated_at = NOW()\nWHERE status = 'pending'\n AND assigned_to IS NOT NULL\n AND assigned_until <= NOW()";
11
+ /**
12
+ * Reassign: hand pending rows to a user, INCLUDING rows under a live claim —
13
+ * the management override that plain assign (claimMany, which skips live
14
+ * claims) deliberately is not. One statement: the CTE reads each row's
15
+ * pre-update assignee (CTEs share one snapshot), so callers get
16
+ * prior_assignee for the event with no read-then-write window. An in-flight
17
+ * resolve by the prior assignee fails its claim assertion once assigned_to
18
+ * changes.
19
+ */
20
+ export declare const BULK_REASSIGN = "WITH prior AS (\n SELECT id, assigned_to FROM public.hmsh_escalations WHERE id = ANY($1::uuid[])\n)\nUPDATE public.hmsh_escalations e\nSET assigned_to = $2,\n assigned_until = NOW() + ($3::int * interval '1 minute'),\n claimed_at = NOW(),\n updated_at = NOW()\nFROM prior\nWHERE e.id = prior.id\n AND e.status = 'pending'\nRETURNING e.*, prior.assigned_to AS prior_assignee";
21
+ /**
22
+ * Unassign: return pending claimed rows to the available pool (an admin
23
+ * override of someone else's claim — self-return stays the release verb).
24
+ * Clears the same field set as RELEASE_EXPIRED_CLAIMS, without the expiry
25
+ * predicate.
26
+ */
27
+ export declare const BULK_UNASSIGN = "WITH prior AS (\n SELECT id, assigned_to FROM public.hmsh_escalations WHERE id = ANY($1::uuid[])\n)\nUPDATE public.hmsh_escalations e\nSET assigned_to = NULL,\n assigned_until = NULL,\n claimed_at = NULL,\n claim_expires_at = NULL,\n updated_at = NOW()\nFROM prior\nWHERE e.id = prior.id\n AND e.status = 'pending'\n AND e.assigned_to IS NOT NULL\nRETURNING e.*, prior.assigned_to AS prior_assignee";
11
28
  /** Count matching the search WHERE (params $1–$13). */
12
29
  export declare const COUNT_SEARCH_ESCALATIONS = "SELECT COUNT(*)::int AS total\n FROM public.lt_escalations\n WHERE ($1::text IS NULL OR status = $1)\n AND ($2::text IS NULL OR role = $2)\n AND (\n ($3::text[] IS NULL AND $10::text[] IS NULL)\n OR ($3::text[] IS NOT NULL AND role = ANY($3))\n OR ($10::text[] IS NOT NULL AND role = ANY($10) AND assigned_to = $11)\n )\n AND ($4::text IS NULL OR type = $4)\n AND ($5::text IS NULL OR subtype = $5)\n AND ($6::int IS NULL OR priority = $6)\n AND ($7::text IS NULL OR assigned_to = $7)\n AND ($8::boolean IS NULL OR available = $8)\n AND ($12::jsonb IS NULL OR metadata @> $12)\n AND ($9::text IS NULL OR origin_id = $9 OR workflow_id = $9\n OR ($13::uuid IS NOT NULL AND id = $13::uuid))";
13
30
  /**
@@ -11,7 +11,7 @@
11
11
  // `hmsh_escalations` here rather than composed from generic SDK calls.
12
12
  // ---------------------------------------------------------------------------
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.STATION_PERIOD_METRICS_SQL = exports.STATION_LIVE_COUNTS_SQL = exports.RESOLVE_BY_METADATA_ATOMIC = exports.COUNT_SEARCH_ESCALATIONS = exports.RELEASE_EXPIRED_CLAIMS = void 0;
14
+ exports.STATION_PERIOD_METRICS_SQL = exports.STATION_LIVE_COUNTS_SQL = exports.RESOLVE_BY_METADATA_ATOMIC = exports.COUNT_SEARCH_ESCALATIONS = exports.BULK_UNASSIGN = exports.BULK_REASSIGN = exports.RELEASE_EXPIRED_CLAIMS = void 0;
15
15
  exports.searchEscalationsQuery = searchEscalationsQuery;
16
16
  /**
17
17
  * Sweep expired claims back to the available pool.
@@ -32,6 +32,49 @@ SET assigned_to = NULL,
32
32
  WHERE status = 'pending'
33
33
  AND assigned_to IS NOT NULL
34
34
  AND assigned_until <= NOW()`;
35
+ /**
36
+ * Reassign: hand pending rows to a user, INCLUDING rows under a live claim —
37
+ * the management override that plain assign (claimMany, which skips live
38
+ * claims) deliberately is not. One statement: the CTE reads each row's
39
+ * pre-update assignee (CTEs share one snapshot), so callers get
40
+ * prior_assignee for the event with no read-then-write window. An in-flight
41
+ * resolve by the prior assignee fails its claim assertion once assigned_to
42
+ * changes.
43
+ */
44
+ exports.BULK_REASSIGN = `\
45
+ WITH prior AS (
46
+ SELECT id, assigned_to FROM public.hmsh_escalations WHERE id = ANY($1::uuid[])
47
+ )
48
+ UPDATE public.hmsh_escalations e
49
+ SET assigned_to = $2,
50
+ assigned_until = NOW() + ($3::int * interval '1 minute'),
51
+ claimed_at = NOW(),
52
+ updated_at = NOW()
53
+ FROM prior
54
+ WHERE e.id = prior.id
55
+ AND e.status = 'pending'
56
+ RETURNING e.*, prior.assigned_to AS prior_assignee`;
57
+ /**
58
+ * Unassign: return pending claimed rows to the available pool (an admin
59
+ * override of someone else's claim — self-return stays the release verb).
60
+ * Clears the same field set as RELEASE_EXPIRED_CLAIMS, without the expiry
61
+ * predicate.
62
+ */
63
+ exports.BULK_UNASSIGN = `\
64
+ WITH prior AS (
65
+ SELECT id, assigned_to FROM public.hmsh_escalations WHERE id = ANY($1::uuid[])
66
+ )
67
+ UPDATE public.hmsh_escalations e
68
+ SET assigned_to = NULL,
69
+ assigned_until = NULL,
70
+ claimed_at = NULL,
71
+ claim_expires_at = NULL,
72
+ updated_at = NOW()
73
+ FROM prior
74
+ WHERE e.id = prior.id
75
+ AND e.status = 'pending'
76
+ AND e.assigned_to IS NOT NULL
77
+ RETURNING e.*, prior.assigned_to AS prior_assignee`;
35
78
  /**
36
79
  * Escalation search by correlation id.
37
80
  *
@@ -5,6 +5,7 @@ exports.validateRequireAll = validateRequireAll;
5
5
  exports.validateFieldType = validateFieldType;
6
6
  exports.validateFieldConstraints = validateFieldConstraints;
7
7
  exports.validateField = validateField;
8
+ const x_lt_options_1 = require("./x-lt-options");
8
9
  /**
9
10
  * Resolve a checklist widget's item definitions from its `x-lt-source`
10
11
  * "domain.path" against the escalation context. Missing domain/path or a
@@ -94,10 +95,11 @@ function validateFieldType(value, fieldSchema) {
94
95
  function validateFieldConstraints(value, fieldSchema, ctx) {
95
96
  if (!fieldSchema)
96
97
  return undefined;
97
- // Enum membership — the form's select widget constrains choices; API-first
98
- // callers are unconstrained, so the schema's enum is the contract.
99
- const allowed = fieldSchema.enum;
100
- if (Array.isArray(allowed) && allowed.length > 0
98
+ // Option membership — the form's select widget constrains choices; API-first
99
+ // callers are unconstrained, so the effective option list is the contract:
100
+ // the static enum, or the x-lt-options list resolved from context.
101
+ const allowed = (0, x_lt_options_1.resolveFieldOptions)(fieldSchema, ctx);
102
+ if (allowed && allowed.length > 0
101
103
  && value !== undefined && value !== null && value !== ''
102
104
  && !allowed.includes(value)) {
103
105
  return `Must be one of: ${allowed.map((v) => String(v)).join(', ')}`;
@@ -14,5 +14,7 @@ export * from './x-lt-query';
14
14
  export * from './x-lt-submit-guard';
15
15
  export * from './x-lt-show-if';
16
16
  export * from './x-lt-require-any';
17
+ export * from './x-lt-require-sum';
18
+ export * from './x-lt-options';
17
19
  export * from './field-validator';
18
20
  export * from './validate-resolver-payload';
@@ -30,5 +30,7 @@ __exportStar(require("./x-lt-query"), exports);
30
30
  __exportStar(require("./x-lt-submit-guard"), exports);
31
31
  __exportStar(require("./x-lt-show-if"), exports);
32
32
  __exportStar(require("./x-lt-require-any"), exports);
33
+ __exportStar(require("./x-lt-require-sum"), exports);
34
+ __exportStar(require("./x-lt-options"), exports);
33
35
  __exportStar(require("./field-validator"), exports);
34
36
  __exportStar(require("./validate-resolver-payload"), exports);
@@ -17,6 +17,8 @@
17
17
  *
18
18
  * Root-level x-lt-require-any groups run after the per-field pass: each group
19
19
  * needs a value in at least one visible member (all-hidden groups are waived).
20
+ * x-lt-require-sum groups follow the same visibility rules but read members
21
+ * as numbers: the group's visible members must sum to at least its minimum.
20
22
  *
21
23
  * The showIf/`resolver.*` domain is always the FLAT form representation, so a
22
24
  * condition like `resolver.approved` reads the same on both sides.
@@ -21,6 +21,8 @@ exports.validateResolverPayload = validateResolverPayload;
21
21
  *
22
22
  * Root-level x-lt-require-any groups run after the per-field pass: each group
23
23
  * needs a value in at least one visible member (all-hidden groups are waived).
24
+ * x-lt-require-sum groups follow the same visibility rules but read members
25
+ * as numbers: the group's visible members must sum to at least its minimum.
24
26
  *
25
27
  * The showIf/`resolver.*` domain is always the FLAT form representation, so a
26
28
  * condition like `resolver.approved` reads the same on both sides.
@@ -29,6 +31,7 @@ const field_validator_1 = require("./field-validator");
29
31
  const x_lt_show_if_1 = require("./x-lt-show-if");
30
32
  const x_lt_bind_1 = require("./x-lt-bind");
31
33
  const x_lt_require_any_1 = require("./x-lt-require-any");
34
+ const x_lt_require_sum_1 = require("./x-lt-require-sum");
32
35
  /**
33
36
  * Validate FLAT form values against the form schema. This is the dashboard's
34
37
  * entry point (the values the user edits, keyed by field name).
@@ -65,6 +68,22 @@ function validateResolverForm(schema, formValues, ctx) {
65
68
  message: `Enter a value for at least one of: ${titles.join(', ')}`,
66
69
  });
67
70
  }
71
+ // Require-sum groups: the numeric values of VISIBLE members must total at
72
+ // least the group's minimum. A `0` is a real number here — unlike
73
+ // require-any, defaulted-zero quantities do not satisfy the group.
74
+ for (const group of (0, x_lt_require_sum_1.readRequireSumGroups)(schema)) {
75
+ const visible = group.fields.filter((k) => properties[k] && (0, x_lt_show_if_1.evaluateShowIf)(properties[k]['x-lt-showIf'], liveCtx));
76
+ if (visible.length === 0)
77
+ continue;
78
+ const total = visible.reduce((sum, k) => sum + (0, x_lt_require_sum_1.requireSumContribution)(formValues[k]), 0);
79
+ if (total >= group.minimum)
80
+ continue;
81
+ const titles = visible.map((k) => properties[k].title ?? k);
82
+ errors.push({
83
+ field: visible[0],
84
+ message: `Combined value of ${titles.join(', ')} must be at least ${group.minimum}`,
85
+ });
86
+ }
68
87
  return errors;
69
88
  }
70
89
  /**
@@ -0,0 +1,22 @@
1
+ /**
2
+ * x-lt-options — a select's option list resolved from the escalation context.
3
+ * The field-level token names a `"domain.path"`; the value at that path is an
4
+ * array of scalars (strings or numbers) that becomes the field's option list,
5
+ * so one static role form can offer a different legal set per escalation
6
+ * (e.g. `[1..N]` where N rides the envelope).
7
+ *
8
+ * x-lt-options "domain.path" — e.g. "envelope.left_quantity_options"
9
+ *
10
+ * A static `enum` takes precedence when both are present — the same
11
+ * static-over-dynamic rule as x-lt-minimum/x-lt-maximum. A path that resolves
12
+ * to nothing, or to no scalar entries, yields no options: the field renders as
13
+ * a plain input for its type and membership is not enforced. Non-scalar
14
+ * entries in a resolved array are dropped.
15
+ */
16
+ export declare const X_LT_OPTIONS = "x-lt-options";
17
+ export type OptionValue = string | number;
18
+ /**
19
+ * The field's effective option list: the static `enum` when present, else the
20
+ * scalars at the token's `"domain.path"`. Undefined when neither yields any.
21
+ */
22
+ export declare function resolveFieldOptions(fieldSchema: Record<string, unknown> | null | undefined, ctx: Record<string, unknown> | undefined): OptionValue[] | undefined;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ /**
3
+ * x-lt-options — a select's option list resolved from the escalation context.
4
+ * The field-level token names a `"domain.path"`; the value at that path is an
5
+ * array of scalars (strings or numbers) that becomes the field's option list,
6
+ * so one static role form can offer a different legal set per escalation
7
+ * (e.g. `[1..N]` where N rides the envelope).
8
+ *
9
+ * x-lt-options "domain.path" — e.g. "envelope.left_quantity_options"
10
+ *
11
+ * A static `enum` takes precedence when both are present — the same
12
+ * static-over-dynamic rule as x-lt-minimum/x-lt-maximum. A path that resolves
13
+ * to nothing, or to no scalar entries, yields no options: the field renders as
14
+ * a plain input for its type and membership is not enforced. Non-scalar
15
+ * entries in a resolved array are dropped.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.X_LT_OPTIONS = void 0;
19
+ exports.resolveFieldOptions = resolveFieldOptions;
20
+ exports.X_LT_OPTIONS = 'x-lt-options';
21
+ /**
22
+ * The field's effective option list: the static `enum` when present, else the
23
+ * scalars at the token's `"domain.path"`. Undefined when neither yields any.
24
+ */
25
+ function resolveFieldOptions(fieldSchema, ctx) {
26
+ if (!fieldSchema)
27
+ return undefined;
28
+ const staticEnum = fieldSchema.enum;
29
+ if (Array.isArray(staticEnum) && staticEnum.length > 0) {
30
+ return staticEnum;
31
+ }
32
+ const sourcePath = fieldSchema[exports.X_LT_OPTIONS];
33
+ if (typeof sourcePath !== 'string' || !ctx)
34
+ return undefined;
35
+ const dot = sourcePath.indexOf('.');
36
+ if (dot === -1)
37
+ return undefined;
38
+ const domainObj = ctx[sourcePath.slice(0, dot)];
39
+ if (!domainObj || typeof domainObj !== 'object')
40
+ return undefined;
41
+ let cur = domainObj;
42
+ for (const p of sourcePath.slice(dot + 1).split('.')) {
43
+ cur = cur[p];
44
+ if (cur === undefined)
45
+ return undefined;
46
+ }
47
+ if (!Array.isArray(cur))
48
+ return undefined;
49
+ const scalars = cur.filter((v) => typeof v === 'string' || (typeof v === 'number' && Number.isFinite(v)));
50
+ return scalars.length > 0 ? scalars : undefined;
51
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * x-lt-require-sum — "these quantities must total at least N" as a
3
+ * root-schema token. Where x-lt-require-any asks that one member carry any
4
+ * answer (so a count defaulting to `0` vacuously satisfies it), require-sum
5
+ * reads the members as numbers and demands their sum reach a minimum. The
6
+ * canonical case: a Left quantity and a Right quantity that both default to
7
+ * `0`, where at least one side must be positive.
8
+ *
9
+ * x-lt-require-sum { fields: string[], minimum?: number }[]
10
+ * — e.g. [{ "fields": ["left_quantity", "right_quantity"] }]
11
+ *
12
+ * `minimum` defaults to 1. Numbers contribute their value and numeric strings
13
+ * coerce (the same reading as dynamic bounds); everything else contributes 0.
14
+ * Visibility rules compose the same way as require-any: a member hidden by
15
+ * its `x-lt-showIf` (or naming no schema property) contributes nothing and is
16
+ * not demanded, and a group whose members are ALL hidden is waived.
17
+ */
18
+ export declare const X_LT_REQUIRE_SUM = "x-lt-require-sum";
19
+ export interface RequireSumGroup {
20
+ fields: string[];
21
+ minimum: number;
22
+ }
23
+ /**
24
+ * The schema's require-sum groups. Malformed declarations (non-array token,
25
+ * groups without a fields array, non-string members, non-numeric minimum)
26
+ * read as no groups — a bad token never bricks submission.
27
+ */
28
+ export declare function readRequireSumGroups(schema: Record<string, unknown> | null | undefined): RequireSumGroup[];
29
+ /** A member's numeric contribution: numbers as-is, numeric strings coerced, all else 0. */
30
+ export declare function requireSumContribution(value: unknown): number;