@hotmeshio/long-tail 0.18.1 → 0.19.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 (367) hide show
  1. package/build/api/escalations/index.d.ts +1 -1
  2. package/build/api/escalations/index.js +2 -1
  3. package/build/api/escalations/list.d.ts +11 -0
  4. package/build/api/escalations/list.js +31 -2
  5. package/build/api/users.d.ts +11 -0
  6. package/build/api/users.js +19 -0
  7. package/build/api/workflows/config.d.ts +5 -1
  8. package/build/api/workflows/config.js +9 -1
  9. package/build/api/workflows/index.d.ts +3 -0
  10. package/build/api/workflows/index.js +7 -1
  11. package/build/api/workflows/input-validation.d.ts +13 -0
  12. package/build/api/workflows/input-validation.js +38 -0
  13. package/build/api/workflows/invocable.d.ts +19 -0
  14. package/build/api/workflows/invocable.js +106 -0
  15. package/build/api/workflows/invocation.js +6 -0
  16. package/build/lib/db/schemas/034_workflow_input_schema.sql +13 -0
  17. package/build/lib/uuid.d.ts +11 -0
  18. package/build/lib/uuid.js +20 -0
  19. package/build/routes/escalations/list.js +10 -1
  20. package/build/routes/users.js +9 -0
  21. package/build/routes/workflows/config.js +2 -0
  22. package/build/routes/workflows/discovery.js +14 -0
  23. package/build/scripts/ortho-populate.d.ts +3 -1
  24. package/build/scripts/ortho-populate.js +15 -5
  25. package/build/sdk/index.d.ts +1 -0
  26. package/build/services/config/cache.js +2 -0
  27. package/build/services/config/read.js +4 -0
  28. package/build/services/config/sql.d.ts +2 -2
  29. package/build/services/config/sql.js +7 -5
  30. package/build/services/config/write.js +11 -1
  31. package/build/services/escalation/batch.js +3 -0
  32. package/build/services/escalation/bulk.js +8 -0
  33. package/build/services/escalation/crud.js +26 -0
  34. package/build/services/escalation/queries.d.ts +14 -1
  35. package/build/services/escalation/queries.js +49 -7
  36. package/build/services/escalation/sql.d.ts +4 -2
  37. package/build/services/escalation/sql.js +4 -0
  38. package/build/services/interceptor/index.js +7 -0
  39. package/build/services/invocation-access.d.ts +18 -0
  40. package/build/services/invocation-access.js +32 -0
  41. package/build/services/role/types.d.ts +1 -1
  42. package/build/services/role/types.js +1 -1
  43. package/build/services/user/auth.js +2 -2
  44. package/build/services/user/crud.d.ts +13 -0
  45. package/build/services/user/crud.js +26 -3
  46. package/build/services/user/index.d.ts +1 -1
  47. package/build/services/user/index.js +2 -1
  48. package/build/services/user/sql.d.ts +11 -5
  49. package/build/services/user/sql.js +18 -6
  50. package/build/services/workflow-invocation.js +4 -9
  51. package/build/shared/form-validation/index.d.ts +1 -0
  52. package/build/shared/form-validation/index.js +1 -0
  53. package/build/shared/form-validation/invoke-context.d.ts +7 -0
  54. package/build/shared/form-validation/invoke-context.js +11 -0
  55. package/build/shared/form-validation/validate-resolver-payload.d.ts +1 -1
  56. package/build/shared/form-validation/validate-resolver-payload.js +1 -0
  57. package/build/shared/form-validation/x-lt-help.d.ts +2 -2
  58. package/build/shared/form-validation/x-lt-help.js +2 -2
  59. package/build/shared/form-validation/x-lt-show-if.d.ts +1 -0
  60. package/build/shared/form-validation/x-lt-show-if.js +3 -0
  61. package/build/start/workers.js +2 -0
  62. package/build/system/mcp-servers/admin/workflows.js +15 -2
  63. package/build/tsconfig.tsbuildinfo +1 -1
  64. package/build/types/config.d.ts +6 -0
  65. package/build/types/index.d.ts +2 -0
  66. package/build/types/index.js +4 -1
  67. package/build/types/startup.d.ts +10 -0
  68. package/build/types/validation.d.ts +4 -2
  69. package/build/types/workflow-icons.d.ts +86 -0
  70. package/build/types/workflow-icons.js +92 -0
  71. package/dashboard/dist/assets/{AdminDashboard-DDY8bceq.js → AdminDashboard-Drs-9TRM.js} +2 -2
  72. package/dashboard/dist/assets/{AdminDashboard-DDY8bceq.js.map → AdminDashboard-Drs-9TRM.js.map} +1 -1
  73. package/dashboard/dist/assets/{AgentConfigPage-D47sHnup.js → AgentConfigPage-BDPDZ7-v.js} +3 -3
  74. package/dashboard/dist/assets/{AgentConfigPage-D47sHnup.js.map → AgentConfigPage-BDPDZ7-v.js.map} +1 -1
  75. package/dashboard/dist/assets/{AgentDetailPage-DwrfByA2.js → AgentDetailPage-CGBulM4_.js} +3 -3
  76. package/dashboard/dist/assets/{AgentDetailPage-DwrfByA2.js.map → AgentDetailPage-CGBulM4_.js.map} +1 -1
  77. package/dashboard/dist/assets/AgentsPage-D77JeViQ.js +2 -0
  78. package/dashboard/dist/assets/{AgentsPage-CLSjlyXy.js.map → AgentsPage-D77JeViQ.js.map} +1 -1
  79. package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js → AutoGrowTextarea-7X3T9La8.js} +2 -2
  80. package/dashboard/dist/assets/{AutoGrowTextarea-DgEQeRQw.js.map → AutoGrowTextarea-7X3T9La8.js.map} +1 -1
  81. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js +2 -0
  82. package/dashboard/dist/assets/AvailableEscalationsPage-CqM_MOMy.js.map +1 -0
  83. package/dashboard/dist/assets/{BotPicker-CbL7gQFq.js → BotPicker-CC5vI_Sv.js} +2 -2
  84. package/dashboard/dist/assets/{BotPicker-CbL7gQFq.js.map → BotPicker-CC5vI_Sv.js.map} +1 -1
  85. package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js +2 -0
  86. package/dashboard/dist/assets/BulkAssignModal-BXiJnlqt.js.map +1 -0
  87. package/dashboard/dist/assets/{CapabilitiesPage-Q9Pe0y_p.js → CapabilitiesPage-D9TC2iKy.js} +2 -2
  88. package/dashboard/dist/assets/{CapabilitiesPage-Q9Pe0y_p.js.map → CapabilitiesPage-D9TC2iKy.js.map} +1 -1
  89. package/dashboard/dist/assets/{CollapsibleSection-BZOtaWPR.js → CollapsibleSection-D10lGw_u.js} +2 -2
  90. package/dashboard/dist/assets/{CollapsibleSection-BZOtaWPR.js.map → CollapsibleSection-D10lGw_u.js.map} +1 -1
  91. package/dashboard/dist/assets/{ConfirmDeleteModal-6CidwpPx.js → ConfirmDeleteModal-BJdLN6No.js} +2 -2
  92. package/dashboard/dist/assets/{ConfirmDeleteModal-6CidwpPx.js.map → ConfirmDeleteModal-BJdLN6No.js.map} +1 -1
  93. package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js → CopyableId-Bn02zYxt.js} +2 -2
  94. package/dashboard/dist/assets/{CopyableId-4Lqlc5cU.js.map → CopyableId-Bn02zYxt.js.map} +1 -1
  95. package/dashboard/dist/assets/CountdownTimer-D9B-BjQ7.js +2 -0
  96. package/dashboard/dist/assets/CountdownTimer-D9B-BjQ7.js.map +1 -0
  97. package/dashboard/dist/assets/{CredentialsPage-dxjrUEyO.js → CredentialsPage-hniUAFBK.js} +2 -2
  98. package/dashboard/dist/assets/{CredentialsPage-dxjrUEyO.js.map → CredentialsPage-hniUAFBK.js.map} +1 -1
  99. package/dashboard/dist/assets/{CronLabel-D8oo8eaA.js → CronLabel-v9DCD2FX.js} +2 -2
  100. package/dashboard/dist/assets/{CronLabel-D8oo8eaA.js.map → CronLabel-v9DCD2FX.js.map} +1 -1
  101. package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js → DataTable-7C7riavf.js} +2 -2
  102. package/dashboard/dist/assets/{DataTable-DFPMeqyQ.js.map → DataTable-7C7riavf.js.map} +1 -1
  103. package/dashboard/dist/assets/{DropZone-CWCh5ItZ.js → DropZone-XlcY8hEH.js} +2 -2
  104. package/dashboard/dist/assets/{DropZone-CWCh5ItZ.js.map → DropZone-XlcY8hEH.js.map} +1 -1
  105. package/dashboard/dist/assets/{ElapsedCell-FHHQ69G3.js → ElapsedCell-_xvVTK8N.js} +2 -2
  106. package/dashboard/dist/assets/{ElapsedCell-FHHQ69G3.js.map → ElapsedCell-_xvVTK8N.js.map} +1 -1
  107. package/dashboard/dist/assets/{EmptyState-lpUFYfun.js → EmptyState-DgC_6njU.js} +2 -2
  108. package/dashboard/dist/assets/{EmptyState-lpUFYfun.js.map → EmptyState-DgC_6njU.js.map} +1 -1
  109. package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js +2 -0
  110. package/dashboard/dist/assets/EntityTimelinePanel-1lT3jkCM.js.map +1 -0
  111. package/dashboard/dist/assets/{EscalationListSchemaPage-D5L5lDNb.js → EscalationListSchemaPage-BeQUTUEO.js} +3 -3
  112. package/dashboard/dist/assets/{EscalationListSchemaPage-D5L5lDNb.js.map → EscalationListSchemaPage-BeQUTUEO.js.map} +1 -1
  113. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js +2 -0
  114. package/dashboard/dist/assets/EscalationListView-uuZRMSLB.js.map +1 -0
  115. package/dashboard/dist/assets/{EscalationSchemaPage-bYbfEpSB.js → EscalationSchemaPage-D4VlEwyS.js} +3 -3
  116. package/dashboard/dist/assets/{EscalationSchemaPage-bYbfEpSB.js.map → EscalationSchemaPage-D4VlEwyS.js.map} +1 -1
  117. package/dashboard/dist/assets/{EscalationsOverview-DjtIjL1b.js → EscalationsOverview-Bx6Zrzm-.js} +2 -2
  118. package/dashboard/dist/assets/{EscalationsOverview-DjtIjL1b.js.map → EscalationsOverview-Bx6Zrzm-.js.map} +1 -1
  119. package/dashboard/dist/assets/{EventTable-CihVTREC.js → EventTable-KEC3YWBf.js} +2 -2
  120. package/dashboard/dist/assets/{EventTable-CihVTREC.js.map → EventTable-KEC3YWBf.js.map} +1 -1
  121. package/dashboard/dist/assets/{FilterBar-Fin1IqHc.js → FilterBar-xwN_b5fj.js} +2 -2
  122. package/dashboard/dist/assets/{FilterBar-Fin1IqHc.js.map → FilterBar-xwN_b5fj.js.map} +1 -1
  123. package/dashboard/dist/assets/{GraphInvokePage-D77ILPd3.js → GraphInvokePage-DV7Y0fe2.js} +2 -2
  124. package/dashboard/dist/assets/{GraphInvokePage-D77ILPd3.js.map → GraphInvokePage-DV7Y0fe2.js.map} +1 -1
  125. package/dashboard/dist/assets/HomePage-G785SWcW.js +2 -0
  126. package/dashboard/dist/assets/HomePage-G785SWcW.js.map +1 -0
  127. package/dashboard/dist/assets/ListToolbar-zPVYPg3W.js +2 -0
  128. package/dashboard/dist/assets/{ListToolbar-DyHaJBTk.js.map → ListToolbar-zPVYPg3W.js.map} +1 -1
  129. package/dashboard/dist/assets/{McpOverview-qz7Ivf0G.js → McpOverview-CMGUq8hx.js} +2 -2
  130. package/dashboard/dist/assets/{McpOverview-qz7Ivf0G.js.map → McpOverview-CMGUq8hx.js.map} +1 -1
  131. package/dashboard/dist/assets/{McpQueryDetailPage-D6MB4CZM.js → McpQueryDetailPage-CdhLhaKn.js} +3 -3
  132. package/dashboard/dist/assets/{McpQueryDetailPage-D6MB4CZM.js.map → McpQueryDetailPage-CdhLhaKn.js.map} +1 -1
  133. package/dashboard/dist/assets/McpQueryPage-CNSNMagY.js +2 -0
  134. package/dashboard/dist/assets/{McpQueryPage-BqqRF5cQ.js.map → McpQueryPage-CNSNMagY.js.map} +1 -1
  135. package/dashboard/dist/assets/{McpRunDetailPage-DxLEhzhn.js → McpRunDetailPage-DBm8hUaW.js} +2 -2
  136. package/dashboard/dist/assets/{McpRunDetailPage-DxLEhzhn.js.map → McpRunDetailPage-DBm8hUaW.js.map} +1 -1
  137. package/dashboard/dist/assets/{McpRunsPage-BOsS4Hdf.js → McpRunsPage-B6rb5QBf.js} +2 -2
  138. package/dashboard/dist/assets/{McpRunsPage-BOsS4Hdf.js.map → McpRunsPage-B6rb5QBf.js.map} +1 -1
  139. package/dashboard/dist/assets/NamespacePill-Bb3revqD.js +2 -0
  140. package/dashboard/dist/assets/{NamespacePill-CJikgGzE.js.map → NamespacePill-Bb3revqD.js.map} +1 -1
  141. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js +3 -0
  142. package/dashboard/dist/assets/OperationsPage-Dxk1fAMg.js.map +1 -0
  143. package/dashboard/dist/assets/OperatorDashboard-DBOscDnf.js +2 -0
  144. package/dashboard/dist/assets/{OperatorDashboard-C5rlijvh.js.map → OperatorDashboard-DBOscDnf.js.map} +1 -1
  145. package/dashboard/dist/assets/{PageHeader-DZmymFBS.js → PageHeader-Di5Sz3an.js} +2 -2
  146. package/dashboard/dist/assets/{PageHeader-DZmymFBS.js.map → PageHeader-Di5Sz3an.js.map} +1 -1
  147. package/dashboard/dist/assets/{PageHeaderWithStats-DuAm6YK2.js → PageHeaderWithStats-DutKJ-h2.js} +2 -2
  148. package/dashboard/dist/assets/{PageHeaderWithStats-DuAm6YK2.js.map → PageHeaderWithStats-DutKJ-h2.js.map} +1 -1
  149. package/dashboard/dist/assets/{PersonaDetailPage-JBdVvT5g.js → PersonaDetailPage-BGRdGpeR.js} +2 -2
  150. package/dashboard/dist/assets/{PersonaDetailPage-JBdVvT5g.js.map → PersonaDetailPage-BGRdGpeR.js.map} +1 -1
  151. package/dashboard/dist/assets/PersonasPage-DRzOZcVa.js +2 -0
  152. package/dashboard/dist/assets/PersonasPage-DRzOZcVa.js.map +1 -0
  153. package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js → PriorityBadge-r33mpDju.js} +2 -2
  154. package/dashboard/dist/assets/{PriorityBadge-BETdj4M-.js.map → PriorityBadge-r33mpDju.js.map} +1 -1
  155. package/dashboard/dist/assets/{ProcessDetailPage-CHnzOzQn.js → ProcessDetailPage-BLGjZXpM.js} +2 -2
  156. package/dashboard/dist/assets/{ProcessDetailPage-CHnzOzQn.js.map → ProcessDetailPage-BLGjZXpM.js.map} +1 -1
  157. package/dashboard/dist/assets/ProcessesListPage-5NnysKFC.js +2 -0
  158. package/dashboard/dist/assets/{ProcessesListPage-DuXTS5-v.js.map → ProcessesListPage-5NnysKFC.js.map} +1 -1
  159. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js +2 -0
  160. package/dashboard/dist/assets/ResolverForm-Dy0yirtP.js.map +1 -0
  161. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js +8 -0
  162. package/dashboard/dist/assets/RoleDetailPage-C_LIoe1j.js.map +1 -0
  163. package/dashboard/dist/assets/{RolePill-C9LSs1aK.js → RolePill-DhnVPK4q.js} +2 -2
  164. package/dashboard/dist/assets/{RolePill-C9LSs1aK.js.map → RolePill-DhnVPK4q.js.map} +1 -1
  165. package/dashboard/dist/assets/RolesPage-BmW1LzkU.js +2 -0
  166. package/dashboard/dist/assets/{RolesPage-h77-JOLd.js.map → RolesPage-BmW1LzkU.js.map} +1 -1
  167. package/dashboard/dist/assets/{RowActions-eYrzgQSj.js → RowActions-Bdd7z4eB.js} +2 -2
  168. package/dashboard/dist/assets/{RowActions-eYrzgQSj.js.map → RowActions-Bdd7z4eB.js.map} +1 -1
  169. package/dashboard/dist/assets/RunAsSelector-BwZTJ4Yj.js +2 -0
  170. package/dashboard/dist/assets/{RunAsSelector-DoLFJ0mZ.js.map → RunAsSelector-BwZTJ4Yj.js.map} +1 -1
  171. package/dashboard/dist/assets/ScanCodesPage-FiYIYB-m.js +2 -0
  172. package/dashboard/dist/assets/{ScanCodesPage-b5NZM_-f.js.map → ScanCodesPage-FiYIYB-m.js.map} +1 -1
  173. package/dashboard/dist/assets/{ScanSchemeDetailPage-t7X6ekaW.js → ScanSchemeDetailPage-BiAqtD-a.js} +2 -2
  174. package/dashboard/dist/assets/{ScanSchemeDetailPage-t7X6ekaW.js.map → ScanSchemeDetailPage-BiAqtD-a.js.map} +1 -1
  175. package/dashboard/dist/assets/ScanStationPage-8CdOtbCD.js +2 -0
  176. package/dashboard/dist/assets/{ScanStationPage-r02hkTAG.js.map → ScanStationPage-8CdOtbCD.js.map} +1 -1
  177. package/dashboard/dist/assets/{ScopeBadge-CjyC7iyO.js → ScopeBadge-CXUg0FHo.js} +2 -2
  178. package/dashboard/dist/assets/{ScopeBadge-CjyC7iyO.js.map → ScopeBadge-CXUg0FHo.js.map} +1 -1
  179. package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js → SegmentedTabs-BpJh4Hwn.js} +2 -2
  180. package/dashboard/dist/assets/{SegmentedTabs-DXNzY05q.js.map → SegmentedTabs-BpJh4Hwn.js.map} +1 -1
  181. package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js → StatCard-nWY4sndl.js} +2 -2
  182. package/dashboard/dist/assets/{StatCard-BXQ8dD9Y.js.map → StatCard-nWY4sndl.js.map} +1 -1
  183. package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js → StatusBadge-DHVwxre2.js} +2 -2
  184. package/dashboard/dist/assets/{StatusBadge-BDeUwPtb.js.map → StatusBadge-DHVwxre2.js.map} +1 -1
  185. package/dashboard/dist/assets/{StickyPagination-BGHQbp0_.js → StickyPagination-DRuqKhZt.js} +2 -2
  186. package/dashboard/dist/assets/{StickyPagination-BGHQbp0_.js.map → StickyPagination-DRuqKhZt.js.map} +1 -1
  187. package/dashboard/dist/assets/{StreamMessageDetail-C-wfdbLJ.js → StreamMessageDetail-JwlbRiMn.js} +2 -2
  188. package/dashboard/dist/assets/{StreamMessageDetail-C-wfdbLJ.js.map → StreamMessageDetail-JwlbRiMn.js.map} +1 -1
  189. package/dashboard/dist/assets/{SwimlaneTimeline-Dnoz-me3.js → SwimlaneTimeline-hu3c4bCJ.js} +2 -2
  190. package/dashboard/dist/assets/{SwimlaneTimeline-Dnoz-me3.js.map → SwimlaneTimeline-hu3c4bCJ.js.map} +1 -1
  191. package/dashboard/dist/assets/{TagInput-D-vLSMQC.js → TagInput-BZ8vb2oW.js} +2 -2
  192. package/dashboard/dist/assets/{TagInput-D-vLSMQC.js.map → TagInput-BZ8vb2oW.js.map} +1 -1
  193. package/dashboard/dist/assets/{TaskDetailPage-c9IiAhVJ.js → TaskDetailPage-NqVZF3jW.js} +2 -2
  194. package/dashboard/dist/assets/{TaskDetailPage-c9IiAhVJ.js.map → TaskDetailPage-NqVZF3jW.js.map} +1 -1
  195. package/dashboard/dist/assets/{TaskQueuePill-sFRMrQ5D.js → TaskQueuePill-Bxir8WRl.js} +2 -2
  196. package/dashboard/dist/assets/{TaskQueuePill-sFRMrQ5D.js.map → TaskQueuePill-Bxir8WRl.js.map} +1 -1
  197. package/dashboard/dist/assets/TasksListPage-BQNaSzCn.js +2 -0
  198. package/dashboard/dist/assets/{TasksListPage-Dor8LSc5.js.map → TasksListPage-BQNaSzCn.js.map} +1 -1
  199. package/dashboard/dist/assets/TimeAgo-Cv35DOiI.js +2 -0
  200. package/dashboard/dist/assets/{TimeAgo-Dd8vmRnM.js.map → TimeAgo-Cv35DOiI.js.map} +1 -1
  201. package/dashboard/dist/assets/{TimestampCell-qJfC6-iT.js → TimestampCell-DHUXey9s.js} +2 -2
  202. package/dashboard/dist/assets/{TimestampCell-qJfC6-iT.js.map → TimestampCell-DHUXey9s.js.map} +1 -1
  203. package/dashboard/dist/assets/{ToolPill-OQ3mC11d.js → ToolPill-FkgTXIhq.js} +2 -2
  204. package/dashboard/dist/assets/{ToolPill-OQ3mC11d.js.map → ToolPill-FkgTXIhq.js.map} +1 -1
  205. package/dashboard/dist/assets/ToolTestPanel-DvuLFWqQ.js +2 -0
  206. package/dashboard/dist/assets/{ToolTestPanel-CEGY5jss.js.map → ToolTestPanel-DvuLFWqQ.js.map} +1 -1
  207. package/dashboard/dist/assets/{TopicDetailPage-SI80ZTVv.js → TopicDetailPage-TXX3QNSo.js} +3 -3
  208. package/dashboard/dist/assets/{TopicDetailPage-SI80ZTVv.js.map → TopicDetailPage-TXX3QNSo.js.map} +1 -1
  209. package/dashboard/dist/assets/{TopicsPage-DiVB8tNr.js → TopicsPage-h-oyTeEJ.js} +2 -2
  210. package/dashboard/dist/assets/{TopicsPage-DiVB8tNr.js.map → TopicsPage-h-oyTeEJ.js.map} +1 -1
  211. package/dashboard/dist/assets/UserName-BceRCeDF.js +2 -0
  212. package/dashboard/dist/assets/UserName-BceRCeDF.js.map +1 -0
  213. package/dashboard/dist/assets/WorkflowExecutionPage-CmHGcaN9.js +2 -0
  214. package/dashboard/dist/assets/{WorkflowExecutionPage-e-Q57yiJ.js.map → WorkflowExecutionPage-CmHGcaN9.js.map} +1 -1
  215. package/dashboard/dist/assets/{WorkflowPill-Dh3hIW1l.js → WorkflowPill--AYMW7u_.js} +2 -2
  216. package/dashboard/dist/assets/WorkflowPill--AYMW7u_.js.map +1 -0
  217. package/dashboard/dist/assets/WorkflowsDashboard-B0r2lQXk.js +2 -0
  218. package/dashboard/dist/assets/{WorkflowsDashboard-DLKzN80h.js.map → WorkflowsDashboard-B0r2lQXk.js.map} +1 -1
  219. package/dashboard/dist/assets/WorkflowsOverview-BTMc2PJ_.js +2 -0
  220. package/dashboard/dist/assets/{WorkflowsOverview-J-ITQiO5.js.map → WorkflowsOverview-BTMc2PJ_.js.map} +1 -1
  221. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B_-ahhf1.js → YamlWorkflowDetailPage-DUiCVnZp.js} +2 -2
  222. package/dashboard/dist/assets/{YamlWorkflowDetailPage-B_-ahhf1.js.map → YamlWorkflowDetailPage-DUiCVnZp.js.map} +1 -1
  223. package/dashboard/dist/assets/YamlWorkflowsPage-BAuXfwi0.js +2 -0
  224. package/dashboard/dist/assets/{YamlWorkflowsPage-DQNeERXU.js.map → YamlWorkflowsPage-BAuXfwi0.js.map} +1 -1
  225. package/dashboard/dist/assets/{agents-BsJ-MizQ.js → agents-BvmLCk4h.js} +2 -2
  226. package/dashboard/dist/assets/{agents-BsJ-MizQ.js.map → agents-BvmLCk4h.js.map} +1 -1
  227. package/dashboard/dist/assets/{bots-q1UYqaIh.js → bots-f_tyhl4I.js} +2 -2
  228. package/dashboard/dist/assets/{bots-q1UYqaIh.js.map → bots-f_tyhl4I.js.map} +1 -1
  229. package/dashboard/dist/assets/capabilities-DNo5bqLx.js +2 -0
  230. package/dashboard/dist/assets/{capabilities-BvjPXUcJ.js.map → capabilities-DNo5bqLx.js.map} +1 -1
  231. package/dashboard/dist/assets/{controlplane-BwlNpoJ_.js → controlplane-Dyyj2Irb.js} +2 -2
  232. package/dashboard/dist/assets/{controlplane-BwlNpoJ_.js.map → controlplane-Dyyj2Irb.js.map} +1 -1
  233. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js +2 -0
  234. package/dashboard/dist/assets/escalation-columns-DIigeTOK.js.map +1 -0
  235. package/dashboard/dist/assets/index-BMlQYOE1.js +67 -0
  236. package/dashboard/dist/assets/index-BMlQYOE1.js.map +1 -0
  237. package/dashboard/dist/assets/index-BNZknxFY.js +2 -0
  238. package/dashboard/dist/assets/{index-cvmt1plS.js.map → index-BNZknxFY.js.map} +1 -1
  239. package/dashboard/dist/assets/index-Bpvfr4OW.css +1 -0
  240. package/dashboard/dist/assets/{index-CldVY0UQ.js → index-C-Xr2V3F.js} +2 -2
  241. package/dashboard/dist/assets/{index-CldVY0UQ.js.map → index-C-Xr2V3F.js.map} +1 -1
  242. package/dashboard/dist/assets/index-CegPUKpc.js +3 -0
  243. package/dashboard/dist/assets/index-CegPUKpc.js.map +1 -0
  244. package/dashboard/dist/assets/{index-O9uuK2yO.js → index-CsKiRyhy.js} +2 -2
  245. package/dashboard/dist/assets/{index-O9uuK2yO.js.map → index-CsKiRyhy.js.map} +1 -1
  246. package/dashboard/dist/assets/index-D7ESqn22.js +2 -0
  247. package/dashboard/dist/assets/{index-BhzsR_gZ.js.map → index-D7ESqn22.js.map} +1 -1
  248. package/dashboard/dist/assets/{index-Hbbox1A4.js → index-DL83W7Gu.js} +2 -2
  249. package/dashboard/dist/assets/{index-Hbbox1A4.js.map → index-DL83W7Gu.js.map} +1 -1
  250. package/dashboard/dist/assets/index-DPLssnMW.js +6 -0
  251. package/dashboard/dist/assets/index-DPLssnMW.js.map +1 -0
  252. package/dashboard/dist/assets/{index-DsKqDMs4.js → index-DWse7ERF.js} +2 -2
  253. package/dashboard/dist/assets/{index-DsKqDMs4.js.map → index-DWse7ERF.js.map} +1 -1
  254. package/dashboard/dist/assets/index-DoETPlJP.js +11 -0
  255. package/dashboard/dist/assets/index-DoETPlJP.js.map +1 -0
  256. package/dashboard/dist/assets/{index-8Gmtvd8e.js → index-DvxxrFBo.js} +2 -2
  257. package/dashboard/dist/assets/{index-8Gmtvd8e.js.map → index-DvxxrFBo.js.map} +1 -1
  258. package/dashboard/dist/assets/{index-DDHoDZRg.js → index-PcyGjmBm.js} +2 -2
  259. package/dashboard/dist/assets/{index-DDHoDZRg.js.map → index-PcyGjmBm.js.map} +1 -1
  260. package/dashboard/dist/assets/{index-BvGIyZUt.js → index-e2X-s0EQ.js} +2 -2
  261. package/dashboard/dist/assets/{index-BvGIyZUt.js.map → index-e2X-s0EQ.js.map} +1 -1
  262. package/dashboard/dist/assets/{knowledge-DM0tNphj.js → knowledge-Coo6CKzo.js} +2 -2
  263. package/dashboard/dist/assets/{knowledge-DM0tNphj.js.map → knowledge-Coo6CKzo.js.map} +1 -1
  264. package/dashboard/dist/assets/{mcp-CQ_TD2P9.js → mcp-Cz5eFnP_.js} +2 -2
  265. package/dashboard/dist/assets/{mcp-CQ_TD2P9.js.map → mcp-Cz5eFnP_.js.map} +1 -1
  266. package/dashboard/dist/assets/{mcp-query-BP7KSGhc.js → mcp-query-BtnuO4LF.js} +2 -2
  267. package/dashboard/dist/assets/{mcp-query-BP7KSGhc.js.map → mcp-query-BtnuO4LF.js.map} +1 -1
  268. package/dashboard/dist/assets/{personas-DclHdHKK.js → personas-C2-LgpHQ.js} +2 -2
  269. package/dashboard/dist/assets/{personas-DclHdHKK.js.map → personas-C2-LgpHQ.js.map} +1 -1
  270. package/dashboard/dist/assets/{pipelines-LwuKJfj-.js → pipelines-TuXQvUA-.js} +2 -2
  271. package/dashboard/dist/assets/{pipelines-LwuKJfj-.js.map → pipelines-TuXQvUA-.js.map} +1 -1
  272. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js +2 -0
  273. package/dashboard/dist/assets/resolver-payload-C1dXB3n6.js.map +1 -0
  274. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js +2 -0
  275. package/dashboard/dist/assets/seed-form-json-DvPsISxD.js.map +1 -0
  276. package/dashboard/dist/assets/{tasks-CDs-Li2v.js → tasks-OUzpu__z.js} +2 -2
  277. package/dashboard/dist/assets/{tasks-CDs-Li2v.js.map → tasks-OUzpu__z.js.map} +1 -1
  278. package/dashboard/dist/assets/{topics-BeOSelBX.js → topics-B8bdrBaW.js} +2 -2
  279. package/dashboard/dist/assets/{topics-BeOSelBX.js.map → topics-B8bdrBaW.js.map} +1 -1
  280. package/dashboard/dist/assets/useDebouncedValue-Cp5ZOtVE.js +2 -0
  281. package/dashboard/dist/assets/{useDebouncedValue-DhhAKjDC.js.map → useDebouncedValue-Cp5ZOtVE.js.map} +1 -1
  282. package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js → useFilterParams-DBRw1Hcv.js} +2 -2
  283. package/dashboard/dist/assets/{useFilterParams-crmlBw_l.js.map → useFilterParams-DBRw1Hcv.js.map} +1 -1
  284. package/dashboard/dist/assets/{useNamespace-C-E2gNEK.js → useNamespace-DtQe3wZ5.js} +2 -2
  285. package/dashboard/dist/assets/{useNamespace-C-E2gNEK.js.map → useNamespace-DtQe3wZ5.js.map} +1 -1
  286. package/dashboard/dist/assets/{useYamlActivityEvents-CmLzX3YU.js → useYamlActivityEvents-CS22c15X.js} +2 -2
  287. package/dashboard/dist/assets/{useYamlActivityEvents-CmLzX3YU.js.map → useYamlActivityEvents-CS22c15X.js.map} +1 -1
  288. package/dashboard/dist/assets/{vendor-icons-R9b9gQ04.js → vendor-icons-DeBdvyKJ.js} +368 -143
  289. package/dashboard/dist/assets/vendor-icons-DeBdvyKJ.js.map +1 -0
  290. package/dashboard/dist/assets/vendor-query-DvWWuNIB.js +18 -0
  291. package/dashboard/dist/assets/vendor-query-DvWWuNIB.js.map +1 -0
  292. package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js → vendor-react-_9U4mKFr.js} +2 -2
  293. package/dashboard/dist/assets/{vendor-react-CdqEC2zv.js.map → vendor-react-_9U4mKFr.js.map} +1 -1
  294. package/dashboard/dist/assets/{yaml-workflows-BgAsc6-I.js → yaml-workflows-HQIki3hI.js} +2 -2
  295. package/dashboard/dist/assets/{yaml-workflows-BgAsc6-I.js.map → yaml-workflows-HQIki3hI.js.map} +1 -1
  296. package/dashboard/dist/index.html +5 -5
  297. package/docs/api/http/workflows.md +25 -1
  298. package/docs/code-owned-configuration.md +1 -1
  299. package/docs/dashboard.md +179 -80
  300. package/docs/events.md +3 -1
  301. package/docs/faceted-routing.md +5 -1
  302. package/docs/hitl/iframe.md +35 -6
  303. package/docs/hitl/invoke-form.md +98 -0
  304. package/docs/hitl/x-lt-list-schema.md +3 -0
  305. package/docs/hitl/x-lt-show-if.md +11 -0
  306. package/docs/hitl-guide.md +4 -2
  307. package/docs/iam.md +1 -1
  308. package/docs/operations.md +61 -60
  309. package/docs/scan-codes.md +30 -3
  310. package/docs/workflows.md +1 -1
  311. package/package.json +1 -1
  312. package/dashboard/dist/assets/AgentsPage-CLSjlyXy.js +0 -2
  313. package/dashboard/dist/assets/AvailableEscalationsPage-D2ukvuQh.js +0 -2
  314. package/dashboard/dist/assets/AvailableEscalationsPage-D2ukvuQh.js.map +0 -1
  315. package/dashboard/dist/assets/BulkAssignModal-CMSgvHIs.js +0 -2
  316. package/dashboard/dist/assets/BulkAssignModal-CMSgvHIs.js.map +0 -1
  317. package/dashboard/dist/assets/CountdownTimer-B5lM7PfE.js +0 -2
  318. package/dashboard/dist/assets/CountdownTimer-B5lM7PfE.js.map +0 -1
  319. package/dashboard/dist/assets/EntityTimelinePanel-B5NuHnPF.js +0 -2
  320. package/dashboard/dist/assets/EntityTimelinePanel-B5NuHnPF.js.map +0 -1
  321. package/dashboard/dist/assets/HomePage-8XsQFqKL.js +0 -2
  322. package/dashboard/dist/assets/HomePage-8XsQFqKL.js.map +0 -1
  323. package/dashboard/dist/assets/ListToolbar-DyHaJBTk.js +0 -2
  324. package/dashboard/dist/assets/McpQueryPage-BqqRF5cQ.js +0 -2
  325. package/dashboard/dist/assets/NamespacePill-CJikgGzE.js +0 -2
  326. package/dashboard/dist/assets/OperationsPage-Cj1mJLMC.js +0 -3
  327. package/dashboard/dist/assets/OperationsPage-Cj1mJLMC.js.map +0 -1
  328. package/dashboard/dist/assets/OperatorDashboard-C5rlijvh.js +0 -2
  329. package/dashboard/dist/assets/PersonasPage-Xp_Gt6El.js +0 -2
  330. package/dashboard/dist/assets/PersonasPage-Xp_Gt6El.js.map +0 -1
  331. package/dashboard/dist/assets/ProcessesListPage-DuXTS5-v.js +0 -2
  332. package/dashboard/dist/assets/RoleDetailPage-C9GGHNf4.js +0 -8
  333. package/dashboard/dist/assets/RoleDetailPage-C9GGHNf4.js.map +0 -1
  334. package/dashboard/dist/assets/RolesPage-h77-JOLd.js +0 -2
  335. package/dashboard/dist/assets/RunAsSelector-DoLFJ0mZ.js +0 -2
  336. package/dashboard/dist/assets/ScanCodesPage-b5NZM_-f.js +0 -2
  337. package/dashboard/dist/assets/ScanStationPage-r02hkTAG.js +0 -2
  338. package/dashboard/dist/assets/TasksListPage-Dor8LSc5.js +0 -2
  339. package/dashboard/dist/assets/TimeAgo-Dd8vmRnM.js +0 -2
  340. package/dashboard/dist/assets/ToolTestPanel-CEGY5jss.js +0 -2
  341. package/dashboard/dist/assets/UserName-Dmm456xT.js +0 -2
  342. package/dashboard/dist/assets/UserName-Dmm456xT.js.map +0 -1
  343. package/dashboard/dist/assets/WorkflowExecutionPage-e-Q57yiJ.js +0 -2
  344. package/dashboard/dist/assets/WorkflowPill-Dh3hIW1l.js.map +0 -1
  345. package/dashboard/dist/assets/WorkflowsDashboard-DLKzN80h.js +0 -2
  346. package/dashboard/dist/assets/WorkflowsOverview-J-ITQiO5.js +0 -2
  347. package/dashboard/dist/assets/YamlWorkflowsPage-DQNeERXU.js +0 -2
  348. package/dashboard/dist/assets/capabilities-BvjPXUcJ.js +0 -2
  349. package/dashboard/dist/assets/escalation-columns-Bo3PfIZj.js +0 -2
  350. package/dashboard/dist/assets/escalation-columns-Bo3PfIZj.js.map +0 -1
  351. package/dashboard/dist/assets/index-B8JfGtQB.js +0 -3
  352. package/dashboard/dist/assets/index-B8JfGtQB.js.map +0 -1
  353. package/dashboard/dist/assets/index-Bb9ZZUyB.js +0 -5
  354. package/dashboard/dist/assets/index-Bb9ZZUyB.js.map +0 -1
  355. package/dashboard/dist/assets/index-BhzsR_gZ.js +0 -2
  356. package/dashboard/dist/assets/index-D88VWEVp.js +0 -67
  357. package/dashboard/dist/assets/index-D88VWEVp.js.map +0 -1
  358. package/dashboard/dist/assets/index-DBvkaa-B.js +0 -6
  359. package/dashboard/dist/assets/index-DBvkaa-B.js.map +0 -1
  360. package/dashboard/dist/assets/index-cvmt1plS.js +0 -2
  361. package/dashboard/dist/assets/index-qU_dXqP4.css +0 -1
  362. package/dashboard/dist/assets/useDebouncedValue-DhhAKjDC.js +0 -2
  363. package/dashboard/dist/assets/vendor-icons-R9b9gQ04.js.map +0 -1
  364. package/dashboard/dist/assets/vendor-query-RUZdMvN6.js +0 -18
  365. package/dashboard/dist/assets/vendor-query-RUZdMvN6.js.map +0 -1
  366. package/dashboard/dist/assets/workflows-CYv1CTU0.js +0 -2
  367. package/dashboard/dist/assets/workflows-CYv1CTU0.js.map +0 -1
@@ -0,0 +1,18 @@
1
+ import type { LTWorkflowConfig } from '../types/config';
2
+ export interface InvocationRoleGrant {
3
+ role: string;
4
+ type: string;
5
+ }
6
+ export declare const INVOCATION_ROLE_TYPES: {
7
+ readonly SUPERADMIN: "superadmin";
8
+ readonly ADMIN: "admin";
9
+ };
10
+ export declare const ADMIN_ROLE = "admin";
11
+ /** Superadmin anywhere, or the named admin role held as admin type, invokes every workflow. */
12
+ export declare function hasGlobalInvocationAccess(roles: readonly InvocationRoleGrant[], authRole?: string): boolean;
13
+ /**
14
+ * The one invocation predicate, shared by the invoke gate and the per-caller
15
+ * list so the two can never disagree. An empty invocation_roles list opens
16
+ * the workflow to every authenticated caller.
17
+ */
18
+ export declare function canInvokeWorkflow(config: Pick<LTWorkflowConfig, 'invocable' | 'invocation_roles'>, roles: readonly InvocationRoleGrant[], authRole?: string): boolean;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ADMIN_ROLE = exports.INVOCATION_ROLE_TYPES = void 0;
4
+ exports.hasGlobalInvocationAccess = hasGlobalInvocationAccess;
5
+ exports.canInvokeWorkflow = canInvokeWorkflow;
6
+ exports.INVOCATION_ROLE_TYPES = {
7
+ SUPERADMIN: 'superadmin',
8
+ ADMIN: 'admin',
9
+ };
10
+ exports.ADMIN_ROLE = 'admin';
11
+ /** Superadmin anywhere, or the named admin role held as admin type, invokes every workflow. */
12
+ function hasGlobalInvocationAccess(roles, authRole) {
13
+ if (authRole === exports.INVOCATION_ROLE_TYPES.SUPERADMIN)
14
+ return true;
15
+ return roles.some((r) => r.type === exports.INVOCATION_ROLE_TYPES.SUPERADMIN)
16
+ || roles.some((r) => r.role === exports.ADMIN_ROLE && r.type === exports.INVOCATION_ROLE_TYPES.ADMIN);
17
+ }
18
+ /**
19
+ * The one invocation predicate, shared by the invoke gate and the per-caller
20
+ * list so the two can never disagree. An empty invocation_roles list opens
21
+ * the workflow to every authenticated caller.
22
+ */
23
+ function canInvokeWorkflow(config, roles, authRole) {
24
+ if (!config.invocable)
25
+ return false;
26
+ if (config.invocation_roles.length === 0)
27
+ return true;
28
+ if (hasGlobalInvocationAccess(roles, authRole))
29
+ return true;
30
+ const held = new Set(roles.map((r) => r.role));
31
+ return config.invocation_roles.some((r) => held.has(r));
32
+ }
@@ -17,7 +17,7 @@ export interface EscalationChain {
17
17
  * the detail page, and the scan screens. Multi-role users get full chrome.
18
18
  * - LINK_VARIABLES: RoleLinkVariable[] — metadata facet names members bind
19
19
  * per device. Pins may reference `{lt:name}` as a whole facet value
20
- * (e.g. `facets={"facility":"{lt:facility}"}`); the dashboard substitutes
20
+ * (e.g. `facets={"region":"{lt:region}"}`); the dashboard substitutes
21
21
  * the device's bound value at render time, falls back to the declared
22
22
  * default, and drops the facet entirely when both are unset.
23
23
  */
@@ -16,7 +16,7 @@ exports.ROLE_PROPERTY_KEYS = void 0;
16
16
  * the detail page, and the scan screens. Multi-role users get full chrome.
17
17
  * - LINK_VARIABLES: RoleLinkVariable[] — metadata facet names members bind
18
18
  * per device. Pins may reference `{lt:name}` as a whole facet value
19
- * (e.g. `facets={"facility":"{lt:facility}"}`); the dashboard substitutes
19
+ * (e.g. `facets={"region":"{lt:region}"}`); the dashboard substitutes
20
20
  * the device's bound value at render time, falls back to the declared
21
21
  * default, and drops the facet entirely when both are unset.
22
22
  */
@@ -16,11 +16,11 @@ const sql_1 = require("./sql");
16
16
  */
17
17
  async function verifyPassword(externalId, password) {
18
18
  const pool = (0, db_1.getPool)();
19
- const { rows } = await pool.query(sql_1.GET_USER_BY_EXTERNAL_ID, [externalId]);
19
+ const { rows } = await pool.query(sql_1.GET_USER_FOR_AUTH, [externalId]);
20
20
  if (!rows[0] || !rows[0].password_hash)
21
21
  return null;
22
22
  const valid = await bcryptjs_1.default.compare(password, rows[0].password_hash);
23
23
  if (!valid)
24
24
  return null;
25
- return (0, crud_1.attachRoles)(rows[0]);
25
+ return (0, crud_1.getUser)(rows[0].id);
26
26
  }
@@ -3,6 +3,19 @@ import type { CreateUserInput, UpdateUserInput, UserPropertyOps } from './types'
3
3
  export declare function attachRoles(user: any): Promise<LTUserRecord>;
4
4
  export declare function createUser(input: CreateUserInput): Promise<LTUserRecord>;
5
5
  export declare function getUser(id: string): Promise<LTUserRecord | null>;
6
+ export interface UserNameRecord {
7
+ id: string;
8
+ display_name: string | null;
9
+ external_id: string;
10
+ email: string | null;
11
+ }
12
+ /**
13
+ * Resolve many user ids to display fields in one query. Non-UUID input is
14
+ * dropped before the SQL (a bad id is not-found, never a 500), ids are deduped,
15
+ * and the batch is capped. Returns display fields only — never secrets, scopes,
16
+ * or metadata.
17
+ */
18
+ export declare function getUserNames(ids: string[]): Promise<UserNameRecord[]>;
6
19
  export declare function getUserByExternalId(externalId: string): Promise<LTUserRecord | null>;
7
20
  export declare function getUserByEmail(email: string): Promise<LTUserRecord | null>;
8
21
  /**
@@ -7,6 +7,7 @@ exports.UserPropertyValidationError = exports.UserPropertyConflictError = void 0
7
7
  exports.attachRoles = attachRoles;
8
8
  exports.createUser = createUser;
9
9
  exports.getUser = getUser;
10
+ exports.getUserNames = getUserNames;
10
11
  exports.getUserByExternalId = getUserByExternalId;
11
12
  exports.getUserByEmail = getUserByEmail;
12
13
  exports.getUserByMetadataValue = getUserByMetadataValue;
@@ -18,14 +19,21 @@ exports.listUsers = listUsers;
18
19
  const bcryptjs_1 = __importDefault(require("bcryptjs"));
19
20
  const db_1 = require("../../lib/db");
20
21
  const sql_1 = require("./sql");
22
+ const uuid_1 = require("../../lib/uuid");
21
23
  const scan_code_1 = require("../scan-code");
22
24
  const scan_code_2 = require("../../types/scan-code");
23
25
  const scope_1 = require("./scope");
24
26
  // ─── Private helpers (exported for internal use by auth.ts) ──────────────────
27
+ /** Last-line guard: strip credentials before any user record leaves the service, so a stray SELECT * can never leak them. */
28
+ function stripUserSecrets(user) {
29
+ delete user.password_hash;
30
+ delete user.oauth_provider_id;
31
+ return user;
32
+ }
25
33
  async function attachRoles(user) {
26
34
  const pool = (0, db_1.getPool)();
27
35
  const { rows } = await pool.query(sql_1.GET_ROLES_BY_USER_ID, [user.id]);
28
- return { ...user, roles: rows };
36
+ return stripUserSecrets({ ...user, roles: rows });
29
37
  }
30
38
  async function attachRolesToMany(users) {
31
39
  if (users.length === 0)
@@ -45,7 +53,7 @@ async function attachRolesToMany(users) {
45
53
  });
46
54
  roleMap.set(row.user_id, list);
47
55
  }
48
- return users.map((u) => ({ ...u, roles: roleMap.get(u.id) || [] }));
56
+ return users.map((u) => stripUserSecrets({ ...u, roles: roleMap.get(u.id) || [] }));
49
57
  }
50
58
  // ─── CRUD ─────────────────────────────────────────────────────────────────────
51
59
  async function createUser(input) {
@@ -85,6 +93,21 @@ async function getUser(id) {
85
93
  return null;
86
94
  return attachRoles(rows[0]);
87
95
  }
96
+ const MAX_NAME_LOOKUP = 200;
97
+ /**
98
+ * Resolve many user ids to display fields in one query. Non-UUID input is
99
+ * dropped before the SQL (a bad id is not-found, never a 500), ids are deduped,
100
+ * and the batch is capped. Returns display fields only — never secrets, scopes,
101
+ * or metadata.
102
+ */
103
+ async function getUserNames(ids) {
104
+ const clean = [...new Set((0, uuid_1.onlyUuids)(ids))].slice(0, MAX_NAME_LOOKUP);
105
+ if (clean.length === 0)
106
+ return [];
107
+ const pool = (0, db_1.getPool)();
108
+ const { rows } = await pool.query(sql_1.GET_NAMES_BY_IDS, [clean]);
109
+ return rows;
110
+ }
88
111
  async function getUserByExternalId(externalId) {
89
112
  const pool = (0, db_1.getPool)();
90
113
  const { rows } = await pool.query(sql_1.GET_USER_BY_EXTERNAL_ID, [externalId]);
@@ -288,7 +311,7 @@ async function listUsers(filters) {
288
311
  const offset = filters.offset || 0;
289
312
  const [countResult, dataResult] = await Promise.all([
290
313
  pool.query(`SELECT COUNT(DISTINCT u.id) FROM lt_users u ${join} ${where}`, values),
291
- pool.query(`SELECT DISTINCT u.* FROM lt_users u ${join} ${where} ORDER BY u.created_at DESC LIMIT $${idx++} OFFSET $${idx++}`, [...values, limit, offset]),
314
+ pool.query(`SELECT DISTINCT ${sql_1.USER_SAFE_COLUMNS_U} FROM lt_users u ${join} ${where} ORDER BY u.created_at DESC LIMIT $${idx++} OFFSET $${idx++}`, [...values, limit, offset]),
292
315
  ]);
293
316
  return {
294
317
  users: await attachRolesToMany(dataResult.rows),
@@ -1,5 +1,5 @@
1
1
  export { CreateUserInput, UpdateUserInput, UserPropertyOps, VALID_ROLE_TYPES } from './types';
2
- export { createUser, getUser, getUserByExternalId, getUserByEmail, getUserByMetadataValue, updateUser, patchUserProperties, getIdentityPropertyKeys, UserPropertyConflictError, UserPropertyValidationError, deleteUser, listUsers, } from './crud';
2
+ export { createUser, getUser, getUserNames, UserNameRecord, getUserByExternalId, getUserByEmail, getUserByMetadataValue, updateUser, patchUserProperties, getIdentityPropertyKeys, UserPropertyConflictError, UserPropertyValidationError, deleteUser, listUsers, } from './crud';
3
3
  export { isValidRoleType, addUserRole, grantRoleIfAbsent, removeUserRole, getUserRoles, hasRole, hasRoleType, } from './roles';
4
4
  export { isSuperAdmin, isGroupAdmin, canManageRole, hasGlobalEscalationAccess, hasRolesAsAdmin, getRoleScope, getRoleWriteScope } from './rbac';
5
5
  export { READ_SCOPES, WRITE_SCOPES, DEFAULT_READ_SCOPE, DEFAULT_WRITE_SCOPE, isValidReadScope, isValidWriteScope, isValidScopePair, effectiveScope, } from './scope';
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.grantRoleIfAbsent = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.UserPropertyValidationError = exports.UserPropertyConflictError = exports.getIdentityPropertyKeys = exports.patchUserProperties = exports.updateUser = exports.getUserByMetadataValue = exports.getUserByEmail = exports.getUserByExternalId = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
3
+ exports.PREFERENCES_MAX_BYTES = exports.patchPreferences = exports.getPreferences = exports.seedAdmin = exports.verifyPassword = exports.effectiveScope = exports.isValidScopePair = exports.isValidWriteScope = exports.isValidReadScope = exports.DEFAULT_WRITE_SCOPE = exports.DEFAULT_READ_SCOPE = exports.WRITE_SCOPES = exports.READ_SCOPES = exports.getRoleWriteScope = exports.getRoleScope = exports.hasRolesAsAdmin = exports.hasGlobalEscalationAccess = exports.canManageRole = exports.isGroupAdmin = exports.isSuperAdmin = exports.hasRoleType = exports.hasRole = exports.getUserRoles = exports.removeUserRole = exports.grantRoleIfAbsent = exports.addUserRole = exports.isValidRoleType = exports.listUsers = exports.deleteUser = exports.UserPropertyValidationError = exports.UserPropertyConflictError = exports.getIdentityPropertyKeys = exports.patchUserProperties = exports.updateUser = exports.getUserByMetadataValue = exports.getUserByEmail = exports.getUserByExternalId = exports.getUserNames = exports.getUser = exports.createUser = exports.VALID_ROLE_TYPES = void 0;
4
4
  var types_1 = require("./types");
5
5
  Object.defineProperty(exports, "VALID_ROLE_TYPES", { enumerable: true, get: function () { return types_1.VALID_ROLE_TYPES; } });
6
6
  var crud_1 = require("./crud");
7
7
  Object.defineProperty(exports, "createUser", { enumerable: true, get: function () { return crud_1.createUser; } });
8
8
  Object.defineProperty(exports, "getUser", { enumerable: true, get: function () { return crud_1.getUser; } });
9
+ Object.defineProperty(exports, "getUserNames", { enumerable: true, get: function () { return crud_1.getUserNames; } });
9
10
  Object.defineProperty(exports, "getUserByExternalId", { enumerable: true, get: function () { return crud_1.getUserByExternalId; } });
10
11
  Object.defineProperty(exports, "getUserByEmail", { enumerable: true, get: function () { return crud_1.getUserByEmail; } });
11
12
  Object.defineProperty(exports, "getUserByMetadataValue", { enumerable: true, get: function () { return crud_1.getUserByMetadataValue; } });
@@ -1,10 +1,14 @@
1
+ export declare const USER_SAFE_COLUMNS: string;
2
+ export declare const USER_SAFE_COLUMNS_U: string;
1
3
  /** Ensure a role name exists in the lt_roles lookup table (FK target). */
2
4
  export declare const ENSURE_ROLE_EXISTS = "INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING";
3
5
  /** Fetch roles for a single user, ordered by creation time. granted_by_persona
4
6
  * is the sustaining persona's key (null = direct grant). */
5
7
  export declare const GET_ROLES_BY_USER_ID = "SELECT r.role, r.type, r.read_scope, r.write_scope, r.created_at, p.key AS granted_by_persona\n FROM lt_user_roles r\n LEFT JOIN lt_personas p ON p.id = r.granted_by_persona\n WHERE r.user_id = $1 ORDER BY r.created_at";
6
8
  /** Fetch a user row by external_id. */
7
- export declare const GET_USER_BY_EXTERNAL_ID = "SELECT * FROM lt_users WHERE external_id = $1";
9
+ export declare const GET_USER_BY_EXTERNAL_ID: string;
10
+ /** Password-check only: the one query that reads the hash, never returned to a client. */
11
+ export declare const GET_USER_FOR_AUTH = "SELECT id, password_hash FROM lt_users WHERE external_id = $1";
8
12
  /**
9
13
  * Create a user and its role assignments in ONE atomic statement. The user row,
10
14
  * the lt_roles FK targets ($9 = role names), and the lt_user_roles links
@@ -15,9 +19,11 @@ export declare const GET_USER_BY_EXTERNAL_ID = "SELECT * FROM lt_users WHERE ext
15
19
  * end, after the sibling role-ensure CTE has run, so brand-new roles are valid
16
20
  * FK targets.
17
21
  */
18
- export declare const CREATE_USER_WITH_ROLES = "WITH new_user AS (\n INSERT INTO lt_users (external_id, email, display_name, status, metadata, password_hash, oauth_provider, oauth_provider_id)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8)\n RETURNING *\n ), ensured_roles AS (\n INSERT INTO lt_roles (role)\n SELECT DISTINCT unnest($9::text[])\n ON CONFLICT DO NOTHING\n ), assigned_roles AS (\n INSERT INTO lt_user_roles (user_id, role, type, read_scope, write_scope)\n SELECT (SELECT id FROM new_user), x.role, x.type, x.read_scope, x.write_scope\n FROM unnest($9::text[], $10::text[], $11::text[], $12::text[]) AS x(role, type, read_scope, write_scope)\n ON CONFLICT DO NOTHING\n )\n SELECT * FROM new_user";
19
- export declare const GET_USER_BY_EMAIL = "SELECT * FROM lt_users WHERE email = $1 LIMIT 1";
20
- export declare const GET_USER_BY_ID = "SELECT * FROM lt_users WHERE id = $1";
22
+ export declare const CREATE_USER_WITH_ROLES: string;
23
+ export declare const GET_USER_BY_EMAIL: string;
24
+ export declare const GET_USER_BY_ID: string;
25
+ /** Thin identity projection for batch name resolution — display fields only, never secrets, scopes, or metadata. */
26
+ export declare const GET_NAMES_BY_IDS = "SELECT id, display_name, external_id, email FROM lt_users WHERE id = ANY($1)";
21
27
  /**
22
28
  * Lookup by a caller-named metadata key (e.g. a badge binding). LIMIT 2 so an
23
29
  * ambiguous binding — two users carrying the same value — is detectable and
@@ -25,7 +31,7 @@ export declare const GET_USER_BY_ID = "SELECT * FROM lt_users WHERE id = $1";
25
31
  * is the people table (small); revisit with a GIN index on metadata if a
26
32
  * deployment ever holds tens of thousands of users.
27
33
  */
28
- export declare const GET_USERS_BY_METADATA_VALUE = "SELECT * FROM lt_users WHERE metadata->>$1 = $2 AND status = 'active' LIMIT 2";
34
+ export declare const GET_USERS_BY_METADATA_VALUE: string;
29
35
  /** Check if a user exists by id. Lightweight — returns only the id column. */
30
36
  export declare const VERIFY_USER_BY_ID = "SELECT id FROM lt_users WHERE id = $1 LIMIT 1";
31
37
  /**
@@ -1,7 +1,15 @@
1
1
  "use strict";
2
2
  // ─── Shared queries (used by multiple modules) ──────────────────────────────
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.IS_GROUP_ADMIN = exports.GET_ROLE_SCOPE = exports.HAS_ROLE_TYPE = exports.HAS_ROLE = exports.DELETE_USER_ROLE = exports.INSERT_USER_ROLE_IF_ABSENT = exports.UPSERT_USER_ROLE = exports.GET_ROLES_BY_USER_IDS = exports.DELETE_USER_BY_ID = exports.GET_USER_WITH_ROLES = exports.PATCH_USER_PROPERTIES = exports.VERIFY_USER_BY_ID = exports.GET_USERS_BY_METADATA_VALUE = exports.GET_USER_BY_ID = exports.GET_USER_BY_EMAIL = exports.CREATE_USER_WITH_ROLES = exports.GET_USER_BY_EXTERNAL_ID = exports.GET_ROLES_BY_USER_ID = exports.ENSURE_ROLE_EXISTS = void 0;
4
+ exports.IS_GROUP_ADMIN = exports.GET_ROLE_SCOPE = exports.HAS_ROLE_TYPE = exports.HAS_ROLE = exports.DELETE_USER_ROLE = exports.INSERT_USER_ROLE_IF_ABSENT = exports.UPSERT_USER_ROLE = exports.GET_ROLES_BY_USER_IDS = exports.DELETE_USER_BY_ID = exports.GET_USER_WITH_ROLES = exports.PATCH_USER_PROPERTIES = exports.VERIFY_USER_BY_ID = exports.GET_USERS_BY_METADATA_VALUE = exports.GET_NAMES_BY_IDS = exports.GET_USER_BY_ID = exports.GET_USER_BY_EMAIL = exports.CREATE_USER_WITH_ROLES = exports.GET_USER_FOR_AUTH = exports.GET_USER_BY_EXTERNAL_ID = exports.GET_ROLES_BY_USER_ID = exports.ENSURE_ROLE_EXISTS = exports.USER_SAFE_COLUMNS_U = exports.USER_SAFE_COLUMNS = void 0;
5
+ /**
6
+ * Every lt_users column a client may see. password_hash and oauth_provider_id
7
+ * are credentials and never appear here — no user read path selects them (the
8
+ * password check has its own GET_USER_FOR_AUTH). `U` prefixes for a joined list.
9
+ */
10
+ const USER_COLS = ['id', 'external_id', 'email', 'display_name', 'status', 'account_type', 'oauth_provider', 'metadata', 'created_at', 'updated_at', 'preferences'];
11
+ exports.USER_SAFE_COLUMNS = USER_COLS.join(', ');
12
+ exports.USER_SAFE_COLUMNS_U = USER_COLS.map((c) => `u.${c}`).join(', ');
5
13
  /** Ensure a role name exists in the lt_roles lookup table (FK target). */
6
14
  exports.ENSURE_ROLE_EXISTS = 'INSERT INTO lt_roles (role) VALUES ($1) ON CONFLICT DO NOTHING';
7
15
  /** Fetch roles for a single user, ordered by creation time. granted_by_persona
@@ -11,7 +19,9 @@ exports.GET_ROLES_BY_USER_ID = `SELECT r.role, r.type, r.read_scope, r.write_sco
11
19
  LEFT JOIN lt_personas p ON p.id = r.granted_by_persona
12
20
  WHERE r.user_id = $1 ORDER BY r.created_at`;
13
21
  /** Fetch a user row by external_id. */
14
- exports.GET_USER_BY_EXTERNAL_ID = 'SELECT * FROM lt_users WHERE external_id = $1';
22
+ exports.GET_USER_BY_EXTERNAL_ID = `SELECT ${exports.USER_SAFE_COLUMNS} FROM lt_users WHERE external_id = $1`;
23
+ /** Password-check only: the one query that reads the hash, never returned to a client. */
24
+ exports.GET_USER_FOR_AUTH = 'SELECT id, password_hash FROM lt_users WHERE external_id = $1';
15
25
  // ─── User CRUD ───────────────────────────────────────────────────────────────
16
26
  /**
17
27
  * Create a user and its role assignments in ONE atomic statement. The user row,
@@ -37,9 +47,11 @@ exports.CREATE_USER_WITH_ROLES = `WITH new_user AS (
37
47
  FROM unnest($9::text[], $10::text[], $11::text[], $12::text[]) AS x(role, type, read_scope, write_scope)
38
48
  ON CONFLICT DO NOTHING
39
49
  )
40
- SELECT * FROM new_user`;
41
- exports.GET_USER_BY_EMAIL = `SELECT * FROM lt_users WHERE email = $1 LIMIT 1`;
42
- exports.GET_USER_BY_ID = 'SELECT * FROM lt_users WHERE id = $1';
50
+ SELECT ${exports.USER_SAFE_COLUMNS} FROM new_user`;
51
+ exports.GET_USER_BY_EMAIL = `SELECT ${exports.USER_SAFE_COLUMNS} FROM lt_users WHERE email = $1 LIMIT 1`;
52
+ exports.GET_USER_BY_ID = `SELECT ${exports.USER_SAFE_COLUMNS} FROM lt_users WHERE id = $1`;
53
+ /** Thin identity projection for batch name resolution — display fields only, never secrets, scopes, or metadata. */
54
+ exports.GET_NAMES_BY_IDS = 'SELECT id, display_name, external_id, email FROM lt_users WHERE id = ANY($1)';
43
55
  /**
44
56
  * Lookup by a caller-named metadata key (e.g. a badge binding). LIMIT 2 so an
45
57
  * ambiguous binding — two users carrying the same value — is detectable and
@@ -47,7 +59,7 @@ exports.GET_USER_BY_ID = 'SELECT * FROM lt_users WHERE id = $1';
47
59
  * is the people table (small); revisit with a GIN index on metadata if a
48
60
  * deployment ever holds tens of thousands of users.
49
61
  */
50
- exports.GET_USERS_BY_METADATA_VALUE = `SELECT * FROM lt_users WHERE metadata->>$1 = $2 AND status = 'active' LIMIT 2`;
62
+ exports.GET_USERS_BY_METADATA_VALUE = `SELECT ${exports.USER_SAFE_COLUMNS} FROM lt_users WHERE metadata->>$1 = $2 AND status = 'active' LIMIT 2`;
51
63
  /** Check if a user exists by id. Lightweight — returns only the id column. */
52
64
  exports.VERIFY_USER_BY_ID = 'SELECT id FROM lt_users WHERE id = $1 LIMIT 1';
53
65
  /**
@@ -46,6 +46,7 @@ exports.InvocationError = void 0;
46
46
  exports.invokeWorkflow = invokeWorkflow;
47
47
  exports.checkInvocationRoles = checkInvocationRoles;
48
48
  const hotmesh_1 = require("@hotmeshio/hotmesh");
49
+ const invocation_access_1 = require("./invocation-access");
49
50
  const workers_1 = require("../workers");
50
51
  const configService = __importStar(require("./config"));
51
52
  const userService = __importStar(require("./user"));
@@ -152,15 +153,9 @@ async function checkInvocationRoles(workflowType, userId, authRole) {
152
153
  if (!user) {
153
154
  throw new InvocationError('User not registered', 403);
154
155
  }
155
- const userRoles = user.roles.map((r) => r.role);
156
- const hasInvocationRole = wfConfig.invocation_roles.some((r) => userRoles.includes(r));
157
- if (!hasInvocationRole) {
158
- // superadmin and admin/admin bypass role checks
159
- const hasGlobalAccess = user.roles.some((r) => r.type === 'superadmin')
160
- || user.roles.some((r) => r.role === 'admin' && r.type === 'admin');
161
- if (!hasGlobalAccess) {
162
- throw new InvocationError('Insufficient role for invocation', 403);
163
- }
156
+ // invocable is resolveTaskQueue's concern; this gate decides roles only.
157
+ if (!(0, invocation_access_1.canInvokeWorkflow)({ ...wfConfig, invocable: true }, user.roles, authRole)) {
158
+ throw new InvocationError('Insufficient role for invocation', 403);
164
159
  }
165
160
  }
166
161
  /**
@@ -19,3 +19,4 @@ export * from './x-lt-options';
19
19
  export * from './ctx-path';
20
20
  export * from './field-validator';
21
21
  export * from './validate-resolver-payload';
22
+ export * from './invoke-context';
@@ -35,3 +35,4 @@ __exportStar(require("./x-lt-options"), exports);
35
35
  __exportStar(require("./ctx-path"), exports);
36
36
  __exportStar(require("./field-validator"), exports);
37
37
  __exportStar(require("./validate-resolver-payload"), exports);
38
+ __exportStar(require("./invoke-context"), exports);
@@ -0,0 +1,7 @@
1
+ import type { ResolverValidationContext } from './validate-resolver-payload';
2
+ /**
3
+ * The context an invoke form validates and renders against. The pass itself
4
+ * supplies the live values under `input` and `resolver`; the envelope
5
+ * metadata is the only other domain an invoke form can reference.
6
+ */
7
+ export declare function buildInvokeFormContext(metadata: Record<string, unknown> | null | undefined): ResolverValidationContext;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildInvokeFormContext = buildInvokeFormContext;
4
+ /**
5
+ * The context an invoke form validates and renders against. The pass itself
6
+ * supplies the live values under `input` and `resolver`; the envelope
7
+ * metadata is the only other domain an invoke form can reference.
8
+ */
9
+ function buildInvokeFormContext(metadata) {
10
+ return { metadata: metadata ?? {} };
11
+ }
@@ -31,7 +31,7 @@ export type { FieldError } from './field-validator';
31
31
  * dynamic constraints against. `resolver` is supplied by the pass itself
32
32
  * (the flat form values under validation) — callers provide the rest.
33
33
  */
34
- export type ResolverValidationContext = Omit<ShowIfContext, 'resolver'>;
34
+ export type ResolverValidationContext = Omit<ShowIfContext, 'resolver' | 'input'>;
35
35
  /**
36
36
  * Validate FLAT form values against the form schema. This is the dashboard's
37
37
  * entry point (the values the user edits, keyed by field name).
@@ -44,6 +44,7 @@ function validateResolverForm(schema, formValues, ctx) {
44
44
  const liveCtx = {
45
45
  ...(ctx ?? {}),
46
46
  resolver: formValues,
47
+ input: formValues,
47
48
  };
48
49
  const errors = [];
49
50
  for (const [field, fieldSchema] of Object.entries(properties)) {
@@ -1,5 +1,5 @@
1
- /** The token domains a help template may reference. */
2
- export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup"];
1
+ /** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
2
+ export declare const HELP_DOMAINS: readonly ["escalation", "metadata", "envelope", "payload", "resolver", "lookup", "input"];
3
3
  export type HelpDomain = (typeof HELP_DOMAINS)[number];
4
4
  export type HelpTokenContext = Partial<Record<HelpDomain, Record<string, unknown> | null>>;
5
5
  /** Replace every `{{domain.path}}` token with its value from the context. */
@@ -23,8 +23,8 @@ exports.defaultHelpMarkdown = defaultHelpMarkdown;
23
23
  * `x-lt-help` is absent.
24
24
  */
25
25
  const x_lt_bind_1 = require("./x-lt-bind");
26
- /** The token domains a help template may reference. */
27
- exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup'];
26
+ /** The token domains a help template may reference. `input` is the invoke-form name for the live values `resolver` also carries. */
27
+ exports.HELP_DOMAINS = ['escalation', 'metadata', 'envelope', 'payload', 'resolver', 'lookup', 'input'];
28
28
  const TOKEN_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
29
29
  const MISSING_VALUE = '—';
30
30
  function formatTokenValue(value) {
@@ -3,5 +3,6 @@ export type ShowIfContext = HelpTokenContext;
3
3
  /**
4
4
  * Evaluates an x-lt-showIf condition. Returns true when the field should be
5
5
  * shown. Returns true when condition is absent, non-string, or context is null.
6
+ * An array of conditions shows the field only when every one holds.
6
7
  */
7
8
  export declare function evaluateShowIf(condition: unknown, ctx: ShowIfContext | null | undefined): boolean;
@@ -54,8 +54,11 @@ function resolvePath(expr, ctx) {
54
54
  /**
55
55
  * Evaluates an x-lt-showIf condition. Returns true when the field should be
56
56
  * shown. Returns true when condition is absent, non-string, or context is null.
57
+ * An array of conditions shows the field only when every one holds.
57
58
  */
58
59
  function evaluateShowIf(condition, ctx) {
60
+ if (Array.isArray(condition))
61
+ return condition.every((c) => evaluateShowIf(c, ctx));
59
62
  if (typeof condition !== 'string' || condition.length === 0)
60
63
  return true;
61
64
  if (!ctx)
@@ -233,6 +233,8 @@ async function startWorkers(startConfig, workers, builtinMcpServerFactories) {
233
233
  consumes: c.consumes ?? [],
234
234
  tool_tags: c.toolTags ?? [],
235
235
  envelope_schema: c.envelopeSchema ?? null,
236
+ input_schema: c.inputSchema ?? null,
237
+ icon: c.icon ?? null,
236
238
  resolver_schema: c.resolverSchema ?? null,
237
239
  cron_schedule: c.cronSchedule ?? null,
238
240
  execute_as: c.executeAs ?? null,
@@ -84,14 +84,24 @@ function registerWorkflowTools(server) {
84
84
  }],
85
85
  };
86
86
  });
87
+ // The invoke input gate: data is validated against input_schema when declared.
88
+ const inputSchemaRejection = async (args) => {
89
+ const config = await configService.getWorkflowConfig(args.workflow_type);
90
+ const body = workflowApi.checkInvokeInput(config, args.data ?? {}, args.metadata);
91
+ return body ? { content: [{ type: 'text', text: JSON.stringify(body) }], isError: true } : null;
92
+ };
87
93
  // mirrors POST /api/workflows/:type/invoke
88
94
  server.registerTool('invoke_workflow', {
89
95
  title: 'Invoke Workflow',
90
96
  description: 'Start a certified workflow by type. The workflow must have invocable=true ' +
91
- 'in its config. Returns the workflow ID immediately; the workflow runs ' +
92
- 'durably in the background.',
97
+ 'in its config. Data is validated against the config input_schema when one ' +
98
+ 'is declared (422-shaped error). Returns the workflow ID immediately; the ' +
99
+ 'workflow runs durably in the background.',
93
100
  inputSchema: schemas_1.invokeWorkflowSchema,
94
101
  }, async (args) => {
102
+ const rejected = await inputSchemaRejection(args);
103
+ if (rejected)
104
+ return rejected;
95
105
  const result = await (0, workflow_invocation_1.invokeWorkflow)({
96
106
  workflowType: args.workflow_type,
97
107
  data: args.data,
@@ -139,6 +149,9 @@ function registerWorkflowTools(server) {
139
149
  isError: true,
140
150
  };
141
151
  }
152
+ const rejected = await inputSchemaRejection(args);
153
+ if (rejected)
154
+ return rejected;
142
155
  const result = await (0, workflow_invocation_1.invokeWorkflow)({
143
156
  workflowType: args.workflow_type,
144
157
  data: args.data,