eve 0.7.4 → 0.8.0

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 (337) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +11 -11
  3. package/dist/src/chunks/{use-eve-agent-DErQj5hs.js → use-eve-agent-BSXZSn-R.js} +6 -1
  4. package/dist/src/chunks/{use-eve-agent-DoR8C4i6.js → use-eve-agent-Dlut2Qzt.js} +6 -1
  5. package/dist/src/cli/commands/init.js +1 -1
  6. package/dist/src/cli/dev/tui/blocks.d.ts +1 -1
  7. package/dist/src/cli/dev/tui/blocks.js +4 -3
  8. package/dist/src/cli/dev/tui/command-typeahead.d.ts +13 -3
  9. package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
  10. package/dist/src/cli/dev/tui/line-editor.d.ts +6 -0
  11. package/dist/src/cli/dev/tui/line-editor.js +1 -1
  12. package/dist/src/cli/dev/tui/prompt-command-handler.d.ts +2 -0
  13. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  14. package/dist/src/cli/dev/tui/runner.d.ts +10 -0
  15. package/dist/src/cli/dev/tui/runner.js +1 -1
  16. package/dist/src/cli/dev/tui/setup-commands.d.ts +11 -7
  17. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  18. package/dist/src/cli/dev/tui/setup-flow.d.ts +72 -10
  19. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  20. package/dist/src/cli/dev/tui/setup-panel.d.ts +91 -39
  21. package/dist/src/cli/dev/tui/setup-panel.js +3 -1
  22. package/dist/src/cli/dev/tui/setup-selection-input.d.ts +48 -0
  23. package/dist/src/cli/dev/tui/setup-selection-input.js +1 -0
  24. package/dist/src/cli/dev/tui/status-line.d.ts +13 -7
  25. package/dist/src/cli/dev/tui/status-line.js +1 -1
  26. package/dist/src/cli/dev/tui/stream-format.d.ts +2 -0
  27. package/dist/src/cli/dev/tui/stream-format.js +2 -2
  28. package/dist/src/cli/dev/tui/terminal-renderer.d.ts +4 -2
  29. package/dist/src/cli/dev/tui/terminal-renderer.js +6 -5
  30. package/dist/src/cli/dev/tui/theme.d.ts +3 -1
  31. package/dist/src/cli/dev/tui/theme.js +1 -1
  32. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  33. package/dist/src/cli/dev/tui/tui.d.ts +6 -0
  34. package/dist/src/cli/dev/tui/tui.js +1 -1
  35. package/dist/src/cli/dev/tui/vercel-status.d.ts +4 -4
  36. package/dist/src/cli/dev/tui/vercel-status.js +1 -1
  37. package/dist/src/cli/run.d.ts +4 -3
  38. package/dist/src/cli/run.js +2 -2
  39. package/dist/src/client/client.js +1 -1
  40. package/dist/src/client/session-utils.d.ts +1 -0
  41. package/dist/src/client/session-utils.js +1 -1
  42. package/dist/src/client/session.d.ts +1 -0
  43. package/dist/src/client/session.js +1 -1
  44. package/dist/src/client/types.d.ts +19 -0
  45. package/dist/src/compiled/.vendor-stamp.json +1 -2
  46. package/dist/src/compiler/compile-from-memory.js +1 -1
  47. package/dist/src/compiler/manifest.d.ts +28 -7
  48. package/dist/src/compiler/manifest.js +1 -1
  49. package/dist/src/compiler/normalize-agent-config.js +1 -1
  50. package/dist/src/compiler/normalize-sandbox.js +1 -1
  51. package/dist/src/evals/cli/eval-client.js +1 -1
  52. package/dist/src/execution/sandbox/bash-tool.js +1 -1
  53. package/dist/src/execution/sandbox/bindings/docker-base-setup.d.ts +9 -0
  54. package/dist/src/execution/sandbox/bindings/docker-base-setup.js +2 -0
  55. package/dist/src/execution/sandbox/bindings/docker-cli.d.ts +77 -0
  56. package/dist/src/execution/sandbox/bindings/docker-cli.js +2 -0
  57. package/dist/src/execution/sandbox/bindings/docker-container.d.ts +16 -0
  58. package/dist/src/execution/sandbox/bindings/docker-container.js +1 -0
  59. package/dist/src/execution/sandbox/bindings/docker-network.d.ts +8 -0
  60. package/dist/src/execution/sandbox/bindings/docker-network.js +1 -0
  61. package/dist/src/execution/sandbox/bindings/docker-options.d.ts +21 -0
  62. package/dist/src/execution/sandbox/bindings/docker-options.js +1 -0
  63. package/dist/src/execution/sandbox/bindings/docker-session.d.ts +7 -0
  64. package/dist/src/execution/sandbox/bindings/docker-session.js +2 -0
  65. package/dist/src/execution/sandbox/bindings/docker-templates.d.ts +35 -0
  66. package/dist/src/execution/sandbox/bindings/docker-templates.js +1 -0
  67. package/dist/src/execution/sandbox/bindings/docker-utils.d.ts +2 -0
  68. package/dist/src/execution/sandbox/bindings/docker-utils.js +1 -0
  69. package/dist/src/execution/sandbox/bindings/docker.d.ts +33 -0
  70. package/dist/src/execution/sandbox/bindings/docker.js +1 -0
  71. package/dist/src/execution/sandbox/bindings/just-bash-runtime.d.ts +30 -0
  72. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -0
  73. package/dist/src/execution/sandbox/bindings/just-bash.d.ts +33 -0
  74. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -0
  75. package/dist/src/execution/sandbox/bindings/local-backend-utils.d.ts +23 -0
  76. package/dist/src/execution/sandbox/bindings/local-backend-utils.js +1 -0
  77. package/dist/src/execution/sandbox/bindings/local-template-prune.d.ts +16 -0
  78. package/dist/src/execution/sandbox/bindings/local-template-prune.js +1 -0
  79. package/dist/src/execution/sandbox/bindings/local.d.ts +16 -25
  80. package/dist/src/execution/sandbox/bindings/local.js +1 -1
  81. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.d.ts +16 -0
  82. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -0
  83. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.d.ts +21 -0
  84. package/dist/src/execution/sandbox/bindings/microsandbox-metadata.js +1 -0
  85. package/dist/src/execution/sandbox/bindings/microsandbox-network.d.ts +18 -0
  86. package/dist/src/execution/sandbox/bindings/microsandbox-network.js +1 -0
  87. package/dist/src/execution/sandbox/bindings/microsandbox-options.d.ts +34 -0
  88. package/dist/src/execution/sandbox/bindings/microsandbox-options.js +1 -0
  89. package/dist/src/execution/sandbox/bindings/microsandbox-platform.d.ts +22 -0
  90. package/dist/src/execution/sandbox/bindings/microsandbox-platform.js +178 -0
  91. package/dist/src/execution/sandbox/bindings/microsandbox-process.d.ts +3 -0
  92. package/dist/src/execution/sandbox/bindings/microsandbox-process.js +1 -0
  93. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +75 -0
  94. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -0
  95. package/dist/src/execution/sandbox/bindings/microsandbox-templates.d.ts +13 -0
  96. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -0
  97. package/dist/src/execution/sandbox/bindings/microsandbox.d.ts +22 -0
  98. package/dist/src/execution/sandbox/bindings/microsandbox.js +1 -0
  99. package/dist/src/execution/sandbox/bindings/vercel-create-api.d.ts +20 -0
  100. package/dist/src/execution/sandbox/bindings/vercel-create-api.js +1 -0
  101. package/dist/src/execution/sandbox/bindings/vercel.d.ts +7 -8
  102. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  103. package/dist/src/execution/sandbox/development-cleanup.d.ts +4 -0
  104. package/dist/src/execution/sandbox/development-cleanup.js +1 -0
  105. package/dist/src/execution/sandbox/development-prewarm.d.ts +11 -0
  106. package/dist/src/execution/sandbox/development-prewarm.js +1 -0
  107. package/dist/src/execution/sandbox/development-run.d.ts +8 -0
  108. package/dist/src/execution/sandbox/development-run.js +1 -0
  109. package/dist/src/execution/sandbox/ensure.js +1 -1
  110. package/dist/src/execution/sandbox/lazy-backend.d.ts +1 -1
  111. package/dist/src/execution/sandbox/logging-session.d.ts +5 -0
  112. package/dist/src/execution/sandbox/logging-session.js +1 -0
  113. package/dist/src/execution/sandbox/prewarm.js +1 -1
  114. package/dist/src/execution/sandbox/template-prewarm-lock.d.ts +8 -0
  115. package/dist/src/execution/sandbox/template-prewarm-lock.js +1 -0
  116. package/dist/src/internal/application/optional-package-install.d.ts +40 -0
  117. package/dist/src/internal/application/optional-package-install.js +1 -0
  118. package/dist/src/internal/application/package.js +1 -1
  119. package/dist/src/internal/authored-definition/sandbox.d.ts +1 -1
  120. package/dist/src/internal/authored-definition/sandbox.js +1 -1
  121. package/dist/src/internal/authored-module-loader.js +2 -2
  122. package/dist/src/internal/classify-model-routing.d.ts +24 -0
  123. package/dist/src/internal/classify-model-routing.js +1 -0
  124. package/dist/src/internal/nitro/host/channel-routes.js +2 -2
  125. package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.d.ts +5 -2
  126. package/dist/src/internal/nitro/host/compiled-sandbox-backend-prune-plugin.js +1 -1
  127. package/dist/src/internal/nitro/host/create-application-nitro.d.ts +10 -0
  128. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  129. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  130. package/dist/src/internal/nitro/host/dev-live-virtual-modules.d.ts +15 -0
  131. package/dist/src/internal/nitro/host/dev-live-virtual-modules.js +1 -0
  132. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.d.ts +28 -0
  133. package/dist/src/internal/nitro/host/optional-engine-dependency-plugin.js +1 -0
  134. package/dist/src/internal/nitro/host/start-development-server.js +1 -1
  135. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.d.ts +2 -0
  136. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  137. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +4 -0
  138. package/dist/src/internal/nitro/routes/info.js +1 -1
  139. package/dist/src/internal/nitro/routes/runtime-artifacts.js +1 -1
  140. package/dist/src/internal/resolve-model-endpoint-status.d.ts +23 -0
  141. package/dist/src/internal/resolve-model-endpoint-status.js +1 -0
  142. package/dist/src/internal/workflow-bundle/builder-support.js +2 -2
  143. package/dist/src/internal/workflow-bundle/vercel-workflow-output.d.ts +1 -1
  144. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  145. package/dist/src/public/definitions/sandbox-backend.js +1 -1
  146. package/dist/src/public/sandbox/backends/default.d.ts +37 -10
  147. package/dist/src/public/sandbox/backends/default.js +1 -1
  148. package/dist/src/public/sandbox/backends/docker.d.ts +14 -0
  149. package/dist/src/public/sandbox/backends/docker.js +1 -0
  150. package/dist/src/public/sandbox/backends/just-bash.d.ts +17 -0
  151. package/dist/src/public/sandbox/backends/just-bash.js +1 -0
  152. package/dist/src/public/sandbox/backends/microsandbox.d.ts +17 -0
  153. package/dist/src/public/sandbox/backends/microsandbox.js +1 -0
  154. package/dist/src/public/sandbox/backends/vercel.d.ts +5 -2
  155. package/dist/src/public/sandbox/backends/vercel.js +1 -1
  156. package/dist/src/public/sandbox/docker-sandbox.d.ts +45 -0
  157. package/dist/src/public/sandbox/index.d.ts +8 -4
  158. package/dist/src/public/sandbox/index.js +1 -1
  159. package/dist/src/public/sandbox/just-bash-sandbox.d.ts +17 -0
  160. package/dist/src/public/sandbox/just-bash-sandbox.js +1 -0
  161. package/dist/src/public/sandbox/microsandbox-sandbox.d.ts +54 -0
  162. package/dist/src/public/sandbox/microsandbox-sandbox.js +1 -0
  163. package/dist/src/public/sandbox/vercel-sandbox.d.ts +1 -1
  164. package/dist/src/runtime/compiled-artifacts-source.d.ts +11 -0
  165. package/dist/src/runtime/compiled-artifacts-source.js +1 -1
  166. package/dist/src/runtime/resolve-sandbox.js +1 -1
  167. package/dist/src/runtime/sandbox/keys.js +1 -1
  168. package/dist/src/runtime/sandbox/registry.d.ts +2 -2
  169. package/dist/src/runtime/types.d.ts +1 -1
  170. package/dist/src/runtime/workspace/spec.js +1 -1
  171. package/dist/src/setup/boxes/add-channels.d.ts +3 -2
  172. package/dist/src/setup/boxes/add-channels.js +2 -2
  173. package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
  174. package/dist/src/setup/boxes/deploy-project.js +1 -1
  175. package/dist/src/setup/boxes/link-project.js +1 -1
  176. package/dist/src/setup/boxes/resolve-provisioning.d.ts +6 -0
  177. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  178. package/dist/src/setup/boxes/select-model.d.ts +2 -2
  179. package/dist/src/setup/boxes/select-model.js +1 -1
  180. package/dist/src/setup/cli/channel-setup-prompter.d.ts +28 -0
  181. package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
  182. package/dist/src/setup/cli/index.d.ts +2 -2
  183. package/dist/src/setup/cli/index.js +1 -1
  184. package/dist/src/setup/cli/option-row.d.ts +89 -0
  185. package/dist/src/setup/cli/option-row.js +1 -0
  186. package/dist/src/setup/cli/prompt-ui.d.ts +15 -29
  187. package/dist/src/setup/cli/prompt-ui.js +2 -2
  188. package/dist/src/setup/cli/select-component.d.ts +4 -3
  189. package/dist/src/setup/cli/select-component.js +1 -1
  190. package/dist/src/setup/cli/select-state.d.ts +3 -3
  191. package/dist/src/setup/cli/select-state.js +1 -1
  192. package/dist/src/setup/flows/channels.d.ts +29 -14
  193. package/dist/src/setup/flows/channels.js +1 -1
  194. package/dist/src/setup/flows/deploy.d.ts +1 -0
  195. package/dist/src/setup/flows/deploy.js +1 -1
  196. package/dist/src/setup/flows/link.d.ts +1 -0
  197. package/dist/src/setup/flows/link.js +1 -1
  198. package/dist/src/setup/flows/model.d.ts +30 -6
  199. package/dist/src/setup/flows/model.js +1 -1
  200. package/dist/src/setup/flows/vercel.d.ts +4 -1
  201. package/dist/src/setup/flows/vercel.js +2 -2
  202. package/dist/src/setup/index.js +1 -1
  203. package/dist/src/setup/primitives/open-url.d.ts +14 -0
  204. package/dist/src/setup/primitives/open-url.js +1 -0
  205. package/dist/src/setup/primitives/pm/pnpm.d.ts +9 -0
  206. package/dist/src/setup/primitives/pm/pnpm.js +2 -2
  207. package/dist/src/setup/primitives/pm/run.d.ts +12 -4
  208. package/dist/src/setup/primitives/pm/run.js +1 -1
  209. package/dist/src/setup/primitives/pm/types.d.ts +3 -0
  210. package/dist/src/setup/primitives/process-abort.d.ts +7 -0
  211. package/dist/src/setup/primitives/process-abort.js +1 -0
  212. package/dist/src/setup/primitives/run-vercel.d.ts +2 -0
  213. package/dist/src/setup/primitives/run-vercel.js +1 -1
  214. package/dist/src/setup/project-resolution.d.ts +6 -3
  215. package/dist/src/setup/project-resolution.js +1 -1
  216. package/dist/src/setup/prompter.d.ts +63 -6
  217. package/dist/src/setup/prompter.js +1 -1
  218. package/dist/src/setup/run-vercel-link.d.ts +1 -1
  219. package/dist/src/setup/run-vercel-link.js +1 -1
  220. package/dist/src/setup/runner.d.ts +2 -0
  221. package/dist/src/setup/runner.js +1 -1
  222. package/dist/src/setup/scaffold/channels-catalog.d.ts +2 -0
  223. package/dist/src/setup/scaffold/channels-catalog.js +1 -1
  224. package/dist/src/setup/scaffold/create/add-to-project.d.ts +1 -0
  225. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  226. package/dist/src/setup/scaffold/create/project.d.ts +2 -0
  227. package/dist/src/setup/scaffold/create/project.js +6 -3
  228. package/dist/src/setup/scaffold/update/channels.d.ts +2 -0
  229. package/dist/src/setup/scaffold/update/channels.js +3 -3
  230. package/dist/src/setup/slack-connect-lifecycle.d.ts +97 -0
  231. package/dist/src/setup/slack-connect-lifecycle.js +1 -0
  232. package/dist/src/setup/slack-connect.d.ts +51 -0
  233. package/dist/src/setup/slack-connect.js +1 -0
  234. package/dist/src/setup/slackbot.d.ts +60 -47
  235. package/dist/src/setup/slackbot.js +1 -1
  236. package/dist/src/setup/state.d.ts +2 -1
  237. package/dist/src/setup/state.js +1 -1
  238. package/dist/src/setup/step.d.ts +4 -0
  239. package/dist/src/setup/validate-gateway-key.d.ts +30 -0
  240. package/dist/src/setup/validate-gateway-key.js +1 -0
  241. package/dist/src/setup/vercel-project.d.ts +19 -12
  242. package/dist/src/setup/vercel-project.js +1 -1
  243. package/dist/src/shared/agent-definition.d.ts +26 -0
  244. package/dist/src/shared/model-endpoint-status.d.ts +27 -0
  245. package/dist/src/shared/model-endpoint-status.js +1 -0
  246. package/dist/src/shared/sandbox-backend.d.ts +8 -2
  247. package/dist/src/shared/sandbox-definition.d.ts +4 -3
  248. package/dist/src/shared/sandbox-network-policy.d.ts +4 -2
  249. package/dist/src/shared/sandbox-session.d.ts +3 -2
  250. package/dist/src/svelte/index.js +1 -1
  251. package/dist/src/svelte/use-eve-agent.js +1 -1
  252. package/dist/src/vue/index.js +1 -1
  253. package/dist/src/vue/use-eve-agent.js +1 -1
  254. package/{dist/docs/public → docs}/getting-started.mdx +14 -4
  255. package/{dist/docs/public → docs}/guides/deployment.md +3 -3
  256. package/{dist/docs/public → docs}/guides/dev-tui.md +2 -2
  257. package/{dist/docs/public → docs}/reference/cli.md +2 -1
  258. package/{dist/docs/public → docs}/sandbox.mdx +39 -15
  259. package/package.json +11 -1
  260. package/dist/src/compiled/just-bash/LICENSE +0 -201
  261. package/dist/src/compiled/just-bash/index.d.ts +0 -139
  262. package/dist/src/compiled/just-bash/index.js +0 -2200
  263. package/dist/src/compiled/just-bash/network/types.d.ts +0 -155
  264. package/dist/src/public/sandbox/backends/local.d.ts +0 -16
  265. package/dist/src/public/sandbox/backends/local.js +0 -1
  266. package/dist/src/public/sandbox/local-sandbox.d.ts +0 -7
  267. /package/dist/src/public/sandbox/{local-sandbox.js → docker-sandbox.js} +0 -0
  268. /package/{dist/docs/public → docs}/README.md +0 -0
  269. /package/{dist/docs/public → docs}/agent-config.md +0 -0
  270. /package/{dist/docs/public → docs}/channels/custom.mdx +0 -0
  271. /package/{dist/docs/public → docs}/channels/discord.mdx +0 -0
  272. /package/{dist/docs/public → docs}/channels/eve.mdx +0 -0
  273. /package/{dist/docs/public → docs}/channels/github.mdx +0 -0
  274. /package/{dist/docs/public → docs}/channels/linear.mdx +0 -0
  275. /package/{dist/docs/public → docs}/channels/meta.json +0 -0
  276. /package/{dist/docs/public → docs}/channels/overview.mdx +0 -0
  277. /package/{dist/docs/public → docs}/channels/slack.mdx +0 -0
  278. /package/{dist/docs/public → docs}/channels/teams.mdx +0 -0
  279. /package/{dist/docs/public → docs}/channels/telegram.mdx +0 -0
  280. /package/{dist/docs/public → docs}/channels/twilio.mdx +0 -0
  281. /package/{dist/docs/public → docs}/concepts/context-control.md +0 -0
  282. /package/{dist/docs/public → docs}/concepts/default-harness.md +0 -0
  283. /package/{dist/docs/public → docs}/concepts/execution-model-and-durability.md +0 -0
  284. /package/{dist/docs/public → docs}/concepts/meta.json +0 -0
  285. /package/{dist/docs/public → docs}/concepts/security-model.md +0 -0
  286. /package/{dist/docs/public → docs}/concepts/sessions-runs-and-streaming.md +0 -0
  287. /package/{dist/docs/public → docs}/connections.mdx +0 -0
  288. /package/{dist/docs/public → docs}/evals/assertions.mdx +0 -0
  289. /package/{dist/docs/public → docs}/evals/cases.mdx +0 -0
  290. /package/{dist/docs/public → docs}/evals/judge.mdx +0 -0
  291. /package/{dist/docs/public → docs}/evals/meta.json +0 -0
  292. /package/{dist/docs/public → docs}/evals/overview.mdx +0 -0
  293. /package/{dist/docs/public → docs}/evals/reporters.mdx +0 -0
  294. /package/{dist/docs/public → docs}/evals/running.mdx +0 -0
  295. /package/{dist/docs/public → docs}/evals/targets.mdx +0 -0
  296. /package/{dist/docs/public → docs}/guides/auth-and-route-protection.md +0 -0
  297. /package/{dist/docs/public → docs}/guides/client/continuations.mdx +0 -0
  298. /package/{dist/docs/public → docs}/guides/client/messages.mdx +0 -0
  299. /package/{dist/docs/public → docs}/guides/client/meta.json +0 -0
  300. /package/{dist/docs/public → docs}/guides/client/output-schema.mdx +0 -0
  301. /package/{dist/docs/public → docs}/guides/client/overview.mdx +0 -0
  302. /package/{dist/docs/public → docs}/guides/client/streaming.mdx +0 -0
  303. /package/{dist/docs/public → docs}/guides/dynamic-capabilities.md +0 -0
  304. /package/{dist/docs/public → docs}/guides/dynamic-workflows.md +0 -0
  305. /package/{dist/docs/public → docs}/guides/frontend/meta.json +0 -0
  306. /package/{dist/docs/public → docs}/guides/frontend/nextjs.mdx +0 -0
  307. /package/{dist/docs/public → docs}/guides/frontend/nuxt.mdx +0 -0
  308. /package/{dist/docs/public → docs}/guides/frontend/overview.mdx +0 -0
  309. /package/{dist/docs/public → docs}/guides/frontend/sveltekit.mdx +0 -0
  310. /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-svelte.mdx +0 -0
  311. /package/{dist/docs/public → docs}/guides/frontend/use-eve-agent-vue.mdx +0 -0
  312. /package/{dist/docs/public → docs}/guides/hooks.md +0 -0
  313. /package/{dist/docs/public → docs}/guides/instrumentation.md +0 -0
  314. /package/{dist/docs/public → docs}/guides/meta.json +0 -0
  315. /package/{dist/docs/public → docs}/guides/remote-agents.md +0 -0
  316. /package/{dist/docs/public → docs}/guides/session-context.md +0 -0
  317. /package/{dist/docs/public → docs}/guides/state.md +0 -0
  318. /package/{dist/docs/public → docs}/instructions.mdx +0 -0
  319. /package/{dist/docs/public → docs}/introduction.md +0 -0
  320. /package/{dist/docs/public → docs}/meta.json +0 -0
  321. /package/{dist/docs/public → docs}/reference/meta.json +0 -0
  322. /package/{dist/docs/public → docs}/reference/project-layout.md +0 -0
  323. /package/{dist/docs/public → docs}/reference/typescript-api.md +0 -0
  324. /package/{dist/docs/public → docs}/schedules.mdx +0 -0
  325. /package/{dist/docs/public → docs}/skills.mdx +0 -0
  326. /package/{dist/docs/public → docs}/subagents.mdx +0 -0
  327. /package/{dist/docs/public → docs}/tools.mdx +0 -0
  328. /package/{dist/docs/public → docs}/tutorial/connect-a-warehouse.mdx +0 -0
  329. /package/{dist/docs/public → docs}/tutorial/first-agent.mdx +0 -0
  330. /package/{dist/docs/public → docs}/tutorial/guard-the-spend.mdx +0 -0
  331. /package/{dist/docs/public → docs}/tutorial/how-it-runs.mdx +0 -0
  332. /package/{dist/docs/public → docs}/tutorial/meta.json +0 -0
  333. /package/{dist/docs/public → docs}/tutorial/query-sample-data.mdx +0 -0
  334. /package/{dist/docs/public → docs}/tutorial/remember-definitions.mdx +0 -0
  335. /package/{dist/docs/public → docs}/tutorial/run-analysis.mdx +0 -0
  336. /package/{dist/docs/public → docs}/tutorial/ship-it.mdx +0 -0
  337. /package/{dist/docs/public → docs}/tutorial/team-playbooks.mdx +0 -0
@@ -1,6 +1,4 @@
1
1
  import { type AddChannelsDeps } from "../boxes/add-channels.js";
2
- import { type LinkProjectDeps } from "../boxes/link-project.js";
3
- import { type ResolveProvisioningDeps } from "../boxes/resolve-provisioning.js";
4
2
  import { inspectExistingChannelRegistrations } from "../channel-add-conflicts.js";
5
3
  import { detectDeployment } from "../project-resolution.js";
6
4
  import type { Prompter } from "../prompter.js";
@@ -9,35 +7,52 @@ export interface ChannelsFlowDeps {
9
7
  detectDeployment: typeof detectDeployment;
10
8
  inspectExistingChannelRegistrations: typeof inspectExistingChannelRegistrations;
11
9
  addChannels?: AddChannelsDeps;
12
- resolveProvisioning?: ResolveProvisioningDeps;
13
- linkProject?: LinkProjectDeps;
14
10
  }
15
11
  export type ChannelsFlowResult = {
16
12
  kind: "done";
17
13
  addedChannels: readonly string[];
14
+ } | {
15
+ /**
16
+ * The user chose "Deploy and chat" on the post-Slack "See it live"
17
+ * prompt. The caller deploys, then points them at this workspace.
18
+ */
19
+ kind: "deploy-and-chat";
20
+ addedChannels: readonly string[];
21
+ chat: {
22
+ chatUrl?: string;
23
+ workspaceName?: string;
24
+ };
18
25
  } | {
19
26
  kind: "cancelled";
27
+ } | {
28
+ kind: "failed";
29
+ addedChannels: readonly string[];
30
+ message: string;
20
31
  };
32
+ /** The post-Slack "see it live" chooser's title. */
33
+ export declare const SEE_IT_LIVE_MESSAGE = "See it live";
21
34
  /**
22
- * THE CHANNELS FLOW for the dev TUI's `/channels`: an action list that loops.
35
+ * THE CHANNELS FLOW for the dev TUI's `/channels`: a task list that loops.
23
36
  * Pick an unregistered channel, run its add sub-flow (Slack provisioning
24
- * included), and land back on the repainted list; "Done" or Esc leaves. A
25
- * cancelled sub-flow also returns to the list channel files only land in
26
- * the stack's final box, so the rows repaint unchanged. Esc on the list after
27
- * something was added reports the additions exactly like Done (they already
28
- * happened on disk); only an empty exit folds to cancelled.
37
+ * included), and land back on the repainted list with that channel checked;
38
+ * "Done" or Esc leaves. Filesystem effects can land before the runner applies
39
+ * their in-memory payload, so every cancelled or failed sub-flow re-inspects
40
+ * authored registrations and preserves a channel that became durable. Esc on
41
+ * the list after something was added reports the additions exactly like Done;
42
+ * only an empty exit folds to cancelled.
29
43
  *
30
44
  * Each pick reuses the `eve channels add` composition — the same conflict
31
45
  * validation, Vercel services config pinned on, and the default empty agent
32
46
  * name (the Slack connector slug falls back to the package.json name) — with
33
47
  * two TUI-specific differences: no trailing deploy box (the TUI exposes
34
- * `/deploy` as its own command), and Slack from an unlinked directory links
35
- * through the same team/project pickers as `/model`'s provider step instead of the bare
36
- * interactive `vercel link` fallback, which cannot own the terminal while the
37
- * TUI holds raw mode.
48
+ * `/deploy` as its own command), and no inline link pickers channels that
49
+ * provision against the Vercel project render disabled with a warning
50
+ * pointing at /model while the directory is unlinked, so a pick can never
51
+ * reach provisioning without a link.
38
52
  */
39
53
  export declare function runChannelsFlow(input: {
40
54
  appRoot: string;
41
55
  prompter: Prompter;
56
+ signal?: AbortSignal;
42
57
  deps?: Partial<ChannelsFlowDeps>;
43
58
  }): Promise<ChannelsFlowResult>;
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{addChannels}from"../boxes/add-channels.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";function channelListRows(e){let t=[];e.webRouteOwners.length>0&&t.push({value:`repl`,label:`Terminal UI`,locked:!0,lockedReason:`the REPL you're using now`});for(let n of SCAFFOLDABLE_CHANNELS){if(n.kind===`web`?e.webAppPresent:e.slackOwners.length>0){t.push({value:n.kind,label:n.label,locked:!0,lockedReason:`already added`});continue}let r=e.disabledChannelReasons[n.kind];if(r!==void 0){t.push({value:n.kind,label:n.label,disabled:!0,disabledReason:r});continue}let i={value:n.kind,label:n.label};n.hint!==void 0&&(i.hint=n.hint),t.push(i)}return t.push({value:`done`,label:`Done`}),t}async function runChannelsFlow(a){let{appRoot:o,prompter:s}=a,c={detectDeployment,inspectExistingChannelRegistrations,...a.deps};async function checkProject(e){let t=s.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let[l,u]=await checkProject(()=>Promise.all([c.detectDeployment(o),c.inspectExistingChannelRegistrations(o)])),d=u,f={...createDefaultSetupState(),project:projectResolutionFromDeployment(l),projectPath:{kind:`resolved`,inPlace:!0,path:o}},p={...resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(s)),prompter:s,targetDirectory:o,mode:{headless:!1},deps:c.resolveProvisioning}),shouldRun:e=>e.channelSelection.includes(`slack`)&&!isProjectResolved(e.project)};for(;;){let t;try{t=await s.select({message:CHANNELS_PROMPT_MESSAGE,options:channelListRows(d)})}catch(e){if(!(e instanceof WizardCancelledError))throw e;if(f.channels.length===0)return{kind:`cancelled`};break}if(t===`done`)break;if(t===`repl`)continue;let n=await runInteractive([selectChannels({asker:interactiveAsker(s),variant:`channels-add`,presetChannels:[t],validateSelection:e=>assertCanAddSelectedChannels(e,d)}),p,linkVercelProject({prompter:s,deps:c.linkProject}),addChannels({asker:interactiveAsker(s),prompter:s,configureVercelServices:!0,deps:c.addChannels})],f,prompterSink(s),{snapshot:snapshotSetupState});n.kind===`done`&&(f=n.state,d=await checkProject(()=>c.inspectExistingChannelRegistrations(o)))}return{kind:`done`,addedChannels:f.channels}}export{runChannelsFlow};
1
+ import{interactiveAsker}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{addChannels}from"../boxes/add-channels.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";import{toErrorMessage}from"#shared/errors.js";const SEE_IT_LIVE_MESSAGE=`See it live`;async function promptSeeItLive(e){try{return await e.select({message:SEE_IT_LIVE_MESSAGE,options:[{value:`deploy`,label:`Deploy and chat`},{value:`later`,label:`Later`}]})}catch(e){if(e instanceof WizardCancelledError)return`later`;throw e}}function channelAlreadyAdded(e,t){return t===`web`?e.webAppPresent:e.slackOwners.length>0}function appendChannel(e,t){return e.includes(t)?[...e]:[...e,t]}async function pickChannel(e,t,n){let r=channelListRows(t,n),i=!r.some(e=>e.value!==`done`&&e.completed!==!0&&e.disabled!==!0),a={message:CHANNELS_PROMPT_MESSAGE,options:r,hintLayout:`inline`};i&&(a.initialValue=`done`);try{return{kind:`picked`,value:await e.select(a)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}function channelLandedDuringSubflow(e,t,n){return!channelAlreadyAdded(e,n)&&channelAlreadyAdded(t,n)}function deployAndChatDetails(e){let t={};return e.slackChatUrl!==void 0&&(t.chatUrl=e.slackChatUrl),e.slackWorkspaceName!==void 0&&(t.workspaceName=e.slackWorkspaceName),t}function channelListRows(e,t){let n=[{value:`repl`,label:`Terminal UI`,completed:!0,focusHint:`Already installed`}];for(let r of SCAFFOLDABLE_CHANNELS){if(channelAlreadyAdded(e,r.kind)){n.push({value:r.kind,label:r.label,completed:!0,focusHint:`Already installed`});continue}let i=e.disabledChannelReasons[r.kind];if(i!==void 0){n.push({value:r.kind,label:r.label,disabled:!0,disabledReason:i});continue}if(r.requiresVercelProject===!0&&!t){n.push({value:r.kind,label:r.label,disabled:!0,disabledReason:`Requires Vercel account, see /model`,disabledReasonTone:`warning`});continue}let a={value:r.kind,label:r.label};r.hint!==void 0&&(a.hint=r.hint),n.push(a)}return n.push({value:`done`,label:`Done`}),n}async function runChannelsFlow(o){let{appRoot:s,prompter:c,signal:l}=o,u={detectDeployment,inspectExistingChannelRegistrations,...o.deps};async function checkProject(e){let t=c.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let[d,f]=await checkProject(()=>Promise.all([l===void 0?u.detectDeployment(s):u.detectDeployment(s,{signal:l}),u.inspectExistingChannelRegistrations(s)]));l?.throwIfAborted();let p=f,m={...createDefaultSetupState(),project:projectResolutionFromDeployment(d),projectPath:{kind:`resolved`,inPlace:!0,path:s}},h;for(;;){let t=await pickChannel(c,p,isProjectResolved(m.project));if(t.kind===`cancelled`){if(m.channels.length===0)return{kind:`cancelled`};break}let r=t.value;if(r===`done`)break;if(r===`repl`||channelAlreadyAdded(p,r))continue;let i=[selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:[r],validateSelection:e=>assertCanAddSelectedChannels(e,p)}),addChannels({asker:interactiveAsker(c),prompter:c,configureVercelServices:!0,deps:u.addChannels})],o;try{o=await runInteractive(i,m,prompterSink(c),{snapshot:snapshotSetupState,signal:l})}catch(e){let t=await checkProject(()=>u.inspectExistingChannelRegistrations(s));if(channelLandedDuringSubflow(p,t,r)){if(m={...m,channels:appendChannel(m.channels,r)},p=t,h=toErrorMessage(e),l?.aborted===!0)break;continue}throw e}if(o.kind===`done`){if(m=o.state,p=await checkProject(()=>u.inspectExistingChannelRegistrations(s)),l?.throwIfAborted(),r===`slack`&&m.slackbotAttached&&await promptSeeItLive(c)===`deploy`)return{kind:`deploy-and-chat`,addedChannels:m.channels,chat:deployAndChatDetails(m)}}else{let e=await checkProject(()=>u.inspectExistingChannelRegistrations(s));if(channelLandedDuringSubflow(p,e,r))return{kind:`done`,addedChannels:appendChannel(m.channels,r)};p=e}}return h===void 0?{kind:`done`,addedChannels:m.channels}:{kind:`failed`,addedChannels:m.channels,message:h}}export{SEE_IT_LIVE_MESSAGE,runChannelsFlow};
@@ -34,6 +34,7 @@ export type DeployFlowResult = {
34
34
  export declare function runDeployFlow(input: {
35
35
  appRoot: string;
36
36
  prompter: Prompter;
37
+ signal?: AbortSignal;
37
38
  /** False when no TTY: an unlinked directory refuses instead of prompting. */
38
39
  interactive: boolean;
39
40
  deps?: Partial<DeployFlowDeps>;
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i}=t,a={detectDeployment,...t.deps},o=r.log.spinner?.(`Checking the current Vercel link...`),s;try{s=projectResolutionFromDeployment(await a.detectDeployment(n))}finally{o?.stop()}let c=isProjectResolved(s);if(!c&&!i)return{kind:`needs-link`};let l=inProjectSetupState(n,s,{deploymentPending:!0}),u=c?[deployProject({prompter:r,headless:!i,deps:a.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:a.resolveProvisioning}),linkVercelProject({prompter:r,deps:a.linkProject}),deployProject({prompter:r,headless:!i,deps:a.deployProject})],d=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(u,l,d,{snapshot:snapshotSetupState})).project)};let f=await runInteractive(u,l,d,{snapshot:snapshotSetupState});return f.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(f.state.project)}}export{runDeployFlow};
1
+ import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=r.log.spinner?.(`Checking the current Vercel link...`),c;try{let e=a===void 0?await o.detectDeployment(n):await o.detectDeployment(n,{signal:a});a?.throwIfAborted(),c=projectResolutionFromDeployment(e)}finally{s?.stop()}let l=isProjectResolved(c);if(!l&&!i)return{kind:`needs-link`};let u=inProjectSetupState(n,c,{deploymentPending:!0}),d=l?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],f=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(d,u,f,{snapshot:snapshotSetupState,signal:a})).project)};let p=await runInteractive(d,u,f,{snapshot:snapshotSetupState,signal:a});return p.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(p.state.project)}}export{runDeployFlow};
@@ -39,5 +39,6 @@ export type LinkFlowResult = {
39
39
  export declare function runLinkFlow(input: {
40
40
  appRoot: string;
41
41
  prompter: Prompter;
42
+ signal?: AbortSignal;
42
43
  deps?: Partial<LinkFlowDeps>;
43
44
  }): Promise<LinkFlowResult>;
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{detectAiGateway,findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{applyAiGatewayCredential}from"../boxes/apply-ai-gateway-credential.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";async function runLinkFlow(r){let{appRoot:i,prompter:a}=r,o={detectProjectIdentity,findEnvFileWithKey,...r.deps},s=a.log.spinner?.(`Checking the current Vercel link...`),c;try{c=await o.detectProjectIdentity(i)}finally{s?.stop()}if(c===void 0){let[e,t]=await Promise.all([o.findEnvFileWithKey(i,`AI_GATEWAY_API_KEY`),o.findEnvFileWithKey(i,`VERCEL_OIDC_TOKEN`)]),n=e??t;a.log.message(n===void 0?`This directory is not linked to a Vercel project yet.`:`This directory is not linked to a Vercel project yet — the model currently runs on credentials from ${n}.`)}else{let e=c.teamName===void 0?c.projectName:`${c.projectName} in ${c.teamName}`;try{await a.select({message:`Already linked to ${e}`,options:[{value:`relink`,label:`Link to another project`,hint:`picks a new team and project`}]})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}let l=inProjectSetupState(i,{kind:`unresolved`});if((await runInteractive([resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(a)),prompter:a,targetDirectory:i,mode:{headless:!1},adoptExistingLink:!1,deps:o.resolveProvisioning}),linkVercelProject({prompter:a,deps:o.linkProject}),detectAiGateway(),applyAiGatewayCredential({prompter:a,deps:o.applyAiGatewayCredential})],l,prompterSink(a),{snapshot:snapshotSetupState})).kind===`cancelled`)return{kind:`cancelled`};let[u,d]=await Promise.all([o.findEnvFileWithKey(i,`VERCEL_OIDC_TOKEN`),o.findEnvFileWithKey(i,`AI_GATEWAY_API_KEY`)]);if(u===void 0&&d===void 0)a.log.warning("Linked, but no model credential landed in an env file (VERCEL_OIDC_TOKEN or AI_GATEWAY_API_KEY). Run `vercel env pull` once the project has AI Gateway access.");else{let e=[...u===void 0?[]:[`VERCEL_OIDC_TOKEN (${u})`],...d===void 0?[]:[`AI_GATEWAY_API_KEY (${d})`]].join(`, `);a.log.success(`Model credentials ready: ${e}.`)}a.log.message("A running `eve dev` reloads env files automatically — no restart needed.");let f={kind:`done`};return u===void 0?d!==void 0&&(f.credential=`AI_GATEWAY_API_KEY`):f.credential=`VERCEL_OIDC_TOKEN`,f}export{runLinkFlow};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker,withAnswers}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{detectAiGateway,findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{applyAiGatewayCredential}from"../boxes/apply-ai-gateway-credential.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";var import_picocolors=__toESM(require_picocolors(),1);async function runLinkFlow(e){let{appRoot:t,prompter:i,signal:a}=e,o={detectProjectIdentity,findEnvFileWithKey,...e.deps},s=i.log.spinner?.(`Checking the current Vercel link...`),c;try{c=a===void 0?await o.detectProjectIdentity(t):await o.detectProjectIdentity(t,{signal:a}),a?.throwIfAborted()}finally{s?.stop()}if(c===void 0){let[e,n]=await Promise.all([o.findEnvFileWithKey(t,`AI_GATEWAY_API_KEY`),o.findEnvFileWithKey(t,`VERCEL_OIDC_TOKEN`)]),r=e??n;r!==void 0&&i.log.message(`This directory is not linked to a Vercel project yet — the model currently runs on credentials from ${r}.`)}else{let e=c.teamName===void 0?import_picocolors.default.bold(c.projectName):`${import_picocolors.default.bold(c.projectName)} in ${import_picocolors.default.bold(c.teamName)}`;try{if(await i.select({message:`This directory is already linked to\n${e}`,options:[{value:`relink`,label:`Link to another project`},{value:`dismiss`,label:`Dismiss`}]})===`dismiss`)return{kind:`cancelled`}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}let l=inProjectSetupState(t,{kind:`unresolved`});if((await runInteractive([resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(i)),prompter:i,targetDirectory:t,mode:{headless:!1},adoptExistingLink:!1,projectSelection:`existing-only`,deps:o.resolveProvisioning}),linkVercelProject({prompter:i,deps:o.linkProject}),detectAiGateway(),applyAiGatewayCredential({prompter:i,deps:o.applyAiGatewayCredential})],l,prompterSink(i),{snapshot:snapshotSetupState,signal:a})).kind===`cancelled`)return{kind:`cancelled`};let[u,d]=await Promise.all([o.findEnvFileWithKey(t,`VERCEL_OIDC_TOKEN`),o.findEnvFileWithKey(t,`AI_GATEWAY_API_KEY`)]);a?.throwIfAborted(),u===void 0&&d===void 0&&i.log.warning("Linked, but no model credential landed in an env file (VERCEL_OIDC_TOKEN or AI_GATEWAY_API_KEY). Run `vercel env pull` once the project has AI Gateway access.");let f={kind:`done`};return u===void 0?d!==void 0&&(f.credential=`AI_GATEWAY_API_KEY`):f.credential=`VERCEL_OIDC_TOKEN`,f}export{runLinkFlow};
@@ -1,10 +1,26 @@
1
1
  import { type SelectModelDeps } from "../boxes/select-model.js";
2
+ import { type ProjectDetectionOptions } from "../project-resolution.js";
3
+ import type { ModelRouting } from "#shared/agent-definition.js";
2
4
  import type { Prompter } from "../prompter.js";
3
5
  import { runVercelFlow } from "./vercel.js";
6
+ /** The current model id, its routing, and whether `/model` can rewrite it. */
7
+ export interface CurrentAgentModel {
8
+ id: string | null;
9
+ routing: ModelRouting | null;
10
+ /**
11
+ * The authored `model` is a string the source editor can rewrite. False for a
12
+ * source-backed SDK model call (`gateway(...)`, `anthropic(...)`), which is
13
+ * not a string literal — independent of how the model routes.
14
+ */
15
+ editable: boolean;
16
+ }
4
17
  /** Injected for tests; defaults to the real reads, fetches, and source edit. */
5
18
  export interface ModelFlowDeps {
6
- /** Reads the model the runtime currently serves; null before first compile. */
7
- readCurrentModel: (appRoot: string) => Promise<string | null>;
19
+ /**
20
+ * Reads the model the runtime currently serves and how it routes; both null
21
+ * before the first compile.
22
+ */
23
+ readCurrentModel: (appRoot: string) => Promise<CurrentAgentModel>;
8
24
  /** Applies the picked slug to authored source. */
9
25
  applyModel: (input: {
10
26
  appRoot: string;
@@ -13,7 +29,7 @@ export interface ModelFlowDeps {
13
29
  /** Catalog fetch behind the shared model picker. */
14
30
  selectModel?: SelectModelDeps;
15
31
  /** Reads how the model is backed right now, for the menu's provider row. */
16
- detectProviderStatus: (appRoot: string) => Promise<ModelProviderStatus>;
32
+ detectProviderStatus: typeof detectModelProviderStatus;
17
33
  /** The provider sub-flow behind the menu's provider row. */
18
34
  runVercelFlow: typeof runVercelFlow;
19
35
  }
@@ -55,14 +71,14 @@ export type ModelFlowResult = {
55
71
  /** The last provider sub-flow outcome, when one ran to completion. */
56
72
  providerOutcome?: ModelProviderOutcome;
57
73
  };
58
- export declare const MODEL_MENU_MESSAGE = "Configure the agent's model";
74
+ export declare const MODEL_MENU_MESSAGE = "";
59
75
  /**
60
76
  * Reads the provider status the menu shows. Detection order matters: a linked
61
77
  * project subsumes any pulled credential (the link is what the user manages),
62
78
  * and `AI_GATEWAY_API_KEY` outranks `VERCEL_OIDC_TOKEN` because it is the one
63
79
  * the provider sub-flow's own-key branch writes.
64
80
  */
65
- export declare function detectModelProviderStatus(appRoot: string): Promise<ModelProviderStatus>;
81
+ export declare function detectModelProviderStatus(appRoot: string, options?: ProjectDetectionOptions): Promise<ModelProviderStatus>;
66
82
  /**
67
83
  * THE MODEL FLOW for the dev TUI's `/model`: a two-row action menu that
68
84
  * loops, uniting the model pick and the provider setup behind one entry
@@ -72,7 +88,7 @@ export declare function detectModelProviderStatus(appRoot: string): Promise<Mode
72
88
  * choice into `agent.ts` (activation is the dev server's HMR watcher).
73
89
  * The provider row runs {@link runVercelFlow} — the provider gate (AI
74
90
  * Gateway or your own), then link-or-paste-a-key.
75
- * Each sub-flow lands back on the repainted menu; Esc leaves. A
91
+ * Each sub-flow lands back on the repainted menu; Done or Esc leaves. A
76
92
  * cancelled sub-flow also returns to the menu. Esc after something completed
77
93
  * reports it exactly like the channels flow (the effects already happened);
78
94
  * only an empty exit folds to cancelled.
@@ -80,6 +96,7 @@ export declare function detectModelProviderStatus(appRoot: string): Promise<Mode
80
96
  export declare function runModelFlow(input: {
81
97
  appRoot: string;
82
98
  prompter: Prompter;
99
+ signal?: AbortSignal;
83
100
  deps?: Partial<ModelFlowDeps>;
84
101
  }): Promise<ModelFlowResult>;
85
102
  /** The outcome of applying a model slug to the agent's authored source. */
@@ -110,3 +127,10 @@ export declare function changeAgentModel(input: {
110
127
  readonly appRoot: string;
111
128
  readonly slug: string;
112
129
  }): Promise<ApplyModelOutcome>;
130
+ /**
131
+ * Refusal message when `/model` can't rewrite the model — it is a source-backed
132
+ * SDK model call (`gateway(...)`, `anthropic(...)`), not a string literal — or
133
+ * null when the model is an editable string. Editability is independent of
134
+ * routing: a `gateway(...)` call is gateway-routed yet still uneditable here.
135
+ */
136
+ export declare function modelChangeRefusalForUneditableModel(appRoot: string): Promise<string | null>;
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{WizardCancelledError}from"../step.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runVercelFlow}from"./vercel.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const MODEL_MENU_MESSAGE=`Configure the agent's model`;function providerStatusHint(e,t=e=>e){return e.kind===`gateway-project`?`AI Gateway (Linked to ${e.teamName===void 0?t(e.projectName):`${t(e.projectName)} in ${t(e.teamName)}`})`:`AI Gateway (${e.envKey} in ${e.envFile})`}function modelMenuRows(e,t){let n={value:`model`,label:`Change model`};return e!==null&&(n.hint=e),[n,t.kind===`unset`?{value:`provider`,label:import_picocolors.default.bold(import_picocolors.default.yellow(`Configure provider`)),hint:`Required to enable the agent`}:{value:`provider`,label:`Change provider`,hint:providerStatusHint(t,import_picocolors.default.bold)}]}function applyModelNotice(e){switch(e.kind){case`changed`:return{tone:`success`,text:`Model changed to ${e.to}`};case`unchanged`:return{tone:`info`,text:`Model is already ${e.model}`};case`rejected`:return{tone:`warning`,text:e.message}}}function providerNotice(e){return e.kind===`unset`?{tone:`warning`,text:`Provider updated — no gateway credential detected yet.`}:{tone:`success`,text:`Provider changed to ${providerStatusHint(e)}`}}async function detectModelProviderStatus(e){let[t,n,i]=await Promise.all([detectProjectIdentity(e),findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(t!==void 0){let e={kind:`gateway-project`,projectName:t.projectName};return t.teamName!==void 0&&(e.teamName=t.teamName),e}return n===void 0?i===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:i}:{kind:`gateway-key`,envKey:`AI_GATEWAY_API_KEY`,envFile:n}}async function runModelFlow(e){let{appRoot:t,prompter:n}=e,r={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps};async function checkProject(e){let t=n.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let[i,a]=await checkProject(()=>Promise.all([r.readCurrentModel(t),r.detectProviderStatus(t)])),o,s,l,u;for(;;){let e;try{e=await n.select({message:MODEL_MENU_MESSAGE,options:modelMenuRows(i,a),layout:`stacked`,notices:[l,u].filter(e=>e!==void 0)})}catch(e){if(!(e instanceof WizardCancelledError))throw e;break}if(e===`model`){let e=await pickModelFromCatalog({appRoot:t,prompter:n,current:i,deps:r.selectModel});e!==void 0&&(o=await r.applyModel({appRoot:t,slug:e}),l=applyModelNotice(o),o.kind===`changed`&&(i=o.to));continue}let d=await r.runVercelFlow({appRoot:t,prompter:n});d.kind===`cancelled`||`outcome`in d||(a=await checkProject(()=>r.detectProviderStatus(t)),s={status:a},d.credential!==void 0&&(s.credential=d.credential),u=providerNotice(a))}if(o===void 0&&s===void 0)return{kind:`cancelled`};let d={kind:`done`};return o!==void 0&&(d.modelMessage=formatApplyModelOutcome(o)),s!==void 0&&(d.providerOutcome=s),d}async function pickModelFromCatalog(e){let{appRoot:t,prompter:r,current:a}=e,c=e.deps?.fetchModels??fetchGatewayCatalog,f={asker:interactiveAsker(r),deps:{fetchModels:async()=>{let e=r.log.spinner?.(`Loading the model catalog...`);try{return await c()}finally{e?.stop()}}}};a!==null&&(f.defaultModel=a);let p=await runInteractive([selectModel(f)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(r),{snapshot:snapshotSetupState});return p.kind===`cancelled`?void 0:p.state.modelId}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model \`${e.to}\` · live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return{kind:`rejected`,message:r};let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`}:a.from===a.to?{kind:`unchanged`,model:a.to}:{kind:`changed`,to:a.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e);return t?.manifest.config.model.id??null}catch{return null}}export{MODEL_MENU_MESSAGE,changeAgentModel,detectModelProviderStatus,formatApplyModelOutcome,runModelFlow};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{interactiveAsker}from"../ask.js";import{detectProjectIdentity}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{findEnvFileWithKey}from"../boxes/detect-ai-gateway.js";import{fetchGatewayCatalog,selectModel}from"../boxes/select-model.js";import{runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";import{runVercelFlow}from"./vercel.js";import{join}from"node:path";import{discoverAgent}from"#discover/discover-agent.js";import{inspectApplication}from"#services/inspect-application.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{createCompiledRuntimeModelCatalogLoader}from"#compiler/model-catalog.js";import{createStaticSourceChange}from"#source-change/static-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const MODEL_MENU_MESSAGE=``;function providerStatusHint(e,t=e=>e){return e.kind===`gateway-project`?`AI Gateway (Linked to ${e.teamName===void 0?t(e.projectName):`${t(e.projectName)} in ${t(e.teamName)}`})`:`AI Gateway (${e.envKey} in ${e.envFile})`}function modelMenuRows(e,t,n,r){let i;r?(i={value:`model`,label:`Change model`},e!==null&&(i.hint=e)):i={value:`model`,label:`Change model`,disabled:!0,description:`Set via an SDK model call in agent.ts; edit the source to change it`};let a;return a=n?.kind===`external`?{value:`provider`,label:`Change provider`,disabled:!0,description:`Disabled in external endpoint mode`}:t.kind===`unset`?{value:`provider`,label:import_picocolors.default.bold(import_picocolors.default.yellow(`Configure provider`)),hint:`Required to enable the agent`,accent:`warning`}:{value:`provider`,label:`Change provider`,hint:providerStatusHint(t,import_picocolors.default.bold)},[i,a,{value:`done`,label:`Done`}]}function applyModelNotice(e){switch(e.kind){case`changed`:return{tone:`success`,text:`Model changed to ${e.to}`};case`unchanged`:return{tone:`info`,text:`Model is already ${e.model}`};case`rejected`:return{tone:`warning`,text:e.message}}}function providerNotice(e){return e.kind===`unset`?{tone:`warning`,text:`Provider updated — no gateway credential detected yet.`}:{tone:`success`,text:`Connected to AI Gateway`}}async function detectModelProviderStatus(e,t={}){let[n,i,a]=await Promise.all([detectProjectIdentity(e,t),findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`),findEnvFileWithKey(e,`VERCEL_OIDC_TOKEN`)]);if(n!==void 0){let e={kind:`gateway-project`,projectName:n.projectName};return n.teamName!==void 0&&(e.teamName=n.teamName),e}return i===void 0?a===void 0?{kind:`unset`}:{kind:`gateway-key`,envKey:`VERCEL_OIDC_TOKEN`,envFile:a}:{kind:`gateway-key`,envKey:`AI_GATEWAY_API_KEY`,envFile:i}}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={readCurrentModel:readCurrentAgentModel,applyModel:changeAgentModel,detectProviderStatus:detectModelProviderStatus,runVercelFlow,...e.deps};async function checkProject(e){let t=n.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let detectProvider=()=>r===void 0?i.detectProviderStatus(t):i.detectProviderStatus(t,{signal:r}),[{id:o,routing:s,editable:c},l]=await checkProject(()=>Promise.all([i.readCurrentModel(t),detectProvider()]));r?.throwIfAborted();let u,d,p,m,h=s?.kind===`external`?{tone:`warning`,text:"`agent.ts` specifies a model provider directly. In-TUI configuration is restricted to AI Gateway endpoints."}:void 0,g=l.kind===`unset`&&s?.kind!==`external`?`provider`:c?`model`:s?.kind===`external`?`done`:`provider`;for(;;){let e;try{e=await n.select({message:``,options:modelMenuRows(o,l,s,c),hintLayout:`stacked`,initialValue:g,notices:[h,p,m].filter(e=>e!==void 0)})}catch(e){if(!(e instanceof WizardCancelledError))throw e;break}if(e===`done`)break;if(e===`model`){let e=await pickModelFromCatalog({appRoot:t,prompter:n,current:o,signal:r,deps:i.selectModel});e===void 0?g=`model`:(r?.throwIfAborted(),u=await i.applyModel({appRoot:t,slug:e}),r?.throwIfAborted(),p=applyModelNotice(u),u.kind===`changed`&&(o=u.to),g=`done`);continue}let f=await i.runVercelFlow({appRoot:t,prompter:n,signal:r});if(r?.throwIfAborted(),f.kind===`cancelled`){g=`provider`;continue}if(`outcome`in f){g=`done`;continue}l=await checkProject(detectProvider),r?.throwIfAborted(),d={status:l},f.credential!==void 0&&(d.credential=f.credential),m=providerNotice(l),g=`done`}if(u===void 0&&d===void 0)return{kind:`cancelled`};let _={kind:`done`};return u!==void 0&&(_.modelMessage=formatApplyModelOutcome(u)),d!==void 0&&(_.providerOutcome=d),_}async function pickModelFromCatalog(e){let{appRoot:t,prompter:r,current:a,signal:o}=e,f=e.deps?.fetchModels??fetchGatewayCatalog,p={asker:interactiveAsker(r),deps:{fetchModels:async e=>{let t=r.log.spinner?.(`Loading the model catalog...`);try{return await f(e)}finally{t?.stop()}}}};a!==null&&(p.defaultModel=a);let m=await runInteractive([selectModel(p)],inProjectSetupState(t,{kind:`unresolved`}),prompterSink(r),{snapshot:snapshotSetupState,signal:o});return m.kind===`cancelled`?void 0:m.state.modelId}function formatApplyModelOutcome(e){switch(e.kind){case`changed`:return`Model changed to ${import_picocolors.default.bold(e.to)}. Live on your next prompt.`;case`unchanged`:return`Model is already \`${e.model}\`.`;case`rejected`:return e.message}}async function changeAgentModel(e){let{appRoot:t,slug:n}=e,r=await validateModelSlug(t,n);if(r!==null)return{kind:`rejected`,message:r};let{manifest:i}=await discoverAgent({agentRoot:join(t,`agent`),appRoot:t}),a=await createStaticSourceChange(i).updateModelName(n);return a.kind===`bail`?{kind:`rejected`,message:`Couldn't edit ${a.at.logicalPath}: ${a.reason}. Change \`model\` by hand.`}:a.from===a.to?{kind:`unchanged`,model:a.to}:{kind:`changed`,to:a.to}}async function validateModelSlug(e,t){if(!t.includes(`/`))return`\`${t}\` isn't a provider/model id (e.g. anthropic/claude-sonnet-4.6).`;let n=createCompiledRuntimeModelCatalogLoader(e);try{if(await n.getModelLimits(formatLanguageModelGatewayId(t))===null)return`I couldn't confirm \`${t}\` in the AI Gateway model catalog, so I didn't change agent.ts.`}catch{return null}return null}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e),n=t?.manifest.config.model;return{id:n?.id??null,routing:n?.routing??null,editable:n!==void 0&&n.source===void 0}}catch{return{id:null,routing:null,editable:!1}}}async function modelChangeRefusalForUneditableModel(e){let{editable:t,routing:n}=await readCurrentAgentModel(e);return t?null:`Model is set via ${n?.kind===`external`?`the external provider \`${n.provider}\``:`an SDK model call`} in agent.ts, not a string literal; /model can't rewrite it. Edit \`model\` in agent.ts.`}export{MODEL_MENU_MESSAGE,changeAgentModel,detectModelProviderStatus,formatApplyModelOutcome,modelChangeRefusalForUneditableModel,runModelFlow};
@@ -1,14 +1,16 @@
1
1
  import { appendEnv } from "../append-env.js";
2
2
  import type { Prompter } from "../prompter.js";
3
+ import { validateGatewayApiKey } from "../validate-gateway-key.js";
3
4
  import { runLinkFlow, type LinkFlowResult } from "./link.js";
4
5
  export declare const PROVIDER_QUESTION = "Which model provider do you want to use?";
5
6
  export declare const CONNECTION_QUESTION = "How do you want to connect to AI Gateway?";
6
7
  export declare const EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE = "Using another model provider";
7
8
  export declare const EXTERNAL_PROVIDER_INSTRUCTIONS: readonly string[];
8
- /** Injected for tests; defaults to the real link flow and env write. */
9
+ /** Injected for tests; defaults to the real link flow, env write, and key check. */
9
10
  export interface VercelFlowDeps {
10
11
  runLinkFlow: typeof runLinkFlow;
11
12
  appendEnv: typeof appendEnv;
13
+ validateGatewayApiKey: typeof validateGatewayApiKey;
12
14
  }
13
15
  export type VercelFlowResult = LinkFlowResult | {
14
16
  kind: "done";
@@ -27,5 +29,6 @@ export type VercelFlowResult = LinkFlowResult | {
27
29
  export declare function runVercelFlow(input: {
28
30
  appRoot: string;
29
31
  prompter: Prompter;
32
+ signal?: AbortSignal;
30
33
  deps?: Partial<VercelFlowDeps>;
31
34
  }): Promise<VercelFlowResult>;
@@ -1,2 +1,2 @@
1
- import{appendEnv}from"../append-env.js";import{WizardCancelledError}from"../step.js";import{runLinkFlow}from"./link.js";import{join}from"node:path";const AI_GATEWAY_ENV_KEY=`AI_GATEWAY_API_KEY`,ENV_FILE_NAME=`.env.local`,PROVIDER_QUESTION=`Which model provider do you want to use?`,CONNECTION_QUESTION=`How do you want to connect to AI Gateway?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${ENV_FILE_NAME} — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.`,'In agent/agent.ts, set `model` to a provider-authored model — e.g. `anthropic("claude-opus-4.8")` from `@ai-sdk/anthropic`.',`See https://beta.eve.dev/docs/agent-config for details.`,"A running `eve dev` reloads env files automatically — no restart needed."];async function runVercelFlow(t){let{appRoot:n,prompter:r}=t,i={runLinkFlow,appendEnv,...t.deps},a,o;try{a=await r.select({message:PROVIDER_QUESTION,options:[{value:`gateway`,label:`Vercel AI Gateway`,hint:`one key, every model`},{value:`other`,label:`Something else`,hint:`use your own provider credentials`}]}),a===`gateway`&&(o=await r.select({message:CONNECTION_QUESTION,options:[{value:`project`,label:`Connect via a project`,hint:`vercel link + env pull`},{value:`own-key`,label:`Use my own key`,hint:`paste an ${AI_GATEWAY_ENV_KEY}`}]}))}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}if(a===`other`)return r.acknowledge?await r.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):r.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
2
- `),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`done`,outcome:`external-provider`};if(o===`own-key`){let e;try{e=await r.password({message:`Enter your ${AI_GATEWAY_ENV_KEY}`,validate:e=>e.trim().length===0?`API key cannot be empty.`:void 0})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}return await i.appendEnv(join(n,ENV_FILE_NAME),{[AI_GATEWAY_ENV_KEY]:e.trim()},{force:!0}),r.log.success(`Saved ${AI_GATEWAY_ENV_KEY} to ${ENV_FILE_NAME}.`),r.log.message("A running `eve dev` reloads env files automatically — no restart needed."),{kind:`done`,credential:AI_GATEWAY_ENV_KEY}}return await i.runLinkFlow({appRoot:n,prompter:r})}export{CONNECTION_QUESTION,EXTERNAL_PROVIDER_INSTRUCTIONS,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,PROVIDER_QUESTION,runVercelFlow};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{appendEnv}from"../append-env.js";import{WizardCancelledError}from"../step.js";import{runLinkFlow}from"./link.js";import{validateGatewayApiKey}from"../validate-gateway-key.js";import{join}from"node:path";var import_picocolors=__toESM(require_picocolors(),1);const AI_GATEWAY_ENV_KEY=`AI_GATEWAY_API_KEY`,ENV_FILE_NAME=`.env.local`,PROVIDER_QUESTION=`Which model provider do you want to use?`,CONNECTION_QUESTION=`How do you want to connect to AI Gateway?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${ENV_FILE_NAME} — e.g. ANTHROPIC_API_KEY or OPENAI_API_KEY.`,'In agent/agent.ts, set `model` to a provider-authored model — e.g. `anthropic("claude-opus-4.8")` from `@ai-sdk/anthropic`.',`See https://beta.eve.dev/docs/agent-config for details.`,"A running `eve dev` reloads env files automatically — no restart needed."];async function runVercelFlow(e){let{appRoot:t,prompter:a,signal:o}=e,s={runLinkFlow,appendEnv,validateGatewayApiKey,...e.deps},c,l;try{c=await a.select({message:PROVIDER_QUESTION,options:[{value:`gateway`,label:`Vercel AI Gateway`,hint:`one key, every model`},{value:`other`,label:`Something else`,hint:`use your own provider credentials`}],hintLayout:`stacked`}),c===`gateway`&&(l=await a.select({message:CONNECTION_QUESTION,options:[{value:`project`,label:`Connect via a project`,hint:`vercel link + env pull`},{value:`own-key`,label:`Use my own key`,hint:`paste an ${AI_GATEWAY_ENV_KEY}`}],hintLayout:`stacked`}))}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}if(c===`other`)return a.acknowledge?await a.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):a.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
2
+ `),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`done`,outcome:`external-provider`};if(l===`own-key`)for(;;){let e;try{e=await a.password({message:`Enter your ${AI_GATEWAY_ENV_KEY}`,validate:e=>e.trim().length===0?`API key cannot be empty.`:void 0})}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}o?.throwIfAborted();let n=e.trim(),r=a.log.spinner?.(`Validating…`),i;try{i=await s.validateGatewayApiKey(n,o)}finally{r?.stop()}if(o?.throwIfAborted(),i.kind===`invalid`){a.log.error(`${i.message} Check the key and try again, or Esc to cancel.`);continue}return i.kind===`inconclusive`?a.log.warning(`Couldn't reach the gateway to validate (${i.message}). Saving the key anyway.`):a.log.success(`${import_picocolors.default.green(`✓`)} ${import_picocolors.default.bold(`Valid key`)}`),await s.appendEnv(join(t,ENV_FILE_NAME),{[AI_GATEWAY_ENV_KEY]:n},{force:!0}),o?.throwIfAborted(),a.log.success(`Saved ${AI_GATEWAY_ENV_KEY} to ${ENV_FILE_NAME}.`),{kind:`done`,credential:AI_GATEWAY_ENV_KEY}}else return await s.runLinkFlow({appRoot:t,prompter:a,signal:o})}export{CONNECTION_QUESTION,EXTERNAL_PROVIDER_INSTRUCTIONS,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,PROVIDER_QUESTION,runVercelFlow};
@@ -1 +1 @@
1
- import{InteractionRequired}from"./ask.js";import{runVercel}from"./primitives/run-vercel.js";import{detectDeployment,detectProjectResolution,projectProductionUrlFromResolution}from"./project-resolution.js";import{provisionSlackbot,reconcileSlackUid}from"./slackbot.js";import{createDefaultSetupState,requireProjectPath,snapshotSetupState}from"./state.js";import{setupConnectionConnector}from"./connection-connector.js";import{linkProject,requireAuth,resolveProjectByNameOrId,resolveTeam}from"./vercel-project.js";import{runVercelEnvPull}from"./run-vercel-link.js";import{createPromptCommandOutput}from"./cli/command-output.js";import"./cli/index.js";import{WizardCancelledError}from"./step.js";import{runHeadless,runInteractive}from"./runner.js";import{HeadlessPromptError,createHeadlessPrompter,formatHeadlessEvent}from"./headless.js";import{createPrompter}from"./prompter.js";import{composeOnboardingBoxes}from"./onboarding.js";import{getPackageManagerStrategy}from"./primitives/pm/index.js";import{runPackageManagerInstall,runPnpmInstall,spawnPackageManager,spawnPnpm}from"./primitives/pm/run.js";import"./primitives/index.js";export{HeadlessPromptError,InteractionRequired,WizardCancelledError,composeOnboardingBoxes,createDefaultSetupState,createHeadlessPrompter,createPromptCommandOutput,createPrompter,detectDeployment,detectProjectResolution,formatHeadlessEvent,getPackageManagerStrategy,linkProject,projectProductionUrlFromResolution,provisionSlackbot,reconcileSlackUid,requireAuth,requireProjectPath,resolveProjectByNameOrId,resolveTeam,runHeadless,runInteractive,runPackageManagerInstall,runPnpmInstall,runVercel,runVercelEnvPull,setupConnectionConnector,snapshotSetupState,spawnPackageManager,spawnPnpm};
1
+ import{InteractionRequired}from"./ask.js";import{runVercel}from"./primitives/run-vercel.js";import{detectDeployment,detectProjectResolution,projectProductionUrlFromResolution}from"./project-resolution.js";import{provisionSlackbot,reconcileSlackUid}from"./slackbot.js";import{createDefaultSetupState,requireProjectPath,snapshotSetupState}from"./state.js";import{WizardCancelledError}from"./step.js";import{setupConnectionConnector}from"./connection-connector.js";import{linkProject,requireAuth,resolveProjectByNameOrId,resolveTeam}from"./vercel-project.js";import{runVercelEnvPull}from"./run-vercel-link.js";import{createPromptCommandOutput}from"./cli/command-output.js";import"./cli/index.js";import{runHeadless,runInteractive}from"./runner.js";import{HeadlessPromptError,createHeadlessPrompter,formatHeadlessEvent}from"./headless.js";import{createPrompter}from"./prompter.js";import{composeOnboardingBoxes}from"./onboarding.js";import{getPackageManagerStrategy}from"./primitives/pm/index.js";import{runPackageManagerInstall,runPnpmInstall,spawnPackageManager,spawnPnpm}from"./primitives/pm/run.js";import"./primitives/index.js";export{HeadlessPromptError,InteractionRequired,WizardCancelledError,composeOnboardingBoxes,createDefaultSetupState,createHeadlessPrompter,createPromptCommandOutput,createPrompter,detectDeployment,detectProjectResolution,formatHeadlessEvent,getPackageManagerStrategy,linkProject,projectProductionUrlFromResolution,provisionSlackbot,reconcileSlackUid,requireAuth,requireProjectPath,resolveProjectByNameOrId,resolveTeam,runHeadless,runInteractive,runPackageManagerInstall,runPnpmInstall,runVercel,runVercelEnvPull,setupConnectionConnector,snapshotSetupState,spawnPackageManager,spawnPnpm};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Parses a candidate string into a normalized web URL, or `undefined` if it is
3
+ * not a valid `http(s)` URL. Uses the URL parser rather than a pattern so the
4
+ * accept/reject decision matches what a browser would resolve.
5
+ */
6
+ export declare function parseWebUrl(candidate: string): string | undefined;
7
+ /**
8
+ * Opens a URL in the user's default browser, best-effort and fire-and-forget.
9
+ * Used where Eve owns the hand-off (e.g. pointing the user at their Slack
10
+ * workspace after a deploy) rather than relying on a child CLI to open it. A
11
+ * missing or failing opener is never fatal: callers still print the URL for the
12
+ * user to open by hand.
13
+ */
14
+ export declare function openUrl(url: string): void;
@@ -0,0 +1 @@
1
+ import{spawn}from"node:child_process";function osOpenCommand(e){switch(process.platform){case`darwin`:return{command:`open`,args:[e]};case`win32`:return{command:`cmd`,args:[`/c`,`start`,``,e]};default:return{command:`xdg-open`,args:[e]}}}function parseWebUrl(e){let t=URL.parse(e.trim());if(t&&(t.protocol===`http:`||t.protocol===`https:`))return t.href}function openUrl(t){if(parseWebUrl(t)===void 0)return;let{command:n,args:r}=osOpenCommand(t);try{let t=spawn(n,r,{stdio:`ignore`,detached:!0});t.on(`error`,()=>{}),t.unref()}catch{}}export{openUrl,parseWebUrl};
@@ -1,5 +1,14 @@
1
1
  export declare const PNPM_WORKSPACE_PATH = "pnpm-workspace.yaml";
2
+ export declare const PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS: readonly ["list", "--depth", "-1", "--json"];
2
3
  export declare const PNPM_WORKSPACE_CONTENT: string;
4
+ /** Whether pnpm can walk from this project into a parent-owned workspace. */
5
+ export declare function hasAncestorPnpmWorkspace(projectRoot: string): boolean;
6
+ /**
7
+ * Reads `pnpm list --depth -1 --json` and answers whether the ancestor
8
+ * workspace explicitly includes `projectRoot`. `undefined` means the output
9
+ * was not trustworthy enough to choose an install mode.
10
+ */
11
+ export declare function pnpmWorkspaceClaimsProject(stdout: string, projectRoot: string): boolean | undefined;
3
12
  export declare const pnpmPackageManager: {
4
13
  kind: "pnpm";
5
14
  scaffoldFiles: {
@@ -1,8 +1,8 @@
1
- import{pathExists}from"../../path-exists.js";import{extname,join}from"node:path";import{existsSync}from"node:fs";import{readFile,writeFile}from"node:fs/promises";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_CONTENT=[`minimumReleaseAgeExclude:`,` - eve`,`allowBuilds:`,` sharp: false`,`# Compatibility for Eve releases with an incomplete runtime manifest.`,`packageExtensions:`,` "eve@>=0.6.0-beta.13 <=0.7.0":`,` dependencies:`,` oxc-parser: 0.134.0`,``].join(`
1
+ import{pathExists}from"../../path-exists.js";import{dirname,extname,join,resolve}from"node:path";import{existsSync,realpathSync}from"node:fs";import{readFile,writeFile}from"node:fs/promises";const PNPM_WORKSPACE_PATH=`pnpm-workspace.yaml`,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS=[`list`,`--depth`,`-1`,`--json`],PNPM_WORKSPACE_CONTENT=[`minimumReleaseAgeExclude:`,` - eve`,`allowBuilds:`,` sharp: false`,`# Compatibility for Eve releases with an incomplete runtime manifest.`,`packageExtensions:`,` "eve@>=0.6.0-beta.13 <=0.7.0":`,` dependencies:`,` oxc-parser: 0.134.0`,``].join(`
2
2
  `),EVE_RELEASE_AGE_EXCLUSION=` - eve`,SHARP_BUILD_POLICY=` sharp: false`;function findYamlBlockEnd(e,t){let n=t+1;for(;n<e.length;){let t=e[n]??``;if(t.length>0&&!t.startsWith(` `)&&!t.startsWith(` `))break;n+=1}return n}function withSharpBuildPolicy(e){let t=e.endsWith(`
3
3
  `)?e:`${e}\n`,n=t.split(`
4
4
  `),r=n.findIndex(e=>e===`allowBuilds:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}allowBuilds:\n${SHARP_BUILD_POLICY}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>/^\s+sharp:/.test(e)))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,SHARP_BUILD_POLICY),n.join(`
5
5
  `)}function withExperimentalEveReleaseAgeExclusion(e){let t=e.endsWith(`
6
6
  `)?e:`${e}\n`,n=t.split(`
7
7
  `),r=n.findIndex(e=>e===`minimumReleaseAgeExclude:`);if(r<0)return`${t.trim().length===0?``:`${t}\n`}minimumReleaseAgeExclude:\n${EVE_RELEASE_AGE_EXCLUSION}\n`;let i=findYamlBlockEnd(n,r);if(n.slice(r+1,i).some(e=>e.trim()===`- eve`))return e;let a=i;for(;a>r+1&&n[a-1]===``;)--a;return n.splice(a,0,EVE_RELEASE_AGE_EXCLUSION),n.join(`
8
- `)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),r=withExperimentalEveReleaseAgeExclusion(withSharpBuildPolicy(n));return r===n?`skipped`:(await writeFile(t,r,`utf8`),`written`)}const pnpmPackageManager={kind:`pnpm`,scaffoldFiles:{[PNPM_WORKSPACE_PATH]:PNPM_WORKSPACE_CONTENT},async applyProjectConfiguration(e){let t=join(e,PNPM_WORKSPACE_PATH);return await ensurePnpmWorkspacePolicy(t)===`written`?{filesSkipped:[],filesWritten:[t]}:{filesSkipped:[t],filesWritten:[]}},devArguments:()=>[`exec`,`eve`,`dev`],installArguments:e=>[`install`,`--no-frozen-lockfile`,...e.bypassMinimumReleaseAge===!0?[`--config.minimum-release-age=0`]:[]],prepareArguments:(e,t)=>[`--dir`,e,...existsSync(join(e,`pnpm-workspace.yaml`))?[]:[`--ignore-workspace`],...t],resolveInvocation(e){let i=process.env.PNPM_HOME;if(i!==void 0){let t=join(i,process.platform===`win32`?`pnpm.CMD`:`pnpm`);if(existsSync(t))return{args:e,command:t,shell:process.platform===`win32`}}let a=process.env.npm_execpath;if(a!==void 0&&a.toLowerCase().includes(`pnpm`)){let n=extname(a).toLowerCase();return n===`.cjs`||n===`.js`?{args:[a,...e],command:process.execPath}:{args:e,command:a,shell:process.platform===`win32`}}return{args:e,command:`pnpm`}}};export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_PATH,pnpmPackageManager};
8
+ `)}async function ensurePnpmWorkspacePolicy(t){if(!await pathExists(t))return await writeFile(t,PNPM_WORKSPACE_CONTENT,`utf8`),`written`;let n=await readFile(t,`utf8`),r=withExperimentalEveReleaseAgeExclusion(withSharpBuildPolicy(n));return r===n?`skipped`:(await writeFile(t,r,`utf8`),`written`)}function hasAncestorPnpmWorkspace(e){let n=dirname(resolve(e));for(;;){if(existsSync(join(n,`pnpm-workspace.yaml`)))return!0;let e=dirname(n);if(e===n)return!1;n=e}}function pnpmWorkspaceClaimsProject(e,t){let n;try{n=JSON.parse(e)}catch{return}if(!Array.isArray(n)||n.length===0)return;let canonicalPath=e=>{let t=resolve(e);try{return realpathSync.native(t)}catch{return t}},r=canonicalPath(t),a=!1;for(let e of n){if(typeof e!=`object`||!e)continue;let t=e.path;if(typeof t==`string`&&(a=!0,canonicalPath(t)===r))return!0}return a?!1:void 0}const pnpmPackageManager={kind:`pnpm`,scaffoldFiles:{[PNPM_WORKSPACE_PATH]:PNPM_WORKSPACE_CONTENT},async applyProjectConfiguration(e){let t=join(e,PNPM_WORKSPACE_PATH);return await ensurePnpmWorkspacePolicy(t)===`written`?{filesSkipped:[],filesWritten:[t]}:{filesSkipped:[t],filesWritten:[]}},devArguments:()=>[`exec`,`eve`,`dev`],installArguments:e=>[`install`,`--no-frozen-lockfile`,...e.bypassMinimumReleaseAge===!0?[`--config.minimum-release-age=0`]:[],...e.ignoreWorkspace===!0?[`--ignore-workspace`]:[]],prepareArguments:(e,t)=>[`--dir`,e,...t],resolveInvocation(e){let t=process.env.npm_execpath;if(t!==void 0&&t.toLowerCase().includes(`pnpm`)){let r=extname(t).toLowerCase();return r===`.cjs`||r===`.js`?{args:[t,...e],command:process.execPath}:{args:e,command:t,shell:process.platform===`win32`}}if(process.env.npm_config_user_agent?.toLowerCase().startsWith(`pnpm/`))return{args:e,command:`pnpm`,shell:process.platform===`win32`};let i=process.env.PNPM_HOME;if(i!==void 0){let t=join(i,process.platform===`win32`?`pnpm.CMD`:`pnpm`);if(existsSync(t))return{args:e,command:t,shell:process.platform===`win32`}}return{args:e,command:`pnpm`}}};export{PNPM_WORKSPACE_CONTENT,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,PNPM_WORKSPACE_PATH,hasAncestorPnpmWorkspace,pnpmPackageManager,pnpmWorkspaceClaimsProject};
@@ -1,19 +1,27 @@
1
1
  import type { PackageManagerKind } from "../../package-manager.js";
2
2
  import { type ProcessOutputHandler } from "../process-output.js";
3
+ import type { PackageManagerInstallOptions } from "./types.js";
3
4
  /** Output routing options for setup-owned package manager commands. */
4
5
  export interface RunPackageManagerOptions {
5
6
  /** Streams command output to a parent-owned renderer instead of writing outside it. */
6
7
  onOutput?: ProcessOutputHandler;
8
+ /** Aborts the package-manager subprocess when setup is interrupted. */
9
+ signal?: AbortSignal;
7
10
  }
8
11
  /** @deprecated Use {@link RunPackageManagerOptions}. */
9
12
  export type RunPnpmOptions = RunPackageManagerOptions;
10
13
  /** Runs the selected package manager in `projectRoot`. */
11
14
  export declare function spawnPackageManager(kind: PackageManagerKind, projectRoot: string, args: readonly string[], options?: RunPackageManagerOptions): Promise<boolean>;
12
- export interface RunInstallOptions extends RunPackageManagerOptions {
13
- /** Disables the manager's minimum-release-age cooldown for this run when supported. */
14
- bypassMinimumReleaseAge?: boolean;
15
+ export interface RunInstallOptions extends RunPackageManagerOptions, PackageManagerInstallOptions {
15
16
  }
16
- /** Installs project dependencies using the selected package-manager strategy. */
17
+ /**
18
+ * Installs project dependencies using the selected package-manager strategy.
19
+ *
20
+ * pnpm resolves an unclaimed nested project as part of an ancestor workspace,
21
+ * where `install` can exit successfully without touching the project and can
22
+ * run the ancestor's lifecycle scripts. Membership is therefore established
23
+ * before installation, so exactly one correctly scoped install runs.
24
+ */
17
25
  export declare function runPackageManagerInstall(kind: PackageManagerKind, projectRoot: string, options?: RunInstallOptions): Promise<boolean>;
18
26
  /** The argv that runs the locally installed Eve binary's `dev` command. */
19
27
  export declare function eveDevArguments(kind: PackageManagerKind): readonly string[];
@@ -1 +1 @@
1
- import{createProcessOutputBuffer}from"../process-output.js";import{getPackageManagerStrategy}from"./index.js";import{spawn}from"node:child_process";function spawnPackageManager(r,i,a,o={}){return new Promise(s=>{let c=getPackageManagerStrategy(r),l=c.prepareArguments(i,a),u=c.resolveInvocation(l),d=o.onOutput&&createProcessOutputBuffer(o.onOutput),f=spawn(u.command,[...u.args],{cwd:i,stdio:o.onOutput?[`inherit`,`pipe`,`pipe`]:`inherit`,shell:u.shell});f.stdout?.on(`data`,e=>d?.write(`stdout`,e)),f.stderr?.on(`data`,e=>d?.write(`stderr`,e));let p=!1;function settle(e){p||(p=!0,d?.flush(),s(e))}function reportFailure(e){o.onOutput?o.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}f.on(`error`,e=>{e.code===`ENOENT`?reportFailure(`${r} not found. Install it before running this step.`):reportFailure(`${r} ${a.join(` `)} failed: ${e.message}`),settle(!1)}),f.on(`close`,e=>settle(e===0))})}function runPackageManagerInstall(e,n,r={}){return spawnPackageManager(e,n,getPackageManagerStrategy(e).installArguments(r),{onOutput:r.onOutput})}function eveDevArguments(e){return getPackageManagerStrategy(e).devArguments()}function spawnPnpm(e,t,n={}){return spawnPackageManager(`pnpm`,e,t,n)}function runPnpmInstall(e,t={}){return runPackageManagerInstall(`pnpm`,e,t)}export{eveDevArguments,runPackageManagerInstall,runPnpmInstall,spawnPackageManager,spawnPnpm};
1
+ import{createProcessOutputBuffer}from"../process-output.js";import{armProcessAbort}from"../process-abort.js";import{PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,hasAncestorPnpmWorkspace,pnpmWorkspaceClaimsProject}from"./pnpm.js";import{getPackageManagerStrategy}from"./index.js";import{spawn}from"node:child_process";function spawnPackageManager(n,r,i,s={}){return s.signal?.aborted===!0?Promise.resolve(!1):new Promise(c=>{let l=getPackageManagerStrategy(n),u=l.prepareArguments(r,i),d=l.resolveInvocation(u),f=s.onOutput&&createProcessOutputBuffer(s.onOutput),p=spawn(d.command,[...d.args],{cwd:r,stdio:s.onOutput?[`inherit`,`pipe`,`pipe`]:`inherit`,shell:d.shell,signal:s.signal}),m=armProcessAbort(p,s.signal);p.stdout?.on(`data`,e=>f?.write(`stdout`,e)),p.stderr?.on(`data`,e=>f?.write(`stderr`,e));let h=!1;function settle(e){h||(h=!0,f?.flush(),c(e))}function reportFailure(e){s.onOutput?s.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}p.on(`error`,e=>{s.signal?.aborted===!0||e.name===`AbortError`||(e.code===`ENOENT`?(m(),reportFailure(`${n} not found. Install it before running this step.`),settle(!1)):(m(),reportFailure(`${n} ${i.join(` `)} failed: ${e.message}`),settle(!1)))}),p.on(`close`,e=>{m(),settle(s.signal?.aborted===!0?!1:e===0)})})}function capturePackageManager(n,r,i,s){return s.signal?.aborted===!0?Promise.resolve({ok:!1,stdout:``}):new Promise(c=>{let l=getPackageManagerStrategy(n),u=l.prepareArguments(r,i),d=l.resolveInvocation(u),f=spawn(d.command,[...d.args],{cwd:r,stdio:[`ignore`,`pipe`,`pipe`],shell:d.shell,signal:s.signal}),p=armProcessAbort(f,s.signal),m=[],h=s.onOutput&&createProcessOutputBuffer(s.onOutput);f.stdout?.on(`data`,e=>m.push(e)),f.stderr?.on(`data`,e=>h?.write(`stderr`,e));let g=!1;function settle(e){g||(g=!0,h?.flush(),c({ok:e,stdout:Buffer.concat(m).toString(`utf8`)}))}function reportFailure(e){s.onOutput?s.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}f.on(`error`,e=>{s.signal?.aborted===!0||e.name===`AbortError`||(p(),reportFailure(e.code===`ENOENT`?`${n} not found. Install it before running this step.`:`${n} ${i.join(` `)} failed: ${e.message}`),settle(!1))}),f.on(`close`,e=>{p(),!g&&e!==0&&s.signal?.aborted!==!0&&reportFailure(`${n} ${i.join(` `)} exited with code ${e??`unknown`}.`),settle(s.signal?.aborted===!0?!1:e===0)})})}async function runPackageManagerInstall(e,t,o={}){let s=getPackageManagerStrategy(e),c=o;if(e===`pnpm`&&o.ignoreWorkspace!==!0&&hasAncestorPnpmWorkspace(t)){let r=await capturePackageManager(e,t,PNPM_WORKSPACE_MEMBERSHIP_ARGUMENTS,o);if(!r.ok)return!1;let a=pnpmWorkspaceClaimsProject(r.stdout,t);if(a===void 0)return o.onOutput?.({stream:`stderr`,text:`Could not determine whether the ancestor pnpm workspace includes this project.`}),!1;a||(c={...o,ignoreWorkspace:!0})}return spawnPackageManager(e,t,s.installArguments(c),o)}function eveDevArguments(e){return getPackageManagerStrategy(e).devArguments()}function spawnPnpm(e,t,n={}){return spawnPackageManager(`pnpm`,e,t,n)}function runPnpmInstall(e,t={}){return runPackageManagerInstall(`pnpm`,e,t)}export{eveDevArguments,runPackageManagerInstall,runPnpmInstall,spawnPackageManager,spawnPnpm};
@@ -11,7 +11,10 @@ export interface PackageManagerConfigurationResult {
11
11
  readonly filesWritten: readonly string[];
12
12
  }
13
13
  export interface PackageManagerInstallOptions {
14
+ /** Disables the manager's minimum-release-age cooldown for this run when supported. */
14
15
  readonly bypassMinimumReleaseAge?: boolean;
16
+ /** Resolves the project standalone even when an ancestor workspace exists. */
17
+ readonly ignoreWorkspace?: boolean;
15
18
  }
16
19
  /**
17
20
  * Package-manager-specific command and generated-project behavior.
@@ -0,0 +1,7 @@
1
+ import type { ChildProcess } from "node:child_process";
2
+ /**
3
+ * Couples a parent abort signal to a child process and guarantees eventual
4
+ * termination. Callers still wait for `close`; this helper only owns signals
5
+ * and the SIGKILL escalation.
6
+ */
7
+ export declare function armProcessAbort(child: ChildProcess, signal: AbortSignal | undefined): () => void;
@@ -0,0 +1 @@
1
+ function armProcessAbort(e,t){if(t===void 0)return()=>{};let n,abort=()=>{e.kill(`SIGTERM`),n=setTimeout(()=>e.kill(`SIGKILL`),5e3),n.unref()};return t.aborted?abort():t.addEventListener(`abort`,abort,{once:!0}),()=>{t.removeEventListener(`abort`,abort),n!==void 0&&clearTimeout(n)}}export{armProcessAbort};
@@ -7,6 +7,8 @@ export interface RunVercelOptions {
7
7
  nonInteractive?: boolean;
8
8
  /** Streams command output to a parent-owned renderer instead of writing outside it. */
9
9
  onOutput?: ProcessOutputHandler;
10
+ /** Aborts the Vercel CLI subprocess when its parent setup flow is interrupted. */
11
+ signal?: AbortSignal;
10
12
  /**
11
13
  * Hard deadline for the whole command. When it elapses the run settles as a
12
14
  * failure and the child is killed (SIGTERM, then SIGKILL after a short
@@ -1 +1 @@
1
- import{createProcessOutputBuffer}from"./process-output.js";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";import{accessSync,constants,existsSync,statSync}from"node:fs";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`},VERCEL_NOT_FOUND_MESSAGE=`Vercel CLI not found. Install with: npm i -g vercel@latest`;function buildSpawnEnv(e){return{...process.env,...CONNECT_FEATURE_FLAG_ENV,...e}}function existingDir(e){let n=resolve(e);for(;!existsSync(n);){let e=dirname(n);if(e===n)break;n=e}return n}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function ancestorDirectories(e){let n=[],i=resolve(e);for(;;){n.push(i);let e=dirname(i);if(e===i)return n;i=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function findLocalVercel(e){for(let t of ancestorDirectories(e)){let e=findExecutable(join(t,`node_modules`,`.bin`,`vercel`));if(e!==void 0)return e}}function resolveVercelInvocation(e){let t=findLocalVercel(e);return t===void 0?{command:`vercel`,commandArgs:[]}:{command:t,commandArgs:[]}}function stdioForRun(e){return e.onOutput?[e.nonInteractive?`ignore`:`inherit`,`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}async function runVercel(t,n){return new Promise(r=>{let a=existingDir(n.cwd),o=resolveVercelInvocation(a),s=n.onOutput&&createProcessOutputBuffer(n.onOutput),c=spawn(o.command,[...o.commandArgs,...t],{cwd:a,stdio:stdioForRun(n),env:buildSpawnEnv(n.extraEnv??{})});c.stdout?.on(`data`,e=>s?.write(`stdout`,e)),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let l=!1;function settle(e){l||(l=!0,s?.flush(),r(e))}function reportFailure(e){n.onOutput?n.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let u=armDeadline(c,n.timeoutMs,()=>{reportFailure(timeoutMessage(t,n.timeoutMs??0)),settle(!1)});c.on(`error`,e=>{u(),e.code===`ENOENT`?reportFailure(VERCEL_NOT_FOUND_MESSAGE):reportFailure(`vercel ${t.join(` `)} failed: ${e.message}`),settle(!1)}),c.on(`close`,e=>{u(),!l&&e!==0&&e!==null&&(s?.flush(),reportFailure(`vercel ${t.join(` `)} exited with code ${e}.`)),settle(e===0)})})}async function runVercelCaptureStdout(t,n){return new Promise(r=>{let a=existingDir(n.cwd),o=resolveVercelInvocation(a),s=n.onOutput&&createProcessOutputBuffer(n.onOutput),c=spawn(o.command,[...o.commandArgs,...t],{cwd:a,stdio:[n.nonInteractive?`ignore`:`inherit`,`pipe`,n.onOutput?`pipe`:`inherit`],env:buildSpawnEnv(n.extraEnv??{})}),l=[];c.stdout?.on(`data`,e=>l.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let u=!1;function settle(e){u||(u=!0,s?.flush(),r({ok:e,stdout:l.join(``)}))}function reportFailure(e){n.onOutput?n.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let d=armDeadline(c,n.timeoutMs,()=>{reportFailure(timeoutMessage(t,n.timeoutMs??0)),settle(!1)});c.on(`error`,e=>{d(),reportFailure(e.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${t.join(` `)} failed: ${e.message}`),settle(!1)}),c.on(`close`,e=>{d(),!u&&e!==0&&e!==null&&reportFailure(`vercel ${t.join(` `)} exited with code ${e}.`),settle(e===0)})})}async function captureVercel(t,n){return new Promise(r=>{let a=existingDir(n.cwd),o=resolveVercelInvocation(a),s=n.onOutput&&createProcessOutputBuffer(n.onOutput),c=spawn(o.command,[...o.commandArgs,...t],{cwd:a,stdio:[`ignore`,`pipe`,`pipe`],env:buildSpawnEnv(n.extraEnv??{})}),l=[],u=[];c.stdout?.on(`data`,e=>l.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>{u.push(e.toString(`utf8`)),s?.write(`stderr`,e)});let d=!1;function fail(e){d||(d=!0,s?.flush(),n.onOutput?.({stream:`stderr`,text:e.message}),r({ok:!1,failure:e}))}function succeed(){d||(d=!0,s?.flush(),r({ok:!0,stdout:l.join(``)}))}let f=armDeadline(c,n.timeoutMs,()=>{fail({code:null,stdout:l.join(``),stderr:u.join(``),message:timeoutMessage(t,n.timeoutMs??0)})});c.on(`error`,e=>{f(),fail({errno:e.code,stdout:l.join(``),stderr:u.join(``),message:e.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${t.join(` `)} failed: ${e.message}`})}),c.on(`close`,e=>{if(f(),e!==0&&e!==null){fail({code:e,stdout:l.join(``),stderr:u.join(``),message:`vercel ${t.join(` `)} exited with code ${e}.`});return}succeed()})})}export{captureVercel,runVercel,runVercelCaptureStdout};
1
+ import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";import{accessSync,constants,existsSync,statSync}from"node:fs";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`},VERCEL_NOT_FOUND_MESSAGE=`Vercel CLI not found. Install with: npm i -g vercel@latest`;function buildSpawnEnv(e){return{...process.env,...CONNECT_FEATURE_FLAG_ENV,...e}}function existingDir(e){let t=resolve(e);for(;!existsSync(t);){let e=dirname(t);if(e===t)break;t=e}return t}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function abortMessage(e){return`vercel ${e.join(` `)} was aborted.`}function isAbortError(e,t){return t?.aborted===!0||e.name===`AbortError`||e.code===`ABORT_ERR`}function ancestorDirectories(e){let t=[],r=resolve(e);for(;;){t.push(r);let e=dirname(r);if(e===r)return t;r=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function findLocalVercel(e){for(let t of ancestorDirectories(e)){let e=findExecutable(join(t,`node_modules`,`.bin`,`vercel`));if(e!==void 0)return e}}function resolveVercelInvocation(e){let t=findLocalVercel(e);return t===void 0?{command:`vercel`,commandArgs:[]}:{command:t,commandArgs:[]}}function stdioForRun(e){return e.onOutput?[e.nonInteractive?`ignore`:`inherit`,`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}async function runVercel(n,r){return r.signal?.aborted===!0?!1:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...n],{cwd:a,stdio:stdioForRun(r),env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal);c.stdout?.on(`data`,e=>s?.write(`stdout`,e)),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let u=!1;function settle(e){u||(u=!0,s?.flush(),i(e))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let d=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(n,r.timeoutMs??0)),settle(!1)});c.on(`error`,e=>{isAbortError(e,r.signal)||(e.code===`ENOENT`?(l(),d(),reportFailure(VERCEL_NOT_FOUND_MESSAGE),settle(!1)):(l(),d(),reportFailure(`vercel ${n.join(` `)} failed: ${e.message}`),settle(!1)))}),c.on(`close`,e=>{if(l(),d(),r.signal?.aborted===!0){settle(!1);return}!u&&e!==0&&e!==null&&(s?.flush(),reportFailure(`vercel ${n.join(` `)} exited with code ${e}.`)),settle(e===0)})})}async function runVercelCaptureStdout(n,r){return r.signal?.aborted===!0?{ok:!1,stdout:``}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...n],{cwd:a,stdio:[r.nonInteractive?`ignore`:`inherit`,`pipe`,r.onOutput?`pipe`:`inherit`],env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal),u=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let d=!1;function settle(e){d||(d=!0,s?.flush(),i({ok:e,stdout:u.join(``)}))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let f=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(n,r.timeoutMs??0)),settle(!1)});c.on(`error`,e=>{isAbortError(e,r.signal)||(l(),f(),reportFailure(e.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${n.join(` `)} failed: ${e.message}`),settle(!1))}),c.on(`close`,e=>{if(l(),f(),r.signal?.aborted===!0){settle(!1);return}!d&&e!==0&&e!==null&&reportFailure(`vercel ${n.join(` `)} exited with code ${e}.`),settle(e===0)})})}async function captureVercel(n,r){return r.signal?.aborted===!0?{ok:!1,failure:{errno:`ABORT_ERR`,stdout:``,stderr:``,message:abortMessage(n)}}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...n],{cwd:a,stdio:[`ignore`,`pipe`,`pipe`],env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal),u=[],d=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>{d.push(e.toString(`utf8`)),s?.write(`stderr`,e)});let f=!1;function fail(e,t=!0){f||(f=!0,s?.flush(),t&&r.onOutput?.({stream:`stderr`,text:e.message}),i({ok:!1,failure:e}))}function succeed(){f||(f=!0,s?.flush(),i({ok:!0,stdout:u.join(``)}))}let p=armDeadline(c,r.timeoutMs,()=>{fail({code:null,stdout:u.join(``),stderr:d.join(``),message:timeoutMessage(n,r.timeoutMs??0)})});c.on(`error`,e=>{isAbortError(e,r.signal)||(l(),p(),fail({errno:e.code,stdout:u.join(``),stderr:d.join(``),message:e.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${n.join(` `)} failed: ${e.message}`}))}),c.on(`close`,e=>{if(l(),p(),r.signal?.aborted===!0){fail({errno:`ABORT_ERR`,stdout:u.join(``),stderr:d.join(``),message:abortMessage(n)},!1);return}if(e!==0&&e!==null){fail({code:e,stdout:u.join(``),stderr:d.join(``),message:`vercel ${n.join(` `)} exited with code ${e}.`});return}succeed()})})}export{captureVercel,runVercel,runVercelCaptureStdout};
@@ -7,10 +7,13 @@ export interface DeploymentInfo {
7
7
  orgId?: string;
8
8
  productionUrl?: string;
9
9
  }
10
+ export interface ProjectDetectionOptions {
11
+ signal?: AbortSignal;
12
+ }
10
13
  /**
11
14
  * Reads local Vercel link metadata and checks whether the linked project has a production alias.
12
15
  */
13
- export declare function detectDeployment(projectPath: string): Promise<DeploymentInfo>;
16
+ export declare function detectDeployment(projectPath: string, options?: ProjectDetectionOptions): Promise<DeploymentInfo>;
14
17
  /** Human-readable identity of a linked Vercel project, for the dashboard status bar. */
15
18
  export interface ProjectIdentity {
16
19
  projectName: string;
@@ -28,7 +31,7 @@ export interface ProjectIdentity {
28
31
  *
29
32
  * @param projectPath Absolute path of the linked project directory.
30
33
  */
31
- export declare function detectProjectIdentity(projectPath: string): Promise<ProjectIdentity | undefined>;
34
+ export declare function detectProjectIdentity(projectPath: string, options?: ProjectDetectionOptions): Promise<ProjectIdentity | undefined>;
32
35
  export type ProjectResolution = {
33
36
  kind: "unresolved";
34
37
  } | {
@@ -44,7 +47,7 @@ export declare function projectResolutionFromDeployment(deployment: DeploymentIn
44
47
  * Side-effect-free fact gathering after a link: reads `.vercel/project.json`
45
48
  * to resolve the project. The on-disk link is the single source of truth.
46
49
  */
47
- export declare function detectProjectResolution(projectRoot: string): Promise<ProjectResolution>;
50
+ export declare function detectProjectResolution(projectRoot: string, options?: ProjectDetectionOptions): Promise<ProjectResolution>;
48
51
  export declare function mergeProjectResolution(current: ProjectResolution, next: ProjectResolution): ProjectResolution;
49
52
  export declare function projectResolutionFromDeployResult(project: ProjectResolution, deploy: {
50
53
  deployed: boolean;
@@ -1 +1 @@
1
- import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(t,n,r){let i=await captureVercel([`api`,`/v9/projects/${t}?teamId=${n}`,`--scope`,n],{cwd:r});if(i.ok)try{let e=pickShortestAlias(JSON.parse(i.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return{state:`unlinked`}}let i;try{i=JSON.parse(r)}catch{return{state:`unlinked`}}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;if(!a||!o)return{state:`unlinked`};let s=await fetchProductionAlias(a,o,e);return{state:s?`deployed`:`linked`,projectId:a,orgId:o,productionUrl:s}}async function fetchVercelName(t,n,r){let i=await captureVercel([`api`,t,`--scope`,n],{cwd:r});if(i.ok)try{let e=JSON.parse(i.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e){let r;try{r=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return}let i;try{i=JSON.parse(r)}catch{return}let a=typeof i.projectId==`string`?i.projectId:void 0,o=typeof i.orgId==`string`?i.orgId:void 0;if(!a||!o)return;let[s,c]=await Promise.all([fetchVercelName(`/v9/projects/${a}?teamId=${o}`,o,e).then(e=>e??a),o.startsWith(`team_`)?fetchVercelName(`/v2/teams/${o}`,o,e):Promise.resolve(void 0)]);return{projectName:s,teamName:c}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e){return projectResolutionFromDeployment(await detectDeployment(e))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment};
1
+ import{captureVercel}from"./primitives/run-vercel.js";import{join}from"node:path";import{readFile}from"node:fs/promises";function pickShortestAlias(e){if(!Array.isArray(e))return;let t;for(let n of e)typeof n!=`string`||n.length===0||(t===void 0||n.length<t.length)&&(t=n);return t}async function fetchProductionAlias(t,n,r,i){let a=await captureVercel([`api`,`/v9/projects/${t}?teamId=${n}`,`--scope`,n],{cwd:r,signal:i.signal});if(a.ok)try{let e=pickShortestAlias(JSON.parse(a.stdout).targets?.production?.alias);return e?`https://${e}`:void 0}catch{return}}async function detectDeployment(e,r={}){r.signal?.throwIfAborted();let i;try{i=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return{state:`unlinked`}}let a;try{a=JSON.parse(i)}catch{return{state:`unlinked`}}let o=typeof a.projectId==`string`?a.projectId:void 0,s=typeof a.orgId==`string`?a.orgId:void 0;if(!o||!s)return{state:`unlinked`};let c=await fetchProductionAlias(o,s,e,r);return r.signal?.throwIfAborted(),{state:c?`deployed`:`linked`,projectId:o,orgId:s,productionUrl:c}}async function fetchVercelName(t,n,r,i){let a=await captureVercel([`api`,t,`--scope`,n],{cwd:r,signal:i.signal});if(a.ok)try{let e=JSON.parse(a.stdout);return typeof e.name==`string`&&e.name.length>0?e.name:typeof e.slug==`string`&&e.slug.length>0?e.slug:void 0}catch{return}}async function detectProjectIdentity(e,r={}){r.signal?.throwIfAborted();let i;try{i=await readFile(join(e,`.vercel`,`project.json`),`utf8`)}catch{return}let a;try{a=JSON.parse(i)}catch{return}let o=typeof a.projectId==`string`?a.projectId:void 0,s=typeof a.orgId==`string`?a.orgId:void 0;if(!o||!s)return;let[c,l]=await Promise.all([fetchVercelName(`/v9/projects/${o}?teamId=${s}`,s,e,r).then(e=>e??o),s.startsWith(`team_`)?fetchVercelName(`/v2/teams/${s}`,s,e,r):Promise.resolve(void 0)]);return r.signal?.throwIfAborted(),{projectName:c,teamName:l}}function projectResolutionFromDeployment(e){return e.state===`unlinked`||e.projectId===void 0?{kind:`unresolved`}:e.state===`deployed`&&e.productionUrl!==void 0?{kind:`deployed`,projectId:e.projectId,productionUrl:e.productionUrl}:{kind:`linked`,projectId:e.projectId}}async function detectProjectResolution(e,t={}){return projectResolutionFromDeployment(await detectDeployment(e,t))}function mergeProjectResolution(e,t){return t.kind===`unresolved`||e.kind===`deployed`&&e.projectId===t.projectId?e:t}function projectResolutionFromDeployResult(e,t){return e.kind===`unresolved`||!t.deployed||t.productionUrl===void 0?e:{kind:`deployed`,projectId:e.projectId,productionUrl:t.productionUrl}}function isProjectResolved(e){return e.kind!==`unresolved`}function projectProductionUrlFromResolution(e){return e.kind===`deployed`?e.productionUrl:void 0}export{detectDeployment,detectProjectIdentity,detectProjectResolution,isProjectResolved,mergeProjectResolution,projectProductionUrlFromResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment};