eve 0.31.2 → 0.32.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 (221) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/src/chunks/{use-eve-agent-CF5D6jSV.js → use-eve-agent-CX87G1vU.js} +30 -5
  3. package/dist/src/chunks/{use-eve-agent-DbYZLG0h.js → use-eve-agent-DwyRde1N.js} +30 -5
  4. package/dist/src/cli/commands/integration-connect.d.ts +1 -0
  5. package/dist/src/cli/commands/integration-connect.js +1 -1
  6. package/dist/src/cli/commands/integration-setup.d.ts +4 -0
  7. package/dist/src/cli/commands/integration-setup.js +1 -1
  8. package/dist/src/cli/commands/register-integration-commands.js +1 -1
  9. package/dist/src/cli/commands/register-registry-commands.js +1 -1
  10. package/dist/src/cli/commands/registry-declared-setups.d.ts +23 -0
  11. package/dist/src/cli/commands/registry-declared-setups.js +1 -0
  12. package/dist/src/cli/commands/registry-metadata.d.ts +69 -0
  13. package/dist/src/cli/commands/registry-metadata.js +1 -1
  14. package/dist/src/cli/commands/registry-package.d.ts +3 -3
  15. package/dist/src/cli/commands/registry-package.js +1 -1
  16. package/dist/src/cli/commands/registry-presentation.d.ts +20 -0
  17. package/dist/src/cli/commands/registry-presentation.js +7 -0
  18. package/dist/src/cli/commands/registry-search-presentation.d.ts +16 -0
  19. package/dist/src/cli/commands/registry-search-presentation.js +6 -0
  20. package/dist/src/cli/commands/registry-setup-command.d.ts +5 -2
  21. package/dist/src/cli/commands/registry-setup-command.js +1 -2
  22. package/dist/src/cli/commands/registry.d.ts +16 -7
  23. package/dist/src/cli/commands/registry.js +1 -6
  24. package/dist/src/cli/commands/setup-answers.d.ts +2 -0
  25. package/dist/src/cli/commands/setup-answers.js +1 -0
  26. package/dist/src/cli/commands/setup-headless.d.ts +79 -0
  27. package/dist/src/cli/commands/setup-headless.js +1 -0
  28. package/dist/src/cli/dev/tui/runner.js +1 -1
  29. package/dist/src/cli/dev/tui/setup-commands.js +3 -3
  30. package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
  31. package/dist/src/cli/dev/tui/terminal-renderer.js +12 -12
  32. package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +1 -1
  33. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  34. package/dist/src/client/url.d.ts +5 -0
  35. package/dist/src/client/url.js +1 -1
  36. package/dist/src/compiled/.vendor-stamp.json +8 -8
  37. package/dist/src/compiled/@ai-sdk/anthropic/index.d.ts +33 -13
  38. package/dist/src/compiled/@ai-sdk/anthropic/index.js +4 -2
  39. package/dist/src/compiled/@ai-sdk/google/index.d.ts +50 -3
  40. package/dist/src/compiled/@ai-sdk/google/index.js +7 -7
  41. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +33 -3
  42. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  43. package/dist/src/compiled/@ai-sdk/openai/index.d.ts +140 -9
  44. package/dist/src/compiled/@ai-sdk/openai/index.js +9 -6
  45. package/dist/src/compiled/@ai-sdk/otel/index.js +1 -1
  46. package/dist/src/compiled/@ai-sdk/provider/index.d.ts +300 -6
  47. package/dist/src/compiled/@ai-sdk/provider-utils/index.d.ts +70 -20
  48. package/dist/src/compiled/@opentelemetry/api/index.d.ts +2 -1
  49. package/dist/src/compiled/@photon-ai/chat-adapter-imessage/index.js +1 -1
  50. package/dist/src/compiled/@vercel/otel/index.d.ts +6 -0
  51. package/dist/src/compiled/@vercel/sandbox/index.js +1 -1
  52. package/dist/src/compiled/_chunks/node/undici-CUIybhQ2.js +95 -0
  53. package/dist/src/compiled/_chunks/workflow/dist-eUxFublw.js +77 -0
  54. package/dist/src/compiled/shadcn-registry/index.js +309 -215
  55. package/dist/src/compiler/extension-compatibility.d.ts +10 -10
  56. package/dist/src/compiler/extension-compatibility.js +1 -1
  57. package/dist/src/context/build-callback-context.js +1 -1
  58. package/dist/src/execution/authorization-callback-match.d.ts +14 -0
  59. package/dist/src/execution/authorization-callback-match.js +1 -0
  60. package/dist/src/execution/next-driver-action.d.ts +1 -0
  61. package/dist/src/execution/parked-delivery-wait.d.ts +16 -1
  62. package/dist/src/execution/parked-delivery-wait.js +1 -1
  63. package/dist/src/execution/sandbox/abort-bound-session.d.ts +1 -1
  64. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  65. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  66. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  67. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +1 -0
  68. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  69. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  70. package/dist/src/execution/sandbox/ensure.js +1 -1
  71. package/dist/src/execution/session-command-inbox.d.ts +26 -1
  72. package/dist/src/execution/session-command-inbox.js +1 -1
  73. package/dist/src/execution/turn-execution-cursor.d.ts +1 -0
  74. package/dist/src/execution/turn-workflow.js +1 -1
  75. package/dist/src/execution/workflow-entry.js +1 -1
  76. package/dist/src/execution/workflow-steps.d.ts +3 -4
  77. package/dist/src/execution/workflow-steps.js +1 -1
  78. package/dist/src/harness/authorization.d.ts +24 -11
  79. package/dist/src/harness/authorization.js +1 -1
  80. package/dist/src/harness/input-extraction.js +1 -1
  81. package/dist/src/harness/input-requests.js +1 -1
  82. package/dist/src/harness/provider-tools.d.ts +1 -1
  83. package/dist/src/harness/provider-tools.js +1 -1
  84. package/dist/src/harness/tool-loop.js +2 -2
  85. package/dist/src/internal/application/package.js +1 -1
  86. package/dist/src/internal/authored-definition/connection.js +1 -1
  87. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  88. package/dist/src/protocol/routes.d.ts +8 -6
  89. package/dist/src/protocol/routes.js +1 -1
  90. package/dist/src/public/channels/linear/linearChannel.d.ts +2 -0
  91. package/dist/src/public/channels/linear/linearChannel.js +1 -1
  92. package/dist/src/public/channels/linear/verify.js +1 -1
  93. package/dist/src/public/channels/slack/attachments.js +1 -1
  94. package/dist/src/public/channels/slack/defaults.js +1 -1
  95. package/dist/src/public/channels/slack/hitl.d.ts +14 -1
  96. package/dist/src/public/channels/slack/hitl.js +2 -2
  97. package/dist/src/public/connections/index.d.ts +1 -0
  98. package/dist/src/public/definitions/callback-context.d.ts +2 -2
  99. package/dist/src/public/definitions/connections/mcp.d.ts +9 -0
  100. package/dist/src/public/definitions/connections/openapi.d.ts +9 -0
  101. package/dist/src/public/definitions/connections/tool-call.d.ts +21 -0
  102. package/dist/src/public/definitions/connections/tool-call.js +1 -0
  103. package/dist/src/public/definitions/sandbox.d.ts +1 -1
  104. package/dist/src/public/definitions/tool.d.ts +9 -9
  105. package/dist/src/public/sandbox/index.d.ts +1 -1
  106. package/dist/src/public/tools/web-search.d.ts +2 -2
  107. package/dist/src/runtime/connections/callback-route.d.ts +4 -5
  108. package/dist/src/runtime/connections/callback-route.js +1 -1
  109. package/dist/src/runtime/connections/mcp-client.js +1 -1
  110. package/dist/src/runtime/connections/openapi-client.js +1 -1
  111. package/dist/src/runtime/connections/provided-arguments.d.ts +9 -0
  112. package/dist/src/runtime/connections/provided-arguments.js +1 -0
  113. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  114. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +2 -2
  115. package/dist/src/runtime/framework-tools/todo.js +1 -1
  116. package/dist/src/runtime/input/types.d.ts +1 -4
  117. package/dist/src/runtime/resolve-connection.js +1 -1
  118. package/dist/src/runtime/types.d.ts +2 -0
  119. package/dist/src/sandbox/state.d.ts +1 -0
  120. package/dist/src/setup/ask-editable.d.ts +22 -0
  121. package/dist/src/setup/ask-editable.js +1 -0
  122. package/dist/src/setup/ask-signals.d.ts +23 -0
  123. package/dist/src/setup/ask-signals.js +1 -0
  124. package/dist/src/setup/ask.d.ts +24 -25
  125. package/dist/src/setup/ask.js +1 -1
  126. package/dist/src/setup/boxes/deploy-project.js +1 -1
  127. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  128. package/dist/src/setup/connection-connector.js +3 -2
  129. package/dist/src/setup/flows/registry-session.d.ts +33 -0
  130. package/dist/src/setup/flows/registry-session.js +1 -0
  131. package/dist/src/setup/flows/registry.d.ts +16 -0
  132. package/dist/src/setup/flows/registry.js +1 -1
  133. package/dist/src/setup/index.js +1 -1
  134. package/dist/src/setup/integrations/discord/setup.d.ts +19 -7
  135. package/dist/src/setup/integrations/discord/setup.js +4 -3
  136. package/dist/src/setup/integrations/github/setup.d.ts +36 -7
  137. package/dist/src/setup/integrations/github/setup.js +2 -2
  138. package/dist/src/setup/integrations/linear/setup.d.ts +21 -9
  139. package/dist/src/setup/integrations/linear/setup.js +2 -2
  140. package/dist/src/setup/integrations/photon/management.d.ts +8 -1
  141. package/dist/src/setup/integrations/photon/management.js +1 -1
  142. package/dist/src/setup/integrations/photon/setup-flow.d.ts +28 -24
  143. package/dist/src/setup/integrations/photon/setup-flow.js +3 -3
  144. package/dist/src/setup/integrations/photon/setup.d.ts +1 -3
  145. package/dist/src/setup/integrations/photon/setup.js +1 -1
  146. package/dist/src/setup/integrations/registry.d.ts +1 -1
  147. package/dist/src/setup/integrations/registry.js +1 -1
  148. package/dist/src/setup/integrations/runner.d.ts +14 -11
  149. package/dist/src/setup/integrations/runner.js +1 -1
  150. package/dist/src/setup/integrations/shared/prerequisite.d.ts +17 -0
  151. package/dist/src/setup/integrations/shared/prerequisite.js +1 -0
  152. package/dist/src/setup/integrations/shared/ui.d.ts +22 -15
  153. package/dist/src/setup/integrations/shared/ui.js +2 -2
  154. package/dist/src/setup/integrations/shared/vercel-project.d.ts +11 -0
  155. package/dist/src/setup/integrations/shared/vercel-project.js +1 -0
  156. package/dist/src/setup/integrations/slack/setup.d.ts +25 -10
  157. package/dist/src/setup/integrations/slack/setup.js +1 -1
  158. package/dist/src/setup/integrations/types.d.ts +43 -13
  159. package/dist/src/setup/integrations/types.js +1 -1
  160. package/dist/src/setup/integrations/web/setup.d.ts +22 -3
  161. package/dist/src/setup/integrations/web/setup.js +1 -1
  162. package/dist/src/setup/prompter.d.ts +8 -0
  163. package/dist/src/setup/question-options.d.ts +15 -0
  164. package/dist/src/setup/question-options.js +1 -0
  165. package/dist/src/setup/registry-setup-client.d.ts +3 -4
  166. package/dist/src/setup/registry-setup-client.js +2 -2
  167. package/dist/src/setup/registry-setup-completion.d.ts +3 -0
  168. package/dist/src/setup/registry-setup-completion.js +1 -0
  169. package/dist/src/setup/registry-setup-protocol.d.ts +22 -3
  170. package/dist/src/setup/registry-setup-protocol.js +1 -1
  171. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  172. package/dist/src/setup/scaffold/create/project.js +55 -3
  173. package/dist/src/setup/scaffold/update/channels.js +1 -1
  174. package/dist/src/setup/setup-question-wire.d.ts +48 -0
  175. package/dist/src/setup/setup-question-wire.js +1 -0
  176. package/dist/src/setup/slackbot.d.ts +5 -1
  177. package/dist/src/setup/slackbot.js +1 -1
  178. package/dist/src/setup/state.d.ts +2 -2
  179. package/dist/src/shared/sandbox-backend.d.ts +6 -0
  180. package/dist/src/shared/sandbox-session.d.ts +15 -0
  181. package/dist/src/shared/tool-definition.d.ts +2 -2
  182. package/dist/src/shared/tool-schema.d.ts +5 -4
  183. package/dist/src/shared/tool-schema.js +1 -1
  184. package/dist/src/svelte/index.js +1 -1
  185. package/dist/src/svelte/use-eve-agent.js +1 -1
  186. package/dist/src/tracing/agent-otel-provider.d.ts +5 -38
  187. package/dist/src/tracing/agent-otel-provider.js +2 -2
  188. package/dist/src/tracing/agent-span-id-generator.d.ts +15 -0
  189. package/dist/src/tracing/agent-span-id-generator.js +1 -0
  190. package/dist/src/tracing/agent-trace-context-store.d.ts +1 -1
  191. package/dist/src/tracing/agent-trace-context-store.js +1 -1
  192. package/dist/src/tracing/agent-trace-state.d.ts +41 -0
  193. package/dist/src/tracing/agent-trace-state.js +1 -0
  194. package/dist/src/tracing/local-instrumentation-runtime.js +1 -1
  195. package/dist/src/vue/index.js +1 -1
  196. package/dist/src/vue/use-eve-agent.js +1 -1
  197. package/docs/channels/chat-sdk.mdx +1 -1
  198. package/docs/channels/github.mdx +1 -1
  199. package/docs/channels/linear.mdx +4 -2
  200. package/docs/channels/overview.mdx +2 -2
  201. package/docs/channels/slack.mdx +154 -40
  202. package/docs/concepts/default-harness.md +3 -3
  203. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  204. package/docs/connections/mcp.mdx +35 -1
  205. package/docs/connections/openapi.mdx +24 -0
  206. package/docs/guides/dev-tui.md +58 -142
  207. package/docs/guides/dynamic-workflows.md +2 -0
  208. package/docs/guides/frontend/overview.mdx +4 -2
  209. package/docs/guides/hooks.md +25 -3
  210. package/docs/guides/session-context.md +18 -0
  211. package/docs/install-integrations.mdx +2 -0
  212. package/docs/reference/cli.md +5 -3
  213. package/docs/reference/typescript-api.md +1 -1
  214. package/docs/sandbox.mdx +25 -5
  215. package/docs/skills.mdx +12 -1
  216. package/docs/subagents.mdx +1 -1
  217. package/docs/tools/human-in-the-loop.md +1 -1
  218. package/docs/tutorial/ship-it.mdx +1 -1
  219. package/package.json +10 -10
  220. package/dist/src/compiled/_chunks/node/undici-DWL_MYmT.js +0 -95
  221. package/dist/src/compiled/_chunks/workflow/dist-CZxNEvEs.js +0 -79
@@ -211,6 +211,14 @@ export interface Prompter {
211
211
  intro(title: string, subtitle?: string): void;
212
212
  /** Prints a final green ● end-cap with the message. */
213
213
  outro(message: string): void;
214
+ /** Replaces transient setup output with one compact current-item summary. */
215
+ replaceContent?(content?: {
216
+ headline: string;
217
+ facts: readonly {
218
+ label: string;
219
+ value: string;
220
+ }[];
221
+ }): void;
214
222
  /** Temporarily hands terminal ownership to a command that inherits stdio. */
215
223
  withInheritedStdio?<T>(task: () => Promise<T>): Promise<T>;
216
224
  /** Gives a setup subprocess exclusive terminal and development-host ownership. */
@@ -0,0 +1,15 @@
1
+ export interface QuestionOption {
2
+ id: string;
3
+ value: unknown;
4
+ }
5
+ interface QuestionWithOptions<O extends QuestionOption> {
6
+ key: string;
7
+ options: readonly O[];
8
+ }
9
+ /** Finds an option by the stable id used by prompt and wire boundaries. */
10
+ export declare function optionById<O extends QuestionOption>(question: QuestionWithOptions<O>, id: unknown): O | undefined;
11
+ /** Finds an option by its in-process rich value. */
12
+ export declare function optionByValue<O extends QuestionOption>(question: QuestionWithOptions<O>, value: O["value"]): O | undefined;
13
+ /** Maps a rich value to its stable id, rejecting an invalid question definition. */
14
+ export declare function requiredOptionId<O extends QuestionOption>(question: QuestionWithOptions<O>, value: O["value"], role: string): string;
15
+ export {};
@@ -0,0 +1 @@
1
+ function optionById(e,t){return e.options.find(e=>e.id===String(t))}function optionByValue(e,t){return e.options.find(e=>e.value===t)}function requiredOptionId(e,t,n){let r=optionByValue(e,t);if(r===void 0)throw Error(`Question "${e.key}" has a ${n} that is not one of its options.`);return r.id}export{optionById,optionByValue,requiredOptionId};
@@ -1,6 +1,6 @@
1
1
  import type { Prompter } from "./prompter.js";
2
- import { type RegistrySetupChildMessage, type RegistrySetupFact, type RegistrySetupParentMessage } from "./registry-setup-protocol.js";
3
- interface SetupProcess {
2
+ import { type RegistrySetupChildMessage, type RegistrySetupCompletion, type RegistrySetupParentMessage } from "./registry-setup-protocol.js";
3
+ export interface SetupProcess {
4
4
  connected?: boolean;
5
5
  send?: (message: RegistrySetupChildMessage) => boolean;
6
6
  disconnect?: () => void;
@@ -10,7 +10,7 @@ interface SetupProcess {
10
10
  export interface RegistrySetupClient {
11
11
  prompter: Prompter;
12
12
  signal: AbortSignal;
13
- complete(facts?: readonly RegistrySetupFact[]): void;
13
+ complete(completion?: RegistrySetupCompletion): void;
14
14
  cancel(): void;
15
15
  fail(error: unknown): void;
16
16
  }
@@ -19,4 +19,3 @@ export declare function createRegistrySetupClient(input?: {
19
19
  process?: SetupProcess;
20
20
  signal?: AbortSignal;
21
21
  }): RegistrySetupClient | undefined;
22
- export {};
@@ -1,2 +1,2 @@
1
- import{WizardCancelledError}from"./step.js";import"./registry-setup-protocol.js";function send(e,t){if(e.send===void 0||!e.connected)throw Error(`The registry setup host disconnected.`);e.send(t)}function registrySetupError(e){if(!(e instanceof Error))return{message:String(e)};let t=e.stack?.split(`
2
- `).slice(1).map(e=>e.trim()).filter(Boolean);return t===void 0||t.length===0?{message:e.message}:{message:e.message,details:t}}function createRegistrySetupClient(t={}){let n=t.process??process;if(n.send===void 0||process.env.EVE_SETUP_PROTOCOL===void 0)return;let r=new AbortController;t.signal!==void 0&&t.signal.addEventListener(`abort`,()=>r.abort(t.signal?.reason),{once:!0});let i=1,a=new Map,onMessage=t=>{if(t.type===`cancel`){r.abort(new WizardCancelledError);for(let e of a.values())e({type:`cancel`});a.clear();return}a.get(t.id)?.(t)};n.on(`message`,onMessage),send(n,{type:`ready`,version:1});async function prompt(t){r.signal.throwIfAborted();let o=i++,s=await new Promise(e=>{a.set(o,e),send(n,{type:`prompt`,id:o,prompt:t})});if(a.delete(o),s.type===`cancel`||s.cancelled===!0)throw new WizardCancelledError;return s.value}async function validatedText(e,t){let n=t.notices;for(;;){let r=await prompt({kind:e,message:t.message,placeholder:t.placeholder,defaultValue:t.defaultValue,notices:n}),i=t.validate?.(r);if(i===void 0)return r;n=[{tone:`error`,text:i}]}}function select(e){return prompt({kind:`select`,options:e})}let o={text:e=>validatedText(`text`,e),password:e=>validatedText(`password`,e),select,async selectEditable(e){let t=await prompt({kind:`editable-select`,options:{...e,editable:{value:e.editable.value,defaultValue:e.editable.defaultValue}}});if(t.kind===`selected`)return{kind:`selected`,value:t.value};let n=e.editable.validate?.(t.text);if(n!==void 0)throw Error(n);return{kind:`edited`,value:t.value,text:t.text}},acknowledge:e=>prompt({kind:`acknowledge`,options:e}),awaitChoice(t){let r=i++;return{choice:new Promise((i,o)=>{a.set(r,t=>{a.delete(r),t.type===`cancel`||t.cancelled===!0?o(new WizardCancelledError):i(t.value)}),send(n,{type:`prompt`,id:r,prompt:{kind:`choice`,options:t}})}),close:()=>{a.delete(r),send(n,{type:`close-prompt`,id:r})}}},note(e,t,r){send(n,{type:`note`,message:e,title:t,tone:r?.tone})},intro(e,t){send(n,{type:`intro`,text:e,subtitle:t})},outro(e){send(n,{type:`outro`,text:e})},log:{message:e=>send(n,{type:`log`,level:`message`,text:e}),info:e=>send(n,{type:`log`,level:`info`,text:e}),success:e=>send(n,{type:`log`,level:`success`,text:e}),warning:e=>send(n,{type:`log`,level:`warning`,text:e}),error:e=>send(n,{type:`log`,level:`error`,text:e}),commandOutput:e=>send(n,{type:`log`,level:`commandOutput`,text:e}),spinner(e,t){let r=i++;return send(n,{type:`status`,id:r,status:e,intent:t?.kind===`external-action`?t:void 0}),{stop:()=>send(n,{type:`status`,id:r})}}}},s=!1,finish=e=>{s||(s=!0,send(n,{type:`result`,outcome:e}),n.off(`message`,onMessage),n.disconnect?.())};return{prompter:o,signal:r.signal,complete:(e=[])=>finish({kind:`completed`,facts:e}),cancel:()=>finish({kind:`cancelled`}),fail:e=>finish({kind:`failed`,error:registrySetupError(e)})}}export{createRegistrySetupClient};
1
+ import{InteractionRequired,InvalidAnswerError}from"./ask-signals.js";import{SetupPrerequisiteRequired}from"./integrations/shared/prerequisite.js";import"./ask.js";import{WizardCancelledError}from"./step.js";import{setupQuestionToWire}from"./setup-question-wire.js";import"./registry-setup-protocol.js";function send(e,t){if(e.send===void 0||!e.connected)throw Error(`The registry setup host disconnected.`);e.send(t)}function registrySetupBlocker(r){if(r instanceof InteractionRequired)return{status:`input_required`,question:setupQuestionToWire(r.question)};if(r instanceof InvalidAnswerError)return{status:`input_required`,question:setupQuestionToWire(r.question),issue:{code:`invalid_answer`,message:r.message}};if(r instanceof SetupPrerequisiteRequired)return{status:`prerequisite_required`,prerequisite:r.prerequisite}}function registrySetupError(e){if(!(e instanceof Error))return{message:String(e)};let t=e.stack?.split(`
2
+ `).slice(1).map(e=>e.trim()).filter(Boolean);return t===void 0||t.length===0?{message:e.message}:{message:e.message,details:t}}function createRegistrySetupClient(e={}){let t=e.process??process;if(t.send===void 0||process.env.EVE_SETUP_PROTOCOL===void 0)return;let n=new AbortController;e.signal!==void 0&&e.signal.addEventListener(`abort`,()=>n.abort(e.signal?.reason),{once:!0});let i=1,a=new Map,onMessage=e=>{if(e.type===`cancel`){n.abort(new WizardCancelledError);for(let e of a.values())e({type:`cancel`});a.clear();return}a.get(e.id)?.(e)};t.on(`message`,onMessage),send(t,{type:`ready`,version:2});async function prompt(e){n.signal.throwIfAborted();let o=i++,s=await new Promise(n=>{a.set(o,n),send(t,{type:`prompt`,id:o,prompt:e})});if(a.delete(o),s.type===`cancel`||s.cancelled===!0)throw new WizardCancelledError;return s.value}async function validatedText(e,t){let n=t.notices;for(;;){let r=await prompt({kind:e,message:t.message,placeholder:t.placeholder,defaultValue:t.defaultValue,notices:n}),i=t.validate?.(r);if(i===void 0)return r;n=[{tone:`error`,text:i}]}}function select(e){return prompt({kind:`select`,options:e})}let o={text:e=>validatedText(`text`,e),password:e=>validatedText(`password`,e),select,async selectEditable(e){let t=await prompt({kind:`editable-select`,options:{...e,editable:{value:e.editable.value,defaultValue:e.editable.defaultValue}}});if(t.kind===`selected`)return{kind:`selected`,value:t.value};let n=e.editable.validate?.(t.text);if(n!==void 0)throw Error(n);return{kind:`edited`,value:t.value,text:t.text}},acknowledge:e=>prompt({kind:`acknowledge`,options:e}),awaitChoice(e){let n=i++;return{choice:new Promise((i,o)=>{a.set(n,e=>{a.delete(n),e.type===`cancel`||e.cancelled===!0?o(new WizardCancelledError):i(e.value)}),send(t,{type:`prompt`,id:n,prompt:{kind:`choice`,options:e}})}),close:()=>{a.delete(n),send(t,{type:`close-prompt`,id:n})}}},note(e,n,r){send(t,{type:`note`,message:e,title:n,tone:r?.tone})},intro(e,n){send(t,{type:`intro`,text:e,subtitle:n})},outro(e){send(t,{type:`outro`,text:e})},log:{message:e=>send(t,{type:`log`,level:`message`,text:e}),info:e=>send(t,{type:`log`,level:`info`,text:e}),success:e=>send(t,{type:`log`,level:`success`,text:e}),warning:e=>send(t,{type:`log`,level:`warning`,text:e}),error:e=>send(t,{type:`log`,level:`error`,text:e}),commandOutput:e=>send(t,{type:`log`,level:`commandOutput`,text:e}),spinner(e,n){let r=i++;return send(t,{type:`status`,id:r,status:e,intent:n?.kind===`external-action`?n:void 0}),{stop:()=>send(t,{type:`status`,id:r})}}}},s=!1,finish=e=>{s||(s=!0,send(t,{type:`result`,outcome:e}),t.off(`message`,onMessage),t.disconnect?.())};return{prompter:o,signal:n.signal,complete:(e={facts:[]})=>finish({kind:`completed`,...e}),cancel:()=>finish({kind:`cancelled`}),fail(e){let t=registrySetupBlocker(e);finish(t===void 0?{kind:`failed`,error:registrySetupError(e)}:{kind:`blocked`,blocker:t})}}}export{createRegistrySetupClient};
@@ -0,0 +1,3 @@
1
+ import type { RegistrySetupCompletion } from "./registry-setup-protocol.js";
2
+ /** Combines setup completions while preserving their facts and deployment requirement. */
3
+ export declare function mergeRegistrySetupCompletions(...completions: readonly RegistrySetupCompletion[]): RegistrySetupCompletion;
@@ -0,0 +1 @@
1
+ function mergeRegistrySetupCompletions(...e){let t=e.flatMap(e=>e.facts);return e.some(e=>e.deploymentRequired===!0)?{facts:t,deploymentRequired:!0}:{facts:t}}export{mergeRegistrySetupCompletions};
@@ -1,17 +1,36 @@
1
1
  import type { AcknowledgeOptions, MultiSelectOptions, PrompterValue, SelectCommonOptions, SelectNotice, SelectOption, SingleSelectOptions } from "./prompter.js";
2
- export declare const REGISTRY_SETUP_PROTOCOL_VERSION = 1;
2
+ import type { SetupPrerequisite } from "./integrations/shared/prerequisite.js";
3
+ import type { SetupWireQuestion } from "./setup-question-wire.js";
4
+ export declare const REGISTRY_SETUP_PROTOCOL_VERSION = 2;
3
5
  export type RegistrySetupFact = {
4
6
  label: string;
5
7
  value: string;
6
8
  kind?: "text" | "url" | "phone";
7
9
  };
10
+ export type RegistrySetupCompletion = {
11
+ facts: readonly RegistrySetupFact[];
12
+ deploymentRequired?: true;
13
+ };
14
+ export type RegistrySetupBlocker = {
15
+ status: "input_required";
16
+ question: SetupWireQuestion;
17
+ issue?: {
18
+ code: "invalid_answer";
19
+ message: string;
20
+ };
21
+ } | {
22
+ status: "prerequisite_required";
23
+ prerequisite: SetupPrerequisite;
24
+ };
8
25
  export type RegistrySetupError = {
9
26
  message: string;
10
27
  details?: readonly string[];
11
28
  };
12
- export type RegistrySetupOutcome = {
29
+ export type RegistrySetupOutcome = ({
13
30
  kind: "completed";
14
- facts: readonly RegistrySetupFact[];
31
+ } & RegistrySetupCompletion) | {
32
+ kind: "blocked";
33
+ blocker: RegistrySetupBlocker;
15
34
  } | {
16
35
  kind: "cancelled";
17
36
  } | {
@@ -1 +1 @@
1
- const REGISTRY_SETUP_PROTOCOL_VERSION=1;function isRegistrySetupChildMessage(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`ready`||t===`prompt`||t===`close-prompt`||t===`log`||t===`note`||t===`intro`||t===`outro`||t===`result`||t===`status`}export{REGISTRY_SETUP_PROTOCOL_VERSION,isRegistrySetupChildMessage};
1
+ const REGISTRY_SETUP_PROTOCOL_VERSION=2;function isRegistrySetupChildMessage(e){if(typeof e!=`object`||!e)return!1;let t=e.type;return t===`ready`||t===`prompt`||t===`close-prompt`||t===`log`||t===`note`||t===`intro`||t===`outro`||t===`result`||t===`status`}export{REGISTRY_SETUP_PROTOCOL_VERSION,isRegistrySetupChildMessage};
@@ -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(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.38`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.3`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}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(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.58`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.3`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.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.38`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.31.2`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).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{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.58`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.3`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.32.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){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).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__",
@@ -71,7 +71,59 @@ dist
71
71
  .output
72
72
  .nitro
73
73
  dist
74
- `,"AGENTS.md":"# eve Agent App\n\nThis project uses the eve framework. Before writing code, read the relevant guide\nfrom the installed eve package docs. In most installs, those docs are at\n`node_modules/eve/docs/`. In workspaces or local package installs, resolve the\ninstalled `eve` package location first and read its `docs/` directory. If\npackage docs are unavailable, use https://eve.dev/docs as a fallback.\n\nBefore implementing an integration yourself, use\n`eve registry search <query>` or `eve registry list` to discover available\nintegrations. Inspect one with `eve registry view <item>`, then install it with\n`eve add <item>`.\n","CLAUDE.md":`@AGENTS.md
74
+ `,"AGENTS.md":`# eve Agent App
75
+
76
+ This project uses the eve framework. Before writing code, read the relevant guide
77
+ from the installed eve package docs. In most installs, those docs are at
78
+ \`node_modules/eve/docs/\`. In workspaces or local package installs, resolve the
79
+ installed \`eve\` package location first and read its \`docs/\` directory. If
80
+ package docs are unavailable, use https://eve.dev/docs as a fallback.
81
+
82
+ ## Adding integrations
83
+
84
+ Before implementing an integration yourself, discover existing integrations:
85
+
86
+ \`\`\`sh
87
+ eve registry search <query> --json
88
+ eve registry view <item>
89
+ \`\`\`
90
+
91
+ Prefer registry items whose \`implementation\` is \`native\`; use Chat SDK adapters when no
92
+ native channel fits. \`registry view\` provides the selected item's documentation link.
93
+
94
+ Install and configure one without driving interactive terminal prompts:
95
+
96
+ \`\`\`sh
97
+ eve add <item> --non-interactive
98
+ \`\`\`
99
+
100
+ Exit code 0 means setup completed, 1 means setup failed, and 2 means setup needs
101
+ input or a prerequisite. On exit 2, parse the final NDJSON event and use its
102
+ \`next.command\` as the continuation.
103
+
104
+ Every \`--answer\` value is JSON, so strings need JSON quotes. For an editable
105
+ question, you may supply its nested \`editable.key\` with the parent key in one
106
+ invocation:
107
+
108
+ \`\`\`sh
109
+ eve add channel/photon-imessage --non-interactive \\
110
+ --answer 'photon-project-source="create"' \\
111
+ --answer 'photon-project-name="eve · my-agent"'
112
+ \`\`\`
113
+
114
+ Add \`--yes\` to accept recommended setup values and reduce setup round trips;
115
+ explicit \`--answer\` values take precedence. Use the reported \`--skip-install\`
116
+ continuation after installation.
117
+ A Vercel Connect setup may report \`eve link\` as a prerequisite; run it and
118
+ retry the continuation. Never pass secrets in \`--answer\`; use the documented
119
+ environment variable or secret store.
120
+
121
+ An \`external_action\` event with \`blocking: true\` means the command is still
122
+ running while it waits for the user. Surface its URL and code, keep the process
123
+ alive, and wait for its matching \`external_action_resolved\` event or a terminal
124
+ event. Do not start a continuation. When a completed event has
125
+ \`deploymentRequired: true\`, recommend its \`next\` command to deploy the changes.
126
+ `,"CLAUDE.md":`@AGENTS.md
75
127
  `};function templateFiles(e){return{"agent/agent.ts":e.byokProvider?`import { defineAgent } from "eve";
76
128
 
77
129
  export default defineAgent({
@@ -86,4 +138,4 @@ export default defineAgent({
86
138
  },
87
139
  },
88
140
  });
89
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));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(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.38`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!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};
141
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=blockingCreateInPlaceEntries(await readdir(e));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(t){let i=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??i),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(i,l);else if(await pathExists(i))throw Error(`Cannot create project because "${i}" already exists.`);let g={appName:basename(i),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.58`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.3`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(i,{recursive:!0});for(let[e,a]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let o=`${i}/${e}`,s=await pathExists(o);await writeTextFile(o,renderTemplate(a,g),{force:c&&l}),s&&await t.onOverwriteFile?.(o)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:i,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),i}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!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};
@@ -1,4 +1,4 @@
1
- import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";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{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";import{basename,join,resolve}from"node:path";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.38`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c,d=!0){let p=join(e,`package.json`);if(!await pathExists(p))return{mutations:[]};let h=resolveEvePackageContract(a.evePackage),g=pinnedNodeEngineMajor(h.nodeEngine),_={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(h.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},v={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":g,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},y=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,b=isPackageManagerWorkspaceMember(n,r),x={scripts:y};d&&(x.dependencies=_,x.devDependencies=v),b||(x.nodeEngineRequirement=h.nodeEngine);let S=await patchPackageJson(p,x),C=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:_.ai,nodeEngineRequirement:h.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??S.nodeEngineOverride;return{mutations:[{path:p,dependencies:d?Object.keys(_):[],devDependencies:d?Object.keys(v):[],scripts:Object.keys(y)}],nodeEngineOverride:C}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
1
+ import{appendEnv}from"../../append-env.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";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{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{readFile,readdir,unlink,writeFile}from"node:fs/promises";import{basename,join,resolve}from"node:path";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH);function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readPackageJsonObject(e){if(!await pathExists(e))return;let t=JSON.parse(await readFile(e,`utf8`));return isJsonObject(t)?t:void 0}async function readDependencyVersion(e,t){let n=await readPackageJsonObject(e);if(n===void 0||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){let n=await readPackageJsonObject(e);return n!==void 0&&packageJsonHasDependency(n,t)}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}const VERCEL_HOST_FRAMEWORK_PRESETS={"@sveltejs/kit":`sveltekit`,[NEXT_PACKAGE_NAME]:`nextjs`,nuxt:`nuxtjs`,nuxt3:`nuxtjs`,"nuxt-edge":`nuxtjs`,"nuxt-nightly":`nuxtjs`};async function resolveVercelHostFrameworkPreset(e){let t=await readPackageJsonObject(join(e,`package.json`));if(t!==void 0){for(let[e,n]of Object.entries(VERCEL_HOST_FRAMEWORK_PRESETS))if(packageJsonHasDependency(t,e))return n}}async function hasVercelHostFramework(e){return await resolveVercelHostFrameworkPreset(e)!==void 0}async function ensurePackageDependency(e,t,n){return!await pathExists(e)||await readDependencyVersion(e,t)===n?[]:(await patchPackageJson(e,{dependencies:{[t]:n}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`^7.0.58`,nextPackageVersion:e?.nextPackageVersion??`16.3.0-preview.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,n,r,a,c,d=!0){let p=join(e,`package.json`);if(!await pathExists(p))return{mutations:[]};let h=resolveEvePackageContract(a.evePackage),g=pinnedNodeEngineMajor(h.nodeEngine),_={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,a.aiPackageVersion),eve:formatEveDependencySpecifier(h.version),next:resolveVersionToken(`nextPackageVersion`,a.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,a.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,a.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,a.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,a.zodPackageVersion)},v={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":g,"@types/react":resolveVersionToken(`typesReactPackageVersion`,a.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,a.typesReactDomPackageVersion),typescript:`6.0.3`},y=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,b=isPackageManagerWorkspaceMember(n,r),x={scripts:y};d&&(x.dependencies=_,x.devDependencies=v),b||(x.nodeEngineRequirement=h.nodeEngine);let S=await patchPackageJson(p,x),C=(await patchWorkspaceRootPackageJson(n,r,{aiPackageVersion:_.ai,nodeEngineRequirement:h.nodeEngine,onWorkspaceRootMutation:c})).nodeEngineOverride??S.nodeEngineOverride;return{mutations:[{path:p,dependencies:d?Object.keys(_):[],devDependencies:d?Object.keys(v):[],scripts:Object.keys(y)}],nodeEngineOverride:C}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackConnectTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
2
2
  import { slackChannel } from "eve/channels/slack";
3
3
 
4
4
  export default slackChannel({
@@ -0,0 +1,48 @@
1
+ import type { AnyQuestion } from "./ask.js";
2
+ export interface SetupWireOption {
3
+ id: string;
4
+ label: string;
5
+ hint?: string;
6
+ disabled?: boolean;
7
+ disabledReason?: string;
8
+ locked?: boolean;
9
+ lockedReason?: string;
10
+ }
11
+ type SharedWireQuestion = {
12
+ key: string;
13
+ message: string;
14
+ required: boolean;
15
+ };
16
+ export type SetupWireQuestion = (SharedWireQuestion & {
17
+ kind: "confirm";
18
+ recommended?: boolean;
19
+ }) | (SharedWireQuestion & {
20
+ kind: "text";
21
+ placeholder?: string;
22
+ sensitive?: false;
23
+ }) | (SharedWireQuestion & {
24
+ kind: "environment";
25
+ variable: string;
26
+ sensitive: true;
27
+ }) | (SharedWireQuestion & {
28
+ kind: "select";
29
+ recommended?: string;
30
+ options: readonly SetupWireOption[];
31
+ }) | (SharedWireQuestion & {
32
+ kind: "multi-select";
33
+ recommended?: readonly string[];
34
+ options: readonly SetupWireOption[];
35
+ }) | (SharedWireQuestion & {
36
+ kind: "editable-select";
37
+ recommended?: string;
38
+ options: readonly SetupWireOption[];
39
+ editable: {
40
+ key: string;
41
+ optionId: string;
42
+ label: string;
43
+ recommended: string;
44
+ };
45
+ });
46
+ /** Removes runtime values and validators from one internal setup question. */
47
+ export declare function setupQuestionToWire(question: AnyQuestion): SetupWireQuestion;
48
+ export {};
@@ -0,0 +1 @@
1
+ import{requiredOptionId}from"./question-options.js";function wireOptions(e){return e.options.map(e=>{let t={id:e.id,label:e.label};return e.hint!==void 0&&(t.hint=e.hint),e.disabled!==void 0&&(t.disabled=e.disabled),e.disabledReason!==void 0&&(t.disabledReason=e.disabledReason),e.locked!==void 0&&(t.locked=e.locked),e.lockedReason!==void 0&&(t.lockedReason=e.lockedReason),t})}function sharedQuestion(e){return{key:e.key,message:e.message,required:e.required===!0}}function setupQuestionToWire(t){let n=sharedQuestion(t);if(`editable`in t){let r=t,i=requiredOptionId(r,r.editable.value,`configured editable value`),a={...n,kind:`editable-select`,options:wireOptions(r),editable:{key:r.editable.key,optionId:i,label:r.editable.label,recommended:r.editable.recommended}};return r.recommended!==void 0&&(a.recommended=requiredOptionId(r,r.recommended,`recommendation`)),a}if(!(`kind`in t)){let r=t,i={...n,kind:`multi-select`,options:wireOptions(r)};return r.recommended!==void 0&&(i.recommended=r.recommended.map(t=>requiredOptionId(r,t,`recommendation`))),i}let r=t;if(r.kind===`confirm`){let e={...n,kind:`confirm`};return r.recommended!==void 0&&(e.recommended=r.recommended),e}if(r.kind===`text`){if(r.sensitive===!0)return{...n,kind:`environment`,variable:r.environment,sensitive:!0};let e={...n,kind:`text`,sensitive:!1};return r.placeholder!==void 0&&(e.placeholder=r.placeholder),e}let i={...n,kind:`select`,options:wireOptions(r)};return r.recommended!==void 0&&(i.recommended=requiredOptionId(r,r.recommended,`recommendation`)),i}export{setupQuestionToWire};
@@ -1,7 +1,7 @@
1
1
  import { type ChannelSetupAwaitChoice, type ChannelSetupLog } from "#setup/cli/index.js";
2
2
  import type { SlackConnectorRef } from "./slack-connect.js";
3
3
  import { type SlackConnectorCreateDeps } from "./slack-connect-create.js";
4
- import { readProjectLink, type SlackConnectLifecycleDeps } from "./slack-connect-lifecycle.js";
4
+ import { readProjectLink, type SlackConnectLifecycleDeps, type SlackConnectorLookup } from "./slack-connect-lifecycle.js";
5
5
  export { parseCreatedSlackConnector, parseSlackConnectorDetails, pickSlackConnector, type SlackConnectorRef, } from "./slack-connect.js";
6
6
  /** Injected for tests; defaults to the real Vercel CLI subprocess primitives. */
7
7
  export interface SlackbotProvisionDeps extends SlackConnectLifecycleDeps, SlackConnectorCreateDeps {
@@ -60,6 +60,10 @@ export type ProvisionSlackbotResult = {
60
60
  * payload before attachment.
61
61
  */
62
62
  export type SlackConnectorSelection = SlackConnectorRef | "create";
63
+ /** Read-only connector inventory used to resolve the create/reuse decision before provisioning. */
64
+ export declare function inspectSlackbotConnectors(log: ChannelSetupLog, projectRoot: string, slug: string, signal?: AbortSignal, deps?: SlackbotProvisionDeps): Promise<Extract<SlackConnectorLookup, {
65
+ state: "found" | "not-found";
66
+ }>>;
63
67
  export interface ProvisionSlackbotOptions {
64
68
  /**
65
69
  * Cancels the caller's whole operation. The promise rejects after attempting
@@ -1 +1 @@
1
- import{parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector}from"./slack-connect.js";import{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink}from"./slack-connect-lifecycle.js";import{createSlackConnector}from"./slack-connect-create.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{captureVercel,runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{setTimeout}from"node:timers/promises";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{updateSlackChannelConnectorUid}from"#setup/scaffold/update/update-slack-channel.js";const defaultDeps={captureVercel,runVercel,runVercelCaptureStdout},realDelay=(e,t)=>setTimeout(e,void 0,{signal:t}),monotonicNow=()=>performance.now();async function pollSlackWorkspace(e,t,n,i,a,s){let c=e.delay??realDelay,l=e.now??monotonicNow,u=l()+3e5;for(;;){s?.throwIfAborted();let d=u-l();if(d<=0)return{state:`timed-out`};let f=await fetchSlackWorkspace({deps:e,projectRoot:t,connectorId:n,orgId:i,onOutput:a,timeoutMs:Math.min(CONNECT_LOOKUP_TIMEOUT_MS,d),signal:s});if(s?.throwIfAborted(),f.state!==`pending`)return f;let p=u-l();if(p<=0)return{state:`timed-out`};await c(Math.min(3e3,p),s)}}function isAbortFromSignal(e,t){return t?.aborted===!0&&(e===t.reason||e instanceof Error&&e.name===`AbortError`)}function cleanupFailureResult(e){return{state:`cleanup-failed`,connectorUids:e.connectorUids}}async function runAttempt(e){let{log:t,deps:n,projectRoot:r,orgId:a,onOutput:o,signal:s,phase:c}=e,l,d;if(e.source.state===`existing`)l=e.source.ref;else{let i=await createSlackConnector({deps:n,projectRoot:r,orgId:a,slug:e.slug,onOutput:o,signal:s,phase:c,onCreated:e.onCreated,waitForWorkspace:async(e,t)=>{let i=await pollSlackWorkspace(n,r,e.id,a,o,t);return i.state===`connected`?i.workspace:void 0}});if(i.state===`failed`)return{state:`create-failed`};if(i.state===`unresolved`)return t.warning(`Vercel did not return an exact Slack connector UID for this request, so eve cannot attach or remove it safely.`),{state:`unresolved`};l=i.ref,i.via===`workspace`&&(d=i.workspace)}if(e.source.state===`existing`&&d===void 0){let e=await c(`Waiting for the Slack workspace connection...`,()=>pollSlackWorkspace(n,r,l.id,a,o,s));if(e.state===`timed-out`)return{state:`timed-out`,ref:l};if(e.state===`failed`)return{state:`failed`,ref:l,message:e.message};d=e.workspace}let f=await c(`Configuring Slack event delivery for this agent...`,()=>attachSlackConnector(n,r,l,o,s));return s?.throwIfAborted(),f.state===`attached`?d===void 0?{state:`attached`,ref:l}:{state:`attached`,ref:l,workspace:d}:{state:f.state,ref:l}}async function raceAttemptAgainstChoice(e){let t=new AbortController,n=e.outerSignal?AbortSignal.any([e.outerSignal,t.signal]):t.signal,r=e.run(n);try{let i=await Promise.race([r.then(e=>({via:`work`,outcome:e})),e.prompt.choice.then(e=>({via:`choice`,choice:e}))]);if(i.via===`work`)return i;t.abort();let a;try{a=await r}catch(e){if(!isAbortFromSignal(e,n))throw e}return{via:`choice`,choice:i.choice,settled:a}}catch(e){t.abort();try{await r}catch{}throw e}finally{e.prompt.close()}}async function provisionSlackbot(e,t,n,r=defaultDeps,i={}){i.signal?.throwIfAborted();let o=createPromptCommandOutput(e),u={log:e,deps:r,projectRoot:t,onOutput:o},d=await(r.readProjectLink??readProjectLink)(t),p=d?.projectId,m=d?.orgId,h=`slack/${n}`,g=await withPhase(e,`Checking for an existing Slackbot...`,()=>findSlackConnector(r,t,p,h,o,i.signal));if(i.signal?.throwIfAborted(),g.state===`failed`)return e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${g.message}`),{state:`connector-lookup-failed`};if(p===void 0&&g.connectorUids.size>0)return e.warning("Could not verify which Slack connectors belong to this Vercel project, so eve did not create another one. Restore `.vercel/project.json`, then try again."),{state:`connector-lookup-failed`};let finishOutcome=async(t,n,r)=>{let i=n.state===`new`;switch(t.state){case`create-failed`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`unresolved`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`detach-failed`:return e.warning(`Could not remove the connector's existing trigger destination. Run \`vercel connect detach ${t.ref.uid} --yes\`, then \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\`.`),{state:`detach-failed`,connectorUid:t.ref.uid};case`attach-failed`:return e.warning(`Could not register this project as a trigger destination. Run \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\` to enable event delivery.`),{state:`attach-failed`,connectorUid:t.ref.uid};case`attached`:return t.workspace===void 0?{state:`attached`,connectorUid:t.ref.uid}:{state:`attached`,connectorUid:t.ref.uid,chatUrl:t.workspace.workspaceUrl,workspaceName:t.workspace.workspaceName};case`failed`:return e.warning(`Could not verify the Slack workspace connection. ${t.message}`),{state:`installation-check-failed`,connectorUid:t.ref.uid};case`timed-out`:if(e.warning(`The Slackbot did not connect to a Slack workspace in time.`),i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`not-installed`}}},cleanupNewAttempt=async(e,t)=>cleanupCreatedAttempt(u,{expectedUid:h,baselineConnectorUids:e.baselineConnectorUids,createdRef:t});function attemptInput(i,a){return{log:e,deps:r,projectRoot:t,orgId:m,slug:n,source:i,onOutput:o,onCreated:a}}async function runExistingConnector(t){let cleanupCurrentAttempt=async()=>({state:`clean`}),notInstalled=()=>(e.warning(`The existing Slack connector \`${t.ref.uid}\` is not connected to a Slack workspace. eve did not remove it because this run did not create it. If its original browser request is still open, complete it; otherwise run \`vercel connect remove ${t.ref.uid} --disconnect-all --yes\` before trying again.`),{state:`existing-not-installed`,connectorUid:t.ref.uid}),finishExistingOutcome=async e=>e.state===`timed-out`?notInstalled():finishOutcome(e,t,cleanupCurrentAttempt);if(i.awaitChoice!==void 0){let e=await raceAttemptAgainstChoice({prompt:i.awaitChoice({status:`Waiting for the existing Slack workspace connection...`,context:`Complete the original setup in the browser`,actions:[{value:`cancel`,label:`Stop waiting`}]}),outerSignal:i.signal,run:e=>runAttempt({...attemptInput(t,()=>{}),signal:e,phase:(e,t)=>t()})});return e.via===`work`?finishExistingOutcome(e.outcome):e.settled?.state===`attached`?finishExistingOutcome(e.settled):notInstalled()}return finishExistingOutcome(await runAttempt({...attemptInput(t,()=>{}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)}))}async function runUncontrolledAttempt(t){let n,cleanupCurrentAttempt=()=>cleanupNewAttempt(t,n),r=runAttempt({...attemptInput(t,e=>{n=e}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)});try{return await finishOutcome(await r,t,cleanupCurrentAttempt)}catch(e){throw i.signal?.aborted===!0&&await cleanupCurrentAttempt(),e}}async function runInteractiveAttempt(n,a){let s,cleanupCurrentAttempt=()=>cleanupNewAttempt(n,s),l=a({status:`Waiting for Slack setup to finish...`,context:`Complete setup in the browser, then wait while eve verifies the connection`,actions:[{value:`retry`,label:`Did your browser not open? Try again`},{value:`cancel`,label:`Cancel`}]}),u;try{u=await raceAttemptAgainstChoice({prompt:l,outerSignal:i.signal,run:t=>runAttempt({...attemptInput(n,e=>{s=e}),signal:t,phase:e.spinner===void 0?(e,t)=>t():(t,n)=>withPhase(e,t,n)})})}catch(e){throw await cleanupCurrentAttempt(),e}if(u.via===`work`)return{state:`finished`,result:await finishOutcome(u.outcome,n,cleanupCurrentAttempt)};if(u.settled?.state===`attached`)return{state:`finished`,result:await finishOutcome(u.settled,n,cleanupCurrentAttempt)};let d=await cleanupCurrentAttempt();if(d.state===`failed`)return{state:`finished`,result:cleanupFailureResult(d)};if(u.choice===`retry`){let n=await withPhase(e,`Checking existing Slack connectors...`,()=>listSlackConnectors(r,t,o,i.signal));return i.signal?.throwIfAborted(),n.state===`failed`?(e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${n.message}`),{state:`finished`,result:{state:`connector-lookup-failed`}}):{state:`retry`,source:{state:`new`,baselineConnectorUids:new Set(n.connectors.map(e=>e.uid))}}}return{state:`finished`,result:{state:`cancelled`}}}if(g.state===`found`){let e=i.selectConnector===void 0?g.preferred??g.connectors[0]:await i.selectConnector(g.connectors,g.preferred);if(i.signal?.throwIfAborted(),e!==`create`)return runExistingConnector({state:`existing`,ref:e})}let _={state:`new`,baselineConnectorUids:g.connectorUids};if(i.awaitChoice===void 0)return runUncontrolledAttempt(_);for(;;){let e=await runInteractiveAttempt(_,i.awaitChoice);if(e.state===`finished`)return e.result;_=e.source}}async function reconcileSlackUid(e,t,n,r){if(n.state!==`attached`||n.connectorUid===r)return!0;let{patched:i}=await updateSlackChannelConnectorUid(join(t,`agent/channels/slack.ts`),n.connectorUid);return i?!0:(e.warning(`Could not patch agent/channels/slack.ts automatically. Update \`connectSlackCredentials("...")\` to \`"${n.connectorUid}"\` and run \`vercel deploy --prod\`.`),!1)}export{parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector,provisionSlackbot,reconcileSlackUid};
1
+ import{parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector}from"./slack-connect.js";import{CONNECT_LOOKUP_TIMEOUT_MS,attachSlackConnector,cleanupCreatedAttempt,fetchSlackWorkspace,findSlackConnector,listSlackConnectors,readProjectLink}from"./slack-connect-lifecycle.js";import{createSlackConnector}from"./slack-connect-create.js";import{join}from"node:path";import{SLACK_CHANNEL_DEFAULT_ROUTE}from"#setup/scaffold/index.js";import{performance}from"node:perf_hooks";import{captureVercel,runVercel,runVercelCaptureStdout}from"#setup/primitives/run-vercel.js";import{setTimeout}from"node:timers/promises";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{updateSlackChannelConnectorUid}from"#setup/scaffold/update/update-slack-channel.js";const defaultDeps={captureVercel,runVercel,runVercelCaptureStdout},realDelay=(e,t)=>setTimeout(e,void 0,{signal:t}),monotonicNow=()=>performance.now();async function pollSlackWorkspace(e,t,n,i,a,s){let c=e.delay??realDelay,l=e.now??monotonicNow,u=l()+3e5;for(;;){s?.throwIfAborted();let d=u-l();if(d<=0)return{state:`timed-out`};let f=await fetchSlackWorkspace({deps:e,projectRoot:t,connectorId:n,orgId:i,onOutput:a,timeoutMs:Math.min(CONNECT_LOOKUP_TIMEOUT_MS,d),signal:s});if(s?.throwIfAborted(),f.state!==`pending`)return f;let p=u-l();if(p<=0)return{state:`timed-out`};await c(Math.min(3e3,p),s)}}function isAbortFromSignal(e,t){return t?.aborted===!0&&(e===t.reason||e instanceof Error&&e.name===`AbortError`)}function cleanupFailureResult(e){return{state:`cleanup-failed`,connectorUids:e.connectorUids}}async function runAttempt(e){let{log:t,deps:n,projectRoot:r,orgId:a,onOutput:o,signal:s,phase:c}=e,l,d;if(e.source.state===`existing`)l=e.source.ref;else{let i=await createSlackConnector({deps:n,projectRoot:r,orgId:a,slug:e.slug,onOutput:o,signal:s,phase:c,onCreated:e.onCreated,waitForWorkspace:async(e,t)=>{let i=await pollSlackWorkspace(n,r,e.id,a,o,t);return i.state===`connected`?i.workspace:void 0}});if(i.state===`failed`)return{state:`create-failed`};if(i.state===`unresolved`)return t.warning(`Vercel did not return an exact Slack connector UID for this request, so eve cannot attach or remove it safely.`),{state:`unresolved`};l=i.ref,i.via===`workspace`&&(d=i.workspace)}if(e.source.state===`existing`&&d===void 0){let e=await c(`Waiting for the Slack workspace connection...`,()=>pollSlackWorkspace(n,r,l.id,a,o,s));if(e.state===`timed-out`)return{state:`timed-out`,ref:l};if(e.state===`failed`)return{state:`failed`,ref:l,message:e.message};d=e.workspace}let f=await c(`Configuring Slack event delivery for this agent...`,()=>attachSlackConnector(n,r,l,o,s));return s?.throwIfAborted(),f.state===`attached`?d===void 0?{state:`attached`,ref:l}:{state:`attached`,ref:l,workspace:d}:{state:f.state,ref:l}}async function raceAttemptAgainstChoice(e){let t=new AbortController,n=e.outerSignal?AbortSignal.any([e.outerSignal,t.signal]):t.signal,r=e.run(n);try{let i=await Promise.race([r.then(e=>({via:`work`,outcome:e})),e.prompt.choice.then(e=>({via:`choice`,choice:e}))]);if(i.via===`work`)return i;t.abort();let a;try{a=await r}catch(e){if(!isAbortFromSignal(e,n))throw e}return{via:`choice`,choice:i.choice,settled:a}}catch(e){t.abort();try{await r}catch{}throw e}finally{e.prompt.close()}}async function inspectSlackbotConnectors(e,t,n,r,i=defaultDeps){let a=await findSlackConnector(i,t,(await(i.readProjectLink??readProjectLink)(t))?.projectId,`slack/${n}`,createPromptCommandOutput(e),r);if(a.state===`failed`)throw Error(a.message);return a}async function provisionSlackbot(e,t,n,r=defaultDeps,i={}){i.signal?.throwIfAborted();let o=createPromptCommandOutput(e),u={log:e,deps:r,projectRoot:t,onOutput:o},d=await(r.readProjectLink??readProjectLink)(t),p=d?.projectId,m=d?.orgId,h=`slack/${n}`,g=await withPhase(e,`Checking for an existing Slackbot...`,()=>findSlackConnector(r,t,p,h,o,i.signal));if(i.signal?.throwIfAborted(),g.state===`failed`)return e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${g.message}`),{state:`connector-lookup-failed`};if(p===void 0&&g.connectorUids.size>0)return e.warning("Could not verify which Slack connectors belong to this Vercel project, so eve did not create another one. Restore `.vercel/project.json`, then try again."),{state:`connector-lookup-failed`};let finishOutcome=async(t,n,r)=>{let i=n.state===`new`;switch(t.state){case`create-failed`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`unresolved`:if(i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`create-failed`};case`detach-failed`:return e.warning(`Could not remove the connector's existing trigger destination. Run \`vercel connect detach ${t.ref.uid} --yes\`, then \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\`.`),{state:`detach-failed`,connectorUid:t.ref.uid};case`attach-failed`:return e.warning(`Could not register this project as a trigger destination. Run \`vercel connect attach ${t.ref.uid} --triggers --trigger-path ${SLACK_CHANNEL_DEFAULT_ROUTE} --yes\` to enable event delivery.`),{state:`attach-failed`,connectorUid:t.ref.uid};case`attached`:return t.workspace===void 0?{state:`attached`,connectorUid:t.ref.uid}:{state:`attached`,connectorUid:t.ref.uid,chatUrl:t.workspace.workspaceUrl,workspaceName:t.workspace.workspaceName};case`failed`:return e.warning(`Could not verify the Slack workspace connection. ${t.message}`),{state:`installation-check-failed`,connectorUid:t.ref.uid};case`timed-out`:if(e.warning(`The Slackbot did not connect to a Slack workspace in time.`),i){let e=await r();if(e.state===`failed`)return cleanupFailureResult(e)}return{state:`not-installed`}}},cleanupNewAttempt=async(e,t)=>cleanupCreatedAttempt(u,{expectedUid:h,baselineConnectorUids:e.baselineConnectorUids,createdRef:t});function attemptInput(i,a){return{log:e,deps:r,projectRoot:t,orgId:m,slug:n,source:i,onOutput:o,onCreated:a}}async function runExistingConnector(t){let cleanupCurrentAttempt=async()=>({state:`clean`}),notInstalled=()=>(e.warning(`The existing Slack connector \`${t.ref.uid}\` is not connected to a Slack workspace. eve did not remove it because this run did not create it. If its original browser request is still open, complete it; otherwise run \`vercel connect remove ${t.ref.uid} --disconnect-all --yes\` before trying again.`),{state:`existing-not-installed`,connectorUid:t.ref.uid}),finishExistingOutcome=async e=>e.state===`timed-out`?notInstalled():finishOutcome(e,t,cleanupCurrentAttempt);if(i.awaitChoice!==void 0){let e=await raceAttemptAgainstChoice({prompt:i.awaitChoice({status:`Waiting for the existing Slack workspace connection...`,context:`Complete the original setup in the browser`,actions:[{value:`cancel`,label:`Stop waiting`}]}),outerSignal:i.signal,run:e=>runAttempt({...attemptInput(t,()=>{}),signal:e,phase:(e,t)=>t()})});return e.via===`work`?finishExistingOutcome(e.outcome):e.settled?.state===`attached`?finishExistingOutcome(e.settled):notInstalled()}return finishExistingOutcome(await runAttempt({...attemptInput(t,()=>{}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)}))}async function runUncontrolledAttempt(t){let n,cleanupCurrentAttempt=()=>cleanupNewAttempt(t,n),r=runAttempt({...attemptInput(t,e=>{n=e}),signal:i.signal,phase:(t,n)=>withPhase(e,t,n)});try{return await finishOutcome(await r,t,cleanupCurrentAttempt)}catch(e){throw i.signal?.aborted===!0&&await cleanupCurrentAttempt(),e}}async function runInteractiveAttempt(n,a){let s,cleanupCurrentAttempt=()=>cleanupNewAttempt(n,s),l=a({status:`Waiting for Slack setup to finish...`,context:`Complete setup in the browser, then wait while eve verifies the connection`,actions:[{value:`retry`,label:`Did your browser not open? Try again`},{value:`cancel`,label:`Cancel`}]}),u;try{u=await raceAttemptAgainstChoice({prompt:l,outerSignal:i.signal,run:t=>runAttempt({...attemptInput(n,e=>{s=e}),signal:t,phase:e.spinner===void 0?(e,t)=>t():(t,n)=>withPhase(e,t,n)})})}catch(e){throw await cleanupCurrentAttempt(),e}if(u.via===`work`)return{state:`finished`,result:await finishOutcome(u.outcome,n,cleanupCurrentAttempt)};if(u.settled?.state===`attached`)return{state:`finished`,result:await finishOutcome(u.settled,n,cleanupCurrentAttempt)};let d=await cleanupCurrentAttempt();if(d.state===`failed`)return{state:`finished`,result:cleanupFailureResult(d)};if(u.choice===`retry`){let n=await withPhase(e,`Checking existing Slack connectors...`,()=>listSlackConnectors(r,t,o,i.signal));return i.signal?.throwIfAborted(),n.state===`failed`?(e.warning(`Could not inspect existing Slack connectors, so eve did not create another one. ${n.message}`),{state:`finished`,result:{state:`connector-lookup-failed`}}):{state:`retry`,source:{state:`new`,baselineConnectorUids:new Set(n.connectors.map(e=>e.uid))}}}return{state:`finished`,result:{state:`cancelled`}}}if(g.state===`found`){let e=i.selectConnector===void 0?g.preferred??g.connectors[0]:await i.selectConnector(g.connectors,g.preferred);if(i.signal?.throwIfAborted(),e!==`create`)return runExistingConnector({state:`existing`,ref:e})}let _={state:`new`,baselineConnectorUids:g.connectorUids};if(i.awaitChoice===void 0)return runUncontrolledAttempt(_);for(;;){let e=await runInteractiveAttempt(_,i.awaitChoice);if(e.state===`finished`)return e.result;_=e.source}}async function reconcileSlackUid(e,t,n,r){if(n.state!==`attached`||n.connectorUid===r)return!0;let{patched:i}=await updateSlackChannelConnectorUid(join(t,`agent/channels/slack.ts`),n.connectorUid);return i?!0:(e.warning(`Could not patch agent/channels/slack.ts automatically. Update \`connectSlackCredentials("...")\` to \`"${n.connectorUid}"\` and run \`vercel deploy --prod\`.`),!1)}export{inspectSlackbotConnectors,parseCreatedSlackConnector,parseSlackConnectorDetails,pickSlackConnector,provisionSlackbot,reconcileSlackUid};
@@ -25,7 +25,7 @@ export type ResolvedProjectPath = {
25
25
  path: string;
26
26
  };
27
27
  /**
28
- * The `--headless` Vercel project flags. Read ONLY on the headless path (see
28
+ * The `--non-interactive` Vercel project flags. Read ONLY on the headless path (see
29
29
  * {@link ProvisioningMode}): an interactive run prompts for these decisions
30
30
  * instead, so the args never reach the prompt code.
31
31
  *
@@ -41,7 +41,7 @@ export interface ArgsHeadlessProject {
41
41
  project?: string;
42
42
  }
43
43
  /**
44
- * The `--headless` AI Gateway flags, read only on the headless path alongside
44
+ * The `--non-interactive` AI Gateway flags, read only on the headless path alongside
45
45
  * {@link ArgsHeadlessProject}.
46
46
  */
47
47
  export interface ArgsHeadlessAiGateway {
@@ -11,6 +11,12 @@ export interface SandboxBackendHandle<SO = Record<string, never>> {
11
11
  readonly session: SandboxSession;
12
12
  readonly useSessionFn: SandboxSessionUseFn<SO>;
13
13
  captureState(): Promise<SandboxBackendSessionState>;
14
+ /**
15
+ * Stops the underlying compute at an authored runtime boundary while
16
+ * preserving any backend state needed to reopen the durable session.
17
+ * Provider errors must reject this call.
18
+ */
19
+ stop(): Promise<void>;
14
20
  /**
15
21
  * Stops the underlying compute because the eve server is shutting
16
22
  * down; nothing may be left running afterwards. The session must
@@ -119,6 +119,21 @@ export interface SandboxSession extends Pick<AiSdkSandbox, "run" | "spawn" | "re
119
119
  */
120
120
  removePath(options: SandboxRemovePathOptions): Promise<void>;
121
121
  }
122
+ /**
123
+ * Sandbox session exposed to authored runtime callbacks through
124
+ * `ctx.getSandbox()`.
125
+ *
126
+ * Unlike the I/O-only session used during sandbox initialization, this handle
127
+ * always exposes a provider-backed `stop()` method.
128
+ */
129
+ export interface RuntimeSandboxSession extends SandboxSession {
130
+ /**
131
+ * Stops the backing sandbox compute while preserving the durable session.
132
+ * A later runtime callback reopens the session through its configured
133
+ * backend. Providers may also support resuming the same handle.
134
+ */
135
+ stop(): Promise<void>;
136
+ }
122
137
  /**
123
138
  * Internal sandbox session, used to construct the public {@link SandboxSession}.
124
139
  *
@@ -1,5 +1,5 @@
1
1
  import type { ToolExecutionOptions } from "ai";
2
- import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
+ import type { StandardJSONSchemaV1, StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
3
3
  import type { JsonObject } from "#shared/json.js";
4
4
  /**
5
5
  * Options forwarded from the AI SDK to the tool's {@link ToolDefinition.execute}
@@ -22,7 +22,7 @@ export interface InternalToolDefinition extends ToolDefinitionBase {
22
22
  inputSchema: JsonObject | null;
23
23
  outputSchema?: JsonObject;
24
24
  }
25
- export type PublicToolInputSchema<TInput = unknown> = StandardJSONSchemaV1<unknown, TInput> | JsonObject;
25
+ export type PublicToolInputSchema<TInput = unknown> = StandardSchemaV1<unknown, TInput> | StandardJSONSchemaV1<unknown, TInput> | JsonObject;
26
26
  export type PublicToolOutputSchema<TOutput = unknown> = StandardJSONSchemaV1<unknown, TOutput> | JsonObject;
27
27
  /**
28
28
  * Authored public tool definition shape. Identity is derived from the
@@ -7,11 +7,12 @@ import { type JsonObject } from "#shared/json.js";
7
7
  */
8
8
  export type ToolSchema<Input = unknown, Output = Input> = StandardSchemaV1<Input, Output> & StandardJSONSchemaV1<Input, Output>;
9
9
  /**
10
- * Any value accepted at a schema boundary: a live {@link ToolSchema}, a
11
- * JSON-Schema-capable Standard Schema, or plain JSON Schema data. Plain data
12
- * is runtime-validated by {@link parseJsonObject} during conversion.
10
+ * Any value accepted at a schema boundary: a live {@link ToolSchema}, a Zod 3
11
+ * Standard Schema, a JSON-Schema-capable Standard Schema, or plain JSON Schema
12
+ * data. Plain data is runtime-validated by {@link parseJsonObject} during
13
+ * conversion.
13
14
  */
14
- export type ToolSchemaSource = StandardJSONSchemaV1 | Record<string, unknown>;
15
+ export type ToolSchemaSource = StandardJSONSchemaV1 | StandardSchemaV1 | Record<string, unknown>;
15
16
  /** `null` and `undefined` pass through every conversion untouched. */
16
17
  type SchemaResult<TSource, TResult> = TSource extends null | undefined ? TSource : TResult;
17
18
  /**
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{toErrorMessage}from"#shared/errors.js";import{parseJsonObject}from"#shared/json.js";const rehydratedSchemas={input:new WeakMap,output:new WeakMap};function toInputSchema(e){return toSchema(e,`input`)}function toOutputSchema(e){return toSchema(e,`output`)}function serializeInputSchema(e){return serializeSchema(e,`input`)}function serializeOutputSchema(e){return serializeSchema(e,`output`)}function isToolSchema(e){if(typeof e!=`object`||!e||!(`~standard`in e))return!1;let t=e[`~standard`];if(typeof t!=`object`||!t)return!1;let n=t,r=n.jsonSchema;return typeof n.validate==`function`&&typeof r==`object`&&!!r&&typeof r.input==`function`&&typeof r.output==`function`}const UNSPECIFIED_INPUT_SCHEMA=z.fromJSONSchema({});function toSchema(e,t){if(e==null||isToolSchema(e))return e;let n=rehydratedSchemas[t],i=n.get(e);return i===void 0&&(i=rehydrateJsonSchema(toJsonObject(e,t)),n.set(e,i)),i}function rehydrateJsonSchema(n){try{return z.fromJSONSchema(n,{defaultTarget:`draft-7`})}catch{}try{return z.fromJSONSchema(n,{defaultTarget:`draft-2020-12`})}catch(e){return console.warn(`[eve] Tool schema uses JSON Schema features outside local validation support; passing input through unvalidated: ${toErrorMessage(e)}`),toPassthroughSchema(n)}}function toPassthroughSchema(e){let emit=()=>structuredClone(e);return{"~standard":{version:1,vendor:`eve`,validate:e=>({value:e}),jsonSchema:{input:emit,output:emit}}}}function serializeSchema(e,t){return e==null?e:toJsonObject(e,t)}function toJsonObject(e,t){let{$schema:r,...i}=isStandardJsonSchema(e)?parseJsonObject(e[`~standard`].jsonSchema[t]({target:`draft-07`})):parseJsonObject(e);return i}function isStandardJsonSchema(e){return typeof e==`object`&&!!e&&`~standard`in e}export{UNSPECIFIED_INPUT_SCHEMA,isToolSchema,serializeInputSchema,serializeOutputSchema,toInputSchema,toOutputSchema};
1
+ import{z}from"#compiled/zod/index.js";import{toErrorMessage}from"#shared/errors.js";import{parseJsonObject}from"#shared/json.js";import{asSchema}from"ai";const rehydratedSchemas={input:new WeakMap,output:new WeakMap};function toInputSchema(e){return toSchema(e,`input`)}function toOutputSchema(e){return toSchema(e,`output`)}function serializeInputSchema(e){return serializeSchema(e,`input`)}function serializeOutputSchema(e){return serializeSchema(e,`output`)}function isToolSchema(e){let t=getStandardSchemaProperties(e);if(t===void 0)return!1;let n=t.jsonSchema;return typeof t.validate==`function`&&typeof n==`object`&&!!n&&typeof n.input==`function`&&typeof n.output==`function`}const UNSPECIFIED_INPUT_SCHEMA=z.fromJSONSchema({});function toSchema(e,t){if(e==null||isToolSchema(e))return e;let n=rehydratedSchemas[t],r=n.get(e);return r===void 0&&(r=rehydrateJsonSchema(toJsonObject(e,t)),n.set(e,r)),r}function rehydrateJsonSchema(n){try{return z.fromJSONSchema(n,{defaultTarget:`draft-7`})}catch{}try{return z.fromJSONSchema(n,{defaultTarget:`draft-2020-12`})}catch(e){return console.warn(`[eve] Tool schema uses JSON Schema features outside local validation support; passing input through unvalidated: ${toErrorMessage(e)}`),toPassthroughSchema(n)}}function toPassthroughSchema(e){let emit=()=>structuredClone(e);return{"~standard":{version:1,vendor:`eve`,validate:e=>({value:e}),jsonSchema:{input:emit,output:emit}}}}function serializeSchema(e,t){return e==null?e:toJsonObject(e,t)}function toJsonObject(e,t){let i=getStandardSchemaProperties(e),a=i?.jsonSchema,o=typeof a==`object`&&a?a[t]:void 0,s=typeof i?.vendor==`string`?i.vendor:`unknown`;if(i!==void 0&&typeof o!=`function`&&s===`zod`){if(t===`input`){let{$schema:t,...i}=parseJsonObject(asSchema(e).jsonSchema);return i}throw Error(`Zod 3 cannot emit an output JSON Schema. Upgrade to Zod 4 or provide a plain JSON Schema object.`)}if(i!==void 0&&typeof o!=`function`)throw Error(`Standard Schema vendor "${s}" does not support JSON Schema conversion. Provide a Standard Schema implementation with JSON Schema conversion or a plain JSON Schema object.`);let{$schema:c,...l}=parseJsonObject(i===void 0?e:o({target:`draft-07`}));return l}function getStandardSchemaProperties(e){if(typeof e!=`object`||!e||!(`~standard`in e))return;let t=e[`~standard`];return typeof t==`object`&&t?t:void 0}export{UNSPECIFIED_INPUT_SCHEMA,isToolSchema,serializeInputSchema,serializeOutputSchema,toInputSchema,toOutputSchema};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DbYZLG0h.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-DwyRde1N.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-DbYZLG0h.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-DwyRde1N.js";
2
2
 
3
3
  export { useEveAgent };
@@ -1,43 +1,9 @@
1
- import { type SpanContext, type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
- import type { InstrumentationContextRunner, InstrumentationProviderDefinition, InstrumentationTurnTerminalEvent } from "#harness/instrumentation-lifecycle.js";
1
+ import { type Tracer } from "#compiled/@opentelemetry/api/index.js";
2
+ import type { AgentSpanIdGenerator } from "#tracing/agent-span-id-generator.js";
3
+ import type { AgentTraceStateStore } from "#tracing/agent-trace-state.js";
4
+ import type { InstrumentationContextRunner, InstrumentationProviderDefinition } from "#harness/instrumentation-lifecycle.js";
3
5
  /** Sized so an ordinary session stays one trace and only an outsized one rolls. */
4
6
  export declare const SESSION_WINDOW_TURN_LIMIT = 200;
5
- export interface AgentSessionTraceState {
6
- readonly agentName?: string;
7
- readonly channelKind?: string;
8
- readonly context: SpanContext;
9
- readonly rootSessionId: string;
10
- readonly turnsInWindow: number;
11
- readonly window: number;
12
- }
13
- export interface AgentTurnTraceState {
14
- readonly context: SpanContext;
15
- readonly rootSessionId: string;
16
- readonly sequence: number;
17
- readonly terminal?: {
18
- readonly error?: unknown;
19
- readonly type: InstrumentationTurnTerminalEvent["type"];
20
- };
21
- }
22
- /** Provider-owned serializable storage for durable agent trace state. */
23
- export interface AgentTraceStateStore {
24
- deleteSession(sessionId: string): void | PromiseLike<void>;
25
- deleteTurn(sessionId: string, turnId: string): void | PromiseLike<void>;
26
- getSession(sessionId: string): AgentSessionTraceState | undefined | PromiseLike<AgentSessionTraceState | undefined>;
27
- getTurn(sessionId: string, turnId: string): AgentTurnTraceState | undefined | PromiseLike<AgentTurnTraceState | undefined>;
28
- setSession(sessionId: string, state: AgentSessionTraceState): void | PromiseLike<void>;
29
- setTurn(sessionId: string, turnId: string, state: AgentTurnTraceState): void | PromiseLike<void>;
30
- }
31
- /** In-memory trace state used by tests and non-durable runtimes. */
32
- export declare class InMemoryAgentTraceStateStore implements AgentTraceStateStore {
33
- #private;
34
- deleteSession(sessionId: string): void;
35
- deleteTurn(sessionId: string, turnId: string): void;
36
- getSession(sessionId: string): AgentSessionTraceState | undefined;
37
- getTurn(sessionId: string, turnId: string): AgentTurnTraceState | undefined;
38
- setSession(sessionId: string, state: AgentSessionTraceState): void;
39
- setTurn(sessionId: string, turnId: string, state: AgentTurnTraceState): void;
40
- }
41
7
  export interface AgentOtelInstrumentationInput {
42
8
  /**
43
9
  * Capture model prompts/responses and tool call inputs/outputs as span
@@ -46,6 +12,7 @@ export interface AgentOtelInstrumentationInput {
46
12
  */
47
13
  readonly captureContent?: boolean;
48
14
  readonly frameworkVersion: string;
15
+ readonly idGenerator: AgentSpanIdGenerator;
49
16
  readonly stateStore: AgentTraceStateStore;
50
17
  readonly tracer: Tracer;
51
18
  }