@hotmeshio/long-tail 0.20.0 → 0.21.1

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 (361) hide show
  1. package/README.md +4 -4
  2. package/build/api/escalations/accumulate.d.ts +104 -0
  3. package/build/api/escalations/accumulate.js +541 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +11 -1
  6. package/build/api/roles.d.ts +4 -5
  7. package/build/api/roles.js +53 -4
  8. package/build/api/scan-codes/context.d.ts +14 -1
  9. package/build/api/scan-codes/context.js +30 -2
  10. package/build/api/scan-codes/execute.js +2 -0
  11. package/build/api/scan-codes/identity.js +1 -0
  12. package/build/api/scan-codes/verbs.d.ts +21 -0
  13. package/build/api/scan-codes/verbs.js +122 -3
  14. package/build/index.d.ts +2 -1
  15. package/build/index.js +63 -2
  16. package/build/lib/db/schemas/036_role_portals.sql +12 -0
  17. package/build/routes/escalations/accumulate.d.ts +7 -0
  18. package/build/routes/escalations/accumulate.js +158 -0
  19. package/build/routes/escalations/index.js +5 -0
  20. package/build/sdk/index.d.ts +28 -0
  21. package/build/sdk/index.js +9 -0
  22. package/build/services/escalation/accumulate.d.ts +81 -0
  23. package/build/services/escalation/accumulate.js +154 -0
  24. package/build/services/escalation/index.d.ts +1 -0
  25. package/build/services/escalation/index.js +1 -0
  26. package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
  27. package/build/services/orchestrator/condition.d.ts +40 -3
  28. package/build/services/orchestrator/condition.js +42 -2
  29. package/build/services/role/index.js +1 -0
  30. package/build/services/role/seed.js +6 -1
  31. package/build/services/role/sql.d.ts +6 -3
  32. package/build/services/role/sql.js +7 -2
  33. package/build/services/role/types.d.ts +38 -10
  34. package/build/services/role/types.js +10 -1
  35. package/build/services/scan-code/index.d.ts +1 -1
  36. package/build/services/scan-code/index.js +3 -1
  37. package/build/services/scan-code/parse.d.ts +17 -3
  38. package/build/services/scan-code/parse.js +37 -4
  39. package/build/services/scan-code/validate.js +35 -0
  40. package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
  41. package/build/shared/form-validation/display-only-widgets.js +25 -0
  42. package/build/shared/form-validation/index.d.ts +2 -0
  43. package/build/shared/form-validation/index.js +2 -0
  44. package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
  45. package/build/shared/form-validation/x-lt-bind.js +12 -8
  46. package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
  47. package/build/shared/form-validation/x-lt-invoke.js +103 -0
  48. package/build/system/mcp-servers/admin/escalations.js +44 -0
  49. package/build/system/mcp-servers/admin/schemas.d.ts +195 -13
  50. package/build/system/mcp-servers/admin/schemas.js +40 -3
  51. package/build/system/mcp-servers/admin/users.js +1 -0
  52. package/build/system/mcp-servers/docs.js +4 -0
  53. package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
  54. package/build/system/mcp-servers/human-queue-schemas.js +19 -1
  55. package/build/system/mcp-servers/human-queue.d.ts +2 -0
  56. package/build/system/mcp-servers/human-queue.js +77 -0
  57. package/build/system/seed/tool-manifests-admin.d.ts +1108 -100
  58. package/build/system/seed/tool-manifests-admin.js +4 -1
  59. package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
  60. package/build/system/seed/tool-manifests-escalation.js +56 -0
  61. package/build/tsconfig.tsbuildinfo +1 -1
  62. package/build/types/escalation.d.ts +52 -0
  63. package/build/types/escalation.js +29 -1
  64. package/build/types/index.d.ts +4 -4
  65. package/build/types/index.js +4 -1
  66. package/build/types/scan-code.d.ts +55 -1
  67. package/build/types/scan-code.js +29 -2
  68. package/build/types/startup.d.ts +20 -0
  69. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js → AdminDashboard-Covdam48.js} +2 -2
  70. package/dashboard/dist/assets/{AdminDashboard-DplvDBti.js.map → AdminDashboard-Covdam48.js.map} +1 -1
  71. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js → AgentConfigPage-CE1k6J5r.js} +6 -6
  72. package/dashboard/dist/assets/{AgentConfigPage-D8Bf6YxO.js.map → AgentConfigPage-CE1k6J5r.js.map} +1 -1
  73. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js → AgentDetailPage-CWJZIZP1.js} +3 -3
  74. package/dashboard/dist/assets/{AgentDetailPage-BN8g0Y2G.js.map → AgentDetailPage-CWJZIZP1.js.map} +1 -1
  75. package/dashboard/dist/assets/AgentsPage---Dg5ufF.js +2 -0
  76. package/dashboard/dist/assets/{AgentsPage-7JJBHku8.js.map → AgentsPage---Dg5ufF.js.map} +1 -1
  77. package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js +2 -0
  78. package/dashboard/dist/assets/AvailableEscalationsPage-CpbC8oTN.js.map +1 -0
  79. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js → BotPicker-D3drO3-T.js} +2 -2
  80. package/dashboard/dist/assets/{BotPicker-CGCnIz8I.js.map → BotPicker-D3drO3-T.js.map} +1 -1
  81. package/dashboard/dist/assets/BulkAssignModal-BOAWsViq.js +2 -0
  82. package/dashboard/dist/assets/{BulkAssignModal-NJBcoj-f.js.map → BulkAssignModal-BOAWsViq.js.map} +1 -1
  83. package/dashboard/dist/assets/CapabilitiesPage-RGgD3YZO.js +2 -0
  84. package/dashboard/dist/assets/{CapabilitiesPage-F8dpNn9B.js.map → CapabilitiesPage-RGgD3YZO.js.map} +1 -1
  85. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js → CollapsibleSection-DNkZn87n.js} +2 -2
  86. package/dashboard/dist/assets/{CollapsibleSection-BZW6VpCU.js.map → CollapsibleSection-DNkZn87n.js.map} +1 -1
  87. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js → ConfirmDeleteModal-BqzOwhPr.js} +2 -2
  88. package/dashboard/dist/assets/{ConfirmDeleteModal-64adXLdq.js.map → ConfirmDeleteModal-BqzOwhPr.js.map} +1 -1
  89. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js → CountdownTimer-BaexQMK6.js} +2 -2
  90. package/dashboard/dist/assets/{CountdownTimer-BxDub9d2.js.map → CountdownTimer-BaexQMK6.js.map} +1 -1
  91. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js → CredentialsPage-D7abp0aS.js} +2 -2
  92. package/dashboard/dist/assets/{CredentialsPage-CnLzopLL.js.map → CredentialsPage-D7abp0aS.js.map} +1 -1
  93. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js → CronLabel-DZiWmTwJ.js} +2 -2
  94. package/dashboard/dist/assets/{CronLabel-CAD5UYDT.js.map → CronLabel-DZiWmTwJ.js.map} +1 -1
  95. package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
  96. package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
  97. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
  98. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
  99. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js → ElapsedCell-BdGO_w4v.js} +2 -2
  100. package/dashboard/dist/assets/{ElapsedCell-CwO4ufd0.js.map → ElapsedCell-BdGO_w4v.js.map} +1 -1
  101. package/dashboard/dist/assets/EntityTimelinePanel-DIDcF5Yu.js +2 -0
  102. package/dashboard/dist/assets/{EntityTimelinePanel-CkF-oW-m.js.map → EntityTimelinePanel-DIDcF5Yu.js.map} +1 -1
  103. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js → EscalationListSchemaPage-C28rn9XC.js} +3 -3
  104. package/dashboard/dist/assets/{EscalationListSchemaPage-h9JO_q5f.js.map → EscalationListSchemaPage-C28rn9XC.js.map} +1 -1
  105. package/dashboard/dist/assets/EscalationListView-CkBnkpDJ.js +2 -0
  106. package/dashboard/dist/assets/EscalationListView-CkBnkpDJ.js.map +1 -0
  107. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js → EscalationSchemaPage-W5r0A1kj.js} +3 -3
  108. package/dashboard/dist/assets/{EscalationSchemaPage-mJFL5_Se.js.map → EscalationSchemaPage-W5r0A1kj.js.map} +1 -1
  109. package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js +2 -0
  110. package/dashboard/dist/assets/EscalationTimeline-DKyTz6sM.js.map +1 -0
  111. package/dashboard/dist/assets/EscalationTitleSelect-CzKfavri.js +2 -0
  112. package/dashboard/dist/assets/EscalationTitleSelect-CzKfavri.js.map +1 -0
  113. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js → EscalationsOverview-Tdu3Yx2c.js} +2 -2
  114. package/dashboard/dist/assets/{EscalationsOverview-DlXUFqWJ.js.map → EscalationsOverview-Tdu3Yx2c.js.map} +1 -1
  115. package/dashboard/dist/assets/{EventTable-Ike2xchn.js → EventTable-DiIxOJwO.js} +2 -2
  116. package/dashboard/dist/assets/{EventTable-Ike2xchn.js.map → EventTable-DiIxOJwO.js.map} +1 -1
  117. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js → FilterBar-CvMBCVIo.js} +2 -2
  118. package/dashboard/dist/assets/{FilterBar-DMOR-O1c.js.map → FilterBar-CvMBCVIo.js.map} +1 -1
  119. package/dashboard/dist/assets/GraphInvokePage-DO-yyhi6.js +2 -0
  120. package/dashboard/dist/assets/{GraphInvokePage-CKtvWowP.js.map → GraphInvokePage-DO-yyhi6.js.map} +1 -1
  121. package/dashboard/dist/assets/HomePage-DSS3eHR2.js +2 -0
  122. package/dashboard/dist/assets/{HomePage-BQ3Q791Q.js.map → HomePage-DSS3eHR2.js.map} +1 -1
  123. package/dashboard/dist/assets/ListToolbar-C3-Tqqub.js +2 -0
  124. package/dashboard/dist/assets/{ListToolbar-DdJzj472.js.map → ListToolbar-C3-Tqqub.js.map} +1 -1
  125. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js → McpOverview-DEJmsdVi.js} +2 -2
  126. package/dashboard/dist/assets/{McpOverview-BbtrduWn.js.map → McpOverview-DEJmsdVi.js.map} +1 -1
  127. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js → McpQueryDetailPage-DYJr16l7.js} +2 -2
  128. package/dashboard/dist/assets/{McpQueryDetailPage-C1L4T-Wt.js.map → McpQueryDetailPage-DYJr16l7.js.map} +1 -1
  129. package/dashboard/dist/assets/McpQueryPage-BBcG_UuU.js +2 -0
  130. package/dashboard/dist/assets/{McpQueryPage-CfJy7HZ7.js.map → McpQueryPage-BBcG_UuU.js.map} +1 -1
  131. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js → McpRunDetailPage-C6xw0kBg.js} +2 -2
  132. package/dashboard/dist/assets/{McpRunDetailPage-CA9yv7he.js.map → McpRunDetailPage-C6xw0kBg.js.map} +1 -1
  133. package/dashboard/dist/assets/McpRunsPage-CRQqrF4Q.js +2 -0
  134. package/dashboard/dist/assets/{McpRunsPage-D7QXjW9z.js.map → McpRunsPage-CRQqrF4Q.js.map} +1 -1
  135. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
  136. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
  137. package/dashboard/dist/assets/OperationsPage-Dlfwzf-0.js +3 -0
  138. package/dashboard/dist/assets/OperationsPage-Dlfwzf-0.js.map +1 -0
  139. package/dashboard/dist/assets/OperatorDashboard-DoiDGZ9R.js +2 -0
  140. package/dashboard/dist/assets/{OperatorDashboard-sXNDh1Ph.js.map → OperatorDashboard-DoiDGZ9R.js.map} +1 -1
  141. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
  142. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
  143. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
  144. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
  145. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js → PersonaDetailPage-BzbA4Prr.js} +2 -2
  146. package/dashboard/dist/assets/{PersonaDetailPage-NeHD-Gra.js.map → PersonaDetailPage-BzbA4Prr.js.map} +1 -1
  147. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js → PersonasPage-B36yn4hU.js} +2 -2
  148. package/dashboard/dist/assets/{PersonasPage-DavKXRWX.js.map → PersonasPage-B36yn4hU.js.map} +1 -1
  149. package/dashboard/dist/assets/PortalPage-BkD4YfDf.js +2 -0
  150. package/dashboard/dist/assets/PortalPage-BkD4YfDf.js.map +1 -0
  151. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js → ProcessDetailPage-BT0eiBWY.js} +2 -2
  152. package/dashboard/dist/assets/{ProcessDetailPage-DkdKJGe6.js.map → ProcessDetailPage-BT0eiBWY.js.map} +1 -1
  153. package/dashboard/dist/assets/ProcessesListPage-BEqeeNae.js +2 -0
  154. package/dashboard/dist/assets/{ProcessesListPage-CjwVKe32.js.map → ProcessesListPage-BEqeeNae.js.map} +1 -1
  155. package/dashboard/dist/assets/ResolverForm-BwgjIX97.js +7 -0
  156. package/dashboard/dist/assets/ResolverForm-BwgjIX97.js.map +1 -0
  157. package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js +8 -0
  158. package/dashboard/dist/assets/RoleDetailPage-BFuLNJXa.js.map +1 -0
  159. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
  160. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
  161. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js → RolesPage-80quJU5-.js} +2 -2
  162. package/dashboard/dist/assets/{RolesPage-OM9KM8Pg.js.map → RolesPage-80quJU5-.js.map} +1 -1
  163. package/dashboard/dist/assets/RunAsSelector-BoePhWVD.js +2 -0
  164. package/dashboard/dist/assets/{RunAsSelector-fFMt1bGe.js.map → RunAsSelector-BoePhWVD.js.map} +1 -1
  165. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js → ScanCodesPage-Cu1bKEix.js} +2 -2
  166. package/dashboard/dist/assets/{ScanCodesPage-AujH-pPQ.js.map → ScanCodesPage-Cu1bKEix.js.map} +1 -1
  167. package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js +2 -0
  168. package/dashboard/dist/assets/ScanSchemeDetailPage-D9AbS6UY.js.map +1 -0
  169. package/dashboard/dist/assets/ScanStationPage-gcZGefvT.js +2 -0
  170. package/dashboard/dist/assets/{ScanStationPage-C1_ppDoZ.js.map → ScanStationPage-gcZGefvT.js.map} +1 -1
  171. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
  172. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
  173. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js → StickyPagination-9ITrei_d.js} +2 -2
  174. package/dashboard/dist/assets/{StickyPagination-B91Pk9xh.js.map → StickyPagination-9ITrei_d.js.map} +1 -1
  175. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js → StreamMessageDetail-BkYvEHFY.js} +2 -2
  176. package/dashboard/dist/assets/{StreamMessageDetail-C7SPqaJt.js.map → StreamMessageDetail-BkYvEHFY.js.map} +1 -1
  177. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js → SwimlaneTimeline-B1rotFix.js} +2 -2
  178. package/dashboard/dist/assets/{SwimlaneTimeline-BcHR8ylf.js.map → SwimlaneTimeline-B1rotFix.js.map} +1 -1
  179. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
  180. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
  181. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js → TaskDetailPage-zhn_U_eC.js} +2 -2
  182. package/dashboard/dist/assets/{TaskDetailPage-Bqj0I_I0.js.map → TaskDetailPage-zhn_U_eC.js.map} +1 -1
  183. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
  184. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
  185. package/dashboard/dist/assets/TasksListPage-CNbNeagx.js +2 -0
  186. package/dashboard/dist/assets/{TasksListPage-BB1f79lL.js.map → TasksListPage-CNbNeagx.js.map} +1 -1
  187. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js → TimeAgo-0YVMBwls.js} +2 -2
  188. package/dashboard/dist/assets/{TimeAgo-BFnODmNe.js.map → TimeAgo-0YVMBwls.js.map} +1 -1
  189. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js → TimestampCell-DB7r3np8.js} +2 -2
  190. package/dashboard/dist/assets/{TimestampCell-BXgLOBsr.js.map → TimestampCell-DB7r3np8.js.map} +1 -1
  191. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
  192. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
  193. package/dashboard/dist/assets/ToolTestPanel-BLfA02wv.js +2 -0
  194. package/dashboard/dist/assets/{ToolTestPanel-Bwe3J5lj.js.map → ToolTestPanel-BLfA02wv.js.map} +1 -1
  195. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js → TopicDetailPage-eAqPKShq.js} +3 -3
  196. package/dashboard/dist/assets/{TopicDetailPage-DAF07vZ9.js.map → TopicDetailPage-eAqPKShq.js.map} +1 -1
  197. package/dashboard/dist/assets/TopicsPage-BNNWD-zl.js +2 -0
  198. package/dashboard/dist/assets/{TopicsPage-C1gxBUap.js.map → TopicsPage-BNNWD-zl.js.map} +1 -1
  199. package/dashboard/dist/assets/{UserName-BzXJUE6q.js → UserName-Pw46tO_k.js} +2 -2
  200. package/dashboard/dist/assets/{UserName-BzXJUE6q.js.map → UserName-Pw46tO_k.js.map} +1 -1
  201. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js → WorkflowExecutionPage-DvA51lT3.js} +2 -2
  202. package/dashboard/dist/assets/{WorkflowExecutionPage-SkRU5cRX.js.map → WorkflowExecutionPage-DvA51lT3.js.map} +1 -1
  203. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
  204. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
  205. package/dashboard/dist/assets/WorkflowsDashboard-DFDTwnhn.js +2 -0
  206. package/dashboard/dist/assets/{WorkflowsDashboard-CZAqRk1N.js.map → WorkflowsDashboard-DFDTwnhn.js.map} +1 -1
  207. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js → WorkflowsOverview-5i2Tcy-p.js} +2 -2
  208. package/dashboard/dist/assets/{WorkflowsOverview-BoN44VTE.js.map → WorkflowsOverview-5i2Tcy-p.js.map} +1 -1
  209. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js → YamlWorkflowDetailPage-p4VEYZS0.js} +11 -11
  210. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CqjhtdJf.js.map → YamlWorkflowDetailPage-p4VEYZS0.js.map} +1 -1
  211. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js → YamlWorkflowsPage-Cq-hMVxl.js} +2 -2
  212. package/dashboard/dist/assets/{YamlWorkflowsPage-CwnJkzyb.js.map → YamlWorkflowsPage-Cq-hMVxl.js.map} +1 -1
  213. package/dashboard/dist/assets/{agents-gV0Ys-sY.js → agents-EyBPJMYa.js} +2 -2
  214. package/dashboard/dist/assets/{agents-gV0Ys-sY.js.map → agents-EyBPJMYa.js.map} +1 -1
  215. package/dashboard/dist/assets/{bots-B97itB3I.js → bots-DX6jjqtF.js} +2 -2
  216. package/dashboard/dist/assets/{bots-B97itB3I.js.map → bots-DX6jjqtF.js.map} +1 -1
  217. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js → capabilities-ZdLv9xBQ.js} +2 -2
  218. package/dashboard/dist/assets/{capabilities-CR9xZgGd.js.map → capabilities-ZdLv9xBQ.js.map} +1 -1
  219. package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
  220. package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
  221. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js → controlplane-CpvZaJuw.js} +2 -2
  222. package/dashboard/dist/assets/{controlplane-YxvP1KCa.js.map → controlplane-CpvZaJuw.js.map} +1 -1
  223. package/dashboard/dist/assets/escalation-columns-Mvsze5eV.js +2 -0
  224. package/dashboard/dist/assets/escalation-columns-Mvsze5eV.js.map +1 -0
  225. package/dashboard/dist/assets/index-B_GT23TE.js +3 -0
  226. package/dashboard/dist/assets/index-B_GT23TE.js.map +1 -0
  227. package/dashboard/dist/assets/index-BbCjGO3M.js +2 -0
  228. package/dashboard/dist/assets/{index-CFbo9FU9.js.map → index-BbCjGO3M.js.map} +1 -1
  229. package/dashboard/dist/assets/{index-DMeaiKgf.js → index-Bhb89oHH.js} +2 -2
  230. package/dashboard/dist/assets/{index-DMeaiKgf.js.map → index-Bhb89oHH.js.map} +1 -1
  231. package/dashboard/dist/assets/index-CgUcYveM.js +67 -0
  232. package/dashboard/dist/assets/index-CgUcYveM.js.map +1 -0
  233. package/dashboard/dist/assets/index-Cn8uJsd7.js +2 -0
  234. package/dashboard/dist/assets/{index-BQpV-DTG.js.map → index-Cn8uJsd7.js.map} +1 -1
  235. package/dashboard/dist/assets/index-D-Xs4rAW.js +2 -0
  236. package/dashboard/dist/assets/{index-Bp9KBLT5.js.map → index-D-Xs4rAW.js.map} +1 -1
  237. package/dashboard/dist/assets/{index-DwOnWeu8.js → index-DGmzBY9D.js} +2 -2
  238. package/dashboard/dist/assets/{index-DwOnWeu8.js.map → index-DGmzBY9D.js.map} +1 -1
  239. package/dashboard/dist/assets/{index-CIpHj4di.js → index-DZhtP2Ok.js} +2 -2
  240. package/dashboard/dist/assets/{index-CIpHj4di.js.map → index-DZhtP2Ok.js.map} +1 -1
  241. package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
  242. package/dashboard/dist/assets/index-DkrBFFSO.js +13 -0
  243. package/dashboard/dist/assets/{index-Cfvkl2J0.js.map → index-DkrBFFSO.js.map} +1 -1
  244. package/dashboard/dist/assets/{index-B9BBCqLI.js → index-Eo-l3Lqo.js} +2 -2
  245. package/dashboard/dist/assets/{index-B9BBCqLI.js.map → index-Eo-l3Lqo.js.map} +1 -1
  246. package/dashboard/dist/assets/index-PfSRKerc.js +2 -0
  247. package/dashboard/dist/assets/{index-CUZ6LYye.js.map → index-PfSRKerc.js.map} +1 -1
  248. package/dashboard/dist/assets/{index-ipqwPavs.js → index-oFKUFGQL.js} +2 -2
  249. package/dashboard/dist/assets/{index-ipqwPavs.js.map → index-oFKUFGQL.js.map} +1 -1
  250. package/dashboard/dist/assets/index-z5Hpeidu.js +2 -0
  251. package/dashboard/dist/assets/index-z5Hpeidu.js.map +1 -0
  252. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js → knowledge-CgloEkaf.js} +2 -2
  253. package/dashboard/dist/assets/{knowledge-XX6cW4Ob.js.map → knowledge-CgloEkaf.js.map} +1 -1
  254. package/dashboard/dist/assets/{mcp-CH13hNH2.js → mcp-Bix7QYO7.js} +2 -2
  255. package/dashboard/dist/assets/{mcp-CH13hNH2.js.map → mcp-Bix7QYO7.js.map} +1 -1
  256. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js → mcp-query-o-sGX2ST.js} +2 -2
  257. package/dashboard/dist/assets/{mcp-query-Duydd3JA.js.map → mcp-query-o-sGX2ST.js.map} +1 -1
  258. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
  259. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
  260. package/dashboard/dist/assets/{personas-mDk4lLQS.js → personas-30azkJ_s.js} +2 -2
  261. package/dashboard/dist/assets/{personas-mDk4lLQS.js.map → personas-30azkJ_s.js.map} +1 -1
  262. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js → pipelines-Bfk2GFK7.js} +2 -2
  263. package/dashboard/dist/assets/{pipelines-B5GcgCeF.js.map → pipelines-Bfk2GFK7.js.map} +1 -1
  264. package/dashboard/dist/assets/{tasks-CItmNsRp.js → tasks-CpdopewW.js} +2 -2
  265. package/dashboard/dist/assets/{tasks-CItmNsRp.js.map → tasks-CpdopewW.js.map} +1 -1
  266. package/dashboard/dist/assets/{topics-CJYG7BX5.js → topics--bvCV9Yp.js} +2 -2
  267. package/dashboard/dist/assets/{topics-CJYG7BX5.js.map → topics--bvCV9Yp.js.map} +1 -1
  268. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
  269. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
  270. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js → useDebouncedValue-Da0lPmj3.js} +2 -2
  271. package/dashboard/dist/assets/{useDebouncedValue-BrwgXcp8.js.map → useDebouncedValue-Da0lPmj3.js.map} +1 -1
  272. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js → useNamespace-DD_Esl6n.js} +2 -2
  273. package/dashboard/dist/assets/{useNamespace-CHty0HAS.js.map → useNamespace-DD_Esl6n.js.map} +1 -1
  274. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js → useYamlActivityEvents-AeAhZJJk.js} +2 -2
  275. package/dashboard/dist/assets/{useYamlActivityEvents-CoTsia7t.js.map → useYamlActivityEvents-AeAhZJJk.js.map} +1 -1
  276. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
  277. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
  278. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js → yaml-workflows-BHAOOGvn.js} +2 -2
  279. package/dashboard/dist/assets/{yaml-workflows-CiWwx5rM.js.map → yaml-workflows-BHAOOGvn.js.map} +1 -1
  280. package/dashboard/dist/index.html +3 -3
  281. package/docs/accumulator.md +113 -0
  282. package/docs/api/http/escalations.md +90 -0
  283. package/docs/api/http/roles.md +1 -0
  284. package/docs/api/sdk/escalations.md +92 -0
  285. package/docs/api/sdk/roles.md +2 -0
  286. package/docs/architecture.md +1 -1
  287. package/docs/code-owned-configuration.md +2 -1
  288. package/docs/dashboard.md +10 -4
  289. package/docs/hitl/design.md +1 -1
  290. package/docs/hitl/escalation.md +37 -1
  291. package/docs/hitl/invoke-form.md +4 -0
  292. package/docs/hitl/pinned-views.md +4 -0
  293. package/docs/hitl/portal.md +97 -0
  294. package/docs/hitl/resolution.md +41 -0
  295. package/docs/hitl/x-lt-embed.md +1 -1
  296. package/docs/hitl/x-lt-invoke.md +95 -0
  297. package/docs/hitl/x-lt-list-schema.md +3 -1
  298. package/docs/hitl/x-lt-widget.md +1 -0
  299. package/docs/hitl-guide.md +8 -1
  300. package/docs/scan-codes.md +33 -9
  301. package/docs/sdk.md +1 -1
  302. package/docs/workflows.md +2 -2
  303. package/package.json +4 -2
  304. package/dashboard/dist/assets/AgentsPage-7JJBHku8.js +0 -2
  305. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js +0 -2
  306. package/dashboard/dist/assets/AvailableEscalationsPage-lz5qwSjg.js.map +0 -1
  307. package/dashboard/dist/assets/BulkAssignModal-NJBcoj-f.js +0 -2
  308. package/dashboard/dist/assets/CapabilitiesPage-F8dpNn9B.js +0 -2
  309. package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
  310. package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
  311. package/dashboard/dist/assets/EntityTimelinePanel-CkF-oW-m.js +0 -2
  312. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js +0 -2
  313. package/dashboard/dist/assets/EscalationListView-AHW2xtlr.js.map +0 -1
  314. package/dashboard/dist/assets/GraphInvokePage-CKtvWowP.js +0 -2
  315. package/dashboard/dist/assets/HomePage-BQ3Q791Q.js +0 -2
  316. package/dashboard/dist/assets/ListToolbar-DdJzj472.js +0 -2
  317. package/dashboard/dist/assets/McpQueryPage-CfJy7HZ7.js +0 -2
  318. package/dashboard/dist/assets/McpRunsPage-D7QXjW9z.js +0 -2
  319. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js +0 -3
  320. package/dashboard/dist/assets/OperationsPage-aLHHAP2X.js.map +0 -1
  321. package/dashboard/dist/assets/OperatorDashboard-sXNDh1Ph.js +0 -2
  322. package/dashboard/dist/assets/ProcessesListPage-CjwVKe32.js +0 -2
  323. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js +0 -3
  324. package/dashboard/dist/assets/ResolverForm-Bk-wDkN-.js.map +0 -1
  325. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js +0 -8
  326. package/dashboard/dist/assets/RoleDetailPage-WQt0y5l7.js.map +0 -1
  327. package/dashboard/dist/assets/RunAsSelector-fFMt1bGe.js +0 -2
  328. package/dashboard/dist/assets/ScanSchemeDetailPage-eKQpmsC_.js +0 -2
  329. package/dashboard/dist/assets/ScanSchemeDetailPage-eKQpmsC_.js.map +0 -1
  330. package/dashboard/dist/assets/ScanStationPage-C1_ppDoZ.js +0 -2
  331. package/dashboard/dist/assets/TasksListPage-BB1f79lL.js +0 -2
  332. package/dashboard/dist/assets/ToolTestPanel-Bwe3J5lj.js +0 -2
  333. package/dashboard/dist/assets/TopicsPage-C1gxBUap.js +0 -2
  334. package/dashboard/dist/assets/WorkflowsDashboard-CZAqRk1N.js +0 -2
  335. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js +0 -2
  336. package/dashboard/dist/assets/escalation-columns-uq-IV2aj.js.map +0 -1
  337. package/dashboard/dist/assets/index-3ezfWLkE.js +0 -6
  338. package/dashboard/dist/assets/index-3ezfWLkE.js.map +0 -1
  339. package/dashboard/dist/assets/index-BQpV-DTG.js +0 -2
  340. package/dashboard/dist/assets/index-Bp9KBLT5.js +0 -2
  341. package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
  342. package/dashboard/dist/assets/index-CFbo9FU9.js +0 -2
  343. package/dashboard/dist/assets/index-CIwlVfvV.js +0 -67
  344. package/dashboard/dist/assets/index-CIwlVfvV.js.map +0 -1
  345. package/dashboard/dist/assets/index-CUZ6LYye.js +0 -2
  346. package/dashboard/dist/assets/index-Cfvkl2J0.js +0 -13
  347. package/dashboard/dist/assets/index-SGyrXGp8.js +0 -3
  348. package/dashboard/dist/assets/index-SGyrXGp8.js.map +0 -1
  349. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js +0 -2
  350. package/dashboard/dist/assets/invoke-context-DrVyUEfs.js.map +0 -1
  351. package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
  352. package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
  353. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js +0 -2
  354. package/dashboard/dist/assets/resolver-payload-m9AGKZ3a.js.map +0 -1
  355. package/docs/compilation.md +0 -152
  356. package/docs/compiler.md +0 -311
  357. package/docs/contributing.md +0 -56
  358. package/docs/design-principles.md +0 -245
  359. package/docs/schema-exchange.md +0 -173
  360. package/docs/self-test.md +0 -106
  361. package/docs/story.md +0 -184
@@ -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.resolveBatchItemByMetadata = exports.resolveBatchItemBySignalKey = exports.resolveBatchItem = 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.getEscalationLookups = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetValues = 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.itemsView = exports.getEscalationItemsBySignalKey = exports.getEscalationItems = exports.removeItemByMetadata = exports.removeItemBySignalKey = exports.removeItem = exports.accumulateItemByMetadata = exports.accumulateItemBySignalKey = exports.accumulateItem = exports.resolveBatchItemByMetadata = exports.resolveBatchItemBySignalKey = exports.resolveBatchItem = 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.getEscalationLookups = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getStationMetrics = exports.getEscalationStats = exports.listFacetValues = 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");
@@ -37,6 +37,16 @@ var resolve_batch_1 = require("./resolve-batch");
37
37
  Object.defineProperty(exports, "resolveBatchItem", { enumerable: true, get: function () { return resolve_batch_1.resolveBatchItem; } });
38
38
  Object.defineProperty(exports, "resolveBatchItemBySignalKey", { enumerable: true, get: function () { return resolve_batch_1.resolveBatchItemBySignalKey; } });
39
39
  Object.defineProperty(exports, "resolveBatchItemByMetadata", { enumerable: true, get: function () { return resolve_batch_1.resolveBatchItemByMetadata; } });
40
+ var accumulate_1 = require("./accumulate");
41
+ Object.defineProperty(exports, "accumulateItem", { enumerable: true, get: function () { return accumulate_1.accumulateItem; } });
42
+ Object.defineProperty(exports, "accumulateItemBySignalKey", { enumerable: true, get: function () { return accumulate_1.accumulateItemBySignalKey; } });
43
+ Object.defineProperty(exports, "accumulateItemByMetadata", { enumerable: true, get: function () { return accumulate_1.accumulateItemByMetadata; } });
44
+ Object.defineProperty(exports, "removeItem", { enumerable: true, get: function () { return accumulate_1.removeItem; } });
45
+ Object.defineProperty(exports, "removeItemBySignalKey", { enumerable: true, get: function () { return accumulate_1.removeItemBySignalKey; } });
46
+ Object.defineProperty(exports, "removeItemByMetadata", { enumerable: true, get: function () { return accumulate_1.removeItemByMetadata; } });
47
+ Object.defineProperty(exports, "getEscalationItems", { enumerable: true, get: function () { return accumulate_1.getEscalationItems; } });
48
+ Object.defineProperty(exports, "getEscalationItemsBySignalKey", { enumerable: true, get: function () { return accumulate_1.getEscalationItemsBySignalKey; } });
49
+ Object.defineProperty(exports, "itemsView", { enumerable: true, get: function () { return accumulate_1.itemsView; } });
40
50
  var metadata_1 = require("./metadata");
41
51
  Object.defineProperty(exports, "findByMetadata", { enumerable: true, get: function () { return metadata_1.findByMetadata; } });
42
52
  Object.defineProperty(exports, "claimByMetadata", { enumerable: true, get: function () { return metadata_1.claimByMetadata; } });
@@ -1,3 +1,4 @@
1
+ import { type RolePin, type RolePortal } from '../services/role/types';
1
2
  import type { LTApiResult } from '../types/sdk';
2
3
  /**
3
4
  * List all distinct role names in the system.
@@ -89,11 +90,9 @@ export declare function updateRole(input: {
89
90
  /** The escalation LIST schema — rich formatting for this role's list page. */
90
91
  list_schema?: Record<string, any> | null;
91
92
  /** Pinned-view seeds for the role's members: [{ label, url, badge? }] or null to clear. */
92
- default_pins?: {
93
- label: string;
94
- url: string;
95
- badge?: boolean;
96
- }[] | null;
93
+ default_pins?: RolePin[] | null;
94
+ /** The role's named portals, each rows of pin cells; null to clear. */
95
+ portals?: RolePortal[] | null;
97
96
  properties?: Record<string, any> | null;
98
97
  ops_visible?: boolean;
99
98
  /** Make this role's sequence the home Pace Board's default segment (single-holder: setting it clears the previous holder). */
@@ -48,6 +48,7 @@ exports.getRoleListSchema = getRoleListSchema;
48
48
  exports.listRoleListSchemaVersions = listRoleListSchemaVersions;
49
49
  exports.deleteRole = deleteRole;
50
50
  const roleService = __importStar(require("../services/role"));
51
+ const types_1 = require("../services/role/types");
51
52
  const facet_sql_1 = require("../services/escalation/facet-sql");
52
53
  /**
53
54
  * List all distinct role names in the system.
@@ -201,6 +202,50 @@ async function replaceEscalationTargets(input) {
201
202
  return { status: 500, error: err.message };
202
203
  }
203
204
  }
205
+ /** A pinned view: a non-blank label over a dashboard-relative url, optionally badged. */
206
+ function isRolePin(p) {
207
+ if (!p || typeof p !== 'object')
208
+ return false;
209
+ const pin = p;
210
+ return typeof pin.label === 'string' && pin.label.trim() !== ''
211
+ && typeof pin.url === 'string' && pin.url.startsWith('/')
212
+ && (pin.badge === undefined || typeof pin.badge === 'boolean');
213
+ }
214
+ /** Rows of pin cells within the portal bounds; every row carries at least one pin. */
215
+ function isPortalRows(value) {
216
+ return Array.isArray(value)
217
+ && value.length >= 1 && value.length <= types_1.PORTAL_LIMITS.MAX_ROWS
218
+ && value.every((row) => Array.isArray(row)
219
+ && row.length >= 1 && row.length <= types_1.PORTAL_LIMITS.MAX_COLS
220
+ && row.every(isRolePin));
221
+ }
222
+ /** A count tile: a pin plus an optional blurb. */
223
+ function isPortalCount(value) {
224
+ if (!value || typeof value !== 'object')
225
+ return false;
226
+ const blurb = value.blurb;
227
+ return isRolePin(value) && (blurb === undefined || typeof blurb === 'string');
228
+ }
229
+ /** A named portal: slug key, non-blank label, a valid matrix, optional bounded counts. */
230
+ function isRolePortal(value) {
231
+ if (!value || typeof value !== 'object')
232
+ return false;
233
+ const portal = value;
234
+ const countsOk = portal.counts === undefined
235
+ || (Array.isArray(portal.counts) && portal.counts.length <= types_1.PORTAL_LIMITS.MAX_COUNTS && portal.counts.every(isPortalCount));
236
+ return typeof portal.key === 'string' && types_1.PORTAL_KEY.test(portal.key)
237
+ && typeof portal.label === 'string' && portal.label.trim() !== ''
238
+ && isPortalRows(portal.rows)
239
+ && countsOk;
240
+ }
241
+ /** The role's portals: bounded in number, every key unique. */
242
+ function isPortalList(value) {
243
+ if (!Array.isArray(value) || value.length < 1 || value.length > types_1.PORTAL_LIMITS.MAX_PORTALS)
244
+ return false;
245
+ if (!value.every(isRolePortal))
246
+ return false;
247
+ return new Set(value.map((p) => p.key)).size === value.length;
248
+ }
204
249
  /**
205
250
  * Update role metadata. Fields omitted from input are left unchanged.
206
251
  * form_schema, metadata_schema, and parent_role can be set to null to clear them.
@@ -241,14 +286,17 @@ async function updateRole(input) {
241
286
  return { status: 400, error: 'parent_role must reference a different role' };
242
287
  }
243
288
  if (input.default_pins != null) {
244
- const pinsValid = Array.isArray(input.default_pins) && input.default_pins.every((p) => p && typeof p === 'object'
245
- && typeof p.label === 'string' && p.label.trim() !== ''
246
- && typeof p.url === 'string' && p.url.startsWith('/')
247
- && (p.badge === undefined || typeof p.badge === 'boolean'));
289
+ const pinsValid = Array.isArray(input.default_pins) && input.default_pins.every(isRolePin);
248
290
  if (!pinsValid) {
249
291
  return { status: 400, error: 'default_pins must be [{ label, url, badge? }] with dashboard-relative urls' };
250
292
  }
251
293
  }
294
+ if (input.portals != null && !isPortalList(input.portals)) {
295
+ return {
296
+ status: 400,
297
+ error: `portals must be 1..${types_1.PORTAL_LIMITS.MAX_PORTALS} of { key (slug, unique), label, rows, counts? }, rows being 1..${types_1.PORTAL_LIMITS.MAX_ROWS} rows of 1..${types_1.PORTAL_LIMITS.MAX_COLS} pins [{ label, url, badge? }] with dashboard-relative urls, counts up to ${types_1.PORTAL_LIMITS.MAX_COUNTS} of { label, url, blurb? }`,
298
+ };
299
+ }
252
300
  if (input.upstream_roles != null) {
253
301
  if (!Array.isArray(input.upstream_roles) || input.upstream_roles.some((u) => typeof u !== 'string' || !u.trim())) {
254
302
  return { status: 400, error: 'upstream_roles must be an array of role names' };
@@ -269,6 +317,7 @@ async function updateRole(input) {
269
317
  metadata_schema: input.metadata_schema,
270
318
  list_schema: input.list_schema,
271
319
  default_pins: input.default_pins,
320
+ portals: input.portals,
272
321
  properties: input.properties,
273
322
  ops_visible: input.ops_visible,
274
323
  ops_home_default: input.ops_home_default,
@@ -16,8 +16,21 @@ export interface StepContext {
16
16
  }
17
17
  export declare function targetFilter(step: ScanStep, ctx: StepContext): Record<string, any>;
18
18
  export declare function templateContext(ctx: StepContext): scanCodeService.ScanTemplateContext;
19
+ /**
20
+ * The metadata of the acting user's single live claim, or undefined when
21
+ * they hold none or more than one. One scoped list query, read before the
22
+ * guarded write; the write re-checks everything under lock.
23
+ */
24
+ export declare function liveClaimMetadata(ctx: StepContext): Promise<Record<string, unknown> | undefined>;
25
+ /**
26
+ * The template context for one step: the scan tokens, the located item row's
27
+ * metadata when the verb has one, and the actor's live claim when the step's
28
+ * params mention `{claim.…}` (the lookup costs one query, so it runs only
29
+ * then).
30
+ */
31
+ export declare function stepTemplate(step: ScanStep, ctx: StepContext, item?: LTEscalationRecord): Promise<scanCodeService.ScanTemplateContext>;
19
32
  export declare function provenance(ctx: StepContext): Record<string, any>;
20
- export declare function interpolatedMetadata(step: ScanStep, ctx: StepContext): Record<string, any>;
33
+ export declare function interpolatedMetadata(step: ScanStep, ctx: StepContext, tpl?: scanCodeService.ScanTemplateContext): Record<string, any>;
21
34
  export declare function executed(escalation: LTEscalationRecord | Record<string, any> | undefined, step: Pick<ScanStep, 'verb'>): LTApiResult<ScanExecuteResponse>;
22
35
  export declare function forbidden(error?: string): LTApiResult<ScanExecuteResponse>;
23
36
  export declare function conflict(error?: string): LTApiResult<ScanExecuteResponse>;
@@ -35,6 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.targetFilter = targetFilter;
37
37
  exports.templateContext = templateContext;
38
+ exports.liveClaimMetadata = liveClaimMetadata;
39
+ exports.stepTemplate = stepTemplate;
38
40
  exports.provenance = provenance;
39
41
  exports.interpolatedMetadata = interpolatedMetadata;
40
42
  exports.executed = executed;
@@ -42,6 +44,7 @@ exports.forbidden = forbidden;
42
44
  exports.conflict = conflict;
43
45
  exports.notPrimed = notPrimed;
44
46
  const scanCodeService = __importStar(require("../../services/scan-code"));
47
+ const escalationService = __importStar(require("../../services/escalation"));
45
48
  const types_1 = require("../../types");
46
49
  function targetFilter(step, ctx) {
47
50
  return { [ctx.scheme.target_facet]: ctx.parsed.target, ...(step.query?.facets ?? {}) };
@@ -49,6 +52,31 @@ function targetFilter(step, ctx) {
49
52
  function templateContext(ctx) {
50
53
  return { target: ctx.parsed.target, category: ctx.parsed.category, scannedAt: ctx.scannedAt };
51
54
  }
55
+ /**
56
+ * The metadata of the acting user's single live claim, or undefined when
57
+ * they hold none or more than one. One scoped list query, read before the
58
+ * guarded write; the write re-checks everything under lock.
59
+ */
60
+ async function liveClaimMetadata(ctx) {
61
+ const { escalations } = await escalationService.listEscalations({
62
+ assigned_to: ctx.auth.userId,
63
+ status: 'pending',
64
+ limit: 2,
65
+ });
66
+ const live = escalations.filter(types_1.isEffectivelyClaimed);
67
+ return live.length === 1 ? (live[0].metadata ?? {}) : undefined;
68
+ }
69
+ /**
70
+ * The template context for one step: the scan tokens, the located item row's
71
+ * metadata when the verb has one, and the actor's live claim when the step's
72
+ * params mention `{claim.…}` (the lookup costs one query, so it runs only
73
+ * then).
74
+ */
75
+ async function stepTemplate(step, ctx, item) {
76
+ const base = templateContext(ctx);
77
+ const claim = scanCodeService.mentionsClaimToken(step.params) ? await liveClaimMetadata(ctx) : undefined;
78
+ return { ...base, ...(item ? { item: item.metadata ?? {} } : {}), ...(claim ? { claim } : {}) };
79
+ }
52
80
  function provenance(ctx) {
53
81
  return {
54
82
  [types_1.SCAN_PROVENANCE_KEYS.SCHEME]: ctx.scheme.version,
@@ -60,9 +88,9 @@ function provenance(ctx) {
60
88
  ...(ctx.acting ? { [types_1.SCAN_PROVENANCE_KEYS.STATION]: ctx.stationAuth.userId } : {}),
61
89
  };
62
90
  }
63
- function interpolatedMetadata(step, ctx) {
91
+ function interpolatedMetadata(step, ctx, tpl = templateContext(ctx)) {
64
92
  return step.params?.metadata
65
- ? scanCodeService.interpolateScanTemplate(step.params.metadata, templateContext(ctx))
93
+ ? scanCodeService.interpolateScanTemplate(step.params.metadata, tpl)
66
94
  : {};
67
95
  }
68
96
  function executed(escalation, step) {
@@ -171,6 +171,8 @@ async function executeStep(step, index, ctx) {
171
171
  return (0, verbs_1.releaseStep)(step, ctx);
172
172
  case types_1.SCAN_VERBS.CANCEL:
173
173
  return (0, verbs_1.cancelStep)(step, ctx);
174
+ case types_1.SCAN_VERBS.ACCUMULATE:
175
+ return (0, verbs_1.accumulateStep)(step, ctx);
174
176
  default:
175
177
  throw new Error(`unknown scan verb "${step.verb}"`);
176
178
  }
@@ -94,6 +94,7 @@ async function executeIdentityScan(parsed, scheme, rule, previousActingToken) {
94
94
  actor: { id: user.id, displayName: user.display_name || user.external_id },
95
95
  actingToken: (0, ephemeral_1.formatEphemeralToken)(uuid, types_1.ACTING_IDENTITY_LABEL),
96
96
  expiresAt,
97
+ maxUses: scheme.grant_max_uses ?? 0,
97
98
  },
98
99
  };
99
100
  }
@@ -13,3 +13,24 @@ export declare function releaseStep(step: ScanStep, ctx: StepContext): Promise<L
13
13
  */
14
14
  export declare function dispatchChoiceVerb(step: ScanStep, ctx: StepContext, row: Record<string, any>): Promise<LTApiResult<ScanExecuteResponse>>;
15
15
  export declare function cancelStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
16
+ /**
17
+ * Adds the scanned item to an accumulator. Two modes, one atomic write:
18
+ *
19
+ * - Item-locate (`params.accumulate.containerFacet`): the scan locates the
20
+ * item's own pending row through the scheme facet, reads the container
21
+ * facet value it carries, and adds the target to the container that shares
22
+ * it, writing the item row as the reciprocal in the same statement. An
23
+ * item with no row, or no container facet, falls through. An item whose
24
+ * container has closed and whose successor has not parked yet answers
25
+ * `no_open_container` with the item row, so the station can say "scan
26
+ * again" instead of showing the bag with no hint.
27
+ * - Container-locate (no `containerFacet`): the scan locates the container
28
+ * by the scheme facet and adds `params.itemKey` (template).
29
+ *
30
+ * Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
31
+ * mode, `{item.<facet>}` (the located row); an unresolvable token falls
32
+ * through. The write is the SDK's guarded statement; the locate only picks
33
+ * ids. A container already holding the item answers conflict, never a
34
+ * second add.
35
+ */
36
+ export declare function accumulateStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
@@ -39,24 +39,45 @@ exports.escalateStep = escalateStep;
39
39
  exports.releaseStep = releaseStep;
40
40
  exports.dispatchChoiceVerb = dispatchChoiceVerb;
41
41
  exports.cancelStep = cancelStep;
42
+ exports.accumulateStep = accumulateStep;
42
43
  const scanCodeService = __importStar(require("../../services/scan-code"));
43
44
  const escalationService = __importStar(require("../../services/escalation"));
44
45
  const metadata_1 = require("../escalations/metadata");
46
+ const accumulate_1 = require("../escalations/accumulate");
45
47
  const create_1 = require("../escalations/create");
46
48
  const claim_1 = require("../escalations/claim");
47
49
  const helpers_1 = require("../escalations/helpers");
48
50
  const types_1 = require("../../types");
49
51
  const context_1 = require("./context");
52
+ const locate_1 = require("./locate");
50
53
  // ── Mutating verbs — each a single atomic operation under the ACTOR's RBAC ──
51
54
  // ctx.auth is the effective actor: the badged person when a grant rode the
52
55
  // request, otherwise the authenticated principal. Attribution and write
53
56
  // scoping both derive from it, live, inside the escalation APIs.
57
+ /**
58
+ * Interpolates a step's params, or falls through when a `{claim.…}` or
59
+ * `{item.…}` token has nothing to read: a literal token never reaches a row.
60
+ */
61
+ async function templated(step, ctx, render, item) {
62
+ const tpl = await (0, context_1.stepTemplate)(step, ctx, item);
63
+ try {
64
+ return render(tpl);
65
+ }
66
+ catch (err) {
67
+ if (err instanceof scanCodeService.ScanTemplateError)
68
+ return null;
69
+ throw err;
70
+ }
71
+ }
54
72
  async function claimStep(step, ctx) {
73
+ const metadata = await templated(step, ctx, (tpl) => (0, context_1.interpolatedMetadata)(step, ctx, tpl));
74
+ if (metadata === null)
75
+ return null;
55
76
  const result = await (0, metadata_1.claimByMetadata)({
56
77
  key: ctx.scheme.target_facet,
57
78
  value: ctx.parsed.target,
58
79
  durationMinutes: step.params?.durationMinutes,
59
- metadata: { ...(0, context_1.interpolatedMetadata)(step, ctx), ...(0, context_1.provenance)(ctx) },
80
+ metadata: { ...metadata, ...(0, context_1.provenance)(ctx) },
60
81
  restrictRoles: step.query?.roles,
61
82
  }, ctx.auth);
62
83
  if (result.status === 404)
@@ -68,11 +89,17 @@ async function claimStep(step, ctx) {
68
89
  return (0, context_1.executed)(result.data.escalation, step);
69
90
  }
70
91
  async function resolveStep(step, ctx) {
92
+ const rendered = await templated(step, ctx, (tpl) => ({
93
+ resolverPayload: scanCodeService.interpolateScanTemplate(step.params?.resolverPayload ?? {}, tpl),
94
+ metadata: (0, context_1.interpolatedMetadata)(step, ctx, tpl),
95
+ }));
96
+ if (rendered === null)
97
+ return null;
71
98
  const result = await (0, metadata_1.resolveByMetadata)({
72
99
  key: ctx.scheme.target_facet,
73
100
  value: ctx.parsed.target,
74
- resolverPayload: scanCodeService.interpolateScanTemplate(step.params?.resolverPayload ?? {}, (0, context_1.templateContext)(ctx)),
75
- metadata: { ...(0, context_1.interpolatedMetadata)(step, ctx), ...(0, context_1.provenance)(ctx) },
101
+ resolverPayload: rendered.resolverPayload,
102
+ metadata: { ...rendered.metadata, ...(0, context_1.provenance)(ctx) },
76
103
  restrictRoles: step.query?.roles,
77
104
  extraFacets: step.query?.facets,
78
105
  }, ctx.auth);
@@ -203,3 +230,95 @@ async function cancelStep(step, ctx) {
203
230
  return (0, context_1.conflict)('Escalation is not cancellable (already terminal)');
204
231
  return (0, context_1.executed)(cancelled, step);
205
232
  }
233
+ /**
234
+ * Adds the scanned item to an accumulator. Two modes, one atomic write:
235
+ *
236
+ * - Item-locate (`params.accumulate.containerFacet`): the scan locates the
237
+ * item's own pending row through the scheme facet, reads the container
238
+ * facet value it carries, and adds the target to the container that shares
239
+ * it, writing the item row as the reciprocal in the same statement. An
240
+ * item with no row, or no container facet, falls through. An item whose
241
+ * container has closed and whose successor has not parked yet answers
242
+ * `no_open_container` with the item row, so the station can say "scan
243
+ * again" instead of showing the bag with no hint.
244
+ * - Container-locate (no `containerFacet`): the scan locates the container
245
+ * by the scheme facet and adds `params.itemKey` (template).
246
+ *
247
+ * Templates may read `{claim.<facet>}` (the actor's live claim) and, in item
248
+ * mode, `{item.<facet>}` (the located row); an unresolvable token falls
249
+ * through. The write is the SDK's guarded statement; the locate only picks
250
+ * ids. A container already holding the item answers conflict, never a
251
+ * second add.
252
+ */
253
+ async function accumulateStep(step, ctx) {
254
+ const options = step.params?.accumulate;
255
+ let item;
256
+ if (options?.containerFacet) {
257
+ const located = await (0, locate_1.locateForStep)(step, ctx, 1);
258
+ item = located?.escalations[0];
259
+ if (!item)
260
+ return null;
261
+ }
262
+ const rendered = await templated(step, ctx, (tpl) => ({
263
+ payload: step.params?.resolverPayload
264
+ ? scanCodeService.interpolateScanTemplate(step.params.resolverPayload, tpl)
265
+ : undefined,
266
+ metadata: { ...(0, context_1.interpolatedMetadata)(step, ctx, tpl), ...(0, context_1.provenance)(ctx) },
267
+ itemKey: options?.containerFacet
268
+ ? ctx.parsed.target
269
+ : scanCodeService.interpolateScanTemplate(step.params.itemKey, tpl),
270
+ }), item);
271
+ if (rendered === null)
272
+ return null;
273
+ let request;
274
+ let container;
275
+ if (options?.containerFacet && item) {
276
+ const containerValue = item.metadata?.[options.containerFacet];
277
+ if (containerValue === undefined || containerValue === null || containerValue === '')
278
+ return null;
279
+ container = { facet: options.containerFacet, value: String(containerValue) };
280
+ request = {
281
+ key: container.facet,
282
+ value: container.value,
283
+ itemKey: rendered.itemKey,
284
+ payload: rendered.payload,
285
+ metadata: rendered.metadata,
286
+ restrictRoles: options.containerRoles,
287
+ ...(options.reciprocal === false ? {} : { reciprocal: { id: item.id } }),
288
+ };
289
+ }
290
+ else {
291
+ request = {
292
+ key: ctx.scheme.target_facet,
293
+ value: ctx.parsed.target,
294
+ itemKey: rendered.itemKey,
295
+ payload: rendered.payload,
296
+ metadata: rendered.metadata,
297
+ restrictRoles: step.query?.roles,
298
+ };
299
+ }
300
+ const result = await (0, accumulate_1.accumulateItemByMetadata)(request, ctx.auth);
301
+ if (result.status === 404) {
302
+ if (!container || !item)
303
+ return null;
304
+ return {
305
+ status: 200,
306
+ data: {
307
+ outcome: types_1.SCAN_OUTCOMES.NO_OPEN_CONTAINER,
308
+ verb: step.verb,
309
+ escalation: item,
310
+ container,
311
+ fallback: ctx.rule.fallback,
312
+ error: `No open container carries ${container.facet} = ${container.value}`,
313
+ },
314
+ };
315
+ }
316
+ if (result.status === 403)
317
+ return (0, context_1.forbidden)(result.error);
318
+ if (result.status === 409)
319
+ return (0, context_1.conflict)(result.error);
320
+ if (result.status !== 200)
321
+ return result;
322
+ const escalation = result.data.escalationId ? { id: result.data.escalationId, ...result.data } : undefined;
323
+ return (0, context_1.executed)(escalation, step);
324
+ }
package/build/index.d.ts CHANGED
@@ -3,7 +3,8 @@ export { midnightTheme } from './themes/midnight';
3
3
  export { registerLT, createLTInterceptor } from './services/interceptor';
4
4
  export { createLTActivityInterceptor } from './services/interceptor/activity-interceptor';
5
5
  export { executeLT } from './services/orchestrator';
6
- export { conditional, conditionLT } from './services/orchestrator/condition';
6
+ export { conditional, conditionLT, conditionalAccumulator } from './services/orchestrator/condition';
7
+ export type { ConditionEscalationConfig, ConditionAccumulatorConfig } from './services/orchestrator/condition';
7
8
  export type { ExecuteLTOptions } from './services/orchestrator/types';
8
9
  export { JwtAuthAdapter, createAuthMiddleware, requireAuth, requireAdmin, signToken, setAuthAdapter } from './modules/auth';
9
10
  export * from './types';
package/build/index.js CHANGED
@@ -36,8 +36,8 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.getActivityIdentity = exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
- exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = void 0;
39
+ exports.McpEscalationStrategy = exports.DefaultEscalationStrategy = exports.escalationStrategyRegistry = exports.McpVisionServer = exports.McpTranslationServer = exports.McpServer = exports.McpClient = exports.McpService = exports.BuiltInMcpAdapter = exports.mcpRegistry = exports.defaultMaintenanceConfig = exports.maintenanceRegistry = exports.PinoLoggerAdapter = exports.loggerRegistry = exports.HoneycombTelemetryAdapter = exports.telemetryRegistry = exports.publishKnowledgeEvent = exports.publishAgentEvent = exports.publishWorkflowEvent = exports.publishActivityEvent = exports.publishEscalationEvent = exports.publishTaskEvent = exports.publishMilestoneEvent = exports.SocketIOEventAdapter = exports.InMemoryEventAdapter = exports.NatsEventAdapter = exports.eventRegistry = exports.ltConfig = exports.seedConfigTopics = exports.seedSystemTopics = exports.TopicService = exports.UserService = exports.ConfigService = exports.EscalationService = exports.TaskService = exports.setAuthAdapter = exports.signToken = exports.requireAdmin = exports.requireAuth = exports.createAuthMiddleware = exports.JwtAuthAdapter = exports.conditionalAccumulator = exports.conditionLT = exports.conditional = exports.executeLT = exports.createLTActivityInterceptor = exports.createLTInterceptor = exports.registerLT = exports.midnightTheme = exports.start = void 0;
40
+ exports.LTExpressAdapter = exports.api = exports.KnowledgeApi = exports.resolveCredential = exports.mimeFromPath = exports.getStorageBackend = exports.listOAuthConnections = exports.getFreshAccessToken = exports.createClient = exports.CallbackEventAdapter = exports.builtinMcpServerFactories = exports.getSystemAgents = exports.getSystemWorkers = exports.registerMcpTool = exports.getToolContext = exports.getActivityIdentity = void 0;
41
41
  const config_1 = require("./modules/config");
42
42
  const logger_1 = require("./lib/logger");
43
43
  const midnight_1 = require("./themes/midnight");
@@ -57,6 +57,7 @@ Object.defineProperty(exports, "executeLT", { enumerable: true, get: function ()
57
57
  var condition_1 = require("./services/orchestrator/condition");
58
58
  Object.defineProperty(exports, "conditional", { enumerable: true, get: function () { return condition_1.conditional; } });
59
59
  Object.defineProperty(exports, "conditionLT", { enumerable: true, get: function () { return condition_1.conditionLT; } });
60
+ Object.defineProperty(exports, "conditionalAccumulator", { enumerable: true, get: function () { return condition_1.conditionalAccumulator; } });
60
61
  var auth_1 = require("./modules/auth");
61
62
  Object.defineProperty(exports, "JwtAuthAdapter", { enumerable: true, get: function () { return auth_1.JwtAuthAdapter; } });
62
63
  Object.defineProperty(exports, "createAuthMiddleware", { enumerable: true, get: function () { return auth_1.createAuthMiddleware; } });
@@ -168,6 +169,66 @@ async function main() {
168
169
  },
169
170
  },
170
171
  examples: true,
172
+ // Code-owned declaration for the reviewer queue the examples route to: a
173
+ // portal that leads with the queue's counts and lays its lists beneath.
174
+ // `reset` keeps the declaration applied on every boot.
175
+ roles: [
176
+ {
177
+ role: 'reviewer',
178
+ title: 'Reviewer',
179
+ reset: true,
180
+ portals: [
181
+ {
182
+ key: 'review-desk',
183
+ label: 'Review desk',
184
+ counts: [
185
+ { label: 'Waiting', url: '/escalations/available?role=reviewer', blurb: 'Unclaimed items in the queue' },
186
+ { label: 'In progress', url: '/escalations/available?role=reviewer&status=claimed', blurb: 'Claimed and being worked' },
187
+ { label: 'Resolved', url: '/escalations/available?role=reviewer&status=resolved', blurb: 'Closed out by a reviewer' },
188
+ { label: 'Expired', url: '/escalations/available?role=reviewer&status=expired', blurb: 'Timed out before anyone acted' },
189
+ { label: 'Cancelled', url: '/escalations/available?role=reviewer&status=cancelled', blurb: 'Withdrawn by the workflow' },
190
+ ],
191
+ rows: [
192
+ [
193
+ { label: 'Waiting', url: '/escalations/available?role=reviewer&view=table&layout=compact', badge: true },
194
+ { label: 'In progress', url: '/escalations/available?role=reviewer&status=claimed&view=table&layout=compact', badge: true },
195
+ ],
196
+ ],
197
+ },
198
+ ],
199
+ },
200
+ {
201
+ // The rollup-bin example's container queue: the list shows each
202
+ // bin's fill level from the accumulator facets.
203
+ role: 'bin',
204
+ title: 'Bin',
205
+ description: 'Open containers filling with scanned bags. Ships at max or when the window closes.',
206
+ reset: true,
207
+ list_schema: {
208
+ 'x-lt-layout': 'facet-table',
209
+ 'x-lt-columns': [
210
+ { label: 'Bin', value: '{{metadata.binKey}}' },
211
+ { label: 'Held', value: '{{metadata.accumulate_count}}' },
212
+ { label: 'Max', value: '{{metadata.accumulate_max}}', priority: 2 },
213
+ { label: 'Open since', value: '{{escalation.created_at}}', format: 'age', priority: 2 },
214
+ ],
215
+ },
216
+ },
217
+ {
218
+ role: 'bag',
219
+ title: 'Bag',
220
+ description: 'Bags waiting to be scanned into a bin.',
221
+ reset: true,
222
+ list_schema: {
223
+ 'x-lt-layout': 'facet-table',
224
+ 'x-lt-columns': [
225
+ { label: 'Order', value: '{{metadata.orderId}}' },
226
+ { label: 'Bin', value: '{{metadata.binKey}}', priority: 2 },
227
+ { label: 'Waiting', value: '{{escalation.created_at}}', format: 'age', priority: 2 },
228
+ ],
229
+ },
230
+ },
231
+ ],
171
232
  features: {
172
233
  // The examples ship the full scan demo (schemes 10/11); surface it.
173
234
  scanCodes: true,
@@ -0,0 +1,12 @@
1
+ -- Migration 036: Role portals
2
+ --
3
+ -- portals is a role-owned list of named portal views. Each portal is a matrix
4
+ -- of pins: rows of cells, each cell a pinned view ({ label, url, badge? }).
5
+ -- The dashboard renders a portal as one page of live list panels at
6
+ -- /portal/:role/:portal, the visual form of the role's pinned views: one
7
+ -- portal for urgent items by facility, another for the team's focus of the
8
+ -- day, each cell named for a person and scoped to their facets. Unversioned
9
+ -- config, like default_pins; null means the role declares no portal.
10
+
11
+ ALTER TABLE lt_roles
12
+ ADD COLUMN IF NOT EXISTS portals JSONB;
@@ -0,0 +1,7 @@
1
+ import type { Router } from 'express';
2
+ /**
3
+ * Open-accumulator routes. The literal single-segment paths are registered
4
+ * before the parameterized routes so /:id never shadows them; the /:id/*
5
+ * forms run as the effective work actor (badge continuity at a station).
6
+ */
7
+ export declare function registerAccumulateRoutes(router: Router): void;