eve 0.15.4 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/src/chunks/{use-eve-agent-8X2UMr8q.js → use-eve-agent-BEOUv37s.js} +70 -0
  3. package/dist/src/chunks/{use-eve-agent-9ZNiSFMb.js → use-eve-agent-C25KOe9i.js} +70 -0
  4. package/dist/src/cli/commands/init.js +1 -1
  5. package/dist/src/cli/dev/tui/agent-header.js +1 -1
  6. package/dist/src/cli/dev/tui/blocks.js +8 -8
  7. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  8. package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
  9. package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
  10. package/dist/src/cli/dev/tui/runner.d.ts +10 -3
  11. package/dist/src/cli/dev/tui/runner.js +1 -1
  12. package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -1
  13. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  14. package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
  15. package/dist/src/cli/dev/tui/setup-issues.d.ts +2 -14
  16. package/dist/src/cli/dev/tui/setup-issues.js +1 -1
  17. package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -8
  18. package/dist/src/cli/dev/tui/setup-panel.js +3 -3
  19. package/dist/src/cli/dev/tui/terminal-renderer.js +6 -6
  20. package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
  21. package/dist/src/cli/dev/tui/tui.d.ts +2 -3
  22. package/dist/src/cli/dev/tui/tui.js +1 -1
  23. package/dist/src/cli/dev/ui-options.d.ts +21 -0
  24. package/dist/src/cli/dev/ui-options.js +1 -0
  25. package/dist/src/cli/run.d.ts +6 -42
  26. package/dist/src/cli/run.js +2 -2
  27. package/dist/src/client/authorization-message-parts.d.ts +4 -0
  28. package/dist/src/client/authorization-message-parts.js +1 -0
  29. package/dist/src/client/index.d.ts +2 -2
  30. package/dist/src/client/message-reducer-types.d.ts +40 -1
  31. package/dist/src/client/message-reducer.d.ts +3 -5
  32. package/dist/src/client/message-reducer.js +1 -1
  33. package/dist/src/compiled/.vendor-stamp.json +1 -1
  34. package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +71 -1
  35. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  36. package/dist/src/harness/emission.d.ts +3 -3
  37. package/dist/src/harness/emission.js +1 -1
  38. package/dist/src/harness/stream-actions.d.ts +17 -0
  39. package/dist/src/harness/stream-actions.js +1 -0
  40. package/dist/src/internal/application/package.js +1 -1
  41. package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
  42. package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +1 -0
  43. package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
  44. package/dist/src/internal/nitro/host/start-development-server.d.ts +8 -0
  45. package/dist/src/internal/nitro/host/start-development-server.js +2 -2
  46. package/dist/src/internal/nitro/host.d.ts +1 -1
  47. package/dist/src/internal/nitro/host.js +1 -1
  48. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  49. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +0 -3
  50. package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -1
  51. package/dist/src/internal/nitro/routes/info.js +1 -1
  52. package/dist/src/internal/vercel/project-link.d.ts +10 -0
  53. package/dist/src/internal/vercel/project-link.js +1 -0
  54. package/dist/src/protocol/message.d.ts +14 -10
  55. package/dist/src/public/channels/auth.d.ts +26 -13
  56. package/dist/src/public/channels/auth.js +1 -1
  57. package/dist/src/react/index.d.ts +1 -1
  58. package/dist/src/runtime/agent/mock-model-adapter.d.ts +3 -2
  59. package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
  60. package/dist/src/runtime/connections/principal.d.ts +2 -0
  61. package/dist/src/runtime/connections/principal.js +1 -1
  62. package/dist/src/runtime/connections/types.d.ts +4 -1
  63. package/dist/src/runtime/framework-channels/index.d.ts +1 -6
  64. package/dist/src/runtime/framework-channels/index.js +1 -1
  65. package/dist/src/runtime/governance/auth/oidc.js +1 -1
  66. package/dist/src/runtime/governance/auth/types.d.ts +14 -10
  67. package/dist/src/runtime/governance/auth/vercel-oidc-project.d.ts +12 -0
  68. package/dist/src/runtime/governance/auth/vercel-oidc-project.js +1 -0
  69. package/dist/src/services/dev-client/client-options.d.ts +5 -0
  70. package/dist/src/services/dev-client/client-options.js +1 -1
  71. package/dist/src/services/dev-client/request-headers.d.ts +8 -0
  72. package/dist/src/services/dev-client/request-headers.js +1 -1
  73. package/dist/src/services/dev-client/runtime-artifacts.d.ts +1 -0
  74. package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
  75. package/dist/src/services/dev-client.d.ts +8 -0
  76. package/dist/src/services/dev-client.js +1 -1
  77. package/dist/src/setup/boxes/add-connections.d.ts +10 -8
  78. package/dist/src/setup/boxes/add-connections.js +1 -1
  79. package/dist/src/setup/boxes/resolve-provisioning.d.ts +1 -0
  80. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  81. package/dist/src/setup/cli/channel-setup-prompter.d.ts +9 -2
  82. package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
  83. package/dist/src/setup/cli/index.d.ts +1 -1
  84. package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
  85. package/dist/src/setup/cli/select-state.js +1 -1
  86. package/dist/src/setup/connection-connector.d.ts +26 -52
  87. package/dist/src/setup/connection-connector.js +2 -1
  88. package/dist/src/setup/flows/channels.js +1 -1
  89. package/dist/src/setup/flows/connections.d.ts +36 -0
  90. package/dist/src/setup/flows/connections.js +3 -0
  91. package/dist/src/setup/flows/link.d.ts +1 -0
  92. package/dist/src/setup/flows/link.js +1 -1
  93. package/dist/src/setup/project-resolution.d.ts +2 -8
  94. package/dist/src/setup/project-resolution.js +1 -1
  95. package/dist/src/setup/prompter.d.ts +2 -0
  96. package/dist/src/setup/scaffold/connections/catalog.d.ts +10 -5
  97. package/dist/src/setup/scaffold/connections/catalog.js +1 -1
  98. package/dist/src/setup/scaffold/create/project.js +11 -11
  99. package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
  100. package/dist/src/setup/scaffold/create/web-template.js +107 -3
  101. package/dist/src/setup/scaffold/index.d.ts +1 -1
  102. package/dist/src/setup/scaffold/index.js +1 -1
  103. package/dist/src/setup/scaffold/update/connections.d.ts +6 -0
  104. package/dist/src/setup/scaffold/update/connections.js +3 -3
  105. package/dist/src/svelte/index.d.ts +1 -1
  106. package/dist/src/svelte/index.js +1 -1
  107. package/dist/src/svelte/use-eve-agent.js +1 -1
  108. package/dist/src/vue/index.d.ts +1 -1
  109. package/dist/src/vue/index.js +1 -1
  110. package/dist/src/vue/use-eve-agent.js +1 -1
  111. package/docs/channels/eve.mdx +3 -3
  112. package/docs/concepts/sessions-runs-and-streaming.md +1 -1
  113. package/docs/guides/auth-and-route-protection.md +5 -5
  114. package/docs/guides/dev-tui.md +11 -4
  115. package/docs/guides/frontend/nextjs.mdx +2 -2
  116. package/docs/guides/frontend/nuxt.mdx +2 -2
  117. package/docs/guides/frontend/overview.mdx +34 -4
  118. package/docs/guides/frontend/sveltekit.mdx +2 -2
  119. package/docs/reference/cli.md +3 -1
  120. package/docs/tutorial/ship-it.mdx +1 -1
  121. package/docs/tutorial/team-playbooks.mdx +1 -1
  122. package/package.json +2 -2
  123. package/dist/src/internal/nitro/host/dev-rebuild-registry.d.ts +0 -5
  124. package/dist/src/internal/nitro/host/dev-rebuild-registry.js +0 -1
@@ -1 +1 @@
1
- import{existsSync}from"node:fs";import{dirname,join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{AUTHORED_ARTIFACTS_UPDATED_LOG_LINE,STRUCTURAL_RELOAD_LOG_LINE,formatChangeDetectedLogLine}from"#internal/nitro/host/dev-watcher-log.js";import{clearCompiledRuntimeAgentBundleCache}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDevelopmentSourceSnapshotWatchPaths}from"#internal/nitro/dev-runtime-source-snapshot.js";import{resolveTsConfigDependencyPaths}from"#internal/application/tsconfig-dependencies.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{computeChannelRouteRegistrations,syncChannelVirtualHandlers}from"#internal/nitro/host/channel-routes.js";import{watch}from"#compiled/chokidar/index.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{registerDevelopmentRebuildHandle}from"#internal/nitro/host/dev-rebuild-registry.js";const WATCHED_LOCKFILE_NAMES=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],WATCH_ROOT_MARKER_NAMES=[`.git`,`pnpm-workspace.yaml`],WATCHER_IGNORED_DIRECTORY_NAMES=new Set([`.generated`,`.eve`,`.git`,`.next`,`.output`,`.turbo`,`.vercel`,`.workflow-data`,`build`,`dist`,`node_modules`]);async function startAuthoredSourceWatcher(e){let t=e.preparedHost,n=!1,r=Promise.resolve(),i,o=!1,s=new Map,c=new Set,d=await resolveAuthoredWatchPaths(t),f=createWatchPathMap(d),p=watch(d,{awaitWriteFinish:{pollInterval:50,stabilityThreshold:160},followSymlinks:!1,ignoreInitial:!0,ignored:shouldIgnoreWatcherPath}),m=waitForWatcherReady(p),flush=async()=>{n||(i!==void 0&&(clearTimeout(i),i=void 0),r=r.then(async()=>{if(n)return;let r=[...s.values()];if(r.length===0)return;let i=[...c];s.clear(),c.clear();let o=t,l=hasSandboxRelatedChange(o.compileResult.project.agentRoot,i),u=hasDevelopmentEnvironmentFileChange(o.appRoot,i);console.log(formatChangeDetectedLogLine(o.appRoot,r));try{u&&loadDevelopmentEnvironmentFiles(o.appRoot);let n=await prepareApplicationHost(o.appRoot,{dev:e.nitro.options.dev===!0}),r=createNitroArtifactsConfig({appRoot:n.appRoot,dev:e.nitro.options.dev===!0});l&&startDevelopmentSandboxPrewarmInBackground({appRoot:n.appRoot,compiledArtifactsSource:resolveNitroCompiledArtifactsSource(r),log:e=>console.log(e)});let i=syncChannelVirtualHandlers(e.nitro,{artifactsConfig:r,next:computeChannelRouteRegistrations(n),previous:computeChannelRouteRegistrations(o)});clearCompiledRuntimeAgentBundleCache(),t=n,i||u?(console.log(STRUCTURAL_RELOAD_LOG_LINE),await e.nitro.hooks.callHook(`rollup:reload`)):console.log(AUTHORED_ARTIFACTS_UPDATED_LOG_LINE),f=syncWatcherPaths({nextWatchPaths:await resolveAuthoredWatchPaths(n),previousWatchPathsByKey:f,watcher:p})}catch(e){console.error(`[eve:dev] rebuild failed: ${toErrorMessage(e)}`)}}).catch(e=>{console.error(`[eve:dev] rebuild queue error: ${toErrorMessage(e)}`)}),await r)},h=registerDevelopmentRebuildHandle(t.appRoot,{flush});return p.on(`all`,(e,t)=>{n||!o||(s.set(`${e}:${t}`,{event:e,path:t}),c.add(t),i!==void 0&&clearTimeout(i),i=setTimeout(()=>{i=void 0,flush()},120))}),await m,o=!0,{async close(){n=!0,h(),i!==void 0&&(clearTimeout(i),i=void 0),await p.close(),await r},flush}}async function waitForWatcherReady(e){await new Promise((t,n)=>{e.on(`ready`,()=>{t()}),e.on(`error`,e=>{n(e)})})}async function resolveAuthoredWatchPaths(e){let t=new Set([e.compileResult.project.agentRoot,join(e.appRoot,`package.json`),join(e.appRoot,`jsconfig.json`),join(e.appRoot,`tsconfig.json`),join(e.appRoot,`tsconfig.*.json`)]),r=await resolveTsConfigWatchPaths(e.appRoot),i=await resolveDevelopmentSourceSnapshotWatchPaths(e.appRoot);for(let n of getDevelopmentEnvironmentFilePaths(e.appRoot))t.add(n);for(let e of i)t.add(e);for(let e of r)t.add(e);for(let r of resolveLockfileSearchDirectories(e.appRoot))for(let e of WATCHED_LOCKFILE_NAMES)t.add(join(r,e));return[...t].sort((e,t)=>e.localeCompare(t))}function createWatchPathMap(e){let t=new Map;for(let n of e)t.set(toWatchPathKey(n),n);return t}function syncWatcherPaths(e){let t=createWatchPathMap(e.nextWatchPaths),n=[],r=[];for(let[r,i]of t)e.previousWatchPathsByKey.has(r)||n.push(i);for(let[n,i]of e.previousWatchPathsByKey)t.has(n)||r.push(i);return n.length>0&&e.watcher.add(n),r.length>0&&e.watcher.unwatch(r),t}function toWatchPathKey(e){return e.replaceAll(`\\`,`/`)}function hasDevelopmentEnvironmentFileChange(e,t){let n=new Set(getDevelopmentEnvironmentFilePaths(e).map(e=>toWatchPathKey(resolve(e))));return t.some(e=>n.has(toWatchPathKey(resolve(e))))}function hasSandboxRelatedChange(e,t){return t.some(t=>{let n=toAgentRelativePath(e,t);return n===`sandbox.ts`||n.startsWith(`sandbox/`)||n===`workspace`||n.startsWith(`workspace/`)||n===`skills`||n.startsWith(`skills/`)})}function toAgentRelativePath(e,t){let n=toWatchPathKey(relative(resolve(e),resolve(t)));return n===`..`||n.startsWith(`../`)||n===``?``:n}function resolveLockfileSearchDirectories(e){let n=resolve(e),r=[n],a=n;for(;;){if(hasWatchRootMarker(a))return r;let e=dirname(a);if(e===a)return[n];a=e,r.push(a)}}function hasWatchRootMarker(t){return WATCH_ROOT_MARKER_NAMES.some(r=>existsSync(join(t,r)))}async function resolveTsConfigWatchPaths(e){return await resolveTsConfigDependencyPaths(e)}function shouldIgnoreWatcherPath(e){return e.replaceAll(`\\`,`/`).split(`/`).filter(Boolean).some(e=>WATCHER_IGNORED_DIRECTORY_NAMES.has(e))}export{startAuthoredSourceWatcher};
1
+ import{existsSync}from"node:fs";import{dirname,join,relative,resolve}from"node:path";import{toErrorMessage}from"#shared/errors.js";import{getDevelopmentEnvironmentFilePaths,loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{AUTHORED_ARTIFACTS_UPDATED_LOG_LINE,STRUCTURAL_RELOAD_LOG_LINE,formatChangeDetectedLogLine}from"#internal/nitro/host/dev-watcher-log.js";import{clearCompiledRuntimeAgentBundleCache}from"#runtime/sessions/compiled-agent-cache.js";import{resolveDevelopmentSourceSnapshotWatchPaths}from"#internal/nitro/dev-runtime-source-snapshot.js";import{resolveTsConfigDependencyPaths}from"#internal/application/tsconfig-dependencies.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{computeChannelRouteRegistrations,syncChannelVirtualHandlers}from"#internal/nitro/host/channel-routes.js";import{watch}from"#compiled/chokidar/index.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";const WATCHED_LOCKFILE_NAMES=[`pnpm-lock.yaml`,`package-lock.json`,`yarn.lock`,`bun.lock`,`bun.lockb`],WATCH_ROOT_MARKER_NAMES=[`.git`,`pnpm-workspace.yaml`],WATCHER_IGNORED_DIRECTORY_NAMES=new Set([`.generated`,`.eve`,`.git`,`.next`,`.output`,`.turbo`,`.vercel`,`.workflow-data`,`build`,`dist`,`node_modules`]);async function startAuthoredSourceWatcher(e){let t=e.preparedHost,n=!1,r=Promise.resolve(),i,o=!1,s=new Map,c=new Set,u=await resolveAuthoredWatchPaths(t),d=createWatchPathMap(u),f=watch(u,{awaitWriteFinish:{pollInterval:50,stabilityThreshold:160},followSymlinks:!1,ignoreInitial:!0,ignored:shouldIgnoreWatcherPath}),p=waitForWatcherReady(f),rebuild=async i=>{n||(r=r.then(async()=>{if(n)return;let r=[...s.values()];if(!i&&r.length===0)return;let o=[...c];s.clear(),c.clear();let l=t,u=hasSandboxRelatedChange(l.compileResult.project.agentRoot,o),p=hasDevelopmentEnvironmentFileChange(l.appRoot,o);r.length>0&&console.log(formatChangeDetectedLogLine(l.appRoot,r));try{p&&loadDevelopmentEnvironmentFiles(l.appRoot);let n=await prepareApplicationHost(l.appRoot,{dev:e.nitro.options.dev===!0}),r=createNitroArtifactsConfig({appRoot:n.appRoot,dev:e.nitro.options.dev===!0});u&&startDevelopmentSandboxPrewarmInBackground({appRoot:n.appRoot,compiledArtifactsSource:resolveNitroCompiledArtifactsSource(r),log:e=>console.log(e)});let i=syncChannelVirtualHandlers(e.nitro,{artifactsConfig:r,next:computeChannelRouteRegistrations(n),previous:computeChannelRouteRegistrations(l)});clearCompiledRuntimeAgentBundleCache(),t=n,i||p?(console.log(STRUCTURAL_RELOAD_LOG_LINE),await e.nitro.hooks.callHook(`rollup:reload`)):console.log(AUTHORED_ARTIFACTS_UPDATED_LOG_LINE),d=syncWatcherPaths({nextWatchPaths:await resolveAuthoredWatchPaths(n),previousWatchPathsByKey:d,watcher:f})}catch(e){console.error(`[eve:dev] rebuild failed: ${toErrorMessage(e)}`)}}).catch(e=>{console.error(`[eve:dev] rebuild queue error: ${toErrorMessage(e)}`)}),await r)},flush=async()=>{i!==void 0&&(clearTimeout(i),i=void 0),await rebuild(!1)};return f.on(`all`,(e,t)=>{n||!o||(s.set(`${e}:${t}`,{event:e,path:t}),c.add(t),i!==void 0&&clearTimeout(i),i=setTimeout(()=>{i=void 0,flush()},120))}),await p,o=!0,{async close(){n=!0,i!==void 0&&(clearTimeout(i),i=void 0),await f.close(),await r},flush,rebuild:async()=>{i!==void 0&&(clearTimeout(i),i=void 0),await rebuild(!0)}}}async function waitForWatcherReady(e){await new Promise((t,n)=>{e.on(`ready`,()=>{t()}),e.on(`error`,e=>{n(e)})})}async function resolveAuthoredWatchPaths(e){let t=new Set([e.compileResult.project.agentRoot,join(e.appRoot,`package.json`),join(e.appRoot,`jsconfig.json`),join(e.appRoot,`tsconfig.json`),join(e.appRoot,`tsconfig.*.json`)]),r=await resolveTsConfigWatchPaths(e.appRoot),i=await resolveDevelopmentSourceSnapshotWatchPaths(e.appRoot);for(let n of getDevelopmentEnvironmentFilePaths(e.appRoot))t.add(n);for(let e of i)t.add(e);for(let e of r)t.add(e);for(let r of resolveLockfileSearchDirectories(e.appRoot))for(let e of WATCHED_LOCKFILE_NAMES)t.add(join(r,e));return[...t].sort((e,t)=>e.localeCompare(t))}function createWatchPathMap(e){let t=new Map;for(let n of e)t.set(toWatchPathKey(n),n);return t}function syncWatcherPaths(e){let t=createWatchPathMap(e.nextWatchPaths),n=[],r=[];for(let[r,i]of t)e.previousWatchPathsByKey.has(r)||n.push(i);for(let[n,i]of e.previousWatchPathsByKey)t.has(n)||r.push(i);return n.length>0&&e.watcher.add(n),r.length>0&&e.watcher.unwatch(r),t}function toWatchPathKey(e){return e.replaceAll(`\\`,`/`)}function hasDevelopmentEnvironmentFileChange(e,t){let n=new Set(getDevelopmentEnvironmentFilePaths(e).map(e=>toWatchPathKey(resolve(e))));return t.some(e=>n.has(toWatchPathKey(resolve(e))))}function hasSandboxRelatedChange(e,t){return t.some(t=>{let n=toAgentRelativePath(e,t);return n===`sandbox.ts`||n.startsWith(`sandbox/`)||n===`workspace`||n.startsWith(`workspace/`)||n===`skills`||n.startsWith(`skills/`)})}function toAgentRelativePath(e,t){let n=toWatchPathKey(relative(resolve(e),resolve(t)));return n===`..`||n.startsWith(`../`)||n===``?``:n}function resolveLockfileSearchDirectories(e){let n=resolve(e),r=[n],a=n;for(;;){if(hasWatchRootMarker(a))return r;let e=dirname(a);if(e===a)return[n];a=e,r.push(a)}}function hasWatchRootMarker(t){return WATCH_ROOT_MARKER_NAMES.some(r=>existsSync(join(t,r)))}async function resolveTsConfigWatchPaths(e){return await resolveTsConfigDependencyPaths(e)}function shouldIgnoreWatcherPath(e){return e.replaceAll(`\\`,`/`).split(`/`).filter(Boolean).some(e=>WATCHER_IGNORED_DIRECTORY_NAMES.has(e))}export{startAuthoredSourceWatcher};
@@ -4,6 +4,14 @@ import type { DevelopmentServer, DevelopmentServerOptions, StartedDevelopmentSer
4
4
  * loopback URL on the same address family.
5
5
  */
6
6
  export declare function normalizeDevelopmentServerClientUrl(serverUrl: string): string;
7
+ /**
8
+ * Returns whether a supplied URL identifies this app's healthy local development
9
+ * server. Only that server receives the local TUI credential path.
10
+ */
11
+ export declare function isActiveDevelopmentServerForApp(input: {
12
+ readonly appRoot: string;
13
+ readonly serverUrl: string;
14
+ }): Promise<boolean>;
7
15
  /**
8
16
  * Creates a development server for an eve application. Call `start()` to boot an
9
17
  * owned Nitro server or attach to a running owner, and `close()` to tear down a
@@ -1,2 +1,2 @@
1
- import{isLoopbackServerUrl}from"#shared/network-address.js";import{detectPackageManager}from"#setup/package-manager.js";import{eveDevArguments}from"#setup/primitives/index.js";import{toErrorMessage}from"#shared/errors.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{resolveDiscoveryProject}from"#discover/project.js";import{EVE_DEV_ENV_FLAG}from"#internal/application/optional-package-install.js";import{EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,clearInitializedDevelopmentSandboxBackendNames,createDevelopmentSandboxRunId,getInitializedDevelopmentSandboxBackendNames}from"#execution/sandbox/development-run.js";import{pruneDevelopmentRuntimeArtifactsSnapshotsInBackground}from"#internal/nitro/dev-runtime-artifacts.js";import{build,createDevServer,prepare}from"nitro/builder";import{createApplicationNitro}from"#internal/nitro/host/create-application-nitro.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{DevelopmentServerState}from"#internal/nitro/host/dev-server-state.js";import{isEveServerHealthy}from"#shared/eve-server-health.js";import{pruneLocalSandboxTemplatesInBackground,stopDevelopmentSandboxResources}from"#execution/sandbox/bindings/local.js";import{DEFAULT_DEVELOPMENT_SERVER_PORT,MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS}from"#internal/nitro/host/ports.js";const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT=65535,WORKFLOW_LOCAL_BASE_URL_ENV=`WORKFLOW_LOCAL_BASE_URL`,PORT_ENV=`PORT`,DEFAULT_DEVELOPMENT_SERVER_HOST=`127.0.0.1`,IPV6_WILDCARD_LISTEN_HOSTNAMES=new Set([`[::]`,`::`]);function normalizeDevelopmentServerClientUrl(e){let t=new URL(e);return IPV6_WILDCARD_LISTEN_HOSTNAMES.has(t.hostname)?(t.hostname=`[::1]`,t.toString()):t.hostname===`0.0.0.0`?(t.hostname=DEFAULT_DEVELOPMENT_SERVER_HOST,t.toString()):e}function isAddressInUseError(e){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`}function resolveDevelopmentServerPort(e){let t=typeof e==`string`?Number(e):e??DEFAULT_DEVELOPMENT_SERVER_PORT;if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid development server port "${String(e)}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function readEnvironmentPort(){let e=process.env[PORT_ENV];if(e===void 0||e.trim()===``)return;let t=Number(e);if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid ${PORT_ENV} environment variable "${e}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}async function detectDevelopmentCommandPackageManager(e){try{return(await detectPackageManager(e)).kind}catch{return`pnpm`}}async function formatDevelopmentServerConnectCommand(e,t){let r=await detectDevelopmentCommandPackageManager(e);return[r,...eveDevArguments(r),t].join(` `)}async function createDevelopmentServerAlreadyRunningError(e,t){let n=await formatDevelopmentServerConnectCommand(e,t);return Error([`A dev server is already running for this eve agent.`,`To connect to the existing instance, run: ${n}`].join(`
2
- `))}function resolveDevelopmentServerPorts(e){let t=resolveDevelopmentServerPort(e.port);if(t===0||!e.retryOnAddressInUse)return[t];let n=[];for(let e=0;e<MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS;e+=1){let r=t+e;if(r>65535)break;n.push(r)}return n}function installWorkflowLocalQueueEnvironment(e){let t=process.env[WORKFLOW_LOCAL_BASE_URL_ENV],n=process.env[PORT_ENV],r=new URL(normalizeDevelopmentServerClientUrl(e));return process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=r.origin,r.port&&(process.env[PORT_ENV]=r.port),()=>{t===void 0?delete process.env[WORKFLOW_LOCAL_BASE_URL_ENV]:process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=t,n===void 0?delete process.env[PORT_ENV]:process.env[PORT_ENV]=n}}function attachTemporarySocketErrorHandler(e){let onSocketError=()=>{};return e.once(`error`,onSocketError),()=>{e.off(`error`,onSocketError)}}function shouldProxyDevelopmentServerWebSocketUpgrades(e){return e.options.features.websocket===!0||e.options.experimental.websocket===!0}function guardDevelopmentServerWebSocketUpgrades(e,t){let n=t.upgrade.bind(t),r=shouldProxyDevelopmentServerWebSocketUpgrades(e);t.upgrade=async(e,t,i)=>{if(!r){t.destroyed||t.destroy();return}let a=attachTemporarySocketErrorHandler(t);try{await n(e,t,i)}catch{t.destroyed||t.destroy()}finally{a()}}}async function closeDevelopmentServerResources(e){let t=[],attempt=async e=>{try{return await e(),!0}catch(e){return t.push(e),!1}},n=e.authoredSourceWatcher;n!==void 0&&await attempt(()=>n.close());let r=e.devServer,i=r===void 0?!0:await attempt(()=>r.close()),a=e.nitro;return a!==void 0&&await attempt(()=>a.close()),await attempt(()=>stopDevelopmentSandboxResources({backendNames:getInitializedDevelopmentSandboxBackendNames(e.developmentSandboxRunId),devRunId:e.developmentSandboxRunId,log:e=>console.warn(`[eve:dev] ${e}`)})),{errors:t,listenerClosed:i}}function createDevelopmentServerCleanupError(e){if(e.length!==0){if(e.length===1){let t=e[0];return t instanceof Error?t:Error(`Failed to close the development server: ${toErrorMessage(t)}`,{cause:t})}return AggregateError(e,`Multiple development-server resources failed to close.`)}}function createDevelopmentServerStartupCleanupError(e,t){return AggregateError([e,...t],`${toErrorMessage(e)} Cleanup also failed.`,{cause:e})}async function listenForDevelopmentServer(e){let t=resolveDevelopmentServerPorts({port:e.port,retryOnAddressInUse:e.retryOnAddressInUse}),n;for(let r of t){let t=e.devServer.listen({hostname:e.host,port:r,silent:!0});try{return await t.ready(),t}catch(r){if(n=r,await t.close().catch(()=>{}),!isAddressInUseError(r)||!e.retryOnAddressInUse)throw r}}throw Error(`Failed to start Nitro dev server after ${t.length} attempts. Tried ports ${t.join(`, `)}.`,{cause:n})}async function startNitroDevelopmentServer(t,n){process.env[EVE_DEV_ENV_FLAG]??=`1`;let r=await resolveDiscoveryProject(t);loadDevelopmentEnvironmentFiles(r.appRoot);let u=readEnvironmentPort(),p=n.port??u,m=n.host!==void 0||n.port!==void 0||u!==void 0,h=new DevelopmentServerState(r),g=await h.read();if(g!==void 0&&isLoopbackServerUrl(g)&&await isEveServerHealthy(g)){if(n.existing===`attach-if-unconfigured`&&!m)return{handle:{kind:`existing`,appRoot:r.appRoot,url:g},close:void 0};throw await createDevelopmentServerAlreadyRunningError(r.appRoot,g)}let _=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV],v=createDevelopmentSandboxRunId();process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=v;let y,b,x,S;try{let e=await devBootPhase(`compiling agent`,()=>prepareApplicationHost(r.appRoot,{dev:!0}),n.onBootProgress);pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(e.appRoot);let t=resolveNitroCompiledArtifactsSource(createNitroArtifactsConfig({appRoot:e.appRoot,dev:!0}));startDevelopmentSandboxPrewarmInBackground({appRoot:e.appRoot,compiledArtifactsSource:t}),pruneLocalSandboxTemplatesInBackground(e.appRoot);let i=await devBootPhase(`creating dev server`,()=>createApplicationNitro(e,!0),n.onBootProgress);y=i,b=createDevServer(i);let o=b;guardDevelopmentServerWebSocketUpgrades(i,b);let s=n.host??i.options.devServer.hostname??DEFAULT_DEVELOPMENT_SERVER_HOST,c=p===void 0,l=await devBootPhase(`binding port`,()=>listenForDevelopmentServer({devServer:o,host:s,port:p,retryOnAddressInUse:c}),n.onBootProgress);if(!l.url)throw Error(`Nitro dev server did not expose a URL.`);let u=normalizeDevelopmentServerClientUrl(l.url);x=installWorkflowLocalQueueEnvironment(u),await devBootPhase(`building dev bundle`,async()=>{await prepare(i),await build(i)},n.onBootProgress),S=await devBootPhase(`starting file watcher`,async()=>{let{startAuthoredSourceWatcher:t}=await import(`#internal/nitro/host/dev-authored-source-watcher.js`);return t({nitro:i,preparedHost:e})},n.onBootProgress),await h.write(u);let d=x;if(d===void 0)throw Error(`Workflow local queue environment was not initialized.`);let f=S,m=b,g=i,C;return{handle:{kind:`started`,appRoot:r.appRoot,url:u},close:()=>(C??=(async()=>{let e=await closeDevelopmentServerResources({authoredSourceWatcher:f,devServer:m,developmentSandboxRunId:v,nitro:g});e.listenerClosed&&await h.remove().catch(()=>{});try{let t=createDevelopmentServerCleanupError(e.errors);if(t!==void 0)throw t}finally{clearInitializedDevelopmentSandboxBackendNames(v),d(),restoreDevelopmentSandboxRunId(_)}})(),C)}}catch(e){let t=await closeDevelopmentServerResources({authoredSourceWatcher:S,devServer:b,developmentSandboxRunId:v,nitro:y}),n=[...t.errors];throw x?.(),clearInitializedDevelopmentSandboxBackendNames(v),t.listenerClosed&&await h.remove().catch(()=>{}),restoreDevelopmentSandboxRunId(_),n.length>0?createDevelopmentServerStartupCleanupError(e,n):e}}function createDevelopmentServer(e,t={}){let n,r;return{start(){if(n!==void 0)throw Error(`DevelopmentServer.start() was already called.`);return n=startNitroDevelopmentServer(e,t).then(({handle:e,close:t})=>(r=t,e)),n},async close(){n!==void 0&&(await n.catch(()=>void 0),await r?.())}}}function restoreDevelopmentSandboxRunId(e){if(e===void 0){delete process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return}process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=e}export{createDevelopmentServer,normalizeDevelopmentServerClientUrl};
1
+ import{isLoopbackServerUrl}from"#shared/network-address.js";import{detectPackageManager}from"#setup/package-manager.js";import{eveDevArguments}from"#setup/primitives/index.js";import{toErrorMessage}from"#shared/errors.js";import{loadDevelopmentEnvironmentFiles}from"#cli/dev/environment.js";import{startDevelopmentSandboxPrewarmInBackground}from"#execution/sandbox/development-prewarm.js";import{devBootPhase}from"#internal/dev-boot-progress.js";import{resolveDiscoveryProject}from"#discover/project.js";import{EVE_DEV_ENV_FLAG}from"#internal/application/optional-package-install.js";import{EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV,clearInitializedDevelopmentSandboxBackendNames,createDevelopmentSandboxRunId,getInitializedDevelopmentSandboxBackendNames}from"#execution/sandbox/development-run.js";import{pruneDevelopmentRuntimeArtifactsSnapshotsInBackground}from"#internal/nitro/dev-runtime-artifacts.js";import{build,createDevServer,prepare}from"nitro/builder";import{createApplicationNitro}from"#internal/nitro/host/create-application-nitro.js";import{prepareApplicationHost}from"#internal/nitro/host/prepare-application-host.js";import{createNitroArtifactsConfig}from"#internal/nitro/host/artifacts-config.js";import{resolveNitroCompiledArtifactsSource}from"#internal/nitro/routes/runtime-artifacts.js";import{DevelopmentServerState}from"#internal/nitro/host/dev-server-state.js";import{isEveServerHealthy}from"#shared/eve-server-health.js";import{pruneLocalSandboxTemplatesInBackground,stopDevelopmentSandboxResources}from"#execution/sandbox/bindings/local.js";import{DEFAULT_DEVELOPMENT_SERVER_PORT,MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS}from"#internal/nitro/host/ports.js";const MAX_ALLOWED_DEVELOPMENT_SERVER_PORT=65535,WORKFLOW_LOCAL_BASE_URL_ENV=`WORKFLOW_LOCAL_BASE_URL`,PORT_ENV=`PORT`,DEFAULT_DEVELOPMENT_SERVER_HOST=`127.0.0.1`,IPV6_WILDCARD_LISTEN_HOSTNAMES=new Set([`[::]`,`::`]);function normalizeDevelopmentServerClientUrl(e){let t=new URL(e);return IPV6_WILDCARD_LISTEN_HOSTNAMES.has(t.hostname)?(t.hostname=`[::1]`,t.toString()):t.hostname===`0.0.0.0`?(t.hostname=DEFAULT_DEVELOPMENT_SERVER_HOST,t.toString()):e}async function isActiveDevelopmentServerForApp(t){try{let n=await new DevelopmentServerState(await resolveDiscoveryProject(t.appRoot)).read();return n===void 0||!isLoopbackServerUrl(n)||!await isEveServerHealthy(n)?!1:new URL(n).origin===new URL(normalizeDevelopmentServerClientUrl(t.serverUrl)).origin}catch{return!1}}function isAddressInUseError(e){return e instanceof Error&&`code`in e&&e.code===`EADDRINUSE`}function resolveDevelopmentServerPort(e){let t=typeof e==`string`?Number(e):e??DEFAULT_DEVELOPMENT_SERVER_PORT;if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid development server port "${String(e)}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}function readEnvironmentPort(){let e=process.env[PORT_ENV];if(e===void 0||e.trim()===``)return;let t=Number(e);if(!Number.isInteger(t)||t<0||t>MAX_ALLOWED_DEVELOPMENT_SERVER_PORT)throw Error(`Invalid ${PORT_ENV} environment variable "${e}". Expected an integer between 0 and ${MAX_ALLOWED_DEVELOPMENT_SERVER_PORT}.`);return t}async function detectDevelopmentCommandPackageManager(e){try{return(await detectPackageManager(e)).kind}catch{return`pnpm`}}async function formatDevelopmentServerConnectCommand(e,t){let r=await detectDevelopmentCommandPackageManager(e);return[r,...eveDevArguments(r),t].join(` `)}async function createDevelopmentServerAlreadyRunningError(e,t){let n=await formatDevelopmentServerConnectCommand(e,t);return Error([`A dev server is already running for this eve agent.`,`To connect to the existing instance, run: ${n}`].join(`
2
+ `))}function resolveDevelopmentServerPorts(e){let t=resolveDevelopmentServerPort(e.port);if(t===0||!e.retryOnAddressInUse)return[t];let n=[];for(let e=0;e<MAX_DEVELOPMENT_SERVER_PORT_ATTEMPTS;e+=1){let r=t+e;if(r>65535)break;n.push(r)}return n}function installWorkflowLocalQueueEnvironment(e){let t=process.env[WORKFLOW_LOCAL_BASE_URL_ENV],n=process.env[PORT_ENV],r=new URL(normalizeDevelopmentServerClientUrl(e));return process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=r.origin,r.port&&(process.env[PORT_ENV]=r.port),()=>{t===void 0?delete process.env[WORKFLOW_LOCAL_BASE_URL_ENV]:process.env[WORKFLOW_LOCAL_BASE_URL_ENV]=t,n===void 0?delete process.env[PORT_ENV]:process.env[PORT_ENV]=n}}function attachTemporarySocketErrorHandler(e){let onSocketError=()=>{};return e.once(`error`,onSocketError),()=>{e.off(`error`,onSocketError)}}function shouldProxyDevelopmentServerWebSocketUpgrades(e){return e.options.features.websocket===!0||e.options.experimental.websocket===!0}function guardDevelopmentServerWebSocketUpgrades(e,t){let n=t.upgrade.bind(t),r=shouldProxyDevelopmentServerWebSocketUpgrades(e);t.upgrade=async(e,t,i)=>{if(!r){t.destroyed||t.destroy();return}let a=attachTemporarySocketErrorHandler(t);try{await n(e,t,i)}catch{t.destroyed||t.destroy()}finally{a()}}}async function closeDevelopmentServerResources(e){let t=[],attempt=async e=>{try{return await e(),!0}catch(e){return t.push(e),!1}},n=e.authoredSourceWatcher;n!==void 0&&await attempt(()=>n.close());let r=e.devServer,i=r===void 0?!0:await attempt(()=>r.close()),a=e.nitro;return a!==void 0&&await attempt(()=>a.close()),await attempt(()=>stopDevelopmentSandboxResources({backendNames:getInitializedDevelopmentSandboxBackendNames(e.developmentSandboxRunId),devRunId:e.developmentSandboxRunId,log:e=>console.warn(`[eve:dev] ${e}`)})),{errors:t,listenerClosed:i}}function createDevelopmentServerCleanupError(e){if(e.length!==0){if(e.length===1){let t=e[0];return t instanceof Error?t:Error(`Failed to close the development server: ${toErrorMessage(t)}`,{cause:t})}return AggregateError(e,`Multiple development-server resources failed to close.`)}}function createDevelopmentServerStartupCleanupError(e,t){return AggregateError([e,...t],`${toErrorMessage(e)} Cleanup also failed.`,{cause:e})}async function listenForDevelopmentServer(e){let t=resolveDevelopmentServerPorts({port:e.port,retryOnAddressInUse:e.retryOnAddressInUse}),n;for(let r of t){let t=e.devServer.listen({hostname:e.host,port:r,silent:!0});try{return await t.ready(),t}catch(r){if(n=r,await t.close().catch(()=>{}),!isAddressInUseError(r)||!e.retryOnAddressInUse)throw r}}throw Error(`Failed to start Nitro dev server after ${t.length} attempts. Tried ports ${t.join(`, `)}.`,{cause:n})}async function startNitroDevelopmentServer(t,n){process.env[EVE_DEV_ENV_FLAG]??=`1`;let r=await resolveDiscoveryProject(t);loadDevelopmentEnvironmentFiles(r.appRoot);let u=readEnvironmentPort(),p=n.port??u,m=n.host!==void 0||n.port!==void 0||u!==void 0,h=new DevelopmentServerState(r),g=await h.read();if(g!==void 0&&isLoopbackServerUrl(g)&&await isEveServerHealthy(g)){if(n.existing===`attach-if-unconfigured`&&!m)return{handle:{kind:`existing`,appRoot:r.appRoot,url:g},close:void 0};throw await createDevelopmentServerAlreadyRunningError(r.appRoot,g)}let _=process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV],v=createDevelopmentSandboxRunId();process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=v;let y,b,x,S;try{let e=await devBootPhase(`compiling agent`,()=>prepareApplicationHost(r.appRoot,{dev:!0}),n.onBootProgress);pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(e.appRoot);let t=resolveNitroCompiledArtifactsSource(createNitroArtifactsConfig({appRoot:e.appRoot,dev:!0}));startDevelopmentSandboxPrewarmInBackground({appRoot:e.appRoot,compiledArtifactsSource:t}),pruneLocalSandboxTemplatesInBackground(e.appRoot);let i=await devBootPhase(`creating dev server`,()=>createApplicationNitro(e,!0),n.onBootProgress);y=i,b=createDevServer(i);let o=b;guardDevelopmentServerWebSocketUpgrades(i,b);let s=n.host??i.options.devServer.hostname??DEFAULT_DEVELOPMENT_SERVER_HOST,c=p===void 0,l=await devBootPhase(`binding port`,()=>listenForDevelopmentServer({devServer:o,host:s,port:p,retryOnAddressInUse:c}),n.onBootProgress);if(!l.url)throw Error(`Nitro dev server did not expose a URL.`);let u=normalizeDevelopmentServerClientUrl(l.url);x=installWorkflowLocalQueueEnvironment(u),await devBootPhase(`building dev bundle`,async()=>{await prepare(i),await build(i)},n.onBootProgress),S=await devBootPhase(`starting file watcher`,async()=>{let{startAuthoredSourceWatcher:t}=await import(`#internal/nitro/host/dev-authored-source-watcher.js`);return t({nitro:i,preparedHost:e})},n.onBootProgress),await h.write(u);let d=x;if(d===void 0)throw Error(`Workflow local queue environment was not initialized.`);let f=S,m=b,g=i,C;return{handle:{kind:`started`,appRoot:r.appRoot,url:u},close:()=>(C??=(async()=>{let e=await closeDevelopmentServerResources({authoredSourceWatcher:f,devServer:m,developmentSandboxRunId:v,nitro:g});e.listenerClosed&&await h.remove().catch(()=>{});try{let t=createDevelopmentServerCleanupError(e.errors);if(t!==void 0)throw t}finally{clearInitializedDevelopmentSandboxBackendNames(v),d(),restoreDevelopmentSandboxRunId(_)}})(),C)}}catch(e){let t=await closeDevelopmentServerResources({authoredSourceWatcher:S,devServer:b,developmentSandboxRunId:v,nitro:y}),n=[...t.errors];throw x?.(),clearInitializedDevelopmentSandboxBackendNames(v),t.listenerClosed&&await h.remove().catch(()=>{}),restoreDevelopmentSandboxRunId(_),n.length>0?createDevelopmentServerStartupCleanupError(e,n):e}}function createDevelopmentServer(e,t={}){let n,r;return{start(){if(n!==void 0)throw Error(`DevelopmentServer.start() was already called.`);return n=startNitroDevelopmentServer(e,t).then(({handle:e,close:t})=>(r=t,e)),n},async close(){n!==void 0&&(await n.catch(()=>void 0),await r?.())}}}function restoreDevelopmentSandboxRunId(e){if(e===void 0){delete process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV];return}process.env[EVE_DEVELOPMENT_SANDBOX_RUN_ID_ENV]=e}export{createDevelopmentServer,isActiveDevelopmentServerForApp,normalizeDevelopmentServerClientUrl};
@@ -1,4 +1,4 @@
1
1
  export { buildApplication } from "#internal/nitro/host/build-application.js";
2
- export { createDevelopmentServer } from "#internal/nitro/host/start-development-server.js";
2
+ export { createDevelopmentServer, isActiveDevelopmentServerForApp, } from "#internal/nitro/host/start-development-server.js";
3
3
  export { startProductionServer } from "#internal/nitro/host/start-production-server.js";
4
4
  export type { DevelopmentServer, DevelopmentServerHandle, DevelopmentServerOptions, ExistingDevelopmentServer, ProductionServerHandle, StartedDevelopmentServer, } from "#internal/nitro/host/types.js";
@@ -1 +1 @@
1
- import{buildApplication}from"#internal/nitro/host/build-application.js";import{createDevelopmentServer}from"#internal/nitro/host/start-development-server.js";import{startProductionServer}from"#internal/nitro/host/start-production-server.js";export{buildApplication,createDevelopmentServer,startProductionServer};
1
+ import{buildApplication}from"#internal/nitro/host/build-application.js";import{createDevelopmentServer,isActiveDevelopmentServerForApp}from"#internal/nitro/host/start-development-server.js";import{startProductionServer}from"#internal/nitro/host/start-production-server.js";export{buildApplication,createDevelopmentServer,isActiveDevelopmentServerForApp,startProductionServer};
@@ -1 +1 @@
1
- import{createGetSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createSendFn}from"#channel/send.js";import{createCrossChannelReceiveFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});let c=buildRouteArgs(e,i,a.name),l;try{if(a.handler)l=await a.handler(e.req,c.args);else{let t={agent:c.agent,waitUntil:c.args.waitUntil,params:c.args.params,requestIp:c.args.requestIp};l=await a.fetch(e.req,t)}}catch(r){let i=logError(log,`channel handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),Response.json({error:`Channel handler failed.`,errorId:i,ok:!1},{status:500})}return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),l}async function dispatchChannelWebSocketRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0||a.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let c=buildRouteArgs(e,i,a.name);try{let n=await a.websocket(e.req,c.args);return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),n}catch(r){let i=logError(log,`channel websocket handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:i,ok:!1},500)}}function buildRouteArgs(t,n,o){let s=readVercelRequestId(t.req.headers),c=extractSocketIp(t),l=[],u=t.context.params??{},d={};for(let[e,t]of Object.entries(u))d[e]=decodeURIComponent(t);let waitUntil=e=>{l.push(e)},f=n.channels.find(e=>e.name===o)?.adapter??{kind:`channel`};return{agent:createRouteAgent(n.runtime,s),args:{send:createSendFn(n.runtime,f,o,{requestId:s}),getSession:createGetSessionFn(n.runtime),receive:createCrossChannelReceiveFn(n.runtime,toCrossChannelTargets(n.channels)),params:d,waitUntil,requestIp:c},backgroundTasks:l}}function createRouteAgent(e,t){return{async deliver(n){let r={...n,requestId:t};return await e.deliver(r)},async getEventStream(t,n){return await e.getEventStream(t,n)},async run(n){let r={...n,requestId:t};return await e.run(r)}}}function readVercelRequestId(e){let t=e.get(`x-vercel-id`)?.trim();return t===``?void 0:t}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,r,i){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:r,channel:i})}))}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};
1
+ import{createGetSessionFn}from"#channel/session.js";import{createLogger,logError}from"#internal/logging.js";import{createSendFn}from"#channel/send.js";import{createCrossChannelReceiveFn,toCrossChannelTargets}from"#channel/cross-channel-receive.js";import{readVercelProjectLink}from"#internal/vercel/project-link.js";import{resolveNitroChannelRuntimeBundle}from"#internal/nitro/routes/runtime-stack.js";import{withVercelOidcProjectResolver}from"#runtime/governance/auth/vercel-oidc-project.js";const log=createLogger(`channel.dispatch`);async function dispatchChannelRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0)return Response.json({error:`No matching channel for this request.`,ok:!1},{status:404});let o=buildRouteArgs(e,i,a.name),c;try{c=await withDevelopmentVercelOidcContext(r,e.req,async()=>{if(a.handler)return await a.handler(e.req,o.args);let t={agent:o.agent,waitUntil:o.args.waitUntil,params:o.args.params,requestIp:o.args.requestIp};return await a.fetch(e.req,t)})}catch(r){let i=logError(log,`channel handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,o.backgroundTasks,t,a.name),Response.json({error:`Channel handler failed.`,errorId:i,ok:!1},{status:500})}return flushBackgroundTasks(e,o.backgroundTasks,t,a.name),c}async function dispatchChannelWebSocketRequest(e,t,r){let i=await resolveNitroChannelRuntimeBundle(r),a=i.channels.find(e=>`${e.method.toUpperCase()} ${e.urlPath}`===t);if(a===void 0||a.websocket===void 0)return rejectWebSocketUpgrade({error:`No matching websocket channel for this request.`,ok:!1},404);let o=a.websocket,c=buildRouteArgs(e,i,a.name);try{let n=await withDevelopmentVercelOidcContext(r,e.req,async()=>await o(e.req,c.args));return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),n}catch(r){let i=logError(log,`channel websocket handler threw`,r,{routeKey:t,channel:a.name});return flushBackgroundTasks(e,c.backgroundTasks,t,a.name),rejectWebSocketUpgrade({error:`Channel websocket handler failed.`,errorId:i,ok:!1},500)}}async function withDevelopmentVercelOidcContext(e,t,n){let r=e.appRoot;return e.dev!==!0||r===void 0?await n():await withVercelOidcProjectResolver({request:t,resolveCurrentProject:async()=>{let e=await readVercelProjectLink(r);return e===void 0?void 0:{environment:`development`,projectId:e.projectId}}},n)}function buildRouteArgs(t,n,o){let s=readVercelRequestId(t.req.headers),c=extractSocketIp(t),l=[],u=t.context.params??{},d={};for(let[e,t]of Object.entries(u))d[e]=decodeURIComponent(t);let waitUntil=e=>{l.push(e)},f=n.channels.find(e=>e.name===o)?.adapter??{kind:`channel`};return{agent:createRouteAgent(n.runtime,s),args:{send:createSendFn(n.runtime,f,o,{requestId:s}),getSession:createGetSessionFn(n.runtime),receive:createCrossChannelReceiveFn(n.runtime,toCrossChannelTargets(n.channels)),params:d,waitUntil,requestIp:c},backgroundTasks:l}}function createRouteAgent(e,t){return{async deliver(n){let r={...n,requestId:t};return await e.deliver(r)},async getEventStream(t,n){return await e.getEventStream(t,n)},async run(n){let r={...n,requestId:t};return await e.run(r)}}}function readVercelRequestId(e){let t=e.get(`x-vercel-id`)?.trim();return t===``?void 0:t}function rejectWebSocketUpgrade(e,t){return{upgrade(){throw Response.json(e,{status:t})}}}function flushBackgroundTasks(e,t,r,i){t.length!==0&&e.waitUntil(Promise.allSettled(t).then(e=>{for(let t of e)t.status===`rejected`&&logError(log,`channel background task failed`,t.reason,{routeKey:r,channel:i})}))}function extractSocketIp(e){let t=e.req.ip;return typeof t==`string`&&t.length>0?t:null}export{dispatchChannelRequest,dispatchChannelWebSocketRequest};
@@ -8,6 +8,3 @@
8
8
  export declare function handleDevRuntimeArtifactsRequest(input: {
9
9
  appRoot: string;
10
10
  }): Response;
11
- export declare function handleDevRuntimeArtifactsRebuildRequest(input: {
12
- appRoot: string;
13
- }): Promise<Response>;
@@ -1 +1 @@
1
- import{readDevelopmentRuntimeArtifactsRevision}from"#internal/nitro/dev-runtime-artifacts.js";import{flushDevelopmentRebuild}from"#internal/nitro/host/dev-rebuild-registry.js";function handleDevRuntimeArtifactsRequest(t){return Response.json(readDevelopmentRuntimeArtifactsRevision(t.appRoot),{headers:{"cache-control":`no-store`}})}async function handleDevRuntimeArtifactsRebuildRequest(e){return await flushDevelopmentRebuild(e.appRoot),handleDevRuntimeArtifactsRequest(e)}export{handleDevRuntimeArtifactsRebuildRequest,handleDevRuntimeArtifactsRequest};
1
+ import{readDevelopmentRuntimeArtifactsRevision}from"#internal/nitro/dev-runtime-artifacts.js";function handleDevRuntimeArtifactsRequest(e){return Response.json(readDevelopmentRuntimeArtifactsRevision(e.appRoot),{headers:{"cache-control":`no-store`}})}export{handleDevRuntimeArtifactsRequest};
@@ -1 +1 @@
1
- import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{buildAgentInfoResponseFromManifest}from"#internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js";import{loadAgentInfoManifestData,resolveAgentInfoCompiledArtifactsSource}from"#internal/nitro/routes/agent-info/load-agent-info-data.js";import{localDev,routeAuth,vercelOidc}from"#public/channels/auth.js";async function createAgentInfoPayload(e){let r=await loadAgentInfoManifestData({compiledArtifactsSource:resolveAgentInfoCompiledArtifactsSource(e)});return buildAgentInfoResponseFromManifest(r,{mode:e.mode??`development`,gatewayCredentials:await resolveGatewayCredentialPresence(r.manifest.config.model.routing)})}function hasEnvValue(e){return e!==void 0&&e.trim()!==``}async function resolveGatewayCredentialPresence(t){let n=hasEnvValue(process.env.AI_GATEWAY_API_KEY);if(t.kind===`external`||n)return{apiKey:n,oidc:!1};try{return await getVercelOidcToken(),{apiKey:!1,oidc:!0}}catch{return{apiKey:!1,oidc:!1}}}async function handleAgentInfoRequest(e,t){let n=await routeAuth(t,[localDev(),vercelOidc()]);return n instanceof Response?n:new Response(JSON.stringify(await createAgentInfoPayload(e)),{headers:{"cache-control":`no-store`,"content-type":`application/json; charset=utf-8`}})}export{handleAgentInfoRequest};
1
+ import{getVercelOidcToken}from"#compiled/@vercel/oidc/index.js";import{buildAgentInfoResponseFromManifest}from"#internal/nitro/routes/agent-info/build-agent-info-response-from-manifest.js";import{loadAgentInfoManifestData,resolveAgentInfoCompiledArtifactsSource}from"#internal/nitro/routes/agent-info/load-agent-info-data.js";import{localDev,routeAuth,vercelOidc}from"#public/channels/auth.js";async function createAgentInfoPayload(e){let r=await loadAgentInfoManifestData({compiledArtifactsSource:resolveAgentInfoCompiledArtifactsSource(e)});return buildAgentInfoResponseFromManifest(r,{mode:e.mode??`development`,gatewayCredentials:await resolveGatewayCredentialPresence(r.manifest.config.model.routing)})}function hasEnvValue(e){return e!==void 0&&e.trim()!==``}async function resolveGatewayCredentialPresence(t){let n=hasEnvValue(process.env.AI_GATEWAY_API_KEY);if(t.kind===`external`||n)return{apiKey:n,oidc:!1};try{return await getVercelOidcToken(),{apiKey:!1,oidc:!0}}catch{return{apiKey:!1,oidc:!1}}}async function handleAgentInfoRequest(e,t){let n=await routeAuth(t,[vercelOidc(),localDev()]);return n instanceof Response?n:new Response(JSON.stringify(await createAgentInfoPayload(e)),{headers:{"cache-control":`no-store`,"content-type":`application/json; charset=utf-8`}})}export{handleAgentInfoRequest};
@@ -0,0 +1,10 @@
1
+ import { z } from "#compiled/zod/index.js";
2
+ export declare const VercelProjectLinkSchema: z.ZodObject<{
3
+ projectId: z.ZodString;
4
+ orgId: z.ZodString;
5
+ projectName: z.ZodOptional<z.ZodString>;
6
+ }, z.core.$strip>;
7
+ /** Validated Vercel owner and project identifiers from `.vercel/project.json`. */
8
+ export type VercelProjectLink = z.infer<typeof VercelProjectLinkSchema>;
9
+ /** Reads a validated Vercel project link without mutating local project state. */
10
+ export declare function readVercelProjectLink(projectPath: string): Promise<VercelProjectLink | undefined>;
@@ -0,0 +1 @@
1
+ import{z}from"#compiled/zod/index.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const VercelProjectLinkSchema=z.object({projectId:z.string().min(1),orgId:z.string().min(1),projectName:z.string().min(1).optional()});async function readVercelProjectLink(e){try{let t=await readFile(join(e,`.vercel`,`project.json`),`utf8`),n=VercelProjectLinkSchema.safeParse(JSON.parse(t));return n.success?n.data:void 0}catch{return}}export{VercelProjectLinkSchema,readVercelProjectLink};
@@ -398,8 +398,8 @@ export interface CompactionCompletedStreamEvent {
398
398
  type: "compaction.completed";
399
399
  }
400
400
  /**
401
- * Stream event emitted when a connection needs user authorization before
402
- * its tools can be used.
401
+ * Stream event emitted when a connection or tool needs user authorization
402
+ * before it can continue.
403
403
  */
404
404
  export interface AuthorizationRequiredStreamEvent {
405
405
  data: {
@@ -417,10 +417,14 @@ export interface AuthorizationRequiredStreamEvent {
417
417
  * Outcome of one completed authorization attempt, emitted on
418
418
  * {@link AuthorizationCompletedStreamEvent}.
419
419
  */
420
- export type ConnectionAuthorizationOutcome = "authorized" | "declined" | "failed" | "timed-out";
420
+ export type AuthorizationOutcome = "authorized" | "declined" | "failed" | "timed-out";
421
+ /**
422
+ * @deprecated Use {@link AuthorizationOutcome}.
423
+ */
424
+ export type ConnectionAuthorizationOutcome = AuthorizationOutcome;
421
425
  /**
422
426
  * Stream event emitted once `completeAuthorization` has resolved
423
- * (successfully or otherwise) for one pending connection. Carries a
427
+ * (successfully or otherwise) for one pending authorization. Carries a
424
428
  * stable `outcome` plus an optional human-readable `reason`.
425
429
  *
426
430
  * Emitted when the tool completes authorization on resume, before the
@@ -435,7 +439,7 @@ export interface AuthorizationCompletedStreamEvent {
435
439
  */
436
440
  authorization?: ConnectionAuthorizationChallenge;
437
441
  name: string;
438
- outcome: ConnectionAuthorizationOutcome;
442
+ outcome: AuthorizationOutcome;
439
443
  reason?: string;
440
444
  sequence: number;
441
445
  stepIndex: number;
@@ -538,12 +542,12 @@ export declare function createActionsRequestedEvent(input: {
538
542
  readonly turnId: string;
539
543
  }): ActionsRequestedStreamEvent;
540
544
  /**
541
- * Creates the `authorization.required` event for one connection
542
- * that needs user authorization before its tools can be used.
545
+ * Creates the `authorization.required` event for one authorization source
546
+ * that needs user authorization before it can continue.
543
547
  *
544
548
  * `authorization` and `webhookUrl` are present together when the runtime
545
549
  * has suspended the turn on a framework-owned webhook; both are absent
546
- * for `getToken`-only connections that authorize out of band.
550
+ * for `getToken`-only authorization sources that authorize out of band.
547
551
  */
548
552
  export declare function createAuthorizationRequiredEvent(input: {
549
553
  readonly authorization?: ConnectionAuthorizationChallenge;
@@ -556,13 +560,13 @@ export declare function createAuthorizationRequiredEvent(input: {
556
560
  }): AuthorizationRequiredStreamEvent;
557
561
  /**
558
562
  * Creates the `authorization.completed` event emitted once per
559
- * connection after `completeAuthorization` has resolved or the
563
+ * authorization source after `completeAuthorization` has resolved or the
560
564
  * authorization deadline has expired.
561
565
  */
562
566
  export declare function createAuthorizationCompletedEvent(input: {
563
567
  readonly authorization?: ConnectionAuthorizationChallenge;
564
568
  readonly name: string;
565
- readonly outcome: ConnectionAuthorizationOutcome;
569
+ readonly outcome: AuthorizationOutcome;
566
570
  readonly reason?: string;
567
571
  readonly sequence: number;
568
572
  readonly stepIndex: number;
@@ -246,7 +246,7 @@ export declare function routeAuth(request: Request, auth: AuthFn<Request> | read
246
246
  * error. Replace it before serving real users:
247
247
  *
248
248
  * ```ts
249
- * eveChannel({ auth: [localDev(), vercelOidc(), placeholderAuth()] });
249
+ * eveChannel({ auth: [vercelOidc(), localDev(), placeholderAuth()] });
250
250
  * ```
251
251
  *
252
252
  * Outside production it returns `null`, so the auth walk keeps the same local
@@ -278,8 +278,8 @@ export declare function none<TEvent = unknown>(): AuthFn<TEvent>;
278
278
  *
279
279
  * Matching requests get a synthetic principal with `principalType:
280
280
  * "local-dev"`. Every other request returns `null`, skipping to the next
281
- * entry under {@link routeAuth}, which makes `[localDev(), vercelOidc()]`
282
- * the canonical "open on localhost, Vercel OIDC in prod" pattern.
281
+ * entry under {@link routeAuth}, which makes `[vercelOidc(), localDev()]`
282
+ * the canonical "Vercel OIDC when present, open on localhost otherwise" pattern.
283
283
  *
284
284
  * The check is not based on bare `process.env.VERCEL`: a deployment
285
285
  * outside Vercel (Fly, Railway, raw container) leaves `VERCEL` unset and
@@ -296,10 +296,21 @@ export declare function none<TEvent = unknown>(): AuthFn<TEvent>;
296
296
  * `localDev()`. Layer a real authenticator on such deployments.
297
297
  */
298
298
  export declare function localDev(): AuthFn<Request>;
299
+ /** Returns whether a request URL names a loopback host accepted by {@link localDev}. */
300
+ export declare function isLoopbackRequest(request: Request): boolean;
299
301
  /**
300
302
  * Options for {@link verifyVercelOidc} and {@link vercelOidc}.
301
303
  */
302
304
  export interface VerifyVercelOidcOptions {
305
+ /**
306
+ * Explicit current-project binding for the verified token. When omitted,
307
+ * the verifier reads `VERCEL_PROJECT_ID` and `VERCEL_TARGET_ENV` /
308
+ * `VERCEL_ENV` from the runtime environment.
309
+ */
310
+ readonly currentVercelProject?: {
311
+ readonly environment?: string;
312
+ readonly projectId: string;
313
+ };
303
314
  /**
304
315
  * Optional `sub` patterns granting callers access on top of the always-on
305
316
  * current-project bypass. Patterns use AWS IAM-style `*` wildcards and may
@@ -314,23 +325,25 @@ export interface VerifyVercelOidcOptions {
314
325
  *
315
326
  * Acceptance rule:
316
327
  *
317
- * - Tokens whose `project_id` matches `VERCEL_PROJECT_ID` are **always**
318
- * accepted regardless of `subjects`, so the deployment's own runtime
319
- * callers (subagent, internal fetches) authenticate without being
320
- * enumerated.
328
+ * - Current-project tokens that reach the service/runtime path are accepted
329
+ * regardless of `subjects`, so the deployment's own runtime callers
330
+ * (subagent, internal fetches) authenticate without being enumerated.
321
331
  * - Tokens with an `external_sub` claim authenticate as
322
- * `principalType: "user"` when they match the current `VERCEL_PROJECT_ID`
323
- * (if set) and `VERCEL_TARGET_ENV` / `VERCEL_ENV` (if set). `external_sub`
332
+ * `principalType: "user"` when they match the configured current project
333
+ * and environment. `external_sub`
324
334
  * becomes the eve subject, `external_iss` or `connector_id` the eve issuer
325
335
  * when present, and string-valued OIDC profile claims (`name`, `picture`,
326
336
  * `email`) are exposed as auth attributes.
337
+ * - Development tokens with a `user_id` claim authenticate as
338
+ * `principalType: "user"` only when both the token and configured current
339
+ * project environment are `development`. A same-project preview target may
340
+ * use one as a `"service"` principal; other target environments reject it.
327
341
  * - Tokens from other Vercel projects are accepted **only** when their `sub`
328
342
  * matches one of {@link VerifyVercelOidcOptions.subjects}.
329
343
  *
330
- * The `environment` claim is not constrained: production, preview, and
331
- * development tokens for the current project all authenticate. Non-user
332
- * principals are tagged `"runtime"` when the token's `environment` matches
333
- * the current deployment, otherwise `"service"`.
344
+ * Tokens without a `user_id` claim are accepted for the current project in
345
+ * production, preview, and development. They are tagged `"runtime"` when the
346
+ * token's `environment` matches the current deployment, otherwise `"service"`.
334
347
  */
335
348
  export declare function verifyVercelOidc(token: string | null, opts?: VerifyVercelOidcOptions): Promise<VerifyResult>;
336
349
  /**
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let r=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return r.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){return e===null||e.length===0?{kind:`not-authenticated`}:await authenticateOidcStrategy({strategy:{acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e===null?!1:isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeChallengeValue(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeChallengeValue(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}return createUnauthorizedResponse({challenges:[{scheme:`Bearer`}]})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return e=>process.env.VERCEL&&process.env.VERCEL_ENV===`development`||isLoopbackRequest(e)?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}const LOOPBACK_HOSTNAMES=new Set([`localhost`,`[::1]`]),LOOPBACK_IPV4_PREFIX=/^127\./;function isLoopbackRequest(e){let t;try{t=new URL(e.url).hostname}catch{return!1}return!!(LOOPBACK_HOSTNAMES.has(t)||LOOPBACK_IPV4_PREFIX.test(t)||t.endsWith(`.localhost`))}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,issuer:n.issuer,subjects:t.subjects??[]});return r.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:r.principal.principalType,subject:r.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(r.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:r.kind,subjectsConfigured:(t.subjects??[]).length>0,...r.kind===`misconfigured`?{detail:r.message}:{}}),{ok:!1})}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return async t=>{let n=await verifyVercelOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function httpBasic(e){return t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null}}function jwtHmac(e){return async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function jwtEcdsa(e){return async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function oidc(e){return async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function decodeUnverifiedJwtClaims(e){let n;try{n=decodeJwt(e)}catch{return null}return typeof n.iss!=`string`||n.iss.length===0?null:{audiences:typeof n.aud==`string`?[n.aud]:Array.isArray(n.aud)?n.aud.filter(e=>typeof e==`string`):[],issuer:n.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,extractBearerToken,httpBasic,isIpAllowed,jwtEcdsa,jwtHmac,localDev,none,oidc,placeholderAuth,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc};
1
+ import{createLogger}from"#internal/logging.js";import{resolveVercelOidcCurrentProject}from"#runtime/governance/auth/vercel-oidc-project.js";import{decodeJwt}from"#compiled/jose/index.js";import{authenticateHttpBasicStrategy}from"#runtime/governance/auth/http-basic.js";import{authenticateJwtEcdsaStrategy}from"#runtime/governance/auth/jwt-ecdsa.js";import{authenticateJwtHmacStrategy}from"#runtime/governance/auth/jwt-hmac.js";import{authenticateOidcStrategy}from"#runtime/governance/auth/oidc.js";import{createRuntimeSessionAuthContext}from"#runtime/governance/auth/types.js";import{createRuntimeIpAllowList,isRuntimeIpAllowed}from"#runtime/governance/network/ip-allow-list.js";const vercelOidcLog=createLogger(`auth.vercel-oidc`);function verifyHttpBasic(e,t){if(e===null)return{ok:!1};let n=authenticateHttpBasicStrategy({authorization:e,strategy:{kind:`http-basic`,password:t.password,username:t.username}});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtHmac(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtHmacStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-hmac`,secret:t.secret,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyJwtEcdsa(e,t){if(e===null||e.length===0)return{ok:!1};let n=await authenticateJwtEcdsaStrategy({strategy:{algorithm:t.algorithm,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,issuer:t.issuer,kind:`jwt-ecdsa`,publicKey:t.publicKey,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}},token:e});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function verifyOidc(e,t){let n=await runOidcVerification(e,{...t,acceptCurrentVercelProject:!1,currentVercelProject:void 0});return n.kind===`authenticated`?{ok:!0,sessionAuth:createRuntimeSessionAuthContext(n.principal)}:{ok:!1}}async function runOidcVerification(e,t){if(e===null||e.length===0)return{kind:`not-authenticated`};let n={acceptCurrentVercelProject:t.acceptCurrentVercelProject,audiences:[...t.audiences],clockSkewSeconds:t.clockSkewSeconds??30,discoveryUrl:t.discoveryUrl??`${t.issuer.replace(/\/$/,``)}/.well-known/openid-configuration`,issuer:t.issuer,kind:`oidc`,...t.claims===void 0?{}:{claims:t.claims},...t.subjects===void 0?{}:{subjects:t.subjects}};return await authenticateOidcStrategy({strategy:t.currentVercelProject===void 0?n:{...n,currentVercelProject:t.currentVercelProject},token:e})}function extractBearerToken(e){if(e===null)return null;let t=/^Bearer\s+(.+)$/i.exec(e)?.[1]?.trim();return t===void 0||t.length===0?null:t}function createIpAllowList(e){return createRuntimeIpAllowList(e)}function isIpAllowed(e,t){return e===null?!1:isRuntimeIpAllowed(e,t)}function createUnauthorizedResponse(e={}){let t=e.status??401,n=e.code??(t===403?`forbidden`:`unauthorized`),r=e.message??(t===403?`Forbidden.`:`Authorization is required for this route.`),i=e.challenges??[],a=new Headers({"cache-control":`no-store`});for(let e of i)a.append(`www-authenticate`,formatChallenge(e));return Response.json({code:n,error:r,ok:!1},{headers:a,status:t})}function formatChallenge(e){if(e.parameters===void 0||Object.keys(e.parameters).length===0)return e.scheme;let t=Object.entries(e.parameters).map(([e,t])=>`${e}="${escapeChallengeValue(t)}"`).join(`, `);return`${e.scheme} ${t}`}function escapeChallengeValue(e){return e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}var UnauthenticatedError=class extends Error{response;constructor(e={}){super(e.message??`Authorization is required for this route.`),this.name=`UnauthenticatedError`,this.response=createUnauthorizedResponse({...e,status:401})}},ForbiddenError=class extends Error{response;constructor(e={}){super(e.message??`Forbidden.`),this.name=`ForbiddenError`,this.response=createUnauthorizedResponse({...e,status:403})}};async function routeAuth(e,t){let n=Array.isArray(t)?t:[t];try{for(let t of n){let n=await t(e);if(n)return n}}catch(e){if(typeof e==`object`&&e&&`response`in e&&e.response instanceof Response)return e.response;throw e}return createUnauthorizedResponse({challenges:[{scheme:`Bearer`}]})}function placeholderAuth(){return()=>{if(process.env.VERCEL_ENV!==`production`)return null;throw new UnauthenticatedError({code:`eve_production_auth_not_configured`,message:`Production auth is not configured. Replace placeholderAuth() in agent/channels/eve.ts with your app's auth provider.`})}}function none(){return()=>ANONYMOUS_SESSION_AUTH_CONTEXT}function localDev(){return e=>process.env.VERCEL&&process.env.VERCEL_ENV===`development`||isLoopbackRequest(e)?LOCAL_DEV_SESSION_AUTH_CONTEXT:null}const LOOPBACK_HOSTNAMES=new Set([`localhost`,`[::1]`]),LOOPBACK_IPV4_PREFIX=/^127\./;function isLoopbackRequest(e){let t;try{t=new URL(e.url).hostname}catch{return!1}return!!(LOOPBACK_HOSTNAMES.has(t)||LOOPBACK_IPV4_PREFIX.test(t)||t.endsWith(`.localhost`))}const ANONYMOUS_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`none`,principalId:`anonymous`,principalType:`anonymous`},LOCAL_DEV_SESSION_AUTH_CONTEXT={attributes:{},authenticator:`local-dev`,principalId:`local-dev`,principalType:`local-dev`};async function verifyVercelOidc(e,t={}){if(e===null||e.length===0)return{ok:!1};let n=decodeUnverifiedJwtClaims(e);if(n===null)return vercelOidcLog.debug(`Rejected token that failed to decode as a JWT.`),{ok:!1};if(!n.issuer.startsWith(`https://oidc.vercel.com/`))return vercelOidcLog.debug(`Rejected token whose issuer is not a Vercel OIDC issuer.`,{issuer:n.issuer}),{ok:!1};if(n.audiences.length===0)return vercelOidcLog.debug(`Rejected token with no audience claim.`,{issuer:n.issuer}),{ok:!1};if(!n.audiences.some(e=>e.startsWith(`https://vercel.com/`)))return vercelOidcLog.debug(`Rejected token whose audience is not a Vercel audience.`,{audiences:n.audiences,issuer:n.issuer}),{ok:!1};let r=resolveCurrentVercelProject(t),i=await runOidcVerification(e,{acceptCurrentVercelProject:!0,audiences:n.audiences,currentVercelProject:r,issuer:n.issuer,subjects:t.subjects??[]});return i.kind===`authenticated`?(vercelOidcLog.debug(`Accepted Vercel OIDC token.`,{issuer:n.issuer,principalType:i.principal.principalType,subject:i.principal.subject}),{ok:!0,sessionAuth:createRuntimeSessionAuthContext(i.principal)}):(vercelOidcLog.debug(`Rejected Vercel OIDC token after verification.`,{audiences:n.audiences,issuer:n.issuer,reason:i.kind,subjectsConfigured:(t.subjects??[]).length>0,...i.kind===`misconfigured`?{detail:i.message}:{}}),{ok:!1})}function resolveCurrentVercelProject(e){if(e.currentVercelProject!==void 0)return e.currentVercelProject;let t=process.env.VERCEL_PROJECT_ID?.trim();if(t===void 0||t.length===0)return;let n=process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim();return n===void 0||n.length===0?{projectId:t}:{environment:n,projectId:t}}function vercelSubject(e){assertVercelSubjectSegment(`teamSlug`,e.teamSlug),assertVercelSubjectSegment(`projectName`,e.projectName);let t=e.environment??`production`;if(t!==`production`&&t!==`preview`&&t!==`development`&&t!==`*`)throw Error(`vercelSubject: invalid environment ${JSON.stringify(t)}; expected "production", "preview", "development", or "*".`);return`owner:${e.teamSlug}:project:${e.projectName}:environment:${t}`}function assertVercelSubjectSegment(e,t){if(t.length===0)throw Error(`vercelSubject: ${e} must be a non-empty string.`);if(t.includes(`*`)||t.includes(`:`))throw Error(`vercelSubject: ${e} ${JSON.stringify(t)} may not contain ${t.includes(`:`)?`':'`:`'*'`}. Hand-write the subject string when wildcards are intentional.`)}function vercelOidc(e={}){return async n=>{let r=extractBearerToken(n.headers.get(`authorization`)),i=e.currentVercelProject??(r!==null&&isLocalDevelopmentVercelOidcRequest(n)?await resolveVercelOidcCurrentProject(n):void 0),a=await verifyVercelOidc(r,i===void 0?e:{...e,currentVercelProject:i});return a.ok?a.sessionAuth:null}}function isLocalDevelopmentVercelOidcRequest(e){return process.env.VERCEL_ENV===`development`?!0:process.env.VERCEL_ENV===`preview`||process.env.VERCEL_ENV===`production`?!1:isLoopbackRequest(e)}function httpBasic(e){return t=>{let n=verifyHttpBasic(t.headers.get(`authorization`),e);return n.ok?n.sessionAuth:null}}function jwtHmac(e){return async t=>{let n=await verifyJwtHmac(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function jwtEcdsa(e){return async t=>{let n=await verifyJwtEcdsa(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function oidc(e){return async t=>{let n=await verifyOidc(extractBearerToken(t.headers.get(`authorization`)),e);return n.ok?n.sessionAuth:null}}function decodeUnverifiedJwtClaims(e){let t;try{t=decodeJwt(e)}catch{return null}return typeof t.iss!=`string`||t.iss.length===0?null:{audiences:typeof t.aud==`string`?[t.aud]:Array.isArray(t.aud)?t.aud.filter(e=>typeof e==`string`):[],issuer:t.iss}}export{ForbiddenError,UnauthenticatedError,createIpAllowList,createUnauthorizedResponse,extractBearerToken,httpBasic,isIpAllowed,isLoopbackRequest,jwtEcdsa,jwtHmac,localDev,none,oidc,placeholderAuth,routeAuth,vercelOidc,vercelSubject,verifyHttpBasic,verifyJwtEcdsa,verifyJwtHmac,verifyOidc,verifyVercelOidc};
@@ -1,3 +1,3 @@
1
1
  export { useEveAgent, type PrepareSend, type UseEveAgentHelpers, type UseEveAgentOptions, type UseEveAgentSnapshot, type UseEveAgentStatus, } from "#react/use-eve-agent.js";
2
2
  export { type EveAgentReducer, type EveAgentReducerEvent, type ClientInputRespondedEvent, type ClientMessageFailedEvent, type ClientMessageSubmittedEvent, } from "#client/reducer.js";
3
- export { defaultMessageReducer, type EveMessageData, type EveDynamicToolPart, type EveMessageInputRequest, type EveMessage, type EveMessageMetadata, type EveMessagePart, type EveMessageToolMetadata, } from "#client/message-reducer.js";
3
+ export { defaultMessageReducer, type EveAuthorizationChallenge, type EveAuthorizationOutcome, type EveAuthorizationPart, type EveMessageData, type EveDynamicToolPart, type EveMessageInputRequest, type EveMessage, type EveMessageMetadata, type EveMessagePart, type EveMessageToolMetadata, } from "#client/message-reducer.js";
@@ -3,8 +3,9 @@ import { type RuntimeModelReference } from "#runtime/agent/bootstrap.js";
3
3
  /**
4
4
  * Returns true when authored runtime models should resolve through the
5
5
  * dedicated deterministic mock adapter. The adapter is internal to the test
6
- * tiers: it activates only under `NODE_ENV=test`, keeping the unit,
7
- * integration, and scenario suites deterministic and credential-free.
6
+ * tiers: unit, integration, and scenario tests activate it through
7
+ * `NODE_ENV=test`; spawned smoke servers use the explicit opt-in environment
8
+ * variable so their package-manager build keeps its normal environment.
8
9
  */
9
10
  export declare function shouldMockAuthoredRuntimeModels(): boolean;
10
11
  /**
@@ -1,4 +1,4 @@
1
- import{z}from"#compiled/zod/index.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{MockLanguageModelV3}from"ai/test";import{FINAL_OUTPUT_TOOL_NAME}from"#runtime/framework-tools/final-output.js";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{createMockAuthoredToolInput,formatToolOutput,resolveMockFixtureToken,resolveWeatherCity}from"#runtime/agent/mock-model-fixtures.js";import{findRelevantSkill,getActivatedSkillIds,getAvailableSkills}from"#runtime/agent/mock-model-skill-selection.js";import{createJsonSchemaSample}from"#runtime/agent/mock-structured-output.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict();function shouldMockAuthoredRuntimeModels(){return process.env.NODE_ENV===`test`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`eve-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=createFollowUpToolCallResult({modelId:t,options:e,result:n});if(r!==null)return r}else{let n=createSkillLoadResult(e.prompt,t)??createAuthoredToolCallResult(e,t);if(n!==null)return n}let r=createFinalOutputResult(e,t);if(r!==null)return r;let i=n===null?createAssistantMessage(e.prompt):formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i),text:i})}function createFinalOutputResult(e,t){let n=getAvailableTools(e).find(e=>e.name===FINAL_OUTPUT_TOOL_NAME);if(n===void 0)return null;let i=createJsonSchemaSample(n.inputSchema);return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(JSON.stringify(i)),toolCallId:createToolCallId(FINAL_OUTPUT_TOOL_NAME),toolName:FINAL_OUTPUT_TOOL_NAME})}function resolveMockAuthoredRuntimeModel(e){return!shouldMockAuthoredRuntimeModels()||e.id===BOOTSTRAP_RUNTIME_MODEL_ID?null:createMockAuthoredRuntimeModel(e)}function createSkillLoadResult(e,n){let r=getLastUserPromptText(e);if(r===null||getActivatedSkillIds(e).length>0)return null;let i=findRelevantSkill(getAvailableSkills(e),r);return i===null?null:createToolCallGenerateResult({input:{skill:i.name},inputTokens:estimateTokenCount(getPromptText(e)),modelId:n,outputTokens:estimateTokenCount(i.name),toolCallId:`call_load_skill`,toolName:LOAD_SKILL_TOOL_NAME})}function createAuthoredToolCallResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=findRelevantTool(getAvailableTools(e),n);if(r===null)return null;let i=createMockAuthoredToolInput(r,n,resolveWeatherCity(n));return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(Object.values(i).join(` `)),toolCallId:createToolCallId(r.name),toolName:r.name})}function createFollowUpToolCallResult(e){let t=findNextExplicitToolAfterResult({previousToolName:e.result.toolName,prompt:e.options.prompt,tools:getAvailableTools(e.options)});if(t===null)return null;let n=createFollowUpToolInput(e.result.output);return n===null?null:createToolCallGenerateResult({input:n,inputTokens:estimateTokenCount(getPromptText(e.options.prompt)),modelId:e.modelId,outputTokens:estimateTokenCount(Object.values(n).join(` `)),toolCallId:createToolCallId(t.name),toolName:t.name})}function createAssistantMessage(e){let t=getLastUserPromptText(e)??`Hello from eve`,n=getSystemPromptLabels(e),r=resolveSystemProbe(e),i=resolveMockFixtureToken(e);return i===null?n.length>0?r===null?`Bootstrap reply [${n.join(`, `)}]: ${t}`:`Bootstrap reply [${n.join(`, `)}; probe=${r}]: ${t}`:r===null?`Bootstrap reply: ${t}`:`Bootstrap reply [probe=${r}]: ${t}`:i}function formatToolResultReply(e,t){if(e.isError)return`Local weather tool failed: ${formatToolOutput(e.output)}`;if(isWeatherPayload(e.output))return`Used local weather tool for ${e.output.city}: ${e.output.condition}, ${e.output.temperatureF}F. ${e.output.summary}`;let n=getLastUserPromptText(t)??`Hello from eve`;return`Used ${e.toolName} for "${n}": ${formatToolOutput(e.output)}`}function createToolCallGenerateResult(e){return{content:[{input:JSON.stringify(e.input),toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-call`}],finishReason:{raw:void 0,unified:`tool-calls`},response:{id:`bootstrap-response`,modelId:e.modelId,timestamp:new Date(`2026-03-16T00:00:00.000Z`)},usage:{inputTokens:{cacheRead:0,cacheWrite:0,noCache:e.inputTokens,total:e.inputTokens},outputTokens:{reasoning:0,text:e.outputTokens,total:e.outputTokens}},warnings:[]}}function getAvailableTools(e){return(e.tools??[]).flatMap(e=>e.type===`function`?[{description:e.description,inputSchema:`inputSchema`in e?e.inputSchema:void 0,name:e.name,outputSchema:`outputSchema`in e?e.outputSchema:void 0}]:[])}function getLastAuthoredToolResult(e){for(let n of[...e].reverse()){if(n.role===`user`)return null;if(!(n.role!==`tool`&&n.role!==`assistant`)){for(let e of[...n.content].reverse())if(!(typeof e==`string`||e.type!==`tool-result`)&&e.toolName!==LOAD_SKILL_TOOL_NAME)return{isError:e.output.type===`error-json`||e.output.type===`error-text`||e.output.type===`execution-denied`,output:e.output.type===`execution-denied`?{reason:e.output.reason??null,type:e.output.type}:e.output.value,toolCallId:e.toolCallId,toolName:e.toolName}}}return null}function findNextExplicitToolAfterResult(e){let t=getLastUserPromptText(e.prompt);if(t===null)return null;let n=normalizeText(t),r=n.indexOf(normalizeText(e.previousToolName));return r<0?null:e.tools.filter(t=>t.name!==e.previousToolName).flatMap(e=>{let t=n.indexOf(normalizeText(e.name),r+1);return t<0?[]:[{index:t,tool:e}]}).sort((e,t)=>e.index-t.index)[0]?.tool??null}function createFollowUpToolInput(e){return isRecord(e)&&typeof e.stepKey==`string`?{stepKey:e.stepKey}:null}function getSystemPromptLabels(e){let t=e.filter(e=>e.role===`system`);if(t.length===0)return[];let n=t.flatMap(e=>{let t=getPromptContentText(e.content);if(t.startsWith(`Available skills
1
+ import{z}from"#compiled/zod/index.js";import{LOAD_SKILL_TOOL_NAME}from"#runtime/skills/fragment-context.js";import{MockLanguageModelV3}from"ai/test";import{FINAL_OUTPUT_TOOL_NAME}from"#runtime/framework-tools/final-output.js";import{BOOTSTRAP_RUNTIME_MODEL_ID,BOOTSTRAP_RUNTIME_SYSTEM_PROMPT}from"#runtime/agent/bootstrap.js";import{createBootstrapGenerateResult,createBootstrapStreamResult,estimateTokenCount,getLastUserPromptText,getPromptContentText,getPromptText}from"#runtime/agent/bootstrap-model-utils.js";import{createMockAuthoredToolInput,formatToolOutput,resolveMockFixtureToken,resolveWeatherCity}from"#runtime/agent/mock-model-fixtures.js";import{findRelevantSkill,getActivatedSkillIds,getAvailableSkills}from"#runtime/agent/mock-model-skill-selection.js";import{createJsonSchemaSample}from"#runtime/agent/mock-structured-output.js";const authoredRuntimeModelMocks=new Map,bootstrapWeatherPayloadSchema=z.object({city:z.string(),condition:z.string(),summary:z.string(),temperatureF:z.number().finite()}).strict();function shouldMockAuthoredRuntimeModels(){return process.env.NODE_ENV===`test`||process.env.EVE_MOCK_AUTHORED_MODELS===`1`}function createMockAuthoredRuntimeModel(e){let t=authoredRuntimeModelMocks.get(e.id);if(t!==void 0)return t;let r=new MockLanguageModelV3({modelId:e.id,provider:`eve-runtime-mock`,doGenerate:async t=>createMockModelResult(t,e.id),doStream:async t=>createBootstrapStreamResult(createMockModelResult(t,e.id))});return authoredRuntimeModelMocks.set(e.id,r),r}function createMockModelResult(e,t){let n=getLastAuthoredToolResult(e.prompt);if(n!==null){let r=createFollowUpToolCallResult({modelId:t,options:e,result:n});if(r!==null)return r}else{let n=createSkillLoadResult(e.prompt,t)??createAuthoredToolCallResult(e,t);if(n!==null)return n}let r=createFinalOutputResult(e,t);if(r!==null)return r;let i=n===null?createAssistantMessage(e.prompt):formatToolResultReply(n,e.prompt);return createBootstrapGenerateResult({inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(i),text:i})}function createFinalOutputResult(e,t){let n=getAvailableTools(e).find(e=>e.name===FINAL_OUTPUT_TOOL_NAME);if(n===void 0)return null;let i=createJsonSchemaSample(n.inputSchema);return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(JSON.stringify(i)),toolCallId:createToolCallId(FINAL_OUTPUT_TOOL_NAME),toolName:FINAL_OUTPUT_TOOL_NAME})}function resolveMockAuthoredRuntimeModel(e){return!shouldMockAuthoredRuntimeModels()||e.id===BOOTSTRAP_RUNTIME_MODEL_ID?null:createMockAuthoredRuntimeModel(e)}function createSkillLoadResult(e,n){let r=getLastUserPromptText(e);if(r===null||getActivatedSkillIds(e).length>0)return null;let i=findRelevantSkill(getAvailableSkills(e),r);return i===null?null:createToolCallGenerateResult({input:{skill:i.name},inputTokens:estimateTokenCount(getPromptText(e)),modelId:n,outputTokens:estimateTokenCount(i.name),toolCallId:`call_load_skill`,toolName:LOAD_SKILL_TOOL_NAME})}function createAuthoredToolCallResult(e,t){let n=getLastUserPromptText(e.prompt);if(n===null)return null;let r=findRelevantTool(getAvailableTools(e),n);if(r===null)return null;let i=createMockAuthoredToolInput(r,n,resolveWeatherCity(n));return createToolCallGenerateResult({input:i,inputTokens:estimateTokenCount(getPromptText(e.prompt)),modelId:t,outputTokens:estimateTokenCount(Object.values(i).join(` `)),toolCallId:createToolCallId(r.name),toolName:r.name})}function createFollowUpToolCallResult(e){let t=findNextExplicitToolAfterResult({previousToolName:e.result.toolName,prompt:e.options.prompt,tools:getAvailableTools(e.options)});if(t===null)return null;let n=createFollowUpToolInput(e.result.output);return n===null?null:createToolCallGenerateResult({input:n,inputTokens:estimateTokenCount(getPromptText(e.options.prompt)),modelId:e.modelId,outputTokens:estimateTokenCount(Object.values(n).join(` `)),toolCallId:createToolCallId(t.name),toolName:t.name})}function createAssistantMessage(e){let t=getLastUserPromptText(e)??`Hello from eve`,n=getSystemPromptLabels(e),r=resolveSystemProbe(e),i=resolveMockFixtureToken(e);return i===null?n.length>0?r===null?`Bootstrap reply [${n.join(`, `)}]: ${t}`:`Bootstrap reply [${n.join(`, `)}; probe=${r}]: ${t}`:r===null?`Bootstrap reply: ${t}`:`Bootstrap reply [probe=${r}]: ${t}`:i}function formatToolResultReply(e,t){if(e.isError)return`Local weather tool failed: ${formatToolOutput(e.output)}`;if(isWeatherPayload(e.output))return`Used local weather tool for ${e.output.city}: ${e.output.condition}, ${e.output.temperatureF}F. ${e.output.summary}`;let n=getLastUserPromptText(t)??`Hello from eve`;return`Used ${e.toolName} for "${n}": ${formatToolOutput(e.output)}`}function createToolCallGenerateResult(e){return{content:[{input:JSON.stringify(e.input),toolCallId:e.toolCallId,toolName:e.toolName,type:`tool-call`}],finishReason:{raw:void 0,unified:`tool-calls`},response:{id:`bootstrap-response`,modelId:e.modelId,timestamp:new Date(`2026-03-16T00:00:00.000Z`)},usage:{inputTokens:{cacheRead:0,cacheWrite:0,noCache:e.inputTokens,total:e.inputTokens},outputTokens:{reasoning:0,text:e.outputTokens,total:e.outputTokens}},warnings:[]}}function getAvailableTools(e){return(e.tools??[]).flatMap(e=>e.type===`function`?[{description:e.description,inputSchema:`inputSchema`in e?e.inputSchema:void 0,name:e.name,outputSchema:`outputSchema`in e?e.outputSchema:void 0}]:[])}function getLastAuthoredToolResult(e){for(let n of[...e].reverse()){if(n.role===`user`)return null;if(!(n.role!==`tool`&&n.role!==`assistant`)){for(let e of[...n.content].reverse())if(!(typeof e==`string`||e.type!==`tool-result`)&&e.toolName!==LOAD_SKILL_TOOL_NAME)return{isError:e.output.type===`error-json`||e.output.type===`error-text`||e.output.type===`execution-denied`,output:e.output.type===`execution-denied`?{reason:e.output.reason??null,type:e.output.type}:e.output.value,toolCallId:e.toolCallId,toolName:e.toolName}}}return null}function findNextExplicitToolAfterResult(e){let t=getLastUserPromptText(e.prompt);if(t===null)return null;let n=normalizeText(t),r=n.indexOf(normalizeText(e.previousToolName));return r<0?null:e.tools.filter(t=>t.name!==e.previousToolName).flatMap(e=>{let t=n.indexOf(normalizeText(e.name),r+1);return t<0?[]:[{index:t,tool:e}]}).sort((e,t)=>e.index-t.index)[0]?.tool??null}function createFollowUpToolInput(e){return isRecord(e)&&typeof e.stepKey==`string`?{stepKey:e.stepKey}:null}function getSystemPromptLabels(e){let t=e.filter(e=>e.role===`system`);if(t.length===0)return[];let n=t.flatMap(e=>{let t=getPromptContentText(e.content);if(t.startsWith(`Available skills
2
2
  `))return[];let n=t.split(`
3
3
  `).map(e=>e.trim()).filter(e=>e.length>0),r=[];for(let e of n){if(e===BOOTSTRAP_RUNTIME_SYSTEM_PROMPT||e===`Available skills`)continue;let t=/^System \((.+)\)$/.exec(e);if(t?.[1]){r.push(t[1]);continue}let n=/^Skill \((.+)\)$/.exec(e);n?.[1]&&r.push(n[1])}if(r.length>0)return r;let i=n.find(e=>e!==BOOTSTRAP_RUNTIME_SYSTEM_PROMPT&&e!==`Available skills`);return i===void 0?[]:[i]});return[...new Set(n)]}function findRelevantTool(e,n){let r=normalizeText(n),i=e.find(e=>e.name!==`agent`&&e.name!==LOAD_SKILL_TOOL_NAME&&r.includes(normalizeText(e.name)));return i===void 0?/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(r)?e.find(e=>/\b(forecast|temperature|weather|wind|rain|snow)\b/u.test(normalizeText(`${e.name} ${e.description??``}`)))??null:null:i}function normalizeText(e){return e.toLowerCase().replace(/[^a-z0-9]+/gu,` `).trim()}function createToolCallId(e){return`call_${e.toLowerCase().replace(/[^a-z0-9]+/gu,`_`).replace(/^_+|_+$/gu,``)||`tool`}`}function resolveSystemProbe(e){let t=e.filter(e=>e.role===`system`).map(e=>getPromptContentText(e.content)).join(`
4
4
  `);return/hmr-probe:\s*([^\n]+)/iu.exec(t)?.[1]?.trim()||null}function isWeatherPayload(e){return bootstrapWeatherPayloadSchema.safeParse(e).success}function isRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}export{createMockAuthoredRuntimeModel,resolveMockAuthoredRuntimeModel,shouldMockAuthoredRuntimeModels};
@@ -20,6 +20,8 @@ import type { AuthorizationDefinition, ConnectionPrincipal } from "#runtime/conn
20
20
  * issuer prefix prevents collisions when the same `id` across
21
21
  * identity providers (for example Slack `U123` vs Google `U123`)
22
22
  * would otherwise alias to the same cache slot.
23
+ * - `{ type: "user", id }` → `"user:${id}"`. This is the native
24
+ * Vercel Connect user projection.
23
25
  */
24
26
  export declare function principalKey(principal: ConnectionPrincipal): string;
25
27
  /**
@@ -1 +1 @@
1
- import{AuthKey}from"#context/keys.js";import{contextStorage}from"#context/container.js";import{ConnectionAuthorizationFailedError}from"#public/connections/errors.js";function principalKey(e){return e.type===`app`?`app`:`user:${e.issuer}:${e.id}`}function resolveConnectionPrincipal(r,i,a=contextStorage.getStore()){if(i.principalType===`app`)return{type:`app`};let o=a?.get(AuthKey);if(o==null||o.principalType!==`user`)throw new ConnectionAuthorizationFailedError(r,{message:buildUserPrincipalRequiredMessage(r,a,o?.principalType),reason:`principal_required`,retryable:!1});return{attributes:o.attributes,id:o.principalId,issuer:o.issuer??o.authenticator,type:`user`}}function buildUserPrincipalRequiredMessage(e,t,n){let r;return r=t===void 0?`it was invoked outside an eve context, so no authenticated user can be resolved.`:n===void 0?`the active session has no authenticated user.`:`the active session is scoped to "${n}", not an authenticated user.`,`Connection "${e}" is user-scoped, but ${r} User-scoped connections require route auth that resolves an authenticated user. If this connection should use credentials shared by the agent instead, configure it as an app-scoped connection.`}export{principalKey,resolveConnectionPrincipal};
1
+ import{AuthKey}from"#context/keys.js";import{contextStorage}from"#context/container.js";import{ConnectionAuthorizationFailedError}from"#public/connections/errors.js";function principalKey(e){return e.type===`app`?`app`:e.issuer===void 0?`user:${e.id}`:`user:${e.issuer}:${e.id}`}function resolveConnectionPrincipal(r,i,a=contextStorage.getStore()){if(i.principalType===`app`)return{type:`app`};let o=a?.get(AuthKey);if(o==null||o.principalType!==`user`)throw new ConnectionAuthorizationFailedError(r,{message:buildUserPrincipalRequiredMessage(r,i,a,o),reason:`principal_required`,retryable:!1});return i.vercelConnect!==void 0&&isVercelDevelopmentUser(o)?{attributes:o.attributes,id:o.subject??o.principalId,type:`user`}:{attributes:o.attributes,id:o.principalId,issuer:o.issuer??o.authenticator,type:`user`}}function isVercelDevelopmentUser(e){return e.authenticator===`oidc`&&e.issuer?.startsWith(`https://oidc.vercel.com/`)===!0&&e.attributes.environment===`development`&&e.subject===e.attributes.user_id}function buildUserPrincipalRequiredMessage(e,t,n,r){let i;return i=n===void 0?`it was invoked outside an eve context, so no authenticated user can be resolved.`:r==null?`the active session has no authenticated user.`:t.vercelConnect!==void 0&&r.authenticator===`local-dev`?`the local request fell back to local development access instead of authenticating a Vercel user. Ensure this directory is linked and the Vercel CLI can mint a Vercel OIDC token, then retry.`:`the active session is scoped to "${r.principalType}", not an authenticated user.`,`Connection "${e}" is user-scoped, but ${i} User-scoped connections require route auth that resolves an authenticated user. If this connection should use credentials shared by the agent instead, configure it as an app-scoped connection.`}export{principalKey,resolveConnectionPrincipal};
@@ -70,13 +70,16 @@ export type ToolFilterDefinition = {
70
70
  * - `{ type: "user", id, issuer }`: per end-user identity; the token
71
71
  * cache keys on `issuer + id` so the same `id` across different
72
72
  * IdPs (Slack `U123` vs Google `U123`) never collides.
73
+ * - `{ type: "user", id }`: Vercel Connect's native user subject, used for a
74
+ * verified Vercel development user. The Vercel OIDC issuer is not forwarded
75
+ * because Connect rejects it.
73
76
  */
74
77
  export type ConnectionPrincipal = {
75
78
  readonly type: "app";
76
79
  } | {
77
80
  readonly type: "user";
78
81
  readonly id: string;
79
- readonly issuer: string;
82
+ readonly issuer?: string;
80
83
  readonly attributes?: Readonly<Record<string, string | readonly string[]>>;
81
84
  };
82
85
  /**
@@ -1,11 +1,6 @@
1
1
  import type { ResolvedChannelDefinition } from "#runtime/types.js";
2
2
  /**
3
- * Framework default for the eve channel. Mirrors verbatim the scaffold
4
- * written by eve into `agent/channels/eve.ts`, so the
5
- * behavior of "no authored file" and "scaffolded file untouched" is
6
- * byte-identical — and the local-dev / Vercel branching lives in a
7
- * single named helper (`localDev`) instead of an env check buried in
8
- * the framework.
3
+ * Framework default for the eve channel.
9
4
  */
10
5
  export declare function getFrameworkChannelDefinitions(): readonly ResolvedChannelDefinition[];
11
6
  export declare function getAllFrameworkChannelNames(): ReadonlySet<string>;
@@ -1 +1 @@
1
- import{localDev,vercelOidc}from"#public/channels/auth.js";import{isHttpRouteDefinition}from"#channel/routes.js";import{eveChannel}from"#public/channels/eve.js";import{getConnectionCallbackChannelDefinitions,getConnectionCallbackChannelNames}from"#runtime/connections/callback-route.js";import{getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames}from"#runtime/session-callback-route.js";function getFrameworkChannelDefinitions(){let r=eveChannel({auth:[localDev(),vercelOidc()]}),i=[];for(let e of r.routes)isHttpRouteDefinition(e)&&i.push({name:`eve`,method:e.method.toUpperCase(),urlPath:e.path,fetch:async(t,n)=>e.handler(t,n),handler:e.handler,adapter:r.adapter,logicalPath:`framework://channels/${e.path}`,sourceId:`eve:framework:${e.method.toLowerCase()}-${e.path}`,sourceKind:`module`});return i.push(...getConnectionCallbackChannelDefinitions(),...getSessionCallbackChannelDefinitions()),i}function getAllFrameworkChannelNames(){return new Set([`eve`,...getConnectionCallbackChannelNames(),...getSessionCallbackChannelNames()])}export{getAllFrameworkChannelNames,getFrameworkChannelDefinitions};
1
+ import{localDev,vercelOidc}from"#public/channels/auth.js";import{isHttpRouteDefinition}from"#channel/routes.js";import{eveChannel}from"#public/channels/eve.js";import{getConnectionCallbackChannelDefinitions,getConnectionCallbackChannelNames}from"#runtime/connections/callback-route.js";import{getSessionCallbackChannelDefinitions,getSessionCallbackChannelNames}from"#runtime/session-callback-route.js";function getFrameworkChannelDefinitions(){let r=eveChannel({auth:[vercelOidc(),localDev()]}),i=[];for(let e of r.routes)isHttpRouteDefinition(e)&&i.push({name:`eve`,method:e.method.toUpperCase(),urlPath:e.path,fetch:async(t,n)=>e.handler(t,n),handler:e.handler,adapter:r.adapter,logicalPath:`framework://channels/${e.path}`,sourceId:`eve:framework:${e.method.toLowerCase()}-${e.path}`,sourceKind:`module`});return i.push(...getConnectionCallbackChannelDefinitions(),...getSessionCallbackChannelDefinitions()),i}function getAllFrameworkChannelNames(){return new Set([`eve`,...getConnectionCallbackChannelNames(),...getSessionCallbackChannelNames()])}export{getAllFrameworkChannelNames,getFrameworkChannelDefinitions};
@@ -1 +1 @@
1
- import{z}from"#compiled/zod/index.js";import{createRemoteJWKSet,jwtVerify}from"#compiled/jose/index.js";import{areTokenClaimMatchersSatisfied,createJwtAuthenticatedCallerPrincipal}from"#runtime/governance/auth/token-claims.js";const oidcDiscoveryDocumentSchema=z.object({issuer:z.string().optional(),jwks_uri:z.string().url()}).passthrough(),oidcDiscoveryDocumentCache=new Map,oidcJwksCache=new Map;async function authenticateOidcStrategy(e){let t;try{t=await getOidcRemoteJwks(e.strategy)}catch(e){return{kind:`misconfigured`,message:`Failed to load OIDC discovery metadata. ${e instanceof Error?e.message:`Unknown discovery failure.`}`}}try{let a=await jwtVerify(e.token,t,{audience:[...e.strategy.audiences],clockTolerance:e.strategy.clockSkewSeconds,issuer:e.strategy.issuer});if(e.strategy.acceptCurrentVercelProject&&e.strategy.issuer.startsWith(`https://oidc.vercel.com/`)&&a.payload.external_sub!==void 0)return typeof a.payload.external_sub!=`string`||a.payload.external_sub.length===0||!currentVercelProjectMatches({payload:a.payload})||!currentVercelEnvironmentMatches({payload:a.payload})?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:createJwtAuthenticatedCallerPrincipal({authenticator:`oidc`,issuerClaims:[`external_iss`,`connector_id`],payload:a.payload,principalType:`user`,subjectClaim:`external_sub`})};if(typeof a.payload.sub!=`string`||a.payload.sub.length===0)return{kind:`not-authenticated`};let o=e.strategy.acceptCurrentVercelProject&&isCurrentVercelProjectToken({issuer:e.strategy.issuer,payload:a.payload}),s=o&&isCurrentVercelEnvironmentToken({payload:a.payload});return!o&&!areTokenClaimMatchersSatisfied(a.payload,e.strategy)?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:createJwtAuthenticatedCallerPrincipal({authenticator:`oidc`,payload:a.payload,principalType:s?`runtime`:`service`})}}catch{return{kind:`not-authenticated`}}}async function getOidcRemoteJwks(e){let n=await getOidcDiscoveryDocument(e.discoveryUrl),r=oidcJwksCache.get(n.jwks_uri);if(r!==void 0)return r;let i=createRemoteJWKSet(new URL(n.jwks_uri));return oidcJwksCache.set(n.jwks_uri,i),i}async function getOidcDiscoveryDocument(e){let t=oidcDiscoveryDocumentCache.get(e);if(t!==void 0)return await t;let n=fetch(e,{headers:{accept:`application/json`}}).then(async e=>{if(!e.ok)throw Error(`Discovery route returned HTTP ${e.status}.`);return oidcDiscoveryDocumentSchema.parse(await e.json())}).catch(t=>{throw oidcDiscoveryDocumentCache.delete(e),t});return oidcDiscoveryDocumentCache.set(e,n),await n}function isCurrentVercelProjectToken(e){if(!e.issuer.startsWith(`https://oidc.vercel.com`))return!1;let t=process.env.VERCEL_PROJECT_ID?.trim();return t===void 0||t.length===0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t}function currentVercelProjectMatches(e){let t=process.env.VERCEL_PROJECT_ID?.trim();return t===void 0||t.length===0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t}function isCurrentVercelEnvironmentToken(e){let t=getCurrentVercelEnvironment();return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}function currentVercelEnvironmentMatches(e){let t=getCurrentVercelEnvironment();return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}function getCurrentVercelEnvironment(){return process.env.VERCEL_TARGET_ENV?.trim()||process.env.VERCEL_ENV?.trim()||void 0}export{authenticateOidcStrategy};
1
+ import{z}from"#compiled/zod/index.js";import{createRemoteJWKSet,jwtVerify}from"#compiled/jose/index.js";import{areTokenClaimMatchersSatisfied,createJwtAuthenticatedCallerPrincipal}from"#runtime/governance/auth/token-claims.js";const oidcDiscoveryDocumentSchema=z.object({issuer:z.string().optional(),jwks_uri:z.string().url()}).passthrough(),oidcDiscoveryDocumentCache=new Map,oidcJwksCache=new Map;async function authenticateOidcStrategy(e){let t;try{t=await getOidcRemoteJwks(e.strategy)}catch(e){return{kind:`misconfigured`,message:`Failed to load OIDC discovery metadata. ${e instanceof Error?e.message:`Unknown discovery failure.`}`}}try{let a=await jwtVerify(e.token,t,{audience:[...e.strategy.audiences],clockTolerance:e.strategy.clockSkewSeconds,issuer:e.strategy.issuer});if(e.strategy.acceptCurrentVercelProject&&e.strategy.issuer.startsWith(`https://oidc.vercel.com/`)&&a.payload.external_sub!==void 0)return typeof a.payload.external_sub!=`string`||a.payload.external_sub.length===0||!currentVercelProjectMatches({payload:a.payload,strategy:e.strategy})||!currentVercelEnvironmentMatches({payload:a.payload,strategy:e.strategy})?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:createJwtAuthenticatedCallerPrincipal({authenticator:`oidc`,issuerClaims:[`external_iss`,`connector_id`],payload:a.payload,principalType:`user`,subjectClaim:`external_sub`})};if(e.strategy.acceptCurrentVercelProject&&e.strategy.issuer.startsWith(`https://oidc.vercel.com/`)&&a.payload.user_id!==void 0){if(typeof a.payload.user_id!=`string`||a.payload.user_id.length===0||a.payload.environment!==`development`||!currentVercelProjectMatches({payload:a.payload,strategy:e.strategy}))return{kind:`caller-not-allowed`};if(currentVercelEnvironmentMatches({payload:a.payload,strategy:e.strategy}))return{kind:`authenticated`,principal:createJwtAuthenticatedCallerPrincipal({authenticator:`oidc`,payload:a.payload,principalType:`user`,subjectClaim:`user_id`})};if(e.strategy.currentVercelProject?.environment!==`preview`)return{kind:`caller-not-allowed`}}if(typeof a.payload.sub!=`string`||a.payload.sub.length===0)return{kind:`not-authenticated`};let o=e.strategy.acceptCurrentVercelProject&&isCurrentVercelProjectToken({issuer:e.strategy.issuer,payload:a.payload,strategy:e.strategy}),s=o&&isCurrentVercelEnvironmentToken({payload:a.payload,strategy:e.strategy});return!o&&!areTokenClaimMatchersSatisfied(a.payload,e.strategy)?{kind:`caller-not-allowed`}:{kind:`authenticated`,principal:createJwtAuthenticatedCallerPrincipal({authenticator:`oidc`,payload:a.payload,principalType:s?`runtime`:`service`})}}catch{return{kind:`not-authenticated`}}}async function getOidcRemoteJwks(e){let n=await getOidcDiscoveryDocument(e.discoveryUrl),r=oidcJwksCache.get(n.jwks_uri);if(r!==void 0)return r;let i=createRemoteJWKSet(new URL(n.jwks_uri));return oidcJwksCache.set(n.jwks_uri,i),i}async function getOidcDiscoveryDocument(e){let t=oidcDiscoveryDocumentCache.get(e);if(t!==void 0)return await t;let n=fetch(e,{headers:{accept:`application/json`}}).then(async e=>{if(!e.ok)throw Error(`Discovery route returned HTTP ${e.status}.`);return oidcDiscoveryDocumentSchema.parse(await e.json())}).catch(t=>{throw oidcDiscoveryDocumentCache.delete(e),t});return oidcDiscoveryDocumentCache.set(e,n),await n}function isCurrentVercelProjectToken(e){if(!e.issuer.startsWith(`https://oidc.vercel.com`))return!1;let t=e.strategy.currentVercelProject;return t===void 0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t.projectId}function currentVercelProjectMatches(e){let t=e.strategy.currentVercelProject;return t===void 0?!1:typeof e.payload.project_id==`string`&&e.payload.project_id===t.projectId}function isCurrentVercelEnvironmentToken(e){let t=e.strategy.currentVercelProject?.environment;return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}function currentVercelEnvironmentMatches(e){let t=e.strategy.currentVercelProject?.environment;return t===void 0||t.length===0?!1:typeof e.payload.environment==`string`&&e.payload.environment===t}export{authenticateOidcStrategy};
@@ -22,6 +22,11 @@ export interface ResolvedTokenClaimMatchers {
22
22
  readonly claims?: Readonly<Record<string, readonly string[]>>;
23
23
  readonly subjects?: readonly string[];
24
24
  }
25
+ /** One Vercel project and environment accepted by a Vercel OIDC strategy. */
26
+ export interface CurrentVercelProject {
27
+ readonly environment?: string;
28
+ readonly projectId: string;
29
+ }
25
30
  /**
26
31
  * Resolved HTTP Basic auth strategy.
27
32
  */
@@ -58,27 +63,26 @@ export interface ResolvedJwtEcdsaAuthStrategy extends ResolvedTokenClaimMatchers
58
63
  export interface ResolvedOidcAuthStrategy extends ResolvedTokenClaimMatchers {
59
64
  /**
60
65
  * Vercel-platform extension. When `true` and the token's issuer is
61
- * a Vercel OIDC issuer, tokens minted for the current
62
- * `VERCEL_PROJECT_ID` are accepted unconditionally — in addition to
66
+ * a Vercel OIDC issuer, tokens minted for the configured current project
67
+ * are accepted unconditionally — in addition to
63
68
  * the author-supplied `subjects`/`claims` matchers — so the
64
69
  * deployment's own runtime callers (subagent, internal fetches)
65
- * always authenticate. Tokens that additionally match the current
66
- * `VERCEL_TARGET_ENV` / `VERCEL_ENV` are tagged
70
+ * always authenticate. Tokens that additionally match the configured
71
+ * current environment are tagged
67
72
  * `principalType: "runtime"`; other current-project tokens are
68
73
  * tagged `"service"`.
69
74
  *
70
- * Vercel OIDC tokens with an `external_sub` claim are user tokens.
71
- * They must satisfy the current project/environment constraints when
72
- * those environment variables are configured, and then authenticate as
73
- * `principalType: "user"` with `external_sub` as their subject and
74
- * `external_iss` / `connector_id` as their issuer when present.
75
+ * Vercel OIDC tokens with an `external_sub` claim are user tokens. So are
76
+ * development tokens with a `user_id` claim when the configured environment
77
+ * is `development`. Both must satisfy the current project/environment bind.
75
78
  *
76
- * Set exclusively by `verifyVercelOidc`. The generic public
79
+ * Set exclusively by Vercel-specific verification. The generic public
77
80
  * `verifyOidc` always passes `false`.
78
81
  */
79
82
  readonly acceptCurrentVercelProject: boolean;
80
83
  readonly audiences: readonly string[];
81
84
  readonly clockSkewSeconds: number;
85
+ readonly currentVercelProject?: CurrentVercelProject;
82
86
  readonly discoveryUrl: string;
83
87
  readonly issuer: string;
84
88
  readonly kind: "oidc";
@@ -0,0 +1,12 @@
1
+ import type { CurrentVercelProject } from "#runtime/governance/auth/types.js";
2
+ type VercelOidcProjectResolver = () => CurrentVercelProject | undefined | Promise<CurrentVercelProject | undefined>;
3
+ /**
4
+ * Binds the current local project only to one request. The global symbol makes
5
+ * the binding visible to both Nitro-inlined and disk-imported eve modules.
6
+ */
7
+ export declare function withVercelOidcProjectResolver<T>(input: {
8
+ readonly request: Request;
9
+ readonly resolveCurrentProject: VercelOidcProjectResolver;
10
+ }, callback: () => Promise<T> | T): Promise<T>;
11
+ export declare function resolveVercelOidcCurrentProject(request: Request): Promise<CurrentVercelProject | undefined>;
12
+ export {};
@@ -0,0 +1 @@
1
+ const VERCEL_OIDC_PROJECT_RESOLVERS=Symbol.for(`eve.vercel-oidc-project-resolvers`),globalResolverRegistry=globalThis;globalResolverRegistry[VERCEL_OIDC_PROJECT_RESOLVERS]===void 0&&(globalResolverRegistry[VERCEL_OIDC_PROJECT_RESOLVERS]=new WeakMap);const projectResolvers=globalResolverRegistry[VERCEL_OIDC_PROJECT_RESOLVERS];async function withVercelOidcProjectResolver(e,t){let n=projectResolvers.get(e.request);projectResolvers.set(e.request,e.resolveCurrentProject);try{return await t()}finally{n===void 0?projectResolvers.delete(e.request):projectResolvers.set(e.request,n)}}async function resolveVercelOidcCurrentProject(e){let t=projectResolvers.get(e);return t===void 0?void 0:await t()}export{resolveVercelOidcCurrentProject,withVercelOidcProjectResolver};
@@ -6,6 +6,11 @@ import type { DevelopmentCredentialGate } from "./credential-gate.js";
6
6
  * credentials through this default path.
7
7
  */
8
8
  export declare function resolveDevelopmentClientOptions(serverUrl: string): ClientOptions;
9
+ /** Builds a non-redirecting local client with an explicit per-request bearer source. */
10
+ export declare function resolveLocalDevelopmentClientOptions(input: {
11
+ readonly serverUrl: string;
12
+ readonly token: () => Promise<string>;
13
+ }): ClientOptions;
9
14
  /** Builds non-redirecting client options backed by one verified credential gate. */
10
15
  export declare function resolveRemoteDevelopmentClientOptions(input: {
11
16
  readonly credentials: DevelopmentCredentialGate;
@@ -1 +1 @@
1
- function resolveDevelopmentClientOptions(e){return{host:e}}function resolveRemoteDevelopmentClientOptions(e){let t=new URL(e.serverUrl).origin;if(e.credentials.serverOrigin!==t)throw Error(`Credential gate origin ${e.credentials.serverOrigin} does not match client origin ${t}.`);return{auth:{vercelOidc:{token:()=>e.credentials.resolveToken()}},headers:e.credentials.resolveBypassHeaders,host:e.serverUrl,redirect:`manual`}}export{resolveDevelopmentClientOptions,resolveRemoteDevelopmentClientOptions};
1
+ function resolveDevelopmentClientOptions(e){return{host:e}}function resolveLocalDevelopmentClientOptions(e){return{auth:{bearer:e.token},host:e.serverUrl,redirect:`manual`}}function resolveRemoteDevelopmentClientOptions(e){let t=new URL(e.serverUrl).origin;if(e.credentials.serverOrigin!==t)throw Error(`Credential gate origin ${e.credentials.serverOrigin} does not match client origin ${t}.`);return{auth:{vercelOidc:{token:()=>e.credentials.resolveToken()}},headers:e.credentials.resolveBypassHeaders,host:e.serverUrl,redirect:`manual`}}export{resolveDevelopmentClientOptions,resolveLocalDevelopmentClientOptions,resolveRemoteDevelopmentClientOptions};