eve 0.12.1 → 0.12.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/src/cli/commands/agent-instructions.d.ts +15 -3
  3. package/dist/src/cli/commands/agent-instructions.js +3 -1
  4. package/dist/src/cli/commands/agent-prompt/build-and-verify.md +33 -0
  5. package/dist/src/cli/commands/agent-prompt/collect-intent.md +18 -0
  6. package/dist/src/cli/commands/agent-prompt/intro-handoff.md +4 -0
  7. package/dist/src/cli/commands/agent-prompt/intro-setup.md +5 -0
  8. package/dist/src/cli/commands/agent-prompt/scaffold.md +19 -0
  9. package/dist/src/cli/commands/agent-prompt/vercel-connect.md +3 -0
  10. package/dist/src/cli/commands/init-repl.d.ts +79 -0
  11. package/dist/src/cli/commands/init-repl.js +1 -0
  12. package/dist/src/cli/commands/init.d.ts +6 -0
  13. package/dist/src/cli/commands/init.js +1 -1
  14. package/dist/src/cli/dev/tui/line-editor.d.ts +2 -0
  15. package/dist/src/cli/dev/tui/line-editor.js +2 -2
  16. package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
  17. package/dist/src/cli/dev/tui/setup-commands.d.ts +26 -7
  18. package/dist/src/cli/dev/tui/setup-commands.js +2 -2
  19. package/dist/src/cli/dev/tui/setup-flow.d.ts +5 -3
  20. package/dist/src/cli/dev/tui/setup-panel.d.ts +12 -7
  21. package/dist/src/cli/dev/tui/setup-panel.js +3 -3
  22. package/dist/src/cli/dev/tui/terminal-renderer.js +10 -10
  23. package/dist/src/cli/dev/tui/terminal-text.d.ts +11 -0
  24. package/dist/src/cli/dev/tui/terminal-text.js +1 -1
  25. package/dist/src/cli/run.d.ts +1 -0
  26. package/dist/src/cli/run.js +2 -2
  27. package/dist/src/cli/ui/live-row.js +1 -1
  28. package/dist/src/cli/ui/progress-pulse.d.ts +10 -0
  29. package/dist/src/cli/ui/progress-pulse.js +1 -0
  30. package/dist/src/compiled/.vendor-stamp.json +1 -1
  31. package/dist/src/compiled/@vercel/sandbox/_async-retry.d.ts +8 -0
  32. package/dist/src/compiled/@vercel/sandbox/_workflow-serde.d.ts +5 -0
  33. package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +1442 -0
  34. package/dist/src/compiled/@vercel/sandbox/api-client/api-error.d.ts +29 -0
  35. package/dist/src/compiled/@vercel/sandbox/api-client/base-client.d.ts +39 -0
  36. package/dist/src/compiled/@vercel/sandbox/api-client/file-writer.d.ts +66 -0
  37. package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +2 -0
  38. package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +878 -0
  39. package/dist/src/compiled/@vercel/sandbox/api-client/with-retry.d.ts +10 -0
  40. package/dist/src/compiled/@vercel/sandbox/auth/error.d.ts +15 -0
  41. package/dist/src/compiled/@vercel/sandbox/auth/file.d.ts +18 -0
  42. package/dist/src/compiled/@vercel/sandbox/auth/index.d.ts +6 -0
  43. package/dist/src/compiled/@vercel/sandbox/auth/oauth.d.ts +111 -0
  44. package/dist/src/compiled/@vercel/sandbox/auth/poll-for-token.d.ts +28 -0
  45. package/dist/src/compiled/@vercel/sandbox/auth/project.d.ts +40 -0
  46. package/dist/src/compiled/@vercel/sandbox/command.d.ts +290 -0
  47. package/dist/src/compiled/@vercel/sandbox/constants.d.ts +5 -0
  48. package/dist/src/compiled/@vercel/sandbox/filesystem.d.ts +258 -0
  49. package/dist/src/compiled/@vercel/sandbox/index.d.ts +10 -129
  50. package/dist/src/compiled/@vercel/sandbox/proxy.d.ts +55 -0
  51. package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +1058 -0
  52. package/dist/src/compiled/@vercel/sandbox/session.d.ts +432 -0
  53. package/dist/src/compiled/@vercel/sandbox/snapshot.d.ts +229 -0
  54. package/dist/src/compiled/@vercel/sandbox/utils/get-credentials.d.ts +21 -0
  55. package/dist/src/compiled/@vercel/sandbox/utils/paginator.d.ts +16 -0
  56. package/dist/src/compiled/@vercel/sandbox/utils/resolveSignal.d.ts +15 -0
  57. package/dist/src/compiled/@vercel/sandbox/utils/sandbox-snapshot.d.ts +11 -0
  58. package/dist/src/compiled/@vercel/sandbox/utils/types.d.ts +11 -0
  59. package/dist/src/compiled/chat/_workflow-serde.d.ts +3 -0
  60. package/dist/src/compiled/chat/index.d.ts +1 -1
  61. package/dist/src/discover/discover-agent.js +1 -1
  62. package/dist/src/evals/target.js +1 -1
  63. package/dist/src/execution/node-step.js +1 -1
  64. package/dist/src/execution/sandbox/bindings/just-bash-runtime.js +1 -1
  65. package/dist/src/execution/sandbox/bindings/vercel-base-runtime.d.ts +3 -3
  66. package/dist/src/execution/sandbox/bindings/vercel-create-sdk.d.ts +8 -13
  67. package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +3 -3
  68. package/dist/src/execution/sandbox/bindings/vercel-lookup.d.ts +4 -5
  69. package/dist/src/execution/sandbox/bindings/vercel-read-stream.d.ts +5 -0
  70. package/dist/src/execution/sandbox/bindings/vercel-read-stream.js +1 -0
  71. package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +5 -0
  72. package/dist/src/execution/sandbox/bindings/vercel-sdk-types.js +1 -0
  73. package/dist/src/execution/sandbox/bindings/vercel.d.ts +4 -4
  74. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  75. package/dist/src/execution/sandbox/multiplexed-command.d.ts +22 -0
  76. package/dist/src/execution/sandbox/multiplexed-command.js +1 -0
  77. package/dist/src/execution/tool-auth.d.ts +13 -3
  78. package/dist/src/execution/tool-auth.js +1 -1
  79. package/dist/src/execution/workflow-steps.js +1 -1
  80. package/dist/src/harness/tool-loop.js +1 -1
  81. package/dist/src/internal/application/package.js +1 -1
  82. package/dist/src/internal/authored-module-loader.js +2 -2
  83. package/dist/src/internal/nitro/dev-runtime-artifacts.js +1 -1
  84. package/dist/src/public/channels/slack/connections.d.ts +16 -18
  85. package/dist/src/public/channels/slack/defaults.d.ts +1 -1
  86. package/dist/src/public/channels/slack/defaults.js +1 -1
  87. package/dist/src/public/channels/slack/slackChannel.d.ts +6 -7
  88. package/dist/src/public/definitions/tool.d.ts +64 -20
  89. package/dist/src/public/sandbox/vercel-sandbox.d.ts +12 -9
  90. package/dist/src/public/tools/index.d.ts +1 -1
  91. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  92. package/dist/src/runtime/connections/validate-authorization.js +1 -1
  93. package/dist/src/runtime/framework-tools/connection-search-dynamic.js +1 -1
  94. package/dist/src/setup/ai-gateway-api-key.d.ts +15 -0
  95. package/dist/src/setup/ai-gateway-api-key.js +1 -0
  96. package/dist/src/setup/boxes/apply-ai-gateway-credential.js +1 -1
  97. package/dist/src/setup/boxes/detect-ai-gateway.js +2 -2
  98. package/dist/src/setup/boxes/resolve-provisioning.js +1 -1
  99. package/dist/src/setup/flows/channels.js +1 -1
  100. package/dist/src/setup/flows/deploy.js +1 -1
  101. package/dist/src/setup/flows/install-vercel-cli.js +1 -1
  102. package/dist/src/setup/flows/link.d.ts +2 -1
  103. package/dist/src/setup/flows/link.js +1 -1
  104. package/dist/src/setup/flows/login.js +1 -1
  105. package/dist/src/setup/flows/model.d.ts +3 -2
  106. package/dist/src/setup/flows/model.js +1 -1
  107. package/dist/src/setup/flows/vercel.js +2 -2
  108. package/dist/src/setup/scaffold/create/add-to-project.js +1 -1
  109. package/dist/src/setup/scaffold/create/project.js +1 -1
  110. package/dist/src/setup/vercel-project.d.ts +2 -6
  111. package/dist/src/setup/vercel-project.js +1 -1
  112. package/dist/src/setup/with-spinner.d.ts +3 -0
  113. package/dist/src/setup/with-spinner.js +1 -0
  114. package/dist/src/shared/package-name.d.ts +4 -0
  115. package/dist/src/shared/package-name.js +1 -0
  116. package/dist/src/shared/sandbox-network-policy.d.ts +2 -2
  117. package/docs/channels/slack.mdx +1 -1
  118. package/docs/connections.mdx +9 -6
  119. package/docs/getting-started.mdx +8 -3
  120. package/docs/guides/auth-and-route-protection.md +59 -10
  121. package/docs/guides/dev-tui.md +2 -2
  122. package/docs/reference/cli.md +2 -2
  123. package/docs/reference/typescript-api.md +9 -7
  124. package/package.json +1 -1
  125. package/dist/src/cli/commands/init-agent-handoff.md +0 -12
  126. package/dist/src/cli/commands/init-agent-instructions.md +0 -16
@@ -1,2 +1,2 @@
1
- import{createRequire}from"node:module";import{expectObjectRecord}from"#internal/authored-module.js";import{existsSync,mkdirSync,realpathSync,writeFileSync}from"node:fs";import{dirname,join,resolve,sep}from"node:path";import{createHash}from"node:crypto";import{createAuthoredAssetImportPlugin}from"#internal/authored-asset-import-plugin.js";import{createAuthoredModuleBundleError}from"#internal/authored-module-bundle.js";import{createAuthoredPackageTsConfigPathsPlugin}from"#internal/authored-package-tsconfig-paths.js";import{buildWithNitroRolldown,getSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{SERVER_EXTERNAL_PACKAGES}from"#internal/nitro/host/server-external-packages.js";import{createNodeEsmCompatBannerPlugin}from"#internal/node-esm-compat-banner.js";const AUTHORED_BUNDLED_MODULE_EXTENSION=/\.[cm]?[jt]sx?$/,AUTHORED_MODULE_BUNDLE_DIRECTORY_PATH=join(`node_modules`,`.cache`,`eve`,`authored-modules`),RESOLVE_EXTENSIONS=[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`],CHANNEL_MODULE_CACHE_KEY=`__eveChannelModuleCache__`,CACHED_CHANNEL_PREFIX=`eve-cached-channel:`;function getChannelModuleCache(){return globalThis[CHANNEL_MODULE_CACHE_KEY]}const inFlightModuleLoads=new Map;function loadAuthoredModuleNamespace(e,t={}){let n=createInFlightModuleLoadKey(resolve(e),t),r=inFlightModuleLoads.get(n);if(r!==void 0)return r;let i=(async()=>{try{return await doLoadAuthoredModuleNamespace(e,t)}finally{inFlightModuleLoads.delete(n)}})();return inFlightModuleLoads.set(n,i),i}async function doLoadAuthoredModuleNamespace(e,n){return expectObjectRecord(AUTHORED_BUNDLED_MODULE_EXTENSION.test(e)?await loadBundledAuthoredModule(e,n):await import(createFileImportSpecifier(e)),`Expected "${e}" to export a module namespace object.`)}function createFileImportSpecifier(e){let t=e.replaceAll(`\\`,`/`);return/^[A-Za-z]:\//.test(t)?`file:///${encodeURI(t)}`:t.startsWith(`/`)?`file://${encodeURI(t)}`:t}async function loadBundledAuthoredModule(e,t){let i=getChannelModuleCache(),o=resolveAuthoredPackageRoot(e),c=resolveAuthoredTsConfigPath(o),l=normalizeExternalDependencies(t.externalDependencies),u=i&&i.size>0?{name:`eve-channel-identity`,async resolveId(e,t,n){if(!/channels[/\\]/.test(e)||n.kind!==`import-statement`)return;let r=await this.resolve(e,t,{kind:n.kind,skipSelf:!0});if(r===null||typeof r.id!=`string`)return;let a=resolve(r.id);if(i.has(a))return{id:`${CACHED_CHANNEL_PREFIX}${a}`}},load(e){if(!e.startsWith(CACHED_CHANNEL_PREFIX))return;let t=e.slice(19);return{code:[`const cache = globalThis["${CHANNEL_MODULE_CACHE_KEY}"];`,`export default cache.get(${JSON.stringify(t)});`].join(`
2
- `),moduleType:`js`}}}:null,d=[createAuthoredAssetImportPlugin(),createAuthoredPackageTsConfigPathsPlugin({appPackageRoot:o,extensions:RESOLVE_EXTENSIONS}),createNodeEsmCompatBannerPlugin({includeRequire:!0}),createPackageBoundaryPlugin(o,l),u].filter(e=>e!==null),f;try{f=getSingleRolldownChunk(await buildWithNitroRolldown({cwd:o,input:e,platform:`node`,plugins:d,resolve:{extensions:[...RESOLVE_EXTENSIONS]},tsconfig:c,write:!1,output:{comments:!1,format:`esm`,sourcemap:`inline`}}),`authored module for "${e}"`)}catch(t){throw createAuthoredModuleBundleError(e,t)}let p=createHash(`sha1`).update(e).update(`\0`).update(l.join(`\0`)).update(`\0`).update(f.code).digest(`hex`),m=join(o,AUTHORED_MODULE_BUNDLE_DIRECTORY_PATH),h=join(m,`${p}.mjs`);return existsSync(h)||(mkdirSync(m,{recursive:!0}),writeFileSync(h,f.code)),await import(`${createFileImportSpecifier(h)}?v=${p}`)}function createPackageBoundaryPlugin(e,t){let n=toCanonicalPath(e);return{name:`eve-package-boundary`,async resolveId(r,i,a){if(!isPackageImport(r))return;if(isEveFrameworkImport(r))return{external:!0,id:r};let o=resolveConfiguredExternalDependency(r,t);if(o!==void 0){if(r!==o){let t=await this.resolve(r,i,{kind:a.kind,skipSelf:!0});if(t!==null&&typeof t.id==`string`)return{external:!0,id:resolveExternalFilePath({importer:i,packageRoot:e,resolvedId:t.id,source:r})};let n=resolveExternalFilePath({importer:i,packageRoot:e,source:r});if(n!==void 0)return{external:!0,id:n}}return{external:!0,id:r}}let s=i===void 0||i.startsWith(`\0`)||i.startsWith(CACHED_CHANNEL_PREFIX)?void 0:resolve(i);if(s!==void 0&&isPathInsideOrEqual(toCanonicalPath(s),n)){let e=await this.resolve(r,i,{kind:a.kind,skipSelf:!0});if(e===null||typeof e.id!=`string`)throw Error(`Cannot resolve package "${r}" imported from "${s}". Install it with your package manager (e.g. \`pnpm install\`); a running \`eve dev\` retries on the next rebuild.`);if(isNodeModulesPath(e.id))return{external:!0,id:r}}}}}function createInFlightModuleLoadKey(e,t){return`${e}\0${normalizeExternalDependencies(t.externalDependencies).join(`\0`)}`}function normalizeExternalDependencies(e=[]){return[...new Set([...SERVER_EXTERNAL_PACKAGES,...e])].sort()}function resolveConfiguredExternalDependency(e,t){return t.find(t=>e===t||e.startsWith(`${t}/`))}function resolveExternalFilePath(t){if(t.resolvedId!==void 0){let e=resolveExistingExternalFilePath(t.resolvedId);if(e!==void 0)return e}let n=normalizeImporterPath(t.importer);if(n!==void 0)try{return createRequire(n).resolve(t.source)}catch{}try{return createRequire(join(t.packageRoot,`package.json`)).resolve(t.source)}catch{return t.resolvedId}}function resolveExistingExternalFilePath(e){if(existsSync(e))return e;for(let t of RESOLVE_EXTENSIONS){let r=`${e}${t}`;if(existsSync(r))return r}}function normalizeImporterPath(e){if(!(e===void 0||e.startsWith(`\0`)||e.startsWith(CACHED_CHANNEL_PREFIX)))return resolve(e)}function isPackageImport(e){return e.startsWith(`.`)||e.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(e)||/^(?:node|data|file):/.test(e)||e.startsWith(`@/`)?!1:!e.startsWith(CACHED_CHANNEL_PREFIX)}function isEveFrameworkImport(e){return e===`eve`||e.startsWith(`eve/`)}function isNodeModulesPath(e){return e.replaceAll(`\\`,`/`).includes(`/node_modules/`)}function toCanonicalPath(e){try{return realpathSync(e)}catch{return resolve(e)}}function isPathInsideOrEqual(e,t){let n=resolve(e),r=resolve(t);return n===r||n.startsWith(`${r}${sep}`)}function resolveAuthoredTsConfigPath(e){for(let t of[`tsconfig.json`,`jsconfig.json`]){let r=join(e,t);if(existsSync(r))return r}return!1}function resolveAuthoredPackageRoot(e){let t=dirname(e);for(;;){if(existsSync(join(t,`package.json`)))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve the authored package root for "${e}".`);t=r}}export{loadAuthoredModuleNamespace};
1
+ import{createRequire}from"node:module";import{expectObjectRecord}from"#internal/authored-module.js";import{existsSync,mkdirSync,realpathSync,statSync,writeFileSync}from"node:fs";import{dirname,isAbsolute,join,resolve,sep}from"node:path";import{createHash}from"node:crypto";import{createAuthoredAssetImportPlugin}from"#internal/authored-asset-import-plugin.js";import{createAuthoredModuleBundleError}from"#internal/authored-module-bundle.js";import{createAuthoredPackageTsConfigPathsPlugin}from"#internal/authored-package-tsconfig-paths.js";import{buildWithNitroRolldown,getSingleRolldownChunk}from"#internal/bundler/nitro-rolldown.js";import{SERVER_EXTERNAL_PACKAGES}from"#internal/nitro/host/server-external-packages.js";import{createNodeEsmCompatBannerPlugin}from"#internal/node-esm-compat-banner.js";const AUTHORED_BUNDLED_MODULE_EXTENSION=/\.[cm]?[jt]sx?$/,AUTHORED_MODULE_BUNDLE_DIRECTORY_PATH=join(`node_modules`,`.cache`,`eve`,`authored-modules`),RESOLVE_EXTENSIONS=[`.ts`,`.tsx`,`.mts`,`.cts`,`.js`,`.jsx`,`.mjs`,`.cjs`,`.json`],CHANNEL_MODULE_CACHE_KEY=`__eveChannelModuleCache__`,CACHED_CHANNEL_PREFIX=`eve-cached-channel:`;function getChannelModuleCache(){return globalThis[CHANNEL_MODULE_CACHE_KEY]}const inFlightModuleLoads=new Map;function loadAuthoredModuleNamespace(e,t={}){let n=createInFlightModuleLoadKey(resolve(e),t),r=inFlightModuleLoads.get(n);if(r!==void 0)return r;let i=(async()=>{try{return await doLoadAuthoredModuleNamespace(e,t)}finally{inFlightModuleLoads.delete(n)}})();return inFlightModuleLoads.set(n,i),i}async function doLoadAuthoredModuleNamespace(e,n){return expectObjectRecord(AUTHORED_BUNDLED_MODULE_EXTENSION.test(e)?await loadBundledAuthoredModule(e,n):await import(createFileImportSpecifier(e)),`Expected "${e}" to export a module namespace object.`)}function createFileImportSpecifier(e){let t=e.replaceAll(`\\`,`/`);return/^[A-Za-z]:\//.test(t)?`file:///${encodeURI(t)}`:t.startsWith(`/`)?`file://${encodeURI(t)}`:t}async function loadBundledAuthoredModule(e,t){let i=getChannelModuleCache(),a=resolveAuthoredPackageRoot(e),s=resolveAuthoredTsConfigPath(a),c=normalizeExternalDependencies(t.externalDependencies),l=[i&&i.size>0?{name:`eve-channel-identity`,async resolveId(e,t,n){if(!/channels[/\\]/.test(e)||n.kind!==`import-statement`)return;let r=await this.resolve(e,t,{kind:n.kind,skipSelf:!0});if(r===null||typeof r.id!=`string`)return;let a=resolve(r.id);if(i.has(a))return{id:`${CACHED_CHANNEL_PREFIX}${a}`}},load(e){if(!e.startsWith(CACHED_CHANNEL_PREFIX))return;let t=e.slice(19);return{code:[`const cache = globalThis["${CHANNEL_MODULE_CACHE_KEY}"];`,`export default cache.get(${JSON.stringify(t)});`].join(`
2
+ `),moduleType:`js`}}}:null,createAuthoredRelativeExtensionResolverPlugin({extensions:RESOLVE_EXTENSIONS}),createAuthoredAssetImportPlugin(),createAuthoredPackageTsConfigPathsPlugin({appPackageRoot:a,extensions:RESOLVE_EXTENSIONS}),createNodeEsmCompatBannerPlugin({includeRequire:!0}),createPackageBoundaryPlugin(a,c)].filter(e=>e!==null),u;try{u=getSingleRolldownChunk(await buildWithNitroRolldown({cwd:a,input:e,platform:`node`,plugins:l,resolve:{extensions:[...RESOLVE_EXTENSIONS]},tsconfig:s,write:!1,output:{comments:!1,format:`esm`,sourcemap:`inline`}}),`authored module for "${e}"`)}catch(t){throw createAuthoredModuleBundleError(e,t)}let d=createHash(`sha1`).update(e).update(`\0`).update(c.join(`\0`)).update(`\0`).update(u.code).digest(`hex`),f=join(a,AUTHORED_MODULE_BUNDLE_DIRECTORY_PATH),p=join(f,`${d}.mjs`);return existsSync(p)||(mkdirSync(f,{recursive:!0}),writeFileSync(p,u.code)),await import(`${createFileImportSpecifier(p)}?v=${d}`)}function createAuthoredRelativeExtensionResolverPlugin(e){return{name:`eve-authored-relative-extension-resolver`,resolveId(t,n){if(n===void 0||n.startsWith(`\0`)||n.startsWith(CACHED_CHANNEL_PREFIX)||!isPathImport(t))return;let r=resolveExistingImportPath(isAbsolute(t)?t:resolve(dirname(n),t),e.extensions);if(r!==void 0)return{id:r}}}}function createPackageBoundaryPlugin(e,t){let n=toCanonicalPath(e);return{name:`eve-package-boundary`,async resolveId(r,i,a){if(!isPackageImport(r))return;if(isEveFrameworkImport(r))return{external:!0,id:r};let o=resolveConfiguredExternalDependency(r,t);if(o!==void 0){if(r!==o){let t=await this.resolve(r,i,{kind:a.kind,skipSelf:!0});if(t!==null&&typeof t.id==`string`)return{external:!0,id:resolveExternalFilePath({importer:i,packageRoot:e,resolvedId:t.id,source:r})};let n=resolveExternalFilePath({importer:i,packageRoot:e,source:r});if(n!==void 0)return{external:!0,id:n}}return{external:!0,id:r}}let s=i===void 0||i.startsWith(`\0`)||i.startsWith(CACHED_CHANNEL_PREFIX)?void 0:resolve(i);if(s!==void 0&&isPathInsideOrEqual(toCanonicalPath(s),n)){let e=await this.resolve(r,i,{kind:a.kind,skipSelf:!0});if(e===null||typeof e.id!=`string`)throw Error(`Cannot resolve package "${r}" imported from "${s}". Install it with your package manager (e.g. \`pnpm install\`); a running \`eve dev\` retries on the next rebuild.`);if(isNodeModulesPath(e.id))return{external:!0,id:r}}}}}function createInFlightModuleLoadKey(e,t){return`${e}\0${normalizeExternalDependencies(t.externalDependencies).join(`\0`)}`}function normalizeExternalDependencies(e=[]){return[...new Set([...SERVER_EXTERNAL_PACKAGES,...e])].sort()}function resolveConfiguredExternalDependency(e,t){return t.find(t=>e===t||e.startsWith(`${t}/`))}function resolveExternalFilePath(t){if(t.resolvedId!==void 0){let e=resolveExistingExternalFilePath(t.resolvedId);if(e!==void 0)return e}let n=normalizeImporterPath(t.importer);if(n!==void 0)try{return createRequire(n).resolve(t.source)}catch{}try{return createRequire(join(t.packageRoot,`package.json`)).resolve(t.source)}catch{return t.resolvedId}}function resolveExistingExternalFilePath(e){if(existsSync(e))return e;for(let t of RESOLVE_EXTENSIONS){let r=`${e}${t}`;if(existsSync(r))return r}}function resolveExistingImportPath(e,t){if(isFile(e))return e;for(let n of t){let t=`${e}${n}`;if(isFile(t))return t}for(let n of t){let t=join(e,`index${n}`);if(isFile(t))return t}}function isFile(e){try{return statSync(e).isFile()}catch{return!1}}function normalizeImporterPath(e){if(!(e===void 0||e.startsWith(`\0`)||e.startsWith(CACHED_CHANNEL_PREFIX)))return resolve(e)}function isPackageImport(e){return isPathImport(e)||/^(?:node|data|file):/.test(e)||e.startsWith(`@/`)?!1:!e.startsWith(CACHED_CHANNEL_PREFIX)}function isPathImport(e){return e.startsWith(`.`)||e.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(e)}function isEveFrameworkImport(e){return e===`eve`||e.startsWith(`eve/`)}function isNodeModulesPath(e){return e.replaceAll(`\\`,`/`).includes(`/node_modules/`)}function toCanonicalPath(e){try{return realpathSync(e)}catch{return resolve(e)}}function isPathInsideOrEqual(e,t){let n=resolve(e),r=resolve(t);return n===r||n.startsWith(`${r}${sep}`)}function resolveAuthoredTsConfigPath(e){for(let t of[`tsconfig.json`,`jsconfig.json`]){let r=join(e,t);if(existsSync(r))return r}return!1}function resolveAuthoredPackageRoot(e){let t=dirname(e);for(;;){if(existsSync(join(t,`package.json`)))return t;let r=dirname(t);if(r===t)throw Error(`Failed to resolve the authored package root for "${e}".`);t=r}}export{loadAuthoredModuleNamespace};
@@ -1 +1 @@
1
- import{existsSync,readFileSync}from"node:fs";import{dirname,join,relative,resolve,sep}from"node:path";import{cp,mkdir,readFile,readdir,rename,rm,stat,writeFile}from"node:fs/promises";import{randomUUID}from"node:crypto";import{copyDevelopmentSourceSnapshot}from"#internal/nitro/dev-runtime-source-snapshot-copy.js";import{createDevelopmentSourceSnapshotPlan}from"#internal/nitro/dev-runtime-source-snapshot.js";const DEV_RUNTIME_ARTIFACTS_DIRECTORY=`dev-runtime`;function resolveDevelopmentRuntimeArtifactsPointerPath(e){return join(e,`.eve`,DEV_RUNTIME_ARTIFACTS_DIRECTORY,`current.json`)}function resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e){return join(e,`.eve`,DEV_RUNTIME_ARTIFACTS_DIRECTORY,`snapshots`)}async function publishDevelopmentRuntimeArtifactsSnapshot(e){let t=await stageDevelopmentRuntimeArtifactsSnapshot(e);return await activateDevelopmentRuntimeArtifactsSnapshot({appRoot:e.project.appRoot,snapshot:t}),t}async function stageDevelopmentRuntimeArtifactsSnapshot(e){let t=join(resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e.project.appRoot),`${Date.now().toString(36)}-${randomUUID()}`),n=await createDevelopmentSourceSnapshotPlan({appRoot:e.project.appRoot,snapshotRoot:t});try{await copyDevelopmentSourceSnapshot(n),await cp(e.paths.compileDirectoryPath,join(n.runtimeAppRoot,`.eve`,`compile`),{recursive:!0}),await rewriteSnapshotCompiledManifest({appRoot:e.project.appRoot,manifestPath:join(n.runtimeAppRoot,`.eve`,`compile`,`compiled-agent-manifest.json`),runtimeAppRoot:n.runtimeAppRoot}),await validateSnapshotCompiledManifestRoots({manifestPath:join(n.runtimeAppRoot,`.eve`,`compile`,`compiled-agent-manifest.json`),runtimeAppRoot:n.runtimeAppRoot})}catch(e){throw await rm(t,{force:!0,recursive:!0}).catch(()=>{}),e}return{runtimeAppRoot:n.runtimeAppRoot,snapshotRoot:t,snapshotSourceRoot:n.snapshotSourceRoot}}async function activateDevelopmentRuntimeArtifactsSnapshot(e){await writeDevelopmentRuntimeArtifactsPointer(e)}function readDevelopmentRuntimeArtifactsSnapshotRoot(e){let t=readDevelopmentRuntimeArtifactsPointer(e);if(t!==void 0)return t.version===1?t.appRoot:t.runtimeAppRoot}function readDevelopmentRuntimeArtifactsRevision(e){return{revision:readDevelopmentRuntimeArtifactsSnapshotRoot(resolveDevelopmentRuntimeArtifactsPointerPath(e))??e}}function pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(e){pruneDevelopmentRuntimeArtifactsSnapshots({appRoot:e}).catch(e=>{console.warn(`[eve:dev] failed to prune stale runtime snapshots: ${formatErrorMessage(e)}`)})}async function pruneDevelopmentRuntimeArtifactsSnapshots(e){let t=resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e.appRoot),n=collectProtectedSnapshotPaths(readDevelopmentRuntimeArtifactsPointer(resolveDevelopmentRuntimeArtifactsPointerPath(e.appRoot))),i=e.now??Date.now(),a=e.recentWindowMs??9e5,o=e.retainCount??5,s;try{s=await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let c=(await Promise.all(s.filter(e=>e.isDirectory()).map(async e=>{let n=join(t,e.name);return{path:n,mtimeMs:(await stat(n)).mtimeMs}}))).sort((e,t)=>t.mtimeMs-e.mtimeMs);await Promise.all(c.map(async(e,t)=>{t<o||i-e.mtimeMs<=a||n.some(t=>pathsOverlap(e.path,t))||await rm(e.path,{force:!0,recursive:!0})}))}function readDevelopmentRuntimeArtifactsPointer(n){if(!(n===void 0||!existsSync(n)))try{let e=JSON.parse(readFileSync(n,`utf8`));return e.kind!==`eve-dev-runtime-artifacts-pointer`||typeof e.version!=`number`?void 0:e.version===1&&typeof e.appRoot==`string`&&e.appRoot.length>0?{appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,version:1}:e.version===2&&typeof e.appRoot==`string`&&typeof e.runtimeAppRoot==`string`&&e.runtimeAppRoot.length>0&&typeof e.snapshotRoot==`string`&&e.snapshotRoot.length>0?{appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,runtimeAppRoot:e.runtimeAppRoot,snapshotRoot:e.snapshotRoot,version:2}:void 0}catch{return}}function collectProtectedSnapshotPaths(e){return e===void 0?[]:e.version===1?[e.appRoot]:[e.runtimeAppRoot,e.snapshotRoot]}function pathsOverlap(e,t){return isPathInsideOrEqual(e,t)||isPathInsideOrEqual(t,e)}function formatErrorMessage(e){return e instanceof Error?e.message:String(e)}async function rewriteSnapshotCompiledManifest(e){let t=JSON.parse(await readFile(e.manifestPath,`utf8`)),n=rewriteManifestRoots({appRoot:e.appRoot,runtimeAppRoot:e.runtimeAppRoot,value:t});await writeFile(e.manifestPath,`${JSON.stringify(n,null,2)}\n`)}function rewriteManifestRoots(e){if(Array.isArray(e.value))return e.value.map(t=>rewriteManifestRoots({...e,value:t}));if(e.value===null||typeof e.value!=`object`)return e.value;let t={};for(let[n,r]of Object.entries(e.value)){if(typeof r==`string`&&(n===`appRoot`||n===`agentRoot`)){t[n]=rewritePathWithinAppRoot({appRoot:e.appRoot,path:r,runtimeAppRoot:e.runtimeAppRoot});continue}t[n]=rewriteManifestRoots({appRoot:e.appRoot,runtimeAppRoot:e.runtimeAppRoot,value:r})}return t}function rewritePathWithinAppRoot(e){if(!isPathInsideOrEqual(e.path,e.appRoot))return e.path;let t=relative(e.appRoot,e.path);return t.length===0?e.runtimeAppRoot:join(e.runtimeAppRoot,t)}async function writeDevelopmentRuntimeArtifactsPointer(e){let t=resolveDevelopmentRuntimeArtifactsPointerPath(e.appRoot),r=`${t}.${randomUUID()}.tmp`,i={appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,runtimeAppRoot:e.snapshot.runtimeAppRoot,snapshotRoot:e.snapshot.snapshotRoot,version:2};await mkdir(dirname(t),{recursive:!0}),await writeFile(r,`${JSON.stringify(i,null,2)}\n`);try{await rename(r,t)}catch(e){throw await rm(r,{force:!0}).catch(()=>{}),e}}async function validateSnapshotCompiledManifestRoots(e){let t=collectManifestRootPaths(JSON.parse(await readFile(e.manifestPath,`utf8`)));for(let n of t)if(!isPathInsideOrEqual(n,e.runtimeAppRoot))throw Error(`Development runtime snapshot manifest root "${n}" is outside runtime app root "${e.runtimeAppRoot}".`)}function collectManifestRootPaths(e){if(Array.isArray(e))return e.flatMap(e=>collectManifestRootPaths(e));if(typeof e!=`object`||!e)return[];let t=[];for(let[n,r]of Object.entries(e)){if((n===`appRoot`||n===`agentRoot`)&&typeof r==`string`){t.push(r);continue}t.push(...collectManifestRootPaths(r))}return t}function isPathInsideOrEqual(e,t){let n=resolve(e),r=resolve(t);return n===r||n.startsWith(`${r}${sep}`)}export{activateDevelopmentRuntimeArtifactsSnapshot,pruneDevelopmentRuntimeArtifactsSnapshots,pruneDevelopmentRuntimeArtifactsSnapshotsInBackground,publishDevelopmentRuntimeArtifactsSnapshot,readDevelopmentRuntimeArtifactsRevision,readDevelopmentRuntimeArtifactsSnapshotRoot,resolveDevelopmentRuntimeArtifactsPointerPath,stageDevelopmentRuntimeArtifactsSnapshot};
1
+ import{existsSync,readFileSync}from"node:fs";import{dirname,join,relative,resolve,sep}from"node:path";import{cp,mkdir,readFile,readdir,rename,rm,stat,writeFile}from"node:fs/promises";import{randomUUID}from"node:crypto";import{copyDevelopmentSourceSnapshot}from"#internal/nitro/dev-runtime-source-snapshot-copy.js";import{createDevelopmentSourceSnapshotPlan}from"#internal/nitro/dev-runtime-source-snapshot.js";const DEV_RUNTIME_ARTIFACTS_DIRECTORY=`dev-runtime`,TERMINAL_WORKFLOW_RUN_STATUSES=new Set([`completed`,`failed`,`cancelled`,`canceled`]);function resolveDevelopmentRuntimeArtifactsPointerPath(e){return join(e,`.eve`,DEV_RUNTIME_ARTIFACTS_DIRECTORY,`current.json`)}function resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e){return join(e,`.eve`,DEV_RUNTIME_ARTIFACTS_DIRECTORY,`snapshots`)}async function publishDevelopmentRuntimeArtifactsSnapshot(e){let t=await stageDevelopmentRuntimeArtifactsSnapshot(e);return await activateDevelopmentRuntimeArtifactsSnapshot({appRoot:e.project.appRoot,snapshot:t}),t}async function stageDevelopmentRuntimeArtifactsSnapshot(e){let t=join(resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e.project.appRoot),`${Date.now().toString(36)}-${randomUUID()}`),n=await createDevelopmentSourceSnapshotPlan({appRoot:e.project.appRoot,snapshotRoot:t});try{await copyDevelopmentSourceSnapshot(n),await cp(e.paths.compileDirectoryPath,join(n.runtimeAppRoot,`.eve`,`compile`),{recursive:!0}),await rewriteSnapshotCompiledManifest({appRoot:e.project.appRoot,manifestPath:join(n.runtimeAppRoot,`.eve`,`compile`,`compiled-agent-manifest.json`),runtimeAppRoot:n.runtimeAppRoot}),await validateSnapshotCompiledManifestRoots({manifestPath:join(n.runtimeAppRoot,`.eve`,`compile`,`compiled-agent-manifest.json`),runtimeAppRoot:n.runtimeAppRoot})}catch(e){throw await rm(t,{force:!0,recursive:!0}).catch(()=>{}),e}return{runtimeAppRoot:n.runtimeAppRoot,snapshotRoot:t,snapshotSourceRoot:n.snapshotSourceRoot}}async function activateDevelopmentRuntimeArtifactsSnapshot(e){await writeDevelopmentRuntimeArtifactsPointer(e)}function readDevelopmentRuntimeArtifactsSnapshotRoot(e){let t=readDevelopmentRuntimeArtifactsPointer(e);if(t!==void 0)return t.version===1?t.appRoot:t.runtimeAppRoot}function readDevelopmentRuntimeArtifactsRevision(e){return{revision:readDevelopmentRuntimeArtifactsSnapshotRoot(resolveDevelopmentRuntimeArtifactsPointerPath(e))??e}}function pruneDevelopmentRuntimeArtifactsSnapshotsInBackground(e){pruneDevelopmentRuntimeArtifactsSnapshots({appRoot:e}).catch(e=>{console.warn(`[eve:dev] failed to prune stale runtime snapshots: ${formatErrorMessage(e)}`)})}async function pruneDevelopmentRuntimeArtifactsSnapshots(e){let t=resolveDevelopmentRuntimeArtifactsSnapshotsDirectory(e.appRoot),n=[...collectProtectedSnapshotPaths(readDevelopmentRuntimeArtifactsPointer(resolveDevelopmentRuntimeArtifactsPointerPath(e.appRoot))),...await collectWorkflowDataSnapshotPaths({appRoot:e.appRoot,snapshotsDirectory:t})],i=e.now??Date.now(),a=e.recentWindowMs??9e5,o=e.retainCount??5,s;try{s=await readdir(t,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}let c=(await Promise.all(s.filter(e=>e.isDirectory()).map(async e=>{let n=join(t,e.name);return{path:n,mtimeMs:(await stat(n)).mtimeMs}}))).sort((e,t)=>t.mtimeMs-e.mtimeMs);await Promise.all(c.map(async(e,t)=>{t<o||i-e.mtimeMs<=a||n.some(t=>pathsOverlap(e.path,t))||await rm(e.path,{force:!0,recursive:!0})}))}function readDevelopmentRuntimeArtifactsPointer(n){if(!(n===void 0||!existsSync(n)))try{let e=JSON.parse(readFileSync(n,`utf8`));return e.kind!==`eve-dev-runtime-artifacts-pointer`||typeof e.version!=`number`?void 0:e.version===1&&typeof e.appRoot==`string`&&e.appRoot.length>0?{appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,version:1}:e.version===2&&typeof e.appRoot==`string`&&typeof e.runtimeAppRoot==`string`&&e.runtimeAppRoot.length>0&&typeof e.snapshotRoot==`string`&&e.snapshotRoot.length>0?{appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,runtimeAppRoot:e.runtimeAppRoot,snapshotRoot:e.snapshotRoot,version:2}:void 0}catch{return}}function collectProtectedSnapshotPaths(e){return e===void 0?[]:e.version===1?[e.appRoot]:[e.runtimeAppRoot,e.snapshotRoot]}async function collectWorkflowDataSnapshotPaths(e){let t=join(e.appRoot,`.workflow-data`),n=new Set;return await collectSnapshotPathsFromDirectory({directory:t,snapshotPaths:n,snapshotsDirectory:e.snapshotsDirectory}),[...n]}async function collectSnapshotPathsFromDirectory(e){let t;try{t=await readdir(e.directory,{withFileTypes:!0})}catch(e){if(e instanceof Error&&`code`in e&&e.code===`ENOENT`)return;throw e}await Promise.all(t.map(async t=>{let n=join(e.directory,t.name);if(t.isDirectory()){await collectSnapshotPathsFromDirectory({directory:n,snapshotPaths:e.snapshotPaths,snapshotsDirectory:e.snapshotsDirectory});return}if(!t.isFile()||(await stat(n)).size>1048576)return;let i=await readFile(n,`utf8`);if(shouldScanWorkflowDataSource(i))for(let t of collectSnapshotPathsFromText(i,e.snapshotsDirectory))e.snapshotPaths.add(t)}))}function collectSnapshotPathsFromText(e,t){let n=new Set,i=t.replaceAll(`\\`,`/`),a=RegExp(`${escapeRegExp(i)}/([^/"'\\s]+)`,`gu`),o=e.replaceAll(`\\\\`,`/`).replaceAll(`\\`,`/`);for(let e of o.matchAll(a)){let i=e[1];i!==void 0&&i.length>0&&n.add(join(t,i))}return[...n]}function shouldScanWorkflowDataSource(e){let t=parseJsonObject(e);if(t===void 0)return!0;let n=t.status;return typeof n!=`string`||!TERMINAL_WORKFLOW_RUN_STATUSES.has(n)}function parseJsonObject(e){try{let t=JSON.parse(e);return isObjectRecord(t)?t:void 0}catch{return}}function isObjectRecord(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function escapeRegExp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,`\\$&`)}function pathsOverlap(e,t){return isPathInsideOrEqual(e,t)||isPathInsideOrEqual(t,e)}function formatErrorMessage(e){return e instanceof Error?e.message:String(e)}async function rewriteSnapshotCompiledManifest(e){let t=JSON.parse(await readFile(e.manifestPath,`utf8`)),n=rewriteManifestRoots({appRoot:e.appRoot,runtimeAppRoot:e.runtimeAppRoot,value:t});await writeFile(e.manifestPath,`${JSON.stringify(n,null,2)}\n`)}function rewriteManifestRoots(e){if(Array.isArray(e.value))return e.value.map(t=>rewriteManifestRoots({...e,value:t}));if(e.value===null||typeof e.value!=`object`)return e.value;let t={};for(let[n,r]of Object.entries(e.value)){if(typeof r==`string`&&(n===`appRoot`||n===`agentRoot`)){t[n]=rewritePathWithinAppRoot({appRoot:e.appRoot,path:r,runtimeAppRoot:e.runtimeAppRoot});continue}t[n]=rewriteManifestRoots({appRoot:e.appRoot,runtimeAppRoot:e.runtimeAppRoot,value:r})}return t}function rewritePathWithinAppRoot(e){if(!isPathInsideOrEqual(e.path,e.appRoot))return e.path;let t=relative(e.appRoot,e.path);return t.length===0?e.runtimeAppRoot:join(e.runtimeAppRoot,t)}async function writeDevelopmentRuntimeArtifactsPointer(e){let t=resolveDevelopmentRuntimeArtifactsPointerPath(e.appRoot),r=`${t}.${randomUUID()}.tmp`,i={appRoot:e.appRoot,kind:`eve-dev-runtime-artifacts-pointer`,runtimeAppRoot:e.snapshot.runtimeAppRoot,snapshotRoot:e.snapshot.snapshotRoot,version:2};await mkdir(dirname(t),{recursive:!0}),await writeFile(r,`${JSON.stringify(i,null,2)}\n`);try{await rename(r,t)}catch(e){throw await rm(r,{force:!0}).catch(()=>{}),e}}async function validateSnapshotCompiledManifestRoots(e){let t=collectManifestRootPaths(JSON.parse(await readFile(e.manifestPath,`utf8`)));for(let n of t)if(!isPathInsideOrEqual(n,e.runtimeAppRoot))throw Error(`Development runtime snapshot manifest root "${n}" is outside runtime app root "${e.runtimeAppRoot}".`)}function collectManifestRootPaths(e){if(Array.isArray(e))return e.flatMap(e=>collectManifestRootPaths(e));if(typeof e!=`object`||!e)return[];let t=[];for(let[n,r]of Object.entries(e)){if((n===`appRoot`||n===`agentRoot`)&&typeof r==`string`){t.push(r);continue}t.push(...collectManifestRootPaths(r))}return t}function isPathInsideOrEqual(e,t){let n=resolve(e),r=resolve(t);return n===r||n.startsWith(`${r}${sep}`)}export{activateDevelopmentRuntimeArtifactsSnapshot,pruneDevelopmentRuntimeArtifactsSnapshots,pruneDevelopmentRuntimeArtifactsSnapshotsInBackground,publishDevelopmentRuntimeArtifactsSnapshot,readDevelopmentRuntimeArtifactsRevision,readDevelopmentRuntimeArtifactsSnapshotRoot,resolveDevelopmentRuntimeArtifactsPointerPath,stageDevelopmentRuntimeArtifactsSnapshot};
@@ -5,16 +5,16 @@
5
5
  * an OAuth-style authorization flow (e.g. signing in to Linear). The
6
6
  * challenge is a credential: anyone in a shared thread could complete a
7
7
  * posted sign-in link and bind their own identity to the session. The
8
- * default handler therefore delivers the challenge as an ephemeral
9
- * "Sign in with X" message visible only to the triggering user.
8
+ * default handler therefore posts a link-free public status while
9
+ * delivering the actual challenge as an ephemeral "Sign in with X"
10
+ * message visible only to the triggering user.
10
11
  *
11
- * Only when no user can be targeted (no triggering user id, no challenge
12
- * URL, or the ephemeral delivery fails) does the handler fall back to a
13
- * public status post, link-free by construction. The matching
14
- * `authorization.completed` handler edits that fallback post in place to
12
+ * When no user can be targeted (no triggering user id, no challenge
13
+ * URL, or the ephemeral delivery fails), the public status still leaves
14
+ * the shared thread with safe progress feedback. The matching
15
+ * `authorization.completed` handler edits that status post in place to
15
16
  * surface the outcome (`authorized` / `declined` / `failed` /
16
- * `timed-out`); on the normal ephemeral path there is nothing to edit
17
- * and the outcome surfaces through the resumed turn itself.
17
+ * `timed-out`).
18
18
  */
19
19
  import type { ConnectionAuthorizationOutcome } from "#protocol/message.js";
20
20
  export type { ConnectionAuthorizationOutcome };
@@ -25,22 +25,20 @@ export type { ConnectionAuthorizationOutcome };
25
25
  */
26
26
  export declare function formatConnectionDisplayName(connectionName: string): string;
27
27
  /**
28
- * Public fallback status text for an authorization challenge that could
29
- * not be delivered ephemerally. Deliberately link-free: it must stay safe
30
- * to post in a shared thread. When the channel cannot identify a
31
- * triggering user (rare schedule-initiated sessions or events that lack
32
- * actor metadata) the text drops the "Connect with" call-to-action since
33
- * there's no one to act on it.
28
+ * Public status text for an authorization challenge. Deliberately
29
+ * link-free: it must stay safe to post in a shared thread. When the
30
+ * channel cannot identify a triggering user (rare schedule-initiated
31
+ * sessions or events that lack actor metadata) the text drops the
32
+ * "Connect with" call-to-action since there's no one to act on it.
34
33
  */
35
34
  export declare function buildAuthRequiredPublicText(input: {
36
35
  readonly displayName: string;
37
36
  readonly hasUser: boolean;
38
37
  }): string;
39
38
  /**
40
- * Final-state markdown for the public fallback status message. Edited in
41
- * place by `authorization.completed` so the thread sees resolution
42
- * without scrolling. Unused on the normal ephemeral path, which posts no
43
- * status message.
39
+ * Final-state markdown for the public status message. Edited in place by
40
+ * `authorization.completed` so the thread sees resolution without
41
+ * scrolling.
44
42
  */
45
43
  export declare function buildAuthCompletedText(input: {
46
44
  readonly displayName: string;
@@ -33,7 +33,7 @@ export declare function defaultInputRequestedHandler(): NonNullable<SlackChannel
33
33
  * and the connection-authorization status flow. Each is overridable
34
34
  * per-event by passing the same key under `slackChannel({ events })`.
35
35
  * Typed as the internal full-context map because the default
36
- * `authorization.required` handler owns the public link-free fallback,
36
+ * `authorization.required` handler owns the public link-free status,
37
37
  * which user overrides cannot express.
38
38
  */
39
39
  export declare const defaultEvents: SlackChannelInternalEvents;
@@ -1,4 +1,4 @@
1
1
  import{createLogger,extractErrorId,formatErrorHint}from"#internal/logging.js";import{truncateMessageText,truncateTypingStatus}from"#public/channels/slack/limits.js";import{buildSlackAuthContext}from"#public/channels/slack/auth.js";import{buildAuthCompletedText,buildAuthEphemeralBlocks,buildAuthRequiredPublicText,formatConnectionDisplayName}from"#public/channels/slack/connections.js";import{renderInputRequestBlocks}from"#public/channels/slack/hitl.js";const log=createLogger(`slack.defaults`);function defaultSlackAuth(e,t){let n=e.author;return n?buildSlackAuthContext({channelId:t.slack.channelId,fullName:n.fullName,isBot:n.isBot,teamId:e.teamId,threadTs:t.slack.threadTs,userId:n.userId,userName:n.userName}):null}async function defaultOnAppMention(e,t){return await e.thread.startTyping(`Thinking...`),{auth:defaultSlackAuth(t,e)}}async function defaultOnDirectMessage(e,t){return await e.thread.startTyping(`Thinking...`),{auth:defaultSlackAuth(t,e)}}function firstNonEmptyLine(e){for(let t of e.split(/\r?\n/u)){let e=t.trim();if(e.length>0)return e}}function defaultInputRequestedHandler(){return async(e,t,n)=>{if(e.requests.length===0)return;let i=truncateMessageText(e.requests.map(e=>e.prompt).join(`
2
2
  `));await t.thread.post({blocks:e.requests.flatMap(renderInputRequestBlocks),text:i})}}const defaultEvents={async"turn.started"(e,t,n){t.state.pendingToolCallMessage=null,t.state.lastReasoningTypingAtMs=null,t.state.lastReasoningTypingStatus=null,await t.thread.startTyping(`Working...`)},async"reasoning.appended"(e,t,n){let r=firstNonEmptyLine(e.reasoningSoFar);if(r===void 0)return;let a=truncateTypingStatus(r),o=t.state.lastReasoningTypingStatus,s=o!=null&&a.startsWith(o)&&a.length>=o.length+4,c=Date.now(),l=t.state.lastReasoningTypingAtMs;if(!s&&l!=null){let e=c-l;if(e>=0&&e<5e3)return}await t.thread.startTyping(a),t.state.lastReasoningTypingAtMs=c,t.state.lastReasoningTypingStatus=a},async"actions.requested"(e,t,n){let r=t.state.pendingToolCallMessage;if(t.state.pendingToolCallMessage=null,r){await t.thread.startTyping(truncateTypingStatus(r));return}let a=e.actions.map(e=>e.kind===`tool-call`?e.toolName:e.kind);await t.thread.startTyping(truncateTypingStatus(`Running ${a.join(`, `)}...`))},async"message.completed"(e,t,n){if(e.finishReason===`tool-calls`){t.state.pendingToolCallMessage=e.message?firstNonEmptyLine(e.message)??null:null;return}t.state.pendingToolCallMessage=null,e.message&&await t.thread.post(e.message)},async"turn.failed"(e,r,i){let a=formatErrorHint(e),o=extractErrorId(e.details);await r.thread.post([`I hit an error while handling your request${a}.`,``,`Please try again, rephrase, or reach out if it keeps failing.`,...o?[``,`_Error id: \`${o}\`_`]:[]].join(`
3
3
  `))},async"session.failed"(e,r){let i=formatErrorHint(e),a=extractErrorId(e.details);await r.thread.post([`This session couldn't recover from an error${i}.`,``,`Start a new thread to continue — I can't pick this one back up.`,...a?[``,`_Error id: \`${a}\`_`]:[]].join(`
4
- `))},async"authorization.required"(e,t,n){let r=e.authorization?.displayName??formatConnectionDisplayName(e.name),i=t.state.triggeringUserId??null,a=e.authorization?.url;if(i&&a){let n=e.authorization?.userCode;try{await t.thread.postEphemeral(i,{blocks:buildAuthEphemeralBlocks({displayName:r,url:a,userCode:n}),text:n?`Sign in with ${r}: ${a} (code: ${n})`:`Sign in with ${r}: ${a}`});return}catch(t){log.error(`Slack auth ephemeral delivery failed`,{name:e.name,error:t})}}let o=buildAuthRequiredPublicText({displayName:r,hasUser:i!==null});try{let n=await t.thread.post(o);n.id&&(t.state.pendingAuthMessageTs={...t.state.pendingAuthMessageTs,[e.name]:n.id})}catch(t){log.error(`Slack auth public message delivery failed`,{name:e.name,error:t})}},async"authorization.completed"(e,t,n){let r=t.state.pendingAuthMessageTs??{},i=r[e.name];if(i===void 0)return;let a=buildAuthCompletedText({displayName:e.authorization?.displayName??formatConnectionDisplayName(e.name),outcome:e.outcome,reason:e.reason});try{await t.slack.request(`chat.update`,{channel:t.slack.channelId,ts:i,text:a})}catch(t){log.error(`Slack auth status edit failed`,{name:e.name,error:t})}let s={...r};delete s[e.name],t.state.pendingAuthMessageTs=s}};export{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage,defaultSlackAuth};
4
+ `))},async"authorization.required"(e,t,n){let r=e.authorization?.displayName??formatConnectionDisplayName(e.name),i=t.state.triggeringUserId??null,a=e.authorization?.url,o=t.state.pendingAuthMessageTs??{};if(o[e.name]===void 0){let n=buildAuthRequiredPublicText({displayName:r,hasUser:i!==null});try{let r=await t.thread.post(n);r.id&&(t.state.pendingAuthMessageTs={...o,[e.name]:r.id})}catch(t){log.error(`Slack auth public message delivery failed`,{name:e.name,error:t})}}if(i&&a){let n=e.authorization?.userCode;try{await t.thread.postEphemeral(i,{blocks:buildAuthEphemeralBlocks({displayName:r,url:a,userCode:n}),text:n?`Sign in with ${r}: ${a} (code: ${n})`:`Sign in with ${r}: ${a}`})}catch(t){log.error(`Slack auth ephemeral delivery failed`,{name:e.name,error:t})}}},async"authorization.completed"(e,t,n){let r=t.state.pendingAuthMessageTs??{},i=r[e.name];if(i===void 0)return;let a=buildAuthCompletedText({displayName:e.authorization?.displayName??formatConnectionDisplayName(e.name),outcome:e.outcome,reason:e.reason});try{await t.slack.request(`chat.update`,{channel:t.slack.channelId,ts:i,text:a})}catch(t){log.error(`Slack auth status edit failed`,{name:e.name,error:t})}let s={...r};delete s[e.name],t.state.pendingAuthMessageTs=s}};export{defaultEvents,defaultInputRequestedHandler,defaultOnAppMention,defaultOnDirectMessage,defaultSlackAuth};
@@ -116,11 +116,10 @@ export interface SlackChannelState {
116
116
  lastReasoningTypingStatus?: string | null;
117
117
  /**
118
118
  * Connection name to Slack message ts. Each entry is the public
119
- * link-free fallback status post created by the default
120
- * `authorization.required` handler when the challenge could not be
121
- * delivered ephemerally; the matching `authorization.completed`
122
- * handler edits it in place to surface the resolution outcome. The
123
- * normal ephemeral path stores nothing here.
119
+ * link-free status post created by the default
120
+ * `authorization.required` handler; the matching
121
+ * `authorization.completed` handler edits it in place to surface the
122
+ * resolution outcome.
124
123
  */
125
124
  pendingAuthMessageTs?: Record<string, string>;
126
125
  }
@@ -272,8 +271,8 @@ export interface SlackChannelEvents {
272
271
  * Full-context variant of {@link SlackChannelEvents} consumed by the
273
272
  * channel internals. The framework's default `authorization.required`
274
273
  * handler keeps the full {@link SlackEventContext} because it owns the
275
- * public link-free fallback for sessions with no user to target
276
- * privately. The factory adapts user overrides into this shape with
274
+ * public link-free status while user overrides remain private-only. The
275
+ * factory adapts user overrides into this shape with
277
276
  * {@link constrainAuthorizationRequired}.
278
277
  */
279
278
  export interface SlackChannelInternalEvents extends Omit<SlackChannelEvents, "authorization.required"> {
@@ -2,7 +2,7 @@ import type { StandardJSONSchemaV1 } from "#compiled/@standard-schema/spec/index
2
2
  import type { PublicToolDefinition, ToolModelOutput } from "#shared/tool-definition.js";
3
3
  import type { SessionContext } from "#public/definitions/callback-context.js";
4
4
  import type { JsonObject } from "#shared/json.js";
5
- import type { AuthorizationDefinition, NonInteractiveAuthorizationDefinition, TokenResult } from "#runtime/connections/types.js";
5
+ import type { AuthorizationDefinition, ConnectionAuthorizationContext, NonInteractiveAuthorizationDefinition, TokenResult } from "#runtime/connections/types.js";
6
6
  import { type DynamicEvents, type DynamicSentinel } from "#shared/dynamic-tool-definition.js";
7
7
  type ApprovalToolInput<TInput> = TInput extends object ? Readonly<TInput> : TInput;
8
8
  type ApprovalContextInput<TInput> = unknown extends TInput ? Record<string, unknown> : TInput;
@@ -25,19 +25,45 @@ export type { ToolModelOutput } from "#shared/tool-definition.js";
25
25
  * `auth` field. Accepts the same shapes as a connection's `auth`:
26
26
  * - a `getToken`-only object (static API keys, pre-provisioned JWTs);
27
27
  * `principalType` may be omitted and defaults to `"app"`.
28
- * - a full interactive OAuth definition (e.g. `connect("okta")` from
28
+ * - a full interactive OAuth definition (e.g. `connect("okta/myagent")` from
29
29
  * `@vercel/connect/eve`, or {@link defineInteractiveAuthorization}).
30
30
  */
31
31
  export type ToolAuthDefinition = (Omit<NonInteractiveAuthorizationDefinition, "principalType"> & {
32
32
  readonly principalType?: NonInteractiveAuthorizationDefinition["principalType"];
33
33
  }) | AuthorizationDefinition;
34
+ export type ToolAuthProvider = ToolAuthDefinition;
35
+ /**
36
+ * Controls Eve runtime behavior for an inline tool auth provider.
37
+ */
38
+ export interface ToolAuthOptions {
39
+ /**
40
+ * Connection metadata passed through to provider callbacks. Tool-only
41
+ * providers usually leave this unset; connection-backed helpers can use it
42
+ * to receive the upstream server URL.
43
+ */
44
+ readonly connection?: ConnectionAuthorizationContext;
45
+ /**
46
+ * Optional human-readable provider name shown in sign-in UI. Presentation
47
+ * only; it does not affect OAuth scopes, token cache keys, or callback URLs.
48
+ */
49
+ readonly displayName?: string;
50
+ /**
51
+ * Optional Eve auth-flow key for token caches, callback URLs, pending
52
+ * authorization state, and authorization completion. This is not an OAuth
53
+ * scope. For Vercel Connect OAuth targeting such as `scopes`, `resources`,
54
+ * or `authorizationDetails`, configure the provider with
55
+ * `connect({ connector, tokenParams })`.
56
+ */
57
+ readonly authKey?: string;
58
+ }
34
59
  /**
35
60
  * Authored tool context. Passed as the last argument to
36
61
  * {@link ToolDefinition.execute}.
37
62
  *
38
- * Extends {@link SessionContext} with token accessors. {@link getToken} and
39
- * {@link requireAuth} only do useful work when the tool declares `auth`;
40
- * calling them on a tool without `auth` throws.
63
+ * Extends {@link SessionContext} with token accessors. Passing a provider
64
+ * resolves that provider inline, which lets one tool use multiple credentials.
65
+ * For backwards compatibility, calling the accessors without a provider uses
66
+ * the tool's deprecated top-level `auth` field and throws when no `auth` exists.
41
67
  */
42
68
  export type ToolContext = SessionContext & {
43
69
  /**
@@ -50,16 +76,34 @@ export type ToolContext = SessionContext & {
50
76
  * callback completes.
51
77
  *
52
78
  * Throws when the tool does not declare an `auth` strategy.
79
+ *
80
+ * @deprecated Prefer `ctx.getToken(provider)` so auth dependencies live at
81
+ * the call site and compose when a tool needs multiple credentials.
53
82
  */
54
83
  getToken(): Promise<TokenResult>;
55
84
  /**
56
- * Signals that the caller must complete this tool's authorization flow
57
- * before proceeding. Throws `ConnectionAuthorizationRequiredError`, which
58
- * the runtime converts into a consent prompt (for interactive strategies)
59
- * and re-runs the tool after sign-in. Use it to gate a tool on
60
- * authorization without resolving a token first.
85
+ * Resolves the bearer token for an inline provider. This accepts the same
86
+ * auth shapes as a connection's `auth` field, including `connect("...")`
87
+ * from `@vercel/connect/eve`.
88
+ */
89
+ getToken(provider: ToolAuthProvider, options?: ToolAuthOptions): Promise<TokenResult>;
90
+ /**
91
+ * Signals that the caller must complete this tool's authorization flow.
92
+ * Throws `ConnectionAuthorizationRequiredError`, which the runtime converts
93
+ * into a consent prompt (for interactive strategies) and re-runs the tool
94
+ * after sign-in. Use it after a downstream request rejects a token returned
95
+ * by the deprecated no-argument {@link getToken}.
96
+ *
97
+ * @deprecated Prefer `ctx.requireAuth(provider)` so auth dependencies live at
98
+ * the call site and compose when a tool needs multiple credentials.
61
99
  */
62
100
  requireAuth(): never;
101
+ /**
102
+ * Signals that the caller must complete authorization for an inline
103
+ * provider before proceeding. Use this after a downstream `401` rejects a
104
+ * token returned by {@link getToken}.
105
+ */
106
+ requireAuth(provider: ToolAuthProvider, options?: ToolAuthOptions): never;
63
107
  };
64
108
  /**
65
109
  * Public tool definition authored in `agent/tools/*.ts`.
@@ -71,17 +115,13 @@ export type ToolContext = SessionContext & {
71
115
  export type ToolDefinition<TInput = unknown, TOutput = unknown> = PublicToolDefinition<TInput, TOutput> & {
72
116
  execute(input: TInput, ctx: ToolContext): Promise<TOutput> | TOutput;
73
117
  /**
74
- * Optional authorization strategy. When set, the execute context gains a
75
- * working {@link ToolContext.getToken} / {@link ToolContext.requireAuth},
76
- * and a thrown `ConnectionAuthorizationRequiredError` (implicit from
77
- * `getToken()` or explicit via `requireAuth()`) drives the framework's
78
- * interactive consent flow, the same machinery MCP connections use, scoped
79
- * to this tool's name.
118
+ * Optional authorization strategy used by the deprecated no-argument
119
+ * {@link ToolContext.getToken} / {@link ToolContext.requireAuth} accessors.
80
120
  *
81
- * Use `connect("...")` from `@vercel/connect/eve` for Vercel
82
- * Connect-backed OAuth, {@link defineInteractiveAuthorization} for a
83
- * custom interactive flow, or a plain `{ getToken }` object for
84
- * static/pre-provisioned credentials.
121
+ * @deprecated Prefer passing a provider at the call site:
122
+ * `ctx.getToken(connect("..."))` or `ctx.requireAuth(connect("..."))`.
123
+ * Inline providers use the same auth shapes and compose when a tool needs
124
+ * multiple credentials.
85
125
  */
86
126
  auth?: ToolAuthDefinition;
87
127
  /**
@@ -120,6 +160,7 @@ export declare function defineTool<TInputSchema extends StandardJSONSchemaV1<unk
120
160
  execute(input: StandardJSONSchemaV1.InferOutput<TInputSchema>, ctx: ToolContext): Promise<StandardJSONSchemaV1.InferOutput<TOutputSchema>> | StandardJSONSchemaV1.InferOutput<TOutputSchema>;
121
161
  needsApproval?: ToolDefinition<StandardJSONSchemaV1.InferOutput<TInputSchema>, unknown>["needsApproval"];
122
162
  toModelOutput?: ToolDefinition<unknown, StandardJSONSchemaV1.InferOutput<TOutputSchema>>["toModelOutput"];
163
+ /** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
123
164
  auth?: ToolAuthDefinition;
124
165
  }): ToolDefinition<StandardJSONSchemaV1.InferOutput<TInputSchema>, StandardJSONSchemaV1.InferOutput<TOutputSchema>>;
125
166
  export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown, unknown>, TOutput>(definition: {
@@ -129,6 +170,7 @@ export declare function defineTool<TSchema extends StandardJSONSchemaV1<unknown,
129
170
  execute(input: StandardJSONSchemaV1.InferOutput<TSchema>, ctx: ToolContext): Promise<TOutput> | TOutput;
130
171
  needsApproval?: ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, unknown>["needsApproval"];
131
172
  toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
173
+ /** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
132
174
  auth?: ToolAuthDefinition;
133
175
  }): ToolDefinition<StandardJSONSchemaV1.InferOutput<TSchema>, TOutput>;
134
176
  export declare function defineTool<TOutputSchema extends StandardJSONSchemaV1<unknown, unknown>>(definition: {
@@ -138,6 +180,7 @@ export declare function defineTool<TOutputSchema extends StandardJSONSchemaV1<un
138
180
  execute(input: Record<string, unknown>, ctx: ToolContext): Promise<StandardJSONSchemaV1.InferOutput<TOutputSchema>> | StandardJSONSchemaV1.InferOutput<TOutputSchema>;
139
181
  needsApproval?: ToolDefinition<Record<string, unknown>, unknown>["needsApproval"];
140
182
  toModelOutput?: ToolDefinition<unknown, StandardJSONSchemaV1.InferOutput<TOutputSchema>>["toModelOutput"];
183
+ /** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
141
184
  auth?: ToolAuthDefinition;
142
185
  }): ToolDefinition<Record<string, unknown>, StandardJSONSchemaV1.InferOutput<TOutputSchema>>;
143
186
  export declare function defineTool<TOutput>(definition: {
@@ -147,6 +190,7 @@ export declare function defineTool<TOutput>(definition: {
147
190
  execute(input: Record<string, unknown>, ctx: ToolContext): Promise<TOutput> | TOutput;
148
191
  needsApproval?: ToolDefinition<Record<string, unknown>, unknown>["needsApproval"];
149
192
  toModelOutput?: ToolDefinition<unknown, TOutput>["toModelOutput"];
193
+ /** @deprecated Prefer inline providers via `ctx.getToken(provider)`. */
150
194
  auth?: ToolAuthDefinition;
151
195
  }): ToolDefinition<Record<string, unknown>, TOutput>;
152
196
  export declare function defineTool<TInput = unknown, TOutput = unknown>(definition: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
@@ -1,4 +1,10 @@
1
- import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@vercel/sandbox/index.js";
1
+ import type * as Vercel from "#compiled/@vercel/sandbox/index.js";
2
+ type VercelCreateOptions = NonNullable<Parameters<typeof Vercel.Sandbox.create>[0]>;
3
+ type VercelUpdateOptions = Parameters<Vercel.Sandbox["update"]>[0];
4
+ type VercelSandboxInternalCreateOptions = {
5
+ readonly [key: `__${string}`]: unknown;
6
+ };
7
+ type VercelSandboxAuthorCreateOptions<T> = T extends unknown ? Omit<T, "name" | "onResume" | "persistent" | "signal"> & VercelSandboxInternalCreateOptions : never;
2
8
  /**
3
9
  * Options accepted by `vercel(opts)`. Forwarded to Vercel
4
10
  * Sandbox creation for every fresh sandbox the framework creates
@@ -25,13 +31,10 @@ import type { Sandbox as SdkSandbox, SandboxUpdateParams } from "#compiled/@verc
25
31
  * snapshot, force a template rebuild (e.g. by changing the sandbox
26
32
  * definition so its template key changes).
27
33
  */
28
- export type VercelSandboxCreateOptions = Omit<NonNullable<Parameters<typeof SdkSandbox.create>[0]>, "name" | "onResume" | "persistent" | "signal"> & VercelSandboxInternalCreateOptions;
29
- type VercelSandboxInternalCreateOptions = {
30
- readonly [key: `__${string}`]: unknown;
31
- };
34
+ export type VercelSandboxCreateOptions = VercelSandboxAuthorCreateOptions<VercelCreateOptions>;
32
35
  /**
33
36
  * Options accepted by the Vercel backend's `bootstrap({ use })` hook.
34
- * Aliases the Vercel SDK's `SandboxUpdateParams` because bootstrap
37
+ * Tracks the Vercel SDK's `Sandbox.update(...)` parameter because bootstrap
35
38
  * applies its options to the template via `sandbox.update(...)` after
36
39
  * `Sandbox.create()` and before the snapshot is captured. The Vercel
37
40
  * SDK persists `update`-d settings on the sandbox so they survive into
@@ -41,11 +44,11 @@ type VercelSandboxInternalCreateOptions = {
41
44
  * {@link VercelSandboxSessionUseOptions}; both are exposed as separate
42
45
  * named aliases so future divergence is non-breaking.
43
46
  */
44
- export type VercelSandboxBootstrapUseOptions = SandboxUpdateParams;
47
+ export type VercelSandboxBootstrapUseOptions = VercelUpdateOptions;
45
48
  /**
46
49
  * Options accepted by the Vercel backend's `onSession({ use })` hook.
47
- * Aliases the Vercel SDK's `SandboxUpdateParams`; passed values are
50
+ * Tracks the Vercel SDK's `Sandbox.update(...)` parameter; passed values are
48
51
  * applied to the live session via the SDK's `update`.
49
52
  */
50
- export type VercelSandboxSessionUseOptions = SandboxUpdateParams;
53
+ export type VercelSandboxSessionUseOptions = VercelUpdateOptions;
51
54
  export {};
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tool authoring helpers for `agent/tools/*.ts` files.
3
3
  */
4
- export { type DisabledToolSentinel, type EnableWorkflowToolSentinel, defineDynamic, defineTool, disableTool, isDisabledToolSentinel, isEnableWorkflowToolSentinel, type NeedsApprovalContext, type ToolDefinition, type ToolContext, type ToolModelOutput, ExperimentalWorkflow, } from "#public/definitions/tool.js";
4
+ export { type DisabledToolSentinel, type EnableWorkflowToolSentinel, defineDynamic, defineTool, disableTool, isDisabledToolSentinel, isEnableWorkflowToolSentinel, type NeedsApprovalContext, type ToolAuthOptions, type ToolAuthProvider, type ToolDefinition, type ToolContext, type ToolModelOutput, ExperimentalWorkflow, } from "#public/definitions/tool.js";
5
5
  export type { DynamicToolEntry, DynamicEvents, DynamicToolEvents, DynamicResolveContext, DynamicSentinel, DynamicToolSet, DynamicToolResult, } from "#shared/dynamic-tool-definition.js";
6
6
  export { type SessionContext } from "#public/definitions/callback-context.js";
7
7
  export { toolResultFrom, type MatchedConnectionResult, type MatchedToolResult, type ToolResultFromFn, } from "#public/tool-result-narrowing.js";
@@ -1 +1 @@
1
- import{contextStorage,loadContext}from"#context/container.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{evictCachedToken,readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";async function resolveScopedToken(t){let{scope:n,authorization:r,connection:i}=t,a=contextStorage.getStore(),o=resolveConnectionPrincipal(n,r,a);if(a===void 0)return await r.getToken({connection:i,principal:o});let u=principalKey(o),d=readCachedToken(a,n,u);if(d!==void 0)return d;let f=await r.getToken({connection:i,principal:o});return writeCachedToken(a,n,u,f),f}async function evictScopedToken(t){let{scope:n,authorization:r,connection:i}=t,a=contextStorage.getStore();if(a===void 0)return;let s;try{s=resolveConnectionPrincipal(n,r,a),evictCachedToken(a,n,principalKey(s))}catch{return}try{await r.evict?.({connection:i,principal:s})}catch{}}async function completeScopedAuthorization(e){let{scope:i,authorization:a,connection:o}=e;if(!supportsInteractiveAuthorization(a))return!1;let s=getAuthorizationResult(i);if(s===void 0)return!1;let u=a,d=loadContext(),f=resolveConnectionPrincipal(i,u,d),p=await u.completeAuthorization({callbackUrl:s.hookUrl,connection:o,principal:f,resume:s.resume,callback:s.callback});return writeCachedToken(d,i,principalKey(f),p),!0}async function startScopedAuthorization(e){let{scope:t,authorization:r,connection:o}=e;if(!supportsInteractiveAuthorization(r))return;let s=getHookUrl(t);if(s===void 0)return;let c=r,l=resolveConnectionPrincipal(t,c),{challenge:u,resume:d}=await c.startAuthorization({callbackUrl:s,connection:o,principal:l});return requestAuthorization([{challenge:stampChallengeDisplayName(u,r),hookUrl:s,name:t,resume:d}])}function stampChallengeDisplayName(e,t){let n=t.displayName??e.displayName;return n===e.displayName?e:{...e,displayName:n}}export{completeScopedAuthorization,evictScopedToken,resolveScopedToken,stampChallengeDisplayName,startScopedAuthorization};
1
+ import{contextStorage,loadContext}from"#context/container.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{evictCachedToken,readCachedToken,writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";async function resolveScopedToken(t){let{scope:n,authorization:r,connection:i}=t,a=contextStorage.getStore(),o=resolveConnectionPrincipal(n,r,a);if(a===void 0)return await r.getToken({connection:i,principal:o});let u=principalKey(o),d=readCachedToken(a,n,u);if(d!==void 0)return d;let f=await r.getToken({connection:i,principal:o});return writeCachedToken(a,n,u,f),f}async function evictScopedToken(t){let{scope:n,authorization:r,connection:i}=t,a=contextStorage.getStore();if(a===void 0)return;let s;try{s=resolveConnectionPrincipal(n,r,a),evictCachedToken(a,n,principalKey(s))}catch{return}try{await r.evict?.({connection:i,principal:s})}catch{}}async function completeScopedAuthorization(e){let{scope:r,authorization:i,connection:o}=e;if(!supportsInteractiveAuthorization(i))return!1;let s=getAuthorizationResult(r);if(s===void 0)return!1;let u=i,d=loadContext(),f=resolveConnectionPrincipal(r,u,d),p=await u.completeAuthorization({callbackUrl:s.hookUrl,connection:o,principal:f,resume:s.resume,callback:s.callback});return writeCachedToken(d,r,principalKey(f),p),!0}async function startScopedAuthorization(e){let{scope:t,authorization:n,connection:o}=e;if(!supportsInteractiveAuthorization(n))return;let s=getHookUrl(t);if(s===void 0)return;let c=n,l=resolveConnectionPrincipal(t,c),{challenge:u,resume:d}=await c.startAuthorization({callbackUrl:s,connection:o,principal:l});return requestAuthorization([{challenge:stampChallengeDisplayName(u,n),hookUrl:s,name:t,resume:d}])}function stampChallengeDisplayName(e,t){let n=t.displayName??e.displayName;return n===e.displayName?e:{...e,displayName:n}}export{completeScopedAuthorization,evictScopedToken,resolveScopedToken,stampChallengeDisplayName,startScopedAuthorization};
@@ -1 +1 @@
1
- function validateAuthorizationSpec(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0;if(!r&&!i&&n.principalType!==void 0&&n.principalType!==`app`&&n.principalType!==`user`)return`The "${t}.principalType" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. App-level credentials must use a getToken-only definition.`;if(n.displayName!==void 0&&(typeof n.displayName!=`string`||n.displayName.length===0))return`The "${t}.displayName" field must be a non-empty string when provided.`}function normalizeAuthorizationSpec(e,t,n=`auth`){let r=validateAuthorizationSpec(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=extractVercelConnectMarker(i.vercelConnect),o=i.displayName;if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return a!==void 0&&(e={...e,vercelConnect:a}),o!==void 0&&(e={...e,displayName:o}),e}let s={getToken:i.getToken,principalType:i.principalType??`app`};return a!==void 0&&(s={...s,vercelConnect:a}),o!==void 0&&(s={...s,displayName:o}),s}function extractVercelConnectMarker(e){if(typeof e!=`object`||!e)return;let t=e.connector;if(!(typeof t!=`string`||t.length===0))return{connector:t}}export{normalizeAuthorizationSpec,validateAuthorizationSpec};
1
+ function validateAuthorizationSpec(e,t=`auth`){if(typeof e!=`object`||!e)return`The "${t}" field must be an object with a "getToken" method.`;let n=e;if(typeof n.getToken!=`function`)return`The "${t}.getToken" field must be a function returning Promise<{ token }>.`;let r=n.startAuthorization!==void 0,i=n.completeAuthorization!==void 0;if(!r&&!i&&n.principalType!==void 0&&n.principalType!==`app`&&n.principalType!==`user`)return`The "${t}.principalType" field must be "app" or "user".`;if(r!==i)return`The "${t}" field must provide either both "startAuthorization" and "completeAuthorization" (interactive OAuth) or neither (getToken-only). Got only "${r?`startAuthorization`:`completeAuthorization`}".`;if(r&&typeof n.startAuthorization!=`function`)return`The "${t}.startAuthorization" field must be a function when provided.`;if(i&&typeof n.completeAuthorization!=`function`)return`The "${t}.completeAuthorization" field must be a function when provided.`;if(r&&n.principalType!==`user`)return`Interactive authorization (startAuthorization + completeAuthorization) is restricted to "principalType": "user" in v1. App-level credentials must use a getToken-only definition.`;if(n.displayName!==void 0&&(typeof n.displayName!=`string`||n.displayName.length===0))return`The "${t}.displayName" field must be a non-empty string when provided.`}function normalizeAuthorizationSpec(e,t,n=`auth`){let r=validateAuthorizationSpec(e,n);if(r!==void 0)throw Error(`${t} ${r}`);let i=e,a=extractVercelConnectMarker(i.vercelConnect),o=i.displayName,s=typeof i.evict==`function`?i.evict:void 0;if(i.startAuthorization!==void 0&&i.completeAuthorization!==void 0){let e={completeAuthorization:i.completeAuthorization,getToken:i.getToken,principalType:`user`,startAuthorization:i.startAuthorization};return a!==void 0&&(e={...e,vercelConnect:a}),o!==void 0&&(e={...e,displayName:o}),s!==void 0&&(e={...e,evict:s}),e}let c={getToken:i.getToken,principalType:i.principalType??`app`};return a!==void 0&&(c={...c,vercelConnect:a}),o!==void 0&&(c={...c,displayName:o}),s!==void 0&&(c={...c,evict:s}),c}function extractVercelConnectMarker(e){if(typeof e!=`object`||!e)return;let t=e.connector;if(!(typeof t!=`string`||t.length===0))return{connector:t}}export{normalizeAuthorizationSpec,validateAuthorizationSpec};
@@ -1 +1 @@
1
- import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_OUTPUT_SCHEMA={items:{additionalProperties:!1,properties:{connection:{type:`string`},description:{type:`string`},error:{type:`string`},inputSchema:{type:`object`},needsAuthorization:{type:`boolean`},outputSchema:{type:`object`},qualifiedName:{type:`string`},tool:{type:`string`}},required:[`connection`,`description`],type:`object`},type:`array`},ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n?.authorization&&supportsInteractiveAuthorization(n.authorization))return n.authorization}async function completePendingAuthorizations(e){let n=loadContext(),r=new Set;for(let t of e.getConnections()){let i=getAuthorizationResult(t.connectionName);if(!i)continue;let a=resolveInteractiveAuth(e,t.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(t.connectionName,a),s=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:{url:t.url??``},principal:o,resume:i.resume,callback:i.callback});writeCachedToken(n,t.connectionName,principalKey(o),s),r.add(t.connectionName)}return r}async function executeConnectionSearch(e){let n=loadContext(),i=n.get(ConnectionRegistryKey);if(i===void 0)return[];let s=await completePendingAuthorizations(i),c=e.limit??10,l=tokenize(e.keywords),u=[],f=[],m=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections(),h=[];for(let e of m){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(s.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),f.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=resolveInteractiveAuth(i,e.connectionName);if(t){let n=getHookUrl(e.connectionName);if(n){let r=resolveConnectionPrincipal(e.connectionName,t);try{let{challenge:i,resume:a}=await t.startAuthorization({callbackUrl:n,connection:{url:e.url??``},principal:r});h.push({name:e.connectionName,challenge:stampChallengeDisplayName(i,t),hookUrl:n,resume:a})}catch(t){logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:t instanceof Error?t:Error(String(t))})}}}f.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),f.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),f.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}for(let n of t){let t=scoreMatch(l,n);t>0&&u.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(h.length>0)return requestAuthorization(h);u.sort((e,t)=>t.score-e.score);let g=u.slice(0,c).map(e=>e.item);if(g.length>0){let e=[...g,...f],t=n.get(ConnectionSearchResultsKey)??[],r=new Map(t.map(e=>[e.qualifiedName,e]));for(let e of g)e.qualifiedName&&r.set(e.qualifiedName,e);return n.set(ConnectionSearchResultsKey,[...r.values()]),e}return m.map(e=>f.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}function createConnectionSearchEvents(){return{"step.started":async(e,n)=>{let a=loadContext().get(ConnectionRegistryKey);if(!a||a.getConnections().length===0)return null;let d=a.getConnections().map(e=>e.connectionName),m=extractDiscoveredTools(n.messages),h=loadContext().get(ConnectionSearchResultsKey)??[],g=new Map;for(let e of h)e.qualifiedName&&g.set(e.qualifiedName,e);for(let e of m)e.qualifiedName&&g.set(e.qualifiedName,e);let _=[...g.values()],v={};v.connection_search={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${d.join(`, `)}.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`},connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`}},required:[`keywords`]},async execute(e){return executeConnectionSearch(e)},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA};for(let e of _){let n=e.connection,d=e.tool,f=a.getConnectionApproval(n);v[qualifiedConnectionToolName(n,d)]={description:e.description,inputSchema:e.inputSchema??{type:`object`},needsApproval:f,outputSchema:e.outputSchema,async execute(e){let a=loadContext().get(ConnectionRegistryKey),f=a.getConnections().find(e=>e.connectionName===n),p=f?.authorization&&supportsInteractiveAuthorization(f.authorization)?f.authorization:void 0,m=!1;if(p){let e=getAuthorizationResult(n);if(e){m=!0;let r=loadContext(),i=resolveConnectionPrincipal(n,p),a=await p.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:f?.url??``},principal:i,resume:e.resume,callback:e.callback});writeCachedToken(r,n,principalKey(i),a)}}try{return await a.getClient(n).executeTool(d,e)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!p)throw e;if(m)throw new ConnectionAuthorizationFailedError(n,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${n}" rejected the token immediately after authorization.`});let t=getHookUrl(n);if(!t)throw e;let r=resolveConnectionPrincipal(n,p),{challenge:a,resume:s}=await p.startAuthorization({callbackUrl:t,connection:{url:f?.url??``},principal:r});return requestAuthorization([{name:n,challenge:stampChallengeDisplayName(a,p),hookUrl:t,resume:s}])}}}}return v}}}function createConnectionSearchResolver(){let e=createConnectionSearchEvents();return{slug:`connection`,eventNames:Object.keys(e),events:e,sourceId:`eve:connection-search-dynamic`,sourceKind:`module`,logicalPath:`eve:framework/connection-search-dynamic`}}export{createConnectionSearchEvents,createConnectionSearchResolver,extractDiscoveredTools};
1
+ import{createLogger}from"#internal/logging.js";import{loadContext}from"#context/container.js";import{ContextKey}from"#context/key.js";import{ConnectionRegistryKey}from"#context/providers/connection.js";import{ConnectionAuthorizationFailedError,isConnectionAuthorizationFailedError,isConnectionAuthorizationRequiredError}from"#public/connections/errors.js";import{getAuthorizationResult,getHookUrl,requestAuthorization}from"#harness/authorization.js";import{supportsInteractiveAuthorization}from"#runtime/connections/types.js";import{stampChallengeDisplayName}from"#runtime/connections/scoped-authorization.js";import{writeCachedToken}from"#runtime/connections/authorization-tokens.js";import{principalKey,resolveConnectionPrincipal}from"#runtime/connections/principal.js";const logger=createLogger(`framework.connection-search-dynamic`),CONNECTION_SEARCH_OUTPUT_SCHEMA={items:{additionalProperties:!1,properties:{connection:{type:`string`},description:{type:`string`},error:{type:`string`},inputSchema:{type:`object`},needsAuthorization:{type:`boolean`},outputSchema:{type:`object`},qualifiedName:{type:`string`},tool:{type:`string`}},required:[`connection`,`description`],type:`object`},type:`array`},ConnectionSearchResultsKey=new ContextKey(`eve.connectionSearchResults`);function qualifiedConnectionToolName(e,t){return`${e}__${t}`}function tokenize(e){return e.toLowerCase().split(/[\s_\-./]+/).filter(e=>e.length>1)}function scoreMatch(e,t){let n=tokenize(t.name),r=tokenize(t.description),i=0;for(let t of e){for(let e of n)(e.includes(t)||t.includes(e))&&(i+=3);for(let e of r)(e.includes(t)||t.includes(e))&&(i+=1)}return i}function resolveInteractiveAuth(e,t){let n=e.getConnections().find(e=>e.connectionName===t);if(n?.authorization&&supportsInteractiveAuthorization(n.authorization))return n.authorization}async function completePendingAuthorizations(e){let n=loadContext(),r=new Set;for(let t of e.getConnections()){let i=getAuthorizationResult(t.connectionName);if(!i)continue;let a=resolveInteractiveAuth(e,t.connectionName);if(!a)continue;let o=resolveConnectionPrincipal(t.connectionName,a),c=await a.completeAuthorization({callbackUrl:i.hookUrl,connection:{url:t.url??``},principal:o,resume:i.resume,callback:i.callback});writeCachedToken(n,t.connectionName,principalKey(o),c),r.add(t.connectionName)}return r}async function executeConnectionSearch(e){let n=loadContext(),i=n.get(ConnectionRegistryKey);if(i===void 0)return[];let s=await completePendingAuthorizations(i),l=e.limit??10,u=tokenize(e.keywords),d=[],p=[],h=e.connection!==void 0&&e.connection!==``?i.getConnections().filter(t=>t.connectionName===e.connection):i.getConnections(),g=[];for(let e of h){let t;try{t=await i.getClient(e.connectionName).getToolMetadata()}catch(t){if(isConnectionAuthorizationRequiredError(t)){if(s.has(e.connectionName)){logger.warn(`connection still unauthorized after authorization`,{connection:e.connectionName}),p.push({connection:e.connectionName,description:e.description,error:`Authorization for "${e.connectionName}" did not take effect; the token was rejected after sign-in.`});continue}let t=resolveInteractiveAuth(i,e.connectionName);if(t){let n=getHookUrl(e.connectionName);if(n){let r=resolveConnectionPrincipal(e.connectionName,t);try{let{challenge:i,resume:a}=await t.startAuthorization({callbackUrl:n,connection:{url:e.url??``},principal:r});g.push({name:e.connectionName,challenge:stampChallengeDisplayName(i,t),hookUrl:n,resume:a})}catch(t){logger.warn(`startAuthorization failed`,{connection:e.connectionName,error:t instanceof Error?t:Error(String(t))})}}}p.push({connection:e.connectionName,description:e.description,needsAuthorization:!0});continue}if(isConnectionAuthorizationFailedError(t)){logger.warn(`connection authorization failed`,{connection:e.connectionName,reason:t.reason,retryable:t.retryable,error:t}),p.push({connection:e.connectionName,description:e.description,error:`Authorization failed for ${e.connectionName}: ${t.message}`});continue}let n=t instanceof Error?t.message:`unknown error`;logger.warn(`failed to load connection tools`,{connection:e.connectionName,error:t instanceof Error?t:Error(n)}),p.push({connection:e.connectionName,description:e.description,error:`Failed to load tools for "${e.connectionName}": ${n}`});continue}for(let n of t){let t=scoreMatch(u,n);t>0&&d.push({item:{connection:e.connectionName,description:n.description,inputSchema:n.inputSchema,outputSchema:n.outputSchema,qualifiedName:qualifiedConnectionToolName(e.connectionName,n.name),tool:n.name},score:t})}}if(g.length>0)return requestAuthorization(g);d.sort((e,t)=>t.score-e.score);let _=d.slice(0,l).map(e=>e.item);if(_.length>0){let e=[..._,...p],t=n.get(ConnectionSearchResultsKey)??[],r=new Map(t.map(e=>[e.qualifiedName,e]));for(let e of _)e.qualifiedName&&r.set(e.qualifiedName,e);return n.set(ConnectionSearchResultsKey,[...r.values()]),e}return h.map(e=>p.find(t=>t.connection===e.connectionName)||{connection:e.connectionName,description:e.description})}function extractDiscoveredTools(e){let t=new Map;for(let n of e){if(n.role!==`tool`)continue;let e=n.content;for(let n of e){if(n.type!==`tool-result`||n.toolName!==`connection_search`)continue;let e=n.output;if(e==null)continue;let r=typeof e==`object`&&`type`in e&&`value`in e?e.value:e;if(Array.isArray(r))for(let e of r)e.tool&&e.qualifiedName&&t.set(e.qualifiedName,e)}}return[...t.values()]}function createConnectionSearchEvents(){return{"step.started":async(e,n)=>{let a=loadContext().get(ConnectionRegistryKey);if(!a||a.getConnections().length===0)return null;let f=a.getConnections().map(e=>e.connectionName),h=extractDiscoveredTools(n.messages),g=loadContext().get(ConnectionSearchResultsKey)??[],_=new Map;for(let e of g)e.qualifiedName&&_.set(e.qualifiedName,e);for(let e of h)e.qualifiedName&&_.set(e.qualifiedName,e);let v=[..._.values()],y={};y.connection_search={description:`Search for tools across your connections. Discovered tools become directly callable by their qualified name (e.g. \`linear__list_issues\`) in your next response. Available connections: ${f.join(`, `)}.`,inputSchema:{type:`object`,additionalProperties:!1,properties:{keywords:{description:`Search keywords and expanded aliases. Distill intent into keywords; avoid stop words like 'a', 'the', 'in'.`,type:`string`},connection:{description:`Optional: limit search to a specific connection name.`,type:`string`},limit:{description:`Max results to return. Default 10.`,type:`number`}},required:[`keywords`]},async execute(e){return executeConnectionSearch(e)},outputSchema:CONNECTION_SEARCH_OUTPUT_SCHEMA};for(let e of v){let n=e.connection,f=e.tool,p=a.getConnectionApproval(n);y[qualifiedConnectionToolName(n,f)]={description:e.description,inputSchema:e.inputSchema??{type:`object`},needsApproval:p,outputSchema:e.outputSchema,async execute(e){let a=loadContext().get(ConnectionRegistryKey),p=a.getConnections().find(e=>e.connectionName===n),m=p?.authorization&&supportsInteractiveAuthorization(p.authorization)?p.authorization:void 0,h=!1;if(m){let e=getAuthorizationResult(n);if(e){h=!0;let r=loadContext(),i=resolveConnectionPrincipal(n,m),a=await m.completeAuthorization({callbackUrl:e.hookUrl,connection:{url:p?.url??``},principal:i,resume:e.resume,callback:e.callback});writeCachedToken(r,n,principalKey(i),a)}}try{return await a.getClient(n).executeTool(f,e)}catch(e){if(!isConnectionAuthorizationRequiredError(e)||!m)throw e;if(h)throw new ConnectionAuthorizationFailedError(n,{retryable:!1,reason:`token_rejected_after_authorization`,message:`Connection "${n}" rejected the token immediately after authorization.`});let t=getHookUrl(n);if(!t)throw e;let r=resolveConnectionPrincipal(n,m),{challenge:a,resume:s}=await m.startAuthorization({callbackUrl:t,connection:{url:p?.url??``},principal:r});return requestAuthorization([{name:n,challenge:stampChallengeDisplayName(a,m),hookUrl:t,resume:s}])}}}}return y}}}function createConnectionSearchResolver(){let e=createConnectionSearchEvents();return{slug:`connection`,eventNames:Object.keys(e),events:e,sourceId:`eve:connection-search-dynamic`,sourceKind:`module`,logicalPath:`eve:framework/connection-search-dynamic`}}export{createConnectionSearchEvents,createConnectionSearchResolver,extractDiscoveredTools};
@@ -0,0 +1,15 @@
1
+ import { appendEnv } from "./append-env.js";
2
+ export declare const AI_GATEWAY_API_KEY_ENV_VAR = "AI_GATEWAY_API_KEY";
3
+ export declare const AI_GATEWAY_API_KEY_ENV_FILE = ".env.local";
4
+ /** The location written by eve when a user supplies an AI Gateway API key. */
5
+ export interface AiGatewayApiKeyLocation {
6
+ envKey: typeof AI_GATEWAY_API_KEY_ENV_VAR;
7
+ envFile: typeof AI_GATEWAY_API_KEY_ENV_FILE;
8
+ envPath: string;
9
+ }
10
+ /** Trims and saves an explicit AI Gateway API key, replacing any prior value. */
11
+ export declare function writeAiGatewayApiKey(input: {
12
+ projectRoot: string;
13
+ apiKey: string;
14
+ appendEnv?: typeof appendEnv;
15
+ }): Promise<AiGatewayApiKeyLocation>;
@@ -0,0 +1 @@
1
+ import{appendEnv}from"./append-env.js";import{join}from"node:path";const AI_GATEWAY_API_KEY_ENV_VAR=`AI_GATEWAY_API_KEY`,AI_GATEWAY_API_KEY_ENV_FILE=`.env.local`;async function writeAiGatewayApiKey(e){let t=join(e.projectRoot,AI_GATEWAY_API_KEY_ENV_FILE);return await(e.appendEnv??appendEnv)(t,{[AI_GATEWAY_API_KEY_ENV_VAR]:e.apiKey.trim()},{force:!0}),{envKey:AI_GATEWAY_API_KEY_ENV_VAR,envFile:AI_GATEWAY_API_KEY_ENV_FILE,envPath:t}}export{AI_GATEWAY_API_KEY_ENV_FILE,AI_GATEWAY_API_KEY_ENV_VAR,writeAiGatewayApiKey};
@@ -1 +1 @@
1
- import{appendEnv}from"../append-env.js";import{isProjectResolved}from"../project-resolution.js";import{requireProjectPath}from"../state.js";import{withNetworkSpinner}from"../vercel-project.js";import{runVercelEnvPull}from"../run-vercel-link.js";import{detectAiGatewayResolution}from"./detect-ai-gateway.js";import{join}from"node:path";import{createPromptCommandOutput}from"#setup/cli/index.js";const AI_GATEWAY_ENV_KEY=`AI_GATEWAY_API_KEY`,ENV_FILE_NAME=`.env.local`;function applyAiGatewayCredential(s){let c=s.deps??{appendEnv,runVercelEnvPull,detectAiGatewayResolution};async function writeAiGatewayApiKey(e,t){let n=join(e,ENV_FILE_NAME);await c.appendEnv(n,{[AI_GATEWAY_ENV_KEY]:t.trim()},{force:!0}),s.prompter.log.success(`Wrote ${AI_GATEWAY_ENV_KEY} to ${n}`)}return{id:`apply-ai-gateway-credential`,shouldRun(e){let{aiGateway:n,project:r}=e;return n.kind===`byok`||n.kind===`inherit`&&isProjectResolved(r)},async gather(){return null},async perform({state:e,signal:i}){let{prompter:a}=s,o=requireProjectPath(e),l=e.aiGateway,u=isProjectResolved(e.project);if(l.kind===`byop`)return{kind:`unresolved`};if(l.kind===`byok`)return await writeAiGatewayApiKey(o,l.apiGatewayKey),{kind:`api-key`,envFile:ENV_FILE_NAME};if(!u)return a.log.warning(`No Vercel project linked and no API key provided. The agent will not reach a model until you set ${AI_GATEWAY_ENV_KEY} in ${ENV_FILE_NAME} or link a project.`),{kind:`unresolved`};let d=createPromptCommandOutput(a.log),f=await withNetworkSpinner(a,`Pulling Vercel environment variables into .env.local...`,()=>c.runVercelEnvPull(o,d,i));return i?.throwIfAborted(),f||a.log.warning(`Linked the project, but pulling environment variables did not complete.`),c.detectAiGatewayResolution(o)},apply(e,t){return{...e,aiGatewayCredentials:t}}}}export{applyAiGatewayCredential};
1
+ import{appendEnv}from"../append-env.js";import{AI_GATEWAY_API_KEY_ENV_FILE,AI_GATEWAY_API_KEY_ENV_VAR,writeAiGatewayApiKey}from"../ai-gateway-api-key.js";import{isProjectResolved}from"../project-resolution.js";import{requireProjectPath}from"../state.js";import{withSpinner}from"../with-spinner.js";import{runVercelEnvPull}from"../run-vercel-link.js";import{detectAiGatewayResolution}from"./detect-ai-gateway.js";import{createPromptCommandOutput}from"#setup/cli/index.js";function applyAiGatewayCredential(a){let o=a.deps??{appendEnv,runVercelEnvPull,detectAiGatewayResolution};return{id:`apply-ai-gateway-credential`,shouldRun(e){let{aiGateway:t,project:n}=e;return t.kind===`byok`||t.kind===`inherit`&&isProjectResolved(n)},async gather(){return null},async perform({state:e,signal:r}){let{prompter:i}=a,s=requireProjectPath(e),c=e.aiGateway,l=isProjectResolved(e.project);if(c.kind===`byop`)return{kind:`unresolved`};if(c.kind===`byok`){let e=await writeAiGatewayApiKey({projectRoot:s,apiKey:c.apiGatewayKey,appendEnv:o.appendEnv});return a.prompter.log.success(`Wrote ${e.envKey} to ${e.envPath}`),{kind:`api-key`,envFile:e.envFile}}if(!l)return i.log.warning(`No Vercel project linked and no API key provided. The agent will not reach a model until you set ${AI_GATEWAY_API_KEY_ENV_VAR} in ${AI_GATEWAY_API_KEY_ENV_FILE} or link a project.`),{kind:`unresolved`};let u=createPromptCommandOutput(i.log),d=await withSpinner(i,`Pulling Vercel environment variables into .env.local...`,()=>o.runVercelEnvPull(s,u,r));return r?.throwIfAborted(),d||i.log.warning(`Linked the project, but pulling environment variables did not complete.`),o.detectAiGatewayResolution(s)},apply(e,t){return{...e,aiGatewayCredentials:t}}}}export{applyAiGatewayCredential};
@@ -1,2 +1,2 @@
1
- import{requireProjectPath}from"../state.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const ENV_FILE_CANDIDATES=[`.env.local`,`.env`];function readEnvValue(e,t){let n=e.trim();if(n.length===0||n.startsWith(`#`)||!n.startsWith(`${t}=`))return;let r=n.slice(t.length+1);if(r.length===0)return;let i=r.length>=2&&r.startsWith(`"`)&&r.endsWith(`"`)?r.slice(1,-1):r;return i.length===0?void 0:i}async function hasApiKeyInFile(e,t){let r;try{r=await readFile(e,`utf8`)}catch{return!1}for(let e of r.split(`
2
- `))if(readEnvValue(e,t)!==void 0)return!0;return!1}async function findEnvFileWithKey(e,n){for(let i of ENV_FILE_CANDIDATES)if(await hasApiKeyInFile(join(e,i),n))return i}async function detectAiGatewayResolution(e){let t=await findEnvFileWithKey(e,`AI_GATEWAY_API_KEY`);return t===void 0?{kind:`unresolved`}:{kind:`api-key`,envFile:t}}function detectAiGateway(){return{id:`detect-ai-gateway`,shouldRun(e){return e.projectPath.kind===`resolved`},async gather(){return null},async perform({state:t}){return detectAiGatewayResolution(requireProjectPath(t))},apply(e,t){return{...e,aiGatewayCredentials:t}}}}export{detectAiGateway,detectAiGatewayResolution,findEnvFileWithKey};
1
+ import{AI_GATEWAY_API_KEY_ENV_FILE,AI_GATEWAY_API_KEY_ENV_VAR}from"../ai-gateway-api-key.js";import{requireProjectPath}from"../state.js";import{join}from"node:path";import{readFile}from"node:fs/promises";const ENV_FILE_CANDIDATES=[AI_GATEWAY_API_KEY_ENV_FILE,`.env`];function readEnvValue(e,t){let n=e.trim();if(n.length===0||n.startsWith(`#`)||!n.startsWith(`${t}=`))return;let r=n.slice(t.length+1);if(r.length===0)return;let i=r.length>=2&&r.startsWith(`"`)&&r.endsWith(`"`)?r.slice(1,-1):r;return i.length===0?void 0:i}async function hasApiKeyInFile(e,t){let n;try{n=await readFile(e,`utf8`)}catch{return!1}for(let e of n.split(`
2
+ `))if(readEnvValue(e,t)!==void 0)return!0;return!1}async function findEnvFileWithKey(e,t){for(let n of ENV_FILE_CANDIDATES)if(await hasApiKeyInFile(join(e,n),t))return n}async function detectAiGatewayResolution(e){let n=await findEnvFileWithKey(e,AI_GATEWAY_API_KEY_ENV_VAR);return n===void 0?{kind:`unresolved`}:{kind:`api-key`,envFile:n}}function detectAiGateway(){return{id:`detect-ai-gateway`,shouldRun(e){return e.projectPath.kind===`resolved`},async gather(){return null},async perform({state:e}){return detectAiGatewayResolution(requireProjectPath(e))},apply(e,t){return{...e,aiGatewayCredentials:t}}}}export{detectAiGateway,detectAiGatewayResolution,findEnvFileWithKey};
@@ -1 +1 @@
1
- import{select,text}from"../ask.js";import{detectProjectResolution,isProjectResolved,mergeProjectResolution}from"../project-resolution.js";import{assertNewProjectNameAvailable,isVercelAuthenticated,pickNewProjectName,pickProject,pickTeam,requireAuth,resolveTeam,validateTeam,withNetworkSpinner}from"../vercel-project.js";import{pathExists}from"../path-exists.js";import{join,resolve}from"node:path";import{byokProviderEnvVar}from"#setup/scaffold/index.js";import{whimsyFor}from"#setup/cli/index.js";function vercelDemands(e){return{slack:e.channelSelection.includes(`slack`),connectSlugs:e.connectionSelection.filter(e=>e.entry.auth?.kind===`connect`).map(e=>e.slug)}}function connectClause(e){let t=e.length===1?`authenticates`:`authenticate`;return`${e.join(`, `)} ${t} through Vercel Connect`}function vercelRequirements(e){let t=[];return e.slack&&t.push(`Slack needs a public URL`),e.connectSlugs.length>0&&t.push(connectClause(e.connectSlugs)),t}function resolveProvisioning(l){let u=l.deps??{requireAuth,isVercelAuthenticated,detectProjectResolution,pathExists,validateTeam,resolveTeam,pickTeam,pickProject,pickNewProjectName,assertNewProjectNameAvailable},parent=()=>resolve(l.targetDirectory??process.cwd());async function detectAdoptableLink(e,t){if(e.projectPath.kind!==`resolved`)return;let n=e.projectPath.path;if(await u.pathExists(join(n,`.vercel`,`project.json`)))return withNetworkSpinner(l.prompter,whimsyFor(`project-detect`),async()=>{let e=await u.detectProjectResolution(n,{signal:t});if(!(!isProjectResolved(e)||!await u.isVercelAuthenticated(n,{signal:t})))return e})}async function plansFromFlags(e,t,n,r){if(t.skipVercel)return n.apiKey===void 0?{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:n.apiKey},modelWiring:`gateway`};if(t.team===void 0||t.team.length===0)throw Error(`Headless Vercel provisioning requires --team <slug> or --scope <slug> so the current CLI scope is not applied silently.`);await u.requireAuth(parent(),void 0,{signal:r}),await u.validateTeam(l.prompter,parent(),t.team,{signal:r});let i=await u.resolveTeam(parent(),t.team,{signal:r}),a=n.apiKey===void 0?{kind:`inherit`}:{kind:`byok`,apiGatewayKey:n.apiKey},o=t.project===void 0?{kind:`new`,project:e,team:i}:{kind:`existing`,project:t.project,team:i};return o.kind===`new`&&await u.assertNewProjectNameAvailable(parent(),i,o.project,{signal:r}),{vercelProject:o,aiGateway:a,modelWiring:`gateway`}}async function promptPlans(n,r){let i=l.prompter,a=n.agentName,o=l.adoptExistingLink===!1?void 0:await detectAdoptableLink(n,r);if(o!==void 0)return i.log.info(`This directory is already linked to a Vercel project, so your agent will run there — the AI Gateway authenticates through your Vercel login.`),{vercelProject:{kind:`none`},aiGateway:{kind:`inherit`},modelWiring:`gateway`,project:o};let s=vercelRequirements(vercelDemands(n)),c=!0;if(s.length>0?i.log.info(`${s.join(` and `)}, so your agent will run on Vercel.`):c=await l.asker.ask(select({key:`deploy`,message:`Where should your agent run?`,options:[{id:`vercel`,value:!0,label:`On Vercel`,hint:`AI Gateway, Durable Workflow, Sandbox, and more`},{id:`local`,value:!1,label:`Locally for now`,hint:`run with eve dev, deploy any time later`}],recommended:!0,required:!0})),c){await u.requireAuth(parent(),i,{signal:r});let t=await u.pickTeam(i,parent(),void 0,{signal:r}),n=[{value:`new`,label:`Create a new project`,hint:`Named ${a}`},{value:`link`,label:`Link an existing project`}],o=l.projectSelection!==`existing-only`&&l.prompter.selectEditable?await l.prompter.selectEditable({message:`Vercel project`,options:n,initialValue:`new`,editable:{value:`new`,defaultValue:a,formatHint:e=>`Named ${e}`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}}):void 0;if((l.projectSelection===`existing-only`?`link`:o?.value??await l.asker.ask(select({key:`vercel-project`,message:`Vercel project`,options:[{id:`new`,value:`new`,label:`Create a new project`,hint:`Named ${a}`},{id:`link`,value:`link`,label:`Link an existing project`}],recommended:`new`,required:!0})))===`new`){let e=o?.kind===`edited`?o.text:a;return{vercelProject:{kind:`new`,project:await u.pickNewProjectName(i,parent(),t,e,{signal:r}),team:t},aiGateway:{kind:`inherit`},modelWiring:`gateway`}}let s=await u.pickProject(i,parent(),t,{allowCreateWhenEmpty:l.projectSelection!==`existing-only`,signal:r});return{vercelProject:{kind:s.exists?`existing`:`new`,project:s.project,team:t},aiGateway:{kind:`inherit`},modelWiring:`gateway`}}return await l.asker.ask(select({key:`credential`,message:`How should your agent reach the model?`,options:[{id:`api-key`,value:`api-key`,label:`Use my own AI Gateway API key`,hint:`AI_GATEWAY_API_KEY`},{id:`local`,value:`local`,label:`Use my own provider API key`,hint:byokProviderEnvVar(n.modelId)}],recommended:`api-key`,required:!0}))===`api-key`?{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:await l.asker.ask(text({key:`gateway-api-key`,message:`Enter your AI_GATEWAY_API_KEY`,sensitive:!0,validate:e=>e.trim().length===0?`API key cannot be empty.`:null,required:!0}))},modelWiring:`gateway`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}}return{id:`resolve-provisioning`,async gather({state:e,signal:t}){if(l.mode.headless){let n=await plansFromFlags(e.agentName,l.mode.project,l.mode.aiGateway,t);if(n.vercelProject.kind===`none`){let t=vercelDemands(e);if(t.slack)throw Error(`Slack requires a Vercel project. Remove --skip-vercel to add Slack.`);if(t.connectSlugs.length>0)throw Error(`${connectClause(t.connectSlugs)}, which needs a Vercel project. Remove --skip-vercel to add ${t.connectSlugs.length===1?`it`:`them`}.`)}return n}return promptPlans(e,t)},async perform({input:e}){return e},apply(e,t){return{...e,vercelProject:t.vercelProject,aiGateway:t.aiGateway,modelWiring:t.modelWiring,project:t.project===void 0?e.project:mergeProjectResolution(e.project,t.project)}}}}export{resolveProvisioning};
1
+ import{select,text}from"../ask.js";import{detectProjectResolution,isProjectResolved,mergeProjectResolution}from"../project-resolution.js";import{withSpinner}from"../with-spinner.js";import{assertNewProjectNameAvailable,isVercelAuthenticated,pickNewProjectName,pickProject,pickTeam,requireAuth,resolveTeam,validateTeam}from"../vercel-project.js";import{pathExists}from"../path-exists.js";import{join,resolve}from"node:path";import{byokProviderEnvVar}from"#setup/scaffold/index.js";import{whimsyFor}from"#setup/cli/index.js";function vercelDemands(e){return{slack:e.channelSelection.includes(`slack`),connectSlugs:e.connectionSelection.filter(e=>e.entry.auth?.kind===`connect`).map(e=>e.slug)}}function connectClause(e){let t=e.length===1?`authenticates`:`authenticate`;return`${e.join(`, `)} ${t} through Vercel Connect`}function vercelRequirements(e){let t=[];return e.slack&&t.push(`Slack needs a public URL`),e.connectSlugs.length>0&&t.push(connectClause(e.connectSlugs)),t}function resolveProvisioning(l){let u=l.deps??{requireAuth,isVercelAuthenticated,detectProjectResolution,pathExists,validateTeam,resolveTeam,pickTeam,pickProject,pickNewProjectName,assertNewProjectNameAvailable},parent=()=>resolve(l.targetDirectory??process.cwd());async function detectAdoptableLink(e,t){if(e.projectPath.kind!==`resolved`)return;let n=e.projectPath.path;if(await u.pathExists(join(n,`.vercel`,`project.json`)))return withSpinner(l.prompter,whimsyFor(`project-detect`),async()=>{let e=await u.detectProjectResolution(n,{signal:t});if(!(!isProjectResolved(e)||!await u.isVercelAuthenticated(n,{signal:t})))return e})}async function plansFromFlags(e,t,n,r){if(t.skipVercel)return n.apiKey===void 0?{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:n.apiKey},modelWiring:`gateway`};if(t.team===void 0||t.team.length===0)throw Error(`Headless Vercel provisioning requires --team <slug> or --scope <slug> so the current CLI scope is not applied silently.`);await u.requireAuth(parent(),void 0,{signal:r}),await u.validateTeam(l.prompter,parent(),t.team,{signal:r});let i=await u.resolveTeam(parent(),t.team,{signal:r}),a=n.apiKey===void 0?{kind:`inherit`}:{kind:`byok`,apiGatewayKey:n.apiKey},o=t.project===void 0?{kind:`new`,project:e,team:i}:{kind:`existing`,project:t.project,team:i};return o.kind===`new`&&await u.assertNewProjectNameAvailable(parent(),i,o.project,{signal:r}),{vercelProject:o,aiGateway:a,modelWiring:`gateway`}}async function promptPlans(n,r){let i=l.prompter,a=n.agentName,o=l.adoptExistingLink===!1?void 0:await detectAdoptableLink(n,r);if(o!==void 0)return i.log.info(`This directory is already linked to a Vercel project, so your agent will run there — the AI Gateway authenticates through your Vercel login.`),{vercelProject:{kind:`none`},aiGateway:{kind:`inherit`},modelWiring:`gateway`,project:o};let s=vercelRequirements(vercelDemands(n)),c=!0;if(s.length>0?i.log.info(`${s.join(` and `)}, so your agent will run on Vercel.`):c=await l.asker.ask(select({key:`deploy`,message:`Where should your agent run?`,options:[{id:`vercel`,value:!0,label:`On Vercel`,hint:`AI Gateway, Durable Workflow, Sandbox, and more`},{id:`local`,value:!1,label:`Locally for now`,hint:`run with eve dev, deploy any time later`}],recommended:!0,required:!0})),c){await u.requireAuth(parent(),i,{signal:r});let t=await u.pickTeam(i,parent(),void 0,{signal:r}),n=[{value:`new`,label:`Create a new project`,hint:`Named ${a}`},{value:`link`,label:`Link an existing project`}],o=l.projectSelection!==`existing-only`&&l.prompter.selectEditable?await l.prompter.selectEditable({message:`Vercel project`,options:n,initialValue:`new`,editable:{value:`new`,defaultValue:a,formatHint:e=>`Named ${e}`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}}):void 0;if((l.projectSelection===`existing-only`?`link`:o?.value??await l.asker.ask(select({key:`vercel-project`,message:`Vercel project`,options:[{id:`new`,value:`new`,label:`Create a new project`,hint:`Named ${a}`},{id:`link`,value:`link`,label:`Link an existing project`}],recommended:`new`,required:!0})))===`new`){let e=o?.kind===`edited`?o.text:a;return{vercelProject:{kind:`new`,project:await u.pickNewProjectName(i,parent(),t,e,{signal:r}),team:t},aiGateway:{kind:`inherit`},modelWiring:`gateway`}}let s=await u.pickProject(i,parent(),t,{allowCreateWhenEmpty:l.projectSelection!==`existing-only`,signal:r});return{vercelProject:{kind:s.exists?`existing`:`new`,project:s.project,team:t},aiGateway:{kind:`inherit`},modelWiring:`gateway`}}return await l.asker.ask(select({key:`credential`,message:`How should your agent reach the model?`,options:[{id:`api-key`,value:`api-key`,label:`Use my own AI Gateway API key`,hint:`AI_GATEWAY_API_KEY`},{id:`local`,value:`local`,label:`Use my own provider API key`,hint:byokProviderEnvVar(n.modelId)}],recommended:`api-key`,required:!0}))===`api-key`?{vercelProject:{kind:`none`},aiGateway:{kind:`byok`,apiGatewayKey:await l.asker.ask(text({key:`gateway-api-key`,message:`Enter your AI_GATEWAY_API_KEY`,sensitive:!0,validate:e=>e.trim().length===0?`API key cannot be empty.`:null,required:!0}))},modelWiring:`gateway`}:{vercelProject:{kind:`none`},aiGateway:{kind:`byop`},modelWiring:`self`}}return{id:`resolve-provisioning`,async gather({state:e,signal:t}){if(l.mode.headless){let n=await plansFromFlags(e.agentName,l.mode.project,l.mode.aiGateway,t);if(n.vercelProject.kind===`none`){let t=vercelDemands(e);if(t.slack)throw Error(`Slack requires a Vercel project. Remove --skip-vercel to add Slack.`);if(t.connectSlugs.length>0)throw Error(`${connectClause(t.connectSlugs)}, which needs a Vercel project. Remove --skip-vercel to add ${t.connectSlugs.length===1?`it`:`them`}.`)}return n}return promptPlans(e,t)},async perform({input:e}){return e},apply(e,t){return{...e,vercelProject:t.vercelProject,aiGateway:t.aiGateway,modelWiring:t.modelWiring,project:t.project===void 0?e.project:mergeProjectResolution(e.project,t.project)}}}}export{resolveProvisioning};
@@ -1 +1 @@
1
- import{interactiveAsker}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{addChannels}from"../boxes/add-channels.js";import{getVercelAuthStatus}from"../vercel-project.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";import{toErrorMessage}from"#shared/errors.js";const SEE_IT_LIVE_MESSAGE=`See it live`;async function promptSeeItLive(e){try{return await e.select({message:SEE_IT_LIVE_MESSAGE,options:[{value:`deploy`,label:`Deploy and chat`},{value:`later`,label:`Later`}]})}catch(e){if(e instanceof WizardCancelledError)return`later`;throw e}}function channelAlreadyAdded(e,t){return t===`web`?e.webAppPresent:e.slackOwners.length>0}function appendChannel(e,t){return e.includes(t)?[...e]:[...e,t]}async function pickChannel(e,t,n,r){let i=channelListRows(t,n,r),a=!i.some(e=>e.value!==`done`&&e.completed!==!0&&e.disabled!==!0),s={message:CHANNELS_PROMPT_MESSAGE,options:i,hintLayout:`inline`};a&&(s.initialValue=`done`);try{return{kind:`picked`,value:await e.select(s)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}function channelLandedDuringSubflow(e,t,n){return!channelAlreadyAdded(e,n)&&channelAlreadyAdded(t,n)}function deployAndChatDetails(e){let t={};return e.slackChatUrl!==void 0&&(t.chatUrl=e.slackChatUrl),e.slackWorkspaceName!==void 0&&(t.workspaceName=e.slackWorkspaceName),t}function vercelChannelBlocker(e,t){if(e===`cli-missing`)return`Vercel CLI not found, see /vc`;if(e===`logged-out`)return`Log in to Vercel first, see /login`;if(e===`unavailable`)return`Couldn't reach Vercel, check your connection`;if(!t)return`Requires Vercel account, see /model`}function channelListRows(e,t,n){let r=[{value:`repl`,label:`Terminal UI`,completed:!0,focusHint:`Already installed`}];for(let i of SCAFFOLDABLE_CHANNELS){if(channelAlreadyAdded(e,i.kind)){r.push({value:i.kind,label:i.label,completed:!0,focusHint:`Already installed`});continue}let a=e.disabledChannelReasons[i.kind];if(a!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:a});continue}if(i.requiresVercelProject===!0){let e=vercelChannelBlocker(n,t);if(e!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:e,disabledReasonTone:`warning`});continue}}let o={value:i.kind,label:i.label};i.hint!==void 0&&(o.hint=i.hint),r.push(o)}return r.push({value:`done`,label:`Done`}),r}async function runChannelsFlow(o){let{appRoot:c,prompter:l,signal:u}=o,d={detectDeployment,inspectExistingChannelRegistrations,getVercelAuthStatus,...o.deps};async function checkProject(e){let t=l.log.spinner?.(`Checking the project…`);try{return await e()}finally{t?.stop()}}let[f,p,m]=await checkProject(()=>Promise.all([d.detectDeployment(c,{signal:u}),d.inspectExistingChannelRegistrations(c),d.getVercelAuthStatus(c,{signal:u})]));u?.throwIfAborted();let h=p,g={...createDefaultSetupState(),project:projectResolutionFromDeployment(f),projectPath:{kind:`resolved`,inPlace:!0,path:c}},_;for(;;){let t=await pickChannel(l,h,isProjectResolved(g.project),m);if(t.kind===`cancelled`){if(g.channels.length===0)return{kind:`cancelled`};break}let r=t.value;if(r===`done`)break;if(r===`repl`||channelAlreadyAdded(h,r))continue;let i=[selectChannels({asker:interactiveAsker(l),variant:`channels-add`,presetChannels:[r],validateSelection:e=>assertCanAddSelectedChannels(e,h)}),addChannels({asker:interactiveAsker(l),prompter:l,configureVercelServices:!0,deps:d.addChannels})],o;try{o=await runInteractive(i,g,prompterSink(l),{snapshot:snapshotSetupState,signal:u})}catch(e){let t=await checkProject(()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,t,r)){if(g={...g,channels:appendChannel(g.channels,r)},h=t,_=toErrorMessage(e),u?.aborted===!0)break;continue}throw e}if(o.kind===`done`){if(g=o.state,h=await checkProject(()=>d.inspectExistingChannelRegistrations(c)),u?.throwIfAborted(),r===`slack`&&g.slackbotAttached&&await promptSeeItLive(l)===`deploy`)return{kind:`deploy-and-chat`,addedChannels:g.channels,chat:deployAndChatDetails(g)}}else{let e=await checkProject(()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,e,r))return{kind:`done`,addedChannels:appendChannel(g.channels,r)};h=e}}return _===void 0?{kind:`done`,addedChannels:g.channels}:{kind:`failed`,addedChannels:g.channels,message:_}}export{SEE_IT_LIVE_MESSAGE,runChannelsFlow};
1
+ import{interactiveAsker}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{createDefaultSetupState,snapshotSetupState}from"../state.js";import{WizardCancelledError}from"../step.js";import{addChannels}from"../boxes/add-channels.js";import{withSpinner}from"../with-spinner.js";import{getVercelAuthStatus,vercelAuthBlockerReason}from"../vercel-project.js";import{CHANNELS_PROMPT_MESSAGE,selectChannels}from"../boxes/select-channels.js";import{assertCanAddSelectedChannels,inspectExistingChannelRegistrations}from"../channel-add-conflicts.js";import{runInteractive}from"../runner.js";import{prompterSink}from"./in-project.js";import{SCAFFOLDABLE_CHANNELS}from"#setup/scaffold/index.js";import{toErrorMessage}from"#shared/errors.js";const SEE_IT_LIVE_MESSAGE=`See it live`;async function promptSeeItLive(e){try{return await e.select({message:SEE_IT_LIVE_MESSAGE,options:[{value:`deploy`,label:`Deploy and chat`},{value:`later`,label:`Later`}]})}catch(e){if(e instanceof WizardCancelledError)return`later`;throw e}}function channelAlreadyAdded(e,t){return t===`web`?e.webAppPresent:e.slackOwners.length>0}function appendChannel(e,t){return e.includes(t)?[...e]:[...e,t]}async function pickChannel(e,t,n,r){let i=channelListRows(t,n,r),a=!i.some(e=>e.value!==`done`&&e.completed!==!0&&e.disabled!==!0),s={message:CHANNELS_PROMPT_MESSAGE,options:i,hintLayout:`inline`};a&&(s.initialValue=`done`);try{return{kind:`picked`,value:await e.select(s)}}catch(e){if(e instanceof WizardCancelledError)return{kind:`cancelled`};throw e}}function channelLandedDuringSubflow(e,t,n){return!channelAlreadyAdded(e,n)&&channelAlreadyAdded(t,n)}function deployAndChatDetails(e){let t={};return e.slackChatUrl!==void 0&&(t.chatUrl=e.slackChatUrl),e.slackWorkspaceName!==void 0&&(t.workspaceName=e.slackWorkspaceName),t}function vercelChannelBlocker(e,t){let n=vercelAuthBlockerReason(e);if(n!==void 0)return n;if(!t)return`Requires Vercel account, see /model`}function channelListRows(e,t,n){let r=[{value:`repl`,label:`Terminal UI`,completed:!0,focusHint:`Already installed`}];for(let i of SCAFFOLDABLE_CHANNELS){if(channelAlreadyAdded(e,i.kind)){r.push({value:i.kind,label:i.label,completed:!0,focusHint:`Already installed`});continue}let a=e.disabledChannelReasons[i.kind];if(a!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:a});continue}if(i.requiresVercelProject===!0){let e=vercelChannelBlocker(n,t);if(e!==void 0){r.push({value:i.kind,label:i.label,disabled:!0,disabledReason:e,disabledReasonTone:`warning`});continue}}let o={value:i.kind,label:i.label};i.hint!==void 0&&(o.hint=i.hint),r.push(o)}return r.push({value:`done`,label:`Done`}),r}async function runChannelsFlow(o){let{appRoot:c,prompter:l,signal:u}=o,d={detectDeployment,inspectExistingChannelRegistrations,getVercelAuthStatus,...o.deps},[f,p,m]=await withSpinner(l,`Checking the project…`,()=>Promise.all([d.detectDeployment(c,{signal:u}),d.inspectExistingChannelRegistrations(c),d.getVercelAuthStatus(c,{signal:u})]));u?.throwIfAborted();let h=p,g={...createDefaultSetupState(),project:projectResolutionFromDeployment(f),projectPath:{kind:`resolved`,inPlace:!0,path:c}},_;for(;;){let t=await pickChannel(l,h,isProjectResolved(g.project),m);if(t.kind===`cancelled`){if(g.channels.length===0)return{kind:`cancelled`};break}let r=t.value;if(r===`done`)break;if(r===`repl`||channelAlreadyAdded(h,r))continue;let i=[selectChannels({asker:interactiveAsker(l),variant:`channels-add`,presetChannels:[r],validateSelection:e=>assertCanAddSelectedChannels(e,h)}),addChannels({asker:interactiveAsker(l),prompter:l,configureVercelServices:!0,deps:d.addChannels})],o;try{o=await runInteractive(i,g,prompterSink(l),{snapshot:snapshotSetupState,signal:u})}catch(e){let t=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,t,r)){if(g={...g,channels:appendChannel(g.channels,r)},h=t,_=toErrorMessage(e),u?.aborted===!0)break;continue}throw e}if(o.kind===`done`){if(g=o.state,h=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c)),u?.throwIfAborted(),r===`slack`&&g.slackbotAttached&&await promptSeeItLive(l)===`deploy`)return{kind:`deploy-and-chat`,addedChannels:g.channels,chat:deployAndChatDetails(g)}}else{let e=await withSpinner(l,`Checking the project…`,()=>d.inspectExistingChannelRegistrations(c));if(channelLandedDuringSubflow(h,e,r))return{kind:`done`,addedChannels:appendChannel(g.channels,r)};h=e}}return _===void 0?{kind:`done`,addedChannels:g.channels}:{kind:`failed`,addedChannels:g.channels,message:_}}export{SEE_IT_LIVE_MESSAGE,runChannelsFlow};
@@ -1 +1 @@
1
- import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=r.log.spinner?.(`Checking the current Vercel link...`),c;try{let e=await o.detectDeployment(n,{signal:a});a?.throwIfAborted(),c=projectResolutionFromDeployment(e)}finally{s?.stop()}let l=isProjectResolved(c);if(!l&&!i)return{kind:`needs-link`};let u=inProjectSetupState(n,c,{deploymentPending:!0}),d=l?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],f=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(d,u,f,{snapshot:snapshotSetupState,signal:a})).project)};let p=await runInteractive(d,u,f,{snapshot:snapshotSetupState,signal:a});return p.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(p.state.project)}}export{runDeployFlow};
1
+ import{interactiveAsker,withAnswers}from"../ask.js";import{detectDeployment,isProjectResolved,projectResolutionFromDeployment}from"../project-resolution.js";import{snapshotSetupState}from"../state.js";import{withSpinner}from"../with-spinner.js";import{deployProject}from"../boxes/deploy-project.js";import{linkVercelProject}from"../boxes/link-project.js";import{resolveProvisioning}from"../boxes/resolve-provisioning.js";import{runHeadless,runInteractive}from"../runner.js";import{inProjectSetupState,prompterSink}from"./in-project.js";function productionUrlOf(e){return e.kind===`deployed`?e.productionUrl:void 0}async function runDeployFlow(t){let{appRoot:n,prompter:r,interactive:i,signal:a}=t,o={detectDeployment,...t.deps},s=await withSpinner(r,`Checking the current Vercel link...`,async()=>{let e=await o.detectDeployment(n,{signal:a});return a?.throwIfAborted(),projectResolutionFromDeployment(e)}),c=isProjectResolved(s);if(!c&&!i)return{kind:`needs-link`};let l=inProjectSetupState(n,s,{deploymentPending:!0}),u=c?[deployProject({prompter:r,headless:!i,deps:o.deployProject})]:[resolveProvisioning({asker:withAnswers({deploy:`vercel`})(interactiveAsker(r)),prompter:r,targetDirectory:n,mode:{headless:!1},deps:o.resolveProvisioning}),linkVercelProject({prompter:r,deps:o.linkProject}),deployProject({prompter:r,headless:!i,deps:o.deployProject})],d=prompterSink(r);if(!i)return{kind:`deployed`,productionUrl:productionUrlOf((await runHeadless(u,l,d,{snapshot:snapshotSetupState,signal:a})).project)};let f=await runInteractive(u,l,d,{snapshot:snapshotSetupState,signal:a});return f.kind===`cancelled`?{kind:`cancelled`}:{kind:`deployed`,productionUrl:productionUrlOf(f.state.project)}}export{runDeployFlow};