eve 0.74.0 → 0.75.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 (186) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/channel/auth/result.d.ts +4 -0
  3. package/dist/src/channel/auth/result.js +1 -0
  4. package/dist/src/channel/types.d.ts +14 -2
  5. package/dist/src/chunks/{use-eve-agent-mP0M7SrL.js → use-eve-agent-B2Kne9z6.js} +7 -2
  6. package/dist/src/chunks/{use-eve-agent-DOOXadF0.js → use-eve-agent-DK_T88EP.js} +7 -2
  7. package/dist/src/cli/commands/integration-connect.d.ts +2 -0
  8. package/dist/src/cli/commands/integration-connect.js +1 -1
  9. package/dist/src/cli/commands/integration-setup.js +1 -1
  10. package/dist/src/cli/commands/registry-declared-setups.d.ts +19 -0
  11. package/dist/src/cli/commands/registry-declared-setups.js +1 -1
  12. package/dist/src/cli/commands/registry-recovery.d.ts +3 -1
  13. package/dist/src/cli/commands/registry-recovery.js +1 -1
  14. package/dist/src/cli/commands/registry.d.ts +12 -4
  15. package/dist/src/cli/commands/registry.js +1 -1
  16. package/dist/src/cli/dev/tui/registry-result-message.js +1 -1
  17. package/dist/src/cli/dev/tui/setup-commands.d.ts +2 -0
  18. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  19. package/dist/src/client/index.d.ts +1 -0
  20. package/dist/src/client/session.d.ts +1 -1
  21. package/dist/src/client/session.js +1 -1
  22. package/dist/src/client/sessions.d.ts +1 -1
  23. package/dist/src/client/types.d.ts +6 -0
  24. package/dist/src/compiled/.vendor-stamp.json +1 -1
  25. package/dist/src/compiler/extension-compatibility.d.ts +18 -12
  26. package/dist/src/compiler/extension-compatibility.js +1 -1
  27. package/dist/src/context/dynamic-connection-lifecycle.d.ts +6 -0
  28. package/dist/src/context/dynamic-connection-lifecycle.js +1 -1
  29. package/dist/src/context/keys.d.ts +4 -1
  30. package/dist/src/context/keys.js +1 -1
  31. package/dist/src/context/providers/sandbox.js +1 -1
  32. package/dist/src/context/providers/tool-stubs-key.d.ts +8 -0
  33. package/dist/src/context/providers/tool-stubs-key.js +1 -0
  34. package/dist/src/context/providers/tool-stubs.d.ts +10 -0
  35. package/dist/src/context/providers/tool-stubs.js +1 -0
  36. package/dist/src/context/run-step.js +1 -1
  37. package/dist/src/evals/index.d.ts +1 -0
  38. package/dist/src/evals/runner/execute-task.js +1 -1
  39. package/dist/src/evals/session-manager.d.ts +2 -0
  40. package/dist/src/evals/session-manager.js +1 -1
  41. package/dist/src/eve-channel/create-request.d.ts +2 -0
  42. package/dist/src/eve-channel/index.js +1 -1
  43. package/dist/src/eve-channel/request.js +1 -1
  44. package/dist/src/execution/agent-sessions/context.d.ts +2 -0
  45. package/dist/src/execution/agent-sessions/context.js +1 -1
  46. package/dist/src/execution/agent-sessions/steps.js +1 -1
  47. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  48. package/dist/src/execution/dynamic-connection-recovery.d.ts +14 -0
  49. package/dist/src/execution/dynamic-connection-recovery.js +1 -0
  50. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  51. package/dist/src/execution/forward-session-input.js +1 -1
  52. package/dist/src/execution/legacy-session/authorization.js +1 -1
  53. package/dist/src/execution/legacy-session/completion-step.js +1 -1
  54. package/dist/src/execution/legacy-session/inbox.js +1 -1
  55. package/dist/src/execution/legacy-session/interrupt-step.js +1 -1
  56. package/dist/src/execution/proxied-deliver-step.js +1 -1
  57. package/dist/src/execution/runtime-context.js +1 -1
  58. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  59. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  60. package/dist/src/execution/sandbox/bindings/just-bash.js +1 -1
  61. package/dist/src/execution/sandbox/bindings/microsandbox-lifecycle.js +1 -1
  62. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  63. package/dist/src/execution/sandbox/ensure.d.ts +3 -1
  64. package/dist/src/execution/sandbox/ensure.js +1 -1
  65. package/dist/src/execution/session/active-turn.js +1 -1
  66. package/dist/src/execution/session/admission.js +1 -1
  67. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  68. package/dist/src/execution/session/end-sandbox-step.d.ts +12 -0
  69. package/dist/src/execution/session/end-sandbox-step.js +1 -0
  70. package/dist/src/execution/session/finalization.js +1 -1
  71. package/dist/src/execution/session/handoff-steps.js +1 -1
  72. package/dist/src/execution/session/handoff.d.ts +1 -1
  73. package/dist/src/execution/session/handoff.js +1 -1
  74. package/dist/src/execution/session/program.js +1 -1
  75. package/dist/src/execution/session/timeout-steps.js +1 -1
  76. package/dist/src/execution/session/turn-step.js +1 -1
  77. package/dist/src/execution/session-inbox/inbox.d.ts +6 -1
  78. package/dist/src/execution/session-inbox/inbox.js +1 -1
  79. package/dist/src/execution/session-inbox/release-step.js +1 -1
  80. package/dist/src/execution/session-inbox/resume.d.ts +2 -1
  81. package/dist/src/execution/session-inbox/resume.js +1 -1
  82. package/dist/src/execution/session-workflow-tool-run.js +1 -1
  83. package/dist/src/execution/settle-cancelled-turn-step.js +1 -1
  84. package/dist/src/execution/tasks/model-step.js +1 -1
  85. package/dist/src/execution/tasks/steps.js +1 -1
  86. package/dist/src/execution/tasks/table.d.ts +7 -1
  87. package/dist/src/execution/tasks/table.js +1 -1
  88. package/dist/src/execution/tool-stubs/playback.d.ts +11 -0
  89. package/dist/src/execution/tool-stubs/playback.js +1 -0
  90. package/dist/src/execution/tool-stubs/steps.d.ts +18 -0
  91. package/dist/src/execution/tool-stubs/steps.js +1 -0
  92. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  93. package/dist/src/execution/tools/connection-tools.d.ts +0 -6
  94. package/dist/src/execution/tools/connection-tools.js +2 -2
  95. package/dist/src/execution/tools/workflow/authorization-completion.js +1 -1
  96. package/dist/src/execution/tools/workflow/body.js +1 -1
  97. package/dist/src/execution/tools/workflow/serve.js +1 -1
  98. package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
  99. package/dist/src/execution/workflow-runtime.js +1 -1
  100. package/dist/src/execution/workflow-webhook-route.js +1 -1
  101. package/dist/src/harness/coordination.js +1 -1
  102. package/dist/src/harness/hitl/approved-calls.d.ts +2 -0
  103. package/dist/src/harness/hitl/approved-calls.js +1 -1
  104. package/dist/src/harness/hitl/index.d.ts +9 -1
  105. package/dist/src/harness/hitl/index.js +1 -1
  106. package/dist/src/harness/hitl/intake.js +1 -1
  107. package/dist/src/harness/model-call/run.js +1 -1
  108. package/dist/src/harness/proxy-input-requests.d.ts +17 -6
  109. package/dist/src/harness/proxy-input-requests.js +1 -1
  110. package/dist/src/harness/session-machine/current.d.ts +4 -0
  111. package/dist/src/harness/session-machine/current.js +1 -1
  112. package/dist/src/harness/step/after-model.js +1 -1
  113. package/dist/src/harness/step/context.d.ts +7 -2
  114. package/dist/src/harness/step/context.js +1 -1
  115. package/dist/src/harness/tool-call-io.js +1 -1
  116. package/dist/src/harness/tool-loop.js +1 -1
  117. package/dist/src/harness/tools.js +1 -1
  118. package/dist/src/internal/application/package.js +1 -1
  119. package/dist/src/internal/invocation/workflow-execution.js +1 -1
  120. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  121. package/dist/src/internal/workflow/cancel-expired-development-run.js +1 -1
  122. package/dist/src/protocol/routes.d.ts +4 -0
  123. package/dist/src/protocol/routes.js +1 -1
  124. package/dist/src/public/channels/auth.d.ts +21 -4
  125. package/dist/src/public/channels/auth.js +1 -1
  126. package/dist/src/public/channels/mcp.js +1 -1
  127. package/dist/src/public/schedules/providers/in-memory.js +1 -1
  128. package/dist/src/public/schedules/providers/vercel.js +1 -1
  129. package/dist/src/public/schedules/subscription.d.ts +0 -1
  130. package/dist/src/sandbox/state.d.ts +1 -0
  131. package/dist/src/self-modification/extension/subagents/agent/instructions.js +1 -1
  132. package/dist/src/self-modification/extension/subagents/agent/tools/registry_add.js +1 -1
  133. package/dist/src/setup/flows/registry-session.d.ts +10 -2
  134. package/dist/src/setup/flows/registry-session.js +1 -1
  135. package/dist/src/setup/flows/registry.d.ts +2 -0
  136. package/dist/src/setup/flows/registry.js +1 -1
  137. package/dist/src/setup/integrations/shared/prerequisite.d.ts +8 -0
  138. package/dist/src/setup/integrations/shared/prerequisite.js +1 -1
  139. package/dist/src/setup/registry-setup-client.js +1 -1
  140. package/dist/src/setup/scaffold/create/project.js +1 -1
  141. package/dist/src/setup/scaffold/index.js +1 -1
  142. package/dist/src/setup/vercel-project.d.ts +1 -2
  143. package/dist/src/setup/vercel-project.js +0 -0
  144. package/dist/src/shared/sandbox-provider.d.ts +9 -2
  145. package/dist/src/subagents/adapter.d.ts +3 -2
  146. package/dist/src/subagents/adapter.js +1 -1
  147. package/dist/src/subagents/callback-route.js +1 -1
  148. package/dist/src/subagents/hitl-proxy.d.ts +4 -3
  149. package/dist/src/subagents/hitl-proxy.js +1 -1
  150. package/dist/src/subagents/parent-notification.js +1 -1
  151. package/dist/src/svelte/index.js +1 -1
  152. package/dist/src/svelte/use-eve-agent.js +1 -1
  153. package/dist/src/tool-stubs/execute.d.ts +13 -0
  154. package/dist/src/tool-stubs/execute.js +1 -0
  155. package/dist/src/tool-stubs/output.d.ts +4 -0
  156. package/dist/src/tool-stubs/output.js +1 -0
  157. package/dist/src/tool-stubs/playback.d.ts +15 -0
  158. package/dist/src/tool-stubs/playback.js +1 -0
  159. package/dist/src/tool-stubs/rules.d.ts +3 -0
  160. package/dist/src/tool-stubs/rules.js +1 -0
  161. package/dist/src/tool-stubs/schema.d.ts +4 -0
  162. package/dist/src/tool-stubs/schema.js +1 -0
  163. package/dist/src/tool-stubs/target.d.ts +8 -0
  164. package/dist/src/tool-stubs/target.js +1 -0
  165. package/dist/src/tool-stubs/types.d.ts +56 -0
  166. package/dist/src/tool-stubs/types.js +1 -0
  167. package/dist/src/tool-stubs/validate-targets.d.ts +6 -0
  168. package/dist/src/tool-stubs/validate-targets.js +1 -0
  169. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  170. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  171. package/dist/src/vue/index.js +1 -1
  172. package/dist/src/vue/use-eve-agent.js +1 -1
  173. package/docs/concepts/sessions-runs-and-streaming.md +2 -2
  174. package/docs/evals/meta.json +10 -1
  175. package/docs/evals/overview.mdx +2 -0
  176. package/docs/evals/tool-stubs.mdx +257 -0
  177. package/docs/extensions.md +1 -1
  178. package/docs/guides/auth-and-route-protection.md +25 -0
  179. package/docs/guides/dynamic-capabilities.md +10 -3
  180. package/docs/guides/frontend/nextjs.mdx +17 -4
  181. package/docs/sandbox/index.mdx +10 -2
  182. package/docs/subagents/index.mdx +1 -1
  183. package/docs/tools/human-in-the-loop.md +1 -1
  184. package/docs/tools/overview.mdx +8 -4
  185. package/docs/tools/workflows.mdx +15 -7
  186. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # eve
2
2
 
3
+ ## 0.75.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 32af96d: Rename custom sandbox provider handle hooks from `onSessionStop()` and `onSessionDelete()` to `onSandboxStop()` and `onSandboxDelete()` so handle lifecycle names describe the sandbox resource they operate on.
8
+
9
+ ### Patch Changes
10
+
11
+ - 84793ed: Schedule creation no longer accepts an initial state: schedules are created active by default (or completed if a one-time schedule is already past). Use the existing enable and disable operations to change a schedule's state after creation.
12
+ - a3c2f40: Add explicitly authorized, session-scoped JSON tool stubs with argument matching and outcome sequences that continue across turns within the same session. Each rule specifies `outcome` or nonempty `outcomes`, with a JSON `response` in each outcome; eve's internal workflow recovery reuses recorded outcomes without consuming another entry.
13
+
14
+ Rules use first-match-wins ordering and explicit slash-separated paths for local child tools. Grant replacement permission on individual `vercelOidc` subject entries or in a custom authenticator's result; existing sessions follow normal channel authentication.
15
+
16
+ Invalid static tool paths and unsupported matcher features fail session creation. Unused rules produce eval warnings. Deployment handoffs use a new checkpoint version for all sessions, so sessions cannot hand off to deployments running an older version.
17
+ - 20c1317: Keep a tool approval answered before a cancelled response resolved, instead of restoring it and resolving it again on the next message. An approved call the cancellation interrupts while it runs gets an interrupted result and is not run again, and a message sent with the answer is kept once.
18
+ - 04d47bc: A typed reply now answers a tool approval or session-limit prompt proxied from a subagent, the same way it answers a subagent's `ctx.ask()` question. On text-only channels such as Linq, Twilio, and Linear, replying `approve` or `continue` resumes the subagent instead of reaching the parent model while the subagent stays parked. When a subagent raises several prompts at once, each reply answers the first open one.
19
+ - bf82cfa: Keep conversation sessions available after a dynamic connection resolver fails, so a later message can retry once the dependency recovers.
20
+ - 89704cb: When a registry item's setup needs a logged-in Vercel CLI, `/add` in `eve dev` now offers to run `vercel login` and then finishes setup without reinstalling the item. Items whose setup fails after their files are installed now show as "setup not finished" with the reason, instead of "Couldn't add". `eve add --non-interactive` reports a `vercel login` prerequisite (exit 2) instead of a raw `vercel connect` failure. eve now detects a logged-out Vercel CLI from `vercel whoami --format json`, so newer CLIs that print only "Logged out." are no longer misreported as a transient error. The self-modification agent no longer describes an item as added before its setup panel has run.
21
+ - 6ab30a5: A subagent's tool approval now stays open on the parent until the subagent settles it. If the subagent's response policy refuses the person who answered, someone else can still answer it, by text or button, instead of the prompt disappearing while the subagent waits. The parent closes the prompt when it relays the subagent's own `input.resolved`, so channels such as Telegram and Discord clear its buttons.
22
+ - 33a95cf: Invoke sandbox provider cleanup when a durable session completes, expires, or fails. Custom providers can implement `onSessionEnd()` to release session-owned resources directly from persisted state.
23
+ - 1cfb212: Tool stubs can now throw an error immediately or mix errors and responses in an outcome sequence. Evals can assert expected tool failures and recovery without treating injected errors as broken stubs.
24
+
3
25
  ## 0.74.0
4
26
 
5
27
  ### Minor Changes
@@ -0,0 +1,4 @@
1
+ import type { SessionAuthContext } from "#channel/types.js";
2
+ import type { AuthResult } from "#public/channels/auth.js";
3
+ /** Do not save this request's stub permission or forward it to another agent. */
4
+ export declare function sessionAuthFromResult(result: AuthResult): SessionAuthContext;
@@ -0,0 +1 @@
1
+ function sessionAuthFromResult(e){let{allowToolStubs:t,...n}=e;return n}export{sessionAuthFromResult};
@@ -11,6 +11,7 @@ import type { JsonObject } from "#shared/json.js";
11
11
  import type { InstrumentationDecision } from "#shared/instrumentation-decision.js";
12
12
  import type { ForwardedTraceAssertion } from "#shared/forwarded-trace-policy.js";
13
13
  import type { ConversationContext } from "#shared/conversation-context.js";
14
+ import type { StubScope } from "#tool-stubs/types.js";
14
15
  export type { ContextAccessor } from "#context/key.js";
15
16
  export type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
16
17
  import type { ChannelInstrumentationProjection } from "#channel/instrumentation.js";
@@ -295,9 +296,12 @@ export interface SubagentInputRequestHookPayload {
295
296
  readonly kind: "subagent-input-request";
296
297
  readonly subagentName: string;
297
298
  }
298
- /** Responder-specific lifecycle event forwarded from a delegated child. */
299
+ /**
300
+ * Lifecycle event forwarded from a delegated child: responder and sign-in progress, and the
301
+ * resolution of its requests. The parent relays it unchanged.
302
+ */
299
303
  export type SubagentAuthorizationEvent = Extract<UnstampedMessageStreamEvent, {
300
- type: "approval.candidate" | "approval.settled" | "authorization.required" | "authorization.completed";
304
+ type: "approval.candidate" | "approval.settled" | "authorization.required" | "authorization.completed" | "input.resolved";
301
305
  }>;
302
306
  /**
303
307
  * Proxy payload sent from a child subagent while it waits for authorization.
@@ -359,6 +363,14 @@ export interface SessionCapabilities {
359
363
  * subagent tool wrapper).
360
364
  */
361
365
  export interface RunInput {
366
+ /**
367
+ * @internal Set by the server after it authorizes tool stubs.
368
+ * Local subagents match rules qualified by their full path, such as researcher/list_tasks.
369
+ * The root session tracks positions per rule; subagent sessions at the same path
370
+ * share those positions. Unprefixed rules apply only to root tools.
371
+ * Remote agents do not receive these stubs.
372
+ */
373
+ readonly toolStubs?: StubScope;
362
374
  /** Server-supplied provenance inherited by locally delegated scheduled work. */
363
375
  readonly schedule?: import("#context/session-schedule.js").SessionSchedule;
364
376
  readonly adapter: ChannelAdapter<any>;
@@ -15,6 +15,7 @@ const EVE_SESSION_CANCEL_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/c
15
15
  const EVE_SESSION_COMPACT_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`;
16
16
  const EVE_SESSION_CLEAR_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`;
17
17
  const EVE_SESSION_RESET_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`;
18
+ const EVE_SESSION_STUBS_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/stubs`;
18
19
  const EVE_SESSION_STREAM_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`;
19
20
  const EVE_SUBAGENT_STREAM_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:parentSessionId/subagents/:callId/:childSessionId/stream`;
20
21
  const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
@@ -2245,7 +2246,7 @@ var ClientSession = class ClientSession {
2245
2246
  this.#state = state;
2246
2247
  }
2247
2248
  static async create(context, input) {
2248
- const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true);
2249
+ const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true, input.stubs);
2249
2250
  const { sessionId } = await readAcceptedMessage(response);
2250
2251
  const session = new ClientSession(context, {
2251
2252
  sessionId,
@@ -2447,7 +2448,10 @@ async function postSessionSend(context, path, input) {
2447
2448
  }
2448
2449
  async function postCreateSession(context, options) {
2449
2450
  const headers = await context.resolveHeaders(options.headers);
2451
+ const body = options.stubs === void 0 ? void 0 : JSON.stringify({ stubs: options.stubs });
2452
+ if (body !== void 0) headers.set("content-type", "application/json");
2450
2453
  const response = await fetch(createClientUrl(context.host, EVE_SESSION_ROUTE_PATH), {
2454
+ body,
2451
2455
  headers,
2452
2456
  method: "POST",
2453
2457
  redirect: context.redirect,
@@ -2462,9 +2466,10 @@ async function postCreateSession(context, options) {
2462
2466
  function isSessionNotReady(error) {
2463
2467
  return error instanceof ClientError && error.status === 409 && error.code === "session_not_ready";
2464
2468
  }
2465
- async function postTurn(context, path, input, requireMessage) {
2469
+ async function postTurn(context, path, input, requireMessage, stubs) {
2466
2470
  const body = createMessageBody(input, requireMessage);
2467
2471
  if (body === null) throw new Error(requireMessage ? "Creating a session requires a non-empty message." : "A session turn requires a non-empty message or inputResponses.");
2472
+ if (stubs !== void 0) body.stubs = stubs;
2468
2473
  const headers = await context.resolveHeaders(input.headers);
2469
2474
  headers.set("content-type", "application/json");
2470
2475
  const response = await fetch(createClientUrl(context.host, path), {
@@ -14,6 +14,7 @@ const EVE_SESSION_CANCEL_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/c
14
14
  const EVE_SESSION_COMPACT_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/compact`;
15
15
  const EVE_SESSION_CLEAR_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/clear`;
16
16
  const EVE_SESSION_RESET_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/reset`;
17
+ const EVE_SESSION_STUBS_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/stubs`;
17
18
  const EVE_SESSION_STREAM_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:sessionId/stream`;
18
19
  const EVE_SUBAGENT_STREAM_ROUTE_PATTERN = `${EVE_SESSION_ROUTE_PATH}/:parentSessionId/subagents/:callId/:childSessionId/stream`;
19
20
  const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
@@ -2244,7 +2245,7 @@ var ClientSession = class ClientSession {
2244
2245
  this.#state = state;
2245
2246
  }
2246
2247
  static async create(context, input) {
2247
- const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true);
2248
+ const response = await postTurn(context, EVE_SESSION_ROUTE_PATH, input, true, input.stubs);
2248
2249
  const { sessionId } = await readAcceptedMessage(response);
2249
2250
  const session = new ClientSession(context, {
2250
2251
  sessionId,
@@ -2446,7 +2447,10 @@ async function postSessionSend(context, path, input) {
2446
2447
  }
2447
2448
  async function postCreateSession(context, options) {
2448
2449
  const headers = await context.resolveHeaders(options.headers);
2450
+ const body = options.stubs === void 0 ? void 0 : JSON.stringify({ stubs: options.stubs });
2451
+ if (body !== void 0) headers.set("content-type", "application/json");
2449
2452
  const response = await fetch(createClientUrl(context.host, EVE_SESSION_ROUTE_PATH), {
2453
+ body,
2450
2454
  headers,
2451
2455
  method: "POST",
2452
2456
  redirect: context.redirect,
@@ -2461,9 +2465,10 @@ async function postCreateSession(context, options) {
2461
2465
  function isSessionNotReady(error) {
2462
2466
  return error instanceof ClientError && error.status === 409 && error.code === "session_not_ready";
2463
2467
  }
2464
- async function postTurn(context, path, input, requireMessage) {
2468
+ async function postTurn(context, path, input, requireMessage, stubs) {
2465
2469
  const body = createMessageBody(input, requireMessage);
2466
2470
  if (body === null) throw new Error(requireMessage ? "Creating a session requires a non-empty message." : "A session turn requires a non-empty message or inputResponses.");
2471
+ if (stubs !== void 0) body.stubs = stubs;
2467
2472
  const headers = await context.resolveHeaders(input.headers);
2468
2473
  headers.set("content-type", "application/json");
2469
2474
  const response = await fetch(createClientUrl(context.host, path), {
@@ -2,6 +2,7 @@ import { cleanupCreatedConnectionConnector, setupConnectionConnector, type Conne
2
2
  import { ensureVercelProject, type EnsureVercelProjectDeps } from "#setup/flows/ensure-vercel-project.js";
3
3
  import { readProjectLink } from "#setup/project-resolution.js";
4
4
  import { type Prompter } from "#setup/prompter.js";
5
+ import { requireAuth } from "#setup/vercel-project.js";
5
6
  import { updateConnectionConnectorUid } from "#setup/scaffold/update/update-connection-connector.js";
6
7
  import type { RegistryCommandLogger } from "./registry.js";
7
8
  export interface IntegrationConnectOptions {
@@ -16,6 +17,7 @@ export interface IntegrationConnectDependencies {
16
17
  ensureVercelProject: typeof ensureVercelProject;
17
18
  ensureVercelProjectDeps?: Partial<EnsureVercelProjectDeps>;
18
19
  readProjectLink: typeof readProjectLink;
20
+ requireAuth: typeof requireAuth;
19
21
  setupConnectionConnector: typeof setupConnectionConnector;
20
22
  cleanupCreatedConnectionConnector: typeof cleanupCreatedConnectionConnector;
21
23
  updateConnectionConnectorUid: typeof updateConnectionConnectorUid;
@@ -1 +1 @@
1
- import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{readProjectLink}from"#setup/project-resolution.js";import{WizardCancelledError}from"#setup/step.js";import{cleanupCreatedConnectionConnector,setupConnectionConnector}from"#setup/connection-connector.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{createHeadlessPrompter}from"#setup/headless.js";import{SetupPrerequisiteRequired}from"#setup/integrations/shared/prerequisite.js";import{resolveIntegrationVercelProject}from"#setup/integrations/shared/vercel-project.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{updateConnectionConnectorUid}from"#setup/scaffold/update/update-connection-connector.js";const defaultDependencies={ensureVercelProject,readProjectLink,setupConnectionConnector,cleanupCreatedConnectionConnector,updateConnectionConnectorUid};async function runIntegrationConnect(e){let t={...defaultDependencies,...e.dependencies},n=e.options?.nonInteractive===!0,r=t.createPrompter?.()??(n?createHeadlessPrompter(()=>{}):createPrompter()),i=e.options?.signal;r.intro(`Set up ${e.slug}`);let a=await t.readProjectLink(e.appRoot);if(a===void 0){if(n)a=await resolveIntegrationVercelProject({appRoot:e.appRoot,integration:e.slug,signal:i,deps:{readProjectLink:t.readProjectLink}});else try{a=await t.ensureVercelProject({appRoot:e.appRoot,prompter:r,signal:i,teamSelectMessage:()=>`You need to link to a project to use ${e.slug} through Vercel Connect.\n\nSelect your team`,deps:t.ensureVercelProjectDeps})}catch(e){if(e instanceof WizardCancelledError)return;throw e}}let o={log:r.log,prompter:r,projectRoot:e.appRoot,slug:e.slug,service:e.service,creationType:e.options?.creationType,connectionMethod:e.options?.connectionMethod,principalType:e.options?.principalType,canonicalConnectorName:e.canonicalConnectorName??e.slug,project:a,signal:i},s=await t.setupConnectionConnector(o),c=join(e.appRoot,`agent`,`connections`,`${e.slug}.ts`);if(!(await t.updateConnectionConnectorUid(c,s.connectorUid)).patched)throw s.kind===`created`&&await t.cleanupCreatedConnectionConnector({log:r.log,projectRoot:e.appRoot,connectorId:s.connectorId,orgId:a.orgId}),Error(`Could not update the connector in agent/connections/${e.slug}.ts.`);r.outro(`Connection ${e.slug} set up.`)}async function runIntegrationConnectCommand(e,t,n,r,i,a={},o=defaultDependencies){let s=createRegistrySetupClient({signal:a.signal});try{await runIntegrationConnect({appRoot:t,slug:n,service:r,canonicalConnectorName:i,options:a,dependencies:{...o,createPrompter:()=>s?.prompter??(a.nonInteractive?createHeadlessPrompter(()=>{}):o.createPrompter?.()??createPrompter())}}),s?.complete()}catch(t){if(s?.fail(t),s!==void 0)return;if(a.nonInteractive&&t instanceof SetupPrerequisiteRequired){e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:t.prerequisite})),process.exitCode=2;return}e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}export{runIntegrationConnect,runIntegrationConnectCommand};
1
+ import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{join}from"node:path";import{createPrompter}from"#setup/prompter.js";import{readProjectLink}from"#setup/project-resolution.js";import{requireAuth}from"#setup/vercel-project.js";import{WizardCancelledError}from"#setup/step.js";import{cleanupCreatedConnectionConnector,setupConnectionConnector}from"#setup/connection-connector.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{createHeadlessPrompter}from"#setup/headless.js";import{setupPrerequisiteOf}from"#setup/integrations/shared/prerequisite.js";import{resolveIntegrationVercelProject}from"#setup/integrations/shared/vercel-project.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{updateConnectionConnectorUid}from"#setup/scaffold/update/update-connection-connector.js";const defaultDependencies={ensureVercelProject,readProjectLink,requireAuth,setupConnectionConnector,cleanupCreatedConnectionConnector,updateConnectionConnectorUid};async function runIntegrationConnect(e){let t={...defaultDependencies,...e.dependencies},n=e.options?.nonInteractive===!0,r=t.createPrompter?.()??(n?createHeadlessPrompter(()=>{}):createPrompter()),i=e.options?.signal;r.intro(`Set up ${e.slug}`);let a=await t.readProjectLink(e.appRoot);if(a!==void 0)await t.requireAuth(e.appRoot,n?void 0:r,{signal:i});else if(n)a=await resolveIntegrationVercelProject({appRoot:e.appRoot,integration:e.slug,signal:i,deps:{readProjectLink:t.readProjectLink}});else try{a=await t.ensureVercelProject({appRoot:e.appRoot,prompter:r,signal:i,teamSelectMessage:()=>`You need to link to a project to use ${e.slug} through Vercel Connect.\n\nSelect your team`,deps:t.ensureVercelProjectDeps})}catch(e){if(e instanceof WizardCancelledError)return;throw e}let o={log:r.log,prompter:r,projectRoot:e.appRoot,slug:e.slug,service:e.service,creationType:e.options?.creationType,connectionMethod:e.options?.connectionMethod,principalType:e.options?.principalType,canonicalConnectorName:e.canonicalConnectorName??e.slug,project:a,signal:i},s=await t.setupConnectionConnector(o),c=join(e.appRoot,`agent`,`connections`,`${e.slug}.ts`);if(!(await t.updateConnectionConnectorUid(c,s.connectorUid)).patched)throw s.kind===`created`&&await t.cleanupCreatedConnectionConnector({log:r.log,projectRoot:e.appRoot,connectorId:s.connectorId,orgId:a.orgId}),Error(`Could not update the connector in agent/connections/${e.slug}.ts.`);r.outro(`Connection ${e.slug} set up.`)}async function runIntegrationConnectCommand(e,t,n,r,i,a={},o=defaultDependencies){let s=createRegistrySetupClient({signal:a.signal});try{await runIntegrationConnect({appRoot:t,slug:n,service:r,canonicalConnectorName:i,options:a,dependencies:{...o,createPrompter:()=>s?.prompter??(a.nonInteractive?createHeadlessPrompter(()=>{}):o.createPrompter?.()??createPrompter())}}),s?.complete()}catch(t){if(s?.fail(t),s!==void 0)return;let n=setupPrerequisiteOf(t);if(a.nonInteractive&&n!==void 0){e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:n})),process.exitCode=2;return}e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}export{runIntegrationConnect,runIntegrationConnectCommand};
@@ -1 +1 @@
1
- import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{createPrompter}from"#setup/prompter.js";import{resolveEveProjectContext}from"#internal/project-context.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{createHeadlessPrompter}from"#setup/headless.js";import{SetupPrerequisiteRequired}from"#setup/integrations/shared/prerequisite.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{InteractionRequired,InvalidAnswerError,headlessAsker,interactiveAsker,withAnswers,withPolicy}from"#setup/ask.js";import{WEB_CHAT_TEAM_REQUIREMENT}from"#setup/integrations/web/auth-options.js";import{runIntegrationSetup}from"#setup/integrations/runner.js";import{setupQuestionToWire}from"#setup/setup-question-wire.js";const defaultIntegrationSetupDependencies={};async function runIntegrationSetupCommand(e,t,n,r={},i=defaultIntegrationSetupDependencies){let a=createRegistrySetupClient({process:i.setupProcess,signal:r.signal});try{let o=r.nonInteractive===!0,s=(await resolveEveProjectContext(t)).environmentRoot,c=a?.prompter??i.createPrompter?.()??(o?createHeadlessPrompter(()=>{}):createPrompter()),l=o?headlessAsker():interactiveAsker(c),u=r.yes?withPolicy(`assume`)(l):l,d=withAnswers(r.answers??{})(u),f=await runIntegrationSetup(n,{appRoot:t,projectRoot:s,prompter:c,asker:d,force:r.force,resolveVercelProject:o?void 0:()=>ensureVercelProject({appRoot:s,teamRequirement:n===`web`?WEB_CHAT_TEAM_REQUIREMENT:void 0,prompter:c,signal:a?.signal??r.signal}),signal:a?.signal??r.signal,beginExternalAction:o?t=>{let n=`external-action-${crypto.randomUUID()}`;return e.log(serializeHeadlessSetupEvent({version:1,type:`external_action`,id:n,blocking:!0,...t})),{complete(){e.log(serializeHeadlessSetupEvent({version:1,type:`external_action_resolved`,id:n}))}}}:void 0},i.runnerDeps);if(f.kind===`cancelled`){a?.cancel(),process.env.EVE_SETUP===`1`?process.exitCode=130:o&&e.error(serializeHeadlessSetupEvent({version:1,type:`cancelled`,item:n}));return}c.outro(`Integration set up.`),a?.complete(f.completion),o&&a===void 0&&e.log(serializeHeadlessSetupEvent({version:1,type:`completed`,item:n}))}catch(t){if(a?.fail(t),a!==void 0)return;r.nonInteractive&&t instanceof InteractionRequired?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`input_required`,question:setupQuestionToWire(t.question)})),process.exitCode=2):r.nonInteractive&&t instanceof InvalidAnswerError?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`input_required`,question:setupQuestionToWire(t.question),issue:{code:`invalid_answer`,message:t.message}})),process.exitCode=2):r.nonInteractive&&t instanceof SetupPrerequisiteRequired?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:t.prerequisite})),process.exitCode=2):(e.error(t instanceof Error?t.message:String(t)),process.exitCode=1)}}export{runIntegrationSetupCommand};
1
+ import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{createPrompter}from"#setup/prompter.js";import{resolveEveProjectContext}from"#internal/project-context.js";import{ensureVercelProject}from"#setup/flows/ensure-vercel-project.js";import{createHeadlessPrompter}from"#setup/headless.js";import{setupPrerequisiteOf}from"#setup/integrations/shared/prerequisite.js";import{createRegistrySetupClient}from"#setup/registry-setup-client.js";import{InteractionRequired,InvalidAnswerError,headlessAsker,interactiveAsker,withAnswers,withPolicy}from"#setup/ask.js";import{WEB_CHAT_TEAM_REQUIREMENT}from"#setup/integrations/web/auth-options.js";import{runIntegrationSetup}from"#setup/integrations/runner.js";import{setupQuestionToWire}from"#setup/setup-question-wire.js";const defaultIntegrationSetupDependencies={};async function runIntegrationSetupCommand(e,t,n,r={},i=defaultIntegrationSetupDependencies){let a=createRegistrySetupClient({process:i.setupProcess,signal:r.signal});try{let o=r.nonInteractive===!0,s=(await resolveEveProjectContext(t)).environmentRoot,c=a?.prompter??i.createPrompter?.()??(o?createHeadlessPrompter(()=>{}):createPrompter()),l=o?headlessAsker():interactiveAsker(c),u=r.yes?withPolicy(`assume`)(l):l,d=withAnswers(r.answers??{})(u),f=await runIntegrationSetup(n,{appRoot:t,projectRoot:s,prompter:c,asker:d,force:r.force,resolveVercelProject:o?void 0:()=>ensureVercelProject({appRoot:s,teamRequirement:n===`web`?WEB_CHAT_TEAM_REQUIREMENT:void 0,prompter:c,signal:a?.signal??r.signal}),signal:a?.signal??r.signal,beginExternalAction:o?t=>{let n=`external-action-${crypto.randomUUID()}`;return e.log(serializeHeadlessSetupEvent({version:1,type:`external_action`,id:n,blocking:!0,...t})),{complete(){e.log(serializeHeadlessSetupEvent({version:1,type:`external_action_resolved`,id:n}))}}}:void 0},i.runnerDeps);if(f.kind===`cancelled`){a?.cancel(),process.env.EVE_SETUP===`1`?process.exitCode=130:o&&e.error(serializeHeadlessSetupEvent({version:1,type:`cancelled`,item:n}));return}c.outro(`Integration set up.`),a?.complete(f.completion),o&&a===void 0&&e.log(serializeHeadlessSetupEvent({version:1,type:`completed`,item:n}))}catch(t){if(a?.fail(t),a!==void 0)return;let n=setupPrerequisiteOf(t);r.nonInteractive&&t instanceof InteractionRequired?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`input_required`,question:setupQuestionToWire(t.question)})),process.exitCode=2):r.nonInteractive&&t instanceof InvalidAnswerError?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`input_required`,question:setupQuestionToWire(t.question),issue:{code:`invalid_answer`,message:t.message}})),process.exitCode=2):r.nonInteractive&&n!==void 0?(e.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,status:`prerequisite_required`,prerequisite:n})),process.exitCode=2):(e.error(t instanceof Error?t.message:String(t)),process.exitCode=1)}}export{runIntegrationSetupCommand};
@@ -1,7 +1,26 @@
1
1
  import { type Prompter } from "#setup/prompter.js";
2
2
  import type { RegistrySetupCompletion } from "#setup/registry-setup-protocol.js";
3
+ import { type SetupPrerequisite } from "#setup/integrations/shared/prerequisite.js";
3
4
  import type { RegistryCommandLogger, RegistrySetupDependencies } from "./registry.js";
4
5
  import type { RegistrySetupCommand } from "./registry-setup-command.js";
6
+ /**
7
+ * A declared setup that failed after the item's source was installed. Keeps
8
+ * the original error as `cause` so interactive callers can report the item as
9
+ * installed-but-not-set-up and recover from a structured prerequisite (for
10
+ * example `vercel login`) instead of parsing the message.
11
+ */
12
+ export declare class RegistrySetupFailedError extends Error {
13
+ readonly item: string;
14
+ readonly resumeCommand: string;
15
+ /** The failure without the resume hint, for callers that render it separately. */
16
+ readonly reason: string;
17
+ constructor(input: {
18
+ item: string;
19
+ resumeCommand: string;
20
+ cause: unknown;
21
+ });
22
+ get prerequisite(): SetupPrerequisite | undefined;
23
+ }
5
24
  interface DeclaredSetupOptions {
6
25
  yes?: boolean;
7
26
  force?: boolean;
@@ -1 +1 @@
1
- import{headlessSetupContinuation,serializeHeadlessSetupEvent}from"./setup-headless.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{createHeadlessPrompter}from"#setup/headless.js";import{mergeRegistrySetupCompletions}from"#setup/registry-setup-completion.js";async function runDeclaredSetups(e){let t={facts:[]};if(e.setups===void 0)return t;let n=await e.dependencies.loadSetupCommandRunner(),r=e.options.prompter??(e.options.nonInteractive?createHeadlessPrompter(e.logger.log):createPrompter());try{for(let i of e.setups){let a=await n(e.appRoot,{...i,args:[...i.args,...e.options.yes?[`--yes`]:[],...e.options.force&&i.package===`eve`&&i.bin===`eve`&&i.args[0]===`integration`&&i.args[1]===`setup`?[`--force`]:[],...e.options.nonInteractive?[`--non-interactive`]:[],...Object.entries(e.options.answers??{}).flatMap(([e,t])=>[`--answer`,`${e}=${JSON.stringify(t)}`])]},e.item,{prompter:r,signal:e.options.signal});if(a.kind===`cancelled`)return!1;if(a.kind===`blocked`){if(!e.options.nonInteractive)throw Error(`Setup requires more input.`);return e.logger.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,item:e.item,installed:!0,completedItems:[],...a.blocker,next:headlessSetupContinuation({item:e.item,installed:!0,answers:e.options.answers,question:a.blocker.status===`input_required`?a.blocker.question:void 0})})),process.exitCode=2,!1}if(e.options.silent!==!0)for(let t of a.facts)e.logger.log(`${t.label}: ${t.value}`);t=mergeRegistrySetupCompletions(t,a)}return t}catch(t){if(t instanceof WizardCancelledError)return!1;let n=t instanceof Error?t.message:String(t);if(e.options.nonInteractive)return e.logger.error(serializeHeadlessSetupEvent({version:1,type:`failed`,item:e.item,completedItems:[],message:n,next:headlessSetupContinuation({item:e.item,installed:!0,answers:e.options.answers})})),process.exitCode=1,!1;throw Error(`${n} Try again with \`${e.resumeCommand}\`.`)}}export{runDeclaredSetups};
1
+ import{headlessSetupContinuation,serializeHeadlessSetupEvent}from"./setup-headless.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{createHeadlessPrompter}from"#setup/headless.js";import{SetupPrerequisiteRequired,setupPrerequisiteOf}from"#setup/integrations/shared/prerequisite.js";import{mergeRegistrySetupCompletions}from"#setup/registry-setup-completion.js";var RegistrySetupFailedError=class extends Error{item;resumeCommand;reason;constructor(e){let t=e.cause instanceof Error?e.cause.message:String(e.cause);super(`${t} Try again with \`${e.resumeCommand}\`.`,{cause:e.cause}),this.name=`RegistrySetupFailedError`,this.item=e.item,this.resumeCommand=e.resumeCommand,this.reason=t}get prerequisite(){return setupPrerequisiteOf(this.cause)}};async function runDeclaredSetups(e){let t={facts:[]};if(e.setups===void 0)return t;let n=await e.dependencies.loadSetupCommandRunner(),r=e.options.prompter??(e.options.nonInteractive?createHeadlessPrompter(e.logger.log):createPrompter());try{for(let i of e.setups){let a=await n(e.appRoot,{...i,args:[...i.args,...e.options.yes?[`--yes`]:[],...e.options.force&&i.package===`eve`&&i.bin===`eve`&&i.args[0]===`integration`&&i.args[1]===`setup`?[`--force`]:[],...e.options.nonInteractive?[`--non-interactive`]:[],...Object.entries(e.options.answers??{}).flatMap(([e,t])=>[`--answer`,`${e}=${JSON.stringify(t)}`])]},e.item,{prompter:r,signal:e.options.signal});if(a.kind===`cancelled`)return!1;if(a.kind===`blocked`){if(!e.options.nonInteractive)throw a.blocker.status===`prerequisite_required`?new SetupPrerequisiteRequired(a.blocker.prerequisite):Error(`Setup requires more input.`);return e.logger.error(serializeHeadlessSetupEvent({version:1,type:`blocked`,item:e.item,installed:!0,completedItems:[],...a.blocker,next:headlessSetupContinuation({item:e.item,installed:!0,answers:e.options.answers,question:a.blocker.status===`input_required`?a.blocker.question:void 0})})),process.exitCode=2,!1}if(e.options.silent!==!0)for(let t of a.facts)e.logger.log(`${t.label}: ${t.value}`);t=mergeRegistrySetupCompletions(t,a)}return t}catch(t){if(t instanceof WizardCancelledError)return!1;let n=t instanceof Error?t.message:String(t);if(e.options.nonInteractive)return e.logger.error(serializeHeadlessSetupEvent({version:1,type:`failed`,item:e.item,completedItems:[],message:n,next:headlessSetupContinuation({item:e.item,installed:!0,answers:e.options.answers})})),process.exitCode=1,!1;throw new RegistrySetupFailedError({item:e.item,resumeCommand:e.resumeCommand,cause:t})}}export{RegistrySetupFailedError,runDeclaredSetups};
@@ -7,7 +7,9 @@ export declare function reportRegistryCompletion(logger: RegistryCommandLogger,
7
7
  nonInteractive?: boolean;
8
8
  }): RegistrySetupCompletion | undefined;
9
9
  export declare function errorMessage(error: unknown): string;
10
- export declare function runRegistryAction<T>(logger: RegistryCommandLogger, _appRoot: string, action: () => Promise<T>): Promise<T | undefined>;
10
+ export declare function runRegistryAction<T>(logger: RegistryCommandLogger, _appRoot: string, action: () => Promise<T>, options?: {
11
+ rethrow?: (error: unknown) => boolean;
12
+ }): Promise<T | undefined>;
11
13
  export declare function resolveRegistryItemForAdd<T>(logger: RegistryCommandLogger, loadItem: () => Promise<T>, printSuggestions: () => Promise<void>): Promise<{
12
14
  found: true;
13
15
  item: T;
@@ -1 +1 @@
1
- import{reportHeadlessSetupCompletion}from"./setup-headless.js";import{WizardCancelledError}from"#setup/step.js";function reportRegistryCompletion(e,t,n,r){return reportHeadlessSetupCompletion({logger:e,item:t,completion:n,nonInteractive:r.nonInteractive})}function errorMessage(e){return e instanceof Error?e.message:String(e)}function isRegistryNotFoundError(e){return e instanceof Error&&`code`in e&&e.code===`NOT_FOUND`}async function runRegistryAction(e,t,n){try{return await n()}catch(t){if(t instanceof WizardCancelledError)return;e.error(errorMessage(t)),process.exitCode=1;return}}async function resolveRegistryItemForAdd(e,t,n){try{return{found:!0,item:await t()}}catch(t){if(!isRegistryNotFoundError(t))throw t;return e.error(errorMessage(t)),await n(),process.exitCode=1,{found:!1}}}function setupResumeCommand(e){return`eve add ${/^[\w@./:-]+$/.test(e)?e:`'${e.replaceAll(`'`,`'\\''`)}'`} --skip-install`}function setupReminder(e,t){return`${t===`cancelled`?`Setup cancelled.`:`Setup skipped.`} Run \`${setupResumeCommand(e)}\` when you're ready.`}export{errorMessage,reportRegistryCompletion,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand};
1
+ import{reportHeadlessSetupCompletion}from"./setup-headless.js";import{WizardCancelledError}from"#setup/step.js";function reportRegistryCompletion(e,t,n,r){return reportHeadlessSetupCompletion({logger:e,item:t,completion:n,nonInteractive:r.nonInteractive})}function errorMessage(e){return e instanceof Error?e.message:String(e)}function isRegistryNotFoundError(e){return e instanceof Error&&`code`in e&&e.code===`NOT_FOUND`}async function runRegistryAction(e,t,n,r={}){try{return await n()}catch(t){if(t instanceof WizardCancelledError)return;if(r.rethrow?.(t)===!0)throw t;e.error(errorMessage(t)),process.exitCode=1;return}}async function resolveRegistryItemForAdd(e,t,n){try{return{found:!0,item:await t()}}catch(t){if(!isRegistryNotFoundError(t))throw t;return e.error(errorMessage(t)),await n(),process.exitCode=1,{found:!1}}}function setupResumeCommand(e){return`eve add ${/^[\w@./:-]+$/.test(e)?e:`'${e.replaceAll(`'`,`'\\''`)}'`} --skip-install`}function setupReminder(e,t){return`${t===`cancelled`?`Setup cancelled.`:`Setup skipped.`} Run \`${setupResumeCommand(e)}\` when you're ready.`}export{errorMessage,reportRegistryCompletion,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand};
@@ -1,3 +1,4 @@
1
+ import type { SetupPrerequisite } from "#setup/integrations/shared/prerequisite.js";
1
2
  import { type Prompter } from "#setup/prompter.js";
2
3
  import type { RegistrySetupCompletion } from "#setup/registry-setup-protocol.js";
3
4
  import { type RegistryCommandLogger } from "./registry-recovery.js";
@@ -5,6 +6,14 @@ import type { runRegistrySetupCommand } from "./registry-setup-command.js";
5
6
  import { prepareWebRegistryProject } from "./registry-project.js";
6
7
  export { runRegistryAddCommand } from "./registry-add-command.js";
7
8
  export type { RegistryCommandLogger } from "./registry-recovery.js";
9
+ /** Source was installed, but the item's setup was cancelled, skipped, or failed. */
10
+ export interface RegistrySetupIncomplete {
11
+ resumeCommand: string;
12
+ /** Why setup failed; absent when it was cancelled or skipped. */
13
+ reason?: string;
14
+ /** A structured action that unblocks setup, such as `vercel login`. */
15
+ prerequisite?: SetupPrerequisite;
16
+ }
8
17
  export interface AddCommandOptions {
9
18
  skipInstall?: boolean;
10
19
  overwrite?: boolean;
@@ -37,6 +46,8 @@ type RunAddCommandOptions = AddCommandOptions & {
37
46
  prompter?: Prompter;
38
47
  signal?: AbortSignal;
39
48
  setupAuthorized?: boolean;
49
+ /** Throw {@link RegistrySetupFailedError} to the caller instead of logging it. */
50
+ throwSetupFailures?: boolean;
40
51
  };
41
52
  /** One discoverable item from an eve-compatible registry catalog. */
42
53
  export interface RegistryCatalogItem {
@@ -75,10 +86,7 @@ export declare function installRegistryItem(appRoot: string, item: string, optio
75
86
  }, dependencies?: AddCommandDependencies): Promise<{
76
87
  output: readonly string[];
77
88
  setup?: RegistrySetupCompletion;
78
- /** Files were added, but setup was cancelled or skipped. */
79
- setupIncomplete?: {
80
- resumeCommand: string;
81
- };
89
+ setupIncomplete?: RegistrySetupIncomplete;
82
90
  }>;
83
91
  /** Installs an official, configured, or URL-addressed registry item. */
84
92
  export declare function runAddCommand(logger: RegistryCommandLogger, appRoot: string, item: string, options: RunAddCommandOptions, dependencies?: AddCommandDependencies): Promise<RegistrySetupCompletion | false | "setup-incomplete" | undefined>;
@@ -1 +1 @@
1
- import{hasInteractiveTerminal}from"./preconditions.js";import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{prepareWebChatProjectRoot,prepareWebRegistryProject,readRegistryConfig}from"./registry-project.js";import{errorMessage,reportRegistryCompletion,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand}from"./registry-recovery.js";import{runRegistryAddCommand}from"./registry-add-command.js";import{runDeclaredSetups}from"./registry-declared-setups.js";import{installRegistryItemTransaction}from"./registry-install-transaction.js";import{eveMetadataFromRegistryItem,parseOfficialRegistrySearchMetadata}from"./registry-metadata.js";import{prepareDeclaredPnpmBuildPolicy}from"./registry-pnpm-build-policy-flow.js";import{printRegistrySearchResults,registryViewText}from"./registry-presentation.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{addRegistryItems,getRegistryItems,searchRegistries}from"#compiled/shadcn-registry/index.js";import semver from"#compiled/semver/index.js";const defaultAddCommandDependencies={createPrompter,hasInteractiveTerminal,loadSetupCommandRunner:async()=>(await import(`./registry-setup-command.js`)).runRegistrySetupCommand,prepareWebRegistryProject};function resolveOfficialRegistryUrl(e=process.env.EVE_DEV_OFFICIAL_REGISTRY_URL){if(e===void 0)return`https://eve.dev/r`;let t;try{t=new URL(e)}catch{throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`);if(t.username!==``||t.password!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include credentials.`);if(t.search!==``||t.hash!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include a query or fragment.`);return t.pathname=t.pathname.replace(/\/+$/,``),t.toString().replace(/\/$/,``)}const OFFICIAL_REGISTRY=resolveOfficialRegistryUrl(),OFFICIAL_CATALOG=`${OFFICIAL_REGISTRY}/registry.json`,SKILLS_REGISTRY=`@skills`;function itemAddress(e){return e.startsWith(`@`)||/^https?:\/\//.test(e)?e:`${OFFICIAL_REGISTRY}/${e}.json`}function assertCompatibleEveVersion(e){if(e===void 0)return;let t=resolveInstalledPackageInfo().version;if(semver.validRange(e)===null)throw Error(`Registry item has an invalid eve version requirement: ${e}.`);if(!semver.subset(t,e))throw Error(`This registry item requires eve ${e}, but this project is using eve ${t}. Upgrade eve and run the command again.`)}function isOfficialItemAddress(e){return e.startsWith(`${OFFICIAL_REGISTRY}/`)}function withBuiltInRegistries(e){return{...e,registries:{[SKILLS_REGISTRY]:`https://www.skills.sh/r/{name}?agent=eve`,...e.registries}}}async function readEveRegistryConfig(e){return withBuiltInRegistries(await readRegistryConfig(e))}function configuredRegistrySources(e){return Object.keys(e.registries??{})}function validateRegistrySource(e){if(e!==void 0&&!e.startsWith(`@`)&&!/^https?:\/\//.test(e))throw Error(`Registry sources must be a namespace or URL: ${e}`)}async function loadOfficialSearchMetadata(){let e=await fetch(OFFICIAL_CATALOG);if(!e.ok)throw Error(`Could not read the eve registry (${e.status}).`);return parseOfficialRegistrySearchMetadata(await e.json())}function searchItemAddress(e){return e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument}function enrichSearchItem(e,t){let n=searchItemAddress(e);return{item:e,address:n,...t.get(n)}}function registrySourceLabel(e){return e===OFFICIAL_CATALOG?`eve`:e===SKILLS_REGISTRY?`skills.sh`:e}function searchPresentationSections(e,t,n){return e.flatMap(e=>{let r=t.get(e);return r===void 0?[]:[{label:registrySourceLabel(e),items:r.items.map(e=>enrichSearchItem(e,n)),total:r.pagination.total}]})}async function printAddSuggestions(e,t,n){try{let r=n.split(`/`).at(-1)||n,{resultsBySource:i,sources:a,metadataByAddress:o}=await searchRegistryCatalog(t,{limit:5,query:r}),s=searchPresentationSections(a,i,o);if(s.every(e=>e.items.length===0))return;e.log(`Did you mean?`),printRegistrySearchResults(e,{query:r,sections:s})}catch{}}async function searchRegistryCatalog(e,t){validateRegistrySource(t.source);let n=await readEveRegistryConfig(e),r=t.source?[t.source]:[OFFICIAL_CATALOG,...configuredRegistrySources(n).filter(e=>t.query!==void 0||e!==SKILLS_REGISTRY)],i=await Promise.all(r.map(async e=>{try{return{result:await searchRegistries([e],{config:n,limit:t.limit??100,query:t.query}),source:e}}catch(t){return{error:t,source:e}}})),a=[],o=new Map;for(let e of i)if(`error`in e)a.push({message:errorMessage(e.error),registry:e.source});else{let t=e.result.errors??[];if(a.push(...t),t.length===0){let t=e.result.items.filter(t=>t.registry===e.source);o.set(e.source,{...e.result,items:t,pagination:{...e.result.pagination,total:e.result.items.length===t.length?e.result.pagination.total:0}})}}let s=new Map(a.map(e=>[`${e.registry}\0${e.message}`,e])),c=o.has(OFFICIAL_CATALOG)?await loadOfficialSearchMetadata():new Map,l=o.get(OFFICIAL_CATALOG);if(l!==void 0){let e=l.items.filter(e=>c.get(searchItemAddress(e))?.hidden!==!0);l.items=e,l.pagination={...l.pagination,total:e.length},l.items.sort((e,t)=>{let rank=e=>c.get(searchItemAddress(e))?.implementation===`native`?0:1;return rank(e)-rank(t)})}let u=[...o.values()];return{config:n,result:{items:u.flatMap(e=>e.items),pagination:{hasMore:u.some(e=>e.pagination.hasMore),limit:t.limit??100,offset:0,total:u.reduce((e,t)=>e+t.pagination.total,0)},...s.size>0?{errors:[...s.values()]}:{}},resultsBySource:o,sources:r,metadataByAddress:c}}async function browseRegistryCatalog(e,t={}){let{result:n}=await searchRegistryCatalog(e,t);return{items:n.items.map(e=>{let t={address:e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument,name:e.name,source:e.registry===OFFICIAL_CATALOG?`Vercel`:e.registry};return e.title!==void 0&&(t.title=e.title),e.type!==void 0&&(t.type=e.type),e.description!==void 0&&(t.description=e.description),t}),total:n.pagination.total,errors:n.errors??[]}}async function browseRegistryItems(e,t,n,r,i={}){let{result:a,resultsBySource:o,sources:s,metadataByAddress:c}=await searchRegistryCatalog(t,{limit:i.limit,query:n,source:r}),l=a.errors??[];if(i.json||o.size>0){let t=a.items.map(e=>({...e,...c.get(searchItemAddress(e))})),r={query:n,sections:searchPresentationSections(s,o,c)};i.json&&(r.json={...a,items:t}),printRegistrySearchResults(e,r)}for(let t of l)e.error(`${t.registry}: ${t.message}`);l.length>0&&(process.exitCode=1)}async function installRegistryItem(e,t,n={},r=defaultAddCommandDependencies){let i,a=[],o={error:e=>{i=e},log:e=>a.push(e)},s=process.exitCode,c=await runAddCommand(o,e,t,{...n,yes:n.prompter===void 0||n.yes,setupAuthorized:n.prompter!==void 0},r);if(process.exitCode=s,i!==void 0)throw Error(i);if(c===!1)throw new WizardCancelledError;if(c===`setup-incomplete`)return{output:a,setupIncomplete:{resumeCommand:setupResumeCommand(t)}};let l={output:a};return c!==void 0&&(l.setup=c),l}async function runAddCommand(e,t,n,r,i=defaultAddCommandDependencies){let setupIncomplete=t=>(r.silent!==!0&&e.log(setupReminder(n,t)),`setup-incomplete`);return runRegistryAction(e,t,async()=>{let a=itemAddress(n),o=a===itemAddress(`channel/web`)&&r.skipInstall!==!0?await prepareWebChatProjectRoot(t):t,s=await readEveRegistryConfig(t);if(r.skipInstall===!0){if(r.overwrite===!0)throw Error(`--overwrite cannot be used with --skip-install.`);if(r.skipSetup===!0)throw Error(`--skip-install cannot be used with --skip-setup.`);if(!isOfficialItemAddress(a))throw Error(`Setup flows are currently supported only for official eve registry items.`)}let c=await resolveRegistryItemForAdd(e,async()=>(await getRegistryItems([a],{config:s}))[0],()=>printAddSuggestions(e,t,n));if(!c.found)return;let l=c.item,u=isOfficialItemAddress(a)?eveMetadataFromRegistryItem(l):void 0;if(assertCompatibleEveVersion(u?.requires),r.skipInstall===!0){if(u?.setup===void 0)throw Error(`Registry item "${n}" does not declare a setup flow.`);let a=await runDeclaredSetups({logger:e,appRoot:t,item:n,setups:u.setup,options:r,dependencies:i,resumeCommand:setupResumeCommand(n)});return a===!1&&!r.nonInteractive?setupIncomplete(`cancelled`):reportRegistryCompletion(e,n,a,r)}if(!await prepareDeclaredPnpmBuildPolicy({logger:e,appRoot:o,item:n,policies:u?.install?.pnpm?.buildScripts,options:r}))return!1;if(a===itemAddress(`channel/web`)&&await(i.prepareWebRegistryProject??prepareWebRegistryProject)(o),await installRegistryItemTransaction({appRoot:o,item:n,registryItem:l,nonInteractive:r.nonInteractive,logger:e,install:async()=>{await addRegistryItems([a],{config:s,cwd:o,overwrite:r.overwrite,silent:r.silent})}}),u?.setup===void 0)return reportRegistryCompletion(e,n,{facts:[]},r);let d=i.hasInteractiveTerminal?.()??defaultAddCommandDependencies.hasInteractiveTerminal();if(r.nonInteractive&&e.log(serializeHeadlessSetupEvent({version:1,type:`progress`,message:r.skipInstall?`Setup ${n}`:`Installed ${n}`})),r.skipSetup===!0)return r.nonInteractive?reportRegistryCompletion(e,n,{facts:[]},r):setupIncomplete(`skipped`);if(!r.nonInteractive&&!r.yes&&!d&&r.setupAuthorized!==!0)return setupIncomplete(`skipped`);if(!r.nonInteractive&&!r.yes&&r.setupAuthorized!==!0)try{if(await(r.prompter??i.createPrompter?.()??defaultAddCommandDependencies.createPrompter()).select({message:`Set up ${n} now?`,initialValue:`yes`,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}]})===`no`)return setupIncomplete(`skipped`)}catch(e){if(!(e instanceof WizardCancelledError))throw e;return setupIncomplete(`cancelled`)}let f=await runDeclaredSetups({logger:e,appRoot:t,item:n,setups:u.setup,options:{...r,force:r.overwrite},dependencies:i,resumeCommand:setupResumeCommand(n)});return f===!1&&!r.nonInteractive?setupIncomplete(`cancelled`):reportRegistryCompletion(e,n,f,r)})}async function runRegistryListCommand(e,t,n,r={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,void 0,n,r))}async function runRegistrySearchCommand(e,t,n,r,i={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,n,r,{...i,limit:i.limit??10}))}async function runRegistryViewCommand(e,t,n,r={}){await runRegistryAction(e,t,async()=>{let i=await readEveRegistryConfig(t),a=await getRegistryItems([itemAddress(n)],{config:i}),o=a.length===1?a[0]:a;e.log(r.json?JSON.stringify(o,null,2):registryViewText(n,o))})}export{browseRegistryCatalog,installRegistryItem,resolveOfficialRegistryUrl,runAddCommand,runRegistryAddCommand,runRegistryListCommand,runRegistrySearchCommand,runRegistryViewCommand};
1
+ import{hasInteractiveTerminal}from"./preconditions.js";import{serializeHeadlessSetupEvent}from"./setup-headless.js";import{prepareWebChatProjectRoot,prepareWebRegistryProject,readRegistryConfig}from"./registry-project.js";import{errorMessage,reportRegistryCompletion,resolveRegistryItemForAdd,runRegistryAction,setupReminder,setupResumeCommand}from"./registry-recovery.js";import{runRegistryAddCommand}from"./registry-add-command.js";import{RegistrySetupFailedError,runDeclaredSetups}from"./registry-declared-setups.js";import{installRegistryItemTransaction}from"./registry-install-transaction.js";import{eveMetadataFromRegistryItem,parseOfficialRegistrySearchMetadata}from"./registry-metadata.js";import{prepareDeclaredPnpmBuildPolicy}from"./registry-pnpm-build-policy-flow.js";import{printRegistrySearchResults,registryViewText}from"./registry-presentation.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{createPrompter}from"#setup/prompter.js";import{WizardCancelledError}from"#setup/step.js";import{addRegistryItems,getRegistryItems,searchRegistries}from"#compiled/shadcn-registry/index.js";import semver from"#compiled/semver/index.js";const defaultAddCommandDependencies={createPrompter,hasInteractiveTerminal,loadSetupCommandRunner:async()=>(await import(`./registry-setup-command.js`)).runRegistrySetupCommand,prepareWebRegistryProject};function resolveOfficialRegistryUrl(e=process.env.EVE_DEV_OFFICIAL_REGISTRY_URL){if(e===void 0)return`https://eve.dev/r`;let t;try{t=new URL(e)}catch{throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`)}if(t.protocol!==`http:`&&t.protocol!==`https:`)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must be an HTTP(S) URL.`);if(t.username!==``||t.password!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include credentials.`);if(t.search!==``||t.hash!==``)throw Error(`EVE_DEV_OFFICIAL_REGISTRY_URL must not include a query or fragment.`);return t.pathname=t.pathname.replace(/\/+$/,``),t.toString().replace(/\/$/,``)}const OFFICIAL_REGISTRY=resolveOfficialRegistryUrl(),OFFICIAL_CATALOG=`${OFFICIAL_REGISTRY}/registry.json`,SKILLS_REGISTRY=`@skills`;function itemAddress(e){return e.startsWith(`@`)||/^https?:\/\//.test(e)?e:`${OFFICIAL_REGISTRY}/${e}.json`}function assertCompatibleEveVersion(e){if(e===void 0)return;let t=resolveInstalledPackageInfo().version;if(semver.validRange(e)===null)throw Error(`Registry item has an invalid eve version requirement: ${e}.`);if(!semver.subset(t,e))throw Error(`This registry item requires eve ${e}, but this project is using eve ${t}. Upgrade eve and run the command again.`)}function isOfficialItemAddress(e){return e.startsWith(`${OFFICIAL_REGISTRY}/`)}function withBuiltInRegistries(e){return{...e,registries:{[SKILLS_REGISTRY]:`https://www.skills.sh/r/{name}?agent=eve`,...e.registries}}}async function readEveRegistryConfig(e){return withBuiltInRegistries(await readRegistryConfig(e))}function configuredRegistrySources(e){return Object.keys(e.registries??{})}function validateRegistrySource(e){if(e!==void 0&&!e.startsWith(`@`)&&!/^https?:\/\//.test(e))throw Error(`Registry sources must be a namespace or URL: ${e}`)}async function loadOfficialSearchMetadata(){let e=await fetch(OFFICIAL_CATALOG);if(!e.ok)throw Error(`Could not read the eve registry (${e.status}).`);return parseOfficialRegistrySearchMetadata(await e.json())}function searchItemAddress(e){return e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument}function enrichSearchItem(e,t){let n=searchItemAddress(e);return{item:e,address:n,...t.get(n)}}function registrySourceLabel(e){return e===OFFICIAL_CATALOG?`eve`:e===SKILLS_REGISTRY?`skills.sh`:e}function searchPresentationSections(e,t,n){return e.flatMap(e=>{let r=t.get(e);return r===void 0?[]:[{label:registrySourceLabel(e),items:r.items.map(e=>enrichSearchItem(e,n)),total:r.pagination.total}]})}async function printAddSuggestions(e,t,n){try{let r=n.split(`/`).at(-1)||n,{resultsBySource:i,sources:a,metadataByAddress:o}=await searchRegistryCatalog(t,{limit:5,query:r}),s=searchPresentationSections(a,i,o);if(s.every(e=>e.items.length===0))return;e.log(`Did you mean?`),printRegistrySearchResults(e,{query:r,sections:s})}catch{}}async function searchRegistryCatalog(e,t){validateRegistrySource(t.source);let n=await readEveRegistryConfig(e),r=t.source?[t.source]:[OFFICIAL_CATALOG,...configuredRegistrySources(n).filter(e=>t.query!==void 0||e!==SKILLS_REGISTRY)],i=await Promise.all(r.map(async e=>{try{return{result:await searchRegistries([e],{config:n,limit:t.limit??100,query:t.query}),source:e}}catch(t){return{error:t,source:e}}})),a=[],o=new Map;for(let e of i)if(`error`in e)a.push({message:errorMessage(e.error),registry:e.source});else{let t=e.result.errors??[];if(a.push(...t),t.length===0){let t=e.result.items.filter(t=>t.registry===e.source);o.set(e.source,{...e.result,items:t,pagination:{...e.result.pagination,total:e.result.items.length===t.length?e.result.pagination.total:0}})}}let s=new Map(a.map(e=>[`${e.registry}\0${e.message}`,e])),c=o.has(OFFICIAL_CATALOG)?await loadOfficialSearchMetadata():new Map,l=o.get(OFFICIAL_CATALOG);if(l!==void 0){let e=l.items.filter(e=>c.get(searchItemAddress(e))?.hidden!==!0);l.items=e,l.pagination={...l.pagination,total:e.length},l.items.sort((e,t)=>{let rank=e=>c.get(searchItemAddress(e))?.implementation===`native`?0:1;return rank(e)-rank(t)})}let u=[...o.values()];return{config:n,result:{items:u.flatMap(e=>e.items),pagination:{hasMore:u.some(e=>e.pagination.hasMore),limit:t.limit??100,offset:0,total:u.reduce((e,t)=>e+t.pagination.total,0)},...s.size>0?{errors:[...s.values()]}:{}},resultsBySource:o,sources:r,metadataByAddress:c}}async function browseRegistryCatalog(e,t={}){let{result:n}=await searchRegistryCatalog(e,t);return{items:n.items.map(e=>{let t={address:e.registry===OFFICIAL_CATALOG?e.name:e.addCommandArgument,name:e.name,source:e.registry===OFFICIAL_CATALOG?`Vercel`:e.registry};return e.title!==void 0&&(t.title=e.title),e.type!==void 0&&(t.type=e.type),e.description!==void 0&&(t.description=e.description),t}),total:n.pagination.total,errors:n.errors??[]}}async function browseRegistryItems(e,t,n,r,i={}){let{result:a,resultsBySource:o,sources:s,metadataByAddress:c}=await searchRegistryCatalog(t,{limit:i.limit,query:n,source:r}),l=a.errors??[];if(i.json||o.size>0){let t=a.items.map(e=>({...e,...c.get(searchItemAddress(e))})),r={query:n,sections:searchPresentationSections(s,o,c)};i.json&&(r.json={...a,items:t}),printRegistrySearchResults(e,r)}for(let t of l)e.error(`${t.registry}: ${t.message}`);l.length>0&&(process.exitCode=1)}async function installRegistryItem(e,t,n={},r=defaultAddCommandDependencies){let i,a=[],o={error:e=>{i=e},log:e=>a.push(e)},s=process.exitCode,c;try{c=await runAddCommand(o,e,t,{...n,yes:n.prompter===void 0||n.yes,setupAuthorized:n.prompter!==void 0,throwSetupFailures:!0},r)}catch(e){if(process.exitCode=s,!(e instanceof RegistrySetupFailedError))throw e;let t={resumeCommand:e.resumeCommand,reason:e.reason};return e.prerequisite!==void 0&&(t.prerequisite=e.prerequisite),{output:a,setupIncomplete:t}}if(process.exitCode=s,i!==void 0)throw Error(i);if(c===!1)throw new WizardCancelledError;if(c===`setup-incomplete`)return{output:a,setupIncomplete:{resumeCommand:setupResumeCommand(t)}};let l={output:a};return c!==void 0&&(l.setup=c),l}async function runAddCommand(e,t,n,r,i=defaultAddCommandDependencies){let setupIncomplete=t=>(r.silent!==!0&&e.log(setupReminder(n,t)),`setup-incomplete`);return runRegistryAction(e,t,async()=>{let a=itemAddress(n),o=a===itemAddress(`channel/web`)&&r.skipInstall!==!0?await prepareWebChatProjectRoot(t):t,s=await readEveRegistryConfig(t);if(r.skipInstall===!0){if(r.overwrite===!0)throw Error(`--overwrite cannot be used with --skip-install.`);if(r.skipSetup===!0)throw Error(`--skip-install cannot be used with --skip-setup.`);if(!isOfficialItemAddress(a))throw Error(`Setup flows are currently supported only for official eve registry items.`)}let c=await resolveRegistryItemForAdd(e,async()=>(await getRegistryItems([a],{config:s}))[0],()=>printAddSuggestions(e,t,n));if(!c.found)return;let l=c.item,u=isOfficialItemAddress(a)?eveMetadataFromRegistryItem(l):void 0;if(assertCompatibleEveVersion(u?.requires),r.skipInstall===!0){if(u?.setup===void 0)throw Error(`Registry item "${n}" does not declare a setup flow.`);let a=await runDeclaredSetups({logger:e,appRoot:t,item:n,setups:u.setup,options:r,dependencies:i,resumeCommand:setupResumeCommand(n)});return a===!1&&!r.nonInteractive?setupIncomplete(`cancelled`):reportRegistryCompletion(e,n,a,r)}if(!await prepareDeclaredPnpmBuildPolicy({logger:e,appRoot:o,item:n,policies:u?.install?.pnpm?.buildScripts,options:r}))return!1;if(a===itemAddress(`channel/web`)&&await(i.prepareWebRegistryProject??prepareWebRegistryProject)(o),await installRegistryItemTransaction({appRoot:o,item:n,registryItem:l,nonInteractive:r.nonInteractive,logger:e,install:async()=>{await addRegistryItems([a],{config:s,cwd:o,overwrite:r.overwrite,silent:r.silent})}}),u?.setup===void 0)return reportRegistryCompletion(e,n,{facts:[]},r);let d=i.hasInteractiveTerminal?.()??defaultAddCommandDependencies.hasInteractiveTerminal();if(r.nonInteractive&&e.log(serializeHeadlessSetupEvent({version:1,type:`progress`,message:r.skipInstall?`Setup ${n}`:`Installed ${n}`})),r.skipSetup===!0)return r.nonInteractive?reportRegistryCompletion(e,n,{facts:[]},r):setupIncomplete(`skipped`);if(!r.nonInteractive&&!r.yes&&!d&&r.setupAuthorized!==!0)return setupIncomplete(`skipped`);if(!r.nonInteractive&&!r.yes&&r.setupAuthorized!==!0)try{if(await(r.prompter??i.createPrompter?.()??defaultAddCommandDependencies.createPrompter()).select({message:`Set up ${n} now?`,initialValue:`yes`,options:[{value:`yes`,label:`Yes`},{value:`no`,label:`No`}]})===`no`)return setupIncomplete(`skipped`)}catch(e){if(!(e instanceof WizardCancelledError))throw e;return setupIncomplete(`cancelled`)}let f=await runDeclaredSetups({logger:e,appRoot:t,item:n,setups:u.setup,options:{...r,force:r.overwrite},dependencies:i,resumeCommand:setupResumeCommand(n)});return f===!1&&!r.nonInteractive?setupIncomplete(`cancelled`):reportRegistryCompletion(e,n,f,r)},{rethrow:e=>r.throwSetupFailures===!0&&e instanceof RegistrySetupFailedError})}async function runRegistryListCommand(e,t,n,r={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,void 0,n,r))}async function runRegistrySearchCommand(e,t,n,r,i={}){await runRegistryAction(e,t,()=>browseRegistryItems(e,t,n,r,{...i,limit:i.limit??10}))}async function runRegistryViewCommand(e,t,n,r={}){await runRegistryAction(e,t,async()=>{let i=await readEveRegistryConfig(t),a=await getRegistryItems([itemAddress(n)],{config:i}),o=a.length===1?a[0]:a;e.log(r.json?JSON.stringify(o,null,2):registryViewText(n,o))})}export{browseRegistryCatalog,installRegistryItem,resolveOfficialRegistryUrl,runAddCommand,runRegistryAddCommand,runRegistryListCommand,runRegistrySearchCommand,runRegistryViewCommand};
@@ -1,4 +1,4 @@
1
- function registryItemProgress(e){return(t,n,r)=>{e.setNavigation?.(void 0),e.replaceContent?.(),e.setStatus(`Adding ${t.title??t.name} · ${n+1} of ${r}`)}}function outcomeDetails(e){switch(e.kind){case`installed`:{let t=e.facts.filter(e=>e.label.length>0),n=Math.max(0,...t.map(e=>e.label.length));return[...e.facts.map(e=>e.label.length===0?e.value:`${e.label.padEnd(n)} ${e.value}`),...e.output]}case`incomplete`:return[`Finish with \`${e.resumeCommand}\``];case`failed`:return e.message.replace(" Try again with `",`
1
+ function registryItemProgress(e){return(t,n,r)=>{e.setNavigation?.(void 0),e.replaceContent?.(),e.setStatus(`Adding ${t.title??t.name} · ${n+1} of ${r}`)}}function outcomeDetails(e){switch(e.kind){case`installed`:{let t=e.facts.filter(e=>e.label.length>0),n=Math.max(0,...t.map(e=>e.label.length));return[...e.facts.map(e=>e.label.length===0?e.value:`${e.label.padEnd(n)} ${e.value}`),...e.output]}case`incomplete`:return[...e.reason===void 0?[]:[e.reason],`Finish with \`${e.resumeCommand}\``];case`failed`:return e.message.replace(" Try again with `",`
2
2
  Try again with \``).split(`
3
3
  `);case`cancelled`:return[]}}function registryOutcomeSummary(e){switch(e.kind){case`installed`:return`Added ${e.title}`;case`incomplete`:return`Added ${e.title} · setup not finished`;case`failed`:return`Couldn't add ${e.title}`;case`cancelled`:return`${e.title} not added`}}function hasFailedOutcome(e){return e.some(e=>e.kind===`failed`)}function registryCommandOutcome(e,t=[]){let{outcomes:n}=e,r=n.filter(e=>e.kind===`installed`||e.kind===`incomplete`).length,i=n.length===1?registryOutcomeSummary(n[0]):`Added ${r} of ${n.length} items`,a=n.length===1?outcomeDetails(n[0]):n.flatMap(e=>[`* ${registryOutcomeSummary(e)}`,...outcomeDetails(e).map(e=>` ${e}`)]);return a.push(...t.map(e=>`⚠ ${e}`)),{failed:hasFailedOutcome(n),summary:i,message:a.join(`
4
4
  `)}}export{registryCommandOutcome,registryItemProgress};
@@ -1,5 +1,6 @@
1
1
  import type { ModelAccessChange, ModelConnectionSelection } from "#shared/model-connection.js";
2
2
  import { runModelLogin } from "#setup/flows/model-login.js";
3
+ import { runLoginFlow } from "#setup/flows/login.js";
3
4
  import { runDeployFlow } from "#setup/flows/deploy.js";
4
5
  import { runInstallVercelCliFlow } from "#setup/flows/install-vercel-cli.js";
5
6
  import { runRegistryFlow } from "#setup/flows/registry.js";
@@ -44,6 +45,7 @@ export interface TuiSetupFlows {
44
45
  runInstallVercelCliFlow: typeof runInstallVercelCliFlow;
45
46
  runRegistryFlow: typeof runRegistryFlow;
46
47
  runDeployFlow: typeof runDeployFlow;
48
+ runLoginFlow?: typeof runLoginFlow;
47
49
  }
48
50
  /** Setup owns flow-close behavior; the command adapter receives only the transcript outcome. */
49
51
  export interface TuiSetupCommandResult extends PromptCommandOutcome {
@@ -1,2 +1,2 @@
1
- import{registryCommandOutcome,registryItemProgress}from"./registry-result-message.js";import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{LOGIN_CONNECTION_OPTIONS}from"#setup/flows/model-login-options.js";import{runModelLogin}from"#setup/flows/model-login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{RegistryFlowFailedError,runRegistryFlow}from"#setup/flows/registry.js";function muteableRenderer(e,t,n,r){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setNavigation:n=>{t()||e.setNavigation?.(n)},setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,i)=>{i===`warning`&&r.push(n),(!t()||i===`warning`||i===`error`)&&e.renderLine(n,i)},replaceContent:n=>{t()||e.replaceContent?.(n)},renderOutput:n=>{t()||e.renderOutput(n)},withInheritedStdio:t=>e.withInheritedStdio(t),withExclusiveTerminal:e=>n?.(e)??e()}}function cancelledSetupResult(){return{message:``,cancelled:!0,preserveFlowDiagnostics:!1}}async function runTuiSetupCommand(e){let{command:t}=e,n=!1,r=new AbortController,i=[],a=muteableRenderer(e.renderer,()=>n,e.withExclusiveTerminal,i),o=(e.createPrompter??createTuiPrompter)(a),cancelActiveRegistryItem,runRegistryItem=async e=>{let t=new AbortController;cancelActiveRegistryItem=()=>t.abort(new WizardCancelledError);try{return await e(AbortSignal.any([r.signal,t.signal]))}finally{cancelActiveRegistryItem=void 0}},s=e.renderer.waitForInterrupt(),c=executeSetupCommand(e,o,a,r.signal,runRegistryItem,i),l=c.then(e=>({kind:`outcome`,value:e}));try{for(;;){let i=!1;try{let a=await Promise.race([l,s.promise.then(e=>({kind:`interrupt`,interrupt:e}))]);if(a.kind===`outcome`)return withCommandSummary(e,a.value);if(t===`add`&&a.interrupt===`escape`&&cancelActiveRegistryItem!==void 0)cancelActiveRegistryItem(),i=!0;else{n=!0,r.abort(new WizardCancelledError);let t=await c;return withCommandSummary(e,t.partial===!0?t:{...t,...cancelledSetupResult(),failed:void 0,summary:void 0})}}finally{s.dispose()}i&&(s=e.renderer.waitForInterrupt())}}finally{e.renderer.setStatus(void 0)}}async function executeSetupCommand(e,t,n,r,i,a){let{command:o,appRoot:s}=e,c={runInstallVercelCliFlow,runRegistryFlow,runDeployFlow,...e.flows};try{switch(o){case`login`:{let n=await(c.runModelLogin??runModelLogin)({appRoot:s,agentRoot:e.agentRoot,prompter:t,signal:r,automatic:e.initialModelStep===`provider`,selected:e.initialLoginConnection,connectionMessage:``,withConnectionUpdate:e.withExclusiveTerminal});if(n.kind===`cancelled`)return{message:e.initialModelStep===`provider`?`Connect a model with /login when you’re ready.`:``,cancelled:!0,preserveFlowDiagnostics:!1};let i=LOGIN_CONNECTION_OPTIONS.find(t=>t.value===e.initialLoginConnection);return{message:``,summary:i===void 0?`Connected`:`Connected with ${i.label}`,effect:{kind:`model-access-changed`,reload:n.reload,...n.model&&{model:n.model}},preserveFlowDiagnostics:!1}}case`add`:{let o=await c.runRegistryFlow({appRoot:s,installRoot:e.agentRoot,prompter:t,signal:r,initialAddress:e.initialRegistryAddress,onScreen:e.onOnboardingScreen,onItemStart:registryItemProgress(n),runItem:i});if(o.kind===`cancelled`||o.result.outcomes.length===0)return cancelledSetupResult();let l=registryResult(o.result,a);return o.result.cancelled===!0&&(l.partial=!0),o.result.deployed===`production`&&(l.effect={kind:`deployed`}),l}case`deploy`:{let e=await c.runDeployFlow({appRoot:s,prompter:t,interactive:!0,signal:r});return e.kind===`cancelled`?cancelledSetupResult():e.kind===`needs-link`?{message:`Not linked to a Vercel project. Run eve deploy in an interactive terminal to link it.`,failed:!0,preserveFlowDiagnostics:!0}:e.kind===`local-model`?{message:`ChatGPT subscription models are local-only. Switch to an AI Gateway or server-authenticated model before deploying.`,failed:!0,preserveFlowDiagnostics:!0}:{message:``,summary:e.productionUrl===void 0?`Deployed`:`Deployed to ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return cancelledSetupResult();let n=e instanceof RegistryFlowFailedError?e.cause:e,i=await vercelCliUpgradeOutcome(n,o,c,{appRoot:s,prompter:t,signal:r});if(i!==void 0)return withRegistryResults(i,e,a);let l=vercelActionOutcome(n,o);return l===void 0?e instanceof RegistryFlowFailedError?withRegistryResults({message:e.message,failed:!0,preserveFlowDiagnostics:!1},e,a):{message:e instanceof Error?e.message:String(e),failed:!0,preserveFlowDiagnostics:o!==`add`}:withRegistryResults(l,e,a)}}function fallbackSummaries(e){switch(e.command){case`add`:{let t=e.initialRegistryAddress;return t===void 0?void 0:{error:`Couldn't add ${t}`,cancelled:`${t} not added`}}case`login`:return{error:`Couldn't connect a model`,cancelled:`Login cancelled`};case`deploy`:return{error:`Couldn't deploy`,cancelled:`Deploy cancelled`}}}function withCommandSummary(e,t){let n=fallbackSummaries(e);return t.summary!==void 0||n===void 0?t:t.failed===!0?{...t,summary:n.error}:t.cancelled===!0?{...t,summary:n.cancelled}:t}function registryResult(e,t){let{failed:n,summary:r,message:i}=registryCommandOutcome(e,t),a=e.cancelled===!0||e.outcomes.some(e=>e.kind===`cancelled`);return{message:i,summary:r,...n&&{failed:!0},...!n&&a&&{cancelled:!0},preserveFlowDiagnostics:!1}}function withRegistryResults(e,t,n){if(!(t instanceof RegistryFlowFailedError))return e;let r=registryResult(t.completed,n);return{...e,summary:r.summary,message:[r.message,e.message].filter(e=>e!==``).join(`
2
- `),partial:!0,failed:!0,preserveFlowDiagnostics:!1}}async function vercelCliUpgradeOutcome(e,t,n,r){if(!(e instanceof HumanActionRequiredError)||e.action.kind!==`vercel-cli-upgrade`)return;let i;try{i=await r.prompter.select({message:`Your Vercel CLI needs an update to list your teams. Upgrade now?`,options:[{value:`upgrade`,label:`Upgrade Vercel CLI`,description:`Run the Vercel CLI's native upgrader`},{value:`later`,label:`Not now`}],initialValue:`upgrade`})}catch{i=`later`}if(i===`later`)return{message:`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`,failed:!0,preserveFlowDiagnostics:!0};let a;try{a=await n.runInstallVercelCliFlow({appRoot:r.appRoot,prompter:r.prompter,signal:r.signal,upgrade:!0})}catch(e){return{message:vercelCliUpgradeFailureMessage(t,errorMessage(e)),failed:!0,preserveFlowDiagnostics:!0}}switch(a.kind){case`installed`:return{message:`Upgraded the Vercel CLI. Retry /${t}.`,failed:!0,preserveFlowDiagnostics:!1};case`failed`:return{message:vercelCliUpgradeFailureMessage(t,a.reason),failed:!0,preserveFlowDiagnostics:!0};case`cancelled`:return{message:`Vercel CLI upgrade cancelled — run \`vercel upgrade\`, then retry /${t}.`,failed:!0,preserveFlowDiagnostics:!0};case`already`:return{message:`The Vercel CLI is already up to date. Retry /${t}.`,failed:!0,preserveFlowDiagnostics:!1}}}function errorMessage(e){let t=(e instanceof Error?e.message:String(e)).replace(/\s+/gu,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}function vercelCliUpgradeFailureMessage(e,t){return`Couldn't upgrade the Vercel CLI${t===void 0||t===``?``:` (${t})`} — run \`vercel upgrade\`, then retry /${e}.`}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,failed:!0,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /deploy to connect your Vercel account, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — check your team access and SSO, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /deploy to install it, then retry /${t}.`;case`vercel-cli-upgrade`:return`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`;default:return}}export{runTuiSetupCommand};
1
+ import{registryCommandOutcome,registryItemProgress}from"./registry-result-message.js";import{createTuiPrompter}from"./tui-prompter.js";import{runDeployFlow}from"#setup/flows/deploy.js";import{WizardCancelledError}from"#setup/step.js";import{LOGIN_CONNECTION_OPTIONS}from"#setup/flows/model-login-options.js";import{runLoginFlow}from"#setup/flows/login.js";import{runModelLogin}from"#setup/flows/model-login.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{runInstallVercelCliFlow}from"#setup/flows/install-vercel-cli.js";import{RegistryFlowFailedError,runRegistryFlow}from"#setup/flows/registry.js";function muteableRenderer(e,t,n,r){return{readSelect:n=>t()?Promise.resolve(void 0):e.readSelect(n),readEditableSelect:n=>t()?Promise.resolve(void 0):e.readEditableSelect(n),readProviderPicker:n=>t()?Promise.resolve(void 0):e.readProviderPicker(n),readText:n=>t()?Promise.resolve(void 0):e.readText(n),readAcknowledge:n=>t()?Promise.resolve():e.readAcknowledge(n),readChoice:n=>t()?{choice:Promise.resolve(void 0),close:()=>{}}:e.readChoice(n),setNavigation:n=>{t()||e.setNavigation?.(n)},setStatus:n=>{t()||e.setStatus(n)},renderLine:(n,i)=>{i===`warning`&&r.push(n),(!t()||i===`warning`||i===`error`)&&e.renderLine(n,i)},replaceContent:n=>{t()||e.replaceContent?.(n)},renderOutput:n=>{t()||e.renderOutput(n)},withInheritedStdio:t=>e.withInheritedStdio(t),withExclusiveTerminal:e=>n?.(e)??e()}}function cancelledSetupResult(){return{message:``,cancelled:!0,preserveFlowDiagnostics:!1}}async function runTuiSetupCommand(e){let{command:t}=e,n=!1,r=new AbortController,i=[],a=muteableRenderer(e.renderer,()=>n,e.withExclusiveTerminal,i),o=(e.createPrompter??createTuiPrompter)(a),cancelActiveRegistryItem,runRegistryItem=async e=>{let t=new AbortController;cancelActiveRegistryItem=()=>t.abort(new WizardCancelledError);try{return await e(AbortSignal.any([r.signal,t.signal]))}finally{cancelActiveRegistryItem=void 0}},s=e.renderer.waitForInterrupt(),c=executeSetupCommand(e,o,a,r.signal,runRegistryItem,i),l=c.then(e=>({kind:`outcome`,value:e}));try{for(;;){let i=!1;try{let a=await Promise.race([l,s.promise.then(e=>({kind:`interrupt`,interrupt:e}))]);if(a.kind===`outcome`)return withCommandSummary(e,a.value);if(t===`add`&&a.interrupt===`escape`&&cancelActiveRegistryItem!==void 0)cancelActiveRegistryItem(),i=!0;else{n=!0,r.abort(new WizardCancelledError);let t=await c;return withCommandSummary(e,t.partial===!0?t:{...t,...cancelledSetupResult(),failed:void 0,summary:void 0})}}finally{s.dispose()}i&&(s=e.renderer.waitForInterrupt())}}finally{e.renderer.setStatus(void 0)}}async function executeSetupCommand(e,t,n,r,i,a){let{command:o,appRoot:s}=e,c={runInstallVercelCliFlow,runRegistryFlow,runDeployFlow,...e.flows};try{switch(o){case`login`:{let n=await(c.runModelLogin??runModelLogin)({appRoot:s,agentRoot:e.agentRoot,prompter:t,signal:r,automatic:e.initialModelStep===`provider`,selected:e.initialLoginConnection,connectionMessage:``,withConnectionUpdate:e.withExclusiveTerminal});if(n.kind===`cancelled`)return{message:e.initialModelStep===`provider`?`Connect a model with /login when you’re ready.`:``,cancelled:!0,preserveFlowDiagnostics:!1};let i=LOGIN_CONNECTION_OPTIONS.find(t=>t.value===e.initialLoginConnection);return{message:``,summary:i===void 0?`Connected`:`Connected with ${i.label}`,effect:{kind:`model-access-changed`,reload:n.reload,...n.model&&{model:n.model}},preserveFlowDiagnostics:!1}}case`add`:{let runAdd=a=>c.runRegistryFlow({appRoot:s,installRoot:e.agentRoot,prompter:t,signal:r,onScreen:e.onOnboardingScreen,onItemStart:registryItemProgress(n),runItem:i,...a}),o=await runAdd({initialAddress:e.initialRegistryAddress});if(o.kind===`cancelled`||o.result.outcomes.length===0)return cancelledSetupResult();let l=await recoverVercelLoginSetup(o.result,{appRoot:s,prompter:t,signal:r,runLoginFlow:c.runLoginFlow??runLoginFlow,resumeSetup:e=>runAdd({initialAddress:e,skipInstall:!0})}),u=registryResult(l,a);return l.cancelled===!0&&(u.partial=!0),l.deployed===`production`&&(u.effect={kind:`deployed`}),u}case`deploy`:{let e=await c.runDeployFlow({appRoot:s,prompter:t,interactive:!0,signal:r});return e.kind===`cancelled`?cancelledSetupResult():e.kind===`needs-link`?{message:`Not linked to a Vercel project. Run eve deploy in an interactive terminal to link it.`,failed:!0,preserveFlowDiagnostics:!0}:e.kind===`local-model`?{message:`ChatGPT subscription models are local-only. Switch to an AI Gateway or server-authenticated model before deploying.`,failed:!0,preserveFlowDiagnostics:!0}:{message:``,summary:e.productionUrl===void 0?`Deployed`:`Deployed to ${e.productionUrl}`,preserveFlowDiagnostics:!0,effect:{kind:`deployed`}}}}}catch(e){if(e instanceof WizardCancelledError)return cancelledSetupResult();let n=e instanceof RegistryFlowFailedError?e.cause:e,i=await vercelCliUpgradeOutcome(n,o,c,{appRoot:s,prompter:t,signal:r});if(i!==void 0)return withRegistryResults(i,e,a);let l=vercelActionOutcome(n,o);return l===void 0?e instanceof RegistryFlowFailedError?withRegistryResults({message:e.message,failed:!0,preserveFlowDiagnostics:!1},e,a):{message:e instanceof Error?e.message:String(e),failed:!0,preserveFlowDiagnostics:o!==`add`}:withRegistryResults(l,e,a)}}function fallbackSummaries(e){switch(e.command){case`add`:{let t=e.initialRegistryAddress;return t===void 0?void 0:{error:`Couldn't add ${t}`,cancelled:`${t} not added`}}case`login`:return{error:`Couldn't connect a model`,cancelled:`Login cancelled`};case`deploy`:return{error:`Couldn't deploy`,cancelled:`Deploy cancelled`}}}function withCommandSummary(e,t){let n=fallbackSummaries(e);return t.summary!==void 0||n===void 0?t:t.failed===!0?{...t,summary:n.error}:t.cancelled===!0?{...t,summary:n.cancelled}:t}function registryResult(e,t){let{failed:n,summary:r,message:i}=registryCommandOutcome(e,t),a=e.cancelled===!0||e.outcomes.some(e=>e.kind===`cancelled`);return{message:i,summary:r,...n&&{failed:!0},...!n&&a&&{cancelled:!0},preserveFlowDiagnostics:!1}}function withRegistryResults(e,t,n){if(!(t instanceof RegistryFlowFailedError))return e;let r=registryResult(t.completed,n);return{...e,summary:r.summary,message:[r.message,e.message].filter(e=>e!==``).join(`
2
+ `),partial:!0,failed:!0,preserveFlowDiagnostics:!1}}async function recoverVercelLoginSetup(e,t){let n=e.outcomes.filter(e=>e.kind===`incomplete`&&e.prerequisite?.code===`vercel-login`);if(n.length===0)return e;let r;try{r=await t.prompter.select({message:`Setup needs the Vercel CLI, which isn't logged in. Log in now?`,options:[{value:`login`,label:`Log in to Vercel`,description:"Runs `vercel login` in your browser, then finishes setup"},{value:`later`,label:`Not now`}],initialValue:`login`})}catch{r=`later`}if(r===`later`)return e;let i=await t.runLoginFlow({appRoot:t.appRoot,prompter:t.prompter,signal:t.signal});if(i.kind!==`logged-in`&&i.kind!==`already`)return e;let a=[...e.outcomes],o=e.deployed;for(let e of n){if(e.kind!==`incomplete`)continue;let n=await t.resumeSetup(e.address);n.kind===`done`&&n.result.outcomes.length===1&&(a[a.indexOf(e)]=n.result.outcomes[0],o??=n.result.deployed)}return{...e,outcomes:a,...o!==void 0&&{deployed:o}}}async function vercelCliUpgradeOutcome(e,t,n,r){if(!(e instanceof HumanActionRequiredError)||e.action.kind!==`vercel-cli-upgrade`)return;let i;try{i=await r.prompter.select({message:`Your Vercel CLI needs an update to list your teams. Upgrade now?`,options:[{value:`upgrade`,label:`Upgrade Vercel CLI`,description:`Run the Vercel CLI's native upgrader`},{value:`later`,label:`Not now`}],initialValue:`upgrade`})}catch{i=`later`}if(i===`later`)return{message:`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`,failed:!0,preserveFlowDiagnostics:!0};let a;try{a=await n.runInstallVercelCliFlow({appRoot:r.appRoot,prompter:r.prompter,signal:r.signal,upgrade:!0})}catch(e){return{message:vercelCliUpgradeFailureMessage(t,errorMessage(e)),failed:!0,preserveFlowDiagnostics:!0}}switch(a.kind){case`installed`:return{message:`Upgraded the Vercel CLI. Retry /${t}.`,failed:!0,preserveFlowDiagnostics:!1};case`failed`:return{message:vercelCliUpgradeFailureMessage(t,a.reason),failed:!0,preserveFlowDiagnostics:!0};case`cancelled`:return{message:`Vercel CLI upgrade cancelled — run \`vercel upgrade\`, then retry /${t}.`,failed:!0,preserveFlowDiagnostics:!0};case`already`:return{message:`The Vercel CLI is already up to date. Retry /${t}.`,failed:!0,preserveFlowDiagnostics:!1}}}function errorMessage(e){let t=(e instanceof Error?e.message:String(e)).replace(/\s+/gu,` `).trim();return t.length<=240?t:`${t.slice(0,239)}…`}function vercelCliUpgradeFailureMessage(e,t){return`Couldn't upgrade the Vercel CLI${t===void 0||t===``?``:` (${t})`} — run \`vercel upgrade\`, then retry /${e}.`}function vercelActionOutcome(e,t){if(!(e instanceof HumanActionRequiredError))return;let n=vercelActionMessage(e.action.kind,t);return n===void 0?void 0:{message:n,failed:!0,preserveFlowDiagnostics:!0}}function vercelActionMessage(e,t){switch(e){case`vercel-login`:return`You're not logged in to Vercel — run /deploy to connect your Vercel account, then retry /${t}.`;case`vercel-forbidden`:return`Vercel denied access to that team — check your team access and SSO, then retry /${t}.`;case`vercel-cli-missing`:return`The Vercel CLI isn't installed — run /deploy to install it, then retry /${t}.`;case`vercel-cli-upgrade`:return`The Vercel CLI needs an update — run \`vercel upgrade\`, then retry /${t}.`;default:return}}export{runTuiSetupCommand};
@@ -22,3 +22,4 @@ export { isCurrentTurnBoundaryEvent, isTurnFailureEvent } from "#protocol/messag
22
22
  export type { InputOption, InputRequest, InputRequestKind, InputResponse } from "#shared/input.js";
23
23
  export { isInputRequest, isInputResponse, parseInputResponse, parseInputResponses, } from "#shared/input.js";
24
24
  export { resolveTextToResponse, resolveTextToResponses } from "#channel/resolve-text.js";
25
+ export type { ToolStub, ToolStubOutcome } from "#tool-stubs/types.js";
@@ -25,7 +25,7 @@ export declare class ClientSession {
25
25
  /** @internal */
26
26
  constructor(context: ClientSessionContext, state: ClientSessionState);
27
27
  /** @internal */
28
- static create<TOutput = unknown>(context: ClientSessionContext, input: SendTurnInput<TOutput>): Promise<{
28
+ static create<TOutput = unknown>(context: ClientSessionContext, input: SendTurnInput<TOutput> & CreateSessionOptions): Promise<{
29
29
  readonly response: MessageResponse<TOutput>;
30
30
  readonly session: ClientSession;
31
31
  }>;
@@ -1 +1 @@
1
- import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath,createEveSessionStreamRoutePath}from"#protocol/routes.js";import{TurnSegment}from"#client/session-utils.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{followStreamIterable,sleep}from"#client/open-stream.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{ClientAgentSession}from"#client/agent-session.js";import{cancelClientSession,clearClientSession,compactClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#tools/schema.js";const followSession=Symbol(`followClientSession`);var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(e,t){let n=await postTurn(e,EVE_SESSION_ROUTE_PATH,t,!0),{sessionId:r}=await readAcceptedMessage(n),i=new ClientSession(e,{sessionId:r,streamIndex:0});return{response:i.#r(n,t,0),session:i}}static async prewarm(e,t={}){let{sessionId:n}=await readAcceptedMessage(await postCreateSession(e,t));return new ClientSession(e,{sessionId:n,streamIndex:0})}get state(){return this.#t}async snapshot(e){e?.signal?.throwIfAborted();let t=[];for await(let n of this.#s({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return e?.signal?.throwIfAborted(),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e},!0)}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e},!1)}async#n(e,t){let n=this.#t.streamIndex,r=createEveSessionRoutePath(this.#t.sessionId),i=t?await postSessionSend(this.#e,r,e):await postTurn(this.#e,r,e,!1),{sessionId:a,deliveryId:o}=await readAcceptedMessage(i,this.#t.sessionId);if(a!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);if(e.message!==void 0&&o===void 0)throw Error(`Message route did not return a delivery id. Update the server before sending with this client.`);return this.#r(i,e,n,e.message===void 0?void 0:o)}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#a(e)}agent(e){return new ClientAgentSession(this.#e,e)}[followSession](e){return this.#a({...e,keepAlive:!0})}#r(e,t,n,r){return e.body?.cancel().catch(()=>{}),new MessageResponse({cancelTurn:async e=>await this.cancel({turnId:e}),createStream:e=>this.#i(n,t,r,e),deliveryId:r,sessionId:this.#t.sessionId})}async*#i(e,t,n,r){let i=0,a=n===void 0,o=!1,s=new TurnSegment({followCallbacks:!0});try{for await(let c of r??this.#s({headers:t.headers,keepAlive:!0,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy})){if(i+=1,n!==void 0){let e=c.meta?.deliveryIds?.includes(n)===!0,t=c.type===`session.failed`||c.type===`session.completed`;if(!e&&t&&(!a||c.type===`session.completed`))throw Error(`The session ended before the accepted message reached its turn boundary.`);if(!a&&!e)continue;let r=c.meta?.deliveryIds!==void 0;if(!t&&r&&!e)continue;a=!0}if(o=s.observe(c),yield c,o)break}if(n!==void 0&&!o&&!t.signal?.aborted)throw Error(`The response stream ended before the accepted message reached its turn boundary.`)}finally{this.#o(e+i)}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;for await(let r of this.#s({follow:e?.follow,headers:e?.headers,keepAlive:e?.keepAlive,onCaughtUp:e?.onCaughtUp,resolveHeaders:e?.resolveHeaders,resolveReconnectPolicy:e?.resolveReconnectPolicy,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,t>=0&&this.#o(t+n),yield r}#o(e){this.#t={sessionId:this.#t.sessionId,streamIndex:Math.max(this.#t.streamIndex,e)}}#s(e){return followStreamIterable({onCaughtUp:e.onCaughtUp,follow:e.follow,host:this.#e.host,keepAlive:e.keepAlive,resolveHeaders:()=>this.#e.resolveHeaders(e.resolveHeaders?.()??e.headers),path:createEveSessionStreamRoutePath(this.#t.sessionId),redirect:this.#e.redirect,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy,resolveReconnectPolicy:e.resolveReconnectPolicy})}};function followClientSession(e,t){return e[followSession](t)}async function postSessionSend(e,t,n){let r=Date.now()+2e4,i=250;for(;;){try{return await postTurn(e,t,n,!1)}catch(e){if(!isSessionNotReady(e))throw e;let t=r-Date.now();if(t<=0)throw e;await sleep(Math.min(i,t),n.signal)}n.signal?.throwIfAborted(),i=Math.min(i*2,2e3)}}async function postCreateSession(e,t){let n=await e.resolveHeaders(t.headers),r=await fetch(createClientUrl(e.host,EVE_SESSION_ROUTE_PATH),{headers:n,method:`POST`,redirect:e.redirect,signal:t.signal??null});if(!r.ok){let e=await r.text();throw new ClientError(r.status,e,r.headers)}return r}function isSessionNotReady(e){return e instanceof ClientError&&e.status===409&&e.code===`session_not_ready`}async function postTurn(e,t,n,r){let i=createMessageBody(n,r);if(i===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);let a=await e.resolveHeaders(n.headers);a.set(`content-type`,`application/json`);let o=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(i),headers:a,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!o.ok){let e=await o.text();throw new ClientError(o.status,e,o.headers)}return o}async function readAcceptedMessage(e,t){let n=await e.json(),r=(typeof n.sessionId==`string`?n.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!r)throw Error(`Message route did not return a session id.`);return{sessionId:r,deliveryId:typeof n.deliveryId==`string`&&n.deliveryId.length>0?n.deliveryId:void 0}}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),!t&&e.message!==void 0&&e.turnPolicy!==void 0&&(n.turnPolicy=e.turnPolicy),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession,followClientSession};
1
+ import{EVE_SESSION_ROUTE_PATH,createEveSessionRoutePath,createEveSessionStreamRoutePath}from"#protocol/routes.js";import{TurnSegment}from"#client/session-utils.js";import{EVE_SESSION_ID_HEADER}from"#protocol/message.js";import{followStreamIterable,sleep}from"#client/open-stream.js";import{ClientError}from"#client/client-error.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{ClientAgentSession}from"#client/agent-session.js";import{cancelClientSession,clearClientSession,compactClientSession,resetClientSession}from"#client/session-controls.js";import{serializeOutputSchema}from"#tools/schema.js";const followSession=Symbol(`followClientSession`);var ClientSession=class ClientSession{#e;#t;constructor(e,t){this.#e=e,this.#t=t}static async create(e,t){let n=await postTurn(e,EVE_SESSION_ROUTE_PATH,t,!0,t.stubs),{sessionId:r}=await readAcceptedMessage(n),i=new ClientSession(e,{sessionId:r,streamIndex:0});return{response:i.#r(n,t,0),session:i}}static async prewarm(e,t={}){let{sessionId:n}=await readAcceptedMessage(await postCreateSession(e,t));return new ClientSession(e,{sessionId:n,streamIndex:0})}get state(){return this.#t}async snapshot(e){e?.signal?.throwIfAborted();let t=[];for await(let n of this.#s({follow:!1,signal:e?.signal,startIndex:0}))t.push(n);return e?.signal?.throwIfAborted(),{events:t,session:{sessionId:this.#t.sessionId,streamIndex:t.length}}}async send(e,t={}){return await this.#n({...t,message:e},!0)}async respond(e,t={}){if(e.length===0)throw Error(`ClientSession.respond() requires at least one input response.`);return await this.#n({...t,inputResponses:e},!1)}async#n(e,t){let n=this.#t.streamIndex,r=createEveSessionRoutePath(this.#t.sessionId),i=t?await postSessionSend(this.#e,r,e):await postTurn(this.#e,r,e,!1),{sessionId:a,deliveryId:o}=await readAcceptedMessage(i,this.#t.sessionId);if(a!==this.#t.sessionId)throw Error(`Message route returned a different session id.`);if(e.message!==void 0&&o===void 0)throw Error(`Message route did not return a delivery id. Update the server before sending with this client.`);return this.#r(i,e,n,e.message===void 0?void 0:o)}async cancel(e){return await cancelClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}async clear(){return await clearClientSession({context:this.#e,sessionId:this.#t.sessionId})}async compact(){return await compactClientSession({context:this.#e,sessionId:this.#t.sessionId})}async reset(e){return await resetClientSession({context:this.#e,options:e,sessionId:this.#t.sessionId})}stream(e){if(e?.follow===!1&&(e.startIndex??this.#t.streamIndex)<0)throw Error(`stream({ follow: false }) requires a nonnegative startIndex; a tail-relative cursor cannot be bounded.`);return this.#a(e)}agent(e){return new ClientAgentSession(this.#e,e)}[followSession](e){return this.#a({...e,keepAlive:!0})}#r(e,t,n,r){return e.body?.cancel().catch(()=>{}),new MessageResponse({cancelTurn:async e=>await this.cancel({turnId:e}),createStream:e=>this.#i(n,t,r,e),deliveryId:r,sessionId:this.#t.sessionId})}async*#i(e,t,n,r){let i=0,a=n===void 0,o=!1,s=new TurnSegment({followCallbacks:!0});try{for await(let c of r??this.#s({headers:t.headers,keepAlive:!0,signal:t.signal,startIndex:e,streamReconnectPolicy:t.streamReconnectPolicy})){if(i+=1,n!==void 0){let e=c.meta?.deliveryIds?.includes(n)===!0,t=c.type===`session.failed`||c.type===`session.completed`;if(!e&&t&&(!a||c.type===`session.completed`))throw Error(`The session ended before the accepted message reached its turn boundary.`);if(!a&&!e)continue;let r=c.meta?.deliveryIds!==void 0;if(!t&&r&&!e)continue;a=!0}if(o=s.observe(c),yield c,o)break}if(n!==void 0&&!o&&!t.signal?.aborted)throw Error(`The response stream ended before the accepted message reached its turn boundary.`)}finally{this.#o(e+i)}}async*#a(e){let t=e?.startIndex??this.#t.streamIndex,n=0;for await(let r of this.#s({follow:e?.follow,headers:e?.headers,keepAlive:e?.keepAlive,onCaughtUp:e?.onCaughtUp,resolveHeaders:e?.resolveHeaders,resolveReconnectPolicy:e?.resolveReconnectPolicy,signal:e?.signal,startIndex:t,streamReconnectPolicy:e?.streamReconnectPolicy}))n+=1,t>=0&&this.#o(t+n),yield r}#o(e){this.#t={sessionId:this.#t.sessionId,streamIndex:Math.max(this.#t.streamIndex,e)}}#s(e){return followStreamIterable({onCaughtUp:e.onCaughtUp,follow:e.follow,host:this.#e.host,keepAlive:e.keepAlive,resolveHeaders:()=>this.#e.resolveHeaders(e.resolveHeaders?.()??e.headers),path:createEveSessionStreamRoutePath(this.#t.sessionId),redirect:this.#e.redirect,signal:e.signal,startIndex:e.startIndex,streamReconnectPolicy:e.streamReconnectPolicy,resolveReconnectPolicy:e.resolveReconnectPolicy})}};function followClientSession(e,t){return e[followSession](t)}async function postSessionSend(e,t,n){let r=Date.now()+2e4,i=250;for(;;){try{return await postTurn(e,t,n,!1)}catch(e){if(!isSessionNotReady(e))throw e;let t=r-Date.now();if(t<=0)throw e;await sleep(Math.min(i,t),n.signal)}n.signal?.throwIfAborted(),i=Math.min(i*2,2e3)}}async function postCreateSession(e,t){let n=await e.resolveHeaders(t.headers),r=t.stubs===void 0?void 0:JSON.stringify({stubs:t.stubs});r!==void 0&&n.set(`content-type`,`application/json`);let i=await fetch(createClientUrl(e.host,EVE_SESSION_ROUTE_PATH),{body:r,headers:n,method:`POST`,redirect:e.redirect,signal:t.signal??null});if(!i.ok){let e=await i.text();throw new ClientError(i.status,e,i.headers)}return i}function isSessionNotReady(e){return e instanceof ClientError&&e.status===409&&e.code===`session_not_ready`}async function postTurn(e,t,n,r,i){let a=createMessageBody(n,r);if(a===null)throw Error(r?`Creating a session requires a non-empty message.`:`A session turn requires a non-empty message or inputResponses.`);i!==void 0&&(a.stubs=i);let o=await e.resolveHeaders(n.headers);o.set(`content-type`,`application/json`);let s=await fetch(createClientUrl(e.host,t),{body:JSON.stringify(a),headers:o,method:`POST`,redirect:e.redirect,signal:n.signal??null});if(!s.ok){let e=await s.text();throw new ClientError(s.status,e,s.headers)}return s}async function readAcceptedMessage(e,t){let n=await e.json(),r=(typeof n.sessionId==`string`?n.sessionId:void 0)??e.headers.get(EVE_SESSION_ID_HEADER)?.trim()??t;if(!r)throw Error(`Message route did not return a session id.`);return{sessionId:r,deliveryId:typeof n.deliveryId==`string`&&n.deliveryId.length>0?n.deliveryId:void 0}}function createMessageBody(e,t){let n={};e.message!==void 0&&(n.message=e.message),e.inputResponses!==void 0&&e.inputResponses.length>0&&(n.inputResponses=e.inputResponses),!t&&e.message!==void 0&&e.turnPolicy!==void 0&&(n.turnPolicy=e.turnPolicy),e.clientContext!==void 0&&(n.clientContext=e.clientContext);let r=serializeOutputSchema(e.outputSchema);return r!==void 0&&(n.outputSchema=r),t&&n.message===void 0||n.message===void 0&&n.inputResponses===void 0?null:n}export{ClientSession,followClientSession};
@@ -16,7 +16,7 @@ export declare class ClientSessions {
16
16
  /** @internal */
17
17
  constructor(context: ClientSessionContext);
18
18
  /** Creates a session and starts its first turn with a message. */
19
- create<TOutput = unknown>(input: SendTurnInput<TOutput>): Promise<CreatedClientSession<TOutput>>;
19
+ create<TOutput = unknown>(input: SendTurnInput<TOutput> & CreateSessionOptions): Promise<CreatedClientSession<TOutput>>;
20
20
  /** Creates a conversation session before its first turn. */
21
21
  create(options?: CreateSessionOptions): Promise<CreatedIdleClientSession>;
22
22
  /** Attaches a fixed handle to a known session ID without performing I/O. */
@@ -8,6 +8,7 @@ import type { ResetStatus } from "#protocol/reset-session.js";
8
8
  import type { TurnPolicy } from "#channel/types.js";
9
9
  import type { InputRequest, InputResponse } from "#shared/input.js";
10
10
  import type { JsonObject } from "#shared/json.js";
11
+ import type { ToolStub } from "#tool-stubs/types.js";
11
12
  export type { HealthResult } from "#client/health-schema.js";
12
13
  export type { AgentInfoChannelEntry, AgentInfoChannels, AgentInfoConnectionEntry, AgentInfoDynamicResolverEntry, AgentInfoEntry, AgentInfoHookEntry, AgentInfoInstructions, AgentInfoInstructionsEntry, AgentInfoMemoryEntry, AgentInfoResult, AgentInfoRemoteAgentEntry, AgentInfoSandboxEntry, AgentInfoScheduleEntry, AgentInfoSkillEntry, AgentInfoSource, AgentInfoSubagentEntry, AgentInfoToolEntry, AgentInfoTools, } from "./agent-info-schema.js";
13
14
  /**
@@ -81,6 +82,11 @@ export interface SendTurnInput<TOutput = unknown> extends SendTurnOptions<TOutpu
81
82
  }
82
83
  /** Request options for creating a conversation session before its first turn. */
83
84
  export interface CreateSessionOptions {
85
+ /**
86
+ * Tool stubs stay fixed for this session and its local subagents.
87
+ * The server must authorize their use.
88
+ */
89
+ readonly stubs?: readonly ToolStub[];
84
90
  /** Abort signal for cancelling the creation request. */
85
91
  readonly signal?: AbortSignal;
86
92
  /** Additional headers for this request only. */
@@ -58,7 +58,7 @@
58
58
  "zod": "4.5.4",
59
59
  "zod-validation-error": "5.0.0"
60
60
  },
61
- "scriptHash": "f4dd2f26745407f5b94342ad15f90a1bf4d0cb1fe83bdebaf282f96684006c66",
61
+ "scriptHash": "e59fccb9248f66a6a9d9b8d97e416fb2ac7576b29087348dc2ecf7a1e82b093d",
62
62
  "toolVersions": {
63
63
  "rolldown": "1.2.9",
64
64
  "typescript": "7.0.2"