eve 0.32.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +8 -4
  3. package/dist/src/channel/channel-address.d.ts +4 -1
  4. package/dist/src/channel/channel-address.js +1 -1
  5. package/dist/src/channel/channel-operations.d.ts +3 -1
  6. package/dist/src/channel/compiled-channel.d.ts +2 -1
  7. package/dist/src/channel/cross-channel-receive.d.ts +5 -2
  8. package/dist/src/channel/cross-channel-receive.js +1 -1
  9. package/dist/src/channel/session.d.ts +6 -2
  10. package/dist/src/channel/session.js +1 -1
  11. package/dist/src/channel/types.d.ts +6 -0
  12. package/dist/src/channel/types.js +1 -1
  13. package/dist/src/chunks/{use-eve-agent-CX87G1vU.js → use-eve-agent-3oBnxzhV.js} +27 -17
  14. package/dist/src/chunks/{use-eve-agent-DwyRde1N.js → use-eve-agent-B-Hky2f4.js} +27 -17
  15. package/dist/src/cli/commands/agent-prompt/collect-intent.md +3 -0
  16. package/dist/src/cli/commands/agent-prompt/scaffold.md +4 -2
  17. package/dist/src/cli/commands/info.js +1 -1
  18. package/dist/src/cli/commands/init-repl.d.ts +1 -1
  19. package/dist/src/cli/commands/init-repl.js +1 -1
  20. package/dist/src/cli/commands/init.d.ts +7 -0
  21. package/dist/src/cli/commands/init.js +1 -1
  22. package/dist/src/cli/commands/integration-connect.d.ts +3 -3
  23. package/dist/src/cli/commands/integration-connect.js +1 -1
  24. package/dist/src/cli/commands/integration-setup.js +1 -1
  25. package/dist/src/cli/commands/set.d.ts +20 -0
  26. package/dist/src/cli/commands/set.js +1 -0
  27. package/dist/src/cli/dev/tui/runner.js +1 -1
  28. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  29. package/dist/src/cli/option-parsers.d.ts +3 -0
  30. package/dist/src/cli/option-parsers.js +1 -1
  31. package/dist/src/cli/run.js +1 -1
  32. package/dist/src/client/agent-info-schema.d.ts +28 -5
  33. package/dist/src/client/agent-info-schema.js +1 -1
  34. package/dist/src/client/session.js +1 -1
  35. package/dist/src/client/types.d.ts +3 -0
  36. package/dist/src/compiler/extension-compatibility.d.ts +19 -9
  37. package/dist/src/compiler/extension-compatibility.js +1 -1
  38. package/dist/src/compiler/manifest.d.ts +119 -19
  39. package/dist/src/compiler/manifest.js +1 -1
  40. package/dist/src/compiler/model-catalog.d.ts +2 -30
  41. package/dist/src/compiler/model-catalog.js +1 -1
  42. package/dist/src/compiler/module-map.d.ts +2 -2
  43. package/dist/src/compiler/module-map.js +2 -2
  44. package/dist/src/compiler/normalize-agent-config.js +1 -1
  45. package/dist/src/compiler/normalize-instructions.js +1 -1
  46. package/dist/src/compiler/normalize-manifest.js +2 -2
  47. package/dist/src/compiler/normalize-skill.js +1 -1
  48. package/dist/src/compiler/normalize-subagent.d.ts +5 -1
  49. package/dist/src/compiler/normalize-subagent.js +1 -1
  50. package/dist/src/compiler/remote-agent-node.d.ts +4 -1
  51. package/dist/src/compiler/workspace-resources.js +1 -1
  52. package/dist/src/context/dynamic-model-lifecycle.d.ts +7 -2
  53. package/dist/src/context/dynamic-model-lifecycle.js +1 -1
  54. package/dist/src/context/dynamic-subagent-lifecycle.js +1 -1
  55. package/dist/src/context/hook-lifecycle.js +1 -1
  56. package/dist/src/context/keys.d.ts +8 -0
  57. package/dist/src/context/keys.js +1 -1
  58. package/dist/src/evals/session.js +1 -1
  59. package/dist/src/execution/dispatch-runtime-actions-step.js +1 -1
  60. package/dist/src/execution/effective-agent-config.js +1 -1
  61. package/dist/src/execution/node-step.js +1 -1
  62. package/dist/src/execution/session-command-wire.js +1 -1
  63. package/dist/src/execution/session.d.ts +2 -0
  64. package/dist/src/execution/session.js +2 -2
  65. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  66. package/dist/src/execution/turn-control-receiver.d.ts +2 -0
  67. package/dist/src/execution/turn-control-receiver.js +1 -1
  68. package/dist/src/execution/workflow-steps.js +1 -1
  69. package/dist/src/harness/emission.d.ts +1 -1
  70. package/dist/src/harness/emission.js +1 -1
  71. package/dist/src/harness/step-hooks.d.ts +1 -1
  72. package/dist/src/harness/step-hooks.js +1 -1
  73. package/dist/src/harness/tool-loop.d.ts +1 -1
  74. package/dist/src/harness/tool-loop.js +2 -2
  75. package/dist/src/harness/types.d.ts +11 -5
  76. package/dist/src/harness/types.js +1 -1
  77. package/dist/src/internal/application/package.js +1 -1
  78. package/dist/src/internal/authored-definition/core.js +1 -1
  79. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  80. package/dist/src/internal/authored-module-loader.js +1 -1
  81. package/dist/src/internal/authored-module-map-loader.js +1 -1
  82. package/dist/src/internal/model-catalog.d.ts +46 -0
  83. package/dist/src/internal/model-catalog.js +1 -0
  84. package/dist/src/internal/nitro/host/build-vercel-agent-summary.js +1 -1
  85. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  86. package/dist/src/internal/nitro/host/dev-host-fingerprint.js +1 -1
  87. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js +1 -1
  88. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.d.ts +20 -10
  89. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  90. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  91. package/dist/src/internal/nitro/routes/info.js +1 -1
  92. package/dist/src/internal/vercel-agent-summary.d.ts +12 -3
  93. package/dist/src/internal/vercel-agent-summary.js +1 -1
  94. package/dist/src/protocol/message.d.ts +2 -2
  95. package/dist/src/protocol/message.js +1 -1
  96. package/dist/src/public/channels/chat-sdk/chatSdkChannel.d.ts +5 -5
  97. package/dist/src/public/channels/chat-sdk/chatSdkChannel.js +2 -2
  98. package/dist/src/public/channels/discord/discordChannel.d.ts +3 -1
  99. package/dist/src/public/channels/discord/discordChannel.js +1 -1
  100. package/dist/src/public/channels/eve.d.ts +3 -1
  101. package/dist/src/public/channels/eve.js +1 -1
  102. package/dist/src/public/channels/github/githubChannel.d.ts +3 -1
  103. package/dist/src/public/channels/github/githubChannel.js +1 -1
  104. package/dist/src/public/channels/index.d.ts +1 -1
  105. package/dist/src/public/channels/linear/linearChannel.d.ts +3 -1
  106. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  107. package/dist/src/public/channels/photon/photonIMessageChannel.d.ts +3 -1
  108. package/dist/src/public/channels/photon/photonIMessageChannel.js +1 -1
  109. package/dist/src/public/channels/slack/slackChannel.d.ts +3 -1
  110. package/dist/src/public/channels/slack/slackChannel.js +1 -1
  111. package/dist/src/public/channels/teams/teamsChannel.d.ts +3 -1
  112. package/dist/src/public/channels/teams/teamsChannel.js +1 -1
  113. package/dist/src/public/channels/telegram/telegramChannel.d.ts +3 -1
  114. package/dist/src/public/channels/telegram/telegramChannel.js +1 -1
  115. package/dist/src/public/channels/twilio/twilioChannel.d.ts +3 -1
  116. package/dist/src/public/channels/twilio/twilioChannel.js +1 -1
  117. package/dist/src/public/definitions/agent.d.ts +5 -7
  118. package/dist/src/public/definitions/agent.js +1 -1
  119. package/dist/src/public/definitions/channel.d.ts +3 -1
  120. package/dist/src/public/definitions/channel.js +1 -1
  121. package/dist/src/public/definitions/tool.d.ts +1 -5
  122. package/dist/src/public/definitions/tool.js +1 -1
  123. package/dist/src/public/index.d.ts +1 -1
  124. package/dist/src/runtime/agent/bootstrap.d.ts +19 -6
  125. package/dist/src/runtime/agent/bootstrap.js +1 -1
  126. package/dist/src/runtime/agent/model-catalog.d.ts +10 -0
  127. package/dist/src/runtime/agent/model-catalog.js +1 -0
  128. package/dist/src/runtime/agent/resolve-model.d.ts +8 -4
  129. package/dist/src/runtime/agent/resolve-model.js +1 -1
  130. package/dist/src/runtime/framework-channels/index.js +1 -1
  131. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  132. package/dist/src/runtime/resolve-agent.d.ts +2 -2
  133. package/dist/src/runtime/resolve-agent.js +1 -1
  134. package/dist/src/runtime/resolve-channel.js +1 -1
  135. package/dist/src/runtime/resolve-dynamic-subagent.d.ts +2 -5
  136. package/dist/src/runtime/subagents/dynamic-agent-config.d.ts +8 -7
  137. package/dist/src/runtime/subagents/dynamic-agent-config.js +1 -1
  138. package/dist/src/runtime/types.d.ts +11 -4
  139. package/dist/src/setup/flows/deploy.d.ts +5 -3
  140. package/dist/src/setup/flows/deploy.js +1 -1
  141. package/dist/src/setup/flows/ensure-vercel-project.d.ts +5 -1
  142. package/dist/src/setup/flows/ensure-vercel-project.js +1 -1
  143. package/dist/src/setup/flows/model-source-change.d.ts +1 -0
  144. package/dist/src/setup/flows/model-source-change.js +1 -1
  145. package/dist/src/setup/integrations/discord/setup.js +1 -1
  146. package/dist/src/setup/integrations/github/setup.js +1 -1
  147. package/dist/src/setup/integrations/linear/setup.js +1 -1
  148. package/dist/src/setup/integrations/photon/setup-flow.js +1 -1
  149. package/dist/src/setup/integrations/slack/setup.js +1 -1
  150. package/dist/src/setup/scaffold/create/add-to-project.d.ts +2 -0
  151. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  152. package/dist/src/setup/scaffold/create/project.d.ts +3 -1
  153. package/dist/src/setup/scaffold/create/project.js +4 -4
  154. package/dist/src/shared/agent-definition.d.ts +23 -23
  155. package/dist/src/shared/agent-definition.js +1 -1
  156. package/dist/src/shared/channel-definition.d.ts +3 -1
  157. package/dist/src/shared/dynamic-tool-definition.d.ts +4 -10
  158. package/dist/src/shared/dynamic-tool-definition.js +1 -1
  159. package/dist/src/svelte/index.js +1 -1
  160. package/dist/src/svelte/use-eve-agent.js +1 -1
  161. package/dist/src/vue/index.js +1 -1
  162. package/dist/src/vue/use-eve-agent.js +1 -1
  163. package/docs/agent-config.md +30 -19
  164. package/docs/channels/chat-sdk.mdx +5 -5
  165. package/docs/channels/custom.mdx +20 -0
  166. package/docs/channels/discord.mdx +1 -0
  167. package/docs/channels/eve.mdx +2 -0
  168. package/docs/channels/github.mdx +1 -1
  169. package/docs/channels/linear.mdx +1 -1
  170. package/docs/channels/overview.mdx +19 -0
  171. package/docs/channels/photon.mdx +5 -2
  172. package/docs/channels/slack.mdx +5 -11
  173. package/docs/concepts/execution-model-and-durability.mdx +5 -8
  174. package/docs/concepts/sessions-runs-and-streaming.md +2 -2
  175. package/docs/guides/dynamic-capabilities.md +24 -20
  176. package/docs/installation.mdx +7 -1
  177. package/docs/reference/cli.md +33 -8
  178. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # eve
2
2
 
3
+ ## 0.33.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ccaa596: Dynamic models and subagents now resolve without compiled fallbacks or placeholder configs. `defineDynamic` accepts only `events`; dynamic model handlers must return a concrete selection, while runtime model metadata is normalized and cached when the selection becomes active.
8
+ - 2dd193b: Channel message sends now use `turnPolicy: "steer"` by default, so accepted messages replace active turns through cancellation-backed steering without a separate cancel request. Set `turnPolicy: "queue"` on a channel or individual send to preserve the previous wait-for-completion behavior.
9
+
10
+ ### Patch Changes
11
+
12
+ - 672c054: Add `eve set` with `--model` and `--reasoning` options for changing an existing agent's model settings, and add the same model settings to `eve init` for scaffolding.
13
+ - 1ee27be: Interactive setup now offers an explicit exit after `eve init` and runs Vercel login and project linking in place whenever Vercel-backed integration setup or deployment needs them.
14
+
3
15
  ## 0.32.0
4
16
 
5
17
  ### Minor Changes
@@ -189,7 +201,7 @@
189
201
  ### Patch Changes
190
202
 
191
203
  - 22bfa02: Add guided Photon setup through `eve add channel/photon-imessage`, including project creation, phone registration, Vercel Connect or portable credentials, and channel scaffolding.
192
- - 0c0de19: Add an opt-in experimental steering policy to Chat SDK sends that cancels an active turn before delivering its replacement message.
204
+ - 0c0de19: Add an opt-in steering policy to Chat SDK sends that cancels an active turn before delivering its replacement message.
193
205
  - b00a79d: Add `photonIMessageChannel`, a first-class Photon iMessage channel with lazy credentials, Vercel OIDC webhook verification, and automatic eve session routing.
194
206
  - 495e93b: Resolve leading `$HOME` paths in the built-in `read_file`, `write_file`, `glob`, and `grep` tools so agents can directly access packaged skill references advertised in their prompt.
195
207
  - bf01952: Local trace spans now capture model and tool payloads: the system prompt, prompt messages, and response text/reasoning/tool calls on model spans, and call arguments/results on tool spans, each capped at 32 KB with provider transport metadata stripped. Set `EVE_TRACES_CONTENT=off` to keep payloads out of the spool.
package/README.md CHANGED
@@ -122,10 +122,13 @@ export default defineAgent({
122
122
  npx eve@latest init my-agent
123
123
  ```
124
124
 
125
- `eve init` writes a new agent with eve's default model. Pass `--channel-web-nextjs` to add the
126
- Web Chat application. It installs dependencies, initializes Git, and starts the
127
- development server. Targeting an existing project directory (`eve init .`) adds
128
- the agent files and missing dependencies instead. It does not create a Vercel
125
+ `eve init` writes a new agent with eve's default model. Pass `--model
126
+ openai/gpt-5.5` to choose another AI Gateway model, `--reasoning high` to set a
127
+ reasoning effort, or `--channel-web-nextjs` to add the Web Chat application. It
128
+ installs dependencies, initializes Git, and starts the development server. When
129
+ it finds a supported coding-agent REPL, the handoff menu can open that REPL
130
+ instead or exit. Targeting an existing project directory (`eve init .`) adds the
131
+ agent files and missing dependencies instead. It does not create a Vercel
129
132
  project or deploy the agent.
130
133
 
131
134
  CLI commands:
@@ -135,6 +138,7 @@ CLI commands:
135
138
  - `eve build` — compile `.eve/` and build the host output
136
139
  - `eve start` — serve the built `.output/` app
137
140
  - `eve dev` — start the local runtime and REPL
141
+ - `eve set [--model <model-id>] [--reasoning <effort>]` — change root model settings
138
142
  - `eve extension init <name>` — create a new extension package
139
143
  - `eve extension build` — build an extension package
140
144
 
@@ -2,7 +2,7 @@ import type { UserContent } from "ai";
2
2
  import type { ChannelAdapter } from "#channel/adapter.js";
3
3
  import type { SendPayload } from "#channel/routes.js";
4
4
  import { type Session } from "#channel/session.js";
5
- import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback } from "#channel/types.js";
5
+ import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
6
6
  import type { RunMode } from "#shared/run-mode.js";
7
7
  interface BaseChannelAddressDeliveryOptions {
8
8
  readonly auth: SessionAuthContext | null;
@@ -10,6 +10,7 @@ interface BaseChannelAddressDeliveryOptions {
10
10
  readonly initiatorAuth?: SessionAuthContext | null;
11
11
  readonly mode?: RunMode;
12
12
  readonly title?: string;
13
+ readonly turnPolicy?: TurnPolicy;
13
14
  }
14
15
  /** Delivery options for a channel address whose continuation token is already bound. */
15
16
  export type ChannelAddressDeliveryOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelAddressDeliveryOptions : BaseChannelAddressDeliveryOptions & {
@@ -45,6 +46,7 @@ export declare function createChannelAddress<TState = undefined>(input: {
45
46
  readonly requestId?: string;
46
47
  };
47
48
  readonly runtime: Runtime;
49
+ readonly turnPolicy?: TurnPolicy;
48
50
  }): ChannelAddress<TState>;
49
51
  /** Builds a request-scoped factory for channel addresses on one authored channel. */
50
52
  export declare function createChannelAddressFn<TState = undefined>(input: {
@@ -54,5 +56,6 @@ export declare function createChannelAddressFn<TState = undefined>(input: {
54
56
  readonly requestId?: string;
55
57
  };
56
58
  readonly runtime: Runtime;
59
+ readonly turnPolicy?: TurnPolicy;
57
60
  }): ChannelAddressFn<TState>;
58
61
  export {};
@@ -1 +1 @@
1
- import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{normalizeSendInput,serializeUrlFilePartsInMessage}from"#channel/send-input.js";import{isRuntimeSessionOwnershipConflictError}from"#execution/runtime-errors.js";import{isReservedSessionCommandToken}from"#execution/session-command-token.js";function createChannelAddress(r){let i=r.metadata??{},a=`${r.channelName}:${r.continuationToken}`;if(isReservedSessionCommandToken(a))throw Error(`Channel address "${a}" uses eve's reserved session namespace.`);return{continuationToken:r.continuationToken,async deliver(n,o){let s=normalizeSendInput(n),c=sessionCallbackToTurnCaller(o.callback),l={auth:o.auth,kind:`send`,payload:{...s,message:serializeUrlFilePartsInMessage(s.message)},requestId:i.requestId},u=c===void 0?l:{...l,caller:c},dispatch=async()=>{let t=await r.runtime.dispatchContinuation({command:u,continuationToken:a});return t.status===`accepted`?createSession(t.sessionId,r.runtime,i):void 0},d=await dispatch();if(d!==void 0)return d;if(s.inputResponses&&s.inputResponses.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let f=o.state,p={adapter:f===void 0?r.adapter:{...r.adapter,state:{...r.adapter.state,...f}},auth:o.auth,capabilities:o.mode===`task`?void 0:{requestInput:!0},callback:o.callback,channelName:r.channelName,continuationToken:a,initiatorAuth:o.initiatorAuth,input:{context:s.context,message:serializeUrlFilePartsInMessage(s.message)??``,outputSchema:s.outputSchema},mode:o.mode??`conversation`,requestId:i.requestId,title:o.title};try{return createSession((await r.runtime.createSession(p)).sessionId,r.runtime,i)}catch(e){if(!isRuntimeSessionOwnershipConflictError(e))throw e;let t=await dispatch();if(t!==void 0)return t;throw e}},async send(e,t){return await this.deliver({message:e},t)},async respond(e,t){if(e===void 0||e.length===0)throw Error(`respond() requires at least one input response.`);return await this.deliver({inputResponses:e},t)},async cancel(e){return await r.runtime.dispatchContinuation({command:{kind:`cancel`,turnId:e?.turnId},continuationToken:a})},async compact(){return await r.runtime.dispatchContinuation({command:{kind:`compact`},continuationToken:a})},async clear(){return await r.runtime.dispatchContinuation({command:{kind:`clear`},continuationToken:a})},async reset(e){return await r.runtime.dispatchContinuation({command:{kind:`reset`,reason:e?.reason},continuationToken:a})},async resolveSession(){let t=await r.runtime.resolveContinuation(a);return t===void 0?void 0:createSession(t.sessionId,r.runtime,i)}}}function createChannelAddressFn(e){return t=>createChannelAddress({...e,continuationToken:t})}export{createChannelAddress,createChannelAddressFn};
1
+ import{createSession,sessionCallbackToTurnCaller}from"#channel/session.js";import{normalizeSendInput,serializeUrlFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{isRuntimeSessionOwnershipConflictError}from"#execution/runtime-errors.js";import{isReservedSessionCommandToken}from"#execution/session-command-token.js";function createChannelAddress(r){let i=r.metadata??{},a=`${r.channelName}:${r.continuationToken}`;if(isReservedSessionCommandToken(a))throw Error(`Channel address "${a}" uses eve's reserved session namespace.`);return{continuationToken:r.continuationToken,async deliver(n,o){let s=normalizeSendInput(n),c=sessionCallbackToTurnCaller(o.callback),l={auth:o.auth,kind:`send`,payload:{...s,message:serializeUrlFilePartsInMessage(s.message)},requestId:i.requestId,turnPolicy:s.message===void 0?void 0:o.turnPolicy??r.turnPolicy??DEFAULT_TURN_POLICY},u=c===void 0?l:{...l,caller:c},dispatch=async()=>{let t=await r.runtime.dispatchContinuation({command:u,continuationToken:a});return t.status===`accepted`?createSession(t.sessionId,r.runtime,{...i,turnPolicy:r.turnPolicy}):void 0},d=await dispatch();if(d!==void 0)return d;if(s.inputResponses&&s.inputResponses.length>0)throw Error(`Cannot deliver inputResponses — the target session was not found via continuation token.`);let f=o.state,p={adapter:f===void 0?r.adapter:{...r.adapter,state:{...r.adapter.state,...f}},auth:o.auth,capabilities:o.mode===`task`?void 0:{requestInput:!0},callback:o.callback,channelName:r.channelName,continuationToken:a,initiatorAuth:o.initiatorAuth,input:{context:s.context,message:serializeUrlFilePartsInMessage(s.message)??``,outputSchema:s.outputSchema},mode:o.mode??`conversation`,requestId:i.requestId,title:o.title};try{return createSession((await r.runtime.createSession(p)).sessionId,r.runtime,{...i,turnPolicy:r.turnPolicy})}catch(e){if(!isRuntimeSessionOwnershipConflictError(e))throw e;let t=await dispatch();if(t!==void 0)return t;throw e}},async send(e,t){return await this.deliver({message:e},t)},async respond(e,t){if(e===void 0||e.length===0)throw Error(`respond() requires at least one input response.`);return await this.deliver({inputResponses:e},t)},async cancel(e){return await r.runtime.dispatchContinuation({command:{kind:`cancel`,turnId:e?.turnId},continuationToken:a})},async compact(){return await r.runtime.dispatchContinuation({command:{kind:`compact`},continuationToken:a})},async clear(){return await r.runtime.dispatchContinuation({command:{kind:`clear`},continuationToken:a})},async reset(e){return await r.runtime.dispatchContinuation({command:{kind:`reset`,reason:e?.reason},continuationToken:a})},async resolveSession(){let t=await r.runtime.resolveContinuation(a);return t===void 0?void 0:createSession(t.sessionId,r.runtime,{...i,turnPolicy:r.turnPolicy})}}}function createChannelAddressFn(e){return t=>createChannelAddress({...e,continuationToken:t})}export{createChannelAddress,createChannelAddressFn};
@@ -3,7 +3,7 @@ import type { ChannelAdapter } from "#channel/adapter.js";
3
3
  import { type ChannelAddressDeliveryOptions } from "#channel/channel-address.js";
4
4
  import type { SendPayload } from "#channel/routes.js";
5
5
  import type { Session } from "#channel/session.js";
6
- import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback } from "#channel/types.js";
6
+ import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, TurnPolicy } from "#channel/types.js";
7
7
  import type { InputResponse } from "#runtime/input/types.js";
8
8
  import type { JsonObject } from "#shared/json.js";
9
9
  import type { RunMode } from "#shared/run-mode.js";
@@ -15,6 +15,7 @@ interface BaseChannelSendOptions {
15
15
  readonly mode?: RunMode;
16
16
  readonly outputSchema?: JsonObject;
17
17
  readonly title?: string;
18
+ readonly turnPolicy?: TurnPolicy;
18
19
  }
19
20
  /** Options for sending a message from a channel-local continuation address. */
20
21
  export type ChannelSendOptions<TState = undefined> = [TState] extends [undefined] ? BaseChannelSendOptions : BaseChannelSendOptions & {
@@ -68,5 +69,6 @@ export declare function createChannelOperations<TState = undefined>(input: {
68
69
  readonly requestId?: string;
69
70
  };
70
71
  readonly runtime: Runtime;
72
+ readonly turnPolicy?: TurnPolicy;
71
73
  }): ChannelReceiveContext<TState>;
72
74
  export {};
@@ -5,7 +5,7 @@ import type { NormalizedChannelCorsOptions } from "#channel/cors.js";
5
5
  import type { TypedReceiveTarget } from "#channel/receive-target.js";
6
6
  import type { RouteDefinition } from "#channel/routes.js";
7
7
  import type { Session } from "#channel/session.js";
8
- import type { SessionAuthContext } from "#channel/types.js";
8
+ import type { SessionAuthContext, TurnPolicy } from "#channel/types.js";
9
9
  export declare const CHANNEL_SENTINEL: "eve:channel";
10
10
  /** Structural identity shared by public authored channels and compiled channels. */
11
11
  export interface ChannelReference<TReceiveTarget = Record<string, unknown>> extends TypedReceiveTarget<TReceiveTarget> {
@@ -21,6 +21,7 @@ export interface CompiledChannel<TState = undefined, TReceiveTarget = Record<str
21
21
  readonly target: Readonly<TReceiveTarget>;
22
22
  readonly auth: SessionAuthContext | null;
23
23
  }, ctx: ChannelReceiveContext<TState>) => Promise<Session>;
24
+ readonly turnPolicy?: TurnPolicy;
24
25
  }
25
26
  export declare function isCompiledChannel(value: unknown): value is CompiledChannel;
26
27
  export declare function getChannelInstrumentationKind(value: unknown): string | undefined;
@@ -3,13 +3,14 @@ import type { ChannelAdapter } from "#channel/adapter.js";
3
3
  import { type ChannelReference, type CompiledChannel } from "#channel/compiled-channel.js";
4
4
  import type { InferReceiveTarget } from "#channel/receive-target.js";
5
5
  import type { Session } from "#channel/session.js";
6
- import type { Runtime, SessionAuthContext } from "#channel/types.js";
6
+ import type { Runtime, SessionAuthContext, TurnPolicy } from "#channel/types.js";
7
7
  import type { ResolvedChannelDefinition } from "#runtime/types.js";
8
8
  /**
9
9
  * Options for sending a message to a channel selected with `ctx.to(...)`.
10
10
  */
11
11
  export interface CrossChannelSendOptions {
12
12
  readonly auth: SessionAuthContext | null;
13
+ readonly turnPolicy?: TurnPolicy;
13
14
  }
14
15
  /** Message delivery bound to one channel-specific proactive target. */
15
16
  export interface CrossChannelTargetHandle {
@@ -27,6 +28,7 @@ export interface CrossChannelTarget {
27
28
  readonly definition: CompiledChannel;
28
29
  readonly receive?: CompiledChannel["receive"];
29
30
  readonly adapter?: ChannelAdapter;
31
+ readonly turnPolicy?: CompiledChannel["turnPolicy"];
30
32
  }
31
33
  /**
32
34
  * Projects an agent's resolved channels into the receiver-input shape.
@@ -42,12 +44,13 @@ export declare function toCrossChannelTargets(channels: readonly ResolvedChannel
42
44
  export declare function createCrossChannelToFn(runtime: Runtime, channels: readonly CrossChannelTarget[]): CrossChannelToFn;
43
45
  interface InvokeChannelReceiveInput {
44
46
  readonly runtime: Runtime;
45
- readonly target: Pick<CrossChannelTarget, "name" | "receive" | "adapter">;
47
+ readonly target: Pick<CrossChannelTarget, "name" | "receive" | "adapter" | "turnPolicy">;
46
48
  readonly input: {
47
49
  readonly message: string | UserContent;
48
50
  readonly target: Readonly<Record<string, unknown>>;
49
51
  readonly auth: SessionAuthContext | null;
50
52
  };
53
+ readonly turnPolicy?: TurnPolicy;
51
54
  readonly describeMissingReceive: () => string;
52
55
  readonly describeMissingAdapter: () => string;
53
56
  }
@@ -1,2 +1,2 @@
1
- import{createChannelOperations}from"#channel/channel-operations.js";import{isCompiledChannel}from"#channel/compiled-channel.js";function toCrossChannelTargets(e){return e.flatMap(e=>e.definition===void 0?[]:[{name:e.name,definition:e.definition,receive:e.receive,adapter:e.adapter}])}function createCrossChannelToFn(e,t){return(n,r)=>{let i=resolveTargetByReference(n,t);return{async send(t,n){return await invokeChannelReceive({runtime:e,target:i,input:{message:t,target:r,auth:n.auth},describeMissingReceive:()=>`ctx.to(): channel "${i.name}" does not implement receive(). Declare a receive hook on the channel to accept cross-channel sessions.`,describeMissingAdapter:()=>`ctx.to(): channel "${i.name}" has no adapter — cannot build ctx.from().`})}}}}async function invokeChannelReceive(t){if(!t.target.receive)throw Error(t.describeMissingReceive());if(!t.target.adapter)throw Error(t.describeMissingAdapter());let n=createChannelOperations({adapter:t.target.adapter,channelName:t.target.name,runtime:t.runtime});return await t.target.receive(t.input,n)}function resolveTargetByReference(e,t){for(let n of t)if(n.definition===e)return n;let n=resolveTargetByRouteFingerprint(e,t);if(n!==null)return n;throw Error(`ctx.to(): the channel passed as the first argument is not registered in this agent's channels/. Import the channel module's default export from agent/channels/<name>.ts and pass that value.`)}function resolveTargetByRouteFingerprint(e,n){if(!isCompiledChannel(e))return null;let r=createRouteFingerprint(e);if(r===null)return null;let i=new Map;for(let e of n)createRouteFingerprint(e.definition)===r&&i.set(e.name,e);if(i.size===1)return[...i.values()][0];if(i.size>1)throw Error(`ctx.to(): the channel passed as the first argument matches multiple registered channels by route shape. Import a channel with a unique route set from agent/channels/<name>.ts before passing it to ctx.to().`);return null}function createRouteFingerprint(e){return e.routes.length===0?null:e.routes.map(e=>`${e.method.toUpperCase()} ${e.path}`).sort().join(`
1
+ import{createChannelOperations}from"#channel/channel-operations.js";import{isCompiledChannel}from"#channel/compiled-channel.js";function toCrossChannelTargets(e){return e.flatMap(e=>e.definition===void 0?[]:[{name:e.name,definition:e.definition,receive:e.receive,adapter:e.adapter,turnPolicy:e.turnPolicy}])}function createCrossChannelToFn(e,t){return(n,r)=>{let i=resolveTargetByReference(n,t);return{async send(t,n){return await invokeChannelReceive({runtime:e,target:i,input:{message:t,target:r,auth:n.auth},turnPolicy:n.turnPolicy,describeMissingReceive:()=>`ctx.to(): channel "${i.name}" does not implement receive(). Declare a receive hook on the channel to accept cross-channel sessions.`,describeMissingAdapter:()=>`ctx.to(): channel "${i.name}" has no adapter — cannot build ctx.from().`})}}}}async function invokeChannelReceive(t){if(!t.target.receive)throw Error(t.describeMissingReceive());if(!t.target.adapter)throw Error(t.describeMissingAdapter());let n=createChannelOperations({adapter:t.target.adapter,channelName:t.target.name,runtime:t.runtime,turnPolicy:t.turnPolicy??t.target.turnPolicy});return await t.target.receive(t.input,n)}function resolveTargetByReference(e,t){for(let n of t)if(n.definition===e)return n;let n=resolveTargetByRouteFingerprint(e,t);if(n!==null)return n;throw Error(`ctx.to(): the channel passed as the first argument is not registered in this agent's channels/. Import the channel module's default export from agent/channels/<name>.ts and pass that value.`)}function resolveTargetByRouteFingerprint(e,n){if(!isCompiledChannel(e))return null;let r=createRouteFingerprint(e);if(r===null)return null;let i=new Map;for(let e of n)createRouteFingerprint(e.definition)===r&&i.set(e.name,e);if(i.size===1)return[...i.values()][0];if(i.size>1)throw Error(`ctx.to(): the channel passed as the first argument matches multiple registered channels by route shape. Import a channel with a unique route set from agent/channels/<name>.ts before passing it to ctx.to().`);return null}function createRouteFingerprint(e){return e.routes.length===0?null:e.routes.map(e=>`${e.method.toUpperCase()} ${e.path}`).sort().join(`
2
2
  `)}export{createCrossChannelToFn,invokeChannelReceive,toCrossChannelTargets};
@@ -1,7 +1,7 @@
1
1
  import type { ContextAccessor } from "#context/key.js";
2
2
  import type { MessageStreamEvent } from "#protocol/message.js";
3
3
  import type { UserContent } from "ai";
4
- import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, SessionSendCommandResult, TurnCaller } from "#channel/types.js";
4
+ import type { CancelTurnResult, ClearSessionResult, CompactSessionResult, ResetSessionResult, Runtime, SessionAuthContext, SessionCallback, SessionSendCommandResult, TurnPolicy, TurnCaller } from "#channel/types.js";
5
5
  import type { SessionAuth } from "#context/keys.js";
6
6
  import type { InputResponse } from "#runtime/input/types.js";
7
7
  import type { JsonObject } from "#shared/json.js";
@@ -37,7 +37,9 @@ interface SessionDeliveryOptions {
37
37
  readonly outputSchema?: JsonObject;
38
38
  }
39
39
  /** Options for sending a message through a fixed session handle. */
40
- export type SessionSendOptions = SessionDeliveryOptions;
40
+ export type SessionSendOptions = SessionDeliveryOptions & {
41
+ readonly turnPolicy?: TurnPolicy;
42
+ };
41
43
  /** Options for answering pending input requests through a fixed session handle. */
42
44
  export type SessionRespondOptions = SessionDeliveryOptions;
43
45
  /**
@@ -57,10 +59,12 @@ export interface SessionHandle {
57
59
  }
58
60
  export declare function createSession(id: string, runtime: Runtime, metadata?: {
59
61
  readonly requestId?: string;
62
+ readonly turnPolicy?: TurnPolicy;
60
63
  }): Session;
61
64
  /** Builds an I/O-free factory for fixed session-ID handles. */
62
65
  export declare function createAttachSessionFn(runtime: Runtime, metadata?: {
63
66
  readonly requestId?: string;
67
+ readonly turnPolicy?: TurnPolicy;
64
68
  }): (sessionId: string) => Session;
65
69
  /**
66
70
  * Builds a live {@link SessionHandle} backed by the active context
@@ -1 +1 @@
1
- import{serializeUrlFilePartsInMessage}from"#channel/send-input.js";import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(t,n,r={}){return{id:t,async send(i,a){let o=sessionCallbackToTurnCaller(a.callback),s={message:serializeUrlFilePartsInMessage(i)};a.context!==void 0&&(s.context=a.context),a.outputSchema!==void 0&&(s.outputSchema=a.outputSchema);let c={auth:a.auth,kind:`send`,payload:s,requestId:r.requestId};return await n.dispatchSession({command:o===void 0?c:{...c,caller:o},sessionId:t})},async respond(e,i){if(e.length===0)throw Error(`respond() requires at least one input response.`);let a=sessionCallbackToTurnCaller(i.callback),o={inputResponses:e};i.context!==void 0&&(o.context=i.context),i.outputSchema!==void 0&&(o.outputSchema=i.outputSchema);let s={auth:i.auth,kind:`send`,payload:o,requestId:r.requestId};return await n.dispatchSession({command:a===void 0?s:{...s,caller:a},sessionId:t})},async cancel(e){return await n.dispatchSession({command:{kind:`cancel`,turnId:e?.turnId},sessionId:t})},async compact(){return await n.dispatchSession({command:{kind:`compact`},sessionId:t})},async clear(){return await n.dispatchSession({command:{kind:`clear`},sessionId:t})},async reset(e){return await n.dispatchSession({command:{kind:`reset`,reason:e?.reason},sessionId:t})},async getEventStream(e){return n.getEventStream(t,e)},async getStreamTailIndex(){return n.getStreamTailIndex(t)}}}function createAttachSessionFn(e,t={}){return n=>createSession(n,e,t)}function buildSessionHandle(e){return{get id(){return e.get(SessionIdKey)??``},get auth(){return{current:e.get(AuthKey)??null,initiator:e.get(InitiatorAuthKey)??null}},get continuation(){let t=e.get(ContinuationTokenKey);if(!(t===void 0||t.length===0))return{token:toChannelLocalContinuationToken(t),rekey(r){let i=namespaceContinuationToken(t,r);t!==i&&e.set(ContinuationTokenKey,i)}}}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}function sessionCallbackToTurnCaller(e){return e===void 0?void 0:{callId:e.callId,replyTo:{kind:`callback`,url:e.url},subagentName:e.subagentName}}export{buildSessionHandle,createAttachSessionFn,createSession,sessionCallbackToTurnCaller};
1
+ import{serializeUrlFilePartsInMessage}from"#channel/send-input.js";import{DEFAULT_TURN_POLICY}from"#channel/types.js";import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";import{toChannelLocalContinuationToken}from"#shared/continuation-token.js";function createSession(n,r,i={}){return{id:n,async send(a,o){let s=sessionCallbackToTurnCaller(o.callback),c={message:serializeUrlFilePartsInMessage(a)};o.context!==void 0&&(c.context=o.context),o.outputSchema!==void 0&&(c.outputSchema=o.outputSchema);let l={auth:o.auth,kind:`send`,payload:c,requestId:i.requestId,turnPolicy:o.turnPolicy??i.turnPolicy??DEFAULT_TURN_POLICY};return await r.dispatchSession({command:s===void 0?l:{...l,caller:s},sessionId:n})},async respond(e,t){if(e.length===0)throw Error(`respond() requires at least one input response.`);let a=sessionCallbackToTurnCaller(t.callback),o={inputResponses:e};t.context!==void 0&&(o.context=t.context),t.outputSchema!==void 0&&(o.outputSchema=t.outputSchema);let s={auth:t.auth,kind:`send`,payload:o,requestId:i.requestId};return await r.dispatchSession({command:a===void 0?s:{...s,caller:a},sessionId:n})},async cancel(e){return await r.dispatchSession({command:{kind:`cancel`,turnId:e?.turnId},sessionId:n})},async compact(){return await r.dispatchSession({command:{kind:`compact`},sessionId:n})},async clear(){return await r.dispatchSession({command:{kind:`clear`},sessionId:n})},async reset(e){return await r.dispatchSession({command:{kind:`reset`,reason:e?.reason},sessionId:n})},async getEventStream(e){return r.getEventStream(n,e)},async getStreamTailIndex(){return r.getStreamTailIndex(n)}}}function createAttachSessionFn(e,t={}){return n=>createSession(n,e,t)}function buildSessionHandle(e){return{get id(){return e.get(SessionIdKey)??``},get auth(){return{current:e.get(AuthKey)??null,initiator:e.get(InitiatorAuthKey)??null}},get continuation(){let t=e.get(ContinuationTokenKey);if(!(t===void 0||t.length===0))return{token:toChannelLocalContinuationToken(t),rekey(n){let i=namespaceContinuationToken(t,n);t!==i&&e.set(ContinuationTokenKey,i)}}}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}function sessionCallbackToTurnCaller(e){return e===void 0?void 0:{callId:e.callId,replyTo:{kind:`callback`,url:e.url},subagentName:e.subagentName}}export{buildSessionHandle,createAttachSessionFn,createSession,sessionCallbackToTurnCaller};
@@ -125,6 +125,10 @@ export interface DeliverPayload {
125
125
  readonly outputSchema?: JsonObject;
126
126
  readonly [key: string]: unknown;
127
127
  }
128
+ /** Controls how a channel message interacts with an active turn. */
129
+ export type TurnPolicy = "steer" | "queue";
130
+ /** Default policy for message sends produced by current channel surfaces. */
131
+ export declare const DEFAULT_TURN_POLICY: TurnPolicy;
128
132
  /** One command accepted by a durable session inbox. */
129
133
  export type SessionCommand = {
130
134
  readonly auth?: SessionAuthContext | null;
@@ -132,6 +136,7 @@ export type SessionCommand = {
132
136
  readonly kind: "send";
133
137
  readonly payload: DeliverPayload;
134
138
  readonly requestId?: string;
139
+ readonly turnPolicy?: TurnPolicy;
135
140
  } | {
136
141
  readonly kind: "cancel";
137
142
  readonly turnId?: string;
@@ -187,6 +192,7 @@ export interface DeliverHookPayload {
187
192
  readonly requestId?: string;
188
193
  readonly kind: "deliver";
189
194
  readonly payloads: readonly DeliverPayload[];
195
+ readonly turnPolicy?: TurnPolicy;
190
196
  }
191
197
  /** Internal deadline signal sent through the stable session command inbox. */
192
198
  export interface SessionTimeoutHookPayload {
@@ -1 +1 @@
1
- export{};
1
+ const DEFAULT_TURN_POLICY=`steer`;export{DEFAULT_TURN_POLICY};
@@ -92,6 +92,31 @@ const modelEndpoint = z.union([
92
92
  connected: z.literal(false)
93
93
  })
94
94
  ]);
95
+ const agentModelBaseFields = {
96
+ contextWindowTokens: z.number().optional(),
97
+ providerOptions: z.unknown().optional(),
98
+ reasoning: z.enum([
99
+ "provider-default",
100
+ "none",
101
+ "minimal",
102
+ "low",
103
+ "medium",
104
+ "high",
105
+ "xhigh"
106
+ ]).optional().catch(void 0),
107
+ source: source.optional()
108
+ };
109
+ const agentModel = z.union([z.object({
110
+ ...agentModelBaseFields,
111
+ id: z.string(),
112
+ routing: modelRouting,
113
+ endpoint: modelEndpoint.optional()
114
+ }).strict(), z.object({
115
+ ...agentModelBaseFields,
116
+ endpoint: z.never().optional(),
117
+ id: z.never().optional(),
118
+ routing: z.object({ kind: z.literal("dynamic") }).strict()
119
+ }).strict()]);
95
120
  const tool = entry.extend({
96
121
  description: z.string(),
97
122
  hasAuth: z.boolean(),
@@ -188,23 +213,7 @@ const AgentInfoResultSchema = z.object({
188
213
  appRoot: z.string(),
189
214
  configSource: source.optional(),
190
215
  description: z.string().optional(),
191
- model: z.object({
192
- contextWindowTokens: z.number().optional(),
193
- id: z.string(),
194
- providerOptions: z.unknown().optional(),
195
- reasoning: z.enum([
196
- "provider-default",
197
- "none",
198
- "minimal",
199
- "low",
200
- "medium",
201
- "high",
202
- "xhigh"
203
- ]).optional().catch(void 0),
204
- source: source.optional(),
205
- routing: modelRouting.optional(),
206
- endpoint: modelEndpoint.optional()
207
- }),
216
+ model: agentModel,
208
217
  name: z.string(),
209
218
  outputSchema: z.unknown().optional()
210
219
  }),
@@ -1098,6 +1107,7 @@ function createMessageBody(input, requireMessage) {
1098
1107
  const body = {};
1099
1108
  if (input.message !== void 0) body.message = input.message;
1100
1109
  if (input.inputResponses !== void 0 && input.inputResponses.length > 0) body.inputResponses = input.inputResponses;
1110
+ if (!requireMessage && input.message !== void 0 && input.turnPolicy !== void 0) body.turnPolicy = input.turnPolicy;
1101
1111
  if (input.clientContext !== void 0) body.clientContext = input.clientContext;
1102
1112
  const outputSchema = serializeOutputSchema(input.outputSchema);
1103
1113
  if (outputSchema !== void 0) body.outputSchema = outputSchema;
@@ -92,6 +92,31 @@ const modelEndpoint = z.union([
92
92
  connected: z.literal(false)
93
93
  })
94
94
  ]);
95
+ const agentModelBaseFields = {
96
+ contextWindowTokens: z.number().optional(),
97
+ providerOptions: z.unknown().optional(),
98
+ reasoning: z.enum([
99
+ "provider-default",
100
+ "none",
101
+ "minimal",
102
+ "low",
103
+ "medium",
104
+ "high",
105
+ "xhigh"
106
+ ]).optional().catch(void 0),
107
+ source: source.optional()
108
+ };
109
+ const agentModel = z.union([z.object({
110
+ ...agentModelBaseFields,
111
+ id: z.string(),
112
+ routing: modelRouting,
113
+ endpoint: modelEndpoint.optional()
114
+ }).strict(), z.object({
115
+ ...agentModelBaseFields,
116
+ endpoint: z.never().optional(),
117
+ id: z.never().optional(),
118
+ routing: z.object({ kind: z.literal("dynamic") }).strict()
119
+ }).strict()]);
95
120
  const tool = entry.extend({
96
121
  description: z.string(),
97
122
  hasAuth: z.boolean(),
@@ -188,23 +213,7 @@ const AgentInfoResultSchema = z.object({
188
213
  appRoot: z.string(),
189
214
  configSource: source.optional(),
190
215
  description: z.string().optional(),
191
- model: z.object({
192
- contextWindowTokens: z.number().optional(),
193
- id: z.string(),
194
- providerOptions: z.unknown().optional(),
195
- reasoning: z.enum([
196
- "provider-default",
197
- "none",
198
- "minimal",
199
- "low",
200
- "medium",
201
- "high",
202
- "xhigh"
203
- ]).optional().catch(void 0),
204
- source: source.optional(),
205
- routing: modelRouting.optional(),
206
- endpoint: modelEndpoint.optional()
207
- }),
216
+ model: agentModel,
208
217
  name: z.string(),
209
218
  outputSchema: z.unknown().optional()
210
219
  }),
@@ -1098,6 +1107,7 @@ function createMessageBody(input, requireMessage) {
1098
1107
  const body = {};
1099
1108
  if (input.message !== void 0) body.message = input.message;
1100
1109
  if (input.inputResponses !== void 0 && input.inputResponses.length > 0) body.inputResponses = input.inputResponses;
1110
+ if (!requireMessage && input.message !== void 0 && input.turnPolicy !== void 0) body.turnPolicy = input.turnPolicy;
1101
1111
  if (input.clientContext !== void 0) body.clientContext = input.clientContext;
1102
1112
  const outputSchema = serializeOutputSchema(input.outputSchema);
1103
1113
  if (outputSchema !== void 0) body.outputSchema = outputSchema;
@@ -16,3 +16,6 @@ the coding harness's prompt tools when available, and do not guess.
16
16
  under `agent/connections/`. When a system needs every end-user to sign in, wire
17
17
  its auth through **Vercel Connect** (`connect()` from `@vercel/connect/eve`),
18
18
  which handles consent, encrypted token storage, and refresh.
19
+ 4. Does the user want a specific AI Gateway model or reasoning effort? If so,
20
+ pass its `provider/model-id` to `eve init --model` and its reasoning effort to
21
+ `--reasoning`; otherwise, use eve's defaults.
@@ -4,7 +4,7 @@ First settle the target: a new project, or the agent added to an existing
4
4
  directory? For a new project, propose a name and ask the user to confirm it; for
5
5
  an existing one, ask for the directory.
6
6
 
7
- For a new project, run (append `--channel-web-nextjs` only if the user wants Web
7
+ For a new project, run (`--channel-web-nextjs` is only for users who want Web
8
8
  Chat):
9
9
 
10
10
  npx eve@latest init <name>
@@ -18,5 +18,7 @@ If the user wants a reusable extension package instead of an agent, run
18
18
 
19
19
  For an existing app, run `npx eve@latest init .` from its directory. This adds the
20
20
  agent and missing dependencies while leaving the existing Git repository and app
21
- scripts alone. If init cannot be used, install by hand with
21
+ scripts alone. Append `--model provider/model-id` or `--reasoning effort` to
22
+ either init command when the user chose those settings. If init cannot be used,
23
+ install by hand with
22
24
  `npm install eve@latest ai zod`; manual installation does not add package scripts.
@@ -1,2 +1,2 @@
1
- import{createCliTheme,renderCliBanner,renderCliSection}from"#cli/ui/output.js";import{inspectApplication}from"#services/inspect-application.js";function buildApplicationInfoJson(e){let{application:t,compiledState:n,messaging:r}=e;return{appRoot:t.appRoot,agentRoot:n?.project.agentRoot??null,layout:n?.project.layout??null,status:n?.metadata.status??`unavailable`,diagnostics:n?{errors:n.metadata.discovery.summary.errors,warnings:n.metadata.discovery.summary.warnings}:null,model:n?.manifest.config.model.id??null,instructions:n?.manifest.instructions?.logicalPath??null,skills:(n?.manifest.skills??[]).map(e=>e.name),tools:(n?.manifest.tools??[]).map(e=>e.name),subagents:(n?.manifest.subagents??[]).map(e=>e.name),schedules:(n?.manifest.schedules??[]).map(e=>e.name),channels:(n?.manifest.channels??[]).map(e=>e.kind===`channel`?{name:e.name,kind:e.adapterKind??null,method:e.method,urlPath:e.urlPath}:{name:e.name,kind:`disabled`,method:null,urlPath:null}),messaging:{create:r.createSessionRoutePath,messages:r.sessionMessagesRoutePattern,stream:r.streamRoutePattern},artifacts:n?{compiledManifest:n.paths.compiledManifestPath,discoveryManifest:n.paths.discoveryManifestPath,diagnostics:n.paths.diagnosticsPath,moduleMap:n.paths.moduleMapPath,metadata:n.paths.compileMetadataPath}:null}}function pluralize(e,t){return`${e} ${t}${e===1?``:`s`}`}function formatDiscoverySummary(e,t){return`${pluralize(e,`error`)}, ${pluralize(t,`warning`)}`}function resolveCompileTone(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function printApplicationInfo(i,a,o={}){let s=await inspectApplication(a);if(o.json){i.log(JSON.stringify(buildApplicationInfoJson(s),null,2));return}let c=s.compiledState,l=s.application,u=createCliTheme(),d=[{label:`App Root`,value:l.appRoot}],f=[{label:`Workflow Build`,value:l.workflowBuildDir},{label:`Output`,value:l.outputDir}],p=[];c===null?d.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(d.push({label:`Agent Root`,value:c.project.agentRoot},{label:`Layout`,value:c.project.layout},{label:`Compile`,tone:resolveCompileTone(c.metadata.status),value:c.metadata.status},{label:`Diagnostics`,tone:c.metadata.discovery.summary.errors>0?`danger`:c.metadata.discovery.summary.warnings>0?`warning`:`success`,value:formatDiscoverySummary(c.metadata.discovery.summary.errors,c.metadata.discovery.summary.warnings)},{label:`Instructions`,value:c.manifest.instructions?.logicalPath??`none`},{label:`Skills`,value:pluralize(c.manifest.skills.length,`skill`)},{label:`Tools`,value:pluralize(c.manifest.tools.length,`tool`)},{label:`Subagents`,value:pluralize(c.manifest.subagents.length,`subagent`)},{label:`Schedules`,value:pluralize(c.manifest.schedules.length,`schedule`)}),f.unshift({label:`Compiled Manifest`,value:c.paths.compiledManifestPath},{label:`Discovery Manifest`,value:c.paths.discoveryManifestPath},{label:`Diagnostics`,value:c.paths.diagnosticsPath},{label:`Module Map`,value:c.paths.moduleMapPath},{label:`Metadata`,value:c.paths.compileMetadataPath}),p.push(c.manifest.instructions===void 0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:c.manifest.instructions.logicalPath})),i.log([renderCliBanner(u,{subtitle:`Resolved application paths and the active message contract.`,title:`eve Info`}),``,renderCliSection(u,{rows:d,title:`Application`}),``,renderCliSection(u,{rows:f,title:`Artifacts`}),...c===null?[]:[``,renderCliSection(u,{rows:p,title:`Instructions`})],``,renderCliSection(u,{rows:[{label:`Workflow ID`,value:l.workflowId},{label:`Source Dir`,value:l.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${s.messaging.createSessionRoutePath}`},{label:`Messages`,tone:`info`,value:`POST ${s.messaging.sessionMessagesRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${s.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
1
+ import{createCliTheme,renderCliBanner,renderCliSection}from"#cli/ui/output.js";import{inspectApplication}from"#services/inspect-application.js";function buildApplicationInfoJson(e){let{application:t,compiledState:n,messaging:r}=e;return{appRoot:t.appRoot,agentRoot:n?.project.agentRoot??null,layout:n?.project.layout??null,status:n?.metadata.status??`unavailable`,diagnostics:n?{errors:n.metadata.discovery.summary.errors,warnings:n.metadata.discovery.summary.warnings}:null,model:n?.manifest.config.model?.id??null,instructions:n?.manifest.instructions?.logicalPath??null,skills:(n?.manifest.skills??[]).map(e=>e.name),tools:(n?.manifest.tools??[]).map(e=>e.name),subagents:(n?.manifest.subagents??[]).map(e=>e.name),schedules:(n?.manifest.schedules??[]).map(e=>e.name),channels:(n?.manifest.channels??[]).map(e=>e.kind===`channel`?{name:e.name,kind:e.adapterKind??null,method:e.method,urlPath:e.urlPath}:{name:e.name,kind:`disabled`,method:null,urlPath:null}),messaging:{create:r.createSessionRoutePath,messages:r.sessionMessagesRoutePattern,stream:r.streamRoutePattern},artifacts:n?{compiledManifest:n.paths.compiledManifestPath,discoveryManifest:n.paths.discoveryManifestPath,diagnostics:n.paths.diagnosticsPath,moduleMap:n.paths.moduleMapPath,metadata:n.paths.compileMetadataPath}:null}}function pluralize(e,t){return`${e} ${t}${e===1?``:`s`}`}function formatDiscoverySummary(e,t){return`${pluralize(e,`error`)}, ${pluralize(t,`warning`)}`}function resolveCompileTone(e){switch(e){case`ready`:return`success`;case`failed`:return`danger`;default:return`warning`}}async function printApplicationInfo(i,a,o={}){let s=await inspectApplication(a);if(o.json){i.log(JSON.stringify(buildApplicationInfoJson(s),null,2));return}let c=s.compiledState,l=s.application,u=createCliTheme(),d=[{label:`App Root`,value:l.appRoot}],f=[{label:`Workflow Build`,value:l.workflowBuildDir},{label:`Output`,value:l.outputDir}],p=[];c===null?d.push({label:`Compile`,tone:`warning`,value:`unavailable`}):(d.push({label:`Agent Root`,value:c.project.agentRoot},{label:`Layout`,value:c.project.layout},{label:`Compile`,tone:resolveCompileTone(c.metadata.status),value:c.metadata.status},{label:`Diagnostics`,tone:c.metadata.discovery.summary.errors>0?`danger`:c.metadata.discovery.summary.warnings>0?`warning`:`success`,value:formatDiscoverySummary(c.metadata.discovery.summary.errors,c.metadata.discovery.summary.warnings)},{label:`Instructions`,value:c.manifest.instructions?.logicalPath??`none`},{label:`Skills`,value:pluralize(c.manifest.skills.length,`skill`)},{label:`Tools`,value:pluralize(c.manifest.tools.length,`tool`)},{label:`Subagents`,value:pluralize(c.manifest.subagents.length,`subagent`)},{label:`Schedules`,value:pluralize(c.manifest.schedules.length,`schedule`)}),f.unshift({label:`Compiled Manifest`,value:c.paths.compiledManifestPath},{label:`Discovery Manifest`,value:c.paths.discoveryManifestPath},{label:`Diagnostics`,value:c.paths.diagnosticsPath},{label:`Module Map`,value:c.paths.moduleMapPath},{label:`Metadata`,value:c.paths.compileMetadataPath}),p.push(c.manifest.instructions===void 0?{label:`Instructions`,value:`No instructions prompt discovered.`}:{label:`Instructions`,value:c.manifest.instructions.logicalPath})),i.log([renderCliBanner(u,{subtitle:`Resolved application paths and the active message contract.`,title:`eve Info`}),``,renderCliSection(u,{rows:d,title:`Application`}),``,renderCliSection(u,{rows:f,title:`Artifacts`}),...c===null?[]:[``,renderCliSection(u,{rows:p,title:`Instructions`})],``,renderCliSection(u,{rows:[{label:`Workflow ID`,value:l.workflowId},{label:`Source Dir`,value:l.workflowSourceDir},{label:`Create`,tone:`info`,value:`POST ${s.messaging.createSessionRoutePath}`},{label:`Messages`,tone:`info`,value:`POST ${s.messaging.sessionMessagesRoutePattern}`},{label:`Stream`,tone:`info`,value:`GET ${s.messaging.streamRoutePattern}`}],title:`Messaging`})].join(`
2
2
  `))}export{buildApplicationInfoJson,printApplicationInfo};
@@ -33,7 +33,7 @@ type CodingAgentReplDefinition = (typeof CODING_AGENT_REPLS)[number];
33
33
  /** A coding-agent REPL that can take over the terminal after `eve init`. */
34
34
  export type CodingAgentRepl = CodingAgentReplDefinition["command"];
35
35
  /** The one post-init continuation point for a human terminal session. */
36
- export type InitHandoff = "eve-dev" | CodingAgentRepl;
36
+ export type InitHandoff = "exit" | "eve-dev" | CodingAgentRepl;
37
37
  export interface InitReplDependencies {
38
38
  createPrompter(): Prompter;
39
39
  hasInteractiveTerminal(): boolean;
@@ -1 +1 @@
1
- import{hasInteractiveTerminal}from"./preconditions.js";import{access,stat}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,extname,join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{spawn}from"node:child_process";const positional=e=>[e],CODING_AGENT_REPLS=[{command:`claude`,label:`Claude Code`,promptArgs:positional},{command:`codex`,label:`Codex`,promptArgs:positional},{command:`cursor-agent`,label:`Cursor`,promptArgs:positional},{command:`droid`,label:`Droid`,promptArgs:positional},{command:`gemini`,label:`Gemini CLI`,promptArgs:e=>[`-i`,e]},{command:`opencode`,label:`opencode`,promptArgs:e=>[`--prompt`,e]},{command:`pi`,label:`Pi`,promptArgs:positional}],WINDOWS_EXECUTABLE_EXTENSIONS=[`.COM`,`.EXE`,`.BAT`,`.CMD`],defaultDependencies={createPrompter,hasInteractiveTerminal,isCodingAgentReplAvailable};function executableNames(e){if(process.platform!==`win32`)return[e];let t=process.env.PATHEXT?.split(`;`).filter(Boolean);return(t&&t.length>0?t:WINDOWS_EXECUTABLE_EXTENSIONS).map(t=>`${e}${t}`)}async function isExecutable(e){try{return(await stat(e)).isFile()?(await access(e,constants.X_OK),!0):!1}catch{return!1}}async function resolveCodingAgentRepl(e){let t=process.env.PATH;if(t===void 0||t.length===0)return null;for(let n of t.split(delimiter))if(n.length!==0)for(let t of executableNames(e)){let e=join(n,t);if(await isExecutable(e))return e}return null}async function isCodingAgentReplAvailable(e){return await resolveCodingAgentRepl(e)!==null}function handoffOptions(e,t){return[{value:`eve-dev`,label:`Start eve dev`,focusHint:`talk to '${t}' in your terminal`},...e.map(e=>({value:e.command,label:`Open ${e.label}`,focusHint:`build '${t}' using ${e.label}`}))]}async function selectInitHandoff(e){let t={...defaultDependencies,...e.deps};if(!t.hasInteractiveTerminal())return`eve-dev`;let n=await Promise.all(CODING_AGENT_REPLS.map(({command:e})=>t.isCodingAgentReplAvailable(e))),r=CODING_AGENT_REPLS.filter((e,t)=>n[t]);return r.length===0?`eve-dev`:t.createPrompter().select({message:`How would you like to continue?`,options:handoffOptions(r,e.agentName),initialValue:`eve-dev`})}function codingAgentRepl(e){let t=CODING_AGENT_REPLS.find(t=>t.command===e);if(t===void 0)throw Error(`Unsupported coding-agent REPL "${e}".`);return t}function isDirectlySpawnable(e,t){if(t!==`win32`)return!0;let n=extname(e).toLowerCase();return n===`.exe`||n===`.com`}function replSpawnPlan(e,t,n,r=process.platform){return t!==null&&isDirectlySpawnable(t,r)?{file:t,args:codingAgentRepl(e).promptArgs(n),shell:!1,seeded:!0}:{file:e,args:[],shell:r===`win32`,seeded:!1}}async function spawnCodingAgentRepl(e){let t=e.resolvePath??resolveCodingAgentRepl,n=replSpawnPlan(e.command,await t(e.command),e.prompt);return n.seeded||e.onPromptUnseeded?.(e.prompt),new Promise(t=>{let r=spawn(n.file,n.args,{cwd:e.cwd,shell:n.shell,stdio:`inherit`}),i=!1,settle=e=>{i||(i=!0,t(e))};r.once(`error`,()=>settle(!1)),r.once(`close`,e=>settle(e===0))})}export{isCodingAgentReplAvailable,replSpawnPlan,resolveCodingAgentRepl,selectInitHandoff,spawnCodingAgentRepl};
1
+ import{hasInteractiveTerminal}from"./preconditions.js";import{access,stat}from"node:fs/promises";import{constants}from"node:fs";import{delimiter,extname,join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{spawn}from"node:child_process";const positional=e=>[e],CODING_AGENT_REPLS=[{command:`claude`,label:`Claude Code`,promptArgs:positional},{command:`codex`,label:`Codex`,promptArgs:positional},{command:`cursor-agent`,label:`Cursor`,promptArgs:positional},{command:`droid`,label:`Droid`,promptArgs:positional},{command:`gemini`,label:`Gemini CLI`,promptArgs:e=>[`-i`,e]},{command:`opencode`,label:`opencode`,promptArgs:e=>[`--prompt`,e]},{command:`pi`,label:`Pi`,promptArgs:positional}],WINDOWS_EXECUTABLE_EXTENSIONS=[`.COM`,`.EXE`,`.BAT`,`.CMD`],defaultDependencies={createPrompter,hasInteractiveTerminal,isCodingAgentReplAvailable};function executableNames(e){if(process.platform!==`win32`)return[e];let t=process.env.PATHEXT?.split(`;`).filter(Boolean);return(t&&t.length>0?t:WINDOWS_EXECUTABLE_EXTENSIONS).map(t=>`${e}${t}`)}async function isExecutable(e){try{return(await stat(e)).isFile()?(await access(e,constants.X_OK),!0):!1}catch{return!1}}async function resolveCodingAgentRepl(e){let t=process.env.PATH;if(t===void 0||t.length===0)return null;for(let n of t.split(delimiter))if(n.length!==0)for(let t of executableNames(e)){let e=join(n,t);if(await isExecutable(e))return e}return null}async function isCodingAgentReplAvailable(e){return await resolveCodingAgentRepl(e)!==null}function handoffOptions(e,t){return[{value:`eve-dev`,label:`Start eve dev`,focusHint:`talk to '${t}' in your terminal`},...e.map(e=>({value:e.command,label:`Open ${e.label}`,focusHint:`build '${t}' using ${e.label}`})),{value:`exit`,label:`Exit`,focusHint:`return to your terminal`}]}async function selectInitHandoff(e){let t={...defaultDependencies,...e.deps};if(!t.hasInteractiveTerminal())return`eve-dev`;let n=await Promise.all(CODING_AGENT_REPLS.map(({command:e})=>t.isCodingAgentReplAvailable(e))),r=CODING_AGENT_REPLS.filter((e,t)=>n[t]);return r.length===0?`eve-dev`:t.createPrompter().select({message:`How would you like to continue?`,options:handoffOptions(r,e.agentName),initialValue:`eve-dev`})}function codingAgentRepl(e){let t=CODING_AGENT_REPLS.find(t=>t.command===e);if(t===void 0)throw Error(`Unsupported coding-agent REPL "${e}".`);return t}function isDirectlySpawnable(e,t){if(t!==`win32`)return!0;let n=extname(e).toLowerCase();return n===`.exe`||n===`.com`}function replSpawnPlan(e,t,n,r=process.platform){return t!==null&&isDirectlySpawnable(t,r)?{file:t,args:codingAgentRepl(e).promptArgs(n),shell:!1,seeded:!0}:{file:e,args:[],shell:r===`win32`,seeded:!1}}async function spawnCodingAgentRepl(e){let t=e.resolvePath??resolveCodingAgentRepl,n=replSpawnPlan(e.command,await t(e.command),e.prompt);return n.seeded||e.onPromptUnseeded?.(e.prompt),new Promise(t=>{let r=spawn(n.file,n.args,{cwd:e.cwd,shell:n.shell,stdio:`inherit`}),i=!1,settle=e=>{i||(i=!0,t(e))};r.once(`error`,()=>settle(!1)),r.once(`close`,e=>settle(e===0))})}export{isCodingAgentReplAvailable,replSpawnPlan,resolveCodingAgentRepl,selectInitHandoff,spawnCodingAgentRepl};
@@ -1,8 +1,10 @@
1
1
  import { isCodingAgentLaunch } from "#cli/agent-detection.js";
2
+ import type { AgentReasoningDefinition } from "#shared/agent-definition.js";
2
3
  import { detectInvokingPackageManager, detectPackageManager } from "#setup/package-manager.js";
3
4
  import { runPackageManagerInstall, spawnPackageManager } from "#setup/primitives/index.js";
4
5
  import { addAgentToProject } from "#setup/scaffold/create/add-to-project.js";
5
6
  import { ensureChannel, scaffoldBaseProject } from "#setup/scaffold/index.js";
7
+ import { validateModelSlug } from "#setup/flows/model-source-change.js";
6
8
  import { tryInitializeGit } from "./init-git.js";
7
9
  import { selectInitHandoff, spawnCodingAgentRepl } from "./init-repl.js";
8
10
  export interface InitCliLogger {
@@ -12,6 +14,10 @@ export interface InitCliLogger {
12
14
  export interface InitCommandOptions {
13
15
  /** Add the Web Chat channel (a Next.js app). Set by `--channel-web-nextjs`. */
14
16
  channelWebNextjs?: boolean;
17
+ /** Model id written to the root agent config. Set by `--model`. */
18
+ model?: string;
19
+ /** Reasoning effort written to the root agent config. Set by `--reasoning`. */
20
+ reasoning?: AgentReasoningDefinition;
15
21
  }
16
22
  export interface InitCommandDependencies {
17
23
  addAgentToProject: typeof addAgentToProject;
@@ -26,6 +32,7 @@ export interface InitCommandDependencies {
26
32
  spawnCodingAgentRepl: typeof spawnCodingAgentRepl;
27
33
  spawnPackageManager: typeof spawnPackageManager;
28
34
  tryInitializeGit: typeof tryInitializeGit;
35
+ validateModelSlug: typeof validateModelSlug;
29
36
  }
30
37
  export declare const EVE_INIT_PACKAGE_SPEC_ENV = "EVE_INIT_PACKAGE_SPEC";
31
38
  /**
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=blockingCreateInPlaceEntries(await readdir(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve add channel/web` from the project afterwards instead.");let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:DEFAULT_AGENT_MODEL_ID,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,l=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(l);else if(await pathExists(l))throw Error(`Cannot create project because "${l}" already exists.`);let f=await mkdtemp(join(o,`.eve-init-`)),p=[];try{let e={projectName:s?basename(l):t,model:DEFAULT_AGENT_MODEL_ID,evePackage:a,targetDirectory:f,workspaceProbeDirectory:l,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:l,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,l):await rename(o,l),{projectPath:l,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(f,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),d=resolveInitEvePackageOverride(),f=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(f);let p=t.now(),m;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,d);m={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,d);m=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let h=t.now()-p;initLog.debug(`${f} done`,{ms:h}),s.update(`Installing dependencies`,`${m.packageManager} install`),initLog.debug(`installing dependencies with ${m.packageManager}`);let g=t.now(),_=[],v=[],y=await t.runPackageManagerInstall(m.packageManager,m.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(v.push(e.text),v.length>20&&v.shift(),NPM_NOISE_LINE.test(e.text)||_.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(m.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),b=t.now()-g;if(!y){initLog.debug(`dependency installation failed`,{ms:b}),s.stop();let e=_.length>0?_:v;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${m.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:b}),m.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...m,agentElapsedMs:h,agentLaunched:e,gitResult:await t.tryInitializeGit(m.projectPath),installElapsedMs:b}):{...m,agentElapsedMs:h,agentLaunched:e,installElapsedMs:b}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),u=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(u);return}let d;try{d=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(d!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${d}`)),!await s.spawnCodingAgentRepl({command:d,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${d} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let f=c.kind===`created`,p=f?[...eveDevArguments(c.packageManager),`--input`,`/model`]:eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(f?`$ eve dev --input /model`:`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,p))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt}from"./agent-instructions.js";import{tryInitializeGit}from"./init-git.js";import{selectInitHandoff,spawnCodingAgentRepl}from"./init-repl.js";import{mkdtemp,readdir,rename,rm,stat}from"node:fs/promises";import{createLogger,isLogLevelEnabled}from"#internal/logging.js";import{basename,join,resolve}from"node:path";import{ensureChannel,scaffoldBaseProject}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{isCodingAgentLaunch}from"#cli/agent-detection.js";import{EVE_WORDMARK}from"#cli/banner.js";import{formatElapsed}from"#cli/format-elapsed.js";import{startCliLiveRow}from"#cli/ui/live-row.js";import{formatNodeEngineOverrideWarning}from"#setup/node-engine.js";import{detectInvokingPackageManager,detectPackageManager}from"#setup/package-manager.js";import{pathExists}from"#setup/path-exists.js";import{parseProjectName}from"#setup/project-name.js";import{eveDevArguments,runPackageManagerInstall,spawnPackageManager}from"#setup/primitives/index.js";import{blockingCreateInPlaceEntries}from"#setup/scaffold/create-in-place.js";import{DEFAULT_EVE_PACKAGE_CONTRACT}from"#setup/scaffold/create/project.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{addAgentToProject}from"#setup/scaffold/create/add-to-project.js";import{WizardCancelledError}from"#setup/step.js";import{validateModelSlug}from"#setup/flows/model-source-change.js";var import_picocolors=__toESM(require_picocolors(),1);const defaultDependencies={addAgentToProject,detectInvokingPackageManager,detectPackageManager,ensureChannel,isCodingAgentLaunch,now:()=>performance.now(),runPackageManagerInstall,scaffoldBaseProject,selectInitHandoff,spawnCodingAgentRepl,spawnPackageManager,tryInitializeGit,validateModelSlug},EVE_INIT_PACKAGE_SPEC_ENV=`EVE_INIT_PACKAGE_SPEC`,initLog=createLogger(`init`);async function resolveTargetDirectory(e,t){let n=resolve(e,t);return(await stat(n).catch(()=>void 0))?.isDirectory()?n:void 0}function isCurrentDirectoryTarget(e){return/^\.(?:[/\\]+\.?)*$/u.test(e.trim())}async function assertCanScaffoldInPlace(e){let t=blockingCreateInPlaceEntries(await readdir(e));if(t.length===0)return;let n=t.slice(0,5).join(`, `),r=t.length>5?`, and ${t.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${n}${r}. Use an empty directory.`)}async function moveDirectoryContents(e,t){for(let n of await readdir(e))await rename(join(e,n),join(t,n))}function uniqueWorkspaceRootMutations(e){let t=new Map;for(let n of e){let e=`${n.kind}:${n.path}`,r=t.get(e);t.set(e,{...n,nodeEngineOverride:n.nodeEngineOverride??r?.nodeEngineOverride})}return[...t.values()]}function formatWorkspaceRootMutationWarning(e){let t=e.kind===`package-json`?`package.json`:`configuration`,n=e.nodeEngineOverride===void 0?``:` (${formatNodeEngineOverrideWarning(e.nodeEngineOverride)})`;return`Updated workspace root ${t} at ${e.path}${n}`}async function addToExistingProject(e,t,n,r){if(t.channelWebNextjs===!0)throw Error("`--channel-web-nextjs` is not supported when adding an agent to an existing project. Run `eve add channel/web` from the project afterwards instead.");if(t.model!==void 0){let r=await n.validateModelSlug(e,t.model);if(r!==null)throw Error(r)}let i=await n.detectPackageManager(e),a=await n.addAgentToProject({projectRoot:e,model:t.model??DEFAULT_AGENT_MODEL_ID,reasoning:t.reasoning,packageManager:i.kind,evePackage:r});return{packageManager:i.kind,nodeEngineOverride:a.nodeEngineOverride}}async function resolveScaffoldPackageManager(e,t){let n=await t.detectPackageManager(e);return n.source==="default"?t.detectInvokingPackageManager()??`pnpm`:n.kind}async function scaffoldProject(e,t,n,r,i,a){let o=resolve(e),s=t===`.`,l=s?o:join(o,t);if(s)await assertCanScaffoldInPlace(l);else if(await pathExists(l))throw Error(`Cannot create project because "${l}" already exists.`);let f=await mkdtemp(join(o,`.eve-init-`)),p=[];try{if(r.model!==void 0){let e=await i.validateModelSlug(f,r.model);if(e!==null)throw Error(e)}let e={projectName:s?basename(l):t,model:r.model??DEFAULT_AGENT_MODEL_ID,reasoning:r.reasoning,evePackage:a,targetDirectory:f,workspaceProbeDirectory:l,packageManager:n,onWorkspaceRootMutation:e=>{p.push(e)}},o=await i.scaffoldBaseProject(e);return r.channelWebNextjs===!0&&await i.ensureChannel({projectRoot:o,kind:`web`,packageManager:n,workspaceProbeDirectory:l,configureVercelServices:!1,onWorkspaceRootMutation:e=>{p.push(e)}}),s?await moveDirectoryContents(o,l):await rename(o,l),{projectPath:l,workspaceRootMutations:uniqueWorkspaceRootMutations(p)}}finally{await rm(f,{recursive:!0,force:!0})}}function installProgressDetail(e,t){let n=t.text.trim();if(n===``||e!==`npm`)return n||void 0;let r=/^npm silly fetch manifest (.+)$/u.exec(n);if(r!==null)return`Resolving ${r[1]}`;let i=/^npm http fetch \S+ \S+ attempt (\d+) failed with (\S+)$/u.exec(n);if(i!==null)return`npm registry · attempt ${i[1]} failed: ${i[2]}`;if(t.stream===`stdout`||/^npm (?:error|warn)\b/u.test(n))return n}const NPM_NOISE_LINE=/^\s*npm (?:silly|verbose|http|timing)\b/u;async function runInitSteps(e){let{dependencies:t,logger:n,options:r,parentDirectory:i,target:a}=e,o=isLogLevelEnabled(`debug`),s=startCliLiveRow(n);s.update(`Preparing project`);try{let e=await t.isCodingAgentLaunch(),c=a??`.`,l=isCurrentDirectoryTarget(c),u=l?await pathExists(join(resolve(i),`package.json`))?resolve(i):void 0:await resolveTargetDirectory(i,c),d=resolveInitEvePackageOverride(),f=u===void 0?`creating agent`:`adding agent`;s.update(u===void 0?`Creating agent`:`Adding agent`),initLog.debug(f);let p=t.now(),m;if(u===void 0){let e=l?`.`:parseProjectName(c),n=resolve(i),a=await resolveScaffoldPackageManager(e===`.`?n:join(n,e),t),o=await scaffoldProject(i,e,a,r,t,d);m={kind:`created`,packageManager:a,projectPath:o.projectPath,workspaceRootMutations:o.workspaceRootMutations}}else{let e=await addToExistingProject(u,r,t,d);m=e.nodeEngineOverride===void 0?{kind:`added`,packageManager:e.packageManager,projectPath:u}:{kind:`added`,nodeEngineOverride:e.nodeEngineOverride,packageManager:e.packageManager,projectPath:u}}let h=t.now()-p;initLog.debug(`${f} done`,{ms:h}),s.update(`Installing dependencies`,`${m.packageManager} install`),initLog.debug(`installing dependencies with ${m.packageManager}`);let g=t.now(),_=[],v=[],y=await t.runPackageManagerInstall(m.packageManager,m.projectPath,{bypassMinimumReleaseAge:!0,progressDetails:process.stdout.isTTY===!0&&!o,onOutput:e=>{e.text.trim()!==``&&(v.push(e.text),v.length>20&&v.shift(),NPM_NOISE_LINE.test(e.text)||_.push(e.text)),o&&initLog.debug(e.text);let t=installProgressDetail(m.packageManager,e);t!==void 0&&s.update(`Installing dependencies`,t)}}),b=t.now()-g;if(!y){initLog.debug(`dependency installation failed`,{ms:b}),s.stop();let e=_.length>0?_:v;for(let t of e)n.error(t);throw Error(`Failed to install dependencies in "${m.projectPath}".`)}return initLog.debug(`dependencies installed`,{ms:b}),m.kind===`created`?(s.update(`Initializing Git repository`),initLog.debug(`initializing git repository`),{...m,agentElapsedMs:h,agentLaunched:e,gitResult:await t.tryInitializeGit(m.projectPath),installElapsedMs:b}):{...m,agentElapsedMs:h,agentLaunched:e,installElapsedMs:b}}finally{s.stop()}}async function runInitCommand(e,t,a,o,s=defaultDependencies){if(a===void 0&&await s.isCodingAgentLaunch()){e.log(initAgentInstructions());return}let c=await runInitSteps({dependencies:s,logger:e,options:o,parentDirectory:t,target:a});if(c.kind===`created`){e.log(`${import_picocolors.default.green(`✓`)} Created an ${EVE_WORDMARK} agent in ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`);for(let t of c.workspaceRootMutations)e.log(import_picocolors.default.yellow(`⚠ ${formatWorkspaceRootMutationWarning(t)}`))}else e.log(`${import_picocolors.default.green(`✓`)} Added an ${EVE_WORDMARK} agent to ${import_picocolors.default.bold(c.projectPath)} ${import_picocolors.default.dim(`in ${formatElapsed(c.agentElapsedMs)}`)}`),c.nodeEngineOverride!==void 0&&e.log(import_picocolors.default.yellow(`⚠ ${formatNodeEngineOverrideWarning(c.nodeEngineOverride)}`));e.log(`${import_picocolors.default.green(`✓`)} Installed dependencies ${import_picocolors.default.dim(`in ${formatElapsed(c.installElapsedMs)}`)}`),c.kind===`created`&&c.gitResult.kind===`failed`&&e.error(import_picocolors.default.yellow(`Git initialization failed: ${c.gitResult.reason}`));let l=[c.packageManager,...eveDevArguments(c.packageManager)].join(` `),u=initAgentDevHandoff({projectPath:c.projectPath,devCommand:l});if(c.agentLaunched){e.log(u);return}let d;try{d=await s.selectInitHandoff({agentName:basename(c.projectPath)})}catch(e){if(e instanceof WizardCancelledError)return;throw e}if(d===`exit`)return;if(d!==`eve-dev`){if(e.log(import_picocolors.default.dim(`$ ${d}`)),!await s.spawnCodingAgentRepl({command:d,cwd:c.projectPath,prompt:initAgentReplPrompt({devCommand:l}),onPromptUnseeded:t=>{e.log(import_picocolors.default.yellow(`Could not seed ${d} automatically. Paste this prompt into it:`)),e.log(t)}}))throw Error(`Coding-agent REPL exited unsuccessfully in "${c.projectPath}".`);return}let f=c.kind===`created`,p=f?[...eveDevArguments(c.packageManager),`--input`,`/model`]:eveDevArguments(c.packageManager);if(e.log(import_picocolors.default.dim(f?`$ eve dev --input /model`:`$ eve dev`)),!await s.spawnPackageManager(c.packageManager,c.projectPath,p))throw Error(`Development server exited unsuccessfully in "${c.projectPath}".`)}function resolveInitEvePackageOverride(){let e=process.env[EVE_INIT_PACKAGE_SPEC_ENV]?.trim();if(!(e===void 0||e.length===0))return{nodeEngine:DEFAULT_EVE_PACKAGE_CONTRACT.nodeEngine,version:e}}export{EVE_INIT_PACKAGE_SPEC_ENV,runInitCommand};
@@ -1,5 +1,5 @@
1
1
  import { cleanupCreatedConnectionConnector, setupConnectionConnector } from "#setup/connection-connector.js";
2
- import { runLinkFlow, type LinkFlowDeps } from "#setup/flows/link.js";
2
+ import { ensureVercelProject, type EnsureVercelProjectDeps } from "#setup/flows/ensure-vercel-project.js";
3
3
  import { readProjectLink } from "#setup/project-resolution.js";
4
4
  import { type Prompter } from "#setup/prompter.js";
5
5
  import { updateConnectionConnectorUid } from "#setup/scaffold/update/update-connection-connector.js";
@@ -10,9 +10,9 @@ export interface IntegrationConnectOptions {
10
10
  }
11
11
  export interface IntegrationConnectDependencies {
12
12
  createPrompter?: () => Prompter;
13
+ ensureVercelProject: typeof ensureVercelProject;
14
+ ensureVercelProjectDeps?: Partial<EnsureVercelProjectDeps>;
13
15
  readProjectLink: typeof readProjectLink;
14
- runLinkFlow: typeof runLinkFlow;
15
- linkFlowDeps?: Partial<LinkFlowDeps>;
16
16
  setupConnectionConnector: typeof setupConnectionConnector;
17
17
  cleanupCreatedConnectionConnector: typeof cleanupCreatedConnectionConnector;
18
18
  updateConnectionConnectorUid: typeof updateConnectionConnectorUid;
@@ -1 +1 @@
1
- import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{join}from"node:path";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{cleanupCreatedConnectionConnector,setupConnectionConnector}from"#setup/connection-connector.js";import{runLinkFlow}from"#setup/flows/link.js";import{createHeadlessPrompter}from"#setup/headless.js";import{SetupPrerequisiteRequired}from"#setup/integrations/shared/prerequisite.js";import{resolveIntegrationVercelProject}from"#setup/integrations/shared/vercel-project.js";import{readProjectLink}from"#setup/project-resolution.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{updateConnectionConnectorUid}from"#setup/scaffold/update/update-connection-connector.js";const defaultDependencies={readProjectLink,runLinkFlow,setupConnectionConnector,cleanupCreatedConnectionConnector,updateConnectionConnectorUid};async function runIntegrationConnect(e){let t={...defaultDependencies,...e.dependencies},r=e.options?.nonInteractive===!0,i=t.createPrompter?.()??(r?createHeadlessPrompter(()=>{}):createPrompter()),a=e.options?.signal;i.intro(`Set up ${e.slug}`);let o=await t.readProjectLink(e.appRoot);if(o===void 0)if(r)o=await resolveIntegrationVercelProject({appRoot:e.appRoot,integration:e.slug,signal:a,deps:{readProjectLink:t.readProjectLink}});else{if((await t.runLinkFlow({appRoot:e.appRoot,prompter:i,signal:a,projectSelection:`create-or-link`,teamSelectMessage:()=>`You need to link to a project to use ${e.slug} through Vercel Connect.\n\nSelect your team`,deps:t.linkFlowDeps})).kind===`cancelled`)return;if(o=await t.readProjectLink(e.appRoot),o===void 0)throw Error(`Project link was not found after linking.`)}let s={log:i.log,prompter:i,projectRoot:e.appRoot,slug:e.slug,service:e.service,canonicalConnectorName:e.canonicalConnectorName??e.slug,project:o,signal:a},l=await t.setupConnectionConnector(s),u=join(e.appRoot,`agent`,`connections`,`${e.slug}.ts`);if(!(await t.updateConnectionConnectorUid(u,l.connectorUid)).patched)throw l.kind===`created`&&await t.cleanupCreatedConnectionConnector({log:i.log,projectRoot:e.appRoot,connectorId:l.connectorId,orgId:o.orgId}),Error(`Could not update the connector in agent/connections/${e.slug}.ts.`);i.outro(`Connection ${e.slug} set up.`)}async function runIntegrationConnectCommand(n,i,a,o,c,l={},d=defaultDependencies){if(!await isEveProject(i)){n.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let f=createRegistrySetupClient({signal:l.signal});try{await runIntegrationConnect({appRoot:i,slug:a,service:o,canonicalConnectorName:c,options:l,dependencies:{...d,createPrompter:()=>f?.prompter??(l.nonInteractive?createHeadlessPrompter(()=>{}):d.createPrompter?.()??createPrompter())}}),f?.complete()}catch(e){if(f?.fail(e),f!==void 0)return;if(l.nonInteractive&&e instanceof SetupPrerequisiteRequired){n.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:e.prerequisite})),process.exitCode=2;return}n.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runIntegrationConnect,runIntegrationConnectCommand};
1
+ import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{join}from"node:path";import{isEveProject}from"#setup/scaffold/index.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{cleanupCreatedConnectionConnector,setupConnectionConnector}from"#setup/connection-connector.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{createHeadlessPrompter}from"#setup/headless.js";import{SetupPrerequisiteRequired}from"#setup/integrations/shared/prerequisite.js";import{resolveIntegrationVercelProject}from"#setup/integrations/shared/vercel-project.js";import{readProjectLink}from"#setup/project-resolution.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{updateConnectionConnectorUid}from"#setup/scaffold/update/update-connection-connector.js";const defaultDependencies={ensureVercelProject,readProjectLink,setupConnectionConnector,cleanupCreatedConnectionConnector,updateConnectionConnectorUid};async function runIntegrationConnect(e){let t={...defaultDependencies,...e.dependencies},r=e.options?.nonInteractive===!0,a=t.createPrompter?.()??(r?createHeadlessPrompter(()=>{}):createPrompter()),o=e.options?.signal;a.intro(`Set up ${e.slug}`);let s=await t.readProjectLink(e.appRoot);if(s===void 0)if(r)s=await resolveIntegrationVercelProject({appRoot:e.appRoot,integration:e.slug,signal:o,deps:{readProjectLink:t.readProjectLink}});else try{s=await t.ensureVercelProject({appRoot:e.appRoot,prompter:a,signal:o,teamSelectMessage:()=>`You need to link to a project to use ${e.slug} through Vercel Connect.\n\nSelect your team`,deps:t.ensureVercelProjectDeps})}catch(e){if(e instanceof WizardCancelledError)return;throw e}let c={log:a.log,prompter:a,projectRoot:e.appRoot,slug:e.slug,service:e.service,canonicalConnectorName:e.canonicalConnectorName??e.slug,project:s,signal:o},u=await t.setupConnectionConnector(c),d=join(e.appRoot,`agent`,`connections`,`${e.slug}.ts`);if(!(await t.updateConnectionConnectorUid(d,u.connectorUid)).patched)throw u.kind===`created`&&await t.cleanupCreatedConnectionConnector({log:a.log,projectRoot:e.appRoot,connectorId:u.connectorId,orgId:s.orgId}),Error(`Could not update the connector in agent/connections/${e.slug}.ts.`);a.outro(`Connection ${e.slug} set up.`)}async function runIntegrationConnectCommand(n,i,a,o,s,l={},u=defaultDependencies){if(!await isEveProject(i)){n.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let f=createRegistrySetupClient({signal:l.signal});try{await runIntegrationConnect({appRoot:i,slug:a,service:o,canonicalConnectorName:s,options:l,dependencies:{...u,createPrompter:()=>f?.prompter??(l.nonInteractive?createHeadlessPrompter(()=>{}):u.createPrompter?.()??createPrompter())}}),f?.complete()}catch(e){if(f?.fail(e),f!==void 0)return;if(l.nonInteractive&&e instanceof SetupPrerequisiteRequired){n.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:e.prerequisite})),process.exitCode=2;return}n.error(e instanceof Error?e.message:String(e)),process.exitCode=1}}export{runIntegrationConnect,runIntegrationConnectCommand};