@netlify/agent-runner-cli 1.41.0 → 1.41.1

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/dist/bin.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import Be from"process";import Xr from"minimist";import{createRequire as Hr}from"module";import{createTracerProvider as Ut}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as He}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as Gt}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as Mt}from"@netlify/otel";import{propagation as qe,context as Ke,W3CTraceContextPropagator as Yt}from"@netlify/otel/opentelemetry";import{OTLPTraceExporter as jt}from"@opentelemetry/exporter-trace-otlp-grpc";function _(e){let t=!process.env.VITEST;return{log:(...r)=>{t&&console.log(`[AR]-[${e}]`,...r)},error:(...r)=>{t&&console.error(`[AR]-[ERROR]-[${e}]`,...r)},warn:(...r)=>{t&&console.warn(`[AR]-[WARN]-[${e}]`,...r)},info:(...r)=>{t&&console.info(`[AR]-[${e}]`,...r)},debug:(...r)=>{t&&console.debug(`[AR]-[DEBUG]-[${e}]`,...r)}}}var Ie=_("tracing"),Ve=async(e,t,r)=>(await Ut({serviceName:"@netlify/agent-runner-cli",serviceVersion:e,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:t,spanProcessors:[new He(new Ae),new He(new jt({url:r.exporterUrl}))],instrumentations:[new Gt({skipHeaders:!0})]}),r.traceparent?(qe.setGlobalPropagator(new Yt),qe.extract(Ke.active(),{traceparent:r.traceparent,isRemote:!0})):Ke.active());function P(e,t,r){return Ie.log(`\u23F3 TRACE: ${t} starting...`),Mt(e,t,r)}var Ae=class{export(t,r){for(let o of t)this.logSpan(o);r({code:1})}async shutdown(){}forceFlush(){return Promise.resolve()}logSpan(t){let r=(t.endTime[0]-t.startTime[0])*1e3+(t.endTime[1]-t.startTime[1])/1e6,o=t.attributes,n=[];for(let[u,i]of Object.entries(o))u.includes("duration")&&typeof i=="number"?n.push(`${u}=${i.toFixed(2)}ms`):n.push(`${u}=${i}`);let s=t.status?.code===2?"\u274C":"\u2705",a=n.length>0?` [${n.join(", ")}]`:"";Ie.log(`${s} TRACE: ${t.name} completed in ${r.toFixed(2)}ms${a}`),t.status?.code===2&&t.status.message&&Ie.log(` \u274C Error: ${t.status.message}`)}};var Bt=["error","failed","exception","fatal","panic","abort","crash"];function We(e){let t=e.split(`
2
+ import Be from"process";import zr from"minimist";import{createRequire as Hr}from"module";import{createTracerProvider as Ut}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as He}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as Gt}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as Mt}from"@netlify/otel";import{propagation as qe,context as Ke,W3CTraceContextPropagator as Yt}from"@netlify/otel/opentelemetry";import{OTLPTraceExporter as jt}from"@opentelemetry/exporter-trace-otlp-grpc";function _(e){let t=!process.env.VITEST;return{log:(...r)=>{t&&console.log(`[AR]-[${e}]`,...r)},error:(...r)=>{t&&console.error(`[AR]-[ERROR]-[${e}]`,...r)},warn:(...r)=>{t&&console.warn(`[AR]-[WARN]-[${e}]`,...r)},info:(...r)=>{t&&console.info(`[AR]-[${e}]`,...r)},debug:(...r)=>{t&&console.debug(`[AR]-[DEBUG]-[${e}]`,...r)}}}var Ie=_("tracing"),Ve=async(e,t,r)=>(await Ut({serviceName:"@netlify/agent-runner-cli",serviceVersion:e,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:t,spanProcessors:[new He(new Ae),new He(new jt({url:r.exporterUrl}))],instrumentations:[new Gt({skipHeaders:!0})]}),r.traceparent?(qe.setGlobalPropagator(new Yt),qe.extract(Ke.active(),{traceparent:r.traceparent,isRemote:!0})):Ke.active());function P(e,t,r){return Ie.log(`\u23F3 TRACE: ${t} starting...`),Mt(e,t,r)}var Ae=class{export(t,r){for(let o of t)this.logSpan(o);r({code:1})}async shutdown(){}forceFlush(){return Promise.resolve()}logSpan(t){let r=(t.endTime[0]-t.startTime[0])*1e3+(t.endTime[1]-t.startTime[1])/1e6,o=t.attributes,n=[];for(let[u,i]of Object.entries(o))u.includes("duration")&&typeof i=="number"?n.push(`${u}=${i.toFixed(2)}ms`):n.push(`${u}=${i}`);let s=t.status?.code===2?"\u274C":"\u2705",a=n.length>0?` [${n.join(", ")}]`:"";Ie.log(`${s} TRACE: ${t.name} completed in ${r.toFixed(2)}ms${a}`),t.status?.code===2&&t.status.message&&Ie.log(` \u274C Error: ${t.status.message}`)}};var Bt=["error","failed","exception","fatal","panic","abort","crash"];function We(e){let t=e.split(`
3
3
  `),r=[],o=-1,n=0;for(;n<t.length;){let u=t[n].slice(0,500).toLowerCase();if(Bt.some(p=>u.includes(p))){let p=Math.max(0,n-10,o+1),c=Math.min(t.length-1,n+20),d=[];for(let f=p;f<=c;f++)d.push(t[f]);r.push(d.join(`
4
4
  `)),o=c,n=c+1}else n++}if(r.length===0)return e;let s=r.map((a,u)=>`<extracted_error_chunk order="${u+1}">
5
5
  ${a}
6
6
  </extracted_error_chunk>`).join(`
7
7
 
8
- `);return s.length>e.length*.8?e:s}import ye from"process";import{getTracer as Cr}from"@netlify/otel";import de from"process";var Ce=de.env.NETLIFY_API_URL,Se=de.env.NETLIFY_API_TOKEN,le=_("api"),me=async(e,t={})=>{if(!Ce||!Se)throw new Error("No API URL or token");let r=new URL(e,Ce),o={...t,headers:{...t.headers,Authorization:`Bearer ${Se}`}};de.env.AGENT_RUNNERS_DEBUG==="true"&&(o.headers["x-nf-debug-logging"]="true"),t.json&&(o.headers||={},o.headers["Content-Type"]="application/json",o.body=JSON.stringify(t.json));let n=await fetch(r,o),s=n.ok&&n.status<=299;if(de.env.AGENT_RUNNERS_DEBUG==="true")le.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{le.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");le.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||le.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw n;return n}let a=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s)throw a;return a},Je=e=>{le.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Ce=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Se=e.constants.NETLIFY_API_TOKEN)},fe=(e,t)=>me(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),G=(e,t,r)=>me(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Xe=(e,t)=>me(`/api/v1/agent_runners/${e}/sessions/${t}`),ze=(e,t,r)=>me(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r}});var Ze=_("ai_gateway"),Qe=async({netlify:e,config:t})=>{let r,o,n,s,a=e.constants?.SITE_ID;if(!a)throw new Error("No site id");let u=async()=>{clearTimeout(n),Ze.log("Requesting AI gateway information");let i=await ze(a,t.id,t.sessionId);if({token:r,url:s}=i,o=i.expires_at?i.expires_at*1e3:void 0,Ze.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{u()},p))}};return await u(),{get url(){return s},get token(){return r}}};import X from"process";import{execa as Jt,execaCommand as yn}from"execa";import{Transform as Ht}from"stream";var qt=new Set(["NODE_ENV","PATH","HOME","USER","USERNAME","SHELL","PWD","OLDPWD","TMPDIR","TMP","TEMP","LANG","TERM","EDITOR","PAGER","OS","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","SYSTEMROOT","WINDIR","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","APPDATA","LOCALAPPDATA","NODE_OPTIONS","NODE_PATH","NODE_DEBUG","NODE_NO_WARNINGS","npm_config_registry","npm_config_cache","npm_execpath","npm_node_execpath","CI","GITHUB_ACTIONS","GITHUB_WORKSPACE","GITHUB_REPOSITORY","GITHUB_REF","BUILDKITE","BUILDKITE_BRANCH","BUILDKITE_COMMIT","BUILDKITE_BUILD_NUMBER","JENKINS_URL","TRAVIS","CIRCLECI","DISPLAY","COLORTERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","COLUMNS","LINES","HISTSIZE","HISTFILE","NETLIFY_AGENT_RUNNER_ID","NETLIFY_AGENT_RUNNER_SESSION_ID","NETLIFY_AGENT_RUNNER_PROMPT","NETLIFY_AGENT_RUNNER_AGENT","NETLIFY_AGENT_RUNNER_MODEL","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED","ERROR_LOGS_PATH","NETLIFY_AGENT_RUNNER_CONTEXT","NETLIFY_AGENT_RUNNER_HAS_REPO","NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED","NETLIFY_AGENT_RUNNER_SHA","NETLIFY_TEAM_TYPE","AGENT_RUNNERS_DEBUG","NETLIFY_TEAM_ID","NETLIFY_AGENT_RUNNER_USER_ID","SITE_NAME"]),Kt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Vt(){return Object.entries(process.env).filter(([e,t])=>!(!t||qt.has(e)||Kt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function M(e){if(typeof e!="string")return e;let t=Vt();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Wt(o),"g");r=r.replace(n,"******")}),r}function Wt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var te=class extends Ht{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=M(n);o(null,s)}};function et(){if(!(process.env.NETLIFY_MASK_LOGS!=="false"))return;let t=process.stdout.write.bind(process.stdout),r=process.stderr.write.bind(process.stderr);process.stdout.write=function(o,n,s){let a=typeof o=="string"?M(o):o;return typeof n=="function"?t(a,n):t(a,n,s)},process.stderr.write=function(o,n,s){let a=typeof o=="string"?M(o):o;return typeof n=="function"?r(a,n):r(a,n,s)}}var ue=null,tt=e=>(ue&&ue.destroy(),ue=new J({totalAllowedTime:e}),ue),rt=()=>ue;var J=class{constructor({totalAllowedTime:t}){this.withStageTimer=async(t,r,o)=>{if(this.isTimeExpired())throw new Error(`${t} stage did not complete in the allowed time. Time has already expired.`);let n=this.onTimesUp(()=>{throw new Error(`${t} stage did not complete in the allowed time.`)}),s=null,a=null;o!==void 0&&(a=new Promise((u,i)=>{s=setTimeout(()=>{i(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return a?await Promise.race([r(),a]):await r()}finally{n(),s&&clearTimeout(s)}};this.startTime=Date.now(),this.totalAllowedTime=t,this.globalTimeoutId=null,this.subscribers=[],this.hasTimedOut=!1,this.setupGlobalTimeout()}getElapsedTime(){return Date.now()-this.startTime}getRemainingTime(){let t=this.getElapsedTime(),r=this.totalAllowedTime-t;return Math.max(0,r)}isTimeExpired(){return this.getRemainingTime()===0||this.hasTimedOut}setupGlobalTimeout(){this.globalTimeoutId&&clearTimeout(this.globalTimeoutId),this.globalTimeoutId=setTimeout(()=>{this.notifyTimeUp()},this.totalAllowedTime)}notifyTimeUp(){this.hasTimedOut=!0;for(let t=this.subscribers.length-1;t>=0;t--)try{this.subscribers[t]()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}}onTimesUp(t){if(this.subscribers.push(t),this.hasTimedOut)try{t()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}return()=>{let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}}off(t){let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}clearSubscribers(){this.subscribers.length=0}getSubscriberCount(){return this.subscribers.length}destroy(){this.globalTimeoutId&&(clearTimeout(this.globalTimeoutId),this.globalTimeoutId=null),this.clearSubscribers()}static{this.timeUnits={seconds:t=>t*1e3,minutes:t=>t*60*1e3,hours:t=>t*60*60*1e3}}};var ge=_("shell"),ve=new Set,Xt={preferLocal:!0},nt=(e,t,r)=>{let[o,n]=zt(t,r),s={...Xt,...n},a=Jt(e,o,s);return Zt(a,s),er(a),a};var zt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Zt=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(X.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new te).pipe(X.stdout),e.stdout?.pipe(new te).pipe(X.stdout),e.stderr?.pipe(new te).pipe(X.stderr);return}e.stdout?.pipe(X.stdout),e.stderr?.pipe(X.stderr)},ot=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(X.kill(-e.pid,t),ge.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return ge.error("Error killing process:",r),!1}},Qt=e=>ot(e,"SIGKILL"),er=e=>{ve.add(e);let t=rt();if(t){let r=t.onTimesUp(()=>{ge.log(`Global timer expired, killing process ${e.pid}`),ot(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing process ${e.pid} after timeout`),Qt(e))},5e3)});e.on("exit",()=>{ve.delete(e),r()}),e.on("error",()=>{ve.delete(e),r()})}};var st="netlify-agent-runner-context.md",Pe="task-history",be="netlify-context",D=".netlify",re="results.md",Oe="assets",Y="other",j="personal";var B="enterprise",H="free",it=[j,"pro",B,H];var at=_("utils"),tr=e=>new Promise(t=>{setTimeout(t,e)}),lt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,a=(...u)=>{if(r)return o=u,new Promise(c=>{n.push(c)});r=!0;let i,p=new Promise(c=>{i=c});return s=(async()=>{await Promise.resolve();let c=await e(...u);for(i(c);;){if(await tr(t),!o)return r=!1,s=null,c;let d=o,f=n;o=null,n=[],c=await e(...d),f.forEach(T=>{T(c)})}})(),p};return a.flush=async()=>{if((r||o)&&s)return await s,a.flush()},a},he=(e,t,r=!1)=>{let o=null,n=null,s=null,a=function(...u){n=u,s=this;let i=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),i&&(e.apply(s,n),n=null,s=null)};return a.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},a.flush=()=>{if(o){clearTimeout(o);let u=n,i=s;o=null,n=null,s=null,e.apply(i,u)}},a},Ee=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):at.error("Could not parse JSON",o))}},ut=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let u=`--${t}${n}`;if(u.length>55)return"";let i=60-u.length;if(i<=0)return"";if(i>=s.length+6){let p=Math.min(i-s.length,e.length);return`${s}${e.slice(0,p)}`}return e.slice(0,i)},rr=e=>!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0?!1:!!it.some(t=>t in e),ct=()=>{let e={},t={codex:process.env.NETLIFY_FF_AGENT_RUNNER_CODEX_VERSION,claude:process.env.NETLIFY_FF_AGENT_RUNNER_CLAUDE_VERSION,gemini:process.env.NETLIFY_FF_AGENT_RUNNER_GEMINI_VERSION};return Object.entries(t).forEach(([r,o])=>{if(o){let n=`NETLIFY_FF_AGENT_RUNNER_${r.toUpperCase()}_VERSION`;try{let s=JSON.parse(o);rr(s)&&(e[r]=s)}catch(s){let u=s instanceof SyntaxError?"Invalid JSON":s.message;at.error(`Could not parse ${r} model version override from ${n}: ${u}`)}}}),e};import{Buffer as pt}from"buffer";import nr from"path";var dt=async({config:e,netlify:t})=>{let r=await sr(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await ir(n);await t.utils.run("git",["add",".",...s]);let a={stdio:["ignore","pipe","pipe"]},i=(await t.utils.run("git",["diff","--staged"],a)).stdout;if(o=!!i,!o)return{hasChanges:!1,ignored:s};let c=(await t.utils.run("git",["diff","--staged","--binary"],a)).stdout,d,f;if(e.sha){await t.utils.run("git",["commit","-m","Agent runner"]),d=(await t.utils.run("git",["diff",e.sha,"HEAD"],a)).stdout;let y=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],a)).stdout;d!==y&&(f=pt.from(y).toString("base64"))}let T={hasChanges:!0,diff:i,resultDiff:d,ignored:s};return i!==c&&(T.diffBinary=pt.from(c).toString("base64")),f&&(T.resultDiffBinary=f),T},or=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],sr=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
8
+ `);return s.length>e.length*.8?e:s}import ye from"process";import{getTracer as Cr}from"@netlify/otel";import de from"process";var Ce=de.env.NETLIFY_API_URL,Se=de.env.NETLIFY_API_TOKEN,le=_("api"),me=async(e,t={})=>{if(!Ce||!Se)throw new Error("No API URL or token");let r=new URL(e,Ce),o={...t,headers:{...t.headers,Authorization:`Bearer ${Se}`}};de.env.AGENT_RUNNERS_DEBUG==="true"&&(o.headers["x-nf-debug-logging"]="true"),t.json&&(o.headers||={},o.headers["Content-Type"]="application/json",o.body=JSON.stringify(t.json));let n=await fetch(r,o),s=n.ok&&n.status<=299;if(de.env.AGENT_RUNNERS_DEBUG==="true")le.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{le.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");le.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||le.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw n;return n}let a=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s)throw a;return a},Je=e=>{le.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Ce=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Se=e.constants.NETLIFY_API_TOKEN)},fe=(e,t)=>me(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),G=(e,t,r)=>me(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Xe=(e,t)=>me(`/api/v1/agent_runners/${e}/sessions/${t}`),ze=(e,t,r)=>me(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r}});var Ze=_("ai_gateway"),Qe=async({netlify:e,config:t})=>{let r,o,n,s,a=e.constants?.SITE_ID;if(!a)throw new Error("No site id");let u=async()=>{clearTimeout(n),Ze.log("Requesting AI gateway information");let i=await ze(a,t.id,t.sessionId);if({token:r,url:s}=i,o=i.expires_at?i.expires_at*1e3:void 0,Ze.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{u()},p))}};return await u(),{get url(){return s},get token(){return r}}};import X from"process";import{execa as Jt,execaCommand as xn}from"execa";import{Transform as Ht}from"stream";var qt=new Set(["NODE_ENV","PATH","HOME","USER","USERNAME","SHELL","PWD","OLDPWD","TMPDIR","TMP","TEMP","LANG","TERM","EDITOR","PAGER","OS","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","SYSTEMROOT","WINDIR","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","APPDATA","LOCALAPPDATA","NODE_OPTIONS","NODE_PATH","NODE_DEBUG","NODE_NO_WARNINGS","npm_config_registry","npm_config_cache","npm_execpath","npm_node_execpath","CI","GITHUB_ACTIONS","GITHUB_WORKSPACE","GITHUB_REPOSITORY","GITHUB_REF","BUILDKITE","BUILDKITE_BRANCH","BUILDKITE_COMMIT","BUILDKITE_BUILD_NUMBER","JENKINS_URL","TRAVIS","CIRCLECI","DISPLAY","COLORTERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","COLUMNS","LINES","HISTSIZE","HISTFILE","NETLIFY_AGENT_RUNNER_ID","NETLIFY_AGENT_RUNNER_SESSION_ID","NETLIFY_AGENT_RUNNER_PROMPT","NETLIFY_AGENT_RUNNER_AGENT","NETLIFY_AGENT_RUNNER_MODEL","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED","ERROR_LOGS_PATH","NETLIFY_AGENT_RUNNER_CONTEXT","NETLIFY_AGENT_RUNNER_HAS_REPO","NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED","NETLIFY_AGENT_RUNNER_SHA","NETLIFY_TEAM_TYPE","AGENT_RUNNERS_DEBUG","NETLIFY_TEAM_ID","NETLIFY_AGENT_RUNNER_USER_ID","SITE_NAME"]),Kt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Vt(){return Object.entries(process.env).filter(([e,t])=>!(!t||qt.has(e)||Kt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function M(e){if(typeof e!="string")return e;let t=Vt();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Wt(o),"g");r=r.replace(n,"******")}),r}function Wt(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var te=class extends Ht{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=M(n);o(null,s)}};function et(){if(!(process.env.NETLIFY_MASK_LOGS!=="false"))return;let t=process.stdout.write.bind(process.stdout),r=process.stderr.write.bind(process.stderr);process.stdout.write=function(o,n,s){let a=typeof o=="string"?M(o):o;return typeof n=="function"?t(a,n):t(a,n,s)},process.stderr.write=function(o,n,s){let a=typeof o=="string"?M(o):o;return typeof n=="function"?r(a,n):r(a,n,s)}}var ue=null,tt=e=>(ue&&ue.destroy(),ue=new J({totalAllowedTime:e}),ue),rt=()=>ue;var J=class{constructor({totalAllowedTime:t}){this.withStageTimer=async(t,r,o)=>{if(this.isTimeExpired())throw new Error(`${t} stage did not complete in the allowed time. Time has already expired.`);let n=this.onTimesUp(()=>{throw new Error(`${t} stage did not complete in the allowed time.`)}),s=null,a=null;o!==void 0&&(a=new Promise((u,i)=>{s=setTimeout(()=>{i(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return a?await Promise.race([r(),a]):await r()}finally{n(),s&&clearTimeout(s)}};this.startTime=Date.now(),this.totalAllowedTime=t,this.globalTimeoutId=null,this.subscribers=[],this.hasTimedOut=!1,this.setupGlobalTimeout()}getElapsedTime(){return Date.now()-this.startTime}getRemainingTime(){let t=this.getElapsedTime(),r=this.totalAllowedTime-t;return Math.max(0,r)}isTimeExpired(){return this.getRemainingTime()===0||this.hasTimedOut}setupGlobalTimeout(){this.globalTimeoutId&&clearTimeout(this.globalTimeoutId),this.globalTimeoutId=setTimeout(()=>{this.notifyTimeUp()},this.totalAllowedTime)}notifyTimeUp(){this.hasTimedOut=!0;for(let t=this.subscribers.length-1;t>=0;t--)try{this.subscribers[t]()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}}onTimesUp(t){if(this.subscribers.push(t),this.hasTimedOut)try{t()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}return()=>{let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}}off(t){let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}clearSubscribers(){this.subscribers.length=0}getSubscriberCount(){return this.subscribers.length}destroy(){this.globalTimeoutId&&(clearTimeout(this.globalTimeoutId),this.globalTimeoutId=null),this.clearSubscribers()}static{this.timeUnits={seconds:t=>t*1e3,minutes:t=>t*60*1e3,hours:t=>t*60*60*1e3}}};var ge=_("shell"),ve=new Set,Xt={preferLocal:!0},nt=(e,t,r)=>{let[o,n]=zt(t,r),s={...Xt,...n},a=Jt(e,o,s);return Zt(a,s),er(a),a};var zt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Zt=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(X.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new te).pipe(X.stdout),e.stdout?.pipe(new te).pipe(X.stdout),e.stderr?.pipe(new te).pipe(X.stderr);return}e.stdout?.pipe(X.stdout),e.stderr?.pipe(X.stderr)},ot=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(X.kill(-e.pid,t),ge.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return ge.error("Error killing process:",r),!1}},Qt=e=>ot(e,"SIGKILL"),er=e=>{ve.add(e);let t=rt();if(t){let r=t.onTimesUp(()=>{ge.log(`Global timer expired, killing process ${e.pid}`),ot(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing process ${e.pid} after timeout`),Qt(e))},5e3)});e.on("exit",()=>{ve.delete(e),r()}),e.on("error",()=>{ve.delete(e),r()})}};var st="netlify-agent-runner-context.md",Pe="task-history",be="netlify-context",D=".netlify",re="results.md",Oe="assets",Y="other",j="personal";var B="enterprise",H="free",it=[j,"pro",B,H];var at=_("utils"),tr=e=>new Promise(t=>{setTimeout(t,e)}),lt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,a=(...u)=>{if(r)return o=u,new Promise(c=>{n.push(c)});r=!0;let i,p=new Promise(c=>{i=c});return s=(async()=>{await Promise.resolve();let c=await e(...u);for(i(c);;){if(await tr(t),!o)return r=!1,s=null,c;let d=o,f=n;o=null,n=[],c=await e(...d),f.forEach(T=>{T(c)})}})(),p};return a.flush=async()=>{if((r||o)&&s)return await s,a.flush()},a},he=(e,t,r=!1)=>{let o=null,n=null,s=null,a=function(...u){n=u,s=this;let i=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),i&&(e.apply(s,n),n=null,s=null)};return a.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},a.flush=()=>{if(o){clearTimeout(o);let u=n,i=s;o=null,n=null,s=null,e.apply(i,u)}},a},Ee=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):at.error("Could not parse JSON",o))}},ut=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let u=`--${t}${n}`;if(u.length>55)return"";let i=60-u.length;if(i<=0)return"";if(i>=s.length+6){let p=Math.min(i-s.length,e.length);return`${s}${e.slice(0,p)}`}return e.slice(0,i)},rr=e=>!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0?!1:!!it.some(t=>t in e),ct=()=>{let e={},t={codex:process.env.NETLIFY_FF_AGENT_RUNNER_CODEX_VERSION,claude:process.env.NETLIFY_FF_AGENT_RUNNER_CLAUDE_VERSION,gemini:process.env.NETLIFY_FF_AGENT_RUNNER_GEMINI_VERSION};return Object.entries(t).forEach(([r,o])=>{if(o){let n=`NETLIFY_FF_AGENT_RUNNER_${r.toUpperCase()}_VERSION`;try{let s=JSON.parse(o);rr(s)&&(e[r]=s)}catch(s){let u=s instanceof SyntaxError?"Invalid JSON":s.message;at.error(`Could not parse ${r} model version override from ${n}: ${u}`)}}}),e};import{Buffer as pt}from"buffer";import nr from"path";var dt=async({config:e,netlify:t})=>{let r=await sr(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await ir(n);await t.utils.run("git",["add",".",...s]);let a={stdio:["ignore","pipe","pipe"]},i=(await t.utils.run("git",["diff","--staged"],a)).stdout;if(o=!!i,!o)return{hasChanges:!1,ignored:s};let c=(await t.utils.run("git",["diff","--staged","--binary"],a)).stdout,d,f;if(e.sha){await t.utils.run("git",["commit","-m","Agent runner"]),d=(await t.utils.run("git",["diff",e.sha,"HEAD"],a)).stdout;let y=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],a)).stdout;d!==y&&(f=pt.from(y).toString("base64"))}let T={hasChanges:!0,diff:i,resultDiff:d,ignored:s};return i!==c&&(T.diffBinary=pt.from(c).toString("base64")),f&&(T.resultDiffBinary=f),T},or=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],sr=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
9
9
  `).filter(n=>!or.some(s=>s instanceof RegExp?s.test(n):n===s))).length!==0,status:t.stdout}};var mt=async e=>{let{stdout:t}=await e.utils.run("git",["rev-parse","HEAD"]);return t.trim()},ft=async e=>{let{stdout:t}=await e.utils.run("git",["rev-list","--max-parents=0","HEAD"]);return t.trim()},ir=async e=>{let t=[".netlify","mise.toml","deno.lock","node_modules"],r=[];return e.split(`
10
10
  `).forEach(o=>{t.forEach(s=>{[`?? ${s}`,`?? ${s}${nr.sep}`].some(u=>o.startsWith(u))&&r.push(`:!${s}`)});let n=o.match(/\?\? (.+?)\.log$/)?.[1];n&&r.push(`:!${n}.log`)}),r};import lr from"fs/promises";import ur from"os";import _e from"path";import K from"process";import cr from"readline";import ke from"path";import ar from"fs/promises";var Le=_("agent-output-utils");async function ne({initialResult:e,agentName:t,hasError:r}){let o="",n=ke.join(process.cwd(),D,re);try{let s=await ar.readFile(n,"utf-8");s&&(o=s,Le.log(`Pulled result from ${ke.relative(process.cwd(),n)}`))}catch{Le.log(`No results file found at ${ke.relative(process.cwd(),n)}`)}return o||(!e&&!r?`${t} has finished working on task.`:e||void 0)}function oe({error:e,agentName:t}){let r=e&&typeof e=="object"?JSON.stringify(e):e,o=r?.replace(/\s+/g," ").trim().toLowerCase()||"",n="";return o?.includes("ai gateway is not available for your account")||o?.includes("ai gateway is not enabled for your account")?n="AI Gateway is currently not available on your account. Please confirm your account meets the criteria for using Agent Runners and AI Gateway and that your account has remaining AI Gateway inference credits available. Reach out to Netlify support if this is unexpected.":o?.includes("error when talking to gemini api")?n="Gemini's API is currently having issues. Please try again or use a different available agent while Google resolves the issue.":(o?.includes("connection closed prematurely")||o?.includes("499")&&t.toLowerCase().includes("gemini"))&&(n=`The ${t} models were currently overloaded. Please try again or use a different available agent.`),o?.includes("request timed out")&&(n=`The ${t} API request's have timed out. Please try again or use a different available agent.`),o?.includes("network error")&&(n=`The ${t} agent is having network issues. Please try again or use a different available agent.`),n&&Le.log(`Providing updated error messsage: ${n}, replacing original error: ${r}`),n||r||void 0}function se(e){if(!e)return!1;let r=(e&&typeof e=="object"?JSON.stringify(e):e)?.replace(/\s+/g," ").trim().toLowerCase()||"";return!!(r?.includes("error when talking to gemini api")||r?.includes("499")||r?.includes("connection closed prematurely")||r?.includes("request timed out")||r?.includes("network error"))}var F=_("runner_claude"),gt="Claude Code",pr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(F.log(`${n} command completed with catch handler triggered`,{hadExistingError:!!r,hadExistingResult:!!o,resultLength:o?o.length:0,catchError:e?.message||"No error object",processExitCode:t.exitCode,processKilled:t.killed}),o?(F.log("Preserving existing result despite catch handler being triggered"),r?{error:r,result:o}:{error:"Process completed with errors but result was captured",result:o}):(F.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function De({config:e,netlify:t,persistSteps:r,aiGateway:o}){let n=e,{accountType:s,prompt:a,modelVersionOverrides:u}=n,{model:i}=n;if(o){let{token:w,url:m}=o;if(!w||!m)throw new Error("No token or url provided from AI Gateway");let l=dr[s];if(!l)throw new Error(`Claude is not supported for the account type ${s}`);if(i&&!l?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.claude){let h=u?.claude?.[s];h&&(i=h)}K.env.ANTHROPIC_API_KEY=w,K.env.ANTHROPIC_BASE_URL=m}else if(!K.env.ANTHROPIC_API_KEY)throw new Error("ANTHROPIC_API_KEY is not provided");let p=[],c=[],d={},f=0,T=0,g,E,y=_e.join(K.cwd(),"node_modules"),N=[_e.join(K.env.NODE_PATH||y,".bin/claude"),"--permission-mode","bypassPermissions","--dangerously-skip-permissions","--output-format","stream-json","--verbose",...i?["--model",i]:[],"-p",a],I=`${K.env.NVM_BIN}/node`;F.log(`Running ${I} ${N.join(" ")}`);let S=t.utils.run(I,N,{all:!0,env:K.env});S.stdin?.end();let A=he(()=>{r?.({steps:p,duration:T})},250),R=(w,m)=>{let l={...w,id:f};f+=1,c.push(l),p.push(l),m||A.flush(),A(),m&&A.flush()},x=cr.createInterface({input:S.all});return x.on("error",w=>{F.error("Readline interface error",{error:w.message,stack:w.stack})}),x.on("line",w=>{let m=null;try{m=JSON.parse(w)}catch{F.log("Could not parse line",w)}Array.isArray(m?.message?.content)?m.message.content.forEach(l=>{switch(l.type){case"text":{l.text&&R({message:l.text});break}case"image":{typeof l.source=="object"&&l.source&&l.source.type==="base64"&&l.source.media_type?R({message:`![](data:${l.source.media_type};base64,${l.source.data})`}):F.log(`Unsupported image type ${l.source?.type}`,l.source);break}case"tool_use":{if(l.name==="Task"){let h=l.input?.description&&`\`${l.input.description}\``;R({title:[l.name,h].filter(Boolean).join(" ")})}else l.id&&(d[l.id]=l);A.flush();break}case"tool_result":{let h=l.tool_use_id?d[l.tool_use_id]:void 0,C;if(h){let U=h.input?.file_path&&_e.relative(K.cwd(),h.input.file_path),v=U&&`\`${U}\``;C=[h.name,v].filter(Boolean).join(" ")}let q=["Bash","Glob","Grep","LS","Read","Edit","Write"].includes(h?.name||""),L;if(typeof l.content=="string")L=l.content;else if(Array.isArray(l.content)){let U=[];l.content.forEach(v=>{v?.type==="text"&&typeof v.text=="string"?U.push(v.text):v?.type==="image"&&typeof v.source=="object"&&v.source?v.source.type==="base64"&&v.source.media_type?U.push(`![](data:${v.source.media_type};base64,${v.source.data})`):F.log(`Unsupported image type ${v.source.type}`,v.source):F.log(`Unsupported block type ${v?.type}`)}),L=U.join(`
11
11
 
@@ -128,5 +128,5 @@ Below are all of the logs with potential issues that we extracted. Some of them
128
128
 
129
129
  ${e.pop()}
130
130
  `;import Yr from"process";import{getTracer as Me}from"@netlify/otel";import{getTracer as Gr}from"@netlify/otel";var ce=_("deploy"),At=async e=>await P(Gr(),"create-preview-deploy",async t=>Mr(e,t)),Mr=async({netlify:e,hasRepo:t,skipBuild:r,message:o="Agent Preview",deploySubdomain:n,cliPath:s,filter:a},u)=>{try{let i=["deploy","--message",`"${o}"`,"--json","--draft","--verbose"];t||(ce.log("Deploy: Uploading source zip"),i.push("--upload-source-zip")),n&&i.push("--alias",n),a&&i.push("--filter",a),r?(ce.log("Deploy: Skipping build"),i.push("--no-build")):i.push("--context","deploy-preview");let p=s||"netlify";ce.log(`Running: ${p} ${i.join(" ")}`),u?.setAttributes({cmd:p,args:i});let c=await e.utils.run(p,i,{stdio:["ignore","pipe","pipe"]}),d=JSON.parse(c.stdout.trim());u?.setAttributes({success:!0,deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id}),ce.log(`
131
- Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let f={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(f.sourceZipFilename=d.source_zip_filename),f}catch(i){throw ce.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var pe=_("deploy_stage"),Ye=async e=>await P(Me(),"run-deploy-stage",async()=>jr(e)),jr=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await P(Me(),"get-runner-diffs",async()=>await dt({config:t,netlify:r}));if(pe.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges)return{diff:"",hasChanges:!1,previewInfo:null};let{diff:a,resultDiff:u,diffBinary:i,resultDiffBinary:p}=s,c=!0;pe.log("Preview deploy condition check:",{resultUndefined:o===void 0,resultType:typeof o,hasChanges:c,wouldCreatePreview:o!==void 0&&c});let d=null;if(o!==void 0&&c)try{let f;try{let T=await P(Me(),"get-runner-session",async()=>await Xe(t.id,t.sessionId));T?.title&&(f=T.title)}catch(T){pe.warn("Failed to fetch session title, using fallback message:",T.message)}await G(t.id,t.sessionId,{steps:[{title:"Deploying the run preview"}]}),d=await At({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:f,skipBuild:!1,deploySubdomain:ut(t.id,Yr.env.SITE_NAME),filter:n})}catch(f){return pe.warn("Failed to create preview deploy (continuing with agent run):",f),{diff:a,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:f instanceof Error?f.message:String(f)}}return pe.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:u,hasChanges:c,previewInfo:d,diffBinary:i,resultDiffBinary:p}};import{getTracer as je}from"@netlify/otel";async function Ct(e,t){let{maxRetries:r,baseDelay:o,onRetry:n}=t,s;for(let a=1;a<=r;a++)try{return await e()}catch(u){if(s=u,a===r)throw s;n&&n(a,s),await new Promise(i=>setTimeout(i,o*a))}throw s}var ae=_("cleanup_stage"),St=async e=>await P(je(),"cleanup-stage",async()=>Br(e)),Br=async({config:e,diff:t,result:r,duration:o,resultDiff:n,diffBinary:s,resultDiffBinary:a,previewInfo:u})=>{let i={result_diff:t,result:r||"Done",duration:o,result_diff_binary:s};return u&&u.deployId&&(i.deploy_id=u.deployId),u&&u.sourceZipFilename&&(i.result_zip_file_name=u.sourceZipFilename),n||a?(ae.log("Updating total agent result diff"),await P(je(),"update-runner",async()=>{await fe(e.id,{result_diff:n,result_diff_binary:a})})):ae.log("No total result diff, not updating"),ae.log("Updated agent runner with result"),await Ct(async()=>await P(je(),"update-runner-session",()=>G(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{ae.error(`Error updating agent runner session (attempt ${p}):`,c),ae.log("Retrying...")}}),ae.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as vt,withActiveSpan as Pt}from"@netlify/otel";var qr=Hr(import.meta.url),bt=qr("../package.json"),Ot=_("pipeline_index"),Ne=3,kt=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,tracing:a={}})=>{let u,{withStageTimer:i}=tt(J.timeUnits.hours(4)),p=await Ve(bt.version,e.id,a);try{await Pt(vt(),"run-pipeline",{},p,async()=>{let c,{aiGateway:d,context:f,persistSteps:T,runner:g,sha:E}=await i("init",()=>Rt({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:bt.version}),J.timeUnits.minutes(10));u=g.clean,e.sha=E;let{runnerResult:y}=await i("inference",()=>we({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:T,aiGateway:d}));await G(e.id,e.sessionId,{steps:[{title:"Building and deploying the preview"}]});let N=await i("deploy",()=>Ye({cliPath:r,config:e,context:f,result:y.result,filter:s})),I=y,S=[];if(N.hasChanges&&N.deployError){S.push(We(N.deployError));let l=1;for(;l<=Ne&&!N.previewInfo;)Ot.log(`Deploy attempt had errors. Retrying. ${l}/${Ne}`),await Pt(vt(),"deploy-stage",async h=>{h?.setAttributes({"stage.attempt":l});let{runnerResult:C}=await i(`inference-retry-${l}`,()=>we({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:T,aiGateway:d,buildErrors:S}));I={...C,steps:[...I.steps||[],...C.steps||[]],duration:(I.duration||0)+(C.duration||0)},N=await i(`deploy-retry-${l}`,()=>Ye({cliPath:r,config:e,context:f,result:C.result,filter:s})),N.deployError&&S.push(N.deployError),l++});l>Ne&&!N.previewInfo&&(c=new Error(`Deploy validation failed after ${Ne} attempts`))}let{diff:A,resultDiff:R,previewInfo:x,diffBinary:w,resultDiffBinary:m}=N;if(await i("cleanup",()=>St({config:e,diff:A,result:I.result,duration:I.duration,resultDiff:R,diffBinary:w,resultDiffBinary:m,previewInfo:x}),J.timeUnits.minutes(10)),c)throw c;await g.clean?.()})}catch(c){Ot.error("Got error while running pipeline",c),await u?.();let d=c instanceof Error&&c.message;throw await G(e.id,e.sessionId,{result:d||"Encountered error when running agent",state:"error"}),c}};import O from"process";var Kr="claude",Vr=e=>(e??[]).filter(t=>t.request&&t.response),Wr=e=>(e??[]).filter(t=>t.site_context),Lt=_("config"),Dt=()=>{let e=O.env.NETLIFY_AGENT_RUNNER_ID,t=O.env.NETLIFY_AGENT_RUNNER_SESSION_ID;if(!e||!t)throw new Error("ID of agent runner is not provided");let r=O.env.NETLIFY_AGENT_RUNNER_RESULT_BRANCH,o=O.env.NETLIFY_AGENT_RUNNER_PROMPT;if(!o)throw new Error("Prompt is not provided");let n=O.env.NETLIFY_AGENT_RUNNER_AGENT||Kr,s=O.env.NETLIFY_AGENT_RUNNER_MODEL,a=O.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED==="1",u=O.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED==="1",i=O.env.ERROR_LOGS_PATH,p=Ee(O.env.NETLIFY_AGENT_RUNNER_CONTEXT,!0,Lt),c=Vr(p),d=Wr(p),f=O.env.NETLIFY_AGENT_RUNNER_HAS_REPO!=="0",T=!O.env.NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED,g=O.env.NETLIFY_AGENT_RUNNER_SHA,E=Jr(),y=ct(),N={id:e,sessionId:t,resultBranch:r,prompt:o,runner:n,model:s,validateAgent:a,errorLogsPath:i,sessionHistoryContext:c,siteContext:d,hasRepo:f,useGateway:T,sha:g,accountType:E,validateAgentWithBuild:u,modelVersionOverrides:y};return Lt.log({fullConfig:N}),N},Jr=()=>{let e=O.env.NETLIFY_TEAM_TYPE;return e?e.includes("personal")?j:e.includes("pro")?"pro":e.startsWith("enterprise")?B:e.startsWith("free")?H:Y:Y};var $t=_("bin_cmd"),ee=Xr(Be.argv.slice(2),{string:["auth","cwd","cli-path","error-logs-path","filter","trace-exporter-url","traceparent"]});try{let e=Dt();await kt({config:e,apiToken:ee.auth,cwd:ee.cwd,cliPath:ee["cli-path"],errorLogsPath:ee["error-logs-path"],filter:ee.filter,tracing:{exporterUrl:ee["trace-exporter-url"],traceparent:ee.traceparent}}),$t.info("Finished agent"),Be.exit(0)}catch(e){$t.error("Error running agent pipeline:",e),Be.exit(1)}
131
+ Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let f={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(f.sourceZipFilename=d.source_zip_filename),f}catch(i){throw ce.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var pe=_("deploy_stage"),Ye=async e=>await P(Me(),"run-deploy-stage",async()=>jr(e)),jr=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await P(Me(),"get-runner-diffs",async()=>await dt({config:t,netlify:r}));if(pe.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges)return{diff:"",hasChanges:!1,previewInfo:null};let{diff:a,resultDiff:u,diffBinary:i,resultDiffBinary:p}=s,c=!0;pe.log("Preview deploy condition check:",{resultUndefined:o===void 0,resultType:typeof o,hasChanges:c,wouldCreatePreview:o!==void 0&&c});let d=null;if(o!==void 0&&c)try{let f;try{let T=await P(Me(),"get-runner-session",async()=>await Xe(t.id,t.sessionId));T?.title&&(f=T.title)}catch(T){pe.warn("Failed to fetch session title, using fallback message:",T.message)}await G(t.id,t.sessionId,{steps:[{title:"Deploying the run preview"}]}),d=await At({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:f,skipBuild:!1,deploySubdomain:ut(t.id,Yr.env.SITE_NAME),filter:n})}catch(f){return pe.warn("Failed to create preview deploy (continuing with agent run):",f),{diff:a,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:f instanceof Error?f.message:String(f)}}return pe.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:u,hasChanges:c,previewInfo:d,diffBinary:i,resultDiffBinary:p}};import{getTracer as je}from"@netlify/otel";async function Ct(e,t){let{maxRetries:r,baseDelay:o,onRetry:n}=t,s;for(let a=1;a<=r;a++)try{return await e()}catch(u){if(s=u,a===r)throw s;n&&n(a,s),await new Promise(i=>setTimeout(i,o*a))}throw s}var ae=_("cleanup_stage"),St=async e=>await P(je(),"cleanup-stage",async()=>Br(e)),Br=async({config:e,diff:t,result:r,duration:o,resultDiff:n,diffBinary:s,resultDiffBinary:a,previewInfo:u})=>{let i={result_diff:t,result:r||"Done",duration:o,result_diff_binary:s};return u&&u.deployId&&(i.deploy_id=u.deployId),u&&u.sourceZipFilename&&(i.result_zip_file_name=u.sourceZipFilename),n||a?(ae.log("Updating total agent result diff"),await P(je(),"update-runner",async()=>{await fe(e.id,{result_diff:n,result_diff_binary:a})})):ae.log("No total result diff, not updating"),ae.log("Updated agent runner with result"),await Ct(async()=>await P(je(),"update-runner-session",()=>G(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{ae.error(`Error updating agent runner session (attempt ${p}):`,c),ae.log("Retrying...")}}),ae.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as vt,shutdownTracers as qr,withActiveSpan as Pt}from"@netlify/otel";var Kr=Hr(import.meta.url),bt=Kr("../package.json"),Ot=_("pipeline_index"),Ne=3,kt=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,tracing:a={}})=>{let u,{withStageTimer:i}=tt(J.timeUnits.hours(4)),p=await Ve(bt.version,e.id,a);try{await Pt(vt(),"run-pipeline",{},p,async()=>{let c,{aiGateway:d,context:f,persistSteps:T,runner:g,sha:E}=await i("init",()=>Rt({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:bt.version}),J.timeUnits.minutes(10));u=g.clean,e.sha=E;let{runnerResult:y}=await i("inference",()=>we({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:T,aiGateway:d}));await G(e.id,e.sessionId,{steps:[{title:"Building and deploying the preview"}]});let N=await i("deploy",()=>Ye({cliPath:r,config:e,context:f,result:y.result,filter:s})),I=y,S=[];if(N.hasChanges&&N.deployError){S.push(We(N.deployError));let l=1;for(;l<=Ne&&!N.previewInfo;)Ot.log(`Deploy attempt had errors. Retrying. ${l}/${Ne}`),await Pt(vt(),"deploy-stage",async h=>{h?.setAttributes({"stage.attempt":l});let{runnerResult:C}=await i(`inference-retry-${l}`,()=>we({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:T,aiGateway:d,buildErrors:S}));I={...C,steps:[...I.steps||[],...C.steps||[]],duration:(I.duration||0)+(C.duration||0)},N=await i(`deploy-retry-${l}`,()=>Ye({cliPath:r,config:e,context:f,result:C.result,filter:s})),N.deployError&&S.push(N.deployError),l++});l>Ne&&!N.previewInfo&&(c=new Error(`Deploy validation failed after ${Ne} attempts`))}let{diff:A,resultDiff:R,previewInfo:x,diffBinary:w,resultDiffBinary:m}=N;if(await i("cleanup",()=>St({config:e,diff:A,result:I.result,duration:I.duration,resultDiff:R,diffBinary:w,resultDiffBinary:m,previewInfo:x}),J.timeUnits.minutes(10)),c)throw c;await g.clean?.()})}catch(c){Ot.error("Got error while running pipeline",c),await u?.();let d=c instanceof Error&&c.message;throw await G(e.id,e.sessionId,{result:d||"Encountered error when running agent",state:"error"}),c}finally{await qr()}};import O from"process";var Vr="claude",Wr=e=>(e??[]).filter(t=>t.request&&t.response),Jr=e=>(e??[]).filter(t=>t.site_context),Lt=_("config"),Dt=()=>{let e=O.env.NETLIFY_AGENT_RUNNER_ID,t=O.env.NETLIFY_AGENT_RUNNER_SESSION_ID;if(!e||!t)throw new Error("ID of agent runner is not provided");let r=O.env.NETLIFY_AGENT_RUNNER_RESULT_BRANCH,o=O.env.NETLIFY_AGENT_RUNNER_PROMPT;if(!o)throw new Error("Prompt is not provided");let n=O.env.NETLIFY_AGENT_RUNNER_AGENT||Vr,s=O.env.NETLIFY_AGENT_RUNNER_MODEL,a=O.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED==="1",u=O.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED==="1",i=O.env.ERROR_LOGS_PATH,p=Ee(O.env.NETLIFY_AGENT_RUNNER_CONTEXT,!0,Lt),c=Wr(p),d=Jr(p),f=O.env.NETLIFY_AGENT_RUNNER_HAS_REPO!=="0",T=!O.env.NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED,g=O.env.NETLIFY_AGENT_RUNNER_SHA,E=Xr(),y=ct(),N={id:e,sessionId:t,resultBranch:r,prompt:o,runner:n,model:s,validateAgent:a,errorLogsPath:i,sessionHistoryContext:c,siteContext:d,hasRepo:f,useGateway:T,sha:g,accountType:E,validateAgentWithBuild:u,modelVersionOverrides:y};return Lt.log({fullConfig:N}),N},Xr=()=>{let e=O.env.NETLIFY_TEAM_TYPE;return e?e.includes("personal")?j:e.includes("pro")?"pro":e.startsWith("enterprise")?B:e.startsWith("free")?H:Y:Y};var $t=_("bin_cmd"),ee=zr(Be.argv.slice(2),{string:["auth","cwd","cli-path","error-logs-path","filter","trace-exporter-url","traceparent"]});try{let e=Dt();await kt({config:e,apiToken:ee.auth,cwd:ee.cwd,cliPath:ee["cli-path"],errorLogsPath:ee["error-logs-path"],filter:ee.filter,tracing:{exporterUrl:ee["trace-exporter-url"],traceparent:ee.traceparent}}),$t.info("Finished agent"),Be.exit(0)}catch(e){$t.error("Error running agent pipeline:",e),Be.exit(1)}
132
132
  //# sourceMappingURL=bin.js.map
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import{createRequire as $r}from"module";import{createTracerProvider as St}from"@
4
4
  ${a}
5
5
  </extracted_error_chunk>`).join(`
6
6
 
7
- `);return s.length>e.length*.8?e:s}import ye from"process";import{getTracer as yr}from"@netlify/otel";import ce from"process";var Ie=ce.env.NETLIFY_API_URL,Ne=ce.env.NETLIFY_API_TOKEN,se=T("api"),pe=async(e,t={})=>{if(!Ie||!Ne)throw new Error("No API URL or token");let r=new URL(e,Ie),o={...t,headers:{...t.headers,Authorization:`Bearer ${Ne}`}};ce.env.AGENT_RUNNERS_DEBUG==="true"&&(o.headers["x-nf-debug-logging"]="true"),t.json&&(o.headers||={},o.headers["Content-Type"]="application/json",o.body=JSON.stringify(t.json));let n=await fetch(r,o),s=n.ok&&n.status<=299;if(ce.env.AGENT_RUNNERS_DEBUG==="true")se.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{se.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");se.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||se.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw n;return n}let a=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s)throw a;return a},qe=e=>{se.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Ie=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Ne=e.constants.NETLIFY_API_TOKEN)},de=(e,t)=>pe(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),U=(e,t,r)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Ke=(e,t)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`),Ve=(e,t,r)=>pe(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r}});var We=T("ai_gateway"),Je=async({netlify:e,config:t})=>{let r,o,n,s,a=e.constants?.SITE_ID;if(!a)throw new Error("No site id");let u=async()=>{clearTimeout(n),We.log("Requesting AI gateway information");let i=await Ve(a,t.id,t.sessionId);if({token:r,url:s}=i,o=i.expires_at?i.expires_at*1e3:void 0,We.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{u()},p))}};return await u(),{get url(){return s},get token(){return r}}};import q from"process";import{execa as Gt,execaCommand as on}from"execa";import{Transform as $t}from"stream";var Dt=new Set(["NODE_ENV","PATH","HOME","USER","USERNAME","SHELL","PWD","OLDPWD","TMPDIR","TMP","TEMP","LANG","TERM","EDITOR","PAGER","OS","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","SYSTEMROOT","WINDIR","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","APPDATA","LOCALAPPDATA","NODE_OPTIONS","NODE_PATH","NODE_DEBUG","NODE_NO_WARNINGS","npm_config_registry","npm_config_cache","npm_execpath","npm_node_execpath","CI","GITHUB_ACTIONS","GITHUB_WORKSPACE","GITHUB_REPOSITORY","GITHUB_REF","BUILDKITE","BUILDKITE_BRANCH","BUILDKITE_COMMIT","BUILDKITE_BUILD_NUMBER","JENKINS_URL","TRAVIS","CIRCLECI","DISPLAY","COLORTERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","COLUMNS","LINES","HISTSIZE","HISTFILE","NETLIFY_AGENT_RUNNER_ID","NETLIFY_AGENT_RUNNER_SESSION_ID","NETLIFY_AGENT_RUNNER_PROMPT","NETLIFY_AGENT_RUNNER_AGENT","NETLIFY_AGENT_RUNNER_MODEL","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED","ERROR_LOGS_PATH","NETLIFY_AGENT_RUNNER_CONTEXT","NETLIFY_AGENT_RUNNER_HAS_REPO","NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED","NETLIFY_AGENT_RUNNER_SHA","NETLIFY_TEAM_TYPE","AGENT_RUNNERS_DEBUG","NETLIFY_TEAM_ID","NETLIFY_AGENT_RUNNER_USER_ID","SITE_NAME"]),Lt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Ft(){return Object.entries(process.env).filter(([e,t])=>!(!t||Dt.has(e)||Lt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function G(e){if(typeof e!="string")return e;let t=Ft();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Ut(o),"g");r=r.replace(n,"******")}),r}function Ut(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var W=class extends $t{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=G(n);o(null,s)}};function Xe(){if(!(process.env.NETLIFY_MASK_LOGS!=="false"))return;let t=process.stdout.write.bind(process.stdout),r=process.stderr.write.bind(process.stderr);process.stdout.write=function(o,n,s){let a=typeof o=="string"?G(o):o;return typeof n=="function"?t(a,n):t(a,n,s)},process.stderr.write=function(o,n,s){let a=typeof o=="string"?G(o):o;return typeof n=="function"?r(a,n):r(a,n,s)}}var ie=null,ze=e=>(ie&&ie.destroy(),ie=new H({totalAllowedTime:e}),ie),Ze=()=>ie;var H=class{constructor({totalAllowedTime:t}){this.withStageTimer=async(t,r,o)=>{if(this.isTimeExpired())throw new Error(`${t} stage did not complete in the allowed time. Time has already expired.`);let n=this.onTimesUp(()=>{throw new Error(`${t} stage did not complete in the allowed time.`)}),s=null,a=null;o!==void 0&&(a=new Promise((u,i)=>{s=setTimeout(()=>{i(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return a?await Promise.race([r(),a]):await r()}finally{n(),s&&clearTimeout(s)}};this.startTime=Date.now(),this.totalAllowedTime=t,this.globalTimeoutId=null,this.subscribers=[],this.hasTimedOut=!1,this.setupGlobalTimeout()}getElapsedTime(){return Date.now()-this.startTime}getRemainingTime(){let t=this.getElapsedTime(),r=this.totalAllowedTime-t;return Math.max(0,r)}isTimeExpired(){return this.getRemainingTime()===0||this.hasTimedOut}setupGlobalTimeout(){this.globalTimeoutId&&clearTimeout(this.globalTimeoutId),this.globalTimeoutId=setTimeout(()=>{this.notifyTimeUp()},this.totalAllowedTime)}notifyTimeUp(){this.hasTimedOut=!0;for(let t=this.subscribers.length-1;t>=0;t--)try{this.subscribers[t]()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}}onTimesUp(t){if(this.subscribers.push(t),this.hasTimedOut)try{t()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}return()=>{let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}}off(t){let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}clearSubscribers(){this.subscribers.length=0}getSubscriberCount(){return this.subscribers.length}destroy(){this.globalTimeoutId&&(clearTimeout(this.globalTimeoutId),this.globalTimeoutId=null),this.clearSubscribers()}static{this.timeUnits={seconds:t=>t*1e3,minutes:t=>t*60*1e3,hours:t=>t*60*60*1e3}}};var me=T("shell"),Ce=new Set,Mt={preferLocal:!0},Qe=(e,t,r)=>{let[o,n]=jt(t,r),s={...Mt,...n},a=Gt(e,o,s);return Yt(a,s),Ht(a),a};var jt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Yt=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(q.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new W).pipe(q.stdout),e.stdout?.pipe(new W).pipe(q.stdout),e.stderr?.pipe(new W).pipe(q.stderr);return}e.stdout?.pipe(q.stdout),e.stderr?.pipe(q.stderr)},et=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(q.kill(-e.pid,t),me.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return me.error("Error killing process:",r),!1}},Bt=e=>et(e,"SIGKILL"),Ht=e=>{Ce.add(e);let t=Ze();if(t){let r=t.onTimesUp(()=>{me.log(`Global timer expired, killing process ${e.pid}`),et(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(me.log(`Force killing process ${e.pid} after timeout`),Bt(e))},5e3)});e.on("exit",()=>{Ce.delete(e),r()}),e.on("error",()=>{Ce.delete(e),r()})}};var tt="netlify-agent-runner-context.md",Ae="task-history",Se="netlify-context",$=".netlify",J="results.md",be="assets",X="other",z="personal";var Z="enterprise",Q="free";var qt=T("utils"),Kt=e=>new Promise(t=>{setTimeout(t,e)}),rt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,a=(...u)=>{if(r)return o=u,new Promise(c=>{n.push(c)});r=!0;let i,p=new Promise(c=>{i=c});return s=(async()=>{await Promise.resolve();let c=await e(...u);for(i(c);;){if(await Kt(t),!o)return r=!1,s=null,c;let d=o,f=n;o=null,n=[],c=await e(...d),f.forEach(_=>{_(c)})}})(),p};return a.flush=async()=>{if((r||o)&&s)return await s,a.flush()},a},fe=(e,t,r=!1)=>{let o=null,n=null,s=null,a=function(...u){n=u,s=this;let i=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),i&&(e.apply(s,n),n=null,s=null)};return a.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},a.flush=()=>{if(o){clearTimeout(o);let u=n,i=s;o=null,n=null,s=null,e.apply(i,u)}},a},nt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):qt.error("Could not parse JSON",o))}},ot=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let u=`--${t}${n}`;if(u.length>55)return"";let i=60-u.length;if(i<=0)return"";if(i>=s.length+6){let p=Math.min(i-s.length,e.length);return`${s}${e.slice(0,p)}`}return e.slice(0,i)};import{Buffer as st}from"buffer";import Vt from"path";var it=async({config:e,netlify:t})=>{let r=await Jt(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await Xt(n);await t.utils.run("git",["add",".",...s]);let a={stdio:["ignore","pipe","pipe"]},i=(await t.utils.run("git",["diff","--staged"],a)).stdout;if(o=!!i,!o)return{hasChanges:!1,ignored:s};let c=(await t.utils.run("git",["diff","--staged","--binary"],a)).stdout,d,f;if(e.sha){await t.utils.run("git",["commit","-m","Agent runner"]),d=(await t.utils.run("git",["diff",e.sha,"HEAD"],a)).stdout;let x=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],a)).stdout;d!==x&&(f=st.from(x).toString("base64"))}let _={hasChanges:!0,diff:i,resultDiff:d,ignored:s};return i!==c&&(_.diffBinary=st.from(c).toString("base64")),f&&(_.resultDiffBinary=f),_},Wt=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],Jt=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
7
+ `);return s.length>e.length*.8?e:s}import ye from"process";import{getTracer as yr}from"@netlify/otel";import ce from"process";var Ie=ce.env.NETLIFY_API_URL,Ne=ce.env.NETLIFY_API_TOKEN,se=T("api"),pe=async(e,t={})=>{if(!Ie||!Ne)throw new Error("No API URL or token");let r=new URL(e,Ie),o={...t,headers:{...t.headers,Authorization:`Bearer ${Ne}`}};ce.env.AGENT_RUNNERS_DEBUG==="true"&&(o.headers["x-nf-debug-logging"]="true"),t.json&&(o.headers||={},o.headers["Content-Type"]="application/json",o.body=JSON.stringify(t.json));let n=await fetch(r,o),s=n.ok&&n.status<=299;if(ce.env.AGENT_RUNNERS_DEBUG==="true")se.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{se.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");se.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||se.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw n;return n}let a=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s)throw a;return a},qe=e=>{se.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Ie=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Ne=e.constants.NETLIFY_API_TOKEN)},de=(e,t)=>pe(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),U=(e,t,r)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Ke=(e,t)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`),Ve=(e,t,r)=>pe(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r}});var We=T("ai_gateway"),Je=async({netlify:e,config:t})=>{let r,o,n,s,a=e.constants?.SITE_ID;if(!a)throw new Error("No site id");let u=async()=>{clearTimeout(n),We.log("Requesting AI gateway information");let i=await Ve(a,t.id,t.sessionId);if({token:r,url:s}=i,o=i.expires_at?i.expires_at*1e3:void 0,We.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{u()},p))}};return await u(),{get url(){return s},get token(){return r}}};import q from"process";import{execa as Gt,execaCommand as sn}from"execa";import{Transform as $t}from"stream";var Dt=new Set(["NODE_ENV","PATH","HOME","USER","USERNAME","SHELL","PWD","OLDPWD","TMPDIR","TMP","TEMP","LANG","TERM","EDITOR","PAGER","OS","PROCESSOR_ARCHITECTURE","PROCESSOR_IDENTIFIER","SYSTEMROOT","WINDIR","PROGRAMFILES","PROGRAMFILES(X86)","PROGRAMDATA","APPDATA","LOCALAPPDATA","NODE_OPTIONS","NODE_PATH","NODE_DEBUG","NODE_NO_WARNINGS","npm_config_registry","npm_config_cache","npm_execpath","npm_node_execpath","CI","GITHUB_ACTIONS","GITHUB_WORKSPACE","GITHUB_REPOSITORY","GITHUB_REF","BUILDKITE","BUILDKITE_BRANCH","BUILDKITE_COMMIT","BUILDKITE_BUILD_NUMBER","JENKINS_URL","TRAVIS","CIRCLECI","DISPLAY","COLORTERM","TERM_PROGRAM","TERM_PROGRAM_VERSION","COLUMNS","LINES","HISTSIZE","HISTFILE","NETLIFY_AGENT_RUNNER_ID","NETLIFY_AGENT_RUNNER_SESSION_ID","NETLIFY_AGENT_RUNNER_PROMPT","NETLIFY_AGENT_RUNNER_AGENT","NETLIFY_AGENT_RUNNER_MODEL","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED","NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED","ERROR_LOGS_PATH","NETLIFY_AGENT_RUNNER_CONTEXT","NETLIFY_AGENT_RUNNER_HAS_REPO","NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED","NETLIFY_AGENT_RUNNER_SHA","NETLIFY_TEAM_TYPE","AGENT_RUNNERS_DEBUG","NETLIFY_TEAM_ID","NETLIFY_AGENT_RUNNER_USER_ID","SITE_NAME"]),Lt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Ft(){return Object.entries(process.env).filter(([e,t])=>!(!t||Dt.has(e)||Lt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function G(e){if(typeof e!="string")return e;let t=Ft();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Ut(o),"g");r=r.replace(n,"******")}),r}function Ut(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var W=class extends $t{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=G(n);o(null,s)}};function Xe(){if(!(process.env.NETLIFY_MASK_LOGS!=="false"))return;let t=process.stdout.write.bind(process.stdout),r=process.stderr.write.bind(process.stderr);process.stdout.write=function(o,n,s){let a=typeof o=="string"?G(o):o;return typeof n=="function"?t(a,n):t(a,n,s)},process.stderr.write=function(o,n,s){let a=typeof o=="string"?G(o):o;return typeof n=="function"?r(a,n):r(a,n,s)}}var ie=null,ze=e=>(ie&&ie.destroy(),ie=new H({totalAllowedTime:e}),ie),Ze=()=>ie;var H=class{constructor({totalAllowedTime:t}){this.withStageTimer=async(t,r,o)=>{if(this.isTimeExpired())throw new Error(`${t} stage did not complete in the allowed time. Time has already expired.`);let n=this.onTimesUp(()=>{throw new Error(`${t} stage did not complete in the allowed time.`)}),s=null,a=null;o!==void 0&&(a=new Promise((u,i)=>{s=setTimeout(()=>{i(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return a?await Promise.race([r(),a]):await r()}finally{n(),s&&clearTimeout(s)}};this.startTime=Date.now(),this.totalAllowedTime=t,this.globalTimeoutId=null,this.subscribers=[],this.hasTimedOut=!1,this.setupGlobalTimeout()}getElapsedTime(){return Date.now()-this.startTime}getRemainingTime(){let t=this.getElapsedTime(),r=this.totalAllowedTime-t;return Math.max(0,r)}isTimeExpired(){return this.getRemainingTime()===0||this.hasTimedOut}setupGlobalTimeout(){this.globalTimeoutId&&clearTimeout(this.globalTimeoutId),this.globalTimeoutId=setTimeout(()=>{this.notifyTimeUp()},this.totalAllowedTime)}notifyTimeUp(){this.hasTimedOut=!0;for(let t=this.subscribers.length-1;t>=0;t--)try{this.subscribers[t]()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}}onTimesUp(t){if(this.subscribers.push(t),this.hasTimedOut)try{t()}catch(r){console.error("TimeKeeper: Error in time up callback:",r)}return()=>{let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}}off(t){let r=this.subscribers.indexOf(t);r>-1&&this.subscribers.splice(r,1)}clearSubscribers(){this.subscribers.length=0}getSubscriberCount(){return this.subscribers.length}destroy(){this.globalTimeoutId&&(clearTimeout(this.globalTimeoutId),this.globalTimeoutId=null),this.clearSubscribers()}static{this.timeUnits={seconds:t=>t*1e3,minutes:t=>t*60*1e3,hours:t=>t*60*60*1e3}}};var me=T("shell"),Ce=new Set,Mt={preferLocal:!0},Qe=(e,t,r)=>{let[o,n]=jt(t,r),s={...Mt,...n},a=Gt(e,o,s);return Yt(a,s),Ht(a),a};var jt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Yt=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(q.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new W).pipe(q.stdout),e.stdout?.pipe(new W).pipe(q.stdout),e.stderr?.pipe(new W).pipe(q.stderr);return}e.stdout?.pipe(q.stdout),e.stderr?.pipe(q.stderr)},et=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(q.kill(-e.pid,t),me.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return me.error("Error killing process:",r),!1}},Bt=e=>et(e,"SIGKILL"),Ht=e=>{Ce.add(e);let t=Ze();if(t){let r=t.onTimesUp(()=>{me.log(`Global timer expired, killing process ${e.pid}`),et(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(me.log(`Force killing process ${e.pid} after timeout`),Bt(e))},5e3)});e.on("exit",()=>{Ce.delete(e),r()}),e.on("error",()=>{Ce.delete(e),r()})}};var tt="netlify-agent-runner-context.md",Ae="task-history",Se="netlify-context",$=".netlify",J="results.md",be="assets",X="other",z="personal";var Z="enterprise",Q="free";var qt=T("utils"),Kt=e=>new Promise(t=>{setTimeout(t,e)}),rt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,a=(...u)=>{if(r)return o=u,new Promise(c=>{n.push(c)});r=!0;let i,p=new Promise(c=>{i=c});return s=(async()=>{await Promise.resolve();let c=await e(...u);for(i(c);;){if(await Kt(t),!o)return r=!1,s=null,c;let d=o,f=n;o=null,n=[],c=await e(...d),f.forEach(_=>{_(c)})}})(),p};return a.flush=async()=>{if((r||o)&&s)return await s,a.flush()},a},fe=(e,t,r=!1)=>{let o=null,n=null,s=null,a=function(...u){n=u,s=this;let i=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),i&&(e.apply(s,n),n=null,s=null)};return a.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},a.flush=()=>{if(o){clearTimeout(o);let u=n,i=s;o=null,n=null,s=null,e.apply(i,u)}},a},nt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):qt.error("Could not parse JSON",o))}},ot=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let u=`--${t}${n}`;if(u.length>55)return"";let i=60-u.length;if(i<=0)return"";if(i>=s.length+6){let p=Math.min(i-s.length,e.length);return`${s}${e.slice(0,p)}`}return e.slice(0,i)};import{Buffer as st}from"buffer";import Vt from"path";var it=async({config:e,netlify:t})=>{let r=await Jt(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await Xt(n);await t.utils.run("git",["add",".",...s]);let a={stdio:["ignore","pipe","pipe"]},i=(await t.utils.run("git",["diff","--staged"],a)).stdout;if(o=!!i,!o)return{hasChanges:!1,ignored:s};let c=(await t.utils.run("git",["diff","--staged","--binary"],a)).stdout,d,f;if(e.sha){await t.utils.run("git",["commit","-m","Agent runner"]),d=(await t.utils.run("git",["diff",e.sha,"HEAD"],a)).stdout;let x=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],a)).stdout;d!==x&&(f=st.from(x).toString("base64"))}let _={hasChanges:!0,diff:i,resultDiff:d,ignored:s};return i!==c&&(_.diffBinary=st.from(c).toString("base64")),f&&(_.resultDiffBinary=f),_},Wt=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],Jt=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
8
8
  `).filter(n=>!Wt.some(s=>s instanceof RegExp?s.test(n):n===s))).length!==0,status:t.stdout}};var at=async e=>{let{stdout:t}=await e.utils.run("git",["rev-parse","HEAD"]);return t.trim()},lt=async e=>{let{stdout:t}=await e.utils.run("git",["rev-list","--max-parents=0","HEAD"]);return t.trim()},Xt=async e=>{let t=[".netlify","mise.toml","deno.lock","node_modules"],r=[];return e.split(`
9
9
  `).forEach(o=>{t.forEach(s=>{[`?? ${s}`,`?? ${s}${Vt.sep}`].some(u=>o.startsWith(u))&&r.push(`:!${s}`)});let n=o.match(/\?\? (.+?)\.log$/)?.[1];n&&r.push(`:!${n}.log`)}),r};import Zt from"fs/promises";import Qt from"os";import ge from"path";import j from"process";import er from"readline";import ve from"path";import zt from"fs/promises";var Pe=T("agent-output-utils");async function ee({initialResult:e,agentName:t,hasError:r}){let o="",n=ve.join(process.cwd(),$,J);try{let s=await zt.readFile(n,"utf-8");s&&(o=s,Pe.log(`Pulled result from ${ve.relative(process.cwd(),n)}`))}catch{Pe.log(`No results file found at ${ve.relative(process.cwd(),n)}`)}return o||(!e&&!r?`${t} has finished working on task.`:e||void 0)}function te({error:e,agentName:t}){let r=e&&typeof e=="object"?JSON.stringify(e):e,o=r?.replace(/\s+/g," ").trim().toLowerCase()||"",n="";return o?.includes("ai gateway is not available for your account")||o?.includes("ai gateway is not enabled for your account")?n="AI Gateway is currently not available on your account. Please confirm your account meets the criteria for using Agent Runners and AI Gateway and that your account has remaining AI Gateway inference credits available. Reach out to Netlify support if this is unexpected.":o?.includes("error when talking to gemini api")?n="Gemini's API is currently having issues. Please try again or use a different available agent while Google resolves the issue.":(o?.includes("connection closed prematurely")||o?.includes("499")&&t.toLowerCase().includes("gemini"))&&(n=`The ${t} models were currently overloaded. Please try again or use a different available agent.`),o?.includes("request timed out")&&(n=`The ${t} API request's have timed out. Please try again or use a different available agent.`),o?.includes("network error")&&(n=`The ${t} agent is having network issues. Please try again or use a different available agent.`),n&&Pe.log(`Providing updated error messsage: ${n}, replacing original error: ${r}`),n||r||void 0}function re(e){if(!e)return!1;let r=(e&&typeof e=="object"?JSON.stringify(e):e)?.replace(/\s+/g," ").trim().toLowerCase()||"";return!!(r?.includes("error when talking to gemini api")||r?.includes("499")||r?.includes("connection closed prematurely")||r?.includes("request timed out")||r?.includes("network error"))}var L=T("runner_claude"),ut="Claude Code",tr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(L.log(`${n} command completed with catch handler triggered`,{hadExistingError:!!r,hadExistingResult:!!o,resultLength:o?o.length:0,catchError:e?.message||"No error object",processExitCode:t.exitCode,processKilled:t.killed}),o?(L.log("Preserving existing result despite catch handler being triggered"),r?{error:r,result:o}:{error:"Process completed with errors but result was captured",result:o}):(L.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function Oe({config:e,netlify:t,persistSteps:r,aiGateway:o}){let n=e,{accountType:s,prompt:a,modelVersionOverrides:u}=n,{model:i}=n;if(o){let{token:R,url:m}=o;if(!R||!m)throw new Error("No token or url provided from AI Gateway");let l=rr[s];if(!l)throw new Error(`Claude is not supported for the account type ${s}`);if(i&&!l?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.claude){let h=u?.claude?.[s];h&&(i=h)}j.env.ANTHROPIC_API_KEY=R,j.env.ANTHROPIC_BASE_URL=m}else if(!j.env.ANTHROPIC_API_KEY)throw new Error("ANTHROPIC_API_KEY is not provided");let p=[],c=[],d={},f=0,_=0,g,y,x=ge.join(j.cwd(),"node_modules"),I=[ge.join(j.env.NODE_PATH||x,".bin/claude"),"--permission-mode","bypassPermissions","--dangerously-skip-permissions","--output-format","stream-json","--verbose",...i?["--model",i]:[],"-p",a],N=`${j.env.NVM_BIN}/node`;L.log(`Running ${N} ${I.join(" ")}`);let S=t.utils.run(N,I,{all:!0,env:j.env});S.stdin?.end();let C=fe(()=>{r?.({steps:p,duration:_})},250),w=(R,m)=>{let l={...R,id:f};f+=1,c.push(l),p.push(l),m||C.flush(),C(),m&&C.flush()},E=er.createInterface({input:S.all});return E.on("error",R=>{L.error("Readline interface error",{error:R.message,stack:R.stack})}),E.on("line",R=>{let m=null;try{m=JSON.parse(R)}catch{L.log("Could not parse line",R)}Array.isArray(m?.message?.content)?m.message.content.forEach(l=>{switch(l.type){case"text":{l.text&&w({message:l.text});break}case"image":{typeof l.source=="object"&&l.source&&l.source.type==="base64"&&l.source.media_type?w({message:`![](data:${l.source.media_type};base64,${l.source.data})`}):L.log(`Unsupported image type ${l.source?.type}`,l.source);break}case"tool_use":{if(l.name==="Task"){let h=l.input?.description&&`\`${l.input.description}\``;w({title:[l.name,h].filter(Boolean).join(" ")})}else l.id&&(d[l.id]=l);C.flush();break}case"tool_result":{let h=l.tool_use_id?d[l.tool_use_id]:void 0,A;if(h){let F=h.input?.file_path&&ge.relative(j.cwd(),h.input.file_path),b=F&&`\`${F}\``;A=[h.name,b].filter(Boolean).join(" ")}let M=["Bash","Glob","Grep","LS","Read","Edit","Write"].includes(h?.name||""),k;if(typeof l.content=="string")k=l.content;else if(Array.isArray(l.content)){let F=[];l.content.forEach(b=>{b?.type==="text"&&typeof b.text=="string"?F.push(b.text):b?.type==="image"&&typeof b.source=="object"&&b.source?b.source.type==="base64"&&b.source.media_type?F.push(`![](data:${b.source.media_type};base64,${b.source.data})`):L.log(`Unsupported image type ${b.source.type}`,b.source):L.log(`Unsupported block type ${b?.type}`)}),k=F.join(`
10
10
 
@@ -127,5 +127,5 @@ Below are all of the logs with potential issues that we extracted. Some of them
127
127
 
128
128
  ${e.pop()}
129
129
  `;import Pr from"process";import{getTracer as Fe}from"@netlify/otel";import{getTracer as br}from"@netlify/otel";var le=T("deploy"),Tt=async e=>await v(br(),"create-preview-deploy",async t=>vr(e,t)),vr=async({netlify:e,hasRepo:t,skipBuild:r,message:o="Agent Preview",deploySubdomain:n,cliPath:s,filter:a},u)=>{try{let i=["deploy","--message",`"${o}"`,"--json","--draft","--verbose"];t||(le.log("Deploy: Uploading source zip"),i.push("--upload-source-zip")),n&&i.push("--alias",n),a&&i.push("--filter",a),r?(le.log("Deploy: Skipping build"),i.push("--no-build")):i.push("--context","deploy-preview");let p=s||"netlify";le.log(`Running: ${p} ${i.join(" ")}`),u?.setAttributes({cmd:p,args:i});let c=await e.utils.run(p,i,{stdio:["ignore","pipe","pipe"]}),d=JSON.parse(c.stdout.trim());u?.setAttributes({success:!0,deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id}),le.log(`
130
- Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let f={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(f.sourceZipFilename=d.source_zip_filename),f}catch(i){throw le.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var ue=T("deploy_stage"),Ue=async e=>await v(Fe(),"run-deploy-stage",async()=>Or(e)),Or=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await v(Fe(),"get-runner-diffs",async()=>await it({config:t,netlify:r}));if(ue.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges)return{diff:"",hasChanges:!1,previewInfo:null};let{diff:a,resultDiff:u,diffBinary:i,resultDiffBinary:p}=s,c=!0;ue.log("Preview deploy condition check:",{resultUndefined:o===void 0,resultType:typeof o,hasChanges:c,wouldCreatePreview:o!==void 0&&c});let d=null;if(o!==void 0&&c)try{let f;try{let _=await v(Fe(),"get-runner-session",async()=>await Ke(t.id,t.sessionId));_?.title&&(f=_.title)}catch(_){ue.warn("Failed to fetch session title, using fallback message:",_.message)}await U(t.id,t.sessionId,{steps:[{title:"Deploying the run preview"}]}),d=await Tt({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:f,skipBuild:!1,deploySubdomain:ot(t.id,Pr.env.SITE_NAME),filter:n})}catch(f){return ue.warn("Failed to create preview deploy (continuing with agent run):",f),{diff:a,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:f instanceof Error?f.message:String(f)}}return ue.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:u,hasChanges:c,previewInfo:d,diffBinary:i,resultDiffBinary:p}};import{getTracer as Ge}from"@netlify/otel";async function xt(e,t){let{maxRetries:r,baseDelay:o,onRetry:n}=t,s;for(let a=1;a<=r;a++)try{return await e()}catch(u){if(s=u,a===r)throw s;n&&n(a,s),await new Promise(i=>setTimeout(i,o*a))}throw s}var oe=T("cleanup_stage"),wt=async e=>await v(Ge(),"cleanup-stage",async()=>kr(e)),kr=async({config:e,diff:t,result:r,duration:o,resultDiff:n,diffBinary:s,resultDiffBinary:a,previewInfo:u})=>{let i={result_diff:t,result:r||"Done",duration:o,result_diff_binary:s};return u&&u.deployId&&(i.deploy_id=u.deployId),u&&u.sourceZipFilename&&(i.result_zip_file_name=u.sourceZipFilename),n||a?(oe.log("Updating total agent result diff"),await v(Ge(),"update-runner",async()=>{await de(e.id,{result_diff:n,result_diff_binary:a})})):oe.log("No total result diff, not updating"),oe.log("Updated agent runner with result"),await xt(async()=>await v(Ge(),"update-runner-session",()=>U(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{oe.error(`Error updating agent runner session (attempt ${p}):`,c),oe.log("Retrying...")}}),oe.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as Rt,withActiveSpan as It}from"@netlify/otel";var Dr=$r(import.meta.url),Nt=Dr("../package.json"),Ct=T("pipeline_index"),xe=3,as=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,tracing:a={}})=>{let u,{withStageTimer:i}=ze(H.timeUnits.hours(4)),p=await Be(Nt.version,e.id,a);try{await It(Rt(),"run-pipeline",{},p,async()=>{let c,{aiGateway:d,context:f,persistSteps:_,runner:g,sha:y}=await i("init",()=>ht({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:Nt.version}),H.timeUnits.minutes(10));u=g.clean,e.sha=y;let{runnerResult:x}=await i("inference",()=>Te({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:_,aiGateway:d}));await U(e.id,e.sessionId,{steps:[{title:"Building and deploying the preview"}]});let I=await i("deploy",()=>Ue({cliPath:r,config:e,context:f,result:x.result,filter:s})),N=x,S=[];if(I.hasChanges&&I.deployError){S.push(He(I.deployError));let l=1;for(;l<=xe&&!I.previewInfo;)Ct.log(`Deploy attempt had errors. Retrying. ${l}/${xe}`),await It(Rt(),"deploy-stage",async h=>{h?.setAttributes({"stage.attempt":l});let{runnerResult:A}=await i(`inference-retry-${l}`,()=>Te({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:_,aiGateway:d,buildErrors:S}));N={...A,steps:[...N.steps||[],...A.steps||[]],duration:(N.duration||0)+(A.duration||0)},I=await i(`deploy-retry-${l}`,()=>Ue({cliPath:r,config:e,context:f,result:A.result,filter:s})),I.deployError&&S.push(I.deployError),l++});l>xe&&!I.previewInfo&&(c=new Error(`Deploy validation failed after ${xe} attempts`))}let{diff:C,resultDiff:w,previewInfo:E,diffBinary:R,resultDiffBinary:m}=I;if(await i("cleanup",()=>wt({config:e,diff:C,result:N.result,duration:N.duration,resultDiff:w,diffBinary:R,resultDiffBinary:m,previewInfo:E}),H.timeUnits.minutes(10)),c)throw c;await g.clean?.()})}catch(c){Ct.error("Got error while running pipeline",c),await u?.();let d=c instanceof Error&&c.message;throw await U(e.id,e.sessionId,{result:d||"Encountered error when running agent",state:"error"}),c}};export{as as runPipeline};
130
+ Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let f={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(f.sourceZipFilename=d.source_zip_filename),f}catch(i){throw le.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var ue=T("deploy_stage"),Ue=async e=>await v(Fe(),"run-deploy-stage",async()=>Or(e)),Or=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await v(Fe(),"get-runner-diffs",async()=>await it({config:t,netlify:r}));if(ue.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges)return{diff:"",hasChanges:!1,previewInfo:null};let{diff:a,resultDiff:u,diffBinary:i,resultDiffBinary:p}=s,c=!0;ue.log("Preview deploy condition check:",{resultUndefined:o===void 0,resultType:typeof o,hasChanges:c,wouldCreatePreview:o!==void 0&&c});let d=null;if(o!==void 0&&c)try{let f;try{let _=await v(Fe(),"get-runner-session",async()=>await Ke(t.id,t.sessionId));_?.title&&(f=_.title)}catch(_){ue.warn("Failed to fetch session title, using fallback message:",_.message)}await U(t.id,t.sessionId,{steps:[{title:"Deploying the run preview"}]}),d=await Tt({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:f,skipBuild:!1,deploySubdomain:ot(t.id,Pr.env.SITE_NAME),filter:n})}catch(f){return ue.warn("Failed to create preview deploy (continuing with agent run):",f),{diff:a,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:f instanceof Error?f.message:String(f)}}return ue.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:u,hasChanges:c,previewInfo:d,diffBinary:i,resultDiffBinary:p}};import{getTracer as Ge}from"@netlify/otel";async function xt(e,t){let{maxRetries:r,baseDelay:o,onRetry:n}=t,s;for(let a=1;a<=r;a++)try{return await e()}catch(u){if(s=u,a===r)throw s;n&&n(a,s),await new Promise(i=>setTimeout(i,o*a))}throw s}var oe=T("cleanup_stage"),wt=async e=>await v(Ge(),"cleanup-stage",async()=>kr(e)),kr=async({config:e,diff:t,result:r,duration:o,resultDiff:n,diffBinary:s,resultDiffBinary:a,previewInfo:u})=>{let i={result_diff:t,result:r||"Done",duration:o,result_diff_binary:s};return u&&u.deployId&&(i.deploy_id=u.deployId),u&&u.sourceZipFilename&&(i.result_zip_file_name=u.sourceZipFilename),n||a?(oe.log("Updating total agent result diff"),await v(Ge(),"update-runner",async()=>{await de(e.id,{result_diff:n,result_diff_binary:a})})):oe.log("No total result diff, not updating"),oe.log("Updated agent runner with result"),await xt(async()=>await v(Ge(),"update-runner-session",()=>U(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{oe.error(`Error updating agent runner session (attempt ${p}):`,c),oe.log("Retrying...")}}),oe.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as Rt,shutdownTracers as Dr,withActiveSpan as It}from"@netlify/otel";var Lr=$r(import.meta.url),Nt=Lr("../package.json"),Ct=T("pipeline_index"),xe=3,ls=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,tracing:a={}})=>{let u,{withStageTimer:i}=ze(H.timeUnits.hours(4)),p=await Be(Nt.version,e.id,a);try{await It(Rt(),"run-pipeline",{},p,async()=>{let c,{aiGateway:d,context:f,persistSteps:_,runner:g,sha:y}=await i("init",()=>ht({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:Nt.version}),H.timeUnits.minutes(10));u=g.clean,e.sha=y;let{runnerResult:x}=await i("inference",()=>Te({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:_,aiGateway:d}));await U(e.id,e.sessionId,{steps:[{title:"Building and deploying the preview"}]});let I=await i("deploy",()=>Ue({cliPath:r,config:e,context:f,result:x.result,filter:s})),N=x,S=[];if(I.hasChanges&&I.deployError){S.push(He(I.deployError));let l=1;for(;l<=xe&&!I.previewInfo;)Ct.log(`Deploy attempt had errors. Retrying. ${l}/${xe}`),await It(Rt(),"deploy-stage",async h=>{h?.setAttributes({"stage.attempt":l});let{runnerResult:A}=await i(`inference-retry-${l}`,()=>Te({cliPath:r,config:e,context:f,runner:g.runner,persistSteps:_,aiGateway:d,buildErrors:S}));N={...A,steps:[...N.steps||[],...A.steps||[]],duration:(N.duration||0)+(A.duration||0)},I=await i(`deploy-retry-${l}`,()=>Ue({cliPath:r,config:e,context:f,result:A.result,filter:s})),I.deployError&&S.push(I.deployError),l++});l>xe&&!I.previewInfo&&(c=new Error(`Deploy validation failed after ${xe} attempts`))}let{diff:C,resultDiff:w,previewInfo:E,diffBinary:R,resultDiffBinary:m}=I;if(await i("cleanup",()=>wt({config:e,diff:C,result:N.result,duration:N.duration,resultDiff:w,diffBinary:R,resultDiffBinary:m,previewInfo:E}),H.timeUnits.minutes(10)),c)throw c;await g.clean?.()})}catch(c){Ct.error("Got error while running pipeline",c),await u?.();let d=c instanceof Error&&c.message;throw await U(e.id,e.sessionId,{result:d||"Encountered error when running agent",state:"error"}),c}finally{await Dr()}};export{ls as runPipeline};
131
131
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/agent-runner-cli",
3
3
  "type": "module",
4
- "version": "1.41.0",
4
+ "version": "1.41.1",
5
5
  "description": "CLI tool for running Netlify agents",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",