eve 0.24.6 → 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 (147) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/src/chunks/{use-eve-agent-6BO9gFVq.js → use-eve-agent-CQIeqmKc.js} +69 -64
  3. package/dist/src/chunks/{use-eve-agent-B1MJNRE-.js → use-eve-agent-Cy73lgA6.js} +69 -64
  4. package/dist/src/cli/commands/agent-instructions.js +1 -1
  5. package/dist/src/cli/commands/channels.js +1 -1
  6. package/dist/src/cli/commands/extension-build.d.ts +1 -1
  7. package/dist/src/cli/commands/extension-build.js +1 -1
  8. package/dist/src/client/output-schema.d.ts +0 -7
  9. package/dist/src/client/output-schema.js +1 -1
  10. package/dist/src/client/session.js +1 -1
  11. package/dist/src/compiler/extension-compatibility.d.ts +56 -0
  12. package/dist/src/compiler/extension-compatibility.js +1 -0
  13. package/dist/src/compiler/normalize-agent-config.js +1 -1
  14. package/dist/src/compiler/normalize-subagent.js +1 -1
  15. package/dist/src/context/build-dynamic-tools.js +1 -1
  16. package/dist/src/context/dynamic-tool-lifecycle.d.ts +1 -1
  17. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  18. package/dist/src/discover/discover-agent.d.ts +29 -7
  19. package/dist/src/discover/discover-agent.js +1 -1
  20. package/dist/src/discover/extensions.d.ts +43 -8
  21. package/dist/src/discover/extensions.js +1 -1
  22. package/dist/src/discover/filesystem.d.ts +3 -1
  23. package/dist/src/discover/filesystem.js +1 -1
  24. package/dist/src/discover/named-source-directory.js +1 -1
  25. package/dist/src/discover/skills.js +1 -1
  26. package/dist/src/evals/autoevals-client.js +2 -2
  27. package/dist/src/execution/node-step.js +1 -1
  28. package/dist/src/execution/sandbox/bindings/docker.js +1 -1
  29. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.d.ts +1 -1
  30. package/dist/src/execution/sandbox/bindings/microsandbox-runtime.js +1 -1
  31. package/dist/src/execution/sandbox/bindings/microsandbox-templates.js +1 -1
  32. package/dist/src/execution/sandbox/development-cleanup.d.ts +1 -1
  33. package/dist/src/execution/sandbox/development-cleanup.js +1 -1
  34. package/dist/src/execution/sandbox/development-run.d.ts +0 -3
  35. package/dist/src/execution/sandbox/development-run.js +1 -1
  36. package/dist/src/execution/sandbox/ensure.js +1 -1
  37. package/dist/src/execution/subagent-tool.js +1 -1
  38. package/dist/src/harness/emission.js +1 -1
  39. package/dist/src/harness/input-extraction.d.ts +10 -1
  40. package/dist/src/harness/input-extraction.js +1 -1
  41. package/dist/src/harness/input-requests.d.ts +12 -2
  42. package/dist/src/harness/input-requests.js +1 -1
  43. package/dist/src/harness/messages.d.ts +8 -1
  44. package/dist/src/harness/messages.js +1 -1
  45. package/dist/src/harness/stale-input-responses.d.ts +26 -0
  46. package/dist/src/harness/stale-input-responses.js +3 -0
  47. package/dist/src/harness/step-hooks.d.ts +1 -12
  48. package/dist/src/harness/step-hooks.js +1 -1
  49. package/dist/src/harness/tool-call-input-errors.d.ts +11 -0
  50. package/dist/src/harness/tool-call-input-errors.js +1 -1
  51. package/dist/src/harness/tool-loop.js +2 -2
  52. package/dist/src/harness/workflow-sandbox.d.ts +1 -1
  53. package/dist/src/harness/workflow-sandbox.js +1 -1
  54. package/dist/src/internal/application/optional-package-install.d.ts +5 -0
  55. package/dist/src/internal/application/optional-package-install.js +1 -1
  56. package/dist/src/internal/application/package.js +1 -1
  57. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  58. package/dist/src/internal/authored-module-loader.d.ts +17 -0
  59. package/dist/src/internal/authored-module-loader.js +2 -2
  60. package/dist/src/internal/authored-module-map-loader.js +1 -1
  61. package/dist/src/internal/authored-package-boundary.d.ts +8 -0
  62. package/dist/src/internal/authored-package-boundary.js +1 -1
  63. package/dist/src/internal/nitro/dev-runtime-source-snapshot.d.ts +4 -0
  64. package/dist/src/internal/nitro/dev-runtime-source-snapshot.js +1 -1
  65. package/dist/src/internal/nitro/host/build-extension.d.ts +6 -21
  66. package/dist/src/internal/nitro/host/build-extension.js +2 -4
  67. package/dist/src/internal/nitro/host/dev-authored-rebuild-coordinator.js +1 -1
  68. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  69. package/dist/src/internal/nitro/host/dev-workspace-extensions.d.ts +18 -0
  70. package/dist/src/internal/nitro/host/dev-workspace-extensions.js +1 -0
  71. package/dist/src/internal/nitro/host/extension-build-config.d.ts +18 -0
  72. package/dist/src/internal/nitro/host/extension-build-config.js +1 -0
  73. package/dist/src/internal/nitro/host/extension-capability-requirements.d.ts +10 -0
  74. package/dist/src/internal/nitro/host/extension-capability-requirements.js +1 -0
  75. package/dist/src/internal/nitro/host/extension-declarations.d.ts +10 -0
  76. package/dist/src/internal/nitro/host/extension-declarations.js +2 -0
  77. package/dist/src/internal/nitro/host/extension-distribution.d.ts +32 -0
  78. package/dist/src/internal/nitro/host/extension-distribution.js +3 -0
  79. package/dist/src/internal/nitro/host/extension-state-usage.d.ts +7 -0
  80. package/dist/src/internal/nitro/host/extension-state-usage.js +1 -0
  81. package/dist/src/internal/nitro/host/prepare-application-host.d.ts +5 -1
  82. package/dist/src/internal/nitro/host/prepare-application-host.js +1 -1
  83. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  84. package/dist/src/internal/nitro/host/types.d.ts +2 -0
  85. package/dist/src/internal/nitro/routes/agent-info/build-agent-info-response.js +1 -1
  86. package/dist/src/public/definitions/tool.d.ts +2 -2
  87. package/dist/src/public/tools/internal.js +1 -1
  88. package/dist/src/runtime/agent/mock-model-fixtures.js +2 -2
  89. package/dist/src/runtime/connections/openapi-client.js +1 -1
  90. package/dist/src/runtime/framework-tools/ask-question.d.ts +23 -9
  91. package/dist/src/runtime/framework-tools/ask-question.js +1 -1
  92. package/dist/src/runtime/framework-tools/bash.d.ts +10 -3
  93. package/dist/src/runtime/framework-tools/bash.js +1 -1
  94. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  95. package/dist/src/runtime/framework-tools/final-output.d.ts +1 -1
  96. package/dist/src/runtime/framework-tools/final-output.js +1 -1
  97. package/dist/src/runtime/framework-tools/glob.d.ts +12 -3
  98. package/dist/src/runtime/framework-tools/glob.js +1 -1
  99. package/dist/src/runtime/framework-tools/grep.d.ts +16 -3
  100. package/dist/src/runtime/framework-tools/grep.js +1 -1
  101. package/dist/src/runtime/framework-tools/read-file.d.ts +13 -3
  102. package/dist/src/runtime/framework-tools/read-file.js +1 -1
  103. package/dist/src/runtime/framework-tools/skill.d.ts +5 -2
  104. package/dist/src/runtime/framework-tools/skill.js +1 -1
  105. package/dist/src/runtime/framework-tools/todo.d.ts +57 -10
  106. package/dist/src/runtime/framework-tools/todo.js +3 -3
  107. package/dist/src/runtime/framework-tools/web-fetch.d.ts +16 -3
  108. package/dist/src/runtime/framework-tools/web-fetch.js +1 -1
  109. package/dist/src/runtime/framework-tools/write-file.d.ts +9 -3
  110. package/dist/src/runtime/framework-tools/write-file.js +1 -1
  111. package/dist/src/runtime/loaders/compile-metadata.js +1 -1
  112. package/dist/src/runtime/loaders/manifest.js +1 -1
  113. package/dist/src/runtime/loaders/module-map.js +1 -1
  114. package/dist/src/runtime/resolve-tool.d.ts +4 -5
  115. package/dist/src/runtime/resolve-tool.js +1 -1
  116. package/dist/src/runtime/subagents/registry.d.ts +6 -3
  117. package/dist/src/runtime/subagents/registry.js +1 -1
  118. package/dist/src/runtime/tools/registry.js +1 -1
  119. package/dist/src/runtime/types.d.ts +7 -9
  120. package/dist/src/setup/boxes/deploy-project.d.ts +11 -1
  121. package/dist/src/setup/boxes/deploy-project.js +1 -1
  122. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  123. package/dist/src/setup/scaffold/create/extension.js +2 -2
  124. package/dist/src/setup/scaffold/create/project.js +2 -2
  125. package/dist/src/setup/scaffold/update/channels.js +1 -1
  126. package/dist/src/setup/scaffold/update/connections.js +1 -1
  127. package/dist/src/setup/vercel-project-framework.d.ts +4 -2
  128. package/dist/src/shared/extension-package-contract.d.ts +11 -0
  129. package/dist/src/shared/extension-package-contract.js +1 -0
  130. package/dist/src/shared/json.d.ts +4 -0
  131. package/dist/src/shared/json.js +1 -1
  132. package/dist/src/shared/tool-schema.d.ts +52 -0
  133. package/dist/src/shared/tool-schema.js +1 -0
  134. package/dist/src/svelte/index.js +1 -1
  135. package/dist/src/svelte/use-eve-agent.js +1 -1
  136. package/dist/src/vue/index.js +1 -1
  137. package/dist/src/vue/use-eve-agent.js +1 -1
  138. package/docs/concepts/sessions-runs-and-streaming.md +6 -0
  139. package/docs/extensions.md +22 -6
  140. package/docs/reference/cli.md +2 -2
  141. package/package.json +1 -1
  142. package/dist/src/internal/json-schema.d.ts +0 -1
  143. package/dist/src/internal/json-schema.js +0 -1
  144. package/dist/src/setup/boxes/reconcile-host-framework-preset.d.ts +0 -26
  145. package/dist/src/setup/boxes/reconcile-host-framework-preset.js +0 -1
  146. package/dist/src/shared/json-schema.d.ts +0 -9
  147. package/dist/src/shared/json-schema.js +0 -1
@@ -1 +1 @@
1
- import{compiledModuleMapSchema}from"#compiler/module-map.js";import{readBundledCompiledArtifacts}from"#runtime/loaders/bundled-artifacts.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";import{formatValidationError}from"#runtime/validation.js";const BUNDLED_MODULE_MAP_SOURCE=`bundled compiled module map`;var LoadCompiledModuleMapError=class extends Error{moduleMapPath;constructor(e,t){super(e),this.name=`LoadCompiledModuleMapError`,t!==void 0&&(this.moduleMapPath=t)}};async function loadCompiledModuleMap(e){let r=e.compiledArtifactsSource.kind===`disk`?resolveRuntimeCompilerArtifactPaths(e.compiledArtifactsSource.appRoot).moduleMapPath:void 0;if(r!==void 0){let e=createFileImportSpecifier(r);try{let t=await import(e);return parseCompiledModuleMap(t.moduleMap??t.default,r)}catch(e){throw new LoadCompiledModuleMapError(formatLoadErrorMessage(e),r)}}let a=readBundledCompiledArtifacts();if(a!==null)return parseCompiledModuleMap(a.moduleMap,BUNDLED_MODULE_MAP_SOURCE);throw new LoadCompiledModuleMapError(`Compiled module map is unavailable without an app root or bundled compiled artifacts.`,BUNDLED_MODULE_MAP_SOURCE)}function parseCompiledModuleMap(t,n){let i=compiledModuleMapSchema.safeParse(t);if(!i.success)throw new LoadCompiledModuleMapError(`Expected "${n}" to export a valid compiled eve module map. ${formatValidationError(i.error)}`,n);return i.data}function formatLoadErrorMessage(e){return e instanceof Error?e.message:`Unknown module-map load failure.`}function createFileImportSpecifier(e){let t=e.replaceAll(`\\`,`/`);return/^[A-Za-z]:\//.test(t)?`file:///${encodeURI(t)}`:t.startsWith(`/`)?`file://${encodeURI(t)}`:t}export{LoadCompiledModuleMapError,loadCompiledModuleMap};
1
+ import{compiledModuleMapSchema}from"#compiler/module-map.js";import{formatValidationError}from"#runtime/validation.js";import{readBundledCompiledArtifacts}from"#runtime/loaders/bundled-artifacts.js";import{resolveRuntimeCompilerArtifactPaths}from"#runtime/loaders/artifact-paths.js";const BUNDLED_MODULE_MAP_SOURCE=`bundled compiled module map`;var LoadCompiledModuleMapError=class extends Error{moduleMapPath;constructor(e,t){super(e),this.name=`LoadCompiledModuleMapError`,t!==void 0&&(this.moduleMapPath=t)}};async function loadCompiledModuleMap(e){let t=e.compiledArtifactsSource.kind===`disk`?resolveRuntimeCompilerArtifactPaths(e.compiledArtifactsSource.appRoot).moduleMapPath:void 0;if(t!==void 0){let e=createFileImportSpecifier(t);try{let n=await import(e);return parseCompiledModuleMap(n.moduleMap??n.default,t)}catch(e){throw new LoadCompiledModuleMapError(formatLoadErrorMessage(e),t)}}let a=readBundledCompiledArtifacts();if(a!==null)return parseCompiledModuleMap(a.moduleMap,BUNDLED_MODULE_MAP_SOURCE);throw new LoadCompiledModuleMapError(`Compiled module map is unavailable without an app root or bundled compiled artifacts.`,BUNDLED_MODULE_MAP_SOURCE)}function parseCompiledModuleMap(n,r){let i=compiledModuleMapSchema.safeParse(n);if(!i.success)throw new LoadCompiledModuleMapError(`Expected "${r}" to export a valid compiled eve module map. ${formatValidationError(i.error)}`,r);return i.data}function formatLoadErrorMessage(e){return e instanceof Error?e.message:`Unknown module-map load failure.`}function createFileImportSpecifier(e){let t=e.replaceAll(`\\`,`/`);return/^[A-Za-z]:\//.test(t)?`file:///${encodeURI(t)}`:t.startsWith(`/`)?`file://${encodeURI(t)}`:t}export{LoadCompiledModuleMapError,loadCompiledModuleMap};
@@ -5,10 +5,9 @@ import type { ResolvedToolDefinition } from "#runtime/types.js";
5
5
  * Resolves one compiled authored tool into a runtime-owned definition
6
6
  * with live callbacks reattached from the authored module.
7
7
  *
8
- * Optional hooks (`approval`, plus an optional Standard Schema
9
- * `inputSchema`) are extracted when
10
- * declared and validated to have the expected shape; any type mismatch
11
- * raises a {@link ResolveAgentError} so typos surface at resolve time
12
- * instead of at first tool call.
8
+ * Schema-bearing module exports are retained when they implement the validated
9
+ * runtime contract; serialized schemas from the compiled manifest are
10
+ * otherwise rehydrated into live validators. Optional hooks are reattached
11
+ * from the live module export.
13
12
  */
14
13
  export declare function resolveToolDefinition(definition: CompiledToolDefinition, moduleMap: CompiledModuleMap, nodeId: string | undefined): Promise<ResolvedToolDefinition>;
@@ -1 +1 @@
1
- import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(i,a,o){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:i,kindLabel:`tool`,moduleMap:a,nodeId:o}),describe(i,`to return an object`)),r={kind:`tool`,logicalPath:i.logicalPath,name:i.name},s=`tool-source:${i.sourceId}`;stampDefinitionKey(n,s),registerDefinitionSource(s,r),registerDefinitionSource(`tool:${n.description}`,r);let c=expectFunction(n.execute,describe(i,`to provide an execute function`));return{description:i.description,execute:c,exportName:i.exportName,inputSchema:i.inputSchema,logicalPath:i.logicalPath,name:i.name,outputSchema:i.outputSchema,sourceId:i.sourceId,sourceKind:`module`,...extractOptionalHooks(n,i)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${i.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:i.logicalPath,sourceId:i.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.approval!==void 0&&(r.approval=expectFunction(t.approval,describe(n,`to provide an approval function`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),t.inputSchema!==void 0&&isFlexibleSchema(t.inputSchema)&&(r.inputStandardSchema=t.inputSchema),t.outputSchema!==void 0&&isFlexibleSchema(t.outputSchema)&&(r.outputStandardSchema=t.outputSchema),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}function isFlexibleSchema(e){return typeof e==`object`&&!!e&&`~standard`in e&&typeof e[`~standard`]==`object`}export{resolveToolDefinition};
1
+ import{expectFunction,expectObjectRecord}from"#internal/authored-module.js";import{toErrorMessage}from"#shared/errors.js";import{isToolSchema,toInputSchema,toOutputSchema}from"#shared/tool-schema.js";import{ResolveAgentError,loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{registerDefinitionSource,stampDefinitionKey}from"#public/tool-result-narrowing.js";async function resolveToolDefinition(a,o,s){try{let n=expectObjectRecord(await loadResolvedModuleExport({definition:a,kindLabel:`tool`,moduleMap:o,nodeId:s}),describe(a,`to return an object`)),i={kind:`tool`,logicalPath:a.logicalPath,name:a.name},c=`tool-source:${a.sourceId}`;stampDefinitionKey(n,c),registerDefinitionSource(c,i),registerDefinitionSource(`tool:${n.description}`,i);let l=expectFunction(n.execute,describe(a,`to provide an execute function`)),u=isToolSchema(n.inputSchema)?n.inputSchema:toInputSchema(a.inputSchema),d=isToolSchema(n.outputSchema)?n.outputSchema:toOutputSchema(a.outputSchema);return{description:a.description,execute:l,exportName:a.exportName,inputSchema:u,logicalPath:a.logicalPath,name:a.name,outputSchema:d,sourceId:a.sourceId,sourceKind:`module`,...extractOptionalHooks(n,a)}}catch(e){throw e instanceof ResolveAgentError?e:new ResolveAgentError(`Failed to attach the tool execute function from "${a.logicalPath}": ${toErrorMessage(e)}`,{logicalPath:a.logicalPath,sourceId:a.sourceId})}}function extractOptionalHooks(t,n){let r={};return t.approval!==void 0&&(r.approval=expectFunction(t.approval,describe(n,`to provide an approval function`))),t.toModelOutput!==void 0&&(r.toModelOutput=expectFunction(t.toModelOutput,describe(n,`to provide a toModelOutput function`))),r}function describe(e,t){return`Expected the tool export "${e.exportName??`default`}" from "${e.logicalPath}" ${t}.`}export{resolveToolDefinition};
@@ -1,4 +1,4 @@
1
- import type { JsonObject } from "#shared/json.js";
1
+ import { z } from "#compiled/zod/index.js";
2
2
  import type { PreparedRuntimeDelegationTool } from "#runtime/sessions/turn.js";
3
3
  import type { ResolvedRuntimeDelegationNode } from "#runtime/types.js";
4
4
  /**
@@ -17,10 +17,13 @@ export interface RuntimeSubagentRegistry {
17
17
  readonly subagentsByNodeId: ReadonlyMap<string, RuntimeRegisteredSubagent>;
18
18
  }
19
19
  /**
20
- * Stable JSON Schema lowered onto every subagent tool. Subagents always
20
+ * Stable input schema lowered onto every subagent tool. Subagents always
21
21
  * accept one free-form `message` string from the parent agent.
22
22
  */
23
- export declare const SUBAGENT_TOOL_INPUT_SCHEMA: JsonObject;
23
+ export declare const SUBAGENT_TOOL_INPUT_SCHEMA: z.ZodObject<{
24
+ message: z.ZodString;
25
+ outputSchema: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
26
+ }, z.core.$strict>;
24
27
  /**
25
28
  * Builds the runtime-owned registry for the resolved subagents visible from one
26
29
  * runtime agent node.
@@ -1 +1 @@
1
- import{RuntimeRegistry,RuntimeRegistryError}from"#internal/runtime-registry.js";const SUBAGENT_TOOL_INPUT_SCHEMA=Object.freeze({type:`object`,properties:Object.freeze({message:Object.freeze({type:`string`,description:`The message to send to the subagent. Provide all context the subagent needs to complete the task; the subagent does not see the parent's history.`}),outputSchema:Object.freeze({type:`object`,description:`When provided, the subagent runs in task mode and must produce structured output matching this JSON Schema. The structured output becomes the tool result.`})}),required:Object.freeze([`message`]),additionalProperties:!1});function createRuntimeSubagentRegistry(t){let n=[],r=new RuntimeRegistry(`subagent`,t.reservedToolNames??[]),i=new Map;for(let e of t.subagents){let t={logicalPath:e.logicalPath,sourceId:e.sourceId};if(i.has(e.nodeId))throw new RuntimeRegistryError(`subagent`,`Found multiple runtime subagents mapped to node id "${e.nodeId}".`,{...t,entryName:e.name});let a=createPreparedRuntimeSubagentTool(e),o={definition:e,prepared:a};r.register(e.name,o,{location:t,duplicateMessage:`Found multiple subagents named "${e.name}". Subagent names must be unique at runtime.`,reservedMessage:`Subagent "${e.name}" collides with another runtime-visible tool name.`}),n.push(a),i.set(e.nodeId,o)}return{preparedTools:n,subagentsByName:r.asMap(),subagentsByNodeId:i}}function createPreparedRuntimeSubagentTool(e){return{description:e.description,inputSchema:SUBAGENT_TOOL_INPUT_SCHEMA,kind:e.kind,logicalPath:e.logicalPath,name:e.name,nodeId:e.nodeId,outputSchema:e.kind===`remote`?e.outputSchema:void 0,sourceId:e.sourceId}}export{SUBAGENT_TOOL_INPUT_SCHEMA,createRuntimeSubagentRegistry};
1
+ import{z}from"#compiled/zod/index.js";import{serializeInputSchema}from"#shared/tool-schema.js";import{RuntimeRegistry,RuntimeRegistryError}from"#internal/runtime-registry.js";const SUBAGENT_TOOL_INPUT_SCHEMA=z.strictObject({message:z.string().describe(`The message to send to the subagent. Provide all context the subagent needs to complete the task; the subagent does not see the parent's history.`),outputSchema:z.looseObject({}).describe(`Only provide a non-empty JSON Schema when the caller explicitly requests structured output; otherwise omit this field. The subagent must match a provided schema, and that structured output becomes the tool result.`).optional()}),SUBAGENT_TOOL_INPUT_JSON_SCHEMA=serializeInputSchema(SUBAGENT_TOOL_INPUT_SCHEMA);function createRuntimeSubagentRegistry(e){let t=[],r=new RuntimeRegistry(`subagent`,e.reservedToolNames??[]),i=new Map;for(let n of e.subagents){let e={logicalPath:n.logicalPath,sourceId:n.sourceId};if(i.has(n.nodeId))throw new RuntimeRegistryError(`subagent`,`Found multiple runtime subagents mapped to node id "${n.nodeId}".`,{...e,entryName:n.name});let a=createPreparedRuntimeSubagentTool(n),o={definition:n,prepared:a};r.register(n.name,o,{location:e,duplicateMessage:`Found multiple subagents named "${n.name}". Subagent names must be unique at runtime.`,reservedMessage:`Subagent "${n.name}" collides with another runtime-visible tool name.`}),t.push(a),i.set(n.nodeId,o)}return{preparedTools:t,subagentsByName:r.asMap(),subagentsByNodeId:i}}function createPreparedRuntimeSubagentTool(e){return{description:e.description,inputSchema:SUBAGENT_TOOL_INPUT_JSON_SCHEMA,kind:e.kind,logicalPath:e.logicalPath,name:e.name,nodeId:e.nodeId,outputSchema:e.kind===`remote`?e.outputSchema:void 0,sourceId:e.sourceId}}export{SUBAGENT_TOOL_INPUT_SCHEMA,createRuntimeSubagentRegistry};
@@ -1 +1 @@
1
- import{RuntimeRegistry}from"#internal/runtime-registry.js";async function createRuntimeToolRegistry(t,n={}){let r=[],i=new RuntimeRegistry(`tool`,n.reservedToolNames??[]);for(let e of t.tools){let t=await createPreparedRuntimeTool(e);i.register(e.name,{definition:e,prepared:t},{location:{logicalPath:e.logicalPath,sourceId:e.sourceId},duplicateMessage:`Found multiple authored tools named "${e.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${e.name}" collides with another runtime-visible tool name.`}),r.push(t)}return{preparedTools:r,toolsByName:i.asMap()}}function findRegisteredRuntimeTool(e,t){return e.toolsByName.get(t)??null}async function createPreparedRuntimeTool(e){return{description:e.description,inputSchema:e.inputSchema,kind:`authored-tool`,logicalPath:e.logicalPath,name:e.name,outputSchema:e.outputSchema,sourceId:e.sourceId}}export{createRuntimeToolRegistry,findRegisteredRuntimeTool};
1
+ import{serializeInputSchema,serializeOutputSchema}from"#shared/tool-schema.js";import{RuntimeRegistry}from"#internal/runtime-registry.js";async function createRuntimeToolRegistry(e,t={}){let r=[],i=new RuntimeRegistry(`tool`,t.reservedToolNames??[]);for(let t of e.tools){let e=await createPreparedRuntimeTool(t);i.register(t.name,{definition:t,prepared:e},{location:{logicalPath:t.logicalPath,sourceId:t.sourceId},duplicateMessage:`Found multiple authored tools named "${t.name}". Tool names must be unique at runtime.`,reservedMessage:`Tool "${t.name}" collides with another runtime-visible tool name.`}),r.push(e)}return{preparedTools:r,toolsByName:i.asMap()}}function findRegisteredRuntimeTool(e,t){return e.toolsByName.get(t)??null}async function createPreparedRuntimeTool(n){return{description:n.description,inputSchema:serializeInputSchema(n.inputSchema),kind:`authored-tool`,logicalPath:n.logicalPath,name:n.name,outputSchema:serializeOutputSchema(n.outputSchema),sourceId:n.sourceId}}export{createRuntimeToolRegistry,findRegisteredRuntimeTool};
@@ -1,4 +1,3 @@
1
- import type { FlexibleSchema } from "ai";
2
1
  import type { ChannelAdapter } from "#channel/adapter.js";
3
2
  import type { CompiledChannel } from "#channel/compiled-channel.js";
4
3
  import type { NormalizedChannelCorsOptions } from "#channel/cors.js";
@@ -25,6 +24,7 @@ import type { RuntimeDynamicModelReference } from "#runtime/agent/bootstrap.js";
25
24
  import type { InternalToolDefinitionWithExecuteFn } from "#shared/tool-definition.js";
26
25
  import type { SandboxBackend } from "#shared/sandbox-backend.js";
27
26
  import type { SandboxBootstrapContext, SandboxSessionContext } from "#shared/sandbox-definition.js";
27
+ import type { ToolSchema } from "#shared/tool-schema.js";
28
28
  /**
29
29
  * Runtime-owned source ref describing one additive config module import.
30
30
  */
@@ -124,18 +124,16 @@ export type ResolvedSandboxDefinition = ResolvedModuleSourceRef & {
124
124
  * declared by the framework catalog.
125
125
  * A tool without `execute` is surfaced to the client and never executed by eve.
126
126
  */
127
- export type ResolvedToolDefinition = Readonly<Optional<InternalToolDefinitionWithExecuteFn<unknown, unknown>, "execute">> & ResolvedModuleSourceRef & {
127
+ export type ResolvedToolDefinition = Readonly<Omit<Optional<InternalToolDefinitionWithExecuteFn<unknown, unknown>, "execute">, "inputSchema" | "outputSchema">> & ResolvedModuleSourceRef & {
128
128
  /**
129
- * Optional live Standard Schema reattached from the authored module at
130
- * resolve time. When present, the AI SDK uses it for both JSON schema
131
- * extraction and runtime validation with transforms/defaults.
129
+ * Validated runtime input schema. Compiled and durable JSON Schemas are
130
+ * rehydrated before entering this runtime-owned definition.
132
131
  */
133
- readonly inputStandardSchema?: FlexibleSchema;
132
+ readonly inputSchema: ToolSchema | null;
134
133
  /**
135
- * Optional live Standard Schema reattached from the authored module at
136
- * resolve time for tool output typing/validation.
134
+ * Optional validated runtime output schema.
137
135
  */
138
- readonly outputStandardSchema?: FlexibleSchema;
136
+ readonly outputSchema?: ToolSchema;
139
137
  /**
140
138
  * Optional per-tool approval gate. When set, determines whether user
141
139
  * approval is required before executing this tool. See
@@ -5,12 +5,14 @@ import { runVercel } from "#setup/primitives/run-vercel.js";
5
5
  import { detectDeployment, type ProjectResolution } from "../project-resolution.js";
6
6
  import { type SetupState } from "../state.js";
7
7
  import type { SetupBox } from "../step.js";
8
+ import { syncHostFrameworkPreset } from "../vercel-project-framework.js";
8
9
  /** Injected for tests; defaults to the real subprocess primitives. */
9
10
  export interface DeployProjectDeps {
10
11
  runVercel: typeof runVercel;
11
12
  detectPackageManager: typeof detectPackageManager;
12
13
  runPackageManagerInstall: typeof runPackageManagerInstall;
13
14
  detectDeployment: typeof detectDeployment;
15
+ syncHostFrameworkPreset: typeof syncHostFrameworkPreset;
14
16
  }
15
17
  export interface DeployProjectOptions {
16
18
  /** Deploy progress and command output stream through this log (rail styling preserved). */
@@ -51,12 +53,20 @@ export interface DeployProjectPayload {
51
53
  /**
52
54
  * THE DEPLOY BOX. Owns the post-channel `vercel deploy --prod` once channel
53
55
  * setup has marked deployment work pending: dependency install (once per
54
- * state), the production deploy, the env pull, and the deployment probe.
56
+ * state), aligning the Vercel Framework Preset with the host framework on disk,
57
+ * the production deploy, the env pull, and the deployment probe.
55
58
  *
56
59
  * The project was linked up front by the link box, so `perform` reuses
57
60
  * `state.project` and never triggers a second interactive `vercel link` (the
58
61
  * #1020 deadlock). When no resolution exists (no link box ran, e.g. the
59
62
  * `eve channels add` composition), it falls back to the interactive bare
60
63
  * `vercel link`, or throws {@link HumanActionRequiredError} headlessly.
64
+ *
65
+ * Once the project is linked, {@link syncHostFrameworkPreset} runs before the
66
+ * deploy so a project that gained a host framework (e.g. a web channel) builds
67
+ * the host app instead of the stale `eve` agent preset. It is a no-op for a
68
+ * plain agent (no host framework on disk) or an already-correct preset, so
69
+ * every deploy surface — `eve channels add`, the dev TUI `/deploy`, onboarding —
70
+ * gets the reconcile without composing a separate box.
61
71
  */
62
72
  export declare function deployProject(options: DeployProjectOptions): SetupBox<SetupState, DeployProjectInput, DeployProjectPayload>;
@@ -1 +1 @@
1
- import{detectDeployment,isProjectResolved,mergeProjectResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment}from"../project-resolution.js";import{hasVercelProject,requireProjectPath}from"../state.js";import{detectPackageManager}from"#setup/package-manager.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{runPackageManagerInstall}from"#setup/primitives/pm/run.js";import{runVercel}from"#setup/primitives/run-vercel.js";const VERCEL_DEPLOY_ENV={VERCEL_USE_EXPERIMENTAL_FRAMEWORKS:`1`};function deployProject(o){let s=o.deps??{runVercel,detectPackageManager,runPackageManagerInstall,detectDeployment};return{id:`deploy-project`,shouldRun(e){return o.skip||!e.deploymentPending?!1:hasVercelProject(e)||o.ensureLinkedProject===`interactive-vercel-link`},async gather(){return{headless:o.headless??!1}},async perform({state:e,input:n,signal:r}){let i=requireProjectPath(e),{log:a}=o.prompter,c=createPromptCommandOutput(a),l=e.project;if(!isProjectResolved(l)){if(n.headless)throw new HumanActionRequiredError({kind:`vercel-link`,command:`vercel link`,reason:`Deployment needs this directory linked to a Vercel project.`});if(a.message(`Linking this directory to a Vercel project before deployment...`),!await s.runVercel([`link`],{cwd:i,signal:r}))throw r?.throwIfAborted(),Error(`Vercel project linking failed. Deployment did not start.`);if(l=mergeProjectResolution(l,projectResolutionFromDeployment(await s.detectDeployment(i,{signal:r}))),!isProjectResolved(l))throw Error(`Vercel project linking failed. Deployment did not start.`)}if(!e.deploymentDependenciesInstalled){let e=await s.detectPackageManager(i);if(!await withPhase(a,`Installing project dependencies before deployment (${e.kind} install)...`,()=>s.runPackageManagerInstall(e.kind,i,{onOutput:c,signal:r})))throw r?.throwIfAborted(),Error(`Dependency installation failed. Deployment did not start.`)}let u=n.headless?[`deploy`,`--prod`,`--yes`,`--non-interactive`]:[`deploy`,`--prod`,`--yes`],d=await withPhase(a,`Deploying the agent to Vercel production...`,()=>s.runVercel(u,{cwd:i,extraEnv:VERCEL_DEPLOY_ENV,nonInteractive:n.headless,onOutput:c,signal:r}));if(r?.throwIfAborted(),!d)throw a.error("`vercel deploy --prod` failed. The deploy output above shows the cause; fix it, then run `vercel deploy --prod` to retry."),Error(`Deployment failed after channel setup.`);let f=await withPhase(a,`Pulling Vercel environment variables into .env.local...`,()=>s.runVercel([`env`,`pull`,`--yes`],{cwd:i,nonInteractive:n.headless,onOutput:c,signal:r}));r?.throwIfAborted(),f||a.warning(`Deployment succeeded, but pulling Vercel environment variables did not complete.`);let p=await s.detectDeployment(i,{signal:r}),m=p.state===`deployed`?p.productionUrl:void 0;return m===void 0?a.warning(`Deployment succeeded, but eve could not verify its production URL.`):a.info(`Production URL: ${m}`),{project:projectResolutionFromDeployResult(l,{deployed:!0,productionUrl:m}),deploymentPending:!1,deploymentDependenciesInstalled:!0}},apply(e,t){return{...e,project:t.project,deploymentPending:t.deploymentPending,deploymentDependenciesInstalled:t.deploymentDependenciesInstalled}}}}export{deployProject};
1
+ import{detectDeployment,isProjectResolved,mergeProjectResolution,projectResolutionFromDeployResult,projectResolutionFromDeployment}from"../project-resolution.js";import{hasVercelProject,requireProjectPath}from"../state.js";import{syncHostFrameworkPreset}from"../vercel-project-framework.js";import{detectPackageManager}from"#setup/package-manager.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{createPromptCommandOutput,withPhase}from"#setup/cli/index.js";import{runPackageManagerInstall}from"#setup/primitives/pm/run.js";import{runVercel}from"#setup/primitives/run-vercel.js";const VERCEL_DEPLOY_ENV={VERCEL_USE_EXPERIMENTAL_FRAMEWORKS:`1`};function deployProject(s){let c=s.deps??{runVercel,detectPackageManager,runPackageManagerInstall,detectDeployment,syncHostFrameworkPreset};return{id:`deploy-project`,shouldRun(e){return s.skip||!e.deploymentPending?!1:hasVercelProject(e)||s.ensureLinkedProject===`interactive-vercel-link`},async gather(){return{headless:s.headless??!1}},async perform({state:e,input:n,signal:r}){let i=requireProjectPath(e),{log:a}=s.prompter,o=createPromptCommandOutput(a),l=e.project;if(!isProjectResolved(l)){if(n.headless)throw new HumanActionRequiredError({kind:`vercel-link`,command:`vercel link`,reason:`Deployment needs this directory linked to a Vercel project.`});if(a.message(`Linking this directory to a Vercel project before deployment...`),!await c.runVercel([`link`],{cwd:i,signal:r}))throw r?.throwIfAborted(),Error(`Vercel project linking failed. Deployment did not start.`);if(l=mergeProjectResolution(l,projectResolutionFromDeployment(await c.detectDeployment(i,{signal:r}))),!isProjectResolved(l))throw Error(`Vercel project linking failed. Deployment did not start.`)}if(await c.syncHostFrameworkPreset(s.prompter,i,o,r?{signal:r}:{}),!e.deploymentDependenciesInstalled){let e=await c.detectPackageManager(i);if(!await withPhase(a,`Installing project dependencies before deployment (${e.kind} install)...`,()=>c.runPackageManagerInstall(e.kind,i,{onOutput:o,signal:r})))throw r?.throwIfAborted(),Error(`Dependency installation failed. Deployment did not start.`)}let u=n.headless?[`deploy`,`--prod`,`--yes`,`--non-interactive`]:[`deploy`,`--prod`,`--yes`],d=await withPhase(a,`Deploying the agent to Vercel production...`,()=>c.runVercel(u,{cwd:i,extraEnv:VERCEL_DEPLOY_ENV,nonInteractive:n.headless,onOutput:o,signal:r}));if(r?.throwIfAborted(),!d)throw a.error("`vercel deploy --prod` failed. The deploy output above shows the cause; fix it, then run `vercel deploy --prod` to retry."),Error(`Deployment failed after channel setup.`);let f=await withPhase(a,`Pulling Vercel environment variables into .env.local...`,()=>c.runVercel([`env`,`pull`,`--yes`],{cwd:i,nonInteractive:n.headless,onOutput:o,signal:r}));r?.throwIfAborted(),f||a.warning(`Deployment succeeded, but pulling Vercel environment variables did not complete.`);let p=await c.detectDeployment(i,{signal:r}),m=p.state===`deployed`?p.productionUrl:void 0;return m===void 0?a.warning(`Deployment succeeded, but eve could not verify its production URL.`):a.info(`Production URL: ${m}`),{project:projectResolutionFromDeployResult(l,{deployed:!0,productionUrl:m}),deploymentPending:!1,deploymentDependenciesInstalled:!0}},apply(e,t){return{...e,project:t.project,deploymentPending:t.deploymentPending,deploymentDependenciesInstalled:t.deploymentDependenciesInstalled}}}}export{deployProject};
@@ -1 +1 @@
1
- import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.26`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.2.2`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
1
+ import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"../update/package-json.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{agentTemplateFiles,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`,`optionalDependencies`,`peerDependencies`];function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasDeclaredDependency(e,t){if(!isJsonObject(e))return!1;for(let n of DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function addAgentToProject(i){let a=i.packageManager??`pnpm`,o=join(i.projectRoot,`package.json`);if(!await pathExists(o))throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it has no package.json. Run \`eve init <name>\` to create a new project instead.`);let s=agentTemplateFiles(i.model),c=[];for(let t of Object.keys(s))await pathExists(join(i.projectRoot,t))&&c.push(t);if(c.length===0&&await pathExists(join(i.projectRoot,`agent`))&&c.push(`agent/`),c.length>0)throw Error(`Cannot add an eve agent to "${i.projectRoot}" because it already has: ${c.join(`, `)}.`);let l=resolveEvePackageContract(i.evePackage),u=resolveVersionToken(`aiPackageVersion`,i.aiPackageVersion??`^7.0.26`),d=resolveVersionToken(`connectPackageVersion`,i.connectPackageVersion??`0.4.0`),f=resolveVersionToken(`zodPackageVersion`,i.zodPackageVersion??`4.4.3`),p=[];for(let[e,n]of Object.entries(s)){let r=join(i.projectRoot,e);await writeTextFile(r,n),p.push(r)}let m=JSON.parse(await readFile(o,`utf8`)),h={"@vercel/connect":d,ai:u,eve:formatEveDependencySpecifier(l.version),zod:f},g={};for(let[e,t]of Object.entries(h))hasDeclaredDependency(m,e)||(g[e]=t);let _={};Object.keys(g).length>0&&(_.dependencies=g),isPackageManagerWorkspaceMember(a,i.projectRoot)||(_.nodeEngineRequirement=l.nodeEngine);let v=await patchPackageJson(o,_),y=(await patchWorkspaceRootPackageJson(a,i.projectRoot,{aiPackageVersion:u,nodeEngineRequirement:l.nodeEngine})).nodeEngineOverride??v.nodeEngineOverride;return await applyPackageManagerWorkspaceConfiguration({packageManager:a,projectRoot:i.projectRoot}),{filesWritten:p,dependenciesAdded:Object.keys(g).sort(),nodeEngineOverride:y}}export{addAgentToProject};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";const ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]);function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function packageJsonTemplate(e){return`${JSON.stringify({name:`__EVE_INIT_APP_NAME__`,version:`0.0.0`,type:`module`,eve:{extension:`./extension`},files:[`extension`,`dist`],exports:{".":`./extension/extension.ts`},scripts:{build:`eve extension build`,prepare:`eve extension build`,typecheck:`tsc`},dependencies:{zod:`__EVE_INIT_ZOD_VERSION__`},devDependencies:{"@types/node":`__EVE_INIT_TYPES_NODE_VERSION__`,eve:`__EVE_INIT_PACKAGE_VERSION__`,typescript:`__EVE_INIT_TYPESCRIPT_VERSION__`},peerDependencies:{eve:`__EVE_INIT_PACKAGE_VERSION__`}},null,2).slice(0,-1)}${e?ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX:``}}\n`}function templateFiles(e){return{"extension/extension.ts":`import { defineExtension } from "eve/extension";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";const ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]);function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function packageJsonTemplate(e){return`${JSON.stringify({name:`__EVE_INIT_APP_NAME__`,version:`0.0.0`,type:`module`,eve:{extension:{source:`./extension`,dist:`./dist/extension`}},files:[`dist`],exports:{".":{types:`./dist/index.d.ts`,default:`./dist/index.mjs`},"./tools":{types:`./dist/tools/index.d.ts`,default:`./dist/tools/index.mjs`}},scripts:{build:`eve extension build`,prepare:`eve extension build`,typecheck:`tsc`},dependencies:{zod:`__EVE_INIT_ZOD_VERSION__`},devDependencies:{"@types/node":`__EVE_INIT_TYPES_NODE_VERSION__`,eve:`__EVE_INIT_PACKAGE_VERSION__`,typescript:`__EVE_INIT_TYPESCRIPT_VERSION__`},peerDependencies:{eve:`*`}},null,2).slice(0,-1)}${e?ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX:``}}\n`}function templateFiles(e){return{"extension/extension.ts":`import { defineExtension } from "eve/extension";
2
2
  import { z } from "zod";
3
3
 
4
4
  export default defineExtension({
@@ -29,5 +29,5 @@ export default defineExtension({
29
29
  dist
30
30
  .DS_Store
31
31
  *.tsbuildinfo
32
- `,"AGENTS.md":"# eve Extension Package\n\nThis package is an eve extension — a reusable package of tools, connections,\nskills, hooks, and instruction fragments that a consuming agent mounts under\n`agent/extensions/`.\n\nBefore writing code, read the Extensions guide from the installed eve package\ndocs. In most installs, those docs are at `node_modules/eve/docs/extensions.md`.\nIn workspaces or local package installs, resolve the installed `eve` package\nlocation first and read its `docs/extensions.md`. If package docs are\nunavailable, use https://eve.dev/docs/extensions as a fallback.\n\n## Authoring\n\n- Declare the extension in `extension/extension.ts` with `defineExtension` from\n `eve/extension`. Config is optional; read bound values via the handle's\n `.config` in tools and hooks.\n- Add contributions under `extension/` the same way as in an agent:\n `tools/`, `connections/`, `skills/`, `hooks/`, and optional instruction\n fragments. Names come from file paths; the mount supplies the namespace, so\n name tools for what they do (`search`, not `crm_search`).\n- An extension cannot declare `agent.ts`, `sandbox`, `schedules`, or nested\n `extensions/` — those belong to the consuming agent.\n\n## Build and publish\n\n`eve extension build` (wired to `build`/`prepare`) compiles the mount factory\nand tool re-exports into `dist/` and fills the package `exports` map. Ship both\n`extension/` (source the consumer recompiles) and `dist/`. Keep `eve` as a peer\ndependency so the consumer's eve is the one that runs.\n","CLAUDE.md":`@AGENTS.md
32
+ `,"AGENTS.md":"# eve Extension Package\n\nThis package is an eve extension — a reusable package of tools, connections,\nskills, hooks, and instruction fragments that a consuming agent mounts under\n`agent/extensions/`.\n\nBefore writing code, read the Extensions guide from the installed eve package\ndocs. In most installs, those docs are at `node_modules/eve/docs/extensions.md`.\nIn workspaces or local package installs, resolve the installed `eve` package\nlocation first and read its `docs/extensions.md`. If package docs are\nunavailable, use https://eve.dev/docs/extensions as a fallback.\n\n## Authoring\n\n- Declare the extension in `extension/extension.ts` with `defineExtension` from\n `eve/extension`. Config is optional; read bound values via the handle's\n `.config` in tools and hooks.\n- Add contributions under `extension/` the same way as in an agent:\n `tools/`, `connections/`, `skills/`, `hooks/`, and optional instruction\n fragments. Names come from file paths; the mount supplies the namespace, so\n name tools for what they do (`search`, not `crm_search`).\n- An extension cannot declare `agent.ts`, `sandbox`, `schedules`, or nested\n `extensions/` — those belong to the consuming agent.\n\n## Build and publish\n\n`eve extension build` (wired to `build`/`prepare`) transforms the complete\nagent-shaped source tree into `dist/extension/`, emits type declarations and a\ncompatibility manifest, and fills the package `exports` map. Ship `dist/` only.\nKeep `eve` as a required wildcard peer so the consumer's eve is the one that runs;\neve validates extension compatibility from the generated manifest.\n","CLAUDE.md":`@AGENTS.md
33
33
  `,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldExtensionProject(o){let s=resolve(o.targetDirectory??process.cwd(),o.projectName),c=o.projectName===`.`,l=o.overwriteExisting??!1,u=o.packageManager??`pnpm`,d=resolveEvePackageContract(o.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT),f=pinnedNodeEngineMajor(d.nodeEngine),p=resolve(o.workspaceProbeDirectory??s),m=isPackageManagerWorkspaceMember(u,p);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let h={appName:basename(s),eveVersion:d.version,zodPackageVersion:resolveVersionToken(`zodPackageVersion`,o.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,o.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:f,nodeEngine:f};await mkdir(s,{recursive:!0});for(let[e,r]of Object.entries(templateFiles(!m))){let i=`${s}/${e}`,a=await pathExists(i);await writeTextFile(i,renderTemplate(r,h),{force:c&&l}),a&&await o.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:u,projectRoot:s,workspaceProbeRoot:p,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(u,p,{nodeEngineRequirement:d.nodeEngine,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),s}export{scaffoldExtensionProject};
@@ -1,4 +1,4 @@
1
- import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.26`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.24.6`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS}from"../update/module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{WEB_APP_TEMPLATE_FILES}from"./web-template.js";import{basename,join,resolve}from"node:path";import{mkdir,readdir,stat}from"node:fs/promises";const CURRENT_DIRECTORY_PROJECT_NAME=`.`,ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]),DEFAULT_AI_PACKAGE_VERSION=`^7.0.26`,DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.0`,DEFAULT_ZOD_PACKAGE_VERSION=`4.4.3`,DEFAULT_EVE_PACKAGE_CONTRACT={version:`0.25.0`,nodeEngine:`>=24`};function resolveEvePackageContract(e=DEFAULT_EVE_PACKAGE_CONTRACT){return{version:resolveVersionToken(`evePackage.version`,e.version),nodeEngine:resolveVersionToken(`evePackage.nodeEngine`,e.nodeEngine)}}function modelProviderSlug(e){let t=(e.split(`/`)[0]??``).replaceAll(/[^A-Za-z0-9._-]/gu,``);return t.length>0?t:`anthropic`}function byokProviderEnvVar(e){let t=modelProviderSlug(e).toUpperCase().replaceAll(/[^A-Z0-9]/gu,`_`);return`${/^[0-9]/.test(t)?`_`:``}${t}_API_KEY`}function agentTemplateFiles(e){return{"agent/agent.ts":BASE_AGENT_TEMPLATE.replaceAll(`__EVE_INIT_MODEL__`,e),"agent/channels/eve.ts":WEB_APP_TEMPLATE_FILES[`agent/channels/eve.ts`],"agent/instructions.md":AGENT_INSTRUCTIONS_TEMPLATE}}function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_MODEL__`,t.model).replaceAll(`__EVE_INIT_BYOK_PROVIDER__`,modelProviderSlug(t.model)).replaceAll(`__EVE_INIT_BYOK_ENV_VAR__`,byokProviderEnvVar(t.model)).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_AI_SDK_VERSION__`,t.aiPackageVersion).replaceAll(`__EVE_INIT_CONNECT_VERSION__`,t.connectPackageVersion).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}const BASE_AGENT_TEMPLATE=`import { defineAgent } from "eve";
2
2
 
3
3
  export default defineAgent({
4
4
  model: "__EVE_INIT_MODEL__",
@@ -93,4 +93,4 @@ export default defineAgent({
93
93
  },
94
94
  },
95
95
  });
96
- `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let s=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??s),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let g={appName:basename(s),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.26`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.2.2`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,g),{force:c&&l}),o&&await t.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
96
+ `:BASE_AGENT_TEMPLATE,...SHARED_TEMPLATE_FILES,"package.json":packageJsonTemplate({includeRootOnlyFields:e.includeRootOnlyPackageJsonFields,packageManager:e.packageManager})}}async function assertCanCreateInPlace(e,t){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!t){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldBaseProject(t){let s=resolve(t.targetDirectory??process.cwd(),t.projectName),c=t.projectName===`.`,l=t.overwriteExisting??!1,u=t.byokProvider??!1,d=t.packageManager??`pnpm`,f=resolveEvePackageContract(t.evePackage),p=pinnedNodeEngineMajor(f.nodeEngine),m=resolve(t.workspaceProbeDirectory??s),h=isPackageManagerWorkspaceMember(d,m);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let g={appName:basename(s),model:t.model,eveVersion:f.version,aiPackageVersion:resolveVersionToken(`aiPackageVersion`,t.aiPackageVersion??`^7.0.26`),connectPackageVersion:resolveVersionToken(`connectPackageVersion`,t.connectPackageVersion??`0.4.0`),zodPackageVersion:resolveVersionToken(`zodPackageVersion`,t.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,t.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:p,nodeEngine:p};await mkdir(s,{recursive:!0});for(let[e,i]of Object.entries(templateFiles({byokProvider:u,includeRootOnlyPackageJsonFields:!h,packageManager:d}))){let a=`${s}/${e}`,o=await pathExists(a);await writeTextFile(a,renderTemplate(i,g),{force:c&&l}),o&&await t.onOverwriteFile?.(a)}return await applyPackageManagerWorkspaceConfiguration({packageManager:d,projectRoot:s,workspaceProbeRoot:m,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(d,m,{aiPackageVersion:g.aiPackageVersion,nodeEngineRequirement:f.nodeEngine,onWorkspaceRootMutation:t.onWorkspaceRootMutation}),s}async function isEveProject(e){for(let n of SUPPORTED_AUTHORED_MODULE_FILE_EXTENSIONS)try{return await stat(join(e,`agent`,`agent${n}`)),!0}catch{}return!1}export{CURRENT_DIRECTORY_PROJECT_NAME,DEFAULT_AI_PACKAGE_VERSION,DEFAULT_CONNECT_PACKAGE_VERSION,DEFAULT_EVE_PACKAGE_CONTRACT,DEFAULT_ZOD_PACKAGE_VERSION,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,agentTemplateFiles,byokProviderEnvVar,formatEveDependencySpecifier,isEveProject,modelProviderSlug,resolveEvePackageContract,scaffoldBaseProject};
@@ -4,4 +4,4 @@ import { slackChannel } from "eve/channels/slack";
4
4
  export default slackChannel({
5
5
  credentials: connectSlackCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let i=join(e,n);await pathExists(i)&&t.push(i)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let a=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,c=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,c,a,e.onWorkspaceRootMutation),d=[],f=[],p=[],g=[],_=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?d.push(t):g.push(t)}let v=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation});d.push(...v.filesWritten),g.push(...v.filesSkipped);for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let a=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(a)){g.push(a);continue}let o=await pathExists(a);await writeTextFile(a,renderWebAppTemplate(n,_),{force:!0}),d.push(a),o&&f.push(a)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let y=[...new Set(d)],b=[...new Set(g)].filter(e=>!y.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:y,filesSkipped:b,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let o=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.2.2`),s=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,o),c=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);await writeTextFile(t,buildSlackTemplate(e.slackConnectorUid??`slack/${c}`),{force:e.force});let l={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:s,slackConnectorSlug:c};return n&&(l.filesOverwritten=[t]),l}async function listAuthoredChannels(e){let r=join(e,`agent/channels`),i;try{i=await readdir(r,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let e of i){if(e.isFile()){let n=getSupportedModuleBaseName(e.name);n!==null&&a.push(n);continue}if(e.isDirectory())try{(await readdir(join(r,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(e.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
7
+ `}function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}async function ensureWebVercelJson(e){return await pathExists(e)?`skipped`:(await writeTextFile(e,`${JSON.stringify({$schema:`https://openapi.vercel.sh/vercel.json`},null,2)}\n`,{force:!0}),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let n of WEB_COMPETING_NEXT_CONFIG_PATHS){let i=join(e,n);await pathExists(i)&&t.push(i)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(e){let t=join(e.projectRoot,`package.json`),n=await pathExists(join(e.projectRoot,`app/page.tsx`));if(!e.force&&await isNextJsProject(e.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let a=resolveWebPackageVersions(e.webPackageVersions),o=e.packageManager??`pnpm`,c=resolve(e.workspaceProbeDirectory??e.projectRoot),l=await patchWebPackageJson(e.projectRoot,o,c,a,e.onWorkspaceRootMutation),d=[],f=[],p=[],g=[],_=basename(resolve(e.projectRoot));if(e.configureVercelServices??!0){let t=join(e.projectRoot,`vercel.json`);await ensureWebVercelJson(t)===`written`?d.push(t):g.push(t)}let v=await applyPackageManagerWorkspaceConfiguration({packageManager:o,projectRoot:e.projectRoot,workspaceProbeRoot:c,onWorkspaceRootMutation:e.onWorkspaceRootMutation});d.push(...v.filesWritten),g.push(...v.filesSkipped);for(let[t,n]of Object.entries(WEB_APP_TEMPLATE_FILES)){let a=join(e.projectRoot,t);if(t===`agent/channels/eve.ts`&&!e.force&&await pathExists(a)){g.push(a);continue}let o=await pathExists(a);await writeTextFile(a,renderWebAppTemplate(n,_),{force:!0}),d.push(a),o&&f.push(a)}p.push(...await findCompetingNextConfigFiles(e.projectRoot));let y=[...new Set(d)],b=[...new Set(g)].filter(e=>!y.includes(e)),x={kind:`web`,action:n?`overwritten`:`created`,filesWritten:y,filesSkipped:b,packageJsonUpdated:l.mutations};return f.length>0&&(x.filesOverwritten=f),p.length>0&&(x.competingNextConfigFiles=p),l.nodeEngineOverride!==void 0&&(x.nodeEngineOverride=l.nodeEngineOverride),x}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),n=await pathExists(t);if(!e.force&&n)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let o=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.4.0`),s=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,o),c=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);await writeTextFile(t,buildSlackTemplate(e.slackConnectorUid??`slack/${c}`),{force:e.force});let l={kind:`slack`,action:n?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:s,slackConnectorSlug:c};return n&&(l.filesOverwritten=[t]),l}async function listAuthoredChannels(e){let r=join(e,`agent/channels`),i;try{i=await readdir(r,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let a=[];for(let e of i){if(e.isFile()){let n=getSupportedModuleBaseName(e.name);n!==null&&a.push(n);continue}if(e.isDirectory())try{(await readdir(join(r,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&a.push(e.name)}catch{}}return a.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug,resolveVercelHostFrameworkPreset};
@@ -1,4 +1,4 @@
1
- import{endpointForProtocol}from"../connections/catalog.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{join}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const DEFAULT_CONNECT_PACKAGE_VERSION=`0.2.2`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
1
+ import{endpointForProtocol}from"../connections/catalog.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{patchPackageJson}from"./package-json.js";import{join}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const DEFAULT_CONNECT_PACKAGE_VERSION=`0.4.0`,CONNECT_PACKAGE_NAME=`@vercel/connect`,USER_AUTHORED_CONNECTION_DIR=`agent/connections`;function resolveAuth(e){return e.auth??{kind:`none`}}function envKeysForAuth(e){switch(e.kind){case`bearer-env`:return[e.envVar];case`header`:return e.headers.map(e=>e.envVar);case`connect`:case`none`:return[]}}function authBlock(e){switch(e.kind){case`connect`:return` auth: connect("${e.connector}"),\n`;case`bearer-env`:return` auth: { getToken: async () => ({ token: process.env.${e.envVar}! }) },\n`;case`header`:return` headers: () => ({\n${e.headers.map(e=>` "${e.header}": process.env.${e.envVar}!,`).join(`
2
2
  `)}\n }),\n`;case`none`:return``}}function renderMcpTemplate(e,t,n){return`${n.kind===`connect`?`import { connect } from "@vercel/connect/eve";
3
3
  import { defineMcpClientConnection } from "eve/connections";
4
4
  `:`import { defineMcpClientConnection } from "eve/connections";
@@ -1,4 +1,4 @@
1
- import { createPromptCommandOutput } from "#setup/cli/index.js";
1
+ import { type ChannelSetupLog, createPromptCommandOutput } from "#setup/cli/index.js";
2
2
  import type { Prompter } from "./prompter.js";
3
3
  import { type VercelProjectOperationOptions } from "./vercel-project-api.js";
4
4
  export interface CreatedProjectFrameworkOptions extends VercelProjectOperationOptions {
@@ -18,5 +18,7 @@ export interface CreatedProjectFrameworkOptions extends VercelProjectOperationOp
18
18
  * change. No host framework, an unlinked directory, or an already-correct preset
19
19
  * is a no-op; a Vercel API failure warns rather than aborting the deploy.
20
20
  */
21
- export declare function syncHostFrameworkPreset(prompter: Prompter, projectRoot: string, onOutput: ReturnType<typeof createPromptCommandOutput>, options: VercelProjectOperationOptions): Promise<void>;
21
+ export declare function syncHostFrameworkPreset(prompter: {
22
+ log: Pick<ChannelSetupLog, "info" | "warning">;
23
+ }, projectRoot: string, onOutput: ReturnType<typeof createPromptCommandOutput>, options: VercelProjectOperationOptions): Promise<void>;
22
24
  export declare function ensureCreatedProjectFramework(prompter: Prompter, projectRoot: string, team: string, projectId: string, onOutput: ReturnType<typeof createPromptCommandOutput>, options: CreatedProjectFrameworkOptions): Promise<void>;
@@ -0,0 +1,11 @@
1
+ /** Authoring and distribution roots declared by an extension package. */
2
+ export interface ExtensionPackageRoots {
3
+ /**
4
+ * Authoring root. Optional so published packages can ship `dist` only;
5
+ * `eve extension build` requires it.
6
+ */
7
+ readonly source?: string;
8
+ readonly dist: string;
9
+ }
10
+ /** Parses the strict `package.json#eve.extension` object contract. */
11
+ export declare function parseExtensionPackageRoots(value: unknown): ExtensionPackageRoots | null;
@@ -0,0 +1 @@
1
+ function parseExtensionPackageRoots(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let t=e;return typeof t.dist!=`string`||t.dist.length===0?null:t.source===void 0?{dist:t.dist}:typeof t.source==`string`&&t.source.length>0?{source:t.source,dist:t.dist}:null}export{parseExtensionPackageRoots};
@@ -32,3 +32,7 @@ export declare function parseJsonValue(value: unknown): JsonValue;
32
32
  * value is `undefined` are treated as omitted.
33
33
  */
34
34
  export declare function parseJsonObject(value: unknown): JsonObject;
35
+ /**
36
+ * Narrows an already-normalized {@link JsonValue} to a {@link JsonObject}.
37
+ */
38
+ export declare function isJsonObjectValue(value: JsonValue | undefined): value is JsonObject;
@@ -1 +1 @@
1
- const INVALID_JSON_VALUE_CANDIDATE=Symbol(`invalid-json-value-candidate`);function parseJsonValue(t){let n=normalizeJsonValueCandidate(t);if(n===INVALID_JSON_VALUE_CANDIDATE)throw TypeError(`Expected a JSON-serializable value.`);return n}function parseJsonObject(e){let t=parseJsonValue(e);if(!isJsonObjectValue(t))throw TypeError(`Expected a JSON-serializable object.`);return t}function normalizeJsonValueCandidate(t,n=new WeakSet){if(t===null||typeof t==`boolean`||typeof t==`string`)return t;if(typeof t==`number`)return Number.isFinite(t)?t:INVALID_JSON_VALUE_CANDIDATE;if(Array.isArray(t)){let r=[];for(let i of t){let t=normalizeJsonValueCandidate(i,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r.push(t)}return r}if(typeof t!=`object`||t===void 0||!isPlainObject(t)||n.has(t))return INVALID_JSON_VALUE_CANDIDATE;n.add(t);let r={};for(let[i,a]of Object.entries(t)){if(a===void 0)continue;let t=normalizeJsonValueCandidate(a,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r[i]=t}return n.delete(t),r}function isJsonObjectValue(e){return e!==null&&!Array.isArray(e)&&typeof e==`object`}function isPlainObject(e){let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}export{parseJsonObject,parseJsonValue};
1
+ const INVALID_JSON_VALUE_CANDIDATE=Symbol(`invalid-json-value-candidate`);function parseJsonValue(t){let n=normalizeJsonValueCandidate(t);if(n===INVALID_JSON_VALUE_CANDIDATE)throw TypeError(`Expected a JSON-serializable value.`);return n}function parseJsonObject(e){let t=parseJsonValue(e);if(!isJsonObjectValue(t))throw TypeError(`Expected a JSON-serializable object.`);return t}function normalizeJsonValueCandidate(t,n=new WeakSet){if(t===null||typeof t==`boolean`||typeof t==`string`)return t;if(typeof t==`number`)return Number.isFinite(t)?t:INVALID_JSON_VALUE_CANDIDATE;if(Array.isArray(t)){let r=[];for(let i of t){let t=normalizeJsonValueCandidate(i,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r.push(t)}return r}if(typeof t!=`object`||t===void 0||!isPlainObject(t)||n.has(t))return INVALID_JSON_VALUE_CANDIDATE;n.add(t);let r={};for(let[i,a]of Object.entries(t)){if(a===void 0)continue;let t=normalizeJsonValueCandidate(a,n);if(t===INVALID_JSON_VALUE_CANDIDATE)return INVALID_JSON_VALUE_CANDIDATE;r[i]=t}return n.delete(t),r}function isJsonObjectValue(e){return e!==null&&!Array.isArray(e)&&typeof e==`object`}function isPlainObject(e){let t=Object.getPrototypeOf(e);return t===null||t===Object.prototype}export{isJsonObjectValue,parseJsonObject,parseJsonValue};
@@ -0,0 +1,52 @@
1
+ import type { StandardJSONSchemaV1, StandardSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
+ import { type JsonObject } from "#shared/json.js";
3
+ /**
4
+ * eve-owned schema contract for tool input and output schemas: a Standard
5
+ * Schema validator that can also emit JSON Schema. Zod implements both
6
+ * constituent protocols without exposing Zod through runtime-owned types.
7
+ */
8
+ export type ToolSchema<Input = unknown, Output = Input> = StandardSchemaV1<Input, Output> & StandardJSONSchemaV1<Input, Output>;
9
+ /**
10
+ * Any value accepted at a schema boundary: a live {@link ToolSchema}, a
11
+ * JSON-Schema-capable Standard Schema, or plain JSON Schema data. Plain data
12
+ * is runtime-validated by {@link parseJsonObject} during conversion.
13
+ */
14
+ export type ToolSchemaSource = StandardJSONSchemaV1 | Record<string, unknown>;
15
+ /** `null` and `undefined` pass through every conversion untouched. */
16
+ type SchemaResult<TSource, TResult> = TSource extends null | undefined ? TSource : TResult;
17
+ /**
18
+ * Resolves a source into a live input {@link ToolSchema}. Live schemas pass
19
+ * through unchanged; serialized JSON Schemas are rehydrated into vendored Zod
20
+ * validators. `null` and `undefined` pass through untouched.
21
+ */
22
+ export declare function toInputSchema<T extends ToolSchemaSource | null | undefined>(source: T): SchemaResult<T, ToolSchema>;
23
+ /**
24
+ * Resolves a source into a live output {@link ToolSchema}. Live schemas pass
25
+ * through unchanged; serialized JSON Schemas are rehydrated into vendored Zod
26
+ * validators. `null` and `undefined` pass through untouched.
27
+ */
28
+ export declare function toOutputSchema<T extends ToolSchemaSource | null | undefined>(source: T): SchemaResult<T, ToolSchema>;
29
+ /**
30
+ * Serializes an input schema source into canonical JSON Schema data (no
31
+ * `$schema` key) for compiled artifacts, durable state, and protocol
32
+ * responses. `null` and `undefined` pass through untouched.
33
+ */
34
+ export declare function serializeInputSchema<T extends ToolSchemaSource | null | undefined>(source: T): SchemaResult<T, JsonObject>;
35
+ /**
36
+ * Serializes an output schema source into canonical JSON Schema data (no
37
+ * `$schema` key) for compiled artifacts, durable state, and protocol
38
+ * responses. `null` and `undefined` pass through untouched.
39
+ */
40
+ export declare function serializeOutputSchema<T extends ToolSchemaSource | null | undefined>(source: T): SchemaResult<T, JsonObject>;
41
+ /**
42
+ * Returns whether a value implements the full {@link ToolSchema} contract:
43
+ * Standard Schema validation plus JSON Schema emission.
44
+ */
45
+ export declare function isToolSchema(value: unknown): value is ToolSchema;
46
+ /**
47
+ * Permissive schema lowered onto model-visible tools whose definitions
48
+ * declare no input schema. Accepts any input — an absent schema declares no
49
+ * contract, so rejecting stray properties would only force needless retries.
50
+ */
51
+ export declare const UNSPECIFIED_INPUT_SCHEMA: ToolSchema;
52
+ export {};
@@ -0,0 +1 @@
1
+ import{z}from"#compiled/zod/index.js";import{parseJsonObject}from"#shared/json.js";const rehydratedSchemas={input:new WeakMap,output:new WeakMap};function toInputSchema(e){return toSchema(e,`input`)}function toOutputSchema(e){return toSchema(e,`output`)}function serializeInputSchema(e){return serializeSchema(e,`input`)}function serializeOutputSchema(e){return serializeSchema(e,`output`)}function isToolSchema(e){if(typeof e!=`object`||!e||!(`~standard`in e))return!1;let t=e[`~standard`];if(typeof t!=`object`||!t)return!1;let n=t,r=n.jsonSchema;return typeof n.validate==`function`&&typeof r==`object`&&!!r&&typeof r.input==`function`&&typeof r.output==`function`}const UNSPECIFIED_INPUT_SCHEMA=z.fromJSONSchema({});function toSchema(t,r){if(t==null||isToolSchema(t))return t;let i=rehydratedSchemas[r],a=i.get(t);if(a===void 0){let n=toJsonObject(t,r);a=z.fromJSONSchema(n,{defaultTarget:`draft-7`}),i.set(t,a)}return a}function serializeSchema(e,t){return e==null?e:toJsonObject(e,t)}function toJsonObject(e,n){let{$schema:r,...i}=isStandardJsonSchema(e)?parseJsonObject(e[`~standard`].jsonSchema[n]({target:`draft-07`})):parseJsonObject(e);return i}function isStandardJsonSchema(e){return typeof e==`object`&&!!e&&`~standard`in e}export{UNSPECIFIED_INPUT_SCHEMA,isToolSchema,serializeInputSchema,serializeOutputSchema,toInputSchema,toOutputSchema};
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-6BO9gFVq.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-CQIeqmKc.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-6BO9gFVq.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-CQIeqmKc.js";
2
2
 
3
3
  export { useEveAgent };
@@ -1,3 +1,3 @@
1
- import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-B1MJNRE-.js";
1
+ import { n as defaultMessageReducer, t as useEveAgent } from "../chunks/use-eve-agent-Cy73lgA6.js";
2
2
 
3
3
  export { defaultMessageReducer, useEveAgent };
@@ -1,3 +1,3 @@
1
- import { t as useEveAgent } from "../chunks/use-eve-agent-B1MJNRE-.js";
1
+ import { t as useEveAgent } from "../chunks/use-eve-agent-Cy73lgA6.js";
2
2
 
3
3
  export { useEveAgent };
@@ -87,6 +87,12 @@ The follow-up reuses the same durable session: same history, same state.
87
87
 
88
88
  If the session is waiting on a human-in-the-loop approval, a matching text reply such as `approve` or `deny` answers the approval. Other follow-up text is held until the approval is answered, so an unrelated message does not implicitly deny the pending tool call.
89
89
 
90
+ If the session is waiting on `ask_question`, a follow-up message clears that pending request before the model continues. An exact option match or permitted freeform response answers the question; any other message marks the question unanswered and starts the follow-up turn.
91
+
92
+ A response is stale when its request is no longer pending: the question or approval was already answered, cleared by a follow-up message, or cancelled. eve delivers a stale response to the model as a new user message, and the model decides whether the old selection still matters. A stale approval never authorizes the earlier tool call; the model must request the action and approval again if they are still needed.
93
+
94
+ Responses match pending requests by request ID, so a response to an older request stays a plain user message even while a different question or approval is pending. Like any follow-up message, a stale response clears a pending question and is held while an approval is pending.
95
+
90
96
  For deterministic ordering, send one follow-up at a time and wait for the next `session.waiting` event before sending another message to the same session. See [message delivery and queueing](./execution-model-and-durability#message-delivery-and-queueing) for the current runtime contract.
91
97
 
92
98
  ## Cancel the in-flight turn
@@ -71,15 +71,21 @@ Config is bound once when the consumer mounts the extension and stays constant f
71
71
 
72
72
  ## Publishing
73
73
 
74
- Point `eve.extension` at the source directory and run `eve extension build` (wired to `build`/`prepare`):
74
+ Declare separate authoring and distribution roots and run `eve extension build` (wired to `build`/`prepare`):
75
75
 
76
76
  ```jsonc title="package.json"
77
77
  {
78
78
  "name": "@acme/crm",
79
79
  "type": "module",
80
- "eve": { "extension": "./extension" },
81
- "files": ["extension", "dist"],
82
- "peerDependencies": { "eve": "^x" },
80
+ "eve": {
81
+ "extension": {
82
+ "source": "./extension",
83
+ "dist": "./dist/extension",
84
+ },
85
+ },
86
+ "files": ["dist"],
87
+ "peerDependencies": { "eve": "*" },
88
+ "devDependencies": { "eve": "^x", "typescript": "^x" },
83
89
  "dependencies": { "zod": "^3" },
84
90
  "scripts": { "build": "eve extension build", "prepare": "eve extension build" },
85
91
  }
@@ -100,11 +106,21 @@ Author the source with `moduleResolution: "bundler"` — eve compiles it, so rel
100
106
  }
101
107
  ```
102
108
 
103
- `eve extension build` compiles the package's entry points to plain JavaScript with type declarations the mount factory (`dist/index.mjs`) and the tool re-exports overrides use (`dist/tools`) and fills the `exports` map so you never hand-list it. Compiling is what lets an installed extension load directly; local and workspace packages also work without publishing.
109
+ `eve extension build` transforms every JavaScript or TypeScript module into an agent-shaped `dist/extension` tree, copies skill packages and their assets, emits type declarations, and writes `dist/extension/_manifest.json`. The generated package entrypoints (`dist/index.mjs` and `dist/tools/index.mjs`) re-export those same dist modules, and the build fills the `exports` map so you never hand-list it. The published package therefore needs `dist/`, not the author's original TypeScript. Consumers read only `eve.extension.dist`, so a published package may omit `eve.extension.source`; keep `source` declared wherever `eve extension build` runs.
110
+
111
+ The build uses the package `tsconfig.json` when it emits declarations. Its `include` must cover every JavaScript or TypeScript module in the extension source (and JavaScript modules require `allowJs`); the build fails before publishing if any distributed module would be missing its declaration.
112
+
113
+ The manifest contains only its format, the diagnostic eve build version, and the versions of extension capabilities this package actually uses. It does not contain compiled tools, schemas, names, or executable definitions; the consuming eve still discovers and normalizes the agent-shaped dist tree.
114
+
115
+ ### Workspace development
116
+
117
+ During local development, `eve dev` automatically rebuilds mounted workspace extensions when their source changes.
104
118
 
105
119
  ### Dependencies
106
120
 
107
- `eve` is a **peer** dependency: one eve lives in the consuming app and the extension's `eve/*` imports resolve to it. Declare the eve versions your extension supports as the peer range (`"eve": "^1"`) eve enforces it when the extension is mounted, failing the build with a clear error if the app's eve is out of range, rather than surfacing a confusing compile break. Everything else the extension imports (SDKs, `zod`, …) goes in `dependencies`; each extension resolves its own versions. The consumer recompiles the extension's contributions from source, so `files` must ship both `extension/` (that source) and `dist/` (the compiled entry points).
121
+ `eve` is a required wildcard **peer** dependency: one eve lives in the consuming app and the extension's `eve/*` imports resolve to it. The extension's concrete eve version belongs in `devDependencies` for authoring types and build tooling. npm peer semver does not decide extension compatibility; eve validates the generated per-capability requirements. Do not mark the eve peer optional and do not add eve to regular `dependencies`.
122
+
123
+ Everything else the extension imports at execution time (SDKs, `zod`, …) goes in `dependencies`; each extension resolves its own versions. Build-only and test-only packages go in `devDependencies`.
108
124
 
109
125
  Those deps resolve from `node_modules` under `eve dev`/`eve eval` and are bundled into the deployable by the consuming agent's `eve build`. A dependency that can't be bundled (a native addon) must be listed in the **consuming agent's** `build.externalDependencies` — an extension can't declare build config, so note it in your README.
110
126
 
@@ -47,7 +47,7 @@ After scaffolding, a human terminal usually continues into `eve dev` (or a codin
47
47
 
48
48
  ## `eve extension`
49
49
 
50
- Commands for reusable [extension](/docs/extensions) packages. An extension is identified by `package.json#eve.extension` (for example `"eve": { "extension": "./extension" }`).
50
+ Commands for reusable [extension](/docs/extensions) packages. An extension declares distinct authoring and distribution roots in `package.json#eve.extension` (for example `"eve": { "extension": { "source": "./extension", "dist": "./dist/extension" } }`).
51
51
 
52
52
  ### `eve extension init`
53
53
 
@@ -73,7 +73,7 @@ See [Extensions](/docs/extensions) for authoring and mount details.
73
73
  eve extension build
74
74
  ```
75
75
 
76
- Builds the current package as an extension: compiles the mount factory and tool re-exports into `dist/`, and fills the package `exports` map. Requires `package.json#eve.extension`.
76
+ Builds the complete agent-shaped extension tree into its configured dist root, emits declarations and compatibility metadata, and fills the package `exports` map. The original TypeScript source is not required in the published package.
77
77
 
78
78
  ## `eve info`
79
79
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve",
3
- "version": "0.24.6",
3
+ "version": "0.25.0",
4
4
  "private": false,
5
5
  "description": "Filesystem-first framework for durable backend AI agents that run anywhere.",
6
6
  "keywords": [
@@ -1 +0,0 @@
1
- export { normalizeJsonSchemaDefinition } from "#shared/json-schema.js";
@@ -1 +0,0 @@
1
- import{normalizeJsonSchemaDefinition}from"#shared/json-schema.js";export{normalizeJsonSchemaDefinition};
@@ -1,26 +0,0 @@
1
- import type { Prompter } from "../prompter.js";
2
- import { type SetupState } from "../state.js";
3
- import type { SetupBox } from "../step.js";
4
- import { syncHostFrameworkPreset } from "../vercel-project-framework.js";
5
- /** Injected for tests; defaults to the real framework-preset reconciliation. */
6
- export interface ReconcileHostFrameworkPresetDeps {
7
- syncHostFrameworkPreset: typeof syncHostFrameworkPreset;
8
- }
9
- export interface ReconcileHostFrameworkPresetOptions {
10
- /** Streams reconciliation progress and the applied-change note. */
11
- prompter: Prompter;
12
- deps?: ReconcileHostFrameworkPresetDeps;
13
- }
14
- /**
15
- * Aligns an already-linked Vercel project's Framework Preset with a newly-added
16
- * web (Next.js) channel before the deploy box runs. A project created as a
17
- * standalone agent keeps the `eve` preset, which would build the agent instead
18
- * of the host app; the command already deploys on the user's behalf, so this
19
- * corrects the preset directly (no confirmation) and notes the change.
20
- *
21
- * Runs only for an already-linked project — an unlinked directory links later
22
- * inside the deploy box, where a fresh `vercel link` detects the framework. All
23
- * effects live in {@link syncHostFrameworkPreset}, a no-op when the preset
24
- * already matches.
25
- */
26
- export declare function reconcileHostFrameworkPreset(options: ReconcileHostFrameworkPresetOptions): SetupBox<SetupState, null, null>;
@@ -1 +0,0 @@
1
- import{isProjectResolved}from"../project-resolution.js";import{requireProjectPath}from"../state.js";import{syncHostFrameworkPreset}from"../vercel-project-framework.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function reconcileHostFrameworkPreset(r){let i=r.deps??{syncHostFrameworkPreset};return{id:`reconcile-host-framework-preset`,shouldRun(t){return t.deploymentPending&&t.channelSelection.includes(`web`)&&isProjectResolved(t.project)},async gather(){return null},async perform({state:e,signal:n}){let a=requireProjectPath(e),o=createPromptCommandOutput(r.prompter.log);return await i.syncHostFrameworkPreset(r.prompter,a,o,{signal:n}),null},apply(e){return e}}}export{reconcileHostFrameworkPreset};
@@ -1,9 +0,0 @@
1
- import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index.js";
2
- import { type JsonObject } from "#shared/json.js";
3
- type JsonSchemaDirection = "input" | "output";
4
- /**
5
- * Normalizes one Standard Schema or JSON Schema definition into plain JSON
6
- * Schema data that can cross eve runtime and client boundaries.
7
- */
8
- export declare function normalizeJsonSchemaDefinition(value: StandardJSONSchemaV1 | Record<string, unknown> | unknown, direction?: JsonSchemaDirection): JsonObject;
9
- export {};
@@ -1 +0,0 @@
1
- import{parseJsonObject}from"#shared/json.js";function normalizeJsonSchemaDefinition(t,n=`input`){return isStandardSchema(t)?parseJsonObject(t[`~standard`].jsonSchema[n]({target:`draft-07`})):parseJsonObject(t)}function isStandardSchema(e){return typeof e==`object`&&!!e&&`~standard`in e}export{normalizeJsonSchemaDefinition};