@hotmeshio/long-tail 0.5.11 → 0.6.0

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 (350) hide show
  1. package/README.md +1 -0
  2. package/build/api/diagnostics.d.ts +5 -0
  3. package/build/api/diagnostics.js +5 -1
  4. package/build/api/escalations/bulk.js +9 -1
  5. package/build/api/escalations/cancel.js +5 -7
  6. package/build/api/escalations/claim.js +18 -15
  7. package/build/api/escalations/create.d.ts +6 -0
  8. package/build/api/escalations/create.js +11 -8
  9. package/build/api/escalations/facets.d.ts +18 -0
  10. package/build/api/escalations/facets.js +115 -0
  11. package/build/api/escalations/helpers.d.ts +70 -1
  12. package/build/api/escalations/helpers.js +101 -7
  13. package/build/api/escalations/index.d.ts +3 -2
  14. package/build/api/escalations/index.js +7 -1
  15. package/build/api/escalations/list.d.ts +23 -2
  16. package/build/api/escalations/list.js +111 -10
  17. package/build/api/escalations/metadata.js +22 -27
  18. package/build/api/escalations/resolve.d.ts +19 -1
  19. package/build/api/escalations/resolve.js +111 -26
  20. package/build/api/escalations/single.js +8 -8
  21. package/build/api/settings.d.ts +1 -1
  22. package/build/api/settings.js +3 -1
  23. package/build/api/users.d.ts +6 -0
  24. package/build/api/users.js +29 -1
  25. package/build/api/workflows/invocation.d.ts +6 -0
  26. package/build/api/workflows/invocation.js +6 -2
  27. package/build/bin/ltc.js +40 -0
  28. package/build/lib/cli/commands/escalations.d.ts +36 -0
  29. package/build/lib/cli/commands/escalations.js +98 -0
  30. package/build/lib/db/schemas/001_schema.sql +10 -5
  31. package/build/lib/db/schemas/012_lt_tasks_workflow_id_unique.sql +20 -0
  32. package/build/lib/db/schemas/013_role_scope.sql +37 -0
  33. package/build/modules/features.d.ts +19 -0
  34. package/build/modules/features.js +16 -0
  35. package/build/modules/version.d.ts +10 -5
  36. package/build/modules/version.js +27 -11
  37. package/build/routes/diagnostics.js +15 -2
  38. package/build/routes/escalations/facets.d.ts +7 -0
  39. package/build/routes/escalations/facets.js +81 -0
  40. package/build/routes/escalations/index.js +3 -0
  41. package/build/routes/escalations/list.js +48 -0
  42. package/build/routes/escalations/resolve.js +22 -4
  43. package/build/routes/users.js +9 -5
  44. package/build/routes/workflows/invocation.js +12 -4
  45. package/build/sdk/index.d.ts +35 -2
  46. package/build/sdk/index.js +7 -0
  47. package/build/services/diagnostics/index.d.ts +40 -6
  48. package/build/services/diagnostics/index.js +54 -5
  49. package/build/services/escalation/crud.d.ts +56 -6
  50. package/build/services/escalation/crud.js +102 -31
  51. package/build/services/escalation/facet-sql.d.ts +18 -0
  52. package/build/services/escalation/facet-sql.js +118 -0
  53. package/build/services/escalation/facets.d.ts +45 -0
  54. package/build/services/escalation/facets.js +218 -0
  55. package/build/services/escalation/index.d.ts +1 -0
  56. package/build/services/escalation/index.js +8 -1
  57. package/build/services/escalation/queries.d.ts +47 -0
  58. package/build/services/escalation/queries.js +185 -2
  59. package/build/services/escalation/sql.d.ts +15 -2
  60. package/build/services/escalation/sql.js +80 -3
  61. package/build/services/interceptor/activities/escalation.d.ts +2 -0
  62. package/build/services/interceptor/activities/escalation.js +1 -1
  63. package/build/services/interceptor/lifecycle.js +4 -0
  64. package/build/services/mcp/server-tools.js +10 -4
  65. package/build/services/orchestrator/condition.js +6 -2
  66. package/build/services/role/index.js +2 -3
  67. package/build/services/role/sql.d.ts +8 -0
  68. package/build/services/role/sql.js +17 -1
  69. package/build/services/task/crud.js +22 -14
  70. package/build/services/task/process.js +3 -21
  71. package/build/services/task/resolve.d.ts +5 -3
  72. package/build/services/task/resolve.js +9 -6
  73. package/build/services/task/sql.d.ts +30 -2
  74. package/build/services/task/sql.js +72 -2
  75. package/build/services/user/crud.d.ts +1 -0
  76. package/build/services/user/crud.js +29 -11
  77. package/build/services/user/index.d.ts +2 -1
  78. package/build/services/user/index.js +12 -1
  79. package/build/services/user/rbac.d.ts +18 -0
  80. package/build/services/user/rbac.js +27 -0
  81. package/build/services/user/roles.d.ts +7 -2
  82. package/build/services/user/roles.js +21 -5
  83. package/build/services/user/scope.d.ts +22 -0
  84. package/build/services/user/scope.js +50 -0
  85. package/build/services/user/seed-admin.js +34 -17
  86. package/build/services/user/sql.d.ts +18 -7
  87. package/build/services/user/sql.js +38 -13
  88. package/build/services/user/sso-provision.js +41 -24
  89. package/build/services/user/types.d.ts +9 -5
  90. package/build/start/adapters.js +3 -0
  91. package/build/system/mcp-servers/admin/diagnostics.d.ts +5 -4
  92. package/build/system/mcp-servers/admin/diagnostics.js +12 -10
  93. package/build/system/mcp-servers/admin/escalations.d.ts +6 -0
  94. package/build/system/mcp-servers/admin/escalations.js +247 -54
  95. package/build/system/mcp-servers/admin/index.js +3 -3
  96. package/build/system/mcp-servers/admin/schemas.d.ts +417 -3
  97. package/build/system/mcp-servers/admin/schemas.js +101 -5
  98. package/build/system/mcp-servers/admin/users.js +28 -2
  99. package/build/system/mcp-servers/admin/workflows.js +23 -12
  100. package/build/system/seed/tool-manifests-admin.d.ts +1324 -562
  101. package/build/system/seed/tool-manifests-admin.js +10 -2
  102. package/build/tsconfig.tsbuildinfo +1 -1
  103. package/build/types/envelope.d.ts +7 -0
  104. package/build/types/facets.d.ts +60 -0
  105. package/build/types/facets.js +10 -0
  106. package/build/types/index.d.ts +2 -1
  107. package/build/types/startup.d.ts +9 -0
  108. package/build/types/user.d.ts +11 -0
  109. package/dashboard/dist/assets/AdminDashboard-2CZ8py9X.js +2 -0
  110. package/dashboard/dist/assets/{AdminDashboard-DZpduYdW.js.map → AdminDashboard-2CZ8py9X.js.map} +1 -1
  111. package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js → AgentConfigPage-D68sodgo.js} +7 -7
  112. package/dashboard/dist/assets/{AgentConfigPage-SFnHMIP6.js.map → AgentConfigPage-D68sodgo.js.map} +1 -1
  113. package/dashboard/dist/assets/AgentDetailPage-BmhuWbKi.js +4 -0
  114. package/dashboard/dist/assets/AgentDetailPage-BmhuWbKi.js.map +1 -0
  115. package/dashboard/dist/assets/AgentsPage-C4SKQVeU.js +2 -0
  116. package/dashboard/dist/assets/AgentsPage-C4SKQVeU.js.map +1 -0
  117. package/dashboard/dist/assets/AvailableEscalationsPage-9RBEYwkt.js +2 -0
  118. package/dashboard/dist/assets/AvailableEscalationsPage-9RBEYwkt.js.map +1 -0
  119. package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js → BotPicker-D-FvXJOM.js} +2 -2
  120. package/dashboard/dist/assets/{BotPicker-Dse2jW4b.js.map → BotPicker-D-FvXJOM.js.map} +1 -1
  121. package/dashboard/dist/assets/CapabilitiesPage-ByDf6WJr.js +2 -0
  122. package/dashboard/dist/assets/{CapabilitiesPage-DTfKCzBQ.js.map → CapabilitiesPage-ByDf6WJr.js.map} +1 -1
  123. package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js → CollapsibleSection-BjGNYEvh.js} +2 -2
  124. package/dashboard/dist/assets/{CollapsibleSection-8vf38J6K.js.map → CollapsibleSection-BjGNYEvh.js.map} +1 -1
  125. package/dashboard/dist/assets/CopyableId-blg-gZvT.js +2 -0
  126. package/dashboard/dist/assets/CopyableId-blg-gZvT.js.map +1 -0
  127. package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js → CredentialsPage-DvCA-wQN.js} +2 -2
  128. package/dashboard/dist/assets/{CredentialsPage-7C4M-hrH.js.map → CredentialsPage-DvCA-wQN.js.map} +1 -1
  129. package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js → CronLabel-DBMurd_c.js} +2 -2
  130. package/dashboard/dist/assets/{CronLabel-DrGWtaSY.js.map → CronLabel-DBMurd_c.js.map} +1 -1
  131. package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js → CustomDurationPicker-DHflFoEa.js} +2 -2
  132. package/dashboard/dist/assets/{CustomDurationPicker-Vcmr4LiR.js.map → CustomDurationPicker-DHflFoEa.js.map} +1 -1
  133. package/dashboard/dist/assets/{DropZone-Dwpgbueb.js → DropZone-CUtdp99Z.js} +2 -2
  134. package/dashboard/dist/assets/{DropZone-Dwpgbueb.js.map → DropZone-CUtdp99Z.js.map} +1 -1
  135. package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js → ElapsedCell-CSjcVOpo.js} +2 -2
  136. package/dashboard/dist/assets/{ElapsedCell-BNexhR5d.js.map → ElapsedCell-CSjcVOpo.js.map} +1 -1
  137. package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js → EscalationsOverview-BUqRNJbK.js} +2 -2
  138. package/dashboard/dist/assets/{EscalationsOverview-BI3DEwYP.js.map → EscalationsOverview-BUqRNJbK.js.map} +1 -1
  139. package/dashboard/dist/assets/{EventTable-CwvX_L9t.js → EventTable-Chz-6XPE.js} +2 -2
  140. package/dashboard/dist/assets/{EventTable-CwvX_L9t.js.map → EventTable-Chz-6XPE.js.map} +1 -1
  141. package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js → GraphInvokePage-BXdgciWg.js} +2 -2
  142. package/dashboard/dist/assets/{GraphInvokePage-C-3b8WK0.js.map → GraphInvokePage-BXdgciWg.js.map} +1 -1
  143. package/dashboard/dist/assets/{HomePage-BS_-jcHr.js → HomePage-CEMxnk0r.js} +2 -2
  144. package/dashboard/dist/assets/{HomePage-BS_-jcHr.js.map → HomePage-CEMxnk0r.js.map} +1 -1
  145. package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js → ListToolbar-_73JCdbB.js} +2 -2
  146. package/dashboard/dist/assets/{ListToolbar-BH9rwQVE.js.map → ListToolbar-_73JCdbB.js.map} +1 -1
  147. package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js → McpOverview-DfdqxhSz.js} +2 -2
  148. package/dashboard/dist/assets/{McpOverview-C9iOdE7E.js.map → McpOverview-DfdqxhSz.js.map} +1 -1
  149. package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js → McpQueryDetailPage-DPAljieY.js} +2 -2
  150. package/dashboard/dist/assets/{McpQueryDetailPage-DMN-yqvJ.js.map → McpQueryDetailPage-DPAljieY.js.map} +1 -1
  151. package/dashboard/dist/assets/McpQueryPage-D5cSziYS.js +2 -0
  152. package/dashboard/dist/assets/McpQueryPage-D5cSziYS.js.map +1 -0
  153. package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js → McpRunDetailPage-DwNb9wZg.js} +2 -2
  154. package/dashboard/dist/assets/{McpRunDetailPage-Wb47sRvo.js.map → McpRunDetailPage-DwNb9wZg.js.map} +1 -1
  155. package/dashboard/dist/assets/McpRunsPage-O5H6yStl.js +2 -0
  156. package/dashboard/dist/assets/McpRunsPage-O5H6yStl.js.map +1 -0
  157. package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js → NamespacePill-uW-xOedj.js} +2 -2
  158. package/dashboard/dist/assets/{NamespacePill-DnJl4Lre.js.map → NamespacePill-uW-xOedj.js.map} +1 -1
  159. package/dashboard/dist/assets/OperatorDashboard-DYw9Ekv5.js +2 -0
  160. package/dashboard/dist/assets/OperatorDashboard-DYw9Ekv5.js.map +1 -0
  161. package/dashboard/dist/assets/PageHeader-DVOZjBfL.js +2 -0
  162. package/dashboard/dist/assets/PageHeader-DVOZjBfL.js.map +1 -0
  163. package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js → PageHeaderWithStats-DtTpDHOd.js} +2 -2
  164. package/dashboard/dist/assets/{PageHeaderWithStats-BuKc9MKt.js.map → PageHeaderWithStats-DtTpDHOd.js.map} +1 -1
  165. package/dashboard/dist/assets/PriorityBadge-B4ykBH7f.js +2 -0
  166. package/dashboard/dist/assets/PriorityBadge-B4ykBH7f.js.map +1 -0
  167. package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js → ProcessDetailPage-B0Dokcx9.js} +2 -2
  168. package/dashboard/dist/assets/{ProcessDetailPage-CvPx-h8y.js.map → ProcessDetailPage-B0Dokcx9.js.map} +1 -1
  169. package/dashboard/dist/assets/ProcessesListPage-Cc87WIjL.js +2 -0
  170. package/dashboard/dist/assets/ProcessesListPage-Cc87WIjL.js.map +1 -0
  171. package/dashboard/dist/assets/RolePill-BaW-30TC.js +2 -0
  172. package/dashboard/dist/assets/RolePill-BaW-30TC.js.map +1 -0
  173. package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js → RolesPage-cp6PiF08.js} +2 -2
  174. package/dashboard/dist/assets/{RolesPage-W5ZjOHpg.js.map → RolesPage-cp6PiF08.js.map} +1 -1
  175. package/dashboard/dist/assets/RowActions-BA9L9djf.js +2 -0
  176. package/dashboard/dist/assets/RowActions-BA9L9djf.js.map +1 -0
  177. package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js → RunAsSelector-2LWkjSnO.js} +2 -2
  178. package/dashboard/dist/assets/{RunAsSelector-CvxGTNGT.js.map → RunAsSelector-2LWkjSnO.js.map} +1 -1
  179. package/dashboard/dist/assets/{StickyPagination-BWhFSr2d.js → StickyPagination-BQEm--kI.js} +2 -2
  180. package/dashboard/dist/assets/{StickyPagination-BWhFSr2d.js.map → StickyPagination-BQEm--kI.js.map} +1 -1
  181. package/dashboard/dist/assets/StreamMessageDetail-BTtw3GjX.js +2 -0
  182. package/dashboard/dist/assets/{StreamMessageDetail-BF0tM0cd.js.map → StreamMessageDetail-BTtw3GjX.js.map} +1 -1
  183. package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js → SwimlaneTimeline-DdXxP4fO.js} +2 -2
  184. package/dashboard/dist/assets/{SwimlaneTimeline-Bv-KHY9s.js.map → SwimlaneTimeline-DdXxP4fO.js.map} +1 -1
  185. package/dashboard/dist/assets/{TagInput-B00uqhjX.js → TagInput-x9XTuqMb.js} +2 -2
  186. package/dashboard/dist/assets/{TagInput-B00uqhjX.js.map → TagInput-x9XTuqMb.js.map} +1 -1
  187. package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js → TaskDetailPage-B8veYG4X.js} +2 -2
  188. package/dashboard/dist/assets/{TaskDetailPage-Bzb_fuLy.js.map → TaskDetailPage-B8veYG4X.js.map} +1 -1
  189. package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js → TaskQueuePill-DSEQZ-HT.js} +2 -2
  190. package/dashboard/dist/assets/{TaskQueuePill-CUsofm0X.js.map → TaskQueuePill-DSEQZ-HT.js.map} +1 -1
  191. package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js → TasksListPage-CsN1gZj5.js} +2 -2
  192. package/dashboard/dist/assets/{TasksListPage-CBezWaZL.js.map → TasksListPage-CsN1gZj5.js.map} +1 -1
  193. package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js → TimeAgo-n182EcLx.js} +2 -2
  194. package/dashboard/dist/assets/{TimeAgo-CKHfTzat.js.map → TimeAgo-n182EcLx.js.map} +1 -1
  195. package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js → TimestampCell-2dlcQAfX.js} +2 -2
  196. package/dashboard/dist/assets/{TimestampCell-Dsje8GH-.js.map → TimestampCell-2dlcQAfX.js.map} +1 -1
  197. package/dashboard/dist/assets/{ToolPill-DjvedZSn.js → ToolPill-B_e4eT77.js} +2 -2
  198. package/dashboard/dist/assets/{ToolPill-DjvedZSn.js.map → ToolPill-B_e4eT77.js.map} +1 -1
  199. package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js → ToolTestPanel-Bhnncc6M.js} +2 -2
  200. package/dashboard/dist/assets/{ToolTestPanel-3OcG18e5.js.map → ToolTestPanel-Bhnncc6M.js.map} +1 -1
  201. package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js → TopicDetailPage-29lsNsqI.js} +3 -3
  202. package/dashboard/dist/assets/{TopicDetailPage-DCtv91hH.js.map → TopicDetailPage-29lsNsqI.js.map} +1 -1
  203. package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js → TopicsPage-KJ7_LAvo.js} +2 -2
  204. package/dashboard/dist/assets/{TopicsPage-DVGSNc_E.js.map → TopicsPage-KJ7_LAvo.js.map} +1 -1
  205. package/dashboard/dist/assets/{UserName-xHAgkk8M.js → UserName-CMoFi9zb.js} +2 -2
  206. package/dashboard/dist/assets/{UserName-xHAgkk8M.js.map → UserName-CMoFi9zb.js.map} +1 -1
  207. package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js → WorkflowExecutionPage-Cymfx-Bp.js} +2 -2
  208. package/dashboard/dist/assets/{WorkflowExecutionPage-CWNxsS8a.js.map → WorkflowExecutionPage-Cymfx-Bp.js.map} +1 -1
  209. package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js → WorkflowPill-B66_AnaY.js} +2 -2
  210. package/dashboard/dist/assets/{WorkflowPill-F1oKUzmc.js.map → WorkflowPill-B66_AnaY.js.map} +1 -1
  211. package/dashboard/dist/assets/WorkflowsDashboard-CqLN8spd.js +2 -0
  212. package/dashboard/dist/assets/WorkflowsDashboard-CqLN8spd.js.map +1 -0
  213. package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js → WorkflowsOverview-0Rc2WT6q.js} +2 -2
  214. package/dashboard/dist/assets/{WorkflowsOverview-e7jWSj_n.js.map → WorkflowsOverview-0Rc2WT6q.js.map} +1 -1
  215. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js → YamlWorkflowDetailPage-CARQ7_LN.js} +2 -2
  216. package/dashboard/dist/assets/{YamlWorkflowDetailPage-CdAeam76.js.map → YamlWorkflowDetailPage-CARQ7_LN.js.map} +1 -1
  217. package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js → YamlWorkflowsPage-B-7sz1nf.js} +2 -2
  218. package/dashboard/dist/assets/{YamlWorkflowsPage-S_gKs2Di.js.map → YamlWorkflowsPage-B-7sz1nf.js.map} +1 -1
  219. package/dashboard/dist/assets/{agents-JE4aL07D.js → agents-zM43d5Yf.js} +2 -2
  220. package/dashboard/dist/assets/{agents-JE4aL07D.js.map → agents-zM43d5Yf.js.map} +1 -1
  221. package/dashboard/dist/assets/api-path-u2Jf9QXS.js +2 -0
  222. package/dashboard/dist/assets/api-path-u2Jf9QXS.js.map +1 -0
  223. package/dashboard/dist/assets/{bots-cAzKkDtQ.js → bots-D5BasOGz.js} +2 -2
  224. package/dashboard/dist/assets/{bots-cAzKkDtQ.js.map → bots-D5BasOGz.js.map} +1 -1
  225. package/dashboard/dist/assets/{capabilities-RBFXLAXF.js → capabilities-BT3PW9CZ.js} +2 -2
  226. package/dashboard/dist/assets/{capabilities-RBFXLAXF.js.map → capabilities-BT3PW9CZ.js.map} +1 -1
  227. package/dashboard/dist/assets/{controlplane-DGhv3rwI.js → controlplane-NpJr49rN.js} +2 -2
  228. package/dashboard/dist/assets/{controlplane-DGhv3rwI.js.map → controlplane-NpJr49rN.js.map} +1 -1
  229. package/dashboard/dist/assets/{escalation-ne7dIaPa.js → escalation-DrzQolPG.js} +2 -2
  230. package/dashboard/dist/assets/{escalation-ne7dIaPa.js.map → escalation-DrzQolPG.js.map} +1 -1
  231. package/dashboard/dist/assets/escalation-columns-QzwmtD60.js +2 -0
  232. package/dashboard/dist/assets/escalation-columns-QzwmtD60.js.map +1 -0
  233. package/dashboard/dist/assets/index-B5w4Gjyk.js +6 -0
  234. package/dashboard/dist/assets/index-B5w4Gjyk.js.map +1 -0
  235. package/dashboard/dist/assets/{index-CByjpYlU.js → index-BCT4kqGR.js} +2 -2
  236. package/dashboard/dist/assets/{index-CByjpYlU.js.map → index-BCT4kqGR.js.map} +1 -1
  237. package/dashboard/dist/assets/{index-CgyucK0e.js → index-C69XvBfg.js} +2 -2
  238. package/dashboard/dist/assets/{index-CgyucK0e.js.map → index-C69XvBfg.js.map} +1 -1
  239. package/dashboard/dist/assets/index-CHw4Fl0t.css +1 -0
  240. package/dashboard/dist/assets/index-C_NwHTMh.js +2 -0
  241. package/dashboard/dist/assets/index-C_NwHTMh.js.map +1 -0
  242. package/dashboard/dist/assets/{index-DgzgRTNg.js → index-Cq0trGqf.js} +2 -2
  243. package/dashboard/dist/assets/{index-DgzgRTNg.js.map → index-Cq0trGqf.js.map} +1 -1
  244. package/dashboard/dist/assets/{index-DPJW96d2.js → index-DE0r9SEX.js} +26 -26
  245. package/dashboard/dist/assets/index-DE0r9SEX.js.map +1 -0
  246. package/dashboard/dist/assets/{index-BTqhAT6p.js → index-DH_CiD0W.js} +2 -2
  247. package/dashboard/dist/assets/{index-BTqhAT6p.js.map → index-DH_CiD0W.js.map} +1 -1
  248. package/dashboard/dist/assets/{index-C2l4GcZ7.js → index-K23FdS-T.js} +3 -3
  249. package/dashboard/dist/assets/{index-C2l4GcZ7.js.map → index-K23FdS-T.js.map} +1 -1
  250. package/dashboard/dist/assets/index-f6K1UNrn.js +2 -0
  251. package/dashboard/dist/assets/index-f6K1UNrn.js.map +1 -0
  252. package/dashboard/dist/assets/{index-BbJuC9kg.js → index-qr1fndqM.js} +2 -2
  253. package/dashboard/dist/assets/{index-BbJuC9kg.js.map → index-qr1fndqM.js.map} +1 -1
  254. package/dashboard/dist/assets/index-vKTvJ_li.js +2 -0
  255. package/dashboard/dist/assets/index-vKTvJ_li.js.map +1 -0
  256. package/dashboard/dist/assets/{index-CQDn-bLr.js → index-y-3ODtEE.js} +2 -2
  257. package/dashboard/dist/assets/{index-CQDn-bLr.js.map → index-y-3ODtEE.js.map} +1 -1
  258. package/dashboard/dist/assets/{index-QxAYCJ1S.js → index-y56Ds-LB.js} +2 -2
  259. package/dashboard/dist/assets/{index-QxAYCJ1S.js.map → index-y56Ds-LB.js.map} +1 -1
  260. package/dashboard/dist/assets/{knowledge-DzRpsm3D.js → knowledge-DSSATOTX.js} +2 -2
  261. package/dashboard/dist/assets/{knowledge-DzRpsm3D.js.map → knowledge-DSSATOTX.js.map} +1 -1
  262. package/dashboard/dist/assets/{mcp-B1lc6nL4.js → mcp-CfJFVo5k.js} +2 -2
  263. package/dashboard/dist/assets/{mcp-B1lc6nL4.js.map → mcp-CfJFVo5k.js.map} +1 -1
  264. package/dashboard/dist/assets/{mcp-query-CXuweaN3.js → mcp-query-DKVx2Q-X.js} +2 -2
  265. package/dashboard/dist/assets/{mcp-query-CXuweaN3.js.map → mcp-query-DKVx2Q-X.js.map} +1 -1
  266. package/dashboard/dist/assets/{pipelines-D4VLWDvu.js → pipelines-BSWzE-6M.js} +2 -2
  267. package/dashboard/dist/assets/{pipelines-D4VLWDvu.js.map → pipelines-BSWzE-6M.js.map} +1 -1
  268. package/dashboard/dist/assets/{roles-CSpHRRu8.js → roles-t9HzhI5N.js} +2 -2
  269. package/dashboard/dist/assets/{roles-CSpHRRu8.js.map → roles-t9HzhI5N.js.map} +1 -1
  270. package/dashboard/dist/assets/{tasks-CWUsKhM4.js → tasks-B7rUihoH.js} +2 -2
  271. package/dashboard/dist/assets/{tasks-CWUsKhM4.js.map → tasks-B7rUihoH.js.map} +1 -1
  272. package/dashboard/dist/assets/{topics-BXwstrzB.js → topics-PC2fEiyD.js} +2 -2
  273. package/dashboard/dist/assets/{topics-BXwstrzB.js.map → topics-PC2fEiyD.js.map} +1 -1
  274. package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js +2 -0
  275. package/dashboard/dist/assets/useDebouncedValue-BA5S7V54.js.map +1 -0
  276. package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js → useEventHooks-DK9mw1cI.js} +2 -2
  277. package/dashboard/dist/assets/{useEventHooks-CjygrbYy.js.map → useEventHooks-DK9mw1cI.js.map} +1 -1
  278. package/dashboard/dist/assets/{useNamespace-CsepDyR5.js → useNamespace-3IjtUtAw.js} +2 -2
  279. package/dashboard/dist/assets/{useNamespace-CsepDyR5.js.map → useNamespace-3IjtUtAw.js.map} +1 -1
  280. package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js → useYamlActivityEvents-uxukp3gO.js} +2 -2
  281. package/dashboard/dist/assets/{useYamlActivityEvents-gWIG6akB.js.map → useYamlActivityEvents-uxukp3gO.js.map} +1 -1
  282. package/dashboard/dist/assets/users-CC4B5Fm5.js +2 -0
  283. package/dashboard/dist/assets/users-CC4B5Fm5.js.map +1 -0
  284. package/dashboard/dist/assets/{vendor-icons-Dj2F0Jrb.js → vendor-icons-Dy5Jpknf.js} +114 -109
  285. package/dashboard/dist/assets/vendor-icons-Dy5Jpknf.js.map +1 -0
  286. package/dashboard/dist/assets/{workflows-C7Cam2Ok.js → workflows-S7MF1nNk.js} +2 -2
  287. package/dashboard/dist/assets/{workflows-C7Cam2Ok.js.map → workflows-S7MF1nNk.js.map} +1 -1
  288. package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js → yaml-workflows-WfdaMHNn.js} +2 -2
  289. package/dashboard/dist/assets/{yaml-workflows-ChUOE22W.js.map → yaml-workflows-WfdaMHNn.js.map} +1 -1
  290. package/dashboard/dist/index.html +3 -3
  291. package/docs/api/http/escalations.md +131 -10
  292. package/docs/api/http/roles.md +44 -9
  293. package/docs/api/http/users.md +15 -6
  294. package/docs/api/mcp/admin.md +164 -14
  295. package/docs/api/mcp/human-queue.md +34 -2
  296. package/docs/api/sdk/escalations.md +155 -2
  297. package/docs/api/sdk/roles.md +11 -0
  298. package/docs/api/sdk/users.md +26 -1
  299. package/docs/auth.md +1 -1
  300. package/docs/dashboard.md +5 -4
  301. package/docs/data.md +9 -2
  302. package/docs/faceted-routing.md +221 -0
  303. package/docs/hitl-guide.md +50 -0
  304. package/docs/iam.md +31 -0
  305. package/docs/mcp.md +8 -0
  306. package/package.json +2 -2
  307. package/dashboard/dist/assets/AdminDashboard-DZpduYdW.js +0 -2
  308. package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js +0 -4
  309. package/dashboard/dist/assets/AgentDetailPage-C-2iSaDs.js.map +0 -1
  310. package/dashboard/dist/assets/AgentsPage-C3FztFd_.js +0 -2
  311. package/dashboard/dist/assets/AgentsPage-C3FztFd_.js.map +0 -1
  312. package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js +0 -2
  313. package/dashboard/dist/assets/AvailableEscalationsPage-DIqdBCwe.js.map +0 -1
  314. package/dashboard/dist/assets/CapabilitiesPage-DTfKCzBQ.js +0 -2
  315. package/dashboard/dist/assets/CopyableId-DaT0ZRHg.js +0 -2
  316. package/dashboard/dist/assets/CopyableId-DaT0ZRHg.js.map +0 -1
  317. package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js +0 -2
  318. package/dashboard/dist/assets/McpQueryPage-Db1LUKVs.js.map +0 -1
  319. package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js +0 -2
  320. package/dashboard/dist/assets/McpRunsPage--tgT5uo7.js.map +0 -1
  321. package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js +0 -2
  322. package/dashboard/dist/assets/OperatorDashboard-BWVUbJkZ.js.map +0 -1
  323. package/dashboard/dist/assets/PageHeader-Bnt2iQQa.js +0 -2
  324. package/dashboard/dist/assets/PageHeader-Bnt2iQQa.js.map +0 -1
  325. package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js +0 -2
  326. package/dashboard/dist/assets/PriorityBadge-DfQY9St9.js.map +0 -1
  327. package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js +0 -2
  328. package/dashboard/dist/assets/ProcessesListPage-CWiRM_h3.js.map +0 -1
  329. package/dashboard/dist/assets/RolePill-DQTT1s9v.js +0 -2
  330. package/dashboard/dist/assets/RolePill-DQTT1s9v.js.map +0 -1
  331. package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js +0 -2
  332. package/dashboard/dist/assets/RowActions-Dg-Fsm5O.js.map +0 -1
  333. package/dashboard/dist/assets/StreamMessageDetail-BF0tM0cd.js +0 -2
  334. package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js +0 -2
  335. package/dashboard/dist/assets/WorkflowsDashboard-M13lIaw7.js.map +0 -1
  336. package/dashboard/dist/assets/escalation-columns-DqTkKbCv.js +0 -2
  337. package/dashboard/dist/assets/escalation-columns-DqTkKbCv.js.map +0 -1
  338. package/dashboard/dist/assets/index-CEpw_Fh8.js +0 -2
  339. package/dashboard/dist/assets/index-CEpw_Fh8.js.map +0 -1
  340. package/dashboard/dist/assets/index-ClvYSNZd.css +0 -1
  341. package/dashboard/dist/assets/index-CucXk58o.js +0 -6
  342. package/dashboard/dist/assets/index-CucXk58o.js.map +0 -1
  343. package/dashboard/dist/assets/index-DPJW96d2.js.map +0 -1
  344. package/dashboard/dist/assets/index-DeZhNCf5.js +0 -2
  345. package/dashboard/dist/assets/index-DeZhNCf5.js.map +0 -1
  346. package/dashboard/dist/assets/index-Do8Xp3pa.js +0 -2
  347. package/dashboard/dist/assets/index-Do8Xp3pa.js.map +0 -1
  348. package/dashboard/dist/assets/users-DvhHbR0R.js +0 -2
  349. package/dashboard/dist/assets/users-DvhHbR0R.js.map +0 -1
  350. package/dashboard/dist/assets/vendor-icons-Dj2F0Jrb.js.map +0 -1
@@ -6,6 +6,7 @@ import type { LTRoleType } from '../types';
6
6
  * @param input.role — filter by role name
7
7
  * @param input.roleType — filter by role type (superadmin, admin, member)
8
8
  * @param input.status — filter by user status
9
+ * @param input.search — free-text match on display name, email, or external_id
9
10
  * @param input.limit — maximum number of users to return
10
11
  * @param input.offset — number of users to skip for pagination
11
12
  * @returns `{ status: 200, data: User[] }` on success
@@ -14,6 +15,7 @@ export declare function listUsers(input: {
14
15
  role?: string;
15
16
  roleType?: LTRoleType;
16
17
  status?: string;
18
+ search?: string;
17
19
  limit?: number;
18
20
  offset?: number;
19
21
  }): Promise<LTApiResult>;
@@ -47,6 +49,8 @@ export declare function createUser(input: {
47
49
  roles?: {
48
50
  role: string;
49
51
  type: string;
52
+ read_scope?: string;
53
+ write_scope?: string;
50
54
  }[];
51
55
  metadata?: Record<string, any>;
52
56
  }): Promise<LTApiResult>;
@@ -103,6 +107,8 @@ export declare function addUserRole(input: {
103
107
  id: string;
104
108
  role: string;
105
109
  type: string;
110
+ read_scope?: string;
111
+ write_scope?: string;
106
112
  }): Promise<LTApiResult>;
107
113
  /**
108
114
  * Remove a role from a user. Requires admin privileges.
@@ -48,6 +48,7 @@ const userService = __importStar(require("../services/user"));
48
48
  * @param input.role — filter by role name
49
49
  * @param input.roleType — filter by role type (superadmin, admin, member)
50
50
  * @param input.status — filter by user status
51
+ * @param input.search — free-text match on display name, email, or external_id
51
52
  * @param input.limit — maximum number of users to return
52
53
  * @param input.offset — number of users to skip for pagination
53
54
  * @returns `{ status: 200, data: User[] }` on success
@@ -105,6 +106,17 @@ async function createUser(input) {
105
106
  error: 'Each role must have a role name and type (superadmin, admin, member)',
106
107
  };
107
108
  }
109
+ if (r.read_scope !== undefined && !userService.isValidReadScope(r.read_scope)) {
110
+ return { status: 400, error: 'read_scope must be self or all' };
111
+ }
112
+ if (r.write_scope !== undefined && !userService.isValidWriteScope(r.write_scope)) {
113
+ return { status: 400, error: 'write_scope must be none, self, or all' };
114
+ }
115
+ const read = (r.read_scope ?? userService.DEFAULT_READ_SCOPE);
116
+ const write = (r.write_scope ?? userService.DEFAULT_WRITE_SCOPE);
117
+ if (!userService.isValidScopePair(read, write)) {
118
+ return { status: 400, error: 'write_scope=all requires read_scope=all' };
119
+ }
108
120
  }
109
121
  }
110
122
  const user = await userService.createUser({
@@ -201,7 +213,23 @@ async function addUserRole(input) {
201
213
  if (!userService.isValidRoleType(input.type)) {
202
214
  return { status: 400, error: 'type must be superadmin, admin, or member' };
203
215
  }
204
- const result = await userService.addUserRole(input.id, input.role, input.type);
216
+ // Work-surface scope (optional; defaults to all/all = full worker). Only
217
+ // meaningful for `member`; admin/superadmin normalize to all/all.
218
+ if (input.read_scope !== undefined && !userService.isValidReadScope(input.read_scope)) {
219
+ return { status: 400, error: 'read_scope must be self or all' };
220
+ }
221
+ if (input.write_scope !== undefined && !userService.isValidWriteScope(input.write_scope)) {
222
+ return { status: 400, error: 'write_scope must be none, self, or all' };
223
+ }
224
+ const read = (input.read_scope ?? userService.DEFAULT_READ_SCOPE);
225
+ const write = (input.write_scope ?? userService.DEFAULT_WRITE_SCOPE);
226
+ if (!userService.isValidScopePair(read, write)) {
227
+ return { status: 400, error: 'write_scope=all requires read_scope=all (cannot act on what you cannot see)' };
228
+ }
229
+ const result = await userService.addUserRole(input.id, input.role, input.type, {
230
+ read_scope: read,
231
+ write_scope: write,
232
+ });
205
233
  return { status: 201, data: result };
206
234
  }
207
235
  catch (err) {
@@ -23,12 +23,16 @@ export declare function invokeWorkflow(input: {
23
23
  *
24
24
  * Returns the HotMesh status code (0 = completed, 1 = running).
25
25
  * Resolves the workflow handle via task record or worker registry.
26
+ * `appId` selects the namespace for the job-entity fallback so a child
27
+ * running in another app resolves instead of 404ing against `durable`.
26
28
  *
27
29
  * @param input.workflowId — HotMesh workflow ID
30
+ * @param input.appId — HotMesh namespace for resolution (default: durable)
28
31
  * @returns `{ status: 200, data: { workflowId, status } }` or 404
29
32
  */
30
33
  export declare function getWorkflowStatus(input: {
31
34
  workflowId: string;
35
+ appId?: string;
32
36
  }): Promise<LTApiResult>;
33
37
  /**
34
38
  * Get the result of a completed workflow.
@@ -37,10 +41,12 @@ export declare function getWorkflowStatus(input: {
37
41
  * payload when complete. Never blocks — always returns immediately.
38
42
  *
39
43
  * @param input.workflowId — HotMesh workflow ID
44
+ * @param input.appId — HotMesh namespace for resolution (default: durable)
40
45
  * @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
41
46
  */
42
47
  export declare function getWorkflowResult(input: {
43
48
  workflowId: string;
49
+ appId?: string;
44
50
  }): Promise<LTApiResult>;
45
51
  /**
46
52
  * Terminate a running workflow.
@@ -87,13 +87,16 @@ async function invokeWorkflow(input, auth) {
87
87
  *
88
88
  * Returns the HotMesh status code (0 = completed, 1 = running).
89
89
  * Resolves the workflow handle via task record or worker registry.
90
+ * `appId` selects the namespace for the job-entity fallback so a child
91
+ * running in another app resolves instead of 404ing against `durable`.
90
92
  *
91
93
  * @param input.workflowId — HotMesh workflow ID
94
+ * @param input.appId — HotMesh namespace for resolution (default: durable)
92
95
  * @returns `{ status: 200, data: { workflowId, status } }` or 404
93
96
  */
94
97
  async function getWorkflowStatus(input) {
95
98
  try {
96
- const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
99
+ const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
97
100
  const client = (0, workers_1.createClient)();
98
101
  const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
99
102
  const status = await handle.status();
@@ -115,11 +118,12 @@ async function getWorkflowStatus(input) {
115
118
  * payload when complete. Never blocks — always returns immediately.
116
119
  *
117
120
  * @param input.workflowId — HotMesh workflow ID
121
+ * @param input.appId — HotMesh namespace for resolution (default: durable)
118
122
  * @returns `{ status: 200, data: { workflowId, result } }` or 202 if running
119
123
  */
120
124
  async function getWorkflowResult(input) {
121
125
  try {
122
- const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId);
126
+ const resolved = await (0, task_1.resolveWorkflowHandle)(input.workflowId, input.appId);
123
127
  const client = (0, workers_1.createClient)();
124
128
  const handle = await client.workflow.getHandle(resolved.taskQueue, resolved.workflowName, input.workflowId);
125
129
  const status = await handle.status();
package/build/bin/ltc.js CHANGED
@@ -120,6 +120,13 @@ escCmd.command('list')
120
120
  .option('--status <status>', 'Filter by status (pending, resolved, cancelled)')
121
121
  .option('--role <role>', 'Filter by role')
122
122
  .option('--limit <n>', 'Max results')
123
+ .option('--facets <json>', 'Required metadata facets, JSON object (metadata @>), e.g. \'{"filament":"pla"}\'')
124
+ .option('--block <json>', 'Exclude rows containing ANY of these facet sets, JSON array')
125
+ .option('--range <json>', 'Numeric ranges over facets, JSON array e.g. \'[{"facet":"confidence","op":"<=","value":0.7}]\'')
126
+ .option('--exists <json>', 'Metadata keys that must be present, JSON array of strings')
127
+ .option('--roles <json>', 'Restrict to these roles, JSON array (narrows within scope)')
128
+ .option('--available <bool>', 'true = unclaimed/expired only; false = held now')
129
+ .option('--order-by <json>', 'Sort keys, JSON array e.g. \'[{"field":"metadata.confidence","numeric":true,"direction":"asc"}]\'')
123
130
  .option('--json', 'JSON output')
124
131
  .option('-q, --quiet', 'IDs only')
125
132
  .action(wrap(esc.listEscalations));
@@ -153,6 +160,39 @@ escCmd.command('resolve-by-meta <key> <value>')
153
160
  .option('--assignee <external_id>', 'Resolve on behalf of user (external_id)')
154
161
  .option('--meta <json>', 'Merge metadata (JSON object)')
155
162
  .action(wrap(esc.resolveByMetadata));
163
+ escCmd.command('resolve-by-ids <ids...>')
164
+ .description('Resolve a set of escalations by id')
165
+ .requiredOption('--payload <json>', 'Resolver payload (JSON string)')
166
+ .option('--metadata <json>', 'Merge metadata (JSON object)')
167
+ .action(wrap(esc.resolveByIds));
168
+ escCmd.command('search-facets')
169
+ .description('Item-level faceted search over a pond (role-scoped)')
170
+ .requiredOption('--role <role>', 'Pond role to search')
171
+ .option('--status <status>', 'Filter by status')
172
+ .option('--available', 'Only available (unclaimed/expired)')
173
+ .option('--facets <json>', 'Required facets (JSON object)')
174
+ .option('--limit <n>', 'Max results')
175
+ .option('--json', 'JSON output')
176
+ .option('-q, --quiet', 'IDs only')
177
+ .action(wrap(esc.searchByFacets));
178
+ escCmd.command('claim-groups')
179
+ .description('Batch-claim complete origin groups in priority order')
180
+ .requiredOption('--role <role>', 'Pond role to claim from')
181
+ .option('--facets <json>', 'Required facets (JSON object)')
182
+ .option('--limit <n>', 'Max groups to claim')
183
+ .option('--duration <minutes>', 'Claim duration in minutes')
184
+ .option('--size-facet <key>', 'Metadata facet declaring group size')
185
+ .option('--json', 'JSON output')
186
+ .action(wrap(esc.claimGroups));
187
+ escCmd.command('claim-by-facets')
188
+ .description('Batch-claim individual rows matching facets')
189
+ .requiredOption('--role <role>', 'Pond role to claim from')
190
+ .option('--facets <json>', 'Required facets (JSON object)')
191
+ .option('--limit <n>', 'Max rows to claim')
192
+ .option('--duration <minutes>', 'Claim duration in minutes')
193
+ .option('--all-or-none', 'Claim all matched rows or none')
194
+ .option('--json', 'JSON output')
195
+ .action(wrap(esc.claimByFacets));
156
196
  // ── Workflows ────────────────────────────────────────────────────────────
157
197
  const wfCmd = commander_1.program.command('workflows').alias('wf').description('Manage durable workflows');
158
198
  wfCmd.command('list')
@@ -4,6 +4,13 @@ interface ListOptions {
4
4
  limit?: string;
5
5
  json?: boolean;
6
6
  quiet?: boolean;
7
+ facets?: string;
8
+ block?: string;
9
+ range?: string;
10
+ exists?: string;
11
+ roles?: string;
12
+ available?: string;
13
+ orderBy?: string;
7
14
  }
8
15
  export declare function listEscalations(opts: ListOptions): Promise<void>;
9
16
  export declare function getEscalation(id: string, opts: {
@@ -27,4 +34,33 @@ export declare function resolveByMetadata(key: string, value: string, opts: {
27
34
  assignee?: string;
28
35
  meta?: string;
29
36
  }): Promise<void>;
37
+ export declare function resolveByIds(ids: string[], opts: {
38
+ payload: string;
39
+ metadata?: string;
40
+ }): Promise<void>;
41
+ export declare function searchByFacets(opts: {
42
+ role: string;
43
+ status?: string;
44
+ available?: boolean;
45
+ facets?: string;
46
+ limit?: string;
47
+ json?: boolean;
48
+ quiet?: boolean;
49
+ }): Promise<void>;
50
+ export declare function claimGroups(opts: {
51
+ role: string;
52
+ facets?: string;
53
+ limit?: string;
54
+ duration?: string;
55
+ sizeFacet?: string;
56
+ json?: boolean;
57
+ }): Promise<void>;
58
+ export declare function claimByFacets(opts: {
59
+ role: string;
60
+ facets?: string;
61
+ limit?: string;
62
+ duration?: string;
63
+ allOrNone?: boolean;
64
+ json?: boolean;
65
+ }): Promise<void>;
30
66
  export {};
@@ -11,6 +11,10 @@ exports.resolveEscalation = resolveEscalation;
11
11
  exports.findByMetadata = findByMetadata;
12
12
  exports.claimByMetadata = claimByMetadata;
13
13
  exports.resolveByMetadata = resolveByMetadata;
14
+ exports.resolveByIds = resolveByIds;
15
+ exports.searchByFacets = searchByFacets;
16
+ exports.claimGroups = claimGroups;
17
+ exports.claimByFacets = claimByFacets;
14
18
  const picocolors_1 = __importDefault(require("picocolors"));
15
19
  const client_1 = require("../client");
16
20
  const format_1 = require("../format");
@@ -30,6 +34,22 @@ async function listEscalations(opts) {
30
34
  params.set('role', opts.role);
31
35
  if (opts.limit)
32
36
  params.set('limit', opts.limit);
37
+ // Faceted query elements travel as JSON-encoded query params (the route JSON-parses
38
+ // them). parseJsonOption validates the input and throws a friendly error on bad JSON.
39
+ if (opts.facets)
40
+ params.set('facets', JSON.stringify(parseJsonOption('--facets', opts.facets)));
41
+ if (opts.block)
42
+ params.set('block', JSON.stringify(parseJsonOption('--block', opts.block)));
43
+ if (opts.range)
44
+ params.set('range', JSON.stringify(parseJsonOption('--range', opts.range)));
45
+ if (opts.exists)
46
+ params.set('exists', JSON.stringify(parseJsonOption('--exists', opts.exists)));
47
+ if (opts.roles)
48
+ params.set('roles', JSON.stringify(parseJsonOption('--roles', opts.roles)));
49
+ if (opts.orderBy)
50
+ params.set('orderBy', JSON.stringify(parseJsonOption('--order-by', opts.orderBy)));
51
+ if (opts.available != null)
52
+ params.set('available', opts.available);
33
53
  const data = await (0, client_1.apiFetch)(`/escalations?${params}`);
34
54
  (0, format_1.output)(data, data.escalations || [], COLUMNS, opts);
35
55
  }
@@ -107,3 +127,81 @@ async function resolveByMetadata(key, value, opts) {
107
127
  });
108
128
  console.log(`\n ${picocolors_1.default.green('✓')} Resolved by ${key}=${value}\n`);
109
129
  }
130
+ // --- Faceted routing commands -----------------------------------------------
131
+ function parseJsonOption(label, raw) {
132
+ try {
133
+ return JSON.parse(raw);
134
+ }
135
+ catch {
136
+ throw new Error(`Invalid JSON for ${label}: ${raw}`);
137
+ }
138
+ }
139
+ async function resolveByIds(ids, opts) {
140
+ const resolverPayload = parseJsonOption('--payload', opts.payload);
141
+ const body = { ids, resolverPayload };
142
+ if (opts.metadata)
143
+ body.metadata = parseJsonOption('--metadata', opts.metadata);
144
+ const data = await (0, client_1.apiFetch)('/escalations/resolve-by-ids', {
145
+ method: 'POST',
146
+ body: JSON.stringify(body),
147
+ });
148
+ console.log(`\n ${picocolors_1.default.green('✓')} Resolved ${data.resolved} escalation(s)\n`);
149
+ }
150
+ async function searchByFacets(opts) {
151
+ const query = { role: opts.role };
152
+ if (opts.status)
153
+ query.status = opts.status;
154
+ if (opts.available)
155
+ query.available = true;
156
+ if (opts.facets)
157
+ query.facets = parseJsonOption('--facets', opts.facets);
158
+ if (opts.limit)
159
+ query.limit = parseInt(opts.limit, 10);
160
+ const data = await (0, client_1.apiFetch)('/escalations/search-by-facets', {
161
+ method: 'POST',
162
+ body: JSON.stringify(query),
163
+ });
164
+ (0, format_1.output)(data, data.escalations || [], COLUMNS, opts);
165
+ }
166
+ async function claimGroups(opts) {
167
+ const query = { role: opts.role };
168
+ if (opts.facets)
169
+ query.facets = parseJsonOption('--facets', opts.facets);
170
+ const body = { query };
171
+ if (opts.limit)
172
+ body.limit = parseInt(opts.limit, 10);
173
+ if (opts.duration)
174
+ body.durationMinutes = parseInt(opts.duration, 10);
175
+ if (opts.sizeFacet)
176
+ body.sizeFacet = opts.sizeFacet;
177
+ const data = await (0, client_1.apiFetch)('/escalations/claim-groups', {
178
+ method: 'POST',
179
+ body: JSON.stringify(body),
180
+ });
181
+ if (opts.json) {
182
+ console.log(JSON.stringify(data, null, 2));
183
+ return;
184
+ }
185
+ console.log(`\n ${picocolors_1.default.green('✓')} Claimed ${data.groups?.length || 0} group(s)\n`);
186
+ }
187
+ async function claimByFacets(opts) {
188
+ const query = { role: opts.role };
189
+ if (opts.facets)
190
+ query.facets = parseJsonOption('--facets', opts.facets);
191
+ const body = { query };
192
+ if (opts.limit)
193
+ body.limit = parseInt(opts.limit, 10);
194
+ if (opts.duration)
195
+ body.durationMinutes = parseInt(opts.duration, 10);
196
+ if (opts.allOrNone)
197
+ body.allOrNone = true;
198
+ const data = await (0, client_1.apiFetch)('/escalations/claim-by-facets', {
199
+ method: 'POST',
200
+ body: JSON.stringify(body),
201
+ });
202
+ if (opts.json) {
203
+ console.log(JSON.stringify(data, null, 2));
204
+ return;
205
+ }
206
+ console.log(`\n ${picocolors_1.default.green('✓')} Claimed ${data.claimed?.length || 0} escalation(s)\n`);
207
+ }
@@ -99,11 +99,16 @@ CREATE OR REPLACE TRIGGER lt_users_updated_at
99
99
  -- ─── lt_user_roles ───────────────────────────────────────────────────────────
100
100
 
101
101
  CREATE TABLE IF NOT EXISTS lt_user_roles (
102
- user_id UUID NOT NULL REFERENCES lt_users(id) ON DELETE CASCADE,
103
- role TEXT NOT NULL REFERENCES lt_roles(role),
104
- type TEXT NOT NULL DEFAULT 'member' CHECK (type IN ('superadmin', 'admin', 'member')),
105
- created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
106
- PRIMARY KEY (user_id, role)
102
+ user_id UUID NOT NULL REFERENCES lt_users(id) ON DELETE CASCADE,
103
+ role TEXT NOT NULL REFERENCES lt_roles(role),
104
+ type TEXT NOT NULL DEFAULT 'member' CHECK (type IN ('superadmin', 'admin', 'member')),
105
+ -- Work-surface scope (orthogonal to `type`, ignored for admin/superadmin).
106
+ -- read governs search, write governs claim/ack/delete. write ⊆ read.
107
+ read_scope TEXT NOT NULL DEFAULT 'all' CHECK (read_scope IN ('self', 'all')),
108
+ write_scope TEXT NOT NULL DEFAULT 'all' CHECK (write_scope IN ('none', 'self', 'all')),
109
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
110
+ PRIMARY KEY (user_id, role),
111
+ CONSTRAINT chk_lt_user_roles_scope CHECK (NOT (write_scope = 'all' AND read_scope = 'self'))
107
112
  );
108
113
 
109
114
  CREATE INDEX IF NOT EXISTS idx_lt_user_roles_type ON lt_user_roles (type);
@@ -0,0 +1,20 @@
1
+ -- ─── 012: lt_tasks.workflow_id uniqueness ─────────────────────────────────────
2
+ -- A task is 1:1 with its workflow_id. Every createTask caller keys the row by a
3
+ -- deterministic workflow_id (orchestrator childWorkflowId, interceptor
4
+ -- wf.workflowId, escalation triage-<id>), and createTask runs inside a
5
+ -- proxyActivity with retry { maximumAttempts: 3 }. Without a unique constraint a
6
+ -- retry — or a re-driven triage saga — double-inserts a task row. The unique
7
+ -- index lets createTask use ON CONFLICT (workflow_id) so retries converge instead
8
+ -- of duplicating, matching how HotMesh upserts the sibling job by (workflowId, app_id).
9
+
10
+ -- Collapse any pre-existing duplicates, keeping the most recent row per workflow_id
11
+ -- (tie-break on id so exactly one survives and the unique index can be built).
12
+ DELETE FROM lt_tasks a
13
+ USING lt_tasks b
14
+ WHERE a.workflow_id = b.workflow_id
15
+ AND (a.created_at < b.created_at
16
+ OR (a.created_at = b.created_at AND a.id < b.id));
17
+
18
+ -- Replace the non-unique lookup index with a unique one (it still serves lookups).
19
+ DROP INDEX IF EXISTS idx_lt_tasks_workflow_id;
20
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_lt_tasks_workflow_id ON lt_tasks (workflow_id);
@@ -0,0 +1,37 @@
1
+ -- ─── lt_user_roles: read/write work-surface scope ──────────────────────────
2
+ --
3
+ -- Open roles split the worker capability into two orthogonal axes so that
4
+ -- one-time and limited-surface users are first-class:
5
+ --
6
+ -- read_scope (self | all) → governs SEARCH (which items appear)
7
+ -- write_scope (none | self | all) → governs CLAIM / ACK / DELETE
8
+ --
9
+ -- `self` = escalations assigned to the user (assigned_to = userId); `all` = the
10
+ -- whole role queue. The only constraint is write ⊆ read (you cannot act on what
11
+ -- you cannot see). `type` (member/admin/superadmin) is unchanged — it remains the
12
+ -- management/global tier, and admin/superadmin ignore scope (always act on all).
13
+ --
14
+ -- Existing rows default to ('all','all') = today's `member` behavior, so this is
15
+ -- backward compatible with zero data backfill. Idempotent: no-op on fresh installs
16
+ -- where 001_schema.sql already created the columns and the named constraint.
17
+
18
+ ALTER TABLE lt_user_roles
19
+ ADD COLUMN IF NOT EXISTS read_scope TEXT NOT NULL DEFAULT 'all'
20
+ CHECK (read_scope IN ('self', 'all'));
21
+
22
+ ALTER TABLE lt_user_roles
23
+ ADD COLUMN IF NOT EXISTS write_scope TEXT NOT NULL DEFAULT 'all'
24
+ CHECK (write_scope IN ('none', 'self', 'all'));
25
+
26
+ -- write ⊆ read: cannot act on the whole queue while only reading your own.
27
+ -- Guarded so a re-run (or a fresh install where 001 already added it) is a no-op.
28
+ DO $$
29
+ BEGIN
30
+ IF NOT EXISTS (
31
+ SELECT 1 FROM pg_constraint WHERE conname = 'chk_lt_user_roles_scope'
32
+ ) THEN
33
+ ALTER TABLE lt_user_roles
34
+ ADD CONSTRAINT chk_lt_user_roles_scope
35
+ CHECK (NOT (write_scope = 'all' AND read_scope = 'self'));
36
+ END IF;
37
+ END $$;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Runtime feature flags surfaced to the dashboard via /api/settings.
3
+ *
4
+ * These gate UI affordances (nav entries, routes) that some deployments want to
5
+ * hide. Defaults are permissive (everything on); a deployment opts OUT through
6
+ * the `features` block of the `start()` config. The dashboard reads the resolved
7
+ * flags from `settings.features` and hides the corresponding nav item + route.
8
+ */
9
+ export interface FeatureFlags {
10
+ /**
11
+ * Show the DB Maintenance admin page (nav entry + route).
12
+ * Default: true. Set `features.dbMaintenance: false` in start config to hide it.
13
+ */
14
+ dbMaintenance: boolean;
15
+ }
16
+ /** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
17
+ export declare function configureFeatureFlags(patch?: Partial<FeatureFlags>): void;
18
+ /** The resolved feature flags reported to the dashboard. */
19
+ export declare function getFeatureFlags(): FeatureFlags;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureFeatureFlags = configureFeatureFlags;
4
+ exports.getFeatureFlags = getFeatureFlags;
5
+ const DEFAULT_FLAGS = {
6
+ dbMaintenance: true,
7
+ };
8
+ let flags = { ...DEFAULT_FLAGS };
9
+ /** Merge a partial set of flags from the start config. Unspecified flags keep their default. */
10
+ function configureFeatureFlags(patch) {
11
+ flags = { ...DEFAULT_FLAGS, ...(patch ?? {}) };
12
+ }
13
+ /** The resolved feature flags reported to the dashboard. */
14
+ function getFeatureFlags() {
15
+ return { ...flags };
16
+ }
@@ -7,10 +7,15 @@
7
7
  */
8
8
  export declare const HOTMESH_VERSION: string;
9
9
  /**
10
- * The long-tail app version. Read from the root package.json at runtime via the
11
- * process working directory (which is the app root in both dev and the Docker
12
- * image, where CMD runs `node build/index.js` from /app). A static
13
- * `../package.json` import would resolve to build/package.json after compile
14
- * a path the Dockerfile does not copy so this reads from cwd instead.
10
+ * The long-tail package version.
11
+ *
12
+ * Resolved from long-tail's OWN package.json by walking up from this module's
13
+ * directory to the first package.json named `@hotmeshio/long-tail`. Reading
14
+ * `process.cwd()/package.json` is wrong when long-tail is consumed as a
15
+ * dependency (e.g. mounted as a NestJS module) — cwd is then the HOST app's
16
+ * root, so it reported the host's version. The upward walk resolves correctly in
17
+ * dev (source tree), the standalone Docker image (`/app`), and under
18
+ * `node_modules/@hotmeshio/long-tail`. A static `../package.json` import can't be
19
+ * used: post-compile it resolves to `build/package.json`, which is not shipped.
15
20
  */
16
21
  export declare const LONG_TAIL_VERSION: string;
@@ -15,20 +15,36 @@ const package_json_1 = __importDefault(require("@hotmeshio/hotmesh/package.json"
15
15
  * node_modules), and resolveJsonModule handles the static import at compile time.
16
16
  */
17
17
  exports.HOTMESH_VERSION = package_json_1.default.version ?? 'unknown';
18
+ const LONG_TAIL_PACKAGE_NAME = '@hotmeshio/long-tail';
18
19
  /**
19
- * The long-tail app version. Read from the root package.json at runtime via the
20
- * process working directory (which is the app root in both dev and the Docker
21
- * image, where CMD runs `node build/index.js` from /app). A static
22
- * `../package.json` import would resolve to build/package.json after compile
23
- * a path the Dockerfile does not copy so this reads from cwd instead.
20
+ * The long-tail package version.
21
+ *
22
+ * Resolved from long-tail's OWN package.json by walking up from this module's
23
+ * directory to the first package.json named `@hotmeshio/long-tail`. Reading
24
+ * `process.cwd()/package.json` is wrong when long-tail is consumed as a
25
+ * dependency (e.g. mounted as a NestJS module) — cwd is then the HOST app's
26
+ * root, so it reported the host's version. The upward walk resolves correctly in
27
+ * dev (source tree), the standalone Docker image (`/app`), and under
28
+ * `node_modules/@hotmeshio/long-tail`. A static `../package.json` import can't be
29
+ * used: post-compile it resolves to `build/package.json`, which is not shipped.
24
30
  */
25
31
  exports.LONG_TAIL_VERSION = readLongTailVersion();
26
32
  function readLongTailVersion() {
27
- try {
28
- const raw = (0, fs_1.readFileSync)((0, path_1.resolve)(process.cwd(), 'package.json'), 'utf8');
29
- return JSON.parse(raw).version ?? 'unknown';
30
- }
31
- catch {
32
- return 'unknown';
33
+ let dir = __dirname;
34
+ const { root } = (0, path_1.parse)(dir);
35
+ // eslint-disable-next-line no-constant-condition
36
+ while (true) {
37
+ try {
38
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(dir, 'package.json'), 'utf8'));
39
+ if (pkg.name === LONG_TAIL_PACKAGE_NAME)
40
+ return pkg.version ?? 'unknown';
41
+ }
42
+ catch {
43
+ /* no readable package.json here — keep walking up */
44
+ }
45
+ if (dir === root)
46
+ break;
47
+ dir = (0, path_1.dirname)(dir);
33
48
  }
49
+ return 'unknown';
34
50
  }
@@ -37,19 +37,32 @@ const express_1 = require("express");
37
37
  const api = __importStar(require("../api/diagnostics"));
38
38
  const auth_1 = require("../modules/auth");
39
39
  const router = (0, express_1.Router)();
40
+ const VALID_SECTIONS = new Set(['events', 'streams']);
41
+ /** Parse a comma-separated `include` query param into the recognized heavy sections. */
42
+ function parseInclude(raw) {
43
+ if (typeof raw !== 'string' || raw.trim() === '')
44
+ return undefined;
45
+ const sections = raw.split(',').map((s) => s.trim()).filter((s) => VALID_SECTIONS.has(s));
46
+ return sections.length > 0 ? sections : undefined;
47
+ }
40
48
  /**
41
49
  * GET /api/diagnostics/jobs/:workflowId
42
- * Full diagnosis for a single workflow job.
50
+ * Compact diagnosis for a single workflow job — the verdict only by default
51
+ * (status, idle time, stream counts, escalation, findings).
43
52
  *
44
53
  * Query params:
45
54
  * app_id — HotMesh namespace (default: durable)
46
- * max_events — cap on events returned (most recent kept; default: 500)
55
+ * max_events — cap on events returned when included (most recent kept; default: 500)
56
+ * include — comma-separated heavy sections to add: events, streams
57
+ * verbosity — 'summary' (default, verdict only) or 'full' (events + streams)
47
58
  */
48
59
  router.get('/jobs/:workflowId', auth_1.requireAdmin, async (req, res) => {
49
60
  const result = await api.diagnose({
50
61
  workflowId: req.params.workflowId,
51
62
  appId: typeof req.query.app_id === 'string' ? req.query.app_id : undefined,
52
63
  maxEvents: req.query.max_events ? Number(req.query.max_events) : undefined,
64
+ include: parseInclude(req.query.include),
65
+ verbosity: req.query.verbosity === 'full' ? 'full' : undefined,
53
66
  });
54
67
  res.status(result.status).json(result.data ?? { error: result.error });
55
68
  });
@@ -0,0 +1,7 @@
1
+ import { Router } from 'express';
2
+ /**
3
+ * Faceted-routing HTTP surface — pond search + batch claim. Each operation targets a
4
+ * single pond `role` and is RBAC-scoped to it (the api layer enforces the gate). These
5
+ * mirror the SDK `escalations.searchByFacets / claimGroups / claimByFacets`.
6
+ */
7
+ export declare function registerFacetRoutes(router: Router): void;