UNPKG

eve

Version:

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

2 lines 3.39 kB
import{InitTargetError}from"./init-telemetry.js";import{readdir,stat}from"node:fs/promises";import{basename,isAbsolute,relative,resolve,sep}from"node:path";import{PROJECT_NAME_ERROR,parseProjectName}from"#setup/project-name.js";import{classifyAgentRootEntry,getDirectoryEntryType}from"#discover/filesystem.js";const ENVIRONMENT_ONLY_ENTRIES=new Set([`.DS_Store`,`.editorconfig`,`.gitattributes`,`.gitignore`,`.git`,`.idea`,`.vscode`]);async function pathKind(e){let t=await stat(e).catch(e=>{if(e.code!==`ENOENT`)throw e});return t===void 0?`missing`:t.isDirectory()?`directory`:`other`}function isEnvironmentOnly(e){return e.every(e=>ENVIRONMENT_ONLY_ENTRIES.has(e))}async function isAgentRoot(e){return(await readdir(e,{withFileTypes:!0}).catch(()=>[])).some(e=>{let t=classifyAgentRootEntry(e.name,getDirectoryEntryType(e));return t!==`unknown`&&t!==`ignored-directory`&&t!==`lib-directory`})}async function isExistingEveProject(e,t){if(await isAgentRoot(e)||(t.includes(`package.json`)||t.includes(`vercel.json`))&&t.includes(`agent`)&&await isAgentRoot(resolve(e,`agent`)))return!0;if(!t.includes(`agents`))return!1;let n=await readdir(resolve(e,`agents`),{withFileTypes:!0}).catch(()=>[]);if(!t.includes(`package.json`))return!1;for(let t of n){if(!t.isDirectory()||t.name.startsWith(`.`))continue;let n=resolve(e,`agents`,t.name);if(await pathKind(resolve(n,`agent`))===`directory`||await isAgentRoot(n))return!0}return!1}function listEntries(e){return e.map(e=>` - ${e}`).join(` `)}function assertTargetStaysWithinParent(e,t,n){if(t===void 0||isAbsolute(t))return;let r=relative(e,n);if(r===`..`||r.startsWith(`..${sep}`))throw new InitTargetError(`target_invalid`,PROJECT_NAME_ERROR)}async function resolveInitTarget(e){let t=resolve(e.parentDirectory),n=resolve(t,e.target??`.`);assertTargetStaysWithinParent(t,e.target,n);let r=n===t,i;try{i=await pathKind(n)}catch(e){throw new InitTargetError(`target_filesystem`,`Could not access the initialization target: ${e instanceof Error?e.message:String(e)}`)}if(i===`other`)throw new InitTargetError(`target_invalid`,`Cannot initialize an agent because "${n}" is not a directory.`);if(i===`missing`){let e;try{e=parseProjectName(basename(n))}catch(e){throw new InitTargetError(`target_invalid`,e instanceof Error?e.message:String(e))}return{createInPlace:!1,failurePolicy:`remove`,kind:`fresh`,overwriteExisting:!1,preservedEntries:[],projectName:e,projectPath:n}}let a;try{a=(await readdir(n)).sort()}catch(e){throw new InitTargetError(`target_filesystem`,`Could not read the initialization target: ${e instanceof Error?e.message:String(e)}`)}if(a.length===0||isEnvironmentOnly(a)){let e;try{e=r?`.`:parseProjectName(basename(n))}catch(e){throw new InitTargetError(`target_invalid`,e instanceof Error?e.message:String(e))}return{createInPlace:r||a.length>0,failurePolicy:`clear`,kind:`fresh`,overwriteExisting:!1,preservedEntries:a,projectName:e,projectPath:n}}if(await isExistingEveProject(n,a))throw new InitTargetError(`target_conflict`,`An eve project already exists at "${n}". Run \`eve dev\` from that directory, or use an existing-project command.`);if(a.includes(`package.json`))return{kind:`existing`,projectPath:n};throw new InitTargetError(`target_conflict`,`Cannot initialize an agent in the non-empty directory "${n}". Move or remove these entries, or choose an empty target:\n${listEntries(a)}`)}export{resolveInitTarget};