stably 4.12.26-rc.0 β 4.12.26
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/index.mjs +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{config as e,parse as t}from"dotenv";import*as r from"path";import n,{resolve as s,dirname as o,join as i,sep as a,normalize as c,basename as l}from"path";import{Command as u}from"commander";import{Buffer as d}from"buffer";import p,{exec as f,execSync as h,spawn as g,execFile as m,execFileSync as y}from"child_process";import b from"process";import*as w from"fs";import v,{mkdirSync as I,writeFileSync as T,rmSync as _,existsSync as E,statSync as S,readFileSync as x,appendFileSync as A,realpathSync as k,createReadStream as P,openSync as C,readSync as R,closeSync as U}from"fs";import{fileURLToPath as L,URL as $}from"url";import D,{tmpdir as N,constants as O}from"os";import"timers/promises";import B from"stream";import{debuglog as j,promisify as M,TextDecoder as F,TextEncoder as H}from"util";import{createSdkMcpServer as G,tool as W,query as V}from"@anthropic-ai/claude-agent-sdk";import{rm as Y,readFile as z,mkdir as q,writeFile as K,unlink as J,access as X,readdir as Q,stat as Z,appendFile as ee}from"fs/promises";import te from"net";import{createInterface as re}from"readline/promises";import ne from"picocolors";import{simpleGit as se}from"simple-git";import oe,{randomUUID as ie}from"crypto";import{log as ae,outro as ce,spinner as le,intro as ue,select as de,isCancel as pe}from"@clack/prompts";import fe,{z as he}from"zod";import ge from"open";import me from"http";import ye from"pino";import be from"sonic-boom";import{z as we}from"zod/v3";import ve from"ws";import{useState as Ie,useRef as Te,useEffect as _e,useCallback as Ee,useMemo as Se}from"react";import{jsx as xe,jsxs as Ae}from"react/jsx-runtime";import{createRequire as ke}from"module";import{parseDocument as Pe}from"yaml";import{startTunnel as Ce}from"@stablyhq/runner-sdk";var Re=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,t)=>("undefined"!=typeof require?require:e)[t]}):e)(function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),Ue={cwdChanged:!1,newCwd:void 0,envFilesLoaded:[],envFileErrors:[],remoteEnvName:void 0},Le=process.argv.findIndex(e=>"-C"===e||"--cwd"===e);if(-1!==Le&&process.argv[Le+1]){const e=process.argv[Le+1];process.chdir(e),Ue.cwdChanged=!0,Ue.newCwd=e,process.argv.splice(Le,2)}for(var $e=[],De=0;De<process.argv.length;)if("--env-file"===process.argv[De]){const e=process.argv[De+1];e&&!e.startsWith("-")?($e.push(e),process.argv.splice(De,2)):De++}else De++;var Ne=process.argv.findIndex(e=>"--env"===e);-1!==Ne&&process.argv[Ne+1]&&!process.argv[Ne+1].startsWith("-")&&(Ue.remoteEnvName=process.argv[Ne+1],process.argv.splice(Ne,2));for(const t of[...$e].reverse()){const r=n.resolve(process.cwd(),t),s=e({path:r,override:!1,quiet:!0});if(s.error){const e=`warning: could not load env file: ${r} (${s.error.message})`;Ue.envFileErrors.push(e),process.stderr.write(`${e}\n`)}else Ue.envFilesLoaded.unshift(r)}var Oe={detect:({env:e})=>Boolean(e.APPVEYOR),configuration({env:e}){const t=e.APPVEYOR_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Appveyor",service:"appveyor",commit:e.APPVEYOR_REPO_COMMIT,tag:e.APPVEYOR_REPO_TAG_NAME,build:e.APPVEYOR_BUILD_NUMBER,buildUrl:`https://ci.appveyor.com/project/${e.APPVEYOR_PROJECT_SLUG}/build/${e.APPVEYOR_BUILD_VERSION}`,branch:e.APPVEYOR_REPO_BRANCH,job:e.APPVEYOR_JOB_NUMBER,jobUrl:`https://ci.appveyor.com/project/${e.APPVEYOR_PROJECT_SLUG}/build/job/${e.APPVEYOR_JOB_ID}`,pr:t,isPr:r,prBranch:e.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH,slug:e.APPVEYOR_REPO_NAME,root:e.APPVEYOR_BUILD_FOLDER}}};function Be(e){return(/\d+(?!.*\d+)/.exec(e)||[])[0]}function je(e){return e?/^(?:refs\/heads\/)?(?<branch>.+)$/i.exec(e)[1]:void 0}var Me={detect:({env:e})=>Boolean(e.BUILD_BUILDURI),configuration({env:e}){const t=e.SYSTEM_PULLREQUEST_PULLREQUESTID,r=Boolean(t);return{name:"Azure Pipelines",service:"azurePipelines",commit:e.BUILD_SOURCEVERSION,build:e.BUILD_BUILDNUMBER,branch:je(r?e.SYSTEM_PULLREQUEST_TARGETBRANCH:e.BUILD_SOURCEBRANCH),pr:t,isPr:r,prBranch:je(r?e.SYSTEM_PULLREQUEST_SOURCEBRANCH:void 0),root:e.BUILD_REPOSITORY_LOCALPATH}}},Fe={detect:({env:e})=>Boolean(e.bamboo_agentId),configuration:({env:e})=>({name:"Bamboo",service:"bamboo",commit:e.bamboo_planRepository_1_revision,build:e.bamboo_buildNumber,buildUrl:e.bamboo_buildResultsUrl,branch:e.bamboo_planRepository_1_branchName,job:e.bamboo_buildKey,root:e.bamboo_build_working_directory})},He={detect:({env:e})=>Boolean(e.BITBUCKET_BUILD_NUMBER),configuration:({env:e})=>({name:"Bitbucket Pipelines",service:"bitbucket",commit:e.BITBUCKET_COMMIT,tag:e.BITBUCKET_TAG,build:e.BITBUCKET_BUILD_NUMBER,buildUrl:`https://bitbucket.org/${e.BITBUCKET_REPO_FULL_NAME}/addon/pipelines/home#!/results/${e.BITBUCKET_BUILD_NUMBER}`,branch:e.BITBUCKET_BRANCH,slug:e.BITBUCKET_REPO_FULL_NAME,root:e.BITBUCKET_CLONE_DIR})},Ge={detect:({env:e})=>Boolean(e.BITRISE_IO),configuration({env:e}){const t="false"===e.BITRISE_PULL_REQUEST?void 0:e.BITRISE_PULL_REQUEST,r=Boolean(t);return{name:"Bitrise",service:"bitrise",commit:e.BITRISE_GIT_COMMIT,tag:e.BITRISE_GIT_TAG,build:e.BITRISE_BUILD_NUMBER,buildUrl:e.BITRISE_BUILD_URL,branch:r?e.BITRISEIO_GIT_BRANCH_DEST:e.BITRISE_GIT_BRANCH,pr:t,isPr:r,prBranch:r?e.BITRISE_GIT_BRANCH:void 0,slug:e.BITRISE_APP_SLUG}}},We={detect:({env:e})=>Boolean(e.BUDDY_WORKSPACE_ID),configuration({env:e}){const t=Be(e.BUDDY_EXECUTION_PULL_REQUEST_ID),r=Boolean(t);return{name:"Buddy",service:"buddy",commit:e.BUDDY_EXECUTION_REVISION,tag:e.BUDDY_EXECUTION_TAG,build:e.BUDDY_EXECUTION_ID,buildUrl:e.BUDDY_EXECUTION_URL,branch:r?e.BUDDY_EXECUTION_PULL_REQUEST_HEAD_BRANCH:e.BUDDY_EXECUTION_BRANCH,pr:t,isPr:r,slug:e.BUDDY_REPO_SLUG}}},Ve="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function Ye(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var ze,qe,Ke,Je,Xe,Qe,Ze,et,tt={exports:{}};var rt,nt,st,ot,it,at,ct,lt,ut,dt,pt,ft,ht,gt,mt,yt={exports:{}},bt={};function wt(){if(ft)return pt;ft=1;const e=n,t=function(){if(st)return nt;st=1;const e=n,t=function(){if(et)return Ze;et=1;const e="win32"===process.platform||"cygwin"===process.env.OSTYPE||"msys"===process.env.OSTYPE,t=n,r=e?";":":",s=function(){if(Qe)return Xe;var e;function t(r,n,s){if("function"==typeof n&&(s=n,n={}),!s){if("function"!=typeof Promise)throw new TypeError("callback not provided");return new Promise(function(e,s){t(r,n||{},function(t,r){t?s(t):e(r)})})}e(r,n||{},function(e,t){e&&("EACCES"===e.code||n&&n.ignoreErrors)&&(e=null,t=!1),s(e,t)})}return Qe=1,e="win32"===process.platform||Ve.TESTING_WINDOWS?function(){if(qe)return ze;qe=1,ze=r,r.sync=function(r,n){return t(e.statSync(r),r,n)};var e=v;function t(e,t,r){return!(!e.isSymbolicLink()&&!e.isFile())&&function(e,t){var r=void 0!==t.pathExt?t.pathExt:process.env.PATHEXT;if(!r)return!0;if(-1!==(r=r.split(";")).indexOf(""))return!0;for(var n=0;n<r.length;n++){var s=r[n].toLowerCase();if(s&&e.substr(-s.length).toLowerCase()===s)return!0}return!1}(t,r)}function r(r,n,s){e.stat(r,function(e,o){s(e,!e&&t(o,r,n))})}return ze}():function(){if(Je)return Ke;Je=1,Ke=t,t.sync=function(t,n){return r(e.statSync(t),n)};var e=v;function t(t,n,s){e.stat(t,function(e,t){s(e,!e&&r(t,n))})}function r(e,t){return e.isFile()&&function(e,t){var r=e.mode,n=e.uid,s=e.gid,o=void 0!==t.uid?t.uid:process.getuid&&process.getuid(),i=void 0!==t.gid?t.gid:process.getgid&&process.getgid(),a=parseInt("100",8),c=parseInt("010",8);return r&parseInt("001",8)||r&c&&s===i||r&a&&n===o||r&(a|c)&&0===o}(e,t)}return Ke}(),Xe=t,t.sync=function(t,r){try{return e.sync(t,r||{})}catch(e){if(r&&r.ignoreErrors||"EACCES"===e.code)return!1;throw e}},Xe}(),o=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),i=(t,n)=>{const s=n.colon||r,o=t.match(/\//)||e&&t.match(/\\/)?[""]:[...e?[process.cwd()]:[],...(n.path||process.env.PATH||"").split(s)],i=e?n.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",a=e?i.split(s):[""];return e&&-1!==t.indexOf(".")&&""!==a[0]&&a.unshift(""),{pathEnv:o,pathExt:a,pathExtExe:i}},a=(e,r,n)=>{"function"==typeof r&&(n=r,r={}),r||(r={});const{pathEnv:a,pathExt:c,pathExtExe:l}=i(e,r),u=[],d=n=>new Promise((s,i)=>{if(n===a.length)return r.all&&u.length?s(u):i(o(e));const c=a[n],l=/^".*"$/.test(c)?c.slice(1,-1):c,d=t.join(l,e),f=!l&&/^\.[\\\/]/.test(e)?e.slice(0,2)+d:d;s(p(f,n,0))}),p=(e,t,n)=>new Promise((o,i)=>{if(n===c.length)return o(d(t+1));const a=c[n];s(e+a,{pathExt:l},(s,i)=>{if(!s&&i){if(!r.all)return o(e+a);u.push(e+a)}return o(p(e,t,n+1))})});return n?d(0).then(e=>n(null,e),n):d(0)};return Ze=a,a.sync=(e,r)=>{r=r||{};const{pathEnv:n,pathExt:a,pathExtExe:c}=i(e,r),l=[];for(let o=0;o<n.length;o++){const i=n[o],u=/^".*"$/.test(i)?i.slice(1,-1):i,d=t.join(u,e),p=!u&&/^\.[\\\/]/.test(e)?e.slice(0,2)+d:d;for(let e=0;e<a.length;e++){const t=p+a[e];try{if(s.sync(t,{pathExt:c})){if(!r.all)return t;l.push(t)}}catch(e){}}}if(r.all&&l.length)return l;if(r.nothrow)return null;throw o(e)},Ze}(),r=function(){if(rt)return yt.exports;rt=1;const e=(e={})=>{const t=e.env||process.env;return"win32"!==(e.platform||process.platform)?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"};return yt.exports=e,yt.exports.default=e,yt.exports}();function s(n,s){const o=n.options.env||process.env,i=process.cwd(),a=null!=n.options.cwd,c=a&&void 0!==process.chdir&&!process.chdir.disabled;if(c)try{process.chdir(n.options.cwd)}catch(e){}let l;try{l=t.sync(n.command,{path:o[r({env:o})],pathExt:s?e.delimiter:void 0})}catch(e){}finally{c&&process.chdir(i)}return l&&(l=e.resolve(a?n.options.cwd:"",l)),l}return nt=function(e){return s(e)||s(e,!0)}}(),r=function(){if(ot)return bt;ot=1;const e=/([()\][%!^"`<>&|;, *?])/g;return bt.command=function(t){return t.replace(e,"^$1")},bt.argument=function(t,r){return t=(t=`"${t=(t=(t=`${t}`).replace(/(?=(\\+?)?)\1"/g,'$1$1\\"')).replace(/(?=(\\+?)?)\1$/,"$1$1")}"`).replace(e,"^$1"),r&&(t=t.replace(e,"^$1")),t},bt}(),s=function(){if(dt)return ut;dt=1;const e=v,t=function(){if(lt)return ct;lt=1;const e=at?it:(at=1,it=/^#!(.*)/);return ct=(t="")=>{const r=t.match(e);if(!r)return null;const[n,s]=r[0].replace(/#! ?/,"").split(" "),o=n.split("/").pop();return"env"===o?s:s?`${o} ${s}`:o}}();return ut=function(r){const n=Buffer.alloc(150);let s;try{s=e.openSync(r,"r"),e.readSync(s,n,0,150,0),e.closeSync(s)}catch(e){}return t(n.toString())}}(),o="win32"===process.platform,i=/\.(?:com|exe)$/i,a=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;return pt=function(n,c,l){c&&!Array.isArray(c)&&(l=c,c=null);const u={command:n,args:c=c?c.slice(0):[],options:l=Object.assign({},l),file:void 0,original:{command:n,args:c}};return l.shell?u:function(n){if(!o)return n;const c=function(e){e.file=t(e);const r=e.file&&s(e.file);return r?(e.args.unshift(e.file),e.command=r,t(e)):e.file}(n),l=!i.test(c);if(n.options.forceShell||l){const t=a.test(c);n.command=e.normalize(n.command),n.command=r.command(n.command),n.args=n.args.map(e=>r.argument(e,t));const s=[n.command].concat(n.args).join(" ");n.args=["/d","/s","/c",`"${s}"`],n.command=process.env.comspec||"cmd.exe",n.options.windowsVerbatimArguments=!0}return n}(u)}}var vt=Ye(function(){if(mt)return tt.exports;mt=1;const e=p,t=wt(),r=function(){if(gt)return ht;gt=1;const e="win32"===process.platform;function t(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function r(r,n){return e&&1===r&&!n.file?t(n.original,"spawn"):null}return ht={hookChildProcess:function(t,n){if(!e)return;const s=t.emit;t.emit=function(e,o){if("exit"===e){const e=r(o,n);if(e)return s.call(t,"error",e)}return s.apply(t,arguments)}},verifyENOENT:r,verifyENOENTSync:function(r,n){return e&&1===r&&!n.file?t(n.original,"spawnSync"):null},notFoundError:t},ht}();function n(n,s,o){const i=t(n,s,o),a=e.spawn(i.command,i.args,i.options);return r.hookChildProcess(a,i),a}return tt.exports=n,tt.exports.spawn=n,tt.exports.sync=function(n,s,o){const i=t(n,s,o),a=e.spawnSync(i.command,i.args,i.options);return a.error=a.error||r.verifyENOENTSync(a.status,i),a},tt.exports._parse=t,tt.exports._enoent=r,tt.exports}());function It(e={}){const{env:t=process.env,platform:r=process.platform}=e;return"win32"!==r?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"}var Tt=(e,t)=>({name:`SIGRT${t+1}`,number:_t+t,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),_t=34,Et=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}],St=()=>{const e=(()=>{const e=64-_t+1;return Array.from({length:e},Tt)})();return[...Et,...e].map(xt)},xt=({name:e,number:t,description:r,action:n,forced:s=!1,standard:o})=>{const{signals:{[e]:i}}=O,a=void 0!==i;return{name:e,number:a?i:t,description:r,supported:a,action:n,forced:s,standard:o}},At=({name:e,number:t,description:r,supported:n,action:s,forced:o,standard:i})=>[e,{name:e,number:t,description:r,supported:n,action:s,forced:o,standard:i}],kt=(()=>{const e=St();return Object.fromEntries(e.map(At))})();(()=>{const e=St(),t=Array.from({length:65},(t,r)=>((e,t)=>{const r=((e,t)=>{const r=t.find(({name:t})=>O.signals[t]===e);return void 0!==r?r:t.find(t=>t.number===e)})(e,t);if(void 0===r)return{};const{name:n,description:s,supported:o,action:i,forced:a,standard:c}=r;return{[e]:{name:n,number:e,description:s,supported:o,action:i,forced:a,standard:c}}})(r,e));Object.assign({},...t)})();var Pt=({stdout:e,stderr:t,all:r,error:n,signal:s,exitCode:o,command:i,escapedCommand:a,timedOut:c,isCanceled:l,killed:u,parsed:{options:{timeout:d,cwd:p=b.cwd()}}})=>{o=null===o?void 0:o;const f=void 0===(s=null===s?void 0:s)?void 0:kt[s].description,h=(({timedOut:e,timeout:t,errorCode:r,signal:n,signalDescription:s,exitCode:o,isCanceled:i})=>e?`timed out after ${t} milliseconds`:void 0!==r?`failed with ${r}`:void 0!==n?`was killed with ${n} (${s})`:void 0!==o?`failed with exit code ${o}`:"failed")({timedOut:c,timeout:d,errorCode:n&&n.code,signal:s,signalDescription:f,exitCode:o,isCanceled:l}),g=`Command ${h}: ${i}`,m="[object Error]"===Object.prototype.toString.call(n),y=m?`${g}\n${n.message}`:g,w=[y,t,e].filter(Boolean).join("\n");return m?(n.originalMessage=n.message,n.message=w):n=new Error(w),n.shortMessage=y,n.command=i,n.escapedCommand=a,n.exitCode=o,n.signal=s,n.signalDescription=f,n.stdout=e,n.stderr=t,n.cwd=p,void 0!==r&&(n.all=r),"bufferedData"in n&&delete n.bufferedData,n.failed=!0,n.timedOut=Boolean(c),n.isCanceled=l,n.killed=u&&!c,n},Ct=["stdin","stdout","stderr"],Rt=[];Rt.push("SIGHUP","SIGINT","SIGTERM"),"win32"!==process.platform&&Rt.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&Rt.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var Ut,Lt,$t=e=>!!e&&"object"==typeof e&&"function"==typeof e.removeListener&&"function"==typeof e.emit&&"function"==typeof e.reallyExit&&"function"==typeof e.listeners&&"function"==typeof e.kill&&"number"==typeof e.pid&&"function"==typeof e.on,Dt=Symbol.for("signal-exit emitter"),Nt=globalThis,Ot=Object.defineProperty.bind(Object),Bt=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(Nt[Dt])return Nt[Dt];Ot(Nt,Dt,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,t){this.listeners[e].push(t)}removeListener(e,t){const r=this.listeners[e],n=r.indexOf(t);-1!==n&&(0===n&&1===r.length?r.length=0:r.splice(n,1))}emit(e,t,r){if(this.emitted[e])return!1;this.emitted[e]=!0;let n=!1;for(const s of this.listeners[e])n=!0===s(t,r)||n;return"exit"===e&&(n=this.emit("afterExit",t,r)||n),n}},jt=class{},Mt=globalThis.process;$t(Mt)?new class extends jt{#e="win32"===Mt.platform?"SIGINT":"SIGHUP";#t=new Bt;#r;#n;#s;#o={};#i=!1;constructor(e){super(),this.#r=e,this.#o={};for(const t of Rt)this.#o[t]=()=>{const r=this.#r.listeners(t);let{count:n}=this.#t;const s=e;if("object"==typeof s.__signal_exit_emitter__&&"number"==typeof s.__signal_exit_emitter__.count&&(n+=s.__signal_exit_emitter__.count),r.length===n){this.unload();const r=this.#t.emit("exit",null,t),n="SIGHUP"===t?this.#e:t;r||e.kill(e.pid,n)}};this.#s=e.reallyExit,this.#n=e.emit}onExit(e,t){if(!$t(this.#r))return()=>{};!1===this.#i&&this.load();const r=t?.alwaysLast?"afterExit":"exit";return this.#t.on(r,e),()=>{this.#t.removeListener(r,e),0===this.#t.listeners.exit.length&&0===this.#t.listeners.afterExit.length&&this.unload()}}load(){if(!this.#i){this.#i=!0,this.#t.count+=1;for(const e of Rt)try{const t=this.#o[e];t&&this.#r.on(e,t)}catch(e){}this.#r.emit=(e,...t)=>this.#a(e,...t),this.#r.reallyExit=e=>this.#c(e)}}unload(){this.#i&&(this.#i=!1,Rt.forEach(e=>{const t=this.#o[e];if(!t)throw new Error("Listener not defined for signal: "+e);try{this.#r.removeListener(e,t)}catch(e){}}),this.#r.emit=this.#n,this.#r.reallyExit=this.#s,this.#t.count-=1)}#c(e){return $t(this.#r)?(this.#r.exitCode=e||0,this.#t.emit("exit",this.#r.exitCode,null),this.#s.call(this.#r,this.#r.exitCode)):0}#a(e,...t){const r=this.#n;if("exit"===e&&$t(this.#r)){"number"==typeof t[0]&&(this.#r.exitCode=t[0]);const n=r.call(this.#r,e,...t);return this.#t.emit("exit",this.#r.exitCode,null),n}return r.call(this.#r,e,...t)}}(Mt):new class extends jt{onExit(){return()=>{}}load(){}unload(){}},new TextEncoder,function(){if(Lt)return Ut;Lt=1;const{PassThrough:e}=B;Ut=function(){var t=[],r=new e({objectMode:!0});return r.setMaxListeners(0),r.add=n,r.isEmpty=function(){return 0==t.length},r.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(n),r;function n(e){return Array.isArray(e)?(e.forEach(n),this):(t.push(e),e.once("end",s.bind(null,e)),e.once("error",r.emit.bind(r,"error")),e.pipe(r,{end:!1}),this)}function s(e){!(t=t.filter(function(t){return t!==e})).length&&r.readable&&r.end()}}}();var Ft=(async()=>{})().constructor.prototype;["then","catch","finally"].map(e=>[e,Reflect.getOwnPropertyDescriptor(Ft,e)]);var Ht=(e,t=[])=>Array.isArray(t)?[e,...t]:[e],Gt=/^[\w.-]+$/,Wt=j("execa").enabled,Vt=(e,t)=>String(e).padStart(t,"0"),Yt=(e,t,r={})=>{const s=vt._parse(e,t,r);return e=s.command,t=s.args,(r={maxBuffer:1e8,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:(r=s.options).cwd||b.cwd(),execPath:b.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:Wt,...r}).env=(({env:e,extendEnv:t,preferLocal:r,localDir:s,execPath:o})=>{const i=t?{...b.env,...e}:e;return r?(({env:e=b.env,...t}={})=>{const r=It({env:e={...e}});return t.path=e[r],e[r]=(({cwd:e=b.cwd(),path:t=b.env[It()],preferLocal:r=!0,execPath:s=b.execPath,addExecPath:o=!0}={})=>{const i=e instanceof URL?L(e):e,a=n.resolve(i),c=[];return r&&((e,t)=>{let r;for(;r!==t;)e.push(n.join(t,"node_modules/.bin")),r=t,t=n.resolve(t,"..")})(c,a),o&&((e,t,r)=>{const s=t instanceof URL?L(t):t;e.push(n.resolve(r,s,".."))})(c,s,a),[...c,t].join(n.delimiter)})(t),e})({env:i,cwd:s,execPath:o}):i})(r),r.stdio=(e=>{if(!e)return;const{stdio:t}=e;if(void 0===t)return Ct.map(t=>e[t]);if((e=>Ct.some(t=>void 0!==e[t]))(e))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${Ct.map(e=>`\`${e}\``).join(", ")}`);if("string"==typeof t)return t;if(!Array.isArray(t))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof t}\``);const r=Math.max(t.length,Ct.length);return Array.from({length:r},(e,r)=>t[r])})(r),"win32"===b.platform&&"cmd"===n.basename(e,".exe")&&t.unshift("/q"),{file:e,args:t,options:r,parsed:s}},zt=(e,t,r)=>"string"==typeof t||d.isBuffer(t)?e.stripFinalNewline?function(e){const t="string"==typeof e?"\n":"\n".charCodeAt(),r="string"==typeof e?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,-1)),e[e.length-1]===r&&(e=e.slice(0,-1)),e}(t):t:void 0===r?void 0:"";function qt(e,t,r){const n=Yt(e,t,r),s=((e,t)=>Ht(e,t).join(" "))(e,t),o=((e,t)=>Ht(e,t).map(e=>(e=>"string"!=typeof e||Gt.test(e)?e:`"${e.replaceAll('"','\\"')}"`)(e)).join(" "))(e,t);((e,{verbose:t})=>{t&&b.stderr.write(`[${(()=>{const e=new Date;return`${Vt(e.getHours(),2)}:${Vt(e.getMinutes(),2)}:${Vt(e.getSeconds(),2)}.${Vt(e.getMilliseconds(),3)}`})()}] ${e}\n`)})(o,n.options);const i=(e=>{const t=(({input:e,inputFile:t})=>"string"!=typeof t?e:((e=>{if(void 0!==e)throw new TypeError("The `input` and `inputFile` options cannot be both set.")})(e),x(t)))(e);if(null!==(r=t)&&"object"==typeof r&&"function"==typeof r.pipe)throw new TypeError("The `input` option cannot be a stream in sync mode");var r;return t})(n.options);let a;try{a=p.spawnSync(n.file,n.args,{...n.options,input:i})}catch(e){throw Pt({error:e,stdout:"",stderr:"",all:"",command:s,escapedCommand:o,parsed:n,timedOut:!1,isCanceled:!1,killed:!1})}const c=zt(n.options,a.stdout,a.error),l=zt(n.options,a.stderr,a.error);if(a.error||0!==a.status||null!==a.signal){const e=Pt({stdout:c,stderr:l,error:a.error,signal:a.signal,exitCode:a.status,command:s,escapedCommand:o,parsed:n,timedOut:a.error&&"ETIMEDOUT"===a.error.code,isCanceled:!1,killed:null!==a.signal});if(!n.options.reject)return e;throw e}return{command:s,escapedCommand:o,exitCode:0,stdout:c,stderr:l,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}}function Kt(e){try{return qt("git",["rev-parse","HEAD"],e).stdout}catch{return}}function Jt(e){try{const t=qt("git",["rev-parse","--abbrev-ref","HEAD"],e).stdout;if("HEAD"===t){const t=qt("git",["show","-s","--pretty=%d","HEAD"],e).stdout.replace(/^\(|\)$/g,"").split(", ").find(e=>e.startsWith("origin/"));return t?t.match(/^origin\/(?<branch>.+)/)[1]:void 0}return t}catch{return}}var Xt=/^(?:.*)@(?:.*):(?:\d+\/)?(.*)\.git$/,Qt=/^\/(.*)\.git$/;function Zt(e){if(e){if(e.match(Xt))return e.replace(Xt,"$1");try{return new URL(e).pathname.replace(Qt,"$1")}catch{return}}}var er,tr={detect:({env:e})=>Boolean(e.BUILDKITE),configuration({env:e}){const t="false"===e.BUILDKITE_PULL_REQUEST?void 0:e.BUILDKITE_PULL_REQUEST,r=Boolean(t);return{name:"Buildkite",service:"buildkite",build:e.BUILDKITE_BUILD_NUMBER,buildUrl:e.BUILDKITE_BUILD_URL,commit:e.BUILDKITE_COMMIT,tag:e.BUILDKITE_TAG,branch:r?e.BUILDKITE_PULL_REQUEST_BASE_BRANCH:e.BUILDKITE_BRANCH,slug:Zt(e.BUILDKITE_REPO),pr:t,isPr:r,prBranch:r?e.BUILDKITE_BRANCH:void 0,root:e.BUILDKITE_BUILD_CHECKOUT_PATH}}},rr={detect:({env:e})=>Boolean(e.CIRCLECI),configuration({env:e}){const t=e.CIRCLE_PR_NUMBER||Be(e.CIRCLE_PULL_REQUEST||e.CI_PULL_REQUEST),r=Boolean(t);return{name:"CircleCI",service:"circleci",build:e.CIRCLE_BUILD_NUM,buildUrl:e.CIRCLE_BUILD_URL,job:`${e.CIRCLE_BUILD_NUM}.${e.CIRCLE_NODE_INDEX}`,commit:e.CIRCLE_SHA1,tag:e.CIRCLE_TAG,branch:r?void 0:e.CIRCLE_BRANCH,pr:t,isPr:r,prBranch:r?e.CIRCLE_BRANCH:void 0,slug:`${e.CIRCLE_PROJECT_USERNAME}/${e.CIRCLE_PROJECT_REPONAME}`}}},nr="https://cirrus-ci.com",sr={detect:({env:e})=>Boolean(e.CIRRUS_CI),configuration({env:e}){const t=e.CIRRUS_PR,r=Boolean(t);return{name:"Cirrus CI",service:"cirrus",commit:e.CIRRUS_CHANGE_IN_REPO,tag:e.CIRRUS_TAG,build:e.CIRRUS_BUILD_ID,buildUrl:`${nr}/build/${e.CIRRUS_BUILD_ID}`,job:e.CIRRUS_TASK_ID,jobUrl:`${nr}/task/${e.CIRRUS_TASK_ID}`,branch:r?e.CIRRUS_BASE_BRANCH:e.CIRRUS_BRANCH,pr:t,isPr:r,prBranch:r?e.CIRRUS_BRANCH:void 0,slug:e.CIRRUS_REPO_FULL_NAME,root:e.CIRRUS_WORKING_DIR}}},or={detect:({env:e})=>Boolean(e.CODEBUILD_BUILD_ID),configuration:({env:e,cwd:t})=>({name:"AWS CodeBuild",service:"codebuild",commit:Kt({env:e,cwd:t}),build:e.CODEBUILD_BUILD_ID,branch:Jt({env:e,cwd:t}),buildUrl:`https://console.aws.amazon.com/codebuild/home?region=${e.AWS_REGION}#/builds/${e.CODEBUILD_BUILD_ID}/view/new`,root:e.PWD})},ir={detect:({env:e})=>Boolean(e.CF_BUILD_ID),configuration({env:e}){const t=e.CF_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Codefresh",service:"codefresh",commit:e.CF_REVISION,build:e.CF_BUILD_ID,buildUrl:e.CF_BUILD_URL,branch:r?e.CF_PULL_REQUEST_TARGET:e.CF_BRANCH,pr:t,isPr:r,prBranch:r?e.CF_BRANCH:void 0,slug:`${e.CF_REPO_OWNER}/${e.CF_REPO_NAME}`,root:e.CF_VOLUME_PATH}}},ar={detect:({env:e})=>Boolean(e.DRONE),configuration({env:e}){const t="pull_request"===e.DRONE_BUILD_EVENT;return{name:"Drone",service:"drone",commit:e.DRONE_COMMIT_SHA,tag:e.DRONE_TAG,build:e.DRONE_BUILD_NUMBER,buildUrl:e.DRONE_BUILD_LINK,branch:t?e.DRONE_TARGET_BRANCH:e.DRONE_BRANCH,job:e.DRONE_JOB_NUMBER,jobUrl:e.DRONE_BUILD_LINK,pr:e.DRONE_PULL_REQUEST,isPr:t,prBranch:t?e.DRONE_SOURCE_BRANCH:void 0,slug:`${e.DRONE_REPO_OWNER}/${e.DRONE_REPO_NAME}`,root:e.DRONE_WORKSPACE}}},cr=e=>({commit:Kt(e),branch:Jt(e)}),lr=({env:e})=>{try{const t=e.GITHUB_EVENT_PATH?JSON.parse(x(e.GITHUB_EVENT_PATH,"utf-8")):void 0;if(t&&t.pull_request)return{branch:t.pull_request.base?je(t.pull_request.base.ref):void 0,pr:t.pull_request.number}}catch{}return{pr:void 0,branch:void 0}},ur={detect:({env:e})=>Boolean(e.GITHUB_ACTIONS),configuration({env:e,cwd:t}){const r="pull_request"===e.GITHUB_EVENT_NAME||"pull_request_target"===e.GITHUB_EVENT_NAME,n=je("pull_request_target"===e.GITHUB_EVENT_NAME?`refs/pull/${(e=>{const t=e.GITHUB_EVENT_PATH?JSON.parse(x(e.GITHUB_EVENT_PATH,"utf-8")):void 0;return t&&t.pull_request?t.pull_request.number:void 0})(e)}/merge`:e.GITHUB_REF);return{name:"GitHub Actions",service:"github",commit:e.GITHUB_SHA,build:e.GITHUB_RUN_ID,buildUrl:`${e.GITHUB_SERVER_URL}/${e.GITHUB_REPOSITORY}/actions/runs/${e.GITHUB_RUN_ID}`,isPr:r,branch:n,prBranch:r?n:void 0,slug:e.GITHUB_REPOSITORY,root:e.GITHUB_WORKSPACE,...r?lr({env:e}):void 0}}},dr={detect:({env:e})=>Boolean(e.GITLAB_CI),configuration({env:e}){const t=e.CI_MERGE_REQUEST_ID,r=Boolean(t);return{name:"GitLab CI/CD",service:"gitlab",commit:e.CI_COMMIT_SHA,tag:e.CI_COMMIT_TAG,build:e.CI_PIPELINE_ID,buildUrl:`${e.CI_PROJECT_URL}/pipelines/${e.CI_PIPELINE_ID}`,job:e.CI_JOB_ID,jobUrl:`${e.CI_PROJECT_URL}/-/jobs/${e.CI_JOB_ID}`,branch:r?e.CI_MERGE_REQUEST_TARGET_BRANCH_NAME:e.CI_COMMIT_REF_NAME,pr:t,isPr:r,prBranch:e.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,slug:e.CI_PROJECT_PATH,root:e.CI_PROJECT_DIR}}},pr={detect:({env:e})=>Boolean(e.JENKINS_URL),configuration({env:e,cwd:t}){const r=e.ghprbPullId||e.gitlabMergeRequestId||e.CHANGE_ID,n=Boolean(r),s=e.GIT_LOCAL_BRANCH||e.GIT_BRANCH||e.gitlabBranch||e.BRANCH_NAME;return{name:"Jenkins",service:"jenkins",commit:e.ghprbActualCommit||e.GIT_COMMIT||Kt({env:e,cwd:t}),branch:n?e.ghprbTargetBranch||e.gitlabTargetBranch:s,build:e.BUILD_NUMBER,buildUrl:e.BUILD_URL,root:e.WORKSPACE,pr:r,isPr:n,prBranch:n?e.ghprbSourceBranch||e.gitlabSourceBranch||s:void 0}}},fr={detect:({env:e})=>"true"===e.NETLIFY,configuration({env:e}){const t="true"===e.PULL_REQUEST;return{name:"Netlify",service:"netlify",commit:e.COMMIT_REF,build:e.DEPLOY_ID,buildUrl:`https://app.netlify.com/sites/${e.SITE_NAME}/deploys/${e.DEPLOY_ID}`,branch:t?void 0:e.HEAD,pr:e.REVIEW_ID,isPr:t,prBranch:t?e.HEAD:void 0,slug:e.REPOSITORY_URL.match(/[^/:]+\/[^/]+?$/)[0],root:e.PWD}}},hr={detect:({env:e})=>Boolean(e.DISTELLI_APPNAME),configuration:({env:e})=>({name:"Puppet",service:"puppet",build:e.DISTELLI_BUILDNUM,buildUrl:e.DISTELLI_RELEASE,commit:e.DISTELLI_RELREVISION,branch:e.DISTELLI_RELBRANCH,root:e.DISTELLI_INSTALLHOME})},gr={detect:({env:e})=>Boolean(e.SAILCI),configuration({env:e}){const t=e.SAIL_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Sail CI",service:"sail",commit:e.SAIL_COMMIT_SHA,branch:r?void 0:e.SAIL_COMMIT_BRANCH,pr:t,isPr:r,slug:`${e.SAIL_REPO_OWNER}/${e.SAIL_REPO_NAME}`,root:e.SAIL_CLONE_DIR}}},mr={detect:({env:e})=>Boolean(e.SCREWDRIVER),configuration({env:e}){const t=e.SD_PULL_REQUEST,r=Boolean(t);return{name:"Screwdriver.cd",service:"screwdriver",branch:r?e.PR_BASE_BRANCH_NAME:e.GIT_BRANCH,prBranch:r?e.PR_BRANCH_NAME:void 0,commit:e.SD_BUILD_SHA,build:e.SD_BUILD_ID,buildUrl:e.SD_UI_BUILD_URL,job:e.SD_JOB_ID,pr:t,isPr:r,slug:e.SD_PIPELINE_NAME,root:e.SD_ROOT_DIR}}},yr={detect:({env:e})=>Boolean(e.SCRUTINIZER),configuration({env:e}){const t=e.SCRUTINIZER_PR_NUMBER,r=Boolean(t);return{name:"Scrutinizer",service:"scrutinizer",commit:e.SCRUTINIZER_SHA1,build:e.SCRUTINIZER_INSPECTION_UUID,branch:e.SCRUTINIZER_BRANCH,pr:t,isPr:r,prBranch:e.SCRUTINIZER_PR_SOURCE_BRANCH}}},br={detect:({env:e})=>Boolean(e.SEMAPHORE),configuration({env:e,cwd:t}){const r=e.SEMAPHORE_GIT_PR_NUMBER||e.PULL_REQUEST_NUMBER,n=Boolean(r);return{name:"Semaphore",service:"semaphore",commit:e.SEMAPHORE_GIT_SHA||Kt({env:e,cwd:t}),tag:e.SEMAPHORE_GIT_TAG_NAME,build:e.SEMAPHORE_JOB_ID||e.SEMAPHORE_BUILD_NUMBER,branch:e.SEMAPHORE_GIT_BRANCH||(n?void 0:e.BRANCH_NAME),pr:r,isPr:n,prBranch:e.SEMAPHORE_GIT_PR_BRANCH||(n?e.BRANCH_NAME:void 0),slug:e.SEMAPHORE_GIT_REPO_SLUG||e.SEMAPHORE_REPO_SLUG,root:e.SEMAPHORE_GIT_DIR||e.SEMAPHORE_PROJECT_DIR}}},wr={detect:({env:e})=>Boolean(e.SHIPPABLE),configuration({env:e}){const t="true"===e.IS_PULL_REQUEST?e.PULL_REQUEST:void 0,r=Boolean(t);return{name:"Shippable",service:"shippable",commit:e.COMMIT,tag:e.GIT_TAG_NAME,build:e.BUILD_NUMBER,buildUrl:e.BUILD_URL,branch:r?e.BASE_BRANCH:e.BRANCH,job:e.JOB_NUMBER,pr:t,isPr:r,prBranch:r?e.HEAD_BRANCH:void 0,slug:e.SHIPPABLE_REPO_SLUG,root:e.SHIPPABLE_BUILD_DIR}}},vr={};function Ir(){if(er)return vr;er=1,Object.defineProperty(vr,"__esModule",{value:!0}),vr.of=vr.PropertiesFile=void 0;var e,t=(e=v)&&e.__esModule?e:{default:e};class r{constructor(...e){this.objs={},e.length&&this.of.apply(this,e)}makeKeys(e){if(e&&0!==e.indexOf("#")){let t=["=",":"].map(t=>e.indexOf(t)).filter(e=>e>-1),r=Math.min(...t),n=e.substring(0,r).trim(),s=e.substring(r+1).trim();if(this.objs.hasOwnProperty(n))if(Array.isArray(this.objs[n]))this.objs[n].push(s);else{let e=this.objs[n];this.objs[n]=[e,s]}else{const e=s.replace(/"/g,'\\"').replace(/\\:/g,":").replace(/\\=/g,"=");this.objs[n]=unescape(JSON.parse('"'+e+'"'))}}}addFile(e){let r=t.default.readFileSync(e,"utf-8").split(/\r?\n/),n=this;for(let e=0;e<r.length;e++){let t=r[e];for(;"\\"===t.substring(t.length-1);)t=t.slice(0,-1),t+=r[e+1].trim(),e++;n.makeKeys(t)}}of(...e){for(let t=0;t<e.length;t++)this.addFile(e[t])}get(e,t){if(this.objs.hasOwnProperty(e)){if(Array.isArray(this.objs[e])){let t=[];for(let r=0;r<this.objs[e].length;r++)t[r]=this.interpolate(this.objs[e][r]);return t}return void 0===this.objs[e]?"":this.interpolate(this.objs[e])}return t}getLast(e,t){if(this.objs.hasOwnProperty(e)){if(Array.isArray(this.objs[e])){var r=this.objs[e].length;return this.interpolate(this.objs[e][r-1])}return void 0===this.objs[e]?"":this.interpolate(this.objs[e])}return t}getFirst(e,t){return this.objs.hasOwnProperty(e)?Array.isArray(this.objs[e])?this.interpolate(this.objs[e][0]):void 0===this.objs[e]?"":this.interpolate(this.objs[e]):t}getInt(e,t){let r=this.getLast(e);return r?parseInt(r,10):t}getFloat(e,t){let r=this.getLast(e);return r?parseFloat(r):t}getBoolean(e,t){let r=this.getLast(e);return r?!/^(false|0)$/i.test(n=r)&&!!n:t||!1;var n}set(e,t){this.objs[e]=t}interpolate(e){let t=this;return e.replace(/\\\\/g,"\\").replace(/\$\{([A-Za-z0-9\.\-\_]*)\}/g,function(e){return t.getLast(e.substring(2,e.length-1))})}getKeys(){let e=[];for(let t in this.objs)e.push(t);return e}getMatchingKeys(e){let t=[];for(let r in this.objs)-1!==r.search(e)&&t.push(r);return t}reset(){this.objs={}}}return vr.PropertiesFile=r,vr.of=function(...e){let t=new r;return t.of.apply(t,e),t},vr}var Tr=Ye(Ir()),_r={root:"teamcity.build.workingDir",branch:"teamcity.build.branch"},Er=e=>{try{return Tr.of(e)}catch{return}},Sr=({env:e,cwd:t})=>{const r=e.TEAMCITY_BUILD_PROPERTIES_FILE?Er(e.TEAMCITY_BUILD_PROPERTIES_FILE):void 0,n=r?r.get("teamcity.configuration.properties.file"):void 0,s=n?Er(n):n;return Object.fromEntries(Object.keys(_r).map(n=>[n,(r?r.get(_r[n]):void 0)||(s?s.get(_r[n]):void 0)||("branch"===n?Jt({env:e,cwd:t}):void 0)]))},xr={appveyor:Oe,azurePipelines:Me,bamboo:Fe,bitbucket:He,bitrise:Ge,buddy:We,buildkite:tr,circleci:rr,cirrus:sr,cloudflarePages:{detect:({env:e})=>"1"===e.CF_PAGES,configuration:({env:e})=>({name:"Cloudflare Pages",service:"cloudflarePages",commit:e.CF_PAGES_COMMIT_SHA,branch:e.CF_PAGES_BRANCH,root:e.PWD})},codebuild:or,codefresh:ir,codeship:{detect:({env:e})=>e.CI_NAME&&"codeship"===e.CI_NAME,configuration:({env:e})=>({name:"Codeship",service:"codeship",build:e.CI_BUILD_NUMBER,buildUrl:e.CI_BUILD_URL,commit:e.CI_COMMIT_ID,branch:e.CI_BRANCH,slug:e.CI_REPO_NAME})},drone:ar,github:ur,gitlab:dr,jenkins:pr,netlify:fr,puppet:hr,sail:gr,screwdriver:mr,scrutinizer:yr,semaphore:br,shippable:wr,teamcity:{detect:({env:e})=>Boolean(e.TEAMCITY_VERSION),configuration:({env:e,cwd:t})=>({name:"TeamCity",service:"teamcity",commit:e.BUILD_VCS_NUMBER,build:e.BUILD_NUMBER,slug:e.TEAMCITY_BUILDCONF_NAME,...Sr({env:e,cwd:t})})},travis:{detect:({env:e})=>Boolean(e.TRAVIS),configuration({env:e}){const t="false"===e.TRAVIS_PULL_REQUEST?void 0:e.TRAVIS_PULL_REQUEST,r=Boolean(t);return{name:"Travis CI",service:"travis",commit:e.TRAVIS_COMMIT,tag:e.TRAVIS_TAG,build:e.TRAVIS_BUILD_NUMBER,buildUrl:e.TRAVIS_BUILD_WEB_URL,branch:e.TRAVIS_BRANCH,job:e.TRAVIS_JOB_NUMBER,jobUrl:e.TRAVIS_JOB_WEB_URL,pr:t,isPr:r,prBranch:e.TRAVIS_PULL_REQUEST_BRANCH,slug:e.TRAVIS_REPO_SLUG,root:e.TRAVIS_BUILD_DIR}}},vela:{detect:({env:e})=>Boolean(e.VELA),configuration({env:e}){const t="pull_request"===e.VELA_BUILD_EVENT;return{name:"Vela",service:"vela",branch:t?e.VELA_PULL_REQUEST_TARGET:e.VELA_BUILD_BRANCH,commit:e.VELA_BUILD_COMMIT,tag:e.VELA_BUILD_TAG,build:e.VELA_BUILD_NUMBER,buildUrl:e.VELA_BUILD_LINK,job:void 0,jobUrl:void 0,isPr:t,pr:e.VELA_BUILD_PULL_REQUEST,prBranch:e.VELA_PULL_REQUEST_SOURCE,slug:e.VELA_REPO_FULL_NAME,root:e.VELA_BUILD_WORKSPACE}}},vercel:{detect:({env:e})=>Boolean(e.VERCEL)||Boolean(e.NOW_GITHUB_DEPLOYMENT),configuration({env:e}){const t="Vercel",r="vercel";return e.VERCEL?{name:t,service:r,commit:e.VERCEL_GIT_COMMIT_SHA,branch:e.VERCEL_GIT_COMMIT_REF,slug:`${e.VERCEL_GIT_REPO_OWNER}/${e.VERCEL_GIT_REPO_SLUG}`}:{name:t,service:r,commit:e.NOW_GITHUB_COMMIT_SHA,branch:e.NOW_GITHUB_COMMIT_REF,slug:`${e.NOW_GITHUB_ORG}/${e.NOW_GITHUB_REPO}`}}},wercker:{detect:({env:e})=>Boolean(e.WERCKER_MAIN_PIPELINE_STARTED),configuration:({env:e})=>({name:"Wercker",service:"wercker",commit:e.WERCKER_GIT_COMMIT,build:e.WERCKER_MAIN_PIPELINE_STARTED,buildUrl:e.WERCKER_RUN_URL,branch:e.WERCKER_GIT_BRANCH,slug:`${e.WERCKER_GIT_OWNER}/${e.WERCKER_GIT_REPOSITORY}`,root:e.WERCKER_ROOT})},woodpecker:{detect:({env:e})=>e.CI&&"woodpecker"===e.CI,configuration({env:e}){const t="pull_request"===e.CI_PIPELINE_EVENT;return{name:"Woodpecker CI",service:"woodpecker",commit:e.CI_COMMIT_SHA,tag:e.CI_COMMIT_TAG,build:e.CI_PIPELINE_NUMBER,buildUrl:e.CI_PIPELINE_URL,branch:t?e.CI_COMMIT_TARGET_BRANCH:e.CI_COMMIT_BRANCH,job:e.CI_STEP_NUMBER,jobUrl:e.CI_STEP_URL,pr:e.CI_COMMIT_PULL_REQUEST,isPr:t,prBranch:t?e.CI_COMMIT_SOURCE_BRANCH:void 0,slug:`${e.CI_REPO_OWNER}/${e.CI_REPO_NAME}`,root:e.CI_WORKSPACE}}},jetbrainsSpace:{detect:({env:e})=>Boolean(e.JB_SPACE_EXECUTION_NUMBER),configuration({env:e}){const t=e.JB_SPACE_PROJECT_KEY,r=e.JB_SPACE_GIT_REPOSITORY_NAME;return{name:"JetBrains Space",service:"jetbrainsSpace",commit:e.JB_SPACE_GIT_REVISION,build:e.JB_SPACE_EXECUTION_NUMBER,branch:je(e.JB_SPACE_GIT_BRANCH),slug:t&&r?`${t.toLowerCase()}/${r}`:void 0}}}},Ar=["test","bug","flake","ui_change","other"],kr=["captured","capture_failed","upload_failed"],Pr={bug:"Application code defect; behavior diverges from expected requirements.",flake:"Non-deterministic failure; timing, race conditions, or environmental variance causes inconsistent test results.",other:"External dependencies, environment, or infra issues outside test/app code.",test:"Test code is incorrect, out-of-date, or missing necessary setup.",ui_change:"Application UI intentionally changed; test expectations (screenshots, selectors, text assertions) are stale and need updating."},Cr=e=>Pr[e],Rr=function(){const e=process.env.STABLY_THEME;if("light"===e||"dark"===e)return e;const t=process.env.COLORFGBG;if(t){const e=t.split(";").at(-1);if(void 0!==e&&""!==e){const t=Number(e);if(Number.isInteger(t)&&t>=0&&t<=15)return t<=6||8===t?"dark":"light"}}const r=void 0!==process.env.VITEST||void 0!==process.env.CI;if(!r&&process.stdout.isTTY){const e=function(){if("win32"===process.platform)return null;try{const e=h("old=$(stty -g </dev/tty 2>/dev/null) || exit 1; trap 'stty \"$old\" </dev/tty 2>/dev/null' EXIT; stty raw -echo min 0 time 1 </dev/tty 2>/dev/null; printf '\\033]11;?\\007' >/dev/tty; dd bs=64 count=1 </dev/tty 2>/dev/null",{encoding:"latin1",timeout:1500,stdio:["pipe","pipe","pipe"]}).match(/\]11;rgb:([0-9a-f]+)\/([0-9a-f]+)\/([0-9a-f]+)/i);if(!e)return null;const t=e=>parseInt(e.length<=2?e.padStart(2,"0"):e.slice(0,2),16),r=t(e[1]);return.299*r+.587*t(e[2])+.114*t(e[3])>128?"light":"dark"}catch{return null}}();if(e)return e}if("darwin"===process.platform&&!r&&process.stdout.isTTY)try{return h("defaults read -g AppleInterfaceStyle 2>/dev/null",{encoding:"utf8",timeout:500}),"dark"}catch{return"light"}return"dark"}(),Ur=function(){const e=process.env.FORCE_COLOR;if(void 0!==e){if("false"===e||"0"===e)return 0;if("true"===e||""===e)return 1;const t=Number(e);return Number.isNaN(t)?1:0===t?0:1===t?1:2===t?2:t>=3?3:1}if(void 0!==process.env.NO_COLOR)return 0;if(!process.stdout.isTTY)return 0;const t=process.env.COLORTERM?.toLowerCase(),r=process.env.TERM_PROGRAM?.toLowerCase(),n=process.env.TERM?.toLowerCase()??"";return"truecolor"===t||"24bit"===t||r&&["iterm.app","iterm2","hyper","wezterm","ghostty","kitty","alacritty","warp","rio"].some(e=>r.includes(e))||"vscode"===r?3:n.startsWith("screen")||n.startsWith("tmux")||n.includes("256color")||n.includes("256colours")||"apple_terminal"===r?2:1}(),Lr="dark"===Rr?{brand:{hex:"#2DD4BF",ansi256:86,ansi:"cyan"},userPrompt:{hex:"#67E8F9",ansi256:87,ansi:"cyan"},muted:{hex:"#D1D5DB",ansi256:252,ansi:"white"},subtle:{hex:"#9CA3AF",ansi256:248,ansi:"gray"},success:{hex:"#4ADE80",ansi256:78,ansi:"green"},error:{hex:"#F87171",ansi256:210,ansi:"red"},warning:{hex:"#FBBF24",ansi256:220,ansi:"yellow"},info:{hex:"#38BDF8",ansi256:75,ansi:"cyan"},accent:{hex:"#A78BFA",ansi256:141,ansi:"magenta"},link:{hex:"#38BDF8",ansi256:75,ansi:"cyan"},inlineCode:{hex:"#A78BFA",ansi256:141,ansi:"magenta"},codeBlock:{hex:"#D1D5DB",ansi256:252,ansi:"white"},fixTriage:{hex:"#FB923C",ansi256:215,ansi:"yellow"},fixDebug:{hex:"#C084FC",ansi256:177,ansi:"magenta"},fixValidation:{hex:"#60A5FA",ansi256:75,ansi:"blue"},fatalBg:{hex:"#991B1B",ansi256:88,ansi:"red"}}:{brand:{hex:"#0D9488",ansi256:30,ansi:"cyan"},userPrompt:{hex:"#0E7490",ansi256:30,ansi:"cyan"},muted:{hex:"#374151",ansi256:238,ansi:"gray"},subtle:{hex:"#6B7280",ansi256:243,ansi:"gray"},success:{hex:"#15803D",ansi256:28,ansi:"green"},error:{hex:"#B91C1C",ansi256:124,ansi:"red"},warning:{hex:"#B45309",ansi256:130,ansi:"yellow"},info:{hex:"#0369A1",ansi256:25,ansi:"blue"},accent:{hex:"#7C3AED",ansi256:98,ansi:"magenta"},link:{hex:"#0369A1",ansi256:25,ansi:"blue"},inlineCode:{hex:"#7C3AED",ansi256:98,ansi:"magenta"},codeBlock:{hex:"#374151",ansi256:239,ansi:"gray"},fixTriage:{hex:"#C2410C",ansi256:166,ansi:"red"},fixDebug:{hex:"#7E22CE",ansi256:91,ansi:"magenta"},fixValidation:{hex:"#1D4ED8",ansi256:26,ansi:"blue"},fatalBg:{hex:"#991B1B",ansi256:88,ansi:"red"}};function $r(e){const t=Lr[e];if(0!==Ur)return 1===Ur?t.ansi:t.hex}function Dr(e,t){if(0===Ur)return t;const r=Lr[e];if(Ur>=3){const[e,n,s]=Or(r.hex);return`[38;2;${e};${n};${s}m${t}[39m`}return 2===Ur?`[38;5;${r.ansi256}m${t}[39m`:function(e,t){const r=Br[e];return r?r(t):t}(r.ansi,t)}function Nr(e,t){if(0===Ur)return t;const r=Lr[e];if(Ur>=3){const[e,n,s]=Or(r.hex);return`[48;2;${e};${n};${s}m${t}[49m`}return 2===Ur?`[48;5;${r.ansi256}m${t}[49m`:function(e,t){const r=jr[e];return r?r(t):t}(r.ansi,t)}function Or(e){const t=e.startsWith("#")?e.slice(1):e;return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}var Br={red:ne.red,green:ne.green,yellow:ne.yellow,blue:ne.blue,magenta:ne.magenta,cyan:ne.cyan,white:ne.white,gray:ne.gray},jr={red:ne.bgRed,green:ne.bgGreen,yellow:ne.bgYellow,blue:ne.bgBlue,magenta:ne.bgMagenta,cyan:ne.bgCyan,white:ne.bgWhite},Mr=class e{git;config;snapshotTreeHash;snapshotIndexPath;constructor(e){this.config=e,this.git=se({baseDir:e.workingDir,maxConcurrentProcesses:1})}static createLocal({workingDir:t}){return new e({mode:"local",workingDir:t})}static createCloud({workingDir:t,baseBranch:r}){return new e({mode:"cloud",workingDir:t,baseBranch:r})}async captureSnapshot(){if("local"!==this.config.mode)return;this.snapshotIndexPath=i(N(),`git-diff-tracker-${ie()}.index`),await this.git.env("GIT_INDEX_FILE",this.snapshotIndexPath).add(["-A"]);const e=await this.git.env("GIT_INDEX_FILE",this.snapshotIndexPath).raw(["write-tree"]);this.snapshotTreeHash=e.trim()}async computeDiff(){return"local"===this.config.mode?this.computeLocalDiff():this.computeCloudDiff()}async computeLocalDiff(){if(!this.snapshotTreeHash)throw new Error("No snapshot captured. Call captureSnapshot() first.");const e=i(N(),`git-diff-tracker-${ie()}.index`);try{await this.git.env("GIT_INDEX_FILE",e).add(["-A"]);const t=(await this.git.env("GIT_INDEX_FILE",e).raw(["write-tree"])).trim();return await this.git.raw(["diff-tree","-p","--no-color",this.snapshotTreeHash,t])}finally{await Fr(e)}}async computeCloudDiff(){if("cloud"!==this.config.mode)throw new Error("computeCloudDiff called but mode is not cloud");const{baseBranch:e}=this.config;return await this.git.revparse([`origin/${e}`]).then(()=>!0).catch(()=>!1)||await this.git.fetch(["origin",`+${e}:refs/remotes/origin/${e}`,"--depth","1","--quiet"]).catch(e=>{console.error("[git-diff-tracker] Failed to fetch base branch:",e)}),await this.git.diff([`origin/${e}`])}async cleanup(){this.snapshotIndexPath&&(await Fr(this.snapshotIndexPath),this.snapshotIndexPath=void 0),this.snapshotTreeHash=void 0}};async function Fr(e){try{await J(e)}catch{}}var Hr="x-stably-org-id",Gr={bodySerializer:e=>JSON.stringify(e,(e,t)=>"bigint"==typeof t?t.toString():t)},Wr=({allowReserved:e,explode:t,name:r,style:n,value:s})=>{if(!t){const t=(e?s:s.map(e=>encodeURIComponent(e))).join((e=>{switch(e){case"form":default:return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20"}})(n));switch(n){case"label":return`.${t}`;case"matrix":return`;${r}=${t}`;case"simple":return t;default:return`${r}=${t}`}}const o=(e=>{switch(e){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}})(n),i=s.map(t=>"label"===n||"simple"===n?e?t:encodeURIComponent(t):Vr({allowReserved:e,name:r,value:t})).join(o);return"label"===n||"matrix"===n?o+i:i},Vr=({allowReserved:e,name:t,value:r})=>{if(null==r)return"";if("object"==typeof r)throw new Error("Deeply-nested arrays/objects arenβt supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?r:encodeURIComponent(r)}`},Yr=({allowReserved:e,explode:t,name:r,style:n,value:s,valueOnly:o})=>{if(s instanceof Date)return o?s.toISOString():`${r}=${s.toISOString()}`;if("deepObject"!==n&&!t){let t=[];Object.entries(s).forEach(([r,n])=>{t=[...t,r,e?n:encodeURIComponent(n)]});const o=t.join(",");switch(n){case"form":return`${r}=${o}`;case"label":return`.${o}`;case"matrix":return`;${r}=${o}`;default:return o}}const i=(e=>{switch(e){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}})(n),a=Object.entries(s).map(([t,s])=>Vr({allowReserved:e,name:"deepObject"===n?`${r}[${t}]`:t,value:s})).join(i);return"label"===n||"matrix"===n?i+a:a},zr=/\{[^{}]+\}/g;function qr(e){const t=void 0!==e.body;return t&&e.bodySerializer?"serializedBody"in e?void 0!==e.serializedBody&&""!==e.serializedBody?e.serializedBody:null:""!==e.body?e.body:null:t?e.body:void 0}var Kr,Jr=async(e,t)=>{const r="function"==typeof t?await t(e):t;if(r)return"bearer"===e.scheme?`Bearer ${r}`:"basic"===e.scheme?`Basic ${btoa(r)}`:r},Xr=({parameters:e={},...t}={})=>r=>{const n=[];if(r&&"object"==typeof r)for(const s in r){const o=r[s];if(null==o)continue;const i=e[s]||t;if(Array.isArray(o)){const e=Wr({allowReserved:i.allowReserved,explode:!0,name:s,style:"form",value:o,...i.array});e&&n.push(e)}else if("object"==typeof o){const e=Yr({allowReserved:i.allowReserved,explode:!0,name:s,style:"deepObject",value:o,...i.object});e&&n.push(e)}else{const e=Vr({allowReserved:i.allowReserved,name:s,value:o});e&&n.push(e)}}return n.join("&")},Qr=(e,t)=>!!t&&!!(e.headers.has(t)||e.query?.[t]||e.headers.get("Cookie")?.includes(`${t}=`)),Zr=e=>(({baseUrl:e,path:t,query:r,querySerializer:n,url:s})=>{let o=(e??"")+(s.startsWith("/")?s:`/${s}`);t&&(o=(({path:e,url:t})=>{let r=t;const n=t.match(zr);if(n)for(const t of n){let n=!1,s=t.substring(1,t.length-1),o="simple";s.endsWith("*")&&(n=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(s=s.substring(1),o="label"):s.startsWith(";")&&(s=s.substring(1),o="matrix");const i=e[s];if(null==i)continue;if(Array.isArray(i)){r=r.replace(t,Wr({explode:n,name:s,style:o,value:i}));continue}if("object"==typeof i){r=r.replace(t,Yr({explode:n,name:s,style:o,value:i,valueOnly:!0}));continue}if("matrix"===o){r=r.replace(t,`;${Vr({name:s,value:i})}`);continue}const a=encodeURIComponent("label"===o?`.${i}`:i);r=r.replace(t,a)}return r})({path:t,url:o}));let i=r?n(r):"";return i.startsWith("?")&&(i=i.substring(1)),i&&(o+=`?${i}`),o})({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:"function"==typeof e.querySerializer?e.querySerializer:Xr(e.querySerializer),url:e.url}),en=(e,t)=>{const r={...e,...t};return r.baseUrl?.endsWith("/")&&(r.baseUrl=r.baseUrl.substring(0,r.baseUrl.length-1)),r.headers=rn(e.headers,t.headers),r},tn=e=>{const t=[];return e.forEach((e,r)=>{t.push([r,e])}),t},rn=(...e)=>{const t=new Headers;for(const r of e){if(!r)continue;const e=r instanceof Headers?tn(r):Object.entries(r);for(const[r,n]of e)if(null===n)t.delete(r);else if(Array.isArray(n))for(const e of n)t.append(r,e);else void 0!==n&&t.set(r,"object"==typeof n?JSON.stringify(n):n)}return t},nn=class{fns=[];clear(){this.fns=[]}eject(e){const t=this.getInterceptorIndex(e);this.fns[t]&&(this.fns[t]=null)}exists(e){const t=this.getInterceptorIndex(e);return Boolean(this.fns[t])}getInterceptorIndex(e){return"number"==typeof e?this.fns[e]?e:-1:this.fns.indexOf(e)}update(e,t){const r=this.getInterceptorIndex(e);return!!this.fns[r]&&(this.fns[r]=t,e)}use(e){return this.fns.push(e),this.fns.length-1}},sn=Xr({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),on={"Content-Type":"application/json"},an=(e={})=>({...Gr,headers:on,parseAs:"auto",querySerializer:sn,...e}),cn=(e={})=>{let t=en(an(),e);const r=()=>({...t}),n={error:new nn,request:new nn,response:new nn},s=async e=>{const r={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:rn(t.headers,e.headers),serializedBody:void 0};return r.security&&await(async({security:e,...t})=>{for(const r of e){if(Qr(t,r.name))continue;const e=await Jr(r,t.auth);if(!e)continue;const n=r.name??"Authorization";switch(r.in){case"query":t.query||(t.query={}),t.query[n]=e;break;case"cookie":t.headers.append("Cookie",`${n}=${e}`);break;default:t.headers.set(n,e)}}})({...r,security:r.security}),r.requestValidator&&await r.requestValidator(r),void 0!==r.body&&r.bodySerializer&&(r.serializedBody=r.bodySerializer(r.body)),void 0!==r.body&&""!==r.serializedBody||r.headers.delete("Content-Type"),{opts:r,url:Zr(r)}},o=async e=>{const{opts:t,url:r}=await s(e),o={redirect:"follow",...t,body:qr(t)};let i=new Request(r,o);for(const e of n.request.fns)e&&(i=await e(i,t));const a=t.fetch;let c=await a(i);for(const e of n.response.fns)e&&(c=await e(c,i,t));const l={request:i,response:c};if(c.ok){const e=("auto"===t.parseAs?(e=>{if(!e)return"stream";const t=e.split(";")[0]?.trim();return t?t.startsWith("application/json")||t.endsWith("+json")?"json":"multipart/form-data"===t?"formData":["application/","audio/","image/","video/"].some(e=>t.startsWith(e))?"blob":t.startsWith("text/")?"text":void 0:void 0})(c.headers.get("Content-Type")):t.parseAs)??"json";if(204===c.status||"0"===c.headers.get("Content-Length")){let r;switch(e){case"arrayBuffer":case"blob":case"text":r=await c[e]();break;case"formData":r=new FormData;break;case"stream":r=c.body;break;default:r={}}return"data"===t.responseStyle?r:{data:r,...l}}let r;switch(e){case"arrayBuffer":case"blob":case"formData":case"json":case"text":r=await c[e]();break;case"stream":return"data"===t.responseStyle?c.body:{data:c.body,...l}}return"json"===e&&(t.responseValidator&&await t.responseValidator(r),t.responseTransformer&&(r=await t.responseTransformer(r))),"data"===t.responseStyle?r:{data:r,...l}}const u=await c.text();let d;try{d=JSON.parse(u)}catch{}const p=d??u;let f=p;for(const e of n.error.fns)e&&(f=await e(p,c,i,t));if(f=f||{},t.throwOnError)throw f;return"data"===t.responseStyle?void 0:{error:f,...l}},i=e=>t=>o({...t,method:e}),a=e=>async t=>{const{opts:r,url:o}=await s(t);return(({onRequest:e,onSseError:t,onSseEvent:r,responseTransformer:n,responseValidator:s,sseDefaultRetryDelay:o,sseMaxRetryAttempts:i,sseMaxRetryDelay:a,sseSleepFn:c,url:l,...u})=>{let d;const p=c??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let c=o??3e3,f=0;const h=u.signal??(new AbortController).signal;for(;!h.aborted;){f++;const o=u.headers instanceof Headers?u.headers:new Headers(u.headers);void 0!==d&&o.set("Last-Event-ID",d);try{const t={redirect:"follow",...u,body:u.serializedBody,headers:o,signal:h};let i=new Request(l,t);e&&(i=await e(l,t));const a=u.fetch??globalThis.fetch,p=await a(i);if(!p.ok)throw new Error(`SSE failed: ${p.status} ${p.statusText}`);if(!p.body)throw new Error("No body in SSE response");const f=p.body.pipeThrough(new TextDecoderStream).getReader();let g="";const m=()=>{try{f.cancel()}catch{}};h.addEventListener("abort",m);try{for(;;){const{done:e,value:t}=await f.read();if(e)break;g+=t;const o=g.split("\n\n");g=o.pop()??"";for(const e of o){const t=e.split("\n"),o=[];let i,a;for(const e of t)if(e.startsWith("data:"))o.push(e.replace(/^data:\s*/,""));else if(e.startsWith("event:"))i=e.replace(/^event:\s*/,"");else if(e.startsWith("id:"))d=e.replace(/^id:\s*/,"");else if(e.startsWith("retry:")){const t=Number.parseInt(e.replace(/^retry:\s*/,""),10);Number.isNaN(t)||(c=t)}let l=!1;if(o.length){const e=o.join("\n");try{a=JSON.parse(e),l=!0}catch{a=e}}l&&(s&&await s(a),n&&(a=await n(a))),r?.({data:a,event:i,id:d,retry:c}),o.length&&(yield a)}}}finally{h.removeEventListener("abort",m),f.releaseLock()}break}catch(e){if(t?.(e),void 0!==i&&f>=i)break;const r=Math.min(c*2**(f-1),a??3e4);await p(r)}}}()}})({...r,body:r.body,headers:r.headers,method:e,onRequest:async(e,t)=>{let s=new Request(e,t);for(const e of n.request.fns)e&&(s=await e(s,r));return s},url:o})};return{buildUrl:Zr,connect:i("CONNECT"),delete:i("DELETE"),get:i("GET"),getConfig:r,head:i("HEAD"),interceptors:n,options:i("OPTIONS"),patch:i("PATCH"),post:i("POST"),put:i("PUT"),request:o,setConfig:e=>(t=en(t,e),r()),sse:{connect:a("CONNECT"),delete:a("DELETE"),get:a("GET"),head:a("HEAD"),options:a("OPTIONS"),patch:a("PATCH"),post:a("POST"),put:a("PUT"),trace:a("TRACE")},trace:i("TRACE")}},ln=cn(an({baseUrl:"https://api.stably.ai"})),un=e=>(e.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs",...e}),dn=e=>(e.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}",...e}),pn="4.12.26-rc.0",fn=process.env.STABLY_API_URL||"https://api.stably.ai",hn=e=>{const t=new URL(e);return t.protocol="http:"===t.protocol?"ws:":"wss:",t},gn=process.env.AUTH_URL||"https://auth.stably.ai",mn=process.env.AUTH_CLIENT_ID||"288007877071cce81f269428ea78653a",yn=process.env.AI_PROXY_URL||"https://ai-proxy.stably.ai",bn=process.env.STABLY_AUTOHEAL_WS_URL||new URL("/autoheal",hn(fn)).toString(),wn=process.env.STABLY_CREATE_PROGRESS_WS_URL||new URL("/create-progress",hn(fn)).toString(),vn="http://localhost:9876/auth/callback",In=()=>Kr||(Kr=cn(an({baseUrl:fn,headers:{"X-STABLY-CLI-VERSION":pn,"X-STABLY-SOURCE":"cli"}}))),Tn=async(e,t)=>{const r=await(n={body:{accessToken:e,orgId:t},client:In()},(n.client??ln).post({url:"/internal/v1/cli/exchange-token",...n,headers:{"Content-Type":"application/json",...n.headers}}));var n;if(401===r.response.status)throw new Error("Invalid or expired access token");if(403===r.response.status)throw new Error("You do not have access to this organization");if(r.error)throw new Error(`Failed to exchange token: ${r.response.status}`);return r.data},_n=he.object({org_id:he.string(),org_name:he.string()}),En=he.object({email:he.string(),org_id_to_org_member_info:he.record(he.string(),_n).optional(),org_member_info:_n.optional(),user_id:he.string()});he.object({email:he.string(),firstName:he.string().optional(),lastName:he.string().optional(),organizations:he.array(he.object({id:he.string(),name:he.string()})),userId:he.string()});var Sn,xn=e=>{const t=e.split(".");if(3!==t.length)throw new Error("Invalid JWT format");const r=t[1].replace(/-/g,"+").replace(/_/g,"/"),n=Buffer.from(r,"base64").toString("utf-8");return JSON.parse(n)},An=e=>{try{const t=En.parse(xn(e)),r=t.org_id_to_org_member_info?Object.entries(t.org_id_to_org_member_info).map(([e,t])=>({id:e,name:t.org_name})):t.org_member_info?[{id:t.org_member_info.org_id,name:t.org_member_info.org_name}]:[];return{email:t.email,organizations:r,userId:t.user_id}}catch(e){throw new Error(`Failed to decode token: ${e instanceof Error?e.message:"Unknown error"}`)}},kn=async(e,t)=>{let r=e;const{root:s}=n.parse(r);for(;r!==s;){const e=n.join(r,t);try{return await X(e),e}catch{r=n.dirname(r)}}},Pn=n.join(D.homedir(),".stably"),Cn=n.join(Pn,"auth.json"),Rn=".stably",Un="project.json",Ln=fe.object({accessToken:fe.string(),expiresAt:fe.number(),idToken:fe.string().optional(),refreshToken:fe.string()}),$n=fe.object({orgId:fe.string(),orgName:fe.string(),projectId:fe.string(),projectName:fe.string()}),Dn=async()=>{try{const e=await z(Cn,"utf-8");return Ln.parse(JSON.parse(e))}catch{return}},Nn=async e=>{await q(Pn,{recursive:!0}),await K(Cn,JSON.stringify(e,null,2),{mode:384})},On=async()=>{try{await J(Cn)}catch{}},Bn=async()=>{try{const e=await kn(process.cwd(),Rn);if(!e)return;const t=n.join(e,Un),r=await z(t,"utf-8");return $n.parse(JSON.parse(r))}catch{return}},jn=async()=>{try{const e=await kn(process.cwd(),Rn);e&&await J(n.join(e,Un))}catch{}},Mn=e=>Date.now()>=e.expiresAt-3e5,Fn=async e=>{const t=new URLSearchParams({client_id:mn,grant_type:"refresh_token",refresh_token:e}),r=await fetch(`${gn}/propelauth/oauth/token`,{body:t.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST"});if(!r.ok)throw new Error(`Token refresh failed: ${r.status}`);const n=await r.json();return{accessToken:n.access_token,expiresAt:Date.now()+1e3*n.expires_in,refreshToken:n.refresh_token}},Hn=e=>`\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Failed Stably CLI</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #000;\n color: #fafafa;\n }\n .container {\n text-align: center;\n padding: 48px;\n max-width: 400px;\n }\n .icon {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #ef4444;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .icon svg { width: 24px; height: 24px; }\n .title {\n font-size: 24px;\n font-weight: 600;\n margin: 0 0 8px;\n letter-spacing: -0.5px;\n }\n .subtitle {\n color: #888;\n font-size: 14px;\n margin: 0 0 32px;\n line-height: 1.5;\n }\n .error-box {\n background: rgba(239, 68, 68, 0.1);\n border: 1px solid rgba(239, 68, 68, 0.3);\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 24px;\n }\n .error-label {\n font-size: 11px;\n font-weight: 600;\n color: #ef4444;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n .error-message {\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n font-size: 13px;\n color: #fafafa;\n word-break: break-word;\n }\n .hint {\n color: #666;\n font-size: 13px;\n }\n .hint code {\n background: #111;\n border: 1px solid #333;\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n font-size: 12px;\n color: #888;\n }\n .brand {\n margin-top: 32px;\n font-size: 12px;\n color: #444;\n letter-spacing: 0.5px;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="icon">\n <svg fill="none" stroke="#000" stroke-width="3" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>\n </svg>\n </div>\n <h1 class="title">Authentication Failed</h1>\n <p class="subtitle">Something went wrong during login.</p>\n <div class="error-box">\n <div class="error-label">Error</div>\n <div class="error-message">${e}</div>\n </div>\n <p class="hint">Run <code>stably login</code> to try again.</p>\n <div class="brand">STABLY</div>\n </div>\n</body>\n</html>\n`,Gn=(e,t,r)=>{e.writeHead(t,{"Content-Type":"text/html"}),e.end(r)},Wn=(e,t)=>{const r=new URLSearchParams({client_id:mn,code_challenge:e,code_challenge_method:"S256",redirect_uri:vn,response_type:"code",state:t});return`${gn}/propelauth/oauth/authorize?${r.toString()}`},Vn=async e=>{const t=le();let r;t.start("Loading user info...");try{r=An(e.accessToken),t.stop(Dr("success",`β Logged in as ${Dr("info",r.email)}`))}catch(e){t.stop(Dr("error","β Failed to load user info"));const r=e instanceof Error?e.message:"Unknown error";return ae.error(r),{success:!1}}const s=await(async e=>{if(0===e.length)return void ae.error("You don't belong to any organizations.");if(1===e.length)return ae.info(`Using organization: ${Dr("info",e[0].name)}`),e[0];if(!process.stdin.isTTY)return ae.info(`Auto-selecting organization: ${Dr("info",e[0].name)}`),e[0];const t=await de({message:"Select an organization",options:[...e].sort((e,t)=>e.name.localeCompare(t.name)).map(e=>({label:e.name,value:e.id}))});return pe(t)?void 0:e.find(e=>e.id===t)})(r.organizations);if(!s)return ae.warn("Organization selection cancelled."),{success:!1};let o;t.start("Getting org credentials...");try{const r=await Tn(e.accessToken,s.id);o={accessToken:r.accessToken,expiresAt:Date.now()+1e3*r.expiresInSeconds,idToken:e.idToken,refreshToken:e.refreshToken},t.stop(Dr("success","β Credentials obtained"))}catch(e){t.stop(Dr("error","β Failed to get org credentials"));const r=e instanceof Error?e.message:"Unknown error";return ae.error(r),{success:!1}}const i=await(async(e,t)=>{const r=le();let n;r.start("Loading projects...");try{n=await(async({accessToken:e,orgId:t})=>{const r=await(n={auth:e,client:In(),path:{orgId:t}},(n.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/orgs/{orgId}/projects",...n}));var n;if(401===r.response.status)throw new Error("Invalid or expired access token");if(403===r.response.status)throw new Error("You do not have access to this organization");if(r.error)throw new Error(`Failed to list projects: ${r.response.status}`);return r.data.projects})({accessToken:e,orgId:t}),r.stop(Dr("success","β Projects loaded"))}catch(e){r.stop(Dr("error","β Failed to load projects"));const t=e instanceof Error?e.message:"Unknown error";return void ae.error(t)}if(0===n.length)return ae.error("No projects found in this organization."),void ae.info(`Create a project at ${ne.underline(Dr("link","https://app.stably.ai"))}`);if(1===n.length)return ae.info(`Using project: ${Dr("info",n[0].name)}`),n[0];if(!process.stdin.isTTY)return ae.info(`Auto-selecting project: ${Dr("info",n[0].name)}`),n[0];const s=await de({message:"Select a project",options:n.map(e=>({label:e.name,value:e.id}))});return pe(s)?void 0:n.find(e=>e.id===s)})(o.accessToken,s.id);return i?(await(async e=>{const t=n.join(process.cwd(),Rn),r=n.join(t,Un);await q(t,{recursive:!0}),await K(r,JSON.stringify(e,null,2)),await(async e=>{const t=n.join(e,".gitignore"),r="# Stably CLI (only docs/ are tracked)\n.stably/*\n!.stably/docs/";try{const e=await z(t,"utf-8"),n=e.split("\n").map(e=>e.trim());if(n.includes(".stably/*")&&n.includes("!.stably/docs/"))return;const s=/^# Stably CLI\n\.stably\/?$/m,o=/^\.stably\/?$/m;if(s.test(e)){const n=e.replace(s,`\n${r}\n`);await K(t,n)}else if(o.test(e)){const n=e.replace(o,`\n${r}\n`);await K(t,n)}else await ee(t,`\n${r}\n`)}catch{await K(t,`${r}\n`)}})(process.cwd())})({orgId:s.id,orgName:s.name,projectId:i.id,projectName:i.name}),ae.info(ne.dim("Linked this directory to your Stably project.")),{scopedTokens:o,success:!0}):(ae.warn("Project selection cancelled."),{success:!1})},Yn=async()=>{if(gs())return ae.warn(`Environment variables ${Dr("info","STABLY_API_KEY")} and ${Dr("info","STABLY_PROJECT_ID")} are set.`),ae.warn("These will be used for authentication instead of OAuth login."),ae.warn("To use OAuth login, unset these environment variables first."),void ce(Dr("warning","Login skipped - using environment variable authentication."));const e=await Dn();if(e){if(!Mn(e)){if(await Bn())return void ce(Dr("warning","You are already logged in. Run `stably logout` first to log out."));ae.info("You are logged in but haven't selected a project yet.");const t=await Vn(e);return void(t.success?(await Nn(t.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):ce(Dr("warning","Setup incomplete. Run `stably login` to try again.")))}const t=le();t.start("Refreshing session...");try{const r=await Fn(e.refreshToken);t.stop(Dr("success","β Session refreshed"));const n=await Bn();if(n){t.start("Getting org credentials...");try{const e=await Tn(r.accessToken,n.orgId),s={accessToken:e.accessToken,expiresAt:Date.now()+1e3*e.expiresInSeconds,idToken:r.idToken,refreshToken:r.refreshToken};await Nn(s),t.stop(Dr("success","β Credentials obtained")),ce(Dr("success","Login successful"))}catch{await Nn(r),t.stop(Dr("warning","Using full credentials")),ce(Dr("success","Login successful"))}}else{const e=await Vn(r);e.success?(await Nn(e.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):ce(Dr("warning","Setup incomplete. Run `stably login` to try again."))}return}catch{t.stop(Dr("warning","Session expired, proceeding with fresh login...")),await On(),await jn()}}const{authorizeUrl:t,serverReady:r,waitForCallback:n}=(()=>{const{authorizeUrl:e,codeVerifier:t,state:r}=(()=>{const e=oe.randomBytes(32).toString("base64url"),t=(r=e,oe.createHash("sha256").update(r).digest("base64url"));var r;const n=oe.randomBytes(16).toString("base64url");return{authorizeUrl:Wn(t,n),codeVerifier:e,state:n}})(),{ready:n,result:s}=(e=>{let t,r;return{ready:new Promise((e,n)=>{t=e,r=n}),result:new Promise((n,s)=>{const o=setTimeout(()=>{a.close(),n({error:"Login timed out",success:!1})},3e5),i=()=>{clearTimeout(o)},a=me.createServer((t,r)=>{const s=new $(t.url||"","http://localhost:9876");if("/auth/callback"!==s.pathname)return r.writeHead(404),void r.end("Not found");const o=s.searchParams.get("code"),c=s.searchParams.get("state"),l=s.searchParams.get("error");return l?(Gn(r,400,Hn(l)),i(),a.close(),void n({error:l,success:!1})):o&&c?c!==e?(Gn(r,400,Hn("Invalid state parameter (possible CSRF attack)")),i(),a.close(),void n({error:"State mismatch",success:!1})):(Gn(r,200,'\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authenticated Stably CLI</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #000;\n color: #fafafa;\n }\n .container {\n text-align: center;\n padding: 48px;\n max-width: 400px;\n }\n .icon {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #22c55e;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .icon svg { width: 24px; height: 24px; }\n .title {\n font-size: 24px;\n font-weight: 600;\n margin: 0 0 8px;\n letter-spacing: -0.5px;\n }\n .subtitle {\n color: #888;\n font-size: 14px;\n margin: 0 0 32px;\n line-height: 1.5;\n }\n .terminal {\n background: #111;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 16px;\n text-align: left;\n font-family: \'SF Mono\', \'Fira Code\', \'Consolas\', monospace;\n font-size: 13px;\n }\n .terminal-header {\n display: flex;\n gap: 6px;\n margin-bottom: 12px;\n }\n .terminal-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #333;\n }\n .terminal-line {\n color: #888;\n }\n .terminal-line .prompt { color: #888; }\n .terminal-line .cmd { color: #fafafa; }\n .terminal-line.success { color: #22c55e; }\n .brand {\n margin-top: 32px;\n font-size: 12px;\n color: #444;\n letter-spacing: 0.5px;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="icon">\n <svg fill="none" stroke="#000" stroke-width="3" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>\n </svg>\n </div>\n <h1 class="title">Authenticated</h1>\n <p class="subtitle">You can close this tab and return to your terminal.</p>\n <div class="terminal">\n <div class="terminal-header">\n <div class="terminal-dot"></div>\n <div class="terminal-dot"></div>\n <div class="terminal-dot"></div>\n </div>\n <div class="terminal-line"><span class="prompt">$</span> <span class="cmd">stably login</span></div>\n <div class="terminal-line success">Logged in successfully</div>\n </div>\n <div class="brand">STABLY</div>\n </div>\n</body>\n</html>\n'),i(),a.close(),void n({code:o,state:c,success:!0})):(Gn(r,400,Hn("Missing code or state parameter")),i(),a.close(),void n({error:"Missing code or state parameter",success:!1}))});a.on("error",e=>{if(i(),"EADDRINUSE"===e.code){const e=new Error("Port 9876 is already in use. Please close the application using it and try again.");return r(e),void s(e)}const t=new Error(`Failed to start callback server: ${e.message}`);r(t),s(t)}),a.listen(9876,()=>{t()})})}})(r);return{authorizeUrl:e,serverReady:n,waitForCallback:async()=>{const e=await s;if(!e.success)throw new Error(e.error);return(async(e,t)=>{const r=new URLSearchParams({client_id:mn,code:e,code_verifier:t,grant_type:"authorization_code",redirect_uri:vn}),n=await fetch(`${gn}/propelauth/oauth/token`,{body:r.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST"});if(!n.ok){const e=await n.text();throw new Error(`Token exchange failed: ${n.status} ${e}`)}const s=await n.json();return{accessToken:s.access_token,expiresAt:Date.now()+1e3*s.expires_in,idToken:s.id_token,refreshToken:s.refresh_token}})(e.code,t)}}})();await r,ae.info("Opening browser for authentication..."),ae.info(ne.dim("If browser doesn't open, visit:")),ae.info(`]8;;${t}${ne.underline(Dr("link",t))}]8;;`);try{await ge(t)}catch{ae.warn("Could not open browser automatically. Please open the URL above manually.")}const s=le();let o;s.start("Waiting for authentication...");try{o=await n(),s.stop(Dr("success","β Authentication successful"))}catch(e){s.stop(Dr("error","β Authentication failed"));const t=e instanceof Error?e.message:"Unknown error";ce(Dr("error",`Login failed: ${t}`)),process.exit(1)}const i=await Vn(o);i.success?(await Nn(i.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):(ce(Dr("warning","Setup incomplete. Run `stably login` to try again.")),process.exit(1))},zn={fatal:60,error:50,warn:40,info:30,debug:20,trace:10},qn=new Set(["help","login","logout","whoami","tunnel","create","fix","internal-fix-run","init","upgrade","test","show-report","codegen"]),Kn=(new Date).toISOString().split("T")[0],Jn=(()=>{const e=[n.join(D.tmpdir(),"stably-logs",Kn),n.join(D.homedir(),".stably","logs",Kn)];for(const t of e)try{return v.mkdirSync(t,{recursive:!0}),t}catch{}return null})(),Xn=process.argv.includes("--verbose")||process.argv.includes("-v"),Qn=process.env.STABLY_LOG_LEVEL?.toLowerCase(),Zn=Xn?"debug":void 0!==(Sn=Qn)&&Sn in zn?Qn:"warn",es=zn[Zn],ts=null,rs=null,ns=null,ss=[],os=!1,is=e=>{if(!os){if(!(ts=(e=>{if(!Jn)return null;const t=(()=>{const e=new Date;return[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")].join("-")})(),r=((e,t=100)=>e.replace(/[/\\:*?"<>|]/g,"-").replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-_]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,t).toLowerCase()||"session")(e);return n.join(Jn,`${t}-${r}.log`)})(e)))return ss=[],void(os=!0);(e=>{const t=["","=".repeat(60),"Stably CLI Debug Log",`Version: ${pn}`,`Generated: ${(new Date).toISOString()}`,`Node: ${process.version}`,`Platform: ${process.platform} ${D.release()}`,`CWD: ${process.cwd()}`,`Args: ${process.argv.slice(2).join(" ")}`,`Log Level (console): ${Zn}`,"=".repeat(60),""].join("\n");e.write(t)})(rs=new be({dest:ts,minLength:4096,sync:!1,append:!0})),ns=ye({level:"debug",timestamp:ye.stdTimeFunctions.isoTime,base:{version:pn}},rs);for(const{level:e,msg:t,context:r}of ss)r?ns[e](r,t):ns[e](t);ss=[],os=!0,Xn&&process.stderr.write(`${ne.dim(`Debug log: ${ts}`)}\n\n`)}},as=(()=>{const e=process.argv.slice(2).find(e=>!e.startsWith("-"));return e&&qn.has(e)?e:null})();as&&is(as);var cs=e=>(t,r)=>{if(ns?r?ns[e](r,t):ns[e](t):os||ss.push({level:e,msg:t,context:r}),(e=>zn[e]>=es)(e)){const r=((e,t)=>`${{fatal:Nr("fatalBg",ne.white(ne.bold(" FATAL "))),error:Dr("error","error"),warn:Dr("warning","warn"),info:Dr("info","info"),debug:ne.dim("debug"),trace:ne.dim("trace")}[e]} ${t}`)(e,t);process.stderr.write(`${r}\n`)}},ls={fatal:cs("fatal"),error:cs("error"),warn:cs("warn"),info:cs("info"),debug:cs("debug"),trace:cs("trace"),initSession:e=>{os||is(e)},getLogFilePath:()=>ts,flush:()=>{if(rs)try{rs.flushSync()}catch{}},printLogFileInfo:()=>{ts&&(process.stderr.write(`\n${ne.dim("Debug log written to:")}\n`),process.stderr.write(` ${Dr("info",ts)}\n`),process.stderr.write(`${ne.dim("Share this file with support for assistance.")}\n`))},getPinoLogger:()=>ns};setInterval(()=>{ls.flush()},3e4).unref(),process.on("beforeExit",()=>{ls.flush()});var us=e=>{const t=()=>{ls.flush(),Xn&&ls.printLogFileInfo(),process.removeListener(e,t),process.kill(process.pid,e)};return t};process.on("SIGINT",us("SIGINT")),process.on("SIGTERM",us("SIGTERM"));var ds=()=>"true"===process.env.GITHUB_ACTIONS?"github-actions":"true"===process.env.GITLAB_CI?"gitlab-ci":"true"===process.env.CIRCLECI?"circleci":process.env.JENKINS_URL?"jenkins":process.env.CI?"generic-ci":"local",ps=()=>"local"!==ds(),fs=e=>{switch(e){case"github-actions":return"GitHub secrets";case"gitlab-ci":return"GitLab CI/CD variables";case"circleci":return"CircleCI environment variables";case"jenkins":return"Jenkins credentials";case"generic-ci":return"CI secrets/environment variables";case"local":return"environment variables"}},hs=()=>{const e=ds();return[`Authentication failed. In CI, add the following to your ${fs(e)}:`," STABLY_API_KEY β https://app.stably.ai/settings?tab=api-key"," STABLY_PROJECT_ID β https://app.stably.ai/settings?tab=project-id"].join("\n")},gs=()=>{const e=process.env.STABLY_API_KEY?.trim(),t=process.env.STABLY_PROJECT_ID?.trim();if(e&&t)return ls.debug("Environment auth detected",{hasApiKey:!0,hasProjectId:!0}),{apiKey:e,projectId:t};ls.debug("Environment auth not set",{hasApiKey:!!e,hasProjectId:!!t})},ms=async()=>{ls.debug("Checking for stored auth tokens");const e=await Dn();if(!e)return void ls.debug("No stored auth tokens found");const t=Mn(e);if(ls.debug("Auth tokens status",{expired:t}),!t){const t=await Bn(),r=(e=>{try{const t=En.parse(xn(e));if(t.org_id_to_org_member_info)return"full";if(t.org_member_info)return"org"}catch{return"unknown"}return"unknown"})(e.accessToken);if(ls.debug("Token scope check",{scope:r,hasContext:!!t}),t&&"full"===r)try{ls.debug("Exchanging full token for org-scoped token",{orgId:t.orgId});const r=await Tn(e.accessToken,t.orgId),n={accessToken:r.accessToken,expiresAt:Date.now()+1e3*r.expiresInSeconds,idToken:e.idToken,refreshToken:e.refreshToken};return await Nn(n),ls.debug("Token exchange successful"),n}catch(t){return ls.debug("Token exchange failed, using existing token",{error:t instanceof Error?t.message:String(t)}),e}return e}try{ls.debug("Attempting token refresh");const t=await Fn(e.refreshToken);ls.debug("Token refresh successful");const r=await Bn();if(r)try{ls.debug("Exchanging refreshed token for org-scoped token");const e=await Tn(t.accessToken,r.orgId),n={accessToken:e.accessToken,expiresAt:Date.now()+1e3*e.expiresInSeconds,idToken:t.idToken,refreshToken:t.refreshToken};return await Nn(n),n}catch{return await Nn(t),t}return await Nn(t),t}catch(e){return void ls.warn("Token refresh failed",{error:e instanceof Error?e.message:String(e)})}},ys=async(e={})=>{ls.debug("Requiring authentication",{autoLogin:e.autoLogin});const t=gs();if(t)return ls.info("Using environment variable authentication"),{auth:t,type:"env"};const r=await Dn();let n=await ms(),s=n?await Bn():void 0;const o=process.stdin.isTTY&&process.stdout.isTTY;if(ls.debug("OAuth auth check",{hasTokens:!!n,hasStoredTokens:!!r,hasContext:!!s,canPrompt:o}),(!n||!s)&&e.autoLogin&&o){ls.info("Prompting user to login"),n?ae.info("You are logged in but need to select an organization and project."):ae.info("You are not logged in."),ae.info("Press Enter to log in."),process.stdout.write(`${ne.dim("Alternatively, set environment variables for an org API key:")}\n${ne.dim(" STABLY_API_KEY=... STABLY_PROJECT_ID=... stably")}\n`),process.stdout.write("\n");const e=re({input:process.stdin,output:process.stdout});try{await e.question(ne.dim("Press Enter to continue... "))}finally{e.close()}await Yn(),n=await ms(),s=n?await Bn():void 0}return n||(ls.warn("Authentication required but no tokens available",{hadStoredTokens:!!r}),ps()?ce(Dr("error",hs())):ce(Dr("error",r?"Your session has expired. Run `stably login` to re-authenticate.":"You are not logged in. Run `stably login` to authenticate.")),process.exit(1)),s||(ls.warn("Authentication succeeded but no project context selected"),ps()?ce(Dr("error",hs())):ce(Dr("error","You haven't selected an organization and project. Run `stably login` to complete setup.")),process.exit(1)),ls.info("OAuth authentication successful",{orgId:s.orgId,projectId:s.projectId}),{auth:{accessToken:n.accessToken,context:s},type:"oauth"}},bs=e=>"env"===e.type?e.auth.projectId:e.auth.context.projectId,ws=e=>"env"===e.type?e.auth.apiKey:e.auth.accessToken,vs=class e{static TOKEN_REFRESH_BUFFER_MS=3e5;initialAuth;refreshPromise=null;cachedToken=null;cachedExpiresAt=0;constructor(e){this.initialAuth=e}async getAuthHeader(){return"env"===this.initialAuth.type?this.initialAuth.auth.apiKey:this.cachedToken&&Date.now()<this.cachedExpiresAt-e.TOKEN_REFRESH_BUFFER_MS?this.cachedToken:(this.refreshPromise||(this.refreshPromise=(async()=>{try{const e=await ms();if(!e)throw new Error("Authentication expired and refresh failed. Please re-run `stably login`.");return this.cachedToken=e.accessToken,this.cachedExpiresAt=e.expiresAt,e.accessToken}finally{this.refreshPromise=null}})()),this.refreshPromise)}getOrgId(){return"oauth"===this.initialAuth.type?this.initialAuth.auth.context.orgId:void 0}getProjectId(){return"env"===this.initialAuth.type?this.initialAuth.auth.projectId:this.initialAuth.auth.context.projectId}},Is=async e=>{const t=await ys(),r=bs(t),n=ws(t);ls.debug("Fetching remote environment variables",{envName:e,projectId:r});const s=await(o={auth:n,client:In(),path:{projectId:r,environment:e}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments/{environment}/variables",...o}));var o;if(404===s.response.status)return{ok:!1,error:`Environment "${e}" not found. Check the name on your Stably dashboard.`};if(401===s.response.status||403===s.response.status)return{ok:!1,error:`Access denied to environment "${e}".`};if(s.error)return{ok:!1,error:`Failed to fetch environment "${e}": ${s.response.status}`};const i={},a=[];for(const e of s.data.variables)i[e.name]=e.value,e.sensitive&&e.value.length>0&&a.push(e.value);const c=s.data.variables.length,l=a.length;return process.stderr.write(`${Dr("info",`Loaded ${c} variable${1!==c?"s":""} from "${e}"`)}${l>0?ne.dim(` (${l} sensitive)`):""}\n`),{ok:!0,result:{variables:i,sensitiveValues:a}}},Ts=async()=>{const e=Ue.remoteEnvName;if(!e)return;const t=await Is(e);return t.ok||(ce(Dr("error",t.error)),process.exit(1)),t.result},_s=e=>e?{[Hr]:e}:void 0,Es=he.object({context:he.string().min(1),autohealReportUrl:he.string(),skippedTests:he.array(he.object({testIdentifier:he.string(),testTitle:he.string(),consecutiveUnfixedCount:he.number()})).optional(),newerPassingSuiteId:he.string().optional(),envName:he.string().optional()}),Ss=we.object({bucket:we.string(),key:we.string()}),xs=async({body:e,contentType:t,uploadUrl:r,errorContext:n="content"})=>{const s=await fetch(r,{body:e instanceof Uint8Array?Buffer.from(e):e,headers:{"Content-Type":t},method:"PUT"});if(!s.ok)throw new Error(`Failed to upload ${n} (${s.status})`)},As=we.object({diffBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string()}),ks=we.object({traceBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string(),sensitiveValues:we.array(we.string())}),Ps=async({authHeader:e,contentType:t="text/plain",orgId:r,runId:n})=>{const s=await(o={auth:e,body:{contentType:t},client:In(),headers:_s(r),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-diff/upload-url",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to presign diff upload (${s.response.status})`);const i=As.parse(s.data);return{diffBucketPath:i.diffBucketPath,expiresInSeconds:i.expiresInSeconds,key:i.key,uploadUrl:i.uploadUrl}},Cs=async({authHeader:e,diffBucketPath:t,orgId:r,runId:n})=>{const s=await(o={auth:e,body:t,client:In(),headers:_s(r),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-diff/confirm-upload",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to confirm diff upload (${s.response.status})`)},Rs=class e{socket;url;authProvider;orgId;runId;pendingEvent=null;reconnectAttempts=0;reconnectTimer;flushPromise=null;debounceTimer;_isClosed=!1;isAuthenticated=!1;authenticationFailed=!1;onUserMessage;maxReconnectAttempts=10;baseReconnectDelay=2e3;maxReconnectDelay=3e4;debounceMs=500;get isClosed(){return this._isClosed}constructor({authProvider:e,orgId:t,runId:r,url:n=bn,onUserMessage:s}){this.authProvider=e,this.orgId=t,this.runId=r,this.url=n,this.onUserMessage=s,ls.info("[ws] Constructing AutohealWebSocketClient",{url:this.url,runId:r})}async start(){await this.connect()}async connect(){if(!this._isClosed)try{const e=await this.authProvider.getAuthHeader();if(this._isClosed)return;const t={Authorization:e};this.orgId&&(t["x-stably-org-id"]=this.orgId);const r=`${this.url}?runId=${encodeURIComponent(this.runId)}`;ls.info("[ws] Connecting",{url:r,attempt:this.reconnectAttempts}),this.socket=new ve(r,{headers:t}),this.socket.on("open",()=>{ls.info("[ws] Connection opened"),this.reconnectAttempts=0}),this.socket.on("message",e=>{try{const t="string"==typeof e?e:e.toString(),r=JSON.parse(t);ls.debug("[ws] Received message",{type:r?.type}),"connected"===r?.type&&(ls.info("[ws] Authenticated successfully"),this.isAuthenticated=!0,this.authenticationFailed=!1,this.flushPending()),"user_message"===r?.type&&"string"==typeof r.content&&(ls.info("[ws] Received user message from web UI"),this.onUserMessage?.(r.content))}catch{}}),this.socket.on("close",(e,t)=>{ls.info("[ws] Connection closed",{code:e,authFailed:1008===e,reconnectAttempts:this.reconnectAttempts,maxReconnect:this.maxReconnectAttempts,isClosed:this._isClosed}),this.isAuthenticated=!1,1008===e&&(this.authenticationFailed=!0),!this._isClosed&&!this.authenticationFailed&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()}),this.socket.on("error",e=>{ls.warn("[ws] Connection error",{error:e.message})})}catch(e){ls.warn("[ws] Failed to create WebSocket",{error:e instanceof Error?e.message:String(e)}),this.scheduleReconnect()}}scheduleReconnect(){if(this._isClosed||this.reconnectTimer)return;this.reconnectAttempts++;const e=Math.min(this.baseReconnectDelay*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelay);ls.info("[ws] Scheduling reconnect",{attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts,delayMs:e}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.connect().catch(e=>{ls.warn("[ws] Reconnect failed",{error:e instanceof Error?e.message:String(e)})})},e)}isConnected(){return!!this.socket&&this.socket.readyState===ve.OPEN&&this.isAuthenticated}sendProgress(e){if(this._isClosed)return void ls.debug("[ws] sendProgress called but client is closed",{phase:e.phase});const t={type:"autoheal_progress",payload:e};return this.pendingEvent=t,this.isConnected()?"complete"===e.phase?(ls.info("[ws] sendProgress: flushing terminal state immediately"),void this.flushPending()):void(this.debounceTimer||(this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.flushPending()},this.debounceMs))):(ls.debug("[ws] sendProgress: not connected, queuing event",{phase:e.phase,socketState:this.socket?.readyState,isAuthenticated:this.isAuthenticated,reconnectAttempts:this.reconnectAttempts}),void(this.socket?.readyState===ve.CLOSED&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()))}flushPending(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),!this.pendingEvent)return;const e=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.debug("[ws] flushPending: not connected, re-queuing event",{phase:e.payload.phase}),void(this.pendingEvent=e);ls.debug("[ws] flushPending: sending event",{phase:e.payload.phase});const t=new Promise(t=>{try{this.socket?.send(JSON.stringify(e),r=>{r&&(ls.warn("[ws] flushPending: send failed",{error:r.message,phase:e.payload.phase}),this.pendingEvent||(this.pendingEvent=e)),t()})}catch(r){ls.warn("[ws] flushPending: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=e,t()}}).finally(()=>{this.flushPromise===t&&(this.flushPromise=null)});this.flushPromise=t}static FLUSH_TIMEOUT_MS=5e3;async flushPendingAndWait(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.flushPromise&&await Promise.race([this.flushPromise,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())]),!this.pendingEvent)return;const t=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.warn("[ws] flushPendingAndWait: not connected, event will be dropped",{phase:t.payload.phase}),void(this.pendingEvent=t);const r=new Promise(e=>{try{ls.debug("[ws] flushPendingAndWait: sending event",{phase:t.payload.phase}),this.socket?.send(JSON.stringify(t),r=>{r&&(ls.warn("[ws] flushPendingAndWait: send failed",{error:r.message,phase:t.payload.phase}),this.pendingEvent||(this.pendingEvent=t)),e()})}catch(r){ls.warn("[ws] flushPendingAndWait: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=t,e()}});await Promise.race([r,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())])}close(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.flushPending();const{socket:e}=this;this.socket=void 0,e&&setTimeout(()=>{e.close()},200)}async closeAndWait(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client and waiting for pending send"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.flushPendingAndWait();const{socket:e}=this;this.socket=void 0,e&&(await new Promise(e=>setTimeout(e,200)),e.close())}},Us=(e,t)=>{const r=e.findIndex(e=>e.testFilePath===t.testFilePath);return-1===r?[...e,t]:e.map((e,n)=>n===r?t:e)},Ls=class e{socket;url;authProvider;orgId;sessionId;pendingEvent=null;reconnectAttempts=0;reconnectTimer;flushPromise=null;debounceTimer;_isClosed=!1;isAuthenticated=!1;authenticationFailed=!1;onUserMessage;maxReconnectAttempts=10;baseReconnectDelay=2e3;maxReconnectDelay=3e4;debounceMs=500;get isClosed(){return this._isClosed}constructor({authProvider:e,orgId:t,sessionId:r,url:n=wn,onUserMessage:s}){this.authProvider=e,this.orgId=t,this.sessionId=r,this.url=n,this.onUserMessage=s,ls.info("[ws] Constructing CreateProgressWebSocketClient",{url:this.url,sessionId:r})}async start(){await this.connect()}async connect(){if(!this._isClosed)try{const e=await this.authProvider.getAuthHeader();if(this._isClosed)return;const t={Authorization:e};this.orgId&&(t["x-stably-org-id"]=this.orgId);const r=`${this.url}?sessionId=${encodeURIComponent(this.sessionId)}`;ls.info("[ws] Connecting",{url:r,attempt:this.reconnectAttempts}),this.socket=new ve(r,{headers:t}),this.socket.on("open",()=>{ls.info("[ws] Connection opened"),this.reconnectAttempts=0}),this.socket.on("message",e=>{try{const t="string"==typeof e?e:e.toString(),r=JSON.parse(t);ls.debug("[ws] Received message",{type:r?.type}),"connected"===r?.type&&(ls.info("[ws] Authenticated successfully"),this.isAuthenticated=!0,this.authenticationFailed=!1,this.flushPending()),"user_message"===r?.type&&"string"==typeof r.content&&(ls.info("[ws] Received user message from web UI"),this.onUserMessage?.(r.content))}catch{}}),this.socket.on("close",(e,t)=>{ls.info("[ws] Connection closed",{code:e,authFailed:1008===e,reconnectAttempts:this.reconnectAttempts,maxReconnect:this.maxReconnectAttempts,isClosed:this._isClosed}),this.isAuthenticated=!1,1008===e&&(this.authenticationFailed=!0),!this._isClosed&&!this.authenticationFailed&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()}),this.socket.on("error",e=>{ls.warn("[ws] Connection error",{error:e.message})})}catch(e){ls.warn("[ws] Failed to create WebSocket",{error:e instanceof Error?e.message:String(e)}),this.scheduleReconnect()}}scheduleReconnect(){if(this._isClosed||this.reconnectTimer)return;this.reconnectAttempts++;const e=Math.min(this.baseReconnectDelay*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelay);ls.info("[ws] Scheduling reconnect",{attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts,delayMs:e}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.connect().catch(e=>{ls.warn("[ws] Reconnect failed",{error:e instanceof Error?e.message:String(e)})})},e)}isConnected(){return!!this.socket&&this.socket.readyState===ve.OPEN&&this.isAuthenticated}sendProgress(e){if(this._isClosed)return void ls.debug("[ws] sendProgress called but client is closed",{phase:e.phase});const t={type:"create_progress",payload:e};return this.pendingEvent=t,this.isConnected()?"complete"===e.phase?(ls.info("[ws] sendProgress: flushing terminal state immediately"),void this.flushPending()):void(this.debounceTimer||(this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.flushPending()},this.debounceMs))):(ls.debug("[ws] sendProgress: not connected, queuing event",{phase:e.phase,socketState:this.socket?.readyState,isAuthenticated:this.isAuthenticated,reconnectAttempts:this.reconnectAttempts}),void(this.socket?.readyState===ve.CLOSED&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()))}flushPending(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),!this.pendingEvent)return;const e=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.debug("[ws] flushPending: not connected, re-queuing event",{phase:e.payload.phase}),void(this.pendingEvent=e);ls.debug("[ws] flushPending: sending event",{phase:e.payload.phase});const t=new Promise(t=>{try{this.socket?.send(JSON.stringify(e),r=>{r&&(ls.warn("[ws] flushPending: send failed",{error:r.message,phase:e.payload.phase}),this.pendingEvent||(this.pendingEvent=e)),t()})}catch(r){ls.warn("[ws] flushPending: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=e,t()}}).finally(()=>{this.flushPromise===t&&(this.flushPromise=null)});this.flushPromise=t}static FLUSH_TIMEOUT_MS=5e3;async flushPendingAndWait(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.flushPromise&&await Promise.race([this.flushPromise,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())]),!this.pendingEvent)return;const t=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.warn("[ws] flushPendingAndWait: not connected, event will be dropped",{phase:t.payload.phase}),void(this.pendingEvent=t);const r=new Promise(e=>{try{ls.debug("[ws] flushPendingAndWait: sending event",{phase:t.payload.phase}),this.socket?.send(JSON.stringify(t),r=>{r&&(ls.warn("[ws] flushPendingAndWait: send failed",{error:r.message,phase:t.payload.phase}),this.pendingEvent||(this.pendingEvent=t)),e()})}catch(r){ls.warn("[ws] flushPendingAndWait: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=t,e()}});await Promise.race([r,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())])}close(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.flushPending();const{socket:e}=this;this.socket=void 0,e&&setTimeout(()=>{e.close()},200)}async closeAndWait(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client and waiting for pending send"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.flushPendingAndWait();const{socket:e}=this;this.socket=void 0,e&&(await new Promise(e=>setTimeout(e,200)),e.close())}},$s=we.object({bucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string()}),Ds=we.object({uploadUrl:we.string(),key:we.string(),bucketPath:we.object({bucket:we.string(),key:we.string()}),expiresInSeconds:we.number()}),Ns=we.object({success:we.boolean()});async function Os({authHeader:e,orgId:t,sessionId:r,projectId:n,history:s}){if(0===s.length)return ls.debug("[session-history] No history to upload"),{success:!0};try{(async()=>{const o=await(i={auth:e,body:{history:s,...n?{projectId:n}:{}},client:In(),headers:_s(t),path:{sessionId:r},signal:AbortSignal.timeout(3e4)},(i.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/history/hot-store",...i,headers:{"Content-Type":"application/json",...i.headers}}));var i;if(o.error)throw new Error(`Hot store mirror failed (${o.response.status})`);Ns.parse(o.data)})().catch(e=>{ls.warn("[session-history] Failed to mirror history to hot store",{error:e instanceof Error?e.message:String(e)})}),ls.info("[session-history] Requesting upload URL",{sessionId:r,messageCount:s.length});const{uploadUrl:o,key:i}=await async function({authHeader:e,orgId:t,sessionId:r,projectId:n}){const s=await(o={auth:e,body:{contentType:"application/x-ndjson",...n?{projectId:n}:{}},client:In(),headers:_s(t),path:{sessionId:r},signal:AbortSignal.timeout(3e4)},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/history/upload-url",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to get history upload URL (${s.response.status})`);return Ds.parse(s.data)}({authHeader:e,orgId:t,sessionId:r,projectId:n}),a=s.map(e=>JSON.stringify(e)).join("\n");ls.info("[session-history] Uploading history",{key:i,messageCount:s.length,sizeBytes:a.length});const c=await fetch(o,{method:"PUT",body:a,headers:{"Content-Type":"application/x-ndjson"},signal:AbortSignal.timeout(6e4)});if(!c.ok)throw new Error(`Upload failed with status ${c.status}`);return ls.info("[session-history] History uploaded successfully",{key:i}),{success:!0,key:i}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.warn("[session-history] Failed to upload history",{error:t}),{success:!1,error:t}}}var Bs="1.58.0",js=["auth login","auth logout","auth setup-git","auth switch","config set","secret set","secret delete","variable set","variable delete","repo delete","repo edit","repo rename","repo archive"];function Ms(e){return/^\.env(\..*)?$/.test(e)||".stably-agent.env"===e}function Fs(e){return Boolean(e&&"object"==typeof e&&"tool_input"in e&&e.tool_input&&"object"==typeof e.tool_input)}function Hs({action:e,pathKey:t}){return function({action:e,fileCheck:t,getBlockMessage:r,pathKey:n}){return async s=>{const o=function({input:e,pathKey:t}){if(!Fs(e))return{decision:"block",reason:`Invalid tool call format: Expected an object with 'tool_input' property. Please ensure the tool call follows the correct structure: { tool_input: { ${t}: "path/to/file" } }`,success:!1,systemMessage:"Tool call blocked due to invalid input format"};const r=e.tool_input;return t in r?"string"==typeof r[t]?{path:r[t],success:!0}:{decision:"block",reason:`Invalid tool call format: The '${t}' parameter must be a string containing the file path, but received ${typeof r[t]}. Please provide a valid file path as a string. Example: { tool_input: { ${t}: "src/example.ts" } }`,success:!1,systemMessage:"Tool call blocked due to invalid parameter type"}:{decision:"block",reason:`Invalid tool call format: Missing required parameter '${t}'. Please provide the file path using the '${t}' parameter. Example: { tool_input: { ${t}: "path/to/file" } }`,success:!1,systemMessage:"Tool call blocked due to missing required parameters"}}({input:s,pathKey:n});if(!o.success)return o;const i=o.path.replace(/\\/g,"/"),a=i.split("/").pop()||i;return t(a)?{decision:"block",reason:r("reading"===e?"Access to":"writing"===e?"Writing to":"editing"===e?"Editing":"Searching in"),systemMessage:"AI blocked due to accessing sensitive content"}:{decision:"approve"}}}({action:e,fileCheck:Ms,getBlockMessage:e=>`${e} .env files is not allowed. Environment variables and secrets should be managed in Stably's Test Data section instead. You can access these values using process.env in your test code.`,pathKey:t})}var Gs=["rm","mv","git","gh","npx","stably","stably-browser","pwtrace","npm","yarn","pnpm","bun"],Ws=["stably","playwright","stably-browser","pwtrace"],Vs=["create","fix","verify"],Ys=["upload"],zs=["push","fetch","pull","clone","ls-remote"],qs=/\S+=(?:\"[^\"\\]*(?:\\.[^\"\\]*)*\"|'[^']*(?:'\\''[^']*)*'|\S+)/;function Ks(e){let t="",r=!1,n=!1,s=!1;for(let o=0;o<e.length;o++){const i=e[o];s?(t+=i,s=!1):"\\"!==i||n?'"'!==i||n?"'"!==i||r?t+=i:n=!n:r=!r:s=!0}return t}function Js(e){const t=[],r=e.trim(),n=/(?:[^\s"']+|"[^"\\]*(?:\\.[^"\\]*)*"|'[^']*(?:'\\''[^']*)*')+/g;let s;for(;null!==(s=n.exec(r));)t.push(s[0]);return t}function Xs(e){let t=0;const r=new RegExp(`^${qs.source}$`);for(;t<e.length&&r.test(e[t]??"");)t+=1;return e.slice(t)}function Qs(e){const t=Xs(Js(e));if("npx"===t[0])for(let e=1;e<t.length;e+=1){const r=t[e];if(r){if("--"===r)return t[e+1];if(!r.startsWith("-"))return Ks(r)}}}function Zs(e){return Js(e).map(Ks).find(e=>Vs.includes(e))}function eo(e,t){const r=c(e).replace(/\\/g,"/"),n=t.replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(r.startsWith(s))return!0;const o=r.lastIndexOf(`/${s}`);if(-1===o)return!1;const i=r.slice(o+`/${s}`.length);return i.length>0&&!i.startsWith("../")}function to({onBeforeGitHubCommand:e,workspaceBoundary:t,allowBackgroundRunTest:r=!1}){return async n=>{if(!Fs(n))return{decision:"block",reason:"Invalid tool call format: Expected an object with tool_input property.",systemMessage:"Tool call blocked due to invalid input format"};const i=n.tool_input,{command:c}=i;if("string"!=typeof c)return{decision:"block",reason:"Invalid Bash command: command must be a string.",systemMessage:"Tool call blocked due to invalid command type"};const l=function(e){const t=e.trim(),r=new RegExp(`^(?:${qs.source}\\s+)*(\\S+)`),n=t.match(r);return n?.[1]}(c);if(!l)return{decision:"block",reason:"Invalid Bash command: could not parse command.",systemMessage:"Tool call blocked due to unparseable command"};if(!r&&"run_in_background"in i&&!0===i.run_in_background&&/\bstably-browser\s+(?:(?:-\w+=?\S*|--\w+=?\S*|-s\s+\S+|--session\s+\S+)\s+)*run-test\b/.test(c))return{decision:"block",reason:"Running `stably-browser run-test` with `run_in_background: true` is not allowed. Test runs must execute in the foreground so their output can be captured and parsed. Remove the `run_in_background` parameter and run the test normally.",systemMessage:"Tool call blocked due to run-test in background"};if(!function(e){return"string"==typeof e&&Gs.includes(e)}(l))return{decision:"block",reason:`The command "${l}" is not allowed. Only the following commands are permitted: ${Gs.join(", ")}. Use the appropriate tools (Read, Write, Edit, Glob, Grep) for file operations instead.`,systemMessage:"Tool call blocked due to disallowed command"};if("npx"===l){const e=function(e){if(/(\s|^)npx\s+.*(\s|^)(-c|--call)(\s|=)/.test(e.trim()))return{valid:!1,reason:"The npx -c/--call form is not allowed. Use direct commands like `npx stably test ...`."};const t=Qs(e);if(!t)return{valid:!1,reason:"Invalid npx command: unable to determine which binary is being executed."};if(!new Set(Ws).has(t))return{valid:!1,reason:`The npx binary "${t}" is not allowed. Only ${Ws.join(", ")} are permitted.`};if("stably"===t){const r=Zs(e);if(r)return{valid:!1,reason:`The npx ${t} subcommand "${r}" is not allowed. The commands ${Vs.join(", ")} are AI-powered and blocked to prevent recursion.`}}return{valid:!0}}(c);if(!e.valid)return{decision:"block",reason:e.reason,systemMessage:"Tool call blocked due to disallowed npx command"}}if("stably-browser"===l||"npx"===l&&"stably-browser"===Qs(c)){const e=function({command:e,binary:t}){const r=Xs(Js(e)),n=r.findIndex(e=>e===t);if(-1!==n)for(let e=n+1;e<r.length;e+=1){const t=r[e];if(t&&!t.startsWith("-"))return Ks(t)}}({command:c,binary:"stably-browser"});if(e&&Ys.includes(e))return{decision:"block",reason:`The stably-browser subcommand "${e}" is not allowed. The "upload" command can read arbitrary files and is blocked for security.`,systemMessage:"Tool call blocked due to disallowed stably-browser subcommand"}}if("stably"===l){const e=Zs(c);if(e)return{decision:"block",reason:`The stably subcommand "${e}" is not allowed. The commands ${Vs.join(", ")} are AI-powered and blocked to prevent recursion.`,systemMessage:"Tool call blocked due to disallowed stably command"}}if("rm"===l){const e=function(e){const t=e.trim().match(/^rm\s+(?:-[a-zA-Z]+\s+|--[a-zA-Z-]+\s+)*(.+)$/),r=t?.[1]?.trim();return r?r.split(/\s+/).filter(e=>e.length>0):[]}(c);if(0===e.length)return{decision:"block",reason:"Invalid rm command: could not determine the file path(s) to remove.",systemMessage:"Tool call blocked due to invalid rm command"};if(t){const r=e.filter(e=>!function({targetPath:e,boundaryDir:t}){const r=function(e){if(E(e))return k.native(e);let t=e;const r=[];for(;!E(t);){const n=o(t);if(n===t)return s(e);r.unshift(t.slice(n.length+1)),t=n}const n=k.native(t);return r.length>0?s(n,...r):n}(e),n=k.native(t),i=r.endsWith(a)?r:r+a,c=n.endsWith(a)?n:n+a;return i.startsWith(c)||r===n}({targetPath:s(t,e),boundaryDir:t}));if(r.length>0)return{decision:"block",reason:`The rm command can only remove files within the workspace. The following path(s) are outside the workspace boundary: ${r.join(", ")}.`,systemMessage:"Tool call blocked due to rm outside workspace"}}else{const t=e.filter(e=>!(eo(e,"tests")||eo(e,".stably")));if(t.length>0)return{decision:"block",reason:`The rm command can only remove files in the tests/ directory or .stably/ directory. The following path(s) are not allowed: ${t.join(", ")}.`,systemMessage:"Tool call blocked due to rm outside allowed directories"}}}if("git"===l&&["-c","--config","--config-env"].some(e=>c.includes(` ${e} `)||c.includes(` ${e}=`)))return{decision:"block",reason:"Git config flags (-c, --config, --config-env) are not allowed for security reasons.",systemMessage:"Tool call blocked due to git config injection attempt"};if("git"===l&&function(e){const t=e.trim();return!!t.startsWith("git ")&&zs.some(e=>t.includes(` ${e}`)||t.includes(`git ${e}`))}(c)&&e)try{await e()}catch(e){console.error("[BashSecurityHook] Failed to refresh git token:",e)}if("gh"===l){const t=function(e){const t=e.toLowerCase();return js.some(e=>t.includes(`gh ${e}`))?{allowed:!1,reason:"This gh subcommand is not allowed for security reasons. Only read operations and PR/issue management are permitted. Blocked subcommands include: auth, config set, secret/variable management, and destructive repo operations.",systemMessage:"Tool call blocked due to dangerous gh subcommand"}:t.includes("gh api")&&(/--method\s+(delete|put|patch)/i.test(e)||/-X\s+(DELETE|PUT|PATCH)/i.test(e))?{allowed:!1,reason:"The gh api command with destructive HTTP methods (DELETE, PUT, PATCH) is not allowed for security reasons. Only GET requests are permitted for raw API access.",systemMessage:"Tool call blocked due to destructive gh api method"}:{allowed:!0}}(c);if(!t.allowed)return{decision:"block",reason:t.reason,systemMessage:t.systemMessage};if(e)try{await e()}catch(e){console.error("[BashSecurityHook] Failed to refresh GitHub token for gh command:",e)}}return{decision:"approve"}}}var ro=/\.(spec|test)\.(ts|tsx|js|jsx|mts|mjs)$/;function no({onFileCreated:e}){return async t=>{const r=(e=>{if(!e||"object"!=typeof e)return;const t=e;return t.tool_input&&"object"==typeof t.tool_input&&!Array.isArray(t.tool_input)?t.tool_input:void 0})(t),n=r?.file_path;return"string"==typeof n&&ro.test(n)&&e(n),{decision:"approve"}}}var so=M(f);async function oo(){try{const{stdout:e}=await so('pgrep -f "playwright run-test-mcp-server" 2>/dev/null || true'),t=e.trim();if(!t)return;const r=t.split("\n").filter(Boolean);await Promise.allSettled(r.map(async e=>{await so(`pkill -KILL -P ${e} '.*' 2>/dev/null || true`)}))}catch{}}var io=class{queue=[];pendingResolve=void 0;done=!1;canSend=!0;[Symbol.asyncIterator](){return this}pushText(e){const t=e.trim();t&&!this.done&&(this.queue.push(t),this.maybeFlush())}allowNextTurn(){this.done||(this.canSend=!0,this.maybeFlush())}hasQueuedMessages(){return this.queue.length>0}drainQueue(){return this.queue.splice(0)}finish(){this.done=!0,this.pendingResolve&&(this.pendingResolve({done:!0,value:void 0}),this.pendingResolve=void 0)}maybeFlush(){if(!this.pendingResolve)return;if(!this.canSend)return;const e=this.queue.shift();if(void 0===e)return;const t={message:{content:[{text:e,type:"text"}],role:"user"},parent_tool_use_id:null,type:"user",session_id:""};this.canSend=!1,this.pendingResolve({done:!1,value:t}),this.pendingResolve=void 0}next(){return this.done?Promise.resolve({done:!0,value:void 0}):new Promise(e=>{this.pendingResolve=e,this.maybeFlush()})}};function ao(e){try{const t=h("git branch --show-current",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!t)return;return{branch:t}}catch{return}}var co=[".ts",".js",".mts",".mjs",".cts",".cjs"],lo=10240,uo=async({defaultContent:e,fileName:t,filePath:r})=>{try{const e=(await Z(r)).size,n=await z(r,"utf-8"),s=Buffer.byteLength(n,"utf-8");if(s<=lo)return n;const o=(e=>{const t=e.split("\n"),r=[];let n=!1,s=!1,o=0,i=!1;for(let e=0;e<t.length;e++){const a=t[e],c=a.trim();c.startsWith("/*")&&(n=!0),c.includes("*/")?n=!1:n||c.startsWith("//")&&!c.startsWith("///")||(c.startsWith("import ")||c.startsWith("export ")?(r.push(a),i=!0):i&&""===c?(r.push(a),i=!1):(i=!1,c.startsWith("type ")||c.startsWith("interface ")?r.push(a):c.startsWith("function ")||c.startsWith("const ")||c.startsWith("async function ")||c.startsWith("export function ")||c.startsWith("export const ")||c.startsWith("test.describe(")||c.startsWith("test(")?(r.push(a),s=!0,o=(a.match(/{/g)||[]).length-(a.match(/}/g)||[]).length,0===o&&(c.endsWith(";")||c.endsWith(","))&&(s=!1)):s?(o+=(a.match(/{/g)||[]).length,o-=(a.match(/}/g)||[]).length,0===o&&c.includes("}")?(r.push(a),s=!1):o>0&&" // ... implementation omitted ..."!==r.at(-1)&&r.push(" // ... implementation omitted ...")):c.match(/^[a-zA-Z_]+:/)&&r.push(a)))}return r.join("\n")})(n),i=Buffer.byteLength(o,"utf-8");return i<=lo?o:o.slice(0,lo)+`\n\n... [TRUNCATED: File "${t}" at ${r} was ${e} bytes (${s} bytes as UTF-8), reduced to ~${i} bytes of essential content, then truncated to 10240 bytes] ...`}catch(r){let n;if(r&&"object"==typeof r&&"code"in r){const e=r.code;"string"==typeof e&&(n=e)}return"ENOENT"!==n&&console.warn(`Failed to read ${t}: ${r}`),e}},po=async({defaultContent:e,dirName:t,dirPath:r})=>{try{const e=await Q(r);return e.length>0?e.join("\n"):"(empty)"}catch(r){let n;if(r&&"object"==typeof r&&"code"in r){const e=r.code;"string"==typeof e&&(n=e)}return"ENOENT"!==n&&console.warn(`Failed to read ${t}: ${r}`),e}};async function fo(e){let t=e;for(;;){try{const e=await z(n.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return"object"==typeof r&&"module"===r?.type}catch{}const e=n.dirname(t);if(e===t)return!1;t=e}}var ho=async({allowedEnvVars:e,mode:t,workspaceInfo:r,authHeader:n,customHeader:s,maxParallelWorkers:o,isCloudBrowser:i})=>{const a=In(),c=ao(r.absolutePath);ls.debug("Requesting system prompt from API",{mode:t,hasGitContext:!!c,envVarCount:e.length});const l=await(u={client:a,auth:n,body:{mode:t,workspaceInfo:r,allowedEnvVars:e,gitContext:c,maxParallelWorkers:o,isCloudBrowser:i}},(u.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/prompts/system",...u,headers:{"Content-Type":"application/json",...u.headers}}));var u;if(401===l.response.status)throw ls.warn("System prompt fetch failed: unauthorized (401)"),await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");if(403===l.response.status)throw ls.debug("System prompt fetch failed: forbidden (403)"),new Error("Your organization does not have an active subscription. Manage your subscription at https://app.stably.ai or contact your organization admin.");if(l.error){ls.warn("System prompt fetch failed",{error:l.error});const e=JSON.stringify(l.error);if(e.toLowerCase().includes("unauthorized")||e.toLowerCase().includes("unauthenticated"))throw await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");throw new Error("Failed to fetch system prompt. Please check your network connection and try again. If this persists, run `stably login` to re-authenticate.")}const d=function({customHeader:e,systemPrompt:t}){return e?`${t}\n\nWhen writing or updating the generated test file, prepend this exact header at the top of the file without modification:\n\`\`\`ts\n${e}\n\`\`\``:t}({systemPrompt:l.data.systemPrompt,customHeader:s});return ls.debug("System prompt received",{size:d.length,appendedCustomHeader:!!s,hasPrContext:!!l.data.prContext}),{systemPrompt:d,prContext:l.data.prContext}},go={chat:"chat",single:"create",fix:"fix",init:"init",verify:"verify",plan:"plan"};async function mo({agentMode:e,authHeader:t,orgId:r,projectId:n,runId:s,fetchImpl:o=fetch,apiUrl:i=fn}){const a=go[e],c=new URL("/internal/v1/cli/progress",i).toString(),l={Authorization:t,"Content-Type":"application/json","X-STABLY-CLI-VERSION":pn};r&&(l["x-stably-org-id"]=r);const u=await o(c,{method:"POST",headers:l,body:JSON.stringify({mode:a,projectId:n,agentId:oe.randomUUID(),..."fix"===a&&s?{playwrightSuiteRunId:s}:{}}),signal:AbortSignal.timeout(1e4)});if(!u.ok){const e=await u.text().catch(()=>"");throw new Error(`Failed to create progress session: ${u.status} ${c} β ${e.slice(0,300)}`)}const{sessionId:d}=await u.json();return{sessionId:d,sessionMode:a}}var yo=".stably-internal.playwright",bo=`${yo}-wrapper.config.*`,wo="STABLY_INTERNAL_EXECUTION",vo=[".ts",".js",".mts",".mjs",".cts",".cjs"];function Io(e){const t=s(e);if(E(t))for(const e of vo){const r=i(t,`playwright.config${e}`);if(E(r))return r}}var To=["tests","e2e","__tests__","test"];function _o(e){try{return E(e)&&S(e).isDirectory()}catch{return!1}}function Eo(e,t){const r="output-flag"===t?"--output flag":"playwright.config.ts"===t?"playwright.config.ts":"auto-detected"===t?"auto-detected":"cwd fallback";console.error(ne.dim(`Using output directory: ${e} (from ${r})`))}var So=["mcp__playwright-test__","mcp__auto-heal-report__","mcp__stably-agent-control__"],xo=["planner_","generator_"],Ao={open:e=>e?`Open ${e}`:"Open browser",close:()=>"Close browser",snapshot:()=>"Page snapshot",screenshot:()=>"Screenshot",click:e=>`Click ${e}`,fill:e=>`Fill ${e.split(/\s+/)[0]||""}`.trim(),type:e=>`Type into ${e.split(/\s+/)[0]||""}`.trim(),hover:e=>`Hover ${e}`,goto:e=>`Navigate to ${e}`,select:e=>`Select option in ${e.split(/\s+/)[0]||""}`.trim(),check:e=>`Check ${e}`,uncheck:e=>`Uncheck ${e}`,back:()=>"Go back",forward:()=>"Go forward","run-test":e=>`Run test ${e}`,"run-code":()=>"Run code","run-file":e=>`Run file ${e}`,"tab-list":()=>"List tabs","tab-new":e=>e?`New tab ${e}`:"New tab","tab-select":e=>`Select tab ${e}`,"tab-close":()=>"Close tab",eval:()=>"Evaluate JavaScript",upload:()=>"Upload file","state-save":()=>"Save browser state","state-load":()=>"Load browser state"},ko={"stably-browser":"Loading browser command reference","stably-cli":"Loading CLI reference","browser-interaction-guide":"Loading browser interaction guide","playwright-config-auth":"Loading project configuration","playwright-cli":"Loading browser command reference","bash-commands":"Loading command reference","stably-sdk-reference":"Loading SDK reference","test-creation-workflow":"Loading test creation guide","bulk-test-handling":"Loading bulk test guide","debugging-test-failures":"Loading debugging guide","recorded-actions-handling":"Loading recorded actions guide","playwright-best-practices":"Loading best practices","pwtrace-debugging":"Loading trace debugging guide","ai-to-programmatic-migration":"Loading migration guide"},Po={Skill:"Preparing for task",ToolSearch:"Searching tools"},Co=(e,t)=>{const r=t.find(t=>e.startsWith(t));return r?e.slice(r.length):e},Ro=e=>e.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" "),Uo=(e,t)=>{if(!t||"object"!=typeof t)return;const r=t,n="string"==typeof r.intent?r.intent:void 0;if("Read"!==e&&"Write"!==e&&"Edit"!==e){if("Glob"===e||"Grep"===e)return"string"==typeof r.pattern?r.pattern:void 0;if("mcp__playwright-test__test_run"!==e&&"test_run"!==e){if("mcp__playwright-test__test_debug"===e||"test_debug"===e){const e=r.test;return"string"==typeof e?.title?e.title:void 0}return"mcp__playwright-test__generator_setup_page"===e||"generator_setup_page"===e?"string"==typeof r.seedFile?r.seedFile:"tests/seed.spec.ts":"mcp__playwright-test__generator_write_test"===e||"generator_write_test"===e?"string"==typeof r.fileName?r.fileName:void 0:"Bash"===e?"string"==typeof r.command?r.command.length>50?`${r.command.slice(0,50)}...`:r.command:void 0:e.includes("browser_navigate")&&!e.includes("back")?"string"==typeof r.url?r.url:n:e.includes("browser_type")?("string"==typeof r.text?`"${r.text}"`:void 0)??n:e.includes("browser_click")?"string"==typeof r.element?r.element:n:e.includes("browser_wait_for")?"string"==typeof r.text?`text: "${r.text}"`:"number"==typeof r.time?`${r.time}ms`:n:e.includes("verify_text")?"string"==typeof r.text?`"${r.text}"`:n:e.includes("verify_element")?"string"==typeof r.accessibleName?r.accessibleName:n:e.includes("screenshot")&&"string"==typeof r.filename?r.filename:n}if(Array.isArray(r.locations)){const e=r.locations.filter(e=>"string"==typeof e);return e.length>0?e.join(", "):void 0}}else if("string"==typeof r.file_path)return r.file_path.split("/").at(-1)??void 0},Lo=(e,t)=>{if(!t||"object"!=typeof t)return null;const r=t;if("Skill"===e){const e="string"==typeof r.skill?r.skill:void 0;if(e){const t=e.includes(":")?e.split(":").pop():e;return ko[t]?ko[t]:`Loading ${t.replace(/-/g," ")}`}return"Preparing for task"}if("Bash"===e&&"string"==typeof r.description&&r.description.trim())return r.description.trim();if("Bash"===e&&"string"==typeof r.command){const e=r.command.match(/(?:^|\s)(?:[\w/.-]*\/)?stably-browser\s+(?:--\S+\s+)*(\S+)(.*)/);if(!e)return null;const[,t,n]=e,s=n.trim().replace(/--\S+=?\S*\s*/g,"").trim(),o=Ao[t];return o?o(s):`${Ro(t)}${s?` ${s.split(/\s+/)[0]}`:""}`.trim()}return"Read"===e&&"string"==typeof r.file_path&&(r.file_path.includes(".stably-browser/")||r.file_path.includes(".playwright-cli/"))&&r.file_path.endsWith(".yml")?"Page snapshot":"TaskOutput"===e?!0===r.block?"Waiting for background task":"Checking background task":null},$o=e=>"mcp__upload-trace-proof__upload-trace-proof"===e||"mcp__auto-heal-report__upload-trace-proof"===e?"Upload Trace":"mcp__auto-heal-report__generate-report"===e?"Generate Report":(e=>{const t=Po[e];if(t)return t;const r=Co(e,So),n=Co(r,xo);return Ro(n)})(e),Do=(e,t)=>{if(t<=0)return 0;let r=t-1;for(;r>0&&/\s/.test(e[r]);)r--;for(;r>0&&!/\s/.test(e[r-1]);)r--;return r},No=(e,t)=>{if(t>=e.length)return e.length;let r=t;for(;r<e.length&&!/\s/.test(e[r]);)r++;for(;r<e.length&&/\s/.test(e[r]);)r++;return r},Oo=(e,t)=>{if(t<=0)return 0;const r=e.lastIndexOf("\n",t-1);return-1===r?0:r+1},Bo=(e,t)=>{const r=e.indexOf("\n",t);return-1===r?e.length:r};function jo(e){const t=e.split("\n");let r=!1;const n=[];for(const e of t){const t=e.trimStart();if(/^`{3,}[^`]*$/.test(t)){r=!r,n.push(Dr("muted",` ${"β".repeat(Math.max(0,Math.min((process.stdout.columns||80)-4,76)))}`));continue}if(r){n.push(`${Dr("muted"," β")} ${Dr("codeBlock",e)}`);continue}if(/^-{3,}\s*$/.test(t)){n.push(Dr("subtle","β".repeat(Math.min(process.stdout.columns||80,80))));continue}const s=e.match(/^(#{1,6})\s+(.+)$/);if(s){const e=s[1].length,t=Mo(s[2]);1===e?n.push(ne.bold(Dr("brand",t))):2===e?n.push(ne.bold(t)):n.push(ne.bold(Dr("subtle",t)));continue}const o=e.match(/^>\s*(.*)$/);if(o){n.push(Dr("subtle",`β ${Mo(o[1])}`));continue}const i=e.match(/^(\s*)[-*]\s+(.+)$/);if(i){const e=i[1]||"";n.push(`${e} β ${Mo(i[2])}`);continue}const a=e.match(/^(\s*)(\d+)\.\s+(.+)$/);if(a){const e=a[1]||"";n.push(`${e} ${a[2]}. ${Mo(a[3])}`);continue}n.push(Mo(e))}return n.join("\n")}function Mo(e){return(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,(e,t)=>ne.bold(t))).replace(/__(.+?)__/g,(e,t)=>ne.bold(t))).replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g,(e,t)=>ne.italic(t))).replace(/`([^`]+)`/g,(e,t)=>Dr("inlineCode",t))}var Fo,Ho=async(e,t)=>{const{Box:r,Static:n,Text:s,render:o,useInput:i}=await import("ink"),a=!!process.stdin.isTTY,c="vscode"!==process.env.TERM_PROGRAM,l=["β ","β ","β Ή","β Έ","β Ό","β ΄","β ¦","β §","β ","β "],u=()=>xe(s,{inverse:!0,children:" "}),d=(({Box:e,Text:t,useInput:r},n,s)=>function({onChoice:o,prompt:i}){const[a,c]=Ie(0),[l,u]=Ie(!1),[d,p]=Ie(""),f=[{label:"Yes, allow this once",value:"allow"},{label:"Yes, always allow for this session",value:"always"},{label:"No, tell AI what to do differently",value:"deny_with_message"}];r((e,t)=>{if(l)return t.return?void o("deny_with_message",d||"User denied this action"):t.escape?(u(!1),void p("")):t.backspace||t.delete?void p(e=>e.slice(0,-1)):void(t.ctrl||t.meta||p(t=>`${t}${e}`));if(t.upArrow)return void c(e=>e>0?e-1:f.length-1);if(t.downArrow)return void c(e=>e<f.length-1?e+1:0);if(t.return){const e=f[a];return"deny_with_message"===e.value?void u(!0):void o(e.value)}const r=parseInt(e,10);if(r>=1&&r<=f.length){const e=f[r-1];if("deny_with_message"===e.value)return void u(!0);o(e.value)}},{isActive:s});const h=$o(i.toolName),g=Uo(i.toolName,i.input);return Ae(e,{borderColor:$r("accent"),borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,paddingY:0,children:[xe(t,{bold:!0,color:$r("accent"),children:"Permission Required"}),Ae(e,{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),children:h}),null!=g&&Ae(t,{color:$r("muted"),children:[" ",g]})]}),null!=i.decisionReason&&xe(e,{marginTop:1,children:Ae(t,{color:$r("muted"),children:["Reason: ",i.decisionReason]})}),Ae(e,l?{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),children:"Enter message for AI (press Enter to submit, Esc to cancel):"}),Ae(t,{children:[xe(t,{color:$r("accent"),children:"β―"})," ",d,xe(n,{})]})]}:{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),children:"Use ββ arrows or number keys to select:"}),f.map((e,r)=>xe(t,{children:Ae(t,{color:r===a?$r("accent"):void 0,children:[r===a?"β―":" "," ",r+1,". ",e.label]})},e.value))]})]})})({Box:r,Text:s,useInput:i},u,a),p=(({Cursor:e,inkComponents:{Box:t,Static:r,Text:n,useInput:s},isRawModeSupported:o,PermissionPrompt:i,Spinner:a})=>{const c="vscode"!==process.env.TERM_PROGRAM,l=e=>"tool"===e.kind?Ae(n,{color:$r("subtle"),children:["β¦ ",e.content]},e.id):"tool_result"===e.kind||"text"===e.kind?xe(n,{color:$r("muted"),children:e.content},e.id):null,u=({progress:e})=>{const[r,s]=Ie(Date.now());_e(()=>{if(!c)return;const e=setInterval(()=>s(Date.now()),1e3);return()=>clearInterval(e)},[]);const o=r-e.startedAt,i=Math.floor(o/1e3),a=Math.floor(i/60),l=i%60,u=a>0?`${a}m ${l.toString().padStart(2,"0")}s`:`${l}s`,d={initializing:{label:"Fetching test results",color:$r("muted")},triage:{label:"Triaging failures",color:$r("fixTriage")},fixing:{label:"Fixing tests",color:$r("brand")},debugging:{label:"Debugging tests",color:$r("fixDebug")},validation:{label:"Validating fixes",color:$r("fixValidation")},complete:{label:"Complete",color:$r("success")}},{label:p,color:f}=d[e.phase],h=e.fixedTests+e.failedTests,g=("fixing"===e.phase||"debugging"===e.phase)&&h>0?null!==e.totalTests?` (fixed ${e.fixedTests}/${e.totalTests}${e.failedTests>0?`, failed ${e.failedTests}`:""})`:` (fixed ${e.fixedTests}${e.failedTests>0?`, failed ${e.failedTests}`:""})`:"";return xe(t,{flexDirection:"column",children:Ae(n,{children:[xe(n,{color:f,bold:!0,children:p}),xe(n,{color:$r("muted"),children:g}),Ae(n,{color:$r("muted"),children:[" [",u,"]"]})]})})},d=({progress:e})=>{const r=e.endedAt??Date.now(),s=Math.floor((r-e.startedAt)/1e3),o=Math.floor(s/60),i=s%60,a=o>0?`${o}m ${i.toString().padStart(2,"0")}s`:`${i}s`,c=e.isError?$r("accent"):$r("success"),l=e.isError?"Fix stopped":"Fix complete";return Ae(t,{flexDirection:"column",children:[Ae(n,{color:c,bold:!0,children:[l," in ",a]}),null!==e.totalTests&&Ae(n,{color:$r("muted"),children:[e.fixedTests,"/",e.totalTests," tests fixed",e.failedTests>0?`, ${e.failedTests} failed`:""]})]})},p=(e,r=!1,s)=>{if("subagent"===e.kind&&e.subagent){const{subagent:s}=e,o="complete"===s.status?$r("success"):"error"===s.status?$r("error"):$r("accent");return Ae(t,{flexDirection:"column",marginTop:1,children:[Ae(n,{children:[xe(n,{color:o,bold:!0,children:"Agent"}),s.description?Ae(n,{color:$r("muted"),children:[" (",s.description,")"]}):null]}),s.activities.length>0&&xe(t,{flexDirection:"column",marginLeft:2,children:(()=>{if(!r)return s.activities.map(e=>l(e));let e=0;const t=[];for(let r=s.activities.length-1;r>=0;r--){const n=s.activities[r];"tool"!==n.kind&&"tool_result"!==n.kind||("tool"===n.kind&&e++,e<=f&&t.unshift(n))}return t.map(e=>l(e))})()})]},e.id)}if("tool"===e.kind)return Ae(n,{color:$r("subtle"),children:["β¦ ",e.content]},e.id);if("tool_result"===e.kind)return xe(n,{color:$r("muted"),children:e.content},e.id);if("user"===e.kind)return xe(t,{marginTop:1,children:Ae(n,{color:$r("userPrompt"),children:["You: ",e.content]})},e.id);const o="text"===e.kind&&("tool"===s||"tool_result"===s);if("thinking"===e.kind){const r=e.content.split("\n"),s=10,o=r.length>s?r.slice(-s):r;return xe(t,{flexDirection:"column",children:xe(n,{color:$r("subtle"),children:o.join("\n")})},e.id)}return"cancelled"===e.kind?xe(n,{color:$r("subtle"),children:e.content},e.id):"text"===e.kind?xe(t,{marginTop:o?1:0,children:xe(n,{children:jo(e.content)})},e.id):xe(t,{children:xe(n,{children:e.content})},e.id)},f=3;return function({onCancel:c,onExit:l,onPermissionChoice:h,onSend:g,showSpinnerImmediately:m,state:y}){const[b,w]=Ie({value:"",cursor:0}),v=b.value,I=b.cursor,T=Te(!1),_=Te(void 0),[E,S]=Ie(!1),[x,A]=Ie(!1),k=Te(0),P=Te(!1),C=!!y.permissionPrompt,R=(({termProgram:e})=>"vscode"===e)({termProgram:process.env.TERM_PROGRAM}),U=y.log.at(-1),L=("text"===U?.kind||"thinking"===U?.kind)&&"running"===y.status,$=y.log.findIndex(e=>"subagent"===e.kind&&"running"===e.subagent?.status),D=-1!==$,N=y.activeThinkingLogIndex??-1,O=N>=0&&N<y.log.length-1,B=o&&!x,j=R?0:D?$:O?N:L?y.log.length-1:y.log.length,M=y.preserveLiveLog?k.current:B&&"running"===y.status?Math.min(j,k.current):j;_e(()=>{y.log.length<k.current&&(k.current=0),M>k.current&&(k.current=M)},[y.log.length,M]);const F=y.log.slice(0,k.current),H=y.log.slice(k.current),G=B?F.filter(e=>"tool"!==e.kind&&"tool_result"!==e.kind&&"thinking"!==e.kind):F,W=(()=>{if(!B)return H;let e=0;const t=[];for(let r=H.length-1;r>=0;r--){const n=H[r];"tool"===n.kind||"tool_result"===n.kind||"thinking"===n.kind?("tool"===n.kind&&e++,e<=f&&t.unshift(n)):t.unshift(n)}return t})(),V=Ee(async()=>{T.current?(_.current&&clearTimeout(_.current),await(l?.()),process.exit(0)):(T.current=!0,S(!0),_.current=setTimeout(()=>{T.current=!1,S(!1)},2e3))},[l]);s((e,t)=>{t.ctrl&&"c"===e&&V().catch(()=>process.exit(1)),t.ctrl&&"o"===e&&A(e=>!e),t.escape&&"running"===y.status&&!C&&0===v.length&&c?.()},{isActive:o}),_e(()=>{if(C||!g)return;process.stdout.isTTY&&process.stdout.write("[?2004h");const e=e=>{const t=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n");t&&w(e=>({value:e.value.slice(0,e.cursor)+t+e.value.slice(e.cursor),cursor:e.cursor+t.length}))},t=t=>{const r=t.toString();if(r.includes("[200~")){P.current=!0;const t=r.slice(r.indexOf("[200~")+6),n=t.includes("[201~"),s=n?t.slice(0,t.indexOf("[201~")):t;return e(s),void(n&&setTimeout(()=>{P.current=!1},0))}if(r.includes("[201~")){const t=r.slice(0,r.indexOf("[201~"));return e(t),void setTimeout(()=>{P.current=!1},0)}P.current?e(r):"[1;5H"!==r&&"[1;5~"!==r?"[1;5F"!==r&&"[4;5~"!==r?"[H"!==r&&"[1~"!==r&&"OH"!==r&&"[7~"!==r?"[F"!==r&&"[4~"!==r&&"OF"!==r&&"[8~"!==r||w(e=>({...e,cursor:Bo(e.value,e.cursor)})):w(e=>({...e,cursor:Oo(e.value,e.cursor)})):w(e=>({...e,cursor:e.value.length})):w(e=>({...e,cursor:0}))};return process.stdin.on("data",t),()=>{process.stdin.off("data",t),process.stdout.isTTY&&process.stdout.write("[?2004l")}},[C,g]),s((e,t)=>{if(!t.ctrl||"c"!==e){if(t.return){if(P.current)return;const e=v.trim();return e&&g?.(e),void w({value:"",cursor:0})}t.ctrl&&"w"===e||t.ctrl&&t.backspace?w(e=>{const t=Do(e.value,e.cursor);return{value:e.value.slice(0,t)+e.value.slice(e.cursor),cursor:t}}):!t.backspace&&!t.delete||t.ctrl?t.ctrl&&t.leftArrow||t.meta&&"b"===e?w(e=>({...e,cursor:Do(e.value,e.cursor)})):t.ctrl&&t.rightArrow||t.meta&&"f"===e?w(e=>({...e,cursor:No(e.value,e.cursor)})):t.leftArrow?w(e=>({...e,cursor:Math.max(0,e.cursor-1)})):t.rightArrow?w(e=>({...e,cursor:Math.min(e.value.length,e.cursor+1)})):t.ctrl&&"a"===e?w(e=>({...e,cursor:Oo(e.value,e.cursor)})):t.ctrl&&"e"===e?w(e=>({...e,cursor:Bo(e.value,e.cursor)})):t.escape&&v.length>0?w({value:"",cursor:0}):!e||t.ctrl||t.meta||t.escape||e.includes("")||/^\[./.test(e)||/^O[A-D]$/.test(e)||P.current||w(t=>({value:t.value.slice(0,t.cursor)+e+t.value.slice(t.cursor),cursor:t.cursor+e.length})):w(e=>e.cursor>0?{value:e.value.slice(0,e.cursor-1)+e.value.slice(e.cursor),cursor:e.cursor-1}:e)}},{isActive:o&&!!g&&!C});const Y=Se(()=>"running"===y.status?xe(a,{label:y.runningLabel??"Working"}):"success"!==y.status?xe(n,{color:$r("error"),children:"β Failed"}):void 0,[y.runningLabel,y.status]),z=!(m||!g||"running"!==y.status||0!==y.log.length||y.resultText||y.errorText),q="running"===y.status&&!z||y.resultText||y.errorText||"error"===y.status;return Ae(t,{flexDirection:"column",children:[R?Ae(t,{flexDirection:"column",flexShrink:0,children:[xe(n,{color:$r("brand"),bold:!0,children:"Stably Agent"}),xe(t,{flexDirection:"column",marginTop:1,children:xe(n,{color:$r("muted"),children:y.promptDisplay})})]}):xe(r,{items:["header"],children:()=>Ae(t,{flexDirection:"column",flexShrink:0,children:[xe(n,{color:$r("brand"),bold:!0,children:"Stably Agent"}),xe(t,{flexDirection:"column",marginTop:1,children:xe(n,{color:$r("muted"),children:y.promptDisplay})})]},"header")}),G.length>0&&xe(r,{items:G,children:(e,t)=>p(e,B,G[t-1]?.kind)}),W.length>0&&xe(t,{flexDirection:"column",children:W.map((e,t)=>{const r=t>0?W[t-1]?.kind:G.at(-1)?.kind;return p(e,B,r)})}),B&&H.length>W.length&&Ae(n,{color:$r("subtle"),children:["β ",H.length-W.length," tool calls hidden (Ctrl+O to expand)"]}),x&&o&&xe(n,{color:$r("subtle"),children:"β Showing all tool calls (Ctrl+O to collapse)"}),"error"===y.status&&y.errorText&&xe(t,{marginTop:1,children:xe(n,{color:$r("error"),children:y.errorText})}),"success"===y.status&&y.resultText&&xe(t,{marginTop:1,children:xe(n,{children:y.resultText})}),q&&xe(t,{flexDirection:"column",flexShrink:0,marginTop:1,children:"running"===y.status&&y.fixProgress?Ae(t,{flexDirection:"column",children:[Ae(t,{children:[xe(a,{}),xe(n,{children:" "}),xe(u,{progress:y.fixProgress})]}),("fixing"===y.fixProgress.phase||"debugging"===y.fixProgress.phase)&&y.log.flatMap(e=>{const{subagent:r}=e;if("subagent"!==e.kind||"code-worker"!==r?.subagentType&&"browser-worker"!==r?.subagentType||"running"!==r.status)return[];const{activities:s}=r,o=s.filter(e=>"tool"===e.kind).length,i=s.at(-1),c=s.filter(e=>"tool"===e.kind).at(-1),l=(()=>{if(!i)return null;if("tool"===i.kind)return null;if("text"===i.kind){const e=i.content.trim().split("\n").at(-1)?.trim();return e?e.length>80?`${e.slice(0,80)}β¦`:e:null}if("tool_result"===i.kind){const e=i.content.trim().split("\n")[0]?.trim();return e?e.length>80?`${e.slice(0,80)}β¦`:e:null}return null})();return Ae(t,{flexDirection:"column",children:[Ae(n,{children:[" ",xe(a,{}),Ae(n,{color:$r("muted"),children:[r.description||r.subagentType||"worker",o>0?` (${o} ${1===o?"cycle":"cycles"})`:""]})]}),c&&Ae(n,{color:$r("subtle"),children:[" β¦ ",c.content]}),l&&Ae(n,{color:$r("subtle"),children:[" ",l]})]},e.id)})]}):"success"!==y.status&&"error"!==y.status||!y.fixProgress?Y:xe(d,{progress:y.fixProgress})}),null!=y.permissionPrompt&&null!=h&&xe(i,{onChoice:h,prompt:y.permissionPrompt}),null!=g&&null==y.permissionPrompt&&!y.isExiting&&Ae(t,{borderColor:"gray",borderStyle:"round",flexDirection:"column",flexShrink:0,marginTop:1,paddingX:1,paddingY:0,children:[xe(n,{color:$r("subtle"),children:"Type a message and press Enter. Press Escape to interrupt. Press Ctrl+C to exit."}),Ae(n,{children:[xe(n,{color:$r("accent"),children:"β―"})," ",v.slice(0,I),xe(e,{}),v.slice(I)]})]}),E&&Ae(t,{marginTop:1,flexDirection:"column",children:[xe(n,{color:$r("accent"),children:"Press Ctrl+C again to exit"}),Xn&&Ae(n,{color:$r("subtle"),children:["Debug log: ",ts]})]})]})}})({Cursor:u,inkComponents:{Box:r,Static:n,Text:s,useInput:i},isInitMode:t?.isInitMode,isRawModeSupported:a,PermissionPrompt:d,Spinner:({label:e})=>{const[t,r]=Ie(0);return _e(()=>{if(!c)return;const e=setInterval(()=>r(e=>(e+1)%l.length),80);return()=>clearInterval(e)},[]),Ae(s,{color:$r("accent"),children:[l[t]," ",e]})}});let f=e;t?.isFixMode&&(f.fixProgress={phase:"initializing",totalTests:null,fixedTests:0,failedTests:0,currentTestDescription:null,lastTestDescription:null,startedAt:Date.now(),endedAt:null,isError:!1});const h={current:(e,t)=>{}},g=o(xe(p,{onCancel:t?.onCancel,onExit:t?.onExit,onPermissionChoice:(e,t)=>h.current(e,t),onSend:t?.onSend,showSpinnerImmediately:t?.showSpinnerImmediately,state:f}),{exitOnCtrlC:!1}),m=()=>{f={...f},g.rerender(xe(p,{onCancel:t?.onCancel,onExit:t?.onExit,onPermissionChoice:(e,t)=>h.current(e,t),onSend:t?.onSend,showSpinnerImmediately:t?.showSpinnerImmediately,state:f}))};let y=null;const b=()=>{y&&(clearTimeout(y),y=null),f.log=[...f.log],m()};let w=null;const v=({text:e})=>{e&&(f.preserveLiveLog=!1,f.log=[...f.log,{content:e,id:f.log.length,kind:"user"}],m())},I=new Map;return{addSubagentActivity:({toolUseId:e,kind:t,content:r})=>{f.preserveLiveLog=!1;const n=I.get(e);if(void 0===n)return void console.error("[addSubagentActivity] No entry index for toolUseId:",e);const s=f.log[n];if("subagent"===s?.kind&&s.subagent){if("text"===t){const e=s.subagent.activities.at(-1);"text"===e?.kind?e.content+=r:s.subagent.activities.push({id:s.subagent.activities.length,kind:"text",content:r.replace(/^\s*\n+/,"")})}else s.subagent.activities.push({id:s.subagent.activities.length,kind:t,content:r});f.log=[...f.log],m()}else console.error("[addSubagentActivity] Entry not found or not subagent:",{entryIndex:n,entryKind:s?.kind})},addSubagentStart:({toolUseId:e,subagentType:t,description:r})=>{f.preserveLiveLog=!1;const n=f.log.length;if(I.set(e,n),f.log=[...f.log,{content:"",id:n,kind:"subagent",subagent:{toolUseId:e,subagentType:t,description:r,status:"running",activities:[]}}],f.fixProgress)if("triage"===t&&"initializing"===f.fixProgress.phase)f.fixProgress={...f.fixProgress,phase:"triage"};else if("code-worker"===t){const e=(f.fixProgress.totalTests??0)+1,t=r||null;f.fixProgress={...f.fixProgress,phase:"fixing",totalTests:e,currentTestDescription:t,lastTestDescription:t??f.fixProgress.lastTestDescription}}else if("browser-worker"===t){const e=(f.fixProgress.totalTests??0)+1,t=r||null;f.fixProgress={...f.fixProgress,phase:"debugging",totalTests:e,currentTestDescription:t,lastTestDescription:t??f.fixProgress.lastTestDescription}}else"validation"===t?f.fixProgress={...f.fixProgress,phase:"validation",currentTestDescription:null}:"context"===t&&(f.fixProgress={...f.fixProgress,currentTestDescription:r||f.fixProgress.currentTestDescription});m()},addTool:({rawName:e,toolInput:t})=>{f.preserveLiveLog=!1;const r=Lo(e,t),n=r??$o(e),s=r?void 0:Uo(e,t),o=s?`${n} (${s})`:n;f.log=[...f.log,{content:o,id:f.log.length,kind:"tool"}],m()},addToolResult:({message:e})=>{f.preserveLiveLog=!1,f.log=[...f.log,{content:e,id:f.log.length,kind:"tool_result"}],m()},appendCancelled:()=>{f.preserveLiveLog=!0,f.log=[...f.log,{content:"[Cancelled]",id:f.log.length,kind:"cancelled"}],m()},appendText:({text:e})=>{if(!e)return;f.preserveLiveLog=!1;const t=f.log.at(-1),r="text"!==t?.kind?e.replace(/^\s*\n+/,""):e;f.log="text"===t?.kind?[...f.log.slice(0,-1),{...t,content:`${t.content}${r}`}]:[...f.log,{content:r,id:f.log.length,kind:"text"}],m()},appendThinking:({text:e,forceNewBlock:t})=>{if(!e)return;f.preserveLiveLog=!1;const r=null!==w?f.log[w]:null;"thinking"!==r?.kind||t?(w=f.log.length,f.log=[...f.log,{content:e,id:f.log.length,kind:"thinking"}]):r.content+=e,f.activeThinkingLogIndex=w,y||(y=setTimeout(b,50))},appendUserMessage:v,cancelThinkingRender:()=>{y&&(clearTimeout(y),y=null)},cleanup:async()=>{const e=g.waitUntilExit();g.unmount(),await e},dismissPermissionPrompt:()=>{f.permissionPrompt&&(f.permissionPrompt.resolve({behavior:"deny",message:"Cancelled by user",interrupt:!0}),f.permissionPrompt=void 0,m())},flushThinkingRender:b,resetThinkingLogIndex:()=>{w=null,f.activeThinkingLogIndex=null},setExiting:()=>{f.isExiting=!0,m()},setRunningLabel:({label:e})=>{f.runningLabel=e,m()},setStatus:({error:e,result:t,status:r})=>{f.errorText=e,f.resultText=t,f.status=r,"running"===r&&(f.preserveLiveLog=!1),m()},setSubagentStatus:({toolUseId:e,status:t})=>{f.preserveLiveLog=!1;const r=I.get(e);if(void 0===r)return;const n=f.log[r];"subagent"===n?.kind&&n.subagent&&(n.subagent.status=t,!f.fixProgress||"code-worker"!==n.subagent.subagentType&&"browser-worker"!==n.subagent.subagentType||("complete"===t?f.fixProgress={...f.fixProgress,fixedTests:f.fixProgress.fixedTests+1,currentTestDescription:null}:"error"===t&&(f.fixProgress={...f.fixProgress,failedTests:f.fixProgress.failedTests+1,currentTestDescription:null})),f.log=[...f.log],m(),"complete"!==t&&"error"!==t||I.delete(e))},showPermissionPrompt:e=>new Promise(t=>{h.current=(r,n)=>{if(f.permissionPrompt=void 0,m(),"allow"===r)t({behavior:"allow",updatedInput:e.input});else if("always"===r)t({behavior:"allow",updatedInput:e.input,updatedPermissions:e.suggestions});else{const e=n??"User denied this action";v({text:e}),t({behavior:"deny",message:e,interrupt:!1})}},f.permissionPrompt={...e,resolve:t},m()}),updateFixProgress:t?.isFixMode?e=>{f.fixProgress&&(f.fixProgress={...f.fixProgress,...e},m())}:void 0}},{zMarkdownAutoHealReport:Go,zRepresentativeTest:Wo}=function(e){const t=e.enum(Ar),r=["Classification of the root cause:","",`- test: ${Cr("test")}`,`- bug: ${Cr("bug")}`,`- flake: ${Cr("flake")}`,`- ui_change: ${Cr("ui_change")}`,`- other: ${Cr("other")}`].join("\n"),n=e.object({filePath:e.string().optional(),testIdentifier:e.string().optional(),testTitle:e.string().optional()}),s=e.object({status:e.enum(kr),representativeTest:n,storage:e.object({bucket:e.string(),key:e.string()}).optional(),signedUrl:e.string().optional(),error:e.string().optional(),testPassed:e.boolean().optional(),testExitCode:e.number().nullable().optional(),testStderr:e.string().optional()}),o=s.extend({testCaseId:e.string().min(1).describe("Test case ID this trace proof corresponds to.")}),i=e.object({erroredUrl:e.string().optional(),issueType:t.describe(r),relatedTestCaseIds:e.array(e.string()).min(1).describe("List of ALL test case IDs impacted by this root cause (must be existing IDs only)."),rootCause:e.string().describe("Brief explanation of what happened (1-2 sentences). Include file:line references (e.g., `src/tests/login.spec.ts:42`) to back up your claim."),traceProofs:e.array(o).min(1).optional().describe("Per-test trace proofs for each testCaseId in this issue.")}),a=e.discriminatedUnion("result",[i.extend({fixApplied:e.string().describe("What fix was applied (brief, specific). Include file:line references (e.g., `src/tests/login.spec.ts:42`) showing where changes were made."),result:e.literal("fixed"),traceProof:s.optional()}),i.extend({followUpActions:e.string().optional().describe("Optional list of follow-up actions for any unfixed issues or missing data."),reasonNotFixed:e.string().describe("Why it could not be auto-fixed (brief). Include file:line references (e.g., `src/tests/login.spec.ts:42`) pointing to the problematic code."),result:e.literal("unfixed")})]),c=e.object({issues:e.array(a).min(1).describe("List of all auto-heal issues/outcomes for this suite."),summary:e.string().min(3).describe("High-level summary (2-3 sentences) of the suite auto-heal results.")}),l=e.discriminatedUnion("result",[e.object({result:e.literal("fixed"),issueType:t,issueId:e.string().optional().describe("Issue ID from triage, used for deterministic fingerprinting across re-uploads."),rootCause:e.string().min(1),fixApplied:e.string().min(1).describe("What fix was applied (brief, specific). Include file:line references."),relatedTestCaseIds:e.array(e.string()).min(1)}),e.object({result:e.literal("unfixed"),issueType:t,issueId:e.string().optional().describe("Issue ID from triage, used for deterministic fingerprinting across re-uploads."),rootCause:e.string().min(1),reasonNotFixed:e.string().min(1).describe("Why it could not be auto-fixed (brief). Include file:line references."),relatedTestCaseIds:e.array(e.string()).min(1)})]),u=e.object({format:e.literal("markdown"),markdown:e.string().min(1).describe("Flexible markdown report content for the auto-heal run. Use headings, bullets, and code fences as needed."),summary:e.string().optional().describe('One-liner summary of the auto-heal run (e.g., "Fixed 2 of 3 issues: stale locators and timing"). Used in notifications, API responses, and triage agent context.'),issues:e.array(l).optional().describe("Structured issue metadata for database tracking. Each issue links a root cause to affected test case IDs.")});return{zAutoHealReport:a,zIssueCategory:t,zMarkdownAutoHealReport:u,zMarkdownAutoHealReportIssue:l,zRepresentativeTest:n,zSuiteAutoHealReport:c,zStoredAutoHealReport:e.union([u,c]),zTraceProof:s,zTraceProofByTest:o}}(we),Vo=ke("/");try{Fo=Vo("worker_threads").Worker}catch(e){}var Yo=Fo?function(e,t,r,n,s){var o=!1,i=new Fo(e+";var __w=require('worker_threads');__w.parentPort.on('message',function(m){onmessage({data:m})}),postMessage=function(m,t){__w.parentPort.postMessage(m,t)},close=process.exit;self=global",{eval:!0}).on("error",function(e){return s(e,null)}).on("message",function(e){return s(null,e)}).on("exit",function(e){e&&!o&&s(new Error("exited with code "+e),null)});return i.postMessage(r,n),i.terminate=function(){return o=!0,Fo.prototype.terminate.call(i)},i}:function(e,t,r,n,s){setImmediate(function(){return s(new Error("async operations unsupported - update to Node 12+ (or Node 10-11 with the --experimental-worker CLI flag)"),null)});var o=function(){};return{terminate:o,postMessage:o}},zo=Uint8Array,qo=Uint16Array,Ko=Int32Array,Jo=new zo([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Xo=new zo([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Qo=new zo([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Zo=function(e,t){for(var r=new qo(31),n=0;n<31;++n)r[n]=t+=1<<e[n-1];var s=new Ko(r[30]);for(n=1;n<30;++n)for(var o=r[n];o<r[n+1];++o)s[o]=o-r[n]<<5|n;return{b:r,r:s}},ei=Zo(Jo,2),ti=ei.b,ri=ei.r;ti[28]=258,ri[258]=28;var ni,si=Zo(Xo,0),oi=si.b,ii=si.r,ai=new qo(32768);for(ui=0;ui<32768;++ui)ni=(61680&(ni=(52428&(ni=(43690&ui)>>1|(21845&ui)<<1))>>2|(13107&ni)<<2))>>4|(3855&ni)<<4,ai[ui]=((65280&ni)>>8|(255&ni)<<8)>>1;var ci=function(e,t,r){for(var n=e.length,s=0,o=new qo(t);s<n;++s)e[s]&&++o[e[s]-1];var i,a=new qo(t);for(s=1;s<t;++s)a[s]=a[s-1]+o[s-1]<<1;if(r){i=new qo(1<<t);var c=15-t;for(s=0;s<n;++s)if(e[s])for(var l=s<<4|e[s],u=t-e[s],d=a[e[s]-1]++<<u,p=d|(1<<u)-1;d<=p;++d)i[ai[d]>>c]=l}else for(i=new qo(n),s=0;s<n;++s)e[s]&&(i[s]=ai[a[e[s]-1]++]>>15-e[s]);return i},li=new zo(288);for(ui=0;ui<144;++ui)li[ui]=8;for(ui=144;ui<256;++ui)li[ui]=9;for(ui=256;ui<280;++ui)li[ui]=7;for(ui=280;ui<288;++ui)li[ui]=8;var ui,di=new zo(32);for(ui=0;ui<32;++ui)di[ui]=5;var pi=ci(li,9,0),fi=ci(li,9,1),hi=ci(di,5,0),gi=ci(di,5,1),mi=function(e){for(var t=e[0],r=1;r<e.length;++r)e[r]>t&&(t=e[r]);return t},yi=function(e,t,r){var n=t/8|0;return(e[n]|e[n+1]<<8)>>(7&t)&r},bi=function(e,t){var r=t/8|0;return(e[r]|e[r+1]<<8|e[r+2]<<16)>>(7&t)},wi=function(e){return(e+7)/8|0},vi=function(e,t,r){return(null==t||t<0)&&(t=0),(null==r||r>e.length)&&(r=e.length),new zo(e.subarray(t,r))},Ii=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Ti=function(e,t,r){var n=new Error(t||Ii[e]);if(n.code=e,Error.captureStackTrace&&Error.captureStackTrace(n,Ti),!r)throw n;return n},_i=function(e,t,r,n){var s=e.length,o=n?n.length:0;if(!s||t.f&&!t.l)return r||new zo(0);var i=!r,a=i||2!=t.i,c=t.i;i&&(r=new zo(3*s));var l=function(e){var t=r.length;if(e>t){var n=new zo(Math.max(2*t,e));n.set(r),r=n}},u=t.f||0,d=t.p||0,p=t.b||0,f=t.l,h=t.d,g=t.m,m=t.n,y=8*s;do{if(!f){u=yi(e,d,1);var b=yi(e,d+1,3);if(d+=3,!b){var w=e[(C=wi(d)+4)-4]|e[C-3]<<8,v=C+w;if(v>s){c&&Ti(0);break}a&&l(p+w),r.set(e.subarray(C,v),p),t.b=p+=w,t.p=d=8*v,t.f=u;continue}if(1==b)f=fi,h=gi,g=9,m=5;else if(2==b){var I=yi(e,d,31)+257,T=yi(e,d+10,15)+4,_=I+yi(e,d+5,31)+1;d+=14;for(var E=new zo(_),S=new zo(19),x=0;x<T;++x)S[Qo[x]]=yi(e,d+3*x,7);d+=3*T;var A=mi(S),k=(1<<A)-1,P=ci(S,A,1);for(x=0;x<_;){var C,R=P[yi(e,d,k)];if(d+=15&R,(C=R>>4)<16)E[x++]=C;else{var U=0,L=0;for(16==C?(L=3+yi(e,d,3),d+=2,U=E[x-1]):17==C?(L=3+yi(e,d,7),d+=3):18==C&&(L=11+yi(e,d,127),d+=7);L--;)E[x++]=U}}var $=E.subarray(0,I),D=E.subarray(I);g=mi($),m=mi(D),f=ci($,g,1),h=ci(D,m,1)}else Ti(1);if(d>y){c&&Ti(0);break}}a&&l(p+131072);for(var N=(1<<g)-1,O=(1<<m)-1,B=d;;B=d){var j=(U=f[bi(e,d)&N])>>4;if((d+=15&U)>y){c&&Ti(0);break}if(U||Ti(2),j<256)r[p++]=j;else{if(256==j){B=d,f=null;break}var M=j-254;if(j>264){var F=Jo[x=j-257];M=yi(e,d,(1<<F)-1)+ti[x],d+=F}var H=h[bi(e,d)&O],G=H>>4;if(H||Ti(3),d+=15&H,D=oi[G],G>3&&(F=Xo[G],D+=bi(e,d)&(1<<F)-1,d+=F),d>y){c&&Ti(0);break}a&&l(p+131072);var W=p+M;if(p<D){var V=o-D,Y=Math.min(D,W);for(V+p<0&&Ti(3);p<Y;++p)r[p]=n[V+p]}for(;p<W;++p)r[p]=r[p-D]}}t.l=f,t.p=B,t.b=p,t.f=u,f&&(u=1,t.m=g,t.d=h,t.n=m)}while(!u);return p!=r.length&&i?vi(r,0,p):r.subarray(0,p)},Ei=function(e,t,r){r<<=7&t;var n=t/8|0;e[n]|=r,e[n+1]|=r>>8},Si=function(e,t,r){r<<=7&t;var n=t/8|0;e[n]|=r,e[n+1]|=r>>8,e[n+2]|=r>>16},xi=function(e,t){for(var r=[],n=0;n<e.length;++n)e[n]&&r.push({s:n,f:e[n]});var s=r.length,o=r.slice();if(!s)return{t:Li,l:0};if(1==s){var i=new zo(r[0].s+1);return i[r[0].s]=1,{t:i,l:1}}r.sort(function(e,t){return e.f-t.f}),r.push({s:-1,f:25001});var a=r[0],c=r[1],l=0,u=1,d=2;for(r[0]={s:-1,f:a.f+c.f,l:a,r:c};u!=s-1;)a=r[r[l].f<r[d].f?l++:d++],c=r[l!=u&&r[l].f<r[d].f?l++:d++],r[u++]={s:-1,f:a.f+c.f,l:a,r:c};var p=o[0].s;for(n=1;n<s;++n)o[n].s>p&&(p=o[n].s);var f=new qo(p+1),h=Ai(r[u-1],f,0);if(h>t){n=0;var g=0,m=h-t,y=1<<m;for(o.sort(function(e,t){return f[t.s]-f[e.s]||e.f-t.f});n<s;++n){var b=o[n].s;if(!(f[b]>t))break;g+=y-(1<<h-f[b]),f[b]=t}for(g>>=m;g>0;){var w=o[n].s;f[w]<t?g-=1<<t-f[w]++-1:++n}for(;n>=0&&g;--n){var v=o[n].s;f[v]==t&&(--f[v],++g)}h=t}return{t:new zo(f),l:h}},Ai=function(e,t,r){return-1==e.s?Math.max(Ai(e.l,t,r+1),Ai(e.r,t,r+1)):t[e.s]=r},ki=function(e){for(var t=e.length;t&&!e[--t];);for(var r=new qo(++t),n=0,s=e[0],o=1,i=function(e){r[n++]=e},a=1;a<=t;++a)if(e[a]==s&&a!=t)++o;else{if(!s&&o>2){for(;o>138;o-=138)i(32754);o>2&&(i(o>10?o-11<<5|28690:o-3<<5|12305),o=0)}else if(o>3){for(i(s),--o;o>6;o-=6)i(8304);o>2&&(i(o-3<<5|8208),o=0)}for(;o--;)i(s);o=1,s=e[a]}return{c:r.subarray(0,n),n:t}},Pi=function(e,t){for(var r=0,n=0;n<t.length;++n)r+=e[n]*t[n];return r},Ci=function(e,t,r){var n=r.length,s=wi(t+2);e[s]=255&n,e[s+1]=n>>8,e[s+2]=255^e[s],e[s+3]=255^e[s+1];for(var o=0;o<n;++o)e[s+o+4]=r[o];return 8*(s+4+n)},Ri=function(e,t,r,n,s,o,i,a,c,l,u){Ei(t,u++,r),++s[256];for(var d=xi(s,15),p=d.t,f=d.l,h=xi(o,15),g=h.t,m=h.l,y=ki(p),b=y.c,w=y.n,v=ki(g),I=v.c,T=v.n,_=new qo(19),E=0;E<b.length;++E)++_[31&b[E]];for(E=0;E<I.length;++E)++_[31&I[E]];for(var S=xi(_,7),x=S.t,A=S.l,k=19;k>4&&!x[Qo[k-1]];--k);var P,C,R,U,L=l+5<<3,$=Pi(s,li)+Pi(o,di)+i,D=Pi(s,p)+Pi(o,g)+i+14+3*k+Pi(_,x)+2*_[16]+3*_[17]+7*_[18];if(c>=0&&L<=$&&L<=D)return Ci(t,u,e.subarray(c,c+l));if(Ei(t,u,1+(D<$)),u+=2,D<$){P=ci(p,f,0),C=p,R=ci(g,m,0),U=g;var N=ci(x,A,0);for(Ei(t,u,w-257),Ei(t,u+5,T-1),Ei(t,u+10,k-4),u+=14,E=0;E<k;++E)Ei(t,u+3*E,x[Qo[E]]);u+=3*k;for(var O=[b,I],B=0;B<2;++B){var j=O[B];for(E=0;E<j.length;++E){var M=31&j[E];Ei(t,u,N[M]),u+=x[M],M>15&&(Ei(t,u,j[E]>>5&127),u+=j[E]>>12)}}}else P=pi,C=li,R=hi,U=di;for(E=0;E<a;++E){var F=n[E];if(F>255){Si(t,u,P[257+(M=F>>18&31)]),u+=C[M+257],M>7&&(Ei(t,u,F>>23&31),u+=Jo[M]);var H=31&F;Si(t,u,R[H]),u+=U[H],H>3&&(Si(t,u,F>>5&8191),u+=Xo[H])}else Si(t,u,P[F]),u+=C[F]}return Si(t,u,P[256]),u+C[256]},Ui=new Ko([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Li=new zo(0),$i=function(e,t,r,n,s,o){var i=o.z||e.length,a=new zo(n+i+5*(1+Math.ceil(i/7e3))+s),c=a.subarray(n,a.length-s),l=o.l,u=7&(o.r||0);if(t){u&&(c[0]=o.r>>3);for(var d=Ui[t-1],p=d>>13,f=8191&d,h=(1<<r)-1,g=o.p||new qo(32768),m=o.h||new qo(h+1),y=Math.ceil(r/3),b=2*y,w=function(t){return(e[t]^e[t+1]<<y^e[t+2]<<b)&h},v=new Ko(25e3),I=new qo(288),T=new qo(32),_=0,E=0,S=o.i||0,x=0,A=o.w||0,k=0;S+2<i;++S){var P=w(S),C=32767&S,R=m[P];if(g[C]=R,m[P]=C,A<=S){var U=i-S;if((_>7e3||x>24576)&&(U>423||!l)){u=Ri(e,c,0,v,I,T,E,x,k,S-k,u),x=_=E=0,k=S;for(var L=0;L<286;++L)I[L]=0;for(L=0;L<30;++L)T[L]=0}var $=2,D=0,N=f,O=C-R&32767;if(U>2&&P==w(S-O))for(var B=Math.min(p,U)-1,j=Math.min(32767,S),M=Math.min(258,U);O<=j&&--N&&C!=R;){if(e[S+$]==e[S+$-O]){for(var F=0;F<M&&e[S+F]==e[S+F-O];++F);if(F>$){if($=F,D=O,F>B)break;var H=Math.min(O,F-2),G=0;for(L=0;L<H;++L){var W=S-O+L&32767,V=W-g[W]&32767;V>G&&(G=V,R=W)}}}O+=(C=R)-(R=g[C])&32767}if(D){v[x++]=268435456|ri[$]<<18|ii[D];var Y=31&ri[$],z=31&ii[D];E+=Jo[Y]+Xo[z],++I[257+Y],++T[z],A=S+$,++_}else v[x++]=e[S],++I[e[S]]}}for(S=Math.max(S,A);S<i;++S)v[x++]=e[S],++I[e[S]];u=Ri(e,c,l,v,I,T,E,x,k,S-k,u),l||(o.r=7&u|c[u/8|0]<<3,u-=7,o.h=m,o.p=g,o.i=S,o.w=A)}else{for(S=o.w||0;S<i+l;S+=65535){var q=S+65535;q>=i&&(c[u/8|0]=l,q=i),u=Ci(c,u+1,e.subarray(S,q))}o.i=i}return vi(a,0,n+wi(u)+s)},Di=function(){for(var e=new Int32Array(256),t=0;t<256;++t){for(var r=t,n=9;--n;)r=(1&r&&-306674912)^r>>>1;e[t]=r}return e}(),Ni=function(e,t,r,n,s){if(!s&&(s={l:1},t.dictionary)){var o=t.dictionary.subarray(-32768),i=new zo(o.length+e.length);i.set(o),i.set(e,o.length),e=i,s.w=o.length}return $i(e,null==t.level?6:t.level,null==t.mem?s.l?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(e.length)))):20:12+t.mem,r,n,s)},Oi=function(e,t){var r={};for(var n in e)r[n]=e[n];for(var n in t)r[n]=t[n];return r},Bi=function(e,t,r){for(var n=e(),s=e.toString(),o=s.slice(s.indexOf("[")+1,s.lastIndexOf("]")).replace(/\s+/g,"").split(","),i=0;i<n.length;++i){var a=n[i],c=o[i];if("function"==typeof a){t+=";"+c+"=";var l=a.toString();if(a.prototype)if(-1!=l.indexOf("[native code]")){var u=l.indexOf(" ",8)+1;t+=l.slice(u,l.indexOf("(",u))}else for(var d in t+=l,a.prototype)t+=";"+c+".prototype."+d+"="+a.prototype[d].toString();else t+=l}else r[c]=a}return t},ji=[],Mi=function(){return[zo,qo,Ko,Jo,Xo,Qo,ti,oi,fi,gi,ai,Ii,ci,mi,yi,bi,wi,vi,Ti,_i,Ji,Hi,Gi]},Fi=function(){return[zo,qo,Ko,Jo,Xo,Qo,ri,ii,pi,li,hi,di,ai,Ui,Li,ci,Ei,Si,xi,Ai,ki,Pi,Ci,Ri,wi,vi,$i,Ni,Ki,Hi]},Hi=function(e){return postMessage(e,[e.buffer])},Gi=function(e){return e&&{out:e.size&&new zo(e.size),dictionary:e.dictionary}},Wi=function(e,t,r,n,s,o){var i=function(e,t,r,n){if(!ji[r]){for(var s="",o={},i=e.length-1,a=0;a<i;++a)s=Bi(e[a],s,o);ji[r]={c:Bi(e[i],s,o),e:o}}var c=Oi({},ji[r].e);return Yo(ji[r].c+";onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage="+t.toString()+"}",r,c,function(e){var t=[];for(var r in e)e[r].buffer&&t.push((e[r]=new e[r].constructor(e[r])).buffer);return t}(c),n)}(r,n,s,function(e,t){i.terminate(),o(e,t)});return i.postMessage([e,t],t.consume?[e.buffer]:[]),function(){i.terminate()}},Vi=function(e,t){return e[t]|e[t+1]<<8},Yi=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},zi=function(e,t){return Yi(e,t)+4294967296*Yi(e,t+4)},qi=function(e,t,r){for(;r;++t)e[t]=r,r>>>=8};function Ki(e,t){return Ni(e,t||{},0,0)}function Ji(e,t){return _i(e,{i:2},t&&t.out,t&&t.dictionary)}var Xi=function(e,t,r,n){for(var s in e){var o=e[s],i=t+s,a=n;Array.isArray(o)&&(a=Oi(n,o[1]),o=o[0]),o instanceof zo?r[i]=[o,a]:(r[i+="/"]=[new zo(0),a],Xi(o,i,r,n))}},Qi="undefined"!=typeof TextEncoder&&new TextEncoder,Zi="undefined"!=typeof TextDecoder&&new TextDecoder;try{Zi.decode(Li,{stream:!0})}catch(e){}function ea(e,t){if(Qi)return Qi.encode(e);for(var r=e.length,n=new zo(e.length+(e.length>>1)),s=0,o=function(e){n[s++]=e},i=0;i<r;++i){if(s+5>n.length){var a=new zo(s+8+(r-i<<1));a.set(n),n=a}var c=e.charCodeAt(i);c<128||t?o(c):c<2048?(o(192|c>>6),o(128|63&c)):c>55295&&c<57344?(o(240|(c=65536+(1047552&c)|1023&e.charCodeAt(++i))>>18),o(128|c>>12&63),o(128|c>>6&63),o(128|63&c)):(o(224|c>>12),o(128|c>>6&63),o(128|63&c))}return vi(n,0,s)}var ta=function(e){var t=0;if(e)for(var r in e){var n=e[r].length;n>65535&&Ti(9),t+=n+4}return t},ra=function(e,t,r,n,s,o,i,a){var c=n.length,l=r.extra,u=a&&a.length,d=ta(l);qi(e,t,null!=i?33639248:67324752),t+=4,null!=i&&(e[t++]=20,e[t++]=r.os),e[t]=20,t+=2,e[t++]=r.flag<<1|(o<0&&8),e[t++]=s&&8,e[t++]=255&r.compression,e[t++]=r.compression>>8;var p=new Date(null==r.mtime?Date.now():r.mtime),f=p.getFullYear()-1980;if((f<0||f>119)&&Ti(10),qi(e,t,f<<25|p.getMonth()+1<<21|p.getDate()<<16|p.getHours()<<11|p.getMinutes()<<5|p.getSeconds()>>1),t+=4,-1!=o&&(qi(e,t,r.crc),qi(e,t+4,o<0?-o-2:o),qi(e,t+8,r.size)),qi(e,t+12,c),qi(e,t+14,d),t+=16,null!=i&&(qi(e,t,u),qi(e,t+6,r.attrs),qi(e,t+10,i),t+=14),e.set(n,t),t+=c,d)for(var h in l){var g=l[h],m=g.length;qi(e,t,+h),qi(e,t+2,m),e.set(g,t+4),t+=4+m}return u&&(e.set(a,t),t+=u),t},na="function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout?setTimeout:function(e){e()};function sa(e,t,r){const n=Math.min(t,512);if("utf-16"===r||"utf-16le"===r||"utf-16be"===r){for(let t=0;t<n;t+=2){const s=e[t],o=t+1<n?e[t+1]:0;if(("utf-16le"===r||"utf-16"===r)&&0===o&&s<32&&9!==s&&10!==s&&13!==s&&0!==s)return!1;if(("utf-16be"===r||"utf-16"===r)&&0===s&&o<32&&9!==o&&10!==o&&13!==o&&0!==o)return!1}return!0}if("latin1"===r||"iso-8859-1"===r){for(let t=0;t<n;t++){const r=e[t];if(0===r)return!1;if(r<32&&9!==r&&10!==r&&13!==r)return!1}return!0}if("cjk"===r||"big5"===r||"gb2312"===r||"gbk"===r||"euc-kr"===r||"shift-jis"===r){for(let t=0;t<n;t++){const r=e[t];if(0===r)return!1;if(r<32&&9!==r&&10!==r&&13!==r)return!1}return!0}return!1}var oa=class{fileBuffer;size;offset;error;constructor(e,t){this.fileBuffer=e,this.size=t,this.offset=0,this.error=!1}hasError(){return this.error}nextByte(){return this.offset===this.size||this.hasError()?(this.error=!0,255):this.fileBuffer[this.offset++]}next(e){if(e<0||e>this.size-this.offset)return this.error=!0,[];const t=new Array;for(let r=0;r<e;r++){if(this.error)return t;t[r]=this.nextByte()}return t}};function ia(e){let t=0,r=0;for(;!e.hasError();){const n=e.nextByte();if(r|=(127&n)<<7*t,!(128&n))break;if(t>=10){e.error=!0;break}t++}return r}function aa(e){switch(7&ia(e)){case 0:return ia(e),!0;case 1:return e.next(8),!0;case 2:const t=ia(e);return e.next(t),!0;case 5:return e.next(4),!0}return!1}function ca(e,t,r){if(0===t)return!1;let n=0;const s=Math.min(t,515),o=Math.min(s,512);if(t>=3&&239===e[0]&&187===e[1]&&191===e[2])return!1;if(t>=4&&0===e[0]&&0===e[1]&&254===e[2]&&255===e[3])return!1;if(t>=4&&255===e[0]&&254===e[1]&&0===e[2]&&0===e[3])return!1;if(t>=4&&132===e[0]&&49===e[1]&&149===e[2]&&51===e[3])return!1;if(s>=5&&"%PDF-"===e.slice(0,5).toString())return!0;if(t>=2&&254===e[0]&&255===e[1])return!1;if(t>=2&&255===e[0]&&254===e[1])return!1;if(r?.encoding)return!sa(e,t,r.encoding);const i=function(e,t){if(t<4)return null;const r=Math.min(t,512);let n=0,s=0;for(let t=0;t<r;t++)0===e[t]&&(t%2==0?n++:s++);const o=n+s;if(o>.3*r&&o<.7*r){if(s>3*n)return"utf-16le";if(n>3*s)return"utf-16be"}return null}(e,t);if(i)return!sa(e,t,i);for(let t=0;t<o;t++){if(0===e[t])return!0;if((e[t]<7||e[t]>14)&&(e[t]<32||e[t]>127)){if(e[t]>=192&&e[t]<=223&&t+1<s){if(t++,e[t]>=128&&e[t]<=191)continue}else if(e[t]>=224&&e[t]<=239&&t+2<s){if(t++,e[t]>=128&&e[t]<=191&&e[t+1]>=128&&e[t+1]<=191){t++;continue}}else if(e[t]>=240&&e[t]<=247&&t+3<s&&(t++,e[t]>=128&&e[t]<=191&&e[t+1]>=128&&e[t+1]<=191&&e[t+2]>=128&&e[t+2]<=191)){t+=2;continue}if(n++,t>=32&&100*n/o>10)return!0}}return 100*n/o>10||!!(n>1&&function(e,t){const r=new oa(e,t);let n=0;for(;;){if(!aa(r)&&!r.hasError())return!1;if(r.hasError())break;n++}return n>0}(e,o))}var la=[/^\/$/,/^\*+$/,/^[0-9]+$/],ua=["/artifact/","https://","http://","*********"],da=Symbol.for("@ts-pattern/matcher"),pa=Symbol.for("@ts-pattern/isVariadic"),fa="@ts-pattern/anonymous-select-key",ha=e=>Boolean(e&&"object"==typeof e),ga=e=>e&&!!e[da],ma=(e,t,r)=>{if(ga(e)){const n=e[da](),{matched:s,selections:o}=n.match(t);return s&&o&&Object.keys(o).forEach(e=>r(e,o[e])),s}if(ha(e)){if(!ha(t))return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=[],s=[],o=[];for(const t of e.keys()){const r=e[t];ga(r)&&r[pa]?o.push(r):o.length?s.push(r):n.push(r)}if(o.length){if(o.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(t.length<n.length+s.length)return!1;const e=t.slice(0,n.length),i=0===s.length?[]:t.slice(-s.length),a=t.slice(n.length,0===s.length?1/0:-s.length);return n.every((t,n)=>ma(t,e[n],r))&&s.every((e,t)=>ma(e,i[t],r))&&(0===o.length||ma(o[0],a,r))}return e.length===t.length&&e.every((e,n)=>ma(e,t[n],r))}return Reflect.ownKeys(e).every(n=>{const s=e[n];return(n in t||ga(o=s)&&"optional"===o[da]().matcherType)&&ma(s,t[n],r);var o})}return Object.is(t,e)},ya=e=>{var t,r,n;return ha(e)?ga(e)?null!=(t=null==(r=(n=e[da]()).getSelectionKeys)?void 0:r.call(n))?t:[]:Array.isArray(e)?ba(e,ya):ba(Object.values(e),ya):[]},ba=(e,t)=>e.reduce((e,r)=>e.concat(t(r)),[]);function wa(e){return Object.assign(e,{optional:()=>{return t=e,wa({[da]:()=>({match:e=>{let r={};const n=(e,t)=>{r[e]=t};return void 0===e?(ya(t).forEach(e=>n(e,void 0)),{matched:!0,selections:r}):{matched:ma(t,e,n),selections:r}},getSelectionKeys:()=>ya(t),matcherType:"optional"})});var t},and:t=>va(e,t),or:t=>function(...e){return wa({[da]:()=>({match:t=>{let r={};const n=(e,t)=>{r[e]=t};return ba(e,ya).forEach(e=>n(e,void 0)),{matched:e.some(e=>ma(e,t,n)),selections:r}},getSelectionKeys:()=>ba(e,ya),matcherType:"or"})})}(e,t),select:t=>void 0===t?Ta(e):Ta(t,e)})}function va(...e){return wa({[da]:()=>({match:t=>{let r={};const n=(e,t)=>{r[e]=t};return{matched:e.every(e=>ma(e,t,n)),selections:r}},getSelectionKeys:()=>ba(e,ya),matcherType:"and"})})}function Ia(e){return{[da]:()=>({match:t=>({matched:Boolean(e(t))})})}}function Ta(...e){const t="string"==typeof e[0]?e[0]:void 0,r=2===e.length?e[1]:"string"==typeof e[0]?void 0:e[0];return wa({[da]:()=>({match:e=>{let n={[null!=t?t:fa]:e};return{matched:void 0===r||ma(r,e,(e,t)=>{n[e]=t}),selections:n}},getSelectionKeys:()=>[null!=t?t:fa].concat(void 0===r?[]:ya(r))})})}function _a(e){return!0}function Ea(e){return"number"==typeof e}function Sa(e){return"string"==typeof e}function xa(e){return"bigint"==typeof e}wa(Ia(_a)),wa(Ia(_a));var Aa=e=>Object.assign(wa(e),{startsWith:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.startsWith(r)))));var r},endsWith:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.endsWith(r)))));var r},minLength:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length>=r))));var r},length:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length===r))));var r},maxLength:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length<=r))));var r},includes:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.includes(r)))));var r},regex:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&Boolean(e.match(r))))));var r}});Aa(Ia(Sa));var ka=e=>Object.assign(wa(e),{between:(t,r)=>{return ka(va(e,(n=t,s=r,Ia(e=>Ea(e)&&n<=e&&s>=e))));var n,s},lt:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e<r))));var r},gt:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e>r))));var r},lte:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e<=r))));var r},gte:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e>=r))));var r},int:()=>ka(va(e,Ia(e=>Ea(e)&&Number.isInteger(e)))),finite:()=>ka(va(e,Ia(e=>Ea(e)&&Number.isFinite(e)))),positive:()=>ka(va(e,Ia(e=>Ea(e)&&e>0))),negative:()=>ka(va(e,Ia(e=>Ea(e)&&e<0)))});ka(Ia(Ea));var Pa=e=>Object.assign(wa(e),{between:(t,r)=>{return Pa(va(e,(n=t,s=r,Ia(e=>xa(e)&&n<=e&&s>=e))));var n,s},lt:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e<r))));var r},gt:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e>r))));var r},lte:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e<=r))));var r},gte:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e>=r))));var r},positive:()=>Pa(va(e,Ia(e=>xa(e)&&e>0))),negative:()=>Pa(va(e,Ia(e=>xa(e)&&e<0)))});Pa(Ia(xa)),wa(Ia(function(e){return"boolean"==typeof e})),wa(Ia(function(e){return"symbol"==typeof e})),wa(Ia(function(e){return null==e})),wa(Ia(function(e){return null!=e}));var Ca=class extends Error{constructor(e){let t;try{t=JSON.stringify(e)}catch(r){t=e}super(`Pattern matching error: no pattern matches value ${t}`),this.input=void 0,this.input=e}},Ra={matched:!1,value:void 0},Ua=class e{constructor(e,t){this.input=void 0,this.state=void 0,this.input=e,this.state=t}with(...t){if(this.state.matched)return this;const r=t[t.length-1],n=[t[0]];let s;3===t.length&&"function"==typeof t[1]?s=t[1]:t.length>2&&n.push(...t.slice(1,t.length-1));let o=!1,i={};const a=(e,t)=>{o=!0,i[e]=t},c=!n.some(e=>ma(e,this.input,a))||s&&!Boolean(s(this.input))?Ra:{matched:!0,value:r(o?fa in i?i[fa]:i:this.input,this.input)};return new e(this.input,c)}when(t,r){if(this.state.matched)return this;const n=Boolean(t(this.input));return new e(this.input,n?{matched:!0,value:r(this.input,this.input)}:Ra)}otherwise(e){return this.state.matched?this.state.value:e(this.input)}exhaustive(e=La){return this.state.matched?this.state.value:e(this.input)}run(){return this.exhaustive()}returnType(){return this}narrow(){return this}};function La(e){throw new Ca(e)}var $a=new Set(["sha1","_sha1","pageref","downloadsPath","tracesDir","pageId"]);function Da({sensitiveValues:e,str:t}){return e.reduce((e,t)=>e.replaceAll(t,"[REDACTED]"),t)}function Na({sensitiveValues:e,value:t}){return"string"==typeof t?Da({sensitiveValues:e,str:t}):Array.isArray(t)?t.map(t=>Na({sensitiveValues:e,value:t})):function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(t)?Ba({obj:t,sensitiveValues:e}):t}function Oa(e){return!!$a.has(e)||e.toLowerCase().endsWith("sha1")}function Ba({obj:e,sensitiveValues:t}){return Object.fromEntries(Object.entries(e).map(([e,r])=>[e,Oa(e)?r:Na({sensitiveValues:t,value:r})]))}function ja({error:e,sensitiveValues:t}){return e?{...e,message:Da({sensitiveValues:t,str:e.message})}:void 0}function Ma({content:e,sensitiveValues:t}){const r=new F,n=new H,s=Da({sensitiveValues:t,str:r.decode(e)});return n.encode(s)}var Fa=M(function(e,t,r){r||(r=t,t={}),"function"!=typeof r&&Ti(7);var n=[],s=function(){for(var e=0;e<n.length;++e)n[e]()},o={},i=function(e,t){na(function(){r(e,t)})};na(function(){i=r});for(var a=e.length-22;101010256!=Yi(e,a);--a)if(!a||e.length-a>65558)return i(Ti(13,0,1),null),s;var c=Vi(e,a+8);if(c){var l=c,u=Yi(e,a+16),d=4294967295==u||65535==l;if(d){var p=Yi(e,a-12);(d=101075792==Yi(e,p))&&(l=c=Yi(e,p+32),u=Yi(e,p+48))}for(var f=t&&t.filter,h=function(t){var r=function(e,t,r){var n=Vi(e,t+28),s=function(e,t){if(t){for(var r="",n=0;n<e.length;n+=16384)r+=String.fromCharCode.apply(null,e.subarray(n,n+16384));return r}if(Zi)return Zi.decode(e);var s=function(e){for(var t="",r=0;;){var n=e[r++],s=(n>127)+(n>223)+(n>239);if(r+s>e.length)return{s:t,r:vi(e,r-1)};s?3==s?(n=((15&n)<<18|(63&e[r++])<<12|(63&e[r++])<<6|63&e[r++])-65536,t+=String.fromCharCode(55296|n>>10,56320|1023&n)):t+=1&s?String.fromCharCode((31&n)<<6|63&e[r++]):String.fromCharCode((15&n)<<12|(63&e[r++])<<6|63&e[r++]):t+=String.fromCharCode(n)}}(e),o=s.s;return(r=s.r).length&&Ti(8),o}(e.subarray(t+46,t+46+n),!(2048&Vi(e,t+8))),o=t+46+n,i=Yi(e,t+20),a=r&&4294967295==i?function(e,t){for(;1!=Vi(e,t);t+=4+Vi(e,t+2));return[zi(e,t+12),zi(e,t+4),zi(e,t+20)]}(e,o):[i,Yi(e,t+24),Yi(e,t+42)],c=a[0],l=a[1],u=a[2];return[Vi(e,t+10),c,l,s,o+Vi(e,t+30)+Vi(e,t+32),u]}(e,u,d),a=r[0],l=r[1],p=r[2],h=r[3],g=r[4],m=r[5],y=function(e,t){return t+30+Vi(e,t+26)+Vi(e,t+28)}(e,m);u=g;var b=function(e,t){e?(s(),i(e,null)):(t&&(o[h]=t),--c||i(null,o))};if(!f||f({name:h,size:l,originalSize:p,compression:a}))if(a)if(8==a){var w=e.subarray(y,y+l);if(p<524288||l>.8*p)try{b(null,Ji(w,{out:new zo(p)}))}catch(e){b(e,null)}else n.push(function(e,t,r){return r||(r=t,t={}),"function"!=typeof r&&Ti(7),Wi(e,t,[Mi],function(e){return Hi(Ji(e.data[0],Gi(e.data[1])))},1,r)}(w,{size:p},b))}else b(Ti(14,"unknown compression type "+a,1),null);else b(null,vi(e,y,y+l));else b(null,null)},g=0;g<l;++g)h()}else i(null,{});return s}),Ha=M(function(e,t,r){r||(r=t,t={}),"function"!=typeof r&&Ti(7);var n={};Xi(e,"",n,t);var s=Object.keys(n),o=s.length,i=0,a=0,c=o,l=new Array(o),u=[],d=function(){for(var e=0;e<u.length;++e)u[e]()},p=function(e,t){na(function(){r(e,t)})};na(function(){p=r});var f=function(){var e=new zo(a+22),t=i,r=a-i;a=0;for(var n=0;n<c;++n){var s=l[n];try{var o=s.c.length;ra(e,a,s,s.f,s.u,o);var u=30+s.f.length+ta(s.extra),d=a+u;e.set(s.c,d),ra(e,i,s,s.f,s.u,o,a,s.m),i+=16+u+(s.m?s.m.length:0),a=d+o}catch(e){return p(e,null)}}!function(e,t,r,n,s){qi(e,t,101010256),qi(e,t+8,r),qi(e,t+10,r),qi(e,t+12,n),qi(e,t+16,s)}(e,i,l.length,r,t),p(null,e)};o||f();for(var h=function(e){var t=s[e],r=n[t],c=r[0],h=r[1],g=function(){var e=-1;return{p:function(t){for(var r=e,n=0;n<t.length;++n)r=Di[255&r^t[n]]^r>>>8;e=r},d:function(){return~e}}}(),m=c.length;g.p(c);var y=ea(t),b=y.length,w=h.comment,v=w&&ea(w),I=v&&v.length,T=ta(h.extra),_=0==h.level?0:8,E=function(r,n){if(r)d(),p(r,null);else{var s=n.length;l[e]=Oi(h,{size:m,crc:g.d(),c:n,f:y,m:v,u:b!=t.length||v&&w.length!=I,compression:_}),i+=30+b+T+s,a+=76+2*(b+T)+(I||0)+s,--o||f()}};if(b>65535&&E(Ti(11,0,1),null),_)if(m<16e4)try{E(null,Ki(c,h))}catch(e){E(e,null)}else u.push(function(e,t,r){return r||(r=t,t={}),"function"!=typeof r&&Ti(7),Wi(e,t,[Fi],function(e){return Hi(Ki(e.data[0],e.data[1]))},0,r)}(c,h,E));else E(null,c)},g=0;g<c;++g)h(g);return d});async function Ga({content:e,filename:t,sensitiveValues:r}){const n=t.toLowerCase();return n.endsWith(".trace")||n.endsWith(".network")?function({content:e,sensitiveValues:t}){const r=new F,n=new H,s=r.decode(e).split("\n").map(e=>{if(!e.trim())return e;try{const r=function({event:e,sensitiveValues:t}){return(r=e,new Ua(r,Ra)).with({type:"console"},e=>({...e,args:e.args?.map(e=>({...e,preview:Da({sensitiveValues:t,str:e.preview}),value:Na({sensitiveValues:t,value:e.value})})),text:Da({sensitiveValues:t,str:e.text})})).with({type:"before"},e=>({...e,params:Ba({obj:e.params,sensitiveValues:t}),title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"after"},e=>({...e,error:ja({error:e.error,sensitiveValues:t}),result:void 0!==e.result?Na({sensitiveValues:t,value:e.result}):void 0})).with({type:"action"},e=>({...e,error:ja({error:e.error,sensitiveValues:t}),params:Ba({obj:e.params,sensitiveValues:t}),result:void 0!==e.result?Na({sensitiveValues:t,value:e.result}):void 0,title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"event"},e=>({...e,params:Ba({obj:e.params,sensitiveValues:t})})).with({type:"stdout"},{type:"stderr"},e=>({...e,text:void 0!==e.text?Da({sensitiveValues:t,str:e.text}):void 0})).with({type:"error"},e=>({...e,message:Da({sensitiveValues:t,str:e.message})})).with({type:"log"},e=>({...e,message:Da({sensitiveValues:t,str:e.message})})).with({type:"context-options"},e=>({...e,options:Ba({obj:e.options,sensitiveValues:t}),title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"frame-snapshot"},e=>({...e,snapshot:Ba({obj:e.snapshot,sensitiveValues:t})})).with({type:"resource-snapshot"},e=>({...e,snapshot:Ba({obj:e.snapshot,sensitiveValues:t})})).with({type:"screencast-frame"},{type:"input"},e=>e).exhaustive();var r}({event:JSON.parse(e),sensitiveValues:t});return JSON.stringify(r)}catch{return Da({sensitiveValues:t,str:e})}});return n.encode(s.join("\n"))}({content:e,sensitiveValues:r}):n.endsWith(".html")||n.endsWith(".dat")||n.endsWith(".json")?Ma({content:e,sensitiveValues:r}):n.startsWith("resources/")?async function({content:e,sensitiveValues:t}){return function(e){return function(e,t){if(function(e){return"string"==typeof e}(e)){!function(e){if(!e.isFile())throw new Error("Path provided was not a file!")}(S(e));const r=C(e,"r"),n=Buffer.alloc(515),s=R(r,n,0,515,0);return U(r),ca(n,s,t)}return ca(e,void 0!==t?.size?t.size:e.length,t)}(Buffer.from(e),{size:e.length})}(e)?e:Ma({content:e,sensitiveValues:t})}({content:e,sensitiveValues:r}):e}var Wa=e=>(e instanceof Error?e.message:String(e)).slice(0,400),Va=async e=>{const t=await Q(e,{withFileTypes:!0}),r=[];for(const s of t){const t=n.join(e,s.name);if(s.isDirectory())r.push(...await Va(t));else if(s.isFile()&&"trace.zip"===s.name){const e=await Z(t);r.push({path:t,mtimeMs:e.mtimeMs})}}return r},Ya=e=>"string"==typeof e&&e.length>0?e:void 0,za=({result:e,representativeTest:t})=>{const r=t.testTitle||t.filePath;return"captured"===e.status&&e.storage?`@[trace:${Buffer.from(JSON.stringify({...e.storage,...r?{label:r}:{}})).toString("base64url")}]`:void 0},qa=async({outputDir:e,tracePath:t,testFilePath:r,issueId:n,proofId:s,testCaseId:o,requestUploadUrl:i})=>{ls.info("[upload-trace-proof] Uploading trace",{testFilePath:r,issueId:n,testCaseId:o,outputDir:e});const a=await(async({tracePath:e,outputDir:t,requestUploadUrl:r})=>{try{let n=e;if(!n){if(!t)return{status:"capture_failed",error:"Either tracePath or outputDir must be provided."};if(!E(t))return{status:"capture_failed",error:`Output directory does not exist: ${t}`};n=await(async e=>{const t=await Va(e);if(0!==t.length)return t.sort((e,t)=>t.mtimeMs-e.mtimeMs),t[0]?.path})(t)}if(!n)return{status:"capture_failed",error:"No trace.zip found in the output directory."};const{traceBucketPath:s,uploadUrl:o,sensitiveValues:i}=await r(),a=await async function({tracePath:e,sensitiveValues:t}){const r=[],n=P(e);for await(const e of n)r.push(e);return async function({sensitiveValues:e,traceBuffer:t}){const r=e.filter(e=>!(e.length<3||la.some(t=>t.test(e))||ua.some(t=>e.includes(t))));if(0===r.length)return new Uint8Array(t);const n=[...r].sort((e,t)=>t.length-e.length),s=await Fa(new Uint8Array(t)),o=Object.entries(s),i=await Promise.all(o.map(async([e,t])=>[e,await Ga({content:t,filename:e,sensitiveValues:n})])),a=Object.fromEntries(i);return Ha(a)}({traceBuffer:new Uint8Array(Buffer.concat(r)),sensitiveValues:t})}({tracePath:n,sensitiveValues:i});try{await xs({body:a,contentType:"application/zip",uploadUrl:o,errorContext:"trace"})}catch(e){return{status:"upload_failed",error:Wa(e)}}return{status:"captured",storage:s}}catch(e){return{status:"upload_failed",error:Wa(e)}}})({tracePath:t,outputDir:e,requestUploadUrl:()=>i({testFilePath:r,issueId:n,proofId:s,testCaseId:o})});return"captured"===a.status?ls.info("[upload-trace-proof] Upload succeeded",{testFilePath:r,traceBucketPath:a.storage}):ls.error("[upload-trace-proof] Failed",{testFilePath:r,error:a.error}),a},Ka=({requestUploadUrl:e,onTraceUploaded:t})=>W("upload-trace-proof",["Upload a Playwright trace proof for a test.","","IMPORTANT: This tool does NOT run tests. You must run the test yourself first","using Playwright with tracing enabled and --output <dir>, then call this tool to upload the trace.","","You MUST provide testFilePath and at least one of outputDir or tracePath.","You MUST also provide testPassed (true if the test exit code was 0, false otherwise).","Only passing traces are uploaded as proof."].join("\n"),{outputDir:we.string().min(1).optional().describe("The --output directory from the Playwright test run containing trace.zip. Required if tracePath is not provided."),tracePath:we.string().min(1).optional().describe("Optional direct path to trace.zip. If omitted, the newest trace in outputDir is used."),testFilePath:we.string().min(1).describe("Path to the test file (relative to the project working directory)."),testPassed:we.boolean().describe("Whether the test run passed (exit code 0). You MUST check the exit code of stably-browser run-test before calling this tool. Exit code 0 = passed, non-zero = failed. Only passing traces are uploaded."),representativeTest:Wo.optional().default({})},async({outputDir:r,tracePath:n,testFilePath:s,testPassed:o,representativeTest:i})=>{const a=Ya(s);if(!a)throw new Error("testFilePath is required for create-mode trace uploads");if("boolean"!=typeof o)throw new Error("testPassed is required for create-mode trace uploads");if(!o)return ls.info("[upload-trace-proof] Skipping upload for failing test",{testFilePath:a}),{content:[{type:"text",text:JSON.stringify({status:"skipped",testFilePath:a,testPassed:!1,reason:"Test failed β only passing traces are uploaded as trace proofs. Fix the test and re-run before uploading."})}]};const c=Wo.parse(i??{}),l=Ya(n),u=Ya(r),d=await qa({outputDir:u,tracePath:l,testFilePath:a,requestUploadUrl:e}),p=za({representativeTest:c,result:d}),f={testFilePath:a,status:d.status,storage:"captured"===d.status?d.storage:null,..."error"in d?{error:d.error}:{}};t?.(f);const h={...d,testFilePath:a,...null!=p?{tracePlaceholder:p}:{}};return{content:[{type:"text",text:JSON.stringify(h)}]}}),Ja=({requestUploadUrl:e,onTraceUploaded:t})=>W("upload-trace-proof",["Upload a Playwright trace proof for a test case.","","IMPORTANT: This tool does NOT run tests. You must run the test yourself first","using Playwright with tracing enabled and --output <dir>, then call this tool to upload the trace.","","MANDATORY: Call for EVERY testCaseId in your issue, whether fixed or unfixed.","- Fixed: Trace proves the fix works","- Unfixed: Trace shows the failure state for auditability","","Pass the outputDir that was used as the --output flag in your test run.","Optionally pass tracePath if you know the exact path to the trace.zip file."].join("\n"),{outputDir:we.string().min(1).optional().describe("The --output directory from the Playwright test run containing trace.zip. Required if tracePath is not provided."),tracePath:we.string().min(1).optional().describe("Optional direct path to trace.zip. If omitted, the newest trace in outputDir is used."),issueId:we.string().min(1).describe("Issue identifier for deterministic output paths and storage key naming."),proofId:we.string().min(1).optional().describe("Optional id for deterministic proof naming and deduplication."),testCaseId:we.string().min(1).optional().describe("Optional test case ID when uploading per-test trace proofs."),testPassed:we.boolean().describe("Whether the test run passed (exit code 0). You MUST check the exit code of stably-browser run-test before calling this tool. Exit code 0 = passed, non-zero = failed."),representativeTest:Wo.optional().default({})},async({outputDir:r,tracePath:n,issueId:s,proofId:o,representativeTest:i,testCaseId:a,testPassed:c})=>{const l=Ya(s);if(!l)throw new Error("issueId is required for fix-mode trace uploads");if("boolean"!=typeof c)throw new Error("testPassed is required for fix-mode trace uploads");const u=Ya(o),d=Ya(a),p=Wo.parse(i??{}),f=Ya(n),h=Ya(r),g=await qa({outputDir:h,tracePath:f,issueId:l,proofId:u,testCaseId:d,requestUploadUrl:e}),m=za({representativeTest:p,result:g}),y={issueId:l,representativeTest:p,status:g.status,storage:"captured"===g.status?g.storage:null,...null!=d?{testCaseId:d}:{},testPassed:c,..."error"in g?{error:g.error}:{}};t?.(y);const b={...g,...null!=d?{testCaseId:d}:{},...null!=m?{tracePlaceholder:m}:{},representativeTest:p,testPassed:c},w=c?"":'\n\nWARNING: testPassed=false β this trace documents a FAILURE, not a successful fix. Do NOT report result:"fixed" for this test. If you applied a fix but the verification run failed (e.g., auth setup error, missing env vars), the fix is NOT proven. Report result:"unfixed" with the failure reason.';return{content:[{type:"text",text:JSON.stringify(b)+w}]}}),Xa=({requestUploadUrl:e,onTraceUploaded:t})=>G({name:"upload-trace-proof",tools:[Ka({requestUploadUrl:e,onTraceUploaded:t})]}),Qa=({authProvider:e,diffTracker:t,orgId:r,runId:n,workingDir:s})=>G({name:"auto-heal-report",tools:[Ja({requestUploadUrl:t=>{const{issueId:s}=t;return s?e.getAuthHeader().then(e=>(async({authHeader:e,issueId:t,proofId:r,testCaseId:n,contentType:s="application/zip",orgId:o,runId:i})=>{const a=await(c={auth:e,body:{contentType:s,issueId:t,proofId:r,testCaseId:n},client:In(),headers:_s(o),path:{runId:i}},(c.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-trace/upload-url",...c,headers:{"Content-Type":"application/json",...c.headers}}));var c;if(a.error)throw new Error(`Failed to presign trace upload (${a.response.status})`);const l=ks.parse(a.data);return{traceBucketPath:l.traceBucketPath,expiresInSeconds:l.expiresInSeconds,key:l.key,uploadUrl:l.uploadUrl,sensitiveValues:l.sensitiveValues}})({authHeader:e,issueId:s,proofId:t.proofId,orgId:r,runId:n,testCaseId:t.testCaseId})):Promise.reject(new Error("issueId is required for fix-mode trace uploads"))}}),W("generate-report",["After attempting to fix all broken tests (skip only those truly infeasible), generate a markdown auto-heal report.","","The UI renders this markdown into structured cards based on ## and ### headings. Follow the heading structure from the MARKDOWN REPORT STRUCTURE section in your instructions:","- ## Summary, ## Fixed Issues (with ### per issue), ## Unfixed Issues (with ### per issue)",'- Each ### must be a short descriptive slug (e.g. "invite-member-flaky-timeouts")',"- Use **bold labels:** for fields (Tests, Flaky signal, Root cause, Fix applied, Why not fixed, Proof of fixed tests)","- Include **Flaky signal:** inside an issue card only when triage flagged that test as flaky β do NOT create a separate ## section for flaky signals","","Write for readability: keep bullets concise, use tables only when they genuinely improve scanability, and wrap file paths, commands, selectors, and code in backticks.","Prefer short sections over long paragraphs. Call out important outcomes first, then supporting evidence.","","ENTITY REFERENCES: When referencing entities by ID, use placeholder syntax so the UI can render clickable links:","- Test cases: @[test-case:<id>] (e.g., @[test-case:fp8f0yzdqqut6bg7cy5euzer])","- Suite runs: @[suite-run:<id>] (e.g., @[suite-run:cm6i7o6ti0000l40350wys0u1])","- Tests: @[test:<id>] (e.g., @[test:wty0g1v58cwrrd8jj6et8nmx])","- Traces: use the tracePlaceholder value returned by upload-trace-proof (e.g., @[trace:eyJi...])","These placeholders will be automatically resolved to clickable links with human-readable labels in the UI.","NEVER show raw entity IDs without wrapping them in @[type:id] syntax."].join("\n"),{markdown:Go.shape.markdown,summary:Go.shape.summary,issues:Go.shape.issues},async({markdown:s,summary:o,issues:i})=>{const a=await e.getAuthHeader(),c=await t.computeDiff(),l=Go.parse({format:"markdown",markdown:s,summary:o,issues:i});try{await(async({authHeader:e,orgId:t,report:r,runId:n})=>{const s=await(o={auth:e,body:{report:JSON.stringify(r)},client:In(),headers:_s(t),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-report",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to upload auto-heal report (${s.response.status})`)})({authHeader:a,orgId:r,report:l,runId:n});const{diffBucketPath:e,uploadUrl:t}=await Ps({authHeader:a,contentType:"text/plain",orgId:r,runId:n});await xs({body:c,contentType:"text/plain",uploadUrl:t,errorContext:"diff"}),await Cs({authHeader:a,diffBucketPath:e,orgId:r,runId:n})}catch(e){return console.error("[auto-heal-report] Failed to upload report or diff:",e),{content:[{text:"Error: Failed to upload auto-heal report or diff. Please surface this to the user, and terminate the session.",type:"text"}]}}return{content:[{text:"Auto-heal report generated. You may terminate this session now.",type:"text"}]}})],version:"0.0.1"});function Za({workingDir:e,packageManager:t,packageSpec:r,targetSection:n}){const{command:s,args:o}=function(e,t,r){const n="npm"===e?"npm":e;return{command:n,args:["npm"===e?"install":"add",..."devDependencies"===r?["bun"===e?"-d":"-D"]:[],..."npm"===n?["--no-fund"]:[],t]}}(t,r,n);y(s,o,{cwd:e,stdio:"pipe",timeout:6e4})}function ec(e){const t=r.join(e,"package.json");return w.existsSync(t)?{path:t,contents:JSON.parse(w.readFileSync(t,"utf-8"))}:null}var tc=["playwright.config.ts","playwright.config.js","playwright.config.mts","playwright.config.mjs","playwright.config.cjs"];function rc(e){return tc.some(t=>w.existsSync(r.join(e,t)))}function nc(e,t){const n=w.readdirSync(e,{withFileTypes:!0}),s=[];for(const o of n){if("node_modules"===o.name||".git"===o.name)continue;const n=r.join(e,o.name);o.isDirectory()?s.push(...nc(n,t)):t.test(o.name)&&s.push(n)}return s}function sc(e){let t=r.resolve(e);for(;;){if(rc(t))return t;const n=r.dirname(t);if(n===t)return e;t=n}}function oc(e){const t=Array.from(new Set(e.map(e=>r.resolve(e)))).sort((e,t)=>e.length-t.length),n=[];for(const e of t)n.some(t=>e===t||e.startsWith(`${t}${r.sep}`))||n.push(e);return n}function ic(e){return/\b(test|testing|playwright|e2e|stably)\b/i.test(e)}function ac(e,t){for(const n of cc(e,t))if(w.existsSync(r.join(n,"package.json")))return n}function cc(e,t){const n=[];let s=r.resolve(e);const o=r.resolve(t);for(;n.push(s),s!==o;){const e=r.dirname(s);if(e===s)break;s=e}return n}function lc(e){return e?.replace(/^[~^>=<]+/,"")}function uc(e){let t=e;for(let e=0;e<5;e++){if(w.existsSync(r.join(t,"pnpm-lock.yaml")))return"pnpm";if(w.existsSync(r.join(t,"yarn.lock")))return"yarn";if(w.existsSync(r.join(t,"bun.lockb"))||w.existsSync(r.join(t,"bun.lock")))return"bun";if(w.existsSync(r.join(t,"package-lock.json"))||w.existsSync(r.join(t,"npm-shrinkwrap.json")))return"npm";const e=r.dirname(t);if(e===t)break;t=e}return"npm"}var dc=we.object({commentUrl:we.string()}),pc=({prContext:e,authProvider:t,orgId:r,onReportPosted:n})=>G({name:"create-report",tools:[W("post_create_report",`Post a test creation report as a GitHub comment on PR #${e.prNumber}.\nCall this tool at the end of test creation to summarize what was created.\nThe report will be posted to: ${e.prUrl}\n\nWHEN TO USE:\n- After you have finished creating test files\n- To provide a summary of the tests created on the PR for visibility\n\nThe report will include:\n- A list of all test files created\n- Your summary of what was tested`,{summary:we.string().describe("A summary of the tests created. Include what features/flows are tested and any important notes."),filesCreated:we.array(we.string()).describe("List of test file paths that were created (relative to workspace root)")},async({summary:s,filesCreated:o})=>{const i=await t.getAuthHeader(),a=Array.isArray(o)?o:[];ls.info("[create-report] Posting report to GitHub PR",{prNumber:e.prNumber,filesCount:a.length});try{const t={summary:"string"==typeof s?s:String(s),filesCreated:a.map(String)},o=await async function({authHeader:e,orgId:t,prNumber:r,owner:n,repo:s,report:o}){const i=new URL("/internal/v1/cli/create-report",fn).toString(),a={Authorization:e,"Content-Type":"application/json"};t&&(a["x-stably-org-id"]=t),ls.debug("Posting create report to GitHub",{prNumber:r,owner:n,repo:s,filesCount:o.filesCreated.length});const c=await fetch(i,{method:"POST",headers:a,body:JSON.stringify({prNumber:r,owner:n,repo:s,report:o}),signal:AbortSignal.timeout(3e4)});if(!c.ok){const e=await c.text().catch(()=>"");throw ls.error("Failed to post create report",{status:c.status,error:e.slice(0,500)}),new Error(`Failed to post create report: ${c.status} ${e.slice(0,200)}`)}const l=dc.parse(await c.json());return ls.info("Create report posted successfully",{commentUrl:l.commentUrl}),l}({authHeader:i,orgId:r,prNumber:e.prNumber,owner:e.owner,repo:e.repo,report:t});return n?.(o),ls.info("[create-report] Report posted successfully",{commentUrl:o.commentUrl}),{content:[{type:"text",text:`β
Test creation report posted to PR #${e.prNumber}\n\nView the comment: ${o.commentUrl}`}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[create-report] Failed to post report",{error:t}),{content:[{type:"text",text:`β Failed to post report to GitHub: ${t}\n\nThe tests were still created successfully, but the PR comment could not be posted.`}],isError:!0}}})]}),fc=we.object({traceBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string(),sensitiveValues:we.array(we.string())}),hc=["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","CANCELLED","INTERRUPTED"],gc=["LOCAL","CI","WEB"],mc=["MANUAL","SCHEDULED","UI","API","GITHUB_ACTION","SUITE_RUN"],yc=({authProvider:e,orgId:t,projectId:r})=>G({name:"run-history",tools:[W("list_runs",'List test runs with optional filters for the current project.\nUse this to find runs with autoheal status on specific branches.\n\nCommon use cases:\n- Find failed runs on the current branch: { "branch": "feature-x", "status": "FAILED", "limit": 10 }\n- Find failed runs on master/main: { "branch": "master", "status": "FAILED", "limit": 10 }\n- Find the most recent run: { "limit": 1 }\n\nIf the user asks about test failures without specifying a run, use this to discover recent failed runs.\n\nReturns an array of runs with their runId, status, autoHealStatus, branch, and timestamps.',{branch:we.string().optional().describe("Filter by branch name"),status:we.enum(hc).optional().describe("Filter by status: QUEUED|RUNNING|PASSED|FAILED|TIMEDOUT|CANCELLED|INTERRUPTED"),limit:we.number().min(1).max(100).optional().describe("Max results (1-100, default 20)"),source:we.enum(gc).optional().describe("Filter by source: LOCAL|CI|WEB"),trigger:we.enum(mc).optional().describe("Filter by trigger: MANUAL|SCHEDULED|UI|API|GITHUB_ACTION|SUITE_RUN"),suite:we.string().optional().describe("Filter by suite name"),after:we.string().optional().describe("Pagination: return runs after this runId"),before:we.string().optional().describe("Pagination: return runs before this runId")},async({branch:n,status:s,limit:o,source:i,trigger:a,suite:c,after:l,before:u})=>{const d=await e.getAuthHeader(),p="string"==typeof n?n:void 0,f="string"==typeof s?s:void 0,h="number"==typeof o?o:void 0,g="string"==typeof i?i:void 0,m="string"==typeof a?a:void 0,y="string"==typeof c?c:void 0,b="string"==typeof l?l:void 0,w="string"==typeof u?u:void 0;ls.info("[run-history] list_runs called",{branch:p,status:f,limit:h});try{const e=await un({auth:d,client:In(),headers:_s(t),query:{projectId:r,branchName:p,status:f,limit:h,source:g,trigger:m,suiteName:y,afterRunId:b,beforeRunId:w}});if(e.error||!e.data){const t=e.response?`API error: ${e.response.status}`:`API error: ${String(e.error)}`;return ls.error("[run-history] list_runs failed",{error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}return ls.info("[run-history] list_runs success",{runCount:e.data.runs?.length??0,hasMore:e.data.hasMore}),{content:[{type:"text",text:JSON.stringify(e.data)}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[run-history] list_runs exception",{error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}}),W("view_run",'Get detailed information about a specific run including issues and test results.\n\nThe response includes:\n- Run metadata (status, branch, timestamps, envName)\n- Issues array with result ("fixed"/"unfixed"), rootCause, and relatedTestIdentifiers\n- Test results with their outcomes\n- envName: the remote environment used (e.g., "staging") β if present, call load_environment with this name before rerunning tests\n\nUse this to examine run details and determine which tests failed or were previously fixed.',{runId:we.string().min(1).describe("The run ID to view (required)")},async({runId:r})=>{const n=await e.getAuthHeader(),s="string"==typeof r?r:String(r);ls.info("[run-history] view_run called",{runId:s});try{const e=await dn({auth:n,client:In(),headers:_s(t),path:{runId:s},query:{detail:"full"}});if(e.error||!e.data){const t=e.response?404===e.response.status?`Run "${s}" not found`:`API error: ${e.response.status}`:`API error: ${String(e.error)}`;return ls.error("[run-history] view_run failed",{error:t,runId:s}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}return ls.info("[run-history] view_run success",{runId:s}),{content:[{type:"text",text:JSON.stringify(e.data)}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[run-history] view_run exception",{error:t,runId:s}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}})]});function bc({localEnv:e,remoteEnv:t,remoteSensitiveValues:r,processEnv:n=process.env}){const s={};for(const[t,r]of Object.entries(e))void 0===n[t]&&(s[t]=r);if(t)for(const[r,o]of Object.entries(t))void 0===n[r]&&void 0===e[r]&&(s[r]=o);return r?.length&&void 0===n.STABLY_SENSITIVE_VALUES&&(s.STABLY_SENSITIVE_VALUES=Buffer.from(JSON.stringify(r)).toString("base64")),s}var wc=({hookEnvVars:e,localEnvSnapshot:t})=>G({name:"environment",tools:[W("load_environment",'Load remote environment variables by name (e.g., "staging", "production").\nUse this when you discover a run was executed with a specific --env and need\nthose variables for rerunning tests.\n\nAfter loading, all subsequent stably-browser run-test commands will automatically\nhave these environment variables injected. Use process.env.VARNAME syntax in test\ncode for these variables.\n\nReturns the list of variable names loaded (never values, for security).',{envName:we.string().min(1).describe('Environment name to load (e.g., "staging")')},async({envName:r})=>{const n="string"==typeof r?r:String(r);ls.info("[load-environment] Loading environment",{envName:n});try{const r=await Is(n);if(!r.ok)return ls.warn("[load-environment] Failed to load environment",{envName:n,error:r.error}),{content:[{type:"text",text:`Error: ${r.error}`}],isError:!0};const s=bc({localEnv:t??{},remoteEnv:r.result.variables,remoteSensitiveValues:r.result.sensitiveValues});for(const t of Object.keys(e))delete e[t];Object.assign(e,s);const o=Object.keys(r.result.variables);return ls.info("[load-environment] Environment loaded",{envName:n,variableCount:o.length}),{content:[{type:"text",text:`Successfully loaded ${o.length} variable(s) from "${n}" environment.\n\nVariable names: ${o.join(", ")}\n\nThese are now available for stably-browser run-test commands. Use \`process.env.VARNAME\` syntax in test code for these variables.`}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[load-environment] Exception loading environment",{envName:n,error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}})]}),vc=e=>e.replace(/Bearer\s+[A-Za-z0-9._-]+/gi,"Bearer [redacted]").replace(/\bsk-[A-Za-z0-9_-]{16,}\b/g,"[redacted]").replace(/\bstably_[A-Za-z0-9_-]{16,}\b/g,"[redacted]"),Ic=(e,t)=>({message:vc(e),status:t?.status,statusText:t?.statusText}),Tc=["ANTHROPIC_","CLAUDE"],_c=new Set(["AWS_BEARER_TOKEN_BEDROCK","BASH_DEFAULT_TIMEOUT_MS","BASH_MAX_OUTPUT_LENGTH","BASH_MAX_TIMEOUT_MS","DISABLE_AUTOUPDATER","DISABLE_BUG_COMMAND","DISABLE_COST_WARNINGS","DISABLE_ERROR_REPORTING","DISABLE_NON_ESSENTIAL_MODEL_CALLS","DISABLE_PROMPT_CACHING","DISABLE_PROMPT_CACHING_HAIKU","DISABLE_PROMPT_CACHING_OPUS","DISABLE_PROMPT_CACHING_SONNET","DISABLE_TELEMETRY","HTTP_PROXY","HTTPS_PROXY","MAX_MCP_OUTPUT_TOKENS","MAX_THINKING_TOKENS","MCP_TIMEOUT","MCP_TOOL_TIMEOUT","NO_PROXY","SLASH_COMMAND_TOOL_CHAR_BUDGET","USE_BUILTIN_RIPGREP","VERTEX_REGION_CLAUDE_3_5_HAIKU","VERTEX_REGION_CLAUDE_3_7_SONNET","VERTEX_REGION_CLAUDE_4_0_OPUS","VERTEX_REGION_CLAUDE_4_0_SONNET","VERTEX_REGION_CLAUDE_4_1_OPUS"]),Ec=async({authHeader:e,mode:t,maxTurnsOverride:r})=>{const n=In();ls.debug("Requesting subagent definitions from API",{mode:t,maxTurnsOverride:r});const s=await(o={client:n,auth:e,body:{mode:t,maxTurnsOverride:r}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/prompts/subagents",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(401===s.response.status)throw ls.warn("Subagent definitions fetch failed: unauthorized (401)"),await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");if(403===s.response.status)throw ls.debug("Subagent definitions fetch failed: forbidden (403)"),new Error("Your organization does not have an active subscription. Manage your subscription at https://app.stably.ai or contact your organization admin.");if(s.error)throw ls.warn("Subagent definitions fetch failed",{error:s.error}),new Error("Failed to fetch subagent definitions. Please check your network connection and try again. If this persists, run `stably login` to re-authenticate.");const{subagents:i}=s.data;return ls.debug("Subagent definitions received",{count:Object.keys(i).length}),i},Sc=n.dirname(L(import.meta.url)),xc=n.join(".claude-plugin","plugin.json"),Ac=[n.join("packages","agent-plugin","stably-plugin-cli"),n.join("agent-plugin","stably-plugin-cli")];function kc(e){return E(n.join(e,xc))}var{zStablyYaml:Pc}=function(e){const t=e.object({cron:e.string(),stablyTestArgs:e.string().optional(),timezone:e.string().optional(),command:e.string().optional(),autofix:e.boolean().optional()}),r=e.object({maxTurnsPerIssue:e.number().int().positive().default(200),maxParallelWorkers:e.number().int().positive().default(3),rules:e.string().optional(),skipAfterConsecutiveUnfixed:e.number().int().positive().default(3),maxBudgetUsd:e.number().positive().default(50)}),n=e.object({maxTurnsPerTestFile:e.number().int().positive().default(200),maxBudgetUsd:e.number().positive().default(50)}),s=e.object({fix:r.optional(),create:n.optional()}),o=e.object({setupScript:e.string().optional()});return{zStablyYaml:e.object({schedules:e.record(e.string(),t).optional(),agent:s.optional(),cloud:o.optional()}),zAgentConfig:s,zAgentFixConfig:r,zAgentCreateConfig:n,zScheduleEntry:t,zCloudConfig:o}}(he),Cc=async(e,t)=>{try{const r=await kn(e,t);if(!r)return void ls.debug(`No ${t} found`);const n=await z(r,"utf-8");if(!n.trim())return;return n.length>1e4?(ls.warn(`${t} exceeds max length (${n.length} > 10000), truncating`,{path:r}),{content:n.slice(0,1e4),path:r}):(ls.debug(`Loaded ${t} rules`,{path:r,contentLength:n.length}),{content:n,path:r})}catch(e){return void ls.warn(`Failed to read ${t}`,{error:e})}},Rc=/(?<![./])\bstably-browser\b/,Uc=/\bpwtrace\b/,Lc="(?:(?:-\\w+=?\\S*|--\\w+=?\\S*|-s\\s+\\S+|--session\\s+\\S+)\\s+)*",$c=new RegExp(`\\bstably-browser\\s+${Lc}run-test\\b`),Dc=/\$\{process\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\}/g,Nc=e=>/^[A-Za-z0-9_./:@=-]+$/.test(e)?e:`'${e.replace(/'/g,"'\\''")}'`,Oc=".stably-browser";async function Bc(){const e=i(o(L(import.meta.url)),"stably-browser.js");if(E(e))return e;ls.debug("[stably-browser-hook] Bundled binary not found",{checkedPath:e});try{return Re.resolve("@stablyai-internal/playwright-cli/playwright-cli.js")}catch{ls.debug("[stably-browser-hook] @stablyai-internal/playwright-cli not resolvable from node_modules")}return new Promise((e,t)=>{m("which",["stably-browser"],(r,n)=>{if(r||!n.trim())return ls.warn("[stably-browser-hook] stably-browser not found on PATH",{error:r?.message}),void t(new Error("stably-browser not found. Ensure @stablyai-internal/playwright-cli is installed or stably-browser is on PATH."));e(n.trim())})})}async function jc(){const e=i(o(L(import.meta.url)),"pwtrace.js");if(E(e))return e;try{return Re.resolve("@stablyai-internal/pwtrace/bin/cli.js")}catch{}return new Promise((e,t)=>{m("which",["pwtrace"],(r,n)=>{!r&&n.trim()?e(n.trim()):t(new Error("pwtrace not found. Ensure @stablyai-internal/pwtrace is installed or pwtrace is on PATH."))})})}function Mc(e,t,r=!1){const n=`${e}\n${t}`;return n.includes("spawn")&&n.includes("ENOENT")&&!n.includes("Executable doesn't exist")?{permanent:!0,reason:"Browser binary exists but cannot be executed (likely Alpine Linux / musl libc incompatibility).",guidance:"The Chromium binary was downloaded but the OS cannot execute it. This usually happens on Alpine Linux containers because Chromium is compiled for glibc, not musl. Ask the user to either: (1) switch to a glibc-based image like node:20-slim instead of node:20-alpine, (2) install glibc compatibility with `apk add gcompat`, or (3) use the official Playwright Docker image (mcr.microsoft.com/playwright). Do not attempt to install browsers β they are already installed, the issue is OS-level. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("is not installed")||n.includes("Executable doesn't exist")?{permanent:!0,reason:"Browser is not installed in this environment.",guidance:"The Playwright browser binary is missing. Ask the user to run `npx playwright install chromium` in their environment (or add it to their Dockerfile/CI setup). Do not attempt to install browsers yourself. You can still analyze test code, make fixes, and use upload-trace-proof (it only uploads existing traces, no browser needed), but cannot run tests locally until browsers are installed. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("Missing system dependencies")||n.includes("cannot open shared object file")?{permanent:!0,reason:"Browser system dependencies are missing.",guidance:"The browser binary exists but required system libraries are missing. Ask the user to run `npx playwright install-deps chromium` (requires apt/sudo) or use a Playwright Docker image. Do not attempt to install system packages yourself. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("already in use")?{permanent:!1,reason:"Browser profile is locked by another process.",guidance:"Another browser session is using the same profile. Try closing the existing session with `stably-browser close` first, or use a different session name."}:n.includes("sandboxing failed")||n.includes("--no-sandbox")?{permanent:!0,reason:"Browser sandboxing failed (likely running as root in a container).",guidance:"Chrome cannot create a sandbox when running as root. Ask the user to either: (1) add `chromiumSandbox: false` to their Playwright launch options, (2) add `--no-sandbox` to their Chrome args, or (3) run the container as a non-root user. Do not attempt to fix this yourself β it requires changes to the user's Playwright config or Docker setup. Do not retry stably-browser commands β they will all fail for the same reason."}:r||e.includes("ETIMEDOUT")||e.includes("timed out")?{permanent:!1,reason:"Daemon startup timed out.",guidance:"The browser daemon did not start within 30 seconds. This may be caused by slow browser download, resource constraints, or a hung process. Retry once, and if it fails again, ask the user to check their environment."}:{permanent:!1,reason:n.slice(0,500).trim(),guidance:"An unexpected error occurred starting the browser daemon. Share the error with the user."}}async function Fc(e,t,r,n,s="chromium"){const o=["open",`-s=${t}`];let i;return r&&o.push("--headed"),n?o.push(`--config=${n}`):o.push(`--browser=${s}`),ls.info("[stably-browser-hook] Starting daemon",{bin:e,args:o}),process.env.CHROME_BIN&&(i={...process.env,PLAYWRIGHT_MCP_EXECUTABLE_PATH:process.env.CHROME_BIN}),"linux"===process.platform&&"function"==typeof process.getuid&&0===process.getuid()&&(i={...i??process.env,PLAYWRIGHT_MCP_SANDBOX:"false"},ls.info("[stably-browser-hook] Running as root on Linux, disabling Chromium sandbox")),new Promise(t=>{m(process.execPath,[e,...o],{timeout:3e4,env:i},(e,r,n)=>{if(e)return ls.error("[stably-browser-hook] Failed to start daemon",{error:e.message,stderr:n}),void t({ok:!1,...Mc(e.message,n??"",e.killed??!1)});ls.info("[stably-browser-hook] Daemon started",{stdout:r.trim()}),t({ok:!0})})})}function Hc(e,t){return t?`${e}-${t}`:e}function Gc(e){if(e&&"object"==typeof e&&"agent_id"in e){const t=e.agent_id;return"string"==typeof t?t:void 0}}async function Wc(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}`,fn);n.searchParams.set("projectId",r);const s=await fetch(n.toString(),{method:"GET",headers:{Authorization:`Bearer ${e}`}});if(!s.ok)throw new Error(`Poll failed: HTTP ${s.status}`);return s.json()}async function Vc(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/acquire`,fn).toString(),s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});if(!s.ok)throw new Error(`Acquire failed: HTTP ${s.status}`);return s.json()}async function Yc(e,t,r){const n=new URL(`/internal/v1/cli/browser/kernelsh/${r}/health`,fn);n.searchParams.set("projectId",t);const s=n.toString();try{const t=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e}`}});return!!t.ok&&(await t.json()).alive}catch{return!1}}var zc=2e3,qc=class{authProvider;projectId;sessions=new Map;healthCheckTimer=null;released=!1;configDir=null;constructor(e){this.authProvider=e.authProvider,this.projectId=e.projectId}async acquire(e,t){const r=this.sessions.get(e);if(r&&!r.needsRecreation)return r.session;r?.needsRecreation&&await this.releaseSession(e),this.released=!1;const n=await this.acquireViaQueue(t);ls.info("[cloud-browser] Waiting for CDP endpoint to be ready...",{sessionName:e,sessionId:n.sessionId}),await async function(e){const t=Date.now()+3e4;for(;Date.now()<t;)try{return void await new Promise((t,r)=>{const n=new ve(e),s=setTimeout(()=>{n.close(),r(new Error("CDP connection timeout"))},5e3);n.on("open",()=>{n.send(JSON.stringify({id:1,method:"Browser.getVersion",params:{}}))}),n.on("message",e=>{try{const o=JSON.parse(e.toString());1===o.id&&(clearTimeout(s),n.close(),o.error?r(new Error(`CDP error: ${o.error.message}`)):t())}catch{}}),n.on("error",e=>{clearTimeout(s),n.close(),r(e)})})}catch(e){const r=t-Date.now();if(r<=500)throw new Error(`CDP endpoint not ready after 30000ms: ${e instanceof Error?e.message:String(e)}`);ls.debug("[cloud-browser] CDP not ready, retrying...",{error:e instanceof Error?e.message:String(e),remainingMs:r}),await Kc(500)}throw new Error("CDP endpoint not ready after 30000ms")}(n.cdpUrl),ls.info("[cloud-browser] CDP endpoint ready",{sessionName:e,sessionId:n.sessionId});const s=this.writeConfig(e,n.cdpUrl);return this.sessions.set(e,{session:n,configPath:s,needsRecreation:!1}),this.ensureHealthCheck(),n}async release(){if(this.released)return;this.released=!0,this.stopHealthCheck();const e=Array.from(this.sessions.keys()).map(e=>this.releaseSession(e));await Promise.all(e),this.cleanupConfigDir()}needsRecreation(e){return this.sessions.get(e)?.needsRecreation??!1}getConfigPath(e){return this.sessions.get(e)?.configPath??null}getAnyConfigPath(){for(const e of this.sessions.values())if(!e.needsRecreation)return e.configPath;return null}isActive(){return this.sessions.size>0&&!this.released}removeSession(e){this.sessions.delete(e)}async acquireViaQueue(e){const t=await this.authProvider.getAuthHeader(),r=await async function(e,t){const r=new URL("/internal/v1/browser/request",fn).toString();try{const n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:t,source:"cli-browser-session"})});if(n.ok||202===n.status){const e=await n.json();return{ok:!0,browserRequestId:e.browserRequestId,initialStatus:e.status}}if(403===n.status)return{ok:!1,status:"forbidden",message:(await n.json().catch(()=>({error:"Forbidden"}))).error??"Cloud browsers not available on your plan."};const s=await n.text().catch(()=>"");return{ok:!1,status:"error",message:`HTTP ${n.status}: ${s.slice(0,200)}`}}catch(e){return{ok:!1,status:"error",message:e instanceof Error?e.message:String(e)}}}(t,this.projectId);if(!r.ok){if("forbidden"===r.status)throw new Error(`Cloud browsers not available on your plan. ${r.message}`);throw new Error(`Cloud browser unavailable: ${r.message}`)}const{browserRequestId:n,initialStatus:s}=r;"queued"===s&&e?.();const o=Date.now()+3e5;for(;Date.now()<o;){const t=await this.authProvider.getAuthHeader(),r=await Wc(t,n,this.projectId);switch(r.status){case"pending":await Kc(zc);continue;case"queued":e?.(),await Kc(zc);continue;case"provisioning":ls.debug("[cloud-browser] Browser is starting up..."),await Kc(zc);continue;case"ready":try{const e=await this.authProvider.getAuthHeader(),t=await Vc(e,n,this.projectId);return{sessionId:t.sessionId,browserRequestId:n,cdpUrl:t.cdpUrl,liveViewUrl:t.liveViewUrl??""}}catch{ls.debug("[cloud-browser] Acquire failed, re-polling status"),await Kc(zc);continue}case"failed":throw new Error(r.error??"Browser provisioning failed. Please try again.");case"cancelled":case"stopped":throw new Error("Browser request was cancelled.");default:throw new Error(`Unexpected browser request status: ${r.status}`)}}const i=await this.authProvider.getAuthHeader();throw await async function(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/cancel`,fn).toString();try{const s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});s.ok||ls.warn("[cloud-browser] Failed to cancel browser request",{browserRequestId:t,status:s.status})}catch(e){ls.warn("[cloud-browser] Error cancelling browser request",{browserRequestId:t,error:e instanceof Error?e.message:String(e)})}}(i,n,this.projectId).catch(()=>{}),new Error("Cloud browser unavailable: timed out waiting for provisioning. Remove --browser=cloud to use a local browser, or wait for a browser to free up.")}writeConfig(e,t){this.configDir||(this.configDir=i(N(),`stably-cloud-browser-${process.pid}`),I(this.configDir,{recursive:!0}));const r=e.replace(/[^a-zA-Z0-9_-]/g,"_"),n=i(this.configDir,`config-${r}.json`),s={browser:{cdpEndpoint:t,isolated:!1},saveSession:!1,outputDir:i(process.cwd(),".stably-browser")};return T(n,JSON.stringify(s,null,2),"utf-8"),ls.debug("[cloud-browser] Wrote config file",{sessionName:e,path:n}),n}cleanupConfigDir(){if(this.configDir){try{_(this.configDir,{recursive:!0,force:!0})}catch{}this.configDir=null}}async releaseSession(e){const t=this.sessions.get(e);if(!t)return;const{sessionId:r,browserRequestId:n}=t.session;ls.info("[cloud-browser] Releasing session",{sessionName:e,sessionId:r,browserRequestId:n});try{const e=await this.authProvider.getAuthHeader();await async function(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/release`,fn).toString();try{const s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});s.ok||ls.warn("[cloud-browser] Failed to release browser",{browserRequestId:t,status:s.status})}catch(e){ls.warn("[cloud-browser] Error releasing browser",{browserRequestId:t,error:e instanceof Error?e.message:String(e)})}}(e,n,this.projectId)}catch(t){ls.warn("[cloud-browser] Error releasing session",{sessionName:e,sessionId:r,error:t instanceof Error?t.message:String(t)})}this.sessions.delete(e)}ensureHealthCheck(){this.healthCheckTimer||(this.healthCheckTimer=setInterval(async()=>{if(0===this.sessions.size||this.released)this.stopHealthCheck();else for(const[e,t]of this.sessions)if(!t.needsRecreation)try{const r=await this.authProvider.getAuthHeader();await Yc(r,this.projectId,t.session.sessionId)||(ls.warn("[cloud-browser] Browser session is dead, marking for recreation",{sessionName:e,sessionId:t.session.sessionId}),t.needsRecreation=!0)}catch(r){ls.warn("[cloud-browser] Health check failed",{sessionName:e,sessionId:t.session.sessionId,error:r instanceof Error?r.message:String(r)})}},3e4),this.healthCheckTimer.unref&&this.healthCheckTimer.unref())}stopHealthCheck(){this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null)}};function Kc(e){return new Promise(t=>setTimeout(t,e))}function Jc({configuredSessionName:e,isFixMode:t,useCloudBrowser:r}){return e??(t||r?"auto":"default")}var Xc=he.object({verdict:he.enum(["PASS","FAIL","INCONCLUSIVE"]),steps:he.array(he.string()).min(1),reason:he.string().nullable(),evidence:he.array(he.string())}).superRefine((e,t)=>{"PASS"===e.verdict||e.reason&&0!==e.reason.trim().length||t.addIssue({code:he.ZodIssueCode.custom,path:["reason"],message:"reason is required for FAIL and INCONCLUSIVE verdicts"})}),Qc=/\bmcp__playwright-mcp__[a-z0-9_]+\b/gi,Zc=/\.playwright-mcp(?:\/[^\s"'`)\]]*)?/gi,el=/\bplaywright[\s_-]?mcp\b/gi;function tl(e){return e.replace(Qc,"browser_tool").replace(Zc,"verification-artifact").replace(el,"browser automation")}function rl(e){return{...e,steps:e.steps.map(e=>tl(e)),reason:e.reason?tl(e.reason):null,evidence:e.evidence.map(e=>tl(e))}}function nl(e){const t=e.matchAll(/```verdict\s*\r?\n([\s\S]*?)\r?\n```/g);let r=null;for(const e of t)try{const t=JSON.parse(e[1]??"");r=Xc.parse(t)}catch{}return r}function sl({mode:e,lastAssistantText:t,maxLength:r=1e4}){const n="verify"===e&&t?tl(t):t;return n?n.slice(0,r):null}var ol=e=>{const t=e.prompt;return(Array.isArray(t)?t.join(" "):t)?.trim()||void 0},il=e=>new Promise(t=>setTimeout(t,e));function al(e){return e>0}var cl=["Bash","Read","Write","Edit","Glob","Grep","Task","Skill"],ll=["Task","Skill"],ul=["Bash","Read","Write","Edit","Glob","Grep","mcp__session-control"],dl=e=>{if("EPIPE"!==e.code)throw e},pl="__main__",fl=[3e3,5173,4173,8080,4200,8e3],hl=/\b(TEST_EMAIL|TEST_PASSWORD|auth|authentication|credentials|login|log in|sign in)\b/i,gl=/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i,ml=/playwright[\s_-]?mcp/i,yl=e=>"mcp__auto-heal-report__generate-report"===e;async function bl(e,t){return!!e&&(!!e.hasQueuedMessages()||new Promise(r=>{const n=setTimeout(()=>{clearInterval(s),r(!1)},t),s=setInterval(()=>{e.hasQueuedMessages()&&(clearTimeout(n),clearInterval(s),r(!0))},200)}))}async function wl(e){return new Promise(t=>{const r=new te.Socket;let n=!1;const s=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(700),r.once("connect",()=>s(!0)),r.once("timeout",()=>s(!1)),r.once("error",()=>s(!1)),r.connect(e,"127.0.0.1")})}var vl=async(e,t,r)=>{const n=r?"[Y/n]":"[y/N]",s=(await e.question(`${Dr("info","?")} ${t} ${ne.gray(n)} `)).trim().toLowerCase();return s?"y"===s||"yes"===s:r},Il=async e=>{if("single"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"create-from-diff")}else if("verify"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"verify")}else if("fix"===e.mode)ls.initSession(`fix-${e.runId}`);else if("plan"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"plan")}ls.info("Agent session starting",{mode:e.mode});const a=(e=>{switch(e.mode){case"chat":return"Ask Stably to build tests for you";case"init":return"Setting up Playwright and Stably SDK";case"fix":return"Fixing broken tests";case"single":return ol(e)||"Creating tests from PR/branch changes";case"verify":return ol(e)||"Verifying application";case"plan":return ol(e)||"Planning test coverage"}})(e),c=((e,t)=>{const r=e?.trim().toLowerCase();return r?"1"===r||"true"===r||"yes"===r?t:"chat"===r||"single"===r||"fix"===r||"init"===r||"verify"===r||"plan"===r||"error"===r?r:null:null})(process.env.STABLY_CLI_VISUAL_MOCK,e.mode);if(process.env.STABLY_CLI_VISUAL_MOCK&&!c)throw new Error("Invalid STABLY_CLI_VISUAL_MOCK value. Expected one of: 1, true, chat, single, fix, init, verify, plan, error.");if(c){if(ls.info("Running CLI visual mock session",{requestedMode:e.mode,scenario:c}),"error"===c){const e={log:[{content:"Visual mock mode enabled. Simulating a failed AI run without contacting the backend.",id:0,kind:"text"}],promptDisplay:a,status:"running"},t=await Ho(e);return t.setRunningLabel({label:"Simulating upstream failure..."}),await new Promise(e=>setTimeout(e,220)),t.setStatus({status:"error",error:"Mocked AI provider failure for CLI visual testing."}),await new Promise(e=>setTimeout(e,220)),void await t.cleanup()}return void await(async({mode:e,promptDisplay:t})=>{const r={log:[],promptDisplay:t,status:"running"},n=await Ho(r,"init"===e?{showSpinnerImmediately:!0,isInitMode:!0}:"fix"===e?{isFixMode:!0}:void 0),s=async(e,t=180)=>{e(),await il(t)};try{if("chat"===e)return await s(()=>n.appendText({text:"Visual mock mode enabled. No real AI calls will be made.\n\n"})),await s(()=>n.appendUserMessage({text:"Create a login test for the dashboard."})),await s(()=>n.appendThinking({text:"Scanning the repository for auth flows and existing test patterns..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Glob",toolInput:{pattern:"**/*login*"}})),await s(()=>n.addToolResult({message:"Found 4 matching files"})),await s(()=>n.appendText({text:"I found the existing auth helpers and would generate a Playwright test next.\n"})),void await s(()=>n.setStatus({status:"success",result:"Mock chat transcript complete."}),260);if("single"===e)return await s(()=>n.setRunningLabel({label:"Analyzing app structure..."})),await s(()=>n.appendThinking({text:"Reviewing routes, existing tests, and the requested flow..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Read",toolInput:{file_path:"app/page.tsx"}})),await s(()=>n.addToolResult({message:"Read homepage and CTA structure"})),await s(()=>n.addTool({rawName:"Write",toolInput:{file_path:"tests/auth/login.spec.ts"}})),await s(()=>n.addToolResult({message:"Created tests/auth/login.spec.ts"})),await s(()=>n.appendText({text:"Generated a focused login flow test with stable selectors and assertions.\n"})),void await s(()=>n.setStatus({status:"success",result:"Created 1 mock test file: tests/auth/login.spec.ts"}),260);if("verify"===e)return await s(()=>n.appendText({text:"Starting verification...\nTarget URL: http://localhost:3000\n"})),await s(()=>n.setRunningLabel({label:"Calibrating verification flow..."})),await s(()=>n.appendThinking({text:"Planning a short verification pass for the requested path..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"mcp__playwright__browser_navigate",toolInput:{url:"http://localhost:3000"}})),await s(()=>n.addToolResult({message:"Opened application homepage"})),await s(()=>n.addTool({rawName:"mcp__playwright__browser_click",toolInput:{element:"Sign in button"}})),await s(()=>n.addToolResult({message:"Reached login form successfully"})),await s(()=>n.appendText({text:"Verification passed for the main sign-in path.\n"})),void await s(()=>n.setStatus({status:"success",result:"Verified requested behavior in visual mock mode."}),260);if("fix"===e)return await s(()=>n.setRunningLabel({label:"Triaging failing tests..."})),await s(()=>n.addSubagentStart({toolUseId:"triage-1",subagentType:"triage",description:"Analyze failing selectors and isolate the root cause"})),await s(()=>n.addSubagentActivity({toolUseId:"triage-1",kind:"text",content:'Selector drift detected after the button label changed from "Log in" to "Sign in".'})),await s(()=>n.setSubagentStatus({toolUseId:"triage-1",status:"complete"})),await s(()=>n.addSubagentStart({toolUseId:"code-1",subagentType:"code-worker",description:"Fix login test selectors"})),await s(()=>n.addSubagentActivity({toolUseId:"code-1",kind:"tool",content:"Edit tests/auth/login.spec.ts"})),await s(()=>n.addSubagentActivity({toolUseId:"code-1",kind:"tool_result",content:"Updated role-based button locator"})),await s(()=>n.setSubagentStatus({toolUseId:"code-1",status:"complete"})),await s(()=>n.addSubagentStart({toolUseId:"validation-1",subagentType:"validation",description:"Re-run impacted tests"})),await s(()=>n.addSubagentActivity({toolUseId:"validation-1",kind:"text",content:"Validation run passed for 3/3 affected tests."})),await s(()=>n.setSubagentStatus({toolUseId:"validation-1",status:"complete"})),void await s(()=>n.setStatus({status:"success",result:"Mock fix flow complete. 1 test fixed, 0 failed."}),260);if("init"===e)return await s(()=>n.addTool({rawName:"Bash",toolInput:{command:"npm install -D @playwright/test @stablyai/playwright"}})),await s(()=>n.addToolResult({message:"Installed Playwright and Stably SDK dependencies"})),await s(()=>n.addTool({rawName:"Write",toolInput:{file_path:"playwright.config.ts"}})),await s(()=>n.addToolResult({message:"Configured Playwright reporter and base settings"})),await s(()=>n.appendText({text:"Playwright and the Stably SDK are configured. You can run `stably test` next.\n"})),void await s(()=>n.setStatus({status:"success",result:"Initialization mock complete."}),260);await s(()=>n.setRunningLabel({label:"Building coverage plan..."})),await s(()=>n.appendThinking({text:"Comparing routes, existing tests, and high-risk gaps..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Read",toolInput:{file_path:"tests/"}})),await s(()=>n.addToolResult({message:"Mapped existing coverage across auth, billing, and onboarding"})),await s(()=>n.appendText({text:"Planned three new `test.fixme()` specs for the highest-risk uncovered flows.\n"})),await s(()=>n.setStatus({status:"success",result:"Planning mock complete."}),260)}finally{await il(120),await n.cleanup()}})({mode:c,promptDisplay:a})}process.stdout.on("error",dl),process.stderr.on("error",dl);const l=e=>{if("EPIPE"!==e.code)throw e};process.on("uncaughtException",l),ls.debug("Checking authentication");const u=await ys({autoLogin:"chat"===e.mode||"init"===e.mode}),d=new vs(u);ls.debug("Authentication resolved",{authType:u.type});const p="oauth"===u.type?u.auth.context.orgId:void 0,f=n.resolve(process.cwd()),h="fix"!==e.mode,g=n.join(f,".env"),y=h&&v.existsSync(g)&&v.statSync(g).isFile(),b=y?t(v.readFileSync(g,"utf8")):{};ls.debug("Environment file",{path:g,exists:y,variableCount:Object.keys(b).length});const I="chat"!==e.mode&&"init"!==e.mode,T="chat"===e.mode,_="chat"===e.mode||"init"===e.mode,S="single"===e.mode,k="verify"===e.mode,P="plan"===e.mode,C=S||k||P;let R,U=new io;"init"===e.mode&&(R=e.initPreferences??await async function(){if(!process.stdin.isTTY||!process.stdout.isTTY)return{googleAuth:!0,emailPackage:!1};const e=re({input:process.stdin,output:process.stdout});try{return{googleAuth:await vl(e,"Include Google Auth test helper guidance? (recommended)",!0),emailPackage:await vl(e,"Install @stablyai/email for inbox testing?",!1)}}finally{e.close()}}());const L="chat"===e.mode?e.getHelpText:void 0,$="verify"===e.mode?(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt).trim():"";let D="verify"===e.mode?e.url?.trim()||function(e){const t=Array.isArray(e)?e.join(" "):e,r=e=>e.replace(/[),.;!?]+$/,""),n=e=>{const t=r(e);try{return new URL(t).toString()}catch{return}},s=t.match(/https?:\/\/[^\s"'`<>]+/i);if(s)return n(s[0]);const o=t.match(/(?<!@)\b(?:localhost|(?:\d{1,3}\.){3}\d{1,3}|(?:[a-z0-9-]+\.)+[a-z]{2,63})(?::\d{2,5})?(?:\/[^\s"'`<>]*)?/i);if(!o)return;const i=r(o[0]),a=i.split("/")[0]??i,c=a.split(":")[0]?.toLowerCase()??"",l=c.includes(".")?c.split(".").at(-1)??"":"";return new Set(["ts","tsx","js","jsx","md","json","yaml","yml","txt","css"]).has(l)?void 0:n(`${"localhost"===c||"127.0.0.1"===c?"http":"https"}://${i}`)}(e.prompt):void 0;if("verify"===e.mode&&!e.url&&D&&ls.info("[verify] Using URL extracted from prompt",{url:D}),"verify"!==e.mode||D||(D=await async function(){for(const e of fl)if(await wl(e))return`http://localhost:${e}`}(),D?ls.info("[verify] Detected local application URL",{url:D}):ls.info("[verify] No common localhost dev server detected")),"verify"===e.mode&&!1!==e.interactive){const e=await async function({envFilePath:e,envFromFile:t,initialUrl:r,verifyPromptText:s,workingDir:o}){if(!process.stdin.isTTY||!process.stdout.isTTY)return{resolvedUrl:r};const i=n.join(o,"STABLY.md"),a=v.existsSync(i),c=a?await v.promises.readFile(i,"utf8").catch(()=>{}):void 0;let l=r?.trim()||void 0;const u=!l,d=(({envEmail:e,envPassword:t,promptIncludesEmail:r,stablyMdContent:n})=>!Boolean(e?.trim()&&t?.trim())&&!r&&!(e=>!!e&&hl.test(e))(n))({envEmail:process.env.TEST_EMAIL??t.TEST_EMAIL,envPassword:process.env.TEST_PASSWORD??t.TEST_PASSWORD,promptIncludesEmail:gl.test(s),stablyMdContent:c}),p=!a;if(!u&&!d&&!p)return{resolvedUrl:l};const f=re({input:process.stdin,output:process.stdout}),h=async(r,n)=>{const s=v.existsSync(e)?await v.promises.readFile(e,"utf8"):"",o=new RegExp(`^${i=r,i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}=.*$`,"m");var i;const a=`${r}=${(e=>/^[A-Za-z0-9_./:@-]+$/.test(e)?e:`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`)(n)}`,c=o.test(s)?s.replace(o,a):`${s}${s&&!s.endsWith("\n")?"\n":""}${a}\n`;await v.promises.writeFile(e,c,"utf8"),t[r]=n};try{if(u){const e=(await f.question("Starting URL (optional, Enter to auto-infer): ")).trim();e&&(l=e)}if(d&&await vl(f,"No TEST_EMAIL/TEST_PASSWORD found in .env and no auth guidance found in STABLY.md. Configure credentials in .env now?",!0)){const e=(await f.question("TEST_EMAIL: ")).trim(),t=(await f.question("TEST_PASSWORD: ")).trim();e&&t&&(await h("TEST_EMAIL",e),await h("TEST_PASSWORD",t),process.env.TEST_EMAIL||(process.env.TEST_EMAIL=e),process.env.TEST_PASSWORD||(process.env.TEST_PASSWORD=t))}if(p&&await vl(f,"No STABLY.md found. Create one at repository root for project instructions?",!0)){const e=["# STABLY.md","","Project instructions for Stably agent runs.","","## Verify Notes","- Keep verification scope to requested behavior only.","- Use TEST_EMAIL and TEST_PASSWORD env vars for authenticated flows.","","## Special Instructions","- Add project-specific constraints here.",""].join("\n");await v.promises.writeFile(i,e,"utf8");const t=(await f.question("Special verify instruction to append to STABLY.md (optional): ")).trim();if(t){const e=await v.promises.readFile(i,"utf8"),r=/(^|\n)## Special Instructions\s*$/m.test(e)?`${e}${e.endsWith("\n")?"":"\n"}- ${t}\n`:`${e}${e.endsWith("\n")?"":"\n"}\n## Special Instructions\n- ${t}\n`;await v.promises.writeFile(i,r,"utf8")}}return{resolvedUrl:l}}finally{f.close()}}({envFilePath:g,envFromFile:b,initialUrl:D,verifyPromptText:$,workingDir:f});D=e.resolvedUrl?.trim()||D}"verify"!==e.mode||D||ls.warn("No verify URL provided and no local app detected on common ports. The agent will try to infer a URL from code/config.");const N={log:[],promptDisplay:a,status:"running"};let O,B,j,M,F=I,H=!1,q=0,K=[],J=!1,X=!1,Q=0;const Z=new Map,ee=[],te=e=>{ee.push(e)},se=new Map;let oe=null,ie=!1,ae=!1;const ce=Date.now();let le,ue="fix"===e.mode?{suiteId:e.runId,phase:"initializing",totalTests:null,fixedTests:0,failedTests:0,currentTestDescription:null,lastTestDescription:null,startedAt:ce,endedAt:null,isError:!1,updatedAt:ce,recentActivity:[],workers:[{id:pl,testDescription:"Orchestrator",workerType:"main",status:"running",summary:null,startedAt:ce,endedAt:null,activity:[]}]}:null;const de=new Set,pe=new Map,fe=(e,t)=>{const r=pe.get(e);if(!r)return;const n={...r,...t};pe.set(e,n),_e({workers:Array.from(pe.values())})},he=(e,t)=>{if(!ue)return;const r=ue.workers.map(r=>{if(r.id!==e)return r;const n=[...r.activity,{...t,timestamp:Date.now()}].slice(-15);return{...r,activity:n}});ye({workers:r})},ge=e=>{if(!ue)return;const t=[...ue.recentActivity,{...e,timestamp:Date.now()}].slice(-10);ye({recentActivity:t})},me=e=>(ue?.workers??[]).map(t=>t.id===pl?{...t,status:e?"failed":"succeeded",endedAt:t.endedAt??Date.now()}:"running"===t.status?{...t,status:"failed",endedAt:Date.now()}:t),ye=e=>{ue&&!le?.isClosed&&(ue={...ue,...e,updatedAt:Date.now()},le?.sendProgress(ue))},be=async t=>{if("fix"===e.mode){if("STARTED"===t){if(ie)return;ie=!0}else{if(ae)return;ae=!0}try{await(async({authHeader:e,orgId:t,runId:r,status:n})=>{const s=await(o={auth:e,body:{status:n},client:In(),headers:_s(t),path:{runId:r}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-status",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to update autoheal status (${s.response.status})`)})({authHeader:await d.getAuthHeader(),orgId:p,runId:e.runId,status:t})}catch{}}},ve=Date.now();let Ie,Te=null;const _e=e=>{Te&&!Ie?.isClosed&&(Te={...Te,...e,updatedAt:Date.now()},Ie?.sendProgress(Te))},Ee=e=>{if(!Te)return;const t=[...Te.recentActivity,{...e,timestamp:Date.now()}].slice(-10);_e({recentActivity:t})};let Se;const xe=(e.mode,!0);if(ls.info("[session] Checking session creation",{mode:e.mode,shouldCreateSession:xe}),"fix"===e.mode)ls.info("[session] Deferring fix-mode session creation until after early-exit checks");else try{ls.info("[session] Creating progress session",{mode:e.mode,projectId:bs(u)});const t=await mo({agentMode:e.mode,authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u)}),{sessionId:r,sessionMode:n}=t;if(Se=r,C){const t="single"===e.mode||"verify"===e.mode||"plan"===e.mode?Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt:null,n=ao(f);Te={sessionId:r,phase:"initializing",startedAt:ve,endedAt:null,isError:!1,updatedAt:ve,currentActivity:null,filesCreated:[],traceProofs:[],recentActivity:[],prompt:t||null,environment:{gitBranch:n?.branch??null,workingDirectory:f,nodeVersion:process.version,cliVersion:pn}},Ie=new Ls({authProvider:d,orgId:p,sessionId:r,onUserMessage:e=>{U&&(ls.info("[ws] Injecting web UI message into agent",{contentLength:e.length}),Ee({type:"user_message",summary:e}),Fe({text:`[Web] ${e}`}),U.pushText(`[Message from web UI user]: ${e}`),F||(F=!0,Ze({status:"running"})))}}),await Ie.start(),_e({phase:"initializing"})}ls.info(`[${n}] Progress session created`,{sessionId:r})}catch(e){const t=e instanceof Error?e.message:String(e);ls.warn(`[progress] Session creation failed (non-fatal): ${t}`)}const Ae={current:e=>{}},ke={current:async()=>{}};let Ce;const Re={current:()=>{}};let Le=!1,$e=!1;const{addSubagentActivity:De,addSubagentStart:Ne,addTool:Oe,appendCancelled:Be,appendText:je,appendThinking:Me,appendUserMessage:Fe,cancelThinkingRender:He,cleanup:Ge,dismissPermissionPrompt:We,flushThinkingRender:Ve,resetThinkingLogIndex:Ye,setExiting:ze,setRunningLabel:qe,setStatus:Ke,setSubagentStatus:Je,updateFixProgress:Xe}=await Ho(N,"init"===e.mode?{onCancel:()=>Re.current(),onExit:()=>ke.current(),onSend:e=>Ae.current(e),showSpinnerImmediately:!0,isInitMode:!0}:"chat"===e.mode?{onCancel:()=>Re.current(),onExit:()=>ke.current(),onSend:e=>Ae.current(e)}:"fix"===e.mode?{onExit:()=>ke.current(),isFixMode:!0}:{onExit:()=>ke.current()});let Qe=N.status;const Ze=({error:e,result:t,status:r})=>{Qe=r,Ke({error:e,result:t,status:r})};let et,tt;k&&(je({text:"Starting verification...\n"}),je(D?{text:`Target URL: ${D}\n`}:{text:"Target URL: auto-detect (agent may infer from project config)\n"}),qe({label:"Calibrating verification flow..."})),Ae.current=e=>{const t=e.trim();if(T&&!ls.getLogFilePath()&&ls.initSession(t||"chat"),ls.debug("User message",{text:t}),"/help"===t){F&&U&&(H=!0,O?.interrupt?.(),U.allowNextTurn(),F=!1),"running"===Qe&&Ze({status:"success"}),Fe({text:e});const t=L?.();return void je({text:t??"Help is not available in this session."})}if(T&&qe({label:void 0}),U){if(F)return Ze({status:"running"}),Fe({text:e}),U.pushText(e),void(q+=1);Ze({status:"running"}),Fe({text:e}),te({role:"user",content:e,timestamp:(new Date).toISOString()}),U.pushText(e),F=!0}};let rt="",nt="";const st=[],ot=[],it=[];let at;const ct=await(async e=>{try{const t=await kn(e,"stably.yaml");if(!t)return void ls.debug("No stably.yaml found");const r=await z(t,"utf-8");if(!r.trim())return;const n=Pe(r),s=Pc.parse(n.toJS()),o=s.agent?.fix?.maxTurnsPerIssue,i=s.agent?.fix?.maxParallelWorkers,a=!!s.agent?.fix?.rules;return ls.debug(`Loaded stably.yaml: maxTurnsPerIssue=${o??"default"}, maxParallelWorkers=${i??"default"}, hasRules=${a}`,{path:t,config:s.agent}),s}catch(e){return void ls.warn("Failed to parse stably.yaml",{error:e})}})(f),lt=ct?.agent?.fix?.skipAfterConsecutiveUnfixed,ut=await(async()=>{if("single"===e.mode){const r=await async function(e,t){const r=s(e);if(t){const e=s(r,t);return Eo(e,"output-flag"),{path:e,source:"output-flag"}}const n=Io(r);if(n){const e=await async function(e){try{const t=(await z(e,"utf-8")).match(/testDir:\s*['"]([^'"]+)['"]/);return t?.[1]}catch{return}}(n);if(e){const t=s(o(n),e);if(_o(t))return Eo(t,"playwright.config.ts"),{path:t,source:"playwright.config.ts"}}}for(const e of To){const t=i(r,e);if(_o(t))return Eo(t,"auto-detected"),{path:t,source:"auto-detected"}}return Eo(r,"cwd-fallback"),{path:r,source:"cwd-fallback"}}(f,e.outputDir);return at=r.path,t=e.prompt,`${(Array.isArray(t)?t.join(" "):t).trim()||"Create tests based on the changes in the current PR or branch. If the user references a specific PR number or branch name, first checkout that PR/branch using `gh pr checkout <number>` or `git checkout <branch>`. Use the Pull Request Context or Git Branch Context section of the system prompt to understand what code was changed, then create appropriate tests for the new or modified functionality. After generating the tests, run them locally (e.g. `pnpm stably test` or the repo's test command) and iterate until the new tests pass."}\n\n[Output directory: ${at}]`}var t;if("verify"===e.mode)return function(e,t){const r=(Array.isArray(e)?e.join(" "):e).trim()||"Verify the application behavior.",n=t?.trim();return n?`Starting URL: ${n}\nURL policy: treat this as the source of truth and do not switch domains unless the user explicitly asks.\n\nVerification prompt: ${r}`:r}(e.prompt,D);if("fix"===e.mode)try{ls.info("[fix] Fetching autoheal context",{runId:e.runId,skipAfterConsecutiveUnfixed:lt});const t=Date.now(),{context:r,autohealReportUrl:n,skippedTests:s,newerPassingSuiteId:o,envName:i}=await(async({authHeader:e,orgId:t,runId:r,skipAfterConsecutiveUnfixed:n})=>{ls.debug("Fetching autoheal context",{runId:r,skipAfterConsecutiveUnfixed:n});const s=await(o={auth:e,client:In(),headers:_s(t),path:{runId:r},query:null!=n?{skipAfterConsecutiveUnfixed:n}:{}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-context",...o}));var o;if(404===s.response.status)throw ls.warn("Autoheal context not found",{runId:r,status:404}),new Error(`Run ID "${r}" was not found.`);if(401===s.response.status)throw ls.warn("Autoheal context fetch unauthorized",{runId:r,status:401}),new Error("Unauthorized: failed to fetch autoheal context (401).");if(422===s.response.status)throw ls.warn("Autoheal context fetch invalid request",{runId:r,status:422,error:s.error?.error}),new Error(s.error?.error??"Failed to fetch autoheal context (422).");if(!s.error){const e=Es.safeParse(s.data);if(e.success)return ls.debug("Autoheal context fetched successfully",{runId:r,contextSize:e.data.context.length,skippedTestCount:e.data.skippedTests?.length??0}),{context:e.data.context,autohealReportUrl:e.data.autohealReportUrl,skippedTests:e.data.skippedTests??[],newerPassingSuiteId:e.data.newerPassingSuiteId,envName:e.data.envName};throw ls.warn("Autoheal context response invalid",{runId:r}),new Error("Autoheal context response missing or invalid context.")}throw ls.warn("Autoheal context fetch failed",{runId:r,error:s.error}),new Error("Failed to fetch autoheal context")})({authHeader:await d.getAuthHeader(),orgId:p,runId:e.runId,skipAfterConsecutiveUnfixed:lt});if(i&&!Ue.remoteEnvName&&(ls.info("[fix] Auto-loaded remote env from run metadata",{envName:i}),Ue.remoteEnvName=i,tt=i),ls.info("[fix] Autoheal context fetched",{runId:e.runId,durationMs:Date.now()-t,contextLength:r.length,skippedTestCount:s.length}),et=n,s.length>0){ls.info(`[fix] Skipping ${s.length} test(s) that failed to be fixed ${lt}+ consecutive times`);for(const e of s)ls.info(`[fix] Skipped: ${e.testIdentifier} β ${e.testTitle} (unfixed ${e.consecutiveUnfixedCount}x)`)}if(o&&(ls.info("[fix] Tests already passing in a newer run β no session created",{newerPassingSuiteId:o}),Ze({status:"success",result:`Tests already passing in a newer run (${o}). Nothing to fix.`}),await Ge(),process.exit(0)),r.includes("No failing tests to fix (all were skipped).")&&(ls.info("[fix] All failing tests were skipped β creating skipped session"),xe&&await async function({authHeader:e,orgId:t,projectId:r,runId:n,reason:s,skippedTests:o,fetchImpl:i=fetch,apiUrl:a=fn}){const c=new URL("/internal/v1/cli/sessions/skipped",a).toString(),l={Authorization:e,"Content-Type":"application/json","X-STABLY-CLI-VERSION":pn};t&&(l["x-stably-org-id"]=t),await i(c,{method:"POST",headers:l,body:JSON.stringify({mode:"fix",projectId:r,...n?{playwrightSuiteRunId:n}:{},progress:{phase:"skipped",isError:!1,reason:s,skippedTests:o,endedAt:Date.now()}}),signal:AbortSignal.timeout(5e3)}).then(e=>{e.ok||console.warn(`[session] Failed to create skipped session: ${e.status} ${e.statusText}`)}).catch(e=>{console.warn(`[session] Failed to create skipped session: ${e instanceof Error?e.message:String(e)}`)})}({authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u),runId:e.runId,reason:`All ${s.length} failing test(s) skipped β each was unfixed ${lt??3}+ consecutive runs`,skippedTests:s}),Ze({status:"success",result:`All failing tests skipped (unfixed ${lt}+ consecutive times). Nothing to fix.`}),await Ge(),process.exit(0)),xe)try{ls.info("[session] Creating fix-mode progress session (post early-exit checks)");const t=await mo({agentMode:e.mode,authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u),runId:e.runId});Se=t.sessionId,ls.info("[fix] Progress session created",{sessionId:Se})}catch(e){const t=e instanceof Error?e.message:String(e);ls.warn(`[progress] Fix session creation failed (non-fatal): ${t}`)}return le||(ls.info("[fix] Creating WebSocket progress reporter"),le=new Rs({authProvider:d,orgId:p,runId:e.runId,onUserMessage:e=>{if(ls.info("[ws] Injecting web UI message into fix agent",{contentLength:e.length}),he(pl,{type:"user_message",summary:e}),ge({type:"user_message",summary:e}),Fe({text:`[Web] ${e}`}),!F)return U.pushText(`[Message from web UI user]: ${e}`),F=!0,void U.allowNextTurn();J||Date.now()-Q<2e3?U.pushText(`[Message from web UI user]: ${e}`):(K.push(e),j&&clearTimeout(j),j=setTimeout(()=>{j=void 0;const e=[...K];K=[],Q=Date.now(),mr(e)},500))}}),await le.start(),ye({phase:"initializing"})),be("STARTED"),r}catch(e){const t=e instanceof Error?e.message:"Failed to fetch autoheal context.";ls.error("[fix] Failed to fetch autoheal context",{error:t}),Ze({error:t,status:"error"}),await Ge(),process.exit(1)}if("plan"===e.mode){const t=(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt)?.trim();return t||"Analyze this repository and generate a comprehensive test coverage plan."}if("init"===e.mode){const e=R??{googleAuth:!0,emailPackage:!1};return["Set up Playwright with the Stably SDK.",`Preferences: Google Auth guidance: ${e.googleAuth?"yes":"no"}, @stablyai/email: ${e.emailPackage?"install":"skip"}.`].join(" ")}return""})(),dt=await async function(e){const t=n.resolve(e),r=n.join(t,"tests"),s=n.join(r,"helpers"),o=n.join(r,"assets"),i=function(e){const t=n.resolve(e);if(E(t))for(const e of co){const r=n.join(t,`playwright.config${e}`);if(E(r))return r}}(t)??n.join(t,"playwright.config.ts"),a=n.basename(i),c=n.join(r,"seed.spec.ts"),[l,u,d,p,f,h,g]=await Promise.all([po({defaultContent:"Unable to read directory",dirName:"working directory",dirPath:t}),po({defaultContent:"Unable to read directory",dirName:"tests directory",dirPath:r}),po({defaultContent:"Directory does not exist yet",dirName:"helpers directory",dirPath:s}),po({defaultContent:"Directory does not exist yet",dirName:"assets directory",dirPath:o}),uo({defaultContent:"File does not exist or could not be read",fileName:a,filePath:i}),uo({defaultContent:"File does not exist or could not be read",fileName:"seed.spec.ts",filePath:c}),fo(t)]);return{absolutePath:t,isEsmProject:g,directories:{assets:p,helpers:d,root:l,tests:u},files:{playwrightConfig:f,playwrightConfigFilename:a,seedSpec:h}}}(f),pt="fix"===e.mode?ct?.agent?.fix?.maxTurnsPerIssue:"single"===e.mode?ct?.agent?.create?.maxTurnsPerTestFile:void 0,ft="cloudBrowser"in e&&e.cloudBrowser,ht=ct?.agent?.fix?.maxParallelWorkers??3,gt="fix"===e.mode?await(async e=>{const t=await Cc(e,"STABLY-FIX.md");return t?.content})(f):void 0,mt="fix"===e.mode?ct?.agent?.fix?.rules:void 0;gt&&mt&&ls.warn("Both STABLY-FIX.md and stably.yaml agent.fix.rules found; using STABLY-FIX.md");const yt=gt??mt,bt=ct?.agent?.fix?.maxBudgetUsd??50,wt="verify"===e.mode?e.maxBudgetUsd??5:void 0,vt="single"===e.mode?ct?.agent?.create?.maxBudgetUsd??50:void 0,It="fix"===e.mode?bt:k?wt:vt,Tt="init"!==e.mode,_t="single"===e.mode?await(async e=>{const t=await Cc(e,"STABLY-CREATE.md");return t?.content})(f):void 0,Et=await(e=>Cc(e,"STABLY.md"))(f),St=Et?.content;let xt;if(k&&(qe({label:"Assembling verification context..."}),je({text:"Assembling workspace context...\n"})),ls.info("[fix] Fetching system prompt and subagent definitions",{mode:e.mode,isCloudBrowser:ft,maxParallelWorkers:ht,maxTurnsOverride:pt,maxBudgetUsd:It,hasCustomRules:!!yt,hasCreateRules:!!_t,hasStablyMd:!!St,stablyMdPath:Et?.path}),Et&&ls.info(`STABLY.md loaded (${Et.content.length} chars)`,{path:Et.path}),"fix"===e.mode&&tt){const e=await Is(tt);e.ok?xt=e.result:ls.warn("[fix] Failed to load auto-detected remote env, continuing without it",{envName:tt,error:e.error})}else xt=await Ts();const At=xt?Object.keys(xt.variables):[],kt=[...new Set([...Object.keys(b),...At])],Pt=Date.now(),Ct=await d.getAuthHeader(),[{systemPrompt:Rt,prContext:Ut},Lt]=await Promise.all([ho({allowedEnvVars:kt,mode:e.mode,workspaceInfo:dt,authHeader:Ct,customHeader:"single"===e.mode?e.customHeader:void 0,maxParallelWorkers:ht,isCloudBrowser:ft}),Tt?Ec({authHeader:Ct,mode:e.mode,maxTurnsOverride:pt}):Promise.resolve({})]);ls.info("[fix] System prompt and subagents fetched",{durationMs:Date.now()-Pt,systemPromptSize:Rt.length,subagentCount:Object.keys(Lt).length,maxTurnsOverride:pt??"default",hasPrContext:!!Ut});const $t=function(e){const t={};for(const[r,n]of Object.entries(e))void 0!==n&&(_c.has(r)||Tc.some(e=>r.startsWith(e))||(t[r]=n));return t}({...b,...process.env}),Dt=!0;ls.debug("AI proxy configuration",{useStablyAiProxy:Dt,wantsBypassProxy:!1,wantsUseOllama:!1}),ls.info("[fix] Acquiring AI proxy key",{useStablyAiProxy:Dt});const Nt=Date.now(),Ot=await async function({auth:e,client:t,source:r,metadata:n,duration:s}){try{const i=await(o={auth:e,client:t,body:{source:r,metadata:n??{},duration:s}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/v1/proxy/api-key",...o,headers:{"Content-Type":"application/json",...o.headers}})),a=i.response;if(i.error){const e="object"==typeof i.error&&"error"in i.error?i.error.error:"Unknown error";return{error:Ic(e,a)}}return i.data?{key:i.data.key}:{error:Ic("No data in response",a)}}catch(e){const t=e instanceof Error?e.message:"Unknown error";return{error:Ic(t)}}var o}({auth:Ct,client:In(),source:"cli"}),Bt=Ot?.key;if(ls.info("[fix] AI proxy key acquired",{durationMs:Date.now()-Nt,success:!!Bt,hasError:!!Ot?.error}),!Bt){const e=Ot?.error?.message?`Unable to make AI calls: ${Ot.error.message}`:"Unable to make AI calls. Check if you are authenticated.";ls.warn("Failed to get proxy API key",{error:Ot?.error?.message}),Ze({error:e,status:"error"}),await Ge(),ls.flush(),ls.printLogFileInfo(),process.exit(1)}ls.debug("Proxy API key acquired",{success:!!Bt});const jt="init"===e.mode,Mt="fix"===e.mode,Ft=!!ft,Ht=Ft?new qc({authProvider:d,projectId:bs(u)}):void 0,Gt=bc({localEnv:b,remoteEnv:xt?.variables,remoteSensitiveValues:xt?.sensitiveValues}),Wt=jt||P?void 0:function(e){let t,r;!function(e){const t=i(e,".gitignore");try{if(E(t)){const e=x(t,"utf-8"),r=e.split("\n").map(e=>e.trim());if(r.includes(Oc)||r.includes(`/${Oc}`))return;const n=e.length>0&&!e.endsWith("\n");A(t,`${n?"\n":""}${Oc}\n`)}}catch{}}(process.cwd());const n=new Set;let s,o;const a=()=>{var t;return o||(t=e.sessionName,o="auto"!==t?t:`stably-${process.pid}`),o};return{hook:async o=>{const i=o&&"object"==typeof o&&"tool_input"in o&&o.tool_input&&"object"==typeof o.tool_input&&"command"in o.tool_input&&"string"==typeof o.tool_input.command?o.tool_input.command:"";if(!Rc.test(i)&&!Uc.test(i))return{decision:"approve"};if(Uc.test(i)&&!Rc.test(i)){if(!r)try{r=await jc(),ls.info("[pwtrace-hook] Resolved binary",{path:r})}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:`pwtrace binary not found: ${t}`}}const e=`${process.execPath} ${r}`;return{decision:"approve",hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:i.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}}}}if(Uc.test(i)&&!r)try{r=await jc(),ls.info("[pwtrace-hook] Resolved binary (mixed command)",{path:r})}catch{}const c=!!e.cloudBrowserManager,l=new RegExp(`\\bstably-browser\\s+${Lc}close\\b(?!-)`).test(i),u=new RegExp(`\\bstably-browser\\s+${Lc}close-all\\b`).test(i),d=new RegExp(`\\bstably-browser\\s+${Lc}(?!close(?:-all)?\\b)\\w`).test(i);if(u){if(s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure via close-all",{reason:s.reason}),s=void 0),!d&&0===n.size)return{decision:"approve"};if(c){const t=e.cloudBrowserManager;await Promise.all(Array.from(n).map(e=>t.releaseSession(e)))}if(n.clear(),!d){if(!t)try{t=await Bc()}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:`stably-browser binary not found: ${t}`}}const e=`${process.execPath} ${t}`;let n=i.replace(/((?:npx\s+)?stably-browser\b[^;&|]*?)\s+(?:-s[= ]|--session[= ])[^\s;&|]+/g,"$1").replace(/(?<![./])\b(?:npx\s+)?stably-browser\b/g,e);if(Uc.test(n)&&r){const e=`${process.execPath} ${r}`;n=n.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}return{hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:n}}}}}if(l){if(s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure via close",{reason:s.reason}),s=void 0),!d&&0===n.size)return{decision:"approve"};const t=Gc(o),r=Hc(a(),t);n.delete(r),c&&e.cloudBrowserManager.getConfigPath(r)&&e.cloudBrowserManager.releaseSession(r)}if(!t)try{t=await Bc(),ls.info("[stably-browser-hook] Resolved binary",{path:t})}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:c?`stably-browser binary not found: ${t}. The stably-browser tool is unavailable. upload-trace-proof only uploads existing traces and does not depend on stably-browser, so it still works regardless. Report this issue to the user and suggest running locally instead.`:`stably-browser binary not found: ${t}. The stably-browser tool is unavailable. upload-trace-proof only uploads existing traces and does not depend on stably-browser, so it still works.`}}const p=Gc(o),f=Hc(a(),p),h=new RegExp(`\\bstably-browser\\s+${Lc}open\\b`).test(i);if(h&&s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure",{sessionName:f,reason:s.reason}),s=void 0),s)return{decision:"block",reason:`Browser unavailable: ${s.reason}`,systemMessage:s.guidance};if(c&&e.cloudBrowserManager.needsRecreation(f)&&n.has(f)&&(ls.info("[stably-browser-hook] Cloud browser needs recreation, clearing session",{sessionName:f}),n.delete(f),e.cloudBrowserManager.releaseSession(f)),(!l&&!u||d)&&!n.has(f))if(c){n.add(f),ls.info("[stably-browser-hook] Provisioning cloud browser...",{sessionName:f});try{let r=!1;const o=await e.cloudBrowserManager.acquire(f,()=>{r||(r=!0,e.onStatusLabel?.("Waiting for a browser to become available..."))});if(r&&e.onStatusLabel?.(void 0),o.liveViewUrl&&process.stderr.write(`Live view: ${o.liveViewUrl}\n`),!h){const r=e.cloudBrowserManager.getConfigPath(f),o=await Fc(t,f,e.headed,r??void 0);if(!o.ok)return n.delete(f),o.permanent&&(s={reason:o.reason,guidance:o.guidance}),{decision:"block",reason:`Failed to start stably-browser daemon with cloud browser: ${o.reason}`,systemMessage:o.guidance}}}catch(e){n.delete(f);const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:`Cloud browser unavailable: ${t}`,systemMessage:`Failed to provision cloud browser: ${t}. Remove --browser=cloud to use a local browser instead.`}}}else if(h)n.add(f);else{n.add(f),ls.info("[stably-browser-hook] First browser command, starting daemon...",{sessionName:f,agentId:p});let r=await Fc(t,f,e.headed,void 0,"chromium");if(!r.ok&&r.reason.includes("not installed")&&(ls.info("[stably-browser-hook] Chromium not found, falling back to system Chrome..."),r=await Fc(t,f,e.headed,void 0,"chrome")),!r.ok)return n.delete(f),r.permanent&&(s={reason:r.reason,guidance:r.guidance}),{decision:"block",reason:`Failed to start stably-browser daemon: ${r.reason}`,systemMessage:r.guidance}}const g=`${process.execPath} ${t}`;let m=i.replace(/(?<![./])\b(?:npx\s+)?stably-browser\b/g,g);if(Uc.test(m)&&r){const e=`${process.execPath} ${r}`;m=m.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}const y=[];if(m.includes("-s=")||m.includes("--session=")||y.push(`-s=${f}`),c){const t=e.cloudBrowserManager.getConfigPath(f);t&&!m.includes("--config=")&&y.push(`--config=${t}`),m=m.replace(/\s*--browser[= ]\S+/g,"")}e.headed&&!m.includes("--headed")&&y.push("--headed"),y.length>0&&(m=m.replaceAll(g,`${g} ${y.join(" ")}`)),u&&(m=m.replace(/([^;&|]*?\bclose-all\b)/g,e=>e.replace(/\s+(?:-s[= ]|--session[= ]|--config[= ])[^\s;&|]+/g,""))),$c.test(i)&&!m.includes("--trace")&&(m=m.replaceAll(/\brun-test\b/g,"run-test --trace=on")),$c.test(i)&&f!==a()&&!m.includes("--output")&&(m=m.replaceAll(/\brun-test\b/g,`run-test --output=.stably-browser/${f}/test-results`)),e.envVars&&(m=m.replace(Dc,(t,r)=>{const n=e.envVars[r];return null!=n?n:t}));const b=[];if("linux"===process.platform&&"function"==typeof process.getuid&&0===process.getuid()&&b.push("PLAYWRIGHT_MCP_SANDBOX=false"),$c.test(i)&&e.envVars)for(const[t,r]of Object.entries(e.envVars))b.push(`${t}=${Nc(r)}`);return b.length>0&&(m=`${b.join(" ")} ${m}`),ls.debug("[stably-browser-hook] Rewritten command",{original:i.slice(0,100),sessionName:f,agentId:p,envVarCount:b.length}),{hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:m}}}},cleanup:async()=>{t&&n.size>0&&(await Promise.all(Array.from(n).map(e=>{return r=t,n=e,new Promise(e=>{m(process.execPath,[r,"close",`-s=${n}`],{timeout:1e4},t=>{t&&ls.debug("[stably-browser-hook] Failed to stop daemon",{error:t.message,sessionName:n}),e()})});var r,n})),n.clear()),e.cloudBrowserManager?.isActive()&&await e.cloudBrowserManager.release()}}}({sessionName:Jc({configuredSessionName:process.env.STABLY_PLAYWRIGHT_SESSION,isFixMode:Mt,useCloudBrowser:Ft}),headed:!("chat"!==e.mode||process.env.CI||"linux"===process.platform&&!process.env.DISPLAY),envVars:Gt,cloudBrowserManager:Ht,onStatusLabel:e=>qe({label:e})}),Vt=Mt?Mr.createLocal({workingDir:f}):void 0;Vt&&await Vt.captureSnapshot();const Yt=()=>{jt&&function({workingDir:e,options:t={}}){const n=function(e){const t=function(e){let t=r.resolve(e);for(;;){if(w.existsSync(r.join(t,".git")))return t;const n=r.dirname(t);if(n===t)return r.resolve(e);t=n}}(e),n=function(e,t){for(const r of cc(e,t))if(rc(r))return r}(e,t),s=oc(nc(e,/playwright\.config\.(ts|js|mts|mjs|cjs)$/).map(e=>r.dirname(e))),o=function(e){const t=new Set;for(const n of e)t.add(sc(r.dirname(n)));return oc(Array.from(t))}(nc(e,/\.(spec|test)\.(ts|js)$/)),i=s.length>0?s:o,a=n??(1===i.length?i[0]:void 0)??e,c=ac(a,t);if(!c)return{repoRoot:t,projectRoot:a,targetDir:void 0};if(!n&&c===r.resolve(e)&&function(e,t,r){const n=new Set;for(const s of e){const e=ac(s,r);e&&e!==t&&n.add(e)}return n.size>1}(i,c,t))return{repoRoot:t,projectRoot:a,targetDir:void 0};const l=ec(c);if(!l||!("workspaces"in l.contents))return{repoRoot:t,projectRoot:a,targetDir:c};const u=function(e,t){let n=r.resolve(e);const s=r.resolve(t);for(;n!==s;){if(w.existsSync(r.join(n,"package.json")))return n;const e=r.dirname(n);if(e===n)break;n=e}}(a,c);return{repoRoot:t,projectRoot:a,targetDir:u??c}}(e);if(n.targetDir){try{!function(e){const t=r.join(e,"package.json");if(!w.existsSync(t))return;const n=JSON.parse(w.readFileSync(t,"utf-8"));if({...n.dependencies,...n.devDependencies}.stably)ls.debug("stably package already present in dependencies");else{ls.info("stably package missing from devDependencies, installing...");try{Za({workingDir:e,packageManager:uc(e),packageSpec:"stably",targetSection:"devDependencies"}),ls.info("stably package installed successfully")}catch(e){ls.warn("Failed to install stably package",{error:String(e)})}}}(n.targetDir)}catch(e){ls.warn("Post-init: ensureStablyDependency failed",{error:String(e)})}try{!function(e){const t=ec(e);if(!t)return;const r=t.contents.devDependencies?.playwright??t.contents.dependencies?.playwright;if(r)if(lc(r)!==Bs)try{Za({workingDir:e,packageManager:uc(e),packageSpec:`playwright@${Bs}`,targetSection:t.contents.devDependencies?.playwright?"devDependencies":"dependencies"}),ls.info("standalone playwright version aligned successfully",{version:Bs})}catch(e){ls.warn("Failed to align standalone playwright version",{error:String(e)})}else ls.debug("standalone playwright already at supported version",{version:Bs});else ls.debug("standalone playwright package not present")}(n.targetDir)}catch(e){ls.warn("Post-init: alignStandalonePlaywrightVersion failed",{error:String(e)})}try{!function(e){const t=ec(e);if(t)if(lc(t.contents.devDependencies?.["@playwright/test"]??t.contents.dependencies?.["@playwright/test"])!==Bs)try{ls.info(`Updating @playwright/test to supported version ${Bs}...`),Za({workingDir:e,packageManager:uc(e),packageSpec:`@playwright/test@${Bs}`,targetSection:t.contents.dependencies?.["@playwright/test"]?"dependencies":"devDependencies"}),ls.info("@playwright/test updated successfully")}catch(e){ls.warn("Failed to update @playwright/test",{error:String(e)})}else ls.debug("@playwright/test already at supported version",{version:Bs});else ls.debug("No package.json found, skipping @playwright/test update")}(n.targetDir)}catch(e){ls.warn("Post-init: updatePlaywrightTest failed",{error:String(e)})}try{!function(e,t,n){const s=[];n.googleAuth&&s.push("Google Auth methods"),n.emailPackage&&s.push("@stablyai/email Inbox methods for email verification flows");const o=`Use Stably CLI for Playwright test runs (better reporting, auto-fix); import from @stablyai/playwright-test for agent.act(), aiAssert, page.extract(), page.getLocatorsByAI()${s.length>0?`; also use ${s.join(" and ")}`:""}.`,i=function(e,t){const n=["CLAUDE.md","AGENTS.md","AGENT.md","agent.md"];for(const s of cc(e,t)){let t;for(const o of n){const n=r.join(s,o);if(!w.existsSync(n))continue;t??=n;const i=w.readFileSync(n,"utf-8");if(/Stably CLI/i.test(i)&&i.includes("@stablyai/playwright-test"))return void ls.debug("Agent guidance already present",{file:r.relative(e,n)||o});if(ic(i))return n}if(t)return t}return r.join(e,"AGENTS.md")}(e,t);if(i){ls.info("Appending Stably guidance",{file:r.basename(i)});try{const e=w.existsSync(i)?w.readFileSync(i,"utf-8"):"",t=e.length>0&&!e.endsWith("\n")?"\n\n":e.length>0?"\n":"";w.writeFileSync(i,`${e}${t}${o}\n`,"utf-8"),ls.info("Agent guidance appended successfully")}catch(e){ls.warn("Failed to update agent guidance file",{error:String(e)})}}}(n.targetDir,n.repoRoot,t)}catch(e){ls.warn("Post-init: ensureAgentGuidance failed",{error:String(e)})}}else ls.warn("Post-init: could not resolve target package directory; skipping verification",{workingDir:e})}({workingDir:f,options:{googleAuth:R?.googleAuth,emailPackage:R?.emailPackage}})},zt=jt?(({onComplete:e})=>G({name:"session-control",tools:[W("complete_session",["Call this tool when you have completed your task and the session should end.","Use this instead of waiting for the user to manually terminate.","Only call this when you are confident the task is fully complete."].join("\n"),{summary:we.string().describe("A brief summary of what was accomplished")},({summary:t})=>{const r="string"==typeof t?t:String(t);return e(),Promise.resolve(`Session complete: ${r}`)})]}))({onComplete:()=>{Yt(),Ze({status:"success"}),ze(),U?.finish(),Ht?(setTimeout(()=>process.exit(0),5e3).unref(),Ht.release().finally(()=>process.exit(0))):process.exit(0)}}):void 0,qt=zt?{"session-control":zt}:{},Kt=S&&Ut?["mcp__create-report"]:[],Jt=S&&Se?["mcp__upload-trace-proof"]:[],Xt=jt?ul:k?cl:[...cl,...Mt?["mcp__auto-heal-report"]:[],...Kt,...Jt],Qt=jt?ul:T?[...ll,"mcp__stably-agent-control"]:k?ll:[...ll,...Kt,...Jt],Zt=S&&Ut?{"create-report":pc({prContext:Ut,authProvider:d,orgId:p,onReportPosted:e=>{_e({githubComment:{url:e.commentUrl,prNumber:Ut.prNumber}})}})}:{},er=S&&Se?{"upload-trace-proof":Xa({requestUploadUrl:e=>{const{testFilePath:t}=e;if(!t)return Promise.reject(new Error("testFilePath is required for create-mode trace uploads"));const r=Se;return d.getAuthHeader().then(e=>(async({authHeader:e,sessionId:t,testFilePath:r,orgId:n,contentType:s="application/zip"})=>{const o=await(i={auth:e,body:{testFilePath:r,contentType:s},client:In(),headers:_s(n),path:{sessionId:t}},(i.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/trace/upload-url",...i,headers:{"Content-Type":"application/json",...i.headers}}));var i;if(o.error)throw new Error(`Failed to presign session trace upload (${o.response.status})`);const a=fc.parse(o.data);return{traceBucketPath:a.traceBucketPath,expiresInSeconds:a.expiresInSeconds,key:a.key,uploadUrl:a.uploadUrl,sensitiveValues:a.sensitiveValues}})({authHeader:e,sessionId:r,testFilePath:t,orgId:p}))},onTraceUploaded:e=>{_e({traceProofs:Us(Te?.traceProofs??[],e)})}})}:{},tr=jt?qt:P?{}:Mt&&Vt?{"auto-heal-report":Qa({authProvider:d,diffTracker:Vt,orgId:p,runId:e.runId,workingDir:f}),"run-history":yc({authProvider:d,orgId:p,projectId:bs(u)}),...qt}:{...qt,...Zt,...er,"run-history":yc({authProvider:d,orgId:p,projectId:bs(u)}),environment:wc({hookEnvVars:Gt,localEnvSnapshot:{...b}})},rr="single"===e.mode,nr=jt?[]:rr?[{matcher:"Write",hooks:[no({onFileCreated:e=>{if(st.includes(e)||st.push(e),Te){if(Te.filesCreated.some(t=>"string"==typeof t?t===e:t.path===e))return;const t=n.isAbsolute(e)?e:n.join(f,e),r=n.basename(e),{sessionId:s}=Te,o=(async()=>{try{const n=await v.promises.readFile(t,"utf8"),o=await(async({authHeader:e,content:t,contentType:r="text/plain",filename:n,filePath:s,orgId:o,sessionId:i})=>{try{const{bucketPath:a,uploadUrl:c}=await(async({authHeader:e,contentType:t="text/plain",filename:r,filePath:n,orgId:s,sessionId:o})=>{const i=await(a={auth:e,body:{filename:r,filePath:n,contentType:t},client:In(),headers:_s(s),path:{sessionId:o}},(a.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/files/upload-url",...a,headers:{"Content-Type":"application/json",...a.headers}}));var a;if(i.error)throw new Error(`Failed to presign file upload (${i.response.status})`);const c=$s.parse(i.data);return{bucketPath:c.bucketPath,expiresInSeconds:c.expiresInSeconds,key:c.key,uploadUrl:c.uploadUrl}})({authHeader:e,contentType:r,filename:n,filePath:s,orgId:o,sessionId:i});return await xs({body:t,contentType:r,uploadUrl:c,errorContext:"file"}),await(async({authHeader:e,bucketPath:t,filename:r,filePath:n,orgId:s,sessionId:o})=>{const i=await(a={auth:e,body:{filename:r,filePath:n,bucketPath:t},client:In(),headers:_s(s),path:{sessionId:o}},(a.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/files/confirm",...a,headers:{"Content-Type":"application/json",...a.headers}}));var a;if(i.error)throw new Error(`Failed to confirm file upload (${i.response.status})`)})({authHeader:e,bucketPath:a,filename:n,filePath:s,orgId:o,sessionId:i}),a}catch(e){return ls.warn("Failed to upload automation file",{error:e instanceof Error?e.message:String(e)}),null}})({authHeader:await d.getAuthHeader(),content:n,contentType:"text/plain",filename:r,filePath:e,orgId:p,sessionId:s}),i={path:e,filename:r,bucketPath:o};ot.push(i),_e({filesCreated:[...ot]})}catch(t){ls.warn("Failed to upload created file",{filePath:e,error:t instanceof Error?t.message:String(t)});const n={path:e,filename:r,bucketPath:null};ot.push(n),_e({filesCreated:[...ot]})}})();it.push(o)}}})]}]:[],sr=jt?[]:[...Mt?[{matcher:"Read",hooks:[Hs({action:"reading",pathKey:"file_path"})]},{matcher:"Write",hooks:[Hs({action:"writing",pathKey:"file_path"})]},{matcher:"Edit",hooks:[Hs({action:"editing",pathKey:"file_path"})]},{matcher:"Grep",hooks:[Hs({action:"searching",pathKey:"path"})]},{matcher:"Glob",hooks:[Hs({action:"searching",pathKey:"path"})]},{matcher:"Bash",hooks:[to({workspaceBoundary:f})]}]:[],...Wt?[{matcher:"Bash",hooks:[Wt.hook]}]:[],{hooks:[async e=>(e&&"object"==typeof e&&"tool_name"in e?e.tool_name:"").startsWith("mcp__plugin_playwright_playwright__browser_")?{decision:"block",reason:"Use stably-browser commands instead of the built-in Playwright MCP tools.",systemMessage:'Do NOT use mcp__plugin_playwright_playwright tools. Use stably-browser bash commands for all browser interaction:\n- `stably-browser open` / `stably-browser open <url>`\n- `stably-browser goto <url>`, `stably-browser click <ref>`, `stably-browser fill <ref> "text"`\n- `stably-browser snapshot`, `stably-browser screenshot`\n- `stably-browser run-test <file>`\n- `stably-browser close`'}:{decision:"approve"}]}],or=Object.keys(Lt).length>0?Lt:void 0,ir={...$t};ir.MCP_TOOL_TIMEOUT=String(6e5),Bt&&(ir.ANTHROPIC_API_KEY=Bt,ir.ANTHROPIC_BASE_URL=yn,ir.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS="1",ir.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1");const ar=process.env.STABLY_AGENT_MODEL??"claude-opus-4-6";!function(e,t){"env"===t.type&&(e.STABLY_API_KEY=t.auth.apiKey,e.STABLY_PROJECT_ID=t.auth.projectId)}(ir,u);const cr=yt?`\n\n## Authoritative Fix Rules (STABLY-FIX.md / stably.yaml)\nThese repository-specific fix instructions take precedence over generic fix guidance when they conflict.\n${yt}`:"",lr=_t?`\n\n## Authoritative Test Generation Rules (STABLY-CREATE.md)\nThese repository-specific create instructions take precedence over generic create guidance when they conflict.\n${_t}`:"",ur=St?`\n\n## Authoritative Project Rules (STABLY.md)\nThese repository-specific project instructions take precedence over generic guidance when they conflict. If STABLY-CREATE.md is also present, use it for create-specific conflicts.\n${St}`:"",dr=ft?"\n\n## Cloud Browser Mode\nYou are running in cloud browser mode. Cloud browsers are remote VMs β there is no local resource cost.\n\n**Each subagent MUST use its own isolated browser session.** Do NOT reuse or share browser sessions between subagents. Session isolation is automatic β each subagent simply calls `stably-browser open` and gets its own browser.\n\nWhen running tests with `stably-browser run-test`, each subagent also gets its own browser automatically.":"",pr=dt.isEsmProject?'\n\n## ES Module Project\nThis project uses ES modules (`"type": "module"` in package.json). You MUST use `import`/`export` syntax β never use `require()` or `module.exports`. `require()` is not available in ES module scope and will throw `ReferenceError: require is not defined`.\n\nWhen writing ANY JavaScript or TypeScript code (test files, helper scripts, temporary scripts, config files):\n- Use `import ... from "..."` instead of `const ... = require("...")`\n- Use `export` / `export default` instead of `module.exports`\n- Use `import { readFileSync } from "node:fs"` instead of `require("fs")`\n- Use `import { fileURLToPath } from "node:url"` and `import { dirname } from "node:path"` instead of `__dirname`/`__filename`':"",fr=Rt+cr+lr+ur+dr+pr;ls.debug("[fix] Final system prompt assembled",{baseSize:Rt.length,fixRulesSize:cr.length,createRulesSize:lr.length,stablyMdSize:ur.length,cloudBrowserSize:dr.length,esmSectionSize:pr.length,isEsmProject:dt.isEsmProject,finalSize:fr.length});const hr=function(){const e=function(){const e=function(){const e=process.env.STABLY_PLUGIN_PATH?.trim();if(!e)return;const t=n.isAbsolute(e)?e:n.resolve(process.cwd(),e);return kc(t)?t:void 0}();if(e)return e;const t=n.join(Sc,"stably-plugin-cli");if(kc(t))return t;for(const e of function*(e){let t=n.resolve(e);for(;;){yield t;const e=n.dirname(t);if(e===t)return;t=e}}(Sc))for(const t of Ac){const r=n.join(e,t);if(kc(r))return r}}();if(e)return{type:"local",path:e}}(),gr=()=>(ls.info("[fix] Starting SDK query",{model:ar,tools:Xt,mcpServers:Object.keys(tr),resumeSessionId:B??null,subagentsEnabled:!!or,subagentCount:Object.keys(Lt).length,useStablyAiProxy:Dt,aiProxyUrl:yn,anthropicBaseUrl:void 0,stablyPluginPath:hr?.path,stablyPluginExists:!!hr}),V({options:{executableArgs:["--max-old-space-size=4096"],tools:Xt,allowedTools:Qt,...null!=It?{maxBudgetUsd:It}:{},betas:[],canUseTool:(e,t)=>(ls.debug("[fix] canUseTool called",{toolName:e}),Promise.resolve({behavior:"allow",updatedInput:t})),cwd:f,env:ir,hooks:{PostToolUse:nr,PreToolUse:sr},includePartialMessages:!0,agents:or,mcpServers:tr,model:ar,permissionMode:"default",plugins:hr?[hr]:void 0,systemPrompt:fr,...B?{resume:B}:{}},prompt:U??ut})),mr=async e=>{if(I&&F&&!J&&!M)M=(async()=>{ls.info("[fix] Interrupting for user message",{messageCount:e.length,phase:ue?.phase});try{await(O?.interrupt?.())}catch(e){ls.warn("[fix] Failed to interrupt response for user message",{error:e instanceof Error?e.message:String(e)})}await oo(),U?.finish(),U=new io,Z.clear(),O=gr();const t=e.map(e=>`[Message from web UI user]: ${e}`).join("\n\n");U.pushText(`[SYSTEM] The user sent a message while you were working. Read their message below, incorporate their feedback, and continue your task. Do not restart from scratch unless the user explicitly asks.\n\n${t}`),X=!0,F=!0})().finally(()=>{M=void 0}),await M;else for(const t of e)U?.pushText(`[Message from web UI user]: ${t}`)};if(Bt){k&&qe({label:"Checking AI connectivity..."});const e=yn,t=`${e.replace(/\/$/,"")}/v1/messages`;ls.debug(`[fix] Pre-flight: POST ${t}`);const r=Date.now();let n;try{const e=await fetch(t,{method:"POST",signal:AbortSignal.timeout(1e4),headers:{"x-api-key":Bt,"anthropic-version":"2023-06-01","content-type":"application/json"},body:"{}"}),s=await e.text().catch(()=>""),o=Date.now()-r;ls.debug(`[fix] Pre-flight: ${e.status} in ${o}ms β ${s.slice(0,300)}`),401===e.status||403===e.status?(ls.error(`[fix] Pre-flight: AI proxy key rejected (${e.status}) at ${t}`),n="Unable to start verification: AI proxy credentials were rejected. Please run `stably login` and try again."):ls.info("[fix] Pre-flight: AI proxy key valid",{status:e.status,durationMs:o})}catch(t){ls.error("[fix] Pre-flight: AI proxy unreachable",{error:t instanceof Error?t.message:String(t),durationMs:Date.now()-r,url:e}),n="Unable to start verification: cannot reach the AI proxy. Please check your network/VPN and try again."}finally{k&&"running"===Qe&&qe({label:void 0})}n&&(je({text:`[stably] ${n}\n`}),Ze({error:n,status:"error"}),await Ge(),ls.flush(),ls.printLogFileInfo(),process.exit(1))}ls.info("[fix] Creating initial agent query"),k&&(qe({label:"Initializing verification session..."}),je({text:"Initializing verification session...\n"})),ls.flush(),O=gr(),ls.info("[fix] Agent query created, entering message loop"),"chat"!==e.mode&&(U.pushText(ut),ee.push({role:"user",content:ut,timestamp:(new Date).toISOString()}));const yr=async t=>{Ce||(Ce=(async()=>{ls.info("[session] Interrupt requested",{source:t,mode:e.mode}),oe="CANCELED",await be("CANCELED"),ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await(le?.closeAndWait()),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0}),await(Ie?.closeAndWait()),j&&(clearTimeout(j),j=void 0),ze(),await oo(),await(Wt?.cleanup());try{await(O?.interrupt?.())}catch{}if(U?.finish(),ee.length>0&&Se)try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[exit] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}Ge(),ls.flush()})()),await Ce};ke.current=async()=>{await yr("ctrl-c")};let br=()=>{};br=function({enabled:e,onSignal:t}){const r=()=>{t("SIGINT")},n=()=>{t("SIGTERM")};return process.prependOnceListener("SIGINT",r),process.prependOnceListener("SIGTERM",n),()=>{process.removeListener("SIGINT",r),process.removeListener("SIGTERM",n)}}({enabled:!0,onSignal:e=>{(async()=>{await yr("signal"),process.exit(function(e){return"SIGINT"===e?130:143}(e))})()}});let wr=null,vr=null,Ir="";Re.current=async()=>{if(!Le&&F&&U){Le=!0;try{ls.info("[chat] User pressed Escape to cancel generation"),We(),Ve(),H=!0,$e=!0;try{await(O?.interrupt?.())}catch(e){ls.warn("[chat] Failed to interrupt response on Escape",{error:e instanceof Error?e.message:String(e)})}await oo();const e=U.drainQueue();U.finish(),U=new io;for(const t of e)U.pushText(t);q=e.length,O=gr();for(const e of Z.keys())Je({toolUseId:e,status:"error"});Be()}finally{Le=!1}}};let Tr=0,_r=null,Er=!1;const Sr=T?void 0:k?9e4:18e4;let xr=!1;const Ar=null!=Sr?setTimeout(()=>{_r||"running"!==Qe||(t=>{if(!xr){if(xr=!0,clearTimeout(Ar),clearInterval(kr),setTimeout(()=>process.exit(1),6e4).unref(),ls.error("[session] Session timeout",{reason:t,mode:e.mode,elapsed:Date.now()-ce}),oe="FAILED",k||T){const e="This is taking longer than expected. Please try again.";je({text:`[stably] ${e}\n`}),Ze({error:e,status:"error"})}else ye({phase:"complete",endedAt:Date.now(),isError:!0,errorReason:"execution_error",errorMessage:`Session timed out: ${t}`,workers:me(!0)});_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:`Timed out: ${t}`});try{O?.interrupt?.()}catch{}U?.finish()}})("no response from AI service")},Sr):void 0;Ar?.unref();const kr=setInterval(()=>{const e=Date.now()-ce;_r?ls.info("[fix] Watchdog: message loop active",{messageCount:Tr,elapsed:e}):(ls.info("[fix] Watchdog: waiting for first SDK message",{elapsed:e}),k&&!Er&&e>=15e3&&(je({text:"Still preparing verification. This can take a bit...\n"}),Er=!0)),ls.flush()},15e3);kr.unref();try{let t=!1,r=!1;for(;;){if(!O){ls.info("[fix] No response object, exiting message loop");break}t=!1,r=!1,ls.info("[fix] Entering for-await on SDK response");try{for await(const t of O){if(xr)break;Tr++,_r||(_r=Date.now(),clearTimeout(Ar),k&&qe({label:void 0}),ls.info("[fix] First SDK message received",{waitDurationMs:_r-ce,messageType:t.type,messageSubtype:"subtype"in t?t.subtype:void 0}));const n="session_id"in t&&"string"==typeof t.session_id?t.session_id:void 0;if(n&&n!==B&&(B=n,ls.debug("Captured Claude session id",{sessionId:B})),"stream_event"===t.type){const{event:e}=t;(Tr<=5||Tr%200==0)&&ls.debug("[fix] Stream event",{msgNum:Tr,eventType:e?.type});const r=e&&"object"==typeof e&&"parent_tool_use_id"in e&&"string"==typeof e.parent_tool_use_id?e.parent_tool_use_id:void 0;if("content_block_start"===e?.type){const t=e.content_block;"thinking"===t?.type&&(wr=e.index??null)}if("content_block_delta"===e?.type){const{delta:t}=e;if("text_delta"===t?.type&&t.text){Ir&&(te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),Ir="");const e=r&&Z.has(r)?r:1===Z.size?Array.from(Z.keys())[0]:void 0;e?De({toolUseId:e,kind:"text",content:t.text}):k||je({text:t.text})}const n=t;if("thinking_delta"===n?.type&&n.thinking){if(r&&Z.has(r))continue;if(Ir+=n.thinking,!k){const e=null!==wr&&wr!==vr;Me({text:n.thinking,forceNewBlock:e}),e&&(vr=wr)}continue}}if("content_block_stop"===e?.type){const t=e.index;null!==wr&&wr===t&&(Ve(),Ir&&(te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),Ir=""),wr=null,Ye())}"message_stop"===e?.type&&U&&(J=!1,U.allowNextTurn());continue}if("assistant"===t.type){const r="parent_tool_use_id"in t&&"string"==typeof t.parent_tool_use_id?t.parent_tool_use_id:void 0,{content:n}=t.message??{};if(Array.isArray(n)&&!r){const t=n.filter(e=>e&&"object"==typeof e&&"type"in e&&"text"===e.type).map(e=>e&&"object"==typeof e&&"text"in e&&"string"==typeof e.text?e.text:void 0).filter(Boolean).join("\n");t&&(rt=t,k&&(nt=nt?`${nt}\n\n${t}`:t),ls.debug("Assistant message",{text:k?tl(t):t}),"fix"===e.mode&&(he(pl,{type:"ai_message",summary:t.slice(0,200)}),ge({type:"ai_message",summary:t.slice(0,200)})),C&&Ee({type:"ai_message",summary:t.slice(0,200)}),te({role:"assistant",content:t,timestamp:(new Date).toISOString()}))}if(Z.size>0){const e=Array.isArray(n)?n.filter(e=>e&&"object"==typeof e&&"type"in e&&"tool_use"===e.type).map(e=>e&&"object"==typeof e&&"name"in e&&"string"==typeof e.name?e.name:void 0):[];ls.debug("Assistant message with active subagents",{hasParentToolUseId:!!r,parentToolUseId:r,activeSubagentIds:Array.from(Z.keys()),toolNames:e,fullMessageKeys:Object.keys(t),rawMessage:JSON.stringify(t).slice(0,500)})}if(Array.isArray(n))for(const t of n){if("tool_use"===t?.type){if("mcp__auto-heal-report__generate-report"===t.name&&(J=!0),t.name.startsWith("mcp__session-control__")||t.name.startsWith("mcp__stably-agent-control__"))continue;if(yl(t.name))continue;if(k&&ml.test(t.name))continue;if(Z.size>0&&ls.debug("Tool use detected with active subagents",{toolName:t.name,hasParentToolUseId:!!r,parentToolUseId:r,wouldRouteToSubagent:!!r&&Z.has(r),activeSubagentIds:Array.from(Z.keys())}),"Task"===t.name){const r=t.input,n=r&&"object"==typeof r?r:void 0,s=n&&"subagent_type"in n&&"string"==typeof n.subagent_type?n.subagent_type:"subagent",o=n&&"description"in n&&"string"==typeof n.description?n.description.trim():"";if(ls.info("[fix] Subagent started",{subagentType:s,description:o,toolUseId:t.id,activeSubagentCount:Z.size+1}),Z.set(t.id,{subagentType:s,description:o}),Ne({toolUseId:t.id,subagentType:s,description:o}),"fix"===e.mode){if("triage"===s){Xe?.({phase:"triage"});const e={id:t.id,testDescription:"Triage",workerType:"triage",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};ye({phase:"triage",workers:[...ue?.workers??[],e]})}else if("code-worker"===s){de.add(o||t.id);const e={id:t.id,testDescription:o||t.id,workerType:"code-worker",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};Xe?.({phase:"fixing",totalTests:de.size,currentTestDescription:o||null}),ye({phase:"fixing",totalTests:de.size,currentTestDescription:o||null,lastTestDescription:o||ue?.lastTestDescription||null,workers:[...ue?.workers??[],e]})}else if("browser-worker"===s){de.add(o||t.id);const e={id:t.id,testDescription:o||t.id,workerType:"browser-worker",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};Xe?.({phase:"debugging",totalTests:de.size,currentTestDescription:o||null}),ye({phase:"debugging",totalTests:de.size,currentTestDescription:o||null,lastTestDescription:o||ue?.lastTestDescription||null,workers:[...ue?.workers??[],e]})}else"validation"===s?(Xe?.({phase:"validation",currentTestDescription:null}),ye({phase:"validation",currentTestDescription:null})):"context"===s&&ye({currentTestDescription:o||null});ge({type:"tool_call",summary:`[${s}] ${o}`.trim()})}if(S)if("create-planner"===s)_e({phase:"planning",currentActivity:"Analyzing test plan..."}),Ee({type:"tool_call",summary:`[create-planner] ${o}`.trim()});else if("create-worker"===s){const e=o.match(/(?:route|page)[:\s]+([^\s,]+)/i),r=(e?.[1]??o.slice(0,50))||t.id,n=o.match(/(\d+)\s*test/i),s=n?parseInt(n[1],10):1,i={pageGroupId:t.id,route:r,status:"exploring",testsCreated:0,testsTotal:s};pe.set(t.id,i),_e({phase:"generating",currentActivity:`Worker exploring ${r}...`,workers:Array.from(pe.values())}),Ee({type:"tool_call",summary:`[create-worker] ${o}`.trim()})}continue}if(r&&Z.has(r)){const n=Lo(t.name,t.input),s=n??$o(t.name),o=n?void 0:Uo(t.name,t.input),i=o?`${s} (${o})`:s;if(ls.debug("Subagent tool called",{tool:t.name,parentToolUseId:r}),De({toolUseId:r,kind:"tool",content:i}),"fix"===e.mode){ge({type:"tool_call",summary:i});const e=Z.get(r);"code-worker"!==e?.subagentType&&"browser-worker"!==e?.subagentType&&"triage"!==e?.subagentType||he(r,{type:"tool_call",summary:i})}if(S){const e=Z.get(r);if(("create-planner"===e?.subagentType||"create-worker"===e?.subagentType)&&(Ee({type:"tool_call",summary:i}),"create-worker"===e.subagentType&&pe.has(r))){const e="Bash"===t.name&&t.input&&"object"==typeof t.input?t.input.command:void 0;t.name.includes("run-test")||t.name.includes("run_test")||"string"==typeof e&&e.includes("run-test")?fe(r,{status:"validating"}):"Write"!==t.name&&"Edit"!==t.name||fe(r,{status:"writing"})}}continue}if(r&&ls.debug("Tool with parent_tool_use_id but no matching subagent",{tool:t.name,parentToolUseId:r,activeSubagentIds:Array.from(Z.keys())}),ls.debug("Tool called",{tool:t.name,input:t.input}),Oe({rawName:t.name,toolInput:t.input}),t.id&&se.set(t.id,t.name),te({role:"tool",content:"",timestamp:(new Date).toISOString(),toolName:t.name,toolInput:t.input}),"fix"===e.mode){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=n?`${r} (${n})`:r;he(pl,{type:"tool_call",summary:s}),ge({type:"tool_call",summary:s})}if(S){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=n?`${r} (${n})`:r;"initializing"===Te?.phase?_e({phase:"generating",currentActivity:s}):"mcp__playwright-test__test_run"===t.name&&"generating"===Te?.phase?_e({phase:"testing",currentActivity:s}):_e({currentActivity:s}),Ee({type:"tool_call",summary:s})}if(k){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=tl(n?`${r} (${n})`:r);_e("initializing"===Te?.phase?{phase:"verifying",currentActivity:s}:{currentActivity:s}),Ee({type:"tool_call",summary:s})}}if("text"===t?.type){const n="string"==typeof t.text?t.text:"",s=r&&Z.has(r)?r:1===Z.size?Array.from(Z.keys())[0]:void 0;if(s&&n){if(De({toolUseId:s,kind:"text",content:n}),"fix"===e.mode){const e=Z.get(s);"code-worker"!==e?.subagentType&&"browser-worker"!==e?.subagentType&&"triage"!==e?.subagentType||he(s,{type:"ai_message",summary:n.slice(0,200)})}if(S){const e=Z.get(s);"create-planner"!==e?.subagentType&&"create-worker"!==e?.subagentType||Ee({type:"ai_message",summary:n.slice(0,200)})}}}}continue}if("user"===t.type){const r="message"in t&&t.message&&"object"==typeof t.message&&"content"in t.message?t.message.content:void 0,n="tool_use_result"in t&&t.tool_use_result&&"object"==typeof t.tool_use_result?t.tool_use_result:void 0;if(Array.isArray(r))for(const t of r)if(t&&"object"==typeof t&&"type"in t&&"tool_result"===t.type&&"tool_use_id"in t){const r="string"==typeof t.tool_use_id?t.tool_use_id:void 0,s="is_error"in t&&!0===t.is_error||"error"===n?.status;let o;const i=n?.content??("content"in t?t.content:void 0);"string"==typeof i?o=i:Array.isArray(i)&&(o=i.filter(e=>e&&"object"==typeof e&&"text"===e.type).map(e=>e.text||"").join("")),ls.debug("Tool result",{toolUseId:r,isError:s,output:o?.slice(0,500)});const a=5e4,c=r?se.get(r):void 0;if(te({role:"tool_result",content:"",timestamp:(new Date).toISOString(),toolName:c,toolOutput:o?.slice(0,a),isError:s}),r&&Z.has(r)){const t=Z.get(r);if(ls.info("[fix] Subagent completed",{toolUseId:r,isError:s,subagentType:t?.subagentType,description:t?.description,activeSubagentCount:Z.size-1}),o&&De({toolUseId:r,kind:"text",content:o}),Je({toolUseId:r,status:s?"error":"complete"}),"fix"===e.mode&&"triage"===t?.subagentType){const e=s?"failed":"succeeded",t=o?o.slice(0,500):null,n=(ue?.workers??[]).map(n=>n.id===r?{...n,status:e,summary:t,endedAt:Date.now()}:n);ye({workers:n})}if("fix"===e.mode&&("code-worker"===t?.subagentType||"browser-worker"===t?.subagentType)){const e=s?"failed":"succeeded",t=o?o.slice(0,500):null,n=(ue?.workers??[]).map(n=>n.id===r?{...n,status:e,summary:t,endedAt:Date.now()}:n);s?(Xe?.({failedTests:(ue?.failedTests??0)+1,currentTestDescription:null}),ye({failedTests:(ue?.failedTests??0)+1,currentTestDescription:null,workers:n})):(Xe?.({fixedTests:(ue?.fixedTests??0)+1,currentTestDescription:null}),ye({fixedTests:(ue?.fixedTests??0)+1,currentTestDescription:null,workers:n}))}if(S&&t)if("create-planner"===t.subagentType)Ee({type:"ai_message",summary:s?"Planner failed":"Test plan analyzed, launching workers..."}),s||_e({phase:"generating",currentActivity:"Launching workers..."});else if("create-worker"===t.subagentType){if(pe.has(r)){const e=o?.match(/\*\*Created:\*\*\s*(\d+)/i),t=e?parseInt(e[1],10):0;fe(r,{status:s?"failed":"complete",testsCreated:t})}Ee({type:"ai_message",summary:s?`Worker failed: ${t.description?.slice(0,100)}`:`Worker complete: ${t.description?.slice(0,100)}`})}Z.delete(r)}}continue}if("result"!==t.type);else{if(r=!0,ls.info("[fix] Agent result received",{subtype:t.subtype,messageCount:Tr,elapsed:Date.now()-ce,activeSubagents:Z.size,fixedTests:ue?.fixedTests,failedTests:ue?.failedTests,phase:ue?.phase}),I){if("success"===t.subtype){j&&(clearTimeout(j),j=void 0);for(const e of K)U?.pushText(`[Message from web UI user]: ${e}`);if(K=[],(C||"fix"===e.mode)&&U){if(U.hasQueuedMessages()){ls.info("[ws] Queued web UI messages found, continuing agent"),F=!0,U.allowNextTurn();continue}if(await bl(U,3e3)){ls.info("[ws] Web UI message received during grace period, continuing agent"),F=!0,U.allowNextTurn();continue}U.finish()}Xe?.({phase:"complete",currentTestDescription:null,endedAt:Date.now()}),ye({phase:"complete",currentTestDescription:null,endedAt:Date.now(),isError:!1,workers:me(!1)}),await Promise.allSettled(it);const t=sl({mode:e.mode,lastAssistantText:rt});if("verify"===e.mode){(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt).trim();const r=nt||rt,n=/```verdict\s*\r?\n/.test(r),s=nl(r)??{verdict:"INCONCLUSIVE",steps:["Agent finished without a parseable verdict block."],reason:n?"Failed to parse verdict.":"The agent completed without reporting a verdict.",evidence:[]},o=rl(s);"PASS"===s.verdict?Dr("success","VERIFICATION PASSED"):"FAIL"===s.verdict?Dr("error","VERIFICATION FAILED"):Dr("warning","VERIFICATION INCONCLUSIVE"),o.steps.length>0&&o.steps.forEach((e,t)=>{}),o.reason&&(s.verdict,o.reason),o.evidence.length>0&&o.evidence.forEach(e=>{}),_e({phase:"complete",endedAt:Date.now(),isError:"PASS"!==s.verdict,currentActivity:null,resultSummary:t}),process.exitCode="PASS"===s.verdict?0:"FAIL"===s.verdict?1:2,Ze({status:"success"})}else{if(_e({phase:"complete",endedAt:Date.now(),isError:!1,currentActivity:null,resultSummary:t}),rr&&st.length>0){process.stdout.write(Dr("success","Created files:")+"\n");for(const e of st)process.stdout.write(Dr("success",`- ${e}`)+"\n")}if(et){const e=process.stdout.isTTY?(e,t)=>`]8;;${e}${t}]8;;`:(e,t)=>t;process.stdout.write(Dr("info",`π View Autoheal Report:\n ${e(et,ne.bold(ne.underline(Dr("link",et))))}`)+"\n")}Ze({status:"success"}),oe="COMPLETED"}}else if(M||X)ls.info("[fix] Suppressing error status: user-message interrupt in progress");else if(H)oe="CANCELED",ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0});else if(k){let e="Execution error before verification completed.";"error_max_budget_usd"===t.subtype?e="Budget limit exceeded before verification completed.":"error_max_turns"===t.subtype&&(e="Maximum turns exceeded before verification completed."),Dr("warning","VERIFICATION INCONCLUSIVE"),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),Ze({status:"success"}),process.exitCode=2}else{let e,r="unknown",n="Run failed.";"error_max_budget_usd"===t.subtype?(r="budget_exceeded",e="total_cost_usd"in t?t.total_cost_usd:void 0,n=`Budget limit exceeded (${void 0!==e?`$${e.toFixed(2)}`:"unknown"} spent). The fix session was stopped to prevent runaway costs.`,ls.warn("[fix] Budget limit exceeded",{subtype:t.subtype,totalCostUsd:e})):"error_max_turns"===t.subtype?(r="max_turns",n="Maximum turns exceeded. The fix session was stopped."):"error_during_execution"===t.subtype&&(r="execution_error"),Xe?.({endedAt:Date.now(),isError:!0}),ye({phase:"complete",endedAt:Date.now(),isError:!0,errorReason:r,errorMessage:n,totalCostUsd:e,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),Ze({error:n,status:"error"}),process.exitCode=1,oe="FAILED"}H=!1;break}if("success"!==t.subtype){if(!H){let e="Run failed.";"error_max_budget_usd"===t.subtype?(e=`Budget limit exceeded (${"total_cost_usd"in t?`$${t.total_cost_usd.toFixed(2)}`:"unknown"} spent). The fix session was stopped to prevent runaway costs.`,ls.warn("[fix] Budget limit exceeded",{subtype:t.subtype,totalCostUsd:"total_cost_usd"in t?t.total_cost_usd:void 0})):"error_max_turns"===t.subtype&&(e="Maximum turns exceeded. The fix session was stopped."),Ze({error:e,status:"error"}),process.exitCode=1}}else Ze({status:"success"});F=!1,H=!1,qe({label:void 0}),U?.allowNextTurn(),_&&q>0&&(q-=1,F=!0,Ze({status:"running"}))}}}catch(e){if($e){$e=!1,H=!1,Z.clear(),He(),Ir&&te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),wr=null,vr=null,Ir="",Ye(),q>0?(F=!0,Ze({status:"running"})):(F=!1,Ze({status:"success"})),t=al(q);continue}const n=e instanceof Error&&"Claude Code process exited with code 1"===e.message;if(n&&r){ls.info("[fix] Claude Code process exited with code 1 (normal exit after result)",{inFlight:F,interrupted:H});break}if(n&&(X||M||H)){ls.info("[fix] Claude Code process exited with code 1 (interrupted)",{inFlight:F,interrupted:H,userMessageInterruptTriggered:!!X,interruptInProgress:!!M});break}throw e}if($e)$e=!1,H=!1,Z.clear(),He(),Ir&&te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),wr=null,vr=null,Ir="",Ye(),q>0?(F=!0,Ze({status:"running"})):(F=!1,Ze({status:"success"})),t=al(q);else if(M&&await M,X&&(X=!1,t=!0,Ze({status:"running"}),ls.info("[fix] Resuming after user-message interrupt")),!t)break}}catch(e){H?(oe="CANCELED",ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0})):(ls.error("[fix] Agent encountered an error",{error:e instanceof Error?e.message:String(e),stack:e instanceof Error?e.stack:void 0,elapsed:Date.now()-ce}),Ze({error:`Agent encountered an error: ${e}`,status:"error"}),process.exitCode=1,oe="FAILED",ye({phase:"complete",endedAt:Date.now(),isError:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),ls.flush(),ls.printLogFileInfo())}finally{if(Ar&&clearTimeout(Ar),clearInterval(kr),j&&(clearTimeout(j),j=void 0),ls.info("[fix] Agent session ending",{finalStatus:oe,elapsed:Date.now()-ce,totalMessages:Tr}),Yt(),F=!1,H=!1,br(),process.off("uncaughtException",l),U?.finish(),oe){ls.info("[fix] Reporting final autoheal status",{status:oe});const e=Date.now();await be(oe),ls.info("[fix] Final autoheal status reported",{durationMs:Date.now()-e})}if(ls.info("[fix] Closing WebSocket progress reporter"),await(le?.closeAndWait()),await Promise.allSettled(it),await(Ie?.closeAndWait()),!Mt&&ee.length>0&&Se){ls.info("[session] Uploading session history",{messageCount:ee.length});try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[session] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}}if(Mt&&Vt){const t=Date.now();try{ls.info("[fix] Computing diff...");const r=await Vt.computeDiff();if(r&&r.trim().length>0){ls.info("[fix] Uploading diff...",{diffLength:r.length});const n=await d.getAuthHeader(),{diffBucketPath:s,uploadUrl:o}=await Ps({authHeader:n,contentType:"text/plain",orgId:p,runId:e.runId});await xs({body:r,contentType:"text/plain",uploadUrl:o,errorContext:"diff"}),await Cs({authHeader:n,diffBucketPath:s,orgId:p,runId:e.runId}),ls.info("[fix] Diff uploaded",{durationMs:Date.now()-t})}else ls.info("[fix] No diff to upload (empty or no changes)")}catch(e){ls.warn("[fix] Failed to upload diff",{error:e instanceof Error?e.message:String(e),durationMs:Date.now()-t})}}if(ls.info("[fix] Cleaning up diff tracker"),await(Vt?.cleanup()),Mt&&ee.length>0&&Se){ls.info("[fix] Uploading session history",{messageCount:ee.length});try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[fix] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}}const t=n.join(f,".stably","traces");await Y(t,{recursive:!0,force:!0}).catch(()=>{}),ls.info("[fix] Running final cleanup"),await(Wt?.cleanup()),await Ge(),ls.info("[fix] Cleanup complete"),xr&&(ls.flush(),ls.printLogFileInfo(),process.exit(1))}},Tl=fe.object({runId:fe.string(),timestamp:fe.number()}),_l=async()=>{try{const e=await kn(process.cwd(),".stably/last-run.json");if(!e)return;const t=await z(e,"utf-8");return{...Tl.parse(JSON.parse(t)),filePath:e}}catch{return}};function El(e=process.cwd()){let t=s(e);for(;;){const e=Sl(t);if(e){const r={...e.dependencies,...e.devDependencies},n="@playwright/test"in r?"@playwright/test":"playwright"in r?"playwright":void 0;if(n){const e=xl(t);let r=!1,s=t;for(;;){const e=i(s,"node_modules"),t=i(e,n);if(E(t)){r=!0;break}const a=o(s);if(a===s)break;s=a}return{inNodeModules:r,installed:!0,packageManager:e,packageName:n}}}const r=o(t);if(r===t)return{inNodeModules:!1,installed:!1,packageManager:void 0};t=r}}function Sl(e){const t=i(e,"package.json");let r;try{r=x(t,"utf-8")}catch{return}try{return JSON.parse(r)}catch{return}}function xl(e){const t=[["npm","package-lock.json"],["pnpm","pnpm-lock.yaml"],["yarn","yarn.lock"]];let r=e;for(;;){for(const[e,n]of t)if(E(i(r,n)))return e;const e=o(r);if(e===r)return;r=e}}function Al(e){if("npm"===e||"pnpm"===e)return["npx","playwright"];if("yarn"===e)return["yarn","playwright"];throw new Error("Package manager not supported")}var kl=[{args:["--trace=on"],description:"Run Playwright tests",name:"test"},{args:[],description:"Install browser dependencies",name:"install"}],Pl=["You have two different versions of @playwright/test"];function Cl(e){const[t,...r]=Al(e),n=[t,...r.slice(0,-1)].join(" ");return(t,r)=>{let s=t.toString();for(const e of kl)s=s.replaceAll(`${n} playwright ${e.name}`,`${n} stably ${e.name}`).replaceAll(`npx playwright ${e.name}`,`npx stably ${e.name}`);if("yarn"===e){const e=s.split("\n");return e.length>0&&(e[0].includes("/.bin/playwright")||e[0].includes("\\.bin\\playwright"))&&e.shift(),void r.write(e.join("\n"))}r.write(s)}}async function Rl({overrideArgs:e,subcommand:t}){ls.info("[test] forwardToPlaywright starting",{subcommand:t,overrideArgs:e});const r=process.argv,n=r.findIndex((e,r)=>r>1&&e===t),a=-1===n?[]:r.slice(n+1),c="--"===a[0],u=c?a.slice(1):a;if(!c&&("--help"===u[0]||"-h"===u[0]))return async function({subcommand:e}){const t=kl.find(t=>t.name===e),r=e=>process.stdout.write(`${e}\n`);r(`stably ${e} - ${t?.description??""}`),r(""),"test"===e&&(r('IMPORTANT: Always use "stably" commands instead of "playwright" directly.'),r(""),r("Stably commands:"),r(" stably test [file] Run tests (auto-enables tracing and analytics)"),r(" stably fix [runId] Auto-fix failing tests using AI"),r(" stably create [prompt] Generate new tests from a prompt or branch diff"),r(""),r("Stably options:"),r(" --env <name> Load environment variables from a remote Stably environment"),r(" --env-file <path> Load environment variables from a local .env file (repeatable)"),r(""),r("Why use Stably?"),r(' - "stably fix" automatically repairs broken tests'),r(' - "stably test" enables --trace=on and test analytics'),r(' - "stably create" generates tests from prompt'),r(""));const n=El();if(!n.installed||!n.inNodeModules)return void r('No Playwright project found in this directory or its parents.\nMake sure you\'re in a directory within your Playwright project, or run "stably init" to create a new playwright directory.');const{packageManager:s}=n;if(!s)return void r("Could not determine package manager.");r("Playwright options:"),r("");const[o,...i]=Al(s),a=Cl(s);return new Promise(t=>{const r=g(o,[...i,e,"--help"],{stdio:["inherit","pipe","pipe"],shell:"win32"===process.platform,env:{...process.env,...process.env.CI?{}:{FORCE_COLOR:"1"}}});r.stdout?.on("data",e=>{a(e,process.stdout)}),r.stderr?.on("data",e=>{a(e,process.stderr)}),r.on("close",()=>{t()})})}({subcommand:t});const d=e??[],p=new Set(d.map(e=>{const[t]=e.split("=");return t})),f=[];for(let e=0;e<u.length;e++){const t=u[e],[r]=t.split("=");p.has(r)?!t.includes("=")&&e+1<u.length&&!u[e+1].startsWith("-")&&e++:f.push(t)}const m=[t,...d,...f];ls.info("[test] Forwarded args computed",{forwardedArgs:m}),ls.info("[test] Resolving Stably test environment");const y=Date.now(),b="test"===t?await(async()=>{ls.info("[test] Resolving Stably test env");const e=(()=>{if(process.env.STABLY_WS_URL)return;if("https://api.stably.ai"===fn)return;const e=fn.startsWith("http://")?"ws://":"wss://";return`${fn.replace(/^https?:\/\//,e).replace(/\/$/,"")}/reporter`})();ls.debug("[test] WebSocket URL resolved",{wsUrl:e??"(default)"});const t=gs();if(t)return ls.info("[test] Using env var auth (STABLY_API_KEY + STABLY_PROJECT_ID)"),{STABLY_API_KEY:t.apiKey,STABLY_PROJECT_ID:t.projectId,...e&&{STABLY_WS_URL:e}};ls.info("[test] No env var auth, attempting OAuth auth");const r=Date.now(),n=await(async()=>{const e=gs();if(e)return{auth:e,type:"env"};const t=await ms(),r=t?await Bn():void 0;return t&&r?{auth:{accessToken:t.accessToken,context:r},type:"oauth"}:void 0})();if(ls.info("[test] OAuth auth resolved",{durationMs:Date.now()-r,hasAuth:!!n,authType:n?.type}),!n||"env"===n.type)return void ls.info("[test] No usable auth found");const s=process.env.STABLY_PROJECT_ID?.trim(),o=s||bs(n);if(!o)return void ls.warn("[test] No project ID available");ls.info("[test] Fetching JWT API key",{projectId:o});const i=Date.now(),a=await(async(e,t)=>{try{ls.debug("Requesting JWT API key",{projectId:t,apiUrl:fn});const r=await(async({accessToken:e,projectId:t})=>{const r=await(n={auth:e,client:In(),path:{projectId:t}},(n.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/api-key",...n}));var n;if(r.error){const e=r.error?.error,{status:t}=r.response;throw new Error(e??`Failed to get API key: ${t}`)}return r.data})({accessToken:e,projectId:t});return ls.debug("JWT API key obtained",{keyPrefix:r.apiKey.substring(0,10)}),r.apiKey}catch(e){return void ls.warn("Failed to get JWT API key for test reporter",{error:e instanceof Error?e.message:String(e)})}})(n.auth.accessToken,o);ls.info("[test] JWT API key fetch complete",{durationMs:Date.now()-i,success:!!a});const c=a?{STABLY_API_KEY:a,STABLY_PROJECT_ID:o,...e&&{STABLY_WS_URL:e}}:void 0;return ls.info("[test] Stably test env resolved",{hasApiKey:!!c?.STABLY_API_KEY,projectId:c?.STABLY_PROJECT_ID,wsUrl:c?.STABLY_WS_URL??process.env.STABLY_WS_URL??"(default)"}),c})():void 0;ls.info("[test] Stably test environment resolved",{durationMs:Date.now()-y,hasCredentials:null!=b,hasWsUrl:!!b?.STABLY_WS_URL}),ls.info("[test] Loading remote environment variables");const w=await Ts();ls.info("[test] Remote environment loaded",{hasRemoteEnv:!!w,variableCount:w?Object.keys(w.variables).length:0});const v={};if(w){const e=[];for(const[t,r]of Object.entries(w.variables))void 0===process.env[t]?v[t]=r:process.env[t]!==r&&e.push(t);e.length>0&&ls.warn(`[test] π‘ Local environment variables overriding remote: ${e.join(", ")}`),w.sensitiveValues.length&&void 0===process.env.STABLY_SENSITIVE_VALUES&&(v.STABLY_SENSITIVE_VALUES=Buffer.from(JSON.stringify(w.sensitiveValues)).toString("base64"))}ls.info("[test] Setting up Stably reporter injection");const S="test"===t?function({forwardedArgs:e,hasCredentials:t}){if(!t){console.warn("[33mβ οΈ Stably credentials not found. Test results will not be reported to Stably.[0m");const e=ds();if("local"!==e){const t=fs(e);console.warn(`[33m To enable reporting, add the following to your ${t}:[0m`),console.warn("[33m β’ STABLY_API_KEY β https://app.stably.ai/settings?tab=api-key[0m"),console.warn("[33m β’ STABLY_PROJECT_ID β https://app.stably.ai/settings?tab=project-id[0m\n")}else console.warn("[33m To enable reporting, either:[0m"),console.warn("[33m β’ Run `npx stably login` to authenticate[0m"),console.warn("[33m β’ Or set STABLY_API_KEY and STABLY_PROJECT_ID environment variables[0m\n");return}const r=process.cwd(),n=e=>{const t=function(e){let t=s(e);for(;;){if([i(t,"node_modules","@stablyai","playwright-test"),i(t,"node_modules",".pnpm","@stablyai+playwright-test")].some(e=>E(e)))return!0;const e=o(t);if(e===t)return!1;t=e}}(e);return t||(console.warn("[33mβ οΈ @stablyai/playwright-test is not installed. Stably reporter will not be injected.[0m"),console.warn("[33m Install it with: npm install @stablyai/playwright-test[0m"),console.warn("[33m Reference: ]8;;https://docs.stably.ai/getting-started/sdk-setup-guidehttps://docs.stably.ai/getting-started/sdk-setup-guide]8;;[0m\n")),t},a=(e,t)=>{try{return function({baseConfigPath:e,projectDir:t}){const r=function(e){try{const t=h("npm pkg get type",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return"module"===JSON.parse(t.trim())}catch{return!1}}(t),n=r?"mts":"ts",a=o(s(e)),c=l(e),u=i(a,function(e){return"1"===process.env[wo]?`${yo}-wrapper.config.${e}`:`.stably-playwright-wrapper.config.${e}`}(n)),d=`\n// Auto-generated wrapper config by Stably CLI\n// This file injects the Stably reporter and ensures trace is enabled\nimport baseConfig from './${c}';\nimport { defineConfig, stablyReporter } from '@stablyai/playwright-test';\n\n// Inline type definitions to avoid import failures when @stablyai/playwright-test is not installed\ntype StablyNotificationConfig = {\n email?: { to: string[]; notifyOnStart?: boolean; notifyOnResult?: 'all' | 'failures-only' | null } | null;\n slack?: { channelName: string; notifyOnStart?: boolean; notifyOnResult?: 'all' | 'failures-only' } | null;\n};\n\ntype ProjectNotificationConfig = {\n projectName: string;\n notifications: StablyNotificationConfig;\n};\n\n// Extract notification configs from projects that have stably.notifications defined\n// This runs at config-load time before Playwright strips custom properties\nconst extractNotificationConfigs = (): ProjectNotificationConfig[] | undefined => {\n const projects = baseConfig.projects;\n if (!projects || !Array.isArray(projects)) return undefined;\n\n const configs = projects\n .map((p: { name?: string; stably?: { notifications?: StablyNotificationConfig } }) => {\n const notifications = p.stably?.notifications;\n return notifications ? { projectName: p.name ?? '', notifications } : undefined;\n })\n .filter((config): config is ProjectNotificationConfig => config != null);\n\n return configs.length > 0 ? configs : undefined;\n};\n\nconst isStablyReporter = (reporter: unknown): boolean => {\n // Only match @stablyai npm scope to avoid false positives on unrelated reporters\n // that might contain "stably" substring (e.g., "unstably-runner")\n if (typeof reporter === 'string') {\n return reporter.includes('@stablyai');\n }\n if (Array.isArray(reporter) && typeof reporter[0] === 'string') {\n return reporter[0].includes('@stablyai');\n }\n return false;\n};\n\nconst getStablyReporterOptions = (reporters: unknown[]): Record<string, unknown> | undefined => {\n for (const reporter of reporters) {\n if (Array.isArray(reporter) && typeof reporter[0] === 'string' && reporter[0].includes('@stablyai')) {\n return (reporter[1] as Record<string, unknown>) ?? {};\n }\n }\n return undefined;\n};\n\nconst filterOutStablyReporter = (reporters: unknown[]): unknown[] => {\n return reporters.filter((reporter) => !isStablyReporter(reporter));\n};\n\n// Decode sensitive values from env var (set by CLI --env flag)\nconst decodeSensitiveValues = (): string[] | undefined => {\n const encoded = process.env.STABLY_SENSITIVE_VALUES;\n if (!encoded) return undefined;\n try {\n const decoded: unknown = JSON.parse(Buffer.from(encoded, 'base64').toString('utf-8'));\n return Array.isArray(decoded) ? decoded.filter((v): v is string => typeof v === 'string') : undefined;\n } catch {\n return undefined;\n }\n};\n\nconst buildReporterList = () => {\n const existingReporters = baseConfig.reporter;\n const sensitiveValues = decodeSensitiveValues();\n\n // Resolve errorSummary: env var STABLY_ERROR_SUMMARY=0 disables it\n const resolveErrorSummary = (existingValue?: unknown): boolean | undefined => {\n if (process.env.STABLY_ERROR_SUMMARY === '0') return false;\n if (typeof existingValue === 'boolean') return existingValue;\n return undefined; // let the reporter default (true)\n };\n\n // No existing reporters - create fresh stably reporter\n if (!existingReporters) {\n return [stablyReporter({\n apiKey: process.env.STABLY_API_KEY,\n cliVersion: '${pn}',\n projectId: process.env.STABLY_PROJECT_ID,\n source: 'cli',\n notificationConfigs: extractNotificationConfigs(),\n errorSummary: resolveErrorSummary(),\n ...(sensitiveValues && { sensitiveValues }),\n })];\n }\n\n // Normalize to array\n const reportersArray: unknown[] = Array.isArray(existingReporters)\n ? existingReporters\n : [[existingReporters, {}]];\n\n // If user has a stably reporter, take their options but override credentials\n const existingOptions = getStablyReporterOptions(reportersArray);\n const stablyReporterEntry = stablyReporter({\n ...existingOptions,\n apiKey: process.env.STABLY_API_KEY,\n cliVersion: '${pn}',\n projectId: process.env.STABLY_PROJECT_ID,\n source: 'cli',\n notificationConfigs: extractNotificationConfigs(),\n errorSummary: resolveErrorSummary(existingOptions?.errorSummary),\n ...(sensitiveValues && { sensitiveValues }),\n });\n\n // Keep all non-stably reporters, add our (merged or fresh) stably reporter\n const otherReporters = filterOutStablyReporter(reportersArray);\n return [...otherReporters, stablyReporterEntry];\n};\n\nexport default defineConfig({\n ...baseConfig,\n use: {\n ...baseConfig.use,\n trace: 'on',\n },\n reporter: buildReporterList(),\n});\n`.trim();return E(a)||I(a,{recursive:!0}),T(u,d,"utf-8"),function(e,t){const r=i(e,".gitignore");try{if(E(r)){const e=x(r,"utf-8");if(e.split("\n").map(e=>e.trim()).includes(t))return;const n=e.length>0&&!e.endsWith("\n");A(r,`${n?"\n":""}${t}\n`)}else T(r,`${t}\n`)}catch{}}(a,"1"===process.env[wo]?bo:".stably-playwright-wrapper.config.*"),u}({baseConfigPath:e,projectDir:t})}catch{return void console.warn("[33mβ οΈ Could not create Stably wrapper config. Reporter injection skipped.[0m")}};if(e.some(e=>"--config"===e||"-c"===e||e.startsWith("--config=")||e.startsWith("-c="))){const t=e.findIndex(e=>"--config"===e||"-c"===e);if(-1!==t&&e[t+1]){const i=s(r,e[t+1]),c=o(i);if(!n(c))return;const l=a(i,c);if(!l)return;return e[t+1]=l,l}const i=e.findIndex(e=>e.startsWith("--config=")||e.startsWith("-c="));if(-1!==i){const t=s(r,e[i].split("=")[1]),c=o(t);if(!n(c))return;const l=a(t,c);if(!l)return;const u=e[i].startsWith("--config=")?"--config=":"-c=";return e[i]=`${u}${l}`,l}}const c=Io(r);if(!c)return;const u=o(c);if(!n(u))return;const d=a(c,u);return d?(e.push("--config",d),d):void 0}({forwardedArgs:m,hasCredentials:null!=b}):void 0;ls.info("[test] Reporter injection setup complete",{hasWrapperConfig:!!S}),ls.info("[test] Spawning Playwright process");const k=Date.now();if(await function(e,t={}){ls.info("[test] Detecting Playwright installation");const r=El();ls.info("[test] Playwright installation check",{installed:r.installed,inNodeModules:r.inNodeModules,packageManager:r.packageManager,packageName:r.packageName}),r.installed||(console.error('Playwright is not installed. Please run "stably init" to install it.'),process.exit(1)),r.inNodeModules||(console.error("Playwright is present in your project, but not in node_modules. Please install your dependencies before proceeding."),process.exit(1));const{packageManager:n}=r;n||(console.error("Playwright installation not found. Could not determine your package manager (tried pnpm, yarn, and npm)."),process.exit(1));const[s,...o]=Al(n),i=(a=t.env)?{...process.env,...a}:process.env;var a;const c=[s,...o,...e];ls.info("[test] Spawning Playwright process",{command:c.join(" "),pid:process.pid});const l=Date.now(),u=g(s,[...o,...e],{stdio:["inherit","pipe","pipe"],shell:"win32"===process.platform,env:{...i,...process.env.CI?{}:{FORCE_COLOR:"1"}}});ls.info("[test] Playwright process spawned",{childPid:u.pid});const d=Cl(n),p=function(){let e=!1,t="";return(r,n)=>{if(!e){t+=r,t.length>1024&&(t=t.slice(-1024));for(const r of Pl)if(t.includes(r))return n.write("\n[stably] Hint: This is a Playwright error, not caused by @stablyai/playwright-test.\n Common causes: running from the wrong directory (especially in monorepos),\n or a dependency pulling in a conflicting @playwright/test version.\n"),void(e=!0)}}}();u.stdout?.on("data",e=>{d(e,process.stdout)}),u.stderr?.on("data",e=>{const t=e.toString();d(e,process.stderr),p(t,process.stderr)});const f=new AbortController,h=()=>!f.signal.aborted&&(f.abort(),t.onClose?.(),process.removeListener("SIGINT",m),process.removeListener("SIGTERM",m),!0),m=e=>{ls.info("[test] Signal received, killing Playwright process",{signal:e,childPid:u.pid}),h(),u.kill(e);const t="SIGINT"===e?130:143;process.exit(t)};return process.on("SIGINT",m),process.on("SIGTERM",m),new Promise((e,t)=>{u.on("error",e=>{h()&&(ls.error("[test] Playwright process error",{error:e.message,childPid:u.pid}),t(e))}),u.on("close",t=>{if(!h())return;ls.info("[test] Playwright process exited",{exitCode:t,durationMs:Date.now()-l});const r=[process.stdout,process.stderr].filter(e=>e.writableNeedDrain).map(e=>new Promise(t=>e.once("drain",t)));Promise.race([Promise.all(r),new Promise(e=>setTimeout(e,5e3))]).then(()=>{process.exitCode=t??0,e(t??0)})})})}(m,{env:{...v,...b},onClose:()=>{var e;ls.info("[test] Playwright process closed, cleaning up wrapper config"),(e=S)&&E(e)&&_(e)}}),Ue.remoteEnvName&&b){const e=await _l(),t=e&&e.timestamp>=k;if(e&&t){const t=await ys();await(async({authHeader:e,orgId:t,runId:r,envName:n,timeoutMs:s=3e3})=>{ls.debug("Tagging run with envName",{runId:r,envName:n});try{let i;const a=new Promise(e=>{i=setTimeout(()=>e("timeout"),s)}),c=await Promise.race([(o={auth:e,client:In(),headers:_s(t),path:{runId:r},body:{envName:n}},(o.client??ln).patch({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/metadata",...o,headers:{"Content-Type":"application/json",...o.headers}})),a]);if(clearTimeout(i),"timeout"===c)return void ls.warn("Timed out tagging run with envName",{runId:r,envName:n,timeoutMs:s});if(c.error)return void ls.warn("Failed to tag run with envName",{runId:r,envName:n,status:c.response?.status});ls.debug("Successfully tagged run with envName",{runId:r,envName:n})}catch(e){ls.warn("Error tagging run with envName",{runId:r,envName:n,error:e instanceof Error?e.message:String(e)})}var o})({authHeader:ws(t),orgId:"oauth"===t.type?t.auth.context.orgId:void 0,runId:e.runId,envName:Ue.remoteEnvName})}else e&&!t?ls.debug("[test] last-run.json predates this test invocation, skipping envName tagging",{runId:e.runId,fileTimestamp:e.timestamp,testStartTime:k}):ls.debug("[test] No last-run.json found, skipping envName tagging")}}function Ul(e){const t=new Date(e),r=new Date,n=r.getTime()-t.getTime(),s=Math.floor(n/1e3),o=Math.floor(s/60),i=Math.floor(o/60),a=Math.floor(i/24);if(s<60)return"just now";if(o<60)return`${o}m ago`;if(i<24)return`${i}h ago`;if(a<=7)return`${a}d ago`;const c=t.toLocaleString("en-US",{month:"short"}),l=t.getDate();return t.getFullYear()===r.getFullYear()?`${c} ${l}`:`${c} ${l}, ${t.getFullYear()}`}var Ll=e=>"oauth"===e.type?e.auth.context.orgId:void 0,$l=(e,t,r)=>{if(401!==e.response.status&&403!==e.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),404===e.response.status&&r&&(ce(Dr("error",r)),process.exit(1)),400===e.response.status){const t=e.error&&"object"==typeof e.error&&"error"in e.error?e.error.error:"Bad request";ce(Dr("error",t)),process.exit(1)}e.error&&(ce(Dr("error",`Failed to ${t}: ${e.response.status}`)),process.exit(1))},Dl={PASSED:e=>Dr("success",e),FAILED:e=>Dr("error",e),TIMEDOUT:e=>Dr("error",e),CANCELLED:e=>Dr("warning",e),INTERRUPTED:e=>Dr("warning",e),RUNNING:e=>Dr("info",e),QUEUED:e=>Dr("muted",e)},Nl=(e,t)=>e?e.length>t?`${e.slice(0,t-1)}β¦`:e:"-",Ol=e=>{if(!e)return"-";const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},Bl=e=>(Dl[e]??(e=>e))(e),jl=/\x1b\[[0-9;]*m/g,Ml=(e,t)=>{const r=e.replace(jl,"").length,n=Math.max(0,t-r);return e+" ".repeat(n)},Fl=e=>`${JSON.stringify(e,null,2)}\n`,Hl=(e,t,r)=>{if(!e)return;const n=e.toUpperCase();if(t.includes(n))return n;ce(Dr("error",`Invalid ${r} value "${e}". Must be one of: ${t.join(", ").toLowerCase()}`)),process.exit(1)},Gl=/\x1b\[[0-9;]*m/g,Wl=(e,t)=>{const r=e.replace(Gl,"").length,n=Math.max(0,t-r);return e+" ".repeat(n)},Vl=(e,t)=>e?e.length>t?`${e.slice(0,t-1)}β¦`:e:"-",Yl=e=>e?e.split("T")[0]??"-":"-",zl=e=>`${(100*e).toFixed(1)}%`,ql=e=>`${JSON.stringify(e,null,2)}\n`,Kl=e=>{if(!e)return;const t=parseInt(e,10);return(Number.isNaN(t)||t<1||t>90)&&(ce(Dr("error","--days must be an integer between 1 and 90")),process.exit(1)),t},Jl=e=>{if(!e)return;const t=parseInt(e,10);return(Number.isNaN(t)||t<1||t>100)&&(ce(Dr("error","--limit must be an integer between 1 and 100")),process.exit(1)),t},Xl="stably",Ql=`https://registry.npmjs.org/${Xl}/latest`;function Zl(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)/);return t?{major:parseInt(t[1],10),minor:parseInt(t[2],10),patch:parseInt(t[3],10)}:null}function eu(e,t){const r=Zl(e),n=Zl(t);return!(!r||!n)&&(n.major>r.major||!(n.major<r.major)&&(n.minor>r.minor||!(n.minor<r.minor)&&n.patch>r.patch))}var tu=n.join(D.homedir(),".stably"),ru=n.join(tu,"update-check.json"),nu="1"===process.env.STABLY_DISABLE_UPDATE_CHECK,su=he.object({lastCheck:he.number(),latestVersion:he.string()}),ou=Symbol.for("stably.updateNotifier.registered");function iu(e=""){process.stdout.write(`${e}\n`)}function au(...e){process.stderr.write(`${e.join(" ")}\n`)}var cu=he.object({version:he.string()});var lu=!1,uu=async()=>{if(lu)try{const{shutdown:e}=await import("@hyperdx/node-opentelemetry"),t=process.stderr.write.bind(process.stderr),r=process.stdout.write.bind(process.stdout),n=(e,...t)=>{const r=t[0];return!("string"!=typeof r||!r.includes("OpenTelemetry"))||!(!Buffer.isBuffer(r)||!r.toString().includes("OpenTelemetry"))||e(...t)};process.stderr.write=(...e)=>n(t,...e),process.stdout.write=(...e)=>n(r,...e);try{await e()}finally{process.stderr.write=t,process.stdout.write=r}}catch{}},du=e=>{const t=e.toLowerCase();return t.startsWith("npm_config_")||"node_options"===t};!function(){if(nu||function(e=process.argv.slice(2)){return e.includes("upgrade")}())return;const e=function(){try{const e=v.readFileSync(ru,"utf-8");return su.parse(JSON.parse(e))}catch{return null}}(),t=Date.now();if((null==e||t-e.lastCheck>=18e5)&&function(){const e=`\n import { get } from 'node:https';\n import fs from 'node:fs';\n const url = '${Ql}';\n const cacheFile = ${JSON.stringify(ru)};\n const cacheDir = ${JSON.stringify(tu)};\n\n const req = get(url, { timeout: 5000 }, (res) => {\n if (res.statusCode !== 200) process.exit(1);\n let data = '';\n res.on('data', (chunk) => data += chunk);\n res.on('end', () => {\n try {\n const version = JSON.parse(data).version;\n if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });\n fs.writeFileSync(cacheFile, JSON.stringify({ lastCheck: Date.now(), latestVersion: version }));\n } catch {}\n process.exit(0);\n });\n });\n req.on('error', () => process.exit(1));\n req.on('timeout', () => { req.destroy(); process.exit(1); });\n `;try{g(process.execPath,["--input-type=module","-e",e],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}(),null!=e&&eu(pn,e.latestVersion)){if(!0===process[ou])return;process[ou]=!0;let t=!1;const r=()=>{if(t)return;t=!0;const r=`${Dr("warning",`update available (${pn} β ${e.latestVersion})`)} - run \`${Xl} upgrade\` to get the latest version\n`;try{v.writeSync(2,r)}catch{}};process.once("beforeExit",r),process.once("exit",r)}}(),Ue.cwdChanged&&ls.debug("Changed working directory",{cwd:Ue.newCwd});for(const e of Ue.envFilesLoaded)ls.debug("Loaded env file",{path:e});for(const e of Ue.envFileErrors)ls.warn(e);var pu=process.argv.findIndex(e=>"-v"===e||"--verbose"===e);-1!==pu&&process.argv.splice(pu,1);var fu=process.argv.findIndex(e=>"--no-telemetry"===e);-1!==fu&&process.argv.splice(fu,1),ls.info("CLI starting",{version:pn,args:process.argv.slice(2),cwd:process.cwd()}),process.on("unhandledRejection",(e,t)=>{ls.error("Unhandled promise rejection",{reason:e instanceof Error?{message:e.message,stack:e.stack}:e,promise:String(t)}),ls.flush(),ls.printLogFileInfo()}),process.on("uncaughtException",(e,t)=>{"EPIPE"!==e.code&&(ls.error("Uncaught exception",{error:{message:e.message,stack:e.stack,name:e.name},origin:t}),ls.flush(),ls.printLogFileInfo())});var hu=new u;hu.name("stably").description("AI-assisted Playwright testing CLI").version(pn),hu.enablePositionalOptions();var gu=(e,t)=>"cloud"===t.browser||"cloud"===e.parent?.opts().browser||"1"===process.env.STABLY_CLOUD_BROWSER;hu.showHelpAfterError(),hu.exitOverride(),hu.configureHelp({subcommandTerm:e=>{const t=e.registeredArguments.map(e=>e.required?`<${e.name()}>`:`[${e.name()}]`).join(" ");return t?`${e.name()} ${t}`:e.name()}}),hu.addHelpText("after","\nGlobal options (available for all commands):\n -C, --cwd <path> Change working directory before running\n --browser <type> Browser type: local or cloud (default: local)\n --env <name> Load environment variables from a remote Stably environment\n --env-file <path> Load environment variables from a local .env file (repeatable)\n -v, --verbose Enable debug-level logging\n --no-telemetry Disable error telemetry");var mu=[];hu.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>{mu.push(e)}});var yu=()=>{const e=hu.helpInformation().trimEnd();return e?`${e}\n`:""},bu=(e,t)=>{let r=e;for(const e of t){const t=r.commands.find(t=>t.name()===e||t.aliases().includes(e));if(!t)return;r=t}return r},wu=()=>{process.stdout.write(yu())};hu.command("help [command...]").description("Show help for a command (e.g. stably help create)").action(e=>{if(!e||0===e.length)return void wu();const t=bu(hu,e);if(!t)return process.stderr.write(`Unknown command: ${e.join(" ")}\n`),wu(),void(process.exitCode=1);var r;r=t,process.stdout.write((e=>{const t=e.helpInformation().trimEnd();return t?`${t}\n`:""})(r))}),hu.option("--browser <type>","Browser type: local or cloud (default: local)").action((e,t)=>Il({mode:"chat",getHelpText:yu,cloudBrowser:gu(t,e)})),hu.command("login").description("Authenticate with Stably in your browser").action(Yn),hu.command("logout").description("Clear stored Stably credentials").action(async()=>{const e=gs();e&&(ae.warn(`Environment variables ${Dr("info","STABLY_API_KEY")} and ${Dr("info","STABLY_PROJECT_ID")} are set.`),ae.warn("They will continue to be used for authentication even after logout."),ae.warn("Unset them if you want to fully de-authenticate this shell/session."));const t=await Dn();if(!t)return void ce(Dr("warning",e?"No stored OAuth login found to clear.":"You are not logged in."));const r=le();r.start("Logging out..."),await(async e=>{try{await fetch(`${gn}/api/backend/v1/logout`,{body:JSON.stringify({refresh_token:e}),headers:{"Content-Type":"application/json"},method:"POST"})}catch{}})(t.refreshToken),await On(),await jn(),r.stop(Dr("success","β Logged out")),ce(Dr("success","You have been logged out successfully."))}),hu.command("whoami").description("Show auth status and current project").action(async()=>{ae.info(`${ne.bold("CLI Version:")} ${Dr("info",pn)}`);const e=gs();if(e){ae.info(ne.dim("Authentication: Environment variables")),ae.info(` ${ne.bold("API Key:")} ${Dr("info",e.apiKey.slice(0,8))}...`),ae.info(` ${ne.bold("Project ID:")} ${Dr("info",e.projectId)}`);const t=await Dn();if(t){let e;try{e=An(t.accessToken).email}catch{e=void 0}ae.warn("Stored OAuth login detected but will be ignored (env auth takes precedence)."),e&&ae.info(` ${ne.bold("OAuth Email:")} ${Dr("info",e)}`),ae.info(` ${ne.bold("Tip:")} Unset env vars to use OAuth`)}return void ce(Dr("success","Authenticated via environment variables"))}const t=await Dn();if(!t)return void ce(Dr("warning","Not logged in. Run `stably login` to authenticate."));let r;try{r=An(t.accessToken).email}catch{r=void 0}const s=await Bn();if(!s)return ae.info(ne.dim("Authentication: OAuth (not linked to a project)")),r&&ae.info(` ${ne.bold("Email:")} ${Dr("info",r)}`),void ce(Dr("warning","Logged in but this directory is not linked to a project. Run `stably login` to link."));const o=await(async()=>kn(process.cwd(),Rn))(),i=o?n.dirname(o):process.cwd(),a=n.relative(process.cwd(),i)||".";ae.info(ne.dim("Authentication: OAuth")),r&&ae.info(` ${ne.bold("Email:")} ${Dr("info",r)}`),ae.info(` ${ne.bold("Organization:")} ${Dr("info",s.orgName)}`),ae.info(` ${ne.bold("Project:")} ${Dr("info",s.projectName)}`),ae.info(` ${ne.bold("Linked at:")} ${ne.dim(a)}`),ce(Dr("success","Authenticated"))}),hu.command("tunnel",{hidden:!0}).description("Expose a local server with a secure tunnel URL").option("-p, --port <number>","Local port to expose","3000").action(async e=>{ue(`Starting development server for port ${e.port}...`);const t=await ys(),r="oauth"===t.type?`${t.auth.context.orgName}-${t.auth.context.projectName}`.toLowerCase().replace(/[^a-z0-9-]/g,""):`project-${t.auth.projectId}`.toLowerCase(),n=le();n.start("Starting development server...");const s=await Ce(`http://localhost:${e.port}`,{subdomain:r});n.stop(`Your local environment is available at: ]8;;${s.url}${ne.underline(Dr("link",s.url))}]8;;`)}),hu.command("create [prompt...]").description("Generate a test from prompt (omit prompt to infer from branch diff)").option("-o, --output <dir>","Output directory for generated test files").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{const n=e.length>0&&"test"===e[0]?e.slice(1):e;return Il({mode:"single",prompt:n,outputDir:t.output,cloudBrowser:gu(r,t)})}).command("test",{hidden:!0}).description("Generate a Playwright test from a prompt (deprecated: use `stably create <prompt>` directly)").argument("<prompt...>","Prompt describing the test to generate").option("-o, --output <dir>","Output directory for generated test files").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>Il({mode:"single",prompt:e,outputDir:t.output,cloudBrowser:gu(r,t)})),hu.command("plan [prompt...]").description("Discover coverage gaps and generate test.fixme() plan files").action(async e=>Il({mode:"plan",prompt:e??[]})),hu.command("verify <prompt...>").description("Verify your app works correctly against a prompt").option("-u, --url <url>","Starting URL to verify against").option("--max-budget <dollars>","Maximum budget in USD (default: 5)",Number.parseFloat).option("--no-interactive","Disable interactive verify preflight setup").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{if(void 0!==t.maxBudget&&(!Number.isFinite(t.maxBudget)||t.maxBudget<=0))throw new Error("--max-budget must be a positive number");return Il({mode:"verify",prompt:e,url:t.url,maxBudgetUsd:t.maxBudget,interactive:t.interactive,cloudBrowser:gu(r,t)})}),hu.command("internal-fix-run <runId>",{hidden:!0}).description("Internal: run fix session in subprocess").action(async e=>Il({mode:"fix",runId:e,cloudBrowser:"1"===process.env.STABLY_CLOUD_BROWSER})),hu.command("fix [runId]").description("Fix failing tests from a run (auto-detects from last test run or CI)").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{const n=Boolean(process.env.STABLY_CLI_VISUAL_MOCK);gu(r,t)&&(process.env.STABLY_CLOUD_BROWSER="1"),n||function(e){try{return h("git rev-parse --is-inside-work-tree",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}(process.cwd())||(ls.error('Not a git repository. The "stably fix" command requires a git repository to track changes made during the fix. Please run this command from inside a git repository.'),process.stderr.write('Error: Not a git repository.\nThe "stably fix" command requires a git repository to track changes made during the fix.\nPlease run this command from inside a git repository.\n'),process.exit(1));const s=await(async e=>{const t=e=>e.replace(/\//g,"_");if(e)return ls.debug("Run ID provided explicitly",{runId:e}),t(e);const r=function(){if(process.env.CI_BUILD_ID)return process.env.CI_BUILD_ID;const e=(({env:e=process.env,cwd:t=process.cwd()}={})=>{for(const r of Object.keys(xr))if(xr[r].detect({env:e,cwd:t}))return{isCi:!0,...xr[r].configuration({env:e,cwd:t})};return{isCi:Boolean(e.CI),...cr({env:e,cwd:t})}})();if(!e.isCi)return;const t=function(e){switch(e){case"github":return process.env.GITHUB_RUN_ATTEMPT;case"azure-devops":return process.env.SYSTEM_JOBATTEMPT;case"bitbucket":return process.env.BITBUCKET_STEP_RUN_NUMBER;default:return}}(e.service),r=[e.service,"slug"in e?e.slug?.replace(/\//g,"_"):void 0,"build"in e?String(e.build):void 0,"job"in e?String(e.job):void 0,t&&String(t)].filter(Boolean);return r.length>0?r.join("-"):void 0}();if(r)return ls.debug("Run ID detected from CI environment",{runId:r}),t(r);ls.debug("No explicit run ID or CI environment detected, checking last-run.json");const n=await _l();if(n){const e=(Date.now()-n.timestamp)/36e5;return ls.debug("Run ID found in last-run.json",{runId:n.runId,timestamp:n.timestamp,filePath:n.filePath,ageHours:Math.round(e)}),e>24&&ls.warn(`Using run ID from ${Math.round(e)} hours ago (${n.filePath}). Provide an explicit run ID if this is not the run you want to fix.`),t(n.runId)}ls.debug("No run ID found in last-run.json")})(e)??(n?"visual-mock-run":void 0);if(s||(process.stderr.write('Run ID is required. Either:\n 1. Run "stably test" first (run ID will be auto-detected)\n 2. Provide a run ID: stably fix <runId>\n 3. Run in CI (auto-detected from environment)\n'),process.exit(1)),n)return Il({mode:"fix",runId:s,cloudBrowser:"1"===process.env.STABLY_CLOUD_BROWSER});const o=await(async e=>{const t=await ys(),r=ws(t),n=bs(t),[,s]=process.argv;if(!s)throw new Error("Unable to determine CLI entrypoint for fix subprocess.");return await(async({runId:e,cliEntry:t,stablyApiKey:r,stablyProjectId:n,baseEnv:s=process.env,cwd:o=process.cwd(),execPath:i=process.execPath,execArgv:a=process.execArgv,stdio:c="inherit",spawnImpl:l=({command:e,args:t,options:r})=>g(e,t,r)})=>{const u=(({baseEnv:e,stablyApiKey:t,stablyProjectId:r,playwrightSession:n})=>{const s={...e};for(const e of Object.keys(s))du(e)&&delete s[e];return{...s,STABLY_API_KEY:t,STABLY_PROJECT_ID:r,...n?{STABLY_PLAYWRIGHT_SESSION:n}:{}}})({baseEnv:s,stablyApiKey:r,stablyProjectId:n});return await new Promise((r,n)=>{const s=l({args:[...a,t,"internal-fix-run",e],command:i,options:{cwd:o,stdio:c,env:u}});s.once("error",n),s.once("exit",(e,t)=>{r(t?1:e??1)})})})({cliEntry:s,runId:e,stablyApiKey:r,stablyProjectId:n,cwd:process.cwd(),stdio:"inherit"})})(s);0!==o&&process.exit(o)}),hu.command("init").description("Initialize Playwright and Stably SDK in your project").action(async()=>Il({mode:"init"})),hu.command("upgrade").description("Upgrade to latest version (use --check to only check)").option("-c, --check","Only check for updates without upgrading").action(e=>async function(e){const{check:t=!1}=e;let r;iu(Dr("info","Checking for updates...\n"));try{r=await async function(){const e=await async function(){const e=new AbortController,t=setTimeout(()=>e.abort(),1e4);t.unref();try{const t=await fetch(Ql,{signal:e.signal});if(!t.ok)throw new Error(`Failed to fetch latest version: ${t.statusText}`);return cu.parse(await t.json()).version}finally{clearTimeout(t)}}();return{current:pn,latest:e,isOutdated:eu(pn,e)}}()}catch(e){return au(Dr("error","Failed to check for updates:"),e instanceof Error?e.message:e),void(process.exitCode=1)}if(iu(`Current version: ${Dr("warning",r.current)}`),iu(`Latest version: ${Dr("success",r.latest)}`),iu(),!r.isOutdated)return void iu(Dr("success","β You are already on the latest version!"));if(iu(Dr("warning",`β A new version is available: ${r.current} β ${r.latest}`)),iu(),t)return iu(ne.dim("Exiting with code 1 to indicate update available (useful for CI).")),void(process.exitCode=1);const n=function(){const e=process.argv[1]||"";if(e.includes("_npx")||e.includes(".npm/_cacache")||e.includes(".npm\\_cacache"))return"npx";try{const t=h("npm root -g",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-npm"}catch{}if(e.includes("node_modules/stably")||e.includes("node_modules\\stably"))return"global-npm";try{const t=h("pnpm root -g",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-pnpm"}catch{}try{const t=h("yarn global dir",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-yarn-classic"}catch{}try{const t=h("yarn config get globalFolder",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-yarn-berry"}catch{}return"unknown"}(),s=function(e){switch(e){case"global-npm":case"global-yarn-berry":case"unknown":return{command:"npm",args:["install","-g","--no-fund",`${Xl}@latest`],description:`npm install -g ${Xl}@latest`};case"global-pnpm":return{command:"pnpm",args:["add","-g",`${Xl}@latest`],description:`pnpm add -g ${Xl}@latest`};case"global-yarn-classic":return{command:"yarn",args:["global","add",`${Xl}@latest`],description:`yarn global add ${Xl}@latest`};case"npx":return{command:"npx",args:[`${Xl}@latest`],description:`npx ${Xl}@latest (always uses latest)`}}}(n);if("npx"===n)return iu(ne.dim("You are running via npx, which always fetches the latest version.")),void iu(ne.dim(`Simply run: ${ne.white("npx stably")} to use the latest version.`));"unknown"===n?(iu(Dr("warning","Could not detect installation method. Falling back to npm.")),iu()):"global-yarn-berry"===n&&(iu(Dr("warning","Yarn Berry does not support global packages. Falling back to npm.")),iu()),iu(`Upgrade command: ${Dr("info",s.description)}`),iu(),iu(Dr("info","Upgrading...")),iu();try{await(o=s.command,i=s.args,new Promise((e,t)=>{const r=g(o,i,{stdio:"inherit",shell:"win32"===process.platform});r.on("close",r=>{0===r?e():t(new Error(`Upgrade command exited with code ${r}`))}),r.on("error",e=>{t(e)})})),function(){try{v.unlinkSync(ru)}catch{}}(),iu(),iu(Dr("success","β Upgrade complete!")),iu(ne.dim(`Run ${ne.white("stably --version")} to verify.`))}catch(e){au(Dr("error","Upgrade failed:"),e instanceof Error?e.message:e),iu(),iu(ne.dim("You can try manually running:")),iu(Dr("info",` ${s.description}`)),process.exitCode=1}var o,i}(e));var vu=hu.command("env").description("Manage remote environments");vu.command("list").description("List available environments").action(async()=>{const e=await ys(),t=bs(e),r=ws(e);ls.debug("Listing environments",{projectId:t});const n=await(s={auth:r,client:In(),path:{projectId:t}},(s.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments",...s}));var s;401!==n.response.status&&403!==n.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),n.error&&(ce(Dr("error",`Failed to list environments: ${n.response.status}`)),process.exit(1));const{environments:o}=n.data;if(0!==o.length){process.stdout.write(`${ne.bold("Environments")}\n\n`);for(const e of o){const t=e.isDefault?Dr("success"," (default)"):"",r=ne.dim(` ${e.variableCount} variable${1!==e.variableCount?"s":""}`);process.stdout.write(` ${Dr("info",e.name)}${t}${r}\n`),e.description&&process.stdout.write(` ${ne.dim(e.description)}\n`)}process.stdout.write("\n")}else process.stdout.write(ne.dim("No environments found. Create one on your Stably dashboard.\n"))}),vu.command("inspect <name>").description("Show variable metadata (name, sensitive flag, updated timestamp)").action(e=>(async e=>{const t=await ys(),r=bs(t),n=ws(t);ls.debug("Inspecting environment",{name:e,projectId:r});const s=await(o={auth:n,client:In(),path:{projectId:r,environmentName:e}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments/{environmentName}/inspect",...o}));var o;404===s.response.status&&(ce(Dr("error",`Environment "${e}" not found. Run ${ne.bold("stably env list")} to see available environments.`)),process.exit(1)),401!==s.response.status&&403!==s.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),s.error&&(ce(Dr("error",`Failed to inspect environment: ${s.response.status}`)),process.exit(1));const{variables:i}=s.data;if(0!==i.length){process.stdout.write(`${ne.bold(e)} ${ne.dim(`(${i.length} variable${1!==i.length?"s":""})`)}\n\n`);for(const e of i){const t=ne.dim(` [updated ${Ul(e.updatedAt)}]`);e.sensitive?process.stdout.write(` ${Dr("info",e.name)} ${Dr("warning","[sensitive]")}${t}\n`):process.stdout.write(` ${Dr("info",e.name)}${t}\n`)}process.stdout.write("\n")}else process.stdout.write(ne.dim(`Environment "${e}" has no variables.\n`))})(e));var Iu=hu.command("analytics").description("View test health analytics");Iu.command("flaky").description("Show most flaky tests ranked by flaky rate").option("--days <n>","Look-back window in days (1-90, default: 7)").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <n>","Max rows returned (1-100, default: 10)").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t),o=Kl(e.days),i=Jl(e.limit);ls.debug("Listing flaky tests",{projectId:r,days:o,branch:e.branch,limit:i});const a=In(),c=await a.get({url:"/internal/v1/cli/analytics/flaky",security:[{scheme:"bearer",type:"http"}],auth:n,headers:{..._s(s)},query:{projectId:r,days:o,branchName:e.branch,limit:i}});$l(c,"list flaky tests");const l=c.data;e.json?process.stdout.write(ql(l)):process.stdout.write(((e,t)=>{const r=[],n=e.filters.branch?`branch: ${e.filters.branch}`:"all branches";if(r.push(ne.bold(`Most Flaky Tests (last ${e.period.days} days, ${n})`)),r.push(""),0===e.tests.length)return r.push(ne.dim(" No flaky tests found.")),r.push(""),r.join("\n");const s=` ${Wl("REF",14)}${Wl("TEST",20)}${Wl("LOCATION",30)}${Wl("FLAKY",8)}${Wl("RUNS",7)}${Wl("RATE",9)}LAST FLAKY`;r.push(ne.dim(s));for(const t of e.tests){const e=t.testRef,n=Vl(t.title,18),s=Vl(t.location,28),o=String(t.flakyCount),i=String(t.nonSkippedRuns),a=zl(t.flakyRate),c=Yl(t.lastFlakyAt);r.push(` ${Wl(e,14)}${Wl(n,20)}${Wl(s,30)}${Wl(o,8)}${Wl(i,7)}${Wl(a,9)}${c}`)}r.push("");const o=e.summary.totalNonSkippedRuns;return r.push(` ${e.summary.totalFlakyTests} flaky tests found across ${o} runs.`),r.push(` Dashboard: ${ne.underline(Dr("link",`https://app.stably.ai/p/${t}/analytics`))}`),r.push(""),r.join("\n")})(l,r))}),Iu.command("failures").description("Show most failing tests ranked by failure rate").option("--days <n>","Look-back window in days (1-90, default: 7)").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <n>","Max rows returned (1-100, default: 10)").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t),o=Kl(e.days),i=Jl(e.limit);ls.debug("Listing failing tests",{projectId:r,days:o,branch:e.branch,limit:i});const a=In(),c=await a.get({url:"/internal/v1/cli/analytics/failures",security:[{scheme:"bearer",type:"http"}],auth:n,headers:{..._s(s)},query:{projectId:r,days:o,branchName:e.branch,limit:i}});$l(c,"list failing tests");const l=c.data;e.json?process.stdout.write(ql(l)):process.stdout.write(((e,t)=>{const r=[],n=e.filters.branch?`branch: ${e.filters.branch}`:"all branches";if(r.push(ne.bold(`Most Failed Tests (last ${e.period.days} days, ${n})`)),r.push(""),0===e.tests.length)return r.push(ne.dim(" No failing tests found.")),r.push(""),r.join("\n");const s=` ${Wl("REF",14)}${Wl("TEST",20)}${Wl("LOCATION",30)}${Wl("FAILED",8)}${Wl("RUNS",7)}${Wl("RATE",9)}LAST FAILED`;r.push(ne.dim(s));for(const t of e.tests){const e=t.testRef,n=Vl(t.title,18),s=Vl(t.location,28),o=String(t.failedCount),i=String(t.nonSkippedRuns),a=zl(t.failureRate),c=Yl(t.lastFailedAt);r.push(` ${Wl(e,14)}${Wl(n,20)}${Wl(s,30)}${Wl(o,8)}${Wl(i,7)}${Wl(a,9)}${c}`)}r.push("");const o=e.summary.totalNonSkippedRuns;return r.push(` ${e.summary.totalFailingTests} failing tests found across ${o} runs.`),r.push(` Dashboard: ${ne.underline(Dr("link",`https://app.stably.ai/p/${t}/analytics`))}`),r.push(""),r.join("\n")})(l,r))});var Tu=hu.command("runs").description("View test run history");Tu.command("list").description("List recent test runs").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <number>","Number of runs (default: 20, max: 100)").option("--after <runId>","Show runs newer than this runId").option("--before <runId>","Show runs older than this runId").option("--source <type>","Filter by source: local, ci, web").option("-s, --status <type>","Filter by status: queued, running, passed, failed, timedout, cancelled, interrupted").option("--suite <name>","Filter by suite name").option("--trigger <type>","Filter by trigger: manual, scheduled, ui, api, github_action, suite_run").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t);let o;e.limit&&(o=parseInt(e.limit,10),(Number.isNaN(o)||o<1||o>100)&&(ce(Dr("error","--limit must be an integer between 1 and 100")),process.exit(1)));const i=Hl(e.source,["LOCAL","CI","WEB"],"--source"),a=Hl(e.status,["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","CANCELLED","INTERRUPTED"],"--status"),c=Hl(e.trigger,["MANUAL","SCHEDULED","UI","API","GITHUB_ACTION","SUITE_RUN"],"--trigger");ls.debug("Listing runs",{projectId:r,branch:e.branch,limit:o,after:e.after,before:e.before,source:i,status:a,suite:e.suite,trigger:c});const l=await un({auth:n,client:In(),headers:_s(s),query:{projectId:r,branchName:e.branch,limit:o,afterRunId:e.after,beforeRunId:e.before,source:i,status:a,suiteName:e.suite,trigger:c}});$l(l,"list runs");const{runs:u,hasMore:d}=l.data;e.json?process.stdout.write(Fl(l.data)):process.stdout.write(((e,t)=>{if(0===e.length)return ne.dim("No runs found matching the specified filters.\n");const r=Math.min(40,Math.max(10,...e.map(e=>e.runId.length))),n={runId:{w:r+2,t:r},status:{w:14},branch:{w:32,t:30},started:{w:18}},s=[],o=`${Ml("Run ID",n.runId.w)}${Ml("Status",n.status.w)}${Ml("Branch",n.branch.w)}${Ml("Started",n.started.w)}Tests`;s.push(ne.bold(o));for(const t of e){const e=Nl(t.runId,n.runId.t),r=Bl(t.status),o=Nl(t.branchName,n.branch.t),i=Ol(t.startedAt),a=t.totalCount.toString();s.push(`${Ml(e,n.runId.w)}${Ml(r,n.status.w)}${Ml(o,n.branch.w)}${Ml(i,n.started.w)}${a}`)}if(t&&e.length>0){const t=e.at(-1)?.runId;t&&(s.push(""),s.push(ne.dim(`Next page: stably runs list --before ${t}`)))}return s.push(""),s.join("\n")})(u,d))}),Tu.command("view <runId>").description("Show details for a specific run").option("--json","Output as JSON").action(async(e,t)=>{const r=await ys(),n=ws(r),s=Ll(r);ls.debug("Viewing run",{runId:e});const o=await dn({auth:n,client:In(),headers:_s(s),path:{runId:e},query:{detail:"full"}});if($l(o,"get run details",`Run "${e}" not found.`),t.json)process.stdout.write(Fl(o.data));else{const e=o.data;process.stdout.write((e=>{const t=[];if(t.push(ne.bold(`Run ${e.runId}`)),t.push(` ${ne.dim("Status:")} ${Bl(e.status)}`),e.branchName&&t.push(` ${ne.dim("Branch:")} ${e.branchName}`),e.commitSha&&t.push(` ${ne.dim("Commit:")} ${e.commitSha.slice(0,7)}`),e.startedAt&&t.push(` ${ne.dim("Started:")} ${Ol(e.startedAt)}`),null!==e.durationMs&&t.push(` ${ne.dim("Duration:")} ${(e=>{if(null===e)return"-";const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const r=Math.floor(t/60);return r<60?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`})(e.durationMs)}`),e.source&&t.push(` ${ne.dim("Source:")} ${e.source.toLowerCase()}`),e.projectId){const r=`https://app.stably.ai/project/${e.projectId}/playwright/history/${e.runId}`;t.push(` ${ne.dim("URL:")} ${ne.underline(Dr("link",r))}`)}t.push("");const r=[];e.passedCount>0&&r.push(Dr("success",`${e.passedCount} passed`)),e.failedCount>0&&r.push(Dr("error",`${e.failedCount} failed`)),e.flakyCount>0&&r.push(Dr("warning",`${e.flakyCount} flaky`)),e.timedoutCount>0&&r.push(Dr("error",`${e.timedoutCount} timedout`)),e.skippedCount>0&&r.push(Dr("muted",`${e.skippedCount} skipped`)),e.interruptedCount>0&&r.push(Dr("warning",`${e.interruptedCount} interrupted`)),t.push(`${ne.bold("Test Results:")} ${r.join(", ")}`);const n=e.testCases.filter(e=>"FAILED"===e.status||"TIMEDOUT"===e.status||"INTERRUPTED"===e.status||"FLAKY"===e.status);if(n.length>0){t.push(""),t.push(ne.bold("Failed/Flaky Tests:"));for(const e of n){const r=e.status??"UNKNOWN",n=Dl[r]??(e=>e),s=e.location??"",o=e.title??e.testIdentifier,{attempts:i}=e,a=i?.length??0,c=a>1?` (${a} attempts)`:"",l=s?`${s} - `:"";t.push(` ${n(r)} ${l}${o}${ne.dim(c)}`);const u=i?.at(-1);if(u?.errorMessage){const e=u.errorMessage.split("\n")[0]?.slice(0,100)??"";t.push(` ${ne.dim(e)}`)}}}return t.push(""),t.join("\n")})(e))}}),hu.command("build",{hidden:!0}).description('(Deprecated) Use "stably create" instead').allowUnknownOption(!0).allowExcessArguments(!0).action(()=>{process.stderr.write('\nπ "stably build" has moved! Use "stably create" instead:\n\n stably create "Read the .md files in /tests directory and then create playwright tests"\n\n'),process.exit(1)}),kl.forEach(({args:e,description:t,name:r})=>{hu.command(r).description(t).helpOption(!1).helpCommand(!1).allowUnknownOption(!0).allowExcessArguments(!0).passThroughOptions().action(()=>Rl({overrideArgs:e,subcommand:r}))});var _u=()=>{0!==mu.length&&(process.stderr.write(mu.join("")),mu=[])};(async()=>{await(async()=>{if(!lu&&"1"!==process.env.STABLY_DISABLE_TELEMETRY&&"1"!==process.env.DO_NOT_TRACK&&!process.argv.includes("--no-telemetry"))try{const{init:e}=await import("@hyperdx/node-opentelemetry");e({apiKey:"61d10b50-9534-47be-a732-95bfe461adb7",service:"stably-cli",consoleCapture:!0,disableTracing:!0,disableMetrics:!0,disableStartupLogs:!0,additionalResourceAttributes:{"cli.version":pn,"node.version":process.version,"os.platform":process.platform}}),lu=!0}catch{}})();try{await hu.parseAsync(process.argv),ls.info("CLI completed successfully")}catch(e){if(!(e=>!!e&&"object"==typeof e&&"code"in e)(e)){const t=e instanceof Error?e.message:String(e);return ls.error(t,{stack:e instanceof Error?e.stack:void 0}),_u(),ls.flush(),ls.printLogFileInfo(),await uu(),void(process.exitCode=1)}const t="number"==typeof e.exitCode?e.exitCode:1,r=process.argv.slice(2).find(e=>!e.startsWith("-")),n=!!r&&!!bu(hu,[r]);if(("commander.excessArguments"===e.code||"commander.unknownCommand"===e.code)&&r&&!n)return mu=[],ls.warn("Unknown command",{command:r}),process.stderr.write(`command '${r}' not found\n`),wu(),void(process.exitCode=t);ls.debug("Commander error",{code:e.code,exitCode:t}),_u(),process.exitCode=t}finally{ls.flush(),await uu()}})();
|
|
2
|
+
import{config as e,parse as t}from"dotenv";import*as r from"path";import n,{resolve as s,dirname as o,join as i,sep as a,normalize as c,basename as l}from"path";import{Command as u}from"commander";import{Buffer as d}from"buffer";import p,{exec as f,execSync as h,spawn as g,execFile as m,execFileSync as y}from"child_process";import b from"process";import*as w from"fs";import v,{mkdirSync as I,writeFileSync as T,rmSync as _,existsSync as E,statSync as S,readFileSync as x,appendFileSync as A,realpathSync as k,createReadStream as P,openSync as C,readSync as R,closeSync as U}from"fs";import{fileURLToPath as L,URL as $}from"url";import D,{tmpdir as N,constants as O}from"os";import"timers/promises";import B from"stream";import{debuglog as j,promisify as M,TextDecoder as F,TextEncoder as H}from"util";import{createSdkMcpServer as G,tool as W,query as V}from"@anthropic-ai/claude-agent-sdk";import{rm as Y,readFile as z,mkdir as q,writeFile as K,unlink as J,access as X,readdir as Q,stat as Z,appendFile as ee}from"fs/promises";import te from"net";import{createInterface as re}from"readline/promises";import ne from"picocolors";import{simpleGit as se}from"simple-git";import oe,{randomUUID as ie}from"crypto";import{log as ae,outro as ce,spinner as le,intro as ue,select as de,isCancel as pe}from"@clack/prompts";import fe,{z as he}from"zod";import ge from"open";import me from"http";import ye from"pino";import be from"sonic-boom";import{z as we}from"zod/v3";import ve from"ws";import{useState as Ie,useRef as Te,useEffect as _e,useCallback as Ee,useMemo as Se}from"react";import{jsx as xe,jsxs as Ae}from"react/jsx-runtime";import{createRequire as ke}from"module";import{parseDocument as Pe}from"yaml";import{startTunnel as Ce}from"@stablyhq/runner-sdk";var Re=(e=>"undefined"!=typeof require?require:"undefined"!=typeof Proxy?new Proxy(e,{get:(e,t)=>("undefined"!=typeof require?require:e)[t]}):e)(function(e){if("undefined"!=typeof require)return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')}),Ue={cwdChanged:!1,newCwd:void 0,envFilesLoaded:[],envFileErrors:[],remoteEnvName:void 0},Le=process.argv.findIndex(e=>"-C"===e||"--cwd"===e);if(-1!==Le&&process.argv[Le+1]){const e=process.argv[Le+1];process.chdir(e),Ue.cwdChanged=!0,Ue.newCwd=e,process.argv.splice(Le,2)}for(var $e=[],De=0;De<process.argv.length;)if("--env-file"===process.argv[De]){const e=process.argv[De+1];e&&!e.startsWith("-")?($e.push(e),process.argv.splice(De,2)):De++}else De++;var Ne=process.argv.findIndex(e=>"--env"===e);-1!==Ne&&process.argv[Ne+1]&&!process.argv[Ne+1].startsWith("-")&&(Ue.remoteEnvName=process.argv[Ne+1],process.argv.splice(Ne,2));for(const t of[...$e].reverse()){const r=n.resolve(process.cwd(),t),s=e({path:r,override:!1,quiet:!0});if(s.error){const e=`warning: could not load env file: ${r} (${s.error.message})`;Ue.envFileErrors.push(e),process.stderr.write(`${e}\n`)}else Ue.envFilesLoaded.unshift(r)}var Oe={detect:({env:e})=>Boolean(e.APPVEYOR),configuration({env:e}){const t=e.APPVEYOR_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Appveyor",service:"appveyor",commit:e.APPVEYOR_REPO_COMMIT,tag:e.APPVEYOR_REPO_TAG_NAME,build:e.APPVEYOR_BUILD_NUMBER,buildUrl:`https://ci.appveyor.com/project/${e.APPVEYOR_PROJECT_SLUG}/build/${e.APPVEYOR_BUILD_VERSION}`,branch:e.APPVEYOR_REPO_BRANCH,job:e.APPVEYOR_JOB_NUMBER,jobUrl:`https://ci.appveyor.com/project/${e.APPVEYOR_PROJECT_SLUG}/build/job/${e.APPVEYOR_JOB_ID}`,pr:t,isPr:r,prBranch:e.APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH,slug:e.APPVEYOR_REPO_NAME,root:e.APPVEYOR_BUILD_FOLDER}}};function Be(e){return(/\d+(?!.*\d+)/.exec(e)||[])[0]}function je(e){return e?/^(?:refs\/heads\/)?(?<branch>.+)$/i.exec(e)[1]:void 0}var Me={detect:({env:e})=>Boolean(e.BUILD_BUILDURI),configuration({env:e}){const t=e.SYSTEM_PULLREQUEST_PULLREQUESTID,r=Boolean(t);return{name:"Azure Pipelines",service:"azurePipelines",commit:e.BUILD_SOURCEVERSION,build:e.BUILD_BUILDNUMBER,branch:je(r?e.SYSTEM_PULLREQUEST_TARGETBRANCH:e.BUILD_SOURCEBRANCH),pr:t,isPr:r,prBranch:je(r?e.SYSTEM_PULLREQUEST_SOURCEBRANCH:void 0),root:e.BUILD_REPOSITORY_LOCALPATH}}},Fe={detect:({env:e})=>Boolean(e.bamboo_agentId),configuration:({env:e})=>({name:"Bamboo",service:"bamboo",commit:e.bamboo_planRepository_1_revision,build:e.bamboo_buildNumber,buildUrl:e.bamboo_buildResultsUrl,branch:e.bamboo_planRepository_1_branchName,job:e.bamboo_buildKey,root:e.bamboo_build_working_directory})},He={detect:({env:e})=>Boolean(e.BITBUCKET_BUILD_NUMBER),configuration:({env:e})=>({name:"Bitbucket Pipelines",service:"bitbucket",commit:e.BITBUCKET_COMMIT,tag:e.BITBUCKET_TAG,build:e.BITBUCKET_BUILD_NUMBER,buildUrl:`https://bitbucket.org/${e.BITBUCKET_REPO_FULL_NAME}/addon/pipelines/home#!/results/${e.BITBUCKET_BUILD_NUMBER}`,branch:e.BITBUCKET_BRANCH,slug:e.BITBUCKET_REPO_FULL_NAME,root:e.BITBUCKET_CLONE_DIR})},Ge={detect:({env:e})=>Boolean(e.BITRISE_IO),configuration({env:e}){const t="false"===e.BITRISE_PULL_REQUEST?void 0:e.BITRISE_PULL_REQUEST,r=Boolean(t);return{name:"Bitrise",service:"bitrise",commit:e.BITRISE_GIT_COMMIT,tag:e.BITRISE_GIT_TAG,build:e.BITRISE_BUILD_NUMBER,buildUrl:e.BITRISE_BUILD_URL,branch:r?e.BITRISEIO_GIT_BRANCH_DEST:e.BITRISE_GIT_BRANCH,pr:t,isPr:r,prBranch:r?e.BITRISE_GIT_BRANCH:void 0,slug:e.BITRISE_APP_SLUG}}},We={detect:({env:e})=>Boolean(e.BUDDY_WORKSPACE_ID),configuration({env:e}){const t=Be(e.BUDDY_EXECUTION_PULL_REQUEST_ID),r=Boolean(t);return{name:"Buddy",service:"buddy",commit:e.BUDDY_EXECUTION_REVISION,tag:e.BUDDY_EXECUTION_TAG,build:e.BUDDY_EXECUTION_ID,buildUrl:e.BUDDY_EXECUTION_URL,branch:r?e.BUDDY_EXECUTION_PULL_REQUEST_HEAD_BRANCH:e.BUDDY_EXECUTION_BRANCH,pr:t,isPr:r,slug:e.BUDDY_REPO_SLUG}}},Ve="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function Ye(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var ze,qe,Ke,Je,Xe,Qe,Ze,et,tt={exports:{}};var rt,nt,st,ot,it,at,ct,lt,ut,dt,pt,ft,ht,gt,mt,yt={exports:{}},bt={};function wt(){if(ft)return pt;ft=1;const e=n,t=function(){if(st)return nt;st=1;const e=n,t=function(){if(et)return Ze;et=1;const e="win32"===process.platform||"cygwin"===process.env.OSTYPE||"msys"===process.env.OSTYPE,t=n,r=e?";":":",s=function(){if(Qe)return Xe;var e;function t(r,n,s){if("function"==typeof n&&(s=n,n={}),!s){if("function"!=typeof Promise)throw new TypeError("callback not provided");return new Promise(function(e,s){t(r,n||{},function(t,r){t?s(t):e(r)})})}e(r,n||{},function(e,t){e&&("EACCES"===e.code||n&&n.ignoreErrors)&&(e=null,t=!1),s(e,t)})}return Qe=1,e="win32"===process.platform||Ve.TESTING_WINDOWS?function(){if(qe)return ze;qe=1,ze=r,r.sync=function(r,n){return t(e.statSync(r),r,n)};var e=v;function t(e,t,r){return!(!e.isSymbolicLink()&&!e.isFile())&&function(e,t){var r=void 0!==t.pathExt?t.pathExt:process.env.PATHEXT;if(!r)return!0;if(-1!==(r=r.split(";")).indexOf(""))return!0;for(var n=0;n<r.length;n++){var s=r[n].toLowerCase();if(s&&e.substr(-s.length).toLowerCase()===s)return!0}return!1}(t,r)}function r(r,n,s){e.stat(r,function(e,o){s(e,!e&&t(o,r,n))})}return ze}():function(){if(Je)return Ke;Je=1,Ke=t,t.sync=function(t,n){return r(e.statSync(t),n)};var e=v;function t(t,n,s){e.stat(t,function(e,t){s(e,!e&&r(t,n))})}function r(e,t){return e.isFile()&&function(e,t){var r=e.mode,n=e.uid,s=e.gid,o=void 0!==t.uid?t.uid:process.getuid&&process.getuid(),i=void 0!==t.gid?t.gid:process.getgid&&process.getgid(),a=parseInt("100",8),c=parseInt("010",8);return r&parseInt("001",8)||r&c&&s===i||r&a&&n===o||r&(a|c)&&0===o}(e,t)}return Ke}(),Xe=t,t.sync=function(t,r){try{return e.sync(t,r||{})}catch(e){if(r&&r.ignoreErrors||"EACCES"===e.code)return!1;throw e}},Xe}(),o=e=>Object.assign(new Error(`not found: ${e}`),{code:"ENOENT"}),i=(t,n)=>{const s=n.colon||r,o=t.match(/\//)||e&&t.match(/\\/)?[""]:[...e?[process.cwd()]:[],...(n.path||process.env.PATH||"").split(s)],i=e?n.pathExt||process.env.PATHEXT||".EXE;.CMD;.BAT;.COM":"",a=e?i.split(s):[""];return e&&-1!==t.indexOf(".")&&""!==a[0]&&a.unshift(""),{pathEnv:o,pathExt:a,pathExtExe:i}},a=(e,r,n)=>{"function"==typeof r&&(n=r,r={}),r||(r={});const{pathEnv:a,pathExt:c,pathExtExe:l}=i(e,r),u=[],d=n=>new Promise((s,i)=>{if(n===a.length)return r.all&&u.length?s(u):i(o(e));const c=a[n],l=/^".*"$/.test(c)?c.slice(1,-1):c,d=t.join(l,e),f=!l&&/^\.[\\\/]/.test(e)?e.slice(0,2)+d:d;s(p(f,n,0))}),p=(e,t,n)=>new Promise((o,i)=>{if(n===c.length)return o(d(t+1));const a=c[n];s(e+a,{pathExt:l},(s,i)=>{if(!s&&i){if(!r.all)return o(e+a);u.push(e+a)}return o(p(e,t,n+1))})});return n?d(0).then(e=>n(null,e),n):d(0)};return Ze=a,a.sync=(e,r)=>{r=r||{};const{pathEnv:n,pathExt:a,pathExtExe:c}=i(e,r),l=[];for(let o=0;o<n.length;o++){const i=n[o],u=/^".*"$/.test(i)?i.slice(1,-1):i,d=t.join(u,e),p=!u&&/^\.[\\\/]/.test(e)?e.slice(0,2)+d:d;for(let e=0;e<a.length;e++){const t=p+a[e];try{if(s.sync(t,{pathExt:c})){if(!r.all)return t;l.push(t)}}catch(e){}}}if(r.all&&l.length)return l;if(r.nothrow)return null;throw o(e)},Ze}(),r=function(){if(rt)return yt.exports;rt=1;const e=(e={})=>{const t=e.env||process.env;return"win32"!==(e.platform||process.platform)?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"};return yt.exports=e,yt.exports.default=e,yt.exports}();function s(n,s){const o=n.options.env||process.env,i=process.cwd(),a=null!=n.options.cwd,c=a&&void 0!==process.chdir&&!process.chdir.disabled;if(c)try{process.chdir(n.options.cwd)}catch(e){}let l;try{l=t.sync(n.command,{path:o[r({env:o})],pathExt:s?e.delimiter:void 0})}catch(e){}finally{c&&process.chdir(i)}return l&&(l=e.resolve(a?n.options.cwd:"",l)),l}return nt=function(e){return s(e)||s(e,!0)}}(),r=function(){if(ot)return bt;ot=1;const e=/([()\][%!^"`<>&|;, *?])/g;return bt.command=function(t){return t.replace(e,"^$1")},bt.argument=function(t,r){return t=(t=`"${t=(t=(t=`${t}`).replace(/(?=(\\+?)?)\1"/g,'$1$1\\"')).replace(/(?=(\\+?)?)\1$/,"$1$1")}"`).replace(e,"^$1"),r&&(t=t.replace(e,"^$1")),t},bt}(),s=function(){if(dt)return ut;dt=1;const e=v,t=function(){if(lt)return ct;lt=1;const e=at?it:(at=1,it=/^#!(.*)/);return ct=(t="")=>{const r=t.match(e);if(!r)return null;const[n,s]=r[0].replace(/#! ?/,"").split(" "),o=n.split("/").pop();return"env"===o?s:s?`${o} ${s}`:o}}();return ut=function(r){const n=Buffer.alloc(150);let s;try{s=e.openSync(r,"r"),e.readSync(s,n,0,150,0),e.closeSync(s)}catch(e){}return t(n.toString())}}(),o="win32"===process.platform,i=/\.(?:com|exe)$/i,a=/node_modules[\\/].bin[\\/][^\\/]+\.cmd$/i;return pt=function(n,c,l){c&&!Array.isArray(c)&&(l=c,c=null);const u={command:n,args:c=c?c.slice(0):[],options:l=Object.assign({},l),file:void 0,original:{command:n,args:c}};return l.shell?u:function(n){if(!o)return n;const c=function(e){e.file=t(e);const r=e.file&&s(e.file);return r?(e.args.unshift(e.file),e.command=r,t(e)):e.file}(n),l=!i.test(c);if(n.options.forceShell||l){const t=a.test(c);n.command=e.normalize(n.command),n.command=r.command(n.command),n.args=n.args.map(e=>r.argument(e,t));const s=[n.command].concat(n.args).join(" ");n.args=["/d","/s","/c",`"${s}"`],n.command=process.env.comspec||"cmd.exe",n.options.windowsVerbatimArguments=!0}return n}(u)}}var vt=Ye(function(){if(mt)return tt.exports;mt=1;const e=p,t=wt(),r=function(){if(gt)return ht;gt=1;const e="win32"===process.platform;function t(e,t){return Object.assign(new Error(`${t} ${e.command} ENOENT`),{code:"ENOENT",errno:"ENOENT",syscall:`${t} ${e.command}`,path:e.command,spawnargs:e.args})}function r(r,n){return e&&1===r&&!n.file?t(n.original,"spawn"):null}return ht={hookChildProcess:function(t,n){if(!e)return;const s=t.emit;t.emit=function(e,o){if("exit"===e){const e=r(o,n);if(e)return s.call(t,"error",e)}return s.apply(t,arguments)}},verifyENOENT:r,verifyENOENTSync:function(r,n){return e&&1===r&&!n.file?t(n.original,"spawnSync"):null},notFoundError:t},ht}();function n(n,s,o){const i=t(n,s,o),a=e.spawn(i.command,i.args,i.options);return r.hookChildProcess(a,i),a}return tt.exports=n,tt.exports.spawn=n,tt.exports.sync=function(n,s,o){const i=t(n,s,o),a=e.spawnSync(i.command,i.args,i.options);return a.error=a.error||r.verifyENOENTSync(a.status,i),a},tt.exports._parse=t,tt.exports._enoent=r,tt.exports}());function It(e={}){const{env:t=process.env,platform:r=process.platform}=e;return"win32"!==r?"PATH":Object.keys(t).reverse().find(e=>"PATH"===e.toUpperCase())||"Path"}var Tt=(e,t)=>({name:`SIGRT${t+1}`,number:_t+t,action:"terminate",description:"Application-specific signal (realtime)",standard:"posix"}),_t=34,Et=[{name:"SIGHUP",number:1,action:"terminate",description:"Terminal closed",standard:"posix"},{name:"SIGINT",number:2,action:"terminate",description:"User interruption with CTRL-C",standard:"ansi"},{name:"SIGQUIT",number:3,action:"core",description:"User interruption with CTRL-\\",standard:"posix"},{name:"SIGILL",number:4,action:"core",description:"Invalid machine instruction",standard:"ansi"},{name:"SIGTRAP",number:5,action:"core",description:"Debugger breakpoint",standard:"posix"},{name:"SIGABRT",number:6,action:"core",description:"Aborted",standard:"ansi"},{name:"SIGIOT",number:6,action:"core",description:"Aborted",standard:"bsd"},{name:"SIGBUS",number:7,action:"core",description:"Bus error due to misaligned, non-existing address or paging error",standard:"bsd"},{name:"SIGEMT",number:7,action:"terminate",description:"Command should be emulated but is not implemented",standard:"other"},{name:"SIGFPE",number:8,action:"core",description:"Floating point arithmetic error",standard:"ansi"},{name:"SIGKILL",number:9,action:"terminate",description:"Forced termination",standard:"posix",forced:!0},{name:"SIGUSR1",number:10,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGSEGV",number:11,action:"core",description:"Segmentation fault",standard:"ansi"},{name:"SIGUSR2",number:12,action:"terminate",description:"Application-specific signal",standard:"posix"},{name:"SIGPIPE",number:13,action:"terminate",description:"Broken pipe or socket",standard:"posix"},{name:"SIGALRM",number:14,action:"terminate",description:"Timeout or timer",standard:"posix"},{name:"SIGTERM",number:15,action:"terminate",description:"Termination",standard:"ansi"},{name:"SIGSTKFLT",number:16,action:"terminate",description:"Stack is empty or overflowed",standard:"other"},{name:"SIGCHLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"posix"},{name:"SIGCLD",number:17,action:"ignore",description:"Child process terminated, paused or unpaused",standard:"other"},{name:"SIGCONT",number:18,action:"unpause",description:"Unpaused",standard:"posix",forced:!0},{name:"SIGSTOP",number:19,action:"pause",description:"Paused",standard:"posix",forced:!0},{name:"SIGTSTP",number:20,action:"pause",description:'Paused using CTRL-Z or "suspend"',standard:"posix"},{name:"SIGTTIN",number:21,action:"pause",description:"Background process cannot read terminal input",standard:"posix"},{name:"SIGBREAK",number:21,action:"terminate",description:"User interruption with CTRL-BREAK",standard:"other"},{name:"SIGTTOU",number:22,action:"pause",description:"Background process cannot write to terminal output",standard:"posix"},{name:"SIGURG",number:23,action:"ignore",description:"Socket received out-of-band data",standard:"bsd"},{name:"SIGXCPU",number:24,action:"core",description:"Process timed out",standard:"bsd"},{name:"SIGXFSZ",number:25,action:"core",description:"File too big",standard:"bsd"},{name:"SIGVTALRM",number:26,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGPROF",number:27,action:"terminate",description:"Timeout or timer",standard:"bsd"},{name:"SIGWINCH",number:28,action:"ignore",description:"Terminal window size changed",standard:"bsd"},{name:"SIGIO",number:29,action:"terminate",description:"I/O is available",standard:"other"},{name:"SIGPOLL",number:29,action:"terminate",description:"Watched event",standard:"other"},{name:"SIGINFO",number:29,action:"ignore",description:"Request for process information",standard:"other"},{name:"SIGPWR",number:30,action:"terminate",description:"Device running out of power",standard:"systemv"},{name:"SIGSYS",number:31,action:"core",description:"Invalid system call",standard:"other"},{name:"SIGUNUSED",number:31,action:"terminate",description:"Invalid system call",standard:"other"}],St=()=>{const e=(()=>{const e=64-_t+1;return Array.from({length:e},Tt)})();return[...Et,...e].map(xt)},xt=({name:e,number:t,description:r,action:n,forced:s=!1,standard:o})=>{const{signals:{[e]:i}}=O,a=void 0!==i;return{name:e,number:a?i:t,description:r,supported:a,action:n,forced:s,standard:o}},At=({name:e,number:t,description:r,supported:n,action:s,forced:o,standard:i})=>[e,{name:e,number:t,description:r,supported:n,action:s,forced:o,standard:i}],kt=(()=>{const e=St();return Object.fromEntries(e.map(At))})();(()=>{const e=St(),t=Array.from({length:65},(t,r)=>((e,t)=>{const r=((e,t)=>{const r=t.find(({name:t})=>O.signals[t]===e);return void 0!==r?r:t.find(t=>t.number===e)})(e,t);if(void 0===r)return{};const{name:n,description:s,supported:o,action:i,forced:a,standard:c}=r;return{[e]:{name:n,number:e,description:s,supported:o,action:i,forced:a,standard:c}}})(r,e));Object.assign({},...t)})();var Pt=({stdout:e,stderr:t,all:r,error:n,signal:s,exitCode:o,command:i,escapedCommand:a,timedOut:c,isCanceled:l,killed:u,parsed:{options:{timeout:d,cwd:p=b.cwd()}}})=>{o=null===o?void 0:o;const f=void 0===(s=null===s?void 0:s)?void 0:kt[s].description,h=(({timedOut:e,timeout:t,errorCode:r,signal:n,signalDescription:s,exitCode:o,isCanceled:i})=>e?`timed out after ${t} milliseconds`:void 0!==r?`failed with ${r}`:void 0!==n?`was killed with ${n} (${s})`:void 0!==o?`failed with exit code ${o}`:"failed")({timedOut:c,timeout:d,errorCode:n&&n.code,signal:s,signalDescription:f,exitCode:o,isCanceled:l}),g=`Command ${h}: ${i}`,m="[object Error]"===Object.prototype.toString.call(n),y=m?`${g}\n${n.message}`:g,w=[y,t,e].filter(Boolean).join("\n");return m?(n.originalMessage=n.message,n.message=w):n=new Error(w),n.shortMessage=y,n.command=i,n.escapedCommand=a,n.exitCode=o,n.signal=s,n.signalDescription=f,n.stdout=e,n.stderr=t,n.cwd=p,void 0!==r&&(n.all=r),"bufferedData"in n&&delete n.bufferedData,n.failed=!0,n.timedOut=Boolean(c),n.isCanceled=l,n.killed=u&&!c,n},Ct=["stdin","stdout","stderr"],Rt=[];Rt.push("SIGHUP","SIGINT","SIGTERM"),"win32"!==process.platform&&Rt.push("SIGALRM","SIGABRT","SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT"),"linux"===process.platform&&Rt.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT");var Ut,Lt,$t=e=>!!e&&"object"==typeof e&&"function"==typeof e.removeListener&&"function"==typeof e.emit&&"function"==typeof e.reallyExit&&"function"==typeof e.listeners&&"function"==typeof e.kill&&"number"==typeof e.pid&&"function"==typeof e.on,Dt=Symbol.for("signal-exit emitter"),Nt=globalThis,Ot=Object.defineProperty.bind(Object),Bt=class{emitted={afterExit:!1,exit:!1};listeners={afterExit:[],exit:[]};count=0;id=Math.random();constructor(){if(Nt[Dt])return Nt[Dt];Ot(Nt,Dt,{value:this,writable:!1,enumerable:!1,configurable:!1})}on(e,t){this.listeners[e].push(t)}removeListener(e,t){const r=this.listeners[e],n=r.indexOf(t);-1!==n&&(0===n&&1===r.length?r.length=0:r.splice(n,1))}emit(e,t,r){if(this.emitted[e])return!1;this.emitted[e]=!0;let n=!1;for(const s of this.listeners[e])n=!0===s(t,r)||n;return"exit"===e&&(n=this.emit("afterExit",t,r)||n),n}},jt=class{},Mt=globalThis.process;$t(Mt)?new class extends jt{#e="win32"===Mt.platform?"SIGINT":"SIGHUP";#t=new Bt;#r;#n;#s;#o={};#i=!1;constructor(e){super(),this.#r=e,this.#o={};for(const t of Rt)this.#o[t]=()=>{const r=this.#r.listeners(t);let{count:n}=this.#t;const s=e;if("object"==typeof s.__signal_exit_emitter__&&"number"==typeof s.__signal_exit_emitter__.count&&(n+=s.__signal_exit_emitter__.count),r.length===n){this.unload();const r=this.#t.emit("exit",null,t),n="SIGHUP"===t?this.#e:t;r||e.kill(e.pid,n)}};this.#s=e.reallyExit,this.#n=e.emit}onExit(e,t){if(!$t(this.#r))return()=>{};!1===this.#i&&this.load();const r=t?.alwaysLast?"afterExit":"exit";return this.#t.on(r,e),()=>{this.#t.removeListener(r,e),0===this.#t.listeners.exit.length&&0===this.#t.listeners.afterExit.length&&this.unload()}}load(){if(!this.#i){this.#i=!0,this.#t.count+=1;for(const e of Rt)try{const t=this.#o[e];t&&this.#r.on(e,t)}catch(e){}this.#r.emit=(e,...t)=>this.#a(e,...t),this.#r.reallyExit=e=>this.#c(e)}}unload(){this.#i&&(this.#i=!1,Rt.forEach(e=>{const t=this.#o[e];if(!t)throw new Error("Listener not defined for signal: "+e);try{this.#r.removeListener(e,t)}catch(e){}}),this.#r.emit=this.#n,this.#r.reallyExit=this.#s,this.#t.count-=1)}#c(e){return $t(this.#r)?(this.#r.exitCode=e||0,this.#t.emit("exit",this.#r.exitCode,null),this.#s.call(this.#r,this.#r.exitCode)):0}#a(e,...t){const r=this.#n;if("exit"===e&&$t(this.#r)){"number"==typeof t[0]&&(this.#r.exitCode=t[0]);const n=r.call(this.#r,e,...t);return this.#t.emit("exit",this.#r.exitCode,null),n}return r.call(this.#r,e,...t)}}(Mt):new class extends jt{onExit(){return()=>{}}load(){}unload(){}},new TextEncoder,function(){if(Lt)return Ut;Lt=1;const{PassThrough:e}=B;Ut=function(){var t=[],r=new e({objectMode:!0});return r.setMaxListeners(0),r.add=n,r.isEmpty=function(){return 0==t.length},r.on("unpipe",s),Array.prototype.slice.call(arguments).forEach(n),r;function n(e){return Array.isArray(e)?(e.forEach(n),this):(t.push(e),e.once("end",s.bind(null,e)),e.once("error",r.emit.bind(r,"error")),e.pipe(r,{end:!1}),this)}function s(e){!(t=t.filter(function(t){return t!==e})).length&&r.readable&&r.end()}}}();var Ft=(async()=>{})().constructor.prototype;["then","catch","finally"].map(e=>[e,Reflect.getOwnPropertyDescriptor(Ft,e)]);var Ht=(e,t=[])=>Array.isArray(t)?[e,...t]:[e],Gt=/^[\w.-]+$/,Wt=j("execa").enabled,Vt=(e,t)=>String(e).padStart(t,"0"),Yt=(e,t,r={})=>{const s=vt._parse(e,t,r);return e=s.command,t=s.args,(r={maxBuffer:1e8,buffer:!0,stripFinalNewline:!0,extendEnv:!0,preferLocal:!1,localDir:(r=s.options).cwd||b.cwd(),execPath:b.execPath,encoding:"utf8",reject:!0,cleanup:!0,all:!1,windowsHide:!0,verbose:Wt,...r}).env=(({env:e,extendEnv:t,preferLocal:r,localDir:s,execPath:o})=>{const i=t?{...b.env,...e}:e;return r?(({env:e=b.env,...t}={})=>{const r=It({env:e={...e}});return t.path=e[r],e[r]=(({cwd:e=b.cwd(),path:t=b.env[It()],preferLocal:r=!0,execPath:s=b.execPath,addExecPath:o=!0}={})=>{const i=e instanceof URL?L(e):e,a=n.resolve(i),c=[];return r&&((e,t)=>{let r;for(;r!==t;)e.push(n.join(t,"node_modules/.bin")),r=t,t=n.resolve(t,"..")})(c,a),o&&((e,t,r)=>{const s=t instanceof URL?L(t):t;e.push(n.resolve(r,s,".."))})(c,s,a),[...c,t].join(n.delimiter)})(t),e})({env:i,cwd:s,execPath:o}):i})(r),r.stdio=(e=>{if(!e)return;const{stdio:t}=e;if(void 0===t)return Ct.map(t=>e[t]);if((e=>Ct.some(t=>void 0!==e[t]))(e))throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${Ct.map(e=>`\`${e}\``).join(", ")}`);if("string"==typeof t)return t;if(!Array.isArray(t))throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof t}\``);const r=Math.max(t.length,Ct.length);return Array.from({length:r},(e,r)=>t[r])})(r),"win32"===b.platform&&"cmd"===n.basename(e,".exe")&&t.unshift("/q"),{file:e,args:t,options:r,parsed:s}},zt=(e,t,r)=>"string"==typeof t||d.isBuffer(t)?e.stripFinalNewline?function(e){const t="string"==typeof e?"\n":"\n".charCodeAt(),r="string"==typeof e?"\r":"\r".charCodeAt();return e[e.length-1]===t&&(e=e.slice(0,-1)),e[e.length-1]===r&&(e=e.slice(0,-1)),e}(t):t:void 0===r?void 0:"";function qt(e,t,r){const n=Yt(e,t,r),s=((e,t)=>Ht(e,t).join(" "))(e,t),o=((e,t)=>Ht(e,t).map(e=>(e=>"string"!=typeof e||Gt.test(e)?e:`"${e.replaceAll('"','\\"')}"`)(e)).join(" "))(e,t);((e,{verbose:t})=>{t&&b.stderr.write(`[${(()=>{const e=new Date;return`${Vt(e.getHours(),2)}:${Vt(e.getMinutes(),2)}:${Vt(e.getSeconds(),2)}.${Vt(e.getMilliseconds(),3)}`})()}] ${e}\n`)})(o,n.options);const i=(e=>{const t=(({input:e,inputFile:t})=>"string"!=typeof t?e:((e=>{if(void 0!==e)throw new TypeError("The `input` and `inputFile` options cannot be both set.")})(e),x(t)))(e);if(null!==(r=t)&&"object"==typeof r&&"function"==typeof r.pipe)throw new TypeError("The `input` option cannot be a stream in sync mode");var r;return t})(n.options);let a;try{a=p.spawnSync(n.file,n.args,{...n.options,input:i})}catch(e){throw Pt({error:e,stdout:"",stderr:"",all:"",command:s,escapedCommand:o,parsed:n,timedOut:!1,isCanceled:!1,killed:!1})}const c=zt(n.options,a.stdout,a.error),l=zt(n.options,a.stderr,a.error);if(a.error||0!==a.status||null!==a.signal){const e=Pt({stdout:c,stderr:l,error:a.error,signal:a.signal,exitCode:a.status,command:s,escapedCommand:o,parsed:n,timedOut:a.error&&"ETIMEDOUT"===a.error.code,isCanceled:!1,killed:null!==a.signal});if(!n.options.reject)return e;throw e}return{command:s,escapedCommand:o,exitCode:0,stdout:c,stderr:l,failed:!1,timedOut:!1,isCanceled:!1,killed:!1}}function Kt(e){try{return qt("git",["rev-parse","HEAD"],e).stdout}catch{return}}function Jt(e){try{const t=qt("git",["rev-parse","--abbrev-ref","HEAD"],e).stdout;if("HEAD"===t){const t=qt("git",["show","-s","--pretty=%d","HEAD"],e).stdout.replace(/^\(|\)$/g,"").split(", ").find(e=>e.startsWith("origin/"));return t?t.match(/^origin\/(?<branch>.+)/)[1]:void 0}return t}catch{return}}var Xt=/^(?:.*)@(?:.*):(?:\d+\/)?(.*)\.git$/,Qt=/^\/(.*)\.git$/;function Zt(e){if(e){if(e.match(Xt))return e.replace(Xt,"$1");try{return new URL(e).pathname.replace(Qt,"$1")}catch{return}}}var er,tr={detect:({env:e})=>Boolean(e.BUILDKITE),configuration({env:e}){const t="false"===e.BUILDKITE_PULL_REQUEST?void 0:e.BUILDKITE_PULL_REQUEST,r=Boolean(t);return{name:"Buildkite",service:"buildkite",build:e.BUILDKITE_BUILD_NUMBER,buildUrl:e.BUILDKITE_BUILD_URL,commit:e.BUILDKITE_COMMIT,tag:e.BUILDKITE_TAG,branch:r?e.BUILDKITE_PULL_REQUEST_BASE_BRANCH:e.BUILDKITE_BRANCH,slug:Zt(e.BUILDKITE_REPO),pr:t,isPr:r,prBranch:r?e.BUILDKITE_BRANCH:void 0,root:e.BUILDKITE_BUILD_CHECKOUT_PATH}}},rr={detect:({env:e})=>Boolean(e.CIRCLECI),configuration({env:e}){const t=e.CIRCLE_PR_NUMBER||Be(e.CIRCLE_PULL_REQUEST||e.CI_PULL_REQUEST),r=Boolean(t);return{name:"CircleCI",service:"circleci",build:e.CIRCLE_BUILD_NUM,buildUrl:e.CIRCLE_BUILD_URL,job:`${e.CIRCLE_BUILD_NUM}.${e.CIRCLE_NODE_INDEX}`,commit:e.CIRCLE_SHA1,tag:e.CIRCLE_TAG,branch:r?void 0:e.CIRCLE_BRANCH,pr:t,isPr:r,prBranch:r?e.CIRCLE_BRANCH:void 0,slug:`${e.CIRCLE_PROJECT_USERNAME}/${e.CIRCLE_PROJECT_REPONAME}`}}},nr="https://cirrus-ci.com",sr={detect:({env:e})=>Boolean(e.CIRRUS_CI),configuration({env:e}){const t=e.CIRRUS_PR,r=Boolean(t);return{name:"Cirrus CI",service:"cirrus",commit:e.CIRRUS_CHANGE_IN_REPO,tag:e.CIRRUS_TAG,build:e.CIRRUS_BUILD_ID,buildUrl:`${nr}/build/${e.CIRRUS_BUILD_ID}`,job:e.CIRRUS_TASK_ID,jobUrl:`${nr}/task/${e.CIRRUS_TASK_ID}`,branch:r?e.CIRRUS_BASE_BRANCH:e.CIRRUS_BRANCH,pr:t,isPr:r,prBranch:r?e.CIRRUS_BRANCH:void 0,slug:e.CIRRUS_REPO_FULL_NAME,root:e.CIRRUS_WORKING_DIR}}},or={detect:({env:e})=>Boolean(e.CODEBUILD_BUILD_ID),configuration:({env:e,cwd:t})=>({name:"AWS CodeBuild",service:"codebuild",commit:Kt({env:e,cwd:t}),build:e.CODEBUILD_BUILD_ID,branch:Jt({env:e,cwd:t}),buildUrl:`https://console.aws.amazon.com/codebuild/home?region=${e.AWS_REGION}#/builds/${e.CODEBUILD_BUILD_ID}/view/new`,root:e.PWD})},ir={detect:({env:e})=>Boolean(e.CF_BUILD_ID),configuration({env:e}){const t=e.CF_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Codefresh",service:"codefresh",commit:e.CF_REVISION,build:e.CF_BUILD_ID,buildUrl:e.CF_BUILD_URL,branch:r?e.CF_PULL_REQUEST_TARGET:e.CF_BRANCH,pr:t,isPr:r,prBranch:r?e.CF_BRANCH:void 0,slug:`${e.CF_REPO_OWNER}/${e.CF_REPO_NAME}`,root:e.CF_VOLUME_PATH}}},ar={detect:({env:e})=>Boolean(e.DRONE),configuration({env:e}){const t="pull_request"===e.DRONE_BUILD_EVENT;return{name:"Drone",service:"drone",commit:e.DRONE_COMMIT_SHA,tag:e.DRONE_TAG,build:e.DRONE_BUILD_NUMBER,buildUrl:e.DRONE_BUILD_LINK,branch:t?e.DRONE_TARGET_BRANCH:e.DRONE_BRANCH,job:e.DRONE_JOB_NUMBER,jobUrl:e.DRONE_BUILD_LINK,pr:e.DRONE_PULL_REQUEST,isPr:t,prBranch:t?e.DRONE_SOURCE_BRANCH:void 0,slug:`${e.DRONE_REPO_OWNER}/${e.DRONE_REPO_NAME}`,root:e.DRONE_WORKSPACE}}},cr=e=>({commit:Kt(e),branch:Jt(e)}),lr=({env:e})=>{try{const t=e.GITHUB_EVENT_PATH?JSON.parse(x(e.GITHUB_EVENT_PATH,"utf-8")):void 0;if(t&&t.pull_request)return{branch:t.pull_request.base?je(t.pull_request.base.ref):void 0,pr:t.pull_request.number}}catch{}return{pr:void 0,branch:void 0}},ur={detect:({env:e})=>Boolean(e.GITHUB_ACTIONS),configuration({env:e,cwd:t}){const r="pull_request"===e.GITHUB_EVENT_NAME||"pull_request_target"===e.GITHUB_EVENT_NAME,n=je("pull_request_target"===e.GITHUB_EVENT_NAME?`refs/pull/${(e=>{const t=e.GITHUB_EVENT_PATH?JSON.parse(x(e.GITHUB_EVENT_PATH,"utf-8")):void 0;return t&&t.pull_request?t.pull_request.number:void 0})(e)}/merge`:e.GITHUB_REF);return{name:"GitHub Actions",service:"github",commit:e.GITHUB_SHA,build:e.GITHUB_RUN_ID,buildUrl:`${e.GITHUB_SERVER_URL}/${e.GITHUB_REPOSITORY}/actions/runs/${e.GITHUB_RUN_ID}`,isPr:r,branch:n,prBranch:r?n:void 0,slug:e.GITHUB_REPOSITORY,root:e.GITHUB_WORKSPACE,...r?lr({env:e}):void 0}}},dr={detect:({env:e})=>Boolean(e.GITLAB_CI),configuration({env:e}){const t=e.CI_MERGE_REQUEST_ID,r=Boolean(t);return{name:"GitLab CI/CD",service:"gitlab",commit:e.CI_COMMIT_SHA,tag:e.CI_COMMIT_TAG,build:e.CI_PIPELINE_ID,buildUrl:`${e.CI_PROJECT_URL}/pipelines/${e.CI_PIPELINE_ID}`,job:e.CI_JOB_ID,jobUrl:`${e.CI_PROJECT_URL}/-/jobs/${e.CI_JOB_ID}`,branch:r?e.CI_MERGE_REQUEST_TARGET_BRANCH_NAME:e.CI_COMMIT_REF_NAME,pr:t,isPr:r,prBranch:e.CI_MERGE_REQUEST_SOURCE_BRANCH_NAME,slug:e.CI_PROJECT_PATH,root:e.CI_PROJECT_DIR}}},pr={detect:({env:e})=>Boolean(e.JENKINS_URL),configuration({env:e,cwd:t}){const r=e.ghprbPullId||e.gitlabMergeRequestId||e.CHANGE_ID,n=Boolean(r),s=e.GIT_LOCAL_BRANCH||e.GIT_BRANCH||e.gitlabBranch||e.BRANCH_NAME;return{name:"Jenkins",service:"jenkins",commit:e.ghprbActualCommit||e.GIT_COMMIT||Kt({env:e,cwd:t}),branch:n?e.ghprbTargetBranch||e.gitlabTargetBranch:s,build:e.BUILD_NUMBER,buildUrl:e.BUILD_URL,root:e.WORKSPACE,pr:r,isPr:n,prBranch:n?e.ghprbSourceBranch||e.gitlabSourceBranch||s:void 0}}},fr={detect:({env:e})=>"true"===e.NETLIFY,configuration({env:e}){const t="true"===e.PULL_REQUEST;return{name:"Netlify",service:"netlify",commit:e.COMMIT_REF,build:e.DEPLOY_ID,buildUrl:`https://app.netlify.com/sites/${e.SITE_NAME}/deploys/${e.DEPLOY_ID}`,branch:t?void 0:e.HEAD,pr:e.REVIEW_ID,isPr:t,prBranch:t?e.HEAD:void 0,slug:e.REPOSITORY_URL.match(/[^/:]+\/[^/]+?$/)[0],root:e.PWD}}},hr={detect:({env:e})=>Boolean(e.DISTELLI_APPNAME),configuration:({env:e})=>({name:"Puppet",service:"puppet",build:e.DISTELLI_BUILDNUM,buildUrl:e.DISTELLI_RELEASE,commit:e.DISTELLI_RELREVISION,branch:e.DISTELLI_RELBRANCH,root:e.DISTELLI_INSTALLHOME})},gr={detect:({env:e})=>Boolean(e.SAILCI),configuration({env:e}){const t=e.SAIL_PULL_REQUEST_NUMBER,r=Boolean(t);return{name:"Sail CI",service:"sail",commit:e.SAIL_COMMIT_SHA,branch:r?void 0:e.SAIL_COMMIT_BRANCH,pr:t,isPr:r,slug:`${e.SAIL_REPO_OWNER}/${e.SAIL_REPO_NAME}`,root:e.SAIL_CLONE_DIR}}},mr={detect:({env:e})=>Boolean(e.SCREWDRIVER),configuration({env:e}){const t=e.SD_PULL_REQUEST,r=Boolean(t);return{name:"Screwdriver.cd",service:"screwdriver",branch:r?e.PR_BASE_BRANCH_NAME:e.GIT_BRANCH,prBranch:r?e.PR_BRANCH_NAME:void 0,commit:e.SD_BUILD_SHA,build:e.SD_BUILD_ID,buildUrl:e.SD_UI_BUILD_URL,job:e.SD_JOB_ID,pr:t,isPr:r,slug:e.SD_PIPELINE_NAME,root:e.SD_ROOT_DIR}}},yr={detect:({env:e})=>Boolean(e.SCRUTINIZER),configuration({env:e}){const t=e.SCRUTINIZER_PR_NUMBER,r=Boolean(t);return{name:"Scrutinizer",service:"scrutinizer",commit:e.SCRUTINIZER_SHA1,build:e.SCRUTINIZER_INSPECTION_UUID,branch:e.SCRUTINIZER_BRANCH,pr:t,isPr:r,prBranch:e.SCRUTINIZER_PR_SOURCE_BRANCH}}},br={detect:({env:e})=>Boolean(e.SEMAPHORE),configuration({env:e,cwd:t}){const r=e.SEMAPHORE_GIT_PR_NUMBER||e.PULL_REQUEST_NUMBER,n=Boolean(r);return{name:"Semaphore",service:"semaphore",commit:e.SEMAPHORE_GIT_SHA||Kt({env:e,cwd:t}),tag:e.SEMAPHORE_GIT_TAG_NAME,build:e.SEMAPHORE_JOB_ID||e.SEMAPHORE_BUILD_NUMBER,branch:e.SEMAPHORE_GIT_BRANCH||(n?void 0:e.BRANCH_NAME),pr:r,isPr:n,prBranch:e.SEMAPHORE_GIT_PR_BRANCH||(n?e.BRANCH_NAME:void 0),slug:e.SEMAPHORE_GIT_REPO_SLUG||e.SEMAPHORE_REPO_SLUG,root:e.SEMAPHORE_GIT_DIR||e.SEMAPHORE_PROJECT_DIR}}},wr={detect:({env:e})=>Boolean(e.SHIPPABLE),configuration({env:e}){const t="true"===e.IS_PULL_REQUEST?e.PULL_REQUEST:void 0,r=Boolean(t);return{name:"Shippable",service:"shippable",commit:e.COMMIT,tag:e.GIT_TAG_NAME,build:e.BUILD_NUMBER,buildUrl:e.BUILD_URL,branch:r?e.BASE_BRANCH:e.BRANCH,job:e.JOB_NUMBER,pr:t,isPr:r,prBranch:r?e.HEAD_BRANCH:void 0,slug:e.SHIPPABLE_REPO_SLUG,root:e.SHIPPABLE_BUILD_DIR}}},vr={};function Ir(){if(er)return vr;er=1,Object.defineProperty(vr,"__esModule",{value:!0}),vr.of=vr.PropertiesFile=void 0;var e,t=(e=v)&&e.__esModule?e:{default:e};class r{constructor(...e){this.objs={},e.length&&this.of.apply(this,e)}makeKeys(e){if(e&&0!==e.indexOf("#")){let t=["=",":"].map(t=>e.indexOf(t)).filter(e=>e>-1),r=Math.min(...t),n=e.substring(0,r).trim(),s=e.substring(r+1).trim();if(this.objs.hasOwnProperty(n))if(Array.isArray(this.objs[n]))this.objs[n].push(s);else{let e=this.objs[n];this.objs[n]=[e,s]}else{const e=s.replace(/"/g,'\\"').replace(/\\:/g,":").replace(/\\=/g,"=");this.objs[n]=unescape(JSON.parse('"'+e+'"'))}}}addFile(e){let r=t.default.readFileSync(e,"utf-8").split(/\r?\n/),n=this;for(let e=0;e<r.length;e++){let t=r[e];for(;"\\"===t.substring(t.length-1);)t=t.slice(0,-1),t+=r[e+1].trim(),e++;n.makeKeys(t)}}of(...e){for(let t=0;t<e.length;t++)this.addFile(e[t])}get(e,t){if(this.objs.hasOwnProperty(e)){if(Array.isArray(this.objs[e])){let t=[];for(let r=0;r<this.objs[e].length;r++)t[r]=this.interpolate(this.objs[e][r]);return t}return void 0===this.objs[e]?"":this.interpolate(this.objs[e])}return t}getLast(e,t){if(this.objs.hasOwnProperty(e)){if(Array.isArray(this.objs[e])){var r=this.objs[e].length;return this.interpolate(this.objs[e][r-1])}return void 0===this.objs[e]?"":this.interpolate(this.objs[e])}return t}getFirst(e,t){return this.objs.hasOwnProperty(e)?Array.isArray(this.objs[e])?this.interpolate(this.objs[e][0]):void 0===this.objs[e]?"":this.interpolate(this.objs[e]):t}getInt(e,t){let r=this.getLast(e);return r?parseInt(r,10):t}getFloat(e,t){let r=this.getLast(e);return r?parseFloat(r):t}getBoolean(e,t){let r=this.getLast(e);return r?!/^(false|0)$/i.test(n=r)&&!!n:t||!1;var n}set(e,t){this.objs[e]=t}interpolate(e){let t=this;return e.replace(/\\\\/g,"\\").replace(/\$\{([A-Za-z0-9\.\-\_]*)\}/g,function(e){return t.getLast(e.substring(2,e.length-1))})}getKeys(){let e=[];for(let t in this.objs)e.push(t);return e}getMatchingKeys(e){let t=[];for(let r in this.objs)-1!==r.search(e)&&t.push(r);return t}reset(){this.objs={}}}return vr.PropertiesFile=r,vr.of=function(...e){let t=new r;return t.of.apply(t,e),t},vr}var Tr=Ye(Ir()),_r={root:"teamcity.build.workingDir",branch:"teamcity.build.branch"},Er=e=>{try{return Tr.of(e)}catch{return}},Sr=({env:e,cwd:t})=>{const r=e.TEAMCITY_BUILD_PROPERTIES_FILE?Er(e.TEAMCITY_BUILD_PROPERTIES_FILE):void 0,n=r?r.get("teamcity.configuration.properties.file"):void 0,s=n?Er(n):n;return Object.fromEntries(Object.keys(_r).map(n=>[n,(r?r.get(_r[n]):void 0)||(s?s.get(_r[n]):void 0)||("branch"===n?Jt({env:e,cwd:t}):void 0)]))},xr={appveyor:Oe,azurePipelines:Me,bamboo:Fe,bitbucket:He,bitrise:Ge,buddy:We,buildkite:tr,circleci:rr,cirrus:sr,cloudflarePages:{detect:({env:e})=>"1"===e.CF_PAGES,configuration:({env:e})=>({name:"Cloudflare Pages",service:"cloudflarePages",commit:e.CF_PAGES_COMMIT_SHA,branch:e.CF_PAGES_BRANCH,root:e.PWD})},codebuild:or,codefresh:ir,codeship:{detect:({env:e})=>e.CI_NAME&&"codeship"===e.CI_NAME,configuration:({env:e})=>({name:"Codeship",service:"codeship",build:e.CI_BUILD_NUMBER,buildUrl:e.CI_BUILD_URL,commit:e.CI_COMMIT_ID,branch:e.CI_BRANCH,slug:e.CI_REPO_NAME})},drone:ar,github:ur,gitlab:dr,jenkins:pr,netlify:fr,puppet:hr,sail:gr,screwdriver:mr,scrutinizer:yr,semaphore:br,shippable:wr,teamcity:{detect:({env:e})=>Boolean(e.TEAMCITY_VERSION),configuration:({env:e,cwd:t})=>({name:"TeamCity",service:"teamcity",commit:e.BUILD_VCS_NUMBER,build:e.BUILD_NUMBER,slug:e.TEAMCITY_BUILDCONF_NAME,...Sr({env:e,cwd:t})})},travis:{detect:({env:e})=>Boolean(e.TRAVIS),configuration({env:e}){const t="false"===e.TRAVIS_PULL_REQUEST?void 0:e.TRAVIS_PULL_REQUEST,r=Boolean(t);return{name:"Travis CI",service:"travis",commit:e.TRAVIS_COMMIT,tag:e.TRAVIS_TAG,build:e.TRAVIS_BUILD_NUMBER,buildUrl:e.TRAVIS_BUILD_WEB_URL,branch:e.TRAVIS_BRANCH,job:e.TRAVIS_JOB_NUMBER,jobUrl:e.TRAVIS_JOB_WEB_URL,pr:t,isPr:r,prBranch:e.TRAVIS_PULL_REQUEST_BRANCH,slug:e.TRAVIS_REPO_SLUG,root:e.TRAVIS_BUILD_DIR}}},vela:{detect:({env:e})=>Boolean(e.VELA),configuration({env:e}){const t="pull_request"===e.VELA_BUILD_EVENT;return{name:"Vela",service:"vela",branch:t?e.VELA_PULL_REQUEST_TARGET:e.VELA_BUILD_BRANCH,commit:e.VELA_BUILD_COMMIT,tag:e.VELA_BUILD_TAG,build:e.VELA_BUILD_NUMBER,buildUrl:e.VELA_BUILD_LINK,job:void 0,jobUrl:void 0,isPr:t,pr:e.VELA_BUILD_PULL_REQUEST,prBranch:e.VELA_PULL_REQUEST_SOURCE,slug:e.VELA_REPO_FULL_NAME,root:e.VELA_BUILD_WORKSPACE}}},vercel:{detect:({env:e})=>Boolean(e.VERCEL)||Boolean(e.NOW_GITHUB_DEPLOYMENT),configuration({env:e}){const t="Vercel",r="vercel";return e.VERCEL?{name:t,service:r,commit:e.VERCEL_GIT_COMMIT_SHA,branch:e.VERCEL_GIT_COMMIT_REF,slug:`${e.VERCEL_GIT_REPO_OWNER}/${e.VERCEL_GIT_REPO_SLUG}`}:{name:t,service:r,commit:e.NOW_GITHUB_COMMIT_SHA,branch:e.NOW_GITHUB_COMMIT_REF,slug:`${e.NOW_GITHUB_ORG}/${e.NOW_GITHUB_REPO}`}}},wercker:{detect:({env:e})=>Boolean(e.WERCKER_MAIN_PIPELINE_STARTED),configuration:({env:e})=>({name:"Wercker",service:"wercker",commit:e.WERCKER_GIT_COMMIT,build:e.WERCKER_MAIN_PIPELINE_STARTED,buildUrl:e.WERCKER_RUN_URL,branch:e.WERCKER_GIT_BRANCH,slug:`${e.WERCKER_GIT_OWNER}/${e.WERCKER_GIT_REPOSITORY}`,root:e.WERCKER_ROOT})},woodpecker:{detect:({env:e})=>e.CI&&"woodpecker"===e.CI,configuration({env:e}){const t="pull_request"===e.CI_PIPELINE_EVENT;return{name:"Woodpecker CI",service:"woodpecker",commit:e.CI_COMMIT_SHA,tag:e.CI_COMMIT_TAG,build:e.CI_PIPELINE_NUMBER,buildUrl:e.CI_PIPELINE_URL,branch:t?e.CI_COMMIT_TARGET_BRANCH:e.CI_COMMIT_BRANCH,job:e.CI_STEP_NUMBER,jobUrl:e.CI_STEP_URL,pr:e.CI_COMMIT_PULL_REQUEST,isPr:t,prBranch:t?e.CI_COMMIT_SOURCE_BRANCH:void 0,slug:`${e.CI_REPO_OWNER}/${e.CI_REPO_NAME}`,root:e.CI_WORKSPACE}}},jetbrainsSpace:{detect:({env:e})=>Boolean(e.JB_SPACE_EXECUTION_NUMBER),configuration({env:e}){const t=e.JB_SPACE_PROJECT_KEY,r=e.JB_SPACE_GIT_REPOSITORY_NAME;return{name:"JetBrains Space",service:"jetbrainsSpace",commit:e.JB_SPACE_GIT_REVISION,build:e.JB_SPACE_EXECUTION_NUMBER,branch:je(e.JB_SPACE_GIT_BRANCH),slug:t&&r?`${t.toLowerCase()}/${r}`:void 0}}}},Ar=["test","bug","flake","ui_change","other"],kr=["captured","capture_failed","upload_failed"],Pr={bug:"Application code defect; behavior diverges from expected requirements.",flake:"Non-deterministic failure; timing, race conditions, or environmental variance causes inconsistent test results.",other:"External dependencies, environment, or infra issues outside test/app code.",test:"Test code is incorrect, out-of-date, or missing necessary setup.",ui_change:"Application UI intentionally changed; test expectations (screenshots, selectors, text assertions) are stale and need updating."},Cr=e=>Pr[e],Rr=function(){const e=process.env.STABLY_THEME;if("light"===e||"dark"===e)return e;const t=process.env.COLORFGBG;if(t){const e=t.split(";").at(-1);if(void 0!==e&&""!==e){const t=Number(e);if(Number.isInteger(t)&&t>=0&&t<=15)return t<=6||8===t?"dark":"light"}}return"dark"}(),Ur=function(){const e=process.env.FORCE_COLOR;if(void 0!==e){if("false"===e||"0"===e)return 0;if("true"===e||""===e)return 1;const t=Number(e);return Number.isNaN(t)?1:0===t?0:1===t?1:2===t?2:t>=3?3:1}if(void 0!==process.env.NO_COLOR)return 0;if(!process.stdout.isTTY)return 0;const t=process.env.COLORTERM?.toLowerCase(),r=process.env.TERM_PROGRAM?.toLowerCase(),n=process.env.TERM?.toLowerCase()??"";return"truecolor"===t||"24bit"===t||r&&["iterm.app","iterm2","hyper","wezterm","ghostty","kitty","alacritty","warp","rio"].some(e=>r.includes(e))||"vscode"===r?3:n.startsWith("screen")||n.startsWith("tmux")||n.includes("256color")||n.includes("256colours")||"apple_terminal"===r?2:1}(),Lr="dark"===Rr?{brand:{hex:"#2DD4BF",ansi256:86,ansi:"cyan"},userPrompt:{hex:"#67E8F9",ansi256:87,ansi:"cyan"},muted:{hex:"#D1D5DB",ansi256:252,ansi:"white"},subtle:{hex:"#9CA3AF",ansi256:248,ansi:"gray"},success:{hex:"#4ADE80",ansi256:78,ansi:"green"},error:{hex:"#F87171",ansi256:210,ansi:"red"},warning:{hex:"#FBBF24",ansi256:220,ansi:"yellow"},info:{hex:"#38BDF8",ansi256:75,ansi:"cyan"},accent:{hex:"#A78BFA",ansi256:141,ansi:"magenta"},link:{hex:"#38BDF8",ansi256:75,ansi:"cyan"},inlineCode:{hex:"#A78BFA",ansi256:141,ansi:"magenta"},codeBlock:{hex:"#D1D5DB",ansi256:252,ansi:"white"},fixTriage:{hex:"#FB923C",ansi256:215,ansi:"yellow"},fixDebug:{hex:"#C084FC",ansi256:177,ansi:"magenta"},fixValidation:{hex:"#60A5FA",ansi256:75,ansi:"blue"},fatalBg:{hex:"#991B1B",ansi256:88,ansi:"red"}}:{brand:{hex:"#0D9488",ansi256:30,ansi:"cyan"},userPrompt:{hex:"#0E7490",ansi256:30,ansi:"cyan"},muted:{hex:"#4B5563",ansi256:240,ansi:"gray"},subtle:{hex:"#808896",ansi256:244,ansi:"gray"},success:{hex:"#15803D",ansi256:28,ansi:"green"},error:{hex:"#B91C1C",ansi256:124,ansi:"red"},warning:{hex:"#B45309",ansi256:130,ansi:"yellow"},info:{hex:"#0369A1",ansi256:25,ansi:"blue"},accent:{hex:"#7C3AED",ansi256:98,ansi:"magenta"},link:{hex:"#0369A1",ansi256:25,ansi:"blue"},inlineCode:{hex:"#7C3AED",ansi256:98,ansi:"magenta"},codeBlock:{hex:"#374151",ansi256:239,ansi:"gray"},fixTriage:{hex:"#C2410C",ansi256:166,ansi:"red"},fixDebug:{hex:"#7E22CE",ansi256:91,ansi:"magenta"},fixValidation:{hex:"#1D4ED8",ansi256:26,ansi:"blue"},fatalBg:{hex:"#991B1B",ansi256:88,ansi:"red"}};function $r(e){const t=Lr[e];if(0!==Ur)return 1===Ur?t.ansi:t.hex}function Dr(e,t){if(0===Ur)return t;const r=Lr[e];if(Ur>=3){const[e,n,s]=Or(r.hex);return`[38;2;${e};${n};${s}m${t}[39m`}return 2===Ur?`[38;5;${r.ansi256}m${t}[39m`:function(e,t){const r=Br[e];return r?r(t):t}(r.ansi,t)}function Nr(e,t){if(0===Ur)return t;const r=Lr[e];if(Ur>=3){const[e,n,s]=Or(r.hex);return`[48;2;${e};${n};${s}m${t}[49m`}return 2===Ur?`[48;5;${r.ansi256}m${t}[49m`:function(e,t){const r=jr[e];return r?r(t):t}(r.ansi,t)}function Or(e){const t=e.startsWith("#")?e.slice(1):e;return[parseInt(t.slice(0,2),16),parseInt(t.slice(2,4),16),parseInt(t.slice(4,6),16)]}var Br={red:ne.red,green:ne.green,yellow:ne.yellow,blue:ne.blue,magenta:ne.magenta,cyan:ne.cyan,white:ne.white,gray:ne.gray},jr={red:ne.bgRed,green:ne.bgGreen,yellow:ne.bgYellow,blue:ne.bgBlue,magenta:ne.bgMagenta,cyan:ne.bgCyan,white:ne.bgWhite},Mr=class e{git;config;snapshotTreeHash;snapshotIndexPath;constructor(e){this.config=e,this.git=se({baseDir:e.workingDir,maxConcurrentProcesses:1})}static createLocal({workingDir:t}){return new e({mode:"local",workingDir:t})}static createCloud({workingDir:t,baseBranch:r}){return new e({mode:"cloud",workingDir:t,baseBranch:r})}async captureSnapshot(){if("local"!==this.config.mode)return;this.snapshotIndexPath=i(N(),`git-diff-tracker-${ie()}.index`),await this.git.env("GIT_INDEX_FILE",this.snapshotIndexPath).add(["-A"]);const e=await this.git.env("GIT_INDEX_FILE",this.snapshotIndexPath).raw(["write-tree"]);this.snapshotTreeHash=e.trim()}async computeDiff(){return"local"===this.config.mode?this.computeLocalDiff():this.computeCloudDiff()}async computeLocalDiff(){if(!this.snapshotTreeHash)throw new Error("No snapshot captured. Call captureSnapshot() first.");const e=i(N(),`git-diff-tracker-${ie()}.index`);try{await this.git.env("GIT_INDEX_FILE",e).add(["-A"]);const t=(await this.git.env("GIT_INDEX_FILE",e).raw(["write-tree"])).trim();return await this.git.raw(["diff-tree","-p","--no-color",this.snapshotTreeHash,t])}finally{await Fr(e)}}async computeCloudDiff(){if("cloud"!==this.config.mode)throw new Error("computeCloudDiff called but mode is not cloud");const{baseBranch:e}=this.config;return await this.git.revparse([`origin/${e}`]).then(()=>!0).catch(()=>!1)||await this.git.fetch(["origin",`+${e}:refs/remotes/origin/${e}`,"--depth","1","--quiet"]).catch(e=>{console.error("[git-diff-tracker] Failed to fetch base branch:",e)}),await this.git.diff([`origin/${e}`])}async cleanup(){this.snapshotIndexPath&&(await Fr(this.snapshotIndexPath),this.snapshotIndexPath=void 0),this.snapshotTreeHash=void 0}};async function Fr(e){try{await J(e)}catch{}}var Hr="x-stably-org-id",Gr={bodySerializer:e=>JSON.stringify(e,(e,t)=>"bigint"==typeof t?t.toString():t)},Wr=({allowReserved:e,explode:t,name:r,style:n,value:s})=>{if(!t){const t=(e?s:s.map(e=>encodeURIComponent(e))).join((e=>{switch(e){case"form":default:return",";case"pipeDelimited":return"|";case"spaceDelimited":return"%20"}})(n));switch(n){case"label":return`.${t}`;case"matrix":return`;${r}=${t}`;case"simple":return t;default:return`${r}=${t}`}}const o=(e=>{switch(e){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}})(n),i=s.map(t=>"label"===n||"simple"===n?e?t:encodeURIComponent(t):Vr({allowReserved:e,name:r,value:t})).join(o);return"label"===n||"matrix"===n?o+i:i},Vr=({allowReserved:e,name:t,value:r})=>{if(null==r)return"";if("object"==typeof r)throw new Error("Deeply-nested arrays/objects arenβt supported. Provide your own `querySerializer()` to handle these.");return`${t}=${e?r:encodeURIComponent(r)}`},Yr=({allowReserved:e,explode:t,name:r,style:n,value:s,valueOnly:o})=>{if(s instanceof Date)return o?s.toISOString():`${r}=${s.toISOString()}`;if("deepObject"!==n&&!t){let t=[];Object.entries(s).forEach(([r,n])=>{t=[...t,r,e?n:encodeURIComponent(n)]});const o=t.join(",");switch(n){case"form":return`${r}=${o}`;case"label":return`.${o}`;case"matrix":return`;${r}=${o}`;default:return o}}const i=(e=>{switch(e){case"label":return".";case"matrix":return";";case"simple":return",";default:return"&"}})(n),a=Object.entries(s).map(([t,s])=>Vr({allowReserved:e,name:"deepObject"===n?`${r}[${t}]`:t,value:s})).join(i);return"label"===n||"matrix"===n?i+a:a},zr=/\{[^{}]+\}/g;function qr(e){const t=void 0!==e.body;return t&&e.bodySerializer?"serializedBody"in e?void 0!==e.serializedBody&&""!==e.serializedBody?e.serializedBody:null:""!==e.body?e.body:null:t?e.body:void 0}var Kr,Jr=async(e,t)=>{const r="function"==typeof t?await t(e):t;if(r)return"bearer"===e.scheme?`Bearer ${r}`:"basic"===e.scheme?`Basic ${btoa(r)}`:r},Xr=({parameters:e={},...t}={})=>r=>{const n=[];if(r&&"object"==typeof r)for(const s in r){const o=r[s];if(null==o)continue;const i=e[s]||t;if(Array.isArray(o)){const e=Wr({allowReserved:i.allowReserved,explode:!0,name:s,style:"form",value:o,...i.array});e&&n.push(e)}else if("object"==typeof o){const e=Yr({allowReserved:i.allowReserved,explode:!0,name:s,style:"deepObject",value:o,...i.object});e&&n.push(e)}else{const e=Vr({allowReserved:i.allowReserved,name:s,value:o});e&&n.push(e)}}return n.join("&")},Qr=(e,t)=>!!t&&!!(e.headers.has(t)||e.query?.[t]||e.headers.get("Cookie")?.includes(`${t}=`)),Zr=e=>(({baseUrl:e,path:t,query:r,querySerializer:n,url:s})=>{let o=(e??"")+(s.startsWith("/")?s:`/${s}`);t&&(o=(({path:e,url:t})=>{let r=t;const n=t.match(zr);if(n)for(const t of n){let n=!1,s=t.substring(1,t.length-1),o="simple";s.endsWith("*")&&(n=!0,s=s.substring(0,s.length-1)),s.startsWith(".")?(s=s.substring(1),o="label"):s.startsWith(";")&&(s=s.substring(1),o="matrix");const i=e[s];if(null==i)continue;if(Array.isArray(i)){r=r.replace(t,Wr({explode:n,name:s,style:o,value:i}));continue}if("object"==typeof i){r=r.replace(t,Yr({explode:n,name:s,style:o,value:i,valueOnly:!0}));continue}if("matrix"===o){r=r.replace(t,`;${Vr({name:s,value:i})}`);continue}const a=encodeURIComponent("label"===o?`.${i}`:i);r=r.replace(t,a)}return r})({path:t,url:o}));let i=r?n(r):"";return i.startsWith("?")&&(i=i.substring(1)),i&&(o+=`?${i}`),o})({baseUrl:e.baseUrl,path:e.path,query:e.query,querySerializer:"function"==typeof e.querySerializer?e.querySerializer:Xr(e.querySerializer),url:e.url}),en=(e,t)=>{const r={...e,...t};return r.baseUrl?.endsWith("/")&&(r.baseUrl=r.baseUrl.substring(0,r.baseUrl.length-1)),r.headers=rn(e.headers,t.headers),r},tn=e=>{const t=[];return e.forEach((e,r)=>{t.push([r,e])}),t},rn=(...e)=>{const t=new Headers;for(const r of e){if(!r)continue;const e=r instanceof Headers?tn(r):Object.entries(r);for(const[r,n]of e)if(null===n)t.delete(r);else if(Array.isArray(n))for(const e of n)t.append(r,e);else void 0!==n&&t.set(r,"object"==typeof n?JSON.stringify(n):n)}return t},nn=class{fns=[];clear(){this.fns=[]}eject(e){const t=this.getInterceptorIndex(e);this.fns[t]&&(this.fns[t]=null)}exists(e){const t=this.getInterceptorIndex(e);return Boolean(this.fns[t])}getInterceptorIndex(e){return"number"==typeof e?this.fns[e]?e:-1:this.fns.indexOf(e)}update(e,t){const r=this.getInterceptorIndex(e);return!!this.fns[r]&&(this.fns[r]=t,e)}use(e){return this.fns.push(e),this.fns.length-1}},sn=Xr({allowReserved:!1,array:{explode:!0,style:"form"},object:{explode:!0,style:"deepObject"}}),on={"Content-Type":"application/json"},an=(e={})=>({...Gr,headers:on,parseAs:"auto",querySerializer:sn,...e}),cn=(e={})=>{let t=en(an(),e);const r=()=>({...t}),n={error:new nn,request:new nn,response:new nn},s=async e=>{const r={...t,...e,fetch:e.fetch??t.fetch??globalThis.fetch,headers:rn(t.headers,e.headers),serializedBody:void 0};return r.security&&await(async({security:e,...t})=>{for(const r of e){if(Qr(t,r.name))continue;const e=await Jr(r,t.auth);if(!e)continue;const n=r.name??"Authorization";switch(r.in){case"query":t.query||(t.query={}),t.query[n]=e;break;case"cookie":t.headers.append("Cookie",`${n}=${e}`);break;default:t.headers.set(n,e)}}})({...r,security:r.security}),r.requestValidator&&await r.requestValidator(r),void 0!==r.body&&r.bodySerializer&&(r.serializedBody=r.bodySerializer(r.body)),void 0!==r.body&&""!==r.serializedBody||r.headers.delete("Content-Type"),{opts:r,url:Zr(r)}},o=async e=>{const{opts:t,url:r}=await s(e),o={redirect:"follow",...t,body:qr(t)};let i=new Request(r,o);for(const e of n.request.fns)e&&(i=await e(i,t));const a=t.fetch;let c=await a(i);for(const e of n.response.fns)e&&(c=await e(c,i,t));const l={request:i,response:c};if(c.ok){const e=("auto"===t.parseAs?(e=>{if(!e)return"stream";const t=e.split(";")[0]?.trim();return t?t.startsWith("application/json")||t.endsWith("+json")?"json":"multipart/form-data"===t?"formData":["application/","audio/","image/","video/"].some(e=>t.startsWith(e))?"blob":t.startsWith("text/")?"text":void 0:void 0})(c.headers.get("Content-Type")):t.parseAs)??"json";if(204===c.status||"0"===c.headers.get("Content-Length")){let r;switch(e){case"arrayBuffer":case"blob":case"text":r=await c[e]();break;case"formData":r=new FormData;break;case"stream":r=c.body;break;default:r={}}return"data"===t.responseStyle?r:{data:r,...l}}let r;switch(e){case"arrayBuffer":case"blob":case"formData":case"json":case"text":r=await c[e]();break;case"stream":return"data"===t.responseStyle?c.body:{data:c.body,...l}}return"json"===e&&(t.responseValidator&&await t.responseValidator(r),t.responseTransformer&&(r=await t.responseTransformer(r))),"data"===t.responseStyle?r:{data:r,...l}}const u=await c.text();let d;try{d=JSON.parse(u)}catch{}const p=d??u;let f=p;for(const e of n.error.fns)e&&(f=await e(p,c,i,t));if(f=f||{},t.throwOnError)throw f;return"data"===t.responseStyle?void 0:{error:f,...l}},i=e=>t=>o({...t,method:e}),a=e=>async t=>{const{opts:r,url:o}=await s(t);return(({onRequest:e,onSseError:t,onSseEvent:r,responseTransformer:n,responseValidator:s,sseDefaultRetryDelay:o,sseMaxRetryAttempts:i,sseMaxRetryDelay:a,sseSleepFn:c,url:l,...u})=>{let d;const p=c??(e=>new Promise(t=>setTimeout(t,e)));return{stream:async function*(){let c=o??3e3,f=0;const h=u.signal??(new AbortController).signal;for(;!h.aborted;){f++;const o=u.headers instanceof Headers?u.headers:new Headers(u.headers);void 0!==d&&o.set("Last-Event-ID",d);try{const t={redirect:"follow",...u,body:u.serializedBody,headers:o,signal:h};let i=new Request(l,t);e&&(i=await e(l,t));const a=u.fetch??globalThis.fetch,p=await a(i);if(!p.ok)throw new Error(`SSE failed: ${p.status} ${p.statusText}`);if(!p.body)throw new Error("No body in SSE response");const f=p.body.pipeThrough(new TextDecoderStream).getReader();let g="";const m=()=>{try{f.cancel()}catch{}};h.addEventListener("abort",m);try{for(;;){const{done:e,value:t}=await f.read();if(e)break;g+=t;const o=g.split("\n\n");g=o.pop()??"";for(const e of o){const t=e.split("\n"),o=[];let i,a;for(const e of t)if(e.startsWith("data:"))o.push(e.replace(/^data:\s*/,""));else if(e.startsWith("event:"))i=e.replace(/^event:\s*/,"");else if(e.startsWith("id:"))d=e.replace(/^id:\s*/,"");else if(e.startsWith("retry:")){const t=Number.parseInt(e.replace(/^retry:\s*/,""),10);Number.isNaN(t)||(c=t)}let l=!1;if(o.length){const e=o.join("\n");try{a=JSON.parse(e),l=!0}catch{a=e}}l&&(s&&await s(a),n&&(a=await n(a))),r?.({data:a,event:i,id:d,retry:c}),o.length&&(yield a)}}}finally{h.removeEventListener("abort",m),f.releaseLock()}break}catch(e){if(t?.(e),void 0!==i&&f>=i)break;const r=Math.min(c*2**(f-1),a??3e4);await p(r)}}}()}})({...r,body:r.body,headers:r.headers,method:e,onRequest:async(e,t)=>{let s=new Request(e,t);for(const e of n.request.fns)e&&(s=await e(s,r));return s},url:o})};return{buildUrl:Zr,connect:i("CONNECT"),delete:i("DELETE"),get:i("GET"),getConfig:r,head:i("HEAD"),interceptors:n,options:i("OPTIONS"),patch:i("PATCH"),post:i("POST"),put:i("PUT"),request:o,setConfig:e=>(t=en(t,e),r()),sse:{connect:a("CONNECT"),delete:a("DELETE"),get:a("GET"),head:a("HEAD"),options:a("OPTIONS"),patch:a("PATCH"),post:a("POST"),put:a("PUT"),trace:a("TRACE")},trace:i("TRACE")}},ln=cn(an({baseUrl:"https://api.stably.ai"})),un=e=>(e.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs",...e}),dn=e=>(e.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}",...e}),pn="4.12.26",fn=process.env.STABLY_API_URL||"https://api.stably.ai",hn=e=>{const t=new URL(e);return t.protocol="http:"===t.protocol?"ws:":"wss:",t},gn=process.env.AUTH_URL||"https://auth.stably.ai",mn=process.env.AUTH_CLIENT_ID||"288007877071cce81f269428ea78653a",yn=process.env.AI_PROXY_URL||"https://ai-proxy.stably.ai",bn=process.env.STABLY_AUTOHEAL_WS_URL||new URL("/autoheal",hn(fn)).toString(),wn=process.env.STABLY_CREATE_PROGRESS_WS_URL||new URL("/create-progress",hn(fn)).toString(),vn="http://localhost:9876/auth/callback",In=()=>Kr||(Kr=cn(an({baseUrl:fn,headers:{"X-STABLY-CLI-VERSION":pn,"X-STABLY-SOURCE":"cli"}}))),Tn=async(e,t)=>{const r=await(n={body:{accessToken:e,orgId:t},client:In()},(n.client??ln).post({url:"/internal/v1/cli/exchange-token",...n,headers:{"Content-Type":"application/json",...n.headers}}));var n;if(401===r.response.status)throw new Error("Invalid or expired access token");if(403===r.response.status)throw new Error("You do not have access to this organization");if(r.error)throw new Error(`Failed to exchange token: ${r.response.status}`);return r.data},_n=he.object({org_id:he.string(),org_name:he.string()}),En=he.object({email:he.string(),org_id_to_org_member_info:he.record(he.string(),_n).optional(),org_member_info:_n.optional(),user_id:he.string()});he.object({email:he.string(),firstName:he.string().optional(),lastName:he.string().optional(),organizations:he.array(he.object({id:he.string(),name:he.string()})),userId:he.string()});var Sn,xn=e=>{const t=e.split(".");if(3!==t.length)throw new Error("Invalid JWT format");const r=t[1].replace(/-/g,"+").replace(/_/g,"/"),n=Buffer.from(r,"base64").toString("utf-8");return JSON.parse(n)},An=e=>{try{const t=En.parse(xn(e)),r=t.org_id_to_org_member_info?Object.entries(t.org_id_to_org_member_info).map(([e,t])=>({id:e,name:t.org_name})):t.org_member_info?[{id:t.org_member_info.org_id,name:t.org_member_info.org_name}]:[];return{email:t.email,organizations:r,userId:t.user_id}}catch(e){throw new Error(`Failed to decode token: ${e instanceof Error?e.message:"Unknown error"}`)}},kn=async(e,t)=>{let r=e;const{root:s}=n.parse(r);for(;r!==s;){const e=n.join(r,t);try{return await X(e),e}catch{r=n.dirname(r)}}},Pn=n.join(D.homedir(),".stably"),Cn=n.join(Pn,"auth.json"),Rn=".stably",Un="project.json",Ln=fe.object({accessToken:fe.string(),expiresAt:fe.number(),idToken:fe.string().optional(),refreshToken:fe.string()}),$n=fe.object({orgId:fe.string(),orgName:fe.string(),projectId:fe.string(),projectName:fe.string()}),Dn=async()=>{try{const e=await z(Cn,"utf-8");return Ln.parse(JSON.parse(e))}catch{return}},Nn=async e=>{await q(Pn,{recursive:!0}),await K(Cn,JSON.stringify(e,null,2),{mode:384})},On=async()=>{try{await J(Cn)}catch{}},Bn=async()=>{try{const e=await kn(process.cwd(),Rn);if(!e)return;const t=n.join(e,Un),r=await z(t,"utf-8");return $n.parse(JSON.parse(r))}catch{return}},jn=async()=>{try{const e=await kn(process.cwd(),Rn);e&&await J(n.join(e,Un))}catch{}},Mn=e=>Date.now()>=e.expiresAt-3e5,Fn=async e=>{const t=new URLSearchParams({client_id:mn,grant_type:"refresh_token",refresh_token:e}),r=await fetch(`${gn}/propelauth/oauth/token`,{body:t.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST"});if(!r.ok)throw new Error(`Token refresh failed: ${r.status}`);const n=await r.json();return{accessToken:n.access_token,expiresAt:Date.now()+1e3*n.expires_in,refreshToken:n.refresh_token}},Hn=e=>`\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authentication Failed Stably CLI</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #000;\n color: #fafafa;\n }\n .container {\n text-align: center;\n padding: 48px;\n max-width: 400px;\n }\n .icon {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #ef4444;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .icon svg { width: 24px; height: 24px; }\n .title {\n font-size: 24px;\n font-weight: 600;\n margin: 0 0 8px;\n letter-spacing: -0.5px;\n }\n .subtitle {\n color: #888;\n font-size: 14px;\n margin: 0 0 32px;\n line-height: 1.5;\n }\n .error-box {\n background: rgba(239, 68, 68, 0.1);\n border: 1px solid rgba(239, 68, 68, 0.3);\n border-radius: 8px;\n padding: 16px;\n margin-bottom: 24px;\n }\n .error-label {\n font-size: 11px;\n font-weight: 600;\n color: #ef4444;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n margin-bottom: 8px;\n }\n .error-message {\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n font-size: 13px;\n color: #fafafa;\n word-break: break-word;\n }\n .hint {\n color: #666;\n font-size: 13px;\n }\n .hint code {\n background: #111;\n border: 1px solid #333;\n border-radius: 4px;\n padding: 2px 6px;\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n font-size: 12px;\n color: #888;\n }\n .brand {\n margin-top: 32px;\n font-size: 12px;\n color: #444;\n letter-spacing: 0.5px;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="icon">\n <svg fill="none" stroke="#000" stroke-width="3" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>\n </svg>\n </div>\n <h1 class="title">Authentication Failed</h1>\n <p class="subtitle">Something went wrong during login.</p>\n <div class="error-box">\n <div class="error-label">Error</div>\n <div class="error-message">${e}</div>\n </div>\n <p class="hint">Run <code>stably login</code> to try again.</p>\n <div class="brand">STABLY</div>\n </div>\n</body>\n</html>\n`,Gn=(e,t,r)=>{e.writeHead(t,{"Content-Type":"text/html"}),e.end(r)},Wn=(e,t)=>{const r=new URLSearchParams({client_id:mn,code_challenge:e,code_challenge_method:"S256",redirect_uri:vn,response_type:"code",state:t});return`${gn}/propelauth/oauth/authorize?${r.toString()}`},Vn=async e=>{const t=le();let r;t.start("Loading user info...");try{r=An(e.accessToken),t.stop(Dr("success",`β Logged in as ${Dr("info",r.email)}`))}catch(e){t.stop(Dr("error","β Failed to load user info"));const r=e instanceof Error?e.message:"Unknown error";return ae.error(r),{success:!1}}const s=await(async e=>{if(0===e.length)return void ae.error("You don't belong to any organizations.");if(1===e.length)return ae.info(`Using organization: ${Dr("info",e[0].name)}`),e[0];if(!process.stdin.isTTY)return ae.info(`Auto-selecting organization: ${Dr("info",e[0].name)}`),e[0];const t=await de({message:"Select an organization",options:[...e].sort((e,t)=>e.name.localeCompare(t.name)).map(e=>({label:e.name,value:e.id}))});return pe(t)?void 0:e.find(e=>e.id===t)})(r.organizations);if(!s)return ae.warn("Organization selection cancelled."),{success:!1};let o;t.start("Getting org credentials...");try{const r=await Tn(e.accessToken,s.id);o={accessToken:r.accessToken,expiresAt:Date.now()+1e3*r.expiresInSeconds,idToken:e.idToken,refreshToken:e.refreshToken},t.stop(Dr("success","β Credentials obtained"))}catch(e){t.stop(Dr("error","β Failed to get org credentials"));const r=e instanceof Error?e.message:"Unknown error";return ae.error(r),{success:!1}}const i=await(async(e,t)=>{const r=le();let n;r.start("Loading projects...");try{n=await(async({accessToken:e,orgId:t})=>{const r=await(n={auth:e,client:In(),path:{orgId:t}},(n.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/orgs/{orgId}/projects",...n}));var n;if(401===r.response.status)throw new Error("Invalid or expired access token");if(403===r.response.status)throw new Error("You do not have access to this organization");if(r.error)throw new Error(`Failed to list projects: ${r.response.status}`);return r.data.projects})({accessToken:e,orgId:t}),r.stop(Dr("success","β Projects loaded"))}catch(e){r.stop(Dr("error","β Failed to load projects"));const t=e instanceof Error?e.message:"Unknown error";return void ae.error(t)}if(0===n.length)return ae.error("No projects found in this organization."),void ae.info(`Create a project at ${ne.underline(Dr("link","https://app.stably.ai"))}`);if(1===n.length)return ae.info(`Using project: ${Dr("info",n[0].name)}`),n[0];if(!process.stdin.isTTY)return ae.info(`Auto-selecting project: ${Dr("info",n[0].name)}`),n[0];const s=await de({message:"Select a project",options:n.map(e=>({label:e.name,value:e.id}))});return pe(s)?void 0:n.find(e=>e.id===s)})(o.accessToken,s.id);return i?(await(async e=>{const t=n.join(process.cwd(),Rn),r=n.join(t,Un);await q(t,{recursive:!0}),await K(r,JSON.stringify(e,null,2)),await(async e=>{const t=n.join(e,".gitignore"),r="# Stably CLI (only docs/ are tracked)\n.stably/*\n!.stably/docs/";try{const e=await z(t,"utf-8"),n=e.split("\n").map(e=>e.trim());if(n.includes(".stably/*")&&n.includes("!.stably/docs/"))return;const s=/^# Stably CLI\n\.stably\/?$/m,o=/^\.stably\/?$/m;if(s.test(e)){const n=e.replace(s,`\n${r}\n`);await K(t,n)}else if(o.test(e)){const n=e.replace(o,`\n${r}\n`);await K(t,n)}else await ee(t,`\n${r}\n`)}catch{await K(t,`${r}\n`)}})(process.cwd())})({orgId:s.id,orgName:s.name,projectId:i.id,projectName:i.name}),ae.info(ne.dim("Linked this directory to your Stably project.")),{scopedTokens:o,success:!0}):(ae.warn("Project selection cancelled."),{success:!1})},Yn=async()=>{if(gs())return ae.warn(`Environment variables ${Dr("info","STABLY_API_KEY")} and ${Dr("info","STABLY_PROJECT_ID")} are set.`),ae.warn("These will be used for authentication instead of OAuth login."),ae.warn("To use OAuth login, unset these environment variables first."),void ce(Dr("warning","Login skipped - using environment variable authentication."));const e=await Dn();if(e){if(!Mn(e)){if(await Bn())return void ce(Dr("warning","You are already logged in. Run `stably logout` first to log out."));ae.info("You are logged in but haven't selected a project yet.");const t=await Vn(e);return void(t.success?(await Nn(t.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):ce(Dr("warning","Setup incomplete. Run `stably login` to try again.")))}const t=le();t.start("Refreshing session...");try{const r=await Fn(e.refreshToken);t.stop(Dr("success","β Session refreshed"));const n=await Bn();if(n){t.start("Getting org credentials...");try{const e=await Tn(r.accessToken,n.orgId),s={accessToken:e.accessToken,expiresAt:Date.now()+1e3*e.expiresInSeconds,idToken:r.idToken,refreshToken:r.refreshToken};await Nn(s),t.stop(Dr("success","β Credentials obtained")),ce(Dr("success","Login successful"))}catch{await Nn(r),t.stop(Dr("warning","Using full credentials")),ce(Dr("success","Login successful"))}}else{const e=await Vn(r);e.success?(await Nn(e.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):ce(Dr("warning","Setup incomplete. Run `stably login` to try again."))}return}catch{t.stop(Dr("warning","Session expired, proceeding with fresh login...")),await On(),await jn()}}const{authorizeUrl:t,serverReady:r,waitForCallback:n}=(()=>{const{authorizeUrl:e,codeVerifier:t,state:r}=(()=>{const e=oe.randomBytes(32).toString("base64url"),t=(r=e,oe.createHash("sha256").update(r).digest("base64url"));var r;const n=oe.randomBytes(16).toString("base64url");return{authorizeUrl:Wn(t,n),codeVerifier:e,state:n}})(),{ready:n,result:s}=(e=>{let t,r;return{ready:new Promise((e,n)=>{t=e,r=n}),result:new Promise((n,s)=>{const o=setTimeout(()=>{a.close(),n({error:"Login timed out",success:!1})},3e5),i=()=>{clearTimeout(o)},a=me.createServer((t,r)=>{const s=new $(t.url||"","http://localhost:9876");if("/auth/callback"!==s.pathname)return r.writeHead(404),void r.end("Not found");const o=s.searchParams.get("code"),c=s.searchParams.get("state"),l=s.searchParams.get("error");return l?(Gn(r,400,Hn(l)),i(),a.close(),void n({error:l,success:!1})):o&&c?c!==e?(Gn(r,400,Hn("Invalid state parameter (possible CSRF attack)")),i(),a.close(),void n({error:"State mismatch",success:!1})):(Gn(r,200,'\n<!DOCTYPE html>\n<html>\n<head>\n <title>Authenticated Stably CLI</title>\n <style>\n * { box-sizing: border-box; }\n body {\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n margin: 0;\n background: #000;\n color: #fafafa;\n }\n .container {\n text-align: center;\n padding: 48px;\n max-width: 400px;\n }\n .icon {\n width: 48px;\n height: 48px;\n border-radius: 50%;\n background: #22c55e;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0 auto 24px;\n }\n .icon svg { width: 24px; height: 24px; }\n .title {\n font-size: 24px;\n font-weight: 600;\n margin: 0 0 8px;\n letter-spacing: -0.5px;\n }\n .subtitle {\n color: #888;\n font-size: 14px;\n margin: 0 0 32px;\n line-height: 1.5;\n }\n .terminal {\n background: #111;\n border: 1px solid #333;\n border-radius: 8px;\n padding: 16px;\n text-align: left;\n font-family: \'SF Mono\', \'Fira Code\', \'Consolas\', monospace;\n font-size: 13px;\n }\n .terminal-header {\n display: flex;\n gap: 6px;\n margin-bottom: 12px;\n }\n .terminal-dot {\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: #333;\n }\n .terminal-line {\n color: #888;\n }\n .terminal-line .prompt { color: #888; }\n .terminal-line .cmd { color: #fafafa; }\n .terminal-line.success { color: #22c55e; }\n .brand {\n margin-top: 32px;\n font-size: 12px;\n color: #444;\n letter-spacing: 0.5px;\n }\n </style>\n</head>\n<body>\n <div class="container">\n <div class="icon">\n <svg fill="none" stroke="#000" stroke-width="3" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7"/>\n </svg>\n </div>\n <h1 class="title">Authenticated</h1>\n <p class="subtitle">You can close this tab and return to your terminal.</p>\n <div class="terminal">\n <div class="terminal-header">\n <div class="terminal-dot"></div>\n <div class="terminal-dot"></div>\n <div class="terminal-dot"></div>\n </div>\n <div class="terminal-line"><span class="prompt">$</span> <span class="cmd">stably login</span></div>\n <div class="terminal-line success">Logged in successfully</div>\n </div>\n <div class="brand">STABLY</div>\n </div>\n</body>\n</html>\n'),i(),a.close(),void n({code:o,state:c,success:!0})):(Gn(r,400,Hn("Missing code or state parameter")),i(),a.close(),void n({error:"Missing code or state parameter",success:!1}))});a.on("error",e=>{if(i(),"EADDRINUSE"===e.code){const e=new Error("Port 9876 is already in use. Please close the application using it and try again.");return r(e),void s(e)}const t=new Error(`Failed to start callback server: ${e.message}`);r(t),s(t)}),a.listen(9876,()=>{t()})})}})(r);return{authorizeUrl:e,serverReady:n,waitForCallback:async()=>{const e=await s;if(!e.success)throw new Error(e.error);return(async(e,t)=>{const r=new URLSearchParams({client_id:mn,code:e,code_verifier:t,grant_type:"authorization_code",redirect_uri:vn}),n=await fetch(`${gn}/propelauth/oauth/token`,{body:r.toString(),headers:{"Content-Type":"application/x-www-form-urlencoded"},method:"POST"});if(!n.ok){const e=await n.text();throw new Error(`Token exchange failed: ${n.status} ${e}`)}const s=await n.json();return{accessToken:s.access_token,expiresAt:Date.now()+1e3*s.expires_in,idToken:s.id_token,refreshToken:s.refresh_token}})(e.code,t)}}})();await r,ae.info("Opening browser for authentication..."),ae.info(ne.dim("If browser doesn't open, visit:")),ae.info(`]8;;${t}${ne.underline(Dr("link",t))}]8;;`);try{await ge(t)}catch{ae.warn("Could not open browser automatically. Please open the URL above manually.")}const s=le();let o;s.start("Waiting for authentication...");try{o=await n(),s.stop(Dr("success","β Authentication successful"))}catch(e){s.stop(Dr("error","β Authentication failed"));const t=e instanceof Error?e.message:"Unknown error";ce(Dr("error",`Login failed: ${t}`)),process.exit(1)}const i=await Vn(o);i.success?(await Nn(i.scopedTokens),ce(Dr("success","Setup complete! You can now use Stably CLI."))):(ce(Dr("warning","Setup incomplete. Run `stably login` to try again.")),process.exit(1))},zn={fatal:60,error:50,warn:40,info:30,debug:20,trace:10},qn=new Set(["help","login","logout","whoami","tunnel","create","fix","internal-fix-run","init","upgrade","test","show-report","codegen"]),Kn=(new Date).toISOString().split("T")[0],Jn=(()=>{const e=[n.join(D.tmpdir(),"stably-logs",Kn),n.join(D.homedir(),".stably","logs",Kn)];for(const t of e)try{return v.mkdirSync(t,{recursive:!0}),t}catch{}return null})(),Xn=process.argv.includes("--verbose")||process.argv.includes("-v"),Qn=process.env.STABLY_LOG_LEVEL?.toLowerCase(),Zn=Xn?"debug":void 0!==(Sn=Qn)&&Sn in zn?Qn:"warn",es=zn[Zn],ts=null,rs=null,ns=null,ss=[],os=!1,is=e=>{if(!os){if(!(ts=(e=>{if(!Jn)return null;const t=(()=>{const e=new Date;return[e.getHours().toString().padStart(2,"0"),e.getMinutes().toString().padStart(2,"0"),e.getSeconds().toString().padStart(2,"0")].join("-")})(),r=((e,t=100)=>e.replace(/[/\\:*?"<>|]/g,"-").replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-_]/g,"").replace(/-+/g,"-").replace(/^-+|-+$/g,"").slice(0,t).toLowerCase()||"session")(e);return n.join(Jn,`${t}-${r}.log`)})(e)))return ss=[],void(os=!0);(e=>{const t=["","=".repeat(60),"Stably CLI Debug Log",`Version: ${pn}`,`Generated: ${(new Date).toISOString()}`,`Node: ${process.version}`,`Platform: ${process.platform} ${D.release()}`,`CWD: ${process.cwd()}`,`Args: ${process.argv.slice(2).join(" ")}`,`Log Level (console): ${Zn}`,"=".repeat(60),""].join("\n");e.write(t)})(rs=new be({dest:ts,minLength:4096,sync:!1,append:!0})),ns=ye({level:"debug",timestamp:ye.stdTimeFunctions.isoTime,base:{version:pn}},rs);for(const{level:e,msg:t,context:r}of ss)r?ns[e](r,t):ns[e](t);ss=[],os=!0,Xn&&process.stderr.write(`${ne.dim(`Debug log: ${ts}`)}\n\n`)}},as=(()=>{const e=process.argv.slice(2).find(e=>!e.startsWith("-"));return e&&qn.has(e)?e:null})();as&&is(as);var cs=e=>(t,r)=>{if(ns?r?ns[e](r,t):ns[e](t):os||ss.push({level:e,msg:t,context:r}),(e=>zn[e]>=es)(e)){const r=((e,t)=>`${{fatal:Nr("fatalBg",ne.white(ne.bold(" FATAL "))),error:Dr("error","error"),warn:Dr("warning","warn"),info:Dr("info","info"),debug:ne.dim("debug"),trace:ne.dim("trace")}[e]} ${t}`)(e,t);process.stderr.write(`${r}\n`)}},ls={fatal:cs("fatal"),error:cs("error"),warn:cs("warn"),info:cs("info"),debug:cs("debug"),trace:cs("trace"),initSession:e=>{os||is(e)},getLogFilePath:()=>ts,flush:()=>{if(rs)try{rs.flushSync()}catch{}},printLogFileInfo:()=>{ts&&(process.stderr.write(`\n${ne.dim("Debug log written to:")}\n`),process.stderr.write(` ${Dr("info",ts)}\n`),process.stderr.write(`${ne.dim("Share this file with support for assistance.")}\n`))},getPinoLogger:()=>ns};setInterval(()=>{ls.flush()},3e4).unref(),process.on("beforeExit",()=>{ls.flush()});var us=e=>{const t=()=>{ls.flush(),Xn&&ls.printLogFileInfo(),process.removeListener(e,t),process.kill(process.pid,e)};return t};process.on("SIGINT",us("SIGINT")),process.on("SIGTERM",us("SIGTERM"));var ds=()=>"true"===process.env.GITHUB_ACTIONS?"github-actions":"true"===process.env.GITLAB_CI?"gitlab-ci":"true"===process.env.CIRCLECI?"circleci":process.env.JENKINS_URL?"jenkins":process.env.CI?"generic-ci":"local",ps=()=>"local"!==ds(),fs=e=>{switch(e){case"github-actions":return"GitHub secrets";case"gitlab-ci":return"GitLab CI/CD variables";case"circleci":return"CircleCI environment variables";case"jenkins":return"Jenkins credentials";case"generic-ci":return"CI secrets/environment variables";case"local":return"environment variables"}},hs=()=>{const e=ds();return[`Authentication failed. In CI, add the following to your ${fs(e)}:`," STABLY_API_KEY β https://app.stably.ai/settings?tab=api-key"," STABLY_PROJECT_ID β https://app.stably.ai/settings?tab=project-id"].join("\n")},gs=()=>{const e=process.env.STABLY_API_KEY?.trim(),t=process.env.STABLY_PROJECT_ID?.trim();if(e&&t)return ls.debug("Environment auth detected",{hasApiKey:!0,hasProjectId:!0}),{apiKey:e,projectId:t};ls.debug("Environment auth not set",{hasApiKey:!!e,hasProjectId:!!t})},ms=async()=>{ls.debug("Checking for stored auth tokens");const e=await Dn();if(!e)return void ls.debug("No stored auth tokens found");const t=Mn(e);if(ls.debug("Auth tokens status",{expired:t}),!t){const t=await Bn(),r=(e=>{try{const t=En.parse(xn(e));if(t.org_id_to_org_member_info)return"full";if(t.org_member_info)return"org"}catch{return"unknown"}return"unknown"})(e.accessToken);if(ls.debug("Token scope check",{scope:r,hasContext:!!t}),t&&"full"===r)try{ls.debug("Exchanging full token for org-scoped token",{orgId:t.orgId});const r=await Tn(e.accessToken,t.orgId),n={accessToken:r.accessToken,expiresAt:Date.now()+1e3*r.expiresInSeconds,idToken:e.idToken,refreshToken:e.refreshToken};return await Nn(n),ls.debug("Token exchange successful"),n}catch(t){return ls.debug("Token exchange failed, using existing token",{error:t instanceof Error?t.message:String(t)}),e}return e}try{ls.debug("Attempting token refresh");const t=await Fn(e.refreshToken);ls.debug("Token refresh successful");const r=await Bn();if(r)try{ls.debug("Exchanging refreshed token for org-scoped token");const e=await Tn(t.accessToken,r.orgId),n={accessToken:e.accessToken,expiresAt:Date.now()+1e3*e.expiresInSeconds,idToken:t.idToken,refreshToken:t.refreshToken};return await Nn(n),n}catch{return await Nn(t),t}return await Nn(t),t}catch(e){return void ls.warn("Token refresh failed",{error:e instanceof Error?e.message:String(e)})}},ys=async(e={})=>{ls.debug("Requiring authentication",{autoLogin:e.autoLogin});const t=gs();if(t)return ls.info("Using environment variable authentication"),{auth:t,type:"env"};const r=await Dn();let n=await ms(),s=n?await Bn():void 0;const o=process.stdin.isTTY&&process.stdout.isTTY;if(ls.debug("OAuth auth check",{hasTokens:!!n,hasStoredTokens:!!r,hasContext:!!s,canPrompt:o}),(!n||!s)&&e.autoLogin&&o){ls.info("Prompting user to login"),n?ae.info("You are logged in but need to select an organization and project."):ae.info("You are not logged in."),ae.info("Press Enter to log in."),process.stdout.write(`${ne.dim("Alternatively, set environment variables for an org API key:")}\n${ne.dim(" STABLY_API_KEY=... STABLY_PROJECT_ID=... stably")}\n`),process.stdout.write("\n");const e=re({input:process.stdin,output:process.stdout});try{await e.question(ne.dim("Press Enter to continue... "))}finally{e.close()}await Yn(),n=await ms(),s=n?await Bn():void 0}return n||(ls.warn("Authentication required but no tokens available",{hadStoredTokens:!!r}),ps()?ce(Dr("error",hs())):ce(Dr("error",r?"Your session has expired. Run `stably login` to re-authenticate.":"You are not logged in. Run `stably login` to authenticate.")),process.exit(1)),s||(ls.warn("Authentication succeeded but no project context selected"),ps()?ce(Dr("error",hs())):ce(Dr("error","You haven't selected an organization and project. Run `stably login` to complete setup.")),process.exit(1)),ls.info("OAuth authentication successful",{orgId:s.orgId,projectId:s.projectId}),{auth:{accessToken:n.accessToken,context:s},type:"oauth"}},bs=e=>"env"===e.type?e.auth.projectId:e.auth.context.projectId,ws=e=>"env"===e.type?e.auth.apiKey:e.auth.accessToken,vs=class e{static TOKEN_REFRESH_BUFFER_MS=3e5;initialAuth;refreshPromise=null;cachedToken=null;cachedExpiresAt=0;constructor(e){this.initialAuth=e}async getAuthHeader(){return"env"===this.initialAuth.type?this.initialAuth.auth.apiKey:this.cachedToken&&Date.now()<this.cachedExpiresAt-e.TOKEN_REFRESH_BUFFER_MS?this.cachedToken:(this.refreshPromise||(this.refreshPromise=(async()=>{try{const e=await ms();if(!e)throw new Error("Authentication expired and refresh failed. Please re-run `stably login`.");return this.cachedToken=e.accessToken,this.cachedExpiresAt=e.expiresAt,e.accessToken}finally{this.refreshPromise=null}})()),this.refreshPromise)}getOrgId(){return"oauth"===this.initialAuth.type?this.initialAuth.auth.context.orgId:void 0}getProjectId(){return"env"===this.initialAuth.type?this.initialAuth.auth.projectId:this.initialAuth.auth.context.projectId}},Is=async e=>{const t=await ys(),r=bs(t),n=ws(t);ls.debug("Fetching remote environment variables",{envName:e,projectId:r});const s=await(o={auth:n,client:In(),path:{projectId:r,environment:e}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments/{environment}/variables",...o}));var o;if(404===s.response.status)return{ok:!1,error:`Environment "${e}" not found. Check the name on your Stably dashboard.`};if(401===s.response.status||403===s.response.status)return{ok:!1,error:`Access denied to environment "${e}".`};if(s.error)return{ok:!1,error:`Failed to fetch environment "${e}": ${s.response.status}`};const i={},a=[];for(const e of s.data.variables)i[e.name]=e.value,e.sensitive&&e.value.length>0&&a.push(e.value);const c=s.data.variables.length,l=a.length;return process.stderr.write(`${Dr("info",`Loaded ${c} variable${1!==c?"s":""} from "${e}"`)}${l>0?ne.dim(` (${l} sensitive)`):""}\n`),{ok:!0,result:{variables:i,sensitiveValues:a}}},Ts=async()=>{const e=Ue.remoteEnvName;if(!e)return;const t=await Is(e);return t.ok||(ce(Dr("error",t.error)),process.exit(1)),t.result},_s=e=>e?{[Hr]:e}:void 0,Es=he.object({context:he.string().min(1),autohealReportUrl:he.string(),skippedTests:he.array(he.object({testIdentifier:he.string(),testTitle:he.string(),consecutiveUnfixedCount:he.number()})).optional(),newerPassingSuiteId:he.string().optional(),envName:he.string().optional()}),Ss=we.object({bucket:we.string(),key:we.string()}),xs=async({body:e,contentType:t,uploadUrl:r,errorContext:n="content"})=>{const s=await fetch(r,{body:e instanceof Uint8Array?Buffer.from(e):e,headers:{"Content-Type":t},method:"PUT"});if(!s.ok)throw new Error(`Failed to upload ${n} (${s.status})`)},As=we.object({diffBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string()}),ks=we.object({traceBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string(),sensitiveValues:we.array(we.string())}),Ps=async({authHeader:e,contentType:t="text/plain",orgId:r,runId:n})=>{const s=await(o={auth:e,body:{contentType:t},client:In(),headers:_s(r),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-diff/upload-url",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to presign diff upload (${s.response.status})`);const i=As.parse(s.data);return{diffBucketPath:i.diffBucketPath,expiresInSeconds:i.expiresInSeconds,key:i.key,uploadUrl:i.uploadUrl}},Cs=async({authHeader:e,diffBucketPath:t,orgId:r,runId:n})=>{const s=await(o={auth:e,body:t,client:In(),headers:_s(r),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-diff/confirm-upload",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to confirm diff upload (${s.response.status})`)},Rs=class e{socket;url;authProvider;orgId;runId;pendingEvent=null;reconnectAttempts=0;reconnectTimer;flushPromise=null;debounceTimer;_isClosed=!1;isAuthenticated=!1;authenticationFailed=!1;onUserMessage;maxReconnectAttempts=10;baseReconnectDelay=2e3;maxReconnectDelay=3e4;debounceMs=500;get isClosed(){return this._isClosed}constructor({authProvider:e,orgId:t,runId:r,url:n=bn,onUserMessage:s}){this.authProvider=e,this.orgId=t,this.runId=r,this.url=n,this.onUserMessage=s,ls.info("[ws] Constructing AutohealWebSocketClient",{url:this.url,runId:r})}async start(){await this.connect()}async connect(){if(!this._isClosed)try{const e=await this.authProvider.getAuthHeader();if(this._isClosed)return;const t={Authorization:e};this.orgId&&(t["x-stably-org-id"]=this.orgId);const r=`${this.url}?runId=${encodeURIComponent(this.runId)}`;ls.info("[ws] Connecting",{url:r,attempt:this.reconnectAttempts}),this.socket=new ve(r,{headers:t}),this.socket.on("open",()=>{ls.info("[ws] Connection opened"),this.reconnectAttempts=0}),this.socket.on("message",e=>{try{const t="string"==typeof e?e:e.toString(),r=JSON.parse(t);ls.debug("[ws] Received message",{type:r?.type}),"connected"===r?.type&&(ls.info("[ws] Authenticated successfully"),this.isAuthenticated=!0,this.authenticationFailed=!1,this.flushPending()),"user_message"===r?.type&&"string"==typeof r.content&&(ls.info("[ws] Received user message from web UI"),this.onUserMessage?.(r.content))}catch{}}),this.socket.on("close",(e,t)=>{ls.info("[ws] Connection closed",{code:e,authFailed:1008===e,reconnectAttempts:this.reconnectAttempts,maxReconnect:this.maxReconnectAttempts,isClosed:this._isClosed}),this.isAuthenticated=!1,1008===e&&(this.authenticationFailed=!0),!this._isClosed&&!this.authenticationFailed&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()}),this.socket.on("error",e=>{ls.warn("[ws] Connection error",{error:e.message})})}catch(e){ls.warn("[ws] Failed to create WebSocket",{error:e instanceof Error?e.message:String(e)}),this.scheduleReconnect()}}scheduleReconnect(){if(this._isClosed||this.reconnectTimer)return;this.reconnectAttempts++;const e=Math.min(this.baseReconnectDelay*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelay);ls.info("[ws] Scheduling reconnect",{attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts,delayMs:e}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.connect().catch(e=>{ls.warn("[ws] Reconnect failed",{error:e instanceof Error?e.message:String(e)})})},e)}isConnected(){return!!this.socket&&this.socket.readyState===ve.OPEN&&this.isAuthenticated}sendProgress(e){if(this._isClosed)return void ls.debug("[ws] sendProgress called but client is closed",{phase:e.phase});const t={type:"autoheal_progress",payload:e};return this.pendingEvent=t,this.isConnected()?"complete"===e.phase?(ls.info("[ws] sendProgress: flushing terminal state immediately"),void this.flushPending()):void(this.debounceTimer||(this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.flushPending()},this.debounceMs))):(ls.debug("[ws] sendProgress: not connected, queuing event",{phase:e.phase,socketState:this.socket?.readyState,isAuthenticated:this.isAuthenticated,reconnectAttempts:this.reconnectAttempts}),void(this.socket?.readyState===ve.CLOSED&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()))}flushPending(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),!this.pendingEvent)return;const e=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.debug("[ws] flushPending: not connected, re-queuing event",{phase:e.payload.phase}),void(this.pendingEvent=e);ls.debug("[ws] flushPending: sending event",{phase:e.payload.phase});const t=new Promise(t=>{try{this.socket?.send(JSON.stringify(e),r=>{r&&(ls.warn("[ws] flushPending: send failed",{error:r.message,phase:e.payload.phase}),this.pendingEvent||(this.pendingEvent=e)),t()})}catch(r){ls.warn("[ws] flushPending: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=e,t()}}).finally(()=>{this.flushPromise===t&&(this.flushPromise=null)});this.flushPromise=t}static FLUSH_TIMEOUT_MS=5e3;async flushPendingAndWait(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.flushPromise&&await Promise.race([this.flushPromise,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())]),!this.pendingEvent)return;const t=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.warn("[ws] flushPendingAndWait: not connected, event will be dropped",{phase:t.payload.phase}),void(this.pendingEvent=t);const r=new Promise(e=>{try{ls.debug("[ws] flushPendingAndWait: sending event",{phase:t.payload.phase}),this.socket?.send(JSON.stringify(t),r=>{r&&(ls.warn("[ws] flushPendingAndWait: send failed",{error:r.message,phase:t.payload.phase}),this.pendingEvent||(this.pendingEvent=t)),e()})}catch(r){ls.warn("[ws] flushPendingAndWait: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=t,e()}});await Promise.race([r,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())])}close(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.flushPending();const{socket:e}=this;this.socket=void 0,e&&setTimeout(()=>{e.close()},200)}async closeAndWait(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client and waiting for pending send"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.flushPendingAndWait();const{socket:e}=this;this.socket=void 0,e&&(await new Promise(e=>setTimeout(e,200)),e.close())}},Us=(e,t)=>{const r=e.findIndex(e=>e.testFilePath===t.testFilePath);return-1===r?[...e,t]:e.map((e,n)=>n===r?t:e)},Ls=class e{socket;url;authProvider;orgId;sessionId;pendingEvent=null;reconnectAttempts=0;reconnectTimer;flushPromise=null;debounceTimer;_isClosed=!1;isAuthenticated=!1;authenticationFailed=!1;onUserMessage;maxReconnectAttempts=10;baseReconnectDelay=2e3;maxReconnectDelay=3e4;debounceMs=500;get isClosed(){return this._isClosed}constructor({authProvider:e,orgId:t,sessionId:r,url:n=wn,onUserMessage:s}){this.authProvider=e,this.orgId=t,this.sessionId=r,this.url=n,this.onUserMessage=s,ls.info("[ws] Constructing CreateProgressWebSocketClient",{url:this.url,sessionId:r})}async start(){await this.connect()}async connect(){if(!this._isClosed)try{const e=await this.authProvider.getAuthHeader();if(this._isClosed)return;const t={Authorization:e};this.orgId&&(t["x-stably-org-id"]=this.orgId);const r=`${this.url}?sessionId=${encodeURIComponent(this.sessionId)}`;ls.info("[ws] Connecting",{url:r,attempt:this.reconnectAttempts}),this.socket=new ve(r,{headers:t}),this.socket.on("open",()=>{ls.info("[ws] Connection opened"),this.reconnectAttempts=0}),this.socket.on("message",e=>{try{const t="string"==typeof e?e:e.toString(),r=JSON.parse(t);ls.debug("[ws] Received message",{type:r?.type}),"connected"===r?.type&&(ls.info("[ws] Authenticated successfully"),this.isAuthenticated=!0,this.authenticationFailed=!1,this.flushPending()),"user_message"===r?.type&&"string"==typeof r.content&&(ls.info("[ws] Received user message from web UI"),this.onUserMessage?.(r.content))}catch{}}),this.socket.on("close",(e,t)=>{ls.info("[ws] Connection closed",{code:e,authFailed:1008===e,reconnectAttempts:this.reconnectAttempts,maxReconnect:this.maxReconnectAttempts,isClosed:this._isClosed}),this.isAuthenticated=!1,1008===e&&(this.authenticationFailed=!0),!this._isClosed&&!this.authenticationFailed&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()}),this.socket.on("error",e=>{ls.warn("[ws] Connection error",{error:e.message})})}catch(e){ls.warn("[ws] Failed to create WebSocket",{error:e instanceof Error?e.message:String(e)}),this.scheduleReconnect()}}scheduleReconnect(){if(this._isClosed||this.reconnectTimer)return;this.reconnectAttempts++;const e=Math.min(this.baseReconnectDelay*Math.pow(2,this.reconnectAttempts-1),this.maxReconnectDelay);ls.info("[ws] Scheduling reconnect",{attempt:this.reconnectAttempts,maxAttempts:this.maxReconnectAttempts,delayMs:e}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=void 0,this.connect().catch(e=>{ls.warn("[ws] Reconnect failed",{error:e instanceof Error?e.message:String(e)})})},e)}isConnected(){return!!this.socket&&this.socket.readyState===ve.OPEN&&this.isAuthenticated}sendProgress(e){if(this._isClosed)return void ls.debug("[ws] sendProgress called but client is closed",{phase:e.phase});const t={type:"create_progress",payload:e};return this.pendingEvent=t,this.isConnected()?"complete"===e.phase?(ls.info("[ws] sendProgress: flushing terminal state immediately"),void this.flushPending()):void(this.debounceTimer||(this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.flushPending()},this.debounceMs))):(ls.debug("[ws] sendProgress: not connected, queuing event",{phase:e.phase,socketState:this.socket?.readyState,isAuthenticated:this.isAuthenticated,reconnectAttempts:this.reconnectAttempts}),void(this.socket?.readyState===ve.CLOSED&&this.reconnectAttempts<this.maxReconnectAttempts&&this.scheduleReconnect()))}flushPending(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),!this.pendingEvent)return;const e=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.debug("[ws] flushPending: not connected, re-queuing event",{phase:e.payload.phase}),void(this.pendingEvent=e);ls.debug("[ws] flushPending: sending event",{phase:e.payload.phase});const t=new Promise(t=>{try{this.socket?.send(JSON.stringify(e),r=>{r&&(ls.warn("[ws] flushPending: send failed",{error:r.message,phase:e.payload.phase}),this.pendingEvent||(this.pendingEvent=e)),t()})}catch(r){ls.warn("[ws] flushPending: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=e,t()}}).finally(()=>{this.flushPromise===t&&(this.flushPromise=null)});this.flushPromise=t}static FLUSH_TIMEOUT_MS=5e3;async flushPendingAndWait(){if(this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.flushPromise&&await Promise.race([this.flushPromise,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())]),!this.pendingEvent)return;const t=this.pendingEvent;if(this.pendingEvent=null,!this.isConnected())return ls.warn("[ws] flushPendingAndWait: not connected, event will be dropped",{phase:t.payload.phase}),void(this.pendingEvent=t);const r=new Promise(e=>{try{ls.debug("[ws] flushPendingAndWait: sending event",{phase:t.payload.phase}),this.socket?.send(JSON.stringify(t),r=>{r&&(ls.warn("[ws] flushPendingAndWait: send failed",{error:r.message,phase:t.payload.phase}),this.pendingEvent||(this.pendingEvent=t)),e()})}catch(r){ls.warn("[ws] flushPendingAndWait: send threw",{error:r instanceof Error?r.message:String(r)}),this.pendingEvent=t,e()}});await Promise.race([r,new Promise(t=>setTimeout(t,e.FLUSH_TIMEOUT_MS).unref())])}close(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),this.flushPending();const{socket:e}=this;this.socket=void 0,e&&setTimeout(()=>{e.close()},200)}async closeAndWait(){if(this._isClosed)return;ls.info("[ws] Closing WebSocket client and waiting for pending send"),this._isClosed=!0,this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=void 0),await this.flushPendingAndWait();const{socket:e}=this;this.socket=void 0,e&&(await new Promise(e=>setTimeout(e,200)),e.close())}},$s=we.object({bucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string()}),Ds=we.object({uploadUrl:we.string(),key:we.string(),bucketPath:we.object({bucket:we.string(),key:we.string()}),expiresInSeconds:we.number()}),Ns=we.object({success:we.boolean()});async function Os({authHeader:e,orgId:t,sessionId:r,projectId:n,history:s}){if(0===s.length)return ls.debug("[session-history] No history to upload"),{success:!0};try{(async()=>{const o=await(i={auth:e,body:{history:s,...n?{projectId:n}:{}},client:In(),headers:_s(t),path:{sessionId:r},signal:AbortSignal.timeout(3e4)},(i.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/history/hot-store",...i,headers:{"Content-Type":"application/json",...i.headers}}));var i;if(o.error)throw new Error(`Hot store mirror failed (${o.response.status})`);Ns.parse(o.data)})().catch(e=>{ls.warn("[session-history] Failed to mirror history to hot store",{error:e instanceof Error?e.message:String(e)})}),ls.info("[session-history] Requesting upload URL",{sessionId:r,messageCount:s.length});const{uploadUrl:o,key:i}=await async function({authHeader:e,orgId:t,sessionId:r,projectId:n}){const s=await(o={auth:e,body:{contentType:"application/x-ndjson",...n?{projectId:n}:{}},client:In(),headers:_s(t),path:{sessionId:r},signal:AbortSignal.timeout(3e4)},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/history/upload-url",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to get history upload URL (${s.response.status})`);return Ds.parse(s.data)}({authHeader:e,orgId:t,sessionId:r,projectId:n}),a=s.map(e=>JSON.stringify(e)).join("\n");ls.info("[session-history] Uploading history",{key:i,messageCount:s.length,sizeBytes:a.length});const c=await fetch(o,{method:"PUT",body:a,headers:{"Content-Type":"application/x-ndjson"},signal:AbortSignal.timeout(6e4)});if(!c.ok)throw new Error(`Upload failed with status ${c.status}`);return ls.info("[session-history] History uploaded successfully",{key:i}),{success:!0,key:i}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.warn("[session-history] Failed to upload history",{error:t}),{success:!1,error:t}}}var Bs="1.58.0",js=["auth login","auth logout","auth setup-git","auth switch","config set","secret set","secret delete","variable set","variable delete","repo delete","repo edit","repo rename","repo archive"];function Ms(e){return/^\.env(\..*)?$/.test(e)||".stably-agent.env"===e}function Fs(e){return Boolean(e&&"object"==typeof e&&"tool_input"in e&&e.tool_input&&"object"==typeof e.tool_input)}function Hs({action:e,pathKey:t}){return function({action:e,fileCheck:t,getBlockMessage:r,pathKey:n}){return async s=>{const o=function({input:e,pathKey:t}){if(!Fs(e))return{decision:"block",reason:`Invalid tool call format: Expected an object with 'tool_input' property. Please ensure the tool call follows the correct structure: { tool_input: { ${t}: "path/to/file" } }`,success:!1,systemMessage:"Tool call blocked due to invalid input format"};const r=e.tool_input;return t in r?"string"==typeof r[t]?{path:r[t],success:!0}:{decision:"block",reason:`Invalid tool call format: The '${t}' parameter must be a string containing the file path, but received ${typeof r[t]}. Please provide a valid file path as a string. Example: { tool_input: { ${t}: "src/example.ts" } }`,success:!1,systemMessage:"Tool call blocked due to invalid parameter type"}:{decision:"block",reason:`Invalid tool call format: Missing required parameter '${t}'. Please provide the file path using the '${t}' parameter. Example: { tool_input: { ${t}: "path/to/file" } }`,success:!1,systemMessage:"Tool call blocked due to missing required parameters"}}({input:s,pathKey:n});if(!o.success)return o;const i=o.path.replace(/\\/g,"/"),a=i.split("/").pop()||i;return t(a)?{decision:"block",reason:r("reading"===e?"Access to":"writing"===e?"Writing to":"editing"===e?"Editing":"Searching in"),systemMessage:"AI blocked due to accessing sensitive content"}:{decision:"approve"}}}({action:e,fileCheck:Ms,getBlockMessage:e=>`${e} .env files is not allowed. Environment variables and secrets should be managed in Stably's Test Data section instead. You can access these values using process.env in your test code.`,pathKey:t})}var Gs=["rm","mv","git","gh","npx","stably","stably-browser","pwtrace","npm","yarn","pnpm","bun"],Ws=["stably","playwright","stably-browser","pwtrace"],Vs=["create","fix","verify"],Ys=["upload"],zs=["push","fetch","pull","clone","ls-remote"],qs=/\S+=(?:\"[^\"\\]*(?:\\.[^\"\\]*)*\"|'[^']*(?:'\\''[^']*)*'|\S+)/;function Ks(e){let t="",r=!1,n=!1,s=!1;for(let o=0;o<e.length;o++){const i=e[o];s?(t+=i,s=!1):"\\"!==i||n?'"'!==i||n?"'"!==i||r?t+=i:n=!n:r=!r:s=!0}return t}function Js(e){const t=[],r=e.trim(),n=/(?:[^\s"']+|"[^"\\]*(?:\\.[^"\\]*)*"|'[^']*(?:'\\''[^']*)*')+/g;let s;for(;null!==(s=n.exec(r));)t.push(s[0]);return t}function Xs(e){let t=0;const r=new RegExp(`^${qs.source}$`);for(;t<e.length&&r.test(e[t]??"");)t+=1;return e.slice(t)}function Qs(e){const t=Xs(Js(e));if("npx"===t[0])for(let e=1;e<t.length;e+=1){const r=t[e];if(r){if("--"===r)return t[e+1];if(!r.startsWith("-"))return Ks(r)}}}function Zs(e){return Js(e).map(Ks).find(e=>Vs.includes(e))}function eo(e,t){const r=c(e).replace(/\\/g,"/"),n=t.replace(/\\/g,"/"),s=n.endsWith("/")?n:`${n}/`;if(r.startsWith(s))return!0;const o=r.lastIndexOf(`/${s}`);if(-1===o)return!1;const i=r.slice(o+`/${s}`.length);return i.length>0&&!i.startsWith("../")}function to({onBeforeGitHubCommand:e,workspaceBoundary:t,allowBackgroundRunTest:r=!1}){return async n=>{if(!Fs(n))return{decision:"block",reason:"Invalid tool call format: Expected an object with tool_input property.",systemMessage:"Tool call blocked due to invalid input format"};const i=n.tool_input,{command:c}=i;if("string"!=typeof c)return{decision:"block",reason:"Invalid Bash command: command must be a string.",systemMessage:"Tool call blocked due to invalid command type"};const l=function(e){const t=e.trim(),r=new RegExp(`^(?:${qs.source}\\s+)*(\\S+)`),n=t.match(r);return n?.[1]}(c);if(!l)return{decision:"block",reason:"Invalid Bash command: could not parse command.",systemMessage:"Tool call blocked due to unparseable command"};if(!r&&"run_in_background"in i&&!0===i.run_in_background&&/\bstably-browser\s+(?:(?:-\w+=?\S*|--\w+=?\S*|-s\s+\S+|--session\s+\S+)\s+)*run-test\b/.test(c))return{decision:"block",reason:"Running `stably-browser run-test` with `run_in_background: true` is not allowed. Test runs must execute in the foreground so their output can be captured and parsed. Remove the `run_in_background` parameter and run the test normally.",systemMessage:"Tool call blocked due to run-test in background"};if(!function(e){return"string"==typeof e&&Gs.includes(e)}(l))return{decision:"block",reason:`The command "${l}" is not allowed. Only the following commands are permitted: ${Gs.join(", ")}. Use the appropriate tools (Read, Write, Edit, Glob, Grep) for file operations instead.`,systemMessage:"Tool call blocked due to disallowed command"};if("npx"===l){const e=function(e){if(/(\s|^)npx\s+.*(\s|^)(-c|--call)(\s|=)/.test(e.trim()))return{valid:!1,reason:"The npx -c/--call form is not allowed. Use direct commands like `npx stably test ...`."};const t=Qs(e);if(!t)return{valid:!1,reason:"Invalid npx command: unable to determine which binary is being executed."};if(!new Set(Ws).has(t))return{valid:!1,reason:`The npx binary "${t}" is not allowed. Only ${Ws.join(", ")} are permitted.`};if("stably"===t){const r=Zs(e);if(r)return{valid:!1,reason:`The npx ${t} subcommand "${r}" is not allowed. The commands ${Vs.join(", ")} are AI-powered and blocked to prevent recursion.`}}return{valid:!0}}(c);if(!e.valid)return{decision:"block",reason:e.reason,systemMessage:"Tool call blocked due to disallowed npx command"}}if("stably-browser"===l||"npx"===l&&"stably-browser"===Qs(c)){const e=function({command:e,binary:t}){const r=Xs(Js(e)),n=r.findIndex(e=>e===t);if(-1!==n)for(let e=n+1;e<r.length;e+=1){const t=r[e];if(t&&!t.startsWith("-"))return Ks(t)}}({command:c,binary:"stably-browser"});if(e&&Ys.includes(e))return{decision:"block",reason:`The stably-browser subcommand "${e}" is not allowed. The "upload" command can read arbitrary files and is blocked for security.`,systemMessage:"Tool call blocked due to disallowed stably-browser subcommand"}}if("stably"===l){const e=Zs(c);if(e)return{decision:"block",reason:`The stably subcommand "${e}" is not allowed. The commands ${Vs.join(", ")} are AI-powered and blocked to prevent recursion.`,systemMessage:"Tool call blocked due to disallowed stably command"}}if("rm"===l){const e=function(e){const t=e.trim().match(/^rm\s+(?:-[a-zA-Z]+\s+|--[a-zA-Z-]+\s+)*(.+)$/),r=t?.[1]?.trim();return r?r.split(/\s+/).filter(e=>e.length>0):[]}(c);if(0===e.length)return{decision:"block",reason:"Invalid rm command: could not determine the file path(s) to remove.",systemMessage:"Tool call blocked due to invalid rm command"};if(t){const r=e.filter(e=>!function({targetPath:e,boundaryDir:t}){const r=function(e){if(E(e))return k.native(e);let t=e;const r=[];for(;!E(t);){const n=o(t);if(n===t)return s(e);r.unshift(t.slice(n.length+1)),t=n}const n=k.native(t);return r.length>0?s(n,...r):n}(e),n=k.native(t),i=r.endsWith(a)?r:r+a,c=n.endsWith(a)?n:n+a;return i.startsWith(c)||r===n}({targetPath:s(t,e),boundaryDir:t}));if(r.length>0)return{decision:"block",reason:`The rm command can only remove files within the workspace. The following path(s) are outside the workspace boundary: ${r.join(", ")}.`,systemMessage:"Tool call blocked due to rm outside workspace"}}else{const t=e.filter(e=>!(eo(e,"tests")||eo(e,".stably")));if(t.length>0)return{decision:"block",reason:`The rm command can only remove files in the tests/ directory or .stably/ directory. The following path(s) are not allowed: ${t.join(", ")}.`,systemMessage:"Tool call blocked due to rm outside allowed directories"}}}if("git"===l&&["-c","--config","--config-env"].some(e=>c.includes(` ${e} `)||c.includes(` ${e}=`)))return{decision:"block",reason:"Git config flags (-c, --config, --config-env) are not allowed for security reasons.",systemMessage:"Tool call blocked due to git config injection attempt"};if("git"===l&&function(e){const t=e.trim();return!!t.startsWith("git ")&&zs.some(e=>t.includes(` ${e}`)||t.includes(`git ${e}`))}(c)&&e)try{await e()}catch(e){console.error("[BashSecurityHook] Failed to refresh git token:",e)}if("gh"===l){const t=function(e){const t=e.toLowerCase();return js.some(e=>t.includes(`gh ${e}`))?{allowed:!1,reason:"This gh subcommand is not allowed for security reasons. Only read operations and PR/issue management are permitted. Blocked subcommands include: auth, config set, secret/variable management, and destructive repo operations.",systemMessage:"Tool call blocked due to dangerous gh subcommand"}:t.includes("gh api")&&(/--method\s+(delete|put|patch)/i.test(e)||/-X\s+(DELETE|PUT|PATCH)/i.test(e))?{allowed:!1,reason:"The gh api command with destructive HTTP methods (DELETE, PUT, PATCH) is not allowed for security reasons. Only GET requests are permitted for raw API access.",systemMessage:"Tool call blocked due to destructive gh api method"}:{allowed:!0}}(c);if(!t.allowed)return{decision:"block",reason:t.reason,systemMessage:t.systemMessage};if(e)try{await e()}catch(e){console.error("[BashSecurityHook] Failed to refresh GitHub token for gh command:",e)}}return{decision:"approve"}}}var ro=/\.(spec|test)\.(ts|tsx|js|jsx|mts|mjs)$/;function no({onFileCreated:e}){return async t=>{const r=(e=>{if(!e||"object"!=typeof e)return;const t=e;return t.tool_input&&"object"==typeof t.tool_input&&!Array.isArray(t.tool_input)?t.tool_input:void 0})(t),n=r?.file_path;return"string"==typeof n&&ro.test(n)&&e(n),{decision:"approve"}}}var so=M(f);async function oo(){try{const{stdout:e}=await so('pgrep -f "playwright run-test-mcp-server" 2>/dev/null || true'),t=e.trim();if(!t)return;const r=t.split("\n").filter(Boolean);await Promise.allSettled(r.map(async e=>{await so(`pkill -KILL -P ${e} '.*' 2>/dev/null || true`)}))}catch{}}var io=class{queue=[];pendingResolve=void 0;done=!1;canSend=!0;[Symbol.asyncIterator](){return this}pushText(e){const t=e.trim();t&&!this.done&&(this.queue.push(t),this.maybeFlush())}allowNextTurn(){this.done||(this.canSend=!0,this.maybeFlush())}hasQueuedMessages(){return this.queue.length>0}drainQueue(){return this.queue.splice(0)}finish(){this.done=!0,this.pendingResolve&&(this.pendingResolve({done:!0,value:void 0}),this.pendingResolve=void 0)}maybeFlush(){if(!this.pendingResolve)return;if(!this.canSend)return;const e=this.queue.shift();if(void 0===e)return;const t={message:{content:[{text:e,type:"text"}],role:"user"},parent_tool_use_id:null,type:"user",session_id:""};this.canSend=!1,this.pendingResolve({done:!1,value:t}),this.pendingResolve=void 0}next(){return this.done?Promise.resolve({done:!0,value:void 0}):new Promise(e=>{this.pendingResolve=e,this.maybeFlush()})}};function ao(e){try{const t=h("git branch --show-current",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}).trim();if(!t)return;return{branch:t}}catch{return}}var co=[".ts",".js",".mts",".mjs",".cts",".cjs"],lo=10240,uo=async({defaultContent:e,fileName:t,filePath:r})=>{try{const e=(await Z(r)).size,n=await z(r,"utf-8"),s=Buffer.byteLength(n,"utf-8");if(s<=lo)return n;const o=(e=>{const t=e.split("\n"),r=[];let n=!1,s=!1,o=0,i=!1;for(let e=0;e<t.length;e++){const a=t[e],c=a.trim();c.startsWith("/*")&&(n=!0),c.includes("*/")?n=!1:n||c.startsWith("//")&&!c.startsWith("///")||(c.startsWith("import ")||c.startsWith("export ")?(r.push(a),i=!0):i&&""===c?(r.push(a),i=!1):(i=!1,c.startsWith("type ")||c.startsWith("interface ")?r.push(a):c.startsWith("function ")||c.startsWith("const ")||c.startsWith("async function ")||c.startsWith("export function ")||c.startsWith("export const ")||c.startsWith("test.describe(")||c.startsWith("test(")?(r.push(a),s=!0,o=(a.match(/{/g)||[]).length-(a.match(/}/g)||[]).length,0===o&&(c.endsWith(";")||c.endsWith(","))&&(s=!1)):s?(o+=(a.match(/{/g)||[]).length,o-=(a.match(/}/g)||[]).length,0===o&&c.includes("}")?(r.push(a),s=!1):o>0&&" // ... implementation omitted ..."!==r.at(-1)&&r.push(" // ... implementation omitted ...")):c.match(/^[a-zA-Z_]+:/)&&r.push(a)))}return r.join("\n")})(n),i=Buffer.byteLength(o,"utf-8");return i<=lo?o:o.slice(0,lo)+`\n\n... [TRUNCATED: File "${t}" at ${r} was ${e} bytes (${s} bytes as UTF-8), reduced to ~${i} bytes of essential content, then truncated to 10240 bytes] ...`}catch(r){let n;if(r&&"object"==typeof r&&"code"in r){const e=r.code;"string"==typeof e&&(n=e)}return"ENOENT"!==n&&console.warn(`Failed to read ${t}: ${r}`),e}},po=async({defaultContent:e,dirName:t,dirPath:r})=>{try{const e=await Q(r);return e.length>0?e.join("\n"):"(empty)"}catch(r){let n;if(r&&"object"==typeof r&&"code"in r){const e=r.code;"string"==typeof e&&(n=e)}return"ENOENT"!==n&&console.warn(`Failed to read ${t}: ${r}`),e}};async function fo(e){let t=e;for(;;){try{const e=await z(n.join(t,"package.json"),"utf-8"),r=JSON.parse(e);return"object"==typeof r&&"module"===r?.type}catch{}const e=n.dirname(t);if(e===t)return!1;t=e}}var ho=async({allowedEnvVars:e,mode:t,workspaceInfo:r,authHeader:n,customHeader:s,maxParallelWorkers:o,isCloudBrowser:i})=>{const a=In(),c=ao(r.absolutePath);ls.debug("Requesting system prompt from API",{mode:t,hasGitContext:!!c,envVarCount:e.length});const l=await(u={client:a,auth:n,body:{mode:t,workspaceInfo:r,allowedEnvVars:e,gitContext:c,maxParallelWorkers:o,isCloudBrowser:i}},(u.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/prompts/system",...u,headers:{"Content-Type":"application/json",...u.headers}}));var u;if(401===l.response.status)throw ls.warn("System prompt fetch failed: unauthorized (401)"),await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");if(403===l.response.status)throw ls.debug("System prompt fetch failed: forbidden (403)"),new Error("Your organization does not have an active subscription. Manage your subscription at https://app.stably.ai or contact your organization admin.");if(l.error){ls.warn("System prompt fetch failed",{error:l.error});const e=JSON.stringify(l.error);if(e.toLowerCase().includes("unauthorized")||e.toLowerCase().includes("unauthenticated"))throw await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");throw new Error("Failed to fetch system prompt. Please check your network connection and try again. If this persists, run `stably login` to re-authenticate.")}const d=function({customHeader:e,systemPrompt:t}){return e?`${t}\n\nWhen writing or updating the generated test file, prepend this exact header at the top of the file without modification:\n\`\`\`ts\n${e}\n\`\`\``:t}({systemPrompt:l.data.systemPrompt,customHeader:s});return ls.debug("System prompt received",{size:d.length,appendedCustomHeader:!!s,hasPrContext:!!l.data.prContext}),{systemPrompt:d,prContext:l.data.prContext}},go={chat:"chat",single:"create",fix:"fix",init:"init",verify:"verify",plan:"plan"};async function mo({agentMode:e,authHeader:t,orgId:r,projectId:n,runId:s,fetchImpl:o=fetch,apiUrl:i=fn}){const a=go[e],c=new URL("/internal/v1/cli/progress",i).toString(),l={Authorization:t,"Content-Type":"application/json","X-STABLY-CLI-VERSION":pn};r&&(l["x-stably-org-id"]=r);const u=await o(c,{method:"POST",headers:l,body:JSON.stringify({mode:a,projectId:n,agentId:oe.randomUUID(),..."fix"===a&&s?{playwrightSuiteRunId:s}:{}}),signal:AbortSignal.timeout(1e4)});if(!u.ok){const e=await u.text().catch(()=>"");throw new Error(`Failed to create progress session: ${u.status} ${c} β ${e.slice(0,300)}`)}const{sessionId:d}=await u.json();return{sessionId:d,sessionMode:a}}var yo=".stably-internal.playwright",bo=`${yo}-wrapper.config.*`,wo="STABLY_INTERNAL_EXECUTION",vo=[".ts",".js",".mts",".mjs",".cts",".cjs"];function Io(e){const t=s(e);if(E(t))for(const e of vo){const r=i(t,`playwright.config${e}`);if(E(r))return r}}var To=["tests","e2e","__tests__","test"];function _o(e){try{return E(e)&&S(e).isDirectory()}catch{return!1}}function Eo(e,t){const r="output-flag"===t?"--output flag":"playwright.config.ts"===t?"playwright.config.ts":"auto-detected"===t?"auto-detected":"cwd fallback";console.error(ne.dim(`Using output directory: ${e} (from ${r})`))}var So=["mcp__playwright-test__","mcp__auto-heal-report__","mcp__stably-agent-control__"],xo=["planner_","generator_"],Ao={open:e=>e?`Open ${e}`:"Open browser",close:()=>"Close browser",snapshot:()=>"Page snapshot",screenshot:()=>"Screenshot",click:e=>`Click ${e}`,fill:e=>`Fill ${e.split(/\s+/)[0]||""}`.trim(),type:e=>`Type into ${e.split(/\s+/)[0]||""}`.trim(),hover:e=>`Hover ${e}`,goto:e=>`Navigate to ${e}`,select:e=>`Select option in ${e.split(/\s+/)[0]||""}`.trim(),check:e=>`Check ${e}`,uncheck:e=>`Uncheck ${e}`,back:()=>"Go back",forward:()=>"Go forward","run-test":e=>`Run test ${e}`,"run-code":()=>"Run code","run-file":e=>`Run file ${e}`,"tab-list":()=>"List tabs","tab-new":e=>e?`New tab ${e}`:"New tab","tab-select":e=>`Select tab ${e}`,"tab-close":()=>"Close tab",eval:()=>"Evaluate JavaScript",upload:()=>"Upload file","state-save":()=>"Save browser state","state-load":()=>"Load browser state"},ko={"stably-browser":"Loading browser command reference","stably-cli":"Loading CLI reference","browser-interaction-guide":"Loading browser interaction guide","playwright-config-auth":"Loading project configuration","playwright-cli":"Loading browser command reference","bash-commands":"Loading command reference","stably-sdk-reference":"Loading SDK reference","test-creation-workflow":"Loading test creation guide","bulk-test-handling":"Loading bulk test guide","debugging-test-failures":"Loading debugging guide","recorded-actions-handling":"Loading recorded actions guide","playwright-best-practices":"Loading best practices","pwtrace-debugging":"Loading trace debugging guide","ai-to-programmatic-migration":"Loading migration guide"},Po={Skill:"Preparing for task",ToolSearch:"Searching tools"},Co=(e,t)=>{const r=t.find(t=>e.startsWith(t));return r?e.slice(r.length):e},Ro=e=>e.split("_").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" "),Uo=(e,t)=>{if(!t||"object"!=typeof t)return;const r=t,n="string"==typeof r.intent?r.intent:void 0;if("Read"!==e&&"Write"!==e&&"Edit"!==e){if("Glob"===e||"Grep"===e)return"string"==typeof r.pattern?r.pattern:void 0;if("mcp__playwright-test__test_run"!==e&&"test_run"!==e){if("mcp__playwright-test__test_debug"===e||"test_debug"===e){const e=r.test;return"string"==typeof e?.title?e.title:void 0}return"mcp__playwright-test__generator_setup_page"===e||"generator_setup_page"===e?"string"==typeof r.seedFile?r.seedFile:"tests/seed.spec.ts":"mcp__playwright-test__generator_write_test"===e||"generator_write_test"===e?"string"==typeof r.fileName?r.fileName:void 0:"Bash"===e?"string"==typeof r.command?r.command.length>50?`${r.command.slice(0,50)}...`:r.command:void 0:e.includes("browser_navigate")&&!e.includes("back")?"string"==typeof r.url?r.url:n:e.includes("browser_type")?("string"==typeof r.text?`"${r.text}"`:void 0)??n:e.includes("browser_click")?"string"==typeof r.element?r.element:n:e.includes("browser_wait_for")?"string"==typeof r.text?`text: "${r.text}"`:"number"==typeof r.time?`${r.time}ms`:n:e.includes("verify_text")?"string"==typeof r.text?`"${r.text}"`:n:e.includes("verify_element")?"string"==typeof r.accessibleName?r.accessibleName:n:e.includes("screenshot")&&"string"==typeof r.filename?r.filename:n}if(Array.isArray(r.locations)){const e=r.locations.filter(e=>"string"==typeof e);return e.length>0?e.join(", "):void 0}}else if("string"==typeof r.file_path)return r.file_path.split("/").at(-1)??void 0},Lo=(e,t)=>{if(!t||"object"!=typeof t)return null;const r=t;if("Skill"===e){const e="string"==typeof r.skill?r.skill:void 0;if(e){const t=e.includes(":")?e.split(":").pop():e;return ko[t]?ko[t]:`Loading ${t.replace(/-/g," ")}`}return"Preparing for task"}if("Bash"===e&&"string"==typeof r.description&&r.description.trim())return r.description.trim();if("Bash"===e&&"string"==typeof r.command){const e=r.command.match(/(?:^|\s)(?:[\w/.-]*\/)?stably-browser\s+(?:--\S+\s+)*(\S+)(.*)/);if(!e)return null;const[,t,n]=e,s=n.trim().replace(/--\S+=?\S*\s*/g,"").trim(),o=Ao[t];return o?o(s):`${Ro(t)}${s?` ${s.split(/\s+/)[0]}`:""}`.trim()}return"Read"===e&&"string"==typeof r.file_path&&(r.file_path.includes(".stably-browser/")||r.file_path.includes(".playwright-cli/"))&&r.file_path.endsWith(".yml")?"Page snapshot":"TaskOutput"===e?!0===r.block?"Waiting for background task":"Checking background task":null},$o=e=>"mcp__upload-trace-proof__upload-trace-proof"===e||"mcp__auto-heal-report__upload-trace-proof"===e?"Upload Trace":"mcp__auto-heal-report__generate-report"===e?"Generate Report":(e=>{const t=Po[e];if(t)return t;const r=Co(e,So),n=Co(r,xo);return Ro(n)})(e),Do=(e,t)=>{if(t<=0)return 0;let r=t-1;for(;r>0&&/\s/.test(e[r]);)r--;for(;r>0&&!/\s/.test(e[r-1]);)r--;return r},No=(e,t)=>{if(t>=e.length)return e.length;let r=t;for(;r<e.length&&!/\s/.test(e[r]);)r++;for(;r<e.length&&/\s/.test(e[r]);)r++;return r},Oo=(e,t)=>{if(t<=0)return 0;const r=e.lastIndexOf("\n",t-1);return-1===r?0:r+1},Bo=(e,t)=>{const r=e.indexOf("\n",t);return-1===r?e.length:r};function jo(e){const t=e.split("\n");let r=!1;const n=[];for(const e of t){const t=e.trimStart();if(/^`{3,}[^`]*$/.test(t)){r=!r,n.push(Dr("muted",` ${"β".repeat(Math.max(0,Math.min((process.stdout.columns||80)-4,76)))}`));continue}if(r){n.push(`${Dr("muted"," β")} ${Dr("codeBlock",e)}`);continue}if(/^-{3,}\s*$/.test(t)){n.push(ne.dim("β".repeat(Math.min(process.stdout.columns||80,80))));continue}const s=e.match(/^(#{1,6})\s+(.+)$/);if(s){const e=s[1].length,t=Mo(s[2]);1===e?n.push(ne.bold(Dr("brand",t))):2===e?n.push(ne.bold(t)):n.push(ne.bold(ne.dim(t)));continue}const o=e.match(/^>\s*(.*)$/);if(o){n.push(ne.dim(`β ${Mo(o[1])}`));continue}const i=e.match(/^(\s*)[-*]\s+(.+)$/);if(i){const e=i[1]||"";n.push(`${e} β ${Mo(i[2])}`);continue}const a=e.match(/^(\s*)(\d+)\.\s+(.+)$/);if(a){const e=a[1]||"";n.push(`${e} ${a[2]}. ${Mo(a[3])}`);continue}n.push(Mo(e))}return n.join("\n")}function Mo(e){return(e=(e=(e=e.replace(/\*\*(.+?)\*\*/g,(e,t)=>ne.bold(t))).replace(/__(.+?)__/g,(e,t)=>ne.bold(t))).replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g,(e,t)=>ne.italic(t))).replace(/`([^`]+)`/g,(e,t)=>Dr("inlineCode",t))}var Fo,Ho=async(e,t)=>{const{Box:r,Static:n,Text:s,render:o,useInput:i}=await import("ink"),a=!!process.stdin.isTTY,c="vscode"!==process.env.TERM_PROGRAM,l=["β ","β ","β Ή","β Έ","β Ό","β ΄","β ¦","β §","β ","β "],u=()=>xe(s,{inverse:!0,children:" "}),d=(({Box:e,Text:t,useInput:r},n,s)=>function({onChoice:o,prompt:i}){const[a,c]=Ie(0),[l,u]=Ie(!1),[d,p]=Ie(""),f=[{label:"Yes, allow this once",value:"allow"},{label:"Yes, always allow for this session",value:"always"},{label:"No, tell AI what to do differently",value:"deny_with_message"}];r((e,t)=>{if(l)return t.return?void o("deny_with_message",d||"User denied this action"):t.escape?(u(!1),void p("")):t.backspace||t.delete?void p(e=>e.slice(0,-1)):void(t.ctrl||t.meta||p(t=>`${t}${e}`));if(t.upArrow)return void c(e=>e>0?e-1:f.length-1);if(t.downArrow)return void c(e=>e<f.length-1?e+1:0);if(t.return){const e=f[a];return"deny_with_message"===e.value?void u(!0):void o(e.value)}const r=parseInt(e,10);if(r>=1&&r<=f.length){const e=f[r-1];if("deny_with_message"===e.value)return void u(!0);o(e.value)}},{isActive:s});const h=$o(i.toolName),g=Uo(i.toolName,i.input);return Ae(e,{borderColor:$r("accent"),borderStyle:"round",flexDirection:"column",marginTop:1,paddingX:1,paddingY:0,children:[xe(t,{bold:!0,color:$r("accent"),children:"Permission Required"}),Ae(e,{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),dimColor:!0,children:h}),null!=g&&Ae(t,{color:$r("muted"),children:[" ",g]})]}),null!=i.decisionReason&&xe(e,{marginTop:1,children:Ae(t,{color:$r("muted"),children:["Reason: ",i.decisionReason]})}),Ae(e,l?{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),children:"Enter message for AI (press Enter to submit, Esc to cancel):"}),Ae(t,{children:[xe(t,{color:$r("accent"),children:"β―"})," ",d,xe(n,{})]})]}:{flexDirection:"column",marginTop:1,children:[xe(t,{color:$r("muted"),children:"Use ββ arrows or number keys to select:"}),f.map((e,r)=>xe(t,{children:Ae(t,{color:r===a?$r("accent"):void 0,children:[r===a?"β―":" "," ",r+1,". ",e.label]})},e.value))]})]})})({Box:r,Text:s,useInput:i},u,a),p=(({Cursor:e,inkComponents:{Box:t,Static:r,Text:n,useInput:s},isRawModeSupported:o,PermissionPrompt:i,Spinner:a})=>{const c="vscode"!==process.env.TERM_PROGRAM,l=e=>"tool"===e.kind?Ae(n,{color:$r("subtle"),children:["β¦ ",e.content]},e.id):"tool_result"===e.kind||"text"===e.kind?xe(n,{color:$r("muted"),children:e.content},e.id):null,u=({progress:e})=>{const[r,s]=Ie(Date.now());_e(()=>{if(!c)return;const e=setInterval(()=>s(Date.now()),1e3);return()=>clearInterval(e)},[]);const o=r-e.startedAt,i=Math.floor(o/1e3),a=Math.floor(i/60),l=i%60,u=a>0?`${a}m ${l.toString().padStart(2,"0")}s`:`${l}s`,d={initializing:{label:"Fetching test results",color:$r("muted")},triage:{label:"Triaging failures",color:$r("fixTriage")},fixing:{label:"Fixing tests",color:$r("brand")},debugging:{label:"Debugging tests",color:$r("fixDebug")},validation:{label:"Validating fixes",color:$r("fixValidation")},complete:{label:"Complete",color:$r("success")}},{label:p,color:f}=d[e.phase],h=e.fixedTests+e.failedTests,g=("fixing"===e.phase||"debugging"===e.phase)&&h>0?null!==e.totalTests?` (fixed ${e.fixedTests}/${e.totalTests}${e.failedTests>0?`, failed ${e.failedTests}`:""})`:` (fixed ${e.fixedTests}${e.failedTests>0?`, failed ${e.failedTests}`:""})`:"";return xe(t,{flexDirection:"column",children:Ae(n,{children:[xe(n,{color:f,bold:!0,children:p}),xe(n,{color:$r("muted"),children:g}),Ae(n,{color:$r("muted"),children:[" [",u,"]"]})]})})},d=({progress:e})=>{const r=e.endedAt??Date.now(),s=Math.floor((r-e.startedAt)/1e3),o=Math.floor(s/60),i=s%60,a=o>0?`${o}m ${i.toString().padStart(2,"0")}s`:`${i}s`,c=e.isError?$r("accent"):$r("success"),l=e.isError?"Fix stopped":"Fix complete";return Ae(t,{flexDirection:"column",children:[Ae(n,{color:c,bold:!0,children:[l," in ",a]}),null!==e.totalTests&&Ae(n,{color:$r("muted"),children:[e.fixedTests,"/",e.totalTests," tests fixed",e.failedTests>0?`, ${e.failedTests} failed`:""]})]})},p=(e,r=!1,s)=>{if("subagent"===e.kind&&e.subagent){const{subagent:s}=e,o="complete"===s.status?$r("success"):"error"===s.status?$r("error"):$r("accent");return Ae(t,{flexDirection:"column",marginTop:1,children:[Ae(n,{children:[xe(n,{color:o,bold:!0,children:"Agent"}),s.description?Ae(n,{color:$r("muted"),children:[" (",s.description,")"]}):null]}),s.activities.length>0&&xe(t,{flexDirection:"column",marginLeft:2,children:(()=>{if(!r)return s.activities.map(e=>l(e));let e=0;const t=[];for(let r=s.activities.length-1;r>=0;r--){const n=s.activities[r];"tool"!==n.kind&&"tool_result"!==n.kind||("tool"===n.kind&&e++,e<=f&&t.unshift(n))}return t.map(e=>l(e))})()})]},e.id)}if("tool"===e.kind)return Ae(n,{color:$r("subtle"),children:["β¦ ",e.content]},e.id);if("tool_result"===e.kind)return xe(n,{color:$r("muted"),children:e.content},e.id);if("user"===e.kind)return xe(t,{marginTop:1,children:Ae(n,{color:$r("userPrompt"),children:["You: ",e.content]})},e.id);const o="text"===e.kind&&("tool"===s||"tool_result"===s);if("thinking"===e.kind){const r=e.content.split("\n"),s=10,o=r.length>s?r.slice(-s):r;return xe(t,{flexDirection:"column",children:xe(n,{color:$r("subtle"),children:o.join("\n")})},e.id)}return"cancelled"===e.kind?xe(n,{color:$r("subtle"),children:e.content},e.id):"text"===e.kind?xe(t,{marginTop:o?1:0,children:xe(n,{children:jo(e.content)})},e.id):xe(t,{children:xe(n,{children:e.content})},e.id)},f=3;return function({onCancel:c,onExit:l,onPermissionChoice:h,onSend:g,showSpinnerImmediately:m,state:y}){const[b,w]=Ie({value:"",cursor:0}),v=b.value,I=b.cursor,T=Te(!1),_=Te(void 0),[E,S]=Ie(!1),[x,A]=Ie(!1),k=Te(0),P=Te(!1),C=!!y.permissionPrompt,R=(({termProgram:e})=>"vscode"===e)({termProgram:process.env.TERM_PROGRAM}),U=y.log.at(-1),L=("text"===U?.kind||"thinking"===U?.kind)&&"running"===y.status,$=y.log.findIndex(e=>"subagent"===e.kind&&"running"===e.subagent?.status),D=-1!==$,N=y.activeThinkingLogIndex??-1,O=N>=0&&N<y.log.length-1,B=o&&!x,j=R?0:D?$:O?N:L?y.log.length-1:y.log.length,M=y.preserveLiveLog?k.current:B&&"running"===y.status?Math.min(j,k.current):j;_e(()=>{y.log.length<k.current&&(k.current=0),M>k.current&&(k.current=M)},[y.log.length,M]);const F=y.log.slice(0,k.current),H=y.log.slice(k.current),G=B?F.filter(e=>"tool"!==e.kind&&"tool_result"!==e.kind&&"thinking"!==e.kind):F,W=(()=>{if(!B)return H;let e=0;const t=[];for(let r=H.length-1;r>=0;r--){const n=H[r];"tool"===n.kind||"tool_result"===n.kind||"thinking"===n.kind?("tool"===n.kind&&e++,e<=f&&t.unshift(n)):t.unshift(n)}return t})(),V=Ee(async()=>{T.current?(_.current&&clearTimeout(_.current),await(l?.()),process.exit(0)):(T.current=!0,S(!0),_.current=setTimeout(()=>{T.current=!1,S(!1)},2e3))},[l]);s((e,t)=>{t.ctrl&&"c"===e&&V().catch(()=>process.exit(1)),t.ctrl&&"o"===e&&A(e=>!e),t.escape&&"running"===y.status&&!C&&0===v.length&&c?.()},{isActive:o}),_e(()=>{if(C||!g)return;process.stdout.isTTY&&process.stdout.write("[?2004h");const e=e=>{const t=e.replace(/\r\n/g,"\n").replace(/\r/g,"\n");t&&w(e=>({value:e.value.slice(0,e.cursor)+t+e.value.slice(e.cursor),cursor:e.cursor+t.length}))},t=t=>{const r=t.toString();if(r.includes("[200~")){P.current=!0;const t=r.slice(r.indexOf("[200~")+6),n=t.includes("[201~"),s=n?t.slice(0,t.indexOf("[201~")):t;return e(s),void(n&&setTimeout(()=>{P.current=!1},0))}if(r.includes("[201~")){const t=r.slice(0,r.indexOf("[201~"));return e(t),void setTimeout(()=>{P.current=!1},0)}P.current?e(r):"[1;5H"!==r&&"[1;5~"!==r?"[1;5F"!==r&&"[4;5~"!==r?"[H"!==r&&"[1~"!==r&&"OH"!==r&&"[7~"!==r?"[F"!==r&&"[4~"!==r&&"OF"!==r&&"[8~"!==r||w(e=>({...e,cursor:Bo(e.value,e.cursor)})):w(e=>({...e,cursor:Oo(e.value,e.cursor)})):w(e=>({...e,cursor:e.value.length})):w(e=>({...e,cursor:0}))};return process.stdin.on("data",t),()=>{process.stdin.off("data",t),process.stdout.isTTY&&process.stdout.write("[?2004l")}},[C,g]),s((e,t)=>{if(!t.ctrl||"c"!==e){if(t.return){if(P.current)return;const e=v.trim();return e&&g?.(e),void w({value:"",cursor:0})}t.ctrl&&"w"===e||t.ctrl&&t.backspace?w(e=>{const t=Do(e.value,e.cursor);return{value:e.value.slice(0,t)+e.value.slice(e.cursor),cursor:t}}):!t.backspace&&!t.delete||t.ctrl?t.ctrl&&t.leftArrow||t.meta&&"b"===e?w(e=>({...e,cursor:Do(e.value,e.cursor)})):t.ctrl&&t.rightArrow||t.meta&&"f"===e?w(e=>({...e,cursor:No(e.value,e.cursor)})):t.leftArrow?w(e=>({...e,cursor:Math.max(0,e.cursor-1)})):t.rightArrow?w(e=>({...e,cursor:Math.min(e.value.length,e.cursor+1)})):t.ctrl&&"a"===e?w(e=>({...e,cursor:Oo(e.value,e.cursor)})):t.ctrl&&"e"===e?w(e=>({...e,cursor:Bo(e.value,e.cursor)})):t.escape&&v.length>0?w({value:"",cursor:0}):!e||t.ctrl||t.meta||t.escape||e.includes("")||/^\[./.test(e)||/^O[A-D]$/.test(e)||P.current||w(t=>({value:t.value.slice(0,t.cursor)+e+t.value.slice(t.cursor),cursor:t.cursor+e.length})):w(e=>e.cursor>0?{value:e.value.slice(0,e.cursor-1)+e.value.slice(e.cursor),cursor:e.cursor-1}:e)}},{isActive:o&&!!g&&!C});const Y=Se(()=>"running"===y.status?xe(a,{label:y.runningLabel??"Working"}):"success"!==y.status?xe(n,{color:$r("error"),children:"β Failed"}):void 0,[y.runningLabel,y.status]),z=!(m||!g||"running"!==y.status||0!==y.log.length||y.resultText||y.errorText),q="running"===y.status&&!z||y.resultText||y.errorText||"error"===y.status;return Ae(t,{flexDirection:"column",children:[R?Ae(t,{flexDirection:"column",flexShrink:0,children:[xe(n,{color:$r("brand"),bold:!0,children:"Stably Agent"}),xe(t,{flexDirection:"column",marginTop:1,children:xe(n,{color:$r("muted"),children:y.promptDisplay})})]}):xe(r,{items:["header"],children:()=>Ae(t,{flexDirection:"column",flexShrink:0,children:[xe(n,{color:$r("brand"),bold:!0,children:"Stably Agent"}),xe(t,{flexDirection:"column",marginTop:1,children:xe(n,{color:$r("muted"),children:y.promptDisplay})})]},"header")}),G.length>0&&xe(r,{items:G,children:(e,t)=>p(e,B,G[t-1]?.kind)}),W.length>0&&xe(t,{flexDirection:"column",children:W.map((e,t)=>{const r=t>0?W[t-1]?.kind:G.at(-1)?.kind;return p(e,B,r)})}),B&&H.length>W.length&&Ae(n,{color:$r("subtle"),dimColor:!0,children:["β ",H.length-W.length," tool calls hidden (Ctrl+O to expand)"]}),x&&o&&xe(n,{color:$r("subtle"),dimColor:!0,children:"β Showing all tool calls (Ctrl+O to collapse)"}),"error"===y.status&&y.errorText&&xe(t,{marginTop:1,children:xe(n,{color:$r("error"),children:y.errorText})}),"success"===y.status&&y.resultText&&xe(t,{marginTop:1,children:xe(n,{children:y.resultText})}),q&&xe(t,{flexDirection:"column",flexShrink:0,marginTop:1,children:"running"===y.status&&y.fixProgress?Ae(t,{flexDirection:"column",children:[Ae(t,{children:[xe(a,{}),xe(n,{children:" "}),xe(u,{progress:y.fixProgress})]}),("fixing"===y.fixProgress.phase||"debugging"===y.fixProgress.phase)&&y.log.flatMap(e=>{const{subagent:r}=e;if("subagent"!==e.kind||"code-worker"!==r?.subagentType&&"browser-worker"!==r?.subagentType||"running"!==r.status)return[];const{activities:s}=r,o=s.filter(e=>"tool"===e.kind).length,i=s.at(-1),c=s.filter(e=>"tool"===e.kind).at(-1),l=(()=>{if(!i)return null;if("tool"===i.kind)return null;if("text"===i.kind){const e=i.content.trim().split("\n").at(-1)?.trim();return e?e.length>80?`${e.slice(0,80)}β¦`:e:null}if("tool_result"===i.kind){const e=i.content.trim().split("\n")[0]?.trim();return e?e.length>80?`${e.slice(0,80)}β¦`:e:null}return null})();return Ae(t,{flexDirection:"column",children:[Ae(n,{children:[" ",xe(a,{}),Ae(n,{color:$r("muted"),children:[r.description||r.subagentType||"worker",o>0?` (${o} ${1===o?"cycle":"cycles"})`:""]})]}),c&&Ae(n,{color:$r("subtle"),children:[" β¦ ",c.content]}),l&&Ae(n,{color:$r("subtle"),children:[" ",l]})]},e.id)})]}):"success"!==y.status&&"error"!==y.status||!y.fixProgress?Y:xe(d,{progress:y.fixProgress})}),null!=y.permissionPrompt&&null!=h&&xe(i,{onChoice:h,prompt:y.permissionPrompt}),null!=g&&null==y.permissionPrompt&&!y.isExiting&&Ae(t,{borderColor:"gray",borderStyle:"round",flexDirection:"column",flexShrink:0,marginTop:1,paddingX:1,paddingY:0,children:[xe(n,{color:$r("subtle"),children:"Type a message and press Enter. Press Escape to interrupt. Press Ctrl+C to exit."}),Ae(n,{children:[xe(n,{color:$r("accent"),children:"β―"})," ",v.slice(0,I),xe(e,{}),v.slice(I)]})]}),E&&Ae(t,{marginTop:1,flexDirection:"column",children:[xe(n,{color:$r("accent"),children:"Press Ctrl+C again to exit"}),Xn&&Ae(n,{color:$r("subtle"),children:["Debug log: ",ts]})]})]})}})({Cursor:u,inkComponents:{Box:r,Static:n,Text:s,useInput:i},isInitMode:t?.isInitMode,isRawModeSupported:a,PermissionPrompt:d,Spinner:({label:e})=>{const[t,r]=Ie(0);return _e(()=>{if(!c)return;const e=setInterval(()=>r(e=>(e+1)%l.length),80);return()=>clearInterval(e)},[]),Ae(s,{color:$r("accent"),children:[l[t]," ",e]})}});let f=e;t?.isFixMode&&(f.fixProgress={phase:"initializing",totalTests:null,fixedTests:0,failedTests:0,currentTestDescription:null,lastTestDescription:null,startedAt:Date.now(),endedAt:null,isError:!1});const h={current:(e,t)=>{}},g=o(xe(p,{onCancel:t?.onCancel,onExit:t?.onExit,onPermissionChoice:(e,t)=>h.current(e,t),onSend:t?.onSend,showSpinnerImmediately:t?.showSpinnerImmediately,state:f}),{exitOnCtrlC:!1}),m=()=>{f={...f},g.rerender(xe(p,{onCancel:t?.onCancel,onExit:t?.onExit,onPermissionChoice:(e,t)=>h.current(e,t),onSend:t?.onSend,showSpinnerImmediately:t?.showSpinnerImmediately,state:f}))};let y=null;const b=()=>{y&&(clearTimeout(y),y=null),f.log=[...f.log],m()};let w=null;const v=({text:e})=>{e&&(f.preserveLiveLog=!1,f.log=[...f.log,{content:e,id:f.log.length,kind:"user"}],m())},I=new Map;return{addSubagentActivity:({toolUseId:e,kind:t,content:r})=>{f.preserveLiveLog=!1;const n=I.get(e);if(void 0===n)return void console.error("[addSubagentActivity] No entry index for toolUseId:",e);const s=f.log[n];if("subagent"===s?.kind&&s.subagent){if("text"===t){const e=s.subagent.activities.at(-1);"text"===e?.kind?e.content+=r:s.subagent.activities.push({id:s.subagent.activities.length,kind:"text",content:r.replace(/^\s*\n+/,"")})}else s.subagent.activities.push({id:s.subagent.activities.length,kind:t,content:r});f.log=[...f.log],m()}else console.error("[addSubagentActivity] Entry not found or not subagent:",{entryIndex:n,entryKind:s?.kind})},addSubagentStart:({toolUseId:e,subagentType:t,description:r})=>{f.preserveLiveLog=!1;const n=f.log.length;if(I.set(e,n),f.log=[...f.log,{content:"",id:n,kind:"subagent",subagent:{toolUseId:e,subagentType:t,description:r,status:"running",activities:[]}}],f.fixProgress)if("triage"===t&&"initializing"===f.fixProgress.phase)f.fixProgress={...f.fixProgress,phase:"triage"};else if("code-worker"===t){const e=(f.fixProgress.totalTests??0)+1,t=r||null;f.fixProgress={...f.fixProgress,phase:"fixing",totalTests:e,currentTestDescription:t,lastTestDescription:t??f.fixProgress.lastTestDescription}}else if("browser-worker"===t){const e=(f.fixProgress.totalTests??0)+1,t=r||null;f.fixProgress={...f.fixProgress,phase:"debugging",totalTests:e,currentTestDescription:t,lastTestDescription:t??f.fixProgress.lastTestDescription}}else"validation"===t?f.fixProgress={...f.fixProgress,phase:"validation",currentTestDescription:null}:"context"===t&&(f.fixProgress={...f.fixProgress,currentTestDescription:r||f.fixProgress.currentTestDescription});m()},addTool:({rawName:e,toolInput:t})=>{f.preserveLiveLog=!1;const r=Lo(e,t),n=r??$o(e),s=r?void 0:Uo(e,t),o=s?`${n} (${s})`:n;f.log=[...f.log,{content:o,id:f.log.length,kind:"tool"}],m()},addToolResult:({message:e})=>{f.preserveLiveLog=!1,f.log=[...f.log,{content:e,id:f.log.length,kind:"tool_result"}],m()},appendCancelled:()=>{f.preserveLiveLog=!0,f.log=[...f.log,{content:"[Cancelled]",id:f.log.length,kind:"cancelled"}],m()},appendText:({text:e})=>{if(!e)return;f.preserveLiveLog=!1;const t=f.log.at(-1),r="text"!==t?.kind?e.replace(/^\s*\n+/,""):e;f.log="text"===t?.kind?[...f.log.slice(0,-1),{...t,content:`${t.content}${r}`}]:[...f.log,{content:r,id:f.log.length,kind:"text"}],m()},appendThinking:({text:e,forceNewBlock:t})=>{if(!e)return;f.preserveLiveLog=!1;const r=null!==w?f.log[w]:null;"thinking"!==r?.kind||t?(w=f.log.length,f.log=[...f.log,{content:e,id:f.log.length,kind:"thinking"}]):r.content+=e,f.activeThinkingLogIndex=w,y||(y=setTimeout(b,50))},appendUserMessage:v,cancelThinkingRender:()=>{y&&(clearTimeout(y),y=null)},cleanup:async()=>{const e=g.waitUntilExit();g.unmount(),await e},dismissPermissionPrompt:()=>{f.permissionPrompt&&(f.permissionPrompt.resolve({behavior:"deny",message:"Cancelled by user",interrupt:!0}),f.permissionPrompt=void 0,m())},flushThinkingRender:b,resetThinkingLogIndex:()=>{w=null,f.activeThinkingLogIndex=null},setExiting:()=>{f.isExiting=!0,m()},setRunningLabel:({label:e})=>{f.runningLabel=e,m()},setStatus:({error:e,result:t,status:r})=>{f.errorText=e,f.resultText=t,f.status=r,"running"===r&&(f.preserveLiveLog=!1),m()},setSubagentStatus:({toolUseId:e,status:t})=>{f.preserveLiveLog=!1;const r=I.get(e);if(void 0===r)return;const n=f.log[r];"subagent"===n?.kind&&n.subagent&&(n.subagent.status=t,!f.fixProgress||"code-worker"!==n.subagent.subagentType&&"browser-worker"!==n.subagent.subagentType||("complete"===t?f.fixProgress={...f.fixProgress,fixedTests:f.fixProgress.fixedTests+1,currentTestDescription:null}:"error"===t&&(f.fixProgress={...f.fixProgress,failedTests:f.fixProgress.failedTests+1,currentTestDescription:null})),f.log=[...f.log],m(),"complete"!==t&&"error"!==t||I.delete(e))},showPermissionPrompt:e=>new Promise(t=>{h.current=(r,n)=>{if(f.permissionPrompt=void 0,m(),"allow"===r)t({behavior:"allow",updatedInput:e.input});else if("always"===r)t({behavior:"allow",updatedInput:e.input,updatedPermissions:e.suggestions});else{const e=n??"User denied this action";v({text:e}),t({behavior:"deny",message:e,interrupt:!1})}},f.permissionPrompt={...e,resolve:t},m()}),updateFixProgress:t?.isFixMode?e=>{f.fixProgress&&(f.fixProgress={...f.fixProgress,...e},m())}:void 0}},{zMarkdownAutoHealReport:Go,zRepresentativeTest:Wo}=function(e){const t=e.enum(Ar),r=["Classification of the root cause:","",`- test: ${Cr("test")}`,`- bug: ${Cr("bug")}`,`- flake: ${Cr("flake")}`,`- ui_change: ${Cr("ui_change")}`,`- other: ${Cr("other")}`].join("\n"),n=e.object({filePath:e.string().optional(),testIdentifier:e.string().optional(),testTitle:e.string().optional()}),s=e.object({status:e.enum(kr),representativeTest:n,storage:e.object({bucket:e.string(),key:e.string()}).optional(),signedUrl:e.string().optional(),error:e.string().optional(),testPassed:e.boolean().optional(),testExitCode:e.number().nullable().optional(),testStderr:e.string().optional()}),o=s.extend({testCaseId:e.string().min(1).describe("Test case ID this trace proof corresponds to.")}),i=e.object({erroredUrl:e.string().optional(),issueType:t.describe(r),relatedTestCaseIds:e.array(e.string()).min(1).describe("List of ALL test case IDs impacted by this root cause (must be existing IDs only)."),rootCause:e.string().describe("Brief explanation of what happened (1-2 sentences). Include file:line references (e.g., `src/tests/login.spec.ts:42`) to back up your claim."),traceProofs:e.array(o).min(1).optional().describe("Per-test trace proofs for each testCaseId in this issue.")}),a=e.discriminatedUnion("result",[i.extend({fixApplied:e.string().describe("What fix was applied (brief, specific). Include file:line references (e.g., `src/tests/login.spec.ts:42`) showing where changes were made."),result:e.literal("fixed"),traceProof:s.optional()}),i.extend({followUpActions:e.string().optional().describe("Optional list of follow-up actions for any unfixed issues or missing data."),reasonNotFixed:e.string().describe("Why it could not be auto-fixed (brief). Include file:line references (e.g., `src/tests/login.spec.ts:42`) pointing to the problematic code."),result:e.literal("unfixed")})]),c=e.object({issues:e.array(a).min(1).describe("List of all auto-heal issues/outcomes for this suite."),summary:e.string().min(3).describe("High-level summary (2-3 sentences) of the suite auto-heal results.")}),l=e.discriminatedUnion("result",[e.object({result:e.literal("fixed"),issueType:t,issueId:e.string().optional().describe("Issue ID from triage, used for deterministic fingerprinting across re-uploads."),rootCause:e.string().min(1),fixApplied:e.string().min(1).describe("What fix was applied (brief, specific). Include file:line references."),relatedTestCaseIds:e.array(e.string()).min(1)}),e.object({result:e.literal("unfixed"),issueType:t,issueId:e.string().optional().describe("Issue ID from triage, used for deterministic fingerprinting across re-uploads."),rootCause:e.string().min(1),reasonNotFixed:e.string().min(1).describe("Why it could not be auto-fixed (brief). Include file:line references."),relatedTestCaseIds:e.array(e.string()).min(1)})]),u=e.object({format:e.literal("markdown"),markdown:e.string().min(1).describe("Flexible markdown report content for the auto-heal run. Use headings, bullets, and code fences as needed."),summary:e.string().optional().describe('One-liner summary of the auto-heal run (e.g., "Fixed 2 of 3 issues: stale locators and timing"). Used in notifications, API responses, and triage agent context.'),issues:e.array(l).optional().describe("Structured issue metadata for database tracking. Each issue links a root cause to affected test case IDs.")});return{zAutoHealReport:a,zIssueCategory:t,zMarkdownAutoHealReport:u,zMarkdownAutoHealReportIssue:l,zRepresentativeTest:n,zSuiteAutoHealReport:c,zStoredAutoHealReport:e.union([u,c]),zTraceProof:s,zTraceProofByTest:o}}(we),Vo=ke("/");try{Fo=Vo("worker_threads").Worker}catch(e){}var Yo=Fo?function(e,t,r,n,s){var o=!1,i=new Fo(e+";var __w=require('worker_threads');__w.parentPort.on('message',function(m){onmessage({data:m})}),postMessage=function(m,t){__w.parentPort.postMessage(m,t)},close=process.exit;self=global",{eval:!0}).on("error",function(e){return s(e,null)}).on("message",function(e){return s(null,e)}).on("exit",function(e){e&&!o&&s(new Error("exited with code "+e),null)});return i.postMessage(r,n),i.terminate=function(){return o=!0,Fo.prototype.terminate.call(i)},i}:function(e,t,r,n,s){setImmediate(function(){return s(new Error("async operations unsupported - update to Node 12+ (or Node 10-11 with the --experimental-worker CLI flag)"),null)});var o=function(){};return{terminate:o,postMessage:o}},zo=Uint8Array,qo=Uint16Array,Ko=Int32Array,Jo=new zo([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Xo=new zo([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Qo=new zo([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Zo=function(e,t){for(var r=new qo(31),n=0;n<31;++n)r[n]=t+=1<<e[n-1];var s=new Ko(r[30]);for(n=1;n<30;++n)for(var o=r[n];o<r[n+1];++o)s[o]=o-r[n]<<5|n;return{b:r,r:s}},ei=Zo(Jo,2),ti=ei.b,ri=ei.r;ti[28]=258,ri[258]=28;var ni,si=Zo(Xo,0),oi=si.b,ii=si.r,ai=new qo(32768);for(ui=0;ui<32768;++ui)ni=(61680&(ni=(52428&(ni=(43690&ui)>>1|(21845&ui)<<1))>>2|(13107&ni)<<2))>>4|(3855&ni)<<4,ai[ui]=((65280&ni)>>8|(255&ni)<<8)>>1;var ci=function(e,t,r){for(var n=e.length,s=0,o=new qo(t);s<n;++s)e[s]&&++o[e[s]-1];var i,a=new qo(t);for(s=1;s<t;++s)a[s]=a[s-1]+o[s-1]<<1;if(r){i=new qo(1<<t);var c=15-t;for(s=0;s<n;++s)if(e[s])for(var l=s<<4|e[s],u=t-e[s],d=a[e[s]-1]++<<u,p=d|(1<<u)-1;d<=p;++d)i[ai[d]>>c]=l}else for(i=new qo(n),s=0;s<n;++s)e[s]&&(i[s]=ai[a[e[s]-1]++]>>15-e[s]);return i},li=new zo(288);for(ui=0;ui<144;++ui)li[ui]=8;for(ui=144;ui<256;++ui)li[ui]=9;for(ui=256;ui<280;++ui)li[ui]=7;for(ui=280;ui<288;++ui)li[ui]=8;var ui,di=new zo(32);for(ui=0;ui<32;++ui)di[ui]=5;var pi=ci(li,9,0),fi=ci(li,9,1),hi=ci(di,5,0),gi=ci(di,5,1),mi=function(e){for(var t=e[0],r=1;r<e.length;++r)e[r]>t&&(t=e[r]);return t},yi=function(e,t,r){var n=t/8|0;return(e[n]|e[n+1]<<8)>>(7&t)&r},bi=function(e,t){var r=t/8|0;return(e[r]|e[r+1]<<8|e[r+2]<<16)>>(7&t)},wi=function(e){return(e+7)/8|0},vi=function(e,t,r){return(null==t||t<0)&&(t=0),(null==r||r>e.length)&&(r=e.length),new zo(e.subarray(t,r))},Ii=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],Ti=function(e,t,r){var n=new Error(t||Ii[e]);if(n.code=e,Error.captureStackTrace&&Error.captureStackTrace(n,Ti),!r)throw n;return n},_i=function(e,t,r,n){var s=e.length,o=n?n.length:0;if(!s||t.f&&!t.l)return r||new zo(0);var i=!r,a=i||2!=t.i,c=t.i;i&&(r=new zo(3*s));var l=function(e){var t=r.length;if(e>t){var n=new zo(Math.max(2*t,e));n.set(r),r=n}},u=t.f||0,d=t.p||0,p=t.b||0,f=t.l,h=t.d,g=t.m,m=t.n,y=8*s;do{if(!f){u=yi(e,d,1);var b=yi(e,d+1,3);if(d+=3,!b){var w=e[(C=wi(d)+4)-4]|e[C-3]<<8,v=C+w;if(v>s){c&&Ti(0);break}a&&l(p+w),r.set(e.subarray(C,v),p),t.b=p+=w,t.p=d=8*v,t.f=u;continue}if(1==b)f=fi,h=gi,g=9,m=5;else if(2==b){var I=yi(e,d,31)+257,T=yi(e,d+10,15)+4,_=I+yi(e,d+5,31)+1;d+=14;for(var E=new zo(_),S=new zo(19),x=0;x<T;++x)S[Qo[x]]=yi(e,d+3*x,7);d+=3*T;var A=mi(S),k=(1<<A)-1,P=ci(S,A,1);for(x=0;x<_;){var C,R=P[yi(e,d,k)];if(d+=15&R,(C=R>>4)<16)E[x++]=C;else{var U=0,L=0;for(16==C?(L=3+yi(e,d,3),d+=2,U=E[x-1]):17==C?(L=3+yi(e,d,7),d+=3):18==C&&(L=11+yi(e,d,127),d+=7);L--;)E[x++]=U}}var $=E.subarray(0,I),D=E.subarray(I);g=mi($),m=mi(D),f=ci($,g,1),h=ci(D,m,1)}else Ti(1);if(d>y){c&&Ti(0);break}}a&&l(p+131072);for(var N=(1<<g)-1,O=(1<<m)-1,B=d;;B=d){var j=(U=f[bi(e,d)&N])>>4;if((d+=15&U)>y){c&&Ti(0);break}if(U||Ti(2),j<256)r[p++]=j;else{if(256==j){B=d,f=null;break}var M=j-254;if(j>264){var F=Jo[x=j-257];M=yi(e,d,(1<<F)-1)+ti[x],d+=F}var H=h[bi(e,d)&O],G=H>>4;if(H||Ti(3),d+=15&H,D=oi[G],G>3&&(F=Xo[G],D+=bi(e,d)&(1<<F)-1,d+=F),d>y){c&&Ti(0);break}a&&l(p+131072);var W=p+M;if(p<D){var V=o-D,Y=Math.min(D,W);for(V+p<0&&Ti(3);p<Y;++p)r[p]=n[V+p]}for(;p<W;++p)r[p]=r[p-D]}}t.l=f,t.p=B,t.b=p,t.f=u,f&&(u=1,t.m=g,t.d=h,t.n=m)}while(!u);return p!=r.length&&i?vi(r,0,p):r.subarray(0,p)},Ei=function(e,t,r){r<<=7&t;var n=t/8|0;e[n]|=r,e[n+1]|=r>>8},Si=function(e,t,r){r<<=7&t;var n=t/8|0;e[n]|=r,e[n+1]|=r>>8,e[n+2]|=r>>16},xi=function(e,t){for(var r=[],n=0;n<e.length;++n)e[n]&&r.push({s:n,f:e[n]});var s=r.length,o=r.slice();if(!s)return{t:Li,l:0};if(1==s){var i=new zo(r[0].s+1);return i[r[0].s]=1,{t:i,l:1}}r.sort(function(e,t){return e.f-t.f}),r.push({s:-1,f:25001});var a=r[0],c=r[1],l=0,u=1,d=2;for(r[0]={s:-1,f:a.f+c.f,l:a,r:c};u!=s-1;)a=r[r[l].f<r[d].f?l++:d++],c=r[l!=u&&r[l].f<r[d].f?l++:d++],r[u++]={s:-1,f:a.f+c.f,l:a,r:c};var p=o[0].s;for(n=1;n<s;++n)o[n].s>p&&(p=o[n].s);var f=new qo(p+1),h=Ai(r[u-1],f,0);if(h>t){n=0;var g=0,m=h-t,y=1<<m;for(o.sort(function(e,t){return f[t.s]-f[e.s]||e.f-t.f});n<s;++n){var b=o[n].s;if(!(f[b]>t))break;g+=y-(1<<h-f[b]),f[b]=t}for(g>>=m;g>0;){var w=o[n].s;f[w]<t?g-=1<<t-f[w]++-1:++n}for(;n>=0&&g;--n){var v=o[n].s;f[v]==t&&(--f[v],++g)}h=t}return{t:new zo(f),l:h}},Ai=function(e,t,r){return-1==e.s?Math.max(Ai(e.l,t,r+1),Ai(e.r,t,r+1)):t[e.s]=r},ki=function(e){for(var t=e.length;t&&!e[--t];);for(var r=new qo(++t),n=0,s=e[0],o=1,i=function(e){r[n++]=e},a=1;a<=t;++a)if(e[a]==s&&a!=t)++o;else{if(!s&&o>2){for(;o>138;o-=138)i(32754);o>2&&(i(o>10?o-11<<5|28690:o-3<<5|12305),o=0)}else if(o>3){for(i(s),--o;o>6;o-=6)i(8304);o>2&&(i(o-3<<5|8208),o=0)}for(;o--;)i(s);o=1,s=e[a]}return{c:r.subarray(0,n),n:t}},Pi=function(e,t){for(var r=0,n=0;n<t.length;++n)r+=e[n]*t[n];return r},Ci=function(e,t,r){var n=r.length,s=wi(t+2);e[s]=255&n,e[s+1]=n>>8,e[s+2]=255^e[s],e[s+3]=255^e[s+1];for(var o=0;o<n;++o)e[s+o+4]=r[o];return 8*(s+4+n)},Ri=function(e,t,r,n,s,o,i,a,c,l,u){Ei(t,u++,r),++s[256];for(var d=xi(s,15),p=d.t,f=d.l,h=xi(o,15),g=h.t,m=h.l,y=ki(p),b=y.c,w=y.n,v=ki(g),I=v.c,T=v.n,_=new qo(19),E=0;E<b.length;++E)++_[31&b[E]];for(E=0;E<I.length;++E)++_[31&I[E]];for(var S=xi(_,7),x=S.t,A=S.l,k=19;k>4&&!x[Qo[k-1]];--k);var P,C,R,U,L=l+5<<3,$=Pi(s,li)+Pi(o,di)+i,D=Pi(s,p)+Pi(o,g)+i+14+3*k+Pi(_,x)+2*_[16]+3*_[17]+7*_[18];if(c>=0&&L<=$&&L<=D)return Ci(t,u,e.subarray(c,c+l));if(Ei(t,u,1+(D<$)),u+=2,D<$){P=ci(p,f,0),C=p,R=ci(g,m,0),U=g;var N=ci(x,A,0);for(Ei(t,u,w-257),Ei(t,u+5,T-1),Ei(t,u+10,k-4),u+=14,E=0;E<k;++E)Ei(t,u+3*E,x[Qo[E]]);u+=3*k;for(var O=[b,I],B=0;B<2;++B){var j=O[B];for(E=0;E<j.length;++E){var M=31&j[E];Ei(t,u,N[M]),u+=x[M],M>15&&(Ei(t,u,j[E]>>5&127),u+=j[E]>>12)}}}else P=pi,C=li,R=hi,U=di;for(E=0;E<a;++E){var F=n[E];if(F>255){Si(t,u,P[257+(M=F>>18&31)]),u+=C[M+257],M>7&&(Ei(t,u,F>>23&31),u+=Jo[M]);var H=31&F;Si(t,u,R[H]),u+=U[H],H>3&&(Si(t,u,F>>5&8191),u+=Xo[H])}else Si(t,u,P[F]),u+=C[F]}return Si(t,u,P[256]),u+C[256]},Ui=new Ko([65540,131080,131088,131104,262176,1048704,1048832,2114560,2117632]),Li=new zo(0),$i=function(e,t,r,n,s,o){var i=o.z||e.length,a=new zo(n+i+5*(1+Math.ceil(i/7e3))+s),c=a.subarray(n,a.length-s),l=o.l,u=7&(o.r||0);if(t){u&&(c[0]=o.r>>3);for(var d=Ui[t-1],p=d>>13,f=8191&d,h=(1<<r)-1,g=o.p||new qo(32768),m=o.h||new qo(h+1),y=Math.ceil(r/3),b=2*y,w=function(t){return(e[t]^e[t+1]<<y^e[t+2]<<b)&h},v=new Ko(25e3),I=new qo(288),T=new qo(32),_=0,E=0,S=o.i||0,x=0,A=o.w||0,k=0;S+2<i;++S){var P=w(S),C=32767&S,R=m[P];if(g[C]=R,m[P]=C,A<=S){var U=i-S;if((_>7e3||x>24576)&&(U>423||!l)){u=Ri(e,c,0,v,I,T,E,x,k,S-k,u),x=_=E=0,k=S;for(var L=0;L<286;++L)I[L]=0;for(L=0;L<30;++L)T[L]=0}var $=2,D=0,N=f,O=C-R&32767;if(U>2&&P==w(S-O))for(var B=Math.min(p,U)-1,j=Math.min(32767,S),M=Math.min(258,U);O<=j&&--N&&C!=R;){if(e[S+$]==e[S+$-O]){for(var F=0;F<M&&e[S+F]==e[S+F-O];++F);if(F>$){if($=F,D=O,F>B)break;var H=Math.min(O,F-2),G=0;for(L=0;L<H;++L){var W=S-O+L&32767,V=W-g[W]&32767;V>G&&(G=V,R=W)}}}O+=(C=R)-(R=g[C])&32767}if(D){v[x++]=268435456|ri[$]<<18|ii[D];var Y=31&ri[$],z=31&ii[D];E+=Jo[Y]+Xo[z],++I[257+Y],++T[z],A=S+$,++_}else v[x++]=e[S],++I[e[S]]}}for(S=Math.max(S,A);S<i;++S)v[x++]=e[S],++I[e[S]];u=Ri(e,c,l,v,I,T,E,x,k,S-k,u),l||(o.r=7&u|c[u/8|0]<<3,u-=7,o.h=m,o.p=g,o.i=S,o.w=A)}else{for(S=o.w||0;S<i+l;S+=65535){var q=S+65535;q>=i&&(c[u/8|0]=l,q=i),u=Ci(c,u+1,e.subarray(S,q))}o.i=i}return vi(a,0,n+wi(u)+s)},Di=function(){for(var e=new Int32Array(256),t=0;t<256;++t){for(var r=t,n=9;--n;)r=(1&r&&-306674912)^r>>>1;e[t]=r}return e}(),Ni=function(e,t,r,n,s){if(!s&&(s={l:1},t.dictionary)){var o=t.dictionary.subarray(-32768),i=new zo(o.length+e.length);i.set(o),i.set(e,o.length),e=i,s.w=o.length}return $i(e,null==t.level?6:t.level,null==t.mem?s.l?Math.ceil(1.5*Math.max(8,Math.min(13,Math.log(e.length)))):20:12+t.mem,r,n,s)},Oi=function(e,t){var r={};for(var n in e)r[n]=e[n];for(var n in t)r[n]=t[n];return r},Bi=function(e,t,r){for(var n=e(),s=e.toString(),o=s.slice(s.indexOf("[")+1,s.lastIndexOf("]")).replace(/\s+/g,"").split(","),i=0;i<n.length;++i){var a=n[i],c=o[i];if("function"==typeof a){t+=";"+c+"=";var l=a.toString();if(a.prototype)if(-1!=l.indexOf("[native code]")){var u=l.indexOf(" ",8)+1;t+=l.slice(u,l.indexOf("(",u))}else for(var d in t+=l,a.prototype)t+=";"+c+".prototype."+d+"="+a.prototype[d].toString();else t+=l}else r[c]=a}return t},ji=[],Mi=function(){return[zo,qo,Ko,Jo,Xo,Qo,ti,oi,fi,gi,ai,Ii,ci,mi,yi,bi,wi,vi,Ti,_i,Ji,Hi,Gi]},Fi=function(){return[zo,qo,Ko,Jo,Xo,Qo,ri,ii,pi,li,hi,di,ai,Ui,Li,ci,Ei,Si,xi,Ai,ki,Pi,Ci,Ri,wi,vi,$i,Ni,Ki,Hi]},Hi=function(e){return postMessage(e,[e.buffer])},Gi=function(e){return e&&{out:e.size&&new zo(e.size),dictionary:e.dictionary}},Wi=function(e,t,r,n,s,o){var i=function(e,t,r,n){if(!ji[r]){for(var s="",o={},i=e.length-1,a=0;a<i;++a)s=Bi(e[a],s,o);ji[r]={c:Bi(e[i],s,o),e:o}}var c=Oi({},ji[r].e);return Yo(ji[r].c+";onmessage=function(e){for(var k in e.data)self[k]=e.data[k];onmessage="+t.toString()+"}",r,c,function(e){var t=[];for(var r in e)e[r].buffer&&t.push((e[r]=new e[r].constructor(e[r])).buffer);return t}(c),n)}(r,n,s,function(e,t){i.terminate(),o(e,t)});return i.postMessage([e,t],t.consume?[e.buffer]:[]),function(){i.terminate()}},Vi=function(e,t){return e[t]|e[t+1]<<8},Yi=function(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16|e[t+3]<<24)>>>0},zi=function(e,t){return Yi(e,t)+4294967296*Yi(e,t+4)},qi=function(e,t,r){for(;r;++t)e[t]=r,r>>>=8};function Ki(e,t){return Ni(e,t||{},0,0)}function Ji(e,t){return _i(e,{i:2},t&&t.out,t&&t.dictionary)}var Xi=function(e,t,r,n){for(var s in e){var o=e[s],i=t+s,a=n;Array.isArray(o)&&(a=Oi(n,o[1]),o=o[0]),o instanceof zo?r[i]=[o,a]:(r[i+="/"]=[new zo(0),a],Xi(o,i,r,n))}},Qi="undefined"!=typeof TextEncoder&&new TextEncoder,Zi="undefined"!=typeof TextDecoder&&new TextDecoder;try{Zi.decode(Li,{stream:!0})}catch(e){}function ea(e,t){if(Qi)return Qi.encode(e);for(var r=e.length,n=new zo(e.length+(e.length>>1)),s=0,o=function(e){n[s++]=e},i=0;i<r;++i){if(s+5>n.length){var a=new zo(s+8+(r-i<<1));a.set(n),n=a}var c=e.charCodeAt(i);c<128||t?o(c):c<2048?(o(192|c>>6),o(128|63&c)):c>55295&&c<57344?(o(240|(c=65536+(1047552&c)|1023&e.charCodeAt(++i))>>18),o(128|c>>12&63),o(128|c>>6&63),o(128|63&c)):(o(224|c>>12),o(128|c>>6&63),o(128|63&c))}return vi(n,0,s)}var ta=function(e){var t=0;if(e)for(var r in e){var n=e[r].length;n>65535&&Ti(9),t+=n+4}return t},ra=function(e,t,r,n,s,o,i,a){var c=n.length,l=r.extra,u=a&&a.length,d=ta(l);qi(e,t,null!=i?33639248:67324752),t+=4,null!=i&&(e[t++]=20,e[t++]=r.os),e[t]=20,t+=2,e[t++]=r.flag<<1|(o<0&&8),e[t++]=s&&8,e[t++]=255&r.compression,e[t++]=r.compression>>8;var p=new Date(null==r.mtime?Date.now():r.mtime),f=p.getFullYear()-1980;if((f<0||f>119)&&Ti(10),qi(e,t,f<<25|p.getMonth()+1<<21|p.getDate()<<16|p.getHours()<<11|p.getMinutes()<<5|p.getSeconds()>>1),t+=4,-1!=o&&(qi(e,t,r.crc),qi(e,t+4,o<0?-o-2:o),qi(e,t+8,r.size)),qi(e,t+12,c),qi(e,t+14,d),t+=16,null!=i&&(qi(e,t,u),qi(e,t+6,r.attrs),qi(e,t+10,i),t+=14),e.set(n,t),t+=c,d)for(var h in l){var g=l[h],m=g.length;qi(e,t,+h),qi(e,t+2,m),e.set(g,t+4),t+=4+m}return u&&(e.set(a,t),t+=u),t},na="function"==typeof queueMicrotask?queueMicrotask:"function"==typeof setTimeout?setTimeout:function(e){e()};function sa(e,t,r){const n=Math.min(t,512);if("utf-16"===r||"utf-16le"===r||"utf-16be"===r){for(let t=0;t<n;t+=2){const s=e[t],o=t+1<n?e[t+1]:0;if(("utf-16le"===r||"utf-16"===r)&&0===o&&s<32&&9!==s&&10!==s&&13!==s&&0!==s)return!1;if(("utf-16be"===r||"utf-16"===r)&&0===s&&o<32&&9!==o&&10!==o&&13!==o&&0!==o)return!1}return!0}if("latin1"===r||"iso-8859-1"===r){for(let t=0;t<n;t++){const r=e[t];if(0===r)return!1;if(r<32&&9!==r&&10!==r&&13!==r)return!1}return!0}if("cjk"===r||"big5"===r||"gb2312"===r||"gbk"===r||"euc-kr"===r||"shift-jis"===r){for(let t=0;t<n;t++){const r=e[t];if(0===r)return!1;if(r<32&&9!==r&&10!==r&&13!==r)return!1}return!0}return!1}var oa=class{fileBuffer;size;offset;error;constructor(e,t){this.fileBuffer=e,this.size=t,this.offset=0,this.error=!1}hasError(){return this.error}nextByte(){return this.offset===this.size||this.hasError()?(this.error=!0,255):this.fileBuffer[this.offset++]}next(e){if(e<0||e>this.size-this.offset)return this.error=!0,[];const t=new Array;for(let r=0;r<e;r++){if(this.error)return t;t[r]=this.nextByte()}return t}};function ia(e){let t=0,r=0;for(;!e.hasError();){const n=e.nextByte();if(r|=(127&n)<<7*t,!(128&n))break;if(t>=10){e.error=!0;break}t++}return r}function aa(e){switch(7&ia(e)){case 0:return ia(e),!0;case 1:return e.next(8),!0;case 2:const t=ia(e);return e.next(t),!0;case 5:return e.next(4),!0}return!1}function ca(e,t,r){if(0===t)return!1;let n=0;const s=Math.min(t,515),o=Math.min(s,512);if(t>=3&&239===e[0]&&187===e[1]&&191===e[2])return!1;if(t>=4&&0===e[0]&&0===e[1]&&254===e[2]&&255===e[3])return!1;if(t>=4&&255===e[0]&&254===e[1]&&0===e[2]&&0===e[3])return!1;if(t>=4&&132===e[0]&&49===e[1]&&149===e[2]&&51===e[3])return!1;if(s>=5&&"%PDF-"===e.slice(0,5).toString())return!0;if(t>=2&&254===e[0]&&255===e[1])return!1;if(t>=2&&255===e[0]&&254===e[1])return!1;if(r?.encoding)return!sa(e,t,r.encoding);const i=function(e,t){if(t<4)return null;const r=Math.min(t,512);let n=0,s=0;for(let t=0;t<r;t++)0===e[t]&&(t%2==0?n++:s++);const o=n+s;if(o>.3*r&&o<.7*r){if(s>3*n)return"utf-16le";if(n>3*s)return"utf-16be"}return null}(e,t);if(i)return!sa(e,t,i);for(let t=0;t<o;t++){if(0===e[t])return!0;if((e[t]<7||e[t]>14)&&(e[t]<32||e[t]>127)){if(e[t]>=192&&e[t]<=223&&t+1<s){if(t++,e[t]>=128&&e[t]<=191)continue}else if(e[t]>=224&&e[t]<=239&&t+2<s){if(t++,e[t]>=128&&e[t]<=191&&e[t+1]>=128&&e[t+1]<=191){t++;continue}}else if(e[t]>=240&&e[t]<=247&&t+3<s&&(t++,e[t]>=128&&e[t]<=191&&e[t+1]>=128&&e[t+1]<=191&&e[t+2]>=128&&e[t+2]<=191)){t+=2;continue}if(n++,t>=32&&100*n/o>10)return!0}}return 100*n/o>10||!!(n>1&&function(e,t){const r=new oa(e,t);let n=0;for(;;){if(!aa(r)&&!r.hasError())return!1;if(r.hasError())break;n++}return n>0}(e,o))}var la=[/^\/$/,/^\*+$/,/^[0-9]+$/],ua=["/artifact/","https://","http://","*********"],da=Symbol.for("@ts-pattern/matcher"),pa=Symbol.for("@ts-pattern/isVariadic"),fa="@ts-pattern/anonymous-select-key",ha=e=>Boolean(e&&"object"==typeof e),ga=e=>e&&!!e[da],ma=(e,t,r)=>{if(ga(e)){const n=e[da](),{matched:s,selections:o}=n.match(t);return s&&o&&Object.keys(o).forEach(e=>r(e,o[e])),s}if(ha(e)){if(!ha(t))return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=[],s=[],o=[];for(const t of e.keys()){const r=e[t];ga(r)&&r[pa]?o.push(r):o.length?s.push(r):n.push(r)}if(o.length){if(o.length>1)throw new Error("Pattern error: Using `...P.array(...)` several times in a single pattern is not allowed.");if(t.length<n.length+s.length)return!1;const e=t.slice(0,n.length),i=0===s.length?[]:t.slice(-s.length),a=t.slice(n.length,0===s.length?1/0:-s.length);return n.every((t,n)=>ma(t,e[n],r))&&s.every((e,t)=>ma(e,i[t],r))&&(0===o.length||ma(o[0],a,r))}return e.length===t.length&&e.every((e,n)=>ma(e,t[n],r))}return Reflect.ownKeys(e).every(n=>{const s=e[n];return(n in t||ga(o=s)&&"optional"===o[da]().matcherType)&&ma(s,t[n],r);var o})}return Object.is(t,e)},ya=e=>{var t,r,n;return ha(e)?ga(e)?null!=(t=null==(r=(n=e[da]()).getSelectionKeys)?void 0:r.call(n))?t:[]:Array.isArray(e)?ba(e,ya):ba(Object.values(e),ya):[]},ba=(e,t)=>e.reduce((e,r)=>e.concat(t(r)),[]);function wa(e){return Object.assign(e,{optional:()=>{return t=e,wa({[da]:()=>({match:e=>{let r={};const n=(e,t)=>{r[e]=t};return void 0===e?(ya(t).forEach(e=>n(e,void 0)),{matched:!0,selections:r}):{matched:ma(t,e,n),selections:r}},getSelectionKeys:()=>ya(t),matcherType:"optional"})});var t},and:t=>va(e,t),or:t=>function(...e){return wa({[da]:()=>({match:t=>{let r={};const n=(e,t)=>{r[e]=t};return ba(e,ya).forEach(e=>n(e,void 0)),{matched:e.some(e=>ma(e,t,n)),selections:r}},getSelectionKeys:()=>ba(e,ya),matcherType:"or"})})}(e,t),select:t=>void 0===t?Ta(e):Ta(t,e)})}function va(...e){return wa({[da]:()=>({match:t=>{let r={};const n=(e,t)=>{r[e]=t};return{matched:e.every(e=>ma(e,t,n)),selections:r}},getSelectionKeys:()=>ba(e,ya),matcherType:"and"})})}function Ia(e){return{[da]:()=>({match:t=>({matched:Boolean(e(t))})})}}function Ta(...e){const t="string"==typeof e[0]?e[0]:void 0,r=2===e.length?e[1]:"string"==typeof e[0]?void 0:e[0];return wa({[da]:()=>({match:e=>{let n={[null!=t?t:fa]:e};return{matched:void 0===r||ma(r,e,(e,t)=>{n[e]=t}),selections:n}},getSelectionKeys:()=>[null!=t?t:fa].concat(void 0===r?[]:ya(r))})})}function _a(e){return!0}function Ea(e){return"number"==typeof e}function Sa(e){return"string"==typeof e}function xa(e){return"bigint"==typeof e}wa(Ia(_a)),wa(Ia(_a));var Aa=e=>Object.assign(wa(e),{startsWith:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.startsWith(r)))));var r},endsWith:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.endsWith(r)))));var r},minLength:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length>=r))));var r},length:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length===r))));var r},maxLength:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.length<=r))));var r},includes:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&e.includes(r)))));var r},regex:t=>{return Aa(va(e,(r=t,Ia(e=>Sa(e)&&Boolean(e.match(r))))));var r}});Aa(Ia(Sa));var ka=e=>Object.assign(wa(e),{between:(t,r)=>{return ka(va(e,(n=t,s=r,Ia(e=>Ea(e)&&n<=e&&s>=e))));var n,s},lt:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e<r))));var r},gt:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e>r))));var r},lte:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e<=r))));var r},gte:t=>{return ka(va(e,(r=t,Ia(e=>Ea(e)&&e>=r))));var r},int:()=>ka(va(e,Ia(e=>Ea(e)&&Number.isInteger(e)))),finite:()=>ka(va(e,Ia(e=>Ea(e)&&Number.isFinite(e)))),positive:()=>ka(va(e,Ia(e=>Ea(e)&&e>0))),negative:()=>ka(va(e,Ia(e=>Ea(e)&&e<0)))});ka(Ia(Ea));var Pa=e=>Object.assign(wa(e),{between:(t,r)=>{return Pa(va(e,(n=t,s=r,Ia(e=>xa(e)&&n<=e&&s>=e))));var n,s},lt:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e<r))));var r},gt:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e>r))));var r},lte:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e<=r))));var r},gte:t=>{return Pa(va(e,(r=t,Ia(e=>xa(e)&&e>=r))));var r},positive:()=>Pa(va(e,Ia(e=>xa(e)&&e>0))),negative:()=>Pa(va(e,Ia(e=>xa(e)&&e<0)))});Pa(Ia(xa)),wa(Ia(function(e){return"boolean"==typeof e})),wa(Ia(function(e){return"symbol"==typeof e})),wa(Ia(function(e){return null==e})),wa(Ia(function(e){return null!=e}));var Ca=class extends Error{constructor(e){let t;try{t=JSON.stringify(e)}catch(r){t=e}super(`Pattern matching error: no pattern matches value ${t}`),this.input=void 0,this.input=e}},Ra={matched:!1,value:void 0},Ua=class e{constructor(e,t){this.input=void 0,this.state=void 0,this.input=e,this.state=t}with(...t){if(this.state.matched)return this;const r=t[t.length-1],n=[t[0]];let s;3===t.length&&"function"==typeof t[1]?s=t[1]:t.length>2&&n.push(...t.slice(1,t.length-1));let o=!1,i={};const a=(e,t)=>{o=!0,i[e]=t},c=!n.some(e=>ma(e,this.input,a))||s&&!Boolean(s(this.input))?Ra:{matched:!0,value:r(o?fa in i?i[fa]:i:this.input,this.input)};return new e(this.input,c)}when(t,r){if(this.state.matched)return this;const n=Boolean(t(this.input));return new e(this.input,n?{matched:!0,value:r(this.input,this.input)}:Ra)}otherwise(e){return this.state.matched?this.state.value:e(this.input)}exhaustive(e=La){return this.state.matched?this.state.value:e(this.input)}run(){return this.exhaustive()}returnType(){return this}narrow(){return this}};function La(e){throw new Ca(e)}var $a=new Set(["sha1","_sha1","pageref","downloadsPath","tracesDir","pageId"]);function Da({sensitiveValues:e,str:t}){return e.reduce((e,t)=>e.replaceAll(t,"[REDACTED]"),t)}function Na({sensitiveValues:e,value:t}){return"string"==typeof t?Da({sensitiveValues:e,str:t}):Array.isArray(t)?t.map(t=>Na({sensitiveValues:e,value:t})):function(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(t)?Ba({obj:t,sensitiveValues:e}):t}function Oa(e){return!!$a.has(e)||e.toLowerCase().endsWith("sha1")}function Ba({obj:e,sensitiveValues:t}){return Object.fromEntries(Object.entries(e).map(([e,r])=>[e,Oa(e)?r:Na({sensitiveValues:t,value:r})]))}function ja({error:e,sensitiveValues:t}){return e?{...e,message:Da({sensitiveValues:t,str:e.message})}:void 0}function Ma({content:e,sensitiveValues:t}){const r=new F,n=new H,s=Da({sensitiveValues:t,str:r.decode(e)});return n.encode(s)}var Fa=M(function(e,t,r){r||(r=t,t={}),"function"!=typeof r&&Ti(7);var n=[],s=function(){for(var e=0;e<n.length;++e)n[e]()},o={},i=function(e,t){na(function(){r(e,t)})};na(function(){i=r});for(var a=e.length-22;101010256!=Yi(e,a);--a)if(!a||e.length-a>65558)return i(Ti(13,0,1),null),s;var c=Vi(e,a+8);if(c){var l=c,u=Yi(e,a+16),d=4294967295==u||65535==l;if(d){var p=Yi(e,a-12);(d=101075792==Yi(e,p))&&(l=c=Yi(e,p+32),u=Yi(e,p+48))}for(var f=t&&t.filter,h=function(t){var r=function(e,t,r){var n=Vi(e,t+28),s=function(e,t){if(t){for(var r="",n=0;n<e.length;n+=16384)r+=String.fromCharCode.apply(null,e.subarray(n,n+16384));return r}if(Zi)return Zi.decode(e);var s=function(e){for(var t="",r=0;;){var n=e[r++],s=(n>127)+(n>223)+(n>239);if(r+s>e.length)return{s:t,r:vi(e,r-1)};s?3==s?(n=((15&n)<<18|(63&e[r++])<<12|(63&e[r++])<<6|63&e[r++])-65536,t+=String.fromCharCode(55296|n>>10,56320|1023&n)):t+=1&s?String.fromCharCode((31&n)<<6|63&e[r++]):String.fromCharCode((15&n)<<12|(63&e[r++])<<6|63&e[r++]):t+=String.fromCharCode(n)}}(e),o=s.s;return(r=s.r).length&&Ti(8),o}(e.subarray(t+46,t+46+n),!(2048&Vi(e,t+8))),o=t+46+n,i=Yi(e,t+20),a=r&&4294967295==i?function(e,t){for(;1!=Vi(e,t);t+=4+Vi(e,t+2));return[zi(e,t+12),zi(e,t+4),zi(e,t+20)]}(e,o):[i,Yi(e,t+24),Yi(e,t+42)],c=a[0],l=a[1],u=a[2];return[Vi(e,t+10),c,l,s,o+Vi(e,t+30)+Vi(e,t+32),u]}(e,u,d),a=r[0],l=r[1],p=r[2],h=r[3],g=r[4],m=r[5],y=function(e,t){return t+30+Vi(e,t+26)+Vi(e,t+28)}(e,m);u=g;var b=function(e,t){e?(s(),i(e,null)):(t&&(o[h]=t),--c||i(null,o))};if(!f||f({name:h,size:l,originalSize:p,compression:a}))if(a)if(8==a){var w=e.subarray(y,y+l);if(p<524288||l>.8*p)try{b(null,Ji(w,{out:new zo(p)}))}catch(e){b(e,null)}else n.push(function(e,t,r){return r||(r=t,t={}),"function"!=typeof r&&Ti(7),Wi(e,t,[Mi],function(e){return Hi(Ji(e.data[0],Gi(e.data[1])))},1,r)}(w,{size:p},b))}else b(Ti(14,"unknown compression type "+a,1),null);else b(null,vi(e,y,y+l));else b(null,null)},g=0;g<l;++g)h()}else i(null,{});return s}),Ha=M(function(e,t,r){r||(r=t,t={}),"function"!=typeof r&&Ti(7);var n={};Xi(e,"",n,t);var s=Object.keys(n),o=s.length,i=0,a=0,c=o,l=new Array(o),u=[],d=function(){for(var e=0;e<u.length;++e)u[e]()},p=function(e,t){na(function(){r(e,t)})};na(function(){p=r});var f=function(){var e=new zo(a+22),t=i,r=a-i;a=0;for(var n=0;n<c;++n){var s=l[n];try{var o=s.c.length;ra(e,a,s,s.f,s.u,o);var u=30+s.f.length+ta(s.extra),d=a+u;e.set(s.c,d),ra(e,i,s,s.f,s.u,o,a,s.m),i+=16+u+(s.m?s.m.length:0),a=d+o}catch(e){return p(e,null)}}!function(e,t,r,n,s){qi(e,t,101010256),qi(e,t+8,r),qi(e,t+10,r),qi(e,t+12,n),qi(e,t+16,s)}(e,i,l.length,r,t),p(null,e)};o||f();for(var h=function(e){var t=s[e],r=n[t],c=r[0],h=r[1],g=function(){var e=-1;return{p:function(t){for(var r=e,n=0;n<t.length;++n)r=Di[255&r^t[n]]^r>>>8;e=r},d:function(){return~e}}}(),m=c.length;g.p(c);var y=ea(t),b=y.length,w=h.comment,v=w&&ea(w),I=v&&v.length,T=ta(h.extra),_=0==h.level?0:8,E=function(r,n){if(r)d(),p(r,null);else{var s=n.length;l[e]=Oi(h,{size:m,crc:g.d(),c:n,f:y,m:v,u:b!=t.length||v&&w.length!=I,compression:_}),i+=30+b+T+s,a+=76+2*(b+T)+(I||0)+s,--o||f()}};if(b>65535&&E(Ti(11,0,1),null),_)if(m<16e4)try{E(null,Ki(c,h))}catch(e){E(e,null)}else u.push(function(e,t,r){return r||(r=t,t={}),"function"!=typeof r&&Ti(7),Wi(e,t,[Fi],function(e){return Hi(Ki(e.data[0],e.data[1]))},0,r)}(c,h,E));else E(null,c)},g=0;g<c;++g)h(g);return d});async function Ga({content:e,filename:t,sensitiveValues:r}){const n=t.toLowerCase();return n.endsWith(".trace")||n.endsWith(".network")?function({content:e,sensitiveValues:t}){const r=new F,n=new H,s=r.decode(e).split("\n").map(e=>{if(!e.trim())return e;try{const r=function({event:e,sensitiveValues:t}){return(r=e,new Ua(r,Ra)).with({type:"console"},e=>({...e,args:e.args?.map(e=>({...e,preview:Da({sensitiveValues:t,str:e.preview}),value:Na({sensitiveValues:t,value:e.value})})),text:Da({sensitiveValues:t,str:e.text})})).with({type:"before"},e=>({...e,params:Ba({obj:e.params,sensitiveValues:t}),title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"after"},e=>({...e,error:ja({error:e.error,sensitiveValues:t}),result:void 0!==e.result?Na({sensitiveValues:t,value:e.result}):void 0})).with({type:"action"},e=>({...e,error:ja({error:e.error,sensitiveValues:t}),params:Ba({obj:e.params,sensitiveValues:t}),result:void 0!==e.result?Na({sensitiveValues:t,value:e.result}):void 0,title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"event"},e=>({...e,params:Ba({obj:e.params,sensitiveValues:t})})).with({type:"stdout"},{type:"stderr"},e=>({...e,text:void 0!==e.text?Da({sensitiveValues:t,str:e.text}):void 0})).with({type:"error"},e=>({...e,message:Da({sensitiveValues:t,str:e.message})})).with({type:"log"},e=>({...e,message:Da({sensitiveValues:t,str:e.message})})).with({type:"context-options"},e=>({...e,options:Ba({obj:e.options,sensitiveValues:t}),title:e.title?Da({sensitiveValues:t,str:e.title}):void 0})).with({type:"frame-snapshot"},e=>({...e,snapshot:Ba({obj:e.snapshot,sensitiveValues:t})})).with({type:"resource-snapshot"},e=>({...e,snapshot:Ba({obj:e.snapshot,sensitiveValues:t})})).with({type:"screencast-frame"},{type:"input"},e=>e).exhaustive();var r}({event:JSON.parse(e),sensitiveValues:t});return JSON.stringify(r)}catch{return Da({sensitiveValues:t,str:e})}});return n.encode(s.join("\n"))}({content:e,sensitiveValues:r}):n.endsWith(".html")||n.endsWith(".dat")||n.endsWith(".json")?Ma({content:e,sensitiveValues:r}):n.startsWith("resources/")?async function({content:e,sensitiveValues:t}){return function(e){return function(e,t){if(function(e){return"string"==typeof e}(e)){!function(e){if(!e.isFile())throw new Error("Path provided was not a file!")}(S(e));const r=C(e,"r"),n=Buffer.alloc(515),s=R(r,n,0,515,0);return U(r),ca(n,s,t)}return ca(e,void 0!==t?.size?t.size:e.length,t)}(Buffer.from(e),{size:e.length})}(e)?e:Ma({content:e,sensitiveValues:t})}({content:e,sensitiveValues:r}):e}var Wa=e=>(e instanceof Error?e.message:String(e)).slice(0,400),Va=async e=>{const t=await Q(e,{withFileTypes:!0}),r=[];for(const s of t){const t=n.join(e,s.name);if(s.isDirectory())r.push(...await Va(t));else if(s.isFile()&&"trace.zip"===s.name){const e=await Z(t);r.push({path:t,mtimeMs:e.mtimeMs})}}return r},Ya=e=>"string"==typeof e&&e.length>0?e:void 0,za=({result:e,representativeTest:t})=>{const r=t.testTitle||t.filePath;return"captured"===e.status&&e.storage?`@[trace:${Buffer.from(JSON.stringify({...e.storage,...r?{label:r}:{}})).toString("base64url")}]`:void 0},qa=async({outputDir:e,tracePath:t,testFilePath:r,issueId:n,proofId:s,testCaseId:o,requestUploadUrl:i})=>{ls.info("[upload-trace-proof] Uploading trace",{testFilePath:r,issueId:n,testCaseId:o,outputDir:e});const a=await(async({tracePath:e,outputDir:t,requestUploadUrl:r})=>{try{let n=e;if(!n){if(!t)return{status:"capture_failed",error:"Either tracePath or outputDir must be provided."};if(!E(t))return{status:"capture_failed",error:`Output directory does not exist: ${t}`};n=await(async e=>{const t=await Va(e);if(0!==t.length)return t.sort((e,t)=>t.mtimeMs-e.mtimeMs),t[0]?.path})(t)}if(!n)return{status:"capture_failed",error:"No trace.zip found in the output directory."};const{traceBucketPath:s,uploadUrl:o,sensitiveValues:i}=await r(),a=await async function({tracePath:e,sensitiveValues:t}){const r=[],n=P(e);for await(const e of n)r.push(e);return async function({sensitiveValues:e,traceBuffer:t}){const r=e.filter(e=>!(e.length<3||la.some(t=>t.test(e))||ua.some(t=>e.includes(t))));if(0===r.length)return new Uint8Array(t);const n=[...r].sort((e,t)=>t.length-e.length),s=await Fa(new Uint8Array(t)),o=Object.entries(s),i=await Promise.all(o.map(async([e,t])=>[e,await Ga({content:t,filename:e,sensitiveValues:n})])),a=Object.fromEntries(i);return Ha(a)}({traceBuffer:new Uint8Array(Buffer.concat(r)),sensitiveValues:t})}({tracePath:n,sensitiveValues:i});try{await xs({body:a,contentType:"application/zip",uploadUrl:o,errorContext:"trace"})}catch(e){return{status:"upload_failed",error:Wa(e)}}return{status:"captured",storage:s}}catch(e){return{status:"upload_failed",error:Wa(e)}}})({tracePath:t,outputDir:e,requestUploadUrl:()=>i({testFilePath:r,issueId:n,proofId:s,testCaseId:o})});return"captured"===a.status?ls.info("[upload-trace-proof] Upload succeeded",{testFilePath:r,traceBucketPath:a.storage}):ls.error("[upload-trace-proof] Failed",{testFilePath:r,error:a.error}),a},Ka=({requestUploadUrl:e,onTraceUploaded:t})=>W("upload-trace-proof",["Upload a Playwright trace proof for a test.","","IMPORTANT: This tool does NOT run tests. You must run the test yourself first","using Playwright with tracing enabled and --output <dir>, then call this tool to upload the trace.","","You MUST provide testFilePath and at least one of outputDir or tracePath.","You MUST also provide testPassed (true if the test exit code was 0, false otherwise).","Only passing traces are uploaded as proof."].join("\n"),{outputDir:we.string().min(1).optional().describe("The --output directory from the Playwright test run containing trace.zip. Required if tracePath is not provided."),tracePath:we.string().min(1).optional().describe("Optional direct path to trace.zip. If omitted, the newest trace in outputDir is used."),testFilePath:we.string().min(1).describe("Path to the test file (relative to the project working directory)."),testPassed:we.boolean().describe("Whether the test run passed (exit code 0). You MUST check the exit code of stably-browser run-test before calling this tool. Exit code 0 = passed, non-zero = failed. Only passing traces are uploaded."),representativeTest:Wo.optional().default({})},async({outputDir:r,tracePath:n,testFilePath:s,testPassed:o,representativeTest:i})=>{const a=Ya(s);if(!a)throw new Error("testFilePath is required for create-mode trace uploads");if("boolean"!=typeof o)throw new Error("testPassed is required for create-mode trace uploads");if(!o)return ls.info("[upload-trace-proof] Skipping upload for failing test",{testFilePath:a}),{content:[{type:"text",text:JSON.stringify({status:"skipped",testFilePath:a,testPassed:!1,reason:"Test failed β only passing traces are uploaded as trace proofs. Fix the test and re-run before uploading."})}]};const c=Wo.parse(i??{}),l=Ya(n),u=Ya(r),d=await qa({outputDir:u,tracePath:l,testFilePath:a,requestUploadUrl:e}),p=za({representativeTest:c,result:d}),f={testFilePath:a,status:d.status,storage:"captured"===d.status?d.storage:null,..."error"in d?{error:d.error}:{}};t?.(f);const h={...d,testFilePath:a,...null!=p?{tracePlaceholder:p}:{}};return{content:[{type:"text",text:JSON.stringify(h)}]}}),Ja=({requestUploadUrl:e,onTraceUploaded:t})=>W("upload-trace-proof",["Upload a Playwright trace proof for a test case.","","IMPORTANT: This tool does NOT run tests. You must run the test yourself first","using Playwright with tracing enabled and --output <dir>, then call this tool to upload the trace.","","MANDATORY: Call for EVERY testCaseId in your issue, whether fixed or unfixed.","- Fixed: Trace proves the fix works","- Unfixed: Trace shows the failure state for auditability","","Pass the outputDir that was used as the --output flag in your test run.","Optionally pass tracePath if you know the exact path to the trace.zip file."].join("\n"),{outputDir:we.string().min(1).optional().describe("The --output directory from the Playwright test run containing trace.zip. Required if tracePath is not provided."),tracePath:we.string().min(1).optional().describe("Optional direct path to trace.zip. If omitted, the newest trace in outputDir is used."),issueId:we.string().min(1).describe("Issue identifier for deterministic output paths and storage key naming."),proofId:we.string().min(1).optional().describe("Optional id for deterministic proof naming and deduplication."),testCaseId:we.string().min(1).optional().describe("Optional test case ID when uploading per-test trace proofs."),testPassed:we.boolean().describe("Whether the test run passed (exit code 0). You MUST check the exit code of stably-browser run-test before calling this tool. Exit code 0 = passed, non-zero = failed."),representativeTest:Wo.optional().default({})},async({outputDir:r,tracePath:n,issueId:s,proofId:o,representativeTest:i,testCaseId:a,testPassed:c})=>{const l=Ya(s);if(!l)throw new Error("issueId is required for fix-mode trace uploads");if("boolean"!=typeof c)throw new Error("testPassed is required for fix-mode trace uploads");const u=Ya(o),d=Ya(a),p=Wo.parse(i??{}),f=Ya(n),h=Ya(r),g=await qa({outputDir:h,tracePath:f,issueId:l,proofId:u,testCaseId:d,requestUploadUrl:e}),m=za({representativeTest:p,result:g}),y={issueId:l,representativeTest:p,status:g.status,storage:"captured"===g.status?g.storage:null,...null!=d?{testCaseId:d}:{},testPassed:c,..."error"in g?{error:g.error}:{}};t?.(y);const b={...g,...null!=d?{testCaseId:d}:{},...null!=m?{tracePlaceholder:m}:{},representativeTest:p,testPassed:c},w=c?"":'\n\nWARNING: testPassed=false β this trace documents a FAILURE, not a successful fix. Do NOT report result:"fixed" for this test. If you applied a fix but the verification run failed (e.g., auth setup error, missing env vars), the fix is NOT proven. Report result:"unfixed" with the failure reason.';return{content:[{type:"text",text:JSON.stringify(b)+w}]}}),Xa=({requestUploadUrl:e,onTraceUploaded:t})=>G({name:"upload-trace-proof",tools:[Ka({requestUploadUrl:e,onTraceUploaded:t})]}),Qa=({authProvider:e,diffTracker:t,orgId:r,runId:n,workingDir:s})=>G({name:"auto-heal-report",tools:[Ja({requestUploadUrl:t=>{const{issueId:s}=t;return s?e.getAuthHeader().then(e=>(async({authHeader:e,issueId:t,proofId:r,testCaseId:n,contentType:s="application/zip",orgId:o,runId:i})=>{const a=await(c={auth:e,body:{contentType:s,issueId:t,proofId:r,testCaseId:n},client:In(),headers:_s(o),path:{runId:i}},(c.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-trace/upload-url",...c,headers:{"Content-Type":"application/json",...c.headers}}));var c;if(a.error)throw new Error(`Failed to presign trace upload (${a.response.status})`);const l=ks.parse(a.data);return{traceBucketPath:l.traceBucketPath,expiresInSeconds:l.expiresInSeconds,key:l.key,uploadUrl:l.uploadUrl,sensitiveValues:l.sensitiveValues}})({authHeader:e,issueId:s,proofId:t.proofId,orgId:r,runId:n,testCaseId:t.testCaseId})):Promise.reject(new Error("issueId is required for fix-mode trace uploads"))}}),W("generate-report",["After attempting to fix all broken tests (skip only those truly infeasible), generate a markdown auto-heal report.","","The UI renders this markdown into structured cards based on ## and ### headings. Follow the heading structure from the MARKDOWN REPORT STRUCTURE section in your instructions:","- ## Summary, ## Fixed Issues (with ### per issue), ## Unfixed Issues (with ### per issue)",'- Each ### must be a short descriptive slug (e.g. "invite-member-flaky-timeouts")',"- Use **bold labels:** for fields (Tests, Flaky signal, Root cause, Fix applied, Why not fixed, Proof of fixed tests)","- Include **Flaky signal:** inside an issue card only when triage flagged that test as flaky β do NOT create a separate ## section for flaky signals","","Write for readability: keep bullets concise, use tables only when they genuinely improve scanability, and wrap file paths, commands, selectors, and code in backticks.","Prefer short sections over long paragraphs. Call out important outcomes first, then supporting evidence.","","ENTITY REFERENCES: When referencing entities by ID, use placeholder syntax so the UI can render clickable links:","- Test cases: @[test-case:<id>] (e.g., @[test-case:fp8f0yzdqqut6bg7cy5euzer])","- Suite runs: @[suite-run:<id>] (e.g., @[suite-run:cm6i7o6ti0000l40350wys0u1])","- Tests: @[test:<id>] (e.g., @[test:wty0g1v58cwrrd8jj6et8nmx])","- Traces: use the tracePlaceholder value returned by upload-trace-proof (e.g., @[trace:eyJi...])","These placeholders will be automatically resolved to clickable links with human-readable labels in the UI.","NEVER show raw entity IDs without wrapping them in @[type:id] syntax."].join("\n"),{markdown:Go.shape.markdown,summary:Go.shape.summary,issues:Go.shape.issues},async({markdown:s,summary:o,issues:i})=>{const a=await e.getAuthHeader(),c=await t.computeDiff(),l=Go.parse({format:"markdown",markdown:s,summary:o,issues:i});try{await(async({authHeader:e,orgId:t,report:r,runId:n})=>{const s=await(o={auth:e,body:{report:JSON.stringify(r)},client:In(),headers:_s(t),path:{runId:n}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-report",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to upload auto-heal report (${s.response.status})`)})({authHeader:a,orgId:r,report:l,runId:n});const{diffBucketPath:e,uploadUrl:t}=await Ps({authHeader:a,contentType:"text/plain",orgId:r,runId:n});await xs({body:c,contentType:"text/plain",uploadUrl:t,errorContext:"diff"}),await Cs({authHeader:a,diffBucketPath:e,orgId:r,runId:n})}catch(e){return console.error("[auto-heal-report] Failed to upload report or diff:",e),{content:[{text:"Error: Failed to upload auto-heal report or diff. Please surface this to the user, and terminate the session.",type:"text"}]}}return{content:[{text:"Auto-heal report generated. You may terminate this session now.",type:"text"}]}})],version:"0.0.1"});function Za({workingDir:e,packageManager:t,packageSpec:r,targetSection:n}){const{command:s,args:o}=function(e,t,r){const n="npm"===e?"npm":e;return{command:n,args:["npm"===e?"install":"add",..."devDependencies"===r?["bun"===e?"-d":"-D"]:[],..."npm"===n?["--no-fund"]:[],t]}}(t,r,n);y(s,o,{cwd:e,stdio:"pipe",timeout:6e4})}function ec(e){const t=r.join(e,"package.json");return w.existsSync(t)?{path:t,contents:JSON.parse(w.readFileSync(t,"utf-8"))}:null}var tc=["playwright.config.ts","playwright.config.js","playwright.config.mts","playwright.config.mjs","playwright.config.cjs"];function rc(e){return tc.some(t=>w.existsSync(r.join(e,t)))}function nc(e,t){const n=w.readdirSync(e,{withFileTypes:!0}),s=[];for(const o of n){if("node_modules"===o.name||".git"===o.name)continue;const n=r.join(e,o.name);o.isDirectory()?s.push(...nc(n,t)):t.test(o.name)&&s.push(n)}return s}function sc(e){let t=r.resolve(e);for(;;){if(rc(t))return t;const n=r.dirname(t);if(n===t)return e;t=n}}function oc(e){const t=Array.from(new Set(e.map(e=>r.resolve(e)))).sort((e,t)=>e.length-t.length),n=[];for(const e of t)n.some(t=>e===t||e.startsWith(`${t}${r.sep}`))||n.push(e);return n}function ic(e){return/\b(test|testing|playwright|e2e|stably)\b/i.test(e)}function ac(e,t){for(const n of cc(e,t))if(w.existsSync(r.join(n,"package.json")))return n}function cc(e,t){const n=[];let s=r.resolve(e);const o=r.resolve(t);for(;n.push(s),s!==o;){const e=r.dirname(s);if(e===s)break;s=e}return n}function lc(e){return e?.replace(/^[~^>=<]+/,"")}function uc(e){let t=e;for(let e=0;e<5;e++){if(w.existsSync(r.join(t,"pnpm-lock.yaml")))return"pnpm";if(w.existsSync(r.join(t,"yarn.lock")))return"yarn";if(w.existsSync(r.join(t,"bun.lockb"))||w.existsSync(r.join(t,"bun.lock")))return"bun";if(w.existsSync(r.join(t,"package-lock.json"))||w.existsSync(r.join(t,"npm-shrinkwrap.json")))return"npm";const e=r.dirname(t);if(e===t)break;t=e}return"npm"}var dc=we.object({commentUrl:we.string()}),pc=({prContext:e,authProvider:t,orgId:r,onReportPosted:n})=>G({name:"create-report",tools:[W("post_create_report",`Post a test creation report as a GitHub comment on PR #${e.prNumber}.\nCall this tool at the end of test creation to summarize what was created.\nThe report will be posted to: ${e.prUrl}\n\nWHEN TO USE:\n- After you have finished creating test files\n- To provide a summary of the tests created on the PR for visibility\n\nThe report will include:\n- A list of all test files created\n- Your summary of what was tested`,{summary:we.string().describe("A summary of the tests created. Include what features/flows are tested and any important notes."),filesCreated:we.array(we.string()).describe("List of test file paths that were created (relative to workspace root)")},async({summary:s,filesCreated:o})=>{const i=await t.getAuthHeader(),a=Array.isArray(o)?o:[];ls.info("[create-report] Posting report to GitHub PR",{prNumber:e.prNumber,filesCount:a.length});try{const t={summary:"string"==typeof s?s:String(s),filesCreated:a.map(String)},o=await async function({authHeader:e,orgId:t,prNumber:r,owner:n,repo:s,report:o}){const i=new URL("/internal/v1/cli/create-report",fn).toString(),a={Authorization:e,"Content-Type":"application/json"};t&&(a["x-stably-org-id"]=t),ls.debug("Posting create report to GitHub",{prNumber:r,owner:n,repo:s,filesCount:o.filesCreated.length});const c=await fetch(i,{method:"POST",headers:a,body:JSON.stringify({prNumber:r,owner:n,repo:s,report:o}),signal:AbortSignal.timeout(3e4)});if(!c.ok){const e=await c.text().catch(()=>"");throw ls.error("Failed to post create report",{status:c.status,error:e.slice(0,500)}),new Error(`Failed to post create report: ${c.status} ${e.slice(0,200)}`)}const l=dc.parse(await c.json());return ls.info("Create report posted successfully",{commentUrl:l.commentUrl}),l}({authHeader:i,orgId:r,prNumber:e.prNumber,owner:e.owner,repo:e.repo,report:t});return n?.(o),ls.info("[create-report] Report posted successfully",{commentUrl:o.commentUrl}),{content:[{type:"text",text:`β
Test creation report posted to PR #${e.prNumber}\n\nView the comment: ${o.commentUrl}`}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[create-report] Failed to post report",{error:t}),{content:[{type:"text",text:`β Failed to post report to GitHub: ${t}\n\nThe tests were still created successfully, but the PR comment could not be posted.`}],isError:!0}}})]}),fc=we.object({traceBucketPath:Ss,expiresInSeconds:we.number(),key:we.string(),uploadUrl:we.string(),sensitiveValues:we.array(we.string())}),hc=["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","CANCELLED","INTERRUPTED"],gc=["LOCAL","CI","WEB"],mc=["MANUAL","SCHEDULED","UI","API","GITHUB_ACTION","SUITE_RUN"],yc=({authProvider:e,orgId:t,projectId:r})=>G({name:"run-history",tools:[W("list_runs",'List test runs with optional filters for the current project.\nUse this to find runs with autoheal status on specific branches.\n\nCommon use cases:\n- Find failed runs on the current branch: { "branch": "feature-x", "status": "FAILED", "limit": 10 }\n- Find failed runs on master/main: { "branch": "master", "status": "FAILED", "limit": 10 }\n- Find the most recent run: { "limit": 1 }\n\nIf the user asks about test failures without specifying a run, use this to discover recent failed runs.\n\nReturns an array of runs with their runId, status, autoHealStatus, branch, and timestamps.',{branch:we.string().optional().describe("Filter by branch name"),status:we.enum(hc).optional().describe("Filter by status: QUEUED|RUNNING|PASSED|FAILED|TIMEDOUT|CANCELLED|INTERRUPTED"),limit:we.number().min(1).max(100).optional().describe("Max results (1-100, default 20)"),source:we.enum(gc).optional().describe("Filter by source: LOCAL|CI|WEB"),trigger:we.enum(mc).optional().describe("Filter by trigger: MANUAL|SCHEDULED|UI|API|GITHUB_ACTION|SUITE_RUN"),suite:we.string().optional().describe("Filter by suite name"),after:we.string().optional().describe("Pagination: return runs after this runId"),before:we.string().optional().describe("Pagination: return runs before this runId")},async({branch:n,status:s,limit:o,source:i,trigger:a,suite:c,after:l,before:u})=>{const d=await e.getAuthHeader(),p="string"==typeof n?n:void 0,f="string"==typeof s?s:void 0,h="number"==typeof o?o:void 0,g="string"==typeof i?i:void 0,m="string"==typeof a?a:void 0,y="string"==typeof c?c:void 0,b="string"==typeof l?l:void 0,w="string"==typeof u?u:void 0;ls.info("[run-history] list_runs called",{branch:p,status:f,limit:h});try{const e=await un({auth:d,client:In(),headers:_s(t),query:{projectId:r,branchName:p,status:f,limit:h,source:g,trigger:m,suiteName:y,afterRunId:b,beforeRunId:w}});if(e.error||!e.data){const t=e.response?`API error: ${e.response.status}`:`API error: ${String(e.error)}`;return ls.error("[run-history] list_runs failed",{error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}return ls.info("[run-history] list_runs success",{runCount:e.data.runs?.length??0,hasMore:e.data.hasMore}),{content:[{type:"text",text:JSON.stringify(e.data)}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[run-history] list_runs exception",{error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}}),W("view_run",'Get detailed information about a specific run including issues and test results.\n\nThe response includes:\n- Run metadata (status, branch, timestamps, envName)\n- Issues array with result ("fixed"/"unfixed"), rootCause, and relatedTestIdentifiers\n- Test results with their outcomes\n- envName: the remote environment used (e.g., "staging") β if present, call load_environment with this name before rerunning tests\n\nUse this to examine run details and determine which tests failed or were previously fixed.',{runId:we.string().min(1).describe("The run ID to view (required)")},async({runId:r})=>{const n=await e.getAuthHeader(),s="string"==typeof r?r:String(r);ls.info("[run-history] view_run called",{runId:s});try{const e=await dn({auth:n,client:In(),headers:_s(t),path:{runId:s},query:{detail:"full"}});if(e.error||!e.data){const t=e.response?404===e.response.status?`Run "${s}" not found`:`API error: ${e.response.status}`:`API error: ${String(e.error)}`;return ls.error("[run-history] view_run failed",{error:t,runId:s}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}return ls.info("[run-history] view_run success",{runId:s}),{content:[{type:"text",text:JSON.stringify(e.data)}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[run-history] view_run exception",{error:t,runId:s}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}})]});function bc({localEnv:e,remoteEnv:t,remoteSensitiveValues:r,processEnv:n=process.env}){const s={};for(const[t,r]of Object.entries(e))void 0===n[t]&&(s[t]=r);if(t)for(const[r,o]of Object.entries(t))void 0===n[r]&&void 0===e[r]&&(s[r]=o);return r?.length&&void 0===n.STABLY_SENSITIVE_VALUES&&(s.STABLY_SENSITIVE_VALUES=Buffer.from(JSON.stringify(r)).toString("base64")),s}var wc=({hookEnvVars:e,localEnvSnapshot:t})=>G({name:"environment",tools:[W("load_environment",'Load remote environment variables by name (e.g., "staging", "production").\nUse this when you discover a run was executed with a specific --env and need\nthose variables for rerunning tests.\n\nAfter loading, all subsequent stably-browser run-test commands will automatically\nhave these environment variables injected. Use process.env.VARNAME syntax in test\ncode for these variables.\n\nReturns the list of variable names loaded (never values, for security).',{envName:we.string().min(1).describe('Environment name to load (e.g., "staging")')},async({envName:r})=>{const n="string"==typeof r?r:String(r);ls.info("[load-environment] Loading environment",{envName:n});try{const r=await Is(n);if(!r.ok)return ls.warn("[load-environment] Failed to load environment",{envName:n,error:r.error}),{content:[{type:"text",text:`Error: ${r.error}`}],isError:!0};const s=bc({localEnv:t??{},remoteEnv:r.result.variables,remoteSensitiveValues:r.result.sensitiveValues});for(const t of Object.keys(e))delete e[t];Object.assign(e,s);const o=Object.keys(r.result.variables);return ls.info("[load-environment] Environment loaded",{envName:n,variableCount:o.length}),{content:[{type:"text",text:`Successfully loaded ${o.length} variable(s) from "${n}" environment.\n\nVariable names: ${o.join(", ")}\n\nThese are now available for stably-browser run-test commands. Use \`process.env.VARNAME\` syntax in test code for these variables.`}]}}catch(e){const t=e instanceof Error?e.message:String(e);return ls.error("[load-environment] Exception loading environment",{envName:n,error:t}),{content:[{type:"text",text:`Error: ${t}`}],isError:!0}}})]}),vc=e=>e.replace(/Bearer\s+[A-Za-z0-9._-]+/gi,"Bearer [redacted]").replace(/\bsk-[A-Za-z0-9_-]{16,}\b/g,"[redacted]").replace(/\bstably_[A-Za-z0-9_-]{16,}\b/g,"[redacted]"),Ic=(e,t)=>({message:vc(e),status:t?.status,statusText:t?.statusText}),Tc=["ANTHROPIC_","CLAUDE"],_c=new Set(["AWS_BEARER_TOKEN_BEDROCK","BASH_DEFAULT_TIMEOUT_MS","BASH_MAX_OUTPUT_LENGTH","BASH_MAX_TIMEOUT_MS","DISABLE_AUTOUPDATER","DISABLE_BUG_COMMAND","DISABLE_COST_WARNINGS","DISABLE_ERROR_REPORTING","DISABLE_NON_ESSENTIAL_MODEL_CALLS","DISABLE_PROMPT_CACHING","DISABLE_PROMPT_CACHING_HAIKU","DISABLE_PROMPT_CACHING_OPUS","DISABLE_PROMPT_CACHING_SONNET","DISABLE_TELEMETRY","HTTP_PROXY","HTTPS_PROXY","MAX_MCP_OUTPUT_TOKENS","MAX_THINKING_TOKENS","MCP_TIMEOUT","MCP_TOOL_TIMEOUT","NO_PROXY","SLASH_COMMAND_TOOL_CHAR_BUDGET","USE_BUILTIN_RIPGREP","VERTEX_REGION_CLAUDE_3_5_HAIKU","VERTEX_REGION_CLAUDE_3_7_SONNET","VERTEX_REGION_CLAUDE_4_0_OPUS","VERTEX_REGION_CLAUDE_4_0_SONNET","VERTEX_REGION_CLAUDE_4_1_OPUS"]),Ec=async({authHeader:e,mode:t,maxTurnsOverride:r})=>{const n=In();ls.debug("Requesting subagent definitions from API",{mode:t,maxTurnsOverride:r});const s=await(o={client:n,auth:e,body:{mode:t,maxTurnsOverride:r}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/prompts/subagents",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(401===s.response.status)throw ls.warn("Subagent definitions fetch failed: unauthorized (401)"),await On(),new Error("Your session has expired or been revoked. Credentials have been cleared. Please run `stably login` to re-authenticate.");if(403===s.response.status)throw ls.debug("Subagent definitions fetch failed: forbidden (403)"),new Error("Your organization does not have an active subscription. Manage your subscription at https://app.stably.ai or contact your organization admin.");if(s.error)throw ls.warn("Subagent definitions fetch failed",{error:s.error}),new Error("Failed to fetch subagent definitions. Please check your network connection and try again. If this persists, run `stably login` to re-authenticate.");const{subagents:i}=s.data;return ls.debug("Subagent definitions received",{count:Object.keys(i).length}),i},Sc=n.dirname(L(import.meta.url)),xc=n.join(".claude-plugin","plugin.json"),Ac=[n.join("packages","agent-plugin","stably-plugin-cli"),n.join("agent-plugin","stably-plugin-cli")];function kc(e){return E(n.join(e,xc))}var{zStablyYaml:Pc}=function(e){const t=e.object({cron:e.string(),stablyTestArgs:e.string().optional(),timezone:e.string().optional(),command:e.string().optional(),autofix:e.boolean().optional()}),r=e.object({maxTurnsPerIssue:e.number().int().positive().default(200),maxParallelWorkers:e.number().int().positive().default(3),rules:e.string().optional(),skipAfterConsecutiveUnfixed:e.number().int().positive().default(3),maxBudgetUsd:e.number().positive().default(50)}),n=e.object({maxTurnsPerTestFile:e.number().int().positive().default(200),maxBudgetUsd:e.number().positive().default(50)}),s=e.object({fix:r.optional(),create:n.optional()}),o=e.object({setupScript:e.string().optional()});return{zStablyYaml:e.object({schedules:e.record(e.string(),t).optional(),agent:s.optional(),cloud:o.optional()}),zAgentConfig:s,zAgentFixConfig:r,zAgentCreateConfig:n,zScheduleEntry:t,zCloudConfig:o}}(he),Cc=async(e,t)=>{try{const r=await kn(e,t);if(!r)return void ls.debug(`No ${t} found`);const n=await z(r,"utf-8");if(!n.trim())return;return n.length>1e4?(ls.warn(`${t} exceeds max length (${n.length} > 10000), truncating`,{path:r}),{content:n.slice(0,1e4),path:r}):(ls.debug(`Loaded ${t} rules`,{path:r,contentLength:n.length}),{content:n,path:r})}catch(e){return void ls.warn(`Failed to read ${t}`,{error:e})}},Rc=/(?<![./])\bstably-browser\b/,Uc=/\bpwtrace\b/,Lc="(?:(?:-\\w+=?\\S*|--\\w+=?\\S*|-s\\s+\\S+|--session\\s+\\S+)\\s+)*",$c=new RegExp(`\\bstably-browser\\s+${Lc}run-test\\b`),Dc=/\$\{process\.env\.([a-zA-Z_][a-zA-Z0-9_]*)\}/g,Nc=e=>/^[A-Za-z0-9_./:@=-]+$/.test(e)?e:`'${e.replace(/'/g,"'\\''")}'`,Oc=".stably-browser";async function Bc(){const e=i(o(L(import.meta.url)),"stably-browser.js");if(E(e))return e;ls.debug("[stably-browser-hook] Bundled binary not found",{checkedPath:e});try{return Re.resolve("@stablyai-internal/playwright-cli/playwright-cli.js")}catch{ls.debug("[stably-browser-hook] @stablyai-internal/playwright-cli not resolvable from node_modules")}return new Promise((e,t)=>{m("which",["stably-browser"],(r,n)=>{if(r||!n.trim())return ls.warn("[stably-browser-hook] stably-browser not found on PATH",{error:r?.message}),void t(new Error("stably-browser not found. Ensure @stablyai-internal/playwright-cli is installed or stably-browser is on PATH."));e(n.trim())})})}async function jc(){const e=i(o(L(import.meta.url)),"pwtrace.js");if(E(e))return e;try{return Re.resolve("@stablyai-internal/pwtrace/bin/cli.js")}catch{}return new Promise((e,t)=>{m("which",["pwtrace"],(r,n)=>{!r&&n.trim()?e(n.trim()):t(new Error("pwtrace not found. Ensure @stablyai-internal/pwtrace is installed or pwtrace is on PATH."))})})}function Mc(e,t,r=!1){const n=`${e}\n${t}`;return n.includes("spawn")&&n.includes("ENOENT")&&!n.includes("Executable doesn't exist")?{permanent:!0,reason:"Browser binary exists but cannot be executed (likely Alpine Linux / musl libc incompatibility).",guidance:"The Chromium binary was downloaded but the OS cannot execute it. This usually happens on Alpine Linux containers because Chromium is compiled for glibc, not musl. Ask the user to either: (1) switch to a glibc-based image like node:20-slim instead of node:20-alpine, (2) install glibc compatibility with `apk add gcompat`, or (3) use the official Playwright Docker image (mcr.microsoft.com/playwright). Do not attempt to install browsers β they are already installed, the issue is OS-level. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("is not installed")||n.includes("Executable doesn't exist")?{permanent:!0,reason:"Browser is not installed in this environment.",guidance:"The Playwright browser binary is missing. Ask the user to run `npx playwright install chromium` in their environment (or add it to their Dockerfile/CI setup). Do not attempt to install browsers yourself. You can still analyze test code, make fixes, and use upload-trace-proof (it only uploads existing traces, no browser needed), but cannot run tests locally until browsers are installed. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("Missing system dependencies")||n.includes("cannot open shared object file")?{permanent:!0,reason:"Browser system dependencies are missing.",guidance:"The browser binary exists but required system libraries are missing. Ask the user to run `npx playwright install-deps chromium` (requires apt/sudo) or use a Playwright Docker image. Do not attempt to install system packages yourself. Do not retry stably-browser commands β they will all fail for the same reason."}:n.includes("already in use")?{permanent:!1,reason:"Browser profile is locked by another process.",guidance:"Another browser session is using the same profile. Try closing the existing session with `stably-browser close` first, or use a different session name."}:n.includes("sandboxing failed")||n.includes("--no-sandbox")?{permanent:!0,reason:"Browser sandboxing failed (likely running as root in a container).",guidance:"Chrome cannot create a sandbox when running as root. Ask the user to either: (1) add `chromiumSandbox: false` to their Playwright launch options, (2) add `--no-sandbox` to their Chrome args, or (3) run the container as a non-root user. Do not attempt to fix this yourself β it requires changes to the user's Playwright config or Docker setup. Do not retry stably-browser commands β they will all fail for the same reason."}:r||e.includes("ETIMEDOUT")||e.includes("timed out")?{permanent:!1,reason:"Daemon startup timed out.",guidance:"The browser daemon did not start within 30 seconds. This may be caused by slow browser download, resource constraints, or a hung process. Retry once, and if it fails again, ask the user to check their environment."}:{permanent:!1,reason:n.slice(0,500).trim(),guidance:"An unexpected error occurred starting the browser daemon. Share the error with the user."}}async function Fc(e,t,r,n,s="chromium"){const o=["open",`-s=${t}`];let i;return r&&o.push("--headed"),n?o.push(`--config=${n}`):o.push(`--browser=${s}`),ls.info("[stably-browser-hook] Starting daemon",{bin:e,args:o}),process.env.CHROME_BIN&&(i={...process.env,PLAYWRIGHT_MCP_EXECUTABLE_PATH:process.env.CHROME_BIN}),"linux"===process.platform&&"function"==typeof process.getuid&&0===process.getuid()&&(i={...i??process.env,PLAYWRIGHT_MCP_SANDBOX:"false"},ls.info("[stably-browser-hook] Running as root on Linux, disabling Chromium sandbox")),new Promise(t=>{m(process.execPath,[e,...o],{timeout:3e4,env:i},(e,r,n)=>{if(e)return ls.error("[stably-browser-hook] Failed to start daemon",{error:e.message,stderr:n}),void t({ok:!1,...Mc(e.message,n??"",e.killed??!1)});ls.info("[stably-browser-hook] Daemon started",{stdout:r.trim()}),t({ok:!0})})})}function Hc(e,t){return t?`${e}-${t}`:e}function Gc(e){if(e&&"object"==typeof e&&"agent_id"in e){const t=e.agent_id;return"string"==typeof t?t:void 0}}async function Wc(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}`,fn);n.searchParams.set("projectId",r);const s=await fetch(n.toString(),{method:"GET",headers:{Authorization:`Bearer ${e}`}});if(!s.ok)throw new Error(`Poll failed: HTTP ${s.status}`);return s.json()}async function Vc(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/acquire`,fn).toString(),s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});if(!s.ok)throw new Error(`Acquire failed: HTTP ${s.status}`);return s.json()}async function Yc(e,t,r){const n=new URL(`/internal/v1/cli/browser/kernelsh/${r}/health`,fn);n.searchParams.set("projectId",t);const s=n.toString();try{const t=await fetch(s,{method:"GET",headers:{Authorization:`Bearer ${e}`}});return!!t.ok&&(await t.json()).alive}catch{return!1}}var zc=2e3,qc=class{authProvider;projectId;sessions=new Map;healthCheckTimer=null;released=!1;configDir=null;constructor(e){this.authProvider=e.authProvider,this.projectId=e.projectId}async acquire(e,t){const r=this.sessions.get(e);if(r&&!r.needsRecreation)return r.session;r?.needsRecreation&&await this.releaseSession(e),this.released=!1;const n=await this.acquireViaQueue(t);ls.info("[cloud-browser] Waiting for CDP endpoint to be ready...",{sessionName:e,sessionId:n.sessionId}),await async function(e){const t=Date.now()+3e4;for(;Date.now()<t;)try{return void await new Promise((t,r)=>{const n=new ve(e),s=setTimeout(()=>{n.close(),r(new Error("CDP connection timeout"))},5e3);n.on("open",()=>{n.send(JSON.stringify({id:1,method:"Browser.getVersion",params:{}}))}),n.on("message",e=>{try{const o=JSON.parse(e.toString());1===o.id&&(clearTimeout(s),n.close(),o.error?r(new Error(`CDP error: ${o.error.message}`)):t())}catch{}}),n.on("error",e=>{clearTimeout(s),n.close(),r(e)})})}catch(e){const r=t-Date.now();if(r<=500)throw new Error(`CDP endpoint not ready after 30000ms: ${e instanceof Error?e.message:String(e)}`);ls.debug("[cloud-browser] CDP not ready, retrying...",{error:e instanceof Error?e.message:String(e),remainingMs:r}),await Kc(500)}throw new Error("CDP endpoint not ready after 30000ms")}(n.cdpUrl),ls.info("[cloud-browser] CDP endpoint ready",{sessionName:e,sessionId:n.sessionId});const s=this.writeConfig(e,n.cdpUrl);return this.sessions.set(e,{session:n,configPath:s,needsRecreation:!1}),this.ensureHealthCheck(),n}async release(){if(this.released)return;this.released=!0,this.stopHealthCheck();const e=Array.from(this.sessions.keys()).map(e=>this.releaseSession(e));await Promise.all(e),this.cleanupConfigDir()}needsRecreation(e){return this.sessions.get(e)?.needsRecreation??!1}getConfigPath(e){return this.sessions.get(e)?.configPath??null}getAnyConfigPath(){for(const e of this.sessions.values())if(!e.needsRecreation)return e.configPath;return null}isActive(){return this.sessions.size>0&&!this.released}removeSession(e){this.sessions.delete(e)}async acquireViaQueue(e){const t=await this.authProvider.getAuthHeader(),r=await async function(e,t){const r=new URL("/internal/v1/browser/request",fn).toString();try{const n=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:t,source:"cli-browser-session"})});if(n.ok||202===n.status){const e=await n.json();return{ok:!0,browserRequestId:e.browserRequestId,initialStatus:e.status}}if(403===n.status)return{ok:!1,status:"forbidden",message:(await n.json().catch(()=>({error:"Forbidden"}))).error??"Cloud browsers not available on your plan."};const s=await n.text().catch(()=>"");return{ok:!1,status:"error",message:`HTTP ${n.status}: ${s.slice(0,200)}`}}catch(e){return{ok:!1,status:"error",message:e instanceof Error?e.message:String(e)}}}(t,this.projectId);if(!r.ok){if("forbidden"===r.status)throw new Error(`Cloud browsers not available on your plan. ${r.message}`);throw new Error(`Cloud browser unavailable: ${r.message}`)}const{browserRequestId:n,initialStatus:s}=r;"queued"===s&&e?.();const o=Date.now()+3e5;for(;Date.now()<o;){const t=await this.authProvider.getAuthHeader(),r=await Wc(t,n,this.projectId);switch(r.status){case"pending":await Kc(zc);continue;case"queued":e?.(),await Kc(zc);continue;case"provisioning":ls.debug("[cloud-browser] Browser is starting up..."),await Kc(zc);continue;case"ready":try{const e=await this.authProvider.getAuthHeader(),t=await Vc(e,n,this.projectId);return{sessionId:t.sessionId,browserRequestId:n,cdpUrl:t.cdpUrl,liveViewUrl:t.liveViewUrl??""}}catch{ls.debug("[cloud-browser] Acquire failed, re-polling status"),await Kc(zc);continue}case"failed":throw new Error(r.error??"Browser provisioning failed. Please try again.");case"cancelled":case"stopped":throw new Error("Browser request was cancelled.");default:throw new Error(`Unexpected browser request status: ${r.status}`)}}const i=await this.authProvider.getAuthHeader();throw await async function(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/cancel`,fn).toString();try{const s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});s.ok||ls.warn("[cloud-browser] Failed to cancel browser request",{browserRequestId:t,status:s.status})}catch(e){ls.warn("[cloud-browser] Error cancelling browser request",{browserRequestId:t,error:e instanceof Error?e.message:String(e)})}}(i,n,this.projectId).catch(()=>{}),new Error("Cloud browser unavailable: timed out waiting for provisioning. Remove --browser=cloud to use a local browser, or wait for a browser to free up.")}writeConfig(e,t){this.configDir||(this.configDir=i(N(),`stably-cloud-browser-${process.pid}`),I(this.configDir,{recursive:!0}));const r=e.replace(/[^a-zA-Z0-9_-]/g,"_"),n=i(this.configDir,`config-${r}.json`),s={browser:{cdpEndpoint:t,isolated:!1},saveSession:!1,outputDir:i(process.cwd(),".stably-browser")};return T(n,JSON.stringify(s,null,2),"utf-8"),ls.debug("[cloud-browser] Wrote config file",{sessionName:e,path:n}),n}cleanupConfigDir(){if(this.configDir){try{_(this.configDir,{recursive:!0,force:!0})}catch{}this.configDir=null}}async releaseSession(e){const t=this.sessions.get(e);if(!t)return;const{sessionId:r,browserRequestId:n}=t.session;ls.info("[cloud-browser] Releasing session",{sessionName:e,sessionId:r,browserRequestId:n});try{const e=await this.authProvider.getAuthHeader();await async function(e,t,r){const n=new URL(`/internal/v1/browser/request/${t}/release`,fn).toString();try{const s=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({projectId:r})});s.ok||ls.warn("[cloud-browser] Failed to release browser",{browserRequestId:t,status:s.status})}catch(e){ls.warn("[cloud-browser] Error releasing browser",{browserRequestId:t,error:e instanceof Error?e.message:String(e)})}}(e,n,this.projectId)}catch(t){ls.warn("[cloud-browser] Error releasing session",{sessionName:e,sessionId:r,error:t instanceof Error?t.message:String(t)})}this.sessions.delete(e)}ensureHealthCheck(){this.healthCheckTimer||(this.healthCheckTimer=setInterval(async()=>{if(0===this.sessions.size||this.released)this.stopHealthCheck();else for(const[e,t]of this.sessions)if(!t.needsRecreation)try{const r=await this.authProvider.getAuthHeader();await Yc(r,this.projectId,t.session.sessionId)||(ls.warn("[cloud-browser] Browser session is dead, marking for recreation",{sessionName:e,sessionId:t.session.sessionId}),t.needsRecreation=!0)}catch(r){ls.warn("[cloud-browser] Health check failed",{sessionName:e,sessionId:t.session.sessionId,error:r instanceof Error?r.message:String(r)})}},3e4),this.healthCheckTimer.unref&&this.healthCheckTimer.unref())}stopHealthCheck(){this.healthCheckTimer&&(clearInterval(this.healthCheckTimer),this.healthCheckTimer=null)}};function Kc(e){return new Promise(t=>setTimeout(t,e))}function Jc({configuredSessionName:e,isFixMode:t,useCloudBrowser:r}){return e??(t||r?"auto":"default")}var Xc=he.object({verdict:he.enum(["PASS","FAIL","INCONCLUSIVE"]),steps:he.array(he.string()).min(1),reason:he.string().nullable(),evidence:he.array(he.string())}).superRefine((e,t)=>{"PASS"===e.verdict||e.reason&&0!==e.reason.trim().length||t.addIssue({code:he.ZodIssueCode.custom,path:["reason"],message:"reason is required for FAIL and INCONCLUSIVE verdicts"})}),Qc=/\bmcp__playwright-mcp__[a-z0-9_]+\b/gi,Zc=/\.playwright-mcp(?:\/[^\s"'`)\]]*)?/gi,el=/\bplaywright[\s_-]?mcp\b/gi;function tl(e){return e.replace(Qc,"browser_tool").replace(Zc,"verification-artifact").replace(el,"browser automation")}function rl(e){return{...e,steps:e.steps.map(e=>tl(e)),reason:e.reason?tl(e.reason):null,evidence:e.evidence.map(e=>tl(e))}}function nl(e){const t=e.matchAll(/```verdict\s*\r?\n([\s\S]*?)\r?\n```/g);let r=null;for(const e of t)try{const t=JSON.parse(e[1]??"");r=Xc.parse(t)}catch{}return r}function sl({mode:e,lastAssistantText:t,maxLength:r=1e4}){const n="verify"===e&&t?tl(t):t;return n?n.slice(0,r):null}var ol=e=>{const t=e.prompt;return(Array.isArray(t)?t.join(" "):t)?.trim()||void 0},il=e=>new Promise(t=>setTimeout(t,e));function al(e){return e>0}var cl=["Bash","Read","Write","Edit","Glob","Grep","Task","Skill"],ll=["Task","Skill"],ul=["Bash","Read","Write","Edit","Glob","Grep","mcp__session-control"],dl=e=>{if("EPIPE"!==e.code)throw e},pl="__main__",fl=[3e3,5173,4173,8080,4200,8e3],hl=/\b(TEST_EMAIL|TEST_PASSWORD|auth|authentication|credentials|login|log in|sign in)\b/i,gl=/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/i,ml=/playwright[\s_-]?mcp/i,yl=e=>"mcp__auto-heal-report__generate-report"===e;async function bl(e,t){return!!e&&(!!e.hasQueuedMessages()||new Promise(r=>{const n=setTimeout(()=>{clearInterval(s),r(!1)},t),s=setInterval(()=>{e.hasQueuedMessages()&&(clearTimeout(n),clearInterval(s),r(!0))},200)}))}async function wl(e){return new Promise(t=>{const r=new te.Socket;let n=!1;const s=e=>{n||(n=!0,r.destroy(),t(e))};r.setTimeout(700),r.once("connect",()=>s(!0)),r.once("timeout",()=>s(!1)),r.once("error",()=>s(!1)),r.connect(e,"127.0.0.1")})}var vl=async(e,t,r)=>{const n=r?"[Y/n]":"[y/N]",s=(await e.question(`${Dr("info","?")} ${t} ${ne.gray(n)} `)).trim().toLowerCase();return s?"y"===s||"yes"===s:r},Il=async e=>{if("single"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"create-from-diff")}else if("verify"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"verify")}else if("fix"===e.mode)ls.initSession(`fix-${e.runId}`);else if("plan"===e.mode){const t=Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt;ls.initSession(t||"plan")}ls.info("Agent session starting",{mode:e.mode});const a=(e=>{switch(e.mode){case"chat":return"Ask Stably to build tests for you";case"init":return"Setting up Playwright and Stably SDK";case"fix":return"Fixing broken tests";case"single":return ol(e)||"Creating tests from PR/branch changes";case"verify":return ol(e)||"Verifying application";case"plan":return ol(e)||"Planning test coverage"}})(e),c=((e,t)=>{const r=e?.trim().toLowerCase();return r?"1"===r||"true"===r||"yes"===r?t:"chat"===r||"single"===r||"fix"===r||"init"===r||"verify"===r||"plan"===r||"error"===r?r:null:null})(process.env.STABLY_CLI_VISUAL_MOCK,e.mode);if(process.env.STABLY_CLI_VISUAL_MOCK&&!c)throw new Error("Invalid STABLY_CLI_VISUAL_MOCK value. Expected one of: 1, true, chat, single, fix, init, verify, plan, error.");if(c){if(ls.info("Running CLI visual mock session",{requestedMode:e.mode,scenario:c}),"error"===c){const e={log:[{content:"Visual mock mode enabled. Simulating a failed AI run without contacting the backend.",id:0,kind:"text"}],promptDisplay:a,status:"running"},t=await Ho(e);return t.setRunningLabel({label:"Simulating upstream failure..."}),await new Promise(e=>setTimeout(e,220)),t.setStatus({status:"error",error:"Mocked AI provider failure for CLI visual testing."}),await new Promise(e=>setTimeout(e,220)),void await t.cleanup()}return void await(async({mode:e,promptDisplay:t})=>{const r={log:[],promptDisplay:t,status:"running"},n=await Ho(r,"init"===e?{showSpinnerImmediately:!0,isInitMode:!0}:"fix"===e?{isFixMode:!0}:void 0),s=async(e,t=180)=>{e(),await il(t)};try{if("chat"===e)return await s(()=>n.appendText({text:"Visual mock mode enabled. No real AI calls will be made.\n\n"})),await s(()=>n.appendUserMessage({text:"Create a login test for the dashboard."})),await s(()=>n.appendThinking({text:"Scanning the repository for auth flows and existing test patterns..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Glob",toolInput:{pattern:"**/*login*"}})),await s(()=>n.addToolResult({message:"Found 4 matching files"})),await s(()=>n.appendText({text:"I found the existing auth helpers and would generate a Playwright test next.\n"})),void await s(()=>n.setStatus({status:"success",result:"Mock chat transcript complete."}),260);if("single"===e)return await s(()=>n.setRunningLabel({label:"Analyzing app structure..."})),await s(()=>n.appendThinking({text:"Reviewing routes, existing tests, and the requested flow..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Read",toolInput:{file_path:"app/page.tsx"}})),await s(()=>n.addToolResult({message:"Read homepage and CTA structure"})),await s(()=>n.addTool({rawName:"Write",toolInput:{file_path:"tests/auth/login.spec.ts"}})),await s(()=>n.addToolResult({message:"Created tests/auth/login.spec.ts"})),await s(()=>n.appendText({text:"Generated a focused login flow test with stable selectors and assertions.\n"})),void await s(()=>n.setStatus({status:"success",result:"Created 1 mock test file: tests/auth/login.spec.ts"}),260);if("verify"===e)return await s(()=>n.appendText({text:"Starting verification...\nTarget URL: http://localhost:3000\n"})),await s(()=>n.setRunningLabel({label:"Calibrating verification flow..."})),await s(()=>n.appendThinking({text:"Planning a short verification pass for the requested path..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"mcp__playwright__browser_navigate",toolInput:{url:"http://localhost:3000"}})),await s(()=>n.addToolResult({message:"Opened application homepage"})),await s(()=>n.addTool({rawName:"mcp__playwright__browser_click",toolInput:{element:"Sign in button"}})),await s(()=>n.addToolResult({message:"Reached login form successfully"})),await s(()=>n.appendText({text:"Verification passed for the main sign-in path.\n"})),void await s(()=>n.setStatus({status:"success",result:"Verified requested behavior in visual mock mode."}),260);if("fix"===e)return await s(()=>n.setRunningLabel({label:"Triaging failing tests..."})),await s(()=>n.addSubagentStart({toolUseId:"triage-1",subagentType:"triage",description:"Analyze failing selectors and isolate the root cause"})),await s(()=>n.addSubagentActivity({toolUseId:"triage-1",kind:"text",content:'Selector drift detected after the button label changed from "Log in" to "Sign in".'})),await s(()=>n.setSubagentStatus({toolUseId:"triage-1",status:"complete"})),await s(()=>n.addSubagentStart({toolUseId:"code-1",subagentType:"code-worker",description:"Fix login test selectors"})),await s(()=>n.addSubagentActivity({toolUseId:"code-1",kind:"tool",content:"Edit tests/auth/login.spec.ts"})),await s(()=>n.addSubagentActivity({toolUseId:"code-1",kind:"tool_result",content:"Updated role-based button locator"})),await s(()=>n.setSubagentStatus({toolUseId:"code-1",status:"complete"})),await s(()=>n.addSubagentStart({toolUseId:"validation-1",subagentType:"validation",description:"Re-run impacted tests"})),await s(()=>n.addSubagentActivity({toolUseId:"validation-1",kind:"text",content:"Validation run passed for 3/3 affected tests."})),await s(()=>n.setSubagentStatus({toolUseId:"validation-1",status:"complete"})),void await s(()=>n.setStatus({status:"success",result:"Mock fix flow complete. 1 test fixed, 0 failed."}),260);if("init"===e)return await s(()=>n.addTool({rawName:"Bash",toolInput:{command:"npm install -D @playwright/test @stablyai/playwright"}})),await s(()=>n.addToolResult({message:"Installed Playwright and Stably SDK dependencies"})),await s(()=>n.addTool({rawName:"Write",toolInput:{file_path:"playwright.config.ts"}})),await s(()=>n.addToolResult({message:"Configured Playwright reporter and base settings"})),await s(()=>n.appendText({text:"Playwright and the Stably SDK are configured. You can run `stably test` next.\n"})),void await s(()=>n.setStatus({status:"success",result:"Initialization mock complete."}),260);await s(()=>n.setRunningLabel({label:"Building coverage plan..."})),await s(()=>n.appendThinking({text:"Comparing routes, existing tests, and high-risk gaps..."})),await s(()=>n.flushThinkingRender(),120),await s(()=>n.addTool({rawName:"Read",toolInput:{file_path:"tests/"}})),await s(()=>n.addToolResult({message:"Mapped existing coverage across auth, billing, and onboarding"})),await s(()=>n.appendText({text:"Planned three new `test.fixme()` specs for the highest-risk uncovered flows.\n"})),await s(()=>n.setStatus({status:"success",result:"Planning mock complete."}),260)}finally{await il(120),await n.cleanup()}})({mode:c,promptDisplay:a})}process.stdout.on("error",dl),process.stderr.on("error",dl);const l=e=>{if("EPIPE"!==e.code)throw e};process.on("uncaughtException",l),ls.debug("Checking authentication");const u=await ys({autoLogin:"chat"===e.mode||"init"===e.mode}),d=new vs(u);ls.debug("Authentication resolved",{authType:u.type});const p="oauth"===u.type?u.auth.context.orgId:void 0,f=n.resolve(process.cwd()),h="fix"!==e.mode,g=n.join(f,".env"),y=h&&v.existsSync(g)&&v.statSync(g).isFile(),b=y?t(v.readFileSync(g,"utf8")):{};ls.debug("Environment file",{path:g,exists:y,variableCount:Object.keys(b).length});const I="chat"!==e.mode&&"init"!==e.mode,T="chat"===e.mode,_="chat"===e.mode||"init"===e.mode,S="single"===e.mode,k="verify"===e.mode,P="plan"===e.mode,C=S||k||P;let R,U=new io;"init"===e.mode&&(R=e.initPreferences??await async function(){if(!process.stdin.isTTY||!process.stdout.isTTY)return{googleAuth:!0,emailPackage:!1};const e=re({input:process.stdin,output:process.stdout});try{return{googleAuth:await vl(e,"Include Google Auth test helper guidance? (recommended)",!0),emailPackage:await vl(e,"Install @stablyai/email for inbox testing?",!1)}}finally{e.close()}}());const L="chat"===e.mode?e.getHelpText:void 0,$="verify"===e.mode?(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt).trim():"";let D="verify"===e.mode?e.url?.trim()||function(e){const t=Array.isArray(e)?e.join(" "):e,r=e=>e.replace(/[),.;!?]+$/,""),n=e=>{const t=r(e);try{return new URL(t).toString()}catch{return}},s=t.match(/https?:\/\/[^\s"'`<>]+/i);if(s)return n(s[0]);const o=t.match(/(?<!@)\b(?:localhost|(?:\d{1,3}\.){3}\d{1,3}|(?:[a-z0-9-]+\.)+[a-z]{2,63})(?::\d{2,5})?(?:\/[^\s"'`<>]*)?/i);if(!o)return;const i=r(o[0]),a=i.split("/")[0]??i,c=a.split(":")[0]?.toLowerCase()??"",l=c.includes(".")?c.split(".").at(-1)??"":"";return new Set(["ts","tsx","js","jsx","md","json","yaml","yml","txt","css"]).has(l)?void 0:n(`${"localhost"===c||"127.0.0.1"===c?"http":"https"}://${i}`)}(e.prompt):void 0;if("verify"===e.mode&&!e.url&&D&&ls.info("[verify] Using URL extracted from prompt",{url:D}),"verify"!==e.mode||D||(D=await async function(){for(const e of fl)if(await wl(e))return`http://localhost:${e}`}(),D?ls.info("[verify] Detected local application URL",{url:D}):ls.info("[verify] No common localhost dev server detected")),"verify"===e.mode&&!1!==e.interactive){const e=await async function({envFilePath:e,envFromFile:t,initialUrl:r,verifyPromptText:s,workingDir:o}){if(!process.stdin.isTTY||!process.stdout.isTTY)return{resolvedUrl:r};const i=n.join(o,"STABLY.md"),a=v.existsSync(i),c=a?await v.promises.readFile(i,"utf8").catch(()=>{}):void 0;let l=r?.trim()||void 0;const u=!l,d=(({envEmail:e,envPassword:t,promptIncludesEmail:r,stablyMdContent:n})=>!Boolean(e?.trim()&&t?.trim())&&!r&&!(e=>!!e&&hl.test(e))(n))({envEmail:process.env.TEST_EMAIL??t.TEST_EMAIL,envPassword:process.env.TEST_PASSWORD??t.TEST_PASSWORD,promptIncludesEmail:gl.test(s),stablyMdContent:c}),p=!a;if(!u&&!d&&!p)return{resolvedUrl:l};const f=re({input:process.stdin,output:process.stdout}),h=async(r,n)=>{const s=v.existsSync(e)?await v.promises.readFile(e,"utf8"):"",o=new RegExp(`^${i=r,i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}=.*$`,"m");var i;const a=`${r}=${(e=>/^[A-Za-z0-9_./:@-]+$/.test(e)?e:`"${e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}"`)(n)}`,c=o.test(s)?s.replace(o,a):`${s}${s&&!s.endsWith("\n")?"\n":""}${a}\n`;await v.promises.writeFile(e,c,"utf8"),t[r]=n};try{if(u){const e=(await f.question("Starting URL (optional, Enter to auto-infer): ")).trim();e&&(l=e)}if(d&&await vl(f,"No TEST_EMAIL/TEST_PASSWORD found in .env and no auth guidance found in STABLY.md. Configure credentials in .env now?",!0)){const e=(await f.question("TEST_EMAIL: ")).trim(),t=(await f.question("TEST_PASSWORD: ")).trim();e&&t&&(await h("TEST_EMAIL",e),await h("TEST_PASSWORD",t),process.env.TEST_EMAIL||(process.env.TEST_EMAIL=e),process.env.TEST_PASSWORD||(process.env.TEST_PASSWORD=t))}if(p&&await vl(f,"No STABLY.md found. Create one at repository root for project instructions?",!0)){const e=["# STABLY.md","","Project instructions for Stably agent runs.","","## Verify Notes","- Keep verification scope to requested behavior only.","- Use TEST_EMAIL and TEST_PASSWORD env vars for authenticated flows.","","## Special Instructions","- Add project-specific constraints here.",""].join("\n");await v.promises.writeFile(i,e,"utf8");const t=(await f.question("Special verify instruction to append to STABLY.md (optional): ")).trim();if(t){const e=await v.promises.readFile(i,"utf8"),r=/(^|\n)## Special Instructions\s*$/m.test(e)?`${e}${e.endsWith("\n")?"":"\n"}- ${t}\n`:`${e}${e.endsWith("\n")?"":"\n"}\n## Special Instructions\n- ${t}\n`;await v.promises.writeFile(i,r,"utf8")}}return{resolvedUrl:l}}finally{f.close()}}({envFilePath:g,envFromFile:b,initialUrl:D,verifyPromptText:$,workingDir:f});D=e.resolvedUrl?.trim()||D}"verify"!==e.mode||D||ls.warn("No verify URL provided and no local app detected on common ports. The agent will try to infer a URL from code/config.");const N={log:[],promptDisplay:a,status:"running"};let O,B,j,M,F=I,H=!1,q=0,K=[],J=!1,X=!1,Q=0;const Z=new Map,ee=[],te=e=>{ee.push(e)},se=new Map;let oe=null,ie=!1,ae=!1;const ce=Date.now();let le,ue="fix"===e.mode?{suiteId:e.runId,phase:"initializing",totalTests:null,fixedTests:0,failedTests:0,currentTestDescription:null,lastTestDescription:null,startedAt:ce,endedAt:null,isError:!1,updatedAt:ce,recentActivity:[],workers:[{id:pl,testDescription:"Orchestrator",workerType:"main",status:"running",summary:null,startedAt:ce,endedAt:null,activity:[]}]}:null;const de=new Set,pe=new Map,fe=(e,t)=>{const r=pe.get(e);if(!r)return;const n={...r,...t};pe.set(e,n),_e({workers:Array.from(pe.values())})},he=(e,t)=>{if(!ue)return;const r=ue.workers.map(r=>{if(r.id!==e)return r;const n=[...r.activity,{...t,timestamp:Date.now()}].slice(-15);return{...r,activity:n}});ye({workers:r})},ge=e=>{if(!ue)return;const t=[...ue.recentActivity,{...e,timestamp:Date.now()}].slice(-10);ye({recentActivity:t})},me=e=>(ue?.workers??[]).map(t=>t.id===pl?{...t,status:e?"failed":"succeeded",endedAt:t.endedAt??Date.now()}:"running"===t.status?{...t,status:"failed",endedAt:Date.now()}:t),ye=e=>{ue&&!le?.isClosed&&(ue={...ue,...e,updatedAt:Date.now()},le?.sendProgress(ue))},be=async t=>{if("fix"===e.mode){if("STARTED"===t){if(ie)return;ie=!0}else{if(ae)return;ae=!0}try{await(async({authHeader:e,orgId:t,runId:r,status:n})=>{const s=await(o={auth:e,body:{status:n},client:In(),headers:_s(t),path:{runId:r}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-status",...o,headers:{"Content-Type":"application/json",...o.headers}}));var o;if(s.error)throw new Error(`Failed to update autoheal status (${s.response.status})`)})({authHeader:await d.getAuthHeader(),orgId:p,runId:e.runId,status:t})}catch{}}},ve=Date.now();let Ie,Te=null;const _e=e=>{Te&&!Ie?.isClosed&&(Te={...Te,...e,updatedAt:Date.now()},Ie?.sendProgress(Te))},Ee=e=>{if(!Te)return;const t=[...Te.recentActivity,{...e,timestamp:Date.now()}].slice(-10);_e({recentActivity:t})};let Se;const xe=(e.mode,!0);if(ls.info("[session] Checking session creation",{mode:e.mode,shouldCreateSession:xe}),"fix"===e.mode)ls.info("[session] Deferring fix-mode session creation until after early-exit checks");else try{ls.info("[session] Creating progress session",{mode:e.mode,projectId:bs(u)});const t=await mo({agentMode:e.mode,authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u)}),{sessionId:r,sessionMode:n}=t;if(Se=r,C){const t="single"===e.mode||"verify"===e.mode||"plan"===e.mode?Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt:null,n=ao(f);Te={sessionId:r,phase:"initializing",startedAt:ve,endedAt:null,isError:!1,updatedAt:ve,currentActivity:null,filesCreated:[],traceProofs:[],recentActivity:[],prompt:t||null,environment:{gitBranch:n?.branch??null,workingDirectory:f,nodeVersion:process.version,cliVersion:pn}},Ie=new Ls({authProvider:d,orgId:p,sessionId:r,onUserMessage:e=>{U&&(ls.info("[ws] Injecting web UI message into agent",{contentLength:e.length}),Ee({type:"user_message",summary:e}),Fe({text:`[Web] ${e}`}),U.pushText(`[Message from web UI user]: ${e}`),F||(F=!0,Ze({status:"running"})))}}),await Ie.start(),_e({phase:"initializing"})}ls.info(`[${n}] Progress session created`,{sessionId:r})}catch(e){const t=e instanceof Error?e.message:String(e);ls.warn(`[progress] Session creation failed (non-fatal): ${t}`)}const Ae={current:e=>{}},ke={current:async()=>{}};let Ce;const Re={current:()=>{}};let Le=!1,$e=!1;const{addSubagentActivity:De,addSubagentStart:Ne,addTool:Oe,appendCancelled:Be,appendText:je,appendThinking:Me,appendUserMessage:Fe,cancelThinkingRender:He,cleanup:Ge,dismissPermissionPrompt:We,flushThinkingRender:Ve,resetThinkingLogIndex:Ye,setExiting:ze,setRunningLabel:qe,setStatus:Ke,setSubagentStatus:Je,updateFixProgress:Xe}=await Ho(N,"init"===e.mode?{onCancel:()=>Re.current(),onExit:()=>ke.current(),onSend:e=>Ae.current(e),showSpinnerImmediately:!0,isInitMode:!0}:"chat"===e.mode?{onCancel:()=>Re.current(),onExit:()=>ke.current(),onSend:e=>Ae.current(e)}:"fix"===e.mode?{onExit:()=>ke.current(),isFixMode:!0}:{onExit:()=>ke.current()});let Qe=N.status;const Ze=({error:e,result:t,status:r})=>{Qe=r,Ke({error:e,result:t,status:r})};let et,tt;k&&(je({text:"Starting verification...\n"}),je(D?{text:`Target URL: ${D}\n`}:{text:"Target URL: auto-detect (agent may infer from project config)\n"}),qe({label:"Calibrating verification flow..."})),Ae.current=e=>{const t=e.trim();if(T&&!ls.getLogFilePath()&&ls.initSession(t||"chat"),ls.debug("User message",{text:t}),"/help"===t){F&&U&&(H=!0,O?.interrupt?.(),U.allowNextTurn(),F=!1),"running"===Qe&&Ze({status:"success"}),Fe({text:e});const t=L?.();return void je({text:t??"Help is not available in this session."})}if(T&&qe({label:void 0}),U){if(F)return Ze({status:"running"}),Fe({text:e}),U.pushText(e),void(q+=1);Ze({status:"running"}),Fe({text:e}),te({role:"user",content:e,timestamp:(new Date).toISOString()}),U.pushText(e),F=!0}};let rt="",nt="";const st=[],ot=[],it=[];let at;const ct=await(async e=>{try{const t=await kn(e,"stably.yaml");if(!t)return void ls.debug("No stably.yaml found");const r=await z(t,"utf-8");if(!r.trim())return;const n=Pe(r),s=Pc.parse(n.toJS()),o=s.agent?.fix?.maxTurnsPerIssue,i=s.agent?.fix?.maxParallelWorkers,a=!!s.agent?.fix?.rules;return ls.debug(`Loaded stably.yaml: maxTurnsPerIssue=${o??"default"}, maxParallelWorkers=${i??"default"}, hasRules=${a}`,{path:t,config:s.agent}),s}catch(e){return void ls.warn("Failed to parse stably.yaml",{error:e})}})(f),lt=ct?.agent?.fix?.skipAfterConsecutiveUnfixed,ut=await(async()=>{if("single"===e.mode){const r=await async function(e,t){const r=s(e);if(t){const e=s(r,t);return Eo(e,"output-flag"),{path:e,source:"output-flag"}}const n=Io(r);if(n){const e=await async function(e){try{const t=(await z(e,"utf-8")).match(/testDir:\s*['"]([^'"]+)['"]/);return t?.[1]}catch{return}}(n);if(e){const t=s(o(n),e);if(_o(t))return Eo(t,"playwright.config.ts"),{path:t,source:"playwright.config.ts"}}}for(const e of To){const t=i(r,e);if(_o(t))return Eo(t,"auto-detected"),{path:t,source:"auto-detected"}}return Eo(r,"cwd-fallback"),{path:r,source:"cwd-fallback"}}(f,e.outputDir);return at=r.path,t=e.prompt,`${(Array.isArray(t)?t.join(" "):t).trim()||"Create tests based on the changes in the current PR or branch. If the user references a specific PR number or branch name, first checkout that PR/branch using `gh pr checkout <number>` or `git checkout <branch>`. Use the Pull Request Context or Git Branch Context section of the system prompt to understand what code was changed, then create appropriate tests for the new or modified functionality. After generating the tests, run them locally (e.g. `pnpm stably test` or the repo's test command) and iterate until the new tests pass."}\n\n[Output directory: ${at}]`}var t;if("verify"===e.mode)return function(e,t){const r=(Array.isArray(e)?e.join(" "):e).trim()||"Verify the application behavior.",n=t?.trim();return n?`Starting URL: ${n}\nURL policy: treat this as the source of truth and do not switch domains unless the user explicitly asks.\n\nVerification prompt: ${r}`:r}(e.prompt,D);if("fix"===e.mode)try{ls.info("[fix] Fetching autoheal context",{runId:e.runId,skipAfterConsecutiveUnfixed:lt});const t=Date.now(),{context:r,autohealReportUrl:n,skippedTests:s,newerPassingSuiteId:o,envName:i}=await(async({authHeader:e,orgId:t,runId:r,skipAfterConsecutiveUnfixed:n})=>{ls.debug("Fetching autoheal context",{runId:r,skipAfterConsecutiveUnfixed:n});const s=await(o={auth:e,client:In(),headers:_s(t),path:{runId:r},query:null!=n?{skipAfterConsecutiveUnfixed:n}:{}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/autoheal-context",...o}));var o;if(404===s.response.status)throw ls.warn("Autoheal context not found",{runId:r,status:404}),new Error(`Run ID "${r}" was not found.`);if(401===s.response.status)throw ls.warn("Autoheal context fetch unauthorized",{runId:r,status:401}),new Error("Unauthorized: failed to fetch autoheal context (401).");if(422===s.response.status)throw ls.warn("Autoheal context fetch invalid request",{runId:r,status:422,error:s.error?.error}),new Error(s.error?.error??"Failed to fetch autoheal context (422).");if(!s.error){const e=Es.safeParse(s.data);if(e.success)return ls.debug("Autoheal context fetched successfully",{runId:r,contextSize:e.data.context.length,skippedTestCount:e.data.skippedTests?.length??0}),{context:e.data.context,autohealReportUrl:e.data.autohealReportUrl,skippedTests:e.data.skippedTests??[],newerPassingSuiteId:e.data.newerPassingSuiteId,envName:e.data.envName};throw ls.warn("Autoheal context response invalid",{runId:r}),new Error("Autoheal context response missing or invalid context.")}throw ls.warn("Autoheal context fetch failed",{runId:r,error:s.error}),new Error("Failed to fetch autoheal context")})({authHeader:await d.getAuthHeader(),orgId:p,runId:e.runId,skipAfterConsecutiveUnfixed:lt});if(i&&!Ue.remoteEnvName&&(ls.info("[fix] Auto-loaded remote env from run metadata",{envName:i}),Ue.remoteEnvName=i,tt=i),ls.info("[fix] Autoheal context fetched",{runId:e.runId,durationMs:Date.now()-t,contextLength:r.length,skippedTestCount:s.length}),et=n,s.length>0){ls.info(`[fix] Skipping ${s.length} test(s) that failed to be fixed ${lt}+ consecutive times`);for(const e of s)ls.info(`[fix] Skipped: ${e.testIdentifier} β ${e.testTitle} (unfixed ${e.consecutiveUnfixedCount}x)`)}if(o&&(ls.info("[fix] Tests already passing in a newer run β no session created",{newerPassingSuiteId:o}),Ze({status:"success",result:`Tests already passing in a newer run (${o}). Nothing to fix.`}),await Ge(),process.exit(0)),r.includes("No failing tests to fix (all were skipped).")&&(ls.info("[fix] All failing tests were skipped β creating skipped session"),xe&&await async function({authHeader:e,orgId:t,projectId:r,runId:n,reason:s,skippedTests:o,fetchImpl:i=fetch,apiUrl:a=fn}){const c=new URL("/internal/v1/cli/sessions/skipped",a).toString(),l={Authorization:e,"Content-Type":"application/json","X-STABLY-CLI-VERSION":pn};t&&(l["x-stably-org-id"]=t),await i(c,{method:"POST",headers:l,body:JSON.stringify({mode:"fix",projectId:r,...n?{playwrightSuiteRunId:n}:{},progress:{phase:"skipped",isError:!1,reason:s,skippedTests:o,endedAt:Date.now()}}),signal:AbortSignal.timeout(5e3)}).then(e=>{e.ok||console.warn(`[session] Failed to create skipped session: ${e.status} ${e.statusText}`)}).catch(e=>{console.warn(`[session] Failed to create skipped session: ${e instanceof Error?e.message:String(e)}`)})}({authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u),runId:e.runId,reason:`All ${s.length} failing test(s) skipped β each was unfixed ${lt??3}+ consecutive runs`,skippedTests:s}),Ze({status:"success",result:`All failing tests skipped (unfixed ${lt}+ consecutive times). Nothing to fix.`}),await Ge(),process.exit(0)),xe)try{ls.info("[session] Creating fix-mode progress session (post early-exit checks)");const t=await mo({agentMode:e.mode,authHeader:await d.getAuthHeader(),orgId:p,projectId:bs(u),runId:e.runId});Se=t.sessionId,ls.info("[fix] Progress session created",{sessionId:Se})}catch(e){const t=e instanceof Error?e.message:String(e);ls.warn(`[progress] Fix session creation failed (non-fatal): ${t}`)}return le||(ls.info("[fix] Creating WebSocket progress reporter"),le=new Rs({authProvider:d,orgId:p,runId:e.runId,onUserMessage:e=>{if(ls.info("[ws] Injecting web UI message into fix agent",{contentLength:e.length}),he(pl,{type:"user_message",summary:e}),ge({type:"user_message",summary:e}),Fe({text:`[Web] ${e}`}),!F)return U.pushText(`[Message from web UI user]: ${e}`),F=!0,void U.allowNextTurn();J||Date.now()-Q<2e3?U.pushText(`[Message from web UI user]: ${e}`):(K.push(e),j&&clearTimeout(j),j=setTimeout(()=>{j=void 0;const e=[...K];K=[],Q=Date.now(),mr(e)},500))}}),await le.start(),ye({phase:"initializing"})),be("STARTED"),r}catch(e){const t=e instanceof Error?e.message:"Failed to fetch autoheal context.";ls.error("[fix] Failed to fetch autoheal context",{error:t}),Ze({error:t,status:"error"}),await Ge(),process.exit(1)}if("plan"===e.mode){const t=(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt)?.trim();return t||"Analyze this repository and generate a comprehensive test coverage plan."}if("init"===e.mode){const e=R??{googleAuth:!0,emailPackage:!1};return["Set up Playwright with the Stably SDK.",`Preferences: Google Auth guidance: ${e.googleAuth?"yes":"no"}, @stablyai/email: ${e.emailPackage?"install":"skip"}.`].join(" ")}return""})(),dt=await async function(e){const t=n.resolve(e),r=n.join(t,"tests"),s=n.join(r,"helpers"),o=n.join(r,"assets"),i=function(e){const t=n.resolve(e);if(E(t))for(const e of co){const r=n.join(t,`playwright.config${e}`);if(E(r))return r}}(t)??n.join(t,"playwright.config.ts"),a=n.basename(i),c=n.join(r,"seed.spec.ts"),[l,u,d,p,f,h,g]=await Promise.all([po({defaultContent:"Unable to read directory",dirName:"working directory",dirPath:t}),po({defaultContent:"Unable to read directory",dirName:"tests directory",dirPath:r}),po({defaultContent:"Directory does not exist yet",dirName:"helpers directory",dirPath:s}),po({defaultContent:"Directory does not exist yet",dirName:"assets directory",dirPath:o}),uo({defaultContent:"File does not exist or could not be read",fileName:a,filePath:i}),uo({defaultContent:"File does not exist or could not be read",fileName:"seed.spec.ts",filePath:c}),fo(t)]);return{absolutePath:t,isEsmProject:g,directories:{assets:p,helpers:d,root:l,tests:u},files:{playwrightConfig:f,playwrightConfigFilename:a,seedSpec:h}}}(f),pt="fix"===e.mode?ct?.agent?.fix?.maxTurnsPerIssue:"single"===e.mode?ct?.agent?.create?.maxTurnsPerTestFile:void 0,ft="cloudBrowser"in e&&e.cloudBrowser,ht=ct?.agent?.fix?.maxParallelWorkers??3,gt="fix"===e.mode?await(async e=>{const t=await Cc(e,"STABLY-FIX.md");return t?.content})(f):void 0,mt="fix"===e.mode?ct?.agent?.fix?.rules:void 0;gt&&mt&&ls.warn("Both STABLY-FIX.md and stably.yaml agent.fix.rules found; using STABLY-FIX.md");const yt=gt??mt,bt=ct?.agent?.fix?.maxBudgetUsd??50,wt="verify"===e.mode?e.maxBudgetUsd??5:void 0,vt="single"===e.mode?ct?.agent?.create?.maxBudgetUsd??50:void 0,It="fix"===e.mode?bt:k?wt:vt,Tt="init"!==e.mode,_t="single"===e.mode?await(async e=>{const t=await Cc(e,"STABLY-CREATE.md");return t?.content})(f):void 0,Et=await(e=>Cc(e,"STABLY.md"))(f),St=Et?.content;let xt;if(k&&(qe({label:"Assembling verification context..."}),je({text:"Assembling workspace context...\n"})),ls.info("[fix] Fetching system prompt and subagent definitions",{mode:e.mode,isCloudBrowser:ft,maxParallelWorkers:ht,maxTurnsOverride:pt,maxBudgetUsd:It,hasCustomRules:!!yt,hasCreateRules:!!_t,hasStablyMd:!!St,stablyMdPath:Et?.path}),Et&&ls.info(`STABLY.md loaded (${Et.content.length} chars)`,{path:Et.path}),"fix"===e.mode&&tt){const e=await Is(tt);e.ok?xt=e.result:ls.warn("[fix] Failed to load auto-detected remote env, continuing without it",{envName:tt,error:e.error})}else xt=await Ts();const At=xt?Object.keys(xt.variables):[],kt=[...new Set([...Object.keys(b),...At])],Pt=Date.now(),Ct=await d.getAuthHeader(),[{systemPrompt:Rt,prContext:Ut},Lt]=await Promise.all([ho({allowedEnvVars:kt,mode:e.mode,workspaceInfo:dt,authHeader:Ct,customHeader:"single"===e.mode?e.customHeader:void 0,maxParallelWorkers:ht,isCloudBrowser:ft}),Tt?Ec({authHeader:Ct,mode:e.mode,maxTurnsOverride:pt}):Promise.resolve({})]);ls.info("[fix] System prompt and subagents fetched",{durationMs:Date.now()-Pt,systemPromptSize:Rt.length,subagentCount:Object.keys(Lt).length,maxTurnsOverride:pt??"default",hasPrContext:!!Ut});const $t=function(e){const t={};for(const[r,n]of Object.entries(e))void 0!==n&&(_c.has(r)||Tc.some(e=>r.startsWith(e))||(t[r]=n));return t}({...b,...process.env}),Dt=!0;ls.debug("AI proxy configuration",{useStablyAiProxy:Dt,wantsBypassProxy:!1,wantsUseOllama:!1}),ls.info("[fix] Acquiring AI proxy key",{useStablyAiProxy:Dt});const Nt=Date.now(),Ot=await async function({auth:e,client:t,source:r,metadata:n,duration:s}){try{const i=await(o={auth:e,client:t,body:{source:r,metadata:n??{},duration:s}},(o.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/v1/proxy/api-key",...o,headers:{"Content-Type":"application/json",...o.headers}})),a=i.response;if(i.error){const e="object"==typeof i.error&&"error"in i.error?i.error.error:"Unknown error";return{error:Ic(e,a)}}return i.data?{key:i.data.key}:{error:Ic("No data in response",a)}}catch(e){const t=e instanceof Error?e.message:"Unknown error";return{error:Ic(t)}}var o}({auth:Ct,client:In(),source:"cli"}),Bt=Ot?.key;if(ls.info("[fix] AI proxy key acquired",{durationMs:Date.now()-Nt,success:!!Bt,hasError:!!Ot?.error}),!Bt){const e=Ot?.error?.message?`Unable to make AI calls: ${Ot.error.message}`:"Unable to make AI calls. Check if you are authenticated.";ls.warn("Failed to get proxy API key",{error:Ot?.error?.message}),Ze({error:e,status:"error"}),await Ge(),ls.flush(),ls.printLogFileInfo(),process.exit(1)}ls.debug("Proxy API key acquired",{success:!!Bt});const jt="init"===e.mode,Mt="fix"===e.mode,Ft=!!ft,Ht=Ft?new qc({authProvider:d,projectId:bs(u)}):void 0,Gt=bc({localEnv:b,remoteEnv:xt?.variables,remoteSensitiveValues:xt?.sensitiveValues}),Wt=jt||P?void 0:function(e){let t,r;!function(e){const t=i(e,".gitignore");try{if(E(t)){const e=x(t,"utf-8"),r=e.split("\n").map(e=>e.trim());if(r.includes(Oc)||r.includes(`/${Oc}`))return;const n=e.length>0&&!e.endsWith("\n");A(t,`${n?"\n":""}${Oc}\n`)}}catch{}}(process.cwd());const n=new Set;let s,o;const a=()=>{var t;return o||(t=e.sessionName,o="auto"!==t?t:`stably-${process.pid}`),o};return{hook:async o=>{const i=o&&"object"==typeof o&&"tool_input"in o&&o.tool_input&&"object"==typeof o.tool_input&&"command"in o.tool_input&&"string"==typeof o.tool_input.command?o.tool_input.command:"";if(!Rc.test(i)&&!Uc.test(i))return{decision:"approve"};if(Uc.test(i)&&!Rc.test(i)){if(!r)try{r=await jc(),ls.info("[pwtrace-hook] Resolved binary",{path:r})}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:`pwtrace binary not found: ${t}`}}const e=`${process.execPath} ${r}`;return{decision:"approve",hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:i.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}}}}if(Uc.test(i)&&!r)try{r=await jc(),ls.info("[pwtrace-hook] Resolved binary (mixed command)",{path:r})}catch{}const c=!!e.cloudBrowserManager,l=new RegExp(`\\bstably-browser\\s+${Lc}close\\b(?!-)`).test(i),u=new RegExp(`\\bstably-browser\\s+${Lc}close-all\\b`).test(i),d=new RegExp(`\\bstably-browser\\s+${Lc}(?!close(?:-all)?\\b)\\w`).test(i);if(u){if(s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure via close-all",{reason:s.reason}),s=void 0),!d&&0===n.size)return{decision:"approve"};if(c){const t=e.cloudBrowserManager;await Promise.all(Array.from(n).map(e=>t.releaseSession(e)))}if(n.clear(),!d){if(!t)try{t=await Bc()}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:`stably-browser binary not found: ${t}`}}const e=`${process.execPath} ${t}`;let n=i.replace(/((?:npx\s+)?stably-browser\b[^;&|]*?)\s+(?:-s[= ]|--session[= ])[^\s;&|]+/g,"$1").replace(/(?<![./])\b(?:npx\s+)?stably-browser\b/g,e);if(Uc.test(n)&&r){const e=`${process.execPath} ${r}`;n=n.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}return{hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:n}}}}}if(l){if(s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure via close",{reason:s.reason}),s=void 0),!d&&0===n.size)return{decision:"approve"};const t=Gc(o),r=Hc(a(),t);n.delete(r),c&&e.cloudBrowserManager.getConfigPath(r)&&e.cloudBrowserManager.releaseSession(r)}if(!t)try{t=await Bc(),ls.info("[stably-browser-hook] Resolved binary",{path:t})}catch(e){const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:t,systemMessage:c?`stably-browser binary not found: ${t}. The stably-browser tool is unavailable. upload-trace-proof only uploads existing traces and does not depend on stably-browser, so it still works regardless. Report this issue to the user and suggest running locally instead.`:`stably-browser binary not found: ${t}. The stably-browser tool is unavailable. upload-trace-proof only uploads existing traces and does not depend on stably-browser, so it still works.`}}const p=Gc(o),f=Hc(a(),p),h=new RegExp(`\\bstably-browser\\s+${Lc}open\\b`).test(i);if(h&&s&&(ls.info("[stably-browser-hook] Clearing cached permanent daemon failure",{sessionName:f,reason:s.reason}),s=void 0),s)return{decision:"block",reason:`Browser unavailable: ${s.reason}`,systemMessage:s.guidance};if(c&&e.cloudBrowserManager.needsRecreation(f)&&n.has(f)&&(ls.info("[stably-browser-hook] Cloud browser needs recreation, clearing session",{sessionName:f}),n.delete(f),e.cloudBrowserManager.releaseSession(f)),(!l&&!u||d)&&!n.has(f))if(c){n.add(f),ls.info("[stably-browser-hook] Provisioning cloud browser...",{sessionName:f});try{let r=!1;const o=await e.cloudBrowserManager.acquire(f,()=>{r||(r=!0,e.onStatusLabel?.("Waiting for a browser to become available..."))});if(r&&e.onStatusLabel?.(void 0),o.liveViewUrl&&process.stderr.write(`Live view: ${o.liveViewUrl}\n`),!h){const r=e.cloudBrowserManager.getConfigPath(f),o=await Fc(t,f,e.headed,r??void 0);if(!o.ok)return n.delete(f),o.permanent&&(s={reason:o.reason,guidance:o.guidance}),{decision:"block",reason:`Failed to start stably-browser daemon with cloud browser: ${o.reason}`,systemMessage:o.guidance}}}catch(e){n.delete(f);const t=e instanceof Error?e.message:String(e);return{decision:"block",reason:`Cloud browser unavailable: ${t}`,systemMessage:`Failed to provision cloud browser: ${t}. Remove --browser=cloud to use a local browser instead.`}}}else if(h)n.add(f);else{n.add(f),ls.info("[stably-browser-hook] First browser command, starting daemon...",{sessionName:f,agentId:p});let r=await Fc(t,f,e.headed,void 0,"chromium");if(!r.ok&&r.reason.includes("not installed")&&(ls.info("[stably-browser-hook] Chromium not found, falling back to system Chrome..."),r=await Fc(t,f,e.headed,void 0,"chrome")),!r.ok)return n.delete(f),r.permanent&&(s={reason:r.reason,guidance:r.guidance}),{decision:"block",reason:`Failed to start stably-browser daemon: ${r.reason}`,systemMessage:r.guidance}}const g=`${process.execPath} ${t}`;let m=i.replace(/(?<![./])\b(?:npx\s+)?stably-browser\b/g,g);if(Uc.test(m)&&r){const e=`${process.execPath} ${r}`;m=m.replace(/\b(?:npx\s+)?pwtrace\b/g,e)}const y=[];if(m.includes("-s=")||m.includes("--session=")||y.push(`-s=${f}`),c){const t=e.cloudBrowserManager.getConfigPath(f);t&&!m.includes("--config=")&&y.push(`--config=${t}`),m=m.replace(/\s*--browser[= ]\S+/g,"")}e.headed&&!m.includes("--headed")&&y.push("--headed"),y.length>0&&(m=m.replaceAll(g,`${g} ${y.join(" ")}`)),u&&(m=m.replace(/([^;&|]*?\bclose-all\b)/g,e=>e.replace(/\s+(?:-s[= ]|--session[= ]|--config[= ])[^\s;&|]+/g,""))),$c.test(i)&&!m.includes("--trace")&&(m=m.replaceAll(/\brun-test\b/g,"run-test --trace=on")),$c.test(i)&&f!==a()&&!m.includes("--output")&&(m=m.replaceAll(/\brun-test\b/g,`run-test --output=.stably-browser/${f}/test-results`)),e.envVars&&(m=m.replace(Dc,(t,r)=>{const n=e.envVars[r];return null!=n?n:t}));const b=[];if("linux"===process.platform&&"function"==typeof process.getuid&&0===process.getuid()&&b.push("PLAYWRIGHT_MCP_SANDBOX=false"),$c.test(i)&&e.envVars)for(const[t,r]of Object.entries(e.envVars))b.push(`${t}=${Nc(r)}`);return b.length>0&&(m=`${b.join(" ")} ${m}`),ls.debug("[stably-browser-hook] Rewritten command",{original:i.slice(0,100),sessionName:f,agentId:p,envVarCount:b.length}),{hookSpecificOutput:{hookEventName:"PreToolUse",updatedInput:{command:m}}}},cleanup:async()=>{t&&n.size>0&&(await Promise.all(Array.from(n).map(e=>{return r=t,n=e,new Promise(e=>{m(process.execPath,[r,"close",`-s=${n}`],{timeout:1e4},t=>{t&&ls.debug("[stably-browser-hook] Failed to stop daemon",{error:t.message,sessionName:n}),e()})});var r,n})),n.clear()),e.cloudBrowserManager?.isActive()&&await e.cloudBrowserManager.release()}}}({sessionName:Jc({configuredSessionName:process.env.STABLY_PLAYWRIGHT_SESSION,isFixMode:Mt,useCloudBrowser:Ft}),headed:!("chat"!==e.mode||process.env.CI||"linux"===process.platform&&!process.env.DISPLAY),envVars:Gt,cloudBrowserManager:Ht,onStatusLabel:e=>qe({label:e})}),Vt=Mt?Mr.createLocal({workingDir:f}):void 0;Vt&&await Vt.captureSnapshot();const Yt=()=>{jt&&function({workingDir:e,options:t={}}){const n=function(e){const t=function(e){let t=r.resolve(e);for(;;){if(w.existsSync(r.join(t,".git")))return t;const n=r.dirname(t);if(n===t)return r.resolve(e);t=n}}(e),n=function(e,t){for(const r of cc(e,t))if(rc(r))return r}(e,t),s=oc(nc(e,/playwright\.config\.(ts|js|mts|mjs|cjs)$/).map(e=>r.dirname(e))),o=function(e){const t=new Set;for(const n of e)t.add(sc(r.dirname(n)));return oc(Array.from(t))}(nc(e,/\.(spec|test)\.(ts|js)$/)),i=s.length>0?s:o,a=n??(1===i.length?i[0]:void 0)??e,c=ac(a,t);if(!c)return{repoRoot:t,projectRoot:a,targetDir:void 0};if(!n&&c===r.resolve(e)&&function(e,t,r){const n=new Set;for(const s of e){const e=ac(s,r);e&&e!==t&&n.add(e)}return n.size>1}(i,c,t))return{repoRoot:t,projectRoot:a,targetDir:void 0};const l=ec(c);if(!l||!("workspaces"in l.contents))return{repoRoot:t,projectRoot:a,targetDir:c};const u=function(e,t){let n=r.resolve(e);const s=r.resolve(t);for(;n!==s;){if(w.existsSync(r.join(n,"package.json")))return n;const e=r.dirname(n);if(e===n)break;n=e}}(a,c);return{repoRoot:t,projectRoot:a,targetDir:u??c}}(e);if(n.targetDir){try{!function(e){const t=r.join(e,"package.json");if(!w.existsSync(t))return;const n=JSON.parse(w.readFileSync(t,"utf-8"));if({...n.dependencies,...n.devDependencies}.stably)ls.debug("stably package already present in dependencies");else{ls.info("stably package missing from devDependencies, installing...");try{Za({workingDir:e,packageManager:uc(e),packageSpec:"stably",targetSection:"devDependencies"}),ls.info("stably package installed successfully")}catch(e){ls.warn("Failed to install stably package",{error:String(e)})}}}(n.targetDir)}catch(e){ls.warn("Post-init: ensureStablyDependency failed",{error:String(e)})}try{!function(e){const t=ec(e);if(!t)return;const r=t.contents.devDependencies?.playwright??t.contents.dependencies?.playwright;if(r)if(lc(r)!==Bs)try{Za({workingDir:e,packageManager:uc(e),packageSpec:`playwright@${Bs}`,targetSection:t.contents.devDependencies?.playwright?"devDependencies":"dependencies"}),ls.info("standalone playwright version aligned successfully",{version:Bs})}catch(e){ls.warn("Failed to align standalone playwright version",{error:String(e)})}else ls.debug("standalone playwright already at supported version",{version:Bs});else ls.debug("standalone playwright package not present")}(n.targetDir)}catch(e){ls.warn("Post-init: alignStandalonePlaywrightVersion failed",{error:String(e)})}try{!function(e){const t=ec(e);if(t)if(lc(t.contents.devDependencies?.["@playwright/test"]??t.contents.dependencies?.["@playwright/test"])!==Bs)try{ls.info(`Updating @playwright/test to supported version ${Bs}...`),Za({workingDir:e,packageManager:uc(e),packageSpec:`@playwright/test@${Bs}`,targetSection:t.contents.dependencies?.["@playwright/test"]?"dependencies":"devDependencies"}),ls.info("@playwright/test updated successfully")}catch(e){ls.warn("Failed to update @playwright/test",{error:String(e)})}else ls.debug("@playwright/test already at supported version",{version:Bs});else ls.debug("No package.json found, skipping @playwright/test update")}(n.targetDir)}catch(e){ls.warn("Post-init: updatePlaywrightTest failed",{error:String(e)})}try{!function(e,t,n){const s=[];n.googleAuth&&s.push("Google Auth methods"),n.emailPackage&&s.push("@stablyai/email Inbox methods for email verification flows");const o=`Use Stably CLI for Playwright test runs (better reporting, auto-fix); import from @stablyai/playwright-test for agent.act(), aiAssert, page.extract(), page.getLocatorsByAI()${s.length>0?`; also use ${s.join(" and ")}`:""}.`,i=function(e,t){const n=["CLAUDE.md","AGENTS.md","AGENT.md","agent.md"];for(const s of cc(e,t)){let t;for(const o of n){const n=r.join(s,o);if(!w.existsSync(n))continue;t??=n;const i=w.readFileSync(n,"utf-8");if(/Stably CLI/i.test(i)&&i.includes("@stablyai/playwright-test"))return void ls.debug("Agent guidance already present",{file:r.relative(e,n)||o});if(ic(i))return n}if(t)return t}return r.join(e,"AGENTS.md")}(e,t);if(i){ls.info("Appending Stably guidance",{file:r.basename(i)});try{const e=w.existsSync(i)?w.readFileSync(i,"utf-8"):"",t=e.length>0&&!e.endsWith("\n")?"\n\n":e.length>0?"\n":"";w.writeFileSync(i,`${e}${t}${o}\n`,"utf-8"),ls.info("Agent guidance appended successfully")}catch(e){ls.warn("Failed to update agent guidance file",{error:String(e)})}}}(n.targetDir,n.repoRoot,t)}catch(e){ls.warn("Post-init: ensureAgentGuidance failed",{error:String(e)})}}else ls.warn("Post-init: could not resolve target package directory; skipping verification",{workingDir:e})}({workingDir:f,options:{googleAuth:R?.googleAuth,emailPackage:R?.emailPackage}})},zt=jt?(({onComplete:e})=>G({name:"session-control",tools:[W("complete_session",["Call this tool when you have completed your task and the session should end.","Use this instead of waiting for the user to manually terminate.","Only call this when you are confident the task is fully complete."].join("\n"),{summary:we.string().describe("A brief summary of what was accomplished")},({summary:t})=>{const r="string"==typeof t?t:String(t);return e(),Promise.resolve(`Session complete: ${r}`)})]}))({onComplete:()=>{Yt(),Ze({status:"success"}),ze(),U?.finish(),Ht?(setTimeout(()=>process.exit(0),5e3).unref(),Ht.release().finally(()=>process.exit(0))):process.exit(0)}}):void 0,qt=zt?{"session-control":zt}:{},Kt=S&&Ut?["mcp__create-report"]:[],Jt=S&&Se?["mcp__upload-trace-proof"]:[],Xt=jt?ul:k?cl:[...cl,...Mt?["mcp__auto-heal-report"]:[],...Kt,...Jt],Qt=jt?ul:T?[...ll,"mcp__stably-agent-control"]:k?ll:[...ll,...Kt,...Jt],Zt=S&&Ut?{"create-report":pc({prContext:Ut,authProvider:d,orgId:p,onReportPosted:e=>{_e({githubComment:{url:e.commentUrl,prNumber:Ut.prNumber}})}})}:{},er=S&&Se?{"upload-trace-proof":Xa({requestUploadUrl:e=>{const{testFilePath:t}=e;if(!t)return Promise.reject(new Error("testFilePath is required for create-mode trace uploads"));const r=Se;return d.getAuthHeader().then(e=>(async({authHeader:e,sessionId:t,testFilePath:r,orgId:n,contentType:s="application/zip"})=>{const o=await(i={auth:e,body:{testFilePath:r,contentType:s},client:In(),headers:_s(n),path:{sessionId:t}},(i.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/trace/upload-url",...i,headers:{"Content-Type":"application/json",...i.headers}}));var i;if(o.error)throw new Error(`Failed to presign session trace upload (${o.response.status})`);const a=fc.parse(o.data);return{traceBucketPath:a.traceBucketPath,expiresInSeconds:a.expiresInSeconds,key:a.key,uploadUrl:a.uploadUrl,sensitiveValues:a.sensitiveValues}})({authHeader:e,sessionId:r,testFilePath:t,orgId:p}))},onTraceUploaded:e=>{_e({traceProofs:Us(Te?.traceProofs??[],e)})}})}:{},tr=jt?qt:P?{}:Mt&&Vt?{"auto-heal-report":Qa({authProvider:d,diffTracker:Vt,orgId:p,runId:e.runId,workingDir:f}),"run-history":yc({authProvider:d,orgId:p,projectId:bs(u)}),...qt}:{...qt,...Zt,...er,"run-history":yc({authProvider:d,orgId:p,projectId:bs(u)}),environment:wc({hookEnvVars:Gt,localEnvSnapshot:{...b}})},rr="single"===e.mode,nr=jt?[]:rr?[{matcher:"Write",hooks:[no({onFileCreated:e=>{if(st.includes(e)||st.push(e),Te){if(Te.filesCreated.some(t=>"string"==typeof t?t===e:t.path===e))return;const t=n.isAbsolute(e)?e:n.join(f,e),r=n.basename(e),{sessionId:s}=Te,o=(async()=>{try{const n=await v.promises.readFile(t,"utf8"),o=await(async({authHeader:e,content:t,contentType:r="text/plain",filename:n,filePath:s,orgId:o,sessionId:i})=>{try{const{bucketPath:a,uploadUrl:c}=await(async({authHeader:e,contentType:t="text/plain",filename:r,filePath:n,orgId:s,sessionId:o})=>{const i=await(a={auth:e,body:{filename:r,filePath:n,contentType:t},client:In(),headers:_s(s),path:{sessionId:o}},(a.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/files/upload-url",...a,headers:{"Content-Type":"application/json",...a.headers}}));var a;if(i.error)throw new Error(`Failed to presign file upload (${i.response.status})`);const c=$s.parse(i.data);return{bucketPath:c.bucketPath,expiresInSeconds:c.expiresInSeconds,key:c.key,uploadUrl:c.uploadUrl}})({authHeader:e,contentType:r,filename:n,filePath:s,orgId:o,sessionId:i});return await xs({body:t,contentType:r,uploadUrl:c,errorContext:"file"}),await(async({authHeader:e,bucketPath:t,filename:r,filePath:n,orgId:s,sessionId:o})=>{const i=await(a={auth:e,body:{filename:r,filePath:n,bucketPath:t},client:In(),headers:_s(s),path:{sessionId:o}},(a.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/sessions/{sessionId}/files/confirm",...a,headers:{"Content-Type":"application/json",...a.headers}}));var a;if(i.error)throw new Error(`Failed to confirm file upload (${i.response.status})`)})({authHeader:e,bucketPath:a,filename:n,filePath:s,orgId:o,sessionId:i}),a}catch(e){return ls.warn("Failed to upload automation file",{error:e instanceof Error?e.message:String(e)}),null}})({authHeader:await d.getAuthHeader(),content:n,contentType:"text/plain",filename:r,filePath:e,orgId:p,sessionId:s}),i={path:e,filename:r,bucketPath:o};ot.push(i),_e({filesCreated:[...ot]})}catch(t){ls.warn("Failed to upload created file",{filePath:e,error:t instanceof Error?t.message:String(t)});const n={path:e,filename:r,bucketPath:null};ot.push(n),_e({filesCreated:[...ot]})}})();it.push(o)}}})]}]:[],sr=jt?[]:[...Mt?[{matcher:"Read",hooks:[Hs({action:"reading",pathKey:"file_path"})]},{matcher:"Write",hooks:[Hs({action:"writing",pathKey:"file_path"})]},{matcher:"Edit",hooks:[Hs({action:"editing",pathKey:"file_path"})]},{matcher:"Grep",hooks:[Hs({action:"searching",pathKey:"path"})]},{matcher:"Glob",hooks:[Hs({action:"searching",pathKey:"path"})]},{matcher:"Bash",hooks:[to({workspaceBoundary:f})]}]:[],...Wt?[{matcher:"Bash",hooks:[Wt.hook]}]:[],{hooks:[async e=>(e&&"object"==typeof e&&"tool_name"in e?e.tool_name:"").startsWith("mcp__plugin_playwright_playwright__browser_")?{decision:"block",reason:"Use stably-browser commands instead of the built-in Playwright MCP tools.",systemMessage:'Do NOT use mcp__plugin_playwright_playwright tools. Use stably-browser bash commands for all browser interaction:\n- `stably-browser open` / `stably-browser open <url>`\n- `stably-browser goto <url>`, `stably-browser click <ref>`, `stably-browser fill <ref> "text"`\n- `stably-browser snapshot`, `stably-browser screenshot`\n- `stably-browser run-test <file>`\n- `stably-browser close`'}:{decision:"approve"}]}],or=Object.keys(Lt).length>0?Lt:void 0,ir={...$t};ir.MCP_TOOL_TIMEOUT=String(6e5),Bt&&(ir.ANTHROPIC_API_KEY=Bt,ir.ANTHROPIC_BASE_URL=yn,ir.CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS="1",ir.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1");const ar=process.env.STABLY_AGENT_MODEL??"claude-opus-4-6";!function(e,t){"env"===t.type&&(e.STABLY_API_KEY=t.auth.apiKey,e.STABLY_PROJECT_ID=t.auth.projectId)}(ir,u);const cr=yt?`\n\n## Authoritative Fix Rules (STABLY-FIX.md / stably.yaml)\nThese repository-specific fix instructions take precedence over generic fix guidance when they conflict.\n${yt}`:"",lr=_t?`\n\n## Authoritative Test Generation Rules (STABLY-CREATE.md)\nThese repository-specific create instructions take precedence over generic create guidance when they conflict.\n${_t}`:"",ur=St?`\n\n## Authoritative Project Rules (STABLY.md)\nThese repository-specific project instructions take precedence over generic guidance when they conflict. If STABLY-CREATE.md is also present, use it for create-specific conflicts.\n${St}`:"",dr=ft?"\n\n## Cloud Browser Mode\nYou are running in cloud browser mode. Cloud browsers are remote VMs β there is no local resource cost.\n\n**Each subagent MUST use its own isolated browser session.** Do NOT reuse or share browser sessions between subagents. Session isolation is automatic β each subagent simply calls `stably-browser open` and gets its own browser.\n\nWhen running tests with `stably-browser run-test`, each subagent also gets its own browser automatically.":"",pr=dt.isEsmProject?'\n\n## ES Module Project\nThis project uses ES modules (`"type": "module"` in package.json). You MUST use `import`/`export` syntax β never use `require()` or `module.exports`. `require()` is not available in ES module scope and will throw `ReferenceError: require is not defined`.\n\nWhen writing ANY JavaScript or TypeScript code (test files, helper scripts, temporary scripts, config files):\n- Use `import ... from "..."` instead of `const ... = require("...")`\n- Use `export` / `export default` instead of `module.exports`\n- Use `import { readFileSync } from "node:fs"` instead of `require("fs")`\n- Use `import { fileURLToPath } from "node:url"` and `import { dirname } from "node:path"` instead of `__dirname`/`__filename`':"",fr=Rt+cr+lr+ur+dr+pr;ls.debug("[fix] Final system prompt assembled",{baseSize:Rt.length,fixRulesSize:cr.length,createRulesSize:lr.length,stablyMdSize:ur.length,cloudBrowserSize:dr.length,esmSectionSize:pr.length,isEsmProject:dt.isEsmProject,finalSize:fr.length});const hr=function(){const e=function(){const e=function(){const e=process.env.STABLY_PLUGIN_PATH?.trim();if(!e)return;const t=n.isAbsolute(e)?e:n.resolve(process.cwd(),e);return kc(t)?t:void 0}();if(e)return e;const t=n.join(Sc,"stably-plugin-cli");if(kc(t))return t;for(const e of function*(e){let t=n.resolve(e);for(;;){yield t;const e=n.dirname(t);if(e===t)return;t=e}}(Sc))for(const t of Ac){const r=n.join(e,t);if(kc(r))return r}}();if(e)return{type:"local",path:e}}(),gr=()=>(ls.info("[fix] Starting SDK query",{model:ar,tools:Xt,mcpServers:Object.keys(tr),resumeSessionId:B??null,subagentsEnabled:!!or,subagentCount:Object.keys(Lt).length,useStablyAiProxy:Dt,aiProxyUrl:yn,anthropicBaseUrl:void 0,stablyPluginPath:hr?.path,stablyPluginExists:!!hr}),V({options:{executableArgs:["--max-old-space-size=4096"],tools:Xt,allowedTools:Qt,...null!=It?{maxBudgetUsd:It}:{},betas:[],canUseTool:(e,t)=>(ls.debug("[fix] canUseTool called",{toolName:e}),Promise.resolve({behavior:"allow",updatedInput:t})),cwd:f,env:ir,hooks:{PostToolUse:nr,PreToolUse:sr},includePartialMessages:!0,agents:or,mcpServers:tr,model:ar,permissionMode:"default",plugins:hr?[hr]:void 0,systemPrompt:fr,...B?{resume:B}:{}},prompt:U??ut})),mr=async e=>{if(I&&F&&!J&&!M)M=(async()=>{ls.info("[fix] Interrupting for user message",{messageCount:e.length,phase:ue?.phase});try{await(O?.interrupt?.())}catch(e){ls.warn("[fix] Failed to interrupt response for user message",{error:e instanceof Error?e.message:String(e)})}await oo(),U?.finish(),U=new io,Z.clear(),O=gr();const t=e.map(e=>`[Message from web UI user]: ${e}`).join("\n\n");U.pushText(`[SYSTEM] The user sent a message while you were working. Read their message below, incorporate their feedback, and continue your task. Do not restart from scratch unless the user explicitly asks.\n\n${t}`),X=!0,F=!0})().finally(()=>{M=void 0}),await M;else for(const t of e)U?.pushText(`[Message from web UI user]: ${t}`)};if(Bt){k&&qe({label:"Checking AI connectivity..."});const e=yn,t=`${e.replace(/\/$/,"")}/v1/messages`;ls.debug(`[fix] Pre-flight: POST ${t}`);const r=Date.now();let n;try{const e=await fetch(t,{method:"POST",signal:AbortSignal.timeout(1e4),headers:{"x-api-key":Bt,"anthropic-version":"2023-06-01","content-type":"application/json"},body:"{}"}),s=await e.text().catch(()=>""),o=Date.now()-r;ls.debug(`[fix] Pre-flight: ${e.status} in ${o}ms β ${s.slice(0,300)}`),401===e.status||403===e.status?(ls.error(`[fix] Pre-flight: AI proxy key rejected (${e.status}) at ${t}`),n="Unable to start verification: AI proxy credentials were rejected. Please run `stably login` and try again."):ls.info("[fix] Pre-flight: AI proxy key valid",{status:e.status,durationMs:o})}catch(t){ls.error("[fix] Pre-flight: AI proxy unreachable",{error:t instanceof Error?t.message:String(t),durationMs:Date.now()-r,url:e}),n="Unable to start verification: cannot reach the AI proxy. Please check your network/VPN and try again."}finally{k&&"running"===Qe&&qe({label:void 0})}n&&(je({text:`[stably] ${n}\n`}),Ze({error:n,status:"error"}),await Ge(),ls.flush(),ls.printLogFileInfo(),process.exit(1))}ls.info("[fix] Creating initial agent query"),k&&(qe({label:"Initializing verification session..."}),je({text:"Initializing verification session...\n"})),ls.flush(),O=gr(),ls.info("[fix] Agent query created, entering message loop"),"chat"!==e.mode&&(U.pushText(ut),ee.push({role:"user",content:ut,timestamp:(new Date).toISOString()}));const yr=async t=>{Ce||(Ce=(async()=>{ls.info("[session] Interrupt requested",{source:t,mode:e.mode}),oe="CANCELED",await be("CANCELED"),ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await(le?.closeAndWait()),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0}),await(Ie?.closeAndWait()),j&&(clearTimeout(j),j=void 0),ze(),await oo(),await(Wt?.cleanup());try{await(O?.interrupt?.())}catch{}if(U?.finish(),ee.length>0&&Se)try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[exit] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}Ge(),ls.flush()})()),await Ce};ke.current=async()=>{await yr("ctrl-c")};let br=()=>{};br=function({enabled:e,onSignal:t}){const r=()=>{t("SIGINT")},n=()=>{t("SIGTERM")};return process.prependOnceListener("SIGINT",r),process.prependOnceListener("SIGTERM",n),()=>{process.removeListener("SIGINT",r),process.removeListener("SIGTERM",n)}}({enabled:!0,onSignal:e=>{(async()=>{await yr("signal"),process.exit(function(e){return"SIGINT"===e?130:143}(e))})()}});let wr=null,vr=null,Ir="";Re.current=async()=>{if(!Le&&F&&U){Le=!0;try{ls.info("[chat] User pressed Escape to cancel generation"),We(),Ve(),H=!0,$e=!0;try{await(O?.interrupt?.())}catch(e){ls.warn("[chat] Failed to interrupt response on Escape",{error:e instanceof Error?e.message:String(e)})}await oo();const e=U.drainQueue();U.finish(),U=new io;for(const t of e)U.pushText(t);q=e.length,O=gr();for(const e of Z.keys())Je({toolUseId:e,status:"error"});Be()}finally{Le=!1}}};let Tr=0,_r=null,Er=!1;const Sr=T?void 0:k?9e4:18e4;let xr=!1;const Ar=null!=Sr?setTimeout(()=>{_r||"running"!==Qe||(t=>{if(!xr){if(xr=!0,clearTimeout(Ar),clearInterval(kr),setTimeout(()=>process.exit(1),6e4).unref(),ls.error("[session] Session timeout",{reason:t,mode:e.mode,elapsed:Date.now()-ce}),oe="FAILED",k||T){const e="This is taking longer than expected. Please try again.";je({text:`[stably] ${e}\n`}),Ze({error:e,status:"error"})}else ye({phase:"complete",endedAt:Date.now(),isError:!0,errorReason:"execution_error",errorMessage:`Session timed out: ${t}`,workers:me(!0)});_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:`Timed out: ${t}`});try{O?.interrupt?.()}catch{}U?.finish()}})("no response from AI service")},Sr):void 0;Ar?.unref();const kr=setInterval(()=>{const e=Date.now()-ce;_r?ls.info("[fix] Watchdog: message loop active",{messageCount:Tr,elapsed:e}):(ls.info("[fix] Watchdog: waiting for first SDK message",{elapsed:e}),k&&!Er&&e>=15e3&&(je({text:"Still preparing verification. This can take a bit...\n"}),Er=!0)),ls.flush()},15e3);kr.unref();try{let t=!1,r=!1;for(;;){if(!O){ls.info("[fix] No response object, exiting message loop");break}t=!1,r=!1,ls.info("[fix] Entering for-await on SDK response");try{for await(const t of O){if(xr)break;Tr++,_r||(_r=Date.now(),clearTimeout(Ar),k&&qe({label:void 0}),ls.info("[fix] First SDK message received",{waitDurationMs:_r-ce,messageType:t.type,messageSubtype:"subtype"in t?t.subtype:void 0}));const n="session_id"in t&&"string"==typeof t.session_id?t.session_id:void 0;if(n&&n!==B&&(B=n,ls.debug("Captured Claude session id",{sessionId:B})),"stream_event"===t.type){const{event:e}=t;(Tr<=5||Tr%200==0)&&ls.debug("[fix] Stream event",{msgNum:Tr,eventType:e?.type});const r=e&&"object"==typeof e&&"parent_tool_use_id"in e&&"string"==typeof e.parent_tool_use_id?e.parent_tool_use_id:void 0;if("content_block_start"===e?.type){const t=e.content_block;"thinking"===t?.type&&(wr=e.index??null)}if("content_block_delta"===e?.type){const{delta:t}=e;if("text_delta"===t?.type&&t.text){Ir&&(te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),Ir="");const e=r&&Z.has(r)?r:1===Z.size?Array.from(Z.keys())[0]:void 0;e?De({toolUseId:e,kind:"text",content:t.text}):k||je({text:t.text})}const n=t;if("thinking_delta"===n?.type&&n.thinking){if(r&&Z.has(r))continue;if(Ir+=n.thinking,!k){const e=null!==wr&&wr!==vr;Me({text:n.thinking,forceNewBlock:e}),e&&(vr=wr)}continue}}if("content_block_stop"===e?.type){const t=e.index;null!==wr&&wr===t&&(Ve(),Ir&&(te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),Ir=""),wr=null,Ye())}"message_stop"===e?.type&&U&&(J=!1,U.allowNextTurn());continue}if("assistant"===t.type){const r="parent_tool_use_id"in t&&"string"==typeof t.parent_tool_use_id?t.parent_tool_use_id:void 0,{content:n}=t.message??{};if(Array.isArray(n)&&!r){const t=n.filter(e=>e&&"object"==typeof e&&"type"in e&&"text"===e.type).map(e=>e&&"object"==typeof e&&"text"in e&&"string"==typeof e.text?e.text:void 0).filter(Boolean).join("\n");t&&(rt=t,k&&(nt=nt?`${nt}\n\n${t}`:t),ls.debug("Assistant message",{text:k?tl(t):t}),"fix"===e.mode&&(he(pl,{type:"ai_message",summary:t.slice(0,200)}),ge({type:"ai_message",summary:t.slice(0,200)})),C&&Ee({type:"ai_message",summary:t.slice(0,200)}),te({role:"assistant",content:t,timestamp:(new Date).toISOString()}))}if(Z.size>0){const e=Array.isArray(n)?n.filter(e=>e&&"object"==typeof e&&"type"in e&&"tool_use"===e.type).map(e=>e&&"object"==typeof e&&"name"in e&&"string"==typeof e.name?e.name:void 0):[];ls.debug("Assistant message with active subagents",{hasParentToolUseId:!!r,parentToolUseId:r,activeSubagentIds:Array.from(Z.keys()),toolNames:e,fullMessageKeys:Object.keys(t),rawMessage:JSON.stringify(t).slice(0,500)})}if(Array.isArray(n))for(const t of n){if("tool_use"===t?.type){if("mcp__auto-heal-report__generate-report"===t.name&&(J=!0),t.name.startsWith("mcp__session-control__")||t.name.startsWith("mcp__stably-agent-control__"))continue;if(yl(t.name))continue;if(k&&ml.test(t.name))continue;if(Z.size>0&&ls.debug("Tool use detected with active subagents",{toolName:t.name,hasParentToolUseId:!!r,parentToolUseId:r,wouldRouteToSubagent:!!r&&Z.has(r),activeSubagentIds:Array.from(Z.keys())}),"Task"===t.name){const r=t.input,n=r&&"object"==typeof r?r:void 0,s=n&&"subagent_type"in n&&"string"==typeof n.subagent_type?n.subagent_type:"subagent",o=n&&"description"in n&&"string"==typeof n.description?n.description.trim():"";if(ls.info("[fix] Subagent started",{subagentType:s,description:o,toolUseId:t.id,activeSubagentCount:Z.size+1}),Z.set(t.id,{subagentType:s,description:o}),Ne({toolUseId:t.id,subagentType:s,description:o}),"fix"===e.mode){if("triage"===s){Xe?.({phase:"triage"});const e={id:t.id,testDescription:"Triage",workerType:"triage",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};ye({phase:"triage",workers:[...ue?.workers??[],e]})}else if("code-worker"===s){de.add(o||t.id);const e={id:t.id,testDescription:o||t.id,workerType:"code-worker",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};Xe?.({phase:"fixing",totalTests:de.size,currentTestDescription:o||null}),ye({phase:"fixing",totalTests:de.size,currentTestDescription:o||null,lastTestDescription:o||ue?.lastTestDescription||null,workers:[...ue?.workers??[],e]})}else if("browser-worker"===s){de.add(o||t.id);const e={id:t.id,testDescription:o||t.id,workerType:"browser-worker",status:"running",summary:null,startedAt:Date.now(),endedAt:null,activity:[]};Xe?.({phase:"debugging",totalTests:de.size,currentTestDescription:o||null}),ye({phase:"debugging",totalTests:de.size,currentTestDescription:o||null,lastTestDescription:o||ue?.lastTestDescription||null,workers:[...ue?.workers??[],e]})}else"validation"===s?(Xe?.({phase:"validation",currentTestDescription:null}),ye({phase:"validation",currentTestDescription:null})):"context"===s&&ye({currentTestDescription:o||null});ge({type:"tool_call",summary:`[${s}] ${o}`.trim()})}if(S)if("create-planner"===s)_e({phase:"planning",currentActivity:"Analyzing test plan..."}),Ee({type:"tool_call",summary:`[create-planner] ${o}`.trim()});else if("create-worker"===s){const e=o.match(/(?:route|page)[:\s]+([^\s,]+)/i),r=(e?.[1]??o.slice(0,50))||t.id,n=o.match(/(\d+)\s*test/i),s=n?parseInt(n[1],10):1,i={pageGroupId:t.id,route:r,status:"exploring",testsCreated:0,testsTotal:s};pe.set(t.id,i),_e({phase:"generating",currentActivity:`Worker exploring ${r}...`,workers:Array.from(pe.values())}),Ee({type:"tool_call",summary:`[create-worker] ${o}`.trim()})}continue}if(r&&Z.has(r)){const n=Lo(t.name,t.input),s=n??$o(t.name),o=n?void 0:Uo(t.name,t.input),i=o?`${s} (${o})`:s;if(ls.debug("Subagent tool called",{tool:t.name,parentToolUseId:r}),De({toolUseId:r,kind:"tool",content:i}),"fix"===e.mode){ge({type:"tool_call",summary:i});const e=Z.get(r);"code-worker"!==e?.subagentType&&"browser-worker"!==e?.subagentType&&"triage"!==e?.subagentType||he(r,{type:"tool_call",summary:i})}if(S){const e=Z.get(r);if(("create-planner"===e?.subagentType||"create-worker"===e?.subagentType)&&(Ee({type:"tool_call",summary:i}),"create-worker"===e.subagentType&&pe.has(r))){const e="Bash"===t.name&&t.input&&"object"==typeof t.input?t.input.command:void 0;t.name.includes("run-test")||t.name.includes("run_test")||"string"==typeof e&&e.includes("run-test")?fe(r,{status:"validating"}):"Write"!==t.name&&"Edit"!==t.name||fe(r,{status:"writing"})}}continue}if(r&&ls.debug("Tool with parent_tool_use_id but no matching subagent",{tool:t.name,parentToolUseId:r,activeSubagentIds:Array.from(Z.keys())}),ls.debug("Tool called",{tool:t.name,input:t.input}),Oe({rawName:t.name,toolInput:t.input}),t.id&&se.set(t.id,t.name),te({role:"tool",content:"",timestamp:(new Date).toISOString(),toolName:t.name,toolInput:t.input}),"fix"===e.mode){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=n?`${r} (${n})`:r;he(pl,{type:"tool_call",summary:s}),ge({type:"tool_call",summary:s})}if(S){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=n?`${r} (${n})`:r;"initializing"===Te?.phase?_e({phase:"generating",currentActivity:s}):"mcp__playwright-test__test_run"===t.name&&"generating"===Te?.phase?_e({phase:"testing",currentActivity:s}):_e({currentActivity:s}),Ee({type:"tool_call",summary:s})}if(k){const e=Lo(t.name,t.input),r=e??$o(t.name),n=e?void 0:Uo(t.name,t.input),s=tl(n?`${r} (${n})`:r);_e("initializing"===Te?.phase?{phase:"verifying",currentActivity:s}:{currentActivity:s}),Ee({type:"tool_call",summary:s})}}if("text"===t?.type){const n="string"==typeof t.text?t.text:"",s=r&&Z.has(r)?r:1===Z.size?Array.from(Z.keys())[0]:void 0;if(s&&n){if(De({toolUseId:s,kind:"text",content:n}),"fix"===e.mode){const e=Z.get(s);"code-worker"!==e?.subagentType&&"browser-worker"!==e?.subagentType&&"triage"!==e?.subagentType||he(s,{type:"ai_message",summary:n.slice(0,200)})}if(S){const e=Z.get(s);"create-planner"!==e?.subagentType&&"create-worker"!==e?.subagentType||Ee({type:"ai_message",summary:n.slice(0,200)})}}}}continue}if("user"===t.type){const r="message"in t&&t.message&&"object"==typeof t.message&&"content"in t.message?t.message.content:void 0,n="tool_use_result"in t&&t.tool_use_result&&"object"==typeof t.tool_use_result?t.tool_use_result:void 0;if(Array.isArray(r))for(const t of r)if(t&&"object"==typeof t&&"type"in t&&"tool_result"===t.type&&"tool_use_id"in t){const r="string"==typeof t.tool_use_id?t.tool_use_id:void 0,s="is_error"in t&&!0===t.is_error||"error"===n?.status;let o;const i=n?.content??("content"in t?t.content:void 0);"string"==typeof i?o=i:Array.isArray(i)&&(o=i.filter(e=>e&&"object"==typeof e&&"text"===e.type).map(e=>e.text||"").join("")),ls.debug("Tool result",{toolUseId:r,isError:s,output:o?.slice(0,500)});const a=5e4,c=r?se.get(r):void 0;if(te({role:"tool_result",content:"",timestamp:(new Date).toISOString(),toolName:c,toolOutput:o?.slice(0,a),isError:s}),r&&Z.has(r)){const t=Z.get(r);if(ls.info("[fix] Subagent completed",{toolUseId:r,isError:s,subagentType:t?.subagentType,description:t?.description,activeSubagentCount:Z.size-1}),o&&De({toolUseId:r,kind:"text",content:o}),Je({toolUseId:r,status:s?"error":"complete"}),"fix"===e.mode&&"triage"===t?.subagentType){const e=s?"failed":"succeeded",t=o?o.slice(0,500):null,n=(ue?.workers??[]).map(n=>n.id===r?{...n,status:e,summary:t,endedAt:Date.now()}:n);ye({workers:n})}if("fix"===e.mode&&("code-worker"===t?.subagentType||"browser-worker"===t?.subagentType)){const e=s?"failed":"succeeded",t=o?o.slice(0,500):null,n=(ue?.workers??[]).map(n=>n.id===r?{...n,status:e,summary:t,endedAt:Date.now()}:n);s?(Xe?.({failedTests:(ue?.failedTests??0)+1,currentTestDescription:null}),ye({failedTests:(ue?.failedTests??0)+1,currentTestDescription:null,workers:n})):(Xe?.({fixedTests:(ue?.fixedTests??0)+1,currentTestDescription:null}),ye({fixedTests:(ue?.fixedTests??0)+1,currentTestDescription:null,workers:n}))}if(S&&t)if("create-planner"===t.subagentType)Ee({type:"ai_message",summary:s?"Planner failed":"Test plan analyzed, launching workers..."}),s||_e({phase:"generating",currentActivity:"Launching workers..."});else if("create-worker"===t.subagentType){if(pe.has(r)){const e=o?.match(/\*\*Created:\*\*\s*(\d+)/i),t=e?parseInt(e[1],10):0;fe(r,{status:s?"failed":"complete",testsCreated:t})}Ee({type:"ai_message",summary:s?`Worker failed: ${t.description?.slice(0,100)}`:`Worker complete: ${t.description?.slice(0,100)}`})}Z.delete(r)}}continue}if("result"!==t.type);else{if(r=!0,ls.info("[fix] Agent result received",{subtype:t.subtype,messageCount:Tr,elapsed:Date.now()-ce,activeSubagents:Z.size,fixedTests:ue?.fixedTests,failedTests:ue?.failedTests,phase:ue?.phase}),I){if("success"===t.subtype){j&&(clearTimeout(j),j=void 0);for(const e of K)U?.pushText(`[Message from web UI user]: ${e}`);if(K=[],(C||"fix"===e.mode)&&U){if(U.hasQueuedMessages()){ls.info("[ws] Queued web UI messages found, continuing agent"),F=!0,U.allowNextTurn();continue}if(await bl(U,3e3)){ls.info("[ws] Web UI message received during grace period, continuing agent"),F=!0,U.allowNextTurn();continue}U.finish()}Xe?.({phase:"complete",currentTestDescription:null,endedAt:Date.now()}),ye({phase:"complete",currentTestDescription:null,endedAt:Date.now(),isError:!1,workers:me(!1)}),await Promise.allSettled(it);const t=sl({mode:e.mode,lastAssistantText:rt});if("verify"===e.mode){(Array.isArray(e.prompt)?e.prompt.join(" "):e.prompt).trim();const r=nt||rt,n=/```verdict\s*\r?\n/.test(r),s=nl(r)??{verdict:"INCONCLUSIVE",steps:["Agent finished without a parseable verdict block."],reason:n?"Failed to parse verdict.":"The agent completed without reporting a verdict.",evidence:[]},o=rl(s);"PASS"===s.verdict?Dr("success","VERIFICATION PASSED"):"FAIL"===s.verdict?Dr("error","VERIFICATION FAILED"):Dr("warning","VERIFICATION INCONCLUSIVE"),o.steps.length>0&&o.steps.forEach((e,t)=>{}),o.reason&&(s.verdict,o.reason),o.evidence.length>0&&o.evidence.forEach(e=>{}),_e({phase:"complete",endedAt:Date.now(),isError:"PASS"!==s.verdict,currentActivity:null,resultSummary:t}),process.exitCode="PASS"===s.verdict?0:"FAIL"===s.verdict?1:2,Ze({status:"success"})}else{if(_e({phase:"complete",endedAt:Date.now(),isError:!1,currentActivity:null,resultSummary:t}),rr&&st.length>0){process.stdout.write(Dr("success","Created files:")+"\n");for(const e of st)process.stdout.write(Dr("success",`- ${e}`)+"\n")}if(et){const e=process.stdout.isTTY?(e,t)=>`]8;;${e}${t}]8;;`:(e,t)=>t;process.stdout.write(Dr("info",`π View Autoheal Report:\n ${e(et,ne.bold(ne.underline(Dr("link",et))))}`)+"\n")}Ze({status:"success"}),oe="COMPLETED"}}else if(M||X)ls.info("[fix] Suppressing error status: user-message interrupt in progress");else if(H)oe="CANCELED",ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0});else if(k){let e="Execution error before verification completed.";"error_max_budget_usd"===t.subtype?e="Budget limit exceeded before verification completed.":"error_max_turns"===t.subtype&&(e="Maximum turns exceeded before verification completed."),Dr("warning","VERIFICATION INCONCLUSIVE"),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),Ze({status:"success"}),process.exitCode=2}else{let e,r="unknown",n="Run failed.";"error_max_budget_usd"===t.subtype?(r="budget_exceeded",e="total_cost_usd"in t?t.total_cost_usd:void 0,n=`Budget limit exceeded (${void 0!==e?`$${e.toFixed(2)}`:"unknown"} spent). The fix session was stopped to prevent runaway costs.`,ls.warn("[fix] Budget limit exceeded",{subtype:t.subtype,totalCostUsd:e})):"error_max_turns"===t.subtype?(r="max_turns",n="Maximum turns exceeded. The fix session was stopped."):"error_during_execution"===t.subtype&&(r="execution_error"),Xe?.({endedAt:Date.now(),isError:!0}),ye({phase:"complete",endedAt:Date.now(),isError:!0,errorReason:r,errorMessage:n,totalCostUsd:e,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),Ze({error:n,status:"error"}),process.exitCode=1,oe="FAILED"}H=!1;break}if("success"!==t.subtype){if(!H){let e="Run failed.";"error_max_budget_usd"===t.subtype?(e=`Budget limit exceeded (${"total_cost_usd"in t?`$${t.total_cost_usd.toFixed(2)}`:"unknown"} spent). The fix session was stopped to prevent runaway costs.`,ls.warn("[fix] Budget limit exceeded",{subtype:t.subtype,totalCostUsd:"total_cost_usd"in t?t.total_cost_usd:void 0})):"error_max_turns"===t.subtype&&(e="Maximum turns exceeded. The fix session was stopped."),Ze({error:e,status:"error"}),process.exitCode=1}}else Ze({status:"success"});F=!1,H=!1,qe({label:void 0}),U?.allowNextTurn(),_&&q>0&&(q-=1,F=!0,Ze({status:"running"}))}}}catch(e){if($e){$e=!1,H=!1,Z.clear(),He(),Ir&&te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),wr=null,vr=null,Ir="",Ye(),q>0?(F=!0,Ze({status:"running"})):(F=!1,Ze({status:"success"})),t=al(q);continue}const n=e instanceof Error&&"Claude Code process exited with code 1"===e.message;if(n&&r){ls.info("[fix] Claude Code process exited with code 1 (normal exit after result)",{inFlight:F,interrupted:H});break}if(n&&(X||M||H)){ls.info("[fix] Claude Code process exited with code 1 (interrupted)",{inFlight:F,interrupted:H,userMessageInterruptTriggered:!!X,interruptInProgress:!!M});break}throw e}if($e)$e=!1,H=!1,Z.clear(),He(),Ir&&te({role:"thinking",content:Ir,timestamp:(new Date).toISOString()}),wr=null,vr=null,Ir="",Ye(),q>0?(F=!0,Ze({status:"running"})):(F=!1,Ze({status:"success"})),t=al(q);else if(M&&await M,X&&(X=!1,t=!0,Ze({status:"running"}),ls.info("[fix] Resuming after user-message interrupt")),!t)break}}catch(e){H?(oe="CANCELED",ye({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!1,isInterrupted:!0})):(ls.error("[fix] Agent encountered an error",{error:e instanceof Error?e.message:String(e),stack:e instanceof Error?e.stack:void 0,elapsed:Date.now()-ce}),Ze({error:`Agent encountered an error: ${e}`,status:"error"}),process.exitCode=1,oe="FAILED",ye({phase:"complete",endedAt:Date.now(),isError:!0,currentTestDescription:null,workers:me(!0)}),await Promise.allSettled(it),_e({phase:"complete",endedAt:Date.now(),isError:!0,currentActivity:null}),ls.flush(),ls.printLogFileInfo())}finally{if(Ar&&clearTimeout(Ar),clearInterval(kr),j&&(clearTimeout(j),j=void 0),ls.info("[fix] Agent session ending",{finalStatus:oe,elapsed:Date.now()-ce,totalMessages:Tr}),Yt(),F=!1,H=!1,br(),process.off("uncaughtException",l),U?.finish(),oe){ls.info("[fix] Reporting final autoheal status",{status:oe});const e=Date.now();await be(oe),ls.info("[fix] Final autoheal status reported",{durationMs:Date.now()-e})}if(ls.info("[fix] Closing WebSocket progress reporter"),await(le?.closeAndWait()),await Promise.allSettled(it),await(Ie?.closeAndWait()),!Mt&&ee.length>0&&Se){ls.info("[session] Uploading session history",{messageCount:ee.length});try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[session] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}}if(Mt&&Vt){const t=Date.now();try{ls.info("[fix] Computing diff...");const r=await Vt.computeDiff();if(r&&r.trim().length>0){ls.info("[fix] Uploading diff...",{diffLength:r.length});const n=await d.getAuthHeader(),{diffBucketPath:s,uploadUrl:o}=await Ps({authHeader:n,contentType:"text/plain",orgId:p,runId:e.runId});await xs({body:r,contentType:"text/plain",uploadUrl:o,errorContext:"diff"}),await Cs({authHeader:n,diffBucketPath:s,orgId:p,runId:e.runId}),ls.info("[fix] Diff uploaded",{durationMs:Date.now()-t})}else ls.info("[fix] No diff to upload (empty or no changes)")}catch(e){ls.warn("[fix] Failed to upload diff",{error:e instanceof Error?e.message:String(e),durationMs:Date.now()-t})}}if(ls.info("[fix] Cleaning up diff tracker"),await(Vt?.cleanup()),Mt&&ee.length>0&&Se){ls.info("[fix] Uploading session history",{messageCount:ee.length});try{await Os({authHeader:await d.getAuthHeader(),orgId:p,sessionId:Se,projectId:bs(u),history:ee})}catch(e){ls.warn("[fix] Failed to upload session history",{error:e instanceof Error?e.message:String(e)})}}const t=n.join(f,".stably","traces");await Y(t,{recursive:!0,force:!0}).catch(()=>{}),ls.info("[fix] Running final cleanup"),await(Wt?.cleanup()),await Ge(),ls.info("[fix] Cleanup complete"),xr&&(ls.flush(),ls.printLogFileInfo(),process.exit(1))}},Tl=fe.object({runId:fe.string(),timestamp:fe.number()}),_l=async()=>{try{const e=await kn(process.cwd(),".stably/last-run.json");if(!e)return;const t=await z(e,"utf-8");return{...Tl.parse(JSON.parse(t)),filePath:e}}catch{return}};function El(e=process.cwd()){let t=s(e);for(;;){const e=Sl(t);if(e){const r={...e.dependencies,...e.devDependencies},n="@playwright/test"in r?"@playwright/test":"playwright"in r?"playwright":void 0;if(n){const e=xl(t);let r=!1,s=t;for(;;){const e=i(s,"node_modules"),t=i(e,n);if(E(t)){r=!0;break}const a=o(s);if(a===s)break;s=a}return{inNodeModules:r,installed:!0,packageManager:e,packageName:n}}}const r=o(t);if(r===t)return{inNodeModules:!1,installed:!1,packageManager:void 0};t=r}}function Sl(e){const t=i(e,"package.json");let r;try{r=x(t,"utf-8")}catch{return}try{return JSON.parse(r)}catch{return}}function xl(e){const t=[["npm","package-lock.json"],["pnpm","pnpm-lock.yaml"],["yarn","yarn.lock"]];let r=e;for(;;){for(const[e,n]of t)if(E(i(r,n)))return e;const e=o(r);if(e===r)return;r=e}}function Al(e){if("npm"===e||"pnpm"===e)return["npx","playwright"];if("yarn"===e)return["yarn","playwright"];throw new Error("Package manager not supported")}var kl=[{args:["--trace=on"],description:"Run Playwright tests",name:"test"},{args:[],description:"Install browser dependencies",name:"install"}],Pl=["You have two different versions of @playwright/test"];function Cl(e){const[t,...r]=Al(e),n=[t,...r.slice(0,-1)].join(" ");return(t,r)=>{let s=t.toString();for(const e of kl)s=s.replaceAll(`${n} playwright ${e.name}`,`${n} stably ${e.name}`).replaceAll(`npx playwright ${e.name}`,`npx stably ${e.name}`);if("yarn"===e){const e=s.split("\n");return e.length>0&&(e[0].includes("/.bin/playwright")||e[0].includes("\\.bin\\playwright"))&&e.shift(),void r.write(e.join("\n"))}r.write(s)}}async function Rl({overrideArgs:e,subcommand:t}){ls.info("[test] forwardToPlaywright starting",{subcommand:t,overrideArgs:e});const r=process.argv,n=r.findIndex((e,r)=>r>1&&e===t),a=-1===n?[]:r.slice(n+1),c="--"===a[0],u=c?a.slice(1):a;if(!c&&("--help"===u[0]||"-h"===u[0]))return async function({subcommand:e}){const t=kl.find(t=>t.name===e),r=e=>process.stdout.write(`${e}\n`);r(`stably ${e} - ${t?.description??""}`),r(""),"test"===e&&(r('IMPORTANT: Always use "stably" commands instead of "playwright" directly.'),r(""),r("Stably commands:"),r(" stably test [file] Run tests (auto-enables tracing and analytics)"),r(" stably fix [runId] Auto-fix failing tests using AI"),r(" stably create [prompt] Generate new tests from a prompt or branch diff"),r(""),r("Stably options:"),r(" --env <name> Load environment variables from a remote Stably environment"),r(" --env-file <path> Load environment variables from a local .env file (repeatable)"),r(""),r("Why use Stably?"),r(' - "stably fix" automatically repairs broken tests'),r(' - "stably test" enables --trace=on and test analytics'),r(' - "stably create" generates tests from prompt'),r(""));const n=El();if(!n.installed||!n.inNodeModules)return void r('No Playwright project found in this directory or its parents.\nMake sure you\'re in a directory within your Playwright project, or run "stably init" to create a new playwright directory.');const{packageManager:s}=n;if(!s)return void r("Could not determine package manager.");r("Playwright options:"),r("");const[o,...i]=Al(s),a=Cl(s);return new Promise(t=>{const r=g(o,[...i,e,"--help"],{stdio:["inherit","pipe","pipe"],shell:"win32"===process.platform,env:{...process.env,...process.env.CI?{}:{FORCE_COLOR:"1"}}});r.stdout?.on("data",e=>{a(e,process.stdout)}),r.stderr?.on("data",e=>{a(e,process.stderr)}),r.on("close",()=>{t()})})}({subcommand:t});const d=e??[],p=new Set(d.map(e=>{const[t]=e.split("=");return t})),f=[];for(let e=0;e<u.length;e++){const t=u[e],[r]=t.split("=");p.has(r)?!t.includes("=")&&e+1<u.length&&!u[e+1].startsWith("-")&&e++:f.push(t)}const m=[t,...d,...f];ls.info("[test] Forwarded args computed",{forwardedArgs:m}),ls.info("[test] Resolving Stably test environment");const y=Date.now(),b="test"===t?await(async()=>{ls.info("[test] Resolving Stably test env");const e=(()=>{if(process.env.STABLY_WS_URL)return;if("https://api.stably.ai"===fn)return;const e=fn.startsWith("http://")?"ws://":"wss://";return`${fn.replace(/^https?:\/\//,e).replace(/\/$/,"")}/reporter`})();ls.debug("[test] WebSocket URL resolved",{wsUrl:e??"(default)"});const t=gs();if(t)return ls.info("[test] Using env var auth (STABLY_API_KEY + STABLY_PROJECT_ID)"),{STABLY_API_KEY:t.apiKey,STABLY_PROJECT_ID:t.projectId,...e&&{STABLY_WS_URL:e}};ls.info("[test] No env var auth, attempting OAuth auth");const r=Date.now(),n=await(async()=>{const e=gs();if(e)return{auth:e,type:"env"};const t=await ms(),r=t?await Bn():void 0;return t&&r?{auth:{accessToken:t.accessToken,context:r},type:"oauth"}:void 0})();if(ls.info("[test] OAuth auth resolved",{durationMs:Date.now()-r,hasAuth:!!n,authType:n?.type}),!n||"env"===n.type)return void ls.info("[test] No usable auth found");const s=process.env.STABLY_PROJECT_ID?.trim(),o=s||bs(n);if(!o)return void ls.warn("[test] No project ID available");ls.info("[test] Fetching JWT API key",{projectId:o});const i=Date.now(),a=await(async(e,t)=>{try{ls.debug("Requesting JWT API key",{projectId:t,apiUrl:fn});const r=await(async({accessToken:e,projectId:t})=>{const r=await(n={auth:e,client:In(),path:{projectId:t}},(n.client??ln).post({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/api-key",...n}));var n;if(r.error){const e=r.error?.error,{status:t}=r.response;throw new Error(e??`Failed to get API key: ${t}`)}return r.data})({accessToken:e,projectId:t});return ls.debug("JWT API key obtained",{keyPrefix:r.apiKey.substring(0,10)}),r.apiKey}catch(e){return void ls.warn("Failed to get JWT API key for test reporter",{error:e instanceof Error?e.message:String(e)})}})(n.auth.accessToken,o);ls.info("[test] JWT API key fetch complete",{durationMs:Date.now()-i,success:!!a});const c=a?{STABLY_API_KEY:a,STABLY_PROJECT_ID:o,...e&&{STABLY_WS_URL:e}}:void 0;return ls.info("[test] Stably test env resolved",{hasApiKey:!!c?.STABLY_API_KEY,projectId:c?.STABLY_PROJECT_ID,wsUrl:c?.STABLY_WS_URL??process.env.STABLY_WS_URL??"(default)"}),c})():void 0;ls.info("[test] Stably test environment resolved",{durationMs:Date.now()-y,hasCredentials:null!=b,hasWsUrl:!!b?.STABLY_WS_URL}),ls.info("[test] Loading remote environment variables");const w=await Ts();ls.info("[test] Remote environment loaded",{hasRemoteEnv:!!w,variableCount:w?Object.keys(w.variables).length:0});const v={};if(w){const e=[];for(const[t,r]of Object.entries(w.variables))void 0===process.env[t]?v[t]=r:process.env[t]!==r&&e.push(t);e.length>0&&ls.warn(`[test] π‘ Local environment variables overriding remote: ${e.join(", ")}`),w.sensitiveValues.length&&void 0===process.env.STABLY_SENSITIVE_VALUES&&(v.STABLY_SENSITIVE_VALUES=Buffer.from(JSON.stringify(w.sensitiveValues)).toString("base64"))}ls.info("[test] Setting up Stably reporter injection");const S="test"===t?function({forwardedArgs:e,hasCredentials:t}){if(!t){console.warn("[33mβ οΈ Stably credentials not found. Test results will not be reported to Stably.[0m");const e=ds();if("local"!==e){const t=fs(e);console.warn(`[33m To enable reporting, add the following to your ${t}:[0m`),console.warn("[33m β’ STABLY_API_KEY β https://app.stably.ai/settings?tab=api-key[0m"),console.warn("[33m β’ STABLY_PROJECT_ID β https://app.stably.ai/settings?tab=project-id[0m\n")}else console.warn("[33m To enable reporting, either:[0m"),console.warn("[33m β’ Run `npx stably login` to authenticate[0m"),console.warn("[33m β’ Or set STABLY_API_KEY and STABLY_PROJECT_ID environment variables[0m\n");return}const r=process.cwd(),n=e=>{const t=function(e){let t=s(e);for(;;){if([i(t,"node_modules","@stablyai","playwright-test"),i(t,"node_modules",".pnpm","@stablyai+playwright-test")].some(e=>E(e)))return!0;const e=o(t);if(e===t)return!1;t=e}}(e);return t||(console.warn("[33mβ οΈ @stablyai/playwright-test is not installed. Stably reporter will not be injected.[0m"),console.warn("[33m Install it with: npm install @stablyai/playwright-test[0m"),console.warn("[33m Reference: ]8;;https://docs.stably.ai/getting-started/sdk-setup-guidehttps://docs.stably.ai/getting-started/sdk-setup-guide]8;;[0m\n")),t},a=(e,t)=>{try{return function({baseConfigPath:e,projectDir:t}){const r=function(e){try{const t=h("npm pkg get type",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]});return"module"===JSON.parse(t.trim())}catch{return!1}}(t),n=r?"mts":"ts",a=o(s(e)),c=l(e),u=i(a,function(e){return"1"===process.env[wo]?`${yo}-wrapper.config.${e}`:`.stably-playwright-wrapper.config.${e}`}(n)),d=`\n// Auto-generated wrapper config by Stably CLI\n// This file injects the Stably reporter and ensures trace is enabled\nimport baseConfig from './${c}';\nimport { defineConfig, stablyReporter } from '@stablyai/playwright-test';\n\n// Inline type definitions to avoid import failures when @stablyai/playwright-test is not installed\ntype StablyNotificationConfig = {\n email?: { to: string[]; notifyOnStart?: boolean; notifyOnResult?: 'all' | 'failures-only' | null } | null;\n slack?: { channelName: string; notifyOnStart?: boolean; notifyOnResult?: 'all' | 'failures-only' } | null;\n};\n\ntype ProjectNotificationConfig = {\n projectName: string;\n notifications: StablyNotificationConfig;\n};\n\n// Extract notification configs from projects that have stably.notifications defined\n// This runs at config-load time before Playwright strips custom properties\nconst extractNotificationConfigs = (): ProjectNotificationConfig[] | undefined => {\n const projects = baseConfig.projects;\n if (!projects || !Array.isArray(projects)) return undefined;\n\n const configs = projects\n .map((p: { name?: string; stably?: { notifications?: StablyNotificationConfig } }) => {\n const notifications = p.stably?.notifications;\n return notifications ? { projectName: p.name ?? '', notifications } : undefined;\n })\n .filter((config): config is ProjectNotificationConfig => config != null);\n\n return configs.length > 0 ? configs : undefined;\n};\n\nconst isStablyReporter = (reporter: unknown): boolean => {\n // Only match @stablyai npm scope to avoid false positives on unrelated reporters\n // that might contain "stably" substring (e.g., "unstably-runner")\n if (typeof reporter === 'string') {\n return reporter.includes('@stablyai');\n }\n if (Array.isArray(reporter) && typeof reporter[0] === 'string') {\n return reporter[0].includes('@stablyai');\n }\n return false;\n};\n\nconst getStablyReporterOptions = (reporters: unknown[]): Record<string, unknown> | undefined => {\n for (const reporter of reporters) {\n if (Array.isArray(reporter) && typeof reporter[0] === 'string' && reporter[0].includes('@stablyai')) {\n return (reporter[1] as Record<string, unknown>) ?? {};\n }\n }\n return undefined;\n};\n\nconst filterOutStablyReporter = (reporters: unknown[]): unknown[] => {\n return reporters.filter((reporter) => !isStablyReporter(reporter));\n};\n\n// Decode sensitive values from env var (set by CLI --env flag)\nconst decodeSensitiveValues = (): string[] | undefined => {\n const encoded = process.env.STABLY_SENSITIVE_VALUES;\n if (!encoded) return undefined;\n try {\n const decoded: unknown = JSON.parse(Buffer.from(encoded, 'base64').toString('utf-8'));\n return Array.isArray(decoded) ? decoded.filter((v): v is string => typeof v === 'string') : undefined;\n } catch {\n return undefined;\n }\n};\n\nconst buildReporterList = () => {\n const existingReporters = baseConfig.reporter;\n const sensitiveValues = decodeSensitiveValues();\n\n // Resolve errorSummary: env var STABLY_ERROR_SUMMARY=0 disables it\n const resolveErrorSummary = (existingValue?: unknown): boolean | undefined => {\n if (process.env.STABLY_ERROR_SUMMARY === '0') return false;\n if (typeof existingValue === 'boolean') return existingValue;\n return undefined; // let the reporter default (true)\n };\n\n // No existing reporters - create fresh stably reporter\n if (!existingReporters) {\n return [stablyReporter({\n apiKey: process.env.STABLY_API_KEY,\n cliVersion: '${pn}',\n projectId: process.env.STABLY_PROJECT_ID,\n source: 'cli',\n notificationConfigs: extractNotificationConfigs(),\n errorSummary: resolveErrorSummary(),\n ...(sensitiveValues && { sensitiveValues }),\n })];\n }\n\n // Normalize to array\n const reportersArray: unknown[] = Array.isArray(existingReporters)\n ? existingReporters\n : [[existingReporters, {}]];\n\n // If user has a stably reporter, take their options but override credentials\n const existingOptions = getStablyReporterOptions(reportersArray);\n const stablyReporterEntry = stablyReporter({\n ...existingOptions,\n apiKey: process.env.STABLY_API_KEY,\n cliVersion: '${pn}',\n projectId: process.env.STABLY_PROJECT_ID,\n source: 'cli',\n notificationConfigs: extractNotificationConfigs(),\n errorSummary: resolveErrorSummary(existingOptions?.errorSummary),\n ...(sensitiveValues && { sensitiveValues }),\n });\n\n // Keep all non-stably reporters, add our (merged or fresh) stably reporter\n const otherReporters = filterOutStablyReporter(reportersArray);\n return [...otherReporters, stablyReporterEntry];\n};\n\nexport default defineConfig({\n ...baseConfig,\n use: {\n ...baseConfig.use,\n trace: 'on',\n },\n reporter: buildReporterList(),\n});\n`.trim();return E(a)||I(a,{recursive:!0}),T(u,d,"utf-8"),function(e,t){const r=i(e,".gitignore");try{if(E(r)){const e=x(r,"utf-8");if(e.split("\n").map(e=>e.trim()).includes(t))return;const n=e.length>0&&!e.endsWith("\n");A(r,`${n?"\n":""}${t}\n`)}else T(r,`${t}\n`)}catch{}}(a,"1"===process.env[wo]?bo:".stably-playwright-wrapper.config.*"),u}({baseConfigPath:e,projectDir:t})}catch{return void console.warn("[33mβ οΈ Could not create Stably wrapper config. Reporter injection skipped.[0m")}};if(e.some(e=>"--config"===e||"-c"===e||e.startsWith("--config=")||e.startsWith("-c="))){const t=e.findIndex(e=>"--config"===e||"-c"===e);if(-1!==t&&e[t+1]){const i=s(r,e[t+1]),c=o(i);if(!n(c))return;const l=a(i,c);if(!l)return;return e[t+1]=l,l}const i=e.findIndex(e=>e.startsWith("--config=")||e.startsWith("-c="));if(-1!==i){const t=s(r,e[i].split("=")[1]),c=o(t);if(!n(c))return;const l=a(t,c);if(!l)return;const u=e[i].startsWith("--config=")?"--config=":"-c=";return e[i]=`${u}${l}`,l}}const c=Io(r);if(!c)return;const u=o(c);if(!n(u))return;const d=a(c,u);return d?(e.push("--config",d),d):void 0}({forwardedArgs:m,hasCredentials:null!=b}):void 0;ls.info("[test] Reporter injection setup complete",{hasWrapperConfig:!!S}),ls.info("[test] Spawning Playwright process");const k=Date.now();if(await function(e,t={}){ls.info("[test] Detecting Playwright installation");const r=El();ls.info("[test] Playwright installation check",{installed:r.installed,inNodeModules:r.inNodeModules,packageManager:r.packageManager,packageName:r.packageName}),r.installed||(console.error('Playwright is not installed. Please run "stably init" to install it.'),process.exit(1)),r.inNodeModules||(console.error("Playwright is present in your project, but not in node_modules. Please install your dependencies before proceeding."),process.exit(1));const{packageManager:n}=r;n||(console.error("Playwright installation not found. Could not determine your package manager (tried pnpm, yarn, and npm)."),process.exit(1));const[s,...o]=Al(n),i=(a=t.env)?{...process.env,...a}:process.env;var a;const c=[s,...o,...e];ls.info("[test] Spawning Playwright process",{command:c.join(" "),pid:process.pid});const l=Date.now(),u=g(s,[...o,...e],{stdio:["inherit","pipe","pipe"],shell:"win32"===process.platform,env:{...i,...process.env.CI?{}:{FORCE_COLOR:"1"}}});ls.info("[test] Playwright process spawned",{childPid:u.pid});const d=Cl(n),p=function(){let e=!1,t="";return(r,n)=>{if(!e){t+=r,t.length>1024&&(t=t.slice(-1024));for(const r of Pl)if(t.includes(r))return n.write("\n[stably] Hint: This is a Playwright error, not caused by @stablyai/playwright-test.\n Common causes: running from the wrong directory (especially in monorepos),\n or a dependency pulling in a conflicting @playwright/test version.\n"),void(e=!0)}}}();u.stdout?.on("data",e=>{d(e,process.stdout)}),u.stderr?.on("data",e=>{const t=e.toString();d(e,process.stderr),p(t,process.stderr)});const f=new AbortController,h=()=>!f.signal.aborted&&(f.abort(),t.onClose?.(),process.removeListener("SIGINT",m),process.removeListener("SIGTERM",m),!0),m=e=>{ls.info("[test] Signal received, killing Playwright process",{signal:e,childPid:u.pid}),h(),u.kill(e);const t="SIGINT"===e?130:143;process.exit(t)};return process.on("SIGINT",m),process.on("SIGTERM",m),new Promise((e,t)=>{u.on("error",e=>{h()&&(ls.error("[test] Playwright process error",{error:e.message,childPid:u.pid}),t(e))}),u.on("close",t=>{if(!h())return;ls.info("[test] Playwright process exited",{exitCode:t,durationMs:Date.now()-l});const r=[process.stdout,process.stderr].filter(e=>e.writableNeedDrain).map(e=>new Promise(t=>e.once("drain",t)));Promise.race([Promise.all(r),new Promise(e=>setTimeout(e,5e3))]).then(()=>{process.exitCode=t??0,e(t??0)})})})}(m,{env:{...v,...b},onClose:()=>{var e;ls.info("[test] Playwright process closed, cleaning up wrapper config"),(e=S)&&E(e)&&_(e)}}),Ue.remoteEnvName&&b){const e=await _l(),t=e&&e.timestamp>=k;if(e&&t){const t=await ys();await(async({authHeader:e,orgId:t,runId:r,envName:n,timeoutMs:s=3e3})=>{ls.debug("Tagging run with envName",{runId:r,envName:n});try{let i;const a=new Promise(e=>{i=setTimeout(()=>e("timeout"),s)}),c=await Promise.race([(o={auth:e,client:In(),headers:_s(t),path:{runId:r},body:{envName:n}},(o.client??ln).patch({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/runs/{runId}/metadata",...o,headers:{"Content-Type":"application/json",...o.headers}})),a]);if(clearTimeout(i),"timeout"===c)return void ls.warn("Timed out tagging run with envName",{runId:r,envName:n,timeoutMs:s});if(c.error)return void ls.warn("Failed to tag run with envName",{runId:r,envName:n,status:c.response?.status});ls.debug("Successfully tagged run with envName",{runId:r,envName:n})}catch(e){ls.warn("Error tagging run with envName",{runId:r,envName:n,error:e instanceof Error?e.message:String(e)})}var o})({authHeader:ws(t),orgId:"oauth"===t.type?t.auth.context.orgId:void 0,runId:e.runId,envName:Ue.remoteEnvName})}else e&&!t?ls.debug("[test] last-run.json predates this test invocation, skipping envName tagging",{runId:e.runId,fileTimestamp:e.timestamp,testStartTime:k}):ls.debug("[test] No last-run.json found, skipping envName tagging")}}function Ul(e){const t=new Date(e),r=new Date,n=r.getTime()-t.getTime(),s=Math.floor(n/1e3),o=Math.floor(s/60),i=Math.floor(o/60),a=Math.floor(i/24);if(s<60)return"just now";if(o<60)return`${o}m ago`;if(i<24)return`${i}h ago`;if(a<=7)return`${a}d ago`;const c=t.toLocaleString("en-US",{month:"short"}),l=t.getDate();return t.getFullYear()===r.getFullYear()?`${c} ${l}`:`${c} ${l}, ${t.getFullYear()}`}var Ll=e=>"oauth"===e.type?e.auth.context.orgId:void 0,$l=(e,t,r)=>{if(401!==e.response.status&&403!==e.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),404===e.response.status&&r&&(ce(Dr("error",r)),process.exit(1)),400===e.response.status){const t=e.error&&"object"==typeof e.error&&"error"in e.error?e.error.error:"Bad request";ce(Dr("error",t)),process.exit(1)}e.error&&(ce(Dr("error",`Failed to ${t}: ${e.response.status}`)),process.exit(1))},Dl={PASSED:e=>Dr("success",e),FAILED:e=>Dr("error",e),TIMEDOUT:e=>Dr("error",e),CANCELLED:e=>Dr("warning",e),INTERRUPTED:e=>Dr("warning",e),RUNNING:e=>Dr("info",e),QUEUED:e=>Dr("muted",e)},Nl=(e,t)=>e?e.length>t?`${e.slice(0,t-1)}β¦`:e:"-",Ol=e=>{if(!e)return"-";const t=new Date(e);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},Bl=e=>(Dl[e]??(e=>e))(e),jl=/\x1b\[[0-9;]*m/g,Ml=(e,t)=>{const r=e.replace(jl,"").length,n=Math.max(0,t-r);return e+" ".repeat(n)},Fl=e=>`${JSON.stringify(e,null,2)}\n`,Hl=(e,t,r)=>{if(!e)return;const n=e.toUpperCase();if(t.includes(n))return n;ce(Dr("error",`Invalid ${r} value "${e}". Must be one of: ${t.join(", ").toLowerCase()}`)),process.exit(1)},Gl=/\x1b\[[0-9;]*m/g,Wl=(e,t)=>{const r=e.replace(Gl,"").length,n=Math.max(0,t-r);return e+" ".repeat(n)},Vl=(e,t)=>e?e.length>t?`${e.slice(0,t-1)}β¦`:e:"-",Yl=e=>e?e.split("T")[0]??"-":"-",zl=e=>`${(100*e).toFixed(1)}%`,ql=e=>`${JSON.stringify(e,null,2)}\n`,Kl=e=>{if(!e)return;const t=parseInt(e,10);return(Number.isNaN(t)||t<1||t>90)&&(ce(Dr("error","--days must be an integer between 1 and 90")),process.exit(1)),t},Jl=e=>{if(!e)return;const t=parseInt(e,10);return(Number.isNaN(t)||t<1||t>100)&&(ce(Dr("error","--limit must be an integer between 1 and 100")),process.exit(1)),t},Xl="stably",Ql=`https://registry.npmjs.org/${Xl}/latest`;function Zl(e){const t=e.match(/^(\d+)\.(\d+)\.(\d+)/);return t?{major:parseInt(t[1],10),minor:parseInt(t[2],10),patch:parseInt(t[3],10)}:null}function eu(e,t){const r=Zl(e),n=Zl(t);return!(!r||!n)&&(n.major>r.major||!(n.major<r.major)&&(n.minor>r.minor||!(n.minor<r.minor)&&n.patch>r.patch))}var tu=n.join(D.homedir(),".stably"),ru=n.join(tu,"update-check.json"),nu="1"===process.env.STABLY_DISABLE_UPDATE_CHECK,su=he.object({lastCheck:he.number(),latestVersion:he.string()}),ou=Symbol.for("stably.updateNotifier.registered");function iu(e=""){process.stdout.write(`${e}\n`)}function au(...e){process.stderr.write(`${e.join(" ")}\n`)}var cu=he.object({version:he.string()});var lu=!1,uu=async()=>{if(lu)try{const{shutdown:e}=await import("@hyperdx/node-opentelemetry"),t=process.stderr.write.bind(process.stderr),r=process.stdout.write.bind(process.stdout),n=(e,...t)=>{const r=t[0];return!("string"!=typeof r||!r.includes("OpenTelemetry"))||!(!Buffer.isBuffer(r)||!r.toString().includes("OpenTelemetry"))||e(...t)};process.stderr.write=(...e)=>n(t,...e),process.stdout.write=(...e)=>n(r,...e);try{await e()}finally{process.stderr.write=t,process.stdout.write=r}}catch{}},du=e=>{const t=e.toLowerCase();return t.startsWith("npm_config_")||"node_options"===t};!function(){if(nu||function(e=process.argv.slice(2)){return e.includes("upgrade")}())return;const e=function(){try{const e=v.readFileSync(ru,"utf-8");return su.parse(JSON.parse(e))}catch{return null}}(),t=Date.now();if((null==e||t-e.lastCheck>=18e5)&&function(){const e=`\n import { get } from 'node:https';\n import fs from 'node:fs';\n const url = '${Ql}';\n const cacheFile = ${JSON.stringify(ru)};\n const cacheDir = ${JSON.stringify(tu)};\n\n const req = get(url, { timeout: 5000 }, (res) => {\n if (res.statusCode !== 200) process.exit(1);\n let data = '';\n res.on('data', (chunk) => data += chunk);\n res.on('end', () => {\n try {\n const version = JSON.parse(data).version;\n if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });\n fs.writeFileSync(cacheFile, JSON.stringify({ lastCheck: Date.now(), latestVersion: version }));\n } catch {}\n process.exit(0);\n });\n });\n req.on('error', () => process.exit(1));\n req.on('timeout', () => { req.destroy(); process.exit(1); });\n `;try{g(process.execPath,["--input-type=module","-e",e],{detached:!0,stdio:"ignore",windowsHide:!0}).unref()}catch{}}(),null!=e&&eu(pn,e.latestVersion)){if(!0===process[ou])return;process[ou]=!0;let t=!1;const r=()=>{if(t)return;t=!0;const r=`${Dr("warning",`update available (${pn} β ${e.latestVersion})`)} - run \`${Xl} upgrade\` to get the latest version\n`;try{v.writeSync(2,r)}catch{}};process.once("beforeExit",r),process.once("exit",r)}}(),Ue.cwdChanged&&ls.debug("Changed working directory",{cwd:Ue.newCwd});for(const e of Ue.envFilesLoaded)ls.debug("Loaded env file",{path:e});for(const e of Ue.envFileErrors)ls.warn(e);var pu=process.argv.findIndex(e=>"-v"===e||"--verbose"===e);-1!==pu&&process.argv.splice(pu,1);var fu=process.argv.findIndex(e=>"--no-telemetry"===e);-1!==fu&&process.argv.splice(fu,1),ls.info("CLI starting",{version:pn,args:process.argv.slice(2),cwd:process.cwd()}),process.on("unhandledRejection",(e,t)=>{ls.error("Unhandled promise rejection",{reason:e instanceof Error?{message:e.message,stack:e.stack}:e,promise:String(t)}),ls.flush(),ls.printLogFileInfo()}),process.on("uncaughtException",(e,t)=>{"EPIPE"!==e.code&&(ls.error("Uncaught exception",{error:{message:e.message,stack:e.stack,name:e.name},origin:t}),ls.flush(),ls.printLogFileInfo())});var hu=new u;hu.name("stably").description("AI-assisted Playwright testing CLI").version(pn),hu.enablePositionalOptions();var gu=(e,t)=>"cloud"===t.browser||"cloud"===e.parent?.opts().browser||"1"===process.env.STABLY_CLOUD_BROWSER;hu.showHelpAfterError(),hu.exitOverride(),hu.configureHelp({subcommandTerm:e=>{const t=e.registeredArguments.map(e=>e.required?`<${e.name()}>`:`[${e.name()}]`).join(" ");return t?`${e.name()} ${t}`:e.name()}}),hu.addHelpText("after","\nGlobal options (available for all commands):\n -C, --cwd <path> Change working directory before running\n --browser <type> Browser type: local or cloud (default: local)\n --env <name> Load environment variables from a remote Stably environment\n --env-file <path> Load environment variables from a local .env file (repeatable)\n -v, --verbose Enable debug-level logging\n --no-telemetry Disable error telemetry");var mu=[];hu.configureOutput({writeOut:e=>process.stdout.write(e),writeErr:e=>{mu.push(e)}});var yu=()=>{const e=hu.helpInformation().trimEnd();return e?`${e}\n`:""},bu=(e,t)=>{let r=e;for(const e of t){const t=r.commands.find(t=>t.name()===e||t.aliases().includes(e));if(!t)return;r=t}return r},wu=()=>{process.stdout.write(yu())};hu.command("help [command...]").description("Show help for a command (e.g. stably help create)").action(e=>{if(!e||0===e.length)return void wu();const t=bu(hu,e);if(!t)return process.stderr.write(`Unknown command: ${e.join(" ")}\n`),wu(),void(process.exitCode=1);var r;r=t,process.stdout.write((e=>{const t=e.helpInformation().trimEnd();return t?`${t}\n`:""})(r))}),hu.option("--browser <type>","Browser type: local or cloud (default: local)").action((e,t)=>Il({mode:"chat",getHelpText:yu,cloudBrowser:gu(t,e)})),hu.command("login").description("Authenticate with Stably in your browser").action(Yn),hu.command("logout").description("Clear stored Stably credentials").action(async()=>{const e=gs();e&&(ae.warn(`Environment variables ${Dr("info","STABLY_API_KEY")} and ${Dr("info","STABLY_PROJECT_ID")} are set.`),ae.warn("They will continue to be used for authentication even after logout."),ae.warn("Unset them if you want to fully de-authenticate this shell/session."));const t=await Dn();if(!t)return void ce(Dr("warning",e?"No stored OAuth login found to clear.":"You are not logged in."));const r=le();r.start("Logging out..."),await(async e=>{try{await fetch(`${gn}/api/backend/v1/logout`,{body:JSON.stringify({refresh_token:e}),headers:{"Content-Type":"application/json"},method:"POST"})}catch{}})(t.refreshToken),await On(),await jn(),r.stop(Dr("success","β Logged out")),ce(Dr("success","You have been logged out successfully."))}),hu.command("whoami").description("Show auth status and current project").action(async()=>{ae.info(`${ne.bold("CLI Version:")} ${Dr("info",pn)}`);const e=gs();if(e){ae.info(ne.dim("Authentication: Environment variables")),ae.info(` ${ne.bold("API Key:")} ${Dr("info",e.apiKey.slice(0,8))}...`),ae.info(` ${ne.bold("Project ID:")} ${Dr("info",e.projectId)}`);const t=await Dn();if(t){let e;try{e=An(t.accessToken).email}catch{e=void 0}ae.warn("Stored OAuth login detected but will be ignored (env auth takes precedence)."),e&&ae.info(` ${ne.bold("OAuth Email:")} ${Dr("info",e)}`),ae.info(` ${ne.bold("Tip:")} Unset env vars to use OAuth`)}return void ce(Dr("success","Authenticated via environment variables"))}const t=await Dn();if(!t)return void ce(Dr("warning","Not logged in. Run `stably login` to authenticate."));let r;try{r=An(t.accessToken).email}catch{r=void 0}const s=await Bn();if(!s)return ae.info(ne.dim("Authentication: OAuth (not linked to a project)")),r&&ae.info(` ${ne.bold("Email:")} ${Dr("info",r)}`),void ce(Dr("warning","Logged in but this directory is not linked to a project. Run `stably login` to link."));const o=await(async()=>kn(process.cwd(),Rn))(),i=o?n.dirname(o):process.cwd(),a=n.relative(process.cwd(),i)||".";ae.info(ne.dim("Authentication: OAuth")),r&&ae.info(` ${ne.bold("Email:")} ${Dr("info",r)}`),ae.info(` ${ne.bold("Organization:")} ${Dr("info",s.orgName)}`),ae.info(` ${ne.bold("Project:")} ${Dr("info",s.projectName)}`),ae.info(` ${ne.bold("Linked at:")} ${ne.dim(a)}`),ce(Dr("success","Authenticated"))}),hu.command("tunnel",{hidden:!0}).description("Expose a local server with a secure tunnel URL").option("-p, --port <number>","Local port to expose","3000").action(async e=>{ue(`Starting development server for port ${e.port}...`);const t=await ys(),r="oauth"===t.type?`${t.auth.context.orgName}-${t.auth.context.projectName}`.toLowerCase().replace(/[^a-z0-9-]/g,""):`project-${t.auth.projectId}`.toLowerCase(),n=le();n.start("Starting development server...");const s=await Ce(`http://localhost:${e.port}`,{subdomain:r});n.stop(`Your local environment is available at: ]8;;${s.url}${ne.underline(Dr("link",s.url))}]8;;`)}),hu.command("create [prompt...]").description("Generate a test from prompt (omit prompt to infer from branch diff)").option("-o, --output <dir>","Output directory for generated test files").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{const n=e.length>0&&"test"===e[0]?e.slice(1):e;return Il({mode:"single",prompt:n,outputDir:t.output,cloudBrowser:gu(r,t)})}).command("test",{hidden:!0}).description("Generate a Playwright test from a prompt (deprecated: use `stably create <prompt>` directly)").argument("<prompt...>","Prompt describing the test to generate").option("-o, --output <dir>","Output directory for generated test files").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>Il({mode:"single",prompt:e,outputDir:t.output,cloudBrowser:gu(r,t)})),hu.command("plan [prompt...]").description("Discover coverage gaps and generate test.fixme() plan files").action(async e=>Il({mode:"plan",prompt:e??[]})),hu.command("verify <prompt...>").description("Verify your app works correctly against a prompt").option("-u, --url <url>","Starting URL to verify against").option("--max-budget <dollars>","Maximum budget in USD (default: 5)",Number.parseFloat).option("--no-interactive","Disable interactive verify preflight setup").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{if(void 0!==t.maxBudget&&(!Number.isFinite(t.maxBudget)||t.maxBudget<=0))throw new Error("--max-budget must be a positive number");return Il({mode:"verify",prompt:e,url:t.url,maxBudgetUsd:t.maxBudget,interactive:t.interactive,cloudBrowser:gu(r,t)})}),hu.command("internal-fix-run <runId>",{hidden:!0}).description("Internal: run fix session in subprocess").action(async e=>Il({mode:"fix",runId:e,cloudBrowser:"1"===process.env.STABLY_CLOUD_BROWSER})),hu.command("fix [runId]").description("Fix failing tests from a run (auto-detects from last test run or CI)").option("--browser <type>","Browser type: local or cloud (default: local)").action(async(e,t,r)=>{const n=Boolean(process.env.STABLY_CLI_VISUAL_MOCK);gu(r,t)&&(process.env.STABLY_CLOUD_BROWSER="1"),n||function(e){try{return h("git rev-parse --is-inside-work-tree",{cwd:e,encoding:"utf-8",stdio:["pipe","pipe","pipe"]}),!0}catch{return!1}}(process.cwd())||(ls.error('Not a git repository. The "stably fix" command requires a git repository to track changes made during the fix. Please run this command from inside a git repository.'),process.stderr.write('Error: Not a git repository.\nThe "stably fix" command requires a git repository to track changes made during the fix.\nPlease run this command from inside a git repository.\n'),process.exit(1));const s=await(async e=>{const t=e=>e.replace(/\//g,"_");if(e)return ls.debug("Run ID provided explicitly",{runId:e}),t(e);const r=function(){if(process.env.CI_BUILD_ID)return process.env.CI_BUILD_ID;const e=(({env:e=process.env,cwd:t=process.cwd()}={})=>{for(const r of Object.keys(xr))if(xr[r].detect({env:e,cwd:t}))return{isCi:!0,...xr[r].configuration({env:e,cwd:t})};return{isCi:Boolean(e.CI),...cr({env:e,cwd:t})}})();if(!e.isCi)return;const t=function(e){switch(e){case"github":return process.env.GITHUB_RUN_ATTEMPT;case"azure-devops":return process.env.SYSTEM_JOBATTEMPT;case"bitbucket":return process.env.BITBUCKET_STEP_RUN_NUMBER;default:return}}(e.service),r=[e.service,"slug"in e?e.slug?.replace(/\//g,"_"):void 0,"build"in e?String(e.build):void 0,"job"in e?String(e.job):void 0,t&&String(t)].filter(Boolean);return r.length>0?r.join("-"):void 0}();if(r)return ls.debug("Run ID detected from CI environment",{runId:r}),t(r);ls.debug("No explicit run ID or CI environment detected, checking last-run.json");const n=await _l();if(n){const e=(Date.now()-n.timestamp)/36e5;return ls.debug("Run ID found in last-run.json",{runId:n.runId,timestamp:n.timestamp,filePath:n.filePath,ageHours:Math.round(e)}),e>24&&ls.warn(`Using run ID from ${Math.round(e)} hours ago (${n.filePath}). Provide an explicit run ID if this is not the run you want to fix.`),t(n.runId)}ls.debug("No run ID found in last-run.json")})(e)??(n?"visual-mock-run":void 0);if(s||(process.stderr.write('Run ID is required. Either:\n 1. Run "stably test" first (run ID will be auto-detected)\n 2. Provide a run ID: stably fix <runId>\n 3. Run in CI (auto-detected from environment)\n'),process.exit(1)),n)return Il({mode:"fix",runId:s,cloudBrowser:"1"===process.env.STABLY_CLOUD_BROWSER});const o=await(async e=>{const t=await ys(),r=ws(t),n=bs(t),[,s]=process.argv;if(!s)throw new Error("Unable to determine CLI entrypoint for fix subprocess.");return await(async({runId:e,cliEntry:t,stablyApiKey:r,stablyProjectId:n,baseEnv:s=process.env,cwd:o=process.cwd(),execPath:i=process.execPath,execArgv:a=process.execArgv,stdio:c="inherit",spawnImpl:l=({command:e,args:t,options:r})=>g(e,t,r)})=>{const u=(({baseEnv:e,stablyApiKey:t,stablyProjectId:r,playwrightSession:n})=>{const s={...e};for(const e of Object.keys(s))du(e)&&delete s[e];return{...s,STABLY_API_KEY:t,STABLY_PROJECT_ID:r,...n?{STABLY_PLAYWRIGHT_SESSION:n}:{}}})({baseEnv:s,stablyApiKey:r,stablyProjectId:n});return await new Promise((r,n)=>{const s=l({args:[...a,t,"internal-fix-run",e],command:i,options:{cwd:o,stdio:c,env:u}});s.once("error",n),s.once("exit",(e,t)=>{r(t?1:e??1)})})})({cliEntry:s,runId:e,stablyApiKey:r,stablyProjectId:n,cwd:process.cwd(),stdio:"inherit"})})(s);0!==o&&process.exit(o)}),hu.command("init").description("Initialize Playwright and Stably SDK in your project").action(async()=>Il({mode:"init"})),hu.command("upgrade").description("Upgrade to latest version (use --check to only check)").option("-c, --check","Only check for updates without upgrading").action(e=>async function(e){const{check:t=!1}=e;let r;iu(Dr("info","Checking for updates...\n"));try{r=await async function(){const e=await async function(){const e=new AbortController,t=setTimeout(()=>e.abort(),1e4);t.unref();try{const t=await fetch(Ql,{signal:e.signal});if(!t.ok)throw new Error(`Failed to fetch latest version: ${t.statusText}`);return cu.parse(await t.json()).version}finally{clearTimeout(t)}}();return{current:pn,latest:e,isOutdated:eu(pn,e)}}()}catch(e){return au(Dr("error","Failed to check for updates:"),e instanceof Error?e.message:e),void(process.exitCode=1)}if(iu(`Current version: ${Dr("warning",r.current)}`),iu(`Latest version: ${Dr("success",r.latest)}`),iu(),!r.isOutdated)return void iu(Dr("success","β You are already on the latest version!"));if(iu(Dr("warning",`β A new version is available: ${r.current} β ${r.latest}`)),iu(),t)return iu(ne.dim("Exiting with code 1 to indicate update available (useful for CI).")),void(process.exitCode=1);const n=function(){const e=process.argv[1]||"";if(e.includes("_npx")||e.includes(".npm/_cacache")||e.includes(".npm\\_cacache"))return"npx";try{const t=h("npm root -g",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-npm"}catch{}if(e.includes("node_modules/stably")||e.includes("node_modules\\stably"))return"global-npm";try{const t=h("pnpm root -g",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-pnpm"}catch{}try{const t=h("yarn global dir",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-yarn-classic"}catch{}try{const t=h("yarn config get globalFolder",{encoding:"utf-8"}).trim();if(e.includes(t))return"global-yarn-berry"}catch{}return"unknown"}(),s=function(e){switch(e){case"global-npm":case"global-yarn-berry":case"unknown":return{command:"npm",args:["install","-g","--no-fund",`${Xl}@latest`],description:`npm install -g ${Xl}@latest`};case"global-pnpm":return{command:"pnpm",args:["add","-g",`${Xl}@latest`],description:`pnpm add -g ${Xl}@latest`};case"global-yarn-classic":return{command:"yarn",args:["global","add",`${Xl}@latest`],description:`yarn global add ${Xl}@latest`};case"npx":return{command:"npx",args:[`${Xl}@latest`],description:`npx ${Xl}@latest (always uses latest)`}}}(n);if("npx"===n)return iu(ne.dim("You are running via npx, which always fetches the latest version.")),void iu(ne.dim(`Simply run: ${ne.white("npx stably")} to use the latest version.`));"unknown"===n?(iu(Dr("warning","Could not detect installation method. Falling back to npm.")),iu()):"global-yarn-berry"===n&&(iu(Dr("warning","Yarn Berry does not support global packages. Falling back to npm.")),iu()),iu(`Upgrade command: ${Dr("info",s.description)}`),iu(),iu(Dr("info","Upgrading...")),iu();try{await(o=s.command,i=s.args,new Promise((e,t)=>{const r=g(o,i,{stdio:"inherit",shell:"win32"===process.platform});r.on("close",r=>{0===r?e():t(new Error(`Upgrade command exited with code ${r}`))}),r.on("error",e=>{t(e)})})),function(){try{v.unlinkSync(ru)}catch{}}(),iu(),iu(Dr("success","β Upgrade complete!")),iu(ne.dim(`Run ${ne.white("stably --version")} to verify.`))}catch(e){au(Dr("error","Upgrade failed:"),e instanceof Error?e.message:e),iu(),iu(ne.dim("You can try manually running:")),iu(Dr("info",` ${s.description}`)),process.exitCode=1}var o,i}(e));var vu=hu.command("env").description("Manage remote environments");vu.command("list").description("List available environments").action(async()=>{const e=await ys(),t=bs(e),r=ws(e);ls.debug("Listing environments",{projectId:t});const n=await(s={auth:r,client:In(),path:{projectId:t}},(s.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments",...s}));var s;401!==n.response.status&&403!==n.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),n.error&&(ce(Dr("error",`Failed to list environments: ${n.response.status}`)),process.exit(1));const{environments:o}=n.data;if(0!==o.length){process.stdout.write(`${ne.bold("Environments")}\n\n`);for(const e of o){const t=e.isDefault?Dr("success"," (default)"):"",r=ne.dim(` ${e.variableCount} variable${1!==e.variableCount?"s":""}`);process.stdout.write(` ${Dr("info",e.name)}${t}${r}\n`),e.description&&process.stdout.write(` ${ne.dim(e.description)}\n`)}process.stdout.write("\n")}else process.stdout.write(ne.dim("No environments found. Create one on your Stably dashboard.\n"))}),vu.command("inspect <name>").description("Show variable metadata (name, sensitive flag, updated timestamp)").action(e=>(async e=>{const t=await ys(),r=bs(t),n=ws(t);ls.debug("Inspecting environment",{name:e,projectId:r});const s=await(o={auth:n,client:In(),path:{projectId:r,environmentName:e}},(o.client??ln).get({security:[{scheme:"bearer",type:"http"}],url:"/internal/v1/cli/projects/{projectId}/environments/{environmentName}/inspect",...o}));var o;404===s.response.status&&(ce(Dr("error",`Environment "${e}" not found. Run ${ne.bold("stably env list")} to see available environments.`)),process.exit(1)),401!==s.response.status&&403!==s.response.status||(ce(Dr("error","Access denied.")),process.exit(1)),s.error&&(ce(Dr("error",`Failed to inspect environment: ${s.response.status}`)),process.exit(1));const{variables:i}=s.data;if(0!==i.length){process.stdout.write(`${ne.bold(e)} ${ne.dim(`(${i.length} variable${1!==i.length?"s":""})`)}\n\n`);for(const e of i){const t=ne.dim(` [updated ${Ul(e.updatedAt)}]`);e.sensitive?process.stdout.write(` ${Dr("info",e.name)} ${Dr("warning","[sensitive]")}${t}\n`):process.stdout.write(` ${Dr("info",e.name)}${t}\n`)}process.stdout.write("\n")}else process.stdout.write(ne.dim(`Environment "${e}" has no variables.\n`))})(e));var Iu=hu.command("analytics").description("View test health analytics");Iu.command("flaky").description("Show most flaky tests ranked by flaky rate").option("--days <n>","Look-back window in days (1-90, default: 7)").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <n>","Max rows returned (1-100, default: 10)").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t),o=Kl(e.days),i=Jl(e.limit);ls.debug("Listing flaky tests",{projectId:r,days:o,branch:e.branch,limit:i});const a=In(),c=await a.get({url:"/internal/v1/cli/analytics/flaky",security:[{scheme:"bearer",type:"http"}],auth:n,headers:{..._s(s)},query:{projectId:r,days:o,branchName:e.branch,limit:i}});$l(c,"list flaky tests");const l=c.data;e.json?process.stdout.write(ql(l)):process.stdout.write(((e,t)=>{const r=[],n=e.filters.branch?`branch: ${e.filters.branch}`:"all branches";if(r.push(ne.bold(`Most Flaky Tests (last ${e.period.days} days, ${n})`)),r.push(""),0===e.tests.length)return r.push(ne.dim(" No flaky tests found.")),r.push(""),r.join("\n");const s=` ${Wl("REF",14)}${Wl("TEST",20)}${Wl("LOCATION",30)}${Wl("FLAKY",8)}${Wl("RUNS",7)}${Wl("RATE",9)}LAST FLAKY`;r.push(ne.dim(s));for(const t of e.tests){const e=t.testRef,n=Vl(t.title,18),s=Vl(t.location,28),o=String(t.flakyCount),i=String(t.nonSkippedRuns),a=zl(t.flakyRate),c=Yl(t.lastFlakyAt);r.push(` ${Wl(e,14)}${Wl(n,20)}${Wl(s,30)}${Wl(o,8)}${Wl(i,7)}${Wl(a,9)}${c}`)}r.push("");const o=e.summary.totalNonSkippedRuns;return r.push(` ${e.summary.totalFlakyTests} flaky tests found across ${o} runs.`),r.push(` Dashboard: ${ne.underline(Dr("link",`https://app.stably.ai/p/${t}/analytics`))}`),r.push(""),r.join("\n")})(l,r))}),Iu.command("failures").description("Show most failing tests ranked by failure rate").option("--days <n>","Look-back window in days (1-90, default: 7)").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <n>","Max rows returned (1-100, default: 10)").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t),o=Kl(e.days),i=Jl(e.limit);ls.debug("Listing failing tests",{projectId:r,days:o,branch:e.branch,limit:i});const a=In(),c=await a.get({url:"/internal/v1/cli/analytics/failures",security:[{scheme:"bearer",type:"http"}],auth:n,headers:{..._s(s)},query:{projectId:r,days:o,branchName:e.branch,limit:i}});$l(c,"list failing tests");const l=c.data;e.json?process.stdout.write(ql(l)):process.stdout.write(((e,t)=>{const r=[],n=e.filters.branch?`branch: ${e.filters.branch}`:"all branches";if(r.push(ne.bold(`Most Failed Tests (last ${e.period.days} days, ${n})`)),r.push(""),0===e.tests.length)return r.push(ne.dim(" No failing tests found.")),r.push(""),r.join("\n");const s=` ${Wl("REF",14)}${Wl("TEST",20)}${Wl("LOCATION",30)}${Wl("FAILED",8)}${Wl("RUNS",7)}${Wl("RATE",9)}LAST FAILED`;r.push(ne.dim(s));for(const t of e.tests){const e=t.testRef,n=Vl(t.title,18),s=Vl(t.location,28),o=String(t.failedCount),i=String(t.nonSkippedRuns),a=zl(t.failureRate),c=Yl(t.lastFailedAt);r.push(` ${Wl(e,14)}${Wl(n,20)}${Wl(s,30)}${Wl(o,8)}${Wl(i,7)}${Wl(a,9)}${c}`)}r.push("");const o=e.summary.totalNonSkippedRuns;return r.push(` ${e.summary.totalFailingTests} failing tests found across ${o} runs.`),r.push(` Dashboard: ${ne.underline(Dr("link",`https://app.stably.ai/p/${t}/analytics`))}`),r.push(""),r.join("\n")})(l,r))});var Tu=hu.command("runs").description("View test run history");Tu.command("list").description("List recent test runs").option("-b, --branch <name>","Filter by branch name").option("-n, --limit <number>","Number of runs (default: 20, max: 100)").option("--after <runId>","Show runs newer than this runId").option("--before <runId>","Show runs older than this runId").option("--source <type>","Filter by source: local, ci, web").option("-s, --status <type>","Filter by status: queued, running, passed, failed, timedout, cancelled, interrupted").option("--suite <name>","Filter by suite name").option("--trigger <type>","Filter by trigger: manual, scheduled, ui, api, github_action, suite_run").option("--json","Output as JSON").action(async e=>{const t=await ys(),r=bs(t),n=ws(t),s=Ll(t);let o;e.limit&&(o=parseInt(e.limit,10),(Number.isNaN(o)||o<1||o>100)&&(ce(Dr("error","--limit must be an integer between 1 and 100")),process.exit(1)));const i=Hl(e.source,["LOCAL","CI","WEB"],"--source"),a=Hl(e.status,["QUEUED","RUNNING","PASSED","FAILED","TIMEDOUT","CANCELLED","INTERRUPTED"],"--status"),c=Hl(e.trigger,["MANUAL","SCHEDULED","UI","API","GITHUB_ACTION","SUITE_RUN"],"--trigger");ls.debug("Listing runs",{projectId:r,branch:e.branch,limit:o,after:e.after,before:e.before,source:i,status:a,suite:e.suite,trigger:c});const l=await un({auth:n,client:In(),headers:_s(s),query:{projectId:r,branchName:e.branch,limit:o,afterRunId:e.after,beforeRunId:e.before,source:i,status:a,suiteName:e.suite,trigger:c}});$l(l,"list runs");const{runs:u,hasMore:d}=l.data;e.json?process.stdout.write(Fl(l.data)):process.stdout.write(((e,t)=>{if(0===e.length)return ne.dim("No runs found matching the specified filters.\n");const r=Math.min(40,Math.max(10,...e.map(e=>e.runId.length))),n={runId:{w:r+2,t:r},status:{w:14},branch:{w:32,t:30},started:{w:18}},s=[],o=`${Ml("Run ID",n.runId.w)}${Ml("Status",n.status.w)}${Ml("Branch",n.branch.w)}${Ml("Started",n.started.w)}Tests`;s.push(ne.bold(o));for(const t of e){const e=Nl(t.runId,n.runId.t),r=Bl(t.status),o=Nl(t.branchName,n.branch.t),i=Ol(t.startedAt),a=t.totalCount.toString();s.push(`${Ml(e,n.runId.w)}${Ml(r,n.status.w)}${Ml(o,n.branch.w)}${Ml(i,n.started.w)}${a}`)}if(t&&e.length>0){const t=e.at(-1)?.runId;t&&(s.push(""),s.push(ne.dim(`Next page: stably runs list --before ${t}`)))}return s.push(""),s.join("\n")})(u,d))}),Tu.command("view <runId>").description("Show details for a specific run").option("--json","Output as JSON").action(async(e,t)=>{const r=await ys(),n=ws(r),s=Ll(r);ls.debug("Viewing run",{runId:e});const o=await dn({auth:n,client:In(),headers:_s(s),path:{runId:e},query:{detail:"full"}});if($l(o,"get run details",`Run "${e}" not found.`),t.json)process.stdout.write(Fl(o.data));else{const e=o.data;process.stdout.write((e=>{const t=[];if(t.push(ne.bold(`Run ${e.runId}`)),t.push(` ${ne.dim("Status:")} ${Bl(e.status)}`),e.branchName&&t.push(` ${ne.dim("Branch:")} ${e.branchName}`),e.commitSha&&t.push(` ${ne.dim("Commit:")} ${e.commitSha.slice(0,7)}`),e.startedAt&&t.push(` ${ne.dim("Started:")} ${Ol(e.startedAt)}`),null!==e.durationMs&&t.push(` ${ne.dim("Duration:")} ${(e=>{if(null===e)return"-";const t=Math.floor(e/1e3);if(t<60)return`${t}s`;const r=Math.floor(t/60);return r<60?`${r}m ${t%60}s`:`${Math.floor(r/60)}h ${r%60}m`})(e.durationMs)}`),e.source&&t.push(` ${ne.dim("Source:")} ${e.source.toLowerCase()}`),e.projectId){const r=`https://app.stably.ai/project/${e.projectId}/playwright/history/${e.runId}`;t.push(` ${ne.dim("URL:")} ${ne.underline(Dr("link",r))}`)}t.push("");const r=[];e.passedCount>0&&r.push(Dr("success",`${e.passedCount} passed`)),e.failedCount>0&&r.push(Dr("error",`${e.failedCount} failed`)),e.flakyCount>0&&r.push(Dr("warning",`${e.flakyCount} flaky`)),e.timedoutCount>0&&r.push(Dr("error",`${e.timedoutCount} timedout`)),e.skippedCount>0&&r.push(Dr("muted",`${e.skippedCount} skipped`)),e.interruptedCount>0&&r.push(Dr("warning",`${e.interruptedCount} interrupted`)),t.push(`${ne.bold("Test Results:")} ${r.join(", ")}`);const n=e.testCases.filter(e=>"FAILED"===e.status||"TIMEDOUT"===e.status||"INTERRUPTED"===e.status||"FLAKY"===e.status);if(n.length>0){t.push(""),t.push(ne.bold("Failed/Flaky Tests:"));for(const e of n){const r=e.status??"UNKNOWN",n=Dl[r]??(e=>e),s=e.location??"",o=e.title??e.testIdentifier,{attempts:i}=e,a=i?.length??0,c=a>1?` (${a} attempts)`:"",l=s?`${s} - `:"";t.push(` ${n(r)} ${l}${o}${ne.dim(c)}`);const u=i?.at(-1);if(u?.errorMessage){const e=u.errorMessage.split("\n")[0]?.slice(0,100)??"";t.push(` ${ne.dim(e)}`)}}}return t.push(""),t.join("\n")})(e))}}),hu.command("build",{hidden:!0}).description('(Deprecated) Use "stably create" instead').allowUnknownOption(!0).allowExcessArguments(!0).action(()=>{process.stderr.write('\nπ "stably build" has moved! Use "stably create" instead:\n\n stably create "Read the .md files in /tests directory and then create playwright tests"\n\n'),process.exit(1)}),kl.forEach(({args:e,description:t,name:r})=>{hu.command(r).description(t).helpOption(!1).helpCommand(!1).allowUnknownOption(!0).allowExcessArguments(!0).passThroughOptions().action(()=>Rl({overrideArgs:e,subcommand:r}))});var _u=()=>{0!==mu.length&&(process.stderr.write(mu.join("")),mu=[])};(async()=>{await(async()=>{if(!lu&&"1"!==process.env.STABLY_DISABLE_TELEMETRY&&"1"!==process.env.DO_NOT_TRACK&&!process.argv.includes("--no-telemetry"))try{const{init:e}=await import("@hyperdx/node-opentelemetry");e({apiKey:"61d10b50-9534-47be-a732-95bfe461adb7",service:"stably-cli",consoleCapture:!0,disableTracing:!0,disableMetrics:!0,disableStartupLogs:!0,additionalResourceAttributes:{"cli.version":pn,"node.version":process.version,"os.platform":process.platform}}),lu=!0}catch{}})();try{await hu.parseAsync(process.argv),ls.info("CLI completed successfully")}catch(e){if(!(e=>!!e&&"object"==typeof e&&"code"in e)(e)){const t=e instanceof Error?e.message:String(e);return ls.error(t,{stack:e instanceof Error?e.stack:void 0}),_u(),ls.flush(),ls.printLogFileInfo(),await uu(),void(process.exitCode=1)}const t="number"==typeof e.exitCode?e.exitCode:1,r=process.argv.slice(2).find(e=>!e.startsWith("-")),n=!!r&&!!bu(hu,[r]);if(("commander.excessArguments"===e.code||"commander.unknownCommand"===e.code)&&r&&!n)return mu=[],ls.warn("Unknown command",{command:r}),process.stderr.write(`command '${r}' not found\n`),wu(),void(process.exitCode=t);ls.debug("Commander error",{code:e.code,exitCode:t}),_u(),process.exitCode=t}finally{ls.flush(),await uu()}})();
|