@hotmeshio/long-tail 0.10.1 → 0.10.3

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 (311) hide show
  1. package/README.md +1 -0
  2. package/build/api/bot-accounts.d.ts +4 -0
  3. package/build/api/bot-accounts.js +3 -1
  4. package/build/api/escalations/metadata.js +21 -1
  5. package/build/api/escalations/resolve.d.ts +8 -0
  6. package/build/api/escalations/resolve.js +82 -3
  7. package/build/api/me.d.ts +16 -0
  8. package/build/api/me.js +79 -0
  9. package/build/api/roles.d.ts +8 -0
  10. package/build/api/roles.js +14 -0
  11. package/build/bin/ltc.js +10 -1
  12. package/build/lib/cli/client.d.ts +4 -1
  13. package/build/lib/cli/client.js +4 -2
  14. package/build/lib/db/schemas/022_user_preferences.sql +18 -0
  15. package/build/lib/db/schemas/023_role_enforce_schema.sql +18 -0
  16. package/build/lib/typed-resolution.d.ts +35 -0
  17. package/build/lib/typed-resolution.js +37 -0
  18. package/build/modules/config.d.ts +1 -0
  19. package/build/modules/config.js +5 -0
  20. package/build/routes/bot-accounts.js +3 -1
  21. package/build/routes/index.js +2 -0
  22. package/build/routes/me.d.ts +2 -0
  23. package/build/routes/me.js +57 -0
  24. package/build/sdk/index.d.ts +10 -0
  25. package/build/sdk/index.js +25 -0
  26. package/build/services/escalation/crud.d.ts +18 -6
  27. package/build/services/escalation/crud.js +18 -2
  28. package/build/services/escalation/index.d.ts +1 -0
  29. package/build/services/escalation/index.js +1 -0
  30. package/build/services/escalation/resolver-validation.d.ts +28 -0
  31. package/build/services/escalation/resolver-validation.js +95 -0
  32. package/build/services/escalation/sql.d.ts +12 -2
  33. package/build/services/escalation/sql.js +22 -2
  34. package/build/services/iam/bots.d.ts +4 -1
  35. package/build/services/iam/bots.js +5 -3
  36. package/build/services/iam/sql.d.ts +2 -2
  37. package/build/services/iam/sql.js +15 -1
  38. package/build/services/role/enforcement-cache.d.ts +21 -0
  39. package/build/services/role/enforcement-cache.js +0 -0
  40. package/build/services/role/index.js +6 -0
  41. package/build/services/role/sql.d.ts +15 -2
  42. package/build/services/role/sql.js +21 -2
  43. package/build/services/role/types.d.ts +25 -0
  44. package/build/services/user/index.d.ts +1 -0
  45. package/build/services/user/index.js +5 -1
  46. package/build/services/user/preferences.d.ts +15 -0
  47. package/build/services/user/preferences.js +38 -0
  48. package/build/shared/form-validation/field-validator.d.ts +45 -0
  49. package/build/shared/form-validation/field-validator.js +214 -0
  50. package/build/shared/form-validation/index.d.ts +11 -0
  51. package/build/shared/form-validation/index.js +27 -0
  52. package/build/shared/form-validation/validate-resolver-payload.d.ts +41 -0
  53. package/build/shared/form-validation/validate-resolver-payload.js +62 -0
  54. package/build/shared/form-validation/x-lt-bind.d.ts +41 -0
  55. package/build/shared/form-validation/x-lt-bind.js +110 -0
  56. package/build/shared/form-validation/x-lt-help.d.ts +21 -0
  57. package/build/shared/form-validation/x-lt-help.js +91 -0
  58. package/build/shared/form-validation/x-lt-show-if.d.ts +7 -0
  59. package/build/shared/form-validation/x-lt-show-if.js +84 -0
  60. package/build/system/mcp-servers/admin/schemas.d.ts +29 -0
  61. package/build/system/mcp-servers/admin/schemas.js +7 -0
  62. package/build/system/mcp-servers/admin/users.js +8 -3
  63. package/build/system/mcp-servers/human-queue-schemas.d.ts +4 -4
  64. package/build/system/mcp-servers/human-queue-schemas.js +4 -1
  65. package/build/system/mcp-servers/human-queue.js +41 -2
  66. package/build/system/seed/tool-manifests-admin.d.ts +167 -0
  67. package/build/system/seed/tool-manifests-admin.js +1 -1
  68. package/build/tsconfig.tsbuildinfo +1 -1
  69. package/build/types/sdk.d.ts +6 -1
  70. package/build/types/validation.d.ts +43 -0
  71. package/build/types/validation.js +28 -0
  72. package/dashboard/dist/assets/{AdminDashboard-D7Amh-EJ.js → AdminDashboard-DQLGybZ9.js} +2 -2
  73. package/dashboard/dist/assets/{AdminDashboard-D7Amh-EJ.js.map → AdminDashboard-DQLGybZ9.js.map} +1 -1
  74. package/dashboard/dist/assets/AgentConfigPage-4JgMpuYJ.js +16 -0
  75. package/dashboard/dist/assets/AgentConfigPage-4JgMpuYJ.js.map +1 -0
  76. package/dashboard/dist/assets/{AgentDetailPage-Dy3Qvlfk.js → AgentDetailPage-DCgKokgX.js} +3 -3
  77. package/dashboard/dist/assets/{AgentDetailPage-Dy3Qvlfk.js.map → AgentDetailPage-DCgKokgX.js.map} +1 -1
  78. package/dashboard/dist/assets/{AgentsPage-D7WePZ0o.js → AgentsPage-BK_8VKZO.js} +2 -2
  79. package/dashboard/dist/assets/{AgentsPage-D7WePZ0o.js.map → AgentsPage-BK_8VKZO.js.map} +1 -1
  80. package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js +2 -0
  81. package/dashboard/dist/assets/AvailableEscalationsPage-Dp1rsIHC.js.map +1 -0
  82. package/dashboard/dist/assets/BotPicker-DvUnYEJk.js +2 -0
  83. package/dashboard/dist/assets/BotPicker-DvUnYEJk.js.map +1 -0
  84. package/dashboard/dist/assets/{CapabilitiesPage-3VTLEPGO.js → CapabilitiesPage-CJ5ldY8w.js} +2 -2
  85. package/dashboard/dist/assets/{CapabilitiesPage-3VTLEPGO.js.map → CapabilitiesPage-CJ5ldY8w.js.map} +1 -1
  86. package/dashboard/dist/assets/{CollapsibleSection-BYgeZz9M.js → CollapsibleSection-BXOpfs3z.js} +2 -2
  87. package/dashboard/dist/assets/{CollapsibleSection-BYgeZz9M.js.map → CollapsibleSection-BXOpfs3z.js.map} +1 -1
  88. package/dashboard/dist/assets/CountdownTimer-D20FNwS-.js +2 -0
  89. package/dashboard/dist/assets/CountdownTimer-D20FNwS-.js.map +1 -0
  90. package/dashboard/dist/assets/{CredentialsPage-CaH3J3SE.js → CredentialsPage-vZ2psNnd.js} +2 -2
  91. package/dashboard/dist/assets/{CredentialsPage-CaH3J3SE.js.map → CredentialsPage-vZ2psNnd.js.map} +1 -1
  92. package/dashboard/dist/assets/{CronLabel-Bma_4AC2.js → CronLabel-KRkqNSYs.js} +2 -2
  93. package/dashboard/dist/assets/{CronLabel-Bma_4AC2.js.map → CronLabel-KRkqNSYs.js.map} +1 -1
  94. package/dashboard/dist/assets/{CustomDurationPicker-BxyjEX27.js → CustomDurationPicker-C-vGsrFl.js} +2 -2
  95. package/dashboard/dist/assets/CustomDurationPicker-C-vGsrFl.js.map +1 -0
  96. package/dashboard/dist/assets/{DropZone-zxH-9B8c.js → DropZone-C3NdMtwK.js} +2 -2
  97. package/dashboard/dist/assets/{DropZone-zxH-9B8c.js.map → DropZone-C3NdMtwK.js.map} +1 -1
  98. package/dashboard/dist/assets/{ElapsedCell-Dr1cEwoi.js → ElapsedCell-DNH-XHOS.js} +2 -2
  99. package/dashboard/dist/assets/{ElapsedCell-Dr1cEwoi.js.map → ElapsedCell-DNH-XHOS.js.map} +1 -1
  100. package/dashboard/dist/assets/{EscalationListSchemaPage-CLdsR-hK.js → EscalationListSchemaPage-BIW1qxjC.js} +3 -3
  101. package/dashboard/dist/assets/{EscalationListSchemaPage-CLdsR-hK.js.map → EscalationListSchemaPage-BIW1qxjC.js.map} +1 -1
  102. package/dashboard/dist/assets/{EscalationSchemaPage-DnEnvolM.js → EscalationSchemaPage-Fj2IwQXQ.js} +2 -2
  103. package/dashboard/dist/assets/{EscalationSchemaPage-DnEnvolM.js.map → EscalationSchemaPage-Fj2IwQXQ.js.map} +1 -1
  104. package/dashboard/dist/assets/{EscalationsOverview-BH8cxgLI.js → EscalationsOverview-BVUx0vZH.js} +2 -2
  105. package/dashboard/dist/assets/{EscalationsOverview-BH8cxgLI.js.map → EscalationsOverview-BVUx0vZH.js.map} +1 -1
  106. package/dashboard/dist/assets/{EventTable-p-xsfYYg.js → EventTable-Dm4zZaRl.js} +2 -2
  107. package/dashboard/dist/assets/{EventTable-p-xsfYYg.js.map → EventTable-Dm4zZaRl.js.map} +1 -1
  108. package/dashboard/dist/assets/{GraphInvokePage-Cf9c_LJ-.js → GraphInvokePage-D4f074qh.js} +2 -2
  109. package/dashboard/dist/assets/GraphInvokePage-D4f074qh.js.map +1 -0
  110. package/dashboard/dist/assets/HomePage-DQ0bb_M_.js +2 -0
  111. package/dashboard/dist/assets/HomePage-DQ0bb_M_.js.map +1 -0
  112. package/dashboard/dist/assets/ListToolbar-CItVkLQ-.js +2 -0
  113. package/dashboard/dist/assets/{ListToolbar-CDlol8XJ.js.map → ListToolbar-CItVkLQ-.js.map} +1 -1
  114. package/dashboard/dist/assets/{McpOverview-ChZ36p9t.js → McpOverview-ByYVDldF.js} +2 -2
  115. package/dashboard/dist/assets/{McpOverview-ChZ36p9t.js.map → McpOverview-ByYVDldF.js.map} +1 -1
  116. package/dashboard/dist/assets/{McpQueryDetailPage-X4j_jm3r.js → McpQueryDetailPage-DYuIdJiH.js} +2 -2
  117. package/dashboard/dist/assets/{McpQueryDetailPage-X4j_jm3r.js.map → McpQueryDetailPage-DYuIdJiH.js.map} +1 -1
  118. package/dashboard/dist/assets/{McpQueryPage-C30HsQfZ.js → McpQueryPage-C9C4mPC0.js} +2 -2
  119. package/dashboard/dist/assets/{McpQueryPage-C30HsQfZ.js.map → McpQueryPage-C9C4mPC0.js.map} +1 -1
  120. package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js +2 -0
  121. package/dashboard/dist/assets/McpRunDetailPage-CWHKhx8n.js.map +1 -0
  122. package/dashboard/dist/assets/{McpRunsPage-BHZHCwMM.js → McpRunsPage-DMamEjjr.js} +2 -2
  123. package/dashboard/dist/assets/{McpRunsPage-BHZHCwMM.js.map → McpRunsPage-DMamEjjr.js.map} +1 -1
  124. package/dashboard/dist/assets/{NamespacePill-BQNMfY0m.js → NamespacePill-B3YOa1xo.js} +2 -2
  125. package/dashboard/dist/assets/{NamespacePill-BQNMfY0m.js.map → NamespacePill-B3YOa1xo.js.map} +1 -1
  126. package/dashboard/dist/assets/OperationsPage-CVPDugQz.js +2 -0
  127. package/dashboard/dist/assets/OperationsPage-CVPDugQz.js.map +1 -0
  128. package/dashboard/dist/assets/{OperatorDashboard-BGJrxLMU.js → OperatorDashboard-CK-4GREp.js} +2 -2
  129. package/dashboard/dist/assets/{OperatorDashboard-BGJrxLMU.js.map → OperatorDashboard-CK-4GREp.js.map} +1 -1
  130. package/dashboard/dist/assets/{PageHeader-BIY1YvKR.js → PageHeader-poyTWcUA.js} +2 -2
  131. package/dashboard/dist/assets/{PageHeader-BIY1YvKR.js.map → PageHeader-poyTWcUA.js.map} +1 -1
  132. package/dashboard/dist/assets/{PageHeaderWithStats-TUyglVW0.js → PageHeaderWithStats-CAmspbl9.js} +2 -2
  133. package/dashboard/dist/assets/{PageHeaderWithStats-TUyglVW0.js.map → PageHeaderWithStats-CAmspbl9.js.map} +1 -1
  134. package/dashboard/dist/assets/{ProcessDetailPage-Bcp3GKFo.js → ProcessDetailPage-BBCwv1bQ.js} +2 -2
  135. package/dashboard/dist/assets/{ProcessDetailPage-Bcp3GKFo.js.map → ProcessDetailPage-BBCwv1bQ.js.map} +1 -1
  136. package/dashboard/dist/assets/{ProcessesListPage-DPrvuLoU.js → ProcessesListPage-m70xmTZx.js} +2 -2
  137. package/dashboard/dist/assets/{ProcessesListPage-DPrvuLoU.js.map → ProcessesListPage-m70xmTZx.js.map} +1 -1
  138. package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js +8 -0
  139. package/dashboard/dist/assets/RoleDetailPage-l865Cx3n.js.map +1 -0
  140. package/dashboard/dist/assets/RolePill-C0SWz9X7.js +2 -0
  141. package/dashboard/dist/assets/RolePill-C0SWz9X7.js.map +1 -0
  142. package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js +2 -0
  143. package/dashboard/dist/assets/RolesPage-Wzfjz7Wc.js.map +1 -0
  144. package/dashboard/dist/assets/RunAsSelector-DlnIolTf.js +2 -0
  145. package/dashboard/dist/assets/{RunAsSelector-Z2Yunqdf.js.map → RunAsSelector-DlnIolTf.js.map} +1 -1
  146. package/dashboard/dist/assets/{SlidePanel-DK4sWXmp.js → SlidePanel-Bm9B6zIA.js} +2 -2
  147. package/dashboard/dist/assets/{SlidePanel-DK4sWXmp.js.map → SlidePanel-Bm9B6zIA.js.map} +1 -1
  148. package/dashboard/dist/assets/{StickyPagination-CeLsnCIS.js → StickyPagination-BHF5fTt5.js} +2 -2
  149. package/dashboard/dist/assets/{StickyPagination-CeLsnCIS.js.map → StickyPagination-BHF5fTt5.js.map} +1 -1
  150. package/dashboard/dist/assets/{StreamMessageDetail-DWs7XkmH.js → StreamMessageDetail-Dgp1lzay.js} +2 -2
  151. package/dashboard/dist/assets/{StreamMessageDetail-DWs7XkmH.js.map → StreamMessageDetail-Dgp1lzay.js.map} +1 -1
  152. package/dashboard/dist/assets/{SwimlaneTimeline-Dxl9a51q.js → SwimlaneTimeline-BlptZ8lr.js} +2 -2
  153. package/dashboard/dist/assets/{SwimlaneTimeline-Dxl9a51q.js.map → SwimlaneTimeline-BlptZ8lr.js.map} +1 -1
  154. package/dashboard/dist/assets/{TagInput-CK-JhBG2.js → TagInput-CM3AV5Ky.js} +2 -2
  155. package/dashboard/dist/assets/{TagInput-CK-JhBG2.js.map → TagInput-CM3AV5Ky.js.map} +1 -1
  156. package/dashboard/dist/assets/{TaskDetailPage-DVr31zDE.js → TaskDetailPage-f5K9dVPG.js} +2 -2
  157. package/dashboard/dist/assets/{TaskDetailPage-DVr31zDE.js.map → TaskDetailPage-f5K9dVPG.js.map} +1 -1
  158. package/dashboard/dist/assets/{TaskQueuePill-C_Vo2Clc.js → TaskQueuePill-BZYmqdcv.js} +2 -2
  159. package/dashboard/dist/assets/{TaskQueuePill-C_Vo2Clc.js.map → TaskQueuePill-BZYmqdcv.js.map} +1 -1
  160. package/dashboard/dist/assets/{TasksListPage-DNGp5lfi.js → TasksListPage-BPyPG6UY.js} +2 -2
  161. package/dashboard/dist/assets/{TasksListPage-DNGp5lfi.js.map → TasksListPage-BPyPG6UY.js.map} +1 -1
  162. package/dashboard/dist/assets/{TimeAgo-j2Q4w4lY.js → TimeAgo-CBaGbueK.js} +2 -2
  163. package/dashboard/dist/assets/{TimeAgo-j2Q4w4lY.js.map → TimeAgo-CBaGbueK.js.map} +1 -1
  164. package/dashboard/dist/assets/{TimestampCell-BLEfob2C.js → TimestampCell-Z5kDrR9U.js} +2 -2
  165. package/dashboard/dist/assets/{TimestampCell-BLEfob2C.js.map → TimestampCell-Z5kDrR9U.js.map} +1 -1
  166. package/dashboard/dist/assets/ToolPill-D_-m3lUO.js +2 -0
  167. package/dashboard/dist/assets/{ToolPill-BCi101Jh.js.map → ToolPill-D_-m3lUO.js.map} +1 -1
  168. package/dashboard/dist/assets/{ToolTestPanel-ZJZT_mDP.js → ToolTestPanel-DFrP_aMx.js} +2 -2
  169. package/dashboard/dist/assets/{ToolTestPanel-ZJZT_mDP.js.map → ToolTestPanel-DFrP_aMx.js.map} +1 -1
  170. package/dashboard/dist/assets/TopicDetailPage-Cj9qXnTW.js +9 -0
  171. package/dashboard/dist/assets/TopicDetailPage-Cj9qXnTW.js.map +1 -0
  172. package/dashboard/dist/assets/{TopicsPage-Ctb_85Tw.js → TopicsPage-Dyq6niOv.js} +2 -2
  173. package/dashboard/dist/assets/{TopicsPage-Ctb_85Tw.js.map → TopicsPage-Dyq6niOv.js.map} +1 -1
  174. package/dashboard/dist/assets/{UserName-CkFpUqVK.js → UserName-DOX2P-8M.js} +2 -2
  175. package/dashboard/dist/assets/{UserName-CkFpUqVK.js.map → UserName-DOX2P-8M.js.map} +1 -1
  176. package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js +2 -0
  177. package/dashboard/dist/assets/WorkflowExecutionPage-Cb_dSIoq.js.map +1 -0
  178. package/dashboard/dist/assets/WorkflowPill-CyYYPB7b.js +2 -0
  179. package/dashboard/dist/assets/{WorkflowPill-DHxrAkp3.js.map → WorkflowPill-CyYYPB7b.js.map} +1 -1
  180. package/dashboard/dist/assets/{WorkflowsDashboard-DOyZbqzf.js → WorkflowsDashboard-DJpMO5IY.js} +2 -2
  181. package/dashboard/dist/assets/{WorkflowsDashboard-DOyZbqzf.js.map → WorkflowsDashboard-DJpMO5IY.js.map} +1 -1
  182. package/dashboard/dist/assets/{WorkflowsOverview-CRyHvUBx.js → WorkflowsOverview-CCC_KaXz.js} +2 -2
  183. package/dashboard/dist/assets/{WorkflowsOverview-CRyHvUBx.js.map → WorkflowsOverview-CCC_KaXz.js.map} +1 -1
  184. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DRBmQXY6.js → YamlWorkflowDetailPage-C3ntUyoZ.js} +11 -11
  185. package/dashboard/dist/assets/{YamlWorkflowDetailPage-DRBmQXY6.js.map → YamlWorkflowDetailPage-C3ntUyoZ.js.map} +1 -1
  186. package/dashboard/dist/assets/{YamlWorkflowsPage-HnI-9eBW.js → YamlWorkflowsPage-ju-9JDXg.js} +2 -2
  187. package/dashboard/dist/assets/{YamlWorkflowsPage-HnI-9eBW.js.map → YamlWorkflowsPage-ju-9JDXg.js.map} +1 -1
  188. package/dashboard/dist/assets/{agents-BA2CvQO9.js → agents-gs9fea8r.js} +2 -2
  189. package/dashboard/dist/assets/{agents-BA2CvQO9.js.map → agents-gs9fea8r.js.map} +1 -1
  190. package/dashboard/dist/assets/bots-DYxAHrob.js +2 -0
  191. package/dashboard/dist/assets/bots-DYxAHrob.js.map +1 -0
  192. package/dashboard/dist/assets/{capabilities-BYBKLRRI.js → capabilities-BJoxz6DJ.js} +2 -2
  193. package/dashboard/dist/assets/{capabilities-BYBKLRRI.js.map → capabilities-BJoxz6DJ.js.map} +1 -1
  194. package/dashboard/dist/assets/{controlplane-H0Ljhb-1.js → controlplane-BeDZgDDf.js} +2 -2
  195. package/dashboard/dist/assets/{controlplane-H0Ljhb-1.js.map → controlplane-BeDZgDDf.js.map} +1 -1
  196. package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js +2 -0
  197. package/dashboard/dist/assets/escalation-columns-CZ4fl0IE.js.map +1 -0
  198. package/dashboard/dist/assets/index-BMM3Xug7.js +2 -0
  199. package/dashboard/dist/assets/index-BMM3Xug7.js.map +1 -0
  200. package/dashboard/dist/assets/{index-BXrm76Hm.js → index-BMXkxgnK.js} +2 -2
  201. package/dashboard/dist/assets/{index-BXrm76Hm.js.map → index-BMXkxgnK.js.map} +1 -1
  202. package/dashboard/dist/assets/{index-CWkAN6wc.js → index-Bj1Mjjiv.js} +2 -2
  203. package/dashboard/dist/assets/{index-CWkAN6wc.js.map → index-Bj1Mjjiv.js.map} +1 -1
  204. package/dashboard/dist/assets/index-BqVb13tE.js +5 -0
  205. package/dashboard/dist/assets/index-BqVb13tE.js.map +1 -0
  206. package/dashboard/dist/assets/{index-YWvrMcqh.js → index-CGrtjUdj.js} +2 -2
  207. package/dashboard/dist/assets/{index-YWvrMcqh.js.map → index-CGrtjUdj.js.map} +1 -1
  208. package/dashboard/dist/assets/{index-DSjih1iX.js → index-CQ8cd4JZ.js} +2 -2
  209. package/dashboard/dist/assets/{index-DSjih1iX.js.map → index-CQ8cd4JZ.js.map} +1 -1
  210. package/dashboard/dist/assets/{index-D1Q8WfGN.js → index-CruL35yU.js} +2 -2
  211. package/dashboard/dist/assets/{index-D1Q8WfGN.js.map → index-CruL35yU.js.map} +1 -1
  212. package/dashboard/dist/assets/index-DAM1Dm1F.js +2 -0
  213. package/dashboard/dist/assets/index-DAM1Dm1F.js.map +1 -0
  214. package/dashboard/dist/assets/{index-CP6D_Gtw.js → index-DZ7PWRg1.js} +2 -2
  215. package/dashboard/dist/assets/{index-CP6D_Gtw.js.map → index-DZ7PWRg1.js.map} +1 -1
  216. package/dashboard/dist/assets/{index-BI-9M7z3.js → index-DfbrPOP3.js} +2 -2
  217. package/dashboard/dist/assets/{index-BI-9M7z3.js.map → index-DfbrPOP3.js.map} +1 -1
  218. package/dashboard/dist/assets/index-DwuM7Fka.js +5 -0
  219. package/dashboard/dist/assets/index-DwuM7Fka.js.map +1 -0
  220. package/dashboard/dist/assets/index-DycfrrTK.js +63 -0
  221. package/dashboard/dist/assets/index-DycfrrTK.js.map +1 -0
  222. package/dashboard/dist/assets/{index-Dx6-4esw.js → index-tbvwCdvQ.js} +2 -2
  223. package/dashboard/dist/assets/{index-Dx6-4esw.js.map → index-tbvwCdvQ.js.map} +1 -1
  224. package/dashboard/dist/assets/index-zP2ncT4m.css +1 -0
  225. package/dashboard/dist/assets/{knowledge-BVbElRHf.js → knowledge-DZnI1Fdk.js} +2 -2
  226. package/dashboard/dist/assets/{knowledge-BVbElRHf.js.map → knowledge-DZnI1Fdk.js.map} +1 -1
  227. package/dashboard/dist/assets/{mcp-CstDdowJ.js → mcp-BB_m6UyI.js} +2 -2
  228. package/dashboard/dist/assets/{mcp-CstDdowJ.js.map → mcp-BB_m6UyI.js.map} +1 -1
  229. package/dashboard/dist/assets/{mcp-query-DHUs0N8H.js → mcp-query-BTSWn0de.js} +2 -2
  230. package/dashboard/dist/assets/{mcp-query-DHUs0N8H.js.map → mcp-query-BTSWn0de.js.map} +1 -1
  231. package/dashboard/dist/assets/{pipelines-BDmAzE3U.js → pipelines-CvGQLyUz.js} +2 -2
  232. package/dashboard/dist/assets/{pipelines-BDmAzE3U.js.map → pipelines-CvGQLyUz.js.map} +1 -1
  233. package/dashboard/dist/assets/task-queues-7-sHKPsN.js +2 -0
  234. package/dashboard/dist/assets/task-queues-7-sHKPsN.js.map +1 -0
  235. package/dashboard/dist/assets/{tasks--qZocuG-.js → tasks-BbgOhCVm.js} +2 -2
  236. package/dashboard/dist/assets/{tasks--qZocuG-.js.map → tasks-BbgOhCVm.js.map} +1 -1
  237. package/dashboard/dist/assets/{topics-P3jkjMsx.js → topics-D9usuYHv.js} +2 -2
  238. package/dashboard/dist/assets/{topics-P3jkjMsx.js.map → topics-D9usuYHv.js.map} +1 -1
  239. package/dashboard/dist/assets/{useEventHooks-CqH8Pasj.js → useEventHooks-DxnqYVPg.js} +2 -2
  240. package/dashboard/dist/assets/{useEventHooks-CqH8Pasj.js.map → useEventHooks-DxnqYVPg.js.map} +1 -1
  241. package/dashboard/dist/assets/{useNamespace-aI3tPfo3.js → useNamespace-CBAn0o5z.js} +2 -2
  242. package/dashboard/dist/assets/{useNamespace-aI3tPfo3.js.map → useNamespace-CBAn0o5z.js.map} +1 -1
  243. package/dashboard/dist/assets/{useYamlActivityEvents-CPVyuW8i.js → useYamlActivityEvents-blOlKGDO.js} +2 -2
  244. package/dashboard/dist/assets/{useYamlActivityEvents-CPVyuW8i.js.map → useYamlActivityEvents-blOlKGDO.js.map} +1 -1
  245. package/dashboard/dist/assets/{users-BrcmIH7O.js → users-CYVJHgNM.js} +2 -2
  246. package/dashboard/dist/assets/{users-BrcmIH7O.js.map → users-CYVJHgNM.js.map} +1 -1
  247. package/dashboard/dist/assets/{vendor-icons-Qk9qLjF_.js → vendor-icons-B98-XxNc.js} +147 -132
  248. package/dashboard/dist/assets/vendor-icons-B98-XxNc.js.map +1 -0
  249. package/dashboard/dist/assets/{workflows-DPhX5L5C.js → workflows-csQAJF0G.js} +2 -2
  250. package/dashboard/dist/assets/{workflows-DPhX5L5C.js.map → workflows-csQAJF0G.js.map} +1 -1
  251. package/dashboard/dist/assets/{yaml-workflows-KZI2cufF.js → yaml-workflows-CctsTDby.js} +2 -2
  252. package/dashboard/dist/assets/{yaml-workflows-KZI2cufF.js.map → yaml-workflows-CctsTDby.js.map} +1 -1
  253. package/dashboard/dist/index.html +3 -3
  254. package/docs/api/http/escalations.md +16 -1
  255. package/docs/api/http/roles.md +4 -0
  256. package/docs/api/http/users.md +39 -0
  257. package/docs/api/sdk/roles.md +5 -0
  258. package/docs/api/sdk/users.md +39 -0
  259. package/docs/hitl/pinned-views.md +45 -0
  260. package/docs/hitl/x-lt-list-schema.md +37 -2
  261. package/docs/hitl/x-lt-show-if.md +11 -0
  262. package/docs/hitl/x-lt-widget.md +22 -0
  263. package/docs/hitl-guide.md +9 -5
  264. package/docs/schema-enforcement.md +149 -0
  265. package/package.json +1 -1
  266. package/dashboard/dist/assets/AgentConfigPage-CW2udbSO.js +0 -16
  267. package/dashboard/dist/assets/AgentConfigPage-CW2udbSO.js.map +0 -1
  268. package/dashboard/dist/assets/AvailableEscalationsPage-Dx51E6s_.js +0 -2
  269. package/dashboard/dist/assets/AvailableEscalationsPage-Dx51E6s_.js.map +0 -1
  270. package/dashboard/dist/assets/BotPicker-KebTxTDi.js +0 -2
  271. package/dashboard/dist/assets/BotPicker-KebTxTDi.js.map +0 -1
  272. package/dashboard/dist/assets/CountdownTimer-DFqEYmiF.js +0 -2
  273. package/dashboard/dist/assets/CountdownTimer-DFqEYmiF.js.map +0 -1
  274. package/dashboard/dist/assets/CustomDurationPicker-BxyjEX27.js.map +0 -1
  275. package/dashboard/dist/assets/GraphInvokePage-Cf9c_LJ-.js.map +0 -1
  276. package/dashboard/dist/assets/HomePage-BdCtKXAV.js +0 -2
  277. package/dashboard/dist/assets/HomePage-BdCtKXAV.js.map +0 -1
  278. package/dashboard/dist/assets/ListToolbar-CDlol8XJ.js +0 -2
  279. package/dashboard/dist/assets/McpRunDetailPage-18d7Iqfy.js +0 -2
  280. package/dashboard/dist/assets/McpRunDetailPage-18d7Iqfy.js.map +0 -1
  281. package/dashboard/dist/assets/OperationsPage-GMojwL3q.js +0 -2
  282. package/dashboard/dist/assets/OperationsPage-GMojwL3q.js.map +0 -1
  283. package/dashboard/dist/assets/RoleDetailPage-Ws3umQKQ.js +0 -8
  284. package/dashboard/dist/assets/RoleDetailPage-Ws3umQKQ.js.map +0 -1
  285. package/dashboard/dist/assets/RolePill-4LO_CuO3.js +0 -2
  286. package/dashboard/dist/assets/RolePill-4LO_CuO3.js.map +0 -1
  287. package/dashboard/dist/assets/RolesPage-D3NNU92h.js +0 -2
  288. package/dashboard/dist/assets/RolesPage-D3NNU92h.js.map +0 -1
  289. package/dashboard/dist/assets/RunAsSelector-Z2Yunqdf.js +0 -2
  290. package/dashboard/dist/assets/ToolPill-BCi101Jh.js +0 -2
  291. package/dashboard/dist/assets/TopicDetailPage-ynUkO1A8.js +0 -9
  292. package/dashboard/dist/assets/TopicDetailPage-ynUkO1A8.js.map +0 -1
  293. package/dashboard/dist/assets/WorkflowExecutionPage-CSw2aQJC.js +0 -2
  294. package/dashboard/dist/assets/WorkflowExecutionPage-CSw2aQJC.js.map +0 -1
  295. package/dashboard/dist/assets/WorkflowPill-DHxrAkp3.js +0 -2
  296. package/dashboard/dist/assets/bots-DHHnoo8x.js +0 -2
  297. package/dashboard/dist/assets/bots-DHHnoo8x.js.map +0 -1
  298. package/dashboard/dist/assets/escalation-columns-BV3Ztn7D.js +0 -2
  299. package/dashboard/dist/assets/escalation-columns-BV3Ztn7D.js.map +0 -1
  300. package/dashboard/dist/assets/index-B4FaugP1.js +0 -2
  301. package/dashboard/dist/assets/index-B4FaugP1.js.map +0 -1
  302. package/dashboard/dist/assets/index-BeFjLCIQ.js +0 -5
  303. package/dashboard/dist/assets/index-BeFjLCIQ.js.map +0 -1
  304. package/dashboard/dist/assets/index-BrEcQQ1p.css +0 -1
  305. package/dashboard/dist/assets/index-CVMA5PVQ.js +0 -2
  306. package/dashboard/dist/assets/index-CVMA5PVQ.js.map +0 -1
  307. package/dashboard/dist/assets/index-O2wWcCLo.js +0 -5
  308. package/dashboard/dist/assets/index-O2wWcCLo.js.map +0 -1
  309. package/dashboard/dist/assets/index-iX8HLLB9.js +0 -63
  310. package/dashboard/dist/assets/index-iX8HLLB9.js.map +0 -1
  311. package/dashboard/dist/assets/vendor-icons-Qk9qLjF_.js.map +0 -1
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * x-lt-bind — maps the escalation FORM (flat field values the user edits) to and
4
+ * from the PAYLOAD (the nested JSON the workflow consumes). A form_schema property
5
+ * may declare `x-lt-bind: "a.b[0].c"`, the path its value occupies in the payload;
6
+ * a property with no bind sits at its own name at the root (1:1). This module is
7
+ * isomorphic — the dashboard renders forms with it, and the API layer inverts a
8
+ * submitted payload through it to validate against the form contract. One
9
+ * implementation, both sides.
10
+ *
11
+ * mapPayloadToForm — payload → flat form values, to PREFILL/display the form
12
+ * (server-side: to validate a submitted payload)
13
+ * mapFormToPayload — flat form values → payload, the shape submitted/stored
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.parsePath = parsePath;
17
+ exports.setDeep = setDeep;
18
+ exports.getDeep = getDeep;
19
+ exports.bindPathFor = bindPathFor;
20
+ exports.mapFormToPayload = mapFormToPayload;
21
+ exports.mapPayloadToForm = mapPayloadToForm;
22
+ const BLOCKED_KEYS = new Set(['__proto__', 'constructor', 'prototype']);
23
+ /** Parse a bind path — dot keys with optional `[n]` indices. Rejects pollution keys. */
24
+ function parsePath(path) {
25
+ const segs = [];
26
+ for (const raw of path.split('.')) {
27
+ const m = raw.match(/^([^[\]]*)((?:\[\d+\])*)$/);
28
+ if (!m)
29
+ throw new Error(`invalid x-lt-bind path segment: "${raw}"`);
30
+ const [, name, brackets] = m;
31
+ if (name) {
32
+ if (BLOCKED_KEYS.has(name))
33
+ throw new Error(`x-lt-bind path may not target "${name}"`);
34
+ segs.push({ key: name });
35
+ }
36
+ for (const b of brackets.match(/\d+/g) ?? [])
37
+ segs.push({ index: Number(b) });
38
+ }
39
+ if (segs.length === 0)
40
+ throw new Error(`empty x-lt-bind path: "${path}"`);
41
+ return segs;
42
+ }
43
+ /** Set `value` at `path` inside `root`, creating intermediate objects/arrays. */
44
+ function setDeep(root, path, value) {
45
+ const segs = parsePath(path);
46
+ let node = root;
47
+ for (let i = 0; i < segs.length - 1; i++) {
48
+ const seg = segs[i];
49
+ const next = segs[i + 1];
50
+ const childKey = 'key' in seg ? seg.key : seg.index;
51
+ const wantArray = 'index' in next;
52
+ if (node[childKey] == null || typeof node[childKey] !== 'object') {
53
+ node[childKey] = wantArray ? [] : {};
54
+ }
55
+ node = node[childKey];
56
+ }
57
+ const last = segs[segs.length - 1];
58
+ node['key' in last ? last.key : last.index] = value;
59
+ }
60
+ /** Read the value at `path` inside `root` (undefined if any segment is missing). */
61
+ function getDeep(root, path) {
62
+ let node = root;
63
+ for (const seg of parsePath(path)) {
64
+ if (node == null || typeof node !== 'object')
65
+ return undefined;
66
+ node = node['key' in seg ? seg.key : seg.index];
67
+ }
68
+ return node;
69
+ }
70
+ /** The bind path for a form property (its `x-lt-bind`, or the property name). */
71
+ function bindPathFor(propName, propDef) {
72
+ const bind = propDef?.['x-lt-bind'];
73
+ return typeof bind === 'string' && bind.length > 0 ? bind : propName;
74
+ }
75
+ /**
76
+ * Assemble the payload from the form's flat values. A field absent from
77
+ * `formValues` is omitted (so clearing/deleting a field drops it from the
78
+ * payload). Unknown keys not declared in the schema are dropped. With no schema
79
+ * properties, values pass through unchanged.
80
+ */
81
+ function mapFormToPayload(formValues, formSchema) {
82
+ const props = formSchema?.properties;
83
+ if (!props)
84
+ return { ...formValues };
85
+ const payload = {};
86
+ for (const [name, def] of Object.entries(props)) {
87
+ if (!(name in formValues))
88
+ continue;
89
+ setDeep(payload, bindPathFor(name, def), formValues[name]);
90
+ }
91
+ return payload;
92
+ }
93
+ /**
94
+ * Reverse of {@link mapFormToPayload}: pull each form field's value out of the
95
+ * payload via its bind path, to prefill/display the form. A field whose bound
96
+ * path is missing from the payload is omitted (the caller falls back to the
97
+ * schema default).
98
+ */
99
+ function mapPayloadToForm(payload, formSchema) {
100
+ const props = formSchema?.properties;
101
+ if (!props)
102
+ return payload ? { ...payload } : {};
103
+ const form = {};
104
+ for (const [name, def] of Object.entries(props)) {
105
+ const v = getDeep(payload, bindPathFor(name, def));
106
+ if (v !== undefined)
107
+ form[name] = v;
108
+ }
109
+ return form;
110
+ }
@@ -0,0 +1,21 @@
1
+ /** The token domains a help template may reference. */
2
+ export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver"];
3
+ export type HelpDomain = (typeof HELP_DOMAINS)[number];
4
+ export type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;
5
+ /** Replace every `{{domain.path}}` token with its value from the context. */
6
+ export declare function interpolateHelp(template: string, ctx: HelpTokenContext): string;
7
+ /** The schema's help source: `x-lt-help` first, `x-lt-context` as fallback. */
8
+ export declare function resolveHelpSource(schema: Record<string, unknown> | null | undefined): string | null;
9
+ /** The schema's help content, interpolated. Null when the schema declares none. */
10
+ export declare function buildHelpMarkdown(schema: Record<string, unknown> | null | undefined, ctx: HelpTokenContext): string | null;
11
+ export interface HelpStateHint {
12
+ isTerminal: boolean;
13
+ status?: string;
14
+ claimed: boolean;
15
+ claimedByMe: boolean;
16
+ }
17
+ /**
18
+ * State-aware guidance shown when the schema carries no help content — the
19
+ * panel always tells the user what this page expects of them right now.
20
+ */
21
+ export declare function defaultHelpMarkdown({ isTerminal, status, claimed, claimedByMe }: HelpStateHint): string;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HELP_DOMAINS = void 0;
4
+ exports.interpolateHelp = interpolateHelp;
5
+ exports.resolveHelpSource = resolveHelpSource;
6
+ exports.buildHelpMarkdown = buildHelpMarkdown;
7
+ exports.defaultHelpMarkdown = defaultHelpMarkdown;
8
+ /**
9
+ * x-lt-help — the form's guidance content, rendered in the side panel beside
10
+ * the resolve form. A form_schema may declare schema-level `x-lt-help`: a
11
+ * markdown string whose `{{domain.path}}` tokens interpolate values from the
12
+ * escalation surface, so help text can reference the live record:
13
+ *
14
+ * {{escalation.role}} — any column on the escalation row
15
+ * {{metadata.schema_version}} — the row's metadata dict
16
+ * {{envelope.formDefaults.customer.name}} — the workflow-sent input envelope
17
+ * {{payload.category}} — the escalation context payload
18
+ * {{resolver.notes}} — the submitted resolver payload
19
+ *
20
+ * Paths reuse the x-lt-bind syntax (`a.b[0].c`). A missing value renders as an
21
+ * em dash. `x-lt-context` is accepted as the plain-text fallback source when
22
+ * `x-lt-help` is absent.
23
+ */
24
+ const x_lt_bind_1 = require("./x-lt-bind");
25
+ /** The token domains a help template may reference. */
26
+ exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver'];
27
+ const TOKEN_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
28
+ const MISSING_VALUE = '—';
29
+ function formatTokenValue(value) {
30
+ if (value === undefined || value === null)
31
+ return MISSING_VALUE;
32
+ if (typeof value === 'string')
33
+ return value;
34
+ if (typeof value === 'number' || typeof value === 'boolean')
35
+ return String(value);
36
+ try {
37
+ return JSON.stringify(value);
38
+ }
39
+ catch {
40
+ return MISSING_VALUE;
41
+ }
42
+ }
43
+ /** Replace every `{{domain.path}}` token with its value from the context. */
44
+ function interpolateHelp(template, ctx) {
45
+ return template.replace(TOKEN_PATTERN, (_match, rawPath) => {
46
+ const dot = rawPath.indexOf('.');
47
+ const domain = (dot === -1 ? rawPath : rawPath.slice(0, dot));
48
+ if (!exports.HELP_DOMAINS.includes(domain))
49
+ return MISSING_VALUE;
50
+ const root = ctx[domain];
51
+ if (dot === -1)
52
+ return formatTokenValue(root);
53
+ try {
54
+ return formatTokenValue((0, x_lt_bind_1.getDeep)(root, rawPath.slice(dot + 1)));
55
+ }
56
+ catch {
57
+ return MISSING_VALUE;
58
+ }
59
+ });
60
+ }
61
+ /** The schema's help source: `x-lt-help` first, `x-lt-context` as fallback. */
62
+ function resolveHelpSource(schema) {
63
+ const help = schema?.['x-lt-help'];
64
+ if (typeof help === 'string' && help.trim().length > 0)
65
+ return help;
66
+ const context = schema?.['x-lt-context'];
67
+ if (typeof context === 'string' && context.trim().length > 0)
68
+ return context;
69
+ return null;
70
+ }
71
+ /** The schema's help content, interpolated. Null when the schema declares none. */
72
+ function buildHelpMarkdown(schema, ctx) {
73
+ const source = resolveHelpSource(schema);
74
+ return source ? interpolateHelp(source, ctx) : null;
75
+ }
76
+ /**
77
+ * State-aware guidance shown when the schema carries no help content — the
78
+ * panel always tells the user what this page expects of them right now.
79
+ */
80
+ function defaultHelpMarkdown({ isTerminal, status, claimed, claimedByMe }) {
81
+ if (isTerminal) {
82
+ return status === 'cancelled'
83
+ ? 'This escalation was cancelled. The record is shown for reference.'
84
+ : 'This escalation has been resolved. The submitted form is shown for reference.';
85
+ }
86
+ if (claimedByMe)
87
+ return 'You have claimed this escalation. Fill out the form and submit to resolve it.';
88
+ if (claimed)
89
+ return 'Another user has claimed this escalation. It unlocks if their claim expires or is released.';
90
+ return 'Claim this escalation to enable the form.';
91
+ }
@@ -0,0 +1,7 @@
1
+ import { type HelpTokenContext } from './x-lt-help';
2
+ export type ShowIfContext = HelpTokenContext;
3
+ /**
4
+ * Evaluates an x-lt-showIf condition. Returns true when the field should be
5
+ * shown. Returns true when condition is absent, non-string, or context is null.
6
+ */
7
+ export declare function evaluateShowIf(condition: unknown, ctx: ShowIfContext | null | undefined): boolean;
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluateShowIf = evaluateShowIf;
4
+ /**
5
+ * x-lt-showIf — conditional field visibility. A form_schema property may
6
+ * declare `x-lt-showIf: "domain.path"` to show the field only when the value
7
+ * at that path is present and truthy. Prefix `!` to invert: show when absent
8
+ * or falsy.
9
+ *
10
+ * Equality forms compare the resolved value's string form:
11
+ * "domain.path=VALUE" — show when String(value) equals VALUE
12
+ * "domain.path!=VALUE" — show when it does not
13
+ * An absent value compares as the empty string, so `=X` is false and `!=X` is
14
+ * true when the path is missing. VALUE is the raw remainder after the operator
15
+ * (trimmed; no quoting). The truthy/! forms are unchanged.
16
+ *
17
+ * Domains follow the same `domain.path` convention as x-lt-help tokens:
18
+ * metadata — the escalation row's metadata dict
19
+ * payload — the escalation context payload (escalation_payload)
20
+ * envelope — the workflow-sent input envelope
21
+ * escalation — top-level escalation row fields
22
+ * resolver — the submitted resolver payload
23
+ *
24
+ * A missing or non-string condition always shows the field (opt-in, safe default).
25
+ */
26
+ const x_lt_bind_1 = require("./x-lt-bind");
27
+ const x_lt_help_1 = require("./x-lt-help");
28
+ function isTruthy(value) {
29
+ return value !== null && value !== undefined && value !== '' && value !== false && value !== 0;
30
+ }
31
+ /** The value's comparable string form; absent compares as the empty string. */
32
+ function asComparable(value) {
33
+ if (value === null || value === undefined)
34
+ return '';
35
+ if (typeof value === 'object')
36
+ return JSON.stringify(value);
37
+ return String(value);
38
+ }
39
+ function resolvePath(expr, ctx) {
40
+ const dot = expr.indexOf('.');
41
+ const domain = (dot === -1 ? expr : expr.slice(0, dot));
42
+ if (!x_lt_help_1.HELP_DOMAINS.includes(domain))
43
+ return { known: false, value: undefined };
44
+ const root = ctx[domain];
45
+ if (dot === -1)
46
+ return { known: true, value: root };
47
+ try {
48
+ return { known: true, value: (0, x_lt_bind_1.getDeep)(root, expr.slice(dot + 1)) };
49
+ }
50
+ catch {
51
+ return { known: true, value: undefined };
52
+ }
53
+ }
54
+ /**
55
+ * Evaluates an x-lt-showIf condition. Returns true when the field should be
56
+ * shown. Returns true when condition is absent, non-string, or context is null.
57
+ */
58
+ function evaluateShowIf(condition, ctx) {
59
+ if (typeof condition !== 'string' || condition.length === 0)
60
+ return true;
61
+ if (!ctx)
62
+ return true;
63
+ const negate = condition.startsWith('!');
64
+ const expr = negate ? condition.slice(1) : condition;
65
+ // Equality forms — `!=` first so it never parses as `=` with a `!` in the path.
66
+ const neqAt = expr.indexOf('!=');
67
+ const eqAt = expr.indexOf('=');
68
+ if (neqAt !== -1 || (eqAt !== -1 && eqAt !== neqAt + 1)) {
69
+ const isNeq = neqAt !== -1 && (eqAt === -1 || neqAt < eqAt);
70
+ const opAt = isNeq ? neqAt : eqAt;
71
+ const path = expr.slice(0, opAt).trim();
72
+ const expected = expr.slice(opAt + (isNeq ? 2 : 1)).trim();
73
+ const { known, value } = resolvePath(path, ctx);
74
+ if (!known)
75
+ return true; // unknown domain — safe default, same as truthy form
76
+ const matches = asComparable(value) === expected;
77
+ const result = isNeq ? !matches : matches;
78
+ return negate ? !result : result;
79
+ }
80
+ const { known, value } = resolvePath(expr, ctx);
81
+ if (!known)
82
+ return true;
83
+ return negate ? !isTruthy(value) : isTruthy(value);
84
+ }
@@ -567,7 +567,22 @@ export declare const updateRoleSchema: z.ZodObject<{
567
567
  worker_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
568
568
  priority_threshold_minutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
569
569
  priority_facet: z.ZodOptional<z.ZodNullable<z.ZodString>>;
570
+ enforce_schema: z.ZodOptional<z.ZodBoolean>;
570
571
  upstream_roles: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
572
+ list_schema: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>>;
573
+ default_pins: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
574
+ label: z.ZodString;
575
+ url: z.ZodString;
576
+ badge: z.ZodOptional<z.ZodBoolean>;
577
+ }, "strip", z.ZodTypeAny, {
578
+ url: string;
579
+ label: string;
580
+ badge?: boolean | undefined;
581
+ }, {
582
+ url: string;
583
+ label: string;
584
+ badge?: boolean | undefined;
585
+ }>, "many">>>;
571
586
  change_summary: z.ZodOptional<z.ZodString>;
572
587
  }, "strip", z.ZodTypeAny, {
573
588
  role: string;
@@ -576,6 +591,12 @@ export declare const updateRoleSchema: z.ZodObject<{
576
591
  title?: string | null | undefined;
577
592
  properties?: Record<string, any> | null | undefined;
578
593
  metadata_schema?: Record<string, any> | null | undefined;
594
+ list_schema?: Record<string, any> | null | undefined;
595
+ default_pins?: {
596
+ url: string;
597
+ label: string;
598
+ badge?: boolean | undefined;
599
+ }[] | null | undefined;
579
600
  ops_visible?: boolean | undefined;
580
601
  parent_role?: string | null | undefined;
581
602
  sla_minutes?: number | null | undefined;
@@ -583,6 +604,7 @@ export declare const updateRoleSchema: z.ZodObject<{
583
604
  worker_count?: number | null | undefined;
584
605
  priority_threshold_minutes?: number | null | undefined;
585
606
  priority_facet?: string | null | undefined;
607
+ enforce_schema?: boolean | undefined;
586
608
  upstream_roles?: string[] | null | undefined;
587
609
  change_summary?: string | undefined;
588
610
  }, {
@@ -592,6 +614,12 @@ export declare const updateRoleSchema: z.ZodObject<{
592
614
  title?: string | null | undefined;
593
615
  properties?: Record<string, any> | null | undefined;
594
616
  metadata_schema?: Record<string, any> | null | undefined;
617
+ list_schema?: Record<string, any> | null | undefined;
618
+ default_pins?: {
619
+ url: string;
620
+ label: string;
621
+ badge?: boolean | undefined;
622
+ }[] | null | undefined;
595
623
  ops_visible?: boolean | undefined;
596
624
  parent_role?: string | null | undefined;
597
625
  sla_minutes?: number | null | undefined;
@@ -599,6 +627,7 @@ export declare const updateRoleSchema: z.ZodObject<{
599
627
  worker_count?: number | null | undefined;
600
628
  priority_threshold_minutes?: number | null | undefined;
601
629
  priority_facet?: string | null | undefined;
630
+ enforce_schema?: boolean | undefined;
602
631
  upstream_roles?: string[] | null | undefined;
603
632
  change_summary?: string | undefined;
604
633
  }>;
@@ -249,7 +249,14 @@ exports.updateRoleSchema = zod_1.z.object({
249
249
  worker_count: zod_1.z.number().nullable().optional().describe('Capacity at this station (staff or machine count). One of the capacity settings.'),
250
250
  priority_threshold_minutes: zod_1.z.number().min(0).nullable().optional().describe('Max age in minutes before a pending unclaimed escalation counts toward the Pace Board priority count. Falls back to sla_minutes when null.'),
251
251
  priority_facet: zod_1.z.string().regex(facet_sql_1.FACET_KEY).nullable().optional().describe('lt_escalations.metadata key holding the age origin for the priority count as an ISO 8601 UTC timestamp (e.g. authorized_at). Falls back to created_at when null. When set, items missing the key or holding an unparseable value are not counted.'),
252
+ enforce_schema: zod_1.z.boolean().optional().describe('When true, every resolve surface validates the submitted resolverPayload against the escalation\'s form schema (the same pass the dashboard runs) and rejects violations with a structured schema_validation error before any state changes.'),
252
253
  upstream_roles: zod_1.z.array(zod_1.z.string()).nullable().optional().describe('Replace the set of roles this station draws input from across other sequences (parent_role stays the single prior step in its own sequence). Omitted = preserve; null or [] = clear.'),
254
+ list_schema: zod_1.z.record(zod_1.z.any()).nullable().optional().describe('JSON contract (x-lt-* markup) that richly formats this role\'s escalation LIST page. Versioned independently of form_schema; the list always renders the latest version.'),
255
+ default_pins: zod_1.z.array(zod_1.z.object({
256
+ label: zod_1.z.string().describe('Pin label shown in the member\'s Pinned nav section'),
257
+ url: zod_1.z.string().describe('Dashboard-relative deep link (must start with /)'),
258
+ badge: zod_1.z.boolean().optional().describe('Render a live count beside the label (escalations-list URLs)'),
259
+ })).nullable().optional().describe('Pinned-view seeds handed to every member of this role. Members promote, hide, or reorder them via their own preferences. Null clears.'),
253
260
  change_summary: zod_1.z.string().optional().describe('Recorded on the schema version snapshot when this update changes form_schema or metadata_schema'),
254
261
  });
255
262
  exports.getRoleSchemaSchema = zod_1.z.object({
@@ -194,9 +194,11 @@ function registerUserTools(server) {
194
194
  server.registerTool('update_role', {
195
195
  title: 'Update Role',
196
196
  description: 'Update role metadata with PATCH semantics — omitted fields keep their ' +
197
- 'values. Covers display name, description, form/metadata schemas, the ' +
198
- 'free properties bag, ops_visible flag, parent role, and the typed ' +
199
- 'operational targets (sla_minutes, target_per_hour, worker_count, ' +
197
+ 'values. Covers display name, description, form/metadata/list schemas, ' +
198
+ 'the free properties bag, ops_visible flag, enforce_schema ' +
199
+ '(server-side resolver validation), parent role, default_pins ' +
200
+ '(member pinned-view seeds), and the typed operational targets ' +
201
+ '(sla_minutes, target_per_hour, worker_count, ' +
200
202
  'priority_threshold_minutes, priority_facet).',
201
203
  inputSchema: schemas_1.updateRoleSchema,
202
204
  }, async (args) => {
@@ -213,7 +215,10 @@ function registerUserTools(server) {
213
215
  worker_count: args.worker_count,
214
216
  priority_threshold_minutes: args.priority_threshold_minutes,
215
217
  priority_facet: args.priority_facet,
218
+ enforce_schema: args.enforce_schema,
216
219
  upstream_roles: args.upstream_roles,
220
+ list_schema: args.list_schema,
221
+ default_pins: args.default_pins,
217
222
  change_summary: args.change_summary,
218
223
  });
219
224
  if (!updated) {
@@ -46,23 +46,23 @@ export declare const claimAndResolveSchema: z.ZodObject<{
46
46
  resolver_id: z.ZodString;
47
47
  payload: z.ZodRecord<z.ZodString, z.ZodAny>;
48
48
  }, "strip", z.ZodTypeAny, {
49
+ payload: Record<string, any>;
49
50
  escalation_id: string;
50
51
  resolver_id: string;
51
- payload: Record<string, any>;
52
52
  }, {
53
+ payload: Record<string, any>;
53
54
  escalation_id: string;
54
55
  resolver_id: string;
55
- payload: Record<string, any>;
56
56
  }>;
57
57
  export declare const resolveEscalationSchema: z.ZodObject<{
58
58
  escalation_id: z.ZodString;
59
59
  payload: z.ZodRecord<z.ZodString, z.ZodAny>;
60
60
  }, "strip", z.ZodTypeAny, {
61
- escalation_id: string;
62
61
  payload: Record<string, any>;
63
- }, {
64
62
  escalation_id: string;
63
+ }, {
65
64
  payload: Record<string, any>;
65
+ escalation_id: string;
66
66
  }>;
67
67
  export declare const escalateAndWaitSchema: z.ZodObject<{
68
68
  role: z.ZodString;
@@ -24,7 +24,10 @@ exports.getAvailableWorkSchema = zod_1.z.object({
24
24
  // The payload is stored exactly as submitted — the resolver payload IS the
25
25
  // payload. Shape it to match the role form's x-lt-bind paths (see the form_schema
26
26
  // check_resolution returns for a pending escalation); no server-side transform.
27
- const RESOLVER_PAYLOAD_DESC = 'Resolution payload, stored as-is. Match the shape the workflow consumes (the form_schema\'s x-lt-bind paths).';
27
+ const RESOLVER_PAYLOAD_DESC = 'Resolution payload, stored as-is. Match the shape the workflow consumes (the form_schema\'s x-lt-bind paths). '
28
+ + 'Roles with enforce_schema validate it server-side: required fields (respecting x-lt-showIf), declared types '
29
+ + '(number vs string), enums, bounds, patterns, and x-lt-require-all checklists. Violations return a '
30
+ + 'schema_validation error listing each field.';
28
31
  exports.claimAndResolveSchema = zod_1.z.object({
29
32
  escalation_id: zod_1.z.string().describe('The escalation ID to claim and resolve'),
30
33
  resolver_id: zod_1.z.string().describe('Identifier for who/what is resolving'),
@@ -40,9 +40,36 @@ const crypto = __importStar(require("crypto"));
40
40
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
41
41
  const logger_1 = require("../../lib/logger");
42
42
  const escalationService = __importStar(require("../../services/escalation"));
43
+ const resolver_validation_1 = require("../../services/escalation/resolver-validation");
44
+ const enforcement_cache_1 = require("../../services/role/enforcement-cache");
43
45
  const escalation_1 = require("../../types/escalation");
44
46
  const human_queue_schemas_1 = require("./human-queue-schemas");
45
47
  let server = null;
48
+ /**
49
+ * Schema enforcement for the MCP resolve tools — the same gate the HTTP
50
+ * surfaces run (agents and the sim workforce submit through these tools, so
51
+ * they get the same contract and the same canonical violation body). Costs
52
+ * zero reads when no role enforces (cached set); otherwise one row read.
53
+ * Returns the MCP error content when the payload is rejected, null to proceed.
54
+ */
55
+ async function checkResolveToolPayload(escalationId, payload) {
56
+ const enforcing = await (0, enforcement_cache_1.getEnforcingRoles)();
57
+ if (enforcing.size === 0)
58
+ return null;
59
+ const escalation = await escalationService.getEscalation(escalationId);
60
+ if (!escalation || !enforcing.has(escalation.role))
61
+ return null;
62
+ const report = await (0, resolver_validation_1.checkResolverPayload)(escalation, payload);
63
+ if (!report)
64
+ return null;
65
+ return {
66
+ content: [{
67
+ type: 'text',
68
+ text: JSON.stringify((0, resolver_validation_1.toValidationErrorBody)(report)),
69
+ }],
70
+ isError: true,
71
+ };
72
+ }
46
73
  /**
47
74
  * Create the Long Tail Human Queue MCP server.
48
75
  *
@@ -129,6 +156,11 @@ async function createHumanQueueServer(options) {
129
156
  else if (escalation.status === 'pending' && detail.form_schema) {
130
157
  // The shape the resolver payload should take (fields + x-lt-bind paths).
131
158
  result.form_schema = detail.form_schema;
159
+ // Tell the agent when this role ENFORCES the form: an incomplete or
160
+ // mis-typed payload will be rejected with a schema_validation error.
161
+ if ((await (0, enforcement_cache_1.getEnforcingRoles)()).has(escalation.role)) {
162
+ result.schema_enforced = true;
163
+ }
132
164
  }
133
165
  return {
134
166
  content: [{ type: 'text', text: JSON.stringify(result) }],
@@ -163,9 +195,13 @@ async function createHumanQueueServer(options) {
163
195
  // ── claim_and_resolve ───────────────────────────────────────────────
164
196
  server.registerTool('claim_and_resolve', {
165
197
  title: 'Claim and Resolve',
166
- description: 'Claim an escalation and immediately resolve it with a payload. Atomic operation.',
198
+ description: 'Claim an escalation and immediately resolve it with a payload. Atomic operation. Roles with enforce_schema validate the payload against the form_schema (see check_resolution) and reject violations with a schema_validation error listing each field.',
167
199
  inputSchema: human_queue_schemas_1.claimAndResolveSchema,
168
200
  }, async (args) => {
201
+ // Validate BEFORE claiming — a rejected payload must never strand a claim.
202
+ const rejected = await checkResolveToolPayload(args.escalation_id, args.payload);
203
+ if (rejected)
204
+ return rejected;
169
205
  const claimed = await escalationService.claimEscalation(args.escalation_id, args.resolver_id, 5);
170
206
  if (!claimed) {
171
207
  return {
@@ -200,9 +236,12 @@ async function createHumanQueueServer(options) {
200
236
  // ── resolve_escalation ──────────────────────────────────────────────
201
237
  server.registerTool('resolve_escalation', {
202
238
  title: 'Resolve Escalation',
203
- description: 'Resolve an already-claimed escalation with a payload. Use when the claim happened externally (e.g. via API).',
239
+ description: 'Resolve an already-claimed escalation with a payload. Use when the claim happened externally (e.g. via API). Roles with enforce_schema validate the payload against the form_schema (see check_resolution) and reject violations with a schema_validation error listing each field.',
204
240
  inputSchema: human_queue_schemas_1.resolveEscalationSchema,
205
241
  }, async (args) => {
242
+ const rejected = await checkResolveToolPayload(args.escalation_id, args.payload);
243
+ if (rejected)
244
+ return rejected;
206
245
  const resolved = await escalationService.resolveEscalation(args.escalation_id, args.payload);
207
246
  if (!resolved) {
208
247
  return {