eve 0.57.0 → 0.58.1

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 (148) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -0
  3. package/dist/src/channel/activity-sink.js +1 -1
  4. package/dist/src/channel/session-callback.js +1 -1
  5. package/dist/src/chunks/{use-eve-agent-C2APNCdP.js → use-eve-agent-CxWcZCsU.js} +22 -3
  6. package/dist/src/chunks/{use-eve-agent-D0YnDLi_.js → use-eve-agent-X0asmJg-.js} +22 -3
  7. package/dist/src/cli/commands/integration-setup.js +1 -1
  8. package/dist/src/cli/dev/command.d.ts +30 -0
  9. package/dist/src/cli/dev/command.js +3 -0
  10. package/dist/src/cli/dev/tui/setup-commands.js +1 -1
  11. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  12. package/dist/src/cli/dev/tui/setup-panel.js +2 -1
  13. package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
  14. package/dist/src/cli/dev/tui/tui.js +1 -1
  15. package/dist/src/cli/option-parsers.js +1 -1
  16. package/dist/src/cli/run.js +1 -3
  17. package/dist/src/client/agent-host.js +1 -1
  18. package/dist/src/client/url.js +1 -1
  19. package/dist/src/compiled/.vendor-stamp.json +2 -2
  20. package/dist/src/compiled/@ai-sdk/code-mode/index.d.ts +18 -2
  21. package/dist/src/compiled/@ai-sdk/code-mode/index.js +16 -14
  22. package/dist/src/compiler/extension-compatibility.d.ts +12 -12
  23. package/dist/src/compiler/extension-compatibility.js +1 -1
  24. package/dist/src/context/dynamic-model-lifecycle.d.ts +1 -0
  25. package/dist/src/context/dynamic-model-lifecycle.js +1 -1
  26. package/dist/src/context/keys.d.ts +11 -3
  27. package/dist/src/context/memory-lifecycle.d.ts +2 -5
  28. package/dist/src/context/memory-lifecycle.js +1 -1
  29. package/dist/src/dynamic/definition.d.ts +2 -0
  30. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  31. package/dist/src/execution/node-step.js +1 -1
  32. package/dist/src/execution/session/event-sink.js +1 -1
  33. package/dist/src/execution/session/turn-step.js +1 -1
  34. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  35. package/dist/src/execution/workflow-callback-url.js +1 -1
  36. package/dist/src/experimental/evaluate/auto-model.d.ts +16 -0
  37. package/dist/src/experimental/evaluate/auto-model.js +2 -0
  38. package/dist/src/harness/emission.d.ts +1 -1
  39. package/dist/src/harness/emission.js +1 -1
  40. package/dist/src/harness/messages.d.ts +1 -0
  41. package/dist/src/harness/messages.js +1 -1
  42. package/dist/src/harness/tool-loop.js +2 -2
  43. package/dist/src/internal/application/package.js +1 -1
  44. package/dist/src/internal/authored-definition/core.js +1 -1
  45. package/dist/src/internal/model-auth/transport.d.ts +3 -1
  46. package/dist/src/internal/model-auth/transport.js +1 -1
  47. package/dist/src/internal/nitro/host/normalize-vercel-service-crons.js +1 -1
  48. package/dist/src/internal/nitro/host/start-development-server.js +1 -1
  49. package/dist/src/internal/runtime-model.d.ts +3 -0
  50. package/dist/src/internal/runtime-model.js +1 -1
  51. package/dist/src/internal/vercel/build-agent-workspace.js +1 -1
  52. package/dist/src/internal/vercel/eve-service-contribution.d.ts +1 -0
  53. package/dist/src/internal/vercel/eve-service-contribution.js +1 -1
  54. package/dist/src/internal/vercel/vercel-services-config.d.ts +1 -0
  55. package/dist/src/internal/vercel/vercel-services-config.js +1 -1
  56. package/dist/src/public/definitions/workspace-agent.js +1 -1
  57. package/dist/src/public/experimental/evaluate/index.d.ts +1 -0
  58. package/dist/src/public/experimental/evaluate/index.js +1 -0
  59. package/dist/src/public/models/anthropic/index.js +1 -1
  60. package/dist/src/public/next/index.d.ts +1 -1
  61. package/dist/src/public/next/index.js +1 -1
  62. package/dist/src/public/vercel/index.d.ts +1 -1
  63. package/dist/src/public/vercel/index.js +1 -1
  64. package/dist/src/react/use-eve-agent.d.ts +1 -1
  65. package/dist/src/runtime/agent/bootstrap.d.ts +4 -2
  66. package/dist/src/runtime/agent/resolve-model.d.ts +0 -1
  67. package/dist/src/runtime/agent/resolve-model.js +1 -1
  68. package/dist/src/self-modification/agent.d.ts +6 -18
  69. package/dist/src/self-modification/agent.js +1 -1
  70. package/dist/src/self-modification/config.d.ts +17 -12
  71. package/dist/src/self-modification/config.js +1 -1
  72. package/dist/src/self-modification/credentials.d.ts +1 -10
  73. package/dist/src/self-modification/credentials.js +1 -1
  74. package/dist/src/self-modification/extension/extension.d.ts +7 -13
  75. package/dist/src/self-modification/extension/extension.js +1 -1
  76. package/dist/src/self-modification/github-publisher.d.ts +1 -1
  77. package/dist/src/self-modification/mode.js +1 -1
  78. package/dist/src/self-modification/setup.d.ts +1 -1
  79. package/dist/src/self-modification/setup.js +23 -4
  80. package/dist/src/setup/flows/model-login-connection.js +1 -1
  81. package/dist/src/setup/flows/registry.d.ts +3 -0
  82. package/dist/src/setup/flows/registry.js +2 -2
  83. package/dist/src/setup/integrations/discord/setup.js +1 -1
  84. package/dist/src/setup/integrations/file-memory/setup.js +2 -2
  85. package/dist/src/setup/integrations/github/setup.js +1 -1
  86. package/dist/src/setup/integrations/linear/setup.js +1 -1
  87. package/dist/src/setup/integrations/linq/setup.js +1 -1
  88. package/dist/src/setup/integrations/photon/setup-flow.js +1 -1
  89. package/dist/src/setup/integrations/registry.js +1 -1
  90. package/dist/src/setup/integrations/runner.d.ts +3 -0
  91. package/dist/src/setup/integrations/runner.js +1 -1
  92. package/dist/src/setup/integrations/self-modification/setup.d.ts +7 -1
  93. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  94. package/dist/src/setup/integrations/shared/scaffold.js +1 -1
  95. package/dist/src/setup/integrations/shared/ui.d.ts +1 -0
  96. package/dist/src/setup/integrations/shared/ui.js +1 -1
  97. package/dist/src/setup/integrations/shopify/setup.js +1 -1
  98. package/dist/src/setup/integrations/slack/setup.js +1 -1
  99. package/dist/src/setup/integrations/teams/connect.d.ts +22 -0
  100. package/dist/src/setup/integrations/teams/connect.js +1 -0
  101. package/dist/src/setup/integrations/teams/setup.d.ts +21 -0
  102. package/dist/src/setup/integrations/teams/setup.js +7 -0
  103. package/dist/src/setup/integrations/types.d.ts +6 -0
  104. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  105. package/dist/src/setup/scaffold/create/project.d.ts +1 -1
  106. package/dist/src/setup/scaffold/create/project.js +2 -2
  107. package/dist/src/setup/scaffold/update/channels.d.ts +2 -0
  108. package/dist/src/setup/scaffold/update/channels.js +2 -2
  109. package/dist/src/setup/scaffold/update/connections.js +3 -3
  110. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  111. package/dist/src/setup/scaffold/version-tokens.d.ts +2 -1
  112. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  113. package/dist/src/shared/agent-definition.d.ts +2 -0
  114. package/dist/src/shared/eve-route-path.d.ts +4 -0
  115. package/dist/src/shared/eve-route-path.js +1 -0
  116. package/dist/src/shared/public-route-prefix.d.ts +1 -1
  117. package/dist/src/subagents/remote-route-url.js +1 -1
  118. package/dist/src/svelte/index.js +1 -1
  119. package/dist/src/svelte/use-eve-agent.d.ts +1 -1
  120. package/dist/src/svelte/use-eve-agent.js +1 -1
  121. package/dist/src/vue/index.js +1 -1
  122. package/dist/src/vue/use-eve-agent.d.ts +1 -1
  123. package/dist/src/vue/use-eve-agent.js +1 -1
  124. package/docs/README.md +45 -40
  125. package/docs/agent-config.md +8 -1
  126. package/docs/channels/teams.mdx +29 -0
  127. package/docs/concepts/meta.json +1 -0
  128. package/docs/concepts/project-structure.mdx +111 -0
  129. package/docs/getting-started.mdx +18 -106
  130. package/docs/guides/auth-and-route-protection.md +8 -4
  131. package/docs/guides/deployment/self-hosting.md +40 -0
  132. package/docs/guides/deployment/vercel.mdx +26 -23
  133. package/docs/guides/dynamic-capabilities.md +4 -0
  134. package/docs/guides/evaluate.md +118 -0
  135. package/docs/guides/frontend/nextjs.mdx +61 -20
  136. package/docs/guides/frontend/overview.mdx +3 -3
  137. package/docs/guides/instrumentation/otel.mdx +7 -2
  138. package/docs/guides/instrumentation/providers.mdx +2 -3
  139. package/docs/guides/remote-agents.md +5 -1
  140. package/docs/install-integrations.mdx +1 -1
  141. package/docs/meta.json +1 -0
  142. package/docs/reference/agent-files.md +104 -0
  143. package/docs/reference/cli.md +2 -2
  144. package/docs/reference/meta.json +1 -1
  145. package/docs/reference/typescript-api.md +2 -1
  146. package/docs/schedules.mdx +1 -1
  147. package/docs/subagents/index.mdx +2 -2
  148. package/package.json +9 -4
@@ -1 +1 @@
1
- import{defineSetupIntegration}from"../types.js";import{describeIntegrationSetupEnvironment}from"../shared/environment.js";import{confirm,select,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`};if(await e.asker.ask(select({key:`self-modification-mode`,message:`How should self-modification be enabled?`,options:[{id:`deployed`,value:`deployed`,label:`Enable for deployed`,hint:`Let deployed agents propose source changes through draft pull requests`},{id:`local`,value:`local`,label:`Keep local`,hint:`Only enable source editing during local development`}],recommended:`local`,required:!0}))===`local`)return{kind:`local`};let[r,i,a]=await Promise.all([e.resolveVercelProject(`self-modification`),t.detectGitRepository(),t.detectChannelNames()]),o=await e.asker.ask(text({key:`self-modification-repository-owner`,message:`GitHub repository owner`,detected:i.owner,required:!0,validate:e=>validationResult(repositoryPartError(e))})),s=await e.asker.ask(text({key:`self-modification-repository-name`,message:`GitHub repository name`,detected:i.repo,required:!0,validate:e=>validationResult(repositoryPartError(e))})),c=await e.asker.ask(text({key:`self-modification-repository-directory`,message:`Application directory relative to the repository root`,detected:i.directory??`.`,required:!0,validate:e=>validationResult(directoryError(e))})),l=await e.asker.ask(text({key:`self-modification-target-branch`,message:`Target branch`,detected:i.branch??`main`,required:!0,validate:e=>validationResult(gitRefError(e))})),u=connectorName(o,s),d={branch:l,channelNames:a,connector:`github/${u}`,directory:c,repository:`github.com/${o}/${s}`,vercelBackend:!0};return e.presenter.note(renderSelfModificationConfig(d),`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:u,project:r,values:d}:{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:[]};let r=await n.findOrCreateConnector(e.connectorName,e.project);return await n.attachConnector(r,e.project),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 deploy or redeploy.`,e.values.vercelBackend?"After deployment, try self-modification by running `eve dev <deployment-url>` from this linked project. The generated policy admits its Vercel OIDC identity over HTTP; configured channels remain denied until you update `agent/subagents/self-modification/config.ts`.":"Before deployment, configure `deployed.authorize` in `agent/subagents/self-modification/config.ts` to admit a trusted principal for your deployment's channel. After deployment, use that channel to try self-modification."]),{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};
1
+ import{defineSetupIntegration}from"../types.js";import{describeIntegrationSetupEnvironment}from"../shared/environment.js";import{installScaffoldDependencies}from"../shared/scaffold.js";import{ensureConnectionDependencies}from"#setup/scaffold/index.js";import{confirm,select,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";const defaultApplyDependencies={ensureConnectionDependencies,installScaffoldDependencies};function validationResult(e){return e??null}async function prepareSelfModificationSetup(e,t=defaultSelfModificationSetupOperations(e.appRoot,void 0,e.projectRoot)){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`};if(await e.asker.ask(select({key:`self-modification-mode`,message:`How should self-modification be enabled?`,options:[{id:`deployed`,value:`deployed`,label:`Enable for deployed`,hint:`Let deployed agents propose source changes through draft pull requests`},{id:`local`,value:`local`,label:`Keep local`,hint:`Only enable source editing during local development`}],recommended:`local`,required:!0}))===`local`)return{kind:`local`};let[r,i,a]=await Promise.all([e.resolveVercelProject(`self-modification`),t.detectGitRepository(),t.detectChannelNames()]),o=await e.asker.ask(text({key:`self-modification-repository-owner`,message:`GitHub repository owner`,detected:i.owner,required:!0,validate:e=>validationResult(repositoryPartError(e))})),s=await e.asker.ask(text({key:`self-modification-repository-name`,message:`GitHub repository name`,detected:i.repo,required:!0,validate:e=>validationResult(repositoryPartError(e))})),c=await e.asker.ask(text({key:`self-modification-repository-directory`,message:`Application directory relative to the repository root`,detected:i.directory??`.`,required:!0,validate:e=>validationResult(directoryError(e))})),l=await e.asker.ask(text({key:`self-modification-target-branch`,message:`Target branch`,detected:i.branch??`main`,required:!0,validate:e=>validationResult(gitRefError(e))})),u=connectorName(o,s),d={branch:l,channelNames:a,connector:`github/${u}`,directory:c,repository:`github.com/${o}/${s}`,vercelBackend:!0};return e.presenter.note(renderSelfModificationConfig(d),`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:u,project:r,values:d}:{kind:`local`}}async function applySelfModificationSetup(e,t,n=defaultSelfModificationSetupOperations(t.appRoot,void 0,t.projectRoot),r=defaultApplyDependencies){if(e.kind===`authored`)return{facts:[{label:`Self-modification`,value:`manual configuration update required`}]};if(e.kind===`local`)return{facts:[]};let i=await n.findOrCreateConnector(e.connectorName,e.project);await n.attachConnector(i,e.project);let a=await r.ensureConnectionDependencies({projectRoot:t.appRoot});return await r.installScaffoldDependencies({changed:a.length>0,log:t.presenter.log,projectPath:t.appRoot,signal:t.signal}),await n.writeConfig(renderSelfModificationConfig({...e.values,connector:i})),t.presenter.log.success(`Updated ${SELF_MODIFICATION_CONFIG_PATH}.`),t.presenter.nextSteps([`Install the managed GitHub App for the configured repository, then deploy or redeploy.`,e.values.vercelBackend?"After deployment, try self-modification by running `eve dev <deployment-url>` from this linked project. The generated policy admits its Vercel OIDC identity over HTTP; configured channels remain denied until you update `agent/subagents/self-modification/config.ts`.":"Before deployment, configure `deployed.authorize` in `agent/subagents/self-modification/config.ts` to admit a trusted principal for your deployment's channel. After deployment, use that channel to try self-modification."]),{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:i}]}}async function prepareLocalSelfModificationSetup(e,t=defaultSelfModificationSetupOperations(e.appRoot,void 0,e.projectRoot)){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};
@@ -1 +1 @@
1
- import{detectPackageManager}from"#setup/package-manager.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/pm/run.js";const defaultDeps={detectPackageManager,runPackageManagerInstall};async function installScaffoldDependencies(e){if(!e.changed||e.skip)return;let t=e.deps??defaultDeps,n=await t.detectPackageManager(e.projectPath),r=await withPhase(e.log,`Installing channel dependencies (${n.kind} install)...`,()=>t.runPackageManagerInstall(n.kind,e.projectPath,{onOutput:createPromptCommandOutput(e.log),signal:e.signal}));packageManagerInstallSucceeded(r)||e.log.warning(`Dependency installation failed. The new channel stays unloadable until \`${n.kind} install\` or a deploy succeeds.`)}function reportOverwrittenFiles(e,t){for(let n of t??[])e.warning(`Overwrote ${n}`)}export{installScaffoldDependencies,reportOverwrittenFiles};
1
+ import{detectPackageManager}from"#setup/package-manager.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{packageManagerInstallSucceeded,runPackageManagerInstall}from"#setup/primitives/pm/run.js";const defaultDeps={detectPackageManager,runPackageManagerInstall};async function installScaffoldDependencies(e){if(!e.changed||e.skip)return;let t=e.deps??defaultDeps,n=await t.detectPackageManager(e.projectPath),r=await withPhase(e.log,`Installing integration dependencies (${n.kind} install)...`,()=>t.runPackageManagerInstall(n.kind,e.projectPath,{onOutput:createPromptCommandOutput(e.log),signal:e.signal}));packageManagerInstallSucceeded(r)||e.log.warning(`Dependency installation failed. The integration stays unloadable until \`${n.kind} install\` or a deploy succeeds.`)}function reportOverwrittenFiles(e,t){for(let n of t??[])e.warning(`Overwrote ${n}`)}export{installScaffoldDependencies,reportOverwrittenFiles};
@@ -8,6 +8,7 @@ export declare function createSetupPresenter(prompter: Prompter, beginExternalAc
8
8
  }) => SetupExternalAction): SetupPresenter;
9
9
  export declare function createSetupContexts(input: {
10
10
  appRoot: string;
11
+ projectRoot?: string;
11
12
  asker: Asker;
12
13
  environment: SetupPrepareContext["environment"];
13
14
  prompter: Prompter;
@@ -1,2 +1,2 @@
1
1
  function createSetupPresenter(e,t){return{log:e.log,note:e.note.bind(e),nextSteps(t){t.length>0&&e.note(t.join(`
2
- `),`Next steps`,{tone:`success`})},beginExternalAction(n){return t===void 0?(e.log.message(n.message),e.log.message(n.url),n.userCode!==void 0&&e.log.message(`Code: ${n.userCode}`),{complete(){}}):t(n)}}}function createSetupContexts(e){let t=createSetupPresenter(e.prompter,e.beginExternalAction),n={appRoot:e.appRoot,presenter:t};return e.signal!==void 0&&(n.signal=e.signal),e.force!==void 0&&(n.force=e.force),{prepare:{...n,asker:e.asker,environment:e.environment,resolveVercelProject:e.resolveVercelProject},apply:n}}export{createSetupContexts,createSetupPresenter};
2
+ `),`Next steps`,{tone:`success`})},beginExternalAction(n){return t===void 0?(e.log.message(n.message),e.log.message(n.url),n.userCode!==void 0&&e.log.message(`Code: ${n.userCode}`),{complete(){}}):t(n)}}}function createSetupContexts(e){let t=createSetupPresenter(e.prompter,e.beginExternalAction),n={appRoot:e.appRoot,projectRoot:e.projectRoot??e.appRoot,presenter:t};return e.signal!==void 0&&(n.signal=e.signal),e.force!==void 0&&(n.force=e.force),{prepare:{...n,asker:e.asker,environment:e.environment,resolveVercelProject:e.resolveVercelProject},apply:n}}export{createSetupContexts,createSetupPresenter};
@@ -1 +1 @@
1
- import{defineSetupIntegration}from"../types.js";import{SHOPIFY_UCP_CHANNEL_TEMPLATE}from"./templates.js";import{join}from"node:path";import{writeTextFile}from"#setup/scaffold/files.js";import{text}from"#setup/ask.js";import{appendEnv}from"#setup/append-env.js";const defaultDeps={appendEnv,writeTextFile};function normalizeStoreDomain(e){return e.trim().replace(/^https?:\/\//i,``).replace(/[/?#].*$/,``)}function validateStoreDomain(e){let t=normalizeStoreDomain(e);try{let e=new URL(`https://${t}`);return t.length>0&&e.hostname.includes(`.`)&&!e.username&&!e.password&&!e.port?null:`Enter a valid Shopify storefront domain.`}catch{return`Enter a valid Shopify storefront domain.`}}async function prepareShopifySetup(e){return{storeDomain:normalizeStoreDomain(await e.asker.ask(text({key:`shopify.store-domain`,message:`Shopify storefront domain`,placeholder:`your-store.myshopify.com`,required:!0,validate:validateStoreDomain})))}}async function applyShopifySetup(e,t,n=defaultDeps){return t.presenter.log.message(`Scaffolding Shopify UCP channel and storefront environment...`),await n.appendEnv(join(t.appRoot,`.env.local`),{SHOPIFY_STORE_DOMAIN:e.storeDomain}),await n.writeTextFile(join(t.appRoot,`agent/channels/ucp.ts`),SHOPIFY_UCP_CHANNEL_TEMPLATE,{force:t.force}),t.presenter.log.success(`Scaffolded channel: ucp`),t.presenter.nextSteps([`Set SHOPIFY_STORE_DOMAIN in .env.local.`,"Shopify cannot reach localhost, so `eve dev` uses Shopify's example agent profile automatically. To test your own profile locally, expose the /.well-known/ucp route with a tool like ngrok."]),{deploymentRequired:!0,facts:[{label:`Store domain`,value:e.storeDomain,kind:`text`}]}}const SHOPIFY_SETUP=defineSetupIntegration({kind:`shopify`,label:`Shopify`,prepare:prepareShopifySetup,apply:applyShopifySetup});export{SHOPIFY_SETUP,applyShopifySetup,prepareShopifySetup};
1
+ import{defineSetupIntegration}from"../types.js";import{SHOPIFY_UCP_CHANNEL_TEMPLATE}from"./templates.js";import{join}from"node:path";import{writeTextFile}from"#setup/scaffold/files.js";import{text}from"#setup/ask.js";import{appendEnv}from"#setup/append-env.js";const defaultDeps={appendEnv,writeTextFile};function normalizeStoreDomain(e){return e.trim().replace(/^https?:\/\//i,``).replace(/[/?#].*$/,``)}function validateStoreDomain(e){let t=normalizeStoreDomain(e);try{let e=new URL(`https://${t}`);return t.length>0&&e.hostname.includes(`.`)&&!e.username&&!e.password&&!e.port?null:`Enter a valid Shopify storefront domain.`}catch{return`Enter a valid Shopify storefront domain.`}}async function prepareShopifySetup(e){return{storeDomain:normalizeStoreDomain(await e.asker.ask(text({key:`shopify.store-domain`,message:`Shopify storefront domain`,placeholder:`your-store.myshopify.com`,required:!0,validate:validateStoreDomain})))}}async function applyShopifySetup(e,t,n=defaultDeps){return t.presenter.log.message(`Scaffolding Shopify UCP channel and storefront environment...`),await n.appendEnv(join(t.projectRoot,`.env.local`),{SHOPIFY_STORE_DOMAIN:e.storeDomain}),await n.writeTextFile(join(t.appRoot,`agent/channels/ucp.ts`),SHOPIFY_UCP_CHANNEL_TEMPLATE,{force:t.force}),t.presenter.log.success(`Scaffolded channel: ucp`),t.presenter.nextSteps([`Set SHOPIFY_STORE_DOMAIN in .env.local.`,"Shopify cannot reach localhost, so `eve dev` uses Shopify's example agent profile automatically. To test your own profile locally, expose the /.well-known/ucp route with a tool like ngrok."]),{deploymentRequired:!0,facts:[{label:`Store domain`,value:e.storeDomain,kind:`text`}]}}const SHOPIFY_SETUP=defineSetupIntegration({kind:`shopify`,label:`Shopify`,prepare:prepareShopifySetup,apply:applyShopifySetup});export{SHOPIFY_SETUP,applyShopifySetup,prepareShopifySetup};
@@ -1 +1 @@
1
- import{defineSetupIntegration}from"../types.js";import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{select}from"#setup/ask.js";import{inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,inspectConnectors:inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid};async function chooseConnector(e,t,n){return t.length===0?`create`:e.asker.ask(select({key:`slack-connector`,message:`Which Slack app would you like to use?`,options:[...t.map(e=>({id:e.uid,value:e,label:`Use ${e.uid}`,hint:e.uid===n?.uid?`Matches this agent`:void 0})),{id:`create`,value:`create`,label:`Create a new Slack app`}],recommended:n??t[0]??`create`,required:!0}))}async function prepareSlackSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`slack-credentials`,message:`How would you like to configure Slack?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}],recommended:`vercel-connect`,required:!0})),r=await t.deriveSlackConnectorSlug(e.appRoot);if(n===`environment`)return{credentials:n,slug:r};let i=await e.resolveVercelProject(`Slack`);if(i.projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let a=await t.inspectConnectors(e.presenter.log,e.appRoot,r,e.signal);return{credentials:n,slug:r,project:i,connector:a.state===`found`?await chooseConnector(e,a.connectors,a.preferred):`create`}}async function applySlackSetup(e,t,n=defaultDeps){if(e.credentials===`environment`){let r=await n.ensureChannel({projectRoot:t.appRoot,kind:`slack`,slackConnectorSlug:e.slug,slackCredentials:`environment`,force:t.force,skipDependencyMutation:!0});return reportOverwrittenFiles(t.presenter.log,r.filesOverwritten),t.presenter.log.success(`Scaffolded channel: slack`),t.presenter.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),{facts:[],deploymentRequired:!0}}let r=await n.provisionSlackbot(t.presenter.log,t.appRoot,e.slug,void 0,{signal:t.signal,selectConnector:async()=>e.connector});if(t.signal?.throwIfAborted(),r.state===`cancelled`)throw new WizardCancelledError;if(r.state!==`attached`){let e=slackbotFailureCopy(r);throw Error(`${e.reason} ${e.followUp}`)}let i=await n.ensureChannel({projectRoot:t.appRoot,kind:`slack`,slackConnectorUid:r.connectorUid,slackConnectorSlug:e.slug,force:t.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(t.presenter.log,i.filesOverwritten),i.action===`skipped`&&!await n.reconcileSlackUid(t.presenter.log,t.appRoot,r,`slack/${e.slug}`))throw Error(`Slack connector UID update is required before deployment.`);return t.presenter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:i.packageJsonUpdated.length>0,log:t.presenter.log,projectPath:t.appRoot,signal:t.signal}),{facts:r.chatUrl===void 0?[]:[{label:`Agent Slack DM`,value:slackMessageDeepLink(r.chatUrl),kind:`url`}],deploymentRequired:!0}}const SLACK_SETUP=defineSetupIntegration({kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,prepare:prepareSlackSetup,apply:applySlackSetup});export{SLACK_SETUP,applySlackSetup,prepareSlackSetup};
1
+ import{defineSetupIntegration}from"../types.js";import{installScaffoldDependencies,reportOverwrittenFiles}from"../shared/scaffold.js";import{deriveSlackConnectorSlug,ensureChannel}from"#setup/scaffold/index.js";import{WizardCancelledError}from"#setup/step.js";import{select}from"#setup/ask.js";import{inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid}from"#setup/slackbot.js";import{slackMessageDeepLink}from"#setup/slack-connect.js";function slackbotFailureCopy(e){switch(e.state){case`not-installed`:return{reason:`Slackbot is not connected to a Slack workspace. Slack channel was not added.`,followUp:"Re-run `eve add channel/slack` after the workspace install is complete."};case`cleanup-failed`:return{reason:`The abandoned Slack connector could not be removed. Slack channel was not added.`,followUp:`Resolve the cleanup warning above before trying again.`};case`connector-lookup-failed`:return{reason:`Existing Slack connectors could not be inspected. Slack channel was not added.`,followUp:"Restore Vercel CLI access, then re-run `eve add channel/slack`."};case`installation-check-failed`:return{reason:`Slack workspace installation could not be verified. Slack channel was not added.`,followUp:"Verify Vercel Connect is reachable, then re-run `eve add channel/slack`."};case`existing-not-installed`:return{reason:`The existing Slack connector is not connected to a Slack workspace. Slack channel was not added.`,followUp:`Resolve the existing connector warning above before trying again.`};case`detach-failed`:return{reason:`Slackbot provisioning could not replace the existing trigger destination. Slack channel was not added.`,followUp:"Run the `vercel connect detach` and `vercel connect attach` commands above."};case`attach-failed`:return{reason:`Slackbot provisioning did not attach this project. Slack channel was not added.`,followUp:"Finish event delivery with the `vercel connect attach` command above."};case`create-failed`:return{reason:`Slackbot creation failed.`,followUp:"Add it later with `eve add channel/slack`."}}}const defaultDeps={deriveSlackConnectorSlug,ensureChannel,inspectConnectors:inspectSlackbotConnectors,provisionSlackbot,reconcileSlackUid};async function chooseConnector(e,t,n){return t.length===0?`create`:e.asker.ask(select({key:`slack-connector`,message:`Which Slack app would you like to use?`,options:[...t.map(e=>({id:e.uid,value:e,label:`Use ${e.uid}`,hint:e.uid===n?.uid?`Matches this agent`:void 0})),{id:`create`,value:`create`,label:`Create a new Slack app`}],recommended:n??t[0]??`create`,required:!0}))}async function prepareSlackSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`slack-credentials`,message:`How would you like to configure Slack?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Read Slack tokens from environment variables`}],recommended:`vercel-connect`,required:!0})),r=await t.deriveSlackConnectorSlug(e.appRoot);if(n===`environment`)return{credentials:n,slug:r};let i=await e.resolveVercelProject(`Slack`);if(i.projectId.length===0)throw Error(`Slack setup with Vercel Connect requires a linked Vercel project.`);let a=await t.inspectConnectors(e.presenter.log,e.projectRoot,r,e.signal);return{credentials:n,slug:r,project:i,connector:a.state===`found`?await chooseConnector(e,a.connectors,a.preferred):`create`}}async function applySlackSetup(e,t,n=defaultDeps){if(e.credentials===`environment`){let r=await n.ensureChannel({projectRoot:t.appRoot,environmentRoot:t.projectRoot,kind:`slack`,slackConnectorSlug:e.slug,slackCredentials:`environment`,force:t.force,skipDependencyMutation:!0});return reportOverwrittenFiles(t.presenter.log,r.filesOverwritten),t.presenter.log.success(`Scaffolded channel: slack`),t.presenter.nextSteps([`Set SLACK_BOT_TOKEN and SLACK_SIGNING_SECRET in .env.local (listed in .env.example).`,`Configure your Slack app to send events to /eve/v1/slack on your public agent URL.`]),{facts:[],deploymentRequired:!0}}let r=await n.provisionSlackbot(t.presenter.log,t.projectRoot,e.slug,void 0,{signal:t.signal,selectConnector:async()=>e.connector});if(t.signal?.throwIfAborted(),r.state===`cancelled`)throw new WizardCancelledError;if(r.state!==`attached`){let e=slackbotFailureCopy(r);throw Error(`${e.reason} ${e.followUp}`)}let i=await n.ensureChannel({projectRoot:t.appRoot,kind:`slack`,slackConnectorUid:r.connectorUid,slackConnectorSlug:e.slug,force:t.force,skipDependencyMutation:!0});if(reportOverwrittenFiles(t.presenter.log,i.filesOverwritten),i.action===`skipped`&&!await n.reconcileSlackUid(t.presenter.log,t.projectRoot,r,`slack/${e.slug}`))throw Error(`Slack connector UID update is required before deployment.`);return t.presenter.log.success(`Scaffolded channel: slack`),await installScaffoldDependencies({changed:i.packageJsonUpdated.length>0,log:t.presenter.log,projectPath:t.projectRoot,signal:t.signal}),{facts:r.chatUrl===void 0?[]:[{label:`Agent Slack DM`,value:slackMessageDeepLink(r.chatUrl),kind:`url`}],deploymentRequired:!0}}const SLACK_SETUP=defineSetupIntegration({kind:`slack`,label:`Slack`,hint:`Slack app mentions and DMs`,prepare:prepareSlackSetup,apply:applySlackSetup});export{SLACK_SETUP,applySlackSetup,prepareSlackSetup};
@@ -0,0 +1,22 @@
1
+ import { type ChannelSetupLog } from "#setup/cli/index.js";
2
+ import type { VercelProjectReference } from "#setup/project-resolution.js";
3
+ import { runVercel, runVercelCaptureStdout } from "#setup/primitives/run-vercel.js";
4
+ export declare const TEAMS_TRIGGER_PATH = "/eve/v1/teams";
5
+ export interface TeamsConnectorRef {
6
+ id: string;
7
+ uid: string;
8
+ }
9
+ export interface ProvisionTeamsConnectorDeps {
10
+ runVercel: typeof runVercel;
11
+ runVercelCaptureStdout: typeof runVercelCaptureStdout;
12
+ }
13
+ export declare function parseCreatedTeamsConnector(stdout: string): TeamsConnectorRef | undefined;
14
+ /** Creates and installs a Teams app through the Vercel Connect CLI. */
15
+ export declare function provisionTeamsConnector(input: {
16
+ name: string;
17
+ log: ChannelSetupLog;
18
+ project: VercelProjectReference;
19
+ projectRoot: string;
20
+ signal?: AbortSignal;
21
+ deps?: ProvisionTeamsConnectorDeps;
22
+ }): Promise<TeamsConnectorRef>;
@@ -0,0 +1 @@
1
+ import{object,string}from"../../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/schemas.js";import"../../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/index.js";import{runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";const TEAMS_TRIGGER_PATH=`/eve/v1/teams`,TeamsConnectorSchema=object({id:string().min(1),uid:string().min(1)});function parseCreatedTeamsConnector(e){try{let t=TeamsConnectorSchema.safeParse(JSON.parse(e));return t.success?t.data:void 0}catch{return}}async function provisionTeamsConnector(e){let t=e.deps??{runVercel,runVercelCaptureStdout},n=createPromptCommandOutput(e.log),r=await withPhase(e.log,`Creating Microsoft Teams connector…`,()=>t.runVercelCaptureStdout([`connect`,`create`,`microsoft-teams`,`--name`,e.name,`-F`,`json`,`--scope`,e.project.orgId],{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal}));if(e.signal?.throwIfAborted(),!r.ok){let e=[r.stderr,r.stdout].find(e=>e!==void 0&&e.trim().length>0);throw Error(e?`Microsoft Teams connector creation failed:\n${e}`:`Microsoft Teams connector creation failed.`)}let i=parseCreatedTeamsConnector(r.stdout);if(i===void 0)throw Error(`Vercel returned an invalid Microsoft Teams connector.`);let a=[`connect`,`attach`,i.uid,`--project`,e.project.projectId,`--environment`,`production`,`--triggers`,`--trigger-path`,TEAMS_TRIGGER_PATH,`--yes`,`--scope`,e.project.orgId],o=await withPhase(e.log,`Connecting Microsoft Teams activities…`,()=>t.runVercel(a,{cwd:e.projectRoot,nonInteractive:!0,onOutput:n,signal:e.signal}));if(e.signal?.throwIfAborted(),!o)throw Error(`Microsoft Teams connector was created, but its trigger destination could not be registered. Run \`vercel ${a.join(` `)}\`.`);return i}export{TEAMS_TRIGGER_PATH,parseCreatedTeamsConnector,provisionTeamsConnector};
@@ -0,0 +1,21 @@
1
+ import type { VercelProjectReference } from "#setup/project-resolution.js";
2
+ import { runVercel, runVercelCaptureStdout } from "#setup/primitives/run-vercel.js";
3
+ import { writeTextFile } from "#setup/scaffold/files.js";
4
+ import { provisionTeamsConnector } from "./connect.js";
5
+ import { type SetupApplyContext, type SetupPrepareContext } from "../types.js";
6
+ export interface TeamsSetupDeps {
7
+ provisionConnector: typeof provisionTeamsConnector;
8
+ runVercel: typeof runVercel;
9
+ runVercelCaptureStdout: typeof runVercelCaptureStdout;
10
+ writeTextFile: typeof writeTextFile;
11
+ }
12
+ export interface TeamsSetupPlan {
13
+ name: string;
14
+ project: VercelProjectReference;
15
+ }
16
+ export declare function prepareTeamsSetup(context: SetupPrepareContext): Promise<TeamsSetupPlan>;
17
+ export declare function applyTeamsSetup(plan: TeamsSetupPlan, context: SetupApplyContext, deps?: TeamsSetupDeps): Promise<{
18
+ facts: never[];
19
+ deploymentRequired: true;
20
+ }>;
21
+ export declare const TEAMS_SETUP: import("../types.js").SetupIntegration;
@@ -0,0 +1,7 @@
1
+ import{defineSetupIntegration}from"../types.js";import{provisionTeamsConnector}from"./connect.js";import{join}from"node:path";import{writeTextFile}from"#setup/scaffold/files.js";import{text}from"#setup/ask.js";import{runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";const defaultDeps={provisionConnector:provisionTeamsConnector,runVercel,runVercelCaptureStdout,writeTextFile};function connectTemplate(e){return`import { connectTeamsCredentials } from "@vercel/connect/eve";
2
+ import { teamsChannel } from "eve/channels/teams";
3
+
4
+ export default teamsChannel({
5
+ credentials: connectTeamsCredentials(${JSON.stringify(e)}),
6
+ });
7
+ `}async function prepareTeamsSetup(e){let t=await e.asker.ask(text({key:`teams.bot-name`,message:`Microsoft Teams bot name`,detected:`eve agent`,required:!0,validate:e=>e.trim().length===0?`A bot name is required.`:null})),n=await e.resolveVercelProject(`Microsoft Teams`);return{name:t.trim(),project:n}}async function applyTeamsSetup(e,t,n=defaultDeps){let r=await n.provisionConnector({...e,log:t.presenter.log,projectRoot:t.projectRoot,signal:t.signal,deps:n});return await n.writeTextFile(join(t.appRoot,`agent/channels/teams.ts`),connectTemplate(r.uid),{force:t.force}),t.presenter.log.success(`Scaffolded channel: teams`),t.presenter.nextSteps([`Deploy the agent.`,`Mention the bot in a channel, or send it a message in a personal chat.`]),{facts:[],deploymentRequired:!0}}const TEAMS_SETUP=defineSetupIntegration({kind:`teams`,label:`Microsoft Teams`,hint:`Managed Teams bot with Vercel Connect`,prepare:prepareTeamsSetup,apply:applyTeamsSetup});export{TEAMS_SETUP,applyTeamsSetup,prepareTeamsSetup};
@@ -15,7 +15,10 @@ export type SetupPresenter = Pick<Prompter, "log" | "note"> & {
15
15
  }): SetupExternalAction;
16
16
  };
17
17
  export interface SetupPrepareContext {
18
+ /** Selected agent project where authored files are changed. */
18
19
  readonly appRoot: string;
20
+ /** Project root for shared dependencies, Vercel links, and environment files. */
21
+ readonly projectRoot: string;
19
22
  readonly asker: Asker;
20
23
  readonly environment: IntegrationSetupEnvironment;
21
24
  readonly presenter: SetupPresenter;
@@ -24,7 +27,10 @@ export interface SetupPrepareContext {
24
27
  force?: boolean;
25
28
  }
26
29
  export interface SetupApplyContext {
30
+ /** Selected agent project where authored files are changed. */
27
31
  readonly appRoot: string;
32
+ /** Project root for shared dependencies, Vercel links, and environment files. */
33
+ readonly projectRoot: string;
28
34
  readonly presenter: SetupPresenter;
29
35
  signal?: AbortSignal;
30
36
  force?: boolean;
@@ -1 +1 @@
1
- import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.93`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`1.0.0`),l=resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),u=[];for(let[t,n]of Object.entries(i)){let r=join(e.projectRoot,t);await writeTextFile(r,n),u.push(r)}let d={"@vercel/connect":c,ai:s,eve:formatEveDependencySpecifier(o.version),zod:l},f={};for(let[e,t]of Object.entries(d))hasDeclaredDependency(r,e)||(f[e]=t);let p={};Object.keys(f).length>0&&(p.dependencies=f),isPackageManagerWorkspaceMember(t,e.projectRoot)||(p.nodeEngineRequirement=o.nodeEngine);let m=await patchPackageJson(n,p),h=await patchWorkspaceRootPackageJson(t,e.projectRoot,{nodeEngineRequirement:o.nodeEngine}),g=h.nodeEngineOverride??m.nodeEngineOverride,_=await applyPackageManagerWorkspaceConfiguration({packageManager:t,projectRoot:e.projectRoot});return{filesWritten:u,dependenciesAdded:Object.keys(f).sort(),nodeEngineOverride:g,configurationFilesChanged:[...m.changed?[n]:[],...h.changed&&h.path!==void 0?[h.path]:[],..._.filesWritten]}}export{addAgentToProject};
1
+ import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{readFile}from"node:fs/promises";import{join}from"node:path";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(e){let t=e.packageManager??`pnpm`,n=join(e.projectRoot,`package.json`);if(!await pathExists(n))throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let r;try{r=JSON.parse(await readFile(n,`utf8`))}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Cannot add an eve agent because "${n}" is not valid JSON. No files were changed. Fix the file, then retry eve init. ${t}`)}let i=agentTemplateFiles(e.model,e.reasoning),a=[];for(let t of Object.keys(i))await pathExists(join(e.projectRoot,t))&&a.push(t);if(a.length===0&&await pathExists(join(e.projectRoot,`agent`))&&a.push(`agent/`),a.length>0)throw Error(`Cannot add an eve agent to "${e.projectRoot}" because it already has: ${a.join(`, `)}.`);let o=resolveEvePackageContract(e.evePackage),s=resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.105`),c=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`),l=resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),u=[];for(let[t,n]of Object.entries(i)){let r=join(e.projectRoot,t);await writeTextFile(r,n),u.push(r)}let d={"@vercel/connect":c,ai:s,eve:formatEveDependencySpecifier(o.version),zod:l},f={};for(let[e,t]of Object.entries(d))hasDeclaredDependency(r,e)||(f[e]=t);let p={};Object.keys(f).length>0&&(p.dependencies=f),isPackageManagerWorkspaceMember(t,e.projectRoot)||(p.nodeEngineRequirement=o.nodeEngine);let m=await patchPackageJson(n,p),h=await patchWorkspaceRootPackageJson(t,e.projectRoot,{nodeEngineRequirement:o.nodeEngine}),g=h.nodeEngineOverride??m.nodeEngineOverride,_=await applyPackageManagerWorkspaceConfiguration({packageManager:t,projectRoot:e.projectRoot});return{filesWritten:u,dependenciesAdded:Object.keys(f).sort(),nodeEngineOverride:g,configurationFilesChanged:[...m.changed?[n]:[],...h.changed&&h.path!==void 0?[h.path]:[],..._.filesWritten]}}export{addAgentToProject};
@@ -3,7 +3,7 @@ import type { AgentReasoningDefinition } from "../../../shared/agent-definition.
3
3
  import { type WorkspaceRootMutation } from "../workspace-root.js";
4
4
  export declare const CURRENT_DIRECTORY_PROJECT_NAME = ".";
5
5
  export declare const DEFAULT_AI_PACKAGE_VERSION = "__AI_SDK_VERSION__";
6
- export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "__VERCEL_CONNECT_VERSION__";
6
+ export { DEFAULT_CONNECT_PACKAGE_VERSION } from "../version-tokens.js";
7
7
  export declare const DEFAULT_ZOD_PACKAGE_VERSION = "__ZOD_VERSION__";
8
8
  /**
9
9
  * The eve package metadata that generated projects consume together. Keeping
@@ -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.93`,DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.57.0`,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{DEFAULT_CONNECT_PACKAGE_VERSION,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.105`,DEFAULT_ZOD_PACKAGE_VERSION=`4.5.4`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.58.1`,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__",
@@ -121,4 +121,4 @@ __EVE_INIT_REASONING__ modelOptions: {
121
121
  },
122
122
  },
123
123
  });
124
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.93`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`1.0.0`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,e.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:s,nodeEngine:s};await mkdir(t,{recursive:!0});for(let[a,o]of Object.entries(templateFiles({byokProvider:i,includeRootOnlyPackageJsonFields:!l}))){let i=`${t}/${a}`,s=await pathExists(i);await writeTextFile(i,renderTemplate(o,u),{force:n&&r}),s&&await e.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:t,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(a,c,{nodeEngineRequirement:o.nodeEngine,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),t}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
124
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate(e.includeRootOnlyPackageJsonFields)}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let n=await readdir(e),r=blockingCreateInPlaceEntries(n);if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(e){let t=resolve(e.targetDirectory??process.cwd(),e.projectName),n=e.projectName===`.`,r=e.overwriteExisting??!1,i=e.byokProvider??!1,a=e.packageManager??`pnpm`,o=resolveEvePackageContract(e.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c=resolve(e.workspaceProbeDirectory??t),l=isPackageManagerWorkspaceMember(a,c);if(n)await assertCanCreateInPlace(t,r);else if(await pathExists(t))throw Error(`Cannot create project because "${t}" already exists.`);let u={appName:basename(t),model:e.model,reasoning:e.reasoning,eveVersion:o.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,e.aiPackageVersion??`^7.0.105`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,e.zodPackageVersion??`4.5.4`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,e.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:s,nodeEngine:s};await mkdir(t,{recursive:!0});for(let[a,o]of Object.entries(templateFiles({byokProvider:i,includeRootOnlyPackageJsonFields:!l}))){let i=`${t}/${a}`,s=await pathExists(i);await writeTextFile(i,renderTemplate(o,u),{force:n&&r}),s&&await e.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:t,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(a,c,{nodeEngineRequirement:o.nodeEngine,onWorkspaceRootMutation:e.onWorkspaceRootMutation}),t}async function isEveProject(e){for(let t of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${t}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -73,6 +73,8 @@ export declare function normalizeSlackConnectorSlug(input: string): SlackConnect
73
73
  export declare function deriveSlackConnectorSlug(projectRoot: string, projectNameHint?: string): Promise<SlackConnectorSlug>;
74
74
  export interface EnsureChannelOptions {
75
75
  projectRoot: string;
76
+ /** Root for environment files shared by workspace agents. */
77
+ environmentRoot?: string;
76
78
  kind: ChannelKind;
77
79
  /** Manager that owns generated project configuration. Defaults to pnpm. */
78
80
  packageManager?: PackageManagerKind;
@@ -4,7 +4,7 @@ import { slackChannel } from "eve/channels/slack";
4
4
  export default slackChannel({
5
5
  credentials: connectSlackCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{}};for(let[n,r]of Object.entries(t)){let t=join(e.projectRoot,n);if(n===`agent/channels/eve.ts`&&!e.force&&await pathExists(t)){d.push(t);continue}let i=await pathExists(t);await writeTextFile(t,renderWebAppTemplate(r,f),{force:!0}),c.push(t),i&&l.push(t)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`1.0.0`);o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,t)}a=buildSlackConnectTemplate(e.slackConnectorUid??`slack/${i}`)}else{a=`import { slackChannel } from "eve/channels/slack";
7
+ `}const SLACK_ENV_EXAMPLE_VALUES={SLACK_BOT_TOKEN:``,SLACK_SIGNING_SECRET:``};function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let r=join(e,n);await pathExists(r)&&t.push(r)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=join(e.projectRoot,`app/page.tsx`),r=await pathExists(n);if(!e.force&&!e.skipDependencyMutation&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let i=resolveWebPackageVersions(e.webPackageVersions,e.webAuthentication),a=e.packageManager??`pnpm`,o=resolve(e.workspaceProbeDirectory??e.projectRoot),s=await patchWebPackageJson(e.projectRoot,a,o,i,e.onWorkspaceRootMutation,!e.skipDependencyMutation,e.webAuthentication),c=[],l=[],u=[],d=[],f=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?c.push(t):d.push(t)}let p=await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:e.projectRoot,workspaceProbeRoot:o,onWorkspaceRootMutation:e.onWorkspaceRootMutation});if(c.push(...p.filesWritten),d.push(...p.filesSkipped),!e.skipDependencyMutation){let t={...WEB_APP_TEMPLATE_FILES,...e.webAuthentication===`sign-in-with-vercel`?WEB_APP_SIGN_IN_WITH_VERCEL_TEMPLATE_FILES:{}};for(let[n,r]of Object.entries(t)){let t=join(e.projectRoot,n);if(n===`agent/channels/eve.ts`&&!e.force&&await pathExists(t)){d.push(t);continue}let i=await pathExists(t);await writeTextFile(t,renderWebAppTemplate(r,f),{force:!0}),c.push(t),i&&l.push(t)}}u.push(...await findCompetingNextConfigFiles(e.projectRoot));let m=[...new Set(c)],h=[...new Set(d)].filter(e=>!m.includes(e)),g={kind:`web`,action:r?`overwritten`:`created`,filesWritten:m,filesSkipped:h,packageJsonUpdated:s.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),s.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=s.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let r=e.slackCredentials??`vercel-connect`,i=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot),a,o=[],s=[t],c=[],l;if(r===`vercel-connect`){if(!e.skipDependencyMutation){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);o=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,t)}a=buildSlackConnectTemplate(e.slackConnectorUid??`slack/${i}`)}else{a=`import { slackChannel } from "eve/channels/slack";
8
8
 
9
9
  export default slackChannel();
10
- `;let t=join(e.projectRoot,`.env.example`);l={path:t,...await pathExists(t)?{content:await readFile(t,`utf8`)}:{}},(await appendEnv(t,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?s.push(t):c.push(t)}try{await writeTextFile(t,a,{force:e.force})}catch(e){throw l!==void 0&&(l.content===void 0?await unlink(l.path):await writeFile(l.path,l.content,`utf8`)),e}let u={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:s,filesSkipped:c,packageJsonUpdated:o,slackConnectorSlug:i};return n&&(u.filesOverwritten=[t]),u}async function listAuthoredChannels(e){let t=join(e,`channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
10
+ `;let t=join(e.environmentRoot??e.projectRoot,`.env.example`);l={path:t,...await pathExists(t)?{content:await readFile(t,`utf8`)}:{}},(await appendEnv(t,SLACK_ENV_EXAMPLE_VALUES)).written.length>0?s.push(t):c.push(t)}try{await writeTextFile(t,a,{force:e.force})}catch(e){throw l!==void 0&&(l.content===void 0?await unlink(l.path):await writeFile(l.path,l.content,`utf8`)),e}let u={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:s,filesSkipped:c,packageJsonUpdated:o,slackConnectorSlug:i};return n&&(u.filesOverwritten=[t]),u}async function listAuthoredChannels(e){let t=join(e,`channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
@@ -1,4 +1,4 @@
1
- import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{endpointForProtocol}from"../connections/catalog.js";import{readFile,readdir,writeFile}from"node:fs/promises";import{join}from"node:path";const DEFAULT_CONNECT_PACKAGE_VERSION=`1.0.0`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
1
+ import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{endpointForProtocol}from"../connections/catalog.js";import{readFile,readdir,writeFile}from"node:fs/promises";import{join}from"node:path";const CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
2
2
  `)}\n }),\n`;case`none`:return``}}function renderMcpTemplate(e,t,n){return`${n.kind===`connect`?`import { connect } from "@vercel/connect/eve";
3
3
  import { defineMcpClientConnection } from "eve/connections";
4
4
  `:`import { defineMcpClientConnection } from "eve/connections";
@@ -15,7 +15,7 @@ export default defineOpenAPIConnection({
15
15
  spec: "${e.spec}",
16
16
  ${i} description: "${t}",
17
17
  ${authBlock(n)}});
18
- `}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??DEFAULT_CONNECT_PACKAGE_VERSION);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let n=``;await pathExists(e)&&(n=await readFile(e,`utf8`));let r=t.filter(e=>!envKeyPresent(n,e));if(r.length===0)return[];let i=`${n.length>0&&!n.endsWith(`
18
+ `}function renderTemplate(e,t,n,r){return e===`mcp`?renderMcpTemplate(t,n,r):renderOpenApiTemplate(t,n,r)}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function ensureConnectDependency(e,t){if(!await pathExists(e))return[];let n=JSON.parse(await readFile(e,`utf8`));return(isJsonObject(n)&&isJsonObject(n.dependencies)?n.dependencies[CONNECT_PACKAGE_NAME]:void 0)===t?[]:(await patchPackageJson(e,{dependencies:{[CONNECT_PACKAGE_NAME]:t}}),[{path:e,dependencies:[CONNECT_PACKAGE_NAME],devDependencies:[],scripts:[]}])}async function ensureConnectionDependencies(e){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);return ensureConnectDependency(join(e.projectRoot,`package.json`),t)}function envKeyPresent(e,t){return RegExp(`^\\s*(?:export\\s+)?${t}\\s*=`,`m`).test(e)}async function seedEnvPlaceholders(e,t){if(t.length===0)return[];let n=``;await pathExists(e)&&(n=await readFile(e,`utf8`));let r=t.filter(e=>!envKeyPresent(n,e));if(r.length===0)return[];let i=`${n.length>0&&!n.endsWith(`
19
19
  `)?`
20
20
  `:``}${r.map(e=>`${e}=`).join(`
21
- `)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??DEFAULT_CONNECT_PACKAGE_VERSION);s.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(i,renderTemplate(e.protocol,r,e.entry.description,n),{force:!0});let c=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),a),l={slug:t,protocol:e.protocol,action:o?`overwritten`:`created`,filePath:i,filesWritten:[i],filesSkipped:[],packageJsonUpdated:s,envKeysAdded:c,envKeysRequired:a};return o&&(l.filesOverwritten=[i]),l}async function listAuthoredConnections(e){let t=join(e,USER_AUTHORED_CONNECTION_DIR),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
21
+ `)}\n`;return await writeFile(e,n+i,`utf8`),r}async function ensureConnection(e){let t=e.slug??e.entry.slug,n=resolveAuth(e.entry),r=endpointForProtocol(e.entry,e.protocol);if(r===null)throw Error(`Connection "${t}" is missing a ${e.protocol===`mcp`?`mcp.url`:`openapi.spec`} endpoint for protocol "${e.protocol}".`);let i=join(e.projectRoot,USER_AUTHORED_CONNECTION_DIR,`${t}.ts`),a=envKeysForAuth(n),o=await pathExists(i);if(!e.force&&o)return{slug:t,protocol:e.protocol,action:`skipped`,filePath:i,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[],envKeysAdded:[],envKeysRequired:a};let s=[];if(n.kind===`connect`){let t=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`2.2.0`);s.push(...await ensureConnectDependency(join(e.projectRoot,`package.json`),t))}await writeTextFile(i,renderTemplate(e.protocol,r,e.entry.description,n),{force:!0});let c=await seedEnvPlaceholders(join(e.projectRoot,`.env.local`),a),l={slug:t,protocol:e.protocol,action:o?`overwritten`:`created`,filePath:i,filesWritten:[i],filesSkipped:[],packageJsonUpdated:s,envKeysAdded:c,envKeysRequired:a};return o&&(l.filesOverwritten=[i]),l}async function listAuthoredConnections(e){let t=join(e,USER_AUTHORED_CONNECTION_DIR),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{ensureConnection,ensureConnectionDependencies,listAuthoredConnections};
@@ -1 +1 @@
1
- import{DEFAULT_EVE_PACKAGE_CONTRACT}from"../create/project.js";function resolveWebPackageVersions(e,t){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.93`,betterAuthPackageVersion:e?.betterAuthPackageVersion??`1.6.26`,nextPackageVersion:e?.nextPackageVersion??(t===`sign-in-with-vercel`?`16.3.0`:`16.3.4`),reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.5.4`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}export{resolveWebPackageVersions};
1
+ import{DEFAULT_EVE_PACKAGE_CONTRACT}from"../create/project.js";function resolveWebPackageVersions(e,t){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.105`,betterAuthPackageVersion:e?.betterAuthPackageVersion??`1.6.26`,nextPackageVersion:e?.nextPackageVersion??(t===`sign-in-with-vercel`?`16.3.0`:`16.3.4`),reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.5.4`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}export{resolveWebPackageVersions};
@@ -1,9 +1,10 @@
1
+ export declare const DEFAULT_CONNECT_PACKAGE_VERSION = "2.2.0";
1
2
  /**
2
3
  * Returns a scaffold version value, resolving a build-stamp token at the point
3
4
  * of need when the running code is unstamped. The published package is stamped
4
5
  * by the build (`scripts/stamp-version-tokens.mjs`), so the fallback only ever
5
6
  * fires in a dev tree — tsc watch emits and tests running from `src` — where
6
- * the live workspace catalog *is* the truth the stamp would have captured.
7
+ * the live package and workspace manifests are the sources the stamp would have captured.
7
8
  * Outside a dev tree an unstamped token still throws, because writing the
8
9
  * literal token into a scaffolded package.json would break the generated
9
10
  * project.
@@ -1 +1 @@
1
- import{dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`VERCEL_CONNECT`)]:{kind:`catalog`,packageName:`@vercel/connect`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let e=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let t=join(e,`package.json`);if(existsSync(t)&&JSON.parse(readFileSync(t,`utf8`)).name===`eve`)return e;let n=dirname(e);if(n===e)return;e=n}}function findWorkspaceManifest(e){let t=e;for(;;){let e=join(t,`pnpm-workspace.yaml`);if(existsSync(e))return e;let n=dirname(t);if(n===t)return;t=n}}function readCatalogVersion(e,t){let n=readFileSync(e,`utf8`).split(/\r?\n/),r=!1;for(let e of n){if(/^catalog:\s*$/.test(e)){r=!0;continue}if(!r)continue;if(/^\S/.test(e))break;let n=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(n&&(n[1]??n[2])===t)return n[3]}}function resolveTokenFromDevTree(e){let t=TOKEN_SOURCES[e];if(t!==void 0)try{let e=findEvePackageRoot();if(e===void 0||!existsSync(join(e,`scripts/stamp-version-tokens.mjs`)))return;if(t.kind===`eve-version`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`));return typeof t.version==`string`?t.version:void 0}if(t.kind===`eve-node-engine`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).engines?.node;return typeof t==`string`?t:void 0}let n=findWorkspaceManifest(e);return n===void 0?void 0:readCatalogVersion(n,t.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{resolveVersionToken};
1
+ import{dirname,join}from"node:path";import{existsSync,readFileSync,realpathSync}from"node:fs";import{fileURLToPath}from"node:url";function versionToken(e){return`__${e}_VERSION__`}function bareToken(e){return`__${e}__`}const NODE_ENGINE_TOKEN=bareToken(`NODE_ENGINE`),DEFAULT_CONNECT_PACKAGE_VERSION=`2.2.0`,TOKEN_SOURCES={[versionToken(`EVE_PACKAGE`)]:{kind:`eve-version`},[versionToken(`EVE_PACKAGE_DEPENDENCY`)]:{kind:`eve-version`},[NODE_ENGINE_TOKEN]:{kind:`eve-node-engine`},[versionToken(`AI_SDK`)]:{kind:`catalog`,packageName:`ai`},[versionToken(`NEXT`)]:{kind:`catalog`,packageName:`next`},[versionToken(`REACT`)]:{kind:`catalog`,packageName:`react`},[versionToken(`REACT_DOM`)]:{kind:`catalog`,packageName:`react-dom`},[versionToken(`STREAMDOWN`)]:{kind:`catalog`,packageName:`streamdown`},[versionToken(`ZOD`)]:{kind:`catalog`,packageName:`zod`},[versionToken(`TYPESCRIPT`)]:{kind:`catalog`,packageName:`typescript`},[versionToken(`TYPES_REACT`)]:{kind:`catalog`,packageName:`@types/react`},[versionToken(`TYPES_REACT_DOM`)]:{kind:`catalog`,packageName:`@types/react-dom`}},resolvedTokens=new Map;function findEvePackageRoot(){let e=dirname(realpathSync(fileURLToPath(import.meta.url)));for(;;){let t=join(e,`package.json`);if(existsSync(t)&&JSON.parse(readFileSync(t,`utf8`)).name===`eve`)return e;let n=dirname(e);if(n===e)return;e=n}}function findWorkspaceManifest(e){let t=e;for(;;){let e=join(t,`pnpm-workspace.yaml`);if(existsSync(e))return e;let n=dirname(t);if(n===t)return;t=n}}function readCatalogVersion(e,t){let n=readFileSync(e,`utf8`).split(/\r?\n/),r=!1;for(let e of n){if(/^catalog:\s*$/.test(e)){r=!0;continue}if(!r)continue;if(/^\S/.test(e))break;let n=e.match(/^\s+(?:"([^"]+)"|([\w@/.-]+)):\s*"([^"]+)"/);if(n&&(n[1]??n[2])===t)return n[3]}}function resolveTokenFromDevTree(e){let t=TOKEN_SOURCES[e];if(t!==void 0)try{let e=findEvePackageRoot();if(e===void 0||!existsSync(join(e,`scripts/stamp-version-tokens.mjs`)))return;if(t.kind===`eve-version`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`));return typeof t.version==`string`?t.version:void 0}if(t.kind===`eve-node-engine`){let t=JSON.parse(readFileSync(join(e,`package.json`),`utf8`)).engines?.node;return typeof t==`string`?t:void 0}let n=findWorkspaceManifest(e);return n===void 0?void 0:readCatalogVersion(n,t.packageName)}catch{return}}function resolveVersionToken(e,t){if(!t.startsWith(`__`))return t;let n=resolvedTokens.get(t);if(n!==void 0)return n;let r=resolveTokenFromDevTree(t);if(r===void 0)throw Error(`Scaffold received unstamped version token (${e}=${t}). Build eve before using its dist entrypoint.`);return resolvedTokens.set(t,r),r}export{DEFAULT_CONNECT_PACKAGE_VERSION,resolveVersionToken};
@@ -56,6 +56,8 @@ export type PublicAgentStaticModelDefinition = string | LanguageModel;
56
56
  export type AgentModelResolveContext = DynamicResolveContext;
57
57
  export interface PublicAgentModelSelectionDefinition {
58
58
  readonly model: PublicAgentStaticModelDefinition;
59
+ /** Override the agent reasoning effort for this selection; omitted values inherit it. */
60
+ readonly reasoning?: AgentReasoningDefinition;
59
61
  /** Context window of the selected model, in tokens. */
60
62
  readonly modelContextWindowTokens?: number;
61
63
  /** Provider options for the selected model. */
@@ -0,0 +1,4 @@
1
+ /** Joins an internal eve route to a public target, including compact named-agent mounts. */
2
+ export declare function joinEveRoutePath(basePath: string, routePath: string): string;
3
+ /** Maps a compact named-agent route back to the internal eve protocol namespace. */
4
+ export declare function normalizePublicEveRoutePath(path: string): string;
@@ -0,0 +1 @@
1
+ import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";const EVE_NAMED_AGENT_MOUNT_PATTERN=/^\/eve\/[a-z0-9][a-z0-9_-]*$/,EVE_NAMED_AGENT_PROTOCOL_PATTERN=/^\/eve\/[a-z0-9][a-z0-9_-]*\/v1$/;function joinEveRoutePath(e,t){let n=trimTrailingSlash(e),r=t.startsWith(`/`)?t:`/${t}`;if(r===EVE_ROUTE_PREFIX||r.startsWith(`${EVE_ROUTE_PREFIX}/`)){if(EVE_NAMED_AGENT_MOUNT_PATTERN.test(n))return`${n}${r.slice(4)}`;if(EVE_NAMED_AGENT_PROTOCOL_PATTERN.test(n))return`${n}${r.slice(EVE_ROUTE_PREFIX.length)}`}return`${n}${r}`}function normalizePublicEveRoutePath(e){return e.replace(/^\/eve\/[a-z0-9][a-z0-9_-]*\/v1(?=\/|$)/,EVE_ROUTE_PREFIX)}function trimTrailingSlash(e){return e===`/`?``:e.endsWith(`/`)?e.slice(0,-1):e}export{joinEveRoutePath,normalizePublicEveRoutePath};
@@ -3,7 +3,7 @@
3
3
  * `/eve/v1/*` transport surface is mounted under on its callback origin.
4
4
  *
5
5
  * Multi-agent host integrations mount each named agent under
6
- * `/eve/agents/<name>/eve/v1/*` and strip that prefix before requests reach
6
+ * `/eve/<name>/v1/*` and strip that prefix before requests reach
7
7
  * the eve service, so a running agent cannot recover its own public mount
8
8
  * from an inbound request. The integration exports this variable in the
9
9
  * generated service build command, the eve CLI resolves it once into the
@@ -1 +1 @@
1
- function createRemoteAgentRouteUrl(e,t){return new URL(t.replace(/^\/+/,``),`${trimTrailingSlash(e)}/`).toString()}function trimTrailingSlash(e){return e.endsWith(`/`)?e.slice(0,-1):e}export{createRemoteAgentRouteUrl};
1
+ import{joinEveRoutePath}from"#shared/eve-route-path.js";function createRemoteAgentRouteUrl(e,t){let n=new URL(t,`http://eve.local`),r=new URL(e);return r.pathname=joinEveRoutePath(r.pathname,n.pathname),r.search=n.search,r.hash=n.hash,r.toString()}export{createRemoteAgentRouteUrl};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-C2APNCdP.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CxWcZCsU.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -64,7 +64,7 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
64
64
  * Named agent mounted by a framework integration such as `withEve({ agents })`.
65
65
  *
66
66
  * `agent: "support"` targets same-origin routes under
67
- * `/eve/agents/support/eve/v1/...`. Do not combine with `host`.
67
+ * `/eve/support/v1/...`. Do not combine with `host`.
68
68
  */
69
69
  readonly agent?: string;
70
70
  /**
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-C2APNCdP.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-CxWcZCsU.js";
2
2
 
3
3
  export { useEveAgent };
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-D0YnDLi_.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-X0asmJg-.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -67,7 +67,7 @@ export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData>
67
67
  * Named agent mounted by a framework integration such as `withEve({ agents })`.
68
68
  *
69
69
  * `agent: "support"` targets same-origin routes under
70
- * `/eve/agents/support/eve/v1/...`. Do not combine with `host`.
70
+ * `/eve/support/v1/...`. Do not combine with `host`.
71
71
  */
72
72
  readonly agent?: string;
73
73
  /** Authentication configuration; a function value is resolved per request. */
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-D0YnDLi_.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-X0asmJg-.js";
2
2
 
3
3
  export { useEveAgent };
package/docs/README.md CHANGED
@@ -12,28 +12,32 @@ Important naming note:
12
12
 
13
13
  ## Find the page for your task
14
14
 
15
- | To do this | Read this |
16
- | -------------------------------------------------------- | -------------------------------------------------------------------------------------- |
17
- | Create a project, or understand the file layout | [Getting Started](./getting-started.mdx) |
18
- | Set the model, reasoning, or other agent-wide config | [Agents](./agent-config.md) |
19
- | Change what the agent does and how it behaves | [Instructions](./instructions.mdx) |
20
- | Give the agent a typed capability it can call | [Tools](./tools/overview.mdx) |
21
- | Require approval, or ask the user something mid-turn | [Human in the Loop](./tools/human-in-the-loop.md) |
22
- | Call an external HTTP API or MCP server | [Connections](./connections/overview.mdx) |
23
- | Add a messaging surface (Slack, Discord, iMessage, …) | [Channels](./channels/overview.mdx) |
24
- | Expose your own HTTP route as a conversation surface | [Custom Channels](./channels/custom.mdx) |
25
- | Package a procedure the agent loads only when it applies | [Skills](./skills.mdx) |
26
- | Carry state across turns, or shape what the model sees | [State](./concepts/state.md), [Context Control](./concepts/context-control.md) |
27
- | Run commands or untrusted code in isolation | [Sandboxes](./sandbox.mdx) |
28
- | Delegate work to a specialist child agent | [Subagents](./subagents/index.mdx) |
29
- | Run work on a recurring schedule | [Schedules](./schedules.mdx) |
30
- | Install an existing integration instead of writing one | [Add Integrations](./install-integrations.mdx) |
31
- | Link a Vercel project and deploy to production | [Deploy to Vercel](./guides/deployment/vercel.mdx) |
32
- | Self-host, or compare hosting strategies | [Deployment](./guides/deployment/overview.md) |
33
- | Authorize routes, sessions, and per-user access | [Authentication](./guides/auth-and-route-protection.md) |
34
- | Build a web UI, or stream a session to a client | [Client SDK](./guides/client/overview.mdx), [Frontend](./guides/frontend/overview.mdx) |
35
- | Test the agent's behavior | [Evals](./evals/overview.mdx) |
36
- | Look up a CLI command or an exported type | [CLI](./reference/cli.md), [TypeScript API](./reference/typescript-api.md) |
15
+ | To do this | Read this |
16
+ | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
17
+ | Organize agents, subagents, and browser application code | [Project Structure](./concepts/project-structure.mdx) |
18
+ | Create a project and run your first agent | [Getting Started](./getting-started.mdx) |
19
+ | Look up agent files and discovery rules | [Agent Files](./reference/agent-files.md) |
20
+ | Set the model, reasoning, or other agent-wide config | [Agents](./agent-config.md) |
21
+ | Choose an agent model automatically for each request | [Automatic Model Selection](./guides/evaluate.md) |
22
+ | Change what the agent does and how it behaves | [Instructions](./instructions.mdx) |
23
+ | Give the agent a typed capability it can call | [Tools](./tools/overview.mdx) |
24
+ | Require approval, or ask the user something mid-turn | [Human in the Loop](./tools/human-in-the-loop.md) |
25
+ | Call an external HTTP API or MCP server | [Connections](./connections/overview.mdx) |
26
+ | Add a messaging surface (Slack, Discord, iMessage, …) | [Channels](./channels/overview.mdx) |
27
+ | Expose your own HTTP route as a conversation surface | [Custom Channels](./channels/custom.mdx) |
28
+ | Package a procedure the agent loads only when it applies | [Skills](./skills.mdx) |
29
+ | Carry state across turns, or shape what the model sees | [State](./concepts/state.md), [Context Control](./concepts/context-control.md) |
30
+ | Run commands or untrusted code in isolation | [Sandboxes](./sandbox.mdx) |
31
+ | Delegate work to a specialist child agent | [Subagents](./subagents/index.mdx) |
32
+ | Run work on a recurring schedule | [Schedules](./schedules.mdx) |
33
+ | Install an existing integration instead of writing one | [Add Integrations](./install-integrations.mdx) |
34
+ | Link a Vercel project and deploy to production | [Deploy to Vercel](./guides/deployment/vercel.mdx) |
35
+ | Self-host, or compare hosting strategies | [Deployment](./guides/deployment/overview.md) |
36
+ | Authorize routes, sessions, and per-user access | [Authentication](./guides/auth-and-route-protection.md) |
37
+ | Add a browser application | [Next.js](./guides/frontend/nextjs.mdx), [Nuxt](./guides/frontend/nuxt.mdx), or [SvelteKit](./guides/frontend/sveltekit.mdx) |
38
+ | Build a custom web UI, or stream a session to a client | [Client SDK](./guides/client/overview.mdx), [Frontend](./guides/frontend/overview.mdx) |
39
+ | Test the agent's behavior | [Evals](./evals/overview.mdx) |
40
+ | Look up a CLI command or an exported type | [CLI](./reference/cli.md), [TypeScript API](./reference/typescript-api.md) |
37
41
 
38
42
  ## Legal and safeguards
39
43
 
@@ -54,24 +58,25 @@ Unless you configure stricter controls, eve agents may operate with permissive s
54
58
  For a full picture rather than a single task, read in this order:
55
59
 
56
60
  1. [Getting Started](./getting-started.mdx)
57
- 2. [Tutorial](./tutorial/first-agent.mdx)
58
- 3. [Agents](./agent-config.md)
59
- 4. [TypeScript API Reference](./reference/typescript-api.md)
60
- 5. [Context Control](./concepts/context-control.md)
61
- 6. [Skills](./skills.mdx)
62
- 7. [Tools](./tools/overview.mdx)
63
- 8. [Connections](./connections/overview.mdx)
64
- 9. [Sandboxes](./sandbox.mdx)
65
- 10. [Channels](./channels/overview.mdx)
66
- 11. [Session Context](./guides/session-context.md)
67
- 12. [Sessions and Streaming](./concepts/sessions-runs-and-streaming.md)
68
- 13. [Client SDK](./guides/client/overview.mdx)
69
- 14. [Subagents](./subagents/index.mdx)
70
- 15. [Schedules](./schedules.mdx)
71
- 16. [Evals](./evals/overview.mdx)
72
- 17. [Authentication](./guides/auth-and-route-protection.md)
73
- 18. [Deployment](./guides/deployment/overview.md)
74
- 19. [CLI](./reference/cli.md)
61
+ 2. [Project Structure](./concepts/project-structure.mdx)
62
+ 3. [Tutorial](./tutorial/first-agent.mdx)
63
+ 4. [Agents](./agent-config.md)
64
+ 5. [TypeScript API Reference](./reference/typescript-api.md)
65
+ 6. [Context Control](./concepts/context-control.md)
66
+ 7. [Skills](./skills.mdx)
67
+ 8. [Tools](./tools/overview.mdx)
68
+ 9. [Connections](./connections/overview.mdx)
69
+ 10. [Sandboxes](./sandbox.mdx)
70
+ 11. [Channels](./channels/overview.mdx)
71
+ 12. [Session Context](./guides/session-context.md)
72
+ 13. [Sessions and Streaming](./concepts/sessions-runs-and-streaming.md)
73
+ 14. [Client SDK](./guides/client/overview.mdx)
74
+ 15. [Subagents](./subagents/index.mdx)
75
+ 16. [Schedules](./schedules.mdx)
76
+ 17. [Evals](./evals/overview.mdx)
77
+ 18. [Authentication](./guides/auth-and-route-protection.md)
78
+ 19. [Deployment](./guides/deployment/overview.md)
79
+ 20. [CLI](./reference/cli.md)
75
80
 
76
81
  ## The public mental model
77
82
 
@@ -62,6 +62,9 @@ to compaction calls.
62
62
 
63
63
  ### Choose the model dynamically
64
64
 
65
+ To select a model from the incoming prompt with an AI SDK evaluation model, use
66
+ [`autoModel` from `eve/experimental/evaluate`](./guides/evaluate).
67
+
65
68
  `model` also accepts `defineDynamic({ events })`. Each matching handler must
66
69
  return the concrete model for its scope; a dynamic model has no compiled
67
70
  default.
@@ -99,7 +102,7 @@ fails the turn.
99
102
  model without valid credentials fails at request time.
100
103
  - **Serialization.** Session/turn selections must be model id strings; return
101
104
  live `LanguageModel` objects only from `step.started`.
102
- - **Selection object.** `{ model, modelContextWindowTokens?, modelOptions? }`.
105
+ - **Selection object.** `{ model, reasoning?, modelContextWindowTokens?, modelOptions? }`.
103
106
  When `modelContextWindowTokens` is omitted, eve resolves it from the AI
104
107
  Gateway catalog and caches successful metadata in durable session state for
105
108
  24 hours. Set it explicitly for an unlisted or custom model. Dynamic agents
@@ -126,6 +129,10 @@ Supported values are `"provider-default"`, `"none"`, `"minimal"`, `"low"`,
126
129
  `"medium"`, `"high"`, and `"xhigh"`. The selected model and provider determine
127
130
  which levels are available and how they map to provider-native settings. Use
128
131
  `modelOptions.providerOptions` when you need provider-specific reasoning controls.
132
+ A dynamic model selection can return `reasoning` alongside `model` to override
133
+ the agent-level setting for that selection. Omitting it inherits the agent setting;
134
+ `"provider-default"` explicitly uses the provider's default.
135
+
129
136
  Run `eve set --reasoning high` to update this field from the command line.
130
137
 
131
138
  ## Compaction