@cursor/july 0.1.96 → 0.1.99

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 (381) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +3 -2
  3. package/dist/bin/agent-serve.js +13 -3
  4. package/dist/channels/github/github-channel.d.ts.map +1 -1
  5. package/dist/channels/github/github-channel.js +16 -0
  6. package/dist/channels/origin/api.d.ts +15 -4
  7. package/dist/channels/origin/api.d.ts.map +1 -1
  8. package/dist/channels/origin/api.js +19 -3
  9. package/dist/channels/origin/binding.d.ts +11 -0
  10. package/dist/channels/origin/binding.d.ts.map +1 -1
  11. package/dist/channels/origin/binding.js +41 -25
  12. package/dist/channels/origin/index.d.ts +1 -0
  13. package/dist/channels/origin/index.d.ts.map +1 -1
  14. package/dist/channels/origin/index.js +1 -0
  15. package/dist/channels/origin/origin-channel.d.ts +2 -0
  16. package/dist/channels/origin/origin-channel.d.ts.map +1 -1
  17. package/dist/channels/origin/origin-channel.js +40 -4
  18. package/dist/channels/origin/reactions.d.ts +56 -0
  19. package/dist/channels/origin/reactions.d.ts.map +1 -0
  20. package/dist/channels/origin/reactions.js +67 -0
  21. package/dist/channels/origin/types.d.ts +11 -0
  22. package/dist/channels/origin/types.d.ts.map +1 -1
  23. package/dist/channels/slack/approvals.d.ts +16 -0
  24. package/dist/channels/slack/approvals.d.ts.map +1 -1
  25. package/dist/channels/slack/approvals.js +86 -0
  26. package/dist/channels/slack/cli-project.d.ts +19 -0
  27. package/dist/channels/slack/cli-project.d.ts.map +1 -0
  28. package/dist/channels/slack/cli-project.js +234 -0
  29. package/dist/channels/slack/defaults.d.ts.map +1 -1
  30. package/dist/channels/slack/defaults.js +142 -63
  31. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  32. package/dist/channels/slack/dispatch.js +1 -1
  33. package/dist/channels/slack/init.d.ts +3 -2
  34. package/dist/channels/slack/init.d.ts.map +1 -1
  35. package/dist/channels/slack/init.js +5 -5
  36. package/dist/channels/slack/interactive.d.ts +2 -1
  37. package/dist/channels/slack/interactive.d.ts.map +1 -1
  38. package/dist/channels/slack/interactive.js +15 -4
  39. package/dist/channels/slack/live-delivery.d.ts +1 -1
  40. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  41. package/dist/channels/slack/live-delivery.js +4 -2
  42. package/dist/channels/slack/manifest.d.ts +1 -1
  43. package/dist/channels/slack/manifest.js +1 -1
  44. package/dist/channels/slack/progress-delivery.d.ts +28 -0
  45. package/dist/channels/slack/progress-delivery.d.ts.map +1 -0
  46. package/dist/channels/slack/progress-delivery.js +115 -0
  47. package/dist/channels/slack/setup.d.ts +1 -1
  48. package/dist/channels/slack/setup.d.ts.map +1 -1
  49. package/dist/channels/slack/setup.js +10 -6
  50. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  51. package/dist/channels/slack/slack-channel.js +1 -0
  52. package/dist/channels/slack/tool-approval-events.d.ts.map +1 -1
  53. package/dist/channels/slack/tool-approval-events.js +91 -1
  54. package/dist/channels/slack/types.d.ts +9 -1
  55. package/dist/channels/slack/types.d.ts.map +1 -1
  56. package/dist/docs/404.html +2 -2
  57. package/dist/docs/ab.html +4 -4
  58. package/dist/docs/assets/{app.jXleCmOc.js → app.BplEAZ3S.js} +1 -1
  59. package/dist/docs/assets/chunks/@localSearchIndexroot.DpuI4i7Z.js +1 -0
  60. package/dist/docs/assets/chunks/{VPLocalSearchBox.8LhyglIT.js → VPLocalSearchBox.CHXyv4wP.js} +1 -1
  61. package/dist/docs/assets/chunks/{theme.9ged-pr2.js → theme.BTcsZmjQ.js} +2 -2
  62. package/dist/docs/assets/{deployment.md.D9msOFOW.js → deployment.md.MFPKqsqI.js} +2 -2
  63. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.js → guides_mcp-oauth.md.CN-6YmTJ.js} +4 -4
  64. package/dist/docs/assets/{guides_mcp-oauth.md.DPYmBCbV.lean.js → guides_mcp-oauth.md.CN-6YmTJ.lean.js} +1 -1
  65. package/dist/docs/assets/guides_slack.md.VDXQV3ja.js +22 -0
  66. package/dist/docs/assets/guides_slack.md.VDXQV3ja.lean.js +1 -0
  67. package/dist/docs/assets/index.md.CVeRUOeZ.js +5 -0
  68. package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.js → reference_agent-config.md.BHeYMgme.js} +1 -1
  69. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.js → reference_cli.md.DfoeyvL0.js} +9 -6
  70. package/dist/docs/assets/{reference_cli.md.CCnG-nJx.lean.js → reference_cli.md.DfoeyvL0.lean.js} +1 -1
  71. package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.js → reference_connections.md.DxldvyIB.js} +4 -3
  72. package/dist/docs/assets/{reference_http-api.md.D89k1mdm.js → reference_http-api.md.BEJx9XVj.js} +2 -2
  73. package/dist/docs/assets/reference_sessions.md.NxFP_CAC.js +1 -0
  74. package/dist/docs/assets/{reference_tools.md.BHeXn2id.js → reference_tools.md.CvAHsdSp.js} +10 -2
  75. package/dist/docs/assets/{reference_tools.md.BHeXn2id.lean.js → reference_tools.md.CvAHsdSp.lean.js} +1 -1
  76. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.js +2 -0
  77. package/dist/docs/assets/templates_agents-md.md.CXSMZljE.lean.js +1 -0
  78. package/dist/docs/assets/troubleshooting.md.DCiPBhYs.js +1 -0
  79. package/dist/docs/building-with-agents.html +4 -4
  80. package/dist/docs/concepts.html +4 -4
  81. package/dist/docs/deployment.html +7 -7
  82. package/dist/docs/deployment.md +5 -4
  83. package/dist/docs/design/runtime-abstraction.md +1757 -0
  84. package/dist/docs/evals.html +4 -4
  85. package/dist/docs/guides/agent-to-agent.html +4 -4
  86. package/dist/docs/guides/cloud-runtime.html +4 -4
  87. package/dist/docs/guides/convert-automation.html +4 -4
  88. package/dist/docs/guides/github.html +4 -4
  89. package/dist/docs/guides/human-in-the-loop.html +4 -4
  90. package/dist/docs/guides/mcp-oauth.html +8 -8
  91. package/dist/docs/guides/mcp-oauth.md +26 -8
  92. package/dist/docs/guides/opentelemetry.html +4 -4
  93. package/dist/docs/guides/slack.html +17 -33
  94. package/dist/docs/guides/slack.md +92 -201
  95. package/dist/docs/guides/webhooks.html +4 -4
  96. package/dist/docs/hashmap.json +1 -1
  97. package/dist/docs/hillclimbing.html +4 -4
  98. package/dist/docs/index.html +6 -6
  99. package/dist/docs/index.md +5 -3
  100. package/dist/docs/llms-full.txt +2065 -637
  101. package/dist/docs/llms.txt +3 -2
  102. package/dist/docs/quickstart.html +4 -4
  103. package/dist/docs/reference/agent-config.html +6 -6
  104. package/dist/docs/reference/agent-config.md +2 -2
  105. package/dist/docs/reference/artifacts.html +4 -4
  106. package/dist/docs/reference/channels.html +4 -4
  107. package/dist/docs/reference/cli.html +13 -10
  108. package/dist/docs/reference/cli.md +32 -16
  109. package/dist/docs/reference/connections.html +9 -8
  110. package/dist/docs/reference/connections.md +6 -3
  111. package/dist/docs/reference/hooks.html +4 -4
  112. package/dist/docs/reference/http-api.html +7 -7
  113. package/dist/docs/reference/http-api.md +3 -1
  114. package/dist/docs/reference/instructions.html +4 -4
  115. package/dist/docs/reference/playground.html +4 -4
  116. package/dist/docs/reference/project-layout.html +4 -4
  117. package/dist/docs/reference/prompt.html +4 -4
  118. package/dist/docs/reference/schedules.html +4 -4
  119. package/dist/docs/reference/sessions.html +5 -5
  120. package/dist/docs/reference/sessions.md +4 -2
  121. package/dist/docs/reference/skills.html +4 -4
  122. package/dist/docs/reference/subagents.html +4 -4
  123. package/dist/docs/reference/tools.html +15 -7
  124. package/dist/docs/reference/tools.md +34 -2
  125. package/dist/docs/scaffolding-agents.html +4 -4
  126. package/dist/docs/storage.html +4 -4
  127. package/dist/docs/templates/agentic-owners.html +4 -4
  128. package/dist/docs/templates/agents-md.html +28 -0
  129. package/dist/docs/templates/agents-md.md +105 -0
  130. package/dist/docs/templates/code-wiki.html +5 -5
  131. package/dist/docs/templates/demo.html +4 -4
  132. package/dist/docs/templates/pr-autofixer.html +4 -4
  133. package/dist/docs/templates/security-help.html +4 -4
  134. package/dist/docs/templates/security-reviewer.html +5 -5
  135. package/dist/docs/templates/triage.html +4 -4
  136. package/dist/docs/troubleshooting.html +5 -5
  137. package/dist/docs/troubleshooting.md +2 -2
  138. package/dist/evals/run-facts.d.ts.map +1 -1
  139. package/dist/evals/run-facts.js +27 -0
  140. package/dist/files-backends/cursor-hosted.d.ts +3 -2
  141. package/dist/files-backends/cursor-hosted.d.ts.map +1 -1
  142. package/dist/files-backends/cursor-hosted.js +3 -2
  143. package/dist/index.d.ts +1 -0
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js +1 -0
  146. package/dist/internal/advertise-tools.d.ts.map +1 -1
  147. package/dist/internal/advertise-tools.js +15 -9
  148. package/dist/internal/approval-gate.d.ts +12 -13
  149. package/dist/internal/approval-gate.d.ts.map +1 -1
  150. package/dist/internal/approval-gate.js +16 -21
  151. package/dist/internal/as-of.d.ts +19 -0
  152. package/dist/internal/as-of.d.ts.map +1 -0
  153. package/dist/internal/as-of.js +82 -0
  154. package/dist/internal/chat-client.js +10 -0
  155. package/dist/internal/cli-deploy.d.ts +6 -0
  156. package/dist/internal/cli-deploy.d.ts.map +1 -1
  157. package/dist/internal/cli-deploy.js +149 -21
  158. package/dist/internal/cli-mcp-oauth.js +8 -18
  159. package/dist/internal/cli-slack-manual.d.ts +24 -2
  160. package/dist/internal/cli-slack-manual.d.ts.map +1 -1
  161. package/dist/internal/cli-slack-manual.js +251 -20
  162. package/dist/internal/cli-slack.d.ts +9 -2
  163. package/dist/internal/cli-slack.d.ts.map +1 -1
  164. package/dist/internal/cli-slack.js +29 -82
  165. package/dist/internal/cursor/account-mcp.d.ts +1 -0
  166. package/dist/internal/cursor/account-mcp.d.ts.map +1 -1
  167. package/dist/internal/cursor/account-mcp.js +17 -0
  168. package/dist/internal/cursor-agent-template.d.ts +1 -1
  169. package/dist/internal/cursor-agent-template.d.ts.map +1 -1
  170. package/dist/internal/cursor-agent-template.js +1 -0
  171. package/dist/internal/cursor-event-relay.d.ts.map +1 -1
  172. package/dist/internal/cursor-event-relay.js +5 -6
  173. package/dist/internal/deploy-client.d.ts +17 -0
  174. package/dist/internal/deploy-client.d.ts.map +1 -1
  175. package/dist/internal/deploy-client.js +31 -10
  176. package/dist/internal/env-file.d.ts +19 -0
  177. package/dist/internal/env-file.d.ts.map +1 -0
  178. package/dist/internal/env-file.js +90 -0
  179. package/dist/internal/framework-file-storage.d.ts +11 -17
  180. package/dist/internal/framework-file-storage.d.ts.map +1 -1
  181. package/dist/internal/framework-file-storage.js +17 -40
  182. package/dist/internal/framework-storage-selection.d.ts +13 -11
  183. package/dist/internal/framework-storage-selection.d.ts.map +1 -1
  184. package/dist/internal/framework-storage-selection.js +37 -26
  185. package/dist/internal/hosted-admission-adapter.d.ts +28 -0
  186. package/dist/internal/hosted-admission-adapter.d.ts.map +1 -0
  187. package/dist/internal/hosted-admission-adapter.js +7 -0
  188. package/dist/internal/hosted-delivery-protocol.d.ts +13 -1
  189. package/dist/internal/hosted-delivery-protocol.d.ts.map +1 -1
  190. package/dist/internal/hosted-delivery-protocol.js +8 -1
  191. package/dist/internal/hosted-delivery.d.ts +21 -1
  192. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  193. package/dist/internal/hosted-delivery.js +101 -34
  194. package/dist/internal/hosted-execution-diag.d.ts +59 -0
  195. package/dist/internal/hosted-execution-diag.d.ts.map +1 -0
  196. package/dist/internal/hosted-execution-diag.js +187 -0
  197. package/dist/internal/http-channel.d.ts.map +1 -1
  198. package/dist/internal/http-channel.js +85 -2
  199. package/dist/internal/init-project.d.ts.map +1 -1
  200. package/dist/internal/init-project.js +2 -0
  201. package/dist/internal/logs-client.d.ts +5 -0
  202. package/dist/internal/logs-client.d.ts.map +1 -1
  203. package/dist/internal/logs-client.js +5 -0
  204. package/dist/internal/mcp-endpoint.js +2 -3
  205. package/dist/internal/mcp-host.d.ts +10 -0
  206. package/dist/internal/mcp-host.d.ts.map +1 -1
  207. package/dist/internal/mcp-host.js +57 -8
  208. package/dist/internal/mcp-oauth-on-demand.d.ts +68 -0
  209. package/dist/internal/mcp-oauth-on-demand.d.ts.map +1 -0
  210. package/dist/internal/mcp-oauth-on-demand.js +287 -0
  211. package/dist/internal/mcp-oauth-persist.d.ts +42 -0
  212. package/dist/internal/mcp-oauth-persist.d.ts.map +1 -0
  213. package/dist/internal/mcp-oauth-persist.js +92 -0
  214. package/dist/internal/mcp-oauth.d.ts +1 -0
  215. package/dist/internal/mcp-oauth.d.ts.map +1 -1
  216. package/dist/internal/mcp-oauth.js +10 -2
  217. package/dist/internal/null-kv-storage.d.ts +48 -0
  218. package/dist/internal/null-kv-storage.d.ts.map +1 -0
  219. package/dist/internal/null-kv-storage.js +58 -0
  220. package/dist/internal/otel/collector.d.ts.map +1 -1
  221. package/dist/internal/otel/collector.js +22 -9
  222. package/dist/internal/server.d.ts +6 -0
  223. package/dist/internal/server.d.ts.map +1 -1
  224. package/dist/internal/server.js +123 -33
  225. package/dist/internal/session-engine.d.ts +88 -3
  226. package/dist/internal/session-engine.d.ts.map +1 -1
  227. package/dist/internal/session-engine.js +538 -46
  228. package/dist/internal/session-run-log.d.ts +120 -0
  229. package/dist/internal/session-run-log.d.ts.map +1 -0
  230. package/dist/internal/session-run-log.js +359 -0
  231. package/dist/internal/sessions-client.d.ts +9 -7
  232. package/dist/internal/sessions-client.d.ts.map +1 -1
  233. package/dist/internal/sessions-client.js +3 -1
  234. package/dist/internal/storage-coordinator.d.ts +13 -0
  235. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  236. package/dist/internal/storage-coordinator.js +37 -6
  237. package/dist/internal/storage-roles.d.ts +5 -0
  238. package/dist/internal/storage-roles.d.ts.map +1 -1
  239. package/dist/internal/stream-progress.d.ts.map +1 -1
  240. package/dist/internal/stream-progress.js +10 -0
  241. package/dist/internal/tool-policy.d.ts +29 -9
  242. package/dist/internal/tool-policy.d.ts.map +1 -1
  243. package/dist/internal/tool-policy.js +24 -0
  244. package/dist/internal/trajectory.d.ts.map +1 -1
  245. package/dist/internal/trajectory.js +10 -0
  246. package/dist/internal/turn-outbox.d.ts +24 -0
  247. package/dist/internal/turn-outbox.d.ts.map +1 -0
  248. package/dist/internal/turn-outbox.js +80 -0
  249. package/dist/playground/assets/index-D7rGZNjy.css +1 -0
  250. package/dist/playground/assets/index-jzNbJENa.js +69 -0
  251. package/dist/playground/index.html +2 -2
  252. package/dist/storage-backends/cursor-hosted.d.ts +1 -1
  253. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  254. package/dist/storage-backends/cursor-hosted.js +12 -0
  255. package/dist/storage-protocol.d.ts +8 -0
  256. package/dist/storage-protocol.d.ts.map +1 -1
  257. package/dist/storage-protocol.js +8 -0
  258. package/dist/storage.d.ts +8 -0
  259. package/dist/storage.d.ts.map +1 -1
  260. package/dist/tools.d.ts +12 -2
  261. package/dist/tools.d.ts.map +1 -1
  262. package/dist/types.d.ts +88 -7
  263. package/dist/types.d.ts.map +1 -1
  264. package/docs/README.md +5 -3
  265. package/docs/deployment.md +5 -4
  266. package/docs/design/runtime-abstraction.md +1757 -0
  267. package/docs/guides/mcp-oauth.md +26 -8
  268. package/docs/guides/slack.md +93 -202
  269. package/docs/reference/agent-config.md +2 -2
  270. package/docs/reference/cli.md +32 -16
  271. package/docs/reference/connections.md +6 -3
  272. package/docs/reference/http-api.md +3 -1
  273. package/docs/reference/sessions.md +4 -2
  274. package/docs/reference/tools.md +34 -2
  275. package/docs/templates/agents-md.md +110 -0
  276. package/docs/troubleshooting.md +2 -2
  277. package/package.json +1 -1
  278. package/skills/create-agent/SKILL.md +2 -1
  279. package/skills/mcp-auth/SKILL.md +6 -3
  280. package/skills/setup-slack/SKILL.md +23 -13
  281. package/src/bin/agent-serve.ts +12 -1
  282. package/src/channels/github/github-channel.ts +17 -0
  283. package/src/channels/origin/api.ts +24 -5
  284. package/src/channels/origin/binding.ts +55 -26
  285. package/src/channels/origin/index.ts +1 -0
  286. package/src/channels/origin/origin-channel.ts +78 -10
  287. package/src/channels/origin/reactions.ts +82 -0
  288. package/src/channels/origin/types.ts +11 -0
  289. package/src/channels/slack/approvals.ts +105 -0
  290. package/src/channels/slack/cli-project.ts +267 -0
  291. package/src/channels/slack/defaults.ts +165 -74
  292. package/src/channels/slack/dispatch.ts +2 -0
  293. package/src/channels/slack/init.ts +10 -5
  294. package/src/channels/slack/interactive.ts +35 -9
  295. package/src/channels/slack/live-delivery.ts +5 -3
  296. package/src/channels/slack/manifest.ts +1 -1
  297. package/src/channels/slack/progress-delivery.ts +133 -0
  298. package/src/channels/slack/setup.ts +10 -6
  299. package/src/channels/slack/slack-channel.ts +1 -0
  300. package/src/channels/slack/tool-approval-events.ts +93 -0
  301. package/src/channels/slack/types.ts +9 -1
  302. package/src/evals/run-facts.ts +32 -0
  303. package/src/files-backends/cursor-hosted.ts +3 -2
  304. package/src/index.ts +4 -0
  305. package/src/internal/advertise-tools.ts +31 -10
  306. package/src/internal/approval-gate.ts +20 -29
  307. package/src/internal/as-of.ts +107 -0
  308. package/src/internal/chat-client.ts +19 -0
  309. package/src/internal/cli-deploy.ts +203 -13
  310. package/src/internal/cli-mcp-oauth.ts +7 -21
  311. package/src/internal/cli-slack-manual.ts +350 -18
  312. package/src/internal/cli-slack.ts +40 -84
  313. package/src/internal/cursor/account-mcp.ts +21 -0
  314. package/src/internal/cursor-agent-template.ts +1 -0
  315. package/src/internal/cursor-event-relay.ts +5 -6
  316. package/src/internal/deploy-client.ts +43 -0
  317. package/src/internal/env-file.ts +84 -0
  318. package/src/internal/framework-file-storage.ts +18 -46
  319. package/src/internal/framework-storage-selection.ts +41 -25
  320. package/src/internal/hosted-admission-adapter.ts +42 -0
  321. package/src/internal/hosted-delivery-protocol.ts +14 -2
  322. package/src/internal/hosted-delivery.ts +169 -44
  323. package/src/internal/hosted-execution-diag.ts +252 -0
  324. package/src/internal/http-channel.ts +107 -0
  325. package/src/internal/init-project.ts +2 -0
  326. package/src/internal/logs-client.ts +5 -0
  327. package/src/internal/mcp-endpoint.ts +13 -4
  328. package/src/internal/mcp-host.ts +77 -11
  329. package/src/internal/mcp-oauth-on-demand.ts +352 -0
  330. package/src/internal/mcp-oauth-persist.ts +127 -0
  331. package/src/internal/mcp-oauth.ts +17 -1
  332. package/src/internal/null-kv-storage.ts +74 -0
  333. package/src/internal/otel/collector.ts +30 -0
  334. package/src/internal/server.ts +159 -11
  335. package/src/internal/session-engine.ts +691 -57
  336. package/src/internal/session-run-log.ts +584 -0
  337. package/src/internal/sessions-client.ts +17 -8
  338. package/src/internal/storage-coordinator.ts +49 -9
  339. package/src/internal/storage-roles.ts +7 -0
  340. package/src/internal/stream-progress.ts +19 -0
  341. package/src/internal/tool-policy.ts +49 -9
  342. package/src/internal/trajectory.ts +10 -0
  343. package/src/internal/turn-outbox.ts +85 -0
  344. package/src/storage-backends/cursor-hosted.ts +13 -1
  345. package/src/storage-protocol.ts +10 -0
  346. package/src/storage.ts +12 -0
  347. package/src/tools.ts +12 -2
  348. package/src/types.ts +93 -8
  349. package/templates/agents-md/README.md +39 -0
  350. package/templates/agents-md/agent/agent.ts +8 -0
  351. package/templates/agents-md/agent/channels/github.ts +10 -0
  352. package/templates/agents-md/agent/channels/queue.ts +28 -0
  353. package/templates/agents-md/agent/channels/slack.ts +9 -0
  354. package/templates/agents-md/agent/instructions.md +39 -0
  355. package/templates/agents-md/agent/lib/collect.ts +439 -0
  356. package/templates/agents-md/agent/lib/config.ts +8 -0
  357. package/templates/agents-md/agent/lib/paths.ts +51 -0
  358. package/templates/agents-md/agent/schedules/weekly.ts +17 -0
  359. package/templates/agents-md/agent/tools/apply_agents.ts +226 -0
  360. package/templates/agents-md/evals/agents.eval.ts +135 -0
  361. package/templates/agents-md/evals/evals.config.ts +5 -0
  362. package/templates/agents-md/init.json +38 -0
  363. package/templates/agents-md/package.json +18 -0
  364. package/templates/agents-md/tsconfig.json +12 -0
  365. package/dist/docs/assets/chunks/@localSearchIndexroot.DFoGuETX.js +0 -1
  366. package/dist/docs/assets/guides_slack.md.C32HsdKk.js +0 -38
  367. package/dist/docs/assets/guides_slack.md.C32HsdKk.lean.js +0 -1
  368. package/dist/docs/assets/index.md.CI93Ltlb.js +0 -5
  369. package/dist/docs/assets/reference_sessions.md.D0mIh4KK.js +0 -1
  370. package/dist/docs/assets/troubleshooting.md.Ctv3T8C2.js +0 -1
  371. package/dist/docs/design/agsh.md +0 -406
  372. package/dist/playground/assets/index-B1DDvBeC.css +0 -1
  373. package/dist/playground/assets/index-Cx9CclK_.js +0 -88
  374. package/docs/design/agsh.md +0 -406
  375. /package/dist/docs/assets/{deployment.md.D9msOFOW.lean.js → deployment.md.MFPKqsqI.lean.js} +0 -0
  376. /package/dist/docs/assets/{index.md.CI93Ltlb.lean.js → index.md.CVeRUOeZ.lean.js} +0 -0
  377. /package/dist/docs/assets/{reference_agent-config.md.Cp_x38Nl.lean.js → reference_agent-config.md.BHeYMgme.lean.js} +0 -0
  378. /package/dist/docs/assets/{reference_connections.md.BH8Oc0D0.lean.js → reference_connections.md.DxldvyIB.lean.js} +0 -0
  379. /package/dist/docs/assets/{reference_http-api.md.D89k1mdm.lean.js → reference_http-api.md.BEJx9XVj.lean.js} +0 -0
  380. /package/dist/docs/assets/{reference_sessions.md.D0mIh4KK.lean.js → reference_sessions.md.NxFP_CAC.lean.js} +0 -0
  381. /package/dist/docs/assets/{troubleshooting.md.Ctv3T8C2.lean.js → troubleshooting.md.DCiPBhYs.lean.js} +0 -0
@@ -1,10 +1,21 @@
1
1
  /**
2
- * `slack init --manual` and `slack manifest` — DIY paste-at-api.slack.com.
3
- * Create/destroy/icon stay in `cli-slack.ts`.
2
+ * `slack init --manual` and `slack manifest` — unmanaged Slack app.
3
+ * Slack CLI create+install when `~/.slack/bin/slack` is present;
4
+ * paste-at-api.slack.com is the fallback. Create/destroy/icon stay
5
+ * in `cli-slack.ts`.
4
6
  */
5
7
 
6
- import { mkdir, writeFile } from "node:fs/promises";
8
+ import { execFile } from "node:child_process";
9
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
7
10
  import { basename, join, resolve as resolvePath } from "node:path";
11
+ import { promisify } from "node:util";
12
+ import {
13
+ detectSlackCli,
14
+ parseSlackAuthTeams,
15
+ readSlackCliAppId,
16
+ SLACK_CLI_HOME_BIN,
17
+ type SlackCliEnvironment,
18
+ } from "../channels/slack/cli-project.js";
8
19
  import {
9
20
  buildSlackManifestPair,
10
21
  initSlackManual,
@@ -12,6 +23,9 @@ import {
12
23
  } from "../channels/slack/index.js";
13
24
  import { describeError } from "./describe-error.js";
14
25
  import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
26
+ import { ensureEnvLocalGitignored, upsertEnvFile } from "./env-file.js";
27
+
28
+ const execFileAsync = promisify(execFile);
15
29
 
16
30
  export interface SlackManualCliOptions {
17
31
  dir: string;
@@ -23,14 +37,133 @@ export interface SlackManualCliOptions {
23
37
  channelPosts?: boolean;
24
38
  /** Gate for `slack init`; ignored by `slack manifest`. */
25
39
  manual?: boolean;
40
+ /** Require Slack CLI install (fail if missing or install fails). */
41
+ install?: boolean;
42
+ /** Skip Slack CLI install even when the CLI is present. */
43
+ noInstall?: boolean;
44
+ slackTeam?: string;
45
+ prod?: boolean;
46
+ detectSlackCli?: () => string | undefined;
47
+ runSlackCli?: SlackCliExec;
26
48
  out?: (text: string) => void;
27
49
  err?: (text: string) => void;
28
50
  }
29
51
 
52
+ export interface SlackCliExecRequest {
53
+ bin: string;
54
+ argv: string[];
55
+ cwd: string;
56
+ env?: NodeJS.ProcessEnv;
57
+ }
58
+
59
+ export interface SlackCliExecResult {
60
+ code: number;
61
+ stdout: string;
62
+ stderr: string;
63
+ }
64
+
65
+ export type SlackCliExec = (
66
+ request: SlackCliExecRequest
67
+ ) => Promise<SlackCliExecResult>;
68
+
69
+ interface SlackCliInstallResult {
70
+ ok: boolean;
71
+ environment: SlackCliEnvironment;
72
+ team?: string;
73
+ appId?: string;
74
+ error?: string;
75
+ tokens: { bot: boolean; app: boolean };
76
+ }
77
+
78
+ interface SlackCliInstallOptions {
79
+ dir: string;
80
+ bin: string;
81
+ envKeys: { bot: string; app: string };
82
+ environment: SlackCliEnvironment;
83
+ team?: string;
84
+ exec?: SlackCliExec;
85
+ }
86
+
30
87
  function errStream(options: SlackManualCliOptions): (text: string) => void {
31
88
  return options.err ?? ((text: string) => void process.stderr.write(text));
32
89
  }
33
90
 
91
+ function afterDoctor(prefix?: string): string[] {
92
+ return [
93
+ prefix === undefined
94
+ ? `${CLI} slack doctor`
95
+ : `${CLI} slack doctor --prefix ${prefix}`,
96
+ `${CLI} serve --dir . --dev`,
97
+ `${CLI} slack setup`,
98
+ ];
99
+ }
100
+
101
+ function slackCliEnvironment(prod?: boolean): SlackCliEnvironment {
102
+ return prod === true ? "deployed" : "local";
103
+ }
104
+
105
+ function slackAppSettingsUrl(appId?: string): string {
106
+ return appId === undefined
107
+ ? "https://api.slack.com/apps"
108
+ : `https://api.slack.com/apps/${appId}`;
109
+ }
110
+
111
+ function pasteNext(
112
+ envKeys: { bot: string; app: string },
113
+ options: { environment: SlackCliEnvironment; prefix?: string }
114
+ ): string[] {
115
+ return [
116
+ "Ask the user to install this Slack app on their workspace",
117
+ `Open ${slackAppSettingsUrl()} → Create from manifest`,
118
+ "Import .slack/manifest.dev.json (then prod)",
119
+ `Install apps; set ${envKeys.bot} + ${envKeys.app}`,
120
+ `Or install Slack CLI to ~/${SLACK_CLI_HOME_BIN}, then slack app install --environment ${options.environment} --team <T> --force`,
121
+ ...afterDoctor(options.prefix),
122
+ ];
123
+ }
124
+
125
+ function cliNext(
126
+ cli: string,
127
+ envKeys: { bot: string; app: string },
128
+ options: {
129
+ team?: string;
130
+ environment: SlackCliEnvironment;
131
+ prefix?: string;
132
+ }
133
+ ): string[] {
134
+ const workspace = options.team ?? "<T>";
135
+ return [
136
+ "Ask the user to install this Slack app on their workspace",
137
+ `${cli} login --no-prompt`,
138
+ `In Slack send /slackauthticket <ticket>; then ${cli} login --ticket <ticket> --challenge <code>`,
139
+ `${cli} app install --environment ${options.environment} --team ${workspace} --force`,
140
+ `Copy xoxb + xapp (connections:write) from ${slackAppSettingsUrl()} into .env.local as ${envKeys.bot} + ${envKeys.app}`,
141
+ `Fallback: paste .slack/manifest.dev.json at ${slackAppSettingsUrl()}`,
142
+ ...afterDoctor(options.prefix),
143
+ ];
144
+ }
145
+
146
+ function installedNext(
147
+ install: SlackCliInstallResult,
148
+ envKeys: { bot: string; app: string },
149
+ prefix?: string
150
+ ): string[] {
151
+ const settings = slackAppSettingsUrl(install.appId);
152
+ const next: string[] = [];
153
+ if (!install.tokens.bot) {
154
+ next.push(
155
+ `Copy the bot token (xoxb-...) from ${settings} into ${envKeys.bot}`
156
+ );
157
+ }
158
+ if (!install.tokens.app) {
159
+ next.push(
160
+ `Mint an app-level token with connections:write at ${settings}; set ${envKeys.app}`
161
+ );
162
+ }
163
+ next.push(...afterDoctor(prefix));
164
+ return next;
165
+ }
166
+
34
167
  export async function cmdSlackInit(
35
168
  options: SlackManualCliOptions
36
169
  ): Promise<number> {
@@ -42,7 +175,7 @@ export async function cmdSlackInit(
42
175
 
43
176
  That opens the Cursor dashboard wizard.
44
177
 
45
- To install a custom Slack app from a manifest (api.slack.com):
178
+ To install a custom Slack app from a manifest (Slack CLI or api.slack.com):
46
179
 
47
180
  ${CLI} slack init --manual --dir .
48
181
  `
@@ -53,6 +186,7 @@ To install a custom Slack app from a manifest (api.slack.com):
53
186
  const dir = resolvePath(options.dir);
54
187
  const out =
55
188
  options.out ?? ((text: string) => void process.stdout.write(text));
189
+ const err = errStream(options);
56
190
  try {
57
191
  const result = await initSlackManual({
58
192
  dir,
@@ -60,32 +194,60 @@ To install a custom Slack app from a manifest (api.slack.com):
60
194
  envPrefix: options.noPrefix === true ? "" : options.prefix,
61
195
  channelPosts: options.channelPosts,
62
196
  });
197
+ const cli = (options.detectSlackCli ?? detectSlackCli)();
198
+ const skipInstall = options.noInstall === true;
199
+ const requireInstall = options.install === true && !skipInstall;
200
+ let install: SlackCliInstallResult | undefined;
201
+ if (!skipInstall && cli !== undefined) {
202
+ install = await installSlackApp({
203
+ dir: result.rootDir,
204
+ bin: cli,
205
+ envKeys: result.envKeys,
206
+ environment: slackCliEnvironment(options.prod),
207
+ team: options.slackTeam,
208
+ exec: options.runSlackCli,
209
+ });
210
+ if (!install.ok && requireInstall) {
211
+ err(`${install.error ?? "slack app install failed"}\n`);
212
+ }
213
+ } else if (requireInstall) {
214
+ err(
215
+ `Slack CLI not found (~/${SLACK_CLI_HOME_BIN}). Install it or omit --install and paste at api.slack.com.\n`
216
+ );
217
+ }
218
+ const ok = !requireInstall || install?.ok === true;
219
+ const next =
220
+ install?.ok === true
221
+ ? installedNext(install, result.envKeys, result.envPrefix)
222
+ : cli !== undefined
223
+ ? cliNext(cli, result.envKeys, {
224
+ team: install?.team ?? options.slackTeam,
225
+ environment: slackCliEnvironment(options.prod),
226
+ prefix: result.envPrefix,
227
+ })
228
+ : pasteNext(result.envKeys, {
229
+ environment: slackCliEnvironment(options.prod),
230
+ prefix: result.envPrefix,
231
+ });
63
232
  out(
64
233
  `${JSON.stringify(
65
234
  {
66
- ok: true,
235
+ ok,
67
236
  directory: result.rootDir,
68
237
  created: result.files,
69
238
  envPrefix: result.envPrefix ?? null,
70
239
  envKeys: result.envKeys,
71
- next: [
72
- "Open https://api.slack.com/apps Create from manifest",
73
- "Import .agent-serve/slack/manifest.dev.json (then prod)",
74
- `Install apps; set ${result.envKeys.bot} + ${result.envKeys.app}`,
75
- result.envPrefix === undefined
76
- ? `${CLI} slack doctor`
77
- : `${CLI} slack doctor --prefix ${result.envPrefix}`,
78
- `${CLI} serve --dir . --dev`,
79
- `${CLI} slack setup`,
80
- ],
240
+ cli: cli ?? null,
241
+ install: install ?? null,
242
+ next,
81
243
  },
82
244
  null,
83
245
  2
84
246
  )}\n`
85
247
  );
86
- return 0;
248
+ return ok ? 0 : 1;
87
249
  } catch (error) {
88
- errStream(options)(`${describeError(error)}\n`);
250
+ err(`${describeError(error)}\n`);
89
251
  return 1;
90
252
  }
91
253
  }
@@ -114,7 +276,7 @@ export async function runSlackManifest(
114
276
  return 0;
115
277
  }
116
278
 
117
- const outDir = join(dir, ".agent-serve/slack");
279
+ const outDir = join(dir, ".slack");
118
280
  await mkdir(outDir, { recursive: true });
119
281
  const written: string[] = [];
120
282
  for (const file of slackManifestFileEntries(pair, env)) {
@@ -125,3 +287,173 @@ export async function runSlackManifest(
125
287
  process.stdout.write(`${JSON.stringify({ ok: true, written }, null, 2)}\n`);
126
288
  return 0;
127
289
  }
290
+
291
+ function parseEnvAssignments(text: string): Record<string, string> {
292
+ const out: Record<string, string> = {};
293
+ for (const line of text.split(/\r?\n/)) {
294
+ const trimmed = line.trim();
295
+ if (trimmed === "" || trimmed.startsWith("#")) {
296
+ continue;
297
+ }
298
+ const raw = trimmed.startsWith("export ") ? trimmed.slice(7) : trimmed;
299
+ const eq = raw.indexOf("=");
300
+ if (eq <= 0) {
301
+ continue;
302
+ }
303
+ out[raw.slice(0, eq)] = raw.slice(eq + 1);
304
+ }
305
+ return out;
306
+ }
307
+
308
+ async function readDotenv(dir: string): Promise<Record<string, string>> {
309
+ return parseEnvAssignments(
310
+ await readFile(join(dir, ".env"), "utf8").catch(() => "")
311
+ );
312
+ }
313
+
314
+ function newToken(
315
+ before: string | undefined,
316
+ after: string | undefined,
317
+ prefix: string
318
+ ): string | undefined {
319
+ if (after === undefined || !after.startsWith(prefix) || after === before) {
320
+ return undefined;
321
+ }
322
+ return after;
323
+ }
324
+
325
+ async function copySlackCliTokensToLocalEnv(options: {
326
+ dir: string;
327
+ envKeys: { bot: string; app: string };
328
+ before: Record<string, string>;
329
+ }): Promise<{ bot: boolean; app: boolean }> {
330
+ const after = await readDotenv(options.dir);
331
+ const bot = newToken(
332
+ options.before.SLACK_BOT_TOKEN,
333
+ after.SLACK_BOT_TOKEN,
334
+ "xoxb-"
335
+ );
336
+ const app = newToken(
337
+ options.before.SLACK_APP_TOKEN,
338
+ after.SLACK_APP_TOKEN,
339
+ "xapp-"
340
+ );
341
+ const entries: Array<{ key: string; value: string }> = [];
342
+ const wrote = { bot: false, app: false };
343
+ if (bot !== undefined) {
344
+ entries.push({ key: options.envKeys.bot, value: bot });
345
+ wrote.bot = true;
346
+ }
347
+ if (app !== undefined) {
348
+ entries.push({ key: options.envKeys.app, value: app });
349
+ wrote.app = true;
350
+ }
351
+ if (entries.length === 0) {
352
+ return wrote;
353
+ }
354
+ await upsertEnvFile(join(options.dir, ".env.local"), entries);
355
+ await ensureEnvLocalGitignored(options.dir);
356
+ return wrote;
357
+ }
358
+
359
+ async function installSlackApp(
360
+ options: SlackCliInstallOptions
361
+ ): Promise<SlackCliInstallResult> {
362
+ const exec = options.exec ?? defaultSlackCliExec;
363
+ const auth = await exec({
364
+ bin: options.bin,
365
+ argv: ["auth", "list"],
366
+ cwd: options.dir,
367
+ });
368
+ const teams = parseSlackAuthTeams(`${auth.stdout}\n${auth.stderr}`);
369
+ if (teams.length === 0) {
370
+ return {
371
+ ok: false,
372
+ environment: options.environment,
373
+ error: "Slack CLI is not logged in. Run slack login --no-prompt.",
374
+ tokens: { bot: false, app: false },
375
+ };
376
+ }
377
+ let team = options.team;
378
+ if (team === undefined) {
379
+ if (teams.length > 1) {
380
+ return {
381
+ ok: false,
382
+ environment: options.environment,
383
+ error: `Multiple Slack CLI teams (${teams.join(", ")}). Pass --slack-team.`,
384
+ tokens: { bot: false, app: false },
385
+ };
386
+ }
387
+ team = teams[0];
388
+ }
389
+ const before = await readDotenv(options.dir);
390
+ const installed = await exec({
391
+ bin: options.bin,
392
+ argv: [
393
+ "app",
394
+ "install",
395
+ "--environment",
396
+ options.environment,
397
+ "--force",
398
+ "--team",
399
+ team,
400
+ ],
401
+ cwd: options.dir,
402
+ env: { ...process.env, SLACK_ENV: options.environment },
403
+ });
404
+ if (installed.code !== 0) {
405
+ const detail = installed.stderr.trim() || installed.stdout.trim();
406
+ return {
407
+ ok: false,
408
+ environment: options.environment,
409
+ team,
410
+ error:
411
+ detail === "" ? `slack app install exited ${installed.code}` : detail,
412
+ tokens: { bot: false, app: false },
413
+ };
414
+ }
415
+ await writeFile(
416
+ join(options.dir, ".slack/cli-environment"),
417
+ `${options.environment}\n`
418
+ );
419
+ const appId = await readSlackCliAppId(options.dir, options.environment, team);
420
+ const tokens = await copySlackCliTokensToLocalEnv({
421
+ dir: options.dir,
422
+ envKeys: options.envKeys,
423
+ before,
424
+ });
425
+ return {
426
+ ok: true,
427
+ environment: options.environment,
428
+ team,
429
+ appId,
430
+ tokens,
431
+ };
432
+ }
433
+
434
+ async function defaultSlackCliExec(
435
+ request: SlackCliExecRequest
436
+ ): Promise<SlackCliExecResult> {
437
+ try {
438
+ const { stdout, stderr } = await execFileAsync(request.bin, request.argv, {
439
+ cwd: request.cwd,
440
+ env: request.env,
441
+ timeout: 120_000,
442
+ });
443
+ return { code: 0, stdout, stderr };
444
+ } catch (error) {
445
+ if (!(error instanceof Error)) {
446
+ throw error;
447
+ }
448
+ const execError = error as Error & {
449
+ code?: number | string;
450
+ stdout?: string;
451
+ stderr?: string;
452
+ };
453
+ return {
454
+ code: typeof execError.code === "number" ? execError.code : 1,
455
+ stdout: execError.stdout ?? "",
456
+ stderr: execError.stderr ?? execError.message,
457
+ };
458
+ }
459
+ }
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * `agent-serve slack …` CLI — doctor, destroy/icon, `create` as a
3
3
  * dashboard-wizard launcher (`slack-provision-client.ts`), and
4
- * `init --manual` for hand-imported manifests.
4
+ * `init --manual` for Slack CLI / paste-at-api.slack.com manifests.
5
5
  */
6
6
 
7
- import { access, chmod, readFile, writeFile } from "node:fs/promises";
7
+ import { access, readFile } from "node:fs/promises";
8
8
  import { basename, extname, join, resolve as resolvePath } from "node:path";
9
9
  import {
10
10
  envPrefixFromName,
@@ -15,12 +15,17 @@ import {
15
15
  slackEnvKeys,
16
16
  } from "../channels/slack/index.js";
17
17
  import { resolveDeployAuth } from "./cli-deploy.js";
18
- import { cmdSlackInit, runSlackManifest } from "./cli-slack-manual.js";
18
+ import {
19
+ cmdSlackInit,
20
+ runSlackManifest,
21
+ type SlackCliExec,
22
+ } from "./cli-slack-manual.js";
19
23
  import { cursorExternalApiUrl } from "./cursor/credentials.js";
20
24
  import { slugFromDirectoryName } from "./deploy-client.js";
21
25
  import { inferDeployGitSource } from "./deploy-source.js";
22
26
  import { describeError } from "./describe-error.js";
23
27
  import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
28
+ import { ensureEnvLocalGitignored, upsertEnvFile } from "./env-file.js";
24
29
  import { loadAgentLocalEnv } from "./local-env.js";
25
30
  import { openBrowser } from "./open-browser.js";
26
31
  import {
@@ -60,8 +65,14 @@ export interface SlackCliOptions {
60
65
  icon?: string;
61
66
  /** create: accepted for compatibility; live-app updates always overwrite. */
62
67
  force?: boolean;
63
- /** `slack init --manual`: manifests for paste at api.slack.com. */
68
+ /** `slack init --manual`: Slack CLI project + paste fallback. */
64
69
  manual?: boolean;
70
+ /** `slack init --manual`: require Slack CLI install. */
71
+ install?: boolean;
72
+ /** `slack init --manual`: skip Slack CLI install. */
73
+ noInstall?: boolean;
74
+ detectSlackCli?: () => string | undefined;
75
+ runSlackCli?: SlackCliExec;
65
76
  /** `slack icon <source>` positional (same URL-or-file forms as --icon). */
66
77
  iconSource?: string;
67
78
  /** doctor: watched channel ids (`C…`) to verify visibility/membership. */
@@ -90,6 +101,8 @@ Usage:
90
101
  [--prod] [--team <id>] [--json]
91
102
  ${CLI} slack init --manual [--dir .] [--name NAME]
92
103
  [--prefix PREFIX | --no-prefix] [--channel-posts]
104
+ [--install | --no-install]
105
+ [--slack-team T0123ABCD] [--prod]
93
106
  ${CLI} slack manifest --env dev|prod|both [--dir .] [--name NAME]
94
107
  [--print]
95
108
  ${CLI} slack doctor [--dir .] [--prefix PREFIX | --no-prefix] [--json]
@@ -107,8 +120,13 @@ create/destroy/icon — dedicated Socket Mode app via the Cursor dashboard:
107
120
  png/jpg/gif file (at most 512KB).
108
121
 
109
122
  \`slack init\` without --manual is not the first-run path. Use \`slack create\`.
110
- \`slack init --manual\` writes the channel file, manifests to paste at
111
- api.slack.com, env.example, and setup-status.json.
123
+ \`slack init --manual\` writes the channel file, manifests, a Slack CLI
124
+ \`.slack/\` project (get-manifest → those JSON files), env.example, and
125
+ setup-status.json. When \`~/.slack/bin/slack\` is logged in, it installs
126
+ the app. Otherwise \`next\` asks the user to install it. \`--install\`
127
+ requires that install. \`--no-install\` skips it. \`--prod\` selects the
128
+ deployed app. Paste at api.slack.com is the fallback. Do not
129
+ \`slack deploy\`.
112
130
 
113
131
  Env tokens:
114
132
  single agent: SLACK_BOT_TOKEN + SLACK_APP_TOKEN
@@ -140,7 +158,22 @@ export async function cmdSlack(
140
158
  case "icon":
141
159
  return cmdSlackIcon(options);
142
160
  case "init":
143
- return cmdSlackInit(options);
161
+ return cmdSlackInit({
162
+ dir: options.dir,
163
+ name: options.name,
164
+ prefix: options.prefix,
165
+ noPrefix: options.noPrefix,
166
+ channelPosts: options.channelPosts,
167
+ manual: options.manual,
168
+ install: options.install,
169
+ noInstall: options.noInstall,
170
+ slackTeam: options.slackTeam,
171
+ detectSlackCli: options.detectSlackCli,
172
+ runSlackCli: options.runSlackCli,
173
+ prod: options.prod,
174
+ out: options.out,
175
+ err: options.err,
176
+ });
144
177
  case "manifest":
145
178
  return runSlackManifest(options);
146
179
  case "doctor":
@@ -812,83 +845,6 @@ async function scaffoldSlackChannelFiles(
812
845
  }
813
846
  }
814
847
 
815
- /**
816
- * Append `KEY=value` lines to an env file, replacing every existing line
817
- * for the same key instead of appending duplicates. Creates the file when
818
- * missing.
819
- */
820
- async function upsertEnvFile(
821
- path: string,
822
- entries: Array<{ key: string; value: string }>
823
- ): Promise<void> {
824
- let existing = "";
825
- try {
826
- existing = await readFile(path, "utf8");
827
- } catch (error) {
828
- if (!isErrnoException(error) || error.code !== "ENOENT") {
829
- throw error;
830
- }
831
- }
832
- const lines =
833
- existing === "" ? [] : existing.replace(/\r?\n$/, "").split(/\r?\n/);
834
- // A stale `export KEY=…` line would shadow or duplicate the bare line
835
- // under some loaders; treat both spellings as the same entry.
836
- const matchesKey = (line: string, key: string): boolean =>
837
- line.startsWith(`${key}=`) || line.startsWith(`export ${key}=`);
838
- for (const { key, value } of entries) {
839
- const next = `${key}=${value}`;
840
- let replaced = false;
841
- for (let i = 0; i < lines.length; ) {
842
- if (!matchesKey(lines[i] ?? "", key)) {
843
- i += 1;
844
- continue;
845
- }
846
- if (replaced) {
847
- lines.splice(i, 1);
848
- continue;
849
- }
850
- lines[i] = next;
851
- replaced = true;
852
- i += 1;
853
- }
854
- if (!replaced) {
855
- lines.push(next);
856
- }
857
- }
858
- // writeFile's mode only applies on create; clamp pre-existing files too.
859
- await writeFile(path, `${lines.join("\n")}\n`, { mode: 0o600 });
860
- await chmod(path, 0o600);
861
- }
862
-
863
- /**
864
- * Ensure the agent directory's .gitignore covers .env.local (create or
865
- * append). A bare `.env` line does not count — that pattern matches only
866
- * the file literally named .env.
867
- */
868
- async function ensureEnvLocalGitignored(dir: string): Promise<boolean> {
869
- const path = join(dir, ".gitignore");
870
- let existing = "";
871
- try {
872
- existing = await readFile(path, "utf8");
873
- } catch (error) {
874
- if (!isErrnoException(error) || error.code !== "ENOENT") {
875
- throw error;
876
- }
877
- }
878
- const covered = existing
879
- .split(/\r?\n/)
880
- .some((line) => /^\.env(\.local\*?|\.\*|\*)$/.test(line.trim()));
881
- if (covered) {
882
- return false;
883
- }
884
- const next =
885
- existing === "" || existing.endsWith("\n")
886
- ? `${existing}.env.local\n`
887
- : `${existing}\n.env.local\n`;
888
- await writeFile(path, next);
889
- return true;
890
- }
891
-
892
848
  function renderDoctorReport(result: SlackDoctorResult): string {
893
849
  let text = `env: ${result.envKeys.bot} / ${result.envKeys.app}\n`;
894
850
  for (const check of result.checks) {
@@ -253,6 +253,27 @@ export class CursorAccountMcpBridge {
253
253
  * Returns a promise that settles when every ref's log lines are written —
254
254
  * callers may ignore it; tests can await it.
255
255
  */
256
+ async probeAuthUrl(
257
+ ref: CursorAccountConnectionRef
258
+ ): Promise<string | undefined> {
259
+ const identifiers =
260
+ ref.servers !== undefined && ref.servers.length > 0
261
+ ? [...ref.servers]
262
+ : (await this.client.getAvailableMcpServers()).map(
263
+ (server) => server.serverIdentifier ?? server.name
264
+ );
265
+ const urls = await probeConnectorAuthUrls({
266
+ client: this.client,
267
+ identifiers,
268
+ });
269
+ for (const url of urls.values()) {
270
+ if (url !== "") {
271
+ return url;
272
+ }
273
+ }
274
+ return undefined;
275
+ }
276
+
256
277
  logPreflight(refs: CursorAccountConnectionRef[]): Promise<void> {
257
278
  return Promise.all(refs.map((ref) => this.runPreflight(ref))).then(
258
279
  () => undefined
@@ -4,6 +4,7 @@ import { join } from "node:path";
4
4
  const MAX = 64;
5
5
  const TEMPLATE_NAMES = [
6
6
  "agentic-owners",
7
+ "agents-md",
7
8
  "code-wiki",
8
9
  "demo",
9
10
  "pr-autofixer",
@@ -616,12 +616,11 @@ export class CursorEventRelay {
616
616
  events: [...subscription.events],
617
617
  })),
618
618
  }),
619
- // Empty subscriptions drop this consumer's registration on clean stop
620
- // instead of leaving it to lapse by TTL.
621
- buildDeregistrationBody: (consumerId) => ({
622
- consumerId,
623
- subscriptions: [],
624
- }),
619
+ // No deregistration on stop: the backend only records events for a
620
+ // repo that some consumer is subscribed to, so dropping the
621
+ // registration leaves a hole in the log until the next process
622
+ // registers, and the durable offset cannot replay what was never
623
+ // written. A consumer that does not come back lapses by TTL.
625
624
  applyRegistrationResponse: (json) => {
626
625
  const result = json as { repos?: SubscriptionStatus[] };
627
626
  const statuses = result.repos ?? [];