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
@@ -18291,11 +18291,15 @@ import {
18291
18291
  ThreadSessionMapRepository
18292
18292
  } from "@agor/core/db";
18293
18293
  import {
18294
- getConnector
18294
+ buildSlackManifest,
18295
+ getConnector,
18296
+ requiredBotEvents,
18297
+ requiredBotScopes
18295
18298
  } from "@agor/core/gateway";
18296
18299
  import {
18297
18300
  GATEWAY_REDACTED_SENTINEL,
18298
18301
  GATEWAY_SENSITIVE_CONFIG_FIELDS,
18302
+ getRequiredSecretFields,
18299
18303
  hasMinimumRole as hasMinimumRole2,
18300
18304
  ROLES as ROLES2
18301
18305
  } from "@agor/core/types";
@@ -18304,6 +18308,19 @@ function requireAdmin(ctx, action) {
18304
18308
  throw new Error(`Access denied: admin role required to ${action}`);
18305
18309
  }
18306
18310
  }
18311
+ async function resolveCallerSessionBranchId(ctx) {
18312
+ if (!ctx.sessionId) return null;
18313
+ const session = await new SessionRepository2(ctx.db).findById(ctx.sessionId);
18314
+ if (!session) {
18315
+ throw new Error("Gateway access denied: calling session not found");
18316
+ }
18317
+ return session.branch_id;
18318
+ }
18319
+ function sessionBranchReadDeniedError() {
18320
+ return new Error(
18321
+ "Gateway read denied: this Slack thread belongs to a gateway channel targeting a different branch than the calling session's. Sessions can read Slack thread history only through gateway channels whose target branch matches their own."
18322
+ );
18323
+ }
18307
18324
  async function canUseGatewayOutbound(ctx, branchRepo, branch) {
18308
18325
  if (hasMinimumRole2(ctx.authenticatedUser?.role, ROLES2.ADMIN)) return true;
18309
18326
  const userId = ctx.userId;
@@ -18382,44 +18399,48 @@ var gatewayChannelCreateSchema = external_exports.strictObject({
18382
18399
  agenticConfig: agenticConfigSchema.optional()
18383
18400
  }).superRefine((value, issue2) => {
18384
18401
  const config2 = value.config ?? {};
18385
- if (value.channelType === "slack") {
18386
- if (!config2.bot_token) {
18387
- issue2.addIssue({
18388
- code: "custom",
18389
- path: ["config", "bot_token"],
18390
- message: "config.bot_token is required for Slack. Prefer a bot token stored outside the transcript when possible."
18391
- });
18392
- }
18393
- if (config2.connection_mode === "socket" && !config2.app_token) {
18394
- issue2.addIssue({
18395
- code: "custom",
18396
- path: ["config", "app_token"],
18397
- message: "config.app_token is required for Slack Socket Mode."
18398
- });
18399
- }
18400
- }
18401
- if (value.channelType === "github") {
18402
- for (const field of ["app_id", "private_key", "installation_id", "watch_repos"]) {
18402
+ if (value.enabled !== false) {
18403
+ const requiredSecretMessages = {
18404
+ bot_token: "config.bot_token is required for Slack. Prefer a bot token stored outside the transcript when possible.",
18405
+ app_token: "config.app_token is required for Slack Socket Mode.",
18406
+ private_key: "config.private_key is required for GitHub gateway channels.",
18407
+ app_password: "config.app_password is required for Teams gateway channels."
18408
+ };
18409
+ for (const field of getRequiredSecretFields(value.channelType, config2)) {
18403
18410
  if (!config2[field]) {
18404
18411
  issue2.addIssue({
18405
18412
  code: "custom",
18406
18413
  path: ["config", field],
18407
- message: `config.${field} is required for GitHub gateway channels.`
18414
+ message: requiredSecretMessages[field] ?? `config.${field} is required for ${value.channelType} gateway channels.`
18408
18415
  });
18409
18416
  }
18410
18417
  }
18411
18418
  }
18412
- if (value.channelType === "teams") {
18413
- for (const field of ["app_id", "app_password"]) {
18419
+ if (value.channelType === "github") {
18420
+ for (const field of ["app_id", "installation_id", "watch_repos"]) {
18414
18421
  if (!config2[field]) {
18415
18422
  issue2.addIssue({
18416
18423
  code: "custom",
18417
18424
  path: ["config", field],
18418
- message: `config.${field} is required for Teams gateway channels.`
18425
+ message: `config.${field} is required for GitHub gateway channels.`
18419
18426
  });
18420
18427
  }
18421
18428
  }
18422
18429
  }
18430
+ if (value.channelType === "teams" && !config2.app_id) {
18431
+ issue2.addIssue({
18432
+ code: "custom",
18433
+ path: ["config", "app_id"],
18434
+ message: "config.app_id is required for Teams gateway channels."
18435
+ });
18436
+ }
18437
+ if (value.channelType === "slack" && config2.align_slack_users !== true && !value.agorUserId) {
18438
+ issue2.addIssue({
18439
+ code: "custom",
18440
+ path: ["agorUserId"],
18441
+ message: "Run-as-selected-user needs agorUserId \u2014 set config.align_slack_users:true to align by email, or pass agorUserId."
18442
+ });
18443
+ }
18423
18444
  });
18424
18445
  var slackThreadHistorySchema = external_exports.strictObject({
18425
18446
  sessionId: mcpOptionalId(
@@ -18525,16 +18546,23 @@ async function resolveSlackThreadHistoryTarget(ctx, args) {
18525
18546
  const channelRepo = new GatewayChannelRepository(ctx.db);
18526
18547
  const threadMapRepo = new ThreadSessionMapRepository(ctx.db);
18527
18548
  const branchRepo = new BranchRepository3(ctx.db);
18549
+ const callerSessionBranchId = await resolveCallerSessionBranchId(ctx);
18528
18550
  if (args.sessionId) {
18529
18551
  const session = await ctx.app.service("sessions").get(args.sessionId, ctx.baseServiceParams);
18530
18552
  const mapping2 = await threadMapRepo.findBySession(session.session_id);
18531
18553
  if (!mapping2) {
18532
18554
  throw new Error(`No gateway thread mapping found for session ${session.session_id}.`);
18533
18555
  }
18556
+ if (callerSessionBranchId && mapping2.branch_id !== callerSessionBranchId) {
18557
+ throw sessionBranchReadDeniedError();
18558
+ }
18534
18559
  const channel2 = await channelRepo.findById(mapping2.channel_id);
18535
18560
  if (!channel2) {
18536
18561
  throw new Error(`Gateway channel not found for session mapping ${mapping2.id}.`);
18537
18562
  }
18563
+ if (callerSessionBranchId && channel2.target_branch_id !== callerSessionBranchId) {
18564
+ throw sessionBranchReadDeniedError();
18565
+ }
18538
18566
  const branch2 = await branchRepo.findById(mapping2.branch_id);
18539
18567
  return {
18540
18568
  channel: channel2,
@@ -18549,6 +18577,9 @@ async function resolveSlackThreadHistoryTarget(ctx, args) {
18549
18577
  if (!channel) {
18550
18578
  throw new Error(`Gateway channel not found: ${args.gatewayChannelId}`);
18551
18579
  }
18580
+ if (callerSessionBranchId && channel.target_branch_id !== callerSessionBranchId) {
18581
+ throw sessionBranchReadDeniedError();
18582
+ }
18552
18583
  const mapping = await threadMapRepo.findByChannelAndThread(channel.id, args.threadId);
18553
18584
  if (mapping) {
18554
18585
  const branch2 = await branchRepo.findById(mapping.branch_id);
@@ -18658,6 +18689,51 @@ function toServiceUpdateData(args) {
18658
18689
  }
18659
18690
  return updates;
18660
18691
  }
18692
+ var slackManifestGenerateSchema = external_exports.strictObject({
18693
+ appName: mcpRequiredString("appName", 'Slack app display name, e.g. "Agor".'),
18694
+ botDisplayName: mcpOptionalNonEmptyString(
18695
+ "botDisplayName",
18696
+ "Bot user display name. Defaults to appName."
18697
+ ),
18698
+ publicChannels: external_exports.boolean().default(false).describe("Listen in public channels (#channel) via @mention."),
18699
+ privateChannels: external_exports.boolean().default(false).describe("Listen in private channels (groups) via @mention."),
18700
+ groupDms: external_exports.boolean().default(false).describe("Listen in group DMs (multi-person IMs) via @mention."),
18701
+ alignUsers: external_exports.boolean().default(true).describe(
18702
+ "Resolve Slack user email \u2192 Agor user (adds the users:read.email scope). Defaults to true: each Slack user runs as their matched Agor account and unmatched users are rejected, so no fixed run-as user is needed. Set false to run every message as one fixed Agor user (then pass agorUserId to agor_gateway_channels_create)."
18703
+ ),
18704
+ outbound: external_exports.boolean().default(false).describe("Proactive outbound: post to channels by name and DM users by email."),
18705
+ restrictToChannelIds: external_exports.array(external_exports.string().min(1)).optional().describe(
18706
+ "Slack channel ID whitelist. Maps to config.allowed_channel_ids when you call agor_gateway_channels_create; it does NOT change the manifest scopes or events."
18707
+ )
18708
+ });
18709
+ function toSlackWizardOptions(args) {
18710
+ return {
18711
+ appName: args.appName,
18712
+ ...args.botDisplayName ? { botDisplayName: args.botDisplayName } : {},
18713
+ publicChannels: args.publicChannels,
18714
+ privateChannels: args.privateChannels,
18715
+ groupDms: args.groupDms,
18716
+ alignUsers: args.alignUsers,
18717
+ outbound: args.outbound
18718
+ };
18719
+ }
18720
+ function toCreateChannelConfigHint(args) {
18721
+ const config2 = {
18722
+ connection_mode: "socket",
18723
+ enable_channels: args.publicChannels,
18724
+ enable_groups: args.privateChannels,
18725
+ enable_mpim: args.groupDms,
18726
+ align_slack_users: args.alignUsers,
18727
+ outbound_enabled: args.outbound
18728
+ };
18729
+ if (args.restrictToChannelIds && args.restrictToChannelIds.length > 0) {
18730
+ config2.allowed_channel_ids = args.restrictToChannelIds;
18731
+ }
18732
+ return { channelType: "slack", config: config2 };
18733
+ }
18734
+ function identityModeSetupStep(alignUsers) {
18735
+ return alignUsers ? "Identity: the channel is set to align Slack users \u2014 each Slack user runs as their matched Agor account and unmatched users are rejected, so no run-as user is needed. Tell me if you would rather every message run as one fixed Agor user (that requires picking a user and passing agorUserId)." : "Identity: the channel is set to run every message as one fixed Agor user, which requires passing agorUserId to agor_gateway_channels_create. Tell me if you would rather align Slack users so each runs as their own matched Agor account instead.";
18736
+ }
18661
18737
  function registerGatewayChannelTools(server, ctx) {
18662
18738
  server.registerTool(
18663
18739
  "agor_gateway_channels_list",
@@ -18703,7 +18779,7 @@ function registerGatewayChannelTools(server, ctx) {
18703
18779
  server.registerTool(
18704
18780
  "agor_gateway_channels_create",
18705
18781
  {
18706
- description: 'Create a gateway channel definition (admin-only) through the same gateway-channels service used by the UI. Current connectors: Slack, GitHub, Teams. Slack example config: { bot_token, app_token, connection_mode:"socket", enable_channels:true, require_mention:true, allowed_channel_ids:["C123"] }. Secrets are encrypted by the service and returned redacted; prefer environment/template references where possible because raw secrets in tool arguments may appear in the MCP transcript.',
18782
+ description: 'Create a gateway channel definition (admin-only) through the same gateway-channels service used by the UI. Current connectors: Slack, GitHub, Teams. For interactive/agent-driven setup, create the channel disabled and without secrets (enabled:false, no tokens), then collect credentials with agor_widgets_request_gateway_token so the user enters them in a secure inline form \u2014 raw secrets passed in tool arguments leak into the MCP transcript. Passing secrets directly here is for programmatic/non-interactive use only. Non-interactive Slack example config: { bot_token, app_token, connection_mode:"socket", enable_channels:true, require_mention:true, allowed_channel_ids:["C123"] }. Secrets are encrypted by the service and returned redacted.',
18707
18783
  annotations: { destructiveHint: false, idempotentHint: false },
18708
18784
  inputSchema: gatewayChannelCreateSchema
18709
18785
  },
@@ -18713,12 +18789,50 @@ function registerGatewayChannelTools(server, ctx) {
18713
18789
  return textResult({
18714
18790
  gateway_channel: redactGatewayChannel(created),
18715
18791
  next_steps: [
18792
+ "If this channel was created disabled without tokens (the recommended interactive path), collect its credentials by calling agor_widgets_request_gateway_token for this channel so the user enters the tokens in the secure form that appears at the end of this message. Do NOT ask the user to paste xoxb-/xapp- tokens into the chat, and do NOT pass tokens as agor_gateway_channels_create arguments during interactive setup.",
18793
+ ...created.channel_type === "slack" ? [
18794
+ identityModeSetupStep(
18795
+ created.config?.align_slack_users === true
18796
+ )
18797
+ ] : [],
18716
18798
  "Verify the channel in Settings > Gateway Channels or with agor_gateway_channels_list.",
18717
18799
  "Channel credentials, env vars, and inbound channel keys are intentionally redacted from MCP responses."
18718
18800
  ]
18719
18801
  });
18720
18802
  }
18721
18803
  );
18804
+ server.registerTool(
18805
+ "agor_gateway_slack_manifest_generate",
18806
+ {
18807
+ description: "Generate a ready-to-install Slack app manifest from desired gateway capabilities (admin-only). The agent-driven equivalent of the Slack setup wizard, backed by the same core generator. Returns the manifest JSON, the derived bot scopes/events, ordered setup steps, and the channel config to pass to agor_gateway_channels_create. This is pure: it creates no Slack app, no Agor channel, and validates no tokens.",
18808
+ annotations: { readOnlyHint: true },
18809
+ inputSchema: slackManifestGenerateSchema
18810
+ },
18811
+ async (args) => {
18812
+ requireAdmin(ctx, "generate Slack app manifests");
18813
+ const options = toSlackWizardOptions(args);
18814
+ return textResult({
18815
+ manifest: buildSlackManifest(options),
18816
+ bot_scopes: requiredBotScopes(options),
18817
+ bot_events: requiredBotEvents(options),
18818
+ setup_steps: [
18819
+ 'Open https://api.slack.com/apps?new_app=1 and choose "Create New App".',
18820
+ 'Select "From a manifest", pick the target workspace, paste the manifest JSON below, and click "Create".',
18821
+ 'Install the app to the workspace, then open OAuth & Permissions and copy the Bot User OAuth Token (starts with "xoxb-").',
18822
+ 'Open Basic Information \u2192 App-Level Tokens \u2192 Generate Token and Scopes, add the connections:write scope, generate it, and copy the App-Level Token (starts with "xapp-").',
18823
+ 'Once the app is installed and you hold the xoxb-/xapp- tokens, call agor_gateway_channels_create with channelType "slack", enabled:false, no tokens, and create_channel_config_hint below to create the channel as a draft.',
18824
+ "Then call agor_widgets_request_gateway_token for that channel so the user enters the xoxb-/xapp- tokens in the secure form that appears at the end of this message, which enables the channel. Do NOT ask the user to paste xoxb-/xapp- tokens into the chat, and do NOT pass tokens as agor_gateway_channels_create arguments.",
18825
+ identityModeSetupStep(args.alignUsers)
18826
+ ],
18827
+ create_channel_config_hint: toCreateChannelConfigHint(args),
18828
+ caveats: [
18829
+ "GENERATED ONLY \u2014 no Slack app created, no Agor channel created, no tokens validated, no event delivery verified.",
18830
+ "The app-level connections:write token is generated manually and is NOT part of the manifest bot scopes.",
18831
+ "restrictToChannelIds maps to config.allowed_channel_ids when you call create \u2014 it does NOT change the manifest scopes or events."
18832
+ ]
18833
+ });
18834
+ }
18835
+ );
18722
18836
  server.registerTool(
18723
18837
  "agor_gateway_channels_update",
18724
18838
  {
@@ -18742,7 +18856,7 @@ function registerGatewayChannelTools(server, ctx) {
18742
18856
  server.registerTool(
18743
18857
  "agor_gateway_outbound_targets_list",
18744
18858
  {
18745
- description: "List Slack gateway outbound targets the caller can use. Returns only outbound-enabled channels where the caller has branch all permission or admin access. Secrets and inbound channel keys are never returned.",
18859
+ description: "List Slack gateway outbound targets the caller can use. Returns only outbound-enabled channels where the caller has branch all permission or admin access; when called from a session, results are additionally scoped to channels targeting the session's branch. Secrets and inbound channel keys are never returned.",
18746
18860
  annotations: { readOnlyHint: true },
18747
18861
  inputSchema: external_exports.strictObject({
18748
18862
  branchId: mcpOptionalId("branchId", "Branch", "Filter by target branch ID."),
@@ -18757,15 +18871,24 @@ function registerGatewayChannelTools(server, ctx) {
18757
18871
  async (args) => {
18758
18872
  const channelRepo = new GatewayChannelRepository(ctx.db);
18759
18873
  const branchRepo = new BranchRepository3(ctx.db);
18874
+ const callerSessionBranchId = await resolveCallerSessionBranchId(ctx);
18760
18875
  const branchFilter = args.branchId ? await branchRepo.findById(args.branchId) : null;
18761
- const branchFilterId = branchFilter?.branch_id;
18876
+ const requestedBranchId = branchFilter?.branch_id;
18877
+ if (callerSessionBranchId && args.branchId && requestedBranchId !== callerSessionBranchId) {
18878
+ return textResult({
18879
+ channels: [],
18880
+ binding: "Results are scoped to the calling session's branch; the requested branchId targets a different branch, so this session cannot use its channels."
18881
+ });
18882
+ }
18883
+ const branchFilterId = callerSessionBranchId ?? requestedBranchId;
18762
18884
  const allChannels = args.gatewayChannelId ? [await channelRepo.findById(args.gatewayChannelId)] : await channelRepo.findAll();
18763
18885
  const channels = [];
18764
18886
  for (const channel of allChannels) {
18765
18887
  if (!channel) continue;
18766
18888
  if (args.channelType && channel.channel_type !== args.channelType) continue;
18767
18889
  if (channel.channel_type !== "slack") continue;
18768
- if (args.branchId && channel.target_branch_id !== branchFilterId) continue;
18890
+ if ((callerSessionBranchId || args.branchId) && channel.target_branch_id !== branchFilterId)
18891
+ continue;
18769
18892
  if (!channel.enabled) continue;
18770
18893
  const outbound = getOutboundConfig(channel);
18771
18894
  if (!outbound.outbound_enabled) continue;
@@ -18788,13 +18911,18 @@ function registerGatewayChannelTools(server, ctx) {
18788
18911
  ]
18789
18912
  });
18790
18913
  }
18791
- return textResult({ channels });
18914
+ return textResult({
18915
+ channels,
18916
+ ...callerSessionBranchId && channels.length === 0 ? {
18917
+ hint: "No outbound-enabled channel targets this session's branch \u2014 ask an operator to create/enable one."
18918
+ } : {}
18919
+ });
18792
18920
  }
18793
18921
  );
18794
18922
  server.registerTool(
18795
18923
  "agor_gateway_slack_thread_history_get",
18796
18924
  {
18797
- description: "Fetch Slack thread history for a gateway-mapped Slack thread without exposing Slack tokens. Prefer sessionId to resolve the gateway thread mapping from an accessible Agor session. Alternatively pass gatewayChannelId + threadId: mapped threads require admin or branch all permission on the mapped branch; unmapped arbitrary thread reads are admin-only. Slack message text is untrusted external content.",
18925
+ description: "Fetch Slack thread history for a gateway-mapped Slack thread without exposing Slack tokens. Prefer sessionId to resolve the gateway thread mapping from an accessible Agor session. Alternatively pass gatewayChannelId + threadId: mapped threads require admin or branch all permission on the mapped branch; unmapped arbitrary thread reads are admin-only. When called from a session, reads are restricted to threads whose target branch matches the calling session's branch. Slack message text is untrusted external content.",
18798
18926
  annotations: { readOnlyHint: true },
18799
18927
  inputSchema: slackThreadHistorySchema
18800
18928
  },
@@ -18862,7 +18990,7 @@ function registerGatewayChannelTools(server, ctx) {
18862
18990
  server.registerTool(
18863
18991
  "agor_gateway_emit_message",
18864
18992
  {
18865
- description: "Send a proactive Slack message through an outbound-enabled gateway channel and persist a seed/audit record. Targets may be Slack channel IDs, channel names, or user emails; v0 intentionally starts a fresh Slack thread/DM message for each emit and does not create a thread-session mapping until a human replies.",
18993
+ description: "Send a proactive Slack message through an outbound-enabled gateway channel and persist a seed/audit record. Targets may be Slack channel IDs, channel names, or user emails; v0 intentionally starts a fresh Slack thread/DM message for each emit and does not create a thread-session mapping until a human replies. When called from a session, outbound is restricted to channels whose target branch matches the calling session's branch.",
18866
18994
  annotations: { destructiveHint: false, idempotentHint: false },
18867
18995
  inputSchema: external_exports.strictObject({
18868
18996
  gatewayChannelId: mcpRequiredId(
@@ -23863,7 +23991,7 @@ function registerUserTools(server, ctx) {
23863
23991
  }
23864
23992
 
23865
23993
  // src/mcp/tools/widgets.ts
23866
- import { MessageRole as MessageRole2 } from "@agor/core/types";
23994
+ import { getRequiredSecretFields as getRequiredSecretFields2, hasMinimumRole as hasMinimumRole5, MessageRole as MessageRole2, ROLES as ROLES6 } from "@agor/core/types";
23867
23995
 
23868
23996
  // src/utils/append-system-message.ts
23869
23997
  import { generateId as generateId2, SessionRepository as SessionRepository3 } from "@agor/core/db";
@@ -24016,7 +24144,44 @@ var envVarsSubmitSchema = external_exports.object({
24016
24144
  }
24017
24145
  });
24018
24146
 
24147
+ // src/widgets/gateway-token/index.ts
24148
+ import { Forbidden as Forbidden2 } from "@agor/core/feathers";
24149
+ import {
24150
+ GATEWAY_SENSITIVE_CONFIG_FIELDS as GATEWAY_SENSITIVE_CONFIG_FIELDS2,
24151
+ hasMinimumRole as hasMinimumRole4,
24152
+ ROLES as ROLES5
24153
+ } from "@agor/core/types";
24154
+ var SUPPORTED_CHANNEL_TYPES = [
24155
+ "slack",
24156
+ "github",
24157
+ "teams"
24158
+ ];
24159
+ function isSupportedGatewayTokenChannelType(channelType) {
24160
+ return SUPPORTED_CHANNEL_TYPES.includes(channelType);
24161
+ }
24162
+ var MAX_TOKEN_LENGTH = 8192;
24163
+ var gatewayTokenParamsSchema = external_exports.object({
24164
+ gatewayChannelId: external_exports.string().min(1).describe("Gateway channel whose credentials are being set."),
24165
+ channelType: external_exports.enum(["slack", "discord", "whatsapp", "telegram", "github", "teams"]).describe("Platform type of the channel; drives per-field placeholders."),
24166
+ channelName: external_exports.string().min(1).max(200).describe("Human-readable channel name for the form heading and prompts."),
24167
+ fields: external_exports.array(external_exports.enum(GATEWAY_SENSITIVE_CONFIG_FIELDS2)).min(1).max(GATEWAY_SENSITIVE_CONFIG_FIELDS2.length).refine((fields) => new Set(fields).size === fields.length, {
24168
+ message: "Token field names must be unique"
24169
+ }).describe("Secret config field names to collect (subset of the sensitive fields)."),
24170
+ reason: external_exports.string().min(1).max(200).describe("One sentence explaining why the tokens are needed. Renders as a muted line.")
24171
+ }).strict();
24172
+ var gatewayTokenSubmitSchema = external_exports.object({
24173
+ tokens: external_exports.partialRecord(
24174
+ external_exports.enum(GATEWAY_SENSITIVE_CONFIG_FIELDS2),
24175
+ external_exports.string().min(1).max(MAX_TOKEN_LENGTH)
24176
+ ).describe("Map of sensitive field name \u2192 credential value.")
24177
+ }).strict();
24178
+
24019
24179
  // src/mcp/tools/widgets.ts
24180
+ function requireAdmin2(ctx, action) {
24181
+ if (!hasMinimumRole5(ctx.authenticatedUser?.role, ROLES6.ADMIN)) {
24182
+ throw new Error(`Access denied: admin role required to ${action}`);
24183
+ }
24184
+ }
24020
24185
  function widgetContentPreview(params) {
24021
24186
  const list = params.names.join(", ");
24022
24187
  return params.names.length === 1 ? `Please provide ${list}: ${params.reason}` : `Please provide ${list}: ${params.reason}`;
@@ -24135,6 +24300,104 @@ function registerWidgetTools(server, ctx) {
24135
24300
  return textResult({ widget_id: widgetId, status: "requested" });
24136
24301
  }
24137
24302
  );
24303
+ server.registerTool(
24304
+ "agor_widgets_request_gateway_token",
24305
+ {
24306
+ description: "Ask an admin to securely provide a gateway channel's platform tokens (Slack bot/app tokens, GitHub private key, Teams app password) via a compact form that appears at the end of your message, so setup finishes without anyone pasting xoxb-/xapp- tokens into chat. FIRE-AND-FORGET: the widget renders inline at the end of your turn; end your turn after calling. You will receive a user-role message when it is resolved. Token values never enter your context \u2014 only the channel identity and field NAMES do. Admin-only: a non-admin agent cannot mint this widget. Keep `reason` to ONE short sentence (\u2264200 chars).",
24307
+ annotations: { destructiveHint: false, openWorldHint: false },
24308
+ inputSchema: external_exports.object({
24309
+ gatewayChannelId: external_exports.string().min(1).describe("Gateway channel ID (UUIDv7 or short ID) whose tokens are being set."),
24310
+ reason: external_exports.string().max(200).optional().describe("One short sentence explaining why the tokens are needed.")
24311
+ })
24312
+ },
24313
+ async (args) => {
24314
+ if (!ctx.sessionId) return sessionContextRequiredResult();
24315
+ const currentSessionId = ctx.sessionId;
24316
+ requireAdmin2(ctx, "set gateway channel tokens");
24317
+ const channel = await ctx.app.service("gateway-channels").get(args.gatewayChannelId, ctx.baseServiceParams);
24318
+ const channelType = channel.channel_type;
24319
+ if (!isSupportedGatewayTokenChannelType(channelType)) {
24320
+ throw new Error(
24321
+ `Gateway channel type "${channelType}" does not support token entry via this widget.`
24322
+ );
24323
+ }
24324
+ const fields = getRequiredSecretFields2(channelType, channel.config);
24325
+ if (fields.length === 0) {
24326
+ throw new Error(
24327
+ `Gateway channel "${channel.name}" has no required secret fields to collect.`
24328
+ );
24329
+ }
24330
+ const params = gatewayTokenParamsSchema.parse({
24331
+ gatewayChannelId: channel.id,
24332
+ channelType,
24333
+ channelName: channel.name,
24334
+ fields,
24335
+ reason: args.reason ?? `Provide the ${channelType} credentials to finish connecting "${channel.name}".`
24336
+ });
24337
+ const requestedAt = (/* @__PURE__ */ new Date()).toISOString();
24338
+ const baseWidgetMeta = {
24339
+ widget_type: "gateway_token",
24340
+ schema_version: 1,
24341
+ params,
24342
+ status: "pending",
24343
+ requested_at: requestedAt,
24344
+ auto_resume: true
24345
+ };
24346
+ const hostTask = await findHostTaskForSession(
24347
+ ctx.app,
24348
+ currentSessionId,
24349
+ ctx.baseServiceParams
24350
+ );
24351
+ const hostTaskId = hostTask?.task_id;
24352
+ const created = await appendSystemMessage({
24353
+ app: ctx.app,
24354
+ db: ctx.db,
24355
+ sessionId: currentSessionId,
24356
+ taskId: hostTaskId,
24357
+ content: `Please provide the ${channelType} tokens for "${channel.name}": ${params.reason}`,
24358
+ contentPreview: `Widget: gateway_token (${channel.name})`,
24359
+ type: "widget_request",
24360
+ role: MessageRole2.SYSTEM,
24361
+ metadata: {
24362
+ widget: {
24363
+ ...baseWidgetMeta,
24364
+ widget_id: "pending"
24365
+ }
24366
+ }
24367
+ });
24368
+ const widgetId = created.message_id;
24369
+ if (hostTask?.message_range) {
24370
+ try {
24371
+ await ctx.app.service("tasks").patch(
24372
+ hostTask.task_id,
24373
+ {
24374
+ message_range: {
24375
+ start_index: hostTask.message_range.start_index,
24376
+ end_index: created.index
24377
+ }
24378
+ },
24379
+ ctx.baseServiceParams
24380
+ );
24381
+ } catch (err) {
24382
+ console.warn(
24383
+ `[widgets] failed to extend task.message_range for widget ${widgetId}:`,
24384
+ err
24385
+ );
24386
+ }
24387
+ }
24388
+ await ctx.app.service("messages").patch(
24389
+ widgetId,
24390
+ {
24391
+ metadata: {
24392
+ ...created.metadata ?? {},
24393
+ widget: { ...baseWidgetMeta, widget_id: widgetId }
24394
+ }
24395
+ },
24396
+ ctx.baseServiceParams
24397
+ );
24398
+ return textResult({ widget_id: widgetId, status: "requested" });
24399
+ }
24400
+ );
24138
24401
  }
24139
24402
 
24140
24403
  // src/mcp/server.ts
@@ -14772,11 +14772,15 @@ import {
14772
14772
  ThreadSessionMapRepository
14773
14773
  } from "@agor/core/db";
14774
14774
  import {
14775
- getConnector
14775
+ buildSlackManifest,
14776
+ getConnector,
14777
+ requiredBotEvents,
14778
+ requiredBotScopes
14776
14779
  } from "@agor/core/gateway";
14777
14780
  import {
14778
14781
  GATEWAY_REDACTED_SENTINEL,
14779
14782
  GATEWAY_SENSITIVE_CONFIG_FIELDS,
14783
+ getRequiredSecretFields,
14780
14784
  hasMinimumRole as hasMinimumRole2,
14781
14785
  ROLES as ROLES2
14782
14786
  } from "@agor/core/types";
@@ -14836,44 +14840,48 @@ var gatewayChannelCreateSchema = external_exports.strictObject({
14836
14840
  agenticConfig: agenticConfigSchema.optional()
14837
14841
  }).superRefine((value, issue2) => {
14838
14842
  const config2 = value.config ?? {};
14839
- if (value.channelType === "slack") {
14840
- if (!config2.bot_token) {
14841
- issue2.addIssue({
14842
- code: "custom",
14843
- path: ["config", "bot_token"],
14844
- message: "config.bot_token is required for Slack. Prefer a bot token stored outside the transcript when possible."
14845
- });
14846
- }
14847
- if (config2.connection_mode === "socket" && !config2.app_token) {
14848
- issue2.addIssue({
14849
- code: "custom",
14850
- path: ["config", "app_token"],
14851
- message: "config.app_token is required for Slack Socket Mode."
14852
- });
14853
- }
14854
- }
14855
- if (value.channelType === "github") {
14856
- for (const field of ["app_id", "private_key", "installation_id", "watch_repos"]) {
14843
+ if (value.enabled !== false) {
14844
+ const requiredSecretMessages = {
14845
+ bot_token: "config.bot_token is required for Slack. Prefer a bot token stored outside the transcript when possible.",
14846
+ app_token: "config.app_token is required for Slack Socket Mode.",
14847
+ private_key: "config.private_key is required for GitHub gateway channels.",
14848
+ app_password: "config.app_password is required for Teams gateway channels."
14849
+ };
14850
+ for (const field of getRequiredSecretFields(value.channelType, config2)) {
14857
14851
  if (!config2[field]) {
14858
14852
  issue2.addIssue({
14859
14853
  code: "custom",
14860
14854
  path: ["config", field],
14861
- message: `config.${field} is required for GitHub gateway channels.`
14855
+ message: requiredSecretMessages[field] ?? `config.${field} is required for ${value.channelType} gateway channels.`
14862
14856
  });
14863
14857
  }
14864
14858
  }
14865
14859
  }
14866
- if (value.channelType === "teams") {
14867
- for (const field of ["app_id", "app_password"]) {
14860
+ if (value.channelType === "github") {
14861
+ for (const field of ["app_id", "installation_id", "watch_repos"]) {
14868
14862
  if (!config2[field]) {
14869
14863
  issue2.addIssue({
14870
14864
  code: "custom",
14871
14865
  path: ["config", field],
14872
- message: `config.${field} is required for Teams gateway channels.`
14866
+ message: `config.${field} is required for GitHub gateway channels.`
14873
14867
  });
14874
14868
  }
14875
14869
  }
14876
14870
  }
14871
+ if (value.channelType === "teams" && !config2.app_id) {
14872
+ issue2.addIssue({
14873
+ code: "custom",
14874
+ path: ["config", "app_id"],
14875
+ message: "config.app_id is required for Teams gateway channels."
14876
+ });
14877
+ }
14878
+ if (value.channelType === "slack" && config2.align_slack_users !== true && !value.agorUserId) {
14879
+ issue2.addIssue({
14880
+ code: "custom",
14881
+ path: ["agorUserId"],
14882
+ message: "Run-as-selected-user needs agorUserId \u2014 set config.align_slack_users:true to align by email, or pass agorUserId."
14883
+ });
14884
+ }
14877
14885
  });
14878
14886
  var slackThreadHistorySchema = external_exports.strictObject({
14879
14887
  sessionId: mcpOptionalId(
@@ -14937,6 +14945,23 @@ var gatewayChannelUpdateSchema = external_exports.strictObject({
14937
14945
  ),
14938
14946
  agenticConfig: agenticConfigSchema.nullable().optional().describe("Replace agent/session defaults. null clears the gateway agentic config.")
14939
14947
  });
14948
+ var slackManifestGenerateSchema = external_exports.strictObject({
14949
+ appName: mcpRequiredString("appName", 'Slack app display name, e.g. "Agor".'),
14950
+ botDisplayName: mcpOptionalNonEmptyString(
14951
+ "botDisplayName",
14952
+ "Bot user display name. Defaults to appName."
14953
+ ),
14954
+ publicChannels: external_exports.boolean().default(false).describe("Listen in public channels (#channel) via @mention."),
14955
+ privateChannels: external_exports.boolean().default(false).describe("Listen in private channels (groups) via @mention."),
14956
+ groupDms: external_exports.boolean().default(false).describe("Listen in group DMs (multi-person IMs) via @mention."),
14957
+ alignUsers: external_exports.boolean().default(true).describe(
14958
+ "Resolve Slack user email \u2192 Agor user (adds the users:read.email scope). Defaults to true: each Slack user runs as their matched Agor account and unmatched users are rejected, so no fixed run-as user is needed. Set false to run every message as one fixed Agor user (then pass agorUserId to agor_gateway_channels_create)."
14959
+ ),
14960
+ outbound: external_exports.boolean().default(false).describe("Proactive outbound: post to channels by name and DM users by email."),
14961
+ restrictToChannelIds: external_exports.array(external_exports.string().min(1)).optional().describe(
14962
+ "Slack channel ID whitelist. Maps to config.allowed_channel_ids when you call agor_gateway_channels_create; it does NOT change the manifest scopes or events."
14963
+ )
14964
+ });
14940
14965
 
14941
14966
  // src/mcp/tools/knowledge.ts
14942
14967
  import { createHash, randomUUID } from "crypto";
@@ -15475,7 +15500,7 @@ var modelConfigInputSchema = external_exports.union([
15475
15500
  import { ROLES as ROLES4 } from "@agor/core/types";
15476
15501
 
15477
15502
  // src/mcp/tools/widgets.ts
15478
- import { MessageRole as MessageRole2 } from "@agor/core/types";
15503
+ import { getRequiredSecretFields as getRequiredSecretFields2, hasMinimumRole as hasMinimumRole5, MessageRole as MessageRole2, ROLES as ROLES6 } from "@agor/core/types";
15479
15504
 
15480
15505
  // src/utils/append-system-message.ts
15481
15506
  import { generateId as generateId2, SessionRepository as SessionRepository3 } from "@agor/core/db";
@@ -15558,6 +15583,30 @@ var envVarsSubmitSchema = external_exports.object({
15558
15583
  }
15559
15584
  });
15560
15585
 
15586
+ // src/widgets/gateway-token/index.ts
15587
+ import { Forbidden as Forbidden2 } from "@agor/core/feathers";
15588
+ import {
15589
+ GATEWAY_SENSITIVE_CONFIG_FIELDS as GATEWAY_SENSITIVE_CONFIG_FIELDS2,
15590
+ hasMinimumRole as hasMinimumRole4,
15591
+ ROLES as ROLES5
15592
+ } from "@agor/core/types";
15593
+ var MAX_TOKEN_LENGTH = 8192;
15594
+ var gatewayTokenParamsSchema = external_exports.object({
15595
+ gatewayChannelId: external_exports.string().min(1).describe("Gateway channel whose credentials are being set."),
15596
+ channelType: external_exports.enum(["slack", "discord", "whatsapp", "telegram", "github", "teams"]).describe("Platform type of the channel; drives per-field placeholders."),
15597
+ channelName: external_exports.string().min(1).max(200).describe("Human-readable channel name for the form heading and prompts."),
15598
+ fields: external_exports.array(external_exports.enum(GATEWAY_SENSITIVE_CONFIG_FIELDS2)).min(1).max(GATEWAY_SENSITIVE_CONFIG_FIELDS2.length).refine((fields) => new Set(fields).size === fields.length, {
15599
+ message: "Token field names must be unique"
15600
+ }).describe("Secret config field names to collect (subset of the sensitive fields)."),
15601
+ reason: external_exports.string().min(1).max(200).describe("One sentence explaining why the tokens are needed. Renders as a muted line.")
15602
+ }).strict();
15603
+ var gatewayTokenSubmitSchema = external_exports.object({
15604
+ tokens: external_exports.partialRecord(
15605
+ external_exports.enum(GATEWAY_SENSITIVE_CONFIG_FIELDS2),
15606
+ external_exports.string().min(1).max(MAX_TOKEN_LENGTH)
15607
+ ).describe("Map of sensitive field name \u2192 credential value.")
15608
+ }).strict();
15609
+
15561
15610
  // src/mcp/server.ts
15562
15611
  var DEBUG_MCP_REQUESTS = process.env.AGOR_DEBUG_MCP_REQUESTS === "1" || process.env.DEBUG?.includes("mcp-requests");
15563
15612
  function textResult(data) {