UNPKG

eve

Version:

Filesystem-first framework for durable backend AI agents that run anywhere.

1 lines 9.72 kB
import{__toESM}from"../_virtual/_rolldown/runtime.js";import{require_picocolors}from"../node_modules/.pnpm/picocolors@1.1.1/node_modules/picocolors/picocolors.js";import{object,string}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{assertNoLegacyProjectLinkDirectory,readProjectLink}from"./project-resolution.js";import{withSpinner}from"./with-spinner.js";import{isForbiddenApiFailure,isNotFoundApiFailure,normalizeVercelApiResult}from"./vercel-api-failure.js";import{VERCEL_PROJECT_REQUEST_TIMEOUT_MS,listRecentProjects,listTeams,parseVercelJson,rankProjectSearchResults,requireVercelTeamAccess,searchProjects}from"./vercel-project-api.js";import{ensureCreatedProjectFramework}from"./vercel-project-framework.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 VercelProjectReferenceSchema=object({id:string().min(1),name:string().min(1)});function unresolvedProject(){return{kind:`unresolved`}}function projectIdFromResolution(e){return e.kind===`unresolved`?void 0:e.projectId}function parseProjectReference(e,t){let n=VercelProjectReferenceSchema.safeParse(parseVercelJson(e,t));if(!n.success)throw Error(`Could not read Vercel project identity from ${t}.`);return{projectId:n.data.id,projectName:n.data.name}}async function resolveProjectByNameOrId(e,t,n,r={}){let i=normalizeVercelApiResult(await captureVercel([`api`,`/v9/projects/${encodeURIComponent(n)}`,`--scope`,t,`--raw`],{cwd:e,signal:r.signal,timeoutMs:VERCEL_PROJECT_REQUEST_TIMEOUT_MS}));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}`)}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}`:``}`)}function vercelAuthBlockerReason(e){switch(e){case`authenticated`:return;case`cli-missing`:return`Vercel CLI not found, see /vc:install`;case`logged-out`:return`Log in to Vercel first, see /vc:login`;case`unavailable`:return`Couldn't reach Vercel, check your connection`;default:return e}}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`}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 withSpinner(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 withSpinner(e,whimsyFor(`teams`),()=>listTeams(t,r));if(i.length<=1)return i.find(e=>e.current)?.slug??await whoamiScope(t,r);let a=i.find(e=>e.current);return e.select({message:r.selectMessage?.(a?.name??await whoamiScope(t,r))??`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:a?.slug})}const SEARCH_PROJECT_PREFIX=`\0search-project:`;function searchMoreProjectsValue(e){return`search-more-projects:${e.next}:${e.query}`}function prioritizeSearchResults(e,t){let n=new Map(t.map(e=>[e.id,e]));for(let t of e)n.has(t.id)||n.set(t.id,t);return[...n.values()]}async function findProjectSearchResults(e,t,n,r,i){let a=n.trim();if(a.length===0)throw Error(`Project search query cannot be empty.`);if(i===void 0){let n=await resolveProjectByNameOrId(e,t,a,r);if(n!==null)return{projects:[{id:n.projectId,name:n.projectName}]}}return await searchProjects(e,t,a,{...r,next:i})}async function findSuggestedProject(e,t,n,r,i){let a=r.find(e=>e.name===n);if(a!==void 0)return a;try{return rankProjectSearchResults((await findProjectSearchResults(e,t,n,i)).projects,n)[0]}catch{i.signal?.throwIfAborted();return}}async function pickProject(e,t,n,r={}){let i=r.suggestedName?.trim(),a=await withSpinner(e,whimsyFor(`projects`,n),async()=>{let e=await listRecentProjects(t,n,r);return{recents:e,suggested:i===void 0||i.length===0?void 0:await findSuggestedProject(t,n,i,e,r)}}),o=a.suggested?.id,s=a.suggested===void 0?a.recents:prioritizeSearchResults(a.recents,[a.suggested]),c=[],l,projectOptions=()=>{let e=s.map(e=>{let t={value:e.id,label:e.name};return e.id===o&&(t.hint=`suggested`),t});return l!==void 0&&e.push({value:searchMoreProjectsValue(l),label:`Show more matches for '${l.query}'`}),e},applySearchResults=(e,t,n)=>{c=rankProjectSearchResults([...n?c:[],...t.projects],e),s=prioritizeSearchResults(s,c),l=t.next===void 0?void 0:{query:e.trim(),next:t.next}};if(s.length===0){if(r.allowCreateWhenEmpty===!1)throw Error(`No existing Vercel projects found in ${n}. Create one in Vercel, then try again.`);return{kind:`new`,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}),team:n}}for(;;){let i=await e.select({message:`Project to link`,search:!0,placeholder:`type to filter projects`,searchAction:{label:e=>`Search for '${e}'`,value:e=>`${SEARCH_PROJECT_PREFIX}${e}`,load:async e=>(applySearchResults(e,await findProjectSearchResults(t,n,e,{signal:r.signal}),!1),projectOptions())},options:projectOptions(),initialValue:o??s[0]?.id}),a=l;if(a!==void 0&&i===searchMoreProjectsValue(a)){let i=await withSpinner(e,`Searching ${n} for "${a.query}"...`,()=>findProjectSearchResults(t,n,a.query,{signal:r.signal},a.next));applySearchResults(a.query,i,!0);continue}let c=i.startsWith(SEARCH_PROJECT_PREFIX)?i.slice(16):void 0;if(c===void 0){let e=s.find(e=>e.id===i);if(e===void 0)throw Error(`Selected Vercel project is not available.`);return{kind:`existing`,project:{projectId:e.id,projectName:e.name},team:n}}let u=await withSpinner(e,`Searching ${n} for "${c}"...`,()=>findProjectSearchResults(t,n,c,{signal:r.signal}));if(applySearchResults(c,u,!1),u.projects.length===0&&u.next===void 0){e.note(`No projects matched "${c}" in ${n}.`);continue}}}async function pickNewProjectName(e,t,n,r,i={}){let a=await withSpinner(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,o={}){await assertNoLegacyProjectLinkDirectory(t);let s=[`--scope`,n.team];if(n.kind===`new`){if(!await withSpinner(e,`Creating Vercel project "${n.project}" in ${n.team}...`,async()=>(await assertNewProjectNameAvailable(t,n.team,n.project,o),runVercel([`link`,`--project`,n.project,...s,`--yes`],{cwd:t,onOutput:r,nonInteractive:!0,signal:o.signal}))))return;let i=await readProjectLink(t);return i===void 0?void 0:(await ensureCreatedProjectFramework(e,t,n.team,i.projectId,r,o),{projectId:i.projectId,projectName:i.projectName??n.project})}let c=n.project;return await withSpinner(e,`Linking this directory to Vercel project "${c.projectName}"...`,()=>runVercel([`link`,`--project`,c.projectId,...s,`--yes`],{cwd:t,onOutput:r,nonInteractive:!0,signal:o.signal}))?c:void 0}export{assertNewProjectNameAvailable,getVercelAuthStatus,isVercelAuthenticated,linkProject,pickNewProjectName,pickProject,pickTeam,projectIdFromResolution,requireAuth,requireVercelAuth,requireVercelLogin,resolveProjectByNameOrId,resolveTeam,unresolvedProject,validateTeam,vercelAuthBlockerReason};