eve 0.52.2 → 0.52.4

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 (315) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/src/channel/types.d.ts +1 -0
  3. package/dist/src/chunks/{use-eve-agent-1NAM6ftx.js → use-eve-agent-BR8EpIOX.js} +27 -10
  4. package/dist/src/chunks/{use-eve-agent-BEjdhhhK.js → use-eve-agent-XnfjQt1Z.js} +27 -10
  5. package/dist/src/cli/commands/deploy.js +1 -1
  6. package/dist/src/cli/commands/extension-init.d.ts +2 -1
  7. package/dist/src/cli/commands/extension-init.js +1 -1
  8. package/dist/src/cli/commands/init.d.ts +2 -13
  9. package/dist/src/cli/commands/init.js +1 -1
  10. package/dist/src/cli/commands/registry-add-command.d.ts +3 -0
  11. package/dist/src/cli/commands/registry-add-command.js +1 -0
  12. package/dist/src/cli/commands/registry-metadata.d.ts +4 -1
  13. package/dist/src/cli/commands/registry-metadata.js +1 -1
  14. package/dist/src/cli/commands/registry.d.ts +1 -2
  15. package/dist/src/cli/commands/registry.js +1 -1
  16. package/dist/src/cli/dev/run-interactive-ui.d.ts +3 -0
  17. package/dist/src/cli/dev/run-interactive-ui.js +1 -1
  18. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  19. package/dist/src/cli/dev/tui/runner.d.ts +6 -0
  20. package/dist/src/cli/dev/tui/runner.js +1 -1
  21. package/dist/src/cli/dev/tui/setup-commands.d.ts +5 -3
  22. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  23. package/dist/src/cli/dev/tui/status-line.js +1 -1
  24. package/dist/src/cli/dev/tui/tui.d.ts +4 -0
  25. package/dist/src/cli/dev/tui/tui.js +1 -1
  26. package/dist/src/cli/run.d.ts +1 -1
  27. package/dist/src/cli/run.js +2 -2
  28. package/dist/src/cli/telemetry/index.d.ts +15 -0
  29. package/dist/src/cli/telemetry/index.js +2 -2
  30. package/dist/src/client/session.js +1 -1
  31. package/dist/src/compiled/.vendor-stamp.json +1 -1
  32. package/dist/src/compiler/compile-from-memory.d.ts +1 -0
  33. package/dist/src/compiler/compile-from-memory.js +1 -1
  34. package/dist/src/compiler/extension-compatibility.d.ts +18 -18
  35. package/dist/src/compiler/extension-compatibility.js +1 -1
  36. package/dist/src/context/build-dynamic-tools.d.ts +2 -1
  37. package/dist/src/context/build-dynamic-tools.js +1 -1
  38. package/dist/src/context/dynamic-tool-lifecycle.d.ts +3 -3
  39. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  40. package/dist/src/context/dynamic-tool-metadata.d.ts +1 -1
  41. package/dist/src/context/hook-lifecycle.js +1 -1
  42. package/dist/src/context/keys.d.ts +2 -0
  43. package/dist/src/context/keys.js +1 -1
  44. package/dist/src/evals/reporters/index.d.ts +1 -0
  45. package/dist/src/evals/reporters/index.js +1 -1
  46. package/dist/src/evals/runner/reporters/datadog.d.ts +137 -0
  47. package/dist/src/evals/runner/reporters/datadog.js +3 -0
  48. package/dist/src/eve-channel/index.js +1 -1
  49. package/dist/src/execution/activity-events.d.ts +1 -0
  50. package/dist/src/execution/activity-events.js +1 -1
  51. package/dist/src/execution/node-step.js +1 -1
  52. package/dist/src/execution/parked-delivery-wait.js +1 -1
  53. package/dist/src/execution/sandbox/bindings/vercel-options.d.ts +10 -0
  54. package/dist/src/execution/sandbox/bindings/vercel-options.js +1 -0
  55. package/dist/src/execution/sandbox/bindings/vercel.js +2 -1
  56. package/dist/src/execution/sandbox/prewarm.js +1 -1
  57. package/dist/src/execution/sandbox/shell-quote.d.ts +1 -12
  58. package/dist/src/execution/sandbox/shell-quote.js +1 -1
  59. package/dist/src/execution/session-activity-projection.js +1 -1
  60. package/dist/src/execution/session-activity.js +1 -1
  61. package/dist/src/execution/session-command-inbox.js +1 -1
  62. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  63. package/dist/src/execution/tasks/child/workflow.js +1 -1
  64. package/dist/src/execution/tasks/parent/dispatch.js +1 -1
  65. package/dist/src/execution/tasks/parent/task-cancel.d.ts +2 -2
  66. package/dist/src/execution/tasks/parent/task-cancel.js +1 -1
  67. package/dist/src/execution/tasks/parent/tool-execution.js +1 -1
  68. package/dist/src/execution/tool-auth.d.ts +4 -32
  69. package/dist/src/execution/tool-auth.js +1 -1
  70. package/dist/src/execution/tools/connection-search.js +2 -2
  71. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  72. package/dist/src/execution/tools/subagent/accept-event-step.d.ts +1 -1
  73. package/dist/src/execution/tools/subagent/accept-event-step.js +1 -1
  74. package/dist/src/execution/tools/subagent/invoke-agent.js +1 -1
  75. package/dist/src/execution/tools/subagent/invoke-step.js +1 -1
  76. package/dist/src/execution/tools/workflow/ask.d.ts +3 -2
  77. package/dist/src/execution/tools/workflow/ask.js +1 -1
  78. package/dist/src/execution/tools/workflow/authorization-completion.d.ts +3 -0
  79. package/dist/src/execution/tools/workflow/authorization-completion.js +1 -0
  80. package/dist/src/execution/tools/workflow/body.d.ts +2 -0
  81. package/dist/src/execution/tools/workflow/body.js +1 -1
  82. package/dist/src/execution/tools/workflow/step-context.d.ts +31 -0
  83. package/dist/src/execution/tools/workflow/step-context.js +1 -0
  84. package/dist/src/execution/tools/workflow/step-execution.d.ts +3 -0
  85. package/dist/src/execution/tools/workflow/step-execution.js +1 -0
  86. package/dist/src/execution/tools/workflow/step.d.ts +3 -0
  87. package/dist/src/execution/tools/workflow/step.js +1 -0
  88. package/dist/src/execution/turn-workflow-tool-run.js +1 -1
  89. package/dist/src/execution/wire/session-inbox-contract.d.ts +7 -0
  90. package/dist/src/execution/wire/session-inbox-contract.js +1 -1
  91. package/dist/src/execution/wire/session-inbox-resume.d.ts +2 -0
  92. package/dist/src/execution/wire/session-inbox-resume.js +1 -1
  93. package/dist/src/execution/workflow-runtime.js +1 -1
  94. package/dist/src/execution/workflow-steps.js +1 -1
  95. package/dist/src/harness/action-presentation.d.ts +13 -0
  96. package/dist/src/harness/action-presentation.js +1 -0
  97. package/dist/src/harness/authorization.d.ts +5 -2
  98. package/dist/src/harness/authorization.js +1 -1
  99. package/dist/src/harness/compaction.js +1 -1
  100. package/dist/src/harness/coordination.js +1 -1
  101. package/dist/src/harness/emission.d.ts +1 -6
  102. package/dist/src/harness/emission.js +1 -1
  103. package/dist/src/harness/execute-tool.d.ts +2 -1
  104. package/dist/src/harness/finish-reason.d.ts +3 -0
  105. package/dist/src/harness/finish-reason.js +1 -0
  106. package/dist/src/harness/provider-tool-schemas.d.ts +1 -0
  107. package/dist/src/harness/provider-tool-schemas.js +1 -1
  108. package/dist/src/harness/step-hooks.js +1 -1
  109. package/dist/src/harness/stream-actions.d.ts +2 -2
  110. package/dist/src/harness/stream-actions.js +1 -1
  111. package/dist/src/harness/tool-call-input-errors.d.ts +4 -3
  112. package/dist/src/harness/tool-call-input-errors.js +1 -1
  113. package/dist/src/harness/tool-loop.js +2 -2
  114. package/dist/src/harness/tool-presentation.d.ts +5 -0
  115. package/dist/src/harness/tool-presentation.js +1 -0
  116. package/dist/src/harness/turn-client-context.d.ts +1 -0
  117. package/dist/src/harness/workflow-lifecycle.d.ts +2 -3
  118. package/dist/src/harness/workflow-lifecycle.js +1 -1
  119. package/dist/src/internal/application/compiled-artifacts.d.ts +3 -0
  120. package/dist/src/internal/application/compiled-artifacts.js +1 -1
  121. package/dist/src/internal/application/package.js +1 -1
  122. package/dist/src/internal/authored-definition/connection.js +1 -1
  123. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  124. package/dist/src/internal/authored-module-conditions.d.ts +2 -0
  125. package/dist/src/internal/authored-module-conditions.js +1 -0
  126. package/dist/src/internal/authored-module-loader.d.ts +3 -0
  127. package/dist/src/internal/authored-module-loader.js +3 -3
  128. package/dist/src/internal/authored-module-map-loader.d.ts +3 -1
  129. package/dist/src/internal/authored-module-map-loader.js +1 -1
  130. package/dist/src/internal/authored-package-boundary.js +1 -1
  131. package/dist/src/internal/authored-runtime-modules.d.ts +2 -0
  132. package/dist/src/internal/authored-runtime-modules.js +1 -1
  133. package/dist/src/internal/bundler/nitro-rolldown.d.ts +1 -0
  134. package/dist/src/internal/bundler/nitro-rolldown.js +1 -1
  135. package/dist/src/internal/nitro/development-generation.d.ts +2 -0
  136. package/dist/src/internal/nitro/development-generation.js +1 -1
  137. package/dist/src/internal/nitro/host/configure-nitro-routes.js +1 -1
  138. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  139. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  140. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  141. package/dist/src/internal/vercel/build-command.d.ts +2 -1
  142. package/dist/src/internal/vercel/build-command.js +1 -1
  143. package/dist/src/internal/workflow-bundle/builder-support.d.ts +5 -0
  144. package/dist/src/internal/workflow-bundle/builder-support.js +1 -1
  145. package/dist/src/internal/workflow-bundle/builder.js +2 -2
  146. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.d.ts +1 -1
  147. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  148. package/dist/src/internal/workflow-bundle/workflow-builders.js +1 -1
  149. package/dist/src/internal/workflow-bundle/workflow-transformer.d.ts +3 -5
  150. package/dist/src/internal/workflow-bundle/workflow-transformer.js +4 -3
  151. package/dist/src/protocol/activity.d.ts +6 -0
  152. package/dist/src/protocol/activity.js +1 -1
  153. package/dist/src/protocol/message.d.ts +13 -1
  154. package/dist/src/protocol/message.js +1 -1
  155. package/dist/src/public/channels/github/checkout.js +1 -1
  156. package/dist/src/public/channels/slack/activity-plan.js +1 -1
  157. package/dist/src/public/channels/slack/activity.js +2 -2
  158. package/dist/src/public/models/openai/chatgpt/credential-store.d.ts +6 -0
  159. package/dist/src/public/models/openai/chatgpt/credential-store.js +1 -0
  160. package/dist/src/public/models/openai/chatgpt/model.d.ts +1 -1
  161. package/dist/src/public/models/openai/chatgpt/oauth.d.ts +20 -0
  162. package/dist/src/public/models/openai/chatgpt/oauth.js +1 -0
  163. package/dist/src/public/models/openai/chatgpt/token-broker.d.ts +4 -3
  164. package/dist/src/public/models/openai/chatgpt/token-broker.js +1 -1
  165. package/dist/src/public/models/openai/chatgpt/transport.d.ts +1 -2
  166. package/dist/src/public/models/openai/index.d.ts +3 -4
  167. package/dist/src/public/tools/index.d.ts +1 -1
  168. package/dist/src/runtime/authorization-context.d.ts +14 -0
  169. package/dist/src/runtime/authorization-context.js +1 -0
  170. package/dist/src/runtime/connections/mcp-client.js +1 -1
  171. package/dist/src/runtime/connections/scoped-authorization.d.ts +18 -2
  172. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  173. package/dist/src/runtime/prompt/compose.js +1 -1
  174. package/dist/src/runtime/resolve-connection.js +1 -1
  175. package/dist/src/runtime/resolve-tool.js +1 -1
  176. package/dist/src/runtime/sandbox/keys.js +1 -1
  177. package/dist/src/runtime/types.d.ts +2 -0
  178. package/dist/src/sandbox/backends/default.d.ts +2 -0
  179. package/dist/src/sandbox/backends/default.js +1 -1
  180. package/dist/src/self-modification/agent.d.ts +5 -2
  181. package/dist/src/self-modification/agent.js +1 -1
  182. package/dist/src/self-modification/config.d.ts +52 -0
  183. package/dist/src/self-modification/config.js +1 -0
  184. package/dist/src/self-modification/credentials.d.ts +18 -0
  185. package/dist/src/self-modification/credentials.js +1 -0
  186. package/dist/src/self-modification/extension/eve-add.d.ts +7 -2
  187. package/dist/src/self-modification/extension/eve-add.js +1 -1
  188. package/dist/src/self-modification/extension/extension.d.ts +46 -1
  189. package/dist/src/self-modification/extension/extension.js +1 -1
  190. package/dist/src/self-modification/extension/instructions.d.ts +1 -3
  191. package/dist/src/self-modification/extension/instructions.js +24 -8
  192. package/dist/src/self-modification/extension/production-registry-add.d.ts +42 -0
  193. package/dist/src/self-modification/extension/production-registry-add.js +1 -0
  194. package/dist/src/self-modification/extension/tools/edit_file.js +1 -1
  195. package/dist/src/self-modification/extension/tools/publish.d.ts +7 -0
  196. package/dist/src/self-modification/extension/tools/publish.js +1 -0
  197. package/dist/src/self-modification/extension/tools/registry_add.d.ts +39 -7
  198. package/dist/src/self-modification/extension/tools/registry_add.js +1 -1
  199. package/dist/src/self-modification/extension/tools/search_registry.d.ts +1 -0
  200. package/dist/src/self-modification/extension/tools/search_registry.js +1 -1
  201. package/dist/src/self-modification/filesystem.js +1 -1
  202. package/dist/src/self-modification/git-workspace.d.ts +31 -0
  203. package/dist/src/self-modification/git-workspace.js +1 -0
  204. package/dist/src/self-modification/git.d.ts +6 -0
  205. package/dist/src/self-modification/git.js +1 -0
  206. package/dist/src/self-modification/github-publisher.d.ts +27 -0
  207. package/dist/src/self-modification/github-publisher.js +2 -0
  208. package/dist/src/self-modification/identifiers.d.ts +4 -0
  209. package/dist/src/self-modification/identifiers.js +1 -0
  210. package/dist/src/self-modification/mode.d.ts +4 -0
  211. package/dist/src/self-modification/mode.js +1 -0
  212. package/dist/src/self-modification/network-policy.d.ts +1 -0
  213. package/dist/src/self-modification/network-policy.js +1 -0
  214. package/dist/src/self-modification/proposal.d.ts +39 -0
  215. package/dist/src/self-modification/proposal.js +2 -0
  216. package/dist/src/self-modification/sandbox.d.ts +25 -1
  217. package/dist/src/self-modification/sandbox.js +1 -1
  218. package/dist/src/self-modification/setup.d.ts +34 -0
  219. package/dist/src/self-modification/setup.js +22 -0
  220. package/dist/src/self-modification/workspace-lock.d.ts +2 -0
  221. package/dist/src/self-modification/workspace-lock.js +1 -0
  222. package/dist/src/setup/flows/chatgpt-auth.d.ts +14 -2
  223. package/dist/src/setup/flows/chatgpt-auth.js +1 -1
  224. package/dist/src/setup/flows/model.d.ts +3 -2
  225. package/dist/src/setup/flows/model.js +1 -1
  226. package/dist/src/setup/flows/provider.js +1 -1
  227. package/dist/src/setup/flows/registry.d.ts +4 -0
  228. package/dist/src/setup/flows/registry.js +1 -1
  229. package/dist/src/setup/integrations/registry.js +1 -1
  230. package/dist/src/setup/integrations/runner.js +1 -1
  231. package/dist/src/setup/integrations/self-modification/setup.d.ts +29 -0
  232. package/dist/src/setup/integrations/self-modification/setup.js +1 -0
  233. package/dist/src/setup/integrations/types.d.ts +2 -0
  234. package/dist/src/setup/integrations/types.js +1 -1
  235. package/dist/src/setup/scaffold/create/project.js +1 -1
  236. package/dist/src/shared/boundary-hook-error.d.ts +4 -0
  237. package/dist/src/shared/boundary-hook-error.js +1 -0
  238. package/dist/src/shared/empty-delivery.js +1 -1
  239. package/dist/src/shared/git.d.ts +16 -0
  240. package/dist/src/shared/git.js +1 -0
  241. package/dist/src/{execution/activity-text.d.ts → shared/presentation-text.d.ts} +1 -1
  242. package/dist/src/shared/presentation-text.js +1 -0
  243. package/dist/src/shared/shell-quote.d.ts +2 -0
  244. package/dist/src/shared/shell-quote.js +1 -0
  245. package/dist/src/shared/vercel-services.js +1 -1
  246. package/dist/src/svelte/index.js +1 -1
  247. package/dist/src/svelte/use-eve-agent.js +1 -1
  248. package/dist/src/tasks/session-index.d.ts +1 -1
  249. package/dist/src/tasks/session-index.js +1 -1
  250. package/dist/src/tasks/session-task-cohorts.d.ts +10 -0
  251. package/dist/src/tasks/session-task-cohorts.js +1 -0
  252. package/dist/src/tools/definition.d.ts +21 -0
  253. package/dist/src/tools/definition.js +1 -1
  254. package/dist/src/tools/durable-callbacks.d.ts +37 -9
  255. package/dist/src/tools/durable-callbacks.js +1 -1
  256. package/dist/src/tools/dynamic.d.ts +2 -1
  257. package/dist/src/tools/framework/agent-contract.js +1 -1
  258. package/dist/src/tools/provided/bash.js +1 -1
  259. package/dist/src/tools/provided/glob.js +1 -1
  260. package/dist/src/tools/provided/grep.js +1 -1
  261. package/dist/src/tools/provided/load-skill.js +1 -1
  262. package/dist/src/tools/provided/read-file.js +1 -1
  263. package/dist/src/tools/provided/web-fetch.js +1 -1
  264. package/dist/src/tools/provided/write-file.js +1 -1
  265. package/dist/src/tools/tool-label.d.ts +1 -0
  266. package/dist/src/tools/tool-label.js +1 -0
  267. package/dist/src/tools/workflow-definition.d.ts +5 -2
  268. package/dist/src/tracing/agent-action-instrumentation.js +1 -1
  269. package/dist/src/tracing/agent-approval-instrumentation.js +1 -1
  270. package/dist/src/tracing/agent-channel-delivery-instrumentation.js +1 -1
  271. package/dist/src/tracing/agent-otel-provider.js +2 -2
  272. package/dist/src/tracing/agent-otel-session-context.js +1 -1
  273. package/dist/src/tracing/agent-otel-usage.d.ts +10 -0
  274. package/dist/src/tracing/agent-otel-usage.js +1 -1
  275. package/dist/src/tracing/agent-span-naming.d.ts +1 -0
  276. package/dist/src/tracing/agent-span-naming.js +1 -0
  277. package/dist/src/tracing/agent-tool-instrumentation.js +1 -1
  278. package/dist/src/vue/index.js +1 -1
  279. package/dist/src/vue/use-eve-agent.js +1 -1
  280. package/docs/concepts/default-harness.md +6 -0
  281. package/docs/concepts/sessions-runs-and-streaming.md +6 -0
  282. package/docs/connections/overview.mdx +1 -1
  283. package/docs/evals/reporters.mdx +20 -1
  284. package/docs/guides/client/continuations.mdx +11 -0
  285. package/docs/guides/dynamic-capabilities.md +4 -4
  286. package/docs/guides/hooks.md +1 -1
  287. package/docs/guides/instrumentation.md +40 -1
  288. package/docs/guides/remote-agents.md +2 -0
  289. package/docs/instructions.mdx +1 -1
  290. package/docs/memory/overview.mdx +45 -13
  291. package/docs/reference/cli.md +6 -0
  292. package/docs/reference/telemetry.md +2 -2
  293. package/docs/reference/typescript-api.md +13 -9
  294. package/docs/sandbox.mdx +16 -2
  295. package/docs/subagents/index.mdx +18 -4
  296. package/docs/tools/overview.mdx +44 -2
  297. package/docs/tools/workflows.mdx +67 -2
  298. package/docs/tutorial/connect-a-warehouse.mdx +49 -26
  299. package/docs/tutorial/first-agent.mdx +20 -19
  300. package/docs/tutorial/guard-the-spend.mdx +4 -4
  301. package/docs/tutorial/how-it-runs.mdx +2 -3
  302. package/docs/tutorial/meta.json +2 -2
  303. package/docs/tutorial/query-sample-data.mdx +30 -19
  304. package/docs/tutorial/remember-definitions.mdx +5 -5
  305. package/docs/tutorial/run-analysis.mdx +155 -18
  306. package/docs/tutorial/ship-it.mdx +71 -81
  307. package/docs/tutorial/team-playbooks.mdx +10 -10
  308. package/package.json +17 -1
  309. package/dist/src/execution/activity-text.js +0 -1
  310. package/dist/src/internal/workflow-bundle/authored-workflow-modules.d.ts +0 -9
  311. package/dist/src/internal/workflow-bundle/authored-workflow-modules.js +0 -1
  312. package/dist/src/public/models/openai/chatgpt/codex-app-server.d.ts +0 -40
  313. package/dist/src/public/models/openai/chatgpt/codex-app-server.js +0 -1
  314. package/dist/src/self-modification/extension/source-lock.d.ts +0 -2
  315. package/dist/src/self-modification/extension/source-lock.js +0 -1
@@ -0,0 +1,2 @@
1
+ import{assertFullSha,assertGitRef,assertOperationId}from"./identifiers.js";import{captureSelfModificationProposal,readProposalBlob}from"./proposal.js";import{createHash}from"node:crypto";async function publishGitHubDraftPullRequest(e){assertOperationId(e.operationId),validateText(e.title,`title`,256,!1),validateText(e.description,`description`,65536,!0);let t=await captureSelfModificationProposal({sandbox:e.sandbox,workspace:e.workspace}),n=selfModificationBranchName(e.workspace.baseSha,e.operationId),r=await e.credentialProvider.resolve({capability:`publish`,repository:repository(e.workspace)});if(r.trim().length===0)throw Error(`Self-modification publication credential is empty.`);let i=new GitHubClient(e.fetch??fetch,r.trim());await assertTargetAtBase(i,repository(e.workspace),e.workspace.targetBranch,t.baseSha);let a=await i.ref(repository(e.workspace),n);if(a!==null)return await reconcile(i,e,t,n,a);let o=await upload(i,e,t);try{await i.createRef(repository(e.workspace),n,o)}catch(r){let a=await i.ref(repository(e.workspace),n);if(a===null)throw r;return await reconcile(i,e,t,n,a)}await assertTargetAtBase(i,repository(e.workspace),e.workspace.targetBranch,t.baseSha);let s=await i.createPullRequest(repository(e.workspace),n,e.workspace.targetBranch,e.title.trim(),body(e.description,t));return receipt(e.workspace,t,n,o,s)}function selfModificationBranchName(e,t){return assertFullSha(e,`proposal base revision`),assertOperationId(t),`eve-self-modification/${e.slice(0,12)}/${createHash(`sha256`).update(t).digest(`hex`).slice(0,24)}`}async function reconcile(e,t,n,r,i){let a=await e.commit(repository(t.workspace),i);if(a.parent!==n.baseSha)throw Error(`Self-modification operation conflict: existing branch has a different base.`);if(a.tree!==n.proposedTreeSha)throw Error(`Self-modification operation conflict: existing branch has different edits.`);let o=await e.pullRequest(repository(t.workspace),r,t.workspace.targetBranch);if(o===null)return await assertTargetAtBase(e,repository(t.workspace),t.workspace.targetBranch,n.baseSha),receipt(t.workspace,n,r,i,await e.createPullRequest(repository(t.workspace),r,t.workspace.targetBranch,t.title.trim(),body(t.description,n)));if(!o.draft)throw Error(`Self-modification operation conflict: its pull request is no longer a draft.`);return receipt(t.workspace,n,r,i,o)}async function upload(e,t,n){let r=await Promise.all(n.changes.map(async n=>n.objectId===null?{mode:`100644`,path:n.path,sha:null,type:`blob`}:{mode:n.mode,path:n.path,sha:await e.blob(repository(t.workspace),await readProposalBlob({change:n,sandbox:t.sandbox,workspace:t.workspace})),type:`blob`})),i=await e.tree(repository(t.workspace),n.baseTreeSha,r);if(i!==n.proposedTreeSha)throw Error(`GitHub did not reassemble the validated proposal tree.`);return await e.commitCreate(repository(t.workspace),n.baseSha,i,`eve self-modification proposal\n\nOperation: ${createHash(`sha256`).update(t.operationId).digest(`hex`).slice(0,24)}`)}async function assertTargetAtBase(e,t,n,r){assertGitRef(n);let i=await e.ref(t,n);if(i===null)throw Error(`Self-modification target branch ${JSON.stringify(n)} does not exist.`);if(i!==r.toLowerCase())throw Error(`Self-modification target branch changed while the proposal was being prepared.`)}function repository(e){return e.repository}function receipt(e,t,n,r,i){if(!i.draft)throw Error(`GitHub did not create a draft self-modification pull request.`);let a=repository(e);return{branch:n,changedPaths:t.changes.map(e=>e.path),commitSha:r,deployed:!1,draft:!0,merged:!1,pullRequestUrl:i.url,repository:`github.com/${a.owner}/${a.repo}`,targetBranch:e.targetBranch}}function body(e,t){return`${e}\n\n---\n\nThis is a draft proposal. Merge and deployment have not occurred.\n\n## Changed files\n${t.changes.map(e=>`- \`${e.path}\``).join(`
2
+ `)}`}function validateText(e,t,n,r){if(e.trim().length===0||e.length>n||!r&&/[\x00-\x1f\x7f]/u.test(e))throw Error(`Self-modification pull request ${t} is invalid.`)}var GitHubClient=class{requestFetch;token;constructor(e,t){this.requestFetch=e,this.token=t}async ref(e,t){let n=await this.request(e,`GET`,`/git/ref/heads/${t.split(`/`).map(encodeURIComponent).join(`/`)}`,void 0,!0);if(n===null||Array.isArray(n)||!record(n).object)return null;let r=record(record(n).object).sha;if(typeof r!=`string`)throw Error(`GitHub returned an invalid ref.`);return assertFullSha(r,`GitHub ref`),r.toLowerCase()}async commit(e,t){let n=record(await this.request(e,`GET`,`/git/commits/${t}`)),r=n.parents,i=record(n.tree).sha;if(!Array.isArray(r)||r.length!==1||typeof i!=`string`)throw Error(`GitHub returned an invalid commit.`);let a=record(r[0]).sha;if(typeof a!=`string`)throw Error(`GitHub returned an invalid commit.`);return assertFullSha(a,`GitHub parent`),assertFullSha(i,`GitHub tree`),{parent:a.toLowerCase(),tree:i.toLowerCase()}}async blob(e,t){return this.sha(await this.request(e,`POST`,`/git/blobs`,{content:t,encoding:`base64`}))}async tree(e,t,n){return this.sha(await this.request(e,`POST`,`/git/trees`,{base_tree:t,tree:n}))}async commitCreate(e,t,n,r){return this.sha(await this.request(e,`POST`,`/git/commits`,{message:r,parents:[t],tree:n}))}async createRef(e,t,n){await this.request(e,`POST`,`/git/refs`,{ref:`refs/heads/${t}`,sha:n})}async pullRequest(e,t,n){let r=new URLSearchParams({head:`${e.owner}:${t}`,state:`all`}),i=await this.request(e,`GET`,`/pulls?${r}`);if(!Array.isArray(i))throw Error(`GitHub returned an invalid pull request list.`);return i[0]===void 0?null:pullRequest(i[0],e,t,n)}async createPullRequest(e,t,n,r,i){return pullRequest(await this.request(e,`POST`,`/pulls`,{base:n,body:i,draft:!0,head:t,title:r}),e,t,n)}async sha(e){let t=record(e).sha;if(typeof t!=`string`)throw Error(`GitHub returned an invalid Git object.`);return assertFullSha(t,`GitHub object`),t.toLowerCase()}async request(e,t,n,r,i=!1){let a={accept:`application/vnd.github+json`,authorization:`Bearer ${this.token}`,"user-agent":`eve-self-modification`,"x-github-api-version":`2022-11-28`};r!==void 0&&(a[`content-type`]=`application/json`);let o=await this.requestFetch(`https://api.github.com/repos/${encodeURIComponent(e.owner)}/${encodeURIComponent(e.repo)}${n}`,{body:r===void 0?void 0:JSON.stringify(r),headers:a,method:t,signal:AbortSignal.timeout(3e4)});if(i&&o.status===404)return null;if(!o.ok)throw Error(`GitHub ${t} ${n} failed with HTTP ${o.status}.`);return await o.json()}};function record(e){if(typeof e!=`object`||!e||Array.isArray(e))throw Error(`GitHub returned an invalid response.`);return e}function pullRequest(e,t,n,r){let i=record(e),a=i.draft,o=i.state,s=i.html_url;if(typeof a!=`boolean`||o!==`open`||typeof s!=`string`||record(i.head).ref!==n||record(i.base).ref!==r||!s.startsWith(`https://github.com/${t.owner}/${t.repo}/pull/`))throw Error(`GitHub returned an invalid pull request.`);return{draft:a,url:s}}export{publishGitHubDraftPullRequest,selfModificationBranchName};
@@ -0,0 +1,4 @@
1
+ export declare function assertFullSha(value: string, label: string): void;
2
+ export declare function assertRepositoryPart(value: string, label: string): void;
3
+ export declare function assertGitRef(value: string, label?: string): void;
4
+ export declare function assertOperationId(operationId: string): void;
@@ -0,0 +1 @@
1
+ import{isFullGitSha,isValidGitRef}from"#shared/git.js";function assertFullSha(e,t){if(!isFullGitSha(e))throw Error(`Self-modification ${t} must be a full Git SHA.`)}function assertRepositoryPart(e,t){if(!/^[A-Za-z0-9_.-]+$/u.test(e)||e===`.`||e===`..`||e.startsWith(`-`))throw Error(`Self-modification ${t} is invalid.`)}function assertGitRef(e,t=`target branch`){if(!isValidGitRef(e))throw Error(`Self-modification ${t} is not a valid Git ref.`)}function assertOperationId(e){if(e.length===0||e.length>512)throw Error(`Self-modification operation id must contain 1–512 characters.`)}export{assertFullSha,assertGitRef,assertOperationId,assertRepositoryPart};
@@ -0,0 +1,4 @@
1
+ import type { ResolvedSelfModificationConfig } from "./config.js";
2
+ export type SelfModificationMode = "local" | "disabled" | "deployed";
3
+ /** Resolves the mutually exclusive local or deployed editing mode. */
4
+ export declare function resolveSelfModificationMode(config: ResolvedSelfModificationConfig): SelfModificationMode;
@@ -0,0 +1 @@
1
+ function resolveSelfModificationMode(e){return process.env.EVE_DEV===`1`?e.localEnabled?`local`:`disabled`:e.deployed===void 0||e.deployed.credentials.kind===`vercel-connect`&&process.env.VERCEL_ENV!==`production`?`disabled`:`deployed`}export{resolveSelfModificationMode};
@@ -0,0 +1 @@
1
+ export declare const SELF_MODIFICATION_BASELINE_NETWORK_POLICY: "allow-all";
@@ -0,0 +1 @@
1
+ const SELF_MODIFICATION_BASELINE_NETWORK_POLICY=`allow-all`;export{SELF_MODIFICATION_BASELINE_NETWORK_POLICY};
@@ -0,0 +1,39 @@
1
+ import type { SandboxSession } from "eve/sandbox";
2
+ import type { PreparedSelfModificationWorkspace } from "./git-workspace.js";
3
+ export declare const MAX_PROPOSAL_CHANGED_BYTES = 1000000;
4
+ export declare const MAX_PROPOSAL_CHANGED_FILES = 100;
5
+ export interface ProposalChange {
6
+ readonly bytes: number;
7
+ readonly kind: "add" | "delete" | "modify";
8
+ readonly mode: "100644" | "100755" | null;
9
+ readonly objectId: string | null;
10
+ readonly path: string;
11
+ }
12
+ export interface SelfModificationProposal {
13
+ readonly baseSha: string;
14
+ readonly baseTreeSha: string;
15
+ readonly changedBytes: number;
16
+ readonly changes: readonly ProposalChange[];
17
+ readonly proposedTreeSha: string;
18
+ }
19
+ type ProposalSandbox = Pick<SandboxSession, "run">;
20
+ /** Captures and validates the worktree before any publication credential is resolved. */
21
+ export declare function captureSelfModificationProposal(input: {
22
+ readonly sandbox: ProposalSandbox;
23
+ readonly workspace: PreparedSelfModificationWorkspace;
24
+ }): Promise<SelfModificationProposal>;
25
+ /** Reads an already captured blob and verifies its Git object id before upload. */
26
+ export declare function readProposalBlob(input: {
27
+ readonly change: ProposalChange;
28
+ readonly sandbox: ProposalSandbox;
29
+ readonly workspace: PreparedSelfModificationWorkspace;
30
+ }): Promise<string>;
31
+ interface RawChange {
32
+ readonly newMode: string;
33
+ readonly newObjectId: string;
34
+ readonly path: string;
35
+ readonly status: "A" | "D" | "M";
36
+ }
37
+ export declare function parseRawDiff(raw: string): readonly RawChange[];
38
+ export declare function assertAllowedChange(change: Pick<ProposalChange, "mode" | "objectId" | "path">, directory: string): void;
39
+ export {};
@@ -0,0 +1,2 @@
1
+ import{assertFullSha}from"./identifiers.js";import{gitOutput,runGitCommand}from"./git.js";import{createHash}from"node:crypto";import{shellQuote}from"#shared/shell-quote.js";const MAX_PROPOSAL_CHANGED_BYTES=1e6,MAX_PROPOSAL_CHANGED_FILES=100;async function captureSelfModificationProposal(e){let t=quote(e.workspace.repositoryPath);assertFullSha(e.workspace.baseSha,`proposal base revision`),await runGitCommand(e.sandbox,`git -C ${t} add -A -- .`);let n=await gitOutput(e.sandbox,`git -C ${t} write-tree`),r=await gitOutput(e.sandbox,`git -C ${t} rev-parse ${quote(`${e.workspace.baseSha}^{tree}`)}`);assertFullSha(n,`proposal tree`),assertFullSha(r,`proposal base tree`);let i=parseRawDiff(await gitOutput(e.sandbox,`git -C ${t} diff-tree -r --no-commit-id --raw -z --no-renames ${quote(e.workspace.baseSha)} ${quote(n)}`,!1));if(i.length===0)throw Error(`Self-modification proposal contains no changes.`);if(i.length>100)throw Error(`Self-modification proposal changes ${i.length} files; limit is 100.`);let a=[],o=0;for(let t of i){let n=t.status===`D`?null:proposalMode(t.newMode,t.path),r=t.status===`D`?null:t.newObjectId;assertAllowedChange({mode:n,objectId:r,path:t.path},e.workspace.directory);let i=r===null?0:await blobSize(e.sandbox,e.workspace.repositoryPath,r);if(o+=i,o>1e6)throw Error(`Self-modification proposal changes more than ${MAX_PROPOSAL_CHANGED_BYTES} bytes.`);a.push({bytes:i,kind:t.status===`A`?`add`:t.status===`D`?`delete`:`modify`,mode:n,objectId:r,path:t.path})}return{baseSha:e.workspace.baseSha,baseTreeSha:r,changedBytes:o,changes:a,proposedTreeSha:n}}async function readProposalBlob(e){if(e.change.objectId===null)throw Error(`Cannot read a deleted proposal blob.`);let t=await gitOutput(e.sandbox,`git -C ${quote(e.workspace.repositoryPath)} cat-file blob ${quote(e.change.objectId)} | base64 | tr -d '\\n'`),n=Buffer.from(t,`base64`),r=createHash(`sha1`).update(`blob ${n.byteLength}\0`).update(n).digest(`hex`);if(n.byteLength!==e.change.bytes||r!==e.change.objectId.toLowerCase())throw Error(`Self-modification proposal blob changed after validation: ${JSON.stringify(e.change.path)}.`);return t}function parseRawDiff(e){if(e.length===0)return[];let t=e.split(`\0`);if(t.at(-1)===``&&t.pop(),t.length%2!=0)throw Error(`Git returned malformed raw diff output.`);let n=[];for(let e=0;e<t.length;e+=2){let r=t[e],i=t[e+1],a=r===void 0?null:/^:[0-7]{6} ([0-7]{6}) [a-f0-9]{40} ([a-f0-9]{40}) ([ADM])$/u.exec(r);if(a===null||i===void 0||!isSafePath(i))throw Error(`Git returned malformed raw diff output.`);n.push({newMode:a[1],newObjectId:a[2],path:i,status:a[3]})}return n}function assertAllowedChange(e,t){let n=e.path,r=t===`.`?``:`${t}/`,i=`${r}agent/`,a=n.split(`/`),o=a.at(-1)??``;if(!isSafePath(n)||a.includes(`.git`)||o===`.env`||o===`.envrc`||o.startsWith(`.env.`)||a.some(e=>[`node_modules`,`dist`,`build`,`.next`,`.output`,`.turbo`,`.vercel`,`coverage`,`out`].includes(e))||n.startsWith(`.github/workflows/`)||n.startsWith(`${i}subagents/self-modification/`)||n===`${r}agent/extensions/selfmod.ts`||n===`${r}agent/self-modification.config.ts`)throw Error(`Self-modification proposal changes a protected path: ${JSON.stringify(n)}.`)}function isSafePath(e){return e.length>0&&!e.startsWith(`/`)&&!e.includes(`\\`)&&!e.includes(`
2
+ `)&&!e.includes(`\r`)&&!e.split(`/`).some(e=>e===``||e===`.`||e===`..`)}function proposalMode(e,t){if(e===`100644`||e===`100755`)return e;throw Error(`Self-modification proposal uses unsafe Git mode ${e}: ${JSON.stringify(t)}.`)}async function blobSize(e,t,n){assertFullSha(n,`proposal blob`);let r=await gitOutput(e,`git -C ${quote(t)} cat-file -s ${quote(n)}`);if(!/^\d+$/u.test(r)||!Number.isSafeInteger(Number(r)))throw Error(`Git returned an invalid blob size.`);return Number(r)}function quote(e){return shellQuote(e)}export{MAX_PROPOSAL_CHANGED_BYTES,MAX_PROPOSAL_CHANGED_FILES,assertAllowedChange,captureSelfModificationProposal,parseRawDiff,readProposalBlob};
@@ -1,2 +1,26 @@
1
- declare const _default: import("#public/sandbox/index.js").SandboxDefinition<Record<string, never>, Record<string, never>>;
1
+ import { type DefaultSandboxProbes } from "#sandbox/backends/default.js";
2
+ import { type SandboxBackend, type SandboxDefinition } from "#public/sandbox/index.js";
3
+ import { type SelfModificationConfig } from "./config.js";
4
+ export interface SelfModificationSandboxOptions {
5
+ /**
6
+ * Production backend. Deployed self-modification owns an allow-all network
7
+ * policy and temporarily adds a credential transform while checking out its
8
+ * source. When omitted, eve selects Vercel Sandbox on Vercel or microsandbox
9
+ * on a supported self-hosted system.
10
+ */
11
+ readonly backend?: SandboxBackend;
12
+ /** Policy shared with the agent and extension mount. */
13
+ readonly config?: SelfModificationConfig;
14
+ }
15
+ type SelfModificationSandboxProbes = Pick<DefaultSandboxProbes, "isDeployedOnVercel" | "isMicrosandboxSupported">;
16
+ /** Defines the local source mount or isolated production proposal workspace. */
17
+ export declare function defineSelfModificationSandbox(options?: SelfModificationSandboxOptions): SandboxDefinition;
18
+ /**
19
+ * Deployed self-modification deliberately selects a backend that can inject
20
+ * GitHub auth at the network boundary, keeping the credential outside the
21
+ * sandbox and agent. Docker and just-bash do not provide that separation.
22
+ * Internal—exported for tests, which inject availability probes.
23
+ */
24
+ export declare function selectDeployedSelfModificationBackend(configured: SandboxBackend | undefined, probes: SelfModificationSandboxProbes): SandboxBackend;
25
+ declare const _default: SandboxDefinition;
2
26
  export default _default;
@@ -1 +1 @@
1
- import{createSelfModificationFilesystem}from"./filesystem.js";import{defineSandbox}from"#public/sandbox/index.js";import{justbash}from"#public/sandbox/just-bash.js";var sandbox_default=defineSandbox({backend:justbash({filesystem:createSelfModificationFilesystem})});export{sandbox_default as default};
1
+ import{resolveSelfModificationConfig}from"./config.js";import{createGitHubCredentialProvider}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{SELF_MODIFICATION_BASELINE_NETWORK_POLICY}from"./network-policy.js";import{REPOSITORY_PATH,prepareSelfModificationWorkspace}from"./git-workspace.js";import{createSelfModificationFilesystem}from"./filesystem.js";import{shellQuote}from"#shared/shell-quote.js";import{SANDBOX_BACKEND_PROBES}from"#sandbox/backends/default.js";import{defaultBackend,defineSandbox}from"#public/sandbox/index.js";import{justbash}from"#public/sandbox/just-bash.js";import{microsandbox}from"#public/sandbox/microsandbox.js";import{vercel}from"#public/sandbox/vercel.js";function defineSelfModificationSandbox(e={}){let t=resolveSelfModificationConfig(e.config);return defineSandbox({backend:()=>{let n=resolveSelfModificationMode(t);return n===`local`?justbash({filesystem:createSelfModificationFilesystem}):n===`disabled`?e.backend??defaultBackend():selectDeployedSelfModificationBackend(e.backend,SANDBOX_BACKEND_PROBES)},async onSession({ctx:e,use:n}){if(resolveSelfModificationMode(t)!==`deployed`||t.deployed===void 0)return;if(e.session.parent===void 0)throw Error(`Production self-modification workspaces require a delegated child session.`);let r=t.deployed,i=await n();await i.setNetworkPolicy(SELF_MODIFICATION_BASELINE_NETWORK_POLICY);let a=await createGitHubCredentialProvider(r.credentials).resolve({capability:`checkout`,repository:r.repository});await prepareSelfModificationWorkspace({directory:r.directory,repository:r.repository,sandbox:i,targetBranch:r.targetBranch,token:a});let o=r.directory===`.`?REPOSITORY_PATH:`${REPOSITORY_PATH}/${r.directory}`;if((await i.run({command:`rm -rf /source && ln -s ${shellQuote(`${o}/agent`)} /source`})).exitCode!==0)throw Error(`Self-modification could not mount the production agent source.`)}})}function selectDeployedSelfModificationBackend(e,t){if(e!==void 0){if(e.name===`vercel`||e.name===`microsandbox`)return e;throw unsupportedBackend(e.name)}if(t.isDeployedOnVercel())return vercel({networkPolicy:SELF_MODIFICATION_BASELINE_NETWORK_POLICY});if(t.isMicrosandboxSupported())return microsandbox({networkPolicy:SELF_MODIFICATION_BASELINE_NETWORK_POLICY});throw unsupportedBackend()}function unsupportedBackend(e){let t=e===void 0?`No supported backend is available.`:`The configured ${e} backend does not support them.`;return Error(`Deployed self-modification requires runtime credential transforms. ${t} Use vercel() on Vercel or microsandbox() on a supported self-hosted system.`)}var sandbox_default=defineSelfModificationSandbox();export{sandbox_default as default,defineSelfModificationSandbox,selectDeployedSelfModificationBackend};
@@ -0,0 +1,34 @@
1
+ import { relative } from "node:path";
2
+ export interface SelfModificationSetupValues {
3
+ readonly branch: string;
4
+ readonly connector: string;
5
+ readonly directory: string;
6
+ readonly repository: string;
7
+ }
8
+ export interface DetectedGitRepository {
9
+ readonly branch?: string;
10
+ readonly directory?: string;
11
+ readonly owner?: string;
12
+ readonly repo?: string;
13
+ readonly remoteKind: "github" | "missing" | "other";
14
+ }
15
+ export interface SelfModificationSetupOperations {
16
+ attachConnector(connector: string): Promise<void>;
17
+ detectGitRepository(): Promise<DetectedGitRepository>;
18
+ findOrCreateConnector(name: string): Promise<string>;
19
+ readConfig(): Promise<string | undefined>;
20
+ writeConfig(source: string): Promise<void>;
21
+ }
22
+ export declare function connectorName(owner: string, repo: string): string;
23
+ export declare function renderSelfModificationConfig(values?: SelfModificationSetupValues): string;
24
+ /** Distinguishes resumable generated source from authored source without evaluating it. */
25
+ export declare function classifySelfModificationConfig(source: string | undefined): "missing" | "local" | "generated" | "authored";
26
+ export declare function parseGitHubRemote(remote: string): {
27
+ owner: string;
28
+ repo: string;
29
+ } | undefined;
30
+ export declare function defaultSelfModificationSetupOperations(appRoot: string): SelfModificationSetupOperations;
31
+ export declare function repositoryRelativeDirectory(repositoryRoot: string, appRoot: string, relativePath?: typeof relative): string;
32
+ export declare function repositoryPartError(value: string): string | undefined;
33
+ export declare function directoryError(value: string): string | undefined;
34
+ export declare function gitRefError(value: string): string | undefined;
@@ -0,0 +1,22 @@
1
+ import{SELF_MODIFICATION_CONFIG_PATH}from"./git-workspace.js";import{createHash}from"node:crypto";import{readFile,writeFile}from"node:fs/promises";import{join,relative}from"node:path";import{execFile}from"node:child_process";import{promisify}from"node:util";const runFile=promisify(execFile);function connectorName(e,t){return`selfmod-${e}-${t}`.toLowerCase().replaceAll(/[^a-z0-9-]/gu,`-`)}function renderSelfModificationConfig(e){if(e===void 0)return`import { defineSelfModificationConfig } from "eve/self-modification/config";
2
+
3
+ export default defineSelfModificationConfig({});
4
+ `;let t=`import { defineSelfModificationConfig } from "eve/self-modification/config";
5
+
6
+ export default defineSelfModificationConfig({
7
+ deployed: {
8
+ source: {
9
+ git: {
10
+ repository: ${JSON.stringify(e.repository)},
11
+ directory: ${JSON.stringify(e.directory)},
12
+ },
13
+ },
14
+ target: { branch: ${JSON.stringify(e.branch)} },
15
+ credentials: {
16
+ vercelConnect: { connector: ${JSON.stringify(e.connector)} },
17
+ },
18
+ },
19
+ });
20
+ `;return`// eve-self-modification: generated-v1 digest:${createHash(`sha256`).update(t).digest(`hex`)}\n${t}`}function classifySelfModificationConfig(e){if(e===void 0)return`missing`;if(e===renderSelfModificationConfig())return`local`;let[t,...n]=e.split(`
21
+ `);return/^\/\/ eve-self-modification: generated-v1 digest:([a-f0-9]{64})$/u.exec(t??``)?.[1]===createHash(`sha256`).update(n.join(`
22
+ `)).digest(`hex`)?`generated`:`authored`}function parseGitHubRemote(e){let t=e.trim().match(/^(?:https?:\/\/github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?$/u);return t?.[1]===void 0||t[2]===void 0?void 0:{owner:t[1],repo:t[2]}}function defaultSelfModificationSetupOperations(e){let t=join(e,SELF_MODIFICATION_CONFIG_PATH);return{async detectGitRepository(){let t=await gitOutput(e,[`config`,`--get`,`remote.origin.url`]),n=t===void 0?void 0:parseGitHubRemote(t),r=await gitOutput(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]),i=await gitOutput(e,[`rev-parse`,`--show-toplevel`]);return{...n,branch:r?.replace(/^origin\//u,``),directory:i===void 0?void 0:repositoryRelativeDirectory(i,e),remoteKind:t===void 0?`missing`:n===void 0?`other`:`github`}},async readConfig(){try{return await readFile(t,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}},writeConfig:e=>writeFile(t,e,`utf8`),async findOrCreateConnector(t){let n=await vercel(e,[`connect`,`list`,`-F`,`json`]);if(!n.ok)throw Error(`Vercel Connect requires an authenticated Vercel CLI linked to this project.`);let r=parseConnectors(n.stdout),i=`github/${t}`,a=r.find(e=>e.uid===i);if(a!==void 0){if(a.type!==`github`)throw Error(`The existing connector ${i} is not a GitHub connector.`);return a.uid}let o=await vercel(e,[`connect`,`create`,`github`,`--name`,t,`-F`,`json`]),s=o.ok?parseCreatedConnector(o.stdout):void 0;if(s===void 0||!s.startsWith(`github/`))throw Error(`Could not create a GitHub Vercel Connect connector.`);return s},async attachConnector(t){let n=await readLinkedProject(e);if(n===void 0)throw Error("Vercel Connect requires this directory to be linked to a Vercel project. Run `vercel link` and retry.");if(!(await vercel(e,[`connect`,`attach`,t,`--project`,n.projectId,`--environment`,`production`,`--yes`])).ok)throw Error(`Could not attach ${t} to the linked Vercel project for Production.`)}}}function parseCreatedConnector(e){try{let t=JSON.parse(e);return typeof t.uid==`string`?t.uid:void 0}catch{return}}function parseConnectors(e){try{let t=JSON.parse(e);return(Array.isArray(t.connectors)?t.connectors:[t]).flatMap(e=>typeof e==`object`&&e&&typeof e.uid==`string`&&typeof e.type==`string`?[{uid:e.uid,type:e.type}]:[])}catch{return[]}}async function vercel(e,t){try{return{ok:!0,stdout:(await runFile(`vercel`,t,{cwd:e})).stdout}}catch{return{ok:!1,stdout:``}}}async function readLinkedProject(e){try{let t=JSON.parse(await readFile(join(e,`.vercel`,`project.json`),`utf8`));return typeof t.projectId==`string`?{projectId:t.projectId}:void 0}catch{return}}function repositoryRelativeDirectory(e,t,n=relative){return n(e,t).replaceAll(`\\`,`/`)||`.`}function repositoryPartError(e){return/^[A-Za-z0-9_.-]+$/u.test(e)?void 0:`Enter a valid GitHub owner or repository name.`}function directoryError(e){return e===`.`||e.length>0&&!e.startsWith(`/`)&&!e.includes(`\\`)&&e.split(`/`).every(e=>e!==``&&e!==`.`&&e!==`..`)?void 0:`Enter a safe repository-relative directory or ".".`}function gitRefError(e){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(e)&&!e.endsWith(`.`)&&!e.endsWith(`/`)&&!e.includes(`..`)&&!e.includes(`//`)&&!e.includes(`@{`)?void 0:`Enter a valid branch name.`}async function gitOutput(e,t){try{return(await runFile(`git`,t,{cwd:e})).stdout.trim()||void 0}catch{return}}export{classifySelfModificationConfig,connectorName,defaultSelfModificationSetupOperations,directoryError,gitRefError,parseGitHubRemote,renderSelfModificationConfig,repositoryPartError,repositoryRelativeDirectory};
@@ -0,0 +1,2 @@
1
+ /** Serializes operations that require an exclusive view of one self-modification workspace. */
2
+ export declare function withSelfModificationWorkspaceLock<T>(workspaceKey: string, operation: () => Promise<T>): Promise<T>;
@@ -0,0 +1 @@
1
+ const workspaceTails=new Map;async function withSelfModificationWorkspaceLock(e,t){let n=workspaceTails.get(e)??Promise.resolve(),r,i=new Promise(e=>{r=e}),a=n.then(()=>i);workspaceTails.set(e,a),await n;try{return await t()}finally{r(),workspaceTails.get(e)===a&&workspaceTails.delete(e)}}export{withSelfModificationWorkspaceLock};
@@ -1,2 +1,14 @@
1
- /** Ensures Codex owns a usable ChatGPT login before setup authors `chatgpt()`. */
2
- export declare function ensureChatGptAuth(): Promise<void>;
1
+ import { type ChatGptCredentialStore } from "#public/models/openai/chatgpt/credential-store.js";
2
+ import { type CodexTokenBroker } from "#public/models/openai/chatgpt/token-broker.js";
3
+ interface ChatGptAuthOptions {
4
+ readonly signal?: AbortSignal;
5
+ readonly broker?: CodexTokenBroker;
6
+ readonly store?: ChatGptCredentialStore;
7
+ readonly fetch?: typeof fetch;
8
+ readonly open?: (url: string) => void;
9
+ readonly log?: (message: string) => void;
10
+ readonly headless?: boolean;
11
+ }
12
+ /** Signs in directly with OpenAI; credentials belong to eve, independently of Codex. */
13
+ export declare function ensureChatGptAuth(options?: ChatGptAuthOptions): Promise<void>;
14
+ export {};
@@ -1 +1 @@
1
- import{spawn}from"node:child_process";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";async function ensureChatGptAuth(){if((await getDefaultCodexTokenBroker().refreshState()).kind===`ready`)return;let e=spawn(`codex`,[`login`],{stdio:`inherit`});if(await new Promise((t,n)=>{e.once(`error`,n),e.once(`exit`,(e,r)=>{e===0?t():n(Error(`codex login failed (${r??e??`unknown`}).`))})}),(await getDefaultCodexTokenBroker().refreshState()).kind!==`ready`)throw Error(`Codex login completed without a usable ChatGPT session.`)}export{ensureChatGptAuth};
1
+ import{createHash,randomBytes}from"node:crypto";import{createServer}from"node:http";import{WizardCancelledError}from"#setup/step.js";import{isErrnoCode,isObject}from"#shared/guards.js";import{setTimeout as setTimeout$1}from"node:timers/promises";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{createChatGptCredentialStore}from"#public/models/openai/chatgpt/credential-store.js";import{CHATGPT_CLIENT_ID,CHATGPT_ISSUER,readChatGptAuthResponse,requestChatGptTokens}from"#public/models/openai/chatgpt/oauth.js";import{openUrl}from"#setup/primitives/open-url.js";const REDIRECT_URI=`http://localhost:1455/auth/callback`;async function ensureChatGptAuth(e={}){let t=e.broker??getDefaultCodexTokenBroker();if(e.signal?.throwIfAborted(),(await t.refreshState()).kind===`ready`)return;let n=new AbortController,cancel=()=>n.abort(new WizardCancelledError);process.once(`SIGINT`,cancel);let r=setTimeout(()=>n.abort(Error(`ChatGPT sign-in timed out. Retry from /model.`)),3e5),i=AbortSignal.any([n.signal,...e.signal?[e.signal]:[]]),a=e.log??(e=>process.stdout.write(`${e}\n`)),o=e.open??openUrl;try{let n=e.headless??!!(process.env.SSH_CONNECTION||process.env.SSH_TTY)?await deviceLogin({...e,signal:i,log:a,open:o}):await browserLogin({...e,signal:i,log:a,open:o});if(i.throwIfAborted(),await(e.store??createChatGptCredentialStore()).update(async()=>(i.throwIfAborted(),n)),(await t.refreshState()).kind!==`ready`)throw Error(`ChatGPT sign-in could not be verified. Retry from /model.`);a(`ChatGPT subscription connected.`)}catch(e){throw i.throwIfAborted(),e}finally{clearTimeout(r),process.removeListener(`SIGINT`,cancel)}}async function browserLogin(e){let t=randomBytes(32).toString(`base64url`),n=randomBytes(32).toString(`base64url`),r=new URL(`${CHATGPT_ISSUER}/oauth/authorize`);r.search=new URLSearchParams({response_type:`code`,client_id:CHATGPT_CLIENT_ID,redirect_uri:REDIRECT_URI,scope:`openid profile email offline_access`,code_challenge:createHash(`sha256`).update(t).digest(`base64url`),code_challenge_method:`S256`,id_token_add_organizations:`true`,codex_cli_simplified_flow:`true`,state:n,originator:`eve`}).toString();let i=Promise.withResolvers();i.promise.catch(()=>{});let a=createServer({requestTimeout:1e4,headersTimeout:1e4,maxHeaderSize:8192},(e,t)=>{let r=URL.parse(e.url??``,REDIRECT_URI);if(t.setHeader(`content-type`,`text/plain; charset=utf-8`),t.setHeader(`cache-control`,`no-store`),e.method!==`GET`||r?.pathname!==`/auth/callback`){t.writeHead(404).end(`Not found.`);return}if(r.searchParams.get(`state`)!==n){t.writeHead(400).end(`This sign-in belongs to another attempt. Return to eve and use its sign-in link.`);return}if(r.searchParams.has(`error`)){t.writeHead(400).end(`ChatGPT sign-in was declined. Return to eve to retry.`),i.reject(Error(`ChatGPT sign-in was declined. Retry from /model.`));return}let a=r.searchParams.get(`code`);if(!a){t.writeHead(400).end(`Missing authorization code.`);return}t.end(`Authorization received. Return to eve to finish connecting your ChatGPT subscription.`),i.resolve(a)});a.maxConnections=10;let abort=()=>i.reject(e.signal.reason);e.signal.addEventListener(`abort`,abort,{once:!0});try{e.signal.throwIfAborted();try{await new Promise((e,t)=>{a.once(`error`,t),a.listen(1455,`127.0.0.1`,e)})}catch(t){if(!isErrnoCode(t,`EADDRINUSE`))throw Error(`Could not start ChatGPT sign-in on localhost:1455. Free the port and retry from /model.`);return e.log(`Local sign-in port is in use. Continuing with a device code.`),await deviceLogin(e)}e.signal.throwIfAborted(),e.log(`Sign in to ChatGPT in your browser:\n${r.href}\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(r.href);let n=await i.promise;return await requestChatGptTokens({grant_type:`authorization_code`,code:n,code_verifier:t,redirect_uri:REDIRECT_URI},e)}finally{e.signal.removeEventListener(`abort`,abort),a.closeAllConnections(),await new Promise(e=>a.close(()=>e()))}}async function deviceLogin(e){let t=await deviceRequest(`usercode`,{client_id:CHATGPT_CLIENT_ID},e);if(!t.ok)throw Error(`ChatGPT device sign-in is unavailable (HTTP ${t.status}). Enable device code authorization in ChatGPT Settings > Security, then retry from /model.`);let n=await readChatGptAuthResponse(t);if(!isObject(n)||typeof n.device_auth_id!=`string`||!n.device_auth_id||typeof n.user_code!=`string`||!/^[A-Z0-9-]{4,32}$/iu.test(n.user_code))throw Error(`ChatGPT returned an invalid device code. Retry from /model.`);let r=Math.min(30,Math.max(1,Number(n.interval)||5))*1e3,i=`${CHATGPT_ISSUER}/codex/device`;for(e.log(`Open ${i} and enter code: ${n.user_code}\nIf prompted, enable device code authorization in ChatGPT Settings > Security.\nWaiting for sign-in. Press Ctrl+C to cancel.`),e.open(i);;){await setTimeout$1(r+1e3,void 0,{signal:e.signal});let t=await deviceRequest(`token`,{device_auth_id:n.device_auth_id,user_code:n.user_code},e);if(t.status===403||t.status===404)continue;if(!t.ok)throw Error(`ChatGPT device sign-in failed (HTTP ${t.status}). Retry from /model.`);let i=await readChatGptAuthResponse(t);if(!isObject(i)||typeof i.authorization_code!=`string`||!i.authorization_code||typeof i.code_verifier!=`string`||!i.code_verifier)throw Error(`ChatGPT returned an invalid device authorization. Retry from /model.`);return requestChatGptTokens({grant_type:`authorization_code`,code:i.authorization_code,code_verifier:i.code_verifier,redirect_uri:`${CHATGPT_ISSUER}/deviceauth/callback`},e)}}async function deviceRequest(e,t,n){try{return await(n.fetch??fetch)(`${CHATGPT_ISSUER}/api/accounts/deviceauth/${e}`,{method:`POST`,headers:{"content-type":`application/json`,"user-agent":`eve`},body:JSON.stringify(t),redirect:`error`,signal:AbortSignal.any([n.signal,AbortSignal.timeout(3e4)])})}catch{throw n.signal.throwIfAborted(),Error(`Could not reach ChatGPT device sign-in. Check your connection and retry from /model.`)}}export{ensureChatGptAuth};
@@ -83,7 +83,7 @@ export interface ModelFlowDeps {
83
83
  readProviderSelection: typeof readProviderSelection;
84
84
  /** The provider sub-flow behind the menu's provider row. */
85
85
  runProviderFlow: typeof runProviderFlow;
86
- /** Ensures Codex owns a usable login before selecting ChatGPT. */
86
+ /** Ensures eve has a usable ChatGPT login before selecting the subscription. */
87
87
  ensureChatGptAuth: typeof ensureChatGptAuth;
88
88
  writeProviderSelection: typeof writeProviderSelection;
89
89
  }
@@ -118,8 +118,9 @@ export declare function runModelFlow(input: {
118
118
  prompter: Prompter;
119
119
  /** Opens provider setup before the root menu when runtime evidence requires it. */
120
120
  initialStep?: "provider";
121
+ onScreen?: (screen: "model_provider" | "model_settings") => void;
121
122
  signal?: AbortSignal;
122
- /** Gives Codex uncontested inherited stdio while it performs login. */
123
+ /** Gives ChatGPT sign-in exclusive terminal ownership. */
123
124
  withExclusiveTerminal?: <T>(task: () => Promise<T>) => Promise<T>;
124
125
  /** Live ChatGPT identity shown in this configuration flow only. */
125
126
  chatGptAccountLabel?: string;
@@ -1 +1 @@
1
- import{AI_GATEWAY_API_KEY_ENV_VAR}from"../ai-gateway-api-key.js";import{withSpinner}from"../with-spinner.js";import{gatewayModelCapabilities}from"../boxes/model-capabilities.js";import{fetchGatewayCatalog,modelOptionsFromCatalog}from"../boxes/select-model.js";import{ensureChatGptAuth}from"./chatgpt-auth.js";import{WizardCancelledError}from"../step.js";import{changeAgentModelSettings,formatApplyModelSettingsOutcome}from"./model-source-change.js";import{runProviderFlow}from"./provider.js";import pc from"#compiled/picocolors/index.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{inspectApplication}from"#services/inspect-application.js";import{readProviderSelection,resolveAvailableProviders,writeProviderSelection}from"#setup/provider-settings.js";import{formatModelSummary}from"#shared/model-summary.js";import{readGatewayServiceTier}from"#shared/gateway-service-tier.js";import{DEFAULT_CHATGPT_MODEL_SELECTION,isChatGptModelRouting,parseChatGptModelSelection}from"#shared/chatgpt-model.js";const MODEL_MENU_MESSAGE=``;function providerSelectionHint(e,t){return e===`chatgpt`?t===void 0?`ChatGPT subscription`:`ChatGPT subscription (${t})`:e===`ai-gateway-project`?`AI Gateway via Project`:`AI Gateway via ${AI_GATEWAY_API_KEY_ENV_VAR}`}function modelListRows(e){return modelOptionsFromCatalog(e).map(e=>{let t={value:e.value,label:e.value};return e.featured===!0&&(t.featured=!0),t})}function formatModelDraftHint(e,t,n){let r={model:e};return t!==null&&(r.reasoning=t),n.kind===`priority`&&(r.fastGlyph=`↯`),formatModelSummary(r)}function modelMenuRows(e,t,n,r,i,a,o,s,c){let l;s||c?(l={value:`model`,label:`Change model`,description:s?`The model, its reasoning effort, and the Gateway service tier`:`Reasoning and service tier; the model itself is an SDK model call in agent.ts`},e!==null&&(l.hint=formatModelDraftHint(e,t,n))):l={value:`model`,label:`Change model`,disabled:!0,description:`Set via an SDK model call in agent.ts; edit the source to change it`};let u;return u=o?.kind===`external`&&!isChatGptModelRouting(o)?{disabled:!0,value:`provider`,label:`Change provider`,description:`Disabled in external endpoint mode`}:i?{value:`provider`,label:`Change provider`,hint:providerSelectionHint(r,a),description:`How your agent reaches the model provider`}:{value:`provider`,label:pc.bold(`Configure model access`),hint:pc.yellow(`Not configured`),description:`How your agent reaches the model provider`,accent:`warning`},[l,u,{value:`done`,label:`Done`}]}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i=e.environmentRoot??t,a={readCurrentModel:readCurrentAgentModel,applySettings:changeAgentModelSettings,resolveAvailableProviders,readProviderSelection,runProviderFlow,ensureChatGptAuth,writeProviderSelection,...e.deps},o=a.selectModel?.fetchModels??fetchGatewayCatalog,[s,c,l,u]=await withSpinner(n,`Checking the project…`,()=>Promise.all([a.readCurrentModel(t),a.resolveAvailableProviders(i,r===void 0?{env:process.env}:{signal:r,env:process.env}),a.readProviderSelection(i),o(r).catch(()=>void 0)]));r?.throwIfAborted();let{id:d,routing:f,serviceTier:p,editable:m,settingsEditable:h}=s,g=s.reasoning===`provider-default`?null:s.reasoning,_=l??(c.includes(`ai-gateway-key`)?`ai-gateway-key`:`ai-gateway-project`),v=c.includes(_),y,b={model:{kind:`keep`},reasoning:{kind:`keep`},gatewayServiceTier:{kind:`keep`}},x,S,C=!1,w=!1,T=!1,E=f?.kind===`external`&&!isChatGptModelRouting(f),D=E?{tone:`warning`,text:"`agent.ts` specifies the model provider directly. Model, provider, and service-tier changes stay source-owned; reasoning remains configurable here."}:void 0,O=!v&&f?.kind!==`external`?`provider`:m||h?`model`:`provider`,k=f?.kind!==`external`&&(e.initialStep===`provider`||!v);for(;;){let t;if(k)k=!1,t=`provider`;else try{t=await n.select({message:``,options:modelMenuRows(d,g,isChatGptModelRouting(f)?{kind:`standard`}:p,_,v,e.chatGptAccountLabel,f,m,h),hintLayout:`stacked`,initialValue:O,notices:D===void 0?[]:[D]})}catch(e){if(!(e instanceof WizardCancelledError))throw e;if(hasModelSettingsChanges(b))return{kind:`cancelled`,discardedDraft:!0};break}if(t===`done`){w=!0,T=!0;break}if(t===`model`){let e=a.pickModelSettings;if(e===void 0)throw Error(`runModelFlow requires a pickModelSettings dep to open the model screen.`);let t=await e({model:m?{kind:`pick`,options:modelListRows(u),current:d}:{kind:`fixed`,current:d,reason:`Set via an SDK model call in agent.ts; edit the source to change it`},reasoning:g,serviceTier:isChatGptModelRouting(f)?{kind:`standard`}:p,settingsEditable:h,externalRouting:E,capabilitiesFor:e=>gatewayModelCapabilities(u,e)});if(r?.throwIfAborted(),t===void 0){O=`model`;continue}t.model!==void 0&&(d=t.model,f=routingForModelSelection(t.model),b.model={kind:`set`,value:t.model}),t.reasoning!==void 0&&(g=t.reasoning==="default"?null:t.reasoning,b.reasoning=g===null?{kind:`remove`}:{kind:`set`,value:g}),t.serviceTier!==void 0&&!isChatGptModelRouting(f)&&(p=t.serviceTier===`priority`?{kind:`priority`}:{kind:`standard`},b.gatewayServiceTier=t.serviceTier===`priority`?{kind:`set`,value:`priority`}:{kind:`remove`}),O=`done`;continue}let o=await a.runProviderFlow({appRoot:i,prompter:n,signal:r,availableProviders:c,selectedProvider:_});if(o.kind===`cancelled`){if(r?.aborted)return{kind:`cancelled`};O=`provider`;continue}if(o.kind===`external-provider`){if(r?.aborted)return{kind:`cancelled`};O=`done`;continue}y=o.kind,y===`chatgpt`?(C=!0,isChatGptModelRouting(f)||(b.model={kind:`set`,value:DEFAULT_CHATGPT_MODEL_SELECTION},b.gatewayServiceTier={kind:`remove`})):isChatGptModelRouting(f)&&(b.model={kind:`set`,value:DEFAULT_AGENT_MODEL_ID}),T=!0;break}let A=b.model.kind===`set`&&parseChatGptModelSelection(b.model.value)!==void 0;if(T&&A&&(b.gatewayServiceTier={kind:`remove`},C=!0),T&&C&&await authenticateChatGpt(a,e.withExclusiveTerminal),T&&hasModelSettingsChanges(b)&&(x=await a.applySettings({appRoot:t,patch:b})),T&&y!==void 0&&x?.kind!==`rejected`&&(await a.writeProviderSelection(i,y),S=y),x!==void 0&&S===void 0&&r?.throwIfAborted(),x===void 0&&S===void 0&&!C)return w?{kind:`done`,accessChanged:!1}:{kind:`cancelled`};let j={kind:`done`,accessChanged:x?.kind===`changed`||S!==void 0||C};return x===void 0?C&&(j.modelMessage=`ChatGPT login ready.`):j.modelMessage=formatApplyModelSettingsOutcome(x),S!==void 0&&(j.providerSelection=S),j}function routingForModelSelection(e){return parseChatGptModelSelection(e)===void 0?{kind:`gateway`,target:e.split(`/`)[0]??``}:{kind:`external`,provider:`codex`}}async function authenticateChatGpt(e,t){let authenticate=()=>e.ensureChatGptAuth();await(t===void 0?authenticate():t(authenticate))}function hasModelSettingsChanges(e){return e.model.kind!==`keep`||e.reasoning.kind!==`keep`||e.gatewayServiceTier.kind!==`keep`}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e),n=t?.manifest.config,r=n?.model,i=isChatGptModelRouting(r?.routing);return{id:i&&r!==void 0?`chatgpt/${r.id}`:r?.id??null,routing:r?.routing??null,reasoning:n?.reasoning??null,serviceTier:readGatewayServiceTier(r?.providerOptions),editable:r!==void 0&&(r.source===void 0||i),settingsEditable:n?.source!==void 0}}catch{return{id:null,routing:null,reasoning:null,serviceTier:{kind:`standard`},editable:!1,settingsEditable:!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,modelChangeRefusalForUneditableModel,runModelFlow};
1
+ import{AI_GATEWAY_API_KEY_ENV_VAR}from"../ai-gateway-api-key.js";import{withSpinner}from"../with-spinner.js";import{gatewayModelCapabilities}from"../boxes/model-capabilities.js";import{fetchGatewayCatalog,modelOptionsFromCatalog}from"../boxes/select-model.js";import{ensureChatGptAuth}from"./chatgpt-auth.js";import{WizardCancelledError}from"../step.js";import{changeAgentModelSettings,formatApplyModelSettingsOutcome}from"./model-source-change.js";import{runProviderFlow}from"./provider.js";import pc from"#compiled/picocolors/index.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{inspectApplication}from"#services/inspect-application.js";import{readProviderSelection,resolveAvailableProviders,writeProviderSelection}from"#setup/provider-settings.js";import{formatModelSummary}from"#shared/model-summary.js";import{readGatewayServiceTier}from"#shared/gateway-service-tier.js";import{DEFAULT_CHATGPT_MODEL_SELECTION,isChatGptModelRouting,parseChatGptModelSelection}from"#shared/chatgpt-model.js";const MODEL_MENU_MESSAGE=``;function providerSelectionHint(e,t){return e===`chatgpt`?t===void 0?`ChatGPT subscription`:`ChatGPT subscription (${t})`:e===`ai-gateway-project`?`AI Gateway via Project`:`AI Gateway via ${AI_GATEWAY_API_KEY_ENV_VAR}`}function modelListRows(e){return modelOptionsFromCatalog(e).map(e=>{let t={value:e.value,label:e.value};return e.featured===!0&&(t.featured=!0),t})}function formatModelDraftHint(e,t,n){let r={model:e};return t!==null&&(r.reasoning=t),n.kind===`priority`&&(r.fastGlyph=`↯`),formatModelSummary(r)}function modelMenuRows(e,t,n,r,i,a,o,s,c){let l;s||c?(l={value:`model`,label:`Change model`,description:s?`The model, its reasoning effort, and the Gateway service tier`:`Reasoning and service tier; the model itself is an SDK model call in agent.ts`},e!==null&&(l.hint=formatModelDraftHint(e,t,n))):l={value:`model`,label:`Change model`,disabled:!0,description:`Set via an SDK model call in agent.ts; edit the source to change it`};let u;return u=o?.kind===`external`&&!isChatGptModelRouting(o)?{disabled:!0,value:`provider`,label:`Change provider`,description:`Disabled in external endpoint mode`}:i?{value:`provider`,label:`Change provider`,hint:providerSelectionHint(r,a),description:`How your agent reaches the model provider`}:{value:`provider`,label:pc.bold(`Configure model access`),hint:pc.yellow(`Not configured`),description:`How your agent reaches the model provider`,accent:`warning`},[l,u,{value:`done`,label:`Done`}]}async function runModelFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i=e.environmentRoot??t,a={readCurrentModel:readCurrentAgentModel,applySettings:changeAgentModelSettings,resolveAvailableProviders,readProviderSelection,runProviderFlow,ensureChatGptAuth,writeProviderSelection,...e.deps},o=a.selectModel?.fetchModels??fetchGatewayCatalog,[s,c,l,u]=await withSpinner(n,`Checking the project…`,()=>Promise.all([a.readCurrentModel(t),a.resolveAvailableProviders(i,r===void 0?{env:process.env}:{signal:r,env:process.env}),a.readProviderSelection(i),o(r).catch(()=>void 0)]));r?.throwIfAborted();let{id:d,routing:f,serviceTier:p,editable:m,settingsEditable:h}=s,g=s.reasoning===`provider-default`?null:s.reasoning,_=l??(c.includes(`ai-gateway-key`)?`ai-gateway-key`:`ai-gateway-project`),v=c.includes(_),y,b={model:{kind:`keep`},reasoning:{kind:`keep`},gatewayServiceTier:{kind:`keep`}},x,S,C=!1,w=!1,T=!1,E=f?.kind===`external`&&!isChatGptModelRouting(f),D=E?{tone:`warning`,text:"`agent.ts` specifies the model provider directly. Model, provider, and service-tier changes stay source-owned; reasoning remains configurable here."}:void 0,O=!v&&f?.kind!==`external`?`provider`:m||h?`model`:`provider`,k=f?.kind!==`external`&&(e.initialStep===`provider`||!v);for(;;){let t;if(k)k=!1,t=`provider`;else try{t=await n.select({message:``,options:modelMenuRows(d,g,isChatGptModelRouting(f)?{kind:`standard`}:p,_,v,e.chatGptAccountLabel,f,m,h),hintLayout:`stacked`,initialValue:O,notices:D===void 0?[]:[D]})}catch(e){if(!(e instanceof WizardCancelledError))throw e;if(hasModelSettingsChanges(b))return{kind:`cancelled`,discardedDraft:!0};break}if(t===`done`){w=!0,T=!0;break}if(t===`model`){e.onScreen?.(`model_settings`);let t=a.pickModelSettings;if(t===void 0)throw Error(`runModelFlow requires a pickModelSettings dep to open the model screen.`);let n=await t({model:m?{kind:`pick`,options:modelListRows(u),current:d}:{kind:`fixed`,current:d,reason:`Set via an SDK model call in agent.ts; edit the source to change it`},reasoning:g,serviceTier:isChatGptModelRouting(f)?{kind:`standard`}:p,settingsEditable:h,externalRouting:E,capabilitiesFor:e=>gatewayModelCapabilities(u,e)});if(r?.throwIfAborted(),n===void 0){O=`model`;continue}n.model!==void 0&&(d=n.model,f=routingForModelSelection(n.model),b.model={kind:`set`,value:n.model}),n.reasoning!==void 0&&(g=n.reasoning==="default"?null:n.reasoning,b.reasoning=g===null?{kind:`remove`}:{kind:`set`,value:g}),n.serviceTier!==void 0&&!isChatGptModelRouting(f)&&(p=n.serviceTier===`priority`?{kind:`priority`}:{kind:`standard`},b.gatewayServiceTier=n.serviceTier===`priority`?{kind:`set`,value:`priority`}:{kind:`remove`}),O=`done`;continue}e.onScreen?.(`model_provider`);let o=await a.runProviderFlow({appRoot:i,prompter:n,signal:r,availableProviders:c,selectedProvider:_});if(o.kind===`cancelled`){if(r?.aborted)return{kind:`cancelled`};O=`provider`;continue}if(o.kind===`external-provider`){if(r?.aborted)return{kind:`cancelled`};O=`done`;continue}y=o.kind,y===`chatgpt`?(C=!0,isChatGptModelRouting(f)||(b.model={kind:`set`,value:DEFAULT_CHATGPT_MODEL_SELECTION},b.gatewayServiceTier={kind:`remove`})):isChatGptModelRouting(f)&&(b.model={kind:`set`,value:DEFAULT_AGENT_MODEL_ID}),T=!0;break}let A=b.model.kind===`set`&&parseChatGptModelSelection(b.model.value)!==void 0;if(T&&A&&(b.gatewayServiceTier={kind:`remove`},C=!0),T&&C&&await authenticateChatGpt(a,e.withExclusiveTerminal,r),T&&hasModelSettingsChanges(b)&&(x=await a.applySettings({appRoot:t,patch:b})),T&&y!==void 0&&x?.kind!==`rejected`&&(await a.writeProviderSelection(i,y),S=y),x!==void 0&&S===void 0&&r?.throwIfAborted(),x===void 0&&S===void 0&&!C)return w?{kind:`done`,accessChanged:!1}:{kind:`cancelled`};let j={kind:`done`,accessChanged:x?.kind===`changed`||S!==void 0||C};return x===void 0?C&&(j.modelMessage=`ChatGPT login ready.`):j.modelMessage=formatApplyModelSettingsOutcome(x),S!==void 0&&(j.providerSelection=S),j}function routingForModelSelection(e){return parseChatGptModelSelection(e)===void 0?{kind:`gateway`,target:e.split(`/`)[0]??``}:{kind:`external`,provider:`codex`}}async function authenticateChatGpt(e,t,n){let authenticate=()=>e.ensureChatGptAuth({signal:n});await(t===void 0?authenticate():t(authenticate))}function hasModelSettingsChanges(e){return e.model.kind!==`keep`||e.reasoning.kind!==`keep`||e.gatewayServiceTier.kind!==`keep`}async function readCurrentAgentModel(e){try{let{compiledState:t}=await inspectApplication(e),n=t?.manifest.config,r=n?.model,i=isChatGptModelRouting(r?.routing);return{id:i&&r!==void 0?`chatgpt/${r.id}`:r?.id??null,routing:r?.routing??null,reasoning:n?.reasoning??null,serviceTier:readGatewayServiceTier(r?.providerOptions),editable:r!==void 0&&(r.source===void 0||i),settingsEditable:n?.source!==void 0}}catch{return{id:null,routing:null,reasoning:null,serviceTier:{kind:`standard`},editable:!1,settingsEditable:!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,modelChangeRefusalForUneditableModel,runModelFlow};
@@ -1,4 +1,4 @@
1
1
  import{appendEnv}from"../append-env.js";import{AI_GATEWAY_API_KEY_ENV_FILE,AI_GATEWAY_API_KEY_ENV_VAR,writeAiGatewayApiKey}from"../ai-gateway-api-key.js";import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus,vercelAuthBlockerReason}from"../vercel-project.js";import{WizardCancelledError}from"../step.js";import{runLinkFlow}from"./link.js";import{validateGatewayApiKey}from"../validate-gateway-key.js";import{HumanActionRequiredError}from"#setup/human-action.js";const PROVIDER_QUESTION=`Which model provider do you want to use?`,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE=`Using another model provider`,EXTERNAL_PROVIDER_INSTRUCTIONS=[`Set your provider's API key in ${AI_GATEWAY_API_KEY_ENV_FILE} — 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://eve.dev/docs/agent-config for details.`,"A running `eve dev` reloads env files automatically — no restart needed."];function projectConnectionOption(e,t){let n={value:`ai-gateway-project`,label:`AI Gateway via Project`,hint:`Authenticates with AI Gateway automatically
2
- in a new or existing project. No keys to manage.`};if(e===`unavailable`)return{...n,hint:`Couldn't reach Vercel — select to retry`};if(t&&e===`logged-out`)return{...n,hint:`Log in to Vercel — select to retry`};if(t&&e===`cli-missing`)return{...n,hint:`Install the Vercel CLI — select to retry`};let r=e===void 0?void 0:vercelAuthBlockerReason(e);return r===void 0?n:{...n,disabled:!0,disabledReason:r,disabledReasonTone:`warning`}}function providerOptions(e,t,n,r){let i=projectConnectionOption(e,r);n&&t===`ai-gateway-project`&&e!==`unavailable`&&(!r||e!==`logged-out`&&e!==`cli-missing`)&&(i={...i,checked:!0,hint:`Current`});let a={value:`ai-gateway-key`,label:`AI Gateway via ${AI_GATEWAY_API_KEY_ENV_VAR}`,hint:`⎿ type your key`};return n&&t===`ai-gateway-key`&&(a={...a,checked:!0,hint:`Current`}),[i,a,{value:`chatgpt`,label:`ChatGPT subscription`,hint:n&&t===`chatgpt`?`Current`:`Authenticate through the Codex CLI`,checked:n&&t===`chatgpt`||void 0},{value:`external`,label:`Other providers`,hint:`Connect directly to a model provider
2
+ in a new or existing project. No keys to manage.`};if(e===`unavailable`)return{...n,hint:`Couldn't reach Vercel — select to retry`};if(t&&e===`logged-out`)return{...n,hint:`Log in to Vercel — select to retry`};if(t&&e===`cli-missing`)return{...n,hint:`Install the Vercel CLI — select to retry`};let r=e===void 0?void 0:vercelAuthBlockerReason(e);return r===void 0?n:{...n,disabled:!0,disabledReason:r,disabledReasonTone:`warning`}}function providerOptions(e,t,n,r){let i=projectConnectionOption(e,r);n&&t===`ai-gateway-project`&&e!==`unavailable`&&(!r||e!==`logged-out`&&e!==`cli-missing`)&&(i={...i,checked:!0,hint:`Current`});let a={value:`ai-gateway-key`,label:`AI Gateway via ${AI_GATEWAY_API_KEY_ENV_VAR}`,hint:`⎿ type your key`};return n&&t===`ai-gateway-key`&&(a={...a,checked:!0,hint:`Current`}),[i,a,{value:`chatgpt`,label:`ChatGPT subscription`,hint:n&&t===`chatgpt`?`Current`:`Sign in with your ChatGPT account`,checked:n&&t===`chatgpt`||void 0},{value:`external`,label:`Other providers`,hint:`Connect directly to a model provider
3
3
  via OPENAI_API_KEY or ANTHROPIC_API_KEY.`}]}async function selectProvider(e){let t={message:PROVIDER_QUESTION,options:e.options,initialValue:e.initialValue,validateInlineKey:e.validateInlineKey};if(e.picker===void 0)throw Error(`The provider flow requires the Dev TUI provider picker.`);let n=await e.picker(t);if(n===void 0)throw new WizardCancelledError;return n}async function runProviderFlow(e){let{appRoot:t,prompter:n,signal:r}=e,i={getVercelAuthStatus,runLinkFlow,appendEnv,validateGatewayApiKey,...e.deps},a,{availableProviders:o,selectedProvider:s}=e,c=s,l;try{for(;;){let u=await selectProvider({picker:e.picker,options:providerOptions(a,s,e.selectionExplicit!==!1,e.recoverHumanAction!==void 0),initialValue:c,validateInlineKey:(e,t)=>i.validateGatewayApiKey(e,r===void 0?t:AbortSignal.any([r,t]))});if(u.kind===`external`)return n.acknowledge?await n.acknowledge({message:EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,lines:EXTERNAL_PROVIDER_INSTRUCTIONS}):n.note(EXTERNAL_PROVIDER_INSTRUCTIONS.join(`
4
4
  `),EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE),{kind:`external-provider`};if(u.kind===`chatgpt`)return u;if(u.kind===`ai-gateway-key`){l=u;break}if(s!==`ai-gateway-project`&&o.includes(`ai-gateway-project`))return u;for(;;){let o=await withSpinner(n,`Checking your Vercel login…`,()=>i.getVercelAuthStatus(t,{signal:r}));if(r?.throwIfAborted(),a=o,o===`authenticated`)break;let s=o===`cli-missing`?`vercel-cli-missing`:o===`logged-out`?`vercel-login`:void 0;if(s===void 0||e.recoverHumanAction===void 0){c=o===`unavailable`?`ai-gateway-project`:`ai-gateway-key`;break}if(await e.recoverHumanAction(new HumanActionRequiredError({kind:s,command:o===`cli-missing`?`npm i -g vercel@latest`:`vercel login`,reason:o===`cli-missing`?`AI Gateway via Project requires the Vercel CLI.`:`AI Gateway via Project requires a Vercel login.`}))===`cancel`){c=`ai-gateway-project`;break}}if(a===`authenticated`)for(;;)try{let e=await i.runLinkFlow({appRoot:t,prompter:n,signal:r,projectSelection:`create-or-link`});return e.kind===`cancelled`?e:{kind:`ai-gateway-project`}}catch(t){if(!(t instanceof HumanActionRequiredError)||e.recoverHumanAction===void 0)throw t;if(await e.recoverHumanAction(t)===`cancel`){c=`ai-gateway-key`;break}}}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}let u=l.key.trim(),d=l.validation;r?.throwIfAborted(),d.kind===`inconclusive`&&n.log.warning(`Couldn't reach the gateway to validate (${d.message}). Saving the key anyway.`);let f=await writeAiGatewayApiKey({projectRoot:t,apiKey:u,appendEnv:i.appendEnv});return n.log.success(`${f.envKey} set.`),{kind:`ai-gateway-key`}}export{EXTERNAL_PROVIDER_INSTRUCTIONS,EXTERNAL_PROVIDER_INSTRUCTIONS_TITLE,PROVIDER_QUESTION,runProviderFlow};
@@ -35,6 +35,10 @@ export declare function runRegistryFlow(input: {
35
35
  /** Registry item supplied by `/add <item>`, confirmed and installed directly. */
36
36
  initialAddress?: string;
37
37
  plannerContext?: RegistryPlannerContext;
38
+ onScreen?: (input: {
39
+ screen: "registry_channels" | "registry_integrations" | "registry_review" | "registry_install";
40
+ registrySelectedCount?: number;
41
+ }) => void;
38
42
  onItemStart?: (item: Item, index: number, total: number) => void;
39
43
  /** Gives each installation its own cancellation boundary without ending the batch. */
40
44
  runItem?<T>(task: (signal?: AbortSignal) => Promise<T>): Promise<T>;
@@ -1,2 +1,2 @@
1
- import{createRegistrySession}from"./registry-session.js";import{PlannerNavigationError}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";const PLANNER_STEPS=[`Channels`,`Integrations`,`Review`];var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};const SECTIONS={channels:{title:`Where should people reach your agent?`,description:`You can add more later with /add.`,featured:[`channel/web`,`channel/slack`,`channel/github`,`channel/linear-agent`,`channel/photon-imessage`],includes:e=>e.name.startsWith(`channel/`)},integrations:{title:`What should your agent be able to work with?`,featured:[`extension/github-tools`,`connection/linear`,`connection/notion`,`connection/vercel`,`extension/agent-browser`,`experimental/self-modification`],includes:e=>!e.name.startsWith(`channel/`)}};function label(e){return e.title??e.name.split(`/`).at(-1)??e.name}function isPlannerItem(e,t){return t.name.includes(`/`)&&SECTIONS[e].includes(t)}function orderedSectionItems(e,t){let n=t.filter(t=>isPlannerItem(e,t)),r=SECTIONS[e].featured.map(e=>n.find(t=>t.name===e)).filter(e=>e!==void 0),i=new Set(r.map(e=>e.address));return[...r,...n.filter(e=>!i.has(e.address))]}function plannerLabel(e){return e.name===`connection/linear`?`Linear MCP`:label(e)}function sectionRows(e,t){return orderedSectionItems(e,t).map(e=>({value:e.address,label:plannerLabel(e),hint:e.description}))}function selectedInSection(e,t,n){return t.filter(t=>isPlannerItem(e,t)&&n.has(t.address)).map(e=>e.address)}function plannerNavigation(e,t){let n=(t.plannerContext?.prefixSteps??[]).map(e=>({label:e.label,complete:e.complete}));return{kind:`planner`,activeStep:n.length+e,firstNavigableStep:n.length,steps:[...n,...PLANNER_STEPS.map((e,n)=>{if(n===2)return{label:e};let r=selectedInSection(n===0?`channels`:`integrations`,t.catalog,t.selected).length;return r===0?{label:e}:{label:e,count:r}})]}}function replaceSectionSelection(e){for(let t of e.catalog)isPlannerItem(e.section,t)&&e.selected.delete(t.address);for(let t of e.addresses)e.selected.add(t)}async function editSection(e){let{section:t,catalog:n,prompter:r,selected:i}=e,a={message:SECTIONS[t].title,multiple:!0,search:!0,placeholder:t===`channels`?`Search channels`:`Search integrations`,navigation:plannerNavigation(t===`channels`?0:1,e),initialValues:selectedInSection(t,n,i),options:sectionRows(t,n)};t===`channels`&&(a.description=SECTIONS.channels.description),e.notices!==void 0&&(a.notices=e.notices);try{return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:await r.select(a)}),`forward`}catch(e){if(!(e instanceof PlannerNavigationError))throw e;return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:e.values.map(e=>{if(typeof e!=`string`)throw Error(`Registry planner returned a non-string item.`);return e})}),e.direction}}async function editPlan(e){let t=`channels`,n=e.notices;for(;;){if(t!==`review`){try{let r=await editSection({...e,section:t,notices:n});n=void 0,r===`back`?t===`integrations`&&(t=`channels`):t=t===`channels`?`integrations`:`review`}catch(e){if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}continue}try{let t=e.selected.size>0,r=[...e.selected].map(t=>{let n=e.itemsByAddress.get(t);if(n===void 0)throw Error(`Registry item "${t}" is no longer available.`);return n}),i=r.filter(e=>e.name.startsWith(`channel/`)),a=r.filter(e=>!e.name.startsWith(`channel/`)),o=[...i.length===0?[]:[{label:`Channels`,value:i.map(label).join(`, `)}],...a.length===0?[]:[{label:`Integrations`,value:a.map(label).join(`, `)}]],s={message:e.plannerContext?.reviewMessage??`Review additions`,metadata:[...e.plannerContext?.reviewMetadata??[],...o],navigation:plannerNavigation(2,e),options:[{value:`install`,label:t?e.plannerContext?.primaryActionLabel??`Install and set up`:e.plannerContext?.emptyActionLabel??`Finish without adding`},{value:`back`,label:`Back`}]};t||(s.description=`No channels or integrations selected.`),n!==void 0&&(s.notices=n);let c=await e.prompter.select(s);if(n=void 0,c===`install`)return`install`}catch(e){if(e instanceof PlannerNavigationError&&e.direction===`back`){t=`integrations`;continue}if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}t=`integrations`}}function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``){if(await e.prompter.select({message:`Add ${n}?`,options:[{value:`install`,label:`Install and set up`},{value:`cancel`,label:`Cancel`}]})===`cancel`)return{kind:`cancelled`};r=[{address:n,name:n,source:`Registry`}]}else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=new Set,o=n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`})),s=new Map(i.map(e=>[e.address,e]));if(await editPlan({prompter:e.prompter,catalog:i,itemsByAddress:s,selected:a,notices:o,plannerContext:e.plannerContext})!==`install`)return{kind:`cancelled`};r=[...a].map(e=>{let t=s.get(e);if(t===void 0)throw Error(`Registry item "${e}" is no longer available.`);return t})}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,o=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:a,runDeployFlow:o});let s=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(e.appRoot,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());s.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){s.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
1
+ import{createRegistrySession}from"./registry-session.js";import{PlannerNavigationError}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";const PLANNER_STEPS=[`Channels`,`Integrations`,`Review`];var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};const SECTIONS={channels:{title:`Where should people reach your agent?`,description:`You can add more later with /add.`,featured:[`channel/web`,`channel/slack`,`channel/github`,`channel/linear-agent`,`channel/photon-imessage`],includes:e=>e.name.startsWith(`channel/`)},integrations:{title:`What should your agent be able to work with?`,featured:[`extension/github-tools`,`connection/linear`,`connection/notion`,`connection/vercel`,`extension/agent-browser`,`experimental/self-modification`],includes:e=>!e.name.startsWith(`channel/`)}};function label(e){return e.title??e.name.split(`/`).at(-1)??e.name}function isPlannerItem(e,t){return t.name.includes(`/`)&&SECTIONS[e].includes(t)}function orderedSectionItems(e,t){let n=t.filter(t=>isPlannerItem(e,t)),r=SECTIONS[e].featured.map(e=>n.find(t=>t.name===e)).filter(e=>e!==void 0),i=new Set(r.map(e=>e.address));return[...r,...n.filter(e=>!i.has(e.address))]}function plannerLabel(e){return e.name===`connection/linear`?`Linear MCP`:label(e)}function sectionRows(e,t){return orderedSectionItems(e,t).map(e=>({value:e.address,label:plannerLabel(e),hint:e.description}))}function selectedInSection(e,t,n){return t.filter(t=>isPlannerItem(e,t)&&n.has(t.address)).map(e=>e.address)}function plannerNavigation(e,t){let n=(t.plannerContext?.prefixSteps??[]).map(e=>({label:e.label,complete:e.complete}));return{kind:`planner`,activeStep:n.length+e,firstNavigableStep:n.length,steps:[...n,...PLANNER_STEPS.map((e,n)=>{if(n===2)return{label:e};let r=selectedInSection(n===0?`channels`:`integrations`,t.catalog,t.selected).length;return r===0?{label:e}:{label:e,count:r}})]}}function replaceSectionSelection(e){for(let t of e.catalog)isPlannerItem(e.section,t)&&e.selected.delete(t.address);for(let t of e.addresses)e.selected.add(t)}async function editSection(e){let{section:t,catalog:n,prompter:r,selected:i}=e,a={message:SECTIONS[t].title,multiple:!0,search:!0,placeholder:t===`channels`?`Search channels`:`Search integrations`,navigation:plannerNavigation(t===`channels`?0:1,e),initialValues:selectedInSection(t,n,i),options:sectionRows(t,n)};t===`channels`&&(a.description=SECTIONS.channels.description),e.notices!==void 0&&(a.notices=e.notices);try{return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:await r.select(a)}),`forward`}catch(e){if(!(e instanceof PlannerNavigationError))throw e;return replaceSectionSelection({section:t,catalog:n,selected:i,addresses:e.values.map(e=>{if(typeof e!=`string`)throw Error(`Registry planner returned a non-string item.`);return e})}),e.direction}}async function editPlan(e){let t=`channels`,n=e.notices;for(;;){if(t!==`review`){e.onScreen?.({screen:t===`channels`?`registry_channels`:`registry_integrations`});try{let r=await editSection({...e,section:t,notices:n});n=void 0,r===`back`?t===`integrations`&&(t=`channels`):t=t===`channels`?`integrations`:`review`}catch(e){if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}continue}try{e.onScreen?.({screen:`registry_review`,registrySelectedCount:e.selected.size});let t=e.selected.size>0,r=[...e.selected].map(t=>{let n=e.itemsByAddress.get(t);if(n===void 0)throw Error(`Registry item "${t}" is no longer available.`);return n}),i=r.filter(e=>e.name.startsWith(`channel/`)),a=r.filter(e=>!e.name.startsWith(`channel/`)),o=[...i.length===0?[]:[{label:`Channels`,value:i.map(label).join(`, `)}],...a.length===0?[]:[{label:`Integrations`,value:a.map(label).join(`, `)}]],s={message:e.plannerContext?.reviewMessage??`Review additions`,metadata:[...e.plannerContext?.reviewMetadata??[],...o],navigation:plannerNavigation(2,e),options:[{value:`install`,label:t?e.plannerContext?.primaryActionLabel??`Install and set up`:e.plannerContext?.emptyActionLabel??`Finish without adding`},{value:`back`,label:`Back`}]};t||(s.description=`No channels or integrations selected.`),n!==void 0&&(s.notices=n);let c=await e.prompter.select(s);if(n=void 0,c===`install`)return`install`}catch(e){if(e instanceof PlannerNavigationError&&e.direction===`back`){t=`integrations`;continue}if(!(e instanceof WizardCancelledError))throw e;return`cancelled`}t=`integrations`}}function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``){if(await e.prompter.select({message:`Add ${n}?`,options:[{value:`install`,label:`Install and set up`},{value:`cancel`,label:`Cancel`}]})===`cancel`)return{kind:`cancelled`};r=[{address:n,name:n,source:`Registry`}]}else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=new Set,o=n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`})),s=new Map(i.map(e=>[e.address,e]));if(await editPlan({prompter:e.prompter,catalog:i,itemsByAddress:s,selected:a,notices:o,plannerContext:e.plannerContext,onScreen:e.onScreen})!==`install`)return{kind:`cancelled`};r=[...a].map(e=>{let t=s.get(e);if(t===void 0)throw Error(`Registry item "${e}" is no longer available.`);return t})}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,o=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:a,runDeployFlow:o}),e.onScreen?.({screen:`registry_install`});let s=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(e.appRoot,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());s.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){s.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
2
2
  `).find(e=>e.trim()!==``);s.addFailure(label(n),r);let a={message:`Couldn't add ${label(n)}`,options:[{value:`skip`,label:`Skip ${label(n)}`},{value:`cancel`,label:`Cancel setup`}]};if(i!==void 0&&(a.description=i),await e.prompter.select(a)===`cancel`)return{kind:`done`,result:{...s.result(),cancelled:!0}}}}return{kind:`done`,result:await s.continueAfterInstall({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal})}}catch(e){if(e instanceof WizardCancelledError){let e=t?.result();return hasSettledOutcomes(e)?{kind:`done`,result:{...e,cancelled:!0}}:{kind:`cancelled`}}let n=t?.result();throw hasSettledOutcomes(n)?new RegistryFlowFailedError(e,n):e}}export{RegistryFlowFailedError,runRegistryFlow};
@@ -1 +1 @@
1
- import{DISCORD_SETUP}from"./discord/setup.js";import{FILE_MEMORY_SETUP}from"./file-memory/setup.js";import{GITHUB_SETUP}from"./github/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{LINQ_SETUP}from"./linq/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SHOPIFY_SETUP}from"./shopify/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createSetupContexts,createSetupPresenter}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,FILE_MEMORY_SETUP,SLACK_SETUP,DISCORD_SETUP,GITHUB_SETUP,LINEAR_SETUP,LINQ_SETUP,PHOTON_SETUP,SHOPIFY_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createSetupContexts,createSetupPresenter,setupIntegration};
1
+ import{DISCORD_SETUP}from"./discord/setup.js";import{FILE_MEMORY_SETUP}from"./file-memory/setup.js";import{GITHUB_SETUP}from"./github/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{LINQ_SETUP}from"./linq/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SELF_MODIFICATION_PRODUCTION_SETUP,SELF_MODIFICATION_SETUP}from"./self-modification/setup.js";import{SHOPIFY_SETUP}from"./shopify/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createSetupContexts,createSetupPresenter}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,FILE_MEMORY_SETUP,SLACK_SETUP,DISCORD_SETUP,GITHUB_SETUP,LINEAR_SETUP,LINQ_SETUP,PHOTON_SETUP,SHOPIFY_SETUP,SELF_MODIFICATION_SETUP,SELF_MODIFICATION_PRODUCTION_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createSetupContexts,createSetupPresenter,setupIntegration};
@@ -1 +1 @@
1
- import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{interactiveAsker}from"#setup/ask.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e);t.prompter.intro(`Set up ${r.label}`,r.hint),t.prompter.log.message(`Checking Vercel setup...`);let[i,a]=await Promise.all([n.detectDeployment(t.appRoot,{signal:t.signal}),n.getVercelAuthStatus(t.appRoot,{signal:t.signal})]),o=projectResolutionFromDeployment(i),s=integrationSetupEnvironment(a,o);return t.prompter.log.info(describeIntegrationSetupEnvironment(s)),r.run(createSetupContexts({appRoot:t.appRoot,asker:t.asker??interactiveAsker(t.prompter),environment:s,prompter:t.prompter,resolveVercelProject:t.resolveVercelProject??(e=>resolveIntegrationVercelProject({appRoot:t.appRoot,integration:e,signal:t.signal})),signal:t.signal,force:t.force,beginExternalAction:t.beginExternalAction}))}export{runIntegrationSetup};
1
+ import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{interactiveAsker}from"#setup/ask.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e);t.prompter.intro(`Set up ${r.label}`,r.hint),t.prompter.log.message(`Checking Vercel setup...`);let[i,a]=await Promise.all([n.detectDeployment(t.appRoot,{signal:t.signal}),n.getVercelAuthStatus(t.appRoot,{signal:t.signal})]),o=projectResolutionFromDeployment(i),s=integrationSetupEnvironment(a,o);return t.prompter.log.info(r.describeEnvironment?.(s)??describeIntegrationSetupEnvironment(s)),r.run(createSetupContexts({appRoot:t.appRoot,asker:t.asker??interactiveAsker(t.prompter),environment:s,prompter:t.prompter,resolveVercelProject:t.resolveVercelProject??(e=>resolveIntegrationVercelProject({appRoot:t.appRoot,integration:e,signal:t.signal})),signal:t.signal,force:t.force,beginExternalAction:t.beginExternalAction}))}export{runIntegrationSetup};
@@ -0,0 +1,29 @@
1
+ import { type SelfModificationSetupOperations, type SelfModificationSetupValues } from "#self-modification/setup.js";
2
+ import { type SetupApplyContext, type SetupPrepareContext } from "../types.js";
3
+ type SelfModificationSetupPlan = {
4
+ readonly kind: "authored";
5
+ } | {
6
+ readonly kind: "local";
7
+ } | {
8
+ readonly kind: "deployed";
9
+ readonly connectorName: string;
10
+ readonly values: SelfModificationSetupValues;
11
+ };
12
+ export declare function prepareSelfModificationSetup(context: SetupPrepareContext, operations?: SelfModificationSetupOperations): Promise<SelfModificationSetupPlan>;
13
+ export declare function applySelfModificationSetup(plan: SelfModificationSetupPlan, context: SetupApplyContext, operations?: SelfModificationSetupOperations): Promise<{
14
+ facts: {
15
+ label: string;
16
+ value: string;
17
+ }[];
18
+ deploymentRequired?: undefined;
19
+ } | {
20
+ deploymentRequired: true;
21
+ facts: {
22
+ label: string;
23
+ value: string;
24
+ }[];
25
+ }>;
26
+ export declare function prepareLocalSelfModificationSetup(context: SetupPrepareContext, operations?: SelfModificationSetupOperations): Promise<SelfModificationSetupPlan>;
27
+ export declare const SELF_MODIFICATION_SETUP: import("../types.js").SetupIntegration;
28
+ export declare const SELF_MODIFICATION_PRODUCTION_SETUP: import("../types.js").SetupIntegration;
29
+ export {};
@@ -0,0 +1 @@
1
+ import{defineSetupIntegration}from"../types.js";import{describeIntegrationSetupEnvironment}from"../shared/environment.js";import{confirm,text}from"#setup/ask.js";import{classifySelfModificationConfig,connectorName,defaultSelfModificationSetupOperations,directoryError,gitRefError,renderSelfModificationConfig,repositoryPartError}from"#self-modification/setup.js";import{SELF_MODIFICATION_CONFIG_PATH}from"#self-modification/git-workspace.js";function validationResult(e){return e??null}async function prepareSelfModificationSetup(e,t=defaultSelfModificationSetupOperations(e.appRoot)){let n=await t.readConfig();if(classifySelfModificationConfig(n)===`authored`)return e.presenter.note(`The existing ${SELF_MODIFICATION_CONFIG_PATH} contains authored configuration and was not overwritten.`,`Manual update required`,{tone:`warning`}),{kind:`authored`};let r=await t.detectGitRepository(),i=await e.asker.ask(text({key:`self-modification-repository-owner`,message:`GitHub repository owner`,detected:r.owner,required:!0,validate:e=>validationResult(repositoryPartError(e))})),a=await e.asker.ask(text({key:`self-modification-repository-name`,message:`GitHub repository name`,detected:r.repo,required:!0,validate:e=>validationResult(repositoryPartError(e))})),o=await e.asker.ask(text({key:`self-modification-repository-directory`,message:`Application directory relative to the repository root`,detected:r.directory??`.`,required:!0,validate:e=>validationResult(directoryError(e))})),s=await e.asker.ask(text({key:`self-modification-target-branch`,message:`Target branch`,detected:r.branch??`main`,required:!0,validate:e=>validationResult(gitRefError(e))})),c=connectorName(i,a),l={branch:s,connector:`github/${c}`,directory:o,repository:`github.com/${i}/${a}`};return e.presenter.note(renderSelfModificationConfig(l),`Generated ${SELF_MODIFICATION_CONFIG_PATH}`),e.presenter.note(`Vercel Connect will issue short-lived GitHub App credentials restricted to this repository. Install the managed GitHub App and select only this repository. Review, merge, and deployment remain separate operator boundaries.`,`Security summary`),await e.asker.ask(confirm({key:`self-modification-confirm`,message:`Create or attach this GitHub connector and write this configuration?`,recommended:!1,required:!0}))?{kind:`deployed`,connectorName:c,values:l}:{kind:`local`}}async function applySelfModificationSetup(e,t,n=defaultSelfModificationSetupOperations(t.appRoot)){if(e.kind===`authored`)return{facts:[{label:`Self-modification`,value:`manual configuration update required`}]};if(e.kind===`local`)return{facts:[{label:`Self-modification`,value:`local editing`}]};let r=await n.findOrCreateConnector(e.connectorName);return await n.attachConnector(r),await n.writeConfig(renderSelfModificationConfig({...e.values,connector:r})),t.presenter.log.success(`Updated ${SELF_MODIFICATION_CONFIG_PATH}.`),t.presenter.nextSteps([`Install the managed GitHub App for the configured repository, then redeploy.`]),{deploymentRequired:!0,facts:[{label:`Repository`,value:e.values.repository},{label:`Application directory`,value:e.values.directory},{label:`Target branch`,value:e.values.branch},{label:`Credential`,value:r}]}}async function prepareLocalSelfModificationSetup(e,t=defaultSelfModificationSetupOperations(e.appRoot)){let n=await t.readConfig();return classifySelfModificationConfig(n)===`authored`?(e.presenter.note(`The existing ${SELF_MODIFICATION_CONFIG_PATH} contains authored configuration and was not overwritten.`,`Manual update required`,{tone:`warning`}),{kind:`authored`}):{kind:`local`}}function describeEnvironment(e){if(e.vercel.kind===`available`)return describeIntegrationSetupEnvironment(e);switch(e.vercel.reason){case`logged-out`:return`No authenticated Vercel account found. Local editing remains available; deployed proposals require Vercel Connect.`;case`cli-missing`:return`Vercel CLI not found. Local editing remains available; deployed proposals require Vercel Connect.`;case`unavailable`:return`Could not verify the Vercel account. Local editing remains available; deployed proposals require Vercel Connect.`}}const SELF_MODIFICATION_SETUP=defineSetupIntegration({kind:`self-modification`,label:`Self-modification`,hint:`Local source editing is enabled`,describeEnvironment,prepare:prepareLocalSelfModificationSetup,apply:applySelfModificationSetup}),SELF_MODIFICATION_PRODUCTION_SETUP=defineSetupIntegration({kind:`self-modification-production`,label:`Self-modification production`,hint:`Configure deployed draft pull requests`,describeEnvironment,prepare:prepareSelfModificationSetup,apply:applySelfModificationSetup});export{SELF_MODIFICATION_PRODUCTION_SETUP,SELF_MODIFICATION_SETUP,applySelfModificationSetup,prepareLocalSelfModificationSetup,prepareSelfModificationSetup};
@@ -39,6 +39,7 @@ interface SetupIntegrationDefinition<Plan> {
39
39
  readonly kind: string;
40
40
  readonly label: string;
41
41
  readonly hint?: string;
42
+ describeEnvironment?(environment: IntegrationSetupEnvironment): string;
42
43
  prepare(context: SetupPrepareContext): Promise<Plan>;
43
44
  apply(plan: Plan, context: SetupApplyContext): Promise<RegistrySetupCompletion>;
44
45
  }
@@ -46,6 +47,7 @@ export interface SetupIntegration {
46
47
  readonly kind: string;
47
48
  readonly label: string;
48
49
  hint?: string;
50
+ describeEnvironment?(environment: IntegrationSetupEnvironment): string;
49
51
  run(input: {
50
52
  prepare: SetupPrepareContext;
51
53
  apply: SetupApplyContext;
@@ -1 +1 @@
1
- import{WizardCancelledError}from"#setup/step.js";function defineSetupIntegration(e){let t={kind:e.kind,label:e.label,async run(t){try{let n=await e.prepare(t.prepare);return{kind:`done`,completion:await e.apply(n,t.apply)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}};return e.hint!==void 0&&(t.hint=e.hint),t}export{defineSetupIntegration};
1
+ import{WizardCancelledError}from"#setup/step.js";function defineSetupIntegration(e){let t={kind:e.kind,label:e.label,async run(t){try{let n=await e.prepare(t.prepare);return{kind:`done`,completion:await e.apply(n,t.apply)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}};return e.hint!==void 0&&(t.hint=e.hint),e.describeEnvironment!==void 0&&(t.describeEnvironment=e.describeEnvironment),t}export{defineSetupIntegration};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.52.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{parseChatGptModelSelection}from"../../../shared/chatgpt-model.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{blockingCreateInPlaceEntries}from"../create-in-place.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{mkdir,readdir,stat}from"node:fs/promises";import{basename,join,resolve}from"node:path";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,DEFAULT_AI_PACKAGE_VERSION=`^7.0.82`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.52.4`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e,t){return{"agent/agent.ts":renderAgentTemplate(e,t),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderAgentTemplate(e,t){let n=parseChatGptModelSelection(e);return n===void 0?BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t)):`import { defineAgent } from "eve";\nimport { chatgpt } from "eve/models/openai";\n\nexport default defineAgent({\n model: chatgpt(${JSON.stringify(n)}),\n${reasoningTemplateLine(t)}});\n`}function reasoningTemplateLine(e){return e===void 0||e===`provider-default`?``:` reasoning: "${e}",\n`}function renderTemplate(e,t){return e===BASE_AGENT_TEMPLATE&&parseChatGptModelSelection(t.model)!==void 0?renderAgentTemplate(t.model,t.reasoning):e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_REASONING__`,reasoningTemplateLine(t.reasoning)).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -0,0 +1,4 @@
1
+ /** Distinguishes authored admission failures from failed runtime lifecycle work. */
2
+ export declare class BoundaryHookError extends Error {
3
+ constructor(cause: unknown);
4
+ }
@@ -0,0 +1 @@
1
+ import{toErrorMessage}from"#shared/errors.js";var BoundaryHookError=class extends Error{constructor(e){super(toErrorMessage(e),{cause:e}),this.name=`BoundaryHookError`}};export{BoundaryHookError};
@@ -1 +1 @@
1
- const EMPTY_DELIVERY_SENTINEL=`<eve-empty-delivery/>`,CONDITIONAL_DELIVERY_INSTRUCTION=`Conditional delivery\nOnly when the current task explicitly makes delivery conditional and there is nothing new to report, reply with exactly ${EMPTY_DELIVERY_SENTINEL} and no other text. This includes results already delivered or incorporated into an earlier response; do not send an acknowledgement of that redundancy. Do not use this marker for ordinary conversations, after input or approval responses, or to omit commentary from a response that still needs delivery. Never return an empty response; use the marker to intentionally deliver nothing.`;function hasEmptyDeliverySentinel(e){return e?.includes(`<eve-empty-delivery/>`)===!0||e?.includes(`&lt;eve-empty-delivery/&gt;`)===!0}export{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel};
1
+ const EMPTY_DELIVERY_SENTINEL=`<eve-empty-delivery/>`,CONDITIONAL_DELIVERY_INSTRUCTION=`Conditional delivery\nOnly when the current task explicitly makes delivery conditional and there is nothing new to report, reply with exactly ${EMPTY_DELIVERY_SENTINEL} and no other text. This includes results already delivered or incorporated into an earlier response; do not send an acknowledgement of that redundancy. Do not use this marker for ordinary conversations, after input or approval responses, or to omit commentary from a response that still needs delivery. Never return an empty response; use the marker to intentionally deliver nothing.`;function hasEmptyDeliverySentinel(e){let t=e?.trim();return t===`<eve-empty-delivery/>`||t===`&lt;eve-empty-delivery/&gt;`}export{CONDITIONAL_DELIVERY_INSTRUCTION,EMPTY_DELIVERY_SENTINEL,hasEmptyDeliverySentinel};
@@ -0,0 +1,16 @@
1
+ import type { SandboxNetworkPolicy } from "./sandbox-network-policy.js";
2
+ /** Returns whether a value is a complete Git object SHA. */
3
+ export declare function isFullGitSha(value: string): boolean;
4
+ /** Returns whether a value can safely be used as a Git ref. */
5
+ export declare function isValidGitRef(value: string): boolean;
6
+ /** Builds the token-free HTTPS remote used by GitHub fetches. */
7
+ export declare function gitHubRemoteUrl(input: {
8
+ readonly owner: string;
9
+ readonly repo: string;
10
+ }): string;
11
+ /**
12
+ * Brokers a GitHub installation token at the sandbox firewall without exposing
13
+ * it to the process running git. codeload.github.com is required for redirects
14
+ * from shallow fetches.
15
+ */
16
+ export declare function gitHubGitBrokerNetworkPolicy(token: string): SandboxNetworkPolicy;
@@ -0,0 +1 @@
1
+ import{Buffer}from"node:buffer";function isFullGitSha(e){return/^[a-f0-9]{40}$/iu.test(e)}function isValidGitRef(e){return!(e.length===0||e.startsWith(`-`)||e.endsWith(`.`)||e.endsWith(`/`)||e.includes(`..`)||e.includes(`//`)||e.includes(`@{`)||e.includes(`\\`)||e.split(`/`).some(e=>e.length===0||e.endsWith(`.lock`))||/[\x00-\x20~^:?*[]/u.test(e))}function gitHubRemoteUrl(e){return`https://github.com/${e.owner}/${e.repo}.git`}function gitHubGitBrokerNetworkPolicy(e){let t=[{transform:[{headers:{Authorization:`Basic ${Buffer.from(`x-access-token:${e}`).toString(`base64`)}`}}]}];return{allow:{"*":[],"github.com":t,"codeload.github.com":t}}}export{gitHubGitBrokerNetworkPolicy,gitHubRemoteUrl,isFullGitSha,isValidGitRef};
@@ -1,3 +1,3 @@
1
1
  export declare const MAX_ACTIVITY_TEXT_LENGTH = 500;
2
2
  /** Normalizes bounded untrusted presentation text before it reaches a renderer. */
3
- export declare function normalizeActivityText(text: string): string;
3
+ export declare function normalizePresentationText(text: string): string;
@@ -0,0 +1 @@
1
+ const MAX_ACTIVITY_TEXT_LENGTH=500;function normalizePresentationText(e){return e.replace(/\p{Cc}/gu,` `).replace(/\s+/g,` `).trim().slice(0,500)}export{MAX_ACTIVITY_TEXT_LENGTH,normalizePresentationText};
@@ -0,0 +1,2 @@
1
+ /** Wraps a value in POSIX single quotes, escaping embedded single quotes. */
2
+ export declare function shellQuote(value: string): string;
@@ -0,0 +1 @@
1
+ function shellQuote(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}export{shellQuote};
@@ -1 +1 @@
1
- import{mkdir,readFile}from"node:fs/promises";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{dirname,join,relative}from"node:path";import{EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV,EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}from"#internal/application/paths.js";import{findClosestLinkedVercelDirectory}from"#shared/vercel-output-directory.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";const VERCEL_JSON_FILE_NAME=`vercel.json`,EVE_SERVICE_ROUTE_SRC=`^${EVE_ROUTE_PREFIX}/(.*)$`,EVE_SERVICE_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/$1`;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function toPosixRelative(e,t){let n=relative(e,t);return n.length===0?`.`:n.replaceAll(`\\`,`/`)}function quoteShellArgument(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function isNamedServiceConfigArray(e){return Array.isArray(e)}function createServiceConfigRecord(e){if(e===void 0)return{};if(isNamedServiceConfigArray(e)){let t={};for(let n of e)if(typeof n.name==`string`&&n.name.trim().length>0){let{name:e,...r}=n;t[e]=r}return t}return e}function normalizeVercelJsonConfig(e){if(!isRecord(e))throw Error(`${VERCEL_JSON_FILE_NAME} must contain a JSON object.`);let t=e.services;if(t!==void 0&&!isRecord(t)&&!(Array.isArray(t)&&t.every(e=>isRecord(e)&&typeof e.name==`string`&&e.name.trim().length>0)))throw Error(`${VERCEL_JSON_FILE_NAME} services must be a JSON object or named service array.`);return e}async function readVercelJsonConfig(e){try{return normalizeVercelJsonConfig(JSON.parse(await readFile(e,`utf8`)))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}function findEveService(e){return Object.values(e).find(e=>e.framework===`eve`)}function assertRootServicesIncludeEve(e,t){if(findEveService(e)===void 0)throw Error(`${VERCEL_JSON_FILE_NAME} already defines services, so the eve ${t} integration cannot add a generated eve service. Add an eve service (framework "eve") and a rewrite from ${EVE_ROUTE_PREFIX}/(.*) to it in ${VERCEL_JSON_FILE_NAME}, or remove services from ${VERCEL_JSON_FILE_NAME}.`)}function createEveServiceRoute(e=`eve`){return{destination:{service:e,type:`service`},src:EVE_SERVICE_ROUTE_SRC}}function createEveServiceRequestPathRoute(){return{src:EVE_SERVICE_ROUTE_SRC,transforms:[{args:EVE_SERVICE_ROUTE_PATH,op:`set`,type:`request.path`}]}}function isEveServiceRoute(e,t){let n=e.destination;return e.src===EVE_SERVICE_ROUTE_SRC&&isRecord(n)&&n.type===`service`&&n.service===t}function insertEveServiceRoute(e,t){let n=e.filter(e=>!(isRecord(e)&&isEveServiceRoute(e,t))),r=n.findIndex(e=>isRecord(e)&&e.handle===`filesystem`);return r===-1?[createEveServiceRoute(t),...n]:[...n.slice(0,r),createEveServiceRoute(t),...n.slice(r)]}function insertEveServiceRequestPathRoute(e){let t=(e??[]).filter(e=>e.src!==EVE_SERVICE_ROUTE_SRC);return[createEveServiceRequestPathRoute(),...t]}function createGeneratedServiceBuild(e){let t=join(e.hostRoot,`.eve/vercel-services`,`eve`),n=join(t,`.vercel`,`output`),r=join(e.hostRoot,`.vercel`,`output`),i=toPosixRelative(t,e.appRoot),a=toPosixRelative(e.appRoot,n),o=toPosixRelative(e.appRoot,r),s=e.eveBuildCommand??`node ${quoteShellArgument(toPosixRelative(e.appRoot,resolveEveBinaryPath(e.hostRoot)))} build`;return{buildCommand:`cd ${quoteShellArgument(i)} && export ${EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV}=${quoteShellArgument(a)} && export ${EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}=${quoteShellArgument(o)} && ${s}`,root:toPosixRelative(e.hostRoot,t),rootDirectory:t}}async function ensureEveVercelServicesConfig(e){let t=await findClosestLinkedVercelDirectory(e.hostRoot),n=t===void 0?e.hostRoot:dirname(t),r=await readVercelJsonConfig(join(e.hostRoot,VERCEL_JSON_FILE_NAME)),i=n===e.hostRoot||Object.keys(createServiceConfigRecord(r.services)).length>0?r:await readVercelJsonConfig(join(n,VERCEL_JSON_FILE_NAME)),a=createServiceConfigRecord(i.services);if(Object.keys(a).length>0)return assertRootServicesIncludeEve(a,e.frameworkName),{mode:`root`};i.experimentalServices!==void 0&&console.warn(`[eve] ${VERCEL_JSON_FILE_NAME} defines experimentalServices, which Vercel no longer routes. The eve ${e.frameworkName} integration now generates the stable services config automatically — remove experimentalServices from ${VERCEL_JSON_FILE_NAME}.`);let o=createGeneratedServiceBuild(e);return await mkdir(o.rootDirectory,{recursive:!0}),{mode:`generated`,services:{eve:{buildCommand:o.buildCommand,framework:`eve`,routes:[createEveServiceRequestPathRoute()],root:o.root}}}}function mergeEveVercelConfig(e,t){let n=e?.services??{},r=Object.entries(n).find(([e,t])=>e===`eve`||t.framework===`eve`),i=r?.[0]??`eve`,a=r?{...n,[i]:{...r[1],routes:insertEveServiceRequestPathRoute(r[1].routes)}}:{...n,...t.services};return{version:3,...e,routes:insertEveServiceRoute(e?.routes??[],i),services:a}}export{createEveServiceRequestPathRoute,createEveServiceRoute,ensureEveVercelServicesConfig,mergeEveVercelConfig};
1
+ import{mkdir,readFile}from"node:fs/promises";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{dirname,join,relative}from"node:path";import{EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV,EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}from"#internal/application/paths.js";import{shellQuote}from"#shared/shell-quote.js";import{findClosestLinkedVercelDirectory}from"#shared/vercel-output-directory.js";import{resolveEveBinaryPath}from"#shared/resolve-eve-binary.js";const VERCEL_JSON_FILE_NAME=`vercel.json`,EVE_SERVICE_ROUTE_SRC=`^${EVE_ROUTE_PREFIX}/(.*)$`,EVE_SERVICE_ROUTE_PATH=`${EVE_ROUTE_PREFIX}/$1`;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function toPosixRelative(e,t){let n=relative(e,t);return n.length===0?`.`:n.replaceAll(`\\`,`/`)}function isNamedServiceConfigArray(e){return Array.isArray(e)}function createServiceConfigRecord(e){if(e===void 0)return{};if(isNamedServiceConfigArray(e)){let t={};for(let n of e)if(typeof n.name==`string`&&n.name.trim().length>0){let{name:e,...r}=n;t[e]=r}return t}return e}function normalizeVercelJsonConfig(e){if(!isRecord(e))throw Error(`${VERCEL_JSON_FILE_NAME} must contain a JSON object.`);let t=e.services;if(t!==void 0&&!isRecord(t)&&!(Array.isArray(t)&&t.every(e=>isRecord(e)&&typeof e.name==`string`&&e.name.trim().length>0)))throw Error(`${VERCEL_JSON_FILE_NAME} services must be a JSON object or named service array.`);return e}async function readVercelJsonConfig(e){try{return normalizeVercelJsonConfig(JSON.parse(await readFile(e,`utf8`)))}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}function findEveService(e){return Object.values(e).find(e=>e.framework===`eve`)}function assertRootServicesIncludeEve(e,t){if(findEveService(e)===void 0)throw Error(`${VERCEL_JSON_FILE_NAME} already defines services, so the eve ${t} integration cannot add a generated eve service. Add an eve service (framework "eve") and a rewrite from ${EVE_ROUTE_PREFIX}/(.*) to it in ${VERCEL_JSON_FILE_NAME}, or remove services from ${VERCEL_JSON_FILE_NAME}.`)}function createEveServiceRoute(e=`eve`){return{destination:{service:e,type:`service`},src:EVE_SERVICE_ROUTE_SRC}}function createEveServiceRequestPathRoute(){return{src:EVE_SERVICE_ROUTE_SRC,transforms:[{args:EVE_SERVICE_ROUTE_PATH,op:`set`,type:`request.path`}]}}function isEveServiceRoute(e,t){let n=e.destination;return e.src===EVE_SERVICE_ROUTE_SRC&&isRecord(n)&&n.type===`service`&&n.service===t}function insertEveServiceRoute(e,t){let n=e.filter(e=>!(isRecord(e)&&isEveServiceRoute(e,t))),r=n.findIndex(e=>isRecord(e)&&e.handle===`filesystem`);return r===-1?[createEveServiceRoute(t),...n]:[...n.slice(0,r),createEveServiceRoute(t),...n.slice(r)]}function insertEveServiceRequestPathRoute(e){let t=(e??[]).filter(e=>e.src!==EVE_SERVICE_ROUTE_SRC);return[createEveServiceRequestPathRoute(),...t]}function createGeneratedServiceBuild(e){let t=join(e.hostRoot,`.eve/vercel-services`,`eve`),n=join(t,`.vercel`,`output`),r=join(e.hostRoot,`.vercel`,`output`),i=toPosixRelative(t,e.appRoot),a=toPosixRelative(e.appRoot,n),o=toPosixRelative(e.appRoot,r),s=e.eveBuildCommand??`node ${shellQuote(toPosixRelative(e.appRoot,resolveEveBinaryPath(e.hostRoot)))} build`;return{buildCommand:`cd ${shellQuote(i)} && export ${EVE_INTERNAL_BUILD_OUTPUT_DIRECTORY_ENV}=${shellQuote(a)} && export ${EVE_INTERNAL_HOST_BUILD_OUTPUT_DIRECTORY_ENV}=${shellQuote(o)} && ${s}`,root:toPosixRelative(e.hostRoot,t),rootDirectory:t}}async function ensureEveVercelServicesConfig(e){let t=await findClosestLinkedVercelDirectory(e.hostRoot),n=t===void 0?e.hostRoot:dirname(t),r=await readVercelJsonConfig(join(e.hostRoot,VERCEL_JSON_FILE_NAME)),i=n===e.hostRoot||Object.keys(createServiceConfigRecord(r.services)).length>0?r:await readVercelJsonConfig(join(n,VERCEL_JSON_FILE_NAME)),a=createServiceConfigRecord(i.services);if(Object.keys(a).length>0)return assertRootServicesIncludeEve(a,e.frameworkName),{mode:`root`};i.experimentalServices!==void 0&&console.warn(`[eve] ${VERCEL_JSON_FILE_NAME} defines experimentalServices, which Vercel no longer routes. The eve ${e.frameworkName} integration now generates the stable services config automatically — remove experimentalServices from ${VERCEL_JSON_FILE_NAME}.`);let o=createGeneratedServiceBuild(e);return await mkdir(o.rootDirectory,{recursive:!0}),{mode:`generated`,services:{eve:{buildCommand:o.buildCommand,framework:`eve`,routes:[createEveServiceRequestPathRoute()],root:o.root}}}}function mergeEveVercelConfig(e,t){let n=e?.services??{},r=Object.entries(n).find(([e,t])=>e===`eve`||t.framework===`eve`),i=r?.[0]??`eve`,a=r?{...n,[i]:{...r[1],routes:insertEveServiceRequestPathRoute(r[1].routes)}}:{...n,...t.services};return{version:3,...e,routes:insertEveServiceRoute(e?.routes??[],i),services:a}}export{createEveServiceRequestPathRoute,createEveServiceRoute,ensureEveVercelServicesConfig,mergeEveVercelConfig};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-BEjdhhhK.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-XnfjQt1Z.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-BEjdhhhK.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-XnfjQt1Z.js";
2
2
 
3
3
  export { useEveAgent };