UNPKG

eve

Version:

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

1 lines 5.71 kB
import{withoutCodingAgentMarkers}from"./coding-agent-env.js";import{createProcessOutputBuffer}from"./process-output.js";import{armProcessAbort}from"./process-abort.js";import{accessSync,constants,existsSync,statSync}from"node:fs";import{dirname,join,resolve}from"node:path";import{spawn}from"node:child_process";const CONNECT_FEATURE_FLAG_ENV={FF_CONNECT_ENABLED:`1`},VERCEL_NOT_FOUND_MESSAGE=`Vercel CLI not found. Install with: npm i -g vercel@latest`;function buildSpawnEnv(t){return{...withoutCodingAgentMarkers(process.env),...CONNECT_FEATURE_FLAG_ENV,...t}}function commandArgs(e,t){return!t||e.includes(`--non-interactive`)?e:[...e,`--non-interactive`]}function existingDir(e){let t=resolve(e);for(;!existsSync(t);){let e=dirname(t);if(e===t)break;t=e}return t}function armDeadline(e,t,n){if(t===void 0)return()=>{};let r=setTimeout(()=>{n(),e.kill(`SIGTERM`);let t=setTimeout(()=>e.kill(`SIGKILL`),5e3);t.unref(),e.once(`close`,()=>clearTimeout(t))},t);return r.unref(),()=>clearTimeout(r)}function timeoutMessage(e,t){return`vercel ${e.join(` `)} timed out after ${Math.round(t/1e3)}s and was aborted.`}function abortMessage(e){return`vercel ${e.join(` `)} was aborted.`}function isAbortError(e,t){return t?.aborted===!0||e.name===`AbortError`||e.code===`ABORT_ERR`}function ancestorDirectories(e){let t=[],n=resolve(e);for(;;){t.push(n);let e=dirname(n);if(e===n)return t;n=e}}function findExecutable(e){try{if(accessSync(e,constants.F_OK|constants.X_OK),statSync(e).isFile())return e}catch{return}}function findLocalVercel(e){for(let t of ancestorDirectories(e)){let e=findExecutable(join(t,`node_modules`,`.bin`,`vercel`));if(e!==void 0)return e}}function resolveVercelInvocation(e){let t=findLocalVercel(e);return t===void 0?{command:`vercel`,commandArgs:[]}:{command:t,commandArgs:[]}}function stdioForRun(e){return e.onOutput?[e.nonInteractive?`ignore`:`inherit`,`pipe`,`pipe`]:e.nonInteractive?[`ignore`,`pipe`,`pipe`]:`inherit`}async function runVercel(e,r){return r.signal?.aborted===!0?!1:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...commandArgs(e,r.nonInteractive)],{cwd:a,stdio:stdioForRun(r),env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal);c.stdout?.on(`data`,e=>s?.write(`stdout`,e)),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let u=!1;function settle(e){u||(u=!0,s?.flush(),i(e))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let d=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(e,r.timeoutMs??0)),settle(!1)});c.on(`error`,t=>{isAbortError(t,r.signal)||(t.code===`ENOENT`?(l(),d(),reportFailure(VERCEL_NOT_FOUND_MESSAGE),settle(!1)):(l(),d(),reportFailure(`vercel ${e.join(` `)} failed: ${t.message}`),settle(!1)))}),c.on(`close`,t=>{if(l(),d(),r.signal?.aborted===!0){settle(!1);return}!u&&t!==0&&t!==null&&(s?.flush(),reportFailure(`vercel ${e.join(` `)} exited with code ${t}.`)),settle(t===0)})})}async function runVercelCaptureStdout(e,r){return r.signal?.aborted===!0?{ok:!1,stdout:``}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...commandArgs(e,r.nonInteractive)],{cwd:a,stdio:[r.nonInteractive?`ignore`:`inherit`,`pipe`,r.onOutput?`pipe`:`inherit`],env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal),u=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>s?.write(`stderr`,e));let d=!1;function settle(e){d||(d=!0,s?.flush(),i({ok:e,stdout:u.join(``)}))}function reportFailure(e){r.onOutput?r.onOutput({stream:`stderr`,text:e}):process.stderr.write(`\n${e}\n`)}let f=armDeadline(c,r.timeoutMs,()=>{reportFailure(timeoutMessage(e,r.timeoutMs??0)),settle(!1)});c.on(`error`,t=>{isAbortError(t,r.signal)||(l(),f(),reportFailure(t.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${e.join(` `)} failed: ${t.message}`),settle(!1))}),c.on(`close`,t=>{if(l(),f(),r.signal?.aborted===!0){settle(!1);return}!d&&t!==0&&t!==null&&reportFailure(`vercel ${e.join(` `)} exited with code ${t}.`),settle(t===0)})})}async function captureVercel(e,r){return r.signal?.aborted===!0?{ok:!1,failure:{errno:`ABORT_ERR`,stdout:``,stderr:``,message:abortMessage(e)}}:new Promise(i=>{let a=existingDir(r.cwd),o=resolveVercelInvocation(a),s=r.onOutput&&createProcessOutputBuffer(r.onOutput),c=spawn(o.command,[...o.commandArgs,...commandArgs(e,r.nonInteractive)],{cwd:a,stdio:[`ignore`,`pipe`,`pipe`],env:buildSpawnEnv(r.extraEnv??{}),signal:r.signal}),l=armProcessAbort(c,r.signal),u=[],d=[];c.stdout?.on(`data`,e=>u.push(e.toString(`utf8`))),c.stderr?.on(`data`,e=>{d.push(e.toString(`utf8`)),s?.write(`stderr`,e)});let f=!1;function fail(e,t=!0){f||(f=!0,s?.flush(),t&&r.onOutput?.({stream:`stderr`,text:e.message}),i({ok:!1,failure:e}))}function succeed(){f||(f=!0,s?.flush(),i({ok:!0,stdout:u.join(``)}))}let p=armDeadline(c,r.timeoutMs,()=>{fail({code:null,stdout:u.join(``),stderr:d.join(``),message:timeoutMessage(e,r.timeoutMs??0)})});c.on(`error`,t=>{isAbortError(t,r.signal)||(l(),p(),fail({errno:t.code,stdout:u.join(``),stderr:d.join(``),message:t.code===`ENOENT`?VERCEL_NOT_FOUND_MESSAGE:`vercel ${e.join(` `)} failed: ${t.message}`}))}),c.on(`close`,t=>{if(l(),p(),r.signal?.aborted===!0){fail({errno:`ABORT_ERR`,stdout:u.join(``),stderr:d.join(``),message:abortMessage(e)},!1);return}if(t!==0&&t!==null){fail({code:t,stdout:u.join(``),stderr:d.join(``),message:`vercel ${e.join(` `)} exited with code ${t}.`});return}succeed()})})}export{captureVercel,runVercel,runVercelCaptureStdout};