@netlify/agent-runner-cli 1.77.0-alpha.0 → 1.77.1-alpha.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-local.js CHANGED
@@ -5,7 +5,7 @@ import L from"process";import Ur from"path";import Gr from"fs";import Eo from"mi
5
5
  ${i}
6
6
  </extracted_error_chunk>`).join(`
7
7
 
8
- `);return s.length>e.length*.8?e:s}import{execSync as Mn}from"child_process";import Tr from"fs/promises";import Un from"path";import ie from"process";import{getTracer as Gn}from"@netlify/otel";import Ae from"process";var me=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},Ot=e=>e instanceof me;var De=Ae.env.NETLIFY_API_URL,Me=Ae.env.NETLIFY_API_TOKEN,K=w("api"),be=()=>Ae.env.NETLIFY_LOCAL_MODE==="true",ge=async(e,t={})=>{if(!De||!Me)throw new Error("No API URL or token");let r=new URL(e,De),o={...t,headers:{...t.headers,Authorization:`Bearer ${Me}`}};Ae.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(Ae.env.AGENT_RUNNERS_DEBUG==="true")K.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{K.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");K.log(`Request ID for ${r}: ${a||"N/A"}`)}if(s||K.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let i=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s){let a=typeof i=="string"?i:JSON.stringify(i);throw n.status===404?new me(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new me(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return i},$t=e=>{K.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(De=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Me=e.constants.NETLIFY_API_TOKEN)},Ft=()=>({apiUrl:De,token:Me}),Ce=async(e,t)=>be()?(K.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):ge(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),B=async(e,t,r)=>be()?(K.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):ge(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Lt=async(e,t)=>be()?(K.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):ge(`/api/v1/agent_runners/${e}/sessions/${t}`),Dt=(e,t,r)=>ge(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Mt=async(e,t)=>be()?(K.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):ge(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),Ut=async(e,t)=>be()?(K.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):ge(`/access-control/bb-api/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),rt=async(e,t)=>{K.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var fe=w("ai_gateway"),nt=null;var Gt=async()=>{if(nt)return nt;fe.log("Fetching available AI gateway providers");let e=await fetch(`${Ft().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return nt=t,fe.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},Jr=async(e,t)=>{let o=(await Gt()).providers[e];if(!o)return fe.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return fe.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},jt=async({netlify:e,config:t})=>{let r,o,n,s,i=e.constants?.SITE_ID;if(!i)throw new Error("No site id");let a=async()=>{clearTimeout(n),fe.log("Requesting AI gateway information");let l=await Dt(i,t.id,t.sessionId);if({token:r,url:s}=l,o=l.expires_at?l.expires_at*1e3:void 0,fe.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let d=o-Date.now()-6e4;d>0&&(n=setTimeout(()=>{a()},d))}};return await Promise.all([a(),Gt()]),{get url(){return s},get token(){return r},isModelAvailableForProvider:Jr}};import z from"process";import ee from"path";import Ue from"fs";import{fileURLToPath as tn}from"url";import{createRequire as rn}from"module";import{execa as nn,execaCommand as Xo}from"execa";import{Transform as Vr}from"stream";var zr=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_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"]),Xr=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Zr(){return Object.entries(process.env).filter(([e,t])=>!(!t||zr.has(e)||Xr.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function Q(e){if(typeof e!="string")return e;let t=Zr();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Qr(o),"g");r=r.replace(n,"******")}),r}function Qr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var he=class extends Vr{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=Q(n);o(null,s)}};function Yt(){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 i=typeof o=="string"?Q(o):o;return typeof n=="function"?t(i,n):t(i,n,s)},process.stderr.write=function(o,n,s){let i=typeof o=="string"?Q(o):o;return typeof n=="function"?r(i,n):r(i,n,s)}}var Ne=null,Bt=e=>(Ne&&Ne.destroy(),Ne=new ne({totalAllowedTime:e}),Ne),qt=()=>Ne;var ne=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,i=null;o!==void 0&&(i=new Promise((a,l)=>{s=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return i?await Promise.race([r(),i]):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 Ht="netlify-agent-runner-context.md",ot="task-history",V=".netlify",ae="results.md",it="assets";var le=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Wt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.0-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var on=tn(import.meta.url),sn=ee.dirname(on),an=rn(import.meta.url),ye=w("shell"),st=new Set,ln={preferLocal:!0},v=(e,t,r)=>{let[o,n]=cn(t,r),s={...ln,...n},i=nn(e,o,s);un(i,s),pn(i);let a=r?.idleTimeout;return a&&a>0&&dn(i,a),i};var cn=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},un=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(z.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new he).pipe(z.stdout),e.stdout?.pipe(new he).pipe(z.stdout),e.stderr?.pipe(new he).pipe(z.stderr);return}e.stdout?.pipe(z.stdout),e.stderr?.pipe(z.stderr)},at=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(z.kill(-e.pid,t),ye.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return ye.error("Error killing process:",r),!1}},Kt=e=>at(e,"SIGKILL"),dn=(e,t)=>{let r=null,o=()=>{ye.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),at(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ye.log(`Force killing idle process ${e.pid}`),Kt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let s=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",s),e.on("error",s)},pn=e=>{st.add(e);let t=qt();if(t){let r=t.onTimesUp(()=>{ye.log(`Global timer expired, killing process ${e.pid}`),at(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ye.log(`Force killing process ${e.pid} after timeout`),Kt(e))},5e3)});e.on("exit",()=>{st.delete(e),r()}),e.on("error",()=>{st.delete(e),r()})}};function Ge(e,t){return!!te(e,t)}function te(e,t){if(!z.env.NETLIFY_LOCAL_MODE)try{let n=an.resolve(Wt.name),s=ee.dirname(n);for(;s!==ee.dirname(s);){let i=ee.dirname(s);if(ee.basename(i)==="node_modules"){let a=ee.join(i,".bin",t);if(Ue.existsSync(a))return a;break}s=i}}catch(n){console.error("Could not resolve package.json",n)}if(z.env.NODE_PATH){let n=ee.join(z.env.NODE_PATH,".bin",t);if(Ue.existsSync(n))return n}let r=ee.join(e,"node_modules",".bin",t);if(Ue.existsSync(r))return r;let o=ee.join(sn,"..","node_modules",".bin",t);if(Ue.existsSync(o))return o}var mn=w("utils"),gn=e=>new Promise(t=>{setTimeout(t,e)}),Jt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,i=(...a)=>{if(r)return o=a,new Promise(p=>{n.push(p)});r=!0;let l,d=new Promise(p=>{l=p});return s=(async()=>{await Promise.resolve();let p=await e(...a);for(l(p);;){if(await gn(t),!o)return r=!1,s=null,p;let u=o,m=n;o=null,n=[],p=await e(...u),m.forEach(E=>{E(p)})}})(),d};return i.flush=async()=>{if((r||o)&&s)return await s,i.flush()},i},Ee=(e,t,r=!1)=>{let o=null,n=null,s=null,i=function(...a){n=a,s=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),l&&(e.apply(s,n),n=null,s=null)};return i.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},i.flush=()=>{if(o){clearTimeout(o);let a=n,l=s;o=null,n=null,s=null,e.apply(l,a)}},i},Vt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):mn.error("Could not parse JSON",o))}},lt=e=>e.charAt(0).toUpperCase()+e.slice(1),ce=e=>e.split("-").map(lt).join(" "),zt=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),Xt=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=s.length+6){let d=Math.min(l-s.length,e.length);return`${s}${e.slice(0,d)}`}return e.slice(0,l)};var fn=50*1024,ct=(e,t=fn)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as Zt}from"buffer";import hn from"path";var Qt=w("repo"),tr=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{Qt.info("Getting runner diffs");let o=await En(r),{hasChanges:n}=o,{status:s}=o;if(!n)return{hasChanges:!1};if(!t){let T=wn(s);await Tn(T,r)}Qt.info("Changes after processing"),await dt(r);let i=await pt(s,r);if(await ut(i,r),n=await _n(r),!n)return{hasChanges:!1,ignored:i};process.env.NETLIFY_INTERNAL_GIT="1";try{await v("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await v("git",["diff",e.runSha,"HEAD"],a),d=String(l.stdout??"");if(n=!!d,!n)return await er(r),{hasChanges:!1,ignored:i};let p=await v("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(p.stdout??""),m,E;if(e.sha){let T=await v("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let I=await v("git",["diff",e.sha,"HEAD","--binary"],a),y=String(I.stdout??"");m!==y&&(E=Zt.from(y).toString("base64"))}await er(r);let _={hasChanges:!0,diff:d,resultDiff:m,ignored:i};return d!==u&&(_.diffBinary=Zt.from(u).toString("base64")),E&&(_.resultDiffBinary=E),_},er=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await v("git",["reset","--soft","HEAD~1"],{cwd:e})},ut=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await v("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},dt=async(e=process.cwd())=>{let t=await v("git",["status","-s"],{cwd:e});return String(t.stdout??"")},rr=/.. (.+)?\.log$/,yn=[rr],En=async(e=process.cwd())=>{let t=await dt(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
8
+ `);return s.length>e.length*.8?e:s}import{execSync as Mn}from"child_process";import Tr from"fs/promises";import Un from"path";import ie from"process";import{getTracer as Gn}from"@netlify/otel";import Ae from"process";var me=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},Ot=e=>e instanceof me;var De=Ae.env.NETLIFY_API_URL,Me=Ae.env.NETLIFY_API_TOKEN,K=w("api"),be=()=>Ae.env.NETLIFY_LOCAL_MODE==="true",ge=async(e,t={})=>{if(!De||!Me)throw new Error("No API URL or token");let r=new URL(e,De),o={...t,headers:{...t.headers,Authorization:`Bearer ${Me}`}};Ae.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(Ae.env.AGENT_RUNNERS_DEBUG==="true")K.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{K.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");K.log(`Request ID for ${r}: ${a||"N/A"}`)}if(s||K.error(`Got status ${n.status} for request ${r}`),t.raw){if(!s)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let i=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!s){let a=typeof i=="string"?i:JSON.stringify(i);throw n.status===404?new me(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new me(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return i},$t=e=>{K.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(De=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(Me=e.constants.NETLIFY_API_TOKEN)},Ft=()=>({apiUrl:De,token:Me}),Ce=async(e,t)=>be()?(K.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):ge(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),B=async(e,t,r)=>be()?(K.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):ge(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Lt=async(e,t)=>be()?(K.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):ge(`/api/v1/agent_runners/${e}/sessions/${t}`),Dt=(e,t,r)=>ge(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Mt=async(e,t)=>be()?(K.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):ge(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),Ut=async(e,t)=>be()?(K.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):ge(`/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),rt=async(e,t)=>{K.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var fe=w("ai_gateway"),nt=null;var Gt=async()=>{if(nt)return nt;fe.log("Fetching available AI gateway providers");let e=await fetch(`${Ft().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return nt=t,fe.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},Jr=async(e,t)=>{let o=(await Gt()).providers[e];if(!o)return fe.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return fe.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},jt=async({netlify:e,config:t})=>{let r,o,n,s,i=e.constants?.SITE_ID;if(!i)throw new Error("No site id");let a=async()=>{clearTimeout(n),fe.log("Requesting AI gateway information");let l=await Dt(i,t.id,t.sessionId);if({token:r,url:s}=l,o=l.expires_at?l.expires_at*1e3:void 0,fe.log("Got AI gateway information",{token:!!r,expiresAt:o,url:s}),o){let d=o-Date.now()-6e4;d>0&&(n=setTimeout(()=>{a()},d))}};return await Promise.all([a(),Gt()]),{get url(){return s},get token(){return r},isModelAvailableForProvider:Jr}};import z from"process";import ee from"path";import Ue from"fs";import{fileURLToPath as tn}from"url";import{createRequire as rn}from"module";import{execa as nn,execaCommand as Xo}from"execa";import{Transform as Vr}from"stream";var zr=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_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"]),Xr=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Zr(){return Object.entries(process.env).filter(([e,t])=>!(!t||zr.has(e)||Xr.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function Q(e){if(typeof e!="string")return e;let t=Zr();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Qr(o),"g");r=r.replace(n,"******")}),r}function Qr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var he=class extends Vr{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),s=Q(n);o(null,s)}};function Yt(){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 i=typeof o=="string"?Q(o):o;return typeof n=="function"?t(i,n):t(i,n,s)},process.stderr.write=function(o,n,s){let i=typeof o=="string"?Q(o):o;return typeof n=="function"?r(i,n):r(i,n,s)}}var Ne=null,Bt=e=>(Ne&&Ne.destroy(),Ne=new ne({totalAllowedTime:e}),Ne),qt=()=>Ne;var ne=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,i=null;o!==void 0&&(i=new Promise((a,l)=>{s=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return i?await Promise.race([r(),i]):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 Ht="netlify-agent-runner-context.md",ot="task-history",V=".netlify",ae="results.md",it="assets";var le=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Wt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.1-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var on=tn(import.meta.url),sn=ee.dirname(on),an=rn(import.meta.url),ye=w("shell"),st=new Set,ln={preferLocal:!0},v=(e,t,r)=>{let[o,n]=cn(t,r),s={...ln,...n},i=nn(e,o,s);un(i,s),pn(i);let a=r?.idleTimeout;return a&&a>0&&dn(i,a),i};var cn=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},un=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(z.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new he).pipe(z.stdout),e.stdout?.pipe(new he).pipe(z.stdout),e.stderr?.pipe(new he).pipe(z.stderr);return}e.stdout?.pipe(z.stdout),e.stderr?.pipe(z.stderr)},at=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(z.kill(-e.pid,t),ye.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return ye.error("Error killing process:",r),!1}},Kt=e=>at(e,"SIGKILL"),dn=(e,t)=>{let r=null,o=()=>{ye.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),at(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ye.log(`Force killing idle process ${e.pid}`),Kt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let s=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",s),e.on("error",s)},pn=e=>{st.add(e);let t=qt();if(t){let r=t.onTimesUp(()=>{ye.log(`Global timer expired, killing process ${e.pid}`),at(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ye.log(`Force killing process ${e.pid} after timeout`),Kt(e))},5e3)});e.on("exit",()=>{st.delete(e),r()}),e.on("error",()=>{st.delete(e),r()})}};function Ge(e,t){return!!te(e,t)}function te(e,t){if(!z.env.NETLIFY_LOCAL_MODE)try{let n=an.resolve(Wt.name),s=ee.dirname(n);for(;s!==ee.dirname(s);){let i=ee.dirname(s);if(ee.basename(i)==="node_modules"){let a=ee.join(i,".bin",t);if(Ue.existsSync(a))return a;break}s=i}}catch(n){console.error("Could not resolve package.json",n)}if(z.env.NODE_PATH){let n=ee.join(z.env.NODE_PATH,".bin",t);if(Ue.existsSync(n))return n}let r=ee.join(e,"node_modules",".bin",t);if(Ue.existsSync(r))return r;let o=ee.join(sn,"..","node_modules",".bin",t);if(Ue.existsSync(o))return o}var mn=w("utils"),gn=e=>new Promise(t=>{setTimeout(t,e)}),Jt=(e,t=3e3)=>{let r=!1,o=null,n=[],s=null,i=(...a)=>{if(r)return o=a,new Promise(p=>{n.push(p)});r=!0;let l,d=new Promise(p=>{l=p});return s=(async()=>{await Promise.resolve();let p=await e(...a);for(l(p);;){if(await gn(t),!o)return r=!1,s=null,p;let u=o,m=n;o=null,n=[],p=await e(...u),m.forEach(E=>{E(p)})}})(),d};return i.flush=async()=>{if((r||o)&&s)return await s,i.flush()},i},Ee=(e,t,r=!1)=>{let o=null,n=null,s=null,i=function(...a){n=a,s=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(s,n),n=null,s=null)},t),l&&(e.apply(s,n),n=null,s=null)};return i.cancel=()=>{clearTimeout(o),o=null,n=null,s=null},i.flush=()=>{if(o){clearTimeout(o);let a=n,l=s;o=null,n=null,s=null,e.apply(l,a)}},i},Vt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):mn.error("Could not parse JSON",o))}},lt=e=>e.charAt(0).toUpperCase()+e.slice(1),ce=e=>e.split("-").map(lt).join(" "),zt=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),Xt=(e,t)=>{let n=".netlify.app",s="agent-";if(!t)return`${s}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=s.length+6){let d=Math.min(l-s.length,e.length);return`${s}${e.slice(0,d)}`}return e.slice(0,l)};var fn=50*1024,ct=(e,t=fn)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as Zt}from"buffer";import hn from"path";var Qt=w("repo"),tr=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{Qt.info("Getting runner diffs");let o=await En(r),{hasChanges:n}=o,{status:s}=o;if(!n)return{hasChanges:!1};if(!t){let T=wn(s);await Tn(T,r)}Qt.info("Changes after processing"),await dt(r);let i=await pt(s,r);if(await ut(i,r),n=await _n(r),!n)return{hasChanges:!1,ignored:i};process.env.NETLIFY_INTERNAL_GIT="1";try{await v("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await v("git",["diff",e.runSha,"HEAD"],a),d=String(l.stdout??"");if(n=!!d,!n)return await er(r),{hasChanges:!1,ignored:i};let p=await v("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(p.stdout??""),m,E;if(e.sha){let T=await v("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let I=await v("git",["diff",e.sha,"HEAD","--binary"],a),y=String(I.stdout??"");m!==y&&(E=Zt.from(y).toString("base64"))}await er(r);let _={hasChanges:!0,diff:d,resultDiff:m,ignored:i};return d!==u&&(_.diffBinary=Zt.from(u).toString("base64")),E&&(_.resultDiffBinary=E),_},er=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await v("git",["reset","--soft","HEAD~1"],{cwd:e})},ut=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await v("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},dt=async(e=process.cwd())=>{let t=await v("git",["status","-s"],{cwd:e});return String(t.stdout??"")},rr=/.. (.+)?\.log$/,yn=[rr],En=async(e=process.cwd())=>{let t=await dt(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
9
9
  `).filter(n=>yn.some(i=>i instanceof RegExp?i.test(n):n===i)?!1:n[1]?.trim()!=="")).length!==0,status:t}},_n=async(e=process.cwd())=>{try{return await v("git",["diff","--staged","--quiet"],{cwd:e}),!1}catch{return!0}},Pe=async(e=process.cwd())=>{let{stdout:t}=await v("git",["rev-parse","HEAD"],{cwd:e});return String(t??"").trim()},nr=async(e=process.cwd())=>{let{stdout:t}=await v("git",["rev-list","--max-parents=0","HEAD"],{cwd:e});return String(t??"").trim()},pt=async(e,t=process.cwd())=>{e||=await dt(t);let r=[".netlify","node_modules","dist",".next","out",".nuxt",".output",".cache",".turbo",".parcel-cache","coverage",".nyc_output","storybook-static","public/build","CLAUDE.local.md"],o=[];return e.split(`
10
10
  `).forEach(n=>{r.forEach(i=>{let a=n===`?? ${i}`,l=n.startsWith(`?? ${i}/`)||n.startsWith(`?? ${i}${hn.sep}`);(a||l)&&o.push(`:!${i}`)});let s=n.match(rr)?.[1];s&&o.push(`:!${s}.log`)}),o},mt=async(e=process.cwd())=>{await v("git",["reset","--hard","HEAD"],{cwd:e})},wn=e=>{let t=e.split(`
11
11
  `).reduce((r,o)=>{if(!o)return r;let[n,s,,...i]=o,a=i.join(""),l=n.trim(),d=s.trim();return r[a]?r[a].change=d:r[a]={filePath:a,stage:l,change:d},r},{});return Object.values(t)},Tn=async(e,t=process.cwd())=>{let r=e.filter(o=>o.stage&&!o.change).map(o=>o.filePath);r.length!==0&&await v("git",["restore","--staged","--worktree","--pathspec-from-file=-"],{cwd:t,input:r.join(`
package/dist/bin.js CHANGED
@@ -5,7 +5,7 @@ import bt from"process";import Po from"minimist";import{createRequire as To}from
5
5
  ${s}
6
6
  </extracted_error_chunk>`).join(`
7
7
 
8
- `);return i.length>e.length*.8?e:i}import{execSync as Hn}from"child_process";import Ar from"fs/promises";import qn from"path";import ne from"process";import{getTracer as Wn}from"@netlify/otel";import ve from"process";var pe=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},Lt=e=>e instanceof pe;var Le=ve.env.NETLIFY_API_URL,De=ve.env.NETLIFY_API_TOKEN,H=w("api"),Ae=()=>ve.env.NETLIFY_LOCAL_MODE==="true",de=async(e,t={})=>{if(!Le||!De)throw new Error("No API URL or token");let r=new URL(e,Le),o={...t,headers:{...t.headers,Authorization:`Bearer ${De}`}};ve.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),i=n.ok&&n.status<=299;if(ve.env.AGENT_RUNNERS_DEBUG==="true")H.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{H.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");H.log(`Request ID for ${r}: ${a||"N/A"}`)}if(i||H.error(`Got status ${n.status} for request ${r}`),t.raw){if(!i)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let s=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!i){let a=typeof s=="string"?s:JSON.stringify(s);throw n.status===404?new pe(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new pe(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return s},Dt=e=>{H.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Le=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(De=e.constants.NETLIFY_API_TOKEN)},$t=()=>({apiUrl:Le,token:De}),Ce=async(e,t)=>Ae()?(H.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):de(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),j=async(e,t,r)=>Ae()?(H.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):de(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Mt=async(e,t)=>Ae()?(H.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):de(`/api/v1/agent_runners/${e}/sessions/${t}`),Ut=(e,t,r)=>de(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Gt=async(e,t)=>Ae()?(H.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):de(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),jt=async(e,t)=>Ae()?(H.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):de(`/access-control/bb-api/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),et=async(e,t)=>{H.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var me=w("ai_gateway"),tt=null;var Yt=async()=>{if(tt)return tt;me.log("Fetching available AI gateway providers");let e=await fetch(`${$t().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return tt=t,me.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},en=async(e,t)=>{let o=(await Yt()).providers[e];if(!o)return me.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return me.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},Bt=async({netlify:e,config:t})=>{let r,o,n,i,s=e.constants?.SITE_ID;if(!s)throw new Error("No site id");let a=async()=>{clearTimeout(n),me.log("Requesting AI gateway information");let l=await Ut(s,t.id,t.sessionId);if({token:r,url:i}=l,o=l.expires_at?l.expires_at*1e3:void 0,me.log("Got AI gateway information",{token:!!r,expiresAt:o,url:i}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{a()},p))}};return await Promise.all([a(),Yt()]),{get url(){return i},get token(){return r},isModelAvailableForProvider:en}};import V from"process";import Z from"path";import $e from"fs";import{fileURLToPath as ln}from"url";import{createRequire as cn}from"module";import{execa as un,execaCommand as cs}from"execa";import{Transform as tn}from"stream";var rn=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_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"]),nn=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function on(){return Object.entries(process.env).filter(([e,t])=>!(!t||rn.has(e)||nn.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function X(e){if(typeof e!="string")return e;let t=on();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(sn(o),"g");r=r.replace(n,"******")}),r}function sn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var ge=class extends tn{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),i=X(n);o(null,i)}};function Ht(){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,i){let s=typeof o=="string"?X(o):o;return typeof n=="function"?t(s,n):t(s,n,i)},process.stderr.write=function(o,n,i){let s=typeof o=="string"?X(o):o;return typeof n=="function"?r(s,n):r(s,n,i)}}var be=null,qt=e=>(be&&be.destroy(),be=new ee({totalAllowedTime:e}),be),Wt=()=>be;var ee=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.`)}),i=null,s=null;o!==void 0&&(s=new Promise((a,l)=>{i=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return s?await Promise.race([r(),s]):await r()}finally{n(),i&&clearTimeout(i)}};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 Kt="netlify-agent-runner-context.md",rt="task-history",K=".netlify",se="results.md",nt="assets",ot="other",st="personal";var it="enterprise",at="free",Vt=[st,"pro",it,at],Jt=["normal","redeploy","create","ask","dtn-prod-iteration","rebase"],zt="The production deploy has changed since you started working. Please reapply the changes to the current codebase, resolving any conflicts that arise. Use the attached diff file if present, otherwise review the previous session context to reproduce the changes.",ie=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Xt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.0-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var pn=ln(import.meta.url),dn=Z.dirname(pn),mn=cn(import.meta.url),fe=w("shell"),lt=new Set,gn={preferLocal:!0},A=(e,t,r)=>{let[o,n]=fn(t,r),i={...gn,...n},s=un(e,o,i);hn(s,i),En(s);let a=r?.idleTimeout;return a&&a>0&&yn(s,a),s};var fn=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},hn=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(V.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new ge).pipe(V.stdout),e.stdout?.pipe(new ge).pipe(V.stdout),e.stderr?.pipe(new ge).pipe(V.stderr);return}e.stdout?.pipe(V.stdout),e.stderr?.pipe(V.stderr)},ct=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(V.kill(-e.pid,t),fe.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return fe.error("Error killing process:",r),!1}},Zt=e=>ct(e,"SIGKILL"),yn=(e,t)=>{let r=null,o=()=>{fe.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),ct(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(fe.log(`Force killing idle process ${e.pid}`),Zt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let i=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",i),e.on("error",i)},En=e=>{lt.add(e);let t=Wt();if(t){let r=t.onTimesUp(()=>{fe.log(`Global timer expired, killing process ${e.pid}`),ct(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(fe.log(`Force killing process ${e.pid} after timeout`),Zt(e))},5e3)});e.on("exit",()=>{lt.delete(e),r()}),e.on("error",()=>{lt.delete(e),r()})}};function te(e,t){if(!V.env.NETLIFY_LOCAL_MODE)try{let n=mn.resolve(Xt.name),i=Z.dirname(n);for(;i!==Z.dirname(i);){let s=Z.dirname(i);if(Z.basename(s)==="node_modules"){let a=Z.join(s,".bin",t);if($e.existsSync(a))return a;break}i=s}}catch(n){console.error("Could not resolve package.json",n)}if(V.env.NODE_PATH){let n=Z.join(V.env.NODE_PATH,".bin",t);if($e.existsSync(n))return n}let r=Z.join(e,"node_modules",".bin",t);if($e.existsSync(r))return r;let o=Z.join(dn,"..","node_modules",".bin",t);if($e.existsSync(o))return o}var Qt=w("utils"),_n=e=>new Promise(t=>{setTimeout(t,e)}),er=(e,t=3e3)=>{let r=!1,o=null,n=[],i=null,s=(...a)=>{if(r)return o=a,new Promise(d=>{n.push(d)});r=!0;let l,p=new Promise(d=>{l=d});return i=(async()=>{await Promise.resolve();let d=await e(...a);for(l(d);;){if(await _n(t),!o)return r=!1,i=null,d;let u=o,m=n;o=null,n=[],d=await e(...u),m.forEach(y=>{y(d)})}})(),p};return s.flush=async()=>{if((r||o)&&i)return await i,s.flush()},s},he=(e,t,r=!1)=>{let o=null,n=null,i=null,s=function(...a){n=a,i=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(i,n),n=null,i=null)},t),l&&(e.apply(i,n),n=null,i=null)};return s.cancel=()=>{clearTimeout(o),o=null,n=null,i=null},s.flush=()=>{if(o){clearTimeout(o);let a=n,l=i;o=null,n=null,i=null,e.apply(l,a)}},s},Me=(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))}},ut=e=>e.charAt(0).toUpperCase()+e.slice(1),ae=e=>e.split("-").map(ut).join(" "),tr=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),rr=(e,t)=>{let n=".netlify.app",i="agent-";if(!t)return`${i}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=i.length+6){let p=Math.min(l-i.length,e.length);return`${i}${e.slice(0,p)}`}return e.slice(0,l)},wn=e=>!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0?!1:!!Vt.some(t=>t in e),nr=()=>{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 i=JSON.parse(o);wn(i)&&(e[r]=i)}catch(i){let a=i instanceof SyntaxError?"Invalid JSON":i.message;Qt.error(`Could not parse ${r} model version override from ${n}: ${a}`)}}}),e},Tn=50*1024,pt=(e,t=Tn)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as or}from"buffer";import xn from"path";var sr=w("repo"),ar=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{sr.info("Getting runner diffs");let o=await In(r),{hasChanges:n}=o,{status:i}=o;if(!n)return{hasChanges:!1};if(!t){let T=vn(i);await An(T,r)}sr.info("Changes after processing"),await mt(r);let s=await ft(i,r);if(await dt(s,r),n=await Sn(r),!n)return{hasChanges:!1,ignored:s};process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await A("git",["diff",e.runSha,"HEAD"],a),p=String(l.stdout??"");if(n=!!p,!n)return await ir(r),{hasChanges:!1,ignored:s};let d=await A("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(d.stdout??""),m,y;if(e.sha){let T=await A("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let x=await A("git",["diff",e.sha,"HEAD","--binary"],a),E=String(x.stdout??"");m!==E&&(y=or.from(E).toString("base64"))}await ir(r);let _={hasChanges:!0,diff:p,resultDiff:m,ignored:s};return p!==u&&(_.diffBinary=or.from(u).toString("base64")),y&&(_.resultDiffBinary=y),_},ir=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await A("git",["reset","--soft","HEAD~1"],{cwd:e})},dt=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},mt=async(e=process.cwd())=>{let t=await A("git",["status","-s"],{cwd:e});return String(t.stdout??"")},lr=/.. (.+)?\.log$/,Rn=[lr],In=async(e=process.cwd())=>{let t=await mt(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
8
+ `);return i.length>e.length*.8?e:i}import{execSync as Hn}from"child_process";import Ar from"fs/promises";import qn from"path";import ne from"process";import{getTracer as Wn}from"@netlify/otel";import ve from"process";var pe=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},Lt=e=>e instanceof pe;var Le=ve.env.NETLIFY_API_URL,De=ve.env.NETLIFY_API_TOKEN,H=w("api"),Ae=()=>ve.env.NETLIFY_LOCAL_MODE==="true",de=async(e,t={})=>{if(!Le||!De)throw new Error("No API URL or token");let r=new URL(e,Le),o={...t,headers:{...t.headers,Authorization:`Bearer ${De}`}};ve.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),i=n.ok&&n.status<=299;if(ve.env.AGENT_RUNNERS_DEBUG==="true")H.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{H.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");H.log(`Request ID for ${r}: ${a||"N/A"}`)}if(i||H.error(`Got status ${n.status} for request ${r}`),t.raw){if(!i)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let s=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!i){let a=typeof s=="string"?s:JSON.stringify(s);throw n.status===404?new pe(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new pe(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return s},Dt=e=>{H.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Le=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&(De=e.constants.NETLIFY_API_TOKEN)},$t=()=>({apiUrl:Le,token:De}),Ce=async(e,t)=>Ae()?(H.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):de(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),j=async(e,t,r)=>Ae()?(H.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):de(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Mt=async(e,t)=>Ae()?(H.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):de(`/api/v1/agent_runners/${e}/sessions/${t}`),Ut=(e,t,r)=>de(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Gt=async(e,t)=>Ae()?(H.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):de(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),jt=async(e,t)=>Ae()?(H.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):de(`/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),et=async(e,t)=>{H.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var me=w("ai_gateway"),tt=null;var Yt=async()=>{if(tt)return tt;me.log("Fetching available AI gateway providers");let e=await fetch(`${$t().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return tt=t,me.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},en=async(e,t)=>{let o=(await Yt()).providers[e];if(!o)return me.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return me.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},Bt=async({netlify:e,config:t})=>{let r,o,n,i,s=e.constants?.SITE_ID;if(!s)throw new Error("No site id");let a=async()=>{clearTimeout(n),me.log("Requesting AI gateway information");let l=await Ut(s,t.id,t.sessionId);if({token:r,url:i}=l,o=l.expires_at?l.expires_at*1e3:void 0,me.log("Got AI gateway information",{token:!!r,expiresAt:o,url:i}),o){let p=o-Date.now()-6e4;p>0&&(n=setTimeout(()=>{a()},p))}};return await Promise.all([a(),Yt()]),{get url(){return i},get token(){return r},isModelAvailableForProvider:en}};import V from"process";import Z from"path";import $e from"fs";import{fileURLToPath as ln}from"url";import{createRequire as cn}from"module";import{execa as un,execaCommand as cs}from"execa";import{Transform as tn}from"stream";var rn=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_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"]),nn=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function on(){return Object.entries(process.env).filter(([e,t])=>!(!t||rn.has(e)||nn.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function X(e){if(typeof e!="string")return e;let t=on();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(sn(o),"g");r=r.replace(n,"******")}),r}function sn(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var ge=class extends tn{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),i=X(n);o(null,i)}};function Ht(){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,i){let s=typeof o=="string"?X(o):o;return typeof n=="function"?t(s,n):t(s,n,i)},process.stderr.write=function(o,n,i){let s=typeof o=="string"?X(o):o;return typeof n=="function"?r(s,n):r(s,n,i)}}var be=null,qt=e=>(be&&be.destroy(),be=new ee({totalAllowedTime:e}),be),Wt=()=>be;var ee=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.`)}),i=null,s=null;o!==void 0&&(s=new Promise((a,l)=>{i=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return s?await Promise.race([r(),s]):await r()}finally{n(),i&&clearTimeout(i)}};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 Kt="netlify-agent-runner-context.md",rt="task-history",K=".netlify",se="results.md",nt="assets",ot="other",st="personal";var it="enterprise",at="free",Vt=[st,"pro",it,at],Jt=["normal","redeploy","create","ask","dtn-prod-iteration","rebase"],zt="The production deploy has changed since you started working. Please reapply the changes to the current codebase, resolving any conflicts that arise. Use the attached diff file if present, otherwise review the previous session context to reproduce the changes.",ie=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Xt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.1-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var pn=ln(import.meta.url),dn=Z.dirname(pn),mn=cn(import.meta.url),fe=w("shell"),lt=new Set,gn={preferLocal:!0},A=(e,t,r)=>{let[o,n]=fn(t,r),i={...gn,...n},s=un(e,o,i);hn(s,i),En(s);let a=r?.idleTimeout;return a&&a>0&&yn(s,a),s};var fn=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},hn=(e,t)=>{if(t.stdio!==void 0||t.stdout!==void 0||t.stderr!==void 0)return;if(V.env.NETLIFY_MASK_LOGS!=="false"){e.all?.pipe(new ge).pipe(V.stdout),e.stdout?.pipe(new ge).pipe(V.stdout),e.stderr?.pipe(new ge).pipe(V.stderr);return}e.stdout?.pipe(V.stdout),e.stderr?.pipe(V.stderr)},ct=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(V.kill(-e.pid,t),fe.log(`Killed process ${e.pid} with signal ${t}`),!0):!1}catch(r){return fe.error("Error killing process:",r),!1}},Zt=e=>ct(e,"SIGKILL"),yn=(e,t)=>{let r=null,o=()=>{fe.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),ct(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(fe.log(`Force killing idle process ${e.pid}`),Zt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let i=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",i),e.on("error",i)},En=e=>{lt.add(e);let t=Wt();if(t){let r=t.onTimesUp(()=>{fe.log(`Global timer expired, killing process ${e.pid}`),ct(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(fe.log(`Force killing process ${e.pid} after timeout`),Zt(e))},5e3)});e.on("exit",()=>{lt.delete(e),r()}),e.on("error",()=>{lt.delete(e),r()})}};function te(e,t){if(!V.env.NETLIFY_LOCAL_MODE)try{let n=mn.resolve(Xt.name),i=Z.dirname(n);for(;i!==Z.dirname(i);){let s=Z.dirname(i);if(Z.basename(s)==="node_modules"){let a=Z.join(s,".bin",t);if($e.existsSync(a))return a;break}i=s}}catch(n){console.error("Could not resolve package.json",n)}if(V.env.NODE_PATH){let n=Z.join(V.env.NODE_PATH,".bin",t);if($e.existsSync(n))return n}let r=Z.join(e,"node_modules",".bin",t);if($e.existsSync(r))return r;let o=Z.join(dn,"..","node_modules",".bin",t);if($e.existsSync(o))return o}var Qt=w("utils"),_n=e=>new Promise(t=>{setTimeout(t,e)}),er=(e,t=3e3)=>{let r=!1,o=null,n=[],i=null,s=(...a)=>{if(r)return o=a,new Promise(d=>{n.push(d)});r=!0;let l,p=new Promise(d=>{l=d});return i=(async()=>{await Promise.resolve();let d=await e(...a);for(l(d);;){if(await _n(t),!o)return r=!1,i=null,d;let u=o,m=n;o=null,n=[],d=await e(...u),m.forEach(y=>{y(d)})}})(),p};return s.flush=async()=>{if((r||o)&&i)return await i,s.flush()},s},he=(e,t,r=!1)=>{let o=null,n=null,i=null,s=function(...a){n=a,i=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(i,n),n=null,i=null)},t),l&&(e.apply(i,n),n=null,i=null)};return s.cancel=()=>{clearTimeout(o),o=null,n=null,i=null},s.flush=()=>{if(o){clearTimeout(o);let a=n,l=i;o=null,n=null,i=null,e.apply(l,a)}},s},Me=(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))}},ut=e=>e.charAt(0).toUpperCase()+e.slice(1),ae=e=>e.split("-").map(ut).join(" "),tr=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),rr=(e,t)=>{let n=".netlify.app",i="agent-";if(!t)return`${i}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=i.length+6){let p=Math.min(l-i.length,e.length);return`${i}${e.slice(0,p)}`}return e.slice(0,l)},wn=e=>!e||typeof e!="object"||Array.isArray(e)||Object.keys(e).length===0?!1:!!Vt.some(t=>t in e),nr=()=>{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 i=JSON.parse(o);wn(i)&&(e[r]=i)}catch(i){let a=i instanceof SyntaxError?"Invalid JSON":i.message;Qt.error(`Could not parse ${r} model version override from ${n}: ${a}`)}}}),e},Tn=50*1024,pt=(e,t=Tn)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as or}from"buffer";import xn from"path";var sr=w("repo"),ar=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{sr.info("Getting runner diffs");let o=await In(r),{hasChanges:n}=o,{status:i}=o;if(!n)return{hasChanges:!1};if(!t){let T=vn(i);await An(T,r)}sr.info("Changes after processing"),await mt(r);let s=await ft(i,r);if(await dt(s,r),n=await Sn(r),!n)return{hasChanges:!1,ignored:s};process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await A("git",["diff",e.runSha,"HEAD"],a),p=String(l.stdout??"");if(n=!!p,!n)return await ir(r),{hasChanges:!1,ignored:s};let d=await A("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(d.stdout??""),m,y;if(e.sha){let T=await A("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let x=await A("git",["diff",e.sha,"HEAD","--binary"],a),E=String(x.stdout??"");m!==E&&(y=or.from(E).toString("base64"))}await ir(r);let _={hasChanges:!0,diff:p,resultDiff:m,ignored:s};return p!==u&&(_.diffBinary=or.from(u).toString("base64")),y&&(_.resultDiffBinary=y),_},ir=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await A("git",["reset","--soft","HEAD~1"],{cwd:e})},dt=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},mt=async(e=process.cwd())=>{let t=await A("git",["status","-s"],{cwd:e});return String(t.stdout??"")},lr=/.. (.+)?\.log$/,Rn=[lr],In=async(e=process.cwd())=>{let t=await mt(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
9
9
  `).filter(n=>Rn.some(s=>s instanceof RegExp?s.test(n):n===s)?!1:n[1]?.trim()!=="")).length!==0,status:t}},Sn=async(e=process.cwd())=>{try{return await A("git",["diff","--staged","--quiet"],{cwd:e}),!1}catch{return!0}},gt=async(e=process.cwd())=>{let{stdout:t}=await A("git",["rev-parse","HEAD"],{cwd:e});return String(t??"").trim()},cr=async(e=process.cwd())=>{let{stdout:t}=await A("git",["rev-list","--max-parents=0","HEAD"],{cwd:e});return String(t??"").trim()},ft=async(e,t=process.cwd())=>{e||=await mt(t);let r=[".netlify","node_modules","dist",".next","out",".nuxt",".output",".cache",".turbo",".parcel-cache","coverage",".nyc_output","storybook-static","public/build","CLAUDE.local.md"],o=[];return e.split(`
10
10
  `).forEach(n=>{r.forEach(s=>{let a=n===`?? ${s}`,l=n.startsWith(`?? ${s}/`)||n.startsWith(`?? ${s}${xn.sep}`);(a||l)&&o.push(`:!${s}`)});let i=n.match(lr)?.[1];i&&o.push(`:!${i}.log`)}),o},ht=async(e=process.cwd())=>{await A("git",["reset","--hard","HEAD"],{cwd:e})},vn=e=>{let t=e.split(`
11
11
  `).reduce((r,o)=>{if(!o)return r;let[n,i,,...s]=o,a=s.join(""),l=n.trim(),p=i.trim();return r[a]?r[a].change=p:r[a]={filePath:a,stage:l,change:p},r},{});return Object.values(t)},An=async(e,t=process.cwd())=>{let r=e.filter(o=>o.stage&&!o.change).map(o=>o.filePath);r.length!==0&&await A("git",["restore","--staged","--worktree","--pathspec-from-file=-"],{cwd:t,input:r.join(`
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import{createRequire as oo}from"module";import{createTracerProvider as kr}from"@
4
4
  ${s}
5
5
  </extracted_error_chunk>`).join(`
6
6
 
7
- `);return i.length>e.length*.8?e:i}import{execSync as bn}from"child_process";import fr from"fs/promises";import Cn from"path";import re from"process";import{getTracer as Nn}from"@netlify/otel";import Re from"process";var ue=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},At=e=>e instanceof ue;var Oe=Re.env.NETLIFY_API_URL,$e=Re.env.NETLIFY_API_TOKEN,q=w("api"),Se=()=>Re.env.NETLIFY_LOCAL_MODE==="true",de=async(e,t={})=>{if(!Oe||!$e)throw new Error("No API URL or token");let r=new URL(e,Oe),o={...t,headers:{...t.headers,Authorization:`Bearer ${$e}`}};Re.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),i=n.ok&&n.status<=299;if(Re.env.AGENT_RUNNERS_DEBUG==="true")q.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{q.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");q.log(`Request ID for ${r}: ${a||"N/A"}`)}if(i||q.error(`Got status ${n.status} for request ${r}`),t.raw){if(!i)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let s=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!i){let a=typeof s=="string"?s:JSON.stringify(s);throw n.status===404?new ue(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new ue(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return s},bt=e=>{q.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Oe=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&($e=e.constants.NETLIFY_API_TOKEN)},Ct=()=>({apiUrl:Oe,token:$e}),ve=async(e,t)=>Se()?(q.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):de(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),j=async(e,t,r)=>Se()?(q.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):de(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Nt=async(e,t)=>Se()?(q.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):de(`/api/v1/agent_runners/${e}/sessions/${t}`),Pt=(e,t,r)=>de(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),kt=async(e,t)=>Se()?(q.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):de(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),Ot=async(e,t)=>Se()?(q.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):de(`/access-control/bb-api/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),Xe=async(e,t)=>{q.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var pe=w("ai_gateway"),Ze=null;var $t=async()=>{if(Ze)return Ze;pe.log("Fetching available AI gateway providers");let e=await fetch(`${Ct().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return Ze=t,pe.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},Mr=async(e,t)=>{let o=(await $t()).providers[e];if(!o)return pe.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return pe.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},Ft=async({netlify:e,config:t})=>{let r,o,n,i,s=e.constants?.SITE_ID;if(!s)throw new Error("No site id");let a=async()=>{clearTimeout(n),pe.log("Requesting AI gateway information");let l=await Pt(s,t.id,t.sessionId);if({token:r,url:i}=l,o=l.expires_at?l.expires_at*1e3:void 0,pe.log("Got AI gateway information",{token:!!r,expiresAt:o,url:i}),o){let d=o-Date.now()-6e4;d>0&&(n=setTimeout(()=>{a()},d))}};return await Promise.all([a(),$t()]),{get url(){return i},get token(){return r},isModelAvailableForProvider:Mr}};import K from"process";import X from"path";import Fe from"fs";import{fileURLToPath as Hr}from"url";import{createRequire as Wr}from"module";import{execa as Kr,execaCommand as Uo}from"execa";import{Transform as Ur}from"stream";var Gr=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_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"]),jr=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Yr(){return Object.entries(process.env).filter(([e,t])=>!(!t||Gr.has(e)||jr.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function z(e){if(typeof e!="string")return e;let t=Yr();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Br(o),"g");r=r.replace(n,"******")}),r}function Br(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var me=class extends Ur{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),i=z(n);o(null,i)}};function Dt(){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,i){let s=typeof o=="string"?z(o):o;return typeof n=="function"?t(s,n):t(s,n,i)},process.stderr.write=function(o,n,i){let s=typeof o=="string"?z(o):o;return typeof n=="function"?r(s,n):r(s,n,i)}}var Ae=null,Lt=e=>(Ae&&Ae.destroy(),Ae=new Q({totalAllowedTime:e}),Ae),Mt=()=>Ae;var Q=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.`)}),i=null,s=null;o!==void 0&&(s=new Promise((a,l)=>{i=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return s?await Promise.race([r(),s]):await r()}finally{n(),i&&clearTimeout(i)}};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 Ut="netlify-agent-runner-context.md",Qe="task-history",W=".netlify",oe="results.md",et="assets";var se=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Gt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.0-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var Jr=Hr(import.meta.url),Vr=X.dirname(Jr),zr=Wr(import.meta.url),ge=w("shell"),tt=new Set,Xr={preferLocal:!0},A=(e,t,r)=>{let[o,n]=Zr(t,r),i={...Xr,...n},s=Kr(e,o,i);Qr(s,i),tn(s);let a=r?.idleTimeout;return a&&a>0&&en(s,a),s};var Zr=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Qr=(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 me).pipe(K.stdout),e.stdout?.pipe(new me).pipe(K.stdout),e.stderr?.pipe(new me).pipe(K.stderr);return}e.stdout?.pipe(K.stdout),e.stderr?.pipe(K.stderr)},rt=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(K.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}},jt=e=>rt(e,"SIGKILL"),en=(e,t)=>{let r=null,o=()=>{ge.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),rt(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing idle process ${e.pid}`),jt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let i=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",i),e.on("error",i)},tn=e=>{tt.add(e);let t=Mt();if(t){let r=t.onTimesUp(()=>{ge.log(`Global timer expired, killing process ${e.pid}`),rt(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing process ${e.pid} after timeout`),jt(e))},5e3)});e.on("exit",()=>{tt.delete(e),r()}),e.on("error",()=>{tt.delete(e),r()})}};function ee(e,t){if(!K.env.NETLIFY_LOCAL_MODE)try{let n=zr.resolve(Gt.name),i=X.dirname(n);for(;i!==X.dirname(i);){let s=X.dirname(i);if(X.basename(s)==="node_modules"){let a=X.join(s,".bin",t);if(Fe.existsSync(a))return a;break}i=s}}catch(n){console.error("Could not resolve package.json",n)}if(K.env.NODE_PATH){let n=X.join(K.env.NODE_PATH,".bin",t);if(Fe.existsSync(n))return n}let r=X.join(e,"node_modules",".bin",t);if(Fe.existsSync(r))return r;let o=X.join(Vr,"..","node_modules",".bin",t);if(Fe.existsSync(o))return o}var rn=w("utils"),nn=e=>new Promise(t=>{setTimeout(t,e)}),Yt=(e,t=3e3)=>{let r=!1,o=null,n=[],i=null,s=(...a)=>{if(r)return o=a,new Promise(p=>{n.push(p)});r=!0;let l,d=new Promise(p=>{l=p});return i=(async()=>{await Promise.resolve();let p=await e(...a);for(l(p);;){if(await nn(t),!o)return r=!1,i=null,p;let u=o,m=n;o=null,n=[],p=await e(...u),m.forEach(_=>{_(p)})}})(),d};return s.flush=async()=>{if((r||o)&&i)return await i,s.flush()},s},fe=(e,t,r=!1)=>{let o=null,n=null,i=null,s=function(...a){n=a,i=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(i,n),n=null,i=null)},t),l&&(e.apply(i,n),n=null,i=null)};return s.cancel=()=>{clearTimeout(o),o=null,n=null,i=null},s.flush=()=>{if(o){clearTimeout(o);let a=n,l=i;o=null,n=null,i=null,e.apply(l,a)}},s},Bt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):rn.error("Could not parse JSON",o))}},nt=e=>e.charAt(0).toUpperCase()+e.slice(1),ie=e=>e.split("-").map(nt).join(" "),qt=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),Ht=(e,t)=>{let n=".netlify.app",i="agent-";if(!t)return`${i}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=i.length+6){let d=Math.min(l-i.length,e.length);return`${i}${e.slice(0,d)}`}return e.slice(0,l)};var on=50*1024,ot=(e,t=on)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as Wt}from"buffer";import sn from"path";var Kt=w("repo"),Vt=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{Kt.info("Getting runner diffs");let o=await ln(r),{hasChanges:n}=o,{status:i}=o;if(!n)return{hasChanges:!1};if(!t){let T=un(i);await dn(T,r)}Kt.info("Changes after processing"),await it(r);let s=await lt(i,r);if(await st(s,r),n=await cn(r),!n)return{hasChanges:!1,ignored:s};process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await A("git",["diff",e.runSha,"HEAD"],a),d=String(l.stdout??"");if(n=!!d,!n)return await Jt(r),{hasChanges:!1,ignored:s};let p=await A("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(p.stdout??""),m,_;if(e.sha){let T=await A("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let x=await A("git",["diff",e.sha,"HEAD","--binary"],a),y=String(x.stdout??"");m!==y&&(_=Wt.from(y).toString("base64"))}await Jt(r);let E={hasChanges:!0,diff:d,resultDiff:m,ignored:s};return d!==u&&(E.diffBinary=Wt.from(u).toString("base64")),_&&(E.resultDiffBinary=_),E},Jt=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await A("git",["reset","--soft","HEAD~1"],{cwd:e})},st=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},it=async(e=process.cwd())=>{let t=await A("git",["status","-s"],{cwd:e});return String(t.stdout??"")},zt=/.. (.+)?\.log$/,an=[zt],ln=async(e=process.cwd())=>{let t=await it(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
7
+ `);return i.length>e.length*.8?e:i}import{execSync as bn}from"child_process";import fr from"fs/promises";import Cn from"path";import re from"process";import{getTracer as Nn}from"@netlify/otel";import Re from"process";var ue=class extends Error{constructor(r,o,n){super(r);this.statusCode=o;this.userMessage=n;this.name="GracefulShutdownError"}},At=e=>e instanceof ue;var Oe=Re.env.NETLIFY_API_URL,$e=Re.env.NETLIFY_API_TOKEN,q=w("api"),Se=()=>Re.env.NETLIFY_LOCAL_MODE==="true",de=async(e,t={})=>{if(!Oe||!$e)throw new Error("No API URL or token");let r=new URL(e,Oe),o={...t,headers:{...t.headers,Authorization:`Bearer ${$e}`}};Re.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),i=n.ok&&n.status<=299;if(Re.env.AGENT_RUNNERS_DEBUG==="true")q.log(`Response headers for ${r}:`),n.headers.forEach((a,l)=>{q.log(` ${l}: ${a}`)});else{let a=n.headers.get("x-request-id")||n.headers.get("x-nf-request-id");q.log(`Request ID for ${r}: ${a||"N/A"}`)}if(i||q.error(`Got status ${n.status} for request ${r}`),t.raw){if(!i)throw new Error(`API request failed: ${n.status} ${n.statusText}`);return n}let s=await(n.headers.get("content-type")?.includes("application/json")?n.json():n.text());if(!i){let a=typeof s=="string"?s:JSON.stringify(s);throw n.status===404?new ue(`API request failed: 404 - ${a}`,404,"The site associated with this agent run no longer exists."):n.status===503&&t.gracefulOn503&&a.toLowerCase().includes("usage exceeded")?new ue(`API request failed: 503 - ${a}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners."):new Error(`API request failed: ${n.status} - ${a}`)}return s},bt=e=>{q.log("Setting details for api",{apiUrl:e?.constants?.NETLIFY_API_HOST,token:!!e?.constants?.NETLIFY_API_TOKEN}),e?.constants?.NETLIFY_API_HOST&&(Oe=`https://${e.constants.NETLIFY_API_HOST}`),e?.constants?.NETLIFY_API_TOKEN&&($e=e.constants.NETLIFY_API_TOKEN)},Ct=()=>({apiUrl:Oe,token:$e}),ve=async(e,t)=>Se()?(q.log("Mock API: updateRunner called",{runnerId:e,data:t}),{id:e,...t}):de(`/api/v1/agent_runners/${e}`,{method:"PUT",json:t}),j=async(e,t,r)=>Se()?(q.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:e,sessionId:t,data:r},null,2)),{id:e,sessionId:t,...r}):de(`/api/v1/agent_runners/${e}/sessions/${t}`,{method:"PUT",json:r});var Nt=async(e,t)=>Se()?(q.log("Mock API: getRunnerSession called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,state:"running"}):de(`/api/v1/agent_runners/${e}/sessions/${t}`),Pt=(e,t,r)=>de(`/api/v1/sites/${e}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":t,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),kt=async(e,t)=>Se()?(q.log("Mock API: getDiffUploadUrls called",{runnerId:e,sessionId:t}),{result:{upload_url:"https://s3.mock.com/mock-upload-url-result",s3_key:"mock-s3-key-result"},cumulative:{upload_url:"https://s3.mock.com/mock-upload-url-cumulative",s3_key:"mock-s3-key-cumulative"}}):de(`/api/v1/agent_runners/${e}/sessions/${t}/diff/upload_urls`,{method:"POST"}),Ot=async(e,t)=>Se()?(q.log("Mock API: updateSessionUsage called",{runnerId:e,sessionId:t}),{id:t,runnerId:e,usage:0}):de(`/api/v1/agent_runners/${e}/sessions/${t}/update_usage`,{method:"POST"}),Xe=async(e,t)=>{q.log(`Uploading diff to S3: ${e.substring(0,50)}...`);let r=await fetch(e,{method:"PUT",body:t,headers:{"Content-Type":"text/plain"}});if(!r.ok)throw new Error(`S3 upload failed with status ${r.status}`);return r};var pe=w("ai_gateway"),Ze=null;var $t=async()=>{if(Ze)return Ze;pe.log("Fetching available AI gateway providers");let e=await fetch(`${Ct().apiUrl}/api/v1/ai-gateway/providers`);if(!e.ok)throw new Error(`Failed to fetch AI gateway providers: ${e.statusText}`);let t=await e.json();return Ze=t,pe.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},Mr=async(e,t)=>{let o=(await $t()).providers[e];if(!o)return pe.log(`Provider '${e}' not found`),!1;let n=o.models.includes(t);return pe.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},Ft=async({netlify:e,config:t})=>{let r,o,n,i,s=e.constants?.SITE_ID;if(!s)throw new Error("No site id");let a=async()=>{clearTimeout(n),pe.log("Requesting AI gateway information");let l=await Pt(s,t.id,t.sessionId);if({token:r,url:i}=l,o=l.expires_at?l.expires_at*1e3:void 0,pe.log("Got AI gateway information",{token:!!r,expiresAt:o,url:i}),o){let d=o-Date.now()-6e4;d>0&&(n=setTimeout(()=>{a()},d))}};return await Promise.all([a(),$t()]),{get url(){return i},get token(){return r},isModelAvailableForProvider:Mr}};import K from"process";import X from"path";import Fe from"fs";import{fileURLToPath as Hr}from"url";import{createRequire as Wr}from"module";import{execa as Kr,execaCommand as Uo}from"execa";import{Transform as Ur}from"stream";var Gr=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_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"]),jr=new Set(["true","false","undefined","null","deploy","project","claude","gemini","codex",""]);function Yr(){return Object.entries(process.env).filter(([e,t])=>!(!t||Gr.has(e)||jr.has(t)||!isNaN(Number(t))||t.length<5)).map(([,e])=>e).filter(Boolean)}function z(e){if(typeof e!="string")return e;let t=Yr();if(t.length===0)return e;let r=e;return t.forEach(o=>{let n=new RegExp(Br(o),"g");r=r.replace(n,"******")}),r}function Br(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}var me=class extends Ur{constructor(t={}){super({...t,objectMode:!1})}_transform(t,r,o){let n=t.toString(),i=z(n);o(null,i)}};function Dt(){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,i){let s=typeof o=="string"?z(o):o;return typeof n=="function"?t(s,n):t(s,n,i)},process.stderr.write=function(o,n,i){let s=typeof o=="string"?z(o):o;return typeof n=="function"?r(s,n):r(s,n,i)}}var Ae=null,Lt=e=>(Ae&&Ae.destroy(),Ae=new Q({totalAllowedTime:e}),Ae),Mt=()=>Ae;var Q=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.`)}),i=null,s=null;o!==void 0&&(s=new Promise((a,l)=>{i=setTimeout(()=>{l(new Error(`${t} stage exceeded its maximum duration of ${o}ms`))},o)}));try{return s?await Promise.race([r(),s]):await r()}finally{n(),i&&clearTimeout(i)}};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 Ut="netlify-agent-runner-context.md",Qe="task-history",W=".netlify",oe="results.md",et="assets";var se=1800*1e3,h={Environment:"environment",UserMessage:"user-message",AgentMessage:"agent-message",Task:"task",RunCommand:"run-command",Explore:"explore",Plan:"plan",FileRead:"file-read",FileWrite:"file-write",Notebook:"notebook",Web:"web",Todo:"todo",Reasoning:"reasoning",Skill:"skill",Memorize:"memorize",Deployment:"deployment",SiteGeneration:"site-generation"};var Gt={name:"@netlify/agent-runner-cli",type:"module",version:"1.77.1-alpha.0",description:"CLI tool for running Netlify agents",main:"./dist/index.js",types:"./dist/index.d.ts",exports:"./dist/index.js",bin:{"agent-runner-cli":"./dist/bin.js","agent-runner-cli-local":"./dist/bin-local.js"},files:["dist/**/*.js","dist/**/*.d.ts","dist/skills/**","patches","scripts"],scripts:{build:"tsup",dev:"tsup --watch",prepare:"husky install node_modules/@netlify/eslint-config-node/.husky/",prepublishOnly:"npm ci && npm test",prepack:"npm run build",test:"run-s build format test:dev",format:"run-s build format:check-fix:*","format:ci":"run-s build format:check:*","format:check-fix:lint":"run-e format:check:lint format:fix:lint","format:check:lint":"cross-env-shell eslint $npm_package_config_eslint","format:fix:lint":"cross-env-shell eslint --fix $npm_package_config_eslint","format:check-fix:prettier":"run-e format:check:prettier format:fix:prettier","format:check:prettier":"cross-env-shell prettier --check $npm_package_config_prettier","format:fix:prettier":"cross-env-shell prettier --write $npm_package_config_prettier","test:dev":"run-s build test:dev:*","test:ci":"run-s build test:ci:*","test:dev:vitest":"LOG=0 vitest --exclude '**/integration/**'","test:ci:vitest":"LOG=0 c8 -r lcovonly -r text -r json vitest --exclude '**/integration/**'","test:integration":"vitest run test/integration/","test:integration:codex":"vitest run test/integration/codex.test.ts","test:integration:claude":"vitest run test/integration/claude.test.ts","test:integration:gemini":"vitest run test/integration/gemini.test.ts","test:integration:create-stage":"vitest run test/integration/create.test.ts","test:integration:skill-invocation":"vitest run test/integration/skill-invocation.test.ts",postinstall:"node scripts/postinstall.js"},config:{eslint:'--cache --format=codeframe --max-warnings=0 "{src,scripts,test,.github}/**/*.{js,ts,md,html}"',prettier:'--ignore-path .gitignore --loglevel=warn "{src,scripts,test,.github}/**/*.{js,ts,md,yml,json,html}" "*.{js,ts,yml,json,html}" ".*.{js,ts,yml,json,html}" "!**/package-lock.json" "!package-lock.json" "!src/skills/**/*.md"'},keywords:[],license:"MIT",repository:"netlify/agent-runner-cli",bugs:{url:"https://github.com/netlify/agent-runner-cli/issues"},author:"Netlify Inc.",directories:{test:"test"},devDependencies:{"@commitlint/cli":"^20.0.0","@commitlint/config-conventional":"^20.0.0","@eslint/compat":"^2.0.0","@eslint/js":"^9.35.0","@netlify/eslint-config-node":"^7.0.1","@types/node":"^24.5.0","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/eslint-plugin":"^1.6.6",c8:"^10.0.0","eslint-config-prettier":"^10.1.8","eslint-plugin-n":"^17.0.0",husky:"^9.0.0","patch-package":"^8.0.0",tsup:"^8.5.0",typescript:"^5.0.0","typescript-eslint":"^8.44.0",vitest:"^4.0.16"},dependencies:{"@anthropic-ai/claude-code":"2.1.52","@anthropic-ai/sdk":"0.77.0","@google/gemini-cli":"0.29.3","@netlify/otel":"^5.1.1","@openai/codex":"0.104.0","@opentelemetry/exporter-trace-otlp-grpc":"^0.212.0",execa:"^9.6.1",kaddidlehopper:"^0.5.0",minimist:"^1.2.8",openai:"6.22.0"}};var Jr=Hr(import.meta.url),Vr=X.dirname(Jr),zr=Wr(import.meta.url),ge=w("shell"),tt=new Set,Xr={preferLocal:!0},A=(e,t,r)=>{let[o,n]=Zr(t,r),i={...Xr,...n},s=Kr(e,o,i);Qr(s,i),tn(s);let a=r?.idleTimeout;return a&&a>0&&en(s,a),s};var Zr=function(e,t){return Array.isArray(e)?[e,t]:typeof e=="object"&&e!==null?[[],e]:[[],void 0]},Qr=(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 me).pipe(K.stdout),e.stdout?.pipe(new me).pipe(K.stdout),e.stderr?.pipe(new me).pipe(K.stderr);return}e.stdout?.pipe(K.stdout),e.stderr?.pipe(K.stderr)},rt=(e,t="SIGTERM")=>{try{return e.pid&&!e.killed?(K.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}},jt=e=>rt(e,"SIGKILL"),en=(e,t)=>{let r=null,o=()=>{ge.log(`Process ${e.pid} killed due to idle timeout (no output for ${t}ms)`),rt(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing idle process ${e.pid}`),jt(e))},5e3)},n=()=>{r&&clearTimeout(r),r=setTimeout(o,t)};n(),e.stdout?.on("data",n),e.stderr?.on("data",n);let i=()=>{r&&(clearTimeout(r),r=null)};e.on("exit",i),e.on("error",i)},tn=e=>{tt.add(e);let t=Mt();if(t){let r=t.onTimesUp(()=>{ge.log(`Global timer expired, killing process ${e.pid}`),rt(e,"SIGTERM"),setTimeout(()=>{e.pid&&!e.killed&&(ge.log(`Force killing process ${e.pid} after timeout`),jt(e))},5e3)});e.on("exit",()=>{tt.delete(e),r()}),e.on("error",()=>{tt.delete(e),r()})}};function ee(e,t){if(!K.env.NETLIFY_LOCAL_MODE)try{let n=zr.resolve(Gt.name),i=X.dirname(n);for(;i!==X.dirname(i);){let s=X.dirname(i);if(X.basename(s)==="node_modules"){let a=X.join(s,".bin",t);if(Fe.existsSync(a))return a;break}i=s}}catch(n){console.error("Could not resolve package.json",n)}if(K.env.NODE_PATH){let n=X.join(K.env.NODE_PATH,".bin",t);if(Fe.existsSync(n))return n}let r=X.join(e,"node_modules",".bin",t);if(Fe.existsSync(r))return r;let o=X.join(Vr,"..","node_modules",".bin",t);if(Fe.existsSync(o))return o}var rn=w("utils"),nn=e=>new Promise(t=>{setTimeout(t,e)}),Yt=(e,t=3e3)=>{let r=!1,o=null,n=[],i=null,s=(...a)=>{if(r)return o=a,new Promise(p=>{n.push(p)});r=!0;let l,d=new Promise(p=>{l=p});return i=(async()=>{await Promise.resolve();let p=await e(...a);for(l(p);;){if(await nn(t),!o)return r=!1,i=null,p;let u=o,m=n;o=null,n=[],p=await e(...u),m.forEach(_=>{_(p)})}})(),d};return s.flush=async()=>{if((r||o)&&i)return await i,s.flush()},s},fe=(e,t,r=!1)=>{let o=null,n=null,i=null,s=function(...a){n=a,i=this;let l=r&&!o;clearTimeout(o),o=setTimeout(()=>{o=null,r||(e.apply(i,n),n=null,i=null)},t),l&&(e.apply(i,n),n=null,i=null)};return s.cancel=()=>{clearTimeout(o),o=null,n=null,i=null},s.flush=()=>{if(o){clearTimeout(o);let a=n,l=i;o=null,n=null,i=null,e.apply(l,a)}},s},Bt=(e,t=!0,r)=>{if(e)try{return JSON.parse(e)}catch(o){t&&(r?.error?r.error("Could not parse JSON",o):rn.error("Could not parse JSON",o))}},nt=e=>e.charAt(0).toUpperCase()+e.slice(1),ie=e=>e.split("-").map(nt).join(" "),qt=e=>Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0)),Ht=(e,t)=>{let n=".netlify.app",i="agent-";if(!t)return`${i}${e.slice(0,6)}`;let a=`--${t}${n}`;if(a.length>55)return"";let l=60-a.length;if(l<=0)return"";if(l>=i.length+6){let d=Math.min(l-i.length,e.length);return`${i}${e.slice(0,d)}`}return e.slice(0,l)};var on=50*1024,ot=(e,t=on)=>{if(!e||typeof e!="string"||e.length<=t)return e;let o=e.startsWith("```")?"\n... [truncated]\n```":"... [truncated]";return e.slice(0,t)+o};import{Buffer as Wt}from"buffer";import sn from"path";var Kt=w("repo"),Vt=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{Kt.info("Getting runner diffs");let o=await ln(r),{hasChanges:n}=o,{status:i}=o;if(!n)return{hasChanges:!1};if(!t){let T=un(i);await dn(T,r)}Kt.info("Changes after processing"),await it(r);let s=await lt(i,r);if(await st(s,r),n=await cn(r),!n)return{hasChanges:!1,ignored:s};process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["commit","-m","Agent runner"],{cwd:r})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}let a={stdio:["ignore","pipe","pipe"],cwd:r},l=await A("git",["diff",e.runSha,"HEAD"],a),d=String(l.stdout??"");if(n=!!d,!n)return await Jt(r),{hasChanges:!1,ignored:s};let p=await A("git",["diff",e.runSha,"HEAD","--binary"],a),u=String(p.stdout??""),m,_;if(e.sha){let T=await A("git",["diff",e.sha,"HEAD"],a);m=String(T.stdout??"");let x=await A("git",["diff",e.sha,"HEAD","--binary"],a),y=String(x.stdout??"");m!==y&&(_=Wt.from(y).toString("base64"))}await Jt(r);let E={hasChanges:!0,diff:d,resultDiff:m,ignored:s};return d!==u&&(E.diffBinary=Wt.from(u).toString("base64")),_&&(E.resultDiffBinary=_),E},Jt=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await A("git",["reset","--soft","HEAD~1"],{cwd:e})},st=async(e=[],t=process.cwd())=>{process.env.NETLIFY_INTERNAL_GIT="1";try{await A("git",["add",".",...e],{cwd:t})}finally{process.env.NETLIFY_INTERNAL_GIT="0"}},it=async(e=process.cwd())=>{let t=await A("git",["status","-s"],{cwd:e});return String(t.stdout??"")},zt=/.. (.+)?\.log$/,an=[zt],ln=async(e=process.cwd())=>{let t=await it(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
8
8
  `).filter(n=>an.some(s=>s instanceof RegExp?s.test(n):n===s)?!1:n[1]?.trim()!=="")).length!==0,status:t}},cn=async(e=process.cwd())=>{try{return await A("git",["diff","--staged","--quiet"],{cwd:e}),!1}catch{return!0}},at=async(e=process.cwd())=>{let{stdout:t}=await A("git",["rev-parse","HEAD"],{cwd:e});return String(t??"").trim()},Xt=async(e=process.cwd())=>{let{stdout:t}=await A("git",["rev-list","--max-parents=0","HEAD"],{cwd:e});return String(t??"").trim()},lt=async(e,t=process.cwd())=>{e||=await it(t);let r=[".netlify","node_modules","dist",".next","out",".nuxt",".output",".cache",".turbo",".parcel-cache","coverage",".nyc_output","storybook-static","public/build","CLAUDE.local.md"],o=[];return e.split(`
9
9
  `).forEach(n=>{r.forEach(s=>{let a=n===`?? ${s}`,l=n.startsWith(`?? ${s}/`)||n.startsWith(`?? ${s}${sn.sep}`);(a||l)&&o.push(`:!${s}`)});let i=n.match(zt)?.[1];i&&o.push(`:!${i}.log`)}),o},ct=async(e=process.cwd())=>{await A("git",["reset","--hard","HEAD"],{cwd:e})},un=e=>{let t=e.split(`
10
10
  `).reduce((r,o)=>{if(!o)return r;let[n,i,,...s]=o,a=s.join(""),l=n.trim(),d=i.trim();return r[a]?r[a].change=d:r[a]={filePath:a,stage:l,change:d},r},{});return Object.values(t)},dn=async(e,t=process.cwd())=>{let r=e.filter(o=>o.stage&&!o.change).map(o=>o.filePath);r.length!==0&&await A("git",["restore","--staged","--worktree","--pathspec-from-file=-"],{cwd:t,input:r.join(`
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/agent-runner-cli",
3
3
  "type": "module",
4
- "version": "1.77.0-alpha.0",
4
+ "version": "1.77.1-alpha.0",
5
5
  "description": "CLI tool for running Netlify agents",
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",