eve 0.22.3 → 0.22.5

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 (138) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +2 -0
  3. package/dist/src/chunks/{use-eve-agent-Cojyfr4X.js → use-eve-agent-CFBTHlPx.js} +18 -1
  4. package/dist/src/chunks/{use-eve-agent-D-S1TPCW.js → use-eve-agent-dEGV09g_.js} +18 -1
  5. package/dist/src/cli/commands/agent-instructions.d.ts +15 -0
  6. package/dist/src/cli/commands/agent-instructions.js +3 -1
  7. package/dist/src/cli/commands/agent-prompt/scaffold.md +3 -0
  8. package/dist/src/cli/commands/extension-build.d.ts +9 -0
  9. package/dist/src/cli/commands/extension-build.js +1 -0
  10. package/dist/src/cli/commands/extension-init.d.ts +25 -0
  11. package/dist/src/cli/commands/extension-init.js +1 -0
  12. package/dist/src/cli/commands/info.js +1 -1
  13. package/dist/src/cli/commands/init-git.js +1 -1
  14. package/dist/src/cli/commands/init-repl.js +1 -1
  15. package/dist/src/cli/commands/init.d.ts +2 -0
  16. package/dist/src/cli/commands/init.js +1 -1
  17. package/dist/src/cli/run.js +1 -1
  18. package/dist/src/client/agent-host.d.ts +4 -0
  19. package/dist/src/client/agent-host.js +1 -0
  20. package/dist/src/compiled/.vendor-stamp.json +4 -4
  21. package/dist/src/compiled/@workflow/core/global.d.ts +20 -0
  22. package/dist/src/compiled/@workflow/core/index.js +2 -2
  23. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +54 -0
  24. package/dist/src/compiled/@workflow/core/runtime/helpers.d.ts +11 -3
  25. package/dist/src/compiled/@workflow/core/runtime/run.d.ts +6 -2
  26. package/dist/src/compiled/@workflow/core/runtime/runs.d.ts +36 -2
  27. package/dist/src/compiled/@workflow/core/runtime/start.d.ts +28 -0
  28. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +23 -0
  29. package/dist/src/compiled/@workflow/core/runtime/step-latency.d.ts +131 -0
  30. package/dist/src/compiled/@workflow/core/runtime/step-ownership.d.ts +72 -0
  31. package/dist/src/compiled/@workflow/core/runtime/step-single-flight.d.ts +12 -0
  32. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +7 -0
  33. package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -1
  34. package/dist/src/compiled/@workflow/core/runtime.js +3 -3
  35. package/dist/src/compiled/@workflow/core/serialization-format.d.ts +1 -0
  36. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +40 -0
  37. package/dist/src/compiled/@workflow/core/telemetry.d.ts +8 -0
  38. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  39. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  40. package/dist/src/compiled/@workflow/world/analytics.d.ts +4 -4
  41. package/dist/src/compiled/@workflow/world/events.d.ts +142 -21
  42. package/dist/src/compiled/@workflow/world/hooks.d.ts +1 -24
  43. package/dist/src/compiled/@workflow/world/index.d.ts +3 -2
  44. package/dist/src/compiled/@workflow/world/queue.d.ts +10 -0
  45. package/dist/src/compiled/@workflow/world/ulid.d.ts +9 -0
  46. package/dist/src/compiled/@workflow/world-local/index.js +4 -4
  47. package/dist/src/compiled/@workflow/world-vercel/index.js +16 -16
  48. package/dist/src/compiled/_chunks/workflow/attribute-changes-ubiPfqvY.js +20 -0
  49. package/dist/src/compiled/_chunks/workflow/{dist-DJU_7R9s.js → dist-DnBjuNAZ.js} +1 -1
  50. package/dist/src/compiled/_chunks/workflow/{functions-CnVBREsg.js → functions-BCMO8vbf.js} +1 -1
  51. package/dist/src/compiled/_chunks/workflow/resume-hook-BkVkWg2r.js +1 -0
  52. package/dist/src/compiled/_chunks/workflow/run-B3N1kN9q.js +1 -0
  53. package/dist/src/compiled/_chunks/workflow/{sleep-phozDCW8.js → sleep-C2Bn-UUg.js} +1 -1
  54. package/dist/src/compiler/manifest.d.ts +4 -4
  55. package/dist/src/compiler/normalize-subagent.js +1 -1
  56. package/dist/src/compiler/remote-agent-node.d.ts +1 -1
  57. package/dist/src/compiler/remote-agent-node.js +1 -1
  58. package/dist/src/discover/filesystem.d.ts +2 -2
  59. package/dist/src/discover/filesystem.js +1 -1
  60. package/dist/src/discover/project.js +1 -1
  61. package/dist/src/harness/emission.d.ts +2 -4
  62. package/dist/src/harness/emission.js +1 -1
  63. package/dist/src/harness/inline-tool-authorization.d.ts +3 -0
  64. package/dist/src/harness/inline-tool-authorization.js +1 -0
  65. package/dist/src/harness/interruptible-stream.d.ts +5 -0
  66. package/dist/src/harness/interruptible-stream.js +1 -0
  67. package/dist/src/harness/model-call-error.js +1 -1
  68. package/dist/src/harness/ordered-stream-emitter.d.ts +17 -0
  69. package/dist/src/harness/ordered-stream-emitter.js +1 -0
  70. package/dist/src/harness/stream-actions.d.ts +1 -0
  71. package/dist/src/harness/stream-actions.js +1 -1
  72. package/dist/src/harness/subagent-depth.d.ts +1 -1
  73. package/dist/src/harness/subagent-depth.js +1 -1
  74. package/dist/src/harness/tool-loop.js +1 -1
  75. package/dist/src/internal/application/optional-package-install.js +2 -2
  76. package/dist/src/internal/application/package.js +1 -1
  77. package/dist/src/internal/authored-module-loader.d.ts +1 -1
  78. package/dist/src/internal/nitro/host/build-application.js +1 -1
  79. package/dist/src/internal/nitro/host/create-application-nitro.js +1 -1
  80. package/dist/src/internal/workflow-bundle/eve-service-route-output.d.ts +1 -2
  81. package/dist/src/internal/workflow-bundle/eve-service-route-output.js +1 -54
  82. package/dist/src/internal/workflow-bundle/vercel-workflow-output.js +1 -1
  83. package/dist/src/packages/eve-catalog/src/index.js +1 -1
  84. package/dist/src/public/definitions/extension.d.ts +4 -4
  85. package/dist/src/public/definitions/remote-agent.d.ts +11 -2
  86. package/dist/src/public/index.d.ts +1 -1
  87. package/dist/src/public/models/openai/chatgpt/auth.d.ts +69 -0
  88. package/dist/src/public/models/openai/chatgpt/auth.js +1 -0
  89. package/dist/src/public/models/openai/chatgpt/model.d.ts +8 -0
  90. package/dist/src/public/models/openai/chatgpt/model.js +1 -0
  91. package/dist/src/public/models/openai/chatgpt/transport.d.ts +24 -0
  92. package/dist/src/public/models/openai/chatgpt/transport.js +1 -0
  93. package/dist/src/public/models/openai/chatgpt/unsigned-jwt.d.ts +5 -0
  94. package/dist/src/public/models/openai/chatgpt/unsigned-jwt.js +1 -0
  95. package/dist/src/public/models/openai/index.d.ts +30 -0
  96. package/dist/src/public/models/openai/index.js +1 -0
  97. package/dist/src/public/next/index.d.ts +38 -3
  98. package/dist/src/public/next/index.js +1 -1
  99. package/dist/src/public/next/server.d.ts +1 -0
  100. package/dist/src/public/next/server.js +2 -1
  101. package/dist/src/public/next/vercel-output-config.d.ts +12 -3
  102. package/dist/src/public/next/vercel-output-config.js +1 -1
  103. package/dist/src/public/nuxt/dev-server.js +1 -1
  104. package/dist/src/public/sveltekit/dev-server.js +1 -1
  105. package/dist/src/react/use-eve-agent.d.ts +8 -1
  106. package/dist/src/react/use-eve-agent.js +1 -1
  107. package/dist/src/runtime/resolve-agent-graph.js +1 -1
  108. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  109. package/dist/src/setup/scaffold/create/extension.d.ts +30 -0
  110. package/dist/src/setup/scaffold/create/extension.js +34 -0
  111. package/dist/src/setup/scaffold/create/project.d.ts +2 -0
  112. package/dist/src/setup/scaffold/create/project.js +2 -2
  113. package/dist/src/setup/scaffold/index.d.ts +1 -0
  114. package/dist/src/setup/scaffold/index.js +1 -1
  115. package/dist/src/shared/agent-definition.d.ts +1 -1
  116. package/dist/src/svelte/index.js +1 -1
  117. package/dist/src/svelte/use-eve-agent.d.ts +8 -1
  118. package/dist/src/svelte/use-eve-agent.js +1 -1
  119. package/dist/src/vue/index.js +1 -1
  120. package/dist/src/vue/use-eve-agent.d.ts +8 -1
  121. package/dist/src/vue/use-eve-agent.js +1 -1
  122. package/docs/agent-config.md +1 -1
  123. package/docs/channels/slack.mdx +6 -0
  124. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  125. package/docs/extensions.md +42 -13
  126. package/docs/guides/client/streaming.mdx +1 -1
  127. package/docs/guides/frontend/nextjs.mdx +32 -7
  128. package/docs/guides/frontend/overview.mdx +7 -1
  129. package/docs/guides/hooks.md +9 -0
  130. package/docs/guides/remote-agents.md +23 -8
  131. package/docs/meta.json +0 -1
  132. package/docs/reference/cli.md +56 -22
  133. package/docs/reference/typescript-api.md +17 -0
  134. package/docs/subagents.mdx +1 -1
  135. package/package.json +10 -5
  136. package/dist/src/compiled/_chunks/workflow/attribute-changes-BnKD8Y3m.js +0 -20
  137. package/dist/src/compiled/_chunks/workflow/resume-hook-DjPY9VGg.js +0 -1
  138. package/dist/src/compiled/_chunks/workflow/run-BSANnUPR.js +0 -1
@@ -0,0 +1,69 @@
1
+ export type CodexAuthMode = "api-key" | "chatgpt";
2
+ export type CodexAuthState = {
3
+ readonly kind: "authenticated";
4
+ readonly accountId?: string;
5
+ readonly authMode: CodexAuthMode;
6
+ readonly authPath: string;
7
+ readonly codexHome: string;
8
+ readonly lastRefresh?: string;
9
+ } | {
10
+ readonly kind: "missing";
11
+ readonly authPath: string;
12
+ readonly codexHome: string;
13
+ } | {
14
+ readonly kind: "invalid";
15
+ readonly authPath: string;
16
+ readonly codexHome: string;
17
+ readonly reason: string;
18
+ };
19
+ export interface ReadCodexAuthStateOptions {
20
+ readonly codexHome?: string;
21
+ }
22
+ export interface CodexApiKeyCredentials {
23
+ readonly apiKey: string;
24
+ readonly authPath: string;
25
+ readonly codexHome: string;
26
+ readonly kind: "api-key";
27
+ }
28
+ export interface CodexChatGptCredentials {
29
+ readonly accessToken?: string;
30
+ readonly accountId?: string;
31
+ readonly authPath: string;
32
+ readonly codexHome: string;
33
+ readonly idToken?: string;
34
+ readonly kind: "chatgpt";
35
+ readonly lastRefresh?: string;
36
+ readonly refreshToken?: string;
37
+ }
38
+ export type CodexAuthCredentials = CodexApiKeyCredentials | CodexChatGptCredentials;
39
+ /**
40
+ * One read of the Codex login state: the reportable state view plus, when
41
+ * authenticated, the credentials the transport uses. Both views derive from
42
+ * the same parse and the same credential selection, so they cannot disagree.
43
+ */
44
+ export interface CodexAuthSnapshot {
45
+ readonly state: CodexAuthState;
46
+ /** Set exactly when `state.kind` is `"authenticated"`. */
47
+ readonly credentials?: CodexAuthCredentials;
48
+ }
49
+ export interface CodexRefreshedTokens {
50
+ readonly accessToken: string;
51
+ readonly accountId?: string;
52
+ readonly idToken?: string;
53
+ readonly refreshToken: string;
54
+ }
55
+ export declare function readCodexAuth(options?: ReadCodexAuthStateOptions): Promise<CodexAuthSnapshot>;
56
+ export declare function readCodexAuthCredentials(options?: ReadCodexAuthStateOptions): Promise<CodexAuthCredentials>;
57
+ export declare function parseCodexAuth(raw: string, input: {
58
+ readonly authPath: string;
59
+ readonly codexHome: string;
60
+ }): CodexAuthSnapshot;
61
+ export declare function writeCodexAuthCredentials(input: {
62
+ readonly credentials: CodexChatGptCredentials;
63
+ readonly now?: () => Date;
64
+ readonly tokens: CodexRefreshedTokens;
65
+ }): Promise<CodexChatGptCredentials>;
66
+ export declare function assertCodexAuthStateAuthenticated(state: CodexAuthState): void;
67
+ export declare function readCodexJwtExpirationMs(token: string | undefined): number | undefined;
68
+ export declare function isFreshCodexAccessToken(accessToken: string | undefined, now: number): boolean;
69
+ export declare function extractCodexAccountIdFromToken(token: string | undefined): string | undefined;
@@ -0,0 +1 @@
1
+ import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{readFile,writeFile}from"node:fs/promises";import{isObject}from"#shared/guards.js";import{toErrorMessage}from"#shared/errors.js";import{decodeJwt}from"#compiled/jose/index.js";import{homedir}from"node:os";const codexAuthTokensSchema=z.object({access_token:z.string().nullable().optional(),account_id:z.string().nullable().optional(),id_token:z.string().nullable().optional(),refresh_token:z.string().nullable().optional()}).passthrough(),codexAuthFileSchema=z.object({OPENAI_API_KEY:z.string().nullable().optional(),auth_mode:z.string().nullable().optional(),last_refresh:z.string().nullable().optional(),tokens:codexAuthTokensSchema.nullable().optional()}).passthrough();async function readCodexAuth(e={}){let r=e.codexHome??resolveDefaultCodexHome(),i=join(r,`auth.json`),o;try{o=await readFile(i,`utf8`)}catch(e){return e instanceof Error&&`code`in e&&e.code===`ENOENT`?{state:{kind:`missing`,authPath:i,codexHome:r}}:{state:{kind:`invalid`,authPath:i,codexHome:r,reason:toErrorMessage(e)}}}return parseCodexAuth(o,{authPath:i,codexHome:r})}async function readCodexAuthCredentials(e={}){let t=await readCodexAuth(e);if(t.credentials!==void 0)return t.credentials;throw assertCodexAuthStateAuthenticated(t.state),Error(`Codex login state at ${t.state.authPath} did not include usable credentials.`)}function parseCodexAuth(e,t){let n=parseCodexAuthFile(e);if(n.kind===`invalid`)return{state:{kind:`invalid`,authPath:t.authPath,codexHome:t.codexHome,reason:n.reason}};let r=selectCodexCredentials(n.value);return r.kind===`none`?{state:{kind:`missing`,authPath:t.authPath,codexHome:t.codexHome}}:r.kind===`api-key`?{state:{kind:`authenticated`,authMode:`api-key`,authPath:t.authPath,codexHome:t.codexHome},credentials:{kind:`api-key`,apiKey:r.apiKey,authPath:t.authPath,codexHome:t.codexHome}}:{state:{kind:`authenticated`,authMode:`chatgpt`,authPath:t.authPath,codexHome:t.codexHome,...r.accountId!==void 0&&{accountId:r.accountId},...r.lastRefresh!==void 0&&{lastRefresh:r.lastRefresh}},credentials:{kind:`chatgpt`,authPath:t.authPath,codexHome:t.codexHome,...r.accessToken!==void 0&&{accessToken:r.accessToken},...r.accountId!==void 0&&{accountId:r.accountId},...r.idToken!==void 0&&{idToken:r.idToken},...r.lastRefresh!==void 0&&{lastRefresh:r.lastRefresh},...r.refreshToken!==void 0&&{refreshToken:r.refreshToken}}}}function selectCodexCredentials(e){let t=readNonEmptyString(e.OPENAI_API_KEY),n=e.tokens??void 0,r=readNonEmptyString(n?.access_token),i=readNonEmptyString(n?.refresh_token),a=r!==void 0||i!==void 0,o=e.auth_mode===`api-key`&&t!==void 0;if(a&&!o){let t=readNonEmptyString(n?.account_id)??extractCodexAccountIdFromToken(readNonEmptyString(n?.id_token))??extractCodexAccountIdFromToken(r),a=readNonEmptyString(n?.id_token),o=readNonEmptyString(e.last_refresh);return{kind:`chatgpt`,...r!==void 0&&{accessToken:r},...t!==void 0&&{accountId:t},...a!==void 0&&{idToken:a},...o!==void 0&&{lastRefresh:o},...i!==void 0&&{refreshToken:i}}}return t===void 0?{kind:`none`}:{kind:`api-key`,apiKey:t}}function parseCodexAuthFile(e){let t;try{t=JSON.parse(e)}catch(e){return{kind:`invalid`,reason:toErrorMessage(e)}}let n=codexAuthFileSchema.safeParse(t);return n.success?{kind:`parsed`,value:n.data}:{kind:`invalid`,reason:`auth.json must match the Codex auth schema.`}}async function writeCodexAuthCredentials(e){let t=await readFile(e.credentials.authPath,`utf8`),a=JSON.parse(t);if(!isObject(a))throw Error(`Codex login state at ${e.credentials.authPath} must contain a JSON object.`);let o=isObject(a.tokens)?a.tokens:{},s=e.tokens.accountId??e.credentials.accountId??extractCodexAccountIdFromToken(e.tokens.idToken)??extractCodexAccountIdFromToken(e.tokens.accessToken),c=e.tokens.idToken??e.credentials.idToken,l=(e.now??(()=>new Date))().toISOString(),u={...a,auth_mode:`chatgpt`,tokens:{...o,access_token:e.tokens.accessToken,refresh_token:e.tokens.refreshToken,...s!==void 0&&{account_id:s},...c!==void 0&&{id_token:c}},last_refresh:l};return await writeFile(e.credentials.authPath,`${JSON.stringify(u,null,2)}\n`,`utf8`),{kind:`chatgpt`,accessToken:e.tokens.accessToken,authPath:e.credentials.authPath,codexHome:e.credentials.codexHome,lastRefresh:l,refreshToken:e.tokens.refreshToken,...s!==void 0&&{accountId:s},...c!==void 0&&{idToken:c}}}function assertCodexAuthStateAuthenticated(e){if(e.kind!==`authenticated`)throw e.kind===`missing`?Error(`Codex login state was not found at ${e.authPath}. Run \`codex login\` before using experimental_chatgpt.`):Error(`Codex login state at ${e.authPath} could not be read: ${e.reason}. Run \`codex login\` again before using experimental_chatgpt.`)}function resolveDefaultCodexHome(){return process.env.CODEX_HOME?.trim()||join(homedir(),`.codex`)}function readNonEmptyString(e){return typeof e==`string`&&e.trim()!==``?e:void 0}function readCodexJwtExpirationMs(e){let t=parseCodexJwtClaims(e);if(!(t===void 0||typeof t.exp!=`number`))return t.exp*1e3}function isFreshCodexAccessToken(e,t){if(e===void 0)return!1;let n=readCodexJwtExpirationMs(e);return n===void 0||n-6e4>t}function extractCodexAccountIdFromToken(e){let t=parseCodexJwtClaims(e);if(t===void 0)return;let n=t[`https://api.openai.com/auth`],r=t.organizations;return readNonEmptyString(t.chatgpt_account_id)??readNonEmptyString(isObject(n)?n.chatgpt_account_id:void 0)??readNonEmptyString(Array.isArray(r)&&isObject(r[0])?r[0].id:void 0)}function parseCodexJwtClaims(e){if(e!==void 0)try{return decodeJwt(e)}catch{return}}export{assertCodexAuthStateAuthenticated,extractCodexAccountIdFromToken,isFreshCodexAccessToken,parseCodexAuth,readCodexAuth,readCodexAuthCredentials,readCodexJwtExpirationMs,writeCodexAuthCredentials};
@@ -0,0 +1,8 @@
1
+ import type { LanguageModelV4 } from "#compiled/@ai-sdk/provider/index.js";
2
+ import { type CodexTransportOptions } from "./transport.js";
3
+ /** Configures the Codex model selected by the local Codex login. */
4
+ export interface CodexModelOptions {
5
+ /** OpenAI model ID passed to the Codex Responses endpoint, for example `gpt-5.6-sol`. */
6
+ readonly model: string;
7
+ }
8
+ export declare function createCodexSubscriptionModel(input: CodexModelOptions, options?: CodexTransportOptions): LanguageModelV4;
@@ -0,0 +1 @@
1
+ import{createCodexFetch}from"./transport.js";import{isObject}from"#shared/guards.js";import{createOpenAI}from"#compiled/@ai-sdk/openai/index.js";function createCodexSubscriptionModel(t,r={}){let i=t.model.trim();if(i.length===0)throw Error(`Expected "model" to name a Codex model.`);let a=createOpenAI({apiKey:`codex-local-auth`,fetch:createCodexFetch(r),name:`codex`}).responses(i);return{specificationVersion:a.specificationVersion,provider:a.provider,modelId:a.modelId,get supportedUrls(){return a.supportedUrls},doGenerate:e=>a.doGenerate(normalizeCodexCallOptions(e)),doStream:e=>a.doStream(normalizeCodexCallOptions(e))}}function normalizeCodexCallOptions(e){let t=e.providerOptions,n=t?.openai??{};return{...e,prompt:stripOpenAIItemIdsFromPrompt(e.prompt),providerOptions:{...t,openai:{...n,store:!1}}}}function stripOpenAIItemIdsFromPrompt(e){return stripOpenAIItemIds(e,new WeakMap)}function stripOpenAIItemIds(e,n){if(typeof e!=`object`||!e)return e;let r=n.get(e);if(r!==void 0)return r;if(n.set(e,e),Array.isArray(e)){let t=!1,r=e.map(e=>{let r=stripOpenAIItemIds(e,n);return r!==e&&(t=!0),r}),i=t?r:e;return n.set(e,i),i}if(!isObject(e))return e;let i=!1,a={};for(let[t,r]of Object.entries(e)){let e=stripOpenAIItemIds(r,n);(t===`providerOptions`||t===`providerMetadata`)&&(e=withoutOpenAIItemId(e)),e!==r&&(i=!0),a[t]=e}let o=i?a:e;return n.set(e,o),o}function withoutOpenAIItemId(e){if(!isObject(e)||!isObject(e.openai)||!(`itemId`in e.openai))return e;let{itemId:n,...r}=e.openai;return{...e,openai:r}}export{createCodexSubscriptionModel};
@@ -0,0 +1,24 @@
1
+ import { type CodexAuthCredentials, type CodexChatGptCredentials, type CodexRefreshedTokens } from "./auth.js";
2
+ type Fetch = typeof globalThis.fetch;
3
+ type CodexCredentialsWriter = (input: {
4
+ readonly credentials: CodexChatGptCredentials;
5
+ readonly tokens: CodexRefreshedTokens;
6
+ }) => Promise<CodexChatGptCredentials>;
7
+ export interface CodexTransportOptions {
8
+ readonly clientId?: string;
9
+ readonly codexApiEndpoint?: string;
10
+ readonly fetch?: Fetch;
11
+ readonly issuer?: string;
12
+ readonly now?: () => number;
13
+ readonly readCredentials?: () => Promise<CodexAuthCredentials>;
14
+ readonly writeCredentials?: CodexCredentialsWriter;
15
+ }
16
+ /**
17
+ * AI SDK's OpenAI client gives eve one per-request hook: `fetch`. Codex needs
18
+ * that hook to choose credentials and endpoint per login mode, not just to swap
19
+ * the base URL. API-key logins stay on OpenAI's Responses endpoint; ChatGPT
20
+ * logins use the Codex backend with a refreshed bearer token.
21
+ */
22
+ export declare function createCodexFetch(options?: CodexTransportOptions): Fetch;
23
+ export declare function rewriteCodexEndpoint(input: string, codexApiEndpoint?: string): string;
24
+ export {};
@@ -0,0 +1 @@
1
+ import{extractCodexAccountIdFromToken,isFreshCodexAccessToken,readCodexAuthCredentials,writeCodexAuthCredentials}from"./auth.js";import{z}from"#compiled/zod/index.js";const CODEX_API_ENDPOINT=`https://chatgpt.com/backend-api/codex/responses`,codexRefreshResponseSchema=z.object({access_token:z.string().trim().min(1),id_token:z.string().trim().min(1).optional(),refresh_token:z.string().trim().min(1)}).passthrough();function createCodexFetch(e={}){let r=e.fetch??fetch,i=e.readCredentials??readCodexAuthCredentials,o=e.now??Date.now,s=e.writeCredentials??createDefaultCodexCredentialsWriter(o),c=e.issuer??`https://auth.openai.com`,l=e.clientId??`app_EMoamEEZ73f0CkXaXp7hrann`,u=e.codexApiEndpoint??CODEX_API_ENDPOINT,d;return async(e,n)=>{let a=await i(),f=cloneHeaders(n?.headers??(e instanceof Request?e.headers:void 0));if(f.delete(`authorization`),f.delete(`Authorization`),f.set(`originator`,`eve`),a.kind===`api-key`)return f.set(`authorization`,`Bearer ${a.apiKey}`),r(e,fetchInit(e,n,f));let p=await authenticateChatGpt();return f.set(`authorization`,`Bearer ${p.accessToken}`),p.accountId!==void 0&&f.set(`ChatGPT-Account-Id`,p.accountId),r(rewriteCodexEndpoint(requestUrl(e),u),fetchInit(e,n,f));async function authenticateChatGpt(){if(a.kind!==`chatgpt`)throw Error(`Expected ChatGPT Codex credentials.`);if(a.accessToken!==void 0&&isFreshCodexAccessToken(a.accessToken,o()))return{...a,accessToken:a.accessToken};let e=a.refreshToken;if(e===void 0)throw Error(`Codex ChatGPT login state at ${a.authPath} does not include a refresh token. Run \`codex login\` again before using experimental_chatgpt.`);d===void 0&&(d=refreshChatGptCredentials({clientId:l,credentials:{...a,refreshToken:e},fetch:r,issuer:c,writeCredentials:s}).finally(()=>{d=void 0}));let n=await d;if(n.accessToken===void 0)throw Error(`Codex token refresh did not return an access token.`);return{...n,accessToken:n.accessToken}}}}function rewriteCodexEndpoint(e,t=CODEX_API_ENDPOINT){let n=new URL(e);return n.pathname.includes(`/v1/responses`)||n.pathname.includes(`/chat/completions`)?t:e}async function refreshChatGptCredentials(t){let n=await t.fetch(`${t.issuer}/oauth/token`,{body:new URLSearchParams({client_id:t.clientId,grant_type:`refresh_token`,refresh_token:t.credentials.refreshToken}).toString(),headers:{"Content-Type":`application/x-www-form-urlencoded`},method:`POST`});if(!n.ok)throw Error(`Codex token refresh failed with status ${n.status}. Run \`codex login\` again.`);let r=parseRefreshResponse(await n.json());return t.writeCredentials({credentials:t.credentials,tokens:{...r,accountId:r.accountId??t.credentials.accountId??extractCodexAccountIdFromToken(r.idToken)??extractCodexAccountIdFromToken(r.accessToken)}})}function parseRefreshResponse(t){let n=codexRefreshResponseSchema.safeParse(t);if(!n.success)throw Error(`Codex token refresh did not return access_token and refresh_token.`);let r=n.data.access_token,i=n.data.refresh_token,a=n.data.id_token;return{accessToken:r,refreshToken:i,...a!==void 0&&{idToken:a},accountId:extractCodexAccountIdFromToken(a)??extractCodexAccountIdFromToken(r)}}function createDefaultCodexCredentialsWriter(e){return t=>writeCodexAuthCredentials({...t,now:()=>new Date(e())})}function cloneHeaders(e){return new Headers(e)}function requestUrl(e){return e instanceof Request?e.url:e.toString()}function fetchInit(e,t,n){return t===void 0?e instanceof Request?{body:e.body,cache:e.cache,credentials:e.credentials,headers:n,integrity:e.integrity,keepalive:e.keepalive,method:e.method,mode:e.mode,redirect:e.redirect,referrer:e.referrer,referrerPolicy:e.referrerPolicy,signal:e.signal}:{headers:n}:{...t,headers:n}}export{createCodexFetch,rewriteCodexEndpoint};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Builds an unsigned JWT (`alg: "none"`, fake signature) whose payload the
3
+ * Codex auth helpers can decode. Test fixture only — no crypto involved.
4
+ */
5
+ export declare function createUnsignedJwt(payload: object): string;
@@ -0,0 +1 @@
1
+ import{Buffer}from"node:buffer";function createUnsignedJwt(e){return`${Buffer.from(JSON.stringify({alg:`none`})).toString(`base64url`)}.${Buffer.from(JSON.stringify(e)).toString(`base64url`)}.sig`}export{createUnsignedJwt};
@@ -0,0 +1,30 @@
1
+ import type { LanguageModel } from "ai";
2
+ /**
3
+ * Creates a language model billed to the local ChatGPT subscription instead
4
+ * of an API key, served through the Codex backend the `codex login` flow
5
+ * authorizes.
6
+ *
7
+ * Defaults to `gpt-5.6-sol`. Pass a bare OpenAI model slug or an
8
+ * `openai/`-prefixed id to override it; the Codex backend serves OpenAI models
9
+ * only, so any other provider-qualified id is rejected. Model availability is
10
+ * enforced by the Codex backend per account at call time, not at compile time.
11
+ *
12
+ * Credentials are read from the Codex CLI login on the machine the agent
13
+ * runs on, so this model works in local dev and fails in a deployment.
14
+ * Branch on environment for production, and set `modelContextWindowTokens`
15
+ * because Codex models carry no AI Gateway metadata:
16
+ *
17
+ * ```ts
18
+ * export default defineAgent({
19
+ * model:
20
+ * process.env.NODE_ENV === "production"
21
+ * ? "anthropic/claude-sonnet-4.6"
22
+ * : experimental_chatgpt(),
23
+ * modelContextWindowTokens: 200_000,
24
+ * });
25
+ * ```
26
+ *
27
+ * Experimental: the Codex backend is not a public API contract and may
28
+ * change or reject subscription-backed access without notice.
29
+ */
30
+ export declare function experimental_chatgpt(model?: string): LanguageModel;
@@ -0,0 +1 @@
1
+ import{createCodexSubscriptionModel}from"./chatgpt/model.js";function experimental_chatgpt(e=`gpt-5.6-sol`){let t=e.trim(),n=t.startsWith(`openai/`)?t.slice(7):t;if(n.length===0)throw Error(`Expected experimental_chatgpt "model" to name an OpenAI model, for example "gpt-5.6-sol".`);if(n.includes(`/`))throw Error(`experimental_chatgpt serves OpenAI models through the local ChatGPT login; received "${e}".`);return createCodexSubscriptionModel({model:n})}export{experimental_chatgpt};
@@ -40,6 +40,31 @@ export type EveNextConfigFunction<TConfig extends EveNextConfig = EveNextConfig>
40
40
  * Next.js config input that {@link withEve} accepts.
41
41
  */
42
42
  export type EveNextConfigInput<TConfig extends EveNextConfig = EveNextConfig> = EveNextConfigFunction<TConfig> | TConfig;
43
+ /**
44
+ * Configuration for one named eve agent mounted by {@link withEve}.
45
+ */
46
+ export interface WithEveAgentOptions {
47
+ /**
48
+ * Path to the eve application root, relative to `process.cwd()` unless
49
+ * absolute.
50
+ */
51
+ readonly root: string;
52
+ /**
53
+ * Build command for this generated eve Vercel service. Defaults to
54
+ * {@link WithEveOptions.eveBuildCommand}, then a generated command that runs
55
+ * the installed eve binary from this agent root.
56
+ */
57
+ readonly buildCommand?: string;
58
+ /**
59
+ * Private route namespace for this agent's legacy manually configured Vercel
60
+ * service and non-Vercel production proxying.
61
+ */
62
+ readonly servicePrefix?: string;
63
+ }
64
+ /**
65
+ * Map of agent names to roots or per-agent configuration.
66
+ */
67
+ export type WithEveAgentsConfig = Record<string, string | WithEveAgentOptions>;
43
68
  /**
44
69
  * Options for {@link withEve}.
45
70
  */
@@ -56,9 +81,19 @@ export interface WithEveOptions {
56
81
  */
57
82
  readonly eveRoot?: string;
58
83
  /**
59
- * Build command for the generated eve Vercel service. Defaults to `eve build`.
60
- * Use this when the eve service needs project-specific prework before the
61
- * framework build, without changing the Next.js service build command.
84
+ * Named eve agents to mount under `/eve/agents/<name>/eve/v1/*`.
85
+ *
86
+ * Use this when one Next.js app needs to talk to multiple eve agents. When
87
+ * set, do not also set {@link eveRoot}; the single-agent form remains the
88
+ * shorthand for one unnamed agent mounted at `/eve/v1/*`.
89
+ */
90
+ readonly agents?: WithEveAgentsConfig;
91
+ /**
92
+ * Build command for the generated eve Vercel service. In multi-agent mode
93
+ * this is the default for agents without their own `buildCommand`.
94
+ *
95
+ * When omitted, withEve generates a command that runs the installed eve
96
+ * binary from the agent root.
62
97
  */
63
98
  readonly eveBuildCommand?: string;
64
99
  /**
@@ -1 +1 @@
1
- import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,resolve}from"node:path";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`,EVE_PROXY_REWRITE_SOURCES=[`${EVE_ROUTE_PREFIX}/:path+`];function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(){let e=process.env[EVE_NEXT_PRODUCTION_PORT_ENV];if(e===void 0||e.trim().length===0)return 4274;let t=Number.parseInt(e,10);if(String(t)!==e.trim()||t<1||t>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);return t}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e)};let n=`http://127.0.0.1:${String(readLocalProductionPort())}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRules(e){return EVE_PROXY_REWRITE_SOURCES.map(t=>({destination:joinRoutePrefix(e,t),source:t}))}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function withEve(n,r={}){let i=process.cwd(),a=resolveApplicationRoot(r.eveRoot),o=resolveDevServerTimeout(r.devServerTimeoutMs),s=normalizeRoutePrefix(r.servicePrefix??`/_eve_internal/eve`);return async function(c,l){let u=await resolveNextConfig(n,c,l),d=u.rewrites,f=await ensureEveVercelOutputConfig({appRoot:a,eveBuildCommand:r.eveBuildCommand??`eve build`,nextRoot:i,servicePrefix:s});if(process.env.VERCEL)return u;let p=resolveProductionDestination(f.servicePrefix);return{...u,async rewrites(){let[t,n]=await Promise.all([resolveExistingRewrites(d),resolveEveDestinationPrefix({appRoot:a,devServerTimeoutMs:o,phase:c,productionDestinationPrefix:p.destinationPrefix,productionServerOrigin:p.localServerOrigin})]);return mergeRewriteRules(t,createEveRewriteRules(n))}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
1
+ import{resolveEveDestinationPrefix}from"./server.js";import{ensureEveVercelOutputConfig}from"./vercel-output-config.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{isAbsolute,join,relative,resolve}from"node:path";const EVE_NEXT_SERVICE_PREFIX=`/_eve_internal/eve`,EVE_NEXT_PRODUCTION_PORT_ENV=`EVE_NEXT_PRODUCTION_PORT`,AGENT_NAME_PATTERN=/^[a-z0-9][a-z0-9_-]*$/;function resolveApplicationRoot(e){return e===void 0||e.length===0?process.cwd():isAbsolute(e)?e:resolve(process.cwd(),e)}function resolveDevServerTimeout(e){if(e!==void 0){if(!Number.isFinite(e)||e<=0)throw Error(`eve Next.js development server timeout must be a positive number.`);return e}}function normalizeRoutePrefix(e){let t=(e.startsWith(`/`)?e:`/${e}`).replace(/\/+$/,``);if(t.length===0)throw Error(`eve Next.js service prefix cannot resolve to the root route.`);return t}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function createNamedAgentRoutePrefix(e){return joinRoutePrefix(`/eve/agents`,e)}function createNamedAgentServicePrefix(e,t){return joinRoutePrefix(e,t)}function createAgentRewriteSource(e){return joinRoutePrefix(e,`${EVE_ROUTE_PREFIX}/:path+`)}function normalizeOrigin(e){return new URL(e.trim()).origin}function readLocalProductionPort(e){let t=process.env[EVE_NEXT_PRODUCTION_PORT_ENV],n=t===void 0||t.trim().length===0?4274:Number.parseInt(t,10);if(t!==void 0&&t.trim().length>0&&String(n)!==t.trim())throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} must be an integer between 1 and 65535.`);let r=n+e;if(r<1||r>65535)throw Error(`${EVE_NEXT_PRODUCTION_PORT_ENV} plus the eve agent count exceeds 65535.`);return r}function resolveProductionDestination(e){if(process.env.VERCEL)return{destinationPrefix:e.servicePrefix};let t=process.env.EVE_NEXT_PRODUCTION_ORIGIN;if(t!==void 0&&t.trim().length>0)return{destinationPrefix:joinRoutePrefix(normalizeOrigin(t),e.servicePrefix)};let n=`http://127.0.0.1:${String(readLocalProductionPort(e.localProductionPortOffset))}`;return{destinationPrefix:n,localServerOrigin:n}}function createEveRewriteRule(e){let t=createAgentRewriteSource(e.publicRoutePrefix);return{destination:joinRoutePrefix(e.destinationPrefix,`${EVE_ROUTE_PREFIX}/:path+`),source:t}}async function resolveExistingRewrites(e){return await e?.()}function mergeRewriteRules(e,t){return e===void 0?{beforeFiles:t}:isRewriteSections(e)?{...e,beforeFiles:[...t,...e.beforeFiles??[]]}:{afterFiles:e,beforeFiles:t}}function isRewriteSections(e){return!Array.isArray(e)}async function resolveNextConfig(e,t,n){return typeof e==`function`?await e(t,n):e}function assertValidAgentName(e){if(!AGENT_NAME_PATTERN.test(e))throw Error(`eve Next.js agent name ${JSON.stringify(e)} is invalid. Use lowercase letters, numbers, underscores, or hyphens, starting with a letter or number.`)}function quoteShellArg(e){return`'${e.replaceAll(`'`,`'\\''`)}'`}function toPosixPath(e){return e.replaceAll(`\\`,`/`)}function createDefaultBuildCommand(e){return`node ${quoteShellArg(toPosixPath(relative(e.agentRoot,join(e.nextRoot,`node_modules`,`eve`,`bin`,`eve.js`))))} build`}function normalizeAgentsConfig(e,t){let n=normalizeRoutePrefix(e.servicePrefix??`/_eve_internal/eve`),resolveBuildCommand=(n,r)=>r??e.eveBuildCommand??createDefaultBuildCommand({agentRoot:n,nextRoot:t});if(e.agents===void 0){let t=resolveApplicationRoot(e.eveRoot);return[{appRoot:t,buildCommand:resolveBuildCommand(t,void 0),localProductionPortOffset:0,publicRoutePrefix:``,servicePrefix:n}]}if(e.eveRoot!==void 0)throw Error(`withEve cannot combine eveRoot with agents. Use one configuration form.`);let r=Object.entries(e.agents);if(r.length===0)throw Error(`withEve agents must contain at least one named eve agent.`);return r.map(([e,t],r)=>{assertValidAgentName(e);let i=typeof t==`string`?{root:t}:t,a=resolveApplicationRoot(i.root);return{appRoot:a,buildCommand:resolveBuildCommand(a,i.buildCommand),localProductionPortOffset:r,name:e,publicRoutePrefix:createNamedAgentRoutePrefix(e),servicePrefix:normalizeRoutePrefix(i.servicePrefix??createNamedAgentServicePrefix(n,e))}})}function withEve(n,r={}){let i=process.cwd(),a=resolveDevServerTimeout(r.devServerTimeoutMs),o=normalizeAgentsConfig(r,i);return async function(r,s){let c=await resolveNextConfig(n,r,s),l=c.rewrites,u=await ensureEveVercelOutputConfig({agents:o.map(e=>({appRoot:e.appRoot,buildCommand:e.buildCommand,name:e.name,publicRoutePrefix:e.publicRoutePrefix,servicePrefix:e.servicePrefix})),nextRoot:i});if(process.env.VERCEL)return c;let d=new Map(u.agents.map(e=>[e.name,e])),f=o.map(e=>{let t=d.get(e.name),n=resolveProductionDestination({localProductionPortOffset:e.localProductionPortOffset,servicePrefix:t?.servicePrefix??e.servicePrefix});return{...e,productionDestination:n}});return{...c,async rewrites(){let[t,n]=await Promise.all([resolveExistingRewrites(l),Promise.all(f.map(async t=>createEveRewriteRule({destinationPrefix:await resolveEveDestinationPrefix({appRoot:t.appRoot,devServerTimeoutMs:a,logLabel:t.name,phase:r,productionDestinationPrefix:t.productionDestination.destinationPrefix,productionServerOrigin:t.productionDestination.localServerOrigin}),publicRoutePrefix:t.publicRoutePrefix})))]);return mergeRewriteRules(t,n)}}}}export{EVE_NEXT_SERVICE_PREFIX,withEve};
@@ -1,6 +1,7 @@
1
1
  export declare function resolveEveDestinationPrefix(input: {
2
2
  readonly appRoot: string;
3
3
  readonly devServerTimeoutMs?: number;
4
+ readonly logLabel?: string;
4
5
  readonly phase: string;
5
6
  readonly productionDestinationPrefix: string;
6
7
  readonly productionServerOrigin?: string;
@@ -1 +1,2 @@
1
- import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{existsSync}from"node:fs";import{join}from"node:path";import{spawn}from"node:child_process";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";const EVE_BASE_URL_ENV=`EVE_BASE_URL`,DEFAULT_SERVER_READY_TIMEOUT_MS=18e4,SERVER_URL_CANDIDATE_PATTERN=/https?:\/\/[^\s"'<>]+/g,globalStateSymbol=Symbol.for(`eve.next.state`);function getGlobalState(){let e=globalThis;return e[globalStateSymbol]??={servers:new Map},e[globalStateSymbol]}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function normalizeOrigin(e){return new URL(e).origin}function readEveBaseUrlEnvironment(){let e=process.env[EVE_BASE_URL_ENV];if(!(e===void 0||e.trim().length===0))return normalizeOrigin(e)}function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let n=new AbortController,r=setTimeout(()=>{n.abort()},1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:n.signal})).ok}catch{return!1}finally{clearTimeout(r)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:(process.env[EVE_BASE_URL_ENV]=t.origin,t.origin)}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e,t){let n=resolveEveCacheDirectory(e),r=resolveEveDevServerLockPath(e),i=Date.now()+t;for(await mkdir(n,{recursive:!0});;)try{let e=await open(r,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(r,{force:!0})}}catch(n){if(!isNodeErrorWithCode(n,`EEXIST`))throw n;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(r),Date.now()>i)throw Error(`Timed out after ${t}ms waiting for another Next.js process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function isLoopbackHostname(e){return e===`localhost`||e===`::1`||e===`[::1]`||/^127(?:\.\d{1,3}){3}$/.test(e)}function parseLocalServerOrigin(e){let t=URL.parse(e);if(!(t===null||t.protocol!==`http:`&&t.protocol!==`https:`||!isLoopbackHostname(t.hostname)||t.port.length===0))return t.origin}function findLocalServerOrigin(e){for(let t of e.matchAll(SERVER_URL_CANDIDATE_PATTERN)){let e=t[0],n=parseLocalServerOrigin(e);if(n!==void 0)return n}}function startServerProcess(e){return new Promise((t,n)=>{let r=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),a=setTimeout(()=>{r.kill(),n(Error(`Timed out after ${e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(a),r.off(`error`,handleError),r.off(`exit`,handleEarlyExit)},handleError=e=>{cleanup(),n(e)},handleEarlyExit=(e,t)=>{cleanup(),n(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},handleOutput=e=>{let n=findLocalServerOrigin(e.toString(`utf8`));n!==void 0&&(cleanup(),t({origin:n,process:r}))};r.once(`error`,handleError),r.once(`exit`,handleEarlyExit),r.stdout.on(`data`,e=>{process.stdout.write(e),handleOutput(e)}),r.stderr.on(`data`,e=>{process.stderr.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e,t){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e,timeoutMs:t}).then(e=>(process.env[EVE_BASE_URL_ENV]=e.origin,installProcessShutdown(e)))}function startEveProductionServer(e){let t=new URL(e.origin),i=t.port,a=join(e.appRoot,`.output`,`server`,`index.mjs`);if(existsSync(a))return startServerProcess({args:[a],command:process.execPath,cwd:e.appRoot,env:{HOST:t.hostname,NITRO_HOST:t.hostname,NITRO_PORT:i,PORT:i}}).then(installProcessShutdown)}async function resolveSharedEveDevServer(e,t){let n=await readUsableEveDevServerRegistry(e);if(n!==void 0)return{origin:n};let r=await acquireEveDevServerLock(e,t);try{let n=await readUsableEveDevServerRegistry(e);if(n!==void 0)return{origin:n};let r=await startEveDevServer(e,t);return await writeEveDevServerRegistry(e,r),r}finally{await r()}}async function resolveEveDestinationPrefix(e){let t=getGlobalState();if(process.env.NODE_ENV===`production`){if(e.phase===`phase-production-build`)return e.productionDestinationPrefix;let n=`production:${e.appRoot}`,r=t.servers.get(n);return r===void 0&&(r=process.env.VERCEL||e.productionServerOrigin===void 0?void 0:startEveProductionServer({appRoot:e.appRoot,origin:e.productionServerOrigin}),r!==void 0&&(r=r.catch(e=>{throw t.servers.delete(n),e}),t.servers.set(n,r))),r===void 0?e.productionDestinationPrefix:(await r).origin}let n=readEveBaseUrlEnvironment();if(n!==void 0)return n;if(process.env.NODE_ENV!==`development`)return e.productionDestinationPrefix;let r=`dev:${e.appRoot}`,i=t.servers.get(r);return i===void 0&&(i=resolveSharedEveDevServer(e.appRoot,e.devServerTimeoutMs??18e4).catch(e=>{throw t.servers.delete(r),e}),t.servers.set(r,i)),(await i).origin}export{resolveEveDestinationPrefix};
1
+ import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{existsSync}from"node:fs";import{join}from"node:path";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";import{spawn}from"node:child_process";const DEFAULT_SERVER_READY_TIMEOUT_MS=18e4,ANSI_ESCAPE_PATTERN=/\u001b\[[0-?]*[ -/]*[@-~]/g,SERVER_URL_CANDIDATE_PATTERN=/https?:\/\/[^\s"'<>]+/g,globalStateSymbol=Symbol.for(`eve.next.state`);function getGlobalState(){let e=globalThis;return e[globalStateSymbol]??={servers:new Map},e[globalStateSymbol]}function joinRoutePrefix(e,t){return`${e.replace(/\/+$/,``)}/${t.replace(/^\/+/,``)}`}function normalizeOrigin(e){return new URL(e).origin}function readEveBaseUrlEnvironment(){let e=process.env.EVE_BASE_URL;if(!(e===void 0||e.trim().length===0))return normalizeOrigin(e)}function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`next-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let n=new AbortController,r=setTimeout(()=>{n.abort()},1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:n.signal})).ok}catch{return!1}finally{clearTimeout(r)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e,t){let n=resolveEveCacheDirectory(e),r=resolveEveDevServerLockPath(e),o=Date.now()+t;for(await mkdir(n,{recursive:!0});;)try{let e=await open(r,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(r,{force:!0})}}catch(n){if(!isNodeErrorWithCode(n,`EEXIST`))throw n;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(r),Date.now()>o)throw Error(`Timed out after ${t}ms waiting for another Next.js process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function isLoopbackHostname(e){return e===`localhost`||e===`::1`||e===`[::1]`||/^127(?:\.\d{1,3}){3}$/.test(e)}function parseLocalServerOrigin(e){let t=URL.parse(e);if(!(t===null||t.protocol!==`http:`&&t.protocol!==`https:`||!isLoopbackHostname(t.hostname)||t.port.length===0))return t.origin}function findLocalServerOrigin(e){for(let t of e.matchAll(SERVER_URL_CANDIDATE_PATTERN)){let e=t[0],n=parseLocalServerOrigin(e);if(n!==void 0)return n}}function formatEveDevOutputLine(e,t){let n=e.replace(/\r$/,``),r=n.replace(ANSI_ESCAPE_PATTERN,``).trim();if(r.length===0||/^☰eve\b/.test(r)||r===`CONFIGURATION_FIELD_CONFLICT`||/^\[CONFIGURATION_FIELD_CONFLICT\]/.test(r))return;let i=t===void 0?`[eve:dev]`:`[eve:dev:${t}]`,a=/server listening at\s+(https?:\/\/[^\s]+)/i.exec(n);return a===null?`${i} ${n}`:`${i} server listening at ${a[1]}`}function createEveDevOutputWriter(e){let t=``,writeLine=t=>{let n=formatEveDevOutputLine(t,e.logLabel);n!==void 0&&e.stream.write(`${n}\n`)};return{flush(){t.length!==0&&(writeLine(t),t=``)},write(e){t+=e.toString(`utf8`);let n=t.split(`
2
+ `);t=n.pop()??``;for(let e of n)writeLine(e)}}}function startServerProcess(e){return new Promise((t,n)=>{let r=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),i=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stderr}),a=createEveDevOutputWriter({logLabel:e.logLabel,stream:process.stdout}),o=setTimeout(()=>{r.kill(),n(Error(`Timed out after ${e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},e.timeoutMs??DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(o),r.off(`error`,handleError),r.off(`exit`,handleEarlyExit)},flushOutput=()=>{a.flush(),i.flush()},handleError=e=>{flushOutput(),cleanup(),n(e)},handleEarlyExit=(e,t)=>{flushOutput(),cleanup(),n(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},handleOutput=e=>{let n=findLocalServerOrigin(e.toString(`utf8`));n!==void 0&&(cleanup(),t({origin:n,process:r}))};r.once(`error`,handleError),r.once(`exit`,handleEarlyExit),r.stdout.on(`data`,e=>{a.write(e),handleOutput(e)}),r.stderr.on(`data`,e=>{i.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e,t,n){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e,logLabel:n,timeoutMs:t}).then(e=>installProcessShutdown(e))}function startEveProductionServer(e){let t=new URL(e.origin),i=t.port,a=join(e.appRoot,`.output`,`server`,`index.mjs`);if(existsSync(a))return startServerProcess({args:[a],command:process.execPath,cwd:e.appRoot,env:{HOST:t.hostname,NITRO_HOST:t.hostname,NITRO_PORT:i,PORT:i}}).then(installProcessShutdown)}async function resolveSharedEveDevServer(e,t,n){let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await acquireEveDevServerLock(e,t);try{let r=await readUsableEveDevServerRegistry(e);if(r!==void 0)return{origin:r};let i=await startEveDevServer(e,t,n);return await writeEveDevServerRegistry(e,i),i}finally{await i()}}async function resolveEveDestinationPrefix(e){let t=getGlobalState();if(process.env.NODE_ENV===`production`){if(e.phase===`phase-production-build`)return e.productionDestinationPrefix;let n=`production:${e.appRoot}`,r=t.servers.get(n);return r===void 0&&(r=process.env.VERCEL||e.productionServerOrigin===void 0?void 0:startEveProductionServer({appRoot:e.appRoot,origin:e.productionServerOrigin}),r!==void 0&&(r=r.catch(e=>{throw t.servers.delete(n),e}),t.servers.set(n,r))),r===void 0?e.productionDestinationPrefix:(await r).origin}let n=readEveBaseUrlEnvironment();if(n!==void 0)return n;if(process.env.NODE_ENV!==`development`)return e.productionDestinationPrefix;let r=`dev:${e.appRoot}`,i=t.servers.get(r);return i===void 0&&(i=resolveSharedEveDevServer(e.appRoot,e.devServerTimeoutMs??18e4,e.logLabel).catch(e=>{throw t.servers.delete(r),e}),t.servers.set(r,i)),(await i).origin}export{resolveEveDestinationPrefix};
@@ -1,9 +1,18 @@
1
1
  export interface EnsureVercelOutputConfigResult {
2
+ readonly agents: readonly EnsureVercelOutputConfigAgentResult[];
3
+ }
4
+ export interface EnsureVercelOutputConfigAgentInput {
5
+ readonly appRoot: string;
6
+ readonly buildCommand: string;
7
+ readonly name?: string;
8
+ readonly publicRoutePrefix: string;
9
+ readonly servicePrefix: string;
10
+ }
11
+ export interface EnsureVercelOutputConfigAgentResult {
12
+ readonly name?: string;
2
13
  readonly servicePrefix: string;
3
14
  }
4
15
  export declare function ensureEveVercelOutputConfig(input: {
5
- readonly appRoot: string;
6
- readonly eveBuildCommand: string;
16
+ readonly agents: readonly EnsureVercelOutputConfigAgentInput[];
7
17
  readonly nextRoot: string;
8
- readonly servicePrefix: string;
9
18
  }): Promise<EnsureVercelOutputConfigResult>;
@@ -1 +1 @@
1
- import{dirname,join,relative}from"node:path";import{mkdir,readFile,writeFile}from"node:fs/promises";import{findClosestLinkedVercelDirectory,findClosestVercelOutputDirectory}from"#shared/vercel-output-directory.js";const VERCEL_JSON_FILE_NAME=`vercel.json`,VERCEL_OUTPUT_CONFIG_FILE_NAME=`.vercel/output/config.json`,EVE_SERVICE_ROUTE_SRC=`^/eve/v1/(.*)$`;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasServices(e){return e!==void 0&&Object.keys(e).length>0}function resolveRelativeEntrypoint(e,t){let r=relative(e,t);return r.length===0?`.`:r.replaceAll(`\\`,`/`)}async function resolveVercelOutputConfigLocation(n){let r=await findClosestLinkedVercelDirectory(n),i=r===void 0?n:dirname(r),a=await findClosestVercelOutputDirectory(n);return a===void 0?r===void 0?{canWriteGeneratedOutput:!!process.env.VERCEL,outputConfigPath:join(n,VERCEL_OUTPUT_CONFIG_FILE_NAME),projectRoot:i}:{canWriteGeneratedOutput:!0,outputConfigPath:join(r,`output`,`config.json`),projectRoot:i}:{canWriteGeneratedOutput:!0,outputConfigPath:join(a,`config.json`),projectRoot:i}}function normalizeVercelServicesConfig(e,t){if(!isRecord(e))throw Error(`${t} must contain a JSON object.`);let n=e.services;if(n!==void 0&&!isRecord(n))throw Error(`${t} services must be a JSON object.`);let r=e.routes;if(r!==void 0&&!Array.isArray(r))throw Error(`${t} routes must be an array.`);return e}async function readVercelServicesConfig(e,t){try{return normalizeVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),t)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}function findServiceByFramework(e,t){return findServiceEntryByFramework(e,t)?.service}function findServiceEntryByFramework(e,t){return Object.entries(e).map(([e,t])=>({name:e,service:t})).find(e=>e.service.framework===t)}function resolveServicePrefix(e){if(e!==void 0){if(typeof e.routePrefix==`string`&&e.routePrefix.trim().length>0)return e.routePrefix.trim();if(typeof e.mount==`string`&&e.mount.trim().length>0)return e.mount.trim();if(isRecord(e.mount)&&typeof e.mount.path==`string`&&e.mount.path.trim().length>0)return e.mount.path.trim()}}function resolveConfiguredServicePrefix(e){return resolveServicePrefix(findServiceByFramework(e.services,`eve`))??e.servicePrefix}function assertRootServicesIncludeEve(e){let t=findServiceByFramework(e.services,`eve`);if(t!==void 0)return resolveServicePrefix(t)??e.servicePrefix;throw Error(`${VERCEL_JSON_FILE_NAME} already defines services, so withEve cannot add a generated eve service through ${VERCEL_OUTPUT_CONFIG_FILE_NAME}. Add the eve service to ${VERCEL_JSON_FILE_NAME}, or remove services from ${VERCEL_JSON_FILE_NAME}.`)}function isEveServiceRoute(e,t){let n=e.destination;return e.src===EVE_SERVICE_ROUTE_SRC&&isRecord(n)&&n.type===`service`&&n.service===t}function createEveServiceRoute(e){return{destination:{service:e,type:`service`},src:EVE_SERVICE_ROUTE_SRC}}function insertEveServiceRoute(e,t){let n=e.find(e=>isEveServiceRoute(e,t)),r=e.filter(e=>!isEveServiceRoute(e,t)),i=r.findIndex(e=>e.handle===`filesystem`),a=n??createEveServiceRoute(t);return i===-1?[a,...r]:[...r.slice(0,i),a,...r.slice(i)]}async function ensureEveVercelOutputConfig(n){let{canWriteGeneratedOutput:i,outputConfigPath:o,projectRoot:s}=await resolveVercelOutputConfigLocation(n.nextRoot),c=(await readVercelServicesConfig(join(s,VERCEL_JSON_FILE_NAME),VERCEL_JSON_FILE_NAME)).services;if(hasServices(c))return{servicePrefix:assertRootServicesIncludeEve({services:c,servicePrefix:n.servicePrefix})};let l=await readVercelServicesConfig(o,VERCEL_OUTPUT_CONFIG_FILE_NAME),u=resolveRelativeEntrypoint(n.nextRoot,n.appRoot),d=l.services??{},f=findServiceEntryByFramework(d,`eve`),p=resolveConfiguredServicePrefix({services:d,servicePrefix:n.servicePrefix});if(!i)return{servicePrefix:p};let m={...d},h=f?.name??`eve`;f===void 0&&(m.eve={buildCommand:n.eveBuildCommand,entrypoint:`package.json`,framework:`eve`,root:u},h=`eve`);let{services:g,..._}=l,v={..._,routes:insertEveServiceRoute(l.routes??[],h),services:m,version:3};return JSON.stringify(l)!==JSON.stringify(v)&&(await mkdir(dirname(o),{recursive:!0}),await writeFile(o,`${JSON.stringify(v,null,2)}\n`)),{servicePrefix:p}}export{ensureEveVercelOutputConfig};
1
+ import{dirname,join,relative}from"node:path";import{mkdir,readFile,writeFile}from"node:fs/promises";import{findClosestLinkedVercelDirectory,findClosestVercelOutputDirectory}from"#shared/vercel-output-directory.js";const VERCEL_JSON_FILE_NAME=`vercel.json`,VERCEL_OUTPUT_CONFIG_FILE_NAME=`.vercel/output/config.json`;function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function hasServices(e){return e!==void 0&&Object.keys(createServiceConfigRecord(e)).length>0}function isNamedServiceConfigArray(e){return Array.isArray(e)}function createServiceConfigRecord(e){if(e===void 0)return{};if(isNamedServiceConfigArray(e)){let t={};for(let n of e)if(typeof n.name==`string`&&n.name.trim().length>0){let{name:e,...r}=n;t[e]=r}return t}return e}function resolveRelativeEntrypoint(e,t){let r=relative(e,t);return r.length===0?`.`:r.replaceAll(`\\`,`/`)}async function resolveVercelOutputConfigLocation(n){let r=await findClosestLinkedVercelDirectory(n),i=r===void 0?n:dirname(r),a=await findClosestVercelOutputDirectory(n);return a===void 0?r===void 0?{canWriteGeneratedOutput:!!process.env.VERCEL,outputConfigPath:join(n,VERCEL_OUTPUT_CONFIG_FILE_NAME),projectRoot:i}:{canWriteGeneratedOutput:!0,outputConfigPath:join(r,`output`,`config.json`),projectRoot:i}:{canWriteGeneratedOutput:!0,outputConfigPath:join(a,`config.json`),projectRoot:i}}function normalizeVercelServicesConfig(e,t){if(!isRecord(e))throw Error(`${t} must contain a JSON object.`);let n=e.services;if(n!==void 0&&!isRecord(n)&&!(Array.isArray(n)&&n.every(e=>isRecord(e)&&typeof e.name==`string`&&e.name.trim().length>0)))throw Error(`${t} services must be a JSON object or named service array.`);let r=e.routes;if(r!==void 0&&!Array.isArray(r))throw Error(`${t} routes must be an array.`);return e}async function readVercelServicesConfig(e,t){try{return normalizeVercelServicesConfig(JSON.parse(await readFile(e,`utf8`)),t)}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return{};throw e}}function findServiceEntryByFramework(e,t){return Object.entries(e).map(([e,t])=>({name:e,service:t})).find(e=>e.service.framework===t)}function findServiceEntryByName(e,t){let n=e[t];return n===void 0?void 0:{name:t,service:n}}function resolveServicePrefix(e){if(e!==void 0){if(typeof e.routePrefix==`string`&&e.routePrefix.trim().length>0)return e.routePrefix.trim();if(typeof e.mount==`string`&&e.mount.trim().length>0)return e.mount.trim();if(isRecord(e.mount)&&typeof e.mount.path==`string`&&e.mount.path.trim().length>0)return e.mount.path.trim()}}function resolveConfiguredServicePrefix(e){let t=findConfiguredEveServiceEntry(e.services,e.agent)?.service;return resolveServicePrefix(t)??e.agent.servicePrefix}function findConfiguredEveServiceEntry(e,t){if(t.name!==void 0){let n=findServiceEntryByName(e,createEveServiceName(t.name));if(n?.service.framework===`eve`)return n}return t.name===void 0?findServiceEntryByFramework(e,`eve`):void 0}function assertRootServicesIncludeEve(e){let t=[];for(let n of e.agents){let r=findConfiguredEveServiceEntry(e.services,n)?.service;if(r===void 0)throw Error(`${VERCEL_JSON_FILE_NAME} already defines services, so withEve cannot add generated eve services through ${VERCEL_OUTPUT_CONFIG_FILE_NAME}. Add the eve service for ${n.name??`the default agent`} to ${VERCEL_JSON_FILE_NAME}, or remove services from ${VERCEL_JSON_FILE_NAME}.`);t.push({name:n.name,servicePrefix:resolveServicePrefix(r)??n.servicePrefix})}return t}function createEveServiceRouteSrc(e){return e.length===0?`^/eve/v1/(.*)$`:`^${escapeRegExp(e.startsWith(`/`)?e:`/${e}`)}/eve/v1/(.*)$`}function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}function createEveServiceName(e){return e===void 0?`eve`:`eve-${e}`}function isEveServiceRoute(e,t,n){let r=e.destination;return e.src===n&&isRecord(r)&&r.type===`service`&&r.service===t}function createEveServiceRoute(e,t){return{destination:{service:e,type:`service`},src:t}}function isEveServiceRequestPathRoute(e,t){return e.src===t}function createEveServiceRequestPathRoute(e){return{src:e,transforms:[{args:`/eve/v1/$1`,op:`set`,type:`request.path`}]}}function insertEveServiceRequestPathRoute(e,t){let n=(e??[]).filter(e=>!isEveServiceRequestPathRoute(e,t));return[createEveServiceRequestPathRoute(t),...n]}function insertEveServiceRoutes(e,t){let n=e.filter(e=>!t.some(t=>isEveServiceRoute(e,t.serviceName,t.routeSrc))),r=n.findIndex(e=>e.handle===`filesystem`),i=t.map(e=>createEveServiceRoute(e.serviceName,e.routeSrc));return r===-1?[...i,...n]:[...n.slice(0,r),...i,...n.slice(r)]}async function ensureEveVercelOutputConfig(n){let{canWriteGeneratedOutput:i,outputConfigPath:o,projectRoot:s}=await resolveVercelOutputConfigLocation(n.nextRoot),c=(await readVercelServicesConfig(join(s,VERCEL_JSON_FILE_NAME),VERCEL_JSON_FILE_NAME)).services;if(hasServices(c))return{agents:assertRootServicesIncludeEve({agents:n.agents,services:createServiceConfigRecord(c)})};let l=await readVercelServicesConfig(o,VERCEL_OUTPUT_CONFIG_FILE_NAME),u=createServiceConfigRecord(l.services),d=n.agents.map(e=>({name:e.name,servicePrefix:resolveConfiguredServicePrefix({agent:e,services:u})}));if(!i)return{agents:d};let f={...u},p=[];for(let e of n.agents){let t=findConfiguredEveServiceEntry(u,e),r=t?.name??createEveServiceName(e.name),i=createEveServiceRouteSrc(e.publicRoutePrefix);if(t===void 0){let t={buildCommand:e.buildCommand,framework:`eve`,routes:insertEveServiceRequestPathRoute(void 0,i),root:resolveRelativeEntrypoint(n.nextRoot,e.appRoot)};e.publicRoutePrefix.length>0&&(t.routePrefix=e.publicRoutePrefix),f[r]=t}else f[r]={...t.service,routes:insertEveServiceRequestPathRoute(t.service.routes,i)};p.push({routeSrc:i,serviceName:r})}let{services:m,...h}=l,g={...h,routes:insertEveServiceRoutes(l.routes??[],p),services:f,version:3};return JSON.stringify(l)!==JSON.stringify(g)&&(await mkdir(dirname(o),{recursive:!0}),await writeFile(o,`${JSON.stringify(g,null,2)}\n`)),{agents:d}}export{ensureEveVercelOutputConfig};
@@ -1 +1 @@
1
- import{joinRoutePrefix,normalizeOrigin}from"./routing.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{join}from"node:path";import{spawn}from"node:child_process";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";const EVE_BASE_URL_ENV=`EVE_BASE_URL`,DEFAULT_SERVER_READY_TIMEOUT_MS=3e4,DEV_SERVER_REGISTRY_TIMEOUT_MS=3e4,LOCAL_SERVER_URL_PATTERN=/https?:\/\/(?:\[[^\]\s]+\]|[^\s/:[\]]+)(?::\d+)?/;function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`nuxt-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`nuxt-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let r=new AbortController,i=setTimeout(()=>r.abort(),1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:r.signal})).ok}catch{return!1}finally{clearTimeout(i)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e){let t=resolveEveCacheDirectory(e),n=resolveEveDevServerLockPath(e),r=Date.now()+DEV_SERVER_REGISTRY_TIMEOUT_MS;for(await mkdir(t,{recursive:!0});;)try{let e=await open(n,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(n,{force:!0})}}catch(t){if(!isNodeErrorWithCode(t,`EEXIST`))throw t;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(n),Date.now()>r)throw Error(`Timed out after ${DEV_SERVER_REGISTRY_TIMEOUT_MS}ms waiting for another Nuxt process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function startServerProcess(e){return new Promise((n,r)=>{let i=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),a=setTimeout(()=>{i.kill(),r(Error(`Timed out after ${DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(a),i.off(`error`,handleError),i.off(`exit`,handleEarlyExit)},handleError=e=>{cleanup(),r(e)},handleEarlyExit=(e,t)=>{cleanup(),r(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},o=!1,handleOutput=e=>{if(o)return;let r=LOCAL_SERVER_URL_PATTERN.exec(e.toString(`utf8`));r!==null&&(o=!0,cleanup(),n({origin:normalizeOrigin(r[0]),process:i}))};i.once(`error`,handleError),i.once(`exit`,handleEarlyExit),i.stdout.on(`data`,e=>{process.stdout.write(e),handleOutput(e)}),i.stderr.on(`data`,e=>{process.stderr.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{process.off(`beforeExit`,close),process.off(`exit`,close),t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e}).then(e=>(process.env[EVE_BASE_URL_ENV]=e.origin,installProcessShutdown(e)))}async function resolveSharedEveDevServer(e){let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await acquireEveDevServerLock(e);try{let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await startEveDevServer(e);return await writeEveDevServerRegistry(e,n),n}finally{await n()}}export{EVE_BASE_URL_ENV,normalizeDevServerRegistry,resolveSharedEveDevServer};
1
+ import{joinRoutePrefix,normalizeOrigin}from"./routing.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{join}from"node:path";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";import{spawn}from"node:child_process";const EVE_BASE_URL_ENV=`EVE_BASE_URL`,DEFAULT_SERVER_READY_TIMEOUT_MS=3e4,DEV_SERVER_REGISTRY_TIMEOUT_MS=3e4,LOCAL_SERVER_URL_PATTERN=/https?:\/\/(?:\[[^\]\s]+\]|[^\s/:[\]]+)(?::\d+)?/;function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`nuxt-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`nuxt-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let r=new AbortController,i=setTimeout(()=>r.abort(),1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:r.signal})).ok}catch{return!1}finally{clearTimeout(i)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e){let t=resolveEveCacheDirectory(e),n=resolveEveDevServerLockPath(e),r=Date.now()+DEV_SERVER_REGISTRY_TIMEOUT_MS;for(await mkdir(t,{recursive:!0});;)try{let e=await open(n,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(n,{force:!0})}}catch(t){if(!isNodeErrorWithCode(t,`EEXIST`))throw t;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(n),Date.now()>r)throw Error(`Timed out after ${DEV_SERVER_REGISTRY_TIMEOUT_MS}ms waiting for another Nuxt process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function startServerProcess(e){return new Promise((n,r)=>{let i=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),a=setTimeout(()=>{i.kill(),r(Error(`Timed out after ${DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(a),i.off(`error`,handleError),i.off(`exit`,handleEarlyExit)},handleError=e=>{cleanup(),r(e)},handleEarlyExit=(e,t)=>{cleanup(),r(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},o=!1,handleOutput=e=>{if(o)return;let r=LOCAL_SERVER_URL_PATTERN.exec(e.toString(`utf8`));r!==null&&(o=!0,cleanup(),n({origin:normalizeOrigin(r[0]),process:i}))};i.once(`error`,handleError),i.once(`exit`,handleEarlyExit),i.stdout.on(`data`,e=>{process.stdout.write(e),handleOutput(e)}),i.stderr.on(`data`,e=>{process.stderr.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{process.off(`beforeExit`,close),process.off(`exit`,close),t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e}).then(e=>(process.env[EVE_BASE_URL_ENV]=e.origin,installProcessShutdown(e)))}async function resolveSharedEveDevServer(e){let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await acquireEveDevServerLock(e);try{let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await startEveDevServer(e);return await writeEveDevServerRegistry(e,n),n}finally{await n()}}export{EVE_BASE_URL_ENV,normalizeDevServerRegistry,resolveSharedEveDevServer};
@@ -1 +1 @@
1
- import{joinRoutePrefix,normalizeOrigin}from"./routing.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{join}from"node:path";import{spawn}from"node:child_process";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";const EVE_BASE_URL_ENV=`EVE_BASE_URL`,DEFAULT_SERVER_READY_TIMEOUT_MS=3e4,DEV_SERVER_REGISTRY_TIMEOUT_MS=3e4,LOCAL_SERVER_URL_PATTERN=/https?:\/\/(?:\[[^\]\s]+\]|[^\s/:[\]]+)(?::\d+)?/;function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`sveltekit-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`sveltekit-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let r=new AbortController,i=setTimeout(()=>r.abort(),1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:r.signal})).ok}catch{return!1}finally{clearTimeout(i)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e){let t=resolveEveCacheDirectory(e),n=resolveEveDevServerLockPath(e),r=Date.now()+DEV_SERVER_REGISTRY_TIMEOUT_MS;for(await mkdir(t,{recursive:!0});;)try{let e=await open(n,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(n,{force:!0})}}catch(t){if(!isNodeErrorWithCode(t,`EEXIST`))throw t;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(n),Date.now()>r)throw Error(`Timed out after ${DEV_SERVER_REGISTRY_TIMEOUT_MS}ms waiting for another SvelteKit process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function startServerProcess(e){return new Promise((n,r)=>{let i=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),a=setTimeout(()=>{i.kill(),r(Error(`Timed out after ${DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(a),i.off(`error`,handleError),i.off(`exit`,handleEarlyExit)},handleError=e=>{cleanup(),r(e)},handleEarlyExit=(e,t)=>{cleanup(),r(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},o=!1,handleOutput=e=>{if(o)return;let r=LOCAL_SERVER_URL_PATTERN.exec(e.toString(`utf8`));r!==null&&(o=!0,cleanup(),n({origin:normalizeOrigin(r[0]),process:i}))};i.once(`error`,handleError),i.once(`exit`,handleEarlyExit),i.stdout.on(`data`,e=>{process.stdout.write(e),handleOutput(e)}),i.stderr.on(`data`,e=>{process.stderr.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{process.off(`beforeExit`,close),process.off(`exit`,close),t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e}).then(e=>(process.env[EVE_BASE_URL_ENV]=e.origin,installProcessShutdown(e)))}async function resolveSharedEveDevServer(e){let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await acquireEveDevServerLock(e);try{let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await startEveDevServer(e);return await writeEveDevServerRegistry(e,n),n}finally{await n()}}export{EVE_BASE_URL_ENV,normalizeDevServerRegistry,resolveSharedEveDevServer};
1
+ import{joinRoutePrefix,normalizeOrigin}from"./routing.js";import{EVE_ROUTE_PREFIX}from"#protocol/routes.js";import{resolvePackageRoot}from"#internal/application/package.js";import{join}from"node:path";import{mkdir,open,readFile,rm,stat,writeFile}from"node:fs/promises";import{spawn}from"node:child_process";const EVE_BASE_URL_ENV=`EVE_BASE_URL`,DEFAULT_SERVER_READY_TIMEOUT_MS=3e4,DEV_SERVER_REGISTRY_TIMEOUT_MS=3e4,LOCAL_SERVER_URL_PATTERN=/https?:\/\/(?:\[[^\]\s]+\]|[^\s/:[\]]+)(?::\d+)?/;function isNodeErrorWithCode(e,t){return e instanceof Error&&`code`in e&&e.code===t}function delay(e){return new Promise(t=>setTimeout(t,e))}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function resolveEveCacheDirectory(e){return join(e,`.eve`)}function resolveEveDevServerRegistryPath(e){return join(resolveEveCacheDirectory(e),`sveltekit-dev-server.json`)}function resolveEveDevServerLockPath(e){return join(resolveEveCacheDirectory(e),`sveltekit-dev-server.lock`)}function normalizeDevServerRegistry(e){if(isRecord(e)&&!(typeof e.appRoot!=`string`||typeof e.origin!=`string`||typeof e.updatedAt!=`string`)&&!(e.pid!==null&&typeof e.pid!=`number`))try{return{appRoot:e.appRoot,origin:normalizeOrigin(e.origin),pid:e.pid,updatedAt:e.updatedAt}}catch{return}}async function isEveServerHealthy(t){let r=new AbortController,i=setTimeout(()=>r.abort(),1e3);try{return(await fetch(joinRoutePrefix(t,`${EVE_ROUTE_PREFIX}/health`),{signal:r.signal})).ok}catch{return!1}finally{clearTimeout(i)}}async function readUsableEveDevServerRegistry(e){try{let t=normalizeDevServerRegistry(JSON.parse(await readFile(resolveEveDevServerRegistryPath(e),`utf8`)));return t===void 0||t.appRoot!==e||!await isEveServerHealthy(t.origin)?void 0:t.origin}catch(e){if(isNodeErrorWithCode(e,`ENOENT`))return;throw e}}async function writeEveDevServerRegistry(e,t){await mkdir(resolveEveCacheDirectory(e),{recursive:!0}),await writeFile(resolveEveDevServerRegistryPath(e),`${JSON.stringify({appRoot:e,origin:t.origin,pid:t.process?.pid??null,updatedAt:new Date().toISOString()},null,2)}\n`)}async function removeStaleEveDevServerLock(e){try{let t=await stat(e);Date.now()-t.mtimeMs>3e4&&await rm(e,{force:!0})}catch(e){if(!isNodeErrorWithCode(e,`ENOENT`))throw e}}async function acquireEveDevServerLock(e){let t=resolveEveCacheDirectory(e),n=resolveEveDevServerLockPath(e),r=Date.now()+DEV_SERVER_REGISTRY_TIMEOUT_MS;for(await mkdir(t,{recursive:!0});;)try{let e=await open(n,`wx`);return await e.writeFile(`${String(process.pid)}\n`),await e.close(),async()=>{await rm(n,{force:!0})}}catch(t){if(!isNodeErrorWithCode(t,`EEXIST`))throw t;if(await readUsableEveDevServerRegistry(e)!==void 0)return async()=>{};if(await removeStaleEveDevServerLock(n),Date.now()>r)throw Error(`Timed out after ${DEV_SERVER_REGISTRY_TIMEOUT_MS}ms waiting for another SvelteKit process to start eve.`);await delay(100)}}function createEveBinaryPath(){return join(resolvePackageRoot(),`bin`,`eve.js`)}function startServerProcess(e){return new Promise((n,r)=>{let i=spawn(e.command,e.args,{cwd:e.cwd,env:{...process.env,...e.env},stdio:[`ignore`,`pipe`,`pipe`]}),a=setTimeout(()=>{i.kill(),r(Error(`Timed out after ${DEFAULT_SERVER_READY_TIMEOUT_MS}ms waiting for eve to print its server URL.`))},DEFAULT_SERVER_READY_TIMEOUT_MS),cleanup=()=>{clearTimeout(a),i.off(`error`,handleError),i.off(`exit`,handleEarlyExit)},handleError=e=>{cleanup(),r(e)},handleEarlyExit=(e,t)=>{cleanup(),r(Error(`eve server process exited before printing its server URL (code ${String(e)}, signal ${String(t)}).`))},o=!1,handleOutput=e=>{if(o)return;let r=LOCAL_SERVER_URL_PATTERN.exec(e.toString(`utf8`));r!==null&&(o=!0,cleanup(),n({origin:normalizeOrigin(r[0]),process:i}))};i.once(`error`,handleError),i.once(`exit`,handleEarlyExit),i.stdout.on(`data`,e=>{process.stdout.write(e),handleOutput(e)}),i.stderr.on(`data`,e=>{process.stderr.write(e),handleOutput(e)})})}function installProcessShutdown(e){let t=e.process;if(t===void 0)return e;let close=()=>{process.off(`beforeExit`,close),process.off(`exit`,close),t.killed||t.kill()};return process.once(`beforeExit`,close),process.once(`exit`,close),e}function startEveDevServer(e){return startServerProcess({args:[createEveBinaryPath(),`dev`,`--no-ui`,`--port`,`0`],command:process.execPath,cwd:e}).then(e=>(process.env[EVE_BASE_URL_ENV]=e.origin,installProcessShutdown(e)))}async function resolveSharedEveDevServer(e){let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await acquireEveDevServerLock(e);try{let t=await readUsableEveDevServerRegistry(e);if(t!==void 0)return process.env[EVE_BASE_URL_ENV]=t,{origin:t};let n=await startEveDevServer(e);return await writeEveDevServerRegistry(e,n),n}finally{await n()}}export{EVE_BASE_URL_ENV,normalizeDevServerRegistry,resolveSharedEveDevServer};
@@ -42,10 +42,17 @@ export interface UseEveAgentHelpers<TData> extends UseEveAgentSnapshot<TData> {
42
42
  * values to `auth` or `headers`; the client resolves those before each request.
43
43
  */
44
44
  export interface UseEveAgentOptions<TData> extends EveAgentStoreCallbacks<TData> {
45
+ /**
46
+ * Named agent mounted by a framework integration such as `withEve({ agents })`.
47
+ *
48
+ * `agent: "support"` targets same-origin routes under
49
+ * `/eve/agents/support/eve/v1/...`. Do not combine with `host`.
50
+ */
51
+ readonly agent?: string;
45
52
  readonly auth?: ClientAuth;
46
53
  readonly headers?: HeadersValue;
47
54
  /**
48
- * Base URL for eve client requests.
55
+ * Base URL for eve client requests. Do not combine with `agent`.
49
56
  *
50
57
  * Defaults to same-origin eve routes such as `/eve/v1/...`. Pass a same-origin
51
58
  * prefix such as `/api` for an app-owned proxy, or an absolute origin to talk
@@ -1 +1 @@
1
- import{EveAgentStore}from"#client/eve-agent-store.js";import{defaultMessageReducer}from"#client/message-reducer.js";import{useCallback,useMemo,useRef,useSyncExternalStore}from"react";function useEveAgent(n={}){let r=useRef(void 0);if(!r.current){let t=n.reducer??defaultMessageReducer();r.current=new EveAgentStore({auth:n.auth,headers:n.headers,host:n.host,initialEvents:n.initialEvents,initialSession:n.initialSession,maxReconnectAttempts:n.maxReconnectAttempts,optimistic:n.optimistic,reducer:t,session:n.session})}let i=r.current;i.setCallbacks({onError:n.onError,onEvent:n.onEvent,onFinish:n.onFinish,onSessionChange:n.onSessionChange,prepareSend:n.prepareSend});let a=useSyncExternalStore(useCallback(e=>i.subscribe(e),[i]),()=>i.snapshot,()=>i.snapshot),o=useCallback(()=>i.reset(),[i]),s=useCallback(e=>i.send(e),[i]),c=useCallback(()=>i.stop(),[i]);return useMemo(()=>({...a,reset:o,send:s,stop:c}),[o,s,a,c])}export{useEveAgent};
1
+ import{EveAgentStore}from"#client/eve-agent-store.js";import{defaultMessageReducer}from"#client/message-reducer.js";import{useCallback,useMemo,useRef,useSyncExternalStore}from"react";import{resolveEveAgentHost}from"#client/agent-host.js";function useEveAgent(n={}){let r=useRef(void 0);if(!r.current){let t=n.reducer??defaultMessageReducer();r.current=new EveAgentStore({auth:n.auth,headers:n.headers,host:resolveEveAgentHost({agent:n.agent,host:n.host}),initialEvents:n.initialEvents,initialSession:n.initialSession,maxReconnectAttempts:n.maxReconnectAttempts,optimistic:n.optimistic,reducer:t,session:n.session})}let i=r.current;i.setCallbacks({onError:n.onError,onEvent:n.onEvent,onFinish:n.onFinish,onSessionChange:n.onSessionChange,prepareSend:n.prepareSend});let a=useSyncExternalStore(useCallback(e=>i.subscribe(e),[i]),()=>i.snapshot,()=>i.snapshot),o=useCallback(()=>i.reset(),[i]),s=useCallback(e=>i.send(e),[i]),c=useCallback(()=>i.stop(),[i]);return useMemo(()=>({...a,reset:o,send:s,stop:c}),[o,s,a,c])}export{useEveAgent};
@@ -1 +1 @@
1
- import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{WORKFLOW_TOOL_NAME}from"#shared/workflow-sandbox.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createConnectionSearchResolver}from"#runtime/framework-tools/connection-search-dynamic.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";var ResolveRuntimeAgentGraphError=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let a=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),o=a.connections.length>0,s=getFrameworkToolDefinitions({hasConnections:o}),c=new Set(s.map(e=>e.name)),l=getAllFrameworkToolNames(),u=new Set(a.tools.map(e=>e.name));for(let n of a.disabledFrameworkTools)if(!l.has(n))throw new ResolveRuntimeAgentGraphError(`agent/tools/${n}.ts exports disableTool() but "${n}" is not a framework tool. Rename the file to one of: ${[...l].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let d=new Set(a.disabledFrameworkTools),f=await createRuntimeToolRegistry({tools:[...s.filter(e=>!u.has(e.name)&&!d.has(e.name)),...a.tools]},{reservedToolNames:[WORKFLOW_TOOL_NAME,...c.has(LOAD_SKILL_TOOL_NAME)||u.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),p=new Set(a.channels.map(e=>e.name)),m=getAllFrameworkChannelNames();for(let n of a.disabledFrameworkChannels)if(!m.has(n))throw new ResolveRuntimeAgentGraphError(`agent/channels/${n}.ts exports disableRoute() but "${n}" is not a framework channel. Rename the file to one of: ${[...m].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let h=new Set(a.disabledFrameworkChannels),g=[...getFrameworkChannelDefinitions().filter(e=>!p.has(e.name)&&!h.has(e.name)),...a.channels],_=createRuntimeSandboxRegistry({authoredSandbox:a.sandbox,workspaceResourceRoot:a.workspaceResourceRoot}),v=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...f.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),y=o?{...a,dynamicToolResolvers:[...a.dynamicToolResolvers,createConnectionSearchResolver()]}:a,b={agent:y,channels:g,hookRegistry:createRuntimeHookRegistry(y.hooks),nodeId:t,sandboxRegistry:_,sourceId:e.sourceId,subagentRegistry:v,toolRegistry:f,turnAgent:createResolvedRuntimeTurnAgent({agent:y,nodeId:t,tools:[...f.preparedTools,...v.preparedTools]})};return e.nodesByNodeId.set(t,b),b}async function resolveRuntimeSubagents(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),outputSchema:t.sourceRef.outputSchema,path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:t.sourceRef.url};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}export{resolveRuntimeAgentGraph};
1
+ import{expectObjectRecord}from"#internal/authored-module.js";import{ROOT_COMPILED_AGENT_NODE_ID}from"#compiler/manifest.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{createRuntimeToolRegistry}from"#runtime/tools/registry.js";import{createRuntimeSubagentRegistry}from"#runtime/subagents/registry.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{WORKFLOW_TOOL_NAME}from"#shared/workflow-sandbox.js";import{getAllFrameworkChannelNames,getFrameworkChannelDefinitions}from"#runtime/framework-channels/index.js";import{getAllFrameworkToolNames,getFrameworkToolDefinitions}from"#runtime/framework-tools/index.js";import{createConnectionSearchResolver}from"#runtime/framework-tools/connection-search-dynamic.js";import{resolveAgent}from"#runtime/resolve-agent.js";import{loadResolvedModuleExport}from"#runtime/resolve-helpers.js";import{createResolvedRuntimeTurnAgent}from"#runtime/agent/bootstrap.js";import{createRuntimeHookRegistry}from"#runtime/hooks/registry.js";import{createRuntimeSandboxRegistry}from"#runtime/sandbox/registry.js";var ResolveRuntimeAgentGraphError=class extends Error{logicalPath;nodeId;sourceId;constructor(e,t={}){super(e),this.name=`ResolveRuntimeAgentGraphError`,t.logicalPath!==void 0&&(this.logicalPath=t.logicalPath),t.nodeId!==void 0&&(this.nodeId=t.nodeId),t.sourceId!==void 0&&(this.sourceId=t.sourceId)}};async function resolveRuntimeAgentGraph(e){let n=new Map,r=createChildNodeIdsByParentNodeId(e.manifest),i=new Map(e.manifest.subagents.map(e=>[e.nodeId,e]));return{nodesByNodeId:n,root:await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:r,manifest:e.manifest,moduleMap:e.moduleMap,nodeId:ROOT_COMPILED_AGENT_NODE_ID,nodesByNodeId:n,subagentNodesById:i})}}async function resolveRuntimeAgentNode(e){let t=toRuntimeNodeId(e.nodeId);if(e.nodesByNodeId.has(t))throw new ResolveRuntimeAgentGraphError(`Found multiple runtime agent nodes for node id "${t}".`,{nodeId:t,sourceId:e.sourceId});let a=await resolveAgent({manifest:e.manifest,moduleMap:e.moduleMap,nodeId:e.nodeId}),o=a.connections.length>0,s=getFrameworkToolDefinitions({hasConnections:o}),c=new Set(s.map(e=>e.name)),l=getAllFrameworkToolNames(),u=new Set(a.tools.map(e=>e.name));for(let n of a.disabledFrameworkTools)if(!l.has(n))throw new ResolveRuntimeAgentGraphError(`agent/tools/${n}.ts exports disableTool() but "${n}" is not a framework tool. Rename the file to one of: ${[...l].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let d=new Set(a.disabledFrameworkTools),f=await createRuntimeToolRegistry({tools:[...s.filter(e=>!u.has(e.name)&&!d.has(e.name)),...a.tools]},{reservedToolNames:[WORKFLOW_TOOL_NAME,...c.has(LOAD_SKILL_TOOL_NAME)||u.has(LOAD_SKILL_TOOL_NAME)?[]:[LOAD_SKILL_TOOL_NAME]]}),p=new Set(a.channels.map(e=>e.name)),m=getAllFrameworkChannelNames();for(let n of a.disabledFrameworkChannels)if(!m.has(n))throw new ResolveRuntimeAgentGraphError(`agent/channels/${n}.ts exports disableRoute() but "${n}" is not a framework channel. Rename the file to one of: ${[...m].sort().join(`, `)}.`,{nodeId:t,sourceId:e.sourceId});let h=new Set(a.disabledFrameworkChannels),g=[...getFrameworkChannelDefinitions().filter(e=>!p.has(e.name)&&!h.has(e.name)),...a.channels],_=createRuntimeSandboxRegistry({authoredSandbox:a.sandbox,workspaceResourceRoot:a.workspaceResourceRoot}),v=createRuntimeSubagentRegistry({reservedToolNames:[LOAD_SKILL_TOOL_NAME,...f.preparedTools.map(e=>e.name)],subagents:await resolveRuntimeSubagents({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.manifest,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,parentNodeId:e.nodeId,subagentNodesById:e.subagentNodesById})}),y=o?{...a,dynamicToolResolvers:[...a.dynamicToolResolvers,createConnectionSearchResolver()]}:a,b={agent:y,channels:g,hookRegistry:createRuntimeHookRegistry(y.hooks),nodeId:t,sandboxRegistry:_,sourceId:e.sourceId,subagentRegistry:v,toolRegistry:f,turnAgent:createResolvedRuntimeTurnAgent({agent:y,nodeId:t,tools:[...f.preparedTools,...v.preparedTools]})};return e.nodesByNodeId.set(t,b),b}async function resolveRuntimeSubagents(e){let t=[],n=e.childNodeIdsByParentNodeId.get(e.parentNodeId)??[];for(let r of n){let n=e.subagentNodesById.get(r);if(n===void 0)throw new ResolveRuntimeAgentGraphError(`Missing compiled subagent node "${r}" while resolving runtime subagents.`,{nodeId:toRuntimeNodeId(e.parentNodeId),sourceId:r});t.push(await resolveRuntimeSubagent({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,moduleMap:e.moduleMap,nodesByNodeId:e.nodesByNodeId,sourceRef:n,subagentNodesById:e.subagentNodesById}))}for(let n of e.manifest.remoteAgents)t.push(await resolveRuntimeRemoteAgent({moduleMap:e.moduleMap,nodeScopeId:e.parentNodeId,sourceRef:n}));return t}async function resolveRuntimeSubagent(e){let t={description:e.sourceRef.description,kind:`subagent`,logicalPath:e.sourceRef.logicalPath,name:e.sourceRef.name,nodeId:toRuntimeNodeId(e.sourceRef.nodeId),sourceId:e.sourceRef.sourceId,sourceKind:`module`};return await resolveRuntimeAgentNode({childNodeIdsByParentNodeId:e.childNodeIdsByParentNodeId,manifest:e.sourceRef.agent,moduleMap:e.moduleMap,nodeId:e.sourceRef.nodeId,nodesByNodeId:e.nodesByNodeId,sourceId:e.sourceRef.sourceId,subagentNodesById:e.subagentNodesById}),t}async function resolveRuntimeRemoteAgent(t){let n=expectObjectRecord(await loadResolvedModuleExport({definition:t.sourceRef,kindLabel:`remote agent`,moduleMap:t.moduleMap,nodeId:t.nodeScopeId}),`Expected remote agent source "${t.sourceRef.logicalPath}" to export an object.`),r={description:t.sourceRef.description,kind:`remote`,logicalPath:t.sourceRef.logicalPath,name:t.sourceRef.name,nodeId:toRuntimeNodeId(t.sourceRef.nodeId),outputSchema:t.sourceRef.outputSchema,path:t.sourceRef.path,sourceId:t.sourceRef.sourceId,sourceKind:`module`,url:await resolveRemoteAgentUrl({bakedUrl:t.sourceRef.url,logicalPath:t.sourceRef.logicalPath,resolvedUrl:n.url})};typeof n.auth==`function`&&(r.auth=n.auth);let i=resolveRemoteAgentHeaders(n.headers);return i!==void 0&&(r.headers=i),r}async function resolveRemoteAgentUrl(e){if(typeof e.resolvedUrl==`function`){let t=await e.resolvedUrl();if(typeof t!=`string`||t.length===0)throw Error(`Remote agent "${e.logicalPath}" url function must return a non-empty string.`);return t}let t=e.bakedUrl??(typeof e.resolvedUrl==`string`?e.resolvedUrl:``);if(t.length===0)throw Error(`Remote agent "${e.logicalPath}" is missing a url.`);return t}function resolveRemoteAgentHeaders(e){if(e===void 0)return;if(typeof e==`function`)return e;if(typeof e!=`object`||!e||Array.isArray(e))return;let t={};for(let[n,r]of Object.entries(e))typeof r==`string`&&(t[n]=r);return t}function createChildNodeIdsByParentNodeId(e){let t=new Map;for(let n of e.subagentEdges){let e=t.get(n.parentNodeId);if(e===void 0){t.set(n.parentNodeId,[n.childNodeId]);continue}e.push(n.childNodeId)}return t}function toRuntimeNodeId(e){return e===ROOT_COMPILED_AGENT_NODE_ID?ROOT_RUNTIME_AGENT_NODE_ID:e}export{resolveRuntimeAgentGraph};
@@ -1 +1 @@
1
- import{connectionEntries,connectionProtocols}from"../../../packages/eve-catalog/src/index.js";const SUPPORTED_PROTOCOLS=[`mcp`],CUSTOM_CONNECTION_SLUG=`custom`,CONNECTION_AUTH={linear:{kind:`connect`,connector:`linear`,service:`mcp.linear.app`},notion:{kind:`connect`,connector:`notion`,service:`mcp.notion.com`},datadog:{kind:`connect`,connector:`datadog`,service:`mcp.datadoghq.com`},honeycomb:{kind:`connect`,connector:`honeycomb`,service:`mcp.honeycomb.io`}};function buildCatalogEntry(e,n,r){let i=CONNECTION_AUTH[e];if(i===void 0)throw Error(`Connection "${e}" is in the catalog but has no scaffolder auth overlay.`);let a={slug:e,label:n,protocols:connectionProtocols(r),description:r.description,auth:i};return r.mcp&&(a.mcp={url:r.mcp.url}),r.openapi&&(a.openapi={spec:r.openapi.spec,baseUrl:r.openapi.baseUrl}),a}const CONNECTION_CATALOG=connectionEntries().map(e=>{if(e.connection===void 0)throw Error(`Catalog connection "${e.slug}" is missing its connection identity.`);return buildCatalogEntry(e.slug,e.name,e.connection)}),CATALOG_BY_SLUG=new Map(CONNECTION_CATALOG.map(e=>[e.slug,e]));function getCatalogEntry(e){return CATALOG_BY_SLUG.get(e)}function catalogSlugs(){return CONNECTION_CATALOG.map(e=>e.slug)}function effectiveProtocols(e){let t=e===void 0||e.length===0?SUPPORTED_PROTOCOLS:e;return SUPPORTED_PROTOCOLS.filter(e=>t.includes(e))}const CONNECTION_SLUG_PATTERN=/^[a-z][a-z0-9-]{0,63}$/;function isValidConnectionSlug(e){return CONNECTION_SLUG_PATTERN.test(e)}function connectorServiceForEntry(e){if(e.auth.kind===`connect`)return e.auth.service?e.auth.service:mcpServiceHost(e.mcp?.url)}function canonicalConnectorNameForEntry(e){if(e.auth?.kind!==`connect`)return;let t=e.auth.connector.trim();return t.length>0?t:void 0}function mcpServiceHost(e){if(e)try{return new URL(e).host||void 0}catch{return}}function endpointForProtocol(e,t){return t===`mcp`?e.mcp??null:e.openapi??null}export{CONNECTION_CATALOG,CUSTOM_CONNECTION_SLUG,SUPPORTED_PROTOCOLS,canonicalConnectorNameForEntry,catalogSlugs,connectorServiceForEntry,effectiveProtocols,endpointForProtocol,getCatalogEntry,isValidConnectionSlug,mcpServiceHost};
1
+ import{connectionEntries,connectionProtocols}from"../../../packages/eve-catalog/src/index.js";const SUPPORTED_PROTOCOLS=[`mcp`],CUSTOM_CONNECTION_SLUG=`custom`,CONNECTION_AUTH={linear:{kind:`connect`,connector:`linear`,service:`mcp.linear.app`},notion:{kind:`connect`,connector:`notion`,service:`mcp.notion.com`},datadog:{kind:`connect`,connector:`datadog`,service:`mcp.datadoghq.com`},honeycomb:{kind:`connect`,connector:`honeycomb`,service:`mcp.honeycomb.io`}};function buildCatalogEntry(e,n,r){let i=CONNECTION_AUTH[e];if(i===void 0)throw Error(`Connection "${e}" is in the catalog but has no scaffolder auth overlay.`);let a={slug:e,label:n,protocols:connectionProtocols(r),description:r.description,auth:i};return r.mcp&&(a.mcp={url:r.mcp.url}),r.openapi&&(a.openapi={spec:r.openapi.spec,baseUrl:r.openapi.baseUrl}),a}const CONNECTION_CATALOG=connectionEntries().filter(e=>e.surfaces.scaffoldable).map(e=>{if(e.connection===void 0)throw Error(`Catalog connection "${e.slug}" is missing its connection identity.`);return buildCatalogEntry(e.slug,e.name,e.connection)}),CATALOG_BY_SLUG=new Map(CONNECTION_CATALOG.map(e=>[e.slug,e]));function getCatalogEntry(e){return CATALOG_BY_SLUG.get(e)}function catalogSlugs(){return CONNECTION_CATALOG.map(e=>e.slug)}function effectiveProtocols(e){let t=e===void 0||e.length===0?SUPPORTED_PROTOCOLS:e;return SUPPORTED_PROTOCOLS.filter(e=>t.includes(e))}const CONNECTION_SLUG_PATTERN=/^[a-z][a-z0-9-]{0,63}$/;function isValidConnectionSlug(e){return CONNECTION_SLUG_PATTERN.test(e)}function connectorServiceForEntry(e){if(e.auth.kind===`connect`)return e.auth.service?e.auth.service:mcpServiceHost(e.mcp?.url)}function canonicalConnectorNameForEntry(e){if(e.auth?.kind!==`connect`)return;let t=e.auth.connector.trim();return t.length>0?t:void 0}function mcpServiceHost(e){if(e)try{return new URL(e).host||void 0}catch{return}}function endpointForProtocol(e,t){return t===`mcp`?e.mcp??null:e.openapi??null}export{CONNECTION_CATALOG,CUSTOM_CONNECTION_SLUG,SUPPORTED_PROTOCOLS,canonicalConnectorNameForEntry,catalogSlugs,connectorServiceForEntry,effectiveProtocols,endpointForProtocol,getCatalogEntry,isValidConnectionSlug,mcpServiceHost};
@@ -0,0 +1,30 @@
1
+ import type { PackageManagerKind } from "../../package-manager.js";
2
+ import { type WorkspaceRootMutation } from "../workspace-root.js";
3
+ import { type EvePackageContract } from "./project.js";
4
+ export interface ScaffoldExtensionProjectOptions {
5
+ projectName: string;
6
+ /**
7
+ * The manager that owns command execution and manager-specific generated
8
+ * project files for this scaffold. Defaults to pnpm.
9
+ */
10
+ packageManager?: PackageManagerKind;
11
+ targetDirectory?: string;
12
+ overwriteExisting?: boolean;
13
+ onOverwriteFile?: (filePath: string) => void | Promise<void>;
14
+ evePackage?: EvePackageContract;
15
+ zodPackageVersion?: string;
16
+ typescriptPackageVersion?: string;
17
+ /**
18
+ * Final project path used to discover ancestor workspaces. This differs from
19
+ * the write target only when the CLI stages a scaffold before moving it into
20
+ * place.
21
+ */
22
+ workspaceProbeDirectory?: string;
23
+ onWorkspaceRootMutation?: (mutation: WorkspaceRootMutation) => void | Promise<void>;
24
+ }
25
+ /**
26
+ * Scaffolds a standalone eve extension package: `extension/extension.ts`, package
27
+ * metadata (`eve.extension`, peer+dev `eve`, zod), and TypeScript config. Does
28
+ * not write sample tools — authors add contributions under `extension/` themselves.
29
+ */
30
+ export declare function scaffoldExtensionProject(options: ScaffoldExtensionProjectOptions): Promise<string>;
@@ -0,0 +1,34 @@
1
+ import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{resolveVersionToken}from"../version-tokens.js";import{applyPackageManagerWorkspaceConfiguration,isPackageManagerWorkspaceMember,patchWorkspaceRootPackageJson}from"../workspace-root.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX,formatEveDependencySpecifier,resolveEvePackageContract}from"./project.js";import{basename,resolve}from"node:path";import{mkdir,readdir}from"node:fs/promises";const ALLOWED_CREATE_IN_PLACE_ENTRIES=new Set([`.DS_Store`,`.git`,`.gitkeep`,`.hg`]);function renderTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t.appName).replaceAll(`__EVE_INIT_PACKAGE_VERSION__`,formatEveDependencySpecifier(t.eveVersion)).replaceAll(`__EVE_INIT_ZOD_VERSION__`,t.zodPackageVersion).replaceAll(`__EVE_INIT_TYPESCRIPT_VERSION__`,t.typescriptPackageVersion).replaceAll(`__EVE_INIT_TYPES_NODE_VERSION__`,t.nodeTypesVersion).replaceAll(`__EVE_INIT_NODE_ENGINE__`,t.nodeEngine)}function packageJsonTemplate(e){return`${JSON.stringify({name:`__EVE_INIT_APP_NAME__`,version:`0.0.0`,type:`module`,eve:{extension:`./extension`},files:[`extension`,`dist`],exports:{".":`./extension/extension.ts`},scripts:{build:`eve extension build`,prepare:`eve extension build`,typecheck:`tsc`},dependencies:{zod:`__EVE_INIT_ZOD_VERSION__`},devDependencies:{"@types/node":`__EVE_INIT_TYPES_NODE_VERSION__`,eve:`__EVE_INIT_PACKAGE_VERSION__`,typescript:`__EVE_INIT_TYPESCRIPT_VERSION__`},peerDependencies:{eve:`__EVE_INIT_PACKAGE_VERSION__`}},null,2).slice(0,-1)}${e?ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX:``}}\n`}function templateFiles(e){return{"extension/extension.ts":`import { defineExtension } from "eve/extension";
2
+ import { z } from "zod";
3
+
4
+ export default defineExtension({
5
+ config: z.object({
6
+ // Replace with the settings consumers pass at the mount site.
7
+ apiKey: z.string(),
8
+ }),
9
+ });
10
+ `,"tsconfig.json":`{
11
+ "compilerOptions": {
12
+ "target": "ES2022",
13
+ "module": "esnext",
14
+ "moduleResolution": "bundler",
15
+ "types": ["node"],
16
+ "strict": true,
17
+ "esModuleInterop": true,
18
+ "skipLibCheck": true,
19
+ "noEmit": true
20
+ },
21
+ "include": ["extension/**/*.ts"]
22
+ }
23
+ `,".gitignore":`node_modules
24
+ .env*
25
+ .eve
26
+ .vercel
27
+ .workflow-data
28
+ .output
29
+ .nitro
30
+ dist
31
+ .DS_Store
32
+ *.tsbuildinfo
33
+ `,"AGENTS.md":"# eve Extension Package\n\nThis package is an eve extension — a reusable package of tools, connections,\nskills, hooks, and instruction fragments that a consuming agent mounts under\n`agent/extensions/`.\n\nBefore writing code, read the Extensions guide from the installed eve package\ndocs. In most installs, those docs are at `node_modules/eve/docs/extensions.md`.\nIn workspaces or local package installs, resolve the installed `eve` package\nlocation first and read its `docs/extensions.md`. If package docs are\nunavailable, use https://eve.dev/docs/extensions as a fallback.\n\n## Authoring\n\n- Declare the extension in `extension/extension.ts` with `defineExtension` from\n `eve/extension`. Config is optional; read bound values via the handle's\n `.config` in tools and hooks.\n- Add contributions under `extension/` the same way as in an agent:\n `tools/`, `connections/`, `skills/`, `hooks/`, and optional instruction\n fragments. Names come from file paths; the mount supplies the namespace, so\n name tools for what they do (`search`, not `crm_search`).\n- An extension cannot declare `agent.ts`, `sandbox`, `schedules`, or nested\n `extensions/` — those belong to the consuming agent.\n\n## Build and publish\n\n`eve extension build` (wired to `build`/`prepare`) compiles the mount factory\nand tool re-exports into `dist/` and fills the package `exports` map. Ship both\n`extension/` (source the consumer recompiles) and `dist/`. Keep `eve` as a peer\ndependency so the consumer's eve is the one that runs.\n","CLAUDE.md":`@AGENTS.md
34
+ `,"package.json":packageJsonTemplate(e)}}async function assertCanCreateInPlace(e,n){if(!await pathExists(e))return;let r=(await readdir(e)).filter(e=>!ALLOWED_CREATE_IN_PLACE_ENTRIES.has(e));if(r.length>0&&!n){let e=r.slice(0,5).join(`, `),t=r.length>5?`, and ${r.length-5} more`:``;throw Error(`Cannot create project in current directory because it is not empty. Found: ${e}${t}. Use an empty directory.`)}}async function scaffoldExtensionProject(o){let s=resolve(o.targetDirectory??process.cwd(),o.projectName),c=o.projectName===`.`,l=o.overwriteExisting??!1,u=o.packageManager??`pnpm`,d=resolveEvePackageContract(o.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT),f=pinnedNodeEngineMajor(d.nodeEngine),p=resolve(o.workspaceProbeDirectory??s),m=isPackageManagerWorkspaceMember(u,p);if(c)await assertCanCreateInPlace(s,l);else if(await pathExists(s))throw Error(`Cannot create project because "${s}" already exists.`);let h={appName:basename(s),eveVersion:d.version,zodPackageVersion:resolveVersionToken(`zodPackageVersion`,o.zodPackageVersion??`4.4.3`),typescriptPackageVersion:resolveVersionToken(`typescriptPackageVersion`,o.typescriptPackageVersion??`7.0.2`),nodeTypesVersion:f,nodeEngine:f};await mkdir(s,{recursive:!0});for(let[e,r]of Object.entries(templateFiles(!m))){let i=`${s}/${e}`,a=await pathExists(i);await writeTextFile(i,renderTemplate(r,h),{force:c&&l}),a&&await o.onOverwriteFile?.(i)}return await applyPackageManagerWorkspaceConfiguration({packageManager:u,projectRoot:s,workspaceProbeRoot:p,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),await patchWorkspaceRootPackageJson(u,p,{nodeEngineRequirement:d.nodeEngine,onWorkspaceRootMutation:o.onWorkspaceRootMutation}),s}export{scaffoldExtensionProject};
@@ -42,6 +42,8 @@ export declare function byokProviderEnvVar(modelId: string): string;
42
42
  */
43
43
  export declare function agentTemplateFiles(model: string): Record<string, string>;
44
44
  export declare function formatEveDependencySpecifier(versionOrSpecifier: string): string;
45
+ /** Trailing fields only written when the scaffold is not a workspace member. */
46
+ export declare const ROOT_ONLY_PACKAGE_JSON_TEMPLATE_SUFFIX = ",\n \"engines\": {\n \"node\": \"__EVE_INIT_NODE_ENGINE__\"\n }\n";
45
47
  export interface ScaffoldBaseProjectOptions {
46
48
  projectName: string;
47
49
  model: string;