@hotmeshio/long-tail 0.24.2 → 0.25.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) 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/services/domain/seed.d.ts +12 -10
  6. package/build/services/domain/seed.js +31 -25
  7. package/build/services/escalation/accumulate.d.ts +3 -1
  8. package/build/services/escalation/facet-sql.js +4 -2
  9. package/build/services/escalation/index.d.ts +1 -0
  10. package/build/services/escalation/index.js +4 -1
  11. package/build/services/escalation/related-extremes.d.ts +17 -0
  12. package/build/services/escalation/related-extremes.js +65 -0
  13. package/build/services/escalation/related.d.ts +4 -0
  14. package/build/services/escalation/related.js +2 -0
  15. package/build/services/escalation/resolver-validation.js +7 -0
  16. package/build/services/escalation/roster.d.ts +13 -0
  17. package/build/services/escalation/roster.js +37 -0
  18. package/build/services/escalation/submit-guard.d.ts +3 -0
  19. package/build/services/escalation/submit-guard.js +21 -2
  20. package/build/services/mcp/server-tools.js +1 -1
  21. package/build/shared/form-validation/display-only-widgets.d.ts +1 -0
  22. package/build/shared/form-validation/display-only-widgets.js +1 -0
  23. package/build/shared/form-validation/index.d.ts +1 -0
  24. package/build/shared/form-validation/index.js +1 -0
  25. package/build/shared/form-validation/validate-resolver-payload.d.ts +1 -0
  26. package/build/shared/form-validation/validate-resolver-payload.js +2 -1
  27. package/build/shared/form-validation/x-lt-help.d.ts +1 -1
  28. package/build/shared/form-validation/x-lt-help.js +2 -1
  29. package/build/shared/form-validation/x-lt-roster.d.ts +92 -0
  30. package/build/shared/form-validation/x-lt-roster.js +253 -0
  31. package/build/shared/form-validation/x-lt-show-if.d.ts +8 -0
  32. package/build/shared/form-validation/x-lt-show-if.js +13 -0
  33. package/build/shared/form-validation/x-lt-submit-guard.d.ts +14 -1
  34. package/build/shared/form-validation/x-lt-submit-guard.js +4 -1
  35. package/build/shared/list-schema/aggregate.d.ts +19 -0
  36. package/build/shared/list-schema/aggregate.js +66 -0
  37. package/build/shared/list-schema/index.d.ts +2 -0
  38. package/build/shared/list-schema/index.js +7 -1
  39. package/build/shared/list-schema/types.d.ts +15 -2
  40. package/build/shared/list-schema/types.js +6 -1
  41. package/build/shared/list-schema/validate.js +28 -2
  42. package/build/start/workers.d.ts +3 -0
  43. package/build/start/workers.js +15 -5
  44. package/build/tsconfig.tsbuildinfo +1 -1
  45. package/build/types/startup.d.ts +8 -1
  46. package/dashboard/dist/assets/{AdminDashboard-B3mkMIOT.js → AdminDashboard-C_0ShYrm.js} +2 -2
  47. package/dashboard/dist/assets/{AdminDashboard-B3mkMIOT.js.map → AdminDashboard-C_0ShYrm.js.map} +1 -1
  48. package/dashboard/dist/assets/{AgentConfigPage-CQj2B678.js → AgentConfigPage-Cc9dI8lO.js} +6 -6
  49. package/dashboard/dist/assets/{AgentConfigPage-CQj2B678.js.map → AgentConfigPage-Cc9dI8lO.js.map} +1 -1
  50. package/dashboard/dist/assets/{AgentDetailPage-CzrD8JJI.js → AgentDetailPage-Sdmt5j-k.js} +3 -3
  51. package/dashboard/dist/assets/{AgentDetailPage-CzrD8JJI.js.map → AgentDetailPage-Sdmt5j-k.js.map} +1 -1
  52. package/dashboard/dist/assets/{AgentsPage-jg2OFwyW.js → AgentsPage-BuzXc1mg.js} +2 -2
  53. package/dashboard/dist/assets/{AgentsPage-jg2OFwyW.js.map → AgentsPage-BuzXc1mg.js.map} +1 -1
  54. package/dashboard/dist/assets/AvailableEscalationsPage-DU84iaBN.js +2 -0
  55. package/dashboard/dist/assets/{AvailableEscalationsPage-IS28XBRe.js.map → AvailableEscalationsPage-DU84iaBN.js.map} +1 -1
  56. package/dashboard/dist/assets/{BotPicker-DvEJFpwS.js → BotPicker-Ci5PUrkl.js} +2 -2
  57. package/dashboard/dist/assets/{BotPicker-DvEJFpwS.js.map → BotPicker-Ci5PUrkl.js.map} +1 -1
  58. package/dashboard/dist/assets/{BulkAssignModal-BoQCi-YC.js → BulkAssignModal-PLx7SLvF.js} +2 -2
  59. package/dashboard/dist/assets/{BulkAssignModal-BoQCi-YC.js.map → BulkAssignModal-PLx7SLvF.js.map} +1 -1
  60. package/dashboard/dist/assets/{CapabilitiesPage-kwlrcb_t.js → CapabilitiesPage-DuSfgr6i.js} +2 -2
  61. package/dashboard/dist/assets/{CapabilitiesPage-kwlrcb_t.js.map → CapabilitiesPage-DuSfgr6i.js.map} +1 -1
  62. package/dashboard/dist/assets/{CollapsibleSection-UMIV4KIj.js → CollapsibleSection-KOO37qs6.js} +2 -2
  63. package/dashboard/dist/assets/{CollapsibleSection-UMIV4KIj.js.map → CollapsibleSection-KOO37qs6.js.map} +1 -1
  64. package/dashboard/dist/assets/{ConfirmDeleteModal-C5puwMg7.js → ConfirmDeleteModal-CI1eE-Nr.js} +2 -2
  65. package/dashboard/dist/assets/{ConfirmDeleteModal-C5puwMg7.js.map → ConfirmDeleteModal-CI1eE-Nr.js.map} +1 -1
  66. package/dashboard/dist/assets/{ConnectedAppsPage-drZa65kP.js → ConnectedAppsPage-DZgbCC0G.js} +2 -2
  67. package/dashboard/dist/assets/{ConnectedAppsPage-drZa65kP.js.map → ConnectedAppsPage-DZgbCC0G.js.map} +1 -1
  68. package/dashboard/dist/assets/CountdownTimer-C-Ngk8oq.js +2 -0
  69. package/dashboard/dist/assets/CountdownTimer-C-Ngk8oq.js.map +1 -0
  70. package/dashboard/dist/assets/{CredentialsPage-CaFQ6vLb.js → CredentialsPage-BR7s6eVu.js} +2 -2
  71. package/dashboard/dist/assets/{CredentialsPage-CaFQ6vLb.js.map → CredentialsPage-BR7s6eVu.js.map} +1 -1
  72. package/dashboard/dist/assets/{CronLabel-Co5j7tzW.js → CronLabel-BQ7Y1Nfd.js} +2 -2
  73. package/dashboard/dist/assets/{CronLabel-Co5j7tzW.js.map → CronLabel-BQ7Y1Nfd.js.map} +1 -1
  74. package/dashboard/dist/assets/{DropZone-B1Tdfddc.js → DropZone-DCZpORx-.js} +2 -2
  75. package/dashboard/dist/assets/{DropZone-B1Tdfddc.js.map → DropZone-DCZpORx-.js.map} +1 -1
  76. package/dashboard/dist/assets/{ElapsedCell-WJyE9G0T.js → ElapsedCell-BT49mUIc.js} +2 -2
  77. package/dashboard/dist/assets/{ElapsedCell-WJyE9G0T.js.map → ElapsedCell-BT49mUIc.js.map} +1 -1
  78. package/dashboard/dist/assets/{EntityTimelinePanel-CDFFfX9d.js → EntityTimelinePanel-BtARWy3R.js} +2 -2
  79. package/dashboard/dist/assets/{EntityTimelinePanel-CDFFfX9d.js.map → EntityTimelinePanel-BtARWy3R.js.map} +1 -1
  80. package/dashboard/dist/assets/{EscalationListSchemaPage-CMrUlaKI.js → EscalationListSchemaPage-EEBsNpTe.js} +3 -3
  81. package/dashboard/dist/assets/{EscalationListSchemaPage-CMrUlaKI.js.map → EscalationListSchemaPage-EEBsNpTe.js.map} +1 -1
  82. package/dashboard/dist/assets/{EscalationSchemaPage-Dx2Lyfrz.js → EscalationSchemaPage-BHSC46Ow.js} +3 -3
  83. package/dashboard/dist/assets/{EscalationSchemaPage-Dx2Lyfrz.js.map → EscalationSchemaPage-BHSC46Ow.js.map} +1 -1
  84. package/dashboard/dist/assets/EscalationTimeline-BWTUBxUf.js +2 -0
  85. package/dashboard/dist/assets/{EscalationTimeline-d3nvshOk.js.map → EscalationTimeline-BWTUBxUf.js.map} +1 -1
  86. package/dashboard/dist/assets/{EscalationTitleSelect-DWQieOM9.js → EscalationTitleSelect-DOsfY4u8.js} +2 -2
  87. package/dashboard/dist/assets/{EscalationTitleSelect-DWQieOM9.js.map → EscalationTitleSelect-DOsfY4u8.js.map} +1 -1
  88. package/dashboard/dist/assets/{EscalationsOverview-BX8Cpi0X.js → EscalationsOverview-Bl8g53x-.js} +2 -2
  89. package/dashboard/dist/assets/{EscalationsOverview-BX8Cpi0X.js.map → EscalationsOverview-Bl8g53x-.js.map} +1 -1
  90. package/dashboard/dist/assets/{EventTable-D1-ITVXS.js → EventTable-Bjx17W_i.js} +2 -2
  91. package/dashboard/dist/assets/{EventTable-D1-ITVXS.js.map → EventTable-Bjx17W_i.js.map} +1 -1
  92. package/dashboard/dist/assets/{FilterBar-ABC9ctin.js → FilterBar-Dnse0soD.js} +2 -2
  93. package/dashboard/dist/assets/{FilterBar-ABC9ctin.js.map → FilterBar-Dnse0soD.js.map} +1 -1
  94. package/dashboard/dist/assets/{FormattedValue-k27T4bG7.js → FormattedValue-DeVrRJy4.js} +2 -2
  95. package/dashboard/dist/assets/{FormattedValue-k27T4bG7.js.map → FormattedValue-DeVrRJy4.js.map} +1 -1
  96. package/dashboard/dist/assets/{GraphInvokePage-DKUErxWc.js → GraphInvokePage-HQEvbHTd.js} +2 -2
  97. package/dashboard/dist/assets/{GraphInvokePage-DKUErxWc.js.map → GraphInvokePage-HQEvbHTd.js.map} +1 -1
  98. package/dashboard/dist/assets/{HomePage-C6u9dIpR.js → HomePage-DizTklVg.js} +2 -2
  99. package/dashboard/dist/assets/{HomePage-C6u9dIpR.js.map → HomePage-DizTklVg.js.map} +1 -1
  100. package/dashboard/dist/assets/{ListToolbar-gA5rFzkz.js → ListToolbar-B0qe2QZ5.js} +2 -2
  101. package/dashboard/dist/assets/{ListToolbar-gA5rFzkz.js.map → ListToolbar-B0qe2QZ5.js.map} +1 -1
  102. package/dashboard/dist/assets/{McpOverview-BOPo3J_i.js → McpOverview-DmH-qtX9.js} +2 -2
  103. package/dashboard/dist/assets/{McpOverview-BOPo3J_i.js.map → McpOverview-DmH-qtX9.js.map} +1 -1
  104. package/dashboard/dist/assets/{McpQueryDetailPage-BRVVi0Zh.js → McpQueryDetailPage-B-qtmwLd.js} +2 -2
  105. package/dashboard/dist/assets/{McpQueryDetailPage-BRVVi0Zh.js.map → McpQueryDetailPage-B-qtmwLd.js.map} +1 -1
  106. package/dashboard/dist/assets/{McpQueryPage-Dmbb6SAc.js → McpQueryPage-DX1T-Ugq.js} +2 -2
  107. package/dashboard/dist/assets/{McpQueryPage-Dmbb6SAc.js.map → McpQueryPage-DX1T-Ugq.js.map} +1 -1
  108. package/dashboard/dist/assets/McpRunDetailPage-DNdl10nB.js +2 -0
  109. package/dashboard/dist/assets/{McpRunDetailPage-bMXNO-6V.js.map → McpRunDetailPage-DNdl10nB.js.map} +1 -1
  110. package/dashboard/dist/assets/{McpRunsPage-Bi9AMWja.js → McpRunsPage-DVXVB4AJ.js} +2 -2
  111. package/dashboard/dist/assets/{McpRunsPage-Bi9AMWja.js.map → McpRunsPage-DVXVB4AJ.js.map} +1 -1
  112. package/dashboard/dist/assets/{NamespacePill-DwM5pNA4.js → NamespacePill-CSZT2fA4.js} +2 -2
  113. package/dashboard/dist/assets/{NamespacePill-DwM5pNA4.js.map → NamespacePill-CSZT2fA4.js.map} +1 -1
  114. package/dashboard/dist/assets/{OperationsPage-CvR74ZUJ.js → OperationsPage-BxgWQq8v.js} +3 -3
  115. package/dashboard/dist/assets/{OperationsPage-CvR74ZUJ.js.map → OperationsPage-BxgWQq8v.js.map} +1 -1
  116. package/dashboard/dist/assets/OperatorDashboard-Cw86vOPg.js +2 -0
  117. package/dashboard/dist/assets/{OperatorDashboard-DctmZw10.js.map → OperatorDashboard-Cw86vOPg.js.map} +1 -1
  118. package/dashboard/dist/assets/{PageHeader-CMd3f4bz.js → PageHeader-C4z1ExF7.js} +2 -2
  119. package/dashboard/dist/assets/{PageHeader-CMd3f4bz.js.map → PageHeader-C4z1ExF7.js.map} +1 -1
  120. package/dashboard/dist/assets/{PageHeaderWithStats-DHj8Mqox.js → PageHeaderWithStats-B_f_Sz_Q.js} +2 -2
  121. package/dashboard/dist/assets/{PageHeaderWithStats-DHj8Mqox.js.map → PageHeaderWithStats-B_f_Sz_Q.js.map} +1 -1
  122. package/dashboard/dist/assets/{PersonaDetailPage-Ubqm2rQH.js → PersonaDetailPage-BTIJ4A6p.js} +2 -2
  123. package/dashboard/dist/assets/{PersonaDetailPage-Ubqm2rQH.js.map → PersonaDetailPage-BTIJ4A6p.js.map} +1 -1
  124. package/dashboard/dist/assets/{PersonasPage-BpFL2rpo.js → PersonasPage-D11PokPb.js} +2 -2
  125. package/dashboard/dist/assets/{PersonasPage-BpFL2rpo.js.map → PersonasPage-D11PokPb.js.map} +1 -1
  126. package/dashboard/dist/assets/PortalPage-1rXm0cNK.js +2 -0
  127. package/dashboard/dist/assets/{PortalPage-Dfc_Q02R.js.map → PortalPage-1rXm0cNK.js.map} +1 -1
  128. package/dashboard/dist/assets/{ProcessDetailPage-liJspvQh.js → ProcessDetailPage-Cp5-969g.js} +2 -2
  129. package/dashboard/dist/assets/{ProcessDetailPage-liJspvQh.js.map → ProcessDetailPage-Cp5-969g.js.map} +1 -1
  130. package/dashboard/dist/assets/{ProcessesListPage-C3OM5ZUy.js → ProcessesListPage-assXQe-x.js} +2 -2
  131. package/dashboard/dist/assets/{ProcessesListPage-C3OM5ZUy.js.map → ProcessesListPage-assXQe-x.js.map} +1 -1
  132. package/dashboard/dist/assets/ResolverForm-CMzNjmGG.js +8 -0
  133. package/dashboard/dist/assets/ResolverForm-CMzNjmGG.js.map +1 -0
  134. package/dashboard/dist/assets/{RoleDetailPage-CrlYCh-R.js → RoleDetailPage-c_Qij0Tf.js} +3 -3
  135. package/dashboard/dist/assets/{RoleDetailPage-CrlYCh-R.js.map → RoleDetailPage-c_Qij0Tf.js.map} +1 -1
  136. package/dashboard/dist/assets/{RolePill-Di2CAHuD.js → RolePill-Bw_n7EpR.js} +2 -2
  137. package/dashboard/dist/assets/{RolePill-Di2CAHuD.js.map → RolePill-Bw_n7EpR.js.map} +1 -1
  138. package/dashboard/dist/assets/{RolesPage-BaazL_pt.js → RolesPage-D4oaYgTg.js} +2 -2
  139. package/dashboard/dist/assets/{RolesPage-BaazL_pt.js.map → RolesPage-D4oaYgTg.js.map} +1 -1
  140. package/dashboard/dist/assets/{RunAsSelector-DxuV0fa1.js → RunAsSelector-Fptil_sB.js} +2 -2
  141. package/dashboard/dist/assets/{RunAsSelector-DxuV0fa1.js.map → RunAsSelector-Fptil_sB.js.map} +1 -1
  142. package/dashboard/dist/assets/{ScanCodesPage-C0mvmYTq.js → ScanCodesPage-BeZA_YJW.js} +2 -2
  143. package/dashboard/dist/assets/{ScanCodesPage-C0mvmYTq.js.map → ScanCodesPage-BeZA_YJW.js.map} +1 -1
  144. package/dashboard/dist/assets/{ScanSchemeDetailPage-CiJgt5dZ.js → ScanSchemeDetailPage-Bxi15xNr.js} +2 -2
  145. package/dashboard/dist/assets/{ScanSchemeDetailPage-CiJgt5dZ.js.map → ScanSchemeDetailPage-Bxi15xNr.js.map} +1 -1
  146. package/dashboard/dist/assets/ScanStationPage-t5Bz957t.js +2 -0
  147. package/dashboard/dist/assets/ScanStationPage-t5Bz957t.js.map +1 -0
  148. package/dashboard/dist/assets/{ScopeBadge-CSItPVOH.js → ScopeBadge-CKgfwTy3.js} +2 -2
  149. package/dashboard/dist/assets/{ScopeBadge-CSItPVOH.js.map → ScopeBadge-CKgfwTy3.js.map} +1 -1
  150. package/dashboard/dist/assets/{StickyPagination-CqbjVY6T.js → StickyPagination-C2drZk7w.js} +2 -2
  151. package/dashboard/dist/assets/{StickyPagination-CqbjVY6T.js.map → StickyPagination-C2drZk7w.js.map} +1 -1
  152. package/dashboard/dist/assets/{StreamMessageDetail-wX3i0aqs.js → StreamMessageDetail-x-l5653y.js} +2 -2
  153. package/dashboard/dist/assets/{StreamMessageDetail-wX3i0aqs.js.map → StreamMessageDetail-x-l5653y.js.map} +1 -1
  154. package/dashboard/dist/assets/{SwimlaneTimeline-C50PsFoV.js → SwimlaneTimeline-Ds_CqLXL.js} +2 -2
  155. package/dashboard/dist/assets/{SwimlaneTimeline-C50PsFoV.js.map → SwimlaneTimeline-Ds_CqLXL.js.map} +1 -1
  156. package/dashboard/dist/assets/{TagInput-CAgdLN_b.js → TagInput-B6fMAqxd.js} +2 -2
  157. package/dashboard/dist/assets/{TagInput-CAgdLN_b.js.map → TagInput-B6fMAqxd.js.map} +1 -1
  158. package/dashboard/dist/assets/{TaskDetailPage-bbNSv4Ae.js → TaskDetailPage-BJGKEnIo.js} +2 -2
  159. package/dashboard/dist/assets/{TaskDetailPage-bbNSv4Ae.js.map → TaskDetailPage-BJGKEnIo.js.map} +1 -1
  160. package/dashboard/dist/assets/{TaskQueuePill-h0oorVMe.js → TaskQueuePill-BnDp_DE6.js} +2 -2
  161. package/dashboard/dist/assets/{TaskQueuePill-h0oorVMe.js.map → TaskQueuePill-BnDp_DE6.js.map} +1 -1
  162. package/dashboard/dist/assets/{TasksListPage-CDWnm_d9.js → TasksListPage-DyLaZvTT.js} +2 -2
  163. package/dashboard/dist/assets/{TasksListPage-CDWnm_d9.js.map → TasksListPage-DyLaZvTT.js.map} +1 -1
  164. package/dashboard/dist/assets/{TimeAgo-BLjqlfoX.js → TimeAgo-B_Ta97uy.js} +2 -2
  165. package/dashboard/dist/assets/{TimeAgo-BLjqlfoX.js.map → TimeAgo-B_Ta97uy.js.map} +1 -1
  166. package/dashboard/dist/assets/{TimestampCell-CnW0ENb5.js → TimestampCell-CiTYBQw-.js} +2 -2
  167. package/dashboard/dist/assets/{TimestampCell-CnW0ENb5.js.map → TimestampCell-CiTYBQw-.js.map} +1 -1
  168. package/dashboard/dist/assets/{ToolPill-CQCsVdzD.js → ToolPill-BRZWo4l8.js} +2 -2
  169. package/dashboard/dist/assets/{ToolPill-CQCsVdzD.js.map → ToolPill-BRZWo4l8.js.map} +1 -1
  170. package/dashboard/dist/assets/{ToolTestPanel-DkMgCB-k.js → ToolTestPanel-Dw8Zu6xr.js} +2 -2
  171. package/dashboard/dist/assets/{ToolTestPanel-DkMgCB-k.js.map → ToolTestPanel-Dw8Zu6xr.js.map} +1 -1
  172. package/dashboard/dist/assets/{TopicDetailPage-g3pljKKX.js → TopicDetailPage-DPMAWKTN.js} +4 -4
  173. package/dashboard/dist/assets/{TopicDetailPage-g3pljKKX.js.map → TopicDetailPage-DPMAWKTN.js.map} +1 -1
  174. package/dashboard/dist/assets/{TopicsPage-CVcCYdy-.js → TopicsPage-0Z2lAE0d.js} +2 -2
  175. package/dashboard/dist/assets/{TopicsPage-CVcCYdy-.js.map → TopicsPage-0Z2lAE0d.js.map} +1 -1
  176. package/dashboard/dist/assets/{UserName-D6zGIK2i.js → UserName-DrAbCpdY.js} +2 -2
  177. package/dashboard/dist/assets/{UserName-D6zGIK2i.js.map → UserName-DrAbCpdY.js.map} +1 -1
  178. package/dashboard/dist/assets/WorkflowExecutionPage-DQITqX-6.js +2 -0
  179. package/dashboard/dist/assets/{WorkflowExecutionPage-B8g81FCJ.js.map → WorkflowExecutionPage-DQITqX-6.js.map} +1 -1
  180. package/dashboard/dist/assets/{WorkflowPill-Dg7BDTyM.js → WorkflowPill-Cly9Ln_3.js} +2 -2
  181. package/dashboard/dist/assets/{WorkflowPill-Dg7BDTyM.js.map → WorkflowPill-Cly9Ln_3.js.map} +1 -1
  182. package/dashboard/dist/assets/{WorkflowsDashboard-nxT3bv6W.js → WorkflowsDashboard-CMJPiR6G.js} +2 -2
  183. package/dashboard/dist/assets/{WorkflowsDashboard-nxT3bv6W.js.map → WorkflowsDashboard-CMJPiR6G.js.map} +1 -1
  184. package/dashboard/dist/assets/{WorkflowsOverview-grI-KAI2.js → WorkflowsOverview-DwVMLe1y.js} +2 -2
  185. package/dashboard/dist/assets/{WorkflowsOverview-grI-KAI2.js.map → WorkflowsOverview-DwVMLe1y.js.map} +1 -1
  186. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BoZ-hfBE.js → YamlWorkflowDetailPage-Do6s_wmW.js} +12 -12
  187. package/dashboard/dist/assets/{YamlWorkflowDetailPage-BoZ-hfBE.js.map → YamlWorkflowDetailPage-Do6s_wmW.js.map} +1 -1
  188. package/dashboard/dist/assets/{YamlWorkflowsPage-Bf04rwRv.js → YamlWorkflowsPage-8Sr6rZMZ.js} +2 -2
  189. package/dashboard/dist/assets/{YamlWorkflowsPage-Bf04rwRv.js.map → YamlWorkflowsPage-8Sr6rZMZ.js.map} +1 -1
  190. package/dashboard/dist/assets/{agents-Dphpdi8l.js → agents-Maom-dbf.js} +2 -2
  191. package/dashboard/dist/assets/{agents-Dphpdi8l.js.map → agents-Maom-dbf.js.map} +1 -1
  192. package/dashboard/dist/assets/{bots-DIFE298x.js → bots-BESWftTA.js} +2 -2
  193. package/dashboard/dist/assets/{bots-DIFE298x.js.map → bots-BESWftTA.js.map} +1 -1
  194. package/dashboard/dist/assets/{capabilities-D7Y7LClY.js → capabilities-BnvJAmFQ.js} +2 -2
  195. package/dashboard/dist/assets/{capabilities-D7Y7LClY.js.map → capabilities-BnvJAmFQ.js.map} +1 -1
  196. package/dashboard/dist/assets/{controlplane-D1TGcYsS.js → controlplane-Cu7TD1RX.js} +2 -2
  197. package/dashboard/dist/assets/{controlplane-D1TGcYsS.js.map → controlplane-Cu7TD1RX.js.map} +1 -1
  198. package/dashboard/dist/assets/escalation-columns-BPSH8qMx.js +2 -0
  199. package/dashboard/dist/assets/escalation-columns-BPSH8qMx.js.map +1 -0
  200. package/dashboard/dist/assets/escalation-items-uDQTphVW.js +2 -0
  201. package/dashboard/dist/assets/escalation-items-uDQTphVW.js.map +1 -0
  202. package/dashboard/dist/assets/index-AJNPDsTI.js +2 -0
  203. package/dashboard/dist/assets/{index-CxdjT1Yk.js.map → index-AJNPDsTI.js.map} +1 -1
  204. package/dashboard/dist/assets/{index-ag2pCAPu.js → index-B4SNhwgt.js} +2 -2
  205. package/dashboard/dist/assets/{index-ag2pCAPu.js.map → index-B4SNhwgt.js.map} +1 -1
  206. package/dashboard/dist/assets/{index-BzYcUPdD.js → index-BG7OpNg7.js} +2 -2
  207. package/dashboard/dist/assets/{index-BzYcUPdD.js.map → index-BG7OpNg7.js.map} +1 -1
  208. package/dashboard/dist/assets/index-BLbZsMRG.js +67 -0
  209. package/dashboard/dist/assets/index-BLbZsMRG.js.map +1 -0
  210. package/dashboard/dist/assets/{index-DpKOr311.js → index-BLlg1aVG.js} +2 -2
  211. package/dashboard/dist/assets/{index-DpKOr311.js.map → index-BLlg1aVG.js.map} +1 -1
  212. package/dashboard/dist/assets/{index-Dl_8hbYI.js → index-BkVarz6E.js} +2 -2
  213. package/dashboard/dist/assets/{index-Dl_8hbYI.js.map → index-BkVarz6E.js.map} +1 -1
  214. package/dashboard/dist/assets/{index-Dy1wWu2e.js → index-BpWutGxS.js} +2 -2
  215. package/dashboard/dist/assets/{index-Dy1wWu2e.js.map → index-BpWutGxS.js.map} +1 -1
  216. package/dashboard/dist/assets/{index-DAvi5_2T.js → index-BvI2_dSt.js} +2 -2
  217. package/dashboard/dist/assets/{index-DAvi5_2T.js.map → index-BvI2_dSt.js.map} +1 -1
  218. package/dashboard/dist/assets/index-CnU7Jjz3.css +1 -0
  219. package/dashboard/dist/assets/{index-HLu98Sqh.js → index-D5JQweUm.js} +2 -2
  220. package/dashboard/dist/assets/{index-HLu98Sqh.js.map → index-D5JQweUm.js.map} +1 -1
  221. package/dashboard/dist/assets/{index-DN-kX7hL.js → index-WA8py2Yc.js} +2 -2
  222. package/dashboard/dist/assets/{index-DN-kX7hL.js.map → index-WA8py2Yc.js.map} +1 -1
  223. package/dashboard/dist/assets/{index-ChV7pBjM.js → index-_yHsJJTS.js} +2 -2
  224. package/dashboard/dist/assets/{index-ChV7pBjM.js.map → index-_yHsJJTS.js.map} +1 -1
  225. package/dashboard/dist/assets/index-kGSUZCOb.js +3 -0
  226. package/dashboard/dist/assets/index-kGSUZCOb.js.map +1 -0
  227. package/dashboard/dist/assets/index-qY2KDGkM.js +13 -0
  228. package/dashboard/dist/assets/{index-gkxPN7Vx.js.map → index-qY2KDGkM.js.map} +1 -1
  229. package/dashboard/dist/assets/{knowledge-DnMs-SOJ.js → knowledge-DCFRNG8R.js} +2 -2
  230. package/dashboard/dist/assets/{knowledge-DnMs-SOJ.js.map → knowledge-DCFRNG8R.js.map} +1 -1
  231. package/dashboard/dist/assets/{mcp-CwW-K3r4.js → mcp-CZhOocmN.js} +2 -2
  232. package/dashboard/dist/assets/{mcp-CwW-K3r4.js.map → mcp-CZhOocmN.js.map} +1 -1
  233. package/dashboard/dist/assets/{mcp-query-BZt5e8_Q.js → mcp-query-Wt8z6yAL.js} +2 -2
  234. package/dashboard/dist/assets/{mcp-query-BZt5e8_Q.js.map → mcp-query-Wt8z6yAL.js.map} +1 -1
  235. package/dashboard/dist/assets/{personas-UA-Xn60f.js → personas-D2_foqJm.js} +2 -2
  236. package/dashboard/dist/assets/{personas-UA-Xn60f.js.map → personas-D2_foqJm.js.map} +1 -1
  237. package/dashboard/dist/assets/{pipelines-Cu3PARum.js → pipelines-Bb159fNz.js} +2 -2
  238. package/dashboard/dist/assets/{pipelines-Cu3PARum.js.map → pipelines-Bb159fNz.js.map} +1 -1
  239. package/dashboard/dist/assets/{tasks-BO6h8GJE.js → tasks-xAU6C6tb.js} +2 -2
  240. package/dashboard/dist/assets/{tasks-BO6h8GJE.js.map → tasks-xAU6C6tb.js.map} +1 -1
  241. package/dashboard/dist/assets/{topics-CWjCR-17.js → topics-DFdqb2Te.js} +2 -2
  242. package/dashboard/dist/assets/{topics-CWjCR-17.js.map → topics-DFdqb2Te.js.map} +1 -1
  243. package/dashboard/dist/assets/{useDebouncedValue-6t0jx1RB.js → useDebouncedValue-CbHmpS4w.js} +2 -2
  244. package/dashboard/dist/assets/{useDebouncedValue-6t0jx1RB.js.map → useDebouncedValue-CbHmpS4w.js.map} +1 -1
  245. package/dashboard/dist/assets/{useNamespace-CqpoQx6D.js → useNamespace-B_00X1yb.js} +2 -2
  246. package/dashboard/dist/assets/{useNamespace-CqpoQx6D.js.map → useNamespace-B_00X1yb.js.map} +1 -1
  247. package/dashboard/dist/assets/{useYamlActivityEvents-hmCQQwzB.js → useYamlActivityEvents-B4F-s9g0.js} +2 -2
  248. package/dashboard/dist/assets/{useYamlActivityEvents-hmCQQwzB.js.map → useYamlActivityEvents-B4F-s9g0.js.map} +1 -1
  249. package/dashboard/dist/assets/{vendor-icons-CeVtUKyP.js → vendor-icons-C_DQEeBy.js} +2 -2
  250. package/dashboard/dist/assets/{vendor-icons-CeVtUKyP.js.map → vendor-icons-C_DQEeBy.js.map} +1 -1
  251. package/dashboard/dist/assets/{yaml-workflows-ziUdZhKY.js → yaml-workflows-DyjbPFVp.js} +2 -2
  252. package/dashboard/dist/assets/{yaml-workflows-ziUdZhKY.js.map → yaml-workflows-DyjbPFVp.js.map} +1 -1
  253. package/dashboard/dist/index.html +3 -3
  254. package/docs/code-owned-configuration.md +2 -2
  255. package/docs/domain-dictionary.md +19 -3
  256. package/docs/faceted-routing.md +15 -1
  257. package/docs/hitl/x-lt-display.md +1 -1
  258. package/docs/hitl/x-lt-embed.md +4 -1
  259. package/docs/hitl/x-lt-list-schema.md +19 -2
  260. package/docs/hitl/x-lt-roster.md +112 -0
  261. package/docs/hitl/x-lt-show-if.md +15 -0
  262. package/docs/hitl/x-lt-widget.md +1 -0
  263. package/docs/hitl-guide.md +3 -1
  264. package/docs/scan-codes.md +4 -0
  265. package/docs/schema-enforcement.md +5 -0
  266. package/package.json +2 -2
  267. package/dashboard/dist/assets/AvailableEscalationsPage-IS28XBRe.js +0 -2
  268. package/dashboard/dist/assets/CountdownTimer-LG03dVgR.js +0 -2
  269. package/dashboard/dist/assets/CountdownTimer-LG03dVgR.js.map +0 -1
  270. package/dashboard/dist/assets/EscalationTimeline-d3nvshOk.js +0 -2
  271. package/dashboard/dist/assets/McpRunDetailPage-bMXNO-6V.js +0 -2
  272. package/dashboard/dist/assets/OperatorDashboard-DctmZw10.js +0 -2
  273. package/dashboard/dist/assets/PortalPage-Dfc_Q02R.js +0 -2
  274. package/dashboard/dist/assets/ResolverForm-B1_x8Blv.js +0 -8
  275. package/dashboard/dist/assets/ResolverForm-B1_x8Blv.js.map +0 -1
  276. package/dashboard/dist/assets/ScanStationPage-DzGaXc40.js +0 -2
  277. package/dashboard/dist/assets/ScanStationPage-DzGaXc40.js.map +0 -1
  278. package/dashboard/dist/assets/WorkflowExecutionPage-B8g81FCJ.js +0 -2
  279. package/dashboard/dist/assets/escalation-columns-cwZE6xyo.js +0 -2
  280. package/dashboard/dist/assets/escalation-columns-cwZE6xyo.js.map +0 -1
  281. package/dashboard/dist/assets/index-CeCtqujG.js +0 -67
  282. package/dashboard/dist/assets/index-CeCtqujG.js.map +0 -1
  283. package/dashboard/dist/assets/index-CniRa65p.js +0 -3
  284. package/dashboard/dist/assets/index-CniRa65p.js.map +0 -1
  285. package/dashboard/dist/assets/index-CxdjT1Yk.js +0 -2
  286. package/dashboard/dist/assets/index-gkxPN7Vx.js +0 -13
  287. package/dashboard/dist/assets/index-m9A3UYst.css +0 -1
  288. package/dashboard/dist/assets/validate-BIRn4a6d.js +0 -2
  289. package/dashboard/dist/assets/validate-BIRn4a6d.js.map +0 -1
@@ -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,253 @@
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
+ /** A row's creation instant in ms; 0 when absent or unreadable. */
170
+ function createdAt(row) {
171
+ const raw = row.escalation.created_at;
172
+ const ms = raw instanceof Date ? raw.getTime() : typeof raw === 'string' ? Date.parse(raw) : NaN;
173
+ return Number.isNaN(ms) ? 0 : ms;
174
+ }
175
+ /**
176
+ * The expected keys in order, each with its member row (query) or label
177
+ * (batch). Several rows sharing a key (a member that parked again) read as
178
+ * one entry on the newest row, so its state and actions follow the live row.
179
+ */
180
+ function expectedEntries(def, ctx, rows) {
181
+ const seen = new Set();
182
+ const out = [];
183
+ const push = (key, extra = {}) => {
184
+ if (!key || key === MISSING || seen.has(key))
185
+ return;
186
+ seen.add(key);
187
+ out.push({ key, ...extra });
188
+ };
189
+ const e = def.expected;
190
+ if ('query' in e) {
191
+ const template = def.key ?? DEFAULT_KEY;
192
+ const newest = new Map();
193
+ for (const row of rows) {
194
+ const key = (0, x_lt_help_1.interpolateHelp)(template, row);
195
+ const held = newest.get(key);
196
+ if (!held || createdAt(row) > createdAt(held))
197
+ newest.set(key, row);
198
+ }
199
+ for (const row of rows) {
200
+ const key = (0, x_lt_help_1.interpolateHelp)(template, row);
201
+ push(key, { row: newest.get(key) });
202
+ }
203
+ }
204
+ else if ('list' in e) {
205
+ strings((0, ctx_path_1.resolveCtxPath)(e.list, ctx)).forEach((k) => push(k));
206
+ }
207
+ else {
208
+ const labels = e.labels ? (0, ctx_path_1.resolveCtxPath)(e.labels, ctx) : undefined;
209
+ for (const key of strings(ctx.metadata?.[BATCH_KEYS])) {
210
+ push(key, isRecord(labels) && key in labels ? { label: labels[key] } : {});
211
+ }
212
+ }
213
+ return out;
214
+ }
215
+ /**
216
+ * Every expected entry with its state, and the counts. `rows` are the
217
+ * member rows a query set read (ignored for list and batch sets). `ctx` is
218
+ * the host row's context with the live form values under `resolver`.
219
+ */
220
+ function computeRoster(def, ctx, rows = []) {
221
+ const arrived = arrivedKeys(def, ctx);
222
+ const entries = expectedEntries(def, ctx, rows).map((e) => {
223
+ if (arrived.has(e.key))
224
+ return { ...e, state: exports.ROSTER_STATES.IN };
225
+ const flag = flagFor(def, e.row);
226
+ return flag ? { ...e, state: exports.ROSTER_STATES.FLAGGED, flag } : { ...e, state: exports.ROSTER_STATES.WAITING };
227
+ });
228
+ const count = (s) => entries.filter((e) => e.state === s).length;
229
+ const waiting = count(exports.ROSTER_STATES.WAITING);
230
+ return {
231
+ entries,
232
+ counts: {
233
+ expected: entries.length,
234
+ in: count(exports.ROSTER_STATES.IN),
235
+ flagged: count(exports.ROSTER_STATES.FLAGGED),
236
+ waiting,
237
+ outstanding: waiting,
238
+ },
239
+ };
240
+ }
241
+ /** The header line: "3 of 5 in · 1 Missing". */
242
+ function rosterHeadline(result) {
243
+ const { counts } = result;
244
+ const parts = [`${counts.in} of ${counts.expected} in`];
245
+ const byFlag = new Map();
246
+ for (const e of result.entries) {
247
+ if (e.state === exports.ROSTER_STATES.FLAGGED && e.flag)
248
+ byFlag.set(e.flag, (byFlag.get(e.flag) ?? 0) + 1);
249
+ }
250
+ for (const [flag, n] of byFlag)
251
+ parts.push(`${n} ${flag}`);
252
+ return parts.join(' · ');
253
+ }
@@ -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;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isExtremeAggregate = isExtremeAggregate;
4
+ exports.relatedValuePath = relatedValuePath;
5
+ exports.relatedAggregateKey = relatedAggregateKey;
6
+ exports.relatedCountText = relatedCountText;
7
+ exports.foldExtreme = foldExtreme;
8
+ const types_1 = require("./types");
9
+ const VALUE_TOKEN = /^\{\{\s*([^{}]+?)\s*\}\}$/;
10
+ const ITEM_PREFIX = 'item.';
11
+ const PATH_SEGMENT = /^[a-zA-Z0-9_]+$/;
12
+ const METADATA_KEY = /^[a-zA-Z0-9_]+$/;
13
+ const COUNT_TOKEN = /\{n\}/g;
14
+ /** True for the aggregates that pick one value rather than count. */
15
+ function isExtremeAggregate(aggregate) {
16
+ return aggregate === types_1.RELATED_AGGREGATES.MIN || aggregate === types_1.RELATED_AGGREGATES.MAX;
17
+ }
18
+ /**
19
+ * The stored path a min/max `value` template reads: `payload.<path>` for an
20
+ * items set, `metadata.<key>` for a query set. Null when the template does
21
+ * not fit the set's source.
22
+ */
23
+ function relatedValuePath(source, value) {
24
+ if (typeof value !== 'string')
25
+ return null;
26
+ const token = value.match(VALUE_TOKEN)?.[1];
27
+ if (!token)
28
+ return null;
29
+ if (source === types_1.RELATED_SOURCES.ITEMS) {
30
+ if (!token.startsWith(`${ITEM_PREFIX}${types_1.SPLIT_PATHS.PAYLOAD}`))
31
+ return null;
32
+ const path = token.slice(ITEM_PREFIX.length + types_1.SPLIT_PATHS.PAYLOAD.length);
33
+ return path && path.split('.').every((s) => PATH_SEGMENT.test(s)) ? `${types_1.SPLIT_PATHS.PAYLOAD}${path}` : null;
34
+ }
35
+ if (!token.startsWith(types_1.SPLIT_PATHS.METADATA))
36
+ return null;
37
+ const key = token.slice(types_1.SPLIT_PATHS.METADATA.length);
38
+ return METADATA_KEY.test(key) ? token : null;
39
+ }
40
+ /** The key a column's per-host aggregates are stored under in its set's result. */
41
+ function relatedAggregateKey(col, source) {
42
+ if (isExtremeAggregate(col.aggregate))
43
+ return `${col.aggregate}:${relatedValuePath(source, col.value) ?? ''}`;
44
+ return col.splitBy ?? '';
45
+ }
46
+ /** A count column's display text, or null when the column declares none for this count. */
47
+ function relatedCountText(display, count) {
48
+ if (!display)
49
+ return null;
50
+ const text = display[String(count)] ?? display[types_1.RELATED_DISPLAY_DEFAULT];
51
+ return text === undefined ? null : text.replace(COUNT_TOKEN, String(count));
52
+ }
53
+ /**
54
+ * The least or greatest of several values: numbers when every value is a
55
+ * number, otherwise text in code-unit order (ISO instants order as text).
56
+ */
57
+ function foldExtreme(fold, values) {
58
+ if (!values.length)
59
+ return undefined;
60
+ const pickMin = fold === types_1.RELATED_AGGREGATES.MIN;
61
+ if (values.every((v) => typeof v === 'number')) {
62
+ return pickMin ? Math.min(...values) : Math.max(...values);
63
+ }
64
+ const texts = values.map(String).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
65
+ return pickMin ? texts[0] : texts[texts.length - 1];
66
+ }
@@ -1,3 +1,5 @@
1
1
  export * from './types';
2
2
  export { METADATA_KEY, readListSchemaRelations, listSchemaRelationsError, splitPathError } from './validate';
3
3
  export { rowTemplateContext, resolveTemplateValue, resolveRelatedFacets } from './template';
4
+ export type { RelatedExtreme } from './aggregate';
5
+ export { isExtremeAggregate, relatedValuePath, relatedAggregateKey, relatedCountText, foldExtreme } from './aggregate';
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.resolveRelatedFacets = exports.resolveTemplateValue = exports.rowTemplateContext = exports.splitPathError = exports.listSchemaRelationsError = exports.readListSchemaRelations = exports.METADATA_KEY = void 0;
17
+ exports.foldExtreme = exports.relatedCountText = exports.relatedAggregateKey = exports.relatedValuePath = exports.isExtremeAggregate = exports.resolveRelatedFacets = exports.resolveTemplateValue = exports.rowTemplateContext = exports.splitPathError = exports.listSchemaRelationsError = exports.readListSchemaRelations = exports.METADATA_KEY = void 0;
18
18
  __exportStar(require("./types"), exports);
19
19
  var validate_1 = require("./validate");
20
20
  Object.defineProperty(exports, "METADATA_KEY", { enumerable: true, get: function () { return validate_1.METADATA_KEY; } });
@@ -25,3 +25,9 @@ var template_1 = require("./template");
25
25
  Object.defineProperty(exports, "rowTemplateContext", { enumerable: true, get: function () { return template_1.rowTemplateContext; } });
26
26
  Object.defineProperty(exports, "resolveTemplateValue", { enumerable: true, get: function () { return template_1.resolveTemplateValue; } });
27
27
  Object.defineProperty(exports, "resolveRelatedFacets", { enumerable: true, get: function () { return template_1.resolveRelatedFacets; } });
28
+ var aggregate_1 = require("./aggregate");
29
+ Object.defineProperty(exports, "isExtremeAggregate", { enumerable: true, get: function () { return aggregate_1.isExtremeAggregate; } });
30
+ Object.defineProperty(exports, "relatedValuePath", { enumerable: true, get: function () { return aggregate_1.relatedValuePath; } });
31
+ Object.defineProperty(exports, "relatedAggregateKey", { enumerable: true, get: function () { return aggregate_1.relatedAggregateKey; } });
32
+ Object.defineProperty(exports, "relatedCountText", { enumerable: true, get: function () { return aggregate_1.relatedCountText; } });
33
+ Object.defineProperty(exports, "foldExtreme", { enumerable: true, get: function () { return aggregate_1.foldExtreme; } });
@@ -23,6 +23,9 @@ export declare const RELATED_SOURCES: {
23
23
  export type RelatedSource = (typeof RELATED_SOURCES)[keyof typeof RELATED_SOURCES];
24
24
  export declare const RELATED_AGGREGATES: {
25
25
  readonly COUNT: "count";
26
+ /** The least item or row value: numbers as numbers, everything else as text. */
27
+ readonly MIN: "min";
28
+ readonly MAX: "max";
26
29
  };
27
30
  export type RelatedAggregate = (typeof RELATED_AGGREGATES)[keyof typeof RELATED_AGGREGATES];
28
31
  /** How a grouped table folds a plain column across a group's rows. */
@@ -73,10 +76,18 @@ export interface RelatedSetDecl {
73
76
  source: RelatedSource;
74
77
  query?: RelatedQueryDecl;
75
78
  }
79
+ /** A count column's text keyed by count; `default` covers the rest, `{n}` reads the count. */
80
+ export declare const RELATED_DISPLAY_DEFAULT = "default";
76
81
  export interface RelatedColumnDecl {
77
82
  label: string;
78
83
  related: string;
79
84
  aggregate?: RelatedAggregate;
85
+ /** min/max: `{{item.payload.<path>}}` on an items set, `{{metadata.<key>}}` on a query set. */
86
+ value?: string;
87
+ /** min/max: how the value renders, as on any facet-table column. */
88
+ format?: string;
89
+ /** count: text by count, e.g. `{ "0": "Ready", "default": "Waiting on {n}" }`. */
90
+ display?: Record<string, string>;
80
91
  splitBy?: string;
81
92
  labels?: Record<string, string>;
82
93
  priority?: 1 | 2 | 3;
@@ -103,9 +114,11 @@ export interface ListSchemaRelations {
103
114
  /** The metadata key a facet-table groups by, when declared. */
104
115
  groupKey: string | null;
105
116
  }
106
- /** Per-host aggregate for one (set, splitBy) pair. */
117
+ /** Per-host aggregate for one (set, splitBy) pair, or one (set, min/max, value) triple. */
107
118
  export interface RelatedHostAggregate {
108
119
  count: number;
120
+ /** min/max: the extreme value among `count` values; absent when none carries one. */
121
+ value?: string | number;
109
122
  /** Split value to count; a null value is keyed by the empty string. */
110
123
  splits?: Record<string, number>;
111
124
  /** Items whose reciprocal row the viewer cannot read. */
@@ -125,7 +138,7 @@ export interface RelatedSetResult {
125
138
  roleLabels?: Record<string, string>;
126
139
  /** Query sets: declared roles outside the viewer's full read scope. */
127
140
  restricted?: string[];
128
- /** Keyed by splitBy ('' when unsplit), then host id. */
141
+ /** Keyed by relatedAggregateKey (the splitBy, '' when unsplit, or `min:<path>`), then host id. */
129
142
  aggregates: Record<string, Record<string, RelatedHostAggregate>>;
130
143
  }
131
144
  export interface RelatedAggregatesResponse {