eve 0.12.0 → 0.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/dist/src/chunks/{use-eve-agent-D9ZhQhyV.js → use-eve-agent-DEm_Jg4k.js} +18 -4
- package/dist/src/chunks/{use-eve-agent-DFI0POM9.js → use-eve-agent-DsXOQMFZ.js} +18 -4
- package/dist/src/cli/commands/init.js +1 -1
- package/dist/src/cli/dev/tui/command-typeahead.d.ts +1 -1
- package/dist/src/cli/dev/tui/command-typeahead.js +1 -1
- package/dist/src/cli/dev/tui/prompt-command-handler.js +1 -1
- package/dist/src/cli/dev/tui/runner.d.ts +6 -2
- package/dist/src/cli/dev/tui/runner.js +1 -1
- package/dist/src/cli/dev/tui/setup-commands.d.ts +6 -2
- package/dist/src/cli/dev/tui/setup-commands.js +2 -2
- package/dist/src/cli/dev/tui/setup-issues.d.ts +16 -2
- package/dist/src/cli/dev/tui/setup-issues.js +1 -1
- package/dist/src/cli/dev/tui/setup-panel.js +2 -2
- package/dist/src/cli/dev/tui/target.d.ts +21 -0
- package/dist/src/cli/dev/tui/target.js +1 -0
- package/dist/src/cli/dev/tui/terminal-renderer.js +3 -3
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.d.ts +2 -0
- package/dist/src/cli/dev/tui/test/fake-setup-flow-renderer.js +1 -0
- package/dist/src/cli/dev/tui/theme.d.ts +3 -1
- package/dist/src/cli/dev/tui/theme.js +1 -1
- package/dist/src/cli/dev/tui/tui.d.ts +4 -14
- package/dist/src/cli/dev/tui/tui.js +1 -1
- package/dist/src/cli/dev/url.js +1 -1
- package/dist/src/cli/run.d.ts +0 -12
- package/dist/src/cli/run.js +2 -2
- package/dist/src/client/client.js +1 -1
- package/dist/src/client/index.d.ts +1 -1
- package/dist/src/client/open-stream.d.ts +2 -0
- package/dist/src/client/open-stream.js +1 -1
- package/dist/src/client/session.d.ts +2 -1
- package/dist/src/client/session.js +1 -1
- package/dist/src/client/types.d.ts +9 -0
- package/dist/src/compiled/.vendor-stamp.json +1 -1
- package/dist/src/compiled/@vercel/sandbox/_async-retry.d.ts +8 -0
- package/dist/src/compiled/@vercel/sandbox/_workflow-serde.d.ts +5 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/api-client.d.ts +1442 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/api-error.d.ts +29 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/base-client.d.ts +39 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/file-writer.d.ts +66 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/index.d.ts +2 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/validators.d.ts +878 -0
- package/dist/src/compiled/@vercel/sandbox/api-client/with-retry.d.ts +10 -0
- package/dist/src/compiled/@vercel/sandbox/auth/error.d.ts +15 -0
- package/dist/src/compiled/@vercel/sandbox/auth/file.d.ts +18 -0
- package/dist/src/compiled/@vercel/sandbox/auth/index.d.ts +6 -0
- package/dist/src/compiled/@vercel/sandbox/auth/oauth.d.ts +111 -0
- package/dist/src/compiled/@vercel/sandbox/auth/poll-for-token.d.ts +28 -0
- package/dist/src/compiled/@vercel/sandbox/auth/project.d.ts +40 -0
- package/dist/src/compiled/@vercel/sandbox/command.d.ts +290 -0
- package/dist/src/compiled/@vercel/sandbox/constants.d.ts +5 -0
- package/dist/src/compiled/@vercel/sandbox/filesystem.d.ts +258 -0
- package/dist/src/compiled/@vercel/sandbox/index.d.ts +10 -129
- package/dist/src/compiled/@vercel/sandbox/proxy.d.ts +55 -0
- package/dist/src/compiled/@vercel/sandbox/sandbox.d.ts +1058 -0
- package/dist/src/compiled/@vercel/sandbox/session.d.ts +432 -0
- package/dist/src/compiled/@vercel/sandbox/snapshot.d.ts +229 -0
- package/dist/src/compiled/@vercel/sandbox/utils/get-credentials.d.ts +21 -0
- package/dist/src/compiled/@vercel/sandbox/utils/paginator.d.ts +16 -0
- package/dist/src/compiled/@vercel/sandbox/utils/resolveSignal.d.ts +15 -0
- package/dist/src/compiled/@vercel/sandbox/utils/sandbox-snapshot.d.ts +11 -0
- package/dist/src/compiled/@vercel/sandbox/utils/types.d.ts +11 -0
- package/dist/src/compiled/chat/_workflow-serde.d.ts +3 -0
- package/dist/src/compiled/chat/index.d.ts +1 -1
- package/dist/src/evals/cli/eval-client.d.ts +12 -16
- package/dist/src/evals/cli/eval-client.js +1 -1
- package/dist/src/evals/cli/eval.js +1 -1
- package/dist/src/execution/sandbox/bindings/vercel-base-runtime.d.ts +3 -3
- package/dist/src/execution/sandbox/bindings/vercel-create-sdk.d.ts +8 -13
- package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +3 -3
- package/dist/src/execution/sandbox/bindings/vercel-lookup.d.ts +4 -5
- package/dist/src/execution/sandbox/bindings/vercel-read-stream.d.ts +5 -0
- package/dist/src/execution/sandbox/bindings/vercel-read-stream.js +1 -0
- package/dist/src/execution/sandbox/bindings/vercel-sdk-types.d.ts +6 -0
- package/dist/src/execution/sandbox/bindings/vercel-sdk-types.js +1 -0
- package/dist/src/execution/sandbox/bindings/vercel.d.ts +4 -4
- package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
- package/dist/src/harness/compaction.d.ts +2 -3
- package/dist/src/harness/compaction.js +1 -1
- package/dist/src/harness/tool-loop.js +1 -1
- package/dist/src/internal/application/package.js +1 -1
- package/dist/src/internal/nitro/host/dev-authored-source-watcher.js +1 -1
- package/dist/src/internal/nitro/host/start-development-server.js +2 -2
- package/dist/src/public/sandbox/vercel-sandbox.d.ts +12 -9
- package/dist/src/runtime/sessions/compiled-agent-cache.js +1 -1
- package/dist/src/services/dev-client/client-options.d.ts +9 -4
- package/dist/src/services/dev-client/client-options.js +1 -1
- package/dist/src/services/dev-client/credential-gate.d.ts +19 -0
- package/dist/src/services/dev-client/credential-gate.js +1 -0
- package/dist/src/services/dev-client/local-host.d.ts +4 -0
- package/dist/src/services/dev-client/local-host.js +1 -0
- package/dist/src/services/dev-client/request-headers.d.ts +38 -56
- package/dist/src/services/dev-client/request-headers.js +1 -1
- package/dist/src/services/dev-client/runtime-artifacts.js +1 -1
- package/dist/src/services/dev-client/vercel-auth-error.d.ts +2 -0
- package/dist/src/services/dev-client/vercel-auth-error.js +2 -2
- package/dist/src/services/dev-client.js +1 -1
- package/dist/src/setup/cli/option-row.d.ts +11 -5
- package/dist/src/setup/cli/option-row.js +1 -1
- package/dist/src/setup/cli/prompt-ui.d.ts +6 -6
- package/dist/src/setup/cli/prompt-ui.js +2 -2
- package/dist/src/setup/flows/model.d.ts +2 -0
- package/dist/src/setup/flows/model.js +1 -1
- package/dist/src/setup/project-resolution.d.ts +13 -0
- package/dist/src/setup/project-resolution.js +1 -1
- package/dist/src/setup/scaffold/create/project.js +1 -1
- package/dist/src/setup/scaffold/index.d.ts +1 -1
- package/dist/src/setup/scaffold/index.js +1 -1
- package/dist/src/setup/scaffold/update/channels.d.ts +8 -1
- package/dist/src/setup/scaffold/update/channels.js +2 -2
- package/dist/src/setup/vercel-deployment.d.ts +53 -0
- package/dist/src/setup/vercel-deployment.js +1 -0
- package/dist/src/setup/vercel-project.js +1 -1
- package/dist/src/setup/verified-remote-client.d.ts +23 -0
- package/dist/src/setup/verified-remote-client.js +1 -0
- package/dist/src/shared/sandbox-network-policy.d.ts +2 -2
- package/dist/src/svelte/index.js +1 -1
- package/dist/src/svelte/use-eve-agent.js +1 -1
- package/dist/src/vue/index.js +1 -1
- package/dist/src/vue/use-eve-agent.js +1 -1
- package/docs/evals/targets.mdx +7 -5
- package/docs/guides/client/overview.mdx +3 -0
- package/docs/guides/dev-tui.md +5 -5
- package/package.json +1 -1
- package/dist/src/harness/tool-result-pruning.d.ts +0 -8
- package/dist/src/harness/tool-result-pruning.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies
|
|
1
|
+
import{getPackageManagerStrategy}from"../../primitives/pm/index.js";import{pinnedNodeEngineMajor}from"../../node-engine.js";import{pathExists,writeTextFile}from"../files.js";import{patchPackageJson}from"./package-json.js";import{resolveVersionToken}from"../version-tokens.js";import{getSupportedModuleBaseName,matchesSupportedModuleBaseName}from"./module-files.js";import{WEB_APP_TEMPLATE_FILES,WEB_APP_TEMPLATE_PACKAGE_JSON}from"../create/web-template.js";import{DEFAULT_EVE_PACKAGE_CONTRACT,resolveEvePackageContract}from"../create/project.js";import{basename,join,resolve}from"node:path";import{readFile,readdir,writeFile}from"node:fs/promises";const SLACK_CHANNEL_DEFAULT_ROUTE=`/eve/v1/slack`,DEFAULT_SLACK_CONNECTOR_SLUG=`my-agent`,NEXT_PACKAGE_NAME=`next`,VERCEL_HOST_FRAMEWORK_PACKAGE_NAMES=[`@sveltejs/kit`,NEXT_PACKAGE_NAME,`nuxt`,`nuxt3`,`nuxt-edge`,`nuxt-nightly`],PACKAGE_DEPENDENCY_FIELDS=[`dependencies`,`devDependencies`],WEB_NEXT_CONFIG_PATH=`next.config.ts`,WEB_VERCEL_JSON_PATH=`vercel.json`,WEB_VERCEL_JSON_SCHEMA=`https://openapi.vercel.sh/vercel.json`,WEB_COMPETING_NEXT_CONFIG_PATHS=[`next.config.js`,`next.config.mjs`,WEB_NEXT_CONFIG_PATH,`next.config.mts`].filter(e=>e!==WEB_NEXT_CONFIG_PATH),WEB_DEFAULT_VERCEL_SERVICES={web:{entrypoint:`.`,framework:`nextjs`,routePrefix:`/`},eve:{buildCommand:`eve build`,entrypoint:`.`,framework:`eve`,routePrefix:`/_eve_internal/eve`}};function toSlackConnectorSlug(e){return e}function isJsonObject(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}async function readDependencyVersion(e,t){let n=JSON.parse(await readFile(e,`utf8`));if(!isJsonObject(n)||!isJsonObject(n.dependencies))return;let r=n.dependencies[t];return typeof r==`string`?r:void 0}function packageJsonHasDependency(e,t){for(let n of PACKAGE_DEPENDENCY_FIELDS){let r=e[n];if(isJsonObject(r)&&typeof r[t]==`string`)return!0}return!1}async function hasPackageDependency(e,t){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)&&packageJsonHasDependency(r,t)}async function hasAnyPackageDependency(e,t){if(!await pathExists(e))return!1;let r=JSON.parse(await readFile(e,`utf8`));return isJsonObject(r)?t.some(e=>packageJsonHasDependency(r,e)):!1}async function isNextJsProject(e){return hasPackageDependency(join(e,`package.json`),NEXT_PACKAGE_NAME)}async function hasVercelHostFramework(e){return hasAnyPackageDependency(join(e,`package.json`),VERCEL_HOST_FRAMEWORK_PACKAGE_NAMES)}async function ensurePackageDependency(e,t,r){return!await pathExists(e)||await readDependencyVersion(e,t)===r?[]:(await patchPackageJson(e,{dependencies:{[t]:r}}),[{path:e,dependencies:[t],devDependencies:[],scripts:[]}])}function resolveWebPackageVersions(e){return{evePackage:e?.evePackage??DEFAULT_EVE_PACKAGE_CONTRACT,aiPackageVersion:e?.aiPackageVersion??`7.0.0-beta.178`,nextPackageVersion:e?.nextPackageVersion??`16.2.6`,reactPackageVersion:e?.reactPackageVersion??`19.2.6`,reactDomPackageVersion:e?.reactDomPackageVersion??`19.2.6`,streamdownPackageVersion:e?.streamdownPackageVersion??`2.5.0`,zodPackageVersion:e?.zodPackageVersion??`4.4.3`,typesReactPackageVersion:e?.typesReactPackageVersion??`19.2.15`,typesReactDomPackageVersion:e?.typesReactDomPackageVersion??`19.2.3`}}function formatEveDependencySpecifier(e){return/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z-.]+)?$/.test(e)?`^${e}`:e}async function patchWebPackageJson(e,r){if(!await pathExists(e))return{mutations:[]};let o=resolveEvePackageContract(r.evePackage),s=pinnedNodeEngineMajor(o.nodeEngine),c={...WEB_APP_TEMPLATE_PACKAGE_JSON.dependencies,ai:resolveVersionToken(`aiPackageVersion`,r.aiPackageVersion),eve:formatEveDependencySpecifier(o.version),next:resolveVersionToken(`nextPackageVersion`,r.nextPackageVersion),react:resolveVersionToken(`reactPackageVersion`,r.reactPackageVersion),"react-dom":resolveVersionToken(`reactDomPackageVersion`,r.reactDomPackageVersion),streamdown:resolveVersionToken(`streamdownPackageVersion`,r.streamdownPackageVersion),zod:resolveVersionToken(`zodPackageVersion`,r.zodPackageVersion)},u={...WEB_APP_TEMPLATE_PACKAGE_JSON.devDependencies,"@types/node":s,"@types/react":resolveVersionToken(`typesReactPackageVersion`,r.typesReactPackageVersion),"@types/react-dom":resolveVersionToken(`typesReactDomPackageVersion`,r.typesReactDomPackageVersion),typescript:`6.0.3`},f=WEB_APP_TEMPLATE_PACKAGE_JSON.scripts,p=await patchPackageJson(e,{dependencies:c,devDependencies:u,scripts:f,nodeEngineRequirement:o.nodeEngine});return{mutations:[{path:e,dependencies:Object.keys(c),devDependencies:Object.keys(u),scripts:Object.keys(f)}],nodeEngineOverride:p.nodeEngineOverride}}function normalizeSlackConnectorSlug(e){return toSlackConnectorSlug((e.trim().replace(/^@/,``).split(`/`).at(-1)??``).toLowerCase().replace(/[^a-z0-9_-]+/g,`-`).replace(/^[^a-z0-9]+/,``).replace(/[^a-z0-9]+$/,``).slice(0,100).replace(/[^a-z0-9]+$/,``)||`my-agent`)}async function deriveSlackConnectorSlug(e,t){if(t!==void 0&&t.length>0&&t!==`.`)return normalizeSlackConnectorSlug(t);try{let t=await readFile(join(e,`package.json`),`utf8`),n=JSON.parse(t);if(typeof n.name==`string`&&n.name.length>0)return normalizeSlackConnectorSlug(n.name)}catch{}return normalizeSlackConnectorSlug(basename(resolve(e))||`my-agent`)}function buildSlackTemplate(e){if(!e.startsWith(`slack/`)||e.length===6)throw Error(`Invalid Slack connector UID "${e}".`);return`import { connectSlackCredentials } from "@vercel/connect/eve";
|
|
2
2
|
import { slackChannel } from "eve/channels/slack";
|
|
3
3
|
|
|
4
4
|
export default slackChannel({
|
|
5
5
|
credentials: connectSlackCredentials(${JSON.stringify(e)}),
|
|
6
6
|
});
|
|
7
|
-
`}function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}function withWebVercelServices(e){let t=JSON.parse(e);if(!isJsonObject(t))throw Error(`${WEB_VERCEL_JSON_PATH} must contain a JSON object.`);let n=t.experimentalServices;if(n!==void 0&&!isJsonObject(n))throw Error(`${WEB_VERCEL_JSON_PATH} experimentalServices must contain a JSON object.`);let r={...t,$schema:typeof t.$schema==`string`?t.$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:{...n,web:n?.web??WEB_DEFAULT_VERCEL_SERVICES.web,eve:n?.eve??WEB_DEFAULT_VERCEL_SERVICES.eve}};return JSON.stringify(t)===JSON.stringify(r)?e:`${JSON.stringify(r,null,2)}\n`}async function ensureWebVercelServices(e){if(!await pathExists(e))return await writeTextFile(e,`${JSON.stringify({$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:WEB_DEFAULT_VERCEL_SERVICES},null,2)}\n`,{force:!0}),`written`;let t=await readFile(e,`utf8`),i=withWebVercelServices(t);return i===t?`skipped`:(await writeFile(e,i,`utf8`),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let r of WEB_COMPETING_NEXT_CONFIG_PATHS){let i=join(e,r);await pathExists(i)&&t.push(i)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(t){let i=join(t.projectRoot,`package.json`),a=await pathExists(join(t.projectRoot,`app/page.tsx`));if(!t.force&&await isNextJsProject(t.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[]};let o=await patchWebPackageJson(i,resolveWebPackageVersions(t.webPackageVersions)),s=[],l=[],u=[],d=[],m=basename(resolve(t.projectRoot));if(t.configureVercelServices??!0){let e=join(t.projectRoot,WEB_VERCEL_JSON_PATH);await ensureWebVercelServices(e)===`written`?s.push(e):d.push(e)}let h=await getPackageManagerStrategy(t.packageManager??`pnpm`).applyProjectConfiguration(t.projectRoot);s.push(...h.filesWritten),d.push(...h.filesSkipped);for(let[e,i]of Object.entries(WEB_APP_TEMPLATE_FILES)){let a=join(t.projectRoot,e);if(e===`agent/channels/eve.ts`&&!t.force&&await pathExists(a)){d.push(a);continue}let o=await pathExists(a);await writeTextFile(a,renderWebAppTemplate(i,m),{force:!0}),s.push(a),o&&l.push(a)}u.push(...await findCompetingNextConfigFiles(t.projectRoot));let g={kind:`web`,action:a?`overwritten`:`created`,filesWritten:s,filesSkipped:d,packageJsonUpdated:o.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),o.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=o.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),i=await pathExists(t);if(!e.force&&i)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let o=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.2.2`),s=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,o),c=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);await writeTextFile(t,buildSlackTemplate(e.slackConnectorUid??`slack/${c}`),{force:e.force});let l={kind:`slack`,action:i?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:s,slackConnectorSlug:c};return i&&(l.filesOverwritten=[t]),l}async function listAuthoredChannels(e){let t=join(e,`agent/channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug};
|
|
7
|
+
`}function renderWebAppTemplate(e,t){return e.replaceAll(`__EVE_INIT_APP_NAME__`,t).replaceAll(`__EVE_INIT_WITH_EVE_OPTIONS__`,``)}function withWebVercelServices(e){let t=JSON.parse(e);if(!isJsonObject(t))throw Error(`${WEB_VERCEL_JSON_PATH} must contain a JSON object.`);let n=t.experimentalServices;if(n!==void 0&&!isJsonObject(n))throw Error(`${WEB_VERCEL_JSON_PATH} experimentalServices must contain a JSON object.`);let r={...t,$schema:typeof t.$schema==`string`?t.$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:{...n,web:n?.web??WEB_DEFAULT_VERCEL_SERVICES.web,eve:n?.eve??WEB_DEFAULT_VERCEL_SERVICES.eve}};return JSON.stringify(t)===JSON.stringify(r)?e:`${JSON.stringify(r,null,2)}\n`}async function ensureWebVercelServices(e){if(!await pathExists(e))return await writeTextFile(e,`${JSON.stringify({$schema:WEB_VERCEL_JSON_SCHEMA,experimentalServices:WEB_DEFAULT_VERCEL_SERVICES},null,2)}\n`,{force:!0}),`written`;let t=await readFile(e,`utf8`),i=withWebVercelServices(t);return i===t?`skipped`:(await writeFile(e,i,`utf8`),`written`)}async function findCompetingNextConfigFiles(e){let t=[];for(let r of WEB_COMPETING_NEXT_CONFIG_PATHS){let i=join(e,r);await pathExists(i)&&t.push(i)}return t}async function ensureChannel(e){switch(e.kind){case`slack`:return ensureSlackChannel({...e,kind:`slack`});case`web`:return ensureWebChannel({...e,kind:`web`})}}async function ensureWebChannel(t){let i=join(t.projectRoot,`package.json`),a=await pathExists(join(t.projectRoot,`app/page.tsx`));if(!t.force&&await isNextJsProject(t.projectRoot))return{kind:`web`,action:`skipped`,skipReason:`nextjs-project`,filesWritten:[],filesSkipped:[i],packageJsonUpdated:[]};let o=await patchWebPackageJson(i,resolveWebPackageVersions(t.webPackageVersions)),s=[],l=[],u=[],d=[],m=basename(resolve(t.projectRoot));if(t.configureVercelServices??!0){let e=join(t.projectRoot,WEB_VERCEL_JSON_PATH);await ensureWebVercelServices(e)===`written`?s.push(e):d.push(e)}let h=await getPackageManagerStrategy(t.packageManager??`pnpm`).applyProjectConfiguration(t.projectRoot);s.push(...h.filesWritten),d.push(...h.filesSkipped);for(let[e,i]of Object.entries(WEB_APP_TEMPLATE_FILES)){let a=join(t.projectRoot,e);if(e===`agent/channels/eve.ts`&&!t.force&&await pathExists(a)){d.push(a);continue}let o=await pathExists(a);await writeTextFile(a,renderWebAppTemplate(i,m),{force:!0}),s.push(a),o&&l.push(a)}u.push(...await findCompetingNextConfigFiles(t.projectRoot));let g={kind:`web`,action:a?`overwritten`:`created`,filesWritten:s,filesSkipped:d,packageJsonUpdated:o.mutations};return l.length>0&&(g.filesOverwritten=l),u.length>0&&(g.competingNextConfigFiles=u),o.nodeEngineOverride!==void 0&&(g.nodeEngineOverride=o.nodeEngineOverride),g}async function ensureSlackChannel(e){let t=join(e.projectRoot,`agent/channels/slack.ts`),i=await pathExists(t);if(!e.force&&i)return{kind:`slack`,action:`skipped`,filesWritten:[],filesSkipped:[t],packageJsonUpdated:[]};let o=resolveVersionToken(`connectPackageVersion`,e.connectPackageVersion??`0.2.2`),s=await ensurePackageDependency(join(e.projectRoot,`package.json`),`@vercel/connect`,o),c=e.slackConnectorSlug??await deriveSlackConnectorSlug(e.projectRoot);await writeTextFile(t,buildSlackTemplate(e.slackConnectorUid??`slack/${c}`),{force:e.force});let l={kind:`slack`,action:i?`overwritten`:`created`,filesWritten:[t],filesSkipped:[],packageJsonUpdated:s,slackConnectorSlug:c};return i&&(l.filesOverwritten=[t]),l}async function listAuthoredChannels(e){let t=join(e,`agent/channels`),n;try{n=await readdir(t,{withFileTypes:!0})}catch(e){if(e.code===`ENOENT`)return[];throw e}let r=[];for(let e of n){if(e.isFile()){let t=getSupportedModuleBaseName(e.name);t!==null&&r.push(t);continue}if(e.isDirectory())try{(await readdir(join(t,e.name))).some(e=>matchesSupportedModuleBaseName(e,`connection`))&&r.push(e.name)}catch{}}return r.sort()}export{DEFAULT_SLACK_CONNECTOR_SLUG,SLACK_CHANNEL_DEFAULT_ROUTE,deriveSlackConnectorSlug,ensureChannel,hasVercelHostFramework,isNextJsProject,listAuthoredChannels,normalizeSlackConnectorSlug};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { captureVercel, type VercelCaptureFailure } from "#setup/primitives/index.js";
|
|
2
|
+
import { readProjectLink, type VercelProjectReference } from "#setup/project-resolution.js";
|
|
3
|
+
declare const verifiedVercelTargetBrand: unique symbol;
|
|
4
|
+
export interface ResolvedVercelDeployment {
|
|
5
|
+
readonly provider: "vercel";
|
|
6
|
+
readonly ownerId: string;
|
|
7
|
+
readonly projectId: string;
|
|
8
|
+
readonly projectName: string;
|
|
9
|
+
readonly environment: string;
|
|
10
|
+
}
|
|
11
|
+
/** Proof that Vercel resolved one exact HTTPS origin under an authenticated scope. */
|
|
12
|
+
export interface VerifiedVercelTarget {
|
|
13
|
+
readonly [verifiedVercelTargetBrand]: true;
|
|
14
|
+
readonly origin: `https://${string}`;
|
|
15
|
+
readonly deployment: ResolvedVercelDeployment;
|
|
16
|
+
}
|
|
17
|
+
export type VercelDeploymentResolutionFailure = {
|
|
18
|
+
readonly cause: "vercel";
|
|
19
|
+
readonly failure: VercelCaptureFailure;
|
|
20
|
+
} | {
|
|
21
|
+
readonly cause: "invalid-json" | "invalid-shape";
|
|
22
|
+
readonly message: string;
|
|
23
|
+
};
|
|
24
|
+
export type VercelDeploymentResolution = {
|
|
25
|
+
readonly kind: "resolved";
|
|
26
|
+
readonly target: VerifiedVercelTarget;
|
|
27
|
+
} | {
|
|
28
|
+
readonly kind: "not-found";
|
|
29
|
+
} | {
|
|
30
|
+
readonly kind: "unscoped";
|
|
31
|
+
} | {
|
|
32
|
+
readonly kind: "project-mismatch";
|
|
33
|
+
readonly expectedProjectId: string;
|
|
34
|
+
readonly actualProjectId: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly kind: "cancelled";
|
|
37
|
+
} | {
|
|
38
|
+
readonly kind: "failed";
|
|
39
|
+
readonly failure: VercelDeploymentResolutionFailure;
|
|
40
|
+
};
|
|
41
|
+
export interface VercelDeploymentResolutionDeps {
|
|
42
|
+
readonly captureVercel: typeof captureVercel;
|
|
43
|
+
readonly readProjectLink: typeof readProjectLink;
|
|
44
|
+
}
|
|
45
|
+
/** Resolves a Vercel deployment URL to its project and target environment. */
|
|
46
|
+
export declare function resolveVercelDeployment(input: {
|
|
47
|
+
readonly workspaceRoot: string;
|
|
48
|
+
readonly host: string;
|
|
49
|
+
readonly source?: Pick<VercelProjectReference, "orgId" | "projectId">;
|
|
50
|
+
readonly signal?: AbortSignal;
|
|
51
|
+
readonly deps?: Partial<VercelDeploymentResolutionDeps>;
|
|
52
|
+
}): Promise<VercelDeploymentResolution>;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{number,object,string,union}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{projectReferenceFromEnvironment,readProjectLink}from"#setup/project-resolution.js";import{captureVercel}from"#setup/primitives/index.js";const VercelDeploymentSchema=object({projectId:string().min(1),name:string().min(1),target:string().nullable().optional(),customEnvironment:object({slug:string().min(1)}).nullable().optional()}),VercelApiErrorSchema=object({error:object({code:union([string(),number()]).optional(),message:string().optional()})}),verifiedVercelTargetBrand=Symbol(`VerifiedVercelTarget`),defaultDeps={captureVercel,readProjectLink};function isNotFoundApiFailure(e){if(e.code===404)return!0;try{let t=VercelApiErrorSchema.safeParse(JSON.parse(e.stdout));if(!t.success)return!1;let n=String(t.data.error.code??``).toLowerCase(),r=t.data.error.message?.toLowerCase()??``;return n===`404`||n===`not_found`||r.includes(`not found`)}catch{return!1}}function environmentForDeployment(e){return e.customEnvironment!==null&&e.customEnvironment!==void 0?e.customEnvironment.slug:e.target===`production`?`production`:`preview`}async function resolveVercelDeployment(e){let t={...defaultDeps,...e.deps},n=e.source??projectReferenceFromEnvironment(process.env)??await t.readProjectLink(e.workspaceRoot);if(n===void 0)return{kind:`unscoped`};let r=await t.captureVercel([`api`,`/v13/deployments/${encodeURIComponent(e.host)}`,`--scope`,n.orgId,`--raw`],{cwd:e.workspaceRoot,nonInteractive:!0,signal:e.signal,timeoutMs:1e4});if(!r.ok)return e.signal?.aborted===!0||r.failure.errno===`ABORT_ERR`?{kind:`cancelled`}:isNotFoundApiFailure(r.failure)?{kind:`not-found`}:{kind:`failed`,failure:{cause:`vercel`,failure:r.failure}};let i;try{i=JSON.parse(r.stdout)}catch{return{kind:`failed`,failure:{cause:`invalid-json`,message:`Vercel returned invalid deployment JSON.`}}}let a=VercelDeploymentSchema.safeParse(i);if(!a.success)return{kind:`failed`,failure:{cause:`invalid-shape`,message:`Vercel returned an invalid deployment response.`}};if(a.data.projectId!==n.projectId)return{kind:`project-mismatch`,expectedProjectId:n.projectId,actualProjectId:a.data.projectId};let o=`https://${new URL(`https://${e.host}`).host}`;return{kind:`resolved`,target:{[verifiedVercelTargetBrand]:!0,origin:o,deployment:{provider:`vercel`,ownerId:n.orgId,projectId:a.data.projectId,projectName:a.data.name,environment:environmentForDeployment(a.data)}}}}export{resolveVercelDeployment};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{boolean,object,record,string,unknown}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{captureVercel,runVercel}from"#setup/primitives/index.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{whimsyFor}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);const JsonObjectSchema=record(string(),unknown()),VercelTeamListEntrySchema=object({name:string(),slug:string(),current:boolean()}),VercelProjectListEntrySchema=object({name:string(),id:string()}),VercelProjectReferenceSchema=object({id:string(),name:string()}),VercelApiErrorSchema=object({error:object({code:string().optional(),message:string().optional()}).optional()});function unresolvedProject(){return{kind:`unresolved`}}async function withNetworkSpinner(e,t,n){let r=e.log.spinner?.(t);try{return await n()}finally{r?.stop()}}function projectIdFromResolution(e){return e.kind===`unresolved`?void 0:e.projectId}function parseJson(e,t){try{return JSON.parse(e)}catch{throw Error(`Could not parse ${t} JSON from Vercel CLI output.`)}}function parseVercelJsonList(e,t,n){let r=parseJson(e,t),i=JsonObjectSchema.safeParse(r);if(!i.success)throw Error(`Could not read ${t} from Vercel CLI JSON output.`);let a=i.data[t];if(!Array.isArray(a))throw Error(`Vercel CLI JSON output did not include ${t}.`);let o=[];for(let e of a){let t=n.safeParse(e);t.success&&o.push(t.data)}return o}function parseTeamList(e){return e===void 0?[]:parseVercelJsonList(e,`teams`,VercelTeamListEntrySchema)}async function listTeams(e,t={}){let n=await captureVercel([`teams`,`ls`,`--format`,`json`],{cwd:e,signal:t.signal});if(!n.ok)throw isForbiddenApiFailure(n.failure)&&requireVercelTeamAccess(n.failure),Error(`Could not list Vercel teams. ${n.failure.message}`);return parseTeamList(n.stdout)}function parseProjectList(e){return e===void 0?[]:parseVercelJsonList(e,`projects`,VercelProjectListEntrySchema)}async function listProjects(e,t,n={}){let r=await captureVercel([`project`,`ls`,`--format`,`json`,`--scope`,t],{cwd:e,signal:n.signal});if(!r.ok)throw isForbiddenApiFailure(r.failure)&&requireVercelTeamAccess(r.failure),Error(`Could not list Vercel projects in ${t}. ${r.failure.message}`);return parseProjectList(r.stdout)}function isNotFoundApiFailure(e){if(e.code===404)return!0;let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stderr}`.toLowerCase();return r.includes(`not_found`)||r.includes(`not found`)||r.includes(`404`)}function isConflictApiFailure(e){let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stdout} ${e.stderr}`.toLowerCase();return r.includes(`409`)||r.includes(`conflict`)||r.includes(`already exists`)}function isForbiddenApiFailure(e){let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stdout} ${e.stderr}`.toLowerCase();return r.includes(`403`)||r.includes(`forbidden`)||r.includes(`not_authorized`)||r.includes(`not authorized`)||r.includes(`sso`)||r.includes(`saml`)}function safeParseJson(e){try{return JSON.parse(e)}catch{return}}function parseProjectReference(e,t){let n=VercelProjectReferenceSchema.safeParse(parseJson(e,t));if(!n.success)throw Error(`Could not read Vercel project identity from ${t}.`);return n.data}async function resolveProjectByNameOrId(e,t,n,r={}){let i=await captureVercel([`api`,`/v9/projects/${encodeURIComponent(n)}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal});if(i.ok)return parseProjectReference(i.stdout,`project ${n}`);if(isNotFoundApiFailure(i.failure))return null;throw isForbiddenApiFailure(i.failure)&&requireVercelTeamAccess(i.failure),Error(`Could not resolve project "${n}" in ${t}. ${i.failure.message}`)}async function createProject(e,t,n,r,i){let a=
|
|
1
|
+
import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{boolean,object,record,string,unknown}from"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/schemas.js";import"../node_modules/.pnpm/zod@4.4.3/node_modules/zod/index.js";import{hasVercelHostFramework}from"#setup/scaffold/index.js";import{captureVercel,runVercel}from"#setup/primitives/index.js";import{HumanActionRequiredError}from"#setup/human-action.js";import{whimsyFor}from"#setup/cli/index.js";var import_picocolors=__toESM(require_picocolors(),1);const JsonObjectSchema=record(string(),unknown()),VercelTeamListEntrySchema=object({name:string(),slug:string(),current:boolean()}),VercelProjectListEntrySchema=object({name:string(),id:string()}),VercelProjectReferenceSchema=object({id:string(),name:string()}),VercelApiErrorSchema=object({error:object({code:string().optional(),message:string().optional()}).optional()});function unresolvedProject(){return{kind:`unresolved`}}async function withNetworkSpinner(e,t,n){let r=e.log.spinner?.(t);try{return await n()}finally{r?.stop()}}function projectIdFromResolution(e){return e.kind===`unresolved`?void 0:e.projectId}function parseJson(e,t){try{return JSON.parse(e)}catch{throw Error(`Could not parse ${t} JSON from Vercel CLI output.`)}}function parseVercelJsonList(e,t,n){let r=parseJson(e,t),i=JsonObjectSchema.safeParse(r);if(!i.success)throw Error(`Could not read ${t} from Vercel CLI JSON output.`);let a=i.data[t];if(!Array.isArray(a))throw Error(`Vercel CLI JSON output did not include ${t}.`);let o=[];for(let e of a){let t=n.safeParse(e);t.success&&o.push(t.data)}return o}function parseTeamList(e){return e===void 0?[]:parseVercelJsonList(e,`teams`,VercelTeamListEntrySchema)}async function listTeams(e,t={}){let n=await captureVercel([`teams`,`ls`,`--format`,`json`],{cwd:e,signal:t.signal});if(!n.ok)throw isForbiddenApiFailure(n.failure)&&requireVercelTeamAccess(n.failure),Error(`Could not list Vercel teams. ${n.failure.message}`);return parseTeamList(n.stdout)}function parseProjectList(e){return e===void 0?[]:parseVercelJsonList(e,`projects`,VercelProjectListEntrySchema)}async function listProjects(e,t,n={}){let r=await captureVercel([`project`,`ls`,`--format`,`json`,`--scope`,t],{cwd:e,signal:n.signal});if(!r.ok)throw isForbiddenApiFailure(r.failure)&&requireVercelTeamAccess(r.failure),Error(`Could not list Vercel projects in ${t}. ${r.failure.message}`);return parseProjectList(r.stdout)}function isNotFoundApiFailure(e){if(e.code===404)return!0;let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stderr}`.toLowerCase();return r.includes(`not_found`)||r.includes(`not found`)||r.includes(`404`)}function isConflictApiFailure(e){let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stdout} ${e.stderr}`.toLowerCase();return r.includes(`409`)||r.includes(`conflict`)||r.includes(`already exists`)}function isForbiddenApiFailure(e){let t=VercelApiErrorSchema.safeParse(safeParseJson(e.stdout)),n=t.success?t.data.error:void 0,r=`${n?.code??``} ${n?.message??``} ${e.stdout} ${e.stderr}`.toLowerCase();return r.includes(`403`)||r.includes(`forbidden`)||r.includes(`not_authorized`)||r.includes(`not authorized`)||r.includes(`sso`)||r.includes(`saml`)}function safeParseJson(e){try{return JSON.parse(e)}catch{return}}function parseProjectReference(e,t){let n=VercelProjectReferenceSchema.safeParse(parseJson(e,t));if(!n.success)throw Error(`Could not read Vercel project identity from ${t}.`);return n.data}async function resolveProjectByNameOrId(e,t,n,r={}){let i=await captureVercel([`api`,`/v9/projects/${encodeURIComponent(n)}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal});if(i.ok)return parseProjectReference(i.stdout,`project ${n}`);if(isNotFoundApiFailure(i.failure))return null;throw isForbiddenApiFailure(i.failure)&&requireVercelTeamAccess(i.failure),Error(`Could not resolve project "${n}" in ${t}. ${i.failure.message}`)}async function createProject(e,t,n,r,i){let a=[`api`,`/v10/projects`,`--scope`,t,`--method`,`POST`,`--raw-field`,`name=${n}`];await hasVercelHostFramework(e)||a.push(`--raw-field`,`framework=eve`),a.push(`--raw`);let o=await captureVercel(a,{cwd:e,onOutput:r,signal:i.signal});if(o.ok)return parseProjectReference(o.stdout,`created project ${n}`);throw isConflictApiFailure(o.failure)?Error(projectNameCollisionMessage(n,t)):(isForbiddenApiFailure(o.failure)&&requireVercelTeamAccess(o.failure),Error(`Could not create Vercel project "${n}" in ${t}. ${o.failure.message}`))}function projectNameCollisionMessage(e,t){return`Vercel project "${e}" already exists in ${t}. Pass --project ${e} to link it, or choose a different project name.`}async function assertNewProjectNameAvailable(e,t,n,r={}){if(await resolveProjectByNameOrId(e,t,n,r)!==null)throw Error(projectNameCollisionMessage(n,t))}function requireVercelLogin(e){let t=`Provisioning a Vercel project requires you to be logged in to Vercel.`,n=e?.stderr.trim();throw new HumanActionRequiredError({kind:`vercel-login`,command:`vercel login`,reason:e?`${t} The Vercel CLI check did not succeed: ${e.message}${n?` ${n}`:``}`:t})}function probeWhoami(e,t){return captureVercel([`whoami`],{cwd:e,signal:t.signal,timeoutMs:1e4})}function isLoggedOutFailure(e){let t=`${e.stdout} ${e.stderr}`.toLowerCase();return t.includes(`credentials`)||t.includes(`not authenticated`)||t.includes(`not logged in`)}function requireVercelAuth(e){if(e.errno===`ENOENT`)throw new HumanActionRequiredError({kind:`vercel-cli-missing`,command:`npm i -g vercel@latest`,reason:e.message});isLoggedOutFailure(e)&&requireVercelLogin(e);let t=e.stderr.trim();throw Error(`Couldn't verify your Vercel login: ${e.message}${t?` ${t}`:``}`)}async function getVercelAuthStatus(e,t={}){let n=await probeWhoami(e,t);return t.signal?.throwIfAborted(),n.ok?`authenticated`:n.failure.errno===`ENOENT`?`cli-missing`:isLoggedOutFailure(n.failure)?`logged-out`:`unavailable`}function requireVercelTeamAccess(e){let t=e.stderr.trim();throw new HumanActionRequiredError({kind:`vercel-forbidden`,command:`vercel login`,reason:`Vercel denied access to this scope.${t?` ${t}`:``} Re-authenticate (for example to complete a team's SSO) or switch to a team you can access.`})}async function requireAuth(e,t,n={}){let check=async()=>{let t=await probeWhoami(e,n);n.signal?.throwIfAborted(),t.ok||requireVercelAuth(t.failure)};if(t===void 0){await check();return}await withNetworkSpinner(t,whimsyFor(`auth`),check)}async function isVercelAuthenticated(e,t={}){return await getVercelAuthStatus(e,t)===`authenticated`}async function whoamiScope(e,t){let n=await probeWhoami(e,t);return t.signal?.throwIfAborted(),n.ok||requireVercelAuth(n.failure),n.stdout.trim()}async function resolveTeam(e,t,n={}){return t===void 0?(await listTeams(e,n)).find(e=>e.current)?.slug??await whoamiScope(e,n):t}async function validateTeam(e,t,n,r={}){if(n===void 0)return;let i=await listTeams(t,r);if(i.length>0&&!i.some(e=>e.slug===n))throw Error(`Team "${n}" was not found in \`vercel teams ls\`. Pass a valid team slug or omit --team.`)}async function pickTeam(e,t,n,r={}){if(n!==void 0)return await validateTeam(e,t,n,r),resolveTeam(t,n,r);let i=await withNetworkSpinner(e,whimsyFor(`teams`),()=>listTeams(t,r));return i.length<=1?i.find(e=>e.current)?.slug??await whoamiScope(t,r):e.select({message:`Select your team`,search:!0,placeholder:`type to search teams`,options:i.map(e=>({value:e.slug,label:e.current?`${e.name} (current)`:e.name})),initialValue:i.find(e=>e.current)?.slug})}async function pickProject(e,t,n,r={}){let i=await withNetworkSpinner(e,whimsyFor(`projects`,n),()=>listProjects(t,n,r));if(i.length===0){if(r.allowCreateWhenEmpty===!1)throw Error(`No existing Vercel projects found in ${n}. Create one in Vercel, then try again.`);return{project:await e.text({message:`No projects found in ${n}. Enter a project name to create`,validate:e=>e.trim().length===0?`Project name cannot be empty.`:void 0}),exists:!1}}return{project:await e.select({message:`Project to link`,search:!0,placeholder:`type to filter projects`,options:i.map(e=>({value:e.name,label:e.name}))}),exists:!0}}async function pickNewProjectName(e,t,n,r,i={}){let a=await withNetworkSpinner(e,whimsyFor(`project-name`,n),()=>resolveProjectByNameOrId(t,n,r.trim(),i)),o=r.trim();for(;a!==null;)o=(await e.text({message:`New project name`,defaultValue:`${o}-2`,notices:[{tone:`warning`,text:`${import_picocolors.default.yellow(`Project named`)} '${import_picocolors.default.blue(o)}' ${import_picocolors.default.yellow(`already exists in`)} '${import_picocolors.default.blue(n)}'`}],validate:e=>{if(e.trim().length===0)return`Project name cannot be empty.`}})).trim(),a=await resolveProjectByNameOrId(t,n,o,i);return o}async function linkProject(e,t,n,r,i={}){let a=[`--scope`,n.team],o;if(n.kind===`new`)o=await withNetworkSpinner(e,`Creating Vercel project "${n.project}" in ${n.team}...`,async()=>(await assertNewProjectNameAvailable(t,n.team,n.project,i),createProject(t,n.team,n.project,r,i)));else{let e=await resolveProjectByNameOrId(t,n.team,n.project,i);if(e===null)throw Error(`Vercel project "${n.project}" was not found in ${n.team}.`);o=e}return withNetworkSpinner(e,`Linking this directory to Vercel project "${o.name}"...`,()=>runVercel([`link`,`--project`,o.id,...a,`--yes`],{cwd:t,onOutput:r,nonInteractive:!0,signal:i.signal}))}export{assertNewProjectNameAvailable,getVercelAuthStatus,isVercelAuthenticated,linkProject,listProjects,listTeams,pickNewProjectName,pickProject,pickTeam,projectIdFromResolution,requireAuth,requireVercelAuth,requireVercelLogin,requireVercelTeamAccess,resolveProjectByNameOrId,resolveTeam,unresolvedProject,validateTeam,withNetworkSpinner};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ClientOptions } from "#client/index.js";
|
|
2
|
+
import { type DevelopmentOidcTokenFailure, resolveDevelopmentOidcToken } from "#services/dev-client/request-headers.js";
|
|
3
|
+
import { resolveVercelDeployment } from "./vercel-deployment.js";
|
|
4
|
+
/** Dependencies for verifying one remote client (injectable for tests). */
|
|
5
|
+
export interface VerifiedRemoteDevelopmentClientDeps {
|
|
6
|
+
readonly resolveVercelDeployment: typeof resolveVercelDeployment;
|
|
7
|
+
readonly resolveDevelopmentOidcToken: typeof resolveDevelopmentOidcToken;
|
|
8
|
+
}
|
|
9
|
+
/** A verified remote client's options plus a reader for its latest OIDC failure. */
|
|
10
|
+
export interface VerifiedRemoteDevelopmentClient {
|
|
11
|
+
readonly options: ClientOptions;
|
|
12
|
+
/** OIDC failure from the most recent request, or `undefined` while healthy. */
|
|
13
|
+
readonly lastOidcTokenFailure: () => DevelopmentOidcTokenFailure | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Resolves a remote client that emits ambient Vercel credentials only after
|
|
17
|
+
* exact origin proof, plus a reader for the latest OIDC token failure.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveVerifiedRemoteDevelopmentClient(input: {
|
|
20
|
+
readonly serverUrl: string;
|
|
21
|
+
readonly workspaceRoot: string;
|
|
22
|
+
readonly deps?: Partial<VerifiedRemoteDevelopmentClientDeps>;
|
|
23
|
+
}): Promise<VerifiedRemoteDevelopmentClient>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{resolveVercelDeployment}from"./vercel-deployment.js";import{resolveRemoteDevelopmentClientOptions}from"#services/dev-client/client-options.js";import{createDevelopmentCredentialGate}from"#services/dev-client/credential-gate.js";import{resolveDevelopmentOidcToken}from"#services/dev-client/request-headers.js";const defaultDeps={resolveVercelDeployment,resolveDevelopmentOidcToken};async function resolveVerifiedRemoteDevelopmentClient(e){let n={...defaultDeps,...e.deps},r=createDevelopmentCredentialGate(e.serverUrl),i=await n.resolveVercelDeployment({workspaceRoot:e.workspaceRoot,host:new URL(e.serverUrl).host});if(i.kind===`resolved`){let{ownerId:e,projectId:t}=i.target.deployment;r.authorize({target:i.target,resolveToken:()=>n.resolveDevelopmentOidcToken({ownerId:e,projectId:t})})}return{options:resolveRemoteDevelopmentClientOptions({serverUrl:e.serverUrl,credentials:r}),lastOidcTokenFailure:r.lastTokenFailure}}export{resolveVerifiedRemoteDevelopmentClient};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type * as Vercel from "#compiled/@vercel/sandbox/index.js";
|
|
2
2
|
/**
|
|
3
3
|
* Firewall network policy applied to a live sandbox session.
|
|
4
4
|
*
|
|
@@ -22,4 +22,4 @@ import type { NetworkPolicy } from "#compiled/@vercel/sandbox/index.js";
|
|
|
22
22
|
* entirely (its network policy is fixed at sandbox creation and it runs
|
|
23
23
|
* no binaries to govern).
|
|
24
24
|
*/
|
|
25
|
-
export type SandboxNetworkPolicy = NetworkPolicy;
|
|
25
|
+
export type SandboxNetworkPolicy = Vercel.NetworkPolicy;
|
package/dist/src/svelte/index.js
CHANGED
package/dist/src/vue/index.js
CHANGED
package/docs/evals/targets.mdx
CHANGED
|
@@ -30,12 +30,14 @@ Sessions attached this way are full `EveEvalSession`s: you can keep driving them
|
|
|
30
30
|
|
|
31
31
|
## Authentication
|
|
32
32
|
|
|
33
|
-
Local targets send no auth: `eve eval` owns the dev server it boots.
|
|
33
|
+
Local targets send no auth: `eve eval` owns the dev server it boots. For a remote `--url`, eve gets the expected Vercel owner and project from `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` when both are set. Otherwise it reads `.vercel/project.json`. Eve then asks Vercel to resolve the exact HTTPS origin and sends ambient credentials only when the project IDs match. An arbitrary URL remains anonymous.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
- `
|
|
35
|
+
After verification, eve sends the available Vercel credentials:
|
|
36
|
+
|
|
37
|
+
- The resolved OIDC token as both the bearer and Vercel trusted-IDP header.
|
|
38
|
+
- `VERCEL_AUTOMATION_BYPASS_SECRET`, when set, as the Protection Bypass for Automation header.
|
|
39
|
+
|
|
40
|
+
`EVE_EVAL_AUTH_TOKEN` is an explicit bearer override for targets whose auth is not Vercel OIDC. Credential-bearing clients do not follow redirects, so those headers cannot be forwarded to another origin.
|
|
39
41
|
|
|
40
42
|
`t.target.fetch(path, init)` carries these same credentials, so channel and webhook ingress you exercise through it authenticates the same way the session protocol does.
|
|
41
43
|
|
|
@@ -67,9 +67,12 @@ const client = new Client({
|
|
|
67
67
|
headers: async () => ({
|
|
68
68
|
"x-vercel-protection-bypass": await getBypassToken(),
|
|
69
69
|
}),
|
|
70
|
+
redirect: "manual",
|
|
70
71
|
});
|
|
71
72
|
```
|
|
72
73
|
|
|
74
|
+
Set `redirect` to `"manual"` or `"error"` on credential-bearing clients so fetch cannot forward custom authorization headers to another origin. The policy applies to inspection requests, custom fetches, session creation, and event streams.
|
|
75
|
+
|
|
73
76
|
Per-request headers can be attached to an individual turn:
|
|
74
77
|
|
|
75
78
|
```ts
|
package/docs/guides/dev-tui.md
CHANGED
|
@@ -16,7 +16,7 @@ On startup the TUI prints a brand line with your agent's name, plus a rotating t
|
|
|
16
16
|
Use /channels to add more ways to reach your agent.
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
If agent discovery reported problems, an error and warning count renders between the two lines. Instructions, tools, skills, and subagents are one `eve info` away, and `/help` lists every command. The TUI also runs a startup check.
|
|
19
|
+
If agent discovery reported problems, an error and warning count renders between the two lines. Instructions, tools, skills, and subagents are one `eve info` away, and `/help` lists every command. The TUI also runs a startup check. When the runtime confirms that no model provider is configured, it opens the `/model` provider questions before the first prompt. When the available evidence cannot confirm that state, missing setup remains visible as an attention line, with each command's outcome hanging under it on a `⎿` connector.
|
|
20
20
|
|
|
21
21
|
## Reading the transcript
|
|
22
22
|
|
|
@@ -30,7 +30,7 @@ Errors render compactly with docs links highlighted. A code bug escaping your ag
|
|
|
30
30
|
|
|
31
31
|
## Slash commands
|
|
32
32
|
|
|
33
|
-
Each command echoes as an invocation line, asks through a bordered panel that takes the input area's place (one question at a time, separate from the chat transcript), and finishes with a one-line `⎿` result. Loading states stay on the ephemeral status line instead of piling into the transcript.
|
|
33
|
+
Each command echoes as an invocation line, asks through a bordered panel that takes the input area's place (one question at a time, separate from the chat transcript), and finishes with a one-line `⎿` result. Loading states stay on the ephemeral status line instead of piling into the transcript. Setup menus render the selected option with a filled arrow and an inverse label padded by one space on each side. The label is blue normally and yellow for warning rows.
|
|
34
34
|
|
|
35
35
|
| Command | Does |
|
|
36
36
|
| ----------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -46,9 +46,9 @@ Each command echoes as an invocation line, asks through a bordered panel that ta
|
|
|
46
46
|
|
|
47
47
|
### Configure the model and provider
|
|
48
48
|
|
|
49
|
-
Bare `/model` opens the configure menu. "Change model" runs the same searchable model picker setup uses (the Vercel AI Gateway catalog, pre-selected on the model the runtime is serving). A model change is written into your agent's authored source, and the command reports success only after eve confirms the new id. `/model <provider/model-id>` applies one directly, skipping the menu.
|
|
49
|
+
Bare `/model` opens the configure menu. When no provider is configured, it opens the provider questions directly; Esc returns to the configure menu. "Change model" runs the same searchable model picker setup uses (the Vercel AI Gateway catalog, pre-selected on the model the runtime is serving). A model change is written into your agent's authored source, and the command reports success only after eve confirms the new id. `/model <provider/model-id>` applies one directly, skipping the menu.
|
|
50
50
|
|
|
51
|
-
The provider row opens the provider questions: which model provider to use, and how to connect. Picking something other than Vercel AI Gateway shows wiring instructions for your own provider and stops there, leaving any existing setup untouched. For Vercel AI Gateway, you either paste your own `AI_GATEWAY_API_KEY` (saved straight to `.env.local`) or connect via a project. Connecting via a project asks for a Vercel team, opens that team's existing-project list (picking again re-links), then pulls the project's environment so an AI Gateway credential lands in `.env.local`. The dev
|
|
51
|
+
The provider row opens the provider questions: which model provider to use, and how to connect. Picking something other than Vercel AI Gateway shows wiring instructions for your own provider and stops there, leaving any existing setup untouched. For Vercel AI Gateway, you either paste your own `AI_GATEWAY_API_KEY` (saved straight to `.env.local`) or connect via a project. Connecting via a project asks for a Vercel team, opens that team's existing-project list (picking again re-links), then pulls the project's environment so an AI Gateway credential lands in `.env.local`. The dev TUI reloads env files, re-reads the runtime's model endpoint, and clears the setup warning automatically; no restart is needed.
|
|
52
52
|
|
|
53
53
|
The provider row demands attention (a bold yellow "Configure provider" with "Required to enable the agent") until a link or gateway credential is detected, then names the connection afterward (for example "AI Gateway (Linked to my-project in my-team)"). Each action's latest outcome stays visible beneath the menu (for example "✓ Model changed to openai/gpt-5.5"). When a turn fails because AI Gateway authentication is missing or stale, the error points you at `/model` directly.
|
|
54
54
|
|
|
@@ -119,7 +119,7 @@ Pass a URL and the TUI talks to a running deployment instead of starting a local
|
|
|
119
119
|
eve dev https://<your-app>
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
The bare URL is shorthand for `--url
|
|
122
|
+
The bare URL is shorthand for `--url`; `--host`, `--port`, and `--no-ui` cannot be combined with a remote target. Eve gets the expected Vercel owner and project from `VERCEL_ORG_ID` and `VERCEL_PROJECT_ID` when both are set, or from the current directory's Vercel link otherwise. It verifies the exact deployment origin before attaching a freshly resolved project-scoped OIDC token or `VERCEL_AUTOMATION_BYPASS_SECRET`. Unverified URLs remain anonymous, and credential-bearing requests do not follow redirects. See [Deployment](./deployment) for the smoke-test flow.
|
|
123
123
|
|
|
124
124
|
## What to read next
|
|
125
125
|
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ModelMessage } from "ai";
|
|
2
|
-
/**
|
|
3
|
-
* Reactively prunes old tool-result content from conversation history.
|
|
4
|
-
*
|
|
5
|
-
* Recent results inside {@link PRUNE_PROTECT_TOKENS} are preserved.
|
|
6
|
-
* Older results are replaced with {@link PRUNED_PLACEHOLDER}.
|
|
7
|
-
*/
|
|
8
|
-
export declare function pruneToolResults(messages: readonly ModelMessage[]): ModelMessage[];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{estimateTokens}from"#harness/compaction.js";function pruneToolResults(e){let t=collectToolResultLocations(e);if(t.length===0)return e;let n=0,r=0,i=new Set;for(let e of t)n<4e4?n+=e.tokens:(i.add(e.key),r+=e.tokens);return r<2e4?e:e.map((e,t)=>{if(e.role!==`tool`||!Array.isArray(e.content))return e;let n=!1,r=e.content.map((e,r)=>{let a=`${t}:${r}`;return i.has(a)?(n=!0,{...e,output:createPrunedToolResultOutput(`[Tool result pruned to save context. Call the tool again if needed.]`)}):e});return n?{...e,content:r}:e})}function collectToolResultLocations(t){let n=[];for(let r=t.length-1;r>=0;r--){let i=t[r];if(!(i===void 0||i.role!==`tool`||!Array.isArray(i.content)))for(let t=i.content.length-1;t>=0;t--){let a=i.content[t];a?.type===`tool-result`&&n.push({key:`${r}:${t}`,tokens:estimateTokens(a)})}}return n}function createPrunedToolResultOutput(e){return{type:`text`,value:e}}export{pruneToolResults};
|