agor-live 0.23.1 → 0.23.2

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 (469) hide show
  1. package/dist/core/claude/index.cjs +51 -27
  2. package/dist/core/claude/index.js +51 -27
  3. package/dist/core/claude-cli/index.cjs +13 -0
  4. package/dist/core/claude-cli/index.js +13 -0
  5. package/dist/core/claude-cli/pricing.d.ts.map +1 -1
  6. package/dist/core/client/index.cjs +17 -0
  7. package/dist/core/client/index.js +16 -0
  8. package/dist/core/db/index.cjs +618 -421
  9. package/dist/core/db/index.js +550 -353
  10. package/dist/core/db/repositories/boards.d.ts +27 -0
  11. package/dist/core/db/repositories/boards.d.ts.map +1 -1
  12. package/dist/core/db/repositories/branches.d.ts +11 -1
  13. package/dist/core/db/repositories/branches.d.ts.map +1 -1
  14. package/dist/core/db/repositories/gateway-channels.d.ts +9 -0
  15. package/dist/core/db/repositories/gateway-channels.d.ts.map +1 -1
  16. package/dist/core/db/repositories/sessions.d.ts +7 -0
  17. package/dist/core/db/repositories/sessions.d.ts.map +1 -1
  18. package/dist/core/environment/render-snapshot.cjs +6 -2
  19. package/dist/core/environment/render-snapshot.d.ts +2 -0
  20. package/dist/core/environment/render-snapshot.d.ts.map +1 -1
  21. package/dist/core/environment/render-snapshot.js +6 -2
  22. package/dist/core/environment/variable-resolver.cjs +3 -1
  23. package/dist/core/environment/variable-resolver.js +3 -1
  24. package/dist/core/index.cjs +684 -486
  25. package/dist/core/index.js +684 -486
  26. package/dist/core/lib/feathers-validation.cjs +3 -0
  27. package/dist/core/lib/feathers-validation.d.ts +1 -0
  28. package/dist/core/lib/feathers-validation.d.ts.map +1 -1
  29. package/dist/core/lib/feathers-validation.js +3 -0
  30. package/dist/core/local-actions/index.cjs +123 -56
  31. package/dist/core/local-actions/index.js +121 -54
  32. package/dist/core/mcp/index.cjs +21 -3
  33. package/dist/core/mcp/index.d.ts +1 -1
  34. package/dist/core/mcp/index.d.ts.map +1 -1
  35. package/dist/core/mcp/index.js +18 -3
  36. package/dist/core/mcp/template-patterns.d.ts +15 -0
  37. package/dist/core/mcp/template-patterns.d.ts.map +1 -0
  38. package/dist/core/mcp/template-resolver.d.ts +13 -0
  39. package/dist/core/mcp/template-resolver.d.ts.map +1 -1
  40. package/dist/core/models/browser.cjs +6 -0
  41. package/dist/core/models/browser.js +6 -0
  42. package/dist/core/models/claude.d.ts.map +1 -1
  43. package/dist/core/models/index.cjs +6 -0
  44. package/dist/core/models/index.js +6 -0
  45. package/dist/core/seed/index.cjs +360 -216
  46. package/dist/core/seed/index.js +329 -185
  47. package/dist/core/templates/handlebars-helpers.cjs +3 -1
  48. package/dist/core/templates/handlebars-helpers.d.ts +5 -0
  49. package/dist/core/templates/handlebars-helpers.d.ts.map +1 -1
  50. package/dist/core/templates/handlebars-helpers.js +3 -1
  51. package/dist/core/tools/mcp/auth-secrets.cjs +3460 -3
  52. package/dist/core/tools/mcp/auth-secrets.d.ts.map +1 -1
  53. package/dist/core/tools/mcp/auth-secrets.js +3477 -3
  54. package/dist/core/tools/mcp/http-headers.cjs +17 -1
  55. package/dist/core/tools/mcp/http-headers.d.ts.map +1 -1
  56. package/dist/core/tools/mcp/http-headers.js +15 -1
  57. package/dist/core/tools/mcp/oauth-refresh.cjs +67 -43
  58. package/dist/core/tools/mcp/oauth-refresh.js +65 -41
  59. package/dist/core/types/board.d.ts +12 -0
  60. package/dist/core/types/board.d.ts.map +1 -1
  61. package/dist/core/types/gateway.d.ts +14 -0
  62. package/dist/core/types/gateway.d.ts.map +1 -1
  63. package/dist/core/types/index.cjs +17 -0
  64. package/dist/core/types/index.js +16 -0
  65. package/dist/core/unix/index.cjs +67 -0
  66. package/dist/core/unix/index.js +67 -0
  67. package/dist/daemon/auth/executor-runtime-scope.d.ts.map +1 -1
  68. package/dist/daemon/auth/executor-runtime-scope.js +19 -5
  69. package/dist/daemon/auth/executor-session-token.d.ts +15 -0
  70. package/dist/daemon/auth/executor-session-token.d.ts.map +1 -0
  71. package/dist/daemon/auth/executor-session-token.js +17 -0
  72. package/dist/daemon/auth/issue-browser-tokens-hook.d.ts +24 -0
  73. package/dist/daemon/auth/issue-browser-tokens-hook.d.ts.map +1 -0
  74. package/dist/daemon/auth/issue-browser-tokens-hook.js +95 -0
  75. package/dist/daemon/auth/service-jwt-strategy.d.ts.map +1 -1
  76. package/dist/daemon/auth/service-jwt-strategy.js +14 -2
  77. package/dist/daemon/declarations.d.ts +1 -0
  78. package/dist/daemon/declarations.d.ts.map +1 -1
  79. package/dist/daemon/index.js +1365 -418
  80. package/dist/daemon/main.js +1365 -418
  81. package/dist/daemon/mcp/server.js +294 -31
  82. package/dist/daemon/mcp/tools/analytics.js +73 -24
  83. package/dist/daemon/mcp/tools/artifacts.js +73 -24
  84. package/dist/daemon/mcp/tools/boards.js +73 -24
  85. package/dist/daemon/mcp/tools/branches.js +73 -24
  86. package/dist/daemon/mcp/tools/card-types.js +73 -24
  87. package/dist/daemon/mcp/tools/cards.js +73 -24
  88. package/dist/daemon/mcp/tools/environment.js +73 -24
  89. package/dist/daemon/mcp/tools/gateway-channels.d.ts.map +1 -1
  90. package/dist/daemon/mcp/tools/gateway-channels.js +190 -38
  91. package/dist/daemon/mcp/tools/knowledge.js +73 -24
  92. package/dist/daemon/mcp/tools/mcp-servers.js +73 -24
  93. package/dist/daemon/mcp/tools/messages.js +73 -24
  94. package/dist/daemon/mcp/tools/proxies.js +73 -24
  95. package/dist/daemon/mcp/tools/repos.js +73 -24
  96. package/dist/daemon/mcp/tools/schedules.js +73 -24
  97. package/dist/daemon/mcp/tools/search.js +73 -24
  98. package/dist/daemon/mcp/tools/sessions.js +73 -24
  99. package/dist/daemon/mcp/tools/tasks.js +73 -24
  100. package/dist/daemon/mcp/tools/users.js +76 -27
  101. package/dist/daemon/mcp/tools/widgets.d.ts.map +1 -1
  102. package/dist/daemon/mcp/tools/widgets.js +257 -99
  103. package/dist/daemon/oauth-auth-helpers.d.ts +35 -0
  104. package/dist/daemon/oauth-auth-helpers.d.ts.map +1 -0
  105. package/dist/daemon/oauth-auth-helpers.js +14 -0
  106. package/dist/daemon/register-hooks.d.ts +1 -0
  107. package/dist/daemon/register-hooks.d.ts.map +1 -1
  108. package/dist/daemon/register-hooks.js +304 -53
  109. package/dist/daemon/register-routes.d.ts.map +1 -1
  110. package/dist/daemon/register-routes.js +738 -288
  111. package/dist/daemon/register-services.d.ts.map +1 -1
  112. package/dist/daemon/register-services.js +386 -155
  113. package/dist/daemon/services/boards.d.ts +5 -0
  114. package/dist/daemon/services/boards.d.ts.map +1 -1
  115. package/dist/daemon/services/boards.js +7 -0
  116. package/dist/daemon/services/branches.d.ts.map +1 -1
  117. package/dist/daemon/services/branches.js +31 -2
  118. package/dist/daemon/services/claude-models.d.ts.map +1 -1
  119. package/dist/daemon/services/claude-models.js +4 -1
  120. package/dist/daemon/services/gateway.d.ts +15 -0
  121. package/dist/daemon/services/gateway.d.ts.map +1 -1
  122. package/dist/daemon/services/gateway.js +34 -0
  123. package/dist/daemon/services/health-monitor.d.ts.map +1 -1
  124. package/dist/daemon/services/health-monitor.js +10 -7
  125. package/dist/daemon/services/session-streams.d.ts +29 -0
  126. package/dist/daemon/services/session-streams.d.ts.map +1 -0
  127. package/dist/daemon/services/session-streams.js +84 -0
  128. package/dist/daemon/services/session-token-service.d.ts.map +1 -1
  129. package/dist/daemon/services/session-token-service.js +8 -4
  130. package/dist/daemon/setup/index.js +43 -11
  131. package/dist/daemon/setup/socketio.d.ts.map +1 -1
  132. package/dist/daemon/setup/socketio.js +43 -11
  133. package/dist/daemon/startup.d.ts.map +1 -1
  134. package/dist/daemon/startup.js +37 -16
  135. package/dist/daemon/utils/authorization.js +19 -5
  136. package/dist/daemon/utils/emit-service-event.d.ts +56 -0
  137. package/dist/daemon/utils/emit-service-event.d.ts.map +1 -0
  138. package/dist/daemon/utils/emit-service-event.js +23 -0
  139. package/dist/daemon/utils/mcp-header-secrets.d.ts +3 -5
  140. package/dist/daemon/utils/mcp-header-secrets.d.ts.map +1 -1
  141. package/dist/daemon/utils/mcp-header-secrets.js +31 -2
  142. package/dist/daemon/utils/realtime-access-cache.d.ts +9 -0
  143. package/dist/daemon/utils/realtime-access-cache.d.ts.map +1 -1
  144. package/dist/daemon/utils/realtime-access-cache.js +24 -0
  145. package/dist/daemon/utils/realtime-publish.d.ts +24 -0
  146. package/dist/daemon/utils/realtime-publish.d.ts.map +1 -1
  147. package/dist/daemon/utils/realtime-publish.js +120 -2
  148. package/dist/daemon/utils/session-queue-tenant-scope.d.ts +24 -0
  149. package/dist/daemon/utils/session-queue-tenant-scope.d.ts.map +1 -0
  150. package/dist/daemon/utils/session-queue-tenant-scope.js +133 -0
  151. package/dist/daemon/widgets/gateway-token/index.d.ts +114 -0
  152. package/dist/daemon/widgets/gateway-token/index.d.ts.map +1 -0
  153. package/dist/daemon/widgets/gateway-token/index.js +14711 -0
  154. package/dist/daemon/widgets/index.d.ts.map +1 -1
  155. package/dist/daemon/widgets/index.js +190 -16
  156. package/dist/daemon/widgets/registry.d.ts +7 -0
  157. package/dist/daemon/widgets/registry.d.ts.map +1 -1
  158. package/dist/daemon/widgets/submissions.js +12 -9
  159. package/dist/executor/commands/git.d.ts.map +1 -1
  160. package/dist/executor/commands/git.js +2 -0
  161. package/dist/executor/db/feathers-repositories.d.ts +19 -1
  162. package/dist/executor/db/feathers-repositories.d.ts.map +1 -1
  163. package/dist/executor/db/feathers-repositories.js +31 -1
  164. package/dist/executor/handlers/sdk/claude.d.ts.map +1 -1
  165. package/dist/executor/handlers/sdk/claude.js +1 -1
  166. package/dist/executor/handlers/sdk/codex.d.ts.map +1 -1
  167. package/dist/executor/handlers/sdk/codex.js +1 -1
  168. package/dist/executor/handlers/sdk/copilot.d.ts.map +1 -1
  169. package/dist/executor/handlers/sdk/copilot.js +1 -1
  170. package/dist/executor/handlers/sdk/cursor.d.ts.map +1 -1
  171. package/dist/executor/handlers/sdk/cursor.js +1 -0
  172. package/dist/executor/handlers/sdk/gemini.d.ts.map +1 -1
  173. package/dist/executor/handlers/sdk/gemini.js +1 -1
  174. package/dist/executor/handlers/sdk/opencode.d.ts.map +1 -1
  175. package/dist/executor/handlers/sdk/opencode.js +1 -1
  176. package/dist/executor/payload-types.d.ts +5 -5
  177. package/dist/executor/sdk-handlers/base/mcp-scoping.d.ts +8 -1
  178. package/dist/executor/sdk-handlers/base/mcp-scoping.d.ts.map +1 -1
  179. package/dist/executor/sdk-handlers/base/mcp-scoping.js +58 -6
  180. package/dist/executor/sdk-handlers/claude/claude-tool.d.ts +2 -2
  181. package/dist/executor/sdk-handlers/claude/claude-tool.d.ts.map +1 -1
  182. package/dist/executor/sdk-handlers/claude/claude-tool.js +2 -2
  183. package/dist/executor/sdk-handlers/claude/prompt-service.d.ts +13 -3
  184. package/dist/executor/sdk-handlers/claude/prompt-service.d.ts.map +1 -1
  185. package/dist/executor/sdk-handlers/claude/prompt-service.js +16 -3
  186. package/dist/executor/sdk-handlers/claude/query-builder.d.ts +2 -1
  187. package/dist/executor/sdk-handlers/claude/query-builder.d.ts.map +1 -1
  188. package/dist/executor/sdk-handlers/claude/query-builder.js +2 -1
  189. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts +2 -2
  190. package/dist/executor/sdk-handlers/codex/codex-tool.d.ts.map +1 -1
  191. package/dist/executor/sdk-handlers/codex/codex-tool.js +2 -2
  192. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts +3 -2
  193. package/dist/executor/sdk-handlers/codex/prompt-service.d.ts.map +1 -1
  194. package/dist/executor/sdk-handlers/codex/prompt-service.js +70 -6
  195. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts +2 -2
  196. package/dist/executor/sdk-handlers/copilot/copilot-tool.d.ts.map +1 -1
  197. package/dist/executor/sdk-handlers/copilot/copilot-tool.js +2 -2
  198. package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts +3 -2
  199. package/dist/executor/sdk-handlers/copilot/prompt-service.d.ts.map +1 -1
  200. package/dist/executor/sdk-handlers/copilot/prompt-service.js +4 -1
  201. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts +2 -2
  202. package/dist/executor/sdk-handlers/gemini/gemini-tool.d.ts.map +1 -1
  203. package/dist/executor/sdk-handlers/gemini/gemini-tool.js +2 -2
  204. package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts +3 -2
  205. package/dist/executor/sdk-handlers/gemini/prompt-service.d.ts.map +1 -1
  206. package/dist/executor/sdk-handlers/gemini/prompt-service.js +4 -1
  207. package/dist/executor/sdk-handlers/opencode/opencode-tool.d.ts +3 -2
  208. package/dist/executor/sdk-handlers/opencode/opencode-tool.d.ts.map +1 -1
  209. package/dist/executor/sdk-handlers/opencode/opencode-tool.js +4 -1
  210. package/dist/executor/services/feathers-client.d.ts.map +1 -1
  211. package/dist/executor/services/feathers-client.js +119 -20
  212. package/dist/ui/assets/AgorEmojiPickerInner-leeNywMc.js +1 -0
  213. package/dist/ui/assets/App-Dpl4Cc0U.js +4 -0
  214. package/dist/ui/assets/App-Dpl4Cc0U.js.gz +0 -0
  215. package/dist/ui/assets/AppNode-wN3UZlFK.js +1 -0
  216. package/dist/ui/assets/AppNode-wN3UZlFK.js.gz +0 -0
  217. package/dist/ui/assets/{ArtifactConsentModal-oMMzRn8L.js → ArtifactConsentModal-DjzXcP_L.js} +1 -1
  218. package/dist/ui/assets/ArtifactConsentModal-DjzXcP_L.js.gz +0 -0
  219. package/dist/ui/assets/ArtifactFullscreenPage-B3b_EZ0F.js +9 -0
  220. package/dist/ui/assets/ArtifactFullscreenPage-B3b_EZ0F.js.gz +0 -0
  221. package/dist/ui/assets/ArtifactNode-DISy2T-6.js +9 -0
  222. package/dist/ui/assets/ArtifactNode-DISy2T-6.js.gz +0 -0
  223. package/dist/ui/assets/AutocompleteTextarea-DUpsoEGr.js +19 -0
  224. package/dist/ui/assets/AutocompleteTextarea-DUpsoEGr.js.gz +0 -0
  225. package/dist/ui/assets/BoardObjectNodes-BakeGpIX.js +34 -0
  226. package/dist/ui/assets/BoardObjectNodes-BakeGpIX.js.gz +0 -0
  227. package/dist/ui/assets/{CodeEditor.inner-Cuj6RuLL.js → CodeEditor.inner-HmSdTLW5.js} +1 -1
  228. package/dist/ui/assets/CodeEditor.inner-HmSdTLW5.js.gz +0 -0
  229. package/dist/ui/assets/ConversationView-mWaA-B1f.js +1 -0
  230. package/dist/ui/assets/ConversationView-mWaA-B1f.js.gz +0 -0
  231. package/dist/ui/assets/{EmbeddedTerminal-Lx5I9EOJ.js → EmbeddedTerminal-NNoyPA81.js} +1 -1
  232. package/dist/ui/assets/EmbeddedTerminal-NNoyPA81.js.gz +0 -0
  233. package/dist/ui/assets/KnowledgePage-CkxVnRvz.js +24 -0
  234. package/dist/ui/assets/KnowledgePage-CkxVnRvz.js.gz +0 -0
  235. package/dist/ui/assets/{MarketingScreenshotPage-CmDPBHOl.js → MarketingScreenshotPage-B86Gs8jx.js} +2 -2
  236. package/dist/ui/assets/MarketingScreenshotPage-B86Gs8jx.js.gz +0 -0
  237. package/dist/ui/assets/MobileApp-BPs-SXvz.js +1 -0
  238. package/dist/ui/assets/MobileApp-BPs-SXvz.js.gz +0 -0
  239. package/dist/ui/assets/SessionCanvas-xVfDoEtz.js +13 -0
  240. package/dist/ui/assets/SessionCanvas-xVfDoEtz.js.gz +0 -0
  241. package/dist/ui/assets/{StreamdownDemoPage-okKKR2QH.js → StreamdownDemoPage-CvWLzVsv.js} +2 -2
  242. package/dist/ui/assets/StreamdownDemoPage-CvWLzVsv.js.gz +0 -0
  243. package/dist/ui/assets/{TerminalModal-D9jMGZXv.js → TerminalModal-ExOgsuOP.js} +2 -2
  244. package/dist/ui/assets/TerminalModal-ExOgsuOP.js.gz +0 -0
  245. package/dist/ui/assets/ThemeSwitcher-Cgyp5ruu.js +1 -0
  246. package/dist/ui/assets/ThemeSwitcher-Cgyp5ruu.js.gz +0 -0
  247. package/dist/ui/assets/{ThemedSyntaxHighlighter.inner-C1FdIHn0.js → ThemedSyntaxHighlighter.inner-rpCN9S6K.js} +1 -1
  248. package/dist/ui/assets/{antd-DT5ackd0.js → antd-BCqimh1J.js} +5 -5
  249. package/dist/ui/assets/{antd-DT5ackd0.js.gz → antd-BCqimh1J.js.gz} +0 -0
  250. package/dist/ui/assets/architecture-U656AL7Q-BxSQIjrE.js +1 -0
  251. package/dist/ui/assets/{architectureDiagram-VXUJARFQ-DwTJGGoj.js → architectureDiagram-VXUJARFQ-pDpGHSqT.js} +1 -1
  252. package/dist/ui/assets/architectureDiagram-VXUJARFQ-pDpGHSqT.js.gz +0 -0
  253. package/dist/ui/assets/{blockDiagram-VD42YOAC-Dh1_TVW2.js → blockDiagram-VD42YOAC-uP8JTJpK.js} +1 -1
  254. package/dist/ui/assets/blockDiagram-VD42YOAC-uP8JTJpK.js.gz +0 -0
  255. package/dist/ui/assets/{c4Diagram-YG6GDRKO-B1e96AcB.js → c4Diagram-YG6GDRKO-qQe72Mm7.js} +1 -1
  256. package/dist/ui/assets/c4Diagram-YG6GDRKO-qQe72Mm7.js.gz +0 -0
  257. package/dist/ui/assets/channel-CoUBs6Zn.js +1 -0
  258. package/dist/ui/assets/{chunk-4BX2VUAB-BODpCjJx.js → chunk-4BX2VUAB-sz-YE8Nt.js} +1 -1
  259. package/dist/ui/assets/chunk-4ZMWKKQ3-3oKtfWXp.js +3 -0
  260. package/dist/ui/assets/chunk-4ZMWKKQ3-3oKtfWXp.js.gz +0 -0
  261. package/dist/ui/assets/chunk-55IACEB6-BS04dgKF.js +1 -0
  262. package/dist/ui/assets/{chunk-ABZYJK2D-DCTXWSzV.js → chunk-ABZYJK2D-t3Gkphds.js} +3 -3
  263. package/dist/ui/assets/chunk-ABZYJK2D-t3Gkphds.js.gz +0 -0
  264. package/dist/ui/assets/{chunk-AGHRB4JF-CbNphBjE.js → chunk-AGHRB4JF-D_QmWxbY.js} +1 -1
  265. package/dist/ui/assets/chunk-AGHRB4JF-D_QmWxbY.js.gz +0 -0
  266. package/dist/ui/assets/{chunk-ATLVNIR6-rWg3qxof.js → chunk-ATLVNIR6-Bmg7-Ufz.js} +1 -1
  267. package/dist/ui/assets/chunk-ATLVNIR6-Bmg7-Ufz.js.gz +0 -0
  268. package/dist/ui/assets/{chunk-B4BG7PRW-CgtLCbpE.js → chunk-B4BG7PRW-dnSEE1u-.js} +1 -1
  269. package/dist/ui/assets/chunk-B4BG7PRW-dnSEE1u-.js.gz +0 -0
  270. package/dist/ui/assets/{chunk-CVBHYZKI-DTL6Zgr0.js → chunk-CVBHYZKI-BStaYnF0.js} +1 -1
  271. package/dist/ui/assets/{chunk-DI55MBZ5-Dwvx2Kva.js → chunk-DI55MBZ5-28dvx6o3.js} +1 -1
  272. package/dist/ui/assets/chunk-DI55MBZ5-28dvx6o3.js.gz +0 -0
  273. package/dist/ui/assets/chunk-EXTU4WIE-X-FURkEh.js +1 -0
  274. package/dist/ui/assets/{chunk-FMBD7UC4-BogA_9CV.js → chunk-FMBD7UC4-C_63gC9S.js} +1 -1
  275. package/dist/ui/assets/{chunk-HN2XXSSU-2blQO3Gb.js → chunk-HN2XXSSU-UFD374KI.js} +1 -1
  276. package/dist/ui/assets/chunk-HN2XXSSU-UFD374KI.js.gz +0 -0
  277. package/dist/ui/assets/{chunk-JA3XYJ7Z-Cr1rmOui.js → chunk-JA3XYJ7Z-B60hLNeR.js} +1 -1
  278. package/dist/ui/assets/chunk-JA3XYJ7Z-B60hLNeR.js.gz +0 -0
  279. package/dist/ui/assets/{chunk-JZLCHNYA-BsgZ79Fa.js → chunk-JZLCHNYA-ButC6pwN.js} +1 -1
  280. package/dist/ui/assets/chunk-JZLCHNYA-ButC6pwN.js.gz +0 -0
  281. package/dist/ui/assets/{chunk-MI3HLSF2-dwYeUy5S.js → chunk-MI3HLSF2-BivYzoSV.js} +1 -1
  282. package/dist/ui/assets/chunk-MI3HLSF2-BivYzoSV.js.gz +0 -0
  283. package/dist/ui/assets/chunk-N4CR4FBY-mVWzo5wJ.js +2 -0
  284. package/dist/ui/assets/chunk-N4CR4FBY-mVWzo5wJ.js.gz +0 -0
  285. package/dist/ui/assets/{chunk-QN33PNHL-DxdIDCAa.js → chunk-QN33PNHL-tXtHZpaG.js} +1 -1
  286. package/dist/ui/assets/{chunk-QXUST7PY-BCK2V0i-.js → chunk-QXUST7PY-DATib_Vv.js} +1 -1
  287. package/dist/ui/assets/chunk-QXUST7PY-DATib_Vv.js.gz +0 -0
  288. package/dist/ui/assets/chunk-QZHKN3VN-y6l249e5.js +1 -0
  289. package/dist/ui/assets/{chunk-S3R3BYOJ-GP3zIxrB.js → chunk-S3R3BYOJ-BEtfmflI.js} +1 -1
  290. package/dist/ui/assets/chunk-S3R3BYOJ-BEtfmflI.js.gz +0 -0
  291. package/dist/ui/assets/{chunk-TZMSLE5B-dX5RaM6g.js → chunk-TZMSLE5B-BY1ZtogK.js} +1 -1
  292. package/dist/ui/assets/chunk-TZMSLE5B-BY1ZtogK.js.gz +0 -0
  293. package/dist/ui/assets/classDiagram-2ON5EDUG-BYvq-uPY.js +1 -0
  294. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-BYvq-uPY.js +1 -0
  295. package/dist/ui/assets/constants-CYzQKfD1.js +1 -0
  296. package/dist/ui/assets/{cose-bilkent-S5V4N54A-Dx0BJVDl.js → cose-bilkent-S5V4N54A-DPvYrqGG.js} +1 -1
  297. package/dist/ui/assets/cose-bilkent-S5V4N54A-DPvYrqGG.js.gz +0 -0
  298. package/dist/ui/assets/{dagre-6UL2VRFP-DiQSUxqN.js → dagre-6UL2VRFP-D800J6qb.js} +1 -1
  299. package/dist/ui/assets/dagre-6UL2VRFP-D800J6qb.js.gz +0 -0
  300. package/dist/ui/assets/{dagre-Bekd9Vdj.js → dagre-TNc4wezg.js} +1 -1
  301. package/dist/ui/assets/dagre-TNc4wezg.js.gz +0 -0
  302. package/dist/ui/assets/{diagram-PSM6KHXK-DtJnDQjc.js → diagram-PSM6KHXK-CGdP9F-X.js} +1 -1
  303. package/dist/ui/assets/diagram-PSM6KHXK-CGdP9F-X.js.gz +0 -0
  304. package/dist/ui/assets/{diagram-QEK2KX5R-CobkCRdj.js → diagram-QEK2KX5R-BD5lOCe5.js} +1 -1
  305. package/dist/ui/assets/diagram-QEK2KX5R-BD5lOCe5.js.gz +0 -0
  306. package/dist/ui/assets/{diagram-S2PKOQOG-DHEZYivc.js → diagram-S2PKOQOG-cp3l22vN.js} +1 -1
  307. package/dist/ui/assets/diagram-S2PKOQOG-cp3l22vN.js.gz +0 -0
  308. package/dist/ui/assets/editor-Cr0W5BQI.js +39 -0
  309. package/dist/ui/assets/editor-Cr0W5BQI.js.gz +0 -0
  310. package/dist/ui/assets/{emoji-B0hLmSLZ.js → emoji-Bv3m24sO.js} +1 -1
  311. package/dist/ui/assets/emoji-Bv3m24sO.js.gz +0 -0
  312. package/dist/ui/assets/{erDiagram-Q2GNP2WA-BVNeTZPQ.js → erDiagram-Q2GNP2WA-CQSXRgqr.js} +1 -1
  313. package/dist/ui/assets/erDiagram-Q2GNP2WA-CQSXRgqr.js.gz +0 -0
  314. package/dist/ui/assets/{flowDiagram-NV44I4VS-C73VFdyk.js → flowDiagram-NV44I4VS-CKcKpkph.js} +1 -1
  315. package/dist/ui/assets/flowDiagram-NV44I4VS-CKcKpkph.js.gz +0 -0
  316. package/dist/ui/assets/{ganttDiagram-LVOFAZNH-B_RosuD1.js → ganttDiagram-LVOFAZNH-DlAHzXO5.js} +1 -1
  317. package/dist/ui/assets/ganttDiagram-LVOFAZNH-DlAHzXO5.js.gz +0 -0
  318. package/dist/ui/assets/{gitGraph-F6HP7TQM-DMFIqn4h.js → gitGraph-F6HP7TQM-DeuXy4B1.js} +1 -1
  319. package/dist/ui/assets/{gitGraphDiagram-NY62KEGX-hxbgwNA1.js → gitGraphDiagram-NY62KEGX-aB-AI4Vq.js} +1 -1
  320. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-aB-AI4Vq.js.gz +0 -0
  321. package/dist/ui/assets/index-B-qHc0o5.js +63 -0
  322. package/dist/ui/assets/index-B-qHc0o5.js.gz +0 -0
  323. package/dist/ui/assets/{info-NVLQJR56-DZ3K-w48.js → info-NVLQJR56-B9PG7xsc.js} +1 -1
  324. package/dist/ui/assets/{infoDiagram-ER5ION4S-CxnBJQu6.js → infoDiagram-ER5ION4S-C5Wpoqim.js} +1 -1
  325. package/dist/ui/assets/{journeyDiagram-XKPGCS4Q-CHYNj-f8.js → journeyDiagram-XKPGCS4Q-CHLziqfS.js} +1 -1
  326. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CHLziqfS.js.gz +0 -0
  327. package/dist/ui/assets/{kanban-definition-3W4ZIXB7-DQPCCsj2.js → kanban-definition-3W4ZIXB7-Dq7GzQE_.js} +1 -1
  328. package/dist/ui/assets/kanban-definition-3W4ZIXB7-Dq7GzQE_.js.gz +0 -0
  329. package/dist/ui/assets/{line-DBRjKmfa.js → line-DHKNg83I.js} +1 -1
  330. package/dist/ui/assets/{linear-DFao5Wyp.js → linear-BvUfn0I8.js} +1 -1
  331. package/dist/ui/assets/linear-BvUfn0I8.js.gz +0 -0
  332. package/dist/ui/assets/{mermaid-parser.core-DYCfacHj.js → mermaid-parser.core-C6d9tKoo.js} +2 -2
  333. package/dist/ui/assets/mermaid-parser.core-C6d9tKoo.js.gz +0 -0
  334. package/dist/ui/assets/{mermaid.core-C6xGFSdE.js → mermaid.core-CxE5KezR.js} +3 -3
  335. package/dist/ui/assets/mermaid.core-CxE5KezR.js.gz +0 -0
  336. package/dist/ui/assets/{mindmap-definition-VGOIOE7T-L3Pw-YM7.js → mindmap-definition-VGOIOE7T-DmPoQ48w.js} +1 -1
  337. package/dist/ui/assets/mindmap-definition-VGOIOE7T-DmPoQ48w.js.gz +0 -0
  338. package/dist/ui/assets/{packet-BFZMPI3H-CpL6iNoa.js → packet-BFZMPI3H-JZEkVZxU.js} +1 -1
  339. package/dist/ui/assets/{particles-CT8hcJOA.js → particles-CxMmUw86.js} +1 -1
  340. package/dist/ui/assets/particles-CxMmUw86.js.gz +0 -0
  341. package/dist/ui/assets/{pie-7BOR55EZ-hTqChbTo.js → pie-7BOR55EZ-_1II5pYQ.js} +1 -1
  342. package/dist/ui/assets/{pieDiagram-ADFJNKIX-Bf4Nou75.js → pieDiagram-ADFJNKIX-DrNkH33i.js} +1 -1
  343. package/dist/ui/assets/pieDiagram-ADFJNKIX-DrNkH33i.js.gz +0 -0
  344. package/dist/ui/assets/{quadrantDiagram-AYHSOK5B-DpjUTLB1.js → quadrantDiagram-AYHSOK5B-DOpC-HEF.js} +1 -1
  345. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DOpC-HEF.js.gz +0 -0
  346. package/dist/ui/assets/{radar-NHE76QYJ-myy7OENC.js → radar-NHE76QYJ-DDmqhzEZ.js} +1 -1
  347. package/dist/ui/assets/{reactflow-Cubtnk8i.js → reactflow-D98uPOMq.js} +1 -1
  348. package/dist/ui/assets/reactflow-D98uPOMq.js.gz +0 -0
  349. package/dist/ui/assets/{requirementDiagram-UZGBJVZJ-Bfrfh-0-.js → requirementDiagram-UZGBJVZJ-Bzx0iEPP.js} +1 -1
  350. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-Bzx0iEPP.js.gz +0 -0
  351. package/dist/ui/assets/{sandpack-C58bwfIS.js → sandpack-059Z4UWP.js} +1 -1
  352. package/dist/ui/assets/sandpack-059Z4UWP.js.gz +0 -0
  353. package/dist/ui/assets/sandpackDefaults-CPMNDsw7.js +1 -0
  354. package/dist/ui/assets/sandpackDefaults-CPMNDsw7.js.gz +0 -0
  355. package/dist/ui/assets/{sankeyDiagram-TZEHDZUN-ClZAZ6va.js → sankeyDiagram-TZEHDZUN-Do9pvfDv.js} +1 -1
  356. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-Do9pvfDv.js.gz +0 -0
  357. package/dist/ui/assets/{sequenceDiagram-WL72ISMW-CNgly63p.js → sequenceDiagram-WL72ISMW-CN8neUTA.js} +1 -1
  358. package/dist/ui/assets/sequenceDiagram-WL72ISMW-CN8neUTA.js.gz +0 -0
  359. package/dist/ui/assets/{src-DAeyG22O.js → src-DEbsv3pp.js} +2 -2
  360. package/dist/ui/assets/src-DEbsv3pp.js.gz +0 -0
  361. package/dist/ui/assets/{stateDiagram-FKZM4ZOC-BrEAoDpE.js → stateDiagram-FKZM4ZOC-BluWJi8n.js} +1 -1
  362. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BluWJi8n.js.gz +0 -0
  363. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-DeyqBMDR.js +1 -0
  364. package/dist/ui/assets/{streamdown-BdAVfkeF.js → streamdown-BT1twtFc.js} +5 -5
  365. package/dist/ui/assets/streamdown-BT1twtFc.js.gz +0 -0
  366. package/dist/ui/assets/{syntax-BOfTnQiy.js → syntax-CBu6nLfm.js} +1 -1
  367. package/dist/ui/assets/syntax-CBu6nLfm.js.gz +0 -0
  368. package/dist/ui/assets/{timeline-definition-IT6M3QCI-CaRH3k4l.js → timeline-definition-IT6M3QCI-WdUNkiRj.js} +1 -1
  369. package/dist/ui/assets/timeline-definition-IT6M3QCI-WdUNkiRj.js.gz +0 -0
  370. package/dist/ui/assets/{treemap-KMMF4GRG-CUaLOV_B.js → treemap-KMMF4GRG-CoriU4Jl.js} +1 -1
  371. package/dist/ui/assets/{useUserLocalStorage-C8sgXgXR.js → useUserLocalStorage-GidNiOPC.js} +1 -1
  372. package/dist/ui/assets/useUserLocalStorage-GidNiOPC.js.gz +0 -0
  373. package/dist/ui/assets/{xychartDiagram-PRI3JC2R-BlhkI9T_.js → xychartDiagram-PRI3JC2R-CgBAKNt2.js} +1 -1
  374. package/dist/ui/assets/xychartDiagram-PRI3JC2R-CgBAKNt2.js.gz +0 -0
  375. package/dist/ui/index.html +9 -8
  376. package/dist/ui/index.html.gz +0 -0
  377. package/package.json +2 -2
  378. package/dist/ui/assets/AgorEmojiPickerInner-DQjr8M3_.js +0 -1
  379. package/dist/ui/assets/App-hJtcOxHv.js +0 -5
  380. package/dist/ui/assets/App-hJtcOxHv.js.gz +0 -0
  381. package/dist/ui/assets/AppNode-BhuMpn8O.js +0 -1
  382. package/dist/ui/assets/AppNode-BhuMpn8O.js.gz +0 -0
  383. package/dist/ui/assets/ArtifactConsentModal-oMMzRn8L.js.gz +0 -0
  384. package/dist/ui/assets/ArtifactFullscreenPage-B3wT8t8f.js +0 -9
  385. package/dist/ui/assets/ArtifactFullscreenPage-B3wT8t8f.js.gz +0 -0
  386. package/dist/ui/assets/ArtifactNode-BzQcrwFS.js +0 -9
  387. package/dist/ui/assets/ArtifactNode-BzQcrwFS.js.gz +0 -0
  388. package/dist/ui/assets/AutocompleteTextarea-Dau-V_30.js +0 -19
  389. package/dist/ui/assets/AutocompleteTextarea-Dau-V_30.js.gz +0 -0
  390. package/dist/ui/assets/BoardObjectNodes-DdKWv_ZT.js +0 -34
  391. package/dist/ui/assets/BoardObjectNodes-DdKWv_ZT.js.gz +0 -0
  392. package/dist/ui/assets/CodeEditor.inner-Cuj6RuLL.js.gz +0 -0
  393. package/dist/ui/assets/ConversationView-9-3ma1u-.js +0 -1
  394. package/dist/ui/assets/ConversationView-9-3ma1u-.js.gz +0 -0
  395. package/dist/ui/assets/EmbeddedTerminal-Lx5I9EOJ.js.gz +0 -0
  396. package/dist/ui/assets/KnowledgePage-Dz8YAMYC.js +0 -24
  397. package/dist/ui/assets/KnowledgePage-Dz8YAMYC.js.gz +0 -0
  398. package/dist/ui/assets/MarketingScreenshotPage-CmDPBHOl.js.gz +0 -0
  399. package/dist/ui/assets/MobileApp-BpgSG_gz.js +0 -1
  400. package/dist/ui/assets/MobileApp-BpgSG_gz.js.gz +0 -0
  401. package/dist/ui/assets/SessionCanvas-B6_mtlxK.js +0 -13
  402. package/dist/ui/assets/SessionCanvas-B6_mtlxK.js.gz +0 -0
  403. package/dist/ui/assets/StreamdownDemoPage-okKKR2QH.js.gz +0 -0
  404. package/dist/ui/assets/TerminalModal-D9jMGZXv.js.gz +0 -0
  405. package/dist/ui/assets/ThemeSwitcher-D9HgT37l.js +0 -1
  406. package/dist/ui/assets/ThemeSwitcher-D9HgT37l.js.gz +0 -0
  407. package/dist/ui/assets/architecture-U656AL7Q-DMnxkQRZ.js +0 -1
  408. package/dist/ui/assets/architectureDiagram-VXUJARFQ-DwTJGGoj.js.gz +0 -0
  409. package/dist/ui/assets/blockDiagram-VD42YOAC-Dh1_TVW2.js.gz +0 -0
  410. package/dist/ui/assets/c4Diagram-YG6GDRKO-B1e96AcB.js.gz +0 -0
  411. package/dist/ui/assets/channel-Jv4dT4S5.js +0 -1
  412. package/dist/ui/assets/chunk-55IACEB6-lJXvUquf.js +0 -1
  413. package/dist/ui/assets/chunk-ABZYJK2D-DCTXWSzV.js.gz +0 -0
  414. package/dist/ui/assets/chunk-AGHRB4JF-CbNphBjE.js.gz +0 -0
  415. package/dist/ui/assets/chunk-ATLVNIR6-rWg3qxof.js.gz +0 -0
  416. package/dist/ui/assets/chunk-B4BG7PRW-CgtLCbpE.js.gz +0 -0
  417. package/dist/ui/assets/chunk-DI55MBZ5-Dwvx2Kva.js.gz +0 -0
  418. package/dist/ui/assets/chunk-EXTU4WIE-DHyaqTsP.js +0 -1
  419. package/dist/ui/assets/chunk-HN2XXSSU-2blQO3Gb.js.gz +0 -0
  420. package/dist/ui/assets/chunk-JA3XYJ7Z-Cr1rmOui.js.gz +0 -0
  421. package/dist/ui/assets/chunk-JZLCHNYA-BsgZ79Fa.js.gz +0 -0
  422. package/dist/ui/assets/chunk-MI3HLSF2-dwYeUy5S.js.gz +0 -0
  423. package/dist/ui/assets/chunk-N4CR4FBY-DEMgSRVe.js +0 -2
  424. package/dist/ui/assets/chunk-N4CR4FBY-DEMgSRVe.js.gz +0 -0
  425. package/dist/ui/assets/chunk-QXUST7PY-BCK2V0i-.js.gz +0 -0
  426. package/dist/ui/assets/chunk-QZHKN3VN-CALjGrEE.js +0 -1
  427. package/dist/ui/assets/chunk-S3R3BYOJ-GP3zIxrB.js.gz +0 -0
  428. package/dist/ui/assets/chunk-TZMSLE5B-dX5RaM6g.js.gz +0 -0
  429. package/dist/ui/assets/classDiagram-2ON5EDUG-C3_RVP70.js +0 -1
  430. package/dist/ui/assets/classDiagram-v2-WZHVMYZB-C3_RVP70.js +0 -1
  431. package/dist/ui/assets/constants-GjIDNVyt.js +0 -1
  432. package/dist/ui/assets/cose-bilkent-S5V4N54A-Dx0BJVDl.js.gz +0 -0
  433. package/dist/ui/assets/dagre-6UL2VRFP-DiQSUxqN.js.gz +0 -0
  434. package/dist/ui/assets/dagre-Bekd9Vdj.js.gz +0 -0
  435. package/dist/ui/assets/diagram-PSM6KHXK-DtJnDQjc.js.gz +0 -0
  436. package/dist/ui/assets/diagram-QEK2KX5R-CobkCRdj.js.gz +0 -0
  437. package/dist/ui/assets/diagram-S2PKOQOG-DHEZYivc.js.gz +0 -0
  438. package/dist/ui/assets/editor-DQIG-JYZ.js +0 -43
  439. package/dist/ui/assets/editor-DQIG-JYZ.js.gz +0 -0
  440. package/dist/ui/assets/emoji-B0hLmSLZ.js.gz +0 -0
  441. package/dist/ui/assets/erDiagram-Q2GNP2WA-BVNeTZPQ.js.gz +0 -0
  442. package/dist/ui/assets/flowDiagram-NV44I4VS-C73VFdyk.js.gz +0 -0
  443. package/dist/ui/assets/ganttDiagram-LVOFAZNH-B_RosuD1.js.gz +0 -0
  444. package/dist/ui/assets/gitGraphDiagram-NY62KEGX-hxbgwNA1.js.gz +0 -0
  445. package/dist/ui/assets/index-DTz1Dif6.js +0 -64
  446. package/dist/ui/assets/index-DTz1Dif6.js.gz +0 -0
  447. package/dist/ui/assets/journeyDiagram-XKPGCS4Q-CHYNj-f8.js.gz +0 -0
  448. package/dist/ui/assets/kanban-definition-3W4ZIXB7-DQPCCsj2.js.gz +0 -0
  449. package/dist/ui/assets/linear-DFao5Wyp.js.gz +0 -0
  450. package/dist/ui/assets/mermaid-parser.core-DYCfacHj.js.gz +0 -0
  451. package/dist/ui/assets/mermaid.core-C6xGFSdE.js.gz +0 -0
  452. package/dist/ui/assets/mindmap-definition-VGOIOE7T-L3Pw-YM7.js.gz +0 -0
  453. package/dist/ui/assets/particles-CT8hcJOA.js.gz +0 -0
  454. package/dist/ui/assets/pieDiagram-ADFJNKIX-Bf4Nou75.js.gz +0 -0
  455. package/dist/ui/assets/quadrantDiagram-AYHSOK5B-DpjUTLB1.js.gz +0 -0
  456. package/dist/ui/assets/reactflow-Cubtnk8i.js.gz +0 -0
  457. package/dist/ui/assets/requirementDiagram-UZGBJVZJ-Bfrfh-0-.js.gz +0 -0
  458. package/dist/ui/assets/sandpack-C58bwfIS.js.gz +0 -0
  459. package/dist/ui/assets/sandpackDefaults-Bkga8XAE.js +0 -1
  460. package/dist/ui/assets/sankeyDiagram-TZEHDZUN-ClZAZ6va.js.gz +0 -0
  461. package/dist/ui/assets/sequenceDiagram-WL72ISMW-CNgly63p.js.gz +0 -0
  462. package/dist/ui/assets/src-DAeyG22O.js.gz +0 -0
  463. package/dist/ui/assets/stateDiagram-FKZM4ZOC-BrEAoDpE.js.gz +0 -0
  464. package/dist/ui/assets/stateDiagram-v2-4FDKWEC3-BNL52_oN.js +0 -1
  465. package/dist/ui/assets/streamdown-BdAVfkeF.js.gz +0 -0
  466. package/dist/ui/assets/syntax-BOfTnQiy.js.gz +0 -0
  467. package/dist/ui/assets/timeline-definition-IT6M3QCI-CaRH3k4l.js.gz +0 -0
  468. package/dist/ui/assets/useUserLocalStorage-C8sgXgXR.js.gz +0 -0
  469. package/dist/ui/assets/xychartDiagram-PRI3JC2R-BlhkI9T_.js.gz +0 -0
@@ -1761,13 +1761,13 @@ var init_identity_token = __esm({
1761
1761
  function oidcFederationProvider(config) {
1762
1762
  return async () => {
1763
1763
  requireSecureTokenEndpoint(config.baseURL);
1764
- const jwt7 = await config.identityTokenProvider();
1765
- if (jwt7.length > 16 * 1024) {
1766
- throw new WorkloadIdentityError(`Identity token is ${Math.ceil(jwt7.length / 1024)} KiB, exceeds the 16 KiB assertion limit`);
1764
+ const jwt8 = await config.identityTokenProvider();
1765
+ if (jwt8.length > 16 * 1024) {
1766
+ throw new WorkloadIdentityError(`Identity token is ${Math.ceil(jwt8.length / 1024)} KiB, exceeds the 16 KiB assertion limit`);
1767
1767
  }
1768
1768
  const body = {
1769
1769
  grant_type: GRANT_TYPE_JWT_BEARER,
1770
- assertion: jwt7,
1770
+ assertion: jwt8,
1771
1771
  federation_rule_id: config.federationRuleId,
1772
1772
  organization_id: config.organizationId
1773
1773
  };
@@ -12143,6 +12143,24 @@ var init_sdk = __esm({
12143
12143
  }
12144
12144
  });
12145
12145
 
12146
+ // src/auth/executor-session-token.ts
12147
+ function isExecutorSessionTokenPayload(payload) {
12148
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) return false;
12149
+ const record = payload;
12150
+ return record.type === EXECUTOR_SESSION_TOKEN_TYPE && record.purpose === EXECUTOR_SESSION_TOKEN_PURPOSE;
12151
+ }
12152
+ function getExecutorSessionTokenSessionId(payload) {
12153
+ return payload.session_id ?? payload.sessionId;
12154
+ }
12155
+ var EXECUTOR_SESSION_TOKEN_TYPE, EXECUTOR_SESSION_TOKEN_PURPOSE;
12156
+ var init_executor_session_token = __esm({
12157
+ "src/auth/executor-session-token.ts"() {
12158
+ "use strict";
12159
+ EXECUTOR_SESSION_TOKEN_TYPE = "executor-session";
12160
+ EXECUTOR_SESSION_TOKEN_PURPOSE = "executor-task";
12161
+ }
12162
+ });
12163
+
12146
12164
  // src/mcp/tokens.ts
12147
12165
  var tokens_exports = {};
12148
12166
  __export(tokens_exports, {
@@ -12157,8 +12175,8 @@ __export(tokens_exports, {
12157
12175
  import { MCP_TOKEN } from "@agor/core/config";
12158
12176
  import {
12159
12177
  generateId as generateId4,
12160
- SessionRepository as SessionRepository4,
12161
- shortId as shortId16
12178
+ SessionRepository as SessionRepository5,
12179
+ shortId as shortId17
12162
12180
  } from "@agor/core/db";
12163
12181
  import {
12164
12182
  MCP_TOKEN_AUDIENCE,
@@ -12183,7 +12201,7 @@ function initMcpTokens(options) {
12183
12201
  const expirationMs = options.expirationMs ?? MCP_TOKEN.DEFAULT_EXPIRATION_MS;
12184
12202
  const now = options.now ?? (() => Date.now());
12185
12203
  _state = {
12186
- sessionRepo: new SessionRepository4(options.db),
12204
+ sessionRepo: new SessionRepository5(options.db),
12187
12205
  expirationMs,
12188
12206
  now,
12189
12207
  tokenCache: /* @__PURE__ */ new Map(),
@@ -12213,7 +12231,7 @@ async function generateSessionToken2(app, sessionId, userId) {
12213
12231
  const cached = s.tokenCache.get(cacheKey);
12214
12232
  const refreshBufferMs = Math.min(5 * 60 * 1e3, Math.max(30 * 1e3, s.expirationMs * 0.1));
12215
12233
  if (cached && cached.expiresAtMs - nowMs > refreshBufferMs) {
12216
- mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${shortId16(sessionId)}`);
12234
+ mcpTokenDebug(`\u{1F3AB} MCP token cache hit: session=${shortId17(sessionId)}`);
12217
12235
  return cached.token;
12218
12236
  }
12219
12237
  const sessionExists = await s.sessionRepo.exists(sessionId);
@@ -12239,7 +12257,7 @@ async function generateSessionToken2(app, sessionId, userId) {
12239
12257
  const token = jwt4.sign(payload, jwtSecret, { algorithm: "HS256" });
12240
12258
  s.tokenCache.set(cacheKey, { token, expiresAtMs });
12241
12259
  mcpTokenDebug(
12242
- `\u{1F3AB} MCP token issued: session=${shortId16(sessionId)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
12260
+ `\u{1F3AB} MCP token issued: session=${shortId17(sessionId)} jti=${jti.substring(0, 8)} exp=+${Math.floor(s.expirationMs / 1e3)}s`
12243
12261
  );
12244
12262
  return token;
12245
12263
  }
@@ -12279,7 +12297,7 @@ async function validateSessionToken(app, token) {
12279
12297
  }
12280
12298
  const sessionExists = await s.sessionRepo.exists(sessionId);
12281
12299
  if (!sessionExists) {
12282
- console.warn(`[mcp-tokens] token rejected: session ${shortId16(sessionId)} not found`);
12300
+ console.warn(`[mcp-tokens] token rejected: session ${shortId17(sessionId)} not found`);
12283
12301
  return null;
12284
12302
  }
12285
12303
  return { sessionId, userId, jti: payload.jti };
@@ -12299,8 +12317,8 @@ var session_token_service_exports = {};
12299
12317
  __export(session_token_service_exports, {
12300
12318
  SessionTokenService: () => SessionTokenService
12301
12319
  });
12302
- import { getCurrentTenantId as getCurrentTenantId4 } from "@agor/core/db";
12303
- import jwt6 from "jsonwebtoken";
12320
+ import { getCurrentTenantId as getCurrentTenantId5 } from "@agor/core/db";
12321
+ import jwt7 from "jsonwebtoken";
12304
12322
  function sessionTokenDebug(...args) {
12305
12323
  if (DEBUG_SESSION_TOKENS) {
12306
12324
  console.debug(...args);
@@ -12310,6 +12328,7 @@ var DEBUG_SESSION_TOKENS, SessionTokenService;
12310
12328
  var init_session_token_service = __esm({
12311
12329
  "src/services/session-token-service.ts"() {
12312
12330
  "use strict";
12331
+ init_executor_session_token();
12313
12332
  DEBUG_SESSION_TOKENS = process.env.AGOR_DEBUG_SESSION_TOKENS === "1" || process.env.DEBUG?.includes("session-token");
12314
12333
  SessionTokenService = class {
12315
12334
  constructor(config) {
@@ -12335,14 +12354,12 @@ var init_session_token_service = __esm({
12335
12354
  }
12336
12355
  const now = /* @__PURE__ */ new Date();
12337
12356
  const expiresAt = new Date(now.getTime() + this.config.expiration_ms);
12338
- const tenantId = getCurrentTenantId4();
12357
+ const tenantId = getCurrentTenantId5();
12339
12358
  const payload = {
12340
12359
  sub: userId,
12341
12360
  // Standard JWT subject claim (used by Feathers for user lookup)
12342
- type: "executor-session",
12343
- purpose: "executor-task",
12344
- sessionId,
12345
- // Custom claim for session tracking
12361
+ type: EXECUTOR_SESSION_TOKEN_TYPE,
12362
+ purpose: EXECUTOR_SESSION_TOKEN_PURPOSE,
12346
12363
  session_id: sessionId,
12347
12364
  task_id: scope.taskId,
12348
12365
  branch_id: scope.branchId,
@@ -12356,7 +12373,7 @@ var init_session_token_service = __esm({
12356
12373
  iss: "agor"
12357
12374
  // Must match Feathers jwtOptions.issuer
12358
12375
  };
12359
- const token = jwt6.sign(payload, this.jwtSecret, {
12376
+ const token = jwt7.sign(payload, this.jwtSecret, {
12360
12377
  algorithm: "HS256"
12361
12378
  // Must match Feathers jwtOptions.algorithm
12362
12379
  // No expiresIn here - we set exp directly in payload
@@ -12557,12 +12574,14 @@ import {
12557
12574
  BoardRepository as BoardRepository5,
12558
12575
  BranchRepository as BranchRepository9,
12559
12576
  eq as eq4,
12577
+ getCurrentTenantId as getCurrentTenantId6,
12560
12578
  inArray as inArray2,
12579
+ isPostgresDatabase as isPostgresDatabase7,
12561
12580
  MCPServerRepository as MCPServerRepository4,
12562
12581
  SessionMCPServerRepository as SessionMCPServerRepository3,
12563
12582
  select as select4,
12564
12583
  sessionMcpServers,
12565
- shortId as shortId21,
12584
+ shortId as shortId22,
12566
12585
  UserMCPOAuthTokenRepository as UserMCPOAuthTokenRepository3,
12567
12586
  visibleSessionReferenceAccessExists
12568
12587
  } from "@agor/core/db";
@@ -12571,7 +12590,7 @@ import {
12571
12590
  AGENTIC_TOOL_CAPABILITIES,
12572
12591
  isSessionExecuting,
12573
12592
  isTaskExecuting,
12574
- ROLES as ROLES16,
12593
+ ROLES as ROLES17,
12575
12594
  SessionStatus as SessionStatus5,
12576
12595
  TaskStatus as TaskStatus3
12577
12596
  } from "@agor/core/types";
@@ -12586,6 +12605,13 @@ function untrackExecutorProcess(sessionId) {
12586
12605
  executorProcesses.delete(sessionId);
12587
12606
  }
12588
12607
 
12608
+ // src/oauth-auth-helpers.ts
12609
+ import { runWithTenantDatabaseScope } from "@agor/core/db";
12610
+ async function runInOAuthTenantScope(db, tenantId, work) {
12611
+ if (!tenantId) return work();
12612
+ return runWithTenantDatabaseScope(db, tenantId, work);
12613
+ }
12614
+
12589
12615
  // src/oauth-cache.ts
12590
12616
  import { MCPServerRepository, UserMCPOAuthTokenRepository } from "@agor/core/db";
12591
12617
  import { resolveTokenExpiry } from "@agor/core/tools/mcp/oauth-token-expiry";
@@ -15874,6 +15900,13 @@ var BoardsService = class extends DrizzleService {
15874
15900
  async batchUpsertBoardObjects(boardId, objects, _params) {
15875
15901
  return this.boardRepo.batchUpsertBoardObjects(boardId, objects);
15876
15902
  }
15903
+ /**
15904
+ * Custom method: Atomically shallow-merge field patches into existing board
15905
+ * objects (used by z-order reorder to persist only the changed zIndex).
15906
+ */
15907
+ async mergeBoardObjectFields(boardId, patches, _params) {
15908
+ return this.boardRepo.mergeBoardObjectFields(boardId, patches);
15909
+ }
15877
15910
  /**
15878
15911
  * Custom method: Delete a zone and handle associated sessions
15879
15912
  */
@@ -16853,6 +16886,27 @@ function shouldUseCloneReferencePath() {
16853
16886
  return (config.execution?.unix_user_mode ?? "simple") !== "strict";
16854
16887
  }
16855
16888
 
16889
+ // src/utils/emit-service-event.ts
16890
+ var DEFAULT_EVENT_METHOD = {
16891
+ created: "create",
16892
+ updated: "update",
16893
+ patched: "patch",
16894
+ removed: "remove"
16895
+ };
16896
+ function emitServiceEvent(app, event) {
16897
+ const service = app.service(event.path);
16898
+ service.emit?.(event.event, event.data, {
16899
+ app,
16900
+ service,
16901
+ path: event.path,
16902
+ method: event.method ?? DEFAULT_EVENT_METHOD[event.event] ?? "patch",
16903
+ event: event.event,
16904
+ id: event.id,
16905
+ result: event.data,
16906
+ params: event.params ?? {}
16907
+ });
16908
+ }
16909
+
16856
16910
  // src/utils/git-impersonation.ts
16857
16911
  async function resolveDaemonUserForGroupRefresh() {
16858
16912
  const { getDaemonUser: getDaemonUser2, isUnixGroupRefreshNeeded } = await import("@agor/core/config");
@@ -16893,7 +16947,7 @@ import {
16893
16947
  enqueueTenantDatabasePostCommitCallback,
16894
16948
  getCurrentTenantId,
16895
16949
  runWithoutTenantDatabaseScope,
16896
- runWithTenantDatabaseScope
16950
+ runWithTenantDatabaseScope as runWithTenantDatabaseScope2
16897
16951
  } from "@agor/core/db";
16898
16952
  import { NotAuthenticated as NotAuthenticated4 } from "@agor/core/feathers";
16899
16953
  import jwt2 from "jsonwebtoken";
@@ -16915,7 +16969,7 @@ function deferWithTenantDatabaseScope(db, params, work, onError) {
16915
16969
  const schedule = () => {
16916
16970
  runWithoutTenantDatabaseScope(() => {
16917
16971
  setImmediate(() => {
16918
- void runWithTenantDatabaseScope(db, tenantId, work).catch((error) => {
16972
+ void runWithTenantDatabaseScope2(db, tenantId, work).catch((error) => {
16919
16973
  if (onError) {
16920
16974
  onError(error);
16921
16975
  return;
@@ -18295,7 +18349,13 @@ var BranchesService = class extends DrizzleService {
18295
18349
  },
18296
18350
  resolvedParams
18297
18351
  );
18298
- this.app.service("branches").emit?.("patched", branch);
18352
+ emitServiceEvent(this.app, {
18353
+ path: "branches",
18354
+ event: "patched",
18355
+ data: branch,
18356
+ params: resolvedParams,
18357
+ id
18358
+ });
18299
18359
  return branch;
18300
18360
  }
18301
18361
  /**
@@ -18730,7 +18790,9 @@ var BranchesService = class extends DrizzleService {
18730
18790
  path: branch.path,
18731
18791
  custom_context: branch.custom_context,
18732
18792
  unix_gid: unixGid,
18733
- host_ip_address: hostIpAddress
18793
+ host_ip_address: hostIpAddress,
18794
+ base_ref: branch.base_ref,
18795
+ ref_type: branch.ref_type
18734
18796
  },
18735
18797
  requestedVariant
18736
18798
  );
@@ -19185,6 +19247,9 @@ function isAlias(id) {
19185
19247
  }
19186
19248
  var CONTEXT_1M_BETA = "context-1m-2025-08-07";
19187
19249
  var ONE_MILLION_TOKENS = 9e5;
19250
+ function hasNativeMillionContext(id) {
19251
+ return id.startsWith("claude-fable");
19252
+ }
19188
19253
  function toModelOptions(models) {
19189
19254
  const aliases = models.filter((m) => isAlias(m.id));
19190
19255
  const options = [];
@@ -19195,7 +19260,7 @@ function toModelOptions(models) {
19195
19260
  description: void 0,
19196
19261
  source: "dynamic"
19197
19262
  });
19198
- if (m.max_input_tokens && m.max_input_tokens >= ONE_MILLION_TOKENS) {
19263
+ if (m.max_input_tokens && m.max_input_tokens >= ONE_MILLION_TOKENS && !hasNativeMillionContext(m.id)) {
19199
19264
  options.push({
19200
19265
  id: `${m.id}[1m]`,
19201
19266
  displayName: `${m.display_name} (1M context)`,
@@ -19539,6 +19604,7 @@ import { Forbidden as Forbidden7, NotAuthenticated as NotAuthenticated7 } from "
19539
19604
  import { hasMinimumRole as hasMinimumRole5, ROLES as ROLES5 } from "@agor/core/types";
19540
19605
 
19541
19606
  // src/auth/executor-runtime-scope.ts
19607
+ init_executor_session_token();
19542
19608
  import { Forbidden as Forbidden6 } from "@agor/core/feathers";
19543
19609
 
19544
19610
  // src/utils/authorization.ts
@@ -20278,7 +20344,8 @@ import {
20278
20344
  getHiddenTenantId,
20279
20345
  MCPServerRepository as MCPServerRepository2,
20280
20346
  runWithoutTenantDatabaseScope as runWithoutTenantDatabaseScope2,
20281
- runWithTenantDatabaseScope as runWithTenantDatabaseScope2,
20347
+ runWithTenantDatabaseScope as runWithTenantDatabaseScope3,
20348
+ SessionRepository as SessionRepository2,
20282
20349
  shortId as shortId10,
20283
20350
  ThreadSessionMapRepository,
20284
20351
  UserMCPOAuthTokenRepository as UserMCPOAuthTokenRepository2,
@@ -20373,6 +20440,13 @@ function oneLineForPrompt(text, maxChars = 900) {
20373
20440
  if (normalized.length <= maxChars) return normalized;
20374
20441
  return `${normalized.slice(0, Math.max(0, maxChars - 1))}\u2026`;
20375
20442
  }
20443
+ var SLACK_GATEWAY_REPLY_NOTE = "Note: Any assistant message you send in this current Agor session is streamed back directly to the Slack conversation. Only use outbound gateway tools when you intentionally need to start a separate thread, DM, or message.";
20444
+ function prependSlackGatewayReplyNote(prompt) {
20445
+ if (prompt.includes(SLACK_GATEWAY_REPLY_NOTE)) return prompt;
20446
+ return `${SLACK_GATEWAY_REPLY_NOTE}
20447
+
20448
+ ${prompt}`;
20449
+ }
20376
20450
  function formatSlackCatchUpPrompt(args) {
20377
20451
  const slackChannelName = typeof args.metadata?.slack_channel_name === "string" ? args.metadata.slack_channel_name : null;
20378
20452
  const slackChannelId = typeof args.metadata?.channel === "string" ? args.metadata.channel : args.threadId.split("-")[0];
@@ -20559,6 +20633,7 @@ var GatewayService = class _GatewayService {
20559
20633
  threadMapRepo;
20560
20634
  outboundRepo;
20561
20635
  branchRepo;
20636
+ sessionRepo;
20562
20637
  usersRepo;
20563
20638
  mcpServerRepo;
20564
20639
  userTokenRepo;
@@ -20601,6 +20676,7 @@ var GatewayService = class _GatewayService {
20601
20676
  this.threadMapRepo = new ThreadSessionMapRepository(db);
20602
20677
  this.outboundRepo = new GatewayOutboundMessageRepository(db);
20603
20678
  this.branchRepo = new BranchRepository5(db);
20679
+ this.sessionRepo = new SessionRepository2(db);
20604
20680
  this.usersRepo = new UsersRepository5(db);
20605
20681
  this.mcpServerRepo = new MCPServerRepository2(db);
20606
20682
  this.userTokenRepo = new UserMCPOAuthTokenRepository2(db);
@@ -21096,6 +21172,24 @@ ${chunk}` : chunk;
21096
21172
  console.warn("[gateway] Failed to mirror message stream to Slack:", error);
21097
21173
  }
21098
21174
  }
21175
+ /**
21176
+ * Session-context emits are hard-bound to the session's branch, with no
21177
+ * admin-role bypass — agent sessions run as admin users, so a role bypass
21178
+ * would let any session impersonate another assistant's channel. The error
21179
+ * deliberately never echoes the channel's target branch, so a denied emit
21180
+ * cannot be used to enumerate which branch a foreign channel serves.
21181
+ */
21182
+ async ensureSessionBranchBoundToChannel(channel, sessionId) {
21183
+ const session = await this.sessionRepo.findById(sessionId);
21184
+ if (!session) {
21185
+ throw new Error("Gateway outbound denied: emitting session not found");
21186
+ }
21187
+ if (session.branch_id !== channel.target_branch_id) {
21188
+ throw new Error(
21189
+ `Gateway outbound denied: session ${shortId10(sessionId)} runs on branch ${shortId10(session.branch_id)}, but this channel targets a different branch. Sessions can emit only through gateway channels whose target branch matches their own. Call agor_gateway_outbound_targets_list to see usable channels.`
21190
+ );
21191
+ }
21192
+ }
21099
21193
  async ensureCanEmitFromChannel(channel, userId, userRole) {
21100
21194
  if (hasMinimumRole6(userRole, ROLES8.ADMIN)) return;
21101
21195
  const branch = await this.branchRepo.findById(channel.target_branch_id);
@@ -21129,6 +21223,9 @@ ${chunk}` : chunk;
21129
21223
  if (config.outbound_enabled !== true) {
21130
21224
  throw new Error("Gateway outbound is disabled for this channel");
21131
21225
  }
21226
+ if (data.emittedBySessionId) {
21227
+ await this.ensureSessionBranchBoundToChannel(channel, data.emittedBySessionId);
21228
+ }
21132
21229
  await this.ensureCanEmitFromChannel(channel, data.emittedByUserId, data.userRole);
21133
21230
  const target = data.target ?? (typeof config.default_outbound_target === "string" ? config.default_outbound_target : void 0);
21134
21231
  if (!target) throw new Error("No usable default outbound target configured");
@@ -21703,6 +21800,9 @@ ${chunk}` : chunk;
21703
21800
  promptText = contextPrefix + promptText;
21704
21801
  }
21705
21802
  }
21803
+ if (channel.channel_type === "slack") {
21804
+ promptText = prependSlackGatewayReplyNote(promptText);
21805
+ }
21706
21806
  if (created && mcpAuthWarning) {
21707
21807
  promptText = `${mcpAuthWarning}
21708
21808
 
@@ -22010,7 +22110,7 @@ ${promptText}`;
22010
22110
  if (!tenantId) {
22011
22111
  throw new Error(`Missing tenant context for gateway listener channel ${channel.id}`);
22012
22112
  }
22013
- await runWithTenantDatabaseScope2(this.db, tenantId, async () => {
22113
+ await runWithTenantDatabaseScope3(this.db, tenantId, async () => {
22014
22114
  await this.create({
22015
22115
  channel_key: channel.channel_key,
22016
22116
  thread_id: msg.threadId,
@@ -26783,6 +26883,80 @@ function createSessionMCPServersService(db) {
26783
26883
  return new SessionMCPServersService(db);
26784
26884
  }
26785
26885
 
26886
+ // src/services/session-streams.ts
26887
+ import { BadRequest as BadRequest12 } from "@agor/core/feathers";
26888
+
26889
+ // src/utils/realtime-publish.ts
26890
+ import {
26891
+ resolveTenantContext as resolveTenantContext2,
26892
+ TenantResolutionError as TenantResolutionError2
26893
+ } from "@agor/core/config";
26894
+ import { getCurrentTenantId as getCurrentTenantId3, shortId as shortId14 } from "@agor/core/db";
26895
+ import { hasMinimumRole as hasMinimumRole9, ROLES as ROLES11 } from "@agor/core/types";
26896
+
26897
+ // src/utils/realtime-access-cache.ts
26898
+ var DEFAULT_BRANCH_VISIBILITY_TTL_MS = 5 * 6e4;
26899
+ var DEFAULT_SESSION_BRANCH_TTL_MS = 60 * 6e4;
26900
+
26901
+ // src/utils/realtime-publish.ts
26902
+ var SESSION_STREAM_CHANNEL_PREFIX = "session-stream:";
26903
+ function sessionStreamChannelName(sessionId) {
26904
+ return `${SESSION_STREAM_CHANNEL_PREFIX}${sessionId}`;
26905
+ }
26906
+ function existingChannel(app, name) {
26907
+ return (app.channels ?? []).includes(name) ? app.channel(name) : null;
26908
+ }
26909
+ function joinSessionStreamChannel(app, sessionId, connection) {
26910
+ app.channel(sessionStreamChannelName(sessionId)).join(connection);
26911
+ }
26912
+ function leaveSessionStreamChannel(app, sessionId, connection) {
26913
+ existingChannel(app, sessionStreamChannelName(sessionId))?.leave(connection);
26914
+ }
26915
+ var DEBUG_REALTIME_PUBLISH = process.env.AGOR_DEBUG_REALTIME_PUBLISH === "1" || process.env.DEBUG?.includes("realtime-publish");
26916
+
26917
+ // src/services/session-streams.ts
26918
+ var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
26919
+ function isCanonicalSessionId(id) {
26920
+ return UUID_RE.test(id);
26921
+ }
26922
+ function createSessionStreamsService(app) {
26923
+ const resolveAccessibleSessionId = async (sessionId, params) => {
26924
+ const session = await app.service("sessions").get(sessionId, { ...params ?? {}, query: {} });
26925
+ return session?.session_id ?? null;
26926
+ };
26927
+ return {
26928
+ async create(data, params) {
26929
+ const connection = params?.connection;
26930
+ if (!connection) {
26931
+ throw new BadRequest12("session stream subscription requires a realtime connection");
26932
+ }
26933
+ const sessionId = data?.session_id ?? data?.sessionId;
26934
+ if (!sessionId || typeof sessionId !== "string") {
26935
+ throw new BadRequest12("session_id is required");
26936
+ }
26937
+ const canonicalId = await resolveAccessibleSessionId(sessionId, params) ?? sessionId;
26938
+ joinSessionStreamChannel(app, canonicalId, connection);
26939
+ return { session_id: canonicalId, subscribed: true };
26940
+ },
26941
+ async remove(id, params) {
26942
+ const connection = params?.connection;
26943
+ const sessionId = typeof id === "string" ? id : "";
26944
+ if (!connection || !sessionId) {
26945
+ return { session_id: sessionId, subscribed: false };
26946
+ }
26947
+ let canonicalId = sessionId;
26948
+ if (!isCanonicalSessionId(sessionId)) {
26949
+ try {
26950
+ canonicalId = await resolveAccessibleSessionId(sessionId, params) ?? sessionId;
26951
+ } catch {
26952
+ }
26953
+ }
26954
+ leaveSessionStreamChannel(app, canonicalId, connection);
26955
+ return { session_id: canonicalId, subscribed: false };
26956
+ }
26957
+ };
26958
+ }
26959
+
26786
26960
  // src/services/sessions.ts
26787
26961
  import { PAGINATION as PAGINATION15 } from "@agor/core/config";
26788
26962
  import {
@@ -26790,10 +26964,10 @@ import {
26790
26964
  SessionEnvSelectionRepository as SessionEnvSelectionRepository2,
26791
26965
  SessionMCPServerRepository as SessionMCPServerRepository2,
26792
26966
  SessionRelationshipRepository,
26793
- SessionRepository as SessionRepository2,
26967
+ SessionRepository as SessionRepository3,
26794
26968
  UsersRepository as UsersRepository6
26795
26969
  } from "@agor/core/db";
26796
- import { BadRequest as BadRequest12, Forbidden as Forbidden15 } from "@agor/core/feathers";
26970
+ import { BadRequest as BadRequest13, Forbidden as Forbidden15 } from "@agor/core/feathers";
26797
26971
  import {
26798
26972
  formatModelToolMismatchWarning,
26799
26973
  formatUnsupportedAgorCodexModelMessage,
@@ -26801,7 +26975,7 @@ import {
26801
26975
  lintModelToolMatch
26802
26976
  } from "@agor/core/models";
26803
26977
  import { resolveChildSessionConfig } from "@agor/core/sessions";
26804
- import { ROLES as ROLES11, SessionStatus as SessionStatus2 } from "@agor/core/types";
26978
+ import { ROLES as ROLES12, SessionStatus as SessionStatus2 } from "@agor/core/types";
26805
26979
  function getInheritableConfig(parent) {
26806
26980
  return {
26807
26981
  permission_config: parent.permission_config,
@@ -26842,11 +27016,11 @@ var SessionsService = class extends DrizzleService {
26842
27016
  branchRepo;
26843
27017
  assertSupportedModelConfig(agenticTool, modelConfig) {
26844
27018
  if (agenticTool === "codex" && modelConfig?.model && isUnsupportedAgorCodexModel(modelConfig.model)) {
26845
- throw new BadRequest12(formatUnsupportedAgorCodexModelMessage(modelConfig.model));
27019
+ throw new BadRequest13(formatUnsupportedAgorCodexModelMessage(modelConfig.model));
26846
27020
  }
26847
27021
  }
26848
27022
  constructor(db, app) {
26849
- const sessionRepo = new SessionRepository2(db);
27023
+ const sessionRepo = new SessionRepository3(db);
26850
27024
  super(sessionRepo, {
26851
27025
  id: "session_id",
26852
27026
  resourceType: "Session",
@@ -27195,7 +27369,7 @@ ${data.extraInstructions}`;
27195
27369
  }
27196
27370
  const callerUserId = params?.user?.user_id;
27197
27371
  const callerRole = params?.user?.role;
27198
- const callerIsCreatorOrAdmin = callerUserId === parent.created_by || callerRole === ROLES11.ADMIN || isSuperAdmin(callerRole);
27372
+ const callerIsCreatorOrAdmin = callerUserId === parent.created_by || callerRole === ROLES12.ADMIN || isSuperAdmin(callerRole);
27199
27373
  if (data.envVarNames !== void 0 && callerIsCreatorOrAdmin) {
27200
27374
  await this.sessionEnvSelectionRepo.setAll(session.session_id, data.envVarNames);
27201
27375
  } else {
@@ -27403,7 +27577,7 @@ import {
27403
27577
  import { PAGINATION as PAGINATION16, resolveExecutorHeartbeatConfig as resolveExecutorHeartbeatConfig2 } from "@agor/core/config";
27404
27578
  import {
27405
27579
  enqueueTenantDatabasePostCommitCallback as enqueueTenantDatabasePostCommitCallback2,
27406
- shortId as shortId15,
27580
+ shortId as shortId16,
27407
27581
  TaskRepository
27408
27582
  } from "@agor/core/db";
27409
27583
  import {
@@ -27413,7 +27587,7 @@ import {
27413
27587
  } from "@agor/core/types";
27414
27588
 
27415
27589
  // src/utils/append-system-message.ts
27416
- import { generateId as generateId2, SessionRepository as SessionRepository3 } from "@agor/core/db";
27590
+ import { generateId as generateId2, SessionRepository as SessionRepository4 } from "@agor/core/db";
27417
27591
  import { MessageRole } from "@agor/core/types";
27418
27592
  async function appendSystemMessage(opts) {
27419
27593
  const {
@@ -27428,7 +27602,7 @@ async function appendSystemMessage(opts) {
27428
27602
  metadata,
27429
27603
  params
27430
27604
  } = opts;
27431
- const index = await new SessionRepository3(db).countMessages(sessionId);
27605
+ const index = await new SessionRepository4(db).countMessages(sessionId);
27432
27606
  const preview = contentPreview ?? (typeof content === "string" ? content.substring(0, 200) : "");
27433
27607
  const message = {
27434
27608
  message_id: generateId2(),
@@ -27448,7 +27622,7 @@ async function appendSystemMessage(opts) {
27448
27622
 
27449
27623
  // src/utils/executor-heartbeat-callback.ts
27450
27624
  import { spawn as spawn3 } from "child_process";
27451
- import { shortId as shortId14 } from "@agor/core/db";
27625
+ import { shortId as shortId15 } from "@agor/core/db";
27452
27626
  var ExecutorHeartbeatCallbackRunner = class {
27453
27627
  constructor(config) {
27454
27628
  this.config = config;
@@ -27460,7 +27634,7 @@ var ExecutorHeartbeatCallbackRunner = class {
27460
27634
  if (!command) return;
27461
27635
  if (this.runningByTask.has(payload.task_id)) {
27462
27636
  console.warn(
27463
- `[executor-heartbeat] Previous callback still running for task ${shortId14(payload.task_id)}; skipping heartbeat callback`
27637
+ `[executor-heartbeat] Previous callback still running for task ${shortId15(payload.task_id)}; skipping heartbeat callback`
27464
27638
  );
27465
27639
  return;
27466
27640
  }
@@ -27654,7 +27828,7 @@ var TasksService = class extends DrizzleService {
27654
27828
  );
27655
27829
  if (data.status === TaskStatus.RUNNING && !Array.isArray(result) && this.app) {
27656
27830
  console.log(`\u{1F50D} [TasksService.create] ENTERING session status update block`);
27657
- console.log(`\u{1F50D} [TasksService.create] About to patch session ${shortId15(result.session_id)}`);
27831
+ console.log(`\u{1F50D} [TasksService.create] About to patch session ${shortId16(result.session_id)}`);
27658
27832
  try {
27659
27833
  const patchResult = await this.app.service("sessions").patch(
27660
27834
  result.session_id,
@@ -27665,7 +27839,7 @@ var TasksService = class extends DrizzleService {
27665
27839
  params
27666
27840
  );
27667
27841
  console.log(
27668
- `\u2705 [TasksService] Session ${shortId15(result.session_id)} status updated to RUNNING (task ${shortId15(result.task_id)} created)`,
27842
+ `\u2705 [TasksService] Session ${shortId16(result.session_id)} status updated to RUNNING (task ${shortId16(result.task_id)} created)`,
27669
27843
  `Patch result status: ${patchResult.status}`
27670
27844
  );
27671
27845
  } catch (error) {
@@ -27753,7 +27927,7 @@ var TasksService = class extends DrizzleService {
27753
27927
  const heartbeatFailureWon = failedTask.status === TaskStatus.FAILED && failedTask.error_message === data.error_message && (!data.completed_at || failedTask.completed_at === data.completed_at);
27754
27928
  if (!heartbeatFailureWon) {
27755
27929
  console.log(
27756
- `\u23ED\uFE0F [TasksService] Skipping heartbeat session failure for task ${shortId15(failedTask.task_id)}; heartbeat failure did not win (status=${failedTask.status})`
27930
+ `\u23ED\uFE0F [TasksService] Skipping heartbeat session failure for task ${shortId16(failedTask.task_id)}; heartbeat failure did not win (status=${failedTask.status})`
27757
27931
  );
27758
27932
  return failedTask;
27759
27933
  }
@@ -27773,7 +27947,7 @@ var TasksService = class extends DrizzleService {
27773
27947
  updatedSession = s;
27774
27948
  }).catch((error) => {
27775
27949
  console.warn(
27776
- `[executor-heartbeat] Failed to mark session ${shortId15(failedTask.session_id)} failed after stale heartbeat:`,
27950
+ `[executor-heartbeat] Failed to mark session ${shortId16(failedTask.session_id)} failed after stale heartbeat:`,
27777
27951
  error instanceof Error ? error.message : String(error)
27778
27952
  );
27779
27953
  });
@@ -27781,7 +27955,7 @@ var TasksService = class extends DrizzleService {
27781
27955
  void this.dispatchCompletionCallbacksAfterCommit(failedTask, updatedSession, params).catch(
27782
27956
  (error) => {
27783
27957
  console.warn(
27784
- `[executor-heartbeat] Failed to dispatch completion callbacks for task ${shortId15(failedTask.task_id)}:`,
27958
+ `[executor-heartbeat] Failed to dispatch completion callbacks for task ${shortId16(failedTask.task_id)}:`,
27785
27959
  error instanceof Error ? error.message : String(error)
27786
27960
  );
27787
27961
  }
@@ -27803,7 +27977,7 @@ var TasksService = class extends DrizzleService {
27803
27977
  }
27804
27978
  } catch (error) {
27805
27979
  console.warn(
27806
- `\u26A0\uFE0F [TasksService] Could not resolve branch_id for heartbeat task ${shortId15(task.task_id)}:`,
27980
+ `\u26A0\uFE0F [TasksService] Could not resolve branch_id for heartbeat task ${shortId16(task.task_id)}:`,
27807
27981
  error instanceof Error ? error.message : String(error)
27808
27982
  );
27809
27983
  }
@@ -27852,7 +28026,7 @@ var TasksService = class extends DrizzleService {
27852
28026
  const currentTask = nextStatus !== void 0 ? await this.get(id, params) : void 0;
27853
28027
  if (currentTask && isTerminalTaskStatus(currentTask.status) && nextStatus !== void 0) {
27854
28028
  console.warn(
27855
- `\u23ED\uFE0F [TasksService] Ignoring status rewrite for terminal task ${shortId15(currentTask.task_id)} (${currentTask.status} \u2192 ${nextStatus})`
28029
+ `\u23ED\uFE0F [TasksService] Ignoring status rewrite for terminal task ${shortId16(currentTask.task_id)} (${currentTask.status} \u2192 ${nextStatus})`
27856
28030
  );
27857
28031
  return currentTask;
27858
28032
  }
@@ -27901,7 +28075,7 @@ var TasksService = class extends DrizzleService {
27901
28075
  this.handleExecutorHeartbeat(result, data.last_executor_heartbeat_at).catch(
27902
28076
  (error) => {
27903
28077
  console.warn(
27904
- `\u26A0\uFE0F [TasksService] Executor heartbeat callback failed for task ${shortId15(result.task_id)}:`,
28078
+ `\u26A0\uFE0F [TasksService] Executor heartbeat callback failed for task ${shortId16(result.task_id)}:`,
27905
28079
  error
27906
28080
  );
27907
28081
  }
@@ -27924,7 +28098,7 @@ var TasksService = class extends DrizzleService {
27924
28098
  }).catch((err) => {
27925
28099
  const message = err instanceof Error ? err.message : String(err);
27926
28100
  console.warn(
27927
- `\u26A0\uFE0F [TasksService] ensureRepoOriginAlignedById failed for session ${task.session_id ? shortId15(task.session_id) : "unknown"}: ${message}`
28101
+ `\u26A0\uFE0F [TasksService] ensureRepoOriginAlignedById failed for session ${task.session_id ? shortId16(task.session_id) : "unknown"}: ${message}`
27928
28102
  );
27929
28103
  });
27930
28104
  }
@@ -27934,7 +28108,7 @@ var TasksService = class extends DrizzleService {
27934
28108
  const isStop = data.status === TaskStatus.STOPPED;
27935
28109
  if (latestTaskId && latestTaskId !== task.task_id) {
27936
28110
  console.log(
27937
- `\u23ED\uFE0F [TasksService] Skipping session terminal-state update - task ${shortId15(task.task_id)} is not the latest (latest: ${shortId15(latestTaskId)})`
28111
+ `\u23ED\uFE0F [TasksService] Skipping session terminal-state update - task ${shortId16(task.task_id)} is not the latest (latest: ${shortId16(latestTaskId)})`
27938
28112
  );
27939
28113
  if (!suppressCompletionCallbacks && !isStop) {
27940
28114
  await this.dispatchCompletionCallbacksAfterCommit(task, session, params);
@@ -27943,11 +28117,11 @@ var TasksService = class extends DrizzleService {
27943
28117
  }
27944
28118
  if (isStop && params?.suppressTerminalQueueProcessing) {
27945
28119
  console.log(
27946
- `\u23ED\uFE0F [TasksService] Skipping session terminal-state update for STOPPED task ${shortId15(task.task_id)} \u2014 caller suppresses terminal queue processing`
28120
+ `\u23ED\uFE0F [TasksService] Skipping session terminal-state update for STOPPED task ${shortId16(task.task_id)} \u2014 caller suppresses terminal queue processing`
27947
28121
  );
27948
28122
  } else if (params?.suppressTerminalSessionStateUpdate) {
27949
28123
  console.log(
27950
- `\u23ED\uFE0F [TasksService] Skipping session terminal-state update for task ${shortId15(task.task_id)} (${data.status}) due to internal patch params`
28124
+ `\u23ED\uFE0F [TasksService] Skipping session terminal-state update for task ${shortId16(task.task_id)} (${data.status}) due to internal patch params`
27951
28125
  );
27952
28126
  } else {
27953
28127
  await this.app.service("sessions").patch(
@@ -27959,7 +28133,7 @@ var TasksService = class extends DrizzleService {
27959
28133
  params
27960
28134
  );
27961
28135
  console.log(
27962
- `\u2705 [TasksService] Session ${shortId15(task.session_id)} status updated after terminal task (task ${shortId15(task.task_id)} ${data.status})`
28136
+ `\u2705 [TasksService] Session ${shortId16(task.session_id)} status updated after terminal task (task ${shortId16(task.task_id)} ${data.status})`
27963
28137
  );
27964
28138
  }
27965
28139
  if (!suppressCompletionCallbacks && !isStop) {
@@ -27973,7 +28147,7 @@ var TasksService = class extends DrizzleService {
27973
28147
  archived_reason: "btw_completed"
27974
28148
  });
27975
28149
  console.log(
27976
- `\u{1F4E6} [TasksService] Auto-archived btw fork session ${shortId15(session.session_id)}`
28150
+ `\u{1F4E6} [TasksService] Auto-archived btw fork session ${shortId16(session.session_id)}`
27977
28151
  );
27978
28152
  } catch (error) {
27979
28153
  console.warn(`\u26A0\uFE0F [TasksService] Failed to auto-archive btw fork:`, error);
@@ -27987,7 +28161,7 @@ var TasksService = class extends DrizzleService {
27987
28161
  await this.triggerQueueProcessingAfterCommit(task.session_id, params);
27988
28162
  } else if (params?.suppressTerminalQueueProcessing) {
27989
28163
  console.log(
27990
- `\u23ED\uFE0F [TasksService] Queue trigger suppressed for session ${shortId15(task.session_id)} (suppressTerminalQueueProcessing)`
28164
+ `\u23ED\uFE0F [TasksService] Queue trigger suppressed for session ${shortId16(task.session_id)} (suppressTerminalQueueProcessing)`
27991
28165
  );
27992
28166
  }
27993
28167
  } catch (error) {
@@ -28068,7 +28242,7 @@ var TasksService = class extends DrizzleService {
28068
28242
  }
28069
28243
  });
28070
28244
  console.log(
28071
- `\u{1F4AC} [TasksService] Injected btw result message into parent session ${shortId15(parentSessionId)} from btw fork ${shortId15(btwSession.session_id)}`
28245
+ `\u{1F4AC} [TasksService] Injected btw result message into parent session ${shortId16(parentSessionId)} from btw fork ${shortId16(btwSession.session_id)}`
28072
28246
  );
28073
28247
  } catch (error) {
28074
28248
  console.warn(`\u26A0\uFE0F [TasksService] Failed to inject btw result message:`, error);
@@ -28096,7 +28270,7 @@ var TasksService = class extends DrizzleService {
28096
28270
  if (dispatchResult.callbackTask) {
28097
28271
  try {
28098
28272
  console.log(
28099
- `\u{1F504} [TasksService] Triggering callback target queue processing for ${shortId15(targetSessionId)} (callback queued)`
28273
+ `\u{1F504} [TasksService] Triggering callback target queue processing for ${shortId16(targetSessionId)} (callback queued)`
28100
28274
  );
28101
28275
  await this.triggerQueueProcessingAfterCommit(targetSessionId, {});
28102
28276
  } catch (error) {
@@ -28116,7 +28290,7 @@ var TasksService = class extends DrizzleService {
28116
28290
  }
28117
28291
  });
28118
28292
  console.log(
28119
- `\u{1F515} [TasksService] Auto-disabled callback for session ${shortId15(childSession.session_id)} (once mode)`
28293
+ `\u{1F515} [TasksService] Auto-disabled callback for session ${shortId16(childSession.session_id)} (once mode)`
28120
28294
  );
28121
28295
  } catch (error) {
28122
28296
  console.warn(`\u26A0\uFE0F [TasksService] Failed to auto-disable callback:`, error);
@@ -28162,7 +28336,7 @@ var TasksService = class extends DrizzleService {
28162
28336
  const latestTask = await this.taskRepo.findById(task.task_id) ?? task;
28163
28337
  if (this.hasCompletionCallbackDispatch(latestTask.metadata, targetSessionId)) {
28164
28338
  console.log(
28165
- `\u23ED\uFE0F [TasksService] Completion callback for task ${shortId15(task.task_id)} to ${shortId15(targetSessionId)} already dispatched`
28339
+ `\u23ED\uFE0F [TasksService] Completion callback for task ${shortId16(task.task_id)} to ${shortId16(targetSessionId)} already dispatched`
28166
28340
  );
28167
28341
  return {};
28168
28342
  }
@@ -28182,7 +28356,7 @@ var TasksService = class extends DrizzleService {
28182
28356
  );
28183
28357
  } catch (error) {
28184
28358
  console.warn(
28185
- `\u26A0\uFE0F [TasksService] Failed to mark completion callback dispatched for task ${shortId15(task.task_id)} to ${shortId15(targetSessionId)} after queueing:`,
28359
+ `\u26A0\uFE0F [TasksService] Failed to mark completion callback dispatched for task ${shortId16(task.task_id)} to ${shortId16(targetSessionId)} after queueing:`,
28186
28360
  error
28187
28361
  );
28188
28362
  }
@@ -28208,7 +28382,7 @@ var TasksService = class extends DrizzleService {
28208
28382
  const callbackEnabled = childSession.callback_config?.enabled ?? targetSession.callback_config?.enabled ?? true;
28209
28383
  if (!callbackEnabled) {
28210
28384
  console.log(
28211
- `\u23ED\uFE0F [TasksService] Callbacks disabled for child session ${shortId15(childSession.session_id)}`
28385
+ `\u23ED\uFE0F [TasksService] Callbacks disabled for child session ${shortId16(childSession.session_id)}`
28212
28386
  );
28213
28387
  return void 0;
28214
28388
  }
@@ -28245,13 +28419,13 @@ var TasksService = class extends DrizzleService {
28245
28419
  }
28246
28420
  }
28247
28421
  const context = {
28248
- childSessionId: shortId15(childSession.session_id),
28422
+ childSessionId: shortId16(childSession.session_id),
28249
28423
  childSessionFullId: childSession.session_id,
28250
- childTaskId: shortId15(task.task_id),
28424
+ childTaskId: shortId16(task.task_id),
28251
28425
  childTaskFullId: task.task_id,
28252
- parentSessionId: shortId15(targetSessionId),
28426
+ parentSessionId: shortId16(targetSessionId),
28253
28427
  // backward compat
28254
- callbackSessionId: shortId15(targetSessionId),
28428
+ callbackSessionId: shortId16(targetSessionId),
28255
28429
  spawnPrompt,
28256
28430
  status: task.status,
28257
28431
  // COMPLETED, FAILED, etc.
@@ -28264,7 +28438,7 @@ var TasksService = class extends DrizzleService {
28264
28438
  const callbackMessage = renderChildCompletionCallback(context, customTemplate);
28265
28439
  if (!targetSession.created_by) {
28266
28440
  console.warn(
28267
- `\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${shortId15(targetSessionId)} has no creator (anonymous session)`
28441
+ `\u26A0\uFE0F [TasksService] Cannot queue callback: target session ${shortId16(targetSessionId)} has no creator (anonymous session)`
28268
28442
  );
28269
28443
  return void 0;
28270
28444
  }
@@ -28284,7 +28458,7 @@ var TasksService = class extends DrizzleService {
28284
28458
  });
28285
28459
  this.emit?.("queued", callbackTask);
28286
28460
  console.log(
28287
- `\u{1F514} Queued callback task ${shortId15(callbackTask.task_id)} on session ${shortId15(targetSessionId)} from child ${shortId15(childSession.session_id)}`
28461
+ `\u{1F514} Queued callback task ${shortId16(callbackTask.task_id)} on session ${shortId16(targetSessionId)} from child ${shortId16(childSession.session_id)}`
28288
28462
  );
28289
28463
  return callbackTask;
28290
28464
  } catch (error) {
@@ -28364,14 +28538,14 @@ function createTasksService(db, app) {
28364
28538
  }
28365
28539
 
28366
28540
  // src/services/templates.ts
28367
- import { BadRequest as BadRequest13 } from "@agor/core/feathers";
28541
+ import { BadRequest as BadRequest14 } from "@agor/core/feathers";
28368
28542
  import { renderTemplate } from "@agor/core/templates/handlebars-helpers";
28369
- import { ROLES as ROLES12 } from "@agor/core/types";
28543
+ import { ROLES as ROLES13 } from "@agor/core/types";
28370
28544
  var TemplatesService = class {
28371
28545
  async create(data, params) {
28372
- ensureMinimumRole(params, ROLES12.MEMBER, "render templates");
28546
+ ensureMinimumRole(params, ROLES13.MEMBER, "render templates");
28373
28547
  if (typeof data?.template !== "string") {
28374
- throw new BadRequest13("template (string) is required");
28548
+ throw new BadRequest14("template (string) is required");
28375
28549
  }
28376
28550
  const context = data.context && typeof data.context === "object" ? data.context : {};
28377
28551
  const rendered = renderTemplate(data.template, context, { onError: data.onError ?? "empty" });
@@ -28395,8 +28569,8 @@ import {
28395
28569
  } from "@agor/core/config";
28396
28570
  import {
28397
28571
  BranchRepository as BranchRepository8,
28398
- SessionRepository as SessionRepository6,
28399
- shortId as shortId18,
28572
+ SessionRepository as SessionRepository7,
28573
+ shortId as shortId19,
28400
28574
  UsersRepository as UsersRepository7
28401
28575
  } from "@agor/core/db";
28402
28576
  import { Forbidden as Forbidden16 } from "@agor/core/feathers";
@@ -28408,15 +28582,15 @@ import {
28408
28582
  } from "@agor/core/unix";
28409
28583
 
28410
28584
  // src/utils/mcp-token-authorization.ts
28411
- import { hasMinimumRole as hasMinimumRole9, ROLES as ROLES13 } from "@agor/core/types";
28585
+ import { hasMinimumRole as hasMinimumRole10, ROLES as ROLES14 } from "@agor/core/types";
28412
28586
  function hasExplicitMinimumRole(userRole, minimumRole) {
28413
- return !!userRole && hasMinimumRole9(userRole, minimumRole);
28587
+ return !!userRole && hasMinimumRole10(userRole, minimumRole);
28414
28588
  }
28415
28589
  function canControlCliSession(params) {
28416
28590
  const { callerUserId, callerRole, sessionCreatedBy } = params;
28417
- const isSuperadmin = hasExplicitMinimumRole(callerRole, ROLES13.SUPERADMIN);
28591
+ const isSuperadmin = hasExplicitMinimumRole(callerRole, ROLES14.SUPERADMIN);
28418
28592
  const isServiceExecutor = callerRole === "service";
28419
- const isCreatorMember = !!callerUserId && callerUserId === sessionCreatedBy && hasExplicitMinimumRole(callerRole, ROLES13.MEMBER);
28593
+ const isCreatorMember = !!callerUserId && callerUserId === sessionCreatedBy && hasExplicitMinimumRole(callerRole, ROLES14.MEMBER);
28420
28594
  return isCreatorMember || isSuperadmin || isServiceExecutor;
28421
28595
  }
28422
28596
 
@@ -28436,11 +28610,11 @@ import {
28436
28610
  import { resolveMultiTenancyConfig as resolveMultiTenancyConfig2 } from "@agor/core/config";
28437
28611
  import {
28438
28612
  generateId as generateId5,
28439
- getCurrentTenantId as getCurrentTenantId3,
28613
+ getCurrentTenantId as getCurrentTenantId4,
28440
28614
  runWithoutTenantDatabaseScope as runWithoutTenantDatabaseScope3,
28441
- runWithTenantDatabaseScope as runWithTenantDatabaseScope3,
28442
- SessionRepository as SessionRepository5,
28443
- shortId as shortId17,
28615
+ runWithTenantDatabaseScope as runWithTenantDatabaseScope4,
28616
+ SessionRepository as SessionRepository6,
28617
+ shortId as shortId18,
28444
28618
  TaskRepository as TaskRepository2
28445
28619
  } from "@agor/core/db";
28446
28620
  import {
@@ -28495,7 +28669,7 @@ function buildSpawnConfigForSession(session, branchCwd, opts = {}) {
28495
28669
  return {
28496
28670
  sessionId: transcriptExists ? void 0 : session.session_id,
28497
28671
  resumeSessionId: transcriptExists ? session.session_id : void 0,
28498
- displayName: `cli-${shortId17(session.session_id)}`,
28672
+ displayName: `cli-${shortId18(session.session_id)}`,
28499
28673
  model: session.model_config?.model,
28500
28674
  effort: session.model_config?.effort,
28501
28675
  advisorModel: session.model_config?.advisorModel,
@@ -28612,7 +28786,7 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
28612
28786
  sessionCreatedBy: session.created_by
28613
28787
  })) {
28614
28788
  console.warn(
28615
- `[claude-cli-integration] not writing owner-scoped MCP config for session ${shortId17(session.session_id)}: caller ${opts.actor.user_id ?? "anonymous"} is not allowed to control the owner-scoped CLI MCP config`
28789
+ `[claude-cli-integration] not writing owner-scoped MCP config for session ${shortId18(session.session_id)}: caller ${opts.actor.user_id ?? "anonymous"} is not allowed to control the owner-scoped CLI MCP config`
28616
28790
  );
28617
28791
  return void 0;
28618
28792
  }
@@ -28629,12 +28803,12 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
28629
28803
  });
28630
28804
  return writeClaudeCliMcpConfigFile({
28631
28805
  mcpConfig,
28632
- sessionShortId: shortId17(session.session_id),
28806
+ sessionShortId: shortId18(session.session_id),
28633
28807
  targetUnixUser: resolveClaudeCliMcpConfigTargetUnixUser(config, session)
28634
28808
  });
28635
28809
  } catch (err) {
28636
28810
  console.warn(
28637
- `[claude-cli-integration] failed to write MCP config for session ${shortId17(session.session_id)}; Agor MCP tools will be unavailable in Claude CLI/RemoteTrigger:`,
28811
+ `[claude-cli-integration] failed to write MCP config for session ${shortId18(session.session_id)}; Agor MCP tools will be unavailable in Claude CLI/RemoteTrigger:`,
28638
28812
  err instanceof Error ? err.message : String(err)
28639
28813
  );
28640
28814
  return void 0;
@@ -28643,7 +28817,7 @@ async function writeClaudeCliMcpConfigForSession(app, session, opts = {}) {
28643
28817
 
28644
28818
  // src/services/terminals.ts
28645
28819
  function buildBranchShellTabName(branch) {
28646
- return `${branch.name} \xB7 ${shortId18(branch.branch_id)}`;
28820
+ return `${branch.name} \xB7 ${shortId19(branch.branch_id)}`;
28647
28821
  }
28648
28822
  function safeRealpath(pathToResolve) {
28649
28823
  try {
@@ -28674,7 +28848,7 @@ function writeEnvFile(userId, env, chownTo) {
28674
28848
  if (!userId) return null;
28675
28849
  try {
28676
28850
  const tmpDir = os2.tmpdir();
28677
- const envFile = path11.join(tmpDir, `agor-env-${shortId18(userId)}.sh`);
28851
+ const envFile = path11.join(tmpDir, `agor-env-${shortId19(userId)}.sh`);
28678
28852
  const exportLines = Object.entries(env).filter(([key]) => {
28679
28853
  const skipKeys = ["PATH", "HOME", "USER", "SHELL", "PWD", "OLDPWD", "TERM", "COLORTERM"];
28680
28854
  return !skipKeys.includes(key);
@@ -28860,7 +29034,7 @@ var TerminalsService = class {
28860
29034
  async resolveEnsureCliTab(sessionId, claimedBranchId, params) {
28861
29035
  if (!sessionId) return null;
28862
29036
  try {
28863
- const sessionRepo = new SessionRepository6(this.db);
29037
+ const sessionRepo = new SessionRepository7(this.db);
28864
29038
  const session = await sessionRepo.findById(sessionId).catch(() => null);
28865
29039
  if (session?.agentic_tool !== "claude-code-cli") return null;
28866
29040
  if (claimedBranchId && claimedBranchId !== session.branch_id) {
@@ -28915,7 +29089,7 @@ var TerminalsService = class {
28915
29089
  });
28916
29090
  const spawnCfg = buildSpawnConfigForSession(session, branch.path, { mcpConfigPath });
28917
29091
  const built = buildClaudeCliSpawn2(spawnCfg);
28918
- const tabName = session.cli_state?.zellij_tab_name ?? spawnCfg.displayName ?? `cli-${shortId18(session.session_id)}`;
29092
+ const tabName = session.cli_state?.zellij_tab_name ?? spawnCfg.displayName ?? `cli-${shortId19(session.session_id)}`;
28919
29093
  return {
28920
29094
  tabName,
28921
29095
  cwd: branch.path,
@@ -28944,12 +29118,12 @@ var TerminalsService = class {
28944
29118
  if (await waitForPendingStart()) {
28945
29119
  return this.createExecutorTerminal(data, params);
28946
29120
  }
28947
- const expectedSessionName = `agor-${shortId18(userId)}`;
29121
+ const expectedSessionName = `agor-${shortId19(userId)}`;
28948
29122
  if (!this.executorTerminals.get(userId)) {
28949
29123
  const adopted = await this.detectExistingExecutor(expectedSessionName);
28950
29124
  if (adopted) {
28951
29125
  console.log(
28952
- `[TerminalsService] adopting existing zellij executor for user ${shortId18(userId)} (sessionName=${expectedSessionName})`
29126
+ `[TerminalsService] adopting existing zellij executor for user ${shortId19(userId)} (sessionName=${expectedSessionName})`
28953
29127
  );
28954
29128
  this.executorTerminals.set(userId, {
28955
29129
  sessionName: expectedSessionName,
@@ -29076,7 +29250,7 @@ var TerminalsService = class {
29076
29250
  cwd = resolveBranchShellCwd(branch, finalUnixUser);
29077
29251
  }
29078
29252
  }
29079
- const userSessionSuffix = shortId18(userId);
29253
+ const userSessionSuffix = shortId19(userId);
29080
29254
  const sessionName = `agor-${userSessionSuffix}`;
29081
29255
  const daemonUrl = `http://localhost:${config.daemon?.port || 3030}`;
29082
29256
  const sessionToken = generateScopedServiceToken(this.app, params);
@@ -29105,7 +29279,7 @@ var TerminalsService = class {
29105
29279
  }
29106
29280
  },
29107
29281
  {
29108
- logPrefix: `[TerminalsService.executor ${shortId18(userId)}]`,
29282
+ logPrefix: `[TerminalsService.executor ${shortId19(userId)}]`,
29109
29283
  asUser: finalUnixUser || void 0,
29110
29284
  env: executorEnv,
29111
29285
  // Clean up map when executor exits (handles crashes too)
@@ -29197,7 +29371,7 @@ var TerminalsService = class {
29197
29371
  */
29198
29372
  handleExecutorExit(userId) {
29199
29373
  this.executorTerminals.delete(userId);
29200
- console.log(`[TerminalsService] Executor terminal exited for user ${shortId18(userId)}`);
29374
+ console.log(`[TerminalsService] Executor terminal exited for user ${shortId19(userId)}`);
29201
29375
  }
29202
29376
  };
29203
29377
 
@@ -29257,9 +29431,9 @@ import { Forbidden as Forbidden18, NotAuthenticated as NotAuthenticated10 } from
29257
29431
  import { isLikelyGitToken } from "@agor/core/git/pure";
29258
29432
  import {
29259
29433
  extractAgenticToolsPublicValues,
29260
- hasMinimumRole as hasMinimumRole11,
29434
+ hasMinimumRole as hasMinimumRole12,
29261
29435
  normalizeRole,
29262
- ROLES as ROLES15,
29436
+ ROLES as ROLES16,
29263
29437
  toAgenticToolsStatus
29264
29438
  } from "@agor/core/types";
29265
29439
 
@@ -29271,7 +29445,7 @@ import {
29271
29445
  } from "@agor/core/db";
29272
29446
  import { Forbidden as Forbidden17 } from "@agor/core/feathers";
29273
29447
  import { SlackConnector } from "@agor/core/gateway";
29274
- import { hasMinimumRole as hasMinimumRole10, ROLES as ROLES14 } from "@agor/core/types";
29448
+ import { hasMinimumRole as hasMinimumRole11, ROLES as ROLES15 } from "@agor/core/types";
29275
29449
  var NAMESPACE = "user_avatars";
29276
29450
  var SETTINGS_KEY = "settings";
29277
29451
  var DEFAULT_SETTINGS = {
@@ -29280,7 +29454,7 @@ var DEFAULT_SETTINGS = {
29280
29454
  gateway_channel_id: null
29281
29455
  };
29282
29456
  function isAdmin(params) {
29283
- return hasMinimumRole10(params?.user?.role, ROLES14.ADMIN);
29457
+ return hasMinimumRole11(params?.user?.role, ROLES15.ADMIN);
29284
29458
  }
29285
29459
  function requireAdmin(params) {
29286
29460
  if (params?.provider && !isAdmin(params)) {
@@ -29398,7 +29572,7 @@ var UserAvatarSyncManager = class {
29398
29572
  user: {
29399
29573
  user_id: "user-avatars-service",
29400
29574
  email: "user-avatars@agor.internal",
29401
- role: ROLES14.ADMIN,
29575
+ role: ROLES15.ADMIN,
29402
29576
  _isServiceAccount: true
29403
29577
  }
29404
29578
  }
@@ -29504,7 +29678,7 @@ var UserAvatarSyncManager = class {
29504
29678
  user: {
29505
29679
  user_id: "user-avatars-service",
29506
29680
  email: "user-avatars@agor.internal",
29507
- role: ROLES14.ADMIN,
29681
+ role: ROLES15.ADMIN,
29508
29682
  _isServiceAccount: true
29509
29683
  }
29510
29684
  }
@@ -29571,7 +29745,7 @@ function isServiceAccount(params) {
29571
29745
  return !!params?.user?._isServiceAccount;
29572
29746
  }
29573
29747
  function isAdmin2(params) {
29574
- return hasMinimumRole11(params?.user?.role, ROLES15.ADMIN);
29748
+ return hasMinimumRole12(params?.user?.role, ROLES16.ADMIN);
29575
29749
  }
29576
29750
  function isSelfEmailLookup(params, email) {
29577
29751
  const requesterEmail = params?.user?.email;
@@ -29700,8 +29874,8 @@ var UsersService = class {
29700
29874
  const hashedPassword = await hash(data.password, 10);
29701
29875
  const now = /* @__PURE__ */ new Date();
29702
29876
  const user_id = generateId6();
29703
- const role = data.role || ROLES15.MEMBER;
29704
- const defaultEmoji = role === ROLES15.ADMIN ? "\u2B50" : "\u{1F464}";
29877
+ const role = data.role || ROLES16.MEMBER;
29878
+ const defaultEmoji = role === ROLES16.ADMIN ? "\u2B50" : "\u{1F464}";
29705
29879
  const row = await insert(this.db, users2).values({
29706
29880
  user_id,
29707
29881
  email: data.email,
@@ -30060,21 +30234,37 @@ function createUsersService(db, app) {
30060
30234
  }
30061
30235
 
30062
30236
  // src/setup/socketio.ts
30063
- import { resolveTenantContext as resolveTenantContext2 } from "@agor/core/config";
30064
- import { shortId as shortId19 } from "@agor/core/db";
30237
+ import { resolveTenantContext as resolveTenantContext3 } from "@agor/core/config";
30238
+ import { shortId as shortId20 } from "@agor/core/db";
30065
30239
  import jwt5 from "jsonwebtoken";
30066
30240
  function userRoomName(userId) {
30067
30241
  return `user:${userId}`;
30068
30242
  }
30069
30243
 
30070
30244
  // src/utils/mcp-header-secrets.ts
30245
+ init_executor_session_token();
30071
30246
  import { redactMCPAuthSecrets } from "@agor/core/tools/mcp/auth-secrets";
30072
30247
  import { redactMCPCustomHeaders } from "@agor/core/tools/mcp/http-headers";
30248
+ import jwt6 from "jsonwebtoken";
30073
30249
  function shouldExposeMCPServerSecretsForSessionToken(params, options = {}) {
30074
- const payload = params?.authentication?.payload;
30075
- const sessionId = params?.session_id ?? payload?.session_id ?? payload?.sessionId;
30250
+ const payload = params?.authentication?.payload ?? decodeExecutorSessionPayload(params);
30251
+ const sessionId = params?.session_id ?? getPayloadSessionId(payload);
30076
30252
  return !!params?.provider && (params.authentication?.strategy === "session-token" || payload?.type === "executor-session") && !!sessionId && (!options.sessionId || sessionId === options.sessionId);
30077
30253
  }
30254
+ function decodeExecutorSessionPayload(params) {
30255
+ if (params?.authentication?.strategy !== "jwt" || !params.authentication.accessToken) {
30256
+ return void 0;
30257
+ }
30258
+ const decoded = jwt6.decode(params.authentication.accessToken);
30259
+ if (!decoded || typeof decoded !== "object" || Array.isArray(decoded)) {
30260
+ return void 0;
30261
+ }
30262
+ if (!isExecutorSessionTokenPayload(decoded)) return void 0;
30263
+ return decoded;
30264
+ }
30265
+ function getPayloadSessionId(payload) {
30266
+ return payload ? getExecutorSessionTokenSessionId(payload) : void 0;
30267
+ }
30078
30268
  function shouldExposeMCPServerSecrets(params, options = {}) {
30079
30269
  if (!params?.provider) return true;
30080
30270
  if (params.user?._isServiceAccount || params.user?.role === "service") return true;
@@ -30175,7 +30365,7 @@ async function restoreFile(filePath, payload) {
30175
30365
  }
30176
30366
 
30177
30367
  // src/utils/session-state-hooks.ts
30178
- import { SerializedSessionRepository, shortId as shortId20 } from "@agor/core/db";
30368
+ import { SerializedSessionRepository, shortId as shortId21 } from "@agor/core/db";
30179
30369
  var STALE_PROCESSING_THRESHOLD_MS = 3e4;
30180
30370
  async function pullIfNeeded(ctx) {
30181
30371
  const repo = new SerializedSessionRepository(ctx.db);
@@ -30193,7 +30383,7 @@ async function pullIfNeeded(ctx) {
30193
30383
  const age = Date.now() - latest.created_at;
30194
30384
  if (age > STALE_PROCESSING_THRESHOLD_MS) {
30195
30385
  console.log(
30196
- `[session-state] Cleaning stale 'processing' row ${shortId20(latest.id)} (age: ${Math.round(age / 1e3)}s)`
30386
+ `[session-state] Cleaning stale 'processing' row ${shortId21(latest.id)} (age: ${Math.round(age / 1e3)}s)`
30197
30387
  );
30198
30388
  await repo.deleteById(latest.id);
30199
30389
  latest = await repo.findLatestDone(ctx.sessionId);
@@ -30216,12 +30406,12 @@ async function pullIfNeeded(ctx) {
30216
30406
  }
30217
30407
  if (!latest.payload) {
30218
30408
  console.warn(
30219
- `[session-state] 'done' row ${shortId20(latest.id)} has no payload, skipping restore`
30409
+ `[session-state] 'done' row ${shortId21(latest.id)} has no payload, skipping restore`
30220
30410
  );
30221
30411
  return;
30222
30412
  }
30223
30413
  console.log(
30224
- `[session-state] Restoring session file from DB (row ${shortId20(latest.id)}, turn ${latest.turn_index})`
30414
+ `[session-state] Restoring session file from DB (row ${shortId21(latest.id)}, turn ${latest.turn_index})`
30225
30415
  );
30226
30416
  await restoreFile(filePath, latest.payload);
30227
30417
  }
@@ -30297,6 +30487,13 @@ async function registerServices(ctx) {
30297
30487
  sessionsService.setExecuteHandler(
30298
30488
  createExecuteHandler(ctx, sessionsService, sessionTokenService)
30299
30489
  );
30490
+ app.use("/session-streams", createSessionStreamsService(app), {
30491
+ methods: ["create", "remove"]
30492
+ });
30493
+ app.service("/session-streams").hooks({
30494
+ before: { all: [ctx.requireAuth] }
30495
+ });
30496
+ app.service("/session-streams").publish(() => []);
30300
30497
  app.use("/tasks", createTasksService(db, app), {
30301
30498
  // Custom events not in this list are dropped at the FeathersJS transport
30302
30499
  // boundary — they fire on the local EventEmitter but never reach socket
@@ -30499,7 +30696,7 @@ async function registerServices(ctx) {
30499
30696
  app.use("/gateway-channels/test", createGatewayChannelsTestService(db));
30500
30697
  app.service("gateway-channels/test").hooks({
30501
30698
  before: {
30502
- create: [ctx.requireAuth, requireMinimumRole(ROLES16.ADMIN, "test gateway channels")]
30699
+ create: [ctx.requireAuth, requireMinimumRole(ROLES17.ADMIN, "test gateway channels")]
30503
30700
  }
30504
30701
  });
30505
30702
  app.use("/thread-session-map", createThreadSessionMapService(db));
@@ -30537,9 +30734,9 @@ async function registerServices(ctx) {
30537
30734
  app.use("/cursor-models", createCursorModelsService(db));
30538
30735
  app.service("/cursor-models").hooks({ before: { find: [ctx.requireAuth] } });
30539
30736
  const branchRepository = new BranchRepository9(db);
30540
- const { UsersRepository: UsersRepository9, SessionRepository: SessionRepository7 } = await import("@agor/core/db");
30737
+ const { UsersRepository: UsersRepository9, SessionRepository: SessionRepository8 } = await import("@agor/core/db");
30541
30738
  const usersRepository = new UsersRepository9(db);
30542
- const sessionsRepository = new SessionRepository7(db);
30739
+ const sessionsRepository = new SessionRepository8(db);
30543
30740
  if (svcEnabled("file_browser")) {
30544
30741
  app.use("/context", createContextService(branchRepository));
30545
30742
  app.use("/file", createFileService(branchRepository));
@@ -30800,7 +30997,7 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
30800
30997
  );
30801
30998
  }
30802
30999
  }
30803
- const logPrefix = `[Executor ${shortId21(sessionId)}]`;
31000
+ const logPrefix = `[Executor ${shortId22(sessionId)}]`;
30804
31001
  spawnExecutor(executorPayload, {
30805
31002
  cwd,
30806
31003
  asUser: executorUnixUser || void 0,
@@ -30825,7 +31022,7 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
30825
31022
  const latestTaskId = currentSession.tasks?.[currentSession.tasks.length - 1];
30826
31023
  if (latestTaskId && latestTaskId !== taskId) {
30827
31024
  console.log(
30828
- `\u23ED\uFE0F [Executor] Task ${shortId21(taskId)} is not the latest (latest: ${shortId21(latestTaskId)}), skipping safety net`
31025
+ `\u23ED\uFE0F [Executor] Task ${shortId22(taskId)} is not the latest (latest: ${shortId22(latestTaskId)}), skipping safety net`
30829
31026
  );
30830
31027
  } else if (isSessionExecuting(currentSession) || currentSession.status === SessionStatus5.TIMED_OUT) {
30831
31028
  try {
@@ -30840,27 +31037,27 @@ function createExecuteHandler(ctx, sessionsService, sessionTokenService) {
30840
31037
  params
30841
31038
  );
30842
31039
  console.log(
30843
- `\u2705 [Executor] Task ${shortId21(taskId)} marked as FAILED after executor exit (code: ${code})`
31040
+ `\u2705 [Executor] Task ${shortId22(taskId)} marked as FAILED after executor exit (code: ${code})`
30844
31041
  );
30845
31042
  } else {
30846
31043
  console.log(
30847
- `\u26A0\uFE0F [Executor] Task ${shortId21(taskId)} already ${currentTask.status}, but session still ${currentSession.status} \u2014 repairing session state`
31044
+ `\u26A0\uFE0F [Executor] Task ${shortId22(taskId)} already ${currentTask.status}, but session still ${currentSession.status} \u2014 repairing session state`
30848
31045
  );
30849
31046
  await app.service("sessions").patch(sessionId, { status: SessionStatus5.IDLE, ready_for_prompt: true }, params);
30850
31047
  }
30851
31048
  } catch (taskError) {
30852
31049
  console.error(
30853
- `\u26A0\uFE0F [Executor] Failed to mark task ${shortId21(taskId)} as FAILED, falling back to session IDLE update:`,
31050
+ `\u26A0\uFE0F [Executor] Failed to mark task ${shortId22(taskId)} as FAILED, falling back to session IDLE update:`,
30854
31051
  taskError
30855
31052
  );
30856
31053
  await app.service("sessions").patch(sessionId, { status: SessionStatus5.IDLE, ready_for_prompt: true }, params);
30857
31054
  console.log(
30858
- `\u2705 [Executor] Session ${shortId21(sessionId)} status updated to IDLE after executor exit (was: ${currentSession.status})`
31055
+ `\u2705 [Executor] Session ${shortId22(sessionId)} status updated to IDLE after executor exit (was: ${currentSession.status})`
30859
31056
  );
30860
31057
  }
30861
31058
  } else {
30862
31059
  console.log(
30863
- `\u2139\uFE0F [Executor] Session ${shortId21(sessionId)} already in ${currentSession.status} state, skipping IDLE update`
31060
+ `\u2139\uFE0F [Executor] Session ${shortId22(sessionId)} already in ${currentSession.status} state, skipping IDLE update`
30864
31061
  );
30865
31062
  }
30866
31063
  } catch (error) {
@@ -31016,6 +31213,7 @@ async function registerMCPServices(ctx, sessionsService) {
31016
31213
  mcpServerId: opts.mcpServerId,
31017
31214
  userId: opts.userId,
31018
31215
  oauthMode: opts.oauthMode,
31216
+ tenantId: opts.tenantId ?? getCurrentTenantId6(),
31019
31217
  socketId: opts.socketId,
31020
31218
  createdAt: Date.now(),
31021
31219
  tokenResolve,
@@ -31039,6 +31237,31 @@ async function registerMCPServices(ctx, sessionsService) {
31039
31237
  }
31040
31238
  return base;
31041
31239
  }
31240
+ const tenantIdFromParams = (params) => params?.tenant?.tenant_id ?? getCurrentTenantId6();
31241
+ const persistOAuthTokenForPendingFlow = async (tokenResponse, pendingFlow, logPrefix) => {
31242
+ const work = () => persistOAuthToken(
31243
+ db,
31244
+ tokenResponse,
31245
+ pendingFlow.mcpUrl,
31246
+ {
31247
+ ...pendingFlow,
31248
+ clientId: pendingFlow.context.clientId,
31249
+ clientSecret: pendingFlow.context.clientSecret,
31250
+ tokenEndpoint: pendingFlow.context.tokenEndpoint
31251
+ },
31252
+ logPrefix
31253
+ );
31254
+ if (pendingFlow.tenantId) {
31255
+ await runInOAuthTenantScope(db, pendingFlow.tenantId, work);
31256
+ return;
31257
+ }
31258
+ if (isPostgresDatabase7(db) && pendingFlow.mcpServerId) {
31259
+ throw new Error(
31260
+ "Missing tenant context for MCP OAuth callback. Please restart the OAuth flow."
31261
+ );
31262
+ }
31263
+ await work();
31264
+ };
31042
31265
  const oauthCallbackHandler = async (req, res) => {
31043
31266
  res.setHeader("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'");
31044
31267
  res.setHeader("X-Content-Type-Options", "nosniff");
@@ -31081,18 +31304,7 @@ async function registerMCPServices(ctx, sessionsService) {
31081
31304
  const { completeMCPOAuthFlow } = await import("@agor/core/tools/mcp/oauth-mcp-transport");
31082
31305
  const tokenResponse = await completeMCPOAuthFlow(pendingFlow.context, code, state);
31083
31306
  pendingOAuthFlows.delete(state);
31084
- await persistOAuthToken(
31085
- db,
31086
- tokenResponse,
31087
- pendingFlow.mcpUrl,
31088
- {
31089
- ...pendingFlow,
31090
- clientId: pendingFlow.context.clientId,
31091
- clientSecret: pendingFlow.context.clientSecret,
31092
- tokenEndpoint: pendingFlow.context.tokenEndpoint
31093
- },
31094
- "OAuth Callback"
31095
- );
31307
+ await persistOAuthTokenForPendingFlow(tokenResponse, pendingFlow, "OAuth Callback");
31096
31308
  if (app.io) {
31097
31309
  const oauthEvent = {
31098
31310
  state,
@@ -31221,6 +31433,7 @@ async function registerMCPServices(ctx, sessionsService) {
31221
31433
  // call (writes to the shared MCP server row, not per-user).
31222
31434
  oauthMode: "shared",
31223
31435
  clientId: data.client_id,
31436
+ tenantId: tenantIdFromParams(params),
31224
31437
  socketId: connection?.id
31225
31438
  });
31226
31439
  } catch (err) {
@@ -31423,6 +31636,7 @@ async function registerMCPServices(ctx, sessionsService) {
31423
31636
  try {
31424
31637
  console.log("[OAuth Start] Starting two-phase OAuth flow for:", data.mcp_url);
31425
31638
  const userId = params?.user?.user_id;
31639
+ const tenantId = tenantIdFromParams(params);
31426
31640
  let oauthMode;
31427
31641
  let authorizationUrlOverride;
31428
31642
  let tokenUrlOverride;
@@ -31430,8 +31644,10 @@ async function registerMCPServices(ctx, sessionsService) {
31430
31644
  let clientIdFromConfig;
31431
31645
  let scopeOverride;
31432
31646
  if (data.mcp_server_id) {
31433
- const mcpServerRepo = new MCPServerRepository4(db);
31434
- const server = await mcpServerRepo.findById(data.mcp_server_id);
31647
+ const server = await runInOAuthTenantScope(db, tenantId, () => {
31648
+ const mcpServerRepo = new MCPServerRepository4(db);
31649
+ return mcpServerRepo.findById(data.mcp_server_id);
31650
+ });
31435
31651
  if (server?.auth?.type === "oauth") {
31436
31652
  oauthMode = server.auth.oauth_mode || "per_user";
31437
31653
  authorizationUrlOverride = server.auth.oauth_authorization_url;
@@ -31479,6 +31695,7 @@ async function registerMCPServices(ctx, sessionsService) {
31479
31695
  authorizationUrlOverride,
31480
31696
  tokenUrlOverride,
31481
31697
  scope: scopeOverride,
31698
+ tenantId,
31482
31699
  socketId
31483
31700
  });
31484
31701
  } catch (err) {
@@ -31523,18 +31740,13 @@ async function registerMCPServices(ctx, sessionsService) {
31523
31740
  };
31524
31741
  const tokenResponse = await completeMCPOAuthFlow(pendingFlow.context, code, state);
31525
31742
  pendingOAuthFlows.delete(state);
31526
- await persistOAuthToken(
31527
- db,
31528
- tokenResponse,
31529
- pendingFlow.mcpUrl,
31530
- {
31531
- ...pendingFlow,
31532
- clientId: pendingFlow.context.clientId,
31533
- clientSecret: pendingFlow.context.clientSecret,
31534
- tokenEndpoint: pendingFlow.context.tokenEndpoint
31535
- },
31536
- "OAuth Complete"
31537
- );
31743
+ const activeTenantId = getCurrentTenantId6();
31744
+ if (pendingFlow.tenantId && activeTenantId && pendingFlow.tenantId !== activeTenantId) {
31745
+ throw new Error(
31746
+ "OAuth flow belongs to a different tenant. Please restart the OAuth flow."
31747
+ );
31748
+ }
31749
+ await persistOAuthTokenForPendingFlow(tokenResponse, pendingFlow, "OAuth Complete");
31538
31750
  return { success: true, message: "OAuth authentication successful!", tokenObtained: true };
31539
31751
  } catch (error) {
31540
31752
  console.error("[OAuth Complete] Error:", error);
@@ -31591,17 +31803,35 @@ async function registerMCPServices(ctx, sessionsService) {
31591
31803
  }
31592
31804
  const sessionId = params?.session_id;
31593
31805
  const trustedInternalOrService = shouldExposeMCPServerSecrets(params);
31594
- const trustedSessionExecutor = shouldExposeMCPServerSecretsForSessionToken(params, {
31806
+ let trustedSessionExecutor = shouldExposeMCPServerSecretsForSessionToken(params, {
31595
31807
  sessionId
31596
31808
  });
31809
+ let executorSessionId = sessionId;
31810
+ if (!trustedSessionExecutor && params?.provider && data.executorSessionToken) {
31811
+ const executorTokenService = app.sessionTokenService;
31812
+ const sessionInfo = await executorTokenService?.validateToken(
31813
+ data.executorSessionToken,
31814
+ {}
31815
+ );
31816
+ if (sessionInfo?.session_id) {
31817
+ executorSessionId = sessionInfo.session_id;
31818
+ trustedSessionExecutor = true;
31819
+ }
31820
+ }
31597
31821
  if (!trustedInternalOrService && !trustedSessionExecutor) {
31598
31822
  throw new Forbidden19("oauth-auth-headers is only available to trusted executor paths");
31599
31823
  }
31600
31824
  const userTokenRepo = new UserMCPOAuthTokenRepository3(db);
31601
31825
  const mcpServerRepo = new MCPServerRepository4(db);
31602
31826
  if (trustedSessionExecutor) {
31827
+ if (!executorSessionId) {
31828
+ throw new Forbidden19("oauth-auth-headers requires executor session scope");
31829
+ }
31603
31830
  const sessionMcpRepo = new SessionMCPServerRepository3(db);
31604
- const attachedServers = await sessionMcpRepo.listServers(sessionId, true);
31831
+ const attachedServers = await sessionMcpRepo.listServers(
31832
+ executorSessionId,
31833
+ true
31834
+ );
31605
31835
  const globalServers = await mcpServerRepo.findAll({ scope: "global", enabled: true });
31606
31836
  const allowedServerIds = /* @__PURE__ */ new Set([
31607
31837
  ...globalServers.map((server) => server.mcp_server_id),
@@ -31741,7 +31971,7 @@ async function registerMCPServices(ctx, sessionsService) {
31741
31971
  const { restoreRedactedMCPAuthSecrets } = await import("@agor/core/tools/mcp/auth-secrets");
31742
31972
  const { resolveMCPAuthHeaders } = await import("@agor/core/tools/mcp/jwt-auth");
31743
31973
  const { mergeMCPRemoteHeaders, restoreRedactedMCPCustomHeaders } = await import("@agor/core/tools/mcp/http-headers");
31744
- const { hasMinimumRole: hasMinimumRole12, ROLES: ROLES17 } = await import("@agor/core/types");
31974
+ const { hasMinimumRole: hasMinimumRole13, ROLES: ROLES18 } = await import("@agor/core/types");
31745
31975
  const mcpServerRepo = new MCPServerRepository4(db);
31746
31976
  const validateUrl = (url) => {
31747
31977
  try {
@@ -31776,7 +32006,7 @@ async function registerMCPServices(ctx, sessionsService) {
31776
32006
  if (params?.provider && params.user) {
31777
32007
  const userId2 = params.user.user_id;
31778
32008
  const userRole = params.user.role?.toLowerCase();
31779
- const isAdmin3 = hasMinimumRole12(userRole, ROLES17.ADMIN);
32009
+ const isAdmin3 = hasMinimumRole13(userRole, ROLES18.ADMIN);
31780
32010
  const isOwner = server.owner_user_id === userId2;
31781
32011
  if (server.scope === "global" && !isOwner && !isAdmin3)
31782
32012
  return {
@@ -31805,7 +32035,7 @@ async function registerMCPServices(ctx, sessionsService) {
31805
32035
  if (params?.provider && params.user) {
31806
32036
  const userId2 = params.user.user_id;
31807
32037
  const userRole = params.user.role?.toLowerCase();
31808
- const isAdmin3 = hasMinimumRole12(userRole, ROLES17.ADMIN);
32038
+ const isAdmin3 = hasMinimumRole13(userRole, ROLES18.ADMIN);
31809
32039
  const isOwner = server.owner_user_id === userId2;
31810
32040
  if (server.scope === "global" && !isOwner && !isAdmin3)
31811
32041
  return {
@@ -31898,6 +32128,7 @@ async function registerMCPServices(ctx, sessionsService) {
31898
32128
  // call). Without a serverId nothing is persisted to the DB; the
31899
32129
  // daemon-level cache below carries the token for this request.
31900
32130
  oauthMode: "shared",
32131
+ tenantId: tenantIdFromParams(params),
31901
32132
  socketId: connection?.id
31902
32133
  });
31903
32134
  const tokenResponse = await started.awaitToken();
@@ -32072,7 +32303,7 @@ async function registerMCPServices(ctx, sessionsService) {
32072
32303
  return { oauthCallbackHandler };
32073
32304
  }
32074
32305
  async function bootstrapSuperadminUsers(config, usersService, allowSuperadmin) {
32075
- const { ROLES: ROLES17 } = await import("@agor/core/types");
32306
+ const { ROLES: ROLES18 } = await import("@agor/core/types");
32076
32307
  const bootstrapUsers = config.execution?.bootstrap_superadmin_users ?? [];
32077
32308
  if (bootstrapUsers.length === 0) return;
32078
32309
  if (!allowSuperadmin) {
@@ -32087,15 +32318,15 @@ async function bootstrapSuperadminUsers(config, usersService, allowSuperadmin) {
32087
32318
  if (!userId) continue;
32088
32319
  try {
32089
32320
  const user = await usersService.get(userId);
32090
- if (user.role === ROLES17.SUPERADMIN) continue;
32091
- await usersService.patch(userId, { role: ROLES17.SUPERADMIN });
32321
+ if (user.role === ROLES18.SUPERADMIN) continue;
32322
+ await usersService.patch(userId, { role: ROLES18.SUPERADMIN });
32092
32323
  promotedCount++;
32093
32324
  console.log(
32094
- `[RBAC] Bootstrap promoted user ${shortId21(userId)} (${user.email}) to superadmin`
32325
+ `[RBAC] Bootstrap promoted user ${shortId22(userId)} (${user.email}) to superadmin`
32095
32326
  );
32096
32327
  } catch (error) {
32097
32328
  console.warn(
32098
- `[RBAC] Failed to bootstrap superadmin for user ${shortId21(userId)}: ${error instanceof Error ? error.message : String(error)}`
32329
+ `[RBAC] Failed to bootstrap superadmin for user ${shortId22(userId)}: ${error instanceof Error ? error.message : String(error)}`
32099
32330
  );
32100
32331
  }
32101
32332
  }