@netlify/agent-runner-cli 1.101.1 → 1.102.0-init.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.
@@ -0,0 +1,168 @@
1
+ import{a as Ue,b as R,c as ae,d as V,e as le,g as Ge,h as je,i as ee,j as F,k as Me,l as Ye,m as ze,n as He,o as qe,p as Be,q as Ie}from"./chunk-XIU5VIKI.js";import{A as ue,H as Qe,K as Se,M as ce,a as h,b as W,c as Ve,d as We,e as te,f as Je,g as _e,h as O,i as re,j as ne,k as Ke,t as Xe,u as Y,v,w as Ze,z as J}from"./chunk-GEX7LBQT.js";import{createRequire as yr}from"module";var Dt=["error","failed","exception","fatal","panic","abort","crash"];function et(e){let t=e.split(`
2
+ `),r=[],i=-1,n=0;for(;n<t.length;){let a=t[n].slice(0,500).toLowerCase();if(Dt.some(l=>a.includes(l))){let l=Math.max(0,n-10,i+1),u=Math.min(t.length-1,n+20),c=[];for(let d=l;d<=u;d++)c.push(t[d]);r.push(c.join(`
3
+ `)),i=u,n=u+1}else n++}if(r.length===0)return e;let o=r.map((s,a)=>`<extracted_error_chunk order="${a+1}">
4
+ ${s}
5
+ </extracted_error_chunk>`).join(`
6
+
7
+ `);return o.length>e.length*.8?e:o}import{execSync as Mt}from"child_process";import lt from"fs/promises";import Yt from"path";import z from"process";import{getTracer as zt}from"@netlify/otel";var K=h("ai_gateway"),xe=null;var de=async()=>{if(xe)return xe;K.log("Fetching available AI gateway providers");let e=await fetch(`${je().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 xe=t,K.log("Cached AI gateway providers",{providerCount:Object.keys(t.providers).length}),t},Nt=async(e,t)=>{let i=(await de()).providers[e];if(!i)return K.log(`Provider '${e}' not found`),!1;let n=i.models.includes(t);return K.log(`Model validation for ${e}/${t}`,{isAvailable:n}),n},tt=async({config:e})=>{let t,r,i,n,o=!e.site?.published_deploy;if(!(o?e.accountId:e.siteId))throw new Error(`No entity id for ${o?"account":"site"}`);let a=async()=>{clearTimeout(i),K.log("Requesting AI gateway information");let l=await(o?ze(e.accountId,e.id,e.sessionId):He(e.siteId,e.id,e.sessionId));if({token:t,url:n}=l,r=l.expires_at?l.expires_at*1e3:void 0,K.log("Got AI gateway information",{token:!!t,expiresAt:r,url:n}),r){let u=r-Date.now()-6e4;u>0&&(i=setTimeout(()=>{a()},u))}};return await Promise.all([a(),de()]),{get url(){return n},get token(){return t},isModelAvailableForProvider:Nt}};import{Buffer as rt}from"buffer";import Ft from"path";var nt=h("repo"),st=async({config:e,isRetry:t,cwd:r=process.cwd()})=>{nt.info("Getting runner diffs");let i=await Lt(r),{hasChanges:n}=i,{status:o}=i;if(!n)return{hasChanges:!1};if(!t){let y=Ut(o);await Gt(y,r)}nt.info("Changes after processing"),await Re(r);let s=await Ce(o,r);if(await Ee(s,r),n=await Ot(r),!n)return{hasChanges:!1,ignored:s};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},g=await v("git",["diff",e.runSha,"HEAD"],a),l=String(g.stdout??"");if(n=!!l,!n)return await it(r),{hasChanges:!1,ignored:s};let u=await v("git",["diff",e.runSha,"HEAD","--binary"],a),c=String(u.stdout??""),d,p;if(e.sha){let y=await v("git",["diff",e.sha,"HEAD"],a);d=String(y.stdout??"");let f=await v("git",["diff",e.sha,"HEAD","--binary"],a),x=String(f.stdout??"");d!==x&&(p=rt.from(x).toString("base64"))}await it(r);let m={hasChanges:!0,diff:l,resultDiff:d,ignored:s};return l!==c&&(m.diffBinary=rt.from(c).toString("base64")),p&&(m.resultDiffBinary=p),m},it=async(e=process.cwd())=>{process.env.NETLIFY_LOCAL_MODE&&await v("git",["reset","--soft","HEAD~1"],{cwd:e})},Ee=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"}},Re=async(e=process.cwd())=>{let t=await v("git",["status","-s"],{cwd:e});return String(t.stdout??"")},ot=/.. (.+)?\.log$/,$t=[ot],Lt=async(e=process.cwd())=>{let t=await Re(e);return{hasChanges:(t.trim().length===0?[]:t.split(`
8
+ `).filter(n=>$t.some(s=>s instanceof RegExp?s.test(n):n===s)?!1:n[1]?.trim()!=="")).length!==0,status:t}},Ot=async(e=process.cwd())=>{try{return await v("git",["diff","--staged","--quiet"],{cwd:e}),!1}catch{return!0}},ve=async(e=process.cwd())=>{let{stdout:t}=await v("git",["rev-parse","HEAD"],{cwd:e});return String(t??"").trim()},at=async(e=process.cwd())=>{let{stdout:t}=await v("git",["rev-list","--max-parents=0","HEAD"],{cwd:e});return String(t??"").trim()},Ce=async(e,t=process.cwd())=>{e||=await Re(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"],i=[];return e.split(`
9
+ `).forEach(n=>{r.forEach(s=>{let a=n===`?? ${s}`,g=n.startsWith(`?? ${s}/`)||n.startsWith(`?? ${s}${Ft.sep}`);(a||g)&&i.push(`:!${s}`)});let o=n.match(ot)?.[1];o&&i.push(`:!${o}.log`)}),i},be=async(e=process.cwd())=>{await v("git",["reset","--hard","HEAD"],{cwd:e})},Ut=e=>{let t=e.split(`
10
+ `).reduce((r,i)=>{if(!i)return r;let[n,o,,...s]=i,a=s.join(""),g=n.trim(),l=o.trim();return r[a]?r[a].change=l:r[a]={filePath:a,stage:g,change:l},r},{});return Object.values(t)},Gt=async(e,t=process.cwd())=>{let r=e.filter(i=>i.stage&&!i.change).map(i=>i.filePath);r.length!==0&&await v("git",["restore","--staged","--worktree","--pathspec-from-file=-"],{cwd:t,input:r.join(`
11
+ `)})};var jt={claude:async()=>{let e=await import("./claude-3LICIC3K.js");return{runner:e.default,clean:e.clean}},codex:async()=>{let e=await import("./codex-BBM2OQAI.js");return{runner:e.default,clean:e.clean}},gemini:async()=>{let e=await import("./gemini-RGNOCS6R.js");return{runner:e.default,clean:e.clean}}},pe=jt;var C=h("init_stage"),ut=async({config:e,apiThrottle:t,apiToken:r,runnerVersion:i})=>await R(zt(),"init-stage",async n=>{let o=performance.now();n?.setAttributes({"init.runner":e.runner,"init.id":e.id,"init.sessionId":e.sessionId,"init.hasRepo":e.hasRepo,"init.useGateway":e.useGateway,"init.runnerVersion":i||"unknown"});let s=pe[e.runner];if(!s)throw n?.setAttributes({"init.error":"unsupported_runner"}),new Error(`${e.runner} is not supported`);let a=await s(),g=qt({apiToken:r,config:e});if(Ge(g),e.siteId)try{C.log("Fetching site info"),e.site=await Me(e.siteId),C.log("Site info fetched")}catch(f){C.error("Failed to get the site information",{error:f})}C.log("Initiating AI gateway");let l=e.useGateway?await tt({config:e}):void 0;C.log("AI gateway initiated"),n?.setAttributes({"init.aiGateway.created":!!l}),C.log("Updating runner session"),await F(e.id,e.sessionId,{steps:[{title:"Environment ready",category:Y.Environment,type:"ready"}]}),C.log("Runner session updated");let u=5*1024,c=1e4,d=ue(async({steps:f=[],duration:x})=>{let E=f.map(_=>{let T=_.title?Se(W(_.title),u):void 0,$=_.category===Y.AgentMessage||_.category===Y.UserMessage,G=_.message?W(_.message):void 0,L=G&&!$?Se(G,c):G,j=_.category===Y.UserMessage,q=L&&!j?ce(L):L;return q!==L&&C.info("Sanitized internal error from step message",{original:L}),{..._,title:T,message:q}});f.length=0;try{return await F(e.id,e.sessionId,{steps:E,duration:x})}catch(_){C.error("persistSteps failed",{error:_?.message||_})}},t);C.log("Adding build files to stage");let p=await Ce();await Ee(p),C.log("Build files staged"),z.env.NETLIFY_LOCAL_MODE||(C.log("Installing git wrapper"),await Ht()),C.log("Resolving SHA");let m;e.hasRepo?e.sha?(m=e.sha,n?.setAttributes({"init.sha.source":"provided"})):(m=await ve(),await ee(e.id,{sha:m}),n?.setAttributes({"init.sha.source":"current_commit"})):(m=await at(),n?.setAttributes({"init.sha.source":"first_commit","init.source":"zip"})),e.runSha=await ve(),C.log("SHA resolved");let y=performance.now()-o;return n?.setAttributes({"init.sha":m||"unknown","init.duration.ms":y,"init.status":"success"}),{aiGateway:l,context:g,persistSteps:d,runner:a,sha:m}}),Ht=async()=>{let e="/usr/bin/git";try{e=Mt("which git").toString().trim()||e}catch{}let t="/tmp/netlify-git-wrapper",r=Yt.join(t,"git"),i=`#!/bin/bash
12
+ # Git wrapper that blocks add and commit commands
13
+ # The deployment system handles staging and commits automatically
14
+
15
+ # Allow internal system calls to bypass the wrapper
16
+ if [ "$NETLIFY_INTERNAL_GIT" = "1" ]; then
17
+ exec ${e} "$@"
18
+ fi
19
+
20
+ case "$1" in
21
+ add)
22
+ echo ""
23
+ echo "Note: 'git add' is disabled in this environment."
24
+ echo "The deployment system automatically detects your file changes."
25
+ echo "Just edit files directly - no need to stage them manually."
26
+ echo ""
27
+ exit 1
28
+ ;;
29
+ commit)
30
+ echo ""
31
+ echo "Note: 'git commit' is disabled in this environment."
32
+ echo "The deployment system handles commits automatically."
33
+ echo "Just edit files and leave them uncommitted."
34
+ echo ""
35
+ exit 1
36
+ ;;
37
+ *)
38
+ exec ${e} "$@"
39
+ ;;
40
+ esac
41
+ `;try{await lt.mkdir(t,{recursive:!0}),await lt.writeFile(r,i,{mode:493}),z.env.PATH=`${t}:${z.env.PATH}`,z.env.NETLIFY_INTERNAL_GIT="0",C.info("Installed git wrapper to block add/commit commands")}catch(n){C.warn("Failed to install git wrapper",{error:n?.message||n})}},qt=({apiToken:e,config:t})=>({constants:{NETLIFY_API_HOST:z.env.NETLIFY_API_HOST||"api.netlify.com",NETLIFY_API_TOKEN:e||z.env.NETLIFY_API_TOKEN,SITE_ID:t.siteId,FUNCTIONS_DIST:z.env.FUNCTIONS_DIST||"netlify/functions"},utils:{run:v}});import{getTracer as ke}from"@netlify/otel";import Bt from"crypto";import b from"fs/promises";import Te from"os";import w from"path";import U from"process";import{fileURLToPath as Vt}from"url";var D=h("context"),Wt=Vt(import.meta.url),Jt=w.dirname(Wt),pt={claude:w.join(Te.homedir(),".claude","skills"),gemini:w.join(Te.homedir(),".agents","skills"),codex:w.join(Te.homedir(),".agents","skills")},ct=w.join(Jt,"skills"),dt=e=>e.replace(/<\/user_request/gi,"&lt;/user_request"),Ae=e=>typeof e=="string"&&/^[A-Za-z0-9_-]+$/.test(e)?e:null,Pe=null;var fe="SKILL.md",Kt=()=>{let e=J().skillVariations;return D.log(`Active skill variations: ${e.length?e.join(", "):"none"}`),e},ft=e=>{let t=e.match(/^(.+)@([^.]+)(.*)$/);return t?{baseName:`${t[1]}${t[3]}`,variation:t[2]}:{baseName:e,variation:null}},Xt=async(e,t=[])=>{try{let r=await b.readdir(e);for(let i of r){let{baseName:n,variation:o}=ft(i);if(o&&n===fe&&t.includes(o))return{filename:i,variation:o}}}catch{}return{filename:fe,variation:null}},Zt=async(e,{targetDir:t}={})=>{let r=t||pt[e];if(!r)return D.warn(`Unknown runner: ${e}, skipping skills setup`),[];if(Pe)return Pe;let i=[],n=Kt();try{await b.mkdir(r,{recursive:!0});let o=await b.readdir(ct);for(let s of o){let a=w.join(ct,s);if(!(await b.stat(a)).isDirectory())continue;let{baseName:l,variation:u}=ft(s);if(u&&!n.includes(u))continue;let c=w.join(r,l);try{await b.cp(a,c,{recursive:!0});let d=await Xt(a,n);d.variation&&(await b.copyFile(w.join(a,d.filename),w.join(c,fe)),await b.unlink(w.join(c,d.filename)),D.log(`Using skill variation for ${l}: ${d.filename}`)),i.push(l),u&&D.log(`Installed skill variation: ${l} (variation: ${u})`)}catch(d){D.warn(`Failed to copy skill ${l}:`,d.message)}}}catch(o){D.warn("Failed to setup agent skills:",o.message)}if(i.includes("netlify-ai-gateway"))try{let o=await de(),s=w.join(r,"netlify-ai-gateway",fe),a=await b.readFile(s,"utf-8");if(a.includes("<!-- AVAILABLE_MODELS -->")){let g=Object.entries(o.providers).map(([l,u])=>`### ${l}
42
+
43
+ ${u.models.map(c=>`- \`${c}\``).join(`
44
+ `)}`).join(`
45
+
46
+ `);a=a.replace("<!-- AVAILABLE_MODELS -->",g),await b.writeFile(s,a,"utf-8"),D.log("Injected dynamic model list into AI Gateway skill",{modelList:g})}}catch(o){D.warn("Failed to inject dynamic model list into AI Gateway skill:",o.message)}return i.length>0&&D.log(`Installed ${i.length} skills for ${e}: ${i.join(", ")}`,{runner:e,skills:i,targetDir:r}),Pe=i,i},Qt=e=>{let t=e?.constants||{};return{siteId:t.SITE_ID,accountId:U.env.NETLIFY_TEAM_ID,userId:U.env.NETLIFY_AGENT_RUNNER_USER_ID,siteSlug:U.env.SITE_NAME,apiHost:t.NETLIFY_API_HOST,functionsDir:t.FUNCTIONS_DIST}},er=10,tr=async e=>{let{name:t,ext:r}=w.parse(e),i=e,n=w.join(U.cwd(),O,i),o=0;for(;await gt(n);){if(o>=er)throw new Error("Failed to generate context file");i=`${t}-${Bt.randomUUID().slice(0,5)}${r}`,n=w.join(U.cwd(),O,i),o+=1}return i},gt=async e=>{try{return await b.access(e),!0}catch{return!1}},mt=async({cliPath:e,netlify:t,config:r,buildErrorContext:i,additionalContext:n})=>{let o=Qt(t),s=await tr(Je),a=w.join(U.cwd(),O);await b.mkdir(a,{recursive:!0});let g=w.join(O,s),l=w.join(U.cwd(),g),u=w.join(U.cwd(),O,re);try{await b.unlink(u),D.log(`Deleted old results file: ${u}`)}catch{}let c=i?`You've already made changes to complete the above request. However, the build is currently failing after your changes.
47
+ Your task is to analyze and fix the build errors.
48
+ Don't apply techniques of reverting changes. Apply fixes related to errors.
49
+ Don't try to run build by yourself. Just fix the errors.
50
+
51
+ <build_error_context>
52
+ ${i}
53
+ </build_error_context>`:"",d="";r.siteContext&&r.siteContext.length!==0&&(d=`
54
+ <project_rules>
55
+ ${r.siteContext.filter(f=>f.site_context).map(f=>typeof f.site_context=="string"?f.site_context:typeof f.site_context=="object"?JSON.stringify(f.site_context):"").join(`
56
+
57
+ `)}
58
+ </project_rules>
59
+ `);let p="";if(r.sessionHistoryContext?.length){let f=w.join(U.cwd(),O,_e);await b.mkdir(f,{recursive:!0});let x=await Promise.all(r.sessionHistoryContext.map(async(E,_)=>{let T=_+1,$=`attempt-${T}.md`,G=w.join(f,$),L=w.join(O,_e,$),j=Ae(E.id),q=j?` ID ${j}`:"",se="";if(j){let oe=w.resolve(a,ne),Q=w.resolve(oe,j);Q.startsWith(oe+w.sep)&&await gt(Q)&&(se=`
60
+ ---
61
+
62
+ ## Assets: ${Q}/
63
+ `)}let we=`# Task History - Attempt ${T}${q}
64
+
65
+ ## Request - what the user asked for
66
+ ${E.request}
67
+
68
+ ---
69
+
70
+ ## Response - what the agent replied with after its work
71
+
72
+ ${E.response}
73
+ ${se}`;return await b.writeFile(G,we,"utf-8"),D.log(`Created history file: ${L}`),L}));p+=`
74
+ <session_history_context>
75
+ History of prior work on this task.
76
+ You MUST review ALL of the files below as context to understand the context of previous attempts. Use this information to continue the discussion appropriately.
77
+
78
+ ${x.slice(-5).map(E=>`- ${E}`).join(`
79
+ `)}
80
+
81
+ </session_history_context>
82
+ `}let m=r.skillsTargetDir||pt[r.runner];r.runner&&await Zt(r.runner,{targetDir:r.skillsTargetDir});let y=`
83
+ You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
84
+
85
+ <request>
86
+ <user_request>
87
+ ${dt(r.prompt)}
88
+ </user_request>
89
+ ${c}
90
+ </request>
91
+
92
+ <requirements>
93
+ <responses>
94
+ - Do not speak in first person. You may speak as "the agent".
95
+ - When work is complete, write a changes summary in ${a}/${re} as a standalone PR description. Explain what was accomplished and why (avoid too many implementation details), assuming the reader has no prior context. Use past tense and write in prose without calling it a "PR", "Changelog", etc. This is the core of a PR message or summary page that already has a heading.
96
+ - If the user's request is informational in nature (asking for output, status, information, or analysis rather than asking you to make changes), write the requested information directly to the ${a}/${re} file.
97
+ - Do not attempt to create git commits, PRs, etc. directly. You can use git to review information if required but the system that runs this agent will handle creating PRs or commits of the changes it performs.
98
+ - NEVER look into the \`.git\` folder
99
+ - NEVER print potentially sensitive values (like secrets) in the planning output or results
100
+ - If the user asks for "a plan", "just planning", or similar (without asking for implementation) you may use plan mode to explore the codebase in read-only mode, design your implementation approach and write the complete plan to ${a}/${re}. Stop there, do not wait for approval and do not implement unless explicitly asked.
101
+ </responses>
102
+ <attachements>
103
+ - for requests that require work with attachments or assets, take into account that uploaded attachments are stored in ${a}/${ne} folder${Ae(r.sessionId)?`, specifically in ${a}/${ne}/${Ae(r.sessionId)}/ for the current session`:""}
104
+ - move assets from ${a}/${ne} folder to the project assets folder if they are referenced in a code or applied changes
105
+ </attachements>
106
+ <rules>
107
+ - Read files efficiently. Use glob first to find the right paths before reading
108
+ - Prefer editing over writing entire files when possible
109
+ - Do NOT run any build commands (e.g. \`netlify build\`, \`netlify functions:build\`, \`npm run build\`, \`yarn build\`, \`pnpm build\`). The system validates builds automatically after your changes. Running these commands can produce build artifacts that pollute the repository.
110
+ - When the task requires data storage or persistence, you MUST use Netlify platform primitives. Use the \`general-database\` skill to determine the right storage solution. NEVER use in-memory data structures, local JSON files, or external database services for data that needs to persist.
111
+ - You have access to Netlify specific skills in ${m}. Before implementing a feature, read the relevant skill's SKILL.md for instructions. Some skills have activation scripts (e.g. \`node scripts/enable.cjs\`) that you MUST run after implementing the feature. Currently, Netlify Forms and Netlify Identity have activation scripts. Skipping this step will cause the feature to not be enabled on deploy.
112
+ </rules>
113
+ ${Xe}
114
+ ${n?`<additional_rules>
115
+ ${n}
116
+ </additional_rules>`:""}
117
+ ${d}
118
+ </requirements>
119
+
120
+ <extra_context>
121
+ <metadata>
122
+ - Site/Project ID: ${o.siteId}
123
+ - Account/Team ID: ${o.accountId}
124
+ - User ID: ${o.userId}
125
+ - Site/Project Slug: ${o.siteSlug}
126
+ - Netlify Functions directory: ${o.functionsDir}
127
+ </metadata>
128
+ <environment>
129
+ - Node Version: ${U.version||"unknown"}
130
+ - Environment variables are set globally (e.g. \`echo $VARIABLE_NAME\` can be used to check if a var is set).
131
+ - 'netlify-cli' npm package is already available as a global package. Don't try to install it again
132
+ - If you need to start a local development server in order to fulfill the request, try using the Netlify CLI over by running the shell command '${e} dev'. This will start a local HTTP server on port 8888, including live-reloading of any changes and, most critically, it offers local emulation for all Netlify features.
133
+ </environment>
134
+ <docs>
135
+ - Netlify Docs: https://docs.netlify.com
136
+ - LLM Resources Index: https://docs.netlify.com/llms.txt
137
+ </docs>
138
+ </extra_context>
139
+
140
+ ${p}
141
+ `;return await b.writeFile(l,y,"utf-8"),D.log(`Generated agent context document at: ${l}`),y.length>5e5&&(y=`
142
+ You're an AI agent designed to assist with tasks related to a Netlify project. Please review, understand, and use the context provided to complete the user's request as needed.
143
+
144
+ <request>
145
+ <user_request>
146
+ ${dt(r.prompt)}
147
+ </user_request>
148
+ ${c}
149
+ </request>
150
+
151
+ Use the following file for the complete context of the ask, the environment, and what's available. ${l} You MUST READ ALL OF IT. Make sure to read it first. Never cite or paraphrase private context.
152
+ `),y};var rr=h("prompt"),yt=async({cliPath:e,config:t,netlify:r,buildErrorContext:i,additionalContext:n})=>{let o=await mt({cliPath:e,config:t,netlify:r,buildErrorContext:i,additionalContext:n});return process.env.AGENT_RUNNER_DEBUG&&rr.log("Contextful Prompt:",o),{prompt:o}};var H=h("inference_stage"),ht=5,X=async e=>{let{additionalContext:t,cliPath:r,config:i,context:n,buildErrors:o,runner:s,persistSteps:a,aiGateway:g,attempt:l,contextPrefix:u,priorAgentSessionId:c,cwd:d}=e;H.log(`Running inference stage, attempt ${l} of ${ht}`);let p=await R(ke(),"inference-stage",async m=>{m?.setAttributes({"inference.attempt":l||1}),Ve(),H.log("Composing prompt");let{prompt:y}=await R(ke(),"compose-prompt",async()=>await yt({cliPath:r,config:i,buildErrorContext:nr(o),netlify:n,additionalContext:t})),f=`
153
+ ${u||""}
154
+ ${y}
155
+ `.trim();H.log("Prompt composed");let x={...i,prompt:f};H.log("Starting runner");let E=await R(ke(),`run-${i.runner}`,async()=>await s({aiGateway:g,config:x,netlify:n,persistSteps:a,continueSession:!!(l&&l>1),priorAgentSessionId:c,cwd:d}));return E.result&&(E.result=W(E.result)),E.error&&(E.error=W(E.error)),await a.flush(),E});if(p.error){if(H.error("Runner failed",{stepsCount:p.steps.length,duration:p.duration,error:p.error,isRetryableError:p.isRetryableError,attempt:l||1,agentSessionId:p.agentSessionId}),p.isRetryableError&&(!l||l<ht))return H.log("Retrying inference stage"),await new Promise(y=>setTimeout(y,5e3)),{runnerResult:(await X({...e,attempt:(l||1)+1,priorAgentSessionId:p.agentSessionId,contextPrefix:p.agentSessionId?"":"<important> The agent has already started on this work but ran into networking errors trying to complete it. Please continue from where it left off (you can use git commands to see what's currently changed thus far) and do not start over. Here is the full prompt for context: </important>"})).runnerResult};throw H.log("Do not retry inference stage"),p.error.toLowerCase().includes("usage exceeded")?new ae(p.error,503,"Credit limit reached. Please add more credits to continue using Agent Runners.",!0):p.isRetryableError?new le(p.error):new Error(p.error)}return{runnerResult:p}},nr=e=>!e||e.length===0?"":`
156
+ Deploy failed failed. Here are the errors to review on the latest build:
157
+
158
+ Below are all of the logs with potential issues that we extracted. Some of them may be false positives, discern them carefully and ensure fixes are relevant.
159
+
160
+ ${e.pop()}
161
+ `;import or from"process";import{getTracer as Ne}from"@netlify/otel";import{getTracer as ir}from"@netlify/otel";var Z=h("deploy"),wt=async e=>await R(ir(),"create-preview-deploy",async t=>sr(e,t)),sr=async({netlify:e,hasRepo:t,skipBuild:r,message:i="Agent Preview",deploySubdomain:n,cliPath:o,filter:s,prodDeploy:a},g)=>{try{let l=["deploy","--message",`"${i}"`,"--json","--verbose",a?"--prod":"--draft"];Z.log("Deploy: Uploading source zip"),l.push("--upload-source-zip"),n&&!a&&l.push("--alias",n),s&&l.push("--filter",s),r?(Z.log("Deploy: Skipping build"),l.push("--no-build")):l.push("--context",a?"production":"deploy-preview");let u=o||"netlify";Z.log(`Running: ${u} ${l.join(" ")}`),g?.setAttributes({cmd:u,args:l});let c=await e.utils.run(u,l,{stdio:["ignore","pipe","pipe"]});c.stderr&&Z.log(String(c.stderr));let d=JSON.parse(String(c.stdout??"").trim());g?.setAttributes({success:!0,deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id}),Z.log(`
162
+ Preview deploy created successfully:`,{deployId:d.deploy_id,deployUrl:d.deploy_url,siteId:d.site_id});let p={deployId:d.deploy_id,previewUrl:d.deploy_url,logsUrl:d.logs,siteId:d.site_id};return t||(p.sourceZipFilename=d.source_zip_filename),p}catch(l){throw Z.error("Failed to create preview deploy via CLI:",l),g?.setAttributes({success:!1,error:l.message}),l}};var It=e=>["dtn-prod-iteration","create"].includes(e);import _t from"fs";import De from"path";var St=(e=process.cwd())=>{let t=De.join(e,O,Ke);return{hasNetlifyForm:_t.existsSync(De.join(t,"netlify-forms")),hasNetlifyIdentity:_t.existsSync(De.join(t,"netlify-identity"))}};var M=h("deploy_stage"),ge=async e=>await R(Ne(),"run-deploy-stage",async()=>ar(e)),ar=async({cliPath:e,config:t,context:r,result:i,filter:n,isRetry:o})=>{let s=await R(Ne(),"get-runner-diffs",async()=>await st({config:t,isRetry:o}));if(M.info("Resolved git",{hasChanges:s.hasChanges,ignored:s.ignored??[]}),!s.hasChanges&&t.mode!=="redeploy")return{diff:"",hasChanges:!1,previewInfo:null,isProdDeploy:!1,hasNetlifyForm:!1,hasNetlifyIdentity:!1};let a=s.hasChanges?s.diff:"",g=s.hasChanges?s.resultDiff:void 0,l=s.hasChanges?s.diffBinary:void 0,u=s.hasChanges?s.resultDiffBinary:void 0,c=s.hasChanges||t.mode==="redeploy",{hasNetlifyForm:d,hasNetlifyIdentity:p}=St();if(d||p){let f={};d&&(M.log("Detected Netlify Forms enablement \u2014 enabling early"),f.has_netlify_form=!0),p&&(M.log("Detected Netlify Identity enablement \u2014 enabling early"),f.has_netlify_identity=!0);try{await F(t.id,t.sessionId,f)}catch(x){M.warn("Failed to send early feature enablement (continuing):",x)}}M.log("Deploy condition check:",{resultUndefined:i===void 0,resultType:typeof i,hasChanges:c,isRedeploy:t.mode==="redeploy",wouldCreateDeploy:i!==void 0&&(c||t.mode==="redeploy")});let m=It(t.mode),y=null;if(i!==void 0&&(c||t.mode==="redeploy"))try{let f;try{let x=await R(Ne(),"get-runner-session",async()=>await Ye(t.id,t.sessionId));x?.title&&(f=x.title)}catch(x){M.warn("Failed to fetch session title, using fallback message:",x.message)}await F(t.id,t.sessionId,{steps:[{title:m?"Deploying project":"Deploying preview",category:Y.Deployment}]}),y=await wt({cliPath:e,netlify:r,hasRepo:t.hasRepo,message:f,skipBuild:!1,deploySubdomain:Qe(t.id,or.env.SITE_NAME),filter:n,prodDeploy:m})}catch(f){return M.warn("Failed to create preview deploy (continuing with agent run):",f),{diff:a,resultDiff:g,hasChanges:c,previewInfo:null,diffBinary:l,resultDiffBinary:u,deployError:f instanceof Error?f.message:String(f),isProdDeploy:m,hasNetlifyForm:d,hasNetlifyIdentity:p}}return M.log("Git status",{hasDiff:!!a,hasChanges:c}),{diff:a,resultDiff:g,hasChanges:c,previewInfo:y,diffBinary:l,resultDiffBinary:u,isProdDeploy:m,hasNetlifyForm:d,hasNetlifyIdentity:p}};import{getTracer as me}from"@netlify/otel";async function xt(e,t){let{maxRetries:r,baseDelay:i,onRetry:n}=t,o;for(let s=1;s<=r;s++)try{return await e()}catch(a){if(o=a,s===r)throw o;n&&n(s,o),await new Promise(g=>setTimeout(g,i*s))}throw o}var P=h("cleanup_stage"),$e=async e=>await R(me(),"cleanup-stage",async()=>lr(e)),Fe=1024*1024*10,lr=async({config:e,diff:t,result:r,duration:i,resultDiff:n,diffBinary:o,resultDiffBinary:s,previewInfo:a,isProdDeploy:g,hasNetlifyForm:l,hasNetlifyIdentity:u})=>{let c={result:r||"Done",duration:i};a&&a.deployId&&(c.deploy_id=a.deployId),a&&a.sourceZipFilename&&(c.result_zip_file_name=a.sourceZipFilename),g&&(c.is_published=!0);let d=t||o||n||s;if(d&&(c.diff_produced=!0),l&&(c.has_netlify_form=!0),u&&(c.has_netlify_identity=!0),d)try{P.log("Getting pre-signed URLs for diff upload");let p=await qe(e.id,e.sessionId),m=[];(t||o)&&m.push(Ie(p.result.upload_url,o||t).then(()=>{c.result_diff_s3_key=p.result.s3_key,P.log("Successfully uploaded result_diff to S3")})),(n||s)&&m.push(Ie(p.cumulative.upload_url,s||n).then(()=>{c.cumulative_diff_s3_key=p.cumulative.s3_key,P.log("Successfully uploaded cumulative_diff to S3")})),P.log(`Uploading ${m.length} diff(s) to S3 in parallel`),await Promise.all(m),(n||s)&&(P.log("Updating agent runner with cumulative diff S3 key"),await R(me(),"update-runner",async()=>{await ee(e.id,{result_diff_s3_key:p.cumulative.s3_key})}))}catch(p){P.error("S3 upload failed, falling back to inline diffs:",p);let m=Buffer.byteLength(t||o||""),y=Buffer.byteLength(s||n||"");if(m>Fe||y>Fe){let f=`Diffs exceed maximum inline size of ${Fe} bytes.`;throw P.error(f),new Error(f)}c.result_diff=t,c.result_diff_binary=o,(n||s)&&(c.cumulative_diff=n,c.cumulative_diff_binary=s,P.log("Updating agent runner with inline diffs (fallback)"),await R(me(),"update-runner",async()=>{await ee(e.id,{result_diff:n,result_diff_binary:s})}))}else P.log("No diffs to upload");return P.log("Updated agent runner with result"),await xt(async()=>await R(me(),"update-runner-session",()=>F(e.id,e.sessionId,c)),{maxRetries:3,baseDelay:1e3,onRetry:(p,m)=>{P.error(`Error updating agent runner session (attempt ${p}):`,m),P.log("Retrying...")}}),P.log("Finished updating agent runner with result"),{sessionUpdate:c}};import ur from"fs";import cr from"path";import dr from"process";import{getTracer as pr}from"@netlify/otel";var Le=h("db_migrations"),fr=new Set(["drizzle.config.ts","drizzle.config.js","drizzle.config.mjs"]),ye=async e=>await R(pr(),"db-migrations",async t=>{let r=e||dr.cwd();if(!(await Et("@netlify/database",r)||await Et("@netlify/db",r)))return t?.setAttributes({skipped:!0,reason:"@netlify/database is not installed"}),{skipped:!0};let n=[...fr].find(o=>ur.existsSync(cr.join(r,o)));if(!n)return t?.setAttributes({skipped:!0,reason:"no drizzle config found"}),{skipped:!0};t?.setAttributes({configFile:n}),Le.log(`Found ${n}, running drizzle-kit generate to ensure migrations are up to date`);try{let o=await v("npx",["drizzle-kit","generate"],{cwd:r,stdio:["ignore","pipe","pipe"]});return o.stdout&&Le.log(String(o.stdout)),t?.setAttributes({success:!0}),{skipped:!1}}catch(o){let s=gr(o);return Le.warn("drizzle-kit generate failed:",s),t?.setAttributes({success:!1,error:s}),{skipped:!1,error:s}}}),Et=async(e,t)=>{try{return await Ze(`node -e "require.resolve('${e}')"`,{cwd:t,stdio:"ignore"}),!0}catch{return!1}},gr=e=>{if(e&&typeof e=="object"){let t=[];if("stderr"in e&&e.stderr&&t.push(String(e.stderr)),"stdout"in e&&e.stdout&&t.push(String(e.stdout)),t.length>0)return t.join(`
163
+ `)}return e instanceof Error?e.message:String(e)};import{getTracer as vt,shutdownTracers as hr,withActiveSpan as Ct}from"@netlify/otel";var ie=h("usage_tracker"),mr=4e3,Rt=(e,t,r)=>{let i=!1,n=!1,o=!1,a=ue(async()=>{try{let u=await Be(e,t);ie.log("Usage update response",{usage:u?.usage}),r!=null&&u?.usage?.total_credits_cost!=null&&u.usage.total_credits_cost>=r&&(ie.log("Credit limit exceeded",{totalCreditsCost:u.usage.total_credits_cost,enforcedCreditsRemaining:r}),o=!0),u?.credit_limit_exceeded&&(ie.log("Credit limit exceeded (flagged by API)"),o=!0)}catch(u){ie.warn("Failed to update usage",{error:u?.message||u})}},mr);return{onAgentOutput:()=>{if(o)throw new ae("AI credit usage exceeded enforced limit.",503,"Credit limit reached. Check credit limits to continue using Agent Runners.",!0);n||(i=!0,a())},stop:async()=>{n||(n=!0,i&&(ie.log("Sending final usage update"),a(),await a.flush()))}}};var wr=yr(import.meta.url),Oe=wr("../package.json"),A=h("pipeline_index"),he=3,Ir=["codex","gemini"],_i=async({config:e,apiToken:t,cliPath:r="netlify",cwd:i,filter:n,tracing:o={}})=>{A.log(`runPipeline entry at ${performance.now().toFixed(0)}ms`);let s,a,{withStageTimer:g}=We(te.timeUnits.hours(4));A.log("Initializing tracing");let l=await Ue(Oe.version,e.id,o);A.log(`tracing initialized at ${performance.now().toFixed(0)}ms`),A.log(`Agent runner orchestrator v${Oe.version}`,{featureFlags:J().raw});try{await Ct(vt(),"run-pipeline",{},l,async()=>{let{aiGateway:u,context:c,persistSteps:d,runner:p,sha:m}=await g("init",()=>ut({config:e,apiToken:t,cliPath:r,cwd:i,filter:n,runnerVersion:Oe.version}),te.timeUnits.minutes(10)),y=p.runner;s=p.clean,a=Rt(e.id,e.sessionId,e.enforcedAICreditsRemaining);let f,x=Object.assign(async I=>{try{a?.onAgentOutput()}catch(S){V(S)?f??=S:A.warn("Unexpected error in onAgentOutput",{error:S?.message||S});return}return d(I)},{flush:d.flush.bind(d)});if(e.sha=m,e.mode==="redeploy"){let I=await g("deploy",()=>ge({cliPath:r,config:e,context:c,result:"Redeploy completed",filter:n,isRetry:!1}));I.deployError&&A.warn(`Redeploy deploy failed: ${I.deployError}`);let{diff:S,resultDiff:B,previewInfo:N,diffBinary:k,resultDiffBinary:Tt,isProdDeploy:At,hasNetlifyForm:Pt,hasNetlifyIdentity:kt}=I;await a?.stop(),await g("cleanup",()=>$e({config:e,diff:S,result:"Redeploy completed",duration:0,resultDiff:B,diffBinary:k,resultDiffBinary:Tt,previewInfo:N,isProdDeploy:At,hasNetlifyForm:Pt,hasNetlifyIdentity:kt}),te.timeUnits.minutes(10)),process.env.NETLIFY_LOCAL_MODE||(await s?.(),await be());return}let E;if(e.mode==="create"){let{runCreateStage:I}=await import("./create-NHDPAP43.js");E=(await g("create",()=>I({config:e,aiGateway:u,cwd:i}))).additionalContext}let{runnerResult:_}=await g("inference",async()=>{try{return await X({cliPath:r,config:e,context:c,runner:y,persistSteps:x,aiGateway:u,additionalContext:E,cwd:i})}catch(I){if(!(I instanceof le)||e.mode!=="rebase"&&e.mode!=="conflict_resolution")throw I;for(let S of Ir){if(f&&V(f))throw f;if(S===e.runner)continue;let B=pe[S];if(!B)continue;let N=await B();A.log(`Primary runner ${e.runner} failed in ${e.mode} mode, falling back to ${S}`);try{let k=await X({cliPath:r,config:{...e,runner:S},context:c,runner:N.runner,persistSteps:x,aiGateway:u,additionalContext:E,cwd:i});return e.runner=S,y=N.runner,s=N.clean,k}catch(k){if(V(k))throw k;A.error(`Fallback runner ${S} also failed`,{error:String(k)})}}throw I}});if(f)throw f;if(J().skillVariations.includes("netlifydb")){let I=await ye(i);if(I.error){A.log("Migration generation failed, running inference to fix the issue");let{runnerResult:S}=await g("inference-migration-fix",()=>X({cliPath:r,config:e,context:c,runner:y,persistSteps:x,aiGateway:u,buildErrors:[`Running \`drizzle-kit generate\` to generate database migrations failed with the following error:
164
+
165
+ ${I.error}
166
+
167
+ Please fix the issue and do NOT run \`drizzle-kit generate\` yourself \u2014 it will be run automatically after you're done.`],priorAgentSessionId:_.agentSessionId}));_={...S,steps:[..._.steps||[],...S.steps||[]],duration:(_.duration||0)+(S.duration||0)},await ye(i)}}let T=await g("deploy",()=>ge({cliPath:r,config:e,context:c,result:_.result,filter:n,isRetry:!1})),$=_,G=[];if(T.hasChanges&&T.deployError){G.push(et(T.deployError));let I=1,S=!1;for(;I<=he&&!T.previewInfo&&!S;)A.log(`Deploy attempt had errors. Retrying. ${I}/${he}`),await Ct(vt(),"deploy-stage",async B=>{B?.setAttributes({"stage.attempt":I});let N;try{N=(await g(`inference-retry-${I}`,()=>X({cliPath:r,config:e,context:c,runner:y,persistSteps:x,aiGateway:u,buildErrors:G,priorAgentSessionId:_.agentSessionId}))).runnerResult}catch(k){if(V(k))throw k;A.warn(`Inference retry ${I} failed, stopping deploy retries:`,k),S=!0;return}if(f)throw f;$={...N,steps:[...$.steps||[],...N.steps||[]],duration:($.duration||0)+(N.duration||0)},J().skillVariations.includes("netlifydb")&&await ye(i),T=await g(`deploy-retry-${I}`,()=>ge({cliPath:r,config:e,context:c,result:N.result,filter:n,isRetry:!0})),T.deployError&&G.push(T.deployError),I++});I>he&&!T.previewInfo&&console.warn(`Deploy validation failed after ${he} attempts`)}let{diff:L,resultDiff:j,previewInfo:q,diffBinary:se,resultDiffBinary:we,isProdDeploy:oe,hasNetlifyForm:Q,hasNetlifyIdentity:bt}=T;await a?.stop(),await g("cleanup",()=>$e({config:e,diff:L,result:$.result,duration:$.duration,resultDiff:j,diffBinary:se,resultDiffBinary:we,previewInfo:q,isProdDeploy:oe,hasNetlifyForm:Q,hasNetlifyIdentity:bt}),te.timeUnits.minutes(10)),process.env.NETLIFY_LOCAL_MODE||(await s?.(),await be())})}catch(u){if(V(u)){A.info("Agent run terminated gracefully",{statusCode:u.statusCode,reason:u.message}),await a?.stop(),await s?.();try{await F(e.id,e.sessionId,{result:u.userMessage,state:u.isCreditLimitExceeded?"cancelled":"error",...u.isCreditLimitExceeded&&{credit_limit_exceeded:!0}})}catch{A.info("Could not update session (site may have been deleted)")}return}A.error("Got error while running pipeline",u),await a?.stop(),await s?.();let c=u instanceof Error&&u.message,d=c?ce(c):"Encountered error when running agent";throw await F(e.id,e.sessionId,{result:d,state:"error"}),u}finally{await hr()}};export{ve as a,_i as b};
168
+ //# sourceMappingURL=chunk-NQHC3XSP.js.map
@@ -0,0 +1,2 @@
1
+ import{a as f}from"./chunk-GEX7LBQT.js";import{createTracerProvider as A}from"@netlify/otel/bootstrap";import{SimpleSpanProcessor as $}from"@netlify/otel/opentelemetry";import{FetchInstrumentation as y}from"@netlify/otel/instrumentation-fetch";import{withActiveSpan as P}from"@netlify/otel";import{propagation as w,context as x,W3CTraceContextPropagator as _}from"@netlify/otel/opentelemetry";import{OTLPTraceExporter as v}from"@opentelemetry/exporter-trace-otlp-grpc";var S=f("tracing"),F=async(t,e,r)=>(await A({serviceName:"@netlify/agent-runner-cli",serviceVersion:t,deploymentEnvironment:"production",siteUrl:"",siteId:process.env.SITE_ID??"",siteName:e,spanProcessors:[new $(new T),new $(new v({url:r.exporterUrl}))],instrumentations:[new y({skipHeaders:!0})]}),r.traceparent?(w.setGlobalPropagator(new _),w.extract(x.active(),{traceparent:r.traceparent,isRemote:!0})):x.active());function C(t,e,r){return S.log(`\u23F3 TRACE: ${e} starting...`),P(t,e,r)}var T=class{export(e,r){for(let i of e)this.logSpan(i);r({code:1})}async shutdown(){}forceFlush(){return Promise.resolve()}logSpan(e){let r=(e.endTime[0]-e.startTime[0])*1e3+(e.endTime[1]-e.startTime[1])/1e6,i=e.attributes,o=[];for(let[n,d]of Object.entries(i))n.includes("duration")&&typeof d=="number"?o.push(`${n}=${d.toFixed(2)}ms`):o.push(`${n}=${d}`);let s=e.status?.code===2?"\u274C":"\u2705",u=o.length>0?` [${o.join(", ")}]`:"";S.log(`${s} TRACE: ${e.name} completed in ${r.toFixed(2)}ms${u}`),e.status?.code===2&&e.status.message&&S.log(` \u274C Error: ${e.status.message}`)}};var l=class extends Error{constructor(r,i,o,s=!1){super(r);this.statusCode=i;this.userMessage=o;this.isCreditLimitExceeded=s;this.name="GracefulShutdownError"}},q=t=>t instanceof l,E=class extends Error{constructor(e){super(e),this.name="ProviderError"}},M=t=>t instanceof E;import g from"process";var m=g.env.NETLIFY_API_URL,h=g.env.NETLIFY_API_TOKEN,a=f("api"),p=()=>g.env.NETLIFY_LOCAL_MODE==="true",c=async(t,e={})=>{if(!m||!h)throw new Error("No API URL or token");let r=new URL(t,m),i={...e,headers:{...e.headers,Authorization:`Bearer ${h}`}};g.env.AGENT_RUNNERS_DEBUG==="true"&&(i.headers["x-nf-debug-logging"]="true"),e.json&&(i.headers||={},i.headers["Content-Type"]="application/json",i.body=JSON.stringify(e.json));let o=await fetch(r,i),s=o.ok&&o.status<=299;if(g.env.AGENT_RUNNERS_DEBUG==="true")a.log(`Response headers for ${r}:`),o.headers.forEach((n,d)=>{a.log(` ${d}: ${n}`)});else{let n=o.headers.get("x-request-id")||o.headers.get("x-nf-request-id");a.log(`Request ID for ${r}: ${n||"N/A"}`)}if(s||a.error(`Got status ${o.status} for request ${r}`),e.raw){if(!s)throw new Error(`API request failed: ${o.status} ${o.statusText}`);return o}let u=await(o.headers.get("content-type")?.includes("application/json")?o.json():o.text());if(!s){let n=typeof u=="string"?u:JSON.stringify(u);throw o.status===404?new l(`API request failed: 404 - ${n}`,404,"The site associated with this agent run no longer exists."):o.status===503&&e.gracefulOn503&&n.toLowerCase().includes("usage exceeded")?new l(`API request failed: 503 - ${n}`,503,"Credit limit reached. Please add more credits to continue using Agent Runners.",!0):new Error(`API request failed: ${o.status} - ${n}`)}return u},B=t=>{a.log("Setting details for api",{apiUrl:t?.constants?.NETLIFY_API_HOST,token:!!t?.constants?.NETLIFY_API_TOKEN}),t?.constants?.NETLIFY_API_HOST&&(m=`https://${t.constants.NETLIFY_API_HOST}`),t?.constants?.NETLIFY_API_TOKEN&&(h=t.constants.NETLIFY_API_TOKEN)},H=()=>({apiUrl:m,token:h}),X=async(t,e)=>p()?(a.log("Mock API: updateRunner called",{runnerId:t,data:e}),{id:t,...e}):c(`/api/v1/agent_runners/${t}`,{method:"PUT",json:e}),J=async(t,e,r)=>p()?(a.log("Mock API: updateRunnerSession called",JSON.stringify({runnerId:t,sessionId:e,data:r},null,2)),{id:t,sessionId:e,...r}):c(`/api/v1/agent_runners/${t}/sessions/${e}`,{method:"PUT",json:r});var z=async t=>p()?(a.log("Mock API: getSite called",{siteId:t}),{id:t,published_deploy:{id:"id"}}):c(`/api/v1/sites/${t}`),W=async(t,e)=>p()?(a.log("Mock API: getRunnerSession called",{runnerId:t,sessionId:e}),{id:e,runnerId:t,state:"running"}):c(`/api/v1/agent_runners/${t}/sessions/${e}`),V=(t,e,r)=>c(`/api/v1/accounts/${t}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":e,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Q=(t,e,r)=>c(`/api/v1/sites/${t}/ai-gateway/token`,{headers:{"X-Nf-Agent-Runner-Id":e,"X-Nf-Agent-Runner-Session-Id":r},gracefulOn503:!0}),Z=async(t,e)=>p()?(a.log("Mock API: getDiffUploadUrls called",{runnerId:t,sessionId:e}),{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"}}):c(`/api/v1/agent_runners/${t}/sessions/${e}/diff/upload_urls`,{method:"POST"}),ee=async(t,e)=>p()?(a.log("Mock API: updateSessionUsage called",{runnerId:t,sessionId:e}),{id:e,runnerId:t,usage:0}):c(`/api/v1/agent_runners/${t}/sessions/${e}/update_usage`,{method:"POST"}),te=async(t,e,{maxRetries:r=3,baseDelayMs:i=500}={})=>{a.log(`Uploading diff to S3: ${t.substring(0,50)}...`);for(let o=1;o<=r;o++)try{let s=await fetch(t,{method:"PUT",body:e,headers:{"Content-Type":"text/plain"}});if(!s.ok)throw new Error(`S3 upload failed with status ${s.status}`);return s}catch(s){if(o===r)throw s;let u=i*2**(o-1);a.warn(`S3 upload attempt ${o}/${r} failed: ${s.message}. Retrying in ${u}ms...`),await new Promise(n=>setTimeout(n,u))}};export{F as a,C as b,l as c,q as d,E as e,M as f,B as g,H as h,X as i,J as j,z as k,W as l,V as m,Q as n,Z as o,ee as p,te as q};
2
+ //# sourceMappingURL=chunk-XIU5VIKI.js.map
@@ -0,0 +1,2 @@
1
+ import{a,b,c}from"./chunk-GOMSKSS3.js";import"./chunk-GEX7LBQT.js";export{b as clean,a as default,c as request};
2
+ //# sourceMappingURL=claude-3LICIC3K.js.map
@@ -0,0 +1,2 @@
1
+ import{a,b,c}from"./chunk-47QGZMF5.js";import"./chunk-GEX7LBQT.js";export{b as clean,a as default,c as request};
2
+ //# sourceMappingURL=codex-BBM2OQAI.js.map
@@ -0,0 +1,25 @@
1
+ import{b as R,j as P}from"./chunk-XIU5VIKI.js";import{c as E}from"./chunk-GOMSKSS3.js";import{c as I}from"./chunk-47QGZMF5.js";import{D as N,a as x,t as A,u as y,v as k,y as S}from"./chunk-GEX7LBQT.js";import M from"process";import{getTracer as D}from"@netlify/otel";import{readdir as $,rm as q,stat as _}from"fs/promises";import{join as b,relative as J}from"path";async function j(t,u=[]){let c=(await $(t)).filter(s=>!u.includes(s));await Promise.all(c.map(s=>q(b(t,s),{recursive:!0,force:!0})))}var F=new Set(["node_modules",".git",".netlify",".claude",".next","dist","build",".cache"]);async function C(t,u=4){let o=[];async function c(s,m){if(m>u)return;let d;try{d=await $(s)}catch{return}d.sort();for(let p of d){if(F.has(p))continue;let n=b(s,p),l=J(t,n),g=!1;try{g=(await _(n)).isDirectory()}catch{continue}g?(o.push(`${l}/`),await c(n,m+1)):o.push(l)}}return await c(t,0),o.join(`
2
+ `)}var r=x("create_stage"),f="After completing the user's request, add a README.md to the project root describing what the project is, the key technologies used, and how to run it locally.",z=t=>({type:"json_schema",schema:{type:"object",properties:{template:{type:"string",enum:t},packageManager:{type:"string",enum:["npm","pnpm","yarn",""]},framework:{type:"string"}},required:["template","packageManager","framework"],additionalProperties:!1}}),L=t=>`Summarize the input to pick the best available template for the new project which matching the criteria of the input.
3
+ List of available templates provided in the end as \`templates array\`.
4
+
5
+ Each item of \`templates array\` has properties:
6
+ * \`description\` - use it to check if current item matches the criteria
7
+ * \`id\` - use it as a value if the description matches the criteria
8
+
9
+ Result Rules:
10
+ - only 1 \`template\` can be picked; do not change it's value or casing.
11
+ - \`packageManager\` should be the preferred package manager if mentioned in the user input (npm, yarn, pnpm), if it's not provided - empty string.
12
+ - \`framework\` should be the name of the framework (e.g. react) if user explicitly provided it, otherwise empty string. Lowercased.
13
+ - should NEVER include any additional text, explanations, labels or extra text.
14
+
15
+ \`Templates array\`:
16
+ ${JSON.stringify(t,null,2)}
17
+
18
+ ${A}`,U=async({config:t,aiGateway:u,templates:o,prompt:c,agent:s="claude",fallback:m=!0})=>{let d=L(o),p={aiGateway:u,config:t,prompt:c,systemPrompt:d,outputFormat:z(o.map(i=>i.id))},n=s,l=s==="claude"?"codex":"claude",g=async i=>i==="claude"?E(p):I({...p,model:"gpt-5.2"});try{r.info(`Attempting template selection with ${n}`);let i=await g(n);return JSON.parse(i.text)}catch(i){if(!m){r.error(`${n} request failed`,{error:i.message});return}r.warn(`${n} request failed, falling back to ${l}`,{error:i.message});try{r.info(`Attempting template selection with ${l}`);let e=await g(l);return JSON.parse(e.text)}catch(e){r.error(`Both ${n} and ${l} requests failed`,{[`${n}Error`]:i.message,[`${l}Error`]:e.message})}}},ie=async({config:t,aiGateway:u,cwd:o=M.cwd()})=>await R(D(),"create-stage",async c=>{let s=performance.now();c?.setAttributes({"create.runner":t.runner,"create.id":t.id,"create.sessionId":t.sessionId}),await j(o,[".netlify",".git","node_modules"]),r.info("Cleaned cwd folder");let m=`${M.env.NVM_BIN}/node`,d=S(o,"ts-cli"),p=[d,"--list-addons-json"];r.log(`Running ${m} ${p.join(" ")}`);let{stdout:n}=await k(m,p),g=JSON.parse(n).filter(a=>a.type==="example").map(a=>{let{type:T,...G}=a;return G});r.info("Retrieved add-ons");let i="prompt"in t?t.prompt:"",e=await U({config:t,aiGateway:u,templates:g,prompt:i,agent:t.runner==="codex"?"codex":"claude"});if(!e)return r.info("Could not pick template, going with the general AI Agent"),{template:"",packageManager:"",framework:"",additionalContext:f};["npm","pnpm","yarn",""].includes(e.packageManager)||(r.info("Picked up unknown package manager",e.packageManager),e.packageManager="");let h=g.find(a=>a.id===e.template),v=h?.features??[];if(h||(r.info("Picked up unknown template",e.template),e.template=""),e.framework&&!["react","react.js","reactjs"].includes(e.framework))return r.info("Picked up different framework then template, going with the general AI Agent"),{...e,additionalContext:f};r.info("Generate template",{template:e.template,packageManager:e.packageManager}),p=[d,"--target-dir","./","--no-git",...e?.template?["--add-ons",e.template]:[],...e?.packageManager?["--package-manager",e.packageManager]:[]],r.log(`Running ${m} ${p.join(" ")}`),await P(t.id,t.sessionId,{steps:[{title:"Generating the site",category:y.SiteGeneration},...v.map(a=>({title:`Use ${a.split("-").map(N).join(" ")}`,category:y.Skill,type:a}))],metadata:{template:e?.template}}),await k(m,p);let w=f;try{let a=await C(o);a&&(w=`This project was just scaffolded from the "${h?.name??e.template}" template. Here is the complete file tree \u2014 do NOT spend time exploring or listing files, jump straight to editing.
19
+
20
+ \`\`\`
21
+ ${a}
22
+ \`\`\`
23
+
24
+ ${f}`,r.info("Generated project structure for agent context"))}catch(a){r.warn("Failed to generate project structure",a.message)}let O=performance.now()-s;return c?.setAttributes({"create.framework":e?.framework,"create.template":e?.template,"create.duration.ms":O,"create.status":"success"}),{...e??{template:"",packageManager:"",framework:""},additionalContext:w}});export{U as pickTemplateWithAI,ie as runCreateStage};
25
+ //# sourceMappingURL=create-NHDPAP43.js.map
@@ -0,0 +1,4 @@
1
+ import{B as Y,C as z,E as R,F as V,L as q,N as H,O as Q,a as W,s as J,u as o,y as K}from"./chunk-GEX7LBQT.js";import _ from"fs/promises";import G from"os";import v from"path";import g from"process";import te from"readline";var a=W("runner_gemini"),L="Gemini CLI",f="gemini-3.1-pro-preview",oe=({catchError:s,runCmd:l,error:r,result:n,runnerName:m})=>(a.log(`${m} command completed with catch handler triggered`,{hadExistingError:!!r,hadExistingResult:!!n,resultLength:n?n.length:0,catchError:s?.message||"No error object",processExitCode:l.exitCode,processKilled:l.killed}),n?(a.log("Preserving existing result despite catch handler being triggered"),r?{error:r,result:n}:{error:"Process completed with errors but result was captured",result:n}):(a.log("Setting result to undefined because no valid result was captured"),{error:r||`${m} failed`,result:void 0})),X={list_directory:{name:"List directory",category:o.Explore},read_file:{name:"Read file",category:o.FileRead},write_file:{name:"Edit file",category:o.FileWrite},glob:{name:"Find files",category:o.Explore},search_file_content:{name:"Search files",category:o.Explore},replace:{name:"Edit file",category:o.FileWrite},run_shell_command:{name:"Run command",category:o.RunCommand},web_fetch:{name:"Fetch web",category:o.Web},web_search:{name:"Search web",category:o.Web},read_many_files:{name:"Read files",category:o.FileRead},save_memory:{name:"Memorize",category:o.Memorize},activate_skill:{name:"Use Skill",category:o.Skill},grep_search:{name:"Search files",category:o.Explore}},ie=async()=>{let s=v.join(G.homedir(),".gemini"),l=v.join(s,"settings.json");try{await _.mkdir(s,{recursive:!0});let r={};try{let n=await _.readFile(l,"utf-8");r=JSON.parse(n)}catch{a.log("Creating new Gemini CLI settings file")}r.general||(r.general={}),r.general.previewFeatures||(r.general.previewFeatures=!0),r.model||(r.model={}),r.model.compressionThreshold!==.3&&(r.model.compressionThreshold=.3),r.skills||(r.skills={}),r.skills.enabled=!0,r.context||(r.context={}),r.context.fileName=["GEMINI.md","AGENTS.md"],await _.writeFile(l,JSON.stringify(r,null,2),"utf-8"),a.log("Configured Gemini CLI settings (preview features and compression threshold)")}catch(r){a.error("Failed to ensure Gemini CLI settings",{error:r.message})}},se=s=>{s?.category===o.Skill&&s.type&&V(a,R(s.type))};async function ae({config:s,netlify:l,persistSteps:r=void 0,sendSteps:n=void 0,aiGateway:m,cwd:M=g.cwd()}){let{accountType:P,prompt:Z,modelVersionOverrides:A}=s,{model:c}=s;if(await ie(),m){let{token:t,url:e}=m;if(!t||!e)throw new Error("No token or url provided from AI Gateway");if(A?.gemini){let i=A?.gemini?.[P];if(i){if(!await m.isModelAvailableForProvider("gemini",i))throw new Error(`Model override '${i}' is not available for gemini provider`);c=i}}if(!c)!!f&&await m.isModelAvailableForProvider("gemini",f)?(c=f,a.log(`Using default model: ${f}`)):f&&a.log(`Default model ${f} is not available, proceeding without model specification`);else if(c&&!A?.gemini?.[P]&&!await m.isModelAvailableForProvider("gemini",c))throw new Error(`Model '${c}' is not available for gemini provider`);g.env.GEMINI_API_KEY=t,g.env.GOOGLE_GEMINI_BASE_URL=e}else if(!g.env.GEMINI_API_KEY)throw new Error("GEMINI_API_KEY is not provided");let C=[],x=[],T=[],j={},O=0,E=0,y,d,D=[K(M,"gemini"),...c?["--model",c]:[],"--yolo","--output-format","stream-json","-p",Z],U=`${g.env.NVM_BIN}/node`;a.log(`Running ${U} ${D.join(" ")}`);let b=l.utils.run(U,D,{all:!0,env:g.env,cwd:M,idleTimeout:J});b.stdin?.end();let u=Y(()=>{r?.({steps:C,duration:E}),n?.({steps:x,duration:E}),x=[]},250),$=(t,e)=>{t.id=O,O+=1,T.push(t),C.push(t),x.push(t),e||u.flush(),u(),e&&u.flush()};$({title:`Using ${L} with ${c||"default"}`,category:o.Environment},!0);let N=te.createInterface({input:b.all});N.on("error",t=>{a.error("Readline interface error",{error:t.message,stack:t.stack})});let p="",ee=()=>{p&&$({message:p.trim(),category:o.AgentMessage}),p=""};return N.on("line",t=>{let e=null;try{if(t.startsWith("[API Error")){let i=t.match(/\[api error: (.+?)]$/i)?.[1];e={type:"error",value:z(i,!1)?.error?.message||i||"Gemini encountered error"}}else e=JSON.parse(t)}catch{return}if(e)switch(["message","result"].includes(e.type)||ee(),e.type){case"message":{e.role!=="user"&&e.content&&(p+=e.content);break}case"tool_use":{let i=X[e.tool_name]?.name??e.tool_name,w=e.parameters?.file_path,F=w&&v.relative(M,w),B=e.parameters?.command,k=e.tool_name==="activate_skill"&&e.parameters?.name,h=[i,F&&`\`${F}\``,B&&`\`${B}\``].filter(Boolean).join(" ");if(k)h=`Use ${R(k)}`;else if(e.tool_name==="grep_search"){let{dir_path:I,pattern:S}=e.parameters||{};I&&S?h=`Search in \`${I}\` for \`${S}\``:I?h=`Search in \`${I}\``:S&&(h=`Search for \`${S}\``)}let re={title:h,category:X[e.tool_name]?.category,...k&&{type:k}};j[e.tool_id]=re,u.flush();break}case"tool_result":{let i=j[e.tool_id];i&&(e.output&&(i.message=`\`\`\`
2
+ ${e.output.trim()}
3
+ \`\`\``),$(i,!0),se(i));break}case"result":{E=e.stats?.duration_ms,e.status==="error"?d=e.error?.message:y=p.trim();break}case"error":{d=e.error;break}case"finished":break;case"init":break;default:{a.warn("Unhandled message type:",e.type);break}}}),await b.catch(t=>{({error:d,result:y}=oe({catchError:t,runCmd:b,error:d,result:y,runnerName:"Gemini"}))}),N.close(),u.flush(),{steps:T,duration:E,result:await q({initialResult:y,agentName:L,hasError:!!d}),error:H({error:d,agentName:L}),isRetryableError:Q(d)}}var ve=async()=>{let s=v.join(G.homedir(),".gemini");await _.rm(s,{recursive:!0,force:!0});let l=v.join(G.homedir(),".agents","skills");await _.rm(l,{recursive:!0,force:!0})};export{ve as clean,ae as default};
4
+ //# sourceMappingURL=gemini-RGNOCS6R.js.map