@hotmeshio/long-tail 0.19.1 → 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 (393) 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/api/workflows/config.d.ts +3 -0
  12. package/build/api/workflows/config.js +15 -0
  13. package/build/api/workflows/index.d.ts +1 -0
  14. package/build/api/workflows/index.js +3 -1
  15. package/build/api/workflows/input-lookups.d.ts +16 -0
  16. package/build/api/workflows/input-lookups.js +69 -0
  17. package/build/api/workflows/input-validation.d.ts +4 -3
  18. package/build/api/workflows/input-validation.js +7 -4
  19. package/build/api/workflows/invocable.js +1 -0
  20. package/build/api/workflows/invocation.js +1 -1
  21. package/build/index.js +60 -0
  22. package/build/lib/db/schemas/035_workflow_input_lookups.sql +9 -0
  23. package/build/lib/db/schemas/036_role_portals.sql +12 -0
  24. package/build/routes/escalations/accumulate.d.ts +7 -0
  25. package/build/routes/escalations/accumulate.js +150 -0
  26. package/build/routes/escalations/index.js +5 -0
  27. package/build/routes/workflows/config.js +10 -0
  28. package/build/sdk/index.d.ts +25 -0
  29. package/build/sdk/index.js +8 -0
  30. package/build/services/config/cache.js +1 -0
  31. package/build/services/config/read.js +2 -0
  32. package/build/services/config/sql.d.ts +2 -2
  33. package/build/services/config/sql.js +6 -5
  34. package/build/services/config/write.js +10 -1
  35. package/build/services/escalation/accumulate.d.ts +81 -0
  36. package/build/services/escalation/accumulate.js +154 -0
  37. package/build/services/escalation/index.d.ts +1 -0
  38. package/build/services/escalation/index.js +1 -0
  39. package/build/services/knowledge/index.d.ts +1 -0
  40. package/build/services/knowledge/index.js +1 -0
  41. package/build/services/knowledge/lookup-refs.d.ts +7 -0
  42. package/build/services/knowledge/lookup-refs.js +26 -0
  43. package/build/services/mcp/db-server/schemas.d.ts +2 -2
  44. package/build/services/mcp/playwright-server/schemas.d.ts +2 -2
  45. package/build/services/orchestrator/condition.d.ts +40 -3
  46. package/build/services/orchestrator/condition.js +42 -2
  47. package/build/services/role/index.js +1 -0
  48. package/build/services/role/seed.js +6 -1
  49. package/build/services/role/sql.d.ts +6 -3
  50. package/build/services/role/sql.js +7 -2
  51. package/build/services/role/types.d.ts +38 -10
  52. package/build/services/role/types.js +10 -1
  53. package/build/services/scan-code/validate.js +16 -0
  54. package/build/shared/form-validation/display-only-widgets.d.ts +16 -0
  55. package/build/shared/form-validation/display-only-widgets.js +25 -0
  56. package/build/shared/form-validation/field-validator.d.ts +1 -0
  57. package/build/shared/form-validation/field-validator.js +94 -6
  58. package/build/shared/form-validation/index.d.ts +2 -0
  59. package/build/shared/form-validation/index.js +2 -0
  60. package/build/shared/form-validation/invoke-context.d.ts +4 -3
  61. package/build/shared/form-validation/invoke-context.js +5 -4
  62. package/build/shared/form-validation/x-lt-bind.d.ts +2 -14
  63. package/build/shared/form-validation/x-lt-bind.js +12 -8
  64. package/build/shared/form-validation/x-lt-invoke.d.ts +38 -0
  65. package/build/shared/form-validation/x-lt-invoke.js +103 -0
  66. package/build/shared/form-validation/x-lt-options.d.ts +3 -3
  67. package/build/shared/form-validation/x-lt-options.js +19 -5
  68. package/build/shared/form-validation/x-lt-show-if.d.ts +5 -0
  69. package/build/shared/form-validation/x-lt-show-if.js +10 -0
  70. package/build/start/workers.js +10 -0
  71. package/build/system/mcp-servers/admin/escalations.js +39 -0
  72. package/build/system/mcp-servers/admin/schemas.d.ts +256 -33
  73. package/build/system/mcp-servers/admin/schemas.js +55 -3
  74. package/build/system/mcp-servers/admin/users.js +1 -0
  75. package/build/system/mcp-servers/admin/workflow-config.js +54 -9
  76. package/build/system/mcp-servers/admin/workflows.js +9 -7
  77. package/build/system/mcp-servers/db-query/schemas.d.ts +2 -2
  78. package/build/system/mcp-servers/docs.js +4 -0
  79. package/build/system/mcp-servers/human-queue-schemas.d.ts +85 -0
  80. package/build/system/mcp-servers/human-queue-schemas.js +19 -1
  81. package/build/system/mcp-servers/human-queue.d.ts +2 -0
  82. package/build/system/mcp-servers/human-queue.js +77 -0
  83. package/build/system/seed/tool-manifests-admin.d.ts +1509 -227
  84. package/build/system/seed/tool-manifests-admin.js +8 -4
  85. package/build/system/seed/tool-manifests-escalation.d.ts +174 -0
  86. package/build/system/seed/tool-manifests-escalation.js +56 -0
  87. package/build/tsconfig.tsbuildinfo +1 -1
  88. package/build/types/config.d.ts +4 -0
  89. package/build/types/escalation.d.ts +52 -0
  90. package/build/types/escalation.js +29 -1
  91. package/build/types/index.d.ts +2 -2
  92. package/build/types/index.js +3 -1
  93. package/build/types/scan-code.d.ts +24 -0
  94. package/build/types/scan-code.js +9 -0
  95. package/build/types/startup.d.ts +26 -0
  96. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js → AdminDashboard-uarpHB88.js} +2 -2
  97. package/dashboard/dist/assets/{AdminDashboard-Drs-9TRM.js.map → AdminDashboard-uarpHB88.js.map} +1 -1
  98. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js → AgentConfigPage-BcUaDD5E.js} +6 -6
  99. package/dashboard/dist/assets/{AgentConfigPage-BDPDZ7-v.js.map → AgentConfigPage-BcUaDD5E.js.map} +1 -1
  100. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js → AgentDetailPage-BaZBhK6i.js} +3 -3
  101. package/dashboard/dist/assets/{AgentDetailPage-CGBulM4_.js.map → AgentDetailPage-BaZBhK6i.js.map} +1 -1
  102. package/dashboard/dist/assets/AgentsPage-CuVFSDc4.js +2 -0
  103. package/dashboard/dist/assets/{AgentsPage-D77JeViQ.js.map → AgentsPage-CuVFSDc4.js.map} +1 -1
  104. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js +2 -0
  105. package/dashboard/dist/assets/AvailableEscalationsPage-iO5NyyIK.js.map +1 -0
  106. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js → BotPicker-CClMby6B.js} +2 -2
  107. package/dashboard/dist/assets/{BotPicker-CC5vI_Sv.js.map → BotPicker-CClMby6B.js.map} +1 -1
  108. package/dashboard/dist/assets/BulkAssignModal-BL8FRgkN.js +2 -0
  109. package/dashboard/dist/assets/{BulkAssignModal-BXiJnlqt.js.map → BulkAssignModal-BL8FRgkN.js.map} +1 -1
  110. package/dashboard/dist/assets/CapabilitiesPage-D53ogPor.js +2 -0
  111. package/dashboard/dist/assets/{CapabilitiesPage-D9TC2iKy.js.map → CapabilitiesPage-D53ogPor.js.map} +1 -1
  112. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js → CollapsibleSection-ow8jpbtD.js} +2 -2
  113. package/dashboard/dist/assets/{CollapsibleSection-D10lGw_u.js.map → CollapsibleSection-ow8jpbtD.js.map} +1 -1
  114. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js → ConfirmDeleteModal-CeEDt9iJ.js} +2 -2
  115. package/dashboard/dist/assets/{ConfirmDeleteModal-BJdLN6No.js.map → ConfirmDeleteModal-CeEDt9iJ.js.map} +1 -1
  116. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js → CountdownTimer-CSqyZMCG.js} +2 -2
  117. package/dashboard/dist/assets/{CountdownTimer-D9B-BjQ7.js.map → CountdownTimer-CSqyZMCG.js.map} +1 -1
  118. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js → CredentialsPage-Dx7SxA23.js} +2 -2
  119. package/dashboard/dist/assets/{CredentialsPage-hniUAFBK.js.map → CredentialsPage-Dx7SxA23.js.map} +1 -1
  120. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js → CronLabel-LYPxpvNN.js} +2 -2
  121. package/dashboard/dist/assets/{CronLabel-v9DCD2FX.js.map → CronLabel-LYPxpvNN.js.map} +1 -1
  122. package/dashboard/dist/assets/DataTable-spX1dFyb.js +2 -0
  123. package/dashboard/dist/assets/DataTable-spX1dFyb.js.map +1 -0
  124. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js → DropZone-f1o-GLM8.js} +2 -2
  125. package/dashboard/dist/assets/{DropZone-XlcY8hEH.js.map → DropZone-f1o-GLM8.js.map} +1 -1
  126. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js → ElapsedCell-BZJTSm9N.js} +2 -2
  127. package/dashboard/dist/assets/{ElapsedCell-_xvVTK8N.js.map → ElapsedCell-BZJTSm9N.js.map} +1 -1
  128. package/dashboard/dist/assets/EntityTimelinePanel-0wIIW2en.js +2 -0
  129. package/dashboard/dist/assets/{EntityTimelinePanel-1lT3jkCM.js.map → EntityTimelinePanel-0wIIW2en.js.map} +1 -1
  130. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js → EscalationListSchemaPage-CoYvtMzj.js} +3 -3
  131. package/dashboard/dist/assets/{EscalationListSchemaPage-BeQUTUEO.js.map → EscalationListSchemaPage-CoYvtMzj.js.map} +1 -1
  132. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js +2 -0
  133. package/dashboard/dist/assets/EscalationListView-DWFHPufv.js.map +1 -0
  134. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js → EscalationSchemaPage-C9Xu_A25.js} +3 -3
  135. package/dashboard/dist/assets/{EscalationSchemaPage-D4VlEwyS.js.map → EscalationSchemaPage-C9Xu_A25.js.map} +1 -1
  136. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js +2 -0
  137. package/dashboard/dist/assets/EscalationTimeline-D8W2LNNk.js.map +1 -0
  138. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js +2 -0
  139. package/dashboard/dist/assets/EscalationTitleSelect-DLK8NWMp.js.map +1 -0
  140. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js → EscalationsOverview-CW57FaP9.js} +2 -2
  141. package/dashboard/dist/assets/{EscalationsOverview-Bx6Zrzm-.js.map → EscalationsOverview-CW57FaP9.js.map} +1 -1
  142. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js → EventTable-D1ctWhKf.js} +2 -2
  143. package/dashboard/dist/assets/{EventTable-KEC3YWBf.js.map → EventTable-D1ctWhKf.js.map} +1 -1
  144. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js → FilterBar-C-iur-Nj.js} +2 -2
  145. package/dashboard/dist/assets/{FilterBar-xwN_b5fj.js.map → FilterBar-C-iur-Nj.js.map} +1 -1
  146. package/dashboard/dist/assets/GraphInvokePage-CcA_44M4.js +2 -0
  147. package/dashboard/dist/assets/{GraphInvokePage-DV7Y0fe2.js.map → GraphInvokePage-CcA_44M4.js.map} +1 -1
  148. package/dashboard/dist/assets/HomePage-Dc085ghJ.js +2 -0
  149. package/dashboard/dist/assets/{HomePage-G785SWcW.js.map → HomePage-Dc085ghJ.js.map} +1 -1
  150. package/dashboard/dist/assets/ListToolbar-h_ziBt4O.js +2 -0
  151. package/dashboard/dist/assets/{ListToolbar-zPVYPg3W.js.map → ListToolbar-h_ziBt4O.js.map} +1 -1
  152. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js → McpOverview-qXXhbNWV.js} +2 -2
  153. package/dashboard/dist/assets/{McpOverview-CMGUq8hx.js.map → McpOverview-qXXhbNWV.js.map} +1 -1
  154. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js → McpQueryDetailPage-SEzSbZrd.js} +2 -2
  155. package/dashboard/dist/assets/{McpQueryDetailPage-CdhLhaKn.js.map → McpQueryDetailPage-SEzSbZrd.js.map} +1 -1
  156. package/dashboard/dist/assets/McpQueryPage-Cy0V0kv9.js +2 -0
  157. package/dashboard/dist/assets/{McpQueryPage-CNSNMagY.js.map → McpQueryPage-Cy0V0kv9.js.map} +1 -1
  158. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js → McpRunDetailPage-DjJO5vSb.js} +2 -2
  159. package/dashboard/dist/assets/{McpRunDetailPage-DBm8hUaW.js.map → McpRunDetailPage-DjJO5vSb.js.map} +1 -1
  160. package/dashboard/dist/assets/McpRunsPage-BfjiJ8mM.js +2 -0
  161. package/dashboard/dist/assets/{McpRunsPage-B6rb5QBf.js.map → McpRunsPage-BfjiJ8mM.js.map} +1 -1
  162. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js → NamespacePill-DADRJOUl.js} +2 -2
  163. package/dashboard/dist/assets/{NamespacePill-Bb3revqD.js.map → NamespacePill-DADRJOUl.js.map} +1 -1
  164. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js +3 -0
  165. package/dashboard/dist/assets/OperationsPage-dJcER0T_.js.map +1 -0
  166. package/dashboard/dist/assets/OperatorDashboard-zCkW4eqk.js +2 -0
  167. package/dashboard/dist/assets/{OperatorDashboard-DBOscDnf.js.map → OperatorDashboard-zCkW4eqk.js.map} +1 -1
  168. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js → PageHeader-Csq434-v.js} +2 -2
  169. package/dashboard/dist/assets/{PageHeader-Di5Sz3an.js.map → PageHeader-Csq434-v.js.map} +1 -1
  170. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js → PageHeaderWithStats-CSnk1p5A.js} +2 -2
  171. package/dashboard/dist/assets/{PageHeaderWithStats-DutKJ-h2.js.map → PageHeaderWithStats-CSnk1p5A.js.map} +1 -1
  172. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js → PersonaDetailPage-Cx6L3Jvu.js} +2 -2
  173. package/dashboard/dist/assets/{PersonaDetailPage-BGRdGpeR.js.map → PersonaDetailPage-Cx6L3Jvu.js.map} +1 -1
  174. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js → PersonasPage-DOgGUlJl.js} +2 -2
  175. package/dashboard/dist/assets/{PersonasPage-DRzOZcVa.js.map → PersonasPage-DOgGUlJl.js.map} +1 -1
  176. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js +2 -0
  177. package/dashboard/dist/assets/PortalPage-BKuL1BeJ.js.map +1 -0
  178. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js → ProcessDetailPage-BFcFSDUv.js} +2 -2
  179. package/dashboard/dist/assets/{ProcessDetailPage-BLGjZXpM.js.map → ProcessDetailPage-BFcFSDUv.js.map} +1 -1
  180. package/dashboard/dist/assets/ProcessesListPage-BaHV2cXp.js +2 -0
  181. package/dashboard/dist/assets/{ProcessesListPage-5NnysKFC.js.map → ProcessesListPage-BaHV2cXp.js.map} +1 -1
  182. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js +7 -0
  183. package/dashboard/dist/assets/ResolverForm-Bgc0Zrya.js.map +1 -0
  184. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js +8 -0
  185. package/dashboard/dist/assets/RoleDetailPage-BPY6i3CU.js.map +1 -0
  186. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js → RolePill-BafrASDX.js} +2 -2
  187. package/dashboard/dist/assets/{RolePill-DhnVPK4q.js.map → RolePill-BafrASDX.js.map} +1 -1
  188. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js → RolesPage-DSqqKPbv.js} +2 -2
  189. package/dashboard/dist/assets/{RolesPage-BmW1LzkU.js.map → RolesPage-DSqqKPbv.js.map} +1 -1
  190. package/dashboard/dist/assets/RunAsSelector-B29iWwel.js +2 -0
  191. package/dashboard/dist/assets/{RunAsSelector-BwZTJ4Yj.js.map → RunAsSelector-B29iWwel.js.map} +1 -1
  192. package/dashboard/dist/assets/ScanCodesPage-S8aAJfnC.js +2 -0
  193. package/dashboard/dist/assets/{ScanCodesPage-FiYIYB-m.js.map → ScanCodesPage-S8aAJfnC.js.map} +1 -1
  194. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js → ScanSchemeDetailPage-CUBRAtmJ.js} +2 -2
  195. package/dashboard/dist/assets/{ScanSchemeDetailPage-BiAqtD-a.js.map → ScanSchemeDetailPage-CUBRAtmJ.js.map} +1 -1
  196. package/dashboard/dist/assets/ScanStationPage-R9t1-CeQ.js +2 -0
  197. package/dashboard/dist/assets/{ScanStationPage-8CdOtbCD.js.map → ScanStationPage-R9t1-CeQ.js.map} +1 -1
  198. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js → ScopeBadge-b6MIBiYD.js} +2 -2
  199. package/dashboard/dist/assets/{ScopeBadge-CXUg0FHo.js.map → ScopeBadge-b6MIBiYD.js.map} +1 -1
  200. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js → StickyPagination-CkW_A507.js} +2 -2
  201. package/dashboard/dist/assets/{StickyPagination-DRuqKhZt.js.map → StickyPagination-CkW_A507.js.map} +1 -1
  202. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js → StreamMessageDetail-yzWX0wac.js} +2 -2
  203. package/dashboard/dist/assets/{StreamMessageDetail-JwlbRiMn.js.map → StreamMessageDetail-yzWX0wac.js.map} +1 -1
  204. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js → SwimlaneTimeline-Cf4DXFxj.js} +2 -2
  205. package/dashboard/dist/assets/{SwimlaneTimeline-hu3c4bCJ.js.map → SwimlaneTimeline-Cf4DXFxj.js.map} +1 -1
  206. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js → TagInput-ZrIIrEUP.js} +2 -2
  207. package/dashboard/dist/assets/{TagInput-BZ8vb2oW.js.map → TagInput-ZrIIrEUP.js.map} +1 -1
  208. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js → TaskDetailPage-DCDcEps9.js} +2 -2
  209. package/dashboard/dist/assets/{TaskDetailPage-NqVZF3jW.js.map → TaskDetailPage-DCDcEps9.js.map} +1 -1
  210. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js → TaskQueuePill-DkQ1uc6y.js} +2 -2
  211. package/dashboard/dist/assets/{TaskQueuePill-Bxir8WRl.js.map → TaskQueuePill-DkQ1uc6y.js.map} +1 -1
  212. package/dashboard/dist/assets/TasksListPage-BBATgpf7.js +2 -0
  213. package/dashboard/dist/assets/{TasksListPage-BQNaSzCn.js.map → TasksListPage-BBATgpf7.js.map} +1 -1
  214. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js → TimeAgo-CSNVEjch.js} +2 -2
  215. package/dashboard/dist/assets/{TimeAgo-Cv35DOiI.js.map → TimeAgo-CSNVEjch.js.map} +1 -1
  216. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js → TimestampCell-Du1nBrPn.js} +2 -2
  217. package/dashboard/dist/assets/{TimestampCell-DHUXey9s.js.map → TimestampCell-Du1nBrPn.js.map} +1 -1
  218. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js → ToolPill-Baxm02L6.js} +2 -2
  219. package/dashboard/dist/assets/{ToolPill-FkgTXIhq.js.map → ToolPill-Baxm02L6.js.map} +1 -1
  220. package/dashboard/dist/assets/ToolTestPanel-CF-h_5Rg.js +2 -0
  221. package/dashboard/dist/assets/{ToolTestPanel-DvuLFWqQ.js.map → ToolTestPanel-CF-h_5Rg.js.map} +1 -1
  222. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js → TopicDetailPage-Dr1UmWcp.js} +3 -3
  223. package/dashboard/dist/assets/{TopicDetailPage-TXX3QNSo.js.map → TopicDetailPage-Dr1UmWcp.js.map} +1 -1
  224. package/dashboard/dist/assets/TopicsPage-CUUo-Ylf.js +2 -0
  225. package/dashboard/dist/assets/{TopicsPage-h-oyTeEJ.js.map → TopicsPage-CUUo-Ylf.js.map} +1 -1
  226. package/dashboard/dist/assets/{UserName-BceRCeDF.js → UserName-kBh1dc39.js} +2 -2
  227. package/dashboard/dist/assets/{UserName-BceRCeDF.js.map → UserName-kBh1dc39.js.map} +1 -1
  228. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js → WorkflowExecutionPage-CCRSbnDx.js} +2 -2
  229. package/dashboard/dist/assets/{WorkflowExecutionPage-CmHGcaN9.js.map → WorkflowExecutionPage-CCRSbnDx.js.map} +1 -1
  230. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js → WorkflowPill-ZepbO_ny.js} +2 -2
  231. package/dashboard/dist/assets/{WorkflowPill--AYMW7u_.js.map → WorkflowPill-ZepbO_ny.js.map} +1 -1
  232. package/dashboard/dist/assets/WorkflowsDashboard-BNQVvyek.js +2 -0
  233. package/dashboard/dist/assets/{WorkflowsDashboard-B0r2lQXk.js.map → WorkflowsDashboard-BNQVvyek.js.map} +1 -1
  234. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js → WorkflowsOverview-DswubNJN.js} +2 -2
  235. package/dashboard/dist/assets/{WorkflowsOverview-BTMc2PJ_.js.map → WorkflowsOverview-DswubNJN.js.map} +1 -1
  236. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js → YamlWorkflowDetailPage-Cw9Dlmup.js} +11 -11
  237. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DUiCVnZp.js.map → YamlWorkflowDetailPage-Cw9Dlmup.js.map} +1 -1
  238. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js → YamlWorkflowsPage-DB8xnIXy.js} +2 -2
  239. package/dashboard/dist/assets/{YamlWorkflowsPage-BAuXfwi0.js.map → YamlWorkflowsPage-DB8xnIXy.js.map} +1 -1
  240. package/dashboard/dist/assets/{agents-BvmLCk4h.js → agents-BwEnf6N9.js} +2 -2
  241. package/dashboard/dist/assets/{agents-BvmLCk4h.js.map → agents-BwEnf6N9.js.map} +1 -1
  242. package/dashboard/dist/assets/{bots-f_tyhl4I.js → bots-CCmJTT2u.js} +2 -2
  243. package/dashboard/dist/assets/{bots-f_tyhl4I.js.map → bots-CCmJTT2u.js.map} +1 -1
  244. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js → capabilities-BZHgp_nh.js} +2 -2
  245. package/dashboard/dist/assets/{capabilities-DNo5bqLx.js.map → capabilities-BZHgp_nh.js.map} +1 -1
  246. package/dashboard/dist/assets/{constants-BHkpVaqx.js → constants-CeBBTzf5.js} +2 -2
  247. package/dashboard/dist/assets/{constants-BHkpVaqx.js.map → constants-CeBBTzf5.js.map} +1 -1
  248. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js → controlplane-CyfwUlFA.js} +2 -2
  249. package/dashboard/dist/assets/{controlplane-Dyyj2Irb.js.map → controlplane-CyfwUlFA.js.map} +1 -1
  250. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js +2 -0
  251. package/dashboard/dist/assets/escalation-columns-BJPTNmLW.js.map +1 -0
  252. package/dashboard/dist/assets/index-3gbd5neL.js +67 -0
  253. package/dashboard/dist/assets/index-3gbd5neL.js.map +1 -0
  254. package/dashboard/dist/assets/index-BAAVTyZ-.js +2 -0
  255. package/dashboard/dist/assets/{index-DL83W7Gu.js.map → index-BAAVTyZ-.js.map} +1 -1
  256. package/dashboard/dist/assets/{index-CsKiRyhy.js → index-BC6Jenlo.js} +2 -2
  257. package/dashboard/dist/assets/{index-CsKiRyhy.js.map → index-BC6Jenlo.js.map} +1 -1
  258. package/dashboard/dist/assets/index-C7KHqOTQ.js +2 -0
  259. package/dashboard/dist/assets/{index-D7ESqn22.js.map → index-C7KHqOTQ.js.map} +1 -1
  260. package/dashboard/dist/assets/index-CDrqqbSR.js +3 -0
  261. package/dashboard/dist/assets/index-CDrqqbSR.js.map +1 -0
  262. package/dashboard/dist/assets/index-CVwzCZ43.js +2 -0
  263. package/dashboard/dist/assets/{index-DvxxrFBo.js.map → index-CVwzCZ43.js.map} +1 -1
  264. package/dashboard/dist/assets/index-CaGF6TCC.js +2 -0
  265. package/dashboard/dist/assets/index-CaGF6TCC.js.map +1 -0
  266. package/dashboard/dist/assets/index-ClVbfe4z.js +13 -0
  267. package/dashboard/dist/assets/index-ClVbfe4z.js.map +1 -0
  268. package/dashboard/dist/assets/{index-DWse7ERF.js → index-CuVkSmj5.js} +2 -2
  269. package/dashboard/dist/assets/{index-DWse7ERF.js.map → index-CuVkSmj5.js.map} +1 -1
  270. package/dashboard/dist/assets/{index-PcyGjmBm.js → index-DAuX_PlL.js} +2 -2
  271. package/dashboard/dist/assets/{index-PcyGjmBm.js.map → index-DAuX_PlL.js.map} +1 -1
  272. package/dashboard/dist/assets/{index-e2X-s0EQ.js → index-DBWS5QL8.js} +2 -2
  273. package/dashboard/dist/assets/{index-e2X-s0EQ.js.map → index-DBWS5QL8.js.map} +1 -1
  274. package/dashboard/dist/assets/index-DIWCI6HC.js +2 -0
  275. package/dashboard/dist/assets/{index-BNZknxFY.js.map → index-DIWCI6HC.js.map} +1 -1
  276. package/dashboard/dist/assets/{index-C-Xr2V3F.js → index-DZ8X_Gp4.js} +2 -2
  277. package/dashboard/dist/assets/{index-C-Xr2V3F.js.map → index-DZ8X_Gp4.js.map} +1 -1
  278. package/dashboard/dist/assets/index-Dh8MJl3L.css +1 -0
  279. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js → knowledge-CqyLhUMg.js} +2 -2
  280. package/dashboard/dist/assets/{knowledge-Coo6CKzo.js.map → knowledge-CqyLhUMg.js.map} +1 -1
  281. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js → mcp-Cvu6bFYH.js} +2 -2
  282. package/dashboard/dist/assets/{mcp-Cz5eFnP_.js.map → mcp-Cvu6bFYH.js.map} +1 -1
  283. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js → mcp-query-qC6A3e9l.js} +2 -2
  284. package/dashboard/dist/assets/{mcp-query-BtnuO4LF.js.map → mcp-query-qC6A3e9l.js.map} +1 -1
  285. package/dashboard/dist/assets/metadata-display-COo3mMCr.js +2 -0
  286. package/dashboard/dist/assets/metadata-display-COo3mMCr.js.map +1 -0
  287. package/dashboard/dist/assets/{personas-C2-LgpHQ.js → personas-BKN_lJuV.js} +2 -2
  288. package/dashboard/dist/assets/{personas-C2-LgpHQ.js.map → personas-BKN_lJuV.js.map} +1 -1
  289. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js → pipelines-BldIfv85.js} +2 -2
  290. package/dashboard/dist/assets/{pipelines-TuXQvUA-.js.map → pipelines-BldIfv85.js.map} +1 -1
  291. package/dashboard/dist/assets/{tasks-OUzpu__z.js → tasks-B-Uay8uL.js} +2 -2
  292. package/dashboard/dist/assets/{tasks-OUzpu__z.js.map → tasks-B-Uay8uL.js.map} +1 -1
  293. package/dashboard/dist/assets/{topics-B8bdrBaW.js → topics-438EQogt.js} +2 -2
  294. package/dashboard/dist/assets/{topics-B8bdrBaW.js.map → topics-438EQogt.js.map} +1 -1
  295. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js +2 -0
  296. package/dashboard/dist/assets/useContainerWidth-DSLp1gEm.js.map +1 -0
  297. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js → useDebouncedValue-Cw8hYZ8y.js} +2 -2
  298. package/dashboard/dist/assets/{useDebouncedValue-Cp5ZOtVE.js.map → useDebouncedValue-Cw8hYZ8y.js.map} +1 -1
  299. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js → useNamespace-D1218GQ8.js} +2 -2
  300. package/dashboard/dist/assets/{useNamespace-DtQe3wZ5.js.map → useNamespace-D1218GQ8.js.map} +1 -1
  301. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js → useYamlActivityEvents-BAQf_y_U.js} +2 -2
  302. package/dashboard/dist/assets/{useYamlActivityEvents-CS22c15X.js.map → useYamlActivityEvents-BAQf_y_U.js.map} +1 -1
  303. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js → vendor-icons-B7OcUM6b.js} +2 -2
  304. package/dashboard/dist/assets/{vendor-icons-DeBdvyKJ.js.map → vendor-icons-B7OcUM6b.js.map} +1 -1
  305. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js → yaml-workflows-CN01gEB0.js} +2 -2
  306. package/dashboard/dist/assets/{yaml-workflows-HQIki3hI.js.map → yaml-workflows-CN01gEB0.js.map} +1 -1
  307. package/dashboard/dist/index.html +3 -3
  308. package/docs/accumulator.md +113 -0
  309. package/docs/api/http/escalations.md +89 -0
  310. package/docs/api/http/roles.md +1 -0
  311. package/docs/api/http/workflows.md +28 -1
  312. package/docs/api/mcp/admin.md +40 -4
  313. package/docs/api/sdk/escalations.md +91 -0
  314. package/docs/api/sdk/roles.md +2 -0
  315. package/docs/architecture.md +1 -1
  316. package/docs/code-owned-configuration.md +3 -2
  317. package/docs/dashboard.md +11 -5
  318. package/docs/hitl/design.md +1 -1
  319. package/docs/hitl/escalation.md +37 -1
  320. package/docs/hitl/form.md +12 -7
  321. package/docs/hitl/invoke-form.md +10 -3
  322. package/docs/hitl/lookups.md +21 -0
  323. package/docs/hitl/pinned-views.md +4 -0
  324. package/docs/hitl/portal.md +97 -0
  325. package/docs/hitl/resolution.md +41 -0
  326. package/docs/hitl/x-lt-embed.md +1 -1
  327. package/docs/hitl/x-lt-invoke.md +95 -0
  328. package/docs/hitl/x-lt-list-schema.md +3 -1
  329. package/docs/hitl/x-lt-validation.md +50 -3
  330. package/docs/hitl/x-lt-widget.md +22 -0
  331. package/docs/hitl-guide.md +12 -2
  332. package/docs/scan-codes.md +15 -2
  333. package/docs/sdk.md +1 -1
  334. package/docs/workflows.md +2 -2
  335. package/package.json +4 -2
  336. package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +0 -2
  337. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +0 -2
  338. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +0 -1
  339. package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +0 -2
  340. package/dashboard/dist/assets/CapabilitiesPage-D9TC2iKy.js +0 -2
  341. package/dashboard/dist/assets/DataTable-7C7riavf.js +0 -2
  342. package/dashboard/dist/assets/DataTable-7C7riavf.js.map +0 -1
  343. package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +0 -2
  344. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +0 -2
  345. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +0 -1
  346. package/dashboard/dist/assets/GraphInvokePage-DV7Y0fe2.js +0 -2
  347. package/dashboard/dist/assets/HomePage-G785SWcW.js +0 -2
  348. package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +0 -2
  349. package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +0 -2
  350. package/dashboard/dist/assets/McpRunsPage-B6rb5QBf.js +0 -2
  351. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +0 -3
  352. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +0 -1
  353. package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +0 -2
  354. package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +0 -2
  355. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +0 -2
  356. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +0 -1
  357. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +0 -8
  358. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +0 -1
  359. package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +0 -2
  360. package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +0 -2
  361. package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +0 -2
  362. package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +0 -2
  363. package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +0 -2
  364. package/dashboard/dist/assets/TopicsPage-h-oyTeEJ.js +0 -2
  365. package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +0 -2
  366. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +0 -2
  367. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +0 -1
  368. package/dashboard/dist/assets/index-BMlQYOE1.js +0 -67
  369. package/dashboard/dist/assets/index-BMlQYOE1.js.map +0 -1
  370. package/dashboard/dist/assets/index-BNZknxFY.js +0 -2
  371. package/dashboard/dist/assets/index-Bpvfr4OW.css +0 -1
  372. package/dashboard/dist/assets/index-CegPUKpc.js +0 -3
  373. package/dashboard/dist/assets/index-CegPUKpc.js.map +0 -1
  374. package/dashboard/dist/assets/index-D7ESqn22.js +0 -2
  375. package/dashboard/dist/assets/index-DL83W7Gu.js +0 -2
  376. package/dashboard/dist/assets/index-DPLssnMW.js +0 -6
  377. package/dashboard/dist/assets/index-DPLssnMW.js.map +0 -1
  378. package/dashboard/dist/assets/index-DoETPlJP.js +0 -11
  379. package/dashboard/dist/assets/index-DoETPlJP.js.map +0 -1
  380. package/dashboard/dist/assets/index-DvxxrFBo.js +0 -2
  381. package/dashboard/dist/assets/metadata-display--TzK0REC.js +0 -2
  382. package/dashboard/dist/assets/metadata-display--TzK0REC.js.map +0 -1
  383. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +0 -2
  384. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +0 -1
  385. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +0 -2
  386. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +0 -1
  387. package/docs/compilation.md +0 -152
  388. package/docs/compiler.md +0 -311
  389. package/docs/contributing.md +0 -56
  390. package/docs/design-principles.md +0 -244
  391. package/docs/schema-exchange.md +0 -173
  392. package/docs/self-test.md +0 -106
  393. 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.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,15 @@ 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, "itemsView", { enumerable: true, get: function () { return accumulate_1.itemsView; } });
40
49
  var metadata_1 = require("./metadata");
41
50
  Object.defineProperty(exports, "findByMetadata", { enumerable: true, get: function () { return metadata_1.findByMetadata; } });
42
51
  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,
@@ -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
  }
@@ -13,3 +13,18 @@ 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.
24
+ * - Container-locate (no `containerFacet`): the scan locates the container
25
+ * by the scheme facet and adds `params.itemKey` (template).
26
+ *
27
+ * The write is the SDK's guarded statement; the locate only picks ids. A
28
+ * container already holding the item answers conflict, never a second add.
29
+ */
30
+ export declare function accumulateStep(step: ScanStep, ctx: StepContext): Promise<LTApiResult<ScanExecuteResponse> | null>;
@@ -39,14 +39,17 @@ 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
@@ -203,3 +206,65 @@ async function cancelStep(step, ctx) {
203
206
  return (0, context_1.conflict)('Escalation is not cancellable (already terminal)');
204
207
  return (0, context_1.executed)(cancelled, step);
205
208
  }
209
+ /**
210
+ * Adds the scanned item to an accumulator. Two modes, one atomic write:
211
+ *
212
+ * - Item-locate (`params.accumulate.containerFacet`): the scan locates the
213
+ * item's own pending row through the scheme facet, reads the container
214
+ * facet value it carries, and adds the target to the container that shares
215
+ * it, writing the item row as the reciprocal in the same statement. An
216
+ * item with no row, or no container facet, falls through.
217
+ * - Container-locate (no `containerFacet`): the scan locates the container
218
+ * by the scheme facet and adds `params.itemKey` (template).
219
+ *
220
+ * The write is the SDK's guarded statement; the locate only picks ids. A
221
+ * container already holding the item answers conflict, never a second add.
222
+ */
223
+ async function accumulateStep(step, ctx) {
224
+ const tpl = (0, context_1.templateContext)(ctx);
225
+ const payload = step.params?.resolverPayload
226
+ ? scanCodeService.interpolateScanTemplate(step.params.resolverPayload, tpl)
227
+ : undefined;
228
+ const metadata = { ...(0, context_1.interpolatedMetadata)(step, ctx), ...(0, context_1.provenance)(ctx) };
229
+ const options = step.params?.accumulate;
230
+ let request;
231
+ if (options?.containerFacet) {
232
+ const located = await (0, locate_1.locateForStep)(step, ctx, 1);
233
+ const item = located?.escalations[0];
234
+ if (!item)
235
+ return null;
236
+ const containerValue = item.metadata?.[options.containerFacet];
237
+ if (containerValue === undefined || containerValue === null || containerValue === '')
238
+ return null;
239
+ request = {
240
+ key: options.containerFacet,
241
+ value: String(containerValue),
242
+ itemKey: ctx.parsed.target,
243
+ payload,
244
+ metadata,
245
+ restrictRoles: options.containerRoles,
246
+ ...(options.reciprocal === false ? {} : { reciprocal: { id: item.id } }),
247
+ };
248
+ }
249
+ else {
250
+ request = {
251
+ key: ctx.scheme.target_facet,
252
+ value: ctx.parsed.target,
253
+ itemKey: scanCodeService.interpolateScanTemplate(step.params.itemKey, tpl),
254
+ payload,
255
+ metadata,
256
+ restrictRoles: step.query?.roles,
257
+ };
258
+ }
259
+ const result = await (0, accumulate_1.accumulateItemByMetadata)(request, ctx.auth);
260
+ if (result.status === 404)
261
+ return null;
262
+ if (result.status === 403)
263
+ return (0, context_1.forbidden)(result.error);
264
+ if (result.status === 409)
265
+ return (0, context_1.conflict)(result.error);
266
+ if (result.status !== 200)
267
+ return result;
268
+ const escalation = result.data.escalationId ? { id: result.data.escalationId, ...result.data } : undefined;
269
+ return (0, context_1.executed)(escalation, step);
270
+ }
@@ -1,3 +1,4 @@
1
+ import { type EscalationLookupRef } from '../../types/escalation';
1
2
  import type { LTApiResult } from '../../types/sdk';
2
3
  /**
3
4
  * List all registered workflow configurations.
@@ -38,6 +39,7 @@ export declare function getWorkflowConfig(input: {
38
39
  * @param input.envelope_schema — JSON template that pre-fills the invoke form
39
40
  * @param input.input_schema — x-lt-* JSON Schema for the rich invoke form; invoke validates data against it
40
41
  * @param input.icon — curated icon name (WORKFLOW_ICONS); anything else is refused
42
+ * @param input.input_lookups: versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused
41
43
  * @param input.resolver_schema — JSON Schema for resolver payload validation
42
44
  * @param input.cron_schedule — cron expression for scheduled execution
43
45
  * @returns `{ status: 200, data: <saved config> }`
@@ -57,6 +59,7 @@ export declare function upsertWorkflowConfig(input: {
57
59
  envelope_schema?: any;
58
60
  input_schema?: any;
59
61
  icon?: string | null;
62
+ input_lookups?: EscalationLookupRef[] | null;
60
63
  resolver_schema?: any;
61
64
  cron_schedule?: string | null;
62
65
  read_safe?: boolean;
@@ -39,6 +39,8 @@ exports.upsertWorkflowConfig = upsertWorkflowConfig;
39
39
  exports.deleteWorkflowConfig = deleteWorkflowConfig;
40
40
  const configService = __importStar(require("../../services/config"));
41
41
  const workflow_icons_1 = require("../../types/workflow-icons");
42
+ const escalation_1 = require("../../types/escalation");
43
+ const lookup_refs_1 = require("../../services/knowledge/lookup-refs");
42
44
  const cron_1 = require("../../services/cron");
43
45
  const ltconfig_1 = require("../../modules/ltconfig");
44
46
  /**
@@ -97,6 +99,7 @@ async function getWorkflowConfig(input) {
97
99
  * @param input.envelope_schema — JSON template that pre-fills the invoke form
98
100
  * @param input.input_schema — x-lt-* JSON Schema for the rich invoke form; invoke validates data against it
99
101
  * @param input.icon — curated icon name (WORKFLOW_ICONS); anything else is refused
102
+ * @param input.input_lookups: versioned knowledge refs the invoke form reads as `lookup.<as ?? key>`; malformed refs are refused
100
103
  * @param input.resolver_schema — JSON Schema for resolver payload validation
101
104
  * @param input.cron_schedule — cron expression for scheduled execution
102
105
  * @returns `{ status: 200, data: <saved config> }`
@@ -106,6 +109,17 @@ async function upsertWorkflowConfig(input) {
106
109
  if (input.icon && !(0, workflow_icons_1.isWorkflowIcon)(input.icon)) {
107
110
  return { status: 400, error: `Unknown workflow icon "${input.icon}"; choose one of WORKFLOW_ICONS` };
108
111
  }
112
+ if (input.input_lookups != null) {
113
+ try {
114
+ (0, escalation_1.assertLookupRefs)(input.input_lookups);
115
+ }
116
+ catch (err) {
117
+ return { status: 400, error: err.message };
118
+ }
119
+ const missing = await (0, lookup_refs_1.describeMissingLookupRefs)(input.input_lookups);
120
+ if (missing.length)
121
+ return { status: 400, error: missing.join('; ') };
122
+ }
109
123
  // Validate cron expression before persisting
110
124
  if (input.cron_schedule) {
111
125
  const { validateCronSchedule } = await Promise.resolve().then(() => __importStar(require('../../services/cron')));
@@ -126,6 +140,7 @@ async function upsertWorkflowConfig(input) {
126
140
  envelope_schema: input.envelope_schema ?? null,
127
141
  input_schema: input.input_schema ?? null,
128
142
  icon: input.icon ?? null,
143
+ input_lookups: input.input_lookups ?? null,
129
144
  resolver_schema: input.resolver_schema ?? null,
130
145
  cron_schedule: input.cron_schedule ?? null,
131
146
  read_safe: input.read_safe ?? false,
@@ -3,4 +3,5 @@ export { listWorkers, listDiscoveredWorkflows, getCronStatus, } from './discover
3
3
  export { listInvocableWorkflows, WORKFLOW_TIERS } from './invocable';
4
4
  export type { InvocableWorkflowEntry, WorkflowTier } from './invocable';
5
5
  export { checkInvokeInput, inputValidationFailure } from './input-validation';
6
+ export { getWorkflowInputLookups } from './input-lookups';
6
7
  export { listWorkflowConfigs, getWorkflowConfig, upsertWorkflowConfig, deleteWorkflowConfig, } from './config';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.deleteWorkflowConfig = exports.upsertWorkflowConfig = exports.getWorkflowConfig = exports.listWorkflowConfigs = exports.inputValidationFailure = exports.checkInvokeInput = exports.WORKFLOW_TIERS = exports.listInvocableWorkflows = exports.getCronStatus = exports.listDiscoveredWorkflows = exports.listWorkers = exports.exportWorkflow = exports.terminateWorkflow = exports.getWorkflowResult = exports.getWorkflowStatus = exports.invokeWorkflow = void 0;
3
+ exports.deleteWorkflowConfig = exports.upsertWorkflowConfig = exports.getWorkflowConfig = exports.listWorkflowConfigs = exports.getWorkflowInputLookups = exports.inputValidationFailure = exports.checkInvokeInput = exports.WORKFLOW_TIERS = exports.listInvocableWorkflows = exports.getCronStatus = exports.listDiscoveredWorkflows = exports.listWorkers = exports.exportWorkflow = exports.terminateWorkflow = exports.getWorkflowResult = exports.getWorkflowStatus = exports.invokeWorkflow = void 0;
4
4
  var invocation_1 = require("./invocation");
5
5
  Object.defineProperty(exports, "invokeWorkflow", { enumerable: true, get: function () { return invocation_1.invokeWorkflow; } });
6
6
  Object.defineProperty(exports, "getWorkflowStatus", { enumerable: true, get: function () { return invocation_1.getWorkflowStatus; } });
@@ -17,6 +17,8 @@ Object.defineProperty(exports, "WORKFLOW_TIERS", { enumerable: true, get: functi
17
17
  var input_validation_1 = require("./input-validation");
18
18
  Object.defineProperty(exports, "checkInvokeInput", { enumerable: true, get: function () { return input_validation_1.checkInvokeInput; } });
19
19
  Object.defineProperty(exports, "inputValidationFailure", { enumerable: true, get: function () { return input_validation_1.inputValidationFailure; } });
20
+ var input_lookups_1 = require("./input-lookups");
21
+ Object.defineProperty(exports, "getWorkflowInputLookups", { enumerable: true, get: function () { return input_lookups_1.getWorkflowInputLookups; } });
20
22
  var config_1 = require("./config");
21
23
  Object.defineProperty(exports, "listWorkflowConfigs", { enumerable: true, get: function () { return config_1.listWorkflowConfigs; } });
22
24
  Object.defineProperty(exports, "getWorkflowConfig", { enumerable: true, get: function () { return config_1.getWorkflowConfig; } });
@@ -0,0 +1,16 @@
1
+ import type { LTApiResult, LTApiAuth } from '../../types/sdk';
2
+ /**
3
+ * Resolve the versioned knowledge lookups pinned on a workflow config.
4
+ *
5
+ * The refs on `input_lookups` ARE the grant: any caller who may invoke the
6
+ * workflow may read exactly the pinned editions it names. A ref whose
7
+ * snapshot does not exist answers with `missing: true`; the batch never
8
+ * fails.
9
+ *
10
+ * @param input.type: workflow type name
11
+ * @param auth: authenticated caller; must pass the invoke predicate
12
+ * @returns `{ status: 200, data: { lookups: [{ domain, key, version, as?, data, missing? }] } }`
13
+ */
14
+ export declare function getWorkflowInputLookups(input: {
15
+ type: string;
16
+ }, auth: LTApiAuth): Promise<LTApiResult>;
@@ -0,0 +1,69 @@
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.getWorkflowInputLookups = getWorkflowInputLookups;
37
+ const configService = __importStar(require("../../services/config"));
38
+ const userService = __importStar(require("../../services/user"));
39
+ const invocation_access_1 = require("../../services/invocation-access");
40
+ const knowledge_1 = require("../../services/knowledge");
41
+ /**
42
+ * Resolve the versioned knowledge lookups pinned on a workflow config.
43
+ *
44
+ * The refs on `input_lookups` ARE the grant: any caller who may invoke the
45
+ * workflow may read exactly the pinned editions it names. A ref whose
46
+ * snapshot does not exist answers with `missing: true`; the batch never
47
+ * fails.
48
+ *
49
+ * @param input.type: workflow type name
50
+ * @param auth: authenticated caller; must pass the invoke predicate
51
+ * @returns `{ status: 200, data: { lookups: [{ domain, key, version, as?, data, missing? }] } }`
52
+ */
53
+ async function getWorkflowInputLookups(input, auth) {
54
+ try {
55
+ const config = await configService.getWorkflowConfig(input.type);
56
+ if (!config) {
57
+ return { status: 404, error: 'Workflow config not found' };
58
+ }
59
+ const user = auth.userId ? await userService.getUser(auth.userId) : null;
60
+ if (!(0, invocation_access_1.canInvokeWorkflow)(config, user?.roles ?? [], auth.role)) {
61
+ return { status: 403, error: 'Not authorized to invoke this workflow' };
62
+ }
63
+ const lookups = await (0, knowledge_1.resolveLookupRefs)(config.input_lookups ?? []);
64
+ return { status: 200, data: { lookups } };
65
+ }
66
+ catch (err) {
67
+ return { status: 500, error: err.message };
68
+ }
69
+ }
@@ -5,9 +5,10 @@ import type { LTApiResult } from '../../types/sdk';
5
5
  * The invoke input gate. A workflow that declares input_schema has its
6
6
  * submitted data validated by the same shared pass the dashboard form runs,
7
7
  * so a payload the form accepts is accepted here and a rejection lists the
8
- * exact violations the form would show. No schema, no gate; a data value
9
- * that is not an object is left to the service's own 400.
8
+ * exact violations the form would show. Pinned input_lookups resolve into
9
+ * the `lookup` domain first. No schema, no gate; a data value that is not
10
+ * an object is left to the service's own 400.
10
11
  */
11
- export declare function checkInvokeInput(config: Pick<LTWorkflowConfig, 'workflow_type' | 'input_schema'> | null | undefined, data: unknown, metadata: Record<string, unknown> | null | undefined): LTValidationErrorBody | null;
12
+ export declare function checkInvokeInput(config: Pick<LTWorkflowConfig, 'workflow_type' | 'input_schema' | 'input_lookups'> | null | undefined, data: unknown, metadata: Record<string, unknown> | null | undefined): Promise<LTValidationErrorBody | null>;
12
13
  /** The canonical 422 result; the route serializes `data` as the body. */
13
14
  export declare function inputValidationFailure(body: LTValidationErrorBody): LTApiResult;
@@ -4,6 +4,7 @@ exports.checkInvokeInput = checkInvokeInput;
4
4
  exports.inputValidationFailure = inputValidationFailure;
5
5
  const validate_resolver_payload_1 = require("../../shared/form-validation/validate-resolver-payload");
6
6
  const invoke_context_1 = require("../../shared/form-validation/invoke-context");
7
+ const lookup_cache_1 = require("../../services/knowledge/lookup-cache");
7
8
  const validation_1 = require("../../types/validation");
8
9
  function isPlainObject(value) {
9
10
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -12,14 +13,16 @@ function isPlainObject(value) {
12
13
  * The invoke input gate. A workflow that declares input_schema has its
13
14
  * submitted data validated by the same shared pass the dashboard form runs,
14
15
  * so a payload the form accepts is accepted here and a rejection lists the
15
- * exact violations the form would show. No schema, no gate; a data value
16
- * that is not an object is left to the service's own 400.
16
+ * exact violations the form would show. Pinned input_lookups resolve into
17
+ * the `lookup` domain first. No schema, no gate; a data value that is not
18
+ * an object is left to the service's own 400.
17
19
  */
18
- function checkInvokeInput(config, data, metadata) {
20
+ async function checkInvokeInput(config, data, metadata) {
19
21
  const schema = config?.input_schema;
20
22
  if (!schema || !isPlainObject(data))
21
23
  return null;
22
- const violations = (0, validate_resolver_payload_1.validateResolverPayload)(schema, data, (0, invoke_context_1.buildInvokeFormContext)(metadata));
24
+ const lookup = await (0, lookup_cache_1.resolveLookupContext)(config?.input_lookups);
25
+ const violations = (0, validate_resolver_payload_1.validateResolverPayload)(schema, data, (0, invoke_context_1.buildInvokeFormContext)(metadata, lookup));
23
26
  if (violations.length === 0)
24
27
  return null;
25
28
  const n = violations.length;
@@ -65,6 +65,7 @@ function durableEntry(workflowType, taskQueue) {
65
65
  envelope_schema: null,
66
66
  input_schema: null,
67
67
  icon: null,
68
+ input_lookups: null,
68
69
  resolver_schema: null,
69
70
  cron_schedule: null,
70
71
  execute_as: null,
@@ -63,7 +63,7 @@ async function invokeWorkflow(input, auth) {
63
63
  try {
64
64
  await (0, workflow_invocation_1.checkInvocationRoles)(input.type, auth.userId, auth.role);
65
65
  const config = await configService.getWorkflowConfig(input.type);
66
- const violation = (0, input_validation_1.checkInvokeInput)(config, input.data, input.metadata);
66
+ const violation = await (0, input_validation_1.checkInvokeInput)(config, input.data, input.metadata);
67
67
  if (violation)
68
68
  return (0, input_validation_1.inputValidationFailure)(violation);
69
69
  const result = await (0, workflow_invocation_1.invokeWorkflow)({
package/build/index.js CHANGED
@@ -168,6 +168,66 @@ async function main() {
168
168
  },
169
169
  },
170
170
  examples: true,
171
+ // Code-owned declaration for the reviewer queue the examples route to: a
172
+ // portal that leads with the queue's counts and lays its lists beneath.
173
+ // `reset` keeps the declaration applied on every boot.
174
+ roles: [
175
+ {
176
+ role: 'reviewer',
177
+ title: 'Reviewer',
178
+ reset: true,
179
+ portals: [
180
+ {
181
+ key: 'review-desk',
182
+ label: 'Review desk',
183
+ counts: [
184
+ { label: 'Waiting', url: '/escalations/available?role=reviewer', blurb: 'Unclaimed items in the queue' },
185
+ { label: 'In progress', url: '/escalations/available?role=reviewer&status=claimed', blurb: 'Claimed and being worked' },
186
+ { label: 'Resolved', url: '/escalations/available?role=reviewer&status=resolved', blurb: 'Closed out by a reviewer' },
187
+ { label: 'Expired', url: '/escalations/available?role=reviewer&status=expired', blurb: 'Timed out before anyone acted' },
188
+ { label: 'Cancelled', url: '/escalations/available?role=reviewer&status=cancelled', blurb: 'Withdrawn by the workflow' },
189
+ ],
190
+ rows: [
191
+ [
192
+ { label: 'Waiting', url: '/escalations/available?role=reviewer&view=table&layout=compact', badge: true },
193
+ { label: 'In progress', url: '/escalations/available?role=reviewer&status=claimed&view=table&layout=compact', badge: true },
194
+ ],
195
+ ],
196
+ },
197
+ ],
198
+ },
199
+ {
200
+ // The rollup-bin example's container queue: the list shows each
201
+ // bin's fill level from the accumulator facets.
202
+ role: 'bin',
203
+ title: 'Bin',
204
+ description: 'Open containers filling with scanned bags. Ships at max or when the window closes.',
205
+ reset: true,
206
+ list_schema: {
207
+ 'x-lt-layout': 'facet-table',
208
+ 'x-lt-columns': [
209
+ { label: 'Bin', value: '{{metadata.binKey}}' },
210
+ { label: 'Held', value: '{{metadata.accumulate_count}}' },
211
+ { label: 'Max', value: '{{metadata.accumulate_max}}', priority: 2 },
212
+ { label: 'Open since', value: '{{escalation.created_at}}', format: 'age', priority: 2 },
213
+ ],
214
+ },
215
+ },
216
+ {
217
+ role: 'bag',
218
+ title: 'Bag',
219
+ description: 'Bags waiting to be scanned into a bin.',
220
+ reset: true,
221
+ list_schema: {
222
+ 'x-lt-layout': 'facet-table',
223
+ 'x-lt-columns': [
224
+ { label: 'Order', value: '{{metadata.orderId}}' },
225
+ { label: 'Bin', value: '{{metadata.binKey}}', priority: 2 },
226
+ { label: 'Waiting', value: '{{escalation.created_at}}', format: 'age', priority: 2 },
227
+ ],
228
+ },
229
+ },
230
+ ],
171
231
  features: {
172
232
  // The examples ship the full scan demo (schemes 10/11); surface it.
173
233
  scanCodes: true,
@@ -0,0 +1,9 @@
1
+ -- Migration 035: workflow input lookups
2
+ --
3
+ -- One opt-in column on the workflow registration:
4
+ -- input_lookups: versioned knowledge refs ({ domain, key, version, as? }[])
5
+ -- the invoke form reads under the `lookup.<as ?? key>`
6
+ -- context domain. NULL renders the form with no lookups.
7
+
8
+ ALTER TABLE lt_config_workflows
9
+ ADD COLUMN IF NOT EXISTS input_lookups JSONB;
@@ -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;