@hotmeshio/long-tail 0.10.13 → 0.10.14

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 (246) hide show
  1. package/README.md +2 -4
  2. package/build/api/escalations/metadata.js +1 -1
  3. package/build/api/escalations/resolve.js +4 -4
  4. package/build/services/escalation/resolver-validation.d.ts +1 -1
  5. package/build/services/escalation/resolver-validation.js +12 -5
  6. package/build/services/escalation/submit-guard.d.ts +29 -0
  7. package/build/services/escalation/submit-guard.js +57 -0
  8. package/build/shared/form-validation/index.d.ts +4 -0
  9. package/build/shared/form-validation/index.js +4 -0
  10. package/build/shared/form-validation/x-lt-labels.d.ts +28 -0
  11. package/build/shared/form-validation/x-lt-labels.js +42 -0
  12. package/build/shared/form-validation/x-lt-query.d.ts +56 -0
  13. package/build/shared/form-validation/x-lt-query.js +49 -0
  14. package/build/shared/form-validation/x-lt-submit-guard.d.ts +46 -0
  15. package/build/shared/form-validation/x-lt-submit-guard.js +25 -0
  16. package/build/shared/form-validation/x-lt-submit-on-claim.d.ts +22 -0
  17. package/build/shared/form-validation/x-lt-submit-on-claim.js +28 -0
  18. package/build/tsconfig.tsbuildinfo +1 -1
  19. package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js → AdminDashboard-Chg69wlx.js} +2 -2
  20. package/dashboard/dist/assets/{AdminDashboard-Bv3pHBzn.js.map → AdminDashboard-Chg69wlx.js.map} +1 -1
  21. package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js → AgentConfigPage-DRTFwbfC.js} +2 -2
  22. package/dashboard/dist/assets/{AgentConfigPage-Dk2zlvDb.js.map → AgentConfigPage-DRTFwbfC.js.map} +1 -1
  23. package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js → AgentDetailPage-JKByfFIi.js} +3 -3
  24. package/dashboard/dist/assets/{AgentDetailPage-DUno6EGs.js.map → AgentDetailPage-JKByfFIi.js.map} +1 -1
  25. package/dashboard/dist/assets/AgentsPage-BlgEmKhA.js +2 -0
  26. package/dashboard/dist/assets/{AgentsPage-CToVu1qj.js.map → AgentsPage-BlgEmKhA.js.map} +1 -1
  27. package/dashboard/dist/assets/AvailableEscalationsPage-C_7y692Q.js +2 -0
  28. package/dashboard/dist/assets/{AvailableEscalationsPage-DldboL4W.js.map → AvailableEscalationsPage-C_7y692Q.js.map} +1 -1
  29. package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js → BotPicker-CCVcz4Cq.js} +2 -2
  30. package/dashboard/dist/assets/{BotPicker-DQOpVB4M.js.map → BotPicker-CCVcz4Cq.js.map} +1 -1
  31. package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js → CapabilitiesPage-Czi9jUwD.js} +2 -2
  32. package/dashboard/dist/assets/{CapabilitiesPage-Dmf46PUJ.js.map → CapabilitiesPage-Czi9jUwD.js.map} +1 -1
  33. package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js → CollapsibleSection-8YE965QX.js} +2 -2
  34. package/dashboard/dist/assets/{CollapsibleSection-CDADefUY.js.map → CollapsibleSection-8YE965QX.js.map} +1 -1
  35. package/dashboard/dist/assets/CountdownTimer-Bxvq3D7j.js +2 -0
  36. package/dashboard/dist/assets/CountdownTimer-Bxvq3D7j.js.map +1 -0
  37. package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js → CredentialsPage-Bn7_SX6-.js} +2 -2
  38. package/dashboard/dist/assets/{CredentialsPage-8LIEvomi.js.map → CredentialsPage-Bn7_SX6-.js.map} +1 -1
  39. package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js → CronLabel-Bn4mX_Yn.js} +2 -2
  40. package/dashboard/dist/assets/{CronLabel-CK3WSsM5.js.map → CronLabel-Bn4mX_Yn.js.map} +1 -1
  41. package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js → CustomDurationPicker-pMcrFyW6.js} +2 -2
  42. package/dashboard/dist/assets/{CustomDurationPicker-FPmlA6cE.js.map → CustomDurationPicker-pMcrFyW6.js.map} +1 -1
  43. package/dashboard/dist/assets/{DropZone-CL9gA7pu.js → DropZone-zCEGjjk-.js} +2 -2
  44. package/dashboard/dist/assets/{DropZone-CL9gA7pu.js.map → DropZone-zCEGjjk-.js.map} +1 -1
  45. package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js → ElapsedCell-BGO7IXEg.js} +2 -2
  46. package/dashboard/dist/assets/{ElapsedCell-BZVkVxE0.js.map → ElapsedCell-BGO7IXEg.js.map} +1 -1
  47. package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js → EscalationListSchemaPage-CFDxbd50.js} +3 -3
  48. package/dashboard/dist/assets/{EscalationListSchemaPage-kYLdUtZX.js.map → EscalationListSchemaPage-CFDxbd50.js.map} +1 -1
  49. package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js → EscalationSchemaPage-DnXPnDkz.js} +3 -3
  50. package/dashboard/dist/assets/{EscalationSchemaPage-kUmCDivo.js.map → EscalationSchemaPage-DnXPnDkz.js.map} +1 -1
  51. package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js → EscalationsOverview-BZMVXrkK.js} +2 -2
  52. package/dashboard/dist/assets/{EscalationsOverview-D17auO-m.js.map → EscalationsOverview-BZMVXrkK.js.map} +1 -1
  53. package/dashboard/dist/assets/EventTable-Bfi-f8as.js +2 -0
  54. package/dashboard/dist/assets/EventTable-Bfi-f8as.js.map +1 -0
  55. package/dashboard/dist/assets/FilterBar-Do7yR4xM.js +2 -0
  56. package/dashboard/dist/assets/FilterBar-Do7yR4xM.js.map +1 -0
  57. package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js → GraphInvokePage-d1ie4T7f.js} +2 -2
  58. package/dashboard/dist/assets/{GraphInvokePage-D11uOnZi.js.map → GraphInvokePage-d1ie4T7f.js.map} +1 -1
  59. package/dashboard/dist/assets/{HomePage-Bcq10Bxx.js → HomePage-BEeodImU.js} +2 -2
  60. package/dashboard/dist/assets/{HomePage-Bcq10Bxx.js.map → HomePage-BEeodImU.js.map} +1 -1
  61. package/dashboard/dist/assets/{ListToolbar-IPXsTb3Q.js → ListToolbar-CLtw-1QN.js} +2 -2
  62. package/dashboard/dist/assets/{ListToolbar-IPXsTb3Q.js.map → ListToolbar-CLtw-1QN.js.map} +1 -1
  63. package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js → McpOverview-DIsy9TB3.js} +2 -2
  64. package/dashboard/dist/assets/{McpOverview-Dx2j0KkF.js.map → McpOverview-DIsy9TB3.js.map} +1 -1
  65. package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js → McpQueryDetailPage-6PomdsyD.js} +2 -2
  66. package/dashboard/dist/assets/{McpQueryDetailPage-CzF_bna8.js.map → McpQueryDetailPage-6PomdsyD.js.map} +1 -1
  67. package/dashboard/dist/assets/McpQueryPage-YMdQCXm9.js +2 -0
  68. package/dashboard/dist/assets/{McpQueryPage-CNsuiw_q.js.map → McpQueryPage-YMdQCXm9.js.map} +1 -1
  69. package/dashboard/dist/assets/McpRunDetailPage-DsD1Gm2o.js +2 -0
  70. package/dashboard/dist/assets/McpRunDetailPage-DsD1Gm2o.js.map +1 -0
  71. package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js → McpRunsPage--a5Jgb33.js} +2 -2
  72. package/dashboard/dist/assets/{McpRunsPage-CK96s3Nt.js.map → McpRunsPage--a5Jgb33.js.map} +1 -1
  73. package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js → NamespacePill-wV6L4VW1.js} +2 -2
  74. package/dashboard/dist/assets/{NamespacePill-B9Vc_Pz2.js.map → NamespacePill-wV6L4VW1.js.map} +1 -1
  75. package/dashboard/dist/assets/OperationsPage-B2v9k3DT.js +2 -0
  76. package/dashboard/dist/assets/{OperationsPage-DvWrLuH6.js.map → OperationsPage-B2v9k3DT.js.map} +1 -1
  77. package/dashboard/dist/assets/OperatorDashboard-CkLfbxEh.js +2 -0
  78. package/dashboard/dist/assets/{OperatorDashboard-C-jE0IRA.js.map → OperatorDashboard-CkLfbxEh.js.map} +1 -1
  79. package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js → PageHeader-BtIr6r-8.js} +2 -2
  80. package/dashboard/dist/assets/{PageHeader-Ce4GcIYo.js.map → PageHeader-BtIr6r-8.js.map} +1 -1
  81. package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js → PageHeaderWithStats-C2sGqFQG.js} +2 -2
  82. package/dashboard/dist/assets/{PageHeaderWithStats-Ck0KZvXD.js.map → PageHeaderWithStats-C2sGqFQG.js.map} +1 -1
  83. package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js → PersonaDetailPage-CCmOgKQb.js} +2 -2
  84. package/dashboard/dist/assets/{PersonaDetailPage-CJ6jqo7h.js.map → PersonaDetailPage-CCmOgKQb.js.map} +1 -1
  85. package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js → PersonasPage-BJkSuDTN.js} +2 -2
  86. package/dashboard/dist/assets/{PersonasPage-D8hL3kL5.js.map → PersonasPage-BJkSuDTN.js.map} +1 -1
  87. package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js → ProcessDetailPage-DT9BlJXK.js} +2 -2
  88. package/dashboard/dist/assets/{ProcessDetailPage-Vnx8Z5_y.js.map → ProcessDetailPage-DT9BlJXK.js.map} +1 -1
  89. package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js → ProcessesListPage-DgSGzTDT.js} +2 -2
  90. package/dashboard/dist/assets/{ProcessesListPage-DRYtvS3N.js.map → ProcessesListPage-DgSGzTDT.js.map} +1 -1
  91. package/dashboard/dist/assets/{RoleDetailPage-BKkUvTO-.js → RoleDetailPage-DMphTvro.js} +2 -2
  92. package/dashboard/dist/assets/{RoleDetailPage-BKkUvTO-.js.map → RoleDetailPage-DMphTvro.js.map} +1 -1
  93. package/dashboard/dist/assets/{RolePill-CnuBPhPw.js → RolePill-BBYjhAPj.js} +2 -2
  94. package/dashboard/dist/assets/{RolePill-CnuBPhPw.js.map → RolePill-BBYjhAPj.js.map} +1 -1
  95. package/dashboard/dist/assets/{RolesPage-BHzWK9n6.js → RolesPage-gi_kaot1.js} +2 -2
  96. package/dashboard/dist/assets/{RolesPage-BHzWK9n6.js.map → RolesPage-gi_kaot1.js.map} +1 -1
  97. package/dashboard/dist/assets/RunAsSelector-CateuvcC.js +2 -0
  98. package/dashboard/dist/assets/{RunAsSelector-CS3KQ-BF.js.map → RunAsSelector-CateuvcC.js.map} +1 -1
  99. package/dashboard/dist/assets/{ScanCodesPage-BW4P4zWf.js → ScanCodesPage-CQ8RxMug.js} +2 -2
  100. package/dashboard/dist/assets/{ScanCodesPage-BW4P4zWf.js.map → ScanCodesPage-CQ8RxMug.js.map} +1 -1
  101. package/dashboard/dist/assets/{ScanSchemeDetailPage-BLykA4j-.js → ScanSchemeDetailPage-puSbuxcV.js} +2 -2
  102. package/dashboard/dist/assets/{ScanSchemeDetailPage-BLykA4j-.js.map → ScanSchemeDetailPage-puSbuxcV.js.map} +1 -1
  103. package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js → ScopeBadge-xs2Nhjy4.js} +2 -2
  104. package/dashboard/dist/assets/{ScopeBadge-BUpYpS3x.js.map → ScopeBadge-xs2Nhjy4.js.map} +1 -1
  105. package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js +2 -0
  106. package/dashboard/dist/assets/SegmentedTabs-DXNzY05q.js.map +1 -0
  107. package/dashboard/dist/assets/StickyPagination-Cg-QdYWL.js +2 -0
  108. package/dashboard/dist/assets/StickyPagination-Cg-QdYWL.js.map +1 -0
  109. package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js → StreamMessageDetail-DEeuh4_-.js} +2 -2
  110. package/dashboard/dist/assets/{StreamMessageDetail-DyJyZwBl.js.map → StreamMessageDetail-DEeuh4_-.js.map} +1 -1
  111. package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js → SwimlaneTimeline-DMY0jL2F.js} +2 -2
  112. package/dashboard/dist/assets/{SwimlaneTimeline-BlzV74V5.js.map → SwimlaneTimeline-DMY0jL2F.js.map} +1 -1
  113. package/dashboard/dist/assets/{TagInput-BbZ25nNe.js → TagInput-BMmiV-MD.js} +2 -2
  114. package/dashboard/dist/assets/{TagInput-BbZ25nNe.js.map → TagInput-BMmiV-MD.js.map} +1 -1
  115. package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js → TaskDetailPage-CPbkIvfF.js} +2 -2
  116. package/dashboard/dist/assets/{TaskDetailPage-B0p_Z4J_.js.map → TaskDetailPage-CPbkIvfF.js.map} +1 -1
  117. package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js → TaskQueuePill-DLgYaw1x.js} +2 -2
  118. package/dashboard/dist/assets/{TaskQueuePill-D0QKBrN3.js.map → TaskQueuePill-DLgYaw1x.js.map} +1 -1
  119. package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js → TasksListPage-CtHudKhQ.js} +2 -2
  120. package/dashboard/dist/assets/{TasksListPage-CiGR2QiQ.js.map → TasksListPage-CtHudKhQ.js.map} +1 -1
  121. package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js → TimeAgo-BdHOizWg.js} +2 -2
  122. package/dashboard/dist/assets/{TimeAgo-D_DA9ucC.js.map → TimeAgo-BdHOizWg.js.map} +1 -1
  123. package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js → TimestampCell-FVukzKRe.js} +2 -2
  124. package/dashboard/dist/assets/{TimestampCell-C7rkC9nh.js.map → TimestampCell-FVukzKRe.js.map} +1 -1
  125. package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js → ToolPill-BvS53hxP.js} +2 -2
  126. package/dashboard/dist/assets/{ToolPill-8xY9rkoc.js.map → ToolPill-BvS53hxP.js.map} +1 -1
  127. package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js → ToolTestPanel-HN0OCYTL.js} +2 -2
  128. package/dashboard/dist/assets/{ToolTestPanel-E8efYGYs.js.map → ToolTestPanel-HN0OCYTL.js.map} +1 -1
  129. package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js → TopicDetailPage-DHdSpN61.js} +4 -4
  130. package/dashboard/dist/assets/{TopicDetailPage-B455XrRc.js.map → TopicDetailPage-DHdSpN61.js.map} +1 -1
  131. package/dashboard/dist/assets/{TopicsPage-1VAc29Qw.js → TopicsPage-Clr6Tl5P.js} +2 -2
  132. package/dashboard/dist/assets/{TopicsPage-1VAc29Qw.js.map → TopicsPage-Clr6Tl5P.js.map} +1 -1
  133. package/dashboard/dist/assets/{UserName-DikzjQHJ.js → UserName-BUVYyIAS.js} +2 -2
  134. package/dashboard/dist/assets/{UserName-DikzjQHJ.js.map → UserName-BUVYyIAS.js.map} +1 -1
  135. package/dashboard/dist/assets/WorkflowExecutionPage-kncWFfe5.js +2 -0
  136. package/dashboard/dist/assets/WorkflowExecutionPage-kncWFfe5.js.map +1 -0
  137. package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js → WorkflowPill-BPC_Dc_I.js} +2 -2
  138. package/dashboard/dist/assets/{WorkflowPill-Da406nEj.js.map → WorkflowPill-BPC_Dc_I.js.map} +1 -1
  139. package/dashboard/dist/assets/WorkflowsDashboard-4ypPDGKx.js +2 -0
  140. package/dashboard/dist/assets/{WorkflowsDashboard-BMQd_0tW.js.map → WorkflowsDashboard-4ypPDGKx.js.map} +1 -1
  141. package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js → WorkflowsOverview-CeQlZkkd.js} +2 -2
  142. package/dashboard/dist/assets/{WorkflowsOverview-CdxjVifp.js.map → WorkflowsOverview-CeQlZkkd.js.map} +1 -1
  143. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js → YamlWorkflowDetailPage-DLAlEzwT.js} +10 -10
  144. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DNVffIXa.js.map → YamlWorkflowDetailPage-DLAlEzwT.js.map} +1 -1
  145. package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js → YamlWorkflowsPage-DQhenKFT.js} +2 -2
  146. package/dashboard/dist/assets/{YamlWorkflowsPage-BGP8wuos.js.map → YamlWorkflowsPage-DQhenKFT.js.map} +1 -1
  147. package/dashboard/dist/assets/{agents-BZJLIJ4h.js → agents-s3feet3W.js} +2 -2
  148. package/dashboard/dist/assets/{agents-BZJLIJ4h.js.map → agents-s3feet3W.js.map} +1 -1
  149. package/dashboard/dist/assets/{bots-ClLcDGJb.js → bots-CkSd2rn9.js} +2 -2
  150. package/dashboard/dist/assets/{bots-ClLcDGJb.js.map → bots-CkSd2rn9.js.map} +1 -1
  151. package/dashboard/dist/assets/capabilities-DA_r09tM.js +2 -0
  152. package/dashboard/dist/assets/{capabilities-IaCcS7ge.js.map → capabilities-DA_r09tM.js.map} +1 -1
  153. package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js → controlplane-C9c25q21.js} +2 -2
  154. package/dashboard/dist/assets/{controlplane-Zi4m_MSx.js.map → controlplane-C9c25q21.js.map} +1 -1
  155. package/dashboard/dist/assets/{escalation-columns-BY2mg9DY.js → escalation-columns-Cp3UrT48.js} +2 -2
  156. package/dashboard/dist/assets/{escalation-columns-BY2mg9DY.js.map → escalation-columns-Cp3UrT48.js.map} +1 -1
  157. package/dashboard/dist/assets/{index-CJu2PBNx.js → index--7Vdkzwd.js} +2 -2
  158. package/dashboard/dist/assets/{index-CJu2PBNx.js.map → index--7Vdkzwd.js.map} +1 -1
  159. package/dashboard/dist/assets/{index-CfAi1OsI.js → index--DG-qQBT.js} +26 -26
  160. package/dashboard/dist/assets/index--DG-qQBT.js.map +1 -0
  161. package/dashboard/dist/assets/{index-CmnNqpWg.js → index-BIcYbDVf.js} +2 -2
  162. package/dashboard/dist/assets/{index-CmnNqpWg.js.map → index-BIcYbDVf.js.map} +1 -1
  163. package/dashboard/dist/assets/index-BU5FFAJo.js +2 -0
  164. package/dashboard/dist/assets/{index-CLmZaNTK.js.map → index-BU5FFAJo.js.map} +1 -1
  165. package/dashboard/dist/assets/{index-yGNt29V9.js → index-Bo5TtX9l.js} +2 -2
  166. package/dashboard/dist/assets/{index-yGNt29V9.js.map → index-Bo5TtX9l.js.map} +1 -1
  167. package/dashboard/dist/assets/{index-BqGnhkh0.js → index-C-MmR-jf.js} +2 -2
  168. package/dashboard/dist/assets/{index-BqGnhkh0.js.map → index-C-MmR-jf.js.map} +1 -1
  169. package/dashboard/dist/assets/{index-BzkE48xJ.js → index-C7ABSOU2.js} +2 -2
  170. package/dashboard/dist/assets/{index-BzkE48xJ.js.map → index-C7ABSOU2.js.map} +1 -1
  171. package/dashboard/dist/assets/index-Cmxzk4ay.js +5 -0
  172. package/dashboard/dist/assets/{index-CvNBdkB1.js.map → index-Cmxzk4ay.js.map} +1 -1
  173. package/dashboard/dist/assets/{index-C3o4OisO.js → index-Cw9poaez.js} +2 -2
  174. package/dashboard/dist/assets/{index-C3o4OisO.js.map → index-Cw9poaez.js.map} +1 -1
  175. package/dashboard/dist/assets/index-DEbY57_c.js +3 -0
  176. package/dashboard/dist/assets/index-DEbY57_c.js.map +1 -0
  177. package/dashboard/dist/assets/index-DnV6LSeY.css +1 -0
  178. package/dashboard/dist/assets/{index-D0zFReGL.js → index-DvoMXQqO.js} +2 -2
  179. package/dashboard/dist/assets/{index-D0zFReGL.js.map → index-DvoMXQqO.js.map} +1 -1
  180. package/dashboard/dist/assets/{index-kiKZresb.js → index-S13oPvuS.js} +2 -2
  181. package/dashboard/dist/assets/{index-kiKZresb.js.map → index-S13oPvuS.js.map} +1 -1
  182. package/dashboard/dist/assets/index-WxE3ONia.js +2 -0
  183. package/dashboard/dist/assets/{index-Dldi3Q3M.js.map → index-WxE3ONia.js.map} +1 -1
  184. package/dashboard/dist/assets/{knowledge-DWLxGTib.js → knowledge-Bpln0zy_.js} +2 -2
  185. package/dashboard/dist/assets/{knowledge-DWLxGTib.js.map → knowledge-Bpln0zy_.js.map} +1 -1
  186. package/dashboard/dist/assets/{mcp-B6AARZ2I.js → mcp-BqDq3RZH.js} +2 -2
  187. package/dashboard/dist/assets/{mcp-B6AARZ2I.js.map → mcp-BqDq3RZH.js.map} +1 -1
  188. package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js → mcp-query-DGue75R6.js} +2 -2
  189. package/dashboard/dist/assets/{mcp-query-DrkvBU3a.js.map → mcp-query-DGue75R6.js.map} +1 -1
  190. package/dashboard/dist/assets/{personas-Cmz2SAEU.js → personas-B8z_sTiJ.js} +2 -2
  191. package/dashboard/dist/assets/{personas-Cmz2SAEU.js.map → personas-B8z_sTiJ.js.map} +1 -1
  192. package/dashboard/dist/assets/{pipelines-CSgfVCMy.js → pipelines-DYgNd9nB.js} +2 -2
  193. package/dashboard/dist/assets/{pipelines-CSgfVCMy.js.map → pipelines-DYgNd9nB.js.map} +1 -1
  194. package/dashboard/dist/assets/{tasks-UOtUkDk-.js → tasks-CJdjjhgO.js} +2 -2
  195. package/dashboard/dist/assets/{tasks-UOtUkDk-.js.map → tasks-CJdjjhgO.js.map} +1 -1
  196. package/dashboard/dist/assets/{topics-Df5hGh6o.js → topics-DPrL8Dtq.js} +2 -2
  197. package/dashboard/dist/assets/{topics-Df5hGh6o.js.map → topics-DPrL8Dtq.js.map} +1 -1
  198. package/dashboard/dist/assets/{useEventHooks-PDbuSJ12.js → useEventHooks-DXCgDgiu.js} +2 -2
  199. package/dashboard/dist/assets/{useEventHooks-PDbuSJ12.js.map → useEventHooks-DXCgDgiu.js.map} +1 -1
  200. package/dashboard/dist/assets/{useNamespace-tZSOlge3.js → useNamespace-DnFZfy7N.js} +2 -2
  201. package/dashboard/dist/assets/{useNamespace-tZSOlge3.js.map → useNamespace-DnFZfy7N.js.map} +1 -1
  202. package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js → useYamlActivityEvents-kx5CLENv.js} +2 -2
  203. package/dashboard/dist/assets/{useYamlActivityEvents-CINLzE32.js.map → useYamlActivityEvents-kx5CLENv.js.map} +1 -1
  204. package/dashboard/dist/assets/{users-G8qwyZKS.js → users-DKng7vAG.js} +2 -2
  205. package/dashboard/dist/assets/{users-G8qwyZKS.js.map → users-DKng7vAG.js.map} +1 -1
  206. package/dashboard/dist/assets/{vendor-icons-BpZiWH2f.js → vendor-icons-CN-bAo9U.js} +138 -133
  207. package/dashboard/dist/assets/vendor-icons-CN-bAo9U.js.map +1 -0
  208. package/dashboard/dist/assets/{workflows-DbPqi1TW.js → workflows-C4V0rMkM.js} +2 -2
  209. package/dashboard/dist/assets/{workflows-DbPqi1TW.js.map → workflows-C4V0rMkM.js.map} +1 -1
  210. package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js → yaml-workflows-D3PAiJ9d.js} +2 -2
  211. package/dashboard/dist/assets/{yaml-workflows-DozD8hpR.js.map → yaml-workflows-D3PAiJ9d.js.map} +1 -1
  212. package/dashboard/dist/index.html +3 -3
  213. package/docs/design-principles.md +9 -7
  214. package/docs/hitl/x-lt-embed.md +8 -4
  215. package/docs/hitl/x-lt-footer.md +68 -0
  216. package/docs/hitl/x-lt-list-schema.md +10 -3
  217. package/docs/hitl-guide.md +9 -0
  218. package/package.json +1 -1
  219. package/dashboard/dist/assets/AgentsPage-CToVu1qj.js +0 -2
  220. package/dashboard/dist/assets/AvailableEscalationsPage-DldboL4W.js +0 -2
  221. package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js +0 -2
  222. package/dashboard/dist/assets/CountdownTimer-DPjIkerB.js.map +0 -1
  223. package/dashboard/dist/assets/EventTable-CwPWl163.js +0 -2
  224. package/dashboard/dist/assets/EventTable-CwPWl163.js.map +0 -1
  225. package/dashboard/dist/assets/FilterBar-D7GghUsU.js +0 -2
  226. package/dashboard/dist/assets/FilterBar-D7GghUsU.js.map +0 -1
  227. package/dashboard/dist/assets/McpQueryPage-CNsuiw_q.js +0 -2
  228. package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js +0 -2
  229. package/dashboard/dist/assets/McpRunDetailPage-BJguEMS0.js.map +0 -1
  230. package/dashboard/dist/assets/OperationsPage-DvWrLuH6.js +0 -2
  231. package/dashboard/dist/assets/OperatorDashboard-C-jE0IRA.js +0 -2
  232. package/dashboard/dist/assets/RunAsSelector-CS3KQ-BF.js +0 -2
  233. package/dashboard/dist/assets/StickyPagination-hMrnLXde.js +0 -2
  234. package/dashboard/dist/assets/StickyPagination-hMrnLXde.js.map +0 -1
  235. package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js +0 -2
  236. package/dashboard/dist/assets/WorkflowExecutionPage-C15GSAoe.js.map +0 -1
  237. package/dashboard/dist/assets/WorkflowsDashboard-BMQd_0tW.js +0 -2
  238. package/dashboard/dist/assets/capabilities-IaCcS7ge.js +0 -2
  239. package/dashboard/dist/assets/index-CLmZaNTK.js +0 -2
  240. package/dashboard/dist/assets/index-CfAi1OsI.js.map +0 -1
  241. package/dashboard/dist/assets/index-CvNBdkB1.js +0 -5
  242. package/dashboard/dist/assets/index-Dldi3Q3M.js +0 -2
  243. package/dashboard/dist/assets/index-mKcQGi2B.js +0 -3
  244. package/dashboard/dist/assets/index-mKcQGi2B.js.map +0 -1
  245. package/dashboard/dist/assets/index-zQiUPfxA.css +0 -1
  246. package/dashboard/dist/assets/vendor-icons-BpZiWH2f.js.map +0 -1
package/README.md CHANGED
@@ -4,9 +4,7 @@
4
4
 
5
5
  Durable platforms are built around determinism — that is their strength and their blind spot. They give you rich, first-class queues for deterministic work (retry, timeout, `backoffCoefficient`, exactly-once) and an `await condition()` to park a workflow until a signal arrives. All of it assumes the thing you are waiting on will, eventually, behave.
6
6
 
7
- Most of the work that decides an outcome behaves on its own schedule: an approval, a person, a shipment, a machine that needs service. You cannot set a `backoffCoefficient` on a person retrying someone who has not answered just asks twice. This is why "human-in-the-loop" keeps getting bolted on as a feature: the platform perfected the deterministic queue and left the non-deterministic one for you to improvise.
8
-
9
- Long Tail makes it a primitive. The same `condition()` wait — except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
7
+ Long Tail makes non-determinism a primitive. The same `condition()` wait except the act of waiting mints a row that is searchable, claimable, deadlined, and role-gated on a shared metadata surface. Machines answer some rows, people answer others; the workflow resumes either way, exactly where it paused.
10
8
 
11
9
  ```bash
12
10
  npm install @hotmeshio/long-tail
@@ -14,7 +12,7 @@ npm install @hotmeshio/long-tail
14
12
 
15
13
  ## How it works
16
14
 
17
- One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for the one reality answers.
15
+ One workflow, both queues: `proxyActivities` for the deterministic one, `condition()` for non-determinism.
18
16
 
19
17
  ```typescript
20
18
  import { Durable } from '@hotmeshio/hotmesh';
@@ -161,7 +161,7 @@ async function resolveByMetadata(input, auth) {
161
161
  const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
162
162
  let result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, enforcing.size > 0 ? [...enforcing] : null, null, input.extraFacets);
163
163
  if (result.outcome === 'validation_required' && result.row) {
164
- const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload);
164
+ const report = await (0, resolver_validation_1.checkResolverPayload)(result.row, input.resolverPayload, undefined, resolveUserId);
165
165
  if (report)
166
166
  return (0, resolve_1.validationFailure)(report);
167
167
  result = await escalationService.resolveByMetadataAtomic(input.key, input.value, resolveUserId, input.resolverPayload, input.metadata, writeAllRoles, writeSelfRoles, null, result.row.id, input.extraFacets);
@@ -98,7 +98,7 @@ async function resolveEscalation(input, auth) {
98
98
  // the escalation's resolved form schema BEFORE any resolution path runs.
99
99
  // Costs nothing when the role does not enforce (cached role set); the
100
100
  // task-fallback envelope read only happens for enforcing roles.
101
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation));
101
+ const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, () => reconstructEnvelope(escalation), auth.userId);
102
102
  if (violation)
103
103
  return validationFailure(violation);
104
104
  // The resolver payload is stored exactly as submitted — its shape is the
@@ -181,7 +181,7 @@ async function resolveBySignalKey(input, auth) {
181
181
  return { status: 404, error: 'Escalation not found' };
182
182
  // Schema enforcement — the row (envelope included) is already loaded, so
183
183
  // this costs zero extra reads beyond the cached schema.
184
- const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload);
184
+ const violation = await (0, resolver_validation_1.checkResolverPayload)(escalation, resolverPayload, undefined, auth.userId);
185
185
  if (violation)
186
186
  return validationFailure(violation);
187
187
  // The payload is delivered as the signal the parked workflow's condition()
@@ -247,7 +247,7 @@ async function resolveByIds(input, auth) {
247
247
  const fullRows = await escalationService.getEscalationsByIds(involved);
248
248
  const failed = [];
249
249
  for (const row of fullRows) {
250
- const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload);
250
+ const report = await (0, resolver_validation_1.checkResolverPayload)(row, resolverPayload, undefined, auth.userId);
251
251
  if (report)
252
252
  failed.push({ id: row.id, report });
253
253
  }
@@ -346,7 +346,7 @@ async function resolveAllOrNone(input, auth) {
346
346
  const row = rowById.get(item.id);
347
347
  if (!row || !row.role || !enforcing.has(row.role))
348
348
  continue;
349
- const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload);
349
+ const report = await (0, resolver_validation_1.checkResolverPayload)(row, item.resolverPayload, undefined, auth.userId);
350
350
  if (report)
351
351
  failed.push({ id: item.id, report });
352
352
  }
@@ -23,6 +23,6 @@ export interface ResolverSchemaViolationReport {
23
23
  * surface's task fallback); by default the row's own envelope column is used.
24
24
  * It is only invoked when the role actually enforces.
25
25
  */
26
- export declare function checkResolverPayload(escalation: ResolvableEscalationRow, resolverPayload: Record<string, any>, loadEnvelope?: () => Promise<Record<string, any>>): Promise<ResolverSchemaViolationReport | null>;
26
+ export declare function checkResolverPayload(escalation: ResolvableEscalationRow, resolverPayload: Record<string, any>, loadEnvelope?: () => Promise<Record<string, any>>, resolvingUserId?: string): Promise<ResolverSchemaViolationReport | null>;
27
27
  /** The canonical 422 body for a violation report (types/validation.ts). */
28
28
  export declare function toValidationErrorBody(report: ResolverSchemaViolationReport): LTValidationErrorBody;
@@ -22,6 +22,7 @@ exports.toValidationErrorBody = toValidationErrorBody;
22
22
  * the gate passes.
23
23
  */
24
24
  const form_validation_1 = require("../../shared/form-validation");
25
+ const submit_guard_1 = require("./submit-guard");
25
26
  const enforcement_cache_1 = require("../role/enforcement-cache");
26
27
  const escalation_1 = require("../../types/escalation");
27
28
  const validation_1 = require("../../types/validation");
@@ -54,7 +55,7 @@ function pinnedVersionOf(metadata) {
54
55
  * surface's task fallback); by default the row's own envelope column is used.
55
56
  * It is only invoked when the role actually enforces.
56
57
  */
57
- async function checkResolverPayload(escalation, resolverPayload, loadEnvelope) {
58
+ async function checkResolverPayload(escalation, resolverPayload, loadEnvelope, resolvingUserId) {
58
59
  const role = escalation.role;
59
60
  if (!role)
60
61
  return null;
@@ -72,15 +73,21 @@ async function checkResolverPayload(escalation, resolverPayload, loadEnvelope) {
72
73
  const envelope = loadEnvelope
73
74
  ? await loadEnvelope()
74
75
  : parseJsonOrNull(escalation.envelope) ?? {};
75
- const violations = (0, form_validation_1.validateResolverPayload)(schema, resolverPayload, {
76
+ const ctx = {
76
77
  escalation: escalation,
77
78
  metadata,
78
79
  envelope,
79
80
  payload: parseJsonOrNull(escalation.escalation_payload),
80
- });
81
- if (violations.length === 0)
81
+ };
82
+ const violations = (0, form_validation_1.validateResolverPayload)(schema, resolverPayload, ctx);
83
+ // The query precondition (x-lt-submit-guard): reject while the embedded query
84
+ // still returns rows. Enforced on the same enforce_schema opt-in as the field
85
+ // contract, so a raw-API resolve honors the gate the dashboard shows.
86
+ const guardViolation = await (0, submit_guard_1.checkSubmitGuard)(schema, ctx, resolvingUserId);
87
+ const allViolations = guardViolation ? [...violations, guardViolation] : violations;
88
+ if (allViolations.length === 0)
82
89
  return null;
83
- return { role, schemaVersion: pin, violations };
90
+ return { role, schemaVersion: pin, violations: allViolations };
84
91
  }
85
92
  /** The canonical 422 body for a violation report (types/validation.ts). */
86
93
  function toValidationErrorBody(report) {
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Server-side enforcement of the `x-lt-submit-guard` query precondition — the
3
+ * API-first counterpart of the dashboard's `useSubmitGuard`. Before an
4
+ * escalation resolves, if its form schema declares a submit guard, the same
5
+ * embedded query runs and the resolve is REJECTED while it still returns rows.
6
+ *
7
+ * Isomorphism with the dashboard is exact: the guard reuses `resolveScopedQuery`
8
+ * (the mapping the escalation-list embed uses) and runs it through
9
+ * `searchEscalationsFaceted` — the same faceted query the list API composes.
10
+ *
11
+ * Two deliberate rules:
12
+ * - The count is taken with `global: true`, bypassing the resolver's read
13
+ * scope, so a role that cannot SEE the children can never falsely clear the
14
+ * gate. Only a real, empty result count clears it (the "403 ≠ empty" rule).
15
+ * - A guard whose scope cannot be evaluated (e.g. `assigned:'me'` on a surface
16
+ * with no resolving user, like an MCP resolve) is skipped here; the consuming
17
+ * workflow's own verification remains the durable backstop.
18
+ */
19
+ import { type ShowIfContext } from '../../shared/form-validation';
20
+ import type { LTFieldViolation } from '../../types/validation';
21
+ /** The synthetic violation field for a guard rejection — not a form field. */
22
+ export declare const SUBMIT_GUARD_VIOLATION_FIELD = "_submitGuard";
23
+ /**
24
+ * Returns a violation when the escalation's submit guard still matches rows, or
25
+ * null when there is no guard, its scope is inert, or the query is confirmed
26
+ * empty. The context carries the escalation domains the query facets and the
27
+ * message interpolate against.
28
+ */
29
+ export declare function checkSubmitGuard(schema: Record<string, any> | null | undefined, ctx: ShowIfContext, resolvingUserId: string | undefined): Promise<LTFieldViolation | null>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SUBMIT_GUARD_VIOLATION_FIELD = void 0;
4
+ exports.checkSubmitGuard = checkSubmitGuard;
5
+ /**
6
+ * Server-side enforcement of the `x-lt-submit-guard` query precondition — the
7
+ * API-first counterpart of the dashboard's `useSubmitGuard`. Before an
8
+ * escalation resolves, if its form schema declares a submit guard, the same
9
+ * embedded query runs and the resolve is REJECTED while it still returns rows.
10
+ *
11
+ * Isomorphism with the dashboard is exact: the guard reuses `resolveScopedQuery`
12
+ * (the mapping the escalation-list embed uses) and runs it through
13
+ * `searchEscalationsFaceted` — the same faceted query the list API composes.
14
+ *
15
+ * Two deliberate rules:
16
+ * - The count is taken with `global: true`, bypassing the resolver's read
17
+ * scope, so a role that cannot SEE the children can never falsely clear the
18
+ * gate. Only a real, empty result count clears it (the "403 ≠ empty" rule).
19
+ * - A guard whose scope cannot be evaluated (e.g. `assigned:'me'` on a surface
20
+ * with no resolving user, like an MCP resolve) is skipped here; the consuming
21
+ * workflow's own verification remains the durable backstop.
22
+ */
23
+ const form_validation_1 = require("../../shared/form-validation");
24
+ const queries_1 = require("./queries");
25
+ /** The synthetic violation field for a guard rejection — not a form field. */
26
+ exports.SUBMIT_GUARD_VIOLATION_FIELD = '_submitGuard';
27
+ /**
28
+ * Returns a violation when the escalation's submit guard still matches rows, or
29
+ * null when there is no guard, its scope is inert, or the query is confirmed
30
+ * empty. The context carries the escalation domains the query facets and the
31
+ * message interpolate against.
32
+ */
33
+ async function checkSubmitGuard(schema, ctx, resolvingUserId) {
34
+ const guard = (0, form_validation_1.readSubmitGuard)(schema);
35
+ if (!guard || guard.mustBeEmpty === false)
36
+ return null;
37
+ const scoped = (0, form_validation_1.resolveScopedQuery)(guard.query, ctx, resolvingUserId);
38
+ if (!scoped.enabled)
39
+ return null;
40
+ const { total } = await (0, queries_1.searchEscalationsFaceted)({
41
+ global: true,
42
+ facet: {
43
+ role: scoped.role,
44
+ status: scoped.status,
45
+ available: scoped.available,
46
+ facets: scoped.facets,
47
+ },
48
+ assigned_to: scoped.assigned_to,
49
+ limit: 1,
50
+ offset: 0,
51
+ });
52
+ if (total <= 0)
53
+ 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);
56
+ return { field: exports.SUBMIT_GUARD_VIOLATION_FIELD, message };
57
+ }
@@ -8,6 +8,10 @@ export * from './derive-field-label';
8
8
  export * from './x-lt-bind';
9
9
  export * from './x-lt-help';
10
10
  export * from './x-lt-transition';
11
+ export * from './x-lt-submit-on-claim';
12
+ export * from './x-lt-labels';
13
+ export * from './x-lt-query';
14
+ export * from './x-lt-submit-guard';
11
15
  export * from './x-lt-show-if';
12
16
  export * from './field-validator';
13
17
  export * from './validate-resolver-payload';
@@ -24,6 +24,10 @@ __exportStar(require("./derive-field-label"), exports);
24
24
  __exportStar(require("./x-lt-bind"), exports);
25
25
  __exportStar(require("./x-lt-help"), exports);
26
26
  __exportStar(require("./x-lt-transition"), exports);
27
+ __exportStar(require("./x-lt-submit-on-claim"), exports);
28
+ __exportStar(require("./x-lt-labels"), exports);
29
+ __exportStar(require("./x-lt-query"), exports);
30
+ __exportStar(require("./x-lt-submit-guard"), exports);
27
31
  __exportStar(require("./x-lt-show-if"), exports);
28
32
  __exportStar(require("./field-validator"), exports);
29
33
  __exportStar(require("./validate-resolver-payload"), exports);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * x-lt-labels — configurable copy for the standard escalation footer. A
3
+ * form_schema may declare, at its schema root, an object that renames the
4
+ * footer's action controls. Each key is a standard target; its value is the
5
+ * label to render in place of the default.
6
+ *
7
+ * x-lt-labels object — { claim, cancel, submit, escalate, release }
8
+ *
9
+ * ```jsonc
10
+ * { "x-lt-labels": { "claim": "Claim and Submit", "submit": "Approve" } }
11
+ * ```
12
+ *
13
+ * Only the five known targets are read; unknown keys and non-string values are
14
+ * ignored. Any target the schema omits keeps its default label, so a schema
15
+ * overrides just the controls it cares about.
16
+ */
17
+ export declare const X_LT_LABELS = "x-lt-labels";
18
+ /** The footer controls a schema may rename. */
19
+ export declare const FOOTER_LABEL_TARGETS: readonly ["claim", "cancel", "submit", "escalate", "release"];
20
+ export type FooterLabelTarget = (typeof FOOTER_LABEL_TARGETS)[number];
21
+ /** A partial map of target → override label. Absent targets keep their default. */
22
+ export type FooterLabels = Partial<Record<FooterLabelTarget, string>>;
23
+ /**
24
+ * The schema's footer label overrides, or an empty map when none are declared.
25
+ * Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and
26
+ * blank or non-string values are dropped.
27
+ */
28
+ export declare function readFooterLabels(schema: Record<string, unknown> | null | undefined): FooterLabels;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /**
3
+ * x-lt-labels — configurable copy for the standard escalation footer. A
4
+ * form_schema may declare, at its schema root, an object that renames the
5
+ * footer's action controls. Each key is a standard target; its value is the
6
+ * label to render in place of the default.
7
+ *
8
+ * x-lt-labels object — { claim, cancel, submit, escalate, release }
9
+ *
10
+ * ```jsonc
11
+ * { "x-lt-labels": { "claim": "Claim and Submit", "submit": "Approve" } }
12
+ * ```
13
+ *
14
+ * Only the five known targets are read; unknown keys and non-string values are
15
+ * ignored. Any target the schema omits keeps its default label, so a schema
16
+ * overrides just the controls it cares about.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.FOOTER_LABEL_TARGETS = exports.X_LT_LABELS = void 0;
20
+ exports.readFooterLabels = readFooterLabels;
21
+ exports.X_LT_LABELS = 'x-lt-labels';
22
+ /** The footer controls a schema may rename. */
23
+ exports.FOOTER_LABEL_TARGETS = ['claim', 'cancel', 'submit', 'escalate', 'release'];
24
+ /**
25
+ * The schema's footer label overrides, or an empty map when none are declared.
26
+ * Reads only the known targets; a non-object `x-lt-labels`, unknown keys, and
27
+ * blank or non-string values are dropped.
28
+ */
29
+ function readFooterLabels(schema) {
30
+ const raw = schema?.[exports.X_LT_LABELS];
31
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
32
+ return {};
33
+ const source = raw;
34
+ const labels = {};
35
+ for (const target of exports.FOOTER_LABEL_TARGETS) {
36
+ const value = source[target];
37
+ if (typeof value === 'string' && value.trim().length > 0) {
38
+ labels[target] = value.trim();
39
+ }
40
+ }
41
+ return labels;
42
+ }
@@ -0,0 +1,56 @@
1
+ import type { ShowIfContext } from './x-lt-show-if';
2
+ /**
3
+ * The embedded escalation query shape shared by `x-lt-query` (escalation-list
4
+ * widget) and `x-lt-submit-guard.query` (form-level submit gate). String
5
+ * values inside `facets` support `{{domain.path}}` token interpolation against
6
+ * the host escalation's context. Isomorphic: the dashboard renders embeds from
7
+ * it, and the API layer enforces the submit gate from the identical mapping.
8
+ *
9
+ * `assigned` is the ownership scope. Ownership is not a separate list — it is
10
+ * one more dimension of the same faceted query language the escalation API
11
+ * composes server-side ("claimed" is the implied status: pending, held, claim
12
+ * window live):
13
+ * - `"me"` — rows claimed by the viewing user (the walk case: I walk what I own)
14
+ * - `"any"` — all matching rows regardless of claim state
15
+ * - omitted — available rows only (unclaimed, or claim window lapsed)
16
+ */
17
+ export interface EmbedQuery {
18
+ role?: string;
19
+ status?: string;
20
+ facets?: Record<string, string>;
21
+ limit?: number;
22
+ assigned?: 'me' | 'any';
23
+ /** Superseded by `assigned`; honored only when `assigned` is omitted. */
24
+ available?: boolean;
25
+ }
26
+ /** Interpolate `{{domain.path}}` tokens in every string value of the facets map. */
27
+ export declare function resolveQueryFacets(facets: Record<string, string> | undefined, ctx: ShowIfContext): Record<string, unknown>;
28
+ /** The escalation-query params an EmbedQuery resolves to — the exact input
29
+ * shape of `useEscalations`, so every embed surface queries identically. */
30
+ export interface ScopedQueryParams {
31
+ role?: string;
32
+ status: string;
33
+ facets: Record<string, unknown>;
34
+ assigned_to?: string;
35
+ available?: boolean;
36
+ limit?: number;
37
+ enabled: boolean;
38
+ }
39
+ /**
40
+ * Resolve an EmbedQuery into concrete escalation-query params — the ONE
41
+ * mapping every embed surface (escalation-list, x-lt-actions, x-lt-submit-guard)
42
+ * consumes, so the visible rows and any count derived from the same query can
43
+ * never disagree.
44
+ *
45
+ * Ownership scope translates into the faceted query language:
46
+ * - `assigned: "me"` → `assigned_to = viewer AND available = false` — the
47
+ * implied "claimed" status (pending + live claim window held by the viewer)
48
+ * - `assigned: "any"` → no ownership constraint
49
+ * - omitted → `available = true` (the unclaimed pool; a declared
50
+ * legacy `available` value is honored)
51
+ *
52
+ * When `assigned: "me"` and no viewer id is supplied (a surface with no
53
+ * resolving user, e.g. an MCP resolve), the scope cannot be evaluated —
54
+ * `enabled` is false rather than silently widening to another scope.
55
+ */
56
+ export declare function resolveScopedQuery(query: EmbedQuery, ctx: ShowIfContext, viewerId: string | undefined): ScopedQueryParams;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveQueryFacets = resolveQueryFacets;
4
+ exports.resolveScopedQuery = resolveScopedQuery;
5
+ const x_lt_help_1 = require("./x-lt-help");
6
+ /** Interpolate `{{domain.path}}` tokens in every string value of the facets map. */
7
+ function resolveQueryFacets(facets, ctx) {
8
+ if (!facets)
9
+ return {};
10
+ const resolved = {};
11
+ for (const [k, v] of Object.entries(facets)) {
12
+ resolved[k] = typeof v === 'string' ? (0, x_lt_help_1.interpolateHelp)(v, ctx) : v;
13
+ }
14
+ return resolved;
15
+ }
16
+ /**
17
+ * Resolve an EmbedQuery into concrete escalation-query params — the ONE
18
+ * mapping every embed surface (escalation-list, x-lt-actions, x-lt-submit-guard)
19
+ * consumes, so the visible rows and any count derived from the same query can
20
+ * never disagree.
21
+ *
22
+ * Ownership scope translates into the faceted query language:
23
+ * - `assigned: "me"` → `assigned_to = viewer AND available = false` — the
24
+ * implied "claimed" status (pending + live claim window held by the viewer)
25
+ * - `assigned: "any"` → no ownership constraint
26
+ * - omitted → `available = true` (the unclaimed pool; a declared
27
+ * legacy `available` value is honored)
28
+ *
29
+ * When `assigned: "me"` and no viewer id is supplied (a surface with no
30
+ * resolving user, e.g. an MCP resolve), the scope cannot be evaluated —
31
+ * `enabled` is false rather than silently widening to another scope.
32
+ */
33
+ function resolveScopedQuery(query, ctx, viewerId) {
34
+ const facets = resolveQueryFacets(query.facets, ctx);
35
+ const base = {
36
+ role: query.role,
37
+ status: query.status ?? 'pending',
38
+ facets,
39
+ limit: query.limit,
40
+ enabled: !!(query.role || Object.keys(facets).length),
41
+ };
42
+ if (query.assigned === 'me') {
43
+ return { ...base, assigned_to: viewerId, available: false, enabled: base.enabled && !!viewerId };
44
+ }
45
+ if (query.assigned === 'any') {
46
+ return base;
47
+ }
48
+ return { ...base, available: query.available ?? true };
49
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * x-lt-submit-guard — a query precondition on the resolve. A form_schema may
3
+ * declare, at its root, that the escalation cannot be resolved while an embedded
4
+ * escalation query still returns rows: the parent references a set of children
5
+ * (commonly claimed by the same person) that must all be completed first, a
6
+ * to-do list that empties as children resolve.
7
+ *
8
+ * "x-lt-submit-guard": {
9
+ * "query": { "role": "print-harvest", "status": "pending",
10
+ * "assigned": "me",
11
+ * "facets": { "walkId": "{{metadata.walkId}}" } },
12
+ * "mustBeEmpty": true, // the only mode today; defaults true
13
+ * "message": "{{count}} plates still pending — bag them before closing.",
14
+ * "autoResolveWhenEmpty": true // auto-submit the parent once empty
15
+ * }
16
+ *
17
+ * The gate is isomorphic. The dashboard disables the submit while the query
18
+ * returns rows (UI honesty), and the API layer enforces the same precondition
19
+ * for `enforce_schema` roles so a raw-API resolve is rejected too. Only a
20
+ * confirmed empty result (a successful read with zero rows) clears the gate — a
21
+ * 403 or any error never does.
22
+ *
23
+ * `autoResolveWhenEmpty` closes the loop: the moment the query is confirmed
24
+ * empty, the claimed parent auto-submits — checked on page-load and after each
25
+ * inline child-resolve — so a set of escalations completes with no extra click.
26
+ */
27
+ import type { EmbedQuery } from './x-lt-query';
28
+ export declare const X_LT_SUBMIT_GUARD = "x-lt-submit-guard";
29
+ export interface SubmitGuardDef {
30
+ query: EmbedQuery;
31
+ /** The gate condition; defaults to true (the only supported mode today). */
32
+ mustBeEmpty?: boolean;
33
+ /** Shown beside the disabled submit. `{{count}}` and `{{domain.path}}` tokens interpolate. */
34
+ message?: string;
35
+ /** When true, auto-submit the claimed parent the moment the query is confirmed empty. */
36
+ autoResolveWhenEmpty?: boolean;
37
+ }
38
+ export declare const SUBMIT_GUARD_DEFAULT_MESSAGE = "{{count}} related items are still pending";
39
+ /** The schema's submit-guard, or undefined when it declares none. */
40
+ export declare function readSubmitGuard(schema: Record<string, unknown> | null | undefined): SubmitGuardDef | undefined;
41
+ /**
42
+ * Whether a guard blocks the resolve given the query's row count. `mustBeEmpty`
43
+ * defaults to true, so any matching row blocks. A pure decision — the caller
44
+ * supplies the count from a confirmed read (never an error/loading state).
45
+ */
46
+ export declare function guardBlocks(count: number, guard: SubmitGuardDef | undefined): boolean;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SUBMIT_GUARD_DEFAULT_MESSAGE = exports.X_LT_SUBMIT_GUARD = void 0;
4
+ exports.readSubmitGuard = readSubmitGuard;
5
+ exports.guardBlocks = guardBlocks;
6
+ exports.X_LT_SUBMIT_GUARD = 'x-lt-submit-guard';
7
+ exports.SUBMIT_GUARD_DEFAULT_MESSAGE = '{{count}} related items are still pending';
8
+ /** The schema's submit-guard, or undefined when it declares none. */
9
+ function readSubmitGuard(schema) {
10
+ const raw = schema?.[exports.X_LT_SUBMIT_GUARD];
11
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
12
+ return undefined;
13
+ const guard = raw;
14
+ if (!guard.query || typeof guard.query !== 'object')
15
+ return undefined;
16
+ return guard;
17
+ }
18
+ /**
19
+ * Whether a guard blocks the resolve given the query's row count. `mustBeEmpty`
20
+ * defaults to true, so any matching row blocks. A pure decision — the caller
21
+ * supplies the count from a confirmed read (never an error/loading state).
22
+ */
23
+ function guardBlocks(count, guard) {
24
+ return !!guard && guard.mustBeEmpty !== false && count > 0;
25
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * x-lt-submit-on-claim — a one-gesture claim. A form_schema may declare, at its
3
+ * schema root, that claiming one of its escalations should also resolve it in
4
+ * the same gesture, submitting whatever the form currently holds (its seeded
5
+ * defaults). The person clicks Claim once and the work item advances — no
6
+ * second Submit step.
7
+ *
8
+ * x-lt-submit-on-claim boolean — opt in to claim-and-submit
9
+ *
10
+ * It is opt-in and defaults off. Pair it with `x-lt-labels` to rename the Claim
11
+ * button ("Claim and Submit") so the single gesture reads honestly. When the
12
+ * seeded defaults fail validation the claim still lands; the page drops into the
13
+ * normal claimed state with the field errors surfaced, so the person finishes
14
+ * the form by hand.
15
+ */
16
+ export declare const X_LT_SUBMIT_ON_CLAIM = "x-lt-submit-on-claim";
17
+ /**
18
+ * Whether the schema opts into claim-and-submit. Truthy `x-lt-submit-on-claim`
19
+ * turns it on; anything else (absent, false) leaves the standard two-step claim
20
+ * then submit.
21
+ */
22
+ export declare function readSubmitOnClaim(schema: Record<string, unknown> | null | undefined): boolean;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ /**
3
+ * x-lt-submit-on-claim — a one-gesture claim. A form_schema may declare, at its
4
+ * schema root, that claiming one of its escalations should also resolve it in
5
+ * the same gesture, submitting whatever the form currently holds (its seeded
6
+ * defaults). The person clicks Claim once and the work item advances — no
7
+ * second Submit step.
8
+ *
9
+ * x-lt-submit-on-claim boolean — opt in to claim-and-submit
10
+ *
11
+ * It is opt-in and defaults off. Pair it with `x-lt-labels` to rename the Claim
12
+ * button ("Claim and Submit") so the single gesture reads honestly. When the
13
+ * seeded defaults fail validation the claim still lands; the page drops into the
14
+ * normal claimed state with the field errors surfaced, so the person finishes
15
+ * the form by hand.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.X_LT_SUBMIT_ON_CLAIM = void 0;
19
+ exports.readSubmitOnClaim = readSubmitOnClaim;
20
+ exports.X_LT_SUBMIT_ON_CLAIM = 'x-lt-submit-on-claim';
21
+ /**
22
+ * Whether the schema opts into claim-and-submit. Truthy `x-lt-submit-on-claim`
23
+ * turns it on; anything else (absent, false) leaves the standard two-step claim
24
+ * then submit.
25
+ */
26
+ function readSubmitOnClaim(schema) {
27
+ return !!schema?.[exports.X_LT_SUBMIT_ON_CLAIM];
28
+ }