@cursor/july 0.1.96 → 0.1.97

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 (321) hide show
  1. package/README.md +3 -2
  2. package/dist/bin/agent-serve.js +14 -3
  3. package/dist/channels/origin/api.d.ts +15 -4
  4. package/dist/channels/origin/api.d.ts.map +1 -1
  5. package/dist/channels/origin/api.js +19 -3
  6. package/dist/channels/origin/binding.d.ts +11 -0
  7. package/dist/channels/origin/binding.d.ts.map +1 -1
  8. package/dist/channels/origin/binding.js +41 -25
  9. package/dist/channels/origin/index.d.ts +1 -0
  10. package/dist/channels/origin/index.d.ts.map +1 -1
  11. package/dist/channels/origin/index.js +1 -0
  12. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  13. package/dist/channels/origin/origin-channel.js +3 -0
  14. package/dist/channels/origin/reactions.d.ts +56 -0
  15. package/dist/channels/origin/reactions.d.ts.map +1 -0
  16. package/dist/channels/origin/reactions.js +67 -0
  17. package/dist/channels/origin/types.d.ts +11 -0
  18. package/dist/channels/origin/types.d.ts.map +1 -1
  19. package/dist/channels/slack/approvals.d.ts +16 -0
  20. package/dist/channels/slack/approvals.d.ts.map +1 -1
  21. package/dist/channels/slack/approvals.js +86 -0
  22. package/dist/channels/slack/cli-project.d.ts +19 -0
  23. package/dist/channels/slack/cli-project.d.ts.map +1 -0
  24. package/dist/channels/slack/cli-project.js +234 -0
  25. package/dist/channels/slack/defaults.d.ts.map +1 -1
  26. package/dist/channels/slack/defaults.js +97 -39
  27. package/dist/channels/slack/init.d.ts +3 -2
  28. package/dist/channels/slack/init.d.ts.map +1 -1
  29. package/dist/channels/slack/init.js +5 -5
  30. package/dist/channels/slack/interactive.d.ts +2 -1
  31. package/dist/channels/slack/interactive.d.ts.map +1 -1
  32. package/dist/channels/slack/interactive.js +15 -4
  33. package/dist/channels/slack/manifest.d.ts +1 -1
  34. package/dist/channels/slack/manifest.js +1 -1
  35. package/dist/channels/slack/setup.d.ts +1 -1
  36. package/dist/channels/slack/setup.d.ts.map +1 -1
  37. package/dist/channels/slack/setup.js +10 -6
  38. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  39. package/dist/channels/slack/slack-channel.js +1 -0
  40. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
  41. package/dist/channels/slack/tool-approval-events.js +91 -1
  42. package/dist/docs/404.html +2 -2
  43. package/dist/docs/ab.html +4 -4
  44. package/dist/docs/assets/{app.jXleCmOc.js → app.B3rWNYE1.js} +1 -1
  45. package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
  46. package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
  47. package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.B40_SXuv.js} +2 -2
  48. package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
  49. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
  50. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
  51. package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
  52. package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
  53. package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
  54. package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
  55. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.RyZf5OTE.js} +9 -6
  56. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
  58. package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
  59. package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
  60. package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
  61. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
  62. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
  63. package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
  64. package/dist/docs/building-with-agents.html +4 -4
  65. package/dist/docs/concepts.html +4 -4
  66. package/dist/docs/deployment.html +7 -7
  67. package/dist/docs/deployment.md +5 -4
  68. package/dist/docs/evals.html +4 -4
  69. package/dist/docs/guides/agent-to-agent.html +4 -4
  70. package/dist/docs/guides/cloud-runtime.html +4 -4
  71. package/dist/docs/guides/convert-automation.html +4 -4
  72. package/dist/docs/guides/github.html +4 -4
  73. package/dist/docs/guides/human-in-the-loop.html +4 -4
  74. package/dist/docs/guides/mcp-oauth.html +8 -8
  75. package/dist/docs/guides/mcp-oauth.md +26 -8
  76. package/dist/docs/guides/opentelemetry.html +4 -4
  77. package/dist/docs/guides/slack.html +17 -33
  78. package/dist/docs/guides/slack.md +92 -201
  79. package/dist/docs/guides/webhooks.html +4 -4
  80. package/dist/docs/hashmap.json +1 -1
  81. package/dist/docs/hillclimbing.html +4 -4
  82. package/dist/docs/index.html +6 -6
  83. package/dist/docs/index.md +5 -3
  84. package/dist/docs/llms-full.txt +299 -653
  85. package/dist/docs/llms.txt +2 -2
  86. package/dist/docs/quickstart.html +4 -4
  87. package/dist/docs/reference/agent-config.html +6 -6
  88. package/dist/docs/reference/agent-config.md +2 -2
  89. package/dist/docs/reference/artifacts.html +4 -4
  90. package/dist/docs/reference/channels.html +4 -4
  91. package/dist/docs/reference/cli.html +13 -10
  92. package/dist/docs/reference/cli.md +38 -16
  93. package/dist/docs/reference/connections.html +9 -8
  94. package/dist/docs/reference/connections.md +6 -3
  95. package/dist/docs/reference/hooks.html +4 -4
  96. package/dist/docs/reference/http-api.html +6 -6
  97. package/dist/docs/reference/http-api.md +2 -1
  98. package/dist/docs/reference/instructions.html +4 -4
  99. package/dist/docs/reference/playground.html +4 -4
  100. package/dist/docs/reference/project-layout.html +4 -4
  101. package/dist/docs/reference/prompt.html +4 -4
  102. package/dist/docs/reference/schedules.html +4 -4
  103. package/dist/docs/reference/sessions.html +5 -5
  104. package/dist/docs/reference/sessions.md +4 -2
  105. package/dist/docs/reference/skills.html +4 -4
  106. package/dist/docs/reference/subagents.html +4 -4
  107. package/dist/docs/reference/tools.html +6 -6
  108. package/dist/docs/reference/tools.md +9 -2
  109. package/dist/docs/scaffolding-agents.html +4 -4
  110. package/dist/docs/storage.html +4 -4
  111. package/dist/docs/templates/agentic-owners.html +4 -4
  112. package/dist/docs/templates/agents-md.html +28 -0
  113. package/dist/docs/templates/agents-md.md +105 -0
  114. package/dist/docs/templates/code-wiki.html +5 -5
  115. package/dist/docs/templates/demo.html +4 -4
  116. package/dist/docs/templates/pr-autofixer.html +4 -4
  117. package/dist/docs/templates/security-help.html +4 -4
  118. package/dist/docs/templates/security-reviewer.html +5 -5
  119. package/dist/docs/templates/triage.html +4 -4
  120. package/dist/docs/troubleshooting.html +5 -5
  121. package/dist/docs/troubleshooting.md +2 -2
  122. package/dist/evals/run-facts.d.ts.map +1 -1
  123. package/dist/evals/run-facts.js +27 -0
  124. package/dist/internal/advertise-tools.d.ts.map +1 -1
  125. package/dist/internal/advertise-tools.js +15 -9
  126. package/dist/internal/approval-gate.d.ts +12 -13
  127. package/dist/internal/approval-gate.d.ts.map +1 -1
  128. package/dist/internal/approval-gate.js +16 -21
  129. package/dist/internal/chat-client.js +10 -0
  130. package/dist/internal/cli-deploy.d.ts +5 -0
  131. package/dist/internal/cli-deploy.d.ts.map +1 -1
  132. package/dist/internal/cli-deploy.js +50 -17
  133. package/dist/internal/cli-mcp-oauth.js +8 -18
  134. package/dist/internal/cli-slack-manual.d.ts +24 -2
  135. package/dist/internal/cli-slack-manual.d.ts.map +1 -1
  136. package/dist/internal/cli-slack-manual.js +251 -20
  137. package/dist/internal/cli-slack.d.ts +9 -2
  138. package/dist/internal/cli-slack.d.ts.map +1 -1
  139. package/dist/internal/cli-slack.js +29 -82
  140. package/dist/internal/cursor/account-mcp.d.ts +1 -0
  141. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  142. package/dist/internal/cursor/account-mcp.js +17 -0
  143. package/dist/internal/cursor-agent-template.d.ts +1 -1
  144. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  145. package/dist/internal/cursor-agent-template.js +1 -0
  146. package/dist/internal/deploy-client.d.ts +17 -0
  147. package/dist/internal/deploy-client.d.ts.map +1 -1
  148. package/dist/internal/deploy-client.js +31 -10
  149. package/dist/internal/env-file.d.ts +19 -0
  150. package/dist/internal/env-file.d.ts.map +1 -0
  151. package/dist/internal/env-file.js +90 -0
  152. package/dist/internal/framework-file-storage.d.ts +1 -1
  153. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  154. package/dist/internal/framework-file-storage.js +6 -0
  155. package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
  156. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  157. package/dist/internal/hosted-delivery-protocol.js +7 -0
  158. package/dist/internal/hosted-delivery.d.ts +6 -0
  159. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  160. package/dist/internal/hosted-delivery.js +63 -22
  161. package/dist/internal/hosted-execution-diag.d.ts +48 -0
  162. package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
  163. package/dist/internal/hosted-execution-diag.js +150 -0
  164. package/dist/internal/http-channel.d.ts.map +1 -1
  165. package/dist/internal/http-channel.js +81 -1
  166. package/dist/internal/init-project.d.ts.map +1 -1
  167. package/dist/internal/init-project.js +2 -0
  168. package/dist/internal/logs-client.d.ts +5 -0
  169. package/dist/internal/logs-client.d.ts.map +1 -1
  170. package/dist/internal/logs-client.js +5 -0
  171. package/dist/internal/mcp-endpoint.js +2 -3
  172. package/dist/internal/mcp-host.d.ts +10 -0
  173. package/dist/internal/mcp-host.d.ts.map +1 -1
  174. package/dist/internal/mcp-host.js +57 -8
  175. package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
  176. package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
  177. package/dist/internal/mcp-oauth-on-demand.js +287 -0
  178. package/dist/internal/mcp-oauth-persist.d.ts +42 -0
  179. package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
  180. package/dist/internal/mcp-oauth-persist.js +92 -0
  181. package/dist/internal/mcp-oauth.d.ts +1 -0
  182. package/dist/internal/mcp-oauth.d.ts.map +1 -1
  183. package/dist/internal/mcp-oauth.js +10 -2
  184. package/dist/internal/otel/collector.d.ts.map +1 -1
  185. package/dist/internal/otel/collector.js +22 -9
  186. package/dist/internal/server.d.ts +3 -0
  187. package/dist/internal/server.d.ts.map +1 -1
  188. package/dist/internal/server.js +49 -22
  189. package/dist/internal/session-engine.d.ts +88 -3
  190. package/dist/internal/session-engine.d.ts.map +1 -1
  191. package/dist/internal/session-engine.js +515 -43
  192. package/dist/internal/sessions-client.d.ts +9 -7
  193. package/dist/internal/sessions-client.d.ts.map +1 -1
  194. package/dist/internal/sessions-client.js +3 -1
  195. package/dist/internal/storage-coordinator.d.ts +7 -0
  196. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  197. package/dist/internal/storage-coordinator.js +28 -5
  198. package/dist/internal/storage-roles.d.ts +5 -0
  199. package/dist/internal/storage-roles.d.ts.map +1 -1
  200. package/dist/internal/stream-progress.d.ts.map +1 -1
  201. package/dist/internal/stream-progress.js +10 -0
  202. package/dist/internal/tool-policy.d.ts +9 -1
  203. package/dist/internal/tool-policy.d.ts.map +1 -1
  204. package/dist/internal/tool-policy.js +13 -0
  205. package/dist/internal/trajectory.d.ts.map +1 -1
  206. package/dist/internal/trajectory.js +10 -0
  207. package/dist/internal/turn-outbox.d.ts +24 -0
  208. package/dist/internal/turn-outbox.d.ts.map +1 -0
  209. package/dist/internal/turn-outbox.js +80 -0
  210. package/dist/playground/assets/{index-Cx9CclK_.js → index-DrkI6y5O.js} +45 -45
  211. package/dist/playground/assets/index-DzNGwm7q.css +1 -0
  212. package/dist/playground/index.html +2 -2
  213. package/dist/storage-backends/cursor-hosted.d.ts +1 -1
  214. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  215. package/dist/storage-backends/cursor-hosted.js +12 -0
  216. package/dist/storage.d.ts +8 -0
  217. package/dist/storage.d.ts.map +1 -1
  218. package/dist/types.d.ts +63 -7
  219. package/dist/types.d.ts.map +1 -1
  220. package/docs/README.md +5 -3
  221. package/docs/deployment.md +5 -4
  222. package/docs/guides/mcp-oauth.md +26 -8
  223. package/docs/guides/slack.md +93 -202
  224. package/docs/reference/agent-config.md +2 -2
  225. package/docs/reference/cli.md +38 -16
  226. package/docs/reference/connections.md +6 -3
  227. package/docs/reference/http-api.md +2 -1
  228. package/docs/reference/sessions.md +4 -2
  229. package/docs/reference/tools.md +9 -2
  230. package/docs/templates/agents-md.md +110 -0
  231. package/docs/troubleshooting.md +2 -2
  232. package/package.json +1 -1
  233. package/skills/create-agent/SKILL.md +2 -1
  234. package/skills/mcp-auth/SKILL.md +6 -3
  235. package/skills/setup-slack/SKILL.md +23 -13
  236. package/src/bin/agent-serve.ts +13 -1
  237. package/src/channels/origin/api.ts +24 -5
  238. package/src/channels/origin/binding.ts +55 -26
  239. package/src/channels/origin/index.ts +1 -0
  240. package/src/channels/origin/origin-channel.ts +4 -0
  241. package/src/channels/origin/reactions.ts +82 -0
  242. package/src/channels/origin/types.ts +11 -0
  243. package/src/channels/slack/approvals.ts +105 -0
  244. package/src/channels/slack/cli-project.ts +267 -0
  245. package/src/channels/slack/defaults.ts +109 -46
  246. package/src/channels/slack/init.ts +10 -5
  247. package/src/channels/slack/interactive.ts +35 -9
  248. package/src/channels/slack/manifest.ts +1 -1
  249. package/src/channels/slack/setup.ts +10 -6
  250. package/src/channels/slack/slack-channel.ts +1 -0
  251. package/src/channels/slack/tool-approval-events.ts +93 -0
  252. package/src/evals/run-facts.ts +32 -0
  253. package/src/internal/advertise-tools.ts +31 -10
  254. package/src/internal/approval-gate.ts +20 -29
  255. package/src/internal/chat-client.ts +19 -0
  256. package/src/internal/cli-deploy.ts +79 -9
  257. package/src/internal/cli-mcp-oauth.ts +7 -21
  258. package/src/internal/cli-slack-manual.ts +350 -18
  259. package/src/internal/cli-slack.ts +40 -84
  260. package/src/internal/cursor/account-mcp.ts +21 -0
  261. package/src/internal/cursor-agent-template.ts +1 -0
  262. package/src/internal/deploy-client.ts +43 -0
  263. package/src/internal/env-file.ts +84 -0
  264. package/src/internal/framework-file-storage.ts +7 -1
  265. package/src/internal/hosted-delivery-protocol.ts +7 -0
  266. package/src/internal/hosted-delivery.ts +100 -27
  267. package/src/internal/hosted-execution-diag.ts +207 -0
  268. package/src/internal/http-channel.ts +99 -0
  269. package/src/internal/init-project.ts +2 -0
  270. package/src/internal/logs-client.ts +5 -0
  271. package/src/internal/mcp-endpoint.ts +13 -4
  272. package/src/internal/mcp-host.ts +77 -11
  273. package/src/internal/mcp-oauth-on-demand.ts +352 -0
  274. package/src/internal/mcp-oauth-persist.ts +127 -0
  275. package/src/internal/mcp-oauth.ts +17 -1
  276. package/src/internal/otel/collector.ts +30 -0
  277. package/src/internal/server.ts +59 -9
  278. package/src/internal/session-engine.ts +659 -56
  279. package/src/internal/sessions-client.ts +17 -8
  280. package/src/internal/storage-coordinator.ts +38 -8
  281. package/src/internal/storage-roles.ts +7 -0
  282. package/src/internal/stream-progress.ts +19 -0
  283. package/src/internal/tool-policy.ts +18 -0
  284. package/src/internal/trajectory.ts +10 -0
  285. package/src/internal/turn-outbox.ts +85 -0
  286. package/src/storage-backends/cursor-hosted.ts +13 -1
  287. package/src/storage.ts +12 -0
  288. package/src/types.ts +68 -8
  289. package/templates/agents-md/README.md +39 -0
  290. package/templates/agents-md/agent/agent.ts +8 -0
  291. package/templates/agents-md/agent/channels/github.ts +10 -0
  292. package/templates/agents-md/agent/channels/queue.ts +28 -0
  293. package/templates/agents-md/agent/channels/slack.ts +9 -0
  294. package/templates/agents-md/agent/instructions.md +39 -0
  295. package/templates/agents-md/agent/lib/collect.ts +439 -0
  296. package/templates/agents-md/agent/lib/config.ts +8 -0
  297. package/templates/agents-md/agent/lib/paths.ts +51 -0
  298. package/templates/agents-md/agent/schedules/weekly.ts +17 -0
  299. package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
  300. package/templates/agents-md/evals/agents.eval.ts +135 -0
  301. package/templates/agents-md/evals/evals.config.ts +5 -0
  302. package/templates/agents-md/init.json +38 -0
  303. package/templates/agents-md/package.json +18 -0
  304. package/templates/agents-md/tsconfig.json +12 -0
  305. package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
  306. package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
  307. package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
  308. package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
  309. package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
  310. package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
  311. package/dist/docs/design/agsh.md +0 -406
  312. package/dist/playground/assets/index-B1DDvBeC.css +0 -1
  313. package/docs/design/agsh.md +0 -406
  314. /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
  315. /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
  316. /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
  317. /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
  318. /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
  319. /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
  320. /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
  321. /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
@@ -222,7 +222,7 @@ export function buildSlackManifestPair(
222
222
  };
223
223
  }
224
224
 
225
- /** Relative names under `.agent-serve/slack/`. */
225
+ /** Manifest filenames written under `.slack/`. */
226
226
  export function slackManifestFileEntries(
227
227
  pair: { dev: SlackAppManifest; prod: SlackAppManifest },
228
228
  env: "dev" | "prod" | "both" = "both"
@@ -2,7 +2,7 @@
2
2
  * Slack setup guide printed by `agent-serve slack setup`.
3
3
  *
4
4
  * Dedicated Socket Mode app via `slack create` (dashboard wizard).
5
- * `slack init --manual` is the unmanaged paste-at-api.slack.com path.
5
+ * `slack init --manual` is the unmanaged Slack CLI / paste path.
6
6
  * {@link SLACK_SETUP_PHASES} is that checklist; its ids key
7
7
  * `.agent-serve/slack/setup-status.json`.
8
8
  */
@@ -21,6 +21,7 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
21
21
  title: "Generate channel + manifests",
22
22
  steps: [
23
23
  "agent-serve slack init --manual --dir . --name My Agent",
24
+ "Installs the Slack app when Slack CLI is logged in. Otherwise next asks the user to install it.",
24
25
  "Manifests default to Socket Mode (no public Request URL).",
25
26
  ],
26
27
  },
@@ -29,9 +30,11 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
29
30
  actor: "human",
30
31
  title: "Create two Slack apps from manifests",
31
32
  steps: [
32
- "Open https://api.slack.com/apps -> Create New App from a manifest",
33
- "Paste .agent-serve/slack/manifest.dev.json -> create the *dev* app",
34
- "Repeat with manifest.prod.json for the *prod* app",
33
+ "Preferred: Slack CLI at ~/.slack/bin/slack. slack login --no-prompt, then slack app install --environment local --team <T> --force",
34
+ "Prod: SLACK_ENV=deployed slack app install --environment deployed --team <T> --force",
35
+ "Do not slack deploy; Agent SDK serve owns Socket Mode",
36
+ "Fallback: https://api.slack.com/apps -> Create New App from a manifest",
37
+ "Paste .slack/manifest.dev.json, then manifest.prod.json",
35
38
  ],
36
39
  },
37
40
  {
@@ -39,8 +42,9 @@ export const SLACK_SETUP_PHASES: SlackSetupPhase[] = [
39
42
  actor: "human",
40
43
  title: "Install + mint App-Level Token",
41
44
  steps: [
42
- "Install to Workspace; copy Bot User OAuth Token (xoxb-...)",
45
+ "Slack CLI install leaves tokens in that process only. Copy xoxb from OAuth & Permissions at https://api.slack.com/apps/<appId>",
43
46
  "App-Level Tokens: create token with connections:write; copy xapp-...",
47
+ "If Slack CLI wrote SLACK_* to .env, copy them into .env.local using env.example names",
44
48
  ],
45
49
  },
46
50
  {
@@ -106,7 +110,7 @@ export function formatSlackSetupGuide(): string {
106
110
  " Finish Slack consent and the bot name there. The CLI writes",
107
111
  " tokens into .env.local.",
108
112
  "",
109
- "Manual Slack app: `slack init --manual`. Phases below.",
113
+ "Manual Slack app: `slack init --manual` (Slack CLI, or paste at api.slack.com).",
110
114
  "Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
111
115
  "App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
112
116
  "",
@@ -487,6 +487,7 @@ export function slackChannel(
487
487
  credentials,
488
488
  getSession: args.getSession,
489
489
  resolveApproval: args.resolveApproval,
490
+ resolveAuth: args.resolveAuth,
490
491
  waitUntil: args.waitUntil,
491
492
  log: getLog(),
492
493
  blockExternals,
@@ -21,8 +21,11 @@
21
21
  import type { ChannelEventHandlers } from "../../types.js";
22
22
  import { postMessage, setThreadStatus, updateMessage } from "./api.js";
23
23
  import {
24
+ authThreadStatus,
24
25
  buildApprovalBlocks,
26
+ buildAuthBlocks,
25
27
  buildResolvedApprovalBlocks,
28
+ buildResolvedAuthBlocks,
26
29
  } from "./approvals.js";
27
30
  import { SLACK_DEFAULT_LOADING_MESSAGES } from "./constants.js";
28
31
  import { defaultSlackLog, type SlackLog } from "./log.js";
@@ -132,5 +135,95 @@ export function buildToolApprovalEvents(
132
135
  decision: event.data.decision,
133
136
  });
134
137
  },
138
+
139
+ async "action.auth_requested"(event, channel, ctx) {
140
+ const log = getLog();
141
+ const state = channel.state;
142
+ if (state.channelId === null || state.threadTs === null) {
143
+ return;
144
+ }
145
+ const blocks = buildAuthBlocks({
146
+ sessionId: ctx.session.id,
147
+ callId: event.data.callId,
148
+ toolName: event.data.toolName,
149
+ connection: event.data.connection,
150
+ authUrl: event.data.authUrl,
151
+ });
152
+ try {
153
+ const posted = await postMessage({
154
+ botToken,
155
+ channel: state.channelId,
156
+ threadTs: state.threadTs,
157
+ text: `Authorization required for \`${event.data.connection}\``,
158
+ blocks,
159
+ });
160
+ channel.state.approvalMessageByCallId = {
161
+ ...(state.approvalMessageByCallId ?? {}),
162
+ [event.data.callId]: posted.ts,
163
+ };
164
+ await setThreadStatus({
165
+ botToken,
166
+ channelId: state.channelId,
167
+ threadTs: state.threadTs,
168
+ status: authThreadStatus(event.data.connection),
169
+ loadingMessages: [
170
+ authThreadStatus(event.data.connection),
171
+ ...SLACK_DEFAULT_LOADING_MESSAGES,
172
+ ],
173
+ });
174
+ log.info("auth card posted", {
175
+ call_id: event.data.callId,
176
+ connection: event.data.connection,
177
+ message_ts: posted.ts,
178
+ });
179
+ } catch (error) {
180
+ log.warn("auth card post failed", {
181
+ call_id: event.data.callId,
182
+ error: error instanceof Error ? error.message : String(error),
183
+ });
184
+ }
185
+ },
186
+
187
+ async "action.auth_resolved"(event, channel) {
188
+ const log = getLog();
189
+ const state = channel.state;
190
+ const messageTs = state.approvalMessageByCallId?.[event.data.callId];
191
+ if (
192
+ state.channelId !== null &&
193
+ messageTs !== undefined &&
194
+ messageTs !== ""
195
+ ) {
196
+ const blocks = buildResolvedAuthBlocks({
197
+ connection: event.data.connection,
198
+ decision: event.data.decision,
199
+ byUserId: event.data.by,
200
+ });
201
+ const verb =
202
+ event.data.decision === "approve" ? "Connected" : "Cancelled";
203
+ await updateMessage({
204
+ botToken,
205
+ channel: state.channelId,
206
+ ts: messageTs,
207
+ text: `${verb} — ${event.data.connection}`,
208
+ blocks,
209
+ });
210
+ const next = { ...(state.approvalMessageByCallId ?? {}) };
211
+ delete next[event.data.callId];
212
+ channel.state.approvalMessageByCallId = next;
213
+ }
214
+ if (state.channelId !== null && state.threadTs !== null) {
215
+ await setThreadStatus({
216
+ botToken,
217
+ channelId: state.channelId,
218
+ threadTs: state.threadTs,
219
+ status: "Working…",
220
+ loadingMessages: [...SLACK_DEFAULT_LOADING_MESSAGES],
221
+ });
222
+ }
223
+ log.info("auth resolved in slack", {
224
+ call_id: event.data.callId,
225
+ decision: event.data.decision,
226
+ });
227
+ },
135
228
  };
136
229
  }
@@ -182,6 +182,38 @@ export function deriveRunFacts(events: readonly SessionEvent[]): EvalRunFacts {
182
182
  }
183
183
  break;
184
184
  }
185
+ case "action.auth_requested": {
186
+ const request: EvalInputRequestFact = {
187
+ callId: event.data.callId,
188
+ toolName: event.data.toolName,
189
+ args: {
190
+ connection: event.data.connection,
191
+ authUrl: event.data.authUrl,
192
+ },
193
+ resolved: false,
194
+ };
195
+ inputRequests.push(request);
196
+ inputRequestsByCallId.set(event.data.callId, request);
197
+ break;
198
+ }
199
+ case "action.auth_resolved": {
200
+ const request = inputRequestsByCallId.get(event.data.callId);
201
+ if (request !== undefined) {
202
+ request.resolved = true;
203
+ request.decision = event.data.decision;
204
+ }
205
+ const fact = ensureCall(
206
+ event.data.callId,
207
+ event.data.toolName,
208
+ event.turnId,
209
+ event.data.parentCallId
210
+ );
211
+ fact.approvalDecision = event.data.decision;
212
+ if (event.data.decision === "deny") {
213
+ fact.status = "rejected";
214
+ }
215
+ break;
216
+ }
185
217
  case "subagent.called": {
186
218
  const existing = subagentsByCallId.get(event.data.callId);
187
219
  if (existing === undefined) {
@@ -118,24 +118,45 @@ export async function resolveAdvertisedTools(args: {
118
118
  return [];
119
119
  }
120
120
  const sourceFor = args.sourceFor ?? sourceForConnection;
121
+ // Each connection's listing is a network round trip against a distinct
122
+ // server (auth callback, MCP initialize, tools/list), so they run
123
+ // concurrently; the fan-out is bounded by the agent's declared
124
+ // connections. Name assignment below stays in declaration order so
125
+ // collision suffixes do not depend on which server answered first.
126
+ type Listing =
127
+ | {
128
+ connection: DiscoveredConnection;
129
+ ok: true;
130
+ source: AdvertisedToolSource;
131
+ listed: HostMcpToolInfo[];
132
+ }
133
+ | { connection: DiscoveredConnection; ok: false; error: unknown };
134
+ const listings = await Promise.all(
135
+ advertising.map(async (connection): Promise<Listing> => {
136
+ try {
137
+ const source = await sourceFor(connection, args.session, args.hostMcp);
138
+ const listed = await source.listTools();
139
+ return { connection, ok: true, source, listed };
140
+ } catch (error) {
141
+ return { connection, ok: false, error };
142
+ }
143
+ })
144
+ );
121
145
  const claimed = new Set(args.agent.tools.map((tool) => tool.name));
122
146
  const resolved: DiscoveredTool[] = [];
123
- for (const connection of advertising) {
124
- let listed: HostMcpToolInfo[];
125
- let source: AdvertisedToolSource;
126
- try {
127
- source = await sourceFor(connection, args.session, args.hostMcp);
128
- listed = await source.listTools();
129
- } catch (error) {
147
+ for (const listing of listings) {
148
+ const { connection } = listing;
149
+ if (!listing.ok) {
130
150
  if (args.onConnectionError !== undefined) {
131
- args.onConnectionError(connection.name, error);
151
+ args.onConnectionError(connection.name, listing.error);
132
152
  continue;
133
153
  }
134
154
  throw new Error(
135
- `Failed to list tools on advertised connection "${connection.name}": ${describeError(error)}`,
136
- { cause: error }
155
+ `Failed to list tools on advertised connection "${connection.name}": ${describeError(listing.error)}`,
156
+ { cause: listing.error }
137
157
  );
138
158
  }
159
+ const { source, listed } = listing;
139
160
  const intended = listed.filter(
140
161
  (info) =>
141
162
  !isDoNotCallTool(info.annotations) &&
@@ -1,13 +1,12 @@
1
1
  /**
2
- * In-memory gate for human-in-the-loop tool approvals. The session
3
- * engine parks inside a server-tool `execute` by awaiting
4
- * {@link ApprovalGate.wait}; HTTP (or the playground) unblocks via
5
- * {@link ApprovalGate.resolve}.
2
+ * In-memory gate for human-in-the-loop parks. The session engine parks
3
+ * inside a server-tool `execute` by awaiting {@link ApprovalGate.wait};
4
+ * HTTP (or the playground) unblocks via {@link ApprovalGate.resolve}.
6
5
  *
7
- * Pending approvals are also mirrored onto {@link SessionRecord} for
8
- * durability of the *list* across reloads. After a process restart the
9
- * in-flight SDK tool callback is gone, so resolve returns false and
10
- * the host treats the approval as interrupted.
6
+ * Used for `needsApproval` and MCP on-demand auth. Pending rows are also
7
+ * mirrored onto {@link SessionRecord} for durability of the *list* across
8
+ * reloads. After a process restart the in-flight SDK tool callback is gone,
9
+ * so resolve returns false and the host treats the park as interrupted.
11
10
  */
12
11
 
13
12
  import type { ApprovalDecision, PendingApproval } from "../types.js";
@@ -21,33 +20,25 @@ export interface ApprovalResolution {
21
20
  by?: string;
22
21
  }
23
22
 
24
- interface Waiter {
25
- meta: PendingApproval;
23
+ interface Waiter<T> {
24
+ meta: T;
26
25
  resolve: (resolution: ApprovalResolution) => void;
27
26
  }
28
27
 
29
- export class ApprovalGate {
30
- private readonly waiters = new Map<string, Waiter>();
28
+ export class ApprovalGate<T extends { callId: string } = PendingApproval> {
29
+ private readonly waiters = new Map<string, Waiter<T>>();
31
30
 
32
- wait(
33
- meta: PendingApproval & { sessionId: string }
34
- ): Promise<ApprovalResolution> {
35
- const key = approvalKey(meta.sessionId, meta.callId);
31
+ wait(sessionId: string, meta: T): Promise<ApprovalResolution> {
32
+ const key = approvalKey(sessionId, meta.callId);
36
33
  const existing = this.waiters.get(key);
37
34
  if (existing !== undefined) {
38
35
  throw new Error(
39
- `Approval already pending for session ${meta.sessionId} call ${meta.callId}`
36
+ `Approval already pending for session ${sessionId} call ${meta.callId}`
40
37
  );
41
38
  }
42
39
  return new Promise<ApprovalResolution>((resolveDecision) => {
43
40
  this.waiters.set(key, {
44
- meta: {
45
- callId: meta.callId,
46
- turnId: meta.turnId,
47
- toolName: meta.toolName,
48
- args: meta.args,
49
- requestedAt: meta.requestedAt,
50
- },
41
+ meta,
51
42
  resolve: resolveDecision,
52
43
  });
53
44
  });
@@ -69,11 +60,11 @@ export class ApprovalGate {
69
60
  return false;
70
61
  }
71
62
  this.waiters.delete(key);
63
+ const by =
64
+ resolvedBy === undefined || resolvedBy === "" ? undefined : resolvedBy;
72
65
  waiter.resolve({
73
66
  decision,
74
- ...(resolvedBy === undefined || resolvedBy === ""
75
- ? {}
76
- : { by: resolvedBy }),
67
+ by,
77
68
  });
78
69
  return true;
79
70
  }
@@ -82,9 +73,9 @@ export class ApprovalGate {
82
73
  return this.waiters.has(approvalKey(sessionId, callId));
83
74
  }
84
75
 
85
- list(sessionId: string): PendingApproval[] {
76
+ list(sessionId: string): T[] {
86
77
  const prefix = `${sessionId}\0`;
87
- const out: PendingApproval[] = [];
78
+ const out: T[] = [];
88
79
  for (const [key, waiter] of this.waiters) {
89
80
  if (key.startsWith(prefix)) {
90
81
  out.push(waiter.meta);
@@ -483,6 +483,25 @@ async function streamTurn(args: StreamTurnArgs): Promise<number> {
483
483
  );
484
484
  continue;
485
485
  }
486
+ if (event.type === "action.auth_requested") {
487
+ closeAssistant();
488
+ write(
489
+ ` ${c.yellow("⏸")} ${c.bold(event.data.connection)} ${c.dim(
490
+ "awaiting MCP authorization"
491
+ )}\n`
492
+ );
493
+ continue;
494
+ }
495
+ if (event.type === "action.auth_resolved") {
496
+ const mark =
497
+ event.data.decision === "approve" ? c.green("✓") : c.red("✗");
498
+ write(
499
+ ` ${mark} ${c.bold(event.data.connection)} ${c.dim(
500
+ event.data.decision === "approve" ? "connected" : "denied"
501
+ )}\n`
502
+ );
503
+ continue;
504
+ }
486
505
  if (event.type === "action.result") {
487
506
  if (
488
507
  event.data.toolName === "task" &&
@@ -112,6 +112,11 @@ export interface DeployCliOptions {
112
112
  cursorEventsRepos?: string[];
113
113
  /** deploy `--allow-domain <domain>` (repeatable; unioned with the manifest). */
114
114
  allowDomains?: string[];
115
+ /**
116
+ * deploy `--multi-tenant`: add a release to an existing Cursor-managed
117
+ * (multi-tenant) product. Cannot create a new multi-tenant application.
118
+ */
119
+ multiTenant?: boolean;
115
120
  /** Test seams. */
116
121
  fetchImpl?: typeof fetch;
117
122
  /** Inject the connector-auth browser opener (tests; also forces interactive). */
@@ -311,7 +316,9 @@ export async function cmdDeploy(options: DeployCliOptions): Promise<number> {
311
316
  manifests.push(await readDeployManifest(target.dir));
312
317
  }
313
318
  if (manifests.every((manifest) => manifest.architecture === "v2")) {
314
- return deployAgentsdkApplication(ctx, options, targets);
319
+ return deployAgentsdkApplication(ctx, options, targets, {
320
+ hasScmChannels: manifests.some((manifest) => manifest.hasScmChannels),
321
+ });
315
322
  }
316
323
  if (
317
324
  !ctx.json &&
@@ -722,9 +729,18 @@ async function deployOne(
722
729
  gitRef,
723
730
  agentPath,
724
731
  repositories: options.cursorEventsRepos,
732
+ hasScmChannels: manifest.hasScmChannels,
733
+ multiTenant: options.multiTenant === true,
725
734
  });
726
735
  }
727
736
 
737
+ if (options.multiTenant === true) {
738
+ ctx.err(
739
+ "--multi-tenant is only valid for architecture: v2 deploys (Cursor-managed products).\n"
740
+ );
741
+ return 1;
742
+ }
743
+
728
744
  // Today's only source shape: the control plane builds from a git ref.
729
745
  // See DeploySource for the artifact seam.
730
746
  const source: DeploySource = {
@@ -804,11 +820,9 @@ async function deployOne(
804
820
  }
805
821
 
806
822
  if (detail.status !== "running") {
807
- const errorDetail =
808
- detail.lastError === null || detail.lastError === undefined
809
- ? ""
810
- : `: ${sanitizeCustomerError(detail.lastError)}`;
811
- ctx.err(`Deployment ${slug} ended ${detail.status}${errorDetail}\n`);
823
+ ctx.err(
824
+ `Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
825
+ );
812
826
  return 1;
813
827
  }
814
828
  const deployedPublicRoutes = detail.publicRoutePaths ?? [];
@@ -845,7 +859,8 @@ async function deployOne(
845
859
  async function deployAgentsdkApplication(
846
860
  ctx: DeployCliContext,
847
861
  options: DeployCliOptions,
848
- targets: readonly DeployTarget[]
862
+ targets: readonly DeployTarget[],
863
+ declarations: { hasScmChannels: boolean }
849
864
  ): Promise<number> {
850
865
  const parentDir = resolve(options.dir ?? ".");
851
866
  const slug = slugFromDirectoryName(basename(parentDir));
@@ -926,6 +941,8 @@ async function deployAgentsdkApplication(
926
941
  agentPath: undefined,
927
942
  components,
928
943
  repositories: options.cursorEventsRepos,
944
+ hasScmChannels: declarations.hasScmChannels,
945
+ multiTenant: options.multiTenant === true,
929
946
  });
930
947
  }
931
948
 
@@ -944,6 +961,10 @@ async function deployOneAgentsdk(
944
961
  agentPath: string | undefined;
945
962
  components?: AgentkitDeployComponent[];
946
963
  repositories: string[] | undefined;
964
+ /** Any component declares a GitHub/Origin channel. */
965
+ hasScmChannels: boolean;
966
+ /** Redeploy an existing Cursor-managed product. */
967
+ multiTenant: boolean;
947
968
  }
948
969
  ): Promise<number> {
949
970
  const { slug } = args;
@@ -953,6 +974,9 @@ async function deployOneAgentsdk(
953
974
  : ` components: ${args.components
954
975
  .map((component) => component.componentKey)
955
976
  .join(", ")}\n`;
977
+ if (args.multiTenant && !ctx.json) {
978
+ ctx.err(" multi-tenant: existing product\n");
979
+ }
956
980
  let accepted: AgentkitDeployAccepted;
957
981
  try {
958
982
  accepted = await ctx.client.deployAgentkit({
@@ -963,6 +987,7 @@ async function deployOneAgentsdk(
963
987
  agentPath: args.agentPath,
964
988
  components: args.components,
965
989
  repositories: args.repositories,
990
+ ...(args.multiTenant ? { multiTenant: true } : {}),
966
991
  });
967
992
  } catch (error) {
968
993
  return renderApiError(error, ctx.err);
@@ -1004,7 +1029,9 @@ async function deployOneAgentsdk(
1004
1029
  }
1005
1030
 
1006
1031
  if (detail.status !== "running") {
1007
- ctx.err(`Deployment ${slug} ended ${detail.status}\n`);
1032
+ ctx.err(
1033
+ `Deployment ${slug} ended ${detail.status}${deployFailureDetail(detail.lastError)}\n`
1034
+ );
1008
1035
  return 1;
1009
1036
  }
1010
1037
  ctx.out(
@@ -1017,8 +1044,19 @@ async function deployOneAgentsdk(
1017
1044
  ? ""
1018
1045
  : ` components: ${args.components
1019
1046
  .map((component) => component.componentKey)
1020
- .join(", ")}\n`)
1047
+ .join(", ")}\n`) +
1048
+ (detail.repositories === undefined || !args.hasScmChannels
1049
+ ? ""
1050
+ : ` watching: ${detail.repositories.length === 0 ? "(nothing)" : detail.repositories.join(", ")}\n`)
1021
1051
  );
1052
+ // An agent with GitHub/Origin channels bound to no repository scope gets
1053
+ // no deliveries at all, which is otherwise invisible in this output.
1054
+ if (args.hasScmChannels && detail.repositories?.length === 0) {
1055
+ ctx.err(
1056
+ `warning: ${slug} watches no repositories, so its GitHub/Origin channels receive no events.\n` +
1057
+ ` Redeploy with --cursor-events-repo <owner>/<name> to set the scope.\n`
1058
+ );
1059
+ }
1022
1060
  return 0;
1023
1061
  }
1024
1062
 
@@ -1128,6 +1166,11 @@ interface DeployManifest {
1128
1166
  * (only `/v1/channels/…` subtrees can be public); surfaced as a warning.
1129
1167
  */
1130
1168
  httpChannelPublicEndpoint: boolean;
1169
+ /**
1170
+ * The agent has GitHub/Origin channels, so it only receives deliveries
1171
+ * while the deployment is bound to at least one `owner/name` scope.
1172
+ */
1173
+ hasScmChannels: boolean;
1131
1174
  }
1132
1175
 
1133
1176
  /**
@@ -1163,6 +1206,10 @@ async function readDeployManifest(dir: string): Promise<DeployManifest> {
1163
1206
  httpChannelPublicEndpoint: (project.httpChannel.auth ?? []).some(
1164
1207
  isPublicEndpointPolicy
1165
1208
  ),
1209
+ hasScmChannels: project.channels.some((channel) => {
1210
+ const kind = channel.definition.meta?.kind;
1211
+ return kind === "github" || kind === "origin";
1212
+ }),
1166
1213
  };
1167
1214
  }
1168
1215
 
@@ -1938,9 +1985,32 @@ function aliasTokenBlock(aliasToken: string): string {
1938
1985
  );
1939
1986
  }
1940
1987
 
1988
+ /**
1989
+ * `: <reason>` suffix for a deploy that ended in a non-running state, or
1990
+ * empty when the control plane recorded no reason.
1991
+ */
1992
+ function deployFailureDetail(lastError: string | null | undefined): string {
1993
+ if (
1994
+ lastError === null ||
1995
+ lastError === undefined ||
1996
+ lastError.trim() === ""
1997
+ ) {
1998
+ return "";
1999
+ }
2000
+ return `: ${sanitizeCustomerError(lastError.trim())}`;
2001
+ }
2002
+
1941
2003
  function renderApiError(error: unknown, err: (text: string) => void): number {
1942
2004
  if (error instanceof DeployApiError) {
1943
2005
  err(`${error.message}\n`);
2006
+ if (
2007
+ error.status === 409 &&
2008
+ error.message.includes("application multiTenant does not match")
2009
+ ) {
2010
+ err(
2011
+ "This slug is a Cursor-managed (multi-tenant) product. Redeploy it with --multi-tenant.\n"
2012
+ );
2013
+ }
1944
2014
  return 1;
1945
2015
  }
1946
2016
  throw error;
@@ -23,10 +23,10 @@ import { CLI_COMMAND_NAME as CLI, LOG_PREFIX } from "./distribution.js";
23
23
  import {
24
24
  createHostMcpOAuthProvider,
25
25
  MCP_OAUTH_CALLBACK_URL,
26
- mcpOauthSecretNames,
27
26
  openBrowser,
28
27
  waitForMcpOAuthCallback,
29
28
  } from "./mcp-oauth.js";
29
+ import { upsertHostMcpOauthSecrets } from "./mcp-oauth-persist.js";
30
30
  import { resolveProdSlug } from "./resolve-prod-target.js";
31
31
 
32
32
  export type McpOauthCliOptions = {
@@ -381,29 +381,15 @@ async function storeOauthSecrets(args: {
381
381
  return auth;
382
382
  }
383
383
 
384
- const names = mcpOauthSecretNames(args.connection);
385
- const secrets: Array<{ name: string; value: string }> = [
386
- { name: names.accessToken, value: tokens.access_token },
387
- ];
388
- if (
389
- tokens.refresh_token !== undefined &&
390
- tokens.refresh_token.trim() !== ""
391
- ) {
392
- secrets.push({ name: names.refreshToken, value: tokens.refresh_token });
393
- }
394
- if (args.clientId !== undefined && args.clientId.trim() !== "") {
395
- secrets.push({ name: names.clientId, value: args.clientId });
396
- }
397
-
398
384
  try {
399
- const secretNames = await auth.client.setSecrets({
400
- teamId: auth.teamId,
401
- slug,
402
- secrets,
385
+ const secretNames = await upsertHostMcpOauthSecrets({
386
+ connection: args.connection,
387
+ tokens,
388
+ clientId: args.clientId,
389
+ target: { client: auth.client, teamId: auth.teamId, slug },
403
390
  });
404
391
  args.out(
405
- `${LOG_PREFIX} Stored on ${slug}: ${secrets.map((s) => s.name).join(", ")}.\n` +
406
- `${LOG_PREFIX} Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`
392
+ `${LOG_PREFIX} Stored on ${slug}. Secrets now: ${secretNames.join(", ")}. Next deploy picks them up.\n`
407
393
  );
408
394
  return 0;
409
395
  } catch (error) {