@hotmeshio/long-tail 0.24.1 → 0.25.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 (294) hide show
  1. package/build/api/escalations/accumulate.js +8 -4
  2. package/build/api/escalations/metadata.js +4 -3
  3. package/build/api/escalations/related.d.ts +1 -1
  4. package/build/api/escalations/related.js +28 -18
  5. package/build/lib/db/schemas/040_oauth_client_consent.sql +15 -0
  6. package/build/modules/config.d.ts +4 -0
  7. package/build/modules/config.js +4 -0
  8. package/build/modules/maintenance.d.ts +1 -1
  9. package/build/modules/maintenance.js +1 -1
  10. package/build/services/auth/oauth-server/index.d.ts +1 -1
  11. package/build/services/auth/oauth-server/index.js +2 -1
  12. package/build/services/auth/oauth-server/sql.d.ts +7 -4
  13. package/build/services/auth/oauth-server/sql.js +10 -4
  14. package/build/services/auth/oauth-server/store.d.ts +8 -1
  15. package/build/services/auth/oauth-server/store.js +31 -2
  16. package/build/services/escalation/accumulate.d.ts +3 -1
  17. package/build/services/escalation/facet-sql.js +4 -2
  18. package/build/services/escalation/index.d.ts +1 -0
  19. package/build/services/escalation/index.js +4 -1
  20. package/build/services/escalation/related-extremes.d.ts +17 -0
  21. package/build/services/escalation/related-extremes.js +65 -0
  22. package/build/services/escalation/related.d.ts +4 -0
  23. package/build/services/escalation/related.js +2 -0
  24. package/build/services/escalation/resolver-validation.js +7 -0
  25. package/build/services/escalation/roster.d.ts +13 -0
  26. package/build/services/escalation/roster.js +37 -0
  27. package/build/services/escalation/submit-guard.d.ts +3 -0
  28. package/build/services/escalation/submit-guard.js +21 -2
  29. package/build/services/maintenance/index.js +1 -1
  30. package/build/services/mcp/server-tools.js +1 -1
  31. package/build/shared/form-validation/display-only-widgets.d.ts +1 -0
  32. package/build/shared/form-validation/display-only-widgets.js +1 -0
  33. package/build/shared/form-validation/index.d.ts +1 -0
  34. package/build/shared/form-validation/index.js +1 -0
  35. package/build/shared/form-validation/validate-resolver-payload.d.ts +1 -0
  36. package/build/shared/form-validation/validate-resolver-payload.js +2 -1
  37. package/build/shared/form-validation/x-lt-help.d.ts +1 -1
  38. package/build/shared/form-validation/x-lt-help.js +2 -1
  39. package/build/shared/form-validation/x-lt-roster.d.ts +92 -0
  40. package/build/shared/form-validation/x-lt-roster.js +234 -0
  41. package/build/shared/form-validation/x-lt-show-if.d.ts +8 -0
  42. package/build/shared/form-validation/x-lt-show-if.js +13 -0
  43. package/build/shared/form-validation/x-lt-submit-guard.d.ts +14 -1
  44. package/build/shared/form-validation/x-lt-submit-guard.js +4 -1
  45. package/build/shared/list-schema/aggregate.d.ts +19 -0
  46. package/build/shared/list-schema/aggregate.js +66 -0
  47. package/build/shared/list-schema/index.d.ts +2 -0
  48. package/build/shared/list-schema/index.js +7 -1
  49. package/build/shared/list-schema/types.d.ts +15 -2
  50. package/build/shared/list-schema/types.js +6 -1
  51. package/build/shared/list-schema/validate.js +28 -2
  52. package/build/tsconfig.tsbuildinfo +1 -1
  53. package/dashboard/dist/assets/{AdminDashboard-B3mkMIOT.js → AdminDashboard-DWVRAu63.js} +2 -2
  54. package/dashboard/dist/assets/{AdminDashboard-B3mkMIOT.js.map → AdminDashboard-DWVRAu63.js.map} +1 -1
  55. package/dashboard/dist/assets/{AgentConfigPage-CQj2B678.js → AgentConfigPage-Exjtjbvp.js} +6 -6
  56. package/dashboard/dist/assets/{AgentConfigPage-CQj2B678.js.map → AgentConfigPage-Exjtjbvp.js.map} +1 -1
  57. package/dashboard/dist/assets/{AgentDetailPage-CzrD8JJI.js → AgentDetailPage-nDbZo6RB.js} +3 -3
  58. package/dashboard/dist/assets/{AgentDetailPage-CzrD8JJI.js.map → AgentDetailPage-nDbZo6RB.js.map} +1 -1
  59. package/dashboard/dist/assets/{AgentsPage-jg2OFwyW.js → AgentsPage-Dsk9iHps.js} +2 -2
  60. package/dashboard/dist/assets/{AgentsPage-jg2OFwyW.js.map → AgentsPage-Dsk9iHps.js.map} +1 -1
  61. package/dashboard/dist/assets/AvailableEscalationsPage-D1mCqj8Z.js +2 -0
  62. package/dashboard/dist/assets/{AvailableEscalationsPage-IS28XBRe.js.map → AvailableEscalationsPage-D1mCqj8Z.js.map} +1 -1
  63. package/dashboard/dist/assets/{BotPicker-DvEJFpwS.js → BotPicker-u5760MWZ.js} +2 -2
  64. package/dashboard/dist/assets/{BotPicker-DvEJFpwS.js.map → BotPicker-u5760MWZ.js.map} +1 -1
  65. package/dashboard/dist/assets/{BulkAssignModal-BoQCi-YC.js → BulkAssignModal-CtISXXmW.js} +2 -2
  66. package/dashboard/dist/assets/{BulkAssignModal-BoQCi-YC.js.map → BulkAssignModal-CtISXXmW.js.map} +1 -1
  67. package/dashboard/dist/assets/{CapabilitiesPage-kwlrcb_t.js → CapabilitiesPage-BKIlrQfU.js} +2 -2
  68. package/dashboard/dist/assets/{CapabilitiesPage-kwlrcb_t.js.map → CapabilitiesPage-BKIlrQfU.js.map} +1 -1
  69. package/dashboard/dist/assets/{CollapsibleSection-UMIV4KIj.js → CollapsibleSection-DlBVTFqc.js} +2 -2
  70. package/dashboard/dist/assets/{CollapsibleSection-UMIV4KIj.js.map → CollapsibleSection-DlBVTFqc.js.map} +1 -1
  71. package/dashboard/dist/assets/{ConfirmDeleteModal-C5puwMg7.js → ConfirmDeleteModal-Pabkchg_.js} +2 -2
  72. package/dashboard/dist/assets/{ConfirmDeleteModal-C5puwMg7.js.map → ConfirmDeleteModal-Pabkchg_.js.map} +1 -1
  73. package/dashboard/dist/assets/{ConnectedAppsPage-drZa65kP.js → ConnectedAppsPage-DG2YZGN3.js} +2 -2
  74. package/dashboard/dist/assets/{ConnectedAppsPage-drZa65kP.js.map → ConnectedAppsPage-DG2YZGN3.js.map} +1 -1
  75. package/dashboard/dist/assets/CountdownTimer-5t8S2qMi.js +2 -0
  76. package/dashboard/dist/assets/CountdownTimer-5t8S2qMi.js.map +1 -0
  77. package/dashboard/dist/assets/{CredentialsPage-CaFQ6vLb.js → CredentialsPage-CPVbYQow.js} +2 -2
  78. package/dashboard/dist/assets/{CredentialsPage-CaFQ6vLb.js.map → CredentialsPage-CPVbYQow.js.map} +1 -1
  79. package/dashboard/dist/assets/{CronLabel-Co5j7tzW.js → CronLabel-C7UbTrO-.js} +2 -2
  80. package/dashboard/dist/assets/{CronLabel-Co5j7tzW.js.map → CronLabel-C7UbTrO-.js.map} +1 -1
  81. package/dashboard/dist/assets/{DropZone-B1Tdfddc.js → DropZone-DCZpORx-.js} +2 -2
  82. package/dashboard/dist/assets/{DropZone-B1Tdfddc.js.map → DropZone-DCZpORx-.js.map} +1 -1
  83. package/dashboard/dist/assets/{ElapsedCell-WJyE9G0T.js → ElapsedCell-Yz7-LbtE.js} +2 -2
  84. package/dashboard/dist/assets/{ElapsedCell-WJyE9G0T.js.map → ElapsedCell-Yz7-LbtE.js.map} +1 -1
  85. package/dashboard/dist/assets/{EntityTimelinePanel-CDFFfX9d.js → EntityTimelinePanel-xgPRdKEq.js} +2 -2
  86. package/dashboard/dist/assets/{EntityTimelinePanel-CDFFfX9d.js.map → EntityTimelinePanel-xgPRdKEq.js.map} +1 -1
  87. package/dashboard/dist/assets/{EscalationListSchemaPage-CMrUlaKI.js → EscalationListSchemaPage-CqCd-y6B.js} +3 -3
  88. package/dashboard/dist/assets/{EscalationListSchemaPage-CMrUlaKI.js.map → EscalationListSchemaPage-CqCd-y6B.js.map} +1 -1
  89. package/dashboard/dist/assets/{EscalationSchemaPage-Dx2Lyfrz.js → EscalationSchemaPage-D8YVQNph.js} +3 -3
  90. package/dashboard/dist/assets/{EscalationSchemaPage-Dx2Lyfrz.js.map → EscalationSchemaPage-D8YVQNph.js.map} +1 -1
  91. package/dashboard/dist/assets/EscalationTimeline-D6jrDcBb.js +2 -0
  92. package/dashboard/dist/assets/{EscalationTimeline-d3nvshOk.js.map → EscalationTimeline-D6jrDcBb.js.map} +1 -1
  93. package/dashboard/dist/assets/{EscalationTitleSelect-DWQieOM9.js → EscalationTitleSelect-CGGT-QTu.js} +2 -2
  94. package/dashboard/dist/assets/{EscalationTitleSelect-DWQieOM9.js.map → EscalationTitleSelect-CGGT-QTu.js.map} +1 -1
  95. package/dashboard/dist/assets/{EscalationsOverview-BX8Cpi0X.js → EscalationsOverview-B7O4ttP4.js} +2 -2
  96. package/dashboard/dist/assets/{EscalationsOverview-BX8Cpi0X.js.map → EscalationsOverview-B7O4ttP4.js.map} +1 -1
  97. package/dashboard/dist/assets/{EventTable-D1-ITVXS.js → EventTable-DJniXnhe.js} +2 -2
  98. package/dashboard/dist/assets/{EventTable-D1-ITVXS.js.map → EventTable-DJniXnhe.js.map} +1 -1
  99. package/dashboard/dist/assets/{FilterBar-ABC9ctin.js → FilterBar-f-LEKcHI.js} +2 -2
  100. package/dashboard/dist/assets/{FilterBar-ABC9ctin.js.map → FilterBar-f-LEKcHI.js.map} +1 -1
  101. package/dashboard/dist/assets/{FormattedValue-k27T4bG7.js → FormattedValue-CUtv1g3k.js} +2 -2
  102. package/dashboard/dist/assets/{FormattedValue-k27T4bG7.js.map → FormattedValue-CUtv1g3k.js.map} +1 -1
  103. package/dashboard/dist/assets/{GraphInvokePage-DKUErxWc.js → GraphInvokePage-CR0MtYv8.js} +2 -2
  104. package/dashboard/dist/assets/{GraphInvokePage-DKUErxWc.js.map → GraphInvokePage-CR0MtYv8.js.map} +1 -1
  105. package/dashboard/dist/assets/{HomePage-C6u9dIpR.js → HomePage-HVw7T5ER.js} +2 -2
  106. package/dashboard/dist/assets/{HomePage-C6u9dIpR.js.map → HomePage-HVw7T5ER.js.map} +1 -1
  107. package/dashboard/dist/assets/{ListToolbar-gA5rFzkz.js → ListToolbar-CTGK5BXW.js} +2 -2
  108. package/dashboard/dist/assets/{ListToolbar-gA5rFzkz.js.map → ListToolbar-CTGK5BXW.js.map} +1 -1
  109. package/dashboard/dist/assets/{McpOverview-BOPo3J_i.js → McpOverview-B2bbKKu2.js} +2 -2
  110. package/dashboard/dist/assets/{McpOverview-BOPo3J_i.js.map → McpOverview-B2bbKKu2.js.map} +1 -1
  111. package/dashboard/dist/assets/{McpQueryDetailPage-BRVVi0Zh.js → McpQueryDetailPage-DgLxwwJy.js} +2 -2
  112. package/dashboard/dist/assets/{McpQueryDetailPage-BRVVi0Zh.js.map → McpQueryDetailPage-DgLxwwJy.js.map} +1 -1
  113. package/dashboard/dist/assets/{McpQueryPage-Dmbb6SAc.js → McpQueryPage-CSkczeJP.js} +2 -2
  114. package/dashboard/dist/assets/{McpQueryPage-Dmbb6SAc.js.map → McpQueryPage-CSkczeJP.js.map} +1 -1
  115. package/dashboard/dist/assets/McpRunDetailPage-CrUsDPRD.js +2 -0
  116. package/dashboard/dist/assets/{McpRunDetailPage-bMXNO-6V.js.map → McpRunDetailPage-CrUsDPRD.js.map} +1 -1
  117. package/dashboard/dist/assets/{McpRunsPage-Bi9AMWja.js → McpRunsPage-twxFdTtJ.js} +2 -2
  118. package/dashboard/dist/assets/{McpRunsPage-Bi9AMWja.js.map → McpRunsPage-twxFdTtJ.js.map} +1 -1
  119. package/dashboard/dist/assets/{NamespacePill-DwM5pNA4.js → NamespacePill-CSZT2fA4.js} +2 -2
  120. package/dashboard/dist/assets/{NamespacePill-DwM5pNA4.js.map → NamespacePill-CSZT2fA4.js.map} +1 -1
  121. package/dashboard/dist/assets/{OperationsPage-CvR74ZUJ.js → OperationsPage-gOVMrL_a.js} +3 -3
  122. package/dashboard/dist/assets/{OperationsPage-CvR74ZUJ.js.map → OperationsPage-gOVMrL_a.js.map} +1 -1
  123. package/dashboard/dist/assets/OperatorDashboard-BoeZIyup.js +2 -0
  124. package/dashboard/dist/assets/{OperatorDashboard-DctmZw10.js.map → OperatorDashboard-BoeZIyup.js.map} +1 -1
  125. package/dashboard/dist/assets/{PageHeader-CMd3f4bz.js → PageHeader-C4z1ExF7.js} +2 -2
  126. package/dashboard/dist/assets/{PageHeader-CMd3f4bz.js.map → PageHeader-C4z1ExF7.js.map} +1 -1
  127. package/dashboard/dist/assets/{PageHeaderWithStats-DHj8Mqox.js → PageHeaderWithStats-B_f_Sz_Q.js} +2 -2
  128. package/dashboard/dist/assets/{PageHeaderWithStats-DHj8Mqox.js.map → PageHeaderWithStats-B_f_Sz_Q.js.map} +1 -1
  129. package/dashboard/dist/assets/{PersonaDetailPage-Ubqm2rQH.js → PersonaDetailPage-CDktk1mi.js} +2 -2
  130. package/dashboard/dist/assets/{PersonaDetailPage-Ubqm2rQH.js.map → PersonaDetailPage-CDktk1mi.js.map} +1 -1
  131. package/dashboard/dist/assets/{PersonasPage-BpFL2rpo.js → PersonasPage-Bs097x07.js} +2 -2
  132. package/dashboard/dist/assets/{PersonasPage-BpFL2rpo.js.map → PersonasPage-Bs097x07.js.map} +1 -1
  133. package/dashboard/dist/assets/PortalPage-DjfjerpF.js +2 -0
  134. package/dashboard/dist/assets/{PortalPage-Dfc_Q02R.js.map → PortalPage-DjfjerpF.js.map} +1 -1
  135. package/dashboard/dist/assets/{ProcessDetailPage-liJspvQh.js → ProcessDetailPage-B30RatjD.js} +2 -2
  136. package/dashboard/dist/assets/{ProcessDetailPage-liJspvQh.js.map → ProcessDetailPage-B30RatjD.js.map} +1 -1
  137. package/dashboard/dist/assets/{ProcessesListPage-C3OM5ZUy.js → ProcessesListPage-DrvjzgWT.js} +2 -2
  138. package/dashboard/dist/assets/{ProcessesListPage-C3OM5ZUy.js.map → ProcessesListPage-DrvjzgWT.js.map} +1 -1
  139. package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js +8 -0
  140. package/dashboard/dist/assets/ResolverForm-Bl8Pibyz.js.map +1 -0
  141. package/dashboard/dist/assets/{RoleDetailPage-CrlYCh-R.js → RoleDetailPage-ClYgn-3d.js} +3 -3
  142. package/dashboard/dist/assets/{RoleDetailPage-CrlYCh-R.js.map → RoleDetailPage-ClYgn-3d.js.map} +1 -1
  143. package/dashboard/dist/assets/{RolePill-Di2CAHuD.js → RolePill-Bw_n7EpR.js} +2 -2
  144. package/dashboard/dist/assets/{RolePill-Di2CAHuD.js.map → RolePill-Bw_n7EpR.js.map} +1 -1
  145. package/dashboard/dist/assets/{RolesPage-BaazL_pt.js → RolesPage-B_3qWsvQ.js} +2 -2
  146. package/dashboard/dist/assets/{RolesPage-BaazL_pt.js.map → RolesPage-B_3qWsvQ.js.map} +1 -1
  147. package/dashboard/dist/assets/{RunAsSelector-DxuV0fa1.js → RunAsSelector-CbJT50Hp.js} +2 -2
  148. package/dashboard/dist/assets/{RunAsSelector-DxuV0fa1.js.map → RunAsSelector-CbJT50Hp.js.map} +1 -1
  149. package/dashboard/dist/assets/{ScanCodesPage-C0mvmYTq.js → ScanCodesPage-CIIDuh8w.js} +2 -2
  150. package/dashboard/dist/assets/{ScanCodesPage-C0mvmYTq.js.map → ScanCodesPage-CIIDuh8w.js.map} +1 -1
  151. package/dashboard/dist/assets/{ScanSchemeDetailPage-CiJgt5dZ.js → ScanSchemeDetailPage-Bd3P3eyh.js} +2 -2
  152. package/dashboard/dist/assets/{ScanSchemeDetailPage-CiJgt5dZ.js.map → ScanSchemeDetailPage-Bd3P3eyh.js.map} +1 -1
  153. package/dashboard/dist/assets/ScanStationPage-BiO34nov.js +2 -0
  154. package/dashboard/dist/assets/ScanStationPage-BiO34nov.js.map +1 -0
  155. package/dashboard/dist/assets/{ScopeBadge-CSItPVOH.js → ScopeBadge-CKgfwTy3.js} +2 -2
  156. package/dashboard/dist/assets/{ScopeBadge-CSItPVOH.js.map → ScopeBadge-CKgfwTy3.js.map} +1 -1
  157. package/dashboard/dist/assets/{StickyPagination-CqbjVY6T.js → StickyPagination-BNOuYZ1m.js} +2 -2
  158. package/dashboard/dist/assets/{StickyPagination-CqbjVY6T.js.map → StickyPagination-BNOuYZ1m.js.map} +1 -1
  159. package/dashboard/dist/assets/{StreamMessageDetail-wX3i0aqs.js → StreamMessageDetail-ALVUnfF1.js} +2 -2
  160. package/dashboard/dist/assets/{StreamMessageDetail-wX3i0aqs.js.map → StreamMessageDetail-ALVUnfF1.js.map} +1 -1
  161. package/dashboard/dist/assets/{SwimlaneTimeline-C50PsFoV.js → SwimlaneTimeline-B5b8-xqI.js} +2 -2
  162. package/dashboard/dist/assets/{SwimlaneTimeline-C50PsFoV.js.map → SwimlaneTimeline-B5b8-xqI.js.map} +1 -1
  163. package/dashboard/dist/assets/{TagInput-CAgdLN_b.js → TagInput-B6fMAqxd.js} +2 -2
  164. package/dashboard/dist/assets/{TagInput-CAgdLN_b.js.map → TagInput-B6fMAqxd.js.map} +1 -1
  165. package/dashboard/dist/assets/{TaskDetailPage-bbNSv4Ae.js → TaskDetailPage-CoV3WcTA.js} +2 -2
  166. package/dashboard/dist/assets/{TaskDetailPage-bbNSv4Ae.js.map → TaskDetailPage-CoV3WcTA.js.map} +1 -1
  167. package/dashboard/dist/assets/{TaskQueuePill-h0oorVMe.js → TaskQueuePill-BnDp_DE6.js} +2 -2
  168. package/dashboard/dist/assets/{TaskQueuePill-h0oorVMe.js.map → TaskQueuePill-BnDp_DE6.js.map} +1 -1
  169. package/dashboard/dist/assets/{TasksListPage-CDWnm_d9.js → TasksListPage-CkMmOYOE.js} +2 -2
  170. package/dashboard/dist/assets/{TasksListPage-CDWnm_d9.js.map → TasksListPage-CkMmOYOE.js.map} +1 -1
  171. package/dashboard/dist/assets/{TimeAgo-BLjqlfoX.js → TimeAgo-DVkFgECX.js} +2 -2
  172. package/dashboard/dist/assets/{TimeAgo-BLjqlfoX.js.map → TimeAgo-DVkFgECX.js.map} +1 -1
  173. package/dashboard/dist/assets/{TimestampCell-CnW0ENb5.js → TimestampCell-CfTc6Txy.js} +2 -2
  174. package/dashboard/dist/assets/{TimestampCell-CnW0ENb5.js.map → TimestampCell-CfTc6Txy.js.map} +1 -1
  175. package/dashboard/dist/assets/{ToolPill-CQCsVdzD.js → ToolPill-BRZWo4l8.js} +2 -2
  176. package/dashboard/dist/assets/{ToolPill-CQCsVdzD.js.map → ToolPill-BRZWo4l8.js.map} +1 -1
  177. package/dashboard/dist/assets/{ToolTestPanel-DkMgCB-k.js → ToolTestPanel-kvqZqM0A.js} +2 -2
  178. package/dashboard/dist/assets/{ToolTestPanel-DkMgCB-k.js.map → ToolTestPanel-kvqZqM0A.js.map} +1 -1
  179. package/dashboard/dist/assets/{TopicDetailPage-g3pljKKX.js → TopicDetailPage-CjkAAyy8.js} +4 -4
  180. package/dashboard/dist/assets/{TopicDetailPage-g3pljKKX.js.map → TopicDetailPage-CjkAAyy8.js.map} +1 -1
  181. package/dashboard/dist/assets/{TopicsPage-CVcCYdy-.js → TopicsPage-CJZnv50y.js} +2 -2
  182. package/dashboard/dist/assets/{TopicsPage-CVcCYdy-.js.map → TopicsPage-CJZnv50y.js.map} +1 -1
  183. package/dashboard/dist/assets/{UserName-D6zGIK2i.js → UserName-CPJPZnN1.js} +2 -2
  184. package/dashboard/dist/assets/{UserName-D6zGIK2i.js.map → UserName-CPJPZnN1.js.map} +1 -1
  185. package/dashboard/dist/assets/WorkflowExecutionPage-46UV5pJd.js +2 -0
  186. package/dashboard/dist/assets/{WorkflowExecutionPage-B8g81FCJ.js.map → WorkflowExecutionPage-46UV5pJd.js.map} +1 -1
  187. package/dashboard/dist/assets/{WorkflowPill-Dg7BDTyM.js → WorkflowPill-Cly9Ln_3.js} +2 -2
  188. package/dashboard/dist/assets/{WorkflowPill-Dg7BDTyM.js.map → WorkflowPill-Cly9Ln_3.js.map} +1 -1
  189. package/dashboard/dist/assets/{WorkflowsDashboard-nxT3bv6W.js → WorkflowsDashboard-DtxYdQbQ.js} +2 -2
  190. package/dashboard/dist/assets/{WorkflowsDashboard-nxT3bv6W.js.map → WorkflowsDashboard-DtxYdQbQ.js.map} +1 -1
  191. package/dashboard/dist/assets/{WorkflowsOverview-grI-KAI2.js → WorkflowsOverview-Cg4LSfck.js} +2 -2
  192. package/dashboard/dist/assets/{WorkflowsOverview-grI-KAI2.js.map → WorkflowsOverview-Cg4LSfck.js.map} +1 -1
  193. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BoZ-hfBE.js → YamlWorkflowDetailPage-Del-RCgi.js} +12 -12
  194. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BoZ-hfBE.js.map → YamlWorkflowDetailPage-Del-RCgi.js.map} +1 -1
  195. package/dashboard/dist/assets/{YamlWorkflowsPage-Bf04rwRv.js → YamlWorkflowsPage-BF6Jtx24.js} +2 -2
  196. package/dashboard/dist/assets/{YamlWorkflowsPage-Bf04rwRv.js.map → YamlWorkflowsPage-BF6Jtx24.js.map} +1 -1
  197. package/dashboard/dist/assets/{agents-Dphpdi8l.js → agents-wL-3dMOX.js} +2 -2
  198. package/dashboard/dist/assets/{agents-Dphpdi8l.js.map → agents-wL-3dMOX.js.map} +1 -1
  199. package/dashboard/dist/assets/{bots-DIFE298x.js → bots-D72EsztP.js} +2 -2
  200. package/dashboard/dist/assets/{bots-DIFE298x.js.map → bots-D72EsztP.js.map} +1 -1
  201. package/dashboard/dist/assets/{capabilities-D7Y7LClY.js → capabilities-DXFo6bRb.js} +2 -2
  202. package/dashboard/dist/assets/{capabilities-D7Y7LClY.js.map → capabilities-DXFo6bRb.js.map} +1 -1
  203. package/dashboard/dist/assets/{controlplane-D1TGcYsS.js → controlplane-gQdOgVtH.js} +2 -2
  204. package/dashboard/dist/assets/{controlplane-D1TGcYsS.js.map → controlplane-gQdOgVtH.js.map} +1 -1
  205. package/dashboard/dist/assets/escalation-columns-CSE5wfWQ.js +2 -0
  206. package/dashboard/dist/assets/escalation-columns-CSE5wfWQ.js.map +1 -0
  207. package/dashboard/dist/assets/escalation-items-BIgBWbaw.js +2 -0
  208. package/dashboard/dist/assets/escalation-items-BIgBWbaw.js.map +1 -0
  209. package/dashboard/dist/assets/{index-CeCtqujG.js → index-BaCDL5fh.js} +38 -38
  210. package/dashboard/dist/assets/index-BaCDL5fh.js.map +1 -0
  211. package/dashboard/dist/assets/{index-Dl_8hbYI.js → index-Btm8FtTQ.js} +2 -2
  212. package/dashboard/dist/assets/{index-Dl_8hbYI.js.map → index-Btm8FtTQ.js.map} +1 -1
  213. package/dashboard/dist/assets/index-BvH8T-jb.js +2 -0
  214. package/dashboard/dist/assets/{index-CxdjT1Yk.js.map → index-BvH8T-jb.js.map} +1 -1
  215. package/dashboard/dist/assets/{index-HLu98Sqh.js → index-C-QQ5rKF.js} +2 -2
  216. package/dashboard/dist/assets/{index-HLu98Sqh.js.map → index-C-QQ5rKF.js.map} +1 -1
  217. package/dashboard/dist/assets/{index-DpKOr311.js → index-C1iuZ4Q5.js} +2 -2
  218. package/dashboard/dist/assets/{index-DpKOr311.js.map → index-C1iuZ4Q5.js.map} +1 -1
  219. package/dashboard/dist/assets/{index-ChV7pBjM.js → index-CDxOQ84B.js} +2 -2
  220. package/dashboard/dist/assets/{index-ChV7pBjM.js.map → index-CDxOQ84B.js.map} +1 -1
  221. package/dashboard/dist/assets/index-CED9cLE2.js +3 -0
  222. package/dashboard/dist/assets/index-CED9cLE2.js.map +1 -0
  223. package/dashboard/dist/assets/index-CnU7Jjz3.css +1 -0
  224. package/dashboard/dist/assets/{index-DAvi5_2T.js → index-CptTEhWp.js} +2 -2
  225. package/dashboard/dist/assets/{index-DAvi5_2T.js.map → index-CptTEhWp.js.map} +1 -1
  226. package/dashboard/dist/assets/{index-ag2pCAPu.js → index-Cu0xdX2t.js} +2 -2
  227. package/dashboard/dist/assets/{index-ag2pCAPu.js.map → index-Cu0xdX2t.js.map} +1 -1
  228. package/dashboard/dist/assets/index-D1lfq5iZ.js +13 -0
  229. package/dashboard/dist/assets/{index-gkxPN7Vx.js.map → index-D1lfq5iZ.js.map} +1 -1
  230. package/dashboard/dist/assets/{index-Dy1wWu2e.js → index-czgLyfSo.js} +2 -2
  231. package/dashboard/dist/assets/{index-Dy1wWu2e.js.map → index-czgLyfSo.js.map} +1 -1
  232. package/dashboard/dist/assets/{index-DN-kX7hL.js → index-h1Useskt.js} +2 -2
  233. package/dashboard/dist/assets/{index-DN-kX7hL.js.map → index-h1Useskt.js.map} +1 -1
  234. package/dashboard/dist/assets/{index-BzYcUPdD.js → index-ujGmmwl6.js} +2 -2
  235. package/dashboard/dist/assets/{index-BzYcUPdD.js.map → index-ujGmmwl6.js.map} +1 -1
  236. package/dashboard/dist/assets/{knowledge-DnMs-SOJ.js → knowledge-150lsM68.js} +2 -2
  237. package/dashboard/dist/assets/{knowledge-DnMs-SOJ.js.map → knowledge-150lsM68.js.map} +1 -1
  238. package/dashboard/dist/assets/{mcp-CwW-K3r4.js → mcp-CRtY4v5W.js} +2 -2
  239. package/dashboard/dist/assets/{mcp-CwW-K3r4.js.map → mcp-CRtY4v5W.js.map} +1 -1
  240. package/dashboard/dist/assets/{mcp-query-BZt5e8_Q.js → mcp-query-CDsSMaYq.js} +2 -2
  241. package/dashboard/dist/assets/{mcp-query-BZt5e8_Q.js.map → mcp-query-CDsSMaYq.js.map} +1 -1
  242. package/dashboard/dist/assets/{personas-UA-Xn60f.js → personas-C2Wm4ng1.js} +2 -2
  243. package/dashboard/dist/assets/{personas-UA-Xn60f.js.map → personas-C2Wm4ng1.js.map} +1 -1
  244. package/dashboard/dist/assets/{pipelines-Cu3PARum.js → pipelines-BH0F9-jf.js} +2 -2
  245. package/dashboard/dist/assets/{pipelines-Cu3PARum.js.map → pipelines-BH0F9-jf.js.map} +1 -1
  246. package/dashboard/dist/assets/{tasks-BO6h8GJE.js → tasks-BkUVpaOa.js} +2 -2
  247. package/dashboard/dist/assets/{tasks-BO6h8GJE.js.map → tasks-BkUVpaOa.js.map} +1 -1
  248. package/dashboard/dist/assets/{topics-CWjCR-17.js → topics-Crl8HKHq.js} +2 -2
  249. package/dashboard/dist/assets/{topics-CWjCR-17.js.map → topics-Crl8HKHq.js.map} +1 -1
  250. package/dashboard/dist/assets/{useDebouncedValue-6t0jx1RB.js → useDebouncedValue-Dk3r5xo-.js} +2 -2
  251. package/dashboard/dist/assets/{useDebouncedValue-6t0jx1RB.js.map → useDebouncedValue-Dk3r5xo-.js.map} +1 -1
  252. package/dashboard/dist/assets/{useNamespace-CqpoQx6D.js → useNamespace-BXuyHKAs.js} +2 -2
  253. package/dashboard/dist/assets/{useNamespace-CqpoQx6D.js.map → useNamespace-BXuyHKAs.js.map} +1 -1
  254. package/dashboard/dist/assets/{useYamlActivityEvents-hmCQQwzB.js → useYamlActivityEvents-DSlkjQfb.js} +2 -2
  255. package/dashboard/dist/assets/{useYamlActivityEvents-hmCQQwzB.js.map → useYamlActivityEvents-DSlkjQfb.js.map} +1 -1
  256. package/dashboard/dist/assets/{vendor-icons-CeVtUKyP.js → vendor-icons-C_DQEeBy.js} +2 -2
  257. package/dashboard/dist/assets/{vendor-icons-CeVtUKyP.js.map → vendor-icons-C_DQEeBy.js.map} +1 -1
  258. package/dashboard/dist/assets/{yaml-workflows-ziUdZhKY.js → yaml-workflows-B230v5Za.js} +2 -2
  259. package/dashboard/dist/assets/{yaml-workflows-ziUdZhKY.js.map → yaml-workflows-B230v5Za.js.map} +1 -1
  260. package/dashboard/dist/index.html +3 -3
  261. package/docs/faceted-routing.md +14 -1
  262. package/docs/hitl/x-lt-embed.md +4 -1
  263. package/docs/hitl/x-lt-list-schema.md +19 -2
  264. package/docs/hitl/x-lt-roster.md +112 -0
  265. package/docs/hitl/x-lt-show-if.md +15 -0
  266. package/docs/hitl/x-lt-widget.md +1 -0
  267. package/docs/hitl-guide.md +3 -1
  268. package/docs/maintenance.md +3 -3
  269. package/docs/mcp.md +2 -0
  270. package/docs/scan-codes.md +4 -0
  271. package/docs/schema-enforcement.md +5 -0
  272. package/package.json +2 -2
  273. package/dashboard/dist/assets/AvailableEscalationsPage-IS28XBRe.js +0 -2
  274. package/dashboard/dist/assets/CountdownTimer-LG03dVgR.js +0 -2
  275. package/dashboard/dist/assets/CountdownTimer-LG03dVgR.js.map +0 -1
  276. package/dashboard/dist/assets/EscalationTimeline-d3nvshOk.js +0 -2
  277. package/dashboard/dist/assets/McpRunDetailPage-bMXNO-6V.js +0 -2
  278. package/dashboard/dist/assets/OperatorDashboard-DctmZw10.js +0 -2
  279. package/dashboard/dist/assets/PortalPage-Dfc_Q02R.js +0 -2
  280. package/dashboard/dist/assets/ResolverForm-B1_x8Blv.js +0 -8
  281. package/dashboard/dist/assets/ResolverForm-B1_x8Blv.js.map +0 -1
  282. package/dashboard/dist/assets/ScanStationPage-DzGaXc40.js +0 -2
  283. package/dashboard/dist/assets/ScanStationPage-DzGaXc40.js.map +0 -1
  284. package/dashboard/dist/assets/WorkflowExecutionPage-B8g81FCJ.js +0 -2
  285. package/dashboard/dist/assets/escalation-columns-cwZE6xyo.js +0 -2
  286. package/dashboard/dist/assets/escalation-columns-cwZE6xyo.js.map +0 -1
  287. package/dashboard/dist/assets/index-CeCtqujG.js.map +0 -1
  288. package/dashboard/dist/assets/index-CniRa65p.js +0 -3
  289. package/dashboard/dist/assets/index-CniRa65p.js.map +0 -1
  290. package/dashboard/dist/assets/index-CxdjT1Yk.js +0 -2
  291. package/dashboard/dist/assets/index-gkxPN7Vx.js +0 -13
  292. package/dashboard/dist/assets/index-m9A3UYst.css +0 -1
  293. package/dashboard/dist/assets/validate-BIRn4a6d.js +0 -2
  294. package/dashboard/dist/assets/validate-BIRn4a6d.js.map +0 -1
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadRosterCounts = loadRosterCounts;
4
+ /**
5
+ * Server-side roster counts: the API-first counterpart of the dashboard's
6
+ * roster widget. For each `x-lt-roster` field of a form schema, the member
7
+ * rows are read with the same query the widget runs and the shared
8
+ * `computeRoster` turns them into counts, so `roster.*` showIf conditions and
9
+ * a roster submit guard evaluate at resolve exactly as the form showed them.
10
+ *
11
+ * Member rows are read with `global: true`: a resolver who cannot see a
12
+ * member must never be told the roster is complete.
13
+ */
14
+ const form_validation_1 = require("../../shared/form-validation");
15
+ const queries_1 = require("./queries");
16
+ /** Each roster field's counts, keyed by field name; empty when the schema declares none. */
17
+ async function loadRosterCounts(schema, ctx) {
18
+ const defs = (0, form_validation_1.readRosterDefs)(schema);
19
+ const counts = {};
20
+ for (const [field, def] of Object.entries(defs)) {
21
+ counts[field] = (0, form_validation_1.computeRoster)(def, ctx, await readMemberRows(def, ctx)).counts;
22
+ }
23
+ return counts;
24
+ }
25
+ async function readMemberRows(def, ctx) {
26
+ const query = (0, form_validation_1.rosterQueryOf)(def);
27
+ const scoped = query ? (0, form_validation_1.resolveRosterQuery)(query, ctx) : null;
28
+ if (!scoped)
29
+ return [];
30
+ const { escalations } = await (0, queries_1.searchEscalationsFaceted)({
31
+ global: true,
32
+ facet: { roles: scoped.roles, status: scoped.status, facets: scoped.facets },
33
+ limit: scoped.limit,
34
+ offset: 0,
35
+ });
36
+ return escalations.map((row) => (0, form_validation_1.rosterRowContext)(row));
37
+ }
@@ -15,6 +15,9 @@
15
15
  * - A guard whose scope cannot be evaluated (e.g. `assigned:'me'` on a surface
16
16
  * with no resolving user, like an MCP resolve) is skipped here; the consuming
17
17
  * workflow's own verification remains the durable backstop.
18
+ *
19
+ * A roster guard reads the counts the caller placed under `ctx.roster`
20
+ * (services/escalation/roster.ts) and rejects while entries are outstanding.
18
21
  */
19
22
  import { type ShowIfContext } from '../../shared/form-validation';
20
23
  import type { LTFieldViolation } from '../../types/validation';
@@ -19,6 +19,9 @@ exports.checkSubmitGuard = checkSubmitGuard;
19
19
  * - A guard whose scope cannot be evaluated (e.g. `assigned:'me'` on a surface
20
20
  * with no resolving user, like an MCP resolve) is skipped here; the consuming
21
21
  * workflow's own verification remains the durable backstop.
22
+ *
23
+ * A roster guard reads the counts the caller placed under `ctx.roster`
24
+ * (services/escalation/roster.ts) and rejects while entries are outstanding.
22
25
  */
23
26
  const form_validation_1 = require("../../shared/form-validation");
24
27
  const queries_1 = require("./queries");
@@ -34,6 +37,10 @@ async function checkSubmitGuard(schema, ctx, resolvingUserId) {
34
37
  const guard = (0, form_validation_1.readSubmitGuard)(schema);
35
38
  if (!guard || guard.mustBeEmpty === false)
36
39
  return null;
40
+ if (guard.roster)
41
+ return checkRosterGuard(guard, ctx);
42
+ if (!guard.query)
43
+ return null;
37
44
  const scoped = (0, form_validation_1.resolveScopedQuery)(guard.query, ctx, resolvingUserId);
38
45
  if (!scoped.enabled)
39
46
  return null;
@@ -51,7 +58,19 @@ async function checkSubmitGuard(schema, ctx, resolvingUserId) {
51
58
  });
52
59
  if (total <= 0)
53
60
  return null;
54
- const template = guard.message ?? form_validation_1.SUBMIT_GUARD_DEFAULT_MESSAGE;
55
- const message = (0, form_validation_1.interpolateHelp)(template.replace(/\{\{count\}\}/g, String(total)), ctx);
61
+ return guardViolation(guard.message ?? form_validation_1.SUBMIT_GUARD_DEFAULT_MESSAGE, total, ctx);
62
+ }
63
+ /** A roster guard: outstanding entries reject; a roster the schema does not declare rejects too. */
64
+ function checkRosterGuard(guard, ctx) {
65
+ const counts = ctx.roster?.[guard.roster];
66
+ if (!counts) {
67
+ return { field: exports.SUBMIT_GUARD_VIOLATION_FIELD, message: `Submit guard names roster "${guard.roster}", which the form does not declare` };
68
+ }
69
+ if (counts.outstanding <= 0)
70
+ return null;
71
+ return guardViolation(guard.message ?? form_validation_1.ROSTER_GUARD_DEFAULT_MESSAGE, counts.outstanding, ctx);
72
+ }
73
+ function guardViolation(template, count, ctx) {
74
+ const message = (0, form_validation_1.interpolateHelp)(template.replace(/\{\{count\}\}/g, String(count)), ctx);
56
75
  return { field: exports.SUBMIT_GUARD_VIOLATION_FIELD, message };
57
76
  }
@@ -107,7 +107,7 @@ async function executeRule(appId, rule) {
107
107
  break;
108
108
  }
109
109
  // Drop the authorization server's dead rows: spent or expired tokens and
110
- // codes, grants with neither left or long revoked, clients with no live grant.
110
+ // codes, grants with neither left or long revoked, clients never consented to.
111
111
  case rule.target === 'oauth' && rule.action === 'delete': {
112
112
  const { pruneOAuthServer } = await Promise.resolve().then(() => __importStar(require('../auth/oauth-server')));
113
113
  const counts = await pruneOAuthServer(rule.olderThan);
@@ -225,7 +225,7 @@ function registerHumanQueueTools(server) {
225
225
  isError: true,
226
226
  };
227
227
  }
228
- const resolved = await escalationService.resolveEscalation(args.escalation_id, args.payload, args.metadata);
228
+ const resolved = await escalationService.resolveEscalation(args.escalation_id, args.payload, { ...args.metadata, resolved_by: args.resolver_id });
229
229
  if (!resolved) {
230
230
  return {
231
231
  content: [{
@@ -9,6 +9,7 @@ export declare const DISPLAY_ONLY_WIDGET_NAMES: {
9
9
  readonly ESCALATION: "escalation";
10
10
  readonly ESCALATION_LIST: "escalation-list";
11
11
  readonly INVOKE: "invoke";
12
+ readonly ROSTER: "roster";
12
13
  };
13
14
  export declare const DISPLAY_ONLY_WIDGETS: ReadonlySet<string>;
14
15
  export declare function isDisplayOnlyWidget(name: unknown): boolean;
@@ -14,6 +14,7 @@ exports.DISPLAY_ONLY_WIDGET_NAMES = {
14
14
  ESCALATION: 'escalation',
15
15
  ESCALATION_LIST: 'escalation-list',
16
16
  INVOKE: 'invoke',
17
+ ROSTER: 'roster',
17
18
  };
18
19
  exports.DISPLAY_ONLY_WIDGETS = new Set(Object.values(exports.DISPLAY_ONLY_WIDGET_NAMES));
19
20
  function isDisplayOnlyWidget(name) {
@@ -23,3 +23,4 @@ export * from './invoke-context';
23
23
  export * from './display-only-widgets';
24
24
  export * from './x-lt-invoke';
25
25
  export * from './x-lt-scan';
26
+ export * from './x-lt-roster';
@@ -39,3 +39,4 @@ __exportStar(require("./invoke-context"), exports);
39
39
  __exportStar(require("./display-only-widgets"), exports);
40
40
  __exportStar(require("./x-lt-invoke"), exports);
41
41
  __exportStar(require("./x-lt-scan"), exports);
42
+ __exportStar(require("./x-lt-roster"), exports);
@@ -9,6 +9,7 @@
9
9
  * Semantics per field:
10
10
  * - x-lt-showIf-hidden fields are skipped entirely (a field the submitter
11
11
  * cannot see never blocks submission)
12
+ * - x-lt-hidden fields are never required; a value they carry is checked
12
13
  * - required (schema.required membership), with checklist/empty-object rules
13
14
  * - declared-type check (string/number/integer/boolean/array/object)
14
15
  * - enum membership
@@ -13,6 +13,7 @@ exports.validateResolverPayload = validateResolverPayload;
13
13
  * Semantics per field:
14
14
  * - x-lt-showIf-hidden fields are skipped entirely (a field the submitter
15
15
  * cannot see never blocks submission)
16
+ * - x-lt-hidden fields are never required; a value they carry is checked
16
17
  * - required (schema.required membership), with checklist/empty-object rules
17
18
  * - declared-type check (string/number/integer/boolean/array/object)
18
19
  * - enum membership
@@ -50,7 +51,7 @@ function validateResolverForm(schema, formValues, ctx) {
50
51
  for (const [field, fieldSchema] of Object.entries(properties)) {
51
52
  if (!(0, x_lt_show_if_1.evaluateShowIf)(fieldSchema['x-lt-showIf'], liveCtx))
52
53
  continue;
53
- const err = (0, field_validator_1.validateField)(formValues[field], fieldSchema, required.has(field), true, liveCtx);
54
+ const err = (0, field_validator_1.validateField)(formValues[field], fieldSchema, required.has(field) && !(0, x_lt_show_if_1.isHiddenField)(fieldSchema), true, liveCtx);
54
55
  if (err)
55
56
  errors.push({ field, message: err });
56
57
  }
@@ -1,5 +1,5 @@
1
1
  /** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
2
- export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup", "input"];
2
+ export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup", "input", "roster"];
3
3
  export type HelpDomain = (typeof HELP_DOMAINS)[number];
4
4
  export type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;
5
5
  /** Replace every `{{domain.path}}` token with its value from the context. */
@@ -17,6 +17,7 @@ exports.defaultHelpMarkdown = defaultHelpMarkdown;
17
17
  * {{payload.category}} — the escalation context payload
18
18
  * {{resolver.notes}} — the submitted resolver payload
19
19
  * {{lookup.materials.items}} — versioned knowledge lookups pinned on the row
20
+ * {{roster.orders.outstanding}} (a roster field's counts, x-lt-roster.ts)
20
21
  *
21
22
  * Paths reuse the x-lt-bind syntax (`a.b[0].c`). A missing value renders as an
22
23
  * em dash. `x-lt-context` is accepted as the plain-text fallback source when
@@ -24,7 +25,7 @@ exports.defaultHelpMarkdown = defaultHelpMarkdown;
24
25
  */
25
26
  const x_lt_bind_1 = require("./x-lt-bind");
26
27
  /** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
27
- exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input'];
28
+ exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input', 'roster'];
28
29
  const TOKEN_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
29
30
  const MISSING_VALUE = '—';
30
31
  function formatTokenValue(value) {
@@ -0,0 +1,92 @@
1
+ import { type HelpTokenContext } from './x-lt-help';
2
+ export declare const X_LT_ROSTER = "x-lt-roster";
3
+ export declare const ROSTER_WIDGET = "roster";
4
+ /** The context domain the counts are read from: `roster.<field>.outstanding`. */
5
+ export declare const ROSTER_DOMAIN = "roster";
6
+ /** The most member rows a query set reads. */
7
+ export declare const ROSTER_QUERY_LIMIT = 200;
8
+ /** The `in` source naming the host row's held keys. */
9
+ export declare const ROSTER_ITEMS_SOURCE = "items";
10
+ /** `query.status` value that reads every status (the default). */
11
+ export declare const ROSTER_ANY_STATUS = "any";
12
+ export declare const ROSTER_STATES: {
13
+ readonly WAITING: "waiting";
14
+ readonly IN: "in";
15
+ readonly FLAGGED: "flagged";
16
+ };
17
+ export type RosterState = (typeof ROSTER_STATES)[keyof typeof ROSTER_STATES];
18
+ export interface RosterQuery {
19
+ role?: string;
20
+ roles?: string[];
21
+ facets?: Record<string, string>;
22
+ /** A status to narrow to; omitted or `any` reads every status. */
23
+ status?: string;
24
+ }
25
+ export type RosterExpected = {
26
+ query: RosterQuery;
27
+ } | {
28
+ list: string;
29
+ } | {
30
+ batch: true;
31
+ labels?: string;
32
+ };
33
+ export interface RosterFlagRule {
34
+ /** An x-lt-showIf condition over the member row's own context. */
35
+ when: string | string[];
36
+ label: string;
37
+ }
38
+ export interface RosterDef {
39
+ expected: RosterExpected;
40
+ key?: string;
41
+ in?: string[];
42
+ flagged?: RosterFlagRule[];
43
+ }
44
+ /** One member row's token context (the row's own domains). */
45
+ export type RosterRow = HelpTokenContext & {
46
+ escalation: Record<string, unknown>;
47
+ };
48
+ export interface RosterEntry {
49
+ key: string;
50
+ state: RosterState;
51
+ /** The matching flag rule's label, when flagged. */
52
+ flag?: string;
53
+ /** The member row, for a query set. */
54
+ row?: RosterRow;
55
+ /** The per-key label value from a batch's `labels` map. */
56
+ label?: unknown;
57
+ }
58
+ export interface RosterCounts {
59
+ expected: number;
60
+ in: number;
61
+ flagged: number;
62
+ waiting: number;
63
+ /** Entries neither in nor flagged: the count a roster guard waits on. */
64
+ outstanding: number;
65
+ }
66
+ export interface RosterResult {
67
+ entries: RosterEntry[];
68
+ counts: RosterCounts;
69
+ }
70
+ /** The field's roster declaration, or undefined when it declares none or an unusable one. */
71
+ export declare function readRosterDef(fieldSchema: Record<string, unknown> | null | undefined): RosterDef | undefined;
72
+ /** Every roster field of a form schema, by field name. */
73
+ export declare function readRosterDefs(schema: Record<string, unknown> | null | undefined): Record<string, RosterDef>;
74
+ /** The roster's member-row query, or null when its set is not a query. */
75
+ export declare function rosterQueryOf(def: RosterDef): RosterQuery | null;
76
+ /** The query's concrete params: facets interpolated, `any` status dropped. Null when the scope is empty. */
77
+ export declare function resolveRosterQuery(query: RosterQuery, ctx: HelpTokenContext): {
78
+ roles?: string[];
79
+ facets: Record<string, string>;
80
+ status?: string;
81
+ limit: number;
82
+ } | null;
83
+ /** A member row's token context, from a row whose JSON columns are strings or objects. */
84
+ export declare function rosterRowContext(row: Record<string, unknown>): RosterRow;
85
+ /**
86
+ * Every expected entry with its state, and the counts. `rows` are the
87
+ * member rows a query set read (ignored for list and batch sets). `ctx` is
88
+ * the host row's context with the live form values under `resolver`.
89
+ */
90
+ export declare function computeRoster(def: RosterDef, ctx: HelpTokenContext, rows?: RosterRow[]): RosterResult;
91
+ /** The header line: "3 of 5 in · 1 Missing". */
92
+ export declare function rosterHeadline(result: RosterResult): string;
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ROSTER_STATES = exports.ROSTER_ANY_STATUS = exports.ROSTER_ITEMS_SOURCE = exports.ROSTER_QUERY_LIMIT = exports.ROSTER_DOMAIN = exports.ROSTER_WIDGET = exports.X_LT_ROSTER = void 0;
4
+ exports.readRosterDef = readRosterDef;
5
+ exports.readRosterDefs = readRosterDefs;
6
+ exports.rosterQueryOf = rosterQueryOf;
7
+ exports.resolveRosterQuery = resolveRosterQuery;
8
+ exports.rosterRowContext = rosterRowContext;
9
+ exports.computeRoster = computeRoster;
10
+ exports.rosterHeadline = rosterHeadline;
11
+ /**
12
+ * x-lt-roster: every member a container row expects, each with its state.
13
+ * A form field declares `x-lt-widget: "roster"` and an `x-lt-roster` block:
14
+ *
15
+ * "x-lt-roster": {
16
+ * "expected": { "query": { "roles": ["packing"], "facets": { "box": "{{escalation.id}}" } } },
17
+ * "key": "{{metadata.orderId}}",
18
+ * "in": ["items", "resolver.bags"],
19
+ * "flagged": [{ "when": "resolver.outcome=missing", "label": "Missing" }]
20
+ * }
21
+ *
22
+ * The expected set is one of:
23
+ * - `query`: member rows matched by role(s) and facets, any status unless
24
+ * `status` narrows it. `key` names each row's entry (default its id).
25
+ * - `list`: a `domain.path` naming an array of keys on the host row.
26
+ * - `batch`: the host row's batch keys; `labels` names a per-key map.
27
+ *
28
+ * An entry is `in` when its key is held by the host row (`items`: the
29
+ * accumulated keys, or a batch's filled keys) or appears in a named context
30
+ * value (`resolver.<field>`, a string or an array). It is `flagged` when its
31
+ * member row matches a `flagged` rule, and `waiting` otherwise. In wins over
32
+ * flagged, so a member flagged on its own row and then added reads in.
33
+ *
34
+ * Isomorphic: the dashboard renders the widget and the form's `roster.*`
35
+ * context from it, and the API layer computes the same counts to evaluate
36
+ * showIf and the roster submit guard at resolve.
37
+ */
38
+ const x_lt_bind_1 = require("./x-lt-bind");
39
+ const ctx_path_1 = require("./ctx-path");
40
+ const x_lt_help_1 = require("./x-lt-help");
41
+ const x_lt_show_if_1 = require("./x-lt-show-if");
42
+ exports.X_LT_ROSTER = 'x-lt-roster';
43
+ exports.ROSTER_WIDGET = 'roster';
44
+ /** The context domain the counts are read from: `roster.<field>.outstanding`. */
45
+ exports.ROSTER_DOMAIN = 'roster';
46
+ /** The most member rows a query set reads. */
47
+ exports.ROSTER_QUERY_LIMIT = 200;
48
+ /** The `in` source naming the host row's held keys. */
49
+ exports.ROSTER_ITEMS_SOURCE = 'items';
50
+ /** `query.status` value that reads every status (the default). */
51
+ exports.ROSTER_ANY_STATUS = 'any';
52
+ exports.ROSTER_STATES = { WAITING: 'waiting', IN: 'in', FLAGGED: 'flagged' };
53
+ const DEFAULT_KEY = '{{escalation.id}}';
54
+ const MISSING = '—';
55
+ const BATCH_KEYS = 'batch_keys';
56
+ const BATCH_PENDING = 'batch_pending';
57
+ const ACCUMULATE_KEYS = 'accumulate_keys';
58
+ function isRecord(v) {
59
+ return !!v && typeof v === 'object' && !Array.isArray(v);
60
+ }
61
+ function strings(v) {
62
+ if (typeof v === 'string')
63
+ return v ? [v] : [];
64
+ if (!Array.isArray(v))
65
+ return [];
66
+ return v.filter((s) => typeof s === 'string' && s.length > 0);
67
+ }
68
+ /** The field's roster declaration, or undefined when it declares none or an unusable one. */
69
+ function readRosterDef(fieldSchema) {
70
+ const raw = fieldSchema?.[exports.X_LT_ROSTER];
71
+ if (!isRecord(raw) || !isRecord(raw.expected))
72
+ return undefined;
73
+ const e = raw.expected;
74
+ const hasSource = isRecord(e.query) || typeof e.list === 'string' || e.batch === true;
75
+ return hasSource ? raw : undefined;
76
+ }
77
+ /** Every roster field of a form schema, by field name. */
78
+ function readRosterDefs(schema) {
79
+ const properties = isRecord(schema?.properties) ? schema.properties : {};
80
+ const defs = {};
81
+ for (const [field, def] of Object.entries(properties)) {
82
+ const roster = isRecord(def) ? readRosterDef(def) : undefined;
83
+ if (roster)
84
+ defs[field] = roster;
85
+ }
86
+ return defs;
87
+ }
88
+ /** The roster's member-row query, or null when its set is not a query. */
89
+ function rosterQueryOf(def) {
90
+ return 'query' in def.expected && isRecord(def.expected.query) ? def.expected.query : null;
91
+ }
92
+ /** The query's concrete params: facets interpolated, `any` status dropped. Null when the scope is empty. */
93
+ function resolveRosterQuery(query, ctx) {
94
+ const facets = {};
95
+ for (const [k, v] of Object.entries(query.facets ?? {})) {
96
+ if (typeof v !== 'string')
97
+ continue;
98
+ const resolved = (0, x_lt_help_1.interpolateHelp)(v, ctx);
99
+ if (!resolved || resolved === MISSING)
100
+ return null;
101
+ facets[k] = resolved;
102
+ }
103
+ const roles = [...(query.role ? [query.role] : []), ...strings(query.roles)];
104
+ if (!roles.length && !Object.keys(facets).length)
105
+ return null;
106
+ const status = query.status && query.status !== exports.ROSTER_ANY_STATUS ? query.status : undefined;
107
+ return { ...(roles.length ? { roles } : {}), facets, ...(status ? { status } : {}), limit: exports.ROSTER_QUERY_LIMIT };
108
+ }
109
+ function parseJson(v) {
110
+ if (isRecord(v))
111
+ return v;
112
+ if (typeof v !== 'string' || !v)
113
+ return null;
114
+ try {
115
+ const parsed = JSON.parse(v);
116
+ return isRecord(parsed) ? parsed : null;
117
+ }
118
+ catch {
119
+ return null;
120
+ }
121
+ }
122
+ /** A member row's token context, from a row whose JSON columns are strings or objects. */
123
+ function rosterRowContext(row) {
124
+ return {
125
+ escalation: row,
126
+ metadata: isRecord(row.metadata) ? row.metadata : parseJson(row.metadata),
127
+ envelope: parseJson(row.envelope),
128
+ payload: parseJson(row.escalation_payload),
129
+ resolver: parseJson(row.resolver_payload),
130
+ };
131
+ }
132
+ /** The keys the host row holds: its accumulated keys, or a batch's filled keys. */
133
+ function heldKeys(ctx) {
134
+ const metadata = ctx.metadata ?? {};
135
+ const accumulated = metadata[ACCUMULATE_KEYS];
136
+ if (Array.isArray(accumulated))
137
+ return new Set(strings(accumulated));
138
+ const envelopeItems = (0, x_lt_bind_1.getDeep)(ctx.envelope, 'accumulate_items');
139
+ if (isRecord(envelopeItems))
140
+ return new Set(Object.keys(envelopeItems));
141
+ if (Array.isArray(metadata[BATCH_PENDING])) {
142
+ const pending = new Set(strings(metadata[BATCH_PENDING]));
143
+ return new Set(strings(metadata[BATCH_KEYS]).filter((k) => !pending.has(k)));
144
+ }
145
+ return new Set();
146
+ }
147
+ function arrivedKeys(def, ctx) {
148
+ const arrived = new Set();
149
+ for (const source of def.in ?? [exports.ROSTER_ITEMS_SOURCE]) {
150
+ const keys = source === exports.ROSTER_ITEMS_SOURCE
151
+ ? [...heldKeys(ctx)]
152
+ : strings((0, ctx_path_1.resolveCtxPath)(source, ctx));
153
+ keys.forEach((k) => arrived.add(k));
154
+ }
155
+ return arrived;
156
+ }
157
+ function flagFor(def, row) {
158
+ if (!row)
159
+ return undefined;
160
+ for (const rule of def.flagged ?? []) {
161
+ const conditions = strings(rule.when);
162
+ if (!conditions.length || typeof rule.label !== 'string')
163
+ continue;
164
+ if ((0, x_lt_show_if_1.evaluateShowIf)(conditions, row))
165
+ return rule.label;
166
+ }
167
+ return undefined;
168
+ }
169
+ /** The expected keys in order, each with its member row (query) or label (batch). */
170
+ function expectedEntries(def, ctx, rows) {
171
+ const seen = new Set();
172
+ const out = [];
173
+ const push = (key, extra = {}) => {
174
+ if (!key || key === MISSING || seen.has(key))
175
+ return;
176
+ seen.add(key);
177
+ out.push({ key, ...extra });
178
+ };
179
+ const e = def.expected;
180
+ if ('query' in e) {
181
+ const template = def.key ?? DEFAULT_KEY;
182
+ for (const row of rows)
183
+ push((0, x_lt_help_1.interpolateHelp)(template, row), { row });
184
+ }
185
+ else if ('list' in e) {
186
+ strings((0, ctx_path_1.resolveCtxPath)(e.list, ctx)).forEach((k) => push(k));
187
+ }
188
+ else {
189
+ const labels = e.labels ? (0, ctx_path_1.resolveCtxPath)(e.labels, ctx) : undefined;
190
+ for (const key of strings(ctx.metadata?.[BATCH_KEYS])) {
191
+ push(key, isRecord(labels) && key in labels ? { label: labels[key] } : {});
192
+ }
193
+ }
194
+ return out;
195
+ }
196
+ /**
197
+ * Every expected entry with its state, and the counts. `rows` are the
198
+ * member rows a query set read (ignored for list and batch sets). `ctx` is
199
+ * the host row's context with the live form values under `resolver`.
200
+ */
201
+ function computeRoster(def, ctx, rows = []) {
202
+ const arrived = arrivedKeys(def, ctx);
203
+ const entries = expectedEntries(def, ctx, rows).map((e) => {
204
+ if (arrived.has(e.key))
205
+ return { ...e, state: exports.ROSTER_STATES.IN };
206
+ const flag = flagFor(def, e.row);
207
+ return flag ? { ...e, state: exports.ROSTER_STATES.FLAGGED, flag } : { ...e, state: exports.ROSTER_STATES.WAITING };
208
+ });
209
+ const count = (s) => entries.filter((e) => e.state === s).length;
210
+ const waiting = count(exports.ROSTER_STATES.WAITING);
211
+ return {
212
+ entries,
213
+ counts: {
214
+ expected: entries.length,
215
+ in: count(exports.ROSTER_STATES.IN),
216
+ flagged: count(exports.ROSTER_STATES.FLAGGED),
217
+ waiting,
218
+ outstanding: waiting,
219
+ },
220
+ };
221
+ }
222
+ /** The header line: "3 of 5 in · 1 Missing". */
223
+ function rosterHeadline(result) {
224
+ const { counts } = result;
225
+ const parts = [`${counts.in} of ${counts.expected} in`];
226
+ const byFlag = new Map();
227
+ for (const e of result.entries) {
228
+ if (e.state === exports.ROSTER_STATES.FLAGGED && e.flag)
229
+ byFlag.set(e.flag, (byFlag.get(e.flag) ?? 0) + 1);
230
+ }
231
+ for (const [flag, n] of byFlag)
232
+ parts.push(`${n} ${flag}`);
233
+ return parts.join(' · ');
234
+ }
@@ -11,3 +11,11 @@ export declare function evaluateShowIf(condition: unknown, ctx: ShowIfContext |
11
11
  * (null, undefined, '', false, or 0). Render and validation share this test.
12
12
  */
13
13
  export declare function isHiddenIfEmpty(fieldSchema: Record<string, unknown> | undefined, value: unknown): boolean;
14
+ /**
15
+ * `x-lt-hidden: true`: the field never renders. A value set by the caller
16
+ * (a workflow default, an API submitter) passes through to the payload and
17
+ * is checked against the field's type and enum; the field is never required,
18
+ * since no one on the form can answer it.
19
+ */
20
+ export declare const X_LT_HIDDEN = "x-lt-hidden";
21
+ export declare function isHiddenField(fieldSchema: Record<string, unknown> | undefined): boolean;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.X_LT_HIDDEN = void 0;
3
4
  exports.evaluateShowIf = evaluateShowIf;
4
5
  exports.isHiddenIfEmpty = isHiddenIfEmpty;
6
+ exports.isHiddenField = isHiddenField;
5
7
  /**
6
8
  * x-lt-showIf — conditional field visibility. A form_schema property may
7
9
  * declare `x-lt-showIf: "domain.path"` to show the field only when the value
@@ -21,6 +23,7 @@ exports.isHiddenIfEmpty = isHiddenIfEmpty;
21
23
  * envelope — the workflow-sent input envelope
22
24
  * escalation — top-level escalation row fields
23
25
  * resolver — the submitted resolver payload
26
+ * roster (each roster field's counts: `roster.orders.outstanding=0`)
24
27
  *
25
28
  * A missing or non-string condition always shows the field (opt-in, safe default).
26
29
  */
@@ -95,3 +98,13 @@ function isHiddenIfEmpty(fieldSchema, value) {
95
98
  return false;
96
99
  return value === null || value === undefined || value === '' || value === false || value === 0;
97
100
  }
101
+ /**
102
+ * `x-lt-hidden: true`: the field never renders. A value set by the caller
103
+ * (a workflow default, an API submitter) passes through to the payload and
104
+ * is checked against the field's type and enum; the field is never required,
105
+ * since no one on the form can answer it.
106
+ */
107
+ exports.X_LT_HIDDEN = 'x-lt-hidden';
108
+ function isHiddenField(fieldSchema) {
109
+ return fieldSchema?.[exports.X_LT_HIDDEN] === true;
110
+ }
@@ -23,11 +23,23 @@
23
23
  * `autoResolveWhenEmpty` closes the loop: the moment the query is confirmed
24
24
  * empty, the claimed parent auto-submits — checked on page-load and after each
25
25
  * inline child-resolve — so a set of escalations completes with no extra click.
26
+ *
27
+ * A guard may name a roster field instead of a query: the resolve waits while
28
+ * that roster has outstanding entries (x-lt-roster.ts), so the list the person
29
+ * works from and the rule that holds the submit are one computation.
30
+ *
31
+ * "x-lt-submit-guard": { "roster": "orders",
32
+ * "message": "{{count}} orders are still unaccounted for" }
33
+ *
34
+ * `{{count}}` is the outstanding count. A roster guard never auto-submits.
26
35
  */
27
36
  import type { EmbedQuery } from './x-lt-query';
28
37
  export declare const X_LT_SUBMIT_GUARD = "x-lt-submit-guard";
29
38
  export interface SubmitGuardDef {
30
- query: EmbedQuery;
39
+ /** The embedded query that must be empty; absent for a roster guard. */
40
+ query?: EmbedQuery;
41
+ /** A roster field whose outstanding entries hold the resolve. */
42
+ roster?: string;
31
43
  /** The gate condition; defaults to true (the only supported mode today). */
32
44
  mustBeEmpty?: boolean;
33
45
  /** Shown beside the disabled submit. `{{count}}` and `{{domain.path}}` tokens interpolate. */
@@ -36,6 +48,7 @@ export interface SubmitGuardDef {
36
48
  autoResolveWhenEmpty?: boolean;
37
49
  }
38
50
  export declare const SUBMIT_GUARD_DEFAULT_MESSAGE = "{{count}} related items are still pending";
51
+ export declare const ROSTER_GUARD_DEFAULT_MESSAGE = "{{count}} expected items are still outstanding";
39
52
  /** The schema's submit-guard, or undefined when it declares none. */
40
53
  export declare function readSubmitGuard(schema: Record<string, unknown> | null | undefined): SubmitGuardDef | undefined;
41
54
  /**
@@ -1,16 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SUBMIT_GUARD_DEFAULT_MESSAGE = exports.X_LT_SUBMIT_GUARD = void 0;
3
+ exports.ROSTER_GUARD_DEFAULT_MESSAGE = exports.SUBMIT_GUARD_DEFAULT_MESSAGE = exports.X_LT_SUBMIT_GUARD = void 0;
4
4
  exports.readSubmitGuard = readSubmitGuard;
5
5
  exports.guardBlocks = guardBlocks;
6
6
  exports.X_LT_SUBMIT_GUARD = 'x-lt-submit-guard';
7
7
  exports.SUBMIT_GUARD_DEFAULT_MESSAGE = '{{count}} related items are still pending';
8
+ exports.ROSTER_GUARD_DEFAULT_MESSAGE = '{{count}} expected items are still outstanding';
8
9
  /** The schema's submit-guard, or undefined when it declares none. */
9
10
  function readSubmitGuard(schema) {
10
11
  const raw = schema?.[exports.X_LT_SUBMIT_GUARD];
11
12
  if (!raw || typeof raw !== 'object' || Array.isArray(raw))
12
13
  return undefined;
13
14
  const guard = raw;
15
+ if (typeof guard.roster === 'string' && guard.roster)
16
+ return guard;
14
17
  if (!guard.query || typeof guard.query !== 'object')
15
18
  return undefined;
16
19
  return guard;
@@ -0,0 +1,19 @@
1
+ import { RELATED_AGGREGATES, type RelatedAggregate, type RelatedColumnDecl } from './types';
2
+ export type RelatedExtreme = typeof RELATED_AGGREGATES.MIN | typeof RELATED_AGGREGATES.MAX;
3
+ /** True for the aggregates that pick one value rather than count. */
4
+ export declare function isExtremeAggregate(aggregate: unknown): aggregate is RelatedExtreme;
5
+ /**
6
+ * The stored path a min/max `value` template reads: `payload.<path>` for an
7
+ * items set, `metadata.<key>` for a query set. Null when the template does
8
+ * not fit the set's source.
9
+ */
10
+ export declare function relatedValuePath(source: string, value: unknown): string | null;
11
+ /** The key a column's per-host aggregates are stored under in its set's result. */
12
+ export declare function relatedAggregateKey(col: Pick<RelatedColumnDecl, 'aggregate' | 'splitBy' | 'value'>, source: string): string;
13
+ /** A count column's display text, or null when the column declares none for this count. */
14
+ export declare function relatedCountText(display: Record<string, string> | undefined, count: number): string | null;
15
+ /**
16
+ * The least or greatest of several values: numbers when every value is a
17
+ * number, otherwise text in code-unit order (ISO instants order as text).
18
+ */
19
+ export declare function foldExtreme(fold: RelatedAggregate, values: Array<string | number>): string | number | undefined;