eve 0.57.0 → 0.58.1

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 (148) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +1 -0
  3. package/dist/src/channel/activity-sink.js +1 -1
  4. package/dist/src/channel/session-callback.js +1 -1
  5. package/dist/src/chunks/{use-eve-agent-C2APNCdP.js → use-eve-agent-CxWcZCsU.js} +22 -3
  6. package/dist/src/chunks/{use-eve-agent-D0YnDLi_.js → use-eve-agent-X0asmJg-.js} +22 -3
  7. package/dist/src/cli/commands/integration-setup.js +1 -1
  8. package/dist/src/cli/dev/command.d.ts +30 -0
  9. package/dist/src/cli/dev/command.js +3 -0
  10. package/dist/src/cli/dev/tui/setup-commands.js +1 -1
  11. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  12. package/dist/src/cli/dev/tui/setup-panel.js +2 -1
  13. package/dist/src/cli/dev/tui/terminal-renderer.js +1 -1
  14. package/dist/src/cli/dev/tui/tui.js +1 -1
  15. package/dist/src/cli/option-parsers.js +1 -1
  16. package/dist/src/cli/run.js +1 -3
  17. package/dist/src/client/agent-host.js +1 -1
  18. package/dist/src/client/url.js +1 -1
  19. package/dist/src/compiled/.vendor-stamp.json +2 -2
  20. package/dist/src/compiled/@ai-sdk/code-mode/index.d.ts +18 -2
  21. package/dist/src/compiled/@ai-sdk/code-mode/index.js +16 -14
  22. package/dist/src/compiler/extension-compatibility.d.ts +12 -12
  23. package/dist/src/compiler/extension-compatibility.js +1 -1
  24. package/dist/src/context/dynamic-model-lifecycle.d.ts +1 -0
  25. package/dist/src/context/dynamic-model-lifecycle.js +1 -1
  26. package/dist/src/context/keys.d.ts +11 -3
  27. package/dist/src/context/memory-lifecycle.d.ts +2 -5
  28. package/dist/src/context/memory-lifecycle.js +1 -1
  29. package/dist/src/dynamic/definition.d.ts +2 -0
  30. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  31. package/dist/src/execution/node-step.js +1 -1
  32. package/dist/src/execution/session/event-sink.js +1 -1
  33. package/dist/src/execution/session/turn-step.js +1 -1
  34. package/dist/src/execution/tools/sleep-workflow.js +1 -1
  35. package/dist/src/execution/workflow-callback-url.js +1 -1
  36. package/dist/src/experimental/evaluate/auto-model.d.ts +16 -0
  37. package/dist/src/experimental/evaluate/auto-model.js +2 -0
  38. package/dist/src/harness/emission.d.ts +1 -1
  39. package/dist/src/harness/emission.js +1 -1
  40. package/dist/src/harness/messages.d.ts +1 -0
  41. package/dist/src/harness/messages.js +1 -1
  42. package/dist/src/harness/tool-loop.js +2 -2
  43. package/dist/src/internal/application/package.js +1 -1
  44. package/dist/src/internal/authored-definition/core.js +1 -1
  45. package/dist/src/internal/model-auth/transport.d.ts +3 -1
  46. package/dist/src/internal/model-auth/transport.js +1 -1
  47. package/dist/src/internal/nitro/host/normalize-vercel-service-crons.js +1 -1
  48. package/dist/src/internal/nitro/host/start-development-server.js +1 -1
  49. package/dist/src/internal/runtime-model.d.ts +3 -0
  50. package/dist/src/internal/runtime-model.js +1 -1
  51. package/dist/src/internal/vercel/build-agent-workspace.js +1 -1
  52. package/dist/src/internal/vercel/eve-service-contribution.d.ts +1 -0
  53. package/dist/src/internal/vercel/eve-service-contribution.js +1 -1
  54. package/dist/src/internal/vercel/vercel-services-config.d.ts +1 -0
  55. package/dist/src/internal/vercel/vercel-services-config.js +1 -1
  56. package/dist/src/public/definitions/workspace-agent.js +1 -1
  57. package/dist/src/public/experimental/evaluate/index.d.ts +1 -0
  58. package/dist/src/public/experimental/evaluate/index.js +1 -0
  59. package/dist/src/public/models/anthropic/index.js +1 -1
  60. package/dist/src/public/next/index.d.ts +1 -1
  61. package/dist/src/public/next/index.js +1 -1
  62. package/dist/src/public/vercel/index.d.ts +1 -1
  63. package/dist/src/public/vercel/index.js +1 -1
  64. package/dist/src/react/use-eve-agent.d.ts +1 -1
  65. package/dist/src/runtime/agent/bootstrap.d.ts +4 -2
  66. package/dist/src/runtime/agent/resolve-model.d.ts +0 -1
  67. package/dist/src/runtime/agent/resolve-model.js +1 -1
  68. package/dist/src/self-modification/agent.d.ts +6 -18
  69. package/dist/src/self-modification/agent.js +1 -1
  70. package/dist/src/self-modification/config.d.ts +17 -12
  71. package/dist/src/self-modification/config.js +1 -1
  72. package/dist/src/self-modification/credentials.d.ts +1 -10
  73. package/dist/src/self-modification/credentials.js +1 -1
  74. package/dist/src/self-modification/extension/extension.d.ts +7 -13
  75. package/dist/src/self-modification/extension/extension.js +1 -1
  76. package/dist/src/self-modification/github-publisher.d.ts +1 -1
  77. package/dist/src/self-modification/mode.js +1 -1
  78. package/dist/src/self-modification/setup.d.ts +1 -1
  79. package/dist/src/self-modification/setup.js +23 -4
  80. package/dist/src/setup/flows/model-login-connection.js +1 -1
  81. package/dist/src/setup/flows/registry.d.ts +3 -0
  82. package/dist/src/setup/flows/registry.js +2 -2
  83. package/dist/src/setup/integrations/discord/setup.js +1 -1
  84. package/dist/src/setup/integrations/file-memory/setup.js +2 -2
  85. package/dist/src/setup/integrations/github/setup.js +1 -1
  86. package/dist/src/setup/integrations/linear/setup.js +1 -1
  87. package/dist/src/setup/integrations/linq/setup.js +1 -1
  88. package/dist/src/setup/integrations/photon/setup-flow.js +1 -1
  89. package/dist/src/setup/integrations/registry.js +1 -1
  90. package/dist/src/setup/integrations/runner.d.ts +3 -0
  91. package/dist/src/setup/integrations/runner.js +1 -1
  92. package/dist/src/setup/integrations/self-modification/setup.d.ts +7 -1
  93. package/dist/src/setup/integrations/self-modification/setup.js +1 -1
  94. package/dist/src/setup/integrations/shared/scaffold.js +1 -1
  95. package/dist/src/setup/integrations/shared/ui.d.ts +1 -0
  96. package/dist/src/setup/integrations/shared/ui.js +1 -1
  97. package/dist/src/setup/integrations/shopify/setup.js +1 -1
  98. package/dist/src/setup/integrations/slack/setup.js +1 -1
  99. package/dist/src/setup/integrations/teams/connect.d.ts +22 -0
  100. package/dist/src/setup/integrations/teams/connect.js +1 -0
  101. package/dist/src/setup/integrations/teams/setup.d.ts +21 -0
  102. package/dist/src/setup/integrations/teams/setup.js +7 -0
  103. package/dist/src/setup/integrations/types.d.ts +6 -0
  104. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  105. package/dist/src/setup/scaffold/create/project.d.ts +1 -1
  106. package/dist/src/setup/scaffold/create/project.js +2 -2
  107. package/dist/src/setup/scaffold/update/channels.d.ts +2 -0
  108. package/dist/src/setup/scaffold/update/channels.js +2 -2
  109. package/dist/src/setup/scaffold/update/connections.js +3 -3
  110. package/dist/src/setup/scaffold/update/web-options.js +1 -1
  111. package/dist/src/setup/scaffold/version-tokens.d.ts +2 -1
  112. package/dist/src/setup/scaffold/version-tokens.js +1 -1
  113. package/dist/src/shared/agent-definition.d.ts +2 -0
  114. package/dist/src/shared/eve-route-path.d.ts +4 -0
  115. package/dist/src/shared/eve-route-path.js +1 -0
  116. package/dist/src/shared/public-route-prefix.d.ts +1 -1
  117. package/dist/src/subagents/remote-route-url.js +1 -1
  118. package/dist/src/svelte/index.js +1 -1
  119. package/dist/src/svelte/use-eve-agent.d.ts +1 -1
  120. package/dist/src/svelte/use-eve-agent.js +1 -1
  121. package/dist/src/vue/index.js +1 -1
  122. package/dist/src/vue/use-eve-agent.d.ts +1 -1
  123. package/dist/src/vue/use-eve-agent.js +1 -1
  124. package/docs/README.md +45 -40
  125. package/docs/agent-config.md +8 -1
  126. package/docs/channels/teams.mdx +29 -0
  127. package/docs/concepts/meta.json +1 -0
  128. package/docs/concepts/project-structure.mdx +111 -0
  129. package/docs/getting-started.mdx +18 -106
  130. package/docs/guides/auth-and-route-protection.md +8 -4
  131. package/docs/guides/deployment/self-hosting.md +40 -0
  132. package/docs/guides/deployment/vercel.mdx +26 -23
  133. package/docs/guides/dynamic-capabilities.md +4 -0
  134. package/docs/guides/evaluate.md +118 -0
  135. package/docs/guides/frontend/nextjs.mdx +61 -20
  136. package/docs/guides/frontend/overview.mdx +3 -3
  137. package/docs/guides/instrumentation/otel.mdx +7 -2
  138. package/docs/guides/instrumentation/providers.mdx +2 -3
  139. package/docs/guides/remote-agents.md +5 -1
  140. package/docs/install-integrations.mdx +1 -1
  141. package/docs/meta.json +1 -0
  142. package/docs/reference/agent-files.md +104 -0
  143. package/docs/reference/cli.md +2 -2
  144. package/docs/reference/meta.json +1 -1
  145. package/docs/reference/typescript-api.md +2 -1
  146. package/docs/schedules.mdx +1 -1
  147. package/docs/subagents/index.mdx +2 -2
  148. package/package.json +9 -4
@@ -2,7 +2,7 @@ import type { HarnessModelMessage } from "#harness/messages.js";
2
2
  import type { PreparedRuntimeTool } from "#runtime/sessions/turn.js";
3
3
  import type { ResolvedAgent, ResolvedAgentDefinition } from "#runtime/types.js";
4
4
  import type { WorkspaceRuntimeSpec } from "#runtime/workspace/types.js";
5
- import type { InternalAgentModelDefinition } from "#shared/agent-definition.js";
5
+ import type { AgentReasoningDefinition, InternalAgentModelDefinition } from "#shared/agent-definition.js";
6
6
  import type { ModuleSourceRef } from "#shared/source-ref.js";
7
7
  import type { AvailableSkillDescription } from "#execution/skills/instructions.js";
8
8
  /**
@@ -13,7 +13,9 @@ export declare const BOOTSTRAP_RUNTIME_MODEL_ID = "eve-bootstrap-model";
13
13
  /**
14
14
  * Runtime-owned model identifier prepared for one harness turn.
15
15
  */
16
- export type RuntimeModelReference = Readonly<InternalAgentModelDefinition>;
16
+ export type RuntimeModelReference = Readonly<InternalAgentModelDefinition & {
17
+ reasoning?: AgentReasoningDefinition;
18
+ }>;
17
19
  /**
18
20
  * Runtime-owned reference to a dynamic model resolver authored in `agent.ts`.
19
21
  */
@@ -30,4 +30,3 @@ export declare function resolveRuntimeModelSelection(input: {
30
30
  readonly selection: PublicAgentDynamicModelResult;
31
31
  readonly state: ContextAccessor;
32
32
  }): Promise<ResolvedRuntimeModelSelection>;
33
- export declare function isRuntimeLanguageModel(value: unknown): value is LanguageModel;
@@ -1 +1 @@
1
- import{RuntimeModelMetadataCacheKey}from"#context/keys.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{localGatewayModel}from"#internal/model-auth/transport.js";import{resolveBootstrapRuntimeModel}from"#runtime/agent/bootstrap-model.js";import{resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels}from"#runtime/agent/mock-model-adapter.js";import{createRuntimeModelCatalog}from"#runtime/agent/model-catalog.js";async function resolveRuntimeModelReference(e,t){let n=resolveBootstrapRuntimeModel(e);if(n!==null)return n;let r=resolveMockAuthoredRuntimeModel(e);return r===null?isSourceBackedRuntimeModelReference(e)?await loadSourceBackedRuntimeModelReference(e,t):localGatewayModel(e.id)??e.id:r}async function loadSourceBackedRuntimeModelReference(e,t){if(t===void 0)throw Error(`Expected a compiled module-map scope to resolve the authored runtime model "${e.id}".`);let n=await loadResolvedModuleExport({definition:e.source,kindLabel:`runtime model "${e.id}"`,moduleMap:t.moduleMap,nodeId:t.nodeId}),r=normalizeAgentDefinition(n,`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to match the public eve shape.`).model;if(r===void 0)throw Error(`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to provide a runtime model.`);if(isDynamicModelDefinition(r))throw Error(`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to provide a static runtime model.`);return r}function isSourceBackedRuntimeModelReference(e){return e.source!==void 0}async function loadDynamicRuntimeModelDefinition(e){let t=await loadResolvedModuleExport({definition:e.dynamicModel,kindLabel:`dynamic runtime model`,moduleMap:e.scope.moduleMap,nodeId:e.scope.nodeId}),n=normalizeAgentDefinition(t,`Expected the authored agent config export "${e.dynamicModel.exportName??`default`}" from "${e.dynamicModel.logicalPath}" to match the public eve shape.`).model;if(!isDynamicModelDefinition(n))throw Error(`Expected the authored agent config export "${e.dynamicModel.exportName??`default`}" from "${e.dynamicModel.logicalPath}" to provide a dynamic model definition.`);return n}async function resolveRuntimeModelSelection(e){if(e.selection===null||e.selection===void 0)throw Error(`Dynamic model resolver returned no model. Every matching dynamic model handler must return a concrete model selection.`);let t=normalizeDynamicModelSelection(e.selection);validateDynamicModelSelection(t);let n=t.modelOptions?.providerOptions===void 0?void 0:parseProviderOptionsRecord(t.modelOptions.providerOptions),r=t.model,i=e.catalog??runtimeModelCatalogForState(e.state);if(typeof r==`string`){let a=formatLanguageModelGatewayId(r),o=await resolveSelectionMetadata({cacheKey:`gateway:${a}`,catalog:i,contextWindowTokens:t.modelContextWindowTokens,load:e=>e.getByGatewayId(a),modelLabel:a,state:e.state});return{reference:{id:o.resolvedModelId,contextWindowTokens:o.contextWindowTokens,maxOutputTokens:o.maxOutputTokens,providerOptions:n}}}if(validateRuntimeLanguageModel(r),e.durability===`durable`)throw Error(`Dynamic model selection returned a provider object, but durable model selections must be serializable. Return a model id string, or use a "step.started" model resolver.`);let a=formatLanguageModelGatewayId(r),o=r.provider.split(`.`)[0],s=await resolveSelectionMetadata({cacheKey:o===`gateway`?`gateway:${r.modelId}`:`provider:${r.provider}:${r.modelId}`,catalog:i,contextWindowTokens:t.modelContextWindowTokens,load:e=>o===`gateway`?e.getByGatewayId(r.modelId):e.getByProviderModelId(r.provider,r.modelId),modelLabel:a,state:e.state});return{model:r,reference:{id:s.resolvedModelId,contextWindowTokens:s.contextWindowTokens,maxOutputTokens:s.maxOutputTokens,providerOptions:n}}}const runtimeModelCatalogsByState=new WeakMap;function runtimeModelCatalogForState(e){let t=runtimeModelCatalogsByState.get(e);if(t!==void 0)return t;let n=createRuntimeModelCatalog();return runtimeModelCatalogsByState.set(e,n),n}async function resolveSelectionMetadata(e){if(e.contextWindowTokens!==void 0)return{contextWindowTokens:e.contextWindowTokens,resolvedModelId:e.modelLabel};let t=Date.now(),n=e.state.get(RuntimeModelMetadataCacheKey)?.[e.cacheKey];if(n!==void 0&&n.expiresAt>t)return n;let r=await e.load(e.catalog);if(r===null)throw Error(`Cannot select model "${e.modelLabel}" because AI Gateway did not provide context window metadata. Return modelContextWindowTokens with this selection for an unlisted or custom model.`);let i={...r,expiresAt:t+864e5};return e.state.set(RuntimeModelMetadataCacheKey,n=>({...Object.fromEntries(Object.entries(n??{}).filter(([,e])=>e.expiresAt>t)),[e.cacheKey]:i})),i}const DYNAMIC_MODEL_SELECTION_KEYS=new Set([`model`,`modelContextWindowTokens`,`modelOptions`]);function validateDynamicModelSelection(e){let t=Object.keys(e).filter(e=>!DYNAMIC_MODEL_SELECTION_KEYS.has(e));if(t.length>0)throw Error(`Dynamic model resolver returned a selection with unknown key(s): ${t.join(`, `)}. Expected { model, modelContextWindowTokens?, modelOptions? }.`);let n=e.modelContextWindowTokens;if(n!==void 0&&(!Number.isInteger(n)||n<=0))throw Error(`Dynamic model resolver returned an invalid modelContextWindowTokens value. Expected a positive integer.`);if(typeof e.model==`string`&&e.model.trim()===``)throw Error(`Dynamic model resolver returned an empty model id.`)}function normalizeDynamicModelSelection(e){return isModelSelectionDefinition(e)?e:{model:e}}function isModelSelectionDefinition(e){return typeof e==`object`&&!!e&&`model`in e&&!isRuntimeLanguageModel(e)}function validateRuntimeLanguageModel(e){if(!isRuntimeLanguageModel(e))throw Error(`Dynamic model resolver returned an invalid model. Return an AI Gateway model id string, an AI SDK language model, or { model, modelContextWindowTokens?, modelOptions? }.`)}function isRuntimeLanguageModel(e){if(typeof e!=`object`||!e)return!1;let t=e;return(t.specificationVersion===`v2`||t.specificationVersion===`v3`||t.specificationVersion===`v4`)&&typeof t.provider==`string`&&typeof t.modelId==`string`&&typeof t.doGenerate==`function`&&typeof t.doStream==`function`}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,r]of Object.entries(e))t[n]=parseJsonObject(r);return t}export{isRuntimeLanguageModel,loadDynamicRuntimeModelDefinition,resolveRuntimeModelReference,resolveRuntimeModelSelection,shouldMockAuthoredRuntimeModels};
1
+ import{RuntimeModelMetadataCacheKey}from"#context/keys.js";import{isDynamicModelDefinition}from"#shared/agent-definition.js";import{normalizeAgentDefinition}from"#internal/authored-definition/core.js";import{formatLanguageModelGatewayId,isAgentReasoningDefinition,isRuntimeLanguageModel}from"#internal/runtime-model.js";import{parseJsonObject}from"#shared/json.js";import{localGatewayModel}from"#internal/model-auth/transport.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{resolveBootstrapRuntimeModel}from"#runtime/agent/bootstrap-model.js";import{resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels}from"#runtime/agent/mock-model-adapter.js";import{createRuntimeModelCatalog}from"#runtime/agent/model-catalog.js";async function resolveRuntimeModelReference(e,t){let n=resolveBootstrapRuntimeModel(e);if(n!==null)return n;let r=resolveMockAuthoredRuntimeModel(e);return r===null?isSourceBackedRuntimeModelReference(e)?await loadSourceBackedRuntimeModelReference(e,t):localGatewayModel(e.id)??e.id:r}async function loadSourceBackedRuntimeModelReference(e,t){if(t===void 0)throw Error(`Expected a compiled module-map scope to resolve the authored runtime model "${e.id}".`);let n=await loadResolvedModuleExport({definition:e.source,kindLabel:`runtime model "${e.id}"`,moduleMap:t.moduleMap,nodeId:t.nodeId}),r=normalizeAgentDefinition(n,`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to match the public eve shape.`).model;if(r===void 0)throw Error(`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to provide a runtime model.`);if(isDynamicModelDefinition(r))throw Error(`Expected the authored agent config export "${e.source.exportName??`default`}" from "${e.source.logicalPath}" to provide a static runtime model.`);return r}function isSourceBackedRuntimeModelReference(e){return e.source!==void 0}async function loadDynamicRuntimeModelDefinition(e){let t=await loadResolvedModuleExport({definition:e.dynamicModel,kindLabel:`dynamic runtime model`,moduleMap:e.scope.moduleMap,nodeId:e.scope.nodeId}),n=normalizeAgentDefinition(t,`Expected the authored agent config export "${e.dynamicModel.exportName??`default`}" from "${e.dynamicModel.logicalPath}" to match the public eve shape.`).model;if(!isDynamicModelDefinition(n))throw Error(`Expected the authored agent config export "${e.dynamicModel.exportName??`default`}" from "${e.dynamicModel.logicalPath}" to provide a dynamic model definition.`);return n}async function resolveRuntimeModelSelection(e){if(e.selection===null||e.selection===void 0)throw Error(`Dynamic model resolver returned no model. Every matching dynamic model handler must return a concrete model selection.`);let t=normalizeDynamicModelSelection(e.selection);validateDynamicModelSelection(t);let n=t.modelOptions?.providerOptions===void 0?void 0:parseProviderOptionsRecord(t.modelOptions.providerOptions),r=t.model,i=e.catalog??runtimeModelCatalogForState(e.state);if(typeof r==`string`){let a=formatLanguageModelGatewayId(r),o=await resolveSelectionMetadata({cacheKey:`gateway:${a}`,catalog:i,contextWindowTokens:t.modelContextWindowTokens,load:e=>e.getByGatewayId(a),modelLabel:a,state:e.state});return{reference:{id:o.resolvedModelId,contextWindowTokens:o.contextWindowTokens,maxOutputTokens:o.maxOutputTokens,providerOptions:n,reasoning:t.reasoning}}}if(validateRuntimeLanguageModel(r),e.durability===`durable`)throw Error(`Dynamic model selection returned a provider object, but durable model selections must be serializable. Return a model id string, or use a "step.started" model resolver.`);let a=formatLanguageModelGatewayId(r),o=r.provider.split(`.`)[0],s=await resolveSelectionMetadata({cacheKey:o===`gateway`?`gateway:${r.modelId}`:`provider:${r.provider}:${r.modelId}`,catalog:i,contextWindowTokens:t.modelContextWindowTokens,load:e=>o===`gateway`?e.getByGatewayId(r.modelId):e.getByProviderModelId(r.provider,r.modelId),modelLabel:a,state:e.state});return{model:r,reference:{id:s.resolvedModelId,contextWindowTokens:s.contextWindowTokens,maxOutputTokens:s.maxOutputTokens,providerOptions:n,reasoning:t.reasoning}}}const runtimeModelCatalogsByState=new WeakMap;function runtimeModelCatalogForState(e){let t=runtimeModelCatalogsByState.get(e);if(t!==void 0)return t;let n=createRuntimeModelCatalog();return runtimeModelCatalogsByState.set(e,n),n}async function resolveSelectionMetadata(e){if(e.contextWindowTokens!==void 0)return{contextWindowTokens:e.contextWindowTokens,resolvedModelId:e.modelLabel};let t=Date.now(),n=e.state.get(RuntimeModelMetadataCacheKey)?.[e.cacheKey];if(n!==void 0&&n.expiresAt>t)return n;let r=await e.load(e.catalog);if(r===null)throw Error(`Cannot select model "${e.modelLabel}" because AI Gateway did not provide context window metadata. Return modelContextWindowTokens with this selection for an unlisted or custom model.`);let i={...r,expiresAt:t+864e5};return e.state.set(RuntimeModelMetadataCacheKey,n=>({...Object.fromEntries(Object.entries(n??{}).filter(([,e])=>e.expiresAt>t)),[e.cacheKey]:i})),i}const DYNAMIC_MODEL_SELECTION_KEYS=new Set([`model`,`modelContextWindowTokens`,`modelOptions`,`reasoning`]);function validateDynamicModelSelection(e){let t=Object.keys(e).filter(e=>!DYNAMIC_MODEL_SELECTION_KEYS.has(e));if(t.length>0)throw Error(`Dynamic model resolver returned a selection with unknown key(s): ${t.join(`, `)}. Expected { model, reasoning?, modelContextWindowTokens?, modelOptions? }.`);if(e.reasoning!==void 0&&!isAgentReasoningDefinition(e.reasoning))throw Error(`Dynamic model resolver returned an invalid reasoning effort. Expected provider-default, none, minimal, low, medium, high, or xhigh.`);let n=e.modelContextWindowTokens;if(n!==void 0&&(!Number.isInteger(n)||n<=0))throw Error(`Dynamic model resolver returned an invalid modelContextWindowTokens value. Expected a positive integer.`);if(typeof e.model==`string`&&e.model.trim()===``)throw Error(`Dynamic model resolver returned an empty model id.`)}function normalizeDynamicModelSelection(e){return isModelSelectionDefinition(e)?e:{model:e}}function isModelSelectionDefinition(e){return typeof e==`object`&&!!e&&`model`in e&&!isRuntimeLanguageModel(e)}function validateRuntimeLanguageModel(e){if(!isRuntimeLanguageModel(e))throw Error(`Dynamic model resolver returned an invalid model. Return an AI Gateway model id string, an AI SDK language model, or { model, modelContextWindowTokens?, modelOptions? }.`)}function parseProviderOptionsRecord(e){if(e===void 0)return;let t={};for(let[n,r]of Object.entries(e))t[n]=parseJsonObject(r);return t}export{loadDynamicRuntimeModelDefinition,resolveRuntimeModelReference,resolveRuntimeModelSelection,shouldMockAuthoredRuntimeModels};
@@ -1,16 +1,12 @@
1
- import { type AgentReasoningDefinition, type AgentStaticModelDefinition } from "#public/index.js";
1
+ import { type AgentReasoningDefinition, type AgentStaticModelDefinition, type DynamicSentinel, type DynamicSubagentDefinition } from "#public/index.js";
2
2
  import { type SelfModificationConfig } from "./config.js";
3
- /** Default model used by the self-modification subagent. */
4
- export declare const DEFAULT_SELF_MODIFICATION_MODEL = "anthropic/claude-sonnet-5";
3
+ /** Fallback model when neither the self-modification agent nor its parent configures one. */
4
+ export declare const FALLBACK_SELF_MODIFICATION_MODEL = "openai/gpt-5.6-luna-fast";
5
5
  /** Configuration for the self-modification subagent. */
6
6
  export interface SelfModificationAgentOptions {
7
7
  /** Policy shared with the sandbox and extension mount. */
8
8
  readonly config?: SelfModificationConfig;
9
- /**
10
- * Model used by the self-modification subagent.
11
- *
12
- * @default "anthropic/claude-sonnet-5"
13
- */
9
+ /** Model used by the self-modification subagent; defaults to the effective parent model. */
14
10
  readonly model?: AgentStaticModelDefinition;
15
11
  /**
16
12
  * Reasoning effort used by the self-modification subagent.
@@ -18,14 +14,6 @@ export interface SelfModificationAgentOptions {
18
14
  readonly reasoning?: AgentReasoningDefinition;
19
15
  }
20
16
  /** Defines the environment-aware self-modification dynamic subagent. */
21
- export declare function defineSelfModificationAgent(options?: SelfModificationAgentOptions): import("#dynamic/definition.js").DynamicSentinel<import("#public/index.js").DefinedAgent<{
22
- description: string;
23
- model: AgentStaticModelDefinition;
24
- reasoning: AgentReasoningDefinition | undefined;
25
- }> | null>;
26
- declare const _default: import("#dynamic/definition.js").DynamicSentinel<import("#public/index.js").DefinedAgent<{
27
- description: string;
28
- model: AgentStaticModelDefinition;
29
- reasoning: AgentReasoningDefinition | undefined;
30
- }> | null>;
17
+ export declare function defineSelfModificationAgent(options?: SelfModificationAgentOptions): DynamicSentinel<DynamicSubagentDefinition | null>;
18
+ declare const _default: DynamicSentinel<DynamicSubagentDefinition | null>;
31
19
  export default _default;
@@ -1 +1 @@
1
- import{resolveSelfModificationConfig}from"./config.js";import{hasGitHubCredential}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{defineAgent,defineDynamic}from"#public/index.js";const DEFAULT_SELF_MODIFICATION_MODEL=`anthropic/claude-sonnet-5`;function renderDescription(e){return e.filter(e=>e.length>0).join(` `)}function defineSelfModificationAgent(e={}){let t=e.model??`anthropic/claude-sonnet-5`,n=e.reasoning,r=resolveSelfModificationConfig(e.config),resolve=async(e,i)=>{let a=resolveSelfModificationMode(r),o=renderDescription([`Delegate here when the user asks to change this eve agent or its authored source.`,`If the requested change references a tool or skill, include the exact identifier. Do not infer source paths; let the child resolve the appropriate file under /source. Delegate the requested change and existing constraints without adding unrequested features, implementation steps, or reporting requirements.`,`Treat requests for persistent changes to future behavior or capabilities as source-modification requests, even when the requester does not mention files or source code. Infer persistence from the request and conversation rather than waiting for phrases such as “modify your source.” For example, asking the agent to stop always doing something, add a capability, or change future responses calls for inspecting and editing the authored source instead of providing a one-turn workaround.`,`Treat questions phrased as whether you can install, add, enable, or connect to a named product or service as requests to extend this eve agent and delegate immediately. Do not assume they refer to device software, ask what kind of installation they mean, or deny them because you lack access to the user's device. The subagent determines whether the request maps to an integration, channel, connection, or other capability, then checks registry availability and any required setup.`,a===`local`?`Delegate questions about which integrations, channels, connections, or capabilities are available to add: the subagent searches the eve registry and reports exact item addresses instead of guessing them.`:`Delegate requests to add integrations, channels, connections, or capabilities: the subagent searches the official eve registry and can install source changes into the draft proposal. Setup may require non-secret answers or an external action, and secret binding remains separate.`,a===`local`?`Delegate requests to investigate, diagnose, or optimize the agent's behavior from local traces to this subagent: it can inspect the invoking session's trace and make persistent source changes when warranted.`:``,`Resolve short follow-ups such as “yes” or “do it” against the preceding conversation. If whether the requested change should persist is genuinely ambiguous, ask one concise clarifying question.`,`If a tool or capability created or changed by this subagent later fails or behaves incorrectly, explain the observed problem and offer to delegate a repair. Do not start the repair until the user confirms. Treat that confirmation as a source-modification request and delegate it immediately, including the exact identifier, failing behavior, expected behavior, and existing constraints.`,a===`local`?`Source edits do not affect the caller’s current turn. After this subagent reports changes, do not invoke edited tools or attempt runtime verification until a new user turn.`:`Source edits do not affect the caller’s current turn. The subagent can publish only a draft pull request, and changes become effective only after review, merge, and redeployment.`]);if(a===`local`)return defineAgent({description:o,model:t,reasoning:n});if(a!==`deployed`||r.deployed===void 0||r.deployed.credentials.kind===`pat`&&!hasGitHubCredential())return null;try{if(!await r.deployed.authorize({channel:i.channel,principal:i.session.auth.current}))return null}catch{return null}return defineAgent({description:o,model:t,reasoning:n})};return defineDynamic({events:{"session.started":resolve,"turn.started":resolve}})}var agent_default=defineSelfModificationAgent();export{DEFAULT_SELF_MODIFICATION_MODEL,agent_default as default,defineSelfModificationAgent};
1
+ import{resolveSelfModificationConfig}from"./config.js";import{hasGitHubCredential}from"./credentials.js";import{resolveSelfModificationMode}from"./mode.js";import{DEFAULT_AGENT_MODEL_ID}from"#shared/default-agent-model.js";import{defineAgent,defineDynamic}from"#public/index.js";const FALLBACK_SELF_MODIFICATION_MODEL=DEFAULT_AGENT_MODEL_ID;function renderDescription(e){return e.filter(e=>e.length>0).join(` `)}function defineSelfModificationAgent(e={}){let t=e.reasoning,n=resolveSelfModificationConfig(e.config),resolve=async(r,i)=>{let a=resolveSelfModificationMode(n),o=e.model??i.model?.id??FALLBACK_SELF_MODIFICATION_MODEL,s=renderDescription([`Delegate here when the user asks to change this eve agent or its authored source.`,`If the requested change references a tool or skill, include the exact identifier. Do not infer source paths; let the child resolve the appropriate file under /source. Delegate the requested change and existing constraints without adding unrequested features, implementation steps, or reporting requirements.`,`Treat requests for persistent changes to future behavior or capabilities as source-modification requests, even when the requester does not mention files or source code. Infer persistence from the request and conversation rather than waiting for phrases such as “modify your source.” For example, asking the agent to stop always doing something, add a capability, or change future responses calls for inspecting and editing the authored source instead of providing a one-turn workaround.`,`Treat questions phrased as whether you can install, add, enable, or connect to a named product or service as requests to extend this eve agent and delegate immediately. Do not assume they refer to device software, ask what kind of installation they mean, or deny them because you lack access to the user's device. The subagent determines whether the request maps to an integration, channel, connection, or other capability, then checks registry availability and any required setup.`,a===`local`?`Delegate questions about which integrations, channels, connections, or capabilities are available to add: the subagent searches the eve registry and reports exact item addresses instead of guessing them.`:`Delegate requests to add integrations, channels, connections, or capabilities: the subagent searches the official eve registry and can install source changes into the draft proposal. Setup may require non-secret answers or an external action, and secret binding remains separate.`,a===`local`?`Delegate requests to investigate, diagnose, or optimize the agent's behavior from local traces to this subagent: it can inspect the invoking session's trace and make persistent source changes when warranted.`:``,`Resolve short follow-ups such as “yes” or “do it” against the preceding conversation. If whether the requested change should persist is genuinely ambiguous, ask one concise clarifying question.`,`If a tool or capability created or changed by this subagent later fails or behaves incorrectly, explain the observed problem and offer to delegate a repair. Do not start the repair until the user confirms. Treat that confirmation as a source-modification request and delegate it immediately, including the exact identifier, failing behavior, expected behavior, and existing constraints.`,a===`local`?`Source edits do not affect the caller’s current turn. After this subagent reports changes, do not invoke edited tools or attempt runtime verification until a new user turn.`:`Source edits do not affect the caller’s current turn. The subagent can publish only a draft pull request, and changes become effective only after review, merge, and redeployment.`]);if(a===`local`)return defineAgent({description:s,model:o,reasoning:t});if(a!==`deployed`||n.deployed===void 0||n.deployed.credentials.kind===`pat`&&!hasGitHubCredential())return null;try{if(!await n.deployed.authorize({channel:i.channel,principal:i.session.auth.current}))return null}catch{return null}return defineAgent({description:s,model:o,reasoning:t})};return defineDynamic({events:{"session.started":resolve,"turn.started":resolve}})}var agent_default=defineSelfModificationAgent();export{FALLBACK_SELF_MODIFICATION_MODEL,agent_default as default,defineSelfModificationAgent};
@@ -10,6 +10,19 @@ export interface SelfModificationAuthorizationContext {
10
10
  }
11
11
  /** Decides whether a principal may use deployed self-modification. */
12
12
  export type SelfModificationAuthorization = (context: SelfModificationAuthorizationContext) => boolean | Promise<boolean>;
13
+ export interface GitHubRepository {
14
+ readonly owner: string;
15
+ readonly repo: string;
16
+ }
17
+ export type GitHubCredentialCapability = "checkout" | "publish";
18
+ export interface GitHubCredentialRequest {
19
+ readonly capability: GitHubCredentialCapability;
20
+ readonly repository: GitHubRepository;
21
+ }
22
+ /** Application-supplied GitHub credentials for deployed self-modification. */
23
+ export interface GitHubCredentialProvider {
24
+ resolve(request: GitHubCredentialRequest): Promise<string>;
25
+ }
13
26
  export interface SelfModificationConfig {
14
27
  readonly local?: {
15
28
  readonly enabled?: boolean;
@@ -28,16 +41,12 @@ export interface SelfModificationConfig {
28
41
  };
29
42
  /** Fail-closed policy for principals that may create draft proposals. */
30
43
  readonly authorize: SelfModificationAuthorization;
31
- readonly credentials?: {
32
- /** Ephemeral, repository-scoped GitHub App credentials from Vercel Connect. */
33
- readonly vercelConnect?: {
34
- readonly connector: string;
35
- };
44
+ readonly credentials?: GitHubCredentialProvider | {
36
45
  /**
37
46
  * Self-hosted exception. Reads `EVE_SELF_MODIFICATION_GITHUB_TOKEN` from
38
47
  * the trusted deployment environment; never injects it into the sandbox.
39
48
  */
40
- readonly pat?: true;
49
+ readonly pat: true;
41
50
  };
42
51
  };
43
52
  }
@@ -55,13 +64,9 @@ export interface ResolvedDeployedSelfModificationConfig {
55
64
  export type ResolvedGitHubCredentials = {
56
65
  readonly kind: "pat";
57
66
  } | {
58
- readonly connector: string;
59
- readonly kind: "vercel-connect";
67
+ readonly kind: "provider";
68
+ readonly provider: GitHubCredentialProvider;
60
69
  };
61
- export interface GitHubRepository {
62
- readonly owner: string;
63
- readonly repo: string;
64
- }
65
70
  /** Defines the policy shared by the self-modification agent, sandbox, and extension. */
66
71
  export declare function defineSelfModificationConfig(config?: SelfModificationConfig): SelfModificationConfig;
67
72
  export declare function resolveSelfModificationConfig(config?: SelfModificationConfig): ResolvedSelfModificationConfig;
@@ -1 +1 @@
1
- import{assertGitRef,assertRepositoryPart}from"./identifiers.js";function defineSelfModificationConfig(e={}){return resolveSelfModificationConfig(e),e}function resolveSelfModificationConfig(e={}){if(!isRecord(e))throw Error(`Self-modification configuration must be an object.`);let t=e.local;if(t!==void 0&&!isRecord(t))throw Error(`Self-modification local must be an object.`);let n=t?.enabled??!0;if(typeof n!=`boolean`)throw Error(`Self-modification local.enabled must be a boolean.`);let r=e.deployed;if(r===void 0)return{localEnabled:n};if(!isRecord(r))throw Error(`Self-modification deployed must be an object.`);let{source:i,target:a,authorize:o,credentials:s}=r;if(i===void 0||a===void 0||o===void 0)throw Error(`Self-modification deployed requires source, target, and authorization configuration.`);if(!isRecord(i))throw Error(`Self-modification deployed.source must be an object.`);if(!isRecord(i.git))throw Error(`Self-modification deployed.source.git must be an object.`);if(!isRecord(a))throw Error(`Self-modification deployed.target must be an object.`);if(typeof o!=`function`)throw Error(`Self-modification deployed.authorize must be a function.`);let{git:c}=i;if(typeof c.repository!=`string`||typeof c.directory!=`string`)throw Error(`Self-modification deployed.source.git.repository and deployed.source.git.directory must be strings.`);if(typeof a.branch!=`string`)throw Error(`Self-modification deployed.target.branch must be a string.`);return{deployed:{authorize:o,credentials:parseCredentials(s),directory:parseDirectory(c.directory),repository:parseGitHubRepository(c.repository),targetBranch:parseBranch(a.branch)},localEnabled:n}}function parseCredentials(e){if(!isRecord(e))throw Error(`Self-modification deployed.credentials must explicitly configure Vercel Connect or the self-hosted PAT exception.`);if(e.vercelConnect!==void 0==(e.pat!==void 0))throw Error(`Self-modification deployed.credentials must configure exactly one of vercelConnect or pat.`);if(e.pat!==void 0){if(e.pat!==!0)throw Error(`Self-modification deployed.credentials.pat must be true.`);return{kind:`pat`}}if(!isRecord(e.vercelConnect))throw Error(`Self-modification deployed.credentials.vercelConnect must be an object.`);let t=e.vercelConnect.connector;if(typeof t!=`string`||t.trim().length===0)throw Error(`Self-modification deployed.credentials.vercelConnect.connector must be a string.`);return{connector:t.trim(),kind:`vercel-connect`}}function parseGitHubRepository(e){let t=/^github\.com\/([^/]+)\/([^/]+)$/u.exec(e);if(t?.[1]===void 0||t[2]===void 0)throw Error(`Self-modification deployed.source.git.repository must use github.com/owner/repo form.`);return assertRepositoryPart(t[1],`repository owner`),assertRepositoryPart(t[2],`repository name`),{owner:t[1],repo:t[2]}}function parseDirectory(e){if(e!==`.`&&(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).some(e=>e===``||e===`.`||e===`..`)))throw Error(`Self-modification deployed.source.git.directory must be a safe repository-relative path.`);return e}function parseBranch(e){if(assertGitRef(e,`target branch`),e.startsWith(`refs/`))throw Error(`Self-modification deployed.target.branch must be a branch name, not a full Git ref.`);return e}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{defineSelfModificationConfig,resolveSelfModificationConfig};
1
+ import{assertGitRef,assertRepositoryPart}from"./identifiers.js";function defineSelfModificationConfig(e={}){return resolveSelfModificationConfig(e),e}function resolveSelfModificationConfig(e={}){if(!isRecord(e))throw Error(`Self-modification configuration must be an object.`);let t=e.local;if(t!==void 0&&!isRecord(t))throw Error(`Self-modification local must be an object.`);let n=t?.enabled??!0;if(typeof n!=`boolean`)throw Error(`Self-modification local.enabled must be a boolean.`);let r=e.deployed;if(r===void 0)return{localEnabled:n};if(!isRecord(r))throw Error(`Self-modification deployed must be an object.`);let{source:i,target:a,authorize:o,credentials:s}=r;if(i===void 0||a===void 0||o===void 0)throw Error(`Self-modification deployed requires source, target, and authorization configuration.`);if(!isRecord(i))throw Error(`Self-modification deployed.source must be an object.`);if(!isRecord(i.git))throw Error(`Self-modification deployed.source.git must be an object.`);if(!isRecord(a))throw Error(`Self-modification deployed.target must be an object.`);if(typeof o!=`function`)throw Error(`Self-modification deployed.authorize must be a function.`);let{git:c}=i;if(typeof c.repository!=`string`||typeof c.directory!=`string`)throw Error(`Self-modification deployed.source.git.repository and deployed.source.git.directory must be strings.`);if(typeof a.branch!=`string`)throw Error(`Self-modification deployed.target.branch must be a string.`);return{deployed:{authorize:o,credentials:parseCredentials(s),directory:parseDirectory(c.directory),repository:parseGitHubRepository(c.repository),targetBranch:parseBranch(a.branch)},localEnabled:n}}function parseCredentials(e){if(!isRecord(e))throw Error(`Self-modification deployed.credentials must explicitly configure a credential provider or the self-hosted PAT exception.`);let t=e.resolve!==void 0,n=e.pat!==void 0;if(t&&n)throw Error(`Self-modification deployed.credentials must configure either a credential provider or pat, not both.`);if(n){if(e.pat!==!0)throw Error(`Self-modification deployed.credentials.pat must be true.`);return{kind:`pat`}}if(!isGitHubCredentialProvider(e))throw Error(`Self-modification deployed.credentials must be an object with a resolve function.`);return{kind:`provider`,provider:e}}function isGitHubCredentialProvider(e){return isRecord(e)&&typeof e.resolve==`function`}function parseGitHubRepository(e){let t=/^github\.com\/([^/]+)\/([^/]+)$/u.exec(e);if(t?.[1]===void 0||t[2]===void 0)throw Error(`Self-modification deployed.source.git.repository must use github.com/owner/repo form.`);return assertRepositoryPart(t[1],`repository owner`),assertRepositoryPart(t[2],`repository name`),{owner:t[1],repo:t[2]}}function parseDirectory(e){if(e!==`.`&&(e.length===0||e.startsWith(`/`)||e.includes(`\\`)||e.split(`/`).some(e=>e===``||e===`.`||e===`..`)))throw Error(`Self-modification deployed.source.git.directory must be a safe repository-relative path.`);return e}function parseBranch(e){if(assertGitRef(e,`target branch`),e.startsWith(`refs/`))throw Error(`Self-modification deployed.target.branch must be a branch name, not a full Git ref.`);return e}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{defineSelfModificationConfig,resolveSelfModificationConfig};
@@ -1,12 +1,4 @@
1
- import type { GitHubRepository, ResolvedGitHubCredentials } from "./config.js";
2
- export type GitHubCredentialCapability = "checkout" | "publish";
3
- export interface GitHubCredentialRequest {
4
- readonly capability: GitHubCredentialCapability;
5
- readonly repository: GitHubRepository;
6
- }
7
- export interface GitHubCredentialProvider {
8
- resolve(request: GitHubCredentialRequest): Promise<string>;
9
- }
1
+ import type { GitHubCredentialProvider, GitHubCredentialRequest, ResolvedGitHubCredentials } from "./config.js";
10
2
  export declare const SELF_MODIFICATION_GITHUB_TOKEN_ENV = "EVE_SELF_MODIFICATION_GITHUB_TOKEN";
11
3
  /** Checks PAT availability without returning the credential. */
12
4
  export declare function hasGitHubCredential(): boolean;
@@ -15,4 +7,3 @@ export declare function createGitHubCredentialProvider(credentials: ResolvedGitH
15
7
  /** Resolves a PAT GitHub credential without exposing it to authored code. */
16
8
  export declare function resolveGitHubCredential(request: GitHubCredentialRequest): Promise<string>;
17
9
  export declare const defaultGitHubCredentialProvider: GitHubCredentialProvider;
18
- export declare function createVercelConnectCredentialProvider(connector: string): GitHubCredentialProvider;
@@ -1 +1 @@
1
- const SELF_MODIFICATION_GITHUB_TOKEN_ENV=`EVE_SELF_MODIFICATION_GITHUB_TOKEN`;function hasGitHubCredential(){return(process.env.EVE_SELF_MODIFICATION_GITHUB_TOKEN?.trim().length??0)>0}function createGitHubCredentialProvider(e){return e.kind===`pat`?defaultGitHubCredentialProvider:createVercelConnectCredentialProvider(e.connector)}async function resolveGitHubCredential(e){return defaultGitHubCredentialProvider.resolve(e)}const defaultGitHubCredentialProvider={async resolve(){let e=process.env[SELF_MODIFICATION_GITHUB_TOKEN_ENV];if(e===void 0||e.trim().length===0)throw Error(`Self-modification requires ${SELF_MODIFICATION_GITHUB_TOKEN_ENV} in the deployment environment.`);return e.trim()}};function createVercelConnectCredentialProvider(e){return{async resolve(t){try{let{getToken:n}=await import(`@vercel/connect`),r=await n(e,{authorizationDetails:[{type:`github_app_installation`,repositories:[`${t.repository.owner}/${t.repository.repo}`]}],scopes:t.capability===`checkout`?[`contents:read`,`metadata:read`]:[`contents:write`,`pull_requests:write`,`metadata:read`],subject:{type:`app`}});if(r.trim().length===0)throw Error(`empty token`);return r}catch(t){throw Error(`Self-modification could not obtain a GitHub credential from Vercel Connect for ${e}. Install and attach the configured GitHub connector to this Vercel project, install the managed GitHub App for the configured repository, then retry.`,{cause:t})}}}}export{SELF_MODIFICATION_GITHUB_TOKEN_ENV,createGitHubCredentialProvider,createVercelConnectCredentialProvider,defaultGitHubCredentialProvider,hasGitHubCredential,resolveGitHubCredential};
1
+ const SELF_MODIFICATION_GITHUB_TOKEN_ENV=`EVE_SELF_MODIFICATION_GITHUB_TOKEN`;function hasGitHubCredential(){return(process.env.EVE_SELF_MODIFICATION_GITHUB_TOKEN?.trim().length??0)>0}function createGitHubCredentialProvider(e){return e.kind===`pat`?defaultGitHubCredentialProvider:{async resolve(t){let n=await e.provider.resolve(t);if(typeof n!=`string`||n.trim().length===0)throw Error(`Self-modification credential provider returned an empty GitHub token.`);return n.trim()}}}async function resolveGitHubCredential(e){return defaultGitHubCredentialProvider.resolve(e)}const defaultGitHubCredentialProvider={async resolve(){let e=process.env[SELF_MODIFICATION_GITHUB_TOKEN_ENV];if(e===void 0||e.trim().length===0)throw Error(`Self-modification requires ${SELF_MODIFICATION_GITHUB_TOKEN_ENV} in the deployment environment.`);return e.trim()}};export{SELF_MODIFICATION_GITHUB_TOKEN_ENV,createGitHubCredentialProvider,defaultGitHubCredentialProvider,hasGitHubCredential,resolveGitHubCredential};
@@ -1,16 +1,13 @@
1
1
  import { z } from "zod";
2
- import type { SelfModificationAuthorization } from "../config.js";
2
+ import type { GitHubCredentialProvider, SelfModificationAuthorization } from "../config.js";
3
3
  export declare const selfModificationConfigSchema: z.ZodObject<{
4
4
  local: z.ZodOptional<z.ZodObject<{
5
5
  enabled: z.ZodOptional<z.ZodBoolean>;
6
6
  }, z.core.$strip>>;
7
7
  deployed: z.ZodOptional<z.ZodObject<{
8
- credentials: z.ZodOptional<z.ZodObject<{
9
- pat: z.ZodOptional<z.ZodLiteral<true>>;
10
- vercelConnect: z.ZodOptional<z.ZodObject<{
11
- connector: z.ZodString;
12
- }, z.core.$strip>>;
13
- }, z.core.$strip>>;
8
+ credentials: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
9
+ pat: z.ZodLiteral<true>;
10
+ }, z.core.$strip>, z.ZodCustom<GitHubCredentialProvider, GitHubCredentialProvider>]>>;
14
11
  source: z.ZodObject<{
15
12
  git: z.ZodObject<{
16
13
  directory: z.ZodString;
@@ -29,12 +26,9 @@ declare const _default: import("eve/extension").ExtensionHandle<z.ZodObject<{
29
26
  enabled: z.ZodOptional<z.ZodBoolean>;
30
27
  }, z.core.$strip>>;
31
28
  deployed: z.ZodOptional<z.ZodObject<{
32
- credentials: z.ZodOptional<z.ZodObject<{
33
- pat: z.ZodOptional<z.ZodLiteral<true>>;
34
- vercelConnect: z.ZodOptional<z.ZodObject<{
35
- connector: z.ZodString;
36
- }, z.core.$strip>>;
37
- }, z.core.$strip>>;
29
+ credentials: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
30
+ pat: z.ZodLiteral<true>;
31
+ }, z.core.$strip>, z.ZodCustom<GitHubCredentialProvider, GitHubCredentialProvider>]>>;
38
32
  source: z.ZodObject<{
39
33
  git: z.ZodObject<{
40
34
  directory: z.ZodString;
@@ -1 +1 @@
1
- import{boolean,custom,literal,object,string}from"../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/schemas.js";import"../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/index.js";import{defineExtension}from"eve/extension";const selfModificationConfigSchema=object({local:object({enabled:boolean().optional()}).optional(),deployed:object({credentials:object({pat:literal(!0).optional(),vercelConnect:object({connector:string()}).optional()}).optional(),source:object({git:object({directory:string(),repository:string()})}),target:object({branch:string()}),authorize:custom(e=>typeof e==`function`)}).optional()});var extension_default=defineExtension({config:selfModificationConfigSchema});export{extension_default as default,selfModificationConfigSchema};
1
+ import{boolean,custom,literal,object,string,union}from"../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/v4/classic/schemas.js";import"../../node_modules/.pnpm/zod@4.5.4/node_modules/zod/index.js";import{defineExtension}from"eve/extension";const selfModificationConfigSchema=object({local:object({enabled:boolean().optional()}).optional(),deployed:object({credentials:union([object({pat:literal(!0)}),custom(e=>typeof e==`object`&&!!e&&`resolve`in e&&typeof e.resolve==`function`)]).optional(),source:object({git:object({directory:string(),repository:string()})}),target:object({branch:string()}),authorize:custom(e=>typeof e==`function`)}).optional()});var extension_default=defineExtension({config:selfModificationConfigSchema});export{extension_default as default,selfModificationConfigSchema};
@@ -1,4 +1,4 @@
1
- import type { GitHubCredentialProvider } from "./credentials.js";
1
+ import type { GitHubCredentialProvider } from "./config.js";
2
2
  import type { PreparedSelfModificationWorkspace } from "./git-workspace.js";
3
3
  import { captureSelfModificationProposal } from "./proposal.js";
4
4
  export interface PublishedSelfModificationProposal {
@@ -1 +1 @@
1
- function resolveSelfModificationMode(e){return process.env.EVE_DEV===`1`?e.localEnabled?`local`:`disabled`:e.deployed===void 0||e.deployed.credentials.kind===`vercel-connect`&&process.env.VERCEL_ENV!==`production`?`disabled`:`deployed`}export{resolveSelfModificationMode};
1
+ function resolveSelfModificationMode(e){return process.env.EVE_DEV===`1`?e.localEnabled?`local`:`disabled`:e.deployed===void 0?`disabled`:`deployed`}export{resolveSelfModificationMode};
@@ -36,7 +36,7 @@ export declare function parseGitHubRemote(remote: string): {
36
36
  owner: string;
37
37
  repo: string;
38
38
  } | undefined;
39
- export declare function defaultSelfModificationSetupOperations(appRoot: string, deps?: SelfModificationSetupDependencies): SelfModificationSetupOperations;
39
+ export declare function defaultSelfModificationSetupOperations(appRoot: string, deps?: SelfModificationSetupDependencies, projectRoot?: string): SelfModificationSetupOperations;
40
40
  export declare function repositoryRelativeDirectory(repositoryRoot: string, appRoot: string, relativePath?: typeof relative): string;
41
41
  export declare function repositoryPartError(value: string): string | undefined;
42
42
  export declare function directoryError(value: string): string | undefined;
@@ -17,7 +17,8 @@ export default defineSelfModificationConfig({
17
17
  principal.attributes.project_id === projectId
18
18
  );
19
19
  }
20
- `:``}${n}`,i=`import { defineSelfModificationConfig } from "eve/self-modification/config";
20
+ `:``}${n}`,i=`Self-modification could not obtain a GitHub credential from Vercel Connect for ${e.connector}. Install and attach the configured GitHub connector to this Vercel project, install the managed GitHub App for the configured repository, then retry.`,a=`import { getToken } from "@vercel/connect";
21
+ import { defineSelfModificationConfig } from "eve/self-modification/config";
21
22
 
22
23
  export default defineSelfModificationConfig({
23
24
  deployed: {
@@ -29,7 +30,25 @@ export default defineSelfModificationConfig({
29
30
  },
30
31
  target: { branch: ${JSON.stringify(e.branch)} },
31
32
  credentials: {
32
- vercelConnect: { connector: ${JSON.stringify(e.connector)} },
33
+ async resolve({ capability, repository }) {
34
+ try {
35
+ return await getToken(${JSON.stringify(e.connector)}, {
36
+ authorizationDetails: [
37
+ {
38
+ type: "github_app_installation",
39
+ repositories: [repository.owner + "/" + repository.repo],
40
+ },
41
+ ],
42
+ scopes:
43
+ capability === "checkout"
44
+ ? ["contents:read", "metadata:read"]
45
+ : ["contents:write", "pull_requests:write", "metadata:read"],
46
+ subject: { type: "app" },
47
+ });
48
+ } catch (error) {
49
+ throw new Error(${JSON.stringify(i)}, { cause: error });
50
+ }
51
+ },
33
52
  },
34
53
  authorize: ({ channel, principal }) => {
35
54
  switch (channel.kind) {
@@ -40,9 +59,9 @@ ${r} default:
40
59
  },
41
60
  },
42
61
  });
43
- `;return`// eve-self-modification: generated-v1 digest:${createHash(`sha256`).update(i).digest(`hex`)}\n${i}`}function classifySelfModificationConfig(e){if(e===void 0)return`missing`;if(e===renderSelfModificationConfig()||e===`import { defineSelfModificationConfig } from "eve/self-modification/config";
62
+ `;return`// eve-self-modification: generated-v1 digest:${createHash(`sha256`).update(a).digest(`hex`)}\n${a}`}function classifySelfModificationConfig(e){if(e===void 0)return`missing`;if(e===renderSelfModificationConfig()||e===`import { defineSelfModificationConfig } from "eve/self-modification/config";
44
63
 
45
64
  export default defineSelfModificationConfig({});
46
65
  `)return`local`;let[t,...n]=e.split(`
47
66
  `);return/^\/\/ eve-self-modification: generated-v1 digest:([a-f0-9]{64})$/u.exec(t??``)?.[1]===createHash(`sha256`).update(n.join(`
48
- `)).digest(`hex`)?`generated`:`authored`}function parseGitHubRemote(e){let t=e.trim().match(/^(?:https?:\/\/github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?$/u);return t?.[1]===void 0||t[2]===void 0?void 0:{owner:t[1],repo:t[2]}}function defaultSelfModificationSetupOperations(e,t=defaultDependencies){let n=join(e,SELF_MODIFICATION_CONFIG_PATH);return{async detectChannelNames(){return(await discoverAgent({appRoot:e,agentRoot:join(e,`agent`)})).manifest.channels.map(e=>stripLogicalPathExtension(e.logicalPath).replace(/^channels\//,``))},async detectGitRepository(){let t=await gitOutput(e,[`config`,`--get`,`remote.origin.url`]),n=t===void 0?void 0:parseGitHubRemote(t),r=await gitOutput(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]),i=await gitOutput(e,[`rev-parse`,`--show-toplevel`]);return{...n,branch:r?.replace(/^origin\//u,``),directory:i===void 0?void 0:repositoryRelativeDirectory(i,e),remoteKind:t===void 0?`missing`:n===void 0?`other`:`github`}},async readConfig(){try{return await readFile(n,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}},writeConfig:e=>writeFile(n,e,`utf8`),async findOrCreateConnector(n,r){let i=await listGitHubConnectors(e,r,t.captureVercel),a=`github/${n}`,o=i.find(e=>e.uid===a);if(o!==void 0){if(o.type!==`github`)throw Error(`The existing connector ${a} is not a GitHub connector.`);return o.uid}let s=await t.runVercelCaptureStdout([`connect`,`create`,`github`,`--name`,n,`-F`,`json`,`--scope`,r.orgId],{cwd:e}),c=s.ok?parseCreatedConnector(s.stdout):void 0;if(c===void 0||!c.startsWith(`github/`))throw Error(`Could not create a GitHub Vercel Connect connector.`);return c},async attachConnector(n,r){if(!(await t.runVercelCaptureStdout([`connect`,`attach`,n,`--project`,r.projectId,`--environment`,`production`,`--yes`,`--scope`,r.orgId],{cwd:e})).ok)throw Error(`Could not attach ${n} to the selected Vercel project for Production.`)}}}function parseCreatedConnector(e){try{let t=JSON.parse(e);return typeof t.uid==`string`?t.uid:void 0}catch{return}}function parseConnectorListPage(e){try{let t=JSON.parse(e);if(!Array.isArray(t.connectors))return;let n=t.connectors.flatMap(e=>typeof e==`object`&&e&&typeof e.uid==`string`&&typeof e.type==`string`?[{uid:e.uid,type:e.type}]:[]);return typeof t.cursor==`string`?{connectors:n,cursor:t.cursor}:{connectors:n}}catch{return}}async function listGitHubConnectors(e,t,n){let r=[],i=new Set,a;do{let o=[`connect`,`list`,`--all-projects`,`--service`,`github`,`-F`,`json`,`--scope`,t.orgId];a!==void 0&&o.push(`--next`,a);let s=await n(o,{cwd:e});if(!s.ok)throw Error(`Could not list GitHub connectors for the selected Vercel project. ${s.failure.message}`);let c=parseConnectorListPage(s.stdout);if(c===void 0)throw Error(`Vercel returned an invalid GitHub connector list for the selected project.`);if(r.push(...c.connectors),c.cursor!==void 0&&i.has(c.cursor))throw Error(`The GitHub connector list repeated cursor ${c.cursor}.`);c.cursor!==void 0&&i.add(c.cursor),a=c.cursor}while(a!==void 0);return r}function repositoryRelativeDirectory(e,t,n=relative){return n(e,t).replaceAll(`\\`,`/`)||`.`}function repositoryPartError(e){return/^[A-Za-z0-9_.-]+$/u.test(e)?void 0:`Enter a valid GitHub owner or repository name.`}function directoryError(e){return e===`.`||e.length>0&&!e.startsWith(`/`)&&!e.includes(`\\`)&&e.split(`/`).every(e=>e!==``&&e!==`.`&&e!==`..`)?void 0:`Enter a safe repository-relative directory or ".".`}function gitRefError(e){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(e)&&!e.endsWith(`.`)&&!e.endsWith(`/`)&&!e.includes(`..`)&&!e.includes(`//`)&&!e.includes(`@{`)?void 0:`Enter a valid branch name.`}async function gitOutput(e,t){try{return(await runFile(`git`,t,{cwd:e})).stdout.trim()||void 0}catch{return}}export{classifySelfModificationConfig,connectorName,defaultSelfModificationSetupOperations,directoryError,gitRefError,parseGitHubRemote,renderSelfModificationConfig,repositoryPartError,repositoryRelativeDirectory};
67
+ `)).digest(`hex`)?`generated`:`authored`}function parseGitHubRemote(e){let t=e.trim().match(/^(?:https?:\/\/github\.com\/|git@github\.com:|ssh:\/\/git@github\.com\/)([^/]+)\/([^/]+?)(?:\.git)?$/u);return t?.[1]===void 0||t[2]===void 0?void 0:{owner:t[1],repo:t[2]}}function defaultSelfModificationSetupOperations(e,t=defaultDependencies,n=e){let r=join(e,SELF_MODIFICATION_CONFIG_PATH);return{async detectChannelNames(){return(await discoverAgent({appRoot:e,agentRoot:join(e,`agent`)})).manifest.channels.map(e=>stripLogicalPathExtension(e.logicalPath).replace(/^channels\//,``))},async detectGitRepository(){let t=await gitOutput(e,[`config`,`--get`,`remote.origin.url`]),n=t===void 0?void 0:parseGitHubRemote(t),r=await gitOutput(e,[`symbolic-ref`,`--quiet`,`--short`,`refs/remotes/origin/HEAD`]),i=await gitOutput(e,[`rev-parse`,`--show-toplevel`]);return{...n,branch:r?.replace(/^origin\//u,``),directory:i===void 0?void 0:repositoryRelativeDirectory(i,e),remoteKind:t===void 0?`missing`:n===void 0?`other`:`github`}},async readConfig(){try{return await readFile(r,`utf8`)}catch(e){if(e.code===`ENOENT`)return;throw e}},writeConfig:e=>writeFile(r,e,`utf8`),async findOrCreateConnector(e,r){let i=await listGitHubConnectors(n,r,t.captureVercel),a=`github/${e}`,o=i.find(e=>e.uid===a);if(o!==void 0){if(o.type!==`github`)throw Error(`The existing connector ${a} is not a GitHub connector.`);return o.uid}let s=await t.runVercelCaptureStdout([`connect`,`create`,`github`,`--name`,e,`-F`,`json`,`--scope`,r.orgId],{cwd:n}),c=s.ok?parseCreatedConnector(s.stdout):void 0;if(c===void 0||!c.startsWith(`github/`))throw Error(`Could not create a GitHub Vercel Connect connector.`);return c},async attachConnector(e,r){if(!(await t.runVercelCaptureStdout([`connect`,`attach`,e,`--project`,r.projectId,`--environment`,`production`,`--yes`,`--scope`,r.orgId],{cwd:n})).ok)throw Error(`Could not attach ${e} to the selected Vercel project for Production.`)}}}function parseCreatedConnector(e){try{let t=JSON.parse(e);return typeof t.uid==`string`?t.uid:void 0}catch{return}}function parseConnectorListPage(e){try{let t=JSON.parse(e);if(!Array.isArray(t.connectors))return;let n=t.connectors.flatMap(e=>typeof e==`object`&&e&&typeof e.uid==`string`&&typeof e.type==`string`?[{uid:e.uid,type:e.type}]:[]);return typeof t.cursor==`string`?{connectors:n,cursor:t.cursor}:{connectors:n}}catch{return}}async function listGitHubConnectors(e,t,n){let r=[],i=new Set,a;do{let o=[`connect`,`list`,`--all-projects`,`--service`,`github`,`-F`,`json`,`--scope`,t.orgId];a!==void 0&&o.push(`--next`,a);let s=await n(o,{cwd:e});if(!s.ok)throw Error(`Could not list GitHub connectors for the selected Vercel project. ${s.failure.message}`);let c=parseConnectorListPage(s.stdout);if(c===void 0)throw Error(`Vercel returned an invalid GitHub connector list for the selected project.`);if(r.push(...c.connectors),c.cursor!==void 0&&i.has(c.cursor))throw Error(`The GitHub connector list repeated cursor ${c.cursor}.`);c.cursor!==void 0&&i.add(c.cursor),a=c.cursor}while(a!==void 0);return r}function repositoryRelativeDirectory(e,t,n=relative){return n(e,t).replaceAll(`\\`,`/`)||`.`}function repositoryPartError(e){return/^[A-Za-z0-9_.-]+$/u.test(e)?void 0:`Enter a valid GitHub owner or repository name.`}function directoryError(e){return e===`.`||e.length>0&&!e.startsWith(`/`)&&!e.includes(`\\`)&&e.split(`/`).every(e=>e!==``&&e!==`.`&&e!==`..`)?void 0:`Enter a safe repository-relative directory or ".".`}function gitRefError(e){return/^[A-Za-z0-9][A-Za-z0-9._/-]*$/u.test(e)&&!e.endsWith(`.`)&&!e.endsWith(`/`)&&!e.includes(`..`)&&!e.includes(`//`)&&!e.includes(`@{`)?void 0:`Enter a valid branch name.`}async function gitOutput(e,t){try{return(await runFile(`git`,t,{cwd:e})).stdout.trim()||void 0}catch{return}}export{classifySelfModificationConfig,connectorName,defaultSelfModificationSetupOperations,directoryError,gitRefError,parseGitHubRemote,renderSelfModificationConfig,repositoryPartError,repositoryRelativeDirectory};
@@ -1 +1 @@
1
- import{ensureChatGptAuth}from"./chatgpt-auth.js";import{withLoginProgress}from"./model-login-progress.js";import{loginVercelModel}from"./vercel-model-login.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{resolveModelApiKey}from"#internal/model-auth/transport.js";import{availableDirectModels}from"#internal/model-auth/available-models.js";import{modelKeySecretName,readVercelSession,writeModelSecret}from"#internal/model-auth/store.js";import{readVercelCliConnection,refreshVercelCliConnection}from"#internal/model-auth/vercel-cli.js";import{VERCEL_MODEL_CLIENT_ID,resolveVercelSession,validateVercelAccess}from"#internal/model-auth/vercel.js";import{validateGatewayApiKey}from"#setup/validate-gateway-key.js";const CONNECTION_OPTIONS=[{value:`vercel`,label:`Vercel Account`},{value:`ai-gateway-key`,label:`Vercel AI Gateway API Key`},{value:`chatgpt`,label:`ChatGPT Subscription`},{value:`openai`,label:`OpenAI API Key`},{value:`anthropic`,label:`Anthropic API Key`}];async function reuseModelConnection(e,t,n){switch(e){case`chatgpt`:return(await getDefaultCodexTokenBroker().refreshState()).kind===`ready`?{selected:e}:void 0;case`vercel`:{if(!await readVercelSession(VERCEL_MODEL_CLIENT_ID))return;let r=await resolveVercelSession();return t??={teamId:r.teamId,teamName:r.teamName},await validateVercelAccess(r.accessToken,t.teamId,n),{selected:e,team:t}}case`vercel-cli`:{let r=await readVercelCliConnection();if(!r)return;t??={teamId:r.teamId,teamName:r.teamId};try{await validateVercelAccess(r.token,t.teamId,n)}catch{if(n?.throwIfAborted(),await refreshVercelCliConnection(),r=await readVercelCliConnection(),!r)return;await validateVercelAccess(r.token,t.teamId,n)}return{selected:e,team:t}}case`ai-gateway-project`:return await getVercelOidcToken().catch(()=>void 0)?{selected:e}:void 0;case`ai-gateway-key`:{let t=await resolveModelApiKey(e);return(await validateGatewayApiKey(t,n)).kind===`valid`?{selected:e}:void 0}case`openai`:case`anthropic`:return{selected:e,availableModels:await availableDirectModels(e,await resolveModelApiKey(e),n)}}}async function authenticateModelConnection(e){let{selected:t,prompter:n,signal:r}=e;if(t===`vercel`)return{selected:t,team:await loginVercelModel(n,r,e.team?.teamId)};if(t===`chatgpt`)return await ensureChatGptAuth({signal:r,log:e=>n.log.info(e)}),{selected:t};if(t===`vercel-cli`||t===`ai-gateway-project`)throw Error(`Choose a connection with /login.`);let i=CONNECTION_OPTIONS.find(e=>e.value===t).label,a=(await n.password({message:i,validate:e=>e.trim()?void 0:`Enter an API key.`})).trim(),o=await withLoginProgress(n,`Checking ${i}…`,async()=>{if(t!==`ai-gateway-key`)return availableDirectModels(t,a,r);if((await validateGatewayApiKey(a,r)).kind!==`valid`)throw Error(`Could not validate the Gateway key. Check the key and your connection, then retry.`)});return r?.throwIfAborted(),await writeModelSecret(modelKeySecretName(t),a),{selected:t,availableModels:o}}export{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection};
1
+ import{ensureChatGptAuth}from"./chatgpt-auth.js";import{withLoginProgress}from"./model-login-progress.js";import{loginVercelModel}from"./vercel-model-login.js";import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{resolveModelApiKey}from"#internal/model-auth/transport.js";import{getDefaultCodexTokenBroker}from"#public/models/openai/chatgpt/token-broker.js";import{availableDirectModels}from"#internal/model-auth/available-models.js";import{modelKeySecretName,readVercelSession,writeModelSecret}from"#internal/model-auth/store.js";import{readVercelCliConnection,refreshVercelCliConnection}from"#internal/model-auth/vercel-cli.js";import{VERCEL_MODEL_CLIENT_ID,resolveVercelSession,validateVercelAccess}from"#internal/model-auth/vercel.js";import{validateGatewayApiKey}from"#setup/validate-gateway-key.js";const CONNECTION_OPTIONS=[{value:`vercel`,label:`Vercel Account`},{value:`ai-gateway-key`,label:`Vercel AI Gateway API Key`},{value:`chatgpt`,label:`ChatGPT Subscription`},{value:`openai`,label:`OpenAI API Key`},{value:`anthropic`,label:`Anthropic API Key`}];async function reuseModelConnection(e,t,n){switch(e){case`chatgpt`:return(await getDefaultCodexTokenBroker().refreshState()).kind===`ready`?{selected:e}:void 0;case`vercel`:{if(!await readVercelSession(VERCEL_MODEL_CLIENT_ID))return;let r=await resolveVercelSession();return t??={teamId:r.teamId,teamName:r.teamName},await validateVercelAccess(r.accessToken,t.teamId,n),{selected:e,team:t}}case`vercel-cli`:{let r=await readVercelCliConnection();if(!r)return;t??={teamId:r.teamId,teamName:r.teamId};try{await validateVercelAccess(r.token,t.teamId,n)}catch{if(n?.throwIfAborted(),await refreshVercelCliConnection(),r=await readVercelCliConnection(),!r)return;await validateVercelAccess(r.token,t.teamId,n)}return{selected:e,team:t}}case`ai-gateway-project`:return await getVercelOidcToken().catch(()=>void 0)?{selected:e}:void 0;case`ai-gateway-key`:{let t=await resolveModelApiKey(e);return(await validateGatewayApiKey(t,n)).kind===`valid`?{selected:e}:void 0}case`openai`:case`anthropic`:return{selected:e,availableModels:await availableDirectModels(e,await resolveModelApiKey(e),n)}}}async function authenticateModelConnection(e){let{selected:t,prompter:n,signal:r}=e;if(t===`vercel`)return{selected:t,team:await loginVercelModel(n,r,e.team?.teamId)};if(t===`chatgpt`)return await ensureChatGptAuth({signal:r,log:e=>n.log.info(e)}),{selected:t};if(t===`vercel-cli`||t===`ai-gateway-project`)throw Error(`Choose a connection with /login.`);let i=CONNECTION_OPTIONS.find(e=>e.value===t).label,a=(await n.password({message:i,validate:e=>e.trim()?void 0:`Enter an API key.`})).trim(),o=await withLoginProgress(n,`Checking ${i}…`,async()=>{if(t!==`ai-gateway-key`)return availableDirectModels(t,a,r);if((await validateGatewayApiKey(a,r)).kind!==`valid`)throw Error(`Could not validate the Gateway key. Check the key and your connection, then retry.`)});return r?.throwIfAborted(),await writeModelSecret(modelKeySecretName(t),a),{selected:t,availableModels:o}}export{CONNECTION_OPTIONS,authenticateModelConnection,reuseModelConnection};
@@ -14,7 +14,10 @@ export declare class RegistryFlowFailedError extends Error {
14
14
  }
15
15
  /** Searches the catalog and installs one selected item with its required setup. */
16
16
  export declare function runRegistryFlow(input: {
17
+ /** Project root for registry configuration, Vercel state, and deployment. */
17
18
  appRoot: string;
19
+ /** Selected agent project where registry payloads and setup are applied. */
20
+ installRoot?: string;
18
21
  prompter: Prompter;
19
22
  signal?: AbortSignal;
20
23
  /** Registry item supplied by `/add <item>`, installed directly. */
@@ -1,2 +1,2 @@
1
- import{createRegistrySession}from"./registry-session.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";function label(e){return e.name}var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``)r=[{address:n,name:n,source:`Registry`}];else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=await e.prompter.select({message:`Add to your agent`,search:!0,options:i.map(e=>({value:e.address,label:e.name,hint:e.address,keywords:[e.title??``,e.description??``]})),notices:n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`}))}),o=i.find(e=>e.address===a);if(o===void 0)throw Error(`That registry item is no longer available. Run /add to try again.`);r=[o]}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,o=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:a,runDeployFlow:o}),e.onScreen?.({screen:`registry_install`});let s=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(e.appRoot,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());s.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){s.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
2
- `).find(e=>e.trim()!==``);s.addFailure(label(n),r);let a={message:`Couldn't add ${label(n)}`,options:[{value:`skip`,label:`Skip ${label(n)}`},{value:`cancel`,label:`Cancel setup`}]};if(i!==void 0&&(a.description=i),await e.prompter.select(a)===`cancel`)return{kind:`done`,result:{...s.result(),cancelled:!0}}}}return{kind:`done`,result:await s.continueAfterInstall({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal})}}catch(e){if(e instanceof WizardCancelledError){let e=t?.result();return hasSettledOutcomes(e)?{kind:`done`,result:{...e,cancelled:!0}}:{kind:`cancelled`}}let n=t?.result();throw hasSettledOutcomes(n)?new RegistryFlowFailedError(e,n):e}}export{RegistryFlowFailedError,runRegistryFlow};
1
+ import{createRegistrySession}from"./registry-session.js";import{WizardCancelledError}from"#setup/step.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{withSpinner}from"#setup/with-spinner.js";function label(e){return e.name}var RegistryFlowFailedError=class extends Error{completed;constructor(e,t){super(e instanceof Error?e.message:String(e),{cause:e}),this.name=`RegistryFlowFailedError`,this.completed=t}};function hasSettledOutcomes(e){return e!==void 0&&(e.items.length>0||e.failures.length>0||e.outcomes!==void 0)}async function runRegistryFlow(e){let t;try{let n=e.initialAddress?.trim(),r;if(n!==void 0&&n!==``)r=[{address:n,name:n,source:`Registry`}];else{let t=e.deps?.browseRegistryCatalog??(await import(`#cli/commands/registry.js`)).browseRegistryCatalog,n=await withSpinner(e.prompter,`Loading registry…`,()=>t(e.appRoot)),i=[...n.items],a=await e.prompter.select({message:`Add to your agent`,search:!0,options:i.map(e=>({value:e.address,label:e.name,hint:e.address,keywords:[e.title??``,e.description??``]})),notices:n.errors.map(e=>({tone:`warning`,text:`${e.registry}: ${e.message}`}))}),o=i.find(e=>e.address===a);if(o===void 0)throw Error(`That registry item is no longer available. Run /add to try again.`);r=[o]}let i=e.deps?.installRegistryItem??(await import(`#cli/commands/registry.js`)).installRegistryItem,a=e.installRoot??e.appRoot,o=e.deps?.detectDeployment??(await import(`#setup/project-resolution.js`)).detectDeployment,s=e.deps?.runDeployFlow??(await import(`./deploy.js`)).runDeployFlow;t=createRegistrySession({detectDeployment:o,runDeployFlow:s}),e.onScreen?.({screen:`registry_install`});let c=t;for(let[t,n]of r.entries()){e.signal?.throwIfAborted(),e.onItemStart?.(n,t,r.length);try{let install=(t=e.signal)=>i(a,n.address,{silent:!0,prompter:e.prompter,signal:t}),run=()=>e.runItem===void 0?install():e.runItem(install),t=await(e.prompter.withExclusiveTerminal?.(run)??run());c.add(label(n),t.output,t.setup)}catch(t){if(e.signal?.throwIfAborted(),t instanceof WizardCancelledError){c.addCancellation(label(n));continue}if(t instanceof HumanActionRequiredError)throw t;let r=(t instanceof Error?t.message:String(t)).trim()||`Installation failed.`,i=r.split(`
2
+ `).find(e=>e.trim()!==``);c.addFailure(label(n),r);let a={message:`Couldn't add ${label(n)}`,options:[{value:`skip`,label:`Skip ${label(n)}`},{value:`cancel`,label:`Cancel setup`}]};if(i!==void 0&&(a.description=i),await e.prompter.select(a)===`cancel`)return{kind:`done`,result:{...c.result(),cancelled:!0}}}}return{kind:`done`,result:await c.continueAfterInstall({appRoot:e.appRoot,prompter:e.prompter,signal:e.signal})}}catch(e){if(e instanceof WizardCancelledError){let e=t?.result();return hasSettledOutcomes(e)?{kind:`done`,result:{...e,cancelled:!0}}:{kind:`cancelled`}}let n=t?.result();throw hasSettledOutcomes(n)?new RegistryFlowFailedError(e,n):e}}export{RegistryFlowFailedError,runRegistryFlow};
@@ -6,4 +6,4 @@ export default discordChannel({
6
6
  });
7
7
  `}async function prepareDiscordSetup(e,t=defaultDeps){e.presenter.log.info(`Create a Discord application or open an existing one, then go to Bot → Reset Token and copy the new bot token.
8
8
  Create: https://discord.com/developers/applications?new_application=true
9
- Existing applications: https://discord.com/developers/applications`);let n=(await e.asker.ask(text({key:`discord-bot-token`,message:`Discord bot token`,required:!0,sensitive:!0,environment:`DISCORD_BOT_TOKEN`}))).trim(),r=await e.asker.ask(text({key:`discord-command-name`,message:`Discord command name`,detected:`ask`,required:!0,validate:validateCommandName})),i=await e.asker.ask(text({key:`discord-command-description`,message:`Discord command description`,detected:`Ask the eve agent`,required:!0,validate:e=>e.trim().length===0?`Command description is required.`:e.trim().length>100?`Command description must be 100 characters or fewer.`:null})),a=await e.resolveVercelProject(`Discord`);return{botToken:n,commandName:r.trim(),commandDescription:i.trim(),project:a,slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyDiscordSetup(e,t,n=defaultDeps){let r=await n.resolveApplication(e.botToken),i=await n.provisionConnector({botToken:e.botToken,log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.slug,signal:t.signal});await n.registerCommand(r.id,e.botToken,{name:e.commandName,description:e.commandDescription}),await n.configureEndpoint(e.botToken,i.id),await n.writeTextFile(join(t.appRoot,`agent/channels/discord.ts`),connectTemplate(i.uid),{force:t.force});let a=`https://discord.com/oauth2/authorize?client_id=${encodeURIComponent(r.id)}&scope=bot%20applications.commands&permissions=3072`;return t.presenter.nextSteps([`Install the Discord application, then try /${e.commandName}: ${a}`]),{deploymentRequired:!0,facts:[{label:`Discord application dashboard`,value:`https://discord.com/developers/applications/${r.id}/information`,kind:`url`}]}}const DISCORD_SETUP=defineSetupIntegration({kind:`discord`,label:`Discord`,hint:`Slash commands and interactions`,prepare:prepareDiscordSetup,apply:applyDiscordSetup});export{DISCORD_SETUP,applyDiscordSetup,prepareDiscordSetup};
9
+ Existing applications: https://discord.com/developers/applications`);let n=(await e.asker.ask(text({key:`discord-bot-token`,message:`Discord bot token`,required:!0,sensitive:!0,environment:`DISCORD_BOT_TOKEN`}))).trim(),r=await e.asker.ask(text({key:`discord-command-name`,message:`Discord command name`,detected:`ask`,required:!0,validate:validateCommandName})),i=await e.asker.ask(text({key:`discord-command-description`,message:`Discord command description`,detected:`Ask the eve agent`,required:!0,validate:e=>e.trim().length===0?`Command description is required.`:e.trim().length>100?`Command description must be 100 characters or fewer.`:null})),a=await e.resolveVercelProject(`Discord`);return{botToken:n,commandName:r.trim(),commandDescription:i.trim(),project:a,slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyDiscordSetup(e,t,n=defaultDeps){let r=await n.resolveApplication(e.botToken),i=await n.provisionConnector({botToken:e.botToken,log:t.presenter.log,project:e.project,projectRoot:t.projectRoot,slug:e.slug,signal:t.signal});await n.registerCommand(r.id,e.botToken,{name:e.commandName,description:e.commandDescription}),await n.configureEndpoint(e.botToken,i.id),await n.writeTextFile(join(t.appRoot,`agent/channels/discord.ts`),connectTemplate(i.uid),{force:t.force});let a=`https://discord.com/oauth2/authorize?client_id=${encodeURIComponent(r.id)}&scope=bot%20applications.commands&permissions=3072`;return t.presenter.nextSteps([`Install the Discord application, then try /${e.commandName}: ${a}`]),{deploymentRequired:!0,facts:[{label:`Discord application dashboard`,value:`https://discord.com/developers/applications/${r.id}/information`,kind:`url`}]}}const DISCORD_SETUP=defineSetupIntegration({kind:`discord`,label:`Discord`,hint:`Slash commands and interactions`,prepare:prepareDiscordSetup,apply:applyDiscordSetup});export{DISCORD_SETUP,applyDiscordSetup,prepareDiscordSetup};
@@ -1,2 +1,2 @@
1
- import{defineSetupIntegration}from"../types.js";import{FILE_MEMORY_BLOB_ENVIRONMENTS,applyFileMemoryBlob,prepareFileMemoryBlob}from"./vercel.js";const defaultDeps={applyBlob:applyFileMemoryBlob,prepareBlob:prepareFileMemoryBlob};async function prepareFileMemorySetup(e,t=defaultDeps){let n=await e.resolveVercelProject(`file memory`);return await t.prepareBlob({appRoot:e.appRoot,project:n,signal:e.signal})}async function applyFileMemorySetup(e,t,n=defaultDeps){t.presenter.note([`Project: ${e.projectName} (${e.project.projectId})`,`Store: ${e.storeName}`,`Region: ${e.region}`,`Environments: ${FILE_MEMORY_BLOB_ENVIRONMENTS.join(`, `)}`,`Setup will create or connect a private Vercel Blob resource. Blob usage may incur charges.`].join(`
2
- `),`File-memory storage`),e.regionWarning!==void 0&&t.presenter.log.warning(e.regionWarning);let r=await n.applyBlob({appRoot:t.appRoot,log:t.presenter.log,plan:e,signal:t.signal}),i=r.action===`create`?`Created`:r.action===`repair`?`Repaired`:`Reused`;return{deploymentRequired:!0,facts:[{label:`Blob store`,value:r.store.name},{label:`Vercel project`,value:e.projectName},{label:`Region`,value:r.store.region},{label:`Environments`,value:FILE_MEMORY_BLOB_ENVIRONMENTS.join(`, `)},{label:`Setup result`,value:i}]}}const FILE_MEMORY_SETUP=defineSetupIntegration({kind:`file-memory`,label:`File memory`,hint:`Store durable facts in a private Vercel Blob store`,prepare:prepareFileMemorySetup,apply:applyFileMemorySetup});export{FILE_MEMORY_SETUP,applyFileMemorySetup,prepareFileMemorySetup};
1
+ import{defineSetupIntegration}from"../types.js";import{FILE_MEMORY_BLOB_ENVIRONMENTS,applyFileMemoryBlob,prepareFileMemoryBlob}from"./vercel.js";const defaultDeps={applyBlob:applyFileMemoryBlob,prepareBlob:prepareFileMemoryBlob};async function prepareFileMemorySetup(e,t=defaultDeps){let n=await e.resolveVercelProject(`file memory`);return await t.prepareBlob({appRoot:e.projectRoot,project:n,signal:e.signal})}async function applyFileMemorySetup(e,t,n=defaultDeps){t.presenter.note([`Project: ${e.projectName} (${e.project.projectId})`,`Store: ${e.storeName}`,`Region: ${e.region}`,`Environments: ${FILE_MEMORY_BLOB_ENVIRONMENTS.join(`, `)}`,`Setup will create or connect a private Vercel Blob resource. Blob usage may incur charges.`].join(`
2
+ `),`File-memory storage`),e.regionWarning!==void 0&&t.presenter.log.warning(e.regionWarning);let r=await n.applyBlob({appRoot:t.projectRoot,log:t.presenter.log,plan:e,signal:t.signal}),i=r.action===`create`?`Created`:r.action===`repair`?`Repaired`:`Reused`;return{deploymentRequired:!0,facts:[{label:`Blob store`,value:r.store.name},{label:`Vercel project`,value:e.projectName},{label:`Region`,value:r.store.region},{label:`Environments`,value:FILE_MEMORY_BLOB_ENVIRONMENTS.join(`, `)},{label:`Setup result`,value:i}]}}const FILE_MEMORY_SETUP=defineSetupIntegration({kind:`file-memory`,label:`File memory`,hint:`Store durable facts in a private Vercel Blob store`,prepare:prepareFileMemorySetup,apply:applyFileMemorySetup});export{FILE_MEMORY_SETUP,applyFileMemorySetup,prepareFileMemorySetup};
@@ -12,4 +12,4 @@ export default githubChannel({
12
12
  botName: ${JSON.stringify(t)},
13
13
  credentials: connectGitHubCredentials(${JSON.stringify(e)}),${a}
14
14
  });
15
- `}async function prepareGitHubSetup(e,t=defaultDeps){return{events:await e.asker.askMany(githubEventsQuestion),project:await e.resolveVercelProject(`GitHub`),slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyGitHubSetup(e,t,n=defaultDeps){t.presenter.log.info(`GitHub App`),t.presenter.log.info(`Vercel Connect creates a GitHub App and routes verified webhooks to your deployed agent.`);let r=await n.provisionConnector({log:t.presenter.log,events:e.events,project:e.project,projectRoot:t.appRoot,slug:e.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/github.ts`),connectTemplate(r.uid,r.appSlug,e.events),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the GitHub App in Vercel Connect and install it in the organization or account where you want to use it.`,`Add @${r.appSlug} to a new issue, pull request, or review comment to invoke the agent. GitHub may not autocomplete or render the token as a linked mention.`]),{facts:[],deploymentRequired:!0}}const GITHUB_SETUP=defineSetupIntegration({kind:`github`,label:`GitHub`,hint:`Respond to issues, pull requests, and comments`,prepare:prepareGitHubSetup,apply:applyGitHubSetup});export{GITHUB_SETUP,applyGitHubSetup,prepareGitHubSetup};
15
+ `}async function prepareGitHubSetup(e,t=defaultDeps){return{events:await e.asker.askMany(githubEventsQuestion),project:await e.resolveVercelProject(`GitHub`),slug:await t.deriveConnectorSlug(e.appRoot)}}async function applyGitHubSetup(e,t,n=defaultDeps){t.presenter.log.info(`GitHub App`),t.presenter.log.info(`Vercel Connect creates a GitHub App and routes verified webhooks to your deployed agent.`);let r=await n.provisionConnector({log:t.presenter.log,events:e.events,project:e.project,projectRoot:t.projectRoot,slug:e.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/github.ts`),connectTemplate(r.uid,r.appSlug,e.events),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the GitHub App in Vercel Connect and install it in the organization or account where you want to use it.`,`Add @${r.appSlug} to a new issue, pull request, or review comment to invoke the agent. GitHub may not autocomplete or render the token as a linked mention.`]),{facts:[],deploymentRequired:!0}}const GITHUB_SETUP=defineSetupIntegration({kind:`github`,label:`GitHub`,hint:`Respond to issues, pull requests, and comments`,prepare:prepareGitHubSetup,apply:applyGitHubSetup});export{GITHUB_SETUP,applyGitHubSetup,prepareGitHubSetup};
@@ -4,4 +4,4 @@ import { linearChannel } from "eve/channels/linear";
4
4
  export default linearChannel({
5
5
  credentials: connectLinearCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function prepareLinearSetup(e,t=defaultDeps){let n=await e.resolveVercelProject(`Linear`),r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.appRoot,slug:i,signal:e.signal});if(a===void 0)return{project:n,connector:{kind:`create`,slug:i}};let o=await e.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(o===`exit`)throw new WizardCancelledError;return o===`reuse`?{project:n,connector:{kind:`reuse`,connector:a}}:{project:n,connector:{kind:`create`,slug:linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})))}}}async function applyLinearSetup(e,t,n=defaultDeps){let r=e.connector.kind===`reuse`?(await n.attachConnector({connector:e.connector.connector,log:t.presenter.log,project:e.project,projectRoot:t.appRoot,signal:t.signal}),e.connector.connector):await n.provisionConnector({log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.connector.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/linear.ts`),connectTemplate(r.uid),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the Linear app in Vercel Connect and install it in the workspace where you want to delegate issues and comments.`,`Delegate an issue or mention the agent in an Agent Session to start a conversation.`]),{facts:[],deploymentRequired:!0}}const LINEAR_SETUP=defineSetupIntegration({kind:`linear`,label:`Linear Agent`,hint:`Delegate Linear issues and comments`,prepare:prepareLinearSetup,apply:applyLinearSetup});export{LINEAR_SETUP,applyLinearSetup,linearSafeConnectorSlug,prepareLinearSetup};
7
+ `}async function prepareLinearSetup(e,t=defaultDeps){let n=await e.resolveVercelProject(`Linear`),r=linearSafeConnectorSlug(await t.deriveConnectorSlug(e.appRoot)),i=linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.connector-name`,message:`Name your Linear agent`,recommended:r,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null}))),a=await t.findConnector({project:n,projectRoot:e.projectRoot,slug:i,signal:e.signal});if(a===void 0)return{project:n,connector:{kind:`create`,slug:i}};let o=await e.asker.ask(select({key:`linear.existing-connector`,message:`A Linear connector named "${i}" already exists. What would you like to do?`,options:[{id:`reuse`,label:`Reuse existing connector`,value:`reuse`},{id:`new`,label:`Create a new connector`,value:`new`},{id:`exit`,label:`Exit setup`,value:`exit`}],recommended:`reuse`}));if(o===`exit`)throw new WizardCancelledError;return o===`reuse`?{project:n,connector:{kind:`reuse`,connector:a}}:{project:n,connector:{kind:`create`,slug:linearSafeConnectorSlug(await e.asker.ask(text({key:`linear.new-connector-name`,message:`Name the new Linear agent`,recommended:`${i}-2`,validate:e=>e.trim().length===0?`A Linear agent name is required.`:null})))}}}async function applyLinearSetup(e,t,n=defaultDeps){let r=e.connector.kind===`reuse`?(await n.attachConnector({connector:e.connector.connector,log:t.presenter.log,project:e.project,projectRoot:t.projectRoot,signal:t.signal}),e.connector.connector):await n.provisionConnector({log:t.presenter.log,project:e.project,projectRoot:t.projectRoot,slug:e.connector.slug,signal:t.signal});return await n.writeTextFile(join(t.appRoot,`agent/channels/linear.ts`),connectTemplate(r.uid),{force:t.force}),t.presenter.nextSteps([`Deploy the agent, then open the Linear app in Vercel Connect and install it in the workspace where you want to delegate issues and comments.`,`Delegate an issue or mention the agent in an Agent Session to start a conversation.`]),{facts:[],deploymentRequired:!0}}const LINEAR_SETUP=defineSetupIntegration({kind:`linear`,label:`Linear Agent`,hint:`Delegate Linear issues and comments`,prepare:prepareLinearSetup,apply:applyLinearSetup});export{LINEAR_SETUP,applyLinearSetup,linearSafeConnectorSlug,prepareLinearSetup};
@@ -4,7 +4,7 @@ import { linqChannel } from "eve/channels/linq";
4
4
  export default linqChannel({
5
5
  credentials: connectLinqCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function prepareLinqSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`linq-credentials`,message:`How would you like to configure Linq?`,options:[{id:`connect`,value:`connect`,label:`Set up Vercel Connect`,hint:`Provision a managed Linq line`},{id:`portable`,value:`portable`,label:`Use portable credentials`,hint:`Register the webhook in Linq`}],recommended:e.environment.vercel.kind===`available`?`connect`:`portable`,required:!0}));if(n===`connect`){if(e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Linq setup.");let r=await e.resolveVercelProject(`Linq`),i=await e.asker.ask(text({key:`linq-connector-name`,message:`Name your Linq agent`,recommended:await deriveSlackConnectorSlug(e.appRoot),required:!0}));if(await e.asker.ask(select({key:`linq-account`,message:`Which Linq account would you like to use?`,options:[{id:`new`,value:`new`,label:`Create a new Linq account`,hint:`Provision a new managed Linq line`},{id:`existing`,value:`existing`,label:`Use an existing Linq account`,hint:`Connect a Linq partner API token and select agent phone numbers`}],recommended:`new`,required:!0}))===`new`)return{credentials:n,connectorSlug:i.trim(),project:r};let a=await e.asker.ask(text({key:`linq-existing-api-token`,message:`Linq partner API token`,required:!0,sensitive:!0,environment:`LINQ_API_KEY`})),o=await t.listPhoneNumbers(a.trim(),e.signal),s=await e.asker.askMany({key:`linq-existing-phone-numbers`,message:`Choose your agent's phone numbers`,options:o.map(e=>({id:e,value:e,label:e})),detected:o,requireSelection:!0,required:!0});return{credentials:n,connectorSlug:i.trim(),existingAccount:{apiToken:a.trim(),phoneNumbers:s},project:r}}let r=await e.asker.ask(text({key:`linq-api-key`,message:`Linq API key`,required:!0,sensitive:!0,environment:`LINQ_API_KEY`})),i=await e.asker.ask(text({key:`linq-signing-secret`,message:`Linq webhook signing secret`,required:!0,sensitive:!0,environment:`LINQ_WEBHOOK_SECRET`}));return{credentials:n,apiKey:r.trim(),signingSecret:i.trim()}}async function applyLinqSetup(e,t){let n=join(t.appRoot,`agent/channels/linq.ts`),r;if(e.credentials===`connect`){let i={log:t.presenter.log,project:e.project,projectRoot:t.appRoot,slug:e.connectorSlug,signal:t.signal};e.existingAccount!==void 0&&(i.existingAccount=e.existingAccount);let a=await provisionLinqConnector(i);r=a.phoneNumber,await writeTextFile(n,connectTemplate(a.uid),{force:t.force}),r!==void 0&&t.presenter.note(r,`Text your agent`,{tone:`success`})}else await appendEnv(join(t.appRoot,`.env.local`),{LINQ_API_KEY:e.apiKey,LINQ_WEBHOOK_SECRET:e.signingSecret}),await writeTextFile(n,`import { linqChannel } from "eve/channels/linq";
7
+ `}async function prepareLinqSetup(e,t=defaultDeps){let n=await e.asker.ask(select({key:`linq-credentials`,message:`How would you like to configure Linq?`,options:[{id:`connect`,value:`connect`,label:`Set up Vercel Connect`,hint:`Provision a managed Linq line`},{id:`portable`,value:`portable`,label:`Use portable credentials`,hint:`Register the webhook in Linq`}],recommended:e.environment.vercel.kind===`available`?`connect`:`portable`,required:!0}));if(n===`connect`){if(e.environment.vercel.kind===`unavailable`)throw Error("Vercel Connect requires an authenticated Vercel CLI. Run `vercel login`, then retry Linq setup.");let r=await e.resolveVercelProject(`Linq`),i=await e.asker.ask(text({key:`linq-connector-name`,message:`Name your Linq agent`,recommended:await deriveSlackConnectorSlug(e.appRoot),required:!0}));if(await e.asker.ask(select({key:`linq-account`,message:`Which Linq account would you like to use?`,options:[{id:`new`,value:`new`,label:`Create a new Linq account`,hint:`Provision a new managed Linq line`},{id:`existing`,value:`existing`,label:`Use an existing Linq account`,hint:`Connect a Linq partner API token and select agent phone numbers`}],recommended:`new`,required:!0}))===`new`)return{credentials:n,connectorSlug:i.trim(),project:r};let a=await e.asker.ask(text({key:`linq-existing-api-token`,message:`Linq partner API token`,required:!0,sensitive:!0,environment:`LINQ_API_KEY`})),o=await t.listPhoneNumbers(a.trim(),e.signal),s=await e.asker.askMany({key:`linq-existing-phone-numbers`,message:`Choose your agent's phone numbers`,options:o.map(e=>({id:e,value:e,label:e})),detected:o,requireSelection:!0,required:!0});return{credentials:n,connectorSlug:i.trim(),existingAccount:{apiToken:a.trim(),phoneNumbers:s},project:r}}let r=await e.asker.ask(text({key:`linq-api-key`,message:`Linq API key`,required:!0,sensitive:!0,environment:`LINQ_API_KEY`})),i=await e.asker.ask(text({key:`linq-signing-secret`,message:`Linq webhook signing secret`,required:!0,sensitive:!0,environment:`LINQ_WEBHOOK_SECRET`}));return{credentials:n,apiKey:r.trim(),signingSecret:i.trim()}}async function applyLinqSetup(e,t){let n=join(t.appRoot,`agent/channels/linq.ts`),r;if(e.credentials===`connect`){let i={log:t.presenter.log,project:e.project,projectRoot:t.projectRoot,slug:e.connectorSlug,signal:t.signal};e.existingAccount!==void 0&&(i.existingAccount=e.existingAccount);let a=await provisionLinqConnector(i);r=a.phoneNumber,await writeTextFile(n,connectTemplate(a.uid),{force:t.force}),r!==void 0&&t.presenter.note(r,`Text your agent`,{tone:`success`})}else await appendEnv(join(t.projectRoot,`.env.local`),{LINQ_API_KEY:e.apiKey,LINQ_WEBHOOK_SECRET:e.signingSecret}),await writeTextFile(n,`import { linqChannel } from "eve/channels/linq";
8
8
 
9
9
  export default linqChannel({
10
10
  credentials: {
@@ -4,7 +4,7 @@ import { photonIMessageChannel } from "eve/channels/photon";
4
4
  export default photonIMessageChannel({
5
5
  credentials: connectPhotonCredentials(${JSON.stringify(e)}),
6
6
  });
7
- `}async function preparePhotonSetup(e,t=defaultDeps){let n=basename(e.appRoot),r=await e.asker.ask(select({key:`photon-credentials`,message:`How would you like to configure Photon?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],recommended:e.environment.vercel.kind===`available`?`vercel-connect`:`environment`,required:!0})),i=`eve · ${n||`agent`}`,a=await e.asker.askEditable({key:`photon-project-source`,message:`Photon project`,options:[{id:`create`,value:`create`,label:`Create a new Photon project`,hint:`Name: ${i}`},{id:`existing`,value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],recommended:`create`,required:!0,editable:{key:`photon-project-name`,value:`create`,label:`Name`,recommended:i,validate:e=>e.trim().length===0?`Project name cannot be empty.`:null}}),o=`create`;if(a.value===`existing`){let t=await e.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),n=await e.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0,environment:`IMESSAGE_PROJECT_SECRET`}));o={projectId:t.trim(),projectSecret:n.trim()}}let s=o===`create`?void 0:await t.findDedicatedLine(o),c=s===void 0?await e.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})):void 0,l=r===`vercel-connect`?await e.resolveVercelProject(`Photon`):void 0,u={agentName:n,credentials:r,photonProject:o,dedicatedLine:s,phoneNumber:c};return a.value===`create`&&(u.photonProjectName=a.text??i),l!==void 0&&(u.vercelProject=l),u}async function resolvePhotonProject(e,t,n){if(e.photonProject!==`create`)return n.useProject({...e.photonProject,dedicatedLine:e.dedicatedLine,phoneNumber:e.phoneNumber});if(e.phoneNumber===void 0)throw Error(`Photon phone number is required.`);let r=t.presenter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`}),i;try{let r=await n.provisionProject({projectName:e.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:e.phoneNumber,signal:t.signal,onAuthorization(e){i=t.presenter.beginExternalAction({message:`Authorize Photon`,url:e.verificationUrl,userCode:e.userCode}),n.openUrl(e.verificationUrl)}});return i?.complete(),r}finally{r?.stop()}}async function applyPhotonSetup(e,t,n=defaultDeps){let r=await resolvePhotonProject(e,t,n);try{let i=join(t.appRoot,`agent/channels/photon.ts`);if(e.credentials===`vercel-connect`){let a=await n.deriveConnectorSlug(t.appRoot,e.agentName),o=await n.provisionConnector({credentials:r,log:t.presenter.log,project:e.vercelProject,projectRoot:t.appRoot,slug:a,signal:t.signal});await n.writeTextFile(i,connectTemplate(o.uid),{force:t.force})}else await n.appendEnv(join(t.appRoot,`.env.local`),{IMESSAGE_PROJECT_ID:r.projectId,IMESSAGE_PROJECT_SECRET:r.projectSecret}),await n.writeTextFile(i,`import { photonIMessageChannel } from "eve/channels/photon";
7
+ `}async function preparePhotonSetup(e,t=defaultDeps){let n=basename(e.appRoot),r=await e.asker.ask(select({key:`photon-credentials`,message:`How would you like to configure Photon?`,options:[{id:`vercel`,value:`vercel-connect`,label:`Set up Vercel Connect`,hint:`Use a linked Vercel project`},{id:`portable`,value:`environment`,label:`Use portable credentials`,hint:`Configure the Photon webhook manually after deployment`}],recommended:e.environment.vercel.kind===`available`?`vercel-connect`:`environment`,required:!0})),i=`eve · ${n||`agent`}`,a=await e.asker.askEditable({key:`photon-project-source`,message:`Photon project`,options:[{id:`create`,value:`create`,label:`Create a new Photon project`,hint:`Name: ${i}`},{id:`existing`,value:`existing`,label:`Use an existing Photon project`,hint:`Enter its project credentials`}],recommended:`create`,required:!0,editable:{key:`photon-project-name`,value:`create`,label:`Name`,recommended:i,validate:e=>e.trim().length===0?`Project name cannot be empty.`:null}}),o=`create`;if(a.value===`existing`){let t=await e.asker.ask(text({key:`photon-project-id`,message:`Photon project ID`,required:!0})),n=await e.asker.ask(text({key:`photon-project-secret`,message:`Photon project secret`,required:!0,sensitive:!0,environment:`IMESSAGE_PROJECT_SECRET`}));o={projectId:t.trim(),projectSecret:n.trim()}}let s=o===`create`?void 0:await t.findDedicatedLine(o),c=s===void 0?await e.asker.ask(text({key:`photon-phone-number`,message:`Your iMessage phone number`,placeholder:`+15551234567`,required:!0,validate:validatePhotonPhoneNumber})):void 0,l=r===`vercel-connect`?await e.resolveVercelProject(`Photon`):void 0,u={agentName:n,credentials:r,photonProject:o,dedicatedLine:s,phoneNumber:c};return a.value===`create`&&(u.photonProjectName=a.text??i),l!==void 0&&(u.vercelProject=l),u}async function resolvePhotonProject(e,t,n){if(e.photonProject!==`create`)return n.useProject({...e.photonProject,dedicatedLine:e.dedicatedLine,phoneNumber:e.phoneNumber});if(e.phoneNumber===void 0)throw Error(`Photon phone number is required.`);let r=t.presenter.log.spinner?.(`Waiting for Photon approval…`,{kind:`external-action`,emphasis:`browser`}),i;try{let r=await n.provisionProject({projectName:e.photonProjectName??`eve · ${e.agentName||`agent`}`,phoneNumber:e.phoneNumber,signal:t.signal,onAuthorization(e){i=t.presenter.beginExternalAction({message:`Authorize Photon`,url:e.verificationUrl,userCode:e.userCode}),n.openUrl(e.verificationUrl)}});return i?.complete(),r}finally{r?.stop()}}async function applyPhotonSetup(e,t,n=defaultDeps){let r=await resolvePhotonProject(e,t,n);try{let i=join(t.appRoot,`agent/channels/photon.ts`);if(e.credentials===`vercel-connect`){let a=await n.deriveConnectorSlug(t.appRoot,e.agentName),o=await n.provisionConnector({credentials:r,log:t.presenter.log,project:e.vercelProject,projectRoot:t.projectRoot,slug:a,signal:t.signal});await n.writeTextFile(i,connectTemplate(o.uid),{force:t.force})}else await n.appendEnv(join(t.projectRoot,`.env.local`),{IMESSAGE_PROJECT_ID:r.projectId,IMESSAGE_PROJECT_SECRET:r.projectSecret}),await n.writeTextFile(i,`import { photonIMessageChannel } from "eve/channels/photon";
8
8
 
9
9
  async function photonCredentials() {
10
10
  const projectId = process.env.IMESSAGE_PROJECT_ID;
@@ -1 +1 @@
1
- import{DISCORD_SETUP}from"./discord/setup.js";import{FILE_MEMORY_SETUP}from"./file-memory/setup.js";import{GITHUB_SETUP}from"./github/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{LINQ_SETUP}from"./linq/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SELF_MODIFICATION_PRODUCTION_SETUP,SELF_MODIFICATION_SETUP}from"./self-modification/setup.js";import{SHOPIFY_SETUP}from"./shopify/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createSetupContexts,createSetupPresenter}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,FILE_MEMORY_SETUP,SLACK_SETUP,DISCORD_SETUP,GITHUB_SETUP,LINEAR_SETUP,LINQ_SETUP,PHOTON_SETUP,SHOPIFY_SETUP,SELF_MODIFICATION_SETUP,SELF_MODIFICATION_PRODUCTION_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createSetupContexts,createSetupPresenter,setupIntegration};
1
+ import{DISCORD_SETUP}from"./discord/setup.js";import{FILE_MEMORY_SETUP}from"./file-memory/setup.js";import{GITHUB_SETUP}from"./github/setup.js";import{LINEAR_SETUP}from"./linear/setup.js";import{LINQ_SETUP}from"./linq/setup.js";import{PHOTON_SETUP}from"./photon/setup.js";import{SELF_MODIFICATION_PRODUCTION_SETUP,SELF_MODIFICATION_SETUP}from"./self-modification/setup.js";import{SHOPIFY_SETUP}from"./shopify/setup.js";import{SLACK_SETUP}from"./slack/setup.js";import{TEAMS_SETUP}from"./teams/setup.js";import{WEB_SETUP}from"./web/setup.js";import{createSetupContexts,createSetupPresenter}from"./shared/ui.js";const SETUP_INTEGRATIONS=[WEB_SETUP,FILE_MEMORY_SETUP,SLACK_SETUP,DISCORD_SETUP,GITHUB_SETUP,LINEAR_SETUP,LINQ_SETUP,PHOTON_SETUP,TEAMS_SETUP,SHOPIFY_SETUP,SELF_MODIFICATION_SETUP,SELF_MODIFICATION_PRODUCTION_SETUP];function setupIntegration(e){let t=SETUP_INTEGRATIONS.find(t=>t.kind===e);if(t===void 0)throw Error(`Integration setup "${e}" is not available in this version of eve. Upgrade eve and try again.`);return t}export{SETUP_INTEGRATIONS,createSetupContexts,createSetupPresenter,setupIntegration};
@@ -5,7 +5,10 @@ import { getVercelAuthStatus } from "#setup/vercel-project.js";
5
5
  import type { IntegrationSetupResult, SetupExternalAction } from "./types.js";
6
6
  /** Inputs shared by every registry-owned integration setup flow. */
7
7
  export interface RunIntegrationSetupOptions {
8
+ /** Selected agent project where authored files are changed. */
8
9
  appRoot: string;
10
+ /** Project root for shared dependencies, Vercel links, and environment files. */
11
+ projectRoot?: string;
9
12
  prompter: Prompter;
10
13
  /** Defaults to the interactive adapter; agent drivers inject an answer-backed asker. */
11
14
  asker?: Asker;
@@ -1 +1 @@
1
- import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{interactiveAsker}from"#setup/ask.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e);t.prompter.intro(`Set up ${r.label}`,r.hint),t.prompter.log.message(`Checking Vercel setup...`);let[i,a]=await Promise.all([n.detectDeployment(t.appRoot,{signal:t.signal}),n.getVercelAuthStatus(t.appRoot,{signal:t.signal})]),o=projectResolutionFromDeployment(i),s=integrationSetupEnvironment(a,o);return t.prompter.log.info(r.describeEnvironment?.(s)??describeIntegrationSetupEnvironment(s)),r.run(createSetupContexts({appRoot:t.appRoot,asker:t.asker??interactiveAsker(t.prompter),environment:s,prompter:t.prompter,resolveVercelProject:t.resolveVercelProject??(e=>resolveIntegrationVercelProject({appRoot:t.appRoot,integration:e,signal:t.signal})),signal:t.signal,force:t.force,beginExternalAction:t.beginExternalAction}))}export{runIntegrationSetup};
1
+ import{describeIntegrationSetupEnvironment,integrationSetupEnvironment}from"./shared/environment.js";import{createSetupContexts}from"./shared/ui.js";import{setupIntegration}from"./registry.js";import{resolveIntegrationVercelProject}from"./shared/vercel-project.js";import{detectDeployment,projectResolutionFromDeployment}from"#setup/project-resolution.js";import{interactiveAsker}from"#setup/ask.js";import{getVercelAuthStatus}from"#setup/vercel-project.js";const defaultDeps={detectDeployment,getVercelAuthStatus};async function runIntegrationSetup(e,t,n=defaultDeps){let r=setupIntegration(e),i=t.projectRoot??t.appRoot;t.prompter.intro(`Set up ${r.label}`,r.hint),t.prompter.log.message(`Checking Vercel setup...`);let[a,o]=await Promise.all([n.detectDeployment(i,{signal:t.signal}),n.getVercelAuthStatus(i,{signal:t.signal})]),s=projectResolutionFromDeployment(a),c=integrationSetupEnvironment(o,s);return t.prompter.log.info(r.describeEnvironment?.(c)??describeIntegrationSetupEnvironment(c)),r.run(createSetupContexts({appRoot:t.appRoot,projectRoot:i,asker:t.asker??interactiveAsker(t.prompter),environment:c,prompter:t.prompter,resolveVercelProject:t.resolveVercelProject??(e=>resolveIntegrationVercelProject({appRoot:i,integration:e,signal:t.signal})),signal:t.signal,force:t.force,beginExternalAction:t.beginExternalAction}))}export{runIntegrationSetup};
@@ -1,6 +1,12 @@
1
1
  import { type SelfModificationSetupOperations, type SelfModificationSetupValues } from "#self-modification/setup.js";
2
2
  import type { VercelProjectReference } from "#setup/project-resolution.js";
3
+ import { ensureConnectionDependencies } from "#setup/scaffold/index.js";
4
+ import { installScaffoldDependencies } from "../shared/scaffold.js";
3
5
  import { type SetupApplyContext, type SetupPrepareContext } from "../types.js";
6
+ export interface SelfModificationApplyDependencies {
7
+ ensureConnectionDependencies: typeof ensureConnectionDependencies;
8
+ installScaffoldDependencies: typeof installScaffoldDependencies;
9
+ }
4
10
  type SelfModificationSetupPlan = {
5
11
  readonly kind: "authored";
6
12
  } | {
@@ -12,7 +18,7 @@ type SelfModificationSetupPlan = {
12
18
  readonly values: SelfModificationSetupValues;
13
19
  };
14
20
  export declare function prepareSelfModificationSetup(context: SetupPrepareContext, operations?: SelfModificationSetupOperations): Promise<SelfModificationSetupPlan>;
15
- export declare function applySelfModificationSetup(plan: SelfModificationSetupPlan, context: SetupApplyContext, operations?: SelfModificationSetupOperations): Promise<{
21
+ export declare function applySelfModificationSetup(plan: SelfModificationSetupPlan, context: SetupApplyContext, operations?: SelfModificationSetupOperations, deps?: SelfModificationApplyDependencies): Promise<{
16
22
  facts: {
17
23
  label: string;
18
24
  value: string;