@hotmeshio/long-tail 0.6.2 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/build/api/escalations/create.js +45 -0
  2. package/build/api/escalations/index.d.ts +1 -1
  3. package/build/api/escalations/index.js +2 -1
  4. package/build/api/escalations/list.d.ts +3 -0
  5. package/build/api/escalations/list.js +14 -0
  6. package/build/api/roles.d.ts +17 -0
  7. package/build/api/roles.js +46 -0
  8. package/build/bin/ltc.js +1 -0
  9. package/build/lib/cli/commands/escalations.d.ts +1 -0
  10. package/build/lib/cli/commands/escalations.js +2 -0
  11. package/build/lib/db/migrate.js +22 -2
  12. package/build/lib/db/schemas/014_roles_v2.sql +19 -0
  13. package/build/lib/db/schemas/015_role_ops.sql +50 -0
  14. package/build/lib/db/schemas/016_station_metrics_indexes.sql +13 -0
  15. package/build/lib/events/system-events.js +3 -0
  16. package/build/modules/auth.d.ts +9 -0
  17. package/build/modules/auth.js +38 -1
  18. package/build/routes/escalations/list.js +10 -0
  19. package/build/routes/roles.js +16 -5
  20. package/build/scripts/ortho-populate.d.ts +37 -0
  21. package/build/scripts/ortho-populate.js +228 -0
  22. package/build/sdk/index.d.ts +4 -0
  23. package/build/sdk/index.js +2 -0
  24. package/build/services/escalation/client.js +93 -2
  25. package/build/services/escalation/crud.js +18 -9
  26. package/build/services/escalation/metrics-cache.d.ts +14 -0
  27. package/build/services/escalation/metrics-cache.js +53 -0
  28. package/build/services/escalation/queries.d.ts +14 -2
  29. package/build/services/escalation/queries.js +121 -11
  30. package/build/services/escalation/sql.d.ts +29 -2
  31. package/build/services/escalation/sql.js +156 -27
  32. package/build/services/escalation/types.d.ts +17 -0
  33. package/build/services/escalation/types.js +1 -0
  34. package/build/services/interceptor/completion.js +17 -12
  35. package/build/services/mcp/external-server.js +5 -1
  36. package/build/services/orchestrator/condition.d.ts +20 -0
  37. package/build/services/orchestrator/condition.js +20 -0
  38. package/build/services/role/index.d.ts +22 -3
  39. package/build/services/role/index.js +50 -2
  40. package/build/services/role/sql.d.ts +11 -1
  41. package/build/services/role/sql.js +38 -1
  42. package/build/services/role/types.d.ts +32 -0
  43. package/build/system/mcp-servers/admin/escalations.js +8 -7
  44. package/build/system/mcp-servers/admin/index.js +5 -3
  45. package/build/system/mcp-servers/admin/ortho.d.ts +10 -0
  46. package/build/system/mcp-servers/admin/ortho.js +242 -0
  47. package/build/system/mcp-servers/admin/schemas.d.ts +40 -3
  48. package/build/system/mcp-servers/admin/schemas.js +17 -4
  49. package/build/system/mcp-servers/admin/users.js +31 -0
  50. package/build/system/seed/tool-manifests-admin.d.ts +4016 -712
  51. package/build/system/seed/tool-manifests-admin.js +14 -1
  52. package/build/tsconfig.tsbuildinfo +1 -1
  53. package/build/types/escalation.d.ts +3 -1
  54. package/dashboard/dist/assets/{AdminDashboard-C5gfVEeL.js → AdminDashboard-Bg1HgukI.js} +2 -2
  55. package/dashboard/dist/assets/{AdminDashboard-C5gfVEeL.js.map → AdminDashboard-Bg1HgukI.js.map} +1 -1
  56. package/dashboard/dist/assets/{AgentConfigPage-CWEnuiGN.js → AgentConfigPage-HBe_YDU_.js} +6 -6
  57. package/dashboard/dist/assets/{AgentConfigPage-CWEnuiGN.js.map → AgentConfigPage-HBe_YDU_.js.map} +1 -1
  58. package/dashboard/dist/assets/{AgentDetailPage-B6IE27iK.js → AgentDetailPage-BsaiYbwL.js} +4 -4
  59. package/dashboard/dist/assets/{AgentDetailPage-B6IE27iK.js.map → AgentDetailPage-BsaiYbwL.js.map} +1 -1
  60. package/dashboard/dist/assets/AgentsPage-DhN2lIBh.js +2 -0
  61. package/dashboard/dist/assets/{AgentsPage-Blhh2RsK.js.map → AgentsPage-DhN2lIBh.js.map} +1 -1
  62. package/dashboard/dist/assets/AvailableEscalationsPage-_xcWvlIz.js +2 -0
  63. package/dashboard/dist/assets/AvailableEscalationsPage-_xcWvlIz.js.map +1 -0
  64. package/dashboard/dist/assets/{BotPicker-DSozotGk.js → BotPicker-DY6iUVC9.js} +2 -2
  65. package/dashboard/dist/assets/{BotPicker-DSozotGk.js.map → BotPicker-DY6iUVC9.js.map} +1 -1
  66. package/dashboard/dist/assets/{CapabilitiesPage-CrS_DTA1.js → CapabilitiesPage-w1owqsmN.js} +2 -2
  67. package/dashboard/dist/assets/{CapabilitiesPage-CrS_DTA1.js.map → CapabilitiesPage-w1owqsmN.js.map} +1 -1
  68. package/dashboard/dist/assets/{CollapsibleSection-1i6bOQ1L.js → CollapsibleSection-DIMGjlJ-.js} +2 -2
  69. package/dashboard/dist/assets/{CollapsibleSection-1i6bOQ1L.js.map → CollapsibleSection-DIMGjlJ-.js.map} +1 -1
  70. package/dashboard/dist/assets/{CredentialsPage-BxJio06E.js → CredentialsPage-D1OmMHux.js} +2 -2
  71. package/dashboard/dist/assets/{CredentialsPage-BxJio06E.js.map → CredentialsPage-D1OmMHux.js.map} +1 -1
  72. package/dashboard/dist/assets/{CronLabel-BAfIHHz4.js → CronLabel-CQy3DrUQ.js} +2 -2
  73. package/dashboard/dist/assets/{CronLabel-BAfIHHz4.js.map → CronLabel-CQy3DrUQ.js.map} +1 -1
  74. package/dashboard/dist/assets/{CustomDurationPicker-BLF0NFJK.js → CustomDurationPicker-BoBkl9tw.js} +2 -2
  75. package/dashboard/dist/assets/{CustomDurationPicker-BLF0NFJK.js.map → CustomDurationPicker-BoBkl9tw.js.map} +1 -1
  76. package/dashboard/dist/assets/{DropZone-CEx_wk-g.js → DropZone-QXbiuU0b.js} +2 -2
  77. package/dashboard/dist/assets/{DropZone-CEx_wk-g.js.map → DropZone-QXbiuU0b.js.map} +1 -1
  78. package/dashboard/dist/assets/{ElapsedCell-nKGJvznH.js → ElapsedCell-Donjm9gT.js} +2 -2
  79. package/dashboard/dist/assets/{ElapsedCell-nKGJvznH.js.map → ElapsedCell-Donjm9gT.js.map} +1 -1
  80. package/dashboard/dist/assets/{EscalationsOverview-bNNVA6R2.js → EscalationsOverview-CvHIJ_GG.js} +2 -2
  81. package/dashboard/dist/assets/{EscalationsOverview-bNNVA6R2.js.map → EscalationsOverview-CvHIJ_GG.js.map} +1 -1
  82. package/dashboard/dist/assets/{EventTable-BCuDdqlU.js → EventTable-DpAXMmT3.js} +2 -2
  83. package/dashboard/dist/assets/{EventTable-BCuDdqlU.js.map → EventTable-DpAXMmT3.js.map} +1 -1
  84. package/dashboard/dist/assets/{GraphInvokePage-BPAvqHls.js → GraphInvokePage-De1XVx5d.js} +2 -2
  85. package/dashboard/dist/assets/{GraphInvokePage-BPAvqHls.js.map → GraphInvokePage-De1XVx5d.js.map} +1 -1
  86. package/dashboard/dist/assets/HomePage-BYR5VXXw.js +2 -0
  87. package/dashboard/dist/assets/HomePage-BYR5VXXw.js.map +1 -0
  88. package/dashboard/dist/assets/{ListToolbar-DIJZfEgu.js → ListToolbar-Bx7jGzPA.js} +2 -2
  89. package/dashboard/dist/assets/{ListToolbar-DIJZfEgu.js.map → ListToolbar-Bx7jGzPA.js.map} +1 -1
  90. package/dashboard/dist/assets/{McpOverview-DCfSCfPg.js → McpOverview-DXRKcJN0.js} +2 -2
  91. package/dashboard/dist/assets/{McpOverview-DCfSCfPg.js.map → McpOverview-DXRKcJN0.js.map} +1 -1
  92. package/dashboard/dist/assets/{McpQueryDetailPage-mb7rmtNe.js → McpQueryDetailPage-CmW15w5e.js} +2 -2
  93. package/dashboard/dist/assets/{McpQueryDetailPage-mb7rmtNe.js.map → McpQueryDetailPage-CmW15w5e.js.map} +1 -1
  94. package/dashboard/dist/assets/{McpQueryPage-D9b1T0I3.js → McpQueryPage-BE6I011z.js} +2 -2
  95. package/dashboard/dist/assets/{McpQueryPage-D9b1T0I3.js.map → McpQueryPage-BE6I011z.js.map} +1 -1
  96. package/dashboard/dist/assets/{McpRunDetailPage-Bz2UyuNm.js → McpRunDetailPage-Dsa3G3XQ.js} +2 -2
  97. package/dashboard/dist/assets/{McpRunDetailPage-Bz2UyuNm.js.map → McpRunDetailPage-Dsa3G3XQ.js.map} +1 -1
  98. package/dashboard/dist/assets/{McpRunsPage-Dw7w_ZO-.js → McpRunsPage-uTbym66Y.js} +2 -2
  99. package/dashboard/dist/assets/{McpRunsPage-Dw7w_ZO-.js.map → McpRunsPage-uTbym66Y.js.map} +1 -1
  100. package/dashboard/dist/assets/{NamespacePill-D27vqDXy.js → NamespacePill-BGf0jHwE.js} +2 -2
  101. package/dashboard/dist/assets/{NamespacePill-D27vqDXy.js.map → NamespacePill-BGf0jHwE.js.map} +1 -1
  102. package/dashboard/dist/assets/OperationsPage-CAmiFHI6.js +2 -0
  103. package/dashboard/dist/assets/OperationsPage-CAmiFHI6.js.map +1 -0
  104. package/dashboard/dist/assets/{OperatorDashboard-CTzSDW3N.js → OperatorDashboard-i8cxaDlk.js} +2 -2
  105. package/dashboard/dist/assets/{OperatorDashboard-CTzSDW3N.js.map → OperatorDashboard-i8cxaDlk.js.map} +1 -1
  106. package/dashboard/dist/assets/{PageHeader-B_1zTx2q.js → PageHeader-BZJsEVOC.js} +2 -2
  107. package/dashboard/dist/assets/{PageHeader-B_1zTx2q.js.map → PageHeader-BZJsEVOC.js.map} +1 -1
  108. package/dashboard/dist/assets/{PageHeaderWithStats-D-cPg7UD.js → PageHeaderWithStats-BWuD7s9c.js} +2 -2
  109. package/dashboard/dist/assets/{PageHeaderWithStats-D-cPg7UD.js.map → PageHeaderWithStats-BWuD7s9c.js.map} +1 -1
  110. package/dashboard/dist/assets/{ProcessDetailPage-olG2CS-h.js → ProcessDetailPage-CP7GZhgs.js} +2 -2
  111. package/dashboard/dist/assets/{ProcessDetailPage-olG2CS-h.js.map → ProcessDetailPage-CP7GZhgs.js.map} +1 -1
  112. package/dashboard/dist/assets/{ProcessesListPage-CUZSL06Y.js → ProcessesListPage-btsU6hBR.js} +2 -2
  113. package/dashboard/dist/assets/{ProcessesListPage-CUZSL06Y.js.map → ProcessesListPage-btsU6hBR.js.map} +1 -1
  114. package/dashboard/dist/assets/RoleDetailPage-BB_e330f.js +16 -0
  115. package/dashboard/dist/assets/RoleDetailPage-BB_e330f.js.map +1 -0
  116. package/dashboard/dist/assets/{RolePill-B-V-31lC.js → RolePill-Pb9TKSQN.js} +2 -2
  117. package/dashboard/dist/assets/{RolePill-B-V-31lC.js.map → RolePill-Pb9TKSQN.js.map} +1 -1
  118. package/dashboard/dist/assets/RolesPage-1DBoEMsb.js +2 -0
  119. package/dashboard/dist/assets/RolesPage-1DBoEMsb.js.map +1 -0
  120. package/dashboard/dist/assets/{RunAsSelector-BoLHF4fy.js → RunAsSelector-Cp6j3FEY.js} +2 -2
  121. package/dashboard/dist/assets/{RunAsSelector-BoLHF4fy.js.map → RunAsSelector-Cp6j3FEY.js.map} +1 -1
  122. package/dashboard/dist/assets/StatusBadge-D9MeQHrh.js +2 -0
  123. package/dashboard/dist/assets/StatusBadge-D9MeQHrh.js.map +1 -0
  124. package/dashboard/dist/assets/{StickyPagination-BEMY1L-H.js → StickyPagination-Pr8kawv8.js} +2 -2
  125. package/dashboard/dist/assets/{StickyPagination-BEMY1L-H.js.map → StickyPagination-Pr8kawv8.js.map} +1 -1
  126. package/dashboard/dist/assets/StreamMessageDetail-BqmQ-N3y.js +2 -0
  127. package/dashboard/dist/assets/{StreamMessageDetail-CVRVWXcU.js.map → StreamMessageDetail-BqmQ-N3y.js.map} +1 -1
  128. package/dashboard/dist/assets/{SwimlaneTimeline-DDpU0-Jn.js → SwimlaneTimeline-y1YmXrsj.js} +2 -2
  129. package/dashboard/dist/assets/{SwimlaneTimeline-DDpU0-Jn.js.map → SwimlaneTimeline-y1YmXrsj.js.map} +1 -1
  130. package/dashboard/dist/assets/{TagInput-BHVfG307.js → TagInput-Df4myuYF.js} +2 -2
  131. package/dashboard/dist/assets/{TagInput-BHVfG307.js.map → TagInput-Df4myuYF.js.map} +1 -1
  132. package/dashboard/dist/assets/{TaskDetailPage-B_xQtJMg.js → TaskDetailPage-CT5rXHK5.js} +2 -2
  133. package/dashboard/dist/assets/{TaskDetailPage-B_xQtJMg.js.map → TaskDetailPage-CT5rXHK5.js.map} +1 -1
  134. package/dashboard/dist/assets/{TaskQueuePill-CGlxXqWt.js → TaskQueuePill-YalYdCNo.js} +2 -2
  135. package/dashboard/dist/assets/{TaskQueuePill-CGlxXqWt.js.map → TaskQueuePill-YalYdCNo.js.map} +1 -1
  136. package/dashboard/dist/assets/{TasksListPage-CsrdIOKk.js → TasksListPage-DOy6JlKS.js} +2 -2
  137. package/dashboard/dist/assets/{TasksListPage-CsrdIOKk.js.map → TasksListPage-DOy6JlKS.js.map} +1 -1
  138. package/dashboard/dist/assets/{TimeAgo-DmicaxjT.js → TimeAgo-BAQwZSpq.js} +2 -2
  139. package/dashboard/dist/assets/{TimeAgo-DmicaxjT.js.map → TimeAgo-BAQwZSpq.js.map} +1 -1
  140. package/dashboard/dist/assets/{TimestampCell-DeK89eRV.js → TimestampCell-BK_jufns.js} +2 -2
  141. package/dashboard/dist/assets/{TimestampCell-DeK89eRV.js.map → TimestampCell-BK_jufns.js.map} +1 -1
  142. package/dashboard/dist/assets/{ToolPill-NV7PxSpA.js → ToolPill-VGpT6Quy.js} +2 -2
  143. package/dashboard/dist/assets/{ToolPill-NV7PxSpA.js.map → ToolPill-VGpT6Quy.js.map} +1 -1
  144. package/dashboard/dist/assets/{ToolTestPanel-D3s2n9-9.js → ToolTestPanel-5PMQyUCe.js} +2 -2
  145. package/dashboard/dist/assets/{ToolTestPanel-D3s2n9-9.js.map → ToolTestPanel-5PMQyUCe.js.map} +1 -1
  146. package/dashboard/dist/assets/{TopicDetailPage-qyv7UWT_.js → TopicDetailPage-Cn1ShfR8.js} +3 -3
  147. package/dashboard/dist/assets/{TopicDetailPage-qyv7UWT_.js.map → TopicDetailPage-Cn1ShfR8.js.map} +1 -1
  148. package/dashboard/dist/assets/{TopicsPage-CEUfMoed.js → TopicsPage-D67tjS8L.js} +2 -2
  149. package/dashboard/dist/assets/{TopicsPage-CEUfMoed.js.map → TopicsPage-D67tjS8L.js.map} +1 -1
  150. package/dashboard/dist/assets/{UserName-Bn_BxI8K.js → UserName-Dsu1Jk4N.js} +2 -2
  151. package/dashboard/dist/assets/{UserName-Bn_BxI8K.js.map → UserName-Dsu1Jk4N.js.map} +1 -1
  152. package/dashboard/dist/assets/{WorkflowExecutionPage-DAk2RqpB.js → WorkflowExecutionPage-BwQoOmUE.js} +2 -2
  153. package/dashboard/dist/assets/{WorkflowExecutionPage-DAk2RqpB.js.map → WorkflowExecutionPage-BwQoOmUE.js.map} +1 -1
  154. package/dashboard/dist/assets/{WorkflowPill-DDR0B6DN.js → WorkflowPill-pPUqmx6Q.js} +2 -2
  155. package/dashboard/dist/assets/{WorkflowPill-DDR0B6DN.js.map → WorkflowPill-pPUqmx6Q.js.map} +1 -1
  156. package/dashboard/dist/assets/{WorkflowsDashboard-DfBgM80t.js → WorkflowsDashboard-D3z7COgH.js} +2 -2
  157. package/dashboard/dist/assets/{WorkflowsDashboard-DfBgM80t.js.map → WorkflowsDashboard-D3z7COgH.js.map} +1 -1
  158. package/dashboard/dist/assets/{WorkflowsOverview--Dkoo9Jq.js → WorkflowsOverview-C15JcxyY.js} +2 -2
  159. package/dashboard/dist/assets/{WorkflowsOverview--Dkoo9Jq.js.map → WorkflowsOverview-C15JcxyY.js.map} +1 -1
  160. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B6HYbfFj.js → YamlWorkflowDetailPage-BYq3t7E-.js} +2 -2
  161. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B6HYbfFj.js.map → YamlWorkflowDetailPage-BYq3t7E-.js.map} +1 -1
  162. package/dashboard/dist/assets/YamlWorkflowsPage-B44WgwE_.js +2 -0
  163. package/dashboard/dist/assets/{YamlWorkflowsPage-CJE-PxC0.js.map → YamlWorkflowsPage-B44WgwE_.js.map} +1 -1
  164. package/dashboard/dist/assets/{agents-DUciUZpt.js → agents-BRmmK6Y9.js} +2 -2
  165. package/dashboard/dist/assets/{agents-DUciUZpt.js.map → agents-BRmmK6Y9.js.map} +1 -1
  166. package/dashboard/dist/assets/{bots-BnyqCfuC.js → bots-BD75mzGG.js} +2 -2
  167. package/dashboard/dist/assets/{bots-BnyqCfuC.js.map → bots-BD75mzGG.js.map} +1 -1
  168. package/dashboard/dist/assets/{capabilities-CkTWWT0q.js → capabilities-DDgC_Kds.js} +2 -2
  169. package/dashboard/dist/assets/{capabilities-CkTWWT0q.js.map → capabilities-DDgC_Kds.js.map} +1 -1
  170. package/dashboard/dist/assets/controlplane-BJh12lMv.js +2 -0
  171. package/dashboard/dist/assets/controlplane-BJh12lMv.js.map +1 -0
  172. package/dashboard/dist/assets/{escalation-De9JnTKI.js → escalation-DIJt2sgn.js} +2 -2
  173. package/dashboard/dist/assets/{escalation-De9JnTKI.js.map → escalation-DIJt2sgn.js.map} +1 -1
  174. package/dashboard/dist/assets/{escalation-columns-Df7Pluzg.js → escalation-columns-zl6E94Up.js} +2 -2
  175. package/dashboard/dist/assets/{escalation-columns-Df7Pluzg.js.map → escalation-columns-zl6E94Up.js.map} +1 -1
  176. package/dashboard/dist/assets/{index-Cqjf-yVP.js → index-B0kmiSmt.js} +2 -2
  177. package/dashboard/dist/assets/{index-Cqjf-yVP.js.map → index-B0kmiSmt.js.map} +1 -1
  178. package/dashboard/dist/assets/index-BRtKQtQZ.css +1 -0
  179. package/dashboard/dist/assets/{index-BxdiKgnH.js → index-BUbzfEA9.js} +2 -2
  180. package/dashboard/dist/assets/{index-BxdiKgnH.js.map → index-BUbzfEA9.js.map} +1 -1
  181. package/dashboard/dist/assets/{index-DpAS4-DA.js → index-BhznDv-4.js} +2 -2
  182. package/dashboard/dist/assets/{index-DpAS4-DA.js.map → index-BhznDv-4.js.map} +1 -1
  183. package/dashboard/dist/assets/{index-BAhkWcOq.js → index-CDPBXB4e.js} +4 -4
  184. package/dashboard/dist/assets/{index-BAhkWcOq.js.map → index-CDPBXB4e.js.map} +1 -1
  185. package/dashboard/dist/assets/{index-CgD9fA9P.js → index-CV4lEd4I.js} +2 -2
  186. package/dashboard/dist/assets/{index-CgD9fA9P.js.map → index-CV4lEd4I.js.map} +1 -1
  187. package/dashboard/dist/assets/{index-DjxTV3cn.js → index-CknKy4RA.js} +2 -2
  188. package/dashboard/dist/assets/{index-DjxTV3cn.js.map → index-CknKy4RA.js.map} +1 -1
  189. package/dashboard/dist/assets/{index-DNugmBs7.js → index-CpgV4Kkp.js} +2 -2
  190. package/dashboard/dist/assets/{index-DNugmBs7.js.map → index-CpgV4Kkp.js.map} +1 -1
  191. package/dashboard/dist/assets/{index-B1kc6itM.js → index-CtDf8vvQ.js} +24 -24
  192. package/dashboard/dist/assets/index-CtDf8vvQ.js.map +1 -0
  193. package/dashboard/dist/assets/{index-BzMsh6Ui.js → index-DU7YumVJ.js} +2 -2
  194. package/dashboard/dist/assets/{index-BzMsh6Ui.js.map → index-DU7YumVJ.js.map} +1 -1
  195. package/dashboard/dist/assets/{index-BsIaUbKD.js → index-DVVIeBBk.js} +2 -2
  196. package/dashboard/dist/assets/{index-BsIaUbKD.js.map → index-DVVIeBBk.js.map} +1 -1
  197. package/dashboard/dist/assets/index-DccCwyZl.js +6 -0
  198. package/dashboard/dist/assets/{index-CN0efCE9.js.map → index-DccCwyZl.js.map} +1 -1
  199. package/dashboard/dist/assets/{index-7hqtQI43.js → index-DrUkTcn-.js} +2 -2
  200. package/dashboard/dist/assets/{index-7hqtQI43.js.map → index-DrUkTcn-.js.map} +1 -1
  201. package/dashboard/dist/assets/{index-B07xLlyz.js → index-j-C7g_Ej.js} +2 -2
  202. package/dashboard/dist/assets/{index-B07xLlyz.js.map → index-j-C7g_Ej.js.map} +1 -1
  203. package/dashboard/dist/assets/{knowledge-D4SvdNv5.js → knowledge-pNDWACXB.js} +2 -2
  204. package/dashboard/dist/assets/{knowledge-D4SvdNv5.js.map → knowledge-pNDWACXB.js.map} +1 -1
  205. package/dashboard/dist/assets/{mcp-query-CLP9EnnU.js → mcp-query-CmNjvxTG.js} +2 -2
  206. package/dashboard/dist/assets/{mcp-query-CLP9EnnU.js.map → mcp-query-CmNjvxTG.js.map} +1 -1
  207. package/dashboard/dist/assets/{mcp-DVxt4T9J.js → mcp-xddLBwUW.js} +2 -2
  208. package/dashboard/dist/assets/{mcp-DVxt4T9J.js.map → mcp-xddLBwUW.js.map} +1 -1
  209. package/dashboard/dist/assets/pipelines-B05sd2nB.js +2 -0
  210. package/dashboard/dist/assets/pipelines-B05sd2nB.js.map +1 -0
  211. package/dashboard/dist/assets/roles-bRgaMcdy.js +2 -0
  212. package/dashboard/dist/assets/roles-bRgaMcdy.js.map +1 -0
  213. package/dashboard/dist/assets/tasks-Bm1OKrJA.js +2 -0
  214. package/dashboard/dist/assets/{tasks-1eTuP02d.js.map → tasks-Bm1OKrJA.js.map} +1 -1
  215. package/dashboard/dist/assets/{topics-B3p8K0PW.js → topics-BVIqtmd4.js} +2 -2
  216. package/dashboard/dist/assets/{topics-B3p8K0PW.js.map → topics-BVIqtmd4.js.map} +1 -1
  217. package/dashboard/dist/assets/useEventHooks-_qCzU74s.js +2 -0
  218. package/dashboard/dist/assets/useEventHooks-_qCzU74s.js.map +1 -0
  219. package/dashboard/dist/assets/{useNamespace-Dx81_JM0.js → useNamespace-CDnCSFpG.js} +2 -2
  220. package/dashboard/dist/assets/{useNamespace-Dx81_JM0.js.map → useNamespace-CDnCSFpG.js.map} +1 -1
  221. package/dashboard/dist/assets/{useYamlActivityEvents-D5T3TbE7.js → useYamlActivityEvents-zrHMhaFM.js} +2 -2
  222. package/dashboard/dist/assets/{useYamlActivityEvents-D5T3TbE7.js.map → useYamlActivityEvents-zrHMhaFM.js.map} +1 -1
  223. package/dashboard/dist/assets/{users-BEMysNdR.js → users-BPBMZg27.js} +2 -2
  224. package/dashboard/dist/assets/{users-BEMysNdR.js.map → users-BPBMZg27.js.map} +1 -1
  225. package/dashboard/dist/assets/{vendor-icons--Ivmp-RX.js → vendor-icons-C1zVP_dv.js} +125 -115
  226. package/dashboard/dist/assets/vendor-icons-C1zVP_dv.js.map +1 -0
  227. package/dashboard/dist/assets/workflows-CT6nTL1I.js +2 -0
  228. package/dashboard/dist/assets/workflows-CT6nTL1I.js.map +1 -0
  229. package/dashboard/dist/assets/{yaml-workflows-4rJ5v5rJ.js → yaml-workflows-CdfjkOKU.js} +2 -2
  230. package/dashboard/dist/assets/{yaml-workflows-4rJ5v5rJ.js.map → yaml-workflows-CdfjkOKU.js.map} +1 -1
  231. package/dashboard/dist/index.html +3 -3
  232. package/docs/api/http/escalations.md +82 -6
  233. package/docs/api/http/roles.md +82 -3
  234. package/docs/api/mcp/admin.md +127 -1
  235. package/docs/api/sdk/escalations.md +65 -4
  236. package/docs/api/sdk/roles.md +81 -0
  237. package/docs/cli.md +2 -0
  238. package/docs/dashboard.md +17 -2
  239. package/docs/hitl-guide.md +12 -3
  240. package/docs/operations.md +113 -0
  241. package/package.json +3 -2
  242. package/dashboard/dist/assets/AgentsPage-Blhh2RsK.js +0 -2
  243. package/dashboard/dist/assets/AvailableEscalationsPage-ClwAle76.js +0 -2
  244. package/dashboard/dist/assets/AvailableEscalationsPage-ClwAle76.js.map +0 -1
  245. package/dashboard/dist/assets/HomePage-BZ1YTrjR.js +0 -2
  246. package/dashboard/dist/assets/HomePage-BZ1YTrjR.js.map +0 -1
  247. package/dashboard/dist/assets/RolesPage-DLnaW6iD.js +0 -2
  248. package/dashboard/dist/assets/RolesPage-DLnaW6iD.js.map +0 -1
  249. package/dashboard/dist/assets/StatusBadge-Bl3FXVmF.js +0 -2
  250. package/dashboard/dist/assets/StatusBadge-Bl3FXVmF.js.map +0 -1
  251. package/dashboard/dist/assets/StreamMessageDetail-CVRVWXcU.js +0 -2
  252. package/dashboard/dist/assets/YamlWorkflowsPage-CJE-PxC0.js +0 -2
  253. package/dashboard/dist/assets/controlplane-D9HaFZsC.js +0 -2
  254. package/dashboard/dist/assets/controlplane-D9HaFZsC.js.map +0 -1
  255. package/dashboard/dist/assets/index-B1kc6itM.js.map +0 -1
  256. package/dashboard/dist/assets/index-CN0efCE9.js +0 -6
  257. package/dashboard/dist/assets/index-nO0cim3_.css +0 -1
  258. package/dashboard/dist/assets/pipelines-C_x0LTBN.js +0 -2
  259. package/dashboard/dist/assets/pipelines-C_x0LTBN.js.map +0 -1
  260. package/dashboard/dist/assets/roles-QaGFZQ58.js +0 -2
  261. package/dashboard/dist/assets/roles-QaGFZQ58.js.map +0 -1
  262. package/dashboard/dist/assets/tasks-1eTuP02d.js +0 -2
  263. package/dashboard/dist/assets/useEventHooks-BNZky4xM.js +0 -2
  264. package/dashboard/dist/assets/useEventHooks-BNZky4xM.js.map +0 -1
  265. package/dashboard/dist/assets/vendor-icons--Ivmp-RX.js.map +0 -1
  266. package/dashboard/dist/assets/workflows-C4rjvQbI.js +0 -2
  267. package/dashboard/dist/assets/workflows-C4rjvQbI.js.map +0 -1
@@ -9,6 +9,9 @@ exports.canEscalateTo = canEscalateTo;
9
9
  exports.listDistinctRoles = listDistinctRoles;
10
10
  exports.listRolesWithDetails = listRolesWithDetails;
11
11
  exports.createRole = createRole;
12
+ exports.updateRoleMetadata = updateRoleMetadata;
13
+ exports.getRoleFormSchema = getRoleFormSchema;
14
+ exports.getRoleMetadataSchema = getRoleMetadataSchema;
12
15
  exports.deleteRole = deleteRole;
13
16
  const db_1 = require("../../lib/db");
14
17
  const user_1 = require("../user");
@@ -103,11 +106,56 @@ async function listRolesWithDetails() {
103
106
  return rows;
104
107
  }
105
108
  /**
106
- * Create a standalone role entry.
109
+ * Create a standalone role entry. Returns true when the role was created by
110
+ * this call, false when it already existed — seeders use this to write
111
+ * default metadata exactly once and leave later admin edits alone.
107
112
  */
108
113
  async function createRole(role) {
109
114
  const pool = (0, db_1.getPool)();
110
- await pool.query(sql_1.ENSURE_ROLE_EXISTS, [role]);
115
+ const { rowCount } = await pool.query(sql_1.ENSURE_ROLE_EXISTS, [role]);
116
+ return (rowCount ?? 0) > 0;
117
+ }
118
+ /**
119
+ * Update role metadata with PATCH semantics: a field omitted from the input
120
+ * (undefined) keeps its current value; explicit null clears it (properties
121
+ * resets to {}). One atomic UPDATE — see UPDATE_ROLE_METADATA.
122
+ */
123
+ async function updateRoleMetadata(role, input) {
124
+ const pool = (0, db_1.getPool)();
125
+ const provided = (key) => input[key] !== undefined;
126
+ const { rows } = await pool.query(sql_1.UPDATE_ROLE_METADATA, [
127
+ role,
128
+ provided('title'), input.title ?? null,
129
+ provided('description'), input.description ?? null,
130
+ provided('form_schema'), input.form_schema != null ? JSON.stringify(input.form_schema) : null,
131
+ provided('metadata_schema'), input.metadata_schema != null ? JSON.stringify(input.metadata_schema) : null,
132
+ provided('properties'), input.properties != null ? JSON.stringify(input.properties) : null,
133
+ provided('ops_visible'), input.ops_visible ?? null,
134
+ provided('parent_role'), input.parent_role ?? null,
135
+ provided('sla_minutes'), input.sla_minutes ?? null,
136
+ provided('target_per_hour'), input.target_per_hour ?? null,
137
+ provided('worker_count'), input.worker_count ?? null,
138
+ ]);
139
+ return rows[0] ?? null;
140
+ }
141
+ /**
142
+ * Fetch form_schema for a role (used as default escalation form when workflow
143
+ * config does not specify a resolver_schema).
144
+ */
145
+ async function getRoleFormSchema(role) {
146
+ const pool = (0, db_1.getPool)();
147
+ const { rows } = await pool.query(sql_1.GET_ROLE_FORM_SCHEMA, [role]);
148
+ return rows[0]?.form_schema ?? null;
149
+ }
150
+ /**
151
+ * Fetch metadata_schema for a role. Used at escalation creation time to
152
+ * validate the caller-supplied metadata bag, and by the faceted-query UI
153
+ * to surface expected keys before any data exists.
154
+ */
155
+ async function getRoleMetadataSchema(role) {
156
+ const pool = (0, db_1.getPool)();
157
+ const { rows } = await pool.query(sql_1.GET_ROLE_METADATA_SCHEMA, [role]);
158
+ return rows[0]?.metadata_schema ?? null;
111
159
  }
112
160
  /**
113
161
  * Delete a role. Returns an error message if the role is referenced.
@@ -15,7 +15,17 @@ export declare const CHECK_ESCALATION_CHAIN_EXISTS = "\n SELECT 1\n FROM lt_co
15
15
  export declare const ENSURE_ROLE_EXISTS = "\n INSERT INTO lt_roles (role) VALUES ($1)\n ON CONFLICT DO NOTHING";
16
16
  export declare const LIST_ROLES = "\n SELECT role FROM lt_roles ORDER BY role";
17
17
  export declare const DELETE_ROLE = "\n DELETE FROM lt_roles WHERE role = $1";
18
- export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n )\n SELECT\n r.role,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n ORDER BY r.role";
18
+ /**
19
+ * PATCH semantics in ONE atomic statement: each column has a boolean
20
+ * "provided" sentinel — when false the column keeps its current value, when
21
+ * true the paired value is written (null clears; properties resets to '{}').
22
+ * This is what lets the dashboard's per-tab saves and single-field MCP calls
23
+ * coexist on the same row without read-modify-write.
24
+ */
25
+ export declare const UPDATE_ROLE_METADATA = "\n UPDATE lt_roles SET\n title = CASE WHEN $2::boolean THEN $3 ELSE title END,\n description = CASE WHEN $4::boolean THEN $5 ELSE description END,\n form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,\n metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,\n properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,\n ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,\n parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,\n sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,\n target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,\n worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END\n WHERE role = $1\n RETURNING\n role, title, description, form_schema, metadata_schema, properties,\n ops_visible, parent_role, sla_minutes, target_per_hour, worker_count";
26
+ export declare const GET_ROLE_FORM_SCHEMA = "\n SELECT form_schema FROM lt_roles WHERE role = $1";
27
+ export declare const GET_ROLE_METADATA_SCHEMA = "\n SELECT metadata_schema FROM lt_roles WHERE role = $1";
28
+ export declare const LIST_ROLES_WITH_DETAILS = "\n WITH\n user_counts AS (\n SELECT role, COUNT(DISTINCT user_id)::int AS cnt\n FROM lt_user_roles\n GROUP BY role\n ),\n chain_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM (\n SELECT source_role AS role FROM lt_config_role_escalations\n UNION ALL\n SELECT target_role AS role FROM lt_config_role_escalations\n ) c\n GROUP BY role\n ),\n workflow_counts AS (\n SELECT role, COUNT(*)::int AS cnt\n FROM lt_config_roles\n GROUP BY role\n )\n SELECT\n r.role,\n r.title,\n r.description,\n r.form_schema,\n r.metadata_schema,\n r.properties,\n r.ops_visible,\n r.parent_role,\n r.sla_minutes,\n r.target_per_hour,\n r.worker_count,\n COALESCE(uc.cnt, 0) AS user_count,\n COALESCE(cc.cnt, 0) AS chain_count,\n COALESCE(wc.cnt, 0) AS workflow_count\n FROM lt_roles r\n LEFT JOIN user_counts uc ON uc.role = r.role\n LEFT JOIN chain_counts cc ON cc.role = r.role\n LEFT JOIN workflow_counts wc ON wc.role = r.role\n ORDER BY r.role";
19
29
  export declare const COUNT_USER_ROLE_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_user_roles WHERE role = $1";
20
30
  export declare const COUNT_CHAIN_REFS = "\n SELECT COUNT(*)::int AS cnt\n FROM lt_config_role_escalations\n WHERE source_role = $1 OR target_role = $1";
21
31
  export declare const COUNT_WORKFLOW_REFS = "\n SELECT COUNT(*)::int AS cnt FROM lt_config_roles WHERE role = $1";
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // ─── Escalation chain queries ───────────────────────────────────────────────
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.COUNT_ACTIVE_ESCALATION_REFS = exports.COUNT_WORKFLOW_REFS = exports.COUNT_CHAIN_REFS = exports.COUNT_USER_ROLE_REFS = exports.LIST_ROLES_WITH_DETAILS = exports.DELETE_ROLE = exports.LIST_ROLES = exports.ENSURE_ROLE_EXISTS = exports.CHECK_ESCALATION_CHAIN_EXISTS = exports.DELETE_ESCALATION_CHAINS_BY_SOURCE = exports.DELETE_ESCALATION_CHAIN = exports.ADD_ESCALATION_CHAIN = exports.INSERT_ESCALATION_CHAIN = exports.GET_ALL_ESCALATION_CHAINS = exports.GET_ESCALATION_TARGETS = void 0;
4
+ exports.COUNT_ACTIVE_ESCALATION_REFS = exports.COUNT_WORKFLOW_REFS = exports.COUNT_CHAIN_REFS = exports.COUNT_USER_ROLE_REFS = exports.LIST_ROLES_WITH_DETAILS = exports.GET_ROLE_METADATA_SCHEMA = exports.GET_ROLE_FORM_SCHEMA = exports.UPDATE_ROLE_METADATA = exports.DELETE_ROLE = exports.LIST_ROLES = exports.ENSURE_ROLE_EXISTS = exports.CHECK_ESCALATION_CHAIN_EXISTS = exports.DELETE_ESCALATION_CHAINS_BY_SOURCE = exports.DELETE_ESCALATION_CHAIN = exports.ADD_ESCALATION_CHAIN = exports.INSERT_ESCALATION_CHAIN = exports.GET_ALL_ESCALATION_CHAINS = exports.GET_ESCALATION_TARGETS = void 0;
5
5
  exports.GET_ESCALATION_TARGETS = `
6
6
  SELECT target_role
7
7
  FROM lt_config_role_escalations
@@ -49,6 +49,33 @@ exports.LIST_ROLES = `
49
49
  SELECT role FROM lt_roles ORDER BY role`;
50
50
  exports.DELETE_ROLE = `
51
51
  DELETE FROM lt_roles WHERE role = $1`;
52
+ /**
53
+ * PATCH semantics in ONE atomic statement: each column has a boolean
54
+ * "provided" sentinel — when false the column keeps its current value, when
55
+ * true the paired value is written (null clears; properties resets to '{}').
56
+ * This is what lets the dashboard's per-tab saves and single-field MCP calls
57
+ * coexist on the same row without read-modify-write.
58
+ */
59
+ exports.UPDATE_ROLE_METADATA = `
60
+ UPDATE lt_roles SET
61
+ title = CASE WHEN $2::boolean THEN $3 ELSE title END,
62
+ description = CASE WHEN $4::boolean THEN $5 ELSE description END,
63
+ form_schema = CASE WHEN $6::boolean THEN $7::jsonb ELSE form_schema END,
64
+ metadata_schema = CASE WHEN $8::boolean THEN $9::jsonb ELSE metadata_schema END,
65
+ properties = CASE WHEN $10::boolean THEN COALESCE($11::jsonb, '{}'::jsonb) ELSE properties END,
66
+ ops_visible = CASE WHEN $12::boolean THEN $13::boolean ELSE ops_visible END,
67
+ parent_role = CASE WHEN $14::boolean THEN $15 ELSE parent_role END,
68
+ sla_minutes = CASE WHEN $16::boolean THEN $17::numeric ELSE sla_minutes END,
69
+ target_per_hour = CASE WHEN $18::boolean THEN $19::numeric ELSE target_per_hour END,
70
+ worker_count = CASE WHEN $20::boolean THEN $21::int ELSE worker_count END
71
+ WHERE role = $1
72
+ RETURNING
73
+ role, title, description, form_schema, metadata_schema, properties,
74
+ ops_visible, parent_role, sla_minutes, target_per_hour, worker_count`;
75
+ exports.GET_ROLE_FORM_SCHEMA = `
76
+ SELECT form_schema FROM lt_roles WHERE role = $1`;
77
+ exports.GET_ROLE_METADATA_SCHEMA = `
78
+ SELECT metadata_schema FROM lt_roles WHERE role = $1`;
52
79
  // ─── Role detail aggregation ────────────────────────────────────────────────
53
80
  exports.LIST_ROLES_WITH_DETAILS = `
54
81
  WITH
@@ -73,6 +100,16 @@ exports.LIST_ROLES_WITH_DETAILS = `
73
100
  )
74
101
  SELECT
75
102
  r.role,
103
+ r.title,
104
+ r.description,
105
+ r.form_schema,
106
+ r.metadata_schema,
107
+ r.properties,
108
+ r.ops_visible,
109
+ r.parent_role,
110
+ r.sla_minutes,
111
+ r.target_per_hour,
112
+ r.worker_count,
76
113
  COALESCE(uc.cnt, 0) AS user_count,
77
114
  COALESCE(cc.cnt, 0) AS chain_count,
78
115
  COALESCE(wc.cnt, 0) AS workflow_count
@@ -5,7 +5,39 @@ export interface EscalationChain {
5
5
  }
6
6
  export interface RoleDetail {
7
7
  role: string;
8
+ title: string | null;
9
+ description: string | null;
10
+ /** JSON Schema for the escalation resolve form. Overridden per-workflow by resolver_schema. */
11
+ form_schema: Record<string, any> | null;
12
+ /**
13
+ * JSON Schema declaring the expected shape of lt_escalations.metadata for
14
+ * escalations created under this role. Drives faceted-query key autocomplete
15
+ * and creation-time metadata validation.
16
+ */
17
+ metadata_schema: Record<string, any> | null;
18
+ /** Free-form user-owned bag. No reserved keys — use for icons, colors, tags, etc. */
19
+ properties: Record<string, any>;
20
+ ops_visible: boolean;
21
+ parent_role: string | null;
22
+ /** Target resolution time (minutes). Part of the ops triangle. */
23
+ sla_minutes: number | null;
24
+ /** Intended throughput (items per hour). Part of the ops triangle. */
25
+ target_per_hour: number | null;
26
+ /** Capacity at this station (people or machines). Part of the ops triangle. */
27
+ worker_count: number | null;
8
28
  user_count: number;
9
29
  chain_count: number;
10
30
  workflow_count: number;
11
31
  }
32
+ export interface UpdateRoleInput {
33
+ title?: string | null;
34
+ description?: string | null;
35
+ form_schema?: Record<string, any> | null;
36
+ metadata_schema?: Record<string, any> | null;
37
+ properties?: Record<string, any> | null;
38
+ ops_visible?: boolean;
39
+ parent_role?: string | null;
40
+ sla_minutes?: number | null;
41
+ target_per_hour?: number | null;
42
+ worker_count?: number | null;
43
+ }
@@ -78,13 +78,14 @@ function registerEscalationTools(server) {
78
78
  server.registerTool('find_escalations', {
79
79
  title: 'Find Escalations',
80
80
  description: 'Search escalations with optional filters (status, role, type, subtype, ' +
81
- 'assigned_to, priority), free-text `search`, and sorting. `search` matches ' +
82
- 'across description, type/subtype, role, workflow/origin id, and metadata values ' +
83
- '(e.g. a correlation key like an order id) server-side over the full result set. ' +
84
- 'Also supports FACETED metadata query — `facets` (metadata @> containment), `block` ' +
85
- '(exclusion), `range` (numeric), `exists` (key present), `roles`, `available`, and ' +
86
- '`orderBy` (incl. metadata.<key>) — all role-scoped and run in SQL. ' +
87
- 'Returns full records including metadata, workflow linkage, assignment, and signal_key.',
81
+ 'assigned_to, priority), correlation-id `search`, and sorting. `search` is an ' +
82
+ 'exact-match lookup by escalation id, workflow id, or origin id (order/ticket) — ' +
83
+ 'index-served over the full result set. To match a value INSIDE metadata ' +
84
+ '(e.g. an order id), use the FACETED metadata query — `facets` (metadata @> containment), ' +
85
+ '`block` (exclusion), `range` (numeric), `exists` (key present), `roles`, `available`, and ' +
86
+ '`orderBy` (incl. metadata.<key>) — all role-scoped, GIN-served, and status-agnostic ' +
87
+ '(no status filter required). Returns full records including metadata, workflow linkage, ' +
88
+ 'assignment, and signal_key.',
88
89
  inputSchema: schemas_1.findEscalationsSchema,
89
90
  }, async (args) => {
90
91
  const result = await escalationApi.listEscalations({
@@ -55,7 +55,8 @@ const settings_1 = require("./settings");
55
55
  const exports_1 = require("./exports");
56
56
  const overview_1 = require("./overview");
57
57
  const diagnostics_1 = require("./diagnostics");
58
- const TOOL_COUNT = 83;
58
+ const ortho_1 = require("./ortho");
59
+ const TOOL_COUNT = 88;
59
60
  let server = null;
60
61
  async function createAdminServer(options) {
61
62
  if (server && !options?.fresh)
@@ -71,7 +72,7 @@ async function createAdminServer(options) {
71
72
  (0, workflows_1.registerWorkflowTools)(instance); // 3 tools
72
73
  (0, mcp_servers_1.registerMcpServerTools)(instance); // 4 tools
73
74
  (0, yaml_workflows_1.registerYamlWorkflowTools)(instance); // 5 tools
74
- (0, users_1.registerUserTools)(instance); // 7 tools (users + roles)
75
+ (0, users_1.registerUserTools)(instance); // 8 tools (users + roles)
75
76
  (0, maintenance_1.registerMaintenanceTools)(instance); // 1 tool
76
77
  (0, agents_1.registerAgentTools)(instance); // 5 tools
77
78
  (0, agent_subscriptions_1.registerAgentSubscriptionTools)(instance); // 3 tools
@@ -83,7 +84,8 @@ async function createAdminServer(options) {
83
84
  (0, exports_1.registerExportTools)(instance); // 4 tools
84
85
  (0, overview_1.registerOverviewTools)(instance); // 1 tool
85
86
  (0, diagnostics_1.registerDiagnosticsTools)(instance); // 3 tools
86
- // Total: 83
87
+ (0, ortho_1.registerOrthoTools)(instance); // 4 tools
88
+ // Total: 88
87
89
  logger_1.loggerRegistry.info(`[lt-mcp:admin] ${name} ready (${TOOL_COUNT} tools registered)`);
88
90
  return instance;
89
91
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Ortho pipeline MCP tools — AI-operable interface for the 8-stage manufacturing workflow.
3
+ *
4
+ * ortho_submit — start a new order through the orthoPipeline workflow
5
+ * ortho_pending — list open stage escalations waiting for completion
6
+ * ortho_complete_stage — claim and resolve one stage escalation (advances the pipeline)
7
+ * ortho_status — get the current status and results for an order workflow
8
+ */
9
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
10
+ export declare function registerOrthoTools(server: McpServer): void;
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerOrthoTools = registerOrthoTools;
37
+ const zod_1 = require("zod");
38
+ const workflow_invocation_1 = require("../../../services/workflow-invocation");
39
+ const escalationApi = __importStar(require("../../../api/escalations"));
40
+ const workflowApi = __importStar(require("../../../api/workflows"));
41
+ const iam_1 = require("../../../services/iam");
42
+ const types_1 = require("../../../examples/workflows/ortho-pipeline/types");
43
+ let systemPrincipalId = null;
44
+ async function systemAuth() {
45
+ if (!systemPrincipalId)
46
+ systemPrincipalId = await (0, iam_1.ensureSystemBot)();
47
+ return { userId: systemPrincipalId, role: 'superadmin' };
48
+ }
49
+ // ── Schemas ──────────────────────────────────────────────────────────────────
50
+ const orthoSubmitSchema = zod_1.z.object({
51
+ order_id: zod_1.z.string().describe('Unique order identifier (e.g. "ORD-001")'),
52
+ item_type: zod_1.z.string().describe('Item type (e.g. "insole-standard", "insole-diabetic")'),
53
+ stages: zod_1.z.array(zod_1.z.string()).optional().describe('Override stage sequence (default: all 8 stages)'),
54
+ metadata: zod_1.z.record(zod_1.z.unknown()).optional().describe('Additional order metadata passed through to each stage'),
55
+ });
56
+ const orthoPendingSchema = zod_1.z.object({
57
+ stage: zod_1.z.string().optional().describe('Filter to a specific stage (e.g. "design"). Omit for all stages.'),
58
+ limit: zod_1.z.number().int().optional().default(50).describe('Max results'),
59
+ });
60
+ const orthoCompleteStageSchema = zod_1.z.object({
61
+ escalation_id: zod_1.z.string().describe('Escalation ID returned by ortho_pending'),
62
+ notes: zod_1.z.string().describe('Completion notes — what was done, any decisions made'),
63
+ outcome: zod_1.z.record(zod_1.z.unknown()).optional().describe('Structured outcome data specific to this stage'),
64
+ });
65
+ const orthoStatusSchema = zod_1.z.object({
66
+ workflow_id: zod_1.z.string().describe('Workflow ID returned by ortho_submit'),
67
+ });
68
+ // ── Tool registration ────────────────────────────────────────────────────────
69
+ function registerOrthoTools(server) {
70
+ // Submit a new order through the ortho manufacturing pipeline
71
+ server.registerTool('ortho_submit', {
72
+ title: 'Submit Ortho Order',
73
+ description: 'Start a new orthotic manufacturing order through the 8-stage pipeline ' +
74
+ '(design → review → print → grind → glue → finish → qa → ship). ' +
75
+ 'Returns a workflow_id used to track progress. Each stage creates a pending ' +
76
+ 'escalation that must be completed via ortho_complete_stage before the next stage begins.',
77
+ inputSchema: orthoSubmitSchema,
78
+ }, async (args) => {
79
+ const auth = await systemAuth();
80
+ const result = await (0, workflow_invocation_1.invokeWorkflow)({
81
+ workflowType: types_1.ORTHO_PIPELINE_WORKFLOW,
82
+ data: {
83
+ order_id: args.order_id,
84
+ item_type: args.item_type,
85
+ ...(args.stages ? { stages: args.stages } : {}),
86
+ ...(args.metadata ? { metadata: args.metadata } : {}),
87
+ },
88
+ auth,
89
+ });
90
+ return {
91
+ content: [{
92
+ type: 'text',
93
+ text: JSON.stringify({
94
+ workflow_id: result.workflowId,
95
+ order_id: args.order_id,
96
+ item_type: args.item_type,
97
+ stages: args.stages ?? [...types_1.ORTHO_STAGES],
98
+ message: 'Pipeline started — first stage escalation will appear momentarily',
99
+ }),
100
+ }],
101
+ };
102
+ });
103
+ // List pending stage escalations, optionally filtered by stage
104
+ server.registerTool('ortho_pending', {
105
+ title: 'List Pending Ortho Stages',
106
+ description: 'List open ortho-pipeline escalations waiting to be completed. ' +
107
+ 'Each entry represents one manufacturing stage blocked on human or AI review. ' +
108
+ 'Filter by stage name to focus on one step. Use ortho_complete_stage to advance.',
109
+ inputSchema: orthoPendingSchema,
110
+ }, async (args) => {
111
+ const auth = await systemAuth();
112
+ const result = await escalationApi.listEscalations({
113
+ status: 'pending',
114
+ type: types_1.ORTHO_STAGE_TYPE,
115
+ ...(args.stage ? { subtype: args.stage } : {}),
116
+ limit: args.limit ?? 50,
117
+ sort_by: 'created_at',
118
+ order: 'asc',
119
+ }, auth);
120
+ if (result.status !== 200 || !result.data) {
121
+ return {
122
+ content: [{
123
+ type: 'text',
124
+ text: JSON.stringify({ error: result.error ?? 'Failed to list escalations' }),
125
+ }],
126
+ };
127
+ }
128
+ const escalations = (result.data.escalations ?? []).map((e) => ({
129
+ id: e.id,
130
+ stage: e.subtype,
131
+ order_id: e.metadata?.order_id,
132
+ item_type: e.metadata?.item_type,
133
+ description: e.description,
134
+ created_at: e.created_at,
135
+ signal_key: e.signal_key,
136
+ workflow_id: e.workflow_id,
137
+ }));
138
+ return {
139
+ content: [{
140
+ type: 'text',
141
+ text: JSON.stringify({ count: escalations.length, escalations }),
142
+ }],
143
+ };
144
+ });
145
+ // Claim and resolve one stage escalation (advances to the next stage)
146
+ server.registerTool('ortho_complete_stage', {
147
+ title: 'Complete Ortho Stage',
148
+ description: 'Complete a pending ortho pipeline stage. Claims the escalation as the system ' +
149
+ 'operator and resolves it with your notes and outcome data. Resolving automatically ' +
150
+ 'signals the workflow to advance to the next stage — a new escalation will appear ' +
151
+ 'for the subsequent step within seconds.',
152
+ inputSchema: orthoCompleteStageSchema,
153
+ }, async (args) => {
154
+ const auth = await systemAuth();
155
+ // Contract guard: this tool advances pipeline stage gates only. The
156
+ // general-purpose resolve_escalation tool covers every other type.
157
+ const detail = await escalationApi.getEscalation({ id: args.escalation_id }, auth);
158
+ if (detail.status !== 200 || detail.data?.type !== types_1.ORTHO_STAGE_TYPE) {
159
+ return {
160
+ content: [{
161
+ type: 'text',
162
+ text: JSON.stringify({
163
+ error: `Escalation ${args.escalation_id} is ${detail.status !== 200 ? 'unknown' : `type "${detail.data?.type}"`} — ortho_complete_stage resolves ${types_1.ORTHO_STAGE_TYPE} gates. Use resolve_escalation for other types.`,
164
+ }),
165
+ }],
166
+ };
167
+ }
168
+ // Claim first (idempotent if already claimed by us)
169
+ const claimResult = await escalationApi.claimEscalation({ id: args.escalation_id, durationMinutes: 60 }, auth);
170
+ if (claimResult.status !== 200) {
171
+ return {
172
+ content: [{
173
+ type: 'text',
174
+ text: JSON.stringify({ error: `Claim failed: ${claimResult.error}` }),
175
+ }],
176
+ };
177
+ }
178
+ // Resolve with stage output. completed_at is stamped here — the durable
179
+ // workflow reads it from the signal payload (replay-deterministic).
180
+ const resolveResult = await escalationApi.resolveEscalation({
181
+ id: args.escalation_id,
182
+ resolverPayload: {
183
+ notes: args.notes,
184
+ completed_at: new Date().toISOString(),
185
+ ...(args.outcome ? { outcome: args.outcome } : {}),
186
+ },
187
+ }, auth);
188
+ return {
189
+ content: [{
190
+ type: 'text',
191
+ text: JSON.stringify({
192
+ resolved: resolveResult.status === 200,
193
+ escalation_id: args.escalation_id,
194
+ status: resolveResult.status,
195
+ error: resolveResult.status !== 200 ? resolveResult.error : undefined,
196
+ message: resolveResult.status === 200
197
+ ? 'Stage resolved — next stage escalation will appear shortly'
198
+ : undefined,
199
+ }),
200
+ }],
201
+ };
202
+ });
203
+ // Get the current status and accumulated results for a pipeline run
204
+ server.registerTool('ortho_status', {
205
+ title: 'Get Ortho Pipeline Status',
206
+ description: 'Get the current status and completed stage results for an ortho pipeline workflow. ' +
207
+ 'Returns "running" while stages are in progress, "complete" with the full stage ' +
208
+ 'result history when all stages are done.',
209
+ inputSchema: orthoStatusSchema,
210
+ }, async (args) => {
211
+ const statusResult = await workflowApi.getWorkflowStatus({ workflowId: args.workflow_id });
212
+ if (statusResult.status === 404) {
213
+ return {
214
+ content: [{
215
+ type: 'text',
216
+ text: JSON.stringify({ error: 'Workflow not found', workflow_id: args.workflow_id }),
217
+ }],
218
+ };
219
+ }
220
+ // status=0 means complete in HotMesh
221
+ const isComplete = statusResult.data?.status === 0;
222
+ if (!isComplete) {
223
+ return {
224
+ content: [{
225
+ type: 'text',
226
+ text: JSON.stringify({ workflow_id: args.workflow_id, status: 'running' }),
227
+ }],
228
+ };
229
+ }
230
+ const resultData = await workflowApi.getWorkflowResult({ workflowId: args.workflow_id });
231
+ return {
232
+ content: [{
233
+ type: 'text',
234
+ text: JSON.stringify({
235
+ workflow_id: args.workflow_id,
236
+ status: 'complete',
237
+ result: resultData.data?.result ?? null,
238
+ }),
239
+ }],
240
+ };
241
+ });
242
+ }
@@ -40,7 +40,7 @@ export declare const getProcessDetailSchema: z.ZodObject<{
40
40
  origin_id: string;
41
41
  }>;
42
42
  export declare const findEscalationsSchema: z.ZodObject<{
43
- status: z.ZodOptional<z.ZodEnum<["pending", "resolved", "cancelled"]>>;
43
+ status: z.ZodOptional<z.ZodEnum<["pending", "resolved", "cancelled", "expired"]>>;
44
44
  role: z.ZodOptional<z.ZodString>;
45
45
  type: z.ZodOptional<z.ZodString>;
46
46
  subtype: z.ZodOptional<z.ZodString>;
@@ -86,7 +86,7 @@ export declare const findEscalationsSchema: z.ZodObject<{
86
86
  limit: number;
87
87
  offset: number;
88
88
  role?: string | undefined;
89
- status?: "pending" | "cancelled" | "resolved" | undefined;
89
+ status?: "pending" | "cancelled" | "resolved" | "expired" | undefined;
90
90
  roles?: string[] | undefined;
91
91
  type?: string | undefined;
92
92
  search?: string | undefined;
@@ -111,7 +111,7 @@ export declare const findEscalationsSchema: z.ZodObject<{
111
111
  exists?: string[] | undefined;
112
112
  }, {
113
113
  role?: string | undefined;
114
- status?: "pending" | "cancelled" | "resolved" | undefined;
114
+ status?: "pending" | "cancelled" | "resolved" | "expired" | undefined;
115
115
  roles?: string[] | undefined;
116
116
  type?: string | undefined;
117
117
  search?: string | undefined;
@@ -550,6 +550,43 @@ export declare const addEscalationChainSchema: z.ZodObject<{
550
550
  source_role: string;
551
551
  target_role: string;
552
552
  }>;
553
+ export declare const updateRoleSchema: z.ZodObject<{
554
+ role: z.ZodString;
555
+ title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
556
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
557
+ form_schema: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>>;
558
+ metadata_schema: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>>;
559
+ properties: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodAny>>>;
560
+ ops_visible: z.ZodOptional<z.ZodBoolean>;
561
+ parent_role: z.ZodOptional<z.ZodNullable<z.ZodString>>;
562
+ sla_minutes: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
563
+ target_per_hour: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
564
+ worker_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
565
+ }, "strip", z.ZodTypeAny, {
566
+ role: string;
567
+ description?: string | null | undefined;
568
+ title?: string | null | undefined;
569
+ form_schema?: Record<string, any> | null | undefined;
570
+ properties?: Record<string, any> | null | undefined;
571
+ metadata_schema?: Record<string, any> | null | undefined;
572
+ ops_visible?: boolean | undefined;
573
+ parent_role?: string | null | undefined;
574
+ sla_minutes?: number | null | undefined;
575
+ target_per_hour?: number | null | undefined;
576
+ worker_count?: number | null | undefined;
577
+ }, {
578
+ role: string;
579
+ description?: string | null | undefined;
580
+ title?: string | null | undefined;
581
+ form_schema?: Record<string, any> | null | undefined;
582
+ properties?: Record<string, any> | null | undefined;
583
+ metadata_schema?: Record<string, any> | null | undefined;
584
+ ops_visible?: boolean | undefined;
585
+ parent_role?: string | null | undefined;
586
+ sla_minutes?: number | null | undefined;
587
+ target_per_hour?: number | null | undefined;
588
+ worker_count?: number | null | undefined;
589
+ }>;
553
590
  export declare const pruneSchema: z.ZodObject<{
554
591
  app_id: z.ZodDefault<z.ZodOptional<z.ZodString>>;
555
592
  expire: z.ZodDefault<z.ZodOptional<z.ZodString>>;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.updateBotSchema = exports.createBotSchema = exports.getBotSchema = exports.listBotsSchema = exports.deleteAgentSubscriptionSchema = exports.createAgentSubscriptionSchema = exports.listAgentSubscriptionsSchema = exports.deleteAgentSchema = exports.updateAgentSchema = exports.createAgentSchema = exports.getAgentSchema = exports.listAgentsSchema = exports.pruneSchema = exports.addEscalationChainSchema = exports.createRoleSchema = exports.listRolesSchema = exports.removeUserRoleSchema = exports.addUserRoleSchema = exports.createUserSchema = exports.listUsersSchema = exports.invokeYamlWorkflowSchema = exports.deployYamlWorkflowSchema = exports.createYamlWorkflowSchema = exports.getYamlWorkflowSchema = exports.listYamlWorkflowsSchema = exports.disconnectMcpServerSchema = exports.connectMcpServerSchema = exports.updateMcpServerSchema = exports.listMcpServersSchema = exports.getWorkflowStatusSchema = exports.invokeWorkflowSchema = exports.listDiscoveredWorkflowsSchema = exports.deleteWorkflowConfigSchema = exports.upsertWorkflowConfigSchema = exports.listWorkflowConfigsSchema = exports.bulkTriageSchema = exports.releaseExpiredClaimsSchema = exports.bulkCancelSchema = exports.cancelEscalationSchema = exports.escalateEscalationSchema = exports.resolveBySignalKeySchema = exports.resolveEscalationSchema = exports.releaseEscalationSchema = exports.claimEscalationSchema = exports.getEscalationStatsSchema = exports.getEscalationsByWorkflowSchema = exports.getEscalationSchema = exports.findEscalationsSchema = exports.getProcessDetailSchema = exports.findTasksSchema = void 0;
4
- exports.claimByFacetsSchema = exports.claimGroupsSchema = exports.searchByFacetsSchema = exports.resolveByIdsSchema = exports.facetQuerySchema = exports.findOrphanedSignalsSchema = exports.findStalledJobsSchema = exports.diagnoseJobSchema = exports.getExportStatusSchema = exports.exportWorkflowExecutionSchema = exports.exportWorkflowStateSchema = exports.listExportJobsSchema = exports.getSettingsSchema = exports.updatePrioritySchema = exports.bulkEscalateSchema = exports.bulkAssignSchema = exports.bulkClaimSchema = exports.resolveByMetadataSchema = exports.claimByMetadataSchema = exports.findByMetadataSchema = exports.deleteTopicSchema = exports.updateTopicSchema = exports.createTopicSchema = exports.getTopicSchema = exports.listTopicsSchema = exports.interruptJobSchema = exports.getJobExecutionSchema = exports.listPipelineJobsSchema = exports.listPipelineEntitiesSchema = exports.listStreamMessagesSchema = exports.getStreamStatsSchema = exports.applyThrottleSchema = exports.rollCallSchema = exports.listAppsSchema = exports.revokeBotKeySchema = exports.createBotApiKeySchema = exports.deleteBotSchema = void 0;
3
+ exports.createBotSchema = exports.getBotSchema = exports.listBotsSchema = exports.deleteAgentSubscriptionSchema = exports.createAgentSubscriptionSchema = exports.listAgentSubscriptionsSchema = exports.deleteAgentSchema = exports.updateAgentSchema = exports.createAgentSchema = exports.getAgentSchema = exports.listAgentsSchema = exports.pruneSchema = exports.updateRoleSchema = exports.addEscalationChainSchema = exports.createRoleSchema = exports.listRolesSchema = exports.removeUserRoleSchema = exports.addUserRoleSchema = exports.createUserSchema = exports.listUsersSchema = exports.invokeYamlWorkflowSchema = exports.deployYamlWorkflowSchema = exports.createYamlWorkflowSchema = exports.getYamlWorkflowSchema = exports.listYamlWorkflowsSchema = exports.disconnectMcpServerSchema = exports.connectMcpServerSchema = exports.updateMcpServerSchema = exports.listMcpServersSchema = exports.getWorkflowStatusSchema = exports.invokeWorkflowSchema = exports.listDiscoveredWorkflowsSchema = exports.deleteWorkflowConfigSchema = exports.upsertWorkflowConfigSchema = exports.listWorkflowConfigsSchema = exports.bulkTriageSchema = exports.releaseExpiredClaimsSchema = exports.bulkCancelSchema = exports.cancelEscalationSchema = exports.escalateEscalationSchema = exports.resolveBySignalKeySchema = exports.resolveEscalationSchema = exports.releaseEscalationSchema = exports.claimEscalationSchema = exports.getEscalationStatsSchema = exports.getEscalationsByWorkflowSchema = exports.getEscalationSchema = exports.findEscalationsSchema = exports.getProcessDetailSchema = exports.findTasksSchema = void 0;
4
+ exports.claimByFacetsSchema = exports.claimGroupsSchema = exports.searchByFacetsSchema = exports.resolveByIdsSchema = exports.facetQuerySchema = exports.findOrphanedSignalsSchema = exports.findStalledJobsSchema = exports.diagnoseJobSchema = exports.getExportStatusSchema = exports.exportWorkflowExecutionSchema = exports.exportWorkflowStateSchema = exports.listExportJobsSchema = exports.getSettingsSchema = exports.updatePrioritySchema = exports.bulkEscalateSchema = exports.bulkAssignSchema = exports.bulkClaimSchema = exports.resolveByMetadataSchema = exports.claimByMetadataSchema = exports.findByMetadataSchema = exports.deleteTopicSchema = exports.updateTopicSchema = exports.createTopicSchema = exports.getTopicSchema = exports.listTopicsSchema = exports.interruptJobSchema = exports.getJobExecutionSchema = exports.listPipelineJobsSchema = exports.listPipelineEntitiesSchema = exports.listStreamMessagesSchema = exports.getStreamStatsSchema = exports.applyThrottleSchema = exports.rollCallSchema = exports.listAppsSchema = exports.revokeBotKeySchema = exports.createBotApiKeySchema = exports.deleteBotSchema = exports.updateBotSchema = void 0;
5
5
  /**
6
6
  * Zod schemas for the admin MCP server tools.
7
7
  *
@@ -28,12 +28,12 @@ exports.getProcessDetailSchema = zod_1.z.object({
28
28
  });
29
29
  // ── escalations (routes/escalations/) ───────────────────────────────────────
30
30
  exports.findEscalationsSchema = zod_1.z.object({
31
- status: zod_1.z.enum(['pending', 'resolved', 'cancelled']).optional().describe('Filter by status'),
31
+ status: zod_1.z.enum(['pending', 'resolved', 'cancelled', 'expired']).optional().describe('Filter by status'),
32
32
  role: zod_1.z.string().optional().describe('Filter by target role'),
33
33
  type: zod_1.z.string().optional().describe('Filter by escalation type'),
34
34
  subtype: zod_1.z.string().optional().describe('Filter by escalation subtype'),
35
35
  assigned_to: zod_1.z.string().optional().describe('Filter by assigned user UUID (active claim holder)'),
36
- search: zod_1.z.string().optional().describe('Free-text search across description, type/subtype, role, workflow/origin id, and metadata values (e.g. a correlation key like an order id). Server-side over the full result set.'),
36
+ search: zod_1.z.string().optional().describe('Exact-match lookup by correlation id — the escalation id, its workflow id, or origin id (order/ticket). Index-served, server-side over the full result set. To match a value INSIDE metadata (e.g. an order id), use `facets` instead.'),
37
37
  priority: zod_1.z.number().int().min(1).max(4).optional().describe('Filter by priority (1=critical, 4=low)'),
38
38
  sort_by: zod_1.z.enum(['created_at', 'priority', 'updated_at']).optional().describe('Sort column (default: priority asc, then created_at asc)'),
39
39
  order: zod_1.z.enum(['asc', 'desc']).optional().describe('Sort direction for sort_by'),
@@ -230,6 +230,19 @@ exports.addEscalationChainSchema = zod_1.z.object({
230
230
  source_role: zod_1.z.string().describe('Originating role'),
231
231
  target_role: zod_1.z.string().describe('Destination role for escalation'),
232
232
  });
233
+ exports.updateRoleSchema = zod_1.z.object({
234
+ role: zod_1.z.string().describe('Role key to update'),
235
+ title: zod_1.z.string().nullable().optional().describe('Display name shown on role cards and station views'),
236
+ description: zod_1.z.string().nullable().optional().describe('Short description of this role\'s purpose'),
237
+ form_schema: zod_1.z.record(zod_1.z.any()).nullable().optional().describe('JSON Schema for the escalation resolve form (overridden by workflow-level resolver_schema)'),
238
+ metadata_schema: zod_1.z.record(zod_1.z.any()).nullable().optional().describe('JSON Schema declaring the expected shape of lt_escalations.metadata for this role. Drives creation-time validation and faceted-query key autocomplete.'),
239
+ properties: zod_1.z.record(zod_1.z.any()).nullable().optional().describe('Free user-owned bag (icon, color, tags, etc.). No reserved keys — use the typed columns below for operational values.'),
240
+ ops_visible: zod_1.z.boolean().optional().describe('When true, role appears as a station on the /operations view'),
241
+ parent_role: zod_1.z.string().nullable().optional().describe('Parent role in the process dependency graph (nullable; roots have no parent)'),
242
+ sla_minutes: zod_1.z.number().nullable().optional().describe('Target resolution time in minutes. One of the capacity settings: target_per_hour = worker_count / (sla_minutes / 60)'),
243
+ target_per_hour: zod_1.z.number().nullable().optional().describe('Intended throughput (items resolved per hour). Drives the station pace baseline on the Operations view.'),
244
+ worker_count: zod_1.z.number().nullable().optional().describe('Capacity at this station (staff or machine count). One of the capacity settings.'),
245
+ });
233
246
  // ── maintenance (routes/dba.ts) ─────────────────────────────────────────────
234
247
  exports.pruneSchema = zod_1.z.object({
235
248
  app_id: zod_1.z.string().optional().default('durable').describe('HotMesh application namespace (default: durable)'),