@cursor/july 0.1.95 → 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 (424) hide show
  1. package/AGENTS.md +3 -4
  2. package/README.md +3 -2
  3. package/dist/bin/agent-serve.js +14 -3
  4. package/dist/channels/deployments/types.d.ts +1 -1
  5. package/dist/channels/deployments/types.d.ts.map +1 -1
  6. package/dist/channels/deployments/types.js +1 -0
  7. package/dist/channels/origin/api.d.ts +72 -15
  8. package/dist/channels/origin/api.d.ts.map +1 -1
  9. package/dist/channels/origin/api.js +185 -28
  10. package/dist/channels/origin/binding.d.ts +13 -2
  11. package/dist/channels/origin/binding.d.ts.map +1 -1
  12. package/dist/channels/origin/binding.js +41 -25
  13. package/dist/channels/origin/checks.d.ts +6 -6
  14. package/dist/channels/origin/checks.js +6 -6
  15. package/dist/channels/origin/cursor-account.d.ts +5 -3
  16. package/dist/channels/origin/cursor-account.d.ts.map +1 -1
  17. package/dist/channels/origin/cursor-account.js +5 -3
  18. package/dist/channels/origin/index.d.ts +1 -0
  19. package/dist/channels/origin/index.d.ts.map +1 -1
  20. package/dist/channels/origin/index.js +1 -0
  21. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  22. package/dist/channels/origin/origin-channel.js +3 -0
  23. package/dist/channels/origin/reactions.d.ts +56 -0
  24. package/dist/channels/origin/reactions.d.ts.map +1 -0
  25. package/dist/channels/origin/reactions.js +67 -0
  26. package/dist/channels/origin/types.d.ts +11 -0
  27. package/dist/channels/origin/types.d.ts.map +1 -1
  28. package/dist/channels/slack/api.d.ts +9 -0
  29. package/dist/channels/slack/api.d.ts.map +1 -1
  30. package/dist/channels/slack/api.js +36 -5
  31. package/dist/channels/slack/approvals.d.ts +16 -0
  32. package/dist/channels/slack/approvals.d.ts.map +1 -1
  33. package/dist/channels/slack/approvals.js +86 -0
  34. package/dist/channels/slack/cli-project.d.ts +19 -0
  35. package/dist/channels/slack/cli-project.d.ts.map +1 -0
  36. package/dist/channels/slack/cli-project.js +234 -0
  37. package/dist/channels/slack/defaults.d.ts.map +1 -1
  38. package/dist/channels/slack/defaults.js +110 -81
  39. package/dist/channels/slack/dispatch.d.ts +7 -1
  40. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  41. package/dist/channels/slack/dispatch.js +47 -23
  42. package/dist/channels/slack/inbound.d.ts +8 -0
  43. package/dist/channels/slack/inbound.d.ts.map +1 -1
  44. package/dist/channels/slack/inbound.js +32 -0
  45. package/dist/channels/slack/init.d.ts +3 -2
  46. package/dist/channels/slack/init.d.ts.map +1 -1
  47. package/dist/channels/slack/init.js +5 -5
  48. package/dist/channels/slack/interactive.d.ts +2 -1
  49. package/dist/channels/slack/interactive.d.ts.map +1 -1
  50. package/dist/channels/slack/interactive.js +15 -4
  51. package/dist/channels/slack/live-delivery.d.ts +26 -29
  52. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  53. package/dist/channels/slack/live-delivery.js +172 -73
  54. package/dist/channels/slack/manifest.d.ts +1 -1
  55. package/dist/channels/slack/manifest.d.ts.map +1 -1
  56. package/dist/channels/slack/manifest.js +6 -2
  57. package/dist/channels/slack/nudge-carrier.d.ts +2 -0
  58. package/dist/channels/slack/nudge-carrier.d.ts.map +1 -1
  59. package/dist/channels/slack/nudge-carrier.js +48 -1
  60. package/dist/channels/slack/setup.d.ts +1 -1
  61. package/dist/channels/slack/setup.d.ts.map +1 -1
  62. package/dist/channels/slack/setup.js +10 -6
  63. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  64. package/dist/channels/slack/slack-channel.js +3 -2
  65. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
  66. package/dist/channels/slack/tool-approval-events.js +91 -1
  67. package/dist/docs/404.html +2 -2
  68. package/dist/docs/ab.html +4 -4
  69. package/dist/docs/assets/{app.BBj0klBO.js → app.B3rWNYE1.js} +1 -1
  70. package/dist/docs/assets/chunks/@localSearchIndexroot.BU9nHdnQ.js +1 -0
  71. package/dist/docs/assets/chunks/{VPLocalSearchBox.CUEXpL78.js → VPLocalSearchBox.C1lhqJJR.js} +1 -1
  72. package/dist/docs/assets/chunks/{theme.DabmQnia.js → theme.B40_SXuv.js} +2 -2
  73. package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
  74. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
  75. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
  76. package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
  77. package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
  78. package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
  79. package/dist/docs/assets/{index.md.BoHaMdeZ.lean.js → index.md.CVeRUOeZ.lean.js} +1 -1
  80. package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
  81. package/dist/docs/assets/{reference_cli.md.BsMOxDvh.js → reference_cli.md.RyZf5OTE.js} +10 -6
  82. package/dist/docs/assets/{reference_cli.md.BsMOxDvh.lean.js → reference_cli.md.RyZf5OTE.lean.js} +1 -1
  83. package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
  84. package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.5zOAbV86.js} +1 -1
  85. package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
  86. package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.B84gw9Ii.js} +1 -1
  87. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
  88. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
  89. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.js +2 -0
  90. package/dist/docs/assets/templates_code-wiki.md.CDYZIBFN.lean.js +1 -0
  91. package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
  92. package/dist/docs/building-with-agents.html +4 -4
  93. package/dist/docs/concepts.html +4 -4
  94. package/dist/docs/deployment.html +7 -7
  95. package/dist/docs/deployment.md +5 -4
  96. package/dist/docs/evals.html +4 -4
  97. package/dist/docs/guides/agent-to-agent.html +4 -4
  98. package/dist/docs/guides/cloud-runtime.html +4 -4
  99. package/dist/docs/guides/convert-automation.html +4 -4
  100. package/dist/docs/guides/github.html +4 -4
  101. package/dist/docs/guides/human-in-the-loop.html +4 -4
  102. package/dist/docs/guides/mcp-oauth.html +8 -8
  103. package/dist/docs/guides/mcp-oauth.md +26 -8
  104. package/dist/docs/guides/opentelemetry.html +4 -4
  105. package/dist/docs/guides/slack.html +17 -33
  106. package/dist/docs/guides/slack.md +92 -201
  107. package/dist/docs/guides/webhooks.html +4 -4
  108. package/dist/docs/hashmap.json +1 -1
  109. package/dist/docs/hillclimbing.html +4 -4
  110. package/dist/docs/index.html +6 -6
  111. package/dist/docs/index.md +7 -3
  112. package/dist/docs/llms-full.txt +398 -653
  113. package/dist/docs/llms.txt +3 -2
  114. package/dist/docs/quickstart.html +4 -4
  115. package/dist/docs/reference/agent-config.html +6 -6
  116. package/dist/docs/reference/agent-config.md +2 -2
  117. package/dist/docs/reference/artifacts.html +4 -4
  118. package/dist/docs/reference/channels.html +4 -4
  119. package/dist/docs/reference/cli.html +14 -10
  120. package/dist/docs/reference/cli.md +39 -16
  121. package/dist/docs/reference/connections.html +9 -8
  122. package/dist/docs/reference/connections.md +6 -3
  123. package/dist/docs/reference/hooks.html +4 -4
  124. package/dist/docs/reference/http-api.html +6 -6
  125. package/dist/docs/reference/http-api.md +2 -1
  126. package/dist/docs/reference/instructions.html +4 -4
  127. package/dist/docs/reference/playground.html +4 -4
  128. package/dist/docs/reference/project-layout.html +4 -4
  129. package/dist/docs/reference/prompt.html +4 -4
  130. package/dist/docs/reference/schedules.html +4 -4
  131. package/dist/docs/reference/sessions.html +5 -5
  132. package/dist/docs/reference/sessions.md +4 -2
  133. package/dist/docs/reference/skills.html +4 -4
  134. package/dist/docs/reference/subagents.html +4 -4
  135. package/dist/docs/reference/tools.html +6 -6
  136. package/dist/docs/reference/tools.md +9 -2
  137. package/dist/docs/scaffolding-agents.html +4 -4
  138. package/dist/docs/storage.html +4 -4
  139. package/dist/docs/templates/agentic-owners.html +4 -4
  140. package/dist/docs/templates/agents-md.html +28 -0
  141. package/dist/docs/templates/agents-md.md +105 -0
  142. package/dist/docs/templates/code-wiki.html +28 -0
  143. package/dist/docs/templates/code-wiki.md +91 -0
  144. package/dist/docs/templates/demo.html +5 -5
  145. package/dist/docs/templates/pr-autofixer.html +4 -4
  146. package/dist/docs/templates/security-help.html +4 -4
  147. package/dist/docs/templates/security-reviewer.html +5 -5
  148. package/dist/docs/templates/triage.html +4 -4
  149. package/dist/docs/troubleshooting.html +5 -5
  150. package/dist/docs/troubleshooting.md +2 -2
  151. package/dist/evals/run-facts.d.ts.map +1 -1
  152. package/dist/evals/run-facts.js +27 -0
  153. package/dist/files-backends/cursor-hosted.d.ts +26 -4
  154. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  155. package/dist/files-backends/cursor-hosted.js +32 -4
  156. package/dist/internal/advertise-tools.d.ts +2 -0
  157. package/dist/internal/advertise-tools.d.ts.map +1 -1
  158. package/dist/internal/advertise-tools.js +30 -10
  159. package/dist/internal/approval-gate.d.ts +12 -13
  160. package/dist/internal/approval-gate.d.ts.map +1 -1
  161. package/dist/internal/approval-gate.js +16 -21
  162. package/dist/internal/bounded.d.ts +7 -0
  163. package/dist/internal/bounded.d.ts.map +1 -0
  164. package/dist/internal/bounded.js +32 -0
  165. package/dist/internal/chat-client.js +10 -0
  166. package/dist/internal/cli-deploy.d.ts +5 -0
  167. package/dist/internal/cli-deploy.d.ts.map +1 -1
  168. package/dist/internal/cli-deploy.js +57 -18
  169. package/dist/internal/cli-mcp-oauth.js +8 -18
  170. package/dist/internal/cli-slack-manual.d.ts +24 -2
  171. package/dist/internal/cli-slack-manual.d.ts.map +1 -1
  172. package/dist/internal/cli-slack-manual.js +251 -20
  173. package/dist/internal/cli-slack.d.ts +9 -2
  174. package/dist/internal/cli-slack.d.ts.map +1 -1
  175. package/dist/internal/cli-slack.js +29 -82
  176. package/dist/internal/conversation-mirror.d.ts +11 -8
  177. package/dist/internal/conversation-mirror.d.ts.map +1 -1
  178. package/dist/internal/conversation-mirror.js +116 -55
  179. package/dist/internal/cursor/account-mcp.d.ts +1 -0
  180. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  181. package/dist/internal/cursor/account-mcp.js +17 -0
  182. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  183. package/dist/internal/cursor/backend-client.js +22 -48
  184. package/dist/internal/cursor/session-token.d.ts +45 -0
  185. package/dist/internal/cursor/session-token.d.ts.map +1 -0
  186. package/dist/internal/cursor/session-token.js +99 -0
  187. package/dist/internal/cursor-agent-template.d.ts +1 -1
  188. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  189. package/dist/internal/cursor-agent-template.js +2 -0
  190. package/dist/internal/deploy-client.d.ts +17 -0
  191. package/dist/internal/deploy-client.d.ts.map +1 -1
  192. package/dist/internal/deploy-client.js +31 -10
  193. package/dist/internal/env-file.d.ts +19 -0
  194. package/dist/internal/env-file.d.ts.map +1 -0
  195. package/dist/internal/env-file.js +90 -0
  196. package/dist/internal/framework-file-storage.d.ts +61 -0
  197. package/dist/internal/framework-file-storage.d.ts.map +1 -0
  198. package/dist/internal/framework-file-storage.js +210 -0
  199. package/dist/internal/framework-storage-selection.d.ts +11 -5
  200. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  201. package/dist/internal/framework-storage-selection.js +38 -11
  202. package/dist/internal/hosted-delivery-protocol.d.ts +7 -0
  203. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  204. package/dist/internal/hosted-delivery-protocol.js +7 -0
  205. package/dist/internal/hosted-delivery.d.ts +13 -0
  206. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  207. package/dist/internal/hosted-delivery.js +64 -19
  208. package/dist/internal/hosted-execution-diag.d.ts +48 -0
  209. package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
  210. package/dist/internal/hosted-execution-diag.js +150 -0
  211. package/dist/internal/http-channel.d.ts.map +1 -1
  212. package/dist/internal/http-channel.js +81 -1
  213. package/dist/internal/init-project.d.ts.map +1 -1
  214. package/dist/internal/init-project.js +4 -0
  215. package/dist/internal/install-cursor-skills.d.ts.map +1 -1
  216. package/dist/internal/install-cursor-skills.js +1 -3
  217. package/dist/internal/logs-client.d.ts +5 -0
  218. package/dist/internal/logs-client.d.ts.map +1 -1
  219. package/dist/internal/logs-client.js +5 -0
  220. package/dist/internal/managed-delivery.d.ts +80 -0
  221. package/dist/internal/managed-delivery.d.ts.map +1 -0
  222. package/dist/internal/managed-delivery.js +86 -0
  223. package/dist/internal/mcp-endpoint.js +2 -3
  224. package/dist/internal/mcp-host.d.ts +10 -0
  225. package/dist/internal/mcp-host.d.ts.map +1 -1
  226. package/dist/internal/mcp-host.js +57 -8
  227. package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
  228. package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
  229. package/dist/internal/mcp-oauth-on-demand.js +287 -0
  230. package/dist/internal/mcp-oauth-persist.d.ts +42 -0
  231. package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
  232. package/dist/internal/mcp-oauth-persist.js +92 -0
  233. package/dist/internal/mcp-oauth.d.ts +1 -0
  234. package/dist/internal/mcp-oauth.d.ts.map +1 -1
  235. package/dist/internal/mcp-oauth.js +10 -2
  236. package/dist/internal/otel/collector.d.ts.map +1 -1
  237. package/dist/internal/otel/collector.js +22 -9
  238. package/dist/internal/runtime-dispatch-runner.d.ts +5 -1
  239. package/dist/internal/runtime-dispatch-runner.d.ts.map +1 -1
  240. package/dist/internal/runtime-dispatch-runner.js +7 -0
  241. package/dist/internal/sdk-runner.d.ts +11 -0
  242. package/dist/internal/sdk-runner.d.ts.map +1 -1
  243. package/dist/internal/sdk-runner.js +39 -8
  244. package/dist/internal/server.d.ts +3 -0
  245. package/dist/internal/server.d.ts.map +1 -1
  246. package/dist/internal/server.js +49 -21
  247. package/dist/internal/session-engine.d.ts +101 -3
  248. package/dist/internal/session-engine.d.ts.map +1 -1
  249. package/dist/internal/session-engine.js +577 -46
  250. package/dist/internal/sessions-client.d.ts +9 -7
  251. package/dist/internal/sessions-client.d.ts.map +1 -1
  252. package/dist/internal/sessions-client.js +3 -1
  253. package/dist/internal/steering.d.ts +15 -0
  254. package/dist/internal/steering.d.ts.map +1 -0
  255. package/dist/internal/steering.js +18 -0
  256. package/dist/internal/storage-coordinator.d.ts +7 -0
  257. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  258. package/dist/internal/storage-coordinator.js +28 -5
  259. package/dist/internal/storage-roles.d.ts +5 -0
  260. package/dist/internal/storage-roles.d.ts.map +1 -1
  261. package/dist/internal/stream-progress.d.ts.map +1 -1
  262. package/dist/internal/stream-progress.js +10 -0
  263. package/dist/internal/tool-policy.d.ts +9 -1
  264. package/dist/internal/tool-policy.d.ts.map +1 -1
  265. package/dist/internal/tool-policy.js +13 -0
  266. package/dist/internal/trajectory.d.ts.map +1 -1
  267. package/dist/internal/trajectory.js +10 -0
  268. package/dist/internal/turn-outbox.d.ts +24 -0
  269. package/dist/internal/turn-outbox.d.ts.map +1 -0
  270. package/dist/internal/turn-outbox.js +80 -0
  271. package/dist/playground/assets/{index-CZA1uEWA.js → index-DrkI6y5O.js} +51 -51
  272. package/dist/playground/assets/index-DzNGwm7q.css +1 -0
  273. package/dist/playground/index.html +2 -2
  274. package/dist/storage-backends/cursor-hosted.d.ts +9 -6
  275. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  276. package/dist/storage-backends/cursor-hosted.js +16 -3
  277. package/dist/storage.d.ts +8 -0
  278. package/dist/storage.d.ts.map +1 -1
  279. package/dist/types.d.ts +65 -8
  280. package/dist/types.d.ts.map +1 -1
  281. package/docs/README.md +7 -3
  282. package/docs/deployment.md +5 -4
  283. package/docs/guides/mcp-oauth.md +26 -8
  284. package/docs/guides/slack.md +93 -202
  285. package/docs/reference/agent-config.md +2 -2
  286. package/docs/reference/cli.md +39 -16
  287. package/docs/reference/connections.md +6 -3
  288. package/docs/reference/http-api.md +2 -1
  289. package/docs/reference/sessions.md +4 -2
  290. package/docs/reference/tools.md +9 -2
  291. package/docs/templates/agents-md.md +110 -0
  292. package/docs/templates/code-wiki.md +96 -0
  293. package/docs/troubleshooting.md +2 -2
  294. package/package.json +2 -2
  295. package/skills/ab/SKILL.md +13 -97
  296. package/skills/create-agent/SKILL.md +124 -223
  297. package/skills/debug/SKILL.md +34 -68
  298. package/skills/evals/SKILL.md +55 -180
  299. package/skills/framework-map/SKILL.md +83 -145
  300. package/skills/github/SKILL.md +53 -111
  301. package/skills/hillclimb/SKILL.md +40 -163
  302. package/skills/mcp-auth/SKILL.md +51 -107
  303. package/skills/otel/SKILL.md +22 -68
  304. package/skills/setup-slack/SKILL.md +91 -212
  305. package/src/bin/agent-serve.ts +13 -1
  306. package/src/channels/deployments/types.ts +1 -0
  307. package/src/channels/origin/api.ts +264 -33
  308. package/src/channels/origin/binding.ts +57 -28
  309. package/src/channels/origin/checks.ts +6 -6
  310. package/src/channels/origin/cursor-account.ts +5 -3
  311. package/src/channels/origin/index.ts +1 -0
  312. package/src/channels/origin/origin-channel.ts +4 -0
  313. package/src/channels/origin/reactions.ts +82 -0
  314. package/src/channels/origin/types.ts +11 -0
  315. package/src/channels/slack/api.ts +41 -5
  316. package/src/channels/slack/approvals.ts +105 -0
  317. package/src/channels/slack/cli-project.ts +267 -0
  318. package/src/channels/slack/defaults.ts +122 -93
  319. package/src/channels/slack/dispatch.ts +56 -22
  320. package/src/channels/slack/inbound.ts +43 -0
  321. package/src/channels/slack/init.ts +10 -5
  322. package/src/channels/slack/interactive.ts +35 -9
  323. package/src/channels/slack/live-delivery.ts +235 -114
  324. package/src/channels/slack/manifest.ts +6 -2
  325. package/src/channels/slack/nudge-carrier.ts +48 -1
  326. package/src/channels/slack/setup.ts +10 -6
  327. package/src/channels/slack/slack-channel.ts +3 -0
  328. package/src/channels/slack/tool-approval-events.ts +93 -0
  329. package/src/evals/run-facts.ts +32 -0
  330. package/src/files-backends/cursor-hosted.ts +40 -7
  331. package/src/internal/advertise-tools.ts +49 -12
  332. package/src/internal/approval-gate.ts +20 -29
  333. package/src/internal/bounded.ts +28 -0
  334. package/src/internal/chat-client.ts +19 -0
  335. package/src/internal/cli-deploy.ts +91 -9
  336. package/src/internal/cli-mcp-oauth.ts +7 -21
  337. package/src/internal/cli-slack-manual.ts +350 -18
  338. package/src/internal/cli-slack.ts +40 -84
  339. package/src/internal/conversation-mirror.ts +145 -69
  340. package/src/internal/cursor/account-mcp.ts +21 -0
  341. package/src/internal/cursor/backend-client.ts +34 -58
  342. package/src/internal/cursor/session-token.ts +115 -0
  343. package/src/internal/cursor-agent-template.ts +2 -0
  344. package/src/internal/deploy-client.ts +43 -0
  345. package/src/internal/env-file.ts +84 -0
  346. package/src/internal/framework-file-storage.ts +228 -0
  347. package/src/internal/framework-storage-selection.ts +51 -11
  348. package/src/internal/hosted-delivery-protocol.ts +7 -0
  349. package/src/internal/hosted-delivery.ts +107 -24
  350. package/src/internal/hosted-execution-diag.ts +207 -0
  351. package/src/internal/http-channel.ts +99 -0
  352. package/src/internal/init-project.ts +4 -0
  353. package/src/internal/install-cursor-skills.ts +1 -4
  354. package/src/internal/logs-client.ts +5 -0
  355. package/src/internal/managed-delivery.ts +125 -0
  356. package/src/internal/mcp-endpoint.ts +13 -4
  357. package/src/internal/mcp-host.ts +77 -11
  358. package/src/internal/mcp-oauth-on-demand.ts +352 -0
  359. package/src/internal/mcp-oauth-persist.ts +127 -0
  360. package/src/internal/mcp-oauth.ts +17 -1
  361. package/src/internal/otel/collector.ts +30 -0
  362. package/src/internal/runtime-dispatch-runner.ts +10 -0
  363. package/src/internal/sdk-runner.ts +56 -8
  364. package/src/internal/server.ts +61 -9
  365. package/src/internal/session-engine.ts +723 -60
  366. package/src/internal/sessions-client.ts +17 -8
  367. package/src/internal/steering.ts +17 -0
  368. package/src/internal/storage-coordinator.ts +38 -8
  369. package/src/internal/storage-roles.ts +7 -0
  370. package/src/internal/stream-progress.ts +19 -0
  371. package/src/internal/tool-policy.ts +18 -0
  372. package/src/internal/trajectory.ts +10 -0
  373. package/src/internal/turn-outbox.ts +85 -0
  374. package/src/storage-backends/cursor-hosted.ts +22 -8
  375. package/src/storage.ts +12 -0
  376. package/src/types.ts +70 -9
  377. package/templates/agents-md/README.md +39 -0
  378. package/templates/agents-md/agent/agent.ts +8 -0
  379. package/templates/agents-md/agent/channels/github.ts +10 -0
  380. package/templates/agents-md/agent/channels/queue.ts +28 -0
  381. package/templates/agents-md/agent/channels/slack.ts +9 -0
  382. package/templates/agents-md/agent/instructions.md +39 -0
  383. package/templates/agents-md/agent/lib/collect.ts +439 -0
  384. package/templates/agents-md/agent/lib/config.ts +8 -0
  385. package/templates/agents-md/agent/lib/paths.ts +51 -0
  386. package/templates/agents-md/agent/schedules/weekly.ts +17 -0
  387. package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
  388. package/templates/agents-md/evals/agents.eval.ts +135 -0
  389. package/templates/agents-md/evals/evals.config.ts +5 -0
  390. package/templates/agents-md/init.json +38 -0
  391. package/templates/agents-md/package.json +18 -0
  392. package/templates/agents-md/tsconfig.json +12 -0
  393. package/templates/code-wiki/README.md +34 -0
  394. package/templates/code-wiki/agent/agent.ts +8 -0
  395. package/templates/code-wiki/agent/channels/github.ts +144 -0
  396. package/templates/code-wiki/agent/instructions.md +39 -0
  397. package/templates/code-wiki/agent/lib/repos.ts +5 -0
  398. package/templates/code-wiki/agent/lib/wiki.ts +22 -0
  399. package/templates/code-wiki/agent/tools/apply_wiki.ts +219 -0
  400. package/templates/code-wiki/evals/evals.config.ts +5 -0
  401. package/templates/code-wiki/evals/wiki.eval.ts +132 -0
  402. package/templates/code-wiki/init.json +25 -0
  403. package/templates/code-wiki/package.json +18 -0
  404. package/templates/code-wiki/tsconfig.json +12 -0
  405. package/dist/docs/assets/chunks/@localSearchIndexroot.oqPawjiD.js +0 -1
  406. package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
  407. package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
  408. package/dist/docs/assets/index.md.BoHaMdeZ.js +0 -5
  409. package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
  410. package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
  411. package/dist/docs/design/agsh.md +0 -406
  412. package/dist/internal/deployment-scm-event-stream.d.ts +0 -116
  413. package/dist/internal/deployment-scm-event-stream.d.ts.map +0 -1
  414. package/dist/internal/deployment-scm-event-stream.js +0 -474
  415. package/dist/playground/assets/index-CF7hUDnQ.css +0 -1
  416. package/docs/design/agsh.md +0 -406
  417. package/src/internal/deployment-scm-event-stream.ts +0 -593
  418. /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
  419. /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
  420. /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
  421. /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.5zOAbV86.lean.js} +0 -0
  422. /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
  423. /package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.B84gw9Ii.lean.js} +0 -0
  424. /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
@@ -2,7 +2,7 @@
2
2
  * Default inbound handlers and stream-event sinks for the Slack channel.
3
3
  */
4
4
 
5
- import type { ChannelEventHandlers } from "../../types.js";
5
+ import type { ChannelEventContext, ChannelEventHandlers } from "../../types.js";
6
6
  import {
7
7
  appendChatStream,
8
8
  postMessage,
@@ -166,7 +166,7 @@ export function buildDefaultEvents(
166
166
  status: "",
167
167
  });
168
168
  if (!result.ok) {
169
- getLog().warn("assistant.threads.setStatus not-ok", {
169
+ getLog().warn("slack setStatus not-ok", {
170
170
  error: result.error,
171
171
  channel: channelId,
172
172
  thread_ts: threadTs,
@@ -174,6 +174,91 @@ export function buildDefaultEvents(
174
174
  }
175
175
  };
176
176
 
177
+ /**
178
+ * Deliver assistant text to the bound Slack thread. Used by a stop-reason
179
+ * `message.completed` and by `turn.completed` when the last assistant
180
+ * block was `finishReason: "tool_call"` (answer then `tag_artifact`,
181
+ * etc.) so the playground result still reaches Slack.
182
+ */
183
+ const deliverReplyText = async (args: {
184
+ channel: ChannelEventContext<SlackChannelState>;
185
+ text: string;
186
+ sessionId: string;
187
+ }): Promise<boolean> => {
188
+ const log = getLog();
189
+ const state = args.channel.state;
190
+ if (
191
+ state.channelId === null ||
192
+ state.threadTs === null ||
193
+ args.text === ""
194
+ ) {
195
+ return false;
196
+ }
197
+ if (state.lastPostedText === args.text) {
198
+ // Stream append sets this watermark while chat.stopStream is still
199
+ // pending. Treat a match as "already on Slack", not "already finalized".
200
+ const streamTs = state.streamTs;
201
+ if (streamTs !== null && streamTs !== "") {
202
+ const canStream = streaming && state.streamingUnavailable !== true;
203
+ if (canStream) {
204
+ await strategy.finalize({
205
+ channel: args.channel,
206
+ channelId: state.streamChannelId ?? state.channelId,
207
+ text: args.text,
208
+ sessionId: args.sessionId,
209
+ });
210
+ } else {
211
+ await strategy.cleanupOrphan({ channel: args.channel });
212
+ }
213
+ }
214
+ return true;
215
+ }
216
+
217
+ const canStream = streaming && state.streamingUnavailable !== true;
218
+ if (canStream) {
219
+ const { delivered } = await strategy.finalize({
220
+ channel: args.channel,
221
+ channelId: state.streamChannelId ?? state.channelId,
222
+ text: args.text,
223
+ sessionId: args.sessionId,
224
+ });
225
+ if (delivered) {
226
+ return true;
227
+ }
228
+ }
229
+
230
+ try {
231
+ const posted = await postMessage({
232
+ botToken,
233
+ channel: state.channelId,
234
+ text: args.text,
235
+ threadTs: state.threadTs,
236
+ });
237
+ state.lastPostedText = args.text;
238
+ state.lastBotMessageTs = posted.ts;
239
+ log.info("reply delivered via postMessage", {
240
+ channel: state.channelId,
241
+ thread_ts: state.threadTs,
242
+ message_ts: posted.ts,
243
+ session: args.sessionId,
244
+ chars: args.text.length,
245
+ });
246
+ return true;
247
+ } catch (error) {
248
+ log.error(
249
+ `postMessage failed: ${
250
+ error instanceof Error ? error.message : String(error)
251
+ }`,
252
+ {
253
+ channel: state.channelId,
254
+ thread_ts: state.threadTs,
255
+ session: args.sessionId,
256
+ }
257
+ );
258
+ return false;
259
+ }
260
+ };
261
+
177
262
  return {
178
263
  async "turn.started"(event, channel) {
179
264
  const log = getLog();
@@ -205,42 +290,22 @@ export function buildDefaultEvents(
205
290
  status: "Working…",
206
291
  loadingMessages,
207
292
  });
208
-
209
- // Retry streaming each turn unless a prior call proved the feature
210
- // unsupported for this workspace/app. Thinking stays on setStatus
211
- // (Cursor-account proxy pins agent username/icon on that method).
212
- if (!streaming || state.streamingUnavailable === true) {
213
- return;
214
- }
215
-
216
- await strategy.start({
217
- channel,
218
- channelId: state.channelId,
219
- threadTs: state.threadTs,
220
- sessionId: event.sessionId,
221
- });
222
293
  },
223
294
 
224
295
  async "message.appended"(event, channel) {
225
296
  if (!streaming || channel.state.streamingUnavailable === true) {
226
297
  return;
227
298
  }
228
- const streamTs = channel.state.streamTs;
229
299
  const channelId =
230
300
  channel.state.streamChannelId ?? channel.state.channelId;
231
- if (
232
- streamTs === null ||
233
- streamTs === "" ||
234
- channelId === null ||
235
- channelId === ""
236
- ) {
301
+ const threadTs = channel.state.threadTs;
302
+ if (channelId === null || channelId === "" || threadTs === null) {
237
303
  return;
238
304
  }
239
305
 
240
306
  await strategy.append({
241
307
  channel,
242
308
  channelId,
243
- streamTs,
244
309
  text: event.data.text,
245
310
  sessionId: event.sessionId,
246
311
  });
@@ -298,24 +363,23 @@ export function buildDefaultEvents(
298
363
  strategy.inlineToolSteps &&
299
364
  thinkingSteps &&
300
365
  streaming &&
301
- channel.state.streamingUnavailable !== true &&
302
- channel.state.streamTs !== null &&
303
- channel.state.streamTs !== ""
366
+ channel.state.streamingUnavailable !== true
304
367
  ) {
305
368
  const channelId =
306
369
  channel.state.streamChannelId ?? channel.state.channelId;
307
- if (channelId !== null && channelId !== "") {
370
+ const threadTs = channel.state.threadTs;
371
+ if (channelId !== null && channelId !== "" && threadTs !== null) {
308
372
  const chunks = buildTaskChunksForCalls(
309
373
  event.data.calls,
310
374
  "in_progress"
311
375
  );
312
- const result = await appendChatStream({
313
- botToken,
314
- channel: channelId,
315
- ts: channel.state.streamTs,
376
+ const streamed = await strategy.appendChunks({
377
+ channel,
378
+ channelId,
316
379
  chunks,
380
+ sessionId: event.sessionId,
317
381
  });
318
- if (result.ok) {
382
+ if (streamed) {
319
383
  if (
320
384
  channel.state.channelId !== null &&
321
385
  channel.state.threadTs !== null
@@ -372,7 +436,6 @@ export function buildDefaultEvents(
372
436
  },
373
437
 
374
438
  async "message.completed"(event, channel) {
375
- const log = getLog();
376
439
  if (event.data.finishReason === "tool_call") {
377
440
  channel.state.pendingToolCallMessage =
378
441
  firstNonEmptyLine(event.data.text) ?? null;
@@ -388,67 +451,16 @@ export function buildDefaultEvents(
388
451
  // Empty final text: still close any open stream / clear the skeleton
389
452
  // and clear typing.
390
453
  if (event.data.text === "") {
391
- if (state.streamTs !== null && state.streamTs !== "") {
392
- await strategy.finalizeEmpty({
393
- channel,
394
- channelId: state.streamChannelId ?? state.channelId,
395
- streamTs: state.streamTs,
396
- });
397
- channel.state.streamTs = null;
398
- }
454
+ await strategy.finalizeEmpty({ channel });
399
455
  await clearWorkingStatus(state.channelId, state.threadTs);
400
456
  return;
401
457
  }
402
458
 
403
- const canStream =
404
- streaming &&
405
- state.streamingUnavailable !== true &&
406
- state.streamTs !== null &&
407
- state.streamTs !== "";
408
-
409
- if (canStream && state.streamTs !== null) {
410
- const { delivered } = await strategy.finalize({
411
- channel,
412
- channelId: state.streamChannelId ?? state.channelId,
413
- streamTs: state.streamTs,
414
- text: event.data.text,
415
- sessionId: event.sessionId,
416
- });
417
- if (delivered) {
418
- await clearWorkingStatus(state.channelId, state.threadTs);
419
- return;
420
- }
421
- }
422
-
423
- try {
424
- const posted = await postMessage({
425
- botToken,
426
- channel: state.channelId,
427
- text: event.data.text,
428
- threadTs: state.threadTs,
429
- });
430
- channel.state.lastPostedText = event.data.text;
431
- channel.state.lastBotMessageTs = posted.ts;
432
- log.info("reply delivered via postMessage", {
433
- channel: state.channelId,
434
- thread_ts: state.threadTs,
435
- message_ts: posted.ts,
436
- session: event.sessionId,
437
- chars: event.data.text.length,
438
- });
439
- } catch (error) {
440
- log.error(
441
- `postMessage failed: ${
442
- error instanceof Error ? error.message : String(error)
443
- }`,
444
- {
445
- channel: state.channelId,
446
- thread_ts: state.threadTs,
447
- session: event.sessionId,
448
- }
449
- );
450
- }
451
-
459
+ await deliverReplyText({
460
+ channel,
461
+ text: event.data.text,
462
+ sessionId: event.sessionId,
463
+ });
452
464
  await clearWorkingStatus(state.channelId, state.threadTs);
453
465
  },
454
466
 
@@ -461,6 +473,24 @@ export function buildDefaultEvents(
461
473
  thread_ts: channel.state.threadTs,
462
474
  });
463
475
 
476
+ // Mid-turn `tool_call` text is held as status, not posted. If the
477
+ // turn ends without a later `finishReason: "stop"` block, the
478
+ // playground still has `result` (last assistant text) and Slack
479
+ // would otherwise stay silent.
480
+ const result = event.data.result;
481
+ const unpublished =
482
+ typeof result === "string" &&
483
+ result !== "" &&
484
+ result !== channel.state.lastPostedText;
485
+ if (unpublished) {
486
+ await deliverReplyText({
487
+ channel,
488
+ text: result,
489
+ sessionId: event.sessionId,
490
+ });
491
+ }
492
+ // Always close leftovers. deliverReplyText may fall through to
493
+ // postMessage when streaming is unavailable and leave streamTs open.
464
494
  await strategy.cleanupOrphan({ channel });
465
495
 
466
496
  // Always drop the assistant chip. message.completed already clears
@@ -509,11 +539,10 @@ export function buildDefaultEvents(
509
539
  const errorText = formatSlackTurnFailureMessage(event.data.message);
510
540
 
511
541
  let delivered = false;
512
- if (state.streamTs !== null && state.streamTs !== "") {
542
+ if (streaming && state.streamingUnavailable !== true) {
513
543
  ({ delivered } = await strategy.fail({
514
544
  channel,
515
545
  channelId: state.streamChannelId ?? state.channelId,
516
- streamTs: state.streamTs,
517
546
  errorText,
518
547
  sessionId: event.sessionId,
519
548
  }));
@@ -9,6 +9,7 @@ import {
9
9
  normalizeIdentity,
10
10
  } from "../../internal/continuation-identity.js";
11
11
  import { routeLocalIngressContinuation } from "../../internal/local-ingress.js";
12
+ import { steeringEnabled } from "../../internal/steering.js";
12
13
  import type {
13
14
  ArtifactsApi,
14
15
  HostContext,
@@ -16,7 +17,11 @@ import type {
16
17
  SendMessageFn,
17
18
  } from "../../types.js";
18
19
  import { buildSlackBinding, slackContinuationKey } from "./api.js";
19
- import { firstLineTitle, maybeSetThreadTitle } from "./assistant.js";
20
+ import {
21
+ firstLineTitle,
22
+ maybeSetSuggestedPrompts,
23
+ maybeSetThreadTitle,
24
+ } from "./assistant.js";
20
25
  import {
21
26
  appendSlackAttachmentAnnotations,
22
27
  prepareSlackAttachments,
@@ -33,6 +38,7 @@ import { isExternalSlackSender } from "./external-policy.js";
33
38
  import {
34
39
  formatSlackContextBlock,
35
40
  parseAppMentionEvent,
41
+ parseAssistantThreadStarted,
36
42
  parseChannelMessageEvent,
37
43
  parseDirectMessageEvent,
38
44
  parseReactionAddedEvent,
@@ -51,6 +57,7 @@ import type {
51
57
  SlackDispatchDecision,
52
58
  SlackMessage,
53
59
  SlackMessageHandler,
60
+ SlackSuggestedPrompt,
54
61
  } from "./types.js";
55
62
 
56
63
  const FOLLOWUP_TYPING = "Saw your follow-up…";
@@ -167,6 +174,12 @@ export interface SlackInboundDispatchDeps extends SlackContinuationProbes {
167
174
  * `false` to admit them (or when an upstream gate already refused them).
168
175
  */
169
176
  blockExternals?: boolean;
177
+ /**
178
+ * Suggested prompts written on `assistant_thread_started` so the
179
+ * assistant pane is not blank before the first user message.
180
+ */
181
+ suggestedPrompts?: SlackSuggestedPrompt[];
182
+ suggestedPromptsTitle?: string;
170
183
  }
171
184
 
172
185
  function triggeringMergeMessage(
@@ -529,27 +542,24 @@ export async function dispatchInboundMessage(args: {
529
542
  continuation,
530
543
  event_id: args.eventId,
531
544
  });
532
- // Queue it for mid-turn injection too. The carrier drains this at the
533
- // running turn's next tool boundary; whatever it does not reach in time
534
- // still drains into the boundary turn, deduped by sourceTs.
535
- try {
536
- await args.host.slackNudges?.append({
537
- continuationKey: continuation,
538
- sourceTs: message.ts,
539
- text: media.userText,
540
- ...(message.author?.userName === undefined
541
- ? {}
542
- : { author: message.author.userName }),
543
- });
544
- } catch (nudgeError) {
545
- log.warn("nudge append failed", {
546
- error:
547
- nudgeError instanceof Error
548
- ? nudgeError.message
549
- : String(nudgeError),
550
- continuation,
551
- event_id: args.eventId,
552
- });
545
+ if (!steeringEnabled()) {
546
+ try {
547
+ await args.host.slackNudges?.append({
548
+ continuationKey: continuation,
549
+ sourceTs: message.ts,
550
+ text: media.userText,
551
+ author: message.author?.userName,
552
+ });
553
+ } catch (nudgeError) {
554
+ log.warn("nudge append failed", {
555
+ error:
556
+ nudgeError instanceof Error
557
+ ? nudgeError.message
558
+ : String(nudgeError),
559
+ continuation,
560
+ event_id: args.eventId,
561
+ });
562
+ }
553
563
  }
554
564
  try {
555
565
  if (args.followUpStatus !== false) {
@@ -750,6 +760,30 @@ export function dispatchInboundFromEventBody(
750
760
  return true;
751
761
  }
752
762
 
763
+ const assistantThread = parseAssistantThreadStarted(body);
764
+ if (assistantThread !== null) {
765
+ const prompts = deps.suggestedPrompts ?? [];
766
+ log.info("assistant thread started", {
767
+ channel: assistantThread.channelId,
768
+ thread_ts: assistantThread.threadTs,
769
+ user: assistantThread.userId,
770
+ event_id: eventId,
771
+ });
772
+ if (prompts.length > 0) {
773
+ deps.waitUntil(
774
+ maybeSetSuggestedPrompts({
775
+ botToken: deps.credentials?.botToken,
776
+ channelId: assistantThread.channelId,
777
+ threadTs: assistantThread.threadTs,
778
+ prompts,
779
+ title: deps.suggestedPromptsTitle,
780
+ log,
781
+ })
782
+ );
783
+ }
784
+ return true;
785
+ }
786
+
753
787
  if (deps.channelWatch !== undefined) {
754
788
  // Parse keeps bot-authored posts; the watcher enforces the per-channel
755
789
  // policy (includeBotPosts, own-post loop safety) with skip logging.
@@ -121,6 +121,49 @@ export function parseAppMentionEvent(
121
121
  return delegation === undefined ? message : { ...message, delegation };
122
122
  }
123
123
 
124
+ export interface SlackAssistantThreadStarted {
125
+ channelId: string;
126
+ threadTs: string;
127
+ userId?: string;
128
+ teamId?: string;
129
+ }
130
+
131
+ /** Slack fires this when a user opens the assistant pane. No model turn. */
132
+ export function parseAssistantThreadStarted(
133
+ body: unknown
134
+ ): SlackAssistantThreadStarted | null {
135
+ const root = asRecord(body);
136
+ if (root === null || root.type !== "event_callback") {
137
+ return null;
138
+ }
139
+ const event = asRecord(root.event);
140
+ if (event === null || event.type !== "assistant_thread_started") {
141
+ return null;
142
+ }
143
+ const thread = asRecord(event.assistant_thread);
144
+ if (thread === null) {
145
+ return null;
146
+ }
147
+ const channelId = asString(thread.channel_id);
148
+ const threadTs = asString(thread.thread_ts);
149
+ if (
150
+ channelId === undefined ||
151
+ channelId === "" ||
152
+ threadTs === undefined ||
153
+ threadTs === ""
154
+ ) {
155
+ return null;
156
+ }
157
+ const userId = asString(thread.user_id);
158
+ const teamId = asString(root.team_id) ?? asString(event.team_id);
159
+ return {
160
+ channelId,
161
+ threadTs,
162
+ userId: userId === undefined || userId === "" ? undefined : userId,
163
+ teamId: teamId === undefined || teamId === "" ? undefined : teamId,
164
+ };
165
+ }
166
+
124
167
  /**
125
168
  * Parse DM / IM messages. More generous than a strict channel_type check:
126
169
  * accepts `channel_type === "im"` or channel ids starting with `D`, and
@@ -2,13 +2,14 @@
2
2
  * Scaffold a Slack channel into an agent-serve project.
3
3
  *
4
4
  * `initSlackChannel` is the create-safe writer: `agent/channels/slack.ts`
5
- * only. DIY manifests for paste at api.slack.com live in
5
+ * only. DIY manifests + Slack CLI `.slack/` live in
6
6
  * {@link initSlackManual} so `slack create` cannot reach them.
7
7
  */
8
8
 
9
9
  import { mkdir, writeFile } from "node:fs/promises";
10
10
  import { basename, join, resolve } from "node:path";
11
11
  import { PACKAGE_NAME } from "../../internal/distribution.js";
12
+ import { writeSlackCliProject } from "./cli-project.js";
12
13
  import { envPrefixFromName, slackEnvKeys } from "./credentials.js";
13
14
  import {
14
15
  buildSlackManifestPair,
@@ -131,7 +132,8 @@ export async function initSlackChannel(
131
132
 
132
133
  /**
133
134
  * `slack init --manual`: channel file plus DIY manifests
134
- * (`managedByCursor: false`), env.example, and setup-status.json.
135
+ * (`managedByCursor: false`), Slack CLI `.slack/` project, env.example,
136
+ * and setup-status.json.
135
137
  */
136
138
  export async function initSlackManual(
137
139
  options: InitSlackManualOptions
@@ -151,9 +153,6 @@ export async function initSlackManual(
151
153
  description: options.description,
152
154
  channelPosts: options.channelPosts,
153
155
  });
154
- for (const file of slackManifestFileEntries(pair)) {
155
- await write(`.agent-serve/slack/${file.name}`, file.contents);
156
- }
157
156
  await write(
158
157
  ".agent-serve/slack/env.example",
159
158
  `# Copy to .env.local (or export in your shell). Use the *dev* Slack app
@@ -176,6 +175,12 @@ ${target.envKeys.app}=xapp-...
176
175
  2
177
176
  )}\n`
178
177
  );
178
+ files.push(
179
+ ...(await writeSlackCliProject(
180
+ target.rootDir,
181
+ slackManifestFileEntries(pair)
182
+ ))
183
+ );
179
184
 
180
185
  return {
181
186
  rootDir: target.rootDir,
@@ -15,10 +15,15 @@ import type {
15
15
  ChannelSession,
16
16
  HostContext,
17
17
  PendingApproval,
18
+ PendingAuth,
18
19
  SendMessageFn,
19
20
  } from "../../types.js";
20
21
  import { updateMessage } from "./api.js";
21
- import { decisionFromActionId, parseApprovalActionValue } from "./approvals.js";
22
+ import {
23
+ decisionFromActionId,
24
+ decisionFromAuthActionId,
25
+ parseApprovalActionValue,
26
+ } from "./approvals.js";
22
27
  import { buildSlackInteractiveApprovalAuth } from "./auth.js";
23
28
  import { dispatchInboundMessage } from "./dispatch.js";
24
29
  import { isExternalSlackSender } from "./external-policy.js";
@@ -41,6 +46,12 @@ export interface SlackInteractiveDispatchDeps {
41
46
  decision: ApprovalDecision,
42
47
  auth: AuthContext | null
43
48
  ) => Promise<PendingApproval>;
49
+ resolveAuth: (
50
+ sessionId: string,
51
+ callId: string,
52
+ decision: ApprovalDecision,
53
+ auth: AuthContext | null
54
+ ) => Promise<PendingAuth>;
44
55
  waitUntil: (promise: Promise<unknown>) => void;
45
56
  log?: SlackLog;
46
57
  /** Defaults to true. */
@@ -61,11 +72,17 @@ export async function dispatchInteractiveFromPayload(
61
72
  return false;
62
73
  }
63
74
 
64
- const decision = decisionFromActionId(parsed.actionId);
75
+ const approvalDecision = decisionFromActionId(parsed.actionId);
76
+ const authDecision = decisionFromAuthActionId(parsed.actionId);
65
77
  const value = parseApprovalActionValue(parsed.value);
66
- if (decision === null || value === null) {
78
+ if (value === null || (approvalDecision === null && authDecision === null)) {
67
79
  return false;
68
80
  }
81
+ const decision = approvalDecision ?? authDecision;
82
+ if (decision === null) {
83
+ return false;
84
+ }
85
+ const kind = approvalDecision !== null ? "approval" : "auth";
69
86
 
70
87
  log.info("interactive approval", {
71
88
  decision,
@@ -153,12 +170,21 @@ export async function dispatchInteractiveFromPayload(
153
170
  });
154
171
 
155
172
  try {
156
- await deps.resolveApproval(
157
- value.sessionId,
158
- value.callId,
159
- decision,
160
- clickingAuth
161
- );
173
+ if (kind === "auth") {
174
+ await deps.resolveAuth(
175
+ value.sessionId,
176
+ value.callId,
177
+ decision,
178
+ clickingAuth
179
+ );
180
+ } else {
181
+ await deps.resolveApproval(
182
+ value.sessionId,
183
+ value.callId,
184
+ decision,
185
+ clickingAuth
186
+ );
187
+ }
162
188
  } catch (error) {
163
189
  log.warn("interactive approval resolve failed", {
164
190
  session: value.sessionId,