@hotmeshio/long-tail 0.4.12 → 0.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (265) hide show
  1. package/README.md +76 -100
  2. package/build/api/escalations/helpers.d.ts +14 -0
  3. package/build/api/escalations/helpers.js +14 -0
  4. package/build/api/escalations/index.d.ts +1 -0
  5. package/build/api/escalations/index.js +5 -1
  6. package/build/api/escalations/metadata.d.ts +56 -0
  7. package/build/api/escalations/metadata.js +178 -0
  8. package/build/api/index.d.ts +2 -1
  9. package/build/api/index.js +3 -2
  10. package/build/api/{mcp-runs.d.ts → pipelines.d.ts} +18 -0
  11. package/build/api/{mcp-runs.js → pipelines.js} +36 -4
  12. package/build/api/workflows/discovery.js +1 -1
  13. package/build/bin/ltc.js +17 -0
  14. package/build/lib/cli/commands/escalations.d.ts +9 -0
  15. package/build/lib/cli/commands/escalations.js +36 -0
  16. package/build/lib/db/schemas/010_metadata_gin.sql +5 -0
  17. package/build/routes/escalations/index.js +3 -0
  18. package/build/routes/escalations/metadata.d.ts +6 -0
  19. package/build/routes/escalations/metadata.js +86 -0
  20. package/build/routes/index.js +3 -2
  21. package/build/routes/{mcp-runs.js → pipelines.js} +17 -4
  22. package/build/sdk/index.d.ts +30 -4
  23. package/build/sdk/index.js +15 -5
  24. package/build/services/escalation/crud.d.ts +5 -0
  25. package/build/services/escalation/crud.js +27 -0
  26. package/build/services/escalation/sql.d.ts +5 -0
  27. package/build/services/escalation/sql.js +39 -1
  28. package/build/services/interceptor/activities/escalation.js +11 -0
  29. package/build/services/{mcp-runs → pipelines}/sql.js +1 -1
  30. package/build/start/adapters.js +3 -6
  31. package/build/start/server.js +7 -3
  32. package/build/tsconfig.tsbuildinfo +1 -1
  33. package/build/types/startup.d.ts +3 -3
  34. package/dashboard/dist/assets/{AdminDashboard-B7AFFt4L.js → AdminDashboard-BuqyRY2r.js} +2 -2
  35. package/dashboard/dist/assets/{AdminDashboard-B7AFFt4L.js.map → AdminDashboard-BuqyRY2r.js.map} +1 -1
  36. package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js +16 -0
  37. package/dashboard/dist/assets/AgentConfigPage-Bum1dUIi.js.map +1 -0
  38. package/dashboard/dist/assets/{AgentDetailPage-DnHaUCS5.js → AgentDetailPage-0Kq-tBF2.js} +3 -3
  39. package/dashboard/dist/assets/{AgentDetailPage-DnHaUCS5.js.map → AgentDetailPage-0Kq-tBF2.js.map} +1 -1
  40. package/dashboard/dist/assets/{AgentsPage-BR2-PdTq.js → AgentsPage-B5gYDSOX.js} +2 -2
  41. package/dashboard/dist/assets/{AgentsPage-BR2-PdTq.js.map → AgentsPage-B5gYDSOX.js.map} +1 -1
  42. package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js +2 -0
  43. package/dashboard/dist/assets/AvailableEscalationsPage-BWHThQDC.js.map +1 -0
  44. package/dashboard/dist/assets/BotPicker-BQ336piW.js +2 -0
  45. package/dashboard/dist/assets/{BotPicker-CAowL3ib.js.map → BotPicker-BQ336piW.js.map} +1 -1
  46. package/dashboard/dist/assets/CapabilitiesPage-CkiJROX-.js +2 -0
  47. package/dashboard/dist/assets/{CapabilitiesPage-CSUKBvEN.js.map → CapabilitiesPage-CkiJROX-.js.map} +1 -1
  48. package/dashboard/dist/assets/{CollapsibleSection-Bv6ixURp.js → CollapsibleSection-SM8_UjNe.js} +2 -2
  49. package/dashboard/dist/assets/{CollapsibleSection-Bv6ixURp.js.map → CollapsibleSection-SM8_UjNe.js.map} +1 -1
  50. package/dashboard/dist/assets/{CredentialsPage-CdPKxRBj.js → CredentialsPage-f6niro9_.js} +2 -2
  51. package/dashboard/dist/assets/{CredentialsPage-CdPKxRBj.js.map → CredentialsPage-f6niro9_.js.map} +1 -1
  52. package/dashboard/dist/assets/{CronLabel-BtdXRDqs.js → CronLabel-DINmdqoe.js} +2 -2
  53. package/dashboard/dist/assets/{CronLabel-BtdXRDqs.js.map → CronLabel-DINmdqoe.js.map} +1 -1
  54. package/dashboard/dist/assets/{CustomDurationPicker-Mq3SLUuv.js → CustomDurationPicker-BCUcYxfB.js} +2 -2
  55. package/dashboard/dist/assets/{CustomDurationPicker-Mq3SLUuv.js.map → CustomDurationPicker-BCUcYxfB.js.map} +1 -1
  56. package/dashboard/dist/assets/{DropZone-lw2wmqty.js → DropZone-BkfRoUcm.js} +2 -2
  57. package/dashboard/dist/assets/{DropZone-lw2wmqty.js.map → DropZone-BkfRoUcm.js.map} +1 -1
  58. package/dashboard/dist/assets/{ElapsedCell-DOTqB4ZX.js → ElapsedCell-DPYZnXsX.js} +2 -2
  59. package/dashboard/dist/assets/{ElapsedCell-DOTqB4ZX.js.map → ElapsedCell-DPYZnXsX.js.map} +1 -1
  60. package/dashboard/dist/assets/{EscalationsOverview-DSM8Mnb-.js → EscalationsOverview-CTB8AEBd.js} +2 -2
  61. package/dashboard/dist/assets/{EscalationsOverview-DSM8Mnb-.js.map → EscalationsOverview-CTB8AEBd.js.map} +1 -1
  62. package/dashboard/dist/assets/{EventTable-C-HagWbs.js → EventTable-8_r3Tg09.js} +2 -2
  63. package/dashboard/dist/assets/{EventTable-C-HagWbs.js.map → EventTable-8_r3Tg09.js.map} +1 -1
  64. package/dashboard/dist/assets/{EventTopicPill-RaASGdZz.js → EventTopicPill-CCWCs07y.js} +2 -2
  65. package/dashboard/dist/assets/{EventTopicPill-RaASGdZz.js.map → EventTopicPill-CCWCs07y.js.map} +1 -1
  66. package/dashboard/dist/assets/HomePage-Bjxnjv6p.js +2 -0
  67. package/dashboard/dist/assets/HomePage-Bjxnjv6p.js.map +1 -0
  68. package/dashboard/dist/assets/ListToolbar-B60JrvJ9.js +2 -0
  69. package/dashboard/dist/assets/{ListToolbar-o8xSCSVv.js.map → ListToolbar-B60JrvJ9.js.map} +1 -1
  70. package/dashboard/dist/assets/McpOverview-whVRP_Nj.js +2 -0
  71. package/dashboard/dist/assets/McpOverview-whVRP_Nj.js.map +1 -0
  72. package/dashboard/dist/assets/{McpQueryDetailPage-UR0bySPJ.js → McpQueryDetailPage-DPuujJkH.js} +2 -2
  73. package/dashboard/dist/assets/McpQueryDetailPage-DPuujJkH.js.map +1 -0
  74. package/dashboard/dist/assets/{McpQueryPage-C-mzOcGH.js → McpQueryPage-DciK6r7r.js} +2 -2
  75. package/dashboard/dist/assets/{McpQueryPage-C-mzOcGH.js.map → McpQueryPage-DciK6r7r.js.map} +1 -1
  76. package/dashboard/dist/assets/McpRunDetailPage-QEz8BCTu.js +2 -0
  77. package/dashboard/dist/assets/McpRunDetailPage-QEz8BCTu.js.map +1 -0
  78. package/dashboard/dist/assets/McpRunsPage-BA6AVpi_.js +2 -0
  79. package/dashboard/dist/assets/McpRunsPage-BA6AVpi_.js.map +1 -0
  80. package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js +2 -0
  81. package/dashboard/dist/assets/OperatorDashboard-DrUMzwnl.js.map +1 -0
  82. package/dashboard/dist/assets/{PageHeader-B4w-LDUF.js → PageHeader-CR6TpJG_.js} +2 -2
  83. package/dashboard/dist/assets/{PageHeader-B4w-LDUF.js.map → PageHeader-CR6TpJG_.js.map} +1 -1
  84. package/dashboard/dist/assets/{PageHeaderWithStats-DQmNXYcG.js → PageHeaderWithStats-CRcQEAO1.js} +2 -2
  85. package/dashboard/dist/assets/{PageHeaderWithStats-DQmNXYcG.js.map → PageHeaderWithStats-CRcQEAO1.js.map} +1 -1
  86. package/dashboard/dist/assets/{ProcessDetailPage-8cJEBC_E.js → ProcessDetailPage-Dc5ASJpQ.js} +2 -2
  87. package/dashboard/dist/assets/{ProcessDetailPage-8cJEBC_E.js.map → ProcessDetailPage-Dc5ASJpQ.js.map} +1 -1
  88. package/dashboard/dist/assets/{ProcessesListPage-CiprI5Wj.js → ProcessesListPage-Sa-bjC-g.js} +2 -2
  89. package/dashboard/dist/assets/{ProcessesListPage-CiprI5Wj.js.map → ProcessesListPage-Sa-bjC-g.js.map} +1 -1
  90. package/dashboard/dist/assets/{RolePill-Dk-YUxCm.js → RolePill-BC54Vn-U.js} +2 -2
  91. package/dashboard/dist/assets/{RolePill-Dk-YUxCm.js.map → RolePill-BC54Vn-U.js.map} +1 -1
  92. package/dashboard/dist/assets/{RolesPage-xo6AgPym.js → RolesPage-DmO8Jlbw.js} +2 -2
  93. package/dashboard/dist/assets/{RolesPage-xo6AgPym.js.map → RolesPage-DmO8Jlbw.js.map} +1 -1
  94. package/dashboard/dist/assets/{RunAsSelector-DPXWgduq.js → RunAsSelector-yWEwIZRe.js} +2 -2
  95. package/dashboard/dist/assets/{RunAsSelector-DPXWgduq.js.map → RunAsSelector-yWEwIZRe.js.map} +1 -1
  96. package/dashboard/dist/assets/{ServerName-A6Wlv3vZ.js → ServerName-Q6okiv4f.js} +2 -2
  97. package/dashboard/dist/assets/{ServerName-A6Wlv3vZ.js.map → ServerName-Q6okiv4f.js.map} +1 -1
  98. package/dashboard/dist/assets/{SwimlaneTimeline-BzG8QxYs.js → SwimlaneTimeline-CmzfFQ09.js} +2 -2
  99. package/dashboard/dist/assets/{SwimlaneTimeline-BzG8QxYs.js.map → SwimlaneTimeline-CmzfFQ09.js.map} +1 -1
  100. package/dashboard/dist/assets/{TagInput-CYh3PFNq.js → TagInput-D6l1SPWd.js} +2 -2
  101. package/dashboard/dist/assets/{TagInput-CYh3PFNq.js.map → TagInput-D6l1SPWd.js.map} +1 -1
  102. package/dashboard/dist/assets/{TaskDetailPage-Ck_0-iO2.js → TaskDetailPage-CI4JTC62.js} +2 -2
  103. package/dashboard/dist/assets/{TaskDetailPage-Ck_0-iO2.js.map → TaskDetailPage-CI4JTC62.js.map} +1 -1
  104. package/dashboard/dist/assets/{TaskQueuePill-BSFLiBcf.js → TaskQueuePill-iDBVCEQQ.js} +2 -2
  105. package/dashboard/dist/assets/{TaskQueuePill-BSFLiBcf.js.map → TaskQueuePill-iDBVCEQQ.js.map} +1 -1
  106. package/dashboard/dist/assets/{TasksListPage-DtR4F0ho.js → TasksListPage-xdNmQsNE.js} +2 -2
  107. package/dashboard/dist/assets/{TasksListPage-DtR4F0ho.js.map → TasksListPage-xdNmQsNE.js.map} +1 -1
  108. package/dashboard/dist/assets/{TimeAgo-BLNstYO1.js → TimeAgo-B_um9BWR.js} +2 -2
  109. package/dashboard/dist/assets/{TimeAgo-BLNstYO1.js.map → TimeAgo-B_um9BWR.js.map} +1 -1
  110. package/dashboard/dist/assets/{TimestampCell-DxIz3l1J.js → TimestampCell-BJ6trAqW.js} +2 -2
  111. package/dashboard/dist/assets/{TimestampCell-DxIz3l1J.js.map → TimestampCell-BJ6trAqW.js.map} +1 -1
  112. package/dashboard/dist/assets/{ToolPill-CcKNnnrK.js → ToolPill-HcRTggHo.js} +2 -2
  113. package/dashboard/dist/assets/{ToolPill-CcKNnnrK.js.map → ToolPill-HcRTggHo.js.map} +1 -1
  114. package/dashboard/dist/assets/{ToolTestPanel-AVDlqGQI.js → ToolTestPanel-DMQhLDES.js} +2 -2
  115. package/dashboard/dist/assets/{ToolTestPanel-AVDlqGQI.js.map → ToolTestPanel-DMQhLDES.js.map} +1 -1
  116. package/dashboard/dist/assets/TopicDetailPage-YeGQA0vD.js +9 -0
  117. package/dashboard/dist/assets/TopicDetailPage-YeGQA0vD.js.map +1 -0
  118. package/dashboard/dist/assets/{TopicsPage-BdnJ7E_S.js → TopicsPage-B3QZNlWz.js} +2 -2
  119. package/dashboard/dist/assets/{TopicsPage-BdnJ7E_S.js.map → TopicsPage-B3QZNlWz.js.map} +1 -1
  120. package/dashboard/dist/assets/{UserName-Bk-pzKYb.js → UserName-MpSZ2_EH.js} +2 -2
  121. package/dashboard/dist/assets/{UserName-Bk-pzKYb.js.map → UserName-MpSZ2_EH.js.map} +1 -1
  122. package/dashboard/dist/assets/WorkflowExecutionPage-DqMqDb1h.js +2 -0
  123. package/dashboard/dist/assets/WorkflowExecutionPage-DqMqDb1h.js.map +1 -0
  124. package/dashboard/dist/assets/WorkflowPill-54px0YiY.js +2 -0
  125. package/dashboard/dist/assets/WorkflowPill-54px0YiY.js.map +1 -0
  126. package/dashboard/dist/assets/{WorkflowsDashboard-nXLTR0OO.js → WorkflowsDashboard-BF7FpMmk.js} +2 -2
  127. package/dashboard/dist/assets/WorkflowsDashboard-BF7FpMmk.js.map +1 -0
  128. package/dashboard/dist/assets/{WorkflowsOverview-BdSHBzzd.js → WorkflowsOverview-YFc_KBMS.js} +2 -2
  129. package/dashboard/dist/assets/{WorkflowsOverview-BdSHBzzd.js.map → WorkflowsOverview-YFc_KBMS.js.map} +1 -1
  130. package/dashboard/dist/assets/YamlWorkflowsPage-BOLs5KTB.js +2 -0
  131. package/dashboard/dist/assets/{YamlWorkflowsPage-BsO4L_SW.js.map → YamlWorkflowsPage-BOLs5KTB.js.map} +1 -1
  132. package/dashboard/dist/assets/{agents-CtF0uBav.js → agents-CPYVSCQ3.js} +2 -2
  133. package/dashboard/dist/assets/{agents-CtF0uBav.js.map → agents-CPYVSCQ3.js.map} +1 -1
  134. package/dashboard/dist/assets/{bots-DOP_eck8.js → bots-DCXjHjID.js} +2 -2
  135. package/dashboard/dist/assets/{bots-DOP_eck8.js.map → bots-DCXjHjID.js.map} +1 -1
  136. package/dashboard/dist/assets/{capabilities-DvxG02aF.js → capabilities-CreogBYU.js} +2 -2
  137. package/dashboard/dist/assets/{capabilities-DvxG02aF.js.map → capabilities-CreogBYU.js.map} +1 -1
  138. package/dashboard/dist/assets/{controlplane-Dmq81vAY.js → controlplane-Cm_-Gb1x.js} +2 -2
  139. package/dashboard/dist/assets/{controlplane-Dmq81vAY.js.map → controlplane-Cm_-Gb1x.js.map} +1 -1
  140. package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js +2 -0
  141. package/dashboard/dist/assets/escalation-columns-CLqe28Ba.js.map +1 -0
  142. package/dashboard/dist/assets/{escalation-BP3UWfIe.js → escalation-ulsBFHVb.js} +2 -2
  143. package/dashboard/dist/assets/{escalation-BP3UWfIe.js.map → escalation-ulsBFHVb.js.map} +1 -1
  144. package/dashboard/dist/assets/{helpers-B_PYr0pL.js → helpers-etjHeZEI.js} +2 -2
  145. package/dashboard/dist/assets/{helpers-B_PYr0pL.js.map → helpers-etjHeZEI.js.map} +1 -1
  146. package/dashboard/dist/assets/index-7Fbktqcl.js +2 -0
  147. package/dashboard/dist/assets/index-7Fbktqcl.js.map +1 -0
  148. package/dashboard/dist/assets/{index-DQs-LMoa.js → index-BkCkBW_D.js} +2 -2
  149. package/dashboard/dist/assets/{index-DQs-LMoa.js.map → index-BkCkBW_D.js.map} +1 -1
  150. package/dashboard/dist/assets/index-BkOv2dQA.js +2 -0
  151. package/dashboard/dist/assets/{index-Bb1ycul8.js.map → index-BkOv2dQA.js.map} +1 -1
  152. package/dashboard/dist/assets/index-C37LMzJa.css +1 -0
  153. package/dashboard/dist/assets/{index-CkcPZdQm.js → index-CKDOaej4.js} +6 -6
  154. package/dashboard/dist/assets/index-CKDOaej4.js.map +1 -0
  155. package/dashboard/dist/assets/{index-Do1x4kN0.js → index-CcvHiZW-.js} +2 -2
  156. package/dashboard/dist/assets/{index-Do1x4kN0.js.map → index-CcvHiZW-.js.map} +1 -1
  157. package/dashboard/dist/assets/{index-B80zLZVl.js → index-CihScSLF.js} +2 -2
  158. package/dashboard/dist/assets/{index-B80zLZVl.js.map → index-CihScSLF.js.map} +1 -1
  159. package/dashboard/dist/assets/{index-B3wGNZN2.js → index-Cnpo94XG.js} +2 -2
  160. package/dashboard/dist/assets/{index-B3wGNZN2.js.map → index-Cnpo94XG.js.map} +1 -1
  161. package/dashboard/dist/assets/index-DFuHrLll.js +15 -0
  162. package/dashboard/dist/assets/index-DFuHrLll.js.map +1 -0
  163. package/dashboard/dist/assets/{index-DzQBDt3K.js → index-DGpIF_Td.js} +2 -2
  164. package/dashboard/dist/assets/{index-DzQBDt3K.js.map → index-DGpIF_Td.js.map} +1 -1
  165. package/dashboard/dist/assets/index-DT0JeuiL.js +2 -0
  166. package/dashboard/dist/assets/index-DT0JeuiL.js.map +1 -0
  167. package/dashboard/dist/assets/index-DT68ewTC.js +2 -0
  168. package/dashboard/dist/assets/{index-EqKHsaVz.js.map → index-DT68ewTC.js.map} +1 -1
  169. package/dashboard/dist/assets/{index-Bv0eLXZq.js → index-DVqtJBno.js} +4 -4
  170. package/dashboard/dist/assets/{index-Bv0eLXZq.js.map → index-DVqtJBno.js.map} +1 -1
  171. package/dashboard/dist/assets/{index-BnB7G5bA.js → index-DYmrNJ_H.js} +23 -23
  172. package/dashboard/dist/assets/index-DYmrNJ_H.js.map +1 -0
  173. package/dashboard/dist/assets/{knowledge--SApApck.js → knowledge-CXA2DJwY.js} +2 -2
  174. package/dashboard/dist/assets/{knowledge--SApApck.js.map → knowledge-CXA2DJwY.js.map} +1 -1
  175. package/dashboard/dist/assets/{mcp-dn9iPrzm.js → mcp-DeC-PpeL.js} +2 -2
  176. package/dashboard/dist/assets/{mcp-dn9iPrzm.js.map → mcp-DeC-PpeL.js.map} +1 -1
  177. package/dashboard/dist/assets/{mcp-query-CgiU2UR6.js → mcp-query-DldD_RPZ.js} +2 -2
  178. package/dashboard/dist/assets/{mcp-query-CgiU2UR6.js.map → mcp-query-DldD_RPZ.js.map} +1 -1
  179. package/dashboard/dist/assets/{namespaces-D93H3wFO.js → namespaces-BIGZ6exX.js} +2 -2
  180. package/dashboard/dist/assets/{namespaces-D93H3wFO.js.map → namespaces-BIGZ6exX.js.map} +1 -1
  181. package/dashboard/dist/assets/pipelines-BtihifKT.js +2 -0
  182. package/dashboard/dist/assets/pipelines-BtihifKT.js.map +1 -0
  183. package/dashboard/dist/assets/{roles-DuOWZTpx.js → roles-4DocbpKy.js} +2 -2
  184. package/dashboard/dist/assets/{roles-DuOWZTpx.js.map → roles-4DocbpKy.js.map} +1 -1
  185. package/dashboard/dist/assets/{tasks-DoCbLKz4.js → tasks-B9P_7SR_.js} +2 -2
  186. package/dashboard/dist/assets/{tasks-DoCbLKz4.js.map → tasks-B9P_7SR_.js.map} +1 -1
  187. package/dashboard/dist/assets/{topics-CS7Sxf_-.js → topics-CcLT-IrY.js} +2 -2
  188. package/dashboard/dist/assets/{topics-CS7Sxf_-.js.map → topics-CcLT-IrY.js.map} +1 -1
  189. package/dashboard/dist/assets/{useEventHooks-CrIe_Ulh.js → useEventHooks-B9UOxef_.js} +2 -2
  190. package/dashboard/dist/assets/{useEventHooks-CrIe_Ulh.js.map → useEventHooks-B9UOxef_.js.map} +1 -1
  191. package/dashboard/dist/assets/{useYamlActivityEvents-JzvzGsUR.js → useYamlActivityEvents-V_MENSI5.js} +2 -2
  192. package/dashboard/dist/assets/{useYamlActivityEvents-JzvzGsUR.js.map → useYamlActivityEvents-V_MENSI5.js.map} +1 -1
  193. package/dashboard/dist/assets/{users-DnxSh2dX.js → users-BHF3YOU1.js} +2 -2
  194. package/dashboard/dist/assets/{users-DnxSh2dX.js.map → users-BHF3YOU1.js.map} +1 -1
  195. package/dashboard/dist/assets/{vendor-icons-5gSix3t2.js → vendor-icons-CrrAvF2g.js} +131 -111
  196. package/dashboard/dist/assets/vendor-icons-CrrAvF2g.js.map +1 -0
  197. package/dashboard/dist/assets/{workflows-zFmmxc08.js → workflows-DorgmYSk.js} +2 -2
  198. package/dashboard/dist/assets/{workflows-zFmmxc08.js.map → workflows-DorgmYSk.js.map} +1 -1
  199. package/dashboard/dist/assets/{yaml-workflows-VSax0tKa.js → yaml-workflows-DTGpqnEG.js} +2 -2
  200. package/dashboard/dist/assets/{yaml-workflows-VSax0tKa.js.map → yaml-workflows-DTGpqnEG.js.map} +1 -1
  201. package/dashboard/dist/index.html +3 -3
  202. package/docs/api/http/escalations.md +96 -0
  203. package/docs/api/http/{mcp-runs.md → pipelines.md} +39 -25
  204. package/docs/api/sdk/escalations.md +84 -0
  205. package/docs/cli.md +8 -0
  206. package/docs/dashboard.md +1 -1
  207. package/docs/sdk.md +2 -2
  208. package/package.json +1 -1
  209. package/dashboard/dist/assets/AgentConfigPage-CjuCbr5J.js +0 -16
  210. package/dashboard/dist/assets/AgentConfigPage-CjuCbr5J.js.map +0 -1
  211. package/dashboard/dist/assets/AvailableEscalationsPage-CEkeo_N4.js +0 -2
  212. package/dashboard/dist/assets/AvailableEscalationsPage-CEkeo_N4.js.map +0 -1
  213. package/dashboard/dist/assets/BotPicker-CAowL3ib.js +0 -2
  214. package/dashboard/dist/assets/CapabilitiesPage-CSUKBvEN.js +0 -2
  215. package/dashboard/dist/assets/HomePage-BkMEYnRK.js +0 -2
  216. package/dashboard/dist/assets/HomePage-BkMEYnRK.js.map +0 -1
  217. package/dashboard/dist/assets/ListToolbar-o8xSCSVv.js +0 -2
  218. package/dashboard/dist/assets/McpOverview-C4man2br.js +0 -2
  219. package/dashboard/dist/assets/McpOverview-C4man2br.js.map +0 -1
  220. package/dashboard/dist/assets/McpQueryDetailPage-UR0bySPJ.js.map +0 -1
  221. package/dashboard/dist/assets/McpRunDetailPage-bJl08JSG.js +0 -2
  222. package/dashboard/dist/assets/McpRunDetailPage-bJl08JSG.js.map +0 -1
  223. package/dashboard/dist/assets/McpRunsPage-i2FGJ6yf.js +0 -2
  224. package/dashboard/dist/assets/McpRunsPage-i2FGJ6yf.js.map +0 -1
  225. package/dashboard/dist/assets/OperatorDashboard-DLpqyLle.js +0 -2
  226. package/dashboard/dist/assets/OperatorDashboard-DLpqyLle.js.map +0 -1
  227. package/dashboard/dist/assets/TopicDetailPage-DQkoAlsj.js +0 -9
  228. package/dashboard/dist/assets/TopicDetailPage-DQkoAlsj.js.map +0 -1
  229. package/dashboard/dist/assets/WorkflowExecutionPage-B6mBqWq6.js +0 -2
  230. package/dashboard/dist/assets/WorkflowExecutionPage-B6mBqWq6.js.map +0 -1
  231. package/dashboard/dist/assets/WorkflowPill-BkfIn8N3.js +0 -2
  232. package/dashboard/dist/assets/WorkflowPill-BkfIn8N3.js.map +0 -1
  233. package/dashboard/dist/assets/WorkflowsDashboard-nXLTR0OO.js.map +0 -1
  234. package/dashboard/dist/assets/YamlWorkflowsPage-BsO4L_SW.js +0 -2
  235. package/dashboard/dist/assets/escalation-columns-BayccZzU.js +0 -2
  236. package/dashboard/dist/assets/escalation-columns-BayccZzU.js.map +0 -1
  237. package/dashboard/dist/assets/index-Bb1ycul8.js +0 -2
  238. package/dashboard/dist/assets/index-BnB7G5bA.js.map +0 -1
  239. package/dashboard/dist/assets/index-BnVnJcXw.js +0 -2
  240. package/dashboard/dist/assets/index-BnVnJcXw.js.map +0 -1
  241. package/dashboard/dist/assets/index-CkcPZdQm.js.map +0 -1
  242. package/dashboard/dist/assets/index-CsagXf3M.js +0 -2
  243. package/dashboard/dist/assets/index-CsagXf3M.js.map +0 -1
  244. package/dashboard/dist/assets/index-DZI2L4ag.css +0 -1
  245. package/dashboard/dist/assets/index-EqKHsaVz.js +0 -2
  246. package/dashboard/dist/assets/index-ox042ec_.js +0 -15
  247. package/dashboard/dist/assets/index-ox042ec_.js.map +0 -1
  248. package/dashboard/dist/assets/mcp-runs-BN5MrKai.js +0 -2
  249. package/dashboard/dist/assets/mcp-runs-BN5MrKai.js.map +0 -1
  250. package/dashboard/dist/assets/vendor-icons-5gSix3t2.js.map +0 -1
  251. /package/build/routes/{mcp-runs.d.ts → pipelines.d.ts} +0 -0
  252. /package/build/services/{mcp-runs → pipelines}/enrichment.d.ts +0 -0
  253. /package/build/services/{mcp-runs → pipelines}/enrichment.js +0 -0
  254. /package/build/services/{mcp-runs → pipelines}/events.d.ts +0 -0
  255. /package/build/services/{mcp-runs → pipelines}/events.js +0 -0
  256. /package/build/services/{mcp-runs → pipelines}/execution-builder.d.ts +0 -0
  257. /package/build/services/{mcp-runs → pipelines}/execution-builder.js +0 -0
  258. /package/build/services/{mcp-runs → pipelines}/index.d.ts +0 -0
  259. /package/build/services/{mcp-runs → pipelines}/index.js +0 -0
  260. /package/build/services/{mcp-runs → pipelines}/queries.d.ts +0 -0
  261. /package/build/services/{mcp-runs → pipelines}/queries.js +0 -0
  262. /package/build/services/{mcp-runs → pipelines}/sql.d.ts +0 -0
  263. /package/build/services/{mcp-runs → pipelines}/types.d.ts +0 -0
  264. /package/build/services/{mcp-runs → pipelines}/types.js +0 -0
  265. /package/docs/api/sdk/{mcp-runs.md → pipelines.md} +0 -0
package/README.md CHANGED
@@ -1,41 +1,14 @@
1
1
  # Long Tail
2
2
 
3
- Long Tail turns your PostgreSQL database into a workflow engine where human and AI work share the same durable execution path. Hand off, pull back, escalate, automate without rewriting systems or losing continuity.
3
+ Write durable workflows in TypeScript. When they need a human, they escalate. When they need AI, they orchestrate. When a pattern repeats, they compile it away. Postgres is the engine.
4
4
 
5
5
  ```bash
6
6
  npm install @hotmeshio/long-tail
7
7
  ```
8
8
 
9
- ## Use Long Tail for
9
+ ## How it works
10
10
 
11
- - **Durable execution** Your functions run as workflows and checkpoint to Postgres. If the process crashes, execution resumes from the last completed step.
12
- - **Identity everywhere** — Workflows know who started them, whose credentials govern their execution, and what permissions are in play. IAM is not bolted on — it's woven into every activity call.
13
- - **Human-in-the-loop** — When confidence is low, the workflow escalates. RBAC-scoped escalation chains route work to the right reviewer. Approval workflows, content review, document verification — the pattern is the same.
14
- - **AI triage** — When human-in-the-loop teams can't resolve a request, AI takes over. Its tool calls are checkpointed. And when the fix works, it compiles into a deterministic pipeline for next time.
15
- - **MCP tool orchestration** — Describe what you need. If you've registered the tools, the Pipeline Designer builds the workflow. Every compiled pipeline deploys as a reusable MCP tool.
16
-
17
- A dashboard, REST API, and live event stream ship with the package. Use what you need.
18
-
19
- ## Start
20
-
21
- Point at Postgres. Everything else is optional.
22
-
23
- ```typescript
24
- import { start } from '@hotmeshio/long-tail';
25
- import * as myWorkflow from './workflows/my-workflow';
26
-
27
- const lt = await start({
28
- database: { host: 'localhost', port: 5432, user: 'postgres', password: 'password', database: 'mydb' },
29
- workers: [{ taskQueue: 'default', workflow: myWorkflow.reviewContent }],
30
- auth: { secret: process.env.JWT_SECRET },
31
- });
32
- ```
33
-
34
- Dashboard at [http://localhost:3000](http://localhost:3000). The [boilerplate](https://github.com/hotmeshio/long-tail-boilerplate) has a working project with custom MCP servers, MinIO, and example workflows.
35
-
36
- ## Write a Durable Workflow
37
-
38
- A workflow receives an envelope and returns a result. Each activity call checkpoints — no work is lost, no step runs twice.
11
+ You write a workflow function. Each activity call checkpoints to Postgres if the process crashes, it resumes from the last completed step.
39
12
 
40
13
  ```typescript
41
14
  import { Durable } from '@hotmeshio/hotmesh';
@@ -51,6 +24,7 @@ export async function reviewContent(envelope: LTEnvelope) {
51
24
  return { type: 'return' as const, data: { approved: true, analysis } };
52
25
  }
53
26
 
27
+ // Low confidence — escalate to a human reviewer
54
28
  return {
55
29
  type: 'escalation' as const,
56
30
  role: 'reviewer',
@@ -60,32 +34,39 @@ export async function reviewContent(envelope: LTEnvelope) {
60
34
  }
61
35
  ```
62
36
 
63
- Activities are plain functions with side effects API calls, LLM invocations, database queries. The `proxyActivities` call wraps them so the engine can checkpoint each result.
37
+ That's a complete workflow. It runs, checkpoints, and when confidence is low, it hands off to a human. The human resolves it through the dashboard or API, and the workflow completes. No separate queue system, no webhook callbacks — the escalation is part of the execution.
38
+
39
+ Activities are plain functions:
64
40
 
65
41
  ```typescript
66
- // activities.ts
67
42
  export async function analyzeContent(content: string) {
68
43
  const result = await llm.classify(content);
69
44
  return { confidence: result.confidence, flags: result.flags };
70
45
  }
71
46
  ```
72
47
 
73
- ## Compile Workflows
48
+ ## Start
74
49
 
75
- Write durable workflows in TypeScript. Compile to YAML DAGs that run without replay overhead. `ltc` is the compiler — like `tsc` for workflows.
50
+ Point at Postgres. Everything else is optional.
76
51
 
77
- ```bash
78
- export ANTHROPIC_API_KEY=sk-ant-...
52
+ ```typescript
53
+ import { start } from '@hotmeshio/long-tail';
79
54
 
80
- npx ltc compile workflows/ # scan and compile all workflow files
81
- npx ltc compile --dry-run # discover without compiling
55
+ const lt = await start({
56
+ database: { host: 'localhost', port: 5432, user: 'postgres', password: 'password', database: 'mydb' },
57
+ workers: [{ taskQueue: 'default', workflow: reviewContent }],
58
+ });
82
59
  ```
83
60
 
84
- The source is the spec. The compiled YAML is the optimized execution. Both live in the repo. See the [Compiler Guide](docs/compiler.md).
61
+ Dashboard at [http://localhost:3000](http://localhost:3000). The [boilerplate](https://github.com/hotmeshio/long-tail-boilerplate) has a working project with workflows, MCP servers, and MinIO.
62
+
63
+ ## The pattern
85
64
 
86
- ## Certify a Workflow
65
+ Most systems start with a durable workflow and stop there. Long Tail keeps going.
87
66
 
88
- Any durable workflow can be promoted to **certified** through the dashboard or API. A certified workflow gains interceptor guarantees: failures escalate instead of throwing, escalation chains route through roles, and every error is either handled or surfaced. It cannot silently fail.
67
+ **Step 1 Author a durable workflow.** Your function checkpoints to Postgres. It can sleep, branch, call child workflows, wait for signals. Standard durable execution.
68
+
69
+ **Step 2 — Certify it.** Promotion to certified adds interceptor guarantees: failures escalate instead of throwing, escalation chains route through RBAC-scoped roles, and every error is either handled or surfaced. It cannot silently fail.
89
70
 
90
71
  ```bash
91
72
  curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
@@ -93,13 +74,17 @@ curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
93
74
  -d '{ "invocable": true, "task_queue": "default", "default_role": "reviewer" }'
94
75
  ```
95
76
 
96
- De-certifying removes the interceptor. The workflow continues as a standard durable workflow — same code, different guarantees.
77
+ **Step 3 React to events.** Workflows publish topics. Agents subscribe. When `activity.failed` fires, an automation can re-run the step, notify a team, or trigger a different workflow. The choreography is dynamic add subscribers through the dashboard without changing code.
78
+
79
+ **Step 4 — Compile what repeats.** The Pipeline Designer takes a working execution and compiles it into a deterministic YAML DAG. No LLM at runtime, no replay overhead, typed inputs and outputs. It deploys as a reusable tool that any workflow or API call can invoke.
80
+
81
+ Over time, the system accumulates compiled tools. Problems that once required a human, then required AI reasoning, eventually require neither.
97
82
 
98
- ## Register MCP Servers
83
+ ## Register MCP tools
99
84
 
100
- Long Tail connects to any MCP server — an npm package, a remote service, or one you write yourself. Registered tools become durable activities and are available to the Pipeline Designer.
85
+ Long Tail connects to any MCP server. Registered tools become durable activities and are available to the Pipeline Designer.
101
86
 
102
- **Use an existing package** — no code, just register:
87
+ **Existing package — no code:**
103
88
 
104
89
  ```bash
105
90
  curl -X POST http://localhost:3000/api/mcp/servers \
@@ -113,21 +98,14 @@ curl -X POST http://localhost:3000/api/mcp/servers \
113
98
  }'
114
99
  ```
115
100
 
116
- **Connect a remote server** — point at a URL:
101
+ **Remote server — point at a URL:**
117
102
 
118
103
  ```bash
119
104
  curl -X POST http://localhost:3000/api/mcp/servers \
120
- -H 'Content-Type: application/json' \
121
- -d '{
122
- "name": "my-python-server",
123
- "transport_type": "sse",
124
- "transport_config": { "url": "http://python-service:8000/mcp" },
125
- "tags": ["ml", "classification"],
126
- "compile_hints": "Returns confidence scores. Use threshold 0.85 for auto-approve."
127
- }'
105
+ -d '{ "name": "my-python-server", "transport_type": "sse", "transport_config": { "url": "http://python-service:8000/mcp" } }'
128
106
  ```
129
107
 
130
- **Write your own** and register it in-process:
108
+ **In-process — write your own:**
131
109
 
132
110
  ```typescript
133
111
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
@@ -139,8 +117,8 @@ export function createImageToolsServer(): McpServer {
139
117
 
140
118
  registerMcpTool(server, 'resize_image', 'Resize an image.', {
141
119
  path: z.string().describe('Path to the image'),
142
- width: z.number().optional().describe('Target width'),
143
- height: z.number().optional().describe('Target height'),
120
+ width: z.number().optional(),
121
+ height: z.number().optional(),
144
122
  }, async (args: any) => ({
145
123
  content: [{ type: 'text', text: JSON.stringify(await resize(args)) }],
146
124
  }));
@@ -152,36 +130,33 @@ export function createImageToolsServer(): McpServer {
152
130
  ```typescript
153
131
  const lt = await start({
154
132
  // ...
155
- mcp: {
156
- serverFactories: { 'image-tools': createImageToolsServer },
157
- },
133
+ mcp: { serverFactories: { 'image-tools': createImageToolsServer } },
158
134
  });
159
135
  ```
160
136
 
161
- All three paths produce the same outcome: tools callable as durable activities. Tags enable discovery. Compile hints guide the compiler when tools are compiled into deterministic pipelines. See the [MCP guide](docs/mcp.md) for the full registration lifecycle.
137
+ All three paths produce the same outcome: tools callable as durable activities. See the [MCP guide](docs/mcp.md).
162
138
 
163
- ## Ask It Anything
139
+ ## Compile workflows
164
140
 
165
- Once your tools are registered, the Pipeline Designer orchestrates them. Describe what you need in plain language:
141
+ The `ltc` compiler scans TypeScript workflow files and compiles them to YAML DAGs like `tsc` for workflows.
166
142
 
167
- > *"Log into localhost:3000 as superadmin, navigate to every page in the sidebar, and save a screenshot of each."*
168
-
169
- The system discovers the right MCP servers, calls the tools, chains the results. If it works, the compilation wizard converts the execution into a deterministic pipeline — parameterized inputs, typed schema, no LLM at runtime. It deploys as a new MCP tool that any workflow, agent, or API call can invoke.
143
+ ```bash
144
+ export ANTHROPIC_API_KEY=sk-ant-...
145
+ npx ltc compile workflows/
146
+ ```
170
147
 
171
- The inventory of compiled tools grows over time. The need for LLM reasoning shrinks. Problems that once required a human, then required an AI, eventually require neither.
148
+ The source is the spec. The compiled YAML is the optimized execution. Both live in the repo. See the [Compiler Guide](docs/compiler.md).
172
149
 
173
- ## Full Configuration
150
+ ## Full configuration
174
151
 
175
152
  ```typescript
176
153
  const lt = await start({
177
154
  database: { connectionString: process.env.DATABASE_URL },
178
- workers: [{ taskQueue: 'default', workflow: myWorkflow.reviewContent }],
155
+ workers: [{ taskQueue: 'default', workflow: reviewContent }],
179
156
 
180
157
  // Everything below is optional
181
- mcp: {
182
- server: { enabled: true },
183
- serverFactories: { 'my-tools': createMyToolsServer },
184
- },
158
+ seed: { admin: { externalId: 'admin', password: process.env.ADMIN_PASSWORD } },
159
+ mcp: { server: { enabled: true }, serverFactories: { 'my-tools': createMyToolsServer } },
185
160
  escalation: { strategy: 'mcp' },
186
161
  auth: { secret: process.env.JWT_SECRET },
187
162
  telemetry: { honeycomb: { apiKey: process.env.HNY } },
@@ -190,56 +165,57 @@ const lt = await start({
190
165
  });
191
166
  ```
192
167
 
193
- ## Use as a Package (No HTTP Server)
168
+ ## Embed in an existing app
194
169
 
195
- Long Tail can run as an embedded package inside your existing application no Express server, no socket.io, no extra ports. The same API surface is available as direct function calls.
170
+ Long Tail runs as an embedded package inside NestJS, Express, or any Node.js application. No extra HTTP server, no extra ports.
196
171
 
197
172
  ```typescript
198
173
  import { start, createClient } from '@hotmeshio/long-tail';
199
174
 
200
- await start({
175
+ const lt = await start({
201
176
  database: { connectionString: process.env.DATABASE_URL },
202
177
  server: { enabled: false },
203
- workers: [{ taskQueue: 'default', workflow: reviewContent.reviewContent }],
178
+ seed: { admin: { externalId: 'system' } },
179
+ workers: [{ taskQueue: 'default', workflow: reviewContent }],
204
180
  });
205
181
 
206
- const lt = createClient({ auth: { userId: 'system' } });
182
+ const client = createClient({ auth: { userId: lt.adminUserId } });
207
183
 
208
- // Same operations as the REST API no HTTP overhead
209
- const tasks = await lt.tasks.list({ status: 'completed', limit: 10 });
210
- const result = await lt.escalations.claim({ id: 'esc_123', durationMinutes: 30 });
184
+ const tasks = await client.tasks.list({ status: 'completed', limit: 10 });
185
+ const result = await client.escalations.claim({ id: 'esc_123', durationMinutes: 30 });
211
186
  ```
212
187
 
213
- Subscribe to events with callbacks instead of socket.io:
188
+ Mount the dashboard at a subpath:
214
189
 
215
190
  ```typescript
216
- lt.events.on('task.completed', (event) => {
217
- console.log('done:', event.workflowId);
218
- });
191
+ import { LTExpressAdapter } from '@hotmeshio/long-tail';
219
192
 
220
- lt.events.on('escalation.*', (event) => {
221
- notifyTeam(event);
222
- });
193
+ const adapter = new LTExpressAdapter();
194
+ adapter.setBasePath('/admin/longtail');
195
+ app.use('/admin/longtail', adapter.getRouter());
196
+ ```
197
+
198
+ Subscribe to events with callbacks:
199
+
200
+ ```typescript
201
+ client.events.on('task.completed', (event) => console.log('done:', event.workflowId));
202
+ client.events.on('escalation.*', (event) => notifyTeam(event));
223
203
  ```
224
204
 
225
- Every SDK call returns an `LTApiResult` — same status codes, same validation, same RBAC. The transport is the only thing that changes. See the [SDK guide](docs/sdk.md) for the full API reference.
205
+ Every SDK call returns an `LTApiResult` — same status codes, same validation, same RBAC. See the [SDK guide](docs/sdk.md).
226
206
 
227
207
  ## Deployment
228
208
 
229
209
  Three modes from the same codebase:
230
210
 
231
211
  ```typescript
232
- // 1. Standalone — dashboard + REST API + workers
212
+ // Standalone — dashboard + API + workers
233
213
  await start({ database: { connectionString: process.env.DATABASE_URL } });
234
214
 
235
- // 2. Worker-only — workflow execution, no HTTP server
236
- await start({
237
- database: { connectionString: process.env.DATABASE_URL },
238
- server: { enabled: false },
239
- workers: [{ taskQueue: 'default', workflow: reviewContent.reviewContent }],
240
- });
215
+ // Worker-only — no HTTP server
216
+ await start({ database: { connectionString: process.env.DATABASE_URL }, server: { enabled: false }, workers: [...] });
241
217
 
242
- // 3. Embedded — inside your NestJS/Next.js/Express app, SDK calls only
218
+ // Embedded — inside your app, SDK calls only
243
219
  await start({ database: { connectionString: process.env.DATABASE_URL }, server: { enabled: false } });
244
220
  const lt = createClient({ auth: { userId: 'service' } });
245
221
  ```
@@ -250,12 +226,12 @@ All modes share PostgreSQL and scale independently. See [Cloud Deployment](docs/
250
226
 
251
227
  | Guide | What it covers |
252
228
  |-------|---------------|
253
- | [The Long Tail Story](docs/story.md) | Why this exists, what accumulates over time, what you own |
229
+ | [The Long Tail Story](docs/story.md) | Why this exists, what accumulates over time |
254
230
  | [Workflows](docs/workflows.md) | Activities, interceptor, escalation lifecycle, composition |
255
231
  | [IAM](docs/iam.md) | Identity propagation, service accounts, credential exchange |
256
232
  | [Dashboard](docs/dashboard.md) | Navigation, key pages, event feed |
257
233
  | [MCP](docs/mcp.md) | Server registration, tool calls, human queue |
258
- | [Compilation](docs/compilation.md) | Dynamic deterministic pipeline wizard |
234
+ | [Compilation](docs/compilation.md) | Dynamic to deterministic pipeline wizard |
259
235
  | [Compiler](docs/compiler.md) | `ltc compile` — durable TypeScript to YAML DAGs |
260
236
  | [CLI](docs/cli.md) | `ltc` — terminal access to workflows, escalations, knowledge, MCP |
261
237
  | [Escalation Strategies](docs/escalation-strategies.md) | Default, MCP triage, custom handlers |
@@ -266,7 +242,7 @@ All modes share PostgreSQL and scale independently. See [Cloud Deployment](docs/
266
242
 
267
243
  **Adapters:** [Auth](docs/auth.md) · [Events](docs/events.md) · [Telemetry](docs/telemetry.md) · [Logging](docs/logging.md) · [Maintenance](docs/maintenance.md) · [OAuth](docs/oauth-and-delegation.md)
268
244
 
269
- **HTTP API:** [Workflows](docs/api/http/workflows.md) · [Tasks](docs/api/http/tasks.md) · [Escalations](docs/api/http/escalations.md) · [YAML Workflows](docs/api/http/yaml-workflows.md) · [Users](docs/api/http/users.md) · [Roles](docs/api/http/roles.md) · [Service Accounts](docs/api/http/service-accounts.md) · [MCP Servers](docs/api/http/mcp-servers.md) · [MCP Runs](docs/api/http/mcp-runs.md) · [Exports](docs/api/http/exports.md)
245
+ **HTTP API:** [Workflows](docs/api/http/workflows.md) · [Tasks](docs/api/http/tasks.md) · [Escalations](docs/api/http/escalations.md) · [YAML Workflows](docs/api/http/yaml-workflows.md) · [Users](docs/api/http/users.md) · [Roles](docs/api/http/roles.md) · [Service Accounts](docs/api/http/service-accounts.md) · [MCP Servers](docs/api/http/mcp-servers.md) · [Pipelines](docs/api/http/pipelines.md) · [Exports](docs/api/http/exports.md)
270
246
 
271
247
  **SDK:** [Overview](docs/sdk.md) · [Workflows](docs/api/sdk/workflows.md) · [Tasks](docs/api/sdk/tasks.md) · [Escalations](docs/api/sdk/escalations.md) · [YAML Workflows](docs/api/sdk/yaml-workflows.md) · [MCP](docs/api/sdk/mcp.md) · [Events](docs/api/sdk/events.md)
272
248
 
@@ -7,4 +7,18 @@ export declare function checkBulkPermission(userId: string, ids: string[]): Prom
7
7
  status: 403;
8
8
  error: string;
9
9
  }>;
10
+ /**
11
+ * Resolve an optional assignee external_id to an internal userId.
12
+ * When omitted, returns the caller's userId from auth.
13
+ */
14
+ export declare function resolveAssignee(assignee: string | undefined, auth: {
15
+ userId: string;
16
+ }): Promise<{
17
+ userId: string;
18
+ } | {
19
+ error: {
20
+ status: number;
21
+ error: string;
22
+ };
23
+ }>;
10
24
  export declare function publishBulkClaimEvents(ids: string[], assignedTo: string): void;
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.getVisibleRoles = getVisibleRoles;
37
37
  exports.validateIds = validateIds;
38
38
  exports.checkBulkPermission = checkBulkPermission;
39
+ exports.resolveAssignee = resolveAssignee;
39
40
  exports.publishBulkClaimEvents = publishBulkClaimEvents;
40
41
  const escalationService = __importStar(require("../../services/escalation"));
41
42
  const userService = __importStar(require("../../services/user"));
@@ -64,6 +65,19 @@ async function checkBulkPermission(userId, ids) {
64
65
  }
65
66
  return { allowed: true };
66
67
  }
68
+ /**
69
+ * Resolve an optional assignee external_id to an internal userId.
70
+ * When omitted, returns the caller's userId from auth.
71
+ */
72
+ async function resolveAssignee(assignee, auth) {
73
+ if (!assignee)
74
+ return { userId: auth.userId };
75
+ const user = await userService.getUserByExternalId(assignee);
76
+ if (!user) {
77
+ return { error: { status: 404, error: `User not found for external_id: ${assignee}` } };
78
+ }
79
+ return { userId: user.id };
80
+ }
67
81
  function publishBulkClaimEvents(ids, assignedTo) {
68
82
  for (const id of ids) {
69
83
  (0, publish_1.publishEscalationEvent)({
@@ -4,3 +4,4 @@ export { getEscalation, getEscalationsByWorkflowId, escalateToRole } from './sin
4
4
  export { claimEscalation, releaseEscalation } from './claim';
5
5
  export { releaseExpiredClaims, updatePriority, bulkClaim, bulkAssign, bulkEscalate, bulkTriage } from './bulk';
6
6
  export { resolveEscalation } from './resolve';
7
+ export { findByMetadata, claimByMetadata, resolveByMetadata } from './metadata';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getEscalationStats = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
3
+ exports.resolveByMetadata = exports.claimByMetadata = exports.findByMetadata = exports.resolveEscalation = exports.bulkTriage = exports.bulkEscalate = exports.bulkAssign = exports.bulkClaim = exports.updatePriority = exports.releaseExpiredClaims = exports.releaseEscalation = exports.claimEscalation = exports.escalateToRole = exports.getEscalationsByWorkflowId = exports.getEscalation = exports.getEscalationStats = exports.listDistinctTypes = exports.listAvailableEscalations = exports.listEscalations = exports.createEscalation = void 0;
4
4
  var create_1 = require("./create");
5
5
  Object.defineProperty(exports, "createEscalation", { enumerable: true, get: function () { return create_1.createEscalation; } });
6
6
  var list_1 = require("./list");
@@ -24,3 +24,7 @@ Object.defineProperty(exports, "bulkEscalate", { enumerable: true, get: function
24
24
  Object.defineProperty(exports, "bulkTriage", { enumerable: true, get: function () { return bulk_1.bulkTriage; } });
25
25
  var resolve_1 = require("./resolve");
26
26
  Object.defineProperty(exports, "resolveEscalation", { enumerable: true, get: function () { return resolve_1.resolveEscalation; } });
27
+ var metadata_1 = require("./metadata");
28
+ Object.defineProperty(exports, "findByMetadata", { enumerable: true, get: function () { return metadata_1.findByMetadata; } });
29
+ Object.defineProperty(exports, "claimByMetadata", { enumerable: true, get: function () { return metadata_1.claimByMetadata; } });
30
+ Object.defineProperty(exports, "resolveByMetadata", { enumerable: true, get: function () { return metadata_1.resolveByMetadata; } });
@@ -0,0 +1,56 @@
1
+ import type { LTApiAuth, LTApiResult } from '../../types/sdk';
2
+ /**
3
+ * Find escalations by a metadata key-value pair.
4
+ *
5
+ * Uses JSONB containment (`@>`) backed by a GIN index.
6
+ * Results are RBAC-scoped to the caller's visible roles.
7
+ *
8
+ * @param input.key — metadata field name (e.g. `"orderId"`)
9
+ * @param input.value — metadata field value (e.g. `"order-123"`)
10
+ * @param input.status — optional status filter (e.g. `"pending"`)
11
+ * @returns `{ status: 200, data: { escalations, total } }`
12
+ */
13
+ export declare function findByMetadata(input: {
14
+ key: string;
15
+ value: string;
16
+ status?: string;
17
+ limit?: number;
18
+ offset?: number;
19
+ }, auth: LTApiAuth): Promise<LTApiResult>;
20
+ /**
21
+ * Claim an escalation by metadata key-value pair.
22
+ *
23
+ * Finds one available (pending + unassigned/expired) escalation matching
24
+ * the metadata and claims it atomically. Optionally resolves an assignee
25
+ * from an external_id.
26
+ *
27
+ * @param input.key — metadata field name
28
+ * @param input.value — metadata field value
29
+ * @param input.durationMinutes — claim duration (default 30)
30
+ * @param input.assignee — optional external_id of the user to claim as
31
+ * @returns `{ status: 200, data: { escalation, isExtension } }`
32
+ */
33
+ export declare function claimByMetadata(input: {
34
+ key: string;
35
+ value: string;
36
+ durationMinutes?: number;
37
+ assignee?: string;
38
+ }, auth: LTApiAuth): Promise<LTApiResult>;
39
+ /**
40
+ * Resolve an escalation by metadata key-value pair.
41
+ *
42
+ * Finds the pending escalation, auto-claims if unclaimed, then delegates
43
+ * to the standard resolve logic (supports all 5 resolution paths).
44
+ *
45
+ * @param input.key — metadata field name
46
+ * @param input.value — metadata field value
47
+ * @param input.resolverPayload — resolution data for the workflow
48
+ * @param input.assignee — optional external_id of the resolving user
49
+ * @returns result from the standard resolve endpoint
50
+ */
51
+ export declare function resolveByMetadata(input: {
52
+ key: string;
53
+ value: string;
54
+ resolverPayload: Record<string, any>;
55
+ assignee?: string;
56
+ }, auth: LTApiAuth): Promise<LTApiResult>;
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.findByMetadata = findByMetadata;
37
+ exports.claimByMetadata = claimByMetadata;
38
+ exports.resolveByMetadata = resolveByMetadata;
39
+ const escalationService = __importStar(require("../../services/escalation"));
40
+ const userService = __importStar(require("../../services/user"));
41
+ const publish_1 = require("../../lib/events/publish");
42
+ const helpers_1 = require("./helpers");
43
+ /**
44
+ * Find escalations by a metadata key-value pair.
45
+ *
46
+ * Uses JSONB containment (`@>`) backed by a GIN index.
47
+ * Results are RBAC-scoped to the caller's visible roles.
48
+ *
49
+ * @param input.key — metadata field name (e.g. `"orderId"`)
50
+ * @param input.value — metadata field value (e.g. `"order-123"`)
51
+ * @param input.status — optional status filter (e.g. `"pending"`)
52
+ * @returns `{ status: 200, data: { escalations, total } }`
53
+ */
54
+ async function findByMetadata(input, auth) {
55
+ try {
56
+ if (!input.key || !input.value) {
57
+ return { status: 400, error: 'key and value are required' };
58
+ }
59
+ const result = await escalationService.findByMetadata(input.key, input.value, input.status, input.limit, input.offset);
60
+ // RBAC: scope to visible roles
61
+ const visibleRoles = await (0, helpers_1.getVisibleRoles)(auth.userId);
62
+ if (visibleRoles) {
63
+ const roleSet = new Set(visibleRoles);
64
+ result.escalations = result.escalations.filter(e => roleSet.has(e.role));
65
+ result.total = result.escalations.length;
66
+ }
67
+ return { status: 200, data: result };
68
+ }
69
+ catch (err) {
70
+ return { status: 500, error: err.message };
71
+ }
72
+ }
73
+ /**
74
+ * Claim an escalation by metadata key-value pair.
75
+ *
76
+ * Finds one available (pending + unassigned/expired) escalation matching
77
+ * the metadata and claims it atomically. Optionally resolves an assignee
78
+ * from an external_id.
79
+ *
80
+ * @param input.key — metadata field name
81
+ * @param input.value — metadata field value
82
+ * @param input.durationMinutes — claim duration (default 30)
83
+ * @param input.assignee — optional external_id of the user to claim as
84
+ * @returns `{ status: 200, data: { escalation, isExtension } }`
85
+ */
86
+ async function claimByMetadata(input, auth) {
87
+ try {
88
+ if (!input.key || !input.value) {
89
+ return { status: 400, error: 'key and value are required' };
90
+ }
91
+ const resolved = await (0, helpers_1.resolveAssignee)(input.assignee, auth);
92
+ if ('error' in resolved)
93
+ return resolved.error;
94
+ const claimUserId = resolved.userId;
95
+ // RBAC: find the candidate to check role membership before atomic claim
96
+ const candidates = await escalationService.findByMetadata(input.key, input.value, 'pending', 1, 0);
97
+ if (candidates.escalations.length === 0) {
98
+ return { status: 404, error: 'No pending escalation found for this metadata' };
99
+ }
100
+ const candidate = candidates.escalations[0];
101
+ const isSuperAdmin = await userService.isSuperAdmin(auth.userId);
102
+ if (!isSuperAdmin) {
103
+ const userHasRole = await userService.hasRole(claimUserId, candidate.role);
104
+ if (!userHasRole) {
105
+ return { status: 403, error: `User must have the "${candidate.role}" role to claim this escalation` };
106
+ }
107
+ }
108
+ const result = await escalationService.claimByMetadata(input.key, input.value, claimUserId, input.durationMinutes);
109
+ if (!result) {
110
+ return { status: 409, error: 'Escalation not available for claim' };
111
+ }
112
+ (0, publish_1.publishEscalationEvent)({
113
+ type: 'escalation.claimed',
114
+ source: 'api',
115
+ workflowId: result.escalation.workflow_id || '',
116
+ workflowName: result.escalation.workflow_type || '',
117
+ taskQueue: result.escalation.task_queue || '',
118
+ escalationId: result.escalation.id,
119
+ status: 'claimed',
120
+ data: { assigned_to: claimUserId },
121
+ });
122
+ return { status: 200, data: result };
123
+ }
124
+ catch (err) {
125
+ return { status: 500, error: err.message };
126
+ }
127
+ }
128
+ /**
129
+ * Resolve an escalation by metadata key-value pair.
130
+ *
131
+ * Finds the pending escalation, auto-claims if unclaimed, then delegates
132
+ * to the standard resolve logic (supports all 5 resolution paths).
133
+ *
134
+ * @param input.key — metadata field name
135
+ * @param input.value — metadata field value
136
+ * @param input.resolverPayload — resolution data for the workflow
137
+ * @param input.assignee — optional external_id of the resolving user
138
+ * @returns result from the standard resolve endpoint
139
+ */
140
+ async function resolveByMetadata(input, auth) {
141
+ try {
142
+ if (!input.key || !input.value) {
143
+ return { status: 400, error: 'key and value are required' };
144
+ }
145
+ if (!input.resolverPayload) {
146
+ return { status: 400, error: 'resolverPayload is required' };
147
+ }
148
+ const candidates = await escalationService.findByMetadata(input.key, input.value, 'pending', 1, 0);
149
+ if (candidates.escalations.length === 0) {
150
+ return { status: 404, error: 'No pending escalation found for this metadata' };
151
+ }
152
+ const escalation = candidates.escalations[0];
153
+ const resolved = await (0, helpers_1.resolveAssignee)(input.assignee, auth);
154
+ if ('error' in resolved)
155
+ return resolved.error;
156
+ const resolveUserId = resolved.userId;
157
+ const isSuperAdmin = await userService.isSuperAdmin(auth.userId);
158
+ if (!isSuperAdmin) {
159
+ const userHasRole = await userService.hasRole(resolveUserId, escalation.role);
160
+ if (!userHasRole) {
161
+ return { status: 403, error: `User must have the "${escalation.role}" role` };
162
+ }
163
+ }
164
+ // Auto-claim if unclaimed or expired
165
+ const isClaimed = escalation.assigned_to &&
166
+ escalation.assigned_until &&
167
+ new Date(escalation.assigned_until) > new Date();
168
+ if (!isClaimed) {
169
+ await escalationService.claimEscalation(escalation.id, resolveUserId, 5);
170
+ }
171
+ // Delegate to the full resolve logic (handles all 5 resolution paths)
172
+ const { resolveEscalation } = await Promise.resolve().then(() => __importStar(require('./resolve')));
173
+ return resolveEscalation({ id: escalation.id, resolverPayload: input.resolverPayload }, auth);
174
+ }
175
+ catch (err) {
176
+ return { status: 500, error: err.message };
177
+ }
178
+ }
@@ -6,7 +6,8 @@ export * as users from './users';
6
6
  export * as roles from './roles';
7
7
  export * as auth from './auth';
8
8
  export * as mcp from './mcp';
9
- export * as mcpRuns from './mcp-runs';
9
+ export * as pipelines from './pipelines';
10
+ export * as mcpRuns from './pipelines';
10
11
  export * as insight from './insight';
11
12
  export * as settings from './settings';
12
13
  export * as exports from './exports';