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.
- package/CHANGELOG.md +17 -0
- package/dist/src/chunks/{use-eve-agent-8X2UMr8q.js → use-eve-agent-BEOUv37s.js} +70 -0
- package/dist/src/chunks/{use-eve-agent-9ZNiSFMb.js → use-eve-agent-C25KOe9i.js} +70 -0
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/agent-header.js +1 -1
- package/dist/src/cli/dev/tui/blocks.js +8 -8
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.d.ts +1 -1
- package/dist/src/cli/dev/tui/prompt-commands.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +10 -3
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +9 -1
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-flow.d.ts +8 -1
- package/dist/src/cli/dev/tui/setup-issues.d.ts +2 -14
- package/dist/src/cli/dev/tui/setup-issues.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.d.ts +14 -8
- package/dist/src/cli/dev/tui/setup-panel.js +3 -3
- package/dist/src/cli/dev/tui/terminal-renderer.js +6 -6
- package/dist/src/cli/dev/tui/tui-prompter.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +2 -3
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/ui-options.d.ts +21 -0
- package/dist/src/cli/dev/ui-options.js +1 -0
- package/dist/src/cli/run.d.ts +6 -42
- package/dist/src/cli/run.js +2 -2
- package/dist/src/client/authorization-message-parts.d.ts +4 -0
- package/dist/src/client/authorization-message-parts.js +1 -0
- package/dist/src/client/index.d.ts +2 -2
- package/dist/src/client/message-reducer-types.d.ts +40 -1
- package/dist/src/client/message-reducer.d.ts +3 -5
- package/dist/src/client/message-reducer.js +1 -1
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.d.ts +71 -1
- package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
- package/dist/src/harness/emission.d.ts +3 -3
- package/dist/src/harness/emission.js +1 -1
- package/dist/src/harness/stream-actions.d.ts +17 -0
- package/dist/src/harness/stream-actions.js +1 -0
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/configure-nitro-routes.js +2 -2
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.d.ts +1 -0
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.d.ts +8 -0
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/internal/nitro/host.d.ts +1 -1
- package/dist/src/internal/nitro/host.js +1 -1
- package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.d.ts +0 -3
- package/dist/src/internal/nitro/routes/dev-runtime-artifacts.js +1 -1
- package/dist/src/internal/nitro/routes/info.js +1 -1
- package/dist/src/internal/vercel/project-link.d.ts +10 -0
- package/dist/src/internal/vercel/project-link.js +1 -0
- package/dist/src/protocol/message.d.ts +14 -10
- package/dist/src/public/channels/auth.d.ts +26 -13
- package/dist/src/public/channels/auth.js +1 -1
- package/dist/src/react/index.d.ts +1 -1
- package/dist/src/runtime/agent/mock-model-adapter.d.ts +3 -2
- package/dist/src/runtime/agent/mock-model-adapter.js +1 -1
- package/dist/src/runtime/connections/principal.d.ts +2 -0
- package/dist/src/runtime/connections/principal.js +1 -1
- package/dist/src/runtime/connections/types.d.ts +4 -1
- package/dist/src/runtime/framework-channels/index.d.ts +1 -6
- package/dist/src/runtime/framework-channels/index.js +1 -1
- package/dist/src/runtime/governance/auth/oidc.js +1 -1
- package/dist/src/runtime/governance/auth/types.d.ts +14 -10
- package/dist/src/runtime/governance/auth/vercel-oidc-project.d.ts +12 -0
- package/dist/src/runtime/governance/auth/vercel-oidc-project.js +1 -0
- package/dist/src/services/dev-client/client-options.d.ts +5 -0
- package/dist/src/services/dev-client/client-options.js +1 -1
- package/dist/src/services/dev-client/request-headers.d.ts +8 -0
- package/dist/src/services/dev-client/request-headers.js +1 -1
- package/dist/src/services/dev-client/runtime-artifacts.d.ts +1 -0
- package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
- package/dist/src/services/dev-client.d.ts +8 -0
- package/dist/src/services/dev-client.js +1 -1
- package/dist/src/setup/boxes/add-connections.d.ts +10 -8
- package/dist/src/setup/boxes/add-connections.js +1 -1
- package/dist/src/setup/boxes/resolve-provisioning.d.ts +1 -0
- package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
- package/dist/src/setup/cli/channel-setup-prompter.d.ts +9 -2
- package/dist/src/setup/cli/channel-setup-prompter.js +1 -1
- package/dist/src/setup/cli/index.d.ts +1 -1
- package/dist/src/setup/cli/prompt-ui.d.ts +2 -0
- package/dist/src/setup/cli/select-state.js +1 -1
- package/dist/src/setup/connection-connector.d.ts +26 -52
- package/dist/src/setup/connection-connector.js +2 -1
- package/dist/src/setup/flows/channels.js +1 -1
- package/dist/src/setup/flows/connections.d.ts +36 -0
- package/dist/src/setup/flows/connections.js +3 -0
- package/dist/src/setup/flows/link.d.ts +1 -0
- package/dist/src/setup/flows/link.js +1 -1
- package/dist/src/setup/project-resolution.d.ts +2 -8
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/prompter.d.ts +2 -0
- package/dist/src/setup/scaffold/connections/catalog.d.ts +10 -5
- package/dist/src/setup/scaffold/connections/catalog.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +11 -11
- package/dist/src/setup/scaffold/create/web-template.d.ts +2 -2
- package/dist/src/setup/scaffold/create/web-template.js +107 -3
- package/dist/src/setup/scaffold/index.d.ts +1 -1
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/connections.d.ts +6 -0
- package/dist/src/setup/scaffold/update/connections.js +3 -3
- package/dist/src/svelte/index.d.ts +1 -1
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.d.ts +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/channels/eve.mdx +3 -3
- package/docs/concepts/sessions-runs-and-streaming.md +1 -1
- package/docs/guides/auth-and-route-protection.md +5 -5
- package/docs/guides/dev-tui.md +11 -4
- package/docs/guides/frontend/nextjs.mdx +2 -2
- package/docs/guides/frontend/nuxt.mdx +2 -2
- package/docs/guides/frontend/overview.mdx +34 -4
- package/docs/guides/frontend/sveltekit.mdx +2 -2
- package/docs/reference/cli.md +3 -1
- package/docs/tutorial/ship-it.mdx +1 -1
- package/docs/tutorial/team-playbooks.mdx +1 -1
- package/package.json +2 -2
- package/dist/src/internal/nitro/host/dev-rebuild-registry.d.ts +0 -5
- 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";
|
|
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
|
|
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};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readDevelopmentRuntimeArtifactsRevision}from"#internal/nitro/dev-runtime-artifacts.js";
|
|
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,[
|
|
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
|
|
402
|
-
*
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
542
|
-
* that needs user authorization before
|
|
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
|
|
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
|
-
*
|
|
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:
|
|
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: [
|
|
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 `[
|
|
282
|
-
* the canonical "
|
|
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
|
-
* -
|
|
318
|
-
*
|
|
319
|
-
*
|
|
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
|
|
323
|
-
*
|
|
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
|
-
*
|
|
331
|
-
*
|
|
332
|
-
*
|
|
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
|
|
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:
|
|
7
|
-
*
|
|
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
|
|
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
|
|
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.
|
|
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:[
|
|
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=
|
|
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
|
-
*
|
|
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
|
|
66
|
-
*
|
|
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
|
-
*
|
|
72
|
-
*
|
|
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
|
|
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};
|