@hotmeshio/long-tail 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (351) hide show
  1. package/README.md +4 -4
  2. package/build/api/escalations/accumulate.d.ts +96 -0
  3. package/build/api/escalations/accumulate.js +516 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +10 -1
  6. package/build/api/roles.d.ts +4 -5
  7. package/build/api/roles.js +53 -4
  8. package/build/api/scan-codes/execute.js +2 -0
  9. package/build/api/scan-codes/verbs.d.ts +15 -0
  10. package/build/api/scan-codes/verbs.js +65 -0
  11. package/build/index.js +60 -0
  12. package/build/lib/db/schemas/036_role_portals.sql +12 -0
  13. package/build/routes/escalations/accumulate.d.ts +7 -0
  14. package/build/routes/escalations/accumulate.js +150 -0
  15. package/build/routes/escalations/index.js +5 -0
  16. package/build/sdk/index.d.ts +25 -0
  17. package/build/sdk/index.js +8 -0
  18. package/build/services/escalation/accumulate.d.ts +81 -0
  19. package/build/services/escalation/accumulate.js +154 -0
  20. package/build/services/escalation/index.d.ts +1 -0
  21. package/build/services/escalation/index.js +1 -0
  22. package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
  23. package/build/services/orchestrator/condition.d.ts +40 -3
  24. package/build/services/orchestrator/condition.js +42 -2
  25. package/build/services/role/index.js +1 -0
  26. package/build/services/role/seed.js +6 -1
  27. package/build/services/role/sql.d.ts +6 -3
  28. package/build/services/role/sql.js +7 -2
  29. package/build/services/role/types.d.ts +38 -10
  30. package/build/services/role/types.js +10 -1
  31. package/build/services/scan-code/validate.js +16 -0
  32. package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
  33. package/build/shared/form-validation/display-only-widgets.js +25 -0
  34. package/build/shared/form-validation/index.d.ts +2 -0
  35. package/build/shared/form-validation/index.js +2 -0
  36. package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
  37. package/build/shared/form-validation/x-lt-bind.js +12 -8
  38. package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
  39. package/build/shared/form-validation/x-lt-invoke.js +103 -0
  40. package/build/system/mcp-servers/admin/escalations.js +39 -0
  41. package/build/system/mcp-servers/admin/schemas.d.ts +192 -13
  42. package/build/system/mcp-servers/admin/schemas.js +39 -3
  43. package/build/system/mcp-servers/admin/users.js +1 -0
  44. package/build/system/mcp-servers/docs.js +4 -0
  45. package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
  46. package/build/system/mcp-servers/human-queue-schemas.js +19 -1
  47. package/build/system/mcp-servers/human-queue.d.ts +2 -0
  48. package/build/system/mcp-servers/human-queue.js +77 -0
  49. package/build/system/seed/tool-manifests-admin.d.ts +922 -103
  50. package/build/system/seed/tool-manifests-admin.js +4 -1
  51. package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
  52. package/build/system/seed/tool-manifests-escalation.js +56 -0
  53. package/build/tsconfig.tsbuildinfo +1 -1
  54. package/build/types/escalation.d.ts +52 -0
  55. package/build/types/escalation.js +29 -1
  56. package/build/types/index.d.ts +2 -2
  57. package/build/types/index.js +3 -1
  58. package/build/types/scan-code.d.ts +24 -0
  59. package/build/types/scan-code.js +9 -0
  60. package/build/types/startup.d.ts +20 -0
  61. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js → AdminDashboard-uarpHB88.js} +2 -2
  62. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
  63. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js → AgentConfigPage-BcUaDD5E.js} +6 -6
  64. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
  65. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js → AgentDetailPage-BaZBhK6i.js} +3 -3
  66. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
  67. package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
  68. package/dashboard/dist/assets/{AgentsPage-7JJBHku8.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
  69. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
  70. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
  71. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js → BotPicker-CClMby6B.js} +2 -2
  72. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js.map → BotPicker-CClMby6B.js.map} +1 -1
  73. package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
  74. package/dashboard/dist/assets/{BulkAssignModal-NJBcoj-f.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
  75. package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
  76. package/dashboard/dist/assets/{CapabilitiesPage-F8dpNn9B.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
  77. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js → CollapsibleSection-ow8jpbtD.js} +2 -2
  78. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
  79. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
  80. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
  81. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js → CountdownTimer-CSqyZMCG.js} +2 -2
  82. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
  83. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js → CredentialsPage-Dx7SxA23.js} +2 -2
  84. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
  85. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js → CronLabel-LYPxpvNN.js} +2 -2
  86. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
  87. package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
  88. package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
  89. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
  90. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
  91. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js → ElapsedCell-BZJTSm9N.js} +2 -2
  92. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
  93. package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
  94. package/dashboard/dist/assets/{EntityTimelinePanel-CkF-oW-m.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
  95. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
  96. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
  97. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
  98. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
  99. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
  100. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
  101. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
  102. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
  103. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
  104. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
  105. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js → EscalationsOverview-CW57FaP9.js} +2 -2
  106. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
  107. package/dashboard/dist/assets/{EventTable-Ike2xchn.js → EventTable-D1ctWhKf.js} +2 -2
  108. package/dashboard/dist/assets/{EventTable-Ike2xchn.js.map → EventTable-D1ctWhKf.js.map} +1 -1
  109. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js → FilterBar-C-iur-Nj.js} +2 -2
  110. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
  111. package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
  112. package/dashboard/dist/assets/{GraphInvokePage-CKtvWowP.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
  113. package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
  114. package/dashboard/dist/assets/{HomePage-BQ3Q791Q.js.map → HomePage-Dc085ghJ.js.map} +1 -1
  115. package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
  116. package/dashboard/dist/assets/{ListToolbar-DdJzj472.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
  117. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js → McpOverview-qXXhbNWV.js} +2 -2
  118. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
  119. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
  120. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
  121. package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
  122. package/dashboard/dist/assets/{McpQueryPage-CfJy7HZ7.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
  123. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
  124. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
  125. package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
  126. package/dashboard/dist/assets/{McpRunsPage-D7QXjW9z.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
  127. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
  128. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
  129. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
  130. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
  131. package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
  132. package/dashboard/dist/assets/{OperatorDashboard-sXNDh1Ph.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
  133. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
  134. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
  135. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
  136. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
  137. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
  138. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
  139. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js → PersonasPage-DOgGUlJl.js} +2 -2
  140. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
  141. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
  142. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
  143. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
  144. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
  145. package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
  146. package/dashboard/dist/assets/{ProcessesListPage-CjwVKe32.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
  147. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
  148. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
  149. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
  150. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
  151. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
  152. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
  153. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js → RolesPage-DSqqKPbv.js} +2 -2
  154. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
  155. package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
  156. package/dashboard/dist/assets/{RunAsSelector-fFMt1bGe.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
  157. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js → ScanCodesPage-S8aAJfnC.js} +2 -2
  158. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
  159. package/dashboard/dist/assets/{ScanSchemeDetailPage-eKQpmsC_.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
  160. package/dashboard/dist/assets/{ScanSchemeDetailPage-eKQpmsC_.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
  161. package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
  162. package/dashboard/dist/assets/{ScanStationPage-C1_ppDoZ.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
  163. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
  164. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
  165. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js → StickyPagination-CkW_A507.js} +2 -2
  166. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js.map → StickyPagination-CkW_A507.js.map} +1 -1
  167. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js → StreamMessageDetail-yzWX0wac.js} +2 -2
  168. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
  169. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
  170. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
  171. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
  172. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
  173. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js → TaskDetailPage-DCDcEps9.js} +2 -2
  174. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
  175. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
  176. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
  177. package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
  178. package/dashboard/dist/assets/{TasksListPage-BB1f79lL.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
  179. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js → TimeAgo-CSNVEjch.js} +2 -2
  180. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
  181. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js → TimestampCell-Du1nBrPn.js} +2 -2
  182. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
  183. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
  184. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
  185. package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
  186. package/dashboard/dist/assets/{ToolTestPanel-Bwe3J5lj.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
  187. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
  188. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
  189. package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
  190. package/dashboard/dist/assets/{TopicsPage-C1gxBUap.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
  191. package/dashboard/dist/assets/{UserName-BzXJUE6q.js → UserName-kBh1dc39.js} +2 -2
  192. package/dashboard/dist/assets/{UserName-BzXJUE6q.js.map → UserName-kBh1dc39.js.map} +1 -1
  193. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
  194. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
  195. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
  196. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
  197. package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
  198. package/dashboard/dist/assets/{WorkflowsDashboard-CZAqRk1N.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
  199. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js → WorkflowsOverview-DswubNJN.js} +2 -2
  200. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
  201. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
  202. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
  203. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
  204. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
  205. package/dashboard/dist/assets/{agents-gV0Ys-sY.js → agents-BwEnf6N9.js} +2 -2
  206. package/dashboard/dist/assets/{agents-gV0Ys-sY.js.map → agents-BwEnf6N9.js.map} +1 -1
  207. package/dashboard/dist/assets/{bots-B97itB3I.js → bots-CCmJTT2u.js} +2 -2
  208. package/dashboard/dist/assets/{bots-B97itB3I.js.map → bots-CCmJTT2u.js.map} +1 -1
  209. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js → capabilities-BZHgp_nh.js} +2 -2
  210. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js.map → capabilities-BZHgp_nh.js.map} +1 -1
  211. package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
  212. package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
  213. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js → controlplane-CyfwUlFA.js} +2 -2
  214. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js.map → controlplane-CyfwUlFA.js.map} +1 -1
  215. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
  216. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
  217. package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
  218. package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
  219. package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
  220. package/dashboard/dist/assets/{index-BQpV-DTG.js.map → index-BAAVTyZ-.js.map} +1 -1
  221. package/dashboard/dist/assets/{index-B9BBCqLI.js → index-BC6Jenlo.js} +2 -2
  222. package/dashboard/dist/assets/{index-B9BBCqLI.js.map → index-BC6Jenlo.js.map} +1 -1
  223. package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
  224. package/dashboard/dist/assets/{index-Bp9KBLT5.js.map → index-C7KHqOTQ.js.map} +1 -1
  225. package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
  226. package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
  227. package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
  228. package/dashboard/dist/assets/{index-CFbo9FU9.js.map → index-CVwzCZ43.js.map} +1 -1
  229. package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
  230. package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
  231. package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
  232. package/dashboard/dist/assets/{index-Cfvkl2J0.js.map → index-ClVbfe4z.js.map} +1 -1
  233. package/dashboard/dist/assets/{index-DMeaiKgf.js → index-CuVkSmj5.js} +2 -2
  234. package/dashboard/dist/assets/{index-DMeaiKgf.js.map → index-CuVkSmj5.js.map} +1 -1
  235. package/dashboard/dist/assets/{index-ipqwPavs.js → index-DAuX_PlL.js} +2 -2
  236. package/dashboard/dist/assets/{index-ipqwPavs.js.map → index-DAuX_PlL.js.map} +1 -1
  237. package/dashboard/dist/assets/{index-CIpHj4di.js → index-DBWS5QL8.js} +2 -2
  238. package/dashboard/dist/assets/{index-CIpHj4di.js.map → index-DBWS5QL8.js.map} +1 -1
  239. package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
  240. package/dashboard/dist/assets/{index-CUZ6LYye.js.map → index-DIWCI6HC.js.map} +1 -1
  241. package/dashboard/dist/assets/{index-DwOnWeu8.js → index-DZ8X_Gp4.js} +2 -2
  242. package/dashboard/dist/assets/{index-DwOnWeu8.js.map → index-DZ8X_Gp4.js.map} +1 -1
  243. package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
  244. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js → knowledge-CqyLhUMg.js} +2 -2
  245. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js.map → knowledge-CqyLhUMg.js.map} +1 -1
  246. package/dashboard/dist/assets/{mcp-CH13hNH2.js → mcp-Cvu6bFYH.js} +2 -2
  247. package/dashboard/dist/assets/{mcp-CH13hNH2.js.map → mcp-Cvu6bFYH.js.map} +1 -1
  248. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js → mcp-query-qC6A3e9l.js} +2 -2
  249. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
  250. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
  251. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
  252. package/dashboard/dist/assets/{personas-mDk4lLQS.js → personas-BKN_lJuV.js} +2 -2
  253. package/dashboard/dist/assets/{personas-mDk4lLQS.js.map → personas-BKN_lJuV.js.map} +1 -1
  254. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js → pipelines-BldIfv85.js} +2 -2
  255. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js.map → pipelines-BldIfv85.js.map} +1 -1
  256. package/dashboard/dist/assets/{tasks-CItmNsRp.js → tasks-B-Uay8uL.js} +2 -2
  257. package/dashboard/dist/assets/{tasks-CItmNsRp.js.map → tasks-B-Uay8uL.js.map} +1 -1
  258. package/dashboard/dist/assets/{topics-CJYG7BX5.js → topics-438EQogt.js} +2 -2
  259. package/dashboard/dist/assets/{topics-CJYG7BX5.js.map → topics-438EQogt.js.map} +1 -1
  260. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
  261. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
  262. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
  263. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
  264. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js → useNamespace-D1218GQ8.js} +2 -2
  265. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js.map → useNamespace-D1218GQ8.js.map} +1 -1
  266. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
  267. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
  268. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
  269. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
  270. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js → yaml-workflows-CN01gEB0.js} +2 -2
  271. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
  272. package/dashboard/dist/index.html +3 -3
  273. package/docs/accumulator.md +113 -0
  274. package/docs/api/http/escalations.md +89 -0
  275. package/docs/api/http/roles.md +1 -0
  276. package/docs/api/sdk/escalations.md +91 -0
  277. package/docs/api/sdk/roles.md +2 -0
  278. package/docs/architecture.md +1 -1
  279. package/docs/code-owned-configuration.md +2 -1
  280. package/docs/dashboard.md +10 -4
  281. package/docs/hitl/design.md +1 -1
  282. package/docs/hitl/escalation.md +37 -1
  283. package/docs/hitl/invoke-form.md +4 -0
  284. package/docs/hitl/pinned-views.md +4 -0
  285. package/docs/hitl/portal.md +97 -0
  286. package/docs/hitl/resolution.md +41 -0
  287. package/docs/hitl/x-lt-embed.md +1 -1
  288. package/docs/hitl/x-lt-invoke.md +95 -0
  289. package/docs/hitl/x-lt-list-schema.md +3 -1
  290. package/docs/hitl/x-lt-widget.md +1 -0
  291. package/docs/hitl-guide.md +8 -1
  292. package/docs/scan-codes.md +15 -2
  293. package/docs/sdk.md +1 -1
  294. package/docs/workflows.md +2 -2
  295. package/package.json +4 -2
  296. package/dashboard/dist/assets/AgentsPage-7JJBHku8.js +0 -2
  297. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js +0 -2
  298. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js.map +0 -1
  299. package/dashboard/dist/assets/BulkAssignModal-NJBcoj-f.js +0 -2
  300. package/dashboard/dist/assets/CapabilitiesPage-F8dpNn9B.js +0 -2
  301. package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
  302. package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
  303. package/dashboard/dist/assets/EntityTimelinePanel-CkF-oW-m.js +0 -2
  304. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js +0 -2
  305. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js.map +0 -1
  306. package/dashboard/dist/assets/GraphInvokePage-CKtvWowP.js +0 -2
  307. package/dashboard/dist/assets/HomePage-BQ3Q791Q.js +0 -2
  308. package/dashboard/dist/assets/ListToolbar-DdJzj472.js +0 -2
  309. package/dashboard/dist/assets/McpQueryPage-CfJy7HZ7.js +0 -2
  310. package/dashboard/dist/assets/McpRunsPage-D7QXjW9z.js +0 -2
  311. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js +0 -3
  312. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js.map +0 -1
  313. package/dashboard/dist/assets/OperatorDashboard-sXNDh1Ph.js +0 -2
  314. package/dashboard/dist/assets/ProcessesListPage-CjwVKe32.js +0 -2
  315. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js +0 -3
  316. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js.map +0 -1
  317. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js +0 -8
  318. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js.map +0 -1
  319. package/dashboard/dist/assets/RunAsSelector-fFMt1bGe.js +0 -2
  320. package/dashboard/dist/assets/ScanStationPage-C1_ppDoZ.js +0 -2
  321. package/dashboard/dist/assets/TasksListPage-BB1f79lL.js +0 -2
  322. package/dashboard/dist/assets/ToolTestPanel-Bwe3J5lj.js +0 -2
  323. package/dashboard/dist/assets/TopicsPage-C1gxBUap.js +0 -2
  324. package/dashboard/dist/assets/WorkflowsDashboard-CZAqRk1N.js +0 -2
  325. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js +0 -2
  326. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js.map +0 -1
  327. package/dashboard/dist/assets/index-3ezfWLkE.js +0 -6
  328. package/dashboard/dist/assets/index-3ezfWLkE.js.map +0 -1
  329. package/dashboard/dist/assets/index-BQpV-DTG.js +0 -2
  330. package/dashboard/dist/assets/index-Bp9KBLT5.js +0 -2
  331. package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
  332. package/dashboard/dist/assets/index-CFbo9FU9.js +0 -2
  333. package/dashboard/dist/assets/index-CIwlVfvV.js +0 -67
  334. package/dashboard/dist/assets/index-CIwlVfvV.js.map +0 -1
  335. package/dashboard/dist/assets/index-CUZ6LYye.js +0 -2
  336. package/dashboard/dist/assets/index-Cfvkl2J0.js +0 -13
  337. package/dashboard/dist/assets/index-SGyrXGp8.js +0 -3
  338. package/dashboard/dist/assets/index-SGyrXGp8.js.map +0 -1
  339. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js +0 -2
  340. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js.map +0 -1
  341. package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
  342. package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
  343. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js +0 -2
  344. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js.map +0 -1
  345. package/docs/compilation.md +0 -152
  346. package/docs/compiler.md +0 -311
  347. package/docs/contributing.md +0 -56
  348. package/docs/design-principles.md +0 -245
  349. package/docs/schema-exchange.md +0 -173
  350. package/docs/self-test.md +0 -106
  351. package/docs/story.md +0 -184
package/README.md CHANGED
@@ -234,13 +234,13 @@ All modes share PostgreSQL and scale independently. See [Cloud Deployment](https
234
234
 
235
235
  | Guide | What it covers |
236
236
  |-------|---------------|
237
- | [The Long Tail Story](https://github.com/hotmeshio/long-tail/blob/main/docs/story.md) | Why this exists, what accumulates over time |
237
+ | [The Long Tail Story](https://github.com/hotmeshio/long-tail/blob/main/docs/donotpublish/story.md) | Why this exists, what accumulates over time |
238
238
  | [Workflows](https://github.com/hotmeshio/long-tail/blob/main/docs/workflows.md) | Activities, interceptor, escalation lifecycle, composition |
239
239
  | [IAM](https://github.com/hotmeshio/long-tail/blob/main/docs/iam.md) | Identity propagation, service accounts, credential exchange |
240
240
  | [Dashboard](https://github.com/hotmeshio/long-tail/blob/main/docs/dashboard.md) | Navigation, key pages, event feed |
241
241
  | [MCP](https://github.com/hotmeshio/long-tail/blob/main/docs/mcp.md) | Server registration, tool calls, human queue |
242
- | [Compilation](https://github.com/hotmeshio/long-tail/blob/main/docs/compilation.md) | Dynamic to deterministic pipeline wizard |
243
- | [Compiler](https://github.com/hotmeshio/long-tail/blob/main/docs/compiler.md) | `ltc compile` — durable TypeScript to YAML DAGs |
242
+ | [Compilation](https://github.com/hotmeshio/long-tail/blob/main/docs/donotpublish/compilation.md) | Dynamic to deterministic pipeline wizard |
243
+ | [Compiler](https://github.com/hotmeshio/long-tail/blob/main/docs/donotpublish/compiler.md) | `ltc compile` — durable TypeScript to YAML DAGs |
244
244
  | [CLI](https://github.com/hotmeshio/long-tail/blob/main/docs/cli.md) | `ltc` — terminal access to workflows, escalations, knowledge, MCP |
245
245
  | [Escalation Strategies](https://github.com/hotmeshio/long-tail/blob/main/docs/escalation-strategies.md) | Default, MCP triage, custom handlers |
246
246
  | [Schema Enforcement](https://github.com/hotmeshio/long-tail/blob/main/docs/schema-enforcement.md) | form_schema as an enforced API contract on every resolve surface |
@@ -274,7 +274,7 @@ Open [http://localhost:3000](http://localhost:3000). Example workflows seed the
274
274
  | `engineer` | `l0ngt@1l` | engineer |
275
275
  | `reviewer` | `l0ngt@1l` | reviewer |
276
276
 
277
- See [Contributing](https://github.com/hotmeshio/long-tail/blob/main/docs/contributing.md).
277
+ See [Contributing](https://github.com/hotmeshio/long-tail/blob/main/docs/donotpublish/contributing.md).
278
278
 
279
279
  ## License
280
280
 
@@ -0,0 +1,96 @@
1
+ import type { AccumulatedItem, LTEscalationRecord } from '../../types';
2
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
3
+ /** Names the second row of a reciprocal add or removal. Exactly one selector. */
4
+ export interface ReciprocalInput {
5
+ id?: string;
6
+ signalKey?: string;
7
+ key?: string;
8
+ value?: string;
9
+ payload?: Record<string, any>;
10
+ }
11
+ export interface AccumulateItemInput {
12
+ itemKey: string;
13
+ /** Stored on the entry and delivered inside `$accumulated`. Validates
14
+ * against the container's versioned role form when present. */
15
+ payload?: Record<string, any>;
16
+ metadata?: Record<string, any>;
17
+ assertClaim?: boolean;
18
+ reciprocal?: ReciprocalInput;
19
+ }
20
+ /**
21
+ * Add ONE item to an accumulator escalation (a `conditional` wait declared
22
+ * with `accumulate: {...}`). Interim adds are cheap atomic row appends: the
23
+ * row stays pending and `count`/`remaining` report progress. An add that
24
+ * reaches `max` completes the escalation: the row resolves and the waiting
25
+ * workflow wakes with the ordered collection, in the same statement.
26
+ *
27
+ * With `reciprocal`, a second accumulator row is written in that same
28
+ * statement or not at all: it holds this container's id as its item key and
29
+ * each entry points at the other row. The reciprocal is RBAC-gated here
30
+ * before the statement runs.
31
+ *
32
+ * Claim semantics match batch: claim-agnostic by default (a container
33
+ * collects contributions from many hands); `assertClaim: true` requires the
34
+ * caller's own live claim, asserted atomically inside the SDK statement.
35
+ */
36
+ export declare function accumulateItem(input: {
37
+ id: string;
38
+ } & AccumulateItemInput, auth: LTApiAuth): Promise<LTApiResult>;
39
+ /**
40
+ * Add selecting the container by its `signal_key`, the deterministic home
41
+ * signal id the waiting workflow parked on. Mirrors resolve-by-signal-key:
42
+ * claim-agnostic, write-scope gated with 404 non-disclosure.
43
+ */
44
+ export declare function accumulateItemBySignalKey(input: {
45
+ signalKey: string;
46
+ } & Omit<AccumulateItemInput, 'assertClaim'>, auth: LTApiAuth): Promise<LTApiResult>;
47
+ /**
48
+ * Add selecting the container by metadata facet, the faceted sibling of
49
+ * {@link accumulateItem}. RBAC folds into the SDK's atomic facet selection
50
+ * as a flat role filter. Schema enforcement is two-phase when enforcing
51
+ * roles exist and a payload is present: the row is picked first, validated
52
+ * against ITS schema, then written by asserted id; a row that went terminal
53
+ * between phases surfaces as a 409.
54
+ */
55
+ export declare function accumulateItemByMetadata(input: {
56
+ key: string;
57
+ value: string;
58
+ restrictRoles?: string[];
59
+ } & Omit<AccumulateItemInput, 'assertClaim'>, auth: LTApiAuth): Promise<LTApiResult>;
60
+ export interface RemoveItemInput {
61
+ itemKey: string;
62
+ reciprocal?: Omit<ReciprocalInput, 'payload'>;
63
+ }
64
+ /**
65
+ * Remove ONE held item from a pending accumulator escalation, one guarded
66
+ * statement, no wake. With `reciprocal`, the container's id leaves that row
67
+ * in the same statement or neither row changes.
68
+ */
69
+ export declare function removeItem(input: {
70
+ id: string;
71
+ } & RemoveItemInput, auth: LTApiAuth): Promise<LTApiResult>;
72
+ export declare function removeItemBySignalKey(input: {
73
+ signalKey: string;
74
+ } & RemoveItemInput, auth: LTApiAuth): Promise<LTApiResult>;
75
+ export declare function removeItemByMetadata(input: {
76
+ key: string;
77
+ value: string;
78
+ restrictRoles?: string[];
79
+ } & RemoveItemInput, auth: LTApiAuth): Promise<LTApiResult>;
80
+ export interface EscalationItemsView {
81
+ escalationId: string;
82
+ kind: 'accumulate' | 'batch';
83
+ status: LTEscalationRecord['status'];
84
+ count: number;
85
+ /** The count trigger (accumulate) or the declared size (batch); null when unbounded. */
86
+ max: number | null;
87
+ items: AccumulatedItem[];
88
+ /** Batch only: declared keys still awaiting submission. */
89
+ pending?: string[];
90
+ }
91
+ /** The normalized ordered item list of an accumulator or batch row. */
92
+ export declare function itemsView(escalation: LTEscalationRecord): EscalationItemsView | null;
93
+ /** GET the held items of an accumulator or batch row, in arrival order. Read access; 404 non-disclosure. */
94
+ export declare function getEscalationItems(input: {
95
+ id: string;
96
+ }, auth: LTApiAuth): Promise<LTApiResult<EscalationItemsView>>;
@@ -0,0 +1,516 @@
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.accumulateItem = accumulateItem;
37
+ exports.accumulateItemBySignalKey = accumulateItemBySignalKey;
38
+ exports.accumulateItemByMetadata = accumulateItemByMetadata;
39
+ exports.removeItem = removeItem;
40
+ exports.removeItemBySignalKey = removeItemBySignalKey;
41
+ exports.removeItemByMetadata = removeItemByMetadata;
42
+ exports.itemsView = itemsView;
43
+ exports.getEscalationItems = getEscalationItems;
44
+ const escalationService = __importStar(require("../../services/escalation"));
45
+ const resolver_validation_1 = require("../../services/escalation/resolver-validation");
46
+ const enforcement_cache_1 = require("../../services/role/enforcement-cache");
47
+ const escalation_1 = require("../../types/escalation");
48
+ const helpers_1 = require("./helpers");
49
+ const resolve_1 = require("./resolve");
50
+ const metadata_1 = require("./metadata");
51
+ function parseEnvelope(escalation) {
52
+ try {
53
+ const parsed = JSON.parse(escalation.envelope || '{}');
54
+ return parsed && typeof parsed === 'object' ? parsed : {};
55
+ }
56
+ catch {
57
+ return {};
58
+ }
59
+ }
60
+ function isAccumulator(escalation) {
61
+ const items = parseEnvelope(escalation)[escalation_1.ESCALATION_ACCUMULATE_KEYS.ITEMS];
62
+ return !!items && typeof items === 'object' && !Array.isArray(items);
63
+ }
64
+ function isBatch(escalation) {
65
+ return Array.isArray(escalation.metadata?.[escalation_1.ESCALATION_BATCH_KEYS.PENDING]);
66
+ }
67
+ function reciprocalSelectorCount(r) {
68
+ return (r.id ? 1 : 0) + (r.signalKey ? 1 : 0) + (r.key !== undefined ? 1 : 0);
69
+ }
70
+ /**
71
+ * Locates and RBAC-gates the reciprocal row before the statement. The row
72
+ * must be visible to the caller (404 non-disclosure otherwise) and within
73
+ * their write scope (403 by id; 404 for the ingress selectors). Returns the
74
+ * selector the service forwards, resolved to the row's id.
75
+ */
76
+ async function gateReciprocal(input, auth) {
77
+ if (!input)
78
+ return {};
79
+ if (reciprocalSelectorCount(input) !== 1) {
80
+ return { error: { status: 400, error: 'reciprocal requires exactly one of id, signalKey, or key/value' } };
81
+ }
82
+ let row = null;
83
+ if (input.id) {
84
+ row = await escalationService.getEscalation(input.id);
85
+ }
86
+ else if (input.signalKey) {
87
+ row = await escalationService.getEscalationBySignalKey(input.signalKey);
88
+ }
89
+ else {
90
+ const writeScope = await (0, helpers_1.getEscalationWriteScope)(auth.userId);
91
+ const found = await escalationService.findByMetadata(input.key, String(input.value), 'pending', 1, 0, writeScope.global ? undefined : { allRoles: writeScope.allRoles, meUserId: auth.userId });
92
+ row = found.escalations[0] ?? null;
93
+ }
94
+ if (!row)
95
+ return { error: { status: 404, error: 'Reciprocal escalation not found' } };
96
+ if (input.id) {
97
+ if (await (0, helpers_1.assertReadAccess)(auth.userId, row)) {
98
+ return { error: { status: 404, error: 'Reciprocal escalation not found' } };
99
+ }
100
+ const denied = await (0, helpers_1.assertWriteAccess)(auth.userId, row);
101
+ if (denied)
102
+ return { error: { ...denied, error: `Reciprocal: ${denied.error}` } };
103
+ }
104
+ else if (await (0, helpers_1.assertWriteAccess)(auth.userId, row)) {
105
+ return { error: { status: 404, error: 'Reciprocal escalation not found' } };
106
+ }
107
+ return { reciprocal: { id: row.id, payload: input.payload } };
108
+ }
109
+ /** Validates the item payload against the container's versioned role form. */
110
+ async function gatePayload(escalation, payload, userId) {
111
+ if (payload === undefined)
112
+ return {};
113
+ if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
114
+ return { error: { status: 400, error: 'payload must be an object' } };
115
+ }
116
+ const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, payload, undefined, userId);
117
+ if (violation)
118
+ return { error: (0, resolve_1.validationFailure)(violation) };
119
+ return { payload: await (0, resolve_1.redactPasswords)(payload, escalation.metadata?.form_schema) };
120
+ }
121
+ /**
122
+ * Add ONE item to an accumulator escalation (a `conditional` wait declared
123
+ * with `accumulate: {...}`). Interim adds are cheap atomic row appends: the
124
+ * row stays pending and `count`/`remaining` report progress. An add that
125
+ * reaches `max` completes the escalation: the row resolves and the waiting
126
+ * workflow wakes with the ordered collection, in the same statement.
127
+ *
128
+ * With `reciprocal`, a second accumulator row is written in that same
129
+ * statement or not at all: it holds this container's id as its item key and
130
+ * each entry points at the other row. The reciprocal is RBAC-gated here
131
+ * before the statement runs.
132
+ *
133
+ * Claim semantics match batch: claim-agnostic by default (a container
134
+ * collects contributions from many hands); `assertClaim: true` requires the
135
+ * caller's own live claim, asserted atomically inside the SDK statement.
136
+ */
137
+ async function accumulateItem(input, auth) {
138
+ try {
139
+ const { id, itemKey, metadata } = input;
140
+ if (!itemKey)
141
+ return { status: 400, error: 'itemKey is required' };
142
+ const escalation = await escalationService.getEscalation(id);
143
+ if (!escalation)
144
+ return { status: 404, error: 'Escalation not found' };
145
+ if (escalation.status === 'cancelled')
146
+ return { status: 409, error: 'Escalation is cancelled' };
147
+ if (escalation.status !== 'pending')
148
+ return { status: 409, error: 'Escalation not available for accumulation' };
149
+ if (!isAccumulator(escalation))
150
+ return { status: 400, error: 'Escalation is not an accumulator' };
151
+ if (await (0, helpers_1.assertReadAccess)(auth.userId, escalation)) {
152
+ return { status: 404, error: 'Escalation not found' };
153
+ }
154
+ const denied = await (0, helpers_1.assertWriteAccess)(auth.userId, escalation);
155
+ if (denied)
156
+ return denied;
157
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
158
+ if ('error' in reciprocal)
159
+ return reciprocal.error;
160
+ const payload = await gatePayload(escalation, input.payload, auth.userId);
161
+ if ('error' in payload)
162
+ return payload.error;
163
+ const result = await escalationService.accumulateItem(escalation.id, {
164
+ itemKey,
165
+ payload: payload.payload,
166
+ metadata: { ...metadata, resolved_by: auth.userId },
167
+ actor: auth.userId,
168
+ assertClaim: input.assertClaim ? auth.userId : undefined,
169
+ resolvedBy: await (0, resolve_1.resolverIdentity)(auth),
170
+ reciprocal: reciprocal.reciprocal,
171
+ });
172
+ return accumulateOutcomeResult(result, itemKey, escalation.workflow_id);
173
+ }
174
+ catch (err) {
175
+ return { status: 500, error: err.message };
176
+ }
177
+ }
178
+ /**
179
+ * Add selecting the container by its `signal_key`, the deterministic home
180
+ * signal id the waiting workflow parked on. Mirrors resolve-by-signal-key:
181
+ * claim-agnostic, write-scope gated with 404 non-disclosure.
182
+ */
183
+ async function accumulateItemBySignalKey(input, auth) {
184
+ try {
185
+ const { signalKey, itemKey, metadata } = input;
186
+ if (!signalKey)
187
+ return { status: 400, error: 'signalKey is required' };
188
+ if (!itemKey)
189
+ return { status: 400, error: 'itemKey is required' };
190
+ const escalation = await escalationService.getEscalationBySignalKey(signalKey);
191
+ if (!escalation)
192
+ return { status: 404, error: 'Escalation not found' };
193
+ if (escalation.status !== 'pending')
194
+ return { status: 409, error: 'Escalation not available for accumulation' };
195
+ if (!isAccumulator(escalation))
196
+ return { status: 400, error: 'Escalation is not an accumulator' };
197
+ const denied = await (0, helpers_1.assertWriteAccess)(auth.userId, escalation);
198
+ if (denied)
199
+ return { status: 404, error: 'Escalation not found' };
200
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
201
+ if ('error' in reciprocal)
202
+ return reciprocal.error;
203
+ const payload = await gatePayload(escalation, input.payload, auth.userId);
204
+ if ('error' in payload)
205
+ return payload.error;
206
+ const result = await escalationService.accumulateItemBySignalKey(signalKey, {
207
+ itemKey,
208
+ payload: payload.payload,
209
+ metadata: { ...metadata, resolved_by: auth.userId },
210
+ actor: auth.userId,
211
+ resolvedBy: await (0, resolve_1.resolverIdentity)(auth),
212
+ reciprocal: reciprocal.reciprocal,
213
+ });
214
+ return accumulateOutcomeResult(result, itemKey, escalation.workflow_id);
215
+ }
216
+ catch (err) {
217
+ return { status: 500, error: err.message };
218
+ }
219
+ }
220
+ /**
221
+ * Add selecting the container by metadata facet, the faceted sibling of
222
+ * {@link accumulateItem}. RBAC folds into the SDK's atomic facet selection
223
+ * as a flat role filter. Schema enforcement is two-phase when enforcing
224
+ * roles exist and a payload is present: the row is picked first, validated
225
+ * against ITS schema, then written by asserted id; a row that went terminal
226
+ * between phases surfaces as a 409.
227
+ */
228
+ async function accumulateItemByMetadata(input, auth) {
229
+ try {
230
+ const { key, value, itemKey, metadata } = input;
231
+ if (!key || !value)
232
+ return { status: 400, error: 'key and value are required' };
233
+ if (!itemKey)
234
+ return { status: 400, error: 'itemKey is required' };
235
+ const writeScope = await (0, helpers_1.getEscalationWriteScope)(auth.userId);
236
+ const allowedRoles = (0, metadata_1.restrictScopeRoles)(writeScope.allRoles, writeScope.global, input.restrictRoles);
237
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
238
+ if ('error' in reciprocal)
239
+ return reciprocal.error;
240
+ const resolvedBy = await (0, resolve_1.resolverIdentity)(auth);
241
+ const outcome = { ...metadata, resolved_by: auth.userId };
242
+ const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
243
+ if (enforcing.size === 0 || input.payload === undefined) {
244
+ const result = await escalationService.accumulateItemByMetadata(key, value, {
245
+ itemKey,
246
+ payload: input.payload,
247
+ metadata: outcome,
248
+ actor: auth.userId,
249
+ resolvedBy,
250
+ roles: allowedRoles ?? undefined,
251
+ reciprocal: reciprocal.reciprocal,
252
+ });
253
+ return accumulateOutcomeResult(result, itemKey, result.escalation?.workflow_id ?? null);
254
+ }
255
+ const found = await escalationService.findByMetadata(key, value, 'pending', 1, 0, allowedRoles === null ? undefined : { allRoles: allowedRoles, meUserId: auth.userId });
256
+ const row = found.escalations[0];
257
+ if (!row)
258
+ return { status: 404, error: 'No pending escalation found for this metadata' };
259
+ if (!isAccumulator(row))
260
+ return { status: 400, error: 'Escalation is not an accumulator' };
261
+ const payload = await gatePayload(row, input.payload, auth.userId);
262
+ if ('error' in payload)
263
+ return payload.error;
264
+ const result = await escalationService.accumulateItem(row.id, {
265
+ itemKey,
266
+ payload: payload.payload,
267
+ metadata: outcome,
268
+ actor: auth.userId,
269
+ resolvedBy,
270
+ reciprocal: reciprocal.reciprocal,
271
+ });
272
+ if (result.outcome === 'not-found') {
273
+ return { status: 409, error: 'A concurrent change is already in progress for this escalation' };
274
+ }
275
+ return accumulateOutcomeResult(result, itemKey, row.workflow_id);
276
+ }
277
+ catch (err) {
278
+ return { status: 500, error: err.message };
279
+ }
280
+ }
281
+ /**
282
+ * Remove ONE held item from a pending accumulator escalation, one guarded
283
+ * statement, no wake. With `reciprocal`, the container's id leaves that row
284
+ * in the same statement or neither row changes.
285
+ */
286
+ async function removeItem(input, auth) {
287
+ try {
288
+ const { id, itemKey } = input;
289
+ if (!itemKey)
290
+ return { status: 400, error: 'itemKey is required' };
291
+ const escalation = await escalationService.getEscalation(id);
292
+ if (!escalation)
293
+ return { status: 404, error: 'Escalation not found' };
294
+ if (escalation.status !== 'pending')
295
+ return { status: 409, error: 'Escalation not available for accumulation' };
296
+ if (!isAccumulator(escalation))
297
+ return { status: 400, error: 'Escalation is not an accumulator' };
298
+ if (await (0, helpers_1.assertReadAccess)(auth.userId, escalation)) {
299
+ return { status: 404, error: 'Escalation not found' };
300
+ }
301
+ const denied = await (0, helpers_1.assertWriteAccess)(auth.userId, escalation);
302
+ if (denied)
303
+ return denied;
304
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
305
+ if ('error' in reciprocal)
306
+ return reciprocal.error;
307
+ const result = await escalationService.removeAccumulatedItem(escalation.id, {
308
+ itemKey, actor: auth.userId, reciprocal: reciprocal.reciprocal,
309
+ });
310
+ return removeOutcomeResult(result, itemKey);
311
+ }
312
+ catch (err) {
313
+ return { status: 500, error: err.message };
314
+ }
315
+ }
316
+ async function removeItemBySignalKey(input, auth) {
317
+ try {
318
+ const { signalKey, itemKey } = input;
319
+ if (!signalKey)
320
+ return { status: 400, error: 'signalKey is required' };
321
+ if (!itemKey)
322
+ return { status: 400, error: 'itemKey is required' };
323
+ const escalation = await escalationService.getEscalationBySignalKey(signalKey);
324
+ if (!escalation)
325
+ return { status: 404, error: 'Escalation not found' };
326
+ if (escalation.status !== 'pending')
327
+ return { status: 409, error: 'Escalation not available for accumulation' };
328
+ if (!isAccumulator(escalation))
329
+ return { status: 400, error: 'Escalation is not an accumulator' };
330
+ if (await (0, helpers_1.assertWriteAccess)(auth.userId, escalation)) {
331
+ return { status: 404, error: 'Escalation not found' };
332
+ }
333
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
334
+ if ('error' in reciprocal)
335
+ return reciprocal.error;
336
+ const result = await escalationService.removeAccumulatedItemBySignalKey(signalKey, {
337
+ itemKey, actor: auth.userId, reciprocal: reciprocal.reciprocal,
338
+ });
339
+ return removeOutcomeResult(result, itemKey);
340
+ }
341
+ catch (err) {
342
+ return { status: 500, error: err.message };
343
+ }
344
+ }
345
+ async function removeItemByMetadata(input, auth) {
346
+ try {
347
+ const { key, value, itemKey } = input;
348
+ if (!key || !value)
349
+ return { status: 400, error: 'key and value are required' };
350
+ if (!itemKey)
351
+ return { status: 400, error: 'itemKey is required' };
352
+ const writeScope = await (0, helpers_1.getEscalationWriteScope)(auth.userId);
353
+ const allowedRoles = (0, metadata_1.restrictScopeRoles)(writeScope.allRoles, writeScope.global, input.restrictRoles);
354
+ const reciprocal = await gateReciprocal(input.reciprocal, auth);
355
+ if ('error' in reciprocal)
356
+ return reciprocal.error;
357
+ const result = await escalationService.removeAccumulatedItemByMetadata(key, value, {
358
+ itemKey, actor: auth.userId, roles: allowedRoles ?? undefined, reciprocal: reciprocal.reciprocal,
359
+ });
360
+ return removeOutcomeResult(result, itemKey);
361
+ }
362
+ catch (err) {
363
+ return { status: 500, error: err.message };
364
+ }
365
+ }
366
+ /** The normalized ordered item list of an accumulator or batch row. */
367
+ function itemsView(escalation) {
368
+ const envelope = parseEnvelope(escalation);
369
+ const metadata = (escalation.metadata ?? {});
370
+ if (isAccumulator(escalation)) {
371
+ const store = envelope[escalation_1.ESCALATION_ACCUMULATE_KEYS.ITEMS];
372
+ const items = Object.entries(store)
373
+ .map(([itemKey, entry]) => ({ itemKey, ...entry }))
374
+ .sort((a, b) => a.at.localeCompare(b.at) || a.itemKey.localeCompare(b.itemKey));
375
+ const max = metadata[escalation_1.ESCALATION_ACCUMULATE_KEYS.MAX];
376
+ return {
377
+ escalationId: escalation.id,
378
+ kind: 'accumulate',
379
+ status: escalation.status,
380
+ count: items.length,
381
+ max: typeof max === 'number' ? max : null,
382
+ items,
383
+ };
384
+ }
385
+ if (isBatch(escalation)) {
386
+ const store = (envelope[escalation_1.ESCALATION_BATCH_KEYS.ITEMS] ?? {});
387
+ const filledAt = (envelope[escalation_1.ESCALATION_BATCH_KEYS.FILLED_AT] ?? {});
388
+ const keys = (metadata[escalation_1.ESCALATION_BATCH_KEYS.KEYS] ?? []);
389
+ const items = Object.entries(store)
390
+ .map(([itemKey, payload]) => ({ itemKey, payload: payload, at: filledAt[itemKey] ?? '' }))
391
+ .sort((a, b) => a.at.localeCompare(b.at) || a.itemKey.localeCompare(b.itemKey));
392
+ return {
393
+ escalationId: escalation.id,
394
+ kind: 'batch',
395
+ status: escalation.status,
396
+ count: items.length,
397
+ max: keys.length,
398
+ items,
399
+ pending: metadata[escalation_1.ESCALATION_BATCH_KEYS.PENDING] ?? [],
400
+ };
401
+ }
402
+ return null;
403
+ }
404
+ /** GET the held items of an accumulator or batch row, in arrival order. Read access; 404 non-disclosure. */
405
+ async function getEscalationItems(input, auth) {
406
+ try {
407
+ const escalation = await escalationService.getEscalation(input.id);
408
+ if (!escalation)
409
+ return { status: 404, error: 'Escalation not found' };
410
+ if (await (0, helpers_1.assertReadAccess)(auth.userId, escalation)) {
411
+ return { status: 404, error: 'Escalation not found' };
412
+ }
413
+ const view = itemsView(escalation);
414
+ if (!view)
415
+ return { status: 400, error: 'Escalation holds no items' };
416
+ return { status: 200, data: view };
417
+ }
418
+ catch (err) {
419
+ return { status: 500, error: err.message };
420
+ }
421
+ }
422
+ function sideData(side) {
423
+ return {
424
+ outcome: side.outcome,
425
+ count: side.count,
426
+ remaining: side.remaining,
427
+ escalationId: side.escalation.id,
428
+ signaled: side.outcome === 'completed' && !!side.escalation.signal_key,
429
+ };
430
+ }
431
+ /** Maps the SDK accumulate outcome vocabulary onto HTTP results. */
432
+ function accumulateOutcomeResult(result, itemKey, workflowId) {
433
+ const reciprocal = result.reciprocal ? { reciprocal: sideData(result.reciprocal) } : {};
434
+ switch (result.outcome) {
435
+ case 'completed':
436
+ return {
437
+ status: 200,
438
+ data: {
439
+ outcome: 'completed',
440
+ count: result.count,
441
+ remaining: 0,
442
+ signaled: !!result.escalation?.signal_key,
443
+ escalationId: result.escalation?.id,
444
+ workflowId,
445
+ ...reciprocal,
446
+ },
447
+ };
448
+ case 'accepted':
449
+ return {
450
+ status: 200,
451
+ data: {
452
+ outcome: 'accepted',
453
+ count: result.count,
454
+ remaining: result.remaining,
455
+ escalationId: result.escalation?.id,
456
+ ...reciprocal,
457
+ },
458
+ };
459
+ case 'duplicate-item':
460
+ return { status: 409, error: 'Item already held', data: { error: 'Item already held', itemKey } };
461
+ case 'full':
462
+ return { status: 409, error: 'Accumulator is full', data: { error: 'Accumulator is full', itemKey } };
463
+ case 'claimed-by-other':
464
+ return { status: 409, error: 'Escalation is claimed by another user' };
465
+ case 'claim-expired':
466
+ return { status: 409, error: 'Your claim has expired; re-claim this escalation to add to it' };
467
+ case 'not-found':
468
+ return { status: 404, error: 'Escalation not found' };
469
+ case 'not-accumulator':
470
+ return { status: 400, error: 'Escalation is not an accumulator' };
471
+ case 'reciprocal-not-found':
472
+ return { status: 404, error: 'Reciprocal escalation not found' };
473
+ case 'reciprocal-not-accumulator':
474
+ return { status: 400, error: 'Reciprocal escalation is not an accumulator' };
475
+ case 'reciprocal-duplicate':
476
+ return { status: 409, error: 'Reciprocal escalation already holds this container', data: { error: 'Reciprocal escalation already holds this container', outcome: result.outcome } };
477
+ case 'reciprocal-full':
478
+ return { status: 409, error: 'Reciprocal accumulator is full', data: { error: 'Reciprocal accumulator is full', outcome: result.outcome } };
479
+ case 'reciprocal-terminal':
480
+ return { status: 409, error: 'Reciprocal escalation is no longer pending', data: { error: 'Reciprocal escalation is no longer pending', outcome: result.outcome } };
481
+ default:
482
+ return { status: 409, error: 'Escalation not available for accumulation' };
483
+ }
484
+ }
485
+ function removeOutcomeResult(result, itemKey) {
486
+ switch (result.outcome) {
487
+ case 'removed':
488
+ return {
489
+ status: 200,
490
+ data: {
491
+ outcome: 'removed',
492
+ count: result.count,
493
+ escalationId: result.escalation?.id,
494
+ ...(result.reciprocal
495
+ ? { reciprocal: { count: result.reciprocal.count, escalationId: result.reciprocal.escalation.id } }
496
+ : {}),
497
+ },
498
+ };
499
+ case 'item-absent':
500
+ return { status: 404, error: 'Item not held by this escalation', data: { error: 'Item not held by this escalation', itemKey } };
501
+ case 'not-found':
502
+ return { status: 404, error: 'Escalation not found' };
503
+ case 'not-accumulator':
504
+ return { status: 400, error: 'Escalation is not an accumulator' };
505
+ case 'reciprocal-not-found':
506
+ return { status: 404, error: 'Reciprocal escalation not found' };
507
+ case 'reciprocal-not-accumulator':
508
+ return { status: 400, error: 'Reciprocal escalation is not an accumulator' };
509
+ case 'reciprocal-absent':
510
+ return { status: 404, error: 'Reciprocal escalation does not hold this container', data: { error: 'Reciprocal escalation does not hold this container', outcome: result.outcome } };
511
+ case 'reciprocal-terminal':
512
+ return { status: 409, error: 'Reciprocal escalation is no longer pending', data: { error: 'Reciprocal escalation is no longer pending', outcome: result.outcome } };
513
+ default:
514
+ return { status: 409, error: 'Escalation not available for accumulation' };
515
+ }
516
+ }
@@ -6,6 +6,7 @@ export { claimEscalation, releaseEscalation } from './claim';
6
6
  export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkUnassign, bulkEscalate, bulkTriage } from './bulk';
7
7
  export { resolveEscalation, resolveBySignalKey, resolveByIds, resolveAllOrNone } from './resolve';
8
8
  export { resolveBatchItem, resolveBatchItemBySignalKey, resolveBatchItemByMetadata } from './resolve-batch';
9
+ export { accumulateItem, accumulateItemBySignalKey, accumulateItemByMetadata, removeItem, removeItemBySignalKey, removeItemByMetadata, getEscalationItems, itemsView, } from './accumulate';
9
10
  export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
10
11
  export { cancelSingleEscalation, bulkCancel } from './cancel';
11
12
  export { searchByFacets, claimGroups, claimByFacets } from './facets';