eve 0.24.5 → 0.25.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 (161) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/src/channel/cancel.d.ts +8 -0
  3. package/dist/src/channel/cancel.js +1 -0
  4. package/dist/src/channel/routes.d.ts +25 -4
  5. package/dist/src/channel/session.d.ts +10 -1
  6. package/dist/src/channel/session.js +1 -1
  7. package/dist/src/channel/types.d.ts +8 -0
  8. package/dist/src/chunks/{use-eve-agent-8rerxDHY.js → use-eve-agent-CQIeqmKc.js} +73 -66
  9. package/dist/src/chunks/{use-eve-agent-DhgdHzDG.js → use-eve-agent-Cy73lgA6.js} +73 -66
  10. package/dist/src/cli/commands/agent-instructions.js +1 -1
  11. package/dist/src/cli/commands/channels.js +1 -1
  12. package/dist/src/cli/commands/extension-build.d.ts +1 -1
  13. package/dist/src/cli/commands/extension-build.js +1 -1
  14. package/dist/src/client/output-schema.d.ts +0 -7
  15. package/dist/src/client/output-schema.js +1 -1
  16. package/dist/src/client/session.d.ts +6 -2
  17. package/dist/src/client/session.js +1 -1
  18. package/dist/src/compiler/extension-compatibility.d.ts +56 -0
  19. package/dist/src/compiler/extension-compatibility.js +1 -0
  20. package/dist/src/compiler/normalize-agent-config.js +1 -1
  21. package/dist/src/compiler/normalize-subagent.js +1 -1
  22. package/dist/src/context/build-dynamic-tools.js +1 -1
  23. package/dist/src/context/dynamic-tool-lifecycle.d.ts +1 -1
  24. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  25. package/dist/src/discover/discover-agent.d.ts +29 -7
  26. package/dist/src/discover/discover-agent.js +1 -1
  27. package/dist/src/discover/extensions.d.ts +43 -8
  28. package/dist/src/discover/extensions.js +1 -1
  29. package/dist/src/discover/filesystem.d.ts +3 -1
  30. package/dist/src/discover/filesystem.js +1 -1
  31. package/dist/src/discover/named-source-directory.js +1 -1
  32. package/dist/src/discover/skills.js +1 -1
  33. package/dist/src/evals/autoevals-client.js +2 -2
  34. package/dist/src/execution/node-step.js +1 -1
  35. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  36. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +1 -1
  37. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  38. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -1
  39. package/dist/src/execution/sandbox/development-cleanup.d.ts +1 -1
  40. package/dist/src/execution/sandbox/development-cleanup.js +1 -1
  41. package/dist/src/execution/sandbox/development-run.d.ts +0 -3
  42. package/dist/src/execution/sandbox/development-run.js +1 -1
  43. package/dist/src/execution/sandbox/ensure.js +1 -1
  44. package/dist/src/execution/subagent-tool.js +1 -1
  45. package/dist/src/execution/workflow-runtime.js +1 -1
  46. package/dist/src/harness/emission.js +1 -1
  47. package/dist/src/harness/input-extraction.d.ts +10 -1
  48. package/dist/src/harness/input-extraction.js +1 -1
  49. package/dist/src/harness/input-requests.d.ts +12 -2
  50. package/dist/src/harness/input-requests.js +1 -1
  51. package/dist/src/harness/messages.d.ts +8 -1
  52. package/dist/src/harness/messages.js +1 -1
  53. package/dist/src/harness/stale-input-responses.d.ts +26 -0
  54. package/dist/src/harness/stale-input-responses.js +3 -0
  55. package/dist/src/harness/step-hooks.d.ts +1 -12
  56. package/dist/src/harness/step-hooks.js +1 -1
  57. package/dist/src/harness/tool-call-input-errors.d.ts +11 -0
  58. package/dist/src/harness/tool-call-input-errors.js +1 -1
  59. package/dist/src/harness/tool-loop.js +2 -2
  60. package/dist/src/harness/workflow-sandbox.d.ts +1 -1
  61. package/dist/src/harness/workflow-sandbox.js +1 -1
  62. package/dist/src/internal/application/optional-package-install.d.ts +5 -0
  63. package/dist/src/internal/application/optional-package-install.js +1 -1
  64. package/dist/src/internal/application/package.js +1 -1
  65. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  66. package/dist/src/internal/authored-module-loader.d.ts +17 -0
  67. package/dist/src/internal/authored-module-loader.js +2 -2
  68. package/dist/src/internal/authored-module-map-loader.js +1 -1
  69. package/dist/src/internal/authored-package-boundary.d.ts +8 -0
  70. package/dist/src/internal/authored-package-boundary.js +1 -1
  71. package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +4 -0
  72. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  73. package/dist/src/internal/nitro/host/build-extension.d.ts +6 -21
  74. package/dist/src/internal/nitro/host/build-extension.js +2 -4
  75. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
  76. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  77. package/dist/src/internal/nitro/host/dev-workspace-extensions.d.ts +18 -0
  78. package/dist/src/internal/nitro/host/dev-workspace-extensions.js +1 -0
  79. package/dist/src/internal/nitro/host/extension-build-config.d.ts +18 -0
  80. package/dist/src/internal/nitro/host/extension-build-config.js +1 -0
  81. package/dist/src/internal/nitro/host/extension-capability-requirements.d.ts +10 -0
  82. package/dist/src/internal/nitro/host/extension-capability-requirements.js +1 -0
  83. package/dist/src/internal/nitro/host/extension-declarations.d.ts +10 -0
  84. package/dist/src/internal/nitro/host/extension-declarations.js +2 -0
  85. package/dist/src/internal/nitro/host/extension-distribution.d.ts +32 -0
  86. package/dist/src/internal/nitro/host/extension-distribution.js +3 -0
  87. package/dist/src/internal/nitro/host/extension-state-usage.d.ts +7 -0
  88. package/dist/src/internal/nitro/host/extension-state-usage.js +1 -0
  89. package/dist/src/internal/nitro/host/prepare-application-host.d.ts +5 -1
  90. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  91. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  92. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  93. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  94. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  95. package/dist/src/public/channels/index.d.ts +1 -1
  96. package/dist/src/public/definitions/channel.d.ts +1 -1
  97. package/dist/src/public/definitions/tool.d.ts +2 -2
  98. package/dist/src/public/tools/internal.js +1 -1
  99. package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
  100. package/dist/src/runtime/connections/openapi-client.js +1 -1
  101. package/dist/src/runtime/framework-tools/ask-question.d.ts +23 -9
  102. package/dist/src/runtime/framework-tools/ask-question.js +1 -1
  103. package/dist/src/runtime/framework-tools/bash.d.ts +10 -3
  104. package/dist/src/runtime/framework-tools/bash.js +1 -1
  105. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  106. package/dist/src/runtime/framework-tools/final-output.d.ts +1 -1
  107. package/dist/src/runtime/framework-tools/final-output.js +1 -1
  108. package/dist/src/runtime/framework-tools/glob.d.ts +12 -3
  109. package/dist/src/runtime/framework-tools/glob.js +1 -1
  110. package/dist/src/runtime/framework-tools/grep.d.ts +16 -3
  111. package/dist/src/runtime/framework-tools/grep.js +1 -1
  112. package/dist/src/runtime/framework-tools/read-file.d.ts +13 -3
  113. package/dist/src/runtime/framework-tools/read-file.js +1 -1
  114. package/dist/src/runtime/framework-tools/skill.d.ts +5 -2
  115. package/dist/src/runtime/framework-tools/skill.js +1 -1
  116. package/dist/src/runtime/framework-tools/todo.d.ts +57 -10
  117. package/dist/src/runtime/framework-tools/todo.js +3 -3
  118. package/dist/src/runtime/framework-tools/web-fetch.d.ts +16 -3
  119. package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
  120. package/dist/src/runtime/framework-tools/write-file.d.ts +9 -3
  121. package/dist/src/runtime/framework-tools/write-file.js +1 -1
  122. package/dist/src/runtime/loaders/compile-metadata.js +1 -1
  123. package/dist/src/runtime/loaders/manifest.js +1 -1
  124. package/dist/src/runtime/loaders/module-map.js +1 -1
  125. package/dist/src/runtime/resolve-tool.d.ts +4 -5
  126. package/dist/src/runtime/resolve-tool.js +1 -1
  127. package/dist/src/runtime/subagents/registry.d.ts +6 -3
  128. package/dist/src/runtime/subagents/registry.js +1 -1
  129. package/dist/src/runtime/tools/registry.js +1 -1
  130. package/dist/src/runtime/types.d.ts +7 -9
  131. package/dist/src/setup/boxes/deploy-project.d.ts +11 -1
  132. package/dist/src/setup/boxes/deploy-project.js +1 -1
  133. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  134. package/dist/src/setup/scaffold/create/extension.js +2 -2
  135. package/dist/src/setup/scaffold/create/project.js +2 -2
  136. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  137. package/dist/src/setup/scaffold/create/web-template.js +1 -0
  138. package/dist/src/setup/scaffold/update/channels.js +2 -2
  139. package/dist/src/setup/scaffold/update/connections.js +1 -1
  140. package/dist/src/setup/vercel-project-framework.d.ts +4 -2
  141. package/dist/src/shared/extension-package-contract.d.ts +11 -0
  142. package/dist/src/shared/extension-package-contract.js +1 -0
  143. package/dist/src/shared/json.d.ts +4 -0
  144. package/dist/src/shared/json.js +1 -1
  145. package/dist/src/shared/tool-schema.d.ts +52 -0
  146. package/dist/src/shared/tool-schema.js +1 -0
  147. package/dist/src/svelte/index.js +1 -1
  148. package/dist/src/svelte/use-eve-agent.js +1 -1
  149. package/dist/src/vue/index.js +1 -1
  150. package/dist/src/vue/use-eve-agent.js +1 -1
  151. package/docs/channels/custom.mdx +32 -2
  152. package/docs/concepts/sessions-runs-and-streaming.md +8 -0
  153. package/docs/extensions.md +22 -6
  154. package/docs/reference/cli.md +2 -2
  155. package/package.json +2 -2
  156. package/dist/src/internal/json-schema.d.ts +0 -1
  157. package/dist/src/internal/json-schema.js +0 -1
  158. package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +0 -26
  159. package/dist/src/setup/boxes/reconcile-host-framework-preset.js +0 -1
  160. package/dist/src/shared/json-schema.d.ts +0 -9
  161. package/dist/src/shared/json-schema.js +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # eve
2
2
 
3
+ ## 0.25.0
4
+
5
+ ### Minor Changes
6
+
7
+ - b9bb8b2: Scaffold extensions with separate source and dist roots, a required wildcard eve peer, and dist-only publication. `eve extension build` now emits an agent-shaped JavaScript distribution with declarations, assets, and capability compatibility metadata instead of requiring author TypeScript in the published package.
8
+
9
+ ### Patch Changes
10
+
11
+ - 29ecffc: Build mounted source-backed workspace extensions before `eve dev` compiles the agent, then rebuild only the affected extension when its source changes. Failed extension builds keep the previous dist and active development generation serving.
12
+ - 46b78b8: Stop development microsandboxes on `eve dev` shutdown by discovering resources from their run labels and loading the application's installed microsandbox version during cleanup.
13
+ - 6a5a36a: Deliver stale HITL responses — answers to a question or approval that is no longer pending — as a new user message, letting the model decide whether the old selection still matters. A stale approval never authorizes the earlier tool call.
14
+ - f7c69b1: The Vercel Framework Preset is now reconciled with the host framework on disk when running `/deploy` via the TUI.
15
+ - bbec675: Extensions installed with a registry-style store layout (e.g. from npm with pnpm) now work in `eve dev` and `eve eval`. Extension modules reached through a node_modules symlink resolve their dependencies from the package's real location — matching standard resolver semantics — instead of failing with `UNRESOLVED_IMPORT`/`ERR_MODULE_NOT_FOUND` or silently picking up another copy of the dependency from the consuming app.
16
+ - 14501dc: Every eve-owned tool input is now validated against its schema before execution, so invalid calls are returned to the model for retry instead of failing the run. Subagent calls treat an empty `outputSchema` as absent, and OpenAPI operations with invalid schemas are omitted with a warning.
17
+
18
+ ## 0.24.6
19
+
20
+ ### Patch Changes
21
+
22
+ - 3029647: Update the generated Web Chat template for Next.js 16.3 preview type declarations.
23
+ - b97f1d1: Custom channel routes can now cancel a session's in-flight turn: route handlers receive a `cancel({ continuationToken, turnId? })` helper addressed by the channel-local continuation token, and `Session` handles returned by `send()` and `getSession()` expose `cancel({ turnId? })` for session-id-addressed cancellation. `ClientSession.cancel()` accepts the same optional `turnId` stale-request guard.
24
+
3
25
  ## 0.24.5
4
26
 
5
27
  ### Patch Changes
@@ -0,0 +1,8 @@
1
+ import type { CancelFn } from "#channel/routes.js";
2
+ import type { Runtime } from "#channel/types.js";
3
+ /**
4
+ * Builds the route-handler `cancel` helper for one channel. Resolves the
5
+ * channel-local continuation token to its owning session without delivering
6
+ * input, then delegates to the runtime's session-id-addressed cancellation.
7
+ */
8
+ export declare function createCancelFn(runtime: Runtime, channelName: string): CancelFn;
@@ -0,0 +1 @@
1
+ function createCancelFn(e,t){return async n=>{let r=`${t}:${n.continuationToken}`,i=await e.resolveSession(r);return i===void 0?{status:`no_active_turn`}:await e.cancelTurn({sessionId:i.sessionId,turnId:n.turnId})}}export{createCancelFn};
@@ -1,6 +1,6 @@
1
1
  import type { UserContent } from "ai";
2
2
  import type { CrossChannelReceiveFn } from "#channel/cross-channel-receive.js";
3
- import type { SessionAuthContext, SessionCallback } from "#channel/types.js";
3
+ import type { CancelTurnResult, SessionAuthContext, SessionCallback } from "#channel/types.js";
4
4
  import type { InputResponse } from "#runtime/input/types.js";
5
5
  import type { Session } from "#channel/session.js";
6
6
  import type { RunMode } from "#shared/run-mode.js";
@@ -9,13 +9,15 @@ import type { ChannelMethod } from "#public/definitions/channel.js";
9
9
  type WebSocketHeaders = Headers | readonly (readonly [string, string])[] | Record<string, string>;
10
10
  /**
11
11
  * Second argument passed to every route handler. `send` starts or continues a
12
- * session on this channel; `getSession` looks one up by id; `receive` hands
13
- * inbound work to a different channel; `params` contains the matched path
14
- * parameters; `waitUntil` keeps background work alive past the response;
12
+ * session on this channel; `cancel` stops the active turn on a session
13
+ * addressed by continuation token; `getSession` looks one up by id; `receive`
14
+ * hands inbound work to a different channel; `params` contains the matched
15
+ * path parameters; `waitUntil` keeps background work alive past the response;
15
16
  * `requestIp` is the client IP, or `null` when the host cannot provide it.
16
17
  */
17
18
  export interface RouteHandlerArgs<TState = undefined> {
18
19
  send: SendFn<TState>;
20
+ cancel: CancelFn;
19
21
  getSession: GetSessionFn;
20
22
  /**
21
23
  * Starts a session on a different channel to hand off inbound work (e.g. an
@@ -78,6 +80,25 @@ export type SendOptions<TState = undefined> = [TState] extends [undefined] ? Bas
78
80
  * stream from within a route handler.
79
81
  */
80
82
  export type GetSessionFn = (sessionId: string) => Session;
83
+ /**
84
+ * Options for {@link CancelFn}. `continuationToken` is the channel-local raw
85
+ * token, exactly as passed to {@link SendFn}. `turnId` limits the request to
86
+ * the turn the caller observed; a stale guard is consumed as a benign no-op.
87
+ */
88
+ export interface CancelOptions {
89
+ readonly continuationToken: string;
90
+ readonly turnId?: string;
91
+ }
92
+ /**
93
+ * Requests cancellation of the active turn on the session that owns the
94
+ * continuation token. Never starts a session, sends input, or clears history.
95
+ *
96
+ * Both statuses are successful: `"accepted"` means the request was consumed,
97
+ * and `"no_active_turn"` covers an unknown token and a session with nothing
98
+ * to cancel. Confirmation is `turn.cancelled` followed by `session.waiting`
99
+ * on the event stream.
100
+ */
101
+ export type CancelFn = (options: CancelOptions) => Promise<CancelTurnResult>;
81
102
  export type RouteHandler<TState = undefined> = (req: Request, args: RouteHandlerArgs<TState>) => Promise<Response>;
82
103
  /**
83
104
  * A connected WebSocket peer passed to every {@link WebSocketRouteHooks}
@@ -1,6 +1,6 @@
1
1
  import type { ContextAccessor } from "#context/key.js";
2
2
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
- import type { Runtime } from "#channel/types.js";
3
+ import type { CancelTurnResult, Runtime } from "#channel/types.js";
4
4
  import type { SessionAuth } from "#context/keys.js";
5
5
  /**
6
6
  * Result of starting or delivering to a session. Exposes the session
@@ -14,6 +14,15 @@ import type { SessionAuth } from "#context/keys.js";
14
14
  export interface Session {
15
15
  readonly id: string;
16
16
  readonly continuationToken: string;
17
+ /**
18
+ * Requests cancellation of this session's in-flight turn. `turnId` limits
19
+ * the request to the turn the caller observed. Both statuses are
20
+ * successful; confirmation is `turn.cancelled` followed by
21
+ * `session.waiting` on the event stream.
22
+ */
23
+ cancel(options?: {
24
+ turnId?: string;
25
+ }): Promise<CancelTurnResult>;
17
26
  /**
18
27
  * Opens the durable event stream. Negative start indexes read relative to
19
28
  * the current tail (`-1` starts at the latest event).
@@ -1 +1 @@
1
- import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return{current:i.get(AuthKey)??null,initiator:i.get(InitiatorAuthKey)??null}},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
1
+ import{AuthKey,ContinuationTokenKey,InitiatorAuthKey,SessionIdKey}from"#context/keys.js";function createSession(e,t,n){return{id:e,continuationToken:t,async cancel(t){return n.cancelTurn({sessionId:e,turnId:t?.turnId})},async getEventStream(t){return n.getEventStream(e,t)}}}function createGetSessionFn(e){return t=>createSession(t,``,e)}function buildSessionHandle(i){return{get id(){return i.get(SessionIdKey)??``},get continuationToken(){return i.get(ContinuationTokenKey)??``},get auth(){return{current:i.get(AuthKey)??null,initiator:i.get(InitiatorAuthKey)??null}},setContinuationToken(e){let n=i.get(ContinuationTokenKey)??``,r=namespaceContinuationToken(n,e);n!==r&&i.set(ContinuationTokenKey,r)}}}function namespaceContinuationToken(e,t){let n=e.indexOf(`:`);if(n<=0)throw Error(`Cannot set session continuation token without an existing namespaced continuation token. Start the session with a placeholder continuationToken.`);return`${e.slice(0,n+1)}${t}`}export{buildSessionHandle,createGetSessionFn,createSession};
@@ -333,6 +333,14 @@ export interface Runtime {
333
333
  deliver(input: DeliverInput): Promise<{
334
334
  sessionId: string;
335
335
  }>;
336
+ /**
337
+ * Resolves the session that currently owns a continuation token without
338
+ * delivering input or starting a run. Returns `undefined` when no session
339
+ * owns the token.
340
+ */
341
+ resolveSession(continuationToken: string): Promise<{
342
+ sessionId: string;
343
+ } | undefined>;
336
344
  /**
337
345
  * Returns a readable stream of lifecycle events for an existing session.
338
346
  *
@@ -302,71 +302,8 @@ const CancelTurnResponseSchema = z.object({
302
302
  status: z.enum(["accepted", "no_active_turn"])
303
303
  });
304
304
 
305
- //#endregion
306
- //#region src/shared/json.ts
307
- const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
308
- const JSON_VALUE_ERROR_MESSAGE = "Expected a JSON-serializable value.";
309
- const JSON_OBJECT_ERROR_MESSAGE = "Expected a JSON-serializable object.";
310
- function parseJsonValue(value) {
311
- const normalized = normalizeJsonValueCandidate(value);
312
- if (normalized === INVALID_JSON_VALUE_CANDIDATE) throw new TypeError(JSON_VALUE_ERROR_MESSAGE);
313
- return normalized;
314
- }
315
- function parseJsonObject(value) {
316
- const normalized = parseJsonValue(value);
317
- if (!isJsonObjectValue(normalized)) throw new TypeError(JSON_OBJECT_ERROR_MESSAGE);
318
- return normalized;
319
- }
320
- function normalizeJsonValueCandidate(value, seen = /* @__PURE__ */ new WeakSet()) {
321
- if (value === null || typeof value === "boolean" || typeof value === "string") return value;
322
- if (typeof value === "number") return Number.isFinite(value) ? value : INVALID_JSON_VALUE_CANDIDATE;
323
- if (Array.isArray(value)) {
324
- const normalizedItems = [];
325
- for (const item of value) {
326
- const normalizedItem = normalizeJsonValueCandidate(item, seen);
327
- if (normalizedItem === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
328
- normalizedItems.push(normalizedItem);
329
- }
330
- return normalizedItems;
331
- }
332
- if (typeof value !== "object" || value === void 0) return INVALID_JSON_VALUE_CANDIDATE;
333
- if (!isPlainObject(value)) return INVALID_JSON_VALUE_CANDIDATE;
334
- if (seen.has(value)) return INVALID_JSON_VALUE_CANDIDATE;
335
- seen.add(value);
336
- const normalized = {};
337
- for (const [key, entry] of Object.entries(value)) {
338
- if (entry === void 0) continue;
339
- const normalizedEntry = normalizeJsonValueCandidate(entry, seen);
340
- if (normalizedEntry === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
341
- normalized[key] = normalizedEntry;
342
- }
343
- seen.delete(value);
344
- return normalized;
345
- }
346
- function isJsonObjectValue(value) {
347
- return value !== null && !Array.isArray(value) && typeof value === "object";
348
- }
349
- function isPlainObject(value) {
350
- const prototype = Object.getPrototypeOf(value);
351
- return prototype === null || prototype === Object.prototype;
352
- }
353
-
354
- //#endregion
355
- //#region src/shared/json-schema.ts
356
- const STANDARD_JSON_SCHEMA_TARGET = "draft-07";
357
- function normalizeJsonSchemaDefinition(value, direction = "input") {
358
- if (isStandardSchema(value)) return parseJsonObject(value["~standard"].jsonSchema[direction]({ target: STANDARD_JSON_SCHEMA_TARGET }));
359
- return parseJsonObject(value);
360
- }
361
- function isStandardSchema(value) {
362
- return value !== null && typeof value === "object" && "~standard" in value;
363
- }
364
-
365
305
  //#endregion
366
306
  //#region src/client/output-schema.ts
367
- function normalizeOutputSchemaForRequest(schema) {
368
- return schema === void 0 ? void 0 : normalizeJsonSchemaDefinition(schema, "output");
369
- }
370
307
  function extractCompletedResult(events) {
371
308
  let result;
372
309
  for (const event of events) if (isResultCompletedEvent(event)) result = event.data.result;
@@ -588,6 +525,74 @@ async function sleep$1(ms) {
588
525
  await new Promise((resolve) => setTimeout(resolve, ms));
589
526
  }
590
527
 
528
+ //#endregion
529
+ //#region src/shared/json.ts
530
+ const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
531
+ const JSON_VALUE_ERROR_MESSAGE = "Expected a JSON-serializable value.";
532
+ const JSON_OBJECT_ERROR_MESSAGE = "Expected a JSON-serializable object.";
533
+ function parseJsonValue(value) {
534
+ const normalized = normalizeJsonValueCandidate(value);
535
+ if (normalized === INVALID_JSON_VALUE_CANDIDATE) throw new TypeError(JSON_VALUE_ERROR_MESSAGE);
536
+ return normalized;
537
+ }
538
+ function parseJsonObject(value) {
539
+ const normalized = parseJsonValue(value);
540
+ if (!isJsonObjectValue(normalized)) throw new TypeError(JSON_OBJECT_ERROR_MESSAGE);
541
+ return normalized;
542
+ }
543
+ function normalizeJsonValueCandidate(value, seen = /* @__PURE__ */ new WeakSet()) {
544
+ if (value === null || typeof value === "boolean" || typeof value === "string") return value;
545
+ if (typeof value === "number") return Number.isFinite(value) ? value : INVALID_JSON_VALUE_CANDIDATE;
546
+ if (Array.isArray(value)) {
547
+ const normalizedItems = [];
548
+ for (const item of value) {
549
+ const normalizedItem = normalizeJsonValueCandidate(item, seen);
550
+ if (normalizedItem === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
551
+ normalizedItems.push(normalizedItem);
552
+ }
553
+ return normalizedItems;
554
+ }
555
+ if (typeof value !== "object" || value === void 0) return INVALID_JSON_VALUE_CANDIDATE;
556
+ if (!isPlainObject(value)) return INVALID_JSON_VALUE_CANDIDATE;
557
+ if (seen.has(value)) return INVALID_JSON_VALUE_CANDIDATE;
558
+ seen.add(value);
559
+ const normalized = {};
560
+ for (const [key, entry] of Object.entries(value)) {
561
+ if (entry === void 0) continue;
562
+ const normalizedEntry = normalizeJsonValueCandidate(entry, seen);
563
+ if (normalizedEntry === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
564
+ normalized[key] = normalizedEntry;
565
+ }
566
+ seen.delete(value);
567
+ return normalized;
568
+ }
569
+ function isJsonObjectValue(value) {
570
+ return value !== null && !Array.isArray(value) && typeof value === "object";
571
+ }
572
+ function isPlainObject(value) {
573
+ const prototype = Object.getPrototypeOf(value);
574
+ return prototype === null || prototype === Object.prototype;
575
+ }
576
+
577
+ //#endregion
578
+ //#region src/shared/tool-schema.ts
579
+ const JSON_SCHEMA_TARGET = "draft-07";
580
+ function serializeOutputSchema(source) {
581
+ return serializeSchema(source, "output");
582
+ }
583
+ const UNSPECIFIED_INPUT_SCHEMA = z.fromJSONSchema({});
584
+ function serializeSchema(source, direction) {
585
+ if (source === null || source === void 0) return source;
586
+ return toJsonObject(source, direction);
587
+ }
588
+ function toJsonObject(source, direction) {
589
+ const { $schema: _schemaVersion, ...canonical } = isStandardJsonSchema(source) ? parseJsonObject(source["~standard"].jsonSchema[direction]({ target: JSON_SCHEMA_TARGET })) : parseJsonObject(source);
590
+ return canonical;
591
+ }
592
+ function isStandardJsonSchema(value) {
593
+ return value !== null && typeof value === "object" && "~standard" in value;
594
+ }
595
+
591
596
  //#endregion
592
597
  //#region src/client/session.ts
593
598
  const DELIVER_RETRY_ATTEMPTS = 10;
@@ -616,14 +621,16 @@ var ClientSession = class {
616
621
  sessionId
617
622
  });
618
623
  }
619
- async cancel() {
624
+ async cancel(options) {
620
625
  const sessionId = this.#state.sessionId;
621
626
  if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
622
627
  const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
623
628
  const headers = await this.#context.resolveHeaders();
629
+ headers.set("content-type", "application/json");
624
630
  const response = await fetch(url, withRedirectPolicy$1({
625
631
  headers,
626
- method: "POST"
632
+ method: "POST",
633
+ body: options ? JSON.stringify(options) : void 0
627
634
  }, this.#context.redirect));
628
635
  const body = await response.text();
629
636
  if (!response.ok) throw new ClientError(response.status, body, response.headers);
@@ -652,7 +659,7 @@ var ClientSession = class {
652
659
  headers.set("content-type", "application/json");
653
660
  const body = createHandleMessageBody({
654
661
  input,
655
- outputSchema: normalizeOutputSchemaForRequest(input.outputSchema),
662
+ outputSchema: serializeOutputSchema(input.outputSchema),
656
663
  session
657
664
  });
658
665
  if (body === null) throw new Error("Session.send requires a non-empty message, inputResponses, or both.");
@@ -302,71 +302,8 @@ const CancelTurnResponseSchema = z.object({
302
302
  status: z.enum(["accepted", "no_active_turn"])
303
303
  });
304
304
 
305
- //#endregion
306
- //#region src/shared/json.ts
307
- const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
308
- const JSON_VALUE_ERROR_MESSAGE = "Expected a JSON-serializable value.";
309
- const JSON_OBJECT_ERROR_MESSAGE = "Expected a JSON-serializable object.";
310
- function parseJsonValue(value) {
311
- const normalized = normalizeJsonValueCandidate(value);
312
- if (normalized === INVALID_JSON_VALUE_CANDIDATE) throw new TypeError(JSON_VALUE_ERROR_MESSAGE);
313
- return normalized;
314
- }
315
- function parseJsonObject(value) {
316
- const normalized = parseJsonValue(value);
317
- if (!isJsonObjectValue(normalized)) throw new TypeError(JSON_OBJECT_ERROR_MESSAGE);
318
- return normalized;
319
- }
320
- function normalizeJsonValueCandidate(value, seen = /* @__PURE__ */ new WeakSet()) {
321
- if (value === null || typeof value === "boolean" || typeof value === "string") return value;
322
- if (typeof value === "number") return Number.isFinite(value) ? value : INVALID_JSON_VALUE_CANDIDATE;
323
- if (Array.isArray(value)) {
324
- const normalizedItems = [];
325
- for (const item of value) {
326
- const normalizedItem = normalizeJsonValueCandidate(item, seen);
327
- if (normalizedItem === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
328
- normalizedItems.push(normalizedItem);
329
- }
330
- return normalizedItems;
331
- }
332
- if (typeof value !== "object" || value === void 0) return INVALID_JSON_VALUE_CANDIDATE;
333
- if (!isPlainObject(value)) return INVALID_JSON_VALUE_CANDIDATE;
334
- if (seen.has(value)) return INVALID_JSON_VALUE_CANDIDATE;
335
- seen.add(value);
336
- const normalized = {};
337
- for (const [key, entry] of Object.entries(value)) {
338
- if (entry === void 0) continue;
339
- const normalizedEntry = normalizeJsonValueCandidate(entry, seen);
340
- if (normalizedEntry === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
341
- normalized[key] = normalizedEntry;
342
- }
343
- seen.delete(value);
344
- return normalized;
345
- }
346
- function isJsonObjectValue(value) {
347
- return value !== null && !Array.isArray(value) && typeof value === "object";
348
- }
349
- function isPlainObject(value) {
350
- const prototype = Object.getPrototypeOf(value);
351
- return prototype === null || prototype === Object.prototype;
352
- }
353
-
354
- //#endregion
355
- //#region src/shared/json-schema.ts
356
- const STANDARD_JSON_SCHEMA_TARGET = "draft-07";
357
- function normalizeJsonSchemaDefinition(value, direction = "input") {
358
- if (isStandardSchema(value)) return parseJsonObject(value["~standard"].jsonSchema[direction]({ target: STANDARD_JSON_SCHEMA_TARGET }));
359
- return parseJsonObject(value);
360
- }
361
- function isStandardSchema(value) {
362
- return value !== null && typeof value === "object" && "~standard" in value;
363
- }
364
-
365
305
  //#endregion
366
306
  //#region src/client/output-schema.ts
367
- function normalizeOutputSchemaForRequest(schema) {
368
- return schema === void 0 ? void 0 : normalizeJsonSchemaDefinition(schema, "output");
369
- }
370
307
  function extractCompletedResult(events) {
371
308
  let result;
372
309
  for (const event of events) if (isResultCompletedEvent(event)) result = event.data.result;
@@ -588,6 +525,74 @@ async function sleep$1(ms) {
588
525
  await new Promise((resolve) => setTimeout(resolve, ms));
589
526
  }
590
527
 
528
+ //#endregion
529
+ //#region src/shared/json.ts
530
+ const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
531
+ const JSON_VALUE_ERROR_MESSAGE = "Expected a JSON-serializable value.";
532
+ const JSON_OBJECT_ERROR_MESSAGE = "Expected a JSON-serializable object.";
533
+ function parseJsonValue(value) {
534
+ const normalized = normalizeJsonValueCandidate(value);
535
+ if (normalized === INVALID_JSON_VALUE_CANDIDATE) throw new TypeError(JSON_VALUE_ERROR_MESSAGE);
536
+ return normalized;
537
+ }
538
+ function parseJsonObject(value) {
539
+ const normalized = parseJsonValue(value);
540
+ if (!isJsonObjectValue(normalized)) throw new TypeError(JSON_OBJECT_ERROR_MESSAGE);
541
+ return normalized;
542
+ }
543
+ function normalizeJsonValueCandidate(value, seen = /* @__PURE__ */ new WeakSet()) {
544
+ if (value === null || typeof value === "boolean" || typeof value === "string") return value;
545
+ if (typeof value === "number") return Number.isFinite(value) ? value : INVALID_JSON_VALUE_CANDIDATE;
546
+ if (Array.isArray(value)) {
547
+ const normalizedItems = [];
548
+ for (const item of value) {
549
+ const normalizedItem = normalizeJsonValueCandidate(item, seen);
550
+ if (normalizedItem === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
551
+ normalizedItems.push(normalizedItem);
552
+ }
553
+ return normalizedItems;
554
+ }
555
+ if (typeof value !== "object" || value === void 0) return INVALID_JSON_VALUE_CANDIDATE;
556
+ if (!isPlainObject(value)) return INVALID_JSON_VALUE_CANDIDATE;
557
+ if (seen.has(value)) return INVALID_JSON_VALUE_CANDIDATE;
558
+ seen.add(value);
559
+ const normalized = {};
560
+ for (const [key, entry] of Object.entries(value)) {
561
+ if (entry === void 0) continue;
562
+ const normalizedEntry = normalizeJsonValueCandidate(entry, seen);
563
+ if (normalizedEntry === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
564
+ normalized[key] = normalizedEntry;
565
+ }
566
+ seen.delete(value);
567
+ return normalized;
568
+ }
569
+ function isJsonObjectValue(value) {
570
+ return value !== null && !Array.isArray(value) && typeof value === "object";
571
+ }
572
+ function isPlainObject(value) {
573
+ const prototype = Object.getPrototypeOf(value);
574
+ return prototype === null || prototype === Object.prototype;
575
+ }
576
+
577
+ //#endregion
578
+ //#region src/shared/tool-schema.ts
579
+ const JSON_SCHEMA_TARGET = "draft-07";
580
+ function serializeOutputSchema(source) {
581
+ return serializeSchema(source, "output");
582
+ }
583
+ const UNSPECIFIED_INPUT_SCHEMA = z.fromJSONSchema({});
584
+ function serializeSchema(source, direction) {
585
+ if (source === null || source === void 0) return source;
586
+ return toJsonObject(source, direction);
587
+ }
588
+ function toJsonObject(source, direction) {
589
+ const { $schema: _schemaVersion, ...canonical } = isStandardJsonSchema(source) ? parseJsonObject(source["~standard"].jsonSchema[direction]({ target: JSON_SCHEMA_TARGET })) : parseJsonObject(source);
590
+ return canonical;
591
+ }
592
+ function isStandardJsonSchema(value) {
593
+ return value !== null && typeof value === "object" && "~standard" in value;
594
+ }
595
+
591
596
  //#endregion
592
597
  //#region src/client/session.ts
593
598
  const DELIVER_RETRY_ATTEMPTS = 10;
@@ -616,14 +621,16 @@ var ClientSession = class {
616
621
  sessionId
617
622
  });
618
623
  }
619
- async cancel() {
624
+ async cancel(options) {
620
625
  const sessionId = this.#state.sessionId;
621
626
  if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
622
627
  const url = createClientUrl(this.#context.host, createEveCancelTurnRoutePath(sessionId));
623
628
  const headers = await this.#context.resolveHeaders();
629
+ headers.set("content-type", "application/json");
624
630
  const response = await fetch(url, withRedirectPolicy$1({
625
631
  headers,
626
- method: "POST"
632
+ method: "POST",
633
+ body: options ? JSON.stringify(options) : void 0
627
634
  }, this.#context.redirect));
628
635
  const body = await response.text();
629
636
  if (!response.ok) throw new ClientError(response.status, body, response.headers);
@@ -652,7 +659,7 @@ var ClientSession = class {
652
659
  headers.set("content-type", "application/json");
653
660
  const body = createHandleMessageBody({
654
661
  input,
655
- outputSchema: normalizeOutputSchemaForRequest(input.outputSchema),
662
+ outputSchema: serializeOutputSchema(input.outputSchema),
656
663
  session
657
664
  });
658
665
  if (body === null) throw new Error("Session.send requires a non-empty message, inputResponses, or both.");
@@ -1,5 +1,5 @@
1
1
  import{readFileSync}from"node:fs";const SETUP_SECTIONS=[`intro-setup.md`,`collect-intent.md`,`vercel-connect.md`,`scaffold.md`,`build-and-verify.md`],HANDOFF_SECTIONS=[`intro-handoff.md`,`collect-intent.md`,`vercel-connect.md`,`build-and-verify.md`];function compose(t,n){let r=t.map(t=>readFileSync(new URL(`./agent-prompt/${t}`,import.meta.url),`utf8`).trim()).join(`
2
2
 
3
3
  `).replaceAll(`{{devCommand}}`,()=>n.devCommand),{workingDirectory:i}=n;return i===void 0?r:r.replaceAll(`{{workingDirectory}}`,()=>i)}function initAgentInstructions(){return compose(SETUP_SECTIONS,{devCommand:`npx eve dev`})}function initAgentDevHandoff(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:e.projectPath})}function initAgentReplPrompt(e){return compose(HANDOFF_SECTIONS,{devCommand:e.devCommand,workingDirectory:`.`})}function initExtensionInstructions(){return[`You are scaffolding an eve extension package (a reusable package of tools,`,`connections, skills, and hooks that a consuming agent mounts under`,`agent/extensions/).`,``,`Ask the user for a package directory name, then run:`,``,` npx eve@latest extension init <name>`,``,`That creates the package, installs dependencies, and initializes Git. It`,`prints what was set up and how to author, build, and mount the extension —`,`it does not start eve dev (extensions are not standalone agents).`,``,"Build with `eve extension build` (or the package `build` script)."].join(`
4
- `)}function initExtensionHandoff(e){return[``,`What we set up:`,` - package.json with eve.extension ./extension, peer+dev eve, and zod`,` - extension/extension.ts (config schema via defineExtension)`,` - build/prepare scripts → eve extension build`,``,`Next:`,` - Add tools, skills, hooks, or connections under extension/`,` (see AGENTS.md and node_modules/eve/docs/extensions.md)`,` - ${`${e.packageManager} run build`} # fills dist/ and package exports`,` - Mount from a consumer agent:`,` // agent/extensions/${e.packageName}.ts`,` import ext from "${e.packageName}";`,` export default ext({ apiKey: process.env.API_KEY });`,``,`Working directory: ${e.projectPath}`].join(`
4
+ `)}function initExtensionHandoff(e){return[``,`What we set up:`,` - package.json with eve.extension source/dist roots, peer+dev eve, and zod`,` - extension/extension.ts (config schema via defineExtension)`,` - build/prepare scripts → eve extension build`,``,`Next:`,` - Add tools, skills, hooks, or connections under extension/`,` (see AGENTS.md and node_modules/eve/docs/extensions.md)`,` - ${`${e.packageManager} run build`} # builds dist/extension and package exports`,` - Mount from a consumer agent:`,` // agent/extensions/${e.packageName}.ts`,` import ext from "${e.packageName}";`,` export default ext({ apiKey: process.env.API_KEY });`,``,`Working directory: ${e.projectPath}`].join(`
5
5
  `)}export{HANDOFF_SECTIONS,SETUP_SECTIONS,initAgentDevHandoff,initAgentInstructions,initAgentReplPrompt,initExtensionHandoff,initExtensionInstructions};
@@ -1 +1 @@
1
- import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{reconcileHostFrameworkPreset}from"#setup/boxes/reconcile-host-framework-preset.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),reconcileHostFrameworkPreset({prompter:c}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
1
+ import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"./channel-add-conflicts.js";import{NOT_AN_AGENT_MESSAGE}from"./preconditions.js";import{isEveProject,listAuthoredChannels}from"#setup/scaffold/index.js";import{interactiveAsker}from"#setup/ask.js";import{addChannels}from"#setup/boxes/add-channels.js";import{deployProject}from"#setup/boxes/deploy-project.js";import{selectChannels}from"#setup/boxes/select-channels.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{createPrompter}from"#setup/prompter.js";import{runInteractive}from"#setup/runner.js";import{createDefaultSetupState,snapshotSetupState}from"#setup/state.js";const KNOWN_CHANNEL_KINDS=[`slack`,`web`];function isChannelKind(e){return KNOWN_CHANNEL_KINDS.includes(e)}function parseChannelKind(e){if(!isChannelKind(e))throw Error(`Unknown channel kind "${e}". Known: ${KNOWN_CHANNEL_KINDS.join(`, `)}.`);return e}const defaultChannelsAddDependencies={detectDeployment};async function runAddChannelsFlow(n,r,i,s){if(r===void 0&&(i.yes||!process.stdin.isTTY||!process.stdout.isTTY))throw Error(`Pass a channel kind: \`eve channels add <${KNOWN_CHANNEL_KINDS.join(`|`)}>\`.`);let c=s.createPrompter?.()??createPrompter();c.intro(`Add channels to your eve agent`),c.log.message(`Checking the current Vercel project...`);let l={...createDefaultSetupState(),project:projectResolutionFromDeployment(await s.detectDeployment(n)),projectPath:{kind:`resolved`,inPlace:!0,path:n}},u;function inspectRegistrations(){return u===void 0&&(c.log.message(`Inspecting existing channel registrations...`),u=inspectExistingChannelRegistrations(n)),u}let d=r===void 0?(await inspectRegistrations()).disabledChannelReasons:void 0,f=await runInteractive([selectChannels({asker:interactiveAsker(c),variant:`channels-add`,presetChannels:r===void 0?void 0:[r],disabledChannelReasons:d,validateSelection:async t=>{!t.includes(`web`)&&!t.includes(`slack`)||assertCanAddSelectedChannels(t,await inspectRegistrations())}}),addChannels({asker:interactiveAsker(c),prompter:c,presetCreateSlackbot:i.yes?!0:void 0,force:i.force,configureVercelServices:!0,ensureLinkedProject:`interactive-vercel-link`,deps:s.addChannelsDeps}),deployProject({prompter:c,ensureLinkedProject:`interactive-vercel-link`,deps:s.deployProjectDeps})],l,{write:e=>c.log.message(e)},{snapshot:snapshotSetupState});f.kind!==`cancelled`&&c.outro(f.state.channels.length===0?`No channels added.`:`Channels added.`)}async function runChannelsAddCommand(e,t,i,a=defaultChannelsAddDependencies){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}try{await runAddChannelsFlow(t,i.kind===void 0?void 0:parseChannelKind(i.kind),i.options,a)}catch(t){e.error(t instanceof Error?t.message:String(t)),process.exitCode=1}}async function runChannelsListCommand(e,t,a){if(!await isEveProject(t)){e.error(NOT_AN_AGENT_MESSAGE),process.exitCode=1;return}let o=await listAuthoredChannels(t);if(a.json){e.log(JSON.stringify({channels:o},null,2));return}if(o.length===0){e.log("No channels defined. Run `eve channels add` to add one.");return}for(let t of o)e.log(t)}export{runChannelsAddCommand,runChannelsListCommand};
@@ -4,6 +4,6 @@ export interface ExtensionBuildCliLogger {
4
4
  }
5
5
  /**
6
6
  * Builds the current package as an eve extension. Requires
7
- * `package.json#eve.extension` pointing at the source root (e.g. `./extension`).
7
+ * `package.json#eve.extension` declaring distinct source and dist roots.
8
8
  */
9
9
  export declare function runExtensionBuildCommand(logger: ExtensionBuildCliLogger, appRoot: string): Promise<void>;
@@ -1 +1 @@
1
- import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{createLogger}from"#internal/logging.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{buildExtensionPackage,tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";var import_picocolors=__toESM(require_picocolors(),1);const buildLog=createLogger(`extension-build`);async function runExtensionBuildCommand(e,t){let n=await tryReadExtensionBuildConfig(t);if(n===null)throw Error('This package is not an eve extension. Add `"eve": { "extension": "./extension" }` to package.json, or run `eve build` for an agent app.');buildLog.debug(`building extension package`,{packageName:n.packageName,sourceRoot:n.sourceRoot});let r=await buildExtensionPackage(t,n),i=createCliTheme();e.log(renderCliTaggedLine(i,{message:`built extension ${import_picocolors.default.bold(n.packageName)} at ${r}`,tag:`build`,tone:`success`}))}export{runExtensionBuildCommand};
1
+ import{__toESM}from"../../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{createLogger}from"#internal/logging.js";import{createCliTheme,renderCliTaggedLine}from"#cli/ui/output.js";import{buildExtensionPackage,tryReadExtensionBuildConfig}from"#internal/nitro/host/build-extension.js";var import_picocolors=__toESM(require_picocolors(),1);const buildLog=createLogger(`extension-build`);async function runExtensionBuildCommand(e,t){let n=await tryReadExtensionBuildConfig(t);if(n===null)throw Error('This package is not an eve extension. Add `"eve": { "extension": { "source": "./extension", "dist": "./dist/extension" } }` to package.json, or run `eve build` for an agent app.');buildLog.debug(`building extension package`,{packageName:n.packageName,sourceRoot:n.sourceRoot});let r=await buildExtensionPackage(t,n),i=createCliTheme();e.log(renderCliTaggedLine(i,{message:`built extension ${import_picocolors.default.bold(n.packageName)} at ${r}`,tag:`build`,tone:`success`}))}export{runExtensionBuildCommand};
@@ -1,11 +1,4 @@
1
- import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
1
  import type { HandleMessageStreamEvent } from "#protocol/message.js";
3
- import type { JsonObject } from "#shared/json.js";
4
- /**
5
- * Normalizes a client-supplied output schema into the wire-safe JSON Schema
6
- * representation accepted by eve message routes.
7
- */
8
- export declare function normalizeOutputSchemaForRequest<TOutput>(schema: StandardJSONSchemaV1<unknown, TOutput> | JsonObject | undefined): JsonObject | undefined;
9
2
  /**
10
3
  * Extracts the most recent finalized structured result from a turn event list.
11
4
  */
@@ -1 +1 @@
1
- import{normalizeJsonSchemaDefinition}from"#shared/json-schema.js";function normalizeOutputSchemaForRequest(t){return t===void 0?void 0:normalizeJsonSchemaDefinition(t,`output`)}function extractCompletedResult(e){let t;for(let n of e)isResultCompletedEvent(n)&&(t=n.data.result);return t}function isResultCompletedEvent(e){return e.type===`result.completed`}export{extractCompletedResult,normalizeOutputSchemaForRequest};
1
+ function extractCompletedResult(e){let t;for(let n of e)isResultCompletedEvent(n)&&(t=n.data.result);return t}function isResultCompletedEvent(e){return e.type===`result.completed`}export{extractCompletedResult};
@@ -42,12 +42,16 @@ export declare class ClientSession {
42
42
  *
43
43
  * Both `accepted` and `no_active_turn` are successful outcomes. The latter
44
44
  * means the active turn settled before the request arrived or the session is
45
- * already parked. Credentials are resolved immediately before the request.
45
+ * already parked. `turnId` limits the request to the turn the caller
46
+ * observed; a stale guard is consumed as a benign no-op. Credentials are
47
+ * resolved immediately before the request.
46
48
  *
47
49
  * @throws {Error} If this handle has not started or attached to a session.
48
50
  * @throws {ClientError} If the cancel route returns a non-successful status.
49
51
  */
50
- cancel(): Promise<CancelSessionResult>;
52
+ cancel(options?: {
53
+ turnId?: string;
54
+ }): Promise<CancelSessionResult>;
51
55
  /**
52
56
  * Opens this session's event stream for the current session ID.
53
57
  *
@@ -1 +1 @@
1
- import{EVE_CREATE_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{normalizeOutputSchemaForRequest}from"#client/output-schema.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{openStreamBody,openStreamIterable}from"#client/open-stream.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);return this.#t===n&&(this.#t={...n,sessionId:i}),new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(){let e=this.#t.sessionId;if(!e)throw Error(`Session has no session ID. Send a message first.`);let n=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(e)),i=await this.#e.resolveHeaders(),o=await fetch(n,withRedirectPolicy({headers:i,method:`POST`},this.#e.redirect)),s=await o.text();if(!o.ok)throw new ClientError(o.status,s,o.headers);let c;try{c=JSON.parse(s)}catch{throw Error(`Cancel route returned invalid JSON (${o.status}).`)}let l=CancelTurnResponseSchema.safeParse(c);if(!l.success||l.data.sessionId!==e)throw Error(`Cancel route returned an invalid response (${o.status}).`);return{sessionId:l.data.sessionId,status:l.data.status}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#a(t,e)}async#n(t,r){let i=r.sessionId?createEveContinueSessionRoutePath(r.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,i),c=await this.#e.resolveHeaders(t.headers);c.set(`content-type`,`application/json`);let u=createHandleMessageBody({input:t,outputSchema:normalizeOutputSchemaForRequest(t.outputSchema),session:r});if(u===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let d=await postTurnWithRetry({body:JSON.stringify(u),headers:c,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),f=await d.json(),p=(typeof f.sessionId==`string`?f.sessionId:void 0)??d.headers.get(EVE_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!p)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof f.continuationToken==`string`?f.continuationToken:void 0,sessionId:p}}async*#r(e,t,n,r){let a=[];try{let t=n.sessionId===e?n.streamIndex:0,i=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,r.signal,r.headers),o=!1;try{for await(let e of readNdjsonStream(n))if(a.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){o=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(o||r.signal?.aborted||i<=0)break;--i}}finally{this.#t=advanceSession({continuationToken:t,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async#i(e,t,n,r){return await openStreamBody({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r),redirect:this.#e.redirect,sessionId:e,signal:n,startIndex:t})}async*#a(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,a=[];try{for await(let n of openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,sessionId:e,signal:t?.signal,startIndex:r}))a.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,i,a;for(let o=0;o<t;o+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,i=await s.text(),a=s.headers,!isRetryableDeliveryFailure(s.status,i))throw new ClientError(s.status,i,s.headers);o<t-1&&await sleep(200)}throw new ClientError(n??0,i??`Failed to deliver session turn.`,a)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};
1
+ import{EVE_CREATE_SESSION_ROUTE_PATH,createEveCancelTurnRoutePath,createEveContinueSessionRoutePath}from"#protocol/routes.js";import{ClientError}from"#client/client-error.js";import{advanceSession}from"#client/session-utils.js";import{createClientUrl}from"#client/url.js";import{MessageResponse}from"#client/message-response.js";import{EVE_SESSION_ID_HEADER,isCurrentTurnBoundaryEvent}from"#protocol/message.js";import{isStreamDisconnectError,readNdjsonStream}from"#client/ndjson.js";import{CancelTurnResponseSchema}from"#protocol/cancel-turn.js";import{openStreamBody,openStreamIterable}from"#client/open-stream.js";import{serializeOutputSchema}from"#shared/tool-schema.js";var ClientSession=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}get state(){return this.#t}async send(e){let t=normalizeSendTurnInput(e),n=this.#t,{continuationToken:r,sessionId:i}=await this.#n(t,n);return this.#t===n&&(this.#t={...n,sessionId:i}),new MessageResponse({continuationToken:r,createStream:()=>this.#r(i,r,n,t),sessionId:i})}async cancel(e){let n=this.#t.sessionId;if(!n)throw Error(`Session has no session ID. Send a message first.`);let i=createClientUrl(this.#e.host,createEveCancelTurnRoutePath(n)),o=await this.#e.resolveHeaders();o.set(`content-type`,`application/json`);let s=await fetch(i,withRedirectPolicy({headers:o,method:`POST`,body:e?JSON.stringify(e):void 0},this.#e.redirect)),c=await s.text();if(!s.ok)throw new ClientError(s.status,c,s.headers);let l;try{l=JSON.parse(c)}catch{throw Error(`Cancel route returned invalid JSON (${s.status}).`)}let u=CancelTurnResponseSchema.safeParse(l);if(!u.success||u.data.sessionId!==n)throw Error(`Cancel route returned an invalid response (${s.status}).`);return{sessionId:u.data.sessionId,status:u.data.status}}stream(e){let t=this.#t.sessionId;if(!t)throw Error(`Session has no session ID. Send a message first.`);return this.#a(t,e)}async#n(t,r){let i=r.sessionId?createEveContinueSessionRoutePath(r.sessionId):EVE_CREATE_SESSION_ROUTE_PATH,o=createClientUrl(this.#e.host,i),c=await this.#e.resolveHeaders(t.headers);c.set(`content-type`,`application/json`);let l=createHandleMessageBody({input:t,outputSchema:serializeOutputSchema(t.outputSchema),session:r});if(l===null)throw Error(`Session.send requires a non-empty message, inputResponses, or both.`);let u=await postTurnWithRetry({body:JSON.stringify(l),headers:c,mustDeliver:(t.inputResponses?.length??0)>0,redirect:this.#e.redirect,signal:t.signal,url:o}),d=await u.json(),f=(typeof d.sessionId==`string`?d.sessionId:void 0)??u.headers.get(EVE_SESSION_ID_HEADER)?.trim()??r.sessionId;if(!f)throw Error(`Message route did not return a session id.`);return{continuationToken:typeof d.continuationToken==`string`?d.continuationToken:void 0,sessionId:f}}async*#r(e,t,n,r){let a=[];try{let t=n.sessionId===e?n.streamIndex:0,i=this.#e.maxReconnectAttempts;for(;;){let n=await this.#i(e,t,r.signal,r.headers),o=!1;try{for await(let e of readNdjsonStream(n))if(a.push(e),t+=1,yield e,isCurrentTurnBoundaryEvent(e)){o=!0;break}}catch(e){if(!isStreamDisconnectError(e))throw e}if(o||r.signal?.aborted||i<=0)break;--i}}finally{this.#t=advanceSession({continuationToken:t,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,sessionId:e,session:n})}}async#i(e,t,n,r){return await openStreamBody({host:this.#e.host,resolveHeaders:()=>this.#e.resolveHeaders(r),redirect:this.#e.redirect,sessionId:e,signal:n,startIndex:t})}async*#a(e,t){let n=this.#t,r=t?.startIndex??n.streamIndex,a=[];try{for await(let n of openStreamIterable({host:this.#e.host,maxReconnectAttempts:this.#e.maxReconnectAttempts,resolveHeaders:()=>this.#e.resolveHeaders(),redirect:this.#e.redirect,sessionId:e,signal:t?.signal,startIndex:r}))a.push(n),yield n}finally{r>=0&&(this.#t=advanceSession({continuationToken:n.continuationToken,events:a,preserveCompletedSessions:this.#e.preserveCompletedSessions,session:{...n,sessionId:e,streamIndex:r},sessionId:e}))}}};async function postTurnWithRetry(e){let t=e.mustDeliver?10:1,n,i,a;for(let o=0;o<t;o+=1){let s=await fetch(e.url,{body:e.body,headers:e.headers,method:`POST`,redirect:e.redirect,signal:e.signal??null});if(s.ok)return s;if(n=s.status,i=await s.text(),a=s.headers,!isRetryableDeliveryFailure(s.status,i))throw new ClientError(s.status,i,s.headers);o<t-1&&await sleep(200)}throw new ClientError(n??0,i??`Failed to deliver session turn.`,a)}function isRetryableDeliveryFailure(e,t){return e===500&&/target session was not found/i.test(t)}async function sleep(e){await new Promise(t=>setTimeout(t,e))}function normalizeSendTurnInput(e){return typeof e==`string`?{message:e}:e}function createHandleMessageBody(e){let t={};return e.input.message!==void 0&&(t.message=e.input.message),e.input.inputResponses!==void 0&&e.input.inputResponses.length>0&&(t.inputResponses=e.input.inputResponses),e.input.clientContext!==void 0&&(t.clientContext=e.input.clientContext),e.outputSchema!==void 0&&(t.outputSchema=e.outputSchema),e.session.continuationToken!==void 0&&(t.continuationToken=e.session.continuationToken),Object.keys(t).length===0||e.session.continuationToken===void 0&&t.message===void 0||e.session.continuationToken!==void 0&&t.message===void 0&&t.inputResponses===void 0?null:t}function withRedirectPolicy(e,t){return t===void 0?e:{...e,redirect:t}}export{ClientSession};