@netlify/agent-runner-cli 1.39.1 → 1.41.0

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,23 +1,23 @@
1
1
  #!/usr/bin/env node
2
- import Ge from"process";import $r from"minimist";import{createRequire as Or}from"module";import{createTracerProvider as St}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as Ye}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as Pt}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as vt}from"@netlify/otel";import{OTLPTraceExporter as Ot}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 Re=_("tracing"),Me=(e,t,r)=>St({serviceName:"@netlify/agent-runner-cli",serviceVersion:e,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:t,spanProcessors:[new Ye(new Ne),new Ye(new Ot({url:r}))],instrumentations:[new Pt({skipHeaders:!0})]});function w(e,t,r){return Re.log(`\u23F3 TRACE: ${t} starting...`),vt(e,t,r)}var Ne=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(", ")}]`:"";Re.log(`${s} TRACE: ${t.name} completed in ${r.toFixed(2)}ms${a}`),t.status?.code===2&&t.status.message&&Re.log(` \u274C Error: ${t.status.message}`)}};var kt=["error","failed","exception","fatal","panic","abort","crash"];function je(e){let t=e.split(`
3
- `),r=[],o=-1,n=0;for(;n<t.length;){let u=t[n].slice(0,500).toLowerCase();if(kt.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 m=p;m<=c;m++)d.push(t[m]);r.push(d.join(`
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(`
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 Ee from"process";import{getTracer as mr}from"@netlify/otel";import ce from"process";var Ie=ce.env.NETLIFY_API_URL,we=ce.env.NETLIFY_API_TOKEN,ae=_("api"),pe=async(e,t={})=>{if(!Ie||!we)throw new Error("No API URL or token");let r=new URL(e,Ie),o={...t,headers:{...t.headers,Authorization:`Bearer ${we}`}};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")ae.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{ae.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");ae.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||ae.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},Be=e=>{ae.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&&(we=e.constants.NETLIFY_API_TOKEN)},de=(e,t)=>pe(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),V=(e,t,r)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var He=(e,t)=>pe(`/api/v1/agent_runners/${e}/sessions/${t}`),qe=(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=_("ai_gateway"),Ve=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 qe(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 Ut,execaCommand as on}from"execa";import{Transform as Lt}from"stream";var bt=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"]),Dt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Ft(){return Object.entries(process.env).filter(([e,t])=>!(!t||bt.has(e)||Dt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function z(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($t(o),"g");r=r.replace(n,"******")}),r}function $t(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var Z=class extends Lt{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=z(n);o(null,s)}};function Ke(){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"?z(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"?z(o):o;return typeof n=="function"?r(a,n):r(a,n,s)}}var ln=_("shell"),Gt={preferLocal:!0},Xe=(e,t,r)=>{let[o,n]=Yt(t,r),s={...Gt,...n},a=Ut(e,o,s);return Mt(a,s),a};var Yt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Mt=(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 Z).pipe(Q.stdout),e.stdout?.pipe(new Z).pipe(Q.stdout),e.stderr?.pipe(new Z).pipe(Q.stderr);return}e.stdout?.pipe(Q.stdout),e.stderr?.pipe(Q.stderr)};var Je="netlify-agent-runner-context.md",Ae="task-history",Ce="netlify-context",D=".netlify",ee="results.md",Se="assets",G="other",Y="personal";var M="enterprise",j="free",ze=[Y,"pro",M,j];var Ze=_("utils"),jt=e=>new Promise(t=>{setTimeout(t,e)}),Qe=(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 jt(t),!o)return r=!1,s=null,c;let d=o,m=n;o=null,n=[],c=await e(...d),m.forEach(T=>{T(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},me=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):Ze.error("Could not parse JSON",o))}},et=(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)},Bt=e=>!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0?!1:!!ze.some(t=>t in e),tt=()=>{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);Bt(s)&&(e[r]=s)}catch(s){let u=s instanceof SyntaxError?"Invalid JSON":s.message;Ze.error(`Could not parse ${r} model version override from ${n}: ${u}`)}}}),e};import{Buffer as rt}from"buffer";import Ht from"path";var nt=async({config:e,netlify:t})=>{let r=await Wt(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await Vt(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,m;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 h=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],a)).stdout;d!==h&&(m=rt.from(h).toString("base64"))}let T={hasChanges:!0,diff:i,resultDiff:d,ignored:s};return i!==c&&(T.diffBinary=rt.from(c).toString("base64")),m&&(T.resultDiffBinary=m),T},qt=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],Wt=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
9
- `).filter(n=>!qt.some(s=>s instanceof RegExp?s.test(n):n===s))).length!==0,status:t.stdout}};var ot=async e=>{let{stdout:t}=await e.utils.run("git",["rev-parse","HEAD"]);return t.trim()},st=async e=>{let{stdout:t}=await e.utils.run("git",["rev-list","--max-parents=0","HEAD"]);return t.trim()},Vt=async e=>{let t=[".netlify","mise.toml","deno.lock","node_modules"],r=[];return e.split(`
10
- `).forEach(o=>{t.forEach(s=>{[`?? ${s}`,`?? ${s}${Ht.sep}`].some(u=>o.startsWith(u))&&r.push(`:!${s}`)});let n=o.match(/\?\? (.+?)\.log$/)?.[1];n&&r.push(`:!${n}.log`)}),r};import Xt from"fs/promises";import Jt from"os";import ge from"path";import H from"process";import zt from"readline";import Pe from"path";import Kt from"fs/promises";var ve=_("agent-output-utils");async function te({initialResult:e,agentName:t,hasError:r}){let o="",n=Pe.join(process.cwd(),D,ee);try{let s=await Kt.readFile(n,"utf-8");s&&(o=s,ve.log(`Pulled result from ${Pe.relative(process.cwd(),n)}`))}catch{ve.log(`No results file found at ${Pe.relative(process.cwd(),n)}`)}return o||(!e&&!r?`${t} has finished working on task.`:e||void 0)}function re({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&&ve.log(`Providing updated error messsage: ${n}, replacing original error: ${r}`),n||r||void 0}function ne(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 $=_("runner_claude"),it="Claude Code",Zt=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>($.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?($.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}):($.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:f}=o;if(!R||!f)throw new Error("No token or url provided from AI Gateway");let l=Qt[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 E=u?.claude?.[s];E&&(i=E)}H.env.ANTHROPIC_API_KEY=R,H.env.ANTHROPIC_BASE_URL=f}else if(!H.env.ANTHROPIC_API_KEY)throw new Error("ANTHROPIC_API_KEY is not provided");let p=[],c=[],d={},m=0,T=0,y,g,h=ge.join(H.cwd(),"node_modules"),A=[ge.join(H.env.NODE_PATH||h,".bin/claude"),"--permission-mode","bypassPermissions","--dangerously-skip-permissions","--output-format","stream-json","--verbose",...i?["--model",i]:[],"-p",a],S=`${H.env.NVM_BIN}/node`;$.log(`Running ${S} ${A.join(" ")}`);let P=t.utils.run(S,A,{all:!0,env:H.env});P.stdin?.end();let I=fe(()=>{r?.({steps:p,duration:T})},250),N=(R,f)=>{let l={...R,id:m};m+=1,c.push(l),p.push(l),f||I.flush(),I(),f&&I.flush()},x=zt.createInterface({input:P.all});return x.on("error",R=>{$.error("Readline interface error",{error:R.message,stack:R.stack})}),x.on("line",R=>{let f=null;try{f=JSON.parse(R)}catch{$.log("Could not parse line",R)}Array.isArray(f?.message?.content)?f.message.content.forEach(l=>{switch(l.type){case"text":{l.text&&N({message:l.text});break}case"image":{typeof l.source=="object"&&l.source&&l.source.type==="base64"&&l.source.media_type?N({message:`![](data:${l.source.media_type};base64,${l.source.data})`}):$.log(`Unsupported image type ${l.source?.type}`,l.source);break}case"tool_use":{if(l.name==="Task"){let E=l.input?.description&&`\`${l.input.description}\``;N({title:[l.name,E].filter(Boolean).join(" ")})}else l.id&&(d[l.id]=l);I.flush();break}case"tool_result":{let E=l.tool_use_id?d[l.tool_use_id]:void 0,v;if(E){let U=E.input?.file_path&&ge.relative(H.cwd(),E.input.file_path),C=U&&`\`${U}\``;v=[E.name,C].filter(Boolean).join(" ")}let B=["Bash","Glob","Grep","LS","Read","Edit","Write"].includes(E?.name||""),b;if(typeof l.content=="string")b=l.content;else if(Array.isArray(l.content)){let U=[];l.content.forEach(C=>{C?.type==="text"&&typeof C.text=="string"?U.push(C.text):C?.type==="image"&&typeof C.source=="object"&&C.source?C.source.type==="base64"&&C.source.media_type?U.push(`![](data:${C.source.media_type};base64,${C.source.data})`):$.log(`Unsupported image type ${C.source.type}`,C.source):$.log(`Unsupported block type ${C?.type}`)}),b=U.join(`
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(`
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
+ `).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
 
12
- `)}B&&b&&(b=`\`\`\`
13
- ${b.trim()}
14
- \`\`\``),N({title:v,message:b},!0);break}case"thinking":{l.thinking&&N({title:"Thinking",message:l.thinking},!0);break}default:$.log(`Message content type is not supported ${l.type}`,l)}}):f?.type==="result"&&(T=f.duration_ms||0,f.is_error?g=f.result:y=f.result,[c,p].forEach(l=>{l[l.length-1]?.message===y&&l.pop()}))}),await P.catch(R=>{({error:g,result:y}=Zt({catchError:R,runCmd:P,error:g,result:y,runnerName:"Claude"}))}),x.close(),I.flush(),{steps:c,duration:T,result:await te({initialResult:y,agentName:it,hasError:!!g}),error:re({error:g,agentName:it}),isRetryableError:ne(g)}}var at=async()=>{let e=ge.join(Jt.homedir(),".claude");await Xt.rm(e,{recursive:!0,force:!0})},Qt={[M]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:64e3},"claude-3-haiku-20240307":{maxTokens:4096},"claude-opus-4-20250514":{maxTokens:32e3},"claude-sonnet-4-20250514":{maxTokens:64e3}}},pro:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[Y]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[j]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}},[G]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}}};import er from"fs/promises";import tr from"os";import ke from"path";import X from"process";import rr from"readline";var J=_("runner_codex"),lt="Codex CLI",nr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(J.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?(J.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}):(J.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function Le({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:N,url:x}=n;if(!N||!x)throw new Error("No token or url provided from AI Gateway");let R=or[s];if(!R)throw new Error(`Codex is not supported for the account type ${s}`);if(i&&!R?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.codex){let f=u?.codex?.[s];f&&(i=f)}X.env.OPENAI_API_KEY=N,X.env.OPENAI_BASE_URL=x}else if(!X.env.OPENAI_API_KEY)throw new Error("OPENAI_API_KEY is not provided");let p=[],c=[],d={},m=0,T=0,y,g,h=ke.join(X.cwd(),"node_modules"),A=[ke.join(X.env.NODE_PATH||h,".bin/codex"),"--approval-mode","full-auto",n?"--disable-response-storage":void 0,"--dangerously-auto-approve-everything",...i?["--model",i]:[],"-q",a].filter(Boolean),S=`${X.env.NVM_BIN}/node`;J.log(`Running ${S} ${A.join(" ")}`);let P=t.utils.run(S,A,{all:!0,env:{...X.env,CODEX_UNSAFE_ALLOW_NO_SANDBOX:"1"}}),I=rr.createInterface({input:P.all});return I.on("error",N=>{J.error("Readline interface error",{error:N.message,stack:N.stack})}),I.on("line",N=>{let x=null;try{x=JSON.parse(N)}catch{J.log("Could not parse line",N);return}let R=[],f=!1;if(x?.duration_ms&&(T=x.duration_ms,f=!0),x?.type==="local_shell_call")d[x.call_id]=x;else if(x?.type==="local_shell_call_output"){let l=ir(d[x.call_id],x);l&&(l.id=m,m+=1,c.push(l),p.push(l),R.push(l),f=!0)}else x?.type==="message"&&x.role==="assistant"?y=x.content.map(l=>l.text).join(`
15
- `):x?.type==="message"&&x.role==="system"&&(g=x.content.map(l=>l.text).join(`
16
- `));f&&(r?.({steps:p,duration:T}),o?.({steps:R,duration:T}))}),await P.catch(N=>{let x=nr({catchError:N,runCmd:P,error:g,result:y,runnerName:"Codex"});g=x.error,y=x.result}),I.close(),{steps:c,duration:T,result:await te({initialResult:y,agentName:lt,hasError:!!g}),error:re({error:g,agentName:lt}),isRetryableError:ne(g)}}var ut=async()=>{let e=ke.join(tr.homedir(),".codex");await er.rm(e,{recursive:!0,force:!0})},or={[M]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},o1:{maxTokens:1e5},"o1-mini":{maxTokens:65536},"o3-mini":{maxTokens:1e5},"gpt-image-1":{},"dall-e-2":{},"dall-e-3":{}}},[Y]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},pro:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},[j]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}},[G]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}}},sr=new Set(["bash","-lc"]),ir=(e,t)=>{if(!e||!t||e.call_id!==t.call_id)return null;let r=e.action?.command?.filter(s=>!sr.has(s)),o=r?`Running \`${r.join(" ")}\``:void 0,n;try{n=JSON.parse(t.output).output?.trim(),n&&(n=`\`\`\`
12
+ `)}q&&L&&(L=`\`\`\`
13
+ ${L.trim()}
14
+ \`\`\``),R({title:C,message:L},!0);break}case"thinking":{l.thinking&&R({title:"Thinking",message:l.thinking},!0);break}default:F.log(`Message content type is not supported ${l.type}`,l)}}):m?.type==="result"&&(T=m.duration_ms||0,m.is_error?E=m.result:g=m.result,[c,p].forEach(l=>{l[l.length-1]?.message===g&&l.pop()}))}),await S.catch(w=>{({error:E,result:g}=pr({catchError:w,runCmd:S,error:E,result:g,runnerName:"Claude"}))}),x.close(),A.flush(),{steps:c,duration:T,result:await ne({initialResult:g,agentName:gt,hasError:!!E}),error:oe({error:E,agentName:gt}),isRetryableError:se(E)}}var ht=async()=>{let e=_e.join(ur.homedir(),".claude");await lr.rm(e,{recursive:!0,force:!0})},dr={[B]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:64e3},"claude-3-haiku-20240307":{maxTokens:4096},"claude-opus-4-20250514":{maxTokens:32e3},"claude-sonnet-4-20250514":{maxTokens:64e3}}},pro:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[j]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[H]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}},[Y]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}}};import mr from"fs/promises";import fr from"os";import $e from"path";import Z from"process";import gr from"readline";var Q=_("runner_codex"),Et="Codex CLI",hr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(Q.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?(Q.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}):(Q.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function Fe({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:R,url:x}=n;if(!R||!x)throw new Error("No token or url provided from AI Gateway");let w=Er[s];if(!w)throw new Error(`Codex is not supported for the account type ${s}`);if(i&&!w?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.codex){let m=u?.codex?.[s];m&&(i=m)}Z.env.OPENAI_API_KEY=R,Z.env.OPENAI_BASE_URL=x}else if(!Z.env.OPENAI_API_KEY)throw new Error("OPENAI_API_KEY is not provided");let p=[],c=[],d={},f=0,T=0,g,E,y=$e.join(Z.cwd(),"node_modules"),N=[$e.join(Z.env.NODE_PATH||y,".bin/codex"),"--approval-mode","full-auto",n?"--disable-response-storage":void 0,"--dangerously-auto-approve-everything",...i?["--model",i]:[],"-q",a].filter(Boolean),I=`${Z.env.NVM_BIN}/node`;Q.log(`Running ${I} ${N.join(" ")}`);let S=t.utils.run(I,N,{all:!0,env:{...Z.env,CODEX_UNSAFE_ALLOW_NO_SANDBOX:"1"}}),A=gr.createInterface({input:S.all});return A.on("error",R=>{Q.error("Readline interface error",{error:R.message,stack:R.stack})}),A.on("line",R=>{let x=null;try{x=JSON.parse(R)}catch{Q.log("Could not parse line",R);return}let w=[],m=!1;if(x?.duration_ms&&(T=x.duration_ms,m=!0),x?.type==="local_shell_call")d[x.call_id]=x;else if(x?.type==="local_shell_call_output"){let l=Tr(d[x.call_id],x);l&&(l.id=f,f+=1,c.push(l),p.push(l),w.push(l),m=!0)}else x?.type==="message"&&x.role==="assistant"?g=x.content.map(l=>l.text).join(`
15
+ `):x?.type==="message"&&x.role==="system"&&(E=x.content.map(l=>l.text).join(`
16
+ `));m&&(r?.({steps:p,duration:T}),o?.({steps:w,duration:T}))}),await S.catch(R=>{let x=hr({catchError:R,runCmd:S,error:E,result:g,runnerName:"Codex"});E=x.error,g=x.result}),A.close(),{steps:c,duration:T,result:await ne({initialResult:g,agentName:Et,hasError:!!E}),error:oe({error:E,agentName:Et}),isRetryableError:se(E)}}var _t=async()=>{let e=$e.join(fr.homedir(),".codex");await mr.rm(e,{recursive:!0,force:!0})},Er={[B]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},o1:{maxTokens:1e5},"o1-mini":{maxTokens:65536},"o3-mini":{maxTokens:1e5},"gpt-image-1":{},"dall-e-2":{},"dall-e-3":{}}},[j]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},pro:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},[H]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}},[Y]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}}},_r=new Set(["bash","-lc"]),Tr=(e,t)=>{if(!e||!t||e.call_id!==t.call_id)return null;let r=e.action?.command?.filter(s=>!_r.has(s)),o=r?`Running \`${r.join(" ")}\``:void 0,n;try{n=JSON.parse(t.output).output?.trim(),n&&(n=`\`\`\`
17
17
  ${n.trim()}
18
- \`\`\``)}catch(s){J.error("Could not decode outputMsg",s,t.output)}return{title:o,message:n}};import ar from"fs/promises";import lr from"os";import he from"path";import q from"process";import ur from"readline";var oe=_("runner_gemini"),ct="Gemini CLI",cr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(oe.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?(oe.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}):(oe.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0})),pr={list_directory:"List",read_file:"Read",write_file:"Write",glob:"Find",search_file_content:"Find",replace:"Edit",run_shell_command:"Run",web_fetch:"Web Fetch",web_search:"Web Search",read_many_files:"Read Many",save_memory:"Memorize"};async function be({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:f,url:l}=n;if(!f||!l)throw new Error("No token or url provided from AI Gateway");let E=dr[s];if(!E)throw new Error(`Gemini is not supported for the account type ${s}`);if(i&&!E?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.gemini){let v=u?.gemini?.[s];v&&(i=v)}q.env.GEMINI_API_KEY=f,q.env.GOOGLE_GEMINI_BASE_URL=l}else if(!q.env.GEMINI_API_KEY)throw new Error("GEMINI_API_KEY is not provided");let p=[],c=[],d=[],m={},T=0,y=0,g,h,A=he.join(q.cwd(),"node_modules"),S=[he.join(q.env.NODE_PATH||A,".bin/gemini"),...i?["--model",i]:[],"--yolo","-p",a],P=`${q.env.NVM_BIN}/node`;oe.log(`Running ${P} ${S.join(" ")}`);let I=t.utils.run(P,S,{all:!0,env:q.env});I.stdin?.end();let N=fe(()=>{r?.({steps:p,duration:y}),o?.({steps:c,duration:y}),c=[]},250),x=(f,l)=>{f.id=T,T+=1,d.push(f),p.push(f),c.push(f),l||N.flush(),N(),l&&N.flush()},R=ur.createInterface({input:I.all});return R.on("error",f=>{oe.error("Readline interface error",{error:f.message,stack:f.stack})}),R.on("line",f=>{let l=null;try{if(f.startsWith("[API Error")){let E=f.match(/\[api error: (.+?)]$/i)?.[1];l={type:"error",value:me(E,!1)?.error?.message||E||"Gemini encountered error"}}else l=JSON.parse(f)}catch{return}if(l)switch(l.type){case"thought":{let E=l.value;x({title:E?.subject??"Thinking...",message:E?.description},!0);break}case"content":{l.value&&x({message:l.value});break}case"tool_call_request":{let E=l.value,v=pr[E.name]??E.name,B=E.args?.path||E.args?.absolute_path,b=B&&he.relative(q.cwd(),B),U=E.args?.command,Ct={title:[v,b&&`\`${b}\``,U&&`\`${U}\``].filter(Boolean).join(" ")};m[E.callId]=Ct,N.flush();break}case"tool_result":{let E=l.value,v=m[E.callId];if(v){let B=[E.resultDisplay,E.responseParts?.functionResponse?.response?.output].find(b=>typeof b=="string"&&b);B&&(v.message=`\`\`\`
19
- ${B.trim()}
20
- \`\`\``),x(v,!0)}break}case"result":{y=l.duration_ms,g=l.value,[d,p,c].forEach(E=>{E[E.length-1]?.message===g&&E.pop()});break}case"error":{h=l.value;break}case"finished":break;default:{oe.warn("Unhandled message type:",l.type);break}}}),await I.catch(f=>{({error:h,result:g}=cr({catchError:f,runCmd:I,error:h,result:g,runnerName:"Gemini"}))}),R.close(),N.flush(),{steps:d,duration:y,result:await te({initialResult:g,agentName:ct,hasError:!!h}),error:re({error:h,agentName:ct}),isRetryableError:ne(h)}}var pt=async()=>{let e=he.join(lr.homedir(),".gemini");await ar.rm(e,{recursive:!0,force:!0})},dr={[M]:{models:{"gemini-1.5-flash":{maxTokens:8192},"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-1.5-pro":{maxTokens:8192},"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:65536},"gemini-2.5-flash-lite":{maxTokens:65536},"gemini-2.5-pro":{maxTokens:65536},"imagen-4.0-generate-001":{},"veo-3.0-generate-preview":{}}},pro:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[Y]:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[j]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}},[G]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}}};var fr={codex:{runner:Le,clean:ut},claude:{runner:Oe,clean:at},gemini:{runner:be,clean:pt}},dt=fr;var ft=async({config:e,apiThrottle:t,apiToken:r,runnerVersion:o})=>w(mr(),"init-stage",async n=>{let s=performance.now();n?.setAttributes({"init.runner":e.runner,"init.id":e.id,"init.sessionId":e.sessionId,"init.hasRepo":e.hasRepo,"init.useGateway":e.useGateway,"init.validateAgent":e.validateAgent,"init.runnerVersion":o||"unknown"});let a=dt[e.runner];if(!a)throw n?.setAttributes({"init.error":"unsupported_runner"}),new Error(`${e.runner} is not supported`);let u=gr({apiToken:r});Be(u);let i=e.useGateway?await Ve({netlify:u,config:e}):void 0;n?.setAttributes({"init.aiGateway.created":!!i}),e.validateAgent&&e.errorLogsPath&&n?.setAttributes({"init.errorLogsPath":e.errorLogsPath});let p=Qe(({steps:m=[],duration:T})=>{let y=m.map(g=>({...g,title:g.title?z(g.title):void 0,message:g.message?z(g.message):void 0}));return m.length=0,V(e.id,e.sessionId,{steps:y,duration:T})},t),c;e.hasRepo?e.sha?(c=e.sha,n?.setAttributes({"init.sha.source":"provided"})):(c=await ot(u),await de(e.id,{sha:c}),n?.setAttributes({"init.sha.source":"current_commit"})):(c=await st(u),n?.setAttributes({"init.sha.source":"first_commit","init.source":"zip"}));let d=performance.now()-s;return n?.setAttributes({"init.sha":c||"unknown","init.duration.ms":d,"init.status":"success"}),{aiGateway:i,context:u,persistSteps:p,runner:a,sha:c}}),gr=({apiToken:e})=>({constants:{NETLIFY_API_HOST:Ee.env.NETLIFY_API_HOST||"api.netlify.com",NETLIFY_API_TOKEN:e||Ee.env.NETLIFY_API_TOKEN,SITE_ID:Ee.env.SITE_ID,FUNCTIONS_DIST:Ee.env.FUNCTIONS_DIST||"netlify/functions"},utils:{run:Xe}});import{getTracer as De}from"@netlify/otel";import hr from"crypto";import W from"fs/promises";import L from"path";import F from"process";var O=_("context"),Er=e=>{let t=e?.constants||{};return{siteId:t.SITE_ID,accountId:F.env.NETLIFY_TEAM_ID,userId:F.env.NETLIFY_AGENT_RUNNER_USER_ID,siteSlug:F.env.SITE_NAME,apiHost:t.NETLIFY_API_HOST,functionsDir:t.FUNCTIONS_DIST}},_r=10,yr=async e=>{let{name:t,ext:r}=L.parse(e),o=e,n=L.join(F.cwd(),D,o),s=0;for(;await Tr(n);){if(s>=_r)throw new Error("Failed to generate context file");o=`${t}-${hr.randomUUID().slice(0,5)}${r}`,n=L.join(F.cwd(),D,o),s+=1}return o},Tr=async e=>{try{return await W.access(e),!0}catch{return!1}},xr=async()=>{try{O.log("Fetching Netlify features context...");let e=await fetch("https://docs.netlify.com/ai-context/context-consumers",{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw new Error(`Failed to fetch context consumers: ${e.status} ${e.statusText}`);let t=await e.json();if(!t||typeof t!="object"||!Array.isArray(t.consumers))return O.warn("Invalid response structure: missing or invalid consumers array"),null;let r=t.consumers.find(o=>o&&typeof o=="object"&&o.key==="catchall-consumer");return r?!r.contextScopes||typeof r.contextScopes!="object"?(O.warn("Catchall consumer missing or invalid contextScopes"),null):r:(O.warn("Catchall consumer not found in context consumers"),null)}catch(e){return e.name==="AbortError"?O.warn("Netlify features context request timed out"):O.warn("Failed to fetch Netlify features context:",e.message),null}},Rr=async(e,t)=>{try{let r=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return await W.writeFile(t,o,"utf-8"),!0}catch(r){return r.name==="AbortError"?O.warn(`Download timeout for ${e}`):O.warn(`Failed to download context file ${e}:`,r.message),!1}},_e=null,Nr=async()=>{if(_e)return _e;let e=await xr();if(!e)return[];let t=L.join(F.cwd(),D,Ce);await W.mkdir(t,{recursive:!0});let r=Object.entries(e.contextScopes).map(async([n,s])=>{if(!s||typeof s!="object"||!s.endpoint||!s.scope)return O.warn(`Invalid scope data for ${n}, skipping...`),null;let a=`${n}.md`,u=L.join(t,a),i=L.join(D,Ce,a);return O.log(`Downloading ${s.scope} context...`),await Rr(s.endpoint,u)?(O.log(`Downloaded: ${i}`),{scope:s.scope,path:i,key:n}):null});return _e=(await Promise.all(r)).filter(n=>n!==null),_e},mt=async({cliPath:e,netlify:t,config:r,buildErrorContext:o})=>{let n=Er(t),s=await yr(Je),a=L.join(F.cwd(),D);await W.mkdir(a,{recursive:!0});let u=L.join(D,s),i=L.join(F.cwd(),u),p=L.join(F.cwd(),D,ee);try{await W.unlink(p),O.log(`Deleted old results file: ${p}`)}catch{}let c=o?`You've already made changes to complete the above request. However, the build is currently failing after your changes.
18
+ \`\`\``)}catch(s){Q.error("Could not decode outputMsg",s,t.output)}return{title:o,message:n}};import yr from"fs/promises";import xr from"os";import Te from"path";import V from"process";import Rr from"readline";var ie=_("runner_gemini"),Tt="Gemini CLI",wr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(ie.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?(ie.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}):(ie.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0})),Nr={list_directory:"List",read_file:"Read",write_file:"Write",glob:"Find",search_file_content:"Find",replace:"Edit",run_shell_command:"Run",web_fetch:"Web Fetch",web_search:"Web Search",read_many_files:"Read Many",save_memory:"Memorize"};async function Ue({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:m,url:l}=n;if(!m||!l)throw new Error("No token or url provided from AI Gateway");let h=Ir[s];if(!h)throw new Error(`Gemini is not supported for the account type ${s}`);if(i&&!h?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.gemini){let C=u?.gemini?.[s];C&&(i=C)}V.env.GEMINI_API_KEY=m,V.env.GOOGLE_GEMINI_BASE_URL=l}else if(!V.env.GEMINI_API_KEY)throw new Error("GEMINI_API_KEY is not provided");let p=[],c=[],d=[],f={},T=0,g=0,E,y,N=Te.join(V.cwd(),"node_modules"),I=[Te.join(V.env.NODE_PATH||N,".bin/gemini"),...i?["--model",i]:[],"--yolo","-p",a],S=`${V.env.NVM_BIN}/node`;ie.log(`Running ${S} ${I.join(" ")}`);let A=t.utils.run(S,I,{all:!0,env:V.env});A.stdin?.end();let R=he(()=>{r?.({steps:p,duration:g}),o?.({steps:c,duration:g}),c=[]},250),x=(m,l)=>{m.id=T,T+=1,d.push(m),p.push(m),c.push(m),l||R.flush(),R(),l&&R.flush()},w=Rr.createInterface({input:A.all});return w.on("error",m=>{ie.error("Readline interface error",{error:m.message,stack:m.stack})}),w.on("line",m=>{let l=null;try{if(m.startsWith("[API Error")){let h=m.match(/\[api error: (.+?)]$/i)?.[1];l={type:"error",value:Ee(h,!1)?.error?.message||h||"Gemini encountered error"}}else l=JSON.parse(m)}catch{return}if(l)switch(l.type){case"thought":{let h=l.value;x({title:h?.subject??"Thinking...",message:h?.description},!0);break}case"content":{l.value&&x({message:l.value});break}case"tool_call_request":{let h=l.value,C=Nr[h.name]??h.name,q=h.args?.path||h.args?.absolute_path,L=q&&Te.relative(V.cwd(),q),U=h.args?.command,Ft={title:[C,L&&`\`${L}\``,U&&`\`${U}\``].filter(Boolean).join(" ")};f[h.callId]=Ft,R.flush();break}case"tool_result":{let h=l.value,C=f[h.callId];if(C){let q=[h.resultDisplay,h.responseParts?.functionResponse?.response?.output].find(L=>typeof L=="string"&&L);q&&(C.message=`\`\`\`
19
+ ${q.trim()}
20
+ \`\`\``),x(C,!0)}break}case"result":{g=l.duration_ms,E=l.value,[d,p,c].forEach(h=>{h[h.length-1]?.message===E&&h.pop()});break}case"error":{y=l.value;break}case"finished":break;default:{ie.warn("Unhandled message type:",l.type);break}}}),await A.catch(m=>{({error:y,result:E}=wr({catchError:m,runCmd:A,error:y,result:E,runnerName:"Gemini"}))}),w.close(),R.flush(),{steps:d,duration:g,result:await ne({initialResult:E,agentName:Tt,hasError:!!y}),error:oe({error:y,agentName:Tt}),isRetryableError:se(y)}}var yt=async()=>{let e=Te.join(xr.homedir(),".gemini");await yr.rm(e,{recursive:!0,force:!0})},Ir={[B]:{models:{"gemini-1.5-flash":{maxTokens:8192},"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-1.5-pro":{maxTokens:8192},"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:65536},"gemini-2.5-flash-lite":{maxTokens:65536},"gemini-2.5-pro":{maxTokens:65536},"imagen-4.0-generate-001":{},"veo-3.0-generate-preview":{}}},pro:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[j]:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[H]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}},[Y]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}}};var Ar={codex:{runner:Fe,clean:_t},claude:{runner:De,clean:ht},gemini:{runner:Ue,clean:yt}},xt=Ar;var Rt=async({config:e,apiThrottle:t,apiToken:r,runnerVersion:o})=>await P(Cr(),"init-stage",async n=>{let s=performance.now();n?.setAttributes({"init.runner":e.runner,"init.id":e.id,"init.sessionId":e.sessionId,"init.hasRepo":e.hasRepo,"init.useGateway":e.useGateway,"init.validateAgent":e.validateAgent,"init.runnerVersion":o||"unknown"});let a=xt[e.runner];if(!a)throw n?.setAttributes({"init.error":"unsupported_runner"}),new Error(`${e.runner} is not supported`);let u=Sr({apiToken:r});Je(u);let i=e.useGateway?await Qe({netlify:u,config:e}):void 0;n?.setAttributes({"init.aiGateway.created":!!i}),e.validateAgent&&e.errorLogsPath&&n?.setAttributes({"init.errorLogsPath":e.errorLogsPath});let p=lt(({steps:f=[],duration:T})=>{let g=f.map(E=>({...E,title:E.title?M(E.title):void 0,message:E.message?M(E.message):void 0}));return f.length=0,G(e.id,e.sessionId,{steps:g,duration:T})},t),c;e.hasRepo?e.sha?(c=e.sha,n?.setAttributes({"init.sha.source":"provided"})):(c=await mt(u),await fe(e.id,{sha:c}),n?.setAttributes({"init.sha.source":"current_commit"})):(c=await ft(u),n?.setAttributes({"init.sha.source":"first_commit","init.source":"zip"}));let d=performance.now()-s;return n?.setAttributes({"init.sha":c||"unknown","init.duration.ms":d,"init.status":"success"}),{aiGateway:i,context:u,persistSteps:p,runner:a,sha:c}}),Sr=({apiToken:e})=>({constants:{NETLIFY_API_HOST:ye.env.NETLIFY_API_HOST||"api.netlify.com",NETLIFY_API_TOKEN:e||ye.env.NETLIFY_API_TOKEN,SITE_ID:ye.env.SITE_ID,FUNCTIONS_DIST:ye.env.FUNCTIONS_DIST||"netlify/functions"},utils:{run:nt}});import{getTracer as Ge}from"@netlify/otel";import vr from"crypto";import W from"fs/promises";import k from"path";import $ from"process";var b=_("context"),Pr=e=>{let t=e?.constants||{};return{siteId:t.SITE_ID,accountId:$.env.NETLIFY_TEAM_ID,userId:$.env.NETLIFY_AGENT_RUNNER_USER_ID,siteSlug:$.env.SITE_NAME,apiHost:t.NETLIFY_API_HOST,functionsDir:t.FUNCTIONS_DIST}},br=10,Or=async e=>{let{name:t,ext:r}=k.parse(e),o=e,n=k.join($.cwd(),D,o),s=0;for(;await kr(n);){if(s>=br)throw new Error("Failed to generate context file");o=`${t}-${vr.randomUUID().slice(0,5)}${r}`,n=k.join($.cwd(),D,o),s+=1}return o},kr=async e=>{try{return await W.access(e),!0}catch{return!1}},Lr=async()=>{try{b.log("Fetching Netlify features context...");let e=await fetch("https://docs.netlify.com/ai-context/context-consumers",{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw new Error(`Failed to fetch context consumers: ${e.status} ${e.statusText}`);let t=await e.json();if(!t||typeof t!="object"||!Array.isArray(t.consumers))return b.warn("Invalid response structure: missing or invalid consumers array"),null;let r=t.consumers.find(o=>o&&typeof o=="object"&&o.key==="catchall-consumer");return r?!r.contextScopes||typeof r.contextScopes!="object"?(b.warn("Catchall consumer missing or invalid contextScopes"),null):r:(b.warn("Catchall consumer not found in context consumers"),null)}catch(e){return e.name==="AbortError"?b.warn("Netlify features context request timed out"):b.warn("Failed to fetch Netlify features context:",e.message),null}},Dr=async(e,t)=>{try{let r=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return await W.writeFile(t,o,"utf-8"),!0}catch(r){return r.name==="AbortError"?b.warn(`Download timeout for ${e}`):b.warn(`Failed to download context file ${e}:`,r.message),!1}},xe=null,$r=async()=>{if(xe)return xe;let e=await Lr();if(!e)return[];let t=k.join($.cwd(),D,be);await W.mkdir(t,{recursive:!0});let r=Object.entries(e.contextScopes).map(async([n,s])=>{if(!s||typeof s!="object"||!s.endpoint||!s.scope)return b.warn(`Invalid scope data for ${n}, skipping...`),null;let a=`${n}.md`,u=k.join(t,a),i=k.join(D,be,a);return b.log(`Downloading ${s.scope} context...`),await Dr(s.endpoint,u)?(b.log(`Downloaded: ${i}`),{scope:s.scope,path:i,key:n}):null});return xe=(await Promise.all(r)).filter(n=>n!==null),xe},wt=async({cliPath:e,netlify:t,config:r,buildErrorContext:o})=>{let n=Pr(t),s=await Or(st),a=k.join($.cwd(),D);await W.mkdir(a,{recursive:!0});let u=k.join(D,s),i=k.join($.cwd(),u),p=k.join($.cwd(),D,re);try{await W.unlink(p),b.log(`Deleted old results file: ${p}`)}catch{}let c=o?`You've already made changes to complete the above request. However, the build is currently failing after your changes.
21
21
  Your task is to analyze and fix the build errors.
22
22
  Don't apply techniques of reverting changes. Apply fixes related to errors.
23
23
  Don't try to run build by yourself. Just fix the errors.
@@ -26,40 +26,40 @@ Don't try to run build by yourself. Just fix the errors.
26
26
  ${o}
27
27
  </build_error_context>`:"",d="";r.siteContext&&r.siteContext.length!==0&&(d=`
28
28
  <project_rules>
29
- ${r.siteContext.filter(h=>h.site_context).map(h=>typeof h.site_context=="string"?h.site_context:typeof h.site_context=="object"?JSON.stringify(h.site_context):"").join(`
29
+ ${r.siteContext.filter(y=>y.site_context).map(y=>typeof y.site_context=="string"?y.site_context:typeof y.site_context=="object"?JSON.stringify(y.site_context):"").join(`
30
30
 
31
31
  `)}
32
32
  </project_rules>
33
- `);let m="";if(r.sessionHistoryContext?.length){let h=L.join(F.cwd(),D,Ae);await W.mkdir(h,{recursive:!0});let A=await Promise.all(r.sessionHistoryContext.map(async(S,P)=>{let I=P+1,N=`attempt-${I}.md`,x=L.join(h,N),R=L.join(D,Ae,N),f=`# Task History - Attempt ${I}
33
+ `);let f="";if(r.sessionHistoryContext?.length){let y=k.join($.cwd(),D,Pe);await W.mkdir(y,{recursive:!0});let N=await Promise.all(r.sessionHistoryContext.map(async(I,S)=>{let A=S+1,R=`attempt-${A}.md`,x=k.join(y,R),w=k.join(D,Pe,R),m=`# Task History - Attempt ${A}
34
34
 
35
35
  ## Request - what the user asked for
36
- ${S.request}
36
+ ${I.request}
37
37
 
38
38
  ---
39
39
 
40
40
  ## Response - what the agent replied with after its work
41
41
 
42
- ${S.response}
43
- `;return await W.writeFile(x,f,"utf-8"),O.log(`Created history file: ${R}`),R}));m+=`
42
+ ${I.response}
43
+ `;return await W.writeFile(x,m,"utf-8"),b.log(`Created history file: ${w}`),w}));f+=`
44
44
  <session_history_context>
45
45
  History of prior work on this task.
46
46
  You MUST review ALL of the files below as context to understand the context of previous attempts. Use this information to continue the discussion appropriately.
47
47
 
48
- ${A.slice(-5).map(S=>`- ${S}`).join(`
48
+ ${N.slice(-5).map(I=>`- ${I}`).join(`
49
49
  `)}
50
50
 
51
51
  </session_history_context>
52
- `}let T=await Nr(),y="";T.length>0&&(y=`
52
+ `}let T=await $r(),g="";T.length>0&&(g=`
53
53
  <netlify_features_context>
54
54
  If the user request is explicitly related to a specific Netlify feature (e.g., Netlify Forms, Netlify Functions, etc.), you MUST review the relevant documentation below in addition to reviewing the project files.
55
55
  DO NOT force the use of any Netlify feature if the user request does not explicitly require it or if the project has alternative implementations in place already.
56
56
 
57
- ${T.map(h=>`- **${h.scope}**: ${h.path}`).join(`
57
+ ${T.map(y=>`- **${y.scope}**: ${y.path}`).join(`
58
58
  `)}
59
59
 
60
60
  Refer to these files when working with specific Netlify features.
61
61
  </netlify_features_context>
62
- `);let g=`
62
+ `);let E=`
63
63
  You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
64
64
 
65
65
  <request>
@@ -72,13 +72,15 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
72
72
  <requirements>
73
73
  <responses>
74
74
  - Do not speak in first person. You may speak as "the agent".
75
- - When work is complete, write a changes summary in ${a}/${ee} as a standalone PR description. Explain what was accomplished and why (avoid too many implementation details), assuming the reader has no prior context. Use past tense and write in prose without calling it a "PR", "Changelog", etc. This is the core of a PR message or summary page that already has a heading.
76
- - If the user's request is informational in nature (asking for output, status, information, or analysis rather than asking you to make changes), write the requested information directly to the ${a}/${ee} file.
75
+ - When work is complete, write a changes summary in ${a}/${re} as a standalone PR description. Explain what was accomplished and why (avoid too many implementation details), assuming the reader has no prior context. Use past tense and write in prose without calling it a "PR", "Changelog", etc. This is the core of a PR message or summary page that already has a heading.
76
+ - If the user's request is informational in nature (asking for output, status, information, or analysis rather than asking you to make changes), write the requested information directly to the ${a}/${re} file.
77
77
  - Do not attempt to create git commits, PRs, etc. directly. You can use git to review information if required but the system that runs this agent will handle creating PRs or commits of the changes it performs.
78
+ - NEVER look into the \`.git\` folder
79
+ - NEVER print potentially sensitive values (like secrets) in the planning output or results
78
80
  </responses>
79
81
  <attachements>
80
- - for requests that require work with attachments or assets, take into account that uploaded attachments are stored in ${a}/${Se} folder
81
- - move assets from ${a}/${Se} folder to the project assets folder if they are referenced in a code or applied changes
82
+ - for requests that require work with attachments or assets, take into account that uploaded attachments are stored in ${a}/${Oe} folder
83
+ - move assets from ${a}/${Oe} folder to the project assets folder if they are referenced in a code or applied changes
82
84
  </attachements>
83
85
  ${d}
84
86
  </requirements>
@@ -92,20 +94,20 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
92
94
  - Netlify Functions directory: ${n.functionsDir}
93
95
  </metadata>
94
96
  <environment>
95
- - Node Version: ${F.version||"unknown"}
97
+ - Node Version: ${$.version||"unknown"}
96
98
  - Environment variables are set globally (e.g. \`echo $VARIABLE_NAME\` can be used to check if a var is set).
97
99
  - 'netlify-cli' npm package is already available as a global package. Don't try to install it again
98
100
  - If you need to start a local development server in order to fulfill the request, try using the Netlify CLI over by running the shell command '${e} dev'. This will start a local HTTP server on port 8888, including live-reloading of any changes and, most critically, it offers local emulation for all Netlify features.
99
101
  </environment>
100
- ${y}
102
+ ${g}
101
103
  <docs>
102
104
  - Netlify Docs: https://docs.netlify.com
103
105
  - LLM Resources Index: https://docs.netlify.com/llms.txt
104
106
  </docs>
105
107
  </extra_context>
106
108
 
107
- ${m}
108
- `;return await W.writeFile(i,g,"utf-8"),O.log(`Generated agent context document at: ${i}`),g.length>5e5&&(g=`
109
+ ${f}
110
+ `;return await W.writeFile(i,E,"utf-8"),b.log(`Generated agent context document at: ${i}`),E.length>5e5&&(E=`
109
111
  You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
110
112
 
111
113
  <request>
@@ -116,15 +118,15 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
116
118
  </request>
117
119
 
118
120
  Use the following file for the complete context of the ask, the environment, and what's available. ${i} You MUST READ ALL OF IT. Make sure to read it first. Never cite or paraphrase private context.
119
- `),g};var Ir=_("prompt"),gt=async({cliPath:e,config:t,netlify:r,buildErrorContext:o})=>{let n=await mt({cliPath:e,config:t,netlify:r,buildErrorContext:o});return process.env.AGENT_RUNNER_DEBUG&&Ir.log("Contextful Prompt:",n),{prompt:n}};var ye=_("inference_stage"),ht=5,Te=async e=>w(De(),"inference-stage",async t=>{let{cliPath:r,config:o,context:n,buildErrors:s,runner:a,persistSteps:u,aiGateway:i,attempt:p,contextPrefix:c}=e;t?.setAttributes({"inference.attempt":p}),ye.log(`Running inference stage, attempt ${p} of ${ht}`),Ke();let{prompt:d}=await w(De(),"compose-prompt",async()=>await gt({cliPath:r,config:o,buildErrorContext:wr(s),netlify:n})),m=`
121
+ `),E};var Fr=_("prompt"),Nt=async({cliPath:e,config:t,netlify:r,buildErrorContext:o})=>{let n=await wt({cliPath:e,config:t,netlify:r,buildErrorContext:o});return process.env.AGENT_RUNNER_DEBUG&&Fr.log("Contextful Prompt:",n),{prompt:n}};var Re=_("inference_stage"),It=5,we=async e=>await P(Ge(),"inference-stage",async t=>{let{cliPath:r,config:o,context:n,buildErrors:s,runner:a,persistSteps:u,aiGateway:i,attempt:p,contextPrefix:c}=e;t?.setAttributes({"inference.attempt":p}),Re.log(`Running inference stage, attempt ${p} of ${It}`),et();let{prompt:d}=await P(Ge(),"compose-prompt",async()=>await Nt({cliPath:r,config:o,buildErrorContext:Ur(s),netlify:n})),f=`
120
122
  ${c||""}
121
123
  ${d}
122
- `.trim(),T={...o,prompt:m},y=await w(De(),`run-${o.runner}`,async()=>await a({aiGateway:i,config:T,netlify:n,persistSteps:u}));if(await u.flush(),y.error){if(ye.error("Runner failed",{stepsCount:y.steps.length,duration:y.duration,error:y.error,isRetryableError:y.isRetryableError,attempt:p||1}),y.isRetryableError&&(!p||p<ht))return ye.log("Retrying inference stage"),await new Promise(h=>setTimeout(h,5e3)),{runnerResult:(await Te({...e,attempt:(p||1)+1,contextPrefix:"<important> The agent has already started on this work but ran into networking errors trying to complete it. Please continue from where it left off (you can use git commands to see what's currently changed thus far) and do not start over. Here is the full prompt for context: </important>"})).runnerResult};throw ye.log("Do not retry inference stage"),new Error(y.error)}return{runnerResult:y}}),wr=e=>!e||e.length===0?"":`
124
+ `.trim(),T={...o,prompt:f},g=await P(Ge(),`run-${o.runner}`,async()=>await a({aiGateway:i,config:T,netlify:n,persistSteps:u}));if(g.result&&(g.result=M(g.result)),g.error&&(g.error=M(g.error)),await u.flush(),g.error){if(Re.error("Runner failed",{stepsCount:g.steps.length,duration:g.duration,error:g.error,isRetryableError:g.isRetryableError,attempt:p||1}),g.isRetryableError&&(!p||p<It))return Re.log("Retrying inference stage"),await new Promise(y=>setTimeout(y,5e3)),{runnerResult:(await we({...e,attempt:(p||1)+1,contextPrefix:"<important> The agent has already started on this work but ran into networking errors trying to complete it. Please continue from where it left off (you can use git commands to see what's currently changed thus far) and do not start over. Here is the full prompt for context: </important>"})).runnerResult};throw Re.log("Do not retry inference stage"),new Error(g.error)}return{runnerResult:g}}),Ur=e=>!e||e.length===0?"":`
123
125
  Deploy failed failed. Here are the errors to review on the latest build:
124
126
 
125
127
  Below are all of the logs with potential issues that we extracted. Some of them may be false positives, discern them carefully and ensure fixes are relevant.
126
128
 
127
129
  ${e.pop()}
128
- `;import Sr from"process";import{getTracer as Fe}from"@netlify/otel";import{getTracer as Ar}from"@netlify/otel";var le=_("deploy"),Et=async e=>await w(Ar(),"create-preview-deploy",async t=>Cr(e,t)),Cr=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(`
129
- Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let m={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(m.sourceZipFilename=d.source_zip_filename),m}catch(i){throw le.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var ue=_("deploy_stage"),$e=async e=>await w(Fe(),"run-deploy-stage",async()=>Pr(e)),Pr=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await w(Fe(),"get-runner-diffs",async()=>await nt({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 m;try{let T=await w(Fe(),"get-runner-session",async()=>await He(t.id,t.sessionId));T?.title&&(m=T.title)}catch(T){ue.warn("Failed to fetch session title, using fallback message:",T.message)}d=await Et({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:m,skipBuild:!1,deploySubdomain:et(t.id,Sr.env.SITE_NAME),filter:n})}catch(m){return ue.warn("Failed to create preview deploy (continuing with agent run):",m),{diff:a,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:m instanceof Error?m.message:String(m)}}return ue.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:u,hasChanges:c,previewInfo:d,diffBinary:i,resultDiffBinary:p}};import{getTracer as Ue}from"@netlify/otel";async function _t(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 se=_("cleanup_stage"),yt=async e=>await w(Ue(),"cleanup-stage",async()=>vr(e)),vr=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?(se.log("Updating total agent result diff"),await w(Ue(),"update-runner",async()=>{await de(e.id,{result_diff:n,result_diff_binary:a})})):se.log("No total result diff, not updating"),se.log("Updated agent runner with result"),await _t(async()=>await w(Ue(),"update-runner-session",()=>V(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{se.error(`Error updating agent runner session (attempt ${p}):`,c),se.log("Retrying...")}}),se.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as Tt}from"@netlify/otel";var kr=Or(import.meta.url),xt=kr("../package.json"),Rt=_("pipeline_index"),xe=3,Nt=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,traceExporterUrl:a})=>{let u;await Me(xt.version,e.id,a),await w(Tt(),"run-pipeline",async()=>{try{let i,{aiGateway:p,context:c,persistSteps:d,runner:m,sha:T}=await ft({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:xt.version});u=m.clean,e.sha=T;let{runnerResult:y}=await Te({cliPath:r,config:e,context:c,runner:m.runner,persistSteps:d,aiGateway:p});await V(e.id,e.sessionId,{steps:[{title:"Deploying the run preview"}]});let g=await $e({cliPath:r,config:e,context:c,result:y.result,filter:s}),h=y,A=[];if(g.hasChanges&&g.deployError){A.push(je(g.deployError));let R=1;for(;R<=xe&&!g.previewInfo;)Rt.log(`Deploy attempt had errors. Retrying. ${R}/${xe}`),await w(Tt(),"deploy-stage",async f=>{f?.setAttributes({"stage.attempt":R});let{runnerResult:l}=await Te({cliPath:r,config:e,context:c,runner:m.runner,persistSteps:d,aiGateway:p,buildErrors:A});h={...l,steps:[...h.steps||[],...l.steps||[]],duration:(h.duration||0)+(l.duration||0)},g=await $e({cliPath:r,config:e,context:c,result:l.result,filter:s}),g.deployError&&A.push(g.deployError),R++});R>xe&&!g.previewInfo&&(i=new Error(`Deploy validation failed after ${xe} attempts`))}let{diff:S,resultDiff:P,previewInfo:I,diffBinary:N,resultDiffBinary:x}=g;if(await yt({config:e,diff:S,result:h.result,duration:h.duration,resultDiff:P,diffBinary:N,resultDiffBinary:x,previewInfo:I}),i)throw i;await m.clean?.()}catch(i){Rt.error("Got error while running pipeline",i),await u?.();let p=i instanceof Error&&i.message;throw await V(e.id,e.sessionId,{result:p||"Encountered error when running agent",state:"error"}),i}})};import k from"process";var Lr="claude",br=e=>(e??[]).filter(t=>t.request&&t.response),Dr=e=>(e??[]).filter(t=>t.site_context),It=_("config"),wt=()=>{let e=k.env.NETLIFY_AGENT_RUNNER_ID,t=k.env.NETLIFY_AGENT_RUNNER_SESSION_ID;if(!e||!t)throw new Error("ID of agent runner is not provided");let r=k.env.NETLIFY_AGENT_RUNNER_RESULT_BRANCH,o=k.env.NETLIFY_AGENT_RUNNER_PROMPT;if(!o)throw new Error("Prompt is not provided");let n=k.env.NETLIFY_AGENT_RUNNER_AGENT||Lr,s=k.env.NETLIFY_AGENT_RUNNER_MODEL,a=k.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_ENABLED==="1",u=k.env.NETLIFY_FF_AGENT_RUNNER_POST_EXECUTION_VALIDATION_WITH_BUILD_ENABLED==="1",i=k.env.ERROR_LOGS_PATH,p=me(k.env.NETLIFY_AGENT_RUNNER_CONTEXT,!0,It),c=br(p),d=Dr(p),m=k.env.NETLIFY_AGENT_RUNNER_HAS_REPO!=="0",T=!k.env.NETLIFY_FF_AGENT_RUNNER_BYOK_ENABLED,y=k.env.NETLIFY_AGENT_RUNNER_SHA,g=Fr(),h=tt(),A={id:e,sessionId:t,resultBranch:r,prompt:o,runner:n,model:s,validateAgent:a,errorLogsPath:i,sessionHistoryContext:c,siteContext:d,hasRepo:m,useGateway:T,sha:y,accountType:g,validateAgentWithBuild:u,modelVersionOverrides:h};return It.log({fullConfig:A}),A},Fr=()=>{let e=k.env.NETLIFY_TEAM_TYPE;return e?e.includes("personal")?Y:e.includes("pro")?"pro":e.startsWith("enterprise")?M:e.startsWith("free")?j:G:G};var At=_("bin_cmd"),ie=$r(Ge.argv.slice(2),{string:["auth","cwd","cli-path","error-logs-path","filter","trace-exporter-url"]});try{let e=wt();await Nt({config:e,apiToken:ie.auth,cwd:ie.cwd,cliPath:ie["cli-path"],errorLogsPath:ie["error-logs-path"],filter:ie.filter,traceExporterUrl:ie["trace-exporter-url"]}),At.info("Finished agent"),Ge.exit(0)}catch(e){At.error("Error running agent pipeline:",e),Ge.exit(1)}
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)}
130
132
  //# sourceMappingURL=bin.js.map
package/dist/index.d.ts CHANGED
@@ -36,8 +36,11 @@ interface PipelineOptions {
36
36
  cwd?: string;
37
37
  errorLogsPath?: string;
38
38
  filter?: string;
39
- traceExporterUrl?: string;
39
+ tracing: {
40
+ exporterUrl?: string;
41
+ traceparent?: string;
42
+ };
40
43
  }
41
- declare const runPipeline: ({ config, apiToken, cliPath, cwd, errorLogsPath, filter, traceExporterUrl, }: PipelineOptions) => Promise<void>;
44
+ declare const runPipeline: ({ config, apiToken, cliPath, cwd, errorLogsPath, filter, tracing, }: PipelineOptions) => Promise<void>;
42
45
 
43
46
  export { type Context, type PipelineOptions, runPipeline };
package/dist/index.js CHANGED
@@ -1,64 +1,64 @@
1
- import{createRequire as xr}from"module";import{createTracerProvider as Et}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as Le}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as _t}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as Tt}from"@netlify/otel";import{OTLPTraceExporter as xt}from"@opentelemetry/exporter-trace-otlp-grpc";function x(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 _e=x("tracing"),Fe=(e,t,r)=>Et({serviceName:"@netlify/agent-runner-cli",serviceVersion:e,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:t,spanProcessors:[new Le(new Te),new Le(new xt({url:r}))],instrumentations:[new _t({skipHeaders:!0})]});function N(e,t,r){return _e.log(`\u23F3 TRACE: ${t} starting...`),Tt(e,t,r)}var Te=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",l=n.length>0?` [${n.join(", ")}]`:"";_e.log(`${s} TRACE: ${t.name} completed in ${r.toFixed(2)}ms${l}`),t.status?.code===2&&t.status.message&&_e.log(` \u274C Error: ${t.status.message}`)}};var wt=["error","failed","exception","fatal","panic","abort","crash"];function Ue(e){let t=e.split(`
2
- `),r=[],o=-1,n=0;for(;n<t.length;){let u=t[n].slice(0,500).toLowerCase();if(wt.some(p=>u.includes(p))){let p=Math.max(0,n-10,o+1),c=Math.min(t.length-1,n+20),f=[];for(let m=p;m<=c;m++)f.push(t[m]);r.push(f.join(`
3
- `)),o=c,n=c+1}else n++}if(r.length===0)return e;let s=r.map((l,u)=>`<extracted_error_chunk order="${u+1}">
4
- ${l}
1
+ import{createRequire as $r}from"module";import{createTracerProvider as St}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as Me}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as bt}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as vt}from"@netlify/otel";import{propagation as je,context as Ye,W3CTraceContextPropagator as Pt}from"@netlify/otel/opentelemetry";import{OTLPTraceExporter as Ot}from"@opentelemetry/exporter-trace-otlp-grpc";function T(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 we=T("tracing"),Be=async(e,t,r)=>(await St({serviceName:"@netlify/agent-runner-cli",serviceVersion:e,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:t,spanProcessors:[new Me(new Re),new Me(new Ot({url:r.exporterUrl}))],instrumentations:[new bt({skipHeaders:!0})]}),r.traceparent?(je.setGlobalPropagator(new Pt),je.extract(Ye.active(),{traceparent:r.traceparent,isRemote:!0})):Ye.active());function v(e,t,r){return we.log(`\u23F3 TRACE: ${t} starting...`),vt(e,t,r)}var Re=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(", ")}]`:"";we.log(`${s} TRACE: ${t.name} completed in ${r.toFixed(2)}ms${a}`),t.status?.code===2&&t.status.message&&we.log(` \u274C Error: ${t.status.message}`)}};var kt=["error","failed","exception","fatal","panic","abort","crash"];function He(e){let t=e.split(`
2
+ `),r=[],o=-1,n=0;for(;n<t.length;){let u=t[n].slice(0,500).toLowerCase();if(kt.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(`
3
+ `)),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}">
4
+ ${a}
5
5
  </extracted_error_chunk>`).join(`
6
6
 
7
- `);return s.length>e.length*.8?e:s}import me from"process";import{getTracer as or}from"@netlify/otel";import le from"process";var xe=le.env.NETLIFY_API_URL,we=le.env.NETLIFY_API_TOKEN,oe=x("api"),ue=async(e,t={})=>{if(!xe||!we)throw new Error("No API URL or token");let r=new URL(e,xe),o={...t,headers:{...t.headers,Authorization:`Bearer ${we}`}};le.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(le.env.AGENT_RUNNERS_DEBUG==="true")oe.log(`Response headers for ${r}:`),n.headers.forEach((u,i)=>{oe.log(` ${i}: ${u}`)});else{let u=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");oe.log(`Request ID for ${r}: ${u||"N/A"}`)}if(s||oe.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw n;return n}let l=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s)throw l;return l},Me=e=>{oe.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(xe=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(we=e.constants.NETLIFY_API_TOKEN)},ce=(e,t)=>ue(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),Y=(e,t,r)=>ue(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Ge=(e,t)=>ue(`/api/v1/agent_runners/${e}/sessions/${t}`),je=(e,t,r)=>ue(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r}});var Ye=x("ai_gateway"),Be=async({netlify:e,config:t})=>{let r,o,n,s,l=e.constants?.SITE_ID;if(!l)throw new Error("No site id");let u=async()=>{clearTimeout(n),Ye.log("Requesting AI gateway information");let i=await je(l,t.id,t.sessionId);if({token:r,url:s}=i,o=i.expires_at?i.expires_at*1e3:void 0,Ye.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 K from"process";import{execa as St,execaCommand as Br}from"execa";import{Transform as Rt}from"stream";var It=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"]),Nt=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Ct(){return Object.entries(process.env).filter(([e,t])=>!(!t||It.has(e)||Nt.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function q(e){if(typeof e!="string")return e;let t=Ct();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(At(o),"g");r=r.replace(n,"******")}),r}function At(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var W=class extends Rt{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=q(n);o(null,s)}};function He(){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 l=typeof o=="string"?q(o):o;return typeof n=="function"?t(l,n):t(l,n,s)},process.stderr.write=function(o,n,s){let l=typeof o=="string"?q(o):o;return typeof n=="function"?r(l,n):r(l,n,s)}}var Wr=x("shell"),Pt={preferLocal:!0},qe=(e,t,r)=>{let[o,n]=vt(t,r),s={...Pt,...n},l=St(e,o,s);return Ot(l,s),l};var vt=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Ot=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(K.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new W).pipe(K.stdout),e.stdout?.pipe(new W).pipe(K.stdout),e.stderr?.pipe(new W).pipe(K.stderr);return}e.stdout?.pipe(K.stdout),e.stderr?.pipe(K.stderr)};var We="netlify-agent-runner-context.md",Re="task-history",Ie="netlify-context",D=".netlify",V="results.md",Ne="assets",X="other",J="personal";var z="enterprise",Z="free";var kt=x("utils"),bt=e=>new Promise(t=>{setTimeout(t,e)}),Ke=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,l=(...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 bt(t),!o)return r=!1,s=null,c;let f=o,m=n;o=null,n=[],c=await e(...f),m.forEach(w=>{w(c)})}})(),p};return l.flush=async()=>{if((r||o)&&s)return await s,l.flush()},l},pe=(e,t,r=!1)=>{let o=null,n=null,s=null,l=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 l.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},l.flush=()=>{if(o){clearTimeout(o);let u=n,i=s;o=null,n=null,s=null,e.apply(i,u)}},l},Ve=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):kt.error("Could not parse JSON",o))}},Xe=(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 Je}from"buffer";import Dt from"path";var ze=async({config:e,netlify:t})=>{let r=await Lt(t),{hasChanges:o}=r,{status:n}=r;if(!o)return{hasChanges:!1};let s=await Ft(n);await t.utils.run("git",["add",".",...s]);let l={stdio:["ignore","pipe","pipe"]},i=(await t.utils.run("git",["diff","--staged"],l)).stdout;if(o=!!i,!o)return{hasChanges:!1,ignored:s};let c=(await t.utils.run("git",["diff","--staged","--binary"],l)).stdout,f,m;if(e.sha){await t.utils.run("git",["commit","-m","Agent runner"]),f=(await t.utils.run("git",["diff",e.sha,"HEAD"],l)).stdout;let y=(await t.utils.run("git",["diff",e.sha,"HEAD","--binary"],l)).stdout;f!==y&&(m=Je.from(y).toString("base64"))}let w={hasChanges:!0,diff:i,resultDiff:f,ignored:s};return i!==c&&(w.diffBinary=Je.from(c).toString("base64")),m&&(w.resultDiffBinary=m),w},$t=["?? mise.toml","?? deno.lock",/\?\? .+?\.log/],Lt=async e=>{let t=await e.utils.run("git",["status","-s"]);return{hasChanges:(t.stdout.trim().length===0?[]:t.stdout.split(`
8
- `).filter(n=>!$t.some(s=>s instanceof RegExp?s.test(n):n===s))).length!==0,status:t.stdout}};var Ze=async e=>{let{stdout:t}=await e.utils.run("git",["rev-parse","HEAD"]);return t.trim()},Qe=async e=>{let{stdout:t}=await e.utils.run("git",["rev-list","--max-parents=0","HEAD"]);return t.trim()},Ft=async e=>{let t=[".netlify","mise.toml","deno.lock","node_modules"],r=[];return e.split(`
9
- `).forEach(o=>{t.forEach(s=>{[`?? ${s}`,`?? ${s}${Dt.sep}`].some(u=>o.startsWith(u))&&r.push(`:!${s}`)});let n=o.match(/\?\? (.+?)\.log$/)?.[1];n&&r.push(`:!${n}.log`)}),r};import Mt from"fs/promises";import Gt from"os";import de from"path";import M from"process";import jt from"readline";import Ce from"path";import Ut from"fs/promises";var Ae=x("agent-output-utils");async function Q({initialResult:e,agentName:t,hasError:r}){let o="",n=Ce.join(process.cwd(),D,V);try{let s=await Ut.readFile(n,"utf-8");s&&(o=s,Ae.log(`Pulled result from ${Ce.relative(process.cwd(),n)}`))}catch{Ae.log(`No results file found at ${Ce.relative(process.cwd(),n)}`)}return o||(!e&&!r?`${t} has finished working on task.`:e||void 0)}function ee({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&&Ae.log(`Providing updated error messsage: ${n}, replacing original error: ${r}`),n||r||void 0}function te(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=x("runner_claude"),et="Claude Code",Yt=({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 Se({config:e,netlify:t,persistSteps:r,aiGateway:o}){let n=e,{accountType:s,prompt:l,modelVersionOverrides:u}=n,{model:i}=n;if(o){let{token:T,url:d}=o;if(!T||!d)throw new Error("No token or url provided from AI Gateway");let a=Bt[s];if(!a)throw new Error(`Claude is not supported for the account type ${s}`);if(i&&!a?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.claude){let h=u?.claude?.[s];h&&(i=h)}M.env.ANTHROPIC_API_KEY=T,M.env.ANTHROPIC_BASE_URL=d}else if(!M.env.ANTHROPIC_API_KEY)throw new Error("ANTHROPIC_API_KEY is not provided");let p=[],c=[],f={},m=0,w=0,E,g,y=de.join(M.cwd(),"node_modules"),O=[de.join(M.env.NODE_PATH||y,".bin/claude"),"--permission-mode","bypassPermissions","--dangerously-skip-permissions","--output-format","stream-json","--verbose",...i?["--model",i]:[],"-p",l],A=`${M.env.NVM_BIN}/node`;L.log(`Running ${A} ${O.join(" ")}`);let S=t.utils.run(A,O,{all:!0,env:M.env});S.stdin?.end();let I=pe(()=>{r?.({steps:p,duration:w})},250),R=(T,d)=>{let a={...T,id:m};m+=1,c.push(a),p.push(a),d||I.flush(),I(),d&&I.flush()},_=jt.createInterface({input:S.all});return _.on("error",T=>{L.error("Readline interface error",{error:T.message,stack:T.stack})}),_.on("line",T=>{let d=null;try{d=JSON.parse(T)}catch{L.log("Could not parse line",T)}Array.isArray(d?.message?.content)?d.message.content.forEach(a=>{switch(a.type){case"text":{a.text&&R({message:a.text});break}case"image":{typeof a.source=="object"&&a.source&&a.source.type==="base64"&&a.source.media_type?R({message:`![](data:${a.source.media_type};base64,${a.source.data})`}):L.log(`Unsupported image type ${a.source?.type}`,a.source);break}case"tool_use":{if(a.name==="Task"){let h=a.input?.description&&`\`${a.input.description}\``;R({title:[a.name,h].filter(Boolean).join(" ")})}else a.id&&(f[a.id]=a);I.flush();break}case"tool_result":{let h=a.tool_use_id?f[a.tool_use_id]:void 0,P;if(h){let F=h.input?.file_path&&de.relative(M.cwd(),h.input.file_path),C=F&&`\`${F}\``;P=[h.name,C].filter(Boolean).join(" ")}let U=["Bash","Glob","Grep","LS","Read","Edit","Write"].includes(h?.name||""),b;if(typeof a.content=="string")b=a.content;else if(Array.isArray(a.content)){let F=[];a.content.forEach(C=>{C?.type==="text"&&typeof C.text=="string"?F.push(C.text):C?.type==="image"&&typeof C.source=="object"&&C.source?C.source.type==="base64"&&C.source.media_type?F.push(`![](data:${C.source.media_type};base64,${C.source.data})`):L.log(`Unsupported image type ${C.source.type}`,C.source):L.log(`Unsupported block type ${C?.type}`)}),b=F.join(`
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(`
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
+ `).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
 
11
- `)}U&&b&&(b=`\`\`\`
12
- ${b.trim()}
13
- \`\`\``),R({title:P,message:b},!0);break}case"thinking":{a.thinking&&R({title:"Thinking",message:a.thinking},!0);break}default:L.log(`Message content type is not supported ${a.type}`,a)}}):d?.type==="result"&&(w=d.duration_ms||0,d.is_error?g=d.result:E=d.result,[c,p].forEach(a=>{a[a.length-1]?.message===E&&a.pop()}))}),await S.catch(T=>{({error:g,result:E}=Yt({catchError:T,runCmd:S,error:g,result:E,runnerName:"Claude"}))}),_.close(),I.flush(),{steps:c,duration:w,result:await Q({initialResult:E,agentName:et,hasError:!!g}),error:ee({error:g,agentName:et}),isRetryableError:te(g)}}var tt=async()=>{let e=de.join(Gt.homedir(),".claude");await Mt.rm(e,{recursive:!0,force:!0})},Bt={[z]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:64e3},"claude-3-haiku-20240307":{maxTokens:4096},"claude-opus-4-20250514":{maxTokens:32e3},"claude-sonnet-4-20250514":{maxTokens:64e3}}},pro:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[J]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[Z]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}},[X]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}}};import Ht from"fs/promises";import qt from"os";import Pe from"path";import B from"process";import Wt from"readline";var H=x("runner_codex"),rt="Codex CLI",Kt=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(H.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?(H.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}):(H.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function ve({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:l,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:R,url:_}=n;if(!R||!_)throw new Error("No token or url provided from AI Gateway");let T=Vt[s];if(!T)throw new Error(`Codex is not supported for the account type ${s}`);if(i&&!T?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.codex){let d=u?.codex?.[s];d&&(i=d)}B.env.OPENAI_API_KEY=R,B.env.OPENAI_BASE_URL=_}else if(!B.env.OPENAI_API_KEY)throw new Error("OPENAI_API_KEY is not provided");let p=[],c=[],f={},m=0,w=0,E,g,y=Pe.join(B.cwd(),"node_modules"),O=[Pe.join(B.env.NODE_PATH||y,".bin/codex"),"--approval-mode","full-auto",n?"--disable-response-storage":void 0,"--dangerously-auto-approve-everything",...i?["--model",i]:[],"-q",l].filter(Boolean),A=`${B.env.NVM_BIN}/node`;H.log(`Running ${A} ${O.join(" ")}`);let S=t.utils.run(A,O,{all:!0,env:{...B.env,CODEX_UNSAFE_ALLOW_NO_SANDBOX:"1"}}),I=Wt.createInterface({input:S.all});return I.on("error",R=>{H.error("Readline interface error",{error:R.message,stack:R.stack})}),I.on("line",R=>{let _=null;try{_=JSON.parse(R)}catch{H.log("Could not parse line",R);return}let T=[],d=!1;if(_?.duration_ms&&(w=_.duration_ms,d=!0),_?.type==="local_shell_call")f[_.call_id]=_;else if(_?.type==="local_shell_call_output"){let a=Jt(f[_.call_id],_);a&&(a.id=m,m+=1,c.push(a),p.push(a),T.push(a),d=!0)}else _?.type==="message"&&_.role==="assistant"?E=_.content.map(a=>a.text).join(`
14
- `):_?.type==="message"&&_.role==="system"&&(g=_.content.map(a=>a.text).join(`
15
- `));d&&(r?.({steps:p,duration:w}),o?.({steps:T,duration:w}))}),await S.catch(R=>{let _=Kt({catchError:R,runCmd:S,error:g,result:E,runnerName:"Codex"});g=_.error,E=_.result}),I.close(),{steps:c,duration:w,result:await Q({initialResult:E,agentName:rt,hasError:!!g}),error:ee({error:g,agentName:rt}),isRetryableError:te(g)}}var nt=async()=>{let e=Pe.join(qt.homedir(),".codex");await Ht.rm(e,{recursive:!0,force:!0})},Vt={[z]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},o1:{maxTokens:1e5},"o1-mini":{maxTokens:65536},"o3-mini":{maxTokens:1e5},"gpt-image-1":{},"dall-e-2":{},"dall-e-3":{}}},[J]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},pro:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},[Z]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}},[X]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}}},Xt=new Set(["bash","-lc"]),Jt=(e,t)=>{if(!e||!t||e.call_id!==t.call_id)return null;let r=e.action?.command?.filter(s=>!Xt.has(s)),o=r?`Running \`${r.join(" ")}\``:void 0,n;try{n=JSON.parse(t.output).output?.trim(),n&&(n=`\`\`\`
11
+ `)}M&&k&&(k=`\`\`\`
12
+ ${k.trim()}
13
+ \`\`\``),w({title:A,message:k},!0);break}case"thinking":{l.thinking&&w({title:"Thinking",message:l.thinking},!0);break}default:L.log(`Message content type is not supported ${l.type}`,l)}}):m?.type==="result"&&(_=m.duration_ms||0,m.is_error?y=m.result:g=m.result,[c,p].forEach(l=>{l[l.length-1]?.message===g&&l.pop()}))}),await S.catch(R=>{({error:y,result:g}=tr({catchError:R,runCmd:S,error:y,result:g,runnerName:"Claude"}))}),E.close(),C.flush(),{steps:c,duration:_,result:await ee({initialResult:g,agentName:ut,hasError:!!y}),error:te({error:y,agentName:ut}),isRetryableError:re(y)}}var ct=async()=>{let e=ge.join(Qt.homedir(),".claude");await Zt.rm(e,{recursive:!0,force:!0})},rr={[Z]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:64e3},"claude-3-haiku-20240307":{maxTokens:4096},"claude-opus-4-20250514":{maxTokens:32e3},"claude-sonnet-4-20250514":{maxTokens:64e3}}},pro:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[z]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-haiku-20240307":{maxTokens:4096}}},[Q]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}},[X]:{models:{"claude-3-5-haiku-20241022":{maxTokens:8192},"claude-3-7-sonnet-20250219":{maxTokens:16e3}}}};import nr from"fs/promises";import or from"os";import ke from"path";import K from"process";import sr from"readline";var V=T("runner_codex"),pt="Codex CLI",ir=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(V.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?(V.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}):(V.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0}));async function $e({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:w,url:E}=n;if(!w||!E)throw new Error("No token or url provided from AI Gateway");let R=ar[s];if(!R)throw new Error(`Codex is not supported for the account type ${s}`);if(i&&!R?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.codex){let m=u?.codex?.[s];m&&(i=m)}K.env.OPENAI_API_KEY=w,K.env.OPENAI_BASE_URL=E}else if(!K.env.OPENAI_API_KEY)throw new Error("OPENAI_API_KEY is not provided");let p=[],c=[],d={},f=0,_=0,g,y,x=ke.join(K.cwd(),"node_modules"),I=[ke.join(K.env.NODE_PATH||x,".bin/codex"),"--approval-mode","full-auto",n?"--disable-response-storage":void 0,"--dangerously-auto-approve-everything",...i?["--model",i]:[],"-q",a].filter(Boolean),N=`${K.env.NVM_BIN}/node`;V.log(`Running ${N} ${I.join(" ")}`);let S=t.utils.run(N,I,{all:!0,env:{...K.env,CODEX_UNSAFE_ALLOW_NO_SANDBOX:"1"}}),C=sr.createInterface({input:S.all});return C.on("error",w=>{V.error("Readline interface error",{error:w.message,stack:w.stack})}),C.on("line",w=>{let E=null;try{E=JSON.parse(w)}catch{V.log("Could not parse line",w);return}let R=[],m=!1;if(E?.duration_ms&&(_=E.duration_ms,m=!0),E?.type==="local_shell_call")d[E.call_id]=E;else if(E?.type==="local_shell_call_output"){let l=ur(d[E.call_id],E);l&&(l.id=f,f+=1,c.push(l),p.push(l),R.push(l),m=!0)}else E?.type==="message"&&E.role==="assistant"?g=E.content.map(l=>l.text).join(`
14
+ `):E?.type==="message"&&E.role==="system"&&(y=E.content.map(l=>l.text).join(`
15
+ `));m&&(r?.({steps:p,duration:_}),o?.({steps:R,duration:_}))}),await S.catch(w=>{let E=ir({catchError:w,runCmd:S,error:y,result:g,runnerName:"Codex"});y=E.error,g=E.result}),C.close(),{steps:c,duration:_,result:await ee({initialResult:g,agentName:pt,hasError:!!y}),error:te({error:y,agentName:pt}),isRetryableError:re(y)}}var dt=async()=>{let e=ke.join(or.homedir(),".codex");await nr.rm(e,{recursive:!0,force:!0})},ar={[Z]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},o1:{maxTokens:1e5},"o1-mini":{maxTokens:65536},"o3-mini":{maxTokens:1e5},"gpt-image-1":{},"dall-e-2":{},"dall-e-3":{}}},[z]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},pro:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768}}},[Q]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}},[X]:{models:{"codex-mini-latest":{maxTokens:75e3},"gpt-3.5-turbo":{maxTokens:4096},"gpt-4-turbo":{maxTokens:4096},"gpt-4o":{maxTokens:16384},"gpt-4o-mini":{maxTokens:32768},"o3-mini":{maxTokens:16e3}}}},lr=new Set(["bash","-lc"]),ur=(e,t)=>{if(!e||!t||e.call_id!==t.call_id)return null;let r=e.action?.command?.filter(s=>!lr.has(s)),o=r?`Running \`${r.join(" ")}\``:void 0,n;try{n=JSON.parse(t.output).output?.trim(),n&&(n=`\`\`\`
16
16
  ${n.trim()}
17
- \`\`\``)}catch(s){H.error("Could not decode outputMsg",s,t.output)}return{title:o,message:n}};import zt from"fs/promises";import Zt from"os";import fe from"path";import G from"process";import Qt from"readline";var re=x("runner_gemini"),ot="Gemini CLI",er=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(re.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?(re.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}):(re.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0})),tr={list_directory:"List",read_file:"Read",write_file:"Write",glob:"Find",search_file_content:"Find",replace:"Edit",run_shell_command:"Run",web_fetch:"Web Fetch",web_search:"Web Search",read_many_files:"Read Many",save_memory:"Memorize"};async function Oe({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:l,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:d,url:a}=n;if(!d||!a)throw new Error("No token or url provided from AI Gateway");let h=rr[s];if(!h)throw new Error(`Gemini is not supported for the account type ${s}`);if(i&&!h?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.gemini){let P=u?.gemini?.[s];P&&(i=P)}G.env.GEMINI_API_KEY=d,G.env.GOOGLE_GEMINI_BASE_URL=a}else if(!G.env.GEMINI_API_KEY)throw new Error("GEMINI_API_KEY is not provided");let p=[],c=[],f=[],m={},w=0,E=0,g,y,O=fe.join(G.cwd(),"node_modules"),A=[fe.join(G.env.NODE_PATH||O,".bin/gemini"),...i?["--model",i]:[],"--yolo","-p",l],S=`${G.env.NVM_BIN}/node`;re.log(`Running ${S} ${A.join(" ")}`);let I=t.utils.run(S,A,{all:!0,env:G.env});I.stdin?.end();let R=pe(()=>{r?.({steps:p,duration:E}),o?.({steps:c,duration:E}),c=[]},250),_=(d,a)=>{d.id=w,w+=1,f.push(d),p.push(d),c.push(d),a||R.flush(),R(),a&&R.flush()},T=Qt.createInterface({input:I.all});return T.on("error",d=>{re.error("Readline interface error",{error:d.message,stack:d.stack})}),T.on("line",d=>{let a=null;try{if(d.startsWith("[API Error")){let h=d.match(/\[api error: (.+?)]$/i)?.[1];a={type:"error",value:Ve(h,!1)?.error?.message||h||"Gemini encountered error"}}else a=JSON.parse(d)}catch{return}if(a)switch(a.type){case"thought":{let h=a.value;_({title:h?.subject??"Thinking...",message:h?.description},!0);break}case"content":{a.value&&_({message:a.value});break}case"tool_call_request":{let h=a.value,P=tr[h.name]??h.name,U=h.args?.path||h.args?.absolute_path,b=U&&fe.relative(G.cwd(),U),F=h.args?.command,yt={title:[P,b&&`\`${b}\``,F&&`\`${F}\``].filter(Boolean).join(" ")};m[h.callId]=yt,R.flush();break}case"tool_result":{let h=a.value,P=m[h.callId];if(P){let U=[h.resultDisplay,h.responseParts?.functionResponse?.response?.output].find(b=>typeof b=="string"&&b);U&&(P.message=`\`\`\`
18
- ${U.trim()}
19
- \`\`\``),_(P,!0)}break}case"result":{E=a.duration_ms,g=a.value,[f,p,c].forEach(h=>{h[h.length-1]?.message===g&&h.pop()});break}case"error":{y=a.value;break}case"finished":break;default:{re.warn("Unhandled message type:",a.type);break}}}),await I.catch(d=>{({error:y,result:g}=er({catchError:d,runCmd:I,error:y,result:g,runnerName:"Gemini"}))}),T.close(),R.flush(),{steps:f,duration:E,result:await Q({initialResult:g,agentName:ot,hasError:!!y}),error:ee({error:y,agentName:ot}),isRetryableError:te(y)}}var st=async()=>{let e=fe.join(Zt.homedir(),".gemini");await zt.rm(e,{recursive:!0,force:!0})},rr={[z]:{models:{"gemini-1.5-flash":{maxTokens:8192},"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-1.5-pro":{maxTokens:8192},"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:65536},"gemini-2.5-flash-lite":{maxTokens:65536},"gemini-2.5-pro":{maxTokens:65536},"imagen-4.0-generate-001":{},"veo-3.0-generate-preview":{}}},pro:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[J]:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[Z]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}},[X]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}}};var nr={codex:{runner:ve,clean:nt},claude:{runner:Se,clean:tt},gemini:{runner:Oe,clean:st}},it=nr;var at=async({config:e,apiThrottle:t,apiToken:r,runnerVersion:o})=>N(or(),"init-stage",async n=>{let s=performance.now();n?.setAttributes({"init.runner":e.runner,"init.id":e.id,"init.sessionId":e.sessionId,"init.hasRepo":e.hasRepo,"init.useGateway":e.useGateway,"init.validateAgent":e.validateAgent,"init.runnerVersion":o||"unknown"});let l=it[e.runner];if(!l)throw n?.setAttributes({"init.error":"unsupported_runner"}),new Error(`${e.runner} is not supported`);let u=sr({apiToken:r});Me(u);let i=e.useGateway?await Be({netlify:u,config:e}):void 0;n?.setAttributes({"init.aiGateway.created":!!i}),e.validateAgent&&e.errorLogsPath&&n?.setAttributes({"init.errorLogsPath":e.errorLogsPath});let p=Ke(({steps:m=[],duration:w})=>{let E=m.map(g=>({...g,title:g.title?q(g.title):void 0,message:g.message?q(g.message):void 0}));return m.length=0,Y(e.id,e.sessionId,{steps:E,duration:w})},t),c;e.hasRepo?e.sha?(c=e.sha,n?.setAttributes({"init.sha.source":"provided"})):(c=await Ze(u),await ce(e.id,{sha:c}),n?.setAttributes({"init.sha.source":"current_commit"})):(c=await Qe(u),n?.setAttributes({"init.sha.source":"first_commit","init.source":"zip"}));let f=performance.now()-s;return n?.setAttributes({"init.sha":c||"unknown","init.duration.ms":f,"init.status":"success"}),{aiGateway:i,context:u,persistSteps:p,runner:l,sha:c}}),sr=({apiToken:e})=>({constants:{NETLIFY_API_HOST:me.env.NETLIFY_API_HOST||"api.netlify.com",NETLIFY_API_TOKEN:e||me.env.NETLIFY_API_TOKEN,SITE_ID:me.env.SITE_ID,FUNCTIONS_DIST:me.env.FUNCTIONS_DIST||"netlify/functions"},utils:{run:qe}});import{getTracer as ke}from"@netlify/otel";import ir from"crypto";import j from"fs/promises";import k from"path";import $ from"process";var v=x("context"),ar=e=>{let t=e?.constants||{};return{siteId:t.SITE_ID,accountId:$.env.NETLIFY_TEAM_ID,userId:$.env.NETLIFY_AGENT_RUNNER_USER_ID,siteSlug:$.env.SITE_NAME,apiHost:t.NETLIFY_API_HOST,functionsDir:t.FUNCTIONS_DIST}},lr=10,ur=async e=>{let{name:t,ext:r}=k.parse(e),o=e,n=k.join($.cwd(),D,o),s=0;for(;await cr(n);){if(s>=lr)throw new Error("Failed to generate context file");o=`${t}-${ir.randomUUID().slice(0,5)}${r}`,n=k.join($.cwd(),D,o),s+=1}return o},cr=async e=>{try{return await j.access(e),!0}catch{return!1}},pr=async()=>{try{v.log("Fetching Netlify features context...");let e=await fetch("https://docs.netlify.com/ai-context/context-consumers",{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw new Error(`Failed to fetch context consumers: ${e.status} ${e.statusText}`);let t=await e.json();if(!t||typeof t!="object"||!Array.isArray(t.consumers))return v.warn("Invalid response structure: missing or invalid consumers array"),null;let r=t.consumers.find(o=>o&&typeof o=="object"&&o.key==="catchall-consumer");return r?!r.contextScopes||typeof r.contextScopes!="object"?(v.warn("Catchall consumer missing or invalid contextScopes"),null):r:(v.warn("Catchall consumer not found in context consumers"),null)}catch(e){return e.name==="AbortError"?v.warn("Netlify features context request timed out"):v.warn("Failed to fetch Netlify features context:",e.message),null}},dr=async(e,t)=>{try{let r=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return await j.writeFile(t,o,"utf-8"),!0}catch(r){return r.name==="AbortError"?v.warn(`Download timeout for ${e}`):v.warn(`Failed to download context file ${e}:`,r.message),!1}},ge=null,fr=async()=>{if(ge)return ge;let e=await pr();if(!e)return[];let t=k.join($.cwd(),D,Ie);await j.mkdir(t,{recursive:!0});let r=Object.entries(e.contextScopes).map(async([n,s])=>{if(!s||typeof s!="object"||!s.endpoint||!s.scope)return v.warn(`Invalid scope data for ${n}, skipping...`),null;let l=`${n}.md`,u=k.join(t,l),i=k.join(D,Ie,l);return v.log(`Downloading ${s.scope} context...`),await dr(s.endpoint,u)?(v.log(`Downloaded: ${i}`),{scope:s.scope,path:i,key:n}):null});return ge=(await Promise.all(r)).filter(n=>n!==null),ge},lt=async({cliPath:e,netlify:t,config:r,buildErrorContext:o})=>{let n=ar(t),s=await ur(We),l=k.join($.cwd(),D);await j.mkdir(l,{recursive:!0});let u=k.join(D,s),i=k.join($.cwd(),u),p=k.join($.cwd(),D,V);try{await j.unlink(p),v.log(`Deleted old results file: ${p}`)}catch{}let c=o?`You've already made changes to complete the above request. However, the build is currently failing after your changes.
17
+ \`\`\``)}catch(s){V.error("Could not decode outputMsg",s,t.output)}return{title:o,message:n}};import cr from"fs/promises";import pr from"os";import he from"path";import Y from"process";import dr from"readline";var ne=T("runner_gemini"),mt="Gemini CLI",mr=({catchError:e,runCmd:t,error:r,result:o,runnerName:n})=>(ne.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?(ne.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}):(ne.log("Setting result to undefined because no valid result was captured"),{error:r||`${n} failed`,result:void 0})),fr={list_directory:"List",read_file:"Read",write_file:"Write",glob:"Find",search_file_content:"Find",replace:"Edit",run_shell_command:"Run",web_fetch:"Web Fetch",web_search:"Web Search",read_many_files:"Read Many",save_memory:"Memorize"};async function De({config:e,netlify:t,persistSteps:r,sendSteps:o,aiGateway:n}){let{accountType:s,prompt:a,modelVersionOverrides:u}=e,{model:i}=e;if(n){let{token:m,url:l}=n;if(!m||!l)throw new Error("No token or url provided from AI Gateway");let h=gr[s];if(!h)throw new Error(`Gemini is not supported for the account type ${s}`);if(i&&!h?.models?.[i])throw new Error(`${i} is not supported for account type ${s}`);if(u?.gemini){let A=u?.gemini?.[s];A&&(i=A)}Y.env.GEMINI_API_KEY=m,Y.env.GOOGLE_GEMINI_BASE_URL=l}else if(!Y.env.GEMINI_API_KEY)throw new Error("GEMINI_API_KEY is not provided");let p=[],c=[],d=[],f={},_=0,g=0,y,x,I=he.join(Y.cwd(),"node_modules"),N=[he.join(Y.env.NODE_PATH||I,".bin/gemini"),...i?["--model",i]:[],"--yolo","-p",a],S=`${Y.env.NVM_BIN}/node`;ne.log(`Running ${S} ${N.join(" ")}`);let C=t.utils.run(S,N,{all:!0,env:Y.env});C.stdin?.end();let w=fe(()=>{r?.({steps:p,duration:g}),o?.({steps:c,duration:g}),c=[]},250),E=(m,l)=>{m.id=_,_+=1,d.push(m),p.push(m),c.push(m),l||w.flush(),w(),l&&w.flush()},R=dr.createInterface({input:C.all});return R.on("error",m=>{ne.error("Readline interface error",{error:m.message,stack:m.stack})}),R.on("line",m=>{let l=null;try{if(m.startsWith("[API Error")){let h=m.match(/\[api error: (.+?)]$/i)?.[1];l={type:"error",value:nt(h,!1)?.error?.message||h||"Gemini encountered error"}}else l=JSON.parse(m)}catch{return}if(l)switch(l.type){case"thought":{let h=l.value;E({title:h?.subject??"Thinking...",message:h?.description},!0);break}case"content":{l.value&&E({message:l.value});break}case"tool_call_request":{let h=l.value,A=fr[h.name]??h.name,M=h.args?.path||h.args?.absolute_path,k=M&&he.relative(Y.cwd(),M),F=h.args?.command,At={title:[A,k&&`\`${k}\``,F&&`\`${F}\``].filter(Boolean).join(" ")};f[h.callId]=At,w.flush();break}case"tool_result":{let h=l.value,A=f[h.callId];if(A){let M=[h.resultDisplay,h.responseParts?.functionResponse?.response?.output].find(k=>typeof k=="string"&&k);M&&(A.message=`\`\`\`
18
+ ${M.trim()}
19
+ \`\`\``),E(A,!0)}break}case"result":{g=l.duration_ms,y=l.value,[d,p,c].forEach(h=>{h[h.length-1]?.message===y&&h.pop()});break}case"error":{x=l.value;break}case"finished":break;default:{ne.warn("Unhandled message type:",l.type);break}}}),await C.catch(m=>{({error:x,result:y}=mr({catchError:m,runCmd:C,error:x,result:y,runnerName:"Gemini"}))}),R.close(),w.flush(),{steps:d,duration:g,result:await ee({initialResult:y,agentName:mt,hasError:!!x}),error:te({error:x,agentName:mt}),isRetryableError:re(x)}}var ft=async()=>{let e=he.join(pr.homedir(),".gemini");await cr.rm(e,{recursive:!0,force:!0})},gr={[Z]:{models:{"gemini-1.5-flash":{maxTokens:8192},"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-1.5-pro":{maxTokens:8192},"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:65536},"gemini-2.5-flash-lite":{maxTokens:65536},"gemini-2.5-pro":{maxTokens:65536},"imagen-4.0-generate-001":{},"veo-3.0-generate-preview":{}}},pro:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[z]:{models:{"gemini-1.5-flash-8b":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192}}},[Q]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}},[X]:{models:{"gemini-2.0-flash":{maxTokens:8192},"gemini-2.0-flash-lite":{maxTokens:8192},"gemini-2.5-flash":{maxTokens:16e3}}}};var hr={codex:{runner:$e,clean:dt},claude:{runner:Oe,clean:ct},gemini:{runner:De,clean:ft}},gt=hr;var ht=async({config:e,apiThrottle:t,apiToken:r,runnerVersion:o})=>await v(yr(),"init-stage",async n=>{let s=performance.now();n?.setAttributes({"init.runner":e.runner,"init.id":e.id,"init.sessionId":e.sessionId,"init.hasRepo":e.hasRepo,"init.useGateway":e.useGateway,"init.validateAgent":e.validateAgent,"init.runnerVersion":o||"unknown"});let a=gt[e.runner];if(!a)throw n?.setAttributes({"init.error":"unsupported_runner"}),new Error(`${e.runner} is not supported`);let u=Er({apiToken:r});qe(u);let i=e.useGateway?await Je({netlify:u,config:e}):void 0;n?.setAttributes({"init.aiGateway.created":!!i}),e.validateAgent&&e.errorLogsPath&&n?.setAttributes({"init.errorLogsPath":e.errorLogsPath});let p=rt(({steps:f=[],duration:_})=>{let g=f.map(y=>({...y,title:y.title?G(y.title):void 0,message:y.message?G(y.message):void 0}));return f.length=0,U(e.id,e.sessionId,{steps:g,duration:_})},t),c;e.hasRepo?e.sha?(c=e.sha,n?.setAttributes({"init.sha.source":"provided"})):(c=await at(u),await de(e.id,{sha:c}),n?.setAttributes({"init.sha.source":"current_commit"})):(c=await lt(u),n?.setAttributes({"init.sha.source":"first_commit","init.source":"zip"}));let d=performance.now()-s;return n?.setAttributes({"init.sha":c||"unknown","init.duration.ms":d,"init.status":"success"}),{aiGateway:i,context:u,persistSteps:p,runner:a,sha:c}}),Er=({apiToken:e})=>({constants:{NETLIFY_API_HOST:ye.env.NETLIFY_API_HOST||"api.netlify.com",NETLIFY_API_TOKEN:e||ye.env.NETLIFY_API_TOKEN,SITE_ID:ye.env.SITE_ID,FUNCTIONS_DIST:ye.env.FUNCTIONS_DIST||"netlify/functions"},utils:{run:Qe}});import{getTracer as Le}from"@netlify/otel";import _r from"crypto";import B from"fs/promises";import O from"path";import D from"process";var P=T("context"),Tr=e=>{let t=e?.constants||{};return{siteId:t.SITE_ID,accountId:D.env.NETLIFY_TEAM_ID,userId:D.env.NETLIFY_AGENT_RUNNER_USER_ID,siteSlug:D.env.SITE_NAME,apiHost:t.NETLIFY_API_HOST,functionsDir:t.FUNCTIONS_DIST}},xr=10,wr=async e=>{let{name:t,ext:r}=O.parse(e),o=e,n=O.join(D.cwd(),$,o),s=0;for(;await Rr(n);){if(s>=xr)throw new Error("Failed to generate context file");o=`${t}-${_r.randomUUID().slice(0,5)}${r}`,n=O.join(D.cwd(),$,o),s+=1}return o},Rr=async e=>{try{return await B.access(e),!0}catch{return!1}},Ir=async()=>{try{P.log("Fetching Netlify features context...");let e=await fetch("https://docs.netlify.com/ai-context/context-consumers",{signal:AbortSignal.timeout(1e4)});if(!e.ok)throw new Error(`Failed to fetch context consumers: ${e.status} ${e.statusText}`);let t=await e.json();if(!t||typeof t!="object"||!Array.isArray(t.consumers))return P.warn("Invalid response structure: missing or invalid consumers array"),null;let r=t.consumers.find(o=>o&&typeof o=="object"&&o.key==="catchall-consumer");return r?!r.contextScopes||typeof r.contextScopes!="object"?(P.warn("Catchall consumer missing or invalid contextScopes"),null):r:(P.warn("Catchall consumer not found in context consumers"),null)}catch(e){return e.name==="AbortError"?P.warn("Netlify features context request timed out"):P.warn("Failed to fetch Netlify features context:",e.message),null}},Nr=async(e,t)=>{try{let r=await fetch(e,{signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`Failed to fetch ${e}: ${r.status} ${r.statusText}`);let o=await r.text();return await B.writeFile(t,o,"utf-8"),!0}catch(r){return r.name==="AbortError"?P.warn(`Download timeout for ${e}`):P.warn(`Failed to download context file ${e}:`,r.message),!1}},Ee=null,Cr=async()=>{if(Ee)return Ee;let e=await Ir();if(!e)return[];let t=O.join(D.cwd(),$,Se);await B.mkdir(t,{recursive:!0});let r=Object.entries(e.contextScopes).map(async([n,s])=>{if(!s||typeof s!="object"||!s.endpoint||!s.scope)return P.warn(`Invalid scope data for ${n}, skipping...`),null;let a=`${n}.md`,u=O.join(t,a),i=O.join($,Se,a);return P.log(`Downloading ${s.scope} context...`),await Nr(s.endpoint,u)?(P.log(`Downloaded: ${i}`),{scope:s.scope,path:i,key:n}):null});return Ee=(await Promise.all(r)).filter(n=>n!==null),Ee},yt=async({cliPath:e,netlify:t,config:r,buildErrorContext:o})=>{let n=Tr(t),s=await wr(tt),a=O.join(D.cwd(),$);await B.mkdir(a,{recursive:!0});let u=O.join($,s),i=O.join(D.cwd(),u),p=O.join(D.cwd(),$,J);try{await B.unlink(p),P.log(`Deleted old results file: ${p}`)}catch{}let c=o?`You've already made changes to complete the above request. However, the build is currently failing after your changes.
20
20
  Your task is to analyze and fix the build errors.
21
21
  Don't apply techniques of reverting changes. Apply fixes related to errors.
22
22
  Don't try to run build by yourself. Just fix the errors.
23
23
 
24
24
  <build_error_context>
25
25
  ${o}
26
- </build_error_context>`:"",f="";r.siteContext&&r.siteContext.length!==0&&(f=`
26
+ </build_error_context>`:"",d="";r.siteContext&&r.siteContext.length!==0&&(d=`
27
27
  <project_rules>
28
- ${r.siteContext.filter(y=>y.site_context).map(y=>typeof y.site_context=="string"?y.site_context:typeof y.site_context=="object"?JSON.stringify(y.site_context):"").join(`
28
+ ${r.siteContext.filter(x=>x.site_context).map(x=>typeof x.site_context=="string"?x.site_context:typeof x.site_context=="object"?JSON.stringify(x.site_context):"").join(`
29
29
 
30
30
  `)}
31
31
  </project_rules>
32
- `);let m="";if(r.sessionHistoryContext?.length){let y=k.join($.cwd(),D,Re);await j.mkdir(y,{recursive:!0});let O=await Promise.all(r.sessionHistoryContext.map(async(A,S)=>{let I=S+1,R=`attempt-${I}.md`,_=k.join(y,R),T=k.join(D,Re,R),d=`# Task History - Attempt ${I}
32
+ `);let f="";if(r.sessionHistoryContext?.length){let x=O.join(D.cwd(),$,Ae);await B.mkdir(x,{recursive:!0});let I=await Promise.all(r.sessionHistoryContext.map(async(N,S)=>{let C=S+1,w=`attempt-${C}.md`,E=O.join(x,w),R=O.join($,Ae,w),m=`# Task History - Attempt ${C}
33
33
 
34
34
  ## Request - what the user asked for
35
- ${A.request}
35
+ ${N.request}
36
36
 
37
37
  ---
38
38
 
39
39
  ## Response - what the agent replied with after its work
40
40
 
41
- ${A.response}
42
- `;return await j.writeFile(_,d,"utf-8"),v.log(`Created history file: ${T}`),T}));m+=`
41
+ ${N.response}
42
+ `;return await B.writeFile(E,m,"utf-8"),P.log(`Created history file: ${R}`),R}));f+=`
43
43
  <session_history_context>
44
44
  History of prior work on this task.
45
45
  You MUST review ALL of the files below as context to understand the context of previous attempts. Use this information to continue the discussion appropriately.
46
46
 
47
- ${O.slice(-5).map(A=>`- ${A}`).join(`
47
+ ${I.slice(-5).map(N=>`- ${N}`).join(`
48
48
  `)}
49
49
 
50
50
  </session_history_context>
51
- `}let w=await fr(),E="";w.length>0&&(E=`
51
+ `}let _=await Cr(),g="";_.length>0&&(g=`
52
52
  <netlify_features_context>
53
53
  If the user request is explicitly related to a specific Netlify feature (e.g., Netlify Forms, Netlify Functions, etc.), you MUST review the relevant documentation below in addition to reviewing the project files.
54
54
  DO NOT force the use of any Netlify feature if the user request does not explicitly require it or if the project has alternative implementations in place already.
55
55
 
56
- ${w.map(y=>`- **${y.scope}**: ${y.path}`).join(`
56
+ ${_.map(x=>`- **${x.scope}**: ${x.path}`).join(`
57
57
  `)}
58
58
 
59
59
  Refer to these files when working with specific Netlify features.
60
60
  </netlify_features_context>
61
- `);let g=`
61
+ `);let y=`
62
62
  You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
63
63
 
64
64
  <request>
@@ -71,15 +71,17 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
71
71
  <requirements>
72
72
  <responses>
73
73
  - Do not speak in first person. You may speak as "the agent".
74
- - When work is complete, write a changes summary in ${l}/${V} as a standalone PR description. Explain what was accomplished and why (avoid too many implementation details), assuming the reader has no prior context. Use past tense and write in prose without calling it a "PR", "Changelog", etc. This is the core of a PR message or summary page that already has a heading.
75
- - If the user's request is informational in nature (asking for output, status, information, or analysis rather than asking you to make changes), write the requested information directly to the ${l}/${V} file.
74
+ - When work is complete, write a changes summary in ${a}/${J} as a standalone PR description. Explain what was accomplished and why (avoid too many implementation details), assuming the reader has no prior context. Use past tense and write in prose without calling it a "PR", "Changelog", etc. This is the core of a PR message or summary page that already has a heading.
75
+ - If the user's request is informational in nature (asking for output, status, information, or analysis rather than asking you to make changes), write the requested information directly to the ${a}/${J} file.
76
76
  - Do not attempt to create git commits, PRs, etc. directly. You can use git to review information if required but the system that runs this agent will handle creating PRs or commits of the changes it performs.
77
+ - NEVER look into the \`.git\` folder
78
+ - NEVER print potentially sensitive values (like secrets) in the planning output or results
77
79
  </responses>
78
80
  <attachements>
79
- - for requests that require work with attachments or assets, take into account that uploaded attachments are stored in ${l}/${Ne} folder
80
- - move assets from ${l}/${Ne} folder to the project assets folder if they are referenced in a code or applied changes
81
+ - for requests that require work with attachments or assets, take into account that uploaded attachments are stored in ${a}/${be} folder
82
+ - move assets from ${a}/${be} folder to the project assets folder if they are referenced in a code or applied changes
81
83
  </attachements>
82
- ${f}
84
+ ${d}
83
85
  </requirements>
84
86
 
85
87
  <extra_context>
@@ -91,20 +93,20 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
91
93
  - Netlify Functions directory: ${n.functionsDir}
92
94
  </metadata>
93
95
  <environment>
94
- - Node Version: ${$.version||"unknown"}
96
+ - Node Version: ${D.version||"unknown"}
95
97
  - Environment variables are set globally (e.g. \`echo $VARIABLE_NAME\` can be used to check if a var is set).
96
98
  - 'netlify-cli' npm package is already available as a global package. Don't try to install it again
97
99
  - If you need to start a local development server in order to fulfill the request, try using the Netlify CLI over by running the shell command '${e} dev'. This will start a local HTTP server on port 8888, including live-reloading of any changes and, most critically, it offers local emulation for all Netlify features.
98
100
  </environment>
99
- ${E}
101
+ ${g}
100
102
  <docs>
101
103
  - Netlify Docs: https://docs.netlify.com
102
104
  - LLM Resources Index: https://docs.netlify.com/llms.txt
103
105
  </docs>
104
106
  </extra_context>
105
107
 
106
- ${m}
107
- `;return await j.writeFile(i,g,"utf-8"),v.log(`Generated agent context document at: ${i}`),g.length>5e5&&(g=`
108
+ ${f}
109
+ `;return await B.writeFile(i,y,"utf-8"),P.log(`Generated agent context document at: ${i}`),y.length>5e5&&(y=`
108
110
  You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
109
111
 
110
112
  <request>
@@ -115,15 +117,15 @@ You're an AI agent designed to assist with tasks related to a Netlify project. P
115
117
  </request>
116
118
 
117
119
  Use the following file for the complete context of the ask, the environment, and what's available. ${i} You MUST READ ALL OF IT. Make sure to read it first. Never cite or paraphrase private context.
118
- `),g};var mr=x("prompt"),ut=async({cliPath:e,config:t,netlify:r,buildErrorContext:o})=>{let n=await lt({cliPath:e,config:t,netlify:r,buildErrorContext:o});return process.env.AGENT_RUNNER_DEBUG&&mr.log("Contextful Prompt:",n),{prompt:n}};var he=x("inference_stage"),ct=5,ye=async e=>N(ke(),"inference-stage",async t=>{let{cliPath:r,config:o,context:n,buildErrors:s,runner:l,persistSteps:u,aiGateway:i,attempt:p,contextPrefix:c}=e;t?.setAttributes({"inference.attempt":p}),he.log(`Running inference stage, attempt ${p} of ${ct}`),He();let{prompt:f}=await N(ke(),"compose-prompt",async()=>await ut({cliPath:r,config:o,buildErrorContext:gr(s),netlify:n})),m=`
120
+ `),y};var Ar=T("prompt"),Et=async({cliPath:e,config:t,netlify:r,buildErrorContext:o})=>{let n=await yt({cliPath:e,config:t,netlify:r,buildErrorContext:o});return process.env.AGENT_RUNNER_DEBUG&&Ar.log("Contextful Prompt:",n),{prompt:n}};var _e=T("inference_stage"),_t=5,Te=async e=>await v(Le(),"inference-stage",async t=>{let{cliPath:r,config:o,context:n,buildErrors:s,runner:a,persistSteps:u,aiGateway:i,attempt:p,contextPrefix:c}=e;t?.setAttributes({"inference.attempt":p}),_e.log(`Running inference stage, attempt ${p} of ${_t}`),Xe();let{prompt:d}=await v(Le(),"compose-prompt",async()=>await Et({cliPath:r,config:o,buildErrorContext:Sr(s),netlify:n})),f=`
119
121
  ${c||""}
120
- ${f}
121
- `.trim(),w={...o,prompt:m},E=await N(ke(),`run-${o.runner}`,async()=>await l({aiGateway:i,config:w,netlify:n,persistSteps:u}));if(await u.flush(),E.error){if(he.error("Runner failed",{stepsCount:E.steps.length,duration:E.duration,error:E.error,isRetryableError:E.isRetryableError,attempt:p||1}),E.isRetryableError&&(!p||p<ct))return he.log("Retrying inference stage"),await new Promise(y=>setTimeout(y,5e3)),{runnerResult:(await ye({...e,attempt:(p||1)+1,contextPrefix:"<important> The agent has already started on this work but ran into networking errors trying to complete it. Please continue from where it left off (you can use git commands to see what's currently changed thus far) and do not start over. Here is the full prompt for context: </important>"})).runnerResult};throw he.log("Do not retry inference stage"),new Error(E.error)}return{runnerResult:E}}),gr=e=>!e||e.length===0?"":`
122
+ ${d}
123
+ `.trim(),_={...o,prompt:f},g=await v(Le(),`run-${o.runner}`,async()=>await a({aiGateway:i,config:_,netlify:n,persistSteps:u}));if(g.result&&(g.result=G(g.result)),g.error&&(g.error=G(g.error)),await u.flush(),g.error){if(_e.error("Runner failed",{stepsCount:g.steps.length,duration:g.duration,error:g.error,isRetryableError:g.isRetryableError,attempt:p||1}),g.isRetryableError&&(!p||p<_t))return _e.log("Retrying inference stage"),await new Promise(x=>setTimeout(x,5e3)),{runnerResult:(await Te({...e,attempt:(p||1)+1,contextPrefix:"<important> The agent has already started on this work but ran into networking errors trying to complete it. Please continue from where it left off (you can use git commands to see what's currently changed thus far) and do not start over. Here is the full prompt for context: </important>"})).runnerResult};throw _e.log("Do not retry inference stage"),new Error(g.error)}return{runnerResult:g}}),Sr=e=>!e||e.length===0?"":`
122
124
  Deploy failed failed. Here are the errors to review on the latest build:
123
125
 
124
126
  Below are all of the logs with potential issues that we extracted. Some of them may be false positives, discern them carefully and ensure fixes are relevant.
125
127
 
126
128
  ${e.pop()}
127
- `;import Er from"process";import{getTracer as be}from"@netlify/otel";import{getTracer as hr}from"@netlify/otel";var ie=x("deploy"),pt=async e=>await N(hr(),"create-preview-deploy",async t=>yr(e,t)),yr=async({netlify:e,hasRepo:t,skipBuild:r,message:o="Agent Preview",deploySubdomain:n,cliPath:s,filter:l},u)=>{try{let i=["deploy","--message",`"${o}"`,"--json","--draft","--verbose"];t||(ie.log("Deploy: Uploading source zip"),i.push("--upload-source-zip")),n&&i.push("--alias",n),l&&i.push("--filter",l),r?(ie.log("Deploy: Skipping build"),i.push("--no-build")):i.push("--context","deploy-preview");let p=s||"netlify";ie.log(`Running: ${p} ${i.join(" ")}`),u?.setAttributes({cmd:p,args:i});let c=await e.utils.run(p,i,{stdio:["ignore","pipe","pipe"]}),f=JSON.parse(c.stdout.trim());u?.setAttributes({success:!0,deployId:f.deploy_id,deployUrl:f.deploy_url,siteId:f.site_id}),ie.log(`
128
- Preview deploy created successfully:`,{deployId:f.deploy_id,deployUrl:f.deploy_url,siteId:f.site_id});let m={deployId:f.deploy_id,previewUrl:f.deploy_url,logsUrl:f.logs,siteId:f.site_id};return t||(m.sourceZipFilename=f.source_zip_filename),m}catch(i){throw ie.error("Failed to create preview deploy via CLI:",i),u?.setAttributes({success:!1,error:i.message}),i}};var ae=x("deploy_stage"),De=async e=>await N(be(),"run-deploy-stage",async()=>_r(e)),_r=async({cliPath:e,config:t,context:r,result:o,filter:n})=>{let s=await N(be(),"get-runner-diffs",async()=>await ze({config:t,netlify:r}));if(ae.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges)return{diff:"",hasChanges:!1,previewInfo:null};let{diff:l,resultDiff:u,diffBinary:i,resultDiffBinary:p}=s,c=!0;ae.log("Preview deploy condition check:",{resultUndefined:o===void 0,resultType:typeof o,hasChanges:c,wouldCreatePreview:o!==void 0&&c});let f=null;if(o!==void 0&&c)try{let m;try{let w=await N(be(),"get-runner-session",async()=>await Ge(t.id,t.sessionId));w?.title&&(m=w.title)}catch(w){ae.warn("Failed to fetch session title, using fallback message:",w.message)}f=await pt({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:m,skipBuild:!1,deploySubdomain:Xe(t.id,Er.env.SITE_NAME),filter:n})}catch(m){return ae.warn("Failed to create preview deploy (continuing with agent run):",m),{diff:l,resultDiff:u,hasChanges:c,previewInfo:null,diffBinary:i,resultDiffBinary:p,deployError:m instanceof Error?m.message:String(m)}}return ae.log("Git status",{hasDiff:!!l,hasChanges:c}),{diff:l,resultDiff:u,hasChanges:c,previewInfo:f,diffBinary:i,resultDiffBinary:p}};import{getTracer as $e}from"@netlify/otel";async function dt(e,t){let{maxRetries:r,baseDelay:o,onRetry:n}=t,s;for(let l=1;l<=r;l++)try{return await e()}catch(u){if(s=u,l===r)throw s;n&&n(l,s),await new Promise(i=>setTimeout(i,o*l))}throw s}var ne=x("cleanup_stage"),ft=async e=>await N($e(),"cleanup-stage",async()=>Tr(e)),Tr=async({config:e,diff:t,result:r,duration:o,resultDiff:n,diffBinary:s,resultDiffBinary:l,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||l?(ne.log("Updating total agent result diff"),await N($e(),"update-runner",async()=>{await ce(e.id,{result_diff:n,result_diff_binary:l})})):ne.log("No total result diff, not updating"),ne.log("Updated agent runner with result"),await dt(async()=>await N($e(),"update-runner-session",()=>Y(e.id,e.sessionId,i)),{maxRetries:3,baseDelay:1e3,onRetry:(p,c)=>{ne.error(`Error updating agent runner session (attempt ${p}):`,c),ne.log("Retrying...")}}),ne.log("Finished updating agent runner with result"),{sessionUpdate:i}};import{getTracer as mt}from"@netlify/otel";var wr=xr(import.meta.url),gt=wr("../package.json"),ht=x("pipeline_index"),Ee=3,qo=async({config:e,apiToken:t,cliPath:r="netlify",cwd:o,errorLogsPath:n,filter:s,traceExporterUrl:l})=>{let u;await Fe(gt.version,e.id,l),await N(mt(),"run-pipeline",async()=>{try{let i,{aiGateway:p,context:c,persistSteps:f,runner:m,sha:w}=await at({config:e,apiToken:t,cliPath:r,cwd:o,errorLogsPath:n,filter:s,runnerVersion:gt.version});u=m.clean,e.sha=w;let{runnerResult:E}=await ye({cliPath:r,config:e,context:c,runner:m.runner,persistSteps:f,aiGateway:p});await Y(e.id,e.sessionId,{steps:[{title:"Deploying the run preview"}]});let g=await De({cliPath:r,config:e,context:c,result:E.result,filter:s}),y=E,O=[];if(g.hasChanges&&g.deployError){O.push(Ue(g.deployError));let T=1;for(;T<=Ee&&!g.previewInfo;)ht.log(`Deploy attempt had errors. Retrying. ${T}/${Ee}`),await N(mt(),"deploy-stage",async d=>{d?.setAttributes({"stage.attempt":T});let{runnerResult:a}=await ye({cliPath:r,config:e,context:c,runner:m.runner,persistSteps:f,aiGateway:p,buildErrors:O});y={...a,steps:[...y.steps||[],...a.steps||[]],duration:(y.duration||0)+(a.duration||0)},g=await De({cliPath:r,config:e,context:c,result:a.result,filter:s}),g.deployError&&O.push(g.deployError),T++});T>Ee&&!g.previewInfo&&(i=new Error(`Deploy validation failed after ${Ee} attempts`))}let{diff:A,resultDiff:S,previewInfo:I,diffBinary:R,resultDiffBinary:_}=g;if(await ft({config:e,diff:A,result:y.result,duration:y.duration,resultDiff:S,diffBinary:R,resultDiffBinary:_,previewInfo:I}),i)throw i;await m.clean?.()}catch(i){ht.error("Got error while running pipeline",i),await u?.();let p=i instanceof Error&&i.message;throw await Y(e.id,e.sessionId,{result:p||"Encountered error when running agent",state:"error"}),i}})};export{qo as runPipeline};
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};
129
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.39.1",
4
+ "version": "1.41.0",
5
5
  "description": "CLI tool for running Netlify agents",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -73,7 +73,7 @@
73
73
  "dependencies": {
74
74
  "@anthropic-ai/claude-code": "^2.0.2",
75
75
  "@google/gemini-cli": "0.1.17",
76
- "@netlify/otel": "^4.0.0",
76
+ "@netlify/otel": "^4.1.0",
77
77
  "@opentelemetry/exporter-trace-otlp-grpc": "^0.57.0",
78
78
  "execa": "^8.0.0",
79
79
  "get-port": "^5.1.1",